]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/AliESDMuonTrack.cxx
#75811 ZDC: changes to be ported to the release
[u/mrichter/AliRoot.git] / STEER / AliESDMuonTrack.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 //
20 /// \class AliESDMuonTrack
21 ///  Class to describe the MUON tracks in the Event Summary Data class
22 ///  This is where the results of reconstruction are stored for the muons
23 ///
24 /// \author G.Martinez
25 //
26 ///////////////////////////////////////////////////////////////////////////////
27
28 #include "AliESDMuonTrack.h"
29 #include "AliESDMuonCluster.h"
30 #include "AliESDEvent.h"
31
32 #include <TClonesArray.h>
33 #include <TLorentzVector.h>
34 #include <TMath.h>
35
36 ClassImp(AliESDMuonTrack)
37
38 //_____________________________________________________________________________
39 AliESDMuonTrack::AliESDMuonTrack ():
40   AliVParticle(),
41   fInverseBendingMomentum(FLT_MAX),
42   fThetaX(0),
43   fThetaY(0),
44   fZ(0),
45   fBendingCoor(0),
46   fNonBendingCoor(0),
47   fInverseBendingMomentumAtDCA(FLT_MAX),
48   fThetaXAtDCA(0),
49   fThetaYAtDCA(0),
50   fBendingCoorAtDCA(0),
51   fNonBendingCoorAtDCA(0),
52   fInverseBendingMomentumUncorrected(FLT_MAX),
53   fThetaXUncorrected(0),
54   fThetaYUncorrected(0),
55   fZUncorrected(0),
56   fBendingCoorUncorrected(0),
57   fNonBendingCoorUncorrected(0),
58   fRAtAbsorberEnd(0),
59   fChi2(0),
60   fChi2MatchTrigger(0),
61   fLocalTrigger(0),
62   fX1Pattern(0),
63   fY1Pattern(0),
64   fX2Pattern(0),
65   fY2Pattern(0),
66   fX3Pattern(0),
67   fY3Pattern(0),
68   fX4Pattern(0),
69   fY4Pattern(0),
70   fMuonClusterMap(0),
71   fHitsPatternInTrigCh(0),
72   fNHit(0),
73   fClusters(0x0),
74   fLabel(-1),
75   fESDEvent(0)
76
77 {
78   //
79   /// Default constructor
80   //
81   for (Int_t i = 0; i < 15; i++) fCovariances[i] = 0;
82 }
83
84
85 //_____________________________________________________________________________
86 AliESDMuonTrack::AliESDMuonTrack (const AliESDMuonTrack& muonTrack):
87   AliVParticle(muonTrack),
88   fInverseBendingMomentum(muonTrack.fInverseBendingMomentum),
89   fThetaX(muonTrack.fThetaX),
90   fThetaY(muonTrack.fThetaY),
91   fZ(muonTrack.fZ),
92   fBendingCoor(muonTrack.fBendingCoor),
93   fNonBendingCoor(muonTrack.fNonBendingCoor),
94   fInverseBendingMomentumAtDCA(muonTrack.fInverseBendingMomentumAtDCA),
95   fThetaXAtDCA(muonTrack.fThetaXAtDCA),
96   fThetaYAtDCA(muonTrack.fThetaYAtDCA),
97   fBendingCoorAtDCA(muonTrack.fBendingCoorAtDCA),
98   fNonBendingCoorAtDCA(muonTrack.fNonBendingCoorAtDCA),
99   fInverseBendingMomentumUncorrected(muonTrack.fInverseBendingMomentumUncorrected),
100   fThetaXUncorrected(muonTrack.fThetaXUncorrected),
101   fThetaYUncorrected(muonTrack.fThetaYUncorrected),
102   fZUncorrected(muonTrack.fZUncorrected),
103   fBendingCoorUncorrected(muonTrack.fBendingCoorUncorrected),
104   fNonBendingCoorUncorrected(muonTrack.fNonBendingCoorUncorrected),
105   fRAtAbsorberEnd(muonTrack.fRAtAbsorberEnd),
106   fChi2(muonTrack.fChi2),
107   fChi2MatchTrigger(muonTrack.fChi2MatchTrigger),
108   fLocalTrigger(muonTrack.fLocalTrigger),
109   fX1Pattern(muonTrack.fX1Pattern),
110   fY1Pattern(muonTrack.fY1Pattern),
111   fX2Pattern(muonTrack.fX2Pattern),
112   fY2Pattern(muonTrack.fY2Pattern),
113   fX3Pattern(muonTrack.fX3Pattern),
114   fY3Pattern(muonTrack.fY3Pattern),
115   fX4Pattern(muonTrack.fX4Pattern),
116   fY4Pattern(muonTrack.fY4Pattern),
117   fMuonClusterMap(muonTrack.fMuonClusterMap),
118   fHitsPatternInTrigCh(muonTrack.fHitsPatternInTrigCh),
119   fNHit(muonTrack.fNHit),
120   fClusters(0x0),
121   fLabel(muonTrack.fLabel),
122   fESDEvent(muonTrack.fESDEvent)
123 {
124   //
125   /// Copy constructor
126   /// Deep copy implemented
127   //
128   for (Int_t i = 0; i < 15; i++) fCovariances[i] = muonTrack.fCovariances[i];
129   
130   // necessary to make a copy of the objects and not only the pointers in TClonesArray
131   if (muonTrack.fClusters) {
132     fClusters = new TClonesArray("AliESDMuonCluster",muonTrack.fClusters->GetEntriesFast());
133     AliESDMuonCluster *cluster = (AliESDMuonCluster*) muonTrack.fClusters->First();
134     while (cluster) {
135       new ((*fClusters)[fClusters->GetEntriesFast()]) AliESDMuonCluster(*cluster);
136       cluster = (AliESDMuonCluster*) muonTrack.fClusters->After(cluster);
137     }
138   }
139 }
140
141 //_____________________________________________________________________________
142 AliESDMuonTrack& AliESDMuonTrack::operator=(const AliESDMuonTrack& muonTrack)
143 {
144   // 
145   /// Equal operator for a deep copy
146   //
147   if (this == &muonTrack)
148     return *this;
149
150   AliVParticle::operator=(muonTrack); // don't forget to invoke the base class' assignment operator
151   
152   fInverseBendingMomentum = muonTrack.fInverseBendingMomentum; 
153   fThetaX                 = muonTrack.fThetaX;           
154   fThetaY                 = muonTrack.fThetaY;           
155   fZ                      = muonTrack.fZ;                
156   fBendingCoor            = muonTrack.fBendingCoor;      
157   fNonBendingCoor         = muonTrack.fNonBendingCoor;   
158   
159   fInverseBendingMomentumAtDCA = muonTrack.fInverseBendingMomentumAtDCA; 
160   fThetaXAtDCA                 = muonTrack.fThetaXAtDCA;           
161   fThetaYAtDCA                 = muonTrack.fThetaYAtDCA;           
162   fBendingCoorAtDCA            = muonTrack.fBendingCoorAtDCA;      
163   fNonBendingCoorAtDCA         = muonTrack.fNonBendingCoorAtDCA;   
164   
165   fInverseBendingMomentumUncorrected = muonTrack.fInverseBendingMomentumUncorrected; 
166   fThetaXUncorrected                 = muonTrack.fThetaXUncorrected;           
167   fThetaYUncorrected                 = muonTrack.fThetaYUncorrected;           
168   fZUncorrected                      = muonTrack.fZUncorrected;                
169   fBendingCoorUncorrected            = muonTrack.fBendingCoorUncorrected;      
170   fNonBendingCoorUncorrected         = muonTrack.fNonBendingCoorUncorrected;   
171   
172   for (Int_t i = 0; i < 15; i++) fCovariances[i] = muonTrack.fCovariances[i];
173   
174   fRAtAbsorberEnd            = muonTrack.fRAtAbsorberEnd;
175   
176   fChi2                   = muonTrack.fChi2;             
177   fNHit                   = muonTrack.fNHit; 
178
179   fLocalTrigger           = muonTrack.fLocalTrigger;  
180   fX1Pattern              = muonTrack.fX1Pattern;  
181   fY1Pattern              = muonTrack.fY1Pattern;  
182   fX2Pattern              = muonTrack.fX2Pattern;  
183   fY2Pattern              = muonTrack.fY2Pattern;  
184   fX3Pattern              = muonTrack.fX3Pattern;  
185   fY3Pattern              = muonTrack.fY3Pattern;  
186   fX4Pattern              = muonTrack.fX4Pattern;  
187   fY4Pattern              = muonTrack.fY4Pattern;  
188   fChi2MatchTrigger       = muonTrack.fChi2MatchTrigger; 
189
190   fHitsPatternInTrigCh    = muonTrack.fHitsPatternInTrigCh;
191  
192   fMuonClusterMap         = muonTrack.fMuonClusterMap;
193
194   fLabel                  = muonTrack.fLabel;
195   
196   fESDEvent               = muonTrack.fESDEvent;
197
198   // necessary to make a copy of the objects and not only the pointers in TClonesArray
199   delete fClusters;
200   if (muonTrack.fClusters) {
201     fClusters = new TClonesArray("AliESDMuonCluster",muonTrack.fClusters->GetEntriesFast());
202     AliESDMuonCluster *cluster = (AliESDMuonCluster*) muonTrack.fClusters->First();
203     while (cluster) {
204       new ((*fClusters)[fClusters->GetEntriesFast()]) AliESDMuonCluster(*cluster);
205       cluster = (AliESDMuonCluster*) muonTrack.fClusters->After(cluster);
206     }
207   } else fClusters = 0x0;
208   
209   return *this;
210 }
211
212 void AliESDMuonTrack::Copy(TObject &obj) const {
213   
214   /// This overwrites the virtual TOBject::Copy()
215   /// to allow run time copying without casting
216   /// in AliESDEvent
217
218   if(this==&obj)return;
219   AliESDMuonTrack *robj = dynamic_cast<AliESDMuonTrack*>(&obj);
220   if(!robj)return; // not an AliESDMuonTrack
221   *robj = *this;
222
223 }
224
225
226 //__________________________________________________________________________
227 AliESDMuonTrack::~AliESDMuonTrack()
228 {
229   /// Destructor
230   delete fClusters;
231 }
232
233 //__________________________________________________________________________
234 void AliESDMuonTrack::Clear(Option_t* opt)
235 {
236   /// Clear arrays
237   if (fClusters) fClusters->Clear(opt);
238 }
239
240 //__________________________________________________________________________
241 void AliESDMuonTrack::Reset()
242 {
243   /// Reset to default values
244   SetUniqueID(0);
245   fInverseBendingMomentum = FLT_MAX;
246   fThetaX = 0.;
247   fThetaY = 0.;
248   fZ = 0.;
249   fBendingCoor = 0.;
250   fNonBendingCoor = 0.;
251   fInverseBendingMomentumAtDCA = FLT_MAX;
252   fThetaXAtDCA = 0.;
253   fThetaYAtDCA = 0.;
254   fBendingCoorAtDCA = 0.;
255   fNonBendingCoorAtDCA = 0.;
256   fInverseBendingMomentumUncorrected = FLT_MAX;
257   fThetaXUncorrected = 0.;
258   fThetaYUncorrected = 0.;
259   fZUncorrected = 0.;
260   fBendingCoorUncorrected = 0.;
261   fNonBendingCoorUncorrected = 0.;
262   fRAtAbsorberEnd = 0.;
263   fChi2 = 0.;
264   fChi2MatchTrigger = 0.;
265   fLocalTrigger = 0;
266   fX1Pattern = 0;
267   fY1Pattern = 0;
268   fX2Pattern = 0;
269   fY2Pattern = 0;
270   fX3Pattern = 0;
271   fY3Pattern = 0;
272   fX4Pattern = 0;
273   fY4Pattern = 0;
274   fMuonClusterMap = 0;
275   fHitsPatternInTrigCh = 0;
276   fNHit = 0;
277   delete fClusters; fClusters = 0x0;
278   for (Int_t i = 0; i < 15; i++) fCovariances[i] = 0.;
279   fLabel = -1;
280   fESDEvent = 0;
281 }
282
283 //_____________________________________________________________________________
284 void AliESDMuonTrack::GetCovariances(TMatrixD& cov) const
285 {
286   /// return covariance matrix of uncorrected parameters
287   cov.ResizeTo(5,5);
288   for (Int_t i = 0; i < 5; i++)
289     for (Int_t j = 0; j <= i; j++)
290       cov(i,j) = cov (j,i) = fCovariances[i*(i+1)/2 + j];
291 }
292
293 //_____________________________________________________________________________
294 void AliESDMuonTrack::SetCovariances(const TMatrixD& cov)
295 {
296   /// set reduced covariance matrix of uncorrected parameters
297   for (Int_t i = 0; i < 5; i++)
298     for (Int_t j = 0; j <= i; j++)
299       fCovariances[i*(i+1)/2 + j] = cov(i,j);
300
301 }
302
303 //_____________________________________________________________________________
304 void AliESDMuonTrack::GetCovarianceXYZPxPyPz(Double_t cov[21]) const
305 {
306   /// return reduced covariance matrix of uncorrected parameters in (X,Y,Z,Px,Py,Pz) coordinate system
307   /// 
308   /// - Cov(x,x) ... :   cov[0]
309   /// - Cov(y,x) ... :   cov[1]  cov[2]
310   /// - Cov(z,x) ... :   cov[3]  cov[4]  cov[5]
311   /// - Cov(px,x)... :   cov[6]  cov[7]  cov[8]  cov[9]
312   /// - Cov(py,x)... :   cov[10] cov[11] cov[12] cov[13] cov[14]
313   /// - Cov(pz,x)... :   cov[15] cov[16] cov[17] cov[18] cov[19] cov[20]
314   ///
315   /// Get ESD covariance matrix into a TMatrixD
316   TMatrixD covESD(5,5);
317   GetCovariances(covESD);
318
319   // compute Jacobian to change the coordinate system
320   // from (X,thetaX,Y,thetaY,c/pYZ) to (X,Y,Z,pX,pY,pZ)
321   Double_t tanThetaX = TMath::Tan(fThetaXUncorrected);
322   Double_t tanThetaY = TMath::Tan(fThetaYUncorrected);
323   Double_t cosThetaX2 = TMath::Cos(fThetaXUncorrected) * TMath::Cos(fThetaXUncorrected);
324   Double_t cosThetaY2 = TMath::Cos(fThetaYUncorrected) * TMath::Cos(fThetaYUncorrected);
325   Double_t pZ = PzUncorrected();
326   Double_t dpZdthetaY = - fInverseBendingMomentumUncorrected * fInverseBendingMomentumUncorrected *
327                           pZ * pZ * pZ * tanThetaY / cosThetaY2;
328   Double_t dpZdinvpYZ = (fInverseBendingMomentumUncorrected != 0.) ? - pZ / fInverseBendingMomentumUncorrected : - FLT_MAX;
329   TMatrixD jacob(6,5);
330   jacob.Zero();
331   jacob(0,0) = 1.;
332   jacob(1,2) = 1.;
333   jacob(3,1) = pZ / cosThetaX2;
334   jacob(3,3) = dpZdthetaY * tanThetaX;
335   jacob(3,4) = dpZdinvpYZ * tanThetaX;
336   jacob(4,3) = dpZdthetaY * tanThetaY + pZ / cosThetaY2;
337   jacob(4,4) = dpZdinvpYZ * tanThetaY;
338   jacob(5,3) = dpZdthetaY;
339   jacob(5,4) = dpZdinvpYZ;
340   
341   // compute covariance matrix in AOD coordinate system
342   TMatrixD tmp(covESD,TMatrixD::kMultTranspose,jacob);
343   TMatrixD covAOD(jacob,TMatrixD::kMult,tmp);
344   
345   // Get AOD covariance matrix into co[21]
346   for (Int_t i = 0; i < 6; i++)
347     for (Int_t j = 0; j <= i; j++)
348       cov[i*(i+1)/2 + j] = covAOD(i,j);
349   
350 }
351
352 //_____________________________________________________________________________
353 Double_t AliESDMuonTrack::Px() const
354 {
355   /// return p_x from track parameters
356   Double_t nonBendingSlope = TMath::Tan(fThetaX);
357   Double_t bendingSlope    = TMath::Tan(fThetaY);
358   Double_t pYZ = (fInverseBendingMomentum != 0.) ? TMath::Abs(1. / fInverseBendingMomentum) : - FLT_MAX;
359   Double_t pZ  = -pYZ / TMath::Sqrt(1.0 + bendingSlope*bendingSlope);  // spectro. (z<0)
360   return pZ * nonBendingSlope;
361 }
362
363 //_____________________________________________________________________________
364 Double_t AliESDMuonTrack::Py() const
365 {
366   /// return p_y from track parameters
367   Double_t bendingSlope = TMath::Tan(fThetaY);
368   Double_t pYZ = (fInverseBendingMomentum != 0.) ? TMath::Abs(1. / fInverseBendingMomentum) : - FLT_MAX;
369   Double_t pZ  = -pYZ / TMath::Sqrt(1.0 + bendingSlope*bendingSlope);  // spectro. (z<0)
370   return pZ * bendingSlope;
371 }
372
373 //_____________________________________________________________________________
374 Double_t AliESDMuonTrack::Pz() const
375 {
376   /// return p_z from track parameters
377   Double_t bendingSlope = TMath::Tan(fThetaY);
378   Double_t pYZ = (fInverseBendingMomentum != 0.) ? TMath::Abs(1. / fInverseBendingMomentum) : - FLT_MAX;
379   return -pYZ / TMath::Sqrt(1.0 + bendingSlope*bendingSlope);  // spectro. (z<0)
380 }
381
382 //_____________________________________________________________________________
383 Double_t AliESDMuonTrack::P() const
384 {
385   /// return p from track parameters
386   Double_t nonBendingSlope = TMath::Tan(fThetaX);
387   Double_t bendingSlope    = TMath::Tan(fThetaY);
388   Double_t pYZ = (fInverseBendingMomentum != 0.) ? TMath::Abs(1. / fInverseBendingMomentum) : - FLT_MAX;
389   Double_t pZ  = -pYZ / TMath::Sqrt(1.0 + bendingSlope*bendingSlope);  // spectro. (z<0)
390   return -pZ * TMath::Sqrt(1.0 + bendingSlope*bendingSlope + nonBendingSlope*nonBendingSlope);
391 }
392
393 //_____________________________________________________________________________
394 void AliESDMuonTrack::LorentzP(TLorentzVector& vP) const
395 {
396   /// return Lorentz momentum vector from track parameters
397   Double_t muonMass = M();
398   Double_t nonBendingSlope = TMath::Tan(fThetaX);
399   Double_t bendingSlope    = TMath::Tan(fThetaY);
400   Double_t pYZ = (fInverseBendingMomentum != 0.) ? TMath::Abs(1. / fInverseBendingMomentum) : - FLT_MAX;
401   Double_t pZ  = -pYZ / TMath::Sqrt(1.0 + bendingSlope*bendingSlope);  // spectro. (z<0)
402   Double_t pX  = pZ * nonBendingSlope;
403   Double_t pY  = pZ * bendingSlope;
404   Double_t e   = TMath::Sqrt(muonMass*muonMass + pX*pX + pY*pY + pZ*pZ);
405   vP.SetPxPyPzE(pX, pY, pZ, e);
406 }
407
408 //_____________________________________________________________________________
409 Double_t AliESDMuonTrack::PxAtDCA() const
410 {
411   /// return p_x from track parameters
412   Double_t nonBendingSlope = TMath::Tan(fThetaXAtDCA);
413   Double_t bendingSlope    = TMath::Tan(fThetaYAtDCA);
414   Double_t pYZ = (fInverseBendingMomentumAtDCA != 0.) ? TMath::Abs(1. / fInverseBendingMomentumAtDCA) : - FLT_MAX;
415   Double_t pZ  = -pYZ / TMath::Sqrt(1.0 + bendingSlope*bendingSlope);  // spectro. (z<0)
416   return pZ * nonBendingSlope;
417 }
418
419 //_____________________________________________________________________________
420 Double_t AliESDMuonTrack::PyAtDCA() const
421 {
422   /// return p_y from track parameters
423   Double_t bendingSlope = TMath::Tan(fThetaYAtDCA);
424   Double_t pYZ = (fInverseBendingMomentumAtDCA != 0.) ? TMath::Abs(1. / fInverseBendingMomentumAtDCA) : - FLT_MAX;
425   Double_t pZ  = -pYZ / TMath::Sqrt(1.0 + bendingSlope*bendingSlope);  // spectro. (z<0)
426   return pZ * bendingSlope;
427 }
428
429 //_____________________________________________________________________________
430 Double_t AliESDMuonTrack::PzAtDCA() const
431 {
432   /// return p_z from track parameters
433   Double_t bendingSlope = TMath::Tan(fThetaYAtDCA);
434   Double_t pYZ = (fInverseBendingMomentumAtDCA != 0.) ? TMath::Abs(1. / fInverseBendingMomentumAtDCA) : - FLT_MAX;
435   return -pYZ / TMath::Sqrt(1.0 + bendingSlope*bendingSlope);  // spectro. (z<0)
436 }
437
438 //_____________________________________________________________________________
439 Double_t AliESDMuonTrack::PAtDCA() const
440 {
441   /// return p from track parameters
442   Double_t nonBendingSlope = TMath::Tan(fThetaXAtDCA);
443   Double_t bendingSlope    = TMath::Tan(fThetaYAtDCA);
444   Double_t pYZ = (fInverseBendingMomentumAtDCA != 0.) ? TMath::Abs(1. / fInverseBendingMomentumAtDCA) : - FLT_MAX;
445   Double_t pZ  = -pYZ / TMath::Sqrt(1.0 + bendingSlope*bendingSlope);  // spectro. (z<0)
446   return -pZ * TMath::Sqrt(1.0 + bendingSlope*bendingSlope + nonBendingSlope*nonBendingSlope);
447 }
448
449 //_____________________________________________________________________________
450 void AliESDMuonTrack::LorentzPAtDCA(TLorentzVector& vP) const
451 {
452   /// return Lorentz momentum vector from track parameters
453   Double_t muonMass = M();
454   Double_t nonBendingSlope = TMath::Tan(fThetaXAtDCA);
455   Double_t bendingSlope    = TMath::Tan(fThetaYAtDCA);
456   Double_t pYZ = (fInverseBendingMomentumAtDCA != 0.) ? TMath::Abs(1. / fInverseBendingMomentumAtDCA) : - FLT_MAX;
457   Double_t pZ  = -pYZ / TMath::Sqrt(1.0 + bendingSlope*bendingSlope);  // spectro. (z<0)
458   Double_t pX  = pZ * nonBendingSlope;
459   Double_t pY  = pZ * bendingSlope;
460   Double_t e   = TMath::Sqrt(muonMass*muonMass + pX*pX + pY*pY + pZ*pZ);
461   vP.SetPxPyPzE(pX, pY, pZ, e);
462 }
463
464 //_____________________________________________________________________________
465 Double_t AliESDMuonTrack::PxUncorrected() const
466 {
467   /// return p_x from track parameters
468   Double_t nonBendingSlope = TMath::Tan(fThetaXUncorrected);
469   Double_t bendingSlope    = TMath::Tan(fThetaYUncorrected);
470   Double_t pYZ = (fInverseBendingMomentumUncorrected != 0.) ? TMath::Abs(1. / fInverseBendingMomentumUncorrected) : - FLT_MAX;
471   Double_t pZ  = -pYZ / TMath::Sqrt(1.0 + bendingSlope*bendingSlope);  // spectro. (z<0)
472   return pZ * nonBendingSlope;
473 }
474
475 //_____________________________________________________________________________
476 Double_t AliESDMuonTrack::PyUncorrected() const
477 {
478   /// return p_y from track parameters
479   Double_t bendingSlope = TMath::Tan(fThetaYUncorrected);
480   Double_t pYZ = (fInverseBendingMomentumUncorrected != 0.) ? TMath::Abs(1. / fInverseBendingMomentumUncorrected) : - FLT_MAX;
481   Double_t pZ  = -pYZ / TMath::Sqrt(1.0 + bendingSlope*bendingSlope);  // spectro. (z<0)
482   return pZ * bendingSlope;
483 }
484
485 //_____________________________________________________________________________
486 Double_t AliESDMuonTrack::PzUncorrected() const
487 {
488   /// return p_z from track parameters
489   Double_t bendingSlope = TMath::Tan(fThetaYUncorrected);
490   Double_t pYZ = (fInverseBendingMomentumUncorrected != 0.) ? TMath::Abs(1. / fInverseBendingMomentumUncorrected) : - FLT_MAX;
491   return -pYZ / TMath::Sqrt(1.0 + bendingSlope*bendingSlope);  // spectro. (z<0)
492 }
493
494 //_____________________________________________________________________________
495 Double_t AliESDMuonTrack::PUncorrected() const
496 {
497   /// return p from track parameters
498   Double_t nonBendingSlope = TMath::Tan(fThetaXUncorrected);
499   Double_t bendingSlope    = TMath::Tan(fThetaYUncorrected);
500   Double_t pYZ = (fInverseBendingMomentumUncorrected != 0.) ? TMath::Abs(1. / fInverseBendingMomentumUncorrected) : - FLT_MAX;
501   Double_t pZ  = -pYZ / TMath::Sqrt(1.0 + bendingSlope*bendingSlope);  // spectro. (z<0)
502   return -pZ * TMath::Sqrt(1.0 + bendingSlope*bendingSlope + nonBendingSlope*nonBendingSlope);
503 }
504
505 //_____________________________________________________________________________
506 void AliESDMuonTrack::LorentzPUncorrected(TLorentzVector& vP) const
507 {
508   /// return Lorentz momentum vector from track parameters
509   Double_t muonMass = M();
510   Double_t nonBendingSlope = TMath::Tan(fThetaXUncorrected);
511   Double_t bendingSlope    = TMath::Tan(fThetaYUncorrected);
512   Double_t pYZ = (fInverseBendingMomentumUncorrected != 0.) ? TMath::Abs(1. / fInverseBendingMomentumUncorrected) : - FLT_MAX;
513   Double_t pZ  = -pYZ / TMath::Sqrt(1.0 + bendingSlope*bendingSlope);  // spectro. (z<0)
514   Double_t pX  = pZ * nonBendingSlope;
515   Double_t pY  = pZ * bendingSlope;
516   Double_t e   = TMath::Sqrt(muonMass*muonMass + pX*pX + pY*pY + pZ*pZ);
517   vP.SetPxPyPzE(pX, pY, pZ, e);
518 }
519
520 //_____________________________________________________________________________
521 Int_t AliESDMuonTrack::GetNDF() const
522 {
523   /// return the number of degrees of freedom
524   
525   Int_t ndf = 2 * static_cast<Int_t>(fNHit) - 5;
526   return (ndf > 0) ? ndf : 0;
527 }
528
529 //_____________________________________________________________________________
530 Double_t AliESDMuonTrack::GetNormalizedChi2() const
531 {
532   /// return the chi2 value divided by the number of degrees of freedom
533   
534   Int_t ndf = GetNDF();
535   return (ndf > 0) ? fChi2 / static_cast<Double_t>(ndf) : 0.;
536 }
537
538 //_____________________________________________________________________________
539 Int_t AliESDMuonTrack::GetMatchTrigger() const
540 {
541   ///  backward compatibility after replacing fMatchTrigger by fLocalTrigger
542   ///  - 0 track does not match trigger
543   ///  - 1 track match but does not pass pt cut
544   ///  - 2 track match Low pt cut
545   ///  - 3 track match High pt cut
546
547   if (!LoCircuit()) {
548     return 0;
549   } else if (LoLpt() == 0 && LoHpt() == 0) {
550     return 1;
551   } else if (LoLpt() >  0 && LoHpt() == 0) {
552     return 2;
553   } else {
554     return 3;
555   }
556
557 }
558
559 //_____________________________________________________________________________
560 Bool_t AliESDMuonTrack::MatchTriggerDigits() const
561 {
562   // return kTRUE if the track matches a digit on both planes of at least 2 trigger chambers
563   
564   Int_t nMatchedChambers = 0;
565   for (Int_t ich=0; ich<4; ich++)
566     if (IsChamberHit(fHitsPatternInTrigCh, 0, ich) &&
567         IsChamberHit(fHitsPatternInTrigCh, 1, ich)) nMatchedChambers++;
568   
569   return (nMatchedChambers >= 2);
570 }
571
572 //_____________________________________________________________________________
573 Int_t AliESDMuonTrack::GetNClusters() const
574 {
575   /// return the number of clusters associated to the track
576   if (!fClusters) return 0;
577   
578   return fClusters->GetEntriesFast();
579 }
580
581 //_____________________________________________________________________________
582 TClonesArray& AliESDMuonTrack::GetClusters() const
583 {
584   /// return the array of clusters associated to the track
585   if (!fClusters) fClusters = new TClonesArray("AliESDMuonCluster",10);
586   
587   return *fClusters;
588 }
589
590 //_____________________________________________________________________________
591 void AliESDMuonTrack::AddCluster(const AliESDMuonCluster &cluster)
592 {
593   /// add a cluster to the TClonesArray of clusters associated to the track
594   if (!fClusters) fClusters = new TClonesArray("AliESDMuonCluster",10);
595   
596   new ((*fClusters)[fClusters->GetEntriesFast()]) AliESDMuonCluster(cluster);
597 }
598
599 //_____________________________________________________________________________
600 Bool_t AliESDMuonTrack::ClustersStored() const
601 {
602   /// return kTRUE if the clusters associated to the track are registered
603   if (GetNClusters() == 0) return kFALSE;
604   
605   return kTRUE;
606 }
607
608 //_____________________________________________________________________________
609 void AliESDMuonTrack::SetFiredChamber(UShort_t& pattern, Int_t cathode, Int_t chamber)
610 {
611   /// Turn on the bit corresponding to fired chameber
612   pattern |= (0x1 << ( 7 - ( 4*cathode + chamber )));
613 }
614
615 //_____________________________________________________________________________
616 void AliESDMuonTrack::AddEffInfo(UShort_t& pattern, Int_t slatOrInfo, EAliTriggerChPatternFlag effType)
617 {
618   /// Add efficiency flag and crossed RPC or info on rejected track
619   pattern |= effType << 8;
620   pattern |= slatOrInfo << 10;
621 }
622
623 //_____________________________________________________________________________
624 Bool_t AliESDMuonTrack::IsChamberHit(UShort_t pattern, Int_t cathode, Int_t chamber)
625
626   /// Check if chamber was was hit
627   return (pattern >> (7 - ( 4*cathode + chamber ))) & 0x1;
628 }
629
630 //_____________________________________________________________________________
631 Int_t AliESDMuonTrack::GetEffFlag(UShort_t pattern)
632 {
633   /// Get Efficiency flag
634   return (pattern >> 8) & 0x03;
635 }
636
637 //_____________________________________________________________________________
638 Int_t AliESDMuonTrack::GetSlatOrInfo(UShort_t pattern) 
639 {
640   /// Getting crossed slat or info
641   return (pattern >> 10) & 0x1F;
642 }