19#include <fairlogger/Logger.h>
32#include <TGeoManager.h>
33#include <TGeoPhysicalNode.h>
38#include "TGeoMatrix.h"
40#include "TGeoVolume.h"
58std::unique_ptr<o2::its::GeometryTGeo> GeometryTGeo::sInstance;
91 LOG(fatal) <<
"Invalid use of public constructor: o2::its::GeometryTGeo instance exists";
106 LOG(fatal) <<
"No adoption: o2::its::GeometryTGeo instance exists";
108 sInstance = std::unique_ptr<o2::its::GeometryTGeo>(raw);
109 sInstance->mOwner = canDelete;
298#ifdef ENABLE_UPGRADES
347 int lay, hba, stav, sstav, mod, chipInMod;
403 static TGeoHMatrix matTmp;
404 gGeoManager->PushPath();
406 if (!gGeoManager->cd(
path.Data())) {
407 gGeoManager->PopPath();
408 LOG(error) <<
"Error in cd-ing to " <<
path.Data();
412 matTmp = *gGeoManager->GetCurrentMatrix();
418 gGeoManager->PopPath();
420 static int chipInGlo{0};
424#ifdef ENABLE_UPGRADES
430 static TGeoTranslation tra(0., 0.5 * delta, 0.);
441 static TGeoHMatrix t2l;
443 t2l.RotateZ(
alpha * RadToDeg());
445 const auto& matL2Gi = matL2G.Inverse();
446 t2l.MultiplyLeft(&matL2Gi);
454 LOG(warning) <<
"Already built";
458 if (gGeoManager ==
nullptr) {
460 LOG(fatal) <<
"Geometry is not loaded";
479 int numberOfChips = 0;
495 LOGP(
debug,
"Summary of extracted Geometry:");
498 LOGP(
debug,
" Layer {}: {:*^30}",
i,
"START");
508 LOGP(
debug,
" Layer {}: {:*^30}",
i,
"END");
510 LOGP(
debug,
"In total there {} chips registered", numberOfChips);
512#ifdef ENABLE_UPGRADES
514 LOGP(info,
"Found active IT3 layers -> Renaming Detector ITS to IT3");
530 LOG(warning) <<
"The method Build was not called yet";
538 LOGP(info,
"Loading {} L2G matrices from TGeo; there are {} matrices",
getName(),
mSize);
540 cacheL2G.setSize(
mSize);
544 cacheL2G.setMatrix(
Mat3D(*hm),
i);
550 LOGP(info,
"Loading {} T2L matrices from TGeo",
getName());
552 cacheT2L.setSize(
mSize);
555 cacheT2L.setMatrix(
Mat3D(hm),
i);
561 LOGP(info,
"Loading {} T2G rotation 2D matrices",
getName());
563 cacheT2Gr.setSize(
mSize);
570 LOG(
debug) <<
"It is faster to use 2D rotation for T2G instead of full Transform3D matrices";
572 LOGP(info,
"Creating {} T2G matrices from TGeo",
getName());
574 cacheT2G.setSize(
mSize);
583 mat.SetComponents(
r.getCos(), -
r.getSin(), 0., 0.,
r.getSin(),
r.getCos(), 0., 0., 0., 0., 1., 0.);
584 cacheT2G.setMatrix(mat,
i);
606 int numberOfLayers = 0;
609 if (itsV ==
nullptr) {
615 TObjArray*
nodes = itsV->GetNodes();
616 int nNodes =
nodes->GetEntriesFast();
617 for (
int j = 0;
j < nNodes;
j++) {
619 auto nd =
dynamic_cast<TGeoNode*
>(
nodes->At(
j));
620 const char*
name = nd->GetName();
626 LOG(fatal) <<
"Failed to extract layer ID from the " <<
name;
634 LOG(fatal) <<
"Failed to extract wrapper ID from the " <<
name;
636 TObjArray* nodesW = nd->GetNodes();
637 int nNodesW = nodesW->GetEntriesFast();
639 for (
int jw = 0; jw < nNodesW; jw++) {
640 auto ndW =
dynamic_cast<TGeoNode*
>(nodesW->At(jw))->GetName();
644 LOGP(fatal,
"Failed to extract layer ID from wrapper volume '{}' from one of its nodes '{}'",
name, ndW);
654 return numberOfLayers;
661 int numberOfHalfBarrels = 2;
663 return numberOfHalfBarrels;
669 int numberOfStaves = 0;
676 TGeoVolume* volHb = gGeoManager->GetVolume(hbarnam);
677 if (volHb ==
nullptr) {
678 LOGP(fatal,
"Can't find '{}' volume (ITS3={})", hbarnam,
mIsLayerITS3[lay]);
683 int nNodes = volHb->GetNodes()->GetEntries();
684 for (
int j = 0;
j < nNodes;
j++) {
704 TGeoVolume* volLd = gGeoManager->GetVolume(stavnam);
705 if (volLd ==
nullptr) {
706 LOG(fatal) <<
"can't find volume " << stavnam;
709 int nNodes = volLd->GetNodes()->GetEntries();
710 for (
int j = 0;
j < nNodes;
j++) {
726 TGeoVolume* volLd =
nullptr;
730 volLd = gGeoManager->GetVolume(stavnam);
734 volLd = gGeoManager->GetVolume(stavnam);
743 int nNodes = volLd->GetNodes()->GetEntries();
745 for (
int j = 0;
j < nNodes;
j++) {
756#ifdef ENABLE_UPGRADES
765 int numberOfChips = 0;
767 TGeoVolume* volLd =
nullptr;
771 volLd = gGeoManager->GetVolume(stavnam);
776 volLd = gGeoManager->GetVolume(stavnam);
781 volLd = gGeoManager->GetVolume(stavnam);
784 LOG(fatal) <<
"can't find volume containing chips on layer " << lay;
788 int nNodes = volLd->GetNodes()->GetEntries();
790 double xmin = 1e9, xmax = -1e9, zmin = 1e9, zmax = -1e9;
791 double lab[3], loc[3] = {0, 0, 0};
792 double dx = -1, dz = -1;
794 for (
int j = 0;
j < nNodes;
j++) {
795 TGeoNodeMatrix* node = (TGeoNodeMatrix*)volLd->GetNodes()->At(
j);
799 node->LocalToMaster(loc, lab);
816 TGeoShape* chShape = node->GetVolume()->GetShape();
817 TGeoBBox*
bbox =
dynamic_cast<TGeoBBox*
>(chShape);
819 LOG(fatal) <<
"Chip " << node->GetName() <<
" volume is of unprocessed shape " << chShape->IsA()->GetName();
821 dx = 2 *
bbox->GetDX();
822 dz = 2 *
bbox->GetDZ();
827 double spanX = xmax - xmin;
828 double spanZ = zmax - zmin;
829 nrow = TMath::Nint(spanX / dx + 1);
830 int ncol = TMath::Nint(spanZ / dz + 1);
831 if (nrow * ncol != numberOfChips) {
832 LOG(error) <<
"Inconsistency between Nchips=" << numberOfChips <<
" and Nrow*Ncol=" << nrow <<
"*" << ncol <<
"->"
833 << nrow * ncol <<
"\n"
834 <<
"Extracted chip dimensions (x,z): " << dx <<
" " << dz <<
" Module Span: " << spanX <<
" " << spanZ <<
"\n"
835 <<
"xmin=" << xmin <<
" xmax=" << xmax
836 <<
" zmin=" << zmin <<
" zmax=" << zmax;
838 return numberOfChips;
846 TGeoVolume* volLd = gGeoManager->GetVolume(stavnam);
848 LOG(fatal) <<
"can't find volume " << stavnam;
851 return volLd->GetUniqueID();
858 LOGF(info,
"Geometry not built yet!");
862 LOGF(info,
"Summary of GeometryTGeo: %s",
getName());
866 "Lr%2d\tNStav:%2d\tNChips:%2d "
867 "(%dx%-2d)\tNMod:%d\tNSubSt:%d\tNSt:%3d\tChip#:%5d:%-5d\tWrapVol:%d",
882 double locA[3] = {-100., 0., 0.}, locB[3] = {100., 0., 0.}, gloA[3], gloB[3];
885#ifdef ENABLE_UPGRADES
891 const auto phi3 = (phi2 - phi1) / 2.;
892 const auto x = radius * std::cos(phi3);
893 const auto y = radius * std::sin(phi3);
895 const auto m =
x /
y;
896 const auto c =
y -
m *
x;
899 locA[1] =
m * locA[0] +
c;
900 locB[1] =
m * locB[0] +
c;
904 matL2G->LocalToMaster(locA, gloA);
905 matL2G->LocalToMaster(locB, gloB);
906 double dx = gloB[0] - gloA[0], dy = gloB[1] - gloA[1];
907 double t = (gloB[0] * dx + gloB[1] * dy) / (dx * dx + dy * dy);
908 double xp = gloB[0] - dx * t, yp = gloB[1] - dy * t;
909 x =
Sqrt(xp * xp + yp * yp);
911 o2::math_utils::bringTo02Pi(alp);
918 static TGeoHMatrix t2l;
919 float x = 0.f, alp = 0.f;
922 t2l.RotateZ(alp * RadToDeg());
924 const TGeoHMatrix& matL2Gi = matL2G->Inverse();
925 t2l.MultiplyLeft(&matL2Gi);
933 if (!nms.BeginsWith(prefix)) {
936 nms.Remove(0, strlen(prefix));
937 if (!isdigit(nms.Data()[0])) {
Definition of the GeometryManager class.
Definition of the GeometryTGeo class.
ClassImp(o2::its::GeometryTGeo)
Definition of the SegmentationAlpide class.
Definition of the SegmentationSuperAlpide 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
Segmentation and response for pixels in ITS3 upgrade.
static constexpr float mSensorLayerThickness
static constexpr float mSensorLayerThicknessEff
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< float, 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"