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