software update to include time corrections during reconstruction.
[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 const Float_t AliTOFGeometry::fgkBunchCrossingBin = fgkTdcBin * 1024; // bunch-crossing bin width [ps]
153
154 const Float_t AliTOFGeometry::fgkDeadTime = 25E+03;        // Single channel dead time (ps)
155 const Float_t AliTOFGeometry::fgkMatchingWindow = fgkTdcBin*TMath::Power(2,13); // Matching window  (ps)
156
157 const Float_t AliTOFGeometry::fgkAngles[kNPlates][kMaxNstrip] = {
158     { 43.99,  43.20,  42.40,  41.59,  40.77,  39.94,  39.11,  38.25,  37.40,  36.53,
159       35.65,  34.76,  33.87,  32.96,  32.05,  31.13,  30.19,  29.24,  12.33,  0.00},
160
161     { 27.26,  26.28,  25.30,  24.31,  23.31,  22.31,  21.30,  20.29,  19.26,  18.24,
162       17.20,  16.16,  15.11,  14.05,  13.00,  11.93,  10.87,   9.80,   8.74,  0.00},
163
164     {  0.00,   6.30,   5.31,   4.25,   3.19,   2.12,   1.06,   0.00,  -1.06,  -2.12,
165       -3.19,  -4.25,  -5.31,  -6.30,   0.00,   0.00,   0.00,   0.00,   0.00,  0.00},
166
167     { -8.74,  -9.80, -10.87, -11.93, -13.00, -14.05, -15.11, -16.16, -17.20, -18.24,
168      -19.26, -20.29, -21.30, -22.31, -23.31, -24.31, -25.30, -26.28, -27.26,  0.00},
169     
170     {-12.33, -29.24, -30.19, -31.13, -32.05, -32.96, -33.87, -34.76, -35.65, -36.53,
171      -37.40, -38.25, -39.11, -39.94, -40.77, -41.59, -42.40, -43.20, -43.99,  0.00}
172   };
173
174 /*
175 const Float_t AliTOFGeometry::fgkHeights[kNPlates][kMaxNstrip] = {
176     {-8.2,  -7.5,  -8.2,  -7.7,  -8.1,  -7.6,  -7.7,  -7.7,  -7.7,  -7.7,
177      -7.5,  -7.2,  -7.3,  -7.5,  -7.6,  -7.8,  -8.3,  -9.3,  -3.1,   0.0},
178
179     {-7.9,  -8.1,  -8.5,  -9.0, -10.1,  -3.9,  -5.9,  -7.7, -10.1,  -3.6,
180      -5.8,  -8.0, -10.4,  -4.4,  -7.2, -10.2,  -4.6,  -7.4, -10.4,   0.0},
181
182     {-2.5, -10.4,  -5.0,  -9.9,  -4.8,  -9.9,  -4.7, -10.2,  -4.7,  -9.9,
183      -4.8,  -9.9,  -5.0, -10.4,  -2.5,   0.0,   0.0,   0.0,   0.0,   0.0},
184
185     {-10.4, -7.4,  -4.6, -10.2,  -7.2,  -4.4, -10.4,  -8.0,  -5.8,  -3.6,
186      -10.1, -7.7,  -5.9,  -3.9, -10.1,  -9.0,  -8.5,  -8.1,  -7.9,   0.0},
187
188     { -3.1, -9.3,  -8.3,  -7.8,  -7.6,  -7.5,  -7.3,  -7.2,  -7.5,  -7.7,
189       -7.7, -7.7,  -7.7,  -7.6,  -8.1,  -7.7,  -8.2,  -7.5,  -8.2,   0.0}
190   };
191 */
192 /*
193 const Float_t AliTOFGeometry::fgkHeights[kNPlates][kMaxNstrip] = {
194   {  -8.405, -10.885,  -8.405,  -7.765,  -8.285,  -7.745,  -7.865,  -7.905,  -7.895,  -7.885,
195      -7.705,  -7.395,  -7.525,  -7.645, -11.285, -10.355,  -8.365,  -9.385,  -3.255,   0.000 },
196   {  -7.905,  -8.235,  -8.605,  -9.045, -10.205,  -3.975,  -5.915,  -7.765, -10.205,  -3.635,
197      -5.885,  -8.005, -10.505,  -4.395,  -7.325, -10.235,  -4.655,  -7.495, -10.515,   0.000 },
198   {  -2.705, -10.645,  -5.165, -10.095,  -4.995, -10.815,  -4.835, -10.385,  -4.835, -10.815,
199      -4.995, -10.095,  -5.165, -10.645,  -2.705,   0.000,   0.000,   0.000,   0.000,   0.000 },
200   { -10.515,  -7.495,  -4.655, -10.235,  -7.325,  -4.395, -10.505,  -8.005,  -5.885,  -3.635,
201     -10.205,  -7.765,  -5.915,  -3.975, -10.205,  -9.045,  -8.605,  -8.235,  -7.905,   0.000 },
202   {  -3.255,  -9.385,  -8.365, -10.355, -11.285,  -7.645,  -7.525,  -7.395,  -7.705,  -7.885,
203      -7.895,  -7.905,  -7.865,  -7.745,  -8.285,  -7.765,  -8.405, -10.885,  -8.405,   0.000 }
204 };
205 */
206
207
208 const Float_t AliTOFGeometry::fgkHeights[kNPlates][kMaxNstrip] = {
209   { -8.405,  -7.725,  -8.405,  -7.765,  -8.285,  -7.745,  -7.865,  -7.905,  -7.895,  -7.885,
210     -7.705,  -7.395,  -7.525,  -7.645,  -7.835,  -7.965,  -8.365,  -9.385,  -3.255,   0.000 },
211   { -7.905,  -8.235,  -8.605,  -9.045, -10.205,  -3.975,  -5.915,  -7.765, -10.205,  -3.635,
212     -5.885,  -8.005, -10.505,  -4.395,  -7.325, -10.235,  -4.655,  -7.495, -10.515,   0.000 },
213   { -2.705, -10.645,  -5.165, -10.095,  -4.995, -10.085,  -4.835, -10.385,  -4.835, -10.085,
214     -4.995, -10.095,  -5.165, -10.645,  -2.705,   0.000,   0.000,   0.000,   0.000,   0.000 },
215   {-10.515,  -7.495,  -4.655, -10.235,  -7.325,  -4.395, -10.505,  -8.005,  -5.885,  -3.635,
216    -10.205,  -7.765,  -5.915,  -3.975, -10.205,  -9.045,  -8.605,  -8.235,  -7.905,   0.000 },
217   { -3.255,  -9.385,  -8.365,  -7.965,  -7.835,  -7.645,  -7.525,  -7.395,  -7.705,  -7.885,
218     -7.895,  -7.905,  -7.865,  -7.745,  -8.285,  -7.765,  -8.405,  -7.725,  -8.405,   0.000 }
219 };
220
221
222
223 const Float_t AliTOFGeometry::fgkDistances[kNPlates][kMaxNstrip] = {
224   { 364.14,  354.88,  344.49,  335.31,  325.44,  316.51,  307.11,  297.91,  288.84,  279.89,
225     271.20,  262.62,  253.84,  245.20,  236.56,  228.06,  219.46,  210.63,  206.09,    0.00 },
226   { 194.57,  186.38,  178.25,  170.13,  161.78,  156.62,  148.10,  139.72,  131.23,  125.87,
227     117.61,  109.44,  101.29,   95.46,   87.36,   79.37,   73.17,   65.33,   57.71,    0.00 },
228   {  49.28,   41.35,   35.37,   27.91,   21.20,   13.94,    7.06,    0.00,   -7.06,  -13.94,
229     -21.20,  -27.91,  -35.37,  -41.35,  -49.28,    0.00,    0.00,    0.00,    0.00,    0.00 },
230   { -57.71,  -65.33,  -73.17,  -79.37,  -87.36,  -95.46, -101.29, -109.44, -117.61, -125.87,
231    -131.23, -139.72, -148.10, -156.62, -161.78, -170.13, -178.25, -186.38, -194.57,    0.00 },
232   {-206.09, -210.63, -219.46, -228.06, -236.56, -245.20, -253.84, -262.62, -271.20, -279.89,
233    -288.84, -297.91, -307.11, -316.51, -325.44, -335.31, -344.49, -354.88, -364.14,    0.00 }
234 };
235
236 /*
237 const Float_t AliTOFGeometry::fgkDistances[kNPlates][kMaxNstrip] = {
238     { 364.1,  354.9,  344.5,  335.4,  325.5,  316.6,  307.2,  298.0,  288.9,  280.0,
239       271.3,  262.7,  254.0,  244.8,  236.1,  227.7,  219.1,  210.3,  205.7,    0.0},
240
241     { 194.2,  186.1,  177.9,  169.8,  161.5,  156.3,  147.8,  139.4,  130.9,  125.6,
242       117.3,  109.2,  101.1,   95.3,   87.1,   79.2,   73.0,   65.1,   57.6,    0.0},
243
244     {  49.5,   41.3,   35.3,   27.8,   21.2,   13.9,    7.0,    0.0,   -7.0,  -13.9,
245       -21.2,  -27.8,  -35.3,  -41.3,  -49.5,    0.0,    0.0,    0.0,    0.0,    0.0},
246
247     { -57.6,  -65.1,  -73.0,  -79.2,  -87.1,  -95.3, -101.1, -109.2, -117.3, -125.6,
248      -130.9, -139.4, -147.8, -156.3, -161.5, -169.8, -177.9, -186.1, -194.2,    0.0},
249
250     {-205.7, -210.3, -219.1, -227.7, -236.1, -244.8, -254.0, -262.7, -271.3, -280.0,
251      -288.9, -298.0, -307.2, -316.6, -325.5, -335.4, -344.5, -354.9, -364.1,    0.0}
252   };
253 */
254 //_____________________________________________________________________________
255 AliTOFGeometry::AliTOFGeometry():
256   fHoles(1)
257 {
258   //
259   // AliTOFGeometry default constructor
260   //
261
262 }
263
264 //_____________________________________________________________________________
265 AliTOFGeometry::~AliTOFGeometry()
266 {
267   //
268   // AliTOFGeometry destructor
269   //
270 }
271 //_____________________________________________________________________________
272 void AliTOFGeometry::ImportGeometry(){
273   TGeoManager::Import("geometry.root");
274 }
275 //_____________________________________________________________________________
276 void AliTOFGeometry::GetPosPar(Int_t *det, Float_t *pos) const
277 {
278 //
279 // Returns space point coor (x,y,z) (cm)  for Detector 
280 // Indices  (iSect,iPlate,iStrip,iPadX,iPadZ) 
281 //
282
283   pos[0]=GetX(det);  
284   pos[1]=GetY(det);  
285   pos[2]=GetZ(det);
286   
287 }
288 //_____________________________________________________________________________
289 void AliTOFGeometry::GetDetID( Float_t *pos, Int_t *det) const
290 {
291  //
292  // Returns Detector Indices (iSect,iPlate,iStrip,iPadX,iPadZ) 
293  // space point coor (x,y,z) (cm)  
294
295
296   det[0]=GetSector(pos);  
297   det[1]=GetPlate(pos);  
298   det[2]=GetStrip(pos);
299   det[3]=GetPadZ(pos);
300   det[4]=GetPadX(pos);
301   
302 }
303 //_____________________________________________________________________________
304
305 void AliTOFGeometry::DetToStripRF(Int_t nPadX, Int_t nPadZ, Float_t &x,  Float_t &z) const
306 {
307   //
308   // Returns the local coordinates (x, z) in strip reference frame
309   // for the bottom corner of the pad number (nPadX, nPadZ)
310   //
311   /*
312   const Float_t xCenterStrip = kNpadX * fgkXPad / 2.;
313   const Float_t zCenterStrip = kNpadZ * fgkZPad / 2.;
314
315   const Float_t xCenterPad = nPadX*fgkXPad + fgkXPad / 2.;
316   const Float_t zCenterPad = nPadZ*fgkZPad + fgkZPad / 2.;
317
318   x = xCenterPad - xCenterStrip;
319   z = zCenterPad - zCenterStrip;
320   */
321
322
323   x = (nPadX - kNpadX*0.5) * fgkXPad;
324   z = (nPadZ - kNpadZ*0.5) * fgkZPad;
325
326
327 }
328 //_____________________________________________________________________________
329 Float_t AliTOFGeometry::DistanceToPadPar(Int_t *det, const Float_t * const pos, Float_t *dist3d) const
330 {
331 //
332 // Returns distance of  space point with coor pos (x,y,z) (cm) wrt 
333 // pad with Detector Indices idet (iSect,iPlate,iStrip,iPadX,iPadZ) 
334 //
335     
336   //Transform pos into Sector Frame
337
338   Float_t x = pos[0];
339   Float_t y = pos[1];
340   Float_t z = pos[2];
341
342   Float_t radius = TMath::Sqrt(x*x+y*y);
343   //Float_t phi=TMath::ATan(y/x);       
344   //if(phi<0) phi = k2PI+phi; //2.*TMath::Pi()+phi;
345   Float_t phi = TMath::Pi()+TMath::ATan2(-y,-x);        
346   //  Get the local angle in the sector philoc
347   Float_t angle   = phi*kRaddeg-( Int_t (kRaddeg*phi/fgkPhiSec) + 0.5)*fgkPhiSec;
348   Float_t xs = radius*TMath::Cos(angle/kRaddeg);
349   Float_t ys = radius*TMath::Sin(angle/kRaddeg);
350   Float_t zs = z;
351
352   // Do the same for the selected pad
353
354   Float_t g[3];
355   GetPosPar(det,g);
356
357   Float_t padRadius = TMath::Sqrt(g[0]*g[0]+g[1]*g[1]);
358   //Float_t padPhi = TMath::ATan(g[1]/g[0]);    
359   //if(padPhi<0) padPhi = k2Pi + padPhi;
360   Float_t padPhi = TMath::Pi()+TMath::ATan2(-g[1],-g[0]);       
361
362   //  Get the local angle in the sector philoc
363   Float_t padAngle = padPhi*kRaddeg-( Int_t (padPhi*kRaddeg/fgkPhiSec)+ 0.5) * fgkPhiSec;
364   Float_t padxs = padRadius*TMath::Cos(padAngle/kRaddeg);
365   Float_t padys = padRadius*TMath::Sin(padAngle/kRaddeg);
366   Float_t padzs = g[2];
367   
368   //Now move to local pad coordinate frame. Translate:
369   
370   Float_t xt = xs-padxs;
371   Float_t yt = ys-padys;
372   Float_t zt = zs-padzs;
373   //Now Rotate:
374   
375   Float_t alpha = GetAngles(det[1],det[2]);
376   Float_t xr =  xt*TMath::Cos(alpha/kRaddeg)+zt*TMath::Sin(alpha/kRaddeg);
377   Float_t yr =  yt;
378   Float_t zr = -xt*TMath::Sin(alpha/kRaddeg)+zt*TMath::Cos(alpha/kRaddeg);
379
380   Float_t dist = TMath::Sqrt(xr*xr+yr*yr+zr*zr);
381
382   if (dist3d){
383     dist3d[0] = xr;
384     dist3d[1] = yr;
385     dist3d[2] = zr;
386   }
387
388   return dist;
389
390 }
391 //_____________________________________________________________________________
392 Bool_t AliTOFGeometry::IsInsideThePadPar(Int_t *det, const Float_t * const pos) const
393 {
394 //
395 // Returns true if space point with coor pos (x,y,z) (cm) falls 
396 // inside pad with Detector Indices idet (iSect,iPlate,iStrip,iPadX,iPadZ) 
397 //
398
399   Bool_t isInside=false; 
400
401   /*
402   const Float_t khhony    = 1.0          ; // heigth of HONY  Layer
403   const Float_t khpcby    = 0.08         ; // heigth of PCB   Layer
404   const Float_t khrgly    = 0.055        ; // heigth of RED GLASS  Layer
405   const Float_t khglfy    = 0.285        ; // heigth of GLASS+FISHLINE  Layer
406   const Float_t khcpcby   = 0.16         ; // heigth of PCB  Central Layer
407   //const Float_t kwcpcbz   = 12.4         ; // z dimension of PCB  Central Layer
408   const Float_t khstripy = 2.*khhony+2.*khpcby+4.*khrgly+2.*khglfy+khcpcby;//3.11
409   //const Float_t kwstripz = kwcpcbz;
410   //const Float_t klstripx = fgkStripLength;
411   */
412
413   const Float_t kPadDepth = 0.5;//0.05;//0.11;//0.16;//          // heigth of Sensitive Layer
414
415   //Transform pos into Sector Frame
416
417   Float_t x = pos[0];
418   Float_t y = pos[1];
419   Float_t z = pos[2];
420
421   Float_t radius = TMath::Sqrt(x*x+y*y);
422   Float_t phi = TMath::Pi()+TMath::ATan2(-y,-x);        
423
424   //  Get the local angle in the sector philoc
425   Float_t angle = phi*kRaddeg-( Int_t (kRaddeg*phi/fgkPhiSec) + 0.5) *fgkPhiSec;
426   Float_t xs = radius*TMath::Cos(angle/kRaddeg);
427   Float_t ys = radius*TMath::Sin(angle/kRaddeg);
428   Float_t zs = z;
429
430   // Do the same for the selected pad
431
432   Float_t g[3];
433   GetPosPar(det,g);
434
435   Float_t padRadius = TMath::Sqrt(g[0]*g[0]+g[1]*g[1]);
436   Float_t padPhi = TMath::Pi()+TMath::ATan2(-g[1],-g[0]);       
437
438   //  Get the local angle in the sector philoc
439   Float_t padAngle = padPhi*kRaddeg-( Int_t (padPhi*kRaddeg/fgkPhiSec)+ 0.5) * fgkPhiSec; 
440   Float_t padxs = padRadius*TMath::Cos(padAngle/kRaddeg);
441   Float_t padys = padRadius*TMath::Sin(padAngle/kRaddeg);
442   Float_t padzs = g[2];
443
444   //Now move to local pad coordinate frame. Translate:
445
446   Float_t xt = xs-padxs;
447   Float_t yt = ys-padys;
448   Float_t zt = zs-padzs;
449
450   //Now Rotate:
451
452   Float_t alpha = GetAngles(det[1],det[2]);
453   Float_t xr =  xt*TMath::Cos(alpha/kRaddeg)+zt*TMath::Sin(alpha/kRaddeg);
454   Float_t yr =  yt;
455   Float_t zr = -xt*TMath::Sin(alpha/kRaddeg)+zt*TMath::Cos(alpha/kRaddeg);
456
457   if(TMath::Abs(xr)<=kPadDepth*0.5 && TMath::Abs(yr)<= (fgkXPad*0.5) && TMath::Abs(zr)<= (fgkZPad*0.5))
458     isInside=true;
459   return isInside;
460
461 }
462 //_____________________________________________________________________________
463 Bool_t AliTOFGeometry::IsInsideThePad(TGeoHMatrix mat, const Float_t * const pos, Float_t *dist3d) const
464 {
465   //
466   // Returns true if space point with coor pos (x,y,z) [cm] falls inside
467   // pad identified by the matrix mat. In case dist3d!=0, dist3d vector
468   // has been filled with the 3D distance between the impact point on
469   // the pad and the pad centre (in the reference frame of the TOF pad
470   // identified by the matrix mat).
471   //
472
473   const Float_t kPadDepth = 0.5;      // heigth of Sensitive Layer
474
475   Double_t posg[3];
476   posg[0] = pos[0];
477   posg[1] = pos[1];
478   posg[2] = pos[2];
479
480   // from ALICE global reference system
481   // towards TOF pad reference system
482   Double_t posl[3] = {0., 0., 0.};
483   mat.MasterToLocal(posg,posl);
484
485   Float_t xr = posl[0];
486   Float_t yr = posl[1];
487   Float_t zr = posl[2];
488
489   Bool_t isInside = false;
490   if (TMath::Abs(yr)<= kPadDepth*0.5 &&
491       TMath::Abs(xr)<= fgkXPad*0.5 &&
492       TMath::Abs(zr)<= fgkZPad*0.5)
493     isInside = true;
494
495   if (dist3d) {
496     //Double_t padl[3] = {0., 0., 0.};
497     dist3d[0] = posl[0]/* - padl[0]*/;
498     dist3d[1] = posl[1]/* - padl[1]*/;
499     dist3d[2] = posl[2]/* - padl[2]*/;
500
501     /*
502     Double_t padg[3] = {0., 0., 0.};
503     // from TOF pad local reference system
504     // towards ALICE global reference system
505     TGeoHMatrix inverse = mat.Inverse();
506     inverse.MasterToLocal(padl,padg);
507
508     // returns the 3d distance
509     // between the impact point on the pad
510     // and the pad centre (in the ALICE global reference frame)
511     dist3d[0] = posg[0] - padg[0];
512     dist3d[1] = posg[1] - padg[1];
513     dist3d[2] = posg[2] - padg[2];
514     */
515   }
516  
517   return isInside;
518
519 }
520 //_____________________________________________________________________________
521 void AliTOFGeometry::GetVolumePath(const Int_t * const ind, Char_t *path ) {
522   //--------------------------------------------------------------------
523   // This function returns the colume path of a given pad 
524   //--------------------------------------------------------------------
525   Int_t sector = ind[0];
526   Char_t  string1[100];
527   Char_t  string2[100];
528   Char_t  string3[100];
529   
530   Int_t icopy=-1;
531   icopy=sector;
532  
533   sprintf(string1,"/ALIC_1/B077_1/BSEGMO%i_1/BTOF%i_1",icopy,icopy);
534   
535   Int_t iplate=ind[1];
536   Int_t istrip=ind[2];
537   if( iplate==0) icopy=istrip; 
538   if( iplate==1) icopy=istrip+NStripC(); 
539   if( iplate==2) icopy=istrip+NStripC()+NStripB(); 
540   if( iplate==3) icopy=istrip+NStripC()+NStripB()+NStripA(); 
541   if( iplate==4) icopy=istrip+NStripC()+2*NStripB()+NStripA(); 
542   icopy++;
543   sprintf(string2,"FTOA_0/FLTA_0/FSTR_%i",icopy);
544   if(fHoles && (sector==13 || sector==14 || sector==15)){
545     if(iplate<2)  sprintf(string2,"FTOB_0/FLTB_0/FSTR_%i",icopy);
546     if(iplate>2)  sprintf(string2,"FTOC_0/FLTC_0/FSTR_%i",icopy);
547   }
548  
549   Int_t padz = ind[3]+1; 
550   Int_t padx = ind[4]+1;
551   sprintf(string3,"FPCB_1/FSEN_1/FSEZ_%i/FPAD_%i",padz,padx);
552   sprintf(path,"%s/%s/%s",string1,string2,string3); 
553
554 }
555 //_____________________________________________________________________________
556 void AliTOFGeometry::GetVolumePath(Int_t sector, Char_t *path ){
557   //--------------------------------------------------------------------
558   // This function returns the colume path of a given sector 
559   //--------------------------------------------------------------------
560
561   Char_t string[100];
562
563   Int_t icopy = sector;
564
565   sprintf(string,"/ALIC_1/B077_1/BSEGMO%i_1/BTOF%i_1",icopy,icopy);
566   sprintf(path,"%s",string);
567
568 }
569 //_____________________________________________________________________________
570 void AliTOFGeometry::GetVolumePath(Int_t sector, Int_t plate, Int_t strip, Char_t *path ) {
571   //--------------------------------------------------------------------
572   // This function returns the colume path of a given strip 
573   //--------------------------------------------------------------------
574
575   Char_t string1[100];
576   Char_t string2[100];
577   Char_t string3[100];
578   
579   Int_t icopy = sector;
580
581   sprintf(string1,"/ALIC_1/B077_1/BSEGMO%i_1/BTOF%i_1",icopy,icopy);
582   
583   if(plate==0) icopy=strip; 
584   if(plate==1) icopy=strip+NStripC(); 
585   if(plate==2) icopy=strip+NStripC()+NStripB(); 
586   if(plate==3) icopy=strip+NStripC()+NStripB()+NStripA(); 
587   if(plate==4) icopy=strip+NStripC()+2*NStripB()+NStripA(); 
588   icopy++;
589   sprintf(string2,"FTOA_0/FLTA_0/FSTR_%i",icopy);
590   if(fHoles && (sector==13 || sector==14 || sector==15)){
591     if(plate<2)  sprintf(string2,"FTOB_0/FLTB_0/FSTR_%i",icopy);
592     if(plate>2)  sprintf(string2,"FTOC_0/FLTC_0/FSTR_%i",icopy);
593   }
594
595   sprintf(string3,"FPCB_1/FSEN_1");
596   sprintf(path,"%s/%s/%s",string1,string2,string3); 
597
598 }
599 //_____________________________________________________________________________
600 void AliTOFGeometry::GetPos(Int_t *det, Float_t *pos) 
601 {
602 //
603 // Returns space point coor (x,y,z) (cm)  for Detector 
604 // Indices  (iSect,iPlate,iStrip,iPadX,iPadZ) 
605 //
606   Char_t path[100];
607   GetVolumePath(det,path );
608   if (!gGeoManager) {
609     printf("ERROR: no TGeo\n");
610   }
611   gGeoManager->cd(path);
612   TGeoHMatrix global;
613   global = *gGeoManager->GetCurrentMatrix();
614   const Double_t *tr = global.GetTranslation();
615
616   pos[0]=tr[0];  
617   pos[1]=tr[1];  
618   pos[2]=tr[2];
619 }
620 //_____________________________________________________________________________
621 Int_t AliTOFGeometry::GetPlate(const Float_t * const pos) const
622 {
623   //
624   // Returns the Plate index 
625   //
626   const Float_t kInterCentrModBorder1 = 49.5;
627   const Float_t kInterCentrModBorder2 = 57.5;
628   const Float_t kExterInterModBorder1 = 196.0;
629   const Float_t kExterInterModBorder2 = 203.5;
630
631   const Float_t kLengthExInModBorder  = 4.7;
632   const Float_t kLengthInCeModBorder  = 7.0;
633
634   //const Float_t khAlWall = 0.1;
635   const Float_t kModuleWallThickness = 0.3;
636   //const Float_t kHoneycombLayerThickness = 1.5;
637
638   Int_t iPlate=-1;
639
640   Float_t posLocal[3];
641   for (Int_t ii=0; ii<3; ii++) posLocal[ii] = pos[ii];
642
643   Int_t isector = GetSector(posLocal);
644   if(isector == -1){
645     //AliError("Detector Index could not be determined");
646     return iPlate;
647   }
648
649   // ALICE reference frame -> B071/B074/B075 = BTO1/2/3 reference frame
650   Double_t angles[6] = 
651     {90., 90.+(isector+0.5)*fgkPhiSec,
652       0., 0.,
653      90., (isector+0.5)*fgkPhiSec
654     };
655   Rotation(posLocal,angles);
656
657   Float_t step[3] = {0., 0., (fgkRmax+fgkRmin)*0.5};
658   Translation(posLocal,step);
659
660   // B071/B074/B075 = BTO1/2/3 reference frame -> FTOA = FLTA reference frame
661   angles[0] = 90.;
662   angles[1] =  0.;
663   angles[2] =  0.;
664   angles[3] =  0.;
665   angles[4] = 90.;
666   angles[5] =270.;
667
668   Rotation(posLocal,angles);
669
670   Float_t yLocal = posLocal[1];
671   Float_t zLocal = posLocal[2];
672
673   Float_t deltaRhoLoc  = (fgkRmax-fgkRmin)*0.5 - kModuleWallThickness + yLocal;
674   Float_t deltaZetaLoc = TMath::Abs(zLocal);
675
676   Float_t deltaRHOmax = 0.;
677
678   if (TMath::Abs(zLocal)>=kExterInterModBorder1 && TMath::Abs(zLocal)<=kExterInterModBorder2) 
679     {
680       deltaRhoLoc -= kLengthExInModBorder;
681       deltaZetaLoc = kExterInterModBorder2-deltaZetaLoc;
682       deltaRHOmax  = (fgkRmax - fgkRmin)*0.5 - kModuleWallThickness - 2.*kLengthExInModBorder; // old 5.35, new 4.8
683
684       if (deltaRhoLoc > deltaZetaLoc*deltaRHOmax/(kInterCentrModBorder2-kInterCentrModBorder1)) {
685         if (zLocal<0) iPlate = 0;
686         else iPlate = 4;
687       }
688       else {
689         if (zLocal<0) iPlate = 1;
690         else iPlate = 3;
691       }
692     }
693   else if (TMath::Abs(zLocal)>=kInterCentrModBorder1 && TMath::Abs(zLocal)<=kInterCentrModBorder2) 
694     {
695       deltaRhoLoc -= kLengthInCeModBorder;
696       deltaZetaLoc = deltaZetaLoc-kInterCentrModBorder1;
697       deltaRHOmax = (fgkRmax - fgkRmin)*0.5 - kModuleWallThickness - 2.*kLengthInCeModBorder; // old 0.39, new 0.2
698
699       if (deltaRhoLoc>deltaZetaLoc*deltaRHOmax/(kInterCentrModBorder2-kInterCentrModBorder1)) iPlate = 2;
700       else {
701         if (zLocal<0) iPlate = 1;
702         else iPlate = 3;
703       }
704     }
705
706   if      (zLocal>-fgkZlenA*0.5          && zLocal<-kExterInterModBorder2) iPlate = 0;
707   else if (zLocal>-kExterInterModBorder1 && zLocal<-kInterCentrModBorder2) iPlate = 1;
708   else if (zLocal>-kInterCentrModBorder1 && zLocal< kInterCentrModBorder1) iPlate = 2;
709   else if (zLocal> kInterCentrModBorder2 && zLocal< kExterInterModBorder1) iPlate = 3;
710   else if (zLocal> kExterInterModBorder2 && zLocal< fgkZlenA*0.5)          iPlate = 4;
711   
712   return iPlate;
713
714 }
715
716 //_____________________________________________________________________________
717 Int_t AliTOFGeometry::GetSector(const Float_t * const pos) const
718 {
719   //
720   // Returns the Sector index 
721   //
722
723   Int_t   iSect = -1; 
724
725   Float_t x = pos[0];
726   Float_t y = pos[1];
727   Float_t z = pos[2];
728
729   Float_t rho = TMath::Sqrt(x*x + y*y);
730
731   if (!((z>=-fgkZlenA*0.5 && z<=fgkZlenA*0.5) &&
732         (rho>=(fgkRmin) && rho<=(fgkRmax)))) {
733     //AliError("Detector Index could not be determined");
734     return iSect;
735   }
736
737   Float_t phi = TMath::Pi() + TMath::ATan2(-y,-x);      
738
739   iSect  = (Int_t) (phi*kRaddeg/fgkPhiSec);
740   
741   return iSect;
742
743 }
744 //_____________________________________________________________________________
745 Int_t AliTOFGeometry::GetStrip(const Float_t * const pos) const
746 {
747   //
748   // Returns the Strip index 
749   //
750   const Float_t khhony    = 1.0          ; // heigth of HONY  Layer
751   const Float_t khpcby    = 0.08         ; // heigth of PCB   Layer
752   const Float_t khrgly    = 0.055        ; // heigth of RED GLASS  Layer
753   const Float_t khglfy    = 0.285        ; // heigth of GLASS+FISHLINE  Layer
754   const Float_t khcpcby   = 0.16         ; // heigth of PCB  Central Layer
755   const Float_t kwcpcbz   = 12.4         ; // z dimension of PCB  Central Layer
756   const Float_t khstripy = 2.*khhony+2.*khpcby+4.*khrgly+2.*khglfy+khcpcby;//3.11
757   const Float_t kwstripz = kwcpcbz;
758   const Float_t klstripx = fgkStripLength;
759   
760   Int_t iStrip=-1;
761    
762   Float_t posLocal[3];
763   for (Int_t ii=0; ii<3; ii++) posLocal[ii] = pos[ii];
764   AliDebug(1,Form("  posLocal[0] = %f, posLocal[1] = %f, posLocal[2] = %f ",
765                   posLocal[0],posLocal[1],posLocal[2]));
766
767   Int_t isector = GetSector(posLocal);
768   if(isector == -1){
769     //AliError("Detector Index could not be determined");
770     return iStrip;}
771   Int_t iplate =  GetPlate(posLocal);
772   if(iplate == -1){
773     //AliError("Detector Index could not be determined");
774     return iStrip;} 
775
776   Int_t nstrips=0;
777   switch (iplate) {
778   case 0:
779   case 4:
780     nstrips=kNStripC;
781     break;
782   case 1:
783   case 3:
784     nstrips=kNStripB;
785     break;
786   case 2:
787     nstrips=kNStripA;
788     break;
789   }
790   
791   // ALICE reference frame -> B071/B074/B075 = BTO1/2/3 reference frame
792   Double_t angles[6] = 
793     {90., 90.+(isector+0.5)*fgkPhiSec,
794       0., 0.,
795      90., (isector+0.5)*fgkPhiSec
796     };
797   Rotation(posLocal,angles);
798   AliDebug(1,Form("  posLocal[0] = %f, posLocal[1] = %f, posLocal[2] = %f ",
799                   posLocal[0],posLocal[1],posLocal[2]));
800
801   Float_t step[3] = {0., 0., (fgkRmax+fgkRmin)*0.5};
802   Translation(posLocal,step);
803   AliDebug(1,Form("  posLocal[0] = %f, posLocal[1] = %f, posLocal[2] = %f ",
804                   posLocal[0],posLocal[1],posLocal[2]));
805
806   // B071/B074/B075 = BTO1/2/3 reference frame -> FTOA = FLTA reference frame
807   angles[0] = 90.;
808   angles[1] =  0.;
809   angles[2] =  0.;
810   angles[3] =  0.;
811   angles[4] = 90.;
812   angles[5] =270.;
813
814   Rotation(posLocal,angles);
815   AliDebug(1,Form("  posLocal[0] = %f, posLocal[1] = %f, posLocal[2] = %f ",
816                   posLocal[0],posLocal[1],posLocal[2]));
817
818   // FTOA/B/C = FLTA/B/C reference frame -> FSTR reference frame
819   Int_t totStrip=0;
820   for (Int_t istrip=0; istrip<nstrips; istrip++){
821
822     Float_t posLoc2[3]={posLocal[0],posLocal[1],posLocal[2]};         
823
824     step[0] = 0.;
825     step[1] = GetHeights(iplate,istrip);
826     step[2] = -GetDistances(iplate,istrip);
827     Translation(posLoc2,step);
828
829     if      (GetAngles(iplate,istrip) >0.) {
830       angles[0] = 90.;
831       angles[1] =  0.;
832       angles[2] = 90.+GetAngles(iplate,istrip);
833       angles[3] = 90.;
834       angles[4] = GetAngles(iplate,istrip);
835       angles[5] = 90.;
836     }
837     else if (GetAngles(iplate,istrip)==0.) {
838       angles[0] = 90.;
839       angles[1] =  0.;
840       angles[2] = 90.;
841       angles[3] = 90.;
842       angles[4] =  0;
843       angles[5] =  0.;
844     }
845     else if (GetAngles(iplate,istrip) <0.) {
846       angles[0] = 90.;
847       angles[1] =  0.;
848       angles[2] = 90.+GetAngles(iplate,istrip);
849       angles[3] = 90.;
850       angles[4] =-GetAngles(iplate,istrip);
851       angles[5] = 270.;
852     }
853     Rotation(posLoc2,angles);
854     AliDebug(1,Form(" strip %2d:  posLoc2[0] = %f, posLoc2[1] = %f, posLoc2[2] = %f ",
855                     istrip, posLoc2[0],posLoc2[1],posLoc2[2]));
856
857     if ((TMath::Abs(posLoc2[0])<=klstripx*0.5) &&
858         (TMath::Abs(posLoc2[1])<=khstripy*0.5) &&
859         (TMath::Abs(posLoc2[2])<=kwstripz*0.5)) {
860       iStrip = istrip;
861       totStrip++;
862       for (Int_t jj=0; jj<3; jj++) posLocal[jj]=posLoc2[jj];
863       AliDebug(2,Form(" posLocal[0] = %f, posLocal[1] = %f, posLocal[2] = %f ",
864                       posLocal[0],posLocal[1],posLocal[2]));
865
866       AliDebug(2,Form(" GetAngles(%1i,%2i) = %f, pos[0] = %f, pos[1] = %f, pos[2] = %f",
867                       iplate, istrip, GetAngles(iplate,istrip), pos[0], pos[1], pos[2]));
868       break;
869     }
870
871     if (totStrip>1) AliInfo(Form("total strip number found %2i",totStrip));
872
873   }
874
875   return iStrip;
876   
877 }
878 //_____________________________________________________________________________
879 Int_t AliTOFGeometry::GetPadZ(const Float_t * const pos) const
880 {
881   //
882   // Returns the Pad index along Z 
883   //
884   //const Float_t klsensmx = kNpadX*fgkXPad;  // length of Sensitive Layer
885   //const Float_t khsensmy = 0.05;//0.11;//0.16;// heigth of Sensitive Layer
886   //const Float_t kwsensmz = kNpadZ*fgkZPad;  // width of Sensitive Layer
887
888   Int_t iPadZ = -1;
889
890   Float_t posLocal[3];
891   for (Int_t ii=0; ii<3; ii++) posLocal[ii] = pos[ii];
892  
893   Int_t isector = GetSector(posLocal);
894   if(isector == -1){
895     //AliError("Detector Index could not be determined");
896     return iPadZ;}
897   Int_t iplate =  GetPlate(posLocal);
898   if(iplate == -1){
899     //AliError("Detector Index could not be determined");
900     return iPadZ;}
901   Int_t istrip =  GetStrip(posLocal);
902   if(istrip == -1){
903     //AliError("Detector Index could not be determined");
904     return iPadZ;}
905
906   // ALICE reference frame -> B071/B074/B075 = BTO1/2/3 reference frame
907   Double_t angles[6] = 
908     {90., 90.+(isector+0.5)*fgkPhiSec,
909       0., 0.,
910      90., (isector+0.5)*fgkPhiSec
911     };
912   Rotation(posLocal,angles);
913
914   Float_t step[3] = {0., 0., (fgkRmax+fgkRmin)*0.5};
915   Translation(posLocal,step);
916
917   // B071/B074/B075 = BTO1/2/3 reference frame -> FTOA = FLTA reference frame
918   angles[0] = 90.;
919   angles[1] =  0.;
920   angles[2] =  0.;
921   angles[3] =  0.;
922   angles[4] = 90.;
923   angles[5] =270.;
924
925   Rotation(posLocal,angles);
926
927   // FTOA/B/C = FLTA/B/C reference frame -> FSTR reference frame
928   step[0] = 0.;
929   step[1] = GetHeights(iplate,istrip);
930   step[2] = -GetDistances(iplate,istrip);
931   Translation(posLocal,step);
932
933   if      (GetAngles(iplate,istrip) >0.) {
934     angles[0] = 90.;
935     angles[1] =  0.;
936     angles[2] = 90.+GetAngles(iplate,istrip);
937     angles[3] = 90.;
938     angles[4] = GetAngles(iplate,istrip);
939     angles[5] = 90.;
940   }
941   else if (GetAngles(iplate,istrip)==0.) {
942     angles[0] = 90.;
943     angles[1] =  0.;
944     angles[2] = 90.;
945     angles[3] = 90.;
946     angles[4] =  0;
947     angles[5] =  0.;
948   }
949   else if (GetAngles(iplate,istrip) <0.) {
950     angles[0] = 90.;
951     angles[1] =  0.;
952     angles[2] = 90.+GetAngles(iplate,istrip);
953     angles[3] = 90.;
954     angles[4] =-GetAngles(iplate,istrip);
955     angles[5] = 270.;
956   }
957   Rotation(posLocal,angles);
958
959   step[0] =-0.5*kNpadX*fgkXPad;
960   step[1] = 0.;
961   step[2] =-0.5*kNpadZ*fgkZPad;
962   Translation(posLocal,step);
963
964   iPadZ = (Int_t)(posLocal[2]/fgkZPad);
965   if (iPadZ==kNpadZ) iPadZ--;
966   else if (iPadZ>kNpadZ) iPadZ=-1;
967
968   return iPadZ;
969
970 }
971 //_____________________________________________________________________________
972 Int_t AliTOFGeometry::GetPadX(const Float_t * const pos) const
973 {
974   //
975   // Returns the Pad index along X 
976   //
977   //const Float_t klsensmx = kNpadX*fgkXPad;  // length of Sensitive Layer
978   //const Float_t khsensmy = 0.05;//0.11;//0.16;// heigth of Sensitive Layer
979   //const Float_t kwsensmz = kNpadZ*fgkZPad;  // width of Sensitive Layer
980
981   Int_t iPadX  = -1;
982
983   Float_t posLocal[3];
984   for (Int_t ii=0; ii<3; ii++) posLocal[ii] = pos[ii];
985  
986   Int_t isector = GetSector(posLocal);
987   if(isector == -1){
988     //AliError("Detector Index could not be determined");
989     return iPadX;}
990   Int_t iplate =  GetPlate(posLocal);
991   if(iplate == -1){
992     //AliError("Detector Index could not be determined");
993     return iPadX;} 
994   Int_t istrip =  GetStrip(posLocal);
995   if(istrip == -1){  
996     //AliError("Detector Index could not be determined");
997     return iPadX;}
998
999   // ALICE reference frame -> B071/B074/B075 = BTO1/2/3 reference frame
1000   Double_t angles[6] = 
1001     {90., 90.+(isector+0.5)*fgkPhiSec,
1002       0.,  0.,
1003      90., (isector+0.5)*fgkPhiSec
1004     };
1005   Rotation(posLocal,angles);
1006
1007   Float_t step[3] = {0., 0., (fgkRmax+fgkRmin)*0.5};
1008   Translation(posLocal,step);
1009
1010   // B071/B074/B075 = BTO1/2/3 reference frame -> FTOA/B/C = FLTA/B/C reference frame
1011   angles[0] = 90.;
1012   angles[1] =  0.;
1013   angles[2] =  0.;
1014   angles[3] =  0.;
1015   angles[4] = 90.;
1016   angles[5] =270.;
1017
1018   Rotation(posLocal,angles);
1019
1020   // FTOA/B/C = FLTA/B/C reference frame -> FSTR reference frame
1021   step[0] = 0.;
1022   step[1] = GetHeights(iplate,istrip);
1023   step[2] = -GetDistances(iplate,istrip);
1024   Translation(posLocal,step);
1025
1026   if      (GetAngles(iplate,istrip) >0.) {
1027     angles[0] = 90.;
1028     angles[1] =  0.;
1029     angles[2] = 90.+GetAngles(iplate,istrip);
1030     angles[3] = 90.;
1031     angles[4] = GetAngles(iplate,istrip);
1032     angles[5] = 90.;
1033   }
1034   else if (GetAngles(iplate,istrip)==0.) {
1035     angles[0] = 90.;
1036     angles[1] =  0.;
1037     angles[2] = 90.;
1038     angles[3] = 90.;
1039     angles[4] =  0;
1040     angles[5] =  0.;
1041   }
1042   else if (GetAngles(iplate,istrip) <0.) {
1043     angles[0] = 90.;
1044     angles[1] =  0.;
1045     angles[2] = 90.+GetAngles(iplate,istrip);
1046     angles[3] = 90.;
1047     angles[4] =-GetAngles(iplate,istrip);
1048     angles[5] = 270.;
1049   }
1050   Rotation(posLocal,angles);
1051
1052   step[0] =-0.5*kNpadX*fgkXPad;
1053   step[1] = 0.;
1054   step[2] =-0.5*kNpadZ*fgkZPad;
1055   Translation(posLocal,step);
1056
1057   iPadX = (Int_t)(posLocal[0]/fgkXPad);
1058   if (iPadX==kNpadX) iPadX--;
1059   else if (iPadX>kNpadX) iPadX=-1;
1060
1061   return iPadX;
1062
1063 }
1064 //_____________________________________________________________________________
1065 Float_t AliTOFGeometry::GetX(const Int_t * const det) const
1066 {
1067   //
1068   // Returns X coordinate (cm)
1069   //
1070
1071   Int_t isector = det[0];
1072   Int_t iplate  = det[1];
1073   Int_t istrip  = det[2];
1074   Int_t ipadz   = det[3];
1075   Int_t ipadx   = det[4];
1076
1077   /*
1078   // Find out distance d on the plane wrt median phi:
1079   Float_t d = (ipadx+0.5-kNpadX*0.5)*fgkXPad;
1080
1081   // The radius r in xy plane:
1082   //Float_t r = (fgkRmin+fgkRmax)*0.5-0.01+GetHeights(iplate,istrip)+
1083   //  (ipadz-0.5)*fgkZPad*TMath::Sin(GetAngles(iplate,istrip)/kRaddeg)-0.25; ???
1084   Float_t r = (fgkRmin+fgkRmax)*0.5-0.01+GetHeights(iplate,istrip)+
1085     (ipadz-0.5)*fgkZPad*TMath::Sin(GetAngles(iplate,istrip)/kRaddeg);
1086
1087   // local azimuthal angle in the sector philoc
1088   Float_t philoc  = TMath::ATan(d/r);
1089   //if(philoc<0.) philoc = k2PI + philoc;
1090
1091   // azimuthal angle in the global frame  phi
1092   Float_t phi   = philoc*kRaddeg+(isector+0.5)*fgkPhiSec;
1093
1094   Float_t xCoor = r/TMath::Cos(philoc)*TMath::Cos(phi/kRaddeg);
1095   */
1096
1097   // Pad reference frame -> FSTR reference frame
1098   Float_t posLocal[3] = {0., 0., 0.};
1099   Float_t step[3] = {-(ipadx+0.5)*fgkXPad, 0., -(ipadz+0.5)*fgkZPad};
1100   Translation(posLocal,step);
1101
1102   step[0] = kNpadX*0.5*fgkXPad;
1103   step[1] = 0.;
1104   step[2] = kNpadZ*0.5*fgkZPad;
1105   /*
1106   Float_t posLocal[3] = {(ipadx+0.5)*fgkXPad, 0., (ipadz+0.5)*fgkZPad};
1107   Float_t step[3]= {kNpadX*0.5*fgkXPad, 0., kNpadZ*0.5*fgkZPad};
1108   */
1109   Translation(posLocal,step);
1110
1111   // FSTR reference frame -> FTOA/B/C = FLTA/B/C reference frame
1112   Double_t angles[6];
1113   if      (GetAngles(iplate,istrip) >0.) {
1114     angles[0] = 90.;
1115     angles[1] =  0.;
1116     angles[2] = 90.+GetAngles(iplate,istrip);
1117     angles[3] = 90.;
1118     angles[4] = GetAngles(iplate,istrip);
1119     angles[5] = 90.;
1120   }
1121   else if (GetAngles(iplate,istrip)==0.) {
1122     angles[0] = 90.;
1123     angles[1] =  0.;
1124     angles[2] = 90.;
1125     angles[3] = 90.;
1126     angles[4] =  0;
1127     angles[5] =  0.;
1128   }
1129   else if (GetAngles(iplate,istrip) <0.) {
1130     angles[0] = 90.;
1131     angles[1] =  0.;
1132     angles[2] = 90.+GetAngles(iplate,istrip);
1133     angles[3] = 90.;
1134     angles[4] =-GetAngles(iplate,istrip);
1135     angles[5] = 270.;
1136   }
1137
1138   InverseRotation(posLocal,angles);
1139
1140   step[0] = 0.;
1141   step[1] = -GetHeights(iplate,istrip);
1142   step[2] =  GetDistances(iplate,istrip);
1143   Translation(posLocal,step);
1144
1145   // FTOA = FLTA reference frame -> B071/B074/B075 = BTO1/2/3 reference frame
1146   angles[0] = 90.;
1147   angles[1] =  0.;
1148   angles[2] =  0.;
1149   angles[3] =  0.;
1150   angles[4] = 90.;
1151   angles[5] =270.;
1152
1153   InverseRotation(posLocal,angles);
1154
1155   // B071/B074/B075 = BTO1/2/3 reference frame -> ALICE reference frame
1156   step[0] = 0.;
1157   step[1] = 0.;
1158   step[2] = -((fgkRmax+fgkRmin)*0.5);
1159   Translation(posLocal,step);
1160
1161   angles[0] = 90.;
1162   angles[1] = 90.+(isector+0.5)*fgkPhiSec;
1163   angles[2] = 0.;
1164   angles[3] = 0.;
1165   angles[4] = 90.;
1166   angles[5] = (isector+0.5)*fgkPhiSec;
1167
1168   InverseRotation(posLocal,angles);
1169
1170   Float_t xCoor = posLocal[0];
1171
1172   return xCoor;
1173
1174 }
1175 //_____________________________________________________________________________
1176 Float_t AliTOFGeometry::GetY(const Int_t * const det) const
1177 {
1178   //
1179   // Returns Y coordinate (cm)
1180   //
1181
1182   Int_t isector = det[0];
1183   Int_t iplate  = det[1];
1184   Int_t istrip  = det[2];
1185   Int_t ipadz   = det[3];
1186   Int_t ipadx   = det[4];
1187
1188   /*
1189   // Find out distance d on the plane wrt median phi:
1190   Float_t d = (ipadx+0.5-kNpadX*0.5)*fgkXPad;
1191
1192   // The radius r in xy plane:
1193   //Float_t r = (fgkRmin+fgkRmax)*0.5-0.01+GetHeights(iplate,istrip)+
1194   //  (ipadz-0.5)*fgkZPad*TMath::Sin(GetAngles(iplate,istrip)/kRaddeg)-0.25; ???
1195   Float_t r = (fgkRmin+fgkRmax)*0.5-0.01+GetHeights(iplate,istrip)+
1196     (ipadz-0.5)*fgkZPad*TMath::Sin(GetAngles(iplate,istrip)/kRaddeg);
1197
1198   // local azimuthal angle in the sector philoc
1199   Float_t philoc = TMath::ATan(d/r);
1200   //if(philoc<0.) philoc = k2PI + philoc;
1201
1202   // azimuthal angle in the global frame  phi
1203   Float_t phi   = philoc*kRaddeg+(isector+0.5)*fgkPhiSec;
1204
1205   Float_t yCoor = r/TMath::Cos(philoc)*TMath::Sin(phi/kRaddeg);
1206   */
1207
1208   // Pad reference frame -> FSTR reference frame
1209   Float_t posLocal[3] = {0., 0., 0.};
1210   Float_t step[3] = {-(ipadx+0.5)*fgkXPad, 0., -(ipadz+0.5)*fgkZPad};
1211   Translation(posLocal,step);
1212
1213   step[0] = kNpadX*0.5*fgkXPad;
1214   step[1] = 0.;
1215   step[2] = kNpadZ*0.5*fgkZPad;
1216   /*
1217   Float_t posLocal[3] = {(ipadx+0.5)*fgkXPad, 0., (ipadz+0.5)*fgkZPad};
1218   Float_t step[3]= {kNpadX*0.5*fgkXPad, 0., kNpadZ*0.5*fgkZPad};
1219   */
1220   Translation(posLocal,step);
1221
1222   // FSTR reference frame -> FTOA/B/C = FLTA/B/C reference frame
1223
1224   Double_t angles[6];
1225   if      (GetAngles(iplate,istrip) >0.) {
1226     angles[0] = 90.;
1227     angles[1] =  0.;
1228     angles[2] = 90.+GetAngles(iplate,istrip);
1229     angles[3] = 90.;
1230     angles[4] = GetAngles(iplate,istrip);
1231     angles[5] = 90.;
1232   }
1233   else if (GetAngles(iplate,istrip)==0.) {
1234     angles[0] = 90.;
1235     angles[1] =  0.;
1236     angles[2] = 90.;
1237     angles[3] = 90.;
1238     angles[4] =  0;
1239     angles[5] =  0.;
1240   }
1241   else if (GetAngles(iplate,istrip) <0.) {
1242     angles[0] = 90.;
1243     angles[1] =  0.;
1244     angles[2] = 90.+GetAngles(iplate,istrip);
1245     angles[3] = 90.;
1246     angles[4] =-GetAngles(iplate,istrip);
1247     angles[5] = 270.;
1248   }
1249
1250   InverseRotation(posLocal,angles);
1251
1252   step[0] = 0.;
1253   step[1] = -GetHeights(iplate,istrip);
1254   step[2] =  GetDistances(iplate,istrip);
1255   Translation(posLocal,step);
1256
1257   // FTOA = FLTA reference frame -> B071/B074/B075 = BTO1/2/3 reference frame
1258   angles[0] = 90.;
1259   angles[1] =  0.;
1260   angles[2] =  0.;
1261   angles[3] =  0.;
1262   angles[4] = 90.;
1263   angles[5] =270.;
1264
1265   InverseRotation(posLocal,angles);
1266
1267   // B071/B074/B075 = BTO1/2/3 reference frame -> ALICE reference frame
1268   step[0] = 0.;
1269   step[1] = 0.;
1270   step[2] = -((fgkRmax+fgkRmin)*0.5);
1271   Translation(posLocal,step);
1272
1273   angles[0] = 90.;
1274   angles[1] = 90.+(isector+0.5)*fgkPhiSec;
1275   angles[2] = 0.;
1276   angles[3] = 0.;
1277   angles[4] = 90.;
1278   angles[5] = (isector+0.5)*fgkPhiSec;
1279
1280   InverseRotation(posLocal,angles);
1281
1282   Float_t yCoor = posLocal[1];
1283
1284   return yCoor;
1285
1286 }
1287
1288 //_____________________________________________________________________________
1289 Float_t AliTOFGeometry::GetZ(const Int_t * const det) const
1290 {
1291   //
1292   // Returns Z coordinate (cm)
1293   //
1294
1295   Int_t isector = det[0];
1296   Int_t iplate  = det[1];
1297   Int_t istrip  = det[2];
1298   Int_t ipadz   = det[3];
1299   Int_t ipadx   = det[4];
1300
1301   /*
1302   Float_t zCoor = GetDistances(iplate,istrip) +
1303     (0.5-ipadz) * fgkZPad * TMath::Cos(GetAngles(iplate,istrip)*kDegrad);
1304   */
1305
1306   // Pad reference frame -> FSTR reference frame
1307   Float_t posLocal[3] = {0., 0., 0.};
1308   Float_t step[3] = {-(ipadx+0.5)*fgkXPad, 0., -(ipadz+0.5)*fgkZPad};
1309   Translation(posLocal,step);
1310
1311   step[0] = kNpadX*0.5*fgkXPad;
1312   step[1] = 0.;
1313   step[2] = kNpadZ*0.5*fgkZPad;
1314   /*
1315   Float_t posLocal[3] = {(ipadx+0.5)*fgkXPad, 0., (ipadz+0.5)*fgkZPad};
1316   Float_t step[3]= {kNpadX*0.5*fgkXPad, 0., kNpadZ*0.5*fgkZPad};
1317   */
1318   Translation(posLocal,step);
1319
1320   // FSTR reference frame -> FTOA/B/C = FLTA/B/C reference frame
1321   Double_t angles[6];
1322   if      (GetAngles(iplate,istrip) >0.) {
1323     angles[0] = 90.;
1324     angles[1] =  0.;
1325     angles[2] = 90.+GetAngles(iplate,istrip);
1326     angles[3] = 90.;
1327     angles[4] = GetAngles(iplate,istrip);
1328     angles[5] = 90.;
1329   }
1330   else if (GetAngles(iplate,istrip)==0.) {
1331     angles[0] = 90.;
1332     angles[1] =  0.;
1333     angles[2] = 90.;
1334     angles[3] = 90.;
1335     angles[4] =  0;
1336     angles[5] =  0.;
1337   }
1338   else if (GetAngles(iplate,istrip) <0.) {
1339     angles[0] = 90.;
1340     angles[1] =  0.;
1341     angles[2] = 90.+GetAngles(iplate,istrip);
1342     angles[3] = 90.;
1343     angles[4] =-GetAngles(iplate,istrip);
1344     angles[5] = 270.;
1345   }
1346
1347   InverseRotation(posLocal,angles);
1348
1349   step[0] = 0.;
1350   step[1] = -GetHeights(iplate,istrip);
1351   step[2] =  GetDistances(iplate,istrip);
1352   Translation(posLocal,step);
1353
1354   // FTOA = FLTA reference frame -> B071/B074/B075 = BTO1/2/3 reference frame
1355   angles[0] = 90.;
1356   angles[1] =  0.;
1357   angles[2] =  0.;
1358   angles[3] =  0.;
1359   angles[4] = 90.;
1360   angles[5] =270.;
1361
1362   InverseRotation(posLocal,angles);
1363
1364   // B071/B074/B075 = BTO1/2/3 reference frame -> ALICE reference frame
1365   step[0] = 0.;
1366   step[1] = 0.;
1367   step[2] = -((fgkRmax+fgkRmin)*0.5);
1368   Translation(posLocal,step);
1369
1370   angles[0] = 90.;
1371   angles[1] = 90.+(isector+0.5)*fgkPhiSec;
1372   angles[2] = 0.;
1373   angles[3] = 0.;
1374   angles[4] = 90.;
1375   angles[5] = (isector+0.5)*fgkPhiSec;
1376
1377   InverseRotation(posLocal,angles);
1378
1379   Float_t zCoor = posLocal[2];
1380
1381   return zCoor;
1382
1383 }
1384 //_____________________________________________________________________________
1385
1386 void AliTOFGeometry::DetToSectorRF(Int_t vol[5], Double_t **coord)
1387 {
1388   //
1389   // Returns the local coordinates (x, y, z) in sector reference frame
1390   // for the 4 corners of each sector pad (vol[1], vol[2], vol[3], vol[4])
1391   //
1392
1393   if (!gGeoManager) printf("ERROR: no TGeo\n");
1394
1395   // ALICE -> TOF Sector
1396   Char_t path1[100]="";
1397   GetVolumePath(vol[0],path1);
1398   gGeoManager->cd(path1);
1399   TGeoHMatrix aliceToSector;
1400   aliceToSector = *gGeoManager->GetCurrentMatrix();
1401
1402   // TOF Sector -> ALICE
1403   //TGeoHMatrix sectorToALICE = aliceToSector.Inverse();
1404
1405   // ALICE -> TOF Pad
1406   Char_t path2[100]="";
1407   GetVolumePath(vol,path2);
1408   gGeoManager->cd(path2);
1409   TGeoHMatrix aliceToPad;
1410   aliceToPad = *gGeoManager->GetCurrentMatrix();
1411
1412   // TOF Pad -> ALICE
1413   TGeoHMatrix padToALICE = aliceToPad.Inverse();
1414
1415   // TOF Pad -> TOF Sector
1416   TGeoHMatrix padToSector = padToALICE*aliceToSector;
1417
1418   // TOF Sector -> TOF Pad
1419   //TGeoHMatrix sectorToPad = sectorToALICE*aliceToPad;
1420
1421   // coordinates of the pad bottom corner
1422   Double_t **cornerPad = new Double_t*[4];
1423   for (Int_t ii=0; ii<4; ii++) cornerPad[ii] = new Double_t[3];
1424
1425   cornerPad[0][0] = -fgkXPad/2.;
1426   cornerPad[0][1] =  0.;
1427   cornerPad[0][2] = -fgkZPad/2.;
1428
1429   cornerPad[1][0] =  fgkXPad/2.;
1430   cornerPad[1][1] =  0.;
1431   cornerPad[1][2] = -fgkZPad/2.;
1432
1433   cornerPad[2][0] =  fgkXPad/2.;
1434   cornerPad[2][1] =  0.;
1435   cornerPad[2][2] =  fgkZPad/2.;
1436
1437   cornerPad[3][0] = -fgkXPad/2.;
1438   cornerPad[3][1] =  0.;
1439   cornerPad[3][2] =  fgkZPad/2.;
1440
1441   for(Int_t aa=0; aa<4; aa++) for(Int_t bb=0; bb<3; bb++) coord[aa][bb]=0.;
1442
1443   for (Int_t jj=0; jj<4; jj++) padToSector.MasterToLocal(&cornerPad[jj][0], &coord[jj][0]);
1444
1445   delete cornerPad;
1446
1447   //sectorToPad.LocalToMaster(cornerPad, coord);
1448
1449 }
1450 //_____________________________________________________________________________
1451 Float_t AliTOFGeometry::GetPadDx(const Float_t * const pos)
1452 {
1453   //
1454   // Returns the x coordinate in the Pad reference frame
1455   //
1456
1457   Float_t xpad = -2.;
1458
1459   Float_t posLocal[3];
1460   for (Int_t ii=0; ii<3; ii++) posLocal[ii] = pos[ii];
1461  
1462   Int_t isector = GetSector(posLocal);
1463   if(isector == -1){
1464     //AliError("Detector Index could not be determined");
1465     return xpad;}
1466   Int_t iplate =  GetPlate(posLocal);
1467   if(iplate == -1){
1468     //AliError("Detector Index could not be determined");
1469     return xpad;} 
1470   Int_t istrip =  GetStrip(posLocal);
1471   if(istrip == -1){  
1472     //AliError("Detector Index could not be determined");
1473     return xpad;}
1474   Int_t ipadz =  GetPadZ(posLocal);
1475   if(ipadz == -1){  
1476     //AliError("Detector Index could not be determined");
1477     return xpad;}
1478   Int_t ipadx =  GetPadX(posLocal);
1479   if(ipadx == -1){
1480     //AliError("Detector Index could not be determined");
1481     return xpad;}
1482
1483   // ALICE reference frame -> B071/B074/B075 = BTO1/2/3 reference frame
1484   Double_t angles[6] = 
1485     {90., 90.+(isector+0.5)*fgkPhiSec,
1486       0.,  0.,
1487      90., (isector+0.5)*fgkPhiSec
1488     };
1489   Rotation(posLocal,angles);
1490
1491   Float_t step[3] = {0., 0., (fgkRmax+fgkRmin)*0.5};
1492   Translation(posLocal,step);
1493
1494   // B071/B074/B075 = BTO1/2/3 reference frame -> FTOA/B/C = FLTA/B/C reference frame
1495   angles[0] = 90.;
1496   angles[1] =  0.;
1497   angles[2] =  0.;
1498   angles[3] =  0.;
1499   angles[4] = 90.;
1500   angles[5] =270.;
1501
1502   Rotation(posLocal,angles);
1503
1504   // FTOA/B/C = FLTA/B/C reference frame -> FSTR reference frame
1505   step[0] = 0.;
1506   step[1] = GetHeights(iplate,istrip);
1507   step[2] = -GetDistances(iplate,istrip);
1508   Translation(posLocal,step);
1509
1510   if      (GetAngles(iplate,istrip) >0.) {
1511     angles[0] = 90.;
1512     angles[1] =  0.;
1513     angles[2] = 90.+GetAngles(iplate,istrip);
1514     angles[3] = 90.;
1515     angles[4] = GetAngles(iplate,istrip);
1516     angles[5] = 90.;
1517   }
1518   else if (GetAngles(iplate,istrip)==0.) {
1519     angles[0] = 90.;
1520     angles[1] =  0.;
1521     angles[2] = 90.;
1522     angles[3] = 90.;
1523     angles[4] =  0;
1524     angles[5] =  0.;
1525   }
1526   else if (GetAngles(iplate,istrip) <0.) {
1527     angles[0] = 90.;
1528     angles[1] =  0.;
1529     angles[2] = 90.+GetAngles(iplate,istrip);
1530     angles[3] = 90.;
1531     angles[4] =-GetAngles(iplate,istrip);
1532     angles[5] = 270.;
1533   }
1534   Rotation(posLocal,angles);
1535
1536   step[0] =-0.5*kNpadX*fgkXPad;
1537   step[1] = 0.;
1538   step[2] =-0.5*kNpadZ*fgkZPad;
1539   Translation(posLocal,step);
1540
1541   step[0] = (ipadx+0.5)*fgkXPad;
1542   step[1] = 0.;
1543   step[2] = (ipadz+0.5)*fgkZPad;
1544   Translation(posLocal,step);
1545   
1546   xpad=posLocal[0];
1547
1548   return xpad;
1549
1550 }
1551 //_____________________________________________________________________________
1552 Float_t AliTOFGeometry::GetPadDy(const Float_t * const pos)
1553 {
1554   //
1555   // Returns the y coordinate in the Pad reference frame
1556   //
1557
1558   Float_t ypad = -2.;
1559
1560   Float_t posLocal[3];
1561   for (Int_t ii=0; ii<3; ii++) posLocal[ii] = pos[ii];
1562  
1563   Int_t isector = GetSector(posLocal);
1564   if(isector == -1){
1565     //AliError("Detector Index could not be determined");
1566     return ypad;}
1567   Int_t iplate =  GetPlate(posLocal);
1568   if(iplate == -1){
1569     //AliError("Detector Index could not be determined");
1570     return ypad;} 
1571   Int_t istrip =  GetStrip(posLocal);
1572   if(istrip == -1){  
1573     //AliError("Detector Index could not be determined");
1574     return ypad;}
1575   Int_t ipadz =  GetPadZ(posLocal);
1576   if(ipadz == -1){  
1577     //AliError("Detector Index could not be determined");
1578     return ypad;}
1579   Int_t ipadx =  GetPadX(posLocal);
1580   if(ipadx == -1){
1581     //AliError("Detector Index could not be determined");
1582     return ypad;}
1583
1584   // ALICE reference frame -> B071/B074/B075 = BTO1/2/3 reference frame
1585   Double_t angles[6] = 
1586     {90., 90.+(isector+0.5)*fgkPhiSec,
1587       0.,  0.,
1588      90., (isector+0.5)*fgkPhiSec
1589     };
1590   Rotation(posLocal,angles);
1591
1592   Float_t step[3] = {0., 0., (fgkRmax+fgkRmin)*0.5};
1593   Translation(posLocal,step);
1594
1595   // B071/B074/B075 = BTO1/2/3 reference frame -> FTOA/B/C = FLTA/B/C reference frame
1596   angles[0] = 90.;
1597   angles[1] =  0.;
1598   angles[2] =  0.;
1599   angles[3] =  0.;
1600   angles[4] = 90.;
1601   angles[5] =270.;
1602
1603   Rotation(posLocal,angles);
1604
1605   // FTOA/B/C = FLTA/B/C reference frame -> FSTR reference frame
1606   step[0] = 0.;
1607   step[1] = GetHeights(iplate,istrip);
1608   step[2] = -GetDistances(iplate,istrip);
1609   Translation(posLocal,step);
1610
1611   if      (GetAngles(iplate,istrip) >0.) {
1612     angles[0] = 90.;
1613     angles[1] =  0.;
1614     angles[2] = 90.+GetAngles(iplate,istrip);
1615     angles[3] = 90.;
1616     angles[4] = GetAngles(iplate,istrip);
1617     angles[5] = 90.;
1618   }
1619   else if (GetAngles(iplate,istrip)==0.) {
1620     angles[0] = 90.;
1621     angles[1] =  0.;
1622     angles[2] = 90.;
1623     angles[3] = 90.;
1624     angles[4] =  0;
1625     angles[5] =  0.;
1626   }
1627   else if (GetAngles(iplate,istrip) <0.) {
1628     angles[0] = 90.;
1629     angles[1] =  0.;
1630     angles[2] = 90.+GetAngles(iplate,istrip);
1631     angles[3] = 90.;
1632     angles[4] =-GetAngles(iplate,istrip);
1633     angles[5] = 270.;
1634   }
1635   Rotation(posLocal,angles);
1636
1637   step[0] =-0.5*kNpadX*fgkXPad;
1638   step[1] = 0.;
1639   step[2] =-0.5*kNpadZ*fgkZPad;
1640   Translation(posLocal,step);
1641   
1642   step[0] = (ipadx+0.5)*fgkXPad;
1643   step[1] = 0.;
1644   step[2] = (ipadz+0.5)*fgkZPad;
1645   Translation(posLocal,step);
1646   
1647   ypad=posLocal[1];
1648   
1649   return ypad;
1650
1651 }
1652 //_____________________________________________________________________________
1653 Float_t AliTOFGeometry::GetPadDz(const Float_t * const pos)
1654 {
1655   //
1656   // Returns the z coordinate in the Pad reference frame
1657   //
1658
1659   Float_t zpad = -2.;
1660
1661   Float_t posLocal[3];
1662   for (Int_t ii=0; ii<3; ii++) posLocal[ii] = pos[ii];
1663  
1664   Int_t isector = GetSector(posLocal);
1665   if(isector == -1){
1666     //AliError("Detector Index could not be determined");
1667     return zpad;}
1668   Int_t iplate =  GetPlate(posLocal);
1669   if(iplate == -1){
1670     //AliError("Detector Index could not be determined");
1671     return zpad;} 
1672   Int_t istrip =  GetStrip(posLocal);
1673   if(istrip == -1){  
1674     //AliError("Detector Index could not be determined");
1675     return zpad;}
1676   Int_t ipadz =  GetPadZ(posLocal);
1677   if(ipadz == -1){  
1678     //AliError("Detector Index could not be determined");
1679     return zpad;}
1680   Int_t ipadx =  GetPadX(posLocal);
1681   if(ipadx == -1){
1682     //AliError("Detector Index could not be determined");
1683     return zpad;}
1684
1685   // ALICE reference frame -> B071/B074/B075 = BTO1/2/3 reference frame
1686   Double_t angles[6] = 
1687     {90., 90.+(isector+0.5)*fgkPhiSec,
1688       0.,  0.,
1689      90., (isector+0.5)*fgkPhiSec
1690     };
1691   Rotation(posLocal,angles);
1692
1693   Float_t step[3] = {0., 0., (fgkRmax+fgkRmin)*0.5};
1694   Translation(posLocal,step);
1695
1696   // B071/B074/B075 = BTO1/2/3 reference frame -> FTOA/B/C = FLTA/B/C reference frame
1697   angles[0] = 90.;
1698   angles[1] =  0.;
1699   angles[2] =  0.;
1700   angles[3] =  0.;
1701   angles[4] = 90.;
1702   angles[5] =270.;
1703
1704   Rotation(posLocal,angles);
1705
1706   // FTOA/B/C = FLTA/B/C reference frame -> FSTR reference frame
1707   step[0] = 0.;
1708   step[1] = GetHeights(iplate,istrip);
1709   step[2] = -GetDistances(iplate,istrip);
1710   Translation(posLocal,step);
1711
1712   if      (GetAngles(iplate,istrip) >0.) {
1713     angles[0] = 90.;
1714     angles[1] =  0.;
1715     angles[2] = 90.+GetAngles(iplate,istrip);
1716     angles[3] = 90.;
1717     angles[4] = GetAngles(iplate,istrip);
1718     angles[5] = 90.;
1719   }
1720   else if (GetAngles(iplate,istrip)==0.) {
1721     angles[0] = 90.;
1722     angles[1] =  0.;
1723     angles[2] = 90.;
1724     angles[3] = 90.;
1725     angles[4] =  0;
1726     angles[5] =  0.;
1727   }
1728   else if (GetAngles(iplate,istrip) <0.) {
1729     angles[0] = 90.;
1730     angles[1] =  0.;
1731     angles[2] = 90.+GetAngles(iplate,istrip);
1732     angles[3] = 90.;
1733     angles[4] =-GetAngles(iplate,istrip);
1734     angles[5] = 270.;
1735   }
1736   Rotation(posLocal,angles);
1737
1738   step[0] =-0.5*kNpadX*fgkXPad;
1739   step[1] = 0.;
1740   step[2] =-0.5*kNpadZ*fgkZPad;
1741   Translation(posLocal,step);
1742   
1743   step[0] = (ipadx+0.5)*fgkXPad;
1744   step[1] = 0.;
1745   step[2] = (ipadz+0.5)*fgkZPad;
1746   Translation(posLocal,step);
1747
1748   zpad=posLocal[2];
1749
1750   return zpad;
1751
1752 }
1753 //_____________________________________________________________________________
1754
1755 void AliTOFGeometry::Translation(Float_t *xyz, Float_t translationVector[3]) const
1756 {
1757   //
1758   // Return the vector xyz translated by translationVector vector
1759   //
1760
1761   Int_t ii=0;
1762
1763   for (ii=0; ii<3; ii++)
1764     xyz[ii] -= translationVector[ii];
1765
1766   return;
1767
1768 }
1769 //_____________________________________________________________________________
1770
1771 void AliTOFGeometry::Rotation(Float_t *xyz, Double_t rotationAngles[6]) const
1772 {
1773   //
1774   // Return the vector xyz rotated according to the rotationAngles angles
1775   //
1776
1777   Int_t ii=0;
1778   /*
1779   TRotMatrix *matrix = new TRotMatrix("matrix","matrix", angles[0], angles[1],
1780                                       angles[2], angles[3],
1781                                       angles[4], angles[5]);
1782   */
1783
1784   for (ii=0; ii<6; ii++) rotationAngles[ii]*=kDegrad;
1785
1786   Float_t xyzDummy[3] = {0., 0., 0.};
1787
1788   for (ii=0; ii<3; ii++) {
1789     xyzDummy[ii] =
1790       xyz[0]*TMath::Sin(rotationAngles[2*ii])*TMath::Cos(rotationAngles[2*ii+1]) +
1791       xyz[1]*TMath::Sin(rotationAngles[2*ii])*TMath::Sin(rotationAngles[2*ii+1]) +
1792       xyz[2]*TMath::Cos(rotationAngles[2*ii]);
1793   }
1794
1795   for (ii=0; ii<3; ii++) xyz[ii]=xyzDummy[ii];
1796
1797   return;
1798
1799 }
1800 //_____________________________________________________________________________
1801 void AliTOFGeometry::InverseRotation(Float_t *xyz, Double_t rotationAngles[6]) const
1802 {
1803   //
1804   // Rotates the vector xyz acordint to the rotationAngles
1805   //
1806
1807   Int_t ii=0;
1808
1809   for (ii=0; ii<6; ii++) rotationAngles[ii]*=kDegrad;
1810
1811   Float_t xyzDummy[3] = {0., 0., 0.};
1812
1813   xyzDummy[0] =
1814     xyz[0]*TMath::Sin(rotationAngles[0])*TMath::Cos(rotationAngles[1]) +
1815     xyz[1]*TMath::Sin(rotationAngles[2])*TMath::Cos(rotationAngles[3]) +
1816     xyz[2]*TMath::Sin(rotationAngles[4])*TMath::Cos(rotationAngles[5]);
1817   
1818   xyzDummy[1] =
1819     xyz[0]*TMath::Sin(rotationAngles[0])*TMath::Sin(rotationAngles[1]) +
1820     xyz[1]*TMath::Sin(rotationAngles[2])*TMath::Sin(rotationAngles[3]) +
1821     xyz[2]*TMath::Sin(rotationAngles[4])*TMath::Sin(rotationAngles[5]);
1822   
1823   xyzDummy[2] =
1824     xyz[0]*TMath::Cos(rotationAngles[0]) +
1825     xyz[1]*TMath::Cos(rotationAngles[2]) +
1826     xyz[2]*TMath::Cos(rotationAngles[4]);
1827   
1828   for (ii=0; ii<3; ii++) xyz[ii]=xyzDummy[ii];
1829
1830   return;
1831
1832 }
1833 //_____________________________________________________________________________
1834
1835 Int_t AliTOFGeometry::GetIndex(const Int_t * const detId)
1836 {
1837   //Retrieve calibration channel index 
1838   Int_t isector = detId[0];
1839   if (isector >= kNSectors){
1840     printf("Wrong sector number in TOF (%d) !\n",isector);
1841     return -1;
1842   }
1843   Int_t iplate = detId[1];
1844   if (iplate >= kNPlates){
1845     printf("Wrong plate number in TOF (%d) !\n",iplate);
1846     return -1;
1847   }
1848   Int_t istrip = detId[2];
1849   Int_t stripOffset = GetStripNumberPerSM(iplate,istrip);
1850   if (stripOffset==-1) {
1851     printf("Wrong strip number per SM in TOF (%d) !\n",stripOffset);
1852     return -1;
1853   }
1854
1855   Int_t ipadz = detId[3];
1856   Int_t ipadx = detId[4];
1857
1858   Int_t idet = ((2*(kNStripC+kNStripB)+kNStripA)*kNpadZ*kNpadX)*isector +
1859                (stripOffset*kNpadZ*kNpadX)+
1860                (kNpadX)*ipadz+
1861                 ipadx;
1862   return idet;
1863 }
1864 //_____________________________________________________________________________
1865
1866 void AliTOFGeometry::GetVolumeIndices(Int_t index, Int_t *detId)
1867 {
1868   //
1869   // Retrieve volume indices from the calibration channel index 
1870   //
1871
1872   detId[0] = index/NpadXStrip()/NStripXSector();
1873
1874   Int_t dummyStripPerModule = 
1875     ( index - ( NStripXSector()*NpadXStrip()*detId[0]) ) / NpadXStrip();
1876   if (dummyStripPerModule<kNStripC) {
1877     detId[1] = 0;
1878     detId[2] = dummyStripPerModule;
1879   }
1880   else if (dummyStripPerModule>=kNStripC && dummyStripPerModule<kNStripC+kNStripB) {
1881     detId[1] = 1;
1882     detId[2] = dummyStripPerModule-kNStripC;
1883   }
1884   else if (dummyStripPerModule>=kNStripC+kNStripB && dummyStripPerModule<kNStripC+kNStripB+kNStripA) {
1885     detId[1] = 2;
1886     detId[2] = dummyStripPerModule-kNStripC-kNStripB;
1887   }
1888   else if (dummyStripPerModule>=kNStripC+kNStripB+kNStripA && dummyStripPerModule<kNStripC+kNStripB+kNStripA+kNStripB) {
1889     detId[1] = 3;
1890     detId[2] = dummyStripPerModule-kNStripC-kNStripB-kNStripA;
1891   }
1892   else if (dummyStripPerModule>=kNStripC+kNStripB+kNStripA+kNStripB && dummyStripPerModule<NStripXSector()) {
1893     detId[1] = 4;
1894     detId[2] = dummyStripPerModule-kNStripC-kNStripB-kNStripA-kNStripB;
1895   }
1896
1897   Int_t padPerStrip = ( index - ( NStripXSector()*NpadXStrip()*detId[0]) ) - dummyStripPerModule*NpadXStrip();
1898
1899   detId[3] = padPerStrip / kNpadX; // padZ
1900   detId[4] = padPerStrip - detId[3]*kNpadX; // padX
1901
1902 }
1903 //_____________________________________________________________________________
1904
1905 Int_t AliTOFGeometry::NStrip(Int_t nPlate)
1906 {
1907   //
1908   // Returns the strips number for the plate number 'nPlate'
1909   //
1910
1911   Int_t nStrips = kNStripC;
1912
1913   switch(nPlate) {
1914   case 2:
1915     nStrips = kNStripA;
1916     break;
1917   case 1:
1918   case 3:
1919     nStrips = kNStripB;
1920     break;
1921   case 0:
1922   case 4:
1923   default:
1924     nStrips = kNStripC;
1925     break;
1926   }
1927
1928   return nStrips;
1929
1930 }
1931 //-------------------------------------------------------------------------
1932
1933 UShort_t AliTOFGeometry::GetAliSensVolIndex(Int_t isector, Int_t iplate, Int_t istrip) const
1934 {
1935   //
1936   // Get the index of the TOF alignable volume in the AliGeomManager order.
1937   //
1938
1939   Int_t index = GetStripNumber(isector, iplate, istrip);
1940
1941   UShort_t volIndex = AliGeomManager::LayerToVolUID(AliGeomManager::kTOF,index);
1942
1943   return volIndex;
1944
1945 }
1946 //-------------------------------------------------------------------------
1947
1948 Int_t AliTOFGeometry::GetStripNumber(Int_t isector, Int_t iplate, Int_t istrip)
1949 {
1950   //
1951   // Get the serial number of the TOF strip number istrip [0,14/18],
1952   //   in the module number iplate [0,4],
1953   //   in the TOF SM number isector [0,17].
1954   // This number will range in [0,1637].
1955   //
1956
1957   Bool_t check = (isector >= kNSectors);
1958
1959   if (check)
1960     printf("E-AliTOFGeometry::GetStripNumber: Wrong sector number in TOF (%d)!\n",isector);
1961
1962   Int_t index = -1;
1963   Int_t stripInSM = GetStripNumberPerSM(iplate, istrip);
1964   if (!check && stripInSM!=-1)
1965     index = (2*(kNStripC+kNStripB)+kNStripA)*isector + stripInSM;
1966
1967   return index;
1968
1969 }
1970 //-------------------------------------------------------------------------
1971
1972 Int_t AliTOFGeometry::GetStripNumberPerSM(Int_t iplate, Int_t istrip)
1973 {
1974   //
1975   // Get the serial number of the TOF strip number istrip [0,14/18],
1976   //   in the module number iplate [0,4].
1977   // This number will range in [0,90].
1978   //
1979
1980   Int_t index = -1;
1981
1982   Bool_t check = (
1983                   (iplate<0 || iplate>=kNPlates)
1984                   ||
1985                   (
1986                    (iplate==2 && (istrip<0 || istrip>=kNStripA))
1987                    ||
1988                    (iplate!=2 && (istrip<0 || istrip>=kNStripC))
1989                    )
1990                   );
1991
1992   if (iplate<0 || iplate>=kNPlates)
1993     printf("E-AliTOFGeometry::GetStripNumberPerSM: Wrong plate number in TOF (%1d)!\n",iplate);
1994
1995   if (
1996       (iplate==2 && (istrip<0 || istrip>=kNStripA))
1997       ||
1998       (iplate!=2 && (istrip<0 || istrip>=kNStripC))
1999       )
2000     printf("E-AliTOFGeometry::GetStripNumberPerSM: Wrong strip number in TOF "
2001            "(strip=%2d in the plate=%1d)!\n",istrip,iplate);
2002
2003   Int_t stripOffset = 0;
2004   switch (iplate) {
2005   case 0:
2006     stripOffset = 0;
2007     break;
2008   case 1:
2009     stripOffset = kNStripC;
2010     break;
2011   case 2:
2012     stripOffset = kNStripC+kNStripB;
2013     break;
2014   case 3:
2015     stripOffset = kNStripC+kNStripB+kNStripA;
2016     break;
2017   case 4:
2018     stripOffset = kNStripC+kNStripB+kNStripA+kNStripB;
2019     break;
2020   };
2021
2022   if (!check) index = stripOffset + istrip;
2023
2024   return index;
2025
2026 }
2027 //-------------------------------------------------------------------------
2028
2029 void AliTOFGeometry::PadRF2TrackingRF(Float_t *ctrackPos, Float_t *differenceT)
2030 {
2031   //
2032   // To convert the 3D distance ctrackPos, referred to the ALICE RF,
2033   // into the 3D distance differenceT, referred to the tracking RF
2034   // in case ctrakPos belongs to a TOF sensitive volume.
2035   //
2036
2037   for (Int_t ii=0; ii<3; ii++) differenceT[ii] = 999.;
2038
2039   AliDebug(1,Form(" track position in ALICE global Ref. frame -> %f, %f, %f",
2040                   ctrackPos[0],ctrackPos[1],ctrackPos[2]));
2041
2042   Int_t detId[5] = {-1,-1,-1,-1,-1};
2043
2044   detId[0] = GetSector(ctrackPos);
2045   if (detId[0]==-1) {
2046     AliWarning(Form("This point does not belong to any TOF sector"));
2047     return;
2048   }
2049
2050   detId[1] = GetPlate(ctrackPos);
2051   if (detId[1]==-1) {
2052     AliWarning(Form("This point does not belong to any TOF module"));
2053     return;
2054   }
2055
2056   detId[2] = GetStrip(ctrackPos);
2057   if (detId[2]==-1) {
2058     AliWarning(Form("This point does not belong to any TOF strip"));
2059     return;
2060   }
2061
2062   detId[3] = GetPadZ(ctrackPos);
2063   if (detId[3]==-1) {
2064     AliWarning(Form("This point does not belong to any TOF pad-row"));
2065     return;
2066   }
2067
2068   detId[4] = GetPadX(ctrackPos);
2069   if (detId[4]==-1) {
2070     AliWarning(Form("This point does not belong to any TOF pad"));
2071     return;
2072   }
2073
2074
2075   UShort_t alignableStripIndex =
2076     GetAliSensVolIndex(detId[0],detId[1],detId[2]);
2077   AliDebug(1,Form(" sector = %2d, plate = %1d, strip = %2d (padZ = %1d, padX = %2d) "
2078                   "---> stripIndex = %4d",
2079                   detId[0], detId[1], detId[2], detId[3], detId[4], alignableStripIndex));
2080
2081   // pad centre coordinates in the strip ref. frame
2082   Double_t padCentreL[3] = {(detId[4]-AliTOFGeometry::NpadX()/2)*AliTOFGeometry::XPad()
2083                             +AliTOFGeometry::XPad()/2.,
2084                             0.,
2085                             (detId[3]-AliTOFGeometry::NpadZ()/2)*AliTOFGeometry::XPad()
2086                             +AliTOFGeometry::XPad()/2.};
2087   // pad centre coordinates in the strip tracking frame
2088   Double_t padCentreT[3] = {0., 0., 0.};
2089   TGeoHMatrix l2t = *AliGeomManager::GetTracking2LocalMatrix(alignableStripIndex);
2090   l2t.MasterToLocal(padCentreL,padCentreT);
2091
2092
2093   Char_t path[100];
2094   // pad centre coordinates in its ref. frame
2095   Double_t padCentreL2[3] = {0., 0., 0.};
2096   // pad centre coordinates in the ALICE global ref. frame
2097   Double_t padCentreG[3] = {0., 0., 0.};
2098   GetVolumePath(detId,path);
2099   gGeoManager->cd(path);
2100   TGeoHMatrix g2l = *gGeoManager->GetCurrentMatrix();
2101   TGeoHMatrix l2g = g2l.Inverse();
2102   l2g.MasterToLocal(padCentreL2,padCentreG);
2103
2104
2105   Char_t path2[100];
2106   // strip centre coordinates in its ref. frame
2107   Double_t stripCentreL[3] = {0., 0., 0.};
2108   // strip centre coordinates in the ALICE global ref. frame
2109   Double_t stripCentreG[3] = {0., 0., 0.};
2110   GetVolumePath(detId[0],detId[1],detId[2],path2);
2111   gGeoManager->cd(path2);
2112   TGeoHMatrix g2lb = *gGeoManager->GetCurrentMatrix();
2113   TGeoHMatrix l2gb = g2lb.Inverse();
2114   l2gb.MasterToLocal(stripCentreL,stripCentreG);
2115
2116   TGeoHMatrix g2t = 0;
2117   AliGeomManager::GetTrackingMatrix(alignableStripIndex, g2t);
2118
2119   // track position in the ALICE global ref. frame
2120   Double_t posG[3];
2121   for (Int_t ii=0; ii<3; ii++) posG[ii] = (Double_t)ctrackPos[ii];
2122
2123   // strip centre coordinates in the tracking ref. frame
2124   Double_t stripCentreT[3] = {0., 0., 0.};
2125   // track position in the tracking ref. frame
2126   Double_t posT[3] = {0., 0., 0.};
2127   g2t.MasterToLocal(posG,posT);
2128   g2t.MasterToLocal(stripCentreG,stripCentreT);
2129
2130   for (Int_t ii=0; ii<3; ii++)
2131     AliDebug(1,Form(" track position in ALICE global and tracking RFs -> posG[%d] = %f --- posT[%d] = %f",
2132                     ii, posG[ii], ii, posT[ii]));
2133   for (Int_t ii=0; ii<3; ii++)
2134     AliDebug(1,Form(" pad centre coordinates in its, the ALICE global and tracking RFs -> "
2135                     "padCentreL[%d] = %f --- padCentreG[%d] = %f --- padCentreT[%d] = %f",
2136                     ii, padCentreL[ii],
2137                     ii, padCentreG[ii],
2138                     ii, padCentreT[ii]));
2139   for (Int_t ii=0; ii<3; ii++)
2140     AliDebug(1,Form(" strip centre coordinates in its, the ALICE global and tracking RFs -> "
2141                     "stripCentreL[%d] = %f --- stripCentreG[%d] = %f --- stripCentreT[%d] = %f",
2142                     ii, stripCentreL[ii],
2143                     ii, stripCentreG[ii],
2144                     ii, stripCentreT[ii]));
2145   for (Int_t ii=0; ii<3; ii++)
2146     AliDebug(1,Form(" difference between the track position and the pad centre in the tracking RF "
2147                     "-> posT[%d]-padCentreT[%d] = %f",
2148                     ii,ii,
2149                     posT[ii]-padCentreT[ii]));
2150
2151   for (Int_t ii=0; ii<3; ii++) differenceT[ii] = (Float_t)(posT[ii]-padCentreT[ii]);
2152
2153 }