// trec.SetBeginPoint(begin);
// trec.SetEndPoint(end);
//
-// Note : All quantities are in GeV, GeV/c or GeV/c**2
+// Note : By default all quantities are in GeV, GeV/c or GeV/c**2
+// but the user can indicate the usage of a different scale
+// for the energy-momentum units via the SetEscale() memberfunction.
+// The actual energy-momentum unit scale can be obtained via the
+// GetEscale() memberfunction.
//
//--- Author: Nick van Eijndhoven 10-jul-1997 UU-SAP Utrecht
//- Modified: NvE $Date$ UU-SAP Utrecht
fClosest=0;
fParent=0;
fFit=0;
+ fTstamp=0;
+ fEscale=1;
}
///////////////////////////////////////////////////////////////////////////
AliTrack::~AliTrack()
{
// Destructor to delete memory allocated for decay tracks array.
-// This destructor automatically cleares the pointer of this AliTrack
-// from all the link slots of the related AliSignal objects.
-
+// This destructor automatically cleares all references to this AliTrack
+// from all the related AliSignal objects.
Int_t nsig=GetNsignals();
for (Int_t i=1; i<=nsig; i++)
{
AliSignal* s=GetSignal(i);
- if (s) s->ResetLinks(this);
+ if (s) s->RemoveTrack(*this,0);
}
if (fDecays)
}
if (fSignals)
{
- fSignals->Clear();
delete fSignals;
fSignals=0;
}
delete fFit;
fFit=0;
}
+ if (fTstamp)
+ {
+ delete fTstamp;
+ fTstamp=0;
+ }
}
///////////////////////////////////////////////////////////////////////////
AliTrack::AliTrack(const AliTrack& t) : TNamed(t),Ali4Vector(t)
if (t.fImpactYZ) fImpactYZ=new AliPositionObj(*(t.fImpactYZ));
if (t.fClosest) fClosest=new AliPositionObj(*(t.fClosest));
if (t.fFit) fFit=t.fFit->Clone();
+ if (t.fTstamp) fTstamp=new AliTimestamp(*(t.fTstamp));
fUserId=t.fUserId;
- fChi2=t.fChi2;
- fNdf=t.fNdf;
+ fEscale=t.fEscale;
fCode=t.fCode;
fParent=t.fParent;
void AliTrack::Reset()
{
// Reset all variables to 0 and delete all auto-generated decay tracks.
+// Note : The scale for the energy/momentum units will not be changed.
fQ=0;
- fChi2=0;
- fNdf=0;
fUserId=0;
fCode=0;
fProb=0;
}
if (fSignals)
{
- fSignals->Clear();
delete fSignals;
fSignals=0;
}
delete fFit;
fFit=0;
}
+ if (fTstamp)
+ {
+ delete fTstamp;
+ fTstamp=0;
+ }
}
///////////////////////////////////////////////////////////////////////////
void AliTrack::Set3Momentum(Ali3Vector& p)
fQ=q;
}
///////////////////////////////////////////////////////////////////////////
-void AliTrack::Data(TString f)
+void AliTrack::Data(TString f,TString u)
{
// Provide track information within the coordinate frame f
+//
+// The string argument "u" allows to choose between different angular units
+// in case e.g. a spherical frame is selected.
+// u = "rad" : angles provided in radians
+// "deg" : angles provided in degrees
+//
+// The defaults are f="car" and u="rad".
+
Double_t m=GetMass();
Double_t dm=GetResultError();
const char* name=GetName();
if (strlen(name)) cout << " Name : " << name;
if (strlen(title)) cout << " Title : " << title;
cout << endl;
+ if (fTstamp) fTstamp->Date(1);
cout << " Id : " << fUserId << " Code : " << fCode
<< " m : " << m << " dm : " << dm << " Charge : " << fQ
<< " p : " << GetMomentum() << endl;
cout << " Nhypotheses : " << GetNhypotheses() << " Ndecay-tracks : " << GetNdecay()
- << " Nsignals : " << GetNsignals() << endl;
+ << " Nsignals : " << GetNsignals() << " Energy scale : " << fEscale << " GeV" << endl;
if (fParent)
{
cout << " Parent track Id : " << fParent->GetId() << " Code : " << fParent->GetParticleCode()
cout << " Fit details present in object of class " << fFit->ClassName() << endl;
if (fFit->InheritsFrom("AliSignal")) ((AliSignal*)fFit)->List(-1);
}
- Ali4Vector::Data(f);
+ Ali4Vector::Data(f,u);
}
///////////////////////////////////////////////////////////////////////////
-void AliTrack::List(TString f)
+void AliTrack::List(TString f,TString u)
{
// Provide current track and decay level 1 information within coordinate frame f
+//
+// The string argument "u" allows to choose between different angular units
+// in case e.g. a spherical frame is selected.
+// u = "rad" : angles provided in radians
+// "deg" : angles provided in degrees
+//
+// The defaults are f="car" and u="rad".
- Data(f); // Information of the current track
+ Data(f,u); // Information of the current track
+ if (fBegin) { cout << " Begin-point :"; fBegin->Data(f,u); }
+ if (fEnd) { cout << " End-point :"; fEnd->Data(f,u); }
+ if (fRef) { cout << " Ref-point :"; fRef->Data(f,u); }
// Decay products of this track
AliTrack* td;
if (td)
{
cout << " ---Level 1 sec. track no. " << id << endl;
- td->Data(f);
+ td->Data(f,u);
}
else
{
}
}
///////////////////////////////////////////////////////////////////////////
-void AliTrack::ListAll(TString f)
+void AliTrack::ListAll(TString f,TString u)
{
// Provide complete track and decay information within the coordinate frame f
+//
+// The string argument "u" allows to choose between different angular units
+// in case e.g. a spherical frame is selected.
+// u = "rad" : angles provided in radians
+// "deg" : angles provided in degrees
+//
+// The defaults are f="car" and u="rad".
- Data(f); // Information of the current track
- if (fBegin) { cout << " Begin-point :"; fBegin->Data(f); }
- if (fEnd) { cout << " End-point :"; fEnd->Data(f); }
- if (fRef) { cout << " Ref-point :"; fRef->Data(f); }
+ Data(f,u); // Information of the current track
+ if (fBegin) { cout << " Begin-point :"; fBegin->Data(f,u); }
+ if (fEnd) { cout << " End-point :"; fEnd->Data(f,u); }
+ if (fRef) { cout << " Ref-point :"; fRef->Data(f,u); }
Int_t nhyp=GetNhypotheses();
if (nhyp)
for (Int_t ih=1; ih<=nhyp; ih++)
{
AliTrack* tx=GetTrackHypothesis(ih);
- if (tx) tx->Data(f);
+ if (tx) tx->Data(f,u);
}
}
}
r=sx->GetPosition();
cout << " Position";
- r.Data(f);
+ r.Data(f,u);
}
}
}
AliTrack* t=this;
- Dumps(t,1,f); // Information of all decay products
+ Dumps(t,1,f,u); // Information of all decay products
}
//////////////////////////////////////////////////////////////////////////
-void AliTrack::Dumps(AliTrack* t,Int_t n,TString f)
+void AliTrack::Dumps(AliTrack* t,Int_t n,TString f,TString u)
{
// Recursively provide the info of all decay levels of this track
AliTrack* td;
if (td)
{
cout << " ---Level " << n << " sec. track no. " << id << endl;
- td->Data(f);
+ td->Data(f,u);
Int_t nhyp=td->GetNhypotheses();
if (nhyp)
for (Int_t ih=1; ih<=nhyp; ih++)
{
AliTrack* tx=td->GetTrackHypothesis(ih);
- if (tx) tx->Data(f);
+ if (tx) tx->Data(f,u);
}
}
for (Int_t is=1; is<=nsig; is++)
{
AliSignal* sx=td->GetSignal(is);
- if (sx) sx->Data(f);
+ if (sx) sx->Data(f,u);
}
}
// Go for next decay level of this decay track recursively
- Dumps(td,n+1,f);
+ Dumps(td,n+1,f,u);
}
else
{
}
}
//////////////////////////////////////////////////////////////////////////
-Double_t AliTrack::GetMomentum()
+Double_t AliTrack::GetMomentum(Float_t scale)
{
// Provide the value of the track 3-momentum.
+// By default the momentum is returned in the units as it was stored in the track
+// structure. However, the user can select a different momentum unit scale by
+// specification of the scale parameter.
+// The convention is that scale=1 corresponds to GeV/c, so specification
+// of scale=0.001 will provide the momentum in MeV/c.
// The error can be obtained by invoking GetResultError() after
// invokation of GetMomentum().
+
Double_t norm=fV.GetNorm();
fDresult=fV.GetResultError();
+ if (scale>0)
+ {
+ norm*=fEscale/scale;
+ fDresult*=fEscale/scale;
+ }
return norm;
}
///////////////////////////////////////////////////////////////////////////
-Ali3Vector AliTrack::Get3Momentum() const
+Ali3Vector AliTrack::Get3Momentum(Float_t scale) const
{
-// Provide the track 3-momentum
- return (Ali3Vector)Get3Vector();
+// Provide the track 3-momentum.
+// By default the components of the 3-momentum are returned in the units
+// as they were stored in the track structure.
+// However, the user can select a different momentum unit scale for the
+// components by specification of the scale parameter.
+// The convention is that scale=1 corresponds to GeV/c, so specification
+// of scale=0.001 will provide the 3-momentum in MeV/c.
+
+ Ali3Vector p=Get3Vector();
+ if (scale>0) p*=fEscale/scale;
+ return p;
}
///////////////////////////////////////////////////////////////////////////
-Double_t AliTrack::GetMass()
+Double_t AliTrack::GetMass(Float_t scale)
{
// Provide the particle mass.
+// By default the mass is returned in the units as it was stored in the track
+// structure. However, the user can select a different mass unit scale by
+// specification of the scale parameter.
+// The convention is that scale=1 corresponds to GeV/c**2, so specification
+// of scale=0.001 will provide the mass in MeV/c**2.
// The error can be obtained by invoking GetResultError() after
// invokation of GetMass().
+
Double_t inv=GetInvariant();
Double_t dinv=GetResultError();
Double_t dm=0;
{
Double_t m=sqrt(inv);
if (m) dm=dinv/(2.*m);
+ if (scale>0)
+ {
+ m*=fEscale/scale;
+ dm*=fEscale/scale;
+ }
fDresult=dm;
return m;
}
return fQ;
}
///////////////////////////////////////////////////////////////////////////
-Double_t AliTrack::GetEnergy()
+Double_t AliTrack::GetEnergy(Float_t scale)
{
// Provide the particle's energy.
+// By default the energy is returned in the units as it was stored in the track
+// structure. However, the user can select a different energy unit scale by
+// specification of the scale parameter.
+// The convention is that scale=1 corresponds to GeV, so specification
+// of scale=0.001 will provide the energy in MeV.
// The error can be obtained by invoking GetResultError() after
// invokation of GetEnergy().
Double_t E=GetScalar();
if (E>0)
{
+ if (scale>0)
+ {
+ E*=fEscale/scale;
+ fDresult*=fEscale/scale;
+ }
return E;
}
else
}
}
///////////////////////////////////////////////////////////////////////////
-void AliTrack::AddSignal(AliSignal& s)
+void AliTrack::AddSignal(AliSignal& s,Int_t mode)
{
// Relate an AliSignal object to this track.
+//
+// mode = 0 : Only the reference to the specified signal is stored in
+// the current track, without storing the (backward) reference
+// to this track into the AliSignal structure.
+// 1 : The (backward) reference to the current track is also automatically
+// stored into the AliSignal (or derived) object specified in the
+// input argument.
+//
+// The default is mode=0.
+
if (!fSignals) fSignals=new TObjArray(1);
// Check if this signal is already stored for this track
}
fSignals->Add(&s);
+ if (mode==1) s.AddTrack(*this,0);
}
///////////////////////////////////////////////////////////////////////////
-void AliTrack::RemoveSignal(AliSignal& s)
+void AliTrack::RemoveSignal(AliSignal& s,Int_t mode)
{
// Remove related AliSignal object from this track.
+//
+// mode = 0 : Only the reference to the specified signal is removed from
+// the current track, without removing the (backward) reference(s)
+// to this track from the AliSignal structure.
+// 1 : The (backward) reference(s) to the current track are also automatically
+// removed from the AliSignal (or derived) object specified in the
+// input argument.
+//
+// The default is mode=1.
+
if (fSignals)
{
AliSignal* test=(AliSignal*)fSignals->Remove(&s);
if (test) fSignals->Compress();
}
+ if (mode==1) s.RemoveTrack(*this,0);
}
///////////////////////////////////////////////////////////////////////////
-void AliTrack::RemoveSignals()
+void AliTrack::RemoveSignals(Int_t mode)
{
// Remove all related AliSignal objects from this track.
- if (fSignals)
+//
+// mode = 0 : All signal references are removed from the current track,
+// without removing the (backward) references to this track from
+// the corresponding AliSignal objects.
+// 1 : The (backward) references to the current track are also automatically
+// removed from the corresponding AliSignal (or derived) objects.
+//
+// The default is mode=1.
+
+ if (!fSignals) return;
+
+ Int_t ns=GetNsignals();
+ for (Int_t i=0; i<ns; i++)
{
- fSignals->Clear();
- delete fSignals;
- fSignals=0;
+ AliSignal* sx=(AliSignal*)fSignals->At(i);
+ if (sx && mode==1) sx->RemoveTrack(*this,0);
}
+
+ delete fSignals;
+ fSignals=0;
}
///////////////////////////////////////////////////////////////////////////
Int_t AliTrack::GetNsignals() const
return nsig;
}
///////////////////////////////////////////////////////////////////////////
+Int_t AliTrack::GetNsignals(const char* classname) const
+{
+// Provide the number of stored signals of the specified class.
+
+ Int_t nsigs=0;
+ for (Int_t isig=1; isig<=GetNsignals(); isig++)
+ {
+ TObject* obj=GetSignal(isig);
+ if (!obj) continue;
+
+ if (obj->InheritsFrom(classname)) nsigs++;
+ }
+ return nsigs;
+}
+///////////////////////////////////////////////////////////////////////////
AliSignal* AliTrack::GetSignal(Int_t j) const
{
// Provide the related AliSignal number j.
void AliTrack::SetBeginPoint(AliPosition& p)
{
// Store the position of the track begin-point.
- if (!fBegin)
- {
- fBegin=new AliPositionObj(p);
- }
- else
- {
- fBegin->Load(p);
- }
+ if (fBegin) delete fBegin;
+ fBegin=new AliPositionObj(p);
}
///////////////////////////////////////////////////////////////////////////
AliPosition* AliTrack::GetBeginPoint()
void AliTrack::SetEndPoint(AliPosition& p)
{
// Store the position of the track end-point.
- if (!fEnd)
- {
- fEnd=new AliPositionObj(p);
- }
- else
- {
- fEnd->Load(p);
- }
+ if (fEnd) delete fEnd;
+ fEnd=new AliPositionObj(p);
}
///////////////////////////////////////////////////////////////////////////
AliPosition* AliTrack::GetEndPoint()
// 3-momentum vector components have been defined.
// This reference point is the preferable point to start track extrapolations
// etc... which are sensitive to the components of the 3-momentum vector.
- if (!fRef)
- {
- fRef=new AliPositionObj(p);
- }
- else
- {
- fRef->Load(p);
- }
+ if (fRef) delete fRef;
+ fRef=new AliPositionObj(p);
}
///////////////////////////////////////////////////////////////////////////
AliPosition* AliTrack::GetReferencePoint()
}
}
///////////////////////////////////////////////////////////////////////////
-Double_t AliTrack::GetPt()
+Double_t AliTrack::GetPt(Float_t scale)
{
-// Provide trans. momentum value w.r.t. z-axis.
+// Provide the transverse momentum value w.r.t. z-axis.
+// By default the value is returned in the units as it was stored in the track
+// structure. However, the user can select a different momentum unit scale by
+// specification of the scale parameter.
+// The convention is that scale=1 corresponds to GeV/c, so specification
+// of scale=0.001 will provide the transverse momentum in MeV/c.
// The error on the value can be obtained by GetResultError()
// after invokation of GetPt().
Ali3Vector v;
v=GetVecTrans();
Double_t norm=v.GetNorm();
fDresult=v.GetResultError();
+ if (scale>0)
+ {
+ norm*=fEscale/scale;
+ fDresult*=fEscale/scale;
+ }
return norm;
}
///////////////////////////////////////////////////////////////////////////
-Double_t AliTrack::GetPl()
+Double_t AliTrack::GetPl(Float_t scale)
{
-// Provide long. momentum value w.r.t. z-axis.
+// Provide the longitudinal momentum value w.r.t. z-axis.
+// By default the value is returned in the units as it was stored in the track
+// structure. However, the user can select a different momentum unit scale by
+// specification of the scale parameter.
+// The convention is that scale=1 corresponds to GeV/c, so specification
+// of scale=0.001 will provide the longitudinal momentum in MeV/c.
// Note : the returned value can also be negative.
// The error on the value can be obtained by GetResultError()
// after invokation of GetPl().
+
Ali3Vector v;
v=GetVecLong();
Double_t a[3];
v.GetVector(a,"sph");
if (cos(a[1])<0) pl=-pl;
+ if (scale>0)
+ {
+ pl*=fEscale/scale;
+ fDresult*=fEscale/scale;
+ }
return pl;
}
///////////////////////////////////////////////////////////////////////////
-Double_t AliTrack::GetEt()
+Double_t AliTrack::GetEt(Float_t scale)
{
-// Provide trans. energy value w.r.t. z-axis.
+// Provide transverse energy value w.r.t. z-axis.
+// By default the value is returned in the units as it was stored in the track
+// structure. However, the user can select a different energy unit scale by
+// specification of the scale parameter.
+// The convention is that scale=1 corresponds to GeV, so specification
+// of scale=0.001 will provide the transverse energy in MeV.
// The error on the value can be obtained by GetResultError()
// after invokation of GetEt().
+
Double_t et=GetScaTrans();
+ if (scale>0)
+ {
+ et*=fEscale/scale;
+ fDresult*=fEscale/scale;
+ }
return et;
}
///////////////////////////////////////////////////////////////////////////
-Double_t AliTrack::GetEl()
+Double_t AliTrack::GetEl(Float_t scale)
{
-// Provide long. energy value w.r.t. z-axis.
+// Provide longitudinal energy value w.r.t. z-axis.
+// By default the value is returned in the units as it was stored in the track
+// structure. However, the user can select a different energy unit scale by
+// specification of the scale parameter.
+// The convention is that scale=1 corresponds to GeV, so specification
+// of scale=0.001 will provide the longitudinal energy in MeV.
// Note : the returned value can also be negative.
// The error on the value can be obtained by GetResultError()
// after invokation of GetEl().
+
Double_t el=GetScaLong();
+ if (scale>0)
+ {
+ el*=fEscale/scale;
+ fDresult*=fEscale/scale;
+ }
return el;
}
///////////////////////////////////////////////////////////////////////////
-Double_t AliTrack::GetMt()
+Double_t AliTrack::GetMt(Float_t scale)
{
// Provide transverse mass value w.r.t. z-axis.
+// By default the value is returned in the units as it was stored in the track
+// structure. However, the user can select a different energy unit scale by
+// specification of the scale parameter.
+// The convention is that scale=1 corresponds to GeV, so specification
+// of scale=0.001 will provide the transverse mass in MeV.
// The error on the value can be obtained by GetResultError()
// after invokation of GetMt().
Double_t pt=GetPt();
if (mt) dmt2=(pow((pt*dpt),2)+pow((m*dm),2))/(mt*mt);
fDresult=sqrt(dmt2);
+ if (scale>0)
+ {
+ mt*=fEscale/scale;
+ fDresult*=fEscale/scale;
+ }
return mt;
}
///////////////////////////////////////////////////////////////////////////
switch (axis)
{
case 1: // Impact-point in the plane X=0
- if (!fImpactYZ)
- {
- fImpactYZ=new AliPositionObj(p);
- }
- else
- {
- fImpactYZ->Load(p);
- }
+ if (fImpactYZ) delete fImpactYZ;
+ fImpactYZ=new AliPositionObj(p);
break;
case 2: // Impact-point in the plane Y=0
- if (!fImpactXZ)
- {
- fImpactXZ=new AliPositionObj(p);
- }
- else
- {
- fImpactXZ->Load(p);
- }
+ if (fImpactXZ) delete fImpactXZ;
+ fImpactXZ=new AliPositionObj(p);
break;
case 3: // Impact-point in the plane Z=0
- if (!fImpactXY)
- {
- fImpactXY=new AliPositionObj(p);
- }
- else
- {
- fImpactXY->Load(p);
- }
+ if (fImpactXY) delete fImpactXY;
+ fImpactXY=new AliPositionObj(p);
break;
default: // Unsupported axis
void AliTrack::SetClosestPoint(AliPosition& p)
{
// Set position p as the point of closest approach w.r.t. some reference
- if (!fClosest)
- {
- fClosest=new AliPositionObj(p);
- }
- else
- {
- fClosest->Load(p);
- }
+ if (fClosest) delete fClosest;
+ fClosest=new AliPositionObj(p);
}
///////////////////////////////////////////////////////////////////////////
AliPosition* AliTrack::GetClosestPoint()
return fClosest;
}
///////////////////////////////////////////////////////////////////////////
-void AliTrack::SetChi2(Float_t chi2)
+void AliTrack::SetEscale(Float_t scale)
{
-// Set the chi-squared value of the track fit.
- if (chi2<0)
- {
- cout << " *AliTrack::SetChi2* Invalid chi2 value : " << chi2 << endl;
- }
- else
- {
- fChi2=chi2;
- }
-}
-///////////////////////////////////////////////////////////////////////////
-void AliTrack::SetNdf(Int_t ndf)
-{
-// Set the number of degrees of freedom for the track fit.
- if (ndf<0)
+// Indicate the energy/momentum scale as used by the user.
+// The convention is that scale=1 indicates values in units
+// of GeV, GeV/c or GeV/c**2.
+// So, in case one decides to store values in units of MeV, MeV/c or MeV/c**2
+// the scale indicator should be set to scale=0.001.
+//
+// By default scale=1 is set in the constructor.
+
+ if (scale>0)
{
- cout << " *AliTrack::SetNdf* Invalid ndf value : " << ndf << endl;
+ fEscale=scale;
}
else
{
- fNdf=ndf;
+ cout << " *AliTrack::SetEscale* Invalid scale value : " << scale << endl;
}
}
///////////////////////////////////////////////////////////////////////////
-Float_t AliTrack::GetChi2() const
+Float_t AliTrack::GetEscale() const
{
-// Provide the chi-squared value of the track fit.
- return fChi2;
-}
-///////////////////////////////////////////////////////////////////////////
-Int_t AliTrack::GetNdf() const
-{
-// Provide the number of degrees of freedom for the track fit.
- return fNdf;
+// Provide the energy/momentum scale as used by the user.
+// The convention is that scale=1 indicates values in units
+// of GeV, GeV/c or GeV/c**2.
+// So, a value of scale=0.001 indicates that energy/momentum values are
+// stored in units of MeV, MeV/c or MeV/c**2.
+ return fEscale;
}
///////////////////////////////////////////////////////////////////////////
void AliTrack::SetParticleCode(Int_t code)
return fFit;
}
///////////////////////////////////////////////////////////////////////////
+void AliTrack::SetTimestamp(AliTimestamp& t)
+{
+// Store the timestamp for this track.
+ if (fTstamp) delete fTstamp;
+ fTstamp=new AliTimestamp(t);
+}
+///////////////////////////////////////////////////////////////////////////
+AliTimestamp* AliTrack::GetTimestamp()
+{
+// Provide the timestamp of this track.
+ return fTstamp;
+}
+///////////////////////////////////////////////////////////////////////////
+void AliTrack::RemoveTimestamp()
+{
+// Remove the timestamp from this track.
+ if (fTstamp)
+ {
+ delete fTstamp;
+ fTstamp=0;
+ }
+}
+///////////////////////////////////////////////////////////////////////////
+Double_t AliTrack::GetDistance(AliPosition* p,Float_t scale)
+{
+// Provide distance of the current track to the position p.
+// The error on the result can be obtained as usual by invoking
+// GetResultError() afterwards.
+//
+// By default the distance will be provided in the metric unit scale of
+// the AliPosition p.
+// However, the user can select a different metric unit scale by
+// specification of the scale parameter.
+// The convention is that scale=1 corresponds to meter, so specification
+// of scale=0.01 will provide the distance in cm.
+// As such it is possible to obtain a correctly computed distance even in case
+// the track parameters have a different unit scale.
+// However, it is recommended to work always with one single unit scale.
+//
+// Note : In case of incomplete information, a distance value of -1 is
+// returned.
+
+ Double_t dist=-1.;
+ fDresult=0.;
+
+ if (!p) return dist;
+
+ // Obtain a defined position on this track
+ AliPosition* rx=fRef;
+ if (!rx) rx=fBegin;
+ if (!rx) rx=fEnd;
+
+ if (!rx) return dist;
+
+ Ali3Vector p1=Get3Momentum();
+
+ if (p1.GetNorm() <= 0.) return dist;
+
+ Ali3Vector r0=(Ali3Vector)(*rx);
+
+ Float_t tscale=rx->GetUnitScale();
+ Float_t pscale=p->GetUnitScale();
+ if ((tscale/pscale > 1.1) || (pscale/tscale > 1.1)) r0=r0*(tscale/pscale);
+
+ // Obtain the direction unit vector of this track
+ Double_t vec[3];
+ Double_t err[3];
+ p1.GetVector(vec,"sph");
+ p1.GetErrors(err,"sph");
+ vec[0]=1.;
+ err[0]=0.;
+ p1.SetVector(vec,"sph");
+ p1.SetErrors(err,"sph");
+
+ Ali3Vector q=(Ali3Vector)(*p);
+ Ali3Vector r=q-r0;
+ Ali3Vector d=r.Cross(p1);
+ dist=d.GetNorm();
+ fDresult=d.GetResultError();
+ if (scale>0)
+ {
+ dist*=pscale/scale;
+ fDresult*=pscale/scale;
+ }
+ return dist;
+}
+///////////////////////////////////////////////////////////////////////////
+Double_t AliTrack::GetDistance(AliTrack* t,Float_t scale)
+{
+// Provide distance of the current track to the track t.
+// The error on the result can be obtained as usual by invoking
+// GetResultError() afterwards.
+//
+// By default the distance will be provided in the metric unit scale of
+// the current track.
+// This implies that the results of t1.GetDistance(t2) and t2.GetDistance(t1)
+// may be numerically different in case t1 and t2 have different metric units.
+// However, the user can specify a required metric unit scale by specification
+// of the scale parameter.
+// The convention is that scale=1 corresponds to meter, so specification
+// of scale=0.01 will provide the distance in cm.
+// As such it is possible to obtain a correctly computed distance even in case
+// the track parameters have a different unit scale.
+// However, it is recommended to work always with one single unit scale.
+//
+// Note : In case of incomplete information, a distance value of -1 is
+// returned.
+
+ Double_t dist=-1.;
+ fDresult=0.;
+
+ if (!t) return dist;
+
+ // Obtain a defined position on this track
+ AliPosition* rx=fRef;
+ if (!rx) rx=fBegin;
+ if (!rx) rx=fEnd;
+
+ if (!rx) return dist;
+
+ // Obtain a defined position on track t
+ AliPosition* ry=t->GetReferencePoint();
+ if (!ry) ry=t->GetBeginPoint();
+ if (!ry) ry=t->GetEndPoint();
+
+ if (!ry) return dist;
+
+ Ali3Vector p1=Get3Momentum();
+ Ali3Vector p2=t->Get3Momentum();
+
+ if (p1.GetNorm() <= 0. || p2.GetNorm() <= 0.) return dist;
+
+ // The vector normal to both track directions
+ Ali3Vector n=p1.Cross(p2);
+
+ Float_t scalex=rx->GetUnitScale();
+ Float_t scaley=ry->GetUnitScale();
+
+ if (n.GetNorm() > 1.e-10)
+ {
+ // Normalise n to a unit vector
+ Double_t vec[3];
+ Double_t err[3];
+ n.GetVector(vec,"sph");
+ n.GetErrors(err,"sph");
+ vec[0]=1.;
+ err[0]=0.;
+ n.SetVector(vec,"sph");
+ n.SetErrors(err,"sph");
+ Ali3Vector r1=(Ali3Vector)(*rx);
+ Ali3Vector r2=(Ali3Vector)(*ry);
+ // Correct components of r2 in case of different unit scales
+ if ((scaley/scalex > 1.1) || (scalex/scaley > 1.1)) r2=r2*(scaley/scalex);
+ Ali3Vector r=r1-r2;
+ dist=fabs(r.Dot(n));
+ fDresult=r.GetResultError();
+ }
+ else // Parallel tracks
+ {
+ dist=t->GetDistance(rx);
+ fDresult=t->GetResultError();
+ }
+
+ if (scale>0)
+ {
+ dist*=scalex/scale;
+ fDresult*=scalex/scale;
+ }
+ return dist;
+}
+///////////////////////////////////////////////////////////////////////////
TObject* AliTrack::Clone(const char* name) const
{
// Make a deep copy of the current object and provide the pointer to the copy.