]>
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()) || | |
167 | (iphi <= 0 || iphi>GetNPhi())) | |
168 | Fatal("TowerIndex", "Unexpected parameters eta = %d phi = %d!", ieta, iphi) ; | |
169 | ||
170 | return ( (iphi - 1)*GetNEta() + ieta ); | |
ca8f5bd0 | 171 | } |
173558f2 | 172 | |
ca8f5bd0 | 173 | //______________________________________________________________________ |
fdebddeb | 174 | void AliEMCALGeometry::TowerIndexes(Int_t index,Int_t &ieta,Int_t &iphi) const { |
395c7ba2 | 175 | // Inputs: |
fdebddeb | 176 | // Int_t index // Tower index number [1-fNZ*fNPhi] |
395c7ba2 | 177 | // Outputs: |
178 | // Int_t ieta // index allong z axis [1-fNZ] | |
179 | // Int_t iphi // index allong phi axis [1-fNPhi] | |
395c7ba2 | 180 | // Returned |
181 | // none. | |
395c7ba2 | 182 | |
fdebddeb | 183 | Int_t nindex = 0; |
395c7ba2 | 184 | |
fdebddeb | 185 | if ( IsInECA(index) ) { // ECAL index |
395c7ba2 | 186 | nindex = index ; |
395c7ba2 | 187 | } |
188 | else | |
189 | Fatal("TowerIndexes", "Unexpected Id number!") ; | |
190 | ||
191 | if (nindex%GetNZ()) | |
192 | iphi = nindex / GetNZ() + 1 ; | |
193 | else | |
194 | iphi = nindex / GetNZ() ; | |
195 | ieta = nindex - (iphi - 1) * GetNZ() ; | |
196 | ||
197 | if (gDebug==2) | |
fdebddeb | 198 | printf("TowerIndexes: index=%d,%d, ieta=%d, iphi = %d", index, nindex,ieta, iphi) ; |
395c7ba2 | 199 | return; |
200 | ||
ca8f5bd0 | 201 | } |
173558f2 | 202 | |
ca8f5bd0 | 203 | //______________________________________________________________________ |
a34b7b9f | 204 | void AliEMCALGeometry::EtaPhiFromIndex(Int_t index,Float_t &eta,Float_t &phi) const { |
ca8f5bd0 | 205 | // given the tower index number it returns the based on the eta and phi |
206 | // of the tower. | |
207 | // Inputs: | |
fdebddeb | 208 | // Int_t index // Tower index number [1-fNZ*fNPhi] |
ca8f5bd0 | 209 | // Outputs: |
210 | // Float_t eta // eta of center of tower in pseudorapidity | |
211 | // Float_t phi // phi of center of tower in degrees | |
212 | // Returned | |
213 | // none. | |
fdebddeb | 214 | Int_t ieta, iphi; |
395c7ba2 | 215 | Float_t deta, dphi ; |
ca8f5bd0 | 216 | |
fdebddeb | 217 | TowerIndexes(index,ieta,iphi); |
395c7ba2 | 218 | |
219 | if (gDebug == 2) | |
fdebddeb | 220 | printf("EtaPhiFromIndex: index = %d, ieta = %d, iphi = %d", index, ieta, iphi) ; |
395c7ba2 | 221 | |
222 | deta = (GetArm1EtaMax()-GetArm1EtaMin())/(static_cast<Float_t>(GetNEta())); | |
223 | eta = GetArm1EtaMin() + ((static_cast<Float_t>(ieta) - 0.5 ))*deta; | |
224 | ||
225 | dphi = (GetArm1PhiMax() - GetArm1PhiMin())/(static_cast<Float_t>(GetNPhi())); // in degrees. | |
226 | phi = GetArm1PhiMin() + dphi*(static_cast<Float_t>(iphi) - 0.5);//iphi range [1-fNphi]. | |
ca8f5bd0 | 227 | } |
173558f2 | 228 | |
ca8f5bd0 | 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] | |
395c7ba2 | 239 | |
e908f07f | 240 | Int_t ieta,iphi; |
ca8f5bd0 | 241 | |
395c7ba2 | 242 | ieta = static_cast<Int_t> ( 1 + (static_cast<Float_t>(GetNEta()) * (eta - GetArm1EtaMin()) / (GetArm1EtaMax() - GetArm1EtaMin())) ) ; |
243 | ||
244 | if( ieta <= 0 || ieta > GetNEta() ) { | |
245 | Error("TowerIndexFromEtaPhi", "Unexpected (eta, phi) = (%f, %f) value, outside of EMCAL!", eta, phi) ; | |
246 | return -1 ; | |
247 | } | |
248 | ||
249 | iphi = static_cast<Int_t> ( 1 + (static_cast<Float_t>(GetNPhi()) * (phi - GetArm1PhiMin()) / (GetArm1PhiMax() - GetArm1PhiMin())) ) ; | |
250 | ||
251 | if( iphi <= 0 || iphi > GetNPhi() ) { | |
252 | Error("TowerIndexFromEtaPhi", "Unexpected (eta, phi) = (%f, %f) value, outside of EMCAL!", eta, phi) ; | |
253 | return -1 ; | |
254 | } | |
255 | ||
256 | return TowerIndex(ieta,iphi); | |
ca8f5bd0 | 257 | } |
173558f2 | 258 | |
ca8f5bd0 | 259 | //______________________________________________________________________ |
a34b7b9f | 260 | Bool_t AliEMCALGeometry::AbsToRelNumbering(Int_t AbsId, Int_t *relid) const { |
ca8f5bd0 | 261 | // Converts the absolute numbering into the following array/ |
2608a1fc | 262 | // relid[0] = Row number inside EMCAL |
263 | // relid[1] = Column number inside EMCAL | |
ca8f5bd0 | 264 | // Input: |
265 | // Int_t AbsId // Tower index number [1-2*fNZ*fNPhi] | |
266 | // Outputs: | |
2608a1fc | 267 | // Int_t *relid // array of 2. Described above. |
ca8f5bd0 | 268 | Bool_t rv = kTRUE ; |
fdebddeb | 269 | Int_t ieta=0,iphi=0,index=AbsId; |
ca8f5bd0 | 270 | |
fdebddeb | 271 | TowerIndexes(index,ieta,iphi); |
2608a1fc | 272 | relid[0] = ieta; |
273 | relid[1] = iphi; | |
ca8f5bd0 | 274 | |
275 | return rv; | |
276 | } | |
173558f2 | 277 | |
ca8f5bd0 | 278 | //______________________________________________________________________ |
395c7ba2 | 279 | void AliEMCALGeometry::PosInAlice(const Int_t *relid, Float_t &theta, Float_t &phi) const |
280 | { | |
281 | // Converts the relative numbering into the local EMCAL-module (x, z) | |
282 | // coordinates | |
2608a1fc | 283 | Int_t ieta = relid[0]; // offset along x axis |
284 | Int_t iphi = relid[1]; // offset along z axis | |
395c7ba2 | 285 | Int_t index; |
286 | Float_t eta; | |
287 | ||
288 | index = TowerIndex(ieta,iphi); | |
289 | EtaPhiFromIndex(index,eta,phi); | |
fdebddeb | 290 | //theta = 180.*(2.0*TMath::ATan(TMath::Exp(-eta)))/TMath::Pi(); |
291 | theta = 2.0*TMath::ATan(TMath::Exp(-eta)); | |
395c7ba2 | 292 | |
fdebddeb | 293 | // correct for distance to IP |
294 | Float_t d = GetIP2ECASection() - GetIPDistance() ; | |
395c7ba2 | 295 | |
296 | Float_t correction = 1 + d/GetIPDistance() ; | |
297 | Float_t tantheta = TMath::Tan(theta) * correction ; | |
298 | theta = TMath::ATan(tantheta) * TMath::RadToDeg() ; | |
299 | if (theta < 0 ) | |
300 | theta += 180. ; | |
301 | ||
302 | return; | |
303 | } | |
ca8f5bd0 | 304 | |
395c7ba2 | 305 | //______________________________________________________________________ |
09884213 | 306 | void AliEMCALGeometry::PosInAlice(Int_t absid, Float_t &theta, Float_t &phi) const |
395c7ba2 | 307 | { |
308 | // Converts the relative numbering into the local EMCAL-module (x, z) | |
309 | // coordinates | |
2608a1fc | 310 | Int_t relid[2] ; |
395c7ba2 | 311 | AbsToRelNumbering(absid, relid) ; |
2608a1fc | 312 | Int_t ieta = relid[0]; // offset along x axis |
313 | Int_t iphi = relid[1]; // offset along z axis | |
395c7ba2 | 314 | Int_t index; |
315 | Float_t eta; | |
316 | ||
317 | index = TowerIndex(ieta,iphi); | |
318 | EtaPhiFromIndex(index,eta,phi); | |
319 | theta = 2.0*TMath::ATan(TMath::Exp(-eta)) ; | |
320 | ||
fdebddeb | 321 | // correct for distance to IP |
395c7ba2 | 322 | Float_t d = 0. ; |
fdebddeb | 323 | if (IsInECA(absid)) |
88cb7938 | 324 | d = GetIP2ECASection() - GetIPDistance() ; |
395c7ba2 | 325 | else |
326 | Fatal("PosInAlice", "Unexpected id # %d!", absid) ; | |
327 | ||
328 | Float_t correction = 1 + d/GetIPDistance() ; | |
329 | Float_t tantheta = TMath::Tan(theta) * correction ; | |
330 | theta = TMath::ATan(tantheta) * TMath::RadToDeg() ; | |
331 | if (theta < 0 ) | |
332 | theta += 180. ; | |
333 | ||
334 | return; | |
ca8f5bd0 | 335 | } |
6119e5db | 336 | |
337 | //______________________________________________________________________ | |
338 | void AliEMCALGeometry::XYZFromIndex(const Int_t *relid,Float_t &x,Float_t &y, Float_t &z) const { | |
339 | // given the tower relative number it returns the X, Y and Z | |
340 | // of the tower. | |
341 | ||
342 | // Outputs: | |
343 | // Float_t x // x of center of tower in cm | |
344 | // Float_t y // y of center of tower in cm | |
345 | // Float_t z // z of centre of tower in cm | |
346 | // Returned | |
347 | // none. | |
348 | ||
fdebddeb | 349 | Float_t eta,theta, phi,cylradius=0. ; |
6119e5db | 350 | |
2608a1fc | 351 | Int_t ieta = relid[0]; // offset along x axis |
352 | Int_t iphi = relid[1]; // offset along z axis. | |
6119e5db | 353 | Int_t index; |
354 | ||
395c7ba2 | 355 | index = TowerIndex(ieta,iphi); |
6119e5db | 356 | EtaPhiFromIndex(index,eta,phi); |
357 | theta = 180.*(2.0*TMath::ATan(TMath::Exp(-eta)))/TMath::Pi(); | |
6119e5db | 358 | |
fdebddeb | 359 | cylradius = GetIP2ECASection() ; |
a97849a9 | 360 | |
395c7ba2 | 361 | Double_t kDeg2Rad = TMath::DegToRad() ; |
fdebddeb | 362 | x = cylradius * TMath::Cos(phi * kDeg2Rad ) ; |
363 | y = cylradius * TMath::Sin(phi * kDeg2Rad ) ; | |
364 | z = cylradius / TMath::Tan(theta * kDeg2Rad ) ; | |
6119e5db | 365 | |
366 | return; | |
367 | } | |
368 | ||
395c7ba2 | 369 | //______________________________________________________________________ |
09884213 | 370 | void AliEMCALGeometry::XYZFromIndex(Int_t absid, TVector3 &v) const { |
395c7ba2 | 371 | // given the tower relative number it returns the X, Y and Z |
372 | // of the tower. | |
373 | ||
374 | // Outputs: | |
375 | // Float_t x // x of center of tower in cm | |
376 | // Float_t y // y of center of tower in cm | |
377 | // Float_t z // z of centre of tower in cm | |
378 | // Returned | |
379 | // none. | |
380 | ||
fdebddeb | 381 | Float_t theta, phi,cylradius=0. ; |
395c7ba2 | 382 | |
383 | PosInAlice(absid, theta, phi) ; | |
384 | ||
88cb7938 | 385 | if ( IsInECA(absid) ) |
fdebddeb | 386 | cylradius = GetIP2ECASection() ; |
395c7ba2 | 387 | else |
388 | Fatal("XYZFromIndex", "Unexpected Tower section") ; | |
389 | ||
390 | Double_t kDeg2Rad = TMath::DegToRad() ; | |
fdebddeb | 391 | v.SetX(cylradius * TMath::Cos(phi * kDeg2Rad ) ); |
392 | v.SetY(cylradius * TMath::Sin(phi * kDeg2Rad ) ); | |
393 | v.SetZ(cylradius / TMath::Tan(theta * kDeg2Rad ) ) ; | |
395c7ba2 | 394 | |
395 | return; | |
396 | } |