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