]> git.uio.no Git - u/mrichter/AliRoot.git/blob - EMCAL/AliEMCALGeometry.cxx
Add sortzv needed by EMCAL.
[u/mrichter/AliRoot.git] / EMCAL / AliEMCALGeometry.cxx
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  
20 // EMCAL consists of layers of scintillator and lead
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
28 //*-- Author: Sahal Yacoob (LBL / UCT)
29 //     and  : Yves Schutz (SUBATECH)
30 //     and  : Jennifer Klay (LBL)
31
32 // --- ROOT system ---
33
34 // --- Standard library ---
35
36 #include <iostream.h>
37
38 // --- AliRoot header files ---
39 #include <TMath.h>
40 // -- ALICE Headers.
41 #include "AliConst.h"
42 // --- EMCAL headers
43 #include "AliEMCALGeometry.h"
44
45 ClassImp(AliEMCALGeometry);
46
47 AliEMCALGeometry *AliEMCALGeometry::fgGeom = 0;
48 Bool_t            AliEMCALGeometry::fgInit = kFALSE;
49
50 //______________________________________________________________________
51 AliEMCALGeometry::~AliEMCALGeometry(void){
52     // dtor
53 }
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
98 }
99 //______________________________________________________________________
100 AliEMCALGeometry *  AliEMCALGeometry::GetInstance(){ 
101     // Returns the pointer of the unique instance
102
103     return (AliEMCALGeometry *) fgGeom; 
104 }
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; 
133 }
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  */