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)
49 , fPDGNotHFMother(NULL)
55 , fSelectionStep(AliDxHFEParticleSelectionEl::kNoCuts)
56 , fStoreCutStepInfo(kFALSE)
64 fMCTools.~AliDxHFEToolsMC();
68 // This is also checked in AddTasks, but just for safety!
69 if(fUseMCReco && fUseKine) AliFatal("CAN'T SET BOTH usekine AND elmcreco AT THE SAME TIME");
71 // TODO: argument scan, build tool options accordingly
72 // e.g. set mc mode first/last, skip control histograms
73 TString toolopt("pdg=11 mc-last");
74 if(fUseKine) toolopt+=" usekine";
75 new (&fMCTools) AliDxHFEToolsMC(toolopt);
78 //at the moment not used, keep for now (to be used when plotting)
79 const char* AliDxHFEParticleSelectionMCEl::fgkPDGMotherBinLabels[]={
94 const char* AliDxHFEParticleSelectionMCEl::fgkPDGBinLabels[]={
108 AliDxHFEParticleSelectionMCEl::~AliDxHFEParticleSelectionMCEl()
112 if(fPDGnotMCElectron){
113 delete fPDGnotMCElectron;
114 fPDGnotMCElectron=NULL;
119 int AliDxHFEParticleSelectionMCEl::Init()
125 // Particles considered HFE background. can be expanded
126 fMotherPDGs.push_back(AliDxHFEToolsMC::kPDGpi0);
127 fMotherPDGs.push_back(AliDxHFEToolsMC::kPDGeta);
128 fMotherPDGs.push_back(AliDxHFEToolsMC::kPDGgamma);
129 fMotherPDGs.push_back(AliDxHFEToolsMC::kPDGJpsi);
132 iResult=AliDxHFEParticleSelectionEl::Init();
133 if (iResult<0) return iResult;
135 // Histo containing PDG of track which was not MC truth electron
136 // TODO: Add to list in baseclass
137 fPDGnotMCElectron=CreateControlHistogram("fPDGnotMCElectron","PDG of track not MC truth electron",AliDxHFEToolsMC::kNofPDGLabels,fgkPDGBinLabels);
138 fPDGNotHFMother=CreateControlHistogram("fPDGNotHFMother","PDG of mother not HF",5000);
139 AddControlObject(fPDGnotMCElectron);
140 AddControlObject(fPDGNotHFMother);
144 THnSparse* AliDxHFEParticleSelectionMCEl::DefineTHnSparse()
147 // Defines the THnSparse.
149 const double Pi=TMath::Pi();
152 name.Form("%s info", GetName());
154 if(fStoreCutStepInfo){
155 const int thnSizeExt =5;
157 InitTHnSparseArray(thnSizeExt);
159 // TODO: Redo binning of distributions more?
162 int thnBinsExt[thnSizeExt] = { 100, 100, 100, 15, kNCutLabels };
163 double thnMinExt [thnSizeExt] = { 0, 0, -1., -1.5, kRecKineITSTPC };
164 double thnMaxExt [thnSizeExt] = { 10, 2*Pi, 1., 13.5, kSelected };
165 const char* thnNamesExt[thnSizeExt]={
169 "Mother", //bin==-1: Not MC truth electron
170 "Last survived cut step"
172 thn=(THnSparse*)CreateControlTHnSparse(name,thnSizeExt,thnBinsExt,thnMinExt,thnMaxExt,thnNamesExt);
176 const int thnSize =4;
177 InitTHnSparseArray(thnSize);
179 // TODO: Redo binning of distributions more?
182 int thnBins[thnSize] = { 100, 100, 100, 15 };
183 double thnMin [thnSize] = { 0, 0, -1., -1.5 };
184 double thnMax [thnSize] = { 10, 2*Pi, 1., 13.5 };
185 const char* thnNames[thnSize]={
189 "Mother", //bin==-1: Not MC truth electron
191 thn=(THnSparse*)CreateControlTHnSparse(name,thnSize,thnBins,thnMin,thnMax,thnNames);
197 int AliDxHFEParticleSelectionMCEl::FillParticleProperties(AliVParticle* p, Double_t* data, int dimension) const
199 // fill the data array from the particle data
200 if (!data) return -EINVAL;
201 if (!p) return -ENODATA;
202 // handle different types of tracks, can be extended
203 AliReducedParticle *trRP=dynamic_cast<AliReducedParticle*>(p);
205 if (dimension!=GetDimTHnSparse()) {
206 // TODO: think about filling only the available data and throwing a warning
209 memset(data, 0, dimension*sizeof(data[0]));
213 if (trRP) data[i]=trRP->GetOriginMother();
214 else data[i]=fOriginMother;
215 i++; // take out of conditionals to be save
217 if(fStoreCutStepInfo) data[i]=GetLastSurvivedCutsStep();
218 i++; // take out of conditionals to be save
223 int AliDxHFEParticleSelectionMCEl::IsSelected(AliVParticle* p, const AliVEvent* pEvent)
225 /// overloaded from AliDxHFEParticleSelection: check particle
226 /// H: Have changed function. Now doing particle selection first, then run MC over
227 /// selected tracks. Could configure it to be configurable, but not sure if it
229 /// Result from normal track selection is returned, result from MC is stored in
238 if(!fUseKine && !fUseMCReco){
240 // optional MC selection before the particle selection
241 if (fMCTools.MCFirst() && (iResult=CheckMC(p, pEvent))==0) {
246 // step 2 or 1, depending on sequence:
247 // normal particle selection
248 iResult=AliDxHFEParticleSelectionEl::IsSelected(p, pEvent);
249 if (fMCTools.MCFirst() || iResult==0) return iResult;
254 // step 2, only executed if MC check is last
255 // optional MC selection after the particle selection
256 // result stored to be filled into THnSparse
257 // TODO: strictly speaken the particles should be rejected
258 // if not mc selected, however skip this for the moment, because of
260 // This line will run always when running directly over the stack or over MC reconstructed tracks
261 // For MC reconstructed tracks, should consider adding more constrictions on the tracks,
262 // maybe do the track selection first (which means could call AliDxHFEParticleSelectionEl::IsSelected()
265 if(fUseMCReco) {// && ( fSelectionStep > AliDxHFEParticleSelectionEl::kNoCuts )){
266 // always check the base class method in mode fUseMCReco
267 iResult=AliDxHFEParticleSelectionEl::IsSelected(p, pEvent);
268 if(iResult == 0) return iResult;
270 fResultMC=CheckMC(p, pEvent);
272 if(fUseKine || fUseMCReco)
279 int AliDxHFEParticleSelectionMCEl::CheckMC(AliVParticle* p, const AliVEvent* pEvent)
281 /// check if MC criteria are fulfilled
287 if (!fMCTools.IsInitialized() && (iResult=fMCTools.InitMCParticles(pEvent))<0) {
288 // TODO: message? but has to be filtered in order to avoid message flood
289 return 0; // no meaningful filtering on mc possible
293 // If run on kinematical level, check if particle is electron (only ones who are relevant)
294 // and if pass IsPhysicalPrimary()
295 Int_t test = fMCTools.CheckMCParticle(p);
296 if(test==1) return 0;
297 // Add additional contraints on the electrons?
298 // remove delta e? also remove E<300MeV?
299 // Should also mark dalitz decay and gamma conversion..
300 AliAODMCParticle *mcp=dynamic_cast<AliAODMCParticle*>(p);
301 if(!mcp || !mcp->IsPhysicalPrimary()) return 0;
306 if (!fUseKine && fMCTools.RejectByPDG(p,false, &pdgParticle)) {
308 // TODO: Move this to fMCTools???? Can this be part of the statistics in the MC class?
309 fPDGnotMCElectron->Fill(fMCTools.MapPDGLabel(pdgParticle));
314 // Find PDG of first mother
315 pdgMother=fMCTools.FindMotherPDG(p,AliDxHFEToolsMC::kGetFirstMother);
317 // Check if first mother is counted as background
318 Bool_t isNotBackground=fMCTools.RejectByPDG(pdgMother,fMotherPDGs);
320 if(!isNotBackground){
321 // Set fOriginMother if mother is counted as background
322 // TODO: Could this be done in a more elegant way?
324 case(AliDxHFEToolsMC::kPDGpi0): fOriginMother=AliDxHFEToolsMC::kNrOrginMother; break;
325 case(AliDxHFEToolsMC::kPDGeta): fOriginMother=AliDxHFEToolsMC::kNrOrginMother+1; break;
326 case(AliDxHFEToolsMC::kPDGgamma): fOriginMother=AliDxHFEToolsMC::kNrOrginMother+2;break;
327 case(AliDxHFEToolsMC::kPDGJpsi): fOriginMother=AliDxHFEToolsMC::kNrOrginMother+3;break;
331 // If loop over Stack, also checks if First mother is a HF meson
332 Bool_t isHFmeson =fMCTools.TestMotherHFMeson(TMath::Abs(pdgMother));
335 // If first mother is a HF meson, loops back to find
336 // original quark + if there was a gluon. Result is
337 // stored in fOriginMother
338 pdgMother=fMCTools.FindMotherPDG(p,AliDxHFEToolsMC::kGetOriginMother);
339 fOriginMother=fMCTools.GetOriginMother();
343 fPDGNotHFMother->Fill(pdgMother);
344 fOriginMother=AliDxHFEToolsMC::kNrOrginMother+4;
352 void AliDxHFEParticleSelectionMCEl::Clear(const char* option)
354 /// clear internal memory
355 fMCTools.Clear(option);
358 AliVParticle *AliDxHFEParticleSelectionMCEl::CreateParticle(AliVParticle* track)
361 AliReducedParticle *part = new AliReducedParticle(track->Eta(), track->Phi(), track->Pt(),track->Charge(),fOriginMother);
367 int AliDxHFEParticleSelectionMCEl::ParseArguments(const char* arguments)
369 // parse arguments and set internal flags
370 TString strArguments(arguments);
371 auto_ptr<TObjArray> tokens(strArguments.Tokenize(" "));
372 if (!tokens.get()) return 0;
374 AliInfo(strArguments);
375 TIter next(tokens.get());
377 while ((token=next())) {
378 TString argument=token->GetName();
379 if (argument.BeginsWith("usekine") ){
383 if (argument.BeginsWith("elmcreco")){
385 if(argument.BeginsWith("elmcreco=")){
386 argument.ReplaceAll("elmcreco=", "");
387 if(argument.CompareTo("alltracks")==0) fSelectionStep=AliDxHFEParticleSelectionEl::kNoCuts;
388 if(argument.CompareTo("afterreckineitstpc")==0) fSelectionStep=AliDxHFEParticleSelectionEl::kRecKineITSTPC;
389 if(argument.CompareTo("afterrecprim")==0) fSelectionStep=AliDxHFEParticleSelectionEl::kRecPrim;
390 if(argument.CompareTo("afterhfeits")==0) fSelectionStep=AliDxHFEParticleSelectionEl::kHFEcutsITS;
391 if(argument.CompareTo("afterhfetof")==0) fSelectionStep=AliDxHFEParticleSelectionEl::kHFEcutsTOF;
392 if(argument.CompareTo("afterhfetpc")==0) fSelectionStep=AliDxHFEParticleSelectionEl::kHFEcutsTPC;
393 if(argument.CompareTo("aftertrackcuts")==0) fSelectionStep=AliDxHFEParticleSelectionEl::kHFEcutsTPC;
394 if(argument.CompareTo("aftertofpid")==0) fSelectionStep=AliDxHFEParticleSelectionEl::kPIDTOF;
395 if(argument.CompareTo("aftertpcpid")==0) fSelectionStep=AliDxHFEParticleSelectionEl::kPIDTPC;
396 if(argument.CompareTo("afterfullpid")==0) fSelectionStep=AliDxHFEParticleSelectionEl::kPIDTOFTPC;
398 AliDxHFEParticleSelectionEl::SetFinalCutStep(fSelectionStep);
402 if(argument.BeginsWith("storelastcutstep")){
403 AliInfo("Stores the last cut step");
405 fStoreCutStepInfo=kTRUE;
406 AliDxHFEParticleSelectionEl::SetStoreLastCutStep(kTRUE);
409 // forwarding of single argument works, unless key-option pairs separated
410 // by blanks are introduced
411 AliDxHFEParticleSelection::ParseArguments(argument);