3 //**************************************************************************
4 //* This file is property of and copyright by the ALICE Project *
5 //* ALICE Experiment at CERN, All rights reserved. *
7 //* Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no> *
8 //* Hege Erdal <hege.erdal@gmail.com> *
10 //* Permission to use, copy, modify and distribute this software and its *
11 //* documentation strictly for non-commercial purposes is hereby granted *
12 //* without fee, provided that the above copyright notice appears in all *
13 //* copies and that both the copyright notice and this permission notice *
14 //* appear in the supporting documentation. The authors make no claims *
15 //* about the suitability of this software for any purpose. It is *
16 //* provided "as is" without express or implied warranty. *
17 //**************************************************************************
19 /// @file AliDxHFEToolsMC.cxx
20 /// @author Hege Erdal, Matthias Richter
22 /// @brief Common Tools for MC particle selection
25 #include "AliDxHFEToolsMC.h"
26 #include "AliAODMCParticle.h"
27 #include "AliVEvent.h"
28 #include "AliVParticle.h"
30 #include "TObjArray.h"
39 /// ROOT macro for the implementation of ROOT specific class methods
40 ClassImp(AliDxHFEToolsMC)
42 AliDxHFEToolsMC::AliDxHFEToolsMC(const char* option)
48 , fHistPDGMother(NULL)
49 , fOriginMother(kOriginNone)
62 const char* AliDxHFEToolsMC::fgkPDGBinLabels[]={
76 const char* AliDxHFEToolsMC::fgkPDGMotherBinLabels[]={
90 const char* AliDxHFEToolsMC::fgkStatisticsBinLabels[]={
91 "all", // all MC particles
92 "found", // selected particles with correct MC
93 "fake" // selected particles without corresponding MC
96 AliDxHFEToolsMC::~AliDxHFEToolsMC()
99 if (fHistPDG) delete fHistPDG;
101 if (fHistPDGMother) delete fHistPDGMother;
105 int AliDxHFEToolsMC::Init(const char* option)
107 // initialize according to options
108 TString strOption(option);
109 bool bControlHist=true;
110 std::auto_ptr<TObjArray> tokens(strOption.Tokenize(" "));
111 if (tokens.get() && tokens->GetEntriesFast()>0) {
112 for (int itoken=0; itoken<tokens->GetEntriesFast(); itoken++) {
113 if (tokens->At(itoken)==NULL) continue;
114 TString arg=tokens->At(itoken)->GetName();
117 if (arg.BeginsWith(key)) {
118 arg.ReplaceAll(key, "");
119 fPDGs.push_back(arg.Atoi());
122 if (arg.BeginsWith(key)) {
123 arg.ReplaceAll(key, "");
124 fMotherPDGs.push_back(arg.Atoi());
127 if (arg.BeginsWith(key)) {
128 arg.ReplaceAll(key, "");
129 bControlHist=arg.CompareTo("off")!=0;
132 if (arg.BeginsWith(key)) {
136 if (arg.BeginsWith(key)) {
140 if(arg.BeginsWith(key)) {
141 printf("AliDxHFEToolsMC::Init() Using Kinematical\n");
148 fHistPDG=CreateControlHistogram("histPDG",
149 "pdg code of selected particle",
150 sizeof(fgkPDGBinLabels)/sizeof(const char*),
152 fHistPDGMother=CreateControlHistogram("histPDGMother",
153 "pdg code of first mother of selected particle",
154 sizeof(fgkPDGMotherBinLabels)/sizeof(fgkPDGMotherBinLabels[0]),
155 fgkPDGMotherBinLabels);
160 int AliDxHFEToolsMC::InitMCParticles(const AliVEvent* pEvent)
163 // init MC info from event object
164 if (!pEvent) return -EINVAL;
166 // TODO: choose branch name depending on VEvent type; configurable?
167 TString branchname(AliAODMCParticle::StdBranchName());
168 TObject* o=pEvent->FindListObject(branchname);
170 AliWarningClass(Form("can not find MC info '%s' in event of type '%s'", branchname.Data(), pEvent->ClassName()));
173 fMCParticles = dynamic_cast<TObjArray*>(o);
175 AliWarningClass(Form("ignoring MC info '%s' of wrong type '%s', expecting TObjArray", branchname.Data(), o->ClassName()));
178 fNrMCParticles=fMCParticles->GetEntriesFast();
182 bool AliDxHFEToolsMC::RejectByPDG(int pdg, const vector<int> &list) const
184 // check if pdg should be rejected, particle is not rejected
185 // if it is in the list, returns always false if list is empty
186 if (list.size()==0) return false;
187 for (vector<int>::const_iterator i=list.begin();
188 i!=list.end(); i++) {
189 if (*i==pdg) return false;
194 bool AliDxHFEToolsMC::RejectByPDG(AliVParticle* p, bool doStatistics, int* pdgParticleResult)
196 // check if pdg should be rejected
197 // always false if not pdg list is initialized
198 if (!p) return false;
199 Int_t MClabel = p->GetLabel();
204 // TODO: there might be more types of particles to be checked
205 AliAODMCParticle* aodmcp=0;
206 aodmcp=dynamic_cast<AliAODMCParticle*>(fMCParticles->At(MClabel));
208 pdgPart=TMath::Abs(aodmcp->GetPdgCode());
209 if (pdgPart<0) return 0;
211 if (pdgParticleResult)
212 *pdgParticleResult=pdgPart;
214 bool bReject=RejectByPDG(pdgPart, fPDGs);
215 if (doStatistics && fHistPDG) {
216 // TODO: think about histogramming mode, e.g. histogramming of rejected particles?
218 fHistPDG->Fill(MapPDGLabel(p->PdgCode()));
224 bool AliDxHFEToolsMC::RejectByMotherPDG(AliVParticle* p, bool doStatistics)
226 // check if pdg should be rejected by mother
227 // always false if not mother pdg list is initialized
228 // H: think maybe this is particle specific, and should be moved to PartSelMCEl
229 if (!p) return false;
230 int motherpdg=FindPdgOriginMother(p);
231 // TODO: This should be tweaked. Want to
232 bool bReject=RejectByPDG(motherpdg, fMotherPDGs);
233 if (doStatistics && fHistPDGMother) {
234 // TODO: think about histogramming mode, e.g. histogramming of rejected particles?
236 fHistPDGMother->Fill(MapPDGMotherLabel(p->PdgCode()));
242 int AliDxHFEToolsMC::FindMotherPDG(AliVParticle* p, bool bReturnFirstMother)
244 // Will find and return pdg of the mother, either first or loop down to the
247 // To reset fOriginMother.
248 fOriginMother=kOriginNone;
250 if (!p) return false;
251 int motherpdg=FindPdgOriginMother(p, bReturnFirstMother);
256 TH1* AliDxHFEToolsMC::CreateControlHistogram(const char* name,
259 const char** binLabels) const
261 /// create control histogram
262 std::auto_ptr<TH1> h(new TH1D(name, title, nBins, -0.5, nBins-0.5));
263 if (!h.get()) return NULL;
264 for (int iLabel=0; iLabel<nBins; iLabel++) {
265 h->GetXaxis()->SetBinLabel(iLabel+1, binLabels[iLabel]);
271 int AliDxHFEToolsMC::MapPDGLabel(int pdg) const
273 /// mapping of pdg code to enum
275 case kPDGelectron : return kPDGLabelElectron;
276 case -kPDGelectron : return kPDGLabelPositron;
277 case kPDGmuon : return kPDGLabelMuPlus;
278 case -kPDGmuon : return kPDGLabelMuMinus;
279 case kPDGpion : return kPDGLabelPiPlus;
280 case -kPDGpion : return kPDGLabelPiMinus;
281 case kPDGkaon : return kPDGLabelKPlus;
282 case -kPDGkaon : return kPDGLabelKMinus;
283 case kPDGproton : return kPDGLabelProton;
284 case -kPDGproton : return kPDGLabelAntiproton;
286 return kPDGLabelOthers;
290 int AliDxHFEToolsMC::MapPDGMotherLabel(int pdg) const
292 /// mapping of pdg code to enum
294 case kPDGd : return kPDGMotherLabelD;
295 case kPDGu : return kPDGMotherLabelU;
296 case kPDGs : return kPDGMotherLabelS;
297 case kPDGc : return kPDGMotherLabelC;
298 case kPDGb : return kPDGMotherLabelB;
299 case kPDGgluon : return kPDGMotherLabelGluon;
300 case kPDGgamma : return kPDGMotherLabelGamma;
301 case kPDGpi0 : return kPDGMotherLabelPi0;
302 case kPDGeta : return kPDGMotherLabelEta;
303 case kPDGproton: return kPDGMotherLabelProton;
305 return kPDGLabelOthers;
309 int AliDxHFEToolsMC::FindPdgOriginMother(AliVParticle* p, bool bReturnFirstMother)
311 // Return the pgd of original mother particle
312 // TODO: need also to have specific for D0, electron etc
313 // for instance to mark when you have gluon, charm or beauty
314 // among the mothers. Or maybe this will be the same anyway?
315 // TODO: implement tests on origin, if charm/beauty quark and if
316 // they came from gluon. use booleans to set this which can be accessed from
317 // outside? Something like fSequence.
319 if (!p) return kPDGnone;
324 // Either using MClabel set from outside (needed for Dmesons), or find it
326 MClabel = p->GetLabel();
331 else MClabel=fMClabel;
333 // try different classes, unfortunately there is no common base class
334 AliAODMCParticle* aodmcp=0;
336 aodmcp=dynamic_cast<AliAODMCParticle*>(p);
338 aodmcp=dynamic_cast<AliAODMCParticle*>(fMCParticles->At(MClabel));
343 imother = aodmcp->GetMother();
345 // Absolute or +/- on pgd ???
346 Int_t pdg=TMath::Abs(aodmcp->GetPdgCode());
349 // also check this particle
350 CheckOriginMother(pdg);
354 if (!fMCParticles->At(imother)) {
355 AliErrorClass(Form("no mc particle with label %d", imother));
359 AliAODMCParticle * mother=dynamic_cast<AliAODMCParticle*>(fMCParticles->At(imother));
361 AliErrorClass(Form("mc mother particle of wrong class type %s", fMCParticles->At(imother)->ClassName()));
365 if(bReturnFirstMother){
366 return mother->GetPdgCode();
369 CheckOriginMother(pdg);
371 if (mother->GetPdgCode()==kPDGproton){
372 // why? - H: This is the proton, can't get further back
373 // To be discussed whether to do this a different way
377 //Reset fMClabel to find pdg of mother if looping on D
379 pdg=FindPdgOriginMother(mother);
384 void AliDxHFEToolsMC::CheckOriginMother(int pdg)
387 // Checking if the particle is a quark or gluon and setting fOriginMother accordingly.
388 // Right now only check on quark. Need also check on whether it comes from D or B meson?
392 fOriginMother = kOriginCharm; break;
394 fOriginMother = kOriginBeauty; break;
396 if(fOriginMother==kOriginCharm) fOriginMother=kOriginGluonCharm;
397 else if(fOriginMother==kOriginBeauty) fOriginMother=kOriginGluonBeauty;
398 else fOriginMother=kOriginGluon;
401 if(!TestIfHFquark(fOriginMother))
402 fOriginMother=kOriginDown;
405 if(!TestIfHFquark(fOriginMother))
406 fOriginMother=kOriginUp;
409 if(!TestIfHFquark(fOriginMother))
410 fOriginMother=kOriginStrange;
415 Bool_t AliDxHFEToolsMC::TestIfHFquark(int origin)
418 // Checking if particle has been marked as charm/beauty quark
426 case(kOriginGluonCharm):
428 case(kOriginGluonBeauty):
434 Bool_t AliDxHFEToolsMC::TestMotherHFMeson(int pdg)
437 // Checking if the pdg corresponds to a HF meson (D or B meson)
441 if((pdg>=400 && pdg <500) || (pdg>=4000 && pdg<5000 ))
443 if((pdg>=500 && pdg <600) || (pdg>=5000 && pdg<6000 ))
444 {isD = kFALSE; isB = kTRUE;}
446 if(isD || isB) return kTRUE;
454 void AliDxHFEToolsMC::Clear(const char* /*option*/)
456 // clear internal memory
462 int AliDxHFEToolsMC::CheckMCParticle(AliVParticle* p){
464 // Checks if MC particle is desired particle
466 AliAODMCParticle* mcPart = dynamic_cast<AliAODMCParticle*>(p);
468 AliInfoClass("MC Particle not found in tree, skipping");
472 Int_t PDG =TMath::Abs(mcPart->PdgCode());
473 int bReject=RejectByPDG(PDG, fPDGs);