#include "AliKFParticle.h"
#include "TDatabasePDG.h"
#include "TParticlePDG.h"
#include "AliVTrack.h"
#include "AliVVertex.h"
#include "AliExternalTrackParam.h"
ClassImp(AliKFParticle)
Double_t AliKFParticle::fgBz = -5.;
AliKFParticle::AliKFParticle( const AliKFParticle &d1, const AliKFParticle &d2, Bool_t gamma )
{
if (!gamma) {
AliKFParticle mother;
mother+= d1;
mother+= d2;
*this = mother;
} else
ConstructGamma(d1, d2);
}
void AliKFParticle::Create( const Double_t Param[], const Double_t Cov[], Int_t Charge, Int_t PID )
{
Double_t C[21];
for( int i=0; i<21; i++ ) C[i] = Cov[i];
TParticlePDG* particlePDG = TDatabasePDG::Instance()->GetParticle(PID);
Double_t mass = (particlePDG) ? particlePDG->Mass() :0.13957;
AliKFParticleBase::Initialize( Param, C, Charge, mass );
}
void AliKFParticle::Create( const Double_t Param[], const Double_t Cov[], Int_t Charge, Double_t Mass )
{
Double_t C[21];
for( int i=0; i<21; i++ ) C[i] = Cov[i];
AliKFParticleBase::Initialize( Param, C, Charge, Mass );
}
AliKFParticle::AliKFParticle( const AliVTrack &track, Int_t PID )
{
track.GetXYZ(fP);
track.PxPyPz(fP+3);
fQ = track.Charge();
track.GetCovarianceXYZPxPyPz( fC );
Create(fP,fC,fQ,PID);
}
AliKFParticle::AliKFParticle( const AliExternalTrackParam &track, Double_t Mass, Int_t Charge )
{
track.GetXYZ(fP);
track.PxPyPz(fP+3);
fQ = track.Charge()*TMath::Abs(Charge);
fP[3] *= TMath::Abs(Charge);
fP[4] *= TMath::Abs(Charge);
fP[5] *= TMath::Abs(Charge);
Double_t pt=1./TMath::Abs(track.GetParameter()[4]) * TMath::Abs(Charge);
Double_t cs=TMath::Cos(track.GetAlpha()), sn=TMath::Sin(track.GetAlpha());
Double_t r=TMath::Sqrt((1.-track.GetParameter()[2])*(1.+track.GetParameter()[2]));
Double_t m00=-sn, m10=cs;
Double_t m23=-pt*(sn + track.GetParameter()[2]*cs/r), m43=-pt*pt*(r*cs - track.GetParameter()[2]*sn);
Double_t m24= pt*(cs - track.GetParameter()[2]*sn/r), m44=-pt*pt*(r*sn + track.GetParameter()[2]*cs);
Double_t m35=pt, m45=-pt*pt*track.GetParameter()[3];
m43*=track.GetSign();
m44*=track.GetSign();
m45*=track.GetSign();
const Double_t *cTr = track.GetCovariance();
fC[0 ] = cTr[0]*m00*m00;
fC[1 ] = cTr[0]*m00*m10;
fC[2 ] = cTr[0]*m10*m10;
fC[3 ] = cTr[1]*m00;
fC[4 ] = cTr[1]*m10;
fC[5 ] = cTr[2];
fC[6 ] = m00*(cTr[3]*m23 + cTr[10]*m43);
fC[7 ] = m10*(cTr[3]*m23 + cTr[10]*m43);
fC[8 ] = cTr[4]*m23 + cTr[11]*m43;
fC[9 ] = m23*(cTr[5]*m23 + cTr[12]*m43) + m43*(cTr[12]*m23 + cTr[14]*m43);
fC[10] = m00*(cTr[3]*m24 + cTr[10]*m44);
fC[11] = m10*(cTr[3]*m24 + cTr[10]*m44);
fC[12] = cTr[4]*m24 + cTr[11]*m44;
fC[13] = m23*(cTr[5]*m24 + cTr[12]*m44) + m43*(cTr[12]*m24 + cTr[14]*m44);
fC[14] = m24*(cTr[5]*m24 + cTr[12]*m44) + m44*(cTr[12]*m24 + cTr[14]*m44);
fC[15] = m00*(cTr[6]*m35 + cTr[10]*m45);
fC[16] = m10*(cTr[6]*m35 + cTr[10]*m45);
fC[17] = cTr[7]*m35 + cTr[11]*m45;
fC[18] = m23*(cTr[8]*m35 + cTr[12]*m45) + m43*(cTr[13]*m35 + cTr[14]*m45);
fC[19] = m24*(cTr[8]*m35 + cTr[12]*m45) + m44*(cTr[13]*m35 + cTr[14]*m45);
fC[20] = m35*(cTr[9]*m35 + cTr[13]*m45) + m45*(cTr[13]*m35 + cTr[14]*m45);
Create(fP,fC,fQ,Mass);
}
AliKFParticle::AliKFParticle( const AliVVertex &vertex )
{
vertex.GetXYZ( fP );
vertex.GetCovarianceMatrix( fC );
fChi2 = vertex.GetChi2();
fNDF = 2*vertex.GetNContributors() - 3;
fQ = 0;
fAtProductionVertex = 0;
fIsLinearized = 0;
fSFromDecay = 0;
}
void AliKFParticle::GetExternalTrackParam( const AliKFParticleBase &p, Double_t &X, Double_t &Alpha, Double_t P[5] )
{
Double_t cosA = p.GetPx(), sinA = p.GetPy();
Double_t pt = TMath::Sqrt(cosA*cosA + sinA*sinA);
Double_t pti = 0;
if( pt<1.e-4 ){
cosA = 1;
sinA = 0;
} else {
pti = 1./pt;
cosA*=pti;
sinA*=pti;
}
Alpha = TMath::ATan2(sinA,cosA);
X = p.GetX()*cosA + p.GetY()*sinA;
P[0]= p.GetY()*cosA - p.GetX()*sinA;
P[1]= p.GetZ();
P[2]= 0;
P[3]= p.GetPz()*pti;
P[4]= p.GetQ()*pti;
}
Bool_t AliKFParticle::GetDistanceFromVertexXY( const Double_t vtx[], const Double_t Cv[], Double_t &val, Double_t &err ) const
{
Bool_t ret = 0;
Double_t mP[8];
Double_t mC[36];
Transport( GetDStoPoint(vtx), mP, mC );
Double_t dx = mP[0] - vtx[0];
Double_t dy = mP[1] - vtx[1];
Double_t px = mP[3];
Double_t py = mP[4];
Double_t pt = TMath::Sqrt(px*px + py*py);
Double_t ex=0, ey=0;
if( pt<1.e-4 ){
ret = 1;
pt = 1.;
val = 1.e4;
} else{
ex = px/pt;
ey = py/pt;
val = dy*ex - dx*ey;
}
Double_t h0 = -ey;
Double_t h1 = ex;
Double_t h3 = (dy*ey + dx*ex)*ey/pt;
Double_t h4 = -(dy*ey + dx*ex)*ex/pt;
err =
h0*(h0*GetCovariance(0,0) + h1*GetCovariance(0,1) + h3*GetCovariance(0,3) + h4*GetCovariance(0,4) ) +
h1*(h0*GetCovariance(1,0) + h1*GetCovariance(1,1) + h3*GetCovariance(1,3) + h4*GetCovariance(1,4) ) +
h3*(h0*GetCovariance(3,0) + h1*GetCovariance(3,1) + h3*GetCovariance(3,3) + h4*GetCovariance(3,4) ) +
h4*(h0*GetCovariance(4,0) + h1*GetCovariance(4,1) + h3*GetCovariance(4,3) + h4*GetCovariance(4,4) );
if( Cv ){
err+= h0*(h0*Cv[0] + h1*Cv[1] ) + h1*(h0*Cv[1] + h1*Cv[2] );
}
err = TMath::Sqrt(TMath::Abs(err));
return ret;
}
Bool_t AliKFParticle::GetDistanceFromVertexXY( const Double_t vtx[], Double_t &val, Double_t &err ) const
{
return GetDistanceFromVertexXY( vtx, 0, val, err );
}
Bool_t AliKFParticle::GetDistanceFromVertexXY( const AliKFParticle &Vtx, Double_t &val, Double_t &err ) const
{
return GetDistanceFromVertexXY( Vtx.fP, Vtx.fC, val, err );
}
Bool_t AliKFParticle::GetDistanceFromVertexXY( const AliVVertex &Vtx, Double_t &val, Double_t &err ) const
{
return GetDistanceFromVertexXY( AliKFParticle(Vtx), val, err );
}
Double_t AliKFParticle::GetDistanceFromVertexXY( const Double_t vtx[] ) const
{
Double_t val, err;
GetDistanceFromVertexXY( vtx, 0, val, err );
return val;
}
Double_t AliKFParticle::GetDistanceFromVertexXY( const AliKFParticle &Vtx ) const
{
return GetDistanceFromVertexXY( Vtx.fP );
}
Double_t AliKFParticle::GetDistanceFromVertexXY( const AliVVertex &Vtx ) const
{
return GetDistanceFromVertexXY( AliKFParticle(Vtx).fP );
}
Double_t AliKFParticle::GetDistanceFromParticleXY( const AliKFParticle &p ) const
{
Double_t dS, dS1;
GetDStoParticleXY( p, dS, dS1 );
Double_t mP[8], mC[36], mP1[8], mC1[36];
Transport( dS, mP, mC );
p.Transport( dS1, mP1, mC1 );
Double_t dx = mP[0]-mP1[0];
Double_t dy = mP[1]-mP1[1];
return TMath::Sqrt(dx*dx+dy*dy);
}
Double_t AliKFParticle::GetDeviationFromParticleXY( const AliKFParticle &p ) const
{
Double_t dS, dS1;
GetDStoParticleXY( p, dS, dS1 );
Double_t mP1[8], mC1[36];
p.Transport( dS1, mP1, mC1 );
Double_t d[2]={ fP[0]-mP1[0], fP[1]-mP1[1] };
Double_t sigmaS = .1+10.*TMath::Sqrt( (d[0]*d[0]+d[1]*d[1] )/
(mP1[3]*mP1[3]+mP1[4]*mP1[4] ) );
Double_t h[2] = { mP1[3]*sigmaS, mP1[4]*sigmaS };
mC1[0] +=h[0]*h[0];
mC1[1] +=h[1]*h[0];
mC1[2] +=h[1]*h[1];
return GetDeviationFromVertexXY( mP1, mC1 )*TMath::Sqrt(2./1.);
}
Double_t AliKFParticle::GetDeviationFromVertexXY( const Double_t vtx[], const Double_t Cv[] ) const
{
Double_t val, err;
Bool_t problem = GetDistanceFromVertexXY( vtx, Cv, val, err );
if( problem || err<1.e-20 ) return 1.e4;
else return val/err;
}
Double_t AliKFParticle::GetDeviationFromVertexXY( const AliKFParticle &Vtx ) const
{
return GetDeviationFromVertexXY( Vtx.fP, Vtx.fC );
}
Double_t AliKFParticle::GetDeviationFromVertexXY( const AliVVertex &Vtx ) const
{
AliKFParticle v(Vtx);
return GetDeviationFromVertexXY( v.fP, v.fC );
}
Double_t AliKFParticle::GetAngle ( const AliKFParticle &p ) const
{
Double_t dS, dS1;
GetDStoParticle( p, dS, dS1 );
Double_t mP[8], mC[36], mP1[8], mC1[36];
Transport( dS, mP, mC );
p.Transport( dS1, mP1, mC1 );
Double_t n = TMath::Sqrt( mP[3]*mP[3] + mP[4]*mP[4] + mP[5]*mP[5] );
Double_t n1= TMath::Sqrt( mP1[3]*mP1[3] + mP1[4]*mP1[4] + mP1[5]*mP1[5] );
n*=n1;
Double_t a = 0;
if( n>1.e-8 ) a = ( mP[3]*mP1[3] + mP[4]*mP1[4] + mP[5]*mP1[5] )/n;
if (TMath::Abs(a)<1.) a = TMath::ACos(a);
else a = (a>=0) ?0 :TMath::Pi();
return a;
}
Double_t AliKFParticle::GetAngleXY( const AliKFParticle &p ) const
{
Double_t dS, dS1;
GetDStoParticleXY( p, dS, dS1 );
Double_t mP[8], mC[36], mP1[8], mC1[36];
Transport( dS, mP, mC );
p.Transport( dS1, mP1, mC1 );
Double_t n = TMath::Sqrt( mP[3]*mP[3] + mP[4]*mP[4] );
Double_t n1= TMath::Sqrt( mP1[3]*mP1[3] + mP1[4]*mP1[4] );
n*=n1;
Double_t a = 0;
if( n>1.e-8 ) a = ( mP[3]*mP1[3] + mP[4]*mP1[4] )/n;
if (TMath::Abs(a)<1.) a = TMath::ACos(a);
else a = (a>=0) ?0 :TMath::Pi();
return a;
}
Double_t AliKFParticle::GetAngleRZ( const AliKFParticle &p ) const
{
Double_t dS, dS1;
GetDStoParticle( p, dS, dS1 );
Double_t mP[8], mC[36], mP1[8], mC1[36];
Transport( dS, mP, mC );
p.Transport( dS1, mP1, mC1 );
Double_t nr = TMath::Sqrt( mP[3]*mP[3] + mP[4]*mP[4] );
Double_t n1r= TMath::Sqrt( mP1[3]*mP1[3] + mP1[4]*mP1[4] );
Double_t n = TMath::Sqrt( nr*nr + mP[5]*mP[5] );
Double_t n1= TMath::Sqrt( n1r*n1r + mP1[5]*mP1[5] );
n*=n1;
Double_t a = 0;
if( n>1.e-8 ) a = ( nr*n1r +mP[5]*mP1[5])/n;
if (TMath::Abs(a)<1.) a = TMath::ACos(a);
else a = (a>=0) ?0 :TMath::Pi();
return a;
}
Double_t AliKFParticle::GetPseudoProperDecayTime( const AliKFParticle &pV, const Double_t& mass, Double_t* timeErr2 ) const
{
const Double_t ipt2 = 1/( Px()*Px() + Py()*Py() );
const Double_t mipt2 = mass*ipt2;
const Double_t dx = X() - pV.X();
const Double_t dy = Y() - pV.Y();
if ( timeErr2 ) {
const Double_t f0 = Px()*mipt2;
const Double_t f1 = Py()*mipt2;
const Double_t mipt2derivative = mipt2*(1-2*Px()*Px()*ipt2);
const Double_t f2 = dx*mipt2derivative;
const Double_t f3 = -dy*mipt2derivative;
const Double_t f4 = -f0;
const Double_t f5 = -f1;
const Double_t& mC00 = GetCovariance(0,0);
const Double_t& mC10 = GetCovariance(0,1);
const Double_t& mC11 = GetCovariance(1,1);
const Double_t& mC20 = GetCovariance(3,0);
const Double_t& mC21 = GetCovariance(3,1);
const Double_t& mC22 = GetCovariance(3,3);
const Double_t& mC30 = GetCovariance(4,0);
const Double_t& mC31 = GetCovariance(4,1);
const Double_t& mC32 = GetCovariance(4,3);
const Double_t& mC33 = GetCovariance(4,4);
const Double_t& mC44 = pV.GetCovariance(0,0);
const Double_t& mC54 = pV.GetCovariance(1,0);
const Double_t& mC55 = pV.GetCovariance(1,1);
*timeErr2 =
f5*mC55*f5 +
f5*mC54*f4 +
f4*mC44*f4 +
f3*mC33*f3 +
f3*mC32*f2 +
f3*mC31*f1 +
f3*mC30*f0 +
f2*mC22*f2 +
f2*mC21*f1 +
f2*mC20*f0 +
f1*mC11*f1 +
f1*mC10*f0 +
f0*mC00*f0;
}
return ( dx*Px() + dy*Py() )*mipt2;
}