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