]> git.uio.no Git - u/mrichter/AliRoot.git/blame - EMCAL/AliEMCALGeometry.cxx
Version number ++
[u/mrichter/AliRoot.git] / EMCAL / AliEMCALGeometry.cxx
CommitLineData
2012850d 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
b13bbe81 20// EMCAL consists of layers of scintillator and lead
ffa6d63b 21// Places the the Barrel Geometry of The EMCAL at Midrapidity
d87bd045 22// between 80 and 180(or 190) degrees of Phi and
ffa6d63b 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
b13bbe81 26//*-- Author: Sahal Yacoob (LBL / UCT)
27// and : Yves Schutz (SUBATECH)
28// and : Jennifer Klay (LBL)
1963b290 29// SHASHLYK : Aleksei Pavlinov (WSU)
c63c3c5d 30// SuperModules -> module(or tower) -> cell
2012850d 31
2012850d 32// --- AliRoot header files ---
ca8f5bd0 33#include <TMath.h>
116cbefd 34#include <TVector3.h>
c63c3c5d 35#include <TRegexp.h>
36#include <TObjArray.h>
37#include <TObjString.h>
173558f2 38
ca8f5bd0 39// -- ALICE Headers.
d64c959b 40//#include "AliConst.h"
173558f2 41
ca8f5bd0 42// --- EMCAL headers
43#include "AliEMCALGeometry.h"
2012850d 44
925e6570 45ClassImp(AliEMCALGeometry)
2012850d 46
b13bbe81 47AliEMCALGeometry *AliEMCALGeometry::fgGeom = 0;
48Bool_t AliEMCALGeometry::fgInit = kFALSE;
1963b290 49TString name; // contains name of geometry
2012850d 50
c63c3c5d 51char *additionalOpts[]={"nl=", // number of sampling layers
52 "pbTh=", // cm, Thickness of the Pb
53 "scTh=" // cm, Thickness of the Sc
54};
55int nAdditionalOpts = sizeof(additionalOpts) / sizeof(char*);
56
b13bbe81 57//______________________________________________________________________
58AliEMCALGeometry::~AliEMCALGeometry(void){
59 // dtor
2012850d 60}
b13bbe81 61
395c7ba2 62//______________________________________________________________________
09884213 63Bool_t AliEMCALGeometry::AreInSameTower(Int_t id1, Int_t id2) const {
c63c3c5d 64 // Find out whether two hits are in the same tower - have to be change
395c7ba2 65 Int_t idmax = TMath::Max(id1, id2) ;
66 Int_t idmin = TMath::Min(id1, id2) ;
67 if ( ((idmax - GetNZ() * GetNPhi()) == idmin ) ||
68 ((idmax - 2 * GetNZ() * GetNPhi()) == idmin ) )
69 return kTRUE ;
70 else
71 return kFALSE ;
72}
05a92d59 73
395c7ba2 74//______________________________________________________________________
75void AliEMCALGeometry::Init(void){
76 // Initializes the EMCAL parameters
fdebddeb 77 // naming convention : GUV_WX_N_ gives the composition of a tower
395c7ba2 78 // WX inform about the composition of the EM calorimeter section:
fdebddeb 79 // thickness in mm of Pb radiator (W) and of scintillator (X), and number of scintillator layers (N)
80 // New geometry: EMCAL_55_25
1963b290 81 // 24-aug-04 for shish-kebab
82 // SHISH_25 or SHISH_62
c63c3c5d 83 // 11-oct-05 - correction for pre final design
84 // Feb 06,2006 - decrease the weight of EMCAL
fdebddeb 85 fgInit = kFALSE; // Assume failed until proven otherwise.
1963b290 86 name = GetName();
d87bd045 87 name.ToUpper();
88 fKey110DEG = 0;
89 if(name.Contains("110DEG")) fKey110DEG = 1; // for GetAbsCellId
1963b290 90
91 fNZ = 114; // granularity along Z (eta)
92 fNPhi = 168; // granularity in phi (azimuth)
93 fArm1PhiMin = 60.0; // degrees, Starting EMCAL Phi position
94 fArm1PhiMax = 180.0; // degrees, Ending EMCAL Phi position
95 fArm1EtaMin = -0.7; // pseudorapidity, Starting EMCAL Eta position
96 fArm1EtaMax = +0.7; // pseudorapidity, Ending EMCAL Eta position
97 fIPDistance = 454.0; // cm, Radial distance to inner surface of EMCAL
905263da 98 fPhiGapForSM = 0.; // cm, only for final TRD1 geometry
1963b290 99
100 // geometry
c63c3c5d 101 if(name.Contains("SHISH")){ // Only shahslyk now
905263da 102 // 7-sep-05; integration issue
103 fArm1PhiMin = 80.0; // 60 -> 80
c01485dd 104 fArm1PhiMax = 180.0; // 180 -> 190
905263da 105
106 fNumberOfSuperModules = 10; // 12 = 6 * 2 (6 in phi, 2 in Z);
1963b290 107 fSteelFrontThick = 2.54; // 9-sep-04
108 fIPDistance = 460.0;
109 fFrontSteelStrip = fPassiveScintThick = 0.0; // 13-may-05
110 fLateralSteelStrip = 0.025; // before MAY 2005
111 fPhiModuleSize = fEtaModuleSize = 11.4;
112 fPhiTileSize = fEtaTileSize = 5.52; // (11.4-5.52*2)/2. = 0.18 cm (wall thickness)
113 fNPhi = 14;
114 fNZ = 30;
115 fAlFrontThick = fGap2Active = 0;
116 fNPHIdiv = fNETAdiv = 2;
117
118 fNECLayers = 62;
119 fECScintThick = fECPbRadThickness = 0.2;
120 fSampling = 1.; // 30-aug-04 - should be calculated
121 if(name.Contains("TWIST")) { // all about EMCAL module
122 fNZ = 27; // 16-sep-04
123 } else if(name.Contains("TRD")) {
124 fIPDistance = 428.0; // 11-may-05
125 fSteelFrontThick = 0.0; // 3.17 -> 0.0; 28-mar-05 : no stell plate
126 fNPhi = 12;
127 fSampling = 12.327;
128 fPhiModuleSize = fEtaModuleSize = 12.26;
129 fNZ = 26; // 11-oct-04
130 fTrd1Angle = 1.3; // in degree
131// 18-nov-04; 1./0.08112=12.327
132// http://pdsfweb01.nersc.gov/~pavlinov/ALICE/SHISHKEBAB/RES/linearityAndResolutionForTRD1.html
133 if(name.Contains("TRD1")) { // 30-jan-05
134 // for final design
905263da 135 fPhiGapForSM = 2.; // cm, only for final TRD1 geometry
136 if(name.Contains("MAY05") || name.Contains("WSUC") || name.Contains("FINAL")){
1963b290 137 fNumberOfSuperModules = 12; // 20-may-05
138 if(name.Contains("WSUC")) fNumberOfSuperModules = 1; // 27-may-05
139 fNECLayers = 77; // (13-may-05 from V.Petrov)
140 fPhiModuleSize = 12.5; // 20-may-05 - rectangular shape
141 fEtaModuleSize = 11.9;
142 fECScintThick = fECPbRadThickness = 0.16;// (13-may-05 from V.Petrov)
143 fFrontSteelStrip = 0.025;// 0.025cm = 0.25mm (13-may-05 from V.Petrov)
144 fLateralSteelStrip = 0.01; // 0.01cm = 0.1mm (13-may-05 from V.Petrov) - was 0.025
145 fPassiveScintThick = 0.8; // 0.8cm = 8mm (13-may-05 from V.Petrov)
146 fNZ = 24;
147 fTrd1Angle = 1.5; // 1.3 or 1.5
905263da 148
149 if(name.Contains("FINAL")) { // 9-sep-05
150 fNumberOfSuperModules = 10;
d87bd045 151 if(name.Contains("110DEG")) {
152 fNumberOfSuperModules = 12;// last two modules have size 10 degree in phi (180<phi<190)
153 fArm1PhiMax = 200.0; // for XEN1 and turn angle of super modules
154 }
905263da 155 fPhiModuleSize = 12.26 - fPhiGapForSM / Float_t(fNPhi); // first assumption
156 fEtaModuleSize = fPhiModuleSize;
c01485dd 157 if(name.Contains("HUGE")) fNECLayers *= 3; // 28-oct-05 for analysing leakage
905263da 158 }
1963b290 159 }
160 } else if(name.Contains("TRD2")) { // 30-jan-05
161 fSteelFrontThick = 0.0; // 11-mar-05
162 fIPDistance+= fSteelFrontThick; // 1-feb-05 - compensate absence of steel plate
163 fTrd1Angle = 1.64; // 1.3->1.64
164 fTrd2AngleY = fTrd1Angle; // symmetric case now
165 fEmptySpace = 0.2; // 2 mm
166 fTubsR = fIPDistance; // 31-jan-05 - as for Fred case
167
168 fPhiModuleSize = fTubsR*2.*TMath::Tan(fTrd2AngleY*TMath::DegToRad()/2.);
169 fPhiModuleSize -= fEmptySpace/2.; // 11-mar-05
170 fEtaModuleSize = fPhiModuleSize; // 20-may-05
171 fTubsTurnAngle = 3.;
172 }
173 fNPHIdiv = fNETAdiv = 2; // 13-oct-04 - division again
174 if(name.Contains("3X3")) { // 23-nov-04
175 fNPHIdiv = fNETAdiv = 3;
176 } else if(name.Contains("4X4")) {
177 fNPHIdiv = fNETAdiv = 4;
178 }
179 }
180 fPhiTileSize = fPhiModuleSize/2. - fLateralSteelStrip; // 13-may-05
181 fEtaTileSize = fEtaModuleSize/2. - fLateralSteelStrip; // 13-may-05
182
183 if(name.Contains("25")){
184 fNECLayers = 25;
185 fECScintThick = fECPbRadThickness = 0.5;
186 }
187 if(name.Contains("WSUC")){ // 18-may-05 - about common structure
188 fShellThickness = 30.; // should be change
189 fNPhi = fNZ = 4;
190 }
c63c3c5d 191
192 CheckAditionalOptions();
193
1963b290 194 // constant for transition absid <--> indexes
195 fNCellsInTower = fNPHIdiv*fNETAdiv;
196 fNCellsInSupMod = fNCellsInTower*fNPhi*fNZ;
197 fNCells = fNCellsInSupMod*fNumberOfSuperModules;
d87bd045 198 if(name.Contains("110DEG")) fNCells -= fNCellsInSupMod;
1963b290 199
200 fLongModuleSize = fNECLayers*(fECScintThick + fECPbRadThickness);
201 if(name.Contains("MAY05")) fLongModuleSize += (fFrontSteelStrip + fPassiveScintThick);
202
203 // 30-sep-04
204 if(name.Contains("TRD")) {
205 f2Trd1Dx2 = fEtaModuleSize + 2.*fLongModuleSize*TMath::Tan(fTrd1Angle*TMath::DegToRad()/2.);
206 if(name.Contains("TRD2")) { // 27-jan-05
207 f2Trd2Dy2 = fPhiModuleSize + 2.*fLongModuleSize*TMath::Tan(fTrd2AngleY*TMath::DegToRad()/2.);
208 }
209 }
c63c3c5d 210 } else Fatal("Init", "%s is an undefined geometry!", name.Data()) ;
fdebddeb 211
1963b290 212 fNPhiSuperModule = fNumberOfSuperModules/2;
213 if(fNPhiSuperModule<1) fNPhiSuperModule = 1;
fdebddeb 214 //There is always one more scintillator than radiator layer because of the first block of aluminium
215 fShellThickness = fAlFrontThick + fGap2Active + fNECLayers*GetECScintThick()+(fNECLayers-1)*GetECPbRadThick();
1963b290 216 if(name.Contains("SHISH")) {
217 fShellThickness = fSteelFrontThick + fLongModuleSize;
218 if(name.Contains("TWIST")) { // 13-sep-04
219 fShellThickness = TMath::Sqrt(fLongModuleSize*fLongModuleSize + fPhiModuleSize*fEtaModuleSize);
220 fShellThickness += fSteelFrontThick;
221 } else if(name.Contains("TRD")) { // 1-oct-04
222 fShellThickness = TMath::Sqrt(fLongModuleSize*fLongModuleSize + f2Trd1Dx2*f2Trd1Dx2);
223 fShellThickness += fSteelFrontThick;
224 }
225 }
fdebddeb 226
395c7ba2 227 fZLength = 2.*ZFromEtaR(fIPDistance+fShellThickness,fArm1EtaMax); // Z coverage
228 fEnvelop[0] = fIPDistance; // mother volume inner radius
229 fEnvelop[1] = fIPDistance + fShellThickness; // mother volume outer r.
230 fEnvelop[2] = 1.00001*fZLength; // add some padding for mother volume.
231
232 fgInit = kTRUE;
233
1963b290 234 if (kTRUE) {
235 printf("Init: geometry of EMCAL named %s is as follows:\n", name.Data());
905263da 236 printf( " ECAL : %d x (%f cm Pb, %f cm Sc) \n", GetNECLayers(), GetECPbRadThick(), GetECScintThick() ) ;
1963b290 237 if(name.Contains("SHISH")){
238 printf(" fIPDistance %6.3f cm \n", fIPDistance);
239 if(fSteelFrontThick>0.)
240 printf(" fSteelFrontThick %6.3f cm \n", fSteelFrontThick);
241 printf(" fNPhi %i | fNZ %i \n", fNPhi, fNZ);
d87bd045 242 printf(" fNCellsInTower %i : fNCellsInSupMod %i : fNCells %i\n",fNCellsInTower, fNCellsInSupMod, fNCells);
1963b290 243 if(name.Contains("MAY05")){
244 printf(" fFrontSteelStrip %6.4f cm (thickness of front steel strip)\n",
245 fFrontSteelStrip);
246 printf(" fLateralSteelStrip %6.4f cm (thickness of lateral steel strip)\n",
247 fLateralSteelStrip);
248 printf(" fPassiveScintThick %6.4f cm (thickness of front passive Sc tile)\n",
249 fPassiveScintThick);
250 }
c63c3c5d 251 printf(" X:Y module size %6.3f , %6.3f cm \n", fPhiModuleSize, fEtaModuleSize);
252 printf(" X:Y tile size %6.3f , %6.3f cm \n", fPhiTileSize, fEtaTileSize);
253 printf(" #of sampling layers %i(fNECLayers) \n", fNECLayers);
254 printf(" fLongModuleSize %6.3f cm \n", fLongModuleSize);
1963b290 255 printf(" #supermodule in phi direction %i \n", fNPhiSuperModule );
256 }
257 if(name.Contains("TRD")) {
258 printf(" fTrd1Angle %7.4f\n", fTrd1Angle);
259 printf(" f2Trd1Dx2 %7.4f\n", f2Trd1Dx2);
260 if(name.Contains("TRD2")) {
261 printf(" fTrd2AngleY %7.4f\n", fTrd2AngleY);
262 printf(" f2Trd2Dy2 %7.4f\n", f2Trd2Dy2);
905263da 263 printf(" fTubsR %7.2f cm\n", fTubsR);
1963b290 264 printf(" fTubsTurnAngle %7.4f\n", fTubsTurnAngle);
905263da 265 printf(" fEmptySpace %7.4f cm\n", fEmptySpace);
266 } else if(name.Contains("TRD1") && name.Contains("FINAL")){
267 printf(" fPhiGapForSM %7.4f cm \n", fPhiGapForSM);
d87bd045 268 if(name.Contains("110DEG"))printf(" Last two modules have size 10 degree in phi (180<phi<190)\n");
1963b290 269 }
270 }
88cb7938 271 printf("Granularity: %d in eta and %d in phi\n", GetNZ(), GetNPhi()) ;
1963b290 272 printf("Layout: phi = (%7.1f, %7.1f), eta = (%5.2f, %5.2f), IP = %7.2f\n",
273 GetArm1PhiMin(), GetArm1PhiMax(),GetArm1EtaMin(), GetArm1EtaMax(), GetIPDistance() );
88cb7938 274 }
2012850d 275}
173558f2 276
c63c3c5d 277//______________________________________________________________________
278
279void AliEMCALGeometry::CheckAditionalOptions()
280{ // Feb 06,2006
281 fArrayOpts = new TObjArray;
282 Int_t nopt = ParseString(name, *fArrayOpts);
283 if(nopt==1) { // no aditional option(s)
284 fArrayOpts->Delete();
285 delete fArrayOpts;
286 fArrayOpts = 0;
287 return;
288 }
289 for(Int_t i=1; i<nopt; i++){
290 TObjString *o = (TObjString*)fArrayOpts->At(i);
291
292 TString addOpt = o->String();
293 Int_t indj=-1;
294 for(Int_t j=0; j<nAdditionalOpts; j++) {
295 TString opt = additionalOpts[j];
296 if(addOpt.Contains(opt,TString::kIgnoreCase)) {
297 indj = j;
298 break;
299 }
300 }
301 if(indj<0) {
302 printf("<E> option |%s| unavailable : ** look to the file AliEMCALGeometry.h **\n",
303 addOpt.Data());
304 assert(0);
305 } else {
306 printf("<I> option |%s| is valid : number %i : |%s|\n",
307 addOpt.Data(), indj, additionalOpts[indj]);
308 if (addOpt.Contains("NL=",TString::kIgnoreCase)) {// number of sampling layers
309 sscanf(addOpt.Data(),"NL=%i", &fNECLayers);
310 printf(" fNECLayers %i (new) \n", fNECLayers);
311 } else if(addOpt.Contains("PBTH=",TString::kIgnoreCase)) {//Thickness of the Pb
312 sscanf(addOpt.Data(),"PBTH=%f", &fECPbRadThickness);
313 } else if(addOpt.Contains("SCTH=",TString::kIgnoreCase)) {//Thickness of the Sc
314 sscanf(addOpt.Data(),"SCTH=%f", &fECScintThick);
315 }
316 }
317 }
318}
319
b13bbe81 320//______________________________________________________________________
321AliEMCALGeometry * AliEMCALGeometry::GetInstance(){
05a92d59 322 // Returns the pointer of the unique instance
323
324 return static_cast<AliEMCALGeometry *>( fgGeom ) ;
2012850d 325}
173558f2 326
b13bbe81 327//______________________________________________________________________
328AliEMCALGeometry* AliEMCALGeometry::GetInstance(const Text_t* name,
329 const Text_t* title){
330 // Returns the pointer of the unique instance
331
332 AliEMCALGeometry * rv = 0;
333 if ( fgGeom == 0 ) {
334 if ( strcmp(name,"") == 0 ) rv = 0;
335 else {
336 fgGeom = new AliEMCALGeometry(name, title);
337 if ( fgInit ) rv = (AliEMCALGeometry * ) fgGeom;
338 else {
339 rv = 0;
340 delete fgGeom;
341 fgGeom = 0;
342 } // end if fgInit
343 } // end if strcmp(name,"")
344 }else{
345 if ( strcmp(fgGeom->GetName(), name) != 0 ) {
fdebddeb 346 printf("\ncurrent geometry is ") ;
347 printf(fgGeom->GetName());
348 printf("\n you cannot call ");
349 printf(name);
b13bbe81 350 }else{
9859bfc0 351 rv = (AliEMCALGeometry *) fgGeom;
b13bbe81 352 } // end if
353 } // end if fgGeom
354 return rv;
2012850d 355}
173558f2 356
c63c3c5d 357// These methods are obsolete but use in AliEMCALRecPoint - keep it now
ca8f5bd0 358//______________________________________________________________________
395c7ba2 359Int_t AliEMCALGeometry::TowerIndex(Int_t ieta,Int_t iphi) const {
360 // Returns the tower index number from the based on the Z and Phi
fdebddeb 361 // index numbers.
395c7ba2 362 // Inputs:
fdebddeb 363 // Int_t ieta // index along z axis [1-fNZ]
364 // Int_t iphi // index along phi axis [1-fNPhi]
395c7ba2 365 // Outputs:
366 // none.
367 // Returned
368 // Int_t index // Tower index number
369
370 if ( (ieta <= 0 || ieta>GetNEta()) ||
f1da4a27 371 (iphi <= 0 || iphi>GetNPhi())) {
372 Error("TowerIndex", "Unexpected parameters eta = %d phi = %d!", ieta, iphi) ;
373 return -1;
374 }
395c7ba2 375 return ( (iphi - 1)*GetNEta() + ieta );
ca8f5bd0 376}
173558f2 377
ca8f5bd0 378//______________________________________________________________________
fdebddeb 379void AliEMCALGeometry::TowerIndexes(Int_t index,Int_t &ieta,Int_t &iphi) const {
395c7ba2 380 // Inputs:
fdebddeb 381 // Int_t index // Tower index number [1-fNZ*fNPhi]
395c7ba2 382 // Outputs:
383 // Int_t ieta // index allong z axis [1-fNZ]
384 // Int_t iphi // index allong phi axis [1-fNPhi]
395c7ba2 385 // Returned
386 // none.
395c7ba2 387
fdebddeb 388 Int_t nindex = 0;
395c7ba2 389
fdebddeb 390 if ( IsInECA(index) ) { // ECAL index
395c7ba2 391 nindex = index ;
395c7ba2 392 }
f1da4a27 393 else {
394 Error("TowerIndexes", "Unexpected Id number!") ;
395 ieta = -1;
396 iphi = -1;
397 return;
398 }
399
395c7ba2 400 if (nindex%GetNZ())
401 iphi = nindex / GetNZ() + 1 ;
402 else
403 iphi = nindex / GetNZ() ;
404 ieta = nindex - (iphi - 1) * GetNZ() ;
405
406 if (gDebug==2)
fdebddeb 407 printf("TowerIndexes: index=%d,%d, ieta=%d, iphi = %d", index, nindex,ieta, iphi) ;
395c7ba2 408 return;
409
ca8f5bd0 410}
173558f2 411
ca8f5bd0 412//______________________________________________________________________
a34b7b9f 413void AliEMCALGeometry::EtaPhiFromIndex(Int_t index,Float_t &eta,Float_t &phi) const {
ca8f5bd0 414 // given the tower index number it returns the based on the eta and phi
415 // of the tower.
416 // Inputs:
fdebddeb 417 // Int_t index // Tower index number [1-fNZ*fNPhi]
ca8f5bd0 418 // Outputs:
419 // Float_t eta // eta of center of tower in pseudorapidity
420 // Float_t phi // phi of center of tower in degrees
421 // Returned
422 // none.
fdebddeb 423 Int_t ieta, iphi;
395c7ba2 424 Float_t deta, dphi ;
ca8f5bd0 425
fdebddeb 426 TowerIndexes(index,ieta,iphi);
395c7ba2 427
428 if (gDebug == 2)
fdebddeb 429 printf("EtaPhiFromIndex: index = %d, ieta = %d, iphi = %d", index, ieta, iphi) ;
395c7ba2 430
431 deta = (GetArm1EtaMax()-GetArm1EtaMin())/(static_cast<Float_t>(GetNEta()));
432 eta = GetArm1EtaMin() + ((static_cast<Float_t>(ieta) - 0.5 ))*deta;
433
434 dphi = (GetArm1PhiMax() - GetArm1PhiMin())/(static_cast<Float_t>(GetNPhi())); // in degrees.
435 phi = GetArm1PhiMin() + dphi*(static_cast<Float_t>(iphi) - 0.5);//iphi range [1-fNphi].
ca8f5bd0 436}
173558f2 437
ca8f5bd0 438//______________________________________________________________________
a34b7b9f 439Int_t AliEMCALGeometry::TowerIndexFromEtaPhi(Float_t eta,Float_t phi) const {
ca8f5bd0 440 // returns the tower index number based on the eta and phi of the tower.
441 // Inputs:
442 // Float_t eta // eta of center of tower in pseudorapidity
443 // Float_t phi // phi of center of tower in degrees
444 // Outputs:
445 // none.
446 // Returned
447 // Int_t index // Tower index number [1-fNZ*fNPhi]
395c7ba2 448
e908f07f 449 Int_t ieta,iphi;
ca8f5bd0 450
395c7ba2 451 ieta = static_cast<Int_t> ( 1 + (static_cast<Float_t>(GetNEta()) * (eta - GetArm1EtaMin()) / (GetArm1EtaMax() - GetArm1EtaMin())) ) ;
452
453 if( ieta <= 0 || ieta > GetNEta() ) {
454 Error("TowerIndexFromEtaPhi", "Unexpected (eta, phi) = (%f, %f) value, outside of EMCAL!", eta, phi) ;
455 return -1 ;
456 }
457
458 iphi = static_cast<Int_t> ( 1 + (static_cast<Float_t>(GetNPhi()) * (phi - GetArm1PhiMin()) / (GetArm1PhiMax() - GetArm1PhiMin())) ) ;
459
460 if( iphi <= 0 || iphi > GetNPhi() ) {
461 Error("TowerIndexFromEtaPhi", "Unexpected (eta, phi) = (%f, %f) value, outside of EMCAL!", eta, phi) ;
462 return -1 ;
463 }
464
465 return TowerIndex(ieta,iphi);
ca8f5bd0 466}
173558f2 467
ca8f5bd0 468//______________________________________________________________________
a34b7b9f 469Bool_t AliEMCALGeometry::AbsToRelNumbering(Int_t AbsId, Int_t *relid) const {
ca8f5bd0 470 // Converts the absolute numbering into the following array/
2608a1fc 471 // relid[0] = Row number inside EMCAL
472 // relid[1] = Column number inside EMCAL
ca8f5bd0 473 // Input:
474 // Int_t AbsId // Tower index number [1-2*fNZ*fNPhi]
475 // Outputs:
2608a1fc 476 // Int_t *relid // array of 2. Described above.
ca8f5bd0 477 Bool_t rv = kTRUE ;
fdebddeb 478 Int_t ieta=0,iphi=0,index=AbsId;
ca8f5bd0 479
fdebddeb 480 TowerIndexes(index,ieta,iphi);
2608a1fc 481 relid[0] = ieta;
482 relid[1] = iphi;
ca8f5bd0 483
484 return rv;
485}
173558f2 486
ca8f5bd0 487//______________________________________________________________________
395c7ba2 488void AliEMCALGeometry::PosInAlice(const Int_t *relid, Float_t &theta, Float_t &phi) const
489{
490 // Converts the relative numbering into the local EMCAL-module (x, z)
491 // coordinates
2608a1fc 492 Int_t ieta = relid[0]; // offset along x axis
493 Int_t iphi = relid[1]; // offset along z axis
395c7ba2 494 Int_t index;
495 Float_t eta;
496
497 index = TowerIndex(ieta,iphi);
498 EtaPhiFromIndex(index,eta,phi);
fdebddeb 499 //theta = 180.*(2.0*TMath::ATan(TMath::Exp(-eta)))/TMath::Pi();
500 theta = 2.0*TMath::ATan(TMath::Exp(-eta));
395c7ba2 501
fdebddeb 502 // correct for distance to IP
503 Float_t d = GetIP2ECASection() - GetIPDistance() ;
395c7ba2 504
505 Float_t correction = 1 + d/GetIPDistance() ;
506 Float_t tantheta = TMath::Tan(theta) * correction ;
507 theta = TMath::ATan(tantheta) * TMath::RadToDeg() ;
508 if (theta < 0 )
509 theta += 180. ;
510
511 return;
512}
ca8f5bd0 513
395c7ba2 514//______________________________________________________________________
09884213 515void AliEMCALGeometry::PosInAlice(Int_t absid, Float_t &theta, Float_t &phi) const
395c7ba2 516{
517 // Converts the relative numbering into the local EMCAL-module (x, z)
518 // coordinates
2608a1fc 519 Int_t relid[2] ;
395c7ba2 520 AbsToRelNumbering(absid, relid) ;
2608a1fc 521 Int_t ieta = relid[0]; // offset along x axis
522 Int_t iphi = relid[1]; // offset along z axis
395c7ba2 523 Int_t index;
524 Float_t eta;
525
526 index = TowerIndex(ieta,iphi);
527 EtaPhiFromIndex(index,eta,phi);
528 theta = 2.0*TMath::ATan(TMath::Exp(-eta)) ;
529
fdebddeb 530 // correct for distance to IP
395c7ba2 531 Float_t d = 0. ;
fdebddeb 532 if (IsInECA(absid))
88cb7938 533 d = GetIP2ECASection() - GetIPDistance() ;
f1da4a27 534 else {
535 Error("PosInAlice", "Unexpected id # %d!", absid) ;
536 return;
537 }
395c7ba2 538
539 Float_t correction = 1 + d/GetIPDistance() ;
540 Float_t tantheta = TMath::Tan(theta) * correction ;
541 theta = TMath::ATan(tantheta) * TMath::RadToDeg() ;
542 if (theta < 0 )
543 theta += 180. ;
544
545 return;
ca8f5bd0 546}
6119e5db 547
548//______________________________________________________________________
549void AliEMCALGeometry::XYZFromIndex(const Int_t *relid,Float_t &x,Float_t &y, Float_t &z) const {
550 // given the tower relative number it returns the X, Y and Z
551 // of the tower.
552
553 // Outputs:
554 // Float_t x // x of center of tower in cm
555 // Float_t y // y of center of tower in cm
556 // Float_t z // z of centre of tower in cm
557 // Returned
558 // none.
559
fdebddeb 560 Float_t eta,theta, phi,cylradius=0. ;
6119e5db 561
2608a1fc 562 Int_t ieta = relid[0]; // offset along x axis
563 Int_t iphi = relid[1]; // offset along z axis.
6119e5db 564 Int_t index;
565
395c7ba2 566 index = TowerIndex(ieta,iphi);
6119e5db 567 EtaPhiFromIndex(index,eta,phi);
568 theta = 180.*(2.0*TMath::ATan(TMath::Exp(-eta)))/TMath::Pi();
6119e5db 569
fdebddeb 570 cylradius = GetIP2ECASection() ;
a97849a9 571
395c7ba2 572 Double_t kDeg2Rad = TMath::DegToRad() ;
fdebddeb 573 x = cylradius * TMath::Cos(phi * kDeg2Rad ) ;
574 y = cylradius * TMath::Sin(phi * kDeg2Rad ) ;
575 z = cylradius / TMath::Tan(theta * kDeg2Rad ) ;
6119e5db 576
577 return;
578}
579
395c7ba2 580//______________________________________________________________________
09884213 581void AliEMCALGeometry::XYZFromIndex(Int_t absid, TVector3 &v) const {
395c7ba2 582 // given the tower relative number it returns the X, Y and Z
583 // of the tower.
584
585 // Outputs:
586 // Float_t x // x of center of tower in cm
587 // Float_t y // y of center of tower in cm
588 // Float_t z // z of centre of tower in cm
589 // Returned
590 // none.
591
fdebddeb 592 Float_t theta, phi,cylradius=0. ;
395c7ba2 593
594 PosInAlice(absid, theta, phi) ;
595
88cb7938 596 if ( IsInECA(absid) )
fdebddeb 597 cylradius = GetIP2ECASection() ;
f1da4a27 598 else {
599 Error("XYZFromIndex", "Unexpected Tower section") ;
600 return;
601 }
395c7ba2 602
603 Double_t kDeg2Rad = TMath::DegToRad() ;
fdebddeb 604 v.SetX(cylradius * TMath::Cos(phi * kDeg2Rad ) );
605 v.SetY(cylradius * TMath::Sin(phi * kDeg2Rad ) );
606 v.SetZ(cylradius / TMath::Tan(theta * kDeg2Rad ) ) ;
395c7ba2 607
608 return;
609}
ab37d09c 610
611Bool_t AliEMCALGeometry::IsInEMCAL(Double_t x, Double_t y, Double_t z) const {
612 // Checks whether point is inside the EMCal volume
613 //
614 // Code uses cylindrical approximation made of inner radius (for speed)
615 //
616 // Points behind EMCAl, i.e. R > outer radius, but eta, phi in acceptance
617 // are considered to inside
618
619 Double_t r=sqrt(x*x+y*y);
620
621 if ( r > fEnvelop[0] ) {
622 Double_t theta;
623 theta = TMath::ATan2(r,z);
624 Double_t eta;
625 if(theta == 0)
626 eta = 9999;
627 else
628 eta = -TMath::Log(TMath::Tan(theta/2.));
629 if (eta < fArm1EtaMin || eta > fArm1EtaMax)
630 return 0;
631
632 Double_t phi = TMath::ATan2(y,x) * 180./TMath::Pi();
633 if (phi > fArm1PhiMin && phi < fArm1PhiMax)
634 return 1;
635 }
636 return 0;
637}
c63c3c5d 638// ==
1963b290 639
640//
641// == Shish-kebab cases ==
642//
eb0b1051 643Int_t AliEMCALGeometry::GetAbsCellId(Int_t nSupMod, Int_t nTower, Int_t nIphi, Int_t nIeta)
d87bd045 644{ // 27-aug-04;
645 // corr. 21-sep-04;
646 // 13-oct-05; 110 degree case
647 // 1 <= nSupMod <= fNumberOfSuperModules
648 // 1 <= nTower <= fNPHI * fNZ ( fNPHI * fNZ/2 for fKey110DEG=1)
649 // 1 <= nIphi <= fNPHIdiv
650 // 1 <= nIeta <= fNETAdiv
651 // 1 <= absid <= fNCells
652 static Int_t id=0; // have to change from 1 to fNCells
653 if(fKey110DEG == 1 && nSupMod > 10) { // 110 degree case; last two supermodules
654 id = fNCellsInSupMod*10 + (fNCellsInSupMod/2)*(nSupMod-11);
655 } else {
656 id = fNCellsInSupMod*(nSupMod-1);
657 }
1963b290 658 id += fNCellsInTower *(nTower-1);
659 id += fNPHIdiv *(nIphi-1);
660 id += nIeta;
661 if(id<=0 || id > fNCells) {
500aeccc 662// printf(" wrong numerations !!\n");
663// printf(" id %6i(will be force to -1)\n", id);
664// printf(" fNCells %6i\n", fNCells);
665// printf(" nSupMod %6i\n", nSupMod);
666// printf(" nTower %6i\n", nTower);
667// printf(" nIphi %6i\n", nIphi);
668// printf(" nIeta %6i\n", nIeta);
d87bd045 669 id = -TMath::Abs(id);
1963b290 670 }
671 return id;
672}
673
674Bool_t AliEMCALGeometry::CheckAbsCellId(Int_t ind)
675{ // 17-niv-04 - analog of IsInECA
676 if(name.Contains("TRD")) {
677 if(ind<=0 || ind > fNCells) return kFALSE;
678 else return kTRUE;
679 } else return IsInECA(ind);
680}
681
eb0b1051 682Bool_t AliEMCALGeometry::GetCellIndex(Int_t absId,Int_t &nSupMod,Int_t &nTower,Int_t &nIphi,Int_t &nIeta)
1963b290 683{ // 21-sep-04
d87bd045 684 // 19-oct-05;
685 static Int_t tmp=0, sm10=0;
1963b290 686 if(absId<=0 || absId>fNCells) {
500aeccc 687// Info("GetCellIndex"," wrong abs Id %i !! \n", absId);
1963b290 688 return kFALSE;
689 }
d87bd045 690 sm10 = fNCellsInSupMod*10;
691 if(fKey110DEG == 1 && absId > sm10) { // 110 degree case; last two supermodules
692 nSupMod = (absId-1-sm10) / (fNCellsInSupMod/2) + 11;
693 tmp = (absId-1-sm10) % (fNCellsInSupMod/2);
694 } else {
695 nSupMod = (absId-1) / fNCellsInSupMod + 1;
696 tmp = (absId-1) % fNCellsInSupMod;
697 }
1963b290 698
699 nTower = tmp / fNCellsInTower + 1;
700 tmp = tmp % fNCellsInTower;
d87bd045 701 nIphi = tmp / fNPHIdiv + 1;
702 nIeta = tmp % fNPHIdiv + 1;
1963b290 703
704 return kTRUE;
705}
706
eb0b1051 707void AliEMCALGeometry::GetTowerPhiEtaIndexInSModule(Int_t nSupMod, Int_t nTower, int &iphit, int &ietat)
d87bd045 708{ // added nSupMod; have to check - 19-oct-05 !
709 static Int_t nphi;
710
711 if(fKey110DEG == 1 && nSupMod>=11) nphi = fNPhi/2;
712 else nphi = fNPhi;
713
714 ietat = (nTower-1)/nphi + 1; // have to change from 1 to fNZ
d87bd045 715 iphit = (nTower-1)%nphi + 1; // have to change from 1 to fNPhi
716}
717
eb0b1051 718void AliEMCALGeometry::GetCellPhiEtaIndexInSModule(Int_t nSupMod, Int_t nTower, Int_t nIphi, Int_t nIeta,
1963b290 719int &iphi, int &ieta)
c01485dd 720{ // added nSupMod; Nov 25, 05
721 static Int_t iphit, ietat;
722
723 GetTowerPhiEtaIndexInSModule(nSupMod,nTower, iphit, ietat);
724 // have to change from 1 to fNZ*fNETAdiv
725 ieta = (ietat-1)*fNETAdiv + (3-nIeta); // x(module) = -z(SM)
726 // iphi - have to change from 1 to fNPhi*fNPHIdiv
727 iphi = (iphit-1)*fNPHIdiv + nIphi; // y(module) = y(SM)
1963b290 728}
c63c3c5d 729// Service routine
730int AliEMCALGeometry::ParseString(const TString &topt, TObjArray &Opt)
731{ // Feb 06, 2006
732 Ssiz_t begin, index, end, end2;
733 begin = index = end = end2 = 0;
734 TRegexp separator("[^ ;,\\t\\s/]+");
735 while ( (begin < topt.Length()) && (index != kNPOS) ) {
736 // loop over given options
737 index = topt.Index(separator,&end,begin);
738 if (index >= 0 && end >= 1) {
739 TString substring(topt(index,end));
740 Opt.Add(new TObjString(substring.Data()));
741 }
742 begin += end+1;
743 }
744 return Opt.GetEntries();
745}