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