08-mar-2003 NvE Compiler option /GR introduced for MSVC++ in mklibs.bat to explicitly...
[u/mrichter/AliRoot.git] / RALICE / AliTrack.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 AliTrack
20 // Handling of the attributes of a reconstructed particle track.
21 //
22 // Coding example :
23 // ----------------
24 //
25 // Float_t a[4]={195.,1.2,-0.04,8.5};
26 // Ali4Vector pmu;
27 // pmu.SetVector(a,"car");
28 // AliTrack t1;
29 // t1.Set4Momentum(pmu);
30 //
31 // Float_t b[3]={1.2,-0.04,8.5};
32 // Ali3Vector p;
33 // p.SetVector(b,"car");
34 // AliTrack t2;
35 // t2.Set3Momentum(p);
36 // t2.SetCharge(0);
37 // t2.SetMass(1.115);
38 //
39 // t1.Data();
40 // t2.Data();
41 //
42 // Float_t pi=acos(-1.);
43 // Float_t thcms=0.2*pi; // decay theta angle in cms
44 // Float_t phicms=pi/4.; // decay theta angle in cms
45 // Float_t m1=0.938;
46 // Float_t m2=0.140;
47 // t2.Decay(m1,m2,thcms,phicms); // Track t2 decay : Lambda -> proton + pion
48 //
49 // t2.List();
50 //
51 // Int_t ndec=t2.GetNdecay();
52 // AliTrack* d1=t2.GetDecayTrack(1); // Access to decay track number 1
53 // AliTrack* d2=t2.GetDecayTrack(2); // Access to decay track number 2
54 //
55 // AliSignal s1,s2,s3,s4;
56 //
57 // .... // Code (e.g. detector readout) to fill AliSignal data
58 //
59 // AliTrack trec; // Track which will be reconstructed from signals
60 // trec.AddSignal(s1);
61 // trec.AddSignal(s3);
62 // trec.AddSignal(s4);
63 //
64 // Ali3Vector P;
65 // Float_t Q,M;
66 //
67 // ... // Code which accesses signals from trec and reconstructs
68 //        3-momentum P, charge Q, mass M etc...
69 //
70 // trec.Set3Momentum(P);
71 // trec.SetCharge(Q);
72 // trec.SetMass(M);
73 //
74 // Float_t r1[3]={1.6,-3.8,25.7};
75 // Float_t er1[3]={0.2,0.5,1.8};
76 // Float_t r2[3]={8.6,23.8,-6.7};
77 // Float_t er2[3]={0.93,1.78,0.8};
78 // AliPosition begin,end;
79 // begin.SetPosition(r1,"car");
80 // begin.SetPositionErrors(er1,"car");
81 // end.SetPosition(r2,"car");
82 // end.SetPositionErrors(er2,"car");
83 // trec.SetBeginPoint(begin);
84 // trec.SetEndPoint(end);
85 // 
86 // Note : All quantities are in GeV, GeV/c or GeV/c**2
87 //
88 //--- Author: Nick van Eijndhoven 10-jul-1997 UU-SAP Utrecht
89 //- Modified: NvE $Date$ UU-SAP Utrecht
90 ///////////////////////////////////////////////////////////////////////////
91
92 #include "AliTrack.h"
93 #include "Riostream.h"
94  
95 ClassImp(AliTrack) // Class implementation to enable ROOT I/O
96  
97 AliTrack::AliTrack() : TObject(),Ali4Vector()
98 {
99 // Default constructor
100 // All variables initialised to 0
101  Init();
102  Reset();
103 }
104 ///////////////////////////////////////////////////////////////////////////
105 void AliTrack::Init()
106 {
107 // Initialisation of pointers etc...
108  fDecays=0;
109  fSignals=0;
110  fMasses=0;
111  fDmasses=0;
112  fPmasses=0;
113  fBegin=0;
114  fEnd=0;
115  fImpactXY=0;
116  fImpactXZ=0;
117  fImpactYZ=0;
118  fClosest=0;
119 }
120 ///////////////////////////////////////////////////////////////////////////
121 AliTrack::~AliTrack()
122 {
123 // Destructor to delete memory allocated for decay tracks array
124  if (fDecays)
125  {
126   delete fDecays;
127   fDecays=0;
128  }
129  if (fSignals)
130  {
131   fSignals->Clear();
132   delete fSignals;
133   fSignals=0;
134  }
135  if (fMasses)
136  {
137   delete fMasses;
138   fMasses=0;
139  }
140  if (fDmasses)
141  {
142   delete fDmasses;
143   fDmasses=0;
144  }
145  if (fPmasses)
146  {
147   delete fPmasses;
148   fPmasses=0;
149  }
150  if (fBegin)
151  {
152   delete fBegin;
153   fBegin=0;
154  }
155  if (fEnd)
156  {
157   delete fEnd;
158   fEnd=0;
159  }
160  if (fImpactXY)
161  {
162   delete fImpactXY;
163   fImpactXY=0;
164  }
165  if (fImpactXZ)
166  {
167   delete fImpactXZ;
168   fImpactXZ=0;
169  }
170  if (fImpactYZ)
171  {
172   delete fImpactYZ;
173   fImpactYZ=0;
174  }
175  if (fClosest)
176  {
177   delete fClosest;
178   fClosest=0;
179  }
180 }
181 ///////////////////////////////////////////////////////////////////////////
182 AliTrack::AliTrack(AliTrack& t) : TObject(t),Ali4Vector(t)
183 {
184 // Copy constructor
185  Init();
186
187  fQ=t.fQ;
188  fNdec=t.fNdec;
189  fNsig=t.fNsig;
190  fNmasses=t.fNmasses;
191  if (fNmasses)
192  {
193   fMasses=new TArrayD(*(t.fMasses));
194   fDmasses=new TArrayD(*(t.fDmasses));
195   fPmasses=new TArrayD(*(t.fPmasses));
196  }
197  if (t.fBegin) fBegin=new AliPositionObj(*(t.fBegin));
198  if (t.fEnd) fEnd=new AliPositionObj(*(t.fEnd));
199  if (t.fImpactXY) fImpactXY=new AliPositionObj(*(t.fImpactXY));
200  if (t.fImpactXZ) fImpactXZ=new AliPositionObj(*(t.fImpactXZ));
201  if (t.fImpactYZ) fImpactYZ=new AliPositionObj(*(t.fImpactYZ));
202  if (t.fClosest) fClosest=new AliPositionObj(*(t.fClosest));
203  fUserId=t.fUserId;
204  fChi2=t.fChi2;
205  fNdf=t.fNdf;
206  fCode=t.fCode;
207
208  if (fNdec)
209  {
210   fDecays=new TObjArray(fNdec);
211   fDecays->SetOwner();
212   for (Int_t it=1; it<=fNdec; it++)
213   {
214    AliTrack* tx=t.GetDecayTrack(it);
215    fDecays->Add(new AliTrack(*tx));
216   }
217  }
218
219  if (fNsig)
220  {
221   fSignals=new TObjArray(fNsig);
222   for (Int_t is=1; is<=fNsig; is++)
223   {
224    AliSignal* sx=t.GetSignal(is);
225    fSignals->Add(sx);
226   }
227  }
228 }
229 ///////////////////////////////////////////////////////////////////////////
230 void AliTrack::Reset()
231 {
232 // Reset all variables to 0 and delete all auto-generated decay tracks.
233  fQ=0;
234  fChi2=0;
235  fNdf=0;
236  fUserId=0;
237  fCode=0;
238  fNdec=0;
239  fNsig=0;
240  fNmasses=0;
241  Double_t a[4]={0,0,0,0};
242  SetVector(a,"sph");
243  if (fDecays)
244  {
245   delete fDecays;
246   fDecays=0;
247  }
248  if (fSignals)
249  {
250   fSignals->Clear();
251   delete fSignals;
252   fSignals=0;
253  }
254  if (fMasses)
255  {
256   delete fMasses;
257   fMasses=0;
258  }
259  if (fDmasses)
260  {
261   delete fDmasses;
262   fDmasses=0;
263  }
264  if (fPmasses)
265  {
266   delete fPmasses;
267   fPmasses=0;
268  }
269  if (fBegin)
270  {
271   delete fBegin;
272   fBegin=0;
273  }
274  if (fEnd)
275  {
276   delete fEnd;
277   fEnd=0;
278  }
279  if (fImpactXY)
280  {
281   delete fImpactXY;
282   fImpactXY=0;
283  }
284  if (fImpactXZ)
285  {
286   delete fImpactXZ;
287   fImpactXZ=0;
288  }
289  if (fImpactYZ)
290  {
291   delete fImpactYZ;
292   fImpactYZ=0;
293  }
294  if (fClosest)
295  {
296   delete fClosest;
297   fClosest=0;
298  }
299 }
300 ///////////////////////////////////////////////////////////////////////////
301 void AliTrack::Set3Momentum(Ali3Vector& p)
302 {
303 // Set the track parameters according to the 3-momentum p
304  Set3Vector(p);
305 }
306 ///////////////////////////////////////////////////////////////////////////
307 void AliTrack::Set4Momentum(Ali4Vector& p)
308 {
309 // Set the track parameters according to the 4-momentum p
310  Double_t E=p.GetScalar();
311  Double_t dE=p.GetResultError();
312  Ali3Vector pv=p.Get3Vector();
313  SetVector(E,pv);
314  SetScalarError(dE);
315 }
316 ///////////////////////////////////////////////////////////////////////////
317 void AliTrack::SetMass(Double_t m,Double_t dm)
318 {
319 // Set the particle mass
320 // The default value for the error dm is 0.
321  Double_t inv=pow(m,2);
322  Double_t dinv=fabs(2.*m*dm);
323  SetInvariant(inv,dinv);
324 }
325 ///////////////////////////////////////////////////////////////////////////
326 void AliTrack::SetCharge(Float_t q)
327 {
328 // Set the particle charge
329  fQ=q;
330 }
331 ///////////////////////////////////////////////////////////////////////////
332 void AliTrack::Data(TString f)
333 {
334 // Provide track information within the coordinate frame f
335  Double_t m=GetMass();
336  Double_t dm=GetResultError();
337  cout << " *AliTrack::Data* Id : " << fUserId << " Code : " << fCode
338       << " Mass : " << m << " error : " << dm << " Charge : " << fQ
339       << " Momentum : " << GetMomentum() << " Nmass hyp. : " << fNmasses
340       << " Ntracks : " << fNdec << " Nsignals : " << fNsig << endl;
341  for (Int_t i=0; i<fNmasses; i++)
342  {
343   cout << " Mass hypothesis " << (i+1) << " Mass : " << fMasses->At(i)
344        << " error : " << fDmasses->At(i) << " prob. : " << fPmasses->At(i)
345        << endl;
346  }
347  Ali4Vector::Data(f); 
348
349 ///////////////////////////////////////////////////////////////////////////
350 void AliTrack::List(TString f)
351 {
352 // Provide current track and decay level 1 information within coordinate frame f
353
354  Data(f); // Information of the current track
355
356  // Decay products of this track
357  AliTrack* td; 
358  for (Int_t id=1; id<=fNdec; id++)
359  {
360   td=GetDecayTrack(id);
361   if (td)
362   {
363    cout << "  ---Level 1 sec. track no. " << id << endl;
364    td->Data(f); 
365   }
366   else
367   {
368    cout << " *AliTrack::List* Error : No decay track present." << endl; 
369   }
370  }
371
372 ///////////////////////////////////////////////////////////////////////////
373 void AliTrack::ListAll(TString f)
374 {
375 // Provide complete track and decay information within the coordinate frame f
376
377  Data(f); // Information of the current track
378  if (fBegin) { cout << " Begin-point :"; fBegin->Data(f); }
379  if (fEnd)   { cout << " End-point   :"; fEnd->Data(f); }
380  for (Int_t is=1; is<=GetNsignals(); is++)
381  {
382   ((AliSignal*)GetSignal(is))->Data(f);
383  }
384
385  AliTrack* t=this;
386  Dump(t,1,f); // Information of all decay products
387 }
388 //////////////////////////////////////////////////////////////////////////
389 void AliTrack::Dump(AliTrack* t,Int_t n,TString f)
390 {
391 // Recursively provide the info of all decay levels of this track
392  AliTrack* td; 
393  for (Int_t id=1; id<=t->GetNdecay(); id++)
394  {
395   td=t->GetDecayTrack(id);
396   if (td)
397   {
398    cout << "  ---Level " << n << " sec. track no. " << id << endl;
399    td->Data(f); 
400    for (Int_t is=1; is<=td->GetNsignals(); is++)
401    {
402     ((AliSignal*)td->GetSignal(is))->Data(f);
403    }
404
405    // Go for next decay level of this decay track recursively
406    Dump(td,n+1,f);
407   }
408   else
409   {
410    cout << " *AliTrack::Dump* Error : No decay track present." << endl; 
411   }
412  }
413
414 //////////////////////////////////////////////////////////////////////////
415 Double_t AliTrack::GetMomentum()
416 {
417 // Provide the value of the track 3-momentum.
418 // The error can be obtained by invoking GetResultError() after
419 // invokation of GetMomentum().
420  Double_t norm=fV.GetNorm();
421  fDresult=fV.GetResultError();
422  return norm;
423 }
424 ///////////////////////////////////////////////////////////////////////////
425 Ali3Vector AliTrack::Get3Momentum()
426 {
427 // Provide the track 3-momentum
428  return (Ali3Vector)Get3Vector();
429 }
430 ///////////////////////////////////////////////////////////////////////////
431 Double_t AliTrack::GetMass()
432 {
433 // Provide the particle mass.
434 // The error can be obtained by invoking GetResultError() after
435 // invokation of GetMass().
436  Double_t inv=GetInvariant();
437  Double_t dinv=GetResultError();
438  Double_t dm=0;
439  if (inv >= 0)
440  {
441  Double_t m=sqrt(inv);
442  if (m) dm=dinv/(2.*m);
443  fDresult=dm;
444  return m;
445  }
446  else
447  {
448   cout << "*AliTrack::GetMass* Unphysical situation m**2 = " << inv << endl;
449   cout << " Value 0 will be returned." << endl;
450   fDresult=dm;
451   return 0;
452  }
453 }
454 ///////////////////////////////////////////////////////////////////////////
455 Float_t AliTrack::GetCharge()
456 {
457 // Provide the particle charge
458  return fQ;
459 }
460 ///////////////////////////////////////////////////////////////////////////
461 Double_t AliTrack::GetEnergy()
462 {
463 // Provide the particle's energy.
464 // The error can be obtained by invoking GetResultError() after
465 // invokation of GetEnergy().
466  Double_t E=GetScalar();
467  if (E>0)
468  {
469   return E;
470  }
471  else
472  {
473   cout << "*AliTrack::GetEnergy* Unphysical situation E = " << E << endl;
474   cout << " Value 0 will be returned." << endl;
475   return 0;
476  }
477 }
478 ///////////////////////////////////////////////////////////////////////////
479 void AliTrack::Decay(Double_t m1,Double_t m2,Double_t thcms,Double_t phicms)
480 {
481 // Perform 2-body decay of current track
482 // m1     : mass of decay product 1
483 // m2     : mass of decay product 2
484 // thcms  : cms theta decay angle (in rad.) of m1
485 // phicms : cms phi decay angle (in rad.) of m1
486  
487  fNdec=2; // it's a 2-body decay
488
489  Double_t M=GetMass();
490  
491 // Compute the 4-momenta of the decay products in the cms
492 // Note : p2=p1=pnorm for a 2-body decay
493  Double_t e1=0;
494  if (M) e1=((M*M)+(m1*m1)-(m2*m2))/(2.*M);
495  Double_t e2=0;
496  if (M) e2=((M*M)+(m2*m2)-(m1*m1))/(2.*M);
497  Double_t pnorm=(e1*e1)-(m1*m1);
498  if (pnorm>0.)
499  {
500   pnorm=sqrt(pnorm);
501  }
502  else
503  {
504   pnorm=0;
505  }
506  
507  Double_t a[3];
508  a[0]=pnorm;
509  a[1]=thcms;
510  a[2]=phicms;
511  Ali3Vector p;
512  p.SetVector(a,"sph");
513
514  Ali4Vector pprim1;
515  pprim1.SetVector(e1,p);
516  pprim1.SetInvariant(m1*m1);
517
518  Ali4Vector pprim2;
519  p*=-1;
520  pprim2.SetVector(e2,p);
521  pprim2.SetInvariant(m2*m2);
522
523  // Determine boost parameters from the parent particle
524  Double_t E=GetEnergy();
525  p=Get3Vector();
526  Ali4Vector pmu;
527  pmu.SetVector(E,p);
528
529  AliBoost q;
530  q.Set4Momentum(pmu);
531  
532  Ali4Vector p1=q.Inverse(pprim1); // Boost decay product 1
533  Ali4Vector p2=q.Inverse(pprim2); // Boost decay product 2
534  
535  // Enter the boosted data into the decay tracks array
536  if (fDecays)
537  {
538   delete fDecays;
539   fDecays=0;
540  }
541  fDecays=new TObjArray();
542  fDecays->SetOwner();
543
544  fDecays->Add(new AliTrack);
545  ((AliTrack*)fDecays->At(0))->Set4Momentum(p1);
546  ((AliTrack*)fDecays->At(0))->SetMass(m1);
547  fDecays->Add(new AliTrack);
548  ((AliTrack*)fDecays->At(1))->Set4Momentum(p2);
549  ((AliTrack*)fDecays->At(1))->SetMass(m2);
550 }
551 ///////////////////////////////////////////////////////////////////////////
552 Int_t AliTrack::GetNdecay()
553 {
554 // Provide the number of decay produced tracks
555  return fNdec;
556 }
557 ///////////////////////////////////////////////////////////////////////////
558 AliTrack* AliTrack::GetDecayTrack(Int_t j)
559 {
560 // Provide decay produced track number j
561 // Note : j=1 denotes the first decay track
562  if (!fDecays)
563  {
564   cout << " *AliTrack::GetDecayTrack* No tracks present." << endl;
565   return 0;
566  }
567  else
568  {
569   if ((j >= 1) && (j <= fNdec))
570   {
571    return (AliTrack*)fDecays->At(j-1);
572   }
573   else
574   {
575    cout << " *AliTrack* decay track number : " << j << " out of range."
576         << " Ndec = " << fNdec << endl;
577    return 0;  
578   }
579  }
580 }
581 ///////////////////////////////////////////////////////////////////////////
582 void AliTrack::AddSignal(AliSignal& s)
583 {
584 // Relate an AliSignal object to this track.
585  if (!fSignals) fSignals=new TObjArray();
586  fNsig++;
587  fSignals->Add(&s);
588 }
589 ///////////////////////////////////////////////////////////////////////////
590 void AliTrack::RemoveSignal(AliSignal& s)
591 {
592 // Remove related AliSignal object to this track.
593  if (fSignals)
594  {
595   AliSignal* test=(AliSignal*)fSignals->Remove(&s);
596   if (test)
597   {
598    fNsig--;
599    fSignals->Compress();
600   }
601  }
602 }
603 ///////////////////////////////////////////////////////////////////////////
604 Int_t AliTrack::GetNsignals()
605 {
606 // Provide the number of related AliSignals.
607  return fNsig;
608 }
609 ///////////////////////////////////////////////////////////////////////////
610 AliSignal* AliTrack::GetSignal(Int_t j)
611 {
612 // Provide the related AliSignal number j.
613 // Note : j=1 denotes the first signal.
614  if (!fSignals)
615  {
616   cout << " *AliTrack::GetSignal* No signals present." << endl;
617   return 0;
618  }
619  else
620  {
621   if ((j >= 1) && (j <= fNsig))
622   {
623    return (AliSignal*)fSignals->At(j-1);
624   }
625   else
626   {
627    cout << " *AliTrack* signal number : " << j << " out of range."
628         << " Nsig = " << fNsig << endl;
629    return 0;
630   }
631  }
632 }
633 ///////////////////////////////////////////////////////////////////////////
634 void AliTrack::SetBeginPoint(AliPosition& p)
635 {
636 // Store the position of the track begin-point.
637  if (!fBegin)
638  {
639   fBegin=new AliPositionObj(p);
640  }
641  else
642  {
643   fBegin->Load(p);
644  }
645 }
646 ///////////////////////////////////////////////////////////////////////////
647 AliPosition* AliTrack::GetBeginPoint()
648 {
649 // Provide the position of the track begin-point.
650  return fBegin;
651 }
652 ///////////////////////////////////////////////////////////////////////////
653 void AliTrack::SetEndPoint(AliPosition& p)
654 {
655 // Store the position of the track end-point.
656  if (!fEnd)
657  {
658   fEnd=new AliPositionObj(p);
659  }
660  else
661  {
662   fEnd->Load(p);
663  }
664 }
665 ///////////////////////////////////////////////////////////////////////////
666 AliPosition* AliTrack::GetEndPoint()
667 {
668 // Provide the position of the track end-point.
669  return fEnd;
670 }
671 ///////////////////////////////////////////////////////////////////////////
672 void AliTrack::AddMassHypothesis(Double_t prob,Double_t m,Double_t dm)
673 {
674 // Add a mass hypothesis for this current track.
675 // prob=probalility  m=mass value  dm=error on the mass value.
676 // The default value for the mass error dm is 0.
677  if (!fMasses) fMasses=new TArrayD();
678  if (!fDmasses) fDmasses=new TArrayD();
679  if (!fPmasses) fPmasses=new TArrayD();
680
681  fNmasses++;
682  fMasses->Set(fNmasses);
683  fDmasses->Set(fNmasses);
684  fPmasses->Set(fNmasses);
685
686  fMasses->AddAt(m,fNmasses-1);
687  fDmasses->AddAt(dm,fNmasses-1);
688  fPmasses->AddAt(prob,fNmasses-1);
689 }
690 ///////////////////////////////////////////////////////////////////////////
691 Int_t AliTrack::GetNMassHypotheses()
692 {
693 // Provide the number of mass hypotheses for this track.
694  return fNmasses;
695 }
696 ///////////////////////////////////////////////////////////////////////////
697 Double_t AliTrack::GetMassHypothesis(Int_t j)
698 {
699 // Provide the mass of the jth hypothesis for this track.
700 // Note : the first hypothesis is indicated by j=1.
701 // Default : j=0 ==> Hypothesis with highest probability.
702 // The error on the mass can be obtained by invoking GetResultError()
703 // after invokation of GetMassHypothesis(j).
704
705  Double_t m=0,dm=0,prob=0;
706
707  // Check validity of index j
708  if (j<0 || j>fNmasses)
709  {
710   cout << " *AliTrack::GetMassHypothesis* Invalid index j : " << j
711        << " Number of mass hypotheses : " << fNmasses << endl;
712   fDresult=0;
713   return 0;
714  }
715
716  // Select mass hypothesis with highest probability
717  if (j==0) 
718  {
719   if (fNmasses) 
720   {
721    m=fMasses->At(0);
722    dm=fDmasses->At(0);
723    prob=fPmasses->At(0);
724    for (Int_t i=1; i<fNmasses; i++)
725    {
726     if (fPmasses->At(i)>prob)
727     {
728      m=fMasses->At(i);
729      dm=fDmasses->At(i);
730     }
731    }
732   }
733   fDresult=dm;
734   return m;  
735  }
736
737  // Provide data of requested mass hypothesis
738  m=fMasses->At(j-1);
739  fDresult=fDmasses->At(j-1);
740  return m;
741 }
742 ///////////////////////////////////////////////////////////////////////////
743 Double_t AliTrack::GetMassHypothesisProb(Int_t j)
744 {
745 // Provide the probability of the jth hypothesis for this track.
746 // Note : the first hypothesis is indicated by j=1.
747 // Default : j=0 ==> Hypothesis with highest probability.
748
749  Double_t prob=0;
750
751  // Check validity of index j
752  if (j<0 || j>fNmasses)
753  {
754   cout << " *AliTrack::GetMassHypothesisProb* Invalid index j : " << j
755        << " Number of mass hypotheses : " << fNmasses << endl;
756   return 0;
757  }
758
759  // Select mass hypothesis with highest probability
760  if (j==0) 
761  {
762   if (fNmasses) 
763   {
764    prob=fPmasses->At(0);
765    for (Int_t i=1; i<fNmasses; i++)
766    {
767     if (fPmasses->At(i)>prob) prob=fPmasses->At(i);
768    }
769   }
770   return prob;  
771  }
772
773  // Provide probability of requested mass hypothesis
774  prob=fPmasses->At(j-1);
775  return prob;
776 }
777 ///////////////////////////////////////////////////////////////////////////
778 void AliTrack::SetMass()
779 {
780 // Set the mass and error to the value of the hypothesis with highest prob.
781
782  Double_t m=0,dm=0,prob=0;
783
784  // Select mass hypothesis with highest probability
785  if (fNmasses) 
786  {
787   m=fMasses->At(0);
788   dm=fDmasses->At(0);
789   prob=fPmasses->At(0);
790   for (Int_t i=1; i<fNmasses; i++)
791   {
792    if (fPmasses->At(i)>prob)
793    {
794     m=fMasses->At(i);
795     dm=fDmasses->At(i);
796    }
797   }
798   SetMass(m,dm);
799  }
800  else
801  {
802   cout << " *AliTrack::SetMass()* No hypothesis present => No action." << endl;
803  }
804 }
805 ///////////////////////////////////////////////////////////////////////////
806 void AliTrack::RemoveMassHypothesis(Int_t j)
807 {
808 // Remove the jth mass hypothesis for this track.
809 // Note : the first hypothesis is indicated by j=1.
810
811  if (j<=0 || j>fNmasses) // Check validity of index j
812  {
813   cout << " *AliTrack::RemoveMassHypothesis* Invalid index j : " << j
814        << " Number of mass hypotheses : " << fNmasses << endl;
815  }
816  else
817  {
818   if (j != fNmasses)
819   {
820    fMasses->AddAt(fMasses->At(fNmasses-1),j-1);
821    fDmasses->AddAt(fDmasses->At(fNmasses-1),j-1);
822    fPmasses->AddAt(fPmasses->At(fNmasses-1),j-1);
823   }
824   fMasses->AddAt(0,fNmasses-1);
825   fDmasses->AddAt(0,fNmasses-1);
826   fPmasses->AddAt(0,fNmasses-1);
827   fNmasses--;
828   fMasses->Set(fNmasses);
829   fDmasses->Set(fNmasses);
830   fPmasses->Set(fNmasses);
831  }
832 }
833 ///////////////////////////////////////////////////////////////////////////
834 Double_t AliTrack::GetPt()
835 {
836 // Provide trans. momentum value w.r.t. z-axis.
837 // The error on the value can be obtained by GetResultError()
838 // after invokation of GetPt().
839  Ali3Vector v;
840  v=GetVecTrans();
841  Double_t norm=v.GetNorm();
842  fDresult=v.GetResultError();
843
844  return norm;
845 }
846 ///////////////////////////////////////////////////////////////////////////
847 Double_t AliTrack::GetPl()
848 {
849 // Provide long. momentum value w.r.t. z-axis.
850 // Note : the returned value can also be negative.
851 // The error on the value can be obtained by GetResultError()
852 // after invokation of GetPl().
853  Ali3Vector v;
854  v=GetVecLong();
855
856  Double_t pl=v.GetNorm();
857  fDresult=v.GetResultError();
858
859  Double_t a[3];
860  v.GetVector(a,"sph");
861  if (cos(a[1])<0) pl=-pl;
862
863  return pl;
864 }
865 ///////////////////////////////////////////////////////////////////////////
866 Double_t AliTrack::GetEt()
867 {
868 // Provide trans. energy value w.r.t. z-axis.
869 // The error on the value can be obtained by GetResultError()
870 // after invokation of GetEt().
871  Double_t et=GetScaTrans();
872
873  return et;
874 }
875 ///////////////////////////////////////////////////////////////////////////
876 Double_t AliTrack::GetEl()
877 {
878 // Provide long. energy value w.r.t. z-axis.
879 // Note : the returned value can also be negative.
880 // The error on the value can be obtained by GetResultError()
881 // after invokation of GetEl().
882  Double_t el=GetScaLong();
883
884  return el;
885 }
886 ///////////////////////////////////////////////////////////////////////////
887 Double_t AliTrack::GetMt()
888 {
889 // Provide transverse mass value w.r.t. z-axis.
890 // The error on the value can be obtained by GetResultError()
891 // after invokation of GetMt().
892  Double_t pt=GetPt();
893  Double_t dpt=GetResultError();
894  Double_t m=GetMass();
895  Double_t dm=GetResultError();
896
897  Double_t mt=sqrt(pt*pt+m*m);
898  Double_t dmt2=0;
899  if (mt) dmt2=(pow((pt*dpt),2)+pow((m*dm),2))/(mt*mt);
900
901  fDresult=sqrt(dmt2);
902  return mt;
903 }
904 ///////////////////////////////////////////////////////////////////////////
905 Double_t AliTrack::GetMt(Int_t j)
906 {
907 // Provide transverse mass value w.r.t. z-axis and jth mass hypothesis.
908 // Note : the first hypothesis is indicated by j=1.
909 //        j=0 ==> Hypothesis with highest probability.
910 // The error on the value can be obtained by GetResultError()
911 // after invokation of GetMt(j).
912  Double_t pt=GetPt();
913  Double_t dpt=GetResultError();
914  Double_t m=GetMassHypothesis(j);
915  Double_t dm=GetResultError();
916
917  Double_t mt=sqrt(pt*pt+m*m);
918  Double_t dmt2=0;
919  if (mt) dmt2=(pow((pt*dpt),2)+pow((m*dm),2))/(mt*mt);
920
921  fDresult=sqrt(dmt2);
922  return mt;
923 }
924 ///////////////////////////////////////////////////////////////////////////
925 Double_t AliTrack::GetRapidity()
926 {
927 // Provide rapidity value w.r.t. z-axis.
928 // The error on the value can be obtained by GetResultError()
929 // after invokation of GetRapidity().
930 // Note : Also GetPseudoRapidity() is available since this class is
931 //        derived from Ali4Vector.
932  Double_t e=GetEnergy();
933  Double_t de=GetResultError();
934  Double_t pl=GetPl();
935  Double_t dpl=GetResultError();
936  Double_t sum=e+pl;
937  Double_t dif=e-pl;
938
939  Double_t y=9999,dy2=0;
940  if (sum && dif) y=0.5*log(sum/dif);
941
942  if (sum*dif) dy2=(1./(sum*dif))*(pow((pl*de),2)+pow((e*dpl),2));
943
944  fDresult=sqrt(dy2);
945  return y;
946 }
947 ///////////////////////////////////////////////////////////////////////////
948 void AliTrack::SetImpactPoint(AliPosition& p,TString q)
949 {
950 // Store the position of the impact-point in the plane "q=0".
951 // Here q denotes one of the axes X, Y or Z.
952 // Note : The character to denote the axis may be entered in lower or
953 //        in uppercase.
954  Int_t axis=0;
955  if (q=="x" || q=="X") axis=1;
956  if (q=="y" || q=="Y") axis=2;
957  if (q=="z" || q=="Z") axis=3;
958
959  switch (axis)
960  {
961   case 1: // Impact-point in the plane X=0
962    if (!fImpactYZ)
963    {
964     fImpactYZ=new AliPositionObj(p);
965    }
966    else
967    {
968     fImpactYZ->Load(p);
969    }
970    break;
971
972   case 2: // Impact-point in the plane Y=0
973    if (!fImpactXZ)
974    {
975     fImpactXZ=new AliPositionObj(p);
976    }
977    else
978    {
979     fImpactXZ->Load(p);
980    }
981    break;
982
983   case 3: // Impact-point in the plane Z=0
984    if (!fImpactXY)
985    {
986     fImpactXY=new AliPositionObj(p);
987    }
988    else
989    {
990     fImpactXY->Load(p);
991    }
992    break;
993
994   default: // Unsupported axis
995    cout << "*AliTrack::SetImpactPoint* Unsupported axis : " << q << endl
996         << " Possible axes are 'X', 'Y' and 'Z'." << endl; 
997    break;
998  }
999 }
1000 ///////////////////////////////////////////////////////////////////////////
1001 AliPosition* AliTrack::GetImpactPoint(TString q)
1002 {
1003 // Provide the position of the impact-point in the plane "q=0".
1004 // Here q denotes one of the axes X, Y or Z.
1005 // Note : The character to denote the axis may be entered in lower or
1006 //        in uppercase.
1007  Int_t axis=0;
1008  if (q=="x" || q=="X") axis=1;
1009  if (q=="y" || q=="Y") axis=2;
1010  if (q=="z" || q=="Z") axis=3;
1011
1012  switch (axis)
1013  {
1014   case 1: // Impact-point in the plane X=0
1015    return fImpactYZ;
1016
1017   case 2: // Impact-point in the plane Y=0
1018    return fImpactXZ;
1019
1020   case 3: // Impact-point in the plane Z=0
1021    return fImpactXY;
1022
1023   default: // Unsupported axis
1024    cout << "*AliTrack::GetImpactPoint* Unsupported axis : " << q << endl
1025         << " Possible axes are 'X', 'Y' and 'Z'." << endl; 
1026    return 0;
1027  }
1028 }
1029 ///////////////////////////////////////////////////////////////////////////
1030 void AliTrack::SetId(Int_t id)
1031 {
1032 // Set a user defined unique identifier for this track.
1033  fUserId=id;
1034 }
1035 ///////////////////////////////////////////////////////////////////////////
1036 Int_t AliTrack::GetId()
1037 {
1038 // Provide the user defined unique identifier of this track.
1039  return fUserId;
1040 }
1041 ///////////////////////////////////////////////////////////////////////////
1042 void AliTrack::SetClosestPoint(AliPosition& p)
1043 {
1044 // Set position p as the point of closest approach w.r.t. some reference
1045  if (!fClosest)
1046  {
1047   fClosest=new AliPositionObj(p);
1048  }
1049  else
1050  {
1051   fClosest->Load(p);
1052  }
1053 }
1054 ///////////////////////////////////////////////////////////////////////////
1055 AliPosition* AliTrack::GetClosestPoint()
1056 {
1057 // Provide the point of closest approach w.r.t. some reference
1058  return fClosest;
1059 }
1060 ///////////////////////////////////////////////////////////////////////////
1061 void AliTrack::SetChi2(Float_t chi2)
1062 {
1063 // Set the chi-squared value of the track fit.
1064  if (chi2<0)
1065  {
1066   cout << " *AliTrack::SetChi2* Invalid chi2 value : " << chi2 << endl;
1067  }
1068  else
1069  {
1070   fChi2=chi2;
1071  }
1072 }
1073 ///////////////////////////////////////////////////////////////////////////
1074 void AliTrack::SetNdf(Int_t ndf)
1075 {
1076 // Set the number of degrees of freedom for the track fit.
1077  if (ndf<0)
1078  {
1079   cout << " *AliTrack::SetNdf* Invalid ndf value : " << ndf << endl;
1080  }
1081  else
1082  {
1083   fNdf=ndf;
1084  }
1085 }
1086 ///////////////////////////////////////////////////////////////////////////
1087 Float_t AliTrack::GetChi2()
1088 {
1089 // Provide the chi-squared value of the track fit.
1090  return fChi2;
1091 }
1092 ///////////////////////////////////////////////////////////////////////////
1093 Int_t AliTrack::GetNdf()
1094 {
1095 // Provide the number of degrees of freedom for the track fit.
1096  return fNdf;
1097 }
1098 ///////////////////////////////////////////////////////////////////////////
1099 void AliTrack::SetParticleCode(Int_t code)
1100 {
1101 // Set the user defined particle id code (e.g. the PDF convention).
1102  fCode=code;
1103 }
1104 ///////////////////////////////////////////////////////////////////////////
1105 Int_t AliTrack::GetParticleCode()
1106 {
1107 // Provide the user defined particle id code.
1108  return fCode;
1109 }
1110 ///////////////////////////////////////////////////////////////////////////