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