Using enum to initaialize static ints in the header file, the initialization of stati...
[u/mrichter/AliRoot.git] / TOF / AliTOFGeometry.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 /*
17 $Log$
18 Revision 1.1  2003/12/29 15:18:03  decaro
19 TOF geometry updating (addition of AliTOFGeometry)
20
21 Revision 0.01  2003/12/04 S.Arcelli
22 Revision 0.02  2003/12/10 S.Arcelli:
23         Implement Global methods GetPos & GetDetID 
24 Revision 0.03  2003/12/14 S.Arcelli
25         Set Phi range [-180,180]->[0,360] 
26 */
27
28 #include <stdlib.h>
29 #include <Riostream.h>
30 ///////////////////////////////////////////////////////////////////////////////
31 //                                                                           //
32 //  TOF Geometry class                                                       //
33 //                                                                           //
34 ///////////////////////////////////////////////////////////////////////////////
35
36 #include "AliConst.h"
37 #include "AliTOFGeometry.h"
38
39 ClassImp(AliTOFGeometry)
40
41 static const Int_t fgkTimeDiff   = 25000;// Min signal separation (ps)
42
43 static const Float_t fgkRmin     = 370.; // Inner radius of the TOF (cm)
44 static const Float_t fgkRmax     = 399;  // Outer radius of the TOF (cm)
45 static const Float_t fgkZlenA    = 106.0;// length (cm) of the A module
46 static const Float_t fgkZlenB    = 141.0;// length (cm) of the B module
47 static const Float_t fgkZlenC    = 177.5;// length (cm) of the C module
48 static const Float_t fgkXPad     = 2.5;  // Pad size in the x direction (cm)
49 static const Float_t fgkZPad     = 3.5;  // Pad size in the z direction (cm)
50 static const Float_t fgkMaxhZtof = 371.5;// Max half z-size of TOF (cm)
51
52
53 static const Float_t fgkSigmaForTail1= 2.;//Sig1 for simulation of TDC tails 
54 static const Float_t fgkSigmaForTail2= 0.5;//Sig2 for simulation of TDC tails
55 static const Float_t fgkSpeedOfLight = 0.299792458;// c (10^9 m/s)
56 static const Float_t fgkPionMass     = 0.13957;// pion mass (Gev/c^2)
57 static const Float_t fgkKaonMass     = 0.49368;// kaon mass (Gev/c^2)
58 static const Float_t fgkProtonMass   = 0.93827;// proton mass (Gev/c^2)
59 static const Float_t fgkElectronMass = 0.00051;// electron mass (Gev/c^2)
60 static const Float_t fgkMuonMass     = 0.10566;// muon mass (Gev/c^2)
61
62
63 static const Float_t fgkDprecMin = 0.0000075;//num.prec.tolerance on Thmin 
64 static const Float_t fgkDprecMax = 0.0000100;//num.prec.tolerance on Thma 
65 static const Float_t fgkDprecCen = 0.0000005;//num.prec.tolerance on <Theta> 
66
67 //_____________________________________________________________________________
68 AliTOFGeometry::AliTOFGeometry()
69 {
70   //
71   // AliTOFGeometry default constructor
72   //
73   Init();
74
75 }
76
77 //_____________________________________________________________________________
78 AliTOFGeometry::~AliTOFGeometry()
79 {
80   //
81   // AliTOFGeometry destructor
82   //
83
84 }
85 //_____________________________________________________________________________
86 void AliTOFGeometry::Init()
87 {
88   //
89   // Initialize strip Tilt Angles and Heights
90   //
91   // Strips Tilt Angles
92  
93   const Float_t angles[fgkNPlates][fgkMaxNstrip] ={
94
95  {44.494, 43.725, 42.946, 42.156, 41.357, 40.548, 39.729, 38.899, 
96   38.060, 37.211, 36.353, 35.484, 34.606, 33.719, 32.822, 31.916, 
97   31.001, 30.077, 29.144, 28.202 },
98
99  {26.884, 25.922, 24.952, 23.975, 22.989, 22.320, 21.016, 20.309,
100   19.015, 18.270, 16.989, 16.205, 14.941, 14.117, 12.871, 12.008,
101   10.784, 9.8807, 8.681, 0.0 },
102
103  { 7.5835, 6.4124, 5.4058, 4.2809, 3.2448,  2.1424, 1.078, -0., -1.078, 
104   -2.1424, -3.2448, -4.2809, -5.4058, -6.4124, -7.5835, 0.0, 0.0, 0.0,
105   0.0, 0.0 },
106   
107  {-8.681, -9.8807, -10.784, -12.008, -12.871, -14.117, -14.941, -16.205,
108   -16.989, -18.27, -19.015, -20.309, -21.016, -22.32, -22.989,
109    -23.975, -24.952, -25.922, -26.884, 0. },
110   
111  {-28.202, -29.144, -30.077, -31.001, -31.916, -32.822, -33.719, -34.606,
112   -35.484, -36.353, -37.211, -38.06, -38.899, -39.729, -40.548,
113    -41.357, -42.156, -42.946, -43.725, -44.494 }};
114
115
116   //Strips Heights
117
118    const Float_t heights[fgkNPlates][fgkMaxNstrip]= {
119
120   {-5.5, -5.5, -5.5, -5.5, -5.5, -5.5, -5.5, -5.5, -5.5, -5.5,
121    -5.5, -5.5, -5.5, -5.5, -5.5, -5.5, -5.5, -5.5, -5.5, -5.5 },
122   
123   {-6.3, -7.1, -7.9, -8.7, -9.5, -3, -9.5,   -3, -9.5,   -3, 
124    -9.5, -3.0, -9.5, -3.0, -9.5, -3, -9.5,   -3,   -9 , 0.},
125   
126   {  -3,   -9, -4.5,   -9, -4.5,     -9, -4.5,   -9, -4.5,   -9, 
127      -4.5,   -9, -4.5,   -9,   -3,   0.0, 0.0, 0.0, 0.0, 0.0 },
128   
129   {  -9,   -3, -9.5,   -3, -9.5, -3, -9.5,   -3, -9.5,   -3, -9.5,
130      -3, -9.5,   -3, -9.5,  -8.7, -7.9, -7.1, -6.3, 0. },
131   
132   {-5.5, -5.5, -5.5, -5.5, -5.5, -5.5, -5.5, -5.5, -5.5, -5.5,
133    -5.5, -5.5, -5.5, -5.5, -5.5, -5.5, -5.5, -5.5, -5.5, -5.5 }};
134
135
136    // Deposit in fAngles, fHeights
137
138   for (Int_t iplate = 0; iplate < fgkNPlates; iplate++) {
139     for (Int_t istrip = 0; istrip < fgkMaxNstrip; istrip++) {
140       fAngles[iplate][istrip]   = angles[iplate][istrip];
141       fHeights[iplate][istrip]  = heights[iplate][istrip];
142     }
143   }
144
145   fPhiSec   = 360./fgkNSectors;
146 }
147
148 //_____________________________________________________________________________
149 void AliTOFGeometry::GetPos(Int_t *det, Float_t *pos) 
150 {
151 //
152 // Returns space point coor (x,y,z) (cm)  for Detector 
153 // Indices  (iSect,iPlate,iStrip,iPadX,iPadZ) 
154 //
155
156   pos[0]=GetX(det);  
157   pos[1]=GetY(det);  
158   pos[2]=GetZ(det);
159   
160 }
161 //_____________________________________________________________________________
162 void AliTOFGeometry::GetDetID( Float_t *pos, Int_t *det) 
163 {
164  //
165  // Returns Detector Indices (iSect,iPlate,iStrip,iPadX,iPadZ) 
166  // space point coor (x,y,z) (cm)  
167
168
169   det[0]=GetSector(pos);  
170   det[1]=GetPlate(pos);  
171   det[2]=GetStrip(pos);
172   det[3]=GetPadZ(pos);
173   det[4]=GetPadX(pos);
174   
175 }
176 //_____________________________________________________________________________
177 Float_t AliTOFGeometry::GetX(Int_t *det) 
178 {
179   //
180   // Returns X coordinate (cm)
181   //
182
183   Int_t isector = det[0];
184   Int_t iplate  = det[1];
185   Int_t istrip  = det[2];
186   Int_t ipadz   = det[3];
187   Int_t ipadx   = det[4];
188
189   // Find out distance d on the plane wrt median phi:
190   Float_t d = (ipadx+0.5)*fgkXPad-(fgkNpadX*fgkXPad)*0.5;
191
192   // The radius r in xy plane:
193   Float_t r = (fgkRmin+fgkRmax)/2.+fHeights[iplate][istrip]+
194     (ipadz-0.5)*fgkZPad*TMath::Sin(fAngles[iplate][istrip]/kRaddeg)-0.25;
195
196   // local azimuthal angle in the sector philoc
197   Float_t philoc   = TMath:: ATan(d/r);
198
199   // azimuthal angle in the global frame  phi
200   Float_t phi      = philoc*kRaddeg+(isector+0.5 )*fPhiSec;                    
201
202   Float_t xCoor    = r/TMath::Cos(philoc)*TMath::Cos(phi/kRaddeg);
203   return xCoor;
204
205 }
206 //_____________________________________________________________________________
207 Float_t AliTOFGeometry::GetY(Int_t *det) 
208 {
209   //
210   // Returns Y coordinate (cm)
211   //
212
213   Int_t isector = det[0];
214   Int_t iplate  = det[1];
215   Int_t istrip  = det[2];
216   Int_t ipadz   = det[3];
217   Int_t ipadx   = det[4];
218
219   // Find out distance d on the plane wrt median phi:
220   Float_t d = (ipadx+0.5)*fgkXPad-(fgkNpadX*fgkXPad)*0.5;
221
222   // The radius r in xy plane:
223   Float_t r = (fgkRmin+fgkRmax)/2.+fHeights[iplate][istrip]+
224     (ipadz-0.5)*fgkZPad*TMath::Sin(fAngles[iplate][istrip]/kRaddeg)-0.25;
225
226   // local azimuthal angle in the sector philoc
227   Float_t philoc   = TMath:: ATan(d/r);
228
229   // azimuthal angle in the global frame  phi
230   Float_t phi      = philoc*kRaddeg+(isector+0.5 )*fPhiSec;                    
231
232   Float_t yCoor    = r/TMath::Cos(philoc)*TMath::Sin(phi/kRaddeg);
233   return yCoor;
234
235 }
236
237 //_____________________________________________________________________________
238 Float_t AliTOFGeometry::GetZ(Int_t *det) 
239 {
240   //
241   // Returns Z coordinate (cm)
242   //
243   
244   Int_t iplate  = det[1];
245   Int_t istrip  = det[2];
246   Int_t ipadz   = det[3];
247   
248   
249   // The radius r in xy plane:
250   Float_t r = (fgkRmin+fgkRmax)/2.+fHeights[iplate][istrip];
251
252   Float_t zCoor = r*TMath::Tan(0.5*TMath::Pi()-GetStripTheta(iplate, istrip))-
253          (ipadz-0.5)*fgkZPad*TMath::Cos(fAngles[iplate][istrip]/kRaddeg);
254   return zCoor;
255
256 }
257 //_____________________________________________________________________________
258 Int_t AliTOFGeometry::GetSector(Float_t *pos) 
259 {
260   //
261   // Returns the Sector index 
262   //
263
264   Int_t   iSect = -1; 
265
266   Float_t x = pos[0];
267   Float_t y = pos[1];
268
269   Float_t phi     =  TMath::ATan2(y,x); 
270   if(phi<0.) phi=2.*TMath::Pi()+phi;
271   iSect  = (Int_t) (phi*kRaddeg/fPhiSec);
272
273   return iSect;
274
275 }
276 //_____________________________________________________________________________
277 Int_t AliTOFGeometry::GetPadX(Float_t *pos) 
278 {
279   //
280   // Returns the Pad index along X 
281   //
282
283   Int_t iPadX  = -1;
284
285   Float_t x = pos[0];
286   Float_t y = pos[1];
287   Float_t z = pos[2];
288
289   Int_t isector = GetSector(pos);
290   if(isector == -1){  
291     cout << "Detector Index could not be determined" << endl;
292     return iPadX;}
293   Int_t iplate =  GetPlate(pos);
294   if(iplate == -1){  
295     cout << "Detector Index could not be determined" << endl;
296     return iPadX;} 
297   Int_t istrip =  GetStrip(pos);
298   if(istrip == -1){  
299     cout << "Detector Index could not be determined" << endl;
300     return iPadX;}
301
302
303   Float_t rho=TMath::Sqrt(x*x+y*y);
304   Float_t phi =  TMath::ATan2(y,x);     
305   if(phi<0.) phi=2.*TMath::Pi()+phi;
306  
307   // Get the local angle in the sector philoc
308   Float_t philoc   = phi*kRaddeg-(isector+0.5)*fPhiSec;
309   philoc*=TMath::Pi()/180.;
310   // theta projected on the median of the sector
311   Float_t theta = TMath::ATan2(rho*TMath::Cos(philoc),z);
312   // The radius r in xy plane:
313   Float_t r   = (fgkRmin+fgkRmax)/2.+fHeights[iplate][istrip]+
314                (theta-GetStripTheta(iplate, istrip))/
315     (GetMaxStripTheta(iplate, istrip)-GetMinStripTheta(iplate, istrip))
316    * 2.*fgkZPad*TMath::Sin(fAngles[iplate][istrip]/kRaddeg)-0.25;
317
318   // Find out distance projected onto the strip plane 
319   Float_t d = (r*TMath::Tan(philoc)+(fgkNpadX*fgkXPad)*0.5);
320
321   iPadX  =  (Int_t) ( d/fgkXPad);  
322   return iPadX;
323
324 }
325 //_____________________________________________________________________________
326 Int_t AliTOFGeometry::GetPlate(Float_t *pos) 
327 {
328   //
329   // Returns the Plate index 
330   //
331   Int_t iPlate=-1;
332
333   Int_t isector = GetSector(pos);
334   if(isector == -1){  
335     cout << "Detector Index could not be determined" << endl;
336     return iPlate;}
337  
338   Float_t x = pos[0];
339   Float_t y = pos[1];
340   Float_t z = pos[2];
341
342   Float_t rho=TMath::Sqrt(x*x+y*y);
343   Float_t phi=TMath::ATan2(y,x);        
344   if(phi<0) phi=2.*TMath::Pi()+phi;
345   // Get the local angle in the sector philoc
346   Float_t philoc   = phi*kRaddeg-(isector+0.5)*fPhiSec;
347   philoc*=TMath::Pi()/180.;
348   // theta projected on the median of the sector
349   Float_t theta=TMath::ATan2(rho*TMath::Cos(philoc),z);
350
351   for (Int_t i=0; i<fgkNPlates; i++){
352     if ( GetMaxPlateTheta(i) >= theta && 
353          GetMinPlateTheta(i) <= theta)iPlate=i;
354   }
355   
356   return iPlate;
357
358 }
359 //_____________________________________________________________________________
360 Int_t AliTOFGeometry::GetStrip(Float_t *pos) 
361 {
362   //
363   // Returns the Strip index 
364   //
365
366   Int_t iStrip=-1;
367
368
369   Int_t isector = GetSector(pos);
370   if(isector == -1){  
371     cout << "Detector Index could not be determined" << endl;
372     return iStrip;}
373   Int_t iplate =  GetPlate(pos);
374   if(iplate == -1){  
375     cout << "Detector Index could not be determined" << endl;
376     return iStrip;} 
377
378
379   Float_t x = pos[0];
380   Float_t y = pos[1];
381   Float_t z = pos[2];
382
383   Int_t nstrips=0;
384   if(iplate==0 || iplate == 4)nstrips=fgkNStripC;
385   if(iplate==1 || iplate == 3)nstrips=fgkNStripB;
386   if(iplate==2)               nstrips=fgkNStripA;
387
388   Float_t rho=TMath::Sqrt(x*x+y*y);
389   Float_t phi=TMath::ATan2(y,x);        
390   if(phi<0) phi=2.*TMath::Pi()+phi;
391   // Get the local angle in the sector philoc
392   Float_t philoc   = phi*kRaddeg-(isector+0.5)*fPhiSec;
393   philoc*=TMath::Pi()/180.;
394   // theta projected on the median of the sector
395   Float_t theta=TMath::ATan2(rho*TMath::Cos(philoc),z);
396
397   for (Int_t istrip=0; istrip<nstrips; istrip++){
398
399     if( 
400        GetMaxStripTheta(iplate,istrip) >= theta 
401        &&  
402        GetMinStripTheta(iplate,istrip) <= theta ) iStrip = istrip;
403    
404   }
405
406   return iStrip;
407 }
408 //_____________________________________________________________________________
409 Int_t AliTOFGeometry::GetPadZ(Float_t *pos) 
410 {
411   //
412   // Returns the Pad index along Z 
413   //
414   Int_t iPadZ = -1;
415
416   Int_t isector = GetSector(pos);
417   if(isector == -1){  
418     cout << "Detector Index could not be determined" << endl;
419     return iPadZ;}
420   Int_t iplate =  GetPlate(pos);
421   if(iplate == -1){  
422     cout << "Detector Index could not be determined" << endl;
423     return iPadZ;} 
424   Int_t istrip =  GetStrip(pos);
425   if(istrip == -1){  
426     cout << "Detector Index could not be determined" << endl;
427     return iPadZ;}
428
429
430   Float_t x = pos[0];
431   Float_t y = pos[1];
432   Float_t z = pos[2];
433
434   Float_t rho=TMath::Sqrt(x*x+y*y);
435   Float_t phi=TMath::ATan2(y,x);        
436   if(phi<0) phi=2.*TMath::Pi()+phi;
437   Float_t philoc   = phi*kRaddeg-(isector+0.5)*fPhiSec;
438   philoc*=TMath::Pi()/180.;
439   Float_t theta=TMath::ATan2(rho*TMath::Cos(philoc),z);
440
441   if (theta >= GetStripTheta(iplate, istrip))iPadZ=1;
442   else iPadZ=0;
443
444   return iPadZ;
445 }
446 //_____________________________________________________________________________
447 Float_t AliTOFGeometry::GetMinPlateTheta(Int_t iPlate) 
448 {
449   //
450   // Returns the minimum theta angle of a given plate iPlate (rad)
451   //
452   
453
454   Int_t index=0;
455
456   Float_t delta =0.;
457   if(iPlate==0)delta = -1. ;
458   if(iPlate==1)delta = -0.5;
459   if(iPlate==3)delta = +0.5;
460   if(iPlate==4)delta = +1. ;
461
462   Float_t z=(fgkRmin+2.)*TMath::Tan(fAngles[iPlate][index]/kRaddeg)+delta;
463   Float_t r=(fgkRmin+fgkRmax)/2.+fHeights[iPlate][index];
464   z =z+fgkZPad*TMath::Cos(fAngles[iPlate][index]/kRaddeg);
465   r =r-fgkZPad*TMath::Sin(fAngles[iPlate][index]/kRaddeg);
466
467   Float_t thmin = 0.5*TMath::Pi()-TMath::ATan(z/r)-fgkDprecMin;
468   return thmin;
469
470 }
471 //_____________________________________________________________________________
472 Float_t AliTOFGeometry::GetMaxPlateTheta(Int_t iPlate) 
473 {
474   //
475   // Returns the maximum theta angle of a given plate iPlate (rad)
476   
477   Int_t index=0;
478   if(iPlate==0 ||iPlate == 4)index=fgkNStripC-1;
479   if(iPlate==1 ||iPlate == 3)index=fgkNStripB-1;
480   if(iPlate==2)              index=fgkNStripA-1;
481
482   Float_t delta =0.;
483   if(iPlate==0)delta = -1. ;
484   if(iPlate==1)delta = -0.5;
485   if(iPlate==3)delta = +0.5;
486   if(iPlate==4)delta = +1. ;
487
488   Float_t z=(fgkRmin+2.)*TMath::Tan(fAngles[iPlate][index]/kRaddeg)+delta;
489   Float_t r=(fgkRmin+fgkRmax)/2.+fHeights[iPlate][index];
490   z =z-fgkZPad*TMath::Cos(fAngles[iPlate][index]/kRaddeg);
491   r= r+fgkZPad*TMath::Sin(fAngles[iPlate][index]/kRaddeg);
492
493   Float_t thmax    = 0.5*TMath::Pi()-TMath::ATan(z/r)+fgkDprecMax;
494   return thmax;
495
496 }
497 //_____________________________________________________________________________
498 Float_t  AliTOFGeometry::GetMaxStripTheta(Int_t iPlate, Int_t iStrip) 
499 {
500   //
501   // Returns the maximum theta angle of a given strip iStrip (rad)
502   //
503   
504
505   Float_t delta =0.;
506   if(iPlate==0)delta = -1. ;
507   if(iPlate==1)delta = -0.5;
508   if(iPlate==3)delta = +0.5;
509   if(iPlate==4)delta = +1. ;
510
511   Float_t r =(fgkRmin+fgkRmax)/2.+fHeights[iPlate][iStrip];
512   Float_t z =(fgkRmin+2.)*TMath::Tan(fAngles[iPlate][iStrip]/kRaddeg)+delta;
513   z = z-fgkZPad*TMath::Cos(fAngles[iPlate][iStrip]/kRaddeg);
514   r = r+fgkZPad*TMath::Sin(fAngles[iPlate][iStrip]/kRaddeg);
515   Float_t thmax =0.5*TMath::Pi()-TMath::ATan(z/r)+fgkDprecMax;
516   return thmax;
517
518 }
519
520 //_____________________________________________________________________________
521 Float_t  AliTOFGeometry::GetMinStripTheta(Int_t iPlate, Int_t iStrip) 
522 {
523   //
524   // Returns the minimum theta angle of a given Strip iStrip (rad)
525   //
526   
527
528   Float_t delta =0.;
529   if(iPlate==0)delta = -1. ;
530   if(iPlate==1)delta = -0.5;
531   if(iPlate==3)delta = +0.5;
532   if(iPlate==4)delta = +1. ;
533
534
535   Float_t r =(fgkRmin+fgkRmax)/2.+fHeights[iPlate][iStrip];
536   Float_t z =(fgkRmin+2.)*TMath::Tan(fAngles[iPlate][iStrip]/kRaddeg)+delta;
537   z =z+fgkZPad*TMath::Cos(fAngles[iPlate][iStrip]/kRaddeg);
538   r =r-fgkZPad*TMath::Sin(fAngles[iPlate][iStrip]/kRaddeg);
539   Float_t thmin =0.5*TMath::Pi()-TMath::ATan(z/r)-fgkDprecMin;
540
541   return thmin;
542
543 }
544
545
546 //_____________________________________________________________________________
547 Float_t  AliTOFGeometry::GetStripTheta(Int_t iPlate, Int_t iStrip) 
548 {
549   //
550   // returns the median theta angle of a given strip iStrip (rad)
551   //
552   
553
554   Float_t delta =0.;
555   if(iPlate==0)delta = -1. ;
556   if(iPlate==1)delta = -0.5;
557   if(iPlate==3)delta = +0.5;
558   if(iPlate==4)delta = +1. ;
559
560   Float_t r =(fgkRmin+fgkRmax)/2.+fHeights[iPlate][iStrip];
561   Float_t z =(fgkRmin+2.)*TMath::Tan(fAngles[iPlate][iStrip]/kRaddeg)+delta;
562   Float_t theta =0.5*TMath::Pi()-TMath::ATan(z/r);
563   if(iPlate != 2){
564   if(theta > 0.5*TMath::Pi() )theta+=fgkDprecCen;
565   if(theta < 0.5*TMath::Pi() )theta-=fgkDprecCen;
566   }
567   return theta;
568 }
569
570
571