]>
Commit | Line | Data |
---|---|---|
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 | 45 | ClassImp(AliEMCALGeometry); |
2012850d | 46 | |
b13bbe81 | 47 | AliEMCALGeometry *AliEMCALGeometry::fgGeom = 0; |
48 | Bool_t AliEMCALGeometry::fgInit = kFALSE; | |
2012850d | 49 | |
b13bbe81 | 50 | //______________________________________________________________________ |
51 | AliEMCALGeometry::~AliEMCALGeometry(void){ | |
52 | // dtor | |
2012850d | 53 | } |
b13bbe81 | 54 | //______________________________________________________________________ |
55 | void 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 | //______________________________________________________________________ |
100 | AliEMCALGeometry * AliEMCALGeometry::GetInstance(){ | |
101 | // Returns the pointer of the unique instance | |
2012850d | 102 | |
b13bbe81 | 103 | return (AliEMCALGeometry *) fgGeom; |
2012850d | 104 | } |
b13bbe81 | 105 | //______________________________________________________________________ |
106 | AliEMCALGeometry* 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 | //______________________________________________________________________ |
135 | Int_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 | //______________________________________________________________________ | |
160 | void 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 | //______________________________________________________________________ | |
193 | void 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 | //______________________________________________________________________ | |
217 | Int_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 | //______________________________________________________________________ | |
255 | Int_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 | //______________________________________________________________________ | |
268 | Bool_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 | //______________________________________________________________________ | |
292 | void 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 | /* | |
311 | Boot_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 | */ |