+Double_t AliExternalTrackParam::Eta() const {
+ // return pseudorapidity
+
+ return -TMath::Log(TMath::Tan(0.5 * Theta()));
+}
+
+Double_t AliExternalTrackParam::Y() const {
+ // return rapidity
+
+ // No PID information available so far.
+ // Redifine in derived class!
+
+ return -999.;
+}
+
+Bool_t AliExternalTrackParam::GetXYZ(Double_t *r) const {
+ //---------------------------------------------------------------------
+ // This function returns the global track position
+ //---------------------------------------------------------------------
+ r[0]=fX; r[1]=fP[0]; r[2]=fP[1];
+ return Local2GlobalPosition(r,fAlpha);
+}
+
+Bool_t AliExternalTrackParam::GetCovarianceXYZPxPyPz(Double_t cv[21]) const {
+ //---------------------------------------------------------------------
+ // This function returns the global covariance matrix of the track params
+ //
+ // Cov(x,x) ... : cv[0]
+ // Cov(y,x) ... : cv[1] cv[2]
+ // Cov(z,x) ... : cv[3] cv[4] cv[5]
+ // Cov(px,x)... : cv[6] cv[7] cv[8] cv[9]
+ // Cov(py,x)... : cv[10] cv[11] cv[12] cv[13] cv[14]
+ // Cov(pz,x)... : cv[15] cv[16] cv[17] cv[18] cv[19] cv[20]
+ //
+ // Results for (nearly) straight tracks are meaningless !
+ //---------------------------------------------------------------------
+ if (TMath::Abs(fP[4])<=kAlmost0) {
+ for (Int_t i=0; i<21; i++) cv[i]=0.;
+ return kFALSE;
+ }
+ if (TMath::Abs(fP[2]) > kAlmost1) {
+ for (Int_t i=0; i<21; i++) cv[i]=0.;
+ return kFALSE;
+ }
+ Double_t pt=1./TMath::Abs(fP[4]);
+ Double_t cs=TMath::Cos(fAlpha), sn=TMath::Sin(fAlpha);
+ Double_t r=TMath::Sqrt((1.-fP[2])*(1.+fP[2]));
+
+ Double_t m00=-sn, m10=cs;
+ Double_t m23=-pt*(sn + fP[2]*cs/r), m43=-pt*pt*(r*cs - fP[2]*sn);
+ Double_t m24= pt*(cs - fP[2]*sn/r), m44=-pt*pt*(r*sn + fP[2]*cs);
+ Double_t m35=pt, m45=-pt*pt*fP[3];
+
+ m43*=GetSign();
+ m44*=GetSign();
+ m45*=GetSign();
+
+ cv[0 ] = fC[0]*m00*m00;
+ cv[1 ] = fC[0]*m00*m10;
+ cv[2 ] = fC[0]*m10*m10;
+ cv[3 ] = fC[1]*m00;
+ cv[4 ] = fC[1]*m10;
+ cv[5 ] = fC[2];
+ cv[6 ] = m00*(fC[3]*m23 + fC[10]*m43);
+ cv[7 ] = m10*(fC[3]*m23 + fC[10]*m43);
+ cv[8 ] = fC[4]*m23 + fC[11]*m43;
+ cv[9 ] = m23*(fC[5]*m23 + fC[12]*m43) + m43*(fC[12]*m23 + fC[14]*m43);
+ cv[10] = m00*(fC[3]*m24 + fC[10]*m44);
+ cv[11] = m10*(fC[3]*m24 + fC[10]*m44);
+ cv[12] = fC[4]*m24 + fC[11]*m44;
+ cv[13] = m23*(fC[5]*m24 + fC[12]*m44) + m43*(fC[12]*m24 + fC[14]*m44);
+ cv[14] = m24*(fC[5]*m24 + fC[12]*m44) + m44*(fC[12]*m24 + fC[14]*m44);
+ cv[15] = m00*(fC[6]*m35 + fC[10]*m45);
+ cv[16] = m10*(fC[6]*m35 + fC[10]*m45);
+ cv[17] = fC[7]*m35 + fC[11]*m45;
+ cv[18] = m23*(fC[8]*m35 + fC[12]*m45) + m43*(fC[13]*m35 + fC[14]*m45);
+ cv[19] = m24*(fC[8]*m35 + fC[12]*m45) + m44*(fC[13]*m35 + fC[14]*m45);
+ cv[20] = m35*(fC[9]*m35 + fC[13]*m45) + m45*(fC[13]*m35 + fC[14]*m45);
+
+ return kTRUE;
+}
+
+
+Bool_t
+AliExternalTrackParam::GetPxPyPzAt(Double_t x, Double_t b, Double_t *p) const {
+ //---------------------------------------------------------------------
+ // This function returns the global track momentum extrapolated to
+ // the radial position "x" (cm) in the magnetic field "b" (kG)
+ //---------------------------------------------------------------------
+ p[0]=fP[4];
+ p[1]=fP[2]+(x-fX)*GetC(b);
+ p[2]=fP[3];
+ return Local2GlobalMomentum(p,fAlpha);
+}
+
+Bool_t
+AliExternalTrackParam::GetYAt(Double_t x, Double_t b, Double_t &y) const {
+ //---------------------------------------------------------------------
+ // This function returns the local Y-coordinate of the intersection
+ // point between this track and the reference plane "x" (cm).
+ // Magnetic field "b" (kG)
+ //---------------------------------------------------------------------
+ Double_t dx=x-fX;
+ if(TMath::Abs(dx)<=kAlmost0) {y=fP[0]; return kTRUE;}
+
+ Double_t f1=fP[2], f2=f1 + dx*GetC(b);
+
+ if (TMath::Abs(f1) >= kAlmost1) return kFALSE;
+ if (TMath::Abs(f2) >= kAlmost1) return kFALSE;
+
+ Double_t r1=TMath::Sqrt(1.- f1*f1), r2=TMath::Sqrt(1.- f2*f2);
+ y = fP[0] + dx*(f1+f2)/(r1+r2);
+ return kTRUE;
+}
+
+Bool_t
+AliExternalTrackParam::GetZAt(Double_t x, Double_t b, Double_t &z) const {
+ //---------------------------------------------------------------------
+ // This function returns the local Z-coordinate of the intersection
+ // point between this track and the reference plane "x" (cm).
+ // Magnetic field "b" (kG)
+ //---------------------------------------------------------------------
+ Double_t dx=x-fX;
+ if(TMath::Abs(dx)<=kAlmost0) {z=fP[1]; return kTRUE;}
+
+ Double_t f1=fP[2], f2=f1 + dx*GetC(b);
+
+ if (TMath::Abs(f1) >= kAlmost1) return kFALSE;
+ if (TMath::Abs(f2) >= kAlmost1) return kFALSE;
+
+ Double_t r1=sqrt(1.- f1*f1), r2=sqrt(1.- f2*f2);
+ z = fP[1] + dx*(r2 + f2*(f1+f2)/(r1+r2))*fP[3]; // Many thanks to P.Hristov !
+ return kTRUE;
+}
+
+Bool_t
+AliExternalTrackParam::GetXYZAt(Double_t x, Double_t b, Double_t *r) const {
+ //---------------------------------------------------------------------
+ // This function returns the global track position extrapolated to
+ // the radial position "x" (cm) in the magnetic field "b" (kG)
+ //---------------------------------------------------------------------
+ Double_t dx=x-fX;
+ if(TMath::Abs(dx)<=kAlmost0) return GetXYZ(r);
+
+ Double_t f1=fP[2], f2=f1 + dx*GetC(b);
+
+ if (TMath::Abs(f1) >= kAlmost1) return kFALSE;
+ if (TMath::Abs(f2) >= kAlmost1) return kFALSE;
+
+ Double_t r1=TMath::Sqrt(1.- f1*f1), r2=TMath::Sqrt(1.- f2*f2);
+ r[0] = x;
+ r[1] = fP[0] + dx*(f1+f2)/(r1+r2);
+ r[2] = fP[1] + dx*(r2 + f2*(f1+f2)/(r1+r2))*fP[3];//Thanks to Andrea & Peter
+
+ return Local2GlobalPosition(r,fAlpha);
+}