Modifications needed to do the following:
[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//
b847fc3d 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//
62e01f4c 31// To indicate the track starting point, the memberfunction SetMarker()
32// may be used.
33// By default no marker will be displayed.
34//
c5555bc0 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
157ClassImp(AliHelix) // Class implementation to enable ROOT I/O
158
159AliHelix::AliHelix() : THelix()
160{
161// Default constructor
162 fRefresh=0;
163 fCurves=0;
164 fExt=0;
165 fTofmax=1e-8;
62e01f4c 166 fMstyle=-1;
167 fMsize=0;
168 fMcol=0;
169 fEnduse=1;
b847fc3d 170
171 fLineWidth=2;
172 fLineColor=-1;
c5555bc0 173}
174///////////////////////////////////////////////////////////////////////////
175AliHelix::~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///////////////////////////////////////////////////////////////////////////
190AliHelix::AliHelix(const AliHelix& h) : THelix(h)
191{
192// Copy constructor
193 fB=h.fB;
194 fRefresh=h.fRefresh;
aa8231b0 195 fTofmax=h.fTofmax;
196 fMstyle=h.fMstyle;
197 fMsize=h.fMsize;
198 fMcol=h.fMcol;
199 fEnduse=h.fEnduse;
c5555bc0 200}
201///////////////////////////////////////////////////////////////////////////
202void 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///////////////////////////////////////////////////////////////////////////
215Ali3Vector& AliHelix::GetB()
216{
217// Provide the magnetic field vector in Tesla.
218 return fB;
219}
220///////////////////////////////////////////////////////////////////////////
221void 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///////////////////////////////////////////////////////////////////////////
234Float_t AliHelix::GetTofmax() const
235{
236// Provide the maximum time of flight for straight tracks in seconds.
237 return fTofmax;
238}
239///////////////////////////////////////////////////////////////////////////
62e01f4c 240void 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///////////////////////////////////////////////////////////////////////////
253void 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///////////////////////////////////////////////////////////////////////////
c5555bc0 266void 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();
62e01f4c 314 AliPosition* rend=0;
315 if (fEnduse) rend=t->GetEndPoint();
c5555bc0 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");
7a086578 363 if (fabs(betavec[abs(iaxis)-1])/betanorm<1e-10) return;
c5555bc0 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;
7a086578 396 if (fabs(w)>0 && fabs(fVt)>0) bend=1;
c5555bc0 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;
7a086578 432 tmin=(range[0]-loc[abs(iaxis)-1])/velprim[abs(iaxis)-1];
433 tmax=(range[1]-loc[abs(iaxis)-1])/velprim[abs(iaxis)-1];
c5555bc0 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;
7a086578 469 if (fabs(fVz)>0) tmin=-fZ0/fVz;
c5555bc0 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;
7a086578 515 if (fabs(fVz)>0) tmin=-fZ0/fVz;
c5555bc0 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");
7a086578 539 if (fabs(fVz)>0) tmin=(vec1[2]-fZ0)/fVz;
c5555bc0 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");
7a086578 549 if (fabs(fVz)>0) tmax=(vec2[2]-fZ0)/fVz;
c5555bc0 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 {
7a086578 562 vec1[abs(iaxis)-1]=range[0];
563 vec2[abs(iaxis)-1]=range[1];
c5555bc0 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 {
7a086578 580 test=fabs(vec1[i]-vec2[i]);
c5555bc0 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///////////////////////////////////////////////////////////////////////////
637void 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
b847fc3d 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 }
c5555bc0 707 curve->Draw();
708
709 if (!fCurves)
710 {
711 fCurves=new TObjArray();
712 fCurves->SetOwner();
713 }
714 fCurves->Add(curve);
62e01f4c 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 }
c5555bc0 729}
730///////////////////////////////////////////////////////////////////////////
731void 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
7a086578 743 if (abs(mode)<2) fRefresh=mode;
c5555bc0 744 if (fCurves) fCurves->Delete();
745}
746///////////////////////////////////////////////////////////////////////////
747void 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///////////////////////////////////////////////////////////////////////////
aa8231b0 779void 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///////////////////////////////////////////////////////////////////////////
c5555bc0 814AliPosition* 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];
7a086578 885 range[0]=pars[0]-fabs(pars[1])/2.;
886 range[1]=pars[0]+fabs(pars[1])/2.;
c5555bc0 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];
7a086578 907 err[0]=fabs(first[0]-last[0]);
908 err[1]=fabs(first[1]-last[1]);
909 err[2]=fabs(first[2]-last[2]);
c5555bc0 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///////////////////////////////////////////////////////////////////////////