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