Double_t crv=GetC(b);
if (TMath::Abs(b) < kAlmost0Field) crv=0.;
- Double_t f1=fP[2], f2=f1 + crv*dx;
+ Double_t x2r = crv*dx;
+ Double_t f1=fP[2], f2=f1 + x2r;
if (TMath::Abs(f1) >= kAlmost1) return kFALSE;
if (TMath::Abs(f2) >= kAlmost1) return kFALSE;
Double_t r1=TMath::Sqrt((1.-f1)*(1.+f1)), r2=TMath::Sqrt((1.-f2)*(1.+f2));
fX=xk;
- fP0 += dx*(f1+f2)/(r1+r2);
- fP1 += dx*(r2 + f2*(f1+f2)/(r1+r2))*fP3; // Many thanks to P.Hristov !
- fP2 += dx*crv;
+ double dy2dx = (f1+f2)/(r1+r2);
+ fP0 += dx*dy2dx;
+ if (TMath::Abs(x2r)<0.05) {
+ fP1 += dx*(r2 + f2*dy2dx)*fP3; // Many thanks to P.Hristov !
+ fP2 += x2r;
+ }
+ else {
+ // for small dx/R the linear apporximation of the arc by the segment is OK,
+ // but at large dx/R the error is very large and leads to incorrect Z propagation
+ // angle traversed delta = 2*asin(dist_start_end / R / 2), hence the arc is: R*deltaPhi
+ // The dist_start_end is obtained from sqrt(dx^2+dy^2) = x/(r1+r2)*sqrt(2+f1*f2+r1*r2)
+ // Similarly, the rotation angle in linear in dx only for dx<<R
+ double chord = dx*TMath::Sqrt(1+dy2dx*dy2dx); // distance from old position to new one
+ double rot = 2*TMath::ASin(0.5*chord*crv); // angular difference seen from the circle center
+ fP1 += rot/crv*fP3;
+ fP2 = TMath::Sin(rot + TMath::ASin(fP2));
+ }
//f = F - 1
Double_t tet = rho*step;
Double_t tsint, sintt, sint, cos1t;
- if (TMath::Abs(tet) > 0.15) {
+ if (TMath::Abs(tet) > 0.03) {
sint = TMath::Sin(tet);
sintt = sint/tet;
tsint = (tet - sint)/tet;
Double_t crv=GetC(b[2]);
if (TMath::Abs(b[2]) < kAlmost0Field) crv=0.;
- Double_t f1=fP[2], f2=f1 + crv*dx;
+ Double_t x2r = crv*dx;
+ Double_t f1=fP[2], f2=f1 + x2r;
if (TMath::Abs(f1) >= kAlmost1) return kFALSE;
if (TMath::Abs(f2) >= kAlmost1) return kFALSE;
CheckCovariance();
// Appoximate step length
- Double_t step=dx*TMath::Abs(r2 + f2*(f1+f2)/(r1+r2));
+ double dy2dx = (f1+f2)/(r1+r2);
+ Double_t step = (TMath::Abs(x2r)<0.05) ? dx*TMath::Abs(r2 + f2*dy2dx) // chord
+ : 2.*TMath::ASin(0.5*dx*TMath::Sqrt(1.+dy2dx*dy2dx)*crv)/crv; // arc
step *= TMath::Sqrt(1.+ GetTgl()*GetTgl());
-
// Get the track's (x,y,z) and (px,py,pz) in the Global System
Double_t r[3]; GetXYZ(r);
Double_t p[3]; GetPxPyPz(p);