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),
110 fNModulesInTRUEta(0),
111 fNModulesInTRUPhi(0),
114 fTrd1Angle(0.),f2Trd1Dx2(0.),
115 fPhiGapForSM(0.),fKey110DEG(0),fPhiBoundariesOfSM(0), fPhiCentersOfSM(0),fEtaMaxOfTRD1(0),
116 fCentersOfCellsEtaDir(0), fCentersOfCellsXDir(0),fCentersOfCellsPhiDir(0),
117 fEtaCentersOfCells(0),fPhiCentersOfCells(0),fShishKebabTrd1Modules(0),
118 fILOSS(-1), fIHADR(-1),
119 //obsolete member data
120 fAlFrontThick(0.), fGap2Active(0.), fSteelFrontThick(0.), fTrd2AngleY(0.),
121 f2Trd2Dy2(0.), fEmptySpace(0.), fTubsR(0.), fTubsTurnAngle(0.)
123 // default ctor only for internal usage (singleton)
124 // must be kept public for root persistency purposes,
125 // but should never be called by the outside world
127 AliDebug(2, "AliEMCALGeometry : default ctor ");
129 //______________________________________________________________________
130 AliEMCALGeometry::AliEMCALGeometry(const Text_t* name, const Text_t* title)
131 : AliGeometry(name, title),
132 fGeoName(0),fArrayOpts(0),fNAdditionalOpts(0),fECPbRadThickness(0.),fECScintThick(0.),
133 fNECLayers(0),fArm1PhiMin(0.),fArm1PhiMax(0.),fArm1EtaMin(0.),fArm1EtaMax(0.),fIPDistance(0.),
134 fShellThickness(0.),fZLength(0.),fNZ(0),fNPhi(0),fSampling(0.),fNumberOfSuperModules(0),
135 fFrontSteelStrip(0.),fLateralSteelStrip(0.),fPassiveScintThick(0.),fPhiModuleSize(0.),
136 fEtaModuleSize(0.),fPhiTileSize(0.),fEtaTileSize(0.),fLongModuleSize(0.),fNPhiSuperModule(0),
137 fNPHIdiv(0),fNETAdiv(0), fNCells(0),fNCellsInSupMod(0),fNCellsInModule(0),
141 fNModulesInTRUEta(0),
142 fNModulesInTRUPhi(0),
145 fTrd1Angle(0.),f2Trd1Dx2(0.),
146 fPhiGapForSM(0.),fKey110DEG(0),fPhiBoundariesOfSM(0), fPhiCentersOfSM(0), fEtaMaxOfTRD1(0),
147 fCentersOfCellsEtaDir(0),fCentersOfCellsXDir(0),fCentersOfCellsPhiDir(0),
148 fEtaCentersOfCells(0),fPhiCentersOfCells(0),fShishKebabTrd1Modules(0),
149 fILOSS(-1), fIHADR(-1),
150 //obsolete member data
151 fAlFrontThick(0.), fGap2Active(0.), fSteelFrontThick(0.), fTrd2AngleY(0.),
152 f2Trd2Dy2(0.), fEmptySpace(0.), fTubsR(0.), fTubsTurnAngle(0.)
154 // ctor only for internal usage (singleton)
155 AliDebug(2, Form("AliEMCALGeometry(%s,%s) ", name,title));
159 CreateListOfTrd1Modules();
161 if (AliDebugLevel()>=2) {
166 //______________________________________________________________________
167 AliEMCALGeometry::AliEMCALGeometry(const AliEMCALGeometry& geom)
169 fGeoName(geom.fGeoName),
170 fArrayOpts(geom.fArrayOpts),
171 fNAdditionalOpts(geom.fNAdditionalOpts),
172 fECPbRadThickness(geom.fECPbRadThickness),
173 fECScintThick(geom.fECScintThick),
174 fNECLayers(geom.fNECLayers),
175 fArm1PhiMin(geom.fArm1PhiMin),
176 fArm1PhiMax(geom.fArm1PhiMax),
177 fArm1EtaMin(geom.fArm1EtaMin),
178 fArm1EtaMax(geom.fArm1EtaMax),
179 fIPDistance(geom.fIPDistance),
180 fShellThickness(geom.fShellThickness),
181 fZLength(geom.fZLength),
184 fSampling(geom.fSampling),
185 fNumberOfSuperModules(geom.fNumberOfSuperModules),
186 fFrontSteelStrip(geom.fFrontSteelStrip),
187 fLateralSteelStrip(geom.fLateralSteelStrip),
188 fPassiveScintThick(geom.fPassiveScintThick),
189 fPhiModuleSize(geom.fPhiModuleSize),
190 fEtaModuleSize(geom.fEtaModuleSize),
191 fPhiTileSize(geom.fPhiTileSize),
192 fEtaTileSize(geom.fEtaTileSize),
193 fLongModuleSize(geom.fLongModuleSize),
194 fNPhiSuperModule(geom.fNPhiSuperModule),
195 fNPHIdiv(geom.fNPHIdiv),
196 fNETAdiv(geom.fNETAdiv),
197 fNCells(geom.fNCells),
198 fNCellsInSupMod(geom.fNCellsInSupMod),
199 fNCellsInModule(geom.fNCellsInModule),
201 fNTRUEta(geom.fNTRUEta),
202 fNTRUPhi(geom.fNTRUPhi),
203 fNModulesInTRUEta(geom.fNModulesInTRUEta),
204 fNModulesInTRUPhi(geom.fNModulesInTRUPhi),
205 fNEtaSubOfTRU(geom.fNEtaSubOfTRU),
207 fTrd1Angle(geom.fTrd1Angle),
208 f2Trd1Dx2(geom.f2Trd1Dx2),
209 fPhiGapForSM(geom.fPhiGapForSM),
210 fKey110DEG(geom.fKey110DEG),
211 fPhiBoundariesOfSM(geom.fPhiBoundariesOfSM),
212 fPhiCentersOfSM(geom.fPhiCentersOfSM),
213 fEtaMaxOfTRD1(geom.fEtaMaxOfTRD1),
214 fCentersOfCellsEtaDir(geom.fCentersOfCellsEtaDir),
215 fCentersOfCellsXDir(geom.fCentersOfCellsXDir),
216 fCentersOfCellsPhiDir(geom.fCentersOfCellsPhiDir),
217 fEtaCentersOfCells(geom.fEtaCentersOfCells),
218 fPhiCentersOfCells(geom.fPhiCentersOfCells),
219 fShishKebabTrd1Modules(geom.fShishKebabTrd1Modules),
220 fILOSS(geom.fILOSS), fIHADR(geom.fIHADR),
221 //obsolete member data
222 fAlFrontThick(geom.fAlFrontThick),
223 fGap2Active(geom.fGap2Active),
224 fSteelFrontThick(geom.fSteelFrontThick),
225 fTrd2AngleY(geom.fTrd2AngleY),
226 f2Trd2Dy2(geom.f2Trd2Dy2),
227 fEmptySpace(geom.fEmptySpace),
229 fTubsTurnAngle(geom.fTubsTurnAngle)
234 //______________________________________________________________________
235 AliEMCALGeometry::~AliEMCALGeometry(void){
239 //______________________________________________________________________
240 void AliEMCALGeometry::Init(void){
242 // Initializes the EMCAL parameters based on the name
243 // Only Shashlyk geometry is available, but various combinations of
244 // layers and number of supermodules can be selected with additional
245 // options or geometry name
248 fAdditionalOpts[0] = "nl="; // number of sampling layers (fNECLayers)
249 fAdditionalOpts[1] = "pbTh="; // cm, Thickness of the Pb (fECPbRadThick)
250 fAdditionalOpts[2] = "scTh="; // cm, Thickness of the Sc (fECScintThick)
251 fAdditionalOpts[3] = "latSS="; // cm, Thickness of lateral steel strip (fLateralSteelStrip)
252 fAdditionalOpts[4] = "allILOSS="; // = 0,1,2,3,4 (4 - energy loss without fluctuation)
253 fAdditionalOpts[5] = "allIHADR="; // = 0,1,2 (0 - no hadronic interaction)
255 fNAdditionalOpts = sizeof(fAdditionalOpts) / sizeof(char*);
258 fgInit = kFALSE; // Assume failed until proven otherwise.
259 fGeoName = GetName();
262 //Convert old geometry names to new ones
263 if(fGeoName.Contains("SHISH_77_TRD1_2X2_FINAL_110DEG")) {
264 if(fGeoName.Contains("PBTH=0.144") && fGeoName.Contains("SCTH=0.176")) {
265 fGeoName = "EMCAL_COMPLETE";
267 fGeoName = "EMCAL_PDC06";
270 if(fGeoName.Contains("WSUC")) fGeoName = "EMCAL_WSUC";
272 //check that we have a valid geometry name
273 if(!(fGeoName.Contains("EMCAL_PDC06") || fGeoName.Contains("EMCAL_COMPLETE") || fGeoName.Contains("EMCAL_WSUC"))) {
274 Fatal("Init", "%s is an undefined geometry!", fGeoName.Data()) ;
277 // Option to know whether we have the "half" supermodule(s) or not
279 if(fGeoName.Contains("COMPLETE") || fGeoName.Contains("PDC06")) fKey110DEG = 1; // for GetAbsCellId
280 fShishKebabTrd1Modules = 0;
283 //default parameters are those of EMCAL_COMPLETE geometry
284 //all others render variations from these at the end of
285 //geometry-name specific options
287 fNumberOfSuperModules = 12; // 12 = 6 * 2 (6 in phi, 2 in Z)
288 fNPhi = 12; // module granularity in phi within smod (azimuth)
289 fNZ = 24; // module granularity along Z within smod (eta)
290 fNPHIdiv = fNETAdiv = 2; // tower granularity within module
291 fArm1PhiMin = 80.0; // degrees, Starting EMCAL Phi position
292 fArm1PhiMax = 200.0; // degrees, Ending EMCAL Phi position
293 fArm1EtaMin = -0.7; // pseudorapidity, Starting EMCAL Eta position
294 fArm1EtaMax = +0.7; // pseudorapidity, Ending EMCAL Eta position
295 fIPDistance = 428.0; // cm, radial distance to front face from nominal vertex point
296 fPhiGapForSM = 2.; // cm, only for final TRD1 geometry
297 fFrontSteelStrip = 0.025; // 0.025cm = 0.25mm (13-may-05 from V.Petrov)
298 fPassiveScintThick = 0.8; // 0.8cm = 8mm (13-may-05 from V.Petrov)
299 fLateralSteelStrip = 0.01; // 0.01cm = 0.1mm (13-may-05 from V.Petrov) - was 0.025
300 fTrd1Angle = 1.5; // in degrees
302 fSampling = 1.; // should be calculated with call to DefineSamplingFraction()
303 fNECLayers = 77; // (13-may-05 from V.Petrov) - can be changed with additional options
304 fECScintThick = 0.176; // scintillator layer thickness
305 fECPbRadThickness = 0.144; // lead layer thickness
307 fPhiModuleSize = 12.26 - fPhiGapForSM / Float_t(fNPhi); // first assumption
308 fEtaModuleSize = fPhiModuleSize;
310 //needs to be called for each geometry and before setting geometry
311 //parameters which can depend on the outcome
312 CheckAdditionalOptions();
314 //modifications to the above for PDC06 geometry
315 if(fGeoName.Contains("PDC06")){ // 18-may-05 - about common structure
316 fECScintThick = fECPbRadThickness = 0.16;// (13-may-05 from V.Petrov)
317 CheckAdditionalOptions();
320 //modifications to the above for WSUC geometry
321 if(fGeoName.Contains("WSUC")){ // 18-may-05 - about common structure
322 fPhiModuleSize = 12.5; // 20-may-05 - rectangular shape
323 fEtaModuleSize = 11.9;
324 fECScintThick = fECPbRadThickness = 0.16;// (13-may-05 from V.Petrov)
325 fNumberOfSuperModules = 1; // 27-may-05
326 fShellThickness = 30.; // should be change
328 CheckAdditionalOptions();
331 // constant for transition absid <--> indexes
332 fNCellsInModule = fNPHIdiv*fNETAdiv;
333 fNCellsInSupMod = fNCellsInModule*fNPhi*fNZ;
334 fNCells = fNCellsInSupMod*fNumberOfSuperModules;
335 if(GetKey110DEG()) fNCells -= fNCellsInSupMod;
337 fNPhiSuperModule = fNumberOfSuperModules/2;
338 if(fNPhiSuperModule<1) fNPhiSuperModule = 1;
340 fPhiTileSize = fPhiModuleSize/double(fNPHIdiv) - fLateralSteelStrip; // 13-may-05
341 fEtaTileSize = fEtaModuleSize/double(fNETAdiv) - fLateralSteelStrip; // 13-may-05
343 fLongModuleSize = fNECLayers*(fECScintThick + fECPbRadThickness);
344 f2Trd1Dx2 = fEtaModuleSize + 2.*fLongModuleSize*TMath::Tan(fTrd1Angle*TMath::DegToRad()/2.);
345 if(!fGeoName.Contains("WSUC")) fShellThickness = TMath::Sqrt(fLongModuleSize*fLongModuleSize + f2Trd1Dx2*f2Trd1Dx2);
347 fZLength = 2.*ZFromEtaR(fIPDistance+fShellThickness,fArm1EtaMax); // Z coverage
348 fEnvelop[0] = fIPDistance; // mother volume inner radius
349 fEnvelop[1] = fIPDistance + fShellThickness; // mother volume outer r.
350 fEnvelop[2] = 1.00001*fZLength; // add some padding for mother volume.
353 fParSM[0] = GetShellThickness()/2.;
354 fParSM[1] = GetPhiModuleSize() * GetNPhi()/2.;
357 // SM phi boundaries - (0,1),(2,3) .. (10,11) - has the same boundaries; Nov 7, 2006
358 fPhiBoundariesOfSM.Set(fNumberOfSuperModules);
359 fPhiCentersOfSM.Set(fNumberOfSuperModules/2);
360 fPhiBoundariesOfSM[0] = TMath::PiOver2() - TMath::ATan2(fParSM[1] , fIPDistance); // 1th and 2th modules)
361 fPhiCentersOfSM[0] = TMath::PiOver2();
362 if(fNumberOfSuperModules > 1)
363 fPhiBoundariesOfSM[1] = TMath::PiOver2() + TMath::ATan2(fParSM[1] , fIPDistance);
364 if(fNumberOfSuperModules > 2) {
365 for(int i=1; i<=4; i++) { // from 2th ro 9th
366 fPhiBoundariesOfSM[2*i] = fPhiBoundariesOfSM[0] + 20.*TMath::DegToRad()*i;
367 fPhiBoundariesOfSM[2*i+1] = fPhiBoundariesOfSM[1] + 20.*TMath::DegToRad()*i;
368 fPhiCentersOfSM[i] = fPhiCentersOfSM[0] + 20.*TMath::DegToRad()*i;
371 if(fNumberOfSuperModules > 10) {
372 fPhiBoundariesOfSM[11] = 190.*TMath::DegToRad();
373 fPhiBoundariesOfSM[10] = fPhiBoundariesOfSM[11] - TMath::ATan2((fParSM[1]) , fIPDistance);
374 fPhiCentersOfSM[5] = (fPhiBoundariesOfSM[10]+fPhiBoundariesOfSM[11])/2.;
377 //called after setting of scintillator and lead layer parameters
378 DefineSamplingFraction();
380 // TRU parameters - Apr 29,08 by PAI.
381 // These parameters values was updated at Nov 05, 2007
382 // As is on Olivier BOURRION (LPSC) ppt preasentation
383 // at ALICE trigger meeting at 13th-14th March
384 fNTRUEta = 1; // was 3
385 fNTRUPhi = 3; // was 1
386 fNModulesInTRUEta = 24; // was 8
387 fNModulesInTRUPhi = 4; // was 12
389 // 3*6*10 + 2*6*2 = 204 -> matrix (nphi(17), neta(12))
395 void AliEMCALGeometry::PrintGeometry()
397 // Separate routine is callable from broswer; Nov 7,2006
398 printf("\nInit: geometry of EMCAL named %s :\n", fGeoName.Data());
400 for(Int_t i=0; i<fArrayOpts->GetEntries(); i++){
401 TObjString *o = (TObjString*)fArrayOpts->At(i);
402 printf(" %i : %s \n", i, o->String().Data());
405 printf("Granularity: %d in eta and %d in phi\n", GetNZ(), GetNPhi()) ;
406 printf("Layout: phi = (%7.1f, %7.1f), eta = (%5.2f, %5.2f), IP = %7.2f -> for EMCAL envelope only\n",
407 GetArm1PhiMin(), GetArm1PhiMax(),GetArm1EtaMin(), GetArm1EtaMax(), GetIPDistance() );
409 printf( " ECAL : %d x (%f cm Pb, %f cm Sc) \n",
410 GetNECLayers(), GetECPbRadThick(), GetECScintThick() ) ;
411 printf(" fSampling %5.2f \n", fSampling );
412 printf(" fIPDistance %6.3f cm \n", fIPDistance);
413 printf(" fNPhi %i | fNZ %i \n", fNPhi, fNZ);
414 printf(" fNCellsInModule %i : fNCellsInSupMod %i : fNCells %i\n",fNCellsInModule, fNCellsInSupMod, fNCells);
415 printf(" X:Y module size %6.3f , %6.3f cm \n", fPhiModuleSize, fEtaModuleSize);
416 printf(" X:Y tile size %6.3f , %6.3f cm \n", fPhiTileSize, fEtaTileSize);
417 printf(" #of sampling layers %i(fNECLayers) \n", fNECLayers);
418 printf(" fLongModuleSize %6.3f cm \n", fLongModuleSize);
419 printf(" #supermodule in phi direction %i \n", fNPhiSuperModule );
420 printf(" fILOSS %i : fIHADR %i \n", fILOSS, fIHADR);
421 printf(" fTrd1Angle %7.4f\n", fTrd1Angle);
422 printf(" f2Trd1Dx2 %7.4f\n", f2Trd1Dx2);
423 printf("SM dimensions(TRD1) : dx %7.2f dy %7.2f dz %7.2f (SMOD, BOX)\n",
424 fParSM[0],fParSM[1],fParSM[2]);
425 printf(" fPhiGapForSM %7.4f cm (%7.4f <- phi size in degree)\n",
426 fPhiGapForSM, TMath::ATan2(fPhiGapForSM,fIPDistance)*TMath::RadToDeg());
427 if(GetKey110DEG()) printf(" Last two modules have size 10 degree in phi (180<phi<190)\n");
428 printf(" phi SM boundaries \n");
429 for(int i=0; i<fPhiBoundariesOfSM.GetSize()/2.; i++) {
430 printf(" %i : %7.5f(%7.2f) -> %7.5f(%7.2f) : center %7.5f(%7.2f) \n", i,
431 fPhiBoundariesOfSM[2*i], fPhiBoundariesOfSM[2*i]*TMath::RadToDeg(),
432 fPhiBoundariesOfSM[2*i+1], fPhiBoundariesOfSM[2*i+1]*TMath::RadToDeg(),
433 fPhiCentersOfSM[i], fPhiCentersOfSM[i]*TMath::RadToDeg());
435 printf(" fShishKebabTrd1Modules has %i modules : max eta %5.4f \n",
436 fShishKebabTrd1Modules->GetSize(),fEtaMaxOfTRD1);
438 printf("\n Cells grid in eta directions : size %i\n", fCentersOfCellsEtaDir.GetSize());
439 for(Int_t i=0; i<fCentersOfCellsEtaDir.GetSize(); i++) {
440 printf(" ind %2.2i : z %8.3f : x %8.3f \n", i,
441 fCentersOfCellsEtaDir.At(i),fCentersOfCellsXDir.At(i));
442 int ind=0; // Nov 21,2006
443 for(Int_t iphi=0; iphi<fCentersOfCellsPhiDir.GetSize(); iphi++) {
444 ind = iphi*fCentersOfCellsEtaDir.GetSize() + i;
445 printf("%6.4f ", fEtaCentersOfCells[ind]);
446 if((iphi+1)%12 == 0) printf("\n");
452 printf("\n Cells grid in phi directions : size %i\n", fCentersOfCellsPhiDir.GetSize());
453 for(Int_t i=0; i<fCentersOfCellsPhiDir.GetSize(); i++) {
454 double phi=fPhiCentersOfCells.At(i);
455 printf(" ind %2.2i : y %8.3f : phi %7.5f(%6.2f) \n", i, fCentersOfCellsPhiDir.At(i),
456 phi, phi*TMath::RadToDeg());
461 //______________________________________________________________________
462 void AliEMCALGeometry::PrintCellIndexes(Int_t absId, int pri, char *tit)
465 Int_t nSupMod, nModule, nIphi, nIeta;
469 GetCellIndex(absId, nSupMod, nModule, nIphi, nIeta);
470 printf(" %s | absId : %i -> nSupMod %i nModule %i nIphi %i nIeta %i \n", tit, absId, nSupMod, nModule, nIphi, nIeta);
472 GetCellPhiEtaIndexInSModule(nSupMod,nModule,nIphi,nIeta, iphi,ieta);
473 printf(" local SM index : iphi %i : ieta %i \n", iphi,ieta);
474 GetGlobal(absId, vg);
475 printf(" vglob : mag %7.2f : perp %7.2f : z %7.2f : eta %6.4f : phi %6.4f(%6.2f) \n",
476 vg.Mag(), vg.Perp(), vg.Z(), vg.Eta(), vg.Phi(), vg.Phi()*TMath::RadToDeg());
480 //______________________________________________________________________
481 void AliEMCALGeometry::CheckAdditionalOptions()
484 // Additional options that
485 // can be used to select
486 // the specific geometry of
489 // adeed allILOSS= and allIHADR= for MIP investigation
490 fArrayOpts = new TObjArray;
491 Int_t nopt = AliEMCALHistoUtilities::ParseString(fGeoName, *fArrayOpts);
492 if(nopt==1) { // no aditional option(s)
493 fArrayOpts->Delete();
498 for(Int_t i=1; i<nopt; i++){
499 TObjString *o = (TObjString*)fArrayOpts->At(i);
501 TString addOpt = o->String();
503 for(Int_t j=0; j<fNAdditionalOpts; j++) {
504 TString opt = fAdditionalOpts[j];
505 if(addOpt.Contains(opt,TString::kIgnoreCase)) {
511 AliDebug(2,Form("<E> option |%s| unavailable : ** look to the file AliEMCALGeometry.h **\n",
515 AliDebug(2,Form("<I> option |%s| is valid : number %i : |%s|\n",
516 addOpt.Data(), indj, fAdditionalOpts[indj]));
517 if (addOpt.Contains("NL=",TString::kIgnoreCase)) {// number of sampling layers
518 sscanf(addOpt.Data(),"NL=%i", &fNECLayers);
519 AliDebug(2,Form(" fNECLayers %i (new) \n", fNECLayers));
520 } else if(addOpt.Contains("PBTH=",TString::kIgnoreCase)) {//Thickness of the Pb(fECPbRadThicknes)
521 sscanf(addOpt.Data(),"PBTH=%f", &fECPbRadThickness);
522 } else if(addOpt.Contains("SCTH=",TString::kIgnoreCase)) {//Thickness of the Sc(fECScintThick)
523 sscanf(addOpt.Data(),"SCTH=%f", &fECScintThick);
524 } else if(addOpt.Contains("LATSS=",TString::kIgnoreCase)) {// Thickness of lateral steel strip (fLateralSteelStrip)
525 sscanf(addOpt.Data(),"LATSS=%f", &fLateralSteelStrip);
526 AliDebug(2,Form(" fLateralSteelStrip %f (new) \n", fLateralSteelStrip));
527 } else if(addOpt.Contains("ILOSS=",TString::kIgnoreCase)) {// As in Geant
528 sscanf(addOpt.Data(),"ALLILOSS=%i", &fILOSS);
529 AliDebug(2,Form(" fILOSS %i \n", fILOSS));
530 } else if(addOpt.Contains("IHADR=",TString::kIgnoreCase)) {// As in Geant
531 sscanf(addOpt.Data(),"ALLIHADR=%i", &fIHADR);
532 AliDebug(2,Form(" fIHADR %i \n", fIHADR));
538 void AliEMCALGeometry::DefineSamplingFraction()
541 // Look http://rhic.physics.wayne.edu/~pavlinov/ALICE/SHISHKEBAB/RES/linearityAndResolutionForTRD1.html
542 // Keep for compatibilty
544 if(fNECLayers == 69) { // 10% layer reduction
546 } else if(fNECLayers == 61) { // 20% layer reduction
548 } else if(fNECLayers == 77) {
549 if (fECScintThick>0.159 && fECScintThick<0.161) { // original sampling fraction, equal layers
550 fSampling = 12.327; // fECScintThick = fECPbRadThickness = 0.160;
551 } else if (fECScintThick>0.175 && fECScintThick<0.177) { // 10% Pb thicknes reduction
552 fSampling = 10.5; // fECScintThick = 0.176, fECPbRadThickness=0.144;
553 } else if(fECScintThick>0.191 && fECScintThick<0.193) { // 20% Pb thicknes reduction
554 fSampling = 8.93; // fECScintThick = 0.192, fECPbRadThickness=0.128;
560 //______________________________________________________________________
561 void AliEMCALGeometry::GetModulePhiEtaIndexInSModuleFromTRUIndex(const Int_t itru, const Int_t iphitru, const Int_t ietatru, Int_t &iphiSM, Int_t &ietaSM) const
564 // This method transforms the (eta,phi) index of module in a
565 // TRU matrix into Super Module (eta,phi) index.
567 // Calculate in which row and column where the TRU are
570 Int_t col = itru/ fNTRUPhi ; // indexes of TRU in SM
571 Int_t row = itru - col*fNTRUPhi ;
573 iphiSM = fNModulesInTRUPhi*row + iphitru ;
574 ietaSM = fNModulesInTRUEta*col + ietatru ;
575 //printf(" GetModulePhiEtaIndexInSModuleFromTRUIndex : itru %2i iphitru %2i ietatru %2i iphiSM %2i ietaSM %2i \n",
576 // itru, iphitru, ietatru, iphiSM, ietaSM);
579 //______________________________________________________________________
580 AliEMCALGeometry * AliEMCALGeometry::GetInstance(){
581 // Returns the pointer of the unique instance
583 AliEMCALGeometry * rv = static_cast<AliEMCALGeometry *>( fgGeom );
587 //______________________________________________________________________
588 AliEMCALGeometry* AliEMCALGeometry::GetInstance(const Text_t* name,
589 const Text_t* title){
590 // Returns the pointer of the unique instance
592 AliEMCALGeometry * rv = 0;
594 if ( strcmp(name,"") == 0 ) { // get default geometry
595 fgGeom = new AliEMCALGeometry(fgDefaultGeometryName, title);
597 fgGeom = new AliEMCALGeometry(name, title);
598 } // end if strcmp(name,"")
599 if ( fgInit ) rv = (AliEMCALGeometry * ) fgGeom;
606 if ( strcmp(fgGeom->GetName(), name) != 0) {
607 printf("\ncurrent geometry is %s : ", fgGeom->GetName());
608 printf(" you cannot call %s ",name);
610 rv = (AliEMCALGeometry *) fgGeom;
616 //_____________________________________________________________________________
617 Bool_t AliEMCALGeometry::IsInEMCAL(Double_t x, Double_t y, Double_t z) const {
618 // Checks whether point is inside the EMCal volume, used in AliEMCALv*.cxx
620 // Code uses cylindrical approximation made of inner radius (for speed)
622 // Points behind EMCAl, i.e. R > outer radius, but eta, phi in acceptance
623 // are considered to inside
625 Double_t r=sqrt(x*x+y*y);
627 if ( r > fEnvelop[0] ) {
629 theta = TMath::ATan2(r,z);
634 eta = -TMath::Log(TMath::Tan(theta/2.));
635 if (eta < fArm1EtaMin || eta > fArm1EtaMax)
638 Double_t phi = TMath::ATan2(y,x) * 180./TMath::Pi();
639 if (phi < 0) phi += 360; // phi should go from 0 to 360 in this case
640 if (phi > fArm1PhiMin && phi < fArm1PhiMax)
647 // == Shish-kebab cases ==
649 //________________________________________________________________________________________________
650 Int_t AliEMCALGeometry::GetAbsCellId(Int_t nSupMod, Int_t nModule, Int_t nIphi, Int_t nIeta) const
654 // 13-oct-05; 110 degree case
655 // May 31, 2006; ALICE numbering scheme:
656 // 0 <= nSupMod < fNumberOfSuperModules
657 // 0 <= nModule < fNPHI * fNZ ( fNPHI * fNZ/2 for fKey110DEG=1)
658 // 0 <= nIphi < fNPHIdiv
659 // 0 <= nIeta < fNETAdiv
660 // 0 <= absid < fNCells
661 static Int_t id=0; // have to change from 0 to fNCells-1
662 if(fKey110DEG == 1 && nSupMod >= 10) { // 110 degree case; last two supermodules
663 id = fNCellsInSupMod*10 + (fNCellsInSupMod/2)*(nSupMod-10);
665 id = fNCellsInSupMod*nSupMod;
667 id += fNCellsInModule *nModule;
668 id += fNPHIdiv *nIphi;
670 if(id<0 || id >= fNCells) {
671 // printf(" wrong numerations !!\n");
672 // printf(" id %6i(will be force to -1)\n", id);
673 // printf(" fNCells %6i\n", fNCells);
674 // printf(" nSupMod %6i\n", nSupMod);
675 // printf(" nModule %6i\n", nModule);
676 // printf(" nIphi %6i\n", nIphi);
677 // printf(" nIeta %6i\n", nIeta);
678 id = -TMath::Abs(id); // if negative something wrong
683 //________________________________________________________________________________________________
684 Bool_t AliEMCALGeometry::CheckAbsCellId(Int_t absId) const
686 // May 31, 2006; only trd1 now
687 if(absId<0 || absId >= fNCells) return kFALSE;
691 //________________________________________________________________________________________________
692 Bool_t AliEMCALGeometry::GetCellIndex(Int_t absId,Int_t &nSupMod,Int_t &nModule,Int_t &nIphi,Int_t &nIeta) const
694 // 21-sep-04; 19-oct-05;
695 // May 31, 2006; ALICE numbering scheme:
698 // absId - cell is as in Geant, 0<= absId < fNCells;
700 // nSupMod - super module(SM) number, 0<= nSupMod < fNumberOfSuperModules;
701 // nModule - module number in SM, 0<= nModule < fNCellsInSupMod/fNCellsInSupMod or(/2) for tow last SM (10th and 11th);
702 // nIphi - cell number in phi driection inside module; 0<= nIphi < fNPHIdiv;
703 // nIeta - cell number in eta driection inside module; 0<= nIeta < fNETAdiv;
705 static Int_t tmp=0, sm10=0;
706 if(!CheckAbsCellId(absId)) return kFALSE;
708 sm10 = fNCellsInSupMod*10;
709 if(fKey110DEG == 1 && absId >= sm10) { // 110 degree case; last two supermodules
710 nSupMod = (absId-sm10) / (fNCellsInSupMod/2) + 10;
711 tmp = (absId-sm10) % (fNCellsInSupMod/2);
713 nSupMod = absId / fNCellsInSupMod;
714 tmp = absId % fNCellsInSupMod;
717 nModule = tmp / fNCellsInModule;
718 tmp = tmp % fNCellsInModule;
719 nIphi = tmp / fNPHIdiv;
720 nIeta = tmp % fNPHIdiv;
725 //________________________________________________________________________________________________
726 void AliEMCALGeometry::GetModulePhiEtaIndexInSModule(Int_t nSupMod, Int_t nModule, int &iphim, int &ietam) const
728 // added nSupMod; - 19-oct-05 !
729 // Alice numbering scheme - Jun 01,2006
730 // ietam, iphi - indexes of module in two dimensional grid of SM
731 // ietam - have to change from 0 to fNZ-1
732 // iphim - have to change from 0 to nphi-1 (fNPhi-1 or fNPhi/2-1)
735 if(fKey110DEG == 1 && nSupMod>=10) nphi = fNPhi/2;
738 ietam = nModule/nphi;
739 iphim = nModule%nphi;
742 //________________________________________________________________________________________________
743 void AliEMCALGeometry::GetCellPhiEtaIndexInSModule(Int_t nSupMod, Int_t nModule, Int_t nIphi, Int_t nIeta,
744 int &iphi, int &ieta) const
747 // Added nSupMod; Nov 25, 05
748 // Alice numbering scheme - Jun 01,2006
750 // nSupMod - super module(SM) number, 0<= nSupMod < fNumberOfSuperModules;
751 // nModule - module number in SM, 0<= nModule < fNCellsInSupMod/fNCellsInSupMod or(/2) for tow last SM (10th and 11th);
752 // nIphi - cell number in phi driection inside module; 0<= nIphi < fNPHIdiv;
753 // nIeta - cell number in eta driection inside module; 0<= nIeta < fNETAdiv;
756 // ieta, iphi - indexes of cell(tower) in two dimensional grid of SM
757 // ieta - have to change from 0 to (fNZ*fNETAdiv-1)
758 // iphi - have to change from 0 to (fNPhi*fNPHIdiv-1 or fNPhi*fNPHIdiv/2-1)
760 static Int_t iphim, ietam;
762 GetModulePhiEtaIndexInSModule(nSupMod,nModule, iphim, ietam);
763 // ieta = ietam*fNETAdiv + (1-nIeta); // x(module) = -z(SM)
764 ieta = ietam*fNETAdiv + (fNETAdiv - 1 - nIeta); // x(module) = -z(SM)
765 iphi = iphim*fNPHIdiv + nIphi; // y(module) = y(SM)
768 AliDebug(1,Form(" nSupMod %i nModule %i nIphi %i nIeta %i => ieta %i iphi %i\n",
769 nSupMod, nModule, nIphi, nIeta, ieta, iphi));
772 //________________________________________________________________________________________________
773 Int_t AliEMCALGeometry::GetSuperModuleNumber(Int_t absId) const
775 // Return the number of the supermodule given the absolute
776 // ALICE numbering id
778 static Int_t nSupMod, nModule, nIphi, nIeta;
779 GetCellIndex(absId, nSupMod, nModule, nIphi, nIeta);
783 //________________________________________________________________________________________________
784 void AliEMCALGeometry::GetModuleIndexesFromCellIndexesInSModule(Int_t nSupMod, Int_t iphi, Int_t ieta,
785 Int_t &iphim, Int_t &ietam, Int_t &nModule) const
787 // Transition from cell indexes (ieta,iphi) to module indexes (ietam,iphim, nModule)
789 nphi = GetNumberOfModuleInPhiDirection(nSupMod);
791 ietam = ieta/fNETAdiv;
792 iphim = iphi/fNPHIdiv;
793 nModule = ietam * nphi + iphim;
796 //________________________________________________________________________________________________
797 Int_t AliEMCALGeometry::GetAbsCellIdFromCellIndexes(Int_t nSupMod, Int_t iphi, Int_t ieta) const
799 // Transition from super module number(nSupMod) and cell indexes (ieta,iphi) to absId
800 static Int_t ietam, iphim, nModule;
801 static Int_t nIeta, nIphi; // cell indexes in module
803 GetModuleIndexesFromCellIndexesInSModule(nSupMod, iphi, ieta, ietam, iphim, nModule);
805 nIeta = ieta%fNETAdiv;
806 nIeta = fNETAdiv - 1 - nIeta;
807 nIphi = iphi%fNPHIdiv;
809 return GetAbsCellId(nSupMod, nModule, nIphi, nIeta);
813 // Methods for AliEMCALRecPoint - Feb 19, 2006
814 //________________________________________________________________________________________________
815 Bool_t AliEMCALGeometry::RelPosCellInSModule(Int_t absId, Double_t &xr, Double_t &yr, Double_t &zr) const
817 // Look to see what the relative
818 // position inside a given cell is
820 // Alice numbering scheme - Jun 08, 2006
822 // absId - cell is as in Geant, 0<= absId < fNCells;
824 // xr,yr,zr - x,y,z coordinates of cell with absId inside SM
826 // Shift index taking into account the difference between standard SM
827 // and SM of half size in phi direction
828 const Int_t kphiIndexShift = fCentersOfCellsPhiDir.GetSize()/4; // Nov 22, 2006; was 6 for cas 2X2
829 static Int_t nSupMod, nModule, nIphi, nIeta, iphi, ieta;
830 if(!CheckAbsCellId(absId)) return kFALSE;
832 GetCellIndex(absId, nSupMod, nModule, nIphi, nIeta);
833 GetCellPhiEtaIndexInSModule(nSupMod,nModule,nIphi,nIeta, iphi, ieta);
835 xr = fCentersOfCellsXDir.At(ieta);
836 zr = fCentersOfCellsEtaDir.At(ieta);
839 yr = fCentersOfCellsPhiDir.At(iphi);
841 yr = fCentersOfCellsPhiDir.At(iphi + kphiIndexShift);
843 AliDebug(1,Form("absId %i nSupMod %i iphi %i ieta %i xr %f yr %f zr %f ",absId,nSupMod,iphi,ieta,xr,yr,zr));
848 //________________________________________________________________________________________________
849 Bool_t AliEMCALGeometry::RelPosCellInSModule(Int_t absId, Double_t loc[3]) const
851 // Alice numbering scheme - Jun 03, 2006
852 loc[0] = loc[1] = loc[2]=0.0;
853 if(RelPosCellInSModule(absId, loc[0],loc[1],loc[2])) {
859 //________________________________________________________________________________________________
860 Bool_t AliEMCALGeometry::RelPosCellInSModule(Int_t absId, TVector3 &vloc) const
862 static Double_t loc[3];
863 if(RelPosCellInSModule(absId,loc)) {
864 vloc.SetXYZ(loc[0], loc[1], loc[2]);
870 // Alice numbering scheme - Jun 03, 2006
873 //________________________________________________________________________________________________
874 Bool_t AliEMCALGeometry::RelPosCellInSModule(Int_t absId, Double_t distEff, Double_t &xr, Double_t &yr, Double_t &zr) const
876 // Jul 30, 2007 - taking into account position of shower max
877 // Look to see what the relative
878 // position inside a given cell is
881 // absId - cell is as in Geant, 0<= absId < fNCells;
882 // e - cluster energy
884 // xr,yr,zr - x,y,z coordinates of cell with absId inside SM
886 // Shift index taking into account the difference between standard SM
887 // and SM of half size in phi direction
888 const Int_t kphiIndexShift = fCentersOfCellsPhiDir.GetSize()/4; // Nov 22, 2006; was 6 for cas 2X2
889 static Int_t nSupMod, nModule, nIphi, nIeta, iphi, ieta;
890 static Int_t iphim, ietam;
891 static AliEMCALShishKebabTrd1Module *mod = 0;
893 if(!CheckAbsCellId(absId)) return kFALSE;
895 GetCellIndex(absId, nSupMod, nModule, nIphi, nIeta);
896 GetModulePhiEtaIndexInSModule(nSupMod, nModule, iphim, ietam);
897 GetCellPhiEtaIndexInSModule(nSupMod,nModule,nIphi,nIeta, iphi, ieta);
899 mod = GetShishKebabModule(ietam);
900 mod->GetPositionAtCenterCellLine(nIeta, distEff, v);
901 xr = v.Y() - fParSM[0];
902 zr = v.X() - fParSM[2];
905 yr = fCentersOfCellsPhiDir.At(iphi);
907 yr = fCentersOfCellsPhiDir.At(iphi + kphiIndexShift);
909 AliDebug(1,Form("absId %i nSupMod %i iphi %i ieta %i xr %f yr %f zr %f ",absId,nSupMod,iphi,ieta,xr,yr,zr));
914 //________________________________________________________________________________________________
915 Bool_t AliEMCALGeometry::RelPosCellInSModule(Int_t absId, Int_t maxAbsId, Double_t distEff, Double_t &xr, Double_t &yr, Double_t &zr) const
917 // Jul 31, 2007 - taking into account position of shower max and apply coor2.
918 // Look to see what the relative
919 // position inside a given cell is
922 // absId - cell is as in Geant, 0<= absId < fNCells;
923 // maxAbsId - abs id of cell with highest energy
924 // e - cluster energy
926 // xr,yr,zr - x,y,z coordinates of cell with absId inside SM
928 // Shift index taking into account the difference between standard SM
929 // and SM of half size in phi direction
930 const Int_t kphiIndexShift = fCentersOfCellsPhiDir.GetSize()/4; // Nov 22, 2006; was 6 for cas 2X2
931 static Int_t nSupMod, nModule, nIphi, nIeta, iphi, ieta;
932 static Int_t iphim, ietam;
933 static AliEMCALShishKebabTrd1Module *mod = 0;
936 static Int_t nSupModM, nModuleM, nIphiM, nIetaM, iphiM, ietaM;
937 static Int_t iphimM, ietamM, maxAbsIdCopy=-1;
938 static AliEMCALShishKebabTrd1Module *modM = 0;
939 static Double_t distCorr;
941 if(!CheckAbsCellId(absId)) return kFALSE;
943 GetCellIndex(absId, nSupMod, nModule, nIphi, nIeta);
944 GetModulePhiEtaIndexInSModule(nSupMod, nModule, iphim, ietam);
945 GetCellPhiEtaIndexInSModule(nSupMod,nModule,nIphi,nIeta, iphi, ieta);
946 mod = GetShishKebabModule(ietam);
948 if(absId != maxAbsId) {
950 if(maxAbsIdCopy != maxAbsId) {
951 GetCellIndex(maxAbsId, nSupModM, nModuleM, nIphiM, nIetaM);
952 GetModulePhiEtaIndexInSModule(nSupModM, nModuleM, iphimM, ietamM);
953 GetCellPhiEtaIndexInSModule(nSupModM,nModuleM,nIphiM,nIetaM, iphiM, ietaM);
954 modM = GetShishKebabModule(ietamM); // do I need this ?
955 maxAbsIdCopy = maxAbsId;
958 distCorr = GetEtaModuleSize()*(ietam-ietamM)/TMath::Tan(modM->GetTheta()); // Stay here
959 //printf(" distCorr %f | dist %f | ietam %i -> etamM %i\n", distCorr, dist, ietam, ietamM);
961 // distEff += distCorr;
963 // Bad resolution in this case, strong bias vs phi
965 mod->GetPositionAtCenterCellLine(nIeta, distEff, v); // Stay here
966 xr = v.Y() - fParSM[0];
967 zr = v.X() - fParSM[2];
970 yr = fCentersOfCellsPhiDir.At(iphi);
972 yr = fCentersOfCellsPhiDir.At(iphi + kphiIndexShift);
974 AliDebug(1,Form("absId %i nSupMod %i iphi %i ieta %i xr %f yr %f zr %f ",absId,nSupMod,iphi,ieta,xr,yr,zr));
979 //________________________________________________________________________________________________
980 void AliEMCALGeometry::CreateListOfTrd1Modules()
982 // Generate the list of Trd1 modules
983 // which will make up the EMCAL
986 AliDebug(2,Form(" AliEMCALGeometry::CreateListOfTrd1Modules() started "));
988 AliEMCALShishKebabTrd1Module *mod=0, *mTmp=0; // current module
989 if(fShishKebabTrd1Modules == 0) {
990 fShishKebabTrd1Modules = new TList;
991 fShishKebabTrd1Modules->SetName("ListOfTRD1");
992 for(int iz=0; iz< GetNZ(); iz++) {
994 mod = new AliEMCALShishKebabTrd1Module(TMath::Pi()/2.,this);
996 mTmp = new AliEMCALShishKebabTrd1Module(*mod);
999 fShishKebabTrd1Modules->Add(mod);
1002 AliDebug(2,Form(" Already exits : "));
1004 mod = (AliEMCALShishKebabTrd1Module*)fShishKebabTrd1Modules->At(fShishKebabTrd1Modules->GetSize()-1);
1005 fEtaMaxOfTRD1 = mod->GetMaxEtaOfModule(0);
1007 AliDebug(2,Form(" fShishKebabTrd1Modules has %i modules : max eta %5.4f \n",
1008 fShishKebabTrd1Modules->GetSize(),fEtaMaxOfTRD1));
1010 // Jun 01, 2006 - ALICE numbering scheme
1011 // define grid for cells in eta(z) and x directions in local coordinates system of SM
1012 // Works just for 2x2 case only -- ?? start here
1015 // Define grid for cells in phi(y) direction in local coordinates system of SM
1016 // as for 2X2 as for 3X3 - Nov 8,2006
1018 AliDebug(2,Form(" Cells grid in phi directions : size %i\n", fCentersOfCellsPhiDir.GetSize()));
1019 Int_t ind=0; // this is phi index
1020 Int_t ieta=0, nModule=0, iphiTemp;
1021 Double_t xr, zr, theta, phi, eta, r, x,y;
1023 Double_t ytCenterModule=0.0, ytCenterCell=0.0;
1025 fCentersOfCellsPhiDir.Set(fNPhi*fNPHIdiv);
1026 fPhiCentersOfCells.Set(fNPhi*fNPHIdiv);
1028 Double_t r0 = GetIPDistance() + GetLongModuleSize()/2.;
1029 for(Int_t it=0; it<fNPhi; it++) { // cycle on modules
1030 ytCenterModule = -fParSM[1] + fPhiModuleSize*(2*it+1)/2; // center of module
1031 for(Int_t ic=0; ic<fNPHIdiv; ic++) { // cycle on cells in module
1033 ytCenterCell = ytCenterModule + fPhiTileSize *(2*ic-1)/2.;
1034 } else if(fNPHIdiv==3){
1035 ytCenterCell = ytCenterModule + fPhiTileSize *(ic-1);
1036 } else if(fNPHIdiv==1){
1037 ytCenterCell = ytCenterModule;
1039 fCentersOfCellsPhiDir.AddAt(ytCenterCell,ind);
1040 // Define grid on phi direction
1041 // Grid is not the same for different eta bin;
1042 // Effect is small but is still here
1043 phi = TMath::ATan2(ytCenterCell, r0);
1044 fPhiCentersOfCells.AddAt(phi, ind);
1046 AliDebug(2,Form(" ind %2.2i : y %8.3f ", ind, fCentersOfCellsPhiDir.At(ind)));
1051 fCentersOfCellsEtaDir.Set(fNZ *fNETAdiv);
1052 fCentersOfCellsXDir.Set(fNZ *fNETAdiv);
1053 fEtaCentersOfCells.Set(fNZ *fNETAdiv * fNPhi*fNPHIdiv);
1054 AliDebug(2,Form(" Cells grid in eta directions : size %i\n", fCentersOfCellsEtaDir.GetSize()));
1055 for(Int_t it=0; it<fNZ; it++) {
1056 AliEMCALShishKebabTrd1Module *trd1 = GetShishKebabModule(it);
1058 for(Int_t ic=0; ic<fNETAdiv; ic++) {
1060 trd1->GetCenterOfCellInLocalCoordinateofSM(ic, xr, zr); // case of 2X2
1061 GetCellPhiEtaIndexInSModule(0, nModule, 0, ic, iphiTemp, ieta);
1063 trd1->GetCenterOfCellInLocalCoordinateofSM_3X3(ic, xr, zr); // case of 3X3
1064 GetCellPhiEtaIndexInSModule(0, nModule, 0, ic, iphiTemp, ieta);
1066 trd1->GetCenterOfCellInLocalCoordinateofSM_1X1(xr, zr); // case of 1X1
1067 GetCellPhiEtaIndexInSModule(0, nModule, 0, ic, iphiTemp, ieta);
1069 fCentersOfCellsXDir.AddAt(float(xr) - fParSM[0],ieta);
1070 fCentersOfCellsEtaDir.AddAt(float(zr) - fParSM[2],ieta);
1071 // Define grid on eta direction for each bin in phi
1072 for(int iphi=0; iphi<fCentersOfCellsPhiDir.GetSize(); iphi++) {
1073 x = xr + trd1->GetRadius();
1074 y = fCentersOfCellsPhiDir[iphi];
1075 r = TMath::Sqrt(x*x + y*y + zr*zr);
1076 theta = TMath::ACos(zr/r);
1077 eta = AliEMCALShishKebabTrd1Module::ThetaToEta(theta);
1078 // ind = ieta*fCentersOfCellsPhiDir.GetSize() + iphi;
1079 ind = iphi*fCentersOfCellsEtaDir.GetSize() + ieta;
1080 fEtaCentersOfCells.AddAt(eta, ind);
1082 //printf(" ieta %i : xr + trd1->GetRadius() %f : zr %f : eta %f \n", ieta, xr + trd1->GetRadius(), zr, eta);
1085 for(Int_t i=0; i<fCentersOfCellsEtaDir.GetSize(); i++) {
1086 AliDebug(2,Form(" ind %2.2i : z %8.3f : x %8.3f", i+1,
1087 fCentersOfCellsEtaDir.At(i),fCentersOfCellsXDir.At(i)));
1092 //________________________________________________________________________________________________
1093 void AliEMCALGeometry::GetGlobal(const Double_t *loc, Double_t *glob, int ind) const
1095 // Figure out the global numbering
1096 // of a given supermodule from the
1097 // local numbering and the transformation
1098 // matrix stored by the geometry manager (allows for misaligned
1101 if(ind>=0 && ind < GetNumberOfSuperModules()) {
1102 TString volpath = "ALIC_1/XEN1_1/SMOD_";
1105 if(GetKey110DEG() && ind>=10) {
1106 volpath = "ALIC_1/XEN1_1/SM10_";
1107 volpath += ind-10+1;
1110 if(!gGeoManager->cd(volpath.Data()))
1111 AliFatal(Form("AliEMCALGeometry::GeoManager cannot find path %s!",volpath.Data()));
1113 TGeoHMatrix* m = gGeoManager->GetCurrentMatrix();
1115 m->LocalToMaster(loc, glob);
1117 AliFatal("Geo matrixes are not loaded \n") ;
1122 //________________________________________________________________________________________________
1123 void AliEMCALGeometry::GetGlobal(const TVector3 &vloc, TVector3 &vglob, int ind) const
1125 //Figure out the global numbering
1126 //of a given supermodule from the
1127 //local numbering given a 3-vector location
1129 static Double_t tglob[3], tloc[3];
1131 GetGlobal(tloc, tglob, ind);
1132 vglob.SetXYZ(tglob[0], tglob[1], tglob[2]);
1135 //________________________________________________________________________________________________
1136 void AliEMCALGeometry::GetGlobal(Int_t absId , double glob[3]) const
1138 // Alice numbering scheme - Jun 03, 2006
1139 static Int_t nSupMod, nModule, nIphi, nIeta;
1140 static double loc[3];
1142 if (!gGeoManager || !gGeoManager->IsClosed()) {
1143 AliError("Can't get the global coordinates! gGeoManager doesn't exist or it is still open!");
1147 glob[0]=glob[1]=glob[2]=0.0; // bad case
1148 if(RelPosCellInSModule(absId, loc)) {
1149 GetCellIndex(absId, nSupMod, nModule, nIphi, nIeta);
1151 TString volpath = "ALIC_1/XEN1_1/SMOD_";
1152 volpath += (nSupMod+1);
1154 if(GetKey110DEG() && nSupMod>=10) {
1155 volpath = "ALIC_1/XEN1_1/SM10_";
1156 volpath += (nSupMod-10+1);
1158 if(!gGeoManager->cd(volpath.Data()))
1159 AliFatal(Form("GeoManager cannot find path %s!",volpath.Data()));
1161 TGeoHMatrix* m = gGeoManager->GetCurrentMatrix();
1163 m->LocalToMaster(loc, glob);
1165 AliFatal("Geo matrixes are not loaded \n") ;
1170 //___________________________________________________________________
1171 void AliEMCALGeometry::GetGlobal(Int_t absId , TVector3 &vglob) const
1173 // Alice numbering scheme - Jun 03, 2006
1174 static Double_t glob[3];
1176 GetGlobal(absId, glob);
1177 vglob.SetXYZ(glob[0], glob[1], glob[2]);
1181 //____________________________________________________________________________
1182 void AliEMCALGeometry::GetGlobal(const AliRecPoint* /*rp*/, TVector3& /* vglob */) const
1184 AliFatal(Form("Please use GetGlobalEMCAL(recPoint,gpos) instead of GetGlobal!"));
1187 //_________________________________________________________________________________
1188 void AliEMCALGeometry::GetGlobalEMCAL(const AliEMCALRecPoint *rp, TVector3 &vglob) const
1190 // Figure out the global numbering
1191 // of a given supermodule from the
1192 // local numbering for RecPoints
1194 static TVector3 vloc;
1195 static Int_t nSupMod, nModule, nIphi, nIeta;
1197 const AliEMCALRecPoint *rpTmp = rp;
1198 const AliEMCALRecPoint *rpEmc = rpTmp;
1200 GetCellIndex(rpEmc->GetAbsId(0), nSupMod, nModule, nIphi, nIeta);
1201 rpTmp->GetLocalPosition(vloc);
1202 GetGlobal(vloc, vglob, nSupMod);
1205 //________________________________________________________________________________________________
1206 void AliEMCALGeometry::EtaPhiFromIndex(Int_t absId,Double_t &eta,Double_t &phi) const
1208 // Nov 16, 2006- float to double
1209 // version for TRD1 only
1210 static TVector3 vglob;
1211 GetGlobal(absId, vglob);
1216 //________________________________________________________________________________________________
1217 void AliEMCALGeometry::EtaPhiFromIndex(Int_t absId,Float_t &eta,Float_t &phi) const
1219 // Nov 16,2006 - should be discard in future
1220 static TVector3 vglob;
1221 GetGlobal(absId, vglob);
1222 eta = float(vglob.Eta());
1223 phi = float(vglob.Phi());
1226 //________________________________________________________________________________________________
1227 Bool_t AliEMCALGeometry::GetPhiBoundariesOfSM(Int_t nSupMod, Double_t &phiMin, Double_t &phiMax) const
1229 // 0<= nSupMod <=11; phi in rad
1231 if(nSupMod<0 || nSupMod >11) return kFALSE;
1233 phiMin = fPhiBoundariesOfSM[2*i];
1234 phiMax = fPhiBoundariesOfSM[2*i+1];
1238 //________________________________________________________________________________________________
1239 Bool_t AliEMCALGeometry::GetPhiBoundariesOfSMGap(Int_t nPhiSec, Double_t &phiMin, Double_t &phiMax) const
1241 // 0<= nPhiSec <=4; phi in rad
1242 // 0; gap boundaries between 0th&2th | 1th&3th SM
1243 // 1; gap boundaries between 2th&4th | 3th&5th SM
1244 // 2; gap boundaries between 4th&6th | 5th&7th SM
1245 // 3; gap boundaries between 6th&8th | 7th&9th SM
1246 // 4; gap boundaries between 8th&10th | 9th&11th SM
1247 if(nPhiSec<0 || nPhiSec >4) return kFALSE;
1248 phiMin = fPhiBoundariesOfSM[2*nPhiSec+1];
1249 phiMax = fPhiBoundariesOfSM[2*nPhiSec+2];
1253 //________________________________________________________________________________________________
1254 Bool_t AliEMCALGeometry::SuperModuleNumberFromEtaPhi(Double_t eta, Double_t phi, Int_t &nSupMod) const
1256 // Return false if phi belongs a phi cracks between SM
1260 if(TMath::Abs(eta) > fEtaMaxOfTRD1) return kFALSE;
1262 phi = TVector2::Phi_0_2pi(phi); // move phi to (0,2pi) boundaries
1263 for(i=0; i<6; i++) {
1264 if(phi>=fPhiBoundariesOfSM[2*i] && phi<=fPhiBoundariesOfSM[2*i+1]) {
1266 if(eta < 0.0) nSupMod++;
1267 AliDebug(1,Form("eta %f phi %f(%5.2f) : nSupMod %i : #bound %i", eta,phi,phi*TMath::RadToDeg(), nSupMod,i));
1274 //________________________________________________________________________________________________
1275 Bool_t AliEMCALGeometry::GetAbsCellIdFromEtaPhi(Double_t eta, Double_t phi, Int_t &absId) const
1278 // stay here - phi problem as usual
1279 static Int_t nSupMod, i, ieta, iphi, etaShift, nphi;
1280 static Double_t absEta=0.0, d=0.0, dmin=0.0, phiLoc;
1281 absId = nSupMod = - 1;
1282 if(SuperModuleNumberFromEtaPhi(eta, phi, nSupMod)) {
1284 phi = TVector2::Phi_0_2pi(phi);
1285 phiLoc = phi - fPhiCentersOfSM[nSupMod/2];
1286 nphi = fPhiCentersOfCells.GetSize();
1288 phiLoc = phi - 190.*TMath::DegToRad();
1292 dmin = TMath::Abs(fPhiCentersOfCells[0]-phiLoc);
1294 for(i=1; i<nphi; i++) {
1295 d = TMath::Abs(fPhiCentersOfCells[i] - phiLoc);
1300 // printf(" i %i : d %f : dmin %f : fPhiCentersOfCells[i] %f \n", i, d, dmin, fPhiCentersOfCells[i]);
1302 // odd SM are turned with respect of even SM - reverse indexes
1303 AliDebug(2,Form(" iphi %i : dmin %f (phi %f, phiLoc %f ) ", iphi, dmin, phi, phiLoc));
1305 absEta = TMath::Abs(eta);
1306 etaShift = iphi*fCentersOfCellsEtaDir.GetSize();
1307 dmin = TMath::Abs(fEtaCentersOfCells[etaShift]-absEta);
1309 for(i=1; i<fCentersOfCellsEtaDir.GetSize(); i++) {
1310 d = TMath::Abs(fEtaCentersOfCells[i+etaShift] - absEta);
1316 AliDebug(2,Form(" ieta %i : dmin %f (eta=%f) : nSupMod %i ", ieta, dmin, eta, nSupMod));
1318 if(eta<0) iphi = (nphi-1) - iphi;
1319 absId = GetAbsCellIdFromCellIndexes(nSupMod, iphi, ieta);
1326 //________________________________________________________________________________________________
1327 AliEMCALShishKebabTrd1Module* AliEMCALGeometry::GetShishKebabModule(Int_t neta) const
1329 //This method was too long to be
1330 //included in the header file - the
1331 //rule checker complained about it's
1332 //length, so we move it here. It returns the
1333 //shishkebabmodule at a given eta index point.
1335 static AliEMCALShishKebabTrd1Module* trd1=0;
1336 if(fShishKebabTrd1Modules && neta>=0 && neta<fShishKebabTrd1Modules->GetSize()) {
1337 trd1 = (AliEMCALShishKebabTrd1Module*)fShishKebabTrd1Modules->At(neta);
1342 //________________________________________________________________________________________________
1343 Int_t AliEMCALGeometry::GetAbsTRUNumberFromNumberInSm(const Int_t row, const Int_t col, const Int_t sm)
1345 Int_t itru = row + col*GetNModulesInTRUPhi() + sm*GetNTRU();
1346 // printf(" GetAbsTRUNumberFromNumberInSm : row %2i col %2i sm %2i -> itru %2i\n", row, col, sm, itru);
1350 //________________________________________________________________________________________________
1351 void AliEMCALGeometry::Browse(TBrowser* b)
1353 //Browse the modules
1354 if(fShishKebabTrd1Modules) b->Add(fShishKebabTrd1Modules);
1357 //________________________________________________________________________________________________
1358 Bool_t AliEMCALGeometry::IsFolder() const
1360 //Check if fShishKebabTrd1Modules is in folder
1361 if(fShishKebabTrd1Modules) return kTRUE;
1365 //________________________________________________________________________________________________
1366 Double_t AliEMCALGeometry::GetPhiCenterOfSM(Int_t nsupmod) const
1368 //returns center of supermodule in phi
1370 return fPhiCentersOfSM[i];