]>
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 | |
b13bbe81 | 26 | //*-- Author: Sahal Yacoob (LBL / UCT) |
27 | // and : Yves Schutz (SUBATECH) | |
28 | // and : Jennifer Klay (LBL) | |
2012850d | 29 | |
2012850d | 30 | // --- AliRoot header files --- |
ca8f5bd0 | 31 | #include <TMath.h> |
116cbefd | 32 | #include <TVector3.h> |
173558f2 | 33 | |
ca8f5bd0 | 34 | // -- ALICE Headers. |
d64c959b | 35 | //#include "AliConst.h" |
173558f2 | 36 | |
ca8f5bd0 | 37 | // --- EMCAL headers |
38 | #include "AliEMCALGeometry.h" | |
2012850d | 39 | |
b13bbe81 | 40 | ClassImp(AliEMCALGeometry); |
2012850d | 41 | |
b13bbe81 | 42 | AliEMCALGeometry *AliEMCALGeometry::fgGeom = 0; |
43 | Bool_t AliEMCALGeometry::fgInit = kFALSE; | |
2012850d | 44 | |
b13bbe81 | 45 | //______________________________________________________________________ |
46 | AliEMCALGeometry::~AliEMCALGeometry(void){ | |
47 | // dtor | |
2012850d | 48 | } |
b13bbe81 | 49 | |
395c7ba2 | 50 | //______________________________________________________________________ |
09884213 | 51 | Bool_t AliEMCALGeometry::AreInSameTower(Int_t id1, Int_t id2) const { |
fdebddeb | 52 | // Find out whether two hits are in the same tower |
395c7ba2 | 53 | Int_t idmax = TMath::Max(id1, id2) ; |
54 | Int_t idmin = TMath::Min(id1, id2) ; | |
55 | if ( ((idmax - GetNZ() * GetNPhi()) == idmin ) || | |
56 | ((idmax - 2 * GetNZ() * GetNPhi()) == idmin ) ) | |
57 | return kTRUE ; | |
58 | else | |
59 | return kFALSE ; | |
60 | } | |
05a92d59 | 61 | |
395c7ba2 | 62 | //______________________________________________________________________ |
63 | void AliEMCALGeometry::Init(void){ | |
64 | // Initializes the EMCAL parameters | |
fdebddeb | 65 | // naming convention : GUV_WX_N_ gives the composition of a tower |
395c7ba2 | 66 | // WX inform about the composition of the EM calorimeter section: |
fdebddeb | 67 | // thickness in mm of Pb radiator (W) and of scintillator (X), and number of scintillator layers (N) |
68 | // New geometry: EMCAL_55_25 | |
395c7ba2 | 69 | |
fdebddeb | 70 | fgInit = kFALSE; // Assume failed until proven otherwise. |
71 | TString name(GetName()) ; | |
72 | if (name == "EMCAL_55_25") { | |
73 | fECPbRadThickness = 0.5; // cm, Thickness of the Pb radiators | |
74 | fECScintThick = 0.5; // cm, Thickness of the scintillator | |
75 | fNECLayers = 25; // number of scintillator layers | |
395c7ba2 | 76 | |
fdebddeb | 77 | fSampling = 11.8; |
395c7ba2 | 78 | |
fdebddeb | 79 | fAlFrontThick = 3.5; // cm, Thickness of front Al layer |
395c7ba2 | 80 | fGap2Active = 1.0; // cm, Gap between Al and 1st Scintillator |
81 | } | |
fdebddeb | 82 | else if( name == "G56_2_55_19" || name == "EMCAL_5655_21" || name == "G56_2_55_19_104_14"|| name == "G65_2_64_19" || name == "EMCAL_6564_21"){ |
83 | Fatal("Init", "%s is an old geometry! Please update your Config file", name.Data()) ; | |
395c7ba2 | 84 | } |
85 | else | |
86 | Fatal("Init", "%s is an undefined geometry!", name.Data()) ; | |
05a92d59 | 87 | |
395c7ba2 | 88 | // geometry |
fdebddeb | 89 | fNZ = 114; // granularity along Z (eta) |
90 | fNPhi = 168; // granularity in phi (azimuth) | |
91 | fArm1PhiMin = 60.0; // degrees, Starting EMCAL Phi position | |
92 | fArm1PhiMax = 180.0; // degrees, Ending EMCAL Phi position | |
93 | fArm1EtaMin = -0.7; // pseudorapidity, Starting EMCAL Eta position | |
94 | fArm1EtaMax = +0.7; // pseudorapidity, Ending EMCAL Eta position | |
395c7ba2 | 95 | |
96 | fIPDistance = 454.0; // cm, Radial distance to inner surface of EMCAL | |
fdebddeb | 97 | |
98 | //There is always one more scintillator than radiator layer because of the first block of aluminium | |
99 | fShellThickness = fAlFrontThick + fGap2Active + fNECLayers*GetECScintThick()+(fNECLayers-1)*GetECPbRadThick(); | |
100 | ||
395c7ba2 | 101 | fZLength = 2.*ZFromEtaR(fIPDistance+fShellThickness,fArm1EtaMax); // Z coverage |
102 | fEnvelop[0] = fIPDistance; // mother volume inner radius | |
103 | fEnvelop[1] = fIPDistance + fShellThickness; // mother volume outer r. | |
104 | fEnvelop[2] = 1.00001*fZLength; // add some padding for mother volume. | |
105 | ||
106 | fgInit = kTRUE; | |
107 | ||
88cb7938 | 108 | if (gDebug) { |
fdebddeb | 109 | printf("Init: geometry of EMCAL named %s is as follows:", name.Data()); |
88cb7938 | 110 | printf( " ECAL : %d x (%f mm Pb, %f mm Sc) \n", GetNECLayers(), GetECPbRadThick(), GetECScintThick() ) ; |
88cb7938 | 111 | printf("Granularity: %d in eta and %d in phi\n", GetNZ(), GetNPhi()) ; |
112 | printf("Layout: phi = (%f, %f), eta = (%f, %f), y = %f\n", | |
113 | GetArm1PhiMin(), GetArm1PhiMax(),GetArm1EtaMin(), GetArm1EtaMax(), GetIPDistance() ) ; | |
114 | } | |
2012850d | 115 | } |
173558f2 | 116 | |
b13bbe81 | 117 | //______________________________________________________________________ |
118 | AliEMCALGeometry * AliEMCALGeometry::GetInstance(){ | |
05a92d59 | 119 | // Returns the pointer of the unique instance |
120 | ||
121 | return static_cast<AliEMCALGeometry *>( fgGeom ) ; | |
2012850d | 122 | } |
173558f2 | 123 | |
b13bbe81 | 124 | //______________________________________________________________________ |
125 | AliEMCALGeometry* AliEMCALGeometry::GetInstance(const Text_t* name, | |
126 | const Text_t* title){ | |
127 | // Returns the pointer of the unique instance | |
128 | ||
129 | AliEMCALGeometry * rv = 0; | |
130 | if ( fgGeom == 0 ) { | |
131 | if ( strcmp(name,"") == 0 ) rv = 0; | |
132 | else { | |
133 | fgGeom = new AliEMCALGeometry(name, title); | |
134 | if ( fgInit ) rv = (AliEMCALGeometry * ) fgGeom; | |
135 | else { | |
136 | rv = 0; | |
137 | delete fgGeom; | |
138 | fgGeom = 0; | |
139 | } // end if fgInit | |
140 | } // end if strcmp(name,"") | |
141 | }else{ | |
142 | if ( strcmp(fgGeom->GetName(), name) != 0 ) { | |
fdebddeb | 143 | printf("\ncurrent geometry is ") ; |
144 | printf(fgGeom->GetName()); | |
145 | printf("\n you cannot call "); | |
146 | printf(name); | |
b13bbe81 | 147 | }else{ |
9859bfc0 | 148 | rv = (AliEMCALGeometry *) fgGeom; |
b13bbe81 | 149 | } // end if |
150 | } // end if fgGeom | |
151 | return rv; | |
2012850d | 152 | } |
173558f2 | 153 | |
ca8f5bd0 | 154 | //______________________________________________________________________ |
395c7ba2 | 155 | Int_t AliEMCALGeometry::TowerIndex(Int_t ieta,Int_t iphi) const { |
156 | // Returns the tower index number from the based on the Z and Phi | |
fdebddeb | 157 | // index numbers. |
395c7ba2 | 158 | // Inputs: |
fdebddeb | 159 | // Int_t ieta // index along z axis [1-fNZ] |
160 | // Int_t iphi // index along phi axis [1-fNPhi] | |
395c7ba2 | 161 | // Outputs: |
162 | // none. | |
163 | // Returned | |
164 | // Int_t index // Tower index number | |
165 | ||
166 | if ( (ieta <= 0 || ieta>GetNEta()) || | |
f1da4a27 | 167 | (iphi <= 0 || iphi>GetNPhi())) { |
168 | Error("TowerIndex", "Unexpected parameters eta = %d phi = %d!", ieta, iphi) ; | |
169 | return -1; | |
170 | } | |
395c7ba2 | 171 | return ( (iphi - 1)*GetNEta() + ieta ); |
ca8f5bd0 | 172 | } |
173558f2 | 173 | |
ca8f5bd0 | 174 | //______________________________________________________________________ |
fdebddeb | 175 | void AliEMCALGeometry::TowerIndexes(Int_t index,Int_t &ieta,Int_t &iphi) const { |
395c7ba2 | 176 | // Inputs: |
fdebddeb | 177 | // Int_t index // Tower index number [1-fNZ*fNPhi] |
395c7ba2 | 178 | // Outputs: |
179 | // Int_t ieta // index allong z axis [1-fNZ] | |
180 | // Int_t iphi // index allong phi axis [1-fNPhi] | |
395c7ba2 | 181 | // Returned |
182 | // none. | |
395c7ba2 | 183 | |
fdebddeb | 184 | Int_t nindex = 0; |
395c7ba2 | 185 | |
fdebddeb | 186 | if ( IsInECA(index) ) { // ECAL index |
395c7ba2 | 187 | nindex = index ; |
395c7ba2 | 188 | } |
f1da4a27 | 189 | else { |
190 | Error("TowerIndexes", "Unexpected Id number!") ; | |
191 | ieta = -1; | |
192 | iphi = -1; | |
193 | return; | |
194 | } | |
195 | ||
395c7ba2 | 196 | if (nindex%GetNZ()) |
197 | iphi = nindex / GetNZ() + 1 ; | |
198 | else | |
199 | iphi = nindex / GetNZ() ; | |
200 | ieta = nindex - (iphi - 1) * GetNZ() ; | |
201 | ||
202 | if (gDebug==2) | |
fdebddeb | 203 | printf("TowerIndexes: index=%d,%d, ieta=%d, iphi = %d", index, nindex,ieta, iphi) ; |
395c7ba2 | 204 | return; |
205 | ||
ca8f5bd0 | 206 | } |
173558f2 | 207 | |
ca8f5bd0 | 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: | |
fdebddeb | 213 | // Int_t index // Tower index number [1-fNZ*fNPhi] |
ca8f5bd0 | 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. | |
fdebddeb | 219 | Int_t ieta, iphi; |
395c7ba2 | 220 | Float_t deta, dphi ; |
ca8f5bd0 | 221 | |
fdebddeb | 222 | TowerIndexes(index,ieta,iphi); |
395c7ba2 | 223 | |
224 | if (gDebug == 2) | |
fdebddeb | 225 | printf("EtaPhiFromIndex: index = %d, ieta = %d, iphi = %d", index, ieta, iphi) ; |
395c7ba2 | 226 | |
227 | deta = (GetArm1EtaMax()-GetArm1EtaMin())/(static_cast<Float_t>(GetNEta())); | |
228 | eta = GetArm1EtaMin() + ((static_cast<Float_t>(ieta) - 0.5 ))*deta; | |
229 | ||
230 | dphi = (GetArm1PhiMax() - GetArm1PhiMin())/(static_cast<Float_t>(GetNPhi())); // in degrees. | |
231 | phi = GetArm1PhiMin() + dphi*(static_cast<Float_t>(iphi) - 0.5);//iphi range [1-fNphi]. | |
ca8f5bd0 | 232 | } |
173558f2 | 233 | |
ca8f5bd0 | 234 | //______________________________________________________________________ |
a34b7b9f | 235 | Int_t AliEMCALGeometry::TowerIndexFromEtaPhi(Float_t eta,Float_t phi) const { |
ca8f5bd0 | 236 | // returns the tower index number based on the eta and phi of the tower. |
237 | // Inputs: | |
238 | // Float_t eta // eta of center of tower in pseudorapidity | |
239 | // Float_t phi // phi of center of tower in degrees | |
240 | // Outputs: | |
241 | // none. | |
242 | // Returned | |
243 | // Int_t index // Tower index number [1-fNZ*fNPhi] | |
395c7ba2 | 244 | |
e908f07f | 245 | Int_t ieta,iphi; |
ca8f5bd0 | 246 | |
395c7ba2 | 247 | ieta = static_cast<Int_t> ( 1 + (static_cast<Float_t>(GetNEta()) * (eta - GetArm1EtaMin()) / (GetArm1EtaMax() - GetArm1EtaMin())) ) ; |
248 | ||
249 | if( ieta <= 0 || ieta > GetNEta() ) { | |
250 | Error("TowerIndexFromEtaPhi", "Unexpected (eta, phi) = (%f, %f) value, outside of EMCAL!", eta, phi) ; | |
251 | return -1 ; | |
252 | } | |
253 | ||
254 | iphi = static_cast<Int_t> ( 1 + (static_cast<Float_t>(GetNPhi()) * (phi - GetArm1PhiMin()) / (GetArm1PhiMax() - GetArm1PhiMin())) ) ; | |
255 | ||
256 | if( iphi <= 0 || iphi > GetNPhi() ) { | |
257 | Error("TowerIndexFromEtaPhi", "Unexpected (eta, phi) = (%f, %f) value, outside of EMCAL!", eta, phi) ; | |
258 | return -1 ; | |
259 | } | |
260 | ||
261 | return TowerIndex(ieta,iphi); | |
ca8f5bd0 | 262 | } |
173558f2 | 263 | |
ca8f5bd0 | 264 | //______________________________________________________________________ |
a34b7b9f | 265 | Bool_t AliEMCALGeometry::AbsToRelNumbering(Int_t AbsId, Int_t *relid) const { |
ca8f5bd0 | 266 | // Converts the absolute numbering into the following array/ |
2608a1fc | 267 | // relid[0] = Row number inside EMCAL |
268 | // relid[1] = Column number inside EMCAL | |
ca8f5bd0 | 269 | // Input: |
270 | // Int_t AbsId // Tower index number [1-2*fNZ*fNPhi] | |
271 | // Outputs: | |
2608a1fc | 272 | // Int_t *relid // array of 2. Described above. |
ca8f5bd0 | 273 | Bool_t rv = kTRUE ; |
fdebddeb | 274 | Int_t ieta=0,iphi=0,index=AbsId; |
ca8f5bd0 | 275 | |
fdebddeb | 276 | TowerIndexes(index,ieta,iphi); |
2608a1fc | 277 | relid[0] = ieta; |
278 | relid[1] = iphi; | |
ca8f5bd0 | 279 | |
280 | return rv; | |
281 | } | |
173558f2 | 282 | |
ca8f5bd0 | 283 | //______________________________________________________________________ |
395c7ba2 | 284 | void AliEMCALGeometry::PosInAlice(const Int_t *relid, Float_t &theta, Float_t &phi) const |
285 | { | |
286 | // Converts the relative numbering into the local EMCAL-module (x, z) | |
287 | // coordinates | |
2608a1fc | 288 | Int_t ieta = relid[0]; // offset along x axis |
289 | Int_t iphi = relid[1]; // offset along z axis | |
395c7ba2 | 290 | Int_t index; |
291 | Float_t eta; | |
292 | ||
293 | index = TowerIndex(ieta,iphi); | |
294 | EtaPhiFromIndex(index,eta,phi); | |
fdebddeb | 295 | //theta = 180.*(2.0*TMath::ATan(TMath::Exp(-eta)))/TMath::Pi(); |
296 | theta = 2.0*TMath::ATan(TMath::Exp(-eta)); | |
395c7ba2 | 297 | |
fdebddeb | 298 | // correct for distance to IP |
299 | Float_t d = GetIP2ECASection() - GetIPDistance() ; | |
395c7ba2 | 300 | |
301 | Float_t correction = 1 + d/GetIPDistance() ; | |
302 | Float_t tantheta = TMath::Tan(theta) * correction ; | |
303 | theta = TMath::ATan(tantheta) * TMath::RadToDeg() ; | |
304 | if (theta < 0 ) | |
305 | theta += 180. ; | |
306 | ||
307 | return; | |
308 | } | |
ca8f5bd0 | 309 | |
395c7ba2 | 310 | //______________________________________________________________________ |
09884213 | 311 | void AliEMCALGeometry::PosInAlice(Int_t absid, Float_t &theta, Float_t &phi) const |
395c7ba2 | 312 | { |
313 | // Converts the relative numbering into the local EMCAL-module (x, z) | |
314 | // coordinates | |
2608a1fc | 315 | Int_t relid[2] ; |
395c7ba2 | 316 | AbsToRelNumbering(absid, relid) ; |
2608a1fc | 317 | Int_t ieta = relid[0]; // offset along x axis |
318 | Int_t iphi = relid[1]; // offset along z axis | |
395c7ba2 | 319 | Int_t index; |
320 | Float_t eta; | |
321 | ||
322 | index = TowerIndex(ieta,iphi); | |
323 | EtaPhiFromIndex(index,eta,phi); | |
324 | theta = 2.0*TMath::ATan(TMath::Exp(-eta)) ; | |
325 | ||
fdebddeb | 326 | // correct for distance to IP |
395c7ba2 | 327 | Float_t d = 0. ; |
fdebddeb | 328 | if (IsInECA(absid)) |
88cb7938 | 329 | d = GetIP2ECASection() - GetIPDistance() ; |
f1da4a27 | 330 | else { |
331 | Error("PosInAlice", "Unexpected id # %d!", absid) ; | |
332 | return; | |
333 | } | |
395c7ba2 | 334 | |
335 | Float_t correction = 1 + d/GetIPDistance() ; | |
336 | Float_t tantheta = TMath::Tan(theta) * correction ; | |
337 | theta = TMath::ATan(tantheta) * TMath::RadToDeg() ; | |
338 | if (theta < 0 ) | |
339 | theta += 180. ; | |
340 | ||
341 | return; | |
ca8f5bd0 | 342 | } |
6119e5db | 343 | |
344 | //______________________________________________________________________ | |
345 | void AliEMCALGeometry::XYZFromIndex(const Int_t *relid,Float_t &x,Float_t &y, Float_t &z) const { | |
346 | // given the tower relative number it returns the X, Y and Z | |
347 | // of the tower. | |
348 | ||
349 | // Outputs: | |
350 | // Float_t x // x of center of tower in cm | |
351 | // Float_t y // y of center of tower in cm | |
352 | // Float_t z // z of centre of tower in cm | |
353 | // Returned | |
354 | // none. | |
355 | ||
fdebddeb | 356 | Float_t eta,theta, phi,cylradius=0. ; |
6119e5db | 357 | |
2608a1fc | 358 | Int_t ieta = relid[0]; // offset along x axis |
359 | Int_t iphi = relid[1]; // offset along z axis. | |
6119e5db | 360 | Int_t index; |
361 | ||
395c7ba2 | 362 | index = TowerIndex(ieta,iphi); |
6119e5db | 363 | EtaPhiFromIndex(index,eta,phi); |
364 | theta = 180.*(2.0*TMath::ATan(TMath::Exp(-eta)))/TMath::Pi(); | |
6119e5db | 365 | |
fdebddeb | 366 | cylradius = GetIP2ECASection() ; |
a97849a9 | 367 | |
395c7ba2 | 368 | Double_t kDeg2Rad = TMath::DegToRad() ; |
fdebddeb | 369 | x = cylradius * TMath::Cos(phi * kDeg2Rad ) ; |
370 | y = cylradius * TMath::Sin(phi * kDeg2Rad ) ; | |
371 | z = cylradius / TMath::Tan(theta * kDeg2Rad ) ; | |
6119e5db | 372 | |
373 | return; | |
374 | } | |
375 | ||
395c7ba2 | 376 | //______________________________________________________________________ |
09884213 | 377 | void AliEMCALGeometry::XYZFromIndex(Int_t absid, TVector3 &v) const { |
395c7ba2 | 378 | // given the tower relative number it returns the X, Y and Z |
379 | // of the tower. | |
380 | ||
381 | // Outputs: | |
382 | // Float_t x // x of center of tower in cm | |
383 | // Float_t y // y of center of tower in cm | |
384 | // Float_t z // z of centre of tower in cm | |
385 | // Returned | |
386 | // none. | |
387 | ||
fdebddeb | 388 | Float_t theta, phi,cylradius=0. ; |
395c7ba2 | 389 | |
390 | PosInAlice(absid, theta, phi) ; | |
391 | ||
88cb7938 | 392 | if ( IsInECA(absid) ) |
fdebddeb | 393 | cylradius = GetIP2ECASection() ; |
f1da4a27 | 394 | else { |
395 | Error("XYZFromIndex", "Unexpected Tower section") ; | |
396 | return; | |
397 | } | |
395c7ba2 | 398 | |
399 | Double_t kDeg2Rad = TMath::DegToRad() ; | |
fdebddeb | 400 | v.SetX(cylradius * TMath::Cos(phi * kDeg2Rad ) ); |
401 | v.SetY(cylradius * TMath::Sin(phi * kDeg2Rad ) ); | |
402 | v.SetZ(cylradius / TMath::Tan(theta * kDeg2Rad ) ) ; | |
395c7ba2 | 403 | |
404 | return; | |
405 | } |