13#include <TGeoManager.h>
26std::unique_ptr<o2::trk::GeometryTGeo> GeometryTGeo::sInstance;
56 LOGP(fatal,
"Invalid use of public constructor: o2::trk::GeometryTGeo instance exists");
73 LOGP(warning,
"Already built");
77 if (gGeoManager ==
nullptr) {
78 LOGP(fatal,
"Geometry is not loaded");
119 int numberOfChipsTotal = 0;
198 }
else if (subDetID == 1) {
224 }
else if (subDetID == 1) {
233 int chipsPerModule = Nchip;
234 int chipsPerHalfStave = Nmod * chipsPerModule;
235 int chipsPerStave = Nhs * chipsPerHalfStave;
236 return index / chipsPerStave;
237 }
else if (Nhs == 1) {
238 int chipsPerModule = Nchip;
239 int chipsPerStave = Nmod * chipsPerModule;
240 return index / chipsPerStave;
255 }
else if (subDetID == 1) {
263 int chipsPerModule = Nchip;
264 int chipsPerHalfStave = Nmod * chipsPerModule;
265 int chipsPerStave = Nhs * chipsPerHalfStave;
267 int rem =
index % chipsPerStave;
268 return rem / chipsPerHalfStave;
282 }
else if (subDetID == 1) {
291 int chipsPerModule = Nchip;
292 int chipsPerHalfStave = Nmod * chipsPerModule;
293 int rem =
index % (Nhs * chipsPerHalfStave);
294 rem = rem % chipsPerHalfStave;
295 return rem / chipsPerModule;
296 }
else if (Nhs == 1) {
297 int chipsPerModule = Nchip;
298 int rem =
index % (Nmod * chipsPerModule);
299 return rem / chipsPerModule;
314 }
else if (subDetID == 1) {
323 int chipsPerModule = Nchip;
324 return index % chipsPerModule;
325 }
else if (Nhs == 1) {
326 int chipsPerModule = Nchip;
327 return index % chipsPerModule;
342 }
else if (subDetID == 1) {
348 int chipsPerModule = Nchip;
349 int chipsPerHalfStave = Nmod * chipsPerModule;
350 int chipsPerStave = Nhs * chipsPerHalfStave;
351 return getFirstChipIndex(lay, petalcase, subDetID) + stave * chipsPerStave + halfstave * chipsPerHalfStave + mod * chipsPerModule + chip;
352 }
else if (Nhs == 1) {
353 int chipsPerModule = Nchip;
354 int chipsPerStave = Nmod * chipsPerModule;
355 return getFirstChipIndex(lay, petalcase, subDetID) + stave * chipsPerStave + mod * chipsPerModule + chip;
359 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);
360 return std::numeric_limits<unsigned short>::max();
369 }
else if (subDetID == 1) {
375 int chipsPerModule = Nchip;
376 int chipsPerHalfStave = Nmod * chipsPerModule;
377 int chipsPerStave = Nhs * chipsPerHalfStave;
378 return getFirstChipIndex(lay, -1, subDetID) + stave * chipsPerStave + halfstave * chipsPerHalfStave + mod * chipsPerModule + chip;
379 }
else if (Nhs == 1) {
380 int chipsPerModule = Nchip;
381 int chipsPerStave = Nmod * chipsPerModule;
382 return getFirstChipIndex(lay, -1, subDetID) + stave * chipsPerStave + mod * chipsPerModule + chip;
386 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);
387 return std::numeric_limits<unsigned short>::max();
414 int subDetID, petalcase, disk,
layer, stave, halfstave, mod, chip;
428 }
else if (
layer >= 0) {
435 }
else if (subDetID == 1) {
463 static TGeoHMatrix matTmp;
464 gGeoManager->PushPath();
466 if (!gGeoManager->cd(
path.Data())) {
467 gGeoManager->PopPath();
468 LOG(error) <<
"Error in cd-ing to " <<
path.Data();
472 matTmp = *gGeoManager->GetCurrentMatrix();
477 gGeoManager->PopPath();
479 static int chipInGlo{0};
516 for (
int i = 0;
i < newSize;
i++) {
527 LOG(warning) <<
"The method Build was not called yet";
535 LOGP(info,
"Loading {} L2G matrices from TGeo; there are {} matrices",
getName(),
mSize);
537 cacheL2G.setSize(
mSize);
541 cacheL2G.setMatrix(
Mat3D(*hm),
i);
547 LOGP(info,
"Loading {} T2L matrices from TGeo for ML & OT",
getName());
551 cacheT2L.setSize(m_Size);
552 for (
int i = 0;
i < m_Size;
i++) {
555 cacheT2L.setMatrix(
Mat3D(hm),
i);
565#ifdef ENABLE_UPGRADES
596 if (!nms.BeginsWith(prefix)) {
599 nms.Remove(0, strlen(prefix));
600 if (!isdigit(nms.Data()[0])) {
609 int numberOfLayers = 0;
611 if (trkV ==
nullptr) {
617 TObjArray*
nodes = trkV->GetNodes();
619 int nNodes =
nodes->GetEntriesFast();
620 for (
int j = 0;
j < nNodes;
j++) {
622 auto nd =
dynamic_cast<TGeoNode*
>(
nodes->At(
j));
623 const char*
name = nd->GetName();
627 LOG(fatal) <<
"Failed to extract layer ID from the " <<
name;
633 LOG(fatal) <<
"Failed to extract wrapper ID from the " <<
name;
635 TObjArray* nodesW = nd->GetNodes();
636 int nNodesW = nodesW->GetEntriesFast();
638 for (
int jw = 0; jw < nNodesW; jw++) {
639 auto ndW =
dynamic_cast<TGeoNode*
>(nodesW->At(jw))->GetName();
642 LOGP(fatal,
"Failed to extract layer ID from wrapper volume '{}' from one of its nodes '{}'",
name, ndW);
650 return numberOfLayers;
656 int numberOfPetals = 0;
664 TObjArray*
nodes = trkV->GetNodes();
670 LOGP(info,
"Searching for petal assemblies in {} (pattern: {})",
673 for (
int j = 0;
j <
nodes->GetEntriesFast();
j++) {
674 auto* nd =
dynamic_cast<TGeoNode*
>(
nodes->At(
j));
675 const char*
name = nd->GetName();
679 LOGP(info,
"Found petal assembly: {}",
name);
682 TGeoVolume* petalVol = nd->GetVolume();
684 TObjArray* petalNodes = petalVol->GetNodes();
686 LOGP(
debug,
"Petal {} contains {} child nodes",
name, petalNodes->GetEntriesFast());
688 for (
int k = 0; k < petalNodes->GetEntriesFast(); k++) {
689 auto* petalNode =
dynamic_cast<TGeoNode*
>(petalNodes->At(k));
690 LOGP(
debug,
" Node {}: {}", k, petalNode->GetName());
693 LOGP(warning,
"Petal {} has no child nodes",
name);
696 LOGP(warning,
"Petal {} has no volume",
name);
701 if (numberOfPetals == 0) {
702 LOGP(warning,
"No petal assemblies found in geometry");
704 LOGP(info,
"Found {} petal assemblies", numberOfPetals);
707 return numberOfPetals;
714 int numberOfParts = 0;
722 TObjArray*
nodes = vdV->GetNodes();
728 bool petalFound =
false;
730 for (
int j = 0;
j <
nodes->GetEntriesFast();
j++) {
731 auto* nd =
dynamic_cast<TGeoNode*
>(
nodes->At(
j));
732 const char*
name = nd->GetName();
738 LOGP(info,
"Counting active parts in petal: {}",
name);
741 TGeoVolume* petalVol = nd->GetVolume();
743 LOGP(warning,
"Petal {} has no volume",
name);
747 TObjArray* petalNodes = petalVol->GetNodes();
749 LOGP(warning,
"Petal {} has no child nodes",
name);
753 for (
int k = 0; k < petalNodes->GetEntriesFast(); k++) {
754 auto* petalNode =
dynamic_cast<TGeoNode*
>(petalNodes->At(k));
755 const char* nodeName = petalNode->GetName();
760 LOGP(
debug,
"Found active part in {}: {}",
name, nodeName);
772 if (numberOfParts == 0) {
773 LOGP(warning,
"No active parts (layers/disks) found in petal");
779 LOGP(info,
"Total number of active parts: {} ({}*{})",
788 int numberOfDisks = 0;
796 TObjArray*
nodes = vdV->GetNodes();
802 bool petalFound =
false;
804 for (
int j = 0;
j <
nodes->GetEntriesFast();
j++) {
805 auto* nd =
dynamic_cast<TGeoNode*
>(
nodes->At(
j));
811 LOGP(info,
"Counting disks in petal: {}", nd->GetName());
814 TGeoVolume* petalVol = nd->GetVolume();
816 LOGP(warning,
"Petal {} has no volume", nd->GetName());
820 TObjArray* petalNodes = petalVol->GetNodes();
822 LOGP(warning,
"Petal {} has no child nodes", nd->GetName());
826 for (
int k = 0; k < petalNodes->GetEntriesFast(); k++) {
827 auto* petalNode =
dynamic_cast<TGeoNode*
>(petalNodes->At(k));
830 LOGP(info,
"Found disk in {} : {}", nd->GetName(), petalNode->GetName());
841 if (numberOfDisks == 0) {
842 LOGP(warning,
"No disks found in VD geometry");
845 return numberOfDisks;
852 int numberOfLayers = 0;
860 TObjArray*
nodes = vdV->GetNodes();
866 bool petalFound =
false;
868 for (
int j = 0;
j <
nodes->GetEntriesFast();
j++) {
869 auto* nd =
dynamic_cast<TGeoNode*
>(
nodes->At(
j));
875 LOGP(info,
"Counting layers in petal: {}", nd->GetName());
878 TGeoVolume* petalVol = nd->GetVolume();
880 LOGP(warning,
"Petal {} has no volume", nd->GetName());
884 TObjArray* petalNodes = petalVol->GetNodes();
886 LOGP(warning,
"Petal {} has no child nodes", nd->GetName());
890 for (
int k = 0; k < petalNodes->GetEntriesFast(); k++) {
891 auto* petalNode =
dynamic_cast<TGeoNode*
>(petalNodes->At(k));
894 LOGP(info,
"Found layer in {} : {}", nd->GetName(), petalNode->GetName());
905 if (numberOfLayers == 0) {
906 LOGP(warning,
"No layers found in VD geometry");
909 return numberOfLayers;
916 int numberOfChips = 0;
924 TObjArray*
nodes = vdV->GetNodes();
930 bool petalFound =
false;
932 for (
int j = 0;
j <
nodes->GetEntriesFast();
j++) {
933 auto* nd =
dynamic_cast<TGeoNode*
>(
nodes->At(
j));
934 const char*
name = nd->GetName();
940 LOGP(info,
"Counting chips in petal: {}",
name);
943 TGeoVolume* petalVol = nd->GetVolume();
945 LOGP(warning,
"Petal {} has no volume",
name);
949 TObjArray* petalNodes = petalVol->GetNodes();
951 LOGP(warning,
"Petal {} has no child nodes",
name);
955 for (
int k = 0; k < petalNodes->GetEntriesFast(); k++) {
956 auto* petalNode =
dynamic_cast<TGeoNode*
>(petalNodes->At(k));
957 const char* nodeName = petalNode->GetName();
958 TGeoVolume* vol = petalNode->GetVolume();
961 LOGP(
debug,
"Node {} has no volume", nodeName);
966 TObjArray* subNodes = vol->GetNodes();
968 LOGP(
debug,
"Node {} has no sub-nodes", nodeName);
972 for (
int i = 0;
i < subNodes->GetEntriesFast();
i++) {
973 auto* subNode =
dynamic_cast<TGeoNode*
>(subNodes->At(
i));
976 LOGP(
debug,
"Found chip in {}: {}", nodeName, subNode->GetName());
988 if (numberOfChips == 0) {
989 LOGP(warning,
"No chips/sensors found in VD petal");
992 LOGP(info,
"Number of chips per petal: {}", numberOfChips);
993 return numberOfChips;
999 int numberOfStaves = 0;
1002 TGeoVolume* layV = gGeoManager->GetVolume(layName.c_str());
1004 if (layV ==
nullptr) {
1009 TObjArray*
nodes = layV->GetNodes();
1012 int nNodes =
nodes->GetEntriesFast();
1014 for (
int j = 0;
j < nNodes;
j++) {
1016 auto nd =
dynamic_cast<TGeoNode*
>(
nodes->At(
j));
1017 const char*
name = nd->GetName();
1022 return numberOfStaves;
1028 int numberOfHalfStaves = 0;
1031 TGeoVolume* staveV = gGeoManager->GetVolume(staveName.c_str());
1033 if (staveV ==
nullptr) {
1038 TObjArray*
nodes = staveV->GetNodes();
1041 int nNodes =
nodes->GetEntriesFast();
1043 for (
int j = 0;
j < nNodes;
j++) {
1044 auto nd =
dynamic_cast<TGeoNode*
>(
nodes->At(
j));
1045 const char*
name = nd->GetName();
1047 numberOfHalfStaves++;
1051 if (numberOfHalfStaves == 0) {
1052 numberOfHalfStaves = 1;
1054 return numberOfHalfStaves;
1060 int numberOfModules = 0;
1063 TGeoVolume* staveV = gGeoManager->GetVolume(staveName.c_str());
1065 if (staveV ==
nullptr) {
1070 TObjArray*
nodes = staveV->GetNodes();
1071 int nNodes =
nodes->GetEntriesFast();
1073 for (
int j = 0;
j < nNodes;
j++) {
1074 auto nd =
dynamic_cast<TGeoNode*
>(
nodes->At(
j));
1075 const char*
name = nd->GetName();
1080 return numberOfModules;
1086 int numberOfChips = 0;
1089 TGeoVolume* moduleV = gGeoManager->GetVolume(moduleName.c_str());
1091 if (moduleV ==
nullptr) {
1096 TObjArray*
nodes = moduleV->GetNodes();
1097 int nNodes =
nodes->GetEntriesFast();
1099 for (
int j = 0;
j < nNodes;
j++) {
1100 auto nd =
dynamic_cast<TGeoNode*
>(
nodes->At(
j));
1101 const char*
name = nd->GetName();
1106 return numberOfChips;
1112 std::cout <<
"\nindex = " <<
index << std::endl;
1113 std::cout <<
"subDetID = " << subDetID << std::endl;
1114 std::cout <<
"petalcase = " << petalcase << std::endl;
1115 std::cout <<
"layer = " << lay << std::endl;
1116 std::cout <<
"disk = " << disk << std::endl;
1117 std::cout <<
"first chip index = " <<
getFirstChipIndex(lay, petalcase, subDetID) << std::endl;
1118 std::cout <<
"stave = " << stave << std::endl;
1119 std::cout <<
"halfstave = " << halfstave << std::endl;
1120 std::cout <<
"module = " << mod << std::endl;
1121 std::cout <<
"chip = " << chip << std::endl;
1128 LOGF(info,
"Geometry not built yet!");
1131 std::cout <<
"Detector ID: " << sInstance.get()->getDetID() << std::endl;
1133 LOGF(info,
"Summary of GeometryTGeo: %s",
getName());
1139 LOGF(info,
"Number of chips per petal VD: ");
1143 LOGF(info,
"Number of staves and half staves per layer MLOT: ");
1145 std::string mlot =
"";
1149 LOGF(info,
"Number of modules per stave (half stave) in each ML(OT) layer: ");
1153 LOGF(info,
"Number of chips per module MLOT: ");
1157 LOGF(info,
"Number of chips per layer MLOT: ");
1163 std::cout <<
"mLastChipIndex = [";
1170 std::cout <<
"]" << std::endl;
1171 std::cout <<
"mLastChipIndexVD = [";
1178 std::cout <<
"]" << std::endl;
1192 if (subDetID < 0 || subDetID > 1) {
1193 LOG(error) <<
"getBarrelLayer(): Invalid subDetID for barrel: " << subDetID
1194 <<
". Expected values are 0 or 1.";
1198 if (subLayerID < 0 || subLayerID > 7) {
1199 LOG(error) <<
"getBarrelLayer(): Invalid subLayerID for barrel: " << subDetID
1200 <<
". Expected values are between 0 and 7.";
1204 const int baseOffsets[] = {0, 3};
1206 return baseOffsets[subDetID] + subLayerID;
1213 double locA[3] = {-100., 0., 0.}, locB[3] = {100., 0., 0.}, gloA[3], gloB[3];
1214 double xp{0}, yp{0};
1218 LOG(error) <<
"extractSensorXAlphaMLOT(): VD layers are not supported yet! chipID = " << chipID;
1223 matL2G->LocalToMaster(locA, gloA);
1224 matL2G->LocalToMaster(locB, gloB);
1225 double dx = gloB[0] - gloA[0], dy = gloB[1] - gloA[1];
1226 double t = (gloB[0] * dx + gloB[1] * dy) / (dx * dx + dy * dy);
1227 xp = gloB[0] - dx * t;
1228 yp = gloB[1] - dy * t;
1231 alp = std::atan2(yp, xp);
1232 x = std::hypot(xp, yp);
1233 o2::math_utils::bringTo02Pi(alp);
1246 LOG(error) <<
"createT2LMatrixMLOT(): VD layers are not supported yet! chipID = " << chipID
1247 <<
"returning dummy values! ";
1248 static TGeoHMatrix dummy;
1252 static TGeoHMatrix t2l;
1255 t2l.RotateZ(
alpha * TMath::RadToDeg());
1257 const TGeoHMatrix& matL2Gi = matL2G->Inverse();
1258 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
local layer index within the sub-detector (0-based per VD/MLOT)
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
int getLayerTRK(int index) const
global layer index across the full TRK (VD layers 0..nVD-1, MLOT layers nVD..nTotal-1)
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"