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