]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PWGHF/correlationHF/AliDxHFEToolsMC.cxx
Bug in storage manager making possible to delete permanent event fixed
[u/mrichter/AliRoot.git] / PWGHF / correlationHF / AliDxHFEToolsMC.cxx
CommitLineData
d731501a 1// $Id$
2
3//**************************************************************************
4//* This file is property of and copyright by the ALICE Project *
5//* ALICE Experiment at CERN, All rights reserved. *
6//* *
7//* Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no> *
8//* Hege Erdal <hege.erdal@gmail.com> *
9//* *
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//**************************************************************************
18
19/// @file AliDxHFEToolsMC.cxx
20/// @author Hege Erdal, Matthias Richter
21/// @date 2012-07-19
22/// @brief Common Tools for MC particle selection
23///
24
25#include "AliDxHFEToolsMC.h"
26#include "AliAODMCParticle.h"
27#include "AliVEvent.h"
28#include "AliVParticle.h"
29#include "AliLog.h"
30#include "TObjArray.h"
31#include "TString.h"
32#include "TH1D.h"
33#include <iostream>
34#include <cerrno>
35#include <memory>
36
37using namespace std;
38
39/// ROOT macro for the implementation of ROOT specific class methods
40ClassImp(AliDxHFEToolsMC)
41
42AliDxHFEToolsMC::AliDxHFEToolsMC(const char* option)
43 : fSequence(kMCLast)
44 , fMCParticles(NULL)
45 , fPDGs()
46 , fMotherPDGs()
47 , fHistPDG(NULL)
48 , fHistPDGMother(NULL)
49 , fOriginMother(kOriginNone)
50 , fMClabel(-1)
dfe96b90 51 , fNrMCParticles(-1)
b4779749 52 , fUseKine(kFALSE)
d731501a 53{
54 // constructor
55 //
56 //
57 //
58 //
59 Init(option);
60}
61
62const char* AliDxHFEToolsMC::fgkPDGBinLabels[]={
63 "positron",
64 "electron",
65 "#mu+",
66 "#mu-",
67 "#pi+",
68 "#pi-",
69 "K+",
70 "K-",
71 "proton",
72 "antiproton",
73 "others"
74};
75
76const char* AliDxHFEToolsMC::fgkPDGMotherBinLabels[]={
77 "d",
78 "u",
79 "s",
80 "c",
81 "b",
82 "gluon",
83 "gamma",
84 "#pi^{0}",
85 "#eta",
86 "proton",
87 "others"
88};
89
90const char* AliDxHFEToolsMC::fgkStatisticsBinLabels[]={
91 "all", // all MC particles
92 "found", // selected particles with correct MC
93 "fake" // selected particles without corresponding MC
94};
95
96AliDxHFEToolsMC::~AliDxHFEToolsMC()
97{
98 // destructor
99 if (fHistPDG) delete fHistPDG;
100 fHistPDG=NULL;
101 if (fHistPDGMother) delete fHistPDGMother;
102 fHistPDGMother=NULL;
103}
104
105int AliDxHFEToolsMC::Init(const char* option)
106{
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();
115 const char* key="";
116 key="pdg=";
117 if (arg.BeginsWith(key)) {
118 arg.ReplaceAll(key, "");
119 fPDGs.push_back(arg.Atoi());
120 }
121 key="mother-pdg=";
122 if (arg.BeginsWith(key)) {
123 arg.ReplaceAll(key, "");
124 fMotherPDGs.push_back(arg.Atoi());
125 }
126 key="control-hist=";
127 if (arg.BeginsWith(key)) {
128 arg.ReplaceAll(key, "");
129 bControlHist=arg.CompareTo("off")!=0;
130 }
131 key="mc-first";
132 if (arg.BeginsWith(key)) {
133 fSequence=kMCFirst;
134 }
135 key="mc-last";
136 if (arg.BeginsWith(key)) {
137 fSequence=kMCLast;
138 }
b4779749 139 key="usekine";
140 if(arg.BeginsWith(key)) {
141 printf("AliDxHFEToolsMC::Init() Using Kinematical\n");
142 fUseKine=kTRUE;
143 }
d731501a 144 }
145 }
146
147 if (bControlHist) {
148 fHistPDG=CreateControlHistogram("histPDG",
149 "pdg code of selected particle",
150 sizeof(fgkPDGBinLabels)/sizeof(const char*),
151 fgkPDGBinLabels);
152 fHistPDGMother=CreateControlHistogram("histPDGMother",
153 "pdg code of first mother of selected particle",
154 sizeof(fgkPDGMotherBinLabels)/sizeof(fgkPDGMotherBinLabels[0]),
155 fgkPDGMotherBinLabels);
156 }
157 return 0;
158}
159
160int AliDxHFEToolsMC::InitMCParticles(const AliVEvent* pEvent)
161{
162
163 // init MC info from event object
164 if (!pEvent) return -EINVAL;
165
166 // TODO: choose branch name depending on VEvent type; configurable?
167 TString branchname(AliAODMCParticle::StdBranchName());
168 TObject* o=pEvent->FindListObject(branchname);
169 if (!o) {
170 AliWarningClass(Form("can not find MC info '%s' in event of type '%s'", branchname.Data(), pEvent->ClassName()));
171 return -ENOENT;
172 }
173 fMCParticles = dynamic_cast<TObjArray*>(o);
174 if (!fMCParticles) {
175 AliWarningClass(Form("ignoring MC info '%s' of wrong type '%s', expecting TObjArray", branchname.Data(), o->ClassName()));
176 return -ENODATA;
177 }
dfe96b90 178 fNrMCParticles=fMCParticles->GetEntriesFast();
d731501a 179 return 0;
180}
181
182bool AliDxHFEToolsMC::RejectByPDG(int pdg, const vector<int> &list) const
183{
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;
190 }
191 return true;
192}
193
dfe96b90 194bool AliDxHFEToolsMC::RejectByPDG(AliVParticle* p, bool doStatistics, int* pdgParticleResult)
d731501a 195{
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();
ea4660f7 200 if(MClabel<0) {
201 return true;
202 }
d731501a 203 int pdgPart=-1;
204 // TODO: there might be more types of particles to be checked
205 AliAODMCParticle* aodmcp=0;
206 aodmcp=dynamic_cast<AliAODMCParticle*>(fMCParticles->At(MClabel));
207 if (aodmcp)
208 pdgPart=TMath::Abs(aodmcp->GetPdgCode());
209 if (pdgPart<0) return 0;
210
dfe96b90 211 if (pdgParticleResult)
212 *pdgParticleResult=pdgPart;
213
d731501a 214 bool bReject=RejectByPDG(pdgPart, fPDGs);
215 if (doStatistics && fHistPDG) {
216 // TODO: think about histogramming mode, e.g. histogramming of rejected particles?
217 if (!bReject) {
218 fHistPDG->Fill(MapPDGLabel(p->PdgCode()));
219 }
220 }
221 return bReject;
222}
223
224bool AliDxHFEToolsMC::RejectByMotherPDG(AliVParticle* p, bool doStatistics)
225{
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?
235 if (!bReject) {
236 fHistPDGMother->Fill(MapPDGMotherLabel(p->PdgCode()));
237 }
238 }
239 return bReject;
240}
241
242int AliDxHFEToolsMC::FindMotherPDG(AliVParticle* p, bool bReturnFirstMother)
243{
244 // Will find and return pdg of the mother, either first or loop down to the
245 // initial quark
246
247 // To reset fOriginMother.
248 fOriginMother=kOriginNone;
249
250 if (!p) return false;
251 int motherpdg=FindPdgOriginMother(p, bReturnFirstMother);
252
253 return motherpdg;
254}
255
d731501a 256TH1* AliDxHFEToolsMC::CreateControlHistogram(const char* name,
257 const char* title,
258 int nBins,
259 const char** binLabels) const
260{
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]);
266 }
267
268 return h.release();
269}
270
271int AliDxHFEToolsMC::MapPDGLabel(int pdg) const
272{
273 /// mapping of pdg code to enum
274 switch (pdg) {
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;
285 default:
286 return kPDGLabelOthers;
287 }
288}
289
290int AliDxHFEToolsMC::MapPDGMotherLabel(int pdg) const
291{
292 /// mapping of pdg code to enum
293 switch (pdg) {
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;
304 default:
305 return kPDGLabelOthers;
306 }
307}
308
309int AliDxHFEToolsMC::FindPdgOriginMother(AliVParticle* p, bool bReturnFirstMother)
310{
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.
318
319 if (!p) return kPDGnone;
320
321 Int_t imother=-1;
322 Int_t MClabel=0;
323
324 // Either using MClabel set from outside (needed for Dmesons), or find it
325 if(fMClabel<0){
326 MClabel = p->GetLabel();
327 if(MClabel<0){
328 return kPDGnone;
329 }
330 }
331 else MClabel=fMClabel;
332
333 // try different classes, unfortunately there is no common base class
334 AliAODMCParticle* aodmcp=0;
b4779749 335 if(fUseKine)
336 aodmcp=dynamic_cast<AliAODMCParticle*>(p);
337 else
338 aodmcp=dynamic_cast<AliAODMCParticle*>(fMCParticles->At(MClabel));
339
d731501a 340 if (!aodmcp) {
341 return kPDGnone;
342 }
343 imother = aodmcp->GetMother();
344
345 // Absolute or +/- on pgd ???
346 Int_t pdg=TMath::Abs(aodmcp->GetPdgCode());
347
348 if (imother<0){
349 // also check this particle
350 CheckOriginMother(pdg);
351 return pdg;
352 }
353
354 if (!fMCParticles->At(imother)) {
355 AliErrorClass(Form("no mc particle with label %d", imother));
356 return pdg;
357 }
358
359 AliAODMCParticle * mother=dynamic_cast<AliAODMCParticle*>(fMCParticles->At(imother));
360 if (!mother) {
361 AliErrorClass(Form("mc mother particle of wrong class type %s", fMCParticles->At(imother)->ClassName()));
362 return pdg;
363 }
364
365 if(bReturnFirstMother){
366 return mother->GetPdgCode();
367 }
368
369 CheckOriginMother(pdg);
370
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
374 return pdg;
375 }
376
377 //Reset fMClabel to find pdg of mother if looping on D
378 fMClabel=-1;
379 pdg=FindPdgOriginMother(mother);
380
381 return pdg;
382}
383
384void AliDxHFEToolsMC::CheckOriginMother(int pdg)
385{
386
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?
389
390 switch(pdg){
391 case(kPDGc):
392 fOriginMother = kOriginCharm; break;
393 case(kPDGb):
394 fOriginMother = kOriginBeauty; break;
395 case(kPDGgluon):
396 if(fOriginMother==kOriginCharm) fOriginMother=kOriginGluonCharm;
397 else if(fOriginMother==kOriginBeauty) fOriginMother=kOriginGluonBeauty;
398 else fOriginMother=kOriginGluon;
399 break;
dfe96b90 400 case(kPDGd):
401 if(!TestIfHFquark(fOriginMother))
402 fOriginMother=kOriginDown;
403 break;
d731501a 404 case(kPDGu):
dfe96b90 405 if(!TestIfHFquark(fOriginMother))
406 fOriginMother=kOriginUp;
407 break;
d731501a 408 case(kPDGs):
dfe96b90 409 if(!TestIfHFquark(fOriginMother))
410 fOriginMother=kOriginStrange;
411 break;
412 }
413}
414
415Bool_t AliDxHFEToolsMC::TestIfHFquark(int origin)
416{
417
418 // Checking if particle has been marked as charm/beauty quark
419
420 Bool_t test=kFALSE;
421 switch(origin){
422 case(kOriginCharm):
423 test=kTRUE; break;
424 case(kOriginBeauty):
425 test=kTRUE; break;
426 case(kOriginGluonCharm):
427 test=kTRUE; break;
428 case(kOriginGluonBeauty):
429 test=kTRUE; break;
d731501a 430 }
dfe96b90 431 return test;
d731501a 432}
433
b4779749 434Bool_t AliDxHFEToolsMC::TestMotherHFMeson(int pdg)
435{
436
437 // Checking if the pdg corresponds to a HF meson (D or B meson)
438
439 Bool_t isD = kFALSE;
440 Bool_t isB = kFALSE;
441 if((pdg>=400 && pdg <500) || (pdg>=4000 && pdg<5000 ))
442 isD = kTRUE;
443 if((pdg>=500 && pdg <600) || (pdg>=5000 && pdg<6000 ))
444 {isD = kFALSE; isB = kTRUE;}
445
446 if(isD || isB) return kTRUE;
447 else return kFALSE;
448
449}
450
451
452
453
d731501a 454void AliDxHFEToolsMC::Clear(const char* /*option*/)
455{
456 // clear internal memory
457 fMCParticles=NULL;
dfe96b90 458 fNrMCParticles=-1;
d731501a 459}
dfe96b90 460
b4779749 461
462int AliDxHFEToolsMC::CheckMCParticle(AliVParticle* p){
463
464 // Checks if MC particle is desired particle
465
466 AliAODMCParticle* mcPart = dynamic_cast<AliAODMCParticle*>(p);
467 if (!mcPart) {
468 AliInfoClass("MC Particle not found in tree, skipping");
469 return -1;
470 }
471
472 Int_t PDG =TMath::Abs(mcPart->PdgCode());
473 int bReject=RejectByPDG(PDG, fPDGs);
474
475 return bReject;
476
477}