Project
Loading...
Searching...
No Matches
GeometryTGeo.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
13#include <TGeoManager.h>
15#include <TMath.h>
16
17#include <limits>
18
20
21namespace o2
22{
23namespace trk
24{
25std::unique_ptr<o2::trk::GeometryTGeo> GeometryTGeo::sInstance;
26
27// Names
28std::string GeometryTGeo::sVolumeName = "TRKV";
29std::string GeometryTGeo::sLayerName = "TRKLayer";
30std::string GeometryTGeo::sPetalAssemblyName = "PETAL";
31std::string GeometryTGeo::sPetalName = "PETALCASE";
32std::string GeometryTGeo::sPetalDiskName = "DISK";
33std::string GeometryTGeo::sPetalLayerName = "LAYER";
34std::string GeometryTGeo::sStaveName = "TRKStave";
35std::string GeometryTGeo::sHalfStaveName = "TRKHalfStave";
36std::string GeometryTGeo::sModuleName = "TRKModule";
37std::string GeometryTGeo::sChipName = "TRKChip";
38std::string GeometryTGeo::sSensorName = "TRKSensor";
39std::string GeometryTGeo::sDeadzoneName = "TRKDeadzone";
40std::string GeometryTGeo::sMetalStackName = "TRKMetalStack";
41
42std::string GeometryTGeo::sWrapperVolumeName = "TRKUWrapVol";
43
45{
46 if (!mOwner) {
47 mOwner = true;
48 sInstance.release();
49 }
50}
51GeometryTGeo::GeometryTGeo(bool build, int loadTrans) : DetMatrixCache(detectors::DetID::TRK)
52{
53 if (sInstance) {
54 LOGP(fatal, "Invalid use of public constructor: o2::trk::GeometryTGeo instance exists");
55 }
56 mLayerToWrapper.fill(-1);
57 if (build) {
58 Build(loadTrans);
59 }
60}
61
62//__________________________________________________________________________
63void GeometryTGeo::Build(int loadTrans)
64{
69
70 if (isBuilt()) {
71 LOGP(warning, "Already built");
72 return; // already initialized
73 }
74
75 if (gGeoManager == nullptr) {
76 LOGP(fatal, "Geometry is not loaded");
77 }
78
81
82 LOG(debug) << "Layout ML: " << mLayoutML << ", Layout OL: " << mLayoutOL;
83
89
94
99
103
104 for (int i = 0; i < mNumberOfLayersMLOT; i++) {
109 }
110
111 int numberOfChipsTotal = 0;
112
114 for (int i = 0; i < mNumberOfPetalsVD; i++) {
116 numberOfChipsTotal += mNumberOfChipsPerPetalVD[i];
117 mLastChipIndex[i] = numberOfChipsTotal - 1;
118 mLastChipIndexVD[i] = numberOfChipsTotal - 1;
119 }
120
122 for (int i = 0; i < mNumberOfLayersMLOT; i++) {
124 numberOfChipsTotal += mNumberOfChipsPerLayerMLOT[i];
125 mLastChipIndex[i + mNumberOfPetalsVD] = numberOfChipsTotal - 1;
126 mLastChipIndexMLOT[i] = numberOfChipsTotal - 1;
127 }
128
129 setSize(numberOfChipsTotal);
130 fillMatrixCache(loadTrans);
133}
134
135//__________________________________________________________________________
137{
138 if (index <= mLastChipIndexVD[mLastChipIndexVD.size() - 1]) {
139 return 0;
140 } else if (index > mLastChipIndexVD[mLastChipIndexVD.size() - 1]) {
141 return 1;
142 }
143 return -1;
144}
145
146//__________________________________________________________________________
148{
149 int petalcase = 0;
150
151 int subDetID = getSubDetID(index);
152 if (subDetID == 1) {
153 return -1;
154 } else if (index <= mLastChipIndexVD[mNumberOfPetalsVD - 1]) {
155 while (index > mLastChipIndexVD[petalcase]) {
156 petalcase++;
157 }
158 }
159 return petalcase;
160}
161
162//__________________________________________________________________________
164{
165 int subDetID = getSubDetID(index);
166 int petalcase = getPetalCase(index);
167
168 if (subDetID == 0) {
170 return -1;
171 }
172 return (index % mNumberOfChipsPerPetalVD[petalcase]) - mNumberOfLayersVD;
173 }
174
175 return -1;
176}
177
178//__________________________________________________________________________
180{
181 int subDetID = getSubDetID(index);
182 int petalcase = getPetalCase(index);
183 int lay = 0;
184
185 if (subDetID == 0) {
187 return -1;
188 }
189 return index % mNumberOfChipsPerPetalVD[petalcase];
190 } else if (subDetID == 1) {
191 while (index > mLastChipIndex[lay]) {
192 lay++;
193 }
194 return lay - mNumberOfPetalsVD;
195 }
196 return -1;
197}
198//__________________________________________________________________________
200{
201 int subDetID = getSubDetID(index);
202 int lay = getLayer(index);
203 int petalcase = getPetalCase(index);
204
205 if (subDetID == 0) {
206 return -1;
207 } else if (subDetID == 1) {
208 int lay = getLayer(index);
209 index -= getFirstChipIndex(lay, petalcase, subDetID); // get the index of the sensing element in the layer
210
211 const int Nhs = mNumberOfHalfStaves[lay];
212 const int Nmod = mNumberOfModules[lay];
213 const int Nchip = mNumberOfChips[lay];
214
215 if (Nhs == 2) {
216 int chipsPerModule = Nchip;
217 int chipsPerHalfStave = Nmod * chipsPerModule;
218 int chipsPerStave = Nhs * chipsPerHalfStave;
219 return index / chipsPerStave;
220 } else if (Nhs == 1) {
221 int chipsPerModule = Nchip;
222 int chipsPerStave = Nmod * chipsPerModule;
223 return index / chipsPerStave;
224 }
225 }
226 return -1;
227}
228
229//__________________________________________________________________________
231{
232 int subDetID = getSubDetID(index);
233 int lay = getLayer(index);
234 int petalcase = getPetalCase(index);
235
236 if (subDetID == 0) {
237 return -1;
238 } else if (subDetID == 1) {
239 int lay = getLayer(index);
240 index -= getFirstChipIndex(lay, petalcase, subDetID); // get the index of the sensing element in the layer
241
242 const int Nhs = mNumberOfHalfStaves[lay];
243 const int Nmod = mNumberOfModules[lay];
244 const int Nchip = mNumberOfChips[lay];
245
246 int chipsPerModule = Nchip;
247 int chipsPerHalfStave = Nmod * chipsPerModule;
248 int chipsPerStave = Nhs * chipsPerHalfStave;
249
250 int rem = index % chipsPerStave;
251 return rem / chipsPerHalfStave; // 0 = left, 1 = right
252 }
253 return -1;
254}
255
256//__________________________________________________________________________
258{
259 int subDetID = getSubDetID(index);
260 int lay = getLayer(index);
261 int petalcase = getPetalCase(index);
262
263 if (subDetID == 0) {
264 return -1;
265 } else if (subDetID == 1) {
266 int lay = getLayer(index);
267 index -= getFirstChipIndex(lay, petalcase, subDetID); // get the index of the sensing element in the layer
268
269 const int Nhs = mNumberOfHalfStaves[lay];
270 const int Nmod = mNumberOfModules[lay];
271 const int Nchip = mNumberOfChips[lay];
272
273 if (Nhs == 2) {
274 int chipsPerModule = Nchip;
275 int chipsPerHalfStave = Nmod * chipsPerModule;
276 int rem = index % (Nhs * chipsPerHalfStave);
277 rem = rem % chipsPerHalfStave;
278 return rem / chipsPerModule;
279 } else if (Nhs == 1) {
280 int chipsPerModule = Nchip;
281 int rem = index % (Nmod * chipsPerModule);
282 return rem / chipsPerModule;
283 }
284 }
285 return -1;
286}
287
288//__________________________________________________________________________
290{
291 int subDetID = getSubDetID(index);
292 int lay = getLayer(index);
293 int petalcase = getPetalCase(index);
294
295 if (subDetID == 0) {
296 return -1;
297 } else if (subDetID == 1) {
298 int lay = getLayer(index);
299 index -= getFirstChipIndex(lay, petalcase, subDetID); // get the index of the sensing element in the layer
300
301 const int Nhs = mNumberOfHalfStaves[lay];
302 const int Nmod = mNumberOfModules[lay];
303 const int Nchip = mNumberOfChips[lay];
304
305 if (Nhs == 2) {
306 int chipsPerModule = Nchip;
307 return index % chipsPerModule;
308 } else if (Nhs == 1) {
309 int chipsPerModule = Nchip;
310 return index % chipsPerModule;
311 }
312 }
313 return -1;
314}
315
316//__________________________________________________________________________
317unsigned short GeometryTGeo::getChipIndex(int subDetID, int petalcase, int disk, int lay, int stave, int halfstave, int mod, int chip) const
318{
319 if (subDetID == 0) { // VD
320 if (lay == -1) { // disk
321 return getFirstChipIndex(lay, petalcase, subDetID) + mNumberOfLayersVD + disk;
322 } else { // layer
323 return getFirstChipIndex(lay, petalcase, subDetID) + lay;
324 }
325 } else if (subDetID == 1) { // MLOT
326 const int Nhs = mNumberOfHalfStaves[lay]; // 1 or 2
327 const int Nmod = mNumberOfModules[lay]; // module per half-stave (per stave if Nhs==1)
328 const int Nchip = mNumberOfChips[lay]; // chips per module
329
330 if (Nhs == 2) { // staggered geometry: layer -> stave -> halfstave -> mod -> chip
331 int chipsPerModule = Nchip;
332 int chipsPerHalfStave = Nmod * chipsPerModule;
333 int chipsPerStave = Nhs * chipsPerHalfStave;
334 return getFirstChipIndex(lay, petalcase, subDetID) + stave * chipsPerStave + halfstave * chipsPerHalfStave + mod * chipsPerModule + chip;
335 } else if (Nhs == 1) { // turbo geometry: layer -> stave -> mod -> chip (no halfstave)
336 int chipsPerModule = Nchip;
337 int chipsPerStave = Nmod * chipsPerModule;
338 return getFirstChipIndex(lay, petalcase, subDetID) + stave * chipsPerStave + mod * chipsPerModule + chip;
339 }
340 }
341
342 LOGP(warning, "Chip index not found for subDetID %d, petalcase %d, disk %d, layer %d, stave %d, halfstave %d, module %d, chip %d, returning numeric limit", subDetID, petalcase, disk, lay, stave, halfstave, mod, chip);
343 return std::numeric_limits<unsigned short>::max(); // not found
344}
345
346//__________________________________________________________________________
347unsigned short GeometryTGeo::getChipIndex(int subDetID, int volume, int lay, int stave, int halfstave, int mod, int chip) const
348{
349 if (subDetID == 0) { // VD
350 return volume;
351
352 } else if (subDetID == 1) { // MLOT
353 const int Nhs = mNumberOfHalfStaves[lay]; // 1 or 2
354 const int Nmod = mNumberOfModules[lay]; // module per half-stave (per stave if Nhs==1)
355 const int Nchip = mNumberOfChips[lay]; // chips per module
356
357 if (Nhs == 2) { // staggered geometry: layer -> stave -> halfstave -> mod -> chip
358 int chipsPerModule = Nchip;
359 int chipsPerHalfStave = Nmod * chipsPerModule;
360 int chipsPerStave = Nhs * chipsPerHalfStave;
361 return getFirstChipIndex(lay, -1, subDetID) + stave * chipsPerStave + halfstave * chipsPerHalfStave + mod * chipsPerModule + chip;
362 } else if (Nhs == 1) { // turbo geometry: layer -> stave -> mod -> chip (no halfstave)
363 int chipsPerModule = Nchip;
364 int chipsPerStave = Nmod * chipsPerModule;
365 return getFirstChipIndex(lay, -1, subDetID) + stave * chipsPerStave + mod * chipsPerModule + chip;
366 }
367 }
368
369 LOGP(warning, "Chip index not found for subDetID %d, volume %d, layer %d, stave %d, halfstave %d, module %d, chip %d, returning numeric limit", subDetID, volume, lay, stave, halfstave, mod, chip);
370 return std::numeric_limits<unsigned short>::max(); // not found
371}
372
373//__________________________________________________________________________
374bool GeometryTGeo::getChipID(int index, int& subDetID, int& petalcase, int& disk, int& lay, int& stave, int& halfstave, int& mod, int& chip) const
375{
376 subDetID = getSubDetID(index);
377 petalcase = getPetalCase(index);
378 disk = getDisk(index);
379 lay = getLayer(index);
380 stave = getStave(index);
381 if (mNumberOfHalfStaves[lay] == 2) {
382 halfstave = getHalfStave(index);
383 } else {
384 halfstave = 0; // if not staggered geometry, return 0
385 }
386 halfstave = getHalfStave(index);
387 mod = getModule(index);
388 chip = getChip(index);
389
390 return kTRUE;
391}
392
393//__________________________________________________________________________
395{
396
397 int subDetID, petalcase, disk, layer, stave, halfstave, mod, chip;
398 getChipID(index, subDetID, petalcase, disk, layer, stave, halfstave, mod, chip);
399
400 // PrintChipID(index, subDetID, petalcase, disk, layer, stave, halfstave, mod, chip);
401
402 // TString path = "/cave_1/barrel_1/TRKV_2/TRKLayer0_1/TRKStave0_1/TRKChip0_1/TRKSensor0_1/"; /// dummy path, to be used for tests
403 TString path = Form("/cave_1/barrel_1/%s_2/", GeometryTGeo::getTRKVolPattern());
404
405 // handling cylindrical configuration for ML and/or OT
406 // needed bercause of the different numbering scheme in the geometry for the cylindrical case wrt the staggered and turbo ones
407 if (subDetID == 1) {
408 if ((layer < 4 && mLayoutML == eLayout::kCylinder) || (layer > 3 && mLayoutOL == eLayout::kCylinder)) {
409 stave = 1;
410 mod = 1;
411 chip = 1;
412 }
413 }
414
415 // build the path
416 if (subDetID == 0) { // VD
417 if (disk >= 0) {
418 path += Form("%s_%d_%d/", getTRKPetalAssemblyPattern(), petalcase, petalcase + 1); // PETAL_n
419 path += Form("%s%d_%s%d_1/", getTRKPetalPattern(), petalcase, getTRKPetalDiskPattern(), disk); // PETALCASEx_DISKy_1
420 path += Form("%s%d_%s%d_%s%d_1/", getTRKPetalPattern(), petalcase, getTRKPetalDiskPattern(), disk, getTRKChipPattern(), disk); // PETALCASEx_DISKy_TRKChipy_1
421 path += Form("%s%d_%s%d_%s%d_1/", getTRKPetalPattern(), petalcase, getTRKPetalDiskPattern(), disk, getTRKSensorPattern(), disk); // PETALCASEx_DISKy_TRKSensory_1
422 } else if (layer >= 0) {
423 path += Form("%s_%d_%d/", getTRKPetalAssemblyPattern(), petalcase, petalcase + 1); // PETAL_n
424 path += Form("%s%d_%s%d_1/", getTRKPetalPattern(), petalcase, getTRKPetalLayerPattern(), layer); // PETALCASEx_LAYERy_1
425 // path += Form("%s%d_%s%d_%s%d_1/", getTRKPetalPattern(), petalcase, getTRKPetalLayerPattern(), layer, getTRKStavePattern(), layer); // PETALCASEx_LAYERy_TRKStavey_1
426 path += Form("%s%d_%s%d_%s%d_1/", getTRKPetalPattern(), petalcase, getTRKPetalLayerPattern(), layer, getTRKChipPattern(), layer); // PETALCASEx_LAYERy_TRKChipy_1
427 path += Form("%s%d_%s%d_%s%d_1/", getTRKPetalPattern(), petalcase, getTRKPetalLayerPattern(), layer, getTRKSensorPattern(), layer); // PETALCASEx_LAYERy_TRKSensory_1
428 }
429 } else if (subDetID == 1) { // MLOT
430 path += Form("%s%d_1/", getTRKLayerPattern(), layer); // TRKLayerx_1
431 path += Form("%s%d_%d/", getTRKStavePattern(), layer, stave); // TRKStavex_y
432 if (mNumberOfHalfStaves[layer] == 2) { // staggered geometry
433 path += Form("%s%d_%d/", getTRKHalfStavePattern(), layer, halfstave); // TRKHalfStavex_y
434 }
435 path += Form("%s%d_%d/", getTRKModulePattern(), layer, mod); // TRKModulx_y
436 path += Form("%s%d_%d/", getTRKChipPattern(), layer, chip); // TRKChipx_y
437 path += Form("%s%d_1/", getTRKSensorPattern(), layer); // TRKSensorx_1
438 }
439 return path;
440}
441
442//__________________________________________________________________________
444{
445 // extract matrix transforming from the PHYSICAL sensor frame to global one
446 // Note, the if the effective sensitive layer thickness is smaller than the
447 // total physical sensor tickness, this matrix is biased and connot be used
448 // directly for transformation from sensor frame to global one.
449 // Therefore we need to add a shift
450
451 auto path = getMatrixPath(index);
452
453 static TGeoHMatrix matTmp;
454 gGeoManager->PushPath(); // Preserve the modeler state.
455
456 if (!gGeoManager->cd(path.Data())) {
457 gGeoManager->PopPath();
458 LOG(error) << "Error in cd-ing to " << path.Data();
459 return nullptr;
460 } // end if !gGeoManager
461
462 matTmp = *gGeoManager->GetCurrentMatrix(); // matrix may change after cd
463
464 // RSS
465 // matTmp.Print();
466 // Restore the modeler state.
467 gGeoManager->PopPath();
468
469 static int chipInGlo{0};
470
472 // account for the difference between physical sensitive layer (where charge collection is simulated) and effective sensor thicknesses
473 // in the VD case this will be accounted by specialized functions during the clusterization (following what it is done for ITS3)
474 // this can be done once the right sensor thickness is in place in the geometry
475 // double delta = 0.;
476 // if (getSubDetID(index) == 1){ /// ML/OT
477 // delta = Segmentation::SensorLayerThicknessVD - Segmentation::SiliconTickness;
478 // static TGeoTranslation tra(0., 0.5 * delta, 0.);
479 // matTmp *= tra;
480 // }
481 // std::cout<<"-----"<<std::endl;
482 // matTmp.Print();
483
484 return &matTmp;
485}
486
487//__________________________________________________________________________
489{
490 for (int i = 0; i < mSize; i++) {
491 if (getSubDetID(i) == 0) {
492 continue;
493 }
494 sensorsMLOT.push_back(i);
495 }
496}
497
498//__________________________________________________________________________
500{
501 // fill for every sensor of ML & OT its tracking frame parameters
502 if (!isTrackingFrameCachedMLOT() && !sensorsMLOT.empty()) {
503 size_t newSize = sensorsMLOT.size();
504 mCacheRefXMLOT.resize(newSize);
505 mCacheRefAlphaMLOT.resize(newSize);
506 for (int i = 0; i < newSize; i++) {
507 int sensorId = sensorsMLOT[i];
509 }
510 }
511}
512
513//__________________________________________________________________________
515{
516 if (mSize < 1) {
517 LOG(warning) << "The method Build was not called yet";
518 Build(mask);
519 return;
520 }
521
522 // build matrices
523 if ((mask & o2::math_utils::bit2Mask(o2::math_utils::TransformType::L2G)) && !getCacheL2G().isFilled()) {
524 // Matrices for Local (Sensor!!! rather than the full chip) to Global frame transformation
525 LOGP(info, "Loading {} L2G matrices from TGeo; there are {} matrices", getName(), mSize);
526 auto& cacheL2G = getCacheL2G();
527 cacheL2G.setSize(mSize);
528
529 for (int i = 0; i < mSize; i++) {
530 TGeoHMatrix* hm = extractMatrixSensor(i);
531 cacheL2G.setMatrix(Mat3D(*hm), i);
532 }
533 }
534
535 // build T2L matrices for ML & OT !! VD is yet to be implemented once its geometry will be more refined
536 if ((mask & o2::math_utils::bit2Mask(o2::math_utils::TransformType::T2L)) && !getCacheT2L().isFilled()) {
537 LOGP(info, "Loading {} T2L matrices from TGeo for ML & OT", getName());
538 if (sensorsMLOT.size()) {
539 int m_Size = sensorsMLOT.size();
540 auto& cacheT2L = getCacheT2L();
541 cacheT2L.setSize(m_Size);
542 for (int i = 0; i < m_Size; i++) {
543 int sensorID = sensorsMLOT[i];
544 TGeoHMatrix& hm = createT2LMatrixMLOT(sensorID);
545 cacheT2L.setMatrix(Mat3D(hm), i); // here, sensorIDs from 0 to 374, sensorIDs shifted to 36 !
546 }
547 }
548 }
549
550 // TODO: build matrices for the cases T2L, T2G and T2GRot when needed
551}
552
553//__________________________________________________________________________
554
555#ifdef ENABLE_UPGRADES
556const char* GeometryTGeo::composeSymNameLayer(int d, int layer)
557{
558 return Form("%s/%s%d", composeSymNameTRK(d), getTRKLayerPattern(), layer);
559}
560#endif
561
563{
564 return Form("%s/%s%d", composeSymNameLayer(d, layer), getTRKStavePattern(), layer);
565}
566
568{
569 return Form("%s/%s%d", composeSymNameStave(d, layer), getTRKModulePattern(), layer);
570}
571
573{
574 return Form("%s/%s%d", composeSymNameStave(d, layer), getTRKChipPattern(), layer);
575}
576
578{
579 return Form("%s/%s%d", composeSymNameChip(d, layer), getTRKSensorPattern(), layer);
580}
581
582//__________________________________________________________________________
583int GeometryTGeo::extractVolumeCopy(const char* name, const char* prefix) const
584{
585 TString nms = name;
586 if (!nms.BeginsWith(prefix)) {
587 return -1;
588 }
589 nms.Remove(0, strlen(prefix));
590 if (!isdigit(nms.Data()[0])) {
591 return -1;
592 }
593 return nms.Atoi();
594}
595
596//__________________________________________________________________________
598{
599 int numberOfLayers = 0;
600 TGeoVolume* trkV = gGeoManager->GetVolume(getTRKVolPattern());
601 if (trkV == nullptr) {
602 LOG(fatal) << getName() << " volume " << getTRKVolPattern() << " is not in the geometry";
603 }
604
605 // Loop on all TRKV nodes, count Layer volumes by checking names
606 // Build on the fly layer - wrapper correspondence
607 TObjArray* nodes = trkV->GetNodes();
608 // nodes->Print();
609 int nNodes = nodes->GetEntriesFast();
610 for (int j = 0; j < nNodes; j++) {
611 int lrID = -1;
612 auto nd = dynamic_cast<TGeoNode*>(nodes->At(j));
613 const char* name = nd->GetName();
614 if (strstr(name, getTRKLayerPattern()) != nullptr) {
615 numberOfLayers++;
617 LOG(fatal) << "Failed to extract layer ID from the " << name;
618 }
619 mLayerToWrapper[lrID] = -1; // not wrapped
620 } else if (strstr(name, getTRKWrapVolPattern()) != nullptr) { // this is a wrapper volume, may cointain layers
621 int wrID = -1;
623 LOG(fatal) << "Failed to extract wrapper ID from the " << name;
624 }
625 TObjArray* nodesW = nd->GetNodes();
626 int nNodesW = nodesW->GetEntriesFast();
627
628 for (int jw = 0; jw < nNodesW; jw++) {
629 auto ndW = dynamic_cast<TGeoNode*>(nodesW->At(jw))->GetName();
630 if (strstr(ndW, getTRKLayerPattern()) != nullptr) {
631 if ((lrID = extractVolumeCopy(ndW, GeometryTGeo::getTRKLayerPattern())) < 0) {
632 LOGP(fatal, "Failed to extract layer ID from wrapper volume '{}' from one of its nodes '{}'", name, ndW);
633 }
634 numberOfLayers++;
635 mLayerToWrapper[lrID] = wrID;
636 }
637 }
638 }
639 }
640 return numberOfLayers;
641}
642
643//__________________________________________________________________________
645{
646 int numberOfPetals = 0;
647 TGeoVolume* trkV = gGeoManager->GetVolume(getTRKVolPattern());
648 if (!trkV) {
649 LOGP(fatal, "{} volume {} is not in the geometry", getName(), getTRKVolPattern());
650 return 0;
651 }
652
653 // Loop on all TRKV nodes, count PETAL assemblies and their contents
654 TObjArray* nodes = trkV->GetNodes();
655 if (!nodes) {
656 LOGP(warning, "{} volume has no child nodes", getTRKVolPattern());
657 return 0;
658 }
659
660 LOGP(info, "Searching for petal assemblies in {} (pattern: {})",
662
663 for (int j = 0; j < nodes->GetEntriesFast(); j++) {
664 auto* nd = dynamic_cast<TGeoNode*>(nodes->At(j));
665 const char* name = nd->GetName();
666
667 if (strstr(name, getTRKPetalAssemblyPattern()) != nullptr) {
668 numberOfPetals++;
669 LOGP(info, "Found petal assembly: {}", name);
670
671 // Get petal volume and its nodes for debugging
672 TGeoVolume* petalVol = nd->GetVolume();
673 if (petalVol) {
674 TObjArray* petalNodes = petalVol->GetNodes();
675 if (petalNodes) {
676 LOGP(debug, "Petal {} contains {} child nodes", name, petalNodes->GetEntriesFast());
677 // Print all nodes in this petal
678 for (int k = 0; k < petalNodes->GetEntriesFast(); k++) {
679 auto* petalNode = dynamic_cast<TGeoNode*>(petalNodes->At(k));
680 LOGP(debug, " Node {}: {}", k, petalNode->GetName());
681 }
682 } else {
683 LOGP(warning, "Petal {} has no child nodes", name);
684 }
685 } else {
686 LOGP(warning, "Petal {} has no volume", name);
687 }
688 }
689 }
690
691 if (numberOfPetals == 0) {
692 LOGP(warning, "No petal assemblies found in geometry");
693 } else {
694 LOGP(info, "Found {} petal assemblies", numberOfPetals);
695 }
696
697 return numberOfPetals;
698}
699
700//__________________________________________________________________________
702{
703 // The number of active parts returned here is 36 = 4 petals * (3 layers + 6 disks)
704 int numberOfParts = 0;
705 TGeoVolume* vdV = gGeoManager->GetVolume(getTRKVolPattern());
706 if (!vdV) {
707 LOGP(fatal, "{} volume {} is not in the geometry", getName(), getTRKVolPattern());
708 return 0;
709 }
710
711 // Find first petal to count its active parts
712 TObjArray* nodes = vdV->GetNodes();
713 if (!nodes) {
714 LOGP(warning, "{} volume has no child nodes", getTRKVolPattern());
715 return 0;
716 }
717
718 bool petalFound = false;
719
720 for (int j = 0; j < nodes->GetEntriesFast(); j++) {
721 auto* nd = dynamic_cast<TGeoNode*>(nodes->At(j));
722 const char* name = nd->GetName();
723 if (strstr(name, getTRKPetalAssemblyPattern()) == nullptr) {
724 continue;
725 }
726
727 petalFound = true;
728 LOGP(info, "Counting active parts in petal: {}", name);
729
730 // Found a petal, count its layers and disks
731 TGeoVolume* petalVol = nd->GetVolume();
732 if (!petalVol) {
733 LOGP(warning, "Petal {} has no volume", name);
734 break;
735 }
736
737 TObjArray* petalNodes = petalVol->GetNodes();
738 if (!petalNodes) {
739 LOGP(warning, "Petal {} has no child nodes", name);
740 break;
741 }
742
743 for (int k = 0; k < petalNodes->GetEntriesFast(); k++) {
744 auto* petalNode = dynamic_cast<TGeoNode*>(petalNodes->At(k));
745 const char* nodeName = petalNode->GetName();
746
747 if (strstr(nodeName, getTRKPetalLayerPattern()) != nullptr ||
748 strstr(nodeName, getTRKPetalDiskPattern()) != nullptr) {
749 numberOfParts++;
750 LOGP(debug, "Found active part in {}: {}", name, nodeName);
751 }
752 }
753 // We only need to check one petal as they're identical
754 break;
755 }
756
757 if (!petalFound) {
758 LOGP(warning, "No petal assembly found matching pattern '{}'", getTRKPetalAssemblyPattern());
759 return 0;
760 }
761
762 if (numberOfParts == 0) {
763 LOGP(warning, "No active parts (layers/disks) found in petal");
764 return 0;
765 }
766
767 // Multiply by number of petals since all petals are identical
768 int totalParts = numberOfParts * mNumberOfPetalsVD;
769 LOGP(info, "Total number of active parts: {} ({}*{})",
770 totalParts, numberOfParts, mNumberOfPetalsVD);
771 return totalParts;
772}
773
774//__________________________________________________________________________
776{
777 // Count disks in the first petal (all petals are identical)
778 int numberOfDisks = 0;
779 TGeoVolume* vdV = gGeoManager->GetVolume(getTRKVolPattern());
780 if (!vdV) {
781 LOGP(fatal, "{} volume {} is not in the geometry", getName(), getTRKVolPattern());
782 return 0;
783 }
784
785 // Find first petal
786 TObjArray* nodes = vdV->GetNodes();
787 if (!nodes) {
788 LOGP(warning, "{} volume has no child nodes", getTRKVolPattern());
789 return 0;
790 }
791
792 bool petalFound = false;
793
794 for (int j = 0; j < nodes->GetEntriesFast(); j++) {
795 auto* nd = dynamic_cast<TGeoNode*>(nodes->At(j));
796 if (strstr(nd->GetName(), getTRKPetalAssemblyPattern()) == nullptr) {
797 continue;
798 }
799
800 petalFound = true;
801 LOGP(info, "Counting disks in petal: {}", nd->GetName());
802
803 // Count disks in this petal
804 TGeoVolume* petalVol = nd->GetVolume();
805 if (!petalVol) {
806 LOGP(warning, "Petal {} has no volume", nd->GetName());
807 break;
808 }
809
810 TObjArray* petalNodes = petalVol->GetNodes();
811 if (!petalNodes) {
812 LOGP(warning, "Petal {} has no child nodes", nd->GetName());
813 break;
814 }
815
816 for (int k = 0; k < petalNodes->GetEntriesFast(); k++) {
817 auto* petalNode = dynamic_cast<TGeoNode*>(petalNodes->At(k));
818 if (strstr(petalNode->GetName(), getTRKPetalDiskPattern()) != nullptr) {
819 numberOfDisks++;
820 LOGP(info, "Found disk in {} : {}", nd->GetName(), petalNode->GetName());
821 }
822 }
823 // One petal is enough
824 break;
825 }
826
827 if (!petalFound) {
828 LOGP(warning, "No petal assembly found matching pattern '{}'", getTRKPetalAssemblyPattern());
829 }
830
831 if (numberOfDisks == 0) {
832 LOGP(warning, "No disks found in VD geometry");
833 }
834
835 return numberOfDisks;
836}
837
838//__________________________________________________________________________
840{
841 // Count layers in the first petal (all petals are identical)
842 int numberOfLayers = 0;
843 TGeoVolume* vdV = gGeoManager->GetVolume(getTRKVolPattern());
844 if (!vdV) {
845 LOGP(fatal, "{} volume {} is not in the geometry", getName(), getTRKVolPattern());
846 return 0;
847 }
848
849 // Find first petal
850 TObjArray* nodes = vdV->GetNodes();
851 if (!nodes) {
852 LOGP(warning, "{} volume has no child nodes", getTRKVolPattern());
853 return 0;
854 }
855
856 bool petalFound = false;
857
858 for (int j = 0; j < nodes->GetEntriesFast(); j++) {
859 auto* nd = dynamic_cast<TGeoNode*>(nodes->At(j));
860 if (strstr(nd->GetName(), getTRKPetalAssemblyPattern()) == nullptr) {
861 continue;
862 }
863
864 petalFound = true;
865 LOGP(info, "Counting layers in petal: {}", nd->GetName());
866
867 // Count layers in this petal
868 TGeoVolume* petalVol = nd->GetVolume();
869 if (!petalVol) {
870 LOGP(warning, "Petal {} has no volume", nd->GetName());
871 break;
872 }
873
874 TObjArray* petalNodes = petalVol->GetNodes();
875 if (!petalNodes) {
876 LOGP(warning, "Petal {} has no child nodes", nd->GetName());
877 break;
878 }
879
880 for (int k = 0; k < petalNodes->GetEntriesFast(); k++) {
881 auto* petalNode = dynamic_cast<TGeoNode*>(petalNodes->At(k));
882 if (strstr(petalNode->GetName(), getTRKPetalLayerPattern()) != nullptr) {
883 numberOfLayers++;
884 LOGP(info, "Found layer in {} : {}", nd->GetName(), petalNode->GetName());
885 }
886 }
887 // One petal is enough
888 break;
889 }
890
891 if (!petalFound) {
892 LOGP(warning, "No petal assembly found matching pattern '{}'", getTRKPetalAssemblyPattern());
893 }
894
895 if (numberOfLayers == 0) {
896 LOGP(warning, "No layers found in VD geometry");
897 }
898
899 return numberOfLayers;
900}
901
902//__________________________________________________________________________
904{
905 // The number of chips per petal returned here is 9 for each layer = number of layers + number of quarters of disks per petal
906 int numberOfChips = 0;
907 TGeoVolume* vdV = gGeoManager->GetVolume(getTRKVolPattern());
908 if (!vdV) {
909 LOGP(fatal, "{} volume {} is not in the geometry", getName(), getTRKVolPattern());
910 return 0;
911 }
912
913 // Find first petal assembly
914 TObjArray* nodes = vdV->GetNodes();
915 if (!nodes) {
916 LOGP(warning, "{} volume has no child nodes", getTRKVolPattern());
917 return 0;
918 }
919
920 bool petalFound = false;
921
922 for (int j = 0; j < nodes->GetEntriesFast(); j++) {
923 auto* nd = dynamic_cast<TGeoNode*>(nodes->At(j));
924 const char* name = nd->GetName();
925 if (strstr(name, getTRKPetalAssemblyPattern()) == nullptr) {
926 continue;
927 }
928
929 petalFound = true;
930 LOGP(info, "Counting chips in petal: {}", name);
931
932 // Found a petal, count sensors in its layers and disks
933 TGeoVolume* petalVol = nd->GetVolume();
934 if (!petalVol) {
935 LOGP(warning, "Petal {} has no volume", name);
936 break;
937 }
938
939 TObjArray* petalNodes = petalVol->GetNodes();
940 if (!petalNodes) {
941 LOGP(warning, "Petal {} has no child nodes", name);
942 break;
943 }
944
945 for (int k = 0; k < petalNodes->GetEntriesFast(); k++) {
946 auto* petalNode = dynamic_cast<TGeoNode*>(petalNodes->At(k));
947 const char* nodeName = petalNode->GetName();
948 TGeoVolume* vol = petalNode->GetVolume();
949
950 if (!vol) {
951 LOGP(debug, "Node {} has no volume", nodeName);
952 continue;
953 }
954
955 // Look for sensors in this volume
956 TObjArray* subNodes = vol->GetNodes();
957 if (!subNodes) {
958 LOGP(debug, "Node {} has no sub-nodes", nodeName);
959 continue;
960 }
961
962 for (int i = 0; i < subNodes->GetEntriesFast(); i++) {
963 auto* subNode = dynamic_cast<TGeoNode*>(subNodes->At(i));
964 if (strstr(subNode->GetName(), getTRKChipPattern()) != nullptr) {
965 numberOfChips++;
966 LOGP(debug, "Found chip in {}: {}", nodeName, subNode->GetName());
967 }
968 }
969 }
970 // We only need one petal
971 break;
972 }
973
974 if (!petalFound) {
975 LOGP(warning, "No petal assembly found matching pattern '{}'", getTRKPetalAssemblyPattern());
976 }
977
978 if (numberOfChips == 0) {
979 LOGP(warning, "No chips/sensors found in VD petal");
980 }
981
982 LOGP(info, "Number of chips per petal: {}", numberOfChips);
983 return numberOfChips;
984}
985
986//__________________________________________________________________________
988{
989 int numberOfStaves = 0;
990
991 std::string layName = Form("%s%d", getTRKLayerPattern(), lay);
992 TGeoVolume* layV = gGeoManager->GetVolume(layName.c_str());
993
994 if (layV == nullptr) {
995 LOG(fatal) << getName() << " volume " << getTRKLayerPattern() << " is not in the geometry";
996 }
997
998 // Loop on all layV nodes, count Layer volumes by checking names
999 TObjArray* nodes = layV->GetNodes();
1000 // std::cout << "Printing nodes for layer " << lay << std::endl;
1001 // nodes->Print();
1002 int nNodes = nodes->GetEntriesFast();
1003
1004 for (int j = 0; j < nNodes; j++) {
1005 int lrID = -1;
1006 auto nd = dynamic_cast<TGeoNode*>(nodes->At(j));
1007 const char* name = nd->GetName();
1008 if (strstr(name, getTRKStavePattern()) != nullptr) {
1009 numberOfStaves++;
1010 }
1011 }
1012 return numberOfStaves;
1013}
1014
1015//__________________________________________________________________________
1017{
1018 int numberOfHalfStaves = 0;
1019
1020 std::string staveName = Form("%s%d", getTRKStavePattern(), lay);
1021 TGeoVolume* staveV = gGeoManager->GetVolume(staveName.c_str());
1022
1023 if (staveV == nullptr) {
1024 LOG(fatal) << getName() << " volume " << getTRKStavePattern() << " is not in the geometry";
1025 }
1026
1027 // Loop on all layV nodes, count Layer volumes by checking names
1028 TObjArray* nodes = staveV->GetNodes();
1029 // std::cout << "Printing nodes for layer " << lay << std::endl;
1030 // nodes->Print();
1031 int nNodes = nodes->GetEntriesFast();
1032
1033 for (int j = 0; j < nNodes; j++) {
1034 auto nd = dynamic_cast<TGeoNode*>(nodes->At(j));
1035 const char* name = nd->GetName();
1036 if (strstr(name, getTRKHalfStavePattern()) != nullptr) {
1037 numberOfHalfStaves++;
1038 }
1039 }
1040
1041 if (numberOfHalfStaves == 0) {
1042 numberOfHalfStaves = 1;
1043 }
1044 return numberOfHalfStaves;
1045}
1046
1047//__________________________________________________________________________
1049{
1050 int numberOfModules = 0;
1051
1052 std::string staveName = Form("%s%d", (mNumberOfHalfStaves[lay] == 2 ? getTRKHalfStavePattern() : getTRKStavePattern()), lay);
1053 TGeoVolume* staveV = gGeoManager->GetVolume(staveName.c_str());
1054
1055 if (staveV == nullptr) {
1056 LOG(fatal) << getName() << " volume " << (mNumberOfHalfStaves[lay] == 2 ? getTRKHalfStavePattern() : getTRKStavePattern()) << " is not in the geometry";
1057 }
1058
1059 // Loop on all staveV nodes, count Module volumes by checking names
1060 TObjArray* nodes = staveV->GetNodes();
1061 int nNodes = nodes->GetEntriesFast();
1062
1063 for (int j = 0; j < nNodes; j++) {
1064 auto nd = dynamic_cast<TGeoNode*>(nodes->At(j));
1065 const char* name = nd->GetName();
1066 if (strstr(name, getTRKModulePattern()) != nullptr) {
1067 numberOfModules++;
1068 }
1069 }
1070 return numberOfModules;
1071}
1072
1073//__________________________________________________________________________
1075{
1076 int numberOfChips = 0;
1077
1078 std::string moduleName = Form("%s%d", getTRKModulePattern(), lay);
1079 TGeoVolume* moduleV = gGeoManager->GetVolume(moduleName.c_str());
1080
1081 if (moduleV == nullptr) {
1082 LOG(fatal) << getName() << " volume " << getTRKModulePattern() << " is not in the geometry";
1083 }
1084
1085 // Loop on all moduleV nodes, count Chip volumes by checking names
1086 TObjArray* nodes = moduleV->GetNodes();
1087 int nNodes = nodes->GetEntriesFast();
1088
1089 for (int j = 0; j < nNodes; j++) {
1090 auto nd = dynamic_cast<TGeoNode*>(nodes->At(j));
1091 const char* name = nd->GetName();
1092 if (strstr(name, getTRKChipPattern()) != nullptr) {
1093 numberOfChips++;
1094 }
1095 }
1096 return numberOfChips;
1097}
1098
1099//__________________________________________________________________________
1100void GeometryTGeo::PrintChipID(int index, int subDetID, int petalcase, int disk, int lay, int stave, int halfstave, int mod, int chip) const
1101{
1102 std::cout << "\nindex = " << index << std::endl;
1103 std::cout << "subDetID = " << subDetID << std::endl;
1104 std::cout << "petalcase = " << petalcase << std::endl;
1105 std::cout << "layer = " << lay << std::endl;
1106 std::cout << "disk = " << disk << std::endl;
1107 std::cout << "first chip index = " << getFirstChipIndex(lay, petalcase, subDetID) << std::endl;
1108 std::cout << "stave = " << stave << std::endl;
1109 std::cout << "halfstave = " << halfstave << std::endl;
1110 std::cout << "module = " << mod << std::endl;
1111 std::cout << "chip = " << chip << std::endl;
1112}
1113
1114//__________________________________________________________________________
1115void GeometryTGeo::Print(Option_t*) const
1116{
1117 if (!isBuilt()) {
1118 LOGF(info, "Geometry not built yet!");
1119 return;
1120 }
1121 std::cout << "Detector ID: " << sInstance.get()->getDetID() << std::endl;
1122
1123 LOGF(info, "Summary of GeometryTGeo: %s", getName());
1124 LOGF(info, "Number of layers ML + OL: %d", mNumberOfLayersMLOT);
1125 LOGF(info, "Number of active parts VD: %d", mNumberOfActivePartsVD);
1126 LOGF(info, "Number of layers VD: %d", mNumberOfLayersVD);
1127 LOGF(info, "Number of petals VD: %d", mNumberOfPetalsVD);
1128 LOGF(info, "Number of disks VD: %d", mNumberOfDisksVD);
1129 LOGF(info, "Number of chips per petal VD: ");
1130 for (int i = 0; i < mNumberOfPetalsVD; i++) {
1131 LOGF(info, "%d", mNumberOfChipsPerPetalVD[i]);
1132 }
1133 LOGF(info, "Number of staves and half staves per layer MLOT: ");
1134 for (int i = 0; i < mNumberOfLayersMLOT; i++) {
1135 std::string mlot = "";
1136 mlot = (i < 4) ? "ML" : "OT";
1137 LOGF(info, "Layer: %d, %s, %d staves, %d half staves per stave", i, mlot.c_str(), mNumberOfStaves[i], mNumberOfHalfStaves[i]);
1138 }
1139 LOGF(info, "Number of modules per stave (half stave) in each ML(OT) layer: ");
1140 for (int i = 0; i < mNumberOfLayersMLOT; i++) {
1141 LOGF(info, "%d", mNumberOfModules[i]);
1142 }
1143 LOGF(info, "Number of chips per module MLOT: ");
1144 for (int i = 0; i < mNumberOfLayersMLOT; i++) {
1145 LOGF(info, "%d", mNumberOfChips[i]);
1146 }
1147 LOGF(info, "Number of chips per layer MLOT: ");
1148 for (int i = 0; i < mNumberOfLayersMLOT; i++) {
1149 LOGF(info, "%d", mNumberOfChipsPerLayerMLOT[i]);
1150 }
1151 LOGF(info, "Total number of chips: %d", getNumberOfChips());
1152
1153 std::cout << "mLastChipIndex = [";
1154 for (int i = 0; i < mLastChipIndex.size(); i++) {
1155 std::cout << mLastChipIndex[i];
1156 if (i < mLastChipIndex.size() - 1) {
1157 std::cout << ", ";
1158 }
1159 }
1160 std::cout << "]" << std::endl;
1161 std::cout << "mLastChipIndexVD = [";
1162 for (int i = 0; i < mLastChipIndexVD.size(); i++) {
1163 std::cout << mLastChipIndexVD[i];
1164 if (i < mLastChipIndexVD.size() - 1) {
1165 std::cout << ", ";
1166 }
1167 }
1168 std::cout << "]" << std::endl;
1169}
1170
1171//__________________________________________________________________________
1172int GeometryTGeo::getBarrelLayer(int chipID) const
1173{
1174 // for barrel layers only,
1175 // so it would be consistent with number of layers i.e. from 0 to 10,
1176 // starting from VD0 to OT10;
1177 // skip the disks;
1178
1179 int subDetID = getSubDetID(chipID);
1180 int subLayerID = getLayer(chipID);
1181
1182 if (subDetID < 0 || subDetID > 1) {
1183 LOG(error) << "getBarrelLayer(): Invalid subDetID for barrel: " << subDetID
1184 << ". Expected values are 0 or 1.";
1185 return -1;
1186 }
1187
1188 if (subLayerID < 0 || subLayerID > 7) {
1189 LOG(error) << "getBarrelLayer(): Invalid subLayerID for barrel: " << subDetID
1190 << ". Expected values are between 0 and 7.";
1191 return -1;
1192 }
1193
1194 const int baseOffsets[] = {0, 3};
1195
1196 return baseOffsets[subDetID] + subLayerID;
1197}
1198
1199//__________________________________________________________________________
1200void GeometryTGeo::extractSensorXAlphaMLOT(int chipID, float& x, float& alp)
1201{
1202 // works for ML and OT only, a.k.a flat sensors !!!
1203 double locA[3] = {-100., 0., 0.}, locB[3] = {100., 0., 0.}, gloA[3], gloB[3];
1204 double xp{0}, yp{0};
1205
1206 if (getSubDetID(chipID) == 0) {
1207
1208 LOG(error) << "extractSensorXAlphaMLOT(): VD layers are not supported yet! chipID = " << chipID;
1209 return;
1210
1211 } else { // flat sensors, ML and OT
1212 const TGeoHMatrix* matL2G = extractMatrixSensor(chipID);
1213 matL2G->LocalToMaster(locA, gloA);
1214 matL2G->LocalToMaster(locB, gloB);
1215 double dx = gloB[0] - gloA[0], dy = gloB[1] - gloA[1];
1216 double t = (gloB[0] * dx + gloB[1] * dy) / (dx * dx + dy * dy);
1217 xp = gloB[0] - dx * t;
1218 yp = gloB[1] - dy * t;
1219 }
1220
1221 alp = std::atan2(yp, xp);
1222 x = std::hypot(xp, yp);
1223 o2::math_utils::bringTo02Pi(alp);
1224
1226 // once the VD segmentation is done, VD should be added
1227}
1228
1229//__________________________________________________________________________
1231{
1232 // works only for ML & OT
1233 // for VD is yet to be implemented once we have more refined geometry
1234 if (getSubDetID(chipID) == 0) {
1235
1236 LOG(error) << "createT2LMatrixMLOT(): VD layers are not supported yet! chipID = " << chipID
1237 << "returning dummy values! ";
1238 static TGeoHMatrix dummy;
1239 return dummy;
1240
1241 } else {
1242 static TGeoHMatrix t2l;
1243 t2l.Clear();
1244 float alpha = getSensorRefAlphaMLOT(chipID);
1245 t2l.RotateZ(alpha * TMath::RadToDeg());
1246 const TGeoHMatrix* matL2G = extractMatrixSensor(chipID);
1247 const TGeoHMatrix& matL2Gi = matL2G->Inverse();
1248 t2l.MultiplyLeft(&matL2Gi);
1249 return t2l;
1250 }
1251}
1252
1253} // namespace trk
1254} // namespace o2
std::ostringstream debug
int32_t i
uint32_t j
Definition RawData.h:0
Definition of the SegmentationChipclass.
Static class with identifiers, bitmasks and names for ALICE detectors.
Definition DetID.h:58
const MatrixCache< Mat3D > & getCacheT2L() const
const char * getName() const
int mSize
prebooked number of sensors
const MatrixCache< Mat3D > & getCacheL2G() const
static const char * composeSymNameModule(int d, int layer)
static const char * getTRKPetalDiskPattern()
int getModule(int index) const
static std::string sPetalAssemblyName
static const char * getTRKStavePattern()
int getPetalCase(int index) const
static const char * getTRKChipPattern()
std::vector< int > mNumberOfChipsPerLayerVD
number of chips per layer VD ( = number of petals)
static std::string sVolumeName
int getSubDetID(int index) const
std::array< char, MAXLAYERS > mLayerToWrapper
Layer to wrapper correspondence, not implemented yet.
static const char * composeSymNameChip(int d, int layer)
static std::string sPetalLayerName
static const char * getTRKSensorPattern()
static std::string sStaveName
bool getChipID(int index, int &subDetID, int &petalcase, int &disk, int &lay, int &stave, int &halfstave, int &mod, int &chip) const
std::vector< int > mNumberOfHalfStaves
Number Of Half staves in each stave of the layer in ML/OT.
int extractNumberOfChipsPerPetalVD() const
bool isTrackingFrameCachedMLOT() const
int extractNumberOfHalfStavesMLOT(int lay) const
static const char * getTRKPetalLayerPattern()
int getChip(int index) const
int extractNumberOfLayersMLOT()
Determines the number of active parts in the Geometry.
int extractNumberOfChipsMLOT(int lay) const
std::vector< int > mNumbersOfChipPerDiskVD
numbersOfChipPerDiskVD
std::vector< int > mNumberOfStaves
Number Of Staves per layer in ML/OT.
Int_t mNumberOfPetalsVD
number of Petals = chip in each VD layer
std::vector< int > mNumberOfModules
Number Of Modules per stave (half stave) in ML/OT.
static std::string sPetalName
int extractNumberOfStavesMLOT(int lay) const
float getSensorRefAlphaMLOT(int index) const
static std::string sPetalDiskName
void Print(Option_t *opt="") const
int getLayer(int index) const
std::vector< unsigned short > mLastChipIndexVD
max ID of the detctor in the layer for the VD
static const char * getTRKWrapVolPattern()
std::vector< float > mCacheRefXMLOT
TString getMatrixPath(int index) const
static const char * getTRKPetalAssemblyPattern()
int getNumberOfChips() const
static const char * getTRKLayerPattern()
static std::string sHalfStaveName
eLayout mLayoutML
cache for sensor ref alpha ML and OT
unsigned short getFirstChipIndex(int lay, int petalcase, int subDetID) const
std::vector< int > mNumberOfChips
number of chips per module in ML/OT
o2::math_utils::Transform3D Mat3D
static std::string sWrapperVolumeName
Wrapper volume name, not implemented at the moment.
TGeoHMatrix & createT2LMatrixMLOT(int)
std::vector< float > mCacheRefAlphaMLOT
cache for X of ML and OT
static const char * getTRKHalfStavePattern()
int extractNumberOfLayersVD() const
std::vector< int > mNumberOfChipsPerPetalVD
numbersOfChipPerPetalVD
static std::string sMetalStackName
static std::string sChipName
static std::string sSensorName
void fillMatrixCache(int mask)
std::vector< int > sensorsMLOT
is it owned by the singleton?
static std::string sDeadzoneName
static std::string sLayerName
unsigned short getChipIndex(int subDetID, int petalcase, int disk, int lay, int stave, int halfstave, int mod, int chip) const
int extractNumberOfActivePartsVD() const
void PrintChipID(int index, int subDetID, int petalcase, int disk, int lay, int stave, int halfstave, int mod, int chip) const
static const char * composeSymNameSensor(int d, int layer)
int extractNumberOfModulesMLOT(int lay) const
int extractNumberOfDisksVD() const
static const char * getTRKPetalPattern()
Int_t mNumberOfActivePartsVD
number of layers
std::vector< int > mNumberOfChipsPerLayerMLOT
number of chips per layer MLOT
Int_t mNumberOfDisksVD
number of Disks = 6
std::vector< unsigned short > mLastChipIndexMLOT
max ID of the detctor in the layer for the MLOT
Int_t mNumberOfLayersMLOT
number of layers
static const char * composeSymNameLayer(int d, int layer)
int getStave(int index) const
int getBarrelLayer(int) const
static const char * getTRKVolPattern()
static const char * getTRKModulePattern()
static const char * composeSymNameStave(int d, int layer)
int getDisk(int index) const
int extractNumberOfPetalsVD() const
int extractVolumeCopy(const char *name, const char *prefix) const
Extract number following the prefix in the name string.
std::vector< unsigned short > mLastChipIndex
max ID of the detctor in the petal(VD) or layer(MLOT)
void extractSensorXAlphaMLOT(int, float &, float &)
void Build(int loadTrans)
Int_t mNumberOfLayersVD
number of layers
int getHalfStave(int index) const
GeometryTGeo(bool build=false, int loadTrans=0)
TGeoHMatrix * extractMatrixSensor(int index) const
static std::string sModuleName
GLfloat GLfloat GLfloat alpha
Definition glcorearb.h:279
GLint GLenum GLint x
Definition glcorearb.h:403
GLuint index
Definition glcorearb.h:781
GLuint const GLchar * name
Definition glcorearb.h:781
GLsizei const GLchar *const * path
Definition glcorearb.h:3591
GLenum GLuint GLint GLint layer
Definition glcorearb.h:1310
GLint GLuint mask
Definition glcorearb.h:291
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
static constexpr int L2G
Definition Cartesian.h:54
static constexpr int T2L
Definition Cartesian.h:55
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"