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");
111 int numberOfChipsTotal = 0;
190 }
else if (subDetID == 1) {
207 }
else if (subDetID == 1) {
216 int chipsPerModule = Nchip;
217 int chipsPerHalfStave = Nmod * chipsPerModule;
218 int chipsPerStave = Nhs * chipsPerHalfStave;
219 return index / chipsPerStave;
220 }
else if (Nhs == 1) {
221 int chipsPerModule = Nchip;
222 int chipsPerStave = Nmod * chipsPerModule;
223 return index / chipsPerStave;
238 }
else if (subDetID == 1) {
246 int chipsPerModule = Nchip;
247 int chipsPerHalfStave = Nmod * chipsPerModule;
248 int chipsPerStave = Nhs * chipsPerHalfStave;
250 int rem =
index % chipsPerStave;
251 return rem / chipsPerHalfStave;
265 }
else if (subDetID == 1) {
274 int chipsPerModule = Nchip;
275 int chipsPerHalfStave = Nmod * chipsPerModule;
276 int rem =
index % (Nhs * chipsPerHalfStave);
277 rem = rem % chipsPerHalfStave;
278 return rem / chipsPerModule;
279 }
else if (Nhs == 1) {
280 int chipsPerModule = Nchip;
281 int rem =
index % (Nmod * chipsPerModule);
282 return rem / chipsPerModule;
297 }
else if (subDetID == 1) {
306 int chipsPerModule = Nchip;
307 return index % chipsPerModule;
308 }
else if (Nhs == 1) {
309 int chipsPerModule = Nchip;
310 return index % chipsPerModule;
325 }
else if (subDetID == 1) {
331 int chipsPerModule = Nchip;
332 int chipsPerHalfStave = Nmod * chipsPerModule;
333 int chipsPerStave = Nhs * chipsPerHalfStave;
334 return getFirstChipIndex(lay, petalcase, subDetID) + stave * chipsPerStave + halfstave * chipsPerHalfStave + mod * chipsPerModule + chip;
335 }
else if (Nhs == 1) {
336 int chipsPerModule = Nchip;
337 int chipsPerStave = Nmod * chipsPerModule;
338 return getFirstChipIndex(lay, petalcase, subDetID) + stave * chipsPerStave + mod * chipsPerModule + chip;
342 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);
343 return std::numeric_limits<unsigned short>::max();
352 }
else if (subDetID == 1) {
358 int chipsPerModule = Nchip;
359 int chipsPerHalfStave = Nmod * chipsPerModule;
360 int chipsPerStave = Nhs * chipsPerHalfStave;
361 return getFirstChipIndex(lay, -1, subDetID) + stave * chipsPerStave + halfstave * chipsPerHalfStave + mod * chipsPerModule + chip;
362 }
else if (Nhs == 1) {
363 int chipsPerModule = Nchip;
364 int chipsPerStave = Nmod * chipsPerModule;
365 return getFirstChipIndex(lay, -1, subDetID) + stave * chipsPerStave + mod * chipsPerModule + chip;
369 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);
370 return std::numeric_limits<unsigned short>::max();
397 int subDetID, petalcase, disk,
layer, stave, halfstave, mod, chip;
422 }
else if (
layer >= 0) {
429 }
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
float getSensorRefAlphaMLOT(int index) const
static std::string sPetalDiskName
void Print(Option_t *opt="") const
int getLayer(int index) const
std::vector< unsigned short > mLastChipIndexVD
max ID of the detctor in the layer for the VD
static const char * getTRKWrapVolPattern()
std::vector< float > mCacheRefXMLOT
TString getMatrixPath(int index) const
static const char * getTRKPetalAssemblyPattern()
int getNumberOfChips() const
static const char * getTRKLayerPattern()
static std::string sHalfStaveName
eLayout mLayoutML
cache for sensor ref alpha ML and OT
unsigned short getFirstChipIndex(int lay, int petalcase, int subDetID) const
std::vector< int > mNumberOfChips
number of chips per module in ML/OT
o2::math_utils::Transform3D Mat3D
static std::string sWrapperVolumeName
Wrapper volume name, not implemented at the moment.
TGeoHMatrix & createT2LMatrixMLOT(int)
std::vector< float > mCacheRefAlphaMLOT
cache for X of ML and OT
static const char * getTRKHalfStavePattern()
int extractNumberOfLayersVD() const
std::vector< int > mNumberOfChipsPerPetalVD
numbersOfChipPerPetalVD
static std::string sMetalStackName
static std::string sChipName
static std::string sSensorName
void fillMatrixCache(int mask)
std::vector< int > sensorsMLOT
is it owned by the singleton?
static std::string sDeadzoneName
static std::string sLayerName
unsigned short getChipIndex(int subDetID, int petalcase, int disk, int lay, int stave, int halfstave, int mod, int chip) const
int extractNumberOfActivePartsVD() const
void PrintChipID(int index, int subDetID, int petalcase, int disk, int lay, int stave, int halfstave, int mod, int chip) const
static const char * composeSymNameSensor(int d, int layer)
int extractNumberOfModulesMLOT(int lay) const
int extractNumberOfDisksVD() const
static const char * getTRKPetalPattern()
Int_t mNumberOfActivePartsVD
number of layers
std::vector< int > mNumberOfChipsPerLayerMLOT
number of chips per layer MLOT
Int_t mNumberOfDisksVD
number of Disks = 6
std::vector< unsigned short > mLastChipIndexMLOT
max ID of the detctor in the layer for the MLOT
Int_t mNumberOfLayersMLOT
number of layers
static const char * composeSymNameLayer(int d, int layer)
int getStave(int index) const
int getBarrelLayer(int) const
static const char * getTRKVolPattern()
static const char * getTRKModulePattern()
static const char * composeSymNameStave(int d, int layer)
int getDisk(int index) const
int extractNumberOfPetalsVD() const
int extractVolumeCopy(const char *name, const char *prefix) const
Extract number following the prefix in the name string.
std::vector< unsigned short > mLastChipIndex
max ID of the detctor in the petal(VD) or layer(MLOT)
void extractSensorXAlphaMLOT(int, float &, float &)
void Build(int loadTrans)
Int_t mNumberOfLayersVD
number of layers
int getHalfStave(int index) const
GeometryTGeo(bool build=false, int loadTrans=0)
TGeoHMatrix * extractMatrixSensor(int index) const
static std::string sModuleName
GLfloat GLfloat GLfloat alpha
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"