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 = - pZ / fInverseBendingMomentumUncorrected;
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) : 0.;
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) : 0.;
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) : 0.;
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) : 0.;
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) : 0.;
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) : 0.;
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) : 0.;
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) : 0.;
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) : 0.;
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) : 0.;
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) : 0.;
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) : 0.;
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) : 0.;
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) : 0.;
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) : 0.;
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 TClonesArray& AliESDMuonTrack::GetClusters() const
471 // return the array of clusters associated to the track
472 if (!fClusters) fClusters = new TClonesArray("AliESDMuonCluster",10);
477 //_____________________________________________________________________________
478 void AliESDMuonTrack::AddCluster(const AliESDMuonCluster &cluster)
480 // add a cluster to the TClonesArray of clusters associated to the track
481 if (!fClusters) fClusters = new TClonesArray("AliESDMuonCluster",10);
483 new ((*fClusters)[fClusters->GetEntriesFast()]) AliESDMuonCluster(cluster);
486 //_____________________________________________________________________________
487 Bool_t AliESDMuonTrack::ClustersStored() const
489 // return kTRUE if the clusters associated to the track are registered
490 if (!fClusters) return kFALSE;
492 if (fClusters->GetEntriesFast() == 0) return kFALSE;