Project
Loading...
Searching...
No Matches
GeometryTGeo.cxx
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
14#include <MathUtils/Utils.h>
15#include <TGeoManager.h>
16#include <TMath.h>
17
18namespace o2
19{
20namespace iotof
21{
22std::unique_ptr<o2::iotof::GeometryTGeo> GeometryTGeo::sInstance;
23
24// Common i/oTOF
25std::string GeometryTGeo::sIOTOFVolumeName = "IOTOFV";
26
27// Inner TOF
28std::string GeometryTGeo::sITOFLayerName = "ITOFLayer";
29std::string GeometryTGeo::sITOFStaveName = "ITOFStave";
30std::string GeometryTGeo::sITOFModuleName = "ITOFModule";
31std::string GeometryTGeo::sITOFChipName = "ITOFChip";
32std::string GeometryTGeo::sITOFSensorName = "ITOFSensor";
33
34// Outer TOF
35std::string GeometryTGeo::sOTOFLayerName = "OTOFLayer";
36std::string GeometryTGeo::sOTOFStaveName = "OTOFStave";
37std::string GeometryTGeo::sOTOFSubStaveName = "OTOFSubStave";
38std::string GeometryTGeo::sOTOFModuleName = "OTOFModule";
39std::string GeometryTGeo::sOTOFChipName = "OTOFChip";
40std::string GeometryTGeo::sOTOFSensorName = "OTOFSensor";
41
42// Forward TOF
43std::string GeometryTGeo::sFTOFLayerName = "FTOFLayer";
44std::string GeometryTGeo::sFTOFChipName = "FTOFChip";
45std::string GeometryTGeo::sFTOFSensorName = "FTOFSensor";
46
47// Backward TOF
48std::string GeometryTGeo::sBTOFLayerName = "BTOFLayer";
49std::string GeometryTGeo::sBTOFChipName = "BTOFChip";
50std::string GeometryTGeo::sBTOFSensorName = "BTOFSensor";
51
52GeometryTGeo::GeometryTGeo(bool build, int loadTrans) : DetMatrixCache()
53{
54 if (sInstance) {
55 LOGP(fatal, "Invalid use of public constructor: o2::iotof::GeometryTGeo instance exists");
56 }
57 if (build) {
58 Build(loadTrans);
59 }
60}
61
63{
64 int numberOfStaves{0};
65
66 std::string layName = lay == 0 ? GeometryTGeo::getITOFLayerPattern() : GeometryTGeo::getOTOFLayerPattern();
67 TGeoVolume* layV = gGeoManager->GetVolume(layName.c_str());
68 if (layV == nullptr) {
69 LOG(fatal) << "Can't find volume " << layName;
70 return -1;
71 }
72
73 TObjArray* nodes = layV->GetNodes();
74 int nNodes = nodes->GetEntriesFast();
75
76 for (int j{0}; j < nNodes; ++j) {
77 if (strstr(nodes->At(j)->GetName(), lay == 0 ? GeometryTGeo::getITOFStavePattern() : GeometryTGeo::getOTOFStavePattern()) != nullptr) {
78 numberOfStaves++;
79 }
80 }
81
82 return numberOfStaves;
83}
84
86{
87 if (lay == 0) {
88 return 1;
89 }
90
91 int numberOfSubStaves{0};
92
93 std::string staveName = GeometryTGeo::getOTOFStavePattern();
94 TGeoVolume* staveV = gGeoManager->GetVolume(staveName.c_str());
95 if (staveV == nullptr) {
96 LOG(fatal) << "Can't find volume " << staveName;
97 return -1;
98 }
99
100 TObjArray* nodes = staveV->GetNodes();
101 int nNodes = nodes->GetEntriesFast();
102
103 for (int j{0}; j < nNodes; ++j) {
104 if (strstr(nodes->At(j)->GetName(), GeometryTGeo::getOTOFSubStavePattern()) != nullptr) {
105 numberOfSubStaves++;
106 }
107 }
108
109 return numberOfSubStaves;
110}
111
113{
114 int numberOfModules{0};
115
116 std::string staveName = lay == 0 ? GeometryTGeo::getITOFStavePattern() : GeometryTGeo::getOTOFSubStavePattern();
117 TGeoVolume* staveV = gGeoManager->GetVolume(staveName.c_str());
118 if (staveV == nullptr) {
119 LOG(fatal) << "Can't find volume " << staveName;
120 return -1;
121 }
122
123 TObjArray* nodes = staveV->GetNodes();
124 int nNodes = nodes->GetEntriesFast();
125
126 for (int j{0}; j < nNodes; ++j) {
127 if (strstr(nodes->At(j)->GetName(), lay == 0 ? GeometryTGeo::getITOFModulePattern() : GeometryTGeo::getOTOFModulePattern()) != nullptr) {
128 numberOfModules++;
129 }
130 }
131
132 return numberOfModules;
133}
134
136{
137 int numberOfChips{0};
138
139 std::string moduleName = lay == 0 ? GeometryTGeo::getITOFModulePattern() : GeometryTGeo::getOTOFModulePattern();
140 TGeoVolume* moduleV = gGeoManager->GetVolume(moduleName.c_str());
141 if (moduleV == nullptr) {
142 LOG(fatal) << "Can't find volume " << moduleName;
143 return -1;
144 }
145
146 TObjArray* nodes = moduleV->GetNodes();
147 int nNodes = nodes->GetEntriesFast();
148
149 for (int j{0}; j < nNodes; ++j) {
150 if (strstr(nodes->At(j)->GetName(), lay == 0 ? GeometryTGeo::getITOFChipPattern() : GeometryTGeo::getOTOFChipPattern()) != nullptr) {
151 numberOfChips++;
152 }
153 }
154
155 return numberOfChips;
156}
157
159{
160 return 0;
161}
162
164{
165 return 0;
166}
167
169{
170 return lay == 0 ? 0 : mLastChipIndex[0] + 1;
171}
172
174{
175 if (index < 0 || index > mLastChipIndex[1]) {
176 LOG(fatal) << "Invalid chip index " << index;
177 return -1;
178 }
179 return index > mLastChipIndex[0] ? 1 : 0;
180}
181
182int GeometryTGeo::getIOTOFChipIndex(int lay, int sta, int substa, int mod, int chip) const
183{
184 return getIOTOFFirstChipIndex(lay) + (sta - 1) * mNumberOfChipsPerStaveIOTOF[lay] + (substa - 1) * mNumberOfChipsPerSubStaveIOTOF[lay] + (mod - 1) * mNumberOfChipsPerModuleIOTOF[lay] + (chip - 1);
185}
186
187bool GeometryTGeo::getIOTOFChipId(int index, int& lay, int& sta, int& substa, int& mod, int& chip) const
188{
189 lay = getIOTOFLayer(index);
191 sta = mNumberOfStavesIOTOF[lay] > 0 ? index / mNumberOfChipsPerStaveIOTOF[lay] : -1;
193 substa = mNumberOfSubStavesIOTOF[lay] > 0 ? index / mNumberOfChipsPerSubStaveIOTOF[lay] : -1;
195 mod = mNumberOfModulesIOTOF[lay] > 0 ? index / mNumberOfChipsPerModuleIOTOF[lay] : -1;
197 return true;
198}
199
201{
202 const auto& specs = ChipSpecificsParam::Instance();
204 loc.SetCoordinates(0.5f * ((specs.ActiveMatrixSizeRows() - specs.PassiveEdgeTop + specs.PassiveEdgeReadOut) - specs.PitchRow) - row * specs.PitchRow,
205 0.f,
206 col * specs.PitchCol + 0.5f * (specs.PitchCol - specs.ActiveMatrixSizeCols()));
207 return loc;
208}
209
211{
212 int lay, sta, substa, mod, chip;
213 getIOTOFChipId(index, lay, sta, substa, mod, chip);
214
215 TString path = Form("/cave_1/barrel_1/%s_2/", GeometryTGeo::getIOTOFVolPattern());
216 sta += 1;
217 substa += 1;
218 mod += 1;
219 chip += 1;
220
221 if (lay == 0) {
222 path += Form("%s_1/", GeometryTGeo::getITOFLayerPattern());
223 if (mNumberOfStavesIOTOF[lay] > 0) {
224 path += Form("%s_%d/", GeometryTGeo::getITOFStavePattern(), sta);
225 }
226 if (mNumberOfModulesIOTOF[lay] > 0) {
227 path += Form("%s_%d/", GeometryTGeo::getITOFModulePattern(), mod);
228 }
229 if (mNumberOfChipsPerModuleIOTOF[lay] > 0) {
231 }
232 } else {
233 path += Form("%s_1/", GeometryTGeo::getOTOFLayerPattern());
234 if (mNumberOfStavesIOTOF[lay] > 0) {
235 path += Form("%s_%d/", GeometryTGeo::getOTOFStavePattern(), sta);
236 }
237 if (mNumberOfSubStavesIOTOF[lay] > 0) {
238 path += Form("%s_%d/", GeometryTGeo::getOTOFSubStavePattern(), substa);
239 }
240 if (mNumberOfModulesIOTOF[lay] > 0) {
241 path += Form("%s_%d/", GeometryTGeo::getOTOFModulePattern(), mod);
242 }
243 if (mNumberOfChipsPerModuleIOTOF[lay] > 0) {
245 }
246 }
247
248 return path;
249}
250
252{
253 auto path = getMatrixPath(index);
254
255 static TGeoHMatrix matTmp;
256 gGeoManager->PushPath();
257
258 if (!gGeoManager->cd(path.Data())) {
259 gGeoManager->PopPath();
260 LOG(error) << "Error in cd-ing to " << path.Data();
261 return nullptr;
262 }
263
264 matTmp = *gGeoManager->GetCurrentMatrix();
265 // LOG(info) << "Path = " << path.Data();
266
267 // Restore the modeler state
268 gGeoManager->PopPath();
269
270 // account for the difference between physical sensitive layer (where charge collection is simulated) and effective sensor thicknesses
271 // TODO: apply translation by the effective sensor thickness, not yet done (see ITS)
272
273 return &matTmp;
274}
275
276void GeometryTGeo::Build(int loadTrans)
277{
278 if (isBuilt()) {
279 LOGP(warning, "Already built");
280 return; // already initialized
281 }
282
283 if (!gGeoManager) {
284 LOGP(fatal, "Geometry is not loaded");
285 }
286
287 auto& iotofPars = IOTOFBaseParam::Instance();
288 if (!iotofPars.segmentedInnerTOF && !iotofPars.segmentedOuterTOF) {
289 return;
290 }
291
292 // Inner/outer TOF
293 for (int j{0}; j < 2; ++j) {
298 }
299
300 // Forward TOF
302
303 // Backward TOF
305
306 int numberOfChips{0};
307 for (int j{0}; j < 2; ++j) {
311 numberOfChips += mNumberOfChipsIOTOF[j];
312 mLastChipIndex[j] = numberOfChips - 1;
313 }
314
315 LOG(info) << "TF3 geometry: numberOfChipsITOF = " << mNumberOfChipsIOTOF[0] << ", numberOfChipsOTOF = "
316 << mNumberOfChipsIOTOF[1] << ", numberOfChips = " << numberOfChips << ", mNumberOfChipsPerStaveITOF"
318
319 setSize(numberOfChips);
322 fillMatrixCache(loadTrans);
323 // fillMatrixCache(o2::math_utils::bit2Mask(o2::math_utils::TransformType::L2G));
324}
325
327{
328 sensors.clear();
329 sensors.reserve(mSize);
330 for (int i = 0; i < mSize; i++) {
331 sensors.push_back(i);
332 }
333}
334
336{
337 // fill for every sensor of IOTOF its tracking frame parameters
338 if (!isTrackingFrameCached() && !sensors.empty()) {
339 size_t newSize = sensors.size();
340 mCacheRefX.resize(newSize);
341 mCacheRefAlpha.resize(newSize);
342 for (int i = 0; i < newSize; i++) {
343 int sensorId = sensors[i];
345 }
346 }
347}
348
350{
351 if (mSize < 1) {
352 LOG(warning) << "The method Build was not called yet";
353 Build(mask);
354 return;
355 }
356
357 LOG(debug) << "Filling matrix cache for " << getName() << " with mask " << mask;
358
359 if ((mask & o2::math_utils::bit2Mask(o2::math_utils::TransformType::L2G)) && !getCacheL2G().isFilled()) {
360 // Matrices for Local (Sensor!!! rather than the full chip) to Global frame transformation
361 LOG(info) << "Loading " << getName() << " L2G matrices from TGeo; there are " << mSize << " matrices";
362 auto& cacheL2G = getCacheL2G();
363 cacheL2G.setSize(mSize);
364
365 for (int i = 0; i < mSize; i++) {
366 TGeoHMatrix* hm = extractMatrixSensor(i);
367 cacheL2G.setMatrix(o2::math_utils::Transform3D(*hm), i);
368 }
369 }
370
371 // build T2L matrices for IOTOF
372 if ((mask & o2::math_utils::bit2Mask(o2::math_utils::TransformType::T2L)) && !getCacheT2L().isFilled()) {
373 LOGP(info, "Loading {} T2L matrices from TGeo for IOTOF", getName());
374 if (sensors.size()) {
375 int m_Size = sensors.size();
376 auto& cacheT2L = getCacheT2L();
377 cacheT2L.setSize(m_Size);
378 for (int i = 0; i < m_Size; i++) {
379 int sensorID = sensors[i];
380 TGeoHMatrix& hm = createT2LMatrix(sensorID);
381 cacheT2L.setMatrix(Mat3D(hm), i);
382 }
383 }
384 }
385}
386
387void GeometryTGeo::extractSensorXAlpha(int chipID, float& x, float& alp)
388{
389 double locA[3] = {-100., 0., 0.}, locB[3] = {100., 0., 0.}, gloA[3], gloB[3];
390 double xp{0}, yp{0};
391
392 const TGeoHMatrix* matL2G = extractMatrixSensor(chipID);
393 matL2G->LocalToMaster(locA, gloA);
394 matL2G->LocalToMaster(locB, gloB);
395 double dx = gloB[0] - gloA[0], dy = gloB[1] - gloA[1];
396 double t = (gloB[0] * dx + gloB[1] * dy) / (dx * dx + dy * dy);
397 xp = gloB[0] - dx * t;
398 yp = gloB[1] - dy * t;
399
400 alp = std::atan2(yp, xp);
401 x = std::hypot(xp, yp);
402 o2::math_utils::bringTo02Pi(alp);
403}
404
405TGeoHMatrix& GeometryTGeo::createT2LMatrix(int chipID)
406{
407 static TGeoHMatrix t2l;
408 t2l.Clear();
409 float alpha = getSensorRefAlpha(chipID);
410 t2l.RotateZ(alpha * TMath::RadToDeg());
411 const TGeoHMatrix* matL2G = extractMatrixSensor(chipID);
412 const TGeoHMatrix& matL2Gi = matL2G->Inverse();
413 t2l.MultiplyLeft(&matL2Gi);
414 return t2l;
415}
416
418{
419 if (!sInstance) {
420 sInstance = std::unique_ptr<GeometryTGeo>(new GeometryTGeo(true, 0));
421 }
422 return sInstance.get();
423}
424
425} // namespace iotof
426} // namespace o2
General auxilliary methods.
std::ostringstream debug
int32_t i
uint32_t j
Definition RawData.h:0
uint32_t col
Definition RawData.h:4
const MatrixCache< Mat3D > & getCacheT2L() const
const char * getName() const
int mSize
prebooked number of sensors
o2::math_utils::Transform3D Mat3D
const MatrixCache< Mat3D > & getCacheL2G() const
int getIOTOFChipIndex(int lay, int sta, int substa, int mod, int chip) const
int extractNumberOfSubStavesIOTOF(int lay) const
static const char * getITOFChipPattern()
static std::string sFTOFSensorName
TString getMatrixPath(int index) const
static std::string sOTOFLayerName
static const char * getIOTOFVolPattern()
static const char * getOTOFLayerPattern()
static const char * getOTOFSubStavePattern()
static const char * getOTOFModulePattern()
static std::string sOTOFSensorName
static std::string sIOTOFVolumeName
o2::math_utils::Point3D< float > detectorToLocal(int row, int col, int chipId) const
static const char * getITOFModulePattern()
void fillMatrixCache(int mask)
void extractSensorXAlpha(int, float &, float &)
static std::string sOTOFSubStaveName
bool isTrackingFrameCached() const
static const char * getOTOFSensorPattern()
static std::string sITOFStaveName
static std::string sFTOFChipName
int extractNumberOfModulesIOTOF(int lay) const
static std::string sOTOFChipName
static std::string sITOFModuleName
static const char * getITOFStavePattern()
static std::string sFTOFLayerName
int extractNumberOfChipsFTOF() const
static const char * getITOFSensorPattern()
static const char * getOTOFStavePattern()
int getIOTOFLayer(int index) const
int getIOTOFFirstChipIndex(int lay) const
GeometryTGeo(bool build=false, int loadTrans=0)
static std::string sBTOFSensorName
static std::string sBTOFChipName
std::vector< float > mCacheRefAlpha
cache for X of IOTOF
static const char * getOTOFChipPattern()
static std::string sITOFChipName
int extractNumberOfChipsPerModuleIOTOF(int lay) const
void Build(int loadTrans)
static std::string sOTOFModuleName
std::vector< float > mCacheRefX
int extractNumberOfStavesIOTOF(int lay) const
std::vector< int > sensors
TGeoHMatrix & createT2LMatrix(int)
static std::string sOTOFStaveName
static std::string sITOFSensorName
static GeometryTGeo * Instance()
static const char * getITOFLayerPattern()
TGeoHMatrix * extractMatrixSensor(int index) const
static std::string sITOFLayerName
int extractNumberOfChipsBTOF() const
static std::string sBTOFLayerName
bool getIOTOFChipId(int index, int &lay, int &sta, int &substa, int &mod, int &chip) const
float getSensorRefAlpha(int chipId) const
GLfloat GLfloat GLfloat alpha
Definition glcorearb.h:279
GLint GLenum GLint x
Definition glcorearb.h:403
GLuint index
Definition glcorearb.h:781
GLsizei const GLchar *const * path
Definition glcorearb.h:3591
GLint GLuint mask
Definition glcorearb.h:291
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
static constexpr int L2G
Definition Cartesian.h:55
static constexpr int T2L
Definition Cartesian.h:56
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
std::vector< int > row