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::sOTOFModuleName = "OTOFModule";
38std::string GeometryTGeo::sOTOFChipName = "OTOFChip";
39std::string GeometryTGeo::sOTOFSensorName = "OTOFSensor";
40
41// Forward TOF
42std::string GeometryTGeo::sFTOFLayerName = "FTOFLayer";
43std::string GeometryTGeo::sFTOFChipName = "FTOFChip";
44std::string GeometryTGeo::sFTOFSensorName = "FTOFSensor";
45
46// Backward TOF
47std::string GeometryTGeo::sBTOFLayerName = "BTOFLayer";
48std::string GeometryTGeo::sBTOFChipName = "BTOFChip";
49std::string GeometryTGeo::sBTOFSensorName = "BTOFSensor";
50
51GeometryTGeo::GeometryTGeo(bool build, int loadTrans) : DetMatrixCache()
52{
53 if (sInstance) {
54 LOGP(fatal, "Invalid use of public constructor: o2::iotof::GeometryTGeo instance exists");
55 }
56 if (build) {
57 Build(loadTrans);
58 }
59}
60
62{
63 int numberOfStaves{0};
64
65 std::string layName = lay == 0 ? GeometryTGeo::getITOFLayerPattern() : GeometryTGeo::getOTOFLayerPattern();
66 TGeoVolume* layV = gGeoManager->GetVolume(layName.c_str());
67 if (layV == nullptr) {
68 LOG(fatal) << "Can't find volume " << layName;
69 return -1;
70 }
71
72 TObjArray* nodes = layV->GetNodes();
73 int nNodes = nodes->GetEntriesFast();
74
75 for (int j{0}; j < nNodes; ++j) {
76 if (strstr(nodes->At(j)->GetName(), lay == 0 ? GeometryTGeo::getITOFStavePattern() : GeometryTGeo::getOTOFStavePattern()) != nullptr) {
77 numberOfStaves++;
78 }
79 }
80
81 return numberOfStaves;
82}
83
85{
86 int numberOfModules{0};
87
88 std::string staveName = lay == 0 ? GeometryTGeo::getITOFStavePattern() : GeometryTGeo::getOTOFStavePattern();
89 TGeoVolume* staveV = gGeoManager->GetVolume(staveName.c_str());
90 if (staveV == nullptr) {
91 LOG(fatal) << "Can't find volume " << staveName;
92 return -1;
93 }
94
95 TObjArray* nodes = staveV->GetNodes();
96 int nNodes = nodes->GetEntriesFast();
97
98 for (int j{0}; j < nNodes; ++j) {
99 if (strstr(nodes->At(j)->GetName(), lay == 0 ? GeometryTGeo::getITOFModulePattern() : GeometryTGeo::getOTOFModulePattern()) != nullptr) {
100 numberOfModules++;
101 }
102 }
103
104 return numberOfModules;
105}
106
108{
109 int numberOfChips{0};
110
111 std::string moduleName = lay == 0 ? GeometryTGeo::getITOFModulePattern() : GeometryTGeo::getOTOFModulePattern();
112 TGeoVolume* moduleV = gGeoManager->GetVolume(moduleName.c_str());
113 if (moduleV == nullptr) {
114 LOG(fatal) << "Can't find volume " << moduleName;
115 return -1;
116 }
117
118 TObjArray* nodes = moduleV->GetNodes();
119 int nNodes = nodes->GetEntriesFast();
120
121 for (int j{0}; j < nNodes; ++j) {
122 if (strstr(nodes->At(j)->GetName(), lay == 0 ? GeometryTGeo::getITOFChipPattern() : GeometryTGeo::getOTOFChipPattern()) != nullptr) {
123 numberOfChips++;
124 }
125 }
126
127 return numberOfChips;
128}
129
131{
132 return 0;
133}
134
136{
137 return 0;
138}
139
141{
142 return lay == 0 ? 0 : mLastChipIndex[0] + 1;
143}
144
146{
147 if (index < 0 || index > mLastChipIndex[1]) {
148 LOG(fatal) << "Invalid chip index " << index;
149 return -1;
150 }
151 return index > mLastChipIndex[0] ? 1 : 0;
152}
153
154int GeometryTGeo::getIOTOFChipIndex(int lay, int sta, int mod, int chip) const
155{
156 return getIOTOFFirstChipIndex(lay) + (sta - 1) * mNumberOfChipsPerStaveIOTOF[lay] + (mod - 1) * mNumberOfChipsPerModuleIOTOF[lay] + (chip - 1);
157}
158
159bool GeometryTGeo::getIOTOFChipId(int index, int& lay, int& sta, int& mod, int& chip) const
160{
161 lay = getIOTOFLayer(index);
163 sta = mNumberOfStavesIOTOF[lay] > 0 ? index / mNumberOfChipsPerStaveIOTOF[lay] : -1;
165 mod = mNumberOfModulesIOTOF[lay] > 0 ? index / mNumberOfChipsPerModuleIOTOF[lay] : -1;
167 return true;
168}
169
171{
172 if (iotofLayer == 0) {
174 }
176}
177
179{
180 const auto& specs = getChipSpecifics(getIOTOFLayer(chipId));
182 loc.SetCoordinates(0.5f * ((specs.ActiveMatrixSizeRows() - specs.PassiveEdgeTop + specs.PassiveEdgeReadOut) - specs.PitchRow) - row * specs.PitchRow,
183 0.f,
184 col * specs.PitchCol + 0.5f * (specs.PitchCol - specs.ActiveMatrixSizeCols()));
185 return loc;
186}
187
189{
190 int lay, sta, mod, chip;
191 getIOTOFChipId(index, lay, sta, mod, chip);
192
193 TString path = Form("/cave_1/barrel_1/%s_2/", GeometryTGeo::getIOTOFVolPattern());
194 sta += 1;
195 mod += 1;
196 chip += 1;
197
198 if (lay == 0) {
199 path += Form("%s_1/", GeometryTGeo::getITOFLayerPattern());
200 if (mNumberOfStavesIOTOF[lay] > 0) {
201 path += Form("%s_%d/", GeometryTGeo::getITOFStavePattern(), sta);
202 }
203 if (mNumberOfModulesIOTOF[lay] > 0) {
204 path += Form("%s_%d/", GeometryTGeo::getITOFModulePattern(), mod);
205 }
206 if (mNumberOfChipsPerModuleIOTOF[lay] > 0) {
208 }
209 } else {
210 path += Form("%s_1/", GeometryTGeo::getOTOFLayerPattern());
211 if (mNumberOfStavesIOTOF[lay] > 0) {
212 path += Form("%s_%d/", GeometryTGeo::getOTOFStavePattern(), sta);
213 }
214 if (mNumberOfModulesIOTOF[lay] > 0) {
215 path += Form("%s_%d/", GeometryTGeo::getOTOFModulePattern(), mod);
216 }
217 if (mNumberOfChipsPerModuleIOTOF[lay] > 0) {
219 }
220 }
221
222 return path;
223}
224
226{
227 auto path = getMatrixPath(index);
228
229 static TGeoHMatrix matTmp;
230 gGeoManager->PushPath();
231
232 if (!gGeoManager->cd(path.Data())) {
233 gGeoManager->PopPath();
234 LOG(error) << "Error in cd-ing to " << path.Data();
235 return nullptr;
236 }
237
238 matTmp = *gGeoManager->GetCurrentMatrix();
239 // LOG(info) << "Path = " << path.Data();
240
241 // Restore the modeler state
242 gGeoManager->PopPath();
243
244 // account for the difference between physical sensitive layer (where charge collection is simulated) and effective sensor thicknesses
245 // TODO: apply translation by the effective sensor thickness, not yet done (see ITS)
246
247 return &matTmp;
248}
249
250void GeometryTGeo::Build(int loadTrans)
251{
252 if (isBuilt()) {
253 LOGP(warning, "Already built");
254 return; // already initialized
255 }
256
257 if (!gGeoManager) {
258 LOGP(fatal, "Geometry is not loaded");
259 }
260
261 auto& iotofPars = IOTOFBaseParam::Instance();
262 if (!iotofPars.segmentedInnerTOF && !iotofPars.segmentedOuterTOF) {
263 return;
264 }
265
266 // Inner/outer TOF
267 for (int j{0}; j < 2; ++j) {
271 }
272
273 // Forward TOF
275
276 // Backward TOF
278
279 int numberOfChips{0};
280 for (int j{0}; j < 2; ++j) {
283 numberOfChips += mNumberOfChipsIOTOF[j];
284 mLastChipIndex[j] = numberOfChips - 1;
285 }
286
287 LOG(info) << "numberOfChipsITOF = " << mNumberOfChipsIOTOF[0] << ", numberOfChipsOTOF = " << mNumberOfChipsIOTOF[1] << ", numberOfChips = " << numberOfChips << ", mNumberOfChipesPerStaveITOF" << mNumberOfChipsPerStaveIOTOF[0];
288
289 setSize(numberOfChips);
292 fillMatrixCache(loadTrans);
293 // fillMatrixCache(o2::math_utils::bit2Mask(o2::math_utils::TransformType::L2G));
294}
295
297{
298 sensors.clear();
299 sensors.reserve(mSize);
300 for (int i = 0; i < mSize; i++) {
301 sensors.push_back(i);
302 }
303}
304
306{
307 // fill for every sensor of IOTOF its tracking frame parameters
308 if (!isTrackingFrameCached() && !sensors.empty()) {
309 size_t newSize = sensors.size();
310 mCacheRefX.resize(newSize);
311 mCacheRefAlpha.resize(newSize);
312 for (int i = 0; i < newSize; i++) {
313 int sensorId = sensors[i];
315 }
316 }
317}
318
320{
321 if (mSize < 1) {
322 LOG(warning) << "The method Build was not called yet";
323 Build(mask);
324 return;
325 }
326
327 LOG(debug) << "Filling matrix cache for " << getName() << " with mask " << mask;
328
329 if ((mask & o2::math_utils::bit2Mask(o2::math_utils::TransformType::L2G)) && !getCacheL2G().isFilled()) {
330 // Matrices for Local (Sensor!!! rather than the full chip) to Global frame transformation
331 LOG(info) << "Loading " << getName() << " L2G matrices from TGeo; there are " << mSize << " matrices";
332 auto& cacheL2G = getCacheL2G();
333 cacheL2G.setSize(mSize);
334
335 for (int i = 0; i < mSize; i++) {
336 TGeoHMatrix* hm = extractMatrixSensor(i);
337 cacheL2G.setMatrix(o2::math_utils::Transform3D(*hm), i);
338 }
339 }
340
341 // build T2L matrices for IOTOF
342 if ((mask & o2::math_utils::bit2Mask(o2::math_utils::TransformType::T2L)) && !getCacheT2L().isFilled()) {
343 LOGP(info, "Loading {} T2L matrices from TGeo for IOTOF", getName());
344 if (sensors.size()) {
345 int m_Size = sensors.size();
346 auto& cacheT2L = getCacheT2L();
347 cacheT2L.setSize(m_Size);
348 for (int i = 0; i < m_Size; i++) {
349 int sensorID = sensors[i];
350 TGeoHMatrix& hm = createT2LMatrix(sensorID);
351 cacheT2L.setMatrix(Mat3D(hm), i);
352 }
353 }
354 }
355}
356
357void GeometryTGeo::extractSensorXAlpha(int chipID, float& x, float& alp)
358{
359 double locA[3] = {-100., 0., 0.}, locB[3] = {100., 0., 0.}, gloA[3], gloB[3];
360 double xp{0}, yp{0};
361
362 const TGeoHMatrix* matL2G = extractMatrixSensor(chipID);
363 matL2G->LocalToMaster(locA, gloA);
364 matL2G->LocalToMaster(locB, gloB);
365 double dx = gloB[0] - gloA[0], dy = gloB[1] - gloA[1];
366 double t = (gloB[0] * dx + gloB[1] * dy) / (dx * dx + dy * dy);
367 xp = gloB[0] - dx * t;
368 yp = gloB[1] - dy * t;
369
370 alp = std::atan2(yp, xp);
371 x = std::hypot(xp, yp);
372 o2::math_utils::bringTo02Pi(alp);
373}
374
375TGeoHMatrix& GeometryTGeo::createT2LMatrix(int chipID)
376{
377 static TGeoHMatrix t2l;
378 t2l.Clear();
379 float alpha = getSensorRefAlpha(chipID);
380 t2l.RotateZ(alpha * TMath::RadToDeg());
381 const TGeoHMatrix* matL2G = extractMatrixSensor(chipID);
382 const TGeoHMatrix& matL2Gi = matL2G->Inverse();
383 t2l.MultiplyLeft(&matL2Gi);
384 return t2l;
385}
386
388{
389 if (!sInstance) {
390 sInstance = std::unique_ptr<GeometryTGeo>(new GeometryTGeo(true, 0));
391 }
392 return sInstance.get();
393}
394
395} // namespace iotof
396} // 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
static const char * getITOFChipPattern()
static std::string sFTOFSensorName
TString getMatrixPath(int index) const
static std::string sOTOFLayerName
static const char * getIOTOFVolPattern()
static const ChipSpecifics & getChipSpecifics(int iotofLayer)
static const char * getOTOFLayerPattern()
bool getIOTOFChipId(int index, int &lay, int &sta, int &mod, int &chip) const
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 &)
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 getIOTOFChipIndex(int lay, int sta, int mod, int chip) const
int extractNumberOfChipsBTOF() const
static std::string sBTOFLayerName
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:54
static constexpr int T2L
Definition Cartesian.h:55
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
std::vector< int > row