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 // with scintillator fiber arranged as "shish-kebab" skewers
22 // Places the the Barrel Geometry of The EMCAL at Midrapidity
23 // between 80 and 180(or 190) degrees of Phi and
26 // EMCAL geometry tree:
27 // EMCAL -> superModule -> module -> tower(cell)
29 // absId -> nSupMod -> nModule -> (nIphi,nIeta)
32 // EMCAL_PDC06 (geometry used for PDC06 simulations, kept for backward compatibility)
33 // = equivalent to SHISH_77_TRD1_2X2_FINAL_110DEG in old notation
34 // EMCAL_COMPLETE (geometry for expected complete detector)
35 // = equivalent to SHISH_77_TRD1_2X2_FINAL_110DEG scTh=0.176 pbTh=0.144
37 // EMCAL_WSUC (Wayne State test stand)
38 // = no definite equivalent in old notation, was only used by
39 // Aleksei, but kept for testing purposes
45 //*-- Author: Sahal Yacoob (LBL / UCT)
46 // and : Yves Schutz (SUBATECH)
47 // and : Jennifer Klay (LBL)
48 // and : Aleksei Pavlinov (WSU)
53 // --- Root header files ---
54 #include <Riostream.h>
56 #include <TClonesArray.h>
57 #include <TGeoManager.h>
58 #include <TGeoMatrix.h>
62 #include <TObjArray.h>
63 #include <TObjString.h>
71 #include "AliEMCALGeometry.h"
72 #include "AliEMCALShishKebabTrd1Module.h"
73 #include "AliEMCALRecPoint.h"
74 #include "AliEMCALDigit.h"
75 #include "AliEMCALHistoUtilities.h"
77 ClassImp(AliEMCALGeometry)
79 // these initialisations are needed for a singleton
80 AliEMCALGeometry *AliEMCALGeometry::fgGeom = 0;
81 Bool_t AliEMCALGeometry::fgInit = kFALSE;
82 Char_t* AliEMCALGeometry::fgDefaultGeometryName = "EMCAL_COMPLETE";
85 // You can create the AliEMCALGeometry object independently from anything.
86 // You have to use just the correct name of geometry. If name is empty string the
87 // default name of geometry will be used.
89 // AliEMCALGeometry* g = AliEMCALGeometry::GetInstance(name,title); // first time
91 // g = AliEMCALGeometry::GetInstance(); // after first time
93 // MC: If you work with MC data you have to get geometry the next way:
94 // == =============================
95 // AliRunLoader *rl = AliRunLoader::GetRunLoader();
96 // AliEMCALGeometry *geom = dynamic_cast<AliEMCAL*>(rl->GetAliRun()->GetDetector("EMCAL"))->GetGeometry();
97 // TGeoManager::Import("geometry.root");
99 AliEMCALGeometry::AliEMCALGeometry()
101 fGeoName(0),fArrayOpts(0),fNAdditionalOpts(0),fECPbRadThickness(0.),fECScintThick(0.),
102 fNECLayers(0),fArm1PhiMin(0.),fArm1PhiMax(0.),fArm1EtaMin(0.),fArm1EtaMax(0.),fIPDistance(0.),
103 fShellThickness(0.),fZLength(0.),fNZ(0),fNPhi(0),fSampling(0.),fNumberOfSuperModules(0),
104 fFrontSteelStrip(0.),fLateralSteelStrip(0.),fPassiveScintThick(0.),fPhiModuleSize(0.),
105 fEtaModuleSize(0.),fPhiTileSize(0.),fEtaTileSize(0.),fLongModuleSize(0.),fNPhiSuperModule(0),
106 fNPHIdiv(0),fNETAdiv(0), fNCells(0),fNCellsInSupMod(0),fNCellsInModule(0),fNTRUEta(0),
107 fNTRUPhi(0), fNCellsInTRUEta(0), fNCellsInTRUPhi(0), fTrd1Angle(0.),f2Trd1Dx2(0.),
108 fPhiGapForSM(0.),fKey110DEG(0),fPhiBoundariesOfSM(0), fPhiCentersOfSM(0),fEtaMaxOfTRD1(0),
109 fCentersOfCellsEtaDir(0), fCentersOfCellsXDir(0),fCentersOfCellsPhiDir(0),
110 fEtaCentersOfCells(0),fPhiCentersOfCells(0),fShishKebabTrd1Modules(0),
111 fILOSS(-1), fIHADR(-1),
112 //obsolete member data
113 fAlFrontThick(0.), fGap2Active(0.), fSteelFrontThick(0.), fTrd2AngleY(0.),
114 f2Trd2Dy2(0.), fEmptySpace(0.), fTubsR(0.), fTubsTurnAngle(0.)
116 // default ctor only for internal usage (singleton)
117 // must be kept public for root persistency purposes,
118 // but should never be called by the outside world
120 AliDebug(2, "AliEMCALGeometry : default ctor ");
122 //______________________________________________________________________
123 AliEMCALGeometry::AliEMCALGeometry(const Text_t* name, const Text_t* title)
124 : AliGeometry(name, title),
125 fGeoName(0),fArrayOpts(0),fNAdditionalOpts(0),fECPbRadThickness(0.),fECScintThick(0.),
126 fNECLayers(0),fArm1PhiMin(0.),fArm1PhiMax(0.),fArm1EtaMin(0.),fArm1EtaMax(0.),fIPDistance(0.),
127 fShellThickness(0.),fZLength(0.),fNZ(0),fNPhi(0),fSampling(0.),fNumberOfSuperModules(0),
128 fFrontSteelStrip(0.),fLateralSteelStrip(0.),fPassiveScintThick(0.),fPhiModuleSize(0.),
129 fEtaModuleSize(0.),fPhiTileSize(0.),fEtaTileSize(0.),fLongModuleSize(0.),fNPhiSuperModule(0),
130 fNPHIdiv(0),fNETAdiv(0), fNCells(0),fNCellsInSupMod(0),fNCellsInModule(0),fNTRUEta(0),
131 fNTRUPhi(0), fNCellsInTRUEta(0), fNCellsInTRUPhi(0), fTrd1Angle(0.),f2Trd1Dx2(0.),
132 fPhiGapForSM(0.),fKey110DEG(0),fPhiBoundariesOfSM(0), fPhiCentersOfSM(0), fEtaMaxOfTRD1(0),
133 fCentersOfCellsEtaDir(0),fCentersOfCellsXDir(0),fCentersOfCellsPhiDir(0),
134 fEtaCentersOfCells(0),fPhiCentersOfCells(0),fShishKebabTrd1Modules(0),
135 fILOSS(-1), fIHADR(-1),
136 //obsolete member data
137 fAlFrontThick(0.), fGap2Active(0.), fSteelFrontThick(0.), fTrd2AngleY(0.),
138 f2Trd2Dy2(0.), fEmptySpace(0.), fTubsR(0.), fTubsTurnAngle(0.)
140 // ctor only for internal usage (singleton)
141 AliDebug(2, Form("AliEMCALGeometry(%s,%s) ", name,title));
145 CreateListOfTrd1Modules();
147 if (AliDebugLevel()>=2) {
152 //______________________________________________________________________
153 AliEMCALGeometry::AliEMCALGeometry(const AliEMCALGeometry& geom)
155 fGeoName(geom.fGeoName),
156 fArrayOpts(geom.fArrayOpts),
157 fNAdditionalOpts(geom.fNAdditionalOpts),
158 fECPbRadThickness(geom.fECPbRadThickness),
159 fECScintThick(geom.fECScintThick),
160 fNECLayers(geom.fNECLayers),
161 fArm1PhiMin(geom.fArm1PhiMin),
162 fArm1PhiMax(geom.fArm1PhiMax),
163 fArm1EtaMin(geom.fArm1EtaMin),
164 fArm1EtaMax(geom.fArm1EtaMax),
165 fIPDistance(geom.fIPDistance),
166 fShellThickness(geom.fShellThickness),
167 fZLength(geom.fZLength),
170 fSampling(geom.fSampling),
171 fNumberOfSuperModules(geom.fNumberOfSuperModules),
172 fFrontSteelStrip(geom.fFrontSteelStrip),
173 fLateralSteelStrip(geom.fLateralSteelStrip),
174 fPassiveScintThick(geom.fPassiveScintThick),
175 fPhiModuleSize(geom.fPhiModuleSize),
176 fEtaModuleSize(geom.fEtaModuleSize),
177 fPhiTileSize(geom.fPhiTileSize),
178 fEtaTileSize(geom.fEtaTileSize),
179 fLongModuleSize(geom.fLongModuleSize),
180 fNPhiSuperModule(geom.fNPhiSuperModule),
181 fNPHIdiv(geom.fNPHIdiv),
182 fNETAdiv(geom.fNETAdiv),
183 fNCells(geom.fNCells),
184 fNCellsInSupMod(geom.fNCellsInSupMod),
185 fNCellsInModule(geom.fNCellsInModule),
186 fNTRUEta(geom.fNTRUEta),
187 fNTRUPhi(geom.fNTRUPhi),
188 fNCellsInTRUEta(geom.fNCellsInTRUEta),
189 fNCellsInTRUPhi(geom.fNCellsInTRUPhi),
190 fTrd1Angle(geom.fTrd1Angle),
191 f2Trd1Dx2(geom.f2Trd1Dx2),
192 fPhiGapForSM(geom.fPhiGapForSM),
193 fKey110DEG(geom.fKey110DEG),
194 fPhiBoundariesOfSM(geom.fPhiBoundariesOfSM),
195 fPhiCentersOfSM(geom.fPhiCentersOfSM),
196 fEtaMaxOfTRD1(geom.fEtaMaxOfTRD1),
197 fCentersOfCellsEtaDir(geom.fCentersOfCellsEtaDir),
198 fCentersOfCellsXDir(geom.fCentersOfCellsXDir),
199 fCentersOfCellsPhiDir(geom.fCentersOfCellsPhiDir),
200 fEtaCentersOfCells(geom.fEtaCentersOfCells),
201 fPhiCentersOfCells(geom.fPhiCentersOfCells),
202 fShishKebabTrd1Modules(geom.fShishKebabTrd1Modules),
203 fILOSS(geom.fILOSS), fIHADR(geom.fIHADR),
204 //obsolete member data
205 fAlFrontThick(geom.fAlFrontThick),
206 fGap2Active(geom.fGap2Active),
207 fSteelFrontThick(geom.fSteelFrontThick),
208 fTrd2AngleY(geom.fTrd2AngleY),
209 f2Trd2Dy2(geom.f2Trd2Dy2),
210 fEmptySpace(geom.fEmptySpace),
212 fTubsTurnAngle(geom.fTubsTurnAngle)
217 //______________________________________________________________________
218 AliEMCALGeometry::~AliEMCALGeometry(void){
222 //______________________________________________________________________
223 void AliEMCALGeometry::Init(void){
225 // Initializes the EMCAL parameters based on the name
226 // Only Shashlyk geometry is available, but various combinations of
227 // layers and number of supermodules can be selected with additional
228 // options or geometry name
231 fAdditionalOpts[0] = "nl="; // number of sampling layers (fNECLayers)
232 fAdditionalOpts[1] = "pbTh="; // cm, Thickness of the Pb (fECPbRadThick)
233 fAdditionalOpts[2] = "scTh="; // cm, Thickness of the Sc (fECScintThick)
234 fAdditionalOpts[3] = "latSS="; // cm, Thickness of lateral steel strip (fLateralSteelStrip)
235 fAdditionalOpts[4] = "allILOSS="; // = 0,1,2,3,4 (4 - energy loss without fluctuation)
236 fAdditionalOpts[5] = "allIHADR="; // = 0,1,2 (0 - no hadronic interaction)
238 fNAdditionalOpts = sizeof(fAdditionalOpts) / sizeof(char*);
241 fgInit = kFALSE; // Assume failed until proven otherwise.
242 fGeoName = GetName();
245 //Convert old geometry names to new ones
246 if(fGeoName.Contains("SHISH_77_TRD1_2X2_FINAL_110DEG")) {
247 if(fGeoName.Contains("PBTH=0.144") && fGeoName.Contains("SCTH=0.176")) {
248 fGeoName = "EMCAL_COMPLETE";
250 fGeoName = "EMCAL_PDC06";
253 if(fGeoName.Contains("WSUC")) fGeoName = "EMCAL_WSUC";
255 //check that we have a valid geometry name
256 if(!(fGeoName.Contains("EMCAL_PDC06") || fGeoName.Contains("EMCAL_COMPLETE") || fGeoName.Contains("EMCAL_WSUC"))) {
257 Fatal("Init", "%s is an undefined geometry!", fGeoName.Data()) ;
260 // Option to know whether we have the "half" supermodule(s) or not
262 if(fGeoName.Contains("COMPLETE") || fGeoName.Contains("PDC06")) fKey110DEG = 1; // for GetAbsCellId
263 fShishKebabTrd1Modules = 0;
266 //default parameters are those of EMCAL_COMPLETE geometry
267 //all others render variations from these at the end of
268 //geometry-name specific options
270 fNumberOfSuperModules = 12; // 12 = 6 * 2 (6 in phi, 2 in Z)
271 fNPhi = 12; // module granularity in phi within smod (azimuth)
272 fNZ = 24; // module granularity along Z within smod (eta)
273 fNPHIdiv = fNETAdiv = 2; // tower granularity within module
274 fArm1PhiMin = 80.0; // degrees, Starting EMCAL Phi position
275 fArm1PhiMax = 200.0; // degrees, Ending EMCAL Phi position
276 fArm1EtaMin = -0.7; // pseudorapidity, Starting EMCAL Eta position
277 fArm1EtaMax = +0.7; // pseudorapidity, Ending EMCAL Eta position
278 fIPDistance = 428.0; // cm, radial distance to front face from nominal vertex point
279 fPhiGapForSM = 2.; // cm, only for final TRD1 geometry
280 fFrontSteelStrip = 0.025; // 0.025cm = 0.25mm (13-may-05 from V.Petrov)
281 fPassiveScintThick = 0.8; // 0.8cm = 8mm (13-may-05 from V.Petrov)
282 fLateralSteelStrip = 0.01; // 0.01cm = 0.1mm (13-may-05 from V.Petrov) - was 0.025
283 fTrd1Angle = 1.5; // in degrees
285 fSampling = 1.; // should be calculated with call to DefineSamplingFraction()
286 fNECLayers = 77; // (13-may-05 from V.Petrov) - can be changed with additional options
287 fECScintThick = 0.176; // scintillator layer thickness
288 fECPbRadThickness = 0.144; // lead layer thickness
290 fPhiModuleSize = 12.26 - fPhiGapForSM / Float_t(fNPhi); // first assumption
291 fEtaModuleSize = fPhiModuleSize;
293 //needs to be called for each geometry and before setting geometry
294 //parameters which can depend on the outcome
295 CheckAdditionalOptions();
297 //modifications to the above for PDC06 geometry
298 if(fGeoName.Contains("PDC06")){ // 18-may-05 - about common structure
299 fECScintThick = fECPbRadThickness = 0.16;// (13-may-05 from V.Petrov)
300 CheckAdditionalOptions();
303 //modifications to the above for WSUC geometry
304 if(fGeoName.Contains("WSUC")){ // 18-may-05 - about common structure
305 fPhiModuleSize = 12.5; // 20-may-05 - rectangular shape
306 fEtaModuleSize = 11.9;
307 fECScintThick = fECPbRadThickness = 0.16;// (13-may-05 from V.Petrov)
308 fNumberOfSuperModules = 1; // 27-may-05
309 fShellThickness = 30.; // should be change
311 CheckAdditionalOptions();
314 // constant for transition absid <--> indexes
315 fNCellsInModule = fNPHIdiv*fNETAdiv;
316 fNCellsInSupMod = fNCellsInModule*fNPhi*fNZ;
317 fNCells = fNCellsInSupMod*fNumberOfSuperModules;
318 if(GetKey110DEG()) fNCells -= fNCellsInSupMod;
320 fNPhiSuperModule = fNumberOfSuperModules/2;
321 if(fNPhiSuperModule<1) fNPhiSuperModule = 1;
323 fPhiTileSize = fPhiModuleSize/double(fNPHIdiv) - fLateralSteelStrip; // 13-may-05
324 fEtaTileSize = fEtaModuleSize/double(fNETAdiv) - fLateralSteelStrip; // 13-may-05
326 fLongModuleSize = fNECLayers*(fECScintThick + fECPbRadThickness);
327 f2Trd1Dx2 = fEtaModuleSize + 2.*fLongModuleSize*TMath::Tan(fTrd1Angle*TMath::DegToRad()/2.);
328 if(!fGeoName.Contains("WSUC")) fShellThickness = TMath::Sqrt(fLongModuleSize*fLongModuleSize + f2Trd1Dx2*f2Trd1Dx2);
330 fZLength = 2.*ZFromEtaR(fIPDistance+fShellThickness,fArm1EtaMax); // Z coverage
331 fEnvelop[0] = fIPDistance; // mother volume inner radius
332 fEnvelop[1] = fIPDistance + fShellThickness; // mother volume outer r.
333 fEnvelop[2] = 1.00001*fZLength; // add some padding for mother volume.
336 fParSM[0] = GetShellThickness()/2.;
337 fParSM[1] = GetPhiModuleSize() * GetNPhi()/2.;
340 // SM phi boundaries - (0,1),(2,3) .. (10,11) - has the same boundaries; Nov 7, 2006
341 fPhiBoundariesOfSM.Set(fNumberOfSuperModules);
342 fPhiCentersOfSM.Set(fNumberOfSuperModules/2);
343 fPhiBoundariesOfSM[0] = TMath::PiOver2() - TMath::ATan2(fParSM[1] , fIPDistance); // 1th and 2th modules)
344 fPhiCentersOfSM[0] = TMath::PiOver2();
345 if(fNumberOfSuperModules > 1)
346 fPhiBoundariesOfSM[1] = TMath::PiOver2() + TMath::ATan2(fParSM[1] , fIPDistance);
347 if(fNumberOfSuperModules > 2) {
348 for(int i=1; i<=4; i++) { // from 2th ro 9th
349 fPhiBoundariesOfSM[2*i] = fPhiBoundariesOfSM[0] + 20.*TMath::DegToRad()*i;
350 fPhiBoundariesOfSM[2*i+1] = fPhiBoundariesOfSM[1] + 20.*TMath::DegToRad()*i;
351 fPhiCentersOfSM[i] = fPhiCentersOfSM[0] + 20.*TMath::DegToRad()*i;
354 if(fNumberOfSuperModules > 10) {
355 fPhiBoundariesOfSM[11] = 190.*TMath::DegToRad();
356 fPhiBoundariesOfSM[10] = fPhiBoundariesOfSM[11] - TMath::ATan2((fParSM[1]) , fIPDistance);
357 fPhiCentersOfSM[5] = (fPhiBoundariesOfSM[10]+fPhiBoundariesOfSM[11])/2.;
360 //called after setting of scintillator and lead layer parameters
361 DefineSamplingFraction();
363 //TRU parameters. These parameters values are not the final ones.
366 fNCellsInTRUEta = 16 ;
367 fNCellsInTRUPhi = 24 ;
372 void AliEMCALGeometry::PrintGeometry()
374 // Separate routine is callable from broswer; Nov 7,2006
375 printf("\nInit: geometry of EMCAL named %s :\n", fGeoName.Data());
377 for(Int_t i=0; i<fArrayOpts->GetEntries(); i++){
378 TObjString *o = (TObjString*)fArrayOpts->At(i);
379 printf(" %i : %s \n", i, o->String().Data());
382 printf("Granularity: %d in eta and %d in phi\n", GetNZ(), GetNPhi()) ;
383 printf("Layout: phi = (%7.1f, %7.1f), eta = (%5.2f, %5.2f), IP = %7.2f -> for EMCAL envelope only\n",
384 GetArm1PhiMin(), GetArm1PhiMax(),GetArm1EtaMin(), GetArm1EtaMax(), GetIPDistance() );
386 printf( " ECAL : %d x (%f cm Pb, %f cm Sc) \n",
387 GetNECLayers(), GetECPbRadThick(), GetECScintThick() ) ;
388 printf(" fSampling %5.2f \n", fSampling );
389 printf(" fIPDistance %6.3f cm \n", fIPDistance);
390 printf(" fNPhi %i | fNZ %i \n", fNPhi, fNZ);
391 printf(" fNCellsInModule %i : fNCellsInSupMod %i : fNCells %i\n",fNCellsInModule, fNCellsInSupMod, fNCells);
392 printf(" X:Y module size %6.3f , %6.3f cm \n", fPhiModuleSize, fEtaModuleSize);
393 printf(" X:Y tile size %6.3f , %6.3f cm \n", fPhiTileSize, fEtaTileSize);
394 printf(" #of sampling layers %i(fNECLayers) \n", fNECLayers);
395 printf(" fLongModuleSize %6.3f cm \n", fLongModuleSize);
396 printf(" #supermodule in phi direction %i \n", fNPhiSuperModule );
397 printf(" fILOSS %i : fIHADR %i \n", fILOSS, fIHADR);
398 printf(" fTrd1Angle %7.4f\n", fTrd1Angle);
399 printf(" f2Trd1Dx2 %7.4f\n", f2Trd1Dx2);
400 printf("SM dimensions(TRD1) : dx %7.2f dy %7.2f dz %7.2f (SMOD, BOX)\n",
401 fParSM[0],fParSM[1],fParSM[2]);
402 printf(" fPhiGapForSM %7.4f cm (%7.4f <- phi size in degree)\n",
403 fPhiGapForSM, TMath::ATan2(fPhiGapForSM,fIPDistance)*TMath::RadToDeg());
404 if(GetKey110DEG()) printf(" Last two modules have size 10 degree in phi (180<phi<190)\n");
405 printf(" phi SM boundaries \n");
406 for(int i=0; i<fPhiBoundariesOfSM.GetSize()/2.; i++) {
407 printf(" %i : %7.5f(%7.2f) -> %7.5f(%7.2f) : center %7.5f(%7.2f) \n", i,
408 fPhiBoundariesOfSM[2*i], fPhiBoundariesOfSM[2*i]*TMath::RadToDeg(),
409 fPhiBoundariesOfSM[2*i+1], fPhiBoundariesOfSM[2*i+1]*TMath::RadToDeg(),
410 fPhiCentersOfSM[i], fPhiCentersOfSM[i]*TMath::RadToDeg());
412 printf(" fShishKebabTrd1Modules has %i modules : max eta %5.4f \n",
413 fShishKebabTrd1Modules->GetSize(),fEtaMaxOfTRD1);
415 printf("\n Cells grid in eta directions : size %i\n", fCentersOfCellsEtaDir.GetSize());
416 for(Int_t i=0; i<fCentersOfCellsEtaDir.GetSize(); i++) {
417 printf(" ind %2.2i : z %8.3f : x %8.3f \n", i,
418 fCentersOfCellsEtaDir.At(i),fCentersOfCellsXDir.At(i));
419 int ind=0; // Nov 21,2006
420 for(Int_t iphi=0; iphi<fCentersOfCellsPhiDir.GetSize(); iphi++) {
421 ind = iphi*fCentersOfCellsEtaDir.GetSize() + i;
422 printf("%6.4f ", fEtaCentersOfCells[ind]);
423 if((iphi+1)%12 == 0) printf("\n");
429 printf("\n Cells grid in phi directions : size %i\n", fCentersOfCellsPhiDir.GetSize());
430 for(Int_t i=0; i<fCentersOfCellsPhiDir.GetSize(); i++) {
431 double phi=fPhiCentersOfCells.At(i);
432 printf(" ind %2.2i : y %8.3f : phi %7.5f(%6.2f) \n", i, fCentersOfCellsPhiDir.At(i),
433 phi, phi*TMath::RadToDeg());
438 //______________________________________________________________________
439 void AliEMCALGeometry::PrintCellIndexes(Int_t absId, int pri, char *tit)
442 Int_t nSupMod, nModule, nIphi, nIeta;
446 GetCellIndex(absId, nSupMod, nModule, nIphi, nIeta);
447 printf(" %s | absId : %i -> nSupMod %i nModule %i nIphi %i nIeta %i \n", tit, absId, nSupMod, nModule, nIphi, nIeta);
449 GetCellPhiEtaIndexInSModule(nSupMod,nModule,nIphi,nIeta, iphi,ieta);
450 printf(" local SM index : iphi %i : ieta %i \n", iphi,ieta);
451 GetGlobal(absId, vg);
452 printf(" vglob : mag %7.2f : perp %7.2f : z %7.2f : eta %6.4f : phi %6.4f(%6.2f) \n",
453 vg.Mag(), vg.Perp(), vg.Z(), vg.Eta(), vg.Phi(), vg.Phi()*TMath::RadToDeg());
457 //______________________________________________________________________
458 void AliEMCALGeometry::CheckAdditionalOptions()
461 // Additional options that
462 // can be used to select
463 // the specific geometry of
466 // adeed allILOSS= and allIHADR= for MIP investigation
467 fArrayOpts = new TObjArray;
468 Int_t nopt = AliEMCALHistoUtilities::ParseString(fGeoName, *fArrayOpts);
469 if(nopt==1) { // no aditional option(s)
470 fArrayOpts->Delete();
475 for(Int_t i=1; i<nopt; i++){
476 TObjString *o = (TObjString*)fArrayOpts->At(i);
478 TString addOpt = o->String();
480 for(Int_t j=0; j<fNAdditionalOpts; j++) {
481 TString opt = fAdditionalOpts[j];
482 if(addOpt.Contains(opt,TString::kIgnoreCase)) {
488 AliDebug(2,Form("<E> option |%s| unavailable : ** look to the file AliEMCALGeometry.h **\n",
492 AliDebug(2,Form("<I> option |%s| is valid : number %i : |%s|\n",
493 addOpt.Data(), indj, fAdditionalOpts[indj]));
494 if (addOpt.Contains("NL=",TString::kIgnoreCase)) {// number of sampling layers
495 sscanf(addOpt.Data(),"NL=%i", &fNECLayers);
496 AliDebug(2,Form(" fNECLayers %i (new) \n", fNECLayers));
497 } else if(addOpt.Contains("PBTH=",TString::kIgnoreCase)) {//Thickness of the Pb(fECPbRadThicknes)
498 sscanf(addOpt.Data(),"PBTH=%f", &fECPbRadThickness);
499 } else if(addOpt.Contains("SCTH=",TString::kIgnoreCase)) {//Thickness of the Sc(fECScintThick)
500 sscanf(addOpt.Data(),"SCTH=%f", &fECScintThick);
501 } else if(addOpt.Contains("LATSS=",TString::kIgnoreCase)) {// Thickness of lateral steel strip (fLateralSteelStrip)
502 sscanf(addOpt.Data(),"LATSS=%f", &fLateralSteelStrip);
503 AliDebug(2,Form(" fLateralSteelStrip %f (new) \n", fLateralSteelStrip));
504 } else if(addOpt.Contains("ILOSS=",TString::kIgnoreCase)) {// As in Geant
505 sscanf(addOpt.Data(),"ALLILOSS=%i", &fILOSS);
506 AliDebug(2,Form(" fILOSS %i \n", fILOSS));
507 } else if(addOpt.Contains("IHADR=",TString::kIgnoreCase)) {// As in Geant
508 sscanf(addOpt.Data(),"ALLIHADR=%i", &fIHADR);
509 AliDebug(2,Form(" fIHADR %i \n", fIHADR));
515 void AliEMCALGeometry::DefineSamplingFraction()
518 // Look http://rhic.physics.wayne.edu/~pavlinov/ALICE/SHISHKEBAB/RES/linearityAndResolutionForTRD1.html
519 // Keep for compatibilty
521 if(fNECLayers == 69) { // 10% layer reduction
523 } else if(fNECLayers == 61) { // 20% layer reduction
525 } else if(fNECLayers == 77) {
526 if (fECScintThick>0.159 && fECScintThick<0.161) { // original sampling fraction, equal layers
527 fSampling = 12.327; // fECScintThick = fECPbRadThickness = 0.160;
528 } else if (fECScintThick>0.175 && fECScintThick<0.177) { // 10% Pb thicknes reduction
529 fSampling = 10.5; // fECScintThick = 0.176, fECPbRadThickness=0.144;
530 } else if(fECScintThick>0.191 && fECScintThick<0.193) { // 20% Pb thicknes reduction
531 fSampling = 8.93; // fECScintThick = 0.192, fECPbRadThickness=0.128;
537 //______________________________________________________________________
538 void AliEMCALGeometry::GetCellPhiEtaIndexInSModuleFromTRUIndex(const Int_t itru, const Int_t iphitru, const Int_t ietatru, Int_t &iphiSM, Int_t &ietaSM) const
541 // This method transforms the (eta,phi) index of cells in a
542 // TRU matrix into Super Module (eta,phi) index.
544 // Calculate in which row and column where the TRU are
547 Int_t col = itru/ fNTRUPhi ;
548 Int_t row = itru - col*fNTRUPhi ;
550 iphiSM = fNCellsInTRUPhi*row + iphitru ;
551 ietaSM = fNCellsInTRUEta*col + ietatru ;
554 //______________________________________________________________________
555 AliEMCALGeometry * AliEMCALGeometry::GetInstance(){
556 // Returns the pointer of the unique instance
558 AliEMCALGeometry * rv = static_cast<AliEMCALGeometry *>( fgGeom );
562 //______________________________________________________________________
563 AliEMCALGeometry* AliEMCALGeometry::GetInstance(const Text_t* name,
564 const Text_t* title){
565 // Returns the pointer of the unique instance
567 AliEMCALGeometry * rv = 0;
569 if ( strcmp(name,"") == 0 ) { // get default geometry
570 fgGeom = new AliEMCALGeometry(fgDefaultGeometryName, title);
572 fgGeom = new AliEMCALGeometry(name, title);
573 } // end if strcmp(name,"")
574 if ( fgInit ) rv = (AliEMCALGeometry * ) fgGeom;
581 if ( strcmp(fgGeom->GetName(), name) != 0) {
582 printf("\ncurrent geometry is %s : ", fgGeom->GetName());
583 printf(" you cannot call %s ",name);
585 rv = (AliEMCALGeometry *) fgGeom;
591 //_____________________________________________________________________________
592 Bool_t AliEMCALGeometry::IsInEMCAL(Double_t x, Double_t y, Double_t z) const {
593 // Checks whether point is inside the EMCal volume, used in AliEMCALv*.cxx
595 // Code uses cylindrical approximation made of inner radius (for speed)
597 // Points behind EMCAl, i.e. R > outer radius, but eta, phi in acceptance
598 // are considered to inside
600 Double_t r=sqrt(x*x+y*y);
602 if ( r > fEnvelop[0] ) {
604 theta = TMath::ATan2(r,z);
609 eta = -TMath::Log(TMath::Tan(theta/2.));
610 if (eta < fArm1EtaMin || eta > fArm1EtaMax)
613 Double_t phi = TMath::ATan2(y,x) * 180./TMath::Pi();
614 if (phi < 0) phi += 360; // phi should go from 0 to 360 in this case
615 if (phi > fArm1PhiMin && phi < fArm1PhiMax)
622 // == Shish-kebab cases ==
624 //________________________________________________________________________________________________
625 Int_t AliEMCALGeometry::GetAbsCellId(Int_t nSupMod, Int_t nModule, Int_t nIphi, Int_t nIeta) const
629 // 13-oct-05; 110 degree case
630 // May 31, 2006; ALICE numbering scheme:
631 // 0 <= nSupMod < fNumberOfSuperModules
632 // 0 <= nModule < fNPHI * fNZ ( fNPHI * fNZ/2 for fKey110DEG=1)
633 // 0 <= nIphi < fNPHIdiv
634 // 0 <= nIeta < fNETAdiv
635 // 0 <= absid < fNCells
636 static Int_t id=0; // have to change from 0 to fNCells-1
637 if(fKey110DEG == 1 && nSupMod >= 10) { // 110 degree case; last two supermodules
638 id = fNCellsInSupMod*10 + (fNCellsInSupMod/2)*(nSupMod-10);
640 id = fNCellsInSupMod*nSupMod;
642 id += fNCellsInModule *nModule;
643 id += fNPHIdiv *nIphi;
645 if(id<0 || id >= fNCells) {
646 // printf(" wrong numerations !!\n");
647 // printf(" id %6i(will be force to -1)\n", id);
648 // printf(" fNCells %6i\n", fNCells);
649 // printf(" nSupMod %6i\n", nSupMod);
650 // printf(" nModule %6i\n", nModule);
651 // printf(" nIphi %6i\n", nIphi);
652 // printf(" nIeta %6i\n", nIeta);
653 id = -TMath::Abs(id); // if negative something wrong
658 //________________________________________________________________________________________________
659 Bool_t AliEMCALGeometry::CheckAbsCellId(Int_t absId) const
661 // May 31, 2006; only trd1 now
662 if(absId<0 || absId >= fNCells) return kFALSE;
666 //________________________________________________________________________________________________
667 Bool_t AliEMCALGeometry::GetCellIndex(Int_t absId,Int_t &nSupMod,Int_t &nModule,Int_t &nIphi,Int_t &nIeta) const
669 // 21-sep-04; 19-oct-05;
670 // May 31, 2006; ALICE numbering scheme:
673 // absId - cell is as in Geant, 0<= absId < fNCells;
675 // nSupMod - super module(SM) number, 0<= nSupMod < fNumberOfSuperModules;
676 // nModule - module number in SM, 0<= nModule < fNCellsInSupMod/fNCellsInSupMod or(/2) for tow last SM (10th and 11th);
677 // nIphi - cell number in phi driection inside module; 0<= nIphi < fNPHIdiv;
678 // nIeta - cell number in eta driection inside module; 0<= nIeta < fNETAdiv;
680 static Int_t tmp=0, sm10=0;
681 if(!CheckAbsCellId(absId)) return kFALSE;
683 sm10 = fNCellsInSupMod*10;
684 if(fKey110DEG == 1 && absId >= sm10) { // 110 degree case; last two supermodules
685 nSupMod = (absId-sm10) / (fNCellsInSupMod/2) + 10;
686 tmp = (absId-sm10) % (fNCellsInSupMod/2);
688 nSupMod = absId / fNCellsInSupMod;
689 tmp = absId % fNCellsInSupMod;
692 nModule = tmp / fNCellsInModule;
693 tmp = tmp % fNCellsInModule;
694 nIphi = tmp / fNPHIdiv;
695 nIeta = tmp % fNPHIdiv;
700 //________________________________________________________________________________________________
701 void AliEMCALGeometry::GetModulePhiEtaIndexInSModule(Int_t nSupMod, Int_t nModule, int &iphim, int &ietam) const
703 // added nSupMod; - 19-oct-05 !
704 // Alice numbering scheme - Jun 01,2006
705 // ietam, iphi - indexes of module in two dimensional grid of SM
706 // ietam - have to change from 0 to fNZ-1
707 // iphim - have to change from 0 to nphi-1 (fNPhi-1 or fNPhi/2-1)
710 if(fKey110DEG == 1 && nSupMod>=10) nphi = fNPhi/2;
713 ietam = nModule/nphi;
714 iphim = nModule%nphi;
717 //________________________________________________________________________________________________
718 void AliEMCALGeometry::GetCellPhiEtaIndexInSModule(Int_t nSupMod, Int_t nModule, Int_t nIphi, Int_t nIeta,
719 int &iphi, int &ieta) const
722 // Added nSupMod; Nov 25, 05
723 // Alice numbering scheme - Jun 01,2006
725 // nSupMod - super module(SM) number, 0<= nSupMod < fNumberOfSuperModules;
726 // nModule - module number in SM, 0<= nModule < fNCellsInSupMod/fNCellsInSupMod or(/2) for tow last SM (10th and 11th);
727 // nIphi - cell number in phi driection inside module; 0<= nIphi < fNPHIdiv;
728 // nIeta - cell number in eta driection inside module; 0<= nIeta < fNETAdiv;
731 // ieta, iphi - indexes of cell(tower) in two dimensional grid of SM
732 // ieta - have to change from 0 to (fNZ*fNETAdiv-1)
733 // iphi - have to change from 0 to (fNPhi*fNPHIdiv-1 or fNPhi*fNPHIdiv/2-1)
735 static Int_t iphim, ietam;
737 GetModulePhiEtaIndexInSModule(nSupMod,nModule, iphim, ietam);
738 // ieta = ietam*fNETAdiv + (1-nIeta); // x(module) = -z(SM)
739 ieta = ietam*fNETAdiv + (fNETAdiv - 1 - nIeta); // x(module) = -z(SM)
740 iphi = iphim*fNPHIdiv + nIphi; // y(module) = y(SM)
743 AliDebug(1,Form(" nSupMod %i nModule %i nIphi %i nIeta %i => ieta %i iphi %i\n",
744 nSupMod, nModule, nIphi, nIeta, ieta, iphi));
747 //________________________________________________________________________________________________
748 Int_t AliEMCALGeometry::GetSuperModuleNumber(Int_t absId) const
750 // Return the number of the supermodule given the absolute
751 // ALICE numbering id
753 static Int_t nSupMod, nModule, nIphi, nIeta;
754 GetCellIndex(absId, nSupMod, nModule, nIphi, nIeta);
758 //________________________________________________________________________________________________
759 void AliEMCALGeometry::GetModuleIndexesFromCellIndexesInSModule(Int_t nSupMod, Int_t iphi, Int_t ieta,
760 Int_t &iphim, Int_t &ietam, Int_t &nModule) const
762 // Transition from cell indexes (ieta,iphi) to module indexes (ietam,iphim, nModule)
764 nphi = GetNumberOfModuleInPhiDirection(nSupMod);
766 ietam = ieta/fNETAdiv;
767 iphim = iphi/fNPHIdiv;
768 nModule = ietam * nphi + iphim;
771 //________________________________________________________________________________________________
772 Int_t AliEMCALGeometry::GetAbsCellIdFromCellIndexes(Int_t nSupMod, Int_t iphi, Int_t ieta) const
774 // Transition from super module number(nSupMod) and cell indexes (ieta,iphi) to absId
775 static Int_t ietam, iphim, nModule;
776 static Int_t nIeta, nIphi; // cell indexes in module
778 GetModuleIndexesFromCellIndexesInSModule(nSupMod, iphi, ieta, ietam, iphim, nModule);
780 nIeta = ieta%fNETAdiv;
781 nIeta = fNETAdiv - 1 - nIeta;
782 nIphi = iphi%fNPHIdiv;
784 return GetAbsCellId(nSupMod, nModule, nIphi, nIeta);
788 // Methods for AliEMCALRecPoint - Feb 19, 2006
789 //________________________________________________________________________________________________
790 Bool_t AliEMCALGeometry::RelPosCellInSModule(Int_t absId, Double_t &xr, Double_t &yr, Double_t &zr) const
792 // Look to see what the relative
793 // position inside a given cell is
795 // Alice numbering scheme - Jun 08, 2006
797 // absId - cell is as in Geant, 0<= absId < fNCells;
799 // xr,yr,zr - x,y,z coordinates of cell with absId inside SM
801 // Shift index taking into account the difference between standard SM
802 // and SM of half size in phi direction
803 const Int_t kphiIndexShift = fCentersOfCellsPhiDir.GetSize()/4; // Nov 22, 2006; was 6 for cas 2X2
804 static Int_t nSupMod, nModule, nIphi, nIeta, iphi, ieta;
805 if(!CheckAbsCellId(absId)) return kFALSE;
807 GetCellIndex(absId, nSupMod, nModule, nIphi, nIeta);
808 GetCellPhiEtaIndexInSModule(nSupMod,nModule,nIphi,nIeta, iphi, ieta);
810 xr = fCentersOfCellsXDir.At(ieta);
811 zr = fCentersOfCellsEtaDir.At(ieta);
814 yr = fCentersOfCellsPhiDir.At(iphi);
816 yr = fCentersOfCellsPhiDir.At(iphi + kphiIndexShift);
818 AliDebug(1,Form("absId %i nSupMod %i iphi %i ieta %i xr %f yr %f zr %f ",absId,nSupMod,iphi,ieta,xr,yr,zr));
823 //________________________________________________________________________________________________
824 Bool_t AliEMCALGeometry::RelPosCellInSModule(Int_t absId, Double_t loc[3]) const
826 // Alice numbering scheme - Jun 03, 2006
827 loc[0] = loc[1] = loc[2]=0.0;
828 if(RelPosCellInSModule(absId, loc[0],loc[1],loc[2])) {
834 //________________________________________________________________________________________________
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 //________________________________________________________________________________________________
849 Bool_t AliEMCALGeometry::RelPosCellInSModule(Int_t absId, Double_t distEff, Double_t &xr, Double_t &yr, Double_t &zr) const
851 // Jul 30, 2007 - taking into account position of shower max
852 // Look to see what the relative
853 // position inside a given cell is
856 // absId - cell is as in Geant, 0<= absId < fNCells;
857 // e - cluster energy
859 // xr,yr,zr - x,y,z coordinates of cell with absId inside SM
861 // Shift index taking into account the difference between standard SM
862 // and SM of half size in phi direction
863 const Int_t kphiIndexShift = fCentersOfCellsPhiDir.GetSize()/4; // Nov 22, 2006; was 6 for cas 2X2
864 static Int_t nSupMod, nModule, nIphi, nIeta, iphi, ieta;
865 static Int_t iphim, ietam;
866 static AliEMCALShishKebabTrd1Module *mod = 0;
868 if(!CheckAbsCellId(absId)) return kFALSE;
870 GetCellIndex(absId, nSupMod, nModule, nIphi, nIeta);
871 GetModulePhiEtaIndexInSModule(nSupMod, nModule, iphim, ietam);
872 GetCellPhiEtaIndexInSModule(nSupMod,nModule,nIphi,nIeta, iphi, ieta);
874 mod = GetShishKebabModule(ietam);
875 mod->GetPositionAtCenterCellLine(nIeta, distEff, v);
876 xr = v.Y() - fParSM[0];
877 zr = v.X() - fParSM[2];
880 yr = fCentersOfCellsPhiDir.At(iphi);
882 yr = fCentersOfCellsPhiDir.At(iphi + kphiIndexShift);
884 AliDebug(1,Form("absId %i nSupMod %i iphi %i ieta %i xr %f yr %f zr %f ",absId,nSupMod,iphi,ieta,xr,yr,zr));
889 //________________________________________________________________________________________________
890 Bool_t AliEMCALGeometry::RelPosCellInSModule(Int_t absId, Int_t maxAbsId, Double_t distEff, Double_t &xr, Double_t &yr, Double_t &zr) const
892 // Jul 31, 2007 - taking into account position of shower max and apply coor2.
893 // Look to see what the relative
894 // position inside a given cell is
897 // absId - cell is as in Geant, 0<= absId < fNCells;
898 // maxAbsId - abs id of cell with highest energy
899 // e - cluster energy
901 // xr,yr,zr - x,y,z coordinates of cell with absId inside SM
903 // Shift index taking into account the difference between standard SM
904 // and SM of half size in phi direction
905 const Int_t kphiIndexShift = fCentersOfCellsPhiDir.GetSize()/4; // Nov 22, 2006; was 6 for cas 2X2
906 static Int_t nSupMod, nModule, nIphi, nIeta, iphi, ieta;
907 static Int_t iphim, ietam;
908 static AliEMCALShishKebabTrd1Module *mod = 0;
911 static Int_t nSupModM, nModuleM, nIphiM, nIetaM, iphiM, ietaM;
912 static Int_t iphimM, ietamM, maxAbsIdCopy=-1;
913 static AliEMCALShishKebabTrd1Module *modM = 0;
914 static Double_t distCorr;
916 if(!CheckAbsCellId(absId)) return kFALSE;
918 GetCellIndex(absId, nSupMod, nModule, nIphi, nIeta);
919 GetModulePhiEtaIndexInSModule(nSupMod, nModule, iphim, ietam);
920 GetCellPhiEtaIndexInSModule(nSupMod,nModule,nIphi,nIeta, iphi, ieta);
921 mod = GetShishKebabModule(ietam);
923 if(absId != maxAbsId) {
925 if(maxAbsIdCopy != maxAbsId) {
926 GetCellIndex(maxAbsId, nSupModM, nModuleM, nIphiM, nIetaM);
927 GetModulePhiEtaIndexInSModule(nSupModM, nModuleM, iphimM, ietamM);
928 GetCellPhiEtaIndexInSModule(nSupModM,nModuleM,nIphiM,nIetaM, iphiM, ietaM);
929 modM = GetShishKebabModule(ietamM); // do I need this ?
930 maxAbsIdCopy = maxAbsId;
933 distCorr = GetEtaModuleSize()*(ietam-ietamM)/TMath::Tan(modM->GetTheta()); // Stay here
934 //printf(" distCorr %f | dist %f | ietam %i -> etamM %i\n", distCorr, dist, ietam, ietamM);
936 // distEff += distCorr;
938 // Bad resolution in this case, strong bias vs phi
940 mod->GetPositionAtCenterCellLine(nIeta, distEff, v); // Stay here
941 xr = v.Y() - fParSM[0];
942 zr = v.X() - fParSM[2];
945 yr = fCentersOfCellsPhiDir.At(iphi);
947 yr = fCentersOfCellsPhiDir.At(iphi + kphiIndexShift);
949 AliDebug(1,Form("absId %i nSupMod %i iphi %i ieta %i xr %f yr %f zr %f ",absId,nSupMod,iphi,ieta,xr,yr,zr));
954 //________________________________________________________________________________________________
955 void AliEMCALGeometry::CreateListOfTrd1Modules()
957 // Generate the list of Trd1 modules
958 // which will make up the EMCAL
961 AliDebug(2,Form(" AliEMCALGeometry::CreateListOfTrd1Modules() started "));
963 AliEMCALShishKebabTrd1Module *mod=0, *mTmp=0; // current module
964 if(fShishKebabTrd1Modules == 0) {
965 fShishKebabTrd1Modules = new TList;
966 fShishKebabTrd1Modules->SetName("ListOfTRD1");
967 for(int iz=0; iz< GetNZ(); iz++) {
969 mod = new AliEMCALShishKebabTrd1Module(TMath::Pi()/2.,this);
971 mTmp = new AliEMCALShishKebabTrd1Module(*mod);
974 fShishKebabTrd1Modules->Add(mod);
977 AliDebug(2,Form(" Already exits : "));
979 mod = (AliEMCALShishKebabTrd1Module*)fShishKebabTrd1Modules->At(fShishKebabTrd1Modules->GetSize()-1);
980 fEtaMaxOfTRD1 = mod->GetMaxEtaOfModule(0);
982 AliDebug(2,Form(" fShishKebabTrd1Modules has %i modules : max eta %5.4f \n",
983 fShishKebabTrd1Modules->GetSize(),fEtaMaxOfTRD1));
985 // Jun 01, 2006 - ALICE numbering scheme
986 // define grid for cells in eta(z) and x directions in local coordinates system of SM
987 // Works just for 2x2 case only -- ?? start here
990 // Define grid for cells in phi(y) direction in local coordinates system of SM
991 // as for 2X2 as for 3X3 - Nov 8,2006
993 AliDebug(2,Form(" Cells grid in phi directions : size %i\n", fCentersOfCellsPhiDir.GetSize()));
994 Int_t ind=0; // this is phi index
995 Int_t ieta=0, nModule=0, iphiTemp;
996 Double_t xr, zr, theta, phi, eta, r, x,y;
998 Double_t ytCenterModule=0.0, ytCenterCell=0.0;
1000 fCentersOfCellsPhiDir.Set(fNPhi*fNPHIdiv);
1001 fPhiCentersOfCells.Set(fNPhi*fNPHIdiv);
1003 Double_t r0 = GetIPDistance() + GetLongModuleSize()/2.;
1004 for(Int_t it=0; it<fNPhi; it++) { // cycle on modules
1005 ytCenterModule = -fParSM[1] + fPhiModuleSize*(2*it+1)/2; // center of module
1006 for(Int_t ic=0; ic<fNPHIdiv; ic++) { // cycle on cells in module
1008 ytCenterCell = ytCenterModule + fPhiTileSize *(2*ic-1)/2.;
1009 } else if(fNPHIdiv==3){
1010 ytCenterCell = ytCenterModule + fPhiTileSize *(ic-1);
1011 } else if(fNPHIdiv==1){
1012 ytCenterCell = ytCenterModule;
1014 fCentersOfCellsPhiDir.AddAt(ytCenterCell,ind);
1015 // Define grid on phi direction
1016 // Grid is not the same for different eta bin;
1017 // Effect is small but is still here
1018 phi = TMath::ATan2(ytCenterCell, r0);
1019 fPhiCentersOfCells.AddAt(phi, ind);
1021 AliDebug(2,Form(" ind %2.2i : y %8.3f ", ind, fCentersOfCellsPhiDir.At(ind)));
1026 fCentersOfCellsEtaDir.Set(fNZ *fNETAdiv);
1027 fCentersOfCellsXDir.Set(fNZ *fNETAdiv);
1028 fEtaCentersOfCells.Set(fNZ *fNETAdiv * fNPhi*fNPHIdiv);
1029 AliDebug(2,Form(" Cells grid in eta directions : size %i\n", fCentersOfCellsEtaDir.GetSize()));
1030 for(Int_t it=0; it<fNZ; it++) {
1031 AliEMCALShishKebabTrd1Module *trd1 = GetShishKebabModule(it);
1033 for(Int_t ic=0; ic<fNETAdiv; ic++) {
1035 trd1->GetCenterOfCellInLocalCoordinateofSM(ic, xr, zr); // case of 2X2
1036 GetCellPhiEtaIndexInSModule(0, nModule, 0, ic, iphiTemp, ieta);
1038 trd1->GetCenterOfCellInLocalCoordinateofSM_3X3(ic, xr, zr); // case of 3X3
1039 GetCellPhiEtaIndexInSModule(0, nModule, 0, ic, iphiTemp, ieta);
1041 trd1->GetCenterOfCellInLocalCoordinateofSM_1X1(xr, zr); // case of 1X1
1042 GetCellPhiEtaIndexInSModule(0, nModule, 0, ic, iphiTemp, ieta);
1044 fCentersOfCellsXDir.AddAt(float(xr) - fParSM[0],ieta);
1045 fCentersOfCellsEtaDir.AddAt(float(zr) - fParSM[2],ieta);
1046 // Define grid on eta direction for each bin in phi
1047 for(int iphi=0; iphi<fCentersOfCellsPhiDir.GetSize(); iphi++) {
1048 x = xr + trd1->GetRadius();
1049 y = fCentersOfCellsPhiDir[iphi];
1050 r = TMath::Sqrt(x*x + y*y + zr*zr);
1051 theta = TMath::ACos(zr/r);
1052 eta = AliEMCALShishKebabTrd1Module::ThetaToEta(theta);
1053 // ind = ieta*fCentersOfCellsPhiDir.GetSize() + iphi;
1054 ind = iphi*fCentersOfCellsEtaDir.GetSize() + ieta;
1055 fEtaCentersOfCells.AddAt(eta, ind);
1057 //printf(" ieta %i : xr + trd1->GetRadius() %f : zr %f : eta %f \n", ieta, xr + trd1->GetRadius(), zr, eta);
1060 for(Int_t i=0; i<fCentersOfCellsEtaDir.GetSize(); i++) {
1061 AliDebug(2,Form(" ind %2.2i : z %8.3f : x %8.3f", i+1,
1062 fCentersOfCellsEtaDir.At(i),fCentersOfCellsXDir.At(i)));
1067 //________________________________________________________________________________________________
1068 void AliEMCALGeometry::GetGlobal(const Double_t *loc, Double_t *glob, int ind) const
1070 // Figure out the global numbering
1071 // of a given supermodule from the
1072 // local numbering and the transformation
1073 // matrix stored by the geometry manager (allows for misaligned
1076 if(ind>=0 && ind < GetNumberOfSuperModules()) {
1077 TString volpath = "ALIC_1/XEN1_1/SMOD_";
1080 if(GetKey110DEG() && ind>=10) {
1081 volpath = "ALIC_1/XEN1_1/SM10_";
1082 volpath += ind-10+1;
1085 if(!gGeoManager->cd(volpath.Data()))
1086 AliFatal(Form("AliEMCALGeometry::GeoManager cannot find path %s!",volpath.Data()));
1088 TGeoHMatrix* m = gGeoManager->GetCurrentMatrix();
1090 m->LocalToMaster(loc, glob);
1092 AliFatal("Geo matrixes are not loaded \n") ;
1097 //________________________________________________________________________________________________
1098 void AliEMCALGeometry::GetGlobal(const TVector3 &vloc, TVector3 &vglob, int ind) const
1100 //Figure out the global numbering
1101 //of a given supermodule from the
1102 //local numbering given a 3-vector location
1104 static Double_t tglob[3], tloc[3];
1106 GetGlobal(tloc, tglob, ind);
1107 vglob.SetXYZ(tglob[0], tglob[1], tglob[2]);
1110 //________________________________________________________________________________________________
1111 void AliEMCALGeometry::GetGlobal(Int_t absId , double glob[3]) const
1113 // Alice numbering scheme - Jun 03, 2006
1114 static Int_t nSupMod, nModule, nIphi, nIeta;
1115 static double loc[3];
1117 if (!gGeoManager || !gGeoManager->IsClosed()) {
1118 AliError("Can't get the global coordinates! gGeoManager doesn't exist or it is still open!");
1122 glob[0]=glob[1]=glob[2]=0.0; // bad case
1123 if(RelPosCellInSModule(absId, loc)) {
1124 GetCellIndex(absId, nSupMod, nModule, nIphi, nIeta);
1126 TString volpath = "ALIC_1/XEN1_1/SMOD_";
1127 volpath += (nSupMod+1);
1129 if(GetKey110DEG() && nSupMod>=10) {
1130 volpath = "ALIC_1/XEN1_1/SM10_";
1131 volpath += (nSupMod-10+1);
1133 if(!gGeoManager->cd(volpath.Data()))
1134 AliFatal(Form("GeoManager cannot find path %s!",volpath.Data()));
1136 TGeoHMatrix* m = gGeoManager->GetCurrentMatrix();
1138 m->LocalToMaster(loc, glob);
1140 AliFatal("Geo matrixes are not loaded \n") ;
1145 //___________________________________________________________________
1146 void AliEMCALGeometry::GetGlobal(Int_t absId , TVector3 &vglob) const
1148 // Alice numbering scheme - Jun 03, 2006
1149 static Double_t glob[3];
1151 GetGlobal(absId, glob);
1152 vglob.SetXYZ(glob[0], glob[1], glob[2]);
1156 //____________________________________________________________________________
1157 void AliEMCALGeometry::GetGlobal(const AliRecPoint* /*rp*/, TVector3& /* vglob */) const
1159 AliFatal(Form("Please use GetGlobalEMCAL(recPoint,gpos) instead of GetGlobal!"));
1162 //_________________________________________________________________________________
1163 void AliEMCALGeometry::GetGlobalEMCAL(const AliEMCALRecPoint *rp, TVector3 &vglob) const
1165 // Figure out the global numbering
1166 // of a given supermodule from the
1167 // local numbering for RecPoints
1169 static TVector3 vloc;
1170 static Int_t nSupMod, nModule, nIphi, nIeta;
1172 const AliEMCALRecPoint *rpTmp = rp;
1173 const AliEMCALRecPoint *rpEmc = rpTmp;
1175 GetCellIndex(rpEmc->GetAbsId(0), nSupMod, nModule, nIphi, nIeta);
1176 rpTmp->GetLocalPosition(vloc);
1177 GetGlobal(vloc, vglob, nSupMod);
1180 //________________________________________________________________________________________________
1181 void AliEMCALGeometry::EtaPhiFromIndex(Int_t absId,Double_t &eta,Double_t &phi) const
1183 // Nov 16, 2006- float to double
1184 // version for TRD1 only
1185 static TVector3 vglob;
1186 GetGlobal(absId, vglob);
1191 //________________________________________________________________________________________________
1192 void AliEMCALGeometry::EtaPhiFromIndex(Int_t absId,Float_t &eta,Float_t &phi) const
1194 // Nov 16,2006 - should be discard in future
1195 static TVector3 vglob;
1196 GetGlobal(absId, vglob);
1197 eta = float(vglob.Eta());
1198 phi = float(vglob.Phi());
1201 //________________________________________________________________________________________________
1202 Bool_t AliEMCALGeometry::GetPhiBoundariesOfSM(Int_t nSupMod, Double_t &phiMin, Double_t &phiMax) const
1204 // 0<= nSupMod <=11; phi in rad
1206 if(nSupMod<0 || nSupMod >11) return kFALSE;
1208 phiMin = fPhiBoundariesOfSM[2*i];
1209 phiMax = fPhiBoundariesOfSM[2*i+1];
1213 //________________________________________________________________________________________________
1214 Bool_t AliEMCALGeometry::GetPhiBoundariesOfSMGap(Int_t nPhiSec, Double_t &phiMin, Double_t &phiMax) const
1216 // 0<= nPhiSec <=4; phi in rad
1217 // 0; gap boundaries between 0th&2th | 1th&3th SM
1218 // 1; gap boundaries between 2th&4th | 3th&5th SM
1219 // 2; gap boundaries between 4th&6th | 5th&7th SM
1220 // 3; gap boundaries between 6th&8th | 7th&9th SM
1221 // 4; gap boundaries between 8th&10th | 9th&11th SM
1222 if(nPhiSec<0 || nPhiSec >4) return kFALSE;
1223 phiMin = fPhiBoundariesOfSM[2*nPhiSec+1];
1224 phiMax = fPhiBoundariesOfSM[2*nPhiSec+2];
1228 //________________________________________________________________________________________________
1229 Bool_t AliEMCALGeometry::SuperModuleNumberFromEtaPhi(Double_t eta, Double_t phi, Int_t &nSupMod) const
1231 // Return false if phi belongs a phi cracks between SM
1235 if(TMath::Abs(eta) > fEtaMaxOfTRD1) return kFALSE;
1237 phi = TVector2::Phi_0_2pi(phi); // move phi to (0,2pi) boundaries
1238 for(i=0; i<6; i++) {
1239 if(phi>=fPhiBoundariesOfSM[2*i] && phi<=fPhiBoundariesOfSM[2*i+1]) {
1241 if(eta < 0.0) nSupMod++;
1242 AliDebug(1,Form("eta %f phi %f(%5.2f) : nSupMod %i : #bound %i", eta,phi,phi*TMath::RadToDeg(), nSupMod,i));
1249 //________________________________________________________________________________________________
1250 Bool_t AliEMCALGeometry::GetAbsCellIdFromEtaPhi(Double_t eta, Double_t phi, Int_t &absId) const
1253 // stay here - phi problem as usual
1254 static Int_t nSupMod, i, ieta, iphi, etaShift, nphi;
1255 static Double_t absEta=0.0, d=0.0, dmin=0.0, phiLoc;
1256 absId = nSupMod = - 1;
1257 if(SuperModuleNumberFromEtaPhi(eta, phi, nSupMod)) {
1259 phi = TVector2::Phi_0_2pi(phi);
1260 phiLoc = phi - fPhiCentersOfSM[nSupMod/2];
1261 nphi = fPhiCentersOfCells.GetSize();
1263 phiLoc = phi - 190.*TMath::DegToRad();
1267 dmin = TMath::Abs(fPhiCentersOfCells[0]-phiLoc);
1269 for(i=1; i<nphi; i++) {
1270 d = TMath::Abs(fPhiCentersOfCells[i] - phiLoc);
1275 // printf(" i %i : d %f : dmin %f : fPhiCentersOfCells[i] %f \n", i, d, dmin, fPhiCentersOfCells[i]);
1277 // odd SM are turned with respect of even SM - reverse indexes
1278 AliDebug(2,Form(" iphi %i : dmin %f (phi %f, phiLoc %f ) ", iphi, dmin, phi, phiLoc));
1280 absEta = TMath::Abs(eta);
1281 etaShift = iphi*fCentersOfCellsEtaDir.GetSize();
1282 dmin = TMath::Abs(fEtaCentersOfCells[etaShift]-absEta);
1284 for(i=1; i<fCentersOfCellsEtaDir.GetSize(); i++) {
1285 d = TMath::Abs(fEtaCentersOfCells[i+etaShift] - absEta);
1291 AliDebug(2,Form(" ieta %i : dmin %f (eta=%f) : nSupMod %i ", ieta, dmin, eta, nSupMod));
1293 if(eta<0) iphi = (nphi-1) - iphi;
1294 absId = GetAbsCellIdFromCellIndexes(nSupMod, iphi, ieta);
1301 //________________________________________________________________________________________________
1302 AliEMCALShishKebabTrd1Module* AliEMCALGeometry::GetShishKebabModule(Int_t neta) const
1304 //This method was too long to be
1305 //included in the header file - the
1306 //rule checker complained about it's
1307 //length, so we move it here. It returns the
1308 //shishkebabmodule at a given eta index point.
1310 static AliEMCALShishKebabTrd1Module* trd1=0;
1311 if(fShishKebabTrd1Modules && neta>=0 && neta<fShishKebabTrd1Modules->GetSize()) {
1312 trd1 = (AliEMCALShishKebabTrd1Module*)fShishKebabTrd1Modules->At(neta);
1317 //________________________________________________________________________________________________
1318 void AliEMCALGeometry::Browse(TBrowser* b)
1320 //Browse the modules
1321 if(fShishKebabTrd1Modules) b->Add(fShishKebabTrd1Modules);
1324 //________________________________________________________________________________________________
1325 Bool_t AliEMCALGeometry::IsFolder() const
1327 //Check if fShishKebabTrd1Modules is in folder
1328 if(fShishKebabTrd1Modules) return kTRUE;
1332 //________________________________________________________________________________________________
1333 Double_t AliEMCALGeometry::GetPhiCenterOfSM(Int_t nsupmod) const
1335 //returns center of supermodule in phi
1337 return fPhiCentersOfSM[i];