19#include <fairlogger/Logger.h>
30#include <TGeoManager.h>
31#include <TGeoPhysicalNode.h>
36#include "TGeoMatrix.h"
38#include "TGeoVolume.h"
56std::unique_ptr<o2::its::GeometryTGeo> GeometryTGeo::sInstance;
89 LOG(fatal) <<
"Invalid use of public constructor: o2::its::GeometryTGeo instance exists";
104 LOG(fatal) <<
"No adoption: o2::its::GeometryTGeo instance exists";
106 sInstance = std::unique_ptr<o2::its::GeometryTGeo>(raw);
107 sInstance->mOwner = canDelete;
296#ifdef ENABLE_UPGRADES
345 int lay, hba, stav, sstav, mod, chipInMod;
401 static TGeoHMatrix matTmp;
402 gGeoManager->PushPath();
404 if (!gGeoManager->cd(
path.Data())) {
405 gGeoManager->PopPath();
406 LOG(error) <<
"Error in cd-ing to " <<
path.Data();
410 matTmp = *gGeoManager->GetCurrentMatrix();
416 gGeoManager->PopPath();
418 static int chipInGlo{0};
423 static TGeoTranslation tra(0., 0.5 * delta, 0.);
424#ifdef ENABLE_UPGRADES
439 LOG(warning) <<
"Already built";
443 if (gGeoManager ==
nullptr) {
445 LOG(fatal) <<
"Geometry is not loaded";
464 int numberOfChips = 0;
480#ifdef ENABLE_UPGRADES
482 LOGP(info,
"Found active IT3 layers -> Renaming Detector ITS to IT3");
498 LOG(warning) <<
"The method Build was not called yet";
506 LOGP(info,
"Loading {} L2G matrices from TGeo; there are {} matrices",
getName(),
mSize);
508 cacheL2G.setSize(
mSize);
512 cacheL2G.setMatrix(
Mat3D(*hm),
i);
518 LOGP(info,
"Loading {} T2L matrices from TGeo",
getName());
520 cacheT2L.setSize(
mSize);
523 cacheT2L.setMatrix(
Mat3D(hm),
i);
529 LOGP(info,
"Loading {} T2G rotation 2D matrices",
getName());
531 cacheT2Gr.setSize(
mSize);
538 LOG(
debug) <<
"It is faster to use 2D rotation for T2G instead of full Transform3D matrices";
540 LOGP(info,
"Creating {} T2G matrices from TGeo",
getName());
542 cacheT2G.setSize(
mSize);
551 mat.SetComponents(
r.getCos(), -
r.getSin(), 0., 0.,
r.getSin(),
r.getCos(), 0., 0., 0., 0., 1., 0.);
552 cacheT2G.setMatrix(mat,
i);
574 int numberOfLayers = 0;
577 if (itsV ==
nullptr) {
583 TObjArray*
nodes = itsV->GetNodes();
584 int nNodes =
nodes->GetEntriesFast();
585 for (
int j = 0;
j < nNodes;
j++) {
587 auto nd =
dynamic_cast<TGeoNode*
>(
nodes->At(
j));
588 const char*
name = nd->GetName();
594 LOG(fatal) <<
"Failed to extract layer ID from the " <<
name;
602 LOG(fatal) <<
"Failed to extract wrapper ID from the " <<
name;
604 TObjArray* nodesW = nd->GetNodes();
605 int nNodesW = nodesW->GetEntriesFast();
607 for (
int jw = 0; jw < nNodesW; jw++) {
608 auto ndW =
dynamic_cast<TGeoNode*
>(nodesW->At(jw))->GetName();
612 LOGP(fatal,
"Failed to extract layer ID from wrapper volume '{}' from one of its nodes '{}'",
name, ndW);
622 return numberOfLayers;
629 int numberOfHalfBarrels = 2;
631 return numberOfHalfBarrels;
637 int numberOfStaves = 0;
644 TGeoVolume* volHb = gGeoManager->GetVolume(hbarnam);
645 if (volHb ==
nullptr) {
646 LOGP(fatal,
"Can't find '{}' volume (ITS3={})", hbarnam,
mIsLayerITS3[lay]);
651 int nNodes = volHb->GetNodes()->GetEntries();
652 for (
int j = 0;
j < nNodes;
j++) {
672 TGeoVolume* volLd = gGeoManager->GetVolume(stavnam);
673 if (volLd ==
nullptr) {
674 LOG(fatal) <<
"can't find volume " << stavnam;
677 int nNodes = volLd->GetNodes()->GetEntries();
678 for (
int j = 0;
j < nNodes;
j++) {
694 TGeoVolume* volLd =
nullptr;
698 volLd = gGeoManager->GetVolume(stavnam);
702 volLd = gGeoManager->GetVolume(stavnam);
711 int nNodes = volLd->GetNodes()->GetEntries();
713 for (
int j = 0;
j < nNodes;
j++) {
724#ifdef ENABLE_UPGRADES
733 int numberOfChips = 0;
735 TGeoVolume* volLd =
nullptr;
739 volLd = gGeoManager->GetVolume(stavnam);
744 volLd = gGeoManager->GetVolume(stavnam);
749 volLd = gGeoManager->GetVolume(stavnam);
752 LOG(fatal) <<
"can't find volume containing chips on layer " << lay;
756 int nNodes = volLd->GetNodes()->GetEntries();
758 double xmin = 1e9, xmax = -1e9, zmin = 1e9, zmax = -1e9;
759 double lab[3], loc[3] = {0, 0, 0};
760 double dx = -1, dz = -1;
762 for (
int j = 0;
j < nNodes;
j++) {
763 TGeoNodeMatrix* node = (TGeoNodeMatrix*)volLd->GetNodes()->At(
j);
767 node->LocalToMaster(loc, lab);
784 TGeoShape* chShape = node->GetVolume()->GetShape();
785 TGeoBBox*
bbox =
dynamic_cast<TGeoBBox*
>(chShape);
787 LOG(fatal) <<
"Chip " << node->GetName() <<
" volume is of unprocessed shape " << chShape->IsA()->GetName();
789 dx = 2 *
bbox->GetDX();
790 dz = 2 *
bbox->GetDZ();
795 double spanX = xmax - xmin;
796 double spanZ = zmax - zmin;
797 nrow = TMath::Nint(spanX / dx + 1);
798 int ncol = TMath::Nint(spanZ / dz + 1);
799 if (nrow * ncol != numberOfChips) {
800 LOG(error) <<
"Inconsistency between Nchips=" << numberOfChips <<
" and Nrow*Ncol=" << nrow <<
"*" << ncol <<
"->"
801 << nrow * ncol <<
"\n"
802 <<
"Extracted chip dimensions (x,z): " << dx <<
" " << dz <<
" Module Span: " << spanX <<
" " << spanZ <<
"\n"
803 <<
"xmin=" << xmin <<
" xmax=" << xmax
804 <<
" zmin=" << zmin <<
" zmax=" << zmax;
806 return numberOfChips;
814 TGeoVolume* volLd = gGeoManager->GetVolume(stavnam);
816 LOG(fatal) <<
"can't find volume " << stavnam;
819 return volLd->GetUniqueID();
826 LOGF(info,
"Geometry not built yet!");
830 LOGF(info,
"Summary of GeometryTGeo: %s",
getName());
834 "Lr%2d\tNStav:%2d\tNChips:%2d "
835 "(%dx%-2d)\tNMod:%d\tNSubSt:%d\tNSt:%3d\tChip#:%5d:%-5d\tWrapVol:%d",
850 double locA[3] = {-100., 0., 0.}, locB[3] = {100., 0., 0.}, gloA[3], gloB[3];
853#ifdef ENABLE_UPGRADES
860 const auto phi3 = (phi2 - phi1) / 2.;
861 locA[0] = radius * std::cos(phi3);
862 locA[1] = radius * std::sin(phi3);
863 matL2G->LocalToMaster(locA, gloA);
867 matL2G->LocalToMaster(locA, gloA);
868 matL2G->LocalToMaster(locB, gloB);
869 double dx = gloB[0] - gloA[0], dy = gloB[1] - gloA[1];
870 double t = (gloB[0] * dx + gloB[1] * dy) / (dx * dx + dy * dy);
871 xp = gloB[0] - dx * t;
872 yp = gloB[1] - dy * t;
875 matL2G->LocalToMaster(locA, gloA);
876 matL2G->LocalToMaster(locB, gloB);
877 double dx = gloB[0] - gloA[0], dy = gloB[1] - gloA[1];
878 double t = (gloB[0] * dx + gloB[1] * dy) / (dx * dx + dy * dy);
879 xp = gloB[0] - dx * t;
880 yp = gloB[1] - dy * t;
882 x = std::hypot(xp, yp);
883 alp = std::atan2(yp, xp);
884 o2::math_utils::bringTo02Pi(alp);
891 static TGeoHMatrix t2l;
892 float x = 0.f, alp = 0.f;
895 t2l.RotateZ(alp * RadToDeg());
897 const TGeoHMatrix& matL2Gi = matL2G->Inverse();
898 t2l.MultiplyLeft(&matL2Gi);
906 static TGeoHMatrix t2l;
908 t2l.RotateZ(
alpha * RadToDeg());
910 const auto& matL2Gi = matL2G.Inverse();
911 t2l.MultiplyLeft(&matL2Gi);
919 if (!nms.BeginsWith(prefix)) {
922 nms.Remove(0, strlen(prefix));
923 if (!isdigit(nms.Data()[0])) {
Definition of the GeometryManager class.
Definition of the GeometryTGeo class.
ClassImp(o2::its::GeometryTGeo)
Definition of the SegmentationAlpide class.
Static class with identifiers, bitmasks and names for ALICE detectors.
static constexpr const char * getName(ID id)
names of defined detectors
o2::detectors::DetID mDetID
detector ID
const MatrixCache< Mat3D > & getCacheT2L() const
const char * getName() const
o2::math_utils::Rotation2Df_t Rot2D
const Mat3D & getMatrixL2G(int sensID) const
const MatrixCache< Mat3D > & getCacheT2G() const
int mSize
prebooked number of sensors
const MatrixCache< Rot2D > & getCacheT2GRot() const
const MatrixCache< Mat3D > & getCacheL2G() const
int extractNumberOfLayers()
Determines the number of layers in the Geometry.
TGeoHMatrix & createT2LMatrix(int isn)
static const char * getITS3ModulePattern()
std::vector< int > mNumberOfChipsPerHalfStave
number of chips per substave
o2::math_utils::Transform3D Mat3D
static const char * getITSLayerPattern()
static const std::string sLayerNameITS3
Layer name for ITS3.
static const char * composeSymNameLayer(int lr, bool isITS3=false)
sym name of the layer
static const std::string sStaveNameITS3
Stave name for ITS3.
int getChipIdInHalfStave(int index) const
Get chip number within stave, from 0.
static const std::string sSensorNameITS3
Sensor name for ITS3.
static const char * composeSymNameITS(bool isITS3=false)
sym name of the layer
std::vector< int > mNumberOfHalfStaves
the number of substaves/stave(layer)
static std::string sHalfBarrelName
HalfBarrel name.
static std::string sHalfStaveName
HalfStave name.
static const char * getITS3SegmentPattern(int layer)
static const char * getITS3ChipPattern()
static const char * getITS3TilePattern(int layer)
static const char * getITSSensorPattern()
bool getChipId(int index, int &lay, int &sta, int &ssta, int &mod, int &chip) const
int extractNumberOfChipsPerModule(int lay, int &nrow) const
static std::string sLayerName
Layer name.
int getHalfBarrel(int index) const
Get chip half barrel, from 0.
std::vector< int > mNumberOfStaves
number of staves/layer(layer)
static const char * getITSHalfBarrelPattern()
std::vector< int > mNumberOfModules
number of modules/substave(layer)
TGeoHMatrix * extractMatrixSensor(int index) const
static const char * getITS3RSUPattern(int layer)
int getLayer(int index) const
Get chip layer, from 0.
static const char * composeSymNameHalfBarrel(int lr, int hba, bool isITS3=false)
Sym name of the half barrel at given layer.
std::array< char, MAXLAYERS > mLayerToWrapper
Layer to wrapper correspondence.
std::array< bool, MAXLAYERS > mIsLayerITS3
flag with the information of the ITS version (ITS2 or ITS3)
static const char * getITS3HalfStavePattern()
float getSensorRefAlpha(int isn) const
static const std::string sModuleNameITS3
Module name for ITS3.
int getChipIdInStave(int index) const
Get chip number within stave, from 0.
static std::string sModuleName
Module name.
static const std::string sHalfStaveNameITS3
HalfStave name for ITS3.
TString getMatrixPath(int index) const
int extractNumberOfModules(int lay) const
static const char * composeSymNameHalfStave(int lr, int hba, int sta, int ssta, bool isITS3=false)
Sym name of the stave at given layer/halfbarrel.
~GeometryTGeo() override
Default destructor, don't use.
static const char * getITS3CarbonFormPattern(int layer)
int extractVolumeCopy(const char *name, const char *prefix) const
Extract number following the prefix in the name string.
const Mat3D getT2LMatrixITS3(int isn, float alpha)
static const char * composeSymNameChip(int lr, int hba, int sta, int ssta, int mod, int chip, bool isITS3=false)
Sym name of the chip in the given layer/halfbarrel/stave/substave/module.
static const char * getITS3PixelArrayPattern(int layer)
static const char * getITSChipPattern()
static const char * composeSymNameModule(int lr, int hba, int sta, int ssta, int mod, bool isITS3=false)
Sym name of the substave at given layer/halfbarrel/stave.
int extractLayerChipType(int lay) const
std::vector< float > mCacheRefX
sensors tracking plane reference X
std::vector< int > mNumberOfChipsPerModule
number of chips per module (group of chips on substaves)
static std::string sWrapperVolumeName
Wrapper volume name.
static const char * getITSVolPattern()
static const char * getITS3HalfBarrelPattern()
std::vector< int > mNumberOfChipsPerStave
number of chips per stave
bool isTrackingFrameCached() const
static const std::string sHalfBarrelNameITS3
HalfBarrel name for ITS3.
void Build(int loadTrans=0) override
Exract ITS parameters from TGeo.
void extractSensorXAlpha(int isn, float &x, float &alp)
std::vector< int > mNumberOfChipsPerLayer
number of chips per stave
int extractNumberOfStaves(int lay) const
int getHalfStave(int index) const
Get chip substave id in stave, from 0.
int getFirstChipIndex(int lay) const
static const char * getITSModulePattern()
int getChipIdInLayer(int index) const
Get chip number within layer, from 0.
static const std::string sChipNameITS3
Chip name for ITS3.
static std::string sStaveName
Stave name.
int extractNumberOfHalfStaves(int lay) const
Int_t mNumberOfHalfBarrels
number of halfbarrels
void fillMatrixCache(int mask) override
void Print(Option_t *opt="") const
static void adopt(GeometryTGeo *raw, bool canDelete=false)
int getChipIndex(int lay, int detInLay) const
std::vector< float > mCacheRefAlpha
sensors tracking plane reference alpha
Int_t mNumberOfLayers
number of layers
void fillTrackingFramesCache()
static const char * composeSymNameStave(int lr, int hba, int sta, bool isITS3=false)
Sym name of the stave at given layer.
int getStave(int index) const
Get chip stave, from 0.
static const char * getITS3LayerPattern()
int getModule(int index) const
Get chip module id in substave, from 0.
static const char * getITS3StavePattern()
static std::string sSensorName
Sensor name.
static std::string sChipName
Chip name.
std::vector< int > mNumberOfChipRowsPerModule
number of chips rows per module (relevant for OB modules)
int getChipIdInModule(int index) const
Get chip number within module, from 0.
std::vector< int > mLastChipIndex
max ID of the detctor in the layer
static const char * getITSHalfStavePattern()
int extractNumberOfHalfBarrels() const
std::vector< int > mNumberOfChipsPerHalfBarrel
number of chips per halfbarrel
static std::string sVolumeName
Mother volume name.
static const char * getITSStavePattern()
int getLastChipIndex(int lay) const
static const char * getITSWrapVolPattern()
Int_t getNumberOfChips() const
static constexpr float SensorLayerThickness
static constexpr float SensorLayerThicknessEff
GLfloat GLfloat GLfloat alpha
GLuint const GLchar * name
GLboolean GLboolean GLboolean b
GLsizei const GLchar *const * path
constexpr unsigned int nTiles
constexpr std::array< double, nLayers > radii
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"