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