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