#include "AliDxHFEToolsMC.h"
#include "AliAODMCParticle.h"
#include "AliVEvent.h"
#include "AliVParticle.h"
#include "AliLog.h"
#include "TObjArray.h"
#include "TString.h"
#include "TH1D.h"
#include <iostream>
#include <cerrno>
#include <memory>
using namespace std;
ClassImp(AliDxHFEToolsMC)
AliDxHFEToolsMC::AliDxHFEToolsMC(const char* option)
: fSequence(kMCLast)
, fMCParticles(NULL)
, fPDGs()
, fMotherPDGs()
, fHistPDG(NULL)
, fHistPDGMother(NULL)
, fOriginMother(kOriginNone)
, fMClabel(-1)
, fNrMCParticles(-1)
, fUseKine(kFALSE)
{
Init(option);
}
const char* AliDxHFEToolsMC::fgkPDGBinLabels[]={
"positron",
"electron",
"#mu+",
"#mu-",
"#pi+",
"#pi-",
"K+",
"K-",
"proton",
"antiproton",
"others"
};
const char* AliDxHFEToolsMC::fgkPDGMotherBinLabels[]={
"d",
"u",
"s",
"c",
"b",
"gluon",
"gamma",
"#pi^{0}",
"#eta",
"proton",
"others"
};
const char* AliDxHFEToolsMC::fgkStatisticsBinLabels[]={
"all",
"found",
"fake"
};
AliDxHFEToolsMC::~AliDxHFEToolsMC()
{
if (fHistPDG) delete fHistPDG;
fHistPDG=NULL;
if (fHistPDGMother) delete fHistPDGMother;
fHistPDGMother=NULL;
}
int AliDxHFEToolsMC::Init(const char* option)
{
TString strOption(option);
bool bControlHist=true;
std::auto_ptr<TObjArray> tokens(strOption.Tokenize(" "));
if (tokens.get() && tokens->GetEntriesFast()>0) {
for (int itoken=0; itoken<tokens->GetEntriesFast(); itoken++) {
if (tokens->At(itoken)==NULL) continue;
TString arg=tokens->At(itoken)->GetName();
const char* key="";
key="pdg=";
if (arg.BeginsWith(key)) {
arg.ReplaceAll(key, "");
fPDGs.push_back(arg.Atoi());
}
key="mother-pdg=";
if (arg.BeginsWith(key)) {
arg.ReplaceAll(key, "");
fMotherPDGs.push_back(arg.Atoi());
}
key="control-hist=";
if (arg.BeginsWith(key)) {
arg.ReplaceAll(key, "");
bControlHist=arg.CompareTo("off")!=0;
}
key="mc-first";
if (arg.BeginsWith(key)) {
fSequence=kMCFirst;
}
key="mc-last";
if (arg.BeginsWith(key)) {
fSequence=kMCLast;
}
key="usekine";
if(arg.BeginsWith(key)) {
printf("AliDxHFEToolsMC::Init() Using Kinematical\n");
fUseKine=kTRUE;
}
}
}
if (bControlHist) {
fHistPDG=CreateControlHistogram("histPDG",
"pdg code of selected particle",
sizeof(fgkPDGBinLabels)/sizeof(const char*),
fgkPDGBinLabels);
fHistPDGMother=CreateControlHistogram("histPDGMother",
"pdg code of first mother of selected particle",
sizeof(fgkPDGMotherBinLabels)/sizeof(fgkPDGMotherBinLabels[0]),
fgkPDGMotherBinLabels);
}
return 0;
}
int AliDxHFEToolsMC::InitMCParticles(const AliVEvent* pEvent)
{
if (!pEvent) return -EINVAL;
TString branchname(AliAODMCParticle::StdBranchName());
TObject* o=pEvent->FindListObject(branchname);
if (!o) {
AliWarningClass(Form("can not find MC info '%s' in event of type '%s'", branchname.Data(), pEvent->ClassName()));
return -ENOENT;
}
fMCParticles = dynamic_cast<TObjArray*>(o);
if (!fMCParticles) {
AliWarningClass(Form("ignoring MC info '%s' of wrong type '%s', expecting TObjArray", branchname.Data(), o->ClassName()));
return -ENODATA;
}
fNrMCParticles=fMCParticles->GetEntriesFast();
return 0;
}
bool AliDxHFEToolsMC::RejectByPDG(int pdg, const vector<int> &list) const
{
if (list.size()==0) return false;
for (vector<int>::const_iterator i=list.begin();
i!=list.end(); i++) {
if (*i==pdg) return false;
}
return true;
}
bool AliDxHFEToolsMC::RejectByPDG(AliVParticle* p, bool doStatistics, int* pdgParticleResult)
{
if (!p) return false;
Int_t MClabel = p->GetLabel();
if(MClabel<0) {
return true;
}
int pdgPart=-1;
AliAODMCParticle* aodmcp=0;
aodmcp=dynamic_cast<AliAODMCParticle*>(fMCParticles->At(MClabel));
if (aodmcp)
pdgPart=TMath::Abs(aodmcp->GetPdgCode());
if (pdgPart<0) return 0;
if (pdgParticleResult)
*pdgParticleResult=pdgPart;
bool bReject=RejectByPDG(pdgPart, fPDGs);
if (doStatistics && fHistPDG) {
if (!bReject) {
fHistPDG->Fill(MapPDGLabel(p->PdgCode()));
}
}
return bReject;
}
bool AliDxHFEToolsMC::RejectByMotherPDG(AliVParticle* p, bool doStatistics)
{
if (!p) return false;
int motherpdg=FindPdgOriginMother(p);
bool bReject=RejectByPDG(motherpdg, fMotherPDGs);
if (doStatistics && fHistPDGMother) {
if (!bReject) {
fHistPDGMother->Fill(MapPDGMotherLabel(p->PdgCode()));
}
}
return bReject;
}
int AliDxHFEToolsMC::FindMotherPDG(AliVParticle* p, bool bReturnFirstMother)
{
fOriginMother=kOriginNone;
if (!p) return false;
int motherpdg=FindPdgOriginMother(p, bReturnFirstMother);
return motherpdg;
}
TH1* AliDxHFEToolsMC::CreateControlHistogram(const char* name,
const char* title,
int nBins,
const char** binLabels) const
{
std::auto_ptr<TH1> h(new TH1D(name, title, nBins, -0.5, nBins-0.5));
if (!h.get()) return NULL;
for (int iLabel=0; iLabel<nBins; iLabel++) {
h->GetXaxis()->SetBinLabel(iLabel+1, binLabels[iLabel]);
}
return h.release();
}
int AliDxHFEToolsMC::MapPDGLabel(int pdg) const
{
switch (pdg) {
case kPDGelectron : return kPDGLabelElectron;
case -kPDGelectron : return kPDGLabelPositron;
case kPDGmuon : return kPDGLabelMuPlus;
case -kPDGmuon : return kPDGLabelMuMinus;
case kPDGpion : return kPDGLabelPiPlus;
case -kPDGpion : return kPDGLabelPiMinus;
case kPDGkaon : return kPDGLabelKPlus;
case -kPDGkaon : return kPDGLabelKMinus;
case kPDGproton : return kPDGLabelProton;
case -kPDGproton : return kPDGLabelAntiproton;
default:
return kPDGLabelOthers;
}
}
int AliDxHFEToolsMC::MapPDGMotherLabel(int pdg) const
{
switch (pdg) {
case kPDGd : return kPDGMotherLabelD;
case kPDGu : return kPDGMotherLabelU;
case kPDGs : return kPDGMotherLabelS;
case kPDGc : return kPDGMotherLabelC;
case kPDGb : return kPDGMotherLabelB;
case kPDGgluon : return kPDGMotherLabelGluon;
case kPDGgamma : return kPDGMotherLabelGamma;
case kPDGpi0 : return kPDGMotherLabelPi0;
case kPDGeta : return kPDGMotherLabelEta;
case kPDGproton: return kPDGMotherLabelProton;
default:
return kPDGLabelOthers;
}
}
int AliDxHFEToolsMC::FindPdgOriginMother(AliVParticle* p, bool bReturnFirstMother)
{
if (!p) return kPDGnone;
Int_t imother=-1;
Int_t MClabel=0;
if(fMClabel<0){
MClabel = p->GetLabel();
if(MClabel<0){
return kPDGnone;
}
}
else MClabel=fMClabel;
AliAODMCParticle* aodmcp=0;
if(fUseKine)
aodmcp=dynamic_cast<AliAODMCParticle*>(p);
else
aodmcp=dynamic_cast<AliAODMCParticle*>(fMCParticles->At(MClabel));
if (!aodmcp) {
return kPDGnone;
}
imother = aodmcp->GetMother();
Int_t pdg=TMath::Abs(aodmcp->GetPdgCode());
if (imother<0){
CheckOriginMother(pdg);
return pdg;
}
if (!fMCParticles->At(imother)) {
AliErrorClass(Form("no mc particle with label %d", imother));
return pdg;
}
AliAODMCParticle * mother=dynamic_cast<AliAODMCParticle*>(fMCParticles->At(imother));
if (!mother) {
AliErrorClass(Form("mc mother particle of wrong class type %s", fMCParticles->At(imother)->ClassName()));
return pdg;
}
if(bReturnFirstMother){
return mother->GetPdgCode();
}
CheckOriginMother(pdg);
if (mother->GetPdgCode()==kPDGproton){
return pdg;
}
fMClabel=-1;
pdg=FindPdgOriginMother(mother);
return pdg;
}
void AliDxHFEToolsMC::CheckOriginMother(int pdg)
{
switch(pdg){
case(kPDGc):
fOriginMother = kOriginCharm; break;
case(kPDGb):
fOriginMother = kOriginBeauty; break;
case(kPDGgluon):
if(fOriginMother==kOriginCharm) fOriginMother=kOriginGluonCharm;
else if(fOriginMother==kOriginBeauty) fOriginMother=kOriginGluonBeauty;
else fOriginMother=kOriginGluon;
break;
case(kPDGd):
if(!TestIfHFquark(fOriginMother))
fOriginMother=kOriginDown;
break;
case(kPDGu):
if(!TestIfHFquark(fOriginMother))
fOriginMother=kOriginUp;
break;
case(kPDGs):
if(!TestIfHFquark(fOriginMother))
fOriginMother=kOriginStrange;
break;
}
}
Bool_t AliDxHFEToolsMC::TestIfHFquark(int origin)
{
Bool_t test=kFALSE;
switch(origin){
case(kOriginCharm):
test=kTRUE; break;
case(kOriginBeauty):
test=kTRUE; break;
case(kOriginGluonCharm):
test=kTRUE; break;
case(kOriginGluonBeauty):
test=kTRUE; break;
}
return test;
}
Bool_t AliDxHFEToolsMC::TestMotherHFMeson(int pdg)
{
Bool_t isD = kFALSE;
Bool_t isB = kFALSE;
if((pdg>=400 && pdg <500) || (pdg>=4000 && pdg<5000 ))
isD = kTRUE;
if((pdg>=500 && pdg <600) || (pdg>=5000 && pdg<6000 ))
{isD = kFALSE; isB = kTRUE;}
if(isD || isB) return kTRUE;
else return kFALSE;
}
void AliDxHFEToolsMC::Clear(const char* )
{
fMCParticles=NULL;
fNrMCParticles=-1;
}
int AliDxHFEToolsMC::CheckMCParticle(AliVParticle* p){
AliAODMCParticle* mcPart = dynamic_cast<AliAODMCParticle*>(p);
if (!mcPart) {
AliInfoClass("MC Particle not found in tree, skipping");
return -1;
}
Int_t PDG =TMath::Abs(mcPart->PdgCode());
int bReject=RejectByPDG(PDG, fPDGs);
return bReject;
}