1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
18 ///////////////////////////////////////////////////////////////////////////////
20 // Class to describe the MUON tracks
21 // in the Event Summary Data class
22 // This is where the results of reconstruction
23 // are stored for the muons
26 ///////////////////////////////////////////////////////////////////////////////
28 #include "AliESDMuonTrack.h"
29 #include "AliESDMuonCluster.h"
31 #include <TClonesArray.h>
32 #include <TLorentzVector.h>
35 ClassImp(AliESDMuonTrack)
37 //_____________________________________________________________________________
38 AliESDMuonTrack::AliESDMuonTrack ():
40 fInverseBendingMomentum(0),
46 fInverseBendingMomentumAtDCA(0),
50 fNonBendingCoorAtDCA(0),
51 fInverseBendingMomentumUncorrected(0),
52 fThetaXUncorrected(0),
53 fThetaYUncorrected(0),
55 fBendingCoorUncorrected(0),
56 fNonBendingCoorUncorrected(0),
61 fHitsPatternInTrigCh(0),
66 // Default constructor
68 for (Int_t i = 0; i < 15; i++) fCovariances[i] = 0;
72 //_____________________________________________________________________________
73 AliESDMuonTrack::AliESDMuonTrack (const AliESDMuonTrack& muonTrack):
74 AliVParticle(muonTrack),
75 fInverseBendingMomentum(muonTrack.fInverseBendingMomentum),
76 fThetaX(muonTrack.fThetaX),
77 fThetaY(muonTrack.fThetaY),
79 fBendingCoor(muonTrack.fBendingCoor),
80 fNonBendingCoor(muonTrack.fNonBendingCoor),
81 fInverseBendingMomentumAtDCA(muonTrack.fInverseBendingMomentumAtDCA),
82 fThetaXAtDCA(muonTrack.fThetaXAtDCA),
83 fThetaYAtDCA(muonTrack.fThetaYAtDCA),
84 fBendingCoorAtDCA(muonTrack.fBendingCoorAtDCA),
85 fNonBendingCoorAtDCA(muonTrack.fNonBendingCoorAtDCA),
86 fInverseBendingMomentumUncorrected(muonTrack.fInverseBendingMomentumUncorrected),
87 fThetaXUncorrected(muonTrack.fThetaXUncorrected),
88 fThetaYUncorrected(muonTrack.fThetaYUncorrected),
89 fZUncorrected(muonTrack.fZUncorrected),
90 fBendingCoorUncorrected(muonTrack.fBendingCoorUncorrected),
91 fNonBendingCoorUncorrected(muonTrack.fNonBendingCoorUncorrected),
92 fChi2(muonTrack.fChi2),
93 fChi2MatchTrigger(muonTrack.fChi2MatchTrigger),
94 fLocalTrigger(muonTrack.fLocalTrigger),
95 fMuonClusterMap(muonTrack.fMuonClusterMap),
96 fHitsPatternInTrigCh(muonTrack.fHitsPatternInTrigCh),
97 fNHit(muonTrack.fNHit),
102 // Deep copy implemented
104 for (Int_t i = 0; i < 15; i++) fCovariances[i] = muonTrack.fCovariances[i];
106 // necessary to make a copy of the objects and not only the pointers in TClonesArray
107 if (muonTrack.fClusters) {
108 fClusters = new TClonesArray("AliESDMuonCluster",muonTrack.fClusters->GetEntriesFast());
109 AliESDMuonCluster *cluster = (AliESDMuonCluster*) muonTrack.fClusters->First();
111 new ((*fClusters)[fClusters->GetEntriesFast()]) AliESDMuonCluster(*cluster);
112 cluster = (AliESDMuonCluster*) muonTrack.fClusters->After(cluster);
117 //_____________________________________________________________________________
118 AliESDMuonTrack& AliESDMuonTrack::operator=(const AliESDMuonTrack& muonTrack)
121 // Equal operator for a deep copy
123 if (this == &muonTrack)
126 AliVParticle::operator=(muonTrack); // don't forget to invoke the base class' assignment operator
128 fInverseBendingMomentum = muonTrack.fInverseBendingMomentum;
129 fThetaX = muonTrack.fThetaX;
130 fThetaY = muonTrack.fThetaY;
132 fBendingCoor = muonTrack.fBendingCoor;
133 fNonBendingCoor = muonTrack.fNonBendingCoor;
135 fInverseBendingMomentumAtDCA = muonTrack.fInverseBendingMomentumAtDCA;
136 fThetaXAtDCA = muonTrack.fThetaXAtDCA;
137 fThetaYAtDCA = muonTrack.fThetaYAtDCA;
138 fBendingCoorAtDCA = muonTrack.fBendingCoorAtDCA;
139 fNonBendingCoorAtDCA = muonTrack.fNonBendingCoorAtDCA;
141 fInverseBendingMomentumUncorrected = muonTrack.fInverseBendingMomentumUncorrected;
142 fThetaXUncorrected = muonTrack.fThetaXUncorrected;
143 fThetaYUncorrected = muonTrack.fThetaYUncorrected;
144 fZUncorrected = muonTrack.fZUncorrected;
145 fBendingCoorUncorrected = muonTrack.fBendingCoorUncorrected;
146 fNonBendingCoorUncorrected = muonTrack.fNonBendingCoorUncorrected;
148 for (Int_t i = 0; i < 15; i++) fCovariances[i] = muonTrack.fCovariances[i];
150 fChi2 = muonTrack.fChi2;
151 fNHit = muonTrack.fNHit;
153 fLocalTrigger = muonTrack.fLocalTrigger;
154 fChi2MatchTrigger = muonTrack.fChi2MatchTrigger;
156 fHitsPatternInTrigCh = muonTrack.fHitsPatternInTrigCh;
158 fMuonClusterMap = muonTrack.fMuonClusterMap;
160 // necessary to make a copy of the objects and not only the pointers in TClonesArray
162 if (muonTrack.fClusters) {
163 fClusters = new TClonesArray("AliESDMuonCluster",muonTrack.fClusters->GetEntriesFast());
164 AliESDMuonCluster *cluster = (AliESDMuonCluster*) muonTrack.fClusters->First();
166 new ((*fClusters)[fClusters->GetEntriesFast()]) AliESDMuonCluster(*cluster);
167 cluster = (AliESDMuonCluster*) muonTrack.fClusters->After(cluster);
169 } else fClusters = 0x0;
174 //__________________________________________________________________________
175 AliESDMuonTrack::~AliESDMuonTrack()
181 //__________________________________________________________________________
182 void AliESDMuonTrack::Clear(Option_t* opt)
185 if (fClusters) fClusters->Clear(opt);
188 //_____________________________________________________________________________
189 void AliESDMuonTrack::GetCovariances(TMatrixD& cov) const
191 // return covariance matrix of uncorrected parameters
193 for (Int_t i = 0; i < 5; i++)
194 for (Int_t j = 0; j <= i; j++)
195 cov(i,j) = cov (j,i) = fCovariances[i*(i+1)/2 + j];
198 //_____________________________________________________________________________
199 void AliESDMuonTrack::SetCovariances(const TMatrixD& cov)
201 // set reduced covariance matrix of uncorrected parameters
202 for (Int_t i = 0; i < 5; i++)
203 for (Int_t j = 0; j <= i; j++)
204 fCovariances[i*(i+1)/2 + j] = cov(i,j);
208 //_____________________________________________________________________________
209 void AliESDMuonTrack::GetCovarianceXYZPxPyPz(Double_t cov[21]) const
211 // return reduced covariance matrix of uncorrected parameters in (X,Y,Z,Px,Py,Pz) coordinate system
213 // Cov(x,x) ... : cov[0]
214 // Cov(y,x) ... : cov[1] cov[2]
215 // Cov(z,x) ... : cov[3] cov[4] cov[5]
216 // Cov(px,x)... : cov[6] cov[7] cov[8] cov[9]
217 // Cov(py,x)... : cov[10] cov[11] cov[12] cov[13] cov[14]
218 // Cov(pz,x)... : cov[15] cov[16] cov[17] cov[18] cov[19] cov[20]
220 // Get ESD covariance matrix into a TMatrixD
221 TMatrixD covESD(5,5);
222 GetCovariances(covESD);
224 // compute Jacobian to change the coordinate system
225 // from (X,thetaX,Y,thetaY,c/pYZ) to (X,Y,Z,pX,pY,pZ)
226 Double_t tanThetaX = TMath::Tan(fThetaXUncorrected);
227 Double_t tanThetaY = TMath::Tan(fThetaYUncorrected);
228 Double_t cosThetaX2 = TMath::Cos(fThetaXUncorrected) * TMath::Cos(fThetaXUncorrected);
229 Double_t cosThetaY2 = TMath::Cos(fThetaYUncorrected) * TMath::Cos(fThetaYUncorrected);
230 Double_t pZ = PzUncorrected();
231 Double_t dpZdthetaY = - fInverseBendingMomentumUncorrected * fInverseBendingMomentumUncorrected *
232 pZ * pZ * pZ * tanThetaY / cosThetaY2;
233 Double_t dpZdinvpYZ = (fInverseBendingMomentumUncorrected != 0.) ? - pZ / fInverseBendingMomentumUncorrected : - FLT_MAX;
238 jacob(3,1) = pZ / cosThetaX2;
239 jacob(3,3) = dpZdthetaY * tanThetaX;
240 jacob(3,4) = dpZdinvpYZ * tanThetaX;
241 jacob(4,3) = dpZdthetaY * tanThetaY + pZ / cosThetaY2;
242 jacob(4,4) = dpZdinvpYZ * tanThetaY;
243 jacob(5,3) = dpZdthetaY;
244 jacob(5,4) = dpZdinvpYZ;
246 // compute covariance matrix in AOD coordinate system
247 TMatrixD tmp(covESD,TMatrixD::kMultTranspose,jacob);
248 TMatrixD covAOD(jacob,TMatrixD::kMult,tmp);
250 // Get AOD covariance matrix into co[21]
251 for (Int_t i = 0; i < 6; i++)
252 for (Int_t j = 0; j <= i; j++)
253 cov[i*(i+1)/2 + j] = covAOD(i,j);
257 //_____________________________________________________________________________
258 Double_t AliESDMuonTrack::Px() const
260 // return p_x from track parameters
261 Double_t nonBendingSlope = TMath::Tan(fThetaX);
262 Double_t bendingSlope = TMath::Tan(fThetaY);
263 Double_t pYZ = (fInverseBendingMomentum != 0.) ? TMath::Abs(1. / fInverseBendingMomentum) : - FLT_MAX;
264 Double_t pZ = -pYZ / TMath::Sqrt(1.0 + bendingSlope*bendingSlope); // spectro. (z<0)
265 return pZ * nonBendingSlope;
268 //_____________________________________________________________________________
269 Double_t AliESDMuonTrack::Py() const
271 // return p_y from track parameters
272 Double_t bendingSlope = TMath::Tan(fThetaY);
273 Double_t pYZ = (fInverseBendingMomentum != 0.) ? TMath::Abs(1. / fInverseBendingMomentum) : - FLT_MAX;
274 Double_t pZ = -pYZ / TMath::Sqrt(1.0 + bendingSlope*bendingSlope); // spectro. (z<0)
275 return pZ * bendingSlope;
278 //_____________________________________________________________________________
279 Double_t AliESDMuonTrack::Pz() const
281 // return p_z from track parameters
282 Double_t bendingSlope = TMath::Tan(fThetaY);
283 Double_t pYZ = (fInverseBendingMomentum != 0.) ? TMath::Abs(1. / fInverseBendingMomentum) : - FLT_MAX;
284 return -pYZ / TMath::Sqrt(1.0 + bendingSlope*bendingSlope); // spectro. (z<0)
287 //_____________________________________________________________________________
288 Double_t AliESDMuonTrack::P() const
290 // return p from track parameters
291 Double_t nonBendingSlope = TMath::Tan(fThetaX);
292 Double_t bendingSlope = TMath::Tan(fThetaY);
293 Double_t pYZ = (fInverseBendingMomentum != 0.) ? TMath::Abs(1. / fInverseBendingMomentum) : - FLT_MAX;
294 Double_t pZ = -pYZ / TMath::Sqrt(1.0 + bendingSlope*bendingSlope); // spectro. (z<0)
295 return -pZ * TMath::Sqrt(1.0 + bendingSlope*bendingSlope + nonBendingSlope*nonBendingSlope);
298 //_____________________________________________________________________________
299 void AliESDMuonTrack::LorentzP(TLorentzVector& vP) const
301 // return Lorentz momentum vector from track parameters
302 Double_t muonMass = M();
303 Double_t nonBendingSlope = TMath::Tan(fThetaX);
304 Double_t bendingSlope = TMath::Tan(fThetaY);
305 Double_t pYZ = (fInverseBendingMomentum != 0.) ? TMath::Abs(1. / fInverseBendingMomentum) : - FLT_MAX;
306 Double_t pZ = -pYZ / TMath::Sqrt(1.0 + bendingSlope*bendingSlope); // spectro. (z<0)
307 Double_t pX = pZ * nonBendingSlope;
308 Double_t pY = pZ * bendingSlope;
309 Double_t e = TMath::Sqrt(muonMass*muonMass + pX*pX + pY*pY + pZ*pZ);
310 vP.SetPxPyPzE(pX, pY, pZ, e);
313 //_____________________________________________________________________________
314 Double_t AliESDMuonTrack::PxAtDCA() const
316 // return p_x from track parameters
317 Double_t nonBendingSlope = TMath::Tan(fThetaXAtDCA);
318 Double_t bendingSlope = TMath::Tan(fThetaYAtDCA);
319 Double_t pYZ = (fInverseBendingMomentumAtDCA != 0.) ? TMath::Abs(1. / fInverseBendingMomentumAtDCA) : - FLT_MAX;
320 Double_t pZ = -pYZ / TMath::Sqrt(1.0 + bendingSlope*bendingSlope); // spectro. (z<0)
321 return pZ * nonBendingSlope;
324 //_____________________________________________________________________________
325 Double_t AliESDMuonTrack::PyAtDCA() const
327 // return p_y from track parameters
328 Double_t bendingSlope = TMath::Tan(fThetaYAtDCA);
329 Double_t pYZ = (fInverseBendingMomentumAtDCA != 0.) ? TMath::Abs(1. / fInverseBendingMomentumAtDCA) : - FLT_MAX;
330 Double_t pZ = -pYZ / TMath::Sqrt(1.0 + bendingSlope*bendingSlope); // spectro. (z<0)
331 return pZ * bendingSlope;
334 //_____________________________________________________________________________
335 Double_t AliESDMuonTrack::PzAtDCA() const
337 // return p_z from track parameters
338 Double_t bendingSlope = TMath::Tan(fThetaYAtDCA);
339 Double_t pYZ = (fInverseBendingMomentumAtDCA != 0.) ? TMath::Abs(1. / fInverseBendingMomentumAtDCA) : - FLT_MAX;
340 return -pYZ / TMath::Sqrt(1.0 + bendingSlope*bendingSlope); // spectro. (z<0)
343 //_____________________________________________________________________________
344 Double_t AliESDMuonTrack::PAtDCA() const
346 // return p from track parameters
347 Double_t nonBendingSlope = TMath::Tan(fThetaXAtDCA);
348 Double_t bendingSlope = TMath::Tan(fThetaYAtDCA);
349 Double_t pYZ = (fInverseBendingMomentumAtDCA != 0.) ? TMath::Abs(1. / fInverseBendingMomentumAtDCA) : - FLT_MAX;
350 Double_t pZ = -pYZ / TMath::Sqrt(1.0 + bendingSlope*bendingSlope); // spectro. (z<0)
351 return -pZ * TMath::Sqrt(1.0 + bendingSlope*bendingSlope + nonBendingSlope*nonBendingSlope);
354 //_____________________________________________________________________________
355 void AliESDMuonTrack::LorentzPAtDCA(TLorentzVector& vP) const
357 // return Lorentz momentum vector from track parameters
358 Double_t muonMass = M();
359 Double_t nonBendingSlope = TMath::Tan(fThetaXAtDCA);
360 Double_t bendingSlope = TMath::Tan(fThetaYAtDCA);
361 Double_t pYZ = (fInverseBendingMomentumAtDCA != 0.) ? TMath::Abs(1. / fInverseBendingMomentumAtDCA) : - FLT_MAX;
362 Double_t pZ = -pYZ / TMath::Sqrt(1.0 + bendingSlope*bendingSlope); // spectro. (z<0)
363 Double_t pX = pZ * nonBendingSlope;
364 Double_t pY = pZ * bendingSlope;
365 Double_t e = TMath::Sqrt(muonMass*muonMass + pX*pX + pY*pY + pZ*pZ);
366 vP.SetPxPyPzE(pX, pY, pZ, e);
369 //_____________________________________________________________________________
370 Double_t AliESDMuonTrack::PxUncorrected() const
372 // return p_x from track parameters
373 Double_t nonBendingSlope = TMath::Tan(fThetaXUncorrected);
374 Double_t bendingSlope = TMath::Tan(fThetaYUncorrected);
375 Double_t pYZ = (fInverseBendingMomentumUncorrected != 0.) ? TMath::Abs(1. / fInverseBendingMomentumUncorrected) : - FLT_MAX;
376 Double_t pZ = -pYZ / TMath::Sqrt(1.0 + bendingSlope*bendingSlope); // spectro. (z<0)
377 return pZ * nonBendingSlope;
380 //_____________________________________________________________________________
381 Double_t AliESDMuonTrack::PyUncorrected() const
383 // return p_y from track parameters
384 Double_t bendingSlope = TMath::Tan(fThetaYUncorrected);
385 Double_t pYZ = (fInverseBendingMomentumUncorrected != 0.) ? TMath::Abs(1. / fInverseBendingMomentumUncorrected) : - FLT_MAX;
386 Double_t pZ = -pYZ / TMath::Sqrt(1.0 + bendingSlope*bendingSlope); // spectro. (z<0)
387 return pZ * bendingSlope;
390 //_____________________________________________________________________________
391 Double_t AliESDMuonTrack::PzUncorrected() const
393 // return p_z from track parameters
394 Double_t bendingSlope = TMath::Tan(fThetaYUncorrected);
395 Double_t pYZ = (fInverseBendingMomentumUncorrected != 0.) ? TMath::Abs(1. / fInverseBendingMomentumUncorrected) : - FLT_MAX;
396 return -pYZ / TMath::Sqrt(1.0 + bendingSlope*bendingSlope); // spectro. (z<0)
399 //_____________________________________________________________________________
400 Double_t AliESDMuonTrack::PUncorrected() const
402 // return p from track parameters
403 Double_t nonBendingSlope = TMath::Tan(fThetaXUncorrected);
404 Double_t bendingSlope = TMath::Tan(fThetaYUncorrected);
405 Double_t pYZ = (fInverseBendingMomentumUncorrected != 0.) ? TMath::Abs(1. / fInverseBendingMomentumUncorrected) : - FLT_MAX;
406 Double_t pZ = -pYZ / TMath::Sqrt(1.0 + bendingSlope*bendingSlope); // spectro. (z<0)
407 return -pZ * TMath::Sqrt(1.0 + bendingSlope*bendingSlope + nonBendingSlope*nonBendingSlope);
410 //_____________________________________________________________________________
411 void AliESDMuonTrack::LorentzPUncorrected(TLorentzVector& vP) const
413 // return Lorentz momentum vector from track parameters
414 Double_t muonMass = M();
415 Double_t nonBendingSlope = TMath::Tan(fThetaXUncorrected);
416 Double_t bendingSlope = TMath::Tan(fThetaYUncorrected);
417 Double_t pYZ = (fInverseBendingMomentumUncorrected != 0.) ? TMath::Abs(1. / fInverseBendingMomentumUncorrected) : - FLT_MAX;
418 Double_t pZ = -pYZ / TMath::Sqrt(1.0 + bendingSlope*bendingSlope); // spectro. (z<0)
419 Double_t pX = pZ * nonBendingSlope;
420 Double_t pY = pZ * bendingSlope;
421 Double_t e = TMath::Sqrt(muonMass*muonMass + pX*pX + pY*pY + pZ*pZ);
422 vP.SetPxPyPzE(pX, pY, pZ, e);
425 //_____________________________________________________________________________
426 Int_t AliESDMuonTrack::GetMatchTrigger() const
428 // backward compatibility after replacing fMatchTrigger by fLocalTrigger
429 // 0 track does not match trigger
430 // 1 track match but does not pass pt cut
431 // 2 track match Low pt cut
432 // 3 track match High pt cut
436 } else if (LoLpt() == 0 && LoHpt() == 0) {
438 } else if (LoLpt() > 0 && LoHpt() == 0) {
446 //_____________________________________________________________________________
447 void AliESDMuonTrack::AddInMuonClusterMap(Int_t chamber)
449 // Update the muon cluster map by adding this chamber(0..)
451 static const UInt_t kMask[10] = {0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80, 0x100, 0x200};
453 fMuonClusterMap |= kMask[chamber];
457 //_____________________________________________________________________________
458 Bool_t AliESDMuonTrack::IsInMuonClusterMap(Int_t chamber) const
460 // return kTRUE if this chamber(0..) is in the muon cluster map
462 static const UInt_t kMask[10] = {0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80, 0x100, 0x200};
464 return ((fMuonClusterMap | kMask[chamber]) == fMuonClusterMap) ? kTRUE : kFALSE;
468 //_____________________________________________________________________________
469 Int_t AliESDMuonTrack::GetNClusters() const
471 // return the number of clusters associated to the track
472 if (!fClusters) return 0;
474 return fClusters->GetEntriesFast();
477 //_____________________________________________________________________________
478 TClonesArray& AliESDMuonTrack::GetClusters() const
480 // return the array of clusters associated to the track
481 if (!fClusters) fClusters = new TClonesArray("AliESDMuonCluster",10);
486 //_____________________________________________________________________________
487 void AliESDMuonTrack::AddCluster(const AliESDMuonCluster &cluster)
489 // add a cluster to the TClonesArray of clusters associated to the track
490 if (!fClusters) fClusters = new TClonesArray("AliESDMuonCluster",10);
492 new ((*fClusters)[fClusters->GetEntriesFast()]) AliESDMuonCluster(cluster);
495 //_____________________________________________________________________________
496 Bool_t AliESDMuonTrack::ClustersStored() const
498 // return kTRUE if the clusters associated to the track are registered
499 if (GetNClusters() == 0) return kFALSE;