Possibility for partial TOF geometry (S.Arcelli)
[u/mrichter/AliRoot.git] / TOF / AliTOFGeometryV5.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.5  2006/04/20 22:30:50  hristov
19 Coding conventions (Annalisa)
20
21 Revision 1.4  2006/04/16 22:29:05  hristov
22 Coding conventions (Annalisa)
23
24 Revision 1.3  2006/03/12 14:38:05  arcelli
25  Changes for TOF Reconstruction using TGeo
26
27 Revision 1.2  2006/02/28 10:38:00  decaro
28 AliTOFGeometry::fAngles, AliTOFGeometry::fHeights, AliTOFGeometry::fDistances arrays: dimension definition in the right location
29
30 Revision 1.1  2005/12/15 08:55:33  decaro
31 New TOF geometry description (V5) -G. Cara Romeo and A. De Caro
32
33 Revision 0.1  2005/07/19 G. Cara Romeo and A. De Caro
34         Modify Global methods IsInsideThePad & DistanceToPad
35                according to the new TOF geometry
36         Implement Global  methods GetPadDx & GetPadDy & GetPadDz
37         Implement Private methods Translation & Rotation & InverseRotation
38         Modify Global methods GetDetID & GetPlate & GetSector &
39                               GetStrip & GetPadX & GetPadZ
40                according to the new TOF geometry
41         Modify Global methods GetPos & GetX & GetY & GetZ
42                according to the new TOF geometry
43 */
44
45 ///////////////////////////////////////////////////////////////////////////////
46 //                                                                           //
47 //  TOF Geometry class (new version)                                         //
48 //                                                                           //
49 ///////////////////////////////////////////////////////////////////////////////
50
51 #include "TGeoManager.h"
52
53 #include "AliConst.h"
54 #include "AliLog.h"
55
56 #include "AliTOFGeometryV5.h"
57
58 extern TGeoManager *gGeoManager;
59
60 ClassImp(AliTOFGeometryV5)
61
62
63 const Float_t AliTOFGeometryV5::fgkZlenA    = 370.6*2.; // length (cm) of the A module
64 const Float_t AliTOFGeometryV5::fgkZlenB    = 146.5;    // length (cm) of the B module
65 const Float_t AliTOFGeometryV5::fgkZlenC    = 170.45;   // length (cm) of the C module
66 const Float_t AliTOFGeometryV5::fgkMaxhZtof = 370.6;    // Max half z-size of TOF (cm)
67
68 const Float_t AliTOFGeometryV5::fgkxTOF     = 371.-0.01;// Inner radius of the TOF for Reconstruction (cm)
69 const Float_t AliTOFGeometryV5::fgkRmin     = 370.-0.01;// Inner radius of the TOF (cm)
70 const Float_t AliTOFGeometryV5::fgkRmax     = 399.-0.01;// Outer radius of the TOF (cm)
71
72 //_____________________________________________________________________________
73 AliTOFGeometryV5::AliTOFGeometryV5()
74   :AliTOFGeometry()
75 {
76   //
77   // AliTOFGeometryV5 default constructor
78   //
79
80   AliTOFGeometry::fNStripC     = kNStripC;       // number of strips in C type module
81
82   AliTOFGeometry::fZlenA       = fgkZlenA;       // length of the TOF supermodule (cm)
83   AliTOFGeometry::fZlenB       = fgkZlenB;       // length of the B module (cm)
84   AliTOFGeometry::fZlenC       = fgkZlenC;       // length of the C module (cm)
85   AliTOFGeometry::fMaxhZtof    = fgkMaxhZtof;    // Max half z-size of TOF supermodule (cm)
86
87   AliTOFGeometry::fxTOF   = fgkxTOF;           // Inner radius of the TOF for Reconstruction (cm)
88   AliTOFGeometry::fRmin   = fgkRmin;           // Inner radius of the TOF (cm)
89   AliTOFGeometry::fRmax   = fgkRmax;           // Outer radius of the TOF (cm)
90
91   Init();
92
93 }
94
95 //_____________________________________________________________________________
96 AliTOFGeometryV5::~AliTOFGeometryV5()
97 {
98   //
99   // AliTOFGeometryV5 destructor
100   //
101
102 }
103 //_____________________________________________________________________________
104 void AliTOFGeometryV5::ImportGeometry(){
105   TGeoManager::Import("geometry.root");
106 }
107 //_____________________________________________________________________________
108 void AliTOFGeometryV5::Init()
109 {
110   //
111   // Initialize strip Tilt Angles, Heights and Distances
112   //
113   // Strips Tilt Angles
114  
115   // For each strip to be positoned in FLTA/FLTB/FLTC,
116   // define 3 arrays containing:
117   //   the angle of the normal with respect to the Y axis of FLTA/FLTB/FLTC
118   //   the Y of the center with respect to the FLTA/FLTB/FLTC reference frame
119   //   the Z of the center with respect to the BT01/BT02/BT03 reference frame
120
121
122   fPhiSec   = 360./kNSectors;
123
124   Float_t const kangles[kNPlates][kMaxNstrip] ={
125     { 43.99,  43.20,  42.40,  41.59,  40.77,  39.94,  39.11,  38.25,  37.40,  36.53,
126       35.65,  34.76,  33.87,  32.96,  32.05,  31.13,  30.19,  29.24,  12.33,  0.00},
127
128     { 27.26,  26.28,  25.30,  24.31,  23.31,  22.31,  21.30,  20.29,  19.26,  18.24,
129       17.20,  16.16,  15.11,  14.05,  13.00,  11.93,  10.87,   9.80,   8.74,  0.00},
130
131     {  0.00,   6.30,   5.31,   4.25,   3.19,   2.12,   1.06,   0.00,  -1.06,  -2.12,
132       -3.19,  -4.25,  -5.31,  -6.30,   0.00,   0.00,   0.00,   0.00,   0.00,  0.00},
133
134     { -8.74,  -9.80, -10.87, -11.93, -13.00, -14.05, -15.11, -16.16, -17.20, -18.24,
135      -19.26, -20.29, -21.30, -22.31, -23.31, -24.31, -25.30, -26.28, -27.26,  0.00},
136     
137     {-12.33, -29.24, -30.19, -31.13, -32.05, -32.96, -33.87, -34.76, -35.65, -36.53,
138      -37.40, -38.25, -39.11, -39.94, -40.77, -41.59, -42.40, -43.20, -43.99,  0.00}
139   };
140
141   Float_t const kheights[kNPlates][kMaxNstrip]= {
142     {-8.2,  -7.5,  -8.2,  -7.7,  -8.1,  -7.6,  -7.7,  -7.7,  -7.7,  -7.7,
143      -7.5,  -7.2,  -7.3,  -7.5,  -7.6,  -7.8,  -8.3,  -9.3,  -3.1,   0.0},
144
145     {-7.9,  -8.1,  -8.5,  -9.0, -10.1,  -3.9,  -5.9,  -7.7, -10.1,  -3.6,
146      -5.8,  -8.0, -10.4,  -4.4,  -7.2, -10.2,  -4.6,  -7.4, -10.4,   0.0},
147
148     {-2.5, -10.4,  -5.0,  -9.9,  -4.8,  -9.9,  -4.7, -10.2,  -4.7,  -9.9,
149      -4.8,  -9.9,  -5.0, -10.4,  -2.5,   0.0,   0.0,   0.0,   0.0,   0.0},
150
151     {-10.4, -7.4,  -4.6, -10.2,  -7.2,  -4.4, -10.4,  -8.0,  -5.8,  -3.6,
152      -10.1,  -7.7, -5.9,  -3.9, -10.1,  -9.0,  -8.5,  -8.1,  -7.9,   0.0},
153
154     { -3.1,  -9.3, -8.3,  -7.8,  -7.6,  -7.5,  -7.3,  -7.2,  -7.5,  -7.7,
155       -7.7,  -7.7, -7.7,  -7.6,  -8.1,  -7.7,  -8.2,  -7.5,  -8.2,   0.0}
156   };
157
158
159   Float_t const kdistances[kNPlates][kMaxNstrip]= {
160     { 364.1,  354.9,  344.5,  335.4,  325.5,  316.6,  307.2,  298.0,  288.9,  280.0,
161       271.3,  262.7,  254.0,  244.8,  236.1,  227.7,  219.1,  210.3,  205.7,    0.0},
162
163     { 194.2,  186.1,  177.9,  169.8,  161.5,  156.3,  147.8,  139.4,  130.9,  125.6,
164       117.3,  109.2,  101.1,   95.3,   87.1,   79.2,   73.0,   65.1,   57.6,    0.0},
165
166     {  49.5,   41.3,   35.3,   27.8,   21.2,   13.9,    7.0,    0.0,   -7.0,  -13.9,
167       -21.2,  -27.8,  -35.3,  -41.3,  -49.5,    0.0,    0.0,    0.0,    0.0,    0.0},
168
169     { -57.6,  -65.1,  -73.0,  -79.2,  -87.1,  -95.3, -101.1, -109.2, -117.3, -125.6,
170      -130.9, -139.4, -147.8, -156.3, -161.5, -169.8, -177.9, -186.1, -194.2,    0.0},
171
172     {-205.7, -210.3, -219.1, -227.7, -236.1, -244.8, -254.0, -262.7, -271.3, -280.0,
173      -288.9, -298.0, -307.2, -316.6, -325.5, -335.4, -344.5, -354.9, -364.1,    0.0}
174   };
175
176
177   for (Int_t iplate = 0; iplate < kNPlates; iplate++) {
178     for (Int_t istrip = 0; istrip < kMaxNstrip; istrip++) {
179       AliTOFGeometry::fAngles[iplate][istrip]   = kangles[iplate][istrip];
180       AliTOFGeometry::fHeights[iplate][istrip]  = kheights[iplate][istrip];
181       AliTOFGeometry::fDistances[iplate][istrip]= kdistances[iplate][istrip];
182     }
183   }
184
185 }
186
187 //_____________________________________________________________________________
188 Float_t AliTOFGeometryV5::DistanceToPadPar(Int_t *det, Float_t *pos, Float_t *dist3d) const
189 {
190 //
191 // Returns distance of  space point with coor pos (x,y,z) (cm) wrt 
192 // pad with Detector Indices idet (iSect,iPlate,iStrip,iPadX,iPadZ) 
193 //
194     
195   //Transform pos into Sector Frame
196
197   Float_t x = pos[0];
198   Float_t y = pos[1];
199   Float_t z = pos[2];
200
201   Float_t radius = TMath::Sqrt(x*x+y*y);
202   //Float_t phi=TMath::ATan(y/x);       
203   //if(phi<0) phi = k2PI+phi; //2.*TMath::Pi()+phi;
204   Float_t phi = TMath::Pi()+TMath::ATan2(-y,-x);        
205   //  Get the local angle in the sector philoc
206   Float_t angle   = phi*kRaddeg-( Int_t (kRaddeg*phi/fPhiSec) + 0.5)*fPhiSec;
207   Float_t xs = radius*TMath::Cos(angle/kRaddeg);
208   Float_t ys = radius*TMath::Sin(angle/kRaddeg);
209   Float_t zs = z;
210
211   // Do the same for the selected pad
212
213   Float_t g[3];
214   GetPosPar(det,g);
215
216   Float_t padRadius = TMath::Sqrt(g[0]*g[0]+g[1]*g[1]);
217   //Float_t padPhi = TMath::ATan(g[1]/g[0]);    
218   //if(padPhi<0) padPhi = k2Pi + padPhi;
219   Float_t padPhi = TMath::Pi()+TMath::ATan2(-g[1],-g[0]);       
220
221   //  Get the local angle in the sector philoc
222   Float_t padAngle = padPhi*kRaddeg-( Int_t (padPhi*kRaddeg/fPhiSec)+ 0.5) * fPhiSec;
223   Float_t padxs = padRadius*TMath::Cos(padAngle/kRaddeg);
224   Float_t padys = padRadius*TMath::Sin(padAngle/kRaddeg);
225   Float_t padzs = g[2];
226   
227   //Now move to local pad coordinate frame. Translate:
228   
229   Float_t xt = xs-padxs;
230   Float_t yt = ys-padys;
231   Float_t zt = zs-padzs;
232   //Now Rotate:
233   
234   Float_t alpha = GetAngles(det[1],det[2]);
235   Float_t xr =  xt*TMath::Cos(alpha/kRaddeg)+zt*TMath::Sin(alpha/kRaddeg);
236   Float_t yr =  yt;
237   Float_t zr = -xt*TMath::Sin(alpha/kRaddeg)+zt*TMath::Cos(alpha/kRaddeg);
238
239   Float_t dist = TMath::Sqrt(xr*xr+yr*yr+zr*zr);
240
241   if (dist3d){
242     dist3d[0] = xr;
243     dist3d[1] = yr;
244     dist3d[2] = zr;
245   }
246
247   return dist;
248
249 }
250
251 //_____________________________________________________________________________
252 Bool_t AliTOFGeometryV5::IsInsideThePadPar(Int_t *det, Float_t *pos) const
253 {
254 //
255 // Returns true if space point with coor pos (x,y,z) (cm) falls 
256 // inside pad with Detector Indices idet (iSect,iPlate,iStrip,iPadX,iPadZ) 
257 //
258
259   Bool_t isInside=false; 
260
261   /*
262   const Float_t khhony    = 1.0          ; // heigth of HONY  Layer
263   const Float_t khpcby    = 0.08         ; // heigth of PCB   Layer
264   const Float_t khrgly    = 0.055        ; // heigth of RED GLASS  Layer
265   const Float_t khglfy    = 0.285        ; // heigth of GLASS+FISHLINE  Layer
266   const Float_t khcpcby   = 0.16         ; // heigth of PCB  Central Layer
267   //const Float_t kwcpcbz   = 12.4         ; // z dimension of PCB  Central Layer
268   const Float_t khstripy = 2.*khhony+2.*khpcby+4.*khrgly+2.*khglfy+khcpcby;//3.11
269   //const Float_t kwstripz = kwcpcbz;
270   //const Float_t klstripx = fgkStripLength;
271   */
272
273   const Float_t khsensmy = 0.5;//0.05;//0.11;//0.16;//          // heigth of Sensitive Layer
274
275   //Transform pos into Sector Frame
276
277   Float_t x = pos[0];
278   Float_t y = pos[1];
279   Float_t z = pos[2];
280
281   Float_t radius = TMath::Sqrt(x*x+y*y);
282   Float_t phi = TMath::Pi()+TMath::ATan2(-y,-x);        
283
284   //  Get the local angle in the sector philoc
285   Float_t angle = phi*kRaddeg-( Int_t (kRaddeg*phi/fPhiSec) + 0.5) *fPhiSec;
286   Float_t xs = radius*TMath::Cos(angle/kRaddeg);
287   Float_t ys = radius*TMath::Sin(angle/kRaddeg);
288   Float_t zs = z;
289
290   // Do the same for the selected pad
291
292   Float_t g[3];
293   GetPosPar(det,g);
294
295   Float_t padRadius = TMath::Sqrt(g[0]*g[0]+g[1]*g[1]);
296   Float_t padPhi = TMath::Pi()+TMath::ATan2(-g[1],-g[0]);       
297
298   //  Get the local angle in the sector philoc
299   Float_t padAngle = padPhi*kRaddeg-( Int_t (padPhi*kRaddeg/fPhiSec)+ 0.5) * fPhiSec; 
300   Float_t padxs = padRadius*TMath::Cos(padAngle/kRaddeg);
301   Float_t padys = padRadius*TMath::Sin(padAngle/kRaddeg);
302   Float_t padzs = g[2];
303
304   //Now move to local pad coordinate frame. Translate:
305
306   Float_t xt = xs-padxs;
307   Float_t yt = ys-padys;
308   Float_t zt = zs-padzs;
309
310   //Now Rotate:
311
312   Float_t alpha = GetAngles(det[1],det[2]);
313   Float_t xr =  xt*TMath::Cos(alpha/kRaddeg)+zt*TMath::Sin(alpha/kRaddeg);
314   Float_t yr =  yt;
315   Float_t zr = -xt*TMath::Sin(alpha/kRaddeg)+zt*TMath::Cos(alpha/kRaddeg);
316
317   if(TMath::Abs(xr)<=khsensmy*0.5 && TMath::Abs(yr)<= (fgkXPad*0.5) && TMath::Abs(zr)<= (fgkZPad*0.5))
318     isInside=true;
319   return isInside;
320
321 }
322
323
324 //_____________________________________________________________________________
325 Float_t AliTOFGeometryV5::DistanceToPad(Int_t *det, TGeoHMatrix mat, Float_t *pos, Float_t *dist3d) const
326 {
327 //
328 // Returns distance of  space point with coor pos (x,y,z) (cm) wrt 
329 // pad with Detector Indices idet (iSect,iPlate,iStrip,iPadX,iPadZ) 
330 //
331   if (!gGeoManager) {
332     printf("ERROR: no TGeo\n");
333     return 0.;
334   }
335   Double_t vecg[3];
336   vecg[0]=pos[0];
337   vecg[1]=pos[1];
338   vecg[2]=pos[2];
339   Double_t veclr[3]={-1.,-1.,-1.};
340   Double_t vecl[3]={-1.,-1.,-1.};
341   mat.MasterToLocal(vecg,veclr);  
342   vecl[0]=veclr[1];
343   vecl[1]=veclr[0];
344   //take into account reflections 
345   if(det[1]>-1)vecl[2]=-veclr[2];
346
347   Float_t dist = TMath::Sqrt(vecl[0]*vecl[0]+vecl[1]*vecl[1]+vecl[2]*vecl[2]);
348
349
350   if (dist3d){
351     dist3d[0] = vecl[0];
352     dist3d[1] = vecl[1];
353     dist3d[2] = vecl[2];
354   }
355
356   return dist;
357
358 }
359
360
361 //_____________________________________________________________________________
362 Bool_t AliTOFGeometryV5::IsInsideThePad( Int_t *det, TGeoHMatrix mat, Float_t *pos) const
363 {
364 //
365 // Returns true if space point with coor pos (x,y,z) (cm) falls 
366 // inside pad with Detector Indices idet (iSect,iPlate,iStrip,iPadX,iPadZ) 
367 //
368
369   const Float_t khsensmy = 0.5;      // heigth of Sensitive Layer
370   Double_t vecg[3];
371   vecg[0]=pos[0];
372   vecg[1]=pos[1];
373   vecg[2]=pos[2];
374   Double_t veclr[3]={-1.,-1.,-1.};
375   Double_t vecl[3]={-1.,-1.,-1.};
376   mat.MasterToLocal(vecg,vecl);  
377   vecl[0]=veclr[1];
378   vecl[1]=veclr[0];
379   //take into account reflections 
380   if(det[1]>-1)vecl[2]=-veclr[2];
381
382   Float_t xr = vecl[0];
383   Float_t yr = vecl[1];
384   Float_t zr = vecl[2];
385
386   Bool_t isInside=false; 
387   if(TMath::Abs(xr)<= khsensmy*0.5 && TMath::Abs(yr)<= (fgkXPad*0.5) && TMath::Abs(zr)<= (fgkZPad*0.5))
388     isInside=true; 
389   return isInside;
390
391 }
392 //_____________________________________________________________________________
393 //_____________________________________________________________________________
394 Float_t AliTOFGeometryV5::GetX(Int_t *det) const
395 {
396   //
397   // Returns X coordinate (cm)
398   //
399
400   Int_t isector = det[0];
401   Int_t iplate  = det[1];
402   Int_t istrip  = det[2];
403   Int_t ipadz   = det[3];
404   Int_t ipadx   = det[4];
405
406   /*
407   // Find out distance d on the plane wrt median phi:
408   Float_t d = (ipadx+0.5-kNpadX*0.5)*fgkXPad;
409
410   // The radius r in xy plane:
411   //Float_t r = (fgkRmin+fgkRmax)*0.5-0.01+GetHeights(iplate,istrip)+
412   //  (ipadz-0.5)*fgkZPad*TMath::Sin(GetAngles(iplate,istrip)/kRaddeg)-0.25; ???
413   Float_t r = (fgkRmin+fgkRmax)*0.5-0.01+GetHeights(iplate,istrip)+
414     (ipadz-0.5)*fgkZPad*TMath::Sin(GetAngles(iplate,istrip)/kRaddeg);
415
416   // local azimuthal angle in the sector philoc
417   Float_t philoc  = TMath::ATan(d/r);
418   //if(philoc<0.) philoc = k2PI + philoc;
419
420   // azimuthal angle in the global frame  phi
421   Float_t phi   = philoc*kRaddeg+(isector+0.5)*fPhiSec;
422
423   Float_t xCoor = r/TMath::Cos(philoc)*TMath::Cos(phi/kRaddeg);
424   */
425
426   // Pad reference frame -> FSTR reference frame
427   //  /*
428   Float_t posLocal[3] = {0., 0., 0.};
429   Float_t step[3] = {-(ipadx+0.5)*fgkXPad, 0., -(ipadz+0.5)*fgkZPad};
430   Translation(posLocal,step);
431
432   step[0] = kNpadX*0.5*fgkXPad;
433   step[1] = 0.;
434   step[2] = kNpadZ*0.5*fgkZPad;
435   //  */
436   /*
437   Float_t posLocal[3] = {(ipadx+0.5)*fgkXPad, 0., (ipadz+0.5)*fgkZPad};
438   Float_t step[3]= {kNpadX*0.5*fgkXPad, 0., kNpadZ*0.5*fgkZPad};
439   */
440   Translation(posLocal,step);
441
442   // FSTR reference frame -> FTOA/B/C = FLTA/B/C reference frame
443   Double_t angles[6];
444   if      (GetAngles(iplate,istrip) >0.) {
445     angles[0] = 90.;
446     angles[1] =  0.;
447     angles[2] = 90.+GetAngles(iplate,istrip);
448     angles[3] = 90.;
449     angles[4] = GetAngles(iplate,istrip);
450     angles[5] = 90.;
451   }
452   else if (GetAngles(iplate,istrip)==0.) {
453     angles[0] = 90.;
454     angles[1] =  0.;
455     angles[2] = 90.;
456     angles[3] = 90.;
457     angles[4] =  0;
458     angles[5] =  0.;
459   }
460   else if (GetAngles(iplate,istrip) <0.) {
461     angles[0] = 90.;
462     angles[1] =  0.;
463     angles[2] = 90.+GetAngles(iplate,istrip);
464     angles[3] = 90.;
465     angles[4] =-GetAngles(iplate,istrip);
466     angles[5] = 270.;
467   }
468
469   InverseRotation(posLocal,angles);
470
471   step[0] = 0.;
472   step[1] = -GetHeights(iplate,istrip);
473   step[2] =  GetDistances(iplate,istrip);
474   Translation(posLocal,step);
475
476   // FTOA = FLTA reference frame -> B071/B074/B075 = BTO1/2/3 reference frame
477   angles[0] = 90.;
478   angles[1] =  0.;
479   angles[2] =  0.;
480   angles[3] =  0.;
481   angles[4] = 90.;
482   angles[5] =270.;
483
484   InverseRotation(posLocal,angles);
485
486   // B071/B074/B075 = BTO1/2/3 reference frame -> ALICE reference frame
487   step[0] = 0.;
488   step[1] = 0.;
489   step[2] = -((fgkRmax+fgkRmin)*0.5);
490   Translation(posLocal,step);
491
492   angles[0] = 90.;
493   angles[1] = 90.+(isector+0.5)*fPhiSec;
494   angles[2] = 0.;
495   angles[3] = 0.;
496   angles[4] = 90.;
497   angles[5] = (isector+0.5)*fPhiSec;
498
499   InverseRotation(posLocal,angles);
500
501   Float_t xCoor = posLocal[0];
502
503   return xCoor;
504
505 }
506 //_____________________________________________________________________________
507 Float_t AliTOFGeometryV5::GetY(Int_t *det) const
508 {
509   //
510   // Returns Y coordinate (cm)
511   //
512
513   Int_t isector = det[0];
514   Int_t iplate  = det[1];
515   Int_t istrip  = det[2];
516   Int_t ipadz   = det[3];
517   Int_t ipadx   = det[4];
518
519   /*
520   // Find out distance d on the plane wrt median phi:
521   Float_t d = (ipadx+0.5-kNpadX*0.5)*fgkXPad;
522
523   // The radius r in xy plane:
524   //Float_t r = (fgkRmin+fgkRmax)*0.5-0.01+GetHeights(iplate,istrip)+
525   //  (ipadz-0.5)*fgkZPad*TMath::Sin(GetAngles(iplate,istrip)/kRaddeg)-0.25; ???
526   Float_t r = (fgkRmin+fgkRmax)*0.5-0.01+GetHeights(iplate,istrip)+
527     (ipadz-0.5)*fgkZPad*TMath::Sin(GetAngles(iplate,istrip)/kRaddeg);
528
529   // local azimuthal angle in the sector philoc
530   Float_t philoc = TMath::ATan(d/r);
531   //if(philoc<0.) philoc = k2PI + philoc;
532
533   // azimuthal angle in the global frame  phi
534   Float_t phi   = philoc*kRaddeg+(isector+0.5)*fPhiSec;
535
536   Float_t yCoor = r/TMath::Cos(philoc)*TMath::Sin(phi/kRaddeg);
537   */
538
539   // Pad reference frame -> FSTR reference frame
540   //  /*
541   Float_t posLocal[3] = {0., 0., 0.};
542   Float_t step[3] = {-(ipadx+0.5)*fgkXPad, 0., -(ipadz+0.5)*fgkZPad};
543   Translation(posLocal,step);
544
545   step[0] = kNpadX*0.5*fgkXPad;
546   step[1] = 0.;
547   step[2] = kNpadZ*0.5*fgkZPad;
548   //  */
549   /*
550   Float_t posLocal[3] = {(ipadx+0.5)*fgkXPad, 0., (ipadz+0.5)*fgkZPad};
551   Float_t step[3]= {kNpadX*0.5*fgkXPad, 0., kNpadZ*0.5*fgkZPad};
552   */
553   Translation(posLocal,step);
554
555   // FSTR reference frame -> FTOA/B/C = FLTA/B/C reference frame
556
557   Double_t angles[6];
558   if      (GetAngles(iplate,istrip) >0.) {
559     angles[0] = 90.;
560     angles[1] =  0.;
561     angles[2] = 90.+GetAngles(iplate,istrip);
562     angles[3] = 90.;
563     angles[4] = GetAngles(iplate,istrip);
564     angles[5] = 90.;
565   }
566   else if (GetAngles(iplate,istrip)==0.) {
567     angles[0] = 90.;
568     angles[1] =  0.;
569     angles[2] = 90.;
570     angles[3] = 90.;
571     angles[4] =  0;
572     angles[5] =  0.;
573   }
574   else if (GetAngles(iplate,istrip) <0.) {
575     angles[0] = 90.;
576     angles[1] =  0.;
577     angles[2] = 90.+GetAngles(iplate,istrip);
578     angles[3] = 90.;
579     angles[4] =-GetAngles(iplate,istrip);
580     angles[5] = 270.;
581   }
582
583   InverseRotation(posLocal,angles);
584
585   step[0] = 0.;
586   step[1] = -GetHeights(iplate,istrip);
587   step[2] =  GetDistances(iplate,istrip);
588   Translation(posLocal,step);
589
590   // FTOA = FLTA reference frame -> B071/B074/B075 = BTO1/2/3 reference frame
591   angles[0] = 90.;
592   angles[1] =  0.;
593   angles[2] =  0.;
594   angles[3] =  0.;
595   angles[4] = 90.;
596   angles[5] =270.;
597
598   InverseRotation(posLocal,angles);
599
600   // B071/B074/B075 = BTO1/2/3 reference frame -> ALICE reference frame
601   step[0] = 0.;
602   step[1] = 0.;
603   step[2] = -((fgkRmax+fgkRmin)*0.5);
604   Translation(posLocal,step);
605
606   angles[0] = 90.;
607   angles[1] = 90.+(isector+0.5)*fPhiSec;
608   angles[2] = 0.;
609   angles[3] = 0.;
610   angles[4] = 90.;
611   angles[5] = (isector+0.5)*fPhiSec;
612
613   InverseRotation(posLocal,angles);
614
615   Float_t yCoor = posLocal[1];
616
617   return yCoor;
618
619 }
620
621 //_____________________________________________________________________________
622 Float_t AliTOFGeometryV5::GetZ(Int_t *det) const
623 {
624   //
625   // Returns Z coordinate (cm)
626   //
627
628   Int_t isector = det[0];
629   Int_t iplate  = det[1];
630   Int_t istrip  = det[2];
631   Int_t ipadz   = det[3];
632   Int_t ipadx   = det[4];
633
634   /*
635   Float_t zCoor = GetDistances(iplate,istrip) +
636     (0.5-ipadz) * fgkZPad * TMath::Cos(GetAngles(iplate,istrip)*kDegrad);
637   */
638
639   // Pad reference frame -> FSTR reference frame
640   //  /*
641   Float_t posLocal[3] = {0., 0., 0.};
642   Float_t step[3] = {-(ipadx+0.5)*fgkXPad, 0., -(ipadz+0.5)*fgkZPad};
643   Translation(posLocal,step);
644
645   step[0] = kNpadX*0.5*fgkXPad;
646   step[1] = 0.;
647   step[2] = kNpadZ*0.5*fgkZPad;
648   //  */
649   /*
650   Float_t posLocal[3] = {(ipadx+0.5)*fgkXPad, 0., (ipadz+0.5)*fgkZPad};
651   Float_t step[3]= {kNpadX*0.5*fgkXPad, 0., kNpadZ*0.5*fgkZPad};
652   */
653   Translation(posLocal,step);
654
655   // FSTR reference frame -> FTOA/B/C = FLTA/B/C reference frame
656   Double_t angles[6];
657   if      (GetAngles(iplate,istrip) >0.) {
658     angles[0] = 90.;
659     angles[1] =  0.;
660     angles[2] = 90.+GetAngles(iplate,istrip);
661     angles[3] = 90.;
662     angles[4] = GetAngles(iplate,istrip);
663     angles[5] = 90.;
664   }
665   else if (GetAngles(iplate,istrip)==0.) {
666     angles[0] = 90.;
667     angles[1] =  0.;
668     angles[2] = 90.;
669     angles[3] = 90.;
670     angles[4] =  0;
671     angles[5] =  0.;
672   }
673   else if (GetAngles(iplate,istrip) <0.) {
674     angles[0] = 90.;
675     angles[1] =  0.;
676     angles[2] = 90.+GetAngles(iplate,istrip);
677     angles[3] = 90.;
678     angles[4] =-GetAngles(iplate,istrip);
679     angles[5] = 270.;
680   }
681
682   InverseRotation(posLocal,angles);
683
684   step[0] = 0.;
685   step[1] = -GetHeights(iplate,istrip);
686   step[2] =  GetDistances(iplate,istrip);
687   Translation(posLocal,step);
688
689   // FTOA = FLTA reference frame -> B071/B074/B075 = BTO1/2/3 reference frame
690   angles[0] = 90.;
691   angles[1] =  0.;
692   angles[2] =  0.;
693   angles[3] =  0.;
694   angles[4] = 90.;
695   angles[5] =270.;
696
697   InverseRotation(posLocal,angles);
698
699   // B071/B074/B075 = BTO1/2/3 reference frame -> ALICE reference frame
700   step[0] = 0.;
701   step[1] = 0.;
702   step[2] = -((fgkRmax+fgkRmin)*0.5);
703   Translation(posLocal,step);
704
705   angles[0] = 90.;
706   angles[1] = 90.+(isector+0.5)*fPhiSec;
707   angles[2] = 0.;
708   angles[3] = 0.;
709   angles[4] = 90.;
710   angles[5] = (isector+0.5)*fPhiSec;
711
712   InverseRotation(posLocal,angles);
713
714   Float_t zCoor = posLocal[2];
715
716   return zCoor;
717
718 }
719
720 //_____________________________________________________________________________
721 Int_t AliTOFGeometryV5::GetSector(Float_t *pos) const
722 {
723   //
724   // Returns the Sector index 
725   //
726
727   //const Float_t khAlWall = 0.1;
728   //const Float_t kModuleWallThickness = 0.3;
729
730   Int_t   iSect = -1; 
731
732   Float_t x = pos[0];
733   Float_t y = pos[1];
734   Float_t z = pos[2];
735
736   Float_t rho = TMath::Sqrt(x*x + y*y);
737
738   //if (!((z>=-fgkMaxhZtof && z<=fgkMaxhZtof) &&
739   if (!((z>=-fgkZlenA*0.5 && z<=fgkZlenA*0.5) &&
740         (rho>=(fgkRmin) && rho<=(fgkRmax)))) {
741     //(rho>=(fgkRmin-0.05)+kModuleWallThickness && rho<=(fgkRmax-0.05)-kModuleWallThickness-khAlWall-kModuleWallThickness))) {
742     //AliError("Detector Index could not be determined");
743     return iSect;
744   }
745
746   Float_t phi = TMath::Pi() + TMath::ATan2(-y,-x);      
747
748   iSect  = (Int_t) (phi*kRaddeg/fPhiSec);
749   
750   return iSect;
751
752 }
753 //_____________________________________________________________________________
754
755 Int_t AliTOFGeometryV5::GetPlate(Float_t *pos) const
756 {
757   //
758   // Returns the Plate index 
759   //
760   const Float_t kInterCentrModBorder1 = 49.5;
761   const Float_t kInterCentrModBorder2 = 57.5;
762   const Float_t kExterInterModBorder1 = 196.0;
763   const Float_t kExterInterModBorder2 = 203.5;
764
765   const Float_t kLengthExInModBorder  = 4.7;
766   const Float_t kLengthInCeModBorder  = 7.0;
767
768   //const Float_t khAlWall = 0.1;
769   const Float_t kModuleWallThickness = 0.3;
770   //const Float_t kHoneycombLayerThickness = 1.5;
771
772   Int_t iPlate=-1;
773
774   Float_t posLocal[3];
775   for (Int_t ii=0; ii<3; ii++) posLocal[ii] = pos[ii];
776
777   Int_t isector = GetSector(posLocal);
778   if(isector == -1){
779     //AliError("Detector Index could not be determined");
780     return iPlate;
781   }
782
783   // ALICE reference frame -> B071/B074/B075 = BTO1/2/3 reference frame
784   Double_t angles[6] = 
785     {90., 90.+(isector+0.5)*fPhiSec,
786       0., 0.,
787      90., (isector+0.5)*fPhiSec
788     };
789   Rotation(posLocal,angles);
790
791   Float_t step[3] = {0., 0., (fgkRmax+fgkRmin)*0.5};
792   Translation(posLocal,step);
793
794   // B071/B074/B075 = BTO1/2/3 reference frame -> FTOA = FLTA reference frame
795   angles[0] = 90.;
796   angles[1] =  0.;
797   angles[2] =  0.;
798   angles[3] =  0.;
799   angles[4] = 90.;
800   angles[5] =270.;
801
802   Rotation(posLocal,angles);
803
804   Float_t yLocal = posLocal[1];
805   Float_t zLocal = posLocal[2];
806
807   Float_t deltaRhoLoc  = (fgkRmax-fgkRmin)*0.5 - kModuleWallThickness + yLocal;
808   Float_t deltaZetaLoc = TMath::Abs(zLocal);
809
810   Float_t deltaRHOmax = 0.;
811
812   if (TMath::Abs(zLocal)>=kExterInterModBorder1 && TMath::Abs(zLocal)<=kExterInterModBorder2) 
813     {
814       deltaRhoLoc -= kLengthExInModBorder;
815       deltaZetaLoc = kExterInterModBorder2-deltaZetaLoc;
816       deltaRHOmax  = (fgkRmax - fgkRmin)*0.5 - kModuleWallThickness - 2.*kLengthExInModBorder; // old 5.35, new 4.8
817
818       if (deltaRhoLoc > deltaZetaLoc*deltaRHOmax/(kInterCentrModBorder2-kInterCentrModBorder1)) {
819         if (zLocal<0) iPlate = 0;
820         else iPlate = 4;
821       }
822       else {
823         if (zLocal<0) iPlate = 1;
824         else iPlate = 3;
825       }
826     }
827   else if (TMath::Abs(zLocal)>=kInterCentrModBorder1 && TMath::Abs(zLocal)<=kInterCentrModBorder2) 
828     {
829       deltaRhoLoc -= kLengthInCeModBorder;
830       deltaZetaLoc = deltaZetaLoc-kInterCentrModBorder1;
831       deltaRHOmax = (fgkRmax - fgkRmin)*0.5 - kModuleWallThickness - 2.*kLengthInCeModBorder; // old 0.39, new 0.2
832
833       if (deltaRhoLoc>deltaZetaLoc*deltaRHOmax/(kInterCentrModBorder2-kInterCentrModBorder1)) iPlate = 2;
834       else {
835         if (zLocal<0) iPlate = 1;
836         else iPlate = 3;
837       }
838     }
839
840   if      (zLocal>-fgkZlenA*0.5/*fgkMaxhZtof*/ && zLocal<-kExterInterModBorder2)       iPlate = 0;
841   else if (zLocal>-kExterInterModBorder1       && zLocal<-kInterCentrModBorder2)       iPlate = 1;
842   else if (zLocal>-kInterCentrModBorder1       && zLocal< kInterCentrModBorder1)       iPlate = 2;
843   else if (zLocal> kInterCentrModBorder2       && zLocal< kExterInterModBorder1)       iPlate = 3;
844   else if (zLocal> kExterInterModBorder2       && zLocal< fgkZlenA*0.5/*fgkMaxhZtof*/) iPlate = 4;
845   
846   return iPlate;
847
848 }
849
850 //_____________________________________________________________________________
851 Int_t AliTOFGeometryV5::GetStrip(Float_t *pos) const
852 {
853   //
854   // Returns the Strip index 
855   //
856   const Float_t khhony    = 1.0          ; // heigth of HONY  Layer
857   const Float_t khpcby    = 0.08         ; // heigth of PCB   Layer
858   const Float_t khrgly    = 0.055        ; // heigth of RED GLASS  Layer
859   const Float_t khglfy    = 0.285        ; // heigth of GLASS+FISHLINE  Layer
860   const Float_t khcpcby   = 0.16         ; // heigth of PCB  Central Layer
861   const Float_t kwcpcbz   = 12.4         ; // z dimension of PCB  Central Layer
862   const Float_t khstripy = 2.*khhony+2.*khpcby+4.*khrgly+2.*khglfy+khcpcby;//3.11
863   const Float_t kwstripz = kwcpcbz;
864   const Float_t klstripx = fgkStripLength;
865   
866   Int_t iStrip=-1;
867    
868   Float_t posLocal[3];
869   for (Int_t ii=0; ii<3; ii++) posLocal[ii] = pos[ii];
870  
871   Int_t isector = GetSector(posLocal);
872   if(isector == -1){
873     //AliError("Detector Index could not be determined");
874     return iStrip;}
875   Int_t iplate =  GetPlate(posLocal);
876   if(iplate == -1){
877     //AliError("Detector Index could not be determined");
878     return iStrip;} 
879
880   Int_t nstrips=0;
881   switch (iplate) {
882   case 0:
883     nstrips=kNStripC;
884     break;
885   case 4:
886     nstrips=kNStripC;
887     break;
888   case 1:
889     nstrips=kNStripB;
890     break;
891   case 3:
892     nstrips=kNStripB;
893     break;
894   case 2:
895     nstrips=kNStripA;
896     break;
897   }
898   
899   // ALICE reference frame -> B071/B074/B075 = BTO1/2/3 reference frame
900   Double_t angles[6] = 
901     {90., 90.+(isector+0.5)*fPhiSec,
902       0., 0.,
903      90., (isector+0.5)*fPhiSec
904     };
905   Rotation(posLocal,angles);
906
907   Float_t step[3] = {0., 0., (fgkRmax+fgkRmin)*0.5};
908   Translation(posLocal,step);
909
910   // B071/B074/B075 = BTO1/2/3 reference frame -> FTOA = FLTA reference frame
911   angles[0] = 90.;
912   angles[1] =  0.;
913   angles[2] =  0.;
914   angles[3] =  0.;
915   angles[4] = 90.;
916   angles[5] =270.;
917
918   Rotation(posLocal,angles);
919
920   // FTOA/B/C = FLTA/B/C reference frame -> FSTR reference frame
921   Int_t totStrip=0;
922   for (Int_t istrip=0; istrip<nstrips; istrip++){
923
924     Float_t posLoc2[3]={posLocal[0],posLocal[1],posLocal[2]};         
925
926     step[0] = 0.;
927     step[1] = GetHeights(iplate,istrip);
928     step[2] = -GetDistances(iplate,istrip);
929     Translation(posLoc2,step);
930
931     if      (GetAngles(iplate,istrip) >0.) {
932       angles[0] = 90.;
933       angles[1] =  0.;
934       angles[2] = 90.+GetAngles(iplate,istrip);
935       angles[3] = 90.;
936       angles[4] = GetAngles(iplate,istrip);
937       angles[5] = 90.;
938     }
939     else if (GetAngles(iplate,istrip)==0.) {
940       angles[0] = 90.;
941       angles[1] =  0.;
942       angles[2] = 90.;
943       angles[3] = 90.;
944       angles[4] =  0;
945       angles[5] =  0.;
946     }
947     else if (GetAngles(iplate,istrip) <0.) {
948       angles[0] = 90.;
949       angles[1] =  0.;
950       angles[2] = 90.+GetAngles(iplate,istrip);
951       angles[3] = 90.;
952       angles[4] =-GetAngles(iplate,istrip);
953       angles[5] = 270.;
954     }
955     Rotation(posLoc2,angles);
956
957     if ((TMath::Abs(posLoc2[0])<=klstripx*0.5) &&
958         (TMath::Abs(posLoc2[1])<=khstripy*0.5) &&
959         (TMath::Abs(posLoc2[2])<=kwstripz*0.5)) {
960       iStrip = istrip;
961       totStrip++;
962       for (Int_t jj=0; jj<3; jj++) posLocal[jj]=posLoc2[jj];
963       //AliInfo(Form(" posLocal[0] = %f, posLocal[1] = %f, posLocal[2] = %f ", posLocal[0],posLocal[1],posLocal[2]));
964
965       //AliInfo(Form(" GetAngles(%1i,%2i) = %f, pos[0] = %f, pos[1] = %f, pos[2] = %f", iplate, istrip, GetAngles(iplate,istrip), pos[0], pos[1], pos[2]));
966       break;
967     }
968
969     if (totStrip>1) AliInfo(Form("total strip number found %2i",totStrip));
970
971   }
972
973   return iStrip;
974   
975 }
976 //_____________________________________________________________________________
977 Int_t AliTOFGeometryV5::GetPadZ(Float_t *pos) const
978 {
979   //
980   // Returns the Pad index along Z 
981   //
982   //const Float_t klsensmx = kNpadX*fgkXPad;  // length of Sensitive Layer
983   //const Float_t khsensmy = 0.05;//0.11;//0.16;// heigth of Sensitive Layer
984   //const Float_t kwsensmz = kNpadZ*fgkZPad;  // width of Sensitive Layer
985
986   Int_t iPadZ = -1;
987
988   Float_t posLocal[3];
989   for (Int_t ii=0; ii<3; ii++) posLocal[ii] = pos[ii];
990  
991   Int_t isector = GetSector(posLocal);
992   if(isector == -1){
993     //AliError("Detector Index could not be determined");
994     return iPadZ;}
995   Int_t iplate =  GetPlate(posLocal);
996   if(iplate == -1){
997     //AliError("Detector Index could not be determined");
998     return iPadZ;}
999   Int_t istrip =  GetStrip(posLocal);
1000   if(istrip == -1){
1001     //AliError("Detector Index could not be determined");
1002     return iPadZ;}
1003
1004   // ALICE reference frame -> B071/B074/B075 = BTO1/2/3 reference frame
1005   Double_t angles[6] = 
1006     {90., 90.+(isector+0.5)*fPhiSec,
1007       0., 0.,
1008      90., (isector+0.5)*fPhiSec
1009     };
1010   Rotation(posLocal,angles);
1011
1012   Float_t step[3] = {0., 0., (fgkRmax+fgkRmin)*0.5};
1013   Translation(posLocal,step);
1014
1015   // B071/B074/B075 = BTO1/2/3 reference frame -> FTOA = FLTA reference frame
1016   angles[0] = 90.;
1017   angles[1] =  0.;
1018   angles[2] =  0.;
1019   angles[3] =  0.;
1020   angles[4] = 90.;
1021   angles[5] =270.;
1022
1023   Rotation(posLocal,angles);
1024
1025   // FTOA/B/C = FLTA/B/C reference frame -> FSTR reference frame
1026   step[0] = 0.;
1027   step[1] = GetHeights(iplate,istrip);
1028   step[2] = -GetDistances(iplate,istrip);
1029   Translation(posLocal,step);
1030
1031   if      (GetAngles(iplate,istrip) >0.) {
1032     angles[0] = 90.;
1033     angles[1] =  0.;
1034     angles[2] = 90.+GetAngles(iplate,istrip);
1035     angles[3] = 90.;
1036     angles[4] = GetAngles(iplate,istrip);
1037     angles[5] = 90.;
1038   }
1039   else if (GetAngles(iplate,istrip)==0.) {
1040     angles[0] = 90.;
1041     angles[1] =  0.;
1042     angles[2] = 90.;
1043     angles[3] = 90.;
1044     angles[4] =  0;
1045     angles[5] =  0.;
1046   }
1047   else if (GetAngles(iplate,istrip) <0.) {
1048     angles[0] = 90.;
1049     angles[1] =  0.;
1050     angles[2] = 90.+GetAngles(iplate,istrip);
1051     angles[3] = 90.;
1052     angles[4] =-GetAngles(iplate,istrip);
1053     angles[5] = 270.;
1054   }
1055   Rotation(posLocal,angles);
1056
1057   //if (TMath::Abs(posLocal[0])<=klsensmx*0.5 && /*TMath::Abs(posLocal[1])<=khsensmy*0.5+0.005 &&*/ TMath::Abs(posLocal[2])<=kwsensmz*0.5) {
1058   //if (TMath::Abs(posLocal[1])<=khsensmy*0.5) {
1059
1060     step[0] =-0.5*kNpadX*fgkXPad;
1061     step[1] = 0.;
1062     step[2] =-0.5*kNpadZ*fgkZPad;
1063     Translation(posLocal,step);
1064
1065     iPadZ = (Int_t)(posLocal[2]/fgkZPad);
1066     if (iPadZ==kNpadZ) iPadZ--;
1067     else if (iPadZ>kNpadZ) iPadZ=-1;
1068
1069   //}
1070   // else AliError("Detector Index could not be determined");
1071
1072   return iPadZ;
1073
1074 }
1075 //_____________________________________________________________________________
1076 Int_t AliTOFGeometryV5::GetPadX(Float_t *pos) const
1077 {
1078   //
1079   // Returns the Pad index along X 
1080   //
1081   //const Float_t klsensmx = kNpadX*fgkXPad;  // length of Sensitive Layer
1082   //const Float_t khsensmy = 0.05;//0.11;//0.16;// heigth of Sensitive Layer
1083   //const Float_t kwsensmz = kNpadZ*fgkZPad;  // width of Sensitive Layer
1084
1085   Int_t iPadX  = -1;
1086
1087   Float_t posLocal[3];
1088   for (Int_t ii=0; ii<3; ii++) posLocal[ii] = pos[ii];
1089  
1090   Int_t isector = GetSector(posLocal);
1091   if(isector == -1){
1092     //AliError("Detector Index could not be determined");
1093     return iPadX;}
1094   Int_t iplate =  GetPlate(posLocal);
1095   if(iplate == -1){
1096     //AliError("Detector Index could not be determined");
1097     return iPadX;} 
1098   Int_t istrip =  GetStrip(posLocal);
1099   if(istrip == -1){  
1100     //AliError("Detector Index could not be determined");
1101     return iPadX;}
1102
1103   // ALICE reference frame -> B071/B074/B075 = BTO1/2/3 reference frame
1104   Double_t angles[6] = 
1105     {90., 90.+(isector+0.5)*fPhiSec,
1106       0.,  0.,
1107      90., (isector+0.5)*fPhiSec
1108     };
1109   Rotation(posLocal,angles);
1110
1111   Float_t step[3] = {0., 0., (fgkRmax+fgkRmin)*0.5};
1112   Translation(posLocal,step);
1113
1114   // B071/B074/B075 = BTO1/2/3 reference frame -> FTOA/B/C = FLTA/B/C reference frame
1115   angles[0] = 90.;
1116   angles[1] =  0.;
1117   angles[2] =  0.;
1118   angles[3] =  0.;
1119   angles[4] = 90.;
1120   angles[5] =270.;
1121
1122   Rotation(posLocal,angles);
1123
1124   // FTOA/B/C = FLTA/B/C reference frame -> FSTR reference frame
1125   step[0] = 0.;
1126   step[1] = GetHeights(iplate,istrip);
1127   step[2] = -GetDistances(iplate,istrip);
1128   Translation(posLocal,step);
1129
1130   if      (GetAngles(iplate,istrip) >0.) {
1131     angles[0] = 90.;
1132     angles[1] =  0.;
1133     angles[2] = 90.+GetAngles(iplate,istrip);
1134     angles[3] = 90.;
1135     angles[4] = GetAngles(iplate,istrip);
1136     angles[5] = 90.;
1137   }
1138   else if (GetAngles(iplate,istrip)==0.) {
1139     angles[0] = 90.;
1140     angles[1] =  0.;
1141     angles[2] = 90.;
1142     angles[3] = 90.;
1143     angles[4] =  0;
1144     angles[5] =  0.;
1145   }
1146   else if (GetAngles(iplate,istrip) <0.) {
1147     angles[0] = 90.;
1148     angles[1] =  0.;
1149     angles[2] = 90.+GetAngles(iplate,istrip);
1150     angles[3] = 90.;
1151     angles[4] =-GetAngles(iplate,istrip);
1152     angles[5] = 270.;
1153   }
1154   Rotation(posLocal,angles);
1155
1156   //if (TMath::Abs(posLocal[0])<=klsensmx*0.5 && /*TMath::Abs(posLocal[1])<=khsensmy*0.5+0.005 &&*/ TMath::Abs(posLocal[2])<=kwsensmz*0.5) {
1157   //if (TMath::Abs(posLocal[1])<=khsensmy*0.5) {
1158
1159     step[0] =-0.5*kNpadX*fgkXPad;
1160     step[1] = 0.;
1161     step[2] =-0.5*kNpadZ*fgkZPad;
1162     Translation(posLocal,step);
1163
1164     iPadX = (Int_t)(posLocal[0]/fgkXPad);
1165     if (iPadX==kNpadX) iPadX--;
1166     else if (iPadX>kNpadX) iPadX=-1;
1167
1168   //}
1169   //else AliError("Detector Index could not be determined");
1170
1171   return iPadX;
1172
1173 }
1174 //_____________________________________________________________________________
1175
1176 Float_t AliTOFGeometryV5::GetPadDx(Float_t *pos)
1177 {
1178   //
1179   // Returns the x coordinate in the Pad reference frame
1180   //
1181
1182   Float_t xpad = -2.;
1183
1184   Float_t posLocal[3];
1185   for (Int_t ii=0; ii<3; ii++) posLocal[ii] = pos[ii];
1186  
1187   Int_t isector = GetSector(posLocal);
1188   if(isector == -1){
1189     //AliError("Detector Index could not be determined");
1190     return xpad;}
1191   Int_t iplate =  GetPlate(posLocal);
1192   if(iplate == -1){
1193     //AliError("Detector Index could not be determined");
1194     return xpad;} 
1195   Int_t istrip =  GetStrip(posLocal);
1196   if(istrip == -1){  
1197     //AliError("Detector Index could not be determined");
1198     return xpad;}
1199   Int_t ipadz =  GetPadZ(posLocal);
1200   if(ipadz == -1){  
1201     //AliError("Detector Index could not be determined");
1202     return xpad;}
1203   Int_t ipadx =  GetPadX(posLocal);
1204   if(ipadx == -1){
1205     //AliError("Detector Index could not be determined");
1206     return xpad;}
1207
1208   // ALICE reference frame -> B071/B074/B075 = BTO1/2/3 reference frame
1209   Double_t angles[6] = 
1210     {90., 90.+(isector+0.5)*fPhiSec,
1211       0.,  0.,
1212      90., (isector+0.5)*fPhiSec
1213     };
1214   Rotation(posLocal,angles);
1215
1216   Float_t step[3] = {0., 0., (fgkRmax+fgkRmin)*0.5};
1217   Translation(posLocal,step);
1218
1219   // B071/B074/B075 = BTO1/2/3 reference frame -> FTOA/B/C = FLTA/B/C reference frame
1220   angles[0] = 90.;
1221   angles[1] =  0.;
1222   angles[2] =  0.;
1223   angles[3] =  0.;
1224   angles[4] = 90.;
1225   angles[5] =270.;
1226
1227   Rotation(posLocal,angles);
1228
1229   // FTOA/B/C = FLTA/B/C reference frame -> FSTR reference frame
1230   step[0] = 0.;
1231   step[1] = GetHeights(iplate,istrip);
1232   step[2] = -GetDistances(iplate,istrip);
1233   Translation(posLocal,step);
1234
1235   if      (GetAngles(iplate,istrip) >0.) {
1236     angles[0] = 90.;
1237     angles[1] =  0.;
1238     angles[2] = 90.+GetAngles(iplate,istrip);
1239     angles[3] = 90.;
1240     angles[4] = GetAngles(iplate,istrip);
1241     angles[5] = 90.;
1242   }
1243   else if (GetAngles(iplate,istrip)==0.) {
1244     angles[0] = 90.;
1245     angles[1] =  0.;
1246     angles[2] = 90.;
1247     angles[3] = 90.;
1248     angles[4] =  0;
1249     angles[5] =  0.;
1250   }
1251   else if (GetAngles(iplate,istrip) <0.) {
1252     angles[0] = 90.;
1253     angles[1] =  0.;
1254     angles[2] = 90.+GetAngles(iplate,istrip);
1255     angles[3] = 90.;
1256     angles[4] =-GetAngles(iplate,istrip);
1257     angles[5] = 270.;
1258   }
1259   Rotation(posLocal,angles);
1260
1261   step[0] =-0.5*kNpadX*fgkXPad;
1262   step[1] = 0.;
1263   step[2] =-0.5*kNpadZ*fgkZPad;
1264   Translation(posLocal,step);
1265
1266   step[0] = (ipadx+0.5)*fgkXPad;
1267   step[1] = 0.;
1268   step[2] = (ipadz+0.5)*fgkZPad;
1269   Translation(posLocal,step);
1270   
1271   xpad=posLocal[0];
1272
1273   return xpad;
1274
1275 }
1276 //_____________________________________________________________________________
1277 Float_t AliTOFGeometryV5::GetPadDy(Float_t *pos)
1278 {
1279   //
1280   // Returns the x coordinate in the Pad reference frame
1281   //
1282
1283   Float_t ypad = -2.;
1284
1285   Float_t posLocal[3];
1286   for (Int_t ii=0; ii<3; ii++) posLocal[ii] = pos[ii];
1287  
1288   Int_t isector = GetSector(posLocal);
1289   if(isector == -1){
1290     //AliError("Detector Index could not be determined");
1291     return ypad;}
1292   Int_t iplate =  GetPlate(posLocal);
1293   if(iplate == -1){
1294     //AliError("Detector Index could not be determined");
1295     return ypad;} 
1296   Int_t istrip =  GetStrip(posLocal);
1297   if(istrip == -1){  
1298     //AliError("Detector Index could not be determined");
1299     return ypad;}
1300   Int_t ipadz =  GetPadZ(posLocal);
1301   if(ipadz == -1){  
1302     //AliError("Detector Index could not be determined");
1303     return ypad;}
1304   Int_t ipadx =  GetPadX(posLocal);
1305   if(ipadx == -1){
1306     //AliError("Detector Index could not be determined");
1307     return ypad;}
1308
1309   // ALICE reference frame -> B071/B074/B075 = BTO1/2/3 reference frame
1310   Double_t angles[6] = 
1311     {90., 90.+(isector+0.5)*fPhiSec,
1312       0.,  0.,
1313      90., (isector+0.5)*fPhiSec
1314     };
1315   Rotation(posLocal,angles);
1316
1317   Float_t step[3] = {0., 0., (fgkRmax+fgkRmin)*0.5};
1318   Translation(posLocal,step);
1319
1320   // B071/B074/B075 = BTO1/2/3 reference frame -> FTOA/B/C = FLTA/B/C reference frame
1321   angles[0] = 90.;
1322   angles[1] =  0.;
1323   angles[2] =  0.;
1324   angles[3] =  0.;
1325   angles[4] = 90.;
1326   angles[5] =270.;
1327
1328   Rotation(posLocal,angles);
1329
1330   // FTOA/B/C = FLTA/B/C reference frame -> FSTR reference frame
1331   step[0] = 0.;
1332   step[1] = GetHeights(iplate,istrip);
1333   step[2] = -GetDistances(iplate,istrip);
1334   Translation(posLocal,step);
1335
1336   if      (GetAngles(iplate,istrip) >0.) {
1337     angles[0] = 90.;
1338     angles[1] =  0.;
1339     angles[2] = 90.+GetAngles(iplate,istrip);
1340     angles[3] = 90.;
1341     angles[4] = GetAngles(iplate,istrip);
1342     angles[5] = 90.;
1343   }
1344   else if (GetAngles(iplate,istrip)==0.) {
1345     angles[0] = 90.;
1346     angles[1] =  0.;
1347     angles[2] = 90.;
1348     angles[3] = 90.;
1349     angles[4] =  0;
1350     angles[5] =  0.;
1351   }
1352   else if (GetAngles(iplate,istrip) <0.) {
1353     angles[0] = 90.;
1354     angles[1] =  0.;
1355     angles[2] = 90.+GetAngles(iplate,istrip);
1356     angles[3] = 90.;
1357     angles[4] =-GetAngles(iplate,istrip);
1358     angles[5] = 270.;
1359   }
1360   Rotation(posLocal,angles);
1361
1362   step[0] =-0.5*kNpadX*fgkXPad;
1363   step[1] = 0.;
1364   step[2] =-0.5*kNpadZ*fgkZPad;
1365   Translation(posLocal,step);
1366   
1367   step[0] = (ipadx+0.5)*fgkXPad;
1368   step[1] = 0.;
1369   step[2] = (ipadz+0.5)*fgkZPad;
1370   Translation(posLocal,step);
1371   
1372   ypad=posLocal[1];
1373   
1374   return ypad;
1375
1376 }
1377 //_____________________________________________________________________________
1378 Float_t AliTOFGeometryV5::GetPadDz(Float_t *pos)
1379 {
1380   //
1381   // Returns the x coordinate in the Pad reference frame
1382   //
1383
1384   Float_t zpad = -2.;
1385
1386   Float_t posLocal[3];
1387   for (Int_t ii=0; ii<3; ii++) posLocal[ii] = pos[ii];
1388  
1389   Int_t isector = GetSector(posLocal);
1390   if(isector == -1){
1391     //AliError("Detector Index could not be determined");
1392     return zpad;}
1393   Int_t iplate =  GetPlate(posLocal);
1394   if(iplate == -1){
1395     //AliError("Detector Index could not be determined");
1396     return zpad;} 
1397   Int_t istrip =  GetStrip(posLocal);
1398   if(istrip == -1){  
1399     //AliError("Detector Index could not be determined");
1400     return zpad;}
1401   Int_t ipadz =  GetPadZ(posLocal);
1402   if(ipadz == -1){  
1403     //AliError("Detector Index could not be determined");
1404     return zpad;}
1405   Int_t ipadx =  GetPadX(posLocal);
1406   if(ipadx == -1){
1407     //AliError("Detector Index could not be determined");
1408     return zpad;}
1409
1410   // ALICE reference frame -> B071/B074/B075 = BTO1/2/3 reference frame
1411   Double_t angles[6] = 
1412     {90., 90.+(isector+0.5)*fPhiSec,
1413       0.,  0.,
1414      90., (isector+0.5)*fPhiSec
1415     };
1416   Rotation(posLocal,angles);
1417
1418   Float_t step[3] = {0., 0., (fgkRmax+fgkRmin)*0.5};
1419   Translation(posLocal,step);
1420
1421   // B071/B074/B075 = BTO1/2/3 reference frame -> FTOA/B/C = FLTA/B/C reference frame
1422   angles[0] = 90.;
1423   angles[1] =  0.;
1424   angles[2] =  0.;
1425   angles[3] =  0.;
1426   angles[4] = 90.;
1427   angles[5] =270.;
1428
1429   Rotation(posLocal,angles);
1430
1431   // FTOA/B/C = FLTA/B/C reference frame -> FSTR reference frame
1432   step[0] = 0.;
1433   step[1] = GetHeights(iplate,istrip);
1434   step[2] = -GetDistances(iplate,istrip);
1435   Translation(posLocal,step);
1436
1437   if      (GetAngles(iplate,istrip) >0.) {
1438     angles[0] = 90.;
1439     angles[1] =  0.;
1440     angles[2] = 90.+GetAngles(iplate,istrip);
1441     angles[3] = 90.;
1442     angles[4] = GetAngles(iplate,istrip);
1443     angles[5] = 90.;
1444   }
1445   else if (GetAngles(iplate,istrip)==0.) {
1446     angles[0] = 90.;
1447     angles[1] =  0.;
1448     angles[2] = 90.;
1449     angles[3] = 90.;
1450     angles[4] =  0;
1451     angles[5] =  0.;
1452   }
1453   else if (GetAngles(iplate,istrip) <0.) {
1454     angles[0] = 90.;
1455     angles[1] =  0.;
1456     angles[2] = 90.+GetAngles(iplate,istrip);
1457     angles[3] = 90.;
1458     angles[4] =-GetAngles(iplate,istrip);
1459     angles[5] = 270.;
1460   }
1461   Rotation(posLocal,angles);
1462
1463   step[0] =-0.5*kNpadX*fgkXPad;
1464   step[1] = 0.;
1465   step[2] =-0.5*kNpadZ*fgkZPad;
1466   Translation(posLocal,step);
1467   
1468   step[0] = (ipadx+0.5)*fgkXPad;
1469   step[1] = 0.;
1470   step[2] = (ipadz+0.5)*fgkZPad;
1471   Translation(posLocal,step);
1472
1473   zpad=posLocal[2];
1474
1475   return zpad;
1476
1477 }
1478 //_____________________________________________________________________________
1479
1480 void AliTOFGeometryV5::Translation(Float_t *xyz, Float_t translationVector[3]) const
1481 {
1482   //
1483   // Return the vector xyz translated by translationVector vector
1484   //
1485
1486   Int_t ii=0;
1487
1488   for (ii=0; ii<3; ii++)
1489     xyz[ii] -= translationVector[ii];
1490
1491   return;
1492
1493 }
1494 //_____________________________________________________________________________
1495
1496 void AliTOFGeometryV5::Rotation(Float_t *xyz, Double_t rotationAngles[6]) const
1497 {
1498   //
1499   // Return the vector xyz rotated according to the rotationAngles angles
1500   //
1501
1502   Int_t ii=0;
1503   /*
1504   TRotMatrix *matrix = new TRotMatrix("matrix","matrix", angles[0], angles[1],
1505                                       angles[2], angles[3],
1506                                       angles[4], angles[5]);
1507   */
1508
1509   for (ii=0; ii<6; ii++) rotationAngles[ii]*=kDegrad;
1510
1511   Float_t xyzDummy[3] = {0., 0., 0.};
1512
1513   for (ii=0; ii<3; ii++) {
1514     xyzDummy[ii] =
1515       xyz[0]*TMath::Sin(rotationAngles[2*ii])*TMath::Cos(rotationAngles[2*ii+1]) +
1516       xyz[1]*TMath::Sin(rotationAngles[2*ii])*TMath::Sin(rotationAngles[2*ii+1]) +
1517       xyz[2]*TMath::Cos(rotationAngles[2*ii]);
1518   }
1519
1520   for (ii=0; ii<3; ii++) xyz[ii]=xyzDummy[ii];
1521
1522   return;
1523
1524 }
1525 //_____________________________________________________________________________
1526 void AliTOFGeometryV5::InverseRotation(Float_t *xyz, Double_t rotationAngles[6]) const
1527 {
1528   //
1529   //
1530   //
1531
1532   Int_t ii=0;
1533
1534   for (ii=0; ii<6; ii++) rotationAngles[ii]*=kDegrad;
1535
1536   Float_t xyzDummy[3] = {0., 0., 0.};
1537
1538   xyzDummy[0] =
1539     xyz[0]*TMath::Sin(rotationAngles[0])*TMath::Cos(rotationAngles[1]) +
1540     xyz[1]*TMath::Sin(rotationAngles[2])*TMath::Cos(rotationAngles[3]) +
1541     xyz[2]*TMath::Sin(rotationAngles[4])*TMath::Cos(rotationAngles[5]);
1542   
1543   xyzDummy[1] =
1544     xyz[0]*TMath::Sin(rotationAngles[0])*TMath::Sin(rotationAngles[1]) +
1545     xyz[1]*TMath::Sin(rotationAngles[2])*TMath::Sin(rotationAngles[3]) +
1546     xyz[2]*TMath::Sin(rotationAngles[4])*TMath::Sin(rotationAngles[5]);
1547   
1548   xyzDummy[2] =
1549     xyz[0]*TMath::Cos(rotationAngles[0]) +
1550     xyz[1]*TMath::Cos(rotationAngles[2]) +
1551     xyz[2]*TMath::Cos(rotationAngles[4]);
1552   
1553   for (ii=0; ii<3; ii++) xyz[ii]=xyzDummy[ii];
1554
1555   return;
1556
1557 }
1558 //_____________________________________________________________________________
1559 void AliTOFGeometryV5::GetVolumePath(Int_t *ind, Char_t *path ) {
1560   //--------------------------------------------------------------------
1561   // This function returns the colume path of a given pad 
1562   //--------------------------------------------------------------------
1563   Int_t sector = ind[0];
1564   Char_t  string1[100];
1565   Char_t  string2[100];
1566   Char_t  string3[100];
1567   
1568   Int_t icopy=-1;
1569
1570   if(sector<13){
1571     icopy=sector+5;}  
1572   else{ icopy=sector-13;}
1573   sprintf(string1,"/ALIC_1/B077_1/BSEGMO%i_1/BTOF%i_1/FTOA_0/FLTA_0",icopy,icopy);
1574   
1575   Int_t iplate=ind[1];
1576   Int_t istrip=ind[2];
1577   if( iplate==0) icopy=istrip; 
1578   if( iplate==1) icopy=istrip+NStripC(); 
1579   if( iplate==2) icopy=istrip+NStripC()+NStripB(); 
1580   if( iplate==3) icopy=istrip+NStripC()+NStripB()+NStripA(); 
1581   if( iplate==4) icopy=istrip+NStripC()+2*NStripB()+NStripA(); 
1582   icopy++;
1583   sprintf(string2,"FSTR_%i",icopy);
1584   if(fHoles && (sector==11 || sector==12)){
1585     if(iplate<2)  sprintf(string2,"FTOB_0/FLTB_0/FSTR_%i",icopy);
1586     if(iplate>2)  sprintf(string2,"FTOC_0/FLTC_0/FSTR_%i",icopy);
1587   }
1588  
1589
1590   Int_t padz = ind[3]+1; 
1591   Int_t padx = ind[4]+1;
1592   sprintf(string3,"FPCB_1/FSEN_1/FSEZ_%i/FPAD_%i",padz,padx);
1593   sprintf(path,"%s/%s/%s",string1,string2,string3); 
1594
1595 }
1596 //_____________________________________________________________________________
1597 void AliTOFGeometryV5::GetPos(Int_t *det, Float_t *pos) 
1598 {
1599 //
1600 // Returns space point coor (x,y,z) (cm)  for Detector 
1601 // Indices  (iSect,iPlate,iStrip,iPadX,iPadZ) 
1602 //
1603   Char_t path[100];
1604   GetVolumePath(det,path );
1605   if (!gGeoManager) {
1606     printf("ERROR: no TGeo\n");
1607   }
1608   gGeoManager->cd(path);
1609   TGeoHMatrix global;
1610   global = *gGeoManager->GetCurrentMatrix();
1611   const Double_t *tr = global.GetTranslation();
1612
1613   pos[0]=tr[0];  
1614   pos[1]=tr[1];  
1615   pos[2]=tr[2];
1616 }
1617 //_____________________________________________________________________________