13#include <TGeoManager.h>
25std::unique_ptr<o2::trk::GeometryTGeo> GeometryTGeo::sInstance;
54 LOGP(fatal,
"Invalid use of public constructor: o2::trk::GeometryTGeo instance exists");
71 LOGP(warning,
"Already built");
75 if (gGeoManager ==
nullptr) {
76 LOGP(fatal,
"Geometry is not loaded");
100 std::cout <<
"Layer MLOT: " <<
i << std::endl;
107 int numberOfChipsTotal = 0;
186 }
else if (subDetID == 1) {
203 }
else if (subDetID == 1) {
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;
234 }
else if (subDetID == 1) {
242 int chipsPerModule = Nchip;
243 int chipsPerHalfStave = Nmod * chipsPerModule;
244 int chipsPerStave = Nhs * chipsPerHalfStave;
246 int rem =
index % chipsPerStave;
247 return rem / chipsPerHalfStave;
261 }
else if (subDetID == 1) {
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;
293 }
else if (subDetID == 1) {
302 int chipsPerModule = Nchip;
303 return index % chipsPerModule;
304 }
else if (Nhs == 1) {
305 int chipsPerModule = Nchip;
306 return index % chipsPerModule;
321 }
else if (subDetID == 1) {
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) {
332 int chipsPerModule = Nchip;
333 int chipsPerStave = Nmod * chipsPerModule;
334 return getFirstChipIndex(lay, petalcase, subDetID) + stave * chipsPerStave + mod * chipsPerModule + chip;
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();
348 }
else if (subDetID == 1) {
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) {
359 int chipsPerModule = Nchip;
360 int chipsPerStave = Nmod * chipsPerModule;
361 return getFirstChipIndex(lay, -1, subDetID) + stave * chipsPerStave + mod * chipsPerModule + chip;
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();
393 int subDetID, petalcase, disk,
layer, stave, halfstave, mod, chip;
407 }
else if (
layer >= 0) {
414 }
else if (subDetID == 1) {
438 static TGeoHMatrix matTmp;
439 gGeoManager->PushPath();
441 if (!gGeoManager->cd(
path.Data())) {
442 gGeoManager->PopPath();
443 LOG(error) <<
"Error in cd-ing to " <<
path.Data();
447 matTmp = *gGeoManager->GetCurrentMatrix();
452 gGeoManager->PopPath();
454 static int chipInGlo{0};
491 for (
int i = 0;
i < newSize;
i++) {
502 LOG(warning) <<
"The method Build was not called yet";
510 LOGP(info,
"Loading {} L2G matrices from TGeo; there are {} matrices",
getName(),
mSize);
512 cacheL2G.setSize(
mSize);
516 cacheL2G.setMatrix(
Mat3D(*hm),
i);
522 LOGP(info,
"Loading {} T2L matrices from TGeo for ML & OT",
getName());
526 cacheT2L.setSize(m_Size);
527 for (
int i = 0;
i < m_Size;
i++) {
530 cacheT2L.setMatrix(
Mat3D(hm),
i);
540#ifdef ENABLE_UPGRADES
571 if (!nms.BeginsWith(prefix)) {
574 nms.Remove(0, strlen(prefix));
575 if (!isdigit(nms.Data()[0])) {
584 int numberOfLayers = 0;
586 if (trkV ==
nullptr) {
592 TObjArray*
nodes = trkV->GetNodes();
594 int nNodes =
nodes->GetEntriesFast();
595 for (
int j = 0;
j < nNodes;
j++) {
597 auto nd =
dynamic_cast<TGeoNode*
>(
nodes->At(
j));
598 const char*
name = nd->GetName();
602 LOG(fatal) <<
"Failed to extract layer ID from the " <<
name;
608 LOG(fatal) <<
"Failed to extract wrapper ID from the " <<
name;
610 TObjArray* nodesW = nd->GetNodes();
611 int nNodesW = nodesW->GetEntriesFast();
613 for (
int jw = 0; jw < nNodesW; jw++) {
614 auto ndW =
dynamic_cast<TGeoNode*
>(nodesW->At(jw))->GetName();
617 LOGP(fatal,
"Failed to extract layer ID from wrapper volume '{}' from one of its nodes '{}'",
name, ndW);
625 return numberOfLayers;
631 int numberOfPetals = 0;
639 TObjArray*
nodes = trkV->GetNodes();
645 LOGP(info,
"Searching for petal assemblies in {} (pattern: {})",
648 for (
int j = 0;
j <
nodes->GetEntriesFast();
j++) {
649 auto* nd =
dynamic_cast<TGeoNode*
>(
nodes->At(
j));
650 const char*
name = nd->GetName();
654 LOGP(info,
"Found petal assembly: {}",
name);
657 TGeoVolume* petalVol = nd->GetVolume();
659 TObjArray* petalNodes = petalVol->GetNodes();
661 LOGP(
debug,
"Petal {} contains {} child nodes",
name, petalNodes->GetEntriesFast());
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());
668 LOGP(warning,
"Petal {} has no child nodes",
name);
671 LOGP(warning,
"Petal {} has no volume",
name);
676 if (numberOfPetals == 0) {
677 LOGP(warning,
"No petal assemblies found in geometry");
679 LOGP(info,
"Found {} petal assemblies", numberOfPetals);
682 return numberOfPetals;
689 int numberOfParts = 0;
697 TObjArray*
nodes = vdV->GetNodes();
703 bool petalFound =
false;
705 for (
int j = 0;
j <
nodes->GetEntriesFast();
j++) {
706 auto* nd =
dynamic_cast<TGeoNode*
>(
nodes->At(
j));
707 const char*
name = nd->GetName();
713 LOGP(info,
"Counting active parts in petal: {}",
name);
716 TGeoVolume* petalVol = nd->GetVolume();
718 LOGP(warning,
"Petal {} has no volume",
name);
722 TObjArray* petalNodes = petalVol->GetNodes();
724 LOGP(warning,
"Petal {} has no child nodes",
name);
728 for (
int k = 0; k < petalNodes->GetEntriesFast(); k++) {
729 auto* petalNode =
dynamic_cast<TGeoNode*
>(petalNodes->At(k));
730 const char* nodeName = petalNode->GetName();
735 LOGP(
debug,
"Found active part in {}: {}",
name, nodeName);
747 if (numberOfParts == 0) {
748 LOGP(warning,
"No active parts (layers/disks) found in petal");
754 LOGP(info,
"Total number of active parts: {} ({}*{})",
763 int numberOfDisks = 0;
771 TObjArray*
nodes = vdV->GetNodes();
777 bool petalFound =
false;
779 for (
int j = 0;
j <
nodes->GetEntriesFast();
j++) {
780 auto* nd =
dynamic_cast<TGeoNode*
>(
nodes->At(
j));
786 LOGP(info,
"Counting disks in petal: {}", nd->GetName());
789 TGeoVolume* petalVol = nd->GetVolume();
791 LOGP(warning,
"Petal {} has no volume", nd->GetName());
795 TObjArray* petalNodes = petalVol->GetNodes();
797 LOGP(warning,
"Petal {} has no child nodes", nd->GetName());
801 for (
int k = 0; k < petalNodes->GetEntriesFast(); k++) {
802 auto* petalNode =
dynamic_cast<TGeoNode*
>(petalNodes->At(k));
805 LOGP(info,
"Found disk in {} : {}", nd->GetName(), petalNode->GetName());
816 if (numberOfDisks == 0) {
817 LOGP(warning,
"No disks found in VD geometry");
820 return numberOfDisks;
827 int numberOfLayers = 0;
835 TObjArray*
nodes = vdV->GetNodes();
841 bool petalFound =
false;
843 for (
int j = 0;
j <
nodes->GetEntriesFast();
j++) {
844 auto* nd =
dynamic_cast<TGeoNode*
>(
nodes->At(
j));
850 LOGP(info,
"Counting layers in petal: {}", nd->GetName());
853 TGeoVolume* petalVol = nd->GetVolume();
855 LOGP(warning,
"Petal {} has no volume", nd->GetName());
859 TObjArray* petalNodes = petalVol->GetNodes();
861 LOGP(warning,
"Petal {} has no child nodes", nd->GetName());
865 for (
int k = 0; k < petalNodes->GetEntriesFast(); k++) {
866 auto* petalNode =
dynamic_cast<TGeoNode*
>(petalNodes->At(k));
869 LOGP(info,
"Found layer in {} : {}", nd->GetName(), petalNode->GetName());
880 if (numberOfLayers == 0) {
881 LOGP(warning,
"No layers found in VD geometry");
884 return numberOfLayers;
891 int numberOfChips = 0;
899 TObjArray*
nodes = vdV->GetNodes();
905 bool petalFound =
false;
907 for (
int j = 0;
j <
nodes->GetEntriesFast();
j++) {
908 auto* nd =
dynamic_cast<TGeoNode*
>(
nodes->At(
j));
909 const char*
name = nd->GetName();
915 LOGP(info,
"Counting chips in petal: {}",
name);
918 TGeoVolume* petalVol = nd->GetVolume();
920 LOGP(warning,
"Petal {} has no volume",
name);
924 TObjArray* petalNodes = petalVol->GetNodes();
926 LOGP(warning,
"Petal {} has no child nodes",
name);
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();
936 LOGP(
debug,
"Node {} has no volume", nodeName);
941 TObjArray* subNodes = vol->GetNodes();
943 LOGP(
debug,
"Node {} has no sub-nodes", nodeName);
947 for (
int i = 0;
i < subNodes->GetEntriesFast();
i++) {
948 auto* subNode =
dynamic_cast<TGeoNode*
>(subNodes->At(
i));
951 LOGP(
debug,
"Found sensor in {}: {}", nodeName, subNode->GetName());
963 if (numberOfChips == 0) {
964 LOGP(warning,
"No chips/sensors found in VD petal");
967 LOGP(info,
"Number of chips per petal: {}", numberOfChips);
968 return numberOfChips;
974 int numberOfStaves = 0;
977 TGeoVolume* layV = gGeoManager->GetVolume(layName.c_str());
979 if (layV ==
nullptr) {
984 TObjArray*
nodes = layV->GetNodes();
987 int nNodes =
nodes->GetEntriesFast();
989 for (
int j = 0;
j < nNodes;
j++) {
991 auto nd =
dynamic_cast<TGeoNode*
>(
nodes->At(
j));
992 const char*
name = nd->GetName();
997 return numberOfStaves;
1003 int numberOfHalfStaves = 0;
1006 TGeoVolume* staveV = gGeoManager->GetVolume(staveName.c_str());
1008 if (staveV ==
nullptr) {
1013 TObjArray*
nodes = staveV->GetNodes();
1016 int nNodes =
nodes->GetEntriesFast();
1018 for (
int j = 0;
j < nNodes;
j++) {
1019 auto nd =
dynamic_cast<TGeoNode*
>(
nodes->At(
j));
1020 const char*
name = nd->GetName();
1022 numberOfHalfStaves++;
1026 if (numberOfHalfStaves == 0) {
1027 numberOfHalfStaves = 1;
1029 return numberOfHalfStaves;
1035 int numberOfModules = 0;
1038 TGeoVolume* staveV = gGeoManager->GetVolume(staveName.c_str());
1040 if (staveV ==
nullptr) {
1045 TObjArray*
nodes = staveV->GetNodes();
1046 int nNodes =
nodes->GetEntriesFast();
1048 for (
int j = 0;
j < nNodes;
j++) {
1049 auto nd =
dynamic_cast<TGeoNode*
>(
nodes->At(
j));
1050 const char*
name = nd->GetName();
1055 return numberOfModules;
1061 int numberOfChips = 0;
1064 TGeoVolume* moduleV = gGeoManager->GetVolume(moduleName.c_str());
1066 if (moduleV ==
nullptr) {
1071 TObjArray*
nodes = moduleV->GetNodes();
1072 int nNodes =
nodes->GetEntriesFast();
1074 for (
int j = 0;
j < nNodes;
j++) {
1075 auto nd =
dynamic_cast<TGeoNode*
>(
nodes->At(
j));
1076 const char*
name = nd->GetName();
1081 return numberOfChips;
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;
1103 LOGF(info,
"Geometry not built yet!");
1106 std::cout <<
"Detector ID: " << sInstance.get()->getDetID() << std::endl;
1108 LOGF(info,
"Summary of GeometryTGeo: %s",
getName());
1114 LOGF(info,
"Number of chips per petal VD: ");
1118 LOGF(info,
"Number of staves and half staves per layer MLOT: ");
1120 std::string mlot =
"";
1121 mlot = (
i < 4) ?
"ML" :
"OT";
1124 LOGF(info,
"Number of modules per layer MLOT: ");
1128 LOGF(info,
"Number of chips per module MLOT: ");
1132 LOGF(info,
"Number of chips per layer MLOT: ");
1138 std::cout <<
"mLastChipIndex = [";
1145 std::cout <<
"]" << std::endl;
1146 std::cout <<
"mLastChipIndexVD = [";
1153 std::cout <<
"]" << std::endl;
1167 if (subDetID < 0 || subDetID > 1) {
1168 LOG(error) <<
"getBarrelLayer(): Invalid subDetID for barrel: " << subDetID
1169 <<
". Expected values are 0 or 1.";
1173 if (subLayerID < 0 || subLayerID > 7) {
1174 LOG(error) <<
"getBarrelLayer(): Invalid subLayerID for barrel: " << subDetID
1175 <<
". Expected values are between 0 and 7.";
1179 const int baseOffsets[] = {0, 3};
1181 return baseOffsets[subDetID] + subLayerID;
1188 double locA[3] = {-100., 0., 0.}, locB[3] = {100., 0., 0.}, gloA[3], gloB[3];
1189 double xp{0}, yp{0};
1193 LOG(error) <<
"extractSensorXAlphaMLOT(): VD layers are not supported yet! chipID = " << 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;
1206 alp = std::atan2(yp, xp);
1207 x = std::hypot(xp, yp);
1208 o2::math_utils::bringTo02Pi(alp);
1221 LOG(error) <<
"createT2LMatrixMLOT(): VD layers are not supported yet! chipID = " << chipID
1222 <<
"returning dummy values! ";
1223 static TGeoHMatrix dummy;
1227 static TGeoHMatrix t2l;
1230 t2l.RotateZ(
alpha * TMath::RadToDeg());
1232 const TGeoHMatrix& matL2Gi = matL2G->Inverse();
1233 t2l.MultiplyLeft(&matL2Gi);
Definition of the SegmentationChipclass.
Static class with identifiers, bitmasks and names for ALICE detectors.
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
void fillTrackingFramesCacheMLOT()
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
GLuint const GLchar * name
GLsizei const GLchar *const * path
GLenum GLuint GLint GLint layer
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"