]> git.uio.no Git - u/mrichter/AliRoot.git/blob - ITS/AliITStrackV2.cxx
Rename AliTRDrawStream to AliTRDrawStreamOld
[u/mrichter/AliRoot.git] / ITS / AliITStrackV2.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 /* $Id$ */
17
18 ///////////////////////////////////////////////////////////////////////////
19 //                Implementation of the ITS track class
20 //
21 //          Origin: Iouri Belikov, CERN, Jouri.Belikov@cern.ch
22 //     dEdx analysis by: Boris Batyunya, JINR, Boris.Batiounia@cern.ch
23 ///////////////////////////////////////////////////////////////////////////
24 #include <TMath.h>
25
26 #include "AliCluster.h"
27 #include "AliESDtrack.h"
28 #include "AliESDVertex.h"
29 #include "AliITSReconstructor.h"
30 #include "AliITStrackV2.h"
31 #include "AliTracker.h"
32
33 const Int_t AliITStrackV2::fgkWARN = 5;
34
35 ClassImp(AliITStrackV2)
36
37
38 //____________________________________________________________________________
39 AliITStrackV2::AliITStrackV2() : AliKalmanTrack(),
40   fCheckInvariant(kTRUE),
41   fdEdx(0),
42   fESDtrack(0)
43 {
44   for(Int_t i=0; i<2*AliITSgeomTGeo::kNLayers; i++) {fIndex[i]=-1; fModule[i]=-1;}
45   for(Int_t i=0; i<4; i++) fdEdxSample[i]=0;
46 }
47
48
49 //____________________________________________________________________________
50 AliITStrackV2::AliITStrackV2(AliESDtrack& t,Bool_t c) throw (const Char_t *) :
51   AliKalmanTrack(),
52   fCheckInvariant(kTRUE),
53   fdEdx(t.GetITSsignal()),
54   fESDtrack(&t)
55 {
56   //------------------------------------------------------------------
57   // Conversion ESD track -> ITS track.
58   // If c==kTRUE, create the ITS track out of the constrained params.
59   //------------------------------------------------------------------
60   const AliExternalTrackParam *par=&t;
61   if (c) {
62     par=t.GetConstrainedParam();
63     if (!par) throw "AliITStrackV2: conversion failed !\n";
64   }
65   Set(par->GetX(),par->GetAlpha(),par->GetParameter(),par->GetCovariance());
66
67   //if (!Invariant()) throw "AliITStrackV2: conversion failed !\n";
68
69   SetLabel(t.GetLabel());
70   SetMass(t.GetMass());
71   SetNumberOfClusters(t.GetITSclusters(fIndex));
72
73   if (t.GetStatus()&AliESDtrack::kTIME) {
74     StartTimeIntegral();
75     Double_t times[10]; t.GetIntegratedTimes(times); SetIntegratedTimes(times);
76     SetIntegratedLength(t.GetIntegratedLength());
77   }
78
79   for(Int_t i=0; i<4; i++) fdEdxSample[i]=0;
80 }
81
82 //____________________________________________________________________________
83 void AliITStrackV2::ResetClusters() {
84   //------------------------------------------------------------------
85   // Reset the array of attached clusters.
86   //------------------------------------------------------------------
87   for (Int_t i=0; i<2*AliITSgeomTGeo::kNLayers; i++) fIndex[i]=-1;
88   SetChi2(0.); 
89   SetNumberOfClusters(0);
90
91
92 //____________________________________________________________________________
93 void AliITStrackV2::UpdateESDtrack(ULong_t flags) const {
94   // Update track params
95   fESDtrack->UpdateTrackParams(this,flags);
96   // copy the module indices
97   for(Int_t i=0;i<12;i++) {
98     //   printf("     %d\n",GetModuleIndex(i));
99     fESDtrack->SetITSModuleIndex(i,GetModuleIndex(i));
100   }
101   // copy the 4 dedx samples
102   Double_t sdedx[4]={0.,0.,0.,0.};
103   for(Int_t i=0; i<4; i++) sdedx[i]=fdEdxSample[i];
104   fESDtrack->SetITSdEdxSamples(sdedx);
105 }
106
107 //____________________________________________________________________________
108 AliITStrackV2::AliITStrackV2(const AliITStrackV2& t) : 
109   AliKalmanTrack(t),
110   fCheckInvariant(t.fCheckInvariant),
111   fdEdx(t.fdEdx),
112   fESDtrack(t.fESDtrack) 
113 {
114   //------------------------------------------------------------------
115   //Copy constructor
116   //------------------------------------------------------------------
117   Int_t i;
118   for (i=0; i<4; i++) fdEdxSample[i]=t.fdEdxSample[i];
119   for (i=0; i<2*AliITSgeomTGeo::GetNLayers(); i++) {
120     fIndex[i]=t.fIndex[i];
121     fModule[i]=t.fModule[i];
122   }
123 }
124
125 //_____________________________________________________________________________
126 Int_t AliITStrackV2::Compare(const TObject *o) const {
127   //-----------------------------------------------------------------
128   // This function compares tracks according to the their curvature
129   //-----------------------------------------------------------------
130   AliITStrackV2 *t=(AliITStrackV2*)o;
131   //Double_t co=OneOverPt();
132   //Double_t c =OneOverPt();
133   Double_t co=t->GetSigmaY2()*t->GetSigmaZ2();
134   Double_t c =GetSigmaY2()*GetSigmaZ2();
135   if (c>co) return 1;
136   else if (c<co) return -1;
137   return 0;
138 }
139
140 //____________________________________________________________________________
141 Bool_t 
142 AliITStrackV2::PropagateToVertex(const AliESDVertex *v,Double_t d,Double_t x0) 
143 {
144   //------------------------------------------------------------------
145   //This function propagates a track to the minimal distance from the origin
146   //------------------------------------------------------------------  
147   Double_t bz=GetBz();
148   if (PropagateToDCA(v,bz,kVeryBig)) {
149     Double_t xOverX0,xTimesRho; 
150     xOverX0 = d; xTimesRho = d*x0;
151     if (CorrectForMeanMaterial(xOverX0,xTimesRho,kTRUE)) return kTRUE;
152   }
153   return kFALSE;
154 }
155
156 //____________________________________________________________________________
157 Bool_t AliITStrackV2::
158 GetGlobalXYZat(Double_t xloc, Double_t &x, Double_t &y, Double_t &z) const {
159   //------------------------------------------------------------------
160   //This function returns a track position in the global system
161   //------------------------------------------------------------------
162   Double_t r[3];
163   Bool_t rc=GetXYZAt(xloc, GetBz(), r);
164   x=r[0]; y=r[1]; z=r[2]; 
165   return rc;
166 }
167
168 //_____________________________________________________________________________
169 Double_t AliITStrackV2::GetPredictedChi2(const AliCluster *c) const {
170   //-----------------------------------------------------------------
171   // This function calculates a predicted chi2 increment.
172   //-----------------------------------------------------------------
173   Double_t p[2]={c->GetY(), c->GetZ()};
174   Double_t cov[3]={c->GetSigmaY2(), 0., c->GetSigmaZ2()};
175   return AliExternalTrackParam::GetPredictedChi2(p,cov);
176 }
177
178 //____________________________________________________________________________
179 Bool_t AliITStrackV2::PropagateTo(Double_t xk, Double_t d, Double_t x0) {
180   //------------------------------------------------------------------
181   //This function propagates a track
182   //------------------------------------------------------------------
183
184   Double_t oldX=GetX(), oldY=GetY(), oldZ=GetZ();
185   
186   //Double_t bz=GetBz();
187   //if (!AliExternalTrackParam::PropagateTo(xk,bz)) return kFALSE;
188   Double_t b[3]; GetBxByBz(b);
189   if (!AliExternalTrackParam::PropagateToBxByBz(xk,b)) return kFALSE;
190   Double_t xOverX0,xTimesRho; 
191   xOverX0 = d; xTimesRho = d*x0;
192   if (!CorrectForMeanMaterial(xOverX0,xTimesRho,kTRUE)) return kFALSE;
193
194   Double_t x=GetX(), y=GetY(), z=GetZ();
195   if (IsStartedTimeIntegral() && x>oldX) {
196     Double_t l2 = (x-oldX)*(x-oldX) + (y-oldY)*(y-oldY) + (z-oldZ)*(z-oldZ);
197     AddTimeStep(TMath::Sqrt(l2));
198   }
199
200   return kTRUE;
201 }
202
203 //____________________________________________________________________________
204 Bool_t AliITStrackV2::PropagateToTGeo(Double_t xToGo, Int_t nstep, Double_t &xOverX0, Double_t &xTimesRho, Bool_t addTime) {
205   //-------------------------------------------------------------------
206   //  Propagates the track to a reference plane x=xToGo in n steps.
207   //  These n steps are only used to take into account the curvature.
208   //  The material is calculated with TGeo. (L.Gaudichet)
209   //-------------------------------------------------------------------
210   
211   Double_t startx = GetX(), starty = GetY(), startz = GetZ();
212   Double_t sign = (startx<xToGo) ? -1.:1.;
213   Double_t step = (xToGo-startx)/TMath::Abs(nstep);
214
215   Double_t start[3], end[3], mparam[7];
216   //Double_t bz = GetBz();
217   Double_t b[3]; GetBxByBz(b);
218   Double_t bz = b[2];
219
220   Double_t x = startx;
221   
222   for (Int_t i=0; i<nstep; i++) {
223     
224     GetXYZ(start);   //starting global position
225     x += step;
226     if (!GetXYZAt(x, bz, end)) return kFALSE;
227     //if (!AliExternalTrackParam::PropagateTo(x, bz)) return kFALSE;
228     if (!AliExternalTrackParam::PropagateToBxByBz(x, b)) return kFALSE;
229     AliTracker::MeanMaterialBudget(start, end, mparam);
230     xTimesRho = sign*mparam[4]*mparam[0];
231     xOverX0   = mparam[1];
232     if (mparam[1]<900000) {
233       if (!AliExternalTrackParam::CorrectForMeanMaterial(xOverX0,
234                            xTimesRho,GetMass())) return kFALSE;
235     } else { // this happens when MeanMaterialBudget cannot cross a boundary
236       return kFALSE;
237     }
238   }
239
240   if (addTime && IsStartedTimeIntegral() && GetX()>startx) {
241     Double_t l2 = ( (GetX()-startx)*(GetX()-startx) +
242                     (GetY()-starty)*(GetY()-starty) +
243                     (GetZ()-startz)*(GetZ()-startz) );
244     AddTimeStep(TMath::Sqrt(l2));
245   }
246
247   return kTRUE;
248 }
249
250 //____________________________________________________________________________
251 Bool_t AliITStrackV2::Update(const AliCluster* c, Double_t chi2, Int_t index) 
252 {
253   //------------------------------------------------------------------
254   //This function updates track parameters
255   //------------------------------------------------------------------
256   Double_t p[2]={c->GetY(), c->GetZ()};
257   Double_t cov[3]={c->GetSigmaY2(), c->GetSigmaYZ(), c->GetSigmaZ2()};
258
259   if (!AliExternalTrackParam::Update(p,cov)) return kFALSE;
260
261   Int_t n=GetNumberOfClusters();
262   if (!Invariant()) {
263      if (n>fgkWARN) AliWarning("Wrong invariant !");
264      return kFALSE;
265   }
266
267   if (chi2<0) return kTRUE;
268
269   // fill residuals for ITS+TPC tracks 
270   if (fESDtrack) {
271     if (fESDtrack->GetStatus()&AliESDtrack::kTPCin) {
272       AliTracker::FillResiduals(this,p,cov,c->GetVolumeId());
273     }
274   }
275
276   fIndex[n]=index;
277   SetNumberOfClusters(n+1);
278   SetChi2(GetChi2()+chi2);
279
280   return kTRUE;
281 }
282
283 Bool_t AliITStrackV2::Invariant() const {
284   //------------------------------------------------------------------
285   // This function is for debugging purpose only
286   //------------------------------------------------------------------
287   if(!fCheckInvariant) return kTRUE;
288
289   Int_t n=GetNumberOfClusters();
290
291   // take into account the misalignment error
292   Float_t maxMisalErrY2=0,maxMisalErrZ2=0;
293   for (Int_t lay=0; lay<AliITSgeomTGeo::kNLayers; lay++) {
294     maxMisalErrY2 = TMath::Max(maxMisalErrY2,AliITSReconstructor::GetRecoParam()->GetClusterMisalErrorY(lay,GetBz()));
295     maxMisalErrZ2 = TMath::Max(maxMisalErrZ2,AliITSReconstructor::GetRecoParam()->GetClusterMisalErrorZ(lay,GetBz()));
296   }
297   maxMisalErrY2 *= maxMisalErrY2;
298   maxMisalErrZ2 *= maxMisalErrZ2;
299   // this is because when we reset before refitting, we multiply the
300   // matrix by 10
301   maxMisalErrY2 *= 10.; 
302   maxMisalErrZ2 *= 10.;
303
304   Double_t sP2=GetParameter()[2];
305   if (TMath::Abs(sP2) >= kAlmost1){
306      if (n>fgkWARN) Warning("Invariant","fP2=%f\n",sP2);
307      return kFALSE;
308   }
309   Double_t sC00=GetCovariance()[0];
310   if (sC00<=0 || sC00>(9.+maxMisalErrY2)) {
311      if (n>fgkWARN) Warning("Invariant","fC00=%f\n",sC00); 
312      return kFALSE;
313   }
314   Double_t sC11=GetCovariance()[2];
315   if (sC11<=0 || sC11>(9.+maxMisalErrZ2)) {
316      if (n>fgkWARN) Warning("Invariant","fC11=%f\n",sC11); 
317      return kFALSE;
318   }
319   Double_t sC22=GetCovariance()[5];
320   if (sC22<=0 || sC22>1.) {
321      if (n>fgkWARN) Warning("Invariant","fC22=%f\n",sC22); 
322      return kFALSE;
323   }
324   Double_t sC33=GetCovariance()[9];
325   if (sC33<=0 || sC33>1.) {
326      if (n>fgkWARN) Warning("Invariant","fC33=%f\n",sC33); 
327      return kFALSE;
328   }
329   Double_t sC44=GetCovariance()[14];
330   if (sC44<=0 /*|| sC44>6e-5*/) {
331      if (n>fgkWARN) Warning("Invariant","fC44=%f\n",sC44);
332      return kFALSE;
333   }
334
335   return kTRUE;
336 }
337
338 //____________________________________________________________________________
339 Bool_t AliITStrackV2::Propagate(Double_t alp,Double_t xk) {
340   //------------------------------------------------------------------
341   //This function propagates a track
342   //------------------------------------------------------------------
343   //Double_t bz=GetBz();
344   //if (!AliExternalTrackParam::Propagate(alp,xk,bz)) return kFALSE;
345   Double_t b[3]; GetBxByBz(b);
346   if (!AliExternalTrackParam::PropagateBxByBz(alp,xk,b)) return kFALSE;
347
348   if (!Invariant()) {
349     Int_t n=GetNumberOfClusters();
350     if (n>fgkWARN) AliWarning("Wrong invariant !");
351     return kFALSE;
352   }
353
354   return kTRUE;
355 }
356
357 Bool_t AliITStrackV2::MeanBudgetToPrimVertex(Double_t xyz[3], Double_t step, Double_t &d) const {
358
359   //-------------------------------------------------------------------
360   //  Get the mean material budget between the actual point and the
361   //  primary vertex. (L.Gaudichet)
362   //-------------------------------------------------------------------
363
364   Double_t cs=TMath::Cos(GetAlpha()), sn=TMath::Sin(GetAlpha());
365   Double_t vertexX = xyz[0]*cs + xyz[1]*sn;
366
367   Int_t nstep = Int_t((GetX()-vertexX)/step);
368   if (nstep<1) nstep = 1;
369   step = (GetX()-vertexX)/nstep;
370
371   //  Double_t mparam[7], densMean=0, radLength=0, length=0;
372   Double_t mparam[7];
373   Double_t p1[3], p2[3], x = GetX(), bz = GetBz();
374   GetXYZ(p1);
375
376   d=0.;
377
378   for (Int_t i=0; i<nstep; i++) {
379     x  += step;
380     if (!GetXYZAt(x, bz, p2)) return kFALSE;
381     AliTracker::MeanMaterialBudget(p1, p2, mparam);
382     if (mparam[1]>900000) return kFALSE;
383     d  += mparam[1];
384
385     p1[0] = p2[0];
386     p1[1] = p2[1];
387     p1[2] = p2[2];
388   }
389
390   return kTRUE;
391 }
392
393 Bool_t AliITStrackV2::Improve(Double_t x0,Double_t xyz[3],Double_t ers[3]) {
394   //------------------------------------------------------------------
395   //This function improves angular track parameters
396   //------------------------------------------------------------------
397   //Store the initail track parameters
398
399   return kTRUE; //PH temporary switched off
400
401   Double_t x = GetX();
402   Double_t alpha = GetAlpha();
403   Double_t par[] = {GetY(),GetZ(),GetSnp(),GetTgl(),GetSigned1Pt()};
404   Double_t cov[] = {
405     GetSigmaY2(),
406     GetSigmaZY(),
407     GetSigmaZ2(),
408     GetSigmaSnpY(),
409     GetSigmaSnpZ(),
410     GetSigmaSnp2(),
411     GetSigmaTglY(),
412     GetSigmaTglZ(),
413     GetSigmaTglSnp(),
414     GetSigmaTgl2(),
415     GetSigma1PtY(),
416     GetSigma1PtZ(),
417     GetSigma1PtSnp(),
418     GetSigma1PtTgl(),
419     GetSigma1Pt2()
420   }; 
421
422
423   Double_t cs=TMath::Cos(GetAlpha()), sn=TMath::Sin(GetAlpha());
424 //Double_t xv = xyz[0]*cs + xyz[1]*sn; // vertex
425   Double_t yv =-xyz[0]*sn + xyz[1]*cs; // in the
426   Double_t zv = xyz[2];                // local frame
427
428   Double_t dy = par[0] - yv, dz = par[1] - zv;
429   Double_t r2=GetX()*GetX() + dy*dy;
430   Double_t p2=(1.+ GetTgl()*GetTgl())/(GetSigned1Pt()*GetSigned1Pt());
431   Double_t beta2=p2/(p2 + GetMass()*GetMass());
432   x0*=TMath::Sqrt((1.+ GetTgl()*GetTgl())/(1.- GetSnp()*GetSnp()));
433   Double_t theta2=14.1*14.1/(beta2*p2*1e6)*x0;
434   //Double_t theta2=1.0259e-6*14*14/28/(beta2*p2)*x0*9.36*2.33;
435
436   Double_t cnv=GetBz()*kB2C;
437   {
438     Double_t dummy = 4/r2 - GetC()*GetC();
439     if (dummy < 0) return kFALSE;
440     Double_t parp = 0.5*(GetC()*GetX() + dy*TMath::Sqrt(dummy));
441     Double_t sigma2p = theta2*(1.-GetSnp())*(1.+GetSnp())*(1. + GetTgl()*GetTgl());
442     Double_t ovSqr2 = 1./TMath::Sqrt(r2);
443     Double_t tfact = ovSqr2*(1.-dy*ovSqr2)*(1.+dy*ovSqr2);
444     sigma2p += cov[0]*tfact*tfact;
445     sigma2p += ers[1]*ers[1]/r2;
446     sigma2p += 0.25*cov[14]*cnv*cnv*GetX()*GetX();
447     Double_t eps2p=sigma2p/(cov[5] + sigma2p);
448     par[0] += cov[3]/(cov[5] + sigma2p)*(parp - GetSnp());
449     par[2]  = eps2p*GetSnp() + (1 - eps2p)*parp;
450     cov[5] *= eps2p;
451     cov[3] *= eps2p;
452   }
453   {
454     Double_t parl=0.5*GetC()*dz/TMath::ASin(0.5*GetC()*TMath::Sqrt(r2));
455     Double_t sigma2l=theta2;
456     sigma2l += cov[2]/r2 + cov[0]*dy*dy*dz*dz/(r2*r2*r2);
457     sigma2l += ers[2]*ers[2]/r2;
458     Double_t eps2l = sigma2l/(cov[9] + sigma2l);
459     par[1] += cov[7 ]/(cov[9] + sigma2l)*(parl - par[3]);
460     par[4] += cov[13]/(cov[9] + sigma2l)*(parl - par[3]);
461     par[3]  = eps2l*par[3] + (1-eps2l)*parl;
462     cov[9] *= eps2l; 
463     cov[13]*= eps2l; 
464     cov[7] *= eps2l; 
465   }
466
467   Set(x,alpha,par,cov);
468
469   if (!Invariant()) return kFALSE;
470
471   return kTRUE;
472 }
473
474 void AliITStrackV2::CookdEdx(Double_t low, Double_t up) {
475   //-----------------------------------------------------------------
476   // This function calculates dE/dX within the "low" and "up" cuts.
477   // Origin: Boris Batyunya, JINR, Boris.Batiounia@cern.ch 
478   // Updated: F. Prino 8-June-2009
479   //-----------------------------------------------------------------
480   // The cluster order is: SDD-1, SDD-2, SSD-1, SSD-2
481
482   Int_t nc=0;
483   Float_t dedx[4];
484   for (Int_t il=0; il<4; il++) { // count good (>0) dE/dx values
485     if(fdEdxSample[il]>0.){
486       dedx[nc]= fdEdxSample[il];
487       nc++;
488     }
489   }
490   if(nc<1){
491     SetdEdx(0.);
492     return;
493   }
494
495   Int_t swap; // sort in ascending order
496   do {
497     swap=0;
498     for (Int_t i=0; i<nc-1; i++) {
499       if (dedx[i]<=dedx[i+1]) continue;
500       Float_t tmp=dedx[i];
501       dedx[i]=dedx[i+1]; 
502       dedx[i+1]=tmp;
503       swap++;
504     }
505   } while (swap);
506
507
508   Double_t nl=low*nc, nu =up*nc;
509   Float_t sumamp = 0;
510   Float_t sumweight =0;
511   for (Int_t i=0; i<nc; i++) {
512     Float_t weight =1;
513     if (i<nl+0.1)     weight = TMath::Max(1.-(nl-i),0.);
514     if (i>nu-1)     weight = TMath::Max(nu-i,0.);
515     sumamp+= dedx[i]*weight;
516     sumweight+=weight;
517   }
518   SetdEdx(sumamp/sumweight);
519 }
520
521 //____________________________________________________________________________
522 Bool_t AliITStrackV2::
523 GetPhiZat(Double_t r, Double_t &phi, Double_t &z) const {
524   //------------------------------------------------------------------
525   // This function returns the global cylindrical (phi,z) of the track 
526   // position estimated at the radius r. 
527   // The track curvature is neglected.
528   //------------------------------------------------------------------
529   Double_t d=GetD(0.,0.);
530   if (TMath::Abs(d) > r) {
531     if (r>1e-1) return kFALSE;
532     r = TMath::Abs(d);
533   }
534
535   Double_t rcurr=TMath::Sqrt(GetX()*GetX() + GetY()*GetY());
536   if (TMath::Abs(d) > rcurr) return kFALSE;
537   Double_t globXYZcurr[3]; GetXYZ(globXYZcurr); 
538   Double_t phicurr=TMath::ATan2(globXYZcurr[1],globXYZcurr[0]);
539
540   if (GetX()>=0.) {
541     phi=phicurr+TMath::ASin(d/r)-TMath::ASin(d/rcurr);
542   } else {
543     phi=phicurr+TMath::ASin(d/r)+TMath::ASin(d/rcurr)-TMath::Pi();
544   }
545
546   // return a phi in [0,2pi[ 
547   if (phi<0.) phi+=2.*TMath::Pi();
548   else if (phi>=2.*TMath::Pi()) phi-=2.*TMath::Pi();
549   z=GetZ()+GetTgl()*(TMath::Sqrt((r-d)*(r+d))-TMath::Sqrt((rcurr-d)*(rcurr+d)));
550   return kTRUE;
551 }
552 //____________________________________________________________________________
553 Bool_t AliITStrackV2::
554 GetLocalXat(Double_t r,Double_t &xloc) const {
555   //------------------------------------------------------------------
556   // This function returns the local x of the track 
557   // position estimated at the radius r. 
558   // The track curvature is neglected.
559   //------------------------------------------------------------------
560   Double_t d=GetD(0.,0.);
561   if (TMath::Abs(d) > r) { 
562     if (r>1e-1) return kFALSE; 
563     r = TMath::Abs(d); 
564   } 
565
566   Double_t rcurr=TMath::Sqrt(GetX()*GetX() + GetY()*GetY());
567   Double_t globXYZcurr[3]; GetXYZ(globXYZcurr); 
568   Double_t phicurr=TMath::ATan2(globXYZcurr[1],globXYZcurr[0]);
569   Double_t phi;
570   if (GetX()>=0.) {
571     phi=phicurr+TMath::ASin(d/r)-TMath::ASin(d/rcurr);
572   } else {
573     phi=phicurr+TMath::ASin(d/r)+TMath::ASin(d/rcurr)-TMath::Pi();
574   }
575
576   xloc=r*(TMath::Cos(phi)*TMath::Cos(GetAlpha())
577          +TMath::Sin(phi)*TMath::Sin(GetAlpha())); 
578
579   return kTRUE;
580 }