]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PWG/muon/AliUtilityMuonAncestor.cxx
968a10a34644a6b02f1356accda31052f28f1c68
[u/mrichter/AliRoot.git] / PWG / muon / AliUtilityMuonAncestor.cxx
1 /**************************************************************************\r
2  * Copyright(c) 1998-2007, ALICE Experiment at CERN, All rights reserved. *\r
3  *                                                                        *\r
4  * Author: The ALICE Off-line Project.                                    *\r
5  * Contributors are mentioned in the code where appropriate.              *\r
6  *                                                                        *\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
15 \r
16 /* $Id: AliUtilityMuonAncestor.cxx 47782 2011-02-24 18:37:31Z martinez $ */\r
17 \r
18 //-----------------------------------------------------------------------------\r
19 /// \class AliUtilityMuonAncestor\r
20 /// Static utilities to get the muon ancestor in MC\r
21 ///\r
22 /// \author Diego Stocco\r
23 //-----------------------------------------------------------------------------\r
24 \r
25 #include "AliUtilityMuonAncestor.h"\r
26 \r
27 // ROOT includes\r
28 #include "TDatabasePDG.h"\r
29 #include "TParticlePDG.h"\r
30 #include "TPDGCode.h"\r
31 #include "TMCProcess.h"\r
32 #include "TMath.h"\r
33 \r
34 // STEER includes\r
35 #include "AliMCEvent.h"\r
36 #include "AliVParticle.h"\r
37 #include "AliMCParticle.h"\r
38 #include "AliAODMCParticle.h"\r
39 #include "AliLog.h"\r
40 \r
41 // PWGmuon includes\r
42 #include "AliAnalysisMuonUtility.h"\r
43 \r
44 /// \cond CLASSIMP\r
45 ClassImp(AliUtilityMuonAncestor) // Class implementation in ROOT context\r
46 /// \endcond\r
47 \r
48 //_________________________________________________________\r
49 AliUtilityMuonAncestor::AliUtilityMuonAncestor() :\r
50 TObject(),\r
51 fPx(0.),\r
52 fPy(0.),\r
53 fPz(0.),\r
54 fMask(0),\r
55 fAncestor(-999)\r
56 {\r
57   /// Default constructor\r
58 }\r
59 \r
60 \r
61 //_________________________________________________________\r
62 AliUtilityMuonAncestor::~AliUtilityMuonAncestor()\r
63 {\r
64   /// Default destructor\r
65 }\r
66 \r
67 //_________________________________________________________\r
68 AliUtilityMuonAncestor::AliUtilityMuonAncestor(const AliUtilityMuonAncestor& obj) :\r
69 TObject(obj),\r
70 fPx(obj.fPx),\r
71 fPy(obj.fPy),\r
72 fPz(obj.fPz),\r
73 fMask(obj.fMask),\r
74 fAncestor(obj.fAncestor)\r
75 {\r
76   /// Copy constructor\r
77 }\r
78 \r
79 //_________________________________________________________\r
80 AliUtilityMuonAncestor& AliUtilityMuonAncestor::operator=(const AliUtilityMuonAncestor& obj)\r
81 {\r
82   /// Copy operator\r
83   if ( this != &obj ) {\r
84     TObject::operator=(obj);\r
85     fPx = obj.fPx;\r
86     fPy = obj.fPy;\r
87     fPz = obj.fPz;\r
88     fMask = obj.fMask;\r
89     fAncestor = obj.fAncestor;\r
90   }\r
91   return *this;\r
92 }\r
93 \r
94 //_________________________________________________________\r
95 Bool_t AliUtilityMuonAncestor::BuildAncestor ( AliVParticle* track, const AliMCEvent* mcEvent )\r
96 {\r
97   /// Build ancestor\r
98   \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
101   fPx = track->Px();\r
102   fPy = track->Py();\r
103   fPz = track->Pz();\r
104   fMask = 0;\r
105   fAncestor = -999;\r
106   if ( ! mcEvent ) return kFALSE;\r
107   \r
108   AliVParticle* mcParticle = 0x0;\r
109   \r
110   if ( AliAnalysisMuonUtility::IsMCTrack(track) ) mcParticle = track;\r
111   else {\r
112     Int_t trackLabel = track->GetLabel();\r
113     if ( trackLabel < 0 ) return kFALSE;\r
114     mcParticle = mcEvent->GetTrack(trackLabel);\r
115   }\r
116   \r
117   // Track is MC (or matches a MC track)\r
118   SETBIT(fMask,kIsID);\r
119   \r
120   Int_t recoPdg = mcParticle->PdgCode();\r
121   \r
122   // Track is not a muon\r
123   if ( TMath::Abs(recoPdg) == 13 ) SETBIT(fMask,kIsMuon);\r
124   \r
125   Int_t imother = AliAnalysisMuonUtility::GetMotherIndex(mcParticle);\r
126 \r
127   while ( imother >= 0 ) {\r
128     AliVParticle* part = mcEvent->GetTrack(imother);\r
129     \r
130     Int_t absPdg = TMath::Abs(part->PdgCode());\r
131     \r
132     // This is a quark\r
133     if ( absPdg < 10 ) return kTRUE;\r
134     \r
135     fAncestor = imother;\r
136     Bool_t isPrimary = AliAnalysisMuonUtility::IsPrimary(part, mcEvent);\r
137     \r
138     if ( isPrimary ) {\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
144         else {\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
149         }\r
150       } // absPdg within 100 and 10000\r
151     } // is primary\r
152     else {\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
159 //        return kTRUE;\r
160       }\r
161     } // is secondary\r
162     \r
163     imother = AliAnalysisMuonUtility::GetMotherIndex(part);\r
164     \r
165   } // loop on mothers\r
166   return kTRUE;\r
167 }\r
168 \r
169 //_________________________________________________________\r
170 Bool_t AliUtilityMuonAncestor::CheckAncestor ( AliVParticle* track, const AliMCEvent* mcEvent, Int_t ancestorPdg, Bool_t matchAbsPdg )\r
171 {\r
172   /// Check ancestor\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
177   }\r
178   return ( pdgCode == ancestorPdg );\r
179 }\r
180 \r
181 //_________________________________________________________\r
182 Int_t AliUtilityMuonAncestor::GetAncestor ( AliVParticle* track, const AliMCEvent* mcEvent )\r
183 {\r
184   /// Return ancestor (compute it if necessary)\r
185   BuildAncestor(track,mcEvent);\r
186   return fAncestor;\r
187 }\r
188 \r
189 //_________________________________________________________\r
190 Int_t AliUtilityMuonAncestor::GetAncestorPdg ( AliVParticle* track, const AliMCEvent* mcEvent )\r
191 {\r
192   /// Return ancestor Pdg\r
193   if ( BuildAncestor(track,mcEvent) ) {\r
194     if ( fAncestor >= 0 ) return mcEvent->GetTrack(fAncestor)->PdgCode();\r
195   }\r
196   return 0;\r
197 }\r
198 \r
199 //_________________________________________________________\r
200 Long64_t AliUtilityMuonAncestor::GetMask ( AliVParticle* track, const AliMCEvent* mcEvent )\r
201 {\r
202   /// Return mask\r
203   BuildAncestor(track,mcEvent);\r
204   return fMask;\r
205 }\r
206 \r
207 \r
208 //_________________________________________________________\r
209 Bool_t AliUtilityMuonAncestor::IsBeautyMu ( AliVParticle* track, const AliMCEvent* mcEvent )\r
210 {\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
214 }\r
215 \r
216 //_________________________________________________________\r
217 Bool_t AliUtilityMuonAncestor::IsBJpsiMu ( AliVParticle* track, const AliMCEvent* mcEvent )\r
218 {\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
223   }\r
224   return kFALSE;\r
225 }\r
226 \r
227 //_________________________________________________________\r
228 Bool_t AliUtilityMuonAncestor::IsCharmMu ( AliVParticle* track, const AliMCEvent* mcEvent )\r
229 {\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
233 }\r
234 \r
235 //_________________________________________________________\r
236 Bool_t AliUtilityMuonAncestor::IsDecayMu ( AliVParticle* track, const AliMCEvent* mcEvent )\r
237 {\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
241 }\r
242 \r
243 //_________________________________________________________\r
244 Bool_t AliUtilityMuonAncestor::IsHadron ( AliVParticle* track, const AliMCEvent* mcEvent )\r
245 {\r
246   /// Reconstructed hadron\r
247   Long64_t mask = GetMask(track,mcEvent);\r
248   return ( TESTBIT(mask,kIsID) && ! TESTBIT(mask,kIsMuon) );\r
249 }\r
250 \r
251 //_________________________________________________________\r
252 Bool_t AliUtilityMuonAncestor::IsMuon ( AliVParticle* track, const AliMCEvent* mcEvent )\r
253 {\r
254   /// Track is muon\r
255   Long64_t mask = GetMask(track,mcEvent);\r
256   return ( TESTBIT(mask,kIsID) && TESTBIT(mask,kIsMuon) );\r
257 }\r
258 \r
259 //_________________________________________________________\r
260 Bool_t AliUtilityMuonAncestor::IsQuarkoniumMu ( AliVParticle* track, const AliMCEvent* mcEvent )\r
261 {\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
265 }\r
266 \r
267 //_________________________________________________________\r
268 Bool_t AliUtilityMuonAncestor::IsSecondaryMu ( AliVParticle* track, const AliMCEvent* mcEvent )\r
269 {\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
273 }\r
274 \r
275 //_________________________________________________________\r
276 Bool_t AliUtilityMuonAncestor::IsUnidentified ( AliVParticle* track, const AliMCEvent* mcEvent )\r
277 {\r
278   /// Unidentified muon\r
279   Long64_t mask = GetMask(track,mcEvent);\r
280   return ( ! TESTBIT(mask,kIsID) );\r
281 }\r
282 \r
283 //_________________________________________________________\r
284 Bool_t AliUtilityMuonAncestor::IsWBosonMu ( AliVParticle* track, const AliMCEvent* mcEvent )\r
285 {\r
286   /// Muon from W boson decays\r
287   return ( IsMuon(track,mcEvent) && CheckAncestor(track,mcEvent,24) );\r
288 }\r
289           \r
290 //_________________________________________________________\r
291 Bool_t AliUtilityMuonAncestor::IsZBosonMu ( AliVParticle* track, const AliMCEvent* mcEvent )\r
292 {\r
293   /// Muon from Z boson decays\r
294   return ( IsMuon(track,mcEvent) && CheckAncestor(track,mcEvent,kZ0) );\r
295 }\r