Added some methods in AliTOFGeometry class, updated the AliTOFGeometry::IsInsideThePa...
[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 inside
419 // pad identified by the matrix mat. In case when dist3d!=0, the
420 // dist3d vector has been filled with the 3d distance between the
421 // impact point on the pad and the pad centre (in the reference frame
422 // of the TOF pad identified by the matrix mat.).
423 //
424
425   const Float_t kPadDepth = 0.5;      // heigth of Sensitive Layer
426
427   Double_t posg[3];
428   posg[0] = pos[0];
429   posg[1] = pos[1];
430   posg[2] = pos[2];
431   Double_t posl[3] = {0., 0., 0.};
432
433   // from ALICE global reference system
434   // towards TOF pad local reference system
435   mat.MasterToLocal(posg,posl);
436
437   Float_t xr = posl[0];
438   Float_t yr = posl[1];
439   Float_t zr = posl[2];
440
441   Bool_t isInside=false; 
442   if (TMath::Abs(yr)<= kPadDepth*0.5 &&
443       TMath::Abs(xr)<= (fgkXPad*0.5) &&
444       TMath::Abs(zr)<= (fgkZPad*0.5))
445     isInside = true; 
446
447   if (dist3d) {
448     //Double_t padl[3] = {0., 0., 0.};
449     dist3d[0] = posl[0]/* - padl[0]*/;
450     dist3d[1] = posl[1]/* - padl[1]*/;
451     dist3d[2] = posl[2]/* - padl[2]*/;
452
453     /*
454     Double_t padg[3] = {0., 0., 0.};
455     // from TOF pad local reference system
456     // towards ALICE global reference system
457     TGeoHMatrix inverse = mat.Inverse();
458     inverse.MasterToLocal(padl,padg);
459
460     // returns the 3d distance
461     // between the impact point on the pad
462     // and the pad centre (in the ALICE global reference frame)
463     dist3d[0] = posg[0] - padg[0];
464     dist3d[1] = posg[1] - padg[1];
465     dist3d[2] = posg[2] - padg[2];
466     */
467   }
468  
469   return isInside;
470
471 }
472 //_____________________________________________________________________________
473 void AliTOFGeometry::GetVolumePath(Int_t *ind, Char_t *path ) {
474   //--------------------------------------------------------------------
475   // This function returns the colume path of a given pad 
476   //--------------------------------------------------------------------
477   Int_t sector = ind[0];
478   Char_t  string1[100];
479   Char_t  string2[100];
480   Char_t  string3[100];
481   
482   Int_t icopy=-1;
483   icopy=sector;
484  
485   sprintf(string1,"/ALIC_1/B077_1/BSEGMO%i_1/BTOF%i_1",icopy,icopy);
486   
487   Int_t iplate=ind[1];
488   Int_t istrip=ind[2];
489   if( iplate==0) icopy=istrip; 
490   if( iplate==1) icopy=istrip+NStripC(); 
491   if( iplate==2) icopy=istrip+NStripC()+NStripB(); 
492   if( iplate==3) icopy=istrip+NStripC()+NStripB()+NStripA(); 
493   if( iplate==4) icopy=istrip+NStripC()+2*NStripB()+NStripA(); 
494   icopy++;
495   sprintf(string2,"FTOA_0/FLTA_0/FSTR_%i",icopy);
496   if(fHoles && (sector==13 || sector==14 || sector==15)){
497     if(iplate<2)  sprintf(string2,"FTOB_0/FLTB_0/FSTR_%i",icopy);
498     if(iplate>2)  sprintf(string2,"FTOC_0/FLTC_0/FSTR_%i",icopy);
499   }
500  
501   Int_t padz = ind[3]+1; 
502   Int_t padx = ind[4]+1;
503   sprintf(string3,"FPCB_1/FSEN_1/FSEZ_%i/FPAD_%i",padz,padx);
504   sprintf(path,"%s/%s/%s",string1,string2,string3); 
505
506 }
507 //_____________________________________________________________________________
508 void AliTOFGeometry::GetVolumePath(Int_t sector, Char_t *path ){
509   //--------------------------------------------------------------------
510   // This function returns the colume path of a given sector 
511   //--------------------------------------------------------------------
512
513   Char_t string[100];
514
515   Int_t icopy = sector;
516
517   sprintf(string,"/ALIC_1/B077_1/BSEGMO%i_1/BTOF%i_1",icopy,icopy);
518   sprintf(path,"%s",string);
519
520 }
521 //_____________________________________________________________________________
522 void AliTOFGeometry::GetVolumePath(Int_t sector, Int_t plate, Int_t strip, Char_t *path ) {
523   //--------------------------------------------------------------------
524   // This function returns the colume path of a given strip 
525   //--------------------------------------------------------------------
526
527   Char_t string1[100];
528   Char_t string2[100];
529   Char_t string3[100];
530   
531   Int_t icopy = sector;
532
533   sprintf(string1,"/ALIC_1/B077_1/BSEGMO%i_1/BTOF%i_1",icopy,icopy);
534   
535   if(plate==0) icopy=strip; 
536   if(plate==1) icopy=strip+NStripC(); 
537   if(plate==2) icopy=strip+NStripC()+NStripB(); 
538   if(plate==3) icopy=strip+NStripC()+NStripB()+NStripA(); 
539   if(plate==4) icopy=strip+NStripC()+2*NStripB()+NStripA(); 
540   icopy++;
541   sprintf(string2,"FTOA_0/FLTA_0/FSTR_%i",icopy);
542   if(fHoles && (sector==13 || sector==14 || sector==15)){
543     if(plate<2)  sprintf(string2,"FTOB_0/FLTB_0/FSTR_%i",icopy);
544     if(plate>2)  sprintf(string2,"FTOC_0/FLTC_0/FSTR_%i",icopy);
545   }
546
547   sprintf(string3,"FPCB_1/FSEN_1");
548   sprintf(path,"%s/%s/%s",string1,string2,string3); 
549
550 }
551 //_____________________________________________________________________________
552 void AliTOFGeometry::GetPos(Int_t *det, Float_t *pos) 
553 {
554 //
555 // Returns space point coor (x,y,z) (cm)  for Detector 
556 // Indices  (iSect,iPlate,iStrip,iPadX,iPadZ) 
557 //
558   Char_t path[100];
559   GetVolumePath(det,path );
560   if (!gGeoManager) {
561     printf("ERROR: no TGeo\n");
562   }
563   gGeoManager->cd(path);
564   TGeoHMatrix global;
565   global = *gGeoManager->GetCurrentMatrix();
566   const Double_t *tr = global.GetTranslation();
567
568   pos[0]=tr[0];  
569   pos[1]=tr[1];  
570   pos[2]=tr[2];
571 }
572 //_____________________________________________________________________________
573 Int_t AliTOFGeometry::GetPlate(Float_t *pos) const
574 {
575   //
576   // Returns the Plate index 
577   //
578   const Float_t kInterCentrModBorder1 = 49.5;
579   const Float_t kInterCentrModBorder2 = 57.5;
580   const Float_t kExterInterModBorder1 = 196.0;
581   const Float_t kExterInterModBorder2 = 203.5;
582
583   const Float_t kLengthExInModBorder  = 4.7;
584   const Float_t kLengthInCeModBorder  = 7.0;
585
586   //const Float_t khAlWall = 0.1;
587   const Float_t kModuleWallThickness = 0.3;
588   //const Float_t kHoneycombLayerThickness = 1.5;
589
590   Int_t iPlate=-1;
591
592   Float_t posLocal[3];
593   for (Int_t ii=0; ii<3; ii++) posLocal[ii] = pos[ii];
594
595   Int_t isector = GetSector(posLocal);
596   if(isector == -1){
597     //AliError("Detector Index could not be determined");
598     return iPlate;
599   }
600
601   // ALICE reference frame -> B071/B074/B075 = BTO1/2/3 reference frame
602   Double_t angles[6] = 
603     {90., 90.+(isector+0.5)*fgkPhiSec,
604       0., 0.,
605      90., (isector+0.5)*fgkPhiSec
606     };
607   Rotation(posLocal,angles);
608
609   Float_t step[3] = {0., 0., (fgkRmax+fgkRmin)*0.5};
610   Translation(posLocal,step);
611
612   // B071/B074/B075 = BTO1/2/3 reference frame -> FTOA = FLTA reference frame
613   angles[0] = 90.;
614   angles[1] =  0.;
615   angles[2] =  0.;
616   angles[3] =  0.;
617   angles[4] = 90.;
618   angles[5] =270.;
619
620   Rotation(posLocal,angles);
621
622   Float_t yLocal = posLocal[1];
623   Float_t zLocal = posLocal[2];
624
625   Float_t deltaRhoLoc  = (fgkRmax-fgkRmin)*0.5 - kModuleWallThickness + yLocal;
626   Float_t deltaZetaLoc = TMath::Abs(zLocal);
627
628   Float_t deltaRHOmax = 0.;
629
630   if (TMath::Abs(zLocal)>=kExterInterModBorder1 && TMath::Abs(zLocal)<=kExterInterModBorder2) 
631     {
632       deltaRhoLoc -= kLengthExInModBorder;
633       deltaZetaLoc = kExterInterModBorder2-deltaZetaLoc;
634       deltaRHOmax  = (fgkRmax - fgkRmin)*0.5 - kModuleWallThickness - 2.*kLengthExInModBorder; // old 5.35, new 4.8
635
636       if (deltaRhoLoc > deltaZetaLoc*deltaRHOmax/(kInterCentrModBorder2-kInterCentrModBorder1)) {
637         if (zLocal<0) iPlate = 0;
638         else iPlate = 4;
639       }
640       else {
641         if (zLocal<0) iPlate = 1;
642         else iPlate = 3;
643       }
644     }
645   else if (TMath::Abs(zLocal)>=kInterCentrModBorder1 && TMath::Abs(zLocal)<=kInterCentrModBorder2) 
646     {
647       deltaRhoLoc -= kLengthInCeModBorder;
648       deltaZetaLoc = deltaZetaLoc-kInterCentrModBorder1;
649       deltaRHOmax = (fgkRmax - fgkRmin)*0.5 - kModuleWallThickness - 2.*kLengthInCeModBorder; // old 0.39, new 0.2
650
651       if (deltaRhoLoc>deltaZetaLoc*deltaRHOmax/(kInterCentrModBorder2-kInterCentrModBorder1)) iPlate = 2;
652       else {
653         if (zLocal<0) iPlate = 1;
654         else iPlate = 3;
655       }
656     }
657
658   if      (zLocal>-fgkZlenA*0.5          && zLocal<-kExterInterModBorder2) iPlate = 0;
659   else if (zLocal>-kExterInterModBorder1 && zLocal<-kInterCentrModBorder2) iPlate = 1;
660   else if (zLocal>-kInterCentrModBorder1 && zLocal< kInterCentrModBorder1) iPlate = 2;
661   else if (zLocal> kInterCentrModBorder2 && zLocal< kExterInterModBorder1) iPlate = 3;
662   else if (zLocal> kExterInterModBorder2 && zLocal< fgkZlenA*0.5)          iPlate = 4;
663   
664   return iPlate;
665
666 }
667
668 //_____________________________________________________________________________
669 Int_t AliTOFGeometry::GetSector(Float_t *pos) const
670 {
671   //
672   // Returns the Sector index 
673   //
674
675   Int_t   iSect = -1; 
676
677   Float_t x = pos[0];
678   Float_t y = pos[1];
679   Float_t z = pos[2];
680
681   Float_t rho = TMath::Sqrt(x*x + y*y);
682
683   if (!((z>=-fgkZlenA*0.5 && z<=fgkZlenA*0.5) &&
684         (rho>=(fgkRmin) && rho<=(fgkRmax)))) {
685     //AliError("Detector Index could not be determined");
686     return iSect;
687   }
688
689   Float_t phi = TMath::Pi() + TMath::ATan2(-y,-x);      
690
691   iSect  = (Int_t) (phi*kRaddeg/fgkPhiSec);
692   
693   return iSect;
694
695 }
696 //_____________________________________________________________________________
697 Int_t AliTOFGeometry::GetStrip(Float_t *pos) const
698 {
699   //
700   // Returns the Strip index 
701   //
702   const Float_t khhony    = 1.0          ; // heigth of HONY  Layer
703   const Float_t khpcby    = 0.08         ; // heigth of PCB   Layer
704   const Float_t khrgly    = 0.055        ; // heigth of RED GLASS  Layer
705   const Float_t khglfy    = 0.285        ; // heigth of GLASS+FISHLINE  Layer
706   const Float_t khcpcby   = 0.16         ; // heigth of PCB  Central Layer
707   const Float_t kwcpcbz   = 12.4         ; // z dimension of PCB  Central Layer
708   const Float_t khstripy = 2.*khhony+2.*khpcby+4.*khrgly+2.*khglfy+khcpcby;//3.11
709   const Float_t kwstripz = kwcpcbz;
710   const Float_t klstripx = fgkStripLength;
711   
712   Int_t iStrip=-1;
713    
714   Float_t posLocal[3];
715   for (Int_t ii=0; ii<3; ii++) posLocal[ii] = pos[ii];
716  
717   Int_t isector = GetSector(posLocal);
718   if(isector == -1){
719     //AliError("Detector Index could not be determined");
720     return iStrip;}
721   Int_t iplate =  GetPlate(posLocal);
722   if(iplate == -1){
723     //AliError("Detector Index could not be determined");
724     return iStrip;} 
725
726   Int_t nstrips=0;
727   switch (iplate) {
728   case 0:
729     nstrips=kNStripC;
730     break;
731   case 4:
732     nstrips=kNStripC;
733     break;
734   case 1:
735     nstrips=kNStripB;
736     break;
737   case 3:
738     nstrips=kNStripB;
739     break;
740   case 2:
741     nstrips=kNStripA;
742     break;
743   }
744   
745   // ALICE reference frame -> B071/B074/B075 = BTO1/2/3 reference frame
746   Double_t angles[6] = 
747     {90., 90.+(isector+0.5)*fgkPhiSec,
748       0., 0.,
749      90., (isector+0.5)*fgkPhiSec
750     };
751   Rotation(posLocal,angles);
752
753   Float_t step[3] = {0., 0., (fgkRmax+fgkRmin)*0.5};
754   Translation(posLocal,step);
755
756   // B071/B074/B075 = BTO1/2/3 reference frame -> FTOA = FLTA reference frame
757   angles[0] = 90.;
758   angles[1] =  0.;
759   angles[2] =  0.;
760   angles[3] =  0.;
761   angles[4] = 90.;
762   angles[5] =270.;
763
764   Rotation(posLocal,angles);
765
766   // FTOA/B/C = FLTA/B/C reference frame -> FSTR reference frame
767   Int_t totStrip=0;
768   for (Int_t istrip=0; istrip<nstrips; istrip++){
769
770     Float_t posLoc2[3]={posLocal[0],posLocal[1],posLocal[2]};         
771
772     step[0] = 0.;
773     step[1] = GetHeights(iplate,istrip);
774     step[2] = -GetDistances(iplate,istrip);
775     Translation(posLoc2,step);
776
777     if      (GetAngles(iplate,istrip) >0.) {
778       angles[0] = 90.;
779       angles[1] =  0.;
780       angles[2] = 90.+GetAngles(iplate,istrip);
781       angles[3] = 90.;
782       angles[4] = GetAngles(iplate,istrip);
783       angles[5] = 90.;
784     }
785     else if (GetAngles(iplate,istrip)==0.) {
786       angles[0] = 90.;
787       angles[1] =  0.;
788       angles[2] = 90.;
789       angles[3] = 90.;
790       angles[4] =  0;
791       angles[5] =  0.;
792     }
793     else if (GetAngles(iplate,istrip) <0.) {
794       angles[0] = 90.;
795       angles[1] =  0.;
796       angles[2] = 90.+GetAngles(iplate,istrip);
797       angles[3] = 90.;
798       angles[4] =-GetAngles(iplate,istrip);
799       angles[5] = 270.;
800     }
801     Rotation(posLoc2,angles);
802
803     if ((TMath::Abs(posLoc2[0])<=klstripx*0.5) &&
804         (TMath::Abs(posLoc2[1])<=khstripy*0.5) &&
805         (TMath::Abs(posLoc2[2])<=kwstripz*0.5)) {
806       iStrip = istrip;
807       totStrip++;
808       for (Int_t jj=0; jj<3; jj++) posLocal[jj]=posLoc2[jj];
809       //AliInfo(Form(" posLocal[0] = %f, posLocal[1] = %f, posLocal[2] = %f ", posLocal[0],posLocal[1],posLocal[2]));
810
811       //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]));
812       break;
813     }
814
815     if (totStrip>1) AliInfo(Form("total strip number found %2i",totStrip));
816
817   }
818
819   return iStrip;
820   
821 }
822 //_____________________________________________________________________________
823 Int_t AliTOFGeometry::GetPadZ(Float_t *pos) const
824 {
825   //
826   // Returns the Pad index along Z 
827   //
828   //const Float_t klsensmx = kNpadX*fgkXPad;  // length of Sensitive Layer
829   //const Float_t khsensmy = 0.05;//0.11;//0.16;// heigth of Sensitive Layer
830   //const Float_t kwsensmz = kNpadZ*fgkZPad;  // width of Sensitive Layer
831
832   Int_t iPadZ = -1;
833
834   Float_t posLocal[3];
835   for (Int_t ii=0; ii<3; ii++) posLocal[ii] = pos[ii];
836  
837   Int_t isector = GetSector(posLocal);
838   if(isector == -1){
839     //AliError("Detector Index could not be determined");
840     return iPadZ;}
841   Int_t iplate =  GetPlate(posLocal);
842   if(iplate == -1){
843     //AliError("Detector Index could not be determined");
844     return iPadZ;}
845   Int_t istrip =  GetStrip(posLocal);
846   if(istrip == -1){
847     //AliError("Detector Index could not be determined");
848     return iPadZ;}
849
850   // ALICE reference frame -> B071/B074/B075 = BTO1/2/3 reference frame
851   Double_t angles[6] = 
852     {90., 90.+(isector+0.5)*fgkPhiSec,
853       0., 0.,
854      90., (isector+0.5)*fgkPhiSec
855     };
856   Rotation(posLocal,angles);
857
858   Float_t step[3] = {0., 0., (fgkRmax+fgkRmin)*0.5};
859   Translation(posLocal,step);
860
861   // B071/B074/B075 = BTO1/2/3 reference frame -> FTOA = FLTA reference frame
862   angles[0] = 90.;
863   angles[1] =  0.;
864   angles[2] =  0.;
865   angles[3] =  0.;
866   angles[4] = 90.;
867   angles[5] =270.;
868
869   Rotation(posLocal,angles);
870
871   // FTOA/B/C = FLTA/B/C reference frame -> FSTR reference frame
872   step[0] = 0.;
873   step[1] = GetHeights(iplate,istrip);
874   step[2] = -GetDistances(iplate,istrip);
875   Translation(posLocal,step);
876
877   if      (GetAngles(iplate,istrip) >0.) {
878     angles[0] = 90.;
879     angles[1] =  0.;
880     angles[2] = 90.+GetAngles(iplate,istrip);
881     angles[3] = 90.;
882     angles[4] = GetAngles(iplate,istrip);
883     angles[5] = 90.;
884   }
885   else if (GetAngles(iplate,istrip)==0.) {
886     angles[0] = 90.;
887     angles[1] =  0.;
888     angles[2] = 90.;
889     angles[3] = 90.;
890     angles[4] =  0;
891     angles[5] =  0.;
892   }
893   else if (GetAngles(iplate,istrip) <0.) {
894     angles[0] = 90.;
895     angles[1] =  0.;
896     angles[2] = 90.+GetAngles(iplate,istrip);
897     angles[3] = 90.;
898     angles[4] =-GetAngles(iplate,istrip);
899     angles[5] = 270.;
900   }
901   Rotation(posLocal,angles);
902
903   step[0] =-0.5*kNpadX*fgkXPad;
904   step[1] = 0.;
905   step[2] =-0.5*kNpadZ*fgkZPad;
906   Translation(posLocal,step);
907
908   iPadZ = (Int_t)(posLocal[2]/fgkZPad);
909   if (iPadZ==kNpadZ) iPadZ--;
910   else if (iPadZ>kNpadZ) iPadZ=-1;
911
912   return iPadZ;
913
914 }
915 //_____________________________________________________________________________
916 Int_t AliTOFGeometry::GetPadX(Float_t *pos) const
917 {
918   //
919   // Returns the Pad index along X 
920   //
921   //const Float_t klsensmx = kNpadX*fgkXPad;  // length of Sensitive Layer
922   //const Float_t khsensmy = 0.05;//0.11;//0.16;// heigth of Sensitive Layer
923   //const Float_t kwsensmz = kNpadZ*fgkZPad;  // width of Sensitive Layer
924
925   Int_t iPadX  = -1;
926
927   Float_t posLocal[3];
928   for (Int_t ii=0; ii<3; ii++) posLocal[ii] = pos[ii];
929  
930   Int_t isector = GetSector(posLocal);
931   if(isector == -1){
932     //AliError("Detector Index could not be determined");
933     return iPadX;}
934   Int_t iplate =  GetPlate(posLocal);
935   if(iplate == -1){
936     //AliError("Detector Index could not be determined");
937     return iPadX;} 
938   Int_t istrip =  GetStrip(posLocal);
939   if(istrip == -1){  
940     //AliError("Detector Index could not be determined");
941     return iPadX;}
942
943   // ALICE reference frame -> B071/B074/B075 = BTO1/2/3 reference frame
944   Double_t angles[6] = 
945     {90., 90.+(isector+0.5)*fgkPhiSec,
946       0.,  0.,
947      90., (isector+0.5)*fgkPhiSec
948     };
949   Rotation(posLocal,angles);
950
951   Float_t step[3] = {0., 0., (fgkRmax+fgkRmin)*0.5};
952   Translation(posLocal,step);
953
954   // B071/B074/B075 = BTO1/2/3 reference frame -> FTOA/B/C = FLTA/B/C reference frame
955   angles[0] = 90.;
956   angles[1] =  0.;
957   angles[2] =  0.;
958   angles[3] =  0.;
959   angles[4] = 90.;
960   angles[5] =270.;
961
962   Rotation(posLocal,angles);
963
964   // FTOA/B/C = FLTA/B/C reference frame -> FSTR reference frame
965   step[0] = 0.;
966   step[1] = GetHeights(iplate,istrip);
967   step[2] = -GetDistances(iplate,istrip);
968   Translation(posLocal,step);
969
970   if      (GetAngles(iplate,istrip) >0.) {
971     angles[0] = 90.;
972     angles[1] =  0.;
973     angles[2] = 90.+GetAngles(iplate,istrip);
974     angles[3] = 90.;
975     angles[4] = GetAngles(iplate,istrip);
976     angles[5] = 90.;
977   }
978   else if (GetAngles(iplate,istrip)==0.) {
979     angles[0] = 90.;
980     angles[1] =  0.;
981     angles[2] = 90.;
982     angles[3] = 90.;
983     angles[4] =  0;
984     angles[5] =  0.;
985   }
986   else if (GetAngles(iplate,istrip) <0.) {
987     angles[0] = 90.;
988     angles[1] =  0.;
989     angles[2] = 90.+GetAngles(iplate,istrip);
990     angles[3] = 90.;
991     angles[4] =-GetAngles(iplate,istrip);
992     angles[5] = 270.;
993   }
994   Rotation(posLocal,angles);
995
996   step[0] =-0.5*kNpadX*fgkXPad;
997   step[1] = 0.;
998   step[2] =-0.5*kNpadZ*fgkZPad;
999   Translation(posLocal,step);
1000
1001   iPadX = (Int_t)(posLocal[0]/fgkXPad);
1002   if (iPadX==kNpadX) iPadX--;
1003   else if (iPadX>kNpadX) iPadX=-1;
1004
1005   return iPadX;
1006
1007 }
1008 //_____________________________________________________________________________
1009 Float_t AliTOFGeometry::GetX(Int_t *det) const
1010 {
1011   //
1012   // Returns X coordinate (cm)
1013   //
1014
1015   Int_t isector = det[0];
1016   Int_t iplate  = det[1];
1017   Int_t istrip  = det[2];
1018   Int_t ipadz   = det[3];
1019   Int_t ipadx   = det[4];
1020
1021   /*
1022   // Find out distance d on the plane wrt median phi:
1023   Float_t d = (ipadx+0.5-kNpadX*0.5)*fgkXPad;
1024
1025   // The radius r in xy plane:
1026   //Float_t r = (fgkRmin+fgkRmax)*0.5-0.01+GetHeights(iplate,istrip)+
1027   //  (ipadz-0.5)*fgkZPad*TMath::Sin(GetAngles(iplate,istrip)/kRaddeg)-0.25; ???
1028   Float_t r = (fgkRmin+fgkRmax)*0.5-0.01+GetHeights(iplate,istrip)+
1029     (ipadz-0.5)*fgkZPad*TMath::Sin(GetAngles(iplate,istrip)/kRaddeg);
1030
1031   // local azimuthal angle in the sector philoc
1032   Float_t philoc  = TMath::ATan(d/r);
1033   //if(philoc<0.) philoc = k2PI + philoc;
1034
1035   // azimuthal angle in the global frame  phi
1036   Float_t phi   = philoc*kRaddeg+(isector+0.5)*fgkPhiSec;
1037
1038   Float_t xCoor = r/TMath::Cos(philoc)*TMath::Cos(phi/kRaddeg);
1039   */
1040
1041   // Pad reference frame -> FSTR reference frame
1042   Float_t posLocal[3] = {0., 0., 0.};
1043   Float_t step[3] = {-(ipadx+0.5)*fgkXPad, 0., -(ipadz+0.5)*fgkZPad};
1044   Translation(posLocal,step);
1045
1046   step[0] = kNpadX*0.5*fgkXPad;
1047   step[1] = 0.;
1048   step[2] = kNpadZ*0.5*fgkZPad;
1049   /*
1050   Float_t posLocal[3] = {(ipadx+0.5)*fgkXPad, 0., (ipadz+0.5)*fgkZPad};
1051   Float_t step[3]= {kNpadX*0.5*fgkXPad, 0., kNpadZ*0.5*fgkZPad};
1052   */
1053   Translation(posLocal,step);
1054
1055   // FSTR reference frame -> FTOA/B/C = FLTA/B/C reference frame
1056   Double_t angles[6];
1057   if      (GetAngles(iplate,istrip) >0.) {
1058     angles[0] = 90.;
1059     angles[1] =  0.;
1060     angles[2] = 90.+GetAngles(iplate,istrip);
1061     angles[3] = 90.;
1062     angles[4] = GetAngles(iplate,istrip);
1063     angles[5] = 90.;
1064   }
1065   else if (GetAngles(iplate,istrip)==0.) {
1066     angles[0] = 90.;
1067     angles[1] =  0.;
1068     angles[2] = 90.;
1069     angles[3] = 90.;
1070     angles[4] =  0;
1071     angles[5] =  0.;
1072   }
1073   else if (GetAngles(iplate,istrip) <0.) {
1074     angles[0] = 90.;
1075     angles[1] =  0.;
1076     angles[2] = 90.+GetAngles(iplate,istrip);
1077     angles[3] = 90.;
1078     angles[4] =-GetAngles(iplate,istrip);
1079     angles[5] = 270.;
1080   }
1081
1082   InverseRotation(posLocal,angles);
1083
1084   step[0] = 0.;
1085   step[1] = -GetHeights(iplate,istrip);
1086   step[2] =  GetDistances(iplate,istrip);
1087   Translation(posLocal,step);
1088
1089   // FTOA = FLTA reference frame -> B071/B074/B075 = BTO1/2/3 reference frame
1090   angles[0] = 90.;
1091   angles[1] =  0.;
1092   angles[2] =  0.;
1093   angles[3] =  0.;
1094   angles[4] = 90.;
1095   angles[5] =270.;
1096
1097   InverseRotation(posLocal,angles);
1098
1099   // B071/B074/B075 = BTO1/2/3 reference frame -> ALICE reference frame
1100   step[0] = 0.;
1101   step[1] = 0.;
1102   step[2] = -((fgkRmax+fgkRmin)*0.5);
1103   Translation(posLocal,step);
1104
1105   angles[0] = 90.;
1106   angles[1] = 90.+(isector+0.5)*fgkPhiSec;
1107   angles[2] = 0.;
1108   angles[3] = 0.;
1109   angles[4] = 90.;
1110   angles[5] = (isector+0.5)*fgkPhiSec;
1111
1112   InverseRotation(posLocal,angles);
1113
1114   Float_t xCoor = posLocal[0];
1115
1116   return xCoor;
1117
1118 }
1119 //_____________________________________________________________________________
1120 Float_t AliTOFGeometry::GetY(Int_t *det) const
1121 {
1122   //
1123   // Returns Y coordinate (cm)
1124   //
1125
1126   Int_t isector = det[0];
1127   Int_t iplate  = det[1];
1128   Int_t istrip  = det[2];
1129   Int_t ipadz   = det[3];
1130   Int_t ipadx   = det[4];
1131
1132   /*
1133   // Find out distance d on the plane wrt median phi:
1134   Float_t d = (ipadx+0.5-kNpadX*0.5)*fgkXPad;
1135
1136   // The radius r in xy plane:
1137   //Float_t r = (fgkRmin+fgkRmax)*0.5-0.01+GetHeights(iplate,istrip)+
1138   //  (ipadz-0.5)*fgkZPad*TMath::Sin(GetAngles(iplate,istrip)/kRaddeg)-0.25; ???
1139   Float_t r = (fgkRmin+fgkRmax)*0.5-0.01+GetHeights(iplate,istrip)+
1140     (ipadz-0.5)*fgkZPad*TMath::Sin(GetAngles(iplate,istrip)/kRaddeg);
1141
1142   // local azimuthal angle in the sector philoc
1143   Float_t philoc = TMath::ATan(d/r);
1144   //if(philoc<0.) philoc = k2PI + philoc;
1145
1146   // azimuthal angle in the global frame  phi
1147   Float_t phi   = philoc*kRaddeg+(isector+0.5)*fgkPhiSec;
1148
1149   Float_t yCoor = r/TMath::Cos(philoc)*TMath::Sin(phi/kRaddeg);
1150   */
1151
1152   // Pad reference frame -> FSTR reference frame
1153   Float_t posLocal[3] = {0., 0., 0.};
1154   Float_t step[3] = {-(ipadx+0.5)*fgkXPad, 0., -(ipadz+0.5)*fgkZPad};
1155   Translation(posLocal,step);
1156
1157   step[0] = kNpadX*0.5*fgkXPad;
1158   step[1] = 0.;
1159   step[2] = kNpadZ*0.5*fgkZPad;
1160   /*
1161   Float_t posLocal[3] = {(ipadx+0.5)*fgkXPad, 0., (ipadz+0.5)*fgkZPad};
1162   Float_t step[3]= {kNpadX*0.5*fgkXPad, 0., kNpadZ*0.5*fgkZPad};
1163   */
1164   Translation(posLocal,step);
1165
1166   // FSTR reference frame -> FTOA/B/C = FLTA/B/C reference frame
1167
1168   Double_t angles[6];
1169   if      (GetAngles(iplate,istrip) >0.) {
1170     angles[0] = 90.;
1171     angles[1] =  0.;
1172     angles[2] = 90.+GetAngles(iplate,istrip);
1173     angles[3] = 90.;
1174     angles[4] = GetAngles(iplate,istrip);
1175     angles[5] = 90.;
1176   }
1177   else if (GetAngles(iplate,istrip)==0.) {
1178     angles[0] = 90.;
1179     angles[1] =  0.;
1180     angles[2] = 90.;
1181     angles[3] = 90.;
1182     angles[4] =  0;
1183     angles[5] =  0.;
1184   }
1185   else if (GetAngles(iplate,istrip) <0.) {
1186     angles[0] = 90.;
1187     angles[1] =  0.;
1188     angles[2] = 90.+GetAngles(iplate,istrip);
1189     angles[3] = 90.;
1190     angles[4] =-GetAngles(iplate,istrip);
1191     angles[5] = 270.;
1192   }
1193
1194   InverseRotation(posLocal,angles);
1195
1196   step[0] = 0.;
1197   step[1] = -GetHeights(iplate,istrip);
1198   step[2] =  GetDistances(iplate,istrip);
1199   Translation(posLocal,step);
1200
1201   // FTOA = FLTA reference frame -> B071/B074/B075 = BTO1/2/3 reference frame
1202   angles[0] = 90.;
1203   angles[1] =  0.;
1204   angles[2] =  0.;
1205   angles[3] =  0.;
1206   angles[4] = 90.;
1207   angles[5] =270.;
1208
1209   InverseRotation(posLocal,angles);
1210
1211   // B071/B074/B075 = BTO1/2/3 reference frame -> ALICE reference frame
1212   step[0] = 0.;
1213   step[1] = 0.;
1214   step[2] = -((fgkRmax+fgkRmin)*0.5);
1215   Translation(posLocal,step);
1216
1217   angles[0] = 90.;
1218   angles[1] = 90.+(isector+0.5)*fgkPhiSec;
1219   angles[2] = 0.;
1220   angles[3] = 0.;
1221   angles[4] = 90.;
1222   angles[5] = (isector+0.5)*fgkPhiSec;
1223
1224   InverseRotation(posLocal,angles);
1225
1226   Float_t yCoor = posLocal[1];
1227
1228   return yCoor;
1229
1230 }
1231
1232 //_____________________________________________________________________________
1233 Float_t AliTOFGeometry::GetZ(Int_t *det) const
1234 {
1235   //
1236   // Returns Z coordinate (cm)
1237   //
1238
1239   Int_t isector = det[0];
1240   Int_t iplate  = det[1];
1241   Int_t istrip  = det[2];
1242   Int_t ipadz   = det[3];
1243   Int_t ipadx   = det[4];
1244
1245   /*
1246   Float_t zCoor = GetDistances(iplate,istrip) +
1247     (0.5-ipadz) * fgkZPad * TMath::Cos(GetAngles(iplate,istrip)*kDegrad);
1248   */
1249
1250   // Pad reference frame -> FSTR reference frame
1251   Float_t posLocal[3] = {0., 0., 0.};
1252   Float_t step[3] = {-(ipadx+0.5)*fgkXPad, 0., -(ipadz+0.5)*fgkZPad};
1253   Translation(posLocal,step);
1254
1255   step[0] = kNpadX*0.5*fgkXPad;
1256   step[1] = 0.;
1257   step[2] = kNpadZ*0.5*fgkZPad;
1258   /*
1259   Float_t posLocal[3] = {(ipadx+0.5)*fgkXPad, 0., (ipadz+0.5)*fgkZPad};
1260   Float_t step[3]= {kNpadX*0.5*fgkXPad, 0., kNpadZ*0.5*fgkZPad};
1261   */
1262   Translation(posLocal,step);
1263
1264   // FSTR reference frame -> FTOA/B/C = FLTA/B/C reference frame
1265   Double_t angles[6];
1266   if      (GetAngles(iplate,istrip) >0.) {
1267     angles[0] = 90.;
1268     angles[1] =  0.;
1269     angles[2] = 90.+GetAngles(iplate,istrip);
1270     angles[3] = 90.;
1271     angles[4] = GetAngles(iplate,istrip);
1272     angles[5] = 90.;
1273   }
1274   else if (GetAngles(iplate,istrip)==0.) {
1275     angles[0] = 90.;
1276     angles[1] =  0.;
1277     angles[2] = 90.;
1278     angles[3] = 90.;
1279     angles[4] =  0;
1280     angles[5] =  0.;
1281   }
1282   else if (GetAngles(iplate,istrip) <0.) {
1283     angles[0] = 90.;
1284     angles[1] =  0.;
1285     angles[2] = 90.+GetAngles(iplate,istrip);
1286     angles[3] = 90.;
1287     angles[4] =-GetAngles(iplate,istrip);
1288     angles[5] = 270.;
1289   }
1290
1291   InverseRotation(posLocal,angles);
1292
1293   step[0] = 0.;
1294   step[1] = -GetHeights(iplate,istrip);
1295   step[2] =  GetDistances(iplate,istrip);
1296   Translation(posLocal,step);
1297
1298   // FTOA = FLTA reference frame -> B071/B074/B075 = BTO1/2/3 reference frame
1299   angles[0] = 90.;
1300   angles[1] =  0.;
1301   angles[2] =  0.;
1302   angles[3] =  0.;
1303   angles[4] = 90.;
1304   angles[5] =270.;
1305
1306   InverseRotation(posLocal,angles);
1307
1308   // B071/B074/B075 = BTO1/2/3 reference frame -> ALICE reference frame
1309   step[0] = 0.;
1310   step[1] = 0.;
1311   step[2] = -((fgkRmax+fgkRmin)*0.5);
1312   Translation(posLocal,step);
1313
1314   angles[0] = 90.;
1315   angles[1] = 90.+(isector+0.5)*fgkPhiSec;
1316   angles[2] = 0.;
1317   angles[3] = 0.;
1318   angles[4] = 90.;
1319   angles[5] = (isector+0.5)*fgkPhiSec;
1320
1321   InverseRotation(posLocal,angles);
1322
1323   Float_t zCoor = posLocal[2];
1324
1325   return zCoor;
1326
1327 }
1328 //_____________________________________________________________________________
1329
1330 void AliTOFGeometry::DetToSectorRF(Int_t vol[5], Double_t **coord)
1331 {
1332   //
1333   // Returns the local coordinates (x, y, z) in sector reference frame
1334   // for the 4 corners of each sector pad (vol[1], vol[2], vol[3], vol[4])
1335   //
1336
1337   if (!gGeoManager) printf("ERROR: no TGeo\n");
1338
1339   // ALICE -> TOF Sector
1340   Char_t path1[100]="";
1341   GetVolumePath(vol[0],path1);
1342   gGeoManager->cd(path1);
1343   TGeoHMatrix aliceToSector;
1344   aliceToSector = *gGeoManager->GetCurrentMatrix();
1345
1346   // TOF Sector -> ALICE
1347   //TGeoHMatrix sectorToALICE = aliceToSector.Inverse();
1348
1349   // ALICE -> TOF Pad
1350   Char_t path2[100]="";
1351   GetVolumePath(vol,path2);
1352   gGeoManager->cd(path2);
1353   TGeoHMatrix aliceToPad;
1354   aliceToPad = *gGeoManager->GetCurrentMatrix();
1355
1356   // TOF Pad -> ALICE
1357   TGeoHMatrix padToALICE = aliceToPad.Inverse();
1358
1359   // TOF Pad -> TOF Sector
1360   TGeoHMatrix padToSector = padToALICE*aliceToSector;
1361
1362   // TOF Sector -> TOF Pad
1363   //TGeoHMatrix sectorToPad = sectorToALICE*aliceToPad;
1364
1365   // coordinates of the pad bottom corner
1366   Double_t **cornerPad = new Double_t*[4];
1367   for (Int_t ii=0; ii<4; ii++) cornerPad[ii] = new Double_t[3];
1368
1369   cornerPad[0][0] = -fgkXPad/2.;
1370   cornerPad[0][1] =  0.;
1371   cornerPad[0][2] = -fgkZPad/2.;
1372
1373   cornerPad[1][0] =  fgkXPad/2.;
1374   cornerPad[1][1] =  0.;
1375   cornerPad[1][2] = -fgkZPad/2.;
1376
1377   cornerPad[2][0] =  fgkXPad/2.;
1378   cornerPad[2][1] =  0.;
1379   cornerPad[2][2] =  fgkZPad/2.;
1380
1381   cornerPad[3][0] = -fgkXPad/2.;
1382   cornerPad[3][1] =  0.;
1383   cornerPad[3][2] =  fgkZPad/2.;
1384
1385   for(Int_t aa=0; aa<4; aa++) for(Int_t bb=0; bb<3; bb++) coord[aa][bb]=0.;
1386
1387   for (Int_t jj=0; jj<4; jj++) padToSector.MasterToLocal(&cornerPad[jj][0], &coord[jj][0]);
1388
1389   delete cornerPad;
1390
1391   //sectorToPad.LocalToMaster(cornerPad, coord);
1392
1393 }
1394 //_____________________________________________________________________________
1395 Float_t AliTOFGeometry::GetPadDx(Float_t *pos)
1396 {
1397   //
1398   // Returns the x coordinate in the Pad reference frame
1399   //
1400
1401   Float_t xpad = -2.;
1402
1403   Float_t posLocal[3];
1404   for (Int_t ii=0; ii<3; ii++) posLocal[ii] = pos[ii];
1405  
1406   Int_t isector = GetSector(posLocal);
1407   if(isector == -1){
1408     //AliError("Detector Index could not be determined");
1409     return xpad;}
1410   Int_t iplate =  GetPlate(posLocal);
1411   if(iplate == -1){
1412     //AliError("Detector Index could not be determined");
1413     return xpad;} 
1414   Int_t istrip =  GetStrip(posLocal);
1415   if(istrip == -1){  
1416     //AliError("Detector Index could not be determined");
1417     return xpad;}
1418   Int_t ipadz =  GetPadZ(posLocal);
1419   if(ipadz == -1){  
1420     //AliError("Detector Index could not be determined");
1421     return xpad;}
1422   Int_t ipadx =  GetPadX(posLocal);
1423   if(ipadx == -1){
1424     //AliError("Detector Index could not be determined");
1425     return xpad;}
1426
1427   // ALICE reference frame -> B071/B074/B075 = BTO1/2/3 reference frame
1428   Double_t angles[6] = 
1429     {90., 90.+(isector+0.5)*fgkPhiSec,
1430       0.,  0.,
1431      90., (isector+0.5)*fgkPhiSec
1432     };
1433   Rotation(posLocal,angles);
1434
1435   Float_t step[3] = {0., 0., (fgkRmax+fgkRmin)*0.5};
1436   Translation(posLocal,step);
1437
1438   // B071/B074/B075 = BTO1/2/3 reference frame -> FTOA/B/C = FLTA/B/C reference frame
1439   angles[0] = 90.;
1440   angles[1] =  0.;
1441   angles[2] =  0.;
1442   angles[3] =  0.;
1443   angles[4] = 90.;
1444   angles[5] =270.;
1445
1446   Rotation(posLocal,angles);
1447
1448   // FTOA/B/C = FLTA/B/C reference frame -> FSTR reference frame
1449   step[0] = 0.;
1450   step[1] = GetHeights(iplate,istrip);
1451   step[2] = -GetDistances(iplate,istrip);
1452   Translation(posLocal,step);
1453
1454   if      (GetAngles(iplate,istrip) >0.) {
1455     angles[0] = 90.;
1456     angles[1] =  0.;
1457     angles[2] = 90.+GetAngles(iplate,istrip);
1458     angles[3] = 90.;
1459     angles[4] = GetAngles(iplate,istrip);
1460     angles[5] = 90.;
1461   }
1462   else if (GetAngles(iplate,istrip)==0.) {
1463     angles[0] = 90.;
1464     angles[1] =  0.;
1465     angles[2] = 90.;
1466     angles[3] = 90.;
1467     angles[4] =  0;
1468     angles[5] =  0.;
1469   }
1470   else if (GetAngles(iplate,istrip) <0.) {
1471     angles[0] = 90.;
1472     angles[1] =  0.;
1473     angles[2] = 90.+GetAngles(iplate,istrip);
1474     angles[3] = 90.;
1475     angles[4] =-GetAngles(iplate,istrip);
1476     angles[5] = 270.;
1477   }
1478   Rotation(posLocal,angles);
1479
1480   step[0] =-0.5*kNpadX*fgkXPad;
1481   step[1] = 0.;
1482   step[2] =-0.5*kNpadZ*fgkZPad;
1483   Translation(posLocal,step);
1484
1485   step[0] = (ipadx+0.5)*fgkXPad;
1486   step[1] = 0.;
1487   step[2] = (ipadz+0.5)*fgkZPad;
1488   Translation(posLocal,step);
1489   
1490   xpad=posLocal[0];
1491
1492   return xpad;
1493
1494 }
1495 //_____________________________________________________________________________
1496 Float_t AliTOFGeometry::GetPadDy(Float_t *pos)
1497 {
1498   //
1499   // Returns the y coordinate in the Pad reference frame
1500   //
1501
1502   Float_t ypad = -2.;
1503
1504   Float_t posLocal[3];
1505   for (Int_t ii=0; ii<3; ii++) posLocal[ii] = pos[ii];
1506  
1507   Int_t isector = GetSector(posLocal);
1508   if(isector == -1){
1509     //AliError("Detector Index could not be determined");
1510     return ypad;}
1511   Int_t iplate =  GetPlate(posLocal);
1512   if(iplate == -1){
1513     //AliError("Detector Index could not be determined");
1514     return ypad;} 
1515   Int_t istrip =  GetStrip(posLocal);
1516   if(istrip == -1){  
1517     //AliError("Detector Index could not be determined");
1518     return ypad;}
1519   Int_t ipadz =  GetPadZ(posLocal);
1520   if(ipadz == -1){  
1521     //AliError("Detector Index could not be determined");
1522     return ypad;}
1523   Int_t ipadx =  GetPadX(posLocal);
1524   if(ipadx == -1){
1525     //AliError("Detector Index could not be determined");
1526     return ypad;}
1527
1528   // ALICE reference frame -> B071/B074/B075 = BTO1/2/3 reference frame
1529   Double_t angles[6] = 
1530     {90., 90.+(isector+0.5)*fgkPhiSec,
1531       0.,  0.,
1532      90., (isector+0.5)*fgkPhiSec
1533     };
1534   Rotation(posLocal,angles);
1535
1536   Float_t step[3] = {0., 0., (fgkRmax+fgkRmin)*0.5};
1537   Translation(posLocal,step);
1538
1539   // B071/B074/B075 = BTO1/2/3 reference frame -> FTOA/B/C = FLTA/B/C reference frame
1540   angles[0] = 90.;
1541   angles[1] =  0.;
1542   angles[2] =  0.;
1543   angles[3] =  0.;
1544   angles[4] = 90.;
1545   angles[5] =270.;
1546
1547   Rotation(posLocal,angles);
1548
1549   // FTOA/B/C = FLTA/B/C reference frame -> FSTR reference frame
1550   step[0] = 0.;
1551   step[1] = GetHeights(iplate,istrip);
1552   step[2] = -GetDistances(iplate,istrip);
1553   Translation(posLocal,step);
1554
1555   if      (GetAngles(iplate,istrip) >0.) {
1556     angles[0] = 90.;
1557     angles[1] =  0.;
1558     angles[2] = 90.+GetAngles(iplate,istrip);
1559     angles[3] = 90.;
1560     angles[4] = GetAngles(iplate,istrip);
1561     angles[5] = 90.;
1562   }
1563   else if (GetAngles(iplate,istrip)==0.) {
1564     angles[0] = 90.;
1565     angles[1] =  0.;
1566     angles[2] = 90.;
1567     angles[3] = 90.;
1568     angles[4] =  0;
1569     angles[5] =  0.;
1570   }
1571   else if (GetAngles(iplate,istrip) <0.) {
1572     angles[0] = 90.;
1573     angles[1] =  0.;
1574     angles[2] = 90.+GetAngles(iplate,istrip);
1575     angles[3] = 90.;
1576     angles[4] =-GetAngles(iplate,istrip);
1577     angles[5] = 270.;
1578   }
1579   Rotation(posLocal,angles);
1580
1581   step[0] =-0.5*kNpadX*fgkXPad;
1582   step[1] = 0.;
1583   step[2] =-0.5*kNpadZ*fgkZPad;
1584   Translation(posLocal,step);
1585   
1586   step[0] = (ipadx+0.5)*fgkXPad;
1587   step[1] = 0.;
1588   step[2] = (ipadz+0.5)*fgkZPad;
1589   Translation(posLocal,step);
1590   
1591   ypad=posLocal[1];
1592   
1593   return ypad;
1594
1595 }
1596 //_____________________________________________________________________________
1597 Float_t AliTOFGeometry::GetPadDz(Float_t *pos)
1598 {
1599   //
1600   // Returns the z coordinate in the Pad reference frame
1601   //
1602
1603   Float_t zpad = -2.;
1604
1605   Float_t posLocal[3];
1606   for (Int_t ii=0; ii<3; ii++) posLocal[ii] = pos[ii];
1607  
1608   Int_t isector = GetSector(posLocal);
1609   if(isector == -1){
1610     //AliError("Detector Index could not be determined");
1611     return zpad;}
1612   Int_t iplate =  GetPlate(posLocal);
1613   if(iplate == -1){
1614     //AliError("Detector Index could not be determined");
1615     return zpad;} 
1616   Int_t istrip =  GetStrip(posLocal);
1617   if(istrip == -1){  
1618     //AliError("Detector Index could not be determined");
1619     return zpad;}
1620   Int_t ipadz =  GetPadZ(posLocal);
1621   if(ipadz == -1){  
1622     //AliError("Detector Index could not be determined");
1623     return zpad;}
1624   Int_t ipadx =  GetPadX(posLocal);
1625   if(ipadx == -1){
1626     //AliError("Detector Index could not be determined");
1627     return zpad;}
1628
1629   // ALICE reference frame -> B071/B074/B075 = BTO1/2/3 reference frame
1630   Double_t angles[6] = 
1631     {90., 90.+(isector+0.5)*fgkPhiSec,
1632       0.,  0.,
1633      90., (isector+0.5)*fgkPhiSec
1634     };
1635   Rotation(posLocal,angles);
1636
1637   Float_t step[3] = {0., 0., (fgkRmax+fgkRmin)*0.5};
1638   Translation(posLocal,step);
1639
1640   // B071/B074/B075 = BTO1/2/3 reference frame -> FTOA/B/C = FLTA/B/C reference frame
1641   angles[0] = 90.;
1642   angles[1] =  0.;
1643   angles[2] =  0.;
1644   angles[3] =  0.;
1645   angles[4] = 90.;
1646   angles[5] =270.;
1647
1648   Rotation(posLocal,angles);
1649
1650   // FTOA/B/C = FLTA/B/C reference frame -> FSTR reference frame
1651   step[0] = 0.;
1652   step[1] = GetHeights(iplate,istrip);
1653   step[2] = -GetDistances(iplate,istrip);
1654   Translation(posLocal,step);
1655
1656   if      (GetAngles(iplate,istrip) >0.) {
1657     angles[0] = 90.;
1658     angles[1] =  0.;
1659     angles[2] = 90.+GetAngles(iplate,istrip);
1660     angles[3] = 90.;
1661     angles[4] = GetAngles(iplate,istrip);
1662     angles[5] = 90.;
1663   }
1664   else if (GetAngles(iplate,istrip)==0.) {
1665     angles[0] = 90.;
1666     angles[1] =  0.;
1667     angles[2] = 90.;
1668     angles[3] = 90.;
1669     angles[4] =  0;
1670     angles[5] =  0.;
1671   }
1672   else if (GetAngles(iplate,istrip) <0.) {
1673     angles[0] = 90.;
1674     angles[1] =  0.;
1675     angles[2] = 90.+GetAngles(iplate,istrip);
1676     angles[3] = 90.;
1677     angles[4] =-GetAngles(iplate,istrip);
1678     angles[5] = 270.;
1679   }
1680   Rotation(posLocal,angles);
1681
1682   step[0] =-0.5*kNpadX*fgkXPad;
1683   step[1] = 0.;
1684   step[2] =-0.5*kNpadZ*fgkZPad;
1685   Translation(posLocal,step);
1686   
1687   step[0] = (ipadx+0.5)*fgkXPad;
1688   step[1] = 0.;
1689   step[2] = (ipadz+0.5)*fgkZPad;
1690   Translation(posLocal,step);
1691
1692   zpad=posLocal[2];
1693
1694   return zpad;
1695
1696 }
1697 //_____________________________________________________________________________
1698
1699 void AliTOFGeometry::Translation(Float_t *xyz, Float_t translationVector[3]) const
1700 {
1701   //
1702   // Return the vector xyz translated by translationVector vector
1703   //
1704
1705   Int_t ii=0;
1706
1707   for (ii=0; ii<3; ii++)
1708     xyz[ii] -= translationVector[ii];
1709
1710   return;
1711
1712 }
1713 //_____________________________________________________________________________
1714
1715 void AliTOFGeometry::Rotation(Float_t *xyz, Double_t rotationAngles[6]) const
1716 {
1717   //
1718   // Return the vector xyz rotated according to the rotationAngles angles
1719   //
1720
1721   Int_t ii=0;
1722   /*
1723   TRotMatrix *matrix = new TRotMatrix("matrix","matrix", angles[0], angles[1],
1724                                       angles[2], angles[3],
1725                                       angles[4], angles[5]);
1726   */
1727
1728   for (ii=0; ii<6; ii++) rotationAngles[ii]*=kDegrad;
1729
1730   Float_t xyzDummy[3] = {0., 0., 0.};
1731
1732   for (ii=0; ii<3; ii++) {
1733     xyzDummy[ii] =
1734       xyz[0]*TMath::Sin(rotationAngles[2*ii])*TMath::Cos(rotationAngles[2*ii+1]) +
1735       xyz[1]*TMath::Sin(rotationAngles[2*ii])*TMath::Sin(rotationAngles[2*ii+1]) +
1736       xyz[2]*TMath::Cos(rotationAngles[2*ii]);
1737   }
1738
1739   for (ii=0; ii<3; ii++) xyz[ii]=xyzDummy[ii];
1740
1741   return;
1742
1743 }
1744 //_____________________________________________________________________________
1745 void AliTOFGeometry::InverseRotation(Float_t *xyz, Double_t rotationAngles[6]) const
1746 {
1747   //
1748   //
1749   //
1750
1751   Int_t ii=0;
1752
1753   for (ii=0; ii<6; ii++) rotationAngles[ii]*=kDegrad;
1754
1755   Float_t xyzDummy[3] = {0., 0., 0.};
1756
1757   xyzDummy[0] =
1758     xyz[0]*TMath::Sin(rotationAngles[0])*TMath::Cos(rotationAngles[1]) +
1759     xyz[1]*TMath::Sin(rotationAngles[2])*TMath::Cos(rotationAngles[3]) +
1760     xyz[2]*TMath::Sin(rotationAngles[4])*TMath::Cos(rotationAngles[5]);
1761   
1762   xyzDummy[1] =
1763     xyz[0]*TMath::Sin(rotationAngles[0])*TMath::Sin(rotationAngles[1]) +
1764     xyz[1]*TMath::Sin(rotationAngles[2])*TMath::Sin(rotationAngles[3]) +
1765     xyz[2]*TMath::Sin(rotationAngles[4])*TMath::Sin(rotationAngles[5]);
1766   
1767   xyzDummy[2] =
1768     xyz[0]*TMath::Cos(rotationAngles[0]) +
1769     xyz[1]*TMath::Cos(rotationAngles[2]) +
1770     xyz[2]*TMath::Cos(rotationAngles[4]);
1771   
1772   for (ii=0; ii<3; ii++) xyz[ii]=xyzDummy[ii];
1773
1774   return;
1775
1776 }
1777 //_____________________________________________________________________________
1778
1779 Int_t AliTOFGeometry::GetIndex(Int_t *detId)
1780 {
1781   //Retrieve calibration channel index 
1782   Int_t isector = detId[0];
1783   if (isector >= kNSectors){
1784     printf("Wrong sector number in TOF (%d) !\n",isector);
1785     return -1;
1786   }
1787   Int_t iplate = detId[1];
1788   if (iplate >= kNPlates){
1789     printf("Wrong plate number in TOF (%d) !\n",iplate);
1790     return -1;
1791   }
1792   Int_t istrip = detId[2];
1793   Int_t stripOffset = GetStripNumberPerSM(iplate,istrip);
1794   if (stripOffset==-1) {
1795     printf("Wrong strip number per SM in TOF (%d) !\n",stripOffset);
1796     return -1;
1797   }
1798
1799   Int_t ipadz = detId[3];
1800   Int_t ipadx = detId[4];
1801
1802   Int_t idet = ((2*(kNStripC+kNStripB)+kNStripA)*kNpadZ*kNpadX)*isector +
1803                (stripOffset*kNpadZ*kNpadX)+
1804                (kNpadX)*ipadz+
1805                 ipadx;
1806   return idet;
1807 }
1808 //_____________________________________________________________________________
1809
1810 void AliTOFGeometry::GetVolumeIndices(Int_t index, Int_t *detId)
1811 {
1812   //
1813   // Retrieve volume indices from the calibration channel index 
1814   //
1815
1816   detId[0] = index/NpadXStrip()/NStripXSector();
1817
1818   Int_t dummyStripPerModule = 
1819     ( index - ( NStripXSector()*NpadXStrip()*detId[0]) ) / NpadXStrip();
1820   if (dummyStripPerModule<kNStripC) {
1821     detId[1] = 0;
1822     detId[2] = dummyStripPerModule;
1823   }
1824   else if (dummyStripPerModule>=kNStripC && dummyStripPerModule<kNStripC+kNStripB) {
1825     detId[1] = 1;
1826     detId[2] = dummyStripPerModule-kNStripC;
1827   }
1828   else if (dummyStripPerModule>=kNStripC+kNStripB && dummyStripPerModule<kNStripC+kNStripB+kNStripA) {
1829     detId[1] = 2;
1830     detId[2] = dummyStripPerModule-kNStripC-kNStripB;
1831   }
1832   else if (dummyStripPerModule>=kNStripC+kNStripB+kNStripA && dummyStripPerModule<kNStripC+kNStripB+kNStripA+kNStripB) {
1833     detId[1] = 3;
1834     detId[2] = dummyStripPerModule-kNStripC-kNStripB-kNStripA;
1835   }
1836   else if (dummyStripPerModule>=kNStripC+kNStripB+kNStripA+kNStripB && dummyStripPerModule<NStripXSector()) {
1837     detId[1] = 4;
1838     detId[2] = dummyStripPerModule-kNStripC-kNStripB-kNStripA-kNStripB;
1839   }
1840
1841   Int_t padPerStrip = ( index - ( NStripXSector()*NpadXStrip()*detId[0]) ) - dummyStripPerModule*NpadXStrip();
1842
1843   detId[3] = padPerStrip / kNpadX; // padZ
1844   detId[4] = padPerStrip - detId[3]*kNpadX; // padX
1845
1846 }
1847 //_____________________________________________________________________________
1848
1849 Int_t AliTOFGeometry::NStrip(Int_t nPlate)
1850 {
1851   //
1852   // Returns the strips number for the plate number 'nPlate'
1853   //
1854
1855   Int_t nStrips = kNStripC;
1856
1857   switch(nPlate) {
1858   case 2:
1859     nStrips = kNStripA;
1860     break;
1861   case 1:
1862   case 3:
1863     nStrips = kNStripB;
1864     break;
1865   case 0:
1866   case 4:
1867   default:
1868     nStrips = kNStripC;
1869     break;
1870   }
1871
1872   return nStrips;
1873
1874 }
1875 //-------------------------------------------------------------------------
1876
1877 UShort_t AliTOFGeometry::GetAliSensVolIndex(Int_t isector, Int_t iplate, Int_t istrip) const
1878 {
1879   //
1880   // Get the index of the TOF alignable volume in the AliGeomManager order.
1881   //
1882
1883   Int_t index = GetStripNumber(isector, iplate, istrip);
1884
1885   UShort_t volIndex = AliGeomManager::LayerToVolUID(AliGeomManager::kTOF,index);
1886
1887   return volIndex;
1888
1889 }
1890 //-------------------------------------------------------------------------
1891
1892 Int_t AliTOFGeometry::GetStripNumber(Int_t isector, Int_t iplate, Int_t istrip)
1893 {
1894   //
1895   // Get the serial number of the TOF strip number istrip [0,14/18],
1896   //   in the module number iplate [0,4],
1897   //   in the TOF SM number isector [0,17].
1898   // This number will range in [0,1637].
1899   //
1900
1901   Bool_t check = (isector >= kNSectors);
1902
1903   if (check)
1904     printf("E-AliTOFGeometry::GetStripNumber: Wrong sector number in TOF (%d)!\n",isector);
1905
1906   Int_t index = -1;
1907   Int_t stripInSM = GetStripNumberPerSM(iplate, istrip);
1908   if (!check && stripInSM!=-1)
1909     index = (2*(kNStripC+kNStripB)+kNStripA)*isector + stripInSM;
1910
1911   return index;
1912
1913 }
1914 //-------------------------------------------------------------------------
1915
1916 Int_t AliTOFGeometry::GetStripNumberPerSM(Int_t iplate, Int_t istrip)
1917 {
1918   //
1919   // Get the serial number of the TOF strip number istrip [0,14/18],
1920   //   in the module number iplate [0,4].
1921   // This number will range in [0,90].
1922   //
1923
1924   Int_t index = -1;
1925
1926   Bool_t check = (
1927                   (iplate<0 || iplate>=kNPlates)
1928                   ||
1929                   (
1930                    (iplate==2 && (istrip<0 || istrip>=kNStripA))
1931                    ||
1932                    (iplate!=2 && (istrip<0 || istrip>=kNStripC))
1933                    )
1934                   );
1935
1936   if (iplate<0 || iplate>=kNPlates)
1937     printf("E-AliTOFGeometry::GetStripNumberPerSM: Wrong plate number in TOF (%1d)!\n",iplate);
1938
1939   if (
1940       (iplate==2 && (istrip<0 || istrip>=kNStripA))
1941       ||
1942       (iplate!=2 && (istrip<0 || istrip>=kNStripC))
1943       )
1944     printf("E-AliTOFGeometry::GetStripNumberPerSM: Wrong strip number in TOF (strip=%2d in the plate=%1d)!\n",istrip,iplate);
1945
1946   Int_t stripOffset = 0;
1947   switch (iplate) {
1948   case 0:
1949     stripOffset = 0;
1950     break;
1951   case 1:
1952     stripOffset = kNStripC;
1953     break;
1954   case 2:
1955     stripOffset = kNStripC+kNStripB;
1956     break;
1957   case 3:
1958     stripOffset = kNStripC+kNStripB+kNStripA;
1959     break;
1960   case 4:
1961     stripOffset = kNStripC+kNStripB+kNStripA+kNStripB;
1962     break;
1963   };
1964
1965   if (!check) index = stripOffset + istrip;
1966
1967   return index;
1968
1969 }