ClassImp(AliExternalTrackParam)
Double32_t AliExternalTrackParam::fgMostProbablePt=kMostProbablePt;
-
+Bool_t AliExternalTrackParam::fgUseLogTermMS = kFALSE;;
//_____________________________________________________________________________
AliExternalTrackParam::AliExternalTrackParam() :
AliVTrack(),
// azimuthal angle of the centre of the TPC sector in which the point
// xyz lies
//
+ const double kSafe = 1e-5;
Double_t radPos2 = xyz[0]*xyz[0]+xyz[1]*xyz[1];
Double_t radMax = 45.; // approximately ITS outer radius
- if (radPos2 < radMax*radMax) { // inside the ITS
-
+ if (radPos2 < radMax*radMax) { // inside the ITS
fAlpha = TMath::ATan2(pxpypz[1],pxpypz[0]);
} else { // outside the ITS
Float_t phiPos = TMath::Pi()+TMath::ATan2(-xyz[1], -xyz[0]);
fAlpha =
TMath::DegToRad()*(20*((((Int_t)(phiPos*TMath::RadToDeg()))/20))+10);
}
-
+ //
+ Double_t cs=TMath::Cos(fAlpha), sn=TMath::Sin(fAlpha);
+ // protection: avoid alpha being too close to 0 or +-pi/2
+ if (TMath::Abs(sn)<kSafe) {
+ fAlpha = kSafe;
+ cs=TMath::Cos(fAlpha);
+ sn=TMath::Sin(fAlpha);
+ }
+ else if (cs<kSafe) {
+ fAlpha -= TMath::Sign(kSafe, fAlpha);
+ cs=TMath::Cos(fAlpha);
+ sn=TMath::Sin(fAlpha);
+ }
// Get the vertex of origin and the momentum
TVector3 ver(xyz[0],xyz[1],xyz[2]);
TVector3 mom(pxpypz[0],pxpypz[1],pxpypz[2]);
+ //
+ // avoid momenta along axis
+ if (TMath::Abs(mom[0])<kSafe) mom[0] = TMath::Sign(kSafe*TMath::Abs(mom[1]), mom[0]);
+ if (TMath::Abs(mom[1])<kSafe) mom[1] = TMath::Sign(kSafe*TMath::Abs(mom[0]), mom[1]);
// Rotate to the local coordinate system
ver.RotateZ(-fAlpha);
// Covariance matrix (formulas to be simplified)
+ if (TMath::Abs( 1-fP[2]) < kSafe) fP[2] = 1.- kSafe; //Protection
+ else if (TMath::Abs(-1-fP[2]) < kSafe) fP[2] =-1.+ kSafe; //Protection
+
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;
//------------------------------------------------------------------
// This function corrects the track parameters for the crossed material.
// "xOverX0" - X/X0, the thickness in units of the radiation length.
- // "xTimesRho" - is the product length*density (g/cm^2).
+ // "xTimesRho" - is the product length*density (g/cm^2).
+ // It should be passed as negative when propagating tracks
+ // from the intreaction point to the outside of the central barrel.
// "mass" - the mass of this particle (GeV/c^2).
// "dEdx" - mean enery loss (GeV/(g/cm^2)
// "anglecorr" - switch for the angular correction
Double_t cC43 = 0.;
Double_t cC44 = 0.;
if (xOverX0 != 0) {
- Double_t theta2=14.1*14.1/(beta2*p2*1e6)*TMath::Abs(xOverX0);
- //Double_t theta2=1.0259e-6*14*14/28/(beta2*p2)*TMath::Abs(d)*9.36*2.33;
- if(theta2>TMath::Pi()*TMath::Pi()) return kFALSE;
- cC22 = theta2*((1.-fP2)*(1.+fP2))*(1. + fP3*fP3);
- cC33 = theta2*(1. + fP3*fP3)*(1. + fP3*fP3);
- cC43 = theta2*fP3*fP4*(1. + fP3*fP3);
- cC44 = theta2*fP3*fP4*fP3*fP4;
+ //Double_t theta2=1.0259e-6*14*14/28/(beta2*p2)*TMath::Abs(d)*9.36*2.33;
+ Double_t theta2=0.0136*0.0136/(beta2*p2)*TMath::Abs(xOverX0);
+ if (GetUseLogTermMS()) {
+ double lt = 1+0.038*TMath::Log(TMath::Abs(xOverX0));
+ if (lt>0) theta2 *= lt*lt;
+ }
+ if(theta2>TMath::Pi()*TMath::Pi()) return kFALSE;
+ cC22 = theta2*((1.-fP2)*(1.+fP2))*(1. + fP3*fP3);
+ cC33 = theta2*(1. + fP3*fP3)*(1. + fP3*fP3);
+ cC43 = theta2*fP3*fP4*(1. + fP3*fP3);
+ cC44 = theta2*fP3*fP4*fP3*fP4;
}
//Calculating the energy loss corrections************************
Double_t e=TMath::Sqrt(p2 + mass*mass);
if ( TMath::Abs(dE) > 0.3*e ) return kFALSE; //30% energy loss is too much!
//cP4 = (1.- e/p2*dE);
+ if ( (1.+ dE/p2*(dE + 2*e)) < 0. ) return kFALSE;
cP4 = 1./TMath::Sqrt(1.+ dE/p2*(dE + 2*e)); //A precise formula by Ruben !
if (TMath::Abs(fP4*cP4)>100.) return kFALSE; //Do not track below 10 MeV/c
// This function corrects the track parameters for the crossed material.
// "xOverX0" - X/X0, the thickness in units of the radiation length.
// "xTimesRho" - is the product length*density (g/cm^2).
+ // It should be passed as negative when propagating tracks
+ // from the intreaction point to the outside of the central barrel.
// "mass" - the mass of this particle (GeV/c^2).
// "anglecorr" - switch for the angular correction
// "Bethe" - function calculating the energy loss (GeV/(g/cm^2))
// using the full Geant-like Bethe-Bloch formula parameterization
// "xOverX0" - X/X0, the thickness in units of the radiation length.
// "xTimesRho" - is the product length*density (g/cm^2).
+ // It should be passed as negative when propagating tracks
+ // from the intreaction point to the outside of the central barrel.
// "mass" - the mass of this particle (GeV/c^2).
// "density" - mean density (g/cm^3)
// "zOverA" - mean Z/A
//
// This function corrects the track parameters for the crossed material
// "d" - the thickness (fraction of the radiation length)
+ // It should be passed as negative when propagating tracks
+ // from the intreaction point to the outside of the central barrel.
// "x0" - the radiation length (g/cm^2)
// "mass" - the mass of this particle (GeV/c^2)
//------------------------------------------------------------------
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;
+ if (TMath::Abs(fP[4])< kAlmost0) return kFALSE;
Double_t &fP0=fP[0], &fP1=fP[1], &fP2=fP[2], &fP3=fP[3], &fP4=fP[4];
Double_t
&fC40=fC[10], &fC41=fC[11], &fC42=fC[12], &fC43=fC[13], &fC44=fC[14];
Double_t r1=TMath::Sqrt((1.-f1)*(1.+f1)), r2=TMath::Sqrt((1.-f2)*(1.+f2));
+ if (TMath::Abs(r1)<kAlmost0) return kFALSE;
+ if (TMath::Abs(r2)<kAlmost0) return kFALSE;
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 dx=xk-fX;
if (TMath::Abs(dx)<=kAlmost0) return kTRUE;
+ if (TMath::Abs(fP[4])<=kAlmost0) return kFALSE;
+ // Do not propagate tracks outside the ALICE detector
+ if (TMath::Abs(dx)>1e5 ||
+ TMath::Abs(GetY())>1e5 ||
+ TMath::Abs(GetZ())>1e5) {
+ AliWarning(Form("Anomalous track, target X:%f",xk));
+ Print();
+ return kFALSE;
+ }
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);