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 // --- Root 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 scTh=0.176 pbTh=0.144";
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();
83 // TGeoManager::Import("geometry.root");
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
311 fNPHIdiv = fNETAdiv = 2; // 13-oct-04 - division again
312 if(fGeoName.Contains("3X3")) { // 23-nov-04
313 fNPHIdiv = fNETAdiv = 3;
314 } else if(fGeoName.Contains("4X4")) {
315 fNPHIdiv = fNETAdiv = 4;
316 } else if(fGeoName.Contains("1X1")) {
317 fNPHIdiv = fNETAdiv = 1;
320 if(fGeoName.Contains("25")){
322 fECScintThick = fECPbRadThickness = 0.5;
324 if(fGeoName.Contains("WSUC")){ // 18-may-05 - about common structure
325 fShellThickness = 30.; // should be change
329 CheckAdditionalOptions();
330 DefineSamplingFraction();
332 fPhiTileSize = fPhiModuleSize/double(fNPHIdiv) - fLateralSteelStrip; // 13-may-05
333 fEtaTileSize = fEtaModuleSize/double(fNETAdiv) - fLateralSteelStrip; // 13-may-05
335 // constant for transition absid <--> indexes
336 fNCellsInModule = fNPHIdiv*fNETAdiv;
337 fNCellsInSupMod = fNCellsInModule*fNPhi*fNZ;
338 fNCells = fNCellsInSupMod*fNumberOfSuperModules;
339 if(GetKey110DEG()) fNCells -= fNCellsInSupMod;
341 fLongModuleSize = fNECLayers*(fECScintThick + fECPbRadThickness);
342 if(fGeoName.Contains("MAY05")) fLongModuleSize += (fFrontSteelStrip + fPassiveScintThick);
345 if(fGeoName.Contains("TRD")) {
346 f2Trd1Dx2 = fEtaModuleSize + 2.*fLongModuleSize*TMath::Tan(fTrd1Angle*TMath::DegToRad()/2.);
348 } else Fatal("Init", "%s is an undefined geometry!", fGeoName.Data()) ;
350 fNPhiSuperModule = fNumberOfSuperModules/2;
351 if(fNPhiSuperModule<1) fNPhiSuperModule = 1;
353 fShellThickness = fAlFrontThick + fGap2Active + fNECLayers*GetECScintThick()+(fNECLayers-1)*GetECPbRadThick();
354 if(fGeoName.Contains("SHISH")) {
355 fShellThickness = fSteelFrontThick + fLongModuleSize;
356 if(fGeoName.Contains("TWIST")) { // 13-sep-04
357 fShellThickness = TMath::Sqrt(fLongModuleSize*fLongModuleSize + fPhiModuleSize*fEtaModuleSize);
358 fShellThickness += fSteelFrontThick;
359 } else if(fGeoName.Contains("TRD")) { // 1-oct-04
360 fShellThickness = TMath::Sqrt(fLongModuleSize*fLongModuleSize + f2Trd1Dx2*f2Trd1Dx2);
361 fShellThickness += fSteelFrontThick;
363 fParSM[0] = GetShellThickness()/2.;
364 fParSM[1] = GetPhiModuleSize() * GetNPhi()/2.;
369 fZLength = 2.*ZFromEtaR(fIPDistance+fShellThickness,fArm1EtaMax); // Z coverage
370 fEnvelop[0] = fIPDistance; // mother volume inner radius
371 fEnvelop[1] = fIPDistance + fShellThickness; // mother volume outer r.
372 fEnvelop[2] = 1.00001*fZLength; // add some padding for mother volume.
374 fNumberOfSuperModules = 12;
376 // SM phi boundaries - (0,1),(2,3) .. (10,11) - has the same boundaries; Nov 7, 2006
377 fPhiBoundariesOfSM.Set(fNumberOfSuperModules);
378 fPhiCentersOfSM.Set(fNumberOfSuperModules/2);
379 fPhiBoundariesOfSM[0] = TMath::PiOver2() - TMath::ATan2(fParSM[1] , fIPDistance); // 1th and 2th modules)
380 fPhiBoundariesOfSM[1] = TMath::PiOver2() + TMath::ATan2(fParSM[1] , fIPDistance);
381 fPhiCentersOfSM[0] = TMath::PiOver2();
382 for(int i=1; i<=4; i++) { // from 2th ro 9th
383 fPhiBoundariesOfSM[2*i] = fPhiBoundariesOfSM[0] + 20.*TMath::DegToRad()*i;
384 fPhiBoundariesOfSM[2*i+1] = fPhiBoundariesOfSM[1] + 20.*TMath::DegToRad()*i;
385 fPhiCentersOfSM[i] = fPhiCentersOfSM[0] + 20.*TMath::DegToRad()*i;
387 fPhiBoundariesOfSM[11] = 190.*TMath::DegToRad();
388 fPhiBoundariesOfSM[10] = fPhiBoundariesOfSM[11] - TMath::ATan2((fParSM[1]) , fIPDistance);
389 fPhiCentersOfSM[5] = (fPhiBoundariesOfSM[10]+fPhiBoundariesOfSM[11])/2.;
391 //TRU parameters. These parameters values are not the final ones.
394 fNCellsInTRUEta = 16 ;
395 fNCellsInTRUPhi = 24 ;
397 if(fGeoName.Contains("WSUC")) fNumberOfSuperModules = 1; // Jul 12, 2007
402 void AliEMCALGeometry::PrintGeometry()
404 // Separate routine is callable from broswer; Nov 7,2006
405 printf("\nInit: geometry of EMCAL named %s :\n", fGeoName.Data());
407 for(Int_t i=0; i<fArrayOpts->GetEntries(); i++){
408 TObjString *o = (TObjString*)fArrayOpts->At(i);
409 printf(" %i : %s \n", i, o->String().Data());
412 printf("Granularity: %d in eta and %d in phi\n", GetNZ(), GetNPhi()) ;
413 printf("Layout: phi = (%7.1f, %7.1f), eta = (%5.2f, %5.2f), IP = %7.2f -> for EMCAL envelope only\n",
414 GetArm1PhiMin(), GetArm1PhiMax(),GetArm1EtaMin(), GetArm1EtaMax(), GetIPDistance() );
416 printf( " ECAL : %d x (%f cm Pb, %f cm Sc) \n",
417 GetNECLayers(), GetECPbRadThick(), GetECScintThick() ) ;
418 printf(" fSampling %5.2f \n", fSampling );
419 if(fGeoName.Contains("SHISH")){
420 printf(" fIPDistance %6.3f cm \n", fIPDistance);
421 if(fSteelFrontThick>0.)
422 printf(" fSteelFrontThick %6.3f cm \n", fSteelFrontThick);
423 printf(" fNPhi %i | fNZ %i \n", fNPhi, fNZ);
424 printf(" fNCellsInModule %i : fNCellsInSupMod %i : fNCells %i\n",fNCellsInModule, fNCellsInSupMod, fNCells);
425 if(fGeoName.Contains("MAY05")){
426 printf(" fFrontSteelStrip %6.4f cm (thickness of front steel strip)\n",
428 printf(" fLateralSteelStrip %6.4f cm (thickness of lateral steel strip)\n",
430 printf(" fPassiveScintThick %6.4f cm (thickness of front passive Sc tile)\n",
433 printf(" X:Y module size %6.3f , %6.3f cm \n", fPhiModuleSize, fEtaModuleSize);
434 printf(" X:Y tile size %6.3f , %6.3f cm \n", fPhiTileSize, fEtaTileSize);
435 printf(" #of sampling layers %i(fNECLayers) \n", fNECLayers);
436 printf(" fLongModuleSize %6.3f cm \n", fLongModuleSize);
437 printf(" #supermodule in phi direction %i \n", fNPhiSuperModule );
439 printf(" fILOSS %i : fIHADR %i \n", fILOSS, fIHADR);
440 if(fGeoName.Contains("TRD")) {
441 printf(" fTrd1Angle %7.4f\n", fTrd1Angle);
442 printf(" f2Trd1Dx2 %7.4f\n", f2Trd1Dx2);
443 if(fGeoName.Contains("TRD1")){
444 printf("SM dimensions(TRD1) : dx %7.2f dy %7.2f dz %7.2f (SMOD, BOX)\n",
445 fParSM[0],fParSM[1],fParSM[2]);
446 printf(" fPhiGapForSM %7.4f cm (%7.4f <- phi size in degree)\n",
447 fPhiGapForSM, TMath::ATan2(fPhiGapForSM,fIPDistance)*TMath::RadToDeg());
448 if(GetKey110DEG()) printf(" Last two modules have size 10 degree in phi (180<phi<190)\n");
449 printf(" phi SM boundaries \n");
450 for(int i=0; i<fPhiBoundariesOfSM.GetSize()/2.; i++) {
451 printf(" %i : %7.5f(%7.2f) -> %7.5f(%7.2f) : center %7.5f(%7.2f) \n", i,
452 fPhiBoundariesOfSM[2*i], fPhiBoundariesOfSM[2*i]*TMath::RadToDeg(),
453 fPhiBoundariesOfSM[2*i+1], fPhiBoundariesOfSM[2*i+1]*TMath::RadToDeg(),
454 fPhiCentersOfSM[i], fPhiCentersOfSM[i]*TMath::RadToDeg());
456 printf(" fShishKebabTrd1Modules has %i modules : max eta %5.4f \n",
457 fShishKebabTrd1Modules->GetSize(),fEtaMaxOfTRD1);
459 printf("\n Cells grid in eta directions : size %i\n", fCentersOfCellsEtaDir.GetSize());
460 for(Int_t i=0; i<fCentersOfCellsEtaDir.GetSize(); i++) {
461 printf(" ind %2.2i : z %8.3f : x %8.3f \n", i,
462 fCentersOfCellsEtaDir.At(i),fCentersOfCellsXDir.At(i));
463 int ind=0; // Nov 21,2006
464 for(Int_t iphi=0; iphi<fCentersOfCellsPhiDir.GetSize(); iphi++) {
465 ind = iphi*fCentersOfCellsEtaDir.GetSize() + i;
466 printf("%6.4f ", fEtaCentersOfCells[ind]);
467 if((iphi+1)%12 == 0) printf("\n");
473 printf("\n Cells grid in phi directions : size %i\n", fCentersOfCellsPhiDir.GetSize());
474 for(Int_t i=0; i<fCentersOfCellsPhiDir.GetSize(); i++) {
475 double phi=fPhiCentersOfCells.At(i);
476 printf(" ind %2.2i : y %8.3f : phi %7.5f(%6.2f) \n", i, fCentersOfCellsPhiDir.At(i),
477 phi, phi*TMath::RadToDeg());
483 void AliEMCALGeometry::PrintCellIndexes(Int_t absId, int pri, char *tit)
486 Int_t nSupMod, nModule, nIphi, nIeta;
490 GetCellIndex(absId, nSupMod, nModule, nIphi, nIeta);
491 printf(" %s | absId : %i -> nSupMod %i nModule %i nIphi %i nIeta %i \n", tit, absId, nSupMod, nModule, nIphi, nIeta);
493 GetCellPhiEtaIndexInSModule(nSupMod,nModule,nIphi,nIeta, iphi,ieta);
494 printf(" local SM index : iphi %i : ieta %i \n", iphi,ieta);
495 GetGlobal(absId, vg);
496 printf(" vglob : mag %7.2f : perp %7.2f : z %7.2f : eta %6.4f : phi %6.4f(%6.2f) \n",
497 vg.Mag(), vg.Perp(), vg.Z(), vg.Eta(), vg.Phi(), vg.Phi()*TMath::RadToDeg());
501 //______________________________________________________________________
502 void AliEMCALGeometry::CheckAdditionalOptions()
505 // Additional options that
506 // can be used to select
507 // the specific geometry of
510 // adeed allILOSS= and allIHADR= for MIP investigation
511 fArrayOpts = new TObjArray;
512 Int_t nopt = AliEMCALHistoUtilities::ParseString(fGeoName, *fArrayOpts);
513 if(nopt==1) { // no aditional option(s)
514 fArrayOpts->Delete();
519 for(Int_t i=1; i<nopt; i++){
520 TObjString *o = (TObjString*)fArrayOpts->At(i);
522 TString addOpt = o->String();
524 for(Int_t j=0; j<fNAdditionalOpts; j++) {
525 TString opt = fAdditionalOpts[j];
526 if(addOpt.Contains(opt,TString::kIgnoreCase)) {
532 AliDebug(2,Form("<E> option |%s| unavailable : ** look to the file AliEMCALGeometry.h **\n",
536 AliDebug(2,Form("<I> option |%s| is valid : number %i : |%s|\n",
537 addOpt.Data(), indj, fAdditionalOpts[indj]));
538 if (addOpt.Contains("NL=",TString::kIgnoreCase)) {// number of sampling layers
539 sscanf(addOpt.Data(),"NL=%i", &fNECLayers);
540 AliDebug(2,Form(" fNECLayers %i (new) \n", fNECLayers));
541 } else if(addOpt.Contains("PBTH=",TString::kIgnoreCase)) {//Thickness of the Pb(fECPbRadThicknes)
542 sscanf(addOpt.Data(),"PBTH=%f", &fECPbRadThickness);
543 } else if(addOpt.Contains("SCTH=",TString::kIgnoreCase)) {//Thickness of the Sc(fECScintThick)
544 sscanf(addOpt.Data(),"SCTH=%f", &fECScintThick);
545 } else if(addOpt.Contains("LATSS=",TString::kIgnoreCase)) {// Thickness of lateral steel strip (fLateralSteelStrip)
546 sscanf(addOpt.Data(),"LATSS=%f", &fLateralSteelStrip);
547 AliDebug(2,Form(" fLateralSteelStrip %f (new) \n", fLateralSteelStrip));
548 } else if(addOpt.Contains("ILOSS=",TString::kIgnoreCase)) {// As in Geant
549 sscanf(addOpt.Data(),"ALLILOSS=%i", &fILOSS);
550 AliDebug(2,Form(" fILOSS %i \n", fILOSS));
551 } else if(addOpt.Contains("IHADR=",TString::kIgnoreCase)) {// As in Geant
552 sscanf(addOpt.Data(),"ALLIHADR=%i", &fIHADR);
553 AliDebug(2,Form(" fIHADR %i \n", fIHADR));
559 void AliEMCALGeometry::DefineSamplingFraction()
562 // Look http://rhic.physics.wayne.edu/~pavlinov/ALICE/SHISHKEBAB/RES/linearityAndResolutionForTRD1.html
563 // Keep for compatibilty
565 if(fNECLayers == 69) { // 10% layer reduction
567 } else if(fNECLayers == 61) { // 20% layer reduction
569 } else if(fNECLayers == 77) {
570 if (fECScintThick>0.175 && fECScintThick<0.177) { // 10% Pb thicknes reduction
571 fSampling = 10.5; // fECScintThick = 0.176, fECPbRadThickness=0.144;
572 } else if(fECScintThick>0.191 && fECScintThick<0.193) { // 20% Pb thicknes reduction
573 fSampling = 8.93; // fECScintThick = 0.192, fECPbRadThickness=0.128;
578 //______________________________________________________________________
579 void AliEMCALGeometry::GetCellPhiEtaIndexInSModuleFromTRUIndex(const Int_t itru, const Int_t iphitru, const Int_t ietatru, Int_t &iphiSM, Int_t &ietaSM) const
582 // This method transforms the (eta,phi) index of cells in a
583 // TRU matrix into Super Module (eta,phi) index.
585 // Calculate in which row and column where the TRU are
588 Int_t col = itru/ fNTRUPhi ;
589 Int_t row = itru - col*fNTRUPhi ;
591 iphiSM = fNCellsInTRUPhi*row + iphitru ;
592 ietaSM = fNCellsInTRUEta*col + ietatru ;
595 //______________________________________________________________________
596 AliEMCALGeometry * AliEMCALGeometry::GetInstance(){
597 // Returns the pointer of the unique instance
599 AliEMCALGeometry * rv = static_cast<AliEMCALGeometry *>( fgGeom );
603 //______________________________________________________________________
604 AliEMCALGeometry* AliEMCALGeometry::GetInstance(const Text_t* name,
605 const Text_t* title){
606 // Returns the pointer of the unique instance
608 AliEMCALGeometry * rv = 0;
610 if ( strcmp(name,"") == 0 ) { // get default geometry
611 fgGeom = new AliEMCALGeometry(fgDefaultGeometryName, title);
613 fgGeom = new AliEMCALGeometry(name, title);
614 } // end if strcmp(name,"")
615 if ( fgInit ) rv = (AliEMCALGeometry * ) fgGeom;
622 if ( strcmp(fgGeom->GetName(), name) != 0) {
623 printf("\ncurrent geometry is %s : ", fgGeom->GetName());
624 printf(" you cannot call %s ",name);
626 rv = (AliEMCALGeometry *) fgGeom;
632 Bool_t AliEMCALGeometry::IsInEMCAL(Double_t x, Double_t y, Double_t z) const {
633 // Checks whether point is inside the EMCal volume, used in AliEMCALv*.cxx
635 // Code uses cylindrical approximation made of inner radius (for speed)
637 // Points behind EMCAl, i.e. R > outer radius, but eta, phi in acceptance
638 // are considered to inside
640 Double_t r=sqrt(x*x+y*y);
642 if ( r > fEnvelop[0] ) {
644 theta = TMath::ATan2(r,z);
649 eta = -TMath::Log(TMath::Tan(theta/2.));
650 if (eta < fArm1EtaMin || eta > fArm1EtaMax)
653 Double_t phi = TMath::ATan2(y,x) * 180./TMath::Pi();
654 if (phi < 0) phi += 360; // phi should go from 0 to 360 in this case
655 if (phi > fArm1PhiMin && phi < fArm1PhiMax)
663 // == Shish-kebab cases ==
665 Int_t AliEMCALGeometry::GetAbsCellId(Int_t nSupMod, Int_t nModule, Int_t nIphi, Int_t nIeta) const
669 // 13-oct-05; 110 degree case
670 // May 31, 2006; ALICE numbering scheme:
671 // 0 <= nSupMod < fNumberOfSuperModules
672 // 0 <= nModule < fNPHI * fNZ ( fNPHI * fNZ/2 for fKey110DEG=1)
673 // 0 <= nIphi < fNPHIdiv
674 // 0 <= nIeta < fNETAdiv
675 // 0 <= absid < fNCells
676 static Int_t id=0; // have to change from 0 to fNCells-1
677 if(fKey110DEG == 1 && nSupMod >= 10) { // 110 degree case; last two supermodules
678 id = fNCellsInSupMod*10 + (fNCellsInSupMod/2)*(nSupMod-10);
680 id = fNCellsInSupMod*nSupMod;
682 id += fNCellsInModule *nModule;
683 id += fNPHIdiv *nIphi;
685 if(id<0 || id >= fNCells) {
686 // printf(" wrong numerations !!\n");
687 // printf(" id %6i(will be force to -1)\n", id);
688 // printf(" fNCells %6i\n", fNCells);
689 // printf(" nSupMod %6i\n", nSupMod);
690 // printf(" nModule %6i\n", nModule);
691 // printf(" nIphi %6i\n", nIphi);
692 // printf(" nIeta %6i\n", nIeta);
693 id = -TMath::Abs(id); // if negative something wrong
698 Bool_t AliEMCALGeometry::CheckAbsCellId(Int_t absId) const
700 // May 31, 2006; only trd1 now
701 if(absId<0 || absId >= fNCells) return kFALSE;
705 Bool_t AliEMCALGeometry::GetCellIndex(Int_t absId,Int_t &nSupMod,Int_t &nModule,Int_t &nIphi,Int_t &nIeta) const
707 // 21-sep-04; 19-oct-05;
708 // May 31, 2006; ALICE numbering scheme:
711 // absId - cell is as in Geant, 0<= absId < fNCells;
713 // nSupMod - super module(SM) number, 0<= nSupMod < fNumberOfSuperModules;
714 // nModule - module number in SM, 0<= nModule < fNCellsInSupMod/fNCellsInSupMod or(/2) for tow last SM (10th and 11th);
715 // nIphi - cell number in phi driection inside module; 0<= nIphi < fNPHIdiv;
716 // nIeta - cell number in eta driection inside module; 0<= nIeta < fNETAdiv;
718 static Int_t tmp=0, sm10=0;
719 if(!CheckAbsCellId(absId)) return kFALSE;
721 sm10 = fNCellsInSupMod*10;
722 if(fKey110DEG == 1 && absId >= sm10) { // 110 degree case; last two supermodules
723 nSupMod = (absId-sm10) / (fNCellsInSupMod/2) + 10;
724 tmp = (absId-sm10) % (fNCellsInSupMod/2);
726 nSupMod = absId / fNCellsInSupMod;
727 tmp = absId % fNCellsInSupMod;
730 nModule = tmp / fNCellsInModule;
731 tmp = tmp % fNCellsInModule;
732 nIphi = tmp / fNPHIdiv;
733 nIeta = tmp % fNPHIdiv;
738 void AliEMCALGeometry::GetModulePhiEtaIndexInSModule(Int_t nSupMod, Int_t nModule, int &iphim, int &ietam) const
740 // added nSupMod; - 19-oct-05 !
741 // Alice numbering scheme - Jun 01,2006
742 // ietam, iphi - indexes of module in two dimensional grid of SM
743 // ietam - have to change from 0 to fNZ-1
744 // iphim - have to change from 0 to nphi-1 (fNPhi-1 or fNPhi/2-1)
747 if(fKey110DEG == 1 && nSupMod>=10) nphi = fNPhi/2;
750 ietam = nModule/nphi;
751 iphim = nModule%nphi;
754 void AliEMCALGeometry::GetCellPhiEtaIndexInSModule(Int_t nSupMod, Int_t nModule, Int_t nIphi, Int_t nIeta,
755 int &iphi, int &ieta) const
758 // Added nSupMod; Nov 25, 05
759 // Alice numbering scheme - Jun 01,2006
761 // nSupMod - super module(SM) number, 0<= nSupMod < fNumberOfSuperModules;
762 // nModule - module number in SM, 0<= nModule < fNCellsInSupMod/fNCellsInSupMod or(/2) for tow last SM (10th and 11th);
763 // nIphi - cell number in phi driection inside module; 0<= nIphi < fNPHIdiv;
764 // nIeta - cell number in eta driection inside module; 0<= nIeta < fNETAdiv;
767 // ieta, iphi - indexes of cell(tower) in two dimensional grid of SM
768 // ieta - have to change from 0 to (fNZ*fNETAdiv-1)
769 // iphi - have to change from 0 to (fNPhi*fNPHIdiv-1 or fNPhi*fNPHIdiv/2-1)
771 static Int_t iphim, ietam;
773 GetModulePhiEtaIndexInSModule(nSupMod,nModule, iphim, ietam);
774 // ieta = ietam*fNETAdiv + (1-nIeta); // x(module) = -z(SM)
775 ieta = ietam*fNETAdiv + (fNETAdiv - 1 - nIeta); // x(module) = -z(SM)
776 iphi = iphim*fNPHIdiv + nIphi; // y(module) = y(SM)
779 AliDebug(1,Form(" nSupMod %i nModule %i nIphi %i nIeta %i => ieta %i iphi %i\n",
780 nSupMod, nModule, nIphi, nIeta, ieta, iphi));
783 Int_t AliEMCALGeometry::GetSuperModuleNumber(Int_t absId) const
785 // Return the number of the supermodule given the absolute
786 // ALICE numbering id
788 static Int_t nSupMod, nModule, nIphi, nIeta;
789 GetCellIndex(absId, nSupMod, nModule, nIphi, nIeta);
793 void AliEMCALGeometry::GetModuleIndexesFromCellIndexesInSModule(Int_t nSupMod, Int_t iphi, Int_t ieta,
794 Int_t &iphim, Int_t &ietam, Int_t &nModule) const
796 // Transition from cell indexes (ieta,iphi) to module indexes (ietam,iphim, nModule)
798 nphi = GetNumberOfModuleInPhiDirection(nSupMod);
800 ietam = ieta/fNETAdiv;
801 iphim = iphi/fNPHIdiv;
802 nModule = ietam * nphi + iphim;
805 Int_t AliEMCALGeometry::GetAbsCellIdFromCellIndexes(Int_t nSupMod, Int_t iphi, Int_t ieta) const
807 // Transition from super module number(nSupMod) and cell indexes (ieta,iphi) to absId
808 static Int_t ietam, iphim, nModule;
809 static Int_t nIeta, nIphi; // cell indexes in module
811 GetModuleIndexesFromCellIndexesInSModule(nSupMod, iphi, ieta, ietam, iphim, nModule);
813 nIeta = ieta%fNETAdiv;
814 nIeta = fNETAdiv - 1 - nIeta;
815 nIphi = iphi%fNPHIdiv;
817 return GetAbsCellId(nSupMod, nModule, nIphi, nIeta);
821 // Methods for AliEMCALRecPoint - Feb 19, 2006
822 Bool_t AliEMCALGeometry::RelPosCellInSModule(Int_t absId, Double_t &xr, Double_t &yr, Double_t &zr) const
824 // Look to see what the relative
825 // position inside a given cell is
827 // Alice numbering scheme - Jun 08, 2006
829 // absId - cell is as in Geant, 0<= absId < fNCells;
831 // xr,yr,zr - x,y,z coordinates of cell with absId inside SM
833 // Shift index taking into account the difference between standard SM
834 // and SM of half size in phi direction
835 const Int_t kphiIndexShift = fCentersOfCellsPhiDir.GetSize()/4; // Nov 22, 2006; was 6 for cas 2X2
836 static Int_t nSupMod, nModule, nIphi, nIeta, iphi, ieta;
837 if(!CheckAbsCellId(absId)) return kFALSE;
839 GetCellIndex(absId, nSupMod, nModule, nIphi, nIeta);
840 GetCellPhiEtaIndexInSModule(nSupMod,nModule,nIphi,nIeta, iphi, ieta);
842 xr = fCentersOfCellsXDir.At(ieta);
843 zr = fCentersOfCellsEtaDir.At(ieta);
846 yr = fCentersOfCellsPhiDir.At(iphi);
848 yr = fCentersOfCellsPhiDir.At(iphi + kphiIndexShift);
850 AliDebug(1,Form("absId %i nSupMod %i iphi %i ieta %i xr %f yr %f zr %f ",absId,nSupMod,iphi,ieta,xr,yr,zr));
855 Bool_t AliEMCALGeometry::RelPosCellInSModule(Int_t absId, Double_t loc[3]) const
857 // Alice numbering scheme - Jun 03, 2006
858 loc[0] = loc[1] = loc[2]=0.0;
859 if(RelPosCellInSModule(absId, loc[0],loc[1],loc[2])) {
865 Bool_t AliEMCALGeometry::RelPosCellInSModule(Int_t absId, TVector3 &vloc) const
867 static Double_t loc[3];
868 if(RelPosCellInSModule(absId,loc)) {
869 vloc.SetXYZ(loc[0], loc[1], loc[2]);
875 // Alice numbering scheme - Jun 03, 2006
878 Bool_t AliEMCALGeometry::RelPosCellInSModule(Int_t absId, Double_t distEff, Double_t &xr, Double_t &yr, Double_t &zr) const
880 // Jul 30, 2007 - taking into account position of shower max
881 // Look to see what the relative
882 // position inside a given cell is
885 // absId - cell is as in Geant, 0<= absId < fNCells;
886 // e - cluster energy
888 // xr,yr,zr - x,y,z coordinates of cell with absId inside SM
890 // Shift index taking into account the difference between standard SM
891 // and SM of half size in phi direction
892 const Int_t kphiIndexShift = fCentersOfCellsPhiDir.GetSize()/4; // Nov 22, 2006; was 6 for cas 2X2
893 static Int_t nSupMod, nModule, nIphi, nIeta, iphi, ieta;
894 static Int_t iphim, ietam;
895 static AliEMCALShishKebabTrd1Module *mod = 0;
897 if(!CheckAbsCellId(absId)) return kFALSE;
899 GetCellIndex(absId, nSupMod, nModule, nIphi, nIeta);
900 GetModulePhiEtaIndexInSModule(nSupMod, nModule, iphim, ietam);
901 GetCellPhiEtaIndexInSModule(nSupMod,nModule,nIphi,nIeta, iphi, ieta);
903 mod = GetShishKebabModule(ietam);
904 mod->GetPositionAtCenterCellLine(nIeta, distEff, v);
905 xr = v.Y() - fParSM[0];
906 zr = v.X() - fParSM[2];
909 yr = fCentersOfCellsPhiDir.At(iphi);
911 yr = fCentersOfCellsPhiDir.At(iphi + kphiIndexShift);
913 AliDebug(1,Form("absId %i nSupMod %i iphi %i ieta %i xr %f yr %f zr %f ",absId,nSupMod,iphi,ieta,xr,yr,zr));
918 Bool_t AliEMCALGeometry::RelPosCellInSModule(Int_t absId, Int_t maxAbsId, Double_t distEff, Double_t &xr, Double_t &yr, Double_t &zr) const
920 // Jul 31, 2007 - taking into account position of shower max and apply coor2.
921 // Look to see what the relative
922 // position inside a given cell is
925 // absId - cell is as in Geant, 0<= absId < fNCells;
926 // maxAbsId - abs id of cell with highest energy
927 // e - cluster energy
929 // xr,yr,zr - x,y,z coordinates of cell with absId inside SM
931 // Shift index taking into account the difference between standard SM
932 // and SM of half size in phi direction
933 const Int_t kphiIndexShift = fCentersOfCellsPhiDir.GetSize()/4; // Nov 22, 2006; was 6 for cas 2X2
934 static Int_t nSupMod, nModule, nIphi, nIeta, iphi, ieta;
935 static Int_t iphim, ietam;
936 static AliEMCALShishKebabTrd1Module *mod = 0;
939 static Int_t nSupModM, nModuleM, nIphiM, nIetaM, iphiM, ietaM;
940 static Int_t iphimM, ietamM, maxAbsIdCopy=-1;
941 static AliEMCALShishKebabTrd1Module *modM = 0;
942 static Double_t distCorr;
944 if(!CheckAbsCellId(absId)) return kFALSE;
946 GetCellIndex(absId, nSupMod, nModule, nIphi, nIeta);
947 GetModulePhiEtaIndexInSModule(nSupMod, nModule, iphim, ietam);
948 GetCellPhiEtaIndexInSModule(nSupMod,nModule,nIphi,nIeta, iphi, ieta);
949 mod = GetShishKebabModule(ietam);
951 if(absId != maxAbsId) {
953 if(maxAbsIdCopy != maxAbsId) {
954 GetCellIndex(maxAbsId, nSupModM, nModuleM, nIphiM, nIetaM);
955 GetModulePhiEtaIndexInSModule(nSupModM, nModuleM, iphimM, ietamM);
956 GetCellPhiEtaIndexInSModule(nSupModM,nModuleM,nIphiM,nIetaM, iphiM, ietaM);
957 modM = GetShishKebabModule(ietamM); // do I need this ?
958 maxAbsIdCopy = maxAbsId;
961 distCorr = GetEtaModuleSize()*(ietam-ietamM)/TMath::Tan(modM->GetTheta()); // Stay here
962 //printf(" distCorr %f | dist %f | ietam %i -> etamM %i\n", distCorr, dist, ietam, ietamM);
964 // distEff += distCorr;
966 // Bad resolution in this case, strong bias vs phi
968 mod->GetPositionAtCenterCellLine(nIeta, distEff, v); // Stay here
969 xr = v.Y() - fParSM[0];
970 zr = v.X() - fParSM[2];
973 yr = fCentersOfCellsPhiDir.At(iphi);
975 yr = fCentersOfCellsPhiDir.At(iphi + kphiIndexShift);
977 AliDebug(1,Form("absId %i nSupMod %i iphi %i ieta %i xr %f yr %f zr %f ",absId,nSupMod,iphi,ieta,xr,yr,zr));
982 void AliEMCALGeometry::CreateListOfTrd1Modules()
984 // Generate the list of Trd1 modules
985 // which will make up the EMCAL
988 AliDebug(2,Form(" AliEMCALGeometry::CreateListOfTrd1Modules() started "));
990 AliEMCALShishKebabTrd1Module *mod=0, *mTmp=0; // current module
991 if(fShishKebabTrd1Modules == 0) {
992 fShishKebabTrd1Modules = new TList;
993 fShishKebabTrd1Modules->SetName("ListOfTRD1");
994 for(int iz=0; iz< GetNZ(); iz++) {
996 mod = new AliEMCALShishKebabTrd1Module(TMath::Pi()/2.,this);
998 mTmp = new AliEMCALShishKebabTrd1Module(*mod);
1001 fShishKebabTrd1Modules->Add(mod);
1004 AliDebug(2,Form(" Already exits : "));
1006 mod = (AliEMCALShishKebabTrd1Module*)fShishKebabTrd1Modules->At(fShishKebabTrd1Modules->GetSize()-1);
1007 fEtaMaxOfTRD1 = mod->GetMaxEtaOfModule(0);
1009 AliDebug(2,Form(" fShishKebabTrd1Modules has %i modules : max eta %5.4f \n",
1010 fShishKebabTrd1Modules->GetSize(),fEtaMaxOfTRD1));
1012 // Jun 01, 2006 - ALICE numbering scheme
1013 // define grid for cells in eta(z) and x directions in local coordinates system of SM
1014 // Works just for 2x2 case only -- ?? start here
1017 // Define grid for cells in phi(y) direction in local coordinates system of SM
1018 // as for 2X2 as for 3X3 - Nov 8,2006
1020 AliDebug(2,Form(" Cells grid in phi directions : size %i\n", fCentersOfCellsPhiDir.GetSize()));
1021 Int_t ind=0; // this is phi index
1022 Int_t ieta=0, nModule=0, iphiTemp;
1023 Double_t xr, zr, theta, phi, eta, r, x,y;
1025 Double_t ytCenterModule=0.0, ytCenterCell=0.0;
1027 fCentersOfCellsPhiDir.Set(fNPhi*fNPHIdiv);
1028 fPhiCentersOfCells.Set(fNPhi*fNPHIdiv);
1030 Double_t r0 = GetIPDistance() + GetLongModuleSize()/2.;
1031 for(Int_t it=0; it<fNPhi; it++) { // cycle on modules
1032 ytCenterModule = -fParSM[1] + fPhiModuleSize*(2*it+1)/2; // center of module
1033 for(Int_t ic=0; ic<fNPHIdiv; ic++) { // cycle on cells in module
1035 ytCenterCell = ytCenterModule + fPhiTileSize *(2*ic-1)/2.;
1036 } else if(fNPHIdiv==3){
1037 ytCenterCell = ytCenterModule + fPhiTileSize *(ic-1);
1038 } else if(fNPHIdiv==1){
1039 ytCenterCell = ytCenterModule;
1041 fCentersOfCellsPhiDir.AddAt(ytCenterCell,ind);
1042 // Define grid on phi direction
1043 // Grid is not the same for different eta bin;
1044 // Effect is small but is still here
1045 phi = TMath::ATan2(ytCenterCell, r0);
1046 fPhiCentersOfCells.AddAt(phi, ind);
1048 AliDebug(2,Form(" ind %2.2i : y %8.3f ", ind, fCentersOfCellsPhiDir.At(ind)));
1053 fCentersOfCellsEtaDir.Set(fNZ *fNETAdiv);
1054 fCentersOfCellsXDir.Set(fNZ *fNETAdiv);
1055 fEtaCentersOfCells.Set(fNZ *fNETAdiv * fNPhi*fNPHIdiv);
1056 AliDebug(2,Form(" Cells grid in eta directions : size %i\n", fCentersOfCellsEtaDir.GetSize()));
1057 for(Int_t it=0; it<fNZ; it++) {
1058 AliEMCALShishKebabTrd1Module *trd1 = GetShishKebabModule(it);
1060 for(Int_t ic=0; ic<fNETAdiv; ic++) {
1062 trd1->GetCenterOfCellInLocalCoordinateofSM(ic, xr, zr); // case of 2X2
1063 GetCellPhiEtaIndexInSModule(0, nModule, 0, ic, iphiTemp, ieta);
1065 trd1->GetCenterOfCellInLocalCoordinateofSM_3X3(ic, xr, zr); // case of 3X3
1066 GetCellPhiEtaIndexInSModule(0, nModule, 0, ic, iphiTemp, ieta);
1068 trd1->GetCenterOfCellInLocalCoordinateofSM_1X1(xr, zr); // case of 1X1
1069 GetCellPhiEtaIndexInSModule(0, nModule, 0, ic, iphiTemp, ieta);
1071 fCentersOfCellsXDir.AddAt(float(xr) - fParSM[0],ieta);
1072 fCentersOfCellsEtaDir.AddAt(float(zr) - fParSM[2],ieta);
1073 // Define grid on eta direction for each bin in phi
1074 for(int iphi=0; iphi<fCentersOfCellsPhiDir.GetSize(); iphi++) {
1075 x = xr + trd1->GetRadius();
1076 y = fCentersOfCellsPhiDir[iphi];
1077 r = TMath::Sqrt(x*x + y*y + zr*zr);
1078 theta = TMath::ACos(zr/r);
1079 eta = AliEMCALShishKebabTrd1Module::ThetaToEta(theta);
1080 // ind = ieta*fCentersOfCellsPhiDir.GetSize() + iphi;
1081 ind = iphi*fCentersOfCellsEtaDir.GetSize() + ieta;
1082 fEtaCentersOfCells.AddAt(eta, ind);
1084 //printf(" ieta %i : xr + trd1->GetRadius() %f : zr %f : eta %f \n", ieta, xr + trd1->GetRadius(), zr, eta);
1087 for(Int_t i=0; i<fCentersOfCellsEtaDir.GetSize(); i++) {
1088 AliDebug(2,Form(" ind %2.2i : z %8.3f : x %8.3f", i+1,
1089 fCentersOfCellsEtaDir.At(i),fCentersOfCellsXDir.At(i)));
1094 void AliEMCALGeometry::GetGlobal(const Double_t *loc, Double_t *glob, int ind) const
1096 // Figure out the global numbering
1097 // of a given supermodule from the
1098 // local numbering and the transformation
1099 // matrix stored by the geometry manager (allows for misaligned
1102 if(ind>=0 && ind < GetNumberOfSuperModules()) {
1103 TString volpath = "ALIC_1/XEN1_1/SMOD_";
1106 if(GetKey110DEG() && ind>=10) {
1107 volpath = "ALIC_1/XEN1_1/SM10_";
1108 volpath += ind-10+1;
1111 if(!gGeoManager->cd(volpath.Data()))
1112 AliFatal(Form("AliEMCALGeometry::GeoManager cannot find path %s!",volpath.Data()));
1114 TGeoHMatrix* m = gGeoManager->GetCurrentMatrix();
1116 m->LocalToMaster(loc, glob);
1118 AliFatal("Geo matrixes are not loaded \n") ;
1123 void AliEMCALGeometry::GetGlobal(const TVector3 &vloc, TVector3 &vglob, int ind) const
1125 //Figure out the global numbering
1126 //of a given supermodule from the
1127 //local numbering given a 3-vector location
1129 static Double_t tglob[3], tloc[3];
1131 GetGlobal(tloc, tglob, ind);
1132 vglob.SetXYZ(tglob[0], tglob[1], tglob[2]);
1135 void AliEMCALGeometry::GetGlobal(Int_t absId , double glob[3]) const
1137 // Alice numbering scheme - Jun 03, 2006
1138 static Int_t nSupMod, nModule, nIphi, nIeta;
1139 static double loc[3];
1141 if (!gGeoManager || !gGeoManager->IsClosed()) {
1142 AliError("Can't get the global coordinates! gGeoManager doesn't exist or it is still open!");
1146 glob[0]=glob[1]=glob[2]=0.0; // bad case
1147 if(RelPosCellInSModule(absId, loc)) {
1148 GetCellIndex(absId, nSupMod, nModule, nIphi, nIeta);
1150 TString volpath = "ALIC_1/XEN1_1/SMOD_";
1151 volpath += (nSupMod+1);
1153 if(GetKey110DEG() && nSupMod>=10) {
1154 volpath = "ALIC_1/XEN1_1/SM10_";
1155 volpath += (nSupMod-10+1);
1157 if(!gGeoManager->cd(volpath.Data()))
1158 AliFatal(Form("GeoManager cannot find path %s!",volpath.Data()));
1160 TGeoHMatrix* m = gGeoManager->GetCurrentMatrix();
1162 m->LocalToMaster(loc, glob);
1164 AliFatal("Geo matrixes are not loaded \n") ;
1169 //___________________________________________________________________
1170 void AliEMCALGeometry::GetGlobal(Int_t absId , TVector3 &vglob) const
1172 // Alice numbering scheme - Jun 03, 2006
1173 static Double_t glob[3];
1175 GetGlobal(absId, glob);
1176 vglob.SetXYZ(glob[0], glob[1], glob[2]);
1180 //____________________________________________________________________________
1181 void AliEMCALGeometry::GetGlobal(const AliRecPoint* /*rp*/, TVector3& /* vglob */) const
1183 AliFatal(Form("Please use GetGlobalEMCAL(recPoint,gpos) instead of GetGlobal!"));
1186 //_________________________________________________________________________________
1187 void AliEMCALGeometry::GetGlobalEMCAL(const AliEMCALRecPoint *rp, TVector3 &vglob) const
1189 // Figure out the global numbering
1190 // of a given supermodule from the
1191 // local numbering for RecPoints
1193 static TVector3 vloc;
1194 static Int_t nSupMod, nModule, nIphi, nIeta;
1196 const AliEMCALRecPoint *rpTmp = rp;
1197 const AliEMCALRecPoint *rpEmc = rpTmp;
1199 GetCellIndex(rpEmc->GetAbsId(0), nSupMod, nModule, nIphi, nIeta);
1200 rpTmp->GetLocalPosition(vloc);
1201 GetGlobal(vloc, vglob, nSupMod);
1204 void AliEMCALGeometry::EtaPhiFromIndex(Int_t absId,Double_t &eta,Double_t &phi) const
1206 // Nov 16, 2006- float to double
1207 // version for TRD1 only
1208 static TVector3 vglob;
1209 GetGlobal(absId, vglob);
1214 void AliEMCALGeometry::EtaPhiFromIndex(Int_t absId,Float_t &eta,Float_t &phi) const
1216 // Nov 16,2006 - should be discard in future
1217 static TVector3 vglob;
1218 GetGlobal(absId, vglob);
1219 eta = float(vglob.Eta());
1220 phi = float(vglob.Phi());
1223 Bool_t AliEMCALGeometry::GetPhiBoundariesOfSM(Int_t nSupMod, Double_t &phiMin, Double_t &phiMax) const
1225 // 0<= nSupMod <=11; phi in rad
1227 if(nSupMod<0 || nSupMod >11) return kFALSE;
1229 phiMin = fPhiBoundariesOfSM[2*i];
1230 phiMax = fPhiBoundariesOfSM[2*i+1];
1234 Bool_t AliEMCALGeometry::GetPhiBoundariesOfSMGap(Int_t nPhiSec, Double_t &phiMin, Double_t &phiMax) const
1236 // 0<= nPhiSec <=4; phi in rad
1237 // 0; gap boundaries between 0th&2th | 1th&3th SM
1238 // 1; gap boundaries between 2th&4th | 3th&5th SM
1239 // 2; gap boundaries between 4th&6th | 5th&7th SM
1240 // 3; gap boundaries between 6th&8th | 7th&9th SM
1241 // 4; gap boundaries between 8th&10th | 9th&11th SM
1242 if(nPhiSec<0 || nPhiSec >4) return kFALSE;
1243 phiMin = fPhiBoundariesOfSM[2*nPhiSec+1];
1244 phiMax = fPhiBoundariesOfSM[2*nPhiSec+2];
1248 Bool_t AliEMCALGeometry::SuperModuleNumberFromEtaPhi(Double_t eta, Double_t phi, Int_t &nSupMod) const
1250 // Return false if phi belongs a phi cracks between SM
1254 if(TMath::Abs(eta) > fEtaMaxOfTRD1) return kFALSE;
1256 phi = TVector2::Phi_0_2pi(phi); // move phi to (0,2pi) boundaries
1257 for(i=0; i<6; i++) {
1258 if(phi>=fPhiBoundariesOfSM[2*i] && phi<=fPhiBoundariesOfSM[2*i+1]) {
1260 if(eta < 0.0) nSupMod++;
1261 AliDebug(1,Form("eta %f phi %f(%5.2f) : nSupMod %i : #bound %i", eta,phi,phi*TMath::RadToDeg(), nSupMod,i));
1268 Bool_t AliEMCALGeometry::GetAbsCellIdFromEtaPhi(Double_t eta, Double_t phi, Int_t &absId) const
1271 // stay here - phi problem as usual
1272 static Int_t nSupMod, i, ieta, iphi, etaShift, nphi;
1273 static Double_t absEta=0.0, d=0.0, dmin=0.0, phiLoc;
1274 absId = nSupMod = - 1;
1275 if(SuperModuleNumberFromEtaPhi(eta, phi, nSupMod)) {
1277 phi = TVector2::Phi_0_2pi(phi);
1278 phiLoc = phi - fPhiCentersOfSM[nSupMod/2];
1279 nphi = fPhiCentersOfCells.GetSize();
1281 phiLoc = phi - 190.*TMath::DegToRad();
1285 dmin = TMath::Abs(fPhiCentersOfCells[0]-phiLoc);
1287 for(i=1; i<nphi; i++) {
1288 d = TMath::Abs(fPhiCentersOfCells[i] - phiLoc);
1293 // printf(" i %i : d %f : dmin %f : fPhiCentersOfCells[i] %f \n", i, d, dmin, fPhiCentersOfCells[i]);
1295 // odd SM are turned with respect of even SM - reverse indexes
1296 AliDebug(2,Form(" iphi %i : dmin %f (phi %f, phiLoc %f ) ", iphi, dmin, phi, phiLoc));
1298 absEta = TMath::Abs(eta);
1299 etaShift = iphi*fCentersOfCellsEtaDir.GetSize();
1300 dmin = TMath::Abs(fEtaCentersOfCells[etaShift]-absEta);
1302 for(i=1; i<fCentersOfCellsEtaDir.GetSize(); i++) {
1303 d = TMath::Abs(fEtaCentersOfCells[i+etaShift] - absEta);
1309 AliDebug(2,Form(" ieta %i : dmin %f (eta=%f) : nSupMod %i ", ieta, dmin, eta, nSupMod));
1311 if(eta<0) iphi = (nphi-1) - iphi;
1312 absId = GetAbsCellIdFromCellIndexes(nSupMod, iphi, ieta);
1319 AliEMCALShishKebabTrd1Module* AliEMCALGeometry::GetShishKebabModule(Int_t neta) const
1321 //This method was too long to be
1322 //included in the header file - the
1323 //rule checker complained about it's
1324 //length, so we move it here. It returns the
1325 //shishkebabmodule at a given eta index point.
1327 static AliEMCALShishKebabTrd1Module* trd1=0;
1328 if(fShishKebabTrd1Modules && neta>=0 && neta<fShishKebabTrd1Modules->GetSize()) {
1329 trd1 = (AliEMCALShishKebabTrd1Module*)fShishKebabTrd1Modules->At(neta);
1334 void AliEMCALGeometry::Browse(TBrowser* b)
1336 //Browse the modules
1337 if(fShishKebabTrd1Modules) b->Add(fShishKebabTrd1Modules);
1340 Bool_t AliEMCALGeometry::IsFolder() const
1342 //Check if fShishKebabTrd1Modules is in folder
1343 if(fShishKebabTrd1Modules) return kTRUE;
1347 Double_t AliEMCALGeometry::GetPhiCenterOfSM(Int_t nsupmod) const
1349 //returns center of supermodule in phi
1351 return fPhiCentersOfSM[i];