]>
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 | ||
e908f07f | 58 | fgInit = kFALSE; // Assume failer untill proven otherwise. |
05a92d59 | 59 | |
60 | TString name(GetName()) ; | |
61 | ||
62 | if( name != "EMCALArch1a" && | |
63 | name != "EMCALArch1b" && | |
64 | name != "EMCALArch2a" && | |
65 | name != "EMCALArch2b" ){ | |
66 | cerr << "ERROR: " << ClassName() << "::Init -> " << name.Data() | |
67 | << " is not a known geometry (choose among EMCALArch1a, EMCALArch1b, EMCALArch2a and EMCALArch2b)" | |
68 | << endl ; | |
69 | abort() ; | |
b13bbe81 | 70 | } // end if |
e908f07f | 71 | // |
05a92d59 | 72 | if ( name == "EMCALArch1a" || |
73 | name == "EMCALArch1b" ) { | |
b13bbe81 | 74 | fNZ = 96; |
75 | fNPhi = 144; | |
76 | } // end if | |
05a92d59 | 77 | if ( name == "EMCALArch2a" || |
78 | name, "EMCALArch2b" ) { | |
b13bbe81 | 79 | fNZ = 112; |
80 | fNPhi = 168; | |
81 | } // end if | |
05a92d59 | 82 | if ( name == "EMCALArch1a" || |
83 | name == "EMCALArch2a" ) { | |
b13bbe81 | 84 | fNLayers = 21; |
85 | } // end if | |
05a92d59 | 86 | if ( name == "EMCALArch1b" || |
87 | name == "EMCALArch2b" ) { | |
b13bbe81 | 88 | fNLayers = 25; |
89 | } // end if | |
e908f07f | 90 | |
91 | // geometry | |
92 | fAirGap = 5.0; // cm, air gap between EMCAL mother volume and | |
93 | // active material. | |
94 | fAlFrontThick = 3.18; // cm, Thickness of front Al layer | |
95 | fPbRadThickness = 0.5; // cm, Thickness of theh Pb radiators. | |
96 | fPreShowerSintThick = 0.6; // cm, Thickness of the sintilator for the | |
97 | // preshower part of the calorimeter | |
98 | fFullShowerSintThick = 0.5; // cm, Thickness of the sintilator for the | |
99 | // full shower part of the calorimeter | |
6365f121 | 100 | fArm1PhiMin = 60.0; // degrees, Starting EMCAL Phi position |
101 | fArm1PhiMax = 180.0; // degrees, Ending EMCAL Phi position | |
e908f07f | 102 | fArm1EtaMin = -0.7; // pseudorapidity, Starting EMCAL Eta position |
103 | fArm1EtaMax = +0.7; // pseudorapidity, Ending EMCAL Eta position | |
104 | fIPDistance = 454.0; // cm, Radial distance to inner surface of EMCAL | |
105 | fShellThickness = GetAlFrontThickness() + 2.*GetPreSintThick() + | |
106 | (fNLayers-2)*GetFullSintThick()+(fNLayers-1)*GetPbRadThick(); | |
107 | //below; cm, Z lenght of the EMCAL. | |
108 | fZLength = 2.*ZFromEtaR(fIPDistance+fShellThickness,fArm1EtaMax); | |
109 | fEnvelop[0] = fIPDistance; // mother volume inner radius | |
110 | fEnvelop[1] = fIPDistance + fShellThickness; // mother volume outer r. | |
111 | fEnvelop[2] = 1.00001*fZLength; // add some padding for mother volume. | |
112 | fGap2Active = 1.0; // cm, Gap between | |
113 | fgInit = kTRUE; | |
2012850d | 114 | } |
b13bbe81 | 115 | //______________________________________________________________________ |
116 | AliEMCALGeometry * AliEMCALGeometry::GetInstance(){ | |
05a92d59 | 117 | // Returns the pointer of the unique instance |
118 | ||
119 | return static_cast<AliEMCALGeometry *>( fgGeom ) ; | |
2012850d | 120 | } |
b13bbe81 | 121 | //______________________________________________________________________ |
122 | AliEMCALGeometry* AliEMCALGeometry::GetInstance(const Text_t* name, | |
123 | const Text_t* title){ | |
124 | // Returns the pointer of the unique instance | |
125 | ||
126 | AliEMCALGeometry * rv = 0; | |
127 | if ( fgGeom == 0 ) { | |
128 | if ( strcmp(name,"") == 0 ) rv = 0; | |
129 | else { | |
130 | fgGeom = new AliEMCALGeometry(name, title); | |
131 | if ( fgInit ) rv = (AliEMCALGeometry * ) fgGeom; | |
132 | else { | |
133 | rv = 0; | |
134 | delete fgGeom; | |
135 | fgGeom = 0; | |
136 | } // end if fgInit | |
137 | } // end if strcmp(name,"") | |
138 | }else{ | |
139 | if ( strcmp(fgGeom->GetName(), name) != 0 ) { | |
140 | cout << "AliEMCALGeometry <E> : current geometry is " | |
141 | << fgGeom->GetName() << endl | |
142 | << " you cannot call " << name | |
143 | << endl; | |
144 | }else{ | |
145 | rv = (AliEMCALGeometry *) fgGeom; | |
146 | } // end if | |
147 | } // end if fgGeom | |
148 | return rv; | |
2012850d | 149 | } |
ca8f5bd0 | 150 | //______________________________________________________________________ |
a34b7b9f | 151 | Int_t AliEMCALGeometry::TowerIndex(Int_t ieta,Int_t iphi,Int_t ipre) const { |
ca8f5bd0 | 152 | // Returns the tower index number from the based on the Z and Phi |
153 | // index numbers. There are 2 times the number of towers to separate | |
154 | // out the full towsers from the pre-towsers. | |
155 | // Inputs: | |
e908f07f | 156 | // Int_t ieta // index allong z axis [1-fNZ] |
ca8f5bd0 | 157 | // Int_t iphi // index allong phi axis [1-fNPhi] |
158 | // Int_t ipre // 0 = Full tower, 1 = Pre-shower tower only. [0,1] | |
159 | // Outputs: | |
160 | // none. | |
161 | // Returned | |
162 | // Int_t the absoulute tower index. [1-2*fNZ*fNPhi] | |
163 | Int_t index; | |
164 | ||
e908f07f | 165 | if((ieta<=0 || ieta>GetNEta()) || (iphi<=0 || iphi>GetNPhi()) || |
ca8f5bd0 | 166 | (ipre<0 || ipre>1) ){ |
e908f07f | 167 | cout << "inputs out of range ieta=" << ieta << " [1-" << GetNEta(); |
168 | cout << "] iphi=" << iphi << " [1-" << GetNPhi() << "] ipre="; | |
ca8f5bd0 | 169 | cout << ipre << "[0,1]. returning -1" << endl; |
170 | return -1; | |
171 | } // end if | |
e908f07f | 172 | index = iphi + GetNPhi()*(ieta-1) + ipre*(GetNPhi()*GetNEta()); |
ca8f5bd0 | 173 | return index; |
174 | } | |
175 | //______________________________________________________________________ | |
e908f07f | 176 | void AliEMCALGeometry::TowerIndexes(Int_t index,Int_t &ieta,Int_t &iphi, |
a34b7b9f | 177 | Int_t &ipre) const { |
ca8f5bd0 | 178 | // given the tower index number it returns the based on the Z and Phi |
179 | // index numbers and if it is for the full tower or the pre-tower number. | |
180 | // There are 2 times the number of towers to separate | |
181 | // out the full towsers from the pre-towsers. | |
182 | // Inputs: | |
183 | // Int_t index // Tower index number [1-2*fNZ*fNPhi] | |
184 | // Outputs: | |
e908f07f | 185 | // Int_t ieta // index allong z axis [1-fNZ] |
ca8f5bd0 | 186 | // Int_t iphi // index allong phi axis [1-fNPhi] |
187 | // Int_t ipre // 0 = Full tower, 1 = Pre-shower tower only. [0,1] | |
188 | // Returned | |
189 | // none. | |
190 | Int_t itowers; | |
191 | ||
e908f07f | 192 | itowers = GetNEta()*GetNPhi(); |
ca8f5bd0 | 193 | if(index<1 || index>2*itowers){ |
194 | cout << "index=" << index <<" is out of range [1-"; | |
195 | cout << 2*itowers << "], returning -1 for all." << endl; | |
e908f07f | 196 | ieta = -1; iphi = -1; ipre = -1; |
ca8f5bd0 | 197 | return ; |
198 | } // end if | |
199 | ipre = 0; | |
200 | if(index>itowers){ // pre shower indexs | |
201 | ipre = 1; | |
202 | index = index - itowers; | |
203 | } // end if | |
4b988fd2 | 204 | ieta = 1+ (Int_t)((index-1)/GetNPhi()); |
205 | iphi = index - GetNPhi()*(ieta-1); | |
ca8f5bd0 | 206 | return; |
207 | } | |
208 | //______________________________________________________________________ | |
a34b7b9f | 209 | void AliEMCALGeometry::EtaPhiFromIndex(Int_t index,Float_t &eta,Float_t &phi) const { |
ca8f5bd0 | 210 | // given the tower index number it returns the based on the eta and phi |
211 | // of the tower. | |
212 | // Inputs: | |
213 | // Int_t index // Tower index number [1-2*fNZ*fNPhi] | |
214 | // Outputs: | |
215 | // Float_t eta // eta of center of tower in pseudorapidity | |
216 | // Float_t phi // phi of center of tower in degrees | |
217 | // Returned | |
218 | // none. | |
e908f07f | 219 | Int_t ieta,iphi,ipre; |
220 | Double_t deta,dphi,phid; | |
ca8f5bd0 | 221 | |
e908f07f | 222 | TowerIndexes(index,ieta,iphi,ipre); |
223 | deta = (GetArm1EtaMax()-GetArm1EtaMin())/((Float_t)GetNEta()); | |
224 | eta = GetArm1EtaMin() + (((Float_t)ieta)-0.5)*deta; | |
225 | dphi = (GetArm1PhiMax() - GetArm1PhiMin())/((Float_t)GetNPhi()); // in degrees. | |
226 | phid = GetArm1PhiMin() + dphi*((Float_t)iphi -0.5);//iphi range [1-fNphi]. | |
ca8f5bd0 | 227 | phi = phid; |
228 | } | |
229 | //______________________________________________________________________ | |
a34b7b9f | 230 | Int_t AliEMCALGeometry::TowerIndexFromEtaPhi(Float_t eta,Float_t phi) const { |
ca8f5bd0 | 231 | // returns the tower index number based on the eta and phi of the tower. |
232 | // Inputs: | |
233 | // Float_t eta // eta of center of tower in pseudorapidity | |
234 | // Float_t phi // phi of center of tower in degrees | |
235 | // Outputs: | |
236 | // none. | |
237 | // Returned | |
238 | // Int_t index // Tower index number [1-fNZ*fNPhi] | |
e908f07f | 239 | Int_t ieta,iphi; |
ca8f5bd0 | 240 | |
e908f07f | 241 | ieta = 1 + (Int_t)(((Float_t)GetNEta())*(eta-GetArm1EtaMin())/ |
242 | (GetArm1EtaMax() - GetArm1EtaMin())); | |
243 | if(ieta<=0 || ieta>GetNEta()){ | |
244 | cout << "TowerIndexFromEtaPhi:"; | |
245 | cout << "ieta = "<< ieta << " eta=" << eta << " is outside of EMCAL. etamin="; | |
246 | cout << GetArm1EtaMin() << " to etamax=" << GetArm1EtaMax(); | |
ca8f5bd0 | 247 | cout << " returning -1" << endl; |
248 | return -1; | |
249 | } // end if | |
e908f07f | 250 | iphi = 1 + (Int_t)(((Float_t)GetNPhi())*(phi-GetArm1PhiMin())/ |
251 | ((Float_t)(GetArm1PhiMax() - GetArm1PhiMin()))); | |
ca8f5bd0 | 252 | if(iphi<=0 || iphi>GetNPhi()){ |
e908f07f | 253 | cout << "TowerIndexFromEtaPhi:"; |
254 | cout << "iphi=" << iphi << " phi=" << phi << " is outside of EMCAL."; | |
ca8f5bd0 | 255 | cout << " Phimin=" << GetArm1PhiMin() << " PhiMax=" << GetArm1PhiMax(); |
256 | cout << " returning -1" << endl; | |
257 | return -1; | |
258 | } // end if | |
e908f07f | 259 | return TowerIndex(ieta,iphi,0); |
ca8f5bd0 | 260 | } |
261 | //______________________________________________________________________ | |
a34b7b9f | 262 | Int_t AliEMCALGeometry::PreTowerIndexFromEtaPhi(Float_t eta,Float_t phi) const { |
ca8f5bd0 | 263 | // returns the pretower index number based on the eta and phi of the tower. |
264 | // Inputs: | |
265 | // Float_t eta // eta of center of tower in pseudorapidity | |
266 | // Float_t phi // phi of center of tower in degrees | |
267 | // Outputs: | |
268 | // none. | |
269 | // Returned | |
270 | // Int_t index // PreTower index number [fNZ*fNPhi-2*fNZ*fNPhi] | |
271 | ||
e908f07f | 272 | return GetNEta()*GetNPhi()+TowerIndexFromEtaPhi(eta,phi); |
ca8f5bd0 | 273 | } |
274 | //______________________________________________________________________ | |
a34b7b9f | 275 | Bool_t AliEMCALGeometry::AbsToRelNumbering(Int_t AbsId, Int_t *relid) const { |
ca8f5bd0 | 276 | // Converts the absolute numbering into the following array/ |
5a9318ff | 277 | // relid[0] = EMCAL Arm number 1:1 |
ca8f5bd0 | 278 | // relid[1] = 0 Not in Pre Shower layers |
279 | // = -1 In Pre Shower | |
280 | // relid[2] = Row number inside EMCAL | |
281 | // relid[3] = Column number inside EMCAL | |
282 | // Input: | |
283 | // Int_t AbsId // Tower index number [1-2*fNZ*fNPhi] | |
284 | // Outputs: | |
285 | // Int_t *relid // array of 5. Discribed above. | |
286 | Bool_t rv = kTRUE ; | |
e908f07f | 287 | Int_t ieta=0,iphi=0,ipre=0,index=AbsId; |
ca8f5bd0 | 288 | |
e908f07f | 289 | TowerIndexes(index,ieta,iphi,ipre); |
ca8f5bd0 | 290 | relid[0] = 1; |
291 | relid[1] = 0; | |
5a9318ff | 292 | if(ipre==1) |
293 | relid[1] = -1; | |
e908f07f | 294 | relid[2] = ieta; |
ca8f5bd0 | 295 | relid[3] = iphi; |
296 | ||
297 | return rv; | |
298 | } | |
299 | //______________________________________________________________________ | |
5a9318ff | 300 | void AliEMCALGeometry::PosInAlice(const Int_t *relid,Float_t &theta, |
a34b7b9f | 301 | Float_t &phi) const { |
5a9318ff | 302 | // Converts the relative numbering into the local EMCAL-module (x, z) |
ca8f5bd0 | 303 | // coordinates |
e908f07f | 304 | Int_t ieta = relid[2]; // offset along x axis |
ca8f5bd0 | 305 | Int_t iphi = relid[3]; // offset along z axis |
5a9318ff | 306 | Int_t ipre = relid[1]; // indicates -1 preshower, or 0 full tower. |
ca8f5bd0 | 307 | Int_t index; |
308 | Float_t eta; | |
309 | ||
310 | if(ipre==-1) ipre = 1; | |
e908f07f | 311 | index = TowerIndex(ieta,iphi,ipre); |
ca8f5bd0 | 312 | EtaPhiFromIndex(index,eta,phi); |
313 | theta = 180.*(2.0*TMath::ATan(TMath::Exp(-eta)))/TMath::Pi(); | |
314 | ||
315 | return; | |
316 | } | |
6119e5db | 317 | |
318 | //______________________________________________________________________ | |
319 | void AliEMCALGeometry::XYZFromIndex(const Int_t *relid,Float_t &x,Float_t &y, Float_t &z) const { | |
320 | // given the tower relative number it returns the X, Y and Z | |
321 | // of the tower. | |
322 | ||
323 | // Outputs: | |
324 | // Float_t x // x of center of tower in cm | |
325 | // Float_t y // y of center of tower in cm | |
326 | // Float_t z // z of centre of tower in cm | |
327 | // Returned | |
328 | // none. | |
329 | ||
330 | Float_t eta,theta, phi,cyl_radius,kDeg2Rad; | |
331 | ||
332 | Int_t ieta = relid[2]; // offset along x axis | |
333 | Int_t iphi = relid[3]; // offset along z axis | |
334 | Int_t ipre = relid[1]; // indicates -1 preshower, or 0 full tower. | |
335 | Int_t index; | |
336 | ||
337 | ||
338 | if(ipre==-1) ipre = 1; | |
339 | index = TowerIndex(ieta,iphi,ipre); | |
340 | EtaPhiFromIndex(index,eta,phi); | |
341 | theta = 180.*(2.0*TMath::ATan(TMath::Exp(-eta)))/TMath::Pi(); | |
342 | ||
343 | ||
344 | ||
345 | kDeg2Rad = TMath::Pi() / static_cast<Double_t>(180) ; | |
346 | cyl_radius = GetIPDistance()+ GetAirGap() ; | |
347 | x = cyl_radius * TMath::Cos(phi * kDeg2Rad ) ; | |
348 | y = cyl_radius * TMath::Cos(phi * kDeg2Rad ) ; | |
349 | z = cyl_radius / TMath::Tan(theta * kDeg2Rad ) ; | |
350 | ||
351 | return; | |
352 | } | |
353 | ||
ca8f5bd0 | 354 | //______________________________________________________________________ |
355 | /* | |
a34b7b9f | 356 | Boot_t AliEMCALGeometry::AreNeighbours(Int_t index1,Int_t index2) const { |
ca8f5bd0 | 357 | // Returns kTRUE if the two towers are neighbours or not, including |
358 | // diagonals. Both indexes are required to be either towers or preshower. | |
359 | // Inputs: | |
360 | // Int_t index1 // index of tower 1 | |
361 | // Int_t index2 // index of tower 2 | |
362 | // Outputs: | |
363 | // none. | |
364 | // Returned | |
365 | // Boot_t kTRUE if the towers are neighbours otherwise false. | |
366 | Boot_t anb = kFALSE; | |
e908f07f | 367 | Int_t ieta1 = 0, ieta2 = 0, iphi1 = 0, iphi2 = 0, ipre1 = 0, ipre2 = 0; |
ca8f5bd0 | 368 | |
e908f07f | 369 | TowerIndexes(index1,ieta1,iphi1,ipre1); |
370 | TowerIndexes(index2,ieta2,iphi2,ipre2); | |
ca8f5bd0 | 371 | if(ipre1!=ipre2) return anb; |
e908f07f | 372 | if((ieta1>=ieta2-1 && ieta1<=ieta2+1) && (iphi1>=iphi2-1 &&iphi1<=iphi2+1)) |
ca8f5bd0 | 373 | anb = kTRUE; |
374 | return anb; | |
375 | } | |
376 | */ |