1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
18 //_________________________________________________________________________
19 // Geometry class for EMCAL : singleton
20 // EMCAL consists of layers of scintillator and lead
21 // Places the the Barrel Geometry of The EMCAL at Midrapidity
22 // between 80 and 180(or 190) degrees of Phi and
24 // Number of Modules and Layers may be controlled by
25 // the name of the instance defined
26 // EMCAL geometry tree:
27 // EMCAL -> superModule -> module -> tower(cell)
29 // absId -> nSupMod -> nModule -> (nIphi,nIeta)
31 //*-- Author: Sahal Yacoob (LBL / UCT)
32 // and : Yves Schutz (SUBATECH)
33 // and : Jennifer Klay (LBL)
34 // SHASHLYK : Aleksei Pavlinov (WSU)
39 // --- AliRoot header files ---
40 #include <Riostream.h>
42 #include <TClonesArray.h>
43 #include <TGeoManager.h>
44 #include <TGeoMatrix.h>
48 #include <TObjArray.h>
49 #include <TObjString.h>
57 #include "AliEMCALGeometry.h"
58 #include "AliEMCALShishKebabTrd1Module.h"
59 #include "AliEMCALRecPoint.h"
60 #include "AliEMCALDigit.h"
61 #include "AliEMCALHistoUtilities.h"
63 ClassImp(AliEMCALGeometry)
65 // these initialisations are needed for a singleton
66 AliEMCALGeometry *AliEMCALGeometry::fgGeom = 0;
67 Bool_t AliEMCALGeometry::fgInit = kFALSE;
68 Char_t* AliEMCALGeometry::fgDefaultGeometryName = "SHISH_77_TRD1_2X2_FINAL_110DEG";
71 // You can create the AliEMCALGeometry object independently from anything.
72 // You have to use just the correct name of geometry. If name is empty string the
73 // default name of geometry will be used.
75 // AliEMCALGeometry* g = AliEMCALGeometry::GetInstance(name,title); // first time
77 // g = AliEMCALGeometry::GetInstance(); // after first time
79 // MC: If you work with MC data you have to get geometry the next way:
80 // == =============================
81 // AliRunLoader *rl = AliRunLoader::GetRunLoader();
82 // AliEMCALGeometry *geom = dynamic_cast<AliEMCAL*>(rl->GetAliRun()->GetDetector("EMCAL"))->GetGeometry();
85 AliEMCALGeometry::AliEMCALGeometry()
87 fGeoName(0),fArrayOpts(0),fAlFrontThick(0.),fECPbRadThickness(0.),fECScintThick(0.),
88 fNECLayers(0),fArm1PhiMin(0.),fArm1PhiMax(0.),fArm1EtaMin(0.),fArm1EtaMax(0.),fIPDistance(0.),
89 fShellThickness(0.),fZLength(0.),fGap2Active(0.),fNZ(0),fNPhi(0),fSampling(0.),fNumberOfSuperModules(0),
90 fSteelFrontThick(0.),fFrontSteelStrip(0.),fLateralSteelStrip(0.),fPassiveScintThick(0.),fPhiModuleSize(0.),
91 fEtaModuleSize(0.),fPhiTileSize(0.),fEtaTileSize(0.),fLongModuleSize(0.),fNPhiSuperModule(0),fNPHIdiv(0),fNETAdiv(0),
92 fNCells(0),fNCellsInSupMod(0),fNCellsInModule(0),fNTRUEta(0),fNTRUPhi(0),
93 fNCellsInTRUEta(0), fNCellsInTRUPhi(0), fTrd1Angle(0.),f2Trd1Dx2(0.),
94 fPhiGapForSM(0.),fKey110DEG(0),fPhiBoundariesOfSM(0), fPhiCentersOfSM(0),fEtaMaxOfTRD1(0),
95 fTrd2AngleY(0.),f2Trd2Dy2(0.),fEmptySpace(0.),fTubsR(0.),fTubsTurnAngle(0.),fCentersOfCellsEtaDir(0),
96 fCentersOfCellsXDir(0),fCentersOfCellsPhiDir(0),fEtaCentersOfCells(0),fPhiCentersOfCells(0),
97 fShishKebabTrd1Modules(0), fNAdditionalOpts(0),
98 fILOSS(-1), fIHADR(-1)
100 // default ctor only for internal usage (singleton)
101 // must be kept public for root persistency purposes, but should never be called by the outside world
102 // CreateListOfTrd1Modules();
103 AliDebug(2, "AliEMCALGeometry : default ctor ");
105 //______________________________________________________________________
106 AliEMCALGeometry::AliEMCALGeometry(const Text_t* name, const Text_t* title)
107 : AliGeometry(name, title),
108 fGeoName(0),fArrayOpts(0),fAlFrontThick(0.),fECPbRadThickness(0.),fECScintThick(0.),
109 fNECLayers(0),fArm1PhiMin(0.),fArm1PhiMax(0.),fArm1EtaMin(0.),fArm1EtaMax(0.),fIPDistance(0.),
110 fShellThickness(0.),fZLength(0.),fGap2Active(0.),fNZ(0),fNPhi(0),fSampling(0.),fNumberOfSuperModules(0),
111 fSteelFrontThick(0.),fFrontSteelStrip(0.),fLateralSteelStrip(0.),fPassiveScintThick(0.),fPhiModuleSize(0.),
112 fEtaModuleSize(0.),fPhiTileSize(0.),fEtaTileSize(0.),fLongModuleSize(0.),fNPhiSuperModule(0),fNPHIdiv(0),fNETAdiv(0),
113 fNCells(0),fNCellsInSupMod(0),fNCellsInModule(0),fNTRUEta(0),fNTRUPhi(0),
114 fNCellsInTRUEta(0), fNCellsInTRUPhi(0), fTrd1Angle(0.),f2Trd1Dx2(0.),
115 fPhiGapForSM(0.),fKey110DEG(0),fPhiBoundariesOfSM(0), fPhiCentersOfSM(0), fEtaMaxOfTRD1(0),
116 fTrd2AngleY(0.),f2Trd2Dy2(0.),fEmptySpace(0.),fTubsR(0.),fTubsTurnAngle(0.),fCentersOfCellsEtaDir(0),
117 fCentersOfCellsXDir(0),fCentersOfCellsPhiDir(0),fEtaCentersOfCells(0),fPhiCentersOfCells(0),
118 fShishKebabTrd1Modules(0),fNAdditionalOpts(0),
119 fILOSS(-1), fIHADR(-1)
121 // ctor only for internal usage (singleton)
122 AliDebug(2, Form("AliEMCALGeometry(%s,%s) ", name,title));
126 CreateListOfTrd1Modules();
128 if (AliDebugLevel()>=2) {
133 //______________________________________________________________________
134 AliEMCALGeometry::AliEMCALGeometry(const AliEMCALGeometry& geom)
136 fGeoName(geom.fGeoName),
137 fArrayOpts(geom.fArrayOpts),
138 fAlFrontThick(geom.fAlFrontThick),
139 fECPbRadThickness(geom.fECPbRadThickness),
140 fECScintThick(geom.fECScintThick),
141 fNECLayers(geom.fNECLayers),
142 fArm1PhiMin(geom.fArm1PhiMin),
143 fArm1PhiMax(geom.fArm1PhiMax),
144 fArm1EtaMin(geom.fArm1EtaMin),
145 fArm1EtaMax(geom.fArm1EtaMax),
146 fIPDistance(geom.fIPDistance),
147 fShellThickness(geom.fShellThickness),
148 fZLength(geom.fZLength),
149 fGap2Active(geom.fGap2Active),
152 fSampling(geom.fSampling),
153 fNumberOfSuperModules(geom.fNumberOfSuperModules),
154 fSteelFrontThick(geom.fSteelFrontThick),
155 fFrontSteelStrip(geom.fFrontSteelStrip),
156 fLateralSteelStrip(geom.fLateralSteelStrip),
157 fPassiveScintThick(geom.fPassiveScintThick),
158 fPhiModuleSize(geom.fPhiModuleSize),
159 fEtaModuleSize(geom.fEtaModuleSize),
160 fPhiTileSize(geom.fPhiTileSize),
161 fEtaTileSize(geom.fEtaTileSize),
162 fLongModuleSize(geom.fLongModuleSize),
163 fNPhiSuperModule(geom.fNPhiSuperModule),
164 fNPHIdiv(geom.fNPHIdiv),
165 fNETAdiv(geom.fNETAdiv),
166 fNCells(geom.fNCells),
167 fNCellsInSupMod(geom.fNCellsInSupMod),
168 fNCellsInModule(geom.fNCellsInModule),
169 fNTRUEta(geom.fNTRUEta),
170 fNTRUPhi(geom.fNTRUPhi),
171 fNCellsInTRUEta(geom.fNCellsInTRUEta),
172 fNCellsInTRUPhi(geom.fNCellsInTRUPhi),
173 fTrd1Angle(geom.fTrd1Angle),
174 f2Trd1Dx2(geom.f2Trd1Dx2),
175 fPhiGapForSM(geom.fPhiGapForSM),
176 fKey110DEG(geom.fKey110DEG),
177 fPhiBoundariesOfSM(geom.fPhiBoundariesOfSM),
178 fPhiCentersOfSM(geom.fPhiCentersOfSM),
179 fEtaMaxOfTRD1(geom.fEtaMaxOfTRD1),
180 fTrd2AngleY(geom.fTrd2AngleY),
181 f2Trd2Dy2(geom.f2Trd2Dy2),
182 fEmptySpace(geom.fEmptySpace),
184 fTubsTurnAngle(geom.fTubsTurnAngle),
185 fCentersOfCellsEtaDir(geom.fCentersOfCellsEtaDir),
186 fCentersOfCellsXDir(geom.fCentersOfCellsXDir),
187 fCentersOfCellsPhiDir(geom.fCentersOfCellsPhiDir),
188 fEtaCentersOfCells(geom.fEtaCentersOfCells),
189 fPhiCentersOfCells(geom.fPhiCentersOfCells),
190 fShishKebabTrd1Modules(geom.fShishKebabTrd1Modules),
191 fNAdditionalOpts(geom.fNAdditionalOpts),
192 fILOSS(geom.fILOSS), fIHADR(geom.fIHADR)
197 //______________________________________________________________________
198 AliEMCALGeometry::~AliEMCALGeometry(void){
201 //______________________________________________________________________
202 void AliEMCALGeometry::Init(void){
203 // Initializes the EMCAL parameters
204 // naming convention : GUV_WX_N_ gives the composition of a tower
205 // WX inform about the composition of the EM calorimeter section:
206 // thickness in mm of Pb radiator (W) and of scintillator (X), and number of scintillator layers (N)
207 // New geometry: EMCAL_55_25
208 // 24-aug-04 for shish-kebab
209 // SHISH_25 or SHISH_62
210 // 11-oct-05 - correction for pre final design
211 // Feb 06,2006 - decrease the weight of EMCAL
213 // Oct 30,2006 - SHISH_TRD1_CURRENT_1X1, SHISH_TRD1_CURRENT_2X2 or SHISH_TRD1_CURRENT_3X3;
216 fAdditionalOpts[0] = "nl="; // number of sampling layers (fNECLayers)
217 fAdditionalOpts[1] = "pbTh="; // cm, Thickness of the Pb (fECPbRadThick)
218 fAdditionalOpts[2] = "scTh="; // cm, Thickness of the Sc (fECScintThick)
219 fAdditionalOpts[3] = "latSS="; // cm, Thickness of lateral steel strip (fLateralSteelStrip)
220 fAdditionalOpts[4] = "allILOSS="; // = 0,1,2,3,4 (4 - energy loss without fluctuation)
221 fAdditionalOpts[5] = "allIHADR="; // = 0,1,2 (0 - no hadronic interaction)
223 fNAdditionalOpts = sizeof(fAdditionalOpts) / sizeof(char*);
225 fgInit = kFALSE; // Assume failed until proven otherwise.
226 fGeoName = GetName();
229 if(fGeoName.Contains("110DEG") || fGeoName.Contains("CURRENT")) fKey110DEG = 1; // for GetAbsCellId
230 fShishKebabTrd1Modules = 0;
231 fTrd2AngleY = f2Trd2Dy2 = fEmptySpace = fTubsR = fTubsTurnAngle = 0;
233 fNZ = 114; // granularity along Z (eta)
234 fNPhi = 168; // granularity in phi (azimuth)
235 fArm1PhiMin = 80.0; // degrees, Starting EMCAL Phi position
236 fArm1PhiMax = 190.0; // degrees, Ending EMCAL Phi position
237 fArm1EtaMin = -0.7; // pseudorapidity, Starting EMCAL Eta position
238 fArm1EtaMax = +0.7; // pseudorapidity, Ending EMCAL Eta position
239 fIPDistance = 454.0; // cm, Radial distance to inner surface of EMCAL
240 fPhiGapForSM = 0.; // cm, only for final TRD1 geometry
243 if(fGeoName.Contains("SHISH")){ // Only shahslyk now
244 // 7-sep-05; integration issue
245 fArm1PhiMin = 80.0; // 60 -> 80
246 fArm1PhiMax = 180.0; // 180 -> 190
248 fNumberOfSuperModules = 10; // 12 = 6 * 2 (6 in phi, 2 in Z);
249 fSteelFrontThick = 2.54; // 9-sep-04
251 fFrontSteelStrip = fPassiveScintThick = 0.0; // 13-may-05
252 fLateralSteelStrip = 0.025; // before MAY 2005
253 fPhiModuleSize = fEtaModuleSize = 11.4;
254 fPhiTileSize = fEtaTileSize = 5.52; // (11.4-5.52*2)/2. = 0.18 cm (wall thickness)
257 fAlFrontThick = fGap2Active = 0;
258 fNPHIdiv = fNETAdiv = 2;
261 fECScintThick = fECPbRadThickness = 0.2;
262 fSampling = 1.; // 30-aug-04 - should be calculated
263 if(fGeoName.Contains("TWIST")) { // all about EMCAL module
264 fNZ = 27; // 16-sep-04
265 } else if(fGeoName.Contains("TRD")) {
266 fIPDistance = 428.0; // 11-may-05
267 fSteelFrontThick = 0.0; // 3.17 -> 0.0; 28-mar-05 : no stell plate
270 fPhiModuleSize = fEtaModuleSize = 12.26;
271 fNZ = 26; // 11-oct-04
272 fTrd1Angle = 1.3; // in degree
273 // 18-nov-04; 1./0.08112=12.327
274 // http://pdsfweb01.nersc.gov/~pavlinov/ALICE/SHISHKEBAB/RES/linearityAndResolutionForTRD1.html
275 if(fGeoName.Contains("TRD1")) { // 30-jan-05
277 fPhiGapForSM = 2.; // cm, only for final TRD1 geometry
278 if(fGeoName.Contains("MAY05") || fGeoName.Contains("WSUC") || fGeoName.Contains("FINAL") || fGeoName.Contains("CURRENT")){
279 fNumberOfSuperModules = 12; // 20-may-05
280 if(fGeoName.Contains("WSUC")) fNumberOfSuperModules = 1; // 27-may-05
281 fNECLayers = 77; // (13-may-05 from V.Petrov)
282 fPhiModuleSize = 12.5; // 20-may-05 - rectangular shape
283 fEtaModuleSize = 11.9;
284 fECScintThick = fECPbRadThickness = 0.16;// (13-may-05 from V.Petrov)
285 fFrontSteelStrip = 0.025;// 0.025cm = 0.25mm (13-may-05 from V.Petrov)
286 fLateralSteelStrip = 0.01; // 0.01cm = 0.1mm (13-may-05 from V.Petrov) - was 0.025
287 fPassiveScintThick = 0.8; // 0.8cm = 8mm (13-may-05 from V.Petrov)
289 fTrd1Angle = 1.5; // 1.3 or 1.5
291 if(fGeoName.Contains("FINAL") || fGeoName.Contains("CURRENT")) { // 9-sep-05
292 fNumberOfSuperModules = 10;
294 fNumberOfSuperModules = 12;// last two modules have size 10 degree in phi (180<phi<190)
295 fArm1PhiMax = 200.0; // for XEN1 and turn angle of super modules
297 if(fGeoName.Contains("FINAL")) {
298 fPhiModuleSize = 12.26 - fPhiGapForSM / Float_t(fNPhi); // first assumption
299 } else if(fGeoName.Contains("CURRENT")) {
300 fECScintThick = 0.176; // 10% of weight reduction
301 fECPbRadThickness = 0.144; //
302 fLateralSteelStrip = 0.015; // 0.015cm = 0.15mm (Oct 30, from Fred)
303 fPhiModuleSize = 12.00;
304 fPhiGapForSM = (12.26 - fPhiModuleSize)*fNPhi; // have to check
306 fEtaModuleSize = fPhiModuleSize;
307 if(fGeoName.Contains("HUGE")) fNECLayers *= 3; // 28-oct-05 for analysing leakage
310 } else if(fGeoName.Contains("TRD2")) { // 30-jan-05
311 fSteelFrontThick = 0.0; // 11-mar-05
312 fIPDistance+= fSteelFrontThick; // 1-feb-05 - compensate absence of steel plate
313 fTrd1Angle = 1.64; // 1.3->1.64
314 fTrd2AngleY = fTrd1Angle; // symmetric case now
315 fEmptySpace = 0.2; // 2 mm
316 fTubsR = fIPDistance; // 31-jan-05 - as for Fred case
318 fPhiModuleSize = fTubsR*2.*TMath::Tan(fTrd2AngleY*TMath::DegToRad()/2.);
319 fPhiModuleSize -= fEmptySpace/2.; // 11-mar-05
320 fEtaModuleSize = fPhiModuleSize; // 20-may-05
323 fNPHIdiv = fNETAdiv = 2; // 13-oct-04 - division again
324 if(fGeoName.Contains("3X3")) { // 23-nov-04
325 fNPHIdiv = fNETAdiv = 3;
326 } else if(fGeoName.Contains("4X4")) {
327 fNPHIdiv = fNETAdiv = 4;
328 } else if(fGeoName.Contains("1X1")) {
329 fNPHIdiv = fNETAdiv = 1;
332 if(fGeoName.Contains("25")){
334 fECScintThick = fECPbRadThickness = 0.5;
336 if(fGeoName.Contains("WSUC")){ // 18-may-05 - about common structure
337 fShellThickness = 30.; // should be change
341 CheckAdditionalOptions();
342 DefineSamplingFraction();
344 fPhiTileSize = fPhiModuleSize/double(fNPHIdiv) - fLateralSteelStrip; // 13-may-05
345 fEtaTileSize = fEtaModuleSize/double(fNETAdiv) - fLateralSteelStrip; // 13-may-05
347 // constant for transition absid <--> indexes
348 fNCellsInModule = fNPHIdiv*fNETAdiv;
349 fNCellsInSupMod = fNCellsInModule*fNPhi*fNZ;
350 fNCells = fNCellsInSupMod*fNumberOfSuperModules;
351 if(GetKey110DEG()) fNCells -= fNCellsInSupMod;
353 fLongModuleSize = fNECLayers*(fECScintThick + fECPbRadThickness);
354 if(fGeoName.Contains("MAY05")) fLongModuleSize += (fFrontSteelStrip + fPassiveScintThick);
357 if(fGeoName.Contains("TRD")) {
358 f2Trd1Dx2 = fEtaModuleSize + 2.*fLongModuleSize*TMath::Tan(fTrd1Angle*TMath::DegToRad()/2.);
359 if(fGeoName.Contains("TRD2")) { // 27-jan-05
360 f2Trd2Dy2 = fPhiModuleSize + 2.*fLongModuleSize*TMath::Tan(fTrd2AngleY*TMath::DegToRad()/2.);
363 } else Fatal("Init", "%s is an undefined geometry!", fGeoName.Data()) ;
365 fNPhiSuperModule = fNumberOfSuperModules/2;
366 if(fNPhiSuperModule<1) fNPhiSuperModule = 1;
368 fShellThickness = fAlFrontThick + fGap2Active + fNECLayers*GetECScintThick()+(fNECLayers-1)*GetECPbRadThick();
369 if(fGeoName.Contains("SHISH")) {
370 fShellThickness = fSteelFrontThick + fLongModuleSize;
371 if(fGeoName.Contains("TWIST")) { // 13-sep-04
372 fShellThickness = TMath::Sqrt(fLongModuleSize*fLongModuleSize + fPhiModuleSize*fEtaModuleSize);
373 fShellThickness += fSteelFrontThick;
374 } else if(fGeoName.Contains("TRD")) { // 1-oct-04
375 fShellThickness = TMath::Sqrt(fLongModuleSize*fLongModuleSize + f2Trd1Dx2*f2Trd1Dx2);
376 fShellThickness += fSteelFrontThick;
378 fParSM[0] = GetShellThickness()/2.;
379 fParSM[1] = GetPhiModuleSize() * GetNPhi()/2.;
384 fZLength = 2.*ZFromEtaR(fIPDistance+fShellThickness,fArm1EtaMax); // Z coverage
385 fEnvelop[0] = fIPDistance; // mother volume inner radius
386 fEnvelop[1] = fIPDistance + fShellThickness; // mother volume outer r.
387 fEnvelop[2] = 1.00001*fZLength; // add some padding for mother volume.
389 fNumberOfSuperModules = 12;
391 // SM phi boundaries - (0,1),(2,3) .. (10,11) - has the same boundaries; Nov 7, 2006
392 fPhiBoundariesOfSM.Set(fNumberOfSuperModules);
393 fPhiCentersOfSM.Set(fNumberOfSuperModules/2);
394 fPhiBoundariesOfSM[0] = TMath::PiOver2() - TMath::ATan2(fParSM[1] , fIPDistance); // 1th and 2th modules)
395 fPhiBoundariesOfSM[1] = TMath::PiOver2() + TMath::ATan2(fParSM[1] , fIPDistance);
396 fPhiCentersOfSM[0] = TMath::PiOver2();
397 for(int i=1; i<=4; i++) { // from 2th ro 9th
398 fPhiBoundariesOfSM[2*i] = fPhiBoundariesOfSM[0] + 20.*TMath::DegToRad()*i;
399 fPhiBoundariesOfSM[2*i+1] = fPhiBoundariesOfSM[1] + 20.*TMath::DegToRad()*i;
400 fPhiCentersOfSM[i] = fPhiCentersOfSM[0] + 20.*TMath::DegToRad()*i;
402 fPhiBoundariesOfSM[11] = 190.*TMath::DegToRad();
403 fPhiBoundariesOfSM[10] = fPhiBoundariesOfSM[11] - TMath::ATan2((fParSM[1]) , fIPDistance);
404 fPhiCentersOfSM[5] = (fPhiBoundariesOfSM[10]+fPhiBoundariesOfSM[11])/2.;
406 //TRU parameters. These parameters values are not the final ones.
409 fNCellsInTRUEta = 16 ;
410 fNCellsInTRUPhi = 24 ;
412 if(fGeoName.Contains("WSUC")) fNumberOfSuperModules = 1; // Jul 12, 2007
415 AliInfo(" is ended");
418 void AliEMCALGeometry::PrintGeometry()
420 // Separate routine is callable from broswer; Nov 7,2006
421 printf("\nInit: geometry of EMCAL named %s :\n", fGeoName.Data());
423 for(Int_t i=0; i<fArrayOpts->GetEntries(); i++){
424 TObjString *o = (TObjString*)fArrayOpts->At(i);
425 printf(" %i : %s \n", i, o->String().Data());
428 printf("Granularity: %d in eta and %d in phi\n", GetNZ(), GetNPhi()) ;
429 printf("Layout: phi = (%7.1f, %7.1f), eta = (%5.2f, %5.2f), IP = %7.2f -> for EMCAL envelope only\n",
430 GetArm1PhiMin(), GetArm1PhiMax(),GetArm1EtaMin(), GetArm1EtaMax(), GetIPDistance() );
432 printf( " ECAL : %d x (%f cm Pb, %f cm Sc) \n",
433 GetNECLayers(), GetECPbRadThick(), GetECScintThick() ) ;
434 printf(" fSampling %5.2f \n", fSampling );
435 if(fGeoName.Contains("SHISH")){
436 printf(" fIPDistance %6.3f cm \n", fIPDistance);
437 if(fSteelFrontThick>0.)
438 printf(" fSteelFrontThick %6.3f cm \n", fSteelFrontThick);
439 printf(" fNPhi %i | fNZ %i \n", fNPhi, fNZ);
440 printf(" fNCellsInModule %i : fNCellsInSupMod %i : fNCells %i\n",fNCellsInModule, fNCellsInSupMod, fNCells);
441 if(fGeoName.Contains("MAY05")){
442 printf(" fFrontSteelStrip %6.4f cm (thickness of front steel strip)\n",
444 printf(" fLateralSteelStrip %6.4f cm (thickness of lateral steel strip)\n",
446 printf(" fPassiveScintThick %6.4f cm (thickness of front passive Sc tile)\n",
449 printf(" X:Y module size %6.3f , %6.3f cm \n", fPhiModuleSize, fEtaModuleSize);
450 printf(" X:Y tile size %6.3f , %6.3f cm \n", fPhiTileSize, fEtaTileSize);
451 printf(" #of sampling layers %i(fNECLayers) \n", fNECLayers);
452 printf(" fLongModuleSize %6.3f cm \n", fLongModuleSize);
453 printf(" #supermodule in phi direction %i \n", fNPhiSuperModule );
455 printf(" fILOSS %i : fIHADR %i \n", fILOSS, fIHADR);
456 if(fGeoName.Contains("TRD")) {
457 printf(" fTrd1Angle %7.4f\n", fTrd1Angle);
458 printf(" f2Trd1Dx2 %7.4f\n", f2Trd1Dx2);
459 if(fGeoName.Contains("TRD2")) {
460 printf(" fTrd2AngleY %7.4f\n", fTrd2AngleY);
461 printf(" f2Trd2Dy2 %7.4f\n", f2Trd2Dy2);
462 printf(" fTubsR %7.2f cm\n", fTubsR);
463 printf(" fTubsTurnAngle %7.4f\n", fTubsTurnAngle);
464 printf(" fEmptySpace %7.4f cm\n", fEmptySpace);
465 } else if(fGeoName.Contains("TRD1")){
466 printf("SM dimensions(TRD1) : dx %7.2f dy %7.2f dz %7.2f (SMOD, BOX)\n",
467 fParSM[0],fParSM[1],fParSM[2]);
468 printf(" fPhiGapForSM %7.4f cm (%7.4f <- phi size in degree)\n",
469 fPhiGapForSM, TMath::ATan2(fPhiGapForSM,fIPDistance)*TMath::RadToDeg());
470 if(GetKey110DEG()) printf(" Last two modules have size 10 degree in phi (180<phi<190)\n");
471 printf(" phi SM boundaries \n");
472 for(int i=0; i<fPhiBoundariesOfSM.GetSize()/2.; i++) {
473 printf(" %i : %7.5f(%7.2f) -> %7.5f(%7.2f) : center %7.5f(%7.2f) \n", i,
474 fPhiBoundariesOfSM[2*i], fPhiBoundariesOfSM[2*i]*TMath::RadToDeg(),
475 fPhiBoundariesOfSM[2*i+1], fPhiBoundariesOfSM[2*i+1]*TMath::RadToDeg(),
476 fPhiCentersOfSM[i], fPhiCentersOfSM[i]*TMath::RadToDeg());
478 printf(" fShishKebabTrd1Modules has %i modules : max eta %5.4f \n",
479 fShishKebabTrd1Modules->GetSize(),fEtaMaxOfTRD1);
481 printf("\n Cells grid in eta directions : size %i\n", fCentersOfCellsEtaDir.GetSize());
482 for(Int_t i=0; i<fCentersOfCellsEtaDir.GetSize(); i++) {
483 printf(" ind %2.2i : z %8.3f : x %8.3f \n", i,
484 fCentersOfCellsEtaDir.At(i),fCentersOfCellsXDir.At(i));
485 int ind=0; // Nov 21,2006
486 for(Int_t iphi=0; iphi<fCentersOfCellsPhiDir.GetSize(); iphi++) {
487 ind = iphi*fCentersOfCellsEtaDir.GetSize() + i;
488 printf("%6.4f ", fEtaCentersOfCells[ind]);
489 if((iphi+1)%12 == 0) printf("\n");
495 printf("\n Cells grid in phi directions : size %i\n", fCentersOfCellsPhiDir.GetSize());
496 for(Int_t i=0; i<fCentersOfCellsPhiDir.GetSize(); i++) {
497 double phi=fPhiCentersOfCells.At(i);
498 printf(" ind %2.2i : y %8.3f : phi %7.5f(%6.2f) \n", i, fCentersOfCellsPhiDir.At(i),
499 phi, phi*TMath::RadToDeg());
506 void AliEMCALGeometry::PrintCellIndexes(Int_t absId, int pri, char *tit)
509 Int_t nSupMod, nModule, nIphi, nIeta;
513 GetCellIndex(absId, nSupMod, nModule, nIphi, nIeta);
514 printf(" %s | absId : %i -> nSupMod %i nModule %i nIphi %i nIeta %i \n", tit, absId, nSupMod, nModule, nIphi, nIeta);
516 GetCellPhiEtaIndexInSModule(nSupMod,nModule,nIphi,nIeta, iphi,ieta);
517 printf(" local SM index : iphi %i : ieta %i \n", iphi,ieta);
518 GetGlobal(absId, vg);
519 printf(" vglob : mag %7.2f : perp %7.2f : z %7.2f : eta %6.4f : phi %6.4f(%6.2f) \n",
520 vg.Mag(), vg.Perp(), vg.Z(), vg.Eta(), vg.Phi(), vg.Phi()*TMath::RadToDeg());
524 //______________________________________________________________________
525 void AliEMCALGeometry::CheckAdditionalOptions()
528 // Additional options that
529 // can be used to select
530 // the specific geometry of
533 // adeed allILOSS= and allIHADR= for MIP investigation
534 fArrayOpts = new TObjArray;
535 Int_t nopt = AliEMCALHistoUtilities::ParseString(fGeoName, *fArrayOpts);
536 if(nopt==1) { // no aditional option(s)
537 fArrayOpts->Delete();
542 for(Int_t i=1; i<nopt; i++){
543 TObjString *o = (TObjString*)fArrayOpts->At(i);
545 TString addOpt = o->String();
547 for(Int_t j=0; j<fNAdditionalOpts; j++) {
548 TString opt = fAdditionalOpts[j];
549 if(addOpt.Contains(opt,TString::kIgnoreCase)) {
555 AliDebug(2,Form("<E> option |%s| unavailable : ** look to the file AliEMCALGeometry.h **\n",
559 AliDebug(2,Form("<I> option |%s| is valid : number %i : |%s|\n",
560 addOpt.Data(), indj, fAdditionalOpts[indj]));
561 if (addOpt.Contains("NL=",TString::kIgnoreCase)) {// number of sampling layers
562 sscanf(addOpt.Data(),"NL=%i", &fNECLayers);
563 AliDebug(2,Form(" fNECLayers %i (new) \n", fNECLayers));
564 } else if(addOpt.Contains("PBTH=",TString::kIgnoreCase)) {//Thickness of the Pb(fECPbRadThicknes)
565 sscanf(addOpt.Data(),"PBTH=%f", &fECPbRadThickness);
566 } else if(addOpt.Contains("SCTH=",TString::kIgnoreCase)) {//Thickness of the Sc(fECScintThick)
567 sscanf(addOpt.Data(),"SCTH=%f", &fECScintThick);
568 } else if(addOpt.Contains("LATSS=",TString::kIgnoreCase)) {// Thickness of lateral steel strip (fLateralSteelStrip)
569 sscanf(addOpt.Data(),"LATSS=%f", &fLateralSteelStrip);
570 AliDebug(2,Form(" fLateralSteelStrip %f (new) \n", fLateralSteelStrip));
571 } else if(addOpt.Contains("ILOSS=",TString::kIgnoreCase)) {// As in Geant
572 sscanf(addOpt.Data(),"ALLILOSS=%i", &fILOSS);
573 AliDebug(2,Form(" fILOSS %i \n", fILOSS));
574 } else if(addOpt.Contains("IHADR=",TString::kIgnoreCase)) {// As in Geant
575 sscanf(addOpt.Data(),"ALLIHADR=%i", &fIHADR);
576 AliDebug(2,Form(" fIHADR %i \n", fIHADR));
582 void AliEMCALGeometry::DefineSamplingFraction()
585 // Look http://rhic.physics.wayne.edu/~pavlinov/ALICE/SHISHKEBAB/RES/linearityAndResolutionForTRD1.html
586 // Keep for compatibilty
588 if(fNECLayers == 69) { // 10% layer reduction
590 } else if(fNECLayers == 61) { // 20% layer reduction
592 } else if(fNECLayers == 77) {
593 if (fECScintThick>0.175 && fECScintThick<0.177) { // 10% Pb thicknes reduction
594 fSampling = 10.5; // fECScintThick = 0.176, fECPbRadThickness=0.144;
595 } else if(fECScintThick>0.191 && fECScintThick<0.193) { // 20% Pb thicknes reduction
596 fSampling = 8.93; // fECScintThick = 0.192, fECPbRadThickness=0.128;
601 //______________________________________________________________________
602 void AliEMCALGeometry::GetCellPhiEtaIndexInSModuleFromTRUIndex(const Int_t itru, const Int_t iphitru, const Int_t ietatru, Int_t &iphiSM, Int_t &ietaSM) const
605 // This method transforms the (eta,phi) index of cells in a
606 // TRU matrix into Super Module (eta,phi) index.
608 // Calculate in which row and column where the TRU are
611 Int_t col = itru/ fNTRUPhi ;
612 Int_t row = itru - col*fNTRUPhi ;
614 iphiSM = fNCellsInTRUPhi*row + iphitru ;
615 ietaSM = fNCellsInTRUEta*col + ietatru ;
618 //______________________________________________________________________
619 AliEMCALGeometry * AliEMCALGeometry::GetInstance(){
620 // Returns the pointer of the unique instance
622 AliEMCALGeometry * rv = static_cast<AliEMCALGeometry *>( fgGeom );
626 //______________________________________________________________________
627 AliEMCALGeometry* AliEMCALGeometry::GetInstance(const Text_t* name,
628 const Text_t* title){
629 // Returns the pointer of the unique instance
631 AliEMCALGeometry * rv = 0;
633 if ( strcmp(name,"") == 0 ) { // get default geometry
634 fgGeom = new AliEMCALGeometry(fgDefaultGeometryName, title);
636 fgGeom = new AliEMCALGeometry(name, title);
637 } // end if strcmp(name,"")
638 if ( fgInit ) rv = (AliEMCALGeometry * ) fgGeom;
645 if ( strcmp(fgGeom->GetName(), name) != 0) {
646 printf("\ncurrent geometry is %s : ", fgGeom->GetName());
647 printf(" you cannot call %s ", name);
649 rv = (AliEMCALGeometry *) fgGeom;
655 Bool_t AliEMCALGeometry::IsInEMCAL(Double_t x, Double_t y, Double_t z) const {
656 // Checks whether point is inside the EMCal volume, used in AliEMCALv*.cxx
658 // Code uses cylindrical approximation made of inner radius (for speed)
660 // Points behind EMCAl, i.e. R > outer radius, but eta, phi in acceptance
661 // are considered to inside
663 Double_t r=sqrt(x*x+y*y);
665 if ( r > fEnvelop[0] ) {
667 theta = TMath::ATan2(r,z);
672 eta = -TMath::Log(TMath::Tan(theta/2.));
673 if (eta < fArm1EtaMin || eta > fArm1EtaMax)
676 Double_t phi = TMath::ATan2(y,x) * 180./TMath::Pi();
677 if (phi < 0) phi += 360; // phi should go from 0 to 360 in this case
678 if (phi > fArm1PhiMin && phi < fArm1PhiMax)
686 // == Shish-kebab cases ==
688 Int_t AliEMCALGeometry::GetAbsCellId(Int_t nSupMod, Int_t nModule, Int_t nIphi, Int_t nIeta) const
692 // 13-oct-05; 110 degree case
693 // May 31, 2006; ALICE numbering scheme:
694 // 0 <= nSupMod < fNumberOfSuperModules
695 // 0 <= nModule < fNPHI * fNZ ( fNPHI * fNZ/2 for fKey110DEG=1)
696 // 0 <= nIphi < fNPHIdiv
697 // 0 <= nIeta < fNETAdiv
698 // 0 <= absid < fNCells
699 static Int_t id=0; // have to change from 0 to fNCells-1
700 if(fKey110DEG == 1 && nSupMod >= 10) { // 110 degree case; last two supermodules
701 id = fNCellsInSupMod*10 + (fNCellsInSupMod/2)*(nSupMod-10);
703 id = fNCellsInSupMod*nSupMod;
705 id += fNCellsInModule *nModule;
706 id += fNPHIdiv *nIphi;
708 if(id<0 || id >= fNCells) {
709 // printf(" wrong numerations !!\n");
710 // printf(" id %6i(will be force to -1)\n", id);
711 // printf(" fNCells %6i\n", fNCells);
712 // printf(" nSupMod %6i\n", nSupMod);
713 // printf(" nModule %6i\n", nModule);
714 // printf(" nIphi %6i\n", nIphi);
715 // printf(" nIeta %6i\n", nIeta);
716 id = -TMath::Abs(id); // if negative something wrong
721 Bool_t AliEMCALGeometry::CheckAbsCellId(Int_t absId) const
723 // May 31, 2006; only trd1 now
724 if(absId<0 || absId >= fNCells) return kFALSE;
728 Bool_t AliEMCALGeometry::GetCellIndex(Int_t absId,Int_t &nSupMod,Int_t &nModule,Int_t &nIphi,Int_t &nIeta) const
730 // 21-sep-04; 19-oct-05;
731 // May 31, 2006; ALICE numbering scheme:
734 // absId - cell is as in Geant, 0<= absId < fNCells;
736 // nSupMod - super module(SM) number, 0<= nSupMod < fNumberOfSuperModules;
737 // nModule - module number in SM, 0<= nModule < fNCellsInSupMod/fNCellsInSupMod or(/2) for tow last SM (10th and 11th);
738 // nIphi - cell number in phi driection inside module; 0<= nIphi < fNPHIdiv;
739 // nIeta - cell number in eta driection inside module; 0<= nIeta < fNETAdiv;
741 static Int_t tmp=0, sm10=0;
742 if(!CheckAbsCellId(absId)) return kFALSE;
744 sm10 = fNCellsInSupMod*10;
745 if(fKey110DEG == 1 && absId >= sm10) { // 110 degree case; last two supermodules
746 nSupMod = (absId-sm10) / (fNCellsInSupMod/2) + 10;
747 tmp = (absId-sm10) % (fNCellsInSupMod/2);
749 nSupMod = absId / fNCellsInSupMod;
750 tmp = absId % fNCellsInSupMod;
753 nModule = tmp / fNCellsInModule;
754 tmp = tmp % fNCellsInModule;
755 nIphi = tmp / fNPHIdiv;
756 nIeta = tmp % fNPHIdiv;
761 void AliEMCALGeometry::GetModulePhiEtaIndexInSModule(Int_t nSupMod, Int_t nModule, int &iphim, int &ietam) const
763 // added nSupMod; - 19-oct-05 !
764 // Alice numbering scheme - Jun 01,2006
765 // ietam, iphi - indexes of module in two dimensional grid of SM
766 // ietam - have to change from 0 to fNZ-1
767 // iphim - have to change from 0 to nphi-1 (fNPhi-1 or fNPhi/2-1)
770 if(fKey110DEG == 1 && nSupMod>=10) nphi = fNPhi/2;
773 ietam = nModule/nphi;
774 iphim = nModule%nphi;
777 void AliEMCALGeometry::GetCellPhiEtaIndexInSModule(Int_t nSupMod, Int_t nModule, Int_t nIphi, Int_t nIeta,
778 int &iphi, int &ieta) const
781 // Added nSupMod; Nov 25, 05
782 // Alice numbering scheme - Jun 01,2006
784 // nSupMod - super module(SM) number, 0<= nSupMod < fNumberOfSuperModules;
785 // nModule - module number in SM, 0<= nModule < fNCellsInSupMod/fNCellsInSupMod or(/2) for tow last SM (10th and 11th);
786 // nIphi - cell number in phi driection inside module; 0<= nIphi < fNPHIdiv;
787 // nIeta - cell number in eta driection inside module; 0<= nIeta < fNETAdiv;
790 // ieta, iphi - indexes of cell(tower) in two dimensional grid of SM
791 // ieta - have to change from 0 to (fNZ*fNETAdiv-1)
792 // iphi - have to change from 0 to (fNPhi*fNPHIdiv-1 or fNPhi*fNPHIdiv/2-1)
794 static Int_t iphim, ietam;
796 GetModulePhiEtaIndexInSModule(nSupMod,nModule, iphim, ietam);
797 // ieta = ietam*fNETAdiv + (1-nIeta); // x(module) = -z(SM)
798 ieta = ietam*fNETAdiv + (fNETAdiv - 1 - nIeta); // x(module) = -z(SM)
799 iphi = iphim*fNPHIdiv + nIphi; // y(module) = y(SM)
802 AliDebug(1,Form(" nSupMod %i nModule %i nIphi %i nIeta %i => ieta %i iphi %i\n",
803 nSupMod, nModule, nIphi, nIeta, ieta, iphi));
806 Int_t AliEMCALGeometry::GetSuperModuleNumber(Int_t absId) const
808 // Return the number of the supermodule given the absolute
809 // ALICE numbering id
811 static Int_t nSupMod, nModule, nIphi, nIeta;
812 GetCellIndex(absId, nSupMod, nModule, nIphi, nIeta);
816 void AliEMCALGeometry::GetModuleIndexesFromCellIndexesInSModule(Int_t nSupMod, Int_t iphi, Int_t ieta,
817 Int_t &iphim, Int_t &ietam, Int_t &nModule) const
819 // Transition from cell indexes (ieta,iphi) to module indexes (ietam,iphim, nModule)
821 nphi = GetNumberOfModuleInPhiDirection(nSupMod);
823 ietam = ieta/fNETAdiv;
824 iphim = iphi/fNPHIdiv;
825 nModule = ietam * nphi + iphim;
828 Int_t AliEMCALGeometry::GetAbsCellIdFromCellIndexes(Int_t nSupMod, Int_t iphi, Int_t ieta) const
830 // Transition from super module number(nSupMod) and cell indexes (ieta,iphi) to absId
831 static Int_t ietam, iphim, nModule;
832 static Int_t nIeta, nIphi; // cell indexes in module
834 GetModuleIndexesFromCellIndexesInSModule(nSupMod, iphi, ieta, ietam, iphim, nModule);
836 nIeta = ieta%fNETAdiv;
837 nIeta = fNETAdiv - 1 - nIeta;
838 nIphi = iphi%fNPHIdiv;
840 return GetAbsCellId(nSupMod, nModule, nIphi, nIeta);
844 // Methods for AliEMCALRecPoint - Feb 19, 2006
845 Bool_t AliEMCALGeometry::RelPosCellInSModule(Int_t absId, Double_t &xr, Double_t &yr, Double_t &zr) const
847 // Look to see what the relative
848 // position inside a given cell is
850 // Alice numbering scheme - Jun 08, 2006
852 // absId - cell is as in Geant, 0<= absId < fNCells;
854 // xr,yr,zr - x,y,z coordinates of cell with absId inside SM
856 // Shift index taking into account the difference between standard SM
857 // and SM of half size in phi direction
858 const Int_t phiIndexShift = fCentersOfCellsPhiDir.GetSize()/4; // Nov 22, 2006; was 6 for cas 2X2
859 static Int_t nSupMod, nModule, nIphi, nIeta, iphi, ieta;
860 if(!CheckAbsCellId(absId)) return kFALSE;
862 GetCellIndex(absId, nSupMod, nModule, nIphi, nIeta);
863 GetCellPhiEtaIndexInSModule(nSupMod,nModule,nIphi,nIeta, iphi, ieta);
865 xr = fCentersOfCellsXDir.At(ieta);
866 zr = fCentersOfCellsEtaDir.At(ieta);
869 yr = fCentersOfCellsPhiDir.At(iphi);
871 yr = fCentersOfCellsPhiDir.At(iphi + phiIndexShift);
873 AliDebug(1,Form("absId %i nSupMod %i iphi %i ieta %i xr %f yr %f zr %f ",absId,nSupMod,iphi,ieta,xr,yr,zr));
878 Bool_t AliEMCALGeometry::RelPosCellInSModule(Int_t absId, Double_t loc[3]) const
880 // Alice numbering scheme - Jun 03, 2006
881 loc[0] = loc[1] = loc[2]=0.0;
882 if(RelPosCellInSModule(absId, loc[0],loc[1],loc[2])) {
888 Bool_t AliEMCALGeometry::RelPosCellInSModule(Int_t absId, TVector3 &vloc) const
890 static Double_t loc[3];
891 if(RelPosCellInSModule(absId,loc)) {
892 vloc.SetXYZ(loc[0], loc[1], loc[2]);
898 // Alice numbering scheme - Jun 03, 2006
901 Bool_t AliEMCALGeometry::RelPosCellInSModule(Int_t absId, Double_t distEff, Double_t &xr, Double_t &yr, Double_t &zr) const
903 // Jul 30, 2007 - taking into account position of shower max
904 // Look to see what the relative
905 // position inside a given cell is
908 // absId - cell is as in Geant, 0<= absId < fNCells;
909 // e - cluster energy
911 // xr,yr,zr - x,y,z coordinates of cell with absId inside SM
913 // Shift index taking into account the difference between standard SM
914 // and SM of half size in phi direction
915 const Int_t phiIndexShift = fCentersOfCellsPhiDir.GetSize()/4; // Nov 22, 2006; was 6 for cas 2X2
916 static Int_t nSupMod, nModule, nIphi, nIeta, iphi, ieta;
917 static Int_t iphim, ietam;
918 static AliEMCALShishKebabTrd1Module *mod = 0;
920 if(!CheckAbsCellId(absId)) return kFALSE;
922 GetCellIndex(absId, nSupMod, nModule, nIphi, nIeta);
923 GetModulePhiEtaIndexInSModule(nSupMod, nModule, iphim, ietam);
924 GetCellPhiEtaIndexInSModule(nSupMod,nModule,nIphi,nIeta, iphi, ieta);
926 mod = GetShishKebabModule(ietam);
927 mod->GetPositionAtCenterCellLine(nIeta, distEff, v);
928 xr = v.Y() - fParSM[0];
929 zr = v.X() - fParSM[2];
932 yr = fCentersOfCellsPhiDir.At(iphi);
934 yr = fCentersOfCellsPhiDir.At(iphi + phiIndexShift);
936 AliDebug(1,Form("absId %i nSupMod %i iphi %i ieta %i xr %f yr %f zr %f ",absId,nSupMod,iphi,ieta,xr,yr,zr));
941 Bool_t AliEMCALGeometry::RelPosCellInSModule(Int_t absId, Int_t maxAbsId, Double_t distEff, Double_t &xr, Double_t &yr, Double_t &zr) const
943 // Jul 31, 2007 - taking into account position of shower max and apply coor2.
944 // Look to see what the relative
945 // position inside a given cell is
948 // absId - cell is as in Geant, 0<= absId < fNCells;
949 // maxAbsId - abs id of cell with highest energy
950 // e - cluster energy
952 // xr,yr,zr - x,y,z coordinates of cell with absId inside SM
954 // Shift index taking into account the difference between standard SM
955 // and SM of half size in phi direction
956 const Int_t phiIndexShift = fCentersOfCellsPhiDir.GetSize()/4; // Nov 22, 2006; was 6 for cas 2X2
957 static Int_t nSupMod, nModule, nIphi, nIeta, iphi, ieta;
958 static Int_t iphim, ietam;
959 static AliEMCALShishKebabTrd1Module *mod = 0;
962 static Int_t nSupModM, nModuleM, nIphiM, nIetaM, iphiM, ietaM;
963 static Int_t iphimM, ietamM, maxAbsIdCopy=-1;
964 static AliEMCALShishKebabTrd1Module *modM = 0;
965 static Double_t distCorr;
967 if(!CheckAbsCellId(absId)) return kFALSE;
969 GetCellIndex(absId, nSupMod, nModule, nIphi, nIeta);
970 GetModulePhiEtaIndexInSModule(nSupMod, nModule, iphim, ietam);
971 GetCellPhiEtaIndexInSModule(nSupMod,nModule,nIphi,nIeta, iphi, ieta);
972 mod = GetShishKebabModule(ietam);
974 if(absId != maxAbsId) {
976 if(maxAbsIdCopy != maxAbsId) {
977 GetCellIndex(maxAbsId, nSupModM, nModuleM, nIphiM, nIetaM);
978 GetModulePhiEtaIndexInSModule(nSupModM, nModuleM, iphimM, ietamM);
979 GetCellPhiEtaIndexInSModule(nSupModM,nModuleM,nIphiM,nIetaM, iphiM, ietaM);
980 modM = GetShishKebabModule(ietamM); // do I need this ?
981 maxAbsIdCopy = maxAbsId;
984 distCorr = GetEtaModuleSize()*(ietam-ietamM)/TMath::Tan(modM->GetTheta()); // Stay here
985 //printf(" distCorr %f | dist %f | ietam %i -> etamM %i\n", distCorr, dist, ietam, ietamM);
987 // distEff += distCorr;
989 // Bad resolution in this case, strong bias vs phi
991 mod->GetPositionAtCenterCellLine(nIeta, distEff, v); // Stay here
992 xr = v.Y() - fParSM[0];
993 zr = v.X() - fParSM[2];
996 yr = fCentersOfCellsPhiDir.At(iphi);
998 yr = fCentersOfCellsPhiDir.At(iphi + phiIndexShift);
1000 AliDebug(1,Form("absId %i nSupMod %i iphi %i ieta %i xr %f yr %f zr %f ",absId,nSupMod,iphi,ieta,xr,yr,zr));
1005 void AliEMCALGeometry::CreateListOfTrd1Modules()
1007 // Generate the list of Trd1 modules
1008 // which will make up the EMCAL
1011 AliDebug(2,Form(" AliEMCALGeometry::CreateListOfTrd1Modules() started "));
1013 AliEMCALShishKebabTrd1Module *mod=0, *mTmp=0; // current module
1014 if(fShishKebabTrd1Modules == 0) {
1015 fShishKebabTrd1Modules = new TList;
1016 fShishKebabTrd1Modules->SetName("ListOfTRD1");
1017 for(int iz=0; iz< GetNZ(); iz++) {
1019 mod = new AliEMCALShishKebabTrd1Module(TMath::Pi()/2.,this);
1021 mTmp = new AliEMCALShishKebabTrd1Module(*mod);
1024 fShishKebabTrd1Modules->Add(mod);
1027 AliDebug(2,Form(" Already exits : "));
1029 mod = (AliEMCALShishKebabTrd1Module*)fShishKebabTrd1Modules->At(fShishKebabTrd1Modules->GetSize()-1);
1030 fEtaMaxOfTRD1 = mod->GetMaxEtaOfModule(0);
1032 AliDebug(2,Form(" fShishKebabTrd1Modules has %i modules : max eta %5.4f \n",
1033 fShishKebabTrd1Modules->GetSize(),fEtaMaxOfTRD1));
1035 // Jun 01, 2006 - ALICE numbering scheme
1036 // define grid for cells in eta(z) and x directions in local coordinates system of SM
1037 // Works just for 2x2 case only -- ?? start here
1040 // Define grid for cells in phi(y) direction in local coordinates system of SM
1041 // as for 2X2 as for 3X3 - Nov 8,2006
1043 AliDebug(2,Form(" Cells grid in phi directions : size %i\n", fCentersOfCellsPhiDir.GetSize()));
1044 Int_t ind=0; // this is phi index
1045 Int_t ieta=0, nModule=0, iphiTemp;
1046 Double_t xr, zr, theta, phi, eta, r, x,y;
1048 Double_t ytCenterModule=0.0, ytCenterCell=0.0;
1050 fCentersOfCellsPhiDir.Set(fNPhi*fNPHIdiv);
1051 fPhiCentersOfCells.Set(fNPhi*fNPHIdiv);
1053 Double_t R0 = GetIPDistance() + GetLongModuleSize()/2.;
1054 for(Int_t it=0; it<fNPhi; it++) { // cycle on modules
1055 ytCenterModule = -fParSM[1] + fPhiModuleSize*(2*it+1)/2; // center of module
1056 for(Int_t ic=0; ic<fNPHIdiv; ic++) { // cycle on cells in module
1058 ytCenterCell = ytCenterModule + fPhiTileSize *(2*ic-1)/2.;
1059 } else if(fNPHIdiv==3){
1060 ytCenterCell = ytCenterModule + fPhiTileSize *(ic-1);
1061 } else if(fNPHIdiv==1){
1062 ytCenterCell = ytCenterModule;
1064 fCentersOfCellsPhiDir.AddAt(ytCenterCell,ind);
1065 // Define grid on phi direction
1066 // Grid is not the same for different eta bin;
1067 // Effect is small but is still here
1068 phi = TMath::ATan2(ytCenterCell, R0);
1069 fPhiCentersOfCells.AddAt(phi, ind);
1071 AliDebug(2,Form(" ind %2.2i : y %8.3f ", ind, fCentersOfCellsPhiDir.At(ind)));
1076 fCentersOfCellsEtaDir.Set(fNZ *fNETAdiv);
1077 fCentersOfCellsXDir.Set(fNZ *fNETAdiv);
1078 fEtaCentersOfCells.Set(fNZ *fNETAdiv * fNPhi*fNPHIdiv);
1079 AliDebug(2,Form(" Cells grid in eta directions : size %i\n", fCentersOfCellsEtaDir.GetSize()));
1080 for(Int_t it=0; it<fNZ; it++) {
1081 AliEMCALShishKebabTrd1Module *trd1 = GetShishKebabModule(it);
1083 for(Int_t ic=0; ic<fNETAdiv; ic++) {
1085 trd1->GetCenterOfCellInLocalCoordinateofSM(ic, xr, zr); // case of 2X2
1086 GetCellPhiEtaIndexInSModule(0, nModule, 0, ic, iphiTemp, ieta);
1088 trd1->GetCenterOfCellInLocalCoordinateofSM_3X3(ic, xr, zr); // case of 3X3
1089 GetCellPhiEtaIndexInSModule(0, nModule, 0, ic, iphiTemp, ieta);
1091 trd1->GetCenterOfCellInLocalCoordinateofSM_1X1(xr, zr); // case of 1X1
1092 GetCellPhiEtaIndexInSModule(0, nModule, 0, ic, iphiTemp, ieta);
1094 fCentersOfCellsXDir.AddAt(float(xr) - fParSM[0],ieta);
1095 fCentersOfCellsEtaDir.AddAt(float(zr) - fParSM[2],ieta);
1096 // Define grid on eta direction for each bin in phi
1097 for(int iphi=0; iphi<fCentersOfCellsPhiDir.GetSize(); iphi++) {
1098 x = xr + trd1->GetRadius();
1099 y = fCentersOfCellsPhiDir[iphi];
1100 r = TMath::Sqrt(x*x + y*y + zr*zr);
1101 theta = TMath::ACos(zr/r);
1102 eta = AliEMCALShishKebabTrd1Module::ThetaToEta(theta);
1103 // ind = ieta*fCentersOfCellsPhiDir.GetSize() + iphi;
1104 ind = iphi*fCentersOfCellsEtaDir.GetSize() + ieta;
1105 fEtaCentersOfCells.AddAt(eta, ind);
1107 //printf(" ieta %i : xr + trd1->GetRadius() %f : zr %f : eta %f \n", ieta, xr + trd1->GetRadius(), zr, eta);
1110 for(Int_t i=0; i<fCentersOfCellsEtaDir.GetSize(); i++) {
1111 AliDebug(2,Form(" ind %2.2i : z %8.3f : x %8.3f", i+1,
1112 fCentersOfCellsEtaDir.At(i),fCentersOfCellsXDir.At(i)));
1117 void AliEMCALGeometry::GetGlobal(const Double_t *loc, Double_t *glob, int ind) const
1119 // Figure out the global numbering
1120 // of a given supermodule from the
1121 // local numbering and the transformation
1122 // matrix stored by the geometry manager (allows for misaligned
1125 if(ind>=0 && ind < GetNumberOfSuperModules()) {
1126 TString volpath = "ALIC_1/XEN1_1/SMOD_";
1129 if(GetKey110DEG() && ind>=10) {
1130 volpath = "ALIC_1/XEN1_1/SM10_";
1131 volpath += (ind-10+1);
1134 if(!gGeoManager->cd(volpath.Data()))
1135 AliFatal(Form("GeoManager cannot find path %s!",volpath.Data()));
1137 TGeoHMatrix* m = gGeoManager->GetCurrentMatrix();
1139 m->LocalToMaster(loc, glob);
1141 AliFatal("Geo matrixes are not loaded \n") ;
1146 void AliEMCALGeometry::GetGlobal(const TVector3 &vloc, TVector3 &vglob, int ind) const
1148 //Figure out the global numbering
1149 //of a given supermodule from the
1150 //local numbering given a 3-vector location
1152 static Double_t tglob[3], tloc[3];
1154 GetGlobal(tloc, tglob, ind);
1155 vglob.SetXYZ(tglob[0], tglob[1], tglob[2]);
1158 void AliEMCALGeometry::GetGlobal(Int_t absId , double glob[3]) const
1160 // Alice numbering scheme - Jun 03, 2006
1161 static Int_t nSupMod, nModule, nIphi, nIeta;
1162 static double loc[3];
1164 glob[0]=glob[1]=glob[2]=0.0; // bad case
1165 if(RelPosCellInSModule(absId, loc)) {
1166 GetCellIndex(absId, nSupMod, nModule, nIphi, nIeta);
1168 TString volpath = "ALIC_1/XEN1_1/SMOD_";
1169 volpath += (nSupMod+1);
1171 if(GetKey110DEG() && nSupMod>=10) {
1172 volpath = "ALIC_1/XEN1_1/SM10_";
1173 volpath += (nSupMod-10+1);
1175 if(!gGeoManager->cd(volpath.Data()))
1176 AliFatal(Form("GeoManager cannot find path %s!",volpath.Data()));
1178 TGeoHMatrix* m = gGeoManager->GetCurrentMatrix();
1180 m->LocalToMaster(loc, glob);
1182 AliFatal("Geo matrixes are not loaded \n") ;
1187 void AliEMCALGeometry::GetGlobal(Int_t absId , TVector3 &vglob) const
1189 // Alice numbering scheme - Jun 03, 2006
1190 static Double_t glob[3];
1192 GetGlobal(absId, glob);
1193 vglob.SetXYZ(glob[0], glob[1], glob[2]);
1197 void AliEMCALGeometry::GetGlobal(const AliRecPoint *rp, TVector3 &vglob) const
1199 // Figure out the global numbering
1200 // of a given supermodule from the
1201 // local numbering for RecPoints
1203 static TVector3 vloc;
1204 static Int_t nSupMod, nModule, nIphi, nIeta;
1206 AliRecPoint *rpTmp = (AliRecPoint*)rp; // const_cast ??
1208 AliEMCALRecPoint *rpEmc = (AliEMCALRecPoint*)rpTmp;
1210 GetCellIndex(rpEmc->GetAbsId(0), nSupMod, nModule, nIphi, nIeta);
1211 rpTmp->GetLocalPosition(vloc);
1212 GetGlobal(vloc, vglob, nSupMod);
1215 void AliEMCALGeometry::EtaPhiFromIndex(Int_t absId,Double_t &eta,Double_t &phi) const
1217 // Nov 16, 2006- float to double
1218 // version for TRD1 only
1219 static TVector3 vglob;
1220 GetGlobal(absId, vglob);
1225 void AliEMCALGeometry::EtaPhiFromIndex(Int_t absId,Float_t &eta,Float_t &phi) const
1227 // Nov 16,2006 - should be discard in future
1228 static TVector3 vglob;
1229 GetGlobal(absId, vglob);
1230 eta = float(vglob.Eta());
1231 phi = float(vglob.Phi());
1234 Bool_t AliEMCALGeometry::GetPhiBoundariesOfSM(Int_t nSupMod, Double_t &phiMin, Double_t &phiMax) const
1236 // 0<= nSupMod <=11; phi in rad
1238 if(nSupMod<0 || nSupMod >11) return kFALSE;
1240 phiMin = fPhiBoundariesOfSM[2*i];
1241 phiMax = fPhiBoundariesOfSM[2*i+1];
1245 Bool_t AliEMCALGeometry::GetPhiBoundariesOfSMGap(Int_t nPhiSec, Double_t &phiMin, Double_t &phiMax) const
1247 // 0<= nPhiSec <=4; phi in rad
1248 // 0; gap boundaries between 0th&2th | 1th&3th SM
1249 // 1; gap boundaries between 2th&4th | 3th&5th SM
1250 // 2; gap boundaries between 4th&6th | 5th&7th SM
1251 // 3; gap boundaries between 6th&8th | 7th&9th SM
1252 // 4; gap boundaries between 8th&10th | 9th&11th SM
1253 if(nPhiSec<0 || nPhiSec >4) return kFALSE;
1254 phiMin = fPhiBoundariesOfSM[2*nPhiSec+1];
1255 phiMax = fPhiBoundariesOfSM[2*nPhiSec+2];
1259 Bool_t AliEMCALGeometry::SuperModuleNumberFromEtaPhi(Double_t eta, Double_t phi, Int_t &nSupMod) const
1261 // Return false if phi belongs a phi cracks between SM
1265 if(TMath::Abs(eta) > fEtaMaxOfTRD1) return kFALSE;
1267 phi = TVector2::Phi_0_2pi(phi); // move phi to (0,2pi) boundaries
1268 for(i=0; i<6; i++) {
1269 if(phi>=fPhiBoundariesOfSM[2*i] && phi<=fPhiBoundariesOfSM[2*i+1]) {
1271 if(eta < 0.0) nSupMod++;
1272 AliDebug(1,Form("eta %f phi %f(%5.2f) : nSupMod %i : #bound %i", eta,phi,phi*TMath::RadToDeg(), nSupMod,i));
1279 Bool_t AliEMCALGeometry::GetAbsCellIdFromEtaPhi(Double_t eta, Double_t phi, Int_t &absId) const
1282 // stay here - phi problem as usual
1283 static Int_t nSupMod, i, ieta, iphi, etaShift, nphi;
1284 static Double_t absEta=0.0, d=0.0, dmin=0.0, phiLoc;
1285 absId = nSupMod = - 1;
1286 if(SuperModuleNumberFromEtaPhi(eta, phi, nSupMod)) {
1288 phi = TVector2::Phi_0_2pi(phi);
1289 phiLoc = phi - fPhiCentersOfSM[nSupMod/2];
1290 nphi = fPhiCentersOfCells.GetSize();
1292 phiLoc = phi - 190.*TMath::DegToRad();
1296 dmin = TMath::Abs(fPhiCentersOfCells[0]-phiLoc);
1298 for(i=1; i<nphi; i++) {
1299 d = TMath::Abs(fPhiCentersOfCells[i] - phiLoc);
1304 // printf(" i %i : d %f : dmin %f : fPhiCentersOfCells[i] %f \n", i, d, dmin, fPhiCentersOfCells[i]);
1306 // odd SM are turned with respect of even SM - reverse indexes
1307 AliDebug(2,Form(" iphi %i : dmin %f (phi %f, phiLoc %f ) ", iphi, dmin, phi, phiLoc));
1309 absEta = TMath::Abs(eta);
1310 etaShift = iphi*fCentersOfCellsEtaDir.GetSize();
1311 dmin = TMath::Abs(fEtaCentersOfCells[etaShift]-absEta);
1313 for(i=1; i<fCentersOfCellsEtaDir.GetSize(); i++) {
1314 d = TMath::Abs(fEtaCentersOfCells[i+etaShift] - absEta);
1320 AliDebug(2,Form(" ieta %i : dmin %f (eta=%f) : nSupMod %i ", ieta, dmin, eta, nSupMod));
1322 if(eta<0) iphi = (nphi-1) - iphi;
1323 absId = GetAbsCellIdFromCellIndexes(nSupMod, iphi, ieta);
1330 AliEMCALShishKebabTrd1Module* AliEMCALGeometry::GetShishKebabModule(Int_t neta) const
1332 //This method was too long to be
1333 //included in the header file - the
1334 //rule checker complained about it's
1335 //length, so we move it here. It returns the
1336 //shishkebabmodule at a given eta index point.
1338 static AliEMCALShishKebabTrd1Module* trd1=0;
1339 if(fShishKebabTrd1Modules && neta>=0 && neta<fShishKebabTrd1Modules->GetSize()) {
1340 trd1 = (AliEMCALShishKebabTrd1Module*)fShishKebabTrd1Modules->At(neta);
1345 void AliEMCALGeometry::Browse(TBrowser* b)
1347 if(fShishKebabTrd1Modules) b->Add(fShishKebabTrd1Modules);
1350 Bool_t AliEMCALGeometry::IsFolder() const
1352 if(fShishKebabTrd1Modules) return kTRUE;