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),fNAdditionalOpts(0),fECPbRadThickness(0.),fECScintThick(0.),
88 fNECLayers(0),fArm1PhiMin(0.),fArm1PhiMax(0.),fArm1EtaMin(0.),fArm1EtaMax(0.),fIPDistance(0.),
89 fShellThickness(0.),fZLength(0.),fNZ(0),fNPhi(0),fSampling(0.),fNumberOfSuperModules(0),
90 fFrontSteelStrip(0.),fLateralSteelStrip(0.),fPassiveScintThick(0.),fPhiModuleSize(0.),
91 fEtaModuleSize(0.),fPhiTileSize(0.),fEtaTileSize(0.),fLongModuleSize(0.),fNPhiSuperModule(0),
92 fNPHIdiv(0),fNETAdiv(0), fNCells(0),fNCellsInSupMod(0),fNCellsInModule(0),fNTRUEta(0),
93 fNTRUPhi(0), fNCellsInTRUEta(0), fNCellsInTRUPhi(0), fTrd1Angle(0.),f2Trd1Dx2(0.),
94 fPhiGapForSM(0.),fKey110DEG(0),fPhiBoundariesOfSM(0), fPhiCentersOfSM(0),fEtaMaxOfTRD1(0),
95 fCentersOfCellsEtaDir(0), fCentersOfCellsXDir(0),fCentersOfCellsPhiDir(0),
96 fEtaCentersOfCells(0),fPhiCentersOfCells(0),fShishKebabTrd1Modules(0),
97 fILOSS(-1), fIHADR(-1),
98 //obsolete member data
99 fAlFrontThick(0.), fGap2Active(0.), fSteelFrontThick(0.), fTrd2AngleY(0.),
100 f2Trd2Dy2(0.), fEmptySpace(0.), fTubsR(0.), fTubsTurnAngle(0.)
102 // default ctor only for internal usage (singleton)
103 // must be kept public for root persistency purposes,
104 // but should never be called by the outside world
106 // CreateListOfTrd1Modules();
107 AliDebug(2, "AliEMCALGeometry : default ctor ");
109 //______________________________________________________________________
110 AliEMCALGeometry::AliEMCALGeometry(const Text_t* name, const Text_t* title)
111 : AliGeometry(name, title),
112 fGeoName(0),fArrayOpts(0),fNAdditionalOpts(0),fECPbRadThickness(0.),fECScintThick(0.),
113 fNECLayers(0),fArm1PhiMin(0.),fArm1PhiMax(0.),fArm1EtaMin(0.),fArm1EtaMax(0.),fIPDistance(0.),
114 fShellThickness(0.),fZLength(0.),fNZ(0),fNPhi(0),fSampling(0.),fNumberOfSuperModules(0),
115 fFrontSteelStrip(0.),fLateralSteelStrip(0.),fPassiveScintThick(0.),fPhiModuleSize(0.),
116 fEtaModuleSize(0.),fPhiTileSize(0.),fEtaTileSize(0.),fLongModuleSize(0.),fNPhiSuperModule(0),
117 fNPHIdiv(0),fNETAdiv(0), fNCells(0),fNCellsInSupMod(0),fNCellsInModule(0),fNTRUEta(0),
118 fNTRUPhi(0), fNCellsInTRUEta(0), fNCellsInTRUPhi(0), fTrd1Angle(0.),f2Trd1Dx2(0.),
119 fPhiGapForSM(0.),fKey110DEG(0),fPhiBoundariesOfSM(0), fPhiCentersOfSM(0), fEtaMaxOfTRD1(0),
120 fCentersOfCellsEtaDir(0),fCentersOfCellsXDir(0),fCentersOfCellsPhiDir(0),
121 fEtaCentersOfCells(0),fPhiCentersOfCells(0),fShishKebabTrd1Modules(0),
122 fILOSS(-1), fIHADR(-1),
123 //obsolete member data
124 fAlFrontThick(0.), fGap2Active(0.), fSteelFrontThick(0.), fTrd2AngleY(0.),
125 f2Trd2Dy2(0.), fEmptySpace(0.), fTubsR(0.), fTubsTurnAngle(0.)
127 // ctor only for internal usage (singleton)
128 AliDebug(2, Form("AliEMCALGeometry(%s,%s) ", name,title));
132 CreateListOfTrd1Modules();
134 if (AliDebugLevel()>=2) {
139 //______________________________________________________________________
140 AliEMCALGeometry::AliEMCALGeometry(const AliEMCALGeometry& geom)
142 fGeoName(geom.fGeoName),
143 fArrayOpts(geom.fArrayOpts),
144 fNAdditionalOpts(geom.fNAdditionalOpts),
145 fECPbRadThickness(geom.fECPbRadThickness),
146 fECScintThick(geom.fECScintThick),
147 fNECLayers(geom.fNECLayers),
148 fArm1PhiMin(geom.fArm1PhiMin),
149 fArm1PhiMax(geom.fArm1PhiMax),
150 fArm1EtaMin(geom.fArm1EtaMin),
151 fArm1EtaMax(geom.fArm1EtaMax),
152 fIPDistance(geom.fIPDistance),
153 fShellThickness(geom.fShellThickness),
154 fZLength(geom.fZLength),
157 fSampling(geom.fSampling),
158 fNumberOfSuperModules(geom.fNumberOfSuperModules),
159 fFrontSteelStrip(geom.fFrontSteelStrip),
160 fLateralSteelStrip(geom.fLateralSteelStrip),
161 fPassiveScintThick(geom.fPassiveScintThick),
162 fPhiModuleSize(geom.fPhiModuleSize),
163 fEtaModuleSize(geom.fEtaModuleSize),
164 fPhiTileSize(geom.fPhiTileSize),
165 fEtaTileSize(geom.fEtaTileSize),
166 fLongModuleSize(geom.fLongModuleSize),
167 fNPhiSuperModule(geom.fNPhiSuperModule),
168 fNPHIdiv(geom.fNPHIdiv),
169 fNETAdiv(geom.fNETAdiv),
170 fNCells(geom.fNCells),
171 fNCellsInSupMod(geom.fNCellsInSupMod),
172 fNCellsInModule(geom.fNCellsInModule),
173 fNTRUEta(geom.fNTRUEta),
174 fNTRUPhi(geom.fNTRUPhi),
175 fNCellsInTRUEta(geom.fNCellsInTRUEta),
176 fNCellsInTRUPhi(geom.fNCellsInTRUPhi),
177 fTrd1Angle(geom.fTrd1Angle),
178 f2Trd1Dx2(geom.f2Trd1Dx2),
179 fPhiGapForSM(geom.fPhiGapForSM),
180 fKey110DEG(geom.fKey110DEG),
181 fPhiBoundariesOfSM(geom.fPhiBoundariesOfSM),
182 fPhiCentersOfSM(geom.fPhiCentersOfSM),
183 fEtaMaxOfTRD1(geom.fEtaMaxOfTRD1),
184 fCentersOfCellsEtaDir(geom.fCentersOfCellsEtaDir),
185 fCentersOfCellsXDir(geom.fCentersOfCellsXDir),
186 fCentersOfCellsPhiDir(geom.fCentersOfCellsPhiDir),
187 fEtaCentersOfCells(geom.fEtaCentersOfCells),
188 fPhiCentersOfCells(geom.fPhiCentersOfCells),
189 fShishKebabTrd1Modules(geom.fShishKebabTrd1Modules),
190 fILOSS(geom.fILOSS), fIHADR(geom.fIHADR),
191 //obsolete member data
192 fAlFrontThick(geom.fAlFrontThick),
193 fGap2Active(geom.fGap2Active),
194 fSteelFrontThick(geom.fSteelFrontThick),
195 fTrd2AngleY(geom.fTrd2AngleY),
196 f2Trd2Dy2(geom.f2Trd2Dy2),
197 fEmptySpace(geom.fEmptySpace),
199 fTubsTurnAngle(geom.fTubsTurnAngle)
204 //______________________________________________________________________
205 AliEMCALGeometry::~AliEMCALGeometry(void){
208 //______________________________________________________________________
209 void AliEMCALGeometry::Init(void){
210 // Initializes the EMCAL parameters
211 // naming convention : GUV_WX_N_ gives the composition of a tower
212 // WX inform about the composition of the EM calorimeter section:
213 // thickness in mm of Pb radiator (W) and of scintillator (X), and number of scintillator layers (N)
214 // New geometry: EMCAL_55_25
215 // 24-aug-04 for shish-kebab
216 // SHISH_25 or SHISH_62
217 // 11-oct-05 - correction for pre final design
218 // Feb 06,2006 - decrease the weight of EMCAL
220 // Oct 30,2006 - SHISH_TRD1_CURRENT_1X1, SHISH_TRD1_CURRENT_2X2 or SHISH_TRD1_CURRENT_3X3;
223 fAdditionalOpts[0] = "nl="; // number of sampling layers (fNECLayers)
224 fAdditionalOpts[1] = "pbTh="; // cm, Thickness of the Pb (fECPbRadThick)
225 fAdditionalOpts[2] = "scTh="; // cm, Thickness of the Sc (fECScintThick)
226 fAdditionalOpts[3] = "latSS="; // cm, Thickness of lateral steel strip (fLateralSteelStrip)
227 fAdditionalOpts[4] = "allILOSS="; // = 0,1,2,3,4 (4 - energy loss without fluctuation)
228 fAdditionalOpts[5] = "allIHADR="; // = 0,1,2 (0 - no hadronic interaction)
230 fNAdditionalOpts = sizeof(fAdditionalOpts) / sizeof(char*);
232 fgInit = kFALSE; // Assume failed until proven otherwise.
233 fGeoName = GetName();
236 if(fGeoName.Contains("110DEG") || fGeoName.Contains("CURRENT")) fKey110DEG = 1; // for GetAbsCellId
237 fShishKebabTrd1Modules = 0;
239 fNZ = 114; // granularity along Z (eta)
240 fNPhi = 168; // granularity in phi (azimuth)
241 fArm1PhiMin = 80.0; // degrees, Starting EMCAL Phi position
242 fArm1PhiMax = 190.0; // degrees, Ending EMCAL Phi position
243 fArm1EtaMin = -0.7; // pseudorapidity, Starting EMCAL Eta position
244 fArm1EtaMax = +0.7; // pseudorapidity, Ending EMCAL Eta position
245 fIPDistance = 454.0; // cm, Radial distance to inner surface of EMCAL
246 fPhiGapForSM = 0.; // cm, only for final TRD1 geometry
249 //JLK: Change this to a check on allowable geometry names
250 // the end of the statement closes with an else that throws a Fatal
251 // exception for undefined geometry
252 if(fGeoName.Contains("SHISH")){ // Only shahslyk now
253 // 7-sep-05; integration issue
254 fArm1PhiMin = 80.0; // 60 -> 80
255 fArm1PhiMax = 180.0; // 180 -> 190
257 fNumberOfSuperModules = 10; // 12 = 6 * 2 (6 in phi, 2 in Z);
259 fFrontSteelStrip = fPassiveScintThick = 0.0; // 13-may-05
260 fLateralSteelStrip = 0.025; // before MAY 2005
261 fPhiModuleSize = fEtaModuleSize = 11.4;
262 fPhiTileSize = fEtaTileSize = 5.52; // (11.4-5.52*2)/2. = 0.18 cm (wall thickness)
265 fNPHIdiv = fNETAdiv = 2;
268 fECScintThick = fECPbRadThickness = 0.2;
269 fSampling = 1.; // 30-aug-04 - should be calculated
270 if(fGeoName.Contains("TRD")) {
271 fIPDistance = 428.0; // 11-may-05
274 fPhiModuleSize = fEtaModuleSize = 12.26;
275 fNZ = 26; // 11-oct-04
276 fTrd1Angle = 1.3; // in degree
277 // 18-nov-04; 1./0.08112=12.327
278 // http://pdsfweb01.nersc.gov/~pavlinov/ALICE/SHISHKEBAB/RES/linearityAndResolutionForTRD1.html
279 if(fGeoName.Contains("TRD1")) { // 30-jan-05
281 fPhiGapForSM = 2.; // cm, only for final TRD1 geometry
282 if(fGeoName.Contains("WSUC") || fGeoName.Contains("FINAL")){
283 fNumberOfSuperModules = 12; // 20-may-05
284 if(fGeoName.Contains("WSUC")) fNumberOfSuperModules = 1; // 27-may-05
285 fNECLayers = 77; // (13-may-05 from V.Petrov)
286 fPhiModuleSize = 12.5; // 20-may-05 - rectangular shape
287 fEtaModuleSize = 11.9;
288 fECScintThick = fECPbRadThickness = 0.16;// (13-may-05 from V.Petrov)
289 fFrontSteelStrip = 0.025;// 0.025cm = 0.25mm (13-may-05 from V.Petrov)
290 fLateralSteelStrip = 0.01; // 0.01cm = 0.1mm (13-may-05 from V.Petrov) - was 0.025
291 fPassiveScintThick = 0.8; // 0.8cm = 8mm (13-may-05 from V.Petrov)
293 fTrd1Angle = 1.5; // 1.3 or 1.5
295 if(fGeoName.Contains("FINAL")) { // 9-sep-05
296 fNumberOfSuperModules = 10;
298 fNumberOfSuperModules = 12;// last two modules have size 10 degree in phi (180<phi<190)
299 fArm1PhiMax = 200.0; // for XEN1 and turn angle of super modules
301 if(fGeoName.Contains("FINAL")) {
302 fPhiModuleSize = 12.26 - fPhiGapForSM / Float_t(fNPhi); // first assumption
304 fEtaModuleSize = fPhiModuleSize;
308 fNPHIdiv = fNETAdiv = 2; // 13-oct-04 - division again
310 if(fGeoName.Contains("WSUC")){ // 18-may-05 - about common structure
311 fShellThickness = 30.; // should be change
315 CheckAdditionalOptions();
316 DefineSamplingFraction();
318 fPhiTileSize = fPhiModuleSize/double(fNPHIdiv) - fLateralSteelStrip; // 13-may-05
319 fEtaTileSize = fEtaModuleSize/double(fNETAdiv) - fLateralSteelStrip; // 13-may-05
321 // constant for transition absid <--> indexes
322 fNCellsInModule = fNPHIdiv*fNETAdiv;
323 fNCellsInSupMod = fNCellsInModule*fNPhi*fNZ;
324 fNCells = fNCellsInSupMod*fNumberOfSuperModules;
325 if(GetKey110DEG()) fNCells -= fNCellsInSupMod;
327 fLongModuleSize = fNECLayers*(fECScintThick + fECPbRadThickness);
330 if(fGeoName.Contains("TRD")) {
331 f2Trd1Dx2 = fEtaModuleSize + 2.*fLongModuleSize*TMath::Tan(fTrd1Angle*TMath::DegToRad()/2.);
333 } else Fatal("Init", "%s is an undefined geometry!", fGeoName.Data()) ;
335 //JLK: The following options are true for all geometries
337 fNPhiSuperModule = fNumberOfSuperModules/2;
338 if(fNPhiSuperModule<1) fNPhiSuperModule = 1;
340 fShellThickness = fLongModuleSize;
341 if(fGeoName.Contains("TRD")) { // 1-oct-04
342 fShellThickness = TMath::Sqrt(fLongModuleSize*fLongModuleSize + f2Trd1Dx2*f2Trd1Dx2);
344 fParSM[0] = GetShellThickness()/2.;
345 fParSM[1] = GetPhiModuleSize() * GetNPhi()/2.;
349 fZLength = 2.*ZFromEtaR(fIPDistance+fShellThickness,fArm1EtaMax); // Z coverage
350 fEnvelop[0] = fIPDistance; // mother volume inner radius
351 fEnvelop[1] = fIPDistance + fShellThickness; // mother volume outer r.
352 fEnvelop[2] = 1.00001*fZLength; // add some padding for mother volume.
354 fNumberOfSuperModules = 12;
356 // SM phi boundaries - (0,1),(2,3) .. (10,11) - has the same boundaries; Nov 7, 2006
357 fPhiBoundariesOfSM.Set(fNumberOfSuperModules);
358 fPhiCentersOfSM.Set(fNumberOfSuperModules/2);
359 fPhiBoundariesOfSM[0] = TMath::PiOver2() - TMath::ATan2(fParSM[1] , fIPDistance); // 1th and 2th modules)
360 fPhiBoundariesOfSM[1] = TMath::PiOver2() + TMath::ATan2(fParSM[1] , fIPDistance);
361 fPhiCentersOfSM[0] = TMath::PiOver2();
362 for(int i=1; i<=4; i++) { // from 2th ro 9th
363 fPhiBoundariesOfSM[2*i] = fPhiBoundariesOfSM[0] + 20.*TMath::DegToRad()*i;
364 fPhiBoundariesOfSM[2*i+1] = fPhiBoundariesOfSM[1] + 20.*TMath::DegToRad()*i;
365 fPhiCentersOfSM[i] = fPhiCentersOfSM[0] + 20.*TMath::DegToRad()*i;
367 fPhiBoundariesOfSM[11] = 190.*TMath::DegToRad();
368 fPhiBoundariesOfSM[10] = fPhiBoundariesOfSM[11] - TMath::ATan2((fParSM[1]) , fIPDistance);
369 fPhiCentersOfSM[5] = (fPhiBoundariesOfSM[10]+fPhiBoundariesOfSM[11])/2.;
371 //TRU parameters. These parameters values are not the final ones.
374 fNCellsInTRUEta = 16 ;
375 fNCellsInTRUPhi = 24 ;
377 if(fGeoName.Contains("WSUC")) fNumberOfSuperModules = 1; // Jul 12, 2007
382 void AliEMCALGeometry::PrintGeometry()
384 // Separate routine is callable from broswer; Nov 7,2006
385 printf("\nInit: geometry of EMCAL named %s :\n", fGeoName.Data());
387 for(Int_t i=0; i<fArrayOpts->GetEntries(); i++){
388 TObjString *o = (TObjString*)fArrayOpts->At(i);
389 printf(" %i : %s \n", i, o->String().Data());
392 printf("Granularity: %d in eta and %d in phi\n", GetNZ(), GetNPhi()) ;
393 printf("Layout: phi = (%7.1f, %7.1f), eta = (%5.2f, %5.2f), IP = %7.2f -> for EMCAL envelope only\n",
394 GetArm1PhiMin(), GetArm1PhiMax(),GetArm1EtaMin(), GetArm1EtaMax(), GetIPDistance() );
396 printf( " ECAL : %d x (%f cm Pb, %f cm Sc) \n",
397 GetNECLayers(), GetECPbRadThick(), GetECScintThick() ) ;
398 printf(" fSampling %5.2f \n", fSampling );
399 if(fGeoName.Contains("SHISH")){
400 printf(" fIPDistance %6.3f cm \n", fIPDistance);
401 printf(" fNPhi %i | fNZ %i \n", fNPhi, fNZ);
402 printf(" fNCellsInModule %i : fNCellsInSupMod %i : fNCells %i\n",fNCellsInModule, fNCellsInSupMod, fNCells);
403 printf(" X:Y module size %6.3f , %6.3f cm \n", fPhiModuleSize, fEtaModuleSize);
404 printf(" X:Y tile size %6.3f , %6.3f cm \n", fPhiTileSize, fEtaTileSize);
405 printf(" #of sampling layers %i(fNECLayers) \n", fNECLayers);
406 printf(" fLongModuleSize %6.3f cm \n", fLongModuleSize);
407 printf(" #supermodule in phi direction %i \n", fNPhiSuperModule );
409 printf(" fILOSS %i : fIHADR %i \n", fILOSS, fIHADR);
410 if(fGeoName.Contains("TRD")) {
411 printf(" fTrd1Angle %7.4f\n", fTrd1Angle);
412 printf(" f2Trd1Dx2 %7.4f\n", f2Trd1Dx2);
413 if(fGeoName.Contains("TRD1")){
414 printf("SM dimensions(TRD1) : dx %7.2f dy %7.2f dz %7.2f (SMOD, BOX)\n",
415 fParSM[0],fParSM[1],fParSM[2]);
416 printf(" fPhiGapForSM %7.4f cm (%7.4f <- phi size in degree)\n",
417 fPhiGapForSM, TMath::ATan2(fPhiGapForSM,fIPDistance)*TMath::RadToDeg());
418 if(GetKey110DEG()) printf(" Last two modules have size 10 degree in phi (180<phi<190)\n");
419 printf(" phi SM boundaries \n");
420 for(int i=0; i<fPhiBoundariesOfSM.GetSize()/2.; i++) {
421 printf(" %i : %7.5f(%7.2f) -> %7.5f(%7.2f) : center %7.5f(%7.2f) \n", i,
422 fPhiBoundariesOfSM[2*i], fPhiBoundariesOfSM[2*i]*TMath::RadToDeg(),
423 fPhiBoundariesOfSM[2*i+1], fPhiBoundariesOfSM[2*i+1]*TMath::RadToDeg(),
424 fPhiCentersOfSM[i], fPhiCentersOfSM[i]*TMath::RadToDeg());
426 printf(" fShishKebabTrd1Modules has %i modules : max eta %5.4f \n",
427 fShishKebabTrd1Modules->GetSize(),fEtaMaxOfTRD1);
429 printf("\n Cells grid in eta directions : size %i\n", fCentersOfCellsEtaDir.GetSize());
430 for(Int_t i=0; i<fCentersOfCellsEtaDir.GetSize(); i++) {
431 printf(" ind %2.2i : z %8.3f : x %8.3f \n", i,
432 fCentersOfCellsEtaDir.At(i),fCentersOfCellsXDir.At(i));
433 int ind=0; // Nov 21,2006
434 for(Int_t iphi=0; iphi<fCentersOfCellsPhiDir.GetSize(); iphi++) {
435 ind = iphi*fCentersOfCellsEtaDir.GetSize() + i;
436 printf("%6.4f ", fEtaCentersOfCells[ind]);
437 if((iphi+1)%12 == 0) printf("\n");
443 printf("\n Cells grid in phi directions : size %i\n", fCentersOfCellsPhiDir.GetSize());
444 for(Int_t i=0; i<fCentersOfCellsPhiDir.GetSize(); i++) {
445 double phi=fPhiCentersOfCells.At(i);
446 printf(" ind %2.2i : y %8.3f : phi %7.5f(%6.2f) \n", i, fCentersOfCellsPhiDir.At(i),
447 phi, phi*TMath::RadToDeg());
453 void AliEMCALGeometry::PrintCellIndexes(Int_t absId, int pri, char *tit)
456 Int_t nSupMod, nModule, nIphi, nIeta;
460 GetCellIndex(absId, nSupMod, nModule, nIphi, nIeta);
461 printf(" %s | absId : %i -> nSupMod %i nModule %i nIphi %i nIeta %i \n", tit, absId, nSupMod, nModule, nIphi, nIeta);
463 GetCellPhiEtaIndexInSModule(nSupMod,nModule,nIphi,nIeta, iphi,ieta);
464 printf(" local SM index : iphi %i : ieta %i \n", iphi,ieta);
465 GetGlobal(absId, vg);
466 printf(" vglob : mag %7.2f : perp %7.2f : z %7.2f : eta %6.4f : phi %6.4f(%6.2f) \n",
467 vg.Mag(), vg.Perp(), vg.Z(), vg.Eta(), vg.Phi(), vg.Phi()*TMath::RadToDeg());
471 //______________________________________________________________________
472 void AliEMCALGeometry::CheckAdditionalOptions()
475 // Additional options that
476 // can be used to select
477 // the specific geometry of
480 // adeed allILOSS= and allIHADR= for MIP investigation
481 fArrayOpts = new TObjArray;
482 Int_t nopt = AliEMCALHistoUtilities::ParseString(fGeoName, *fArrayOpts);
483 if(nopt==1) { // no aditional option(s)
484 fArrayOpts->Delete();
489 for(Int_t i=1; i<nopt; i++){
490 TObjString *o = (TObjString*)fArrayOpts->At(i);
492 TString addOpt = o->String();
494 for(Int_t j=0; j<fNAdditionalOpts; j++) {
495 TString opt = fAdditionalOpts[j];
496 if(addOpt.Contains(opt,TString::kIgnoreCase)) {
502 AliDebug(2,Form("<E> option |%s| unavailable : ** look to the file AliEMCALGeometry.h **\n",
506 AliDebug(2,Form("<I> option |%s| is valid : number %i : |%s|\n",
507 addOpt.Data(), indj, fAdditionalOpts[indj]));
508 if (addOpt.Contains("NL=",TString::kIgnoreCase)) {// number of sampling layers
509 sscanf(addOpt.Data(),"NL=%i", &fNECLayers);
510 AliDebug(2,Form(" fNECLayers %i (new) \n", fNECLayers));
511 } else if(addOpt.Contains("PBTH=",TString::kIgnoreCase)) {//Thickness of the Pb(fECPbRadThicknes)
512 sscanf(addOpt.Data(),"PBTH=%f", &fECPbRadThickness);
513 } else if(addOpt.Contains("SCTH=",TString::kIgnoreCase)) {//Thickness of the Sc(fECScintThick)
514 sscanf(addOpt.Data(),"SCTH=%f", &fECScintThick);
515 } else if(addOpt.Contains("LATSS=",TString::kIgnoreCase)) {// Thickness of lateral steel strip (fLateralSteelStrip)
516 sscanf(addOpt.Data(),"LATSS=%f", &fLateralSteelStrip);
517 AliDebug(2,Form(" fLateralSteelStrip %f (new) \n", fLateralSteelStrip));
518 } else if(addOpt.Contains("ILOSS=",TString::kIgnoreCase)) {// As in Geant
519 sscanf(addOpt.Data(),"ALLILOSS=%i", &fILOSS);
520 AliDebug(2,Form(" fILOSS %i \n", fILOSS));
521 } else if(addOpt.Contains("IHADR=",TString::kIgnoreCase)) {// As in Geant
522 sscanf(addOpt.Data(),"ALLIHADR=%i", &fIHADR);
523 AliDebug(2,Form(" fIHADR %i \n", fIHADR));
529 void AliEMCALGeometry::DefineSamplingFraction()
532 // Look http://rhic.physics.wayne.edu/~pavlinov/ALICE/SHISHKEBAB/RES/linearityAndResolutionForTRD1.html
533 // Keep for compatibilty
535 if(fNECLayers == 69) { // 10% layer reduction
537 } else if(fNECLayers == 61) { // 20% layer reduction
539 } else if(fNECLayers == 77) {
540 if (fECScintThick>0.175 && fECScintThick<0.177) { // 10% Pb thicknes reduction
541 fSampling = 10.5; // fECScintThick = 0.176, fECPbRadThickness=0.144;
542 } else if(fECScintThick>0.191 && fECScintThick<0.193) { // 20% Pb thicknes reduction
543 fSampling = 8.93; // fECScintThick = 0.192, fECPbRadThickness=0.128;
548 //______________________________________________________________________
549 void AliEMCALGeometry::GetCellPhiEtaIndexInSModuleFromTRUIndex(const Int_t itru, const Int_t iphitru, const Int_t ietatru, Int_t &iphiSM, Int_t &ietaSM) const
552 // This method transforms the (eta,phi) index of cells in a
553 // TRU matrix into Super Module (eta,phi) index.
555 // Calculate in which row and column where the TRU are
558 Int_t col = itru/ fNTRUPhi ;
559 Int_t row = itru - col*fNTRUPhi ;
561 iphiSM = fNCellsInTRUPhi*row + iphitru ;
562 ietaSM = fNCellsInTRUEta*col + ietatru ;
565 //______________________________________________________________________
566 AliEMCALGeometry * AliEMCALGeometry::GetInstance(){
567 // Returns the pointer of the unique instance
569 AliEMCALGeometry * rv = static_cast<AliEMCALGeometry *>( fgGeom );
573 //______________________________________________________________________
574 AliEMCALGeometry* AliEMCALGeometry::GetInstance(const Text_t* name,
575 const Text_t* title){
576 // Returns the pointer of the unique instance
578 AliEMCALGeometry * rv = 0;
580 if ( strcmp(name,"") == 0 ) { // get default geometry
581 fgGeom = new AliEMCALGeometry(fgDefaultGeometryName, title);
583 fgGeom = new AliEMCALGeometry(name, title);
584 } // end if strcmp(name,"")
585 if ( fgInit ) rv = (AliEMCALGeometry * ) fgGeom;
592 if ( strcmp(fgGeom->GetName(), name) != 0) {
593 printf("\ncurrent geometry is %s : ", fgGeom->GetName());
594 printf(" you cannot call %s ",name);
596 rv = (AliEMCALGeometry *) fgGeom;
602 Bool_t AliEMCALGeometry::IsInEMCAL(Double_t x, Double_t y, Double_t z) const {
603 // Checks whether point is inside the EMCal volume, used in AliEMCALv*.cxx
605 // Code uses cylindrical approximation made of inner radius (for speed)
607 // Points behind EMCAl, i.e. R > outer radius, but eta, phi in acceptance
608 // are considered to inside
610 Double_t r=sqrt(x*x+y*y);
612 if ( r > fEnvelop[0] ) {
614 theta = TMath::ATan2(r,z);
619 eta = -TMath::Log(TMath::Tan(theta/2.));
620 if (eta < fArm1EtaMin || eta > fArm1EtaMax)
623 Double_t phi = TMath::ATan2(y,x) * 180./TMath::Pi();
624 if (phi < 0) phi += 360; // phi should go from 0 to 360 in this case
625 if (phi > fArm1PhiMin && phi < fArm1PhiMax)
633 // == Shish-kebab cases ==
635 Int_t AliEMCALGeometry::GetAbsCellId(Int_t nSupMod, Int_t nModule, Int_t nIphi, Int_t nIeta) const
639 // 13-oct-05; 110 degree case
640 // May 31, 2006; ALICE numbering scheme:
641 // 0 <= nSupMod < fNumberOfSuperModules
642 // 0 <= nModule < fNPHI * fNZ ( fNPHI * fNZ/2 for fKey110DEG=1)
643 // 0 <= nIphi < fNPHIdiv
644 // 0 <= nIeta < fNETAdiv
645 // 0 <= absid < fNCells
646 static Int_t id=0; // have to change from 0 to fNCells-1
647 if(fKey110DEG == 1 && nSupMod >= 10) { // 110 degree case; last two supermodules
648 id = fNCellsInSupMod*10 + (fNCellsInSupMod/2)*(nSupMod-10);
650 id = fNCellsInSupMod*nSupMod;
652 id += fNCellsInModule *nModule;
653 id += fNPHIdiv *nIphi;
655 if(id<0 || id >= fNCells) {
656 // printf(" wrong numerations !!\n");
657 // printf(" id %6i(will be force to -1)\n", id);
658 // printf(" fNCells %6i\n", fNCells);
659 // printf(" nSupMod %6i\n", nSupMod);
660 // printf(" nModule %6i\n", nModule);
661 // printf(" nIphi %6i\n", nIphi);
662 // printf(" nIeta %6i\n", nIeta);
663 id = -TMath::Abs(id); // if negative something wrong
668 Bool_t AliEMCALGeometry::CheckAbsCellId(Int_t absId) const
670 // May 31, 2006; only trd1 now
671 if(absId<0 || absId >= fNCells) return kFALSE;
675 Bool_t AliEMCALGeometry::GetCellIndex(Int_t absId,Int_t &nSupMod,Int_t &nModule,Int_t &nIphi,Int_t &nIeta) const
677 // 21-sep-04; 19-oct-05;
678 // May 31, 2006; ALICE numbering scheme:
681 // absId - cell is as in Geant, 0<= absId < fNCells;
683 // nSupMod - super module(SM) number, 0<= nSupMod < fNumberOfSuperModules;
684 // nModule - module number in SM, 0<= nModule < fNCellsInSupMod/fNCellsInSupMod or(/2) for tow last SM (10th and 11th);
685 // nIphi - cell number in phi driection inside module; 0<= nIphi < fNPHIdiv;
686 // nIeta - cell number in eta driection inside module; 0<= nIeta < fNETAdiv;
688 static Int_t tmp=0, sm10=0;
689 if(!CheckAbsCellId(absId)) return kFALSE;
691 sm10 = fNCellsInSupMod*10;
692 if(fKey110DEG == 1 && absId >= sm10) { // 110 degree case; last two supermodules
693 nSupMod = (absId-sm10) / (fNCellsInSupMod/2) + 10;
694 tmp = (absId-sm10) % (fNCellsInSupMod/2);
696 nSupMod = absId / fNCellsInSupMod;
697 tmp = absId % fNCellsInSupMod;
700 nModule = tmp / fNCellsInModule;
701 tmp = tmp % fNCellsInModule;
702 nIphi = tmp / fNPHIdiv;
703 nIeta = tmp % fNPHIdiv;
708 void AliEMCALGeometry::GetModulePhiEtaIndexInSModule(Int_t nSupMod, Int_t nModule, int &iphim, int &ietam) const
710 // added nSupMod; - 19-oct-05 !
711 // Alice numbering scheme - Jun 01,2006
712 // ietam, iphi - indexes of module in two dimensional grid of SM
713 // ietam - have to change from 0 to fNZ-1
714 // iphim - have to change from 0 to nphi-1 (fNPhi-1 or fNPhi/2-1)
717 if(fKey110DEG == 1 && nSupMod>=10) nphi = fNPhi/2;
720 ietam = nModule/nphi;
721 iphim = nModule%nphi;
724 void AliEMCALGeometry::GetCellPhiEtaIndexInSModule(Int_t nSupMod, Int_t nModule, Int_t nIphi, Int_t nIeta,
725 int &iphi, int &ieta) const
728 // Added nSupMod; Nov 25, 05
729 // Alice numbering scheme - Jun 01,2006
731 // nSupMod - super module(SM) number, 0<= nSupMod < fNumberOfSuperModules;
732 // nModule - module number in SM, 0<= nModule < fNCellsInSupMod/fNCellsInSupMod or(/2) for tow last SM (10th and 11th);
733 // nIphi - cell number in phi driection inside module; 0<= nIphi < fNPHIdiv;
734 // nIeta - cell number in eta driection inside module; 0<= nIeta < fNETAdiv;
737 // ieta, iphi - indexes of cell(tower) in two dimensional grid of SM
738 // ieta - have to change from 0 to (fNZ*fNETAdiv-1)
739 // iphi - have to change from 0 to (fNPhi*fNPHIdiv-1 or fNPhi*fNPHIdiv/2-1)
741 static Int_t iphim, ietam;
743 GetModulePhiEtaIndexInSModule(nSupMod,nModule, iphim, ietam);
744 // ieta = ietam*fNETAdiv + (1-nIeta); // x(module) = -z(SM)
745 ieta = ietam*fNETAdiv + (fNETAdiv - 1 - nIeta); // x(module) = -z(SM)
746 iphi = iphim*fNPHIdiv + nIphi; // y(module) = y(SM)
749 AliDebug(1,Form(" nSupMod %i nModule %i nIphi %i nIeta %i => ieta %i iphi %i\n",
750 nSupMod, nModule, nIphi, nIeta, ieta, iphi));
753 Int_t AliEMCALGeometry::GetSuperModuleNumber(Int_t absId) const
755 // Return the number of the supermodule given the absolute
756 // ALICE numbering id
758 static Int_t nSupMod, nModule, nIphi, nIeta;
759 GetCellIndex(absId, nSupMod, nModule, nIphi, nIeta);
763 void AliEMCALGeometry::GetModuleIndexesFromCellIndexesInSModule(Int_t nSupMod, Int_t iphi, Int_t ieta,
764 Int_t &iphim, Int_t &ietam, Int_t &nModule) const
766 // Transition from cell indexes (ieta,iphi) to module indexes (ietam,iphim, nModule)
768 nphi = GetNumberOfModuleInPhiDirection(nSupMod);
770 ietam = ieta/fNETAdiv;
771 iphim = iphi/fNPHIdiv;
772 nModule = ietam * nphi + iphim;
775 Int_t AliEMCALGeometry::GetAbsCellIdFromCellIndexes(Int_t nSupMod, Int_t iphi, Int_t ieta) const
777 // Transition from super module number(nSupMod) and cell indexes (ieta,iphi) to absId
778 static Int_t ietam, iphim, nModule;
779 static Int_t nIeta, nIphi; // cell indexes in module
781 GetModuleIndexesFromCellIndexesInSModule(nSupMod, iphi, ieta, ietam, iphim, nModule);
783 nIeta = ieta%fNETAdiv;
784 nIeta = fNETAdiv - 1 - nIeta;
785 nIphi = iphi%fNPHIdiv;
787 return GetAbsCellId(nSupMod, nModule, nIphi, nIeta);
791 // Methods for AliEMCALRecPoint - Feb 19, 2006
792 Bool_t AliEMCALGeometry::RelPosCellInSModule(Int_t absId, Double_t &xr, Double_t &yr, Double_t &zr) const
794 // Look to see what the relative
795 // position inside a given cell is
797 // Alice numbering scheme - Jun 08, 2006
799 // absId - cell is as in Geant, 0<= absId < fNCells;
801 // xr,yr,zr - x,y,z coordinates of cell with absId inside SM
803 // Shift index taking into account the difference between standard SM
804 // and SM of half size in phi direction
805 const Int_t kphiIndexShift = fCentersOfCellsPhiDir.GetSize()/4; // Nov 22, 2006; was 6 for cas 2X2
806 static Int_t nSupMod, nModule, nIphi, nIeta, iphi, ieta;
807 if(!CheckAbsCellId(absId)) return kFALSE;
809 GetCellIndex(absId, nSupMod, nModule, nIphi, nIeta);
810 GetCellPhiEtaIndexInSModule(nSupMod,nModule,nIphi,nIeta, iphi, ieta);
812 xr = fCentersOfCellsXDir.At(ieta);
813 zr = fCentersOfCellsEtaDir.At(ieta);
816 yr = fCentersOfCellsPhiDir.At(iphi);
818 yr = fCentersOfCellsPhiDir.At(iphi + kphiIndexShift);
820 AliDebug(1,Form("absId %i nSupMod %i iphi %i ieta %i xr %f yr %f zr %f ",absId,nSupMod,iphi,ieta,xr,yr,zr));
825 Bool_t AliEMCALGeometry::RelPosCellInSModule(Int_t absId, Double_t loc[3]) const
827 // Alice numbering scheme - Jun 03, 2006
828 loc[0] = loc[1] = loc[2]=0.0;
829 if(RelPosCellInSModule(absId, loc[0],loc[1],loc[2])) {
835 Bool_t AliEMCALGeometry::RelPosCellInSModule(Int_t absId, TVector3 &vloc) const
837 static Double_t loc[3];
838 if(RelPosCellInSModule(absId,loc)) {
839 vloc.SetXYZ(loc[0], loc[1], loc[2]);
845 // Alice numbering scheme - Jun 03, 2006
848 Bool_t AliEMCALGeometry::RelPosCellInSModule(Int_t absId, Double_t distEff, Double_t &xr, Double_t &yr, Double_t &zr) const
850 // Jul 30, 2007 - taking into account position of shower max
851 // Look to see what the relative
852 // position inside a given cell is
855 // absId - cell is as in Geant, 0<= absId < fNCells;
856 // e - cluster energy
858 // xr,yr,zr - x,y,z coordinates of cell with absId inside SM
860 // Shift index taking into account the difference between standard SM
861 // and SM of half size in phi direction
862 const Int_t kphiIndexShift = fCentersOfCellsPhiDir.GetSize()/4; // Nov 22, 2006; was 6 for cas 2X2
863 static Int_t nSupMod, nModule, nIphi, nIeta, iphi, ieta;
864 static Int_t iphim, ietam;
865 static AliEMCALShishKebabTrd1Module *mod = 0;
867 if(!CheckAbsCellId(absId)) return kFALSE;
869 GetCellIndex(absId, nSupMod, nModule, nIphi, nIeta);
870 GetModulePhiEtaIndexInSModule(nSupMod, nModule, iphim, ietam);
871 GetCellPhiEtaIndexInSModule(nSupMod,nModule,nIphi,nIeta, iphi, ieta);
873 mod = GetShishKebabModule(ietam);
874 mod->GetPositionAtCenterCellLine(nIeta, distEff, v);
875 xr = v.Y() - fParSM[0];
876 zr = v.X() - fParSM[2];
879 yr = fCentersOfCellsPhiDir.At(iphi);
881 yr = fCentersOfCellsPhiDir.At(iphi + kphiIndexShift);
883 AliDebug(1,Form("absId %i nSupMod %i iphi %i ieta %i xr %f yr %f zr %f ",absId,nSupMod,iphi,ieta,xr,yr,zr));
888 Bool_t AliEMCALGeometry::RelPosCellInSModule(Int_t absId, Int_t maxAbsId, Double_t distEff, Double_t &xr, Double_t &yr, Double_t &zr) const
890 // Jul 31, 2007 - taking into account position of shower max and apply coor2.
891 // Look to see what the relative
892 // position inside a given cell is
895 // absId - cell is as in Geant, 0<= absId < fNCells;
896 // maxAbsId - abs id of cell with highest energy
897 // e - cluster energy
899 // xr,yr,zr - x,y,z coordinates of cell with absId inside SM
901 // Shift index taking into account the difference between standard SM
902 // and SM of half size in phi direction
903 const Int_t kphiIndexShift = fCentersOfCellsPhiDir.GetSize()/4; // Nov 22, 2006; was 6 for cas 2X2
904 static Int_t nSupMod, nModule, nIphi, nIeta, iphi, ieta;
905 static Int_t iphim, ietam;
906 static AliEMCALShishKebabTrd1Module *mod = 0;
909 static Int_t nSupModM, nModuleM, nIphiM, nIetaM, iphiM, ietaM;
910 static Int_t iphimM, ietamM, maxAbsIdCopy=-1;
911 static AliEMCALShishKebabTrd1Module *modM = 0;
912 static Double_t distCorr;
914 if(!CheckAbsCellId(absId)) return kFALSE;
916 GetCellIndex(absId, nSupMod, nModule, nIphi, nIeta);
917 GetModulePhiEtaIndexInSModule(nSupMod, nModule, iphim, ietam);
918 GetCellPhiEtaIndexInSModule(nSupMod,nModule,nIphi,nIeta, iphi, ieta);
919 mod = GetShishKebabModule(ietam);
921 if(absId != maxAbsId) {
923 if(maxAbsIdCopy != maxAbsId) {
924 GetCellIndex(maxAbsId, nSupModM, nModuleM, nIphiM, nIetaM);
925 GetModulePhiEtaIndexInSModule(nSupModM, nModuleM, iphimM, ietamM);
926 GetCellPhiEtaIndexInSModule(nSupModM,nModuleM,nIphiM,nIetaM, iphiM, ietaM);
927 modM = GetShishKebabModule(ietamM); // do I need this ?
928 maxAbsIdCopy = maxAbsId;
931 distCorr = GetEtaModuleSize()*(ietam-ietamM)/TMath::Tan(modM->GetTheta()); // Stay here
932 //printf(" distCorr %f | dist %f | ietam %i -> etamM %i\n", distCorr, dist, ietam, ietamM);
934 // distEff += distCorr;
936 // Bad resolution in this case, strong bias vs phi
938 mod->GetPositionAtCenterCellLine(nIeta, distEff, v); // Stay here
939 xr = v.Y() - fParSM[0];
940 zr = v.X() - fParSM[2];
943 yr = fCentersOfCellsPhiDir.At(iphi);
945 yr = fCentersOfCellsPhiDir.At(iphi + kphiIndexShift);
947 AliDebug(1,Form("absId %i nSupMod %i iphi %i ieta %i xr %f yr %f zr %f ",absId,nSupMod,iphi,ieta,xr,yr,zr));
952 void AliEMCALGeometry::CreateListOfTrd1Modules()
954 // Generate the list of Trd1 modules
955 // which will make up the EMCAL
958 AliDebug(2,Form(" AliEMCALGeometry::CreateListOfTrd1Modules() started "));
960 AliEMCALShishKebabTrd1Module *mod=0, *mTmp=0; // current module
961 if(fShishKebabTrd1Modules == 0) {
962 fShishKebabTrd1Modules = new TList;
963 fShishKebabTrd1Modules->SetName("ListOfTRD1");
964 for(int iz=0; iz< GetNZ(); iz++) {
966 mod = new AliEMCALShishKebabTrd1Module(TMath::Pi()/2.,this);
968 mTmp = new AliEMCALShishKebabTrd1Module(*mod);
971 fShishKebabTrd1Modules->Add(mod);
974 AliDebug(2,Form(" Already exits : "));
976 mod = (AliEMCALShishKebabTrd1Module*)fShishKebabTrd1Modules->At(fShishKebabTrd1Modules->GetSize()-1);
977 fEtaMaxOfTRD1 = mod->GetMaxEtaOfModule(0);
979 AliDebug(2,Form(" fShishKebabTrd1Modules has %i modules : max eta %5.4f \n",
980 fShishKebabTrd1Modules->GetSize(),fEtaMaxOfTRD1));
982 // Jun 01, 2006 - ALICE numbering scheme
983 // define grid for cells in eta(z) and x directions in local coordinates system of SM
984 // Works just for 2x2 case only -- ?? start here
987 // Define grid for cells in phi(y) direction in local coordinates system of SM
988 // as for 2X2 as for 3X3 - Nov 8,2006
990 AliDebug(2,Form(" Cells grid in phi directions : size %i\n", fCentersOfCellsPhiDir.GetSize()));
991 Int_t ind=0; // this is phi index
992 Int_t ieta=0, nModule=0, iphiTemp;
993 Double_t xr, zr, theta, phi, eta, r, x,y;
995 Double_t ytCenterModule=0.0, ytCenterCell=0.0;
997 fCentersOfCellsPhiDir.Set(fNPhi*fNPHIdiv);
998 fPhiCentersOfCells.Set(fNPhi*fNPHIdiv);
1000 Double_t r0 = GetIPDistance() + GetLongModuleSize()/2.;
1001 for(Int_t it=0; it<fNPhi; it++) { // cycle on modules
1002 ytCenterModule = -fParSM[1] + fPhiModuleSize*(2*it+1)/2; // center of module
1003 for(Int_t ic=0; ic<fNPHIdiv; ic++) { // cycle on cells in module
1005 ytCenterCell = ytCenterModule + fPhiTileSize *(2*ic-1)/2.;
1006 } else if(fNPHIdiv==3){
1007 ytCenterCell = ytCenterModule + fPhiTileSize *(ic-1);
1008 } else if(fNPHIdiv==1){
1009 ytCenterCell = ytCenterModule;
1011 fCentersOfCellsPhiDir.AddAt(ytCenterCell,ind);
1012 // Define grid on phi direction
1013 // Grid is not the same for different eta bin;
1014 // Effect is small but is still here
1015 phi = TMath::ATan2(ytCenterCell, r0);
1016 fPhiCentersOfCells.AddAt(phi, ind);
1018 AliDebug(2,Form(" ind %2.2i : y %8.3f ", ind, fCentersOfCellsPhiDir.At(ind)));
1023 fCentersOfCellsEtaDir.Set(fNZ *fNETAdiv);
1024 fCentersOfCellsXDir.Set(fNZ *fNETAdiv);
1025 fEtaCentersOfCells.Set(fNZ *fNETAdiv * fNPhi*fNPHIdiv);
1026 AliDebug(2,Form(" Cells grid in eta directions : size %i\n", fCentersOfCellsEtaDir.GetSize()));
1027 for(Int_t it=0; it<fNZ; it++) {
1028 AliEMCALShishKebabTrd1Module *trd1 = GetShishKebabModule(it);
1030 for(Int_t ic=0; ic<fNETAdiv; ic++) {
1032 trd1->GetCenterOfCellInLocalCoordinateofSM(ic, xr, zr); // case of 2X2
1033 GetCellPhiEtaIndexInSModule(0, nModule, 0, ic, iphiTemp, ieta);
1035 trd1->GetCenterOfCellInLocalCoordinateofSM_3X3(ic, xr, zr); // case of 3X3
1036 GetCellPhiEtaIndexInSModule(0, nModule, 0, ic, iphiTemp, ieta);
1038 trd1->GetCenterOfCellInLocalCoordinateofSM_1X1(xr, zr); // case of 1X1
1039 GetCellPhiEtaIndexInSModule(0, nModule, 0, ic, iphiTemp, ieta);
1041 fCentersOfCellsXDir.AddAt(float(xr) - fParSM[0],ieta);
1042 fCentersOfCellsEtaDir.AddAt(float(zr) - fParSM[2],ieta);
1043 // Define grid on eta direction for each bin in phi
1044 for(int iphi=0; iphi<fCentersOfCellsPhiDir.GetSize(); iphi++) {
1045 x = xr + trd1->GetRadius();
1046 y = fCentersOfCellsPhiDir[iphi];
1047 r = TMath::Sqrt(x*x + y*y + zr*zr);
1048 theta = TMath::ACos(zr/r);
1049 eta = AliEMCALShishKebabTrd1Module::ThetaToEta(theta);
1050 // ind = ieta*fCentersOfCellsPhiDir.GetSize() + iphi;
1051 ind = iphi*fCentersOfCellsEtaDir.GetSize() + ieta;
1052 fEtaCentersOfCells.AddAt(eta, ind);
1054 //printf(" ieta %i : xr + trd1->GetRadius() %f : zr %f : eta %f \n", ieta, xr + trd1->GetRadius(), zr, eta);
1057 for(Int_t i=0; i<fCentersOfCellsEtaDir.GetSize(); i++) {
1058 AliDebug(2,Form(" ind %2.2i : z %8.3f : x %8.3f", i+1,
1059 fCentersOfCellsEtaDir.At(i),fCentersOfCellsXDir.At(i)));
1064 void AliEMCALGeometry::GetGlobal(const Double_t *loc, Double_t *glob, int ind) const
1066 // Figure out the global numbering
1067 // of a given supermodule from the
1068 // local numbering and the transformation
1069 // matrix stored by the geometry manager (allows for misaligned
1072 if(ind>=0 && ind < GetNumberOfSuperModules()) {
1073 TString volpath = "ALIC_1/XEN1_1/SMOD_";
1076 if(GetKey110DEG() && ind>=10) {
1077 volpath = "ALIC_1/XEN1_1/SM10_";
1078 volpath += ind-10+1;
1081 if(!gGeoManager->cd(volpath.Data()))
1082 AliFatal(Form("AliEMCALGeometry::GeoManager cannot find path %s!",volpath.Data()));
1084 TGeoHMatrix* m = gGeoManager->GetCurrentMatrix();
1086 m->LocalToMaster(loc, glob);
1088 AliFatal("Geo matrixes are not loaded \n") ;
1093 void AliEMCALGeometry::GetGlobal(const TVector3 &vloc, TVector3 &vglob, int ind) const
1095 //Figure out the global numbering
1096 //of a given supermodule from the
1097 //local numbering given a 3-vector location
1099 static Double_t tglob[3], tloc[3];
1101 GetGlobal(tloc, tglob, ind);
1102 vglob.SetXYZ(tglob[0], tglob[1], tglob[2]);
1105 void AliEMCALGeometry::GetGlobal(Int_t absId , double glob[3]) const
1107 // Alice numbering scheme - Jun 03, 2006
1108 static Int_t nSupMod, nModule, nIphi, nIeta;
1109 static double loc[3];
1111 if (!gGeoManager || !gGeoManager->IsClosed()) {
1112 AliError("Can't get the global coordinates! gGeoManager doesn't exist or it is still open!");
1116 glob[0]=glob[1]=glob[2]=0.0; // bad case
1117 if(RelPosCellInSModule(absId, loc)) {
1118 GetCellIndex(absId, nSupMod, nModule, nIphi, nIeta);
1120 TString volpath = "ALIC_1/XEN1_1/SMOD_";
1121 volpath += (nSupMod+1);
1123 if(GetKey110DEG() && nSupMod>=10) {
1124 volpath = "ALIC_1/XEN1_1/SM10_";
1125 volpath += (nSupMod-10+1);
1127 if(!gGeoManager->cd(volpath.Data()))
1128 AliFatal(Form("GeoManager cannot find path %s!",volpath.Data()));
1130 TGeoHMatrix* m = gGeoManager->GetCurrentMatrix();
1132 m->LocalToMaster(loc, glob);
1134 AliFatal("Geo matrixes are not loaded \n") ;
1139 //___________________________________________________________________
1140 void AliEMCALGeometry::GetGlobal(Int_t absId , TVector3 &vglob) const
1142 // Alice numbering scheme - Jun 03, 2006
1143 static Double_t glob[3];
1145 GetGlobal(absId, glob);
1146 vglob.SetXYZ(glob[0], glob[1], glob[2]);
1150 //____________________________________________________________________________
1151 void AliEMCALGeometry::GetGlobal(const AliRecPoint* /*rp*/, TVector3& /* vglob */) const
1153 AliFatal(Form("Please use GetGlobalEMCAL(recPoint,gpos) instead of GetGlobal!"));
1156 //_________________________________________________________________________________
1157 void AliEMCALGeometry::GetGlobalEMCAL(const AliEMCALRecPoint *rp, TVector3 &vglob) const
1159 // Figure out the global numbering
1160 // of a given supermodule from the
1161 // local numbering for RecPoints
1163 static TVector3 vloc;
1164 static Int_t nSupMod, nModule, nIphi, nIeta;
1166 const AliEMCALRecPoint *rpTmp = rp;
1167 const AliEMCALRecPoint *rpEmc = rpTmp;
1169 GetCellIndex(rpEmc->GetAbsId(0), nSupMod, nModule, nIphi, nIeta);
1170 rpTmp->GetLocalPosition(vloc);
1171 GetGlobal(vloc, vglob, nSupMod);
1174 void AliEMCALGeometry::EtaPhiFromIndex(Int_t absId,Double_t &eta,Double_t &phi) const
1176 // Nov 16, 2006- float to double
1177 // version for TRD1 only
1178 static TVector3 vglob;
1179 GetGlobal(absId, vglob);
1184 void AliEMCALGeometry::EtaPhiFromIndex(Int_t absId,Float_t &eta,Float_t &phi) const
1186 // Nov 16,2006 - should be discard in future
1187 static TVector3 vglob;
1188 GetGlobal(absId, vglob);
1189 eta = float(vglob.Eta());
1190 phi = float(vglob.Phi());
1193 Bool_t AliEMCALGeometry::GetPhiBoundariesOfSM(Int_t nSupMod, Double_t &phiMin, Double_t &phiMax) const
1195 // 0<= nSupMod <=11; phi in rad
1197 if(nSupMod<0 || nSupMod >11) return kFALSE;
1199 phiMin = fPhiBoundariesOfSM[2*i];
1200 phiMax = fPhiBoundariesOfSM[2*i+1];
1204 Bool_t AliEMCALGeometry::GetPhiBoundariesOfSMGap(Int_t nPhiSec, Double_t &phiMin, Double_t &phiMax) const
1206 // 0<= nPhiSec <=4; phi in rad
1207 // 0; gap boundaries between 0th&2th | 1th&3th SM
1208 // 1; gap boundaries between 2th&4th | 3th&5th SM
1209 // 2; gap boundaries between 4th&6th | 5th&7th SM
1210 // 3; gap boundaries between 6th&8th | 7th&9th SM
1211 // 4; gap boundaries between 8th&10th | 9th&11th SM
1212 if(nPhiSec<0 || nPhiSec >4) return kFALSE;
1213 phiMin = fPhiBoundariesOfSM[2*nPhiSec+1];
1214 phiMax = fPhiBoundariesOfSM[2*nPhiSec+2];
1218 Bool_t AliEMCALGeometry::SuperModuleNumberFromEtaPhi(Double_t eta, Double_t phi, Int_t &nSupMod) const
1220 // Return false if phi belongs a phi cracks between SM
1224 if(TMath::Abs(eta) > fEtaMaxOfTRD1) return kFALSE;
1226 phi = TVector2::Phi_0_2pi(phi); // move phi to (0,2pi) boundaries
1227 for(i=0; i<6; i++) {
1228 if(phi>=fPhiBoundariesOfSM[2*i] && phi<=fPhiBoundariesOfSM[2*i+1]) {
1230 if(eta < 0.0) nSupMod++;
1231 AliDebug(1,Form("eta %f phi %f(%5.2f) : nSupMod %i : #bound %i", eta,phi,phi*TMath::RadToDeg(), nSupMod,i));
1238 Bool_t AliEMCALGeometry::GetAbsCellIdFromEtaPhi(Double_t eta, Double_t phi, Int_t &absId) const
1241 // stay here - phi problem as usual
1242 static Int_t nSupMod, i, ieta, iphi, etaShift, nphi;
1243 static Double_t absEta=0.0, d=0.0, dmin=0.0, phiLoc;
1244 absId = nSupMod = - 1;
1245 if(SuperModuleNumberFromEtaPhi(eta, phi, nSupMod)) {
1247 phi = TVector2::Phi_0_2pi(phi);
1248 phiLoc = phi - fPhiCentersOfSM[nSupMod/2];
1249 nphi = fPhiCentersOfCells.GetSize();
1251 phiLoc = phi - 190.*TMath::DegToRad();
1255 dmin = TMath::Abs(fPhiCentersOfCells[0]-phiLoc);
1257 for(i=1; i<nphi; i++) {
1258 d = TMath::Abs(fPhiCentersOfCells[i] - phiLoc);
1263 // printf(" i %i : d %f : dmin %f : fPhiCentersOfCells[i] %f \n", i, d, dmin, fPhiCentersOfCells[i]);
1265 // odd SM are turned with respect of even SM - reverse indexes
1266 AliDebug(2,Form(" iphi %i : dmin %f (phi %f, phiLoc %f ) ", iphi, dmin, phi, phiLoc));
1268 absEta = TMath::Abs(eta);
1269 etaShift = iphi*fCentersOfCellsEtaDir.GetSize();
1270 dmin = TMath::Abs(fEtaCentersOfCells[etaShift]-absEta);
1272 for(i=1; i<fCentersOfCellsEtaDir.GetSize(); i++) {
1273 d = TMath::Abs(fEtaCentersOfCells[i+etaShift] - absEta);
1279 AliDebug(2,Form(" ieta %i : dmin %f (eta=%f) : nSupMod %i ", ieta, dmin, eta, nSupMod));
1281 if(eta<0) iphi = (nphi-1) - iphi;
1282 absId = GetAbsCellIdFromCellIndexes(nSupMod, iphi, ieta);
1289 AliEMCALShishKebabTrd1Module* AliEMCALGeometry::GetShishKebabModule(Int_t neta) const
1291 //This method was too long to be
1292 //included in the header file - the
1293 //rule checker complained about it's
1294 //length, so we move it here. It returns the
1295 //shishkebabmodule at a given eta index point.
1297 static AliEMCALShishKebabTrd1Module* trd1=0;
1298 if(fShishKebabTrd1Modules && neta>=0 && neta<fShishKebabTrd1Modules->GetSize()) {
1299 trd1 = (AliEMCALShishKebabTrd1Module*)fShishKebabTrd1Modules->At(neta);
1304 void AliEMCALGeometry::Browse(TBrowser* b)
1306 //Browse the modules
1307 if(fShishKebabTrd1Modules) b->Add(fShishKebabTrd1Modules);
1310 Bool_t AliEMCALGeometry::IsFolder() const
1312 //Check if fShishKebabTrd1Modules is in folder
1313 if(fShishKebabTrd1Modules) return kTRUE;
1317 Double_t AliEMCALGeometry::GetPhiCenterOfSM(Int_t nsupmod) const
1319 //returns center of supermodule in phi
1321 return fPhiCentersOfSM[i];