]> git.uio.no Git - u/mrichter/AliRoot.git/blob - TOF/AliTOFGeometry.cxx
Come back to the previous revision for tracker
[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.20.1  2007/05/19 decaro
19          Added the following methods:
20              GetVolumeIndices(Int_t index, Int_t *det), to get
21           the volume indices (sector, plate, strip, padz, padx,
22           stored respectively in det[0], det[1], det[2], det[3], det[4])
23           from the calibration channel index;
24              NStrip(Int_t nPlate), to get the strips number
25           per each kind of TOF module.
26
27 Revision 1.20  2007/10/08 17:52:55  decaro
28 hole region in front of PHOS detector: update of sectors' numbers
29
30 Revision 1.19  2007/10/04 14:05:09  zampolli
31 AliTOFGeometryV5 becoming AliTOFGeometry
32
33 Revision 1.18  2007/02/19 18:55:26  decaro
34 Added getter methods for volume path (for Event Display)
35
36 Revision 1.17.1  2006/12/15 
37          Added method DetToStripRF(...) to get
38          a pad corner coordinates in its strip reference frame
39          (A.De Caro, M.Di Stefano)
40 Revision 1.17  2006/08/22 13:30:02  arcelli
41 removal of effective c++ warnings (C.Zampolli)
42
43 Revision 1.16  2006/04/20 22:30:50  hristov
44 Coding conventions (Annalisa)
45
46 Revision 1.15  2006/04/16 22:29:05  hristov
47 Coding conventions (Annalisa)
48
49 Revision 1.14  2006/04/05 08:35:38  hristov
50 Coding conventions (S.Arcelli, C.Zampolli)
51
52 Revision 1.13  2006/03/12 14:37:54  arcelli
53  Changes for TOF Reconstruction using TGeo
54
55 Revision 1.12  2006/02/28 10:38:00  decaro
56 AliTOFGeometry::fAngles, AliTOFGeometry::fHeights, AliTOFGeometry::fDistances arrays: dimension definition in the right location
57
58 Revision 1.11  2005/12/15 14:17:29  decaro
59 Correction of some parameter values
60
61 Revision 1.10  2005/12/15 08:55:32  decaro
62 New TOF geometry description (V5) -G. Cara Romeo and A. De Caro
63
64 Revision 1.9.1  2005/07/19 A. De Caro
65         Created daughter-classes AliTOFGeometryV4 and AliTOFGeometryV5
66         => moved global methods IsInsideThePad, DistanceToPad,
67         GetPlate, GetSector, GetStrip, GetPadX, GetPadZ,
68         GetX, GetY, GetZ, GetPadDx, GetPadDy and GetPadDz
69         in daughter-classes
70
71 Revision 1.9  2005/10/20 12:41:35  hristov
72 Implementation of parallel tracking. It is not the default version, one can use it passing option MI from AliReconstruction to TOF (M.Ivanov)
73
74 Revision 1.8  2004/11/29 08:28:01  decaro
75 Introduction of a new TOF constant (i.e. TDC bin width)
76
77 Revision 1.7  2004/11/05 07:20:08  decaro
78 TOF library splitting and conversion of some printout messages in AliLog schema (T.Kuhr)
79
80 Revision 1.6  2004/06/15 15:27:59  decaro
81 TOF raw data: preliminary implementation and style changes
82
83 Revision 1.5  2004/04/20 14:37:22  hristov
84 Using TMath::Abs instead of fabs, arrays of variable size created/deleted correctly (HP,Sun)
85
86 Revision 1.4  2004/04/13 09:42:51  decaro
87 Track reconstruction code for TOF: updating
88
89 Revision 1.3  2003/12/29 18:40:39  hristov
90 Copy/paste error corrected
91
92 Revision 1.2  2003/12/29 17:26:01  hristov
93 Using enum to initaialize static ints in the header file, the initialization of static floats moved to the implementation file
94
95 Revision 1.1  2003/12/29 15:18:03  decaro
96 TOF geometry updating (addition of AliTOFGeometry)
97
98 Revision 0.05  2004/6/11 A.De Caro
99         Implement Global method NpadXStrip
100         Insert four float constants (originally  in AliTOF class)
101 Revision 0.04  2004/4/05 S.Arcelli
102         Implement Global methods IsInsideThePad 
103                                   DistanceToPad 
104 Revision 0.03  2003/12/14 S.Arcelli
105         Set Phi range [-180,180]->[0,360] 
106 Revision 0.02  2003/12/10 S.Arcelli:
107         Implement Global methods GetPos & GetDetID 
108 Revision 0.01  2003/12/04 S.Arcelli
109 */
110
111 ///////////////////////////////////////////////////////////////////////////////
112 //                                                                           //
113 //  TOF Geometry class                                                       //
114 //                                                                           //
115 ///////////////////////////////////////////////////////////////////////////////
116
117 #include "TGeoManager.h"
118 //#include "TGeoMatrix.h"
119 #include "TMath.h"
120
121 #include "AliConst.h"
122 #include "AliGeomManager.h"
123 #include "AliLog.h"
124
125 #include "AliTOFGeometry.h"
126
127 extern TGeoManager *gGeoManager;
128
129 ClassImp(AliTOFGeometry)
130
131 const Float_t AliTOFGeometry::fgkZlenA    = 370.6*2.; // length (cm) of the A module
132 const Float_t AliTOFGeometry::fgkZlenB    = 146.5;    // length (cm) of the B module
133 const Float_t AliTOFGeometry::fgkZlenC    = 170.45;   // length (cm) of the C module
134 const Float_t AliTOFGeometry::fgkMaxhZtof = 370.6;    // Max half z-size of TOF (cm)
135
136 const Float_t AliTOFGeometry::fgkxTOF     = 372.00;// Inner radius of the TOF for Reconstruction (cm)
137 const Float_t AliTOFGeometry::fgkRmin     = 371.00;// Inner radius of the TOF (cm)
138 const Float_t AliTOFGeometry::fgkRmax     = 400.05;// Outer radius of the TOF (cm)
139
140 const Float_t AliTOFGeometry::fgkXPad     = 2.5;    // Pad size in the x direction (cm)
141 const Float_t AliTOFGeometry::fgkZPad     = 3.5;    // Pad size in the z direction (cm)
142
143 const Float_t AliTOFGeometry::fgkStripLength = 122.;// Strip Length (rho X phi direction) (cm)
144
145 const Float_t AliTOFGeometry::fgkSigmaForTail1= 2.; //Sig1 for simulation of TDC tails 
146 const Float_t AliTOFGeometry::fgkSigmaForTail2= 0.5;//Sig2 for simulation of TDC tails
147
148 const Float_t AliTOFGeometry::fgkPhiSec= 20;//sector Phi width (deg)
149
150 const Float_t AliTOFGeometry::fgkTdcBin = 24.4;     // time-of-flight bin width [ps]
151 const Float_t AliTOFGeometry::fgkToTBin = 48.8;     // time-over-threshold bin width [ps]
152
153 const Float_t AliTOFGeometry::fgkDeadTime = 25E+03;        // Single channel dead time (ps)
154 const Float_t AliTOFGeometry::fgkMatchingWindow = fgkTdcBin*TMath::Power(2,13); // Matching window  (ps)
155
156 const Float_t AliTOFGeometry::fgkAngles[kNPlates][kMaxNstrip] = {
157     { 43.99,  43.20,  42.40,  41.59,  40.77,  39.94,  39.11,  38.25,  37.40,  36.53,
158       35.65,  34.76,  33.87,  32.96,  32.05,  31.13,  30.19,  29.24,  12.33,  0.00},
159
160     { 27.26,  26.28,  25.30,  24.31,  23.31,  22.31,  21.30,  20.29,  19.26,  18.24,
161       17.20,  16.16,  15.11,  14.05,  13.00,  11.93,  10.87,   9.80,   8.74,  0.00},
162
163     {  0.00,   6.30,   5.31,   4.25,   3.19,   2.12,   1.06,   0.00,  -1.06,  -2.12,
164       -3.19,  -4.25,  -5.31,  -6.30,   0.00,   0.00,   0.00,   0.00,   0.00,  0.00},
165
166     { -8.74,  -9.80, -10.87, -11.93, -13.00, -14.05, -15.11, -16.16, -17.20, -18.24,
167      -19.26, -20.29, -21.30, -22.31, -23.31, -24.31, -25.30, -26.28, -27.26,  0.00},
168     
169     {-12.33, -29.24, -30.19, -31.13, -32.05, -32.96, -33.87, -34.76, -35.65, -36.53,
170      -37.40, -38.25, -39.11, -39.94, -40.77, -41.59, -42.40, -43.20, -43.99,  0.00}
171   };
172 const Float_t AliTOFGeometry::fgkHeights[kNPlates][kMaxNstrip] = {
173     {-8.2,  -7.5,  -8.2,  -7.7,  -8.1,  -7.6,  -7.7,  -7.7,  -7.7,  -7.7,
174      -7.5,  -7.2,  -7.3,  -7.5,  -7.6,  -7.8,  -8.3,  -9.3,  -3.1,   0.0},
175
176     {-7.9,  -8.1,  -8.5,  -9.0, -10.1,  -3.9,  -5.9,  -7.7, -10.1,  -3.6,
177      -5.8,  -8.0, -10.4,  -4.4,  -7.2, -10.2,  -4.6,  -7.4, -10.4,   0.0},
178
179     {-2.5, -10.4,  -5.0,  -9.9,  -4.8,  -9.9,  -4.7, -10.2,  -4.7,  -9.9,
180      -4.8,  -9.9,  -5.0, -10.4,  -2.5,   0.0,   0.0,   0.0,   0.0,   0.0},
181
182     {-10.4, -7.4,  -4.6, -10.2,  -7.2,  -4.4, -10.4,  -8.0,  -5.8,  -3.6,
183      -10.1,  -7.7, -5.9,  -3.9, -10.1,  -9.0,  -8.5,  -8.1,  -7.9,   0.0},
184
185     { -3.1,  -9.3, -8.3,  -7.8,  -7.6,  -7.5,  -7.3,  -7.2,  -7.5,  -7.7,
186       -7.7,  -7.7, -7.7,  -7.6,  -8.1,  -7.7,  -8.2,  -7.5,  -8.2,   0.0}
187   };
188
189
190 const Float_t AliTOFGeometry::fgkDistances[kNPlates][kMaxNstrip] = {
191     { 364.1,  354.9,  344.5,  335.4,  325.5,  316.6,  307.2,  298.0,  288.9,  280.0,
192       271.3,  262.7,  254.0,  244.8,  236.1,  227.7,  219.1,  210.3,  205.7,    0.0},
193
194     { 194.2,  186.1,  177.9,  169.8,  161.5,  156.3,  147.8,  139.4,  130.9,  125.6,
195       117.3,  109.2,  101.1,   95.3,   87.1,   79.2,   73.0,   65.1,   57.6,    0.0},
196
197     {  49.5,   41.3,   35.3,   27.8,   21.2,   13.9,    7.0,    0.0,   -7.0,  -13.9,
198       -21.2,  -27.8,  -35.3,  -41.3,  -49.5,    0.0,    0.0,    0.0,    0.0,    0.0},
199
200     { -57.6,  -65.1,  -73.0,  -79.2,  -87.1,  -95.3, -101.1, -109.2, -117.3, -125.6,
201      -130.9, -139.4, -147.8, -156.3, -161.5, -169.8, -177.9, -186.1, -194.2,    0.0},
202
203     {-205.7, -210.3, -219.1, -227.7, -236.1, -244.8, -254.0, -262.7, -271.3, -280.0,
204      -288.9, -298.0, -307.2, -316.6, -325.5, -335.4, -344.5, -354.9, -364.1,    0.0}
205   };
206 //_____________________________________________________________________________
207 AliTOFGeometry::AliTOFGeometry():
208   fHoles(1)
209 {
210   //
211   // AliTOFGeometry default constructor
212   //
213
214 }
215
216 //_____________________________________________________________________________
217 AliTOFGeometry::~AliTOFGeometry()
218 {
219   //
220   // AliTOFGeometry destructor
221   //
222 }
223 //_____________________________________________________________________________
224 void AliTOFGeometry::ImportGeometry(){
225   TGeoManager::Import("geometry.root");
226 }
227 //_____________________________________________________________________________
228 void AliTOFGeometry::GetPosPar(Int_t *det, Float_t *pos) const
229 {
230 //
231 // Returns space point coor (x,y,z) (cm)  for Detector 
232 // Indices  (iSect,iPlate,iStrip,iPadX,iPadZ) 
233 //
234
235   pos[0]=GetX(det);  
236   pos[1]=GetY(det);  
237   pos[2]=GetZ(det);
238   
239 }
240 //_____________________________________________________________________________
241 void AliTOFGeometry::GetDetID( Float_t *pos, Int_t *det) const
242 {
243  //
244  // Returns Detector Indices (iSect,iPlate,iStrip,iPadX,iPadZ) 
245  // space point coor (x,y,z) (cm)  
246
247
248   det[0]=GetSector(pos);  
249   det[1]=GetPlate(pos);  
250   det[2]=GetStrip(pos);
251   det[3]=GetPadZ(pos);
252   det[4]=GetPadX(pos);
253   
254 }
255 //_____________________________________________________________________________
256
257 void AliTOFGeometry::DetToStripRF(Int_t nPadX, Int_t nPadZ, Float_t &x,  Float_t &z) const
258 {
259   //
260   // Returns the local coordinates (x, z) in strip reference frame
261   // for the bottom corner of the pad number (nPadX, nPadZ)
262   //
263   /*
264   const Float_t xCenterStrip = kNpadX * fgkXPad / 2.;
265   const Float_t zCenterStrip = kNpadZ * fgkZPad / 2.;
266
267   const Float_t xCenterPad = nPadX*fgkXPad + fgkXPad / 2.;
268   const Float_t zCenterPad = nPadZ*fgkZPad + fgkZPad / 2.;
269
270   x = xCenterPad - xCenterStrip;
271   z = zCenterPad - zCenterStrip;
272   */
273
274
275   x = (nPadX - kNpadX*0.5) * fgkXPad;
276   z = (nPadZ - kNpadZ*0.5) * fgkZPad;
277
278
279 }
280 //_____________________________________________________________________________
281 Float_t AliTOFGeometry::DistanceToPadPar(Int_t *det, Float_t *pos, Float_t *dist3d) const
282 {
283 //
284 // Returns distance of  space point with coor pos (x,y,z) (cm) wrt 
285 // pad with Detector Indices idet (iSect,iPlate,iStrip,iPadX,iPadZ) 
286 //
287     
288   //Transform pos into Sector Frame
289
290   Float_t x = pos[0];
291   Float_t y = pos[1];
292   Float_t z = pos[2];
293
294   Float_t radius = TMath::Sqrt(x*x+y*y);
295   //Float_t phi=TMath::ATan(y/x);       
296   //if(phi<0) phi = k2PI+phi; //2.*TMath::Pi()+phi;
297   Float_t phi = TMath::Pi()+TMath::ATan2(-y,-x);        
298   //  Get the local angle in the sector philoc
299   Float_t angle   = phi*kRaddeg-( Int_t (kRaddeg*phi/fgkPhiSec) + 0.5)*fgkPhiSec;
300   Float_t xs = radius*TMath::Cos(angle/kRaddeg);
301   Float_t ys = radius*TMath::Sin(angle/kRaddeg);
302   Float_t zs = z;
303
304   // Do the same for the selected pad
305
306   Float_t g[3];
307   GetPosPar(det,g);
308
309   Float_t padRadius = TMath::Sqrt(g[0]*g[0]+g[1]*g[1]);
310   //Float_t padPhi = TMath::ATan(g[1]/g[0]);    
311   //if(padPhi<0) padPhi = k2Pi + padPhi;
312   Float_t padPhi = TMath::Pi()+TMath::ATan2(-g[1],-g[0]);       
313
314   //  Get the local angle in the sector philoc
315   Float_t padAngle = padPhi*kRaddeg-( Int_t (padPhi*kRaddeg/fgkPhiSec)+ 0.5) * fgkPhiSec;
316   Float_t padxs = padRadius*TMath::Cos(padAngle/kRaddeg);
317   Float_t padys = padRadius*TMath::Sin(padAngle/kRaddeg);
318   Float_t padzs = g[2];
319   
320   //Now move to local pad coordinate frame. Translate:
321   
322   Float_t xt = xs-padxs;
323   Float_t yt = ys-padys;
324   Float_t zt = zs-padzs;
325   //Now Rotate:
326   
327   Float_t alpha = GetAngles(det[1],det[2]);
328   Float_t xr =  xt*TMath::Cos(alpha/kRaddeg)+zt*TMath::Sin(alpha/kRaddeg);
329   Float_t yr =  yt;
330   Float_t zr = -xt*TMath::Sin(alpha/kRaddeg)+zt*TMath::Cos(alpha/kRaddeg);
331
332   Float_t dist = TMath::Sqrt(xr*xr+yr*yr+zr*zr);
333
334   if (dist3d){
335     dist3d[0] = xr;
336     dist3d[1] = yr;
337     dist3d[2] = zr;
338   }
339
340   return dist;
341
342 }
343 //_____________________________________________________________________________
344 Bool_t AliTOFGeometry::IsInsideThePadPar(Int_t *det, Float_t *pos) const
345 {
346 //
347 // Returns true if space point with coor pos (x,y,z) (cm) falls 
348 // inside pad with Detector Indices idet (iSect,iPlate,iStrip,iPadX,iPadZ) 
349 //
350
351   Bool_t isInside=false; 
352
353   /*
354   const Float_t khhony    = 1.0          ; // heigth of HONY  Layer
355   const Float_t khpcby    = 0.08         ; // heigth of PCB   Layer
356   const Float_t khrgly    = 0.055        ; // heigth of RED GLASS  Layer
357   const Float_t khglfy    = 0.285        ; // heigth of GLASS+FISHLINE  Layer
358   const Float_t khcpcby   = 0.16         ; // heigth of PCB  Central Layer
359   //const Float_t kwcpcbz   = 12.4         ; // z dimension of PCB  Central Layer
360   const Float_t khstripy = 2.*khhony+2.*khpcby+4.*khrgly+2.*khglfy+khcpcby;//3.11
361   //const Float_t kwstripz = kwcpcbz;
362   //const Float_t klstripx = fgkStripLength;
363   */
364
365   const Float_t kPadDepth = 0.5;//0.05;//0.11;//0.16;//          // heigth of Sensitive Layer
366
367   //Transform pos into Sector Frame
368
369   Float_t x = pos[0];
370   Float_t y = pos[1];
371   Float_t z = pos[2];
372
373   Float_t radius = TMath::Sqrt(x*x+y*y);
374   Float_t phi = TMath::Pi()+TMath::ATan2(-y,-x);        
375
376   //  Get the local angle in the sector philoc
377   Float_t angle = phi*kRaddeg-( Int_t (kRaddeg*phi/fgkPhiSec) + 0.5) *fgkPhiSec;
378   Float_t xs = radius*TMath::Cos(angle/kRaddeg);
379   Float_t ys = radius*TMath::Sin(angle/kRaddeg);
380   Float_t zs = z;
381
382   // Do the same for the selected pad
383
384   Float_t g[3];
385   GetPosPar(det,g);
386
387   Float_t padRadius = TMath::Sqrt(g[0]*g[0]+g[1]*g[1]);
388   Float_t padPhi = TMath::Pi()+TMath::ATan2(-g[1],-g[0]);       
389
390   //  Get the local angle in the sector philoc
391   Float_t padAngle = padPhi*kRaddeg-( Int_t (padPhi*kRaddeg/fgkPhiSec)+ 0.5) * fgkPhiSec; 
392   Float_t padxs = padRadius*TMath::Cos(padAngle/kRaddeg);
393   Float_t padys = padRadius*TMath::Sin(padAngle/kRaddeg);
394   Float_t padzs = g[2];
395
396   //Now move to local pad coordinate frame. Translate:
397
398   Float_t xt = xs-padxs;
399   Float_t yt = ys-padys;
400   Float_t zt = zs-padzs;
401
402   //Now Rotate:
403
404   Float_t alpha = GetAngles(det[1],det[2]);
405   Float_t xr =  xt*TMath::Cos(alpha/kRaddeg)+zt*TMath::Sin(alpha/kRaddeg);
406   Float_t yr =  yt;
407   Float_t zr = -xt*TMath::Sin(alpha/kRaddeg)+zt*TMath::Cos(alpha/kRaddeg);
408
409   if(TMath::Abs(xr)<=kPadDepth*0.5 && TMath::Abs(yr)<= (fgkXPad*0.5) && TMath::Abs(zr)<= (fgkZPad*0.5))
410     isInside=true;
411   return isInside;
412
413 }
414 //_____________________________________________________________________________
415 Bool_t AliTOFGeometry::IsInsideThePad(TGeoHMatrix mat, Float_t *pos, Float_t *dist3d) const
416 {
417 //
418 // Returns true if space point with coor pos (x,y,z) (cm) falls 
419 // inside pad with Detector Indices idet (iSect,iPlate,iStrip,iPadX,iPadZ) 
420 //
421
422   const Float_t kPadDepth = 0.5;      // heigth of Sensitive Layer
423   Double_t vecg[3];
424   vecg[0]=pos[0];
425   vecg[1]=pos[1];
426   vecg[2]=pos[2];
427   Double_t veclr[3]={-1.,-1.,-1.};
428   Double_t vecl[3]={-1.,-1.,-1.};
429   mat.MasterToLocal(vecg,veclr);  
430   vecl[0]=veclr[1];
431   vecl[1]=veclr[0];
432   //take into account reflections 
433   vecl[2]=-veclr[2];
434
435   Float_t xr = vecl[0];
436   Float_t yr = vecl[1];
437   Float_t zr = vecl[2];
438
439   if (dist3d){
440     dist3d[0] = vecl[0];
441     dist3d[1] = vecl[1];
442     dist3d[2] = vecl[2];
443   }
444  
445   Bool_t isInside=false; 
446   if(TMath::Abs(xr)<= kPadDepth*0.5 && TMath::Abs(yr)<= (fgkXPad*0.5) && TMath::Abs(zr)<= (fgkZPad*0.5))
447     isInside=true; 
448   return isInside;
449
450 }
451 //_____________________________________________________________________________
452 void AliTOFGeometry::GetVolumePath(Int_t *ind, Char_t *path ) {
453   //--------------------------------------------------------------------
454   // This function returns the colume path of a given pad 
455   //--------------------------------------------------------------------
456   Int_t sector = ind[0];
457   Char_t  string1[100];
458   Char_t  string2[100];
459   Char_t  string3[100];
460   
461   Int_t icopy=-1;
462   icopy=sector;
463  
464   sprintf(string1,"/ALIC_1/B077_1/BSEGMO%i_1/BTOF%i_1",icopy,icopy);
465   
466   Int_t iplate=ind[1];
467   Int_t istrip=ind[2];
468   if( iplate==0) icopy=istrip; 
469   if( iplate==1) icopy=istrip+NStripC(); 
470   if( iplate==2) icopy=istrip+NStripC()+NStripB(); 
471   if( iplate==3) icopy=istrip+NStripC()+NStripB()+NStripA(); 
472   if( iplate==4) icopy=istrip+NStripC()+2*NStripB()+NStripA(); 
473   icopy++;
474   sprintf(string2,"FTOA_0/FLTA_0/FSTR_%i",icopy);
475   if(fHoles && (sector==13 || sector==14 || sector==15)){
476     if(iplate<2)  sprintf(string2,"FTOB_0/FLTB_0/FSTR_%i",icopy);
477     if(iplate>2)  sprintf(string2,"FTOC_0/FLTC_0/FSTR_%i",icopy);
478   }
479  
480   Int_t padz = ind[3]+1; 
481   Int_t padx = ind[4]+1;
482   sprintf(string3,"FPCB_1/FSEN_1/FSEZ_%i/FPAD_%i",padz,padx);
483   sprintf(path,"%s/%s/%s",string1,string2,string3); 
484
485 }
486 //_____________________________________________________________________________
487 void AliTOFGeometry::GetVolumePath(Int_t sector, Char_t *path ){
488   //--------------------------------------------------------------------
489   // This function returns the colume path of a given sector 
490   //--------------------------------------------------------------------
491
492   Char_t string[100];
493
494   Int_t icopy = sector;
495
496   sprintf(string,"/ALIC_1/B077_1/BSEGMO%i_1/BTOF%i_1",icopy,icopy);
497   sprintf(path,"%s",string);
498
499 }
500 //_____________________________________________________________________________
501 void AliTOFGeometry::GetVolumePath(Int_t sector, Int_t plate, Int_t strip, Char_t *path ) {
502   //--------------------------------------------------------------------
503   // This function returns the colume path of a given strip 
504   //--------------------------------------------------------------------
505
506   Char_t string1[100];
507   Char_t string2[100];
508   Char_t string3[100];
509   
510   Int_t icopy = sector;
511
512   sprintf(string1,"/ALIC_1/B077_1/BSEGMO%i_1/BTOF%i_1",icopy,icopy);
513   
514   if(plate==0) icopy=strip; 
515   if(plate==1) icopy=strip+NStripC(); 
516   if(plate==2) icopy=strip+NStripC()+NStripB(); 
517   if(plate==3) icopy=strip+NStripC()+NStripB()+NStripA(); 
518   if(plate==4) icopy=strip+NStripC()+2*NStripB()+NStripA(); 
519   icopy++;
520   sprintf(string2,"FTOA_0/FLTA_0/FSTR_%i",icopy);
521   if(fHoles && (sector==13 || sector==14 || sector==15)){
522     if(plate<2)  sprintf(string2,"FTOB_0/FLTB_0/FSTR_%i",icopy);
523     if(plate>2)  sprintf(string2,"FTOC_0/FLTC_0/FSTR_%i",icopy);
524   }
525
526   sprintf(string3,"FPCB_1/FSEN_1");
527   sprintf(path,"%s/%s/%s",string1,string2,string3); 
528
529 }
530 //_____________________________________________________________________________
531 void AliTOFGeometry::GetPos(Int_t *det, Float_t *pos) 
532 {
533 //
534 // Returns space point coor (x,y,z) (cm)  for Detector 
535 // Indices  (iSect,iPlate,iStrip,iPadX,iPadZ) 
536 //
537   Char_t path[100];
538   GetVolumePath(det,path );
539   if (!gGeoManager) {
540     printf("ERROR: no TGeo\n");
541   }
542   gGeoManager->cd(path);
543   TGeoHMatrix global;
544   global = *gGeoManager->GetCurrentMatrix();
545   const Double_t *tr = global.GetTranslation();
546
547   pos[0]=tr[0];  
548   pos[1]=tr[1];  
549   pos[2]=tr[2];
550 }
551 //_____________________________________________________________________________
552 Int_t AliTOFGeometry::GetPlate(Float_t *pos) const
553 {
554   //
555   // Returns the Plate index 
556   //
557   const Float_t kInterCentrModBorder1 = 49.5;
558   const Float_t kInterCentrModBorder2 = 57.5;
559   const Float_t kExterInterModBorder1 = 196.0;
560   const Float_t kExterInterModBorder2 = 203.5;
561
562   const Float_t kLengthExInModBorder  = 4.7;
563   const Float_t kLengthInCeModBorder  = 7.0;
564
565   //const Float_t khAlWall = 0.1;
566   const Float_t kModuleWallThickness = 0.3;
567   //const Float_t kHoneycombLayerThickness = 1.5;
568
569   Int_t iPlate=-1;
570
571   Float_t posLocal[3];
572   for (Int_t ii=0; ii<3; ii++) posLocal[ii] = pos[ii];
573
574   Int_t isector = GetSector(posLocal);
575   if(isector == -1){
576     //AliError("Detector Index could not be determined");
577     return iPlate;
578   }
579
580   // ALICE reference frame -> B071/B074/B075 = BTO1/2/3 reference frame
581   Double_t angles[6] = 
582     {90., 90.+(isector+0.5)*fgkPhiSec,
583       0., 0.,
584      90., (isector+0.5)*fgkPhiSec
585     };
586   Rotation(posLocal,angles);
587
588   Float_t step[3] = {0., 0., (fgkRmax+fgkRmin)*0.5};
589   Translation(posLocal,step);
590
591   // B071/B074/B075 = BTO1/2/3 reference frame -> FTOA = FLTA reference frame
592   angles[0] = 90.;
593   angles[1] =  0.;
594   angles[2] =  0.;
595   angles[3] =  0.;
596   angles[4] = 90.;
597   angles[5] =270.;
598
599   Rotation(posLocal,angles);
600
601   Float_t yLocal = posLocal[1];
602   Float_t zLocal = posLocal[2];
603
604   Float_t deltaRhoLoc  = (fgkRmax-fgkRmin)*0.5 - kModuleWallThickness + yLocal;
605   Float_t deltaZetaLoc = TMath::Abs(zLocal);
606
607   Float_t deltaRHOmax = 0.;
608
609   if (TMath::Abs(zLocal)>=kExterInterModBorder1 && TMath::Abs(zLocal)<=kExterInterModBorder2) 
610     {
611       deltaRhoLoc -= kLengthExInModBorder;
612       deltaZetaLoc = kExterInterModBorder2-deltaZetaLoc;
613       deltaRHOmax  = (fgkRmax - fgkRmin)*0.5 - kModuleWallThickness - 2.*kLengthExInModBorder; // old 5.35, new 4.8
614
615       if (deltaRhoLoc > deltaZetaLoc*deltaRHOmax/(kInterCentrModBorder2-kInterCentrModBorder1)) {
616         if (zLocal<0) iPlate = 0;
617         else iPlate = 4;
618       }
619       else {
620         if (zLocal<0) iPlate = 1;
621         else iPlate = 3;
622       }
623     }
624   else if (TMath::Abs(zLocal)>=kInterCentrModBorder1 && TMath::Abs(zLocal)<=kInterCentrModBorder2) 
625     {
626       deltaRhoLoc -= kLengthInCeModBorder;
627       deltaZetaLoc = deltaZetaLoc-kInterCentrModBorder1;
628       deltaRHOmax = (fgkRmax - fgkRmin)*0.5 - kModuleWallThickness - 2.*kLengthInCeModBorder; // old 0.39, new 0.2
629
630       if (deltaRhoLoc>deltaZetaLoc*deltaRHOmax/(kInterCentrModBorder2-kInterCentrModBorder1)) iPlate = 2;
631       else {
632         if (zLocal<0) iPlate = 1;
633         else iPlate = 3;
634       }
635     }
636
637   if      (zLocal>-fgkZlenA*0.5          && zLocal<-kExterInterModBorder2) iPlate = 0;
638   else if (zLocal>-kExterInterModBorder1 && zLocal<-kInterCentrModBorder2) iPlate = 1;
639   else if (zLocal>-kInterCentrModBorder1 && zLocal< kInterCentrModBorder1) iPlate = 2;
640   else if (zLocal> kInterCentrModBorder2 && zLocal< kExterInterModBorder1) iPlate = 3;
641   else if (zLocal> kExterInterModBorder2 && zLocal< fgkZlenA*0.5)          iPlate = 4;
642   
643   return iPlate;
644
645 }
646
647 //_____________________________________________________________________________
648 Int_t AliTOFGeometry::GetSector(Float_t *pos) const
649 {
650   //
651   // Returns the Sector index 
652   //
653
654   Int_t   iSect = -1; 
655
656   Float_t x = pos[0];
657   Float_t y = pos[1];
658   Float_t z = pos[2];
659
660   Float_t rho = TMath::Sqrt(x*x + y*y);
661
662   if (!((z>=-fgkZlenA*0.5 && z<=fgkZlenA*0.5) &&
663         (rho>=(fgkRmin) && rho<=(fgkRmax)))) {
664     //AliError("Detector Index could not be determined");
665     return iSect;
666   }
667
668   Float_t phi = TMath::Pi() + TMath::ATan2(-y,-x);      
669
670   iSect  = (Int_t) (phi*kRaddeg/fgkPhiSec);
671   
672   return iSect;
673
674 }
675 //_____________________________________________________________________________
676 Int_t AliTOFGeometry::GetStrip(Float_t *pos) const
677 {
678   //
679   // Returns the Strip index 
680   //
681   const Float_t khhony    = 1.0          ; // heigth of HONY  Layer
682   const Float_t khpcby    = 0.08         ; // heigth of PCB   Layer
683   const Float_t khrgly    = 0.055        ; // heigth of RED GLASS  Layer
684   const Float_t khglfy    = 0.285        ; // heigth of GLASS+FISHLINE  Layer
685   const Float_t khcpcby   = 0.16         ; // heigth of PCB  Central Layer
686   const Float_t kwcpcbz   = 12.4         ; // z dimension of PCB  Central Layer
687   const Float_t khstripy = 2.*khhony+2.*khpcby+4.*khrgly+2.*khglfy+khcpcby;//3.11
688   const Float_t kwstripz = kwcpcbz;
689   const Float_t klstripx = fgkStripLength;
690   
691   Int_t iStrip=-1;
692    
693   Float_t posLocal[3];
694   for (Int_t ii=0; ii<3; ii++) posLocal[ii] = pos[ii];
695  
696   Int_t isector = GetSector(posLocal);
697   if(isector == -1){
698     //AliError("Detector Index could not be determined");
699     return iStrip;}
700   Int_t iplate =  GetPlate(posLocal);
701   if(iplate == -1){
702     //AliError("Detector Index could not be determined");
703     return iStrip;} 
704
705   Int_t nstrips=0;
706   switch (iplate) {
707   case 0:
708     nstrips=kNStripC;
709     break;
710   case 4:
711     nstrips=kNStripC;
712     break;
713   case 1:
714     nstrips=kNStripB;
715     break;
716   case 3:
717     nstrips=kNStripB;
718     break;
719   case 2:
720     nstrips=kNStripA;
721     break;
722   }
723   
724   // ALICE reference frame -> B071/B074/B075 = BTO1/2/3 reference frame
725   Double_t angles[6] = 
726     {90., 90.+(isector+0.5)*fgkPhiSec,
727       0., 0.,
728      90., (isector+0.5)*fgkPhiSec
729     };
730   Rotation(posLocal,angles);
731
732   Float_t step[3] = {0., 0., (fgkRmax+fgkRmin)*0.5};
733   Translation(posLocal,step);
734
735   // B071/B074/B075 = BTO1/2/3 reference frame -> FTOA = FLTA reference frame
736   angles[0] = 90.;
737   angles[1] =  0.;
738   angles[2] =  0.;
739   angles[3] =  0.;
740   angles[4] = 90.;
741   angles[5] =270.;
742
743   Rotation(posLocal,angles);
744
745   // FTOA/B/C = FLTA/B/C reference frame -> FSTR reference frame
746   Int_t totStrip=0;
747   for (Int_t istrip=0; istrip<nstrips; istrip++){
748
749     Float_t posLoc2[3]={posLocal[0],posLocal[1],posLocal[2]};         
750
751     step[0] = 0.;
752     step[1] = GetHeights(iplate,istrip);
753     step[2] = -GetDistances(iplate,istrip);
754     Translation(posLoc2,step);
755
756     if      (GetAngles(iplate,istrip) >0.) {
757       angles[0] = 90.;
758       angles[1] =  0.;
759       angles[2] = 90.+GetAngles(iplate,istrip);
760       angles[3] = 90.;
761       angles[4] = GetAngles(iplate,istrip);
762       angles[5] = 90.;
763     }
764     else if (GetAngles(iplate,istrip)==0.) {
765       angles[0] = 90.;
766       angles[1] =  0.;
767       angles[2] = 90.;
768       angles[3] = 90.;
769       angles[4] =  0;
770       angles[5] =  0.;
771     }
772     else if (GetAngles(iplate,istrip) <0.) {
773       angles[0] = 90.;
774       angles[1] =  0.;
775       angles[2] = 90.+GetAngles(iplate,istrip);
776       angles[3] = 90.;
777       angles[4] =-GetAngles(iplate,istrip);
778       angles[5] = 270.;
779     }
780     Rotation(posLoc2,angles);
781
782     if ((TMath::Abs(posLoc2[0])<=klstripx*0.5) &&
783         (TMath::Abs(posLoc2[1])<=khstripy*0.5) &&
784         (TMath::Abs(posLoc2[2])<=kwstripz*0.5)) {
785       iStrip = istrip;
786       totStrip++;
787       for (Int_t jj=0; jj<3; jj++) posLocal[jj]=posLoc2[jj];
788       //AliInfo(Form(" posLocal[0] = %f, posLocal[1] = %f, posLocal[2] = %f ", posLocal[0],posLocal[1],posLocal[2]));
789
790       //AliInfo(Form(" GetAngles(%1i,%2i) = %f, pos[0] = %f, pos[1] = %f, pos[2] = %f", iplate, istrip, GetAngles(iplate,istrip), pos[0], pos[1], pos[2]));
791       break;
792     }
793
794     if (totStrip>1) AliInfo(Form("total strip number found %2i",totStrip));
795
796   }
797
798   return iStrip;
799   
800 }
801 //_____________________________________________________________________________
802 Int_t AliTOFGeometry::GetPadZ(Float_t *pos) const
803 {
804   //
805   // Returns the Pad index along Z 
806   //
807   //const Float_t klsensmx = kNpadX*fgkXPad;  // length of Sensitive Layer
808   //const Float_t khsensmy = 0.05;//0.11;//0.16;// heigth of Sensitive Layer
809   //const Float_t kwsensmz = kNpadZ*fgkZPad;  // width of Sensitive Layer
810
811   Int_t iPadZ = -1;
812
813   Float_t posLocal[3];
814   for (Int_t ii=0; ii<3; ii++) posLocal[ii] = pos[ii];
815  
816   Int_t isector = GetSector(posLocal);
817   if(isector == -1){
818     //AliError("Detector Index could not be determined");
819     return iPadZ;}
820   Int_t iplate =  GetPlate(posLocal);
821   if(iplate == -1){
822     //AliError("Detector Index could not be determined");
823     return iPadZ;}
824   Int_t istrip =  GetStrip(posLocal);
825   if(istrip == -1){
826     //AliError("Detector Index could not be determined");
827     return iPadZ;}
828
829   // ALICE reference frame -> B071/B074/B075 = BTO1/2/3 reference frame
830   Double_t angles[6] = 
831     {90., 90.+(isector+0.5)*fgkPhiSec,
832       0., 0.,
833      90., (isector+0.5)*fgkPhiSec
834     };
835   Rotation(posLocal,angles);
836
837   Float_t step[3] = {0., 0., (fgkRmax+fgkRmin)*0.5};
838   Translation(posLocal,step);
839
840   // B071/B074/B075 = BTO1/2/3 reference frame -> FTOA = FLTA reference frame
841   angles[0] = 90.;
842   angles[1] =  0.;
843   angles[2] =  0.;
844   angles[3] =  0.;
845   angles[4] = 90.;
846   angles[5] =270.;
847
848   Rotation(posLocal,angles);
849
850   // FTOA/B/C = FLTA/B/C reference frame -> FSTR reference frame
851   step[0] = 0.;
852   step[1] = GetHeights(iplate,istrip);
853   step[2] = -GetDistances(iplate,istrip);
854   Translation(posLocal,step);
855
856   if      (GetAngles(iplate,istrip) >0.) {
857     angles[0] = 90.;
858     angles[1] =  0.;
859     angles[2] = 90.+GetAngles(iplate,istrip);
860     angles[3] = 90.;
861     angles[4] = GetAngles(iplate,istrip);
862     angles[5] = 90.;
863   }
864   else if (GetAngles(iplate,istrip)==0.) {
865     angles[0] = 90.;
866     angles[1] =  0.;
867     angles[2] = 90.;
868     angles[3] = 90.;
869     angles[4] =  0;
870     angles[5] =  0.;
871   }
872   else if (GetAngles(iplate,istrip) <0.) {
873     angles[0] = 90.;
874     angles[1] =  0.;
875     angles[2] = 90.+GetAngles(iplate,istrip);
876     angles[3] = 90.;
877     angles[4] =-GetAngles(iplate,istrip);
878     angles[5] = 270.;
879   }
880   Rotation(posLocal,angles);
881
882   step[0] =-0.5*kNpadX*fgkXPad;
883   step[1] = 0.;
884   step[2] =-0.5*kNpadZ*fgkZPad;
885   Translation(posLocal,step);
886
887   iPadZ = (Int_t)(posLocal[2]/fgkZPad);
888   if (iPadZ==kNpadZ) iPadZ--;
889   else if (iPadZ>kNpadZ) iPadZ=-1;
890
891   return iPadZ;
892
893 }
894 //_____________________________________________________________________________
895 Int_t AliTOFGeometry::GetPadX(Float_t *pos) const
896 {
897   //
898   // Returns the Pad index along X 
899   //
900   //const Float_t klsensmx = kNpadX*fgkXPad;  // length of Sensitive Layer
901   //const Float_t khsensmy = 0.05;//0.11;//0.16;// heigth of Sensitive Layer
902   //const Float_t kwsensmz = kNpadZ*fgkZPad;  // width of Sensitive Layer
903
904   Int_t iPadX  = -1;
905
906   Float_t posLocal[3];
907   for (Int_t ii=0; ii<3; ii++) posLocal[ii] = pos[ii];
908  
909   Int_t isector = GetSector(posLocal);
910   if(isector == -1){
911     //AliError("Detector Index could not be determined");
912     return iPadX;}
913   Int_t iplate =  GetPlate(posLocal);
914   if(iplate == -1){
915     //AliError("Detector Index could not be determined");
916     return iPadX;} 
917   Int_t istrip =  GetStrip(posLocal);
918   if(istrip == -1){  
919     //AliError("Detector Index could not be determined");
920     return iPadX;}
921
922   // ALICE reference frame -> B071/B074/B075 = BTO1/2/3 reference frame
923   Double_t angles[6] = 
924     {90., 90.+(isector+0.5)*fgkPhiSec,
925       0.,  0.,
926      90., (isector+0.5)*fgkPhiSec
927     };
928   Rotation(posLocal,angles);
929
930   Float_t step[3] = {0., 0., (fgkRmax+fgkRmin)*0.5};
931   Translation(posLocal,step);
932
933   // B071/B074/B075 = BTO1/2/3 reference frame -> FTOA/B/C = FLTA/B/C reference frame
934   angles[0] = 90.;
935   angles[1] =  0.;
936   angles[2] =  0.;
937   angles[3] =  0.;
938   angles[4] = 90.;
939   angles[5] =270.;
940
941   Rotation(posLocal,angles);
942
943   // FTOA/B/C = FLTA/B/C reference frame -> FSTR reference frame
944   step[0] = 0.;
945   step[1] = GetHeights(iplate,istrip);
946   step[2] = -GetDistances(iplate,istrip);
947   Translation(posLocal,step);
948
949   if      (GetAngles(iplate,istrip) >0.) {
950     angles[0] = 90.;
951     angles[1] =  0.;
952     angles[2] = 90.+GetAngles(iplate,istrip);
953     angles[3] = 90.;
954     angles[4] = GetAngles(iplate,istrip);
955     angles[5] = 90.;
956   }
957   else if (GetAngles(iplate,istrip)==0.) {
958     angles[0] = 90.;
959     angles[1] =  0.;
960     angles[2] = 90.;
961     angles[3] = 90.;
962     angles[4] =  0;
963     angles[5] =  0.;
964   }
965   else if (GetAngles(iplate,istrip) <0.) {
966     angles[0] = 90.;
967     angles[1] =  0.;
968     angles[2] = 90.+GetAngles(iplate,istrip);
969     angles[3] = 90.;
970     angles[4] =-GetAngles(iplate,istrip);
971     angles[5] = 270.;
972   }
973   Rotation(posLocal,angles);
974
975   step[0] =-0.5*kNpadX*fgkXPad;
976   step[1] = 0.;
977   step[2] =-0.5*kNpadZ*fgkZPad;
978   Translation(posLocal,step);
979
980   iPadX = (Int_t)(posLocal[0]/fgkXPad);
981   if (iPadX==kNpadX) iPadX--;
982   else if (iPadX>kNpadX) iPadX=-1;
983
984   return iPadX;
985
986 }
987 //_____________________________________________________________________________
988 Float_t AliTOFGeometry::GetX(Int_t *det) const
989 {
990   //
991   // Returns X coordinate (cm)
992   //
993
994   Int_t isector = det[0];
995   Int_t iplate  = det[1];
996   Int_t istrip  = det[2];
997   Int_t ipadz   = det[3];
998   Int_t ipadx   = det[4];
999
1000   /*
1001   // Find out distance d on the plane wrt median phi:
1002   Float_t d = (ipadx+0.5-kNpadX*0.5)*fgkXPad;
1003
1004   // The radius r in xy plane:
1005   //Float_t r = (fgkRmin+fgkRmax)*0.5-0.01+GetHeights(iplate,istrip)+
1006   //  (ipadz-0.5)*fgkZPad*TMath::Sin(GetAngles(iplate,istrip)/kRaddeg)-0.25; ???
1007   Float_t r = (fgkRmin+fgkRmax)*0.5-0.01+GetHeights(iplate,istrip)+
1008     (ipadz-0.5)*fgkZPad*TMath::Sin(GetAngles(iplate,istrip)/kRaddeg);
1009
1010   // local azimuthal angle in the sector philoc
1011   Float_t philoc  = TMath::ATan(d/r);
1012   //if(philoc<0.) philoc = k2PI + philoc;
1013
1014   // azimuthal angle in the global frame  phi
1015   Float_t phi   = philoc*kRaddeg+(isector+0.5)*fgkPhiSec;
1016
1017   Float_t xCoor = r/TMath::Cos(philoc)*TMath::Cos(phi/kRaddeg);
1018   */
1019
1020   // Pad reference frame -> FSTR reference frame
1021   Float_t posLocal[3] = {0., 0., 0.};
1022   Float_t step[3] = {-(ipadx+0.5)*fgkXPad, 0., -(ipadz+0.5)*fgkZPad};
1023   Translation(posLocal,step);
1024
1025   step[0] = kNpadX*0.5*fgkXPad;
1026   step[1] = 0.;
1027   step[2] = kNpadZ*0.5*fgkZPad;
1028   /*
1029   Float_t posLocal[3] = {(ipadx+0.5)*fgkXPad, 0., (ipadz+0.5)*fgkZPad};
1030   Float_t step[3]= {kNpadX*0.5*fgkXPad, 0., kNpadZ*0.5*fgkZPad};
1031   */
1032   Translation(posLocal,step);
1033
1034   // FSTR reference frame -> FTOA/B/C = FLTA/B/C reference frame
1035   Double_t angles[6];
1036   if      (GetAngles(iplate,istrip) >0.) {
1037     angles[0] = 90.;
1038     angles[1] =  0.;
1039     angles[2] = 90.+GetAngles(iplate,istrip);
1040     angles[3] = 90.;
1041     angles[4] = GetAngles(iplate,istrip);
1042     angles[5] = 90.;
1043   }
1044   else if (GetAngles(iplate,istrip)==0.) {
1045     angles[0] = 90.;
1046     angles[1] =  0.;
1047     angles[2] = 90.;
1048     angles[3] = 90.;
1049     angles[4] =  0;
1050     angles[5] =  0.;
1051   }
1052   else if (GetAngles(iplate,istrip) <0.) {
1053     angles[0] = 90.;
1054     angles[1] =  0.;
1055     angles[2] = 90.+GetAngles(iplate,istrip);
1056     angles[3] = 90.;
1057     angles[4] =-GetAngles(iplate,istrip);
1058     angles[5] = 270.;
1059   }
1060
1061   InverseRotation(posLocal,angles);
1062
1063   step[0] = 0.;
1064   step[1] = -GetHeights(iplate,istrip);
1065   step[2] =  GetDistances(iplate,istrip);
1066   Translation(posLocal,step);
1067
1068   // FTOA = FLTA reference frame -> B071/B074/B075 = BTO1/2/3 reference frame
1069   angles[0] = 90.;
1070   angles[1] =  0.;
1071   angles[2] =  0.;
1072   angles[3] =  0.;
1073   angles[4] = 90.;
1074   angles[5] =270.;
1075
1076   InverseRotation(posLocal,angles);
1077
1078   // B071/B074/B075 = BTO1/2/3 reference frame -> ALICE reference frame
1079   step[0] = 0.;
1080   step[1] = 0.;
1081   step[2] = -((fgkRmax+fgkRmin)*0.5);
1082   Translation(posLocal,step);
1083
1084   angles[0] = 90.;
1085   angles[1] = 90.+(isector+0.5)*fgkPhiSec;
1086   angles[2] = 0.;
1087   angles[3] = 0.;
1088   angles[4] = 90.;
1089   angles[5] = (isector+0.5)*fgkPhiSec;
1090
1091   InverseRotation(posLocal,angles);
1092
1093   Float_t xCoor = posLocal[0];
1094
1095   return xCoor;
1096
1097 }
1098 //_____________________________________________________________________________
1099 Float_t AliTOFGeometry::GetY(Int_t *det) const
1100 {
1101   //
1102   // Returns Y coordinate (cm)
1103   //
1104
1105   Int_t isector = det[0];
1106   Int_t iplate  = det[1];
1107   Int_t istrip  = det[2];
1108   Int_t ipadz   = det[3];
1109   Int_t ipadx   = det[4];
1110
1111   /*
1112   // Find out distance d on the plane wrt median phi:
1113   Float_t d = (ipadx+0.5-kNpadX*0.5)*fgkXPad;
1114
1115   // The radius r in xy plane:
1116   //Float_t r = (fgkRmin+fgkRmax)*0.5-0.01+GetHeights(iplate,istrip)+
1117   //  (ipadz-0.5)*fgkZPad*TMath::Sin(GetAngles(iplate,istrip)/kRaddeg)-0.25; ???
1118   Float_t r = (fgkRmin+fgkRmax)*0.5-0.01+GetHeights(iplate,istrip)+
1119     (ipadz-0.5)*fgkZPad*TMath::Sin(GetAngles(iplate,istrip)/kRaddeg);
1120
1121   // local azimuthal angle in the sector philoc
1122   Float_t philoc = TMath::ATan(d/r);
1123   //if(philoc<0.) philoc = k2PI + philoc;
1124
1125   // azimuthal angle in the global frame  phi
1126   Float_t phi   = philoc*kRaddeg+(isector+0.5)*fgkPhiSec;
1127
1128   Float_t yCoor = r/TMath::Cos(philoc)*TMath::Sin(phi/kRaddeg);
1129   */
1130
1131   // Pad reference frame -> FSTR reference frame
1132   Float_t posLocal[3] = {0., 0., 0.};
1133   Float_t step[3] = {-(ipadx+0.5)*fgkXPad, 0., -(ipadz+0.5)*fgkZPad};
1134   Translation(posLocal,step);
1135
1136   step[0] = kNpadX*0.5*fgkXPad;
1137   step[1] = 0.;
1138   step[2] = kNpadZ*0.5*fgkZPad;
1139   /*
1140   Float_t posLocal[3] = {(ipadx+0.5)*fgkXPad, 0., (ipadz+0.5)*fgkZPad};
1141   Float_t step[3]= {kNpadX*0.5*fgkXPad, 0., kNpadZ*0.5*fgkZPad};
1142   */
1143   Translation(posLocal,step);
1144
1145   // FSTR reference frame -> FTOA/B/C = FLTA/B/C reference frame
1146
1147   Double_t angles[6];
1148   if      (GetAngles(iplate,istrip) >0.) {
1149     angles[0] = 90.;
1150     angles[1] =  0.;
1151     angles[2] = 90.+GetAngles(iplate,istrip);
1152     angles[3] = 90.;
1153     angles[4] = GetAngles(iplate,istrip);
1154     angles[5] = 90.;
1155   }
1156   else if (GetAngles(iplate,istrip)==0.) {
1157     angles[0] = 90.;
1158     angles[1] =  0.;
1159     angles[2] = 90.;
1160     angles[3] = 90.;
1161     angles[4] =  0;
1162     angles[5] =  0.;
1163   }
1164   else if (GetAngles(iplate,istrip) <0.) {
1165     angles[0] = 90.;
1166     angles[1] =  0.;
1167     angles[2] = 90.+GetAngles(iplate,istrip);
1168     angles[3] = 90.;
1169     angles[4] =-GetAngles(iplate,istrip);
1170     angles[5] = 270.;
1171   }
1172
1173   InverseRotation(posLocal,angles);
1174
1175   step[0] = 0.;
1176   step[1] = -GetHeights(iplate,istrip);
1177   step[2] =  GetDistances(iplate,istrip);
1178   Translation(posLocal,step);
1179
1180   // FTOA = FLTA reference frame -> B071/B074/B075 = BTO1/2/3 reference frame
1181   angles[0] = 90.;
1182   angles[1] =  0.;
1183   angles[2] =  0.;
1184   angles[3] =  0.;
1185   angles[4] = 90.;
1186   angles[5] =270.;
1187
1188   InverseRotation(posLocal,angles);
1189
1190   // B071/B074/B075 = BTO1/2/3 reference frame -> ALICE reference frame
1191   step[0] = 0.;
1192   step[1] = 0.;
1193   step[2] = -((fgkRmax+fgkRmin)*0.5);
1194   Translation(posLocal,step);
1195
1196   angles[0] = 90.;
1197   angles[1] = 90.+(isector+0.5)*fgkPhiSec;
1198   angles[2] = 0.;
1199   angles[3] = 0.;
1200   angles[4] = 90.;
1201   angles[5] = (isector+0.5)*fgkPhiSec;
1202
1203   InverseRotation(posLocal,angles);
1204
1205   Float_t yCoor = posLocal[1];
1206
1207   return yCoor;
1208
1209 }
1210
1211 //_____________________________________________________________________________
1212 Float_t AliTOFGeometry::GetZ(Int_t *det) const
1213 {
1214   //
1215   // Returns Z coordinate (cm)
1216   //
1217
1218   Int_t isector = det[0];
1219   Int_t iplate  = det[1];
1220   Int_t istrip  = det[2];
1221   Int_t ipadz   = det[3];
1222   Int_t ipadx   = det[4];
1223
1224   /*
1225   Float_t zCoor = GetDistances(iplate,istrip) +
1226     (0.5-ipadz) * fgkZPad * TMath::Cos(GetAngles(iplate,istrip)*kDegrad);
1227   */
1228
1229   // Pad reference frame -> FSTR reference frame
1230   Float_t posLocal[3] = {0., 0., 0.};
1231   Float_t step[3] = {-(ipadx+0.5)*fgkXPad, 0., -(ipadz+0.5)*fgkZPad};
1232   Translation(posLocal,step);
1233
1234   step[0] = kNpadX*0.5*fgkXPad;
1235   step[1] = 0.;
1236   step[2] = kNpadZ*0.5*fgkZPad;
1237   /*
1238   Float_t posLocal[3] = {(ipadx+0.5)*fgkXPad, 0., (ipadz+0.5)*fgkZPad};
1239   Float_t step[3]= {kNpadX*0.5*fgkXPad, 0., kNpadZ*0.5*fgkZPad};
1240   */
1241   Translation(posLocal,step);
1242
1243   // FSTR reference frame -> FTOA/B/C = FLTA/B/C reference frame
1244   Double_t angles[6];
1245   if      (GetAngles(iplate,istrip) >0.) {
1246     angles[0] = 90.;
1247     angles[1] =  0.;
1248     angles[2] = 90.+GetAngles(iplate,istrip);
1249     angles[3] = 90.;
1250     angles[4] = GetAngles(iplate,istrip);
1251     angles[5] = 90.;
1252   }
1253   else if (GetAngles(iplate,istrip)==0.) {
1254     angles[0] = 90.;
1255     angles[1] =  0.;
1256     angles[2] = 90.;
1257     angles[3] = 90.;
1258     angles[4] =  0;
1259     angles[5] =  0.;
1260   }
1261   else if (GetAngles(iplate,istrip) <0.) {
1262     angles[0] = 90.;
1263     angles[1] =  0.;
1264     angles[2] = 90.+GetAngles(iplate,istrip);
1265     angles[3] = 90.;
1266     angles[4] =-GetAngles(iplate,istrip);
1267     angles[5] = 270.;
1268   }
1269
1270   InverseRotation(posLocal,angles);
1271
1272   step[0] = 0.;
1273   step[1] = -GetHeights(iplate,istrip);
1274   step[2] =  GetDistances(iplate,istrip);
1275   Translation(posLocal,step);
1276
1277   // FTOA = FLTA reference frame -> B071/B074/B075 = BTO1/2/3 reference frame
1278   angles[0] = 90.;
1279   angles[1] =  0.;
1280   angles[2] =  0.;
1281   angles[3] =  0.;
1282   angles[4] = 90.;
1283   angles[5] =270.;
1284
1285   InverseRotation(posLocal,angles);
1286
1287   // B071/B074/B075 = BTO1/2/3 reference frame -> ALICE reference frame
1288   step[0] = 0.;
1289   step[1] = 0.;
1290   step[2] = -((fgkRmax+fgkRmin)*0.5);
1291   Translation(posLocal,step);
1292
1293   angles[0] = 90.;
1294   angles[1] = 90.+(isector+0.5)*fgkPhiSec;
1295   angles[2] = 0.;
1296   angles[3] = 0.;
1297   angles[4] = 90.;
1298   angles[5] = (isector+0.5)*fgkPhiSec;
1299
1300   InverseRotation(posLocal,angles);
1301
1302   Float_t zCoor = posLocal[2];
1303
1304   return zCoor;
1305
1306 }
1307 //_____________________________________________________________________________
1308
1309 void AliTOFGeometry::DetToSectorRF(Int_t vol[5], Double_t **coord)
1310 {
1311   //
1312   // Returns the local coordinates (x, y, z) in sector reference frame
1313   // for the 4 corners of each sector pad (vol[1], vol[2], vol[3], vol[4])
1314   //
1315
1316   if (!gGeoManager) printf("ERROR: no TGeo\n");
1317
1318   // ALICE -> TOF Sector
1319   Char_t path1[100]="";
1320   GetVolumePath(vol[0],path1);
1321   gGeoManager->cd(path1);
1322   TGeoHMatrix aliceToSector;
1323   aliceToSector = *gGeoManager->GetCurrentMatrix();
1324
1325   // TOF Sector -> ALICE
1326   //TGeoHMatrix sectorToALICE = aliceToSector.Inverse();
1327
1328   // ALICE -> TOF Pad
1329   Char_t path2[100]="";
1330   GetVolumePath(vol,path2);
1331   gGeoManager->cd(path2);
1332   TGeoHMatrix aliceToPad;
1333   aliceToPad = *gGeoManager->GetCurrentMatrix();
1334
1335   // TOF Pad -> ALICE
1336   TGeoHMatrix padToALICE = aliceToPad.Inverse();
1337
1338   // TOF Pad -> TOF Sector
1339   TGeoHMatrix padToSector = padToALICE*aliceToSector;
1340
1341   // TOF Sector -> TOF Pad
1342   //TGeoHMatrix sectorToPad = sectorToALICE*aliceToPad;
1343
1344   // coordinates of the pad bottom corner
1345   Double_t **cornerPad = new Double_t*[4];
1346   for (Int_t ii=0; ii<4; ii++) cornerPad[ii] = new Double_t[3];
1347
1348   cornerPad[0][0] = -fgkXPad/2.;
1349   cornerPad[0][1] =  0.;
1350   cornerPad[0][2] = -fgkZPad/2.;
1351
1352   cornerPad[1][0] =  fgkXPad/2.;
1353   cornerPad[1][1] =  0.;
1354   cornerPad[1][2] = -fgkZPad/2.;
1355
1356   cornerPad[2][0] =  fgkXPad/2.;
1357   cornerPad[2][1] =  0.;
1358   cornerPad[2][2] =  fgkZPad/2.;
1359
1360   cornerPad[3][0] = -fgkXPad/2.;
1361   cornerPad[3][1] =  0.;
1362   cornerPad[3][2] =  fgkZPad/2.;
1363
1364   for(Int_t aa=0; aa<4; aa++) for(Int_t bb=0; bb<3; bb++) coord[aa][bb]=0.;
1365
1366   for (Int_t jj=0; jj<4; jj++) padToSector.MasterToLocal(&cornerPad[jj][0], &coord[jj][0]);
1367
1368   delete cornerPad;
1369
1370   //sectorToPad.LocalToMaster(cornerPad, coord);
1371
1372 }
1373 //_____________________________________________________________________________
1374 Float_t AliTOFGeometry::GetPadDx(Float_t *pos)
1375 {
1376   //
1377   // Returns the x coordinate in the Pad reference frame
1378   //
1379
1380   Float_t xpad = -2.;
1381
1382   Float_t posLocal[3];
1383   for (Int_t ii=0; ii<3; ii++) posLocal[ii] = pos[ii];
1384  
1385   Int_t isector = GetSector(posLocal);
1386   if(isector == -1){
1387     //AliError("Detector Index could not be determined");
1388     return xpad;}
1389   Int_t iplate =  GetPlate(posLocal);
1390   if(iplate == -1){
1391     //AliError("Detector Index could not be determined");
1392     return xpad;} 
1393   Int_t istrip =  GetStrip(posLocal);
1394   if(istrip == -1){  
1395     //AliError("Detector Index could not be determined");
1396     return xpad;}
1397   Int_t ipadz =  GetPadZ(posLocal);
1398   if(ipadz == -1){  
1399     //AliError("Detector Index could not be determined");
1400     return xpad;}
1401   Int_t ipadx =  GetPadX(posLocal);
1402   if(ipadx == -1){
1403     //AliError("Detector Index could not be determined");
1404     return xpad;}
1405
1406   // ALICE reference frame -> B071/B074/B075 = BTO1/2/3 reference frame
1407   Double_t angles[6] = 
1408     {90., 90.+(isector+0.5)*fgkPhiSec,
1409       0.,  0.,
1410      90., (isector+0.5)*fgkPhiSec
1411     };
1412   Rotation(posLocal,angles);
1413
1414   Float_t step[3] = {0., 0., (fgkRmax+fgkRmin)*0.5};
1415   Translation(posLocal,step);
1416
1417   // B071/B074/B075 = BTO1/2/3 reference frame -> FTOA/B/C = FLTA/B/C reference frame
1418   angles[0] = 90.;
1419   angles[1] =  0.;
1420   angles[2] =  0.;
1421   angles[3] =  0.;
1422   angles[4] = 90.;
1423   angles[5] =270.;
1424
1425   Rotation(posLocal,angles);
1426
1427   // FTOA/B/C = FLTA/B/C reference frame -> FSTR reference frame
1428   step[0] = 0.;
1429   step[1] = GetHeights(iplate,istrip);
1430   step[2] = -GetDistances(iplate,istrip);
1431   Translation(posLocal,step);
1432
1433   if      (GetAngles(iplate,istrip) >0.) {
1434     angles[0] = 90.;
1435     angles[1] =  0.;
1436     angles[2] = 90.+GetAngles(iplate,istrip);
1437     angles[3] = 90.;
1438     angles[4] = GetAngles(iplate,istrip);
1439     angles[5] = 90.;
1440   }
1441   else if (GetAngles(iplate,istrip)==0.) {
1442     angles[0] = 90.;
1443     angles[1] =  0.;
1444     angles[2] = 90.;
1445     angles[3] = 90.;
1446     angles[4] =  0;
1447     angles[5] =  0.;
1448   }
1449   else if (GetAngles(iplate,istrip) <0.) {
1450     angles[0] = 90.;
1451     angles[1] =  0.;
1452     angles[2] = 90.+GetAngles(iplate,istrip);
1453     angles[3] = 90.;
1454     angles[4] =-GetAngles(iplate,istrip);
1455     angles[5] = 270.;
1456   }
1457   Rotation(posLocal,angles);
1458
1459   step[0] =-0.5*kNpadX*fgkXPad;
1460   step[1] = 0.;
1461   step[2] =-0.5*kNpadZ*fgkZPad;
1462   Translation(posLocal,step);
1463
1464   step[0] = (ipadx+0.5)*fgkXPad;
1465   step[1] = 0.;
1466   step[2] = (ipadz+0.5)*fgkZPad;
1467   Translation(posLocal,step);
1468   
1469   xpad=posLocal[0];
1470
1471   return xpad;
1472
1473 }
1474 //_____________________________________________________________________________
1475 Float_t AliTOFGeometry::GetPadDy(Float_t *pos)
1476 {
1477   //
1478   // Returns the y coordinate in the Pad reference frame
1479   //
1480
1481   Float_t ypad = -2.;
1482
1483   Float_t posLocal[3];
1484   for (Int_t ii=0; ii<3; ii++) posLocal[ii] = pos[ii];
1485  
1486   Int_t isector = GetSector(posLocal);
1487   if(isector == -1){
1488     //AliError("Detector Index could not be determined");
1489     return ypad;}
1490   Int_t iplate =  GetPlate(posLocal);
1491   if(iplate == -1){
1492     //AliError("Detector Index could not be determined");
1493     return ypad;} 
1494   Int_t istrip =  GetStrip(posLocal);
1495   if(istrip == -1){  
1496     //AliError("Detector Index could not be determined");
1497     return ypad;}
1498   Int_t ipadz =  GetPadZ(posLocal);
1499   if(ipadz == -1){  
1500     //AliError("Detector Index could not be determined");
1501     return ypad;}
1502   Int_t ipadx =  GetPadX(posLocal);
1503   if(ipadx == -1){
1504     //AliError("Detector Index could not be determined");
1505     return ypad;}
1506
1507   // ALICE reference frame -> B071/B074/B075 = BTO1/2/3 reference frame
1508   Double_t angles[6] = 
1509     {90., 90.+(isector+0.5)*fgkPhiSec,
1510       0.,  0.,
1511      90., (isector+0.5)*fgkPhiSec
1512     };
1513   Rotation(posLocal,angles);
1514
1515   Float_t step[3] = {0., 0., (fgkRmax+fgkRmin)*0.5};
1516   Translation(posLocal,step);
1517
1518   // B071/B074/B075 = BTO1/2/3 reference frame -> FTOA/B/C = FLTA/B/C reference frame
1519   angles[0] = 90.;
1520   angles[1] =  0.;
1521   angles[2] =  0.;
1522   angles[3] =  0.;
1523   angles[4] = 90.;
1524   angles[5] =270.;
1525
1526   Rotation(posLocal,angles);
1527
1528   // FTOA/B/C = FLTA/B/C reference frame -> FSTR reference frame
1529   step[0] = 0.;
1530   step[1] = GetHeights(iplate,istrip);
1531   step[2] = -GetDistances(iplate,istrip);
1532   Translation(posLocal,step);
1533
1534   if      (GetAngles(iplate,istrip) >0.) {
1535     angles[0] = 90.;
1536     angles[1] =  0.;
1537     angles[2] = 90.+GetAngles(iplate,istrip);
1538     angles[3] = 90.;
1539     angles[4] = GetAngles(iplate,istrip);
1540     angles[5] = 90.;
1541   }
1542   else if (GetAngles(iplate,istrip)==0.) {
1543     angles[0] = 90.;
1544     angles[1] =  0.;
1545     angles[2] = 90.;
1546     angles[3] = 90.;
1547     angles[4] =  0;
1548     angles[5] =  0.;
1549   }
1550   else if (GetAngles(iplate,istrip) <0.) {
1551     angles[0] = 90.;
1552     angles[1] =  0.;
1553     angles[2] = 90.+GetAngles(iplate,istrip);
1554     angles[3] = 90.;
1555     angles[4] =-GetAngles(iplate,istrip);
1556     angles[5] = 270.;
1557   }
1558   Rotation(posLocal,angles);
1559
1560   step[0] =-0.5*kNpadX*fgkXPad;
1561   step[1] = 0.;
1562   step[2] =-0.5*kNpadZ*fgkZPad;
1563   Translation(posLocal,step);
1564   
1565   step[0] = (ipadx+0.5)*fgkXPad;
1566   step[1] = 0.;
1567   step[2] = (ipadz+0.5)*fgkZPad;
1568   Translation(posLocal,step);
1569   
1570   ypad=posLocal[1];
1571   
1572   return ypad;
1573
1574 }
1575 //_____________________________________________________________________________
1576 Float_t AliTOFGeometry::GetPadDz(Float_t *pos)
1577 {
1578   //
1579   // Returns the z coordinate in the Pad reference frame
1580   //
1581
1582   Float_t zpad = -2.;
1583
1584   Float_t posLocal[3];
1585   for (Int_t ii=0; ii<3; ii++) posLocal[ii] = pos[ii];
1586  
1587   Int_t isector = GetSector(posLocal);
1588   if(isector == -1){
1589     //AliError("Detector Index could not be determined");
1590     return zpad;}
1591   Int_t iplate =  GetPlate(posLocal);
1592   if(iplate == -1){
1593     //AliError("Detector Index could not be determined");
1594     return zpad;} 
1595   Int_t istrip =  GetStrip(posLocal);
1596   if(istrip == -1){  
1597     //AliError("Detector Index could not be determined");
1598     return zpad;}
1599   Int_t ipadz =  GetPadZ(posLocal);
1600   if(ipadz == -1){  
1601     //AliError("Detector Index could not be determined");
1602     return zpad;}
1603   Int_t ipadx =  GetPadX(posLocal);
1604   if(ipadx == -1){
1605     //AliError("Detector Index could not be determined");
1606     return zpad;}
1607
1608   // ALICE reference frame -> B071/B074/B075 = BTO1/2/3 reference frame
1609   Double_t angles[6] = 
1610     {90., 90.+(isector+0.5)*fgkPhiSec,
1611       0.,  0.,
1612      90., (isector+0.5)*fgkPhiSec
1613     };
1614   Rotation(posLocal,angles);
1615
1616   Float_t step[3] = {0., 0., (fgkRmax+fgkRmin)*0.5};
1617   Translation(posLocal,step);
1618
1619   // B071/B074/B075 = BTO1/2/3 reference frame -> FTOA/B/C = FLTA/B/C reference frame
1620   angles[0] = 90.;
1621   angles[1] =  0.;
1622   angles[2] =  0.;
1623   angles[3] =  0.;
1624   angles[4] = 90.;
1625   angles[5] =270.;
1626
1627   Rotation(posLocal,angles);
1628
1629   // FTOA/B/C = FLTA/B/C reference frame -> FSTR reference frame
1630   step[0] = 0.;
1631   step[1] = GetHeights(iplate,istrip);
1632   step[2] = -GetDistances(iplate,istrip);
1633   Translation(posLocal,step);
1634
1635   if      (GetAngles(iplate,istrip) >0.) {
1636     angles[0] = 90.;
1637     angles[1] =  0.;
1638     angles[2] = 90.+GetAngles(iplate,istrip);
1639     angles[3] = 90.;
1640     angles[4] = GetAngles(iplate,istrip);
1641     angles[5] = 90.;
1642   }
1643   else if (GetAngles(iplate,istrip)==0.) {
1644     angles[0] = 90.;
1645     angles[1] =  0.;
1646     angles[2] = 90.;
1647     angles[3] = 90.;
1648     angles[4] =  0;
1649     angles[5] =  0.;
1650   }
1651   else if (GetAngles(iplate,istrip) <0.) {
1652     angles[0] = 90.;
1653     angles[1] =  0.;
1654     angles[2] = 90.+GetAngles(iplate,istrip);
1655     angles[3] = 90.;
1656     angles[4] =-GetAngles(iplate,istrip);
1657     angles[5] = 270.;
1658   }
1659   Rotation(posLocal,angles);
1660
1661   step[0] =-0.5*kNpadX*fgkXPad;
1662   step[1] = 0.;
1663   step[2] =-0.5*kNpadZ*fgkZPad;
1664   Translation(posLocal,step);
1665   
1666   step[0] = (ipadx+0.5)*fgkXPad;
1667   step[1] = 0.;
1668   step[2] = (ipadz+0.5)*fgkZPad;
1669   Translation(posLocal,step);
1670
1671   zpad=posLocal[2];
1672
1673   return zpad;
1674
1675 }
1676 //_____________________________________________________________________________
1677
1678 void AliTOFGeometry::Translation(Float_t *xyz, Float_t translationVector[3]) const
1679 {
1680   //
1681   // Return the vector xyz translated by translationVector vector
1682   //
1683
1684   Int_t ii=0;
1685
1686   for (ii=0; ii<3; ii++)
1687     xyz[ii] -= translationVector[ii];
1688
1689   return;
1690
1691 }
1692 //_____________________________________________________________________________
1693
1694 void AliTOFGeometry::Rotation(Float_t *xyz, Double_t rotationAngles[6]) const
1695 {
1696   //
1697   // Return the vector xyz rotated according to the rotationAngles angles
1698   //
1699
1700   Int_t ii=0;
1701   /*
1702   TRotMatrix *matrix = new TRotMatrix("matrix","matrix", angles[0], angles[1],
1703                                       angles[2], angles[3],
1704                                       angles[4], angles[5]);
1705   */
1706
1707   for (ii=0; ii<6; ii++) rotationAngles[ii]*=kDegrad;
1708
1709   Float_t xyzDummy[3] = {0., 0., 0.};
1710
1711   for (ii=0; ii<3; ii++) {
1712     xyzDummy[ii] =
1713       xyz[0]*TMath::Sin(rotationAngles[2*ii])*TMath::Cos(rotationAngles[2*ii+1]) +
1714       xyz[1]*TMath::Sin(rotationAngles[2*ii])*TMath::Sin(rotationAngles[2*ii+1]) +
1715       xyz[2]*TMath::Cos(rotationAngles[2*ii]);
1716   }
1717
1718   for (ii=0; ii<3; ii++) xyz[ii]=xyzDummy[ii];
1719
1720   return;
1721
1722 }
1723 //_____________________________________________________________________________
1724 void AliTOFGeometry::InverseRotation(Float_t *xyz, Double_t rotationAngles[6]) const
1725 {
1726   //
1727   //
1728   //
1729
1730   Int_t ii=0;
1731
1732   for (ii=0; ii<6; ii++) rotationAngles[ii]*=kDegrad;
1733
1734   Float_t xyzDummy[3] = {0., 0., 0.};
1735
1736   xyzDummy[0] =
1737     xyz[0]*TMath::Sin(rotationAngles[0])*TMath::Cos(rotationAngles[1]) +
1738     xyz[1]*TMath::Sin(rotationAngles[2])*TMath::Cos(rotationAngles[3]) +
1739     xyz[2]*TMath::Sin(rotationAngles[4])*TMath::Cos(rotationAngles[5]);
1740   
1741   xyzDummy[1] =
1742     xyz[0]*TMath::Sin(rotationAngles[0])*TMath::Sin(rotationAngles[1]) +
1743     xyz[1]*TMath::Sin(rotationAngles[2])*TMath::Sin(rotationAngles[3]) +
1744     xyz[2]*TMath::Sin(rotationAngles[4])*TMath::Sin(rotationAngles[5]);
1745   
1746   xyzDummy[2] =
1747     xyz[0]*TMath::Cos(rotationAngles[0]) +
1748     xyz[1]*TMath::Cos(rotationAngles[2]) +
1749     xyz[2]*TMath::Cos(rotationAngles[4]);
1750   
1751   for (ii=0; ii<3; ii++) xyz[ii]=xyzDummy[ii];
1752
1753   return;
1754
1755 }
1756 //_____________________________________________________________________________
1757
1758 Int_t AliTOFGeometry::GetIndex(Int_t *detId)
1759 {
1760   //Retrieve calibration channel index 
1761   Int_t isector = detId[0];
1762   if (isector >= kNSectors){
1763     printf("Wrong sector number in TOF (%d) !\n",isector);
1764     return -1;
1765   }
1766   Int_t iplate = detId[1];
1767   if (iplate >= kNPlates){
1768     printf("Wrong plate number in TOF (%d) !\n",iplate);
1769     return -1;
1770   }
1771   Int_t istrip = detId[2];
1772   Int_t stripOffset = GetStripNumberPerSM(iplate,istrip);
1773   if (stripOffset==-1) {
1774     printf("Wrong strip number per SM in TOF (%d) !\n",stripOffset);
1775     return -1;
1776   }
1777
1778   Int_t ipadz = detId[3];
1779   Int_t ipadx = detId[4];
1780
1781   Int_t idet = ((2*(kNStripC+kNStripB)+kNStripA)*kNpadZ*kNpadX)*isector +
1782                (stripOffset*kNpadZ*kNpadX)+
1783                (kNpadX)*ipadz+
1784                 ipadx;
1785   return idet;
1786 }
1787 //_____________________________________________________________________________
1788
1789 void AliTOFGeometry::GetVolumeIndices(Int_t index, Int_t *detId)
1790 {
1791   //
1792   // Retrieve volume indices from the calibration channel index 
1793   //
1794
1795   detId[0] = index/NpadXStrip()/NStripXSector();
1796
1797   Int_t dummyStripPerModule = 
1798     ( index - ( NStripXSector()*NpadXStrip()*detId[0]) ) / NpadXStrip();
1799   if (dummyStripPerModule<kNStripC) {
1800     detId[1] = 0;
1801     detId[2] = dummyStripPerModule;
1802   }
1803   else if (dummyStripPerModule>=kNStripC && dummyStripPerModule<kNStripC+kNStripB) {
1804     detId[1] = 1;
1805     detId[2] = dummyStripPerModule-kNStripC;
1806   }
1807   else if (dummyStripPerModule>=kNStripC+kNStripB && dummyStripPerModule<kNStripC+kNStripB+kNStripA) {
1808     detId[1] = 2;
1809     detId[2] = dummyStripPerModule-kNStripC-kNStripB;
1810   }
1811   else if (dummyStripPerModule>=kNStripC+kNStripB+kNStripA && dummyStripPerModule<kNStripC+kNStripB+kNStripA+kNStripB) {
1812     detId[1] = 3;
1813     detId[2] = dummyStripPerModule-kNStripC-kNStripB-kNStripA;
1814   }
1815   else if (dummyStripPerModule>=kNStripC+kNStripB+kNStripA+kNStripB && dummyStripPerModule<NStripXSector()) {
1816     detId[1] = 4;
1817     detId[2] = dummyStripPerModule-kNStripC-kNStripB-kNStripA-kNStripB;
1818   }
1819
1820   Int_t padPerStrip = ( index - ( NStripXSector()*NpadXStrip()*detId[0]) ) - dummyStripPerModule*NpadXStrip();
1821
1822   detId[3] = padPerStrip / kNpadX; // padZ
1823   detId[4] = padPerStrip - detId[3]*kNpadX; // padX
1824
1825 }
1826 //_____________________________________________________________________________
1827
1828 Int_t AliTOFGeometry::NStrip(Int_t nPlate)
1829 {
1830   //
1831   // Returns the strips number for the plate number 'nPlate'
1832   //
1833
1834   Int_t nStrips = kNStripC;
1835
1836   switch(nPlate) {
1837   case 2:
1838     nStrips = kNStripA;
1839     break;
1840   case 1:
1841   case 3:
1842     nStrips = kNStripB;
1843     break;
1844   case 0:
1845   case 4:
1846   default:
1847     nStrips = kNStripC;
1848     break;
1849   }
1850
1851   return nStrips;
1852
1853 }
1854 //-------------------------------------------------------------------------
1855
1856 UShort_t AliTOFGeometry::GetAliSensVolIndex(Int_t isector, Int_t iplate, Int_t istrip) const
1857 {
1858   //
1859   // Get the index of the TOF alignable volume in the AliGeomManager order.
1860   //
1861
1862   Int_t index = GetStripNumber(isector, iplate, istrip);
1863
1864   UShort_t volIndex = AliGeomManager::LayerToVolUID(AliGeomManager::kTOF,index);
1865
1866   return volIndex;
1867
1868 }
1869 //-------------------------------------------------------------------------
1870
1871 Int_t AliTOFGeometry::GetStripNumber(Int_t isector, Int_t iplate, Int_t istrip)
1872 {
1873   //
1874   // Get the serial number of the TOF strip number istrip [0,14/18],
1875   //   in the module number iplate [0,4],
1876   //   in the TOF SM number isector [0,17].
1877   // This number will range in [0,1637].
1878   //
1879
1880   Bool_t check = (isector >= kNSectors);
1881
1882   if (check)
1883     printf("E-AliTOFGeometry::GetStripNumber: Wrong sector number in TOF (%d)!\n",isector);
1884
1885   Int_t index = -1;
1886   Int_t stripInSM = GetStripNumberPerSM(iplate, istrip);
1887   if (!check && stripInSM!=-1)
1888     index = (2*(kNStripC+kNStripB)+kNStripA)*isector + stripInSM;
1889
1890   return index;
1891
1892 }
1893 //-------------------------------------------------------------------------
1894
1895 Int_t AliTOFGeometry::GetStripNumberPerSM(Int_t iplate, Int_t istrip)
1896 {
1897   //
1898   // Get the serial number of the TOF strip number istrip [0,14/18],
1899   //   in the module number iplate [0,4].
1900   // This number will range in [0,90].
1901   //
1902
1903   Int_t index = -1;
1904
1905   Bool_t check = (
1906                   (iplate<0 || iplate>=kNPlates)
1907                   ||
1908                   (
1909                    (iplate==2 && (istrip<0 || istrip>=kNStripA))
1910                    ||
1911                    (iplate!=2 && (istrip<0 || istrip>=kNStripC))
1912                    )
1913                   );
1914
1915   if (iplate<0 || iplate>=kNPlates)
1916     printf("E-AliTOFGeometry::GetStripNumberPerSM: Wrong plate number in TOF (%1d)!\n",iplate);
1917
1918   if (
1919       (iplate==2 && (istrip<0 || istrip>=kNStripA))
1920       ||
1921       (iplate!=2 && (istrip<0 || istrip>=kNStripC))
1922       )
1923     printf("E-AliTOFGeometry::GetStripNumberPerSM: Wrong strip number in TOF (strip=%2d in the plate=%1d)!\n",istrip,iplate);
1924
1925   Int_t stripOffset = 0;
1926   switch (iplate) {
1927   case 0:
1928     stripOffset = 0;
1929     break;
1930   case 1:
1931     stripOffset = kNStripC;
1932     break;
1933   case 2:
1934     stripOffset = kNStripC+kNStripB;
1935     break;
1936   case 3:
1937     stripOffset = kNStripC+kNStripB+kNStripA;
1938     break;
1939   case 4:
1940     stripOffset = kNStripC+kNStripB+kNStripA+kNStripB;
1941     break;
1942   };
1943
1944   if (!check) index = stripOffset + istrip;
1945
1946   return index;
1947
1948 }