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