22-mar-2006 NvE Line attribute selections for displays extended in AliHelix.
[u/mrichter/AliRoot.git] / RALICE / AliHelix.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
7  * Permission to use, copy, modify and distribute this software and its   *
8  * documentation strictly for non-commercial purposes is hereby granted   *
9  * without fee, provided that the above copyright notice appears in all   *
10  * copies and that both the copyright notice and this permission notice   *
11  * appear in the supporting documentation. The authors make no claims     *
12  * about the suitability of this software for any purpose. It is          *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15
16 // $Id$
17
18 ///////////////////////////////////////////////////////////////////////////
19 // Class AliHelix
20 // Representation and extrapolation of AliTracks in a magnetic field.
21 //
22 // This class is meant to provide a means to display and extrapolate
23 // AliTrack objects in the presence of a constant homogeneous magnetic field. 
24 //
25 // For track/event displays the line width, colour etc... can be set using the
26 // standard facilities (see TAttLine).
27 // By default the linewith is set to 2 and the colour set to -1 in the constructor.
28 // The latter results in an automatic colour coding according to the track charge
29 // with the convention positive=red neutral=green negative=blue.
30 //
31 // To indicate the track starting point, the memberfunction SetMarker()
32 // may be used.
33 // By default no marker will be displayed. 
34 //
35 // Examples :
36 // ==========
37 //
38 // Display and extrapolation of individual tracks 
39 // ----------------------------------------------
40 // Float_t vec[3];
41 // AliPosition r1;
42 // Ali3Vector p;
43 // AliTrack t;
44 //
45 // vec[0]=0;
46 // vec[1]=0;
47 // vec[2]=0;
48 // r1.SetVector(vec,"car");
49 //
50 // vec[0]=1;
51 // vec[1]=0;
52 // vec[2]=0.3;
53 // p.SetVector(vec,"car");
54 //
55 // t.Set3Momentum(p);
56 // t.SetBeginPoint(r1);
57 // t.SetCharge(-1);
58 // t.SetMass(0.139);
59 //
60 // // The magnetic field vector in Tesla
61 // Ali3Vector b;
62 // vec[0]=0;
63 // vec[1]=0;
64 // vec[2]=1;
65 // b.SetVector(vec,"car");
66 //
67 // AliHelix* helix=new AliHelix();
68 // helix->SetB(b);
69 // helix->SetTofmax(1e-7);
70 //
71 // TCanvas* c1=new TCanvas("c1","c1");
72 // TView* view=new TView(1);
73 // view->SetRange(-1000,-1000,-1000,1000,1000,1000);
74 // view->ShowAxis();
75 //
76 // // Track displays 
77 // Double_t range[2]={0,600};
78 // helix->Display(&t,range,3);
79 // t.SetCharge(-t.GetCharge());
80 // helix->Display(&t);
81 //
82 // // Track extrapolation
83 // Double_t pars[3]={550,0.001,3};
84 // AliPosition* rext=helix->Extrapolate(&t,pars);
85 // if (rext) rext->Data();
86 // ======================================================================
87 //
88 // Online display of events generated via AliCollider
89 // -------------------------------------------------- 
90 // Int_t nevents=5;   // Number of events to be generated
91 // Int_t jrun=1;      // The run number of this batch of generated events
92 //
93 // cout << " ***" << endl;
94 // cout << " *** AliCollider run for " << nevents << " events." << endl; 
95 // cout << " ***" << endl;
96 //
97 // AliCollider* gen=new AliCollider();
98 //
99 // gen->OpenFortranFile(6,"dump.log");
100 //
101 // gen->SetVertexMode(2);
102 // gen->SetResolution(1e-4);
103 //
104 // gen->SetRunNumber(jrun);
105 // gen->SetPrintFreq(1);
106 //
107 // gen->SetSpectatorPmin(0.01);
108 //
109 // Int_t zp=1;
110 // Int_t ap=1;
111 // Int_t zt=2;
112 // Int_t at=4;
113 //
114 // gen->Init("fixt",zp,ap,zt,at,158);
115 //
116 // AliHelix* helix=new AliHelix();
117 // Float_t vec[3]={0,2,0};
118 // Ali3Vector b;
119 // b.SetVector(vec,"car");
120 // helix->SetB(b);
121 //
122 // helix->Refresh(-1); // Refresh display after each event
123 //
124 // TCanvas* c1=new TCanvas("c1","c1");
125 // TView* view=new TView(1);
126 // view->SetRange(-200,-200,-200,200,200,200);
127 // view->ShowAxis();
128 //
129 // // Prepare random number sequence for this run
130 // // to obtain the number of participants for each event
131 // AliRandom rndm(abs(jrun));
132 // Float_t* rans=new Float_t[nevents];
133 // rndm.Uniform(rans,nevents,2,ap+at);
134 // Int_t npart=0;
135 // Int_t ntk=0;
136 // for (Int_t i=0; i<nevents; i++)
137 // {
138 //  npart=rans[i];
139 //  gen->MakeEvent(npart);
140 //  AliEvent* evt=gen->GetEvent();
141 //  if (evt)
142 //  {
143 //   helix->Display(evt);
144 //   c1->Update();
145 //   gSystem->Sleep(5000); // Some delay to keep the display on screen
146 //  }
147 // }
148 // ======================================================================
149 //
150 //--- Author: Nick van Eijndhoven 17-jun-2004 Utrecht University
151 //- Modified: NvE $Date$ Utrecht University
152 ///////////////////////////////////////////////////////////////////////////
153
154 #include "AliHelix.h"
155 #include "Riostream.h"
156  
157 ClassImp(AliHelix) // Class implementation to enable ROOT I/O
158  
159 AliHelix::AliHelix() : THelix()
160 {
161 // Default constructor
162  fRefresh=0;
163  fCurves=0;
164  fExt=0;
165  fTofmax=1e-8;
166  fMstyle=-1;
167  fMsize=0;
168  fMcol=0;
169  fEnduse=1;
170
171  fLineWidth=2;
172  fLineColor=-1;
173 }
174 ///////////////////////////////////////////////////////////////////////////
175 AliHelix::~AliHelix()
176 {
177 // Destructor to delete dynamically allocated memory.
178  if (fCurves)
179  {
180   delete fCurves;
181   fCurves=0;
182  }
183  if (fExt)
184  {
185   delete fExt;
186   fExt=0;
187  }
188 }
189 ///////////////////////////////////////////////////////////////////////////
190 AliHelix::AliHelix(const AliHelix& h) : THelix(h)
191 {
192 // Copy constructor
193  fB=h.fB;
194  fRefresh=h.fRefresh;
195  fTofmax=h.fTofmax;
196  fMstyle=h.fMstyle;
197  fMsize=h.fMsize;
198  fMcol=h.fMcol;
199  fEnduse=h.fEnduse;
200 }
201 ///////////////////////////////////////////////////////////////////////////
202 void AliHelix::SetB(Ali3Vector& b)
203 {
204 // Set the magnetic field vector in Tesla.
205  fB=b;
206
207  if (fB.GetNorm()>0)
208  {
209   Double_t axis[3];
210   fB.GetVector(axis,"car");
211   SetAxis(axis);
212  }
213 }
214 ///////////////////////////////////////////////////////////////////////////
215 Ali3Vector& AliHelix::GetB()
216 {
217 // Provide the magnetic field vector in Tesla.
218  return fB;
219 }
220 ///////////////////////////////////////////////////////////////////////////
221 void AliHelix::SetTofmax(Float_t tof)
222 {
223 // Set the maximum time of flight for straight tracks in seconds.
224 // This maximum tof will be used for drawing etc... in case no begin
225 // and endpoints can be determined from the track info.
226 // Notes :
227 // -------
228 // 1) In case the user specifies an explicit range, it will override
229 //    the maximum tof limit.
230 // 2) By default the tofmax is set to 10 ns in the AliHelix constructor.
231  fTofmax=tof;
232 }
233 ///////////////////////////////////////////////////////////////////////////
234 Float_t AliHelix::GetTofmax() const
235 {
236 // Provide the maximum time of flight for straight tracks in seconds.
237  return fTofmax;
238 }
239 ///////////////////////////////////////////////////////////////////////////
240 void AliHelix::SetMarker(Int_t style,Float_t size,Int_t col)
241 {
242 // Specify the marker (style, size and colour) to indicate the starting point
243 // of a track in a display.
244 // In case col<0 the marker will have the same color as the track itself.
245 // 
246 // Defaults are style=8, size=0.2 and col=-1.
247  
248  fMstyle=style;
249  fMsize=size;
250  fMcol=col;
251 }
252 ///////////////////////////////////////////////////////////////////////////
253 void AliHelix::UseEndPoint(Int_t mode)
254 {
255 // Select usage of track endpoint in drawing and extrapolation.
256 // This allows correct event displays even for very long tracks.
257 //
258 // mode = 0 : Do not use the track endpoint
259 //        1 : Use the track endpoint
260 // 
261 // The default value is mode=1 (which is also set in the constructor).
262
263  if (mode==0 || mode==1) fEnduse=mode; 
264 }
265 ///////////////////////////////////////////////////////////////////////////
266 void AliHelix::MakeCurve(AliTrack* t,Double_t* range,Int_t iaxis,Double_t scale)
267 {
268 // Make the helix curve for the specified AliTrack.
269 // Detailed information of all the helix points can be obtained via the
270 // GetN() and GetP() memberfunctions of TPolyLine3D.
271 // In case one wants to display or extrapolate an AliTrack it is preferable
272 // to use the Display() or Extrapolate() memberfunctions.
273 // It is assumed that the track charge is stored in elementary units
274 // (i.e. charge=1 for a proton) and that the track energy is stored in GeV.
275 // The input argument "scale" specifies the unit scale for the various
276 // locations where scale=0.01 indicates unit scales in cm etc...
277 // In case scale<=0, the unit scale for locations is determined from the
278 // begin, reference or endpoint of the track. If neither of these
279 // positions is present, all locations are assumed to be given in cm.
280 // The lower and upper bounds for the range are specified by range[0] and
281 // range[1] and the argument "iaxis" indicates along which axis this range
282 // is specified.
283 // The range can be specified either in the LAB frame or in the Helix frame.
284 // The latter is the frame in which the Z axis points in the B direction.
285 //
286 // The conventions for the "iaxis" argument are the following :
287 // iaxis = 1 ==> X axis in the LAB frame
288 //         2 ==> Y axis in the LAB frame
289 //         3 ==> Z axis in the LAB frame
290 //        -1 ==> X axis in the Helix frame
291 //        -2 ==> Y axis in the Helix frame
292 //        -3 ==> Z axis in the Helix frame
293 //
294 // In case range=0 the begin/end/reference points of the AliTrack and the
295 // maximum time of flight (see the SetTofmax() memberfunction) will be used
296 // and an appropriate choice for the iaxis parameter will be made automatically
297 // based on the track kinematics.
298 // In case the reference point is not present, the begin or endpoint will be used
299 // as reference point for the 3-momentum specification. If neither of these positions
300 // is present, (0,0,0) will be taken as the reference point.
301 // 
302 // The default values are range=0, iaxis=3 and scale=-1.
303
304  SetPolyLine(0); // Reset the polyline data points
305
306  if (!t || (range && !iaxis)) return;
307
308  Double_t energy=t->GetEnergy();
309  Double_t betanorm=t->GetBeta();
310
311  if (energy<=0 || betanorm<=0) return;
312
313  AliPosition* rbeg=t->GetBeginPoint();
314  AliPosition* rend=0;
315  if (fEnduse) rend=t->GetEndPoint();
316  AliPosition* rref=t->GetReferencePoint();
317
318  // Magnetic field vector or default Z-direction
319  Double_t bvec[3]={0,0,1};
320  if (fB.GetNorm()>0) fB.GetVector(bvec,"car");
321
322  // The unit scale for locations if not specified by the user
323  if (scale<=0)
324  {
325   scale=0.01; // Set default to cm
326   if (rbeg)
327   {
328    scale=rbeg->GetUnitScale();
329   }
330   else if (rend)
331   {
332    scale=rend->GetUnitScale();
333   }
334   else if (rref)
335   {
336    scale=rref->GetUnitScale();
337   }
338  }
339
340  Double_t c=2.99792458e8/scale; // Lightspeed in the selected unit scale
341
342  // The helix angular frequency
343  Double_t w=9e7*(t->GetCharge()*fB.GetNorm())/energy;
344
345  // The particle velocity in the LAB frame
346  Ali3Vector beta=t->GetBetaVector();
347  Ali3Vector v=beta*c;
348  Double_t vel[3];
349  v.GetVector(vel,"car");
350
351  // The particle velocity in the Helix frame
352  Ali3Vector betaprim=beta.GetPrimed(fRotMat);
353  v=v.GetPrimed(fRotMat);
354  Double_t velprim[3];
355  v.GetVector(velprim,"car");
356
357  // Check compatibility of velocity and range specification.
358  if (range)
359  {
360   Double_t betavec[3];
361   if (iaxis>0) beta.GetVector(betavec,"car");
362   if (iaxis<0) betaprim.GetVector(betavec,"car");
363   if (fabs(betavec[abs(iaxis)-1])/betanorm<1e-10) return;
364  }
365
366  // The LAB location in which the velocity of the particle is defined
367  Double_t loc[3]={0,0,0};
368  Ali3Vector* rx=0;
369  Double_t scalex=0;
370  if (rref)
371  {
372   rx=(Ali3Vector*)rref;
373   scalex=rref->GetUnitScale();
374  }
375  else if (rbeg)
376  {
377   rx=(Ali3Vector*)rbeg;
378   scalex=rbeg->GetUnitScale();
379  }
380  else if (rend)
381  {
382   rx=(Ali3Vector*)rend;
383   scalex=rend->GetUnitScale();
384  }
385
386  if (rx)
387  {
388   if (scalex/scale>1.1 || scale/scalex>1.1) (*rx)*=scalex/scale;
389   rx->GetVector(loc,"car");
390  }
391
392  // Initialisation of Helix kinematics
393  SetHelix(loc,vel,w,0,kUnchanged,bvec);
394
395  Int_t bend=0;
396  if (fabs(w)>0 && fabs(fVt)>0) bend=1;
397
398  // Flight time boundaries.
399  // The time origin t=0 is chosen to indicate the position in which
400  // the particle velocity was defined.
401  // The total flight time is initialised to the (user specified) tofmax.
402  Double_t tmin=0,tmax=0;
403  Double_t tof=fTofmax;
404  Double_t dum=0;
405
406  // The trajectory begin and end points
407  Double_t vec1[3]={0,0,0};
408  Double_t vec2[3]={0,0,0};
409  Ali3Vector r1;
410  Ali3Vector r2;
411  Double_t scale1=0.01;
412  Double_t scale2=0.01;
413
414  if (!bend)
415  {
416   ////////////////////////////////////////
417   // Treatment of straight trajectories //
418   ////////////////////////////////////////
419   Ali3Vector r;
420   if (range) // Specified range allows for exact flight time boundaries
421   {
422    if (iaxis>0)
423    {
424     tmin=(range[0]-loc[iaxis-1])/vel[iaxis-1];
425     tmax=(range[1]-loc[iaxis-1])/vel[iaxis-1];
426    }
427    else
428    {
429     loc[0]=fX0;
430     loc[1]=fY0;
431     loc[2]=fZ0;
432     tmin=(range[0]-loc[abs(iaxis)-1])/velprim[abs(iaxis)-1];
433     tmax=(range[1]-loc[abs(iaxis)-1])/velprim[abs(iaxis)-1];
434    }
435    if (tmax<tmin)
436    {
437     dum=tmin;
438     tmin=tmax;
439     tmax=dum;
440    }
441    // Make the 'curve' in the LAB frame and exit.
442    // Use the parametrisation : r(t)=r0+t*v
443    // using the range based flight time boundaries.
444    // An additional point in the middle of the trajectory is
445    // generated in view of accuracy in the case of extrapolations.
446    tof=tmax-tmin;
447    v=beta*c;
448    if (rx) r1=(*rx);
449    r=v*tmin;
450    r1=r1+r;
451    r1.GetVector(vec1,"car");
452    SetNextPoint(float(vec1[0]),float(vec1[1]),float(vec1[2]));
453    r=v*(tof/2.);
454    r2=r1+r;
455    r2.GetVector(vec2,"car");
456    SetNextPoint(float(vec2[0]),float(vec2[1]),float(vec2[2]));
457    r=v*tof;
458    r2=r1+r;
459    r2.GetVector(vec2,"car");
460    SetNextPoint(float(vec2[0]),float(vec2[1]),float(vec2[2]));
461   }
462   else // Automatic range determination
463   {
464    // Initially the point with Z=0 in the Helix frame is taken as a starting point.
465    // In case this point can't be reached, the point in which the particle velocity
466    // was defined is taken as the starting point.
467    // The endpoint is initially obtained by applying the tofmax from the start point.
468    tmin=0;
469    if (fabs(fVz)>0) tmin=-fZ0/fVz;
470    v=beta*c;
471    if (rx) r1=(*rx);
472    r=v*tmin;
473    r1=r1+r;
474
475    // Override the initial begin and endpoint settings by the track data
476    if (rbeg)
477    {
478     r1=(Ali3Vector)(*rbeg); 
479     scale1=rbeg->GetUnitScale();
480     // All coordinates in the selected unit scale
481     if (scale1/scale>1.1 || scale/scale1>1.1) r1*=scale1/scale;
482    }
483
484    r=v*fTofmax;
485    r2=r1+r;
486    if (rend)
487    {
488     r2=(Ali3Vector)(*rend); 
489     scale2=rend->GetUnitScale();
490     // All coordinates in the selected unit scale
491     if (scale2/scale>1.1 || scale/scale2>1.1) r2*=scale2/scale;
492    }
493    
494    r1.GetVector(vec1,"car");
495    r2.GetVector(vec2,"car");
496
497    // Make the 'curve' in the LAB frame and exit.
498    SetNextPoint(float(vec1[0]),float(vec1[1]),float(vec1[2]));
499    SetNextPoint(float(vec2[0]),float(vec2[1]),float(vec2[2]));
500   }
501  }
502  else
503  {
504   //////////////////////////////////////
505   // Treatment of curved trajectories //
506   //////////////////////////////////////
507
508   // Initialisation of the flight time boundaries.
509   // Based on the constant motion of the particle along the Helix Z-axis,
510   // the parametrisation z(t)=z0+fVz*t in the Helix frame is used. 
511   // If possible the point with Z=0 in the Helix frame is taken as a starting point.
512   // In case this point can't be reached, the point in which the particle velocity
513   // was defined is taken as the starting point.
514   tmin=0;
515   if (fabs(fVz)>0) tmin=-fZ0/fVz;
516   tmax=tmin+fTofmax;
517
518   if (tmax<tmin)
519   {
520    dum=tmin;
521    tmin=tmax;
522    tmax=dum;
523   }
524
525   // Determination of the range in the helix frame
526
527   if (!range) // Automatic range determination
528   {
529    scale1=0.01;
530    scale2=0.01;
531    if (rbeg)
532    {
533     r1=rbeg->GetPrimed(fRotMat);
534     scale1=rbeg->GetUnitScale();
535     // All coordinates in the selected unit scale
536     if (scale1/scale>1.1 || scale/scale1>1.1) r1*=scale1/scale;
537     // Re-calculate the tmin for this new starting point
538     r1.GetVector(vec1,"car");
539     if (fabs(fVz)>0) tmin=(vec1[2]-fZ0)/fVz;
540     tmax=tmin+fTofmax;
541    }
542    if (rend)
543    {
544     r2=rend->GetPrimed(fRotMat);
545     scale2=rend->GetUnitScale();
546     // All coordinates in the selected unit scale
547     if (scale2/scale>1.1 || scale/scale2>1.1) r2*=scale2/scale;
548     r2.GetVector(vec2,"car");
549     if (fabs(fVz)>0) tmax=(vec2[2]-fZ0)/fVz;
550    }
551    // Make the curve on basis of the flight time boundaries and exit
552    if (tmax<tmin)
553    {
554     dum=tmin;
555     tmin=tmax;
556     tmax=dum;
557    }
558    SetRange(tmin,tmax,kHelixT);
559   }
560   else // User explicitly specified range
561   {
562    vec1[abs(iaxis)-1]=range[0];
563    vec2[abs(iaxis)-1]=range[1];
564    r1.SetVector(vec1,"car");
565    r2.SetVector(vec2,"car");
566    if (iaxis>0) // Range specified in LAB frame
567    {
568     r1=r1.GetPrimed(fRotMat);
569     r1.GetVector(vec1,"car");
570     r2=r2.GetPrimed(fRotMat);
571     r2.GetVector(vec2,"car");
572    } 
573    // Determination of the axis component with the
574    // largest range difference
575    Double_t dmax=0;
576    Int_t imax=0;
577    Double_t test=0;
578    for (Int_t i=0; i<3; i++)
579    {
580     test=fabs(vec1[i]-vec2[i]);
581     if (test>dmax)
582     {
583      dmax=test;
584      imax=i;
585     }
586    }
587
588    Double_t rmin=vec1[imax];
589    Double_t rmax=vec2[imax];
590    if (rmax<rmin)
591    {
592     dum=rmin;
593     rmin=rmax;
594     rmax=dum;
595    }
596
597    // The kinematic range boundaries in the helix frame
598    Double_t xmin=fX0-fVt/fW;
599    Double_t xmax=fX0+fVt/fW;
600    Double_t ymin=fY0-fVt/fW;
601    Double_t ymax=fY0+fVt/fW;
602
603    if (xmax<xmin)
604    {
605     dum=xmin;
606     xmin=xmax;
607     xmax=dum;
608    }
609    if (ymax<ymin)
610    {
611     dum=ymin;
612     ymin=ymax;
613     ymax=dum;
614    }
615
616    // Set the range for the helix
617    if (imax==2 && dmax>0) SetRange(rmin,rmax,kHelixZ);
618    if (imax==1)
619    {
620     // Limit range to kinematic boundaries if needed
621     if (rmin<=ymin) rmin=ymin+1e-6*dmax;
622     if (rmax>=ymax) rmax=ymax-1e-6*dmax;
623     if (rmin<rmax) SetRange(rmin,rmax,kHelixY);
624    }
625    if (imax==0)
626    {
627     // Limit range to kinematic boundaries if needed
628     if (rmin<=xmin) rmin=xmin+1e-6*dmax;
629     if (rmax>=xmax) rmax=xmax-1e-6*dmax;
630     if (rmin<rmax) SetRange(rmin,rmax,kHelixX);
631    }
632   }
633  }
634  return;
635 }
636 ///////////////////////////////////////////////////////////////////////////
637 void AliHelix::Display(AliTrack* t,Double_t* range,Int_t iaxis,Double_t scale)
638 {
639 // Display the helix curve of an AliTrack.
640 // Various curves can be displayed together or individually; please refer to
641 // the memberfunction Refresh() for further details.
642 // It is assumed that the track charge is stored in elementary units
643 // (i.e. charge=1 for a proton) and that the track energy is stored in GeV.
644 // The input argument "scale" specifies the unit scale for the various
645 // locations where scale=0.01 indicates unit scales in cm etc...
646 // In case scale<=0, the unit scale for locations is determined from the
647 // begin, reference or endpoint of the track. If neither of these
648 // positions is present, all locations are assumed to be given in cm.
649 // The lower and upper bounds for the range are specified by range[0] and
650 // range[1] and the argument "iaxis" indicates along which axis this range
651 // is specified.
652 // The range can be specified either in the LAB frame or in the Helix frame.
653 // The latter is the frame in which the Z axis points in the B direction.
654 //
655 // The conventions for the "iaxis" argument are the following :
656 // iaxis = 1 ==> X axis in the LAB frame
657 //         2 ==> Y axis in the LAB frame
658 //         3 ==> Z axis in the LAB frame
659 //        -1 ==> X axis in the Helix frame
660 //        -2 ==> Y axis in the Helix frame
661 //        -3 ==> Z axis in the Helix frame
662 //
663 // In case range=0 the begin/end/reference points of the AliTrack and the
664 // maximum time of flight (see the SetTofmax() memberfunction) will be used
665 // and an appropriate choice for the iaxis parameter will be made automatically
666 // based on the track kinematics.
667 // In case the reference point is not present, the begin or endpoint will be used
668 // as reference point for the 3-momentum specification. If neither of these positions
669 // is present, (0,0,0) will be taken as the reference point.
670 // 
671 // The default values are range=0, iaxis=3 and scale=-1.
672 //
673 // Note :
674 // ------
675 // Before any display activity, a TCanvas and a TView have to be initiated
676 // first by the user like for instance
677 // 
678 // TCanvas* c1=new TCanvas("c1","c1");
679 // TView* view=new TView(1);
680 // view->SetRange(-1000,-1000,-1000,1000,1000,1000);
681 // view->ShowAxis();
682
683  if (!t || (range && !iaxis)) return;
684
685  MakeCurve(t,range,iaxis,scale);
686
687  if (fRefresh>0) Refresh(fRefresh);
688
689  Int_t np=GetN();
690  if (!np) return;
691
692  Float_t* points=GetP();
693  TPolyLine3D* curve=new TPolyLine3D(np,points);
694
695  curve->SetLineWidth(fLineWidth);
696  if (fLineColor<0)
697  {
698   Float_t q=t->GetCharge();
699   curve->SetLineColor(kGreen);
700   if (q>0) curve->SetLineColor(kRed);
701   if (q<0) curve->SetLineColor(kBlue);
702  }
703  else
704  {
705   curve->SetLineColor(fLineColor);
706  }
707  curve->Draw();
708
709  if (!fCurves)
710  {
711   fCurves=new TObjArray();
712   fCurves->SetOwner();
713  }
714  fCurves->Add(curve);
715
716  // Display the marker for the track starting point
717  if (fMstyle>0)
718  {
719   TPolyMarker3D* m=new TPolyMarker3D();
720   m->SetPoint(0,points[0],points[1],points[2]);
721   m->SetMarkerStyle(fMstyle);
722   m->SetMarkerSize(fMsize);
723   Int_t col=curve->GetLineColor();
724   if (fMcol>0) col=fMcol;
725   m->SetMarkerColor(col);
726   m->Draw();
727   fCurves->Add(m);
728  }
729 }
730 ///////////////////////////////////////////////////////////////////////////
731 void AliHelix::Refresh(Int_t mode)
732 {
733 // Refresh the display screen before showing the next curve.
734 //
735 // mode = 0 : refreshing fully under user control.
736 //        1 : the display screen will be refreshed automatically
737 //            at each individual track display.
738 //       -1 : the display screen will be refreshed automatically
739 //            at each event display.
740 //
741 // The default is mode=0.
742
743  if (abs(mode)<2) fRefresh=mode;
744  if (fCurves) fCurves->Delete();
745 }
746 ///////////////////////////////////////////////////////////////////////////
747 void AliHelix::Display(AliEvent* evt,Double_t* range,Int_t iaxis,Double_t scale)
748 {
749 // Display the helix curves of all tracks of the specified event.
750 // Various events can be displayed together or individually; please refer to
751 // the memberfunction Refresh() for further details.
752 // Please refer to the track display memberfunction for further details
753 // on the input arguments.
754 // 
755 // The default values are range=0, iaxis=3 and scale=-1.
756 //
757 // Note :
758 // ------
759 // Before any display activity, a TCanvas and a TView have to be initiated
760 // first by the user like for instance
761 // 
762 // TCanvas* c1=new TCanvas("c1","c1");
763 // TView* view=new TView(1);
764 // view->SetRange(-1000,-1000,-1000,1000,1000,1000);
765 // view->ShowAxis();
766
767  if (!evt) return;
768
769  if (fRefresh<0) Refresh(fRefresh);
770
771  Int_t ntk=evt->GetNtracks();
772  for (Int_t jtk=1; jtk<=ntk; jtk++)
773  {
774   AliTrack* tx=evt->GetTrack(jtk);
775   if (tx) Display(tx,range,iaxis,scale);
776  }
777 }
778 ///////////////////////////////////////////////////////////////////////////
779 void AliHelix::Display(TObjArray* arr,Double_t* range,Int_t iaxis,Double_t scale)
780 {
781 // Display the helix curves of all tracks in the specified array.
782 // A convenient way to obtain an array with selected tracks from e.g. an AliEvent
783 // is to make use of its GetTracks() selection facility.
784 // Various arrays can be displayed together or individually; please refer to
785 // the memberfunction Refresh() for further details.
786 // Please refer to the track display memberfunction for further details
787 // on the input arguments.
788 // 
789 // The default values are range=0, iaxis=3 and scale=-1.
790 //
791 // Note :
792 // ------
793 // Before any display activity, a TCanvas and a TView have to be initiated
794 // first by the user like for instance
795 // 
796 // TCanvas* c1=new TCanvas("c1","c1");
797 // TView* view=new TView(1);
798 // view->SetRange(-1000,-1000,-1000,1000,1000,1000);
799 // view->ShowAxis();
800
801  if (!arr) return;
802
803  Int_t ntk=arr->GetEntries();
804  for (Int_t jtk=0; jtk<ntk; jtk++)
805  {
806   TObject* obj=arr->At(jtk);
807   if (!obj) continue;
808   if (!(obj->InheritsFrom("AliTrack"))) continue;
809   AliTrack* tx=(AliTrack*)obj;
810   Display(tx,range,iaxis,scale);
811  }
812 }
813 ///////////////////////////////////////////////////////////////////////////
814 AliPosition* AliHelix::Extrapolate(AliTrack* t,Double_t* pars,Double_t scale)
815 {
816 // Extrapolate an AliTrack according to the corresponding helix curve
817 // and provide a pointer to the impact position w.r.t. a specified plane.
818 // In case the track can never reach the specified plane, the returned
819 // position pointer is zero.
820 // Detailed information of all the helix points used in the extrapolation
821 // can be obtained via the GetN() and GetP() memberfunctions of TPolyLine3D.
822 // It is assumed that the track charge is stored in elementary units
823 // (i.e. charge=1 for a proton) and that the track energy is stored in GeV.
824 // The input argument "scale" specifies the unit scale for the various
825 // locations where scale=0.01 indicates unit scales in cm etc...
826 // In case scale<=0, the unit scale for locations is determined from the
827 // begin, reference or endpoint of the track. If neither of these
828 // positions is present, all locations are assumed to be given in cm.
829 // The extrapolation parameters for the impact plane and required accuracy
830 // are specified by pars[0], pars[1] and pars[2], respectively.
831 // pars[0] = coordinate value of the plane for the impact point
832 // pars[1] = required accuracy on the specified impact plane coordinate
833 // pars[2] = the axis along which the value of par[0] is specified
834 //
835 // The parameters can be specified either w.r.t. the LAB frame or the Helix frame.
836 // The latter is the frame in which the Z axis points in the B direction.
837 //
838 // The conventions for the par[2] argument are the following :
839 // par[2] = 1 ==> X axis in the LAB frame
840 //          2 ==> Y axis in the LAB frame
841 //          3 ==> Z axis in the LAB frame
842 //         -1 ==> X axis in the Helix frame
843 //         -2 ==> Y axis in the Helix frame
844 //         -3 ==> Z axis in the Helix frame
845 //
846 // Example :
847 // ---------
848 // To obtain an extrapolation to the plane Z=0 in the LAB frame
849 // with an accuracy of 0.001 cm the input arguments would be
850 // pars[0]=0  pars[1]=0.001  pars[2]=3  scale=0.01
851 //
852 // Note : The default value for the scale is -1.
853
854  if (fExt)
855  {
856   delete fExt;
857   fExt=0;
858  }
859
860  if (!t || !pars) return fExt;
861
862  AliPosition* rbeg=t->GetBeginPoint();
863  AliPosition* rend=t->GetEndPoint();
864  AliPosition* rref=t->GetReferencePoint();
865
866  // The unit scale for locations if not specified by the user
867  if (scale<=0)
868  {
869   scale=0.01; // Set default to cm
870   if (rbeg)
871   {
872    scale=rbeg->GetUnitScale();
873   }
874   else if (rend)
875   {
876    scale=rend->GetUnitScale();
877   }
878   else if (rref)
879   {
880    scale=rref->GetUnitScale();
881   }
882  }
883
884  Double_t range[2];
885  range[0]=pars[0]-fabs(pars[1])/2.;
886  range[1]=pars[0]+fabs(pars[1])/2.;
887
888  Int_t iaxis=int(pars[2]);
889
890  MakeCurve(t,range,iaxis,scale);
891
892  Int_t np=GetN();
893  if (!np) return fExt;
894
895  Float_t* points=GetP();
896
897  // First point of the curve around the impact
898  Int_t ip=0;
899  Float_t first[3]={points[3*ip],points[3*ip+1],points[3*ip+2]};
900
901  // Last point of the curve around the impact
902  ip=np-1;
903  Float_t last[3]={points[3*ip],points[3*ip+1],points[3*ip+2]};
904
905  // The accuracy on the impact point 
906  Float_t err[3];
907  err[0]=fabs(first[0]-last[0]);
908  err[1]=fabs(first[1]-last[1]);
909  err[2]=fabs(first[2]-last[2]);
910
911  // Take the middle point as impact location
912  ip=np/2;
913  Float_t imp[3]={points[3*ip],points[3*ip+1],points[3*ip+2]};
914
915  fExt=new AliPosition();
916  fExt->SetUnitScale(scale);
917  fExt->SetPosition(imp,"car");
918  fExt->SetPositionErrors(err,"car");
919
920  return fExt;
921 }
922 ///////////////////////////////////////////////////////////////////////////