minor corrections for calibration staff
[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 // Places the the Barrel Geometry of The EMCAL at Midrapidity
22 // between 80 and 180(or 190) degrees of Phi and
23 // -0.7 to 0.7 in eta 
24 // Number of Modules and Layers may be controlled by 
25 // the name of the instance defined               
26 //     EMCAL geometry tree:
27 //     EMCAL -> superModule -> module -> tower(cell)
28 //     Indexes
29 //     absId -> nSupMod     -> nModule -> (nIphi,nIeta)
30 //
31 //*-- Author: Sahal Yacoob (LBL / UCT)
32 //     and  : Yves Schutz (SUBATECH)
33 //     and  : Jennifer Klay (LBL)
34 //     SHASHLYK : Aleksei Pavlinov (WSU) 
35 //
36
37 #include <assert.h>
38
39 // --- AliRoot header files ---
40 #include <Riostream.h>
41 #include <TBrowser.h>
42 #include <TClonesArray.h>
43 #include <TGeoManager.h>
44 #include <TGeoMatrix.h>
45 #include <TGeoNode.h>
46 #include <TList.h>
47 #include <TMatrixD.h>
48 #include <TObjArray.h>
49 #include <TObjString.h>
50 #include <TVector2.h>
51 #include <TVector3.h>
52
53 // -- ALICE Headers.
54 #include "AliLog.h"
55
56 // --- EMCAL headers
57 #include "AliEMCALGeometry.h"
58 #include "AliEMCALShishKebabTrd1Module.h"
59 #include "AliEMCALRecPoint.h"
60 #include "AliEMCALDigit.h"
61 #include "AliEMCALHistoUtilities.h"
62
63 ClassImp(AliEMCALGeometry)
64
65 // these initialisations are needed for a singleton
66 AliEMCALGeometry  *AliEMCALGeometry::fgGeom      = 0;
67 Bool_t             AliEMCALGeometry::fgInit      = kFALSE;
68 Char_t*            AliEMCALGeometry::fgDefaultGeometryName = "SHISH_77_TRD1_2X2_FINAL_110DEG";
69 //
70 // Usage: 
71 //        You can create the AliEMCALGeometry object independently from anything.
72 //        You have to use just the correct name of geometry. If name is empty string the
73 //        default name of geometry will be used.
74 //         
75 //  AliEMCALGeometry* g = AliEMCALGeometry::GetInstance(name,title); // first time
76 //  ..
77 //  g = AliEMCALGeometry::GetInstance();                             // after first time
78 //
79 //  MC:   If you work with MC data you have to get geometry the next way: 
80 //  ==                                      =============================
81 //  AliRunLoader    *rl   = AliRunLoader::GetRunLoader();
82 // AliEMCALGeometry *geom = dynamic_cast<AliEMCAL*>(rl->GetAliRun()->GetDetector("EMCAL"))->GetGeometry();
83
84
85 AliEMCALGeometry::AliEMCALGeometry() 
86   : AliGeometry(),
87     fGeoName(0),fArrayOpts(0),fAlFrontThick(0.),fECPbRadThickness(0.),fECScintThick(0.),
88     fNECLayers(0),fArm1PhiMin(0.),fArm1PhiMax(0.),fArm1EtaMin(0.),fArm1EtaMax(0.),fIPDistance(0.),
89     fShellThickness(0.),fZLength(0.),fGap2Active(0.),fNZ(0),fNPhi(0),fSampling(0.),fNumberOfSuperModules(0),
90     fSteelFrontThick(0.),fFrontSteelStrip(0.),fLateralSteelStrip(0.),fPassiveScintThick(0.),fPhiModuleSize(0.),
91     fEtaModuleSize(0.),fPhiTileSize(0.),fEtaTileSize(0.),fLongModuleSize(0.),fNPhiSuperModule(0),fNPHIdiv(0),fNETAdiv(0),
92     fNCells(0),fNCellsInSupMod(0),fNCellsInModule(0),fNTRUEta(0),fNTRUPhi(0),
93     fNCellsInTRUEta(0), fNCellsInTRUPhi(0), fTrd1Angle(0.),f2Trd1Dx2(0.),
94     fPhiGapForSM(0.),fKey110DEG(0),fPhiBoundariesOfSM(0), fPhiCentersOfSM(0),fEtaMaxOfTRD1(0),
95     fTrd2AngleY(0.),f2Trd2Dy2(0.),fEmptySpace(0.),fTubsR(0.),fTubsTurnAngle(0.),fCentersOfCellsEtaDir(0),
96     fCentersOfCellsXDir(0),fCentersOfCellsPhiDir(0),fEtaCentersOfCells(0),fPhiCentersOfCells(0),
97     fShishKebabTrd1Modules(0), fNAdditionalOpts(0),
98     fILOSS(-1), fIHADR(-1) 
99
100   // default ctor only for internal usage (singleton)
101   // must be kept public for root persistency purposes, but should never be called by the outside world    
102   //  CreateListOfTrd1Modules();
103   AliDebug(2, "AliEMCALGeometry : default ctor ");
104 }
105 //______________________________________________________________________
106 AliEMCALGeometry::AliEMCALGeometry(const Text_t* name, const Text_t* title) 
107   : AliGeometry(name, title),
108     fGeoName(0),fArrayOpts(0),fAlFrontThick(0.),fECPbRadThickness(0.),fECScintThick(0.),
109     fNECLayers(0),fArm1PhiMin(0.),fArm1PhiMax(0.),fArm1EtaMin(0.),fArm1EtaMax(0.),fIPDistance(0.),
110     fShellThickness(0.),fZLength(0.),fGap2Active(0.),fNZ(0),fNPhi(0),fSampling(0.),fNumberOfSuperModules(0),
111     fSteelFrontThick(0.),fFrontSteelStrip(0.),fLateralSteelStrip(0.),fPassiveScintThick(0.),fPhiModuleSize(0.),
112     fEtaModuleSize(0.),fPhiTileSize(0.),fEtaTileSize(0.),fLongModuleSize(0.),fNPhiSuperModule(0),fNPHIdiv(0),fNETAdiv(0),
113     fNCells(0),fNCellsInSupMod(0),fNCellsInModule(0),fNTRUEta(0),fNTRUPhi(0),
114     fNCellsInTRUEta(0), fNCellsInTRUPhi(0), fTrd1Angle(0.),f2Trd1Dx2(0.),
115     fPhiGapForSM(0.),fKey110DEG(0),fPhiBoundariesOfSM(0), fPhiCentersOfSM(0), fEtaMaxOfTRD1(0),
116     fTrd2AngleY(0.),f2Trd2Dy2(0.),fEmptySpace(0.),fTubsR(0.),fTubsTurnAngle(0.),fCentersOfCellsEtaDir(0),
117     fCentersOfCellsXDir(0),fCentersOfCellsPhiDir(0),fEtaCentersOfCells(0),fPhiCentersOfCells(0),
118     fShishKebabTrd1Modules(0),fNAdditionalOpts(0),
119     fILOSS(-1), fIHADR(-1) 
120 {
121   // ctor only for internal usage (singleton)
122   AliDebug(2, Form("AliEMCALGeometry(%s,%s) ", name,title));
123
124   Init();
125
126   CreateListOfTrd1Modules();
127
128   if (AliDebugLevel()>=2) {
129     PrintGeometry();
130   }
131
132 }
133 //______________________________________________________________________
134 AliEMCALGeometry::AliEMCALGeometry(const AliEMCALGeometry& geom)
135   : AliGeometry(geom),
136     fGeoName(geom.fGeoName),
137     fArrayOpts(geom.fArrayOpts),
138     fAlFrontThick(geom.fAlFrontThick),
139     fECPbRadThickness(geom.fECPbRadThickness),
140     fECScintThick(geom.fECScintThick),
141     fNECLayers(geom.fNECLayers),
142     fArm1PhiMin(geom.fArm1PhiMin),
143     fArm1PhiMax(geom.fArm1PhiMax),
144     fArm1EtaMin(geom.fArm1EtaMin),
145     fArm1EtaMax(geom.fArm1EtaMax),
146     fIPDistance(geom.fIPDistance),
147     fShellThickness(geom.fShellThickness),
148     fZLength(geom.fZLength),
149     fGap2Active(geom.fGap2Active),
150     fNZ(geom.fNZ),
151     fNPhi(geom.fNPhi),
152     fSampling(geom.fSampling),
153     fNumberOfSuperModules(geom.fNumberOfSuperModules),
154     fSteelFrontThick(geom.fSteelFrontThick),
155     fFrontSteelStrip(geom.fFrontSteelStrip),
156     fLateralSteelStrip(geom.fLateralSteelStrip),
157     fPassiveScintThick(geom.fPassiveScintThick),
158     fPhiModuleSize(geom.fPhiModuleSize),
159     fEtaModuleSize(geom.fEtaModuleSize),
160     fPhiTileSize(geom.fPhiTileSize),
161     fEtaTileSize(geom.fEtaTileSize),
162     fLongModuleSize(geom.fLongModuleSize),
163     fNPhiSuperModule(geom.fNPhiSuperModule),
164     fNPHIdiv(geom.fNPHIdiv),
165     fNETAdiv(geom.fNETAdiv),
166     fNCells(geom.fNCells),
167     fNCellsInSupMod(geom.fNCellsInSupMod),
168     fNCellsInModule(geom.fNCellsInModule),
169     fNTRUEta(geom.fNTRUEta),
170     fNTRUPhi(geom.fNTRUPhi),
171     fNCellsInTRUEta(geom.fNCellsInTRUEta),
172     fNCellsInTRUPhi(geom.fNCellsInTRUPhi),
173     fTrd1Angle(geom.fTrd1Angle),
174     f2Trd1Dx2(geom.f2Trd1Dx2),
175     fPhiGapForSM(geom.fPhiGapForSM),
176     fKey110DEG(geom.fKey110DEG),
177     fPhiBoundariesOfSM(geom.fPhiBoundariesOfSM),
178     fPhiCentersOfSM(geom.fPhiCentersOfSM),
179     fEtaMaxOfTRD1(geom.fEtaMaxOfTRD1),
180     fTrd2AngleY(geom.fTrd2AngleY),
181     f2Trd2Dy2(geom.f2Trd2Dy2),
182     fEmptySpace(geom.fEmptySpace),
183     fTubsR(geom.fTubsR),
184     fTubsTurnAngle(geom.fTubsTurnAngle),
185     fCentersOfCellsEtaDir(geom.fCentersOfCellsEtaDir),
186     fCentersOfCellsXDir(geom.fCentersOfCellsXDir),
187     fCentersOfCellsPhiDir(geom.fCentersOfCellsPhiDir),
188     fEtaCentersOfCells(geom.fEtaCentersOfCells),
189     fPhiCentersOfCells(geom.fPhiCentersOfCells),
190     fShishKebabTrd1Modules(geom.fShishKebabTrd1Modules),
191     fNAdditionalOpts(geom.fNAdditionalOpts),
192     fILOSS(geom.fILOSS), fIHADR(geom.fIHADR) 
193 {
194   //copy ctor
195 }
196
197 //______________________________________________________________________
198 AliEMCALGeometry::~AliEMCALGeometry(void){
199     // dtor
200 }
201 //______________________________________________________________________
202 void AliEMCALGeometry::Init(void){
203   // Initializes the EMCAL parameters
204   // naming convention : GUV_WX_N_ gives the composition of a tower
205   // WX inform about the composition of the EM calorimeter section: 
206   //   thickness in mm of Pb radiator (W) and of scintillator (X), and number of scintillator layers (N)
207   // New geometry: EMCAL_55_25
208   // 24-aug-04 for shish-kebab
209   // SHISH_25 or SHISH_62
210   // 11-oct-05   - correction for pre final design
211   // Feb 06,2006 - decrease the weight of EMCAL
212   //
213   // Oct 30,2006 - SHISH_TRD1_CURRENT_1X1, SHISH_TRD1_CURRENT_2X2 or SHISH_TRD1_CURRENT_3X3;
214   //
215
216   fAdditionalOpts[0] = "nl=";       // number of sampling layers (fNECLayers)
217   fAdditionalOpts[1] = "pbTh=";     // cm, Thickness of the Pb   (fECPbRadThick)
218   fAdditionalOpts[2] = "scTh=";     // cm, Thickness of the Sc    (fECScintThick)
219   fAdditionalOpts[3] = "latSS=";    // cm, Thickness of lateral steel strip (fLateralSteelStrip)
220   fAdditionalOpts[4] = "allILOSS="; // = 0,1,2,3,4 (4 - energy loss without fluctuation)
221   fAdditionalOpts[5] = "allIHADR="; // = 0,1,2 (0 - no hadronic interaction)
222
223   fNAdditionalOpts = sizeof(fAdditionalOpts) / sizeof(char*);
224
225   fgInit = kFALSE; // Assume failed until proven otherwise.
226   fGeoName   = GetName();
227   fGeoName.ToUpper();
228   fKey110DEG = 0;
229   if(fGeoName.Contains("110DEG") || fGeoName.Contains("CURRENT")) fKey110DEG = 1; // for GetAbsCellId
230   fShishKebabTrd1Modules = 0;
231   fTrd2AngleY = f2Trd2Dy2 = fEmptySpace = fTubsR = fTubsTurnAngle = 0;
232
233   fNZ             = 114;        // granularity along Z (eta) 
234   fNPhi           = 168;        // granularity in phi (azimuth)
235   fArm1PhiMin     = 80.0;       // degrees, Starting EMCAL Phi position
236   fArm1PhiMax     = 190.0;      // degrees, Ending EMCAL Phi position
237   fArm1EtaMin     = -0.7;       // pseudorapidity, Starting EMCAL Eta position
238   fArm1EtaMax     = +0.7;       // pseudorapidity, Ending EMCAL Eta position
239   fIPDistance     = 454.0;      // cm, Radial distance to inner surface of EMCAL
240   fPhiGapForSM    = 0.;         // cm, only for final TRD1 geometry
241   for(int i=0; i<12; i++) fMatrixOfSM[i] = 0;
242
243   // geometry
244   if(fGeoName.Contains("SHISH")){ // Only shahslyk now
245     // 7-sep-05; integration issue
246     fArm1PhiMin     = 80.0;     // 60  -> 80
247     fArm1PhiMax     = 180.0;    // 180 -> 190
248
249     fNumberOfSuperModules = 10; // 12 = 6 * 2 (6 in phi, 2 in Z);
250     fSteelFrontThick = 2.54;    //  9-sep-04
251     fIPDistance      = 460.0;
252     fFrontSteelStrip = fPassiveScintThick = 0.0; // 13-may-05
253     fLateralSteelStrip = 0.025; // before MAY 2005 
254     fPhiModuleSize   = fEtaModuleSize   = 11.4;
255     fPhiTileSize = fEtaTileSize      = 5.52; // (11.4-5.52*2)/2. = 0.18 cm (wall thickness)
256     fNPhi            = 14;
257     fNZ              = 30;
258     fAlFrontThick    = fGap2Active = 0;
259     fNPHIdiv = fNETAdiv = 2;
260
261     fNECLayers       = 62;
262     fECScintThick    = fECPbRadThickness = 0.2;
263     fSampling        = 1.;  // 30-aug-04 - should be calculated
264     if(fGeoName.Contains("TWIST")) { // all about EMCAL module
265       fNZ             = 27;  // 16-sep-04
266     } else if(fGeoName.Contains("TRD")) {
267       fIPDistance      = 428.0;  //  11-may-05
268       fSteelFrontThick = 0.0;    // 3.17 -> 0.0; 28-mar-05 : no stell plate
269       fNPhi            = 12;
270       fSampling       = 12.327;
271       fPhiModuleSize = fEtaModuleSize = 12.26;
272       fNZ            = 26;     // 11-oct-04
273       fTrd1Angle     = 1.3;    // in degree
274 // 18-nov-04; 1./0.08112=12.327
275 // http://pdsfweb01.nersc.gov/~pavlinov/ALICE/SHISHKEBAB/RES/linearityAndResolutionForTRD1.html
276       if(fGeoName.Contains("TRD1")) {       // 30-jan-05
277         // for final design
278         fPhiGapForSM    = 2.;         // cm, only for final TRD1 geometry
279         if(fGeoName.Contains("MAY05") || fGeoName.Contains("WSUC") || fGeoName.Contains("FINAL") || fGeoName.Contains("CURRENT")){
280           fNumberOfSuperModules = 12; // 20-may-05
281           if(fGeoName.Contains("WSUC")) fNumberOfSuperModules = 1; // 27-may-05
282           fNECLayers     = 77;       // (13-may-05 from V.Petrov)
283           fPhiModuleSize = 12.5;     // 20-may-05 - rectangular shape
284           fEtaModuleSize = 11.9;
285           fECScintThick  = fECPbRadThickness = 0.16;// (13-may-05 from V.Petrov)
286           fFrontSteelStrip   = 0.025;// 0.025cm = 0.25mm  (13-may-05 from V.Petrov)
287           fLateralSteelStrip = 0.01; // 0.01cm  = 0.1mm   (13-may-05 from V.Petrov) - was 0.025
288           fPassiveScintThick = 0.8;  // 0.8cm   = 8mm     (13-may-05 from V.Petrov)
289           fNZ                = 24;
290           fTrd1Angle         = 1.5;  // 1.3 or 1.5
291
292           if(fGeoName.Contains("FINAL") || fGeoName.Contains("CURRENT")) { // 9-sep-05
293             fNumberOfSuperModules = 10;
294             if(GetKey110DEG()) {
295               fNumberOfSuperModules = 12;// last two modules have size 10 degree in phi (180<phi<190)
296               fArm1PhiMax = 200.0;       // for XEN1 and turn angle of super modules
297             }
298             if(fGeoName.Contains("FINAL")) {
299               fPhiModuleSize = 12.26 - fPhiGapForSM / Float_t(fNPhi); // first assumption
300             } else if(fGeoName.Contains("CURRENT")) {
301               fECScintThick      = 0.176; // 10% of weight reduction
302               fECPbRadThickness  = 0.144; //
303               fLateralSteelStrip = 0.015; // 0.015cm  = 0.15mm (Oct 30, from Fred)
304               fPhiModuleSize     = 12.00;
305               fPhiGapForSM       = (12.26 - fPhiModuleSize)*fNPhi; // have to check
306             }
307             fEtaModuleSize = fPhiModuleSize;
308             if(fGeoName.Contains("HUGE")) fNECLayers *= 3; // 28-oct-05 for analysing leakage    
309           }
310         }
311       } else if(fGeoName.Contains("TRD2")) {       // 30-jan-05
312         fSteelFrontThick = 0.0;         // 11-mar-05
313         fIPDistance+= fSteelFrontThick; // 1-feb-05 - compensate absence of steel plate
314         fTrd1Angle  = 1.64;             // 1.3->1.64
315         fTrd2AngleY = fTrd1Angle;       //  symmetric case now
316         fEmptySpace    = 0.2; // 2 mm
317         fTubsR         = fIPDistance; // 31-jan-05 - as for Fred case
318
319         fPhiModuleSize  = fTubsR*2.*TMath::Tan(fTrd2AngleY*TMath::DegToRad()/2.);
320         fPhiModuleSize -= fEmptySpace/2.; // 11-mar-05  
321         fEtaModuleSize  = fPhiModuleSize; // 20-may-05 
322         fTubsTurnAngle  = 3.;
323       }
324       fNPHIdiv = fNETAdiv  = 2;   // 13-oct-04 - division again
325       if(fGeoName.Contains("3X3")) {   // 23-nov-04
326         fNPHIdiv = fNETAdiv  = 3;
327       } else if(fGeoName.Contains("4X4")) {
328         fNPHIdiv = fNETAdiv  = 4;
329       } else if(fGeoName.Contains("1X1")) {
330         fNPHIdiv = fNETAdiv  = 1;
331       }
332     }
333     if(fGeoName.Contains("25")){
334       fNECLayers     = 25;
335       fECScintThick  = fECPbRadThickness = 0.5;
336     }
337     if(fGeoName.Contains("WSUC")){ // 18-may-05 - about common structure
338       fShellThickness = 30.;       // should be change 
339       fNPhi = fNZ = 4; 
340     }
341
342     CheckAdditionalOptions();
343     DefineSamplingFraction();
344
345     fPhiTileSize = fPhiModuleSize/double(fNPHIdiv) - fLateralSteelStrip; // 13-may-05 
346     fEtaTileSize = fEtaModuleSize/double(fNETAdiv) - fLateralSteelStrip; // 13-may-05 
347
348     // constant for transition absid <--> indexes
349     fNCellsInModule  = fNPHIdiv*fNETAdiv;
350     fNCellsInSupMod = fNCellsInModule*fNPhi*fNZ;
351     fNCells         = fNCellsInSupMod*fNumberOfSuperModules;
352     if(GetKey110DEG()) fNCells -= fNCellsInSupMod;
353
354     fLongModuleSize = fNECLayers*(fECScintThick + fECPbRadThickness);
355     if(fGeoName.Contains("MAY05")) fLongModuleSize += (fFrontSteelStrip + fPassiveScintThick);
356
357     // 30-sep-04
358     if(fGeoName.Contains("TRD")) {
359       f2Trd1Dx2 = fEtaModuleSize + 2.*fLongModuleSize*TMath::Tan(fTrd1Angle*TMath::DegToRad()/2.);
360       if(fGeoName.Contains("TRD2")) {  // 27-jan-05
361         f2Trd2Dy2 = fPhiModuleSize + 2.*fLongModuleSize*TMath::Tan(fTrd2AngleY*TMath::DegToRad()/2.);
362       }
363     }
364   } else Fatal("Init", "%s is an undefined geometry!", fGeoName.Data()) ; 
365
366   fNPhiSuperModule = fNumberOfSuperModules/2;
367   if(fNPhiSuperModule<1) fNPhiSuperModule = 1;
368
369   fShellThickness = fAlFrontThick + fGap2Active + fNECLayers*GetECScintThick()+(fNECLayers-1)*GetECPbRadThick();
370   if(fGeoName.Contains("SHISH")) {
371     fShellThickness = fSteelFrontThick + fLongModuleSize;
372     if(fGeoName.Contains("TWIST")) { // 13-sep-04
373       fShellThickness  = TMath::Sqrt(fLongModuleSize*fLongModuleSize + fPhiModuleSize*fEtaModuleSize);
374       fShellThickness += fSteelFrontThick;
375     } else if(fGeoName.Contains("TRD")) { // 1-oct-04
376       fShellThickness  = TMath::Sqrt(fLongModuleSize*fLongModuleSize + f2Trd1Dx2*f2Trd1Dx2);
377       fShellThickness += fSteelFrontThick;
378       // Local coordinates
379       fParSM[0] = GetShellThickness()/2.;        
380       fParSM[1] = GetPhiModuleSize() * GetNPhi()/2.;
381       fParSM[2] = 350./2.;
382     }
383   }
384
385   fZLength        = 2.*ZFromEtaR(fIPDistance+fShellThickness,fArm1EtaMax); // Z coverage
386   fEnvelop[0]     = fIPDistance; // mother volume inner radius
387   fEnvelop[1]     = fIPDistance + fShellThickness; // mother volume outer r.
388   fEnvelop[2]     = 1.00001*fZLength; // add some padding for mother volume. 
389
390   fNumberOfSuperModules = 12;
391
392   // SM phi boundaries - (0,1),(2,3) .. (10,11) - has the same boundaries; Nov 7, 2006 
393   fPhiBoundariesOfSM.Set(fNumberOfSuperModules);
394   fPhiCentersOfSM.Set(fNumberOfSuperModules/2);
395   fPhiBoundariesOfSM[0] = TMath::PiOver2() - TMath::ATan2(fParSM[1] , fIPDistance); // 1th and 2th modules)
396   fPhiBoundariesOfSM[1] = TMath::PiOver2() + TMath::ATan2(fParSM[1] , fIPDistance);
397   fPhiCentersOfSM[0]     = TMath::PiOver2();
398   for(int i=1; i<=4; i++) { // from 2th ro 9th
399     fPhiBoundariesOfSM[2*i]   = fPhiBoundariesOfSM[0] + 20.*TMath::DegToRad()*i;
400     fPhiBoundariesOfSM[2*i+1] = fPhiBoundariesOfSM[1] + 20.*TMath::DegToRad()*i;
401     fPhiCentersOfSM[i]         = fPhiCentersOfSM[0]     + 20.*TMath::DegToRad()*i;
402   }
403   fPhiBoundariesOfSM[11] = 190.*TMath::DegToRad();
404   fPhiBoundariesOfSM[10] = fPhiBoundariesOfSM[11] - TMath::ATan2((fParSM[1]) , fIPDistance);
405   fPhiCentersOfSM[5]      = (fPhiBoundariesOfSM[10]+fPhiBoundariesOfSM[11])/2.; 
406
407   //TRU parameters. These parameters values are not the final ones.
408   fNTRUEta = 3 ;
409   fNTRUPhi = 1 ;
410   fNCellsInTRUEta = 16 ;
411   fNCellsInTRUPhi = 24 ;
412
413       // Define TGeoMatrix of SM - Jan 19, 2007 (just fro TRD1)
414   if(fGeoName.Contains("TRD1")) { // copy code from  AliEMCALv0::CreateSmod()
415     int nphism  = GetNumberOfSuperModules()/2;
416     double dphi = (GetArm1PhiMax() - GetArm1PhiMin())/nphism;
417     double rpos = (GetEnvelop(0) + GetEnvelop(1))/2.;
418     double phi, phiRad, xpos, ypos, zpos;
419     for(int i=0; i<nphism; i++){
420        phi    = GetArm1PhiMin() + dphi*(2*i+1)/2.; // phi= 90, 110, 130, 150, 170, 190
421        phiRad = phi*TMath::Pi()/180.;
422        xpos = rpos * TMath::Cos(phiRad);
423        ypos = rpos * TMath::Sin(phiRad);
424        zpos = fParSM[2];
425        if(i==5) {
426          xpos += (fParSM[1]/2. * TMath::Sin(phiRad)); 
427          ypos -= (fParSM[1]/2. * TMath::Cos(phiRad));
428        }
429        // pozitive z
430        int ind = 2*i;
431        TGeoRotation *geoRot0 = new TGeoRotation("geoRot0", 90.0, phi, 90.0, 90.0+phi, 0.0, 0.0);
432        fMatrixOfSM[ind] = new TGeoCombiTrans(Form("EmcalSM%2.2i",ind),
433                                                  xpos,ypos, zpos, geoRot0);
434        // negaive z
435        ind++;
436        double phiy = 90. + phi + 180.;
437        if(phiy>=360.) phiy -= 360.;
438        TGeoRotation *geoRot1 = new TGeoRotation("geoRot1", 90.0, phi, 90.0, phiy, 180.0, 0.0);
439        fMatrixOfSM[ind] = new TGeoCombiTrans(Form("EmcalSM%2.2i",ind),
440                                            xpos,ypos,-zpos, geoRot1);
441     } // for
442   }
443
444   if(fGeoName.Contains("WSUC")) fNumberOfSuperModules = 1; // Jul 12, 2007
445
446   fgInit = kTRUE; 
447   AliInfo(" is ended");  
448 }
449
450 void AliEMCALGeometry::PrintGeometry()
451 {
452   // Separate routine is callable from broswer; Nov 7,2006
453   printf("\nInit: geometry of EMCAL named %s :\n", fGeoName.Data());
454   if(fArrayOpts) {
455     for(Int_t i=0; i<fArrayOpts->GetEntries(); i++){
456       TObjString *o = (TObjString*)fArrayOpts->At(i);
457       printf(" %i : %s \n", i, o->String().Data());
458     }
459   }
460   printf("Granularity: %d in eta and %d in phi\n", GetNZ(), GetNPhi()) ;
461   printf("Layout: phi = (%7.1f, %7.1f), eta = (%5.2f, %5.2f), IP = %7.2f -> for EMCAL envelope only\n",  
462            GetArm1PhiMin(), GetArm1PhiMax(),GetArm1EtaMin(), GetArm1EtaMax(), GetIPDistance() );
463
464   printf( "               ECAL      : %d x (%f cm Pb, %f cm Sc) \n", 
465   GetNECLayers(), GetECPbRadThick(), GetECScintThick() ) ; 
466   printf("                fSampling %5.2f \n",  fSampling );
467   if(fGeoName.Contains("SHISH")){
468     printf(" fIPDistance       %6.3f cm \n", fIPDistance);
469     if(fSteelFrontThick>0.) 
470     printf(" fSteelFrontThick  %6.3f cm \n", fSteelFrontThick);
471     printf(" fNPhi %i   |  fNZ %i \n", fNPhi, fNZ);
472     printf(" fNCellsInModule %i : fNCellsInSupMod %i : fNCells %i\n",fNCellsInModule, fNCellsInSupMod, fNCells);
473     if(fGeoName.Contains("MAY05")){
474       printf(" fFrontSteelStrip         %6.4f cm (thickness of front steel strip)\n", 
475       fFrontSteelStrip);
476       printf(" fLateralSteelStrip       %6.4f cm (thickness of lateral steel strip)\n", 
477       fLateralSteelStrip);
478       printf(" fPassiveScintThick  %6.4f cm (thickness of front passive Sc tile)\n",
479       fPassiveScintThick);
480     }
481     printf(" X:Y module size     %6.3f , %6.3f cm \n", fPhiModuleSize, fEtaModuleSize);
482     printf(" X:Y   tile size     %6.3f , %6.3f cm \n", fPhiTileSize, fEtaTileSize);
483     printf(" #of sampling layers %i(fNECLayers) \n", fNECLayers);
484     printf(" fLongModuleSize     %6.3f cm \n", fLongModuleSize);
485     printf(" #supermodule in phi direction %i \n", fNPhiSuperModule );
486   }
487   printf(" fILOSS %i : fIHADR %i \n", fILOSS, fIHADR);
488   if(fGeoName.Contains("TRD")) {
489     printf(" fTrd1Angle %7.4f\n", fTrd1Angle);
490     printf(" f2Trd1Dx2  %7.4f\n",  f2Trd1Dx2);
491     if(fGeoName.Contains("TRD2")) {
492       printf(" fTrd2AngleY     %7.4f\n", fTrd2AngleY);
493       printf(" f2Trd2Dy2       %7.4f\n", f2Trd2Dy2);
494       printf(" fTubsR          %7.2f cm\n", fTubsR);
495       printf(" fTubsTurnAngle  %7.4f\n", fTubsTurnAngle);
496       printf(" fEmptySpace     %7.4f cm\n", fEmptySpace);
497     } else if(fGeoName.Contains("TRD1")){
498       printf("SM dimensions(TRD1) : dx %7.2f dy %7.2f dz %7.2f (SMOD, BOX)\n", 
499       fParSM[0],fParSM[1],fParSM[2]);
500       printf(" fPhiGapForSM  %7.4f cm (%7.4f <- phi size in degree)\n",  
501       fPhiGapForSM, TMath::ATan2(fPhiGapForSM,fIPDistance)*TMath::RadToDeg());
502       if(GetKey110DEG()) printf(" Last two modules have size 10 degree in  phi (180<phi<190)\n");
503       printf(" phi SM boundaries \n"); 
504       for(int i=0; i<fPhiBoundariesOfSM.GetSize()/2.; i++) {
505         printf(" %i : %7.5f(%7.2f) -> %7.5f(%7.2f) : center %7.5f(%7.2f) \n", i, 
506         fPhiBoundariesOfSM[2*i], fPhiBoundariesOfSM[2*i]*TMath::RadToDeg(),
507                fPhiBoundariesOfSM[2*i+1], fPhiBoundariesOfSM[2*i+1]*TMath::RadToDeg(),
508                fPhiCentersOfSM[i], fPhiCentersOfSM[i]*TMath::RadToDeg());
509       }
510       printf(" fShishKebabTrd1Modules has %i modules : max eta %5.4f \n", 
511                fShishKebabTrd1Modules->GetSize(),fEtaMaxOfTRD1);
512
513       printf("\n Cells grid in eta directions : size %i\n", fCentersOfCellsEtaDir.GetSize());
514       for(Int_t i=0; i<fCentersOfCellsEtaDir.GetSize(); i++) {
515         printf(" ind %2.2i : z %8.3f : x %8.3f \n", i, 
516                fCentersOfCellsEtaDir.At(i),fCentersOfCellsXDir.At(i));
517         int ind=0; // Nov 21,2006
518         for(Int_t iphi=0; iphi<fCentersOfCellsPhiDir.GetSize(); iphi++) {
519           ind = iphi*fCentersOfCellsEtaDir.GetSize() + i;
520           printf("%6.4f ", fEtaCentersOfCells[ind]);
521           if((iphi+1)%12 == 0) printf("\n");
522         }
523         printf("\n");
524
525       }
526       printf(" Matrix transformation\n");
527       for(Int_t i=0; i<12; i++) {
528         TGeoMatrix *m = fMatrixOfSM[i];
529         if(m==0) continue;
530         const double *xyz = m->GetTranslation();
531         printf(" %2.2i %s %s x %7.2f y %7.2f z %7.2f\n", 
532                i, m->GetName(), m->ClassName(), xyz[0],xyz[1],xyz[2]); 
533       }
534
535       printf("\n Cells grid in phi directions : size %i\n", fCentersOfCellsPhiDir.GetSize());
536       for(Int_t i=0; i<fCentersOfCellsPhiDir.GetSize(); i++) {
537         double phi=fPhiCentersOfCells.At(i);
538         printf(" ind %2.2i : y %8.3f : phi %7.5f(%6.2f) \n", i, fCentersOfCellsPhiDir.At(i), 
539                phi, phi*TMath::RadToDeg());
540       }
541     }
542   }
543   cout<<endl;
544 }
545
546 void AliEMCALGeometry::PrintCellIndexes(Int_t absId, int pri, char *tit)
547 {
548   // Service methods
549   Int_t nSupMod, nModule, nIphi, nIeta;
550   Int_t iphi, ieta;
551   TVector3 vg;
552
553   GetCellIndex(absId,  nSupMod, nModule, nIphi, nIeta);
554   printf(" %s | absId : %i -> nSupMod %i nModule %i nIphi %i nIeta %i \n", tit, absId,  nSupMod, nModule, nIphi, nIeta);
555   if(pri>0) {
556     GetCellPhiEtaIndexInSModule(nSupMod,nModule,nIphi,nIeta, iphi,ieta);
557     printf(" local SM index : iphi %i : ieta %i \n", iphi,ieta);
558     GetGlobal(absId, vg);
559     printf(" vglob : mag %7.2f : perp %7.2f : z %7.2f : eta %6.4f : phi %6.4f(%6.2f) \n", 
560            vg.Mag(), vg.Perp(), vg.Z(), vg.Eta(), vg.Phi(), vg.Phi()*TMath::RadToDeg());
561   }
562 }
563
564 //______________________________________________________________________
565 void AliEMCALGeometry::CheckAdditionalOptions()
566 {
567   // Feb 06,2006
568   // Additional options that
569   // can be used to select
570   // the specific geometry of 
571   // EMCAL to run
572   // Dec 27,2006
573   // adeed allILOSS= and allIHADR= for MIP investigation
574   fArrayOpts = new TObjArray;
575   Int_t nopt = AliEMCALHistoUtilities::ParseString(fGeoName, *fArrayOpts);
576   if(nopt==1) { // no aditional option(s)
577     fArrayOpts->Delete();
578     delete fArrayOpts;
579     fArrayOpts = 0; 
580     return;
581   }              
582   for(Int_t i=1; i<nopt; i++){
583     TObjString *o = (TObjString*)fArrayOpts->At(i); 
584
585     TString addOpt = o->String();
586     Int_t indj=-1;
587     for(Int_t j=0; j<fNAdditionalOpts; j++) {
588       TString opt = fAdditionalOpts[j];
589       if(addOpt.Contains(opt,TString::kIgnoreCase)) {
590           indj = j;
591         break;
592       }
593     }
594     if(indj<0) {
595       AliDebug(2,Form("<E> option |%s| unavailable : ** look to the file AliEMCALGeometry.h **\n", 
596                       addOpt.Data()));
597       assert(0);
598     } else {
599       AliDebug(2,Form("<I> option |%s| is valid : number %i : |%s|\n", 
600                       addOpt.Data(), indj, fAdditionalOpts[indj]));
601       if       (addOpt.Contains("NL=",TString::kIgnoreCase))   {// number of sampling layers
602         sscanf(addOpt.Data(),"NL=%i", &fNECLayers);
603         AliDebug(2,Form(" fNECLayers %i (new) \n", fNECLayers));
604       } else if(addOpt.Contains("PBTH=",TString::kIgnoreCase)) {//Thickness of the Pb(fECPbRadThicknes)
605         sscanf(addOpt.Data(),"PBTH=%f", &fECPbRadThickness);
606       } else if(addOpt.Contains("SCTH=",TString::kIgnoreCase)) {//Thickness of the Sc(fECScintThick)
607         sscanf(addOpt.Data(),"SCTH=%f", &fECScintThick);
608       } else if(addOpt.Contains("LATSS=",TString::kIgnoreCase)) {// Thickness of lateral steel strip (fLateralSteelStrip)
609         sscanf(addOpt.Data(),"LATSS=%f", &fLateralSteelStrip);
610         AliDebug(2,Form(" fLateralSteelStrip %f (new) \n", fLateralSteelStrip));
611       } else if(addOpt.Contains("ILOSS=",TString::kIgnoreCase)) {// As in Geant
612         sscanf(addOpt.Data(),"ALLILOSS=%i", &fILOSS);
613         AliDebug(2,Form(" fILOSS %i \n", fILOSS));
614       } else if(addOpt.Contains("IHADR=",TString::kIgnoreCase)) {// As in Geant
615         sscanf(addOpt.Data(),"ALLIHADR=%i", &fIHADR);
616         AliDebug(2,Form(" fIHADR %i \n", fIHADR));
617       }
618     }
619   }
620 }
621
622 void AliEMCALGeometry::DefineSamplingFraction()
623 {
624   // Jun 05,2006
625   // Look http://rhic.physics.wayne.edu/~pavlinov/ALICE/SHISHKEBAB/RES/linearityAndResolutionForTRD1.html
626   // Keep for compatibilty
627   //
628   if(fNECLayers == 69) {        // 10% layer reduction
629     fSampling = 12.55;
630   } else if(fNECLayers == 61) { // 20% layer reduction
631     fSampling = 12.80;
632   } else if(fNECLayers == 77) {
633     if       (fECScintThick>0.175 && fECScintThick<0.177) { // 10% Pb thicknes reduction
634       fSampling = 10.5; // fECScintThick = 0.176, fECPbRadThickness=0.144;
635     } else if(fECScintThick>0.191 && fECScintThick<0.193) { // 20% Pb thicknes reduction
636       fSampling = 8.93; // fECScintThick = 0.192, fECPbRadThickness=0.128;
637     }
638   }
639 }
640
641 //______________________________________________________________________
642 void AliEMCALGeometry::GetCellPhiEtaIndexInSModuleFromTRUIndex(const Int_t itru, const Int_t iphitru, const Int_t ietatru, Int_t &iphiSM, Int_t &ietaSM) const 
643 {
644   
645   // This method transforms the (eta,phi) index of cells in a 
646   // TRU matrix into Super Module (eta,phi) index.
647   
648   // Calculate in which row and column where the TRU are 
649   // ordered in the SM
650
651   Int_t col = itru/ fNTRUPhi ;
652   Int_t row = itru - col*fNTRUPhi ;
653    
654   iphiSM = fNCellsInTRUPhi*row + iphitru  ;
655   ietaSM = fNCellsInTRUEta*col + ietatru  ; 
656 }
657
658 //______________________________________________________________________
659 AliEMCALGeometry *  AliEMCALGeometry::GetInstance(){ 
660   // Returns the pointer of the unique instance
661   
662   AliEMCALGeometry * rv = static_cast<AliEMCALGeometry *>( fgGeom );
663   return rv; 
664 }
665
666 //______________________________________________________________________
667 AliEMCALGeometry* AliEMCALGeometry::GetInstance(const Text_t* name,
668                                                 const Text_t* title){
669     // Returns the pointer of the unique instance
670
671     AliEMCALGeometry * rv = 0; 
672     if ( fgGeom == 0 ) {
673       if ( strcmp(name,"") == 0 ) { // get default geometry
674          fgGeom = new AliEMCALGeometry(fgDefaultGeometryName, title);
675       } else {
676          fgGeom = new AliEMCALGeometry(name, title);
677       }  // end if strcmp(name,"")
678       if ( fgInit ) rv = (AliEMCALGeometry * ) fgGeom;
679       else {
680          rv = 0; 
681          delete fgGeom; 
682          fgGeom = 0; 
683       } // end if fgInit
684     }else{
685         if ( strcmp(fgGeom->GetName(), name) != 0) {
686           printf("\ncurrent geometry is %s : ", fgGeom->GetName());
687           printf(" you cannot call %s ", name);  
688         }else{
689           rv = (AliEMCALGeometry *) fgGeom; 
690         } // end 
691     }  // end if fgGeom
692     return rv; 
693 }
694
695 Bool_t AliEMCALGeometry::IsInEMCAL(Double_t x, Double_t y, Double_t z) const {
696   // Checks whether point is inside the EMCal volume, used in AliEMCALv*.cxx
697   //
698   // Code uses cylindrical approximation made of inner radius (for speed)
699   //
700   // Points behind EMCAl, i.e. R > outer radius, but eta, phi in acceptance 
701   // are considered to inside
702
703   Double_t r=sqrt(x*x+y*y);
704
705   if ( r > fEnvelop[0] ) {
706      Double_t theta;
707      theta  =    TMath::ATan2(r,z);
708      Double_t eta;
709      if(theta == 0) 
710        eta = 9999;
711      else 
712        eta    =   -TMath::Log(TMath::Tan(theta/2.));
713      if (eta < fArm1EtaMin || eta > fArm1EtaMax)
714        return 0;
715  
716      Double_t phi = TMath::ATan2(y,x) * 180./TMath::Pi();
717      if (phi < 0) phi += 360;  // phi should go from 0 to 360 in this case
718      if (phi > fArm1PhiMin && phi < fArm1PhiMax)
719        return 1;
720   }
721   return 0;
722 }
723 // ==
724
725 //
726 // == Shish-kebab cases ==
727 //
728 Int_t AliEMCALGeometry::GetAbsCellId(Int_t nSupMod, Int_t nModule, Int_t nIphi, Int_t nIeta) const
729
730   // 27-aug-04; 
731   // corr. 21-sep-04; 
732   //       13-oct-05; 110 degree case
733   // May 31, 2006; ALICE numbering scheme:
734   // 0 <= nSupMod < fNumberOfSuperModules
735   // 0 <= nModule  < fNPHI * fNZ ( fNPHI * fNZ/2 for fKey110DEG=1)
736   // 0 <= nIphi   < fNPHIdiv
737   // 0 <= nIeta   < fNETAdiv
738   // 0 <= absid   < fNCells
739   static Int_t id=0; // have to change from 0 to fNCells-1
740   if(fKey110DEG == 1 && nSupMod >= 10) { // 110 degree case; last two supermodules
741     id  = fNCellsInSupMod*10 + (fNCellsInSupMod/2)*(nSupMod-10);
742   } else {
743     id  = fNCellsInSupMod*nSupMod;
744   }
745   id += fNCellsInModule *nModule;
746   id += fNPHIdiv *nIphi;
747   id += nIeta;
748   if(id<0 || id >= fNCells) {
749 //     printf(" wrong numerations !!\n");
750 //     printf("    id      %6i(will be force to -1)\n", id);
751 //     printf("    fNCells %6i\n", fNCells);
752 //     printf("    nSupMod %6i\n", nSupMod);
753 //     printf("    nModule  %6i\n", nModule);
754 //     printf("    nIphi   %6i\n", nIphi);
755 //     printf("    nIeta   %6i\n", nIeta);
756     id = -TMath::Abs(id); // if negative something wrong
757   }
758   return id;
759 }
760
761 Bool_t  AliEMCALGeometry::CheckAbsCellId(Int_t absId) const
762
763   // May 31, 2006; only trd1 now
764   if(absId<0 || absId >= fNCells) return kFALSE;
765   else                            return kTRUE;
766 }
767
768 Bool_t AliEMCALGeometry::GetCellIndex(Int_t absId,Int_t &nSupMod,Int_t &nModule,Int_t &nIphi,Int_t &nIeta) const
769
770   // 21-sep-04; 19-oct-05;
771   // May 31, 2006; ALICE numbering scheme:
772   // 
773   // In:
774   // absId   - cell is as in Geant,     0<= absId   < fNCells;
775   // Out:
776   // nSupMod - super module(SM) number, 0<= nSupMod < fNumberOfSuperModules;
777   // nModule  - module number in SM,     0<= nModule  < fNCellsInSupMod/fNCellsInSupMod or(/2) for tow last SM (10th and 11th);
778   // nIphi   - cell number in phi driection inside module; 0<= nIphi < fNPHIdiv; 
779   // nIeta   - cell number in eta driection inside module; 0<= nIeta < fNETAdiv; 
780   // 
781   static Int_t tmp=0, sm10=0;
782   if(!CheckAbsCellId(absId)) return kFALSE;
783
784   sm10 = fNCellsInSupMod*10;
785   if(fKey110DEG == 1 && absId >= sm10) { // 110 degree case; last two supermodules  
786     nSupMod = (absId-sm10) / (fNCellsInSupMod/2) + 10;
787     tmp     = (absId-sm10) % (fNCellsInSupMod/2);
788   } else {
789     nSupMod = absId / fNCellsInSupMod;
790     tmp     = absId % fNCellsInSupMod;
791   }
792
793   nModule  = tmp / fNCellsInModule;
794   tmp     = tmp % fNCellsInModule;
795   nIphi   = tmp / fNPHIdiv;
796   nIeta   = tmp % fNPHIdiv;
797
798   return kTRUE;
799 }
800
801 void AliEMCALGeometry::GetModulePhiEtaIndexInSModule(Int_t nSupMod, Int_t nModule,  int &iphim, int &ietam) const
802
803   // added nSupMod; - 19-oct-05 !
804   // Alice numbering scheme        - Jun 01,2006 
805   // ietam, iphi - indexes of module in two dimensional grid of SM
806   // ietam - have to change from 0 to fNZ-1
807   // iphim - have to change from 0 to nphi-1 (fNPhi-1 or fNPhi/2-1)
808   static Int_t nphi;
809
810   if(fKey110DEG == 1 && nSupMod>=10) nphi = fNPhi/2;
811   else                               nphi = fNPhi;
812
813   ietam = nModule/nphi;
814   iphim = nModule%nphi;
815 }
816
817 void AliEMCALGeometry::GetCellPhiEtaIndexInSModule(Int_t nSupMod, Int_t nModule, Int_t nIphi, Int_t nIeta, 
818 int &iphi, int &ieta) const
819
820   // 
821   // Added nSupMod; Nov 25, 05
822   // Alice numbering scheme  - Jun 01,2006 
823   // IN:
824   // nSupMod - super module(SM) number, 0<= nSupMod < fNumberOfSuperModules;
825   // nModule  - module number in SM,     0<= nModule  < fNCellsInSupMod/fNCellsInSupMod or(/2) for tow last SM (10th and 11th);
826   // nIphi   - cell number in phi driection inside module; 0<= nIphi < fNPHIdiv; 
827   // nIeta   - cell number in eta driection inside module; 0<= nIeta < fNETAdiv; 
828   // 
829  // OUT:
830   // ieta, iphi - indexes of cell(tower) in two dimensional grid of SM
831   // ieta - have to change from 0 to (fNZ*fNETAdiv-1)
832   // iphi - have to change from 0 to (fNPhi*fNPHIdiv-1 or fNPhi*fNPHIdiv/2-1)
833   //
834   static Int_t iphim, ietam;
835
836   GetModulePhiEtaIndexInSModule(nSupMod,nModule, iphim, ietam); 
837   //  ieta  = ietam*fNETAdiv + (1-nIeta); // x(module) = -z(SM) 
838   ieta  = ietam*fNETAdiv + (fNETAdiv - 1 - nIeta); // x(module) = -z(SM) 
839   iphi  = iphim*fNPHIdiv + nIphi;     // y(module) =  y(SM) 
840
841   if(iphi<0 || ieta<0)
842   AliDebug(1,Form(" nSupMod %i nModule %i nIphi %i nIeta %i => ieta %i iphi %i\n", 
843   nSupMod, nModule, nIphi, nIeta, ieta, iphi));
844 }
845
846 Int_t  AliEMCALGeometry::GetSuperModuleNumber(Int_t absId)  const
847 {
848   // Return the number of the  supermodule given the absolute
849   // ALICE numbering id
850
851   static Int_t nSupMod, nModule, nIphi, nIeta;
852   GetCellIndex(absId, nSupMod, nModule, nIphi, nIeta);
853   return nSupMod;
854
855
856 void  AliEMCALGeometry::GetModuleIndexesFromCellIndexesInSModule(Int_t nSupMod, Int_t iphi, Int_t ieta, 
857                         Int_t &iphim, Int_t &ietam, Int_t &nModule) const
858 {
859   // Transition from cell indexes (ieta,iphi) to module indexes (ietam,iphim, nModule)
860   static Int_t nphi;
861   nphi  = GetNumberOfModuleInPhiDirection(nSupMod);  
862
863   ietam  = ieta/fNETAdiv;
864   iphim  = iphi/fNPHIdiv;
865   nModule = ietam * nphi + iphim; 
866 }
867
868 Int_t  AliEMCALGeometry::GetAbsCellIdFromCellIndexes(Int_t nSupMod, Int_t iphi, Int_t ieta) const
869 {
870   // Transition from super module number(nSupMod) and cell indexes (ieta,iphi) to absId
871   static Int_t ietam, iphim, nModule;
872   static Int_t nIeta, nIphi; // cell indexes in module
873
874   GetModuleIndexesFromCellIndexesInSModule(nSupMod, iphi, ieta, ietam, iphim, nModule);
875
876   nIeta = ieta%fNETAdiv;
877   nIeta = fNETAdiv - 1 - nIeta;
878   nIphi = iphi%fNPHIdiv;
879
880   return GetAbsCellId(nSupMod, nModule, nIphi, nIeta);
881 }
882
883
884 // Methods for AliEMCALRecPoint - Feb 19, 2006
885 Bool_t AliEMCALGeometry::RelPosCellInSModule(Int_t absId, Double_t &xr, Double_t &yr, Double_t &zr) const
886 {
887   // Look to see what the relative
888   // position inside a given cell is
889   // for a recpoint.
890   // Alice numbering scheme - Jun 08, 2006
891   // In:
892   // absId   - cell is as in Geant,     0<= absId   < fNCells;
893   // OUT:
894   // xr,yr,zr - x,y,z coordinates of cell with absId inside SM 
895
896   // Shift index taking into account the difference between standard SM 
897   // and SM of half size in phi direction
898   const Int_t phiIndexShift = fCentersOfCellsPhiDir.GetSize()/4; // Nov 22, 2006; was 6 for cas 2X2
899   static Int_t nSupMod, nModule, nIphi, nIeta, iphi, ieta;
900   if(!CheckAbsCellId(absId)) return kFALSE;
901
902   GetCellIndex(absId, nSupMod, nModule, nIphi, nIeta);
903   GetCellPhiEtaIndexInSModule(nSupMod,nModule,nIphi,nIeta, iphi, ieta); 
904  
905   xr = fCentersOfCellsXDir.At(ieta);
906   zr = fCentersOfCellsEtaDir.At(ieta);
907
908   if(nSupMod<10) {
909     yr = fCentersOfCellsPhiDir.At(iphi);
910   } else {
911     yr = fCentersOfCellsPhiDir.At(iphi + phiIndexShift);
912   }
913   AliDebug(1,Form("absId %i nSupMod %i iphi %i ieta %i xr %f yr %f zr %f ",absId,nSupMod,iphi,ieta,xr,yr,zr));
914
915   return kTRUE;
916 }
917
918 Bool_t AliEMCALGeometry::RelPosCellInSModule(Int_t absId, Double_t loc[3]) const
919 {
920   // Alice numbering scheme - Jun 03, 2006
921   loc[0] = loc[1] = loc[2]=0.0;
922   if(RelPosCellInSModule(absId, loc[0],loc[1],loc[2])) {
923     return kTRUE;
924   }
925   return kFALSE;
926 }
927
928 Bool_t AliEMCALGeometry::RelPosCellInSModule(Int_t absId, TVector3 &vloc) const
929 {
930   static Double_t loc[3];
931   if(RelPosCellInSModule(absId,loc)) {
932     vloc.SetXYZ(loc[0], loc[1], loc[2]);
933     return kTRUE;
934   } else {
935     vloc.SetXYZ(0,0,0);
936     return kFALSE;
937   }
938   // Alice numbering scheme - Jun 03, 2006
939 }
940
941 Bool_t AliEMCALGeometry::RelPosCellInSModule(Int_t absId, Double_t distEff, Double_t &xr, Double_t &yr, Double_t &zr) const
942 {
943   // Jul 30, 2007 - taking into account position of shower max
944   // Look to see what the relative
945   // position inside a given cell is
946   // for a recpoint.
947   // In:
948   // absId   - cell is as in Geant,     0<= absId   < fNCells;
949   // e       - cluster energy
950   // OUT:
951   // xr,yr,zr - x,y,z coordinates of cell with absId inside SM 
952
953   // Shift index taking into account the difference between standard SM 
954   // and SM of half size in phi direction
955   const  Int_t phiIndexShift = fCentersOfCellsPhiDir.GetSize()/4; // Nov 22, 2006; was 6 for cas 2X2
956   static Int_t nSupMod, nModule, nIphi, nIeta, iphi, ieta;
957   static Int_t iphim, ietam;
958   static AliEMCALShishKebabTrd1Module *mod = 0;
959   static TVector2 v;
960   if(!CheckAbsCellId(absId)) return kFALSE;
961
962   GetCellIndex(absId, nSupMod, nModule, nIphi, nIeta);
963   GetModulePhiEtaIndexInSModule(nSupMod, nModule, iphim, ietam);
964   GetCellPhiEtaIndexInSModule(nSupMod,nModule,nIphi,nIeta, iphi, ieta); 
965  
966   mod = GetShishKebabModule(ietam);
967   mod->GetPositionAtCenterCellLine(nIeta, distEff, v); 
968   xr = v.Y() - fParSM[0];
969   zr = v.X() - fParSM[2];
970
971   if(nSupMod<10) {
972     yr = fCentersOfCellsPhiDir.At(iphi);
973   } else {
974     yr = fCentersOfCellsPhiDir.At(iphi + phiIndexShift);
975   }
976   AliDebug(1,Form("absId %i nSupMod %i iphi %i ieta %i xr %f yr %f zr %f ",absId,nSupMod,iphi,ieta,xr,yr,zr));
977
978   return kTRUE;
979 }
980
981 Bool_t AliEMCALGeometry::RelPosCellInSModule(Int_t absId, Int_t maxAbsId, Double_t distEff, Double_t &xr, Double_t &yr, Double_t &zr) const
982 {
983   // Jul 31, 2007 - taking into account position of shower max and apply coor2.
984   // Look to see what the relative
985   // position inside a given cell is
986   // for a recpoint.
987   // In:
988   // absId     - cell is as in Geant,     0<= absId   < fNCells;
989   // maxAbsId  - abs id of cell with highest energy
990   // e         - cluster energy
991   // OUT:
992   // xr,yr,zr - x,y,z coordinates of cell with absId inside SM 
993
994   // Shift index taking into account the difference between standard SM 
995   // and SM of half size in phi direction
996   const  Int_t phiIndexShift = fCentersOfCellsPhiDir.GetSize()/4; // Nov 22, 2006; was 6 for cas 2X2
997   static Int_t nSupMod, nModule, nIphi, nIeta, iphi, ieta;
998   static Int_t iphim, ietam;
999   static AliEMCALShishKebabTrd1Module *mod = 0;
1000   static TVector2 v;
1001
1002   static Int_t nSupModM, nModuleM, nIphiM, nIetaM, iphiM, ietaM;
1003   static Int_t iphimM, ietamM, maxAbsIdCopy=-1;
1004   static AliEMCALShishKebabTrd1Module *modM = 0;
1005   static Double_t distCorr;
1006
1007   if(!CheckAbsCellId(absId)) return kFALSE;
1008
1009   GetCellIndex(absId, nSupMod, nModule, nIphi, nIeta);
1010   GetModulePhiEtaIndexInSModule(nSupMod, nModule, iphim, ietam);
1011   GetCellPhiEtaIndexInSModule(nSupMod,nModule,nIphi,nIeta, iphi, ieta); 
1012   mod = GetShishKebabModule(ietam);
1013
1014   if(absId != maxAbsId) {
1015     distCorr = 0.;
1016     if(maxAbsIdCopy != maxAbsId) {
1017       GetCellIndex(maxAbsId, nSupModM, nModuleM, nIphiM, nIetaM);
1018       GetModulePhiEtaIndexInSModule(nSupModM, nModuleM, iphimM, ietamM);
1019       GetCellPhiEtaIndexInSModule(nSupModM,nModuleM,nIphiM,nIetaM, iphiM, ietaM); 
1020       modM = GetShishKebabModule(ietamM); // do I need this ?
1021       maxAbsIdCopy = maxAbsId;
1022     }
1023     if(ietamM !=0) {
1024       distCorr = GetEtaModuleSize()*(ietam-ietamM)/TMath::Tan(modM->GetTheta()); // Stay here
1025       //printf(" distCorr %f | dist %f | ietam %i -> etamM %i\n", distCorr, dist, ietam, ietamM);  
1026     }
1027     // distEff += distCorr;
1028   }
1029   // Bad resolution in this case, strong bias vs phi
1030   // distEff = 0.0; 
1031   mod->GetPositionAtCenterCellLine(nIeta, distEff, v); // Stay here
1032   xr = v.Y() - fParSM[0];
1033   zr = v.X() - fParSM[2];
1034
1035   if(nSupMod<10) {
1036     yr = fCentersOfCellsPhiDir.At(iphi);
1037   } else {
1038     yr = fCentersOfCellsPhiDir.At(iphi + phiIndexShift);
1039   }
1040   AliDebug(1,Form("absId %i nSupMod %i iphi %i ieta %i xr %f yr %f zr %f ",absId,nSupMod,iphi,ieta,xr,yr,zr));
1041
1042   return kTRUE;
1043 }
1044
1045 void AliEMCALGeometry::CreateListOfTrd1Modules()
1046 {
1047   // Generate the list of Trd1 modules
1048   // which will make up the EMCAL
1049   // geometry
1050
1051   AliDebug(2,Form(" AliEMCALGeometry::CreateListOfTrd1Modules() started "));
1052
1053   AliEMCALShishKebabTrd1Module *mod=0, *mTmp=0; // current module
1054   if(fShishKebabTrd1Modules == 0) {
1055     fShishKebabTrd1Modules = new TList;
1056     fShishKebabTrd1Modules->SetName("ListOfTRD1");
1057     for(int iz=0; iz< GetNZ(); iz++) { 
1058       if(iz==0) { 
1059         mod  = new AliEMCALShishKebabTrd1Module(TMath::Pi()/2.,this);
1060       } else {
1061         mTmp  = new AliEMCALShishKebabTrd1Module(*mod);
1062         mod   = mTmp;
1063       }
1064       fShishKebabTrd1Modules->Add(mod);
1065     }
1066   } else {
1067     AliDebug(2,Form(" Already exits : "));
1068   }
1069   mod = (AliEMCALShishKebabTrd1Module*)fShishKebabTrd1Modules->At(fShishKebabTrd1Modules->GetSize()-1);
1070   fEtaMaxOfTRD1 = mod->GetMaxEtaOfModule(0);
1071
1072   AliDebug(2,Form(" fShishKebabTrd1Modules has %i modules : max eta %5.4f \n", 
1073                   fShishKebabTrd1Modules->GetSize(),fEtaMaxOfTRD1));
1074   // Feb 20,2006;
1075   // Jun 01, 2006 - ALICE numbering scheme
1076   // define grid for cells in eta(z) and x directions in local coordinates system of SM
1077   // Works just for 2x2 case only -- ?? start here
1078   // 
1079   //
1080   // Define grid for cells in phi(y) direction in local coordinates system of SM
1081   // as for 2X2 as for 3X3 - Nov 8,2006
1082   // 
1083   AliDebug(2,Form(" Cells grid in phi directions : size %i\n", fCentersOfCellsPhiDir.GetSize()));
1084   Int_t ind=0; // this is phi index
1085   Int_t ieta=0, nModule=0, iphiTemp;
1086   Double_t xr, zr, theta, phi, eta, r, x,y;
1087   TVector3 vglob;
1088   Double_t ytCenterModule=0.0, ytCenterCell=0.0;
1089
1090   fCentersOfCellsPhiDir.Set(fNPhi*fNPHIdiv);
1091   fPhiCentersOfCells.Set(fNPhi*fNPHIdiv);
1092
1093   Double_t R0 = GetIPDistance() + GetLongModuleSize()/2.;
1094   for(Int_t it=0; it<fNPhi; it++) { // cycle on modules
1095     ytCenterModule = -fParSM[1] + fPhiModuleSize*(2*it+1)/2;  // center of module
1096     for(Int_t ic=0; ic<fNPHIdiv; ic++) { // cycle on cells in module
1097       if(fNPHIdiv==2) {
1098         ytCenterCell = ytCenterModule + fPhiTileSize *(2*ic-1)/2.;
1099       } else if(fNPHIdiv==3){
1100         ytCenterCell = ytCenterModule + fPhiTileSize *(ic-1);
1101       } else if(fNPHIdiv==1){
1102         ytCenterCell = ytCenterModule;
1103       }
1104       fCentersOfCellsPhiDir.AddAt(ytCenterCell,ind);
1105       // Define grid on phi direction
1106       // Grid is not the same for different eta bin;
1107       // Effect is small but is still here
1108       phi = TMath::ATan2(ytCenterCell, R0);
1109       fPhiCentersOfCells.AddAt(phi, ind);
1110
1111       AliDebug(2,Form(" ind %2.2i : y %8.3f ", ind, fCentersOfCellsPhiDir.At(ind))); 
1112       ind++;
1113     }
1114   }
1115
1116   fCentersOfCellsEtaDir.Set(fNZ *fNETAdiv);
1117   fCentersOfCellsXDir.Set(fNZ *fNETAdiv);
1118   fEtaCentersOfCells.Set(fNZ *fNETAdiv * fNPhi*fNPHIdiv);
1119   AliDebug(2,Form(" Cells grid in eta directions : size %i\n", fCentersOfCellsEtaDir.GetSize()));
1120   for(Int_t it=0; it<fNZ; it++) {
1121     AliEMCALShishKebabTrd1Module *trd1 = GetShishKebabModule(it);
1122     nModule = fNPhi*it;
1123     for(Int_t ic=0; ic<fNETAdiv; ic++) {
1124       if(fNPHIdiv==2) {
1125         trd1->GetCenterOfCellInLocalCoordinateofSM(ic, xr, zr);      // case of 2X2
1126         GetCellPhiEtaIndexInSModule(0, nModule, 0, ic, iphiTemp, ieta); 
1127       } if(fNPHIdiv==3) {
1128         trd1->GetCenterOfCellInLocalCoordinateofSM_3X3(ic, xr, zr);  // case of 3X3
1129         GetCellPhiEtaIndexInSModule(0, nModule, 0, ic, iphiTemp, ieta); 
1130       } if(fNPHIdiv==1) {
1131         trd1->GetCenterOfCellInLocalCoordinateofSM_1X1(xr, zr);      // case of 1X1
1132         GetCellPhiEtaIndexInSModule(0, nModule, 0, ic, iphiTemp, ieta); 
1133       }
1134       fCentersOfCellsXDir.AddAt(float(xr) - fParSM[0],ieta);
1135       fCentersOfCellsEtaDir.AddAt(float(zr) - fParSM[2],ieta);
1136       // Define grid on eta direction for each bin in phi
1137       for(int iphi=0; iphi<fCentersOfCellsPhiDir.GetSize(); iphi++) {
1138         x = xr + trd1->GetRadius();
1139         y = fCentersOfCellsPhiDir[iphi];
1140         r = TMath::Sqrt(x*x + y*y + zr*zr);
1141         theta = TMath::ACos(zr/r);
1142         eta   = AliEMCALShishKebabTrd1Module::ThetaToEta(theta);
1143         //        ind   = ieta*fCentersOfCellsPhiDir.GetSize() + iphi;
1144         ind   = iphi*fCentersOfCellsEtaDir.GetSize() + ieta;
1145         fEtaCentersOfCells.AddAt(eta, ind);
1146       }
1147       //printf(" ieta %i : xr + trd1->GetRadius() %f : zr %f : eta %f \n", ieta, xr + trd1->GetRadius(), zr, eta);
1148     }
1149   }
1150   for(Int_t i=0; i<fCentersOfCellsEtaDir.GetSize(); i++) {
1151     AliDebug(2,Form(" ind %2.2i : z %8.3f : x %8.3f", i+1, 
1152                     fCentersOfCellsEtaDir.At(i),fCentersOfCellsXDir.At(i)));
1153   }
1154
1155 }
1156
1157 void  AliEMCALGeometry::GetTransformationForSM()
1158 {
1159   //Uses the geometry manager to
1160   //load the transformation matrix
1161   //for the supermodules
1162   // Unused after 19 Jan, 2007 - keep for compatibility; 
1163
1164   return;
1165   static Bool_t transInit=kFALSE;
1166   if(transInit) return;
1167
1168   int i=0;
1169   if(gGeoManager == 0) {
1170     Info("CreateTransformationForSM() "," Load geometry : TGeoManager::Import()");
1171     assert(0);
1172   }
1173   TGeoNode *tn = gGeoManager->GetTopNode();
1174   TGeoNode *node=0, *xen1 = 0;
1175   for(i=0; i<tn->GetNdaughters(); i++) {
1176     node = tn->GetDaughter(i);
1177     TString ns(node->GetName());
1178     if(ns.Contains(GetNameOfEMCALEnvelope())) {
1179       xen1 = node;
1180       break;
1181     }
1182   }
1183   if(!xen1) {
1184     Info("CreateTransformationForSM() "," geometry has not EMCAL envelope with name %s", 
1185     GetNameOfEMCALEnvelope());
1186     assert(0);
1187   }
1188   printf(" i %i : EMCAL Envelope is %s : #SM %i \n", i, xen1->GetName(), xen1->GetNdaughters());
1189   for(i=0; i<xen1->GetNdaughters(); i++) {
1190     TGeoNodeMatrix *sm = (TGeoNodeMatrix*)xen1->GetDaughter(i);
1191     fMatrixOfSM[i] = sm->GetMatrix();
1192     //Compiler doesn't like this syntax...
1193     //    printf(" %i : matrix %x \n", i, fMatrixOfSM[i]);
1194   }
1195   transInit = kTRUE;
1196 }
1197
1198 void AliEMCALGeometry::GetGlobal(const Double_t *loc, Double_t *glob, int ind) const
1199 {
1200   // Figure out the global numbering
1201   // of a given supermodule from the
1202   // local numbering
1203   // Alice numbering - Jun 03,2006
1204   //  if(fMatrixOfSM[0] == 0) GetTransformationForSM();
1205
1206   if(ind>=0 && ind < GetNumberOfSuperModules()) {
1207     fMatrixOfSM[ind]->LocalToMaster(loc, glob);
1208   }
1209 }
1210
1211 void AliEMCALGeometry::GetGlobal(const TVector3 &vloc, TVector3 &vglob, int ind) const
1212 {
1213   //Figure out the global numbering
1214   //of a given supermodule from the
1215   //local numbering given a 3-vector location
1216
1217   static Double_t tglob[3], tloc[3];
1218   vloc.GetXYZ(tloc);
1219   GetGlobal(tloc, tglob, ind);
1220   vglob.SetXYZ(tglob[0], tglob[1], tglob[2]);
1221 }
1222
1223 void AliEMCALGeometry::GetGlobal(Int_t absId , double glob[3]) const
1224
1225   // Alice numbering scheme - Jun 03, 2006
1226   static Int_t nSupMod, nModule, nIphi, nIeta;
1227   static double loc[3];
1228
1229   glob[0]=glob[1]=glob[2]=0.0; // bad case
1230   if(RelPosCellInSModule(absId, loc)) {
1231     GetCellIndex(absId, nSupMod, nModule, nIphi, nIeta);
1232     fMatrixOfSM[nSupMod]->LocalToMaster(loc, glob);
1233   }
1234 }
1235
1236 void AliEMCALGeometry::GetGlobal(Int_t absId , TVector3 &vglob) const
1237
1238   // Alice numbering scheme - Jun 03, 2006
1239   static Double_t glob[3];
1240
1241   GetGlobal(absId, glob);
1242   vglob.SetXYZ(glob[0], glob[1], glob[2]);
1243
1244 }
1245
1246 void AliEMCALGeometry::GetGlobal(const AliRecPoint *rp, TVector3 &vglob) const
1247 {
1248   // Figure out the global numbering
1249   // of a given supermodule from the
1250   // local numbering for RecPoints
1251
1252   static TVector3 vloc;
1253   static Int_t nSupMod, nModule, nIphi, nIeta;
1254
1255   AliRecPoint *rpTmp = (AliRecPoint*)rp; // const_cast ??
1256   if(!rpTmp) return;
1257   AliEMCALRecPoint *rpEmc = (AliEMCALRecPoint*)rpTmp;
1258
1259   GetCellIndex(rpEmc->GetAbsId(0), nSupMod, nModule, nIphi, nIeta);
1260   rpTmp->GetLocalPosition(vloc);
1261   GetGlobal(vloc, vglob, nSupMod);
1262 }
1263
1264 void AliEMCALGeometry::EtaPhiFromIndex(Int_t absId,Double_t &eta,Double_t &phi) const
1265 {
1266   // Nov 16, 2006- float to double
1267   // version for TRD1 only
1268   static TVector3 vglob;
1269   GetGlobal(absId, vglob);
1270   eta = vglob.Eta();
1271   phi = vglob.Phi();
1272 }
1273
1274 void AliEMCALGeometry::EtaPhiFromIndex(Int_t absId,Float_t &eta,Float_t &phi) const
1275 {
1276   // Nov 16,2006 - should be discard in future
1277   static TVector3 vglob;
1278   GetGlobal(absId, vglob);
1279   eta = float(vglob.Eta());
1280   phi = float(vglob.Phi());
1281 }
1282
1283 Bool_t AliEMCALGeometry::GetPhiBoundariesOfSM(Int_t nSupMod, Double_t &phiMin, Double_t &phiMax) const
1284 {
1285   // 0<= nSupMod <=11; phi in rad
1286   static int i;
1287   if(nSupMod<0 || nSupMod >11) return kFALSE; 
1288   i = nSupMod/2;
1289   phiMin = fPhiBoundariesOfSM[2*i];
1290   phiMax = fPhiBoundariesOfSM[2*i+1];
1291   return kTRUE; 
1292 }
1293
1294 Bool_t AliEMCALGeometry::GetPhiBoundariesOfSMGap(Int_t nPhiSec, Double_t &phiMin, Double_t &phiMax) const
1295 {
1296   // 0<= nPhiSec <=4; phi in rad
1297   // 0;  gap boundaries between  0th&2th  | 1th&3th SM
1298   // 1;  gap boundaries between  2th&4th  | 3th&5th SM
1299   // 2;  gap boundaries between  4th&6th  | 5th&7th SM
1300   // 3;  gap boundaries between  6th&8th  | 7th&9th SM
1301   // 4;  gap boundaries between  8th&10th | 9th&11th SM
1302   if(nPhiSec<0 || nPhiSec >4) return kFALSE; 
1303   phiMin = fPhiBoundariesOfSM[2*nPhiSec+1];
1304   phiMax = fPhiBoundariesOfSM[2*nPhiSec+2];
1305   return kTRUE; 
1306 }
1307
1308 Bool_t AliEMCALGeometry::SuperModuleNumberFromEtaPhi(Double_t eta, Double_t phi, Int_t &nSupMod) const
1309
1310   // Return false if phi belongs a phi cracks between SM
1311  
1312   static Int_t i;
1313
1314   if(TMath::Abs(eta) > fEtaMaxOfTRD1) return kFALSE;
1315
1316   phi = TVector2::Phi_0_2pi(phi); // move phi to (0,2pi) boundaries
1317   for(i=0; i<6; i++) {
1318     if(phi>=fPhiBoundariesOfSM[2*i] && phi<=fPhiBoundariesOfSM[2*i+1]) {
1319       nSupMod = 2*i;
1320       if(eta < 0.0) nSupMod++;
1321       AliDebug(1,Form("eta %f phi %f(%5.2f) : nSupMod %i : #bound %i", eta,phi,phi*TMath::RadToDeg(), nSupMod,i));
1322       return kTRUE;
1323     }
1324   }
1325   return kFALSE;
1326 }
1327
1328 Bool_t AliEMCALGeometry::GetAbsCellIdFromEtaPhi(Double_t eta, Double_t phi, Int_t &absId) const
1329 {
1330   // Nov 17,2006
1331   // stay here - phi problem as usual 
1332   static Int_t nSupMod, i, ieta, iphi, etaShift, nphi;
1333   static Double_t absEta=0.0, d=0.0, dmin=0.0, phiLoc;
1334   absId = nSupMod = - 1;
1335   if(SuperModuleNumberFromEtaPhi(eta, phi, nSupMod)) {
1336     // phi index first
1337     phi    = TVector2::Phi_0_2pi(phi);
1338     phiLoc = phi - fPhiCentersOfSM[nSupMod/2];
1339     nphi   = fPhiCentersOfCells.GetSize();
1340     if(nSupMod>=10) {
1341       phiLoc = phi - 190.*TMath::DegToRad();
1342       nphi  /= 2;
1343     }
1344
1345     dmin   = TMath::Abs(fPhiCentersOfCells[0]-phiLoc);
1346     iphi   = 0;
1347     for(i=1; i<nphi; i++) {
1348       d = TMath::Abs(fPhiCentersOfCells[i] - phiLoc);
1349       if(d < dmin) {
1350         dmin = d;
1351         iphi = i;
1352       }
1353       //      printf(" i %i : d %f : dmin %f : fPhiCentersOfCells[i] %f \n", i, d, dmin, fPhiCentersOfCells[i]);
1354     }
1355     // odd SM are turned with respect of even SM - reverse indexes
1356     AliDebug(2,Form(" iphi %i : dmin %f (phi %f, phiLoc %f ) ", iphi, dmin, phi, phiLoc));
1357     // eta index
1358     absEta   = TMath::Abs(eta);
1359     etaShift = iphi*fCentersOfCellsEtaDir.GetSize();
1360     dmin     = TMath::Abs(fEtaCentersOfCells[etaShift]-absEta);
1361     ieta     = 0;
1362     for(i=1; i<fCentersOfCellsEtaDir.GetSize(); i++) {
1363       d = TMath::Abs(fEtaCentersOfCells[i+etaShift] - absEta);
1364       if(d < dmin) {
1365         dmin = d;
1366         ieta = i;
1367       }
1368     }
1369     AliDebug(2,Form(" ieta %i : dmin %f (eta=%f) : nSupMod %i ", ieta, dmin, eta, nSupMod));
1370
1371     if(eta<0) iphi = (nphi-1) - iphi;
1372     absId = GetAbsCellIdFromCellIndexes(nSupMod, iphi, ieta);
1373
1374     return kTRUE;
1375   }
1376   return kFALSE;
1377 }
1378
1379 AliEMCALShishKebabTrd1Module* AliEMCALGeometry::GetShishKebabModule(Int_t neta) const
1380 {
1381   //This method was too long to be
1382   //included in the header file - the
1383   //rule checker complained about it's
1384   //length, so we move it here.  It returns the
1385   //shishkebabmodule at a given eta index point.
1386
1387   static AliEMCALShishKebabTrd1Module* trd1=0;
1388   if(fShishKebabTrd1Modules && neta>=0 && neta<fShishKebabTrd1Modules->GetSize()) {
1389     trd1 = (AliEMCALShishKebabTrd1Module*)fShishKebabTrd1Modules->At(neta);
1390   } else trd1 = 0;
1391   return trd1;
1392 }
1393
1394 void AliEMCALGeometry::Browse(TBrowser* b)
1395 {
1396   if(fShishKebabTrd1Modules) b->Add(fShishKebabTrd1Modules);
1397   for(int i=0; i<fNumberOfSuperModules; i++) {
1398     if(fMatrixOfSM[i])  b->Add(fMatrixOfSM[i]);
1399   }
1400 }
1401
1402 Bool_t AliEMCALGeometry::IsFolder() const
1403 {
1404   if(fShishKebabTrd1Modules) return kTRUE;
1405   else                       return kFALSE;
1406 }