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