16#include <fairlogger/Logger.h>
19#include <TGeoManager.h>
20#include <TGeoPhysicalNode.h>
25#include "TGeoMatrix.h"
27#include "TGeoVolume.h"
43std::unique_ptr<o2::ft3::GeometryTGeo> GeometryTGeo::sInstance;
66 LOG(fatal) <<
"Invalid use of public constructor: o2::ft3::GeometryTGeo instance exists";
79 LOG(warning) <<
"Already built";
85 LOG(fatal) <<
"Geometry is not loaded";
100 for (
int iDir = 0; iDir < 2; iDir++) {
102 LOG(info) <<
"direction " << iDir <<
" has " <<
mNumberOfDiscs[iDir] <<
" discs";
107 if (ft3V ==
nullptr) {
111 if (layerNode ==
nullptr) {
114 auto layerVol = layerNode->GetVolume();
115 if (layerVol ==
nullptr) {
118 TObjArray*
nodes = layerVol->GetNodes();
119 int nNodes =
nodes->GetEntriesFast();
122 std::vector<int> chipsPerStave;
123 for (
int j = 0;
j < nNodes;
j++) {
124 auto nd =
dynamic_cast<TGeoNode*
>(
nodes->At(
j));
125 const char*
name = nd->GetName();
126 if (strstr(
name,
"FT3Sensor") !=
nullptr && strstr(
name,
"Inactive") ==
nullptr) {
127 int direction = 0,
layer = 0;
128 int stave = 0, chip = 0;
130 if (stave >= chipsPerStave.size()) {
131 chipsPerStave.resize(stave + 1, 0);
134 if (chip + 1 >= chipsPerStave[stave]) {
135 chipsPerStave[stave] = chip + 1;
140 LOG(info) <<
"direction " << iDir <<
" disc " << iDisc <<
" has " << nNodes <<
" nodes of which " << nSensor <<
" sensors in " << chipsPerStave.size() <<
" staves";
142 if (nStaves != chipsPerStave.size()) {
143 LOG(info) <<
"Inconsistency in stave count " << nStaves <<
" " << chipsPerStave.size();
145 mChipIdxStave.resize(absStaveIdx + chipsPerStave.size() + 1);
148 for (
int nChips : chipsPerStave) {
149 LOG(
debug) <<
"Absolute Stave ID " << absStaveIdx <<
" : " << nChips <<
" sensors";
156 if (totSensor != nSensor) {
157 LOG(info) <<
"Inconsistency in sensor count " << nSensor <<
" " << totSensor;
159 LOG(
debug) <<
" adding stave Idx " << absStaveIdx <<
" to disc array; element " <<
mStaveIdxDisc.size();
163 LOG(info) <<
"Total sensors so far " <<
mSize;
167 LOG(info) <<
"Total sensors " <<
mSize;
204 if (ft3V ==
nullptr) {
208 TObjArray*
nodes = layerVol->GetNodes();
209 int nNodes =
nodes->GetEntriesFast();
211 for (
int j = 0;
j < nNodes;
j++) {
212 auto nd =
dynamic_cast<TGeoNode*
>(
nodes->At(
j));
213 const char*
name = nd->GetName();
214 if (strstr(
name,
"FT3Sensor") !=
nullptr && strstr(
name,
"Inactive") ==
nullptr) {
218 LOG(info) <<
"direction " << dir <<
" layer " <<
layer <<
" has " << nNodes <<
" nodes of which " << nSensor <<
" sensors";
224 if (volName.find(
"FT3Sensor_Active") == 0) {
225 return std::stoi(volName.substr(volName.rfind(
'_') + 1));
227 LOG(error) <<
"Not a sensor volume " << volName;
232 if (volName.find(
"FT3Sensor_Active") == 0) {
233 int idx = volName.rfind(
'_');
234 chip = std::stoi(volName.substr(idx + 1));
235 idx = volName.rfind(
'_', idx);
236 stave = std::stoi(volName.substr(idx + 1));
238 LOG(error) <<
"Not a sensor volume " << volName;
245 if (volName.find(
"FT3Sensor_Active") == 0) {
246 int idx = volName.find(
'_') + 1;
247 idx = volName.find(
'_', idx) + 1;
248 direction = std::stoi(volName.substr(idx));
249 idx = volName.find(
'_', idx) + 1;
250 layer = std::stoi(volName.substr(idx));
251 idx = volName.find(
'_', idx) + 1;
252 stave = std::stoi(volName.substr(idx));
253 idx = volName.find(
'_', idx) + 1;
254 chip = std::stoi(volName.substr(idx));
256 LOG(error) <<
"Not a sensor volume " << volName;
312 path += Form(
"FT3Sensor_Active_%d_%d_%d_%d_%d", direction,
layer, stave, chip, chip);
332 LOG(warning) <<
"The method Build was not called yet";
338 if ((
mask & o2::math_utils::bit2Mask(o2::math_utils::TransformType::L2G)) && !
getCacheL2G().isFilled()) {
340 LOGP(info,
"Loading {} L2G matrices from TGeo; there are {} matrices",
getName(),
mSize);
342 cacheL2G.setSize(
mSize);
344 cacheT2L.setSize(
mSize);
347 double locA[3] = {-100., 0., 0.}, locB[3] = {100., 0., 0.}, gloA[3], gloB[3];
350 gGeoManager->PushPath();
353 for (
int absDisc = 0; absDisc < nTotDisc; absDisc++) {
360 LOG(info) <<
"Direction " << direction <<
" layer " <<
layer;
367 LOG(fatal) <<
"Attempting to get absStave + 1 from index array size " <<
mChipIdxStave.size();
370 LOG(
debug) <<
"Getting matrices for direction " << direction <<
" layer " <<
layer <<
" stave " << stave <<
" : " << nChip <<
" chips";
371 for (
int chip = 0; chip < nChip; chip++) {
376 const TGeoHMatrix* matL2G = gGeoManager->GetCurrentMatrix();
377 if (chipIdx >=
mSize) {
378 LOG(fatal) <<
"ChipIdx " << chipIdx <<
" out of range " <<
mSize;
380 cacheL2G.setMatrix(
Mat3D(*matL2G), chipIdx);
382 matL2G->LocalToMaster(locA, gloA);
383 matL2G->LocalToMaster(locB, gloB);
384 double dx = gloB[0] - gloA[0], dy = gloB[1] - gloA[1];
385 double t = (gloB[0] * dx + gloB[1] * dy) / (dx * dx + dy * dy);
386 xp = gloB[0] - dx * t;
387 yp = gloB[1] - dy * t;
388 float alp = std::atan2(yp, xp);
390 o2::math_utils::bringTo02Pi(alp);
393 static TGeoHMatrix t2l;
396 const TGeoHMatrix& matL2Gi = matL2G->Inverse();
397 t2l.MultiplyLeft(&matL2Gi);
398 cacheT2L.setMatrix(
Mat3D(t2l), chipIdx);
402 gGeoManager->PopPath();
410 LOGF(info,
"Geometry not built yet!");
413 std::cout <<
"Detector ID: " << sInstance.get()->getDetID() << std::endl;
415 LOGF(info,
"Summary of GeometryTGeo: %s",
getName());
417 LOGF(info,
"Total number of sensors: %d",
mSize);
Definition of the GeometryTGeo class.
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
int extractNumberOfDiscs(int dir)
std::vector< float > mCacheRefXDiscs
static std::string sPassiveName
Passive material name.
static std::string sChipName
Chip name.
void extractChipIds(std::string const volName, int &direction, int &layer, int &stave, int &chip)
std::vector< int > mNumberOfChipsPerDisc
Index of first chup for each global stave.
void Build(int loadTrans)
static const char * composeSymNameSensor(Int_t d, Int_t lr)
static std::string sLayerName
Layer name.
static const char * getFT3SensorPattern()
o2::math_utils::Transform3D Mat3D
void Print(Option_t *opt="") const
static std::string sVolumeName
Mother volume name.
void fillMatrixCache(int mask)
int getChipOnStave(int chipIdx) const
static const char * getFT3ChipPattern()
std::vector< int > mNumberOfStavesPerDisc
static std::string sSensorName
Sensor name.
GeometryTGeo(bool build=false, int loadTrans=0)
static const char * composeSymNameLayer(Int_t d, Int_t lr)
int getStave(int chipIdx) const
int extractNumberOfChips(int dir, int layer)
std::vector< int > mChipIdxStave
Index of first global stave Id for each disc.
static std::string sInnerVolumeName
Mother inner volume name.
std::vector< float > mCacheRefAlphaDiscs
cache for X of ML and OT
std::vector< int > mStaveIdxDisc
TODO; in principle redundant?
static const char * getFT3LayerPattern()
static const char * composeSymNameChip(Int_t d, Int_t lr)
int extractChipId(std::string const volName)
std::vector< int > mNumberOfDiscs
cache for sensor ref alpha ML and OT
void extractStaveChipId(std::string const volName, int &stave, int &chip)
int getLayer(int chipIdx) const
static const char * getFT3VolPattern()
int getChipIndex(int dir, int disc, int stave, int chip) const
std::string getMatrixPath(int direction, int layer, int stave, int chip) const
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"