updates to comply with AliTOFGeometryV5 becoming AliTOFGeometry
[u/mrichter/AliRoot.git] / TOF / AliTOFGeometryV4.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
7  * Permission to use, copy, modify and distribute this software and its   *
8  * documentation strictly for non-commercial purposes is hereby granted   *
9  * without fee, provided that the above copyright notice appears in all   *
10  * copies and that both the copyright notice and this permission notice   *
11  * appear in the supporting documentation. The authors make no claims     *
12  * about the suitability of this software for any purpose. It is          *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15
16 /*
17 $Log$
18 Revision 1.5  2006/04/20 22:30:50  hristov
19 Coding conventions (Annalisa)
20
21 Revision 1.4  2006/04/16 22:29:05  hristov
22 Coding conventions (Annalisa)
23
24 Revision 1.3  2006/03/12 14:38:13  arcelli
25  Changes for TOF Reconstruction using TGeo
26
27 Revision 1.2  2006/02/28 10:38:00  decaro
28 AliTOFGeometry::fAngles, AliTOFGeometry::fHeights, AliTOFGeometry::fDistances arrays: dimension definition in the right location
29
30 Revision 1.1  2005/12/15 08:55:33  decaro
31 New TOF geometry description (V5) -G. Cara Romeo and A. De Caro
32
33 Revision 0.1  2005/07/19 A. De Caro
34         Modify Global methods IsInsideThePad & DistanceToPad
35                according to the PPR TOF geometry
36         Implement Global  methods GetPadDx & GetPadDy & GetPadDz
37         Modify Global methods GetDetID & GetPlate & GetSector &
38                               GetStrip & GetPadX & GetPadZ
39                according to the PPR TOF geometry
40         Modify Global methods GetPos & GetX & GetY & GetZ
41                according to the PPR TOF geometry
42 */
43
44 ///////////////////////////////////////////////////////////////////////////////
45 //                                                                           //
46 //  TOF Geometry class (PPR version)                                         //
47 //                                                                           //
48 ///////////////////////////////////////////////////////////////////////////////
49
50 #include "TGeoManager.h"
51
52 #include "AliConst.h"
53 #include "AliLog.h"
54
55 #include "AliTOFGeometryV4.h"
56
57 extern TGeoManager *gGeoManager;
58
59 ClassImp(AliTOFGeometryV4)
60
61
62 const Float_t AliTOFGeometryV4::fgkZlenA    = 106.0;    // length (cm) of the A module
63 const Float_t AliTOFGeometryV4::fgkZlenB    = 141.0;    // length (cm) of the B module
64 const Float_t AliTOFGeometryV4::fgkZlenC    = 177.5;    // length (cm) of the C module
65 const Float_t AliTOFGeometryV4::fgkMaxhZtof = 371.5;    // Max half z-size of TOF (cm)
66
67 const Float_t AliTOFGeometryV4::fgkDeadBndX = 1.0;      // Dead Boundaries of a Strip along X direction (length) (cm)
68 const Float_t AliTOFGeometryV4::fgkDeadBndZ = 1.5;      // Dead Boundaries of a Strip along Z direction (width) (cm)
69 const Float_t AliTOFGeometryV4::fgkOverSpc = 15.3;      // Space available for sensitive layers in radial direction (cm)
70
71 const Float_t AliTOFGeometryV4::fgkDprecMin = 0.0000075;//num.prec.tolerance on Thmin 
72 const Float_t AliTOFGeometryV4::fgkDprecMax = 0.0000100;//num.prec.tolerance on Thma 
73 const Float_t AliTOFGeometryV4::fgkDprecCen = 0.0000005;//num.prec.tolerance on <Theta> 
74
75 const Float_t AliTOFGeometryV4::fgkxTOF     = 371.;     // Inner radius of the TOF for Reconstruction (cm)
76 const Float_t AliTOFGeometryV4::fgkRmin     = 370.;     // Inner radius of the TOF (cm)
77 const Float_t AliTOFGeometryV4::fgkRmax     = 399.;     // Outer radius of the TOF (cm)
78
79 //_____________________________________________________________________________
80 AliTOFGeometryV4::AliTOFGeometryV4()
81   :AliTOFGeometry()
82 {
83   //
84   // AliTOFGeometryV4 default constructor
85   //
86
87   AliTOFGeometry::fNStripC   = kNStripC;         // number of strips in C type module
88
89   AliTOFGeometry::fZlenA    = fgkZlenA;          // length (cm) of the A module
90   AliTOFGeometry::fZlenB    = fgkZlenB;          // length (cm) of the B module
91   AliTOFGeometry::fZlenC    = fgkZlenC;          // length (cm) of the C module
92   AliTOFGeometry::fMaxhZtof = fgkMaxhZtof;       // Max half z-size of TOF (cm)
93
94   AliTOFGeometry::fxTOF   = fgkxTOF;           // Inner radius of the TOF for Reconstruction (cm)
95   AliTOFGeometry::fRmin   = fgkRmin;           // Inner radius of the TOF (cm)
96   AliTOFGeometry::fRmax   = fgkRmax;           // Outer radius of the TOF (cm)
97
98   Init();
99
100 }
101
102 //_____________________________________________________________________________
103 AliTOFGeometryV4::~AliTOFGeometryV4()
104 {
105   //
106   // AliTOFGeometryV4 destructor
107   //
108
109 }
110 //_____________________________________________________________________________
111 void AliTOFGeometryV4::ImportGeometry(){
112   TGeoManager::Import("geometry.root");
113 }
114 //_____________________________________________________________________________
115 void AliTOFGeometryV4::Init()
116 {
117   //
118   // Initialize strip Tilt Angles and Heights
119   //
120   // Strips Tilt Angles
121  
122   fPhiSec   = 360./kNSectors;
123
124   Float_t const kangles[kNPlates][kMaxNstrip] ={
125
126  {44.494, 43.725, 42.946, 42.156, 41.357, 40.548, 39.729, 38.899, 
127   38.060, 37.211, 36.353, 35.484, 34.606, 33.719, 32.822, 31.916, 
128   31.001, 30.077, 29.144, 28.202 },
129
130  {26.884, 25.922, 24.952, 23.975, 22.989, 22.320, 21.016, 20.309,
131   19.015, 18.270, 16.989, 16.205, 14.941, 14.117, 12.871, 12.008,
132   10.784, 9.8807, 8.681, 0.0 },
133
134  { 7.5835, 6.4124, 5.4058, 4.2809, 3.2448,  2.1424, 1.078, -0., -1.078, 
135   -2.1424, -3.2448, -4.2809, -5.4058, -6.4124, -7.5835, 0.0, 0.0, 0.0,
136   0.0, 0.0 },
137   
138  {-8.681, -9.8807, -10.784, -12.008, -12.871, -14.117, -14.941, -16.205,
139   -16.989, -18.27, -19.015, -20.309, -21.016, -22.32, -22.989,
140    -23.975, -24.952, -25.922, -26.884, 0. },
141   
142  {-28.202, -29.144, -30.077, -31.001, -31.916, -32.822, -33.719, -34.606,
143   -35.484, -36.353, -37.211, -38.06, -38.899, -39.729, -40.548,
144    -41.357, -42.156, -42.946, -43.725, -44.494 }};
145
146
147   //Strips Heights
148
149    Float_t const kheights[kNPlates][kMaxNstrip]= {
150
151   {-5.5, -5.5, -5.5, -5.5, -5.5, -5.5, -5.5, -5.5, -5.5, -5.5,
152    -5.5, -5.5, -5.5, -5.5, -5.5, -5.5, -5.5, -5.5, -5.5, -5.5 },
153   
154   {-6.3, -7.1, -7.9, -8.7, -9.5, -3, -9.5,   -3, -9.5,   -3, 
155    -9.5, -3.0, -9.5, -3.0, -9.5, -3, -9.5,   -3,   -9 , 0.},
156   
157   {  -3,   -9, -4.5,   -9, -4.5,     -9, -4.5,   -9, -4.5,   -9, 
158      -4.5,   -9, -4.5,   -9,   -3,   0.0, 0.0, 0.0, 0.0, 0.0 },
159   
160   {  -9,   -3, -9.5,   -3, -9.5, -3, -9.5,   -3, -9.5,   -3, -9.5,
161      -3, -9.5,   -3, -9.5,  -8.7, -7.9, -7.1, -6.3, 0. },
162   
163   {-5.5, -5.5, -5.5, -5.5, -5.5, -5.5, -5.5, -5.5, -5.5, -5.5,
164    -5.5, -5.5, -5.5, -5.5, -5.5, -5.5, -5.5, -5.5, -5.5, -5.5 }};
165
166    // Deposit in fAngles, fHeights
167
168    for (Int_t iplate = 0; iplate < kNPlates; iplate++) {
169      for (Int_t istrip = 0; istrip < kMaxNstrip; istrip++) {
170        AliTOFGeometry::fAngles[iplate][istrip]   = kangles[iplate][istrip];
171        AliTOFGeometry::fHeights[iplate][istrip]  = kheights[iplate][istrip];
172      }
173    }
174
175 }
176
177 //_____________________________________________________________________________
178 Float_t AliTOFGeometryV4::DistanceToPadPar(Int_t *det, Float_t *pos, Float_t *dist3d) const
179 {
180 //
181 // Returns distance of  space point with coor pos (x,y,z) (cm) wrt 
182 // pad with Detector Indices idet (iSect,iPlate,iStrip,iPadX,iPadZ) 
183 //
184     
185   //Transform pos into Sector Frame
186
187   Float_t x = pos[0];
188   Float_t y = pos[1];
189   Float_t z = pos[2];
190
191   Float_t radius = TMath::Sqrt(x*x+y*y);
192   Float_t phi=TMath::ATan2(y,x);        
193   if(phi<0) phi=2.*TMath::Pi()+phi;
194   //  Get the local angle in the sector philoc
195   Float_t angle   = phi*kRaddeg-( Int_t (kRaddeg*phi/fPhiSec) + 0.5)*fPhiSec;
196   Float_t xs = radius*TMath::Cos(angle/kRaddeg);
197   Float_t ys = radius*TMath::Sin(angle/kRaddeg);
198   Float_t zs = z;
199
200   // Do the same for the selected pad
201
202   Float_t g[3];
203   GetPosPar(det,g);
204
205   Float_t padRadius = TMath::Sqrt(g[0]*g[0]+g[1]*g[1]);
206   Float_t padPhi=TMath::ATan2(g[1],g[0]);       
207   if(padPhi<0) padPhi=2.*TMath::Pi()+padPhi;
208   //  Get the local angle in the sector philoc
209   Float_t padAngle   = padPhi*kRaddeg-( Int_t (padPhi*kRaddeg/fPhiSec)+ 0.5) * fPhiSec; 
210   Float_t padxs = padRadius*TMath::Cos(padAngle/kRaddeg);
211   Float_t padys = padRadius*TMath::Sin(padAngle/kRaddeg);
212   Float_t padzs = g[2];
213   
214   //Now move to local pad coordinate frame. Translate:
215   
216   Float_t xt = xs-padxs;
217   Float_t yt = ys-padys;
218   Float_t zt = zs-padzs;
219   //Now Rotate:
220   
221   Float_t alpha = GetAngles(det[1],det[2]);
222   Float_t xr =  xt*TMath::Cos(alpha/kRaddeg)+zt*TMath::Sin(alpha/kRaddeg);
223   Float_t yr =  yt;
224   Float_t zr = -xt*TMath::Sin(alpha/kRaddeg)+zt*TMath::Cos(alpha/kRaddeg);
225
226   Float_t dist = TMath::Sqrt(xr*xr+yr*yr+zr*zr);
227   if (dist3d){
228     dist3d[0] = xr;
229     dist3d[1] = yr;
230     dist3d[2] = zr;
231   }
232
233   return dist;
234
235 }
236
237 //_____________________________________________________________________________
238 Bool_t AliTOFGeometryV4::IsInsideThePadPar(Int_t *det, Float_t *pos) const
239 {
240 //
241 // Returns true if space point with coor pos (x,y,z) (cm) falls 
242 // inside pad with Detector Indices idet (iSect,iPlate,iStrip,iPadX,iPadZ) 
243 //
244
245   Bool_t isInside=false; 
246
247   //Transform pos into Sector Frame
248
249   Float_t x = pos[0];
250   Float_t y = pos[1];
251   Float_t z = pos[2];
252
253   Float_t radius = TMath::Sqrt(x*x+y*y);
254   Float_t phi=TMath::ATan2(y,x);        
255   if(phi<0) phi=2.*TMath::Pi()+phi;
256   //  Get the local angle in the sector philoc
257   Float_t angle   = phi*kRaddeg-( Int_t (kRaddeg*phi/fPhiSec) + 0.5) *fPhiSec;
258   Float_t xs = radius*TMath::Cos(angle/kRaddeg);
259   Float_t ys = radius*TMath::Sin(angle/kRaddeg);
260   Float_t zs = z;
261
262   // Do the same for the selected pad
263
264   Float_t g[3];
265   GetPosPar(det,g);
266
267   Float_t padRadius = TMath::Sqrt(g[0]*g[0]+g[1]*g[1]);
268   Float_t padPhi=TMath::ATan2(g[1],g[0]);       
269   if(padPhi<0) padPhi=2.*TMath::Pi()+padPhi;
270   //  Get the local angle in the sector philoc
271   Float_t padAngle   = padPhi*kRaddeg-( Int_t (padPhi*kRaddeg/fPhiSec)+ 0.5) * fPhiSec; 
272   Float_t padxs = padRadius*TMath::Cos(padAngle/kRaddeg);
273   Float_t padys = padRadius*TMath::Sin(padAngle/kRaddeg);
274   Float_t padzs = g[2];
275
276   //Now move to local pad coordinate frame. Translate:
277
278   Float_t xt = xs-padxs;
279   Float_t yt = ys-padys;
280   Float_t zt = zs-padzs;
281
282   //Now Rotate:
283
284   Float_t alpha = GetAngles(det[1],det[2]);
285   Float_t xr =  xt*TMath::Cos(alpha/kRaddeg)+zt*TMath::Sin(alpha/kRaddeg);
286   Float_t yr =  yt;
287   Float_t zr = -xt*TMath::Sin(alpha/kRaddeg)+zt*TMath::Cos(alpha/kRaddeg);
288
289   if(TMath::Abs(xr)<=0.75 && TMath::Abs(yr)<= (fgkXPad*0.5) && TMath::Abs(zr)<= (fgkZPad*0.5))
290     isInside=true; 
291   return isInside;
292
293 }
294
295
296 //_____________________________________________________________________________
297 Float_t AliTOFGeometryV4::DistanceToPad(Int_t *det, TGeoHMatrix mat, Float_t *pos, Float_t *dist3d) const
298 {
299 //
300 // Returns distance of  space point with coor pos (x,y,z) (cm) wrt 
301 // pad with Detector Indices idet (iSect,iPlate,iStrip,iPadX,iPadZ) 
302 //
303   if (!gGeoManager) {
304     printf("ERROR: no TGeo\n");
305     return 0.;
306   }
307   Double_t vecg[3];
308   vecg[0]=pos[0];
309   vecg[1]=pos[1];
310   vecg[2]=pos[2];
311   Double_t veclr[3]={-1.,-1.,-1.};
312   Double_t vecl[3]={-1.,-1.,-1.};
313   mat.MasterToLocal(vecg,veclr);  
314   vecl[0]=veclr[1];
315   vecl[1]=veclr[0];
316   vecl[2]=-veclr[2];
317   //Take into account reflections
318   if(det[1]>2){
319     vecl[1]=-veclr[0];
320     vecl[2]= veclr[2];
321   }     
322
323   Float_t dist = TMath::Sqrt(vecl[0]*vecl[0]+vecl[1]*vecl[1]+vecl[2]*vecl[2]);
324
325
326   if (dist3d){
327     dist3d[0] = vecl[0];
328     dist3d[1] = vecl[1];
329     dist3d[2] = vecl[2];
330   }
331
332   return dist;
333
334 }
335
336
337 //_____________________________________________________________________________
338 Bool_t AliTOFGeometryV4::IsInsideThePad( Int_t *det, TGeoHMatrix mat, Float_t *pos) const
339 {
340 //
341 // Returns true if space point with coor pos (x,y,z) (cm) falls 
342 // inside pad with Detector Indices idet (iSect,iPlate,iStrip,iPadX,iPadZ) 
343 //
344
345   const Float_t khsensmy = 0.5;      // heigth of Sensitive Layer
346
347   Double_t vecg[3];
348   vecg[0]=pos[0];
349   vecg[1]=pos[1];
350   vecg[2]=pos[2];
351   Double_t veclr[3]={-1.,-1.,-1.};
352   Double_t vecl[3]={-1.,-1.,-1.};
353   mat.MasterToLocal(vecg,veclr);  
354   vecl[0]=veclr[1];
355   vecl[1]=veclr[0];
356   vecl[2]=-veclr[2];
357   //Take into account reflections
358   if(det[1]>2){
359     vecl[1]=-veclr[0];
360     vecl[2]= veclr[2];
361   }     
362
363   Float_t xr = vecl[0];
364   Float_t yr = vecl[1];
365   Float_t zr = vecl[2];
366
367   Bool_t isInside=false; 
368   if(TMath::Abs(xr)<= khsensmy*0.5 && TMath::Abs(yr)<= (fgkXPad*0.5) && TMath::Abs(zr)<= (fgkZPad*0.5))
369     isInside=true; 
370   return isInside;
371
372 }
373 //_____________________________________________________________________________
374 Float_t AliTOFGeometryV4::GetX(Int_t *det) const
375 {
376   //
377   // Returns X coordinate (cm)
378   //
379
380   Int_t isector = det[0];
381   Int_t iplate  = det[1];
382   Int_t istrip  = det[2];
383   Int_t ipadz   = det[3];
384   Int_t ipadx   = det[4];
385
386   // Find out distance d on the plane wrt median phi:
387   Float_t d = (ipadx+0.5)*fgkXPad-(kNpadX*fgkXPad)*0.5;
388
389   // The radius r in xy plane:
390   Float_t r = (fgkRmin+fgkRmax)/2.+fHeights[iplate][istrip]+
391     (ipadz-0.5)*fgkZPad*TMath::Sin(fAngles[iplate][istrip]/kRaddeg)-0.25;
392
393   // local azimuthal angle in the sector philoc
394   Float_t philoc   = TMath:: ATan(d/r);
395
396   // azimuthal angle in the global frame  phi
397   Float_t phi      = philoc*kRaddeg+(isector+0.5 )*fPhiSec;                    
398
399   Float_t xCoor    = r/TMath::Cos(philoc)*TMath::Cos(phi/kRaddeg);
400
401   return xCoor;
402
403 }
404 //_____________________________________________________________________________
405 Float_t AliTOFGeometryV4::GetY(Int_t *det) const
406 {
407   //
408   // Returns Y coordinate (cm)
409   //
410
411   Int_t isector = det[0];
412   Int_t iplate  = det[1];
413   Int_t istrip  = det[2];
414   Int_t ipadz   = det[3];
415   Int_t ipadx   = det[4];
416
417   // Find out distance d on the plane wrt median phi:
418   Float_t d = (ipadx+0.5)*fgkXPad-(kNpadX*fgkXPad)*0.5;
419
420   // The radius r in xy plane:
421   Float_t r = (fgkRmin+fgkRmax)/2.+fHeights[iplate][istrip]+
422     (ipadz-0.5)*fgkZPad*TMath::Sin(fAngles[iplate][istrip]/kRaddeg)-0.25;
423
424   // local azimuthal angle in the sector philoc
425   Float_t philoc   = TMath:: ATan(d/r);
426
427   // azimuthal angle in the global frame  phi
428   Float_t phi      = philoc*kRaddeg+(isector+0.5 )*fPhiSec;                    
429
430   Float_t yCoor    = r/TMath::Cos(philoc)*TMath::Sin(phi/kRaddeg);
431
432   return yCoor;
433
434 }
435
436 //_____________________________________________________________________________
437 Float_t AliTOFGeometryV4::GetZ(Int_t *det) const
438 {
439   //
440   // Returns Z coordinate (cm)
441   //
442
443   Int_t iplate  = det[1];
444   Int_t istrip  = det[2];
445   Int_t ipadz   = det[3];
446
447   // The radius r in xy plane:
448   Float_t r = (fgkRmin+fgkRmax)/2.+fHeights[iplate][istrip];
449
450   Float_t zCoor = r*TMath::Tan(0.5*TMath::Pi()-GetStripTheta(iplate,istrip))-
451          (ipadz-0.5)*fgkZPad*TMath::Cos(fAngles[iplate][istrip]/kRaddeg);
452   return zCoor;
453
454 }
455
456 //_____________________________________________________________________________
457 Int_t AliTOFGeometryV4::GetSector(Float_t *pos) const
458 {
459   //
460   // Returns the Sector index 
461   //
462
463   Int_t   iSect = -1; 
464
465   Float_t x = pos[0];
466   Float_t y = pos[1];
467
468   Float_t phi     =  TMath::ATan2(y,x); 
469   if(phi<0.) phi=2.*TMath::Pi()+phi;
470   iSect  = (Int_t) (phi*kRaddeg/fPhiSec);
471
472   return iSect;
473
474 }
475
476 //_____________________________________________________________________________
477 Int_t AliTOFGeometryV4::GetPadX(Float_t *pos) const
478 {
479   //
480   // Returns the Pad index along X 
481   //
482
483   Int_t iPadX  = -1;
484
485   Float_t x = pos[0];
486   Float_t y = pos[1];
487   Float_t z = pos[2];
488
489   Int_t isector = GetSector(pos);
490   if(isector == -1){  
491     AliError("Detector Index could not be determined");
492     return iPadX;}
493   Int_t iplate =  GetPlate(pos);
494   if(iplate == -1){  
495     AliError("Detector Index could not be determined");
496     return iPadX;} 
497   Int_t istrip =  GetStrip(pos);
498   if(istrip == -1){  
499     AliError("Detector Index could not be determined");
500     return iPadX;}
501
502
503   Float_t rho=TMath::Sqrt(x*x+y*y);
504   Float_t phi =  TMath::ATan2(y,x);     
505   if(phi<0.) phi=2.*TMath::Pi()+phi;
506  
507   // Get the local angle in the sector philoc
508   Float_t philoc   = phi*kRaddeg-(isector+0.5)*fPhiSec;
509   philoc*=TMath::Pi()/180.;
510   // theta projected on the median of the sector
511   Float_t theta = TMath::ATan2(rho*TMath::Cos(philoc),z);
512   // The radius r in xy plane:
513   Float_t r   = (fgkRmin+fgkRmax)/2.+fHeights[iplate][istrip]+
514                (theta-GetStripTheta(iplate, istrip))/
515     (GetMaxStripTheta(iplate, istrip)-GetMinStripTheta(iplate, istrip))
516    * 2.*fgkZPad*TMath::Sin(fAngles[iplate][istrip]/kRaddeg)-0.25;
517
518   // Find out distance projected onto the strip plane 
519   Float_t d = (r*TMath::Tan(philoc)+(kNpadX*fgkXPad)*0.5);
520
521   iPadX  =  (Int_t) ( d/fgkXPad);  
522   return iPadX;
523
524 }
525 //_____________________________________________________________________________
526 Int_t AliTOFGeometryV4::GetPlate(Float_t *pos) const
527 {
528   //
529   // Returns the Plate index 
530   //
531   Int_t iPlate=-1;
532
533   Int_t isector = GetSector(pos);
534   if(isector == -1){  
535     AliError("Detector Index could not be determined");
536     return iPlate;}
537  
538   Float_t x = pos[0];
539   Float_t y = pos[1];
540   Float_t z = pos[2];
541
542   Float_t rho=TMath::Sqrt(x*x+y*y);
543   Float_t phi=TMath::ATan2(y,x);        
544   if(phi<0) phi=2.*TMath::Pi()+phi;
545   // Get the local angle in the sector philoc
546   Float_t philoc   = phi*kRaddeg-(isector+0.5)*fPhiSec;
547   philoc*=TMath::Pi()/180.;
548   // theta projected on the median of the sector
549   Float_t theta=TMath::ATan2(rho*TMath::Cos(philoc),z);
550
551   for (Int_t i=0; i<kNPlates; i++){
552     if ( GetMaxPlateTheta(i) >= theta && 
553          GetMinPlateTheta(i) <= theta)iPlate=i;
554   }
555
556   return iPlate;
557
558 }
559
560 //_____________________________________________________________________________
561 Int_t AliTOFGeometryV4::GetStrip(Float_t *pos) const
562 {
563   //
564   // Returns the Strip index 
565   //
566
567   Int_t iStrip=-1;
568
569
570   Int_t isector = GetSector(pos);
571   if(isector == -1){  
572     AliError("Detector Index could not be determined");
573     return iStrip;}
574   Int_t iplate =  GetPlate(pos);
575   if(iplate == -1){  
576     AliError("Detector Index could not be determined");
577     return iStrip;} 
578
579
580   Float_t x = pos[0];
581   Float_t y = pos[1];
582   Float_t z = pos[2];
583
584   Int_t nstrips=0;
585   if(iplate==0 || iplate == 4)nstrips=kNStripC;
586   if(iplate==1 || iplate == 3)nstrips=kNStripB;
587   if(iplate==2)               nstrips=kNStripA;
588
589   Float_t rho=TMath::Sqrt(x*x+y*y);
590   Float_t phi=TMath::ATan2(y,x);        
591   if(phi<0) phi=2.*TMath::Pi()+phi;
592   // Get the local angle in the sector philoc
593   Float_t philoc   = phi*kRaddeg-(isector+0.5)*fPhiSec;
594   philoc*=TMath::Pi()/180.;
595   // theta projected on the median of the sector
596   Float_t theta=TMath::ATan2(rho*TMath::Cos(philoc),z);
597
598   for (Int_t istrip=0; istrip<nstrips; istrip++){
599
600     if( 
601        GetMaxStripTheta(iplate,istrip) >= theta 
602        &&  
603        GetMinStripTheta(iplate,istrip) <= theta ) iStrip = istrip;
604    
605   }
606
607   return iStrip;
608
609 }
610 //_____________________________________________________________________________
611 Int_t AliTOFGeometryV4::GetPadZ(Float_t *pos) const
612 {
613   //
614   // Returns the Pad index along Z 
615   //
616   Int_t iPadZ = -1;
617
618   Int_t isector = GetSector(pos);
619   if(isector == -1){  
620     AliError("Detector Index could not be determined");
621     return iPadZ;}
622   Int_t iplate =  GetPlate(pos);
623   if(iplate == -1){  
624     AliError("Detector Index could not be determined");
625     return iPadZ;} 
626   Int_t istrip =  GetStrip(pos);
627   if(istrip == -1){  
628     AliError("Detector Index could not be determined");
629     return iPadZ;}
630
631
632   Float_t x = pos[0];
633   Float_t y = pos[1];
634   Float_t z = pos[2];
635
636   Float_t rho=TMath::Sqrt(x*x+y*y);
637   Float_t phi=TMath::ATan2(y,x);        
638   if(phi<0) phi=2.*TMath::Pi()+phi;
639   Float_t philoc   = phi*kRaddeg-(isector+0.5)*fPhiSec;
640   philoc*=TMath::Pi()/180.;
641   Float_t theta=TMath::ATan2(rho*TMath::Cos(philoc),z);
642
643   if (theta >= GetStripTheta(iplate, istrip))iPadZ=1;
644   else iPadZ=0;
645
646   return iPadZ;
647
648 }
649 //_____________________________________________________________________________
650 Float_t AliTOFGeometryV4::GetMinPlateTheta(Int_t iPlate) const
651 {
652   //
653   // Returns the minimum theta angle of a given plate iPlate (rad)
654   //
655   
656
657   Int_t index=0;
658
659   Float_t delta =0.;
660   if(iPlate==0)delta = -1. ;
661   if(iPlate==1)delta = -0.5;
662   if(iPlate==3)delta = +0.5;
663   if(iPlate==4)delta = +1. ;
664
665   Float_t z=(fgkRmin+2.)*TMath::Tan(fAngles[iPlate][index]/kRaddeg)+delta;
666   Float_t r=(fgkRmin+fgkRmax)/2.+fHeights[iPlate][index];
667   z =z+fgkZPad*TMath::Cos(fAngles[iPlate][index]/kRaddeg);
668   r =r-fgkZPad*TMath::Sin(fAngles[iPlate][index]/kRaddeg);
669
670   Float_t thmin = 0.5*TMath::Pi()-TMath::ATan(z/r)-fgkDprecMin;
671   return thmin;
672
673 }
674 //_____________________________________________________________________________
675 Float_t AliTOFGeometryV4::GetMaxPlateTheta(Int_t iPlate) const
676 {
677   //
678   // Returns the maximum theta angle of a given plate iPlate (rad)
679   
680   Int_t index=0;
681   if(iPlate==0 ||iPlate == 4)index=kNStripC-1;
682   if(iPlate==1 ||iPlate == 3)index=kNStripB-1;
683   if(iPlate==2)              index=kNStripA-1;
684
685   Float_t delta =0.;
686   if(iPlate==0)delta = -1. ;
687   if(iPlate==1)delta = -0.5;
688   if(iPlate==3)delta = +0.5;
689   if(iPlate==4)delta = +1. ;
690
691   Float_t z=(fgkRmin+2.)*TMath::Tan(fAngles[iPlate][index]/kRaddeg)+delta;
692   Float_t r=(fgkRmin+fgkRmax)/2.+fHeights[iPlate][index];
693   z =z-fgkZPad*TMath::Cos(fAngles[iPlate][index]/kRaddeg);
694   r= r+fgkZPad*TMath::Sin(fAngles[iPlate][index]/kRaddeg);
695
696   Float_t thmax    = 0.5*TMath::Pi()-TMath::ATan(z/r)+fgkDprecMax;
697
698   return thmax;
699
700 }
701 //_____________________________________________________________________________
702 Float_t  AliTOFGeometryV4::GetMaxStripTheta(Int_t iPlate, Int_t iStrip) const
703 {
704   //
705   // Returns the maximum theta angle of a given strip iStrip (rad)
706   //
707
708
709   Float_t delta =0.;
710   if(iPlate==0)delta = -1. ;
711   if(iPlate==1)delta = -0.5;
712   if(iPlate==3)delta = +0.5;
713   if(iPlate==4)delta = +1. ;
714
715   Float_t r =(fgkRmin+fgkRmax)/2.+fHeights[iPlate][iStrip];
716   Float_t z =(fgkRmin+2.)*TMath::Tan(fAngles[iPlate][iStrip]/kRaddeg)+delta;
717   z = z-fgkZPad*TMath::Cos(fAngles[iPlate][iStrip]/kRaddeg);
718   r = r+fgkZPad*TMath::Sin(fAngles[iPlate][iStrip]/kRaddeg);
719   Float_t thmax =0.5*TMath::Pi()-TMath::ATan(z/r)+fgkDprecMax;
720   return thmax;
721
722 }
723 //_____________________________________________________________________________
724 Float_t  AliTOFGeometryV4::GetMinStripTheta(Int_t iPlate, Int_t iStrip) const
725 {
726   //
727   // Returns the minimum theta angle of a given Strip iStrip (rad)
728   //
729   
730
731   Float_t delta =0.;
732   if(iPlate==0)delta = -1. ;
733   if(iPlate==1)delta = -0.5;
734   if(iPlate==3)delta = +0.5;
735   if(iPlate==4)delta = +1. ;
736
737
738   Float_t r =(fgkRmin+fgkRmax)/2.+fHeights[iPlate][iStrip];
739   Float_t z =(fgkRmin+2.)*TMath::Tan(fAngles[iPlate][iStrip]/kRaddeg)+delta;
740   z =z+fgkZPad*TMath::Cos(fAngles[iPlate][iStrip]/kRaddeg);
741   r =r-fgkZPad*TMath::Sin(fAngles[iPlate][iStrip]/kRaddeg);
742   Float_t thmin =0.5*TMath::Pi()-TMath::ATan(z/r)-fgkDprecMin;
743
744   return thmin;
745
746 }
747 //_____________________________________________________________________________
748 Float_t  AliTOFGeometryV4::GetStripTheta(Int_t iPlate, Int_t iStrip) const
749 {
750   //
751   // returns the median theta angle of a given strip iStrip (rad)
752   //
753   
754
755   Float_t delta =0.;
756   if(iPlate==0)delta = -1. ;
757   if(iPlate==1)delta = -0.5;
758   if(iPlate==3)delta = +0.5;
759   if(iPlate==4)delta = +1. ;
760
761   Float_t r =(fgkRmin+fgkRmax)/2.+fHeights[iPlate][iStrip];
762   Float_t z =(fgkRmin+2.)*TMath::Tan(fAngles[iPlate][iStrip]/kRaddeg)+delta;
763   Float_t theta =0.5*TMath::Pi()-TMath::ATan(z/r);
764   if(iPlate != 2){
765   if(theta > 0.5*TMath::Pi() )theta+=fgkDprecCen;
766   if(theta < 0.5*TMath::Pi() )theta-=fgkDprecCen;
767   }
768   return theta;
769
770 }
771 //_____________________________________________________________________________
772 void AliTOFGeometryV4::GetVolumePath(Int_t *ind, Char_t *path ) {
773   //--------------------------------------------------------------------
774   // This function returns the colume path of a given pad 
775   //--------------------------------------------------------------------
776   Int_t sector = ind[0];
777   Char_t  string1[100];
778   Char_t  string2[100];
779   Char_t  string3[100];
780   Char_t  string4[100];
781   Int_t nstrB = NStripB();
782   Int_t nstrC = NStripC();
783   
784   Int_t icopy=-1;
785   
786   if(sector<3){
787     icopy=sector+1;
788     sprintf(string1,"/ALIC_1/B077_1/B075_%i/BTO3_1",icopy);
789   }
790   else if(sector<11){
791     //  icopy=sector-2;
792     icopy=sector+3;
793     sprintf(string1,"/ALIC_1/B077_1/B071_%i/BTO1_1",icopy);
794   }
795   else if(sector==11 || sector==12){
796     icopy=sector-10;
797     sprintf(string1,"/ALIC_1/B077_1/B074_%i/BTO2_1",icopy);
798   }
799   else {
800     //  icopy=sector-4;
801     icopy=sector-12;
802     sprintf(string1,"/ALIC_1/B077_1/B071_%i/BTO1_1",icopy);
803   }
804   
805   Int_t modnum=ind[1];
806   Int_t istrip=ind[2];
807   
808   if( modnum ==0){
809     sprintf(string2,"FTOC_1/FLTC_0");
810     icopy= nstrC - istrip;
811     sprintf(string3,"FSTR_%i",icopy);
812   }    
813   else if( modnum ==1){
814     sprintf(string2,"FTOB_1/FLTB_0");
815     icopy= nstrB - istrip;
816       sprintf(string3,"FSTR_%i",icopy);
817   }
818   else if( modnum ==2){
819     sprintf(string2,"FTOA_0/FLTA_0");
820     icopy= istrip+1;
821     sprintf(string3,"FSTR_%i",icopy);
822   }
823   else if( modnum ==3){
824     sprintf(string2,"FTOB_2/FLTB_0");
825     icopy= istrip+1;
826     sprintf(string3,"FSTR_%i",icopy);
827   }
828   else if( modnum ==4){
829     sprintf(string2,"FTOC_2/FLTC_0");
830     icopy= istrip+1;
831     sprintf(string3,"FSTR_%i",icopy);
832   }
833
834
835   Int_t padz = ind[3]+1; 
836   Int_t padx = ind[4]+1;
837   if(modnum==3 || modnum==4){
838     padz = NpadZ() -ind[3];
839     padx = NpadX() -ind[4];
840   }
841   sprintf(string4,"FSEN_0/FSEZ_%i/FSEX_%i",padz,padx);
842   sprintf(path,"%s/%s/%s/%s",string1,string2,string3,string4); 
843
844 }
845
846 //_____________________________________________________________________________
847 void AliTOFGeometryV4::GetVolumePath(Int_t sector, Char_t *path ) {
848   //--------------------------------------------------------------------
849   // This function returns the colume path of a given sector 
850   //--------------------------------------------------------------------
851   Char_t string[100];
852   
853   Int_t icopy=-1;
854   
855   if(sector<3){
856     icopy=sector+1;
857     sprintf(string,"/ALIC_1/B077_1/B075_%i/BTO3_1",icopy);
858   }
859   else if(sector<11){
860     //  icopy=sector-2;
861     icopy=sector+3;
862     sprintf(string,"/ALIC_1/B077_1/B071_%i/BTO1_1",icopy);
863   }
864   else if(sector==11 || sector==12){
865     icopy=sector-10;
866     sprintf(string,"/ALIC_1/B077_1/B074_%i/BTO2_1",icopy);
867   }
868   else {
869     //  icopy=sector-4;
870     icopy=sector-12;
871     sprintf(string,"/ALIC_1/B077_1/B071_%i/BTO1_1",icopy);
872   }
873   
874   sprintf(path,"%s",string); 
875
876 }
877 //_____________________________________________________________________________
878 void AliTOFGeometryV4::GetVolumePath(Int_t sector, Int_t plate, Int_t strip, Char_t *path ) {
879   //--------------------------------------------------------------------
880   // This function returns the colume path of a given strip 
881   //--------------------------------------------------------------------
882   Char_t string1[100];
883   Char_t string2[100];
884   Char_t string3[100];
885   Int_t nstrB = NStripB();
886   Int_t nstrC = NStripC();
887   
888   Int_t icopy=-1;
889   
890   if(sector<3){
891     icopy=sector+1;
892     sprintf(string1,"/ALIC_1/B077_1/B075_%i/BTO3_1",icopy);
893   }
894   else if(sector<11){
895     //  icopy=sector-2;
896     icopy=sector+3;
897     sprintf(string1,"/ALIC_1/B077_1/B071_%i/BTO1_1",icopy);
898   }
899   else if(sector==11 || sector==12){
900     icopy=sector-10;
901     sprintf(string1,"/ALIC_1/B077_1/B074_%i/BTO2_1",icopy);
902   }
903   else {
904     //  icopy=sector-4;
905     icopy=sector-12;
906     sprintf(string1,"/ALIC_1/B077_1/B071_%i/BTO1_1",icopy);
907   }
908   
909   if( plate ==0){
910     sprintf(string2,"FTOC_1/FLTC_0");
911     icopy = nstrC - strip;
912     sprintf(string3,"FSTR_%i",icopy);
913   }    
914   else if( plate ==1){
915     sprintf(string2,"FTOB_1/FLTB_0");
916     icopy = nstrB - strip;
917       sprintf(string3,"FSTR_%i",icopy);
918   }
919   else if( plate ==2){
920     sprintf(string2,"FTOA_0/FLTA_0");
921     icopy = strip+1;
922     sprintf(string3,"FSTR_%i",icopy);
923   }
924   else if( plate ==3){
925     sprintf(string2,"FTOB_2/FLTB_0");
926     icopy = strip+1;
927     sprintf(string3,"FSTR_%i",icopy);
928   }
929   else if( plate ==4){
930     sprintf(string2,"FTOC_2/FLTC_0");
931     icopy = strip+1;
932     sprintf(string3,"FSTR_%i",icopy);
933   }
934
935   sprintf(path,"%s/%s/%s/FSEN_0",string1,string2,string3); 
936
937 }
938
939 //_____________________________________________________________________________
940 void AliTOFGeometryV4::GetPos(Int_t *det, Float_t *pos) 
941 {
942 //
943 // Returns space point coor (x,y,z) (cm)  for Detector 
944 // Indices  (iSect,iPlate,iStrip,iPadX,iPadZ) 
945 //
946   Char_t path[100];
947   GetVolumePath(det,path );
948   if (!gGeoManager) {
949     printf("ERROR: no TGeo\n");
950   }
951   gGeoManager->cd(path);
952   TGeoHMatrix global;
953   global = *gGeoManager->GetCurrentMatrix();
954   const Double_t *tr = global.GetTranslation();
955
956   pos[0]=tr[0];  
957   pos[1]=tr[1];  
958   pos[2]=tr[2];
959 }
960 //_____________________________________________________________________________