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