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;
339 int lay, hba, stav, sstav, mod, chipInMod;
395 static TGeoHMatrix matTmp;
396 gGeoManager->PushPath();
398 if (!gGeoManager->cd(
path.Data())) {
399 gGeoManager->PopPath();
400 LOG(error) <<
"Error in cd-ing to " <<
path.Data();
404 matTmp = *gGeoManager->GetCurrentMatrix();
410 gGeoManager->PopPath();
412 static int chipInGlo{0};
417 static TGeoTranslation tra(0., 0.5 * delta, 0.);
418#ifdef ENABLE_UPGRADES
433 LOG(warning) <<
"Already built";
437 if (gGeoManager ==
nullptr) {
439 LOG(fatal) <<
"Geometry is not loaded";
458 int numberOfChips = 0;
474#ifdef ENABLE_UPGRADES
476 LOGP(info,
"Found active IT3 layers -> Renaming Detector ITS to IT3");
492 LOG(warning) <<
"The method Build was not called yet";
500 LOGP(info,
"Loading {} L2G matrices from TGeo; there are {} matrices",
getName(),
mSize);
502 cacheL2G.setSize(
mSize);
506 cacheL2G.setMatrix(
Mat3D(*hm),
i);
512 LOGP(info,
"Loading {} T2L matrices from TGeo",
getName());
514 cacheT2L.setSize(
mSize);
517 cacheT2L.setMatrix(
Mat3D(hm),
i);
523 LOGP(info,
"Loading {} T2G rotation 2D matrices",
getName());
525 cacheT2Gr.setSize(
mSize);
532 LOG(
debug) <<
"It is faster to use 2D rotation for T2G instead of full Transform3D matrices";
534 LOGP(info,
"Creating {} T2G matrices from TGeo",
getName());
536 cacheT2G.setSize(
mSize);
545 mat.SetComponents(
r.getCos(), -
r.getSin(), 0., 0.,
r.getSin(),
r.getCos(), 0., 0., 0., 0., 1., 0.);
546 cacheT2G.setMatrix(mat,
i);
568 int numberOfLayers = 0;
571 if (itsV ==
nullptr) {
577 TObjArray*
nodes = itsV->GetNodes();
578 int nNodes =
nodes->GetEntriesFast();
579 for (
int j = 0;
j < nNodes;
j++) {
581 auto nd =
dynamic_cast<TGeoNode*
>(
nodes->At(
j));
582 const char*
name = nd->GetName();
588 LOG(fatal) <<
"Failed to extract layer ID from the " <<
name;
596 LOG(fatal) <<
"Failed to extract wrapper ID from the " <<
name;
598 TObjArray* nodesW = nd->GetNodes();
599 int nNodesW = nodesW->GetEntriesFast();
601 for (
int jw = 0; jw < nNodesW; jw++) {
602 auto ndW =
dynamic_cast<TGeoNode*
>(nodesW->At(jw))->GetName();
606 LOGP(fatal,
"Failed to extract layer ID from wrapper volume '{}' from one of its nodes '{}'",
name, ndW);
616 return numberOfLayers;
623 int numberOfHalfBarrels = 2;
625 return numberOfHalfBarrels;
631 int numberOfStaves = 0;
638 TGeoVolume* volHb = gGeoManager->GetVolume(hbarnam);
639 if (volHb ==
nullptr) {
640 LOGP(fatal,
"Can't find '{}' volume (ITS3={})", hbarnam,
mIsLayerITS3[lay]);
645 int nNodes = volHb->GetNodes()->GetEntries();
646 for (
int j = 0;
j < nNodes;
j++) {
666 TGeoVolume* volLd = gGeoManager->GetVolume(stavnam);
667 if (volLd ==
nullptr) {
668 LOG(fatal) <<
"can't find volume " << stavnam;
671 int nNodes = volLd->GetNodes()->GetEntries();
672 for (
int j = 0;
j < nNodes;
j++) {
688 TGeoVolume* volLd =
nullptr;
692 volLd = gGeoManager->GetVolume(stavnam);
696 volLd = gGeoManager->GetVolume(stavnam);
705 int nNodes = volLd->GetNodes()->GetEntries();
707 for (
int j = 0;
j < nNodes;
j++) {
718#ifdef ENABLE_UPGRADES
727 int numberOfChips = 0;
729 TGeoVolume* volLd =
nullptr;
733 volLd = gGeoManager->GetVolume(stavnam);
738 volLd = gGeoManager->GetVolume(stavnam);
743 volLd = gGeoManager->GetVolume(stavnam);
746 LOG(fatal) <<
"can't find volume containing chips on layer " << lay;
750 int nNodes = volLd->GetNodes()->GetEntries();
752 double xmin = 1e9, xmax = -1e9, zmin = 1e9, zmax = -1e9;
753 double lab[3], loc[3] = {0, 0, 0};
754 double dx = -1, dz = -1;
756 for (
int j = 0;
j < nNodes;
j++) {
757 TGeoNodeMatrix*
node = (TGeoNodeMatrix*)volLd->GetNodes()->At(
j);
761 node->LocalToMaster(loc, lab);
778 TGeoShape* chShape =
node->GetVolume()->GetShape();
781 LOG(fatal) <<
"Chip " <<
node->GetName() <<
" volume is of unprocessed shape " << chShape->IsA()->GetName();
783 dx = 2 *
bbox->GetDX();
784 dz = 2 *
bbox->GetDZ();
789 double spanX = xmax - xmin;
790 double spanZ = zmax - zmin;
791 nrow = TMath::Nint(spanX / dx + 1);
792 int ncol = TMath::Nint(spanZ / dz + 1);
793 if (nrow * ncol != numberOfChips) {
794 LOG(error) <<
"Inconsistency between Nchips=" << numberOfChips <<
" and Nrow*Ncol=" << nrow <<
"*" << ncol <<
"->"
795 << nrow * ncol <<
"\n"
796 <<
"Extracted chip dimensions (x,z): " << dx <<
" " << dz <<
" Module Span: " << spanX <<
" " << spanZ <<
"\n"
797 <<
"xmin=" << xmin <<
" xmax=" << xmax
798 <<
" zmin=" << zmin <<
" zmax=" << zmax;
800 return numberOfChips;
808 TGeoVolume* volLd = gGeoManager->GetVolume(stavnam);
810 LOG(fatal) <<
"can't find volume " << stavnam;
813 return volLd->GetUniqueID();
820 LOGF(info,
"Geometry not built yet!");
824 LOGF(info,
"Summary of GeometryTGeo: %s",
getName());
828 "Lr%2d\tNStav:%2d\tNChips:%2d "
829 "(%dx%-2d)\tNMod:%d\tNSubSt:%d\tNSt:%3d\tChip#:%5d:%-5d\tWrapVol:%d",
844 double locA[3] = {-100., 0., 0.}, locB[3] = {100., 0., 0.}, gloA[3], gloB[3];
847#ifdef ENABLE_UPGRADES
854 const auto phi3 = (phi2 - phi1) / 2.;
855 locA[0] = radius * std::cos(phi3);
856 locA[1] = radius * std::sin(phi3);
857 matL2G->LocalToMaster(locA, gloA);
861 matL2G->LocalToMaster(locA, gloA);
862 matL2G->LocalToMaster(locB, gloB);
863 double dx = gloB[0] - gloA[0], dy = gloB[1] - gloA[1];
864 double t = (gloB[0] * dx + gloB[1] * dy) / (dx * dx + dy * dy);
865 xp = gloB[0] - dx * t;
866 yp = gloB[1] - dy * t;
869 matL2G->LocalToMaster(locA, gloA);
870 matL2G->LocalToMaster(locB, gloB);
871 double dx = gloB[0] - gloA[0], dy = gloB[1] - gloA[1];
872 double t = (gloB[0] * dx + gloB[1] * dy) / (dx * dx + dy * dy);
873 xp = gloB[0] - dx * t;
874 yp = gloB[1] - dy * t;
876 x = std::hypot(xp, yp);
877 alp = std::atan2(yp, xp);
878 o2::math_utils::bringTo02Pi(alp);
885 static TGeoHMatrix t2l;
886 float x = 0.f, alp = 0.f;
889 t2l.RotateZ(alp * RadToDeg());
891 const TGeoHMatrix& matL2Gi = matL2G->Inverse();
892 t2l.MultiplyLeft(&matL2Gi);
900 if (!nms.BeginsWith(prefix)) {
903 nms.Remove(0, strlen(prefix));
904 if (!isdigit(nms.Data()[0])) {
Definition of the GeometryManager class.
std::unique_ptr< expressions::Node > node
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 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.
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)
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.
static const char * composeSymNameITS()
sym name of the layer
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.
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.
int getLayer(int index) const final
Get chip layer, from 0.
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 detector 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
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"