1 /**************************************************************************
\r
2 * Copyright(c) 1998-2007, ALICE Experiment at CERN, All rights reserved. *
\r
4 * Author: The ALICE Off-line Project. *
\r
5 * Contributors are mentioned in the code where appropriate. *
\r
7 * Permission to use, copy, modify and distribute this software and its *
\r
8 * documentation strictly for non-commercial purposes is hereby granted *
\r
9 * without fee, provided that the above copyright notice appears in all *
\r
10 * copies and that both the copyright notice and this permission notice *
\r
11 * appear in the supporting documentation. The authors make no claims *
\r
12 * about the suitability of this software for any purpose. It is *
\r
13 * provided "as is" without express or implied warranty. *
\r
14 **************************************************************************/
\r
16 /* $Id: AliUtilityMuonAncestor.cxx 47782 2011-02-24 18:37:31Z martinez $ */
\r
18 //-----------------------------------------------------------------------------
\r
19 /// \class AliUtilityMuonAncestor
\r
20 /// Static utilities to get the muon ancestor in MC
\r
22 /// \author Diego Stocco
\r
23 //-----------------------------------------------------------------------------
\r
25 #include "AliUtilityMuonAncestor.h"
\r
28 #include "TDatabasePDG.h"
\r
29 #include "TParticlePDG.h"
\r
30 #include "TPDGCode.h"
\r
31 #include "TMCProcess.h"
\r
35 #include "AliMCEvent.h"
\r
36 #include "AliVParticle.h"
\r
37 #include "AliMCParticle.h"
\r
38 #include "AliAODMCParticle.h"
\r
42 #include "AliAnalysisMuonUtility.h"
\r
45 ClassImp(AliUtilityMuonAncestor) // Class implementation in ROOT context
\r
48 //_________________________________________________________
\r
49 AliUtilityMuonAncestor::AliUtilityMuonAncestor() :
\r
57 /// Default constructor
\r
61 //_________________________________________________________
\r
62 AliUtilityMuonAncestor::~AliUtilityMuonAncestor()
\r
64 /// Default destructor
\r
67 //_________________________________________________________
\r
68 AliUtilityMuonAncestor::AliUtilityMuonAncestor(const AliUtilityMuonAncestor& obj) :
\r
74 fAncestor(obj.fAncestor)
\r
76 /// Copy constructor
\r
79 //_________________________________________________________
\r
80 AliUtilityMuonAncestor& AliUtilityMuonAncestor::operator=(const AliUtilityMuonAncestor& obj)
\r
83 if ( this != &obj ) {
\r
84 TObject::operator=(obj);
\r
89 fAncestor = obj.fAncestor;
\r
94 //_________________________________________________________
\r
95 Bool_t AliUtilityMuonAncestor::BuildAncestor ( AliVParticle* track, const AliMCEvent* mcEvent )
\r
99 // If track is the same as the one in memory, do not re-build the track ancestor
\r
100 if ( track->Px() == fPx && track->Py() == fPy && track->Pz() == fPz ) return kTRUE;
\r
106 if ( ! mcEvent ) return kFALSE;
\r
108 AliVParticle* mcParticle = 0x0;
\r
110 if ( AliAnalysisMuonUtility::IsMCTrack(track) ) mcParticle = track;
\r
112 Int_t trackLabel = track->GetLabel();
\r
113 if ( trackLabel < 0 ) return kFALSE;
\r
114 mcParticle = mcEvent->GetTrack(trackLabel);
\r
117 // Track is MC (or matches a MC track)
\r
118 SETBIT(fMask,kIsID);
\r
120 Int_t recoPdg = mcParticle->PdgCode();
\r
122 // Track is not a muon
\r
123 if ( TMath::Abs(recoPdg) == 13 ) SETBIT(fMask,kIsMuon);
\r
125 Int_t imother = AliAnalysisMuonUtility::GetMotherIndex(mcParticle);
\r
127 while ( imother >= 0 ) {
\r
128 AliVParticle* part = mcEvent->GetTrack(imother);
\r
130 Int_t absPdg = TMath::Abs(part->PdgCode());
\r
133 if ( absPdg < 10 ) return kTRUE;
\r
135 fAncestor = imother;
\r
136 Bool_t isPrimary = AliAnalysisMuonUtility::IsPrimary(part, mcEvent);
\r
139 Int_t mpdg = absPdg%100000;
\r
140 if ( mpdg >= 100 && mpdg < 10000 ) {
\r
141 Int_t flv = Int_t ( mpdg / TMath::Power(10, Int_t(TMath::Log10(mpdg) )));
\r
142 if ( flv < 4 ) SETBIT(fMask,kHasLightParent);
\r
143 else if ( flv >= 6 ) continue;
\r
145 TParticlePDG* partPdg = TDatabasePDG::Instance()->GetParticle(part->PdgCode());
\r
146 if ( partPdg && ! partPdg->AntiParticle() ) SETBIT(fMask,kHasQuarkoniumParent);
\r
147 else if ( flv == 4 ) SETBIT(fMask,kHasCharmParent);
\r
148 else SETBIT(fMask,kHasBeautyParent);
\r
150 } // absPdg within 100 and 10000
\r
153 UInt_t mcProcess = AliAnalysisMuonUtility::GetMCProcess(part);
\r
154 if ( mcProcess == kPHadronic ||
\r
155 ( mcProcess == 0 && part->Zv() < -90. ) ) {
\r
156 // The MC process is not well computed in the AODs of old MC productions
\r
157 // In this case, declare the particle as "secondary" if it is produced inside the front absorber
\r
158 SETBIT(fMask,kIsSecondary);
\r
163 imother = AliAnalysisMuonUtility::GetMotherIndex(part);
\r
165 } // loop on mothers
\r
169 //_________________________________________________________
\r
170 Bool_t AliUtilityMuonAncestor::CheckAncestor ( AliVParticle* track, const AliMCEvent* mcEvent, Int_t ancestorPdg, Bool_t matchAbsPdg )
\r
173 Int_t pdgCode = GetAncestorPdg(track, mcEvent);
\r
174 if ( matchAbsPdg ) {
\r
175 pdgCode = TMath::Abs(pdgCode);
\r
176 ancestorPdg = TMath::Abs(ancestorPdg);
\r
178 return ( pdgCode == ancestorPdg );
\r
181 //_________________________________________________________
\r
182 Int_t AliUtilityMuonAncestor::GetAncestor ( AliVParticle* track, const AliMCEvent* mcEvent )
\r
184 /// Return ancestor (compute it if necessary)
\r
185 BuildAncestor(track,mcEvent);
\r
189 //_________________________________________________________
\r
190 Int_t AliUtilityMuonAncestor::GetAncestorPdg ( AliVParticle* track, const AliMCEvent* mcEvent )
\r
192 /// Return ancestor Pdg
\r
193 if ( BuildAncestor(track,mcEvent) ) {
\r
194 if ( fAncestor >= 0 ) return mcEvent->GetTrack(fAncestor)->PdgCode();
\r
199 //_________________________________________________________
\r
200 Long64_t AliUtilityMuonAncestor::GetMask ( AliVParticle* track, const AliMCEvent* mcEvent )
\r
203 BuildAncestor(track,mcEvent);
\r
208 //_________________________________________________________
\r
209 Bool_t AliUtilityMuonAncestor::IsBeautyMu ( AliVParticle* track, const AliMCEvent* mcEvent )
\r
211 /// Muon from beauty decays
\r
212 Long64_t mask = GetMask(track,mcEvent);
\r
213 return ( TESTBIT(mask,kIsID) && TESTBIT(mask,kIsMuon) && TESTBIT(mask,kHasBeautyParent) & ! TESTBIT(mask,kHasLightParent) );
\r
216 //_________________________________________________________
\r
217 Bool_t AliUtilityMuonAncestor::IsBJpsiMu ( AliVParticle* track, const AliMCEvent* mcEvent )
\r
219 /// Muon B->J/psi decays
\r
220 if ( IsBeautyMu(track,mcEvent) ) {
\r
221 Int_t imother = AliAnalysisMuonUtility::GetMotherIndex(track);
\r
222 if ( imother >= 0 ) return ( mcEvent->GetTrack(imother)->PdgCode() == 443 );
\r
227 //_________________________________________________________
\r
228 Bool_t AliUtilityMuonAncestor::IsCharmMu ( AliVParticle* track, const AliMCEvent* mcEvent )
\r
230 /// Muon from charm decays
\r
231 Long64_t mask = GetMask(track,mcEvent);
\r
232 return ( TESTBIT(mask,kIsID) && TESTBIT(mask,kIsMuon) && TESTBIT(mask,kHasCharmParent) && ! TESTBIT(mask,kHasBeautyParent) && ! TESTBIT(mask,kHasLightParent) );
\r
235 //_________________________________________________________
\r
236 Bool_t AliUtilityMuonAncestor::IsDecayMu ( AliVParticle* track, const AliMCEvent* mcEvent )
\r
238 /// Muon from light hadron decays
\r
239 Long64_t mask = GetMask(track,mcEvent);
\r
240 return ( TESTBIT(mask,kIsID) && TESTBIT(mask,kIsMuon) && TESTBIT(mask,kHasLightParent) && ! TESTBIT(mask,kIsSecondary) );
\r
243 //_________________________________________________________
\r
244 Bool_t AliUtilityMuonAncestor::IsHadron ( AliVParticle* track, const AliMCEvent* mcEvent )
\r
246 /// Reconstructed hadron
\r
247 Long64_t mask = GetMask(track,mcEvent);
\r
248 return ( TESTBIT(mask,kIsID) && ! TESTBIT(mask,kIsMuon) );
\r
251 //_________________________________________________________
\r
252 Bool_t AliUtilityMuonAncestor::IsMuon ( AliVParticle* track, const AliMCEvent* mcEvent )
\r
255 Long64_t mask = GetMask(track,mcEvent);
\r
256 return ( TESTBIT(mask,kIsID) && TESTBIT(mask,kIsMuon) );
\r
259 //_________________________________________________________
\r
260 Bool_t AliUtilityMuonAncestor::IsQuarkoniumMu ( AliVParticle* track, const AliMCEvent* mcEvent )
\r
262 /// Mu from quarkonium decay
\r
263 Long64_t mask = GetMask(track,mcEvent);
\r
264 return ( TESTBIT(mask,kIsID) && TESTBIT(mask,kIsMuon) && TESTBIT(mask,kHasQuarkoniumParent) );
\r
267 //_________________________________________________________
\r
268 Bool_t AliUtilityMuonAncestor::IsSecondaryMu ( AliVParticle* track, const AliMCEvent* mcEvent )
\r
270 /// Muon from secondary decays in absorber
\r
271 Long64_t mask = GetMask(track,mcEvent);
\r
272 return ( TESTBIT(mask,kIsID) && TESTBIT(mask,kIsMuon) && TESTBIT(mask,kIsSecondary) );
\r
275 //_________________________________________________________
\r
276 Bool_t AliUtilityMuonAncestor::IsUnidentified ( AliVParticle* track, const AliMCEvent* mcEvent )
\r
278 /// Unidentified muon
\r
279 Long64_t mask = GetMask(track,mcEvent);
\r
280 return ( ! TESTBIT(mask,kIsID) );
\r
283 //_________________________________________________________
\r
284 Bool_t AliUtilityMuonAncestor::IsWBosonMu ( AliVParticle* track, const AliMCEvent* mcEvent )
\r
286 /// Muon from W boson decays
\r
287 return ( IsMuon(track,mcEvent) && CheckAncestor(track,mcEvent,24) );
\r
290 //_________________________________________________________
\r
291 Bool_t AliUtilityMuonAncestor::IsZBosonMu ( AliVParticle* track, const AliMCEvent* mcEvent )
\r
293 /// Muon from Z boson decays
\r
294 return ( IsMuon(track,mcEvent) && CheckAncestor(track,mcEvent,kZ0) );
\r