Project
Loading...
Searching...
No Matches
Layer.cxx
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
14
15#include "Framework/Logger.h"
16
17#include <TGeoBBox.h>
18#include <TGeoMatrix.h>
19#include <TGeoTube.h>
20#include <TGeoVolume.h>
21#include <TMath.h>
22
23#include <algorithm>
24#include <cmath>
25
26namespace o2
27{
28namespace iotof
29{
30Layer::Layer(std::string layerName, float rInn, float rOut, float zLength, float zOffset, float layerX2X0,
31 int layout, int nStaves, float staveSize, double staveTiltAngle, int modulesPerStave, float sensorThickness)
32 : mLayerName(layerName),
33 mInnerRadius(rInn),
34 mOuterRadius(rOut),
35 mZLength(zLength),
36 mZOffset(zOffset),
37 mSensorThickness(sensorThickness),
38 mX2X0(layerX2X0),
39 mLayout(layout),
40 mStaves(nStaves, staveSize),
41 mModulesPerStave(modulesPerStave),
42 mTiltAngle(staveTiltAngle)
43{
44 const float Si_X0 = 9.5f; // cm, radiation length of silicon
45 mChipThickness = mX2X0 * Si_X0;
46 std::string name = "";
47 switch (layout) {
48 case kBarrel:
50 name = "barrel";
52 break;
53 case kDisk:
54 case kDiskSegmented:
55 name = "forward";
57 break;
58 default:
59 LOG(fatal) << "Invalid layout " << layout;
60 }
61 // Sanity checks
63 LOG(fatal) << "Invalid layer dimensions: rInner " << mInnerRadius << " cm is larger than rOuter " << mOuterRadius << " cm";
64 }
65 if ((mStaves.first != 0 || mStaves.second != 0.0f) && (layout != kBarrelSegmented && layout != kDiskSegmented)) {
66 LOG(fatal) << "Invalid configuration: number of segments " << mStaves.first << " is set for non-segmented layout " << layout;
67 }
68 if ((mStaves.first <= 1 || mStaves.second <= 0.0f) && (layout == kBarrelSegmented || layout == kDiskSegmented)) {
69 LOG(fatal) << "Invalid configuration: number of segments " << mStaves.first << " must be positive for segmented layout " << layout;
70 }
71 if (mModulesPerStave <= 0 && (layout == kBarrelSegmented || layout == kDiskSegmented)) {
72 LOG(fatal) << "Invalid configuration: number of sensors per segment " << mModulesPerStave << " must be positive for segmented layout " << layout;
73 }
74 if (std::abs(mTiltAngle) > 0.1 && (layout != kBarrelSegmented && layout != kDiskSegmented)) {
75 LOG(fatal) << "Invalid configuration: tilt angle " << mTiltAngle << " is set for non-segmented layout " << layout;
76 }
77 if ((mTiltAngle < 0.0 || mTiltAngle > 90.0) && (layout == kBarrelSegmented || layout == kDiskSegmented)) {
78 LOG(fatal) << "Invalid configuration: tilt angle " << mTiltAngle << " is too large, it must be between 0 and 90 degrees";
79 }
80 if (mSensorThickness < 0.0f || mSensorThickness > mChipThickness) {
81 LOG(fatal) << "Invalid configuration: sensor thickness " << mSensorThickness << " cm is out of range (0, " << mChipThickness << ") cm";
82 }
83 if (sensorThickness > 0.0f && (layout == kBarrel || layout == kDisk)) {
84 LOG(fatal) << "Invalid configuration: sensor thickness " << mSensorThickness << " cm is set for non-segmented layout, it should be 0";
85 }
86
87 LOGP(info, "TOF: Creating {} layer: rInner: {} (cm) rOuter: {} (cm) zLength: {} (cm) zOffset: {} x2X0: {}", name.c_str(), mInnerRadius, mOuterRadius, mZLength, mZOffset, mX2X0);
88}
89
90void setLayerStyle(TGeoVolume* obj)
91{
92 obj->SetLineColor(kRed - 7);
93 obj->SetFillColor(kRed - 7);
94 obj->SetLineWidth(1);
95 obj->SetTransparency(70);
96}
97void setStaveStyle(TGeoVolume* obj)
98{
99 obj->SetLineColor(kRed - 5);
100 obj->SetFillColor(kRed - 9);
101 obj->SetLineWidth(2);
102 obj->SetTransparency(45);
103}
104void setModuleStyle(TGeoVolume* obj)
105{
106 obj->SetLineColor(kRed - 3);
107 obj->SetFillColor(kRed - 8);
108 obj->SetLineWidth(2);
109 obj->SetTransparency(35);
110}
111void setChipStyle(TGeoVolume* obj)
112{
113 obj->SetLineColor(kOrange);
114 obj->SetFillColor(kOrange - 9);
115 obj->SetLineWidth(3);
116 obj->SetTransparency(15);
117}
118void setSensorStyle(TGeoVolume* obj)
119{
120 obj->SetLineColor(kRed);
121 obj->SetFillColor(kRed - 9);
122 obj->SetLineWidth(3);
123 obj->SetTransparency(5);
124}
125
126std::vector<std::string> ITOFLayer::mRegister;
127void ITOFLayer::createLayer(TGeoVolume* motherVolume)
128{
129 const char* chipName = o2::iotof::GeometryTGeo::getITOFChipPattern();
130 const char* sensName = o2::iotof::GeometryTGeo::getITOFSensorPattern();
131 const char* moduleName = o2::iotof::GeometryTGeo::getITOFModulePattern();
132 const char* staveName = o2::iotof::GeometryTGeo::getITOFStavePattern();
133
134 TGeoMedium* medSi = gGeoManager->GetMedium("TF3_SILICON$");
135 TGeoMedium* medAir = gGeoManager->GetMedium("TF3_AIR$");
136 LOGP(info, "Media: {} {}", (void*)medSi, (void*)medAir);
137
138 switch (mLayout) {
139 case kBarrel: {
140 TGeoTube* sensor = new TGeoTube(mInnerRadius, mOuterRadius, mZLength / 2);
141 TGeoTube* chip = new TGeoTube(mInnerRadius, mOuterRadius, mZLength / 2);
142 TGeoTube* layer = new TGeoTube(mInnerRadius, mOuterRadius, mZLength / 2);
143
144 TGeoVolume* sensVol = new TGeoVolume(sensName, sensor, medSi);
145 TGeoVolume* chipVol = new TGeoVolume(chipName, chip, medSi);
146 TGeoVolume* layerVol = new TGeoVolume(mLayerName.c_str(), layer, medAir);
147 setSensorStyle(sensVol);
148 setChipStyle(chipVol);
149 setLayerStyle(layerVol);
150
151 LOGP(info, "Inserting Barrel {} in {} ", sensVol->GetName(), chipVol->GetName());
152 ITOFLayer::mRegister.push_back(sensVol->GetName());
153 chipVol->AddNode(sensVol, 1, nullptr);
154
155 LOGP(info, "Inserting Barrel {} in {} ", chipVol->GetName(), layerVol->GetName());
156 layerVol->AddNode(chipVol, 1, nullptr);
157
158 LOGP(info, "Inserting Barrel {} in {} ", layerVol->GetName(), motherVolume->GetName());
159 motherVolume->AddNode(layerVol, 1, nullptr);
160 return;
161 }
162 case kBarrelSegmented: {
163 // First we create the volume for the whole layer, which will be used as mother volume for the segments
164 const double avgRadius = 0.5 * (mInnerRadius + mOuterRadius);
165 const double staveSizeX = mStaves.second; // cm
166 const double staveSizeY = mOuterRadius - mInnerRadius; // cm
167 const double staveSizeZ = mZLength; // cm
168 const double deltaForTilt = 0.5 * (std::sin(TMath::DegToRad() * mTiltAngle) * staveSizeX + std::cos(TMath::DegToRad() * mTiltAngle) * staveSizeY); // we increase the size of the layer to account for the tilt of the staves
169 const double radiusMax = std::sqrt(avgRadius * avgRadius + 0.25 * staveSizeX * staveSizeX + 0.25 * staveSizeY * staveSizeY + avgRadius * 2. * deltaForTilt); // we increase the outer radius to account for the tilt of the staves
170 const double radiusMin = std::sqrt(avgRadius * avgRadius + 0.25 * staveSizeX * staveSizeX + 0.25 * staveSizeY * staveSizeY - avgRadius * 2. * deltaForTilt); // we decrease the inner radius to account for the tilt of the staves
171 TGeoTube* layer = new TGeoTube(radiusMin - 0.05, radiusMax + 0.05, mZLength / 2); // cm, small margins to ensure staves are fully encapsulated in the layer volume
172 TGeoVolume* layerVol = new TGeoVolume(mLayerName.c_str(), layer, medAir);
173 setLayerStyle(layerVol);
174
175 // Now we create the volume for a single stave
176 TGeoBBox* stave = new TGeoBBox(staveSizeX * 0.5, staveSizeY * 0.5, staveSizeZ * 0.5);
177 TGeoVolume* staveVol = new TGeoVolume(staveName, stave, medAir);
178 setStaveStyle(staveVol);
179
180 // Now we create the volume for a single module (sensor + chip)
181 const int modulesPerStaveX = 1; // we assume that each stave is divided in 2 modules along the x direction
182 const double moduleSizeX = staveSizeX / modulesPerStaveX; // cm
183 const double moduleSizeY = staveSizeY; // cm
184 const double moduleSizeZ = staveSizeZ / mModulesPerStave; // cm
185 TGeoBBox* module = new TGeoBBox(moduleSizeX * 0.5, moduleSizeY * 0.5, moduleSizeZ * 0.5);
186 TGeoVolume* moduleVol = new TGeoVolume(moduleName, module, medAir);
187 setModuleStyle(moduleVol);
188
189 // Now we create the volume of the chip, which is the same for all modules
190 const int chipsPerModuleX = 2; // we assume that each module is divided in 2 chips along the x direction
191 const int chipsPerModuleZ = 2; // we assume that each module is divided in 2 chips along the z direction
192 const double chipSizeX = moduleSizeX / chipsPerModuleX; // cm
193 const double chipSizeY = moduleSizeY; // cm
194 const double chipSizeZ = moduleSizeZ / chipsPerModuleZ; // cm
195 TGeoBBox* chip = new TGeoBBox(chipSizeX * 0.5, chipSizeY * 0.5, chipSizeZ * 0.5);
196 TGeoVolume* chipVol = new TGeoVolume(chipName, chip, medSi);
197 setChipStyle(chipVol);
198
199 // Finally we create the volume of the sensor, which is the same for all chips
200 const int sensorsPerChipX = 1; // we assume that each chip is divided in 2 sensors along the x direction
201 const int sensorsPerChipZ = 1; // we assume that each chip is divided in 2 sensors along the z direction
202 const double sensorSizeX = chipSizeX / sensorsPerChipX; // cm
203 const double sensorSizeY = mSensorThickness; // cm
204 const double sensorSizeZ = chipSizeZ / sensorsPerChipZ; // cm
205 TGeoBBox* sensor = new TGeoBBox(sensorSizeX * 0.5, sensorSizeY * 0.5, sensorSizeZ * 0.5);
206 TGeoVolume* sensVol = new TGeoVolume(sensName, sensor, medSi);
207 setSensorStyle(sensVol);
208 ITOFLayer::mRegister.push_back(sensVol->GetName());
209
210 // Now we build a chip from sensors
211 for (int i = 0; i < sensorsPerChipX; ++i) {
212 for (int j = 0; j < sensorsPerChipZ; ++j) {
213 LOGP(info, "iTOF: Creating sensor {}/{} for chip {}/{}", i + 1, sensorsPerChipX, j + 1, sensorsPerChipZ);
214 auto* translation = new TGeoTranslation((i + 0.5) * sensorSizeX - 0.5 * chipSizeX,
215 0,
216 (j + 0.5) * sensorSizeZ - 0.5 * chipSizeZ);
217 chipVol->AddNode(sensVol, 1 + i * sensorsPerChipZ + j, translation);
218 }
219 }
220
221 // Now we build a module from chips
222 for (int i = 0; i < chipsPerModuleX; ++i) {
223 for (int j = 0; j < chipsPerModuleZ; ++j) {
224 LOGP(info, "iTOF: Creating chip {}/{} for module {}/{}", i + 1, chipsPerModuleX, j + 1, chipsPerModuleZ);
225 auto* translation = new TGeoTranslation((i + 0.5) * chipSizeX - 0.5 * moduleSizeX, 0, (j + 0.5) * chipSizeZ - 0.5 * moduleSizeZ);
226 moduleVol->AddNode(chipVol, 1 + i * chipsPerModuleZ + j, translation);
227 }
228 }
229
230 // Now we build a stave from modules
231 for (int i = 0; i < modulesPerStaveX; ++i) {
232 for (int j = 0; j < mModulesPerStave; ++j) {
233 LOGP(info, "iTOF: Creating module {}/{} for stave {}/{}", i + 1, modulesPerStaveX, j + 1, mModulesPerStave);
234 auto* translation = new TGeoTranslation((i + 0.5) * moduleSizeX - 0.5 * staveSizeX, 0, (j + 0.5) * moduleSizeZ - 0.5 * staveSizeZ);
235 staveVol->AddNode(moduleVol, 1 + i * mModulesPerStave + j, translation);
236 }
237 }
238
239 // We finally put all the staves in the layer
240 for (int i = 0; i < mStaves.first; ++i) {
241 LOGP(info, "iTOF: Creating stave {}/{} for layer {}", i + 1, mStaves.first, layerVol->GetName());
242 const double phi = TMath::TwoPi() * i / mStaves.first;
243 const double x = avgRadius * TMath::Cos(phi);
244 const double y = avgRadius * TMath::Sin(phi);
245 auto* rotation = new TGeoRotation(Form("segmentRot%d", i + 1), phi * TMath::RadToDeg() + 90 + mTiltAngle, 0, 0);
246 auto* transformation = new TGeoCombiTrans(x, y, 0, rotation);
247
248 LOGP(info, "Inserting Barrel {} in {} ", chipVol->GetName(), layerVol->GetName());
249 layerVol->AddNode(staveVol, 1 + i, transformation);
250 }
251 LOGP(info, "Inserting Barrel {} in {} at r={} cm", layerVol->GetName(), motherVolume->GetName(), avgRadius);
252 motherVolume->AddNode(layerVol, 1, nullptr);
253 return;
254 }
255 default:
256 LOG(fatal) << "Invalid layout " << mLayout;
257 }
258}
259
260std::vector<std::string> OTOFLayer::mRegister;
261void OTOFLayer::createLayer(TGeoVolume* motherVolume)
262{
263 const char* chipName = o2::iotof::GeometryTGeo::getOTOFChipPattern();
264 const char* sensName = o2::iotof::GeometryTGeo::getOTOFSensorPattern();
265 const char* moduleName = o2::iotof::GeometryTGeo::getOTOFModulePattern();
266 const char* staveName = o2::iotof::GeometryTGeo::getOTOFStavePattern();
267
268 TGeoMedium* medSi = gGeoManager->GetMedium("TF3_SILICON$");
269 TGeoMedium* medAir = gGeoManager->GetMedium("TF3_AIR$");
270 LOGP(info, "Media: {} {}", (void*)medSi, (void*)medAir);
271
272 switch (mLayout) {
273 case kBarrel: {
274 TGeoTube* sensor = new TGeoTube(mInnerRadius, mOuterRadius, mZLength / 2);
275 TGeoTube* chip = new TGeoTube(mInnerRadius, mOuterRadius, mZLength / 2);
276 TGeoTube* layer = new TGeoTube(mInnerRadius, mOuterRadius, mZLength / 2);
277
278 TGeoVolume* sensVol = new TGeoVolume(sensName, sensor, medSi);
279 TGeoVolume* chipVol = new TGeoVolume(chipName, chip, medSi);
280 TGeoVolume* layerVol = new TGeoVolume(mLayerName.c_str(), layer, medAir);
281 setSensorStyle(sensVol);
282 setChipStyle(chipVol);
283 setLayerStyle(layerVol);
284
285 LOGP(info, "Inserting {} in {} ", sensVol->GetName(), chipVol->GetName());
286 OTOFLayer::mRegister.push_back(sensVol->GetName());
287 chipVol->AddNode(sensVol, 1, nullptr);
288
289 LOGP(info, "Inserting {} in {} ", chipVol->GetName(), layerVol->GetName());
290 layerVol->AddNode(chipVol, 1, nullptr);
291
292 LOGP(info, "Inserting {} in {} ", layerVol->GetName(), motherVolume->GetName());
293 motherVolume->AddNode(layerVol, 1, nullptr);
294 return;
295 }
296 case kBarrelSegmented: {
297 // First we create the volume for the whole layer, which will be used as mother volume for the segments
298 const double avgRadius = 0.5 * (mInnerRadius + mOuterRadius);
299 const double staveSizeX = mStaves.second; // cm, tangential stave size
300 const double staveSizeY = mOuterRadius - mInnerRadius; // cm, radial stave size
301 const double staveSizeZ = mZLength; // cm
302
303 // Build the mother layer tube from the exact inscribed/outscribed radii of a tilted stave rectangle.
304 const double alpha = mTiltAngle * TMath::DegToRad();
305 const double u0 = -avgRadius * std::cos(alpha);
306 const double v0 = avgRadius * std::sin(alpha);
307 const double uClamped = std::max(-0.5 * staveSizeY, std::min(0.5 * staveSizeY, u0));
308 const double vClamped = std::max(-0.5 * staveSizeX, std::min(0.5 * staveSizeX, v0));
309 const double radiusMin = std::hypot(uClamped - u0, vClamped - v0);
310
311 const double uCorners[4] = {-0.5 * staveSizeY, 0.5 * staveSizeY, 0.5 * staveSizeY, -0.5 * staveSizeY};
312 const double vCorners[4] = {-0.5 * staveSizeX, -0.5 * staveSizeX, 0.5 * staveSizeX, 0.5 * staveSizeX};
313 double radiusMax = 0.0;
314 for (int i = 0; i < 4; ++i) {
315 radiusMax = std::max(radiusMax, std::hypot(uCorners[i] - u0, vCorners[i] - v0));
316 }
317 TGeoTube* layer = new TGeoTube(radiusMin, radiusMax, mZLength / 2);
318 TGeoVolume* layerVol = new TGeoVolume(mLayerName.c_str(), layer, medAir);
319 setLayerStyle(layerVol);
320
321 // Now we create the volume for a single stave
322 TGeoBBox* stave = new TGeoBBox(staveSizeX * 0.5, staveSizeY * 0.5, staveSizeZ * 0.5);
323 TGeoVolume* staveVol = new TGeoVolume(staveName, stave, medAir);
324 setStaveStyle(staveVol);
325
326 // Now we create the volume for a single module (sensor + chip)
327 // oTOF V2 is a 2xN matrix of modules per stave with overlap along z.
328 const int modulesPerStaveX = 2;
329 if (mModulesPerStave % modulesPerStaveX != 0) {
330 LOG(fatal) << "Invalid oTOF module layout: total modules per stave " << mModulesPerStave
331 << " is not divisible by modulesPerStaveX=" << modulesPerStaveX;
332 }
333 const int modulesPerStaveZ = mModulesPerStave / modulesPerStaveX;
334 const double moduleOverlapZ = 0.7; // cm, 7 mm longitudinal overlap from oTOF V2 specs
335 const double moduleSizeX = staveSizeX / modulesPerStaveX;
336 const double moduleSizeY = staveSizeY;
337 const double moduleSizeZ = (staveSizeZ + (modulesPerStaveZ - 1) * moduleOverlapZ) / modulesPerStaveZ;
338 const double modulePitchZ = moduleSizeZ - moduleOverlapZ;
339 if (modulePitchZ <= 0.0) {
340 LOG(fatal) << "Invalid oTOF module overlap " << moduleOverlapZ << " cm for module size " << moduleSizeZ << " cm";
341 }
342 TGeoBBox* module = new TGeoBBox(moduleSizeX * 0.5, moduleSizeY * 0.5, moduleSizeZ * 0.5);
343 TGeoVolume* moduleVol = new TGeoVolume(moduleName, module, medAir);
344 setModuleStyle(moduleVol);
345
346 // Now we create the volume of the chip, which is the same for all modules
347 const int chipsPerModuleX = 2; // we assume that each module is divided in 2 chips along the x direction
348 const int chipsPerModuleZ = 2; // we assume that each module is divided in 2 chips along the z direction
349 const double chipSizeX = moduleSizeX / chipsPerModuleX; // cm
350 const double chipSizeY = moduleSizeY; // cm
351 const double chipSizeZ = moduleSizeZ / chipsPerModuleZ; // cm
352 TGeoBBox* chip = new TGeoBBox(chipSizeX * 0.5, chipSizeY * 0.5, chipSizeZ * 0.5);
353 TGeoVolume* chipVol = new TGeoVolume(chipName, chip, medSi);
354 setChipStyle(chipVol);
355
356 // Finally we create the volume of the sensor, which is the same for all chips
357 const int sensorsPerChipX = 1; // we assume that each chip is divided in 2 sensors along the x direction
358 const int sensorsPerChipZ = 1; // we assume that each chip is divided in 2 sensors along the z direction
359 const double sensorSizeX = chipSizeX / sensorsPerChipX; // cm
360 const double sensorSizeY = mSensorThickness; // cm
361 const double sensorSizeZ = chipSizeZ / sensorsPerChipZ; // cm
362 TGeoBBox* sensor = new TGeoBBox(sensorSizeX * 0.5, sensorSizeY * 0.5, sensorSizeZ * 0.5);
363 TGeoVolume* sensVol = new TGeoVolume(sensName, sensor, medSi);
364 setSensorStyle(sensVol);
365 OTOFLayer::mRegister.push_back(sensVol->GetName());
366
367 // Now we build a chip from sensors
368 for (int i = 0; i < sensorsPerChipX; ++i) {
369 for (int j = 0; j < sensorsPerChipZ; ++j) {
370 LOGP(info, "oTOF: Creating sensor {}/{} for chip {}/{}", i + 1, sensorsPerChipX, j + 1, sensorsPerChipZ);
371 auto* translation = new TGeoTranslation((i + 0.5) * sensorSizeX - 0.5 * chipSizeX,
372 0,
373 (j + 0.5) * sensorSizeZ - 0.5 * chipSizeZ);
374 chipVol->AddNode(sensVol, 1 + i * sensorsPerChipZ + j, translation);
375 }
376 }
377
378 // Now we build a module from chips
379 for (int i = 0; i < chipsPerModuleX; ++i) {
380 for (int j = 0; j < chipsPerModuleZ; ++j) {
381 LOGP(info, "oTOF: Creating chip {}/{} for module {}/{}", i + 1, chipsPerModuleX, j + 1, chipsPerModuleZ);
382 auto* translation = new TGeoTranslation((i + 0.5) * chipSizeX - 0.5 * moduleSizeX, 0, (j + 0.5) * chipSizeZ - 0.5 * moduleSizeZ);
383 moduleVol->AddNode(chipVol, 1 + i * chipsPerModuleZ + j, translation);
384 }
385 }
386
387 // Now we build a stave from modules
388 for (int i = 0; i < modulesPerStaveX; ++i) {
389 for (int j = 0; j < modulesPerStaveZ; ++j) {
390 LOGP(info, "oTOF: Creating module {}/{} for stave {}/{}", i + 1, modulesPerStaveX, j + 1, modulesPerStaveZ);
391 const double tx = (i + 0.5) * moduleSizeX - 0.5 * staveSizeX;
392 const double tz = -0.5 * staveSizeZ + 0.5 * moduleSizeZ + j * modulePitchZ;
393 auto* translation = new TGeoTranslation(tx, 0, tz);
394 staveVol->AddNode(moduleVol, 1 + i * modulesPerStaveZ + j, translation);
395 }
396 }
397
398 // We finally put all the staves in the layer
399 for (int i = 0; i < mStaves.first; ++i) {
400 LOGP(info, "oTOF: Creating stave {}/{} for layer {}", i + 1, mStaves.first, layerVol->GetName());
401 const double phi = TMath::TwoPi() * i / mStaves.first;
402 const double x = avgRadius * TMath::Cos(phi);
403 const double y = avgRadius * TMath::Sin(phi);
404 auto* rotation = new TGeoRotation(Form("segmentRot%d", i + 1), phi * TMath::RadToDeg() + 90 + mTiltAngle, 0, 0);
405 auto* transformation = new TGeoCombiTrans(x, y, 0, rotation);
406
407 LOGP(info, "Inserting Barrel {} in {} ", chipVol->GetName(), layerVol->GetName());
408 layerVol->AddNode(staveVol, 1 + i, transformation);
409 }
410 LOGP(info, "Inserting Barrel {} in {} at r={} cm", layerVol->GetName(), motherVolume->GetName(), avgRadius);
411 motherVolume->AddNode(layerVol, 1, nullptr);
412 return;
413 }
414 default:
415 LOG(fatal) << "Invalid layout " << mLayout;
416 }
417}
418
419void FTOFLayer::createLayer(TGeoVolume* motherVolume)
420{
421 std::string chipName = o2::iotof::GeometryTGeo::getFTOFChipPattern(),
423
424 TGeoTube* sensor = new TGeoTube(mInnerRadius, mOuterRadius, mZLength / 2);
425 TGeoTube* chip = new TGeoTube(mInnerRadius, mOuterRadius, mZLength / 2);
426 TGeoTube* layer = new TGeoTube(mInnerRadius, mOuterRadius, mZLength / 2);
427
428 TGeoMedium* medSi = gGeoManager->GetMedium("TF3_SILICON$");
429 TGeoMedium* medAir = gGeoManager->GetMedium("TF3_AIR$");
430
431 TGeoVolume* sensVol = new TGeoVolume(sensName.c_str(), sensor, medSi);
432 TGeoVolume* chipVol = new TGeoVolume(chipName.c_str(), chip, medSi);
433 TGeoVolume* layerVol = new TGeoVolume(mLayerName.c_str(), layer, medAir);
434 setSensorStyle(sensVol);
435 setChipStyle(chipVol);
436 setLayerStyle(layerVol);
437
438 LOGP(info, "Inserting {} in {} ", sensVol->GetName(), chipVol->GetName());
439 chipVol->AddNode(sensVol, 1, nullptr);
440
441 LOGP(info, "Inserting {} in {} ", chipVol->GetName(), layerVol->GetName());
442 layerVol->AddNode(chipVol, 1, nullptr);
443
444 auto* fwdTOFRotation = new TGeoRotation("fwdTOFRotation", 0, 0, 180);
445 auto* fwdTOFCombiTrans = new TGeoCombiTrans(0, 0, mZOffset, fwdTOFRotation);
446
447 LOGP(info, "Inserting {} in {} ", layerVol->GetName(), motherVolume->GetName());
448 motherVolume->AddNode(layerVol, 1, fwdTOFCombiTrans);
449}
450
451void BTOFLayer::createLayer(TGeoVolume* motherVolume)
452{
453 std::string chipName = o2::iotof::GeometryTGeo::getBTOFChipPattern(),
455
456 TGeoTube* sensor = new TGeoTube(mInnerRadius, mOuterRadius, mZLength / 2);
457 TGeoTube* chip = new TGeoTube(mInnerRadius, mOuterRadius, mZLength / 2);
458 TGeoTube* layer = new TGeoTube(mInnerRadius, mOuterRadius, mZLength / 2);
459
460 TGeoMedium* medSi = gGeoManager->GetMedium("TF3_SILICON$");
461 TGeoMedium* medAir = gGeoManager->GetMedium("TF3_AIR$");
462
463 TGeoVolume* sensVol = new TGeoVolume(sensName.c_str(), sensor, medSi);
464 TGeoVolume* chipVol = new TGeoVolume(chipName.c_str(), chip, medSi);
465 TGeoVolume* layerVol = new TGeoVolume(mLayerName.c_str(), layer, medAir);
466 setSensorStyle(sensVol);
467 setChipStyle(chipVol);
468 setLayerStyle(layerVol);
469
470 LOGP(info, "Inserting {} in {} ", sensVol->GetName(), chipVol->GetName());
471 chipVol->AddNode(sensVol, 1, nullptr);
472
473 LOGP(info, "Inserting {} in {} ", chipVol->GetName(), layerVol->GetName());
474 layerVol->AddNode(chipVol, 1, nullptr);
475
476 auto* bwdTOFRotation = new TGeoRotation("bwdTOFRotation", 0, 0, 180);
477 auto* fwdTOFCombiTrans = new TGeoCombiTrans(0, 0, mZOffset, bwdTOFRotation);
478
479 LOGP(info, "Inserting {} in {} ", layerVol->GetName(), motherVolume->GetName());
480 motherVolume->AddNode(layerVol, 1, fwdTOFCombiTrans);
481}
482
483} // namespace iotof
484} // namespace o2
int32_t i
uint32_t j
Definition RawData.h:0
virtual void createLayer(TGeoVolume *motherVolume) override
Definition Layer.cxx:451
virtual void createLayer(TGeoVolume *motherVolume) override
Definition Layer.cxx:419
static const char * getITOFChipPattern()
static const char * getFTOFSensorPattern()
static const char * getFTOFChipPattern()
static const char * getBTOFChipPattern()
static const char * getOTOFModulePattern()
static const char * getITOFModulePattern()
static const char * getOTOFSensorPattern()
static const char * getITOFStavePattern()
static const char * getITOFSensorPattern()
static const char * getOTOFStavePattern()
static const char * getOTOFChipPattern()
static const char * getBTOFSensorPattern()
static std::vector< std::string > mRegister
Definition Layer.h:69
virtual void createLayer(TGeoVolume *motherVolume) override
Definition Layer.cxx:127
float mZOffset
Definition Layer.h:53
float mOuterRadius
Definition Layer.h:51
float mZLength
Definition Layer.h:52
int mModulesPerStave
Definition Layer.h:60
static constexpr int kBarrelSegmented
Definition Layer.h:43
static constexpr int kDisk
Definition Layer.h:42
float mSensorThickness
Definition Layer.h:56
float mChipThickness
Definition Layer.h:55
static constexpr int kBarrel
Definition Layer.h:41
static constexpr int kDiskSegmented
Definition Layer.h:44
std::pair< int, float > mStaves
Definition Layer.h:59
std::string mLayerName
Definition Layer.h:49
float mInnerRadius
Definition Layer.h:50
double mTiltAngle
Definition Layer.h:61
float mX2X0
Definition Layer.h:54
virtual void createLayer(TGeoVolume *motherVolume) override
Definition Layer.cxx:261
static std::vector< std::string > mRegister
Definition Layer.h:77
GLfloat GLfloat GLfloat alpha
Definition glcorearb.h:279
GLint GLenum GLint x
Definition glcorearb.h:403
GLuint const GLchar * name
Definition glcorearb.h:781
GLfloat v0
Definition glcorearb.h:811
GLenum GLuint GLint GLint layer
Definition glcorearb.h:1310
void setLayerStyle(TGeoVolume *obj)
Definition Layer.cxx:90
void setModuleStyle(TGeoVolume *obj)
Definition Layer.cxx:104
void setChipStyle(TGeoVolume *obj)
Definition Layer.cxx:111
void setStaveStyle(TGeoVolume *obj)
Definition Layer.cxx:97
void setSensorStyle(TGeoVolume *obj)
Definition Layer.cxx:118
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
auto transformation
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"