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 AliDxHFEParticleSelectionMCEl.cxx
20 /// @author Hege Erdal, Matthias Richter
22 /// @brief MC El selection for D0-HFE correlation
25 #include "AliDxHFEParticleSelectionMCEl.h"
26 #include "AliVParticle.h"
28 #include "THnSparse.h"
29 #include "AliAODMCParticle.h"
32 #include "AliAODTrack.h"
33 #include "AliReducedParticle.h"
42 /// ROOT macro for the implementation of ROOT specific class methods
43 ClassImp(AliDxHFEParticleSelectionMCEl)
45 AliDxHFEParticleSelectionMCEl::AliDxHFEParticleSelectionMCEl(const char* opt)
46 : AliDxHFEParticleSelectionEl(opt)
48 , fPDGnotMCElectron(NULL)
54 , fSelectionStep(AliDxHFEParticleSelectionEl::kNoCuts)
62 fMCTools.~AliDxHFEToolsMC();
66 // This is also checked in AddTasks, but just for safety!
67 if(fUseMCReco && fUseKine) AliFatal("CAN'T SET BOTH usekine AND elmcreco AT THE SAME TIME");
69 // TODO: argument scan, build tool options accordingly
70 // e.g. set mc mode first/last, skip control histograms
71 TString toolopt("pdg=11 mc-last");
72 if(fUseKine) toolopt+=" usekine";
73 new (&fMCTools) AliDxHFEToolsMC(toolopt);
76 //at the moment not used, keep for now (to be used when plotting)
77 const char* AliDxHFEParticleSelectionMCEl::fgkPDGMotherBinLabels[]={
92 const char* AliDxHFEParticleSelectionMCEl::fgkPDGBinLabels[]={
106 AliDxHFEParticleSelectionMCEl::~AliDxHFEParticleSelectionMCEl()
110 if(fPDGnotMCElectron){
111 delete fPDGnotMCElectron;
112 fPDGnotMCElectron=NULL;
117 int AliDxHFEParticleSelectionMCEl::Init()
123 // Particles considered HFE background. can be expanded
124 fMotherPDGs.push_back(AliDxHFEToolsMC::kPDGpi0);
125 fMotherPDGs.push_back(AliDxHFEToolsMC::kPDGeta);
126 fMotherPDGs.push_back(AliDxHFEToolsMC::kPDGgamma);
127 fMotherPDGs.push_back(AliDxHFEToolsMC::kPDGJpsi);
130 iResult=AliDxHFEParticleSelectionEl::Init();
131 if (iResult<0) return iResult;
133 // Histo containing PDG of track which was not MC truth electron
134 // TODO: Add to list in baseclass
135 fPDGnotMCElectron=CreateControlHistogram("fPDGnotMCElectron","PDG of track not MC truth electron",AliDxHFEToolsMC::kNofPDGLabels,fgkPDGBinLabels);
136 AddControlObject(fPDGnotMCElectron);
140 THnSparse* AliDxHFEParticleSelectionMCEl::DefineTHnSparse()
143 // Defines the THnSparse.
145 const int thnSize = 4;
146 InitTHnSparseArray(thnSize);
147 const double Pi=TMath::Pi();
149 name.Form("%s info", GetName());
153 int thnBins[thnSize] = { 1000, 200, 500, 15 };
154 double thnMin [thnSize] = { 0, 0, -1., -1.5 };
155 double thnMax [thnSize] = { 100, 2*Pi, 1., 13.5 };
156 const char* thnNames[thnSize]={
160 "Mother", //bin==-1: Not MC truth electron
163 return CreateControlTHnSparse(name,thnSize,thnBins,thnMin,thnMax,thnNames);
166 int AliDxHFEParticleSelectionMCEl::FillParticleProperties(AliVParticle* p, Double_t* data, int dimension) const
168 // fill the data array from the particle data
169 if (!data) return -EINVAL;
170 AliAODTrack *track=(AliAODTrack*)p;
171 if (!track) return -ENODATA;
173 if (dimension!=GetDimTHnSparse()) {
174 // TODO: think about filling only the available data and throwing a warning
177 data[i++]=track->Pt();
178 data[i++]=track->Phi();
179 data[i++]=track->Eta();
180 data[i++]=fOriginMother;
185 int AliDxHFEParticleSelectionMCEl::IsSelected(AliVParticle* p, const AliVEvent* pEvent)
187 /// overloaded from AliDxHFEParticleSelection: check particle
188 /// H: Have changed function. Now doing particle selection first, then run MC over
189 /// selected tracks. Could configure it to be configurable, but not sure if it
191 /// Result from normal track selection is returned, result from MC is stored in
200 if(!fUseKine && !fUseMCReco){
202 // optional MC selection before the particle selection
203 if (fMCTools.MCFirst() && (iResult=CheckMC(p, pEvent))==0) {
208 // step 2 or 1, depending on sequence:
209 // normal particle selection
210 iResult=AliDxHFEParticleSelectionEl::IsSelected(p, pEvent);
211 if (fMCTools.MCFirst() || iResult==0) return iResult;
216 // step 2, only executed if MC check is last
217 // optional MC selection after the particle selection
218 // result stored to be filled into THnSparse
219 // TODO: strictly speaken the particles should be rejected
220 // if not mc selected, however skip this for the moment, because of
222 // This line will run always when running directly over the stack or over MC reconstructed tracks
223 // For MC reconstructed tracks, should consider adding more constrictions on the tracks,
224 // maybe do the track selection first (which means could call AliDxHFEParticleSelectionEl::IsSelected()
227 if(fUseMCReco && ( fSelectionStep > AliDxHFEParticleSelectionEl::kNoCuts )){
228 iResult=AliDxHFEParticleSelectionEl::IsSelected(p, pEvent);
229 if(iResult ==0) return iResult;
231 fResultMC=CheckMC(p, pEvent);
233 if(fUseKine || fUseMCReco)
240 int AliDxHFEParticleSelectionMCEl::CheckMC(AliVParticle* p, const AliVEvent* pEvent)
242 /// check if MC criteria are fulfilled
248 if (!fMCTools.IsInitialized() && (iResult=fMCTools.InitMCParticles(pEvent))<0) {
249 // TODO: message? but has to be filtered in order to avoid message flood
250 return 0; // no meaningful filtering on mc possible
254 // If run on kinematical level, check if particle is electron (only ones who are relevant)
255 // and if pass IsPhysicalPrimary()
256 Int_t test = fMCTools.CheckMCParticle(p);
257 if(test==1) return 0;
258 // Add additional contraints on the electrons?
259 // remove delta e? also remove E<300MeV?
260 // Should also mark dalitz decay and gamma conversion..
261 AliAODMCParticle *mcp=dynamic_cast<AliAODMCParticle*>(p);
262 if(!mcp->IsPhysicalPrimary()) return 0;
267 if (!fUseKine && fMCTools.RejectByPDG(p,false, &pdgParticle)) {
269 // TODO: Move this to fMCTools???? Can this be part of the statistics in the MC class?
270 fPDGnotMCElectron->Fill(fMCTools.MapPDGLabel(pdgParticle));
275 // Find PDG of first mother
276 pdgMother=fMCTools.FindMotherPDG(p,AliDxHFEToolsMC::kGetFirstMother);
278 // Check if first mother is counted as background
279 Bool_t isNotBackground=fMCTools.RejectByPDG(pdgMother,fMotherPDGs);
281 if(!isNotBackground){
282 // Set fOriginMother if mother is counted as background
283 // TODO: Could this be done in a more elegant way?
285 case(AliDxHFEToolsMC::kPDGpi0): fOriginMother=AliDxHFEToolsMC::kNrOrginMother; break;
286 case(AliDxHFEToolsMC::kPDGeta): fOriginMother=AliDxHFEToolsMC::kNrOrginMother+1; break;
287 case(AliDxHFEToolsMC::kPDGgamma): fOriginMother=AliDxHFEToolsMC::kNrOrginMother+2;break;
288 case(AliDxHFEToolsMC::kPDGJpsi): fOriginMother=AliDxHFEToolsMC::kNrOrginMother+3;break;
292 // If loop over Stack, also checks if First mother is a HF meson
293 Bool_t isHFmeson =fMCTools.TestMotherHFMeson(TMath::Abs(pdgMother));
296 // If first mother is a HF meson, loops back to find
297 // original quark + if there was a gluon. Result is
298 // stored in fOriginMother
299 pdgMother=fMCTools.FindMotherPDG(p,AliDxHFEToolsMC::kGetOriginMother);
300 fOriginMother=fMCTools.GetOriginMother();
303 fOriginMother=AliDxHFEToolsMC::kNrOrginMother+4;
311 void AliDxHFEParticleSelectionMCEl::Clear(const char* option)
313 /// clear internal memory
314 fMCTools.Clear(option);
317 AliVParticle *AliDxHFEParticleSelectionMCEl::CreateParticle(AliVParticle* track)
320 AliReducedParticle *part = new AliReducedParticle(track->Eta(), track->Phi(), track->Pt(),track->Charge(),fOriginMother);
326 int AliDxHFEParticleSelectionMCEl::ParseArguments(const char* arguments)
328 // parse arguments and set internal flags
329 TString strArguments(arguments);
330 auto_ptr<TObjArray> tokens(strArguments.Tokenize(" "));
331 if (!tokens.get()) return 0;
333 AliInfo(strArguments);
334 TIter next(tokens.get());
336 while ((token=next())) {
337 TString argument=token->GetName();
338 if (argument.BeginsWith("usekine") ){
342 if (argument.BeginsWith("elmcreco")){
344 if(argument.BeginsWith("elmcreco=")){
345 argument.ReplaceAll("elmcreco=", "");
346 if(argument.CompareTo("aftertrackcuts")==0) fSelectionStep=AliDxHFEParticleSelectionEl::kHFEcutsTPC;
347 if(argument.CompareTo("aftertofpid")==0) fSelectionStep=AliDxHFEParticleSelectionEl::kPIDTOF;
348 if(argument.CompareTo("afterfullpid")==0) fSelectionStep=AliDxHFEParticleSelectionEl::kPIDTOFTPC;
350 AliDxHFEParticleSelectionEl::SetFinalCutStep(fSelectionStep);
355 // forwarding of single argument works, unless key-option pairs separated
356 // by blanks are introduced
357 AliDxHFEParticleSelection::ParseArguments(argument);