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)
60 const char* AliDxHFEToolsMC::fgkPDGBinLabels[]={
74 const char* AliDxHFEToolsMC::fgkPDGMotherBinLabels[]={
88 const char* AliDxHFEToolsMC::fgkStatisticsBinLabels[]={
89 "all", // all MC particles
90 "found", // selected particles with correct MC
91 "fake" // selected particles without corresponding MC
94 AliDxHFEToolsMC::~AliDxHFEToolsMC()
97 if (fHistPDG) delete fHistPDG;
99 if (fHistPDGMother) delete fHistPDGMother;
103 int AliDxHFEToolsMC::Init(const char* option)
105 // initialize according to options
106 TString strOption(option);
107 bool bControlHist=true;
108 std::auto_ptr<TObjArray> tokens(strOption.Tokenize(" "));
109 if (tokens.get() && tokens->GetEntriesFast()>0) {
110 for (int itoken=0; itoken<tokens->GetEntriesFast(); itoken++) {
111 if (tokens->At(itoken)==NULL) continue;
112 TString arg=tokens->At(itoken)->GetName();
115 if (arg.BeginsWith(key)) {
116 arg.ReplaceAll(key, "");
117 fPDGs.push_back(arg.Atoi());
120 if (arg.BeginsWith(key)) {
121 arg.ReplaceAll(key, "");
122 fMotherPDGs.push_back(arg.Atoi());
125 if (arg.BeginsWith(key)) {
126 arg.ReplaceAll(key, "");
127 bControlHist=arg.CompareTo("off")!=0;
130 if (arg.BeginsWith(key)) {
134 if (arg.BeginsWith(key)) {
141 fHistPDG=CreateControlHistogram("histPDG",
142 "pdg code of selected particle",
143 sizeof(fgkPDGBinLabels)/sizeof(const char*),
145 fHistPDGMother=CreateControlHistogram("histPDGMother",
146 "pdg code of first mother of selected particle",
147 sizeof(fgkPDGMotherBinLabels)/sizeof(fgkPDGMotherBinLabels[0]),
148 fgkPDGMotherBinLabels);
153 int AliDxHFEToolsMC::InitMCParticles(const AliVEvent* pEvent)
156 // init MC info from event object
157 if (!pEvent) return -EINVAL;
159 // TODO: choose branch name depending on VEvent type; configurable?
160 TString branchname(AliAODMCParticle::StdBranchName());
161 TObject* o=pEvent->FindListObject(branchname);
163 AliWarningClass(Form("can not find MC info '%s' in event of type '%s'", branchname.Data(), pEvent->ClassName()));
166 fMCParticles = dynamic_cast<TObjArray*>(o);
168 AliWarningClass(Form("ignoring MC info '%s' of wrong type '%s', expecting TObjArray", branchname.Data(), o->ClassName()));
175 bool AliDxHFEToolsMC::RejectByPDG(int pdg, const vector<int> &list) const
177 // check if pdg should be rejected, particle is not rejected
178 // if it is in the list, returns always false if list is empty
179 if (list.size()==0) return false;
180 for (vector<int>::const_iterator i=list.begin();
181 i!=list.end(); i++) {
182 if (*i==pdg) return false;
187 bool AliDxHFEToolsMC::RejectByPDG(AliVParticle* p, bool doStatistics)
189 // check if pdg should be rejected
190 // always false if not pdg list is initialized
191 if (!p) return false;
192 Int_t MClabel = p->GetLabel();
193 if(MClabel<0) return 0;
196 // TODO: there might be more types of particles to be checked
197 AliAODMCParticle* aodmcp=0;
198 aodmcp=dynamic_cast<AliAODMCParticle*>(fMCParticles->At(MClabel));
200 pdgPart=TMath::Abs(aodmcp->GetPdgCode());
201 if (pdgPart<0) return 0;
203 bool bReject=RejectByPDG(pdgPart, fPDGs);
204 if (doStatistics && fHistPDG) {
205 // TODO: think about histogramming mode, e.g. histogramming of rejected particles?
207 fHistPDG->Fill(MapPDGLabel(p->PdgCode()));
213 bool AliDxHFEToolsMC::RejectByMotherPDG(AliVParticle* p, bool doStatistics)
215 // check if pdg should be rejected by mother
216 // always false if not mother pdg list is initialized
217 // H: think maybe this is particle specific, and should be moved to PartSelMCEl
218 if (!p) return false;
219 int motherpdg=FindPdgOriginMother(p);
220 // TODO: This should be tweaked. Want to
221 bool bReject=RejectByPDG(motherpdg, fMotherPDGs);
222 if (doStatistics && fHistPDGMother) {
223 // TODO: think about histogramming mode, e.g. histogramming of rejected particles?
225 fHistPDGMother->Fill(MapPDGMotherLabel(p->PdgCode()));
231 int AliDxHFEToolsMC::FindMotherPDG(AliVParticle* p, bool bReturnFirstMother)
233 // Will find and return pdg of the mother, either first or loop down to the
236 // To reset fOriginMother.
237 fOriginMother=kOriginNone;
239 if (!p) return false;
240 int motherpdg=FindPdgOriginMother(p, bReturnFirstMother);
246 TH1* AliDxHFEToolsMC::CreateControlHistogram(const char* name,
249 const char** binLabels) const
251 /// create control histogram
252 std::auto_ptr<TH1> h(new TH1D(name, title, nBins, -0.5, nBins-0.5));
253 if (!h.get()) return NULL;
254 for (int iLabel=0; iLabel<nBins; iLabel++) {
255 h->GetXaxis()->SetBinLabel(iLabel+1, binLabels[iLabel]);
261 int AliDxHFEToolsMC::MapPDGLabel(int pdg) const
263 /// mapping of pdg code to enum
265 case kPDGelectron : return kPDGLabelElectron;
266 case -kPDGelectron : return kPDGLabelPositron;
267 case kPDGmuon : return kPDGLabelMuPlus;
268 case -kPDGmuon : return kPDGLabelMuMinus;
269 case kPDGpion : return kPDGLabelPiPlus;
270 case -kPDGpion : return kPDGLabelPiMinus;
271 case kPDGkaon : return kPDGLabelKPlus;
272 case -kPDGkaon : return kPDGLabelKMinus;
273 case kPDGproton : return kPDGLabelProton;
274 case -kPDGproton : return kPDGLabelAntiproton;
276 return kPDGLabelOthers;
280 int AliDxHFEToolsMC::MapPDGMotherLabel(int pdg) const
282 /// mapping of pdg code to enum
284 case kPDGd : return kPDGMotherLabelD;
285 case kPDGu : return kPDGMotherLabelU;
286 case kPDGs : return kPDGMotherLabelS;
287 case kPDGc : return kPDGMotherLabelC;
288 case kPDGb : return kPDGMotherLabelB;
289 case kPDGgluon : return kPDGMotherLabelGluon;
290 case kPDGgamma : return kPDGMotherLabelGamma;
291 case kPDGpi0 : return kPDGMotherLabelPi0;
292 case kPDGeta : return kPDGMotherLabelEta;
293 case kPDGproton: return kPDGMotherLabelProton;
295 return kPDGLabelOthers;
299 int AliDxHFEToolsMC::FindPdgOriginMother(AliVParticle* p, bool bReturnFirstMother)
301 // Return the pgd of original mother particle
302 // TODO: need also to have specific for D0, electron etc
303 // for instance to mark when you have gluon, charm or beauty
304 // among the mothers. Or maybe this will be the same anyway?
305 // TODO: implement tests on origin, if charm/beauty quark and if
306 // they came from gluon. use booleans to set this which can be accessed from
307 // outside? Something like fSequence.
309 if (!p) return kPDGnone;
314 // Either using MClabel set from outside (needed for Dmesons), or find it
316 MClabel = p->GetLabel();
321 else MClabel=fMClabel;
323 // try different classes, unfortunately there is no common base class
324 AliAODMCParticle* aodmcp=0;
325 aodmcp=dynamic_cast<AliAODMCParticle*>(fMCParticles->At(MClabel));
329 imother = aodmcp->GetMother();
331 // Absolute or +/- on pgd ???
332 Int_t pdg=TMath::Abs(aodmcp->GetPdgCode());
335 // also check this particle
336 CheckOriginMother(pdg);
340 if (!fMCParticles->At(imother)) {
341 AliErrorClass(Form("no mc particle with label %d", imother));
345 AliAODMCParticle * mother=dynamic_cast<AliAODMCParticle*>(fMCParticles->At(imother));
347 AliErrorClass(Form("mc mother particle of wrong class type %s", fMCParticles->At(imother)->ClassName()));
351 if(bReturnFirstMother){
352 return mother->GetPdgCode();
355 CheckOriginMother(pdg);
357 if (mother->GetPdgCode()==kPDGproton){
358 // why? - H: This is the proton, can't get further back
359 // To be discussed whether to do this a different way
363 //Reset fMClabel to find pdg of mother if looping on D
365 pdg=FindPdgOriginMother(mother);
370 void AliDxHFEToolsMC::CheckOriginMother(int pdg)
373 // Checking if the particle is a quark or gluon and setting fOriginMother accordingly.
374 // Right now only check on quark. Need also check on whether it comes from D or B meson?
378 fOriginMother = kOriginCharm; break;
380 fOriginMother = kOriginBeauty; break;
382 if(fOriginMother==kOriginCharm) fOriginMother=kOriginGluonCharm;
383 else if(fOriginMother==kOriginBeauty) fOriginMother=kOriginGluonBeauty;
384 else fOriginMother=kOriginGluon;
387 fOriginMother=kOriginDown; break;
389 fOriginMother=kOriginUp; break;
391 fOriginMother=kOriginStrange; break;
395 void AliDxHFEToolsMC::Clear(const char* /*option*/)
397 // clear internal memory