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");
105 std::cout <<
"Layer MLOT: " <<
i << std::endl;
112 int numberOfChipsTotal = 0;
191 }
else if (subDetID == 1) {
208 }
else if (subDetID == 1) {
217 int chipsPerModule = Nchip;
218 int chipsPerHalfStave = Nmod * chipsPerModule;
219 int chipsPerStave = Nhs * chipsPerHalfStave;
220 return index / chipsPerStave;
221 }
else if (Nhs == 1) {
222 int chipsPerModule = Nchip;
223 int chipsPerStave = Nmod * chipsPerModule;
224 return index / chipsPerStave;
239 }
else if (subDetID == 1) {
247 int chipsPerModule = Nchip;
248 int chipsPerHalfStave = Nmod * chipsPerModule;
249 int chipsPerStave = Nhs * chipsPerHalfStave;
251 int rem =
index % chipsPerStave;
252 return rem / chipsPerHalfStave;
266 }
else if (subDetID == 1) {
275 int chipsPerModule = Nchip;
276 int chipsPerHalfStave = Nmod * chipsPerModule;
277 int rem =
index % (Nhs * chipsPerHalfStave);
278 rem = rem % chipsPerHalfStave;
279 return rem / chipsPerModule;
280 }
else if (Nhs == 1) {
281 int chipsPerModule = Nchip;
282 int rem =
index % (Nmod * chipsPerModule);
283 return rem / chipsPerModule;
298 }
else if (subDetID == 1) {
307 int chipsPerModule = Nchip;
308 return index % chipsPerModule;
309 }
else if (Nhs == 1) {
310 int chipsPerModule = Nchip;
311 return index % chipsPerModule;
326 }
else if (subDetID == 1) {
332 int chipsPerModule = Nchip;
333 int chipsPerHalfStave = Nmod * chipsPerModule;
334 int chipsPerStave = Nhs * chipsPerHalfStave;
335 return getFirstChipIndex(lay, petalcase, subDetID) + stave * chipsPerStave + halfstave * chipsPerHalfStave + mod * chipsPerModule + chip;
336 }
else if (Nhs == 1) {
337 int chipsPerModule = Nchip;
338 int chipsPerStave = Nmod * chipsPerModule;
339 return getFirstChipIndex(lay, petalcase, subDetID) + stave * chipsPerStave + mod * chipsPerModule + chip;
343 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);
344 return std::numeric_limits<unsigned short>::max();
353 }
else if (subDetID == 1) {
359 int chipsPerModule = Nchip;
360 int chipsPerHalfStave = Nmod * chipsPerModule;
361 int chipsPerStave = Nhs * chipsPerHalfStave;
362 return getFirstChipIndex(lay, -1, subDetID) + stave * chipsPerStave + halfstave * chipsPerHalfStave + mod * chipsPerModule + chip;
363 }
else if (Nhs == 1) {
364 int chipsPerModule = Nchip;
365 int chipsPerStave = Nmod * chipsPerModule;
366 return getFirstChipIndex(lay, -1, subDetID) + stave * chipsPerStave + mod * chipsPerModule + chip;
370 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);
371 return std::numeric_limits<unsigned short>::max();
398 int subDetID, petalcase, disk,
layer, stave, halfstave, mod, chip;
423 }
else if (
layer >= 0) {
430 }
else if (subDetID == 1) {
454 static TGeoHMatrix matTmp;
455 gGeoManager->PushPath();
457 if (!gGeoManager->cd(
path.Data())) {
458 gGeoManager->PopPath();
459 LOG(error) <<
"Error in cd-ing to " <<
path.Data();
463 matTmp = *gGeoManager->GetCurrentMatrix();
468 gGeoManager->PopPath();
470 static int chipInGlo{0};
507 for (
int i = 0;
i < newSize;
i++) {
518 LOG(warning) <<
"The method Build was not called yet";
526 LOGP(info,
"Loading {} L2G matrices from TGeo; there are {} matrices",
getName(),
mSize);
528 cacheL2G.setSize(
mSize);
532 cacheL2G.setMatrix(
Mat3D(*hm),
i);
538 LOGP(info,
"Loading {} T2L matrices from TGeo for ML & OT",
getName());
542 cacheT2L.setSize(m_Size);
543 for (
int i = 0;
i < m_Size;
i++) {
546 cacheT2L.setMatrix(
Mat3D(hm),
i);
556#ifdef ENABLE_UPGRADES
587 if (!nms.BeginsWith(prefix)) {
590 nms.Remove(0, strlen(prefix));
591 if (!isdigit(nms.Data()[0])) {
600 int numberOfLayers = 0;
602 if (trkV ==
nullptr) {
608 TObjArray*
nodes = trkV->GetNodes();
610 int nNodes =
nodes->GetEntriesFast();
611 for (
int j = 0;
j < nNodes;
j++) {
613 auto nd =
dynamic_cast<TGeoNode*
>(
nodes->At(
j));
614 const char*
name = nd->GetName();
618 LOG(fatal) <<
"Failed to extract layer ID from the " <<
name;
624 LOG(fatal) <<
"Failed to extract wrapper ID from the " <<
name;
626 TObjArray* nodesW = nd->GetNodes();
627 int nNodesW = nodesW->GetEntriesFast();
629 for (
int jw = 0; jw < nNodesW; jw++) {
630 auto ndW =
dynamic_cast<TGeoNode*
>(nodesW->At(jw))->GetName();
633 LOGP(fatal,
"Failed to extract layer ID from wrapper volume '{}' from one of its nodes '{}'",
name, ndW);
641 return numberOfLayers;
647 int numberOfPetals = 0;
655 TObjArray*
nodes = trkV->GetNodes();
661 LOGP(info,
"Searching for petal assemblies in {} (pattern: {})",
664 for (
int j = 0;
j <
nodes->GetEntriesFast();
j++) {
665 auto* nd =
dynamic_cast<TGeoNode*
>(
nodes->At(
j));
666 const char*
name = nd->GetName();
670 LOGP(info,
"Found petal assembly: {}",
name);
673 TGeoVolume* petalVol = nd->GetVolume();
675 TObjArray* petalNodes = petalVol->GetNodes();
677 LOGP(
debug,
"Petal {} contains {} child nodes",
name, petalNodes->GetEntriesFast());
679 for (
int k = 0; k < petalNodes->GetEntriesFast(); k++) {
680 auto* petalNode =
dynamic_cast<TGeoNode*
>(petalNodes->At(k));
681 LOGP(
debug,
" Node {}: {}", k, petalNode->GetName());
684 LOGP(warning,
"Petal {} has no child nodes",
name);
687 LOGP(warning,
"Petal {} has no volume",
name);
692 if (numberOfPetals == 0) {
693 LOGP(warning,
"No petal assemblies found in geometry");
695 LOGP(info,
"Found {} petal assemblies", numberOfPetals);
698 return numberOfPetals;
705 int numberOfParts = 0;
713 TObjArray*
nodes = vdV->GetNodes();
719 bool petalFound =
false;
721 for (
int j = 0;
j <
nodes->GetEntriesFast();
j++) {
722 auto* nd =
dynamic_cast<TGeoNode*
>(
nodes->At(
j));
723 const char*
name = nd->GetName();
729 LOGP(info,
"Counting active parts in petal: {}",
name);
732 TGeoVolume* petalVol = nd->GetVolume();
734 LOGP(warning,
"Petal {} has no volume",
name);
738 TObjArray* petalNodes = petalVol->GetNodes();
740 LOGP(warning,
"Petal {} has no child nodes",
name);
744 for (
int k = 0; k < petalNodes->GetEntriesFast(); k++) {
745 auto* petalNode =
dynamic_cast<TGeoNode*
>(petalNodes->At(k));
746 const char* nodeName = petalNode->GetName();
751 LOGP(
debug,
"Found active part in {}: {}",
name, nodeName);
763 if (numberOfParts == 0) {
764 LOGP(warning,
"No active parts (layers/disks) found in petal");
770 LOGP(info,
"Total number of active parts: {} ({}*{})",
779 int numberOfDisks = 0;
787 TObjArray*
nodes = vdV->GetNodes();
793 bool petalFound =
false;
795 for (
int j = 0;
j <
nodes->GetEntriesFast();
j++) {
796 auto* nd =
dynamic_cast<TGeoNode*
>(
nodes->At(
j));
802 LOGP(info,
"Counting disks in petal: {}", nd->GetName());
805 TGeoVolume* petalVol = nd->GetVolume();
807 LOGP(warning,
"Petal {} has no volume", nd->GetName());
811 TObjArray* petalNodes = petalVol->GetNodes();
813 LOGP(warning,
"Petal {} has no child nodes", nd->GetName());
817 for (
int k = 0; k < petalNodes->GetEntriesFast(); k++) {
818 auto* petalNode =
dynamic_cast<TGeoNode*
>(petalNodes->At(k));
821 LOGP(info,
"Found disk in {} : {}", nd->GetName(), petalNode->GetName());
832 if (numberOfDisks == 0) {
833 LOGP(warning,
"No disks found in VD geometry");
836 return numberOfDisks;
843 int numberOfLayers = 0;
851 TObjArray*
nodes = vdV->GetNodes();
857 bool petalFound =
false;
859 for (
int j = 0;
j <
nodes->GetEntriesFast();
j++) {
860 auto* nd =
dynamic_cast<TGeoNode*
>(
nodes->At(
j));
866 LOGP(info,
"Counting layers in petal: {}", nd->GetName());
869 TGeoVolume* petalVol = nd->GetVolume();
871 LOGP(warning,
"Petal {} has no volume", nd->GetName());
875 TObjArray* petalNodes = petalVol->GetNodes();
877 LOGP(warning,
"Petal {} has no child nodes", nd->GetName());
881 for (
int k = 0; k < petalNodes->GetEntriesFast(); k++) {
882 auto* petalNode =
dynamic_cast<TGeoNode*
>(petalNodes->At(k));
885 LOGP(info,
"Found layer in {} : {}", nd->GetName(), petalNode->GetName());
896 if (numberOfLayers == 0) {
897 LOGP(warning,
"No layers found in VD geometry");
900 return numberOfLayers;
907 int numberOfChips = 0;
915 TObjArray*
nodes = vdV->GetNodes();
921 bool petalFound =
false;
923 for (
int j = 0;
j <
nodes->GetEntriesFast();
j++) {
924 auto* nd =
dynamic_cast<TGeoNode*
>(
nodes->At(
j));
925 const char*
name = nd->GetName();
931 LOGP(info,
"Counting chips in petal: {}",
name);
934 TGeoVolume* petalVol = nd->GetVolume();
936 LOGP(warning,
"Petal {} has no volume",
name);
940 TObjArray* petalNodes = petalVol->GetNodes();
942 LOGP(warning,
"Petal {} has no child nodes",
name);
946 for (
int k = 0; k < petalNodes->GetEntriesFast(); k++) {
947 auto* petalNode =
dynamic_cast<TGeoNode*
>(petalNodes->At(k));
948 const char* nodeName = petalNode->GetName();
949 TGeoVolume* vol = petalNode->GetVolume();
952 LOGP(
debug,
"Node {} has no volume", nodeName);
957 TObjArray* subNodes = vol->GetNodes();
959 LOGP(
debug,
"Node {} has no sub-nodes", nodeName);
963 for (
int i = 0;
i < subNodes->GetEntriesFast();
i++) {
964 auto* subNode =
dynamic_cast<TGeoNode*
>(subNodes->At(
i));
967 LOGP(
debug,
"Found sensor in {}: {}", nodeName, subNode->GetName());
979 if (numberOfChips == 0) {
980 LOGP(warning,
"No chips/sensors found in VD petal");
983 LOGP(info,
"Number of chips per petal: {}", numberOfChips);
984 return numberOfChips;
990 int numberOfStaves = 0;
993 TGeoVolume* layV = gGeoManager->GetVolume(layName.c_str());
995 if (layV ==
nullptr) {
1000 TObjArray*
nodes = layV->GetNodes();
1003 int nNodes =
nodes->GetEntriesFast();
1005 for (
int j = 0;
j < nNodes;
j++) {
1007 auto nd =
dynamic_cast<TGeoNode*
>(
nodes->At(
j));
1008 const char*
name = nd->GetName();
1013 return numberOfStaves;
1019 int numberOfHalfStaves = 0;
1022 TGeoVolume* staveV = gGeoManager->GetVolume(staveName.c_str());
1024 if (staveV ==
nullptr) {
1029 TObjArray*
nodes = staveV->GetNodes();
1032 int nNodes =
nodes->GetEntriesFast();
1034 for (
int j = 0;
j < nNodes;
j++) {
1035 auto nd =
dynamic_cast<TGeoNode*
>(
nodes->At(
j));
1036 const char*
name = nd->GetName();
1038 numberOfHalfStaves++;
1042 if (numberOfHalfStaves == 0) {
1043 numberOfHalfStaves = 1;
1045 return numberOfHalfStaves;
1051 int numberOfModules = 0;
1054 TGeoVolume* staveV = gGeoManager->GetVolume(staveName.c_str());
1056 if (staveV ==
nullptr) {
1061 TObjArray*
nodes = staveV->GetNodes();
1062 int nNodes =
nodes->GetEntriesFast();
1064 for (
int j = 0;
j < nNodes;
j++) {
1065 auto nd =
dynamic_cast<TGeoNode*
>(
nodes->At(
j));
1066 const char*
name = nd->GetName();
1071 return numberOfModules;
1077 int numberOfChips = 0;
1080 TGeoVolume* moduleV = gGeoManager->GetVolume(moduleName.c_str());
1082 if (moduleV ==
nullptr) {
1087 TObjArray*
nodes = moduleV->GetNodes();
1088 int nNodes =
nodes->GetEntriesFast();
1090 for (
int j = 0;
j < nNodes;
j++) {
1091 auto nd =
dynamic_cast<TGeoNode*
>(
nodes->At(
j));
1092 const char*
name = nd->GetName();
1097 return numberOfChips;
1103 std::cout <<
"\nindex = " <<
index << std::endl;
1104 std::cout <<
"subDetID = " << subDetID << std::endl;
1105 std::cout <<
"petalcase = " << petalcase << std::endl;
1106 std::cout <<
"layer = " << lay << std::endl;
1107 std::cout <<
"disk = " << disk << std::endl;
1108 std::cout <<
"first chip index = " <<
getFirstChipIndex(lay, petalcase, subDetID) << std::endl;
1109 std::cout <<
"stave = " << stave << std::endl;
1110 std::cout <<
"halfstave = " << halfstave << std::endl;
1111 std::cout <<
"module = " << mod << std::endl;
1112 std::cout <<
"chip = " << chip << std::endl;
1119 LOGF(info,
"Geometry not built yet!");
1122 std::cout <<
"Detector ID: " << sInstance.get()->getDetID() << std::endl;
1124 LOGF(info,
"Summary of GeometryTGeo: %s",
getName());
1130 LOGF(info,
"Number of chips per petal VD: ");
1134 LOGF(info,
"Number of staves and half staves per layer MLOT: ");
1136 std::string mlot =
"";
1137 mlot = (
i < 4) ?
"ML" :
"OT";
1140 LOGF(info,
"Number of modules per stave (half stave) in each ML(OT) layer: ");
1144 LOGF(info,
"Number of chips per module MLOT: ");
1148 LOGF(info,
"Number of chips per layer MLOT: ");
1154 std::cout <<
"mLastChipIndex = [";
1161 std::cout <<
"]" << std::endl;
1162 std::cout <<
"mLastChipIndexVD = [";
1169 std::cout <<
"]" << std::endl;
1183 if (subDetID < 0 || subDetID > 1) {
1184 LOG(error) <<
"getBarrelLayer(): Invalid subDetID for barrel: " << subDetID
1185 <<
". Expected values are 0 or 1.";
1189 if (subLayerID < 0 || subLayerID > 7) {
1190 LOG(error) <<
"getBarrelLayer(): Invalid subLayerID for barrel: " << subDetID
1191 <<
". Expected values are between 0 and 7.";
1195 const int baseOffsets[] = {0, 3};
1197 return baseOffsets[subDetID] + subLayerID;
1204 double locA[3] = {-100., 0., 0.}, locB[3] = {100., 0., 0.}, gloA[3], gloB[3];
1205 double xp{0}, yp{0};
1209 LOG(error) <<
"extractSensorXAlphaMLOT(): VD layers are not supported yet! chipID = " << chipID;
1214 matL2G->LocalToMaster(locA, gloA);
1215 matL2G->LocalToMaster(locB, gloB);
1216 double dx = gloB[0] - gloA[0], dy = gloB[1] - gloA[1];
1217 double t = (gloB[0] * dx + gloB[1] * dy) / (dx * dx + dy * dy);
1218 xp = gloB[0] - dx * t;
1219 yp = gloB[1] - dy * t;
1222 alp = std::atan2(yp, xp);
1223 x = std::hypot(xp, yp);
1224 o2::math_utils::bringTo02Pi(alp);
1237 LOG(error) <<
"createT2LMatrixMLOT(): VD layers are not supported yet! chipID = " << chipID
1238 <<
"returning dummy values! ";
1239 static TGeoHMatrix dummy;
1243 static TGeoHMatrix t2l;
1246 t2l.RotateZ(
alpha * TMath::RadToDeg());
1248 const TGeoHMatrix& matL2Gi = matL2G->Inverse();
1249 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"