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