// This class is meant to provide a means to display and extrapolate
// AliTrack objects in the presence of a constant homogeneous magnetic field.
//
+// For track/event displays the line width, colour etc... can be set using the
+// standard facilities (see TAttLine).
+// By default the linewith is set to 2 and the colour set to -1 in the constructor.
+// The latter results in an automatic colour coding according to the track charge
+// with the convention positive=red neutral=green negative=blue.
+//
+// To indicate the track starting point, the memberfunction SetMarker()
+// may be used.
+// By default no marker will be displayed.
+//
// Examples :
// ==========
//
//- Modified: NvE $Date$ Utrecht University
///////////////////////////////////////////////////////////////////////////
+#include <cstdlib>
#include "AliHelix.h"
#include "Riostream.h"
fCurves=0;
fExt=0;
fTofmax=1e-8;
+ fMstyle=-1;
+ fMsize=0;
+ fMcol=0;
+ fEnduse=1;
+
+ fLineWidth=2;
+ fLineColor=-1;
}
///////////////////////////////////////////////////////////////////////////
AliHelix::~AliHelix()
// Copy constructor
fB=h.fB;
fRefresh=h.fRefresh;
+ fTofmax=h.fTofmax;
+ fMstyle=h.fMstyle;
+ fMsize=h.fMsize;
+ fMcol=h.fMcol;
+ fEnduse=h.fEnduse;
}
///////////////////////////////////////////////////////////////////////////
void AliHelix::SetB(Ali3Vector& b)
return fTofmax;
}
///////////////////////////////////////////////////////////////////////////
+void AliHelix::SetMarker(Int_t style,Float_t size,Int_t col)
+{
+// Specify the marker (style, size and colour) to indicate the starting point
+// of a track in a display.
+// In case col<0 the marker will have the same color as the track itself.
+//
+// Defaults are style=8, size=0.2 and col=-1.
+
+ fMstyle=style;
+ fMsize=size;
+ fMcol=col;
+}
+///////////////////////////////////////////////////////////////////////////
+void AliHelix::UseEndPoint(Int_t mode)
+{
+// Select usage of track endpoint in drawing and extrapolation.
+// This allows correct event displays even for very long tracks.
+//
+// mode = 0 : Do not use the track endpoint
+// 1 : Use the track endpoint
+//
+// The default value is mode=1 (which is also set in the constructor).
+
+ if (mode==0 || mode==1) fEnduse=mode;
+}
+///////////////////////////////////////////////////////////////////////////
void AliHelix::MakeCurve(AliTrack* t,Double_t* range,Int_t iaxis,Double_t scale)
{
// Make the helix curve for the specified AliTrack.
// In case one wants to display or extrapolate an AliTrack it is preferable
// to use the Display() or Extrapolate() memberfunctions.
// It is assumed that the track charge is stored in elementary units
-// (i.e. charge=1 for a proton) and that the track energy is stored in GeV.
+// (i.e. charge=1 for a proton).
// The input argument "scale" specifies the unit scale for the various
// locations where scale=0.01 indicates unit scales in cm etc...
// In case scale<=0, the unit scale for locations is determined from the
// begin, reference or endpoint of the track. If neither of these
-// positions is present, all locations are assumed to be given in cm.
+// positions is present, all locations are assumed to be given in meter.
// The lower and upper bounds for the range are specified by range[0] and
// range[1] and the argument "iaxis" indicates along which axis this range
// is specified.
if (!t || (range && !iaxis)) return;
- Double_t energy=t->GetEnergy();
+ Double_t energy=t->GetEnergy(1); // Track energy in GeV
Double_t betanorm=t->GetBeta();
if (energy<=0 || betanorm<=0) return;
AliPosition* rbeg=t->GetBeginPoint();
- AliPosition* rend=t->GetEndPoint();
+ AliPosition* rend=0;
+ if (fEnduse) rend=t->GetEndPoint();
AliPosition* rref=t->GetReferencePoint();
// Magnetic field vector or default Z-direction
// The unit scale for locations if not specified by the user
if (scale<=0)
{
- scale=0.01; // Set default to cm
+ scale=1; // Set default to meter
if (rbeg)
{
scale=rbeg->GetUnitScale();
Double_t betavec[3];
if (iaxis>0) beta.GetVector(betavec,"car");
if (iaxis<0) betaprim.GetVector(betavec,"car");
- if (TMath::Abs(betavec[TMath::Abs(iaxis)-1])/betanorm<1e-10) return;
+ if (fabs(betavec[abs(iaxis)-1])/betanorm<1e-10) return;
}
// The LAB location in which the velocity of the particle is defined
Double_t loc[3]={0,0,0};
- Ali3Vector* rx=0;
- Double_t scalex=0;
+ Ali3Vector rx;
+ Double_t scalex=-1;
if (rref)
{
- rx=(Ali3Vector*)rref;
+ rx=(Ali3Vector)(*rref);
scalex=rref->GetUnitScale();
}
else if (rbeg)
{
- rx=(Ali3Vector*)rbeg;
+ rx=(Ali3Vector)(*rbeg);
scalex=rbeg->GetUnitScale();
}
else if (rend)
{
- rx=(Ali3Vector*)rend;
+ rx=(Ali3Vector)(*rend);
scalex=rend->GetUnitScale();
}
- if (rx)
- {
- if (scalex/scale>1.1 || scale/scalex>1.1) (*rx)*=scalex/scale;
- rx->GetVector(loc,"car");
- }
+ if (scalex>0 && (scalex/scale>1.1 || scale/scalex>1.1)) rx*=scalex/scale;
+ rx.GetVector(loc,"car");
// Initialisation of Helix kinematics
SetHelix(loc,vel,w,0,kUnchanged,bvec);
Int_t bend=0;
- if (TMath::Abs(w)>0 && TMath::Abs(fVt)>0) bend=1;
+ if (fabs(w)>0 && fabs(fVt)>0) bend=1;
// Flight time boundaries.
// The time origin t=0 is chosen to indicate the position in which
Double_t vec2[3]={0,0,0};
Ali3Vector r1;
Ali3Vector r2;
- Double_t scale1=0.01;
- Double_t scale2=0.01;
+ Double_t scale1=1;
+ Double_t scale2=1;
if (!bend)
{
loc[0]=fX0;
loc[1]=fY0;
loc[2]=fZ0;
- tmin=(range[0]-loc[TMath::Abs(iaxis)-1])/velprim[TMath::Abs(iaxis)-1];
- tmax=(range[1]-loc[TMath::Abs(iaxis)-1])/velprim[TMath::Abs(iaxis)-1];
+ tmin=(range[0]-loc[abs(iaxis)-1])/velprim[abs(iaxis)-1];
+ tmax=(range[1]-loc[abs(iaxis)-1])/velprim[abs(iaxis)-1];
}
if (tmax<tmin)
{
// generated in view of accuracy in the case of extrapolations.
tof=tmax-tmin;
v=beta*c;
- if (rx) r1=(*rx);
+ r1=rx;
r=v*tmin;
r1=r1+r;
r1.GetVector(vec1,"car");
// was defined is taken as the starting point.
// The endpoint is initially obtained by applying the tofmax from the start point.
tmin=0;
- if (TMath::Abs(fVz)>0) tmin=-fZ0/fVz;
+ if (fabs(fVz)>0) tmin=-fZ0/fVz;
v=beta*c;
- if (rx) r1=(*rx);
+ r1=rx;
r=v*tmin;
r1=r1+r;
// In case this point can't be reached, the point in which the particle velocity
// was defined is taken as the starting point.
tmin=0;
- if (TMath::Abs(fVz)>0) tmin=-fZ0/fVz;
+ if (fabs(fVz)>0) tmin=-fZ0/fVz;
tmax=tmin+fTofmax;
if (tmax<tmin)
if (!range) // Automatic range determination
{
- scale1=0.01;
- scale2=0.01;
+ scale1=1;
+ scale2=1;
if (rbeg)
{
r1=rbeg->GetPrimed(fRotMat);
if (scale1/scale>1.1 || scale/scale1>1.1) r1*=scale1/scale;
// Re-calculate the tmin for this new starting point
r1.GetVector(vec1,"car");
- if (TMath::Abs(fVz)>0) tmin=(vec1[2]-fZ0)/fVz;
+ if (fabs(fVz)>0) tmin=(vec1[2]-fZ0)/fVz;
tmax=tmin+fTofmax;
}
if (rend)
// All coordinates in the selected unit scale
if (scale2/scale>1.1 || scale/scale2>1.1) r2*=scale2/scale;
r2.GetVector(vec2,"car");
- if (TMath::Abs(fVz)>0) tmax=(vec2[2]-fZ0)/fVz;
+ if (fabs(fVz)>0) tmax=(vec2[2]-fZ0)/fVz;
}
// Make the curve on basis of the flight time boundaries and exit
if (tmax<tmin)
}
else // User explicitly specified range
{
- vec1[TMath::Abs(iaxis)-1]=range[0];
- vec2[TMath::Abs(iaxis)-1]=range[1];
+ vec1[abs(iaxis)-1]=range[0];
+ vec2[abs(iaxis)-1]=range[1];
r1.SetVector(vec1,"car");
r2.SetVector(vec2,"car");
if (iaxis>0) // Range specified in LAB frame
Double_t test=0;
for (Int_t i=0; i<3; i++)
{
- test=TMath::Abs(vec1[i]-vec2[i]);
+ test=fabs(vec1[i]-vec2[i]);
if (test>dmax)
{
dmax=test;
// Various curves can be displayed together or individually; please refer to
// the memberfunction Refresh() for further details.
// It is assumed that the track charge is stored in elementary units
-// (i.e. charge=1 for a proton) and that the track energy is stored in GeV.
+// (i.e. charge=1 for a proton).
// The input argument "scale" specifies the unit scale for the various
// locations where scale=0.01 indicates unit scales in cm etc...
// In case scale<=0, the unit scale for locations is determined from the
// begin, reference or endpoint of the track. If neither of these
-// positions is present, all locations are assumed to be given in cm.
+// positions is present, all locations are assumed to be given in meter.
// The lower and upper bounds for the range are specified by range[0] and
// range[1] and the argument "iaxis" indicates along which axis this range
// is specified.
// TView* view=new TView(1);
// view->SetRange(-1000,-1000,-1000,1000,1000,1000);
// view->ShowAxis();
+//
+// The user can also use the 3D viewing facilities from the TCanvas menu
+// to open an appropriate view.
if (!t || (range && !iaxis)) return;
if (fRefresh>0) Refresh(fRefresh);
- Int_t np=GetN();
+ Int_t np=GetLastPoint()+1;
if (!np) return;
Float_t* points=GetP();
TPolyLine3D* curve=new TPolyLine3D(np,points);
- curve->SetLineWidth(2);
- Float_t q=t->GetCharge();
- curve->SetLineColor(kGreen);
- if (q>0) curve->SetLineColor(kRed);
- if (q<0) curve->SetLineColor(kBlue);
+ curve->SetLineWidth(fLineWidth);
+ if (fLineColor<0)
+ {
+ Float_t q=t->GetCharge();
+ curve->SetLineColor(kGreen);
+ if (q>0) curve->SetLineColor(kRed);
+ if (q<0) curve->SetLineColor(kBlue);
+ }
+ else
+ {
+ curve->SetLineColor(fLineColor);
+ }
curve->Draw();
if (!fCurves)
fCurves->SetOwner();
}
fCurves->Add(curve);
+
+ // Display the marker for the track starting point
+ if (fMstyle>0)
+ {
+ TPolyMarker3D* m=new TPolyMarker3D();
+ m->SetPoint(0,points[0],points[1],points[2]);
+ m->SetMarkerStyle(fMstyle);
+ m->SetMarkerSize(fMsize);
+ Int_t col=curve->GetLineColor();
+ if (fMcol>0) col=fMcol;
+ m->SetMarkerColor(col);
+ m->Draw();
+ fCurves->Add(m);
+ }
}
///////////////////////////////////////////////////////////////////////////
void AliHelix::Refresh(Int_t mode)
//
// The default is mode=0.
- if (TMath::Abs(mode)<2) fRefresh=mode;
+ if (abs(mode)<2) fRefresh=mode;
if (fCurves) fCurves->Delete();
}
///////////////////////////////////////////////////////////////////////////
// TView* view=new TView(1);
// view->SetRange(-1000,-1000,-1000,1000,1000,1000);
// view->ShowAxis();
+//
+// The user can also use the 3D viewing facilities from the TCanvas menu
+// to open an appropriate view.
if (!evt) return;
}
}
///////////////////////////////////////////////////////////////////////////
+void AliHelix::Display(TObjArray* arr,Double_t* range,Int_t iaxis,Double_t scale)
+{
+// Display the helix curves of all tracks in the specified array.
+// A convenient way to obtain an array with selected tracks from e.g. an AliEvent
+// is to make use of its GetTracks() selection facility.
+// Various arrays can be displayed together or individually; please refer to
+// the memberfunction Refresh() for further details.
+// Please refer to the track display memberfunction for further details
+// on the input arguments.
+//
+// The default values are range=0, iaxis=3 and scale=-1.
+//
+// Note :
+// ------
+// Before any display activity, a TCanvas and a TView have to be initiated
+// first by the user like for instance
+//
+// TCanvas* c1=new TCanvas("c1","c1");
+// TView* view=new TView(1);
+// view->SetRange(-1000,-1000,-1000,1000,1000,1000);
+// view->ShowAxis();
+//
+// The user can also use the 3D viewing facilities from the TCanvas menu
+// to open an appropriate view.
+
+ if (!arr) return;
+
+ Int_t ntk=arr->GetEntries();
+ for (Int_t jtk=0; jtk<ntk; jtk++)
+ {
+ TObject* obj=arr->At(jtk);
+ if (!obj) continue;
+ if (!(obj->InheritsFrom("AliTrack"))) continue;
+ AliTrack* tx=(AliTrack*)obj;
+ Display(tx,range,iaxis,scale);
+ }
+}
+///////////////////////////////////////////////////////////////////////////
AliPosition* AliHelix::Extrapolate(AliTrack* t,Double_t* pars,Double_t scale)
{
// Extrapolate an AliTrack according to the corresponding helix curve
// Detailed information of all the helix points used in the extrapolation
// can be obtained via the GetN() and GetP() memberfunctions of TPolyLine3D.
// It is assumed that the track charge is stored in elementary units
-// (i.e. charge=1 for a proton) and that the track energy is stored in GeV.
+// (i.e. charge=1 for a proton).
// The input argument "scale" specifies the unit scale for the various
// locations where scale=0.01 indicates unit scales in cm etc...
// In case scale<=0, the unit scale for locations is determined from the
// begin, reference or endpoint of the track. If neither of these
-// positions is present, all locations are assumed to be given in cm.
+// positions is present, all locations are assumed to be given in meter.
// The extrapolation parameters for the impact plane and required accuracy
// are specified by pars[0], pars[1] and pars[2], respectively.
// pars[0] = coordinate value of the plane for the impact point
// The unit scale for locations if not specified by the user
if (scale<=0)
{
- scale=0.01; // Set default to cm
+ scale=1; // Set default to meter
if (rbeg)
{
scale=rbeg->GetUnitScale();
}
Double_t range[2];
- range[0]=pars[0]-TMath::Abs(pars[1])/2.;
- range[1]=pars[0]+TMath::Abs(pars[1])/2.;
+ range[0]=pars[0]-fabs(pars[1])/2.;
+ range[1]=pars[0]+fabs(pars[1])/2.;
Int_t iaxis=int(pars[2]);
MakeCurve(t,range,iaxis,scale);
- Int_t np=GetN();
+ Int_t np=GetLastPoint()+1;
if (!np) return fExt;
Float_t* points=GetP();
Float_t first[3]={points[3*ip],points[3*ip+1],points[3*ip+2]};
// Last point of the curve around the impact
- ip=np-1;
+ ip=GetLastPoint();
Float_t last[3]={points[3*ip],points[3*ip+1],points[3*ip+2]};
// The accuracy on the impact point
Float_t err[3];
- err[0]=TMath::Abs(first[0]-last[0]);
- err[1]=TMath::Abs(first[1]-last[1]);
- err[2]=TMath::Abs(first[2]-last[2]);
+ err[0]=fabs(first[0]-last[0]);
+ err[1]=fabs(first[1]-last[1]);
+ err[2]=fabs(first[2]-last[2]);
// Take the middle point as impact location
ip=np/2;