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