undo precedent change
[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
22// between 0 and 120 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// EMCALArch2x has more modules along both phi and eta
27// EMCALArchxa has less Layers in the Radial Direction
b13bbe81 28//*-- Author: Sahal Yacoob (LBL / UCT)
29// and : Yves Schutz (SUBATECH)
30// and : Jennifer Klay (LBL)
2012850d 31
32// --- ROOT system ---
33
34// --- Standard library ---
35
36#include <iostream.h>
37
38// --- AliRoot header files ---
ca8f5bd0 39#include <TMath.h>
40// -- ALICE Headers.
2012850d 41#include "AliConst.h"
ca8f5bd0 42// --- EMCAL headers
43#include "AliEMCALGeometry.h"
2012850d 44
b13bbe81 45ClassImp(AliEMCALGeometry);
2012850d 46
b13bbe81 47AliEMCALGeometry *AliEMCALGeometry::fgGeom = 0;
48Bool_t AliEMCALGeometry::fgInit = kFALSE;
2012850d 49
b13bbe81 50//______________________________________________________________________
51AliEMCALGeometry::~AliEMCALGeometry(void){
52 // dtor
2012850d 53}
b13bbe81 54//______________________________________________________________________
55void AliEMCALGeometry::Init(void){
56 // Initializes the EMCAL parameters
57
58 if(!( (strcmp( fName, "EMCALArch1a" ) == 0) |
59 (strcmp( fName, "EMCALArch1b" ) == 0) |
60 (strcmp( fName, "EMCALArch2a" ) == 0) |
61 (strcmp( fName, "EMCALArch2b" ) == 0) )){
62 fgInit = kFALSE;
63 cout <<"Instance " << fName << " undefined" << endl;
64 } // end if
65 fgInit = kTRUE;
66
67 // geometry
68 fAirGap = 5.0;
69 fArm1PhiMin = 0.0;
70 fArm1PhiMax = 120.0;
71
72 fIPDistance = 454.0;
73 fZLength = 817.0;
74 fEnvelop[0] = fIPDistance;
75 fEnvelop[2] = fZLength;
76 fGap2Active = 1.0;
77 fShellThickness = 3.18 + 1.2 + (double)((2*fNLayers -3)/2);
78 fEnvelop[1] = fIPDistance + fShellThickness;
79
80 if (((strcmp( fName, "EMCALArch1a" )) == 0) |
81 ((strcmp( fName, "EMCALArch1b" )) == 0)){
82 fNZ = 96;
83 fNPhi = 144;
84 } // end if
85 if (((strcmp( fName, "EMCALArch2a" )) == 0) |
86 ((strcmp( fName, "EMCALArch2b" )) == 0)){
87 fNZ = 112;
88 fNPhi = 168;
89 } // end if
90 if (((strcmp( fName, "EMCALArch1a" )) == 0) |
91 ((strcmp( fName, "EMCALArch2a" )) == 0)){
92 fNLayers = 21;
93 } // end if
94 if (((strcmp( fName, "EMCALArch1b" )) == 0) |
95 ((strcmp( fName, "EMCALArch2b" )) == 0)){
96 fNLayers = 25;
97 } // end if
2012850d 98}
b13bbe81 99//______________________________________________________________________
100AliEMCALGeometry * AliEMCALGeometry::GetInstance(){
101 // Returns the pointer of the unique instance
2012850d 102
b13bbe81 103 return (AliEMCALGeometry *) fgGeom;
2012850d 104}
b13bbe81 105//______________________________________________________________________
106AliEMCALGeometry* AliEMCALGeometry::GetInstance(const Text_t* name,
107 const Text_t* title){
108 // Returns the pointer of the unique instance
109
110 AliEMCALGeometry * rv = 0;
111 if ( fgGeom == 0 ) {
112 if ( strcmp(name,"") == 0 ) rv = 0;
113 else {
114 fgGeom = new AliEMCALGeometry(name, title);
115 if ( fgInit ) rv = (AliEMCALGeometry * ) fgGeom;
116 else {
117 rv = 0;
118 delete fgGeom;
119 fgGeom = 0;
120 } // end if fgInit
121 } // end if strcmp(name,"")
122 }else{
123 if ( strcmp(fgGeom->GetName(), name) != 0 ) {
124 cout << "AliEMCALGeometry <E> : current geometry is "
125 << fgGeom->GetName() << endl
126 << " you cannot call " << name
127 << endl;
128 }else{
129 rv = (AliEMCALGeometry *) fgGeom;
130 } // end if
131 } // end if fgGeom
132 return rv;
2012850d 133}
ca8f5bd0 134//______________________________________________________________________
135Int_t AliEMCALGeometry::TowerIndex(Int_t iz,Int_t iphi,Int_t ipre){
136 // Returns the tower index number from the based on the Z and Phi
137 // index numbers. There are 2 times the number of towers to separate
138 // out the full towsers from the pre-towsers.
139 // Inputs:
140 // Int_t iz // index allong z axis [1-fNZ]
141 // Int_t iphi // index allong phi axis [1-fNPhi]
142 // Int_t ipre // 0 = Full tower, 1 = Pre-shower tower only. [0,1]
143 // Outputs:
144 // none.
145 // Returned
146 // Int_t the absoulute tower index. [1-2*fNZ*fNPhi]
147 Int_t index;
148
149 if((iz<=0 || iz>GetNZ()) || (iphi<=0 || iphi>GetNPhi()) ||
150 (ipre<0 || ipre>1) ){
151 cout << "inputs out of range iz=" << iz << "[1-" << GetNZ();
152 cout << "] iPhi=" << iphi << "[1-" << GetNPhi() << "] ipre=";
153 cout << ipre << "[0,1]. returning -1" << endl;
154 return -1;
155 } // end if
156 index = iphi + GetNPhi()*(iz-1) + ipre*(GetNPhi()*GetNZ());
157 return index;
158}
159//______________________________________________________________________
160void AliEMCALGeometry::TowerIndexes(Int_t index,Int_t &iz,Int_t &iphi,
161 Int_t &ipre){
162 // given the tower index number it returns the based on the Z and Phi
163 // index numbers and if it is for the full tower or the pre-tower number.
164 // There are 2 times the number of towers to separate
165 // out the full towsers from the pre-towsers.
166 // Inputs:
167 // Int_t index // Tower index number [1-2*fNZ*fNPhi]
168 // Outputs:
169 // Int_t iz // index allong z axis [1-fNZ]
170 // Int_t iphi // index allong phi axis [1-fNPhi]
171 // Int_t ipre // 0 = Full tower, 1 = Pre-shower tower only. [0,1]
172 // Returned
173 // none.
174 Int_t itowers;
175
176 itowers = GetNZ()*GetNPhi();
177 if(index<1 || index>2*itowers){
178 cout << "index=" << index <<" is out of range [1-";
179 cout << 2*itowers << "], returning -1 for all." << endl;
180 iz = -1; iphi = -1; ipre = -1;
181 return ;
182 } // end if
183 ipre = 0;
184 if(index>itowers){ // pre shower indexs
185 ipre = 1;
186 index = index - itowers;
187 } // end if
188 iz = 1+ (Int_t)(index/GetNPhi());
189 iphi = index - GetNPhi()*(iz-1);
190 return;
191}
192//______________________________________________________________________
193void AliEMCALGeometry::EtaPhiFromIndex(Int_t index,Float_t &eta,Float_t &phi){
194 // given the tower index number it returns the based on the eta and phi
195 // of the tower.
196 // Inputs:
197 // Int_t index // Tower index number [1-2*fNZ*fNPhi]
198 // Outputs:
199 // Float_t eta // eta of center of tower in pseudorapidity
200 // Float_t phi // phi of center of tower in degrees
201 // Returned
202 // none.
203 Int_t iz,iphi,ipre;
204 Double_t dz,dphi,zmax,z,phid,r;
205
206 TowerIndexes(index,iz,iphi,ipre);
207 zmax = (Double_t) GetZLength();
208 dz = zmax/((Double_t)GetNZ());
209 r = GetIPDistance();
210 z = dz*((Double_t)iz - 0.5); // iz range [1-fNZ].
211 eta = -TMath::Log(TMath::Tan(0.5*TMath::ATan2(r,z)));
212 dphi = GetArm1PhiMax() - GetArm1PhiMin(); // in degrees.
213 phid = GetArm1PhiMin() + dphi*((Double_t)iphi -0.5);//iphi range [1-fNphi].
214 phi = phid;
215}
216//______________________________________________________________________
217Int_t AliEMCALGeometry::TowerIndexFromEtaPhi(Float_t eta,Float_t phi){
218 // returns the tower index number based on the eta and phi of the tower.
219 // Inputs:
220 // Float_t eta // eta of center of tower in pseudorapidity
221 // Float_t phi // phi of center of tower in degrees
222 // Outputs:
223 // none.
224 // Returned
225 // Int_t index // Tower index number [1-fNZ*fNPhi]
226 Int_t iz,iphi;
227 Double_t z,zp,r,zl;
228
229 r = GetIPDistance();
230 z = 2.0*TMath::ATan(TMath::Exp(-eta));
231 z = TMath::Tan(z);
232 if(z!=0.0) z = r/z;
233 else z = 0.0;
234 zp = z;
235 zl = GetZLength();
236 z = 0.5*zl+z;
237 iz = (Int_t)(((Double_t)GetNZ())*z/zl);
238 if(iz<=0 || iz>GetNZ()){
239 cout << "z=" << zp << " is outside of EMCAL. r=" << r << " eta =";
240 cout << eta << " z length =" << zl ;
241 cout << " returning -1" << endl;
242 return -1;
243 } // end if
244 iphi =(Int_t)(((Double_t)GetNPhi())*((Double_t)phi)/
245 ((Double_t)(GetArm1PhiMax() - GetArm1PhiMin())));
246 if(iphi<=0 || iphi>GetNPhi()){
247 cout << "phi=" << phi << " is outside of EMCAL. r=" << r;
248 cout << " Phimin=" << GetArm1PhiMin() << " PhiMax=" << GetArm1PhiMax();
249 cout << " returning -1" << endl;
250 return -1;
251 } // end if
252 return TowerIndex(iz,iphi,0);
253}
254//______________________________________________________________________
255Int_t AliEMCALGeometry::PreTowerIndexFromEtaPhi(Float_t eta,Float_t phi){
256 // returns the pretower index number based on the eta and phi of the tower.
257 // Inputs:
258 // Float_t eta // eta of center of tower in pseudorapidity
259 // Float_t phi // phi of center of tower in degrees
260 // Outputs:
261 // none.
262 // Returned
263 // Int_t index // PreTower index number [fNZ*fNPhi-2*fNZ*fNPhi]
264
265 return GetNZ()*GetNPhi()+TowerIndexFromEtaPhi(eta,phi);
266}
267//______________________________________________________________________
268Bool_t AliEMCALGeometry::AbsToRelNumbering(Int_t AbsId, Int_t *relid){
269 // Converts the absolute numbering into the following array/
270 // relid[0] = EMCAL Module number 1:1 (EMCAL arm number)
271 // relid[1] = 0 Not in Pre Shower layers
272 // = -1 In Pre Shower
273 // relid[2] = Row number inside EMCAL
274 // relid[3] = Column number inside EMCAL
275 // Input:
276 // Int_t AbsId // Tower index number [1-2*fNZ*fNPhi]
277 // Outputs:
278 // Int_t *relid // array of 5. Discribed above.
279 Bool_t rv = kTRUE ;
280 Int_t iz=0,iphi=0,ipre=0,index=AbsId;
281
282 TowerIndexes(index,iz,iphi,ipre);
283 relid[0] = 1;
284 relid[1] = 0;
285 if(ipre==1) relid[1] = -1;
286 relid[2] = iz;
287 relid[3] = iphi;
288
289 return rv;
290}
291//______________________________________________________________________
292void AliEMCALGeometry::RelPosInModule(const Int_t *relid,Float_t &theta,
293 Float_t &phi){
294 // Converts the relative numbering into the local PHOS-module (x, z)
295 // coordinates
296 Int_t iz = relid[2]; // offset along x axis
297 Int_t iphi = relid[3]; // offset along z axis
298 Int_t ipre = relid[1]; // indecates -1 preshower, or 0 full tower.
299 Int_t index;
300 Float_t eta;
301
302 if(ipre==-1) ipre = 1;
303 index = TowerIndex(iz,iphi,ipre);
304 EtaPhiFromIndex(index,eta,phi);
305 theta = 180.*(2.0*TMath::ATan(TMath::Exp(-eta)))/TMath::Pi();
306
307 return;
308}
309//______________________________________________________________________
310/*
311Boot_t AliEMCALGeometry::AreNeighbours(Int_t index1,Int_t index2){
312 // Returns kTRUE if the two towers are neighbours or not, including
313 // diagonals. Both indexes are required to be either towers or preshower.
314 // Inputs:
315 // Int_t index1 // index of tower 1
316 // Int_t index2 // index of tower 2
317 // Outputs:
318 // none.
319 // Returned
320 // Boot_t kTRUE if the towers are neighbours otherwise false.
321 Boot_t anb = kFALSE;
322 Int_t iz1 = 0, iz2 = 0, iphi1 = 0, iphi2 = 0, ipre1 = 0, ipre2 = 0;
323
324 TowerIndexes(index1,iz1,iphi1,ipre1);
325 TowerIndexes(index2,iz2,iphi2,ipre2);
326 if(ipre1!=ipre2) return anb;
327 if((iz1>=iz2-1 && iz1<=iz2+1) && (iphi1>=iphi2-1 && iphi1<=iphi2+1))
328 anb = kTRUE;
329 return anb;
330}
331 */