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