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