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