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