]> git.uio.no Git - u/mrichter/AliRoot.git/blob - EMCAL/AliEMCALGeometry.cxx
remove classes alredy moved to EMCALcalib library
[u/mrichter/AliRoot.git] / EMCAL / AliEMCALGeometry.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
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  **************************************************************************/
15
16 /* $Id$*/
17
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
24 // -0.7 to 0.7 in eta 
25 //
26 //     EMCAL geometry tree:
27 //     EMCAL -> superModule -> module -> tower(cell)
28 //     Indexes
29 //     absId -> nSupMod     -> nModule -> (nIphi,nIeta)
30 //
31 //   Name choices: 
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
36 //          in old notation
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
40 //
41 //   etc.
42 //
43 //
44 //
45 //*-- Author: Sahal Yacoob (LBL / UCT)
46 //     and  : Yves Schutz (SUBATECH)
47 //     and  : Jennifer Klay (LBL)
48 //     and  : Aleksei Pavlinov (WSU) 
49 //
50
51 #include <cassert>
52
53 // --- Root header files ---
54 #include <Riostream.h>
55 #include <TBrowser.h>
56 #include <TClonesArray.h>
57 #include <TGeoManager.h>
58 #include <TGeoMatrix.h>
59 #include <TGeoNode.h>
60 #include <TList.h>
61 #include <TMatrixD.h>
62 #include <TObjArray.h>
63 #include <TObjString.h>
64 #include <TVector2.h>
65 #include <TVector3.h>
66
67 // -- ALICE Headers.
68 #include "AliLog.h"
69
70 // --- EMCAL headers
71 #include "AliEMCALGeometry.h"
72 #include "AliEMCALShishKebabTrd1Module.h"
73 #include "AliEMCALRecPoint.h"
74 #include "AliEMCALDigit.h"
75 #include "AliEMCALHistoUtilities.h"
76
77 ClassImp(AliEMCALGeometry)
78
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";
83 //
84 // Usage: 
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.
88 //         
89 //  AliEMCALGeometry* g = AliEMCALGeometry::GetInstance(name,title); // first time
90 //  ..
91 //  g = AliEMCALGeometry::GetInstance();                             // after first time
92 //
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");
98
99 AliEMCALGeometry::AliEMCALGeometry() 
100   : AliGeometry(),
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),
107     // Trigger staff
108     fNTRUEta(0),
109     fNTRUPhi(0), 
110     fNModulesInTRUEta(0), 
111     fNModulesInTRUPhi(0), 
112     fNEtaSubOfTRU(0),
113     // 
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.)
122
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    
126
127   AliDebug(2, "AliEMCALGeometry : default ctor ");
128 }
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),
138     // Trigger staff
139     fNTRUEta(0),
140     fNTRUPhi(0), 
141     fNModulesInTRUEta(0), 
142     fNModulesInTRUPhi(0), 
143     fNEtaSubOfTRU(0),
144     // 
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.)
153 {
154   // ctor only for internal usage (singleton)
155   AliDebug(2, Form("AliEMCALGeometry(%s,%s) ", name,title));
156
157   Init();
158
159   CreateListOfTrd1Modules();
160
161   if (AliDebugLevel()>=2) {
162     PrintGeometry();
163   }
164
165 }
166 //______________________________________________________________________
167 AliEMCALGeometry::AliEMCALGeometry(const AliEMCALGeometry& geom)
168   : AliGeometry(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),
182     fNZ(geom.fNZ),
183     fNPhi(geom.fNPhi),
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),
200     // Trigger staff
201     fNTRUEta(geom.fNTRUEta),
202     fNTRUPhi(geom.fNTRUPhi),
203     fNModulesInTRUEta(geom.fNModulesInTRUEta),
204     fNModulesInTRUPhi(geom.fNModulesInTRUPhi),
205     fNEtaSubOfTRU(geom.fNEtaSubOfTRU),
206     //
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),
228     fTubsR(geom.fTubsR),
229     fTubsTurnAngle(geom.fTubsTurnAngle)
230 {
231   //copy ctor
232 }
233
234 //______________________________________________________________________
235 AliEMCALGeometry::~AliEMCALGeometry(void){
236     // dtor
237 }
238
239 //______________________________________________________________________
240 void AliEMCALGeometry::Init(void){
241   //
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
246   //
247
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)
254
255   fNAdditionalOpts = sizeof(fAdditionalOpts) / sizeof(char*);
256
257   // geometry
258   fgInit = kFALSE; // Assume failed until proven otherwise.
259   fGeoName   = GetName();
260   fGeoName.ToUpper();
261
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";
266     } else {
267       fGeoName = "EMCAL_PDC06";
268     }
269   }
270   if(fGeoName.Contains("WSUC")) fGeoName = "EMCAL_WSUC";
271
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()) ; 
275   }
276
277   // Option to know whether we have the "half" supermodule(s) or not
278   fKey110DEG = 0;
279   if(fGeoName.Contains("COMPLETE") || fGeoName.Contains("PDC06")) fKey110DEG = 1; // for GetAbsCellId
280   fShishKebabTrd1Modules = 0;
281
282   // JLK 13-Apr-2008
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
286
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       
301
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
306
307   fPhiModuleSize = 12.26 - fPhiGapForSM / Float_t(fNPhi); // first assumption
308   fEtaModuleSize = fPhiModuleSize;
309
310   //needs to be called for each geometry and before setting geometry
311   //parameters which can depend on the outcome
312   CheckAdditionalOptions();
313
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();
318   }
319
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 
327     fNPhi = fNZ = 4; 
328     CheckAdditionalOptions();
329   }
330
331   // constant for transition absid <--> indexes
332   fNCellsInModule  = fNPHIdiv*fNETAdiv;
333   fNCellsInSupMod = fNCellsInModule*fNPhi*fNZ;
334   fNCells         = fNCellsInSupMod*fNumberOfSuperModules;
335   if(GetKey110DEG()) fNCells -= fNCellsInSupMod;
336
337   fNPhiSuperModule = fNumberOfSuperModules/2;
338   if(fNPhiSuperModule<1) fNPhiSuperModule = 1;
339     
340   fPhiTileSize = fPhiModuleSize/double(fNPHIdiv) - fLateralSteelStrip; // 13-may-05 
341   fEtaTileSize = fEtaModuleSize/double(fNETAdiv) - fLateralSteelStrip; // 13-may-05 
342
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);
346   
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. 
351
352   // Local coordinates
353   fParSM[0] = GetShellThickness()/2.;        
354   fParSM[1] = GetPhiModuleSize() * GetNPhi()/2.;
355   fParSM[2] = 350./2.;
356
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;
369     }
370   }
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.; 
375   }
376
377   //called after setting of scintillator and lead layer parameters
378   DefineSamplingFraction();
379
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
388   // Jet trigger 
389   // 3*6*10 + 2*6*2 = 204 -> matrix (nphi(17), neta(12))
390   fNEtaSubOfTRU     = 6;  
391
392   fgInit = kTRUE; 
393 }
394
395 void AliEMCALGeometry::PrintGeometry()
396 {
397   // Separate routine is callable from broswer; Nov 7,2006
398   printf("\nInit: geometry of EMCAL named %s :\n", fGeoName.Data());
399   if(fArrayOpts) {
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());
403     }
404   }
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() );
408
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());
434   }
435   printf(" fShishKebabTrd1Modules has %i modules : max eta %5.4f \n", 
436          fShishKebabTrd1Modules->GetSize(),fEtaMaxOfTRD1);
437   
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");
447     }
448     printf("\n");
449     
450   }
451
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());
457   }
458
459 }
460
461 //______________________________________________________________________
462 void AliEMCALGeometry::PrintCellIndexes(Int_t absId, int pri, char *tit)
463 {
464   // Service methods
465   Int_t nSupMod, nModule, nIphi, nIeta;
466   Int_t iphi, ieta;
467   TVector3 vg;
468
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);
471   if(pri>0) {
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());
477   }
478 }
479
480 //______________________________________________________________________
481 void AliEMCALGeometry::CheckAdditionalOptions()
482 {
483   // Feb 06,2006
484   // Additional options that
485   // can be used to select
486   // the specific geometry of 
487   // EMCAL to run
488   // Dec 27,2006
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();
494     delete fArrayOpts;
495     fArrayOpts = 0; 
496     return;
497   }              
498   for(Int_t i=1; i<nopt; i++){
499     TObjString *o = (TObjString*)fArrayOpts->At(i); 
500
501     TString addOpt = o->String();
502     Int_t indj=-1;
503     for(Int_t j=0; j<fNAdditionalOpts; j++) {
504       TString opt = fAdditionalOpts[j];
505       if(addOpt.Contains(opt,TString::kIgnoreCase)) {
506           indj = j;
507         break;
508       }
509     }
510     if(indj<0) {
511       AliDebug(2,Form("<E> option |%s| unavailable : ** look to the file AliEMCALGeometry.h **\n", 
512                       addOpt.Data()));
513       assert(0);
514     } else {
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));
533       }
534     }
535   }
536 }
537
538 void AliEMCALGeometry::DefineSamplingFraction()
539 {
540   // Jun 05,2006
541   // Look http://rhic.physics.wayne.edu/~pavlinov/ALICE/SHISHKEBAB/RES/linearityAndResolutionForTRD1.html
542   // Keep for compatibilty
543   //
544   if(fNECLayers == 69) {        // 10% layer reduction
545     fSampling = 12.55;
546   } else if(fNECLayers == 61) { // 20% layer reduction
547     fSampling = 12.80;
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;
555     }
556
557   }
558 }
559
560 //______________________________________________________________________
561 void AliEMCALGeometry::GetModulePhiEtaIndexInSModuleFromTRUIndex(const Int_t itru, const Int_t iphitru, const Int_t ietatru, Int_t &iphiSM, Int_t &ietaSM) const 
562 {
563   
564   // This method transforms the (eta,phi) index of module in a 
565   // TRU matrix into Super Module (eta,phi) index.
566   
567   // Calculate in which row and column where the TRU are 
568   // ordered in the SM
569
570   Int_t col = itru/ fNTRUPhi ; // indexes of TRU in SM
571   Int_t row = itru - col*fNTRUPhi ;
572    
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);
577 }
578
579 //______________________________________________________________________
580 AliEMCALGeometry *  AliEMCALGeometry::GetInstance(){ 
581   // Returns the pointer of the unique instance
582   
583   AliEMCALGeometry * rv = static_cast<AliEMCALGeometry *>( fgGeom );
584   return rv; 
585 }
586
587 //______________________________________________________________________
588 AliEMCALGeometry* AliEMCALGeometry::GetInstance(const Text_t* name,
589                                                 const Text_t* title){
590     // Returns the pointer of the unique instance
591
592     AliEMCALGeometry * rv = 0; 
593     if ( fgGeom == 0 ) {
594       if ( strcmp(name,"") == 0 ) { // get default geometry
595          fgGeom = new AliEMCALGeometry(fgDefaultGeometryName, title);
596       } else {
597          fgGeom = new AliEMCALGeometry(name, title);
598       }  // end if strcmp(name,"")
599       if ( fgInit ) rv = (AliEMCALGeometry * ) fgGeom;
600       else {
601          rv = 0; 
602          delete fgGeom; 
603          fgGeom = 0; 
604       } // end if fgInit
605     }else{
606         if ( strcmp(fgGeom->GetName(), name) != 0) {
607           printf("\ncurrent geometry is %s : ", fgGeom->GetName());
608           printf(" you cannot call %s ",name);  
609         }else{
610           rv = (AliEMCALGeometry *) fgGeom; 
611         } // end 
612     }  // end if fgGeom
613     return rv; 
614 }
615
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
619   //
620   // Code uses cylindrical approximation made of inner radius (for speed)
621   //
622   // Points behind EMCAl, i.e. R > outer radius, but eta, phi in acceptance 
623   // are considered to inside
624
625   Double_t r=sqrt(x*x+y*y);
626
627   if ( r > fEnvelop[0] ) {
628      Double_t theta;
629      theta  =    TMath::ATan2(r,z);
630      Double_t eta;
631      if(theta == 0) 
632        eta = 9999;
633      else 
634        eta    =   -TMath::Log(TMath::Tan(theta/2.));
635      if (eta < fArm1EtaMin || eta > fArm1EtaMax)
636        return 0;
637  
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)
641        return 1;
642   }
643   return 0;
644 }
645
646 //
647 // == Shish-kebab cases ==
648 //
649 //________________________________________________________________________________________________
650 Int_t AliEMCALGeometry::GetAbsCellId(Int_t nSupMod, Int_t nModule, Int_t nIphi, Int_t nIeta) const
651
652   // 27-aug-04; 
653   // corr. 21-sep-04; 
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);
664   } else {
665     id  = fNCellsInSupMod*nSupMod;
666   }
667   id += fNCellsInModule *nModule;
668   id += fNPHIdiv *nIphi;
669   id += nIeta;
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
679   }
680   return id;
681 }
682
683 //________________________________________________________________________________________________
684 Bool_t  AliEMCALGeometry::CheckAbsCellId(Int_t absId) const
685
686   // May 31, 2006; only trd1 now
687   if(absId<0 || absId >= fNCells) return kFALSE;
688   else                            return kTRUE;
689 }
690
691 //________________________________________________________________________________________________
692 Bool_t AliEMCALGeometry::GetCellIndex(Int_t absId,Int_t &nSupMod,Int_t &nModule,Int_t &nIphi,Int_t &nIeta) const
693
694   // 21-sep-04; 19-oct-05;
695   // May 31, 2006; ALICE numbering scheme:
696   // 
697   // In:
698   // absId   - cell is as in Geant,     0<= absId   < fNCells;
699   // Out:
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; 
704   // 
705   static Int_t tmp=0, sm10=0;
706   if(!CheckAbsCellId(absId)) return kFALSE;
707
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);
712   } else {
713     nSupMod = absId / fNCellsInSupMod;
714     tmp     = absId % fNCellsInSupMod;
715   }
716
717   nModule  = tmp / fNCellsInModule;
718   tmp     = tmp % fNCellsInModule;
719   nIphi   = tmp / fNPHIdiv;
720   nIeta   = tmp % fNPHIdiv;
721
722   return kTRUE;
723 }
724
725 //________________________________________________________________________________________________
726 void AliEMCALGeometry::GetModulePhiEtaIndexInSModule(Int_t nSupMod, Int_t nModule,  int &iphim, int &ietam) const
727
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)
733   static Int_t nphi;
734
735   if(fKey110DEG == 1 && nSupMod>=10) nphi = fNPhi/2;
736   else                               nphi = fNPhi;
737
738   ietam = nModule/nphi;
739   iphim = nModule%nphi;
740 }
741
742 //________________________________________________________________________________________________
743 void AliEMCALGeometry::GetCellPhiEtaIndexInSModule(Int_t nSupMod, Int_t nModule, Int_t nIphi, Int_t nIeta, 
744 int &iphi, int &ieta) const
745
746   // 
747   // Added nSupMod; Nov 25, 05
748   // Alice numbering scheme  - Jun 01,2006 
749   // IN:
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; 
754   // 
755  // OUT:
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)
759   //
760   static Int_t iphim, ietam;
761
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) 
766
767   if(iphi<0 || ieta<0)
768   AliDebug(1,Form(" nSupMod %i nModule %i nIphi %i nIeta %i => ieta %i iphi %i\n", 
769   nSupMod, nModule, nIphi, nIeta, ieta, iphi));
770 }
771
772 //________________________________________________________________________________________________
773 Int_t  AliEMCALGeometry::GetSuperModuleNumber(Int_t absId)  const
774 {
775   // Return the number of the  supermodule given the absolute
776   // ALICE numbering id
777
778   static Int_t nSupMod, nModule, nIphi, nIeta;
779   GetCellIndex(absId, nSupMod, nModule, nIphi, nIeta);
780   return nSupMod;
781
782
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
786 {
787   // Transition from cell indexes (ieta,iphi) to module indexes (ietam,iphim, nModule)
788   static Int_t nphi;
789   nphi  = GetNumberOfModuleInPhiDirection(nSupMod);  
790
791   ietam  = ieta/fNETAdiv;
792   iphim  = iphi/fNPHIdiv;
793   nModule = ietam * nphi + iphim; 
794 }
795
796 //________________________________________________________________________________________________
797 Int_t  AliEMCALGeometry::GetAbsCellIdFromCellIndexes(Int_t nSupMod, Int_t iphi, Int_t ieta) const
798 {
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
802
803   GetModuleIndexesFromCellIndexesInSModule(nSupMod, iphi, ieta, ietam, iphim, nModule);
804
805   nIeta = ieta%fNETAdiv;
806   nIeta = fNETAdiv - 1 - nIeta;
807   nIphi = iphi%fNPHIdiv;
808
809   return GetAbsCellId(nSupMod, nModule, nIphi, nIeta);
810 }
811
812
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
816 {
817   // Look to see what the relative
818   // position inside a given cell is
819   // for a recpoint.
820   // Alice numbering scheme - Jun 08, 2006
821   // In:
822   // absId   - cell is as in Geant,     0<= absId   < fNCells;
823   // OUT:
824   // xr,yr,zr - x,y,z coordinates of cell with absId inside SM 
825
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;
831
832   GetCellIndex(absId, nSupMod, nModule, nIphi, nIeta);
833   GetCellPhiEtaIndexInSModule(nSupMod,nModule,nIphi,nIeta, iphi, ieta); 
834  
835   xr = fCentersOfCellsXDir.At(ieta);
836   zr = fCentersOfCellsEtaDir.At(ieta);
837
838   if(nSupMod<10) {
839     yr = fCentersOfCellsPhiDir.At(iphi);
840   } else {
841     yr = fCentersOfCellsPhiDir.At(iphi + kphiIndexShift);
842   }
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));
844
845   return kTRUE;
846 }
847
848 //________________________________________________________________________________________________
849 Bool_t AliEMCALGeometry::RelPosCellInSModule(Int_t absId, Double_t loc[3]) const
850 {
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])) {
854     return kTRUE;
855   }
856   return kFALSE;
857 }
858
859 //________________________________________________________________________________________________
860 Bool_t AliEMCALGeometry::RelPosCellInSModule(Int_t absId, TVector3 &vloc) const
861 {
862   static Double_t loc[3];
863   if(RelPosCellInSModule(absId,loc)) {
864     vloc.SetXYZ(loc[0], loc[1], loc[2]);
865     return kTRUE;
866   } else {
867     vloc.SetXYZ(0,0,0);
868     return kFALSE;
869   }
870   // Alice numbering scheme - Jun 03, 2006
871 }
872
873 //________________________________________________________________________________________________
874 Bool_t AliEMCALGeometry::RelPosCellInSModule(Int_t absId, Double_t distEff, Double_t &xr, Double_t &yr, Double_t &zr) const
875 {
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
879   // for a recpoint.
880   // In:
881   // absId   - cell is as in Geant,     0<= absId   < fNCells;
882   // e       - cluster energy
883   // OUT:
884   // xr,yr,zr - x,y,z coordinates of cell with absId inside SM 
885
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;
892   static TVector2 v;
893   if(!CheckAbsCellId(absId)) return kFALSE;
894
895   GetCellIndex(absId, nSupMod, nModule, nIphi, nIeta);
896   GetModulePhiEtaIndexInSModule(nSupMod, nModule, iphim, ietam);
897   GetCellPhiEtaIndexInSModule(nSupMod,nModule,nIphi,nIeta, iphi, ieta); 
898  
899   mod = GetShishKebabModule(ietam);
900   mod->GetPositionAtCenterCellLine(nIeta, distEff, v); 
901   xr = v.Y() - fParSM[0];
902   zr = v.X() - fParSM[2];
903
904   if(nSupMod<10) {
905     yr = fCentersOfCellsPhiDir.At(iphi);
906   } else {
907     yr = fCentersOfCellsPhiDir.At(iphi + kphiIndexShift);
908   }
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));
910
911   return kTRUE;
912 }
913
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
916 {
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
920   // for a recpoint.
921   // In:
922   // absId     - cell is as in Geant,     0<= absId   < fNCells;
923   // maxAbsId  - abs id of cell with highest energy
924   // e         - cluster energy
925   // OUT:
926   // xr,yr,zr - x,y,z coordinates of cell with absId inside SM 
927
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;
934   static TVector2 v;
935
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;
940
941   if(!CheckAbsCellId(absId)) return kFALSE;
942
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);
947
948   if(absId != maxAbsId) {
949     distCorr = 0.;
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;
956     }
957     if(ietamM !=0) {
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);  
960     }
961     // distEff += distCorr;
962   }
963   // Bad resolution in this case, strong bias vs phi
964   // distEff = 0.0; 
965   mod->GetPositionAtCenterCellLine(nIeta, distEff, v); // Stay here
966   xr = v.Y() - fParSM[0];
967   zr = v.X() - fParSM[2];
968
969   if(nSupMod<10) {
970     yr = fCentersOfCellsPhiDir.At(iphi);
971   } else {
972     yr = fCentersOfCellsPhiDir.At(iphi + kphiIndexShift);
973   }
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));
975
976   return kTRUE;
977 }
978
979 //________________________________________________________________________________________________
980 void AliEMCALGeometry::CreateListOfTrd1Modules()
981 {
982   // Generate the list of Trd1 modules
983   // which will make up the EMCAL
984   // geometry
985
986   AliDebug(2,Form(" AliEMCALGeometry::CreateListOfTrd1Modules() started "));
987
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++) { 
993       if(iz==0) { 
994         mod  = new AliEMCALShishKebabTrd1Module(TMath::Pi()/2.,this);
995       } else {
996         mTmp  = new AliEMCALShishKebabTrd1Module(*mod);
997         mod   = mTmp;
998       }
999       fShishKebabTrd1Modules->Add(mod);
1000     }
1001   } else {
1002     AliDebug(2,Form(" Already exits : "));
1003   }
1004   mod = (AliEMCALShishKebabTrd1Module*)fShishKebabTrd1Modules->At(fShishKebabTrd1Modules->GetSize()-1);
1005   fEtaMaxOfTRD1 = mod->GetMaxEtaOfModule(0);
1006
1007   AliDebug(2,Form(" fShishKebabTrd1Modules has %i modules : max eta %5.4f \n", 
1008                   fShishKebabTrd1Modules->GetSize(),fEtaMaxOfTRD1));
1009   // Feb 20,2006;
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
1013   // 
1014   //
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
1017   // 
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;
1022   TVector3 vglob;
1023   Double_t ytCenterModule=0.0, ytCenterCell=0.0;
1024
1025   fCentersOfCellsPhiDir.Set(fNPhi*fNPHIdiv);
1026   fPhiCentersOfCells.Set(fNPhi*fNPHIdiv);
1027
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
1032       if(fNPHIdiv==2) {
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;
1038       }
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);
1045
1046       AliDebug(2,Form(" ind %2.2i : y %8.3f ", ind, fCentersOfCellsPhiDir.At(ind))); 
1047       ind++;
1048     }
1049   }
1050
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);
1057     nModule = fNPhi*it;
1058     for(Int_t ic=0; ic<fNETAdiv; ic++) {
1059       if(fNPHIdiv==2) {
1060         trd1->GetCenterOfCellInLocalCoordinateofSM(ic, xr, zr);      // case of 2X2
1061         GetCellPhiEtaIndexInSModule(0, nModule, 0, ic, iphiTemp, ieta); 
1062       } if(fNPHIdiv==3) {
1063         trd1->GetCenterOfCellInLocalCoordinateofSM_3X3(ic, xr, zr);  // case of 3X3
1064         GetCellPhiEtaIndexInSModule(0, nModule, 0, ic, iphiTemp, ieta); 
1065       } if(fNPHIdiv==1) {
1066         trd1->GetCenterOfCellInLocalCoordinateofSM_1X1(xr, zr);      // case of 1X1
1067         GetCellPhiEtaIndexInSModule(0, nModule, 0, ic, iphiTemp, ieta); 
1068       }
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);
1081       }
1082       //printf(" ieta %i : xr + trd1->GetRadius() %f : zr %f : eta %f \n", ieta, xr + trd1->GetRadius(), zr, eta);
1083     }
1084   }
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)));
1088   }
1089
1090 }
1091
1092 //________________________________________________________________________________________________
1093 void AliEMCALGeometry::GetGlobal(const Double_t *loc, Double_t *glob, int ind) const
1094 {
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
1099   // geometry)
1100
1101   if(ind>=0 && ind < GetNumberOfSuperModules()) {
1102     TString volpath = "ALIC_1/XEN1_1/SMOD_";
1103     volpath += ind+1;
1104
1105     if(GetKey110DEG() && ind>=10) {
1106       volpath = "ALIC_1/XEN1_1/SM10_";
1107       volpath += ind-10+1;
1108     }
1109
1110     if(!gGeoManager->cd(volpath.Data()))
1111       AliFatal(Form("AliEMCALGeometry::GeoManager cannot find path %s!",volpath.Data()));
1112
1113     TGeoHMatrix* m = gGeoManager->GetCurrentMatrix();
1114     if(m) {
1115       m->LocalToMaster(loc, glob);
1116     } else {
1117       AliFatal("Geo matrixes are not loaded \n") ;
1118     }
1119   }
1120 }
1121
1122 //________________________________________________________________________________________________
1123 void AliEMCALGeometry::GetGlobal(const TVector3 &vloc, TVector3 &vglob, int ind) const
1124 {
1125   //Figure out the global numbering
1126   //of a given supermodule from the
1127   //local numbering given a 3-vector location
1128
1129   static Double_t tglob[3], tloc[3];
1130   vloc.GetXYZ(tloc);
1131   GetGlobal(tloc, tglob, ind);
1132   vglob.SetXYZ(tglob[0], tglob[1], tglob[2]);
1133 }
1134
1135 //________________________________________________________________________________________________
1136 void AliEMCALGeometry::GetGlobal(Int_t absId , double glob[3]) const
1137
1138   // Alice numbering scheme - Jun 03, 2006
1139   static Int_t nSupMod, nModule, nIphi, nIeta;
1140   static double loc[3];
1141
1142   if (!gGeoManager || !gGeoManager->IsClosed()) {
1143     AliError("Can't get the global coordinates! gGeoManager doesn't exist or it is still open!");
1144     return;
1145   }
1146
1147   glob[0]=glob[1]=glob[2]=0.0; // bad case
1148   if(RelPosCellInSModule(absId, loc)) {
1149     GetCellIndex(absId, nSupMod, nModule, nIphi, nIeta);
1150
1151     TString volpath = "ALIC_1/XEN1_1/SMOD_";
1152     volpath += (nSupMod+1);
1153
1154     if(GetKey110DEG() && nSupMod>=10) {
1155       volpath = "ALIC_1/XEN1_1/SM10_";
1156       volpath += (nSupMod-10+1);
1157     }
1158     if(!gGeoManager->cd(volpath.Data()))
1159       AliFatal(Form("GeoManager cannot find path %s!",volpath.Data()));
1160
1161     TGeoHMatrix* m = gGeoManager->GetCurrentMatrix();
1162     if(m) {
1163       m->LocalToMaster(loc, glob);
1164     } else {
1165       AliFatal("Geo matrixes are not loaded \n") ;
1166     }
1167   }
1168 }
1169
1170 //___________________________________________________________________
1171 void AliEMCALGeometry::GetGlobal(Int_t absId , TVector3 &vglob) const
1172
1173   // Alice numbering scheme - Jun 03, 2006
1174   static Double_t glob[3];
1175
1176   GetGlobal(absId, glob);
1177   vglob.SetXYZ(glob[0], glob[1], glob[2]);
1178
1179 }
1180
1181 //____________________________________________________________________________
1182 void AliEMCALGeometry::GetGlobal(const AliRecPoint* /*rp*/, TVector3& /* vglob */) const
1183 {
1184   AliFatal(Form("Please use GetGlobalEMCAL(recPoint,gpos) instead of GetGlobal!"));
1185 }
1186
1187 //_________________________________________________________________________________
1188 void AliEMCALGeometry::GetGlobalEMCAL(const AliEMCALRecPoint *rp, TVector3 &vglob) const
1189 {
1190   // Figure out the global numbering
1191   // of a given supermodule from the
1192   // local numbering for RecPoints
1193
1194   static TVector3 vloc;
1195   static Int_t nSupMod, nModule, nIphi, nIeta;
1196
1197   const AliEMCALRecPoint *rpTmp = rp;
1198   const AliEMCALRecPoint *rpEmc = rpTmp;
1199
1200   GetCellIndex(rpEmc->GetAbsId(0), nSupMod, nModule, nIphi, nIeta);
1201   rpTmp->GetLocalPosition(vloc);
1202   GetGlobal(vloc, vglob, nSupMod);
1203 }
1204
1205 //________________________________________________________________________________________________
1206 void AliEMCALGeometry::EtaPhiFromIndex(Int_t absId,Double_t &eta,Double_t &phi) const
1207 {
1208   // Nov 16, 2006- float to double
1209   // version for TRD1 only
1210   static TVector3 vglob;
1211   GetGlobal(absId, vglob);
1212   eta = vglob.Eta();
1213   phi = vglob.Phi();
1214 }
1215
1216 //________________________________________________________________________________________________
1217 void AliEMCALGeometry::EtaPhiFromIndex(Int_t absId,Float_t &eta,Float_t &phi) const
1218 {
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());
1224 }
1225
1226 //________________________________________________________________________________________________
1227 Bool_t AliEMCALGeometry::GetPhiBoundariesOfSM(Int_t nSupMod, Double_t &phiMin, Double_t &phiMax) const
1228 {
1229   // 0<= nSupMod <=11; phi in rad
1230   static int i;
1231   if(nSupMod<0 || nSupMod >11) return kFALSE; 
1232   i = nSupMod/2;
1233   phiMin = fPhiBoundariesOfSM[2*i];
1234   phiMax = fPhiBoundariesOfSM[2*i+1];
1235   return kTRUE; 
1236 }
1237
1238 //________________________________________________________________________________________________
1239 Bool_t AliEMCALGeometry::GetPhiBoundariesOfSMGap(Int_t nPhiSec, Double_t &phiMin, Double_t &phiMax) const
1240 {
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];
1250   return kTRUE; 
1251 }
1252
1253 //________________________________________________________________________________________________
1254 Bool_t AliEMCALGeometry::SuperModuleNumberFromEtaPhi(Double_t eta, Double_t phi, Int_t &nSupMod) const
1255
1256   // Return false if phi belongs a phi cracks between SM
1257  
1258   static Int_t i;
1259
1260   if(TMath::Abs(eta) > fEtaMaxOfTRD1) return kFALSE;
1261
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]) {
1265       nSupMod = 2*i;
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));
1268       return kTRUE;
1269     }
1270   }
1271   return kFALSE;
1272 }
1273
1274 //________________________________________________________________________________________________
1275 Bool_t AliEMCALGeometry::GetAbsCellIdFromEtaPhi(Double_t eta, Double_t phi, Int_t &absId) const
1276 {
1277   // Nov 17,2006
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)) {
1283     // phi index first
1284     phi    = TVector2::Phi_0_2pi(phi);
1285     phiLoc = phi - fPhiCentersOfSM[nSupMod/2];
1286     nphi   = fPhiCentersOfCells.GetSize();
1287     if(nSupMod>=10) {
1288       phiLoc = phi - 190.*TMath::DegToRad();
1289       nphi  /= 2;
1290     }
1291
1292     dmin   = TMath::Abs(fPhiCentersOfCells[0]-phiLoc);
1293     iphi   = 0;
1294     for(i=1; i<nphi; i++) {
1295       d = TMath::Abs(fPhiCentersOfCells[i] - phiLoc);
1296       if(d < dmin) {
1297         dmin = d;
1298         iphi = i;
1299       }
1300       //      printf(" i %i : d %f : dmin %f : fPhiCentersOfCells[i] %f \n", i, d, dmin, fPhiCentersOfCells[i]);
1301     }
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));
1304     // eta index
1305     absEta   = TMath::Abs(eta);
1306     etaShift = iphi*fCentersOfCellsEtaDir.GetSize();
1307     dmin     = TMath::Abs(fEtaCentersOfCells[etaShift]-absEta);
1308     ieta     = 0;
1309     for(i=1; i<fCentersOfCellsEtaDir.GetSize(); i++) {
1310       d = TMath::Abs(fEtaCentersOfCells[i+etaShift] - absEta);
1311       if(d < dmin) {
1312         dmin = d;
1313         ieta = i;
1314       }
1315     }
1316     AliDebug(2,Form(" ieta %i : dmin %f (eta=%f) : nSupMod %i ", ieta, dmin, eta, nSupMod));
1317
1318     if(eta<0) iphi = (nphi-1) - iphi;
1319     absId = GetAbsCellIdFromCellIndexes(nSupMod, iphi, ieta);
1320
1321     return kTRUE;
1322   }
1323   return kFALSE;
1324 }
1325
1326 //________________________________________________________________________________________________
1327 AliEMCALShishKebabTrd1Module* AliEMCALGeometry::GetShishKebabModule(Int_t neta) const
1328 {
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.
1334
1335   static AliEMCALShishKebabTrd1Module* trd1=0;
1336   if(fShishKebabTrd1Modules && neta>=0 && neta<fShishKebabTrd1Modules->GetSize()) {
1337     trd1 = (AliEMCALShishKebabTrd1Module*)fShishKebabTrd1Modules->At(neta);
1338   } else trd1 = 0;
1339   return trd1;
1340 }
1341
1342 //________________________________________________________________________________________________
1343 Int_t AliEMCALGeometry::GetAbsTRUNumberFromNumberInSm(const Int_t row, const Int_t col, const Int_t sm)
1344 { // Nov 6, 2007
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); 
1347   return itru;
1348 }
1349
1350 //________________________________________________________________________________________________
1351 void AliEMCALGeometry::Browse(TBrowser* b)
1352 {
1353   //Browse the modules
1354   if(fShishKebabTrd1Modules) b->Add(fShishKebabTrd1Modules);
1355 }
1356
1357 //________________________________________________________________________________________________
1358 Bool_t AliEMCALGeometry::IsFolder() const
1359 {
1360   //Check if fShishKebabTrd1Modules is in folder
1361   if(fShishKebabTrd1Modules) return kTRUE;
1362   else                       return kFALSE;
1363 }
1364
1365 //________________________________________________________________________________________________
1366 Double_t AliEMCALGeometry::GetPhiCenterOfSM(Int_t nsupmod) const
1367 {
1368   //returns center of supermodule in phi 
1369   int i = nsupmod/2;
1370   return fPhiCentersOfSM[i];
1371
1372 }