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");
110 int numberOfChipsTotal = 0;
189 }
else if (subDetID == 1) {
206 }
else if (subDetID == 1) {
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;
237 }
else if (subDetID == 1) {
245 int chipsPerModule = Nchip;
246 int chipsPerHalfStave = Nmod * chipsPerModule;
247 int chipsPerStave = Nhs * chipsPerHalfStave;
249 int rem =
index % chipsPerStave;
250 return rem / chipsPerHalfStave;
264 }
else if (subDetID == 1) {
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;
296 }
else if (subDetID == 1) {
305 int chipsPerModule = Nchip;
306 return index % chipsPerModule;
307 }
else if (Nhs == 1) {
308 int chipsPerModule = Nchip;
309 return index % chipsPerModule;
324 }
else if (subDetID == 1) {
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) {
335 int chipsPerModule = Nchip;
336 int chipsPerStave = Nmod * chipsPerModule;
337 return getFirstChipIndex(lay, petalcase, subDetID) + stave * chipsPerStave + mod * chipsPerModule + chip;
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();
351 }
else if (subDetID == 1) {
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) {
362 int chipsPerModule = Nchip;
363 int chipsPerStave = Nmod * chipsPerModule;
364 return getFirstChipIndex(lay, -1, subDetID) + stave * chipsPerStave + mod * chipsPerModule + chip;
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();
396 int subDetID, petalcase, disk,
layer, stave, halfstave, mod, chip;
421 }
else if (
layer >= 0) {
428 }
else if (subDetID == 1) {
452 static TGeoHMatrix matTmp;
453 gGeoManager->PushPath();
455 if (!gGeoManager->cd(
path.Data())) {
456 gGeoManager->PopPath();
457 LOG(error) <<
"Error in cd-ing to " <<
path.Data();
461 matTmp = *gGeoManager->GetCurrentMatrix();
466 gGeoManager->PopPath();
468 static int chipInGlo{0};
505 for (
int i = 0;
i < newSize;
i++) {
516 LOG(warning) <<
"The method Build was not called yet";
524 LOGP(info,
"Loading {} L2G matrices from TGeo; there are {} matrices",
getName(),
mSize);
526 cacheL2G.setSize(
mSize);
530 cacheL2G.setMatrix(
Mat3D(*hm),
i);
536 LOGP(info,
"Loading {} T2L matrices from TGeo for ML & OT",
getName());
540 cacheT2L.setSize(m_Size);
541 for (
int i = 0;
i < m_Size;
i++) {
544 cacheT2L.setMatrix(
Mat3D(hm),
i);
554#ifdef ENABLE_UPGRADES
585 if (!nms.BeginsWith(prefix)) {
588 nms.Remove(0, strlen(prefix));
589 if (!isdigit(nms.Data()[0])) {
598 int numberOfLayers = 0;
600 if (trkV ==
nullptr) {
606 TObjArray*
nodes = trkV->GetNodes();
608 int nNodes =
nodes->GetEntriesFast();
609 for (
int j = 0;
j < nNodes;
j++) {
611 auto nd =
dynamic_cast<TGeoNode*
>(
nodes->At(
j));
612 const char*
name = nd->GetName();
616 LOG(fatal) <<
"Failed to extract layer ID from the " <<
name;
622 LOG(fatal) <<
"Failed to extract wrapper ID from the " <<
name;
624 TObjArray* nodesW = nd->GetNodes();
625 int nNodesW = nodesW->GetEntriesFast();
627 for (
int jw = 0; jw < nNodesW; jw++) {
628 auto ndW =
dynamic_cast<TGeoNode*
>(nodesW->At(jw))->GetName();
631 LOGP(fatal,
"Failed to extract layer ID from wrapper volume '{}' from one of its nodes '{}'",
name, ndW);
639 return numberOfLayers;
645 int numberOfPetals = 0;
653 TObjArray*
nodes = trkV->GetNodes();
659 LOGP(info,
"Searching for petal assemblies in {} (pattern: {})",
662 for (
int j = 0;
j <
nodes->GetEntriesFast();
j++) {
663 auto* nd =
dynamic_cast<TGeoNode*
>(
nodes->At(
j));
664 const char*
name = nd->GetName();
668 LOGP(info,
"Found petal assembly: {}",
name);
671 TGeoVolume* petalVol = nd->GetVolume();
673 TObjArray* petalNodes = petalVol->GetNodes();
675 LOGP(
debug,
"Petal {} contains {} child nodes",
name, petalNodes->GetEntriesFast());
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());
682 LOGP(warning,
"Petal {} has no child nodes",
name);
685 LOGP(warning,
"Petal {} has no volume",
name);
690 if (numberOfPetals == 0) {
691 LOGP(warning,
"No petal assemblies found in geometry");
693 LOGP(info,
"Found {} petal assemblies", numberOfPetals);
696 return numberOfPetals;
703 int numberOfParts = 0;
711 TObjArray*
nodes = vdV->GetNodes();
717 bool petalFound =
false;
719 for (
int j = 0;
j <
nodes->GetEntriesFast();
j++) {
720 auto* nd =
dynamic_cast<TGeoNode*
>(
nodes->At(
j));
721 const char*
name = nd->GetName();
727 LOGP(info,
"Counting active parts in petal: {}",
name);
730 TGeoVolume* petalVol = nd->GetVolume();
732 LOGP(warning,
"Petal {} has no volume",
name);
736 TObjArray* petalNodes = petalVol->GetNodes();
738 LOGP(warning,
"Petal {} has no child nodes",
name);
742 for (
int k = 0; k < petalNodes->GetEntriesFast(); k++) {
743 auto* petalNode =
dynamic_cast<TGeoNode*
>(petalNodes->At(k));
744 const char* nodeName = petalNode->GetName();
749 LOGP(
debug,
"Found active part in {}: {}",
name, nodeName);
761 if (numberOfParts == 0) {
762 LOGP(warning,
"No active parts (layers/disks) found in petal");
768 LOGP(info,
"Total number of active parts: {} ({}*{})",
777 int numberOfDisks = 0;
785 TObjArray*
nodes = vdV->GetNodes();
791 bool petalFound =
false;
793 for (
int j = 0;
j <
nodes->GetEntriesFast();
j++) {
794 auto* nd =
dynamic_cast<TGeoNode*
>(
nodes->At(
j));
800 LOGP(info,
"Counting disks in petal: {}", nd->GetName());
803 TGeoVolume* petalVol = nd->GetVolume();
805 LOGP(warning,
"Petal {} has no volume", nd->GetName());
809 TObjArray* petalNodes = petalVol->GetNodes();
811 LOGP(warning,
"Petal {} has no child nodes", nd->GetName());
815 for (
int k = 0; k < petalNodes->GetEntriesFast(); k++) {
816 auto* petalNode =
dynamic_cast<TGeoNode*
>(petalNodes->At(k));
819 LOGP(info,
"Found disk in {} : {}", nd->GetName(), petalNode->GetName());
830 if (numberOfDisks == 0) {
831 LOGP(warning,
"No disks found in VD geometry");
834 return numberOfDisks;
841 int numberOfLayers = 0;
849 TObjArray*
nodes = vdV->GetNodes();
855 bool petalFound =
false;
857 for (
int j = 0;
j <
nodes->GetEntriesFast();
j++) {
858 auto* nd =
dynamic_cast<TGeoNode*
>(
nodes->At(
j));
864 LOGP(info,
"Counting layers in petal: {}", nd->GetName());
867 TGeoVolume* petalVol = nd->GetVolume();
869 LOGP(warning,
"Petal {} has no volume", nd->GetName());
873 TObjArray* petalNodes = petalVol->GetNodes();
875 LOGP(warning,
"Petal {} has no child nodes", nd->GetName());
879 for (
int k = 0; k < petalNodes->GetEntriesFast(); k++) {
880 auto* petalNode =
dynamic_cast<TGeoNode*
>(petalNodes->At(k));
883 LOGP(info,
"Found layer in {} : {}", nd->GetName(), petalNode->GetName());
894 if (numberOfLayers == 0) {
895 LOGP(warning,
"No layers found in VD geometry");
898 return numberOfLayers;
905 int numberOfChips = 0;
913 TObjArray*
nodes = vdV->GetNodes();
919 bool petalFound =
false;
921 for (
int j = 0;
j <
nodes->GetEntriesFast();
j++) {
922 auto* nd =
dynamic_cast<TGeoNode*
>(
nodes->At(
j));
923 const char*
name = nd->GetName();
929 LOGP(info,
"Counting chips in petal: {}",
name);
932 TGeoVolume* petalVol = nd->GetVolume();
934 LOGP(warning,
"Petal {} has no volume",
name);
938 TObjArray* petalNodes = petalVol->GetNodes();
940 LOGP(warning,
"Petal {} has no child nodes",
name);
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();
950 LOGP(
debug,
"Node {} has no volume", nodeName);
955 TObjArray* subNodes = vol->GetNodes();
957 LOGP(
debug,
"Node {} has no sub-nodes", nodeName);
961 for (
int i = 0;
i < subNodes->GetEntriesFast();
i++) {
962 auto* subNode =
dynamic_cast<TGeoNode*
>(subNodes->At(
i));
965 LOGP(
debug,
"Found chip in {}: {}", nodeName, subNode->GetName());
977 if (numberOfChips == 0) {
978 LOGP(warning,
"No chips/sensors found in VD petal");
981 LOGP(info,
"Number of chips per petal: {}", numberOfChips);
982 return numberOfChips;
988 int numberOfStaves = 0;
991 TGeoVolume* layV = gGeoManager->GetVolume(layName.c_str());
993 if (layV ==
nullptr) {
998 TObjArray*
nodes = layV->GetNodes();
1001 int nNodes =
nodes->GetEntriesFast();
1003 for (
int j = 0;
j < nNodes;
j++) {
1005 auto nd =
dynamic_cast<TGeoNode*
>(
nodes->At(
j));
1006 const char*
name = nd->GetName();
1011 return numberOfStaves;
1017 int numberOfHalfStaves = 0;
1020 TGeoVolume* staveV = gGeoManager->GetVolume(staveName.c_str());
1022 if (staveV ==
nullptr) {
1027 TObjArray*
nodes = staveV->GetNodes();
1030 int nNodes =
nodes->GetEntriesFast();
1032 for (
int j = 0;
j < nNodes;
j++) {
1033 auto nd =
dynamic_cast<TGeoNode*
>(
nodes->At(
j));
1034 const char*
name = nd->GetName();
1036 numberOfHalfStaves++;
1040 if (numberOfHalfStaves == 0) {
1041 numberOfHalfStaves = 1;
1043 return numberOfHalfStaves;
1049 int numberOfModules = 0;
1052 TGeoVolume* staveV = gGeoManager->GetVolume(staveName.c_str());
1054 if (staveV ==
nullptr) {
1059 TObjArray*
nodes = staveV->GetNodes();
1060 int nNodes =
nodes->GetEntriesFast();
1062 for (
int j = 0;
j < nNodes;
j++) {
1063 auto nd =
dynamic_cast<TGeoNode*
>(
nodes->At(
j));
1064 const char*
name = nd->GetName();
1069 return numberOfModules;
1075 int numberOfChips = 0;
1078 TGeoVolume* moduleV = gGeoManager->GetVolume(moduleName.c_str());
1080 if (moduleV ==
nullptr) {
1085 TObjArray*
nodes = moduleV->GetNodes();
1086 int nNodes =
nodes->GetEntriesFast();
1088 for (
int j = 0;
j < nNodes;
j++) {
1089 auto nd =
dynamic_cast<TGeoNode*
>(
nodes->At(
j));
1090 const char*
name = nd->GetName();
1095 return numberOfChips;
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;
1117 LOGF(info,
"Geometry not built yet!");
1120 std::cout <<
"Detector ID: " << sInstance.get()->getDetID() << std::endl;
1122 LOGF(info,
"Summary of GeometryTGeo: %s",
getName());
1128 LOGF(info,
"Number of chips per petal VD: ");
1132 LOGF(info,
"Number of staves and half staves per layer MLOT: ");
1134 std::string mlot =
"";
1135 mlot = (
i < 4) ?
"ML" :
"OT";
1138 LOGF(info,
"Number of modules per stave (half stave) in each ML(OT) layer: ");
1142 LOGF(info,
"Number of chips per module MLOT: ");
1146 LOGF(info,
"Number of chips per layer MLOT: ");
1152 std::cout <<
"mLastChipIndex = [";
1159 std::cout <<
"]" << std::endl;
1160 std::cout <<
"mLastChipIndexVD = [";
1167 std::cout <<
"]" << std::endl;
1181 if (subDetID < 0 || subDetID > 1) {
1182 LOG(error) <<
"getBarrelLayer(): Invalid subDetID for barrel: " << subDetID
1183 <<
". Expected values are 0 or 1.";
1187 if (subLayerID < 0 || subLayerID > 7) {
1188 LOG(error) <<
"getBarrelLayer(): Invalid subLayerID for barrel: " << subDetID
1189 <<
". Expected values are between 0 and 7.";
1193 const int baseOffsets[] = {0, 3};
1195 return baseOffsets[subDetID] + subLayerID;
1202 double locA[3] = {-100., 0., 0.}, locB[3] = {100., 0., 0.}, gloA[3], gloB[3];
1203 double xp{0}, yp{0};
1207 LOG(error) <<
"extractSensorXAlphaMLOT(): VD layers are not supported yet! chipID = " << 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;
1220 alp = std::atan2(yp, xp);
1221 x = std::hypot(xp, yp);
1222 o2::math_utils::bringTo02Pi(alp);
1235 LOG(error) <<
"createT2LMatrixMLOT(): VD layers are not supported yet! chipID = " << chipID
1236 <<
"returning dummy values! ";
1237 static TGeoHMatrix dummy;
1241 static TGeoHMatrix t2l;
1244 t2l.RotateZ(
alpha * TMath::RadToDeg());
1246 const TGeoHMatrix& matL2Gi = matL2G->Inverse();
1247 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.
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"