1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
18 //_________________________________________________________________________
19 // Geometry class for EMCAL : singleton
20 // EMCAL consists of layers of scintillator and lead
21 // Places the the Barrel Geometry of The EMCAL at Midrapidity
22 // between 80 and 180(or 190) degrees of Phi and
24 // Number of Modules and Layers may be controlled by
25 // the name of the instance defined
26 // EMCAL geometry tree:
27 // EMCAL -> superModule -> module -> tower(cell)
29 // absId -> nSupMod -> nModule -> (nIphi,nIeta)
31 //*-- Author: Sahal Yacoob (LBL / UCT)
32 // and : Yves Schutz (SUBATECH)
33 // and : Jennifer Klay (LBL)
34 // SHASHLYK : Aleksei Pavlinov (WSU)
39 // --- AliRoot header files ---
40 #include <Riostream.h>
42 #include <TClonesArray.h>
43 #include <TGeoManager.h>
44 #include <TGeoMatrix.h>
48 #include <TObjArray.h>
49 #include <TObjString.h>
56 #include "AliEMCALGeometry.h"
57 #include "AliEMCALShishKebabTrd1Module.h"
58 #include "AliEMCALRecPoint.h"
59 #include "AliEMCALDigit.h"
60 #include "AliEMCALHistoUtilities.h"
62 ClassImp(AliEMCALGeometry)
64 // these initialisations are needed for a singleton
65 AliEMCALGeometry *AliEMCALGeometry::fgGeom = 0;
66 Bool_t AliEMCALGeometry::fgInit = kFALSE;
67 Char_t* AliEMCALGeometry::fgDefaultGeometryName = "SHISH_77_TRD1_2X2_FINAL_110DEG";
70 // You can create the AliEMCALGeometry object independently from anything.
71 // You have to use just the correct name of geometry. If name is empty string the
72 // default name of geometry will be used.
74 // AliEMCALGeometry* g = AliEMCALGeometry::GetInstance(name,title); // first time
76 // g = AliEMCALGeometry::GetInstance(); // after first time
78 // MC: If you work with MC data you have to get geometry the next way:
79 // == =============================
80 // AliRunLoader *rl = AliRunLoader::GetRunLoader();
81 // AliEMCALGeometry *geom = dynamic_cast<AliEMCAL*>(rl->GetAliRun()->GetDetector("EMCAL"))->GetGeometry();
84 AliEMCALGeometry::AliEMCALGeometry()
86 fGeoName(0),fArrayOpts(0),fAlFrontThick(0.),fECPbRadThickness(0.),fECScintThick(0.),
87 fNECLayers(0),fArm1PhiMin(0.),fArm1PhiMax(0.),fArm1EtaMin(0.),fArm1EtaMax(0.),fIPDistance(0.),
88 fShellThickness(0.),fZLength(0.),fGap2Active(0.),fNZ(0),fNPhi(0),fSampling(0.),fNumberOfSuperModules(0),
89 fSteelFrontThick(0.),fFrontSteelStrip(0.),fLateralSteelStrip(0.),fPassiveScintThick(0.),fPhiModuleSize(0.),
90 fEtaModuleSize(0.),fPhiTileSize(0.),fEtaTileSize(0.),fLongModuleSize(0.),fNPhiSuperModule(0),fNPHIdiv(0),fNETAdiv(0),
91 fNCells(0),fNCellsInSupMod(0),fNCellsInModule(0),fNTRU(0),fNTRUEta(0),fNTRUPhi(0),fTrd1Angle(0.),f2Trd1Dx2(0.),
92 fPhiGapForSM(0.),fKey110DEG(0),fPhiBoundariesOfSM(0), fPhiCentersOfSM(0),fEtaMaxOfTRD1(0),
93 fTrd2AngleY(0.),f2Trd2Dy2(0.),fEmptySpace(0.),fTubsR(0.),fTubsTurnAngle(0.),fCentersOfCellsEtaDir(0),
94 fCentersOfCellsXDir(0),fCentersOfCellsPhiDir(0),fEtaCentersOfCells(0),fPhiCentersOfCells(0),
95 fShishKebabTrd1Modules(0), fNAdditionalOpts(0),
96 fILOSS(-1), fIHADR(-1)
98 // default ctor only for internal usage (singleton)
99 // must be kept public for root persistency purposes, but should never be called by the outside world
100 // CreateListOfTrd1Modules();
101 AliDebug(2, "AliEMCALGeometry : default ctor ");
103 //______________________________________________________________________
104 AliEMCALGeometry::AliEMCALGeometry(const Text_t* name, const Text_t* title)
105 : AliGeometry(name, title),
106 fGeoName(0),fArrayOpts(0),fAlFrontThick(0.),fECPbRadThickness(0.),fECScintThick(0.),
107 fNECLayers(0),fArm1PhiMin(0.),fArm1PhiMax(0.),fArm1EtaMin(0.),fArm1EtaMax(0.),fIPDistance(0.),
108 fShellThickness(0.),fZLength(0.),fGap2Active(0.),fNZ(0),fNPhi(0),fSampling(0.),fNumberOfSuperModules(0),
109 fSteelFrontThick(0.),fFrontSteelStrip(0.),fLateralSteelStrip(0.),fPassiveScintThick(0.),fPhiModuleSize(0.),
110 fEtaModuleSize(0.),fPhiTileSize(0.),fEtaTileSize(0.),fLongModuleSize(0.),fNPhiSuperModule(0),fNPHIdiv(0),fNETAdiv(0),
111 fNCells(0),fNCellsInSupMod(0),fNCellsInModule(0),fNTRU(0),fNTRUEta(0),fNTRUPhi(0),fTrd1Angle(0.),f2Trd1Dx2(0.),
112 fPhiGapForSM(0.),fKey110DEG(0),fPhiBoundariesOfSM(0), fPhiCentersOfSM(0), fEtaMaxOfTRD1(0),
113 fTrd2AngleY(0.),f2Trd2Dy2(0.),fEmptySpace(0.),fTubsR(0.),fTubsTurnAngle(0.),fCentersOfCellsEtaDir(0),
114 fCentersOfCellsXDir(0),fCentersOfCellsPhiDir(0),fEtaCentersOfCells(0),fPhiCentersOfCells(0),
115 fShishKebabTrd1Modules(0),fNAdditionalOpts(0),
116 fILOSS(-1), fIHADR(-1)
118 // ctor only for internal usage (singleton)
119 AliDebug(2, Form("AliEMCALGeometry(%s,%s) ", name,title));
123 CreateListOfTrd1Modules();
125 if (AliDebugLevel()>=2) {
130 //______________________________________________________________________
131 AliEMCALGeometry::AliEMCALGeometry(const AliEMCALGeometry& geom)
133 fGeoName(geom.fGeoName),
134 fArrayOpts(geom.fArrayOpts),
135 fAlFrontThick(geom.fAlFrontThick),
136 fECPbRadThickness(geom.fECPbRadThickness),
137 fECScintThick(geom.fECScintThick),
138 fNECLayers(geom.fNECLayers),
139 fArm1PhiMin(geom.fArm1PhiMin),
140 fArm1PhiMax(geom.fArm1PhiMax),
141 fArm1EtaMin(geom.fArm1EtaMin),
142 fArm1EtaMax(geom.fArm1EtaMax),
143 fIPDistance(geom.fIPDistance),
144 fShellThickness(geom.fShellThickness),
145 fZLength(geom.fZLength),
146 fGap2Active(geom.fGap2Active),
149 fSampling(geom.fSampling),
150 fNumberOfSuperModules(geom.fNumberOfSuperModules),
151 fSteelFrontThick(geom.fSteelFrontThick),
152 fFrontSteelStrip(geom.fFrontSteelStrip),
153 fLateralSteelStrip(geom.fLateralSteelStrip),
154 fPassiveScintThick(geom.fPassiveScintThick),
155 fPhiModuleSize(geom.fPhiModuleSize),
156 fEtaModuleSize(geom.fEtaModuleSize),
157 fPhiTileSize(geom.fPhiTileSize),
158 fEtaTileSize(geom.fEtaTileSize),
159 fLongModuleSize(geom.fLongModuleSize),
160 fNPhiSuperModule(geom.fNPhiSuperModule),
161 fNPHIdiv(geom.fNPHIdiv),
162 fNETAdiv(geom.fNETAdiv),
163 fNCells(geom.fNCells),
164 fNCellsInSupMod(geom.fNCellsInSupMod),
165 fNCellsInModule(geom.fNCellsInModule),
167 fNTRUEta(geom.fNTRUEta),
168 fNTRUPhi(geom.fNTRUPhi),
169 fTrd1Angle(geom.fTrd1Angle),
170 f2Trd1Dx2(geom.f2Trd1Dx2),
171 fPhiGapForSM(geom.fPhiGapForSM),
172 fKey110DEG(geom.fKey110DEG),
173 fPhiBoundariesOfSM(geom.fPhiBoundariesOfSM),
174 fPhiCentersOfSM(geom.fPhiCentersOfSM),
175 fEtaMaxOfTRD1(geom.fEtaMaxOfTRD1),
176 fTrd2AngleY(geom.fTrd2AngleY),
177 f2Trd2Dy2(geom.f2Trd2Dy2),
178 fEmptySpace(geom.fEmptySpace),
180 fTubsTurnAngle(geom.fTubsTurnAngle),
181 fCentersOfCellsEtaDir(geom.fCentersOfCellsEtaDir),
182 fCentersOfCellsXDir(geom.fCentersOfCellsXDir),
183 fCentersOfCellsPhiDir(geom.fCentersOfCellsPhiDir),
184 fEtaCentersOfCells(geom.fEtaCentersOfCells),
185 fPhiCentersOfCells(geom.fPhiCentersOfCells),
186 fShishKebabTrd1Modules(geom.fShishKebabTrd1Modules),
187 fNAdditionalOpts(geom.fNAdditionalOpts),
188 fILOSS(geom.fILOSS), fIHADR(geom.fIHADR)
193 //______________________________________________________________________
194 AliEMCALGeometry::~AliEMCALGeometry(void){
197 //______________________________________________________________________
198 void AliEMCALGeometry::Init(void){
199 // Initializes the EMCAL parameters
200 // naming convention : GUV_WX_N_ gives the composition of a tower
201 // WX inform about the composition of the EM calorimeter section:
202 // thickness in mm of Pb radiator (W) and of scintillator (X), and number of scintillator layers (N)
203 // New geometry: EMCAL_55_25
204 // 24-aug-04 for shish-kebab
205 // SHISH_25 or SHISH_62
206 // 11-oct-05 - correction for pre final design
207 // Feb 06,2006 - decrease the weight of EMCAL
209 // Oct 30,2006 - SHISH_TRD1_CURRENT_1X1, SHISH_TRD1_CURRENT_2X2 or SHISH_TRD1_CURRENT_3X3;
212 fAdditionalOpts[0] = "nl="; // number of sampling layers (fNECLayers)
213 fAdditionalOpts[1] = "pbTh="; // cm, Thickness of the Pb (fECPbRadThick)
214 fAdditionalOpts[2] = "scTh="; // cm, Thickness of the Sc (fECScintThick)
215 fAdditionalOpts[3] = "latSS="; // cm, Thickness of lateral steel strip (fLateralSteelStrip)
216 fAdditionalOpts[4] = "allILOSS="; // = 0,1,2,3,4 (4 - energy loss without fluctuation)
217 fAdditionalOpts[5] = "allIHADR="; // = 0,1,2 (0 - no hadronic interaction)
219 fNAdditionalOpts = sizeof(fAdditionalOpts) / sizeof(char*);
221 fgInit = kFALSE; // Assume failed until proven otherwise.
222 fGeoName = GetName();
225 if(fGeoName.Contains("110DEG") || fGeoName.Contains("CURRENT")) fKey110DEG = 1; // for GetAbsCellId
226 fShishKebabTrd1Modules = 0;
227 fTrd2AngleY = f2Trd2Dy2 = fEmptySpace = fTubsR = fTubsTurnAngle = 0;
229 fNZ = 114; // granularity along Z (eta)
230 fNPhi = 168; // granularity in phi (azimuth)
231 fArm1PhiMin = 80.0; // degrees, Starting EMCAL Phi position
232 fArm1PhiMax = 190.0; // degrees, Ending EMCAL Phi position
233 fArm1EtaMin = -0.7; // pseudorapidity, Starting EMCAL Eta position
234 fArm1EtaMax = +0.7; // pseudorapidity, Ending EMCAL Eta position
235 fIPDistance = 454.0; // cm, Radial distance to inner surface of EMCAL
236 fPhiGapForSM = 0.; // cm, only for final TRD1 geometry
237 for(int i=0; i<12; i++) fMatrixOfSM[i] = 0;
240 if(fGeoName.Contains("SHISH")){ // Only shahslyk now
241 // 7-sep-05; integration issue
242 fArm1PhiMin = 80.0; // 60 -> 80
243 fArm1PhiMax = 180.0; // 180 -> 190
245 fNumberOfSuperModules = 10; // 12 = 6 * 2 (6 in phi, 2 in Z);
246 fSteelFrontThick = 2.54; // 9-sep-04
248 fFrontSteelStrip = fPassiveScintThick = 0.0; // 13-may-05
249 fLateralSteelStrip = 0.025; // before MAY 2005
250 fPhiModuleSize = fEtaModuleSize = 11.4;
251 fPhiTileSize = fEtaTileSize = 5.52; // (11.4-5.52*2)/2. = 0.18 cm (wall thickness)
254 fAlFrontThick = fGap2Active = 0;
255 fNPHIdiv = fNETAdiv = 2;
258 fECScintThick = fECPbRadThickness = 0.2;
259 fSampling = 1.; // 30-aug-04 - should be calculated
260 if(fGeoName.Contains("TWIST")) { // all about EMCAL module
261 fNZ = 27; // 16-sep-04
262 } else if(fGeoName.Contains("TRD")) {
263 fIPDistance = 428.0; // 11-may-05
264 fSteelFrontThick = 0.0; // 3.17 -> 0.0; 28-mar-05 : no stell plate
267 fPhiModuleSize = fEtaModuleSize = 12.26;
268 fNZ = 26; // 11-oct-04
269 fTrd1Angle = 1.3; // in degree
270 // 18-nov-04; 1./0.08112=12.327
271 // http://pdsfweb01.nersc.gov/~pavlinov/ALICE/SHISHKEBAB/RES/linearityAndResolutionForTRD1.html
272 if(fGeoName.Contains("TRD1")) { // 30-jan-05
274 fPhiGapForSM = 2.; // cm, only for final TRD1 geometry
275 if(fGeoName.Contains("MAY05") || fGeoName.Contains("WSUC") || fGeoName.Contains("FINAL") || fGeoName.Contains("CURRENT")){
276 fNumberOfSuperModules = 12; // 20-may-05
277 if(fGeoName.Contains("WSUC")) fNumberOfSuperModules = 1; // 27-may-05
278 fNECLayers = 77; // (13-may-05 from V.Petrov)
279 fPhiModuleSize = 12.5; // 20-may-05 - rectangular shape
280 fEtaModuleSize = 11.9;
281 fECScintThick = fECPbRadThickness = 0.16;// (13-may-05 from V.Petrov)
282 fFrontSteelStrip = 0.025;// 0.025cm = 0.25mm (13-may-05 from V.Petrov)
283 fLateralSteelStrip = 0.01; // 0.01cm = 0.1mm (13-may-05 from V.Petrov) - was 0.025
284 fPassiveScintThick = 0.8; // 0.8cm = 8mm (13-may-05 from V.Petrov)
286 fTrd1Angle = 1.5; // 1.3 or 1.5
288 if(fGeoName.Contains("FINAL") || fGeoName.Contains("CURRENT")) { // 9-sep-05
289 fNumberOfSuperModules = 10;
291 fNumberOfSuperModules = 12;// last two modules have size 10 degree in phi (180<phi<190)
292 fArm1PhiMax = 200.0; // for XEN1 and turn angle of super modules
294 if(fGeoName.Contains("FINAL")) {
295 fPhiModuleSize = 12.26 - fPhiGapForSM / Float_t(fNPhi); // first assumption
296 } else if(fGeoName.Contains("CURRENT")) {
297 fECScintThick = 0.176; // 10% of weight reduction
298 fECPbRadThickness = 0.144; //
299 fLateralSteelStrip = 0.015; // 0.015cm = 0.15mm (Oct 30, from Fred)
300 fPhiModuleSize = 12.00;
301 fPhiGapForSM = (12.26 - fPhiModuleSize)*fNPhi; // have to check
303 fEtaModuleSize = fPhiModuleSize;
304 if(fGeoName.Contains("HUGE")) fNECLayers *= 3; // 28-oct-05 for analysing leakage
307 } else if(fGeoName.Contains("TRD2")) { // 30-jan-05
308 fSteelFrontThick = 0.0; // 11-mar-05
309 fIPDistance+= fSteelFrontThick; // 1-feb-05 - compensate absence of steel plate
310 fTrd1Angle = 1.64; // 1.3->1.64
311 fTrd2AngleY = fTrd1Angle; // symmetric case now
312 fEmptySpace = 0.2; // 2 mm
313 fTubsR = fIPDistance; // 31-jan-05 - as for Fred case
315 fPhiModuleSize = fTubsR*2.*TMath::Tan(fTrd2AngleY*TMath::DegToRad()/2.);
316 fPhiModuleSize -= fEmptySpace/2.; // 11-mar-05
317 fEtaModuleSize = fPhiModuleSize; // 20-may-05
320 fNPHIdiv = fNETAdiv = 2; // 13-oct-04 - division again
321 if(fGeoName.Contains("3X3")) { // 23-nov-04
322 fNPHIdiv = fNETAdiv = 3;
323 } else if(fGeoName.Contains("4X4")) {
324 fNPHIdiv = fNETAdiv = 4;
325 } else if(fGeoName.Contains("1X1")) {
326 fNPHIdiv = fNETAdiv = 1;
329 if(fGeoName.Contains("25")){
331 fECScintThick = fECPbRadThickness = 0.5;
333 if(fGeoName.Contains("WSUC")){ // 18-may-05 - about common structure
334 fShellThickness = 30.; // should be change
338 CheckAdditionalOptions();
339 DefineSamplingFraction();
341 fPhiTileSize = fPhiModuleSize/double(fNPHIdiv) - fLateralSteelStrip; // 13-may-05
342 fEtaTileSize = fEtaModuleSize/double(fNETAdiv) - fLateralSteelStrip; // 13-may-05
344 // constant for transition absid <--> indexes
345 fNCellsInModule = fNPHIdiv*fNETAdiv;
346 fNCellsInSupMod = fNCellsInModule*fNPhi*fNZ;
347 fNCells = fNCellsInSupMod*fNumberOfSuperModules;
348 if(GetKey110DEG()) fNCells -= fNCellsInSupMod;
350 fLongModuleSize = fNECLayers*(fECScintThick + fECPbRadThickness);
351 if(fGeoName.Contains("MAY05")) fLongModuleSize += (fFrontSteelStrip + fPassiveScintThick);
354 if(fGeoName.Contains("TRD")) {
355 f2Trd1Dx2 = fEtaModuleSize + 2.*fLongModuleSize*TMath::Tan(fTrd1Angle*TMath::DegToRad()/2.);
356 if(fGeoName.Contains("TRD2")) { // 27-jan-05
357 f2Trd2Dy2 = fPhiModuleSize + 2.*fLongModuleSize*TMath::Tan(fTrd2AngleY*TMath::DegToRad()/2.);
360 } else Fatal("Init", "%s is an undefined geometry!", fGeoName.Data()) ;
362 fNPhiSuperModule = fNumberOfSuperModules/2;
363 if(fNPhiSuperModule<1) fNPhiSuperModule = 1;
365 fShellThickness = fAlFrontThick + fGap2Active + fNECLayers*GetECScintThick()+(fNECLayers-1)*GetECPbRadThick();
366 if(fGeoName.Contains("SHISH")) {
367 fShellThickness = fSteelFrontThick + fLongModuleSize;
368 if(fGeoName.Contains("TWIST")) { // 13-sep-04
369 fShellThickness = TMath::Sqrt(fLongModuleSize*fLongModuleSize + fPhiModuleSize*fEtaModuleSize);
370 fShellThickness += fSteelFrontThick;
371 } else if(fGeoName.Contains("TRD")) { // 1-oct-04
372 fShellThickness = TMath::Sqrt(fLongModuleSize*fLongModuleSize + f2Trd1Dx2*f2Trd1Dx2);
373 fShellThickness += fSteelFrontThick;
375 fParSM[0] = GetShellThickness()/2.;
376 fParSM[1] = GetPhiModuleSize() * GetNPhi()/2.;
381 fZLength = 2.*ZFromEtaR(fIPDistance+fShellThickness,fArm1EtaMax); // Z coverage
382 fEnvelop[0] = fIPDistance; // mother volume inner radius
383 fEnvelop[1] = fIPDistance + fShellThickness; // mother volume outer r.
384 fEnvelop[2] = 1.00001*fZLength; // add some padding for mother volume.
386 fNumberOfSuperModules = 12;
388 // SM phi boundaries - (0,1),(2,3) .. (10,11) - has the same boundaries; Nov 7, 2006
389 fPhiBoundariesOfSM.Set(fNumberOfSuperModules);
390 fPhiCentersOfSM.Set(fNumberOfSuperModules/2);
391 fPhiBoundariesOfSM[0] = TMath::PiOver2() - TMath::ATan2(fParSM[1] , fIPDistance); // 1th and 2th modules)
392 fPhiBoundariesOfSM[1] = TMath::PiOver2() + TMath::ATan2(fParSM[1] , fIPDistance);
393 fPhiCentersOfSM[0] = TMath::PiOver2();
394 for(int i=1; i<=4; i++) { // from 2th ro 9th
395 fPhiBoundariesOfSM[2*i] = fPhiBoundariesOfSM[0] + 20.*TMath::DegToRad()*i;
396 fPhiBoundariesOfSM[2*i+1] = fPhiBoundariesOfSM[1] + 20.*TMath::DegToRad()*i;
397 fPhiCentersOfSM[i] = fPhiCentersOfSM[0] + 20.*TMath::DegToRad()*i;
399 fPhiBoundariesOfSM[11] = 190.*TMath::DegToRad();
400 fPhiBoundariesOfSM[10] = fPhiBoundariesOfSM[11] - TMath::ATan2((fParSM[1]) , fIPDistance);
401 fPhiCentersOfSM[5] = (fPhiBoundariesOfSM[10]+fPhiBoundariesOfSM[11])/2.;
403 //TRU parameters. These parameters values are not the final ones.
408 // Define TGeoMatrix of SM - Jan 19, 2007 (just fro TRD1)
409 if(fGeoName.Contains("TRD1")) { // copy code from AliEMCALv0::CreateSmod()
410 int nphism = GetNumberOfSuperModules()/2;
411 double dphi = (GetArm1PhiMax() - GetArm1PhiMin())/nphism;
412 double rpos = (GetEnvelop(0) + GetEnvelop(1))/2.;
413 double phi, phiRad, xpos, ypos, zpos;
414 for(int i=0; i<nphism; i++){
415 phi = GetArm1PhiMin() + dphi*(2*i+1)/2.; // phi= 90, 110, 130, 150, 170, 190
416 phiRad = phi*TMath::Pi()/180.;
417 xpos = rpos * TMath::Cos(phiRad);
418 ypos = rpos * TMath::Sin(phiRad);
421 xpos += (fParSM[1]/2. * TMath::Sin(phiRad));
422 ypos -= (fParSM[1]/2. * TMath::Cos(phiRad));
426 TGeoRotation *geoRot0 = new TGeoRotation("geoRot0", 90.0, phi, 90.0, 90.0+phi, 0.0, 0.0);
427 fMatrixOfSM[ind] = new TGeoCombiTrans(Form("EmcalSM%2.2i",ind),
428 xpos,ypos, zpos, geoRot0);
431 double phiy = 90. + phi + 180.;
432 if(phiy>=360.) phiy -= 360.;
433 TGeoRotation *geoRot1 = new TGeoRotation("geoRot1", 90.0, phi, 90.0, phiy, 180.0, 0.0);
434 fMatrixOfSM[ind] = new TGeoCombiTrans(Form("EmcalSM%2.2i",ind),
435 xpos,ypos,-zpos, geoRot1);
439 AliInfo(" is ended");
442 void AliEMCALGeometry::PrintGeometry()
444 // Separate routine is callable from broswer; Nov 7,2006
445 printf("\nInit: geometry of EMCAL named %s :\n", fGeoName.Data());
447 for(Int_t i=0; i<fArrayOpts->GetEntries(); i++){
448 TObjString *o = (TObjString*)fArrayOpts->At(i);
449 printf(" %i : %s \n", i, o->String().Data());
452 printf("Granularity: %d in eta and %d in phi\n", GetNZ(), GetNPhi()) ;
453 printf("Layout: phi = (%7.1f, %7.1f), eta = (%5.2f, %5.2f), IP = %7.2f -> for EMCAL envelope only\n",
454 GetArm1PhiMin(), GetArm1PhiMax(),GetArm1EtaMin(), GetArm1EtaMax(), GetIPDistance() );
456 printf( " ECAL : %d x (%f cm Pb, %f cm Sc) \n",
457 GetNECLayers(), GetECPbRadThick(), GetECScintThick() ) ;
458 printf(" fSampling %5.2f \n", fSampling );
459 if(fGeoName.Contains("SHISH")){
460 printf(" fIPDistance %6.3f cm \n", fIPDistance);
461 if(fSteelFrontThick>0.)
462 printf(" fSteelFrontThick %6.3f cm \n", fSteelFrontThick);
463 printf(" fNPhi %i | fNZ %i \n", fNPhi, fNZ);
464 printf(" fNCellsInModule %i : fNCellsInSupMod %i : fNCells %i\n",fNCellsInModule, fNCellsInSupMod, fNCells);
465 if(fGeoName.Contains("MAY05")){
466 printf(" fFrontSteelStrip %6.4f cm (thickness of front steel strip)\n",
468 printf(" fLateralSteelStrip %6.4f cm (thickness of lateral steel strip)\n",
470 printf(" fPassiveScintThick %6.4f cm (thickness of front passive Sc tile)\n",
473 printf(" X:Y module size %6.3f , %6.3f cm \n", fPhiModuleSize, fEtaModuleSize);
474 printf(" X:Y tile size %6.3f , %6.3f cm \n", fPhiTileSize, fEtaTileSize);
475 printf(" #of sampling layers %i(fNECLayers) \n", fNECLayers);
476 printf(" fLongModuleSize %6.3f cm \n", fLongModuleSize);
477 printf(" #supermodule in phi direction %i \n", fNPhiSuperModule );
479 printf(" fILOSS %i : fIHADR %i \n", fILOSS, fIHADR);
480 if(fGeoName.Contains("TRD")) {
481 printf(" fTrd1Angle %7.4f\n", fTrd1Angle);
482 printf(" f2Trd1Dx2 %7.4f\n", f2Trd1Dx2);
483 if(fGeoName.Contains("TRD2")) {
484 printf(" fTrd2AngleY %7.4f\n", fTrd2AngleY);
485 printf(" f2Trd2Dy2 %7.4f\n", f2Trd2Dy2);
486 printf(" fTubsR %7.2f cm\n", fTubsR);
487 printf(" fTubsTurnAngle %7.4f\n", fTubsTurnAngle);
488 printf(" fEmptySpace %7.4f cm\n", fEmptySpace);
489 } else if(fGeoName.Contains("TRD1")){
490 printf("SM dimensions(TRD1) : dx %7.2f dy %7.2f dz %7.2f (SMOD, BOX)\n",
491 fParSM[0],fParSM[1],fParSM[2]);
492 printf(" fPhiGapForSM %7.4f cm (%7.4f <- phi size in degree)\n",
493 fPhiGapForSM, TMath::ATan2(fPhiGapForSM,fIPDistance)*TMath::RadToDeg());
494 if(GetKey110DEG()) printf(" Last two modules have size 10 degree in phi (180<phi<190)\n");
495 printf(" phi SM boundaries \n");
496 for(int i=0; i<fPhiBoundariesOfSM.GetSize()/2.; i++) {
497 printf(" %i : %7.5f(%7.2f) -> %7.5f(%7.2f) : center %7.5f(%7.2f) \n", i,
498 fPhiBoundariesOfSM[2*i], fPhiBoundariesOfSM[2*i]*TMath::RadToDeg(),
499 fPhiBoundariesOfSM[2*i+1], fPhiBoundariesOfSM[2*i+1]*TMath::RadToDeg(),
500 fPhiCentersOfSM[i], fPhiCentersOfSM[i]*TMath::RadToDeg());
502 printf(" fShishKebabTrd1Modules has %i modules : max eta %5.4f \n",
503 fShishKebabTrd1Modules->GetSize(),fEtaMaxOfTRD1);
505 printf("\n Cells grid in eta directions : size %i\n", fCentersOfCellsEtaDir.GetSize());
506 for(Int_t i=0; i<fCentersOfCellsEtaDir.GetSize(); i++) {
507 printf(" ind %2.2i : z %8.3f : x %8.3f \n", i,
508 fCentersOfCellsEtaDir.At(i),fCentersOfCellsXDir.At(i));
509 int ind=0; // Nov 21,2006
510 for(Int_t iphi=0; iphi<fCentersOfCellsPhiDir.GetSize(); iphi++) {
511 ind = iphi*fCentersOfCellsEtaDir.GetSize() + i;
512 printf("%6.4f ", fEtaCentersOfCells[ind]);
513 if((iphi+1)%12 == 0) printf("\n");
518 printf(" Matrix transformation\n");
519 for(Int_t i=0; i<12; i++) {
520 TGeoMatrix *m = fMatrixOfSM[i];
522 const double *xyz = m->GetTranslation();
523 printf(" %2.2i %s %s x %7.2f y %7.2f z %7.2f\n",
524 i, m->GetName(), m->ClassName(), xyz[0],xyz[1],xyz[2]);
527 printf("\n Cells grid in phi directions : size %i\n", fCentersOfCellsPhiDir.GetSize());
528 for(Int_t i=0; i<fCentersOfCellsPhiDir.GetSize(); i++) {
529 double phi=fPhiCentersOfCells.At(i);
530 printf(" ind %2.2i : y %8.3f : phi %7.5f(%6.2f) \n", i, fCentersOfCellsPhiDir.At(i),
531 phi, phi*TMath::RadToDeg());
538 void AliEMCALGeometry::PrintCellIndexes(Int_t absId, int pri, char *tit)
541 Int_t nSupMod, nModule, nIphi, nIeta;
545 GetCellIndex(absId, nSupMod, nModule, nIphi, nIeta);
546 printf(" %s | absId : %i -> nSupMod %i nModule %i nIphi %i nIeta %i \n", tit, absId, nSupMod, nModule, nIphi, nIeta);
548 GetCellPhiEtaIndexInSModule(nSupMod,nModule,nIphi,nIeta, iphi,ieta);
549 printf(" local SM index : iphi %i : ieta %i \n", iphi,ieta);
550 GetGlobal(absId, vg);
551 printf(" vglob : mag %7.2f : perp %7.2f : z %7.2f : eta %6.4f : phi %6.4f(%6.2f) \n",
552 vg.Mag(), vg.Perp(), vg.Z(), vg.Eta(), vg.Phi(), vg.Phi()*TMath::RadToDeg());
556 //______________________________________________________________________
557 void AliEMCALGeometry::CheckAdditionalOptions()
560 // Additional options that
561 // can be used to select
562 // the specific geometry of
565 // adeed allILOSS= and allIHADR= for MIP investigation
566 fArrayOpts = new TObjArray;
567 Int_t nopt = AliEMCALHistoUtilities::ParseString(fGeoName, *fArrayOpts);
568 if(nopt==1) { // no aditional option(s)
569 fArrayOpts->Delete();
574 for(Int_t i=1; i<nopt; i++){
575 TObjString *o = (TObjString*)fArrayOpts->At(i);
577 TString addOpt = o->String();
579 for(Int_t j=0; j<fNAdditionalOpts; j++) {
580 TString opt = fAdditionalOpts[j];
581 if(addOpt.Contains(opt,TString::kIgnoreCase)) {
587 AliDebug(2,Form("<E> option |%s| unavailable : ** look to the file AliEMCALGeometry.h **\n",
591 AliDebug(2,Form("<I> option |%s| is valid : number %i : |%s|\n",
592 addOpt.Data(), indj, fAdditionalOpts[indj]));
593 if (addOpt.Contains("NL=",TString::kIgnoreCase)) {// number of sampling layers
594 sscanf(addOpt.Data(),"NL=%i", &fNECLayers);
595 AliDebug(2,Form(" fNECLayers %i (new) \n", fNECLayers));
596 } else if(addOpt.Contains("PBTH=",TString::kIgnoreCase)) {//Thickness of the Pb(fECPbRadThicknes)
597 sscanf(addOpt.Data(),"PBTH=%f", &fECPbRadThickness);
598 } else if(addOpt.Contains("SCTH=",TString::kIgnoreCase)) {//Thickness of the Sc(fECScintThick)
599 sscanf(addOpt.Data(),"SCTH=%f", &fECScintThick);
600 } else if(addOpt.Contains("LATSS=",TString::kIgnoreCase)) {// Thickness of lateral steel strip (fLateralSteelStrip)
601 sscanf(addOpt.Data(),"LATSS=%f", &fLateralSteelStrip);
602 AliDebug(2,Form(" fLateralSteelStrip %f (new) \n", fLateralSteelStrip));
603 } else if(addOpt.Contains("ILOSS=",TString::kIgnoreCase)) {// As in Geant
604 sscanf(addOpt.Data(),"ALLILOSS=%i", &fILOSS);
605 AliDebug(2,Form(" fILOSS %i \n", fILOSS));
606 } else if(addOpt.Contains("IHADR=",TString::kIgnoreCase)) {// As in Geant
607 sscanf(addOpt.Data(),"ALLIHADR=%i", &fIHADR);
608 AliDebug(2,Form(" fIHADR %i \n", fIHADR));
614 void AliEMCALGeometry::DefineSamplingFraction()
617 // Look http://rhic.physics.wayne.edu/~pavlinov/ALICE/SHISHKEBAB/RES/linearityAndResolutionForTRD1.html
618 // Keep for compatibilty
620 if(fNECLayers == 69) { // 10% layer reduction
622 } else if(fNECLayers == 61) { // 20% layer reduction
624 } else if(fNECLayers == 77) {
625 if (fECScintThick>0.175 && fECScintThick<0.177) { // 10% Pb thicknes reduction
626 fSampling = 10.5; // fECScintThick = 0.176, fECPbRadThickness=0.144;
627 } else if(fECScintThick>0.191 && fECScintThick<0.193) { // 20% Pb thicknes reduction
628 fSampling = 8.93; // fECScintThick = 0.192, fECPbRadThickness=0.128;
633 //______________________________________________________________________
634 void AliEMCALGeometry::GetCellPhiEtaIndexInSModuleFromTRUIndex(const Int_t itru, const Int_t iphitru, const Int_t ietatru, Int_t &iphiSM, Int_t &ietaSM) const
637 // This method transforms the (eta,phi) index of cells in a
638 // TRU matrix into Super Module (eta,phi) index.
640 // Calculate in which row and column where the TRU are
643 Int_t col = itru/ fNTRUPhi ;
644 Int_t row = itru - col*fNTRUPhi ;
646 //Calculate the (eta,phi) index in SM
647 Int_t nCellsPhi = fNPhi*2/fNTRUPhi;
648 Int_t nCellsEta = fNZ*2/fNTRUEta;
650 iphiSM = nCellsPhi*row + iphitru ;
651 ietaSM = nCellsEta*col + ietatru ;
654 //______________________________________________________________________
655 AliEMCALGeometry * AliEMCALGeometry::GetInstance(){
656 // Returns the pointer of the unique instance
658 AliEMCALGeometry * rv = static_cast<AliEMCALGeometry *>( fgGeom );
662 //______________________________________________________________________
663 AliEMCALGeometry* AliEMCALGeometry::GetInstance(const Text_t* name,
664 const Text_t* title){
665 // Returns the pointer of the unique instance
667 AliEMCALGeometry * rv = 0;
669 if ( strcmp(name,"") == 0 ) { // get default geometry
670 fgGeom = new AliEMCALGeometry(fgDefaultGeometryName, title);
672 fgGeom = new AliEMCALGeometry(name, title);
673 } // end if strcmp(name,"")
674 if ( fgInit ) rv = (AliEMCALGeometry * ) fgGeom;
681 if ( strcmp(fgGeom->GetName(), name) != 0) {
682 printf("\ncurrent geometry is %s : ", fgGeom->GetName());
683 printf(" you cannot call %s ", name);
685 rv = (AliEMCALGeometry *) fgGeom;
691 Bool_t AliEMCALGeometry::IsInEMCAL(Double_t x, Double_t y, Double_t z) const {
692 // Checks whether point is inside the EMCal volume, used in AliEMCALv*.cxx
694 // Code uses cylindrical approximation made of inner radius (for speed)
696 // Points behind EMCAl, i.e. R > outer radius, but eta, phi in acceptance
697 // are considered to inside
699 Double_t r=sqrt(x*x+y*y);
701 if ( r > fEnvelop[0] ) {
703 theta = TMath::ATan2(r,z);
708 eta = -TMath::Log(TMath::Tan(theta/2.));
709 if (eta < fArm1EtaMin || eta > fArm1EtaMax)
712 Double_t phi = TMath::ATan2(y,x) * 180./TMath::Pi();
713 if (phi > fArm1PhiMin && phi < fArm1PhiMax)
721 // == Shish-kebab cases ==
723 Int_t AliEMCALGeometry::GetAbsCellId(Int_t nSupMod, Int_t nModule, Int_t nIphi, Int_t nIeta) const
727 // 13-oct-05; 110 degree case
728 // May 31, 2006; ALICE numbering scheme:
729 // 0 <= nSupMod < fNumberOfSuperModules
730 // 0 <= nModule < fNPHI * fNZ ( fNPHI * fNZ/2 for fKey110DEG=1)
731 // 0 <= nIphi < fNPHIdiv
732 // 0 <= nIeta < fNETAdiv
733 // 0 <= absid < fNCells
734 static Int_t id=0; // have to change from 0 to fNCells-1
735 if(fKey110DEG == 1 && nSupMod >= 10) { // 110 degree case; last two supermodules
736 id = fNCellsInSupMod*10 + (fNCellsInSupMod/2)*(nSupMod-10);
738 id = fNCellsInSupMod*nSupMod;
740 id += fNCellsInModule *nModule;
741 id += fNPHIdiv *nIphi;
743 if(id<0 || id >= fNCells) {
744 // printf(" wrong numerations !!\n");
745 // printf(" id %6i(will be force to -1)\n", id);
746 // printf(" fNCells %6i\n", fNCells);
747 // printf(" nSupMod %6i\n", nSupMod);
748 // printf(" nModule %6i\n", nModule);
749 // printf(" nIphi %6i\n", nIphi);
750 // printf(" nIeta %6i\n", nIeta);
751 id = -TMath::Abs(id); // if negative something wrong
756 Bool_t AliEMCALGeometry::CheckAbsCellId(Int_t absId) const
758 // May 31, 2006; only trd1 now
759 if(absId<0 || absId >= fNCells) return kFALSE;
763 Bool_t AliEMCALGeometry::GetCellIndex(Int_t absId,Int_t &nSupMod,Int_t &nModule,Int_t &nIphi,Int_t &nIeta) const
765 // 21-sep-04; 19-oct-05;
766 // May 31, 2006; ALICE numbering scheme:
769 // absId - cell is as in Geant, 0<= absId < fNCells;
771 // nSupMod - super module(SM) number, 0<= nSupMod < fNumberOfSuperModules;
772 // nModule - module number in SM, 0<= nModule < fNCellsInSupMod/fNCellsInSupMod or(/2) for tow last SM (10th and 11th);
773 // nIphi - cell number in phi driection inside module; 0<= nIphi < fNPHIdiv;
774 // nIeta - cell number in eta driection inside module; 0<= nIeta < fNETAdiv;
776 static Int_t tmp=0, sm10=0;
777 if(!CheckAbsCellId(absId)) return kFALSE;
779 sm10 = fNCellsInSupMod*10;
780 if(fKey110DEG == 1 && absId >= sm10) { // 110 degree case; last two supermodules
781 nSupMod = (absId-sm10) / (fNCellsInSupMod/2) + 10;
782 tmp = (absId-sm10) % (fNCellsInSupMod/2);
784 nSupMod = absId / fNCellsInSupMod;
785 tmp = absId % fNCellsInSupMod;
788 nModule = tmp / fNCellsInModule;
789 tmp = tmp % fNCellsInModule;
790 nIphi = tmp / fNPHIdiv;
791 nIeta = tmp % fNPHIdiv;
796 void AliEMCALGeometry::GetModulePhiEtaIndexInSModule(Int_t nSupMod, Int_t nModule, int &iphim, int &ietam) const
798 // added nSupMod; - 19-oct-05 !
799 // Alice numbering scheme - Jun 01,2006
800 // ietam, iphi - indexes of module in two dimensional grid of SM
801 // ietam - have to change from 0 to fNZ-1
802 // iphim - have to change from 0 to nphi-1 (fNPhi-1 or fNPhi/2-1)
805 if(fKey110DEG == 1 && nSupMod>=10) nphi = fNPhi/2;
808 ietam = nModule/nphi;
809 iphim = nModule%nphi;
812 void AliEMCALGeometry::GetCellPhiEtaIndexInSModule(Int_t nSupMod, Int_t nModule, Int_t nIphi, Int_t nIeta,
813 int &iphi, int &ieta) const
816 // Added nSupMod; Nov 25, 05
817 // Alice numbering scheme - Jun 01,2006
819 // nSupMod - super module(SM) number, 0<= nSupMod < fNumberOfSuperModules;
820 // nModule - module number in SM, 0<= nModule < fNCellsInSupMod/fNCellsInSupMod or(/2) for tow last SM (10th and 11th);
821 // nIphi - cell number in phi driection inside module; 0<= nIphi < fNPHIdiv;
822 // nIeta - cell number in eta driection inside module; 0<= nIeta < fNETAdiv;
825 // ieta, iphi - indexes of cell(tower) in two dimensional grid of SM
826 // ieta - have to change from 0 to (fNZ*fNETAdiv-1)
827 // iphi - have to change from 0 to (fNPhi*fNPHIdiv-1 or fNPhi*fNPHIdiv/2-1)
829 static Int_t iphim, ietam;
831 GetModulePhiEtaIndexInSModule(nSupMod,nModule, iphim, ietam);
832 // ieta = ietam*fNETAdiv + (1-nIeta); // x(module) = -z(SM)
833 ieta = ietam*fNETAdiv + (fNETAdiv - 1 - nIeta); // x(module) = -z(SM)
834 iphi = iphim*fNPHIdiv + nIphi; // y(module) = y(SM)
837 AliDebug(1,Form(" nSupMod %i nModule %i nIphi %i nIeta %i => ieta %i iphi %i\n",
838 nSupMod, nModule, nIphi, nIeta, ieta, iphi));
841 Int_t AliEMCALGeometry::GetSuperModuleNumber(Int_t absId) const
843 // Return the number of the supermodule given the absolute
844 // ALICE numbering id
846 static Int_t nSupMod, nModule, nIphi, nIeta;
847 GetCellIndex(absId, nSupMod, nModule, nIphi, nIeta);
851 void AliEMCALGeometry::GetModuleIndexesFromCellIndexesInSModule(Int_t nSupMod, Int_t iphi, Int_t ieta,
852 Int_t &iphim, Int_t &ietam, Int_t &nModule) const
854 // Transition from cell indexes (ieta,iphi) to module indexes (ietam,iphim, nModule)
856 nphi = GetNumberOfModuleInPhiDirection(nSupMod);
858 ietam = ieta/fNETAdiv;
859 iphim = iphi/fNPHIdiv;
860 nModule = ietam * nphi + iphim;
863 Int_t AliEMCALGeometry::GetAbsCellIdFromCellIndexes(Int_t nSupMod, Int_t iphi, Int_t ieta) const
865 // Transition from super module number(nSupMod) and cell indexes (ieta,iphi) to absId
866 static Int_t ietam, iphim, nModule;
867 static Int_t nIeta, nIphi; // cell indexes in module
869 GetModuleIndexesFromCellIndexesInSModule(nSupMod, iphi, ieta, ietam, iphim, nModule);
871 nIeta = ieta%fNETAdiv;
872 nIeta = fNETAdiv - 1 - nIeta;
873 nIphi = iphi%fNPHIdiv;
875 return GetAbsCellId(nSupMod, nModule, nIphi, nIeta);
879 // Methods for AliEMCALRecPoint - Feb 19, 2006
880 Bool_t AliEMCALGeometry::RelPosCellInSModule(Int_t absId, Double_t &xr, Double_t &yr, Double_t &zr) const
882 // Look to see what the relative
883 // position inside a given cell is
885 // Alice numbering scheme - Jun 08, 2006
887 // absId - cell is as in Geant, 0<= absId < fNCells;
889 // xr,yr,zr - x,y,z coordinates of cell with absId inside SM
891 // Shift index taking into account the difference between standard SM
892 // and SM of half size in phi direction
893 const Int_t phiIndexShift = fCentersOfCellsPhiDir.GetSize()/4; // Nov 22, 2006; was 6 for cas 2X2
894 static Int_t nSupMod, nModule, nIphi, nIeta, iphi, ieta;
895 if(!CheckAbsCellId(absId)) return kFALSE;
897 GetCellIndex(absId, nSupMod, nModule, nIphi, nIeta);
898 GetCellPhiEtaIndexInSModule(nSupMod,nModule,nIphi,nIeta, iphi, ieta);
900 xr = fCentersOfCellsXDir.At(ieta);
901 zr = fCentersOfCellsEtaDir.At(ieta);
904 yr = fCentersOfCellsPhiDir.At(iphi);
906 yr = fCentersOfCellsPhiDir.At(iphi + phiIndexShift);
908 AliDebug(1,Form("absId %i nSupMod %i iphi %i ieta %i xr %f yr %f zr %f ",absId,nSupMod,iphi,ieta,xr,yr,zr));
913 Bool_t AliEMCALGeometry::RelPosCellInSModule(Int_t absId, Double_t loc[3]) const
915 // Alice numbering scheme - Jun 03, 2006
916 loc[0] = loc[1] = loc[2]=0.0;
917 if(RelPosCellInSModule(absId, loc[0],loc[1],loc[2])) {
923 Bool_t AliEMCALGeometry::RelPosCellInSModule(Int_t absId, TVector3 &vloc) const
925 static Double_t loc[3];
926 if(RelPosCellInSModule(absId,loc)) {
927 vloc.SetXYZ(loc[0], loc[1], loc[2]);
933 // Alice numbering scheme - Jun 03, 2006
936 void AliEMCALGeometry::CreateListOfTrd1Modules()
938 // Generate the list of Trd1 modules
939 // which will make up the EMCAL
942 AliDebug(2,Form(" AliEMCALGeometry::CreateListOfTrd1Modules() started "));
944 AliEMCALShishKebabTrd1Module *mod=0, *mTmp=0; // current module
945 if(fShishKebabTrd1Modules == 0) {
946 fShishKebabTrd1Modules = new TList;
947 fShishKebabTrd1Modules->SetName("ListOfTRD1");
948 for(int iz=0; iz< GetNZ(); iz++) {
950 mod = new AliEMCALShishKebabTrd1Module(TMath::Pi()/2.,this);
952 mTmp = new AliEMCALShishKebabTrd1Module(*mod);
955 fShishKebabTrd1Modules->Add(mod);
958 AliDebug(2,Form(" Already exits : "));
960 mod = (AliEMCALShishKebabTrd1Module*)fShishKebabTrd1Modules->At(fShishKebabTrd1Modules->GetSize()-1);
961 fEtaMaxOfTRD1 = mod->GetMaxEtaOfModule(0);
963 AliDebug(2,Form(" fShishKebabTrd1Modules has %i modules : max eta %5.4f \n",
964 fShishKebabTrd1Modules->GetSize(),fEtaMaxOfTRD1));
966 // Jun 01, 2006 - ALICE numbering scheme
967 // define grid for cells in eta(z) and x directions in local coordinates system of SM
968 // Works just for 2x2 case only -- ?? start here
971 // Define grid for cells in phi(y) direction in local coordinates system of SM
972 // as for 2X2 as for 3X3 - Nov 8,2006
974 AliDebug(2,Form(" Cells grid in phi directions : size %i\n", fCentersOfCellsPhiDir.GetSize()));
975 Int_t ind=0; // this is phi index
976 Int_t ieta=0, nModule=0, iphiTemp;
977 Double_t xr, zr, theta, phi, eta, r, x,y;
979 Double_t ytCenterModule=0.0, ytCenterCell=0.0;
981 fCentersOfCellsPhiDir.Set(fNPhi*fNPHIdiv);
982 fPhiCentersOfCells.Set(fNPhi*fNPHIdiv);
984 Double_t R0 = GetIPDistance() + GetLongModuleSize()/2.;
985 for(Int_t it=0; it<fNPhi; it++) { // cycle on modules
986 ytCenterModule = -fParSM[1] + fPhiModuleSize*(2*it+1)/2; // center of module
987 for(Int_t ic=0; ic<fNPHIdiv; ic++) { // cycle on cells in module
989 ytCenterCell = ytCenterModule + fPhiTileSize *(2*ic-1)/2.;
990 } else if(fNPHIdiv==3){
991 ytCenterCell = ytCenterModule + fPhiTileSize *(ic-1);
992 } else if(fNPHIdiv==1){
993 ytCenterCell = ytCenterModule;
995 fCentersOfCellsPhiDir.AddAt(ytCenterCell,ind);
996 // Define grid on phi direction
997 // Grid is not the same for different eta bin;
998 // Effect is small but is still here
999 phi = TMath::ATan2(ytCenterCell, R0);
1000 fPhiCentersOfCells.AddAt(phi, ind);
1002 AliDebug(2,Form(" ind %2.2i : y %8.3f ", ind, fCentersOfCellsPhiDir.At(ind)));
1007 fCentersOfCellsEtaDir.Set(fNZ *fNETAdiv);
1008 fCentersOfCellsXDir.Set(fNZ *fNETAdiv);
1009 fEtaCentersOfCells.Set(fNZ *fNETAdiv * fNPhi*fNPHIdiv);
1010 AliDebug(2,Form(" Cells grid in eta directions : size %i\n", fCentersOfCellsEtaDir.GetSize()));
1011 for(Int_t it=0; it<fNZ; it++) {
1012 AliEMCALShishKebabTrd1Module *trd1 = GetShishKebabModule(it);
1014 for(Int_t ic=0; ic<fNETAdiv; ic++) {
1016 trd1->GetCenterOfCellInLocalCoordinateofSM(ic, xr, zr); // case of 2X2
1017 GetCellPhiEtaIndexInSModule(0, nModule, 0, ic, iphiTemp, ieta);
1019 trd1->GetCenterOfCellInLocalCoordinateofSM_3X3(ic, xr, zr); // case of 3X3
1020 GetCellPhiEtaIndexInSModule(0, nModule, 0, ic, iphiTemp, ieta);
1022 trd1->GetCenterOfCellInLocalCoordinateofSM_1X1(xr, zr); // case of 1X1
1023 GetCellPhiEtaIndexInSModule(0, nModule, 0, ic, iphiTemp, ieta);
1025 fCentersOfCellsXDir.AddAt(float(xr) - fParSM[0],ieta);
1026 fCentersOfCellsEtaDir.AddAt(float(zr) - fParSM[2],ieta);
1027 // Define grid on eta direction for each bin in phi
1028 for(int iphi=0; iphi<fCentersOfCellsPhiDir.GetSize(); iphi++) {
1029 x = xr + trd1->GetRadius();
1030 y = fCentersOfCellsPhiDir[iphi];
1031 r = TMath::Sqrt(x*x + y*y + zr*zr);
1032 theta = TMath::ACos(zr/r);
1033 eta = AliEMCALShishKebabTrd1Module::ThetaToEta(theta);
1034 // ind = ieta*fCentersOfCellsPhiDir.GetSize() + iphi;
1035 ind = iphi*fCentersOfCellsEtaDir.GetSize() + ieta;
1036 fEtaCentersOfCells.AddAt(eta, ind);
1038 //printf(" ieta %i : xr + trd1->GetRadius() %f : zr %f : eta %f \n", ieta, xr + trd1->GetRadius(), zr, eta);
1041 for(Int_t i=0; i<fCentersOfCellsEtaDir.GetSize(); i++) {
1042 AliDebug(2,Form(" ind %2.2i : z %8.3f : x %8.3f", i+1,
1043 fCentersOfCellsEtaDir.At(i),fCentersOfCellsXDir.At(i)));
1048 void AliEMCALGeometry::GetTransformationForSM()
1050 //Uses the geometry manager to
1051 //load the transformation matrix
1052 //for the supermodules
1053 // Unused after 19 Jan, 2007 - keep for compatibility;
1056 static Bool_t transInit=kFALSE;
1057 if(transInit) return;
1060 if(gGeoManager == 0) {
1061 Info("CreateTransformationForSM() "," Load geometry : TGeoManager::Import()");
1064 TGeoNode *tn = gGeoManager->GetTopNode();
1065 TGeoNode *node=0, *xen1 = 0;
1066 for(i=0; i<tn->GetNdaughters(); i++) {
1067 node = tn->GetDaughter(i);
1068 TString ns(node->GetName());
1069 if(ns.Contains(GetNameOfEMCALEnvelope())) {
1075 Info("CreateTransformationForSM() "," geometry has not EMCAL envelope with name %s",
1076 GetNameOfEMCALEnvelope());
1079 printf(" i %i : EMCAL Envelope is %s : #SM %i \n", i, xen1->GetName(), xen1->GetNdaughters());
1080 for(i=0; i<xen1->GetNdaughters(); i++) {
1081 TGeoNodeMatrix *sm = (TGeoNodeMatrix*)xen1->GetDaughter(i);
1082 fMatrixOfSM[i] = sm->GetMatrix();
1083 //Compiler doesn't like this syntax...
1084 // printf(" %i : matrix %x \n", i, fMatrixOfSM[i]);
1089 void AliEMCALGeometry::GetGlobal(const Double_t *loc, Double_t *glob, int ind) const
1091 // Figure out the global numbering
1092 // of a given supermodule from the
1094 // Alice numbering - Jun 03,2006
1095 // if(fMatrixOfSM[0] == 0) GetTransformationForSM();
1097 if(ind>=0 && ind < GetNumberOfSuperModules()) {
1098 fMatrixOfSM[ind]->LocalToMaster(loc, glob);
1102 void AliEMCALGeometry::GetGlobal(const TVector3 &vloc, TVector3 &vglob, int ind) const
1104 //Figure out the global numbering
1105 //of a given supermodule from the
1106 //local numbering given a 3-vector location
1108 static Double_t tglob[3], tloc[3];
1110 GetGlobal(tloc, tglob, ind);
1111 vglob.SetXYZ(tglob[0], tglob[1], tglob[2]);
1114 void AliEMCALGeometry::GetGlobal(Int_t absId , double glob[3]) const
1116 // Alice numbering scheme - Jun 03, 2006
1117 static Int_t nSupMod, nModule, nIphi, nIeta;
1118 static double loc[3];
1120 glob[0]=glob[1]=glob[2]=0.0; // bad case
1121 if(RelPosCellInSModule(absId, loc)) {
1122 GetCellIndex(absId, nSupMod, nModule, nIphi, nIeta);
1123 fMatrixOfSM[nSupMod]->LocalToMaster(loc, glob);
1127 void AliEMCALGeometry::GetGlobal(Int_t absId , TVector3 &vglob) const
1129 // Alice numbering scheme - Jun 03, 2006
1130 static Double_t glob[3];
1132 GetGlobal(absId, glob);
1133 vglob.SetXYZ(glob[0], glob[1], glob[2]);
1137 void AliEMCALGeometry::GetGlobal(const AliRecPoint *rp, TVector3 &vglob) const
1139 // Figure out the global numbering
1140 // of a given supermodule from the
1141 // local numbering for RecPoints
1143 static TVector3 vloc;
1144 static Int_t nSupMod, nModule, nIphi, nIeta;
1146 AliRecPoint *rpTmp = (AliRecPoint*)rp; // const_cast ??
1148 AliEMCALRecPoint *rpEmc = (AliEMCALRecPoint*)rpTmp;
1150 GetCellIndex(rpEmc->GetAbsId(0), nSupMod, nModule, nIphi, nIeta);
1151 rpTmp->GetLocalPosition(vloc);
1152 GetGlobal(vloc, vglob, nSupMod);
1155 void AliEMCALGeometry::EtaPhiFromIndex(Int_t absId,Double_t &eta,Double_t &phi) const
1157 // Nov 16, 2006- float to double
1158 // version for TRD1 only
1159 static TVector3 vglob;
1160 GetGlobal(absId, vglob);
1165 void AliEMCALGeometry::EtaPhiFromIndex(Int_t absId,Float_t &eta,Float_t &phi) const
1167 // Nov 16,2006 - should be discard in future
1168 static TVector3 vglob;
1169 GetGlobal(absId, vglob);
1170 eta = float(vglob.Eta());
1171 phi = float(vglob.Phi());
1174 Bool_t AliEMCALGeometry::GetPhiBoundariesOfSM(Int_t nSupMod, Double_t &phiMin, Double_t &phiMax) const
1176 // 0<= nSupMod <=11; phi in rad
1178 if(nSupMod<0 || nSupMod >11) return kFALSE;
1180 phiMin = fPhiBoundariesOfSM[2*i];
1181 phiMax = fPhiBoundariesOfSM[2*i+1];
1185 Bool_t AliEMCALGeometry::GetPhiBoundariesOfSMGap(Int_t nPhiSec, Double_t &phiMin, Double_t &phiMax) const
1187 // 0<= nPhiSec <=4; phi in rad
1188 // 0; gap boundaries between 0th&2th | 1th&3th SM
1189 // 1; gap boundaries between 2th&4th | 3th&5th SM
1190 // 2; gap boundaries between 4th&6th | 5th&7th SM
1191 // 3; gap boundaries between 6th&8th | 7th&9th SM
1192 // 4; gap boundaries between 8th&10th | 9th&11th SM
1193 if(nPhiSec<0 || nPhiSec >4) return kFALSE;
1194 phiMin = fPhiBoundariesOfSM[2*nPhiSec+1];
1195 phiMax = fPhiBoundariesOfSM[2*nPhiSec+2];
1199 Bool_t AliEMCALGeometry::SuperModuleNumberFromEtaPhi(Double_t eta, Double_t phi, Int_t &nSupMod) const
1201 // Return false if phi belongs a phi cracks between SM
1205 if(TMath::Abs(eta) > fEtaMaxOfTRD1) return kFALSE;
1207 phi = TVector2::Phi_0_2pi(phi); // move phi to (0,2pi) boundaries
1208 for(i=0; i<6; i++) {
1209 if(phi>=fPhiBoundariesOfSM[2*i] && phi<=fPhiBoundariesOfSM[2*i+1]) {
1211 if(eta < 0.0) nSupMod++;
1212 AliDebug(1,Form("eta %f phi %f(%5.2f) : nSupMod %i : #bound %i", eta,phi,phi*TMath::RadToDeg(), nSupMod,i));
1219 Bool_t AliEMCALGeometry::GetAbsCellIdFromEtaPhi(Double_t eta, Double_t phi, Int_t &absId) const
1222 // stay here - phi problem as usual
1223 static Int_t nSupMod, i, ieta, iphi, etaShift, nphi;
1224 static Double_t absEta=0.0, d=0.0, dmin=0.0, phiLoc;
1225 absId = nSupMod = - 1;
1226 if(SuperModuleNumberFromEtaPhi(eta, phi, nSupMod)) {
1228 phi = TVector2::Phi_0_2pi(phi);
1229 phiLoc = phi - fPhiCentersOfSM[nSupMod/2];
1230 nphi = fPhiCentersOfCells.GetSize();
1232 phiLoc = phi - 190.*TMath::DegToRad();
1236 dmin = TMath::Abs(fPhiCentersOfCells[0]-phiLoc);
1238 for(i=1; i<nphi; i++) {
1239 d = TMath::Abs(fPhiCentersOfCells[i] - phiLoc);
1244 // printf(" i %i : d %f : dmin %f : fPhiCentersOfCells[i] %f \n", i, d, dmin, fPhiCentersOfCells[i]);
1246 // odd SM are turned with respect of even SM - reverse indexes
1247 AliDebug(2,Form(" iphi %i : dmin %f (phi %f, phiLoc %f ) ", iphi, dmin, phi, phiLoc));
1249 absEta = TMath::Abs(eta);
1250 etaShift = iphi*fCentersOfCellsEtaDir.GetSize();
1251 dmin = TMath::Abs(fEtaCentersOfCells[etaShift]-absEta);
1253 for(i=1; i<fCentersOfCellsEtaDir.GetSize(); i++) {
1254 d = TMath::Abs(fEtaCentersOfCells[i+etaShift] - absEta);
1260 AliDebug(2,Form(" ieta %i : dmin %f (eta=%f) : nSupMod %i ", ieta, dmin, eta, nSupMod));
1262 if(eta<0) iphi = (nphi-1) - iphi;
1263 absId = GetAbsCellIdFromCellIndexes(nSupMod, iphi, ieta);
1270 AliEMCALShishKebabTrd1Module* AliEMCALGeometry::GetShishKebabModule(Int_t neta)
1272 //This method was too long to be
1273 //included in the header file - the
1274 //rule checker complained about it's
1275 //length, so we move it here. It returns the
1276 //shishkebabmodule at a given eta index point.
1278 static AliEMCALShishKebabTrd1Module* trd1=0;
1279 if(fShishKebabTrd1Modules && neta>=0 && neta<fShishKebabTrd1Modules->GetSize()) {
1280 trd1 = (AliEMCALShishKebabTrd1Module*)fShishKebabTrd1Modules->At(neta);
1285 void AliEMCALGeometry::Browse(TBrowser* b)
1287 if(fShishKebabTrd1Modules) b->Add(fShishKebabTrd1Modules);
1288 for(int i=0; i<fNumberOfSuperModules; i++) {
1289 if(fMatrixOfSM[i]) b->Add(fMatrixOfSM[i]);
1293 Bool_t AliEMCALGeometry::IsFolder() const
1295 if(fShishKebabTrd1Modules) return kTRUE;