]> git.uio.no Git - u/mrichter/AliRoot.git/blob - TOF/AliTOFGeometry.cxx
automatic histogram scaling for AODs now available
[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 dist3d!=0, dist3d vector
420   // has been filled with the 3D distance between the impact point on
421   // the pad and the pad centre (in the reference frame of the TOF pad
422   // 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
432   // from ALICE global reference system
433   // towards TOF pad reference system
434   Double_t posl[3] = {0., 0., 0.};
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   AliDebug(1,Form("  posLocal[0] = %f, posLocal[1] = %f, posLocal[2] = %f ",
717                   posLocal[0],posLocal[1],posLocal[2]));
718
719   Int_t isector = GetSector(posLocal);
720   if(isector == -1){
721     //AliError("Detector Index could not be determined");
722     return iStrip;}
723   Int_t iplate =  GetPlate(posLocal);
724   if(iplate == -1){
725     //AliError("Detector Index could not be determined");
726     return iStrip;} 
727
728   Int_t nstrips=0;
729   switch (iplate) {
730   case 0:
731   case 4:
732     nstrips=kNStripC;
733     break;
734   case 1:
735   case 3:
736     nstrips=kNStripB;
737     break;
738   case 2:
739     nstrips=kNStripA;
740     break;
741   }
742   
743   // ALICE reference frame -> B071/B074/B075 = BTO1/2/3 reference frame
744   Double_t angles[6] = 
745     {90., 90.+(isector+0.5)*fgkPhiSec,
746       0., 0.,
747      90., (isector+0.5)*fgkPhiSec
748     };
749   Rotation(posLocal,angles);
750   AliDebug(1,Form("  posLocal[0] = %f, posLocal[1] = %f, posLocal[2] = %f ",
751                   posLocal[0],posLocal[1],posLocal[2]));
752
753   Float_t step[3] = {0., 0., (fgkRmax+fgkRmin)*0.5};
754   Translation(posLocal,step);
755   AliDebug(1,Form("  posLocal[0] = %f, posLocal[1] = %f, posLocal[2] = %f ",
756                   posLocal[0],posLocal[1],posLocal[2]));
757
758   // B071/B074/B075 = BTO1/2/3 reference frame -> FTOA = FLTA reference frame
759   angles[0] = 90.;
760   angles[1] =  0.;
761   angles[2] =  0.;
762   angles[3] =  0.;
763   angles[4] = 90.;
764   angles[5] =270.;
765
766   Rotation(posLocal,angles);
767   AliDebug(1,Form("  posLocal[0] = %f, posLocal[1] = %f, posLocal[2] = %f ",
768                   posLocal[0],posLocal[1],posLocal[2]));
769
770   // FTOA/B/C = FLTA/B/C reference frame -> FSTR reference frame
771   Int_t totStrip=0;
772   for (Int_t istrip=0; istrip<nstrips; istrip++){
773
774     Float_t posLoc2[3]={posLocal[0],posLocal[1],posLocal[2]};         
775
776     step[0] = 0.;
777     step[1] = GetHeights(iplate,istrip);
778     step[2] = -GetDistances(iplate,istrip);
779     Translation(posLoc2,step);
780
781     if      (GetAngles(iplate,istrip) >0.) {
782       angles[0] = 90.;
783       angles[1] =  0.;
784       angles[2] = 90.+GetAngles(iplate,istrip);
785       angles[3] = 90.;
786       angles[4] = GetAngles(iplate,istrip);
787       angles[5] = 90.;
788     }
789     else if (GetAngles(iplate,istrip)==0.) {
790       angles[0] = 90.;
791       angles[1] =  0.;
792       angles[2] = 90.;
793       angles[3] = 90.;
794       angles[4] =  0;
795       angles[5] =  0.;
796     }
797     else if (GetAngles(iplate,istrip) <0.) {
798       angles[0] = 90.;
799       angles[1] =  0.;
800       angles[2] = 90.+GetAngles(iplate,istrip);
801       angles[3] = 90.;
802       angles[4] =-GetAngles(iplate,istrip);
803       angles[5] = 270.;
804     }
805     Rotation(posLoc2,angles);
806     AliDebug(1,Form(" strip %2d:  posLoc2[0] = %f, posLoc2[1] = %f, posLoc2[2] = %f ",
807                     istrip, posLoc2[0],posLoc2[1],posLoc2[2]));
808
809     if ((TMath::Abs(posLoc2[0])<=klstripx*0.5) &&
810         (TMath::Abs(posLoc2[1])<=khstripy*0.5) &&
811         (TMath::Abs(posLoc2[2])<=kwstripz*0.5)) {
812       iStrip = istrip;
813       totStrip++;
814       for (Int_t jj=0; jj<3; jj++) posLocal[jj]=posLoc2[jj];
815       AliDebug(2,Form(" posLocal[0] = %f, posLocal[1] = %f, posLocal[2] = %f ",
816                       posLocal[0],posLocal[1],posLocal[2]));
817
818       AliDebug(2,Form(" GetAngles(%1i,%2i) = %f, pos[0] = %f, pos[1] = %f, pos[2] = %f",
819                       iplate, istrip, GetAngles(iplate,istrip), pos[0], pos[1], pos[2]));
820       break;
821     }
822
823     if (totStrip>1) AliInfo(Form("total strip number found %2i",totStrip));
824
825   }
826
827   return iStrip;
828   
829 }
830 //_____________________________________________________________________________
831 Int_t AliTOFGeometry::GetPadZ(Float_t *pos) const
832 {
833   //
834   // Returns the Pad index along Z 
835   //
836   //const Float_t klsensmx = kNpadX*fgkXPad;  // length of Sensitive Layer
837   //const Float_t khsensmy = 0.05;//0.11;//0.16;// heigth of Sensitive Layer
838   //const Float_t kwsensmz = kNpadZ*fgkZPad;  // width of Sensitive Layer
839
840   Int_t iPadZ = -1;
841
842   Float_t posLocal[3];
843   for (Int_t ii=0; ii<3; ii++) posLocal[ii] = pos[ii];
844  
845   Int_t isector = GetSector(posLocal);
846   if(isector == -1){
847     //AliError("Detector Index could not be determined");
848     return iPadZ;}
849   Int_t iplate =  GetPlate(posLocal);
850   if(iplate == -1){
851     //AliError("Detector Index could not be determined");
852     return iPadZ;}
853   Int_t istrip =  GetStrip(posLocal);
854   if(istrip == -1){
855     //AliError("Detector Index could not be determined");
856     return iPadZ;}
857
858   // ALICE reference frame -> B071/B074/B075 = BTO1/2/3 reference frame
859   Double_t angles[6] = 
860     {90., 90.+(isector+0.5)*fgkPhiSec,
861       0., 0.,
862      90., (isector+0.5)*fgkPhiSec
863     };
864   Rotation(posLocal,angles);
865
866   Float_t step[3] = {0., 0., (fgkRmax+fgkRmin)*0.5};
867   Translation(posLocal,step);
868
869   // B071/B074/B075 = BTO1/2/3 reference frame -> FTOA = FLTA reference frame
870   angles[0] = 90.;
871   angles[1] =  0.;
872   angles[2] =  0.;
873   angles[3] =  0.;
874   angles[4] = 90.;
875   angles[5] =270.;
876
877   Rotation(posLocal,angles);
878
879   // FTOA/B/C = FLTA/B/C reference frame -> FSTR reference frame
880   step[0] = 0.;
881   step[1] = GetHeights(iplate,istrip);
882   step[2] = -GetDistances(iplate,istrip);
883   Translation(posLocal,step);
884
885   if      (GetAngles(iplate,istrip) >0.) {
886     angles[0] = 90.;
887     angles[1] =  0.;
888     angles[2] = 90.+GetAngles(iplate,istrip);
889     angles[3] = 90.;
890     angles[4] = GetAngles(iplate,istrip);
891     angles[5] = 90.;
892   }
893   else if (GetAngles(iplate,istrip)==0.) {
894     angles[0] = 90.;
895     angles[1] =  0.;
896     angles[2] = 90.;
897     angles[3] = 90.;
898     angles[4] =  0;
899     angles[5] =  0.;
900   }
901   else if (GetAngles(iplate,istrip) <0.) {
902     angles[0] = 90.;
903     angles[1] =  0.;
904     angles[2] = 90.+GetAngles(iplate,istrip);
905     angles[3] = 90.;
906     angles[4] =-GetAngles(iplate,istrip);
907     angles[5] = 270.;
908   }
909   Rotation(posLocal,angles);
910
911   step[0] =-0.5*kNpadX*fgkXPad;
912   step[1] = 0.;
913   step[2] =-0.5*kNpadZ*fgkZPad;
914   Translation(posLocal,step);
915
916   iPadZ = (Int_t)(posLocal[2]/fgkZPad);
917   if (iPadZ==kNpadZ) iPadZ--;
918   else if (iPadZ>kNpadZ) iPadZ=-1;
919
920   return iPadZ;
921
922 }
923 //_____________________________________________________________________________
924 Int_t AliTOFGeometry::GetPadX(Float_t *pos) const
925 {
926   //
927   // Returns the Pad index along X 
928   //
929   //const Float_t klsensmx = kNpadX*fgkXPad;  // length of Sensitive Layer
930   //const Float_t khsensmy = 0.05;//0.11;//0.16;// heigth of Sensitive Layer
931   //const Float_t kwsensmz = kNpadZ*fgkZPad;  // width of Sensitive Layer
932
933   Int_t iPadX  = -1;
934
935   Float_t posLocal[3];
936   for (Int_t ii=0; ii<3; ii++) posLocal[ii] = pos[ii];
937  
938   Int_t isector = GetSector(posLocal);
939   if(isector == -1){
940     //AliError("Detector Index could not be determined");
941     return iPadX;}
942   Int_t iplate =  GetPlate(posLocal);
943   if(iplate == -1){
944     //AliError("Detector Index could not be determined");
945     return iPadX;} 
946   Int_t istrip =  GetStrip(posLocal);
947   if(istrip == -1){  
948     //AliError("Detector Index could not be determined");
949     return iPadX;}
950
951   // ALICE reference frame -> B071/B074/B075 = BTO1/2/3 reference frame
952   Double_t angles[6] = 
953     {90., 90.+(isector+0.5)*fgkPhiSec,
954       0.,  0.,
955      90., (isector+0.5)*fgkPhiSec
956     };
957   Rotation(posLocal,angles);
958
959   Float_t step[3] = {0., 0., (fgkRmax+fgkRmin)*0.5};
960   Translation(posLocal,step);
961
962   // B071/B074/B075 = BTO1/2/3 reference frame -> FTOA/B/C = FLTA/B/C reference frame
963   angles[0] = 90.;
964   angles[1] =  0.;
965   angles[2] =  0.;
966   angles[3] =  0.;
967   angles[4] = 90.;
968   angles[5] =270.;
969
970   Rotation(posLocal,angles);
971
972   // FTOA/B/C = FLTA/B/C reference frame -> FSTR reference frame
973   step[0] = 0.;
974   step[1] = GetHeights(iplate,istrip);
975   step[2] = -GetDistances(iplate,istrip);
976   Translation(posLocal,step);
977
978   if      (GetAngles(iplate,istrip) >0.) {
979     angles[0] = 90.;
980     angles[1] =  0.;
981     angles[2] = 90.+GetAngles(iplate,istrip);
982     angles[3] = 90.;
983     angles[4] = GetAngles(iplate,istrip);
984     angles[5] = 90.;
985   }
986   else if (GetAngles(iplate,istrip)==0.) {
987     angles[0] = 90.;
988     angles[1] =  0.;
989     angles[2] = 90.;
990     angles[3] = 90.;
991     angles[4] =  0;
992     angles[5] =  0.;
993   }
994   else if (GetAngles(iplate,istrip) <0.) {
995     angles[0] = 90.;
996     angles[1] =  0.;
997     angles[2] = 90.+GetAngles(iplate,istrip);
998     angles[3] = 90.;
999     angles[4] =-GetAngles(iplate,istrip);
1000     angles[5] = 270.;
1001   }
1002   Rotation(posLocal,angles);
1003
1004   step[0] =-0.5*kNpadX*fgkXPad;
1005   step[1] = 0.;
1006   step[2] =-0.5*kNpadZ*fgkZPad;
1007   Translation(posLocal,step);
1008
1009   iPadX = (Int_t)(posLocal[0]/fgkXPad);
1010   if (iPadX==kNpadX) iPadX--;
1011   else if (iPadX>kNpadX) iPadX=-1;
1012
1013   return iPadX;
1014
1015 }
1016 //_____________________________________________________________________________
1017 Float_t AliTOFGeometry::GetX(Int_t *det) const
1018 {
1019   //
1020   // Returns X coordinate (cm)
1021   //
1022
1023   Int_t isector = det[0];
1024   Int_t iplate  = det[1];
1025   Int_t istrip  = det[2];
1026   Int_t ipadz   = det[3];
1027   Int_t ipadx   = det[4];
1028
1029   /*
1030   // Find out distance d on the plane wrt median phi:
1031   Float_t d = (ipadx+0.5-kNpadX*0.5)*fgkXPad;
1032
1033   // The radius r in xy plane:
1034   //Float_t r = (fgkRmin+fgkRmax)*0.5-0.01+GetHeights(iplate,istrip)+
1035   //  (ipadz-0.5)*fgkZPad*TMath::Sin(GetAngles(iplate,istrip)/kRaddeg)-0.25; ???
1036   Float_t r = (fgkRmin+fgkRmax)*0.5-0.01+GetHeights(iplate,istrip)+
1037     (ipadz-0.5)*fgkZPad*TMath::Sin(GetAngles(iplate,istrip)/kRaddeg);
1038
1039   // local azimuthal angle in the sector philoc
1040   Float_t philoc  = TMath::ATan(d/r);
1041   //if(philoc<0.) philoc = k2PI + philoc;
1042
1043   // azimuthal angle in the global frame  phi
1044   Float_t phi   = philoc*kRaddeg+(isector+0.5)*fgkPhiSec;
1045
1046   Float_t xCoor = r/TMath::Cos(philoc)*TMath::Cos(phi/kRaddeg);
1047   */
1048
1049   // Pad reference frame -> FSTR reference frame
1050   Float_t posLocal[3] = {0., 0., 0.};
1051   Float_t step[3] = {-(ipadx+0.5)*fgkXPad, 0., -(ipadz+0.5)*fgkZPad};
1052   Translation(posLocal,step);
1053
1054   step[0] = kNpadX*0.5*fgkXPad;
1055   step[1] = 0.;
1056   step[2] = kNpadZ*0.5*fgkZPad;
1057   /*
1058   Float_t posLocal[3] = {(ipadx+0.5)*fgkXPad, 0., (ipadz+0.5)*fgkZPad};
1059   Float_t step[3]= {kNpadX*0.5*fgkXPad, 0., kNpadZ*0.5*fgkZPad};
1060   */
1061   Translation(posLocal,step);
1062
1063   // FSTR reference frame -> FTOA/B/C = FLTA/B/C reference frame
1064   Double_t angles[6];
1065   if      (GetAngles(iplate,istrip) >0.) {
1066     angles[0] = 90.;
1067     angles[1] =  0.;
1068     angles[2] = 90.+GetAngles(iplate,istrip);
1069     angles[3] = 90.;
1070     angles[4] = GetAngles(iplate,istrip);
1071     angles[5] = 90.;
1072   }
1073   else if (GetAngles(iplate,istrip)==0.) {
1074     angles[0] = 90.;
1075     angles[1] =  0.;
1076     angles[2] = 90.;
1077     angles[3] = 90.;
1078     angles[4] =  0;
1079     angles[5] =  0.;
1080   }
1081   else if (GetAngles(iplate,istrip) <0.) {
1082     angles[0] = 90.;
1083     angles[1] =  0.;
1084     angles[2] = 90.+GetAngles(iplate,istrip);
1085     angles[3] = 90.;
1086     angles[4] =-GetAngles(iplate,istrip);
1087     angles[5] = 270.;
1088   }
1089
1090   InverseRotation(posLocal,angles);
1091
1092   step[0] = 0.;
1093   step[1] = -GetHeights(iplate,istrip);
1094   step[2] =  GetDistances(iplate,istrip);
1095   Translation(posLocal,step);
1096
1097   // FTOA = FLTA reference frame -> B071/B074/B075 = BTO1/2/3 reference frame
1098   angles[0] = 90.;
1099   angles[1] =  0.;
1100   angles[2] =  0.;
1101   angles[3] =  0.;
1102   angles[4] = 90.;
1103   angles[5] =270.;
1104
1105   InverseRotation(posLocal,angles);
1106
1107   // B071/B074/B075 = BTO1/2/3 reference frame -> ALICE reference frame
1108   step[0] = 0.;
1109   step[1] = 0.;
1110   step[2] = -((fgkRmax+fgkRmin)*0.5);
1111   Translation(posLocal,step);
1112
1113   angles[0] = 90.;
1114   angles[1] = 90.+(isector+0.5)*fgkPhiSec;
1115   angles[2] = 0.;
1116   angles[3] = 0.;
1117   angles[4] = 90.;
1118   angles[5] = (isector+0.5)*fgkPhiSec;
1119
1120   InverseRotation(posLocal,angles);
1121
1122   Float_t xCoor = posLocal[0];
1123
1124   return xCoor;
1125
1126 }
1127 //_____________________________________________________________________________
1128 Float_t AliTOFGeometry::GetY(Int_t *det) const
1129 {
1130   //
1131   // Returns Y coordinate (cm)
1132   //
1133
1134   Int_t isector = det[0];
1135   Int_t iplate  = det[1];
1136   Int_t istrip  = det[2];
1137   Int_t ipadz   = det[3];
1138   Int_t ipadx   = det[4];
1139
1140   /*
1141   // Find out distance d on the plane wrt median phi:
1142   Float_t d = (ipadx+0.5-kNpadX*0.5)*fgkXPad;
1143
1144   // The radius r in xy plane:
1145   //Float_t r = (fgkRmin+fgkRmax)*0.5-0.01+GetHeights(iplate,istrip)+
1146   //  (ipadz-0.5)*fgkZPad*TMath::Sin(GetAngles(iplate,istrip)/kRaddeg)-0.25; ???
1147   Float_t r = (fgkRmin+fgkRmax)*0.5-0.01+GetHeights(iplate,istrip)+
1148     (ipadz-0.5)*fgkZPad*TMath::Sin(GetAngles(iplate,istrip)/kRaddeg);
1149
1150   // local azimuthal angle in the sector philoc
1151   Float_t philoc = TMath::ATan(d/r);
1152   //if(philoc<0.) philoc = k2PI + philoc;
1153
1154   // azimuthal angle in the global frame  phi
1155   Float_t phi   = philoc*kRaddeg+(isector+0.5)*fgkPhiSec;
1156
1157   Float_t yCoor = r/TMath::Cos(philoc)*TMath::Sin(phi/kRaddeg);
1158   */
1159
1160   // Pad reference frame -> FSTR reference frame
1161   Float_t posLocal[3] = {0., 0., 0.};
1162   Float_t step[3] = {-(ipadx+0.5)*fgkXPad, 0., -(ipadz+0.5)*fgkZPad};
1163   Translation(posLocal,step);
1164
1165   step[0] = kNpadX*0.5*fgkXPad;
1166   step[1] = 0.;
1167   step[2] = kNpadZ*0.5*fgkZPad;
1168   /*
1169   Float_t posLocal[3] = {(ipadx+0.5)*fgkXPad, 0., (ipadz+0.5)*fgkZPad};
1170   Float_t step[3]= {kNpadX*0.5*fgkXPad, 0., kNpadZ*0.5*fgkZPad};
1171   */
1172   Translation(posLocal,step);
1173
1174   // FSTR reference frame -> FTOA/B/C = FLTA/B/C reference frame
1175
1176   Double_t angles[6];
1177   if      (GetAngles(iplate,istrip) >0.) {
1178     angles[0] = 90.;
1179     angles[1] =  0.;
1180     angles[2] = 90.+GetAngles(iplate,istrip);
1181     angles[3] = 90.;
1182     angles[4] = GetAngles(iplate,istrip);
1183     angles[5] = 90.;
1184   }
1185   else if (GetAngles(iplate,istrip)==0.) {
1186     angles[0] = 90.;
1187     angles[1] =  0.;
1188     angles[2] = 90.;
1189     angles[3] = 90.;
1190     angles[4] =  0;
1191     angles[5] =  0.;
1192   }
1193   else if (GetAngles(iplate,istrip) <0.) {
1194     angles[0] = 90.;
1195     angles[1] =  0.;
1196     angles[2] = 90.+GetAngles(iplate,istrip);
1197     angles[3] = 90.;
1198     angles[4] =-GetAngles(iplate,istrip);
1199     angles[5] = 270.;
1200   }
1201
1202   InverseRotation(posLocal,angles);
1203
1204   step[0] = 0.;
1205   step[1] = -GetHeights(iplate,istrip);
1206   step[2] =  GetDistances(iplate,istrip);
1207   Translation(posLocal,step);
1208
1209   // FTOA = FLTA reference frame -> B071/B074/B075 = BTO1/2/3 reference frame
1210   angles[0] = 90.;
1211   angles[1] =  0.;
1212   angles[2] =  0.;
1213   angles[3] =  0.;
1214   angles[4] = 90.;
1215   angles[5] =270.;
1216
1217   InverseRotation(posLocal,angles);
1218
1219   // B071/B074/B075 = BTO1/2/3 reference frame -> ALICE reference frame
1220   step[0] = 0.;
1221   step[1] = 0.;
1222   step[2] = -((fgkRmax+fgkRmin)*0.5);
1223   Translation(posLocal,step);
1224
1225   angles[0] = 90.;
1226   angles[1] = 90.+(isector+0.5)*fgkPhiSec;
1227   angles[2] = 0.;
1228   angles[3] = 0.;
1229   angles[4] = 90.;
1230   angles[5] = (isector+0.5)*fgkPhiSec;
1231
1232   InverseRotation(posLocal,angles);
1233
1234   Float_t yCoor = posLocal[1];
1235
1236   return yCoor;
1237
1238 }
1239
1240 //_____________________________________________________________________________
1241 Float_t AliTOFGeometry::GetZ(Int_t *det) const
1242 {
1243   //
1244   // Returns Z coordinate (cm)
1245   //
1246
1247   Int_t isector = det[0];
1248   Int_t iplate  = det[1];
1249   Int_t istrip  = det[2];
1250   Int_t ipadz   = det[3];
1251   Int_t ipadx   = det[4];
1252
1253   /*
1254   Float_t zCoor = GetDistances(iplate,istrip) +
1255     (0.5-ipadz) * fgkZPad * TMath::Cos(GetAngles(iplate,istrip)*kDegrad);
1256   */
1257
1258   // Pad reference frame -> FSTR reference frame
1259   Float_t posLocal[3] = {0., 0., 0.};
1260   Float_t step[3] = {-(ipadx+0.5)*fgkXPad, 0., -(ipadz+0.5)*fgkZPad};
1261   Translation(posLocal,step);
1262
1263   step[0] = kNpadX*0.5*fgkXPad;
1264   step[1] = 0.;
1265   step[2] = kNpadZ*0.5*fgkZPad;
1266   /*
1267   Float_t posLocal[3] = {(ipadx+0.5)*fgkXPad, 0., (ipadz+0.5)*fgkZPad};
1268   Float_t step[3]= {kNpadX*0.5*fgkXPad, 0., kNpadZ*0.5*fgkZPad};
1269   */
1270   Translation(posLocal,step);
1271
1272   // FSTR reference frame -> FTOA/B/C = FLTA/B/C reference frame
1273   Double_t angles[6];
1274   if      (GetAngles(iplate,istrip) >0.) {
1275     angles[0] = 90.;
1276     angles[1] =  0.;
1277     angles[2] = 90.+GetAngles(iplate,istrip);
1278     angles[3] = 90.;
1279     angles[4] = GetAngles(iplate,istrip);
1280     angles[5] = 90.;
1281   }
1282   else if (GetAngles(iplate,istrip)==0.) {
1283     angles[0] = 90.;
1284     angles[1] =  0.;
1285     angles[2] = 90.;
1286     angles[3] = 90.;
1287     angles[4] =  0;
1288     angles[5] =  0.;
1289   }
1290   else if (GetAngles(iplate,istrip) <0.) {
1291     angles[0] = 90.;
1292     angles[1] =  0.;
1293     angles[2] = 90.+GetAngles(iplate,istrip);
1294     angles[3] = 90.;
1295     angles[4] =-GetAngles(iplate,istrip);
1296     angles[5] = 270.;
1297   }
1298
1299   InverseRotation(posLocal,angles);
1300
1301   step[0] = 0.;
1302   step[1] = -GetHeights(iplate,istrip);
1303   step[2] =  GetDistances(iplate,istrip);
1304   Translation(posLocal,step);
1305
1306   // FTOA = FLTA reference frame -> B071/B074/B075 = BTO1/2/3 reference frame
1307   angles[0] = 90.;
1308   angles[1] =  0.;
1309   angles[2] =  0.;
1310   angles[3] =  0.;
1311   angles[4] = 90.;
1312   angles[5] =270.;
1313
1314   InverseRotation(posLocal,angles);
1315
1316   // B071/B074/B075 = BTO1/2/3 reference frame -> ALICE reference frame
1317   step[0] = 0.;
1318   step[1] = 0.;
1319   step[2] = -((fgkRmax+fgkRmin)*0.5);
1320   Translation(posLocal,step);
1321
1322   angles[0] = 90.;
1323   angles[1] = 90.+(isector+0.5)*fgkPhiSec;
1324   angles[2] = 0.;
1325   angles[3] = 0.;
1326   angles[4] = 90.;
1327   angles[5] = (isector+0.5)*fgkPhiSec;
1328
1329   InverseRotation(posLocal,angles);
1330
1331   Float_t zCoor = posLocal[2];
1332
1333   return zCoor;
1334
1335 }
1336 //_____________________________________________________________________________
1337
1338 void AliTOFGeometry::DetToSectorRF(Int_t vol[5], Double_t **coord)
1339 {
1340   //
1341   // Returns the local coordinates (x, y, z) in sector reference frame
1342   // for the 4 corners of each sector pad (vol[1], vol[2], vol[3], vol[4])
1343   //
1344
1345   if (!gGeoManager) printf("ERROR: no TGeo\n");
1346
1347   // ALICE -> TOF Sector
1348   Char_t path1[100]="";
1349   GetVolumePath(vol[0],path1);
1350   gGeoManager->cd(path1);
1351   TGeoHMatrix aliceToSector;
1352   aliceToSector = *gGeoManager->GetCurrentMatrix();
1353
1354   // TOF Sector -> ALICE
1355   //TGeoHMatrix sectorToALICE = aliceToSector.Inverse();
1356
1357   // ALICE -> TOF Pad
1358   Char_t path2[100]="";
1359   GetVolumePath(vol,path2);
1360   gGeoManager->cd(path2);
1361   TGeoHMatrix aliceToPad;
1362   aliceToPad = *gGeoManager->GetCurrentMatrix();
1363
1364   // TOF Pad -> ALICE
1365   TGeoHMatrix padToALICE = aliceToPad.Inverse();
1366
1367   // TOF Pad -> TOF Sector
1368   TGeoHMatrix padToSector = padToALICE*aliceToSector;
1369
1370   // TOF Sector -> TOF Pad
1371   //TGeoHMatrix sectorToPad = sectorToALICE*aliceToPad;
1372
1373   // coordinates of the pad bottom corner
1374   Double_t **cornerPad = new Double_t*[4];
1375   for (Int_t ii=0; ii<4; ii++) cornerPad[ii] = new Double_t[3];
1376
1377   cornerPad[0][0] = -fgkXPad/2.;
1378   cornerPad[0][1] =  0.;
1379   cornerPad[0][2] = -fgkZPad/2.;
1380
1381   cornerPad[1][0] =  fgkXPad/2.;
1382   cornerPad[1][1] =  0.;
1383   cornerPad[1][2] = -fgkZPad/2.;
1384
1385   cornerPad[2][0] =  fgkXPad/2.;
1386   cornerPad[2][1] =  0.;
1387   cornerPad[2][2] =  fgkZPad/2.;
1388
1389   cornerPad[3][0] = -fgkXPad/2.;
1390   cornerPad[3][1] =  0.;
1391   cornerPad[3][2] =  fgkZPad/2.;
1392
1393   for(Int_t aa=0; aa<4; aa++) for(Int_t bb=0; bb<3; bb++) coord[aa][bb]=0.;
1394
1395   for (Int_t jj=0; jj<4; jj++) padToSector.MasterToLocal(&cornerPad[jj][0], &coord[jj][0]);
1396
1397   delete cornerPad;
1398
1399   //sectorToPad.LocalToMaster(cornerPad, coord);
1400
1401 }
1402 //_____________________________________________________________________________
1403 Float_t AliTOFGeometry::GetPadDx(Float_t *pos)
1404 {
1405   //
1406   // Returns the x coordinate in the Pad reference frame
1407   //
1408
1409   Float_t xpad = -2.;
1410
1411   Float_t posLocal[3];
1412   for (Int_t ii=0; ii<3; ii++) posLocal[ii] = pos[ii];
1413  
1414   Int_t isector = GetSector(posLocal);
1415   if(isector == -1){
1416     //AliError("Detector Index could not be determined");
1417     return xpad;}
1418   Int_t iplate =  GetPlate(posLocal);
1419   if(iplate == -1){
1420     //AliError("Detector Index could not be determined");
1421     return xpad;} 
1422   Int_t istrip =  GetStrip(posLocal);
1423   if(istrip == -1){  
1424     //AliError("Detector Index could not be determined");
1425     return xpad;}
1426   Int_t ipadz =  GetPadZ(posLocal);
1427   if(ipadz == -1){  
1428     //AliError("Detector Index could not be determined");
1429     return xpad;}
1430   Int_t ipadx =  GetPadX(posLocal);
1431   if(ipadx == -1){
1432     //AliError("Detector Index could not be determined");
1433     return xpad;}
1434
1435   // ALICE reference frame -> B071/B074/B075 = BTO1/2/3 reference frame
1436   Double_t angles[6] = 
1437     {90., 90.+(isector+0.5)*fgkPhiSec,
1438       0.,  0.,
1439      90., (isector+0.5)*fgkPhiSec
1440     };
1441   Rotation(posLocal,angles);
1442
1443   Float_t step[3] = {0., 0., (fgkRmax+fgkRmin)*0.5};
1444   Translation(posLocal,step);
1445
1446   // B071/B074/B075 = BTO1/2/3 reference frame -> FTOA/B/C = FLTA/B/C reference frame
1447   angles[0] = 90.;
1448   angles[1] =  0.;
1449   angles[2] =  0.;
1450   angles[3] =  0.;
1451   angles[4] = 90.;
1452   angles[5] =270.;
1453
1454   Rotation(posLocal,angles);
1455
1456   // FTOA/B/C = FLTA/B/C reference frame -> FSTR reference frame
1457   step[0] = 0.;
1458   step[1] = GetHeights(iplate,istrip);
1459   step[2] = -GetDistances(iplate,istrip);
1460   Translation(posLocal,step);
1461
1462   if      (GetAngles(iplate,istrip) >0.) {
1463     angles[0] = 90.;
1464     angles[1] =  0.;
1465     angles[2] = 90.+GetAngles(iplate,istrip);
1466     angles[3] = 90.;
1467     angles[4] = GetAngles(iplate,istrip);
1468     angles[5] = 90.;
1469   }
1470   else if (GetAngles(iplate,istrip)==0.) {
1471     angles[0] = 90.;
1472     angles[1] =  0.;
1473     angles[2] = 90.;
1474     angles[3] = 90.;
1475     angles[4] =  0;
1476     angles[5] =  0.;
1477   }
1478   else if (GetAngles(iplate,istrip) <0.) {
1479     angles[0] = 90.;
1480     angles[1] =  0.;
1481     angles[2] = 90.+GetAngles(iplate,istrip);
1482     angles[3] = 90.;
1483     angles[4] =-GetAngles(iplate,istrip);
1484     angles[5] = 270.;
1485   }
1486   Rotation(posLocal,angles);
1487
1488   step[0] =-0.5*kNpadX*fgkXPad;
1489   step[1] = 0.;
1490   step[2] =-0.5*kNpadZ*fgkZPad;
1491   Translation(posLocal,step);
1492
1493   step[0] = (ipadx+0.5)*fgkXPad;
1494   step[1] = 0.;
1495   step[2] = (ipadz+0.5)*fgkZPad;
1496   Translation(posLocal,step);
1497   
1498   xpad=posLocal[0];
1499
1500   return xpad;
1501
1502 }
1503 //_____________________________________________________________________________
1504 Float_t AliTOFGeometry::GetPadDy(Float_t *pos)
1505 {
1506   //
1507   // Returns the y coordinate in the Pad reference frame
1508   //
1509
1510   Float_t ypad = -2.;
1511
1512   Float_t posLocal[3];
1513   for (Int_t ii=0; ii<3; ii++) posLocal[ii] = pos[ii];
1514  
1515   Int_t isector = GetSector(posLocal);
1516   if(isector == -1){
1517     //AliError("Detector Index could not be determined");
1518     return ypad;}
1519   Int_t iplate =  GetPlate(posLocal);
1520   if(iplate == -1){
1521     //AliError("Detector Index could not be determined");
1522     return ypad;} 
1523   Int_t istrip =  GetStrip(posLocal);
1524   if(istrip == -1){  
1525     //AliError("Detector Index could not be determined");
1526     return ypad;}
1527   Int_t ipadz =  GetPadZ(posLocal);
1528   if(ipadz == -1){  
1529     //AliError("Detector Index could not be determined");
1530     return ypad;}
1531   Int_t ipadx =  GetPadX(posLocal);
1532   if(ipadx == -1){
1533     //AliError("Detector Index could not be determined");
1534     return ypad;}
1535
1536   // ALICE reference frame -> B071/B074/B075 = BTO1/2/3 reference frame
1537   Double_t angles[6] = 
1538     {90., 90.+(isector+0.5)*fgkPhiSec,
1539       0.,  0.,
1540      90., (isector+0.5)*fgkPhiSec
1541     };
1542   Rotation(posLocal,angles);
1543
1544   Float_t step[3] = {0., 0., (fgkRmax+fgkRmin)*0.5};
1545   Translation(posLocal,step);
1546
1547   // B071/B074/B075 = BTO1/2/3 reference frame -> FTOA/B/C = FLTA/B/C reference frame
1548   angles[0] = 90.;
1549   angles[1] =  0.;
1550   angles[2] =  0.;
1551   angles[3] =  0.;
1552   angles[4] = 90.;
1553   angles[5] =270.;
1554
1555   Rotation(posLocal,angles);
1556
1557   // FTOA/B/C = FLTA/B/C reference frame -> FSTR reference frame
1558   step[0] = 0.;
1559   step[1] = GetHeights(iplate,istrip);
1560   step[2] = -GetDistances(iplate,istrip);
1561   Translation(posLocal,step);
1562
1563   if      (GetAngles(iplate,istrip) >0.) {
1564     angles[0] = 90.;
1565     angles[1] =  0.;
1566     angles[2] = 90.+GetAngles(iplate,istrip);
1567     angles[3] = 90.;
1568     angles[4] = GetAngles(iplate,istrip);
1569     angles[5] = 90.;
1570   }
1571   else if (GetAngles(iplate,istrip)==0.) {
1572     angles[0] = 90.;
1573     angles[1] =  0.;
1574     angles[2] = 90.;
1575     angles[3] = 90.;
1576     angles[4] =  0;
1577     angles[5] =  0.;
1578   }
1579   else if (GetAngles(iplate,istrip) <0.) {
1580     angles[0] = 90.;
1581     angles[1] =  0.;
1582     angles[2] = 90.+GetAngles(iplate,istrip);
1583     angles[3] = 90.;
1584     angles[4] =-GetAngles(iplate,istrip);
1585     angles[5] = 270.;
1586   }
1587   Rotation(posLocal,angles);
1588
1589   step[0] =-0.5*kNpadX*fgkXPad;
1590   step[1] = 0.;
1591   step[2] =-0.5*kNpadZ*fgkZPad;
1592   Translation(posLocal,step);
1593   
1594   step[0] = (ipadx+0.5)*fgkXPad;
1595   step[1] = 0.;
1596   step[2] = (ipadz+0.5)*fgkZPad;
1597   Translation(posLocal,step);
1598   
1599   ypad=posLocal[1];
1600   
1601   return ypad;
1602
1603 }
1604 //_____________________________________________________________________________
1605 Float_t AliTOFGeometry::GetPadDz(Float_t *pos)
1606 {
1607   //
1608   // Returns the z coordinate in the Pad reference frame
1609   //
1610
1611   Float_t zpad = -2.;
1612
1613   Float_t posLocal[3];
1614   for (Int_t ii=0; ii<3; ii++) posLocal[ii] = pos[ii];
1615  
1616   Int_t isector = GetSector(posLocal);
1617   if(isector == -1){
1618     //AliError("Detector Index could not be determined");
1619     return zpad;}
1620   Int_t iplate =  GetPlate(posLocal);
1621   if(iplate == -1){
1622     //AliError("Detector Index could not be determined");
1623     return zpad;} 
1624   Int_t istrip =  GetStrip(posLocal);
1625   if(istrip == -1){  
1626     //AliError("Detector Index could not be determined");
1627     return zpad;}
1628   Int_t ipadz =  GetPadZ(posLocal);
1629   if(ipadz == -1){  
1630     //AliError("Detector Index could not be determined");
1631     return zpad;}
1632   Int_t ipadx =  GetPadX(posLocal);
1633   if(ipadx == -1){
1634     //AliError("Detector Index could not be determined");
1635     return zpad;}
1636
1637   // ALICE reference frame -> B071/B074/B075 = BTO1/2/3 reference frame
1638   Double_t angles[6] = 
1639     {90., 90.+(isector+0.5)*fgkPhiSec,
1640       0.,  0.,
1641      90., (isector+0.5)*fgkPhiSec
1642     };
1643   Rotation(posLocal,angles);
1644
1645   Float_t step[3] = {0., 0., (fgkRmax+fgkRmin)*0.5};
1646   Translation(posLocal,step);
1647
1648   // B071/B074/B075 = BTO1/2/3 reference frame -> FTOA/B/C = FLTA/B/C reference frame
1649   angles[0] = 90.;
1650   angles[1] =  0.;
1651   angles[2] =  0.;
1652   angles[3] =  0.;
1653   angles[4] = 90.;
1654   angles[5] =270.;
1655
1656   Rotation(posLocal,angles);
1657
1658   // FTOA/B/C = FLTA/B/C reference frame -> FSTR reference frame
1659   step[0] = 0.;
1660   step[1] = GetHeights(iplate,istrip);
1661   step[2] = -GetDistances(iplate,istrip);
1662   Translation(posLocal,step);
1663
1664   if      (GetAngles(iplate,istrip) >0.) {
1665     angles[0] = 90.;
1666     angles[1] =  0.;
1667     angles[2] = 90.+GetAngles(iplate,istrip);
1668     angles[3] = 90.;
1669     angles[4] = GetAngles(iplate,istrip);
1670     angles[5] = 90.;
1671   }
1672   else if (GetAngles(iplate,istrip)==0.) {
1673     angles[0] = 90.;
1674     angles[1] =  0.;
1675     angles[2] = 90.;
1676     angles[3] = 90.;
1677     angles[4] =  0;
1678     angles[5] =  0.;
1679   }
1680   else if (GetAngles(iplate,istrip) <0.) {
1681     angles[0] = 90.;
1682     angles[1] =  0.;
1683     angles[2] = 90.+GetAngles(iplate,istrip);
1684     angles[3] = 90.;
1685     angles[4] =-GetAngles(iplate,istrip);
1686     angles[5] = 270.;
1687   }
1688   Rotation(posLocal,angles);
1689
1690   step[0] =-0.5*kNpadX*fgkXPad;
1691   step[1] = 0.;
1692   step[2] =-0.5*kNpadZ*fgkZPad;
1693   Translation(posLocal,step);
1694   
1695   step[0] = (ipadx+0.5)*fgkXPad;
1696   step[1] = 0.;
1697   step[2] = (ipadz+0.5)*fgkZPad;
1698   Translation(posLocal,step);
1699
1700   zpad=posLocal[2];
1701
1702   return zpad;
1703
1704 }
1705 //_____________________________________________________________________________
1706
1707 void AliTOFGeometry::Translation(Float_t *xyz, Float_t translationVector[3]) const
1708 {
1709   //
1710   // Return the vector xyz translated by translationVector vector
1711   //
1712
1713   Int_t ii=0;
1714
1715   for (ii=0; ii<3; ii++)
1716     xyz[ii] -= translationVector[ii];
1717
1718   return;
1719
1720 }
1721 //_____________________________________________________________________________
1722
1723 void AliTOFGeometry::Rotation(Float_t *xyz, Double_t rotationAngles[6]) const
1724 {
1725   //
1726   // Return the vector xyz rotated according to the rotationAngles angles
1727   //
1728
1729   Int_t ii=0;
1730   /*
1731   TRotMatrix *matrix = new TRotMatrix("matrix","matrix", angles[0], angles[1],
1732                                       angles[2], angles[3],
1733                                       angles[4], angles[5]);
1734   */
1735
1736   for (ii=0; ii<6; ii++) rotationAngles[ii]*=kDegrad;
1737
1738   Float_t xyzDummy[3] = {0., 0., 0.};
1739
1740   for (ii=0; ii<3; ii++) {
1741     xyzDummy[ii] =
1742       xyz[0]*TMath::Sin(rotationAngles[2*ii])*TMath::Cos(rotationAngles[2*ii+1]) +
1743       xyz[1]*TMath::Sin(rotationAngles[2*ii])*TMath::Sin(rotationAngles[2*ii+1]) +
1744       xyz[2]*TMath::Cos(rotationAngles[2*ii]);
1745   }
1746
1747   for (ii=0; ii<3; ii++) xyz[ii]=xyzDummy[ii];
1748
1749   return;
1750
1751 }
1752 //_____________________________________________________________________________
1753 void AliTOFGeometry::InverseRotation(Float_t *xyz, Double_t rotationAngles[6]) const
1754 {
1755   //
1756   //
1757   //
1758
1759   Int_t ii=0;
1760
1761   for (ii=0; ii<6; ii++) rotationAngles[ii]*=kDegrad;
1762
1763   Float_t xyzDummy[3] = {0., 0., 0.};
1764
1765   xyzDummy[0] =
1766     xyz[0]*TMath::Sin(rotationAngles[0])*TMath::Cos(rotationAngles[1]) +
1767     xyz[1]*TMath::Sin(rotationAngles[2])*TMath::Cos(rotationAngles[3]) +
1768     xyz[2]*TMath::Sin(rotationAngles[4])*TMath::Cos(rotationAngles[5]);
1769   
1770   xyzDummy[1] =
1771     xyz[0]*TMath::Sin(rotationAngles[0])*TMath::Sin(rotationAngles[1]) +
1772     xyz[1]*TMath::Sin(rotationAngles[2])*TMath::Sin(rotationAngles[3]) +
1773     xyz[2]*TMath::Sin(rotationAngles[4])*TMath::Sin(rotationAngles[5]);
1774   
1775   xyzDummy[2] =
1776     xyz[0]*TMath::Cos(rotationAngles[0]) +
1777     xyz[1]*TMath::Cos(rotationAngles[2]) +
1778     xyz[2]*TMath::Cos(rotationAngles[4]);
1779   
1780   for (ii=0; ii<3; ii++) xyz[ii]=xyzDummy[ii];
1781
1782   return;
1783
1784 }
1785 //_____________________________________________________________________________
1786
1787 Int_t AliTOFGeometry::GetIndex(Int_t *detId)
1788 {
1789   //Retrieve calibration channel index 
1790   Int_t isector = detId[0];
1791   if (isector >= kNSectors){
1792     printf("Wrong sector number in TOF (%d) !\n",isector);
1793     return -1;
1794   }
1795   Int_t iplate = detId[1];
1796   if (iplate >= kNPlates){
1797     printf("Wrong plate number in TOF (%d) !\n",iplate);
1798     return -1;
1799   }
1800   Int_t istrip = detId[2];
1801   Int_t stripOffset = GetStripNumberPerSM(iplate,istrip);
1802   if (stripOffset==-1) {
1803     printf("Wrong strip number per SM in TOF (%d) !\n",stripOffset);
1804     return -1;
1805   }
1806
1807   Int_t ipadz = detId[3];
1808   Int_t ipadx = detId[4];
1809
1810   Int_t idet = ((2*(kNStripC+kNStripB)+kNStripA)*kNpadZ*kNpadX)*isector +
1811                (stripOffset*kNpadZ*kNpadX)+
1812                (kNpadX)*ipadz+
1813                 ipadx;
1814   return idet;
1815 }
1816 //_____________________________________________________________________________
1817
1818 void AliTOFGeometry::GetVolumeIndices(Int_t index, Int_t *detId)
1819 {
1820   //
1821   // Retrieve volume indices from the calibration channel index 
1822   //
1823
1824   detId[0] = index/NpadXStrip()/NStripXSector();
1825
1826   Int_t dummyStripPerModule = 
1827     ( index - ( NStripXSector()*NpadXStrip()*detId[0]) ) / NpadXStrip();
1828   if (dummyStripPerModule<kNStripC) {
1829     detId[1] = 0;
1830     detId[2] = dummyStripPerModule;
1831   }
1832   else if (dummyStripPerModule>=kNStripC && dummyStripPerModule<kNStripC+kNStripB) {
1833     detId[1] = 1;
1834     detId[2] = dummyStripPerModule-kNStripC;
1835   }
1836   else if (dummyStripPerModule>=kNStripC+kNStripB && dummyStripPerModule<kNStripC+kNStripB+kNStripA) {
1837     detId[1] = 2;
1838     detId[2] = dummyStripPerModule-kNStripC-kNStripB;
1839   }
1840   else if (dummyStripPerModule>=kNStripC+kNStripB+kNStripA && dummyStripPerModule<kNStripC+kNStripB+kNStripA+kNStripB) {
1841     detId[1] = 3;
1842     detId[2] = dummyStripPerModule-kNStripC-kNStripB-kNStripA;
1843   }
1844   else if (dummyStripPerModule>=kNStripC+kNStripB+kNStripA+kNStripB && dummyStripPerModule<NStripXSector()) {
1845     detId[1] = 4;
1846     detId[2] = dummyStripPerModule-kNStripC-kNStripB-kNStripA-kNStripB;
1847   }
1848
1849   Int_t padPerStrip = ( index - ( NStripXSector()*NpadXStrip()*detId[0]) ) - dummyStripPerModule*NpadXStrip();
1850
1851   detId[3] = padPerStrip / kNpadX; // padZ
1852   detId[4] = padPerStrip - detId[3]*kNpadX; // padX
1853
1854 }
1855 //_____________________________________________________________________________
1856
1857 Int_t AliTOFGeometry::NStrip(Int_t nPlate)
1858 {
1859   //
1860   // Returns the strips number for the plate number 'nPlate'
1861   //
1862
1863   Int_t nStrips = kNStripC;
1864
1865   switch(nPlate) {
1866   case 2:
1867     nStrips = kNStripA;
1868     break;
1869   case 1:
1870   case 3:
1871     nStrips = kNStripB;
1872     break;
1873   case 0:
1874   case 4:
1875   default:
1876     nStrips = kNStripC;
1877     break;
1878   }
1879
1880   return nStrips;
1881
1882 }
1883 //-------------------------------------------------------------------------
1884
1885 UShort_t AliTOFGeometry::GetAliSensVolIndex(Int_t isector, Int_t iplate, Int_t istrip) const
1886 {
1887   //
1888   // Get the index of the TOF alignable volume in the AliGeomManager order.
1889   //
1890
1891   Int_t index = GetStripNumber(isector, iplate, istrip);
1892
1893   UShort_t volIndex = AliGeomManager::LayerToVolUID(AliGeomManager::kTOF,index);
1894
1895   return volIndex;
1896
1897 }
1898 //-------------------------------------------------------------------------
1899
1900 Int_t AliTOFGeometry::GetStripNumber(Int_t isector, Int_t iplate, Int_t istrip)
1901 {
1902   //
1903   // Get the serial number of the TOF strip number istrip [0,14/18],
1904   //   in the module number iplate [0,4],
1905   //   in the TOF SM number isector [0,17].
1906   // This number will range in [0,1637].
1907   //
1908
1909   Bool_t check = (isector >= kNSectors);
1910
1911   if (check)
1912     printf("E-AliTOFGeometry::GetStripNumber: Wrong sector number in TOF (%d)!\n",isector);
1913
1914   Int_t index = -1;
1915   Int_t stripInSM = GetStripNumberPerSM(iplate, istrip);
1916   if (!check && stripInSM!=-1)
1917     index = (2*(kNStripC+kNStripB)+kNStripA)*isector + stripInSM;
1918
1919   return index;
1920
1921 }
1922 //-------------------------------------------------------------------------
1923
1924 Int_t AliTOFGeometry::GetStripNumberPerSM(Int_t iplate, Int_t istrip)
1925 {
1926   //
1927   // Get the serial number of the TOF strip number istrip [0,14/18],
1928   //   in the module number iplate [0,4].
1929   // This number will range in [0,90].
1930   //
1931
1932   Int_t index = -1;
1933
1934   Bool_t check = (
1935                   (iplate<0 || iplate>=kNPlates)
1936                   ||
1937                   (
1938                    (iplate==2 && (istrip<0 || istrip>=kNStripA))
1939                    ||
1940                    (iplate!=2 && (istrip<0 || istrip>=kNStripC))
1941                    )
1942                   );
1943
1944   if (iplate<0 || iplate>=kNPlates)
1945     printf("E-AliTOFGeometry::GetStripNumberPerSM: Wrong plate number in TOF (%1d)!\n",iplate);
1946
1947   if (
1948       (iplate==2 && (istrip<0 || istrip>=kNStripA))
1949       ||
1950       (iplate!=2 && (istrip<0 || istrip>=kNStripC))
1951       )
1952     printf("E-AliTOFGeometry::GetStripNumberPerSM: Wrong strip number in TOF "
1953            "(strip=%2d in the plate=%1d)!\n",istrip,iplate);
1954
1955   Int_t stripOffset = 0;
1956   switch (iplate) {
1957   case 0:
1958     stripOffset = 0;
1959     break;
1960   case 1:
1961     stripOffset = kNStripC;
1962     break;
1963   case 2:
1964     stripOffset = kNStripC+kNStripB;
1965     break;
1966   case 3:
1967     stripOffset = kNStripC+kNStripB+kNStripA;
1968     break;
1969   case 4:
1970     stripOffset = kNStripC+kNStripB+kNStripA+kNStripB;
1971     break;
1972   };
1973
1974   if (!check) index = stripOffset + istrip;
1975
1976   return index;
1977
1978 }
1979 //-------------------------------------------------------------------------
1980
1981 void AliTOFGeometry::PadRF2TrackingRF(Float_t *ctrackPos, Float_t *differenceT)
1982 {
1983   //
1984   // To convert the 3D distance ctrackPos, referred to the ALICE RF,
1985   // into the 3D distance differenceT, referred to the tracking RF
1986   // in case ctrakPos belongs to a TOF sensitive volume.
1987   //
1988
1989   for (Int_t ii=0; ii<3; ii++) differenceT[ii] = 999.;
1990
1991   AliDebug(1,Form(" track position in ALICE global Ref. frame -> %f, %f, %f",
1992                   ctrackPos[0],ctrackPos[1],ctrackPos[2]));
1993
1994   Int_t detId[5] = {-1,-1,-1,-1,-1};
1995
1996   detId[0] = GetSector(ctrackPos);
1997   if (detId[0]==-1) {
1998     AliWarning(Form("This point does not belong to any TOF sector"));
1999     return;
2000   }
2001
2002   detId[1] = GetPlate(ctrackPos);
2003   if (detId[1]==-1) {
2004     AliWarning(Form("This point does not belong to any TOF module"));
2005     return;
2006   }
2007
2008   detId[2] = GetStrip(ctrackPos);
2009   if (detId[2]==-1) {
2010     AliWarning(Form("This point does not belong to any TOF strip"));
2011     return;
2012   }
2013
2014   detId[3] = GetPadZ(ctrackPos);
2015   if (detId[3]==-1) {
2016     AliWarning(Form("This point does not belong to any TOF pad-row"));
2017     return;
2018   }
2019
2020   detId[4] = GetPadX(ctrackPos);
2021   if (detId[4]==-1) {
2022     AliWarning(Form("This point does not belong to any TOF pad"));
2023     return;
2024   }
2025
2026
2027   UShort_t alignableStripIndex =
2028     GetAliSensVolIndex(detId[0],detId[1],detId[2]);
2029   AliDebug(1,Form(" sector = %2d, plate = %1d, strip = %2d (padZ = %1d, padX = %2d) "
2030                   "---> stripIndex = %4d",
2031                   detId[0], detId[1], detId[2], detId[3], detId[4], alignableStripIndex));
2032
2033   // pad centre coordinates in the strip ref. frame
2034   Double_t padCentreL[3] = {(detId[4]-AliTOFGeometry::NpadX()/2)*AliTOFGeometry::XPad()
2035                             +AliTOFGeometry::XPad()/2.,
2036                             0.,
2037                             (detId[3]-AliTOFGeometry::NpadZ()/2)*AliTOFGeometry::XPad()
2038                             +AliTOFGeometry::XPad()/2.};
2039   // pad centre coordinates in the strip tracking frame
2040   Double_t padCentreT[3] = {0., 0., 0.};
2041   TGeoHMatrix l2t = *AliGeomManager::GetTracking2LocalMatrix(alignableStripIndex);
2042   l2t.MasterToLocal(padCentreL,padCentreT);
2043
2044
2045   Char_t path[100];
2046   // pad centre coordinates in its ref. frame
2047   Double_t padCentreL2[3] = {0., 0., 0.};
2048   // pad centre coordinates in the ALICE global ref. frame
2049   Double_t padCentreG[3] = {0., 0., 0.};
2050   GetVolumePath(detId,path);
2051   gGeoManager->cd(path);
2052   TGeoHMatrix g2l = *gGeoManager->GetCurrentMatrix();
2053   TGeoHMatrix l2g = g2l.Inverse();
2054   l2g.MasterToLocal(padCentreL2,padCentreG);
2055
2056
2057   Char_t path2[100];
2058   // strip centre coordinates in its ref. frame
2059   Double_t stripCentreL[3] = {0., 0., 0.};
2060   // strip centre coordinates in the ALICE global ref. frame
2061   Double_t stripCentreG[3] = {0., 0., 0.};
2062   GetVolumePath(detId[0],detId[1],detId[2],path2);
2063   gGeoManager->cd(path2);
2064   TGeoHMatrix g2lb = *gGeoManager->GetCurrentMatrix();
2065   TGeoHMatrix l2gb = g2lb.Inverse();
2066   l2gb.MasterToLocal(stripCentreL,stripCentreG);
2067
2068   TGeoHMatrix g2t = 0;
2069   AliGeomManager::GetTrackingMatrix(alignableStripIndex, g2t);
2070
2071   // track position in the ALICE global ref. frame
2072   Double_t posG[3];
2073   for (Int_t ii=0; ii<3; ii++) posG[ii] = (Double_t)ctrackPos[ii];
2074
2075   // strip centre coordinates in the tracking ref. frame
2076   Double_t stripCentreT[3] = {0., 0., 0.};
2077   // track position in the tracking ref. frame
2078   Double_t posT[3] = {0., 0., 0.};
2079   g2t.MasterToLocal(posG,posT);
2080   g2t.MasterToLocal(stripCentreG,stripCentreT);
2081
2082   for (Int_t ii=0; ii<3; ii++)
2083     AliDebug(1,Form(" track position in ALICE global and tracking RFs -> posG[%d] = %f --- posT[%d] = %f",
2084                     ii, posG[ii], ii, posT[ii]));
2085   for (Int_t ii=0; ii<3; ii++)
2086     AliDebug(1,Form(" pad centre coordinates in its, the ALICE global and tracking RFs -> "
2087                     "padCentreL[%d] = %f --- padCentreG[%d] = %f --- padCentreT[%d] = %f",
2088                     ii, padCentreL[ii],
2089                     ii, padCentreG[ii],
2090                     ii, padCentreT[ii]));
2091   for (Int_t ii=0; ii<3; ii++)
2092     AliDebug(1,Form(" strip centre coordinates in its, the ALICE global and tracking RFs -> "
2093                     "stripCentreL[%d] = %f --- stripCentreG[%d] = %f --- stripCentreT[%d] = %f",
2094                     ii, stripCentreL[ii],
2095                     ii, stripCentreG[ii],
2096                     ii, stripCentreT[ii]));
2097   for (Int_t ii=0; ii<3; ii++)
2098     AliDebug(1,Form(" difference between the track position and the pad centre in the tracking RF "
2099                     "-> posT[%d]-padCentreT[%d] = %f",
2100                     ii,ii,
2101                     posT[ii]-padCentreT[ii]));
2102
2103   for (Int_t ii=0; ii<3; ii++) differenceT[ii] = (Float_t)(posT[ii]-padCentreT[ii]);
2104
2105 }