Project
Loading...
Searching...
No Matches
Geometry.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#include "EMCALBase/Geometry.h"
13
15#include "CCDB/CcdbApi.h"
17#include "GPUROOTCartesianFwd.h"
18#include "MathUtils/Cartesian.h" // IWYU pragma: keep
19
20#include <RtypesCore.h>
21#include <TMath.h>
22#include <TVector3.h>
23#include <TMathBase.h>
24#include <TVector2.h>
25#include <TParticle.h>
26#include <TString.h>
27#include <TGeoNode.h>
28#include <TJAlienCredentials.h>
29#include <TObjArray.h>
30#include <fairlogger/Logger.h>
31
32#include <algorithm>
33#include <cctype>
34#include <cmath>
35#include <cstdio>
36#include <cstring>
37#include <iomanip>
38#include <ostream>
39#include <string>
40#include <span>
41#include <string_view>
42#include <tuple>
43
44#include <TGeoBBox.h>
45#include <TGeoManager.h>
46#include <TGeoMatrix.h>
47
48#include <boost/algorithm/string/predicate.hpp>
49
50using namespace o2::emcal;
51
52// these initialisations are needed for a singleton
53Geometry* Geometry::sGeom = nullptr;
54
56 : mGeoName(geo.mGeoName),
57 mKey110DEG(geo.mKey110DEG),
58 mnSupModInDCAL(geo.mnSupModInDCAL),
59 mNCellsInSupMod(geo.mNCellsInSupMod),
60 mNETAdiv(geo.mNETAdiv),
61 mNPHIdiv(geo.mNPHIdiv),
62 mNCellsInModule(geo.mNCellsInModule),
63 mPhiBoundariesOfSM(geo.mPhiBoundariesOfSM),
64 mPhiCentersOfSM(geo.mPhiCentersOfSM),
65 mPhiCentersOfSMSec(geo.mPhiCentersOfSMSec),
66 mPhiCentersOfCells(geo.mPhiCentersOfCells),
67 mCentersOfCellsEtaDir(geo.mCentersOfCellsEtaDir),
68 mCentersOfCellsPhiDir(geo.mCentersOfCellsPhiDir),
69 mEtaCentersOfCells(geo.mEtaCentersOfCells),
70 mNCells(geo.mNCells),
71 mNPhi(geo.mNPhi),
72 mCentersOfCellsXDir(geo.mCentersOfCellsXDir),
73 mEnvelop(geo.mEnvelop),
74 mArm1EtaMin(geo.mArm1EtaMin),
75 mArm1EtaMax(geo.mArm1EtaMax),
76 mArm1PhiMin(geo.mArm1PhiMin),
77 mArm1PhiMax(geo.mArm1PhiMax),
78 mEtaMaxOfTRD1(geo.mEtaMaxOfTRD1),
79 mDCALPhiMin(geo.mDCALPhiMin),
80 mDCALPhiMax(geo.mDCALPhiMax),
81 mEMCALPhiMax(geo.mEMCALPhiMax),
82 mDCALStandardPhiMax(geo.mDCALStandardPhiMax),
83 mDCALInnerExtandedEta(geo.mDCALInnerExtandedEta),
84 mDCALInnerEdge(geo.mDCALInnerEdge),
85 mShishKebabTrd1Modules(geo.mShishKebabTrd1Modules),
86 mParSM(geo.mParSM),
87 mPhiModuleSize(geo.mPhiModuleSize),
88 mEtaModuleSize(geo.mEtaModuleSize),
89 mPhiTileSize(geo.mPhiTileSize),
90 mEtaTileSize(geo.mEtaTileSize),
91 mNZ(geo.mNZ),
92 mIPDistance(geo.mIPDistance),
93 mLongModuleSize(geo.mLongModuleSize),
94 mShellThickness(geo.mShellThickness),
95 mZLength(geo.mZLength),
96 mSampling(geo.mSampling),
97 mECPbRadThickness(geo.mECPbRadThickness),
98 mECScintThick(geo.mECScintThick),
99 mNECLayers(geo.mNECLayers),
100 mNumberOfSuperModules(geo.mNumberOfSuperModules),
101 mEMCSMSystem(geo.mEMCSMSystem),
102 mFrontSteelStrip(geo.mFrontSteelStrip),
103 mLateralSteelStrip(geo.mLateralSteelStrip),
104 mPassiveScintThick(geo.mPassiveScintThick),
105 mPhiSuperModule(geo.mPhiSuperModule),
106 mNPhiSuperModule(geo.mNPhiSuperModule),
107 mTrd1Angle(geo.mTrd1Angle),
108 m2Trd1Dx2(geo.m2Trd1Dx2),
109 mPhiGapForSM(geo.mPhiGapForSM),
110 mTrd1AlFrontThick(geo.mTrd1AlFrontThick),
111 mTrd1BondPaperThick(geo.mTrd1BondPaperThick),
112 mILOSS(geo.mILOSS),
113 mIHADR(geo.mIHADR),
114 mSteelFrontThick(geo.mSteelFrontThick), // obsolete data member?
115 mCellIndexLookup(geo.mCellIndexLookup)
116{
117}
118
119Geometry::Geometry(const std::string_view name, const std::string_view mcname, const std::string_view mctitle)
120 : mGeoName(name)
121{
122 DefineEMC(mcname, mctitle);
123
125
127 for (auto icell = 0; icell < mNCells; icell++) {
128 mCellIndexLookup[icell] = CalculateCellIndex(icell);
129 }
130
131 LOG(debug) << "Name <<" << name << ">>";
132}
133
135{
136 LOG(fatal) << "assignment operator, not implemented";
137 return *this;
138}
139
141{
142 if (this == sGeom) {
143 LOG(error) << "Do not call delete on me";
144 return;
145 }
146
147 for (Int_t smod = 0; smod < mNumberOfSuperModules; smod++) {
148 if (SMODULEMATRIX[smod]) {
149 delete SMODULEMATRIX[smod];
150 }
151 }
152}
153
155{
156 Geometry* rv = sGeom;
157 if (!rv) {
159 }
160 return rv;
161}
162
163Geometry* Geometry::GetInstance(const std::string_view name, const std::string_view mcname,
164 const std::string_view mctitle)
165{
166 if (!sGeom) {
167 if (name.length() == 0) { // get default geometry
168 sGeom = new Geometry(DEFAULT_GEOMETRY, mcname, mctitle);
169 } else {
170 sGeom = new Geometry(name, mcname, mctitle);
171 } // end if strcmp(name,"")
172 return sGeom;
173 } // end if sGeom
174 if (sGeom->GetName() != name) {
175 LOG(info) << "\n current geometry is " << sGeom->GetName() << " : you should not call " << name;
176 } // end
177 return sGeom;
178
179 return nullptr;
180}
181
182Geometry* Geometry::GetInstanceFromRunNumber(Int_t runNumber, const std::string_view geoName,
183 const std::string_view mcname, const std::string_view mctitle)
184{
185 using boost::algorithm::contains;
186
187 // printf("AliEMCALGeometry::GetInstanceFromRunNumber() - run %d, geoName <<%s>> \n",runNumber,geoName.Data());
188
189 if (runNumber >= 104064 && runNumber < 140000) {
190 // 2009-2010 runs
191 // First year geometry, 4 SM.
192
193 if (contains(geoName, "FIRSTYEARV1") && geoName != std::string("")) {
194 LOG(info) << "o2::emcal::Geometry::GetInstanceFromRunNumber() *** ATTENTION *** \n"
195 << "\t Specified geometry name <<" << geoName << ">> for run " << runNumber
196 << " is not considered! \n"
197 << "\t In use <<EMCAL_FIRSTYEARV1>>, check run number and year";
198 } else {
199 LOG(info)
200 << "o2::emcal::Geometry::GetInstanceFromRunNumber() - Initialized geometry with name <<EMCAL_FIRSTYEARV1>>";
201 }
202
203 return Geometry::GetInstance("EMCAL_FIRSTYEARV1", mcname, mctitle);
204 }
205 if (runNumber >= 140000 && runNumber <= 170593) {
206 // Almost complete EMCAL geometry, 10 SM. Year 2011 configuration
207
208 if (contains(geoName, "COMPLETEV1") && geoName != std::string("")) {
209 LOG(info) << "o2::emcal::Geometry::GetInstanceFromRunNumber() *** ATTENTION *** \n"
210 << "\t Specified geometry name <<" << geoName << ">> for run " << runNumber
211 << " is not considered! \n"
212 << "\t In use <<EMCAL_COMPLETEV1>>, check run number and year";
213 } else {
214 LOG(info)
215 << "o2::emcal::Geometry::GetInstanceFromRunNumber() - Initialized geometry with name <<EMCAL_COMPLETEV1>>";
216 }
217 return Geometry::GetInstance("EMCAL_COMPLETEV1", mcname, mctitle);
218 }
219 if (runNumber > 176000 && runNumber <= 197692) {
220 // Complete EMCAL geometry, 12 SM. Year 2012 and on
221 // The last 2 SM were not active, anyway they were there.
222
223 if (contains(geoName, "COMPLETE12SMV1") && geoName != std::string("")) {
224 LOG(info) << "o2::emcal::Geometry::GetInstanceFromRunNumber() *** ATTENTION *** \n"
225 << "\t Specified geometry name <<" << geoName << " >> for run " << runNumber
226 << " is not considered! \n"
227 << "\t In use <<EMCAL_COMPLETE12SMV1>>, check run number and year";
228 } else {
229 LOG(info) << "o2::emcal::Geometry::GetInstanceFromRunNumber() - Initialized geometry with name "
230 "<<EMCAL_COMPLETE12SMV1>>";
231 }
232 return Geometry::GetInstance("EMCAL_COMPLETE12SMV1", mcname, mctitle);
233 }
234 // Run 2
235 // EMCAL + DCAL geometry, 20 SM. Year 2015 and on
236
237 if (contains(geoName, "DCAL_8SM") && geoName != std::string("")) {
238 LOG(info) << "o2::emcal::Geometry::GetInstanceFromRunNumber() *** ATTENTION *** \n"
239 << "\t Specified geometry name <<" << geoName << ">> for run " << runNumber
240 << " is not considered! \n"
241 << "\t In use <<EMCAL_COMPLETE12SMV1_DCAL_8SM>>, check run number and year";
242 } else {
243 LOG(info) << "o2::emcal::Geometry::GetInstanceFromRunNumber() - Initialized geometry with name "
244 "<<EMCAL_COMPLETE12SMV1_DCAL_8SM>>";
245 }
246 return Geometry::GetInstance("EMCAL_COMPLETE12SMV1_DCAL_8SM", mcname, mctitle);
247}
248
249void Geometry::DefineSamplingFraction(const std::string_view mcname, const std::string_view mctitle)
250{
251 // Jun 05,2006
252 // Look http://rhic.physics.wayne.edu/~pavlinov/ALICE/SHISHKEBAB/RES/linearityAndResolutionForTRD1.html
253 // Keep for compatibility
254 //
255 using boost::algorithm::contains;
256
257 // Sampling factor for G3
258 mSampling = 10.87; // Default value - Nov 25,2010
259 if (mNECLayers == 69) { // 10% layer reduction
260 mSampling = 12.55;
261 } else if (mNECLayers == 61) { // 20% layer reduction
262 mSampling = 12.80;
263 } else if (mNECLayers == 77) {
264 if (contains(mGeoName, "V1")) {
265 mSampling = 10.87; // Adding paper sheets and cover plate; Nov 25,2010
266 } else if (mECScintThick > 0.159 && mECScintThick < 0.161) { // original sampling fraction, equal layers
267 mSampling = 12.327; // fECScintThick = fECPbRadThickness = 0.160;
268 } else if (mECScintThick > 0.175 && mECScintThick < 0.177) { // 10% Pb thicknes reduction
269 mSampling = 10.5; // fECScintThick = 0.176, fECPbRadThickness=0.144;
270 } else if (mECScintThick > 0.191 && mECScintThick < 0.193) { // 20% Pb thicknes reduction
271 mSampling = 8.93; // fECScintThick = 0.192, fECPbRadThickness=0.128;
272 }
273 }
274
275 Float_t samplingFactorTranportModel = 1.;
276 // Note: The sampling factors are chosen so that results from the simulation
277 // engines correspond well with testbeam data
278
279 if (contains(mcname, "Geant3") || contains(mcname, "Fluka")) {
280 samplingFactorTranportModel = 1.; // 0.988 // Do nothing
281 } else if (contains(mcname, "Geant4")) {
282 std::string physicslist = mctitle.substr(mctitle.find(":") + 2).data();
283 LOG(info) << "Selected physics list: " << physicslist;
284 // sampling factors for different Geant4 physics list
285 // GEANT4 10.7 -> EMCAL-784
286
287 // set a default (there may be many physics list strings)
288 samplingFactorTranportModel = 0.81;
289 if (physicslist == "FTFP_BERT_EMV+optical") {
290 samplingFactorTranportModel = 0.821;
291 } else if (physicslist == "FTFP_BERT_EMV+optical+biasing" || physicslist == "FTFP_INCLXX_EMV+optical") {
292 samplingFactorTranportModel = 0.81;
293 }
294 }
295
296 LOG(info) << "MC modeler <" << mcname << ">, Title <" << mctitle << ">: Sampling " << std::setw(2)
297 << std::setprecision(3) << mSampling << ", model fraction with respect to G3 "
298 << samplingFactorTranportModel << ", final sampling " << mSampling * samplingFactorTranportModel;
299
300 mSampling *= samplingFactorTranportModel;
301}
302
303void Geometry::DefineEMC(std::string_view /*mcname*/, std::string_view /*mctitle*/)
304{
305 using boost::algorithm::contains;
306
307 // geometry
308 std::transform(mGeoName.begin(), mGeoName.end(), mGeoName.begin(), ::toupper);
309
310 // Convert old geometry names to new ones
311 if (contains(mGeoName, "SHISH_77_TRD1_2X2_FINAL_110DEG")) {
312 if (contains(mGeoName, "PBTH=0.144") && contains(mGeoName, "SCTH=0.176")) {
313 mGeoName = "EMCAL_COMPLETE";
314 } else {
315 mGeoName = "EMCAL_PDC06";
316 }
317 }
318
319 if (contains(mGeoName, "WSUC")) {
320 mGeoName = "EMCAL_WSUC";
321 }
322
323 // check that we have a valid geometry name
324 if (!(contains(mGeoName, "EMCAL_PDC06") || contains(mGeoName, "EMCAL_WSUC") || contains(mGeoName, "EMCAL_COMPLETE") ||
325 contains(mGeoName, "EMCAL_COMPLETEV1") || contains(mGeoName, "EMCAL_COMPLETE12SMV1") ||
326 contains(mGeoName, "EMCAL_FIRSTYEAR") || contains(mGeoName, "EMCAL_FIRSTYEARV1"))) {
327 LOG(fatal) << "Init, " << mGeoName << " is an undefined geometry!\n";
328 }
329
330 // Option to know whether we have the "half" supermodule(s) or not
331 mKey110DEG = 0;
332 if (contains(mGeoName, "COMPLETE") || contains(mGeoName, "PDC06") || contains(mGeoName, "12SM")) {
333 mKey110DEG = 1; // for GetAbsCellId
334 }
335 if (contains(mGeoName, "COMPLETEV1")) {
336 mKey110DEG = 0;
337 }
338
339 mnSupModInDCAL = 0;
340 if (contains(mGeoName, "DCAL_DEV")) {
341 mnSupModInDCAL = 10;
342 } else if (contains(mGeoName, "DCAL_8SM")) {
343 mnSupModInDCAL = 8;
344 } else if (contains(mGeoName, "DCAL")) {
345 mnSupModInDCAL = 6;
346 }
347
348 // JLK 13-Apr-2008
349 // default parameters are those of EMCAL_COMPLETE geometry
350 // all others render variations from these at the end of
351 // geometry-name specific options
352
353 mNumberOfSuperModules = 12; // 12 = 6 * 2 (6 in phi, 2 in Z)
354 mNPhi = 12; // module granularity in phi within smod (azimuth)
355 mNZ = 24; // module granularity along Z within smod (eta)
356 mNPHIdiv = mNETAdiv = 2; // tower granularity within module
357 mArm1PhiMin = 80.0; // degrees, Starting EMCAL Phi position
358 mArm1PhiMax = 200.0; // degrees, Ending EMCAL Phi position
359 mArm1EtaMin = -0.7; // pseudorapidity, Starting EMCAL Eta position
360 mArm1EtaMax = +0.7; // pseudorapidity, Ending EMCAL Eta position
361 mIPDistance = 428.0; // cm, radial distance to front face from nominal vertex point
362 mPhiGapForSM = 2.; // cm, only for final TRD1 geometry
363 mFrontSteelStrip = 0.025; // 0.025cm = 0.25mm (13-may-05 from V.Petrov)
364 mPassiveScintThick = 0.8; // 0.8cm = 8mm (13-may-05 from V.Petrov)
365 mLateralSteelStrip = 0.01; // 0.01cm = 0.1mm (13-may-05 from V.Petrov) - was 0.025
366 mTrd1Angle = 1.5; // in degrees
367
368 mSampling = 1.; // should be calculated with call to DefineSamplingFraction()
369 mNECLayers = 77; // (13-may-05 from V.Petrov) - can be changed with additional options
370 mECScintThick = 0.176; // scintillator layer thickness
371 mECPbRadThickness = 0.144; // lead layer thickness
372
373 mPhiModuleSize = 12.26 - mPhiGapForSM / Float_t(mNPhi); // first assumption
375
376 mZLength = 700.; // Z coverage (cm)
377 mPhiSuperModule = 20.; // phi in degree
378 mDCALInnerEdge = mIPDistance * TMath::Tan(mTrd1Angle * 8. * TMath::DegToRad());
379
380 // modifications to the above for PDC06 geometry
381 if (contains(mGeoName, "PDC06")) { // 18-may-05 - about common structure
382 mECScintThick = mECPbRadThickness = 0.16; // (13-may-05 from V.Petrov)
383 }
384
385 // modifications to the above for WSUC geometry
386 if (contains(mGeoName, "WSUC")) { // 18-may-05 - about common structure
387 mNumberOfSuperModules = 2; // 27-may-05; Nov 24,2010 for TB
388 mNPhi = mNZ = 4;
389 mTrd1AlFrontThick = 1.0; // one cm
390 // Bond paper - two sheets around Sc tile
391 mTrd1BondPaperThick = 0.01; // 0.01cm = 0.1 mm
392
393 mPhiModuleSize = 12.0;
395 mLateralSteelStrip = 0.015; // 0.015cm = 0.15mm
396 }
397
398 // In 2009-2010 data taking runs only 4 SM, in the upper position.
399 if (contains(mGeoName, "FIRSTYEAR")) {
401 mArm1PhiMax = 120.0;
402 }
403
404 if (contains(mGeoName, "FIRSTYEARV1") || contains(mGeoName, "COMPLETEV1") || contains(mGeoName, "COMPLETE12SMV1")) {
405 // Oct 26,2010 : First module has tilt = 0.75 degree :
406 // look to AliEMCALShishKebabTrd1Module::DefineFirstModule(key)
407 // New sizes from production drawing, added Al front plate.
408 // The thickness of sampling is change due to existing two sheets of paper.
409
410 // Will replace fFrontSteelStrip
411 mTrd1AlFrontThick = 1.0; // one cm
412 // Bond paper - two sheets around Sc tile
413 mTrd1BondPaperThick = 0.01; // 0.01cm = 0.1 mm
414
415 mPhiModuleSize = 12.0;
417 mLateralSteelStrip = 0.015; // 0.015cm = 0.15mm
418
419 if (contains(mGeoName, "COMPLETEV1")) {
421 mArm1PhiMax = 180.0;
422 } else if (contains(mGeoName, "COMPLETE12SMV1")) {
424 mArm1PhiMax = 200.0;
425 }
426 if (contains(mGeoName, "DCAL")) {
428 mArm1PhiMax = 320.0;
429 if (contains(mGeoName, "DCAL_8SM")) {
430 mArm1PhiMax = 340.0; // degrees, End of DCAL Phi position
431 } else if (contains(mGeoName, "DCAL_DEV")) {
432 mArm1PhiMin = 40.0; // degrees, Starting EMCAL(shifted) Phi position
433 }
435 }
436 }
437
438 //
439 // Init EMCal/DCal SMs type array
440 mEMCSMSystem.clear();
442
443 for (Int_t i = 0; i < mNumberOfSuperModules; i++) {
445 }
446
447 Int_t iSM = 0;
448
449 //
450 // BASIC EMCAL SM
451 if (contains(mGeoName, "WSUC")) {
452 for (int i = 0; i < 2; i++) {
454 iSM++;
455 }
456 } else if (contains(mGeoName, "FIRSTYEAR")) {
457 for (int i = 0; i < 4; i++) {
459 iSM++;
460 }
461 } else if (contains(mGeoName, "PDC06") || contains(mGeoName, "COMPLETE")) {
462 for (int i = 0; i < 10; i++) {
464 iSM++;
465 }
466 }
467
468 //
469 // EMCAL 110SM
470 if (mKey110DEG > 0 && contains(mGeoName, "12SM")) {
471 for (int i = 0; i < 2; i++) {
473 if (contains(mGeoName, "12SMV1")) {
475 }
476 iSM++;
477 }
478 }
479
480 //
481 // DCAL SM
482 if (mnSupModInDCAL > 0 && contains(mGeoName, "DCAL")) {
483 if (contains(mGeoName, "8SM")) {
484 for (int i = 0; i < mnSupModInDCAL - 2; i++) {
486 iSM++;
487 }
488 for (int i = 0; i < 2; i++) {
489 mEMCSMSystem[iSM] = DCAL_EXT;
490 iSM++;
491 }
492 } else {
493 for (int i = 0; i < mnSupModInDCAL; i++) {
495 iSM++;
496 }
497 }
498 }
499
500 // constant for transition absid <--> indexes
503 mNCells = 0;
504 for (int i = 0; i < mNumberOfSuperModules; i++) {
505 if (GetSMType(i) == EMCAL_STANDARD) {
507 } else if (GetSMType(i) == EMCAL_HALF) {
509 } else if (GetSMType(i) == EMCAL_THIRD || GetSMType(i) == DCAL_EXT) {
511 } else if (GetSMType(i) == DCAL_STANDARD) {
512 mNCells += 2 * mNCellsInSupMod / 3;
513 } else {
514 LOG(error) << "Uknown SuperModule Type !!\n";
515 }
516 }
517
519 if (mNPhiSuperModule < 1) {
521 }
522
523 mPhiTileSize = mPhiModuleSize / double(mNPHIdiv) - mLateralSteelStrip; // 13-may-05
524 mEtaTileSize = mEtaModuleSize / double(mNETAdiv) - mLateralSteelStrip; // 13-may-05
525
527 if (contains(mGeoName, "V1")) {
528 Double_t ws = mECScintThick + mECPbRadThickness + 2. * mTrd1BondPaperThick; // sampling width
529 // Number of Pb tiles = Number of Sc tiles - 1
531 }
532 m2Trd1Dx2 = mEtaModuleSize + 2. * mLongModuleSize * TMath::Tan(mTrd1Angle * TMath::DegToRad() / 2.);
533
534 if (!contains(mGeoName, "WSUC")) {
536 }
537
538 // These parameters are used to create the mother volume to hold the supermodules
539 // 2cm padding added to allow for misalignments - JLK 30-May-2008
540 mEnvelop[0] = mIPDistance - 1.; // mother volume inner radius
541 mEnvelop[1] = mIPDistance + mShellThickness + 1.; // mother volume outer r.
542 mEnvelop[2] = mZLength + 2.; // mother volume length
543
544 // Local coordinates
545 mParSM[0] = GetShellThickness() / 2.;
546 mParSM[1] = GetPhiModuleSize() * GetNPhi() / 2.;
547 mParSM[2] = mZLength / 4.; // divide by 4 to get half-length of SM
548
549 // SM phi boundaries - (0,1),(2,3) ... - has the same boundaries;
553 Double_t kfSupermodulePhiWidth = mPhiSuperModule * TMath::DegToRad();
554 mPhiCentersOfSM[0] = (mArm1PhiMin + mPhiSuperModule / 2.) * TMath::DegToRad(); // Define from First SM
555 mPhiCentersOfSMSec[0] = mPhiCentersOfSM[0]; // the same in the First SM
556 mPhiBoundariesOfSM[0] = mPhiCentersOfSM[0] - TMath::ATan2(mParSM[1], mIPDistance); // 1th and 2th modules)
557 mPhiBoundariesOfSM[1] = mPhiCentersOfSM[0] + TMath::ATan2(mParSM[1], mIPDistance);
558
559 if (mNumberOfSuperModules > 2) { // 2 to Max
560 Int_t tmpSMType = GetSMType(2);
561 for (int i = 1; i < mNPhiSuperModule; i++) {
562 mPhiBoundariesOfSM[2 * i] += mPhiBoundariesOfSM[2 * i - 2] + kfSupermodulePhiWidth;
563 if (tmpSMType == GetSMType(2 * i)) {
564 mPhiBoundariesOfSM[2 * i + 1] += mPhiBoundariesOfSM[2 * i - 1] + kfSupermodulePhiWidth;
565 } else {
566 // changed SM Type, redefine the [2*i+1] Boundaries
567 tmpSMType = GetSMType(2 * i);
568 switch (GetSMType(2 * i)) {
569 case EMCAL_STANDARD:
570 mPhiBoundariesOfSM[2 * i + 1] = mPhiBoundariesOfSM[2 * i] + kfSupermodulePhiWidth;
571 break;
572 case EMCAL_HALF:
573 mPhiBoundariesOfSM[2 * i + 1] = mPhiBoundariesOfSM[2 * i] + 2. * TMath::ATan2((mParSM[1]) / 2, mIPDistance);
574 break;
575 case EMCAL_THIRD:
576 mPhiBoundariesOfSM[2 * i + 1] = mPhiBoundariesOfSM[2 * i] + 2. * TMath::ATan2((mParSM[1]) / 3, mIPDistance);
577 break;
578 case DCAL_STANDARD:
579 mPhiBoundariesOfSM[2 * i] = (mDCALPhiMin - mArm1PhiMin) * TMath::DegToRad() + mPhiBoundariesOfSM[0];
580 mPhiBoundariesOfSM[2 * i + 1] = (mDCALPhiMin - mArm1PhiMin) * TMath::DegToRad() + mPhiBoundariesOfSM[1];
581 break;
582 case DCAL_EXT:
583 mPhiBoundariesOfSM[2 * i + 1] = mPhiBoundariesOfSM[2 * i] + 2. * TMath::ATan2((mParSM[1]) / 3, mIPDistance);
584 break;
585 default:
586 break;
587 };
588 }
589 mPhiCentersOfSM[i] = (mPhiBoundariesOfSM[2 * i] + mPhiBoundariesOfSM[2 * i + 1]) / 2.;
590 mPhiCentersOfSMSec[i] = mPhiBoundariesOfSM[2 * i] + TMath::ATan2(mParSM[1], mIPDistance);
591 }
592 }
593
594 // inner extend in eta (same as outer part) for DCal (0.189917), //calculated from the smallest gap (1# cell to the
595 // 80-degree-edge),
596 const double INNNER_EXTENDED_PHI =
597 1.102840997; // calculated from the smallest gap (1# cell to the 80-degree-edge), too complicatd to explain...
598 mDCALInnerExtandedEta = -TMath::Log(
599 TMath::Tan((TMath::Pi() / 2. - 8 * mTrd1Angle * TMath::DegToRad() +
600 (TMath::Pi() / 2 - mNZ * mTrd1Angle * TMath::DegToRad() - TMath::ATan(TMath::Exp(mArm1EtaMin)) * 2)) /
601 2.));
602
604 mDCALPhiMax = mDCALPhiMin; // DCAl extention will not be included
605 for (Int_t i = 0; i < mNumberOfSuperModules; i += 2) {
606 switch (GetSMType(i)) {
607 case EMCAL_STANDARD:
608 mEMCALPhiMax += 20.;
609 break;
610 case EMCAL_HALF:
611 mEMCALPhiMax += mPhiSuperModule / 2. + INNNER_EXTENDED_PHI;
612 break;
613 case EMCAL_THIRD:
614 mEMCALPhiMax += mPhiSuperModule / 3. + 4.0 * INNNER_EXTENDED_PHI / 3.0;
615 break;
616 case DCAL_STANDARD:
617 mDCALPhiMax += 20.;
619 break;
620 case DCAL_EXT:
621 mDCALPhiMax += mPhiSuperModule / 3. + 4.0 * INNNER_EXTENDED_PHI / 3.0;
622 break;
623 default:
624 LOG(error) << "Unkown SM Type!!\n";
625 break;
626 };
627 }
628 // for compatible reason
629 // if(fNumberOfSuperModules == 4) {fEMCALPhiMax = fArm1PhiMax ;}
630 if (mNumberOfSuperModules == 12) {
632 }
633
634 // called after setting of scintillator and lead layer parameters
635 // called now in AliEMCALv0::CreateGeometry() - 15/03/16
636 // DefineSamplingFraction(mcname,mctitle);
637}
638
639void Geometry::GetGlobal(std::span<const double, 3> loc, std::span<double, 3> glob, int iSM) const
640{
641 const TGeoHMatrix* m = GetMatrixForSuperModule(iSM);
642 if (m) {
643 m->LocalToMaster(loc.data(), glob.data());
644 } else {
645 LOG(fatal) << "Geo matrixes are not loaded \n";
646 }
647}
648
649void Geometry::GetGlobal(const TVector3& vloc, TVector3& vglob, int iSM) const
650{
651 std::array<double, 3> tglob{}, tloc{};
652 vloc.GetXYZ(tloc.data());
653 GetGlobal(tloc, tglob, iSM);
654 vglob.SetXYZ(tglob[0], tglob[1], tglob[2]);
655}
656
657void Geometry::GetGlobal(int absId, std::span<double, 3> glob) const
658{
659 std::array<double, 3> loc{};
660 std::ranges::fill(glob, 0.0);
661 try {
662 auto cellpos = RelPosCellInSModule(absId);
663 loc[0] = cellpos.X();
664 loc[1] = cellpos.Y();
665 loc[2] = cellpos.Z();
666 } catch (InvalidCellIDException& e) {
667 LOG(error) << e.what();
668 return;
669 }
670
671 Int_t nSupMod = std::get<0>(GetCellIndex(absId));
672 const TGeoHMatrix* m = GetMatrixForSuperModule(nSupMod);
673 if (m) {
674 m->LocalToMaster(loc.data(), glob.data());
675 } else {
676 LOG(fatal) << "Geo matrixes are not loaded \n";
677 }
678}
679
680void Geometry::GetGlobal(int absId, TVector3& vglob) const
681{
682 std::array<double, 3> glob{};
683
684 GetGlobal(absId, glob);
685 vglob.SetXYZ(glob[0], glob[1], glob[2]);
686}
687
688std::tuple<double, double> Geometry::EtaPhiFromIndex(Int_t absId) const
689{
690 TVector3 vglob;
691 GetGlobal(absId, vglob);
692 return std::make_tuple(vglob.Eta(), vglob.Phi());
693}
694
695int Geometry::GetAbsCellId(int supermoduleID, int moduleID, int phiInModule, int etaInModule) const
696{
697 // 0 <= nSupMod < fNumberOfSuperModules
698 // 0 <= nModule < fNPHI * fNZ ( fNPHI * fNZ/2 for fKey110DEG=1)
699 // 0 <= nIphi < fNPHIdiv
700 // 0 <= nIeta < fNETAdiv
701 // 0 <= absid < fNCells
702 int cellid = 0; // have to change from 0 to fNCells-1
703 for (int i = 0; i < supermoduleID; i++) {
704 switch (GetSMType(i)) {
705 case EMCAL_STANDARD:
706 cellid += mNCellsInSupMod;
707 break;
708 case EMCAL_HALF:
709 cellid += mNCellsInSupMod / 2;
710 break;
711 case EMCAL_THIRD:
712 cellid += mNCellsInSupMod / 3;
713 break;
714 case DCAL_STANDARD:
715 cellid += 2 * mNCellsInSupMod / 3;
716 break;
717 case DCAL_EXT:
718 cellid += mNCellsInSupMod / 3;
719 break;
720 default:
722 };
723 }
724
725 cellid += mNCellsInModule * moduleID;
726 cellid += mNPHIdiv * phiInModule;
727 cellid += etaInModule;
728 if (!CheckAbsCellId(cellid)) {
729 throw InvalidCellIDException(cellid);
730 }
731
732 return cellid;
733}
734
735std::tuple<int, int, int> Geometry::GetModuleIndexesFromCellIndexesInSModule(int supermoduleID, int phiInSupermodule, int etaInSupermodule) const
736{
737 int nModulesInSMPhi = GetNumberOfModuleInPhiDirection(supermoduleID);
738
739 int moduleEta = etaInSupermodule / mNETAdiv,
740 modulePhi = phiInSupermodule / mNPHIdiv,
741 moduleID = moduleEta * nModulesInSMPhi + modulePhi;
742 int etaInModule = etaInSupermodule % mNETAdiv,
743 phiInModule = phiInSupermodule % mNPHIdiv;
744 // return std::make_tuple(modulePhi, moduleEta, moduleID);
745 return std::make_tuple(phiInModule, etaInModule, moduleID);
746}
747
748Int_t Geometry::GetAbsCellIdFromCellIndexes(Int_t nSupMod, Int_t iphi, Int_t ieta) const
749{
750 // Check if the indeces correspond to existing SM or tower indeces
751 if (iphi < 0 || iphi >= EMCAL_ROWS || ieta < 0 || ieta >= EMCAL_COLS || nSupMod < 0 ||
752 nSupMod >= GetNumberOfSuperModules()) {
753 LOG(debug) << "Wrong cell indexes : SM " << nSupMod << ", column (eta) " << ieta << ", row (phi) " << iphi;
754 return -1;
755 }
756
757 auto indexmod = GetModuleIndexesFromCellIndexesInSModule(nSupMod, iphi, ieta);
758
759 Int_t nIeta = ieta % mNETAdiv,
760 nIphi = iphi % mNPHIdiv;
761 nIeta = mNETAdiv - 1 - nIeta;
762 return GetAbsCellId(nSupMod, std::get<2>(indexmod), nIphi, nIeta);
763}
764
765std::tuple<int, int> Geometry::GlobalRowColFromIndex(int cellID) const
766{
767 if (!CheckAbsCellId(cellID)) {
768 throw InvalidCellIDException(cellID);
769 }
770 auto [supermodule, module, phiInModule, etaInModule] = GetCellIndex(cellID);
771 auto [row, col] = GetCellPhiEtaIndexInSModule(supermodule, module, phiInModule, etaInModule);
772 // add offsets (row / col per supermodule)
773 if (supermodule == 13 || supermodule == 15 || supermodule == 17) {
774 // DCal odd SMs need shift of the col. index in oder to get the global col. index
775 col += 16;
776 }
777 if (supermodule % 2 != 0) {
778 col += mNZ * 2;
779 }
780 int sector = supermodule / 2;
781 if (sector > 0) {
782 for (int isec = 0; isec < sector; isec++) {
783 auto smtype = GetSMType(isec * 2);
784 auto nphism = (smtype == EMCAL_THIRD || smtype == DCAL_EXT) ? GetNPhi() / 3 : GetNPhi();
785 row += 2 * nphism;
786 }
787 }
788 return std::make_tuple(row, col);
789}
790
791std::tuple<int, int, int> Geometry::GetPositionInSupermoduleFromGlobalRowCol(int row, int col) const
792{
793 if (col < 0 || col >= 4 * GetNEta()) {
794 throw RowColException(row, col);
795 }
796 int side = col < GetNEta() * 2 ? 0 : 1,
797 colSM = col % (GetNEta() * 2);
798 int sector = -1,
799 rowSM = row;
800 for (int isec = 0; isec < GetNPhiSuperModule(); isec++) {
801 auto smtype = GetSMType(isec * 2);
802 auto nphism = GetNPhi() * 2;
803 if (smtype == EMCAL_THIRD || smtype == DCAL_EXT) {
804 nphism /= 3;
805 }
806 if (rowSM < nphism) {
807 sector = isec;
808 break;
809 }
810 rowSM -= nphism;
811 }
812 if (sector < 0) {
813 throw RowColException(row, col);
814 }
815 int supermodule = sector * 2 + side;
816 if (supermodule == 13 || supermodule == 15 || supermodule == 17) {
817 // DCal odd SMs need shift of the col. index as global col index includes PHOS hole
818 colSM -= 16;
819 if (colSM < 0) {
820 throw RowColException(row, col); // Position inside PHOS hole specified
821 }
822 }
823 if (supermodule == 12 || supermodule == 14 || supermodule == 16) {
824 if (colSM > 32) {
825 throw RowColException(row, col); // Position inside PHOS hole specified
826 }
827 }
828 return std::make_tuple(supermodule, rowSM, colSM);
829}
830
832{
834 return GetAbsCellIdFromCellIndexes(supermodule, rowSM, colSM);
835}
836
837std::tuple<int, int, int, int> Geometry::GetCellIndexFromGlobalRowCol(int row, int col) const
838{
840 auto indexmod = GetModuleIndexesFromCellIndexesInSModule(supermodule, rowSM, colSM);
841
842 Int_t colInModule = colSM % mNETAdiv,
843 rowInMOdule = rowSM % mNPHIdiv;
844 colInModule = mNETAdiv - 1 - colInModule;
845 return std::make_tuple(supermodule, std::get<2>(indexmod), rowInMOdule, colInModule);
846}
847
848int Geometry::GlobalCol(int cellID) const
849{
850 return std::get<1>(GlobalRowColFromIndex(cellID));
851}
852
853int Geometry::GlobalRow(int cellID) const
854{
855 return std::get<0>(GlobalRowColFromIndex(cellID));
856}
857
858Int_t Geometry::SuperModuleNumberFromEtaPhi(Double_t eta, Double_t phi) const
859{
860 if (TMath::Abs(eta) > mEtaMaxOfTRD1) {
861 throw InvalidPositionException(eta, phi);
862 }
863
864 phi = TVector2::Phi_0_2pi(phi); // move phi to (0,2pi) boundaries
865 Int_t nphism = mNumberOfSuperModules / 2;
866 Int_t nSupMod = 0;
867 for (Int_t i = 0; i < nphism; i++) {
868 LOG(debug) << "Sec " << i << ": Min " << mPhiBoundariesOfSM[2 * i] << ", Max " << mPhiBoundariesOfSM[2 * i + 1];
869 if (phi >= mPhiBoundariesOfSM[2 * i] && phi <= mPhiBoundariesOfSM[2 * i + 1]) {
870 nSupMod = 2 * i;
871 if (eta < 0.0) {
872 nSupMod++;
873 }
874
875 if (GetSMType(nSupMod) == DCAL_STANDARD) { // Gap between DCAL
876 const Int_t nEtaThird = GetNEta() / 3; // integer division intended: truncate to whole eta-bin count
877 if (TMath::Abs(eta) < nEtaThird * mTrd1Angle * TMath::DegToRad()) {
878 throw InvalidPositionException(eta, phi);
879 }
880 }
881
882 LOG(debug) << "eta " << eta << " phi " << phi << " (" << std::setw(5) << std::setprecision(2)
883 << phi * TMath::RadToDeg() << ") : nSupMod " << nSupMod << ": #bound " << i;
884 return nSupMod;
885 }
886 }
887 throw InvalidPositionException(eta, phi);
888}
889
890Int_t Geometry::GetAbsCellIdFromEtaPhi(Double_t eta, Double_t phi) const
891{
892 Int_t nSupMod = SuperModuleNumberFromEtaPhi(eta, phi);
893
894 // phi index first
895 phi = TVector2::Phi_0_2pi(phi);
896 Double_t phiLoc = phi - mPhiCentersOfSMSec[nSupMod / 2];
897 Int_t nphi = mPhiCentersOfCells.size();
898 switch (GetSMType(nSupMod)) {
899 case EMCAL_HALF:
900 nphi /= 2;
901 case EMCAL_THIRD:
902 case DCAL_EXT:
903 nphi /= 3;
904 break;
905 default:
906 // All other supermodules have full number of cells in phi
907 break;
908 };
909
910 Double_t dmin = TMath::Abs(mPhiCentersOfCells[0] - phiLoc),
911 d = 0.;
912 Int_t iphi = 0;
913 for (Int_t i = 1; i < nphi; i++) {
914 d = TMath::Abs(mPhiCentersOfCells[i] - phiLoc);
915 if (d < dmin) {
916 dmin = d;
917 iphi = i;
918 }
919 // printf(" i %i : d %f : dmin %f : fPhiCentersOfCells[i] %f \n", i, d, dmin, fPhiCentersOfCells[i]);
920 }
921 // odd SM are turned with respect of even SM - reverse indexes
922 LOG(debug2) << " iphi " << iphi << " : dmin " << dmin << " (phi " << phi << ", phiLoc " << phiLoc << ")\n";
923
924 // eta index
925 Double_t absEta = TMath::Abs(eta);
926 Int_t neta = mCentersOfCellsEtaDir.size(),
927 etaShift = iphi * neta,
928 ieta = 0;
929 if (GetSMType(nSupMod) == DCAL_STANDARD) {
930 ieta += 16; // jump 16 cells for DCSM
931 }
932 dmin = TMath::Abs(mEtaCentersOfCells[etaShift + ieta] - absEta);
933 for (Int_t i = ieta + 1; i < neta; i++) {
934 d = TMath::Abs(mEtaCentersOfCells[i + etaShift] - absEta);
935 if (d < dmin) {
936 dmin = d;
937 ieta = i;
938 }
939 }
940
941 if (GetSMType(nSupMod) == DCAL_STANDARD) {
942 ieta -= 16; // jump 16 cells for DCSM
943 }
944
945 LOG(debug2) << " ieta " << ieta << " : dmin " << dmin << " (eta=" << eta << ") : nSupMod " << nSupMod;
946
947 // patch for mapping following alice convention
948 if (nSupMod % 2 ==
949 0) { // 47 + 16 -ieta for DCSM, 47 - ieta for others, revert the ordering on A side in order to keep convention.
950 ieta = (neta - 1) - ieta;
951 if (GetSMType(nSupMod) == DCAL_STANDARD) {
952 ieta -= 16; // recover cells for DCSM
953 }
954 }
955
956 return GetAbsCellIdFromCellIndexes(nSupMod, iphi, ieta);
957}
958
959std::tuple<int, int, int, int> Geometry::CalculateCellIndex(Int_t absId) const
960{
961 if (!CheckAbsCellId(absId)) {
962 throw InvalidCellIDException(absId);
963 }
964
965 Int_t tmp = absId;
966 Int_t test = absId;
967
968 Int_t nSupMod = -1;
969 for (nSupMod = -1; test >= 0;) {
970 nSupMod++;
971 tmp = test;
972 switch (GetSMType(nSupMod)) {
973 case EMCAL_STANDARD:
975 break;
976 case EMCAL_HALF:
977 test -= mNCellsInSupMod / 2;
978 break;
979 case DCAL_STANDARD:
980 test -= 2 * mNCellsInSupMod / 3;
981 break;
982 case EMCAL_THIRD:
983 case DCAL_EXT:
984 test -= mNCellsInSupMod / 3;
985 break;
986 default:
988 };
989 }
990
991 Int_t nModule = tmp / mNCellsInModule;
992 tmp = tmp % mNCellsInModule;
993 Int_t nIphi = tmp / mNPHIdiv, nIeta = tmp % mNETAdiv;
994 return std::make_tuple(nSupMod, nModule, nIphi, nIeta);
995}
996
997std::tuple<int, int, int, int> Geometry::GetCellIndex(Int_t absId) const
998{
999 if (!CheckAbsCellId(absId)) {
1000 throw InvalidCellIDException(absId);
1001 }
1002 return mCellIndexLookup[absId];
1003}
1004
1005Int_t Geometry::GetSuperModuleNumber(Int_t absId) const { return std::get<0>(GetCellIndex(absId)); }
1006
1007std::tuple<int, int> Geometry::GetModulePhiEtaIndexInSModule(int supermoduleID, int moduleID) const
1008{
1009 int nModulesInPhi = -1;
1010 switch (GetSMType(supermoduleID)) {
1011 case EMCAL_HALF:
1012 nModulesInPhi = mNPhi / 2; // halfSM
1013 break;
1014 case EMCAL_THIRD:
1015 case DCAL_EXT:
1016 nModulesInPhi = mNPhi / 3; // 1/3 SM
1017 break;
1018 default:
1019 nModulesInPhi = mNPhi; // full SM
1020 break;
1021 };
1022 return std::make_tuple(moduleID % nModulesInPhi, moduleID / nModulesInPhi);
1023}
1024
1025std::tuple<int, int> Geometry::GetCellPhiEtaIndexInSModule(int supermoduleID, int moduleID, int phiInModule,
1026 int etaInModule) const
1027{
1028 auto [phiOfModule, etaOfModule] = GetModulePhiEtaIndexInSModule(supermoduleID, moduleID);
1029
1030 // ieta = etaOfModule*fNETAdiv + (1-etaInModule); // x(module) = -z(SM)
1031 int etaInSupermodule = etaOfModule * mNETAdiv + (mNETAdiv - 1 - etaInModule); // x(module) = -z(SM)
1032 int phiInSupermodule = phiOfModule * mNPHIdiv + phiInModule; // y(module) = y(SM)
1033
1034 if (phiInSupermodule < 0 || etaInSupermodule < 0) {
1035 LOG(debug) << " Supermodule " << supermoduleID << ", Module " << moduleID << " (phi " << phiInModule << ", eta " << etaInModule << ")"
1036 << " => in Supermodule: eta " << etaInSupermodule << ", phi " << phiInSupermodule;
1037 }
1038 return std::make_tuple(phiInSupermodule, etaInSupermodule);
1039}
1040
1041std::tuple<short, short> Geometry::GetTopologicalRowColumn(int supermoduleID, int moduleID, int phiInModule, int etaInModule) const
1042{
1043 auto [iphi, ieta] = GetCellPhiEtaIndexInSModule(supermoduleID, moduleID, phiInModule, etaInModule);
1044 int row = iphi;
1045 int column = ieta;
1046
1047 // Add shifts wrt. supermodule and type of calorimeter
1048 // NOTE:
1049 // * Rows (phi) are arranged that one space is left empty between supermodules in phi
1050 // This is due to the physical gap that forbids clustering
1051 // * For DCAL, there is an additional empty column between two supermodules in eta
1052 // Again, this is to account for the gap in DCAL
1053
1054 row += supermoduleID / 2 * (24 + 1);
1055 // In DCAL, leave a gap between two SMs with same phi
1056 if (!IsDCALSM(supermoduleID)) { // EMCAL
1057 column += supermoduleID % 2 * 48;
1058 } else {
1059 column += supermoduleID % 2 * (48 + 1);
1060 }
1061
1062 return std::make_tuple(static_cast<short>(row), static_cast<short>(column));
1063}
1064
1065std::tuple<int, int> Geometry::ShiftOnlineToOfflineCellIndexes(Int_t supermoduleID, Int_t iphi, Int_t ieta) const
1066{
1067 if (supermoduleID == 13 || supermoduleID == 15 || supermoduleID == 17) {
1068 // DCal odd SMs
1069 ieta -= 16; // Same cabling mapping as for EMCal, not considered offline.
1070 } else if (supermoduleID == 18 || supermoduleID == 19) {
1071 // DCal 1/3 SMs
1072 iphi -= 16; // Needed due to cabling mistake.
1073 }
1074 return {iphi, ieta};
1075}
1076
1077std::tuple<int, int> Geometry::ShiftOfflineToOnlineCellIndexes(Int_t supermoduleID, Int_t iphi, Int_t ieta) const
1078{
1079 if (supermoduleID == 13 || supermoduleID == 15 || supermoduleID == 17) {
1080 // DCal odd SMs
1081 ieta += 16; // Same cabling mapping as for EMCal, not considered offline.
1082 } else if (supermoduleID == 18 || supermoduleID == 19) {
1083 // DCal 1/3 SMs
1084 iphi += 16; // Needed due to cabling mistake.
1085 }
1086 return {iphi, ieta};
1087}
1088
1090{
1091 // Shift index taking into account the difference between standard SM
1092 // and SM of half (or one third) size in phi direction
1093
1094 Int_t phiindex = mCentersOfCellsPhiDir.size();
1095 Double_t zshift = 0.5 * GetDCALInnerEdge();
1096 Double_t xr = 0, yr = 0, zr = 0;
1097
1098 if (!CheckAbsCellId(absId)) {
1099 throw InvalidCellIDException(absId);
1100 }
1101
1102 auto cellindex = GetCellIndex(absId);
1103 Int_t nSupMod = std::get<0>(cellindex), nModule = std::get<1>(cellindex), phiInModule = std::get<2>(cellindex), etaInModule = std::get<3>(cellindex);
1104 auto indexinsm = GetCellPhiEtaIndexInSModule(nSupMod, nModule, phiInModule, etaInModule);
1105 Int_t iphi = std::get<0>(indexinsm), ieta = std::get<1>(indexinsm);
1106
1107 // Get eta position. Careful with ALICE conventions (increase index decrease eta)
1108 Int_t ieta2 = ieta;
1109 if (nSupMod % 2 == 0) {
1110 ieta2 = (mCentersOfCellsEtaDir.size() - 1) -
1111 ieta; // 47-ieta, revert the ordering on A side in order to keep convention.
1112 }
1113
1114 if (GetSMType(nSupMod) == DCAL_STANDARD && nSupMod % 2 != 0) {
1115 ieta2 += 16; // DCAL revert the ordering on C side ...
1116 }
1117 zr = mCentersOfCellsEtaDir[ieta2];
1118 if (GetSMType(nSupMod) == DCAL_STANDARD) {
1119 zr -= zshift; // DCAL shift (SMALLER SM)
1120 }
1121 xr = mCentersOfCellsXDir[ieta2];
1122
1123 // Get phi position. Careful with ALICE conventions (increase index increase phi)
1124 Int_t iphi2 = iphi;
1125 if (GetSMType(nSupMod) == DCAL_EXT || GetSMType(nSupMod) == EMCAL_THIRD) {
1126 if (nSupMod % 2 != 0) {
1127 iphi2 = (phiindex / 3 - 1) - iphi; // 7-iphi [1/3SM], revert the ordering on C side in order to keep convention.
1128 }
1129 yr = mCentersOfCellsPhiDir[iphi2 + phiindex / 3];
1130 } else if (GetSMType(nSupMod) == EMCAL_HALF) {
1131 if (nSupMod % 2 != 0) {
1132 iphi2 = (phiindex / 2 - 1) - iphi; // 11-iphi [1/2SM], revert the ordering on C side in order to keep
1133 }
1134 // convention.
1135 yr = mCentersOfCellsPhiDir[iphi2 + phiindex / 4];
1136 } else {
1137 if (nSupMod % 2 != 0) {
1138 iphi2 = (phiindex - 1) - iphi; // 23-iphi, revert the ordering on C side in order to keep conventi
1139 }
1140 yr = mCentersOfCellsPhiDir[iphi2];
1141 }
1142
1143 LOG(debug) << "absId " << absId << " nSupMod " << nSupMod << " iphi " << iphi << " ieta " << ieta << " xr " << xr
1144 << " yr " << yr << " zr " << zr;
1145 return {xr, yr, zr};
1146}
1147
1149{
1150 // Shift index taking into account the difference between standard SM
1151 // and SM of half (or one third) size in phi direction
1152 Double_t xr = 0, yr = 0, zr = 0;
1153 Int_t nphiIndex = mCentersOfCellsPhiDir.size();
1154 Double_t zshift = 0.5 * GetDCALInnerEdge();
1155 Int_t kDCalshift = 8; // wangml DCal cut first 8 modules(16 cells)
1156
1157 Int_t iphim = -1, ietam = -1;
1158 TVector2 v;
1159 if (!CheckAbsCellId(absId)) {
1160 throw InvalidCellIDException(absId);
1161 }
1162
1163 auto cellindex = GetCellIndex(absId);
1164 Int_t nSupMod = std::get<0>(cellindex), nModule = std::get<1>(cellindex), phiInModule = std::get<2>(cellindex), etaInModule = std::get<3>(cellindex);
1165 auto indmodep = GetModulePhiEtaIndexInSModule(nSupMod, nModule);
1166 iphim = std::get<0>(indmodep);
1167 ietam = std::get<1>(indmodep);
1168 auto indexinsm = GetCellPhiEtaIndexInSModule(nSupMod, nModule, phiInModule, etaInModule);
1169 Int_t iphi = std::get<0>(indexinsm), ieta = std::get<1>(indexinsm);
1170
1171 // Get eta position. Careful with ALICE conventions (increase index decrease eta)
1172 if (nSupMod % 2 == 0) {
1173 ietam = (mCentersOfCellsEtaDir.size() / 2 - 1) -
1174 ietam; // 24-ietam, revert the ordering on A side in order to keep convention.
1175 if (etaInModule == 0) {
1176 etaInModule = 1;
1177 } else {
1178 etaInModule = 0;
1179 }
1180 }
1181
1182 if (GetSMType(nSupMod) == DCAL_STANDARD && (nSupMod % 2) != 0) {
1183 ietam += kDCalshift; // DCAL revert the ordering on C side ....
1184 }
1185 const ShishKebabTrd1Module& mod = GetShishKebabModule(ietam);
1186 mod.GetPositionAtCenterCellLine(etaInModule, distEff, v);
1187 xr = v.Y() - mParSM[0];
1188 zr = v.X() - mParSM[2];
1189 if (GetSMType(nSupMod) == DCAL_STANDARD) {
1190 zr -= zshift; // DCAL shift (SMALLER SM)
1191 }
1192
1193 // Get phi position. Careful with ALICE conventions (increase index increase phi)
1194 Int_t iphi2 = iphi;
1195 if (GetSMType(nSupMod) == DCAL_EXT || GetSMType(nSupMod) == EMCAL_THIRD) {
1196 if (nSupMod % 2 != 0) {
1197 iphi2 = (nphiIndex / 3 - 1) - iphi; // 7-iphi [1/3SM], revert the ordering on C side in order to keep convention.
1198 }
1199 yr = mCentersOfCellsPhiDir[iphi2 + nphiIndex / 3];
1200 } else if (GetSMType(nSupMod) == EMCAL_HALF) {
1201 if (nSupMod % 2 != 0) {
1202 iphi2 = (nphiIndex / 2 - 1) - iphi; // 11-iphi [1/2SM], revert the ordering on C side in order to keep
1203 }
1204 // convention.
1205 yr = mCentersOfCellsPhiDir[iphi2 + nphiIndex / 2];
1206 } else {
1207 if (nSupMod % 2 != 0) {
1208 iphi2 = (nphiIndex - 1) - iphi; // 23-iphi, revert the ordering on C side in order to keep convention.
1209 }
1210 yr = mCentersOfCellsPhiDir[iphi2];
1211 }
1212
1213 LOG(debug) << "absId " << absId << " nSupMod " << nSupMod << " iphi " << iphi << " ieta " << ieta << " xr " << xr
1214 << " yr " << yr << " zr " << zr;
1215 return {xr, yr, zr};
1216}
1217
1219{
1220 LOG(debug2) << " o2::emcal::Geometry::CreateListOfTrd1Modules() started\n";
1221
1222 if (mShishKebabTrd1Modules.empty()) {
1223 for (int iz = 0; iz < mNZ; iz++) {
1224 if (iz == 0) {
1225 // mod = new AliEMCALShishKebabTrd1Module(TMath::Pi()/2.,this);
1226 mShishKebabTrd1Modules.emplace_back(ShishKebabTrd1Module(TMath::Pi() / 2., this));
1227 } else {
1229 }
1230 }
1231 } else {
1232 LOG(debug2) << " Already exits :\n";
1233 }
1234
1237 LOG(debug2) << " mShishKebabTrd1Modules has " << mShishKebabTrd1Modules.size() << " modules : max eta "
1238 << std::setw(5) << std::setprecision(4) << mEtaMaxOfTRD1;
1239
1240 // define grid for cells in eta(z) and x directions in local coordinates system of SM
1241 // Works just for 2x2 case only -- ?? start here
1242 //
1243 //
1244 // Define grid for cells in phi(y) direction in local coordinates system of SM
1245 // as for 2X2 as for 3X3 - Nov 8,2006
1246 //
1247 LOG(debug2) << " Cells grid in phi directions : size " << mCentersOfCellsPhiDir.size();
1248
1249 Int_t ind = 0; // this is phi index
1250 Int_t ieta = 0, nModule = 0;
1251 Double_t xr = 0., zr = 0., theta = 0., phi = 0., eta = 0., r = 0., x = 0., y = 0.;
1252 TVector3 vglob;
1253 Double_t ytCenterModule = 0.0, ytCenterCell = 0.0;
1254
1257
1258 Double_t r0 = mIPDistance + mLongModuleSize / 2.;
1259 for (Int_t it = 0; it < mNPhi; it++) { // cycle on modules
1260 ytCenterModule = -mParSM[1] + mPhiModuleSize * (2 * it + 1) / 2; // center of module
1261 for (Int_t ic = 0; ic < mNPHIdiv; ic++) { // cycle on cells in module
1262 if (mNPHIdiv == 2) {
1263 ytCenterCell = ytCenterModule + mPhiTileSize * (2 * ic - 1) / 2.;
1264 } else if (mNPHIdiv == 3) {
1265 ytCenterCell = ytCenterModule + mPhiTileSize * (ic - 1);
1266 } else if (mNPHIdiv == 1) {
1267 ytCenterCell = ytCenterModule;
1268 }
1269 mCentersOfCellsPhiDir[ind] = ytCenterCell;
1270 // Define grid on phi direction
1271 // Grid is not the same for different eta bin;
1272 // Effect is small but is still here
1273 phi = TMath::ATan2(ytCenterCell, r0);
1274 mPhiCentersOfCells[ind] = phi;
1275
1276 LOG(debug2) << " ind " << std::setw(2) << std::setprecision(2) << ind << " : y " << std::setw(8)
1277 << std::setprecision(3) << mCentersOfCellsPhiDir[ind];
1278 ind++;
1279 }
1280 }
1281
1285
1286 LOG(debug2) << " Cells grid in eta directions : size " << mCentersOfCellsEtaDir.size();
1287
1288 for (Int_t it = 0; it < mNZ; it++) {
1289 const ShishKebabTrd1Module& trd1 = GetShishKebabModule(it);
1290 nModule = mNPhi * it;
1291 for (Int_t ic = 0; ic < mNETAdiv; ic++) {
1292 if (mNPHIdiv == 2) {
1293 trd1.GetCenterOfCellInLocalCoordinateofSM(ic, xr, zr); // case of 2X2
1294 auto indexinsm = GetCellPhiEtaIndexInSModule(0, nModule, 0, ic);
1295 ieta = std::get<1>(indexinsm);
1296 }
1297 if (mNPHIdiv == 3) {
1298 trd1.GetCenterOfCellInLocalCoordinateofSM3X3(ic, xr, zr); // case of 3X3
1299 auto indexinsm = GetCellPhiEtaIndexInSModule(0, nModule, 0, ic);
1300 ieta = std::get<1>(indexinsm);
1301 }
1302 if (mNPHIdiv == 1) {
1303 trd1.GetCenterOfCellInLocalCoordinateofSM1X1(xr, zr); // case of 1X1
1304 auto indexinsm = GetCellPhiEtaIndexInSModule(0, nModule, 0, ic);
1305 ieta = std::get<1>(indexinsm);
1306 }
1307 mCentersOfCellsXDir[ieta] = float(xr) - mParSM[0];
1308 mCentersOfCellsEtaDir[ieta] = float(zr) - mParSM[2];
1309 // Define grid on eta direction for each bin in phi
1310 for (int iphi = 0; iphi < mCentersOfCellsPhiDir.size(); iphi++) {
1311 x = xr + trd1.GetRadius();
1312 y = mCentersOfCellsPhiDir[iphi];
1313 r = TMath::Sqrt(x * x + y * y + zr * zr);
1314 theta = TMath::ACos(zr / r);
1316 // ind = ieta*fCentersOfCellsPhiDir.GetSize() + iphi;
1317 ind = iphi * mCentersOfCellsEtaDir.size() + ieta;
1318 mEtaCentersOfCells[ind] = eta;
1319 }
1320 // printf(" ieta %i : xr + trd1->GetRadius() %f : zr %f : eta %f \n", ieta, xr + trd1->GetRadius(), zr, eta);
1321 }
1322 }
1323
1324 for (Int_t i = 0; i < mCentersOfCellsEtaDir.size(); i++) {
1325 LOG(debug2) << " ind " << std::setw(2) << std::setprecision(2) << i + 1 << " : z " << std::setw(8)
1326 << std::setprecision(3) << mCentersOfCellsEtaDir[i] << " : x " << std::setw(8)
1327 << std::setprecision(3) << mCentersOfCellsXDir[i];
1328 }
1329}
1330
1332{
1333 if (mShishKebabTrd1Modules.size() > 0 && neta >= 0 && neta < mShishKebabTrd1Modules.size()) {
1334 return mShishKebabTrd1Modules.at(neta);
1335 }
1337}
1338
1339Bool_t Geometry::Impact(const TParticle* particle) const
1340{
1341 Bool_t in = kFALSE;
1342 Int_t absID = 0;
1343 math_utils::Point3D<double> vimpact = {0, 0, 0};
1344
1345 ImpactOnEmcal({particle->Vx(), particle->Vy(), particle->Vz()}, particle->Theta(), particle->Phi(), absID, vimpact);
1346
1347 if (absID >= 0) {
1348 in = kTRUE;
1349 }
1350
1351 return in;
1352}
1353
1354void Geometry::ImpactOnEmcal(const math_utils::Point3D<double>& vtx, Double_t theta, Double_t phi, Int_t& absId, math_utils::Point3D<double>& vimpact) const
1355{
1356 math_utils::Vector3D<double> p(TMath::Sin(theta) * TMath::Cos(phi), TMath::Sin(theta) * TMath::Sin(phi), TMath::Cos(theta));
1357
1358 vimpact.SetXYZ(0, 0, 0);
1359 absId = -1;
1360 if (phi == 0 || theta == 0) {
1361 return;
1362 }
1363
1365 Double_t factor = (mIPDistance - vtx.Y()) / p.Y();
1366 direction = vtx + factor * p;
1367
1368 // from particle direction -> tower hitted
1369 absId = GetAbsCellIdFromEtaPhi(direction.Eta(), direction.Phi());
1370
1371 // tower absID hitted -> tower/module plane (evaluated at the center of the tower)
1372
1373 std::array<double, 3> loc{}, loc2{}, loc3{};
1374 std::array<double, 3> glob{}, glob2{}, glob3{};
1375
1376 try {
1377 RelPosCellInSModule(absId).GetCoordinates(loc[0], loc[1], loc[2]);
1378 } catch (InvalidCellIDException& e) {
1379 LOG(error) << e.what();
1380 return;
1381 }
1382
1383 // loc is cell center of tower
1384 auto cellindex = GetCellIndex(absId);
1385 Int_t nSupMod = std::get<0>(cellindex), nModule = std::get<1>(cellindex), phiInModule = std::get<2>(cellindex),
1386 etaInModule = std::get<3>(cellindex);
1387 // look at 2 neighbours-s cell using phiInModule={0,1} and etaInModule={0,1}
1388 Int_t phiInModule2 = -1, etaInModule2 = -1, absId2 = -1, absId3 = -1;
1389 if (etaInModule == 0) {
1390 etaInModule2 = 1;
1391 } else {
1392 etaInModule2 = 0;
1393 }
1394 absId2 = GetAbsCellId(nSupMod, nModule, phiInModule, etaInModule2); // NOLINT(readability-suspicious-call-argument)
1395 if (phiInModule == 0) {
1396 phiInModule2 = 1;
1397 } else {
1398 phiInModule2 = 0;
1399 }
1400 absId3 = GetAbsCellId(nSupMod, nModule, phiInModule2, etaInModule); // NOLINT(readability-suspicious-call-argument)
1401
1402 // 2nd point on emcal cell plane
1403 try {
1404 RelPosCellInSModule(absId2).GetCoordinates(loc2[0], loc2[1], loc2[2]);
1405 } catch (InvalidCellIDException& e) {
1406 LOG(error) << e.what();
1407 return;
1408 }
1409
1410 // 3rd point on emcal cell plane
1411 try {
1412 RelPosCellInSModule(absId3).GetCoordinates(loc3[0], loc3[1], loc3[2]);
1413 } catch (InvalidCellIDException& e) {
1414 LOG(error) << e.what();
1415 return;
1416 }
1417
1418 // Get Matrix
1419 const TGeoHMatrix* m = GetMatrixForSuperModule(nSupMod);
1420 if (m) {
1421 m->LocalToMaster(loc.data(), glob.data());
1422 m->LocalToMaster(loc2.data(), glob2.data());
1423 m->LocalToMaster(loc3.data(), glob3.data());
1424 } else {
1425 LOG(fatal) << "Geo matrixes are not loaded \n";
1426 }
1427
1428 // Equation of Plane from glob,glob2,glob3 (Ax+By+Cz+D=0)
1429 Double_t a = glob[1] * (glob2[2] - glob3[2]) + glob2[1] * (glob3[2] - glob[2]) + glob3[1] * (glob[2] - glob2[2]);
1430 Double_t b = glob[2] * (glob2[0] - glob3[0]) + glob2[2] * (glob3[0] - glob[0]) + glob3[2] * (glob[0] - glob2[0]);
1431 Double_t c = glob[0] * (glob2[1] - glob3[1]) + glob2[0] * (glob3[1] - glob[1]) + glob3[0] * (glob[1] - glob2[1]);
1432 Double_t d = glob[0] * (glob2[1] * glob3[2] - glob3[1] * glob2[2]) +
1433 glob2[0] * (glob3[1] * glob[2] - glob[1] * glob3[2]) +
1434 glob3[0] * (glob[1] * glob2[2] - glob2[1] * glob[2]);
1435 d = -d;
1436
1437 // shift equation of plane from tower/module center to surface along vector (A,B,C) normal to tower/module plane
1438 Double_t dist = mLongModuleSize / 2.;
1439 Double_t norm = TMath::Sqrt(a * a + b * b + c * c);
1440 std::array<double, 3> glob4{};
1442 math_utils::Point3D<double> point = {glob[0], glob[1], glob[2]};
1443 if (point.Dot(dir) < 0) {
1444 dist *= -1;
1445 }
1446 glob4[0] = glob[0] - dist * a / norm;
1447 glob4[1] = glob[1] - dist * b / norm;
1448 glob4[2] = glob[2] - dist * c / norm;
1449 d = glob4[0] * a + glob4[1] * b + glob4[2] * c;
1450 d = -d;
1451
1452 // Line determination (2 points for equation of line : vtx and direction)
1453 // impact between line (particle) and plane (module/tower plane)
1454 Double_t den = a * (vtx.X() - direction.X()) + b * (vtx.Y() - direction.Y()) + c * (vtx.Z() - direction.Z());
1455 if (den == 0) {
1456 LOG(error) << "ImpactOnEmcal() No solution :\n";
1457 return;
1458 }
1459
1460 Double_t length = a * vtx.X() + b * vtx.Y() + c * vtx.Z() + d;
1461 length /= den;
1462
1463 vimpact.SetXYZ(vtx.X() + length * (direction.X() - vtx.X()), vtx.Y() + length * (direction.Y() - vtx.Y()),
1464 vtx.Z() + length * (direction.Z() - vtx.Z()));
1465
1466 // shift vimpact from tower/module surface to center along vector (A,B,C) normal to tower/module plane
1467 vimpact.SetXYZ(vimpact.Z() + dist * a / norm, vimpact.Y() + dist * b / norm, vimpact.Z() + dist * c / norm);
1468}
1469
1471{
1472 if (IsInEMCALOrDCAL(pnt) == EMCAL_ACCEPTANCE) {
1473 return kTRUE;
1474 }
1475 return kFALSE;
1476}
1477
1479{
1480 if (IsInEMCALOrDCAL(pnt) == DCAL_ACCEPTANCE) {
1481 return kTRUE;
1482 }
1483 return kFALSE;
1484}
1485
1487{
1488 Double_t r = sqrt(pnt.X() * pnt.X() + pnt.Y() * pnt.Y());
1489
1490 if (r <= mEnvelop[0]) {
1491 return NON_ACCEPTANCE;
1492 }
1493 Double_t theta = TMath::ATan2(r, pnt.Z());
1494 Double_t eta = 0;
1495 if (theta == 0) {
1496 eta = 9999;
1497 } else {
1498 eta = -TMath::Log(TMath::Tan(theta / 2.));
1499 }
1500 if (eta < mArm1EtaMin || eta > mArm1EtaMax) {
1501 return NON_ACCEPTANCE;
1502 }
1503
1504 Double_t phi = TMath::ATan2(pnt.Y(), pnt.X()) * 180. / TMath::Pi();
1505 if (phi < 0) {
1506 phi += 360; // phi should go from 0 to 360 in this case
1507 }
1508
1509 if (phi >= mArm1PhiMin && phi <= mEMCALPhiMax) {
1510 return EMCAL_ACCEPTANCE;
1511 }
1512 if (phi >= mDCALPhiMin && phi <= mDCALStandardPhiMax && TMath::Abs(eta) > mDCALInnerExtandedEta) {
1513 return DCAL_ACCEPTANCE;
1514 }
1515 if (phi > mDCALStandardPhiMax && phi <= mDCALPhiMax) {
1516 return DCAL_ACCEPTANCE;
1517 }
1518 return NON_ACCEPTANCE;
1519}
1520
1521const TGeoHMatrix* Geometry::GetMatrixForSuperModule(Int_t smod) const
1522{
1523 if (smod < 0 || smod > mNumberOfSuperModules) {
1524 LOG(fatal) << "Wrong supermodule index -> " << smod;
1525 }
1526
1527 if (!SMODULEMATRIX[smod]) {
1528 if (gGeoManager) {
1529 LOG(info) << "Loading EMCAL misalignment matrix for SM " << smod << " from GeoManager.";
1531 } else {
1532 LOG(fatal) << "Cannot find EMCAL misalignment matrices! Recover them either: \n"
1533 << "\t - importing TGeoManager from file geometry.root or \n"
1534 << "\t - from OADB in file OADB/EMCAL/EMCALlocal2master.root or \n"
1535 << "\t - from OCDB in directory OCDB/EMCAL/Align/Data/ or \n"
1536 << "\t - from AliESDs (not in AliAOD) via AliESDRun::GetEMCALMatrix(Int_t superModIndex). \n"
1537 << "Store them via AliEMCALGeometry::SetMisalMatrix(Int_t superModIndex)";
1538 }
1539 }
1540
1541 return SMODULEMATRIX[smod];
1542}
1543
1544const TGeoHMatrix* Geometry::GetMatrixForSuperModuleFromArray(Int_t smod) const
1545{
1546 if (smod < 0 || smod > mNumberOfSuperModules) {
1547 LOG(fatal) << "Wrong supermodule index -> " << smod;
1548 }
1549
1550 return SMODULEMATRIX[smod];
1551}
1552
1553const TGeoHMatrix* Geometry::GetMatrixForSuperModuleFromGeoManager(Int_t smod) const
1554{
1555 Int_t tmpType = -1;
1556 Int_t smOrder = 0;
1557
1558 // Get the order for SM
1559 for (Int_t i = 0; i < smod + 1; i++) {
1560 if (GetSMType(i) == tmpType) {
1561 smOrder++;
1562 } else {
1563 tmpType = GetSMType(i);
1564 smOrder = 1;
1565 }
1566 }
1567
1568 Int_t smType = GetSMType(smod);
1569 TString smName = "";
1570
1571 if (smType == EMCAL_STANDARD) {
1572 smName = "SMOD";
1573 } else if (smType == EMCAL_HALF) {
1574 smName = "SM10";
1575 } else if (smType == EMCAL_THIRD) {
1576 smName = "SM3rd";
1577 } else if (smType == DCAL_STANDARD) {
1578 smName = "DCSM";
1579 } else if (smType == DCAL_EXT) {
1580 smName = "DCEXT";
1581 } else {
1582 LOG(error) << "Unkown SM Type!!\n";
1583 }
1584
1585 std::string path = fmt::format("/cave/barrel_1/{}_{}", smName.Data(), smOrder);
1586
1587 if (!gGeoManager->cd(path.c_str())) {
1588 LOG(fatal) << "Geo manager can not find path " << path << "!\n";
1589 }
1590
1591 return gGeoManager->GetCurrentMatrix();
1592}
1593
1594void Geometry::RecalculateTowerPosition(Float_t drow, Float_t dcol, const Int_t sm, const Float_t depth,
1595 std::span<const float, 15> misaligTransShifts, std::span<const float, 15> misaligRotShifts,
1596 std::span<float, 3> global) const
1597{
1598 // To use in a print later
1599 Float_t droworg = drow;
1600 Float_t dcolorg = dcol;
1601
1602 if (gGeoManager) {
1603 // Recover some stuff
1604
1605 const Int_t nSMod = mNumberOfSuperModules;
1606
1607 gGeoManager->cd("/cave/barrel_1/");
1608 TGeoNode* geoXEn1 = gGeoManager->GetCurrentNode();
1609 std::vector<TGeoNodeMatrix*> geoSM(nSMod);
1610 std::vector<TGeoVolume*> geoSMVol(nSMod);
1611 std::vector<TGeoShape*> geoSMShape(nSMod);
1612 std::vector<TGeoBBox*> geoBox(nSMod);
1613 std::vector<TGeoMatrix*> geoSMMatrix(nSMod);
1614
1615 for (int iSM = 0; iSM < nSMod; iSM++) {
1616 geoSM[iSM] = dynamic_cast<TGeoNodeMatrix*>(geoXEn1->GetDaughter(iSM));
1617 geoSMVol[iSM] = geoSM[iSM]->GetVolume();
1618 geoSMShape[iSM] = geoSMVol[iSM]->GetShape();
1619 geoBox[iSM] = dynamic_cast<TGeoBBox*>(geoSMShape[iSM]);
1620 geoSMMatrix[iSM] = geoSM[iSM]->GetMatrix();
1621 }
1622
1623 if (sm % 2 == 0) {
1624 dcol = 47. - dcol;
1625 drow = 23. - drow;
1626 }
1627
1628 Int_t istrip = 0;
1629 Float_t z0 = 0;
1630 Float_t zb = 0;
1631 Float_t zIs = 0;
1632
1633 Float_t x = 0, y = 0, z = 0; // return variables in terry's RF
1634
1635 //***********************************************************
1636 // Do not like this: too many hardcoded values, is it not already stored somewhere else?
1637 // : need more comments in the code
1638 //***********************************************************
1639
1640 Float_t dz = 6.0; // base cell width in eta
1641 Float_t dx = 6.004; // base cell width in phi
1642
1643 // Float_t L = 26.04; // active tower length for hadron (lead+scint+paper)
1644 // we use the geant numbers 13.87*2=27.74
1645 Float_t teta1 = 0.;
1646
1647 // Do some basic checks
1648 if (dcol >= 47.5 || dcol < -0.5) {
1649 LOG(error) << "Bad tower coordinate dcol=" << dcol << ", where dcol >= 47.5 || dcol<-0.5; org: " << dcolorg;
1650 return;
1651 }
1652 if (drow >= 23.5 || drow < -0.5) {
1653 LOG(error) << "Bad tower coordinate drow=" << drow << ", where drow >= 23.5 || drow<-0.5; org: " << droworg;
1654 return;
1655 }
1656 if (sm >= nSMod || sm < 0) {
1657 LOG(error) << "Bad SM number sm=" << nSMod << ", where sm >= " << sm << " || sm < 0\n";
1658 return;
1659 }
1660
1661 istrip = int((dcol + 0.5) / 2);
1662
1663 // tapering angle
1664 teta1 = TMath::DegToRad() * istrip * 1.5;
1665
1666 // calculation of module corner along z
1667 // as a function of strip
1668
1669 for (int is = 0; is <= istrip; is++) {
1670 teta1 = TMath::DegToRad() * (is * 1.5 + 0.75);
1671 if (is == 0) {
1672 zIs = zIs + 2 * dz * TMath::Cos(teta1);
1673 } else {
1674 zIs =
1675 zIs + 2 * dz * TMath::Cos(teta1) + 2 * dz * TMath::Sin(teta1) * TMath::Tan(teta1 - 0.75 * TMath::DegToRad());
1676 }
1677 }
1678
1679 z0 = dz * (dcol - 2 * istrip + 0.5);
1680 zb = (2 * dz - z0 - depth * TMath::Tan(teta1));
1681
1682 z = zIs - zb * TMath::Cos(teta1);
1683 y = depth / TMath::Cos(teta1) + zb * TMath::Sin(teta1);
1684
1685 x = (drow + 0.5) * dx;
1686
1687 // moving the origin from terry's RF
1688 // to the GEANT one
1689
1690 double xx = y - geoBox[sm]->GetDX();
1691 double yy = -x + geoBox[sm]->GetDY();
1692 double zz = z - geoBox[sm]->GetDZ();
1693 const std::array<double, 3> localIn = {xx, yy, zz};
1694 std::array<double, 3> dglobal{};
1695 // geoSMMatrix[sm]->Print();
1696 // printf("TFF Local (row = %d, col = %d, x = %3.2f, y = %3.2f, z = %3.2f)\n", iroworg, icolorg, localIn[0],
1697 // localIn[1], localIn[2]);
1698 geoSMMatrix[sm]->LocalToMaster(localIn.data(), dglobal.data());
1699 // printf("TFF Global (row = %2.0f, col = %2.0f, x = %3.2f, y = %3.2f, z = %3.2f)\n", drow, dcol, dglobal[0],
1700 // dglobal[1], dglobal[2]);
1701
1702 // apply global shifts
1703 if (sm == 2 || sm == 3) { // sector 1
1704 global[0] = dglobal[0] + misaligTransShifts[3] + misaligRotShifts[3] * TMath::Sin(TMath::DegToRad() * 20);
1705 global[1] = dglobal[1] + misaligTransShifts[4] + misaligRotShifts[4] * TMath::Cos(TMath::DegToRad() * 20);
1706 global[2] = dglobal[2] + misaligTransShifts[5];
1707 } else if (sm == 0 || sm == 1) { // sector 0
1708 global[0] = dglobal[0] + misaligTransShifts[0];
1709 global[1] = dglobal[1] + misaligTransShifts[1];
1710 global[2] = dglobal[2] + misaligTransShifts[2];
1711 } else {
1712 LOG(info) << "Careful, correction not implemented yet!\n";
1713 global[0] = dglobal[0];
1714 global[1] = dglobal[1];
1715 global[2] = dglobal[2];
1716 }
1717 } else {
1718 LOG(fatal) << "Geometry boxes information, check that geometry.root is loaded\n";
1719 }
1720}
1721
1722void Geometry::SetMisalMatrix(const TGeoHMatrix* m, Int_t smod) const
1723{
1724 if (smod >= 0 && smod < mNumberOfSuperModules) {
1725 if (!SMODULEMATRIX[smod]) {
1726 SMODULEMATRIX[smod] = new TGeoHMatrix(*m); // Set only if not set yet
1727 }
1728 } else {
1729 LOG(fatal) << "Wrong supermodule index -> " << smod << std::endl;
1730 }
1731}
1732
1733void Geometry::SetMisalMatrixFromCcdb(const char* path, int timestamp) const
1734{
1735 LOG(info) << "Using CCDB to obtain EMCal alignment.";
1737 std::map<std::string, std::string> metadata; // can be empty
1738 api.init("http://alice-ccdb.cern.ch");
1739 TObjArray* matrices = api.retrieveFromTFileAny<TObjArray>(path, metadata, timestamp);
1740
1741 for (int iSM = 0; iSM < mNumberOfSuperModules; ++iSM) {
1742 auto* mat = dynamic_cast<TGeoHMatrix*>(matrices->At(iSM));
1743 if (mat) {
1744
1745 SetMisalMatrix(mat, iSM);
1746 } else {
1747 LOG(info) << "Could not obtain Alignment Matrix for SM " << iSM;
1748 }
1749 }
1750}
1751
1752Bool_t Geometry::IsDCALSM(Int_t nSupMod) const
1753{
1754 if (mEMCSMSystem[nSupMod] == DCAL_STANDARD || mEMCSMSystem[nSupMod] == DCAL_EXT) {
1755 return kTRUE;
1756 }
1757
1758 return kFALSE;
1759}
1760
1761Bool_t Geometry::IsDCALExtSM(Int_t nSupMod) const
1762{
1763 if (mEMCSMSystem[nSupMod] == DCAL_EXT) {
1764 return kTRUE;
1765 }
1766
1767 return kFALSE;
1768}
1769
1770Double_t Geometry::GetPhiCenterOfSMSec(Int_t nsupmod) const
1771{
1772 int i = nsupmod / 2;
1773 return mPhiCentersOfSMSec[i];
1774}
1775
1776Double_t Geometry::GetPhiCenterOfSM(Int_t nsupmod) const
1777{
1778 int i = nsupmod / 2;
1779 return mPhiCentersOfSM[i];
1780}
1781
1782std::tuple<double, double> Geometry::GetPhiBoundariesOfSM(Int_t nSupMod) const
1783{
1784 int i = 0;
1785 if (nSupMod < 0 || nSupMod > 12 + mnSupModInDCAL - 1) {
1786 throw InvalidModuleException(nSupMod, 12 + mnSupModInDCAL);
1787 }
1788 i = nSupMod / 2;
1789 return std::make_tuple((Double_t)mPhiBoundariesOfSM[2 * i], (Double_t)mPhiBoundariesOfSM[2 * i + 1]);
1790}
1791
1792std::tuple<double, double> Geometry::GetPhiBoundariesOfSMGap(Int_t nPhiSec) const
1793{
1794 if (nPhiSec < 0 || nPhiSec > 5 + mnSupModInDCAL / 2 - 1) {
1795 throw InvalidModuleException(nPhiSec, 5 + mnSupModInDCAL / 2);
1796 }
1797 return std::make_tuple(mPhiBoundariesOfSM[2 * nPhiSec + 1], mPhiBoundariesOfSM[2 * nPhiSec + 2]);
1798}
1799
1800std::tuple<int, int, int> Geometry::getOnlineID(int towerID)
1801{
1802 auto cellindex = GetCellIndex(towerID);
1803 auto supermoduleID = std::get<0>(cellindex);
1804 auto etaphi = GetCellPhiEtaIndexInSModule(supermoduleID, std::get<1>(cellindex), std::get<2>(cellindex), std::get<3>(cellindex));
1805 auto etaphishift = ShiftOfflineToOnlineCellIndexes(supermoduleID, std::get<0>(etaphi), std::get<1>(etaphi));
1806 int row = std::get<0>(etaphishift), col = std::get<1>(etaphishift);
1807
1808 int ddlInSupermoudel = -1;
1809 if ((0 <= row && row < 8) || (8 <= row && row < 16 && 0 <= col && col < 24)) {
1810 ddlInSupermoudel = 0; // first cable row or first half
1811 } else if ((8 <= row && row < 16 && 24 <= col && col < 48) || (16 <= row && row < 24)) {
1812 ddlInSupermoudel = 1; // second half or third cable row;
1813 }
1814 if (supermoduleID % 2 == 1) {
1815 ddlInSupermoudel = 1 - ddlInSupermoudel; // swap for odd=C side, to allow us to cable both sides the same
1816 }
1817
1818 return std::make_tuple(supermoduleID * 2 + ddlInSupermoudel, row, col);
1819}
1820
1821std::tuple<bool, int, int> Geometry::areAbsIDsFromSameTCard(int absId1, int absId2) const
1822{
1823
1824 int rowDiff = -100;
1825 int colDiff = -100;
1826
1827 if (absId1 == absId2) {
1828 return {false, rowDiff, colDiff};
1829 }
1830
1831 // Check if in same SM, if not for sure not same TCard
1832 const int sm1 = GetSuperModuleNumber(absId1);
1833 const int sm2 = GetSuperModuleNumber(absId2);
1834 if (sm1 != sm2) {
1835 return {false, rowDiff, colDiff};
1836 }
1837
1838 // Get the column and row of each absId
1839 const auto [smUnused1, iTower1, iIphi1, iIeta1] = GetCellIndex(absId1);
1840 const auto [row1, col1] = GetCellPhiEtaIndexInSModule(sm1, iTower1, iIphi1, iIeta1);
1841
1842 const auto [smUnused2, iTower2, iIphi2, iIeta2] = GetCellIndex(absId2);
1843 const auto [row2, col2] = GetCellPhiEtaIndexInSModule(sm2, iTower2, iIphi2, iIeta2);
1844
1845 // Define corner of TCard for absId1
1846 const int tcardRow0 = row1 - row1 % 8;
1847 const int tcardCol0 = col1 - col1 % 2;
1848
1849 // Difference of absId2 from corner of absId1's TCard
1850 const int rowOffset = row2 - tcardRow0;
1851 const int colOffset = col2 - tcardCol0;
1852
1853 // Differences between the two cells directly
1854 rowDiff = row1 - row2;
1855 colDiff = col1 - col2;
1856
1857 const bool sameTCard = (rowOffset >= 0 && rowOffset < 8 &&
1858 colOffset >= 0 && colOffset < 2);
1859 return {sameTCard, rowDiff, colDiff};
1860}
std::ostringstream debug
int32_t i
uint32_t supermodule
Definition RawData.h:3
uint32_t side
Definition RawData.h:0
uint32_t col
Definition RawData.h:4
uint32_t c
Definition RawData.h:2
void init(std::string const &hosts)
Definition CcdbApi.cxx:237
std::enable_if<!std::is_base_of< o2::conf::ConfigurableParam, T >::value, T * >::type retrieveFromTFileAny(std::string const &path, std::map< std::string, std::string > const &metadata, long timestamp=-1, std::map< std::string, std::string > *headers=nullptr, std::string const &etag="", const std::string &createdNotAfter="", const std::string &createdNotBefore="") const
Definition CcdbApi.h:662
Error handling access to non-initialized geometry.
EMCAL geometry definition.
Definition Geometry.h:42
std::tuple< int, int, int > GetModuleIndexesFromCellIndexesInSModule(int supermoduleID, int phiInSupermodule, int etaInSupermodule) const
Transition from cell indexes (iphi, ieta) to module indexes (iphim, ietam, nModule)
Definition Geometry.cxx:735
Float_t mFrontSteelStrip
13-may-05
Definition Geometry.h:693
static Geometry * GetInstanceFromRunNumber(Int_t runNumber, const std::string_view="", const std::string_view mcname="TGeant3", const std::string_view mctitle="")
Instanciate geometry depending on the run number. Mostly used in analysis and MC anchors.
Definition Geometry.cxx:182
Float_t mEtaMaxOfTRD1
Max eta in case of TRD1 geometry (see AliEMCALShishKebabTrd1Module)
Definition Geometry.h:660
Int_t GetSuperModuleNumber(Int_t absId) const
Get cell SM, from absolute ID number.
std::tuple< int, int, int, int > CalculateCellIndex(Int_t absId) const
Calculate cell SM, module numbers from absolute ID number.
Definition Geometry.cxx:959
Float_t mIPDistance
Radial Distance of the inner surface of the EMCAL.
Definition Geometry.h:674
Float_t mDCALPhiMin
Minimum angular position of DCAL in Phi (degrees)
Definition Geometry.h:661
Float_t mPassiveScintThick
13-may-05
Definition Geometry.h:695
Float_t mPhiTileSize
Size of phi tile.
Definition Geometry.h:671
int GlobalRow(int cellID) const
Get row number of cell in global numbering scheme.
Definition Geometry.cxx:853
Int_t mNZ
Number of Towers in the Z direction.
Definition Geometry.h:673
Float_t mECScintThick
cm, Thickness of the scintillators
Definition Geometry.h:684
const TGeoHMatrix * GetMatrixForSuperModuleFromGeoManager(Int_t smod) const
Provides shift-rotation matrix for EMCAL from the TGeoManager.
std::tuple< int, int > GetCellPhiEtaIndexInSModule(int supermoduleID, int moduleID, int phiInModule, int etaInModule) const
Get eta-phi indexes of cell in SM.
std::tuple< int, int, int, int > GetCellIndex(Int_t absId) const
Get cell SM, module numbers from absolute ID number.
Definition Geometry.cxx:997
std::tuple< double, double > GetPhiBoundariesOfSM(Int_t nSupMod) const
Int_t mNECLayers
number of scintillator layers
Definition Geometry.h:685
std::vector< Double_t > mPhiCentersOfCells
[fNPhi*fNPHIdiv] from center of SM (-10. < phi < +10.)
Definition Geometry.h:647
const TGeoHMatrix * GetMatrixForSuperModule(Int_t smod) const
Provides shift-rotation matrix for EMCAL from externally set matrix or from TGeoManager.
Geometry & operator=(const Geometry &rvalue)
Assignment operator.
Definition Geometry.cxx:134
Float_t GetDCALInnerEdge() const
Definition Geometry.h:186
std::tuple< int, int, int > getOnlineID(int towerID)
Get link ID, row and column from cell ID, have a look here: https://alice.its.cern....
Int_t GetNEta() const
Get the number of modules in supermodule in #eta direction.
Definition Geometry.h:200
Float_t mEtaModuleSize
Eta -> Y.
Definition Geometry.h:670
void SetMisalMatrixFromCcdb(const char *path="Users/m/mhemmer/EMCAL/Config/GeometryAligned", int timestamp=10000) const
Double_t GetPhiCenterOfSMSec(Int_t nsupmod) const
Float_t GetPhiModuleSize() const
Definition Geometry.h:211
Bool_t CheckAbsCellId(Int_t absId) const
Check whether a cell number is valid.
Definition Geometry.h:724
Float_t mZLength
Total length in z direction.
Definition Geometry.h:679
Float_t mDCALInnerEdge
Inner edge for DCAL.
Definition Geometry.h:666
void CreateListOfTrd1Modules()
Float_t GetShellThickness() const
Definition Geometry.h:184
Int_t mNCellsInModule
Number cell in module.
Definition Geometry.h:641
std::vector< EMCALSMType > mEMCSMSystem
geometry structure
Definition Geometry.h:691
Bool_t IsDCALExtSM(Int_t nSupMod) const
Check if iSupMod is a valid DCal 1/3rd SM.
std::tuple< int, int, int, int > GetCellIndexFromGlobalRowCol(int row, int col) const
Get the cell indices from global position in the EMCAL.
Definition Geometry.cxx:837
Double_t GetPhiCenterOfSM(Int_t nsupmod) const
std::tuple< int, int > GetModulePhiEtaIndexInSModule(int supermoduleID, int moduleID) const
Get eta-phi indexes of module in SM.
std::tuple< int, int, int > GetPositionInSupermoduleFromGlobalRowCol(int row, int col) const
Get the posision (row, col) of a global row-col position.
Definition Geometry.cxx:791
const TGeoHMatrix * GetMatrixForSuperModuleFromArray(Int_t smod) const
Provides shift-rotation matrix for EMCAL from fkSModuleMatrix[smod].
Float_t mTrd1AlFrontThick
Thickness of the Al front plate.
Definition Geometry.h:706
Float_t mSampling
Sampling factor.
Definition Geometry.h:680
Float_t mDCALPhiMax
Maximum angular position of DCAL in Phi (degrees)
Definition Geometry.h:662
Float_t mTrd1BondPaperThick
Thickness of the Bond Paper sheet.
Definition Geometry.h:707
Int_t mNCells
Number of cells in calo.
Definition Geometry.h:652
std::tuple< bool, int, int > areAbsIDsFromSameTCard(int absId1, int absId2) const
Check if 2 cells belong to the same T-Card.
Float_t mArm1PhiMin
Minimum angular position of EMCAL in Phi (degrees)
Definition Geometry.h:658
void SetMisalMatrix(const TGeoHMatrix *m, Int_t smod) const
Int_t mNETAdiv
Number eta division of module.
Definition Geometry.h:639
std::tuple< short, short > GetTopologicalRowColumn(int supermoduleID, int moduleID, int phiInModule, int etaInModule) const
Get topological row and column of cell in SM (same as for clusteriser with artifical gaps)
Float_t mLateralSteelStrip
13-may-05
Definition Geometry.h:694
std::tuple< int, int > GlobalRowColFromIndex(int cellID) const
get (Column,Row) pair of cell in global numbering scheme
Definition Geometry.cxx:765
Float_t mTrd1Angle
angle in x-z plane (in degree)
Definition Geometry.h:701
Float_t mECPbRadThickness
cm, Thickness of the Pb radiators
Definition Geometry.h:683
std::vector< Double_t > mEtaCentersOfCells
[fNEta*fNETAdiv*fNPhi*fNPHIdiv], positive direction (eta>0); eta depend from phi position;
Definition Geometry.h:651
int GetAbsCellId(int supermoduleID, int moduleID, int phiInModule, int etaInModule) const
Get cell absolute ID number from location module (2 times 2 cells) of a super module.
Definition Geometry.cxx:695
Float_t mArm1PhiMax
Maximum angular position of EMCAL in Phi (degrees)
Definition Geometry.h:659
static Geometry * GetInstance()
Get geometry instance. It should have been set before.
Definition Geometry.cxx:154
std::tuple< double, double > EtaPhiFromIndex(Int_t absId) const
Figure out the eta/phi coordinates of a cell.
Definition Geometry.cxx:688
Int_t mKey110DEG
For calculation abs cell id; 19-oct-05.
Definition Geometry.h:636
std::vector< Double_t > mPhiCentersOfSMSec
Phi of centers of section where SM lies; size is fNumberOfSuperModules/2.
Definition Geometry.h:644
std::vector< Double_t > mCentersOfCellsEtaDir
Size fNEta*fNETAdiv (for TRD1 only) (eta or z in SM, in cm)
Definition Geometry.h:648
std::string mGeoName
Geometry name string.
Definition Geometry.h:635
Int_t GetNPhiSuperModule() const
Definition Geometry.h:219
int GlobalCol(int cellID) const
Get column number of cell in global numbering scheme.
Definition Geometry.cxx:848
Float_t mShellThickness
Total thickness in (x,y) direction.
Definition Geometry.h:678
EMCALSMType GetSMType(Int_t nSupMod) const
Definition Geometry.h:244
std::vector< Double_t > mCentersOfCellsPhiDir
Size fNPhi*fNPHIdiv (for TRD1 only) (phi or y in SM, in cm)
Definition Geometry.h:649
Int_t mNPHIdiv
Number phi division of module.
Definition Geometry.h:640
Int_t mnSupModInDCAL
For calculation abs cell id; 06-nov-12.
Definition Geometry.h:637
Float_t mEtaTileSize
Size of eta tile.
Definition Geometry.h:672
void GetGlobal(std::span< const double, 3 > loc, std::span< double, 3 > glob, int iSM) const
Figure out the global coordinates from local coordinates on a supermodule.
Definition Geometry.cxx:639
int SuperModuleNumberFromEtaPhi(Double_t eta, Double_t phi) const
Given a global eta/phi point check if it belongs to a supermodule covered region.
Definition Geometry.cxx:858
void RecalculateTowerPosition(Float_t drow, Float_t dcol, const Int_t sm, const Float_t depth, std::span< const float, 15 > misaligTransShifts, std::span< const float, 15 > misaligRotShifts, std::span< float, 3 > global) const
void DefineEMC(std::string_view mcname, std::string_view mctitle)
Init function of previous class EMCGeometry.
Definition Geometry.cxx:303
Bool_t IsDCALSM(Int_t nSupMod) const
Check if iSupMod is a valid DCal standard SM.
Bool_t Impact(const TParticle *particle) const
Check if particle falls in the EMCal/DCal geometry.
std::vector< ShishKebabTrd1Module > mShishKebabTrd1Modules
List of modules.
Definition Geometry.h:667
Bool_t IsInEMCAL(const math_utils::Point3D< double > &pnt) const
Checks whether point is inside the EMCal volume.
math_utils::Point3D< double > RelPosCellInSModule(Int_t absId, Double_t distEf) const
Look to see what the relative position inside a given cell is for a recpoint.
const std::string & GetName() const
Definition Geometry.h:111
Float_t mEMCALPhiMax
Maximum angular position of EMCAL in Phi (degrees)
Definition Geometry.h:663
Bool_t IsInDCAL(const math_utils::Point3D< double > &pnt) const
Checks whether point is inside the DCal volume.
Int_t mNPhiSuperModule
9 - number supermodule in phi direction
Definition Geometry.h:698
Float_t mPhiModuleSize
Phi -> X.
Definition Geometry.h:669
Float_t mPhiGapForSM
Gap betweeen supermodules in phi direction.
Definition Geometry.h:703
Geometry()=default
Default constructor. It must be kept public for root persistency purposes, but should never be called...
std::array< float, 3 > mParSM
SM sizes as in GEANT (TRD1)
Definition Geometry.h:668
Float_t m2Trd1Dx2
2*dx2 for TRD1
Definition Geometry.h:702
AcceptanceType_t IsInEMCALOrDCAL(const math_utils::Point3D< double > &pnt) const
Checks whether point is inside the EMCal volume (included DCal)
Int_t GetNumberOfSuperModules() const
Definition Geometry.h:209
~Geometry()
Destructor.
Definition Geometry.cxx:140
std::array< const TGeoHMatrix *, EMCAL_MODULES > SMODULEMATRIX
Orientations of EMCAL super modules.
Definition Geometry.h:717
Int_t GetNumberOfModuleInPhiDirection(Int_t nSupMod) const
Definition Geometry.h:472
std::tuple< int, int > ShiftOnlineToOfflineCellIndexes(Int_t supermoduleID, Int_t iphi, Int_t ieta) const
Adapt cell indices in supermodule to online indexing.
Float_t mPhiSuperModule
Phi of normal supermodule (20, in degree)
Definition Geometry.h:697
Float_t mArm1EtaMin
Minimum pseudorapidity position of EMCAL in Eta.
Definition Geometry.h:656
void ImpactOnEmcal(const math_utils::Point3D< double > &vtx, Double_t theta, Double_t phi, Int_t &absId, math_utils::Point3D< double > &vimpact) const
Get the impact coordinates on EMCAL.
Int_t GetNPhi() const
Get the number of modules in supermodule in #phi direction.
Definition Geometry.h:204
Float_t mArm1EtaMax
Maximum pseudorapidity position of EMCAL in Eta.
Definition Geometry.h:657
Int_t GetAbsCellIdFromCellIndexes(Int_t nSupMod, Int_t iphi, Int_t ieta) const
Transition from super module number (nSupMod) and cell indexes (ieta,iphi) to cell absolute ID number...
Definition Geometry.cxx:748
std::vector< Double_t > mCentersOfCellsXDir
Size fNEta*fNETAdiv (for TRD1 only) ( x in SM, in cm)
Definition Geometry.h:654
Int_t mNPhi
Number of Towers in the PHI direction.
Definition Geometry.h:653
const ShishKebabTrd1Module & GetShishKebabModule(Int_t neta) const
Get the Module parameters for a eta.
Int_t mNumberOfSuperModules
default is 12 = 6 * 2
Definition Geometry.h:688
std::tuple< double, double > GetPhiBoundariesOfSMGap(Int_t nPhiSec) const
std::vector< Double_t > mPhiBoundariesOfSM
Phi boundaries of SM in rad; size is fNumberOfSuperModules;.
Definition Geometry.h:642
std::vector< std::tuple< int, int, int, int > > mCellIndexLookup
Lookup table for cell indices.
Definition Geometry.h:718
void DefineSamplingFraction(const std::string_view mcname="", const std::string_view mctitle="")
Set the value of the Sampling used to calibrate the MC hits energy (check)
Definition Geometry.cxx:249
Float_t mDCALStandardPhiMax
Special edge for the case that DCAL contian extension.
Definition Geometry.h:664
Float_t mLongModuleSize
Size of long module.
Definition Geometry.h:675
std::array< float, 3 > mEnvelop
The GEANT TUB for the detector.
Definition Geometry.h:655
int GetAbsCellIdFromEtaPhi(Double_t eta, Double_t phi) const
Get cell absolute ID number from eta and phi location.
Definition Geometry.cxx:890
Int_t mNCellsInSupMod
Number cell in super module.
Definition Geometry.h:638
int GetCellAbsIDFromGlobalRowCol(int row, int col) const
Get the absolute cell ID from global position in the EMCAL.
Definition Geometry.cxx:831
std::tuple< int, int > ShiftOfflineToOnlineCellIndexes(Int_t supermoduleID, Int_t iphi, Int_t ieta) const
Adapt cell indices in supermodule to offline indexing.
std::vector< Double_t > mPhiCentersOfSM
Phi of centers of SM; size is fNumberOfSuperModules/2.
Definition Geometry.h:643
Float_t mDCALInnerExtandedEta
DCAL inner edge in Eta (with some extension)
Definition Geometry.h:665
Exception handling non-existing cell IDs.
const char * what() const noexcept final
Access to error message of the exception.
Error Handling when an invalid module ID (outside the limits) is called.
Exception handling errors due to positions not in the EMCAL area.
Exception handling improper or uninitialized supermodule types.
Handling error for invalid positions in row-column space.
Main class for TRD1 geometry of Shish-Kebab case.
void GetCenterOfCellInLocalCoordinateofSM3X3(Int_t ieta, Double_t &xr, Double_t &zr) const
void GetCenterOfCellInLocalCoordinateofSM1X1(Double_t &xr, Double_t &zr) const
static Double_t ThetaToEta(Double_t theta)
void GetPositionAtCenterCellLine(Int_t ieta, Double_t dist, TVector2 &v) const
const TVector2 & GetCenterOfCellInLocalCoordinateofSM(Int_t ieta) const
GLint GLenum GLint x
Definition glcorearb.h:403
const GLfloat * m
Definition glcorearb.h:4066
const GLdouble * v
Definition glcorearb.h:832
GLuint const GLchar * name
Definition glcorearb.h:781
GLboolean GLboolean GLboolean b
Definition glcorearb.h:1233
GLuint GLsizei GLsizei * length
Definition glcorearb.h:790
GLint GLint GLsizei GLsizei GLsizei depth
Definition glcorearb.h:470
GLsizei const GLchar *const * path
Definition glcorearb.h:3591
GLboolean r
Definition glcorearb.h:1233
GLboolean GLboolean GLboolean GLboolean a
Definition glcorearb.h:1233
GLdouble GLdouble GLdouble z
Definition glcorearb.h:843
const std::string DEFAULT_GEOMETRY
@ EMCAL_ROWS
Number of rows per module for EMCAL.
Definition Constants.h:25
@ EMCAL_COLS
Number of columns per module for EMCAL.
Definition Constants.h:26
FIXME: do not use data model tables.
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
std::vector< int > row