13#include <TGeoManager.h>
25std::unique_ptr<o2::trk::GeometryTGeo> GeometryTGeo::sInstance;
55 LOGP(fatal,
"Invalid use of public constructor: o2::trk::GeometryTGeo instance exists");
72 LOGP(warning,
"Already built");
76 if (gGeoManager ==
nullptr) {
77 LOGP(fatal,
"Geometry is not loaded");
118 int numberOfChipsTotal = 0;
197 }
else if (subDetID == 1) {
214 }
else if (subDetID == 1) {
223 int chipsPerModule = Nchip;
224 int chipsPerHalfStave = Nmod * chipsPerModule;
225 int chipsPerStave = Nhs * chipsPerHalfStave;
226 return index / chipsPerStave;
227 }
else if (Nhs == 1) {
228 int chipsPerModule = Nchip;
229 int chipsPerStave = Nmod * chipsPerModule;
230 return index / chipsPerStave;
245 }
else if (subDetID == 1) {
253 int chipsPerModule = Nchip;
254 int chipsPerHalfStave = Nmod * chipsPerModule;
255 int chipsPerStave = Nhs * chipsPerHalfStave;
257 int rem =
index % chipsPerStave;
258 return rem / chipsPerHalfStave;
272 }
else if (subDetID == 1) {
281 int chipsPerModule = Nchip;
282 int chipsPerHalfStave = Nmod * chipsPerModule;
283 int rem =
index % (Nhs * chipsPerHalfStave);
284 rem = rem % chipsPerHalfStave;
285 return rem / chipsPerModule;
286 }
else if (Nhs == 1) {
287 int chipsPerModule = Nchip;
288 int rem =
index % (Nmod * chipsPerModule);
289 return rem / chipsPerModule;
304 }
else if (subDetID == 1) {
313 int chipsPerModule = Nchip;
314 return index % chipsPerModule;
315 }
else if (Nhs == 1) {
316 int chipsPerModule = Nchip;
317 return index % chipsPerModule;
332 }
else if (subDetID == 1) {
338 int chipsPerModule = Nchip;
339 int chipsPerHalfStave = Nmod * chipsPerModule;
340 int chipsPerStave = Nhs * chipsPerHalfStave;
341 return getFirstChipIndex(lay, petalcase, subDetID) + stave * chipsPerStave + halfstave * chipsPerHalfStave + mod * chipsPerModule + chip;
342 }
else if (Nhs == 1) {
343 int chipsPerModule = Nchip;
344 int chipsPerStave = Nmod * chipsPerModule;
345 return getFirstChipIndex(lay, petalcase, subDetID) + stave * chipsPerStave + mod * chipsPerModule + chip;
349 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);
350 return std::numeric_limits<unsigned short>::max();
359 }
else if (subDetID == 1) {
365 int chipsPerModule = Nchip;
366 int chipsPerHalfStave = Nmod * chipsPerModule;
367 int chipsPerStave = Nhs * chipsPerHalfStave;
368 return getFirstChipIndex(lay, -1, subDetID) + stave * chipsPerStave + halfstave * chipsPerHalfStave + mod * chipsPerModule + chip;
369 }
else if (Nhs == 1) {
370 int chipsPerModule = Nchip;
371 int chipsPerStave = Nmod * chipsPerModule;
372 return getFirstChipIndex(lay, -1, subDetID) + stave * chipsPerStave + mod * chipsPerModule + chip;
376 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);
377 return std::numeric_limits<unsigned short>::max();
404 int subDetID, petalcase, disk,
layer, stave, halfstave, mod, chip;
418 }
else if (
layer >= 0) {
425 }
else if (subDetID == 1) {
453 static TGeoHMatrix matTmp;
454 gGeoManager->PushPath();
456 if (!gGeoManager->cd(
path.Data())) {
457 gGeoManager->PopPath();
458 LOG(error) <<
"Error in cd-ing to " <<
path.Data();
462 matTmp = *gGeoManager->GetCurrentMatrix();
467 gGeoManager->PopPath();
469 static int chipInGlo{0};
506 for (
int i = 0;
i < newSize;
i++) {
517 LOG(warning) <<
"The method Build was not called yet";
525 LOGP(info,
"Loading {} L2G matrices from TGeo; there are {} matrices",
getName(),
mSize);
527 cacheL2G.setSize(
mSize);
531 cacheL2G.setMatrix(
Mat3D(*hm),
i);
537 LOGP(info,
"Loading {} T2L matrices from TGeo for ML & OT",
getName());
541 cacheT2L.setSize(m_Size);
542 for (
int i = 0;
i < m_Size;
i++) {
545 cacheT2L.setMatrix(
Mat3D(hm),
i);
555#ifdef ENABLE_UPGRADES
586 if (!nms.BeginsWith(prefix)) {
589 nms.Remove(0, strlen(prefix));
590 if (!isdigit(nms.Data()[0])) {
599 int numberOfLayers = 0;
601 if (trkV ==
nullptr) {
607 TObjArray*
nodes = trkV->GetNodes();
609 int nNodes =
nodes->GetEntriesFast();
610 for (
int j = 0;
j < nNodes;
j++) {
612 auto nd =
dynamic_cast<TGeoNode*
>(
nodes->At(
j));
613 const char*
name = nd->GetName();
617 LOG(fatal) <<
"Failed to extract layer ID from the " <<
name;
623 LOG(fatal) <<
"Failed to extract wrapper ID from the " <<
name;
625 TObjArray* nodesW = nd->GetNodes();
626 int nNodesW = nodesW->GetEntriesFast();
628 for (
int jw = 0; jw < nNodesW; jw++) {
629 auto ndW =
dynamic_cast<TGeoNode*
>(nodesW->At(jw))->GetName();
632 LOGP(fatal,
"Failed to extract layer ID from wrapper volume '{}' from one of its nodes '{}'",
name, ndW);
640 return numberOfLayers;
646 int numberOfPetals = 0;
654 TObjArray*
nodes = trkV->GetNodes();
660 LOGP(info,
"Searching for petal assemblies in {} (pattern: {})",
663 for (
int j = 0;
j <
nodes->GetEntriesFast();
j++) {
664 auto* nd =
dynamic_cast<TGeoNode*
>(
nodes->At(
j));
665 const char*
name = nd->GetName();
669 LOGP(info,
"Found petal assembly: {}",
name);
672 TGeoVolume* petalVol = nd->GetVolume();
674 TObjArray* petalNodes = petalVol->GetNodes();
676 LOGP(
debug,
"Petal {} contains {} child nodes",
name, petalNodes->GetEntriesFast());
678 for (
int k = 0; k < petalNodes->GetEntriesFast(); k++) {
679 auto* petalNode =
dynamic_cast<TGeoNode*
>(petalNodes->At(k));
680 LOGP(
debug,
" Node {}: {}", k, petalNode->GetName());
683 LOGP(warning,
"Petal {} has no child nodes",
name);
686 LOGP(warning,
"Petal {} has no volume",
name);
691 if (numberOfPetals == 0) {
692 LOGP(warning,
"No petal assemblies found in geometry");
694 LOGP(info,
"Found {} petal assemblies", numberOfPetals);
697 return numberOfPetals;
704 int numberOfParts = 0;
712 TObjArray*
nodes = vdV->GetNodes();
718 bool petalFound =
false;
720 for (
int j = 0;
j <
nodes->GetEntriesFast();
j++) {
721 auto* nd =
dynamic_cast<TGeoNode*
>(
nodes->At(
j));
722 const char*
name = nd->GetName();
728 LOGP(info,
"Counting active parts in petal: {}",
name);
731 TGeoVolume* petalVol = nd->GetVolume();
733 LOGP(warning,
"Petal {} has no volume",
name);
737 TObjArray* petalNodes = petalVol->GetNodes();
739 LOGP(warning,
"Petal {} has no child nodes",
name);
743 for (
int k = 0; k < petalNodes->GetEntriesFast(); k++) {
744 auto* petalNode =
dynamic_cast<TGeoNode*
>(petalNodes->At(k));
745 const char* nodeName = petalNode->GetName();
750 LOGP(
debug,
"Found active part in {}: {}",
name, nodeName);
762 if (numberOfParts == 0) {
763 LOGP(warning,
"No active parts (layers/disks) found in petal");
769 LOGP(info,
"Total number of active parts: {} ({}*{})",
778 int numberOfDisks = 0;
786 TObjArray*
nodes = vdV->GetNodes();
792 bool petalFound =
false;
794 for (
int j = 0;
j <
nodes->GetEntriesFast();
j++) {
795 auto* nd =
dynamic_cast<TGeoNode*
>(
nodes->At(
j));
801 LOGP(info,
"Counting disks in petal: {}", nd->GetName());
804 TGeoVolume* petalVol = nd->GetVolume();
806 LOGP(warning,
"Petal {} has no volume", nd->GetName());
810 TObjArray* petalNodes = petalVol->GetNodes();
812 LOGP(warning,
"Petal {} has no child nodes", nd->GetName());
816 for (
int k = 0; k < petalNodes->GetEntriesFast(); k++) {
817 auto* petalNode =
dynamic_cast<TGeoNode*
>(petalNodes->At(k));
820 LOGP(info,
"Found disk in {} : {}", nd->GetName(), petalNode->GetName());
831 if (numberOfDisks == 0) {
832 LOGP(warning,
"No disks found in VD geometry");
835 return numberOfDisks;
842 int numberOfLayers = 0;
850 TObjArray*
nodes = vdV->GetNodes();
856 bool petalFound =
false;
858 for (
int j = 0;
j <
nodes->GetEntriesFast();
j++) {
859 auto* nd =
dynamic_cast<TGeoNode*
>(
nodes->At(
j));
865 LOGP(info,
"Counting layers in petal: {}", nd->GetName());
868 TGeoVolume* petalVol = nd->GetVolume();
870 LOGP(warning,
"Petal {} has no volume", nd->GetName());
874 TObjArray* petalNodes = petalVol->GetNodes();
876 LOGP(warning,
"Petal {} has no child nodes", nd->GetName());
880 for (
int k = 0; k < petalNodes->GetEntriesFast(); k++) {
881 auto* petalNode =
dynamic_cast<TGeoNode*
>(petalNodes->At(k));
884 LOGP(info,
"Found layer in {} : {}", nd->GetName(), petalNode->GetName());
895 if (numberOfLayers == 0) {
896 LOGP(warning,
"No layers found in VD geometry");
899 return numberOfLayers;
906 int numberOfChips = 0;
914 TObjArray*
nodes = vdV->GetNodes();
920 bool petalFound =
false;
922 for (
int j = 0;
j <
nodes->GetEntriesFast();
j++) {
923 auto* nd =
dynamic_cast<TGeoNode*
>(
nodes->At(
j));
924 const char*
name = nd->GetName();
930 LOGP(info,
"Counting chips in petal: {}",
name);
933 TGeoVolume* petalVol = nd->GetVolume();
935 LOGP(warning,
"Petal {} has no volume",
name);
939 TObjArray* petalNodes = petalVol->GetNodes();
941 LOGP(warning,
"Petal {} has no child nodes",
name);
945 for (
int k = 0; k < petalNodes->GetEntriesFast(); k++) {
946 auto* petalNode =
dynamic_cast<TGeoNode*
>(petalNodes->At(k));
947 const char* nodeName = petalNode->GetName();
948 TGeoVolume* vol = petalNode->GetVolume();
951 LOGP(
debug,
"Node {} has no volume", nodeName);
956 TObjArray* subNodes = vol->GetNodes();
958 LOGP(
debug,
"Node {} has no sub-nodes", nodeName);
962 for (
int i = 0;
i < subNodes->GetEntriesFast();
i++) {
963 auto* subNode =
dynamic_cast<TGeoNode*
>(subNodes->At(
i));
966 LOGP(
debug,
"Found chip in {}: {}", nodeName, subNode->GetName());
978 if (numberOfChips == 0) {
979 LOGP(warning,
"No chips/sensors found in VD petal");
982 LOGP(info,
"Number of chips per petal: {}", numberOfChips);
983 return numberOfChips;
989 int numberOfStaves = 0;
992 TGeoVolume* layV = gGeoManager->GetVolume(layName.c_str());
994 if (layV ==
nullptr) {
999 TObjArray*
nodes = layV->GetNodes();
1002 int nNodes =
nodes->GetEntriesFast();
1004 for (
int j = 0;
j < nNodes;
j++) {
1006 auto nd =
dynamic_cast<TGeoNode*
>(
nodes->At(
j));
1007 const char*
name = nd->GetName();
1012 return numberOfStaves;
1018 int numberOfHalfStaves = 0;
1021 TGeoVolume* staveV = gGeoManager->GetVolume(staveName.c_str());
1023 if (staveV ==
nullptr) {
1028 TObjArray*
nodes = staveV->GetNodes();
1031 int nNodes =
nodes->GetEntriesFast();
1033 for (
int j = 0;
j < nNodes;
j++) {
1034 auto nd =
dynamic_cast<TGeoNode*
>(
nodes->At(
j));
1035 const char*
name = nd->GetName();
1037 numberOfHalfStaves++;
1041 if (numberOfHalfStaves == 0) {
1042 numberOfHalfStaves = 1;
1044 return numberOfHalfStaves;
1050 int numberOfModules = 0;
1053 TGeoVolume* staveV = gGeoManager->GetVolume(staveName.c_str());
1055 if (staveV ==
nullptr) {
1060 TObjArray*
nodes = staveV->GetNodes();
1061 int nNodes =
nodes->GetEntriesFast();
1063 for (
int j = 0;
j < nNodes;
j++) {
1064 auto nd =
dynamic_cast<TGeoNode*
>(
nodes->At(
j));
1065 const char*
name = nd->GetName();
1070 return numberOfModules;
1076 int numberOfChips = 0;
1079 TGeoVolume* moduleV = gGeoManager->GetVolume(moduleName.c_str());
1081 if (moduleV ==
nullptr) {
1086 TObjArray*
nodes = moduleV->GetNodes();
1087 int nNodes =
nodes->GetEntriesFast();
1089 for (
int j = 0;
j < nNodes;
j++) {
1090 auto nd =
dynamic_cast<TGeoNode*
>(
nodes->At(
j));
1091 const char*
name = nd->GetName();
1096 return numberOfChips;
1102 std::cout <<
"\nindex = " <<
index << std::endl;
1103 std::cout <<
"subDetID = " << subDetID << std::endl;
1104 std::cout <<
"petalcase = " << petalcase << std::endl;
1105 std::cout <<
"layer = " << lay << std::endl;
1106 std::cout <<
"disk = " << disk << std::endl;
1107 std::cout <<
"first chip index = " <<
getFirstChipIndex(lay, petalcase, subDetID) << std::endl;
1108 std::cout <<
"stave = " << stave << std::endl;
1109 std::cout <<
"halfstave = " << halfstave << std::endl;
1110 std::cout <<
"module = " << mod << std::endl;
1111 std::cout <<
"chip = " << chip << std::endl;
1118 LOGF(info,
"Geometry not built yet!");
1121 std::cout <<
"Detector ID: " << sInstance.get()->getDetID() << std::endl;
1123 LOGF(info,
"Summary of GeometryTGeo: %s",
getName());
1129 LOGF(info,
"Number of chips per petal VD: ");
1133 LOGF(info,
"Number of staves and half staves per layer MLOT: ");
1135 std::string mlot =
"";
1136 mlot = (
i < 4) ?
"ML" :
"OT";
1139 LOGF(info,
"Number of modules per stave (half stave) in each ML(OT) layer: ");
1143 LOGF(info,
"Number of chips per module MLOT: ");
1147 LOGF(info,
"Number of chips per layer MLOT: ");
1153 std::cout <<
"mLastChipIndex = [";
1160 std::cout <<
"]" << std::endl;
1161 std::cout <<
"mLastChipIndexVD = [";
1168 std::cout <<
"]" << std::endl;
1182 if (subDetID < 0 || subDetID > 1) {
1183 LOG(error) <<
"getBarrelLayer(): Invalid subDetID for barrel: " << subDetID
1184 <<
". Expected values are 0 or 1.";
1188 if (subLayerID < 0 || subLayerID > 7) {
1189 LOG(error) <<
"getBarrelLayer(): Invalid subLayerID for barrel: " << subDetID
1190 <<
". Expected values are between 0 and 7.";
1194 const int baseOffsets[] = {0, 3};
1196 return baseOffsets[subDetID] + subLayerID;
1203 double locA[3] = {-100., 0., 0.}, locB[3] = {100., 0., 0.}, gloA[3], gloB[3];
1204 double xp{0}, yp{0};
1208 LOG(error) <<
"extractSensorXAlphaMLOT(): VD layers are not supported yet! chipID = " << chipID;
1213 matL2G->LocalToMaster(locA, gloA);
1214 matL2G->LocalToMaster(locB, gloB);
1215 double dx = gloB[0] - gloA[0], dy = gloB[1] - gloA[1];
1216 double t = (gloB[0] * dx + gloB[1] * dy) / (dx * dx + dy * dy);
1217 xp = gloB[0] - dx * t;
1218 yp = gloB[1] - dy * t;
1221 alp = std::atan2(yp, xp);
1222 x = std::hypot(xp, yp);
1223 o2::math_utils::bringTo02Pi(alp);
1236 LOG(error) <<
"createT2LMatrixMLOT(): VD layers are not supported yet! chipID = " << chipID
1237 <<
"returning dummy values! ";
1238 static TGeoHMatrix dummy;
1242 static TGeoHMatrix t2l;
1245 t2l.RotateZ(
alpha * TMath::RadToDeg());
1247 const TGeoHMatrix& matL2Gi = matL2G->Inverse();
1248 t2l.MultiplyLeft(&matL2Gi);
Definition of the SegmentationChipclass.
static const TRKBaseParam & Instance()
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
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.
static std::string sServiceVolName
TGeoHMatrix & createT2LMatrixMLOT(int)
std::vector< float > mCacheRefAlphaMLOT
cache for X of ML and OT
static const char * getTRKHalfStavePattern()
int extractNumberOfLayersVD() const
std::vector< int > mNumberOfChipsPerPetalVD
numbersOfChipPerPetalVD
static std::string sMetalStackName
static std::string sChipName
static std::string sSensorName
void fillMatrixCache(int mask)
std::vector< int > sensorsMLOT
is it owned by the singleton?
static std::string sDeadzoneName
static std::string sLayerName
unsigned short getChipIndex(int subDetID, int petalcase, int disk, int lay, int stave, int halfstave, int mod, int chip) const
int extractNumberOfActivePartsVD() const
void PrintChipID(int index, int subDetID, int petalcase, int disk, int lay, int stave, int halfstave, int mod, int chip) const
static const char * composeSymNameSensor(int d, int layer)
int extractNumberOfModulesMLOT(int lay) const
int extractNumberOfDisksVD() const
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
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"