]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PWGHF/hfe/AliAnalysisTaskHFE.cxx
Update of hfe code
[u/mrichter/AliRoot.git] / PWGHF / hfe / AliAnalysisTaskHFE.cxx
1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 *                                                                        *
4 * Author: The ALICE Off-line Project.                                    *
5 * Contributors are mentioned in the code where appropriate.              *
6 *                                                                        *
7 * Permission to use, copy, modify and distribute this software and its   *
8 * documentation strictly for non-commercial purposes is hereby granted   *
9 * without fee, provided that the above copyright notice appears in all   *
10 * copies and that both the copyright notice and this permission notice   *
11 * appear in the supporting documentation. The authors make no claims     *
12 * about the suitability of this software for any purpose. It is          *
13 * provided "as is" without express or implied warranty.                  *
14 **************************************************************************/
15 //
16 // The analysis task:
17 // Filling an AliCFContainer with the quantities pt, eta and phi
18 // for tracks which survivied the particle cuts (MC resp. ESD tracks)
19 // Track selection is done using the AliHFE package
20 // 
21 // Author:
22 //  Raphaelle Bailhache <R.Bailhache@gsi.de>
23 //  Markus Fasel <M.Fasel@gsi.de>
24 //  Matus Kalisky <matus.kalisky@cern.ch>
25 //  MinJung Kweon <minjung@physi.uni-heidelberg.de>
26 //
27 #include <TAxis.h>
28 #include <TBits.h>
29 #include <TCanvas.h>
30 #include <TChain.h>
31 #include <TDirectory.h>
32 #include <TFile.h>
33 #include <TH3D.h>
34 #include <TIterator.h>
35 #include <TList.h>
36 #include <TLegend.h>
37 #include <TMath.h>
38 #include <TObjArray.h>
39 #include <TObjString.h>
40 #include <TParticle.h>
41 #include <TProfile.h>
42 #include <TString.h>
43 #include <TF1.h>
44 #include <TTree.h>
45
46 #include "AliESDtrackCuts.h"
47 #include "AliAnalysisManager.h"
48 #include "AliAODInputHandler.h"
49 #include "AliAODMCParticle.h"
50 #include "AliAODTrack.h"
51 #include "AliAODVertex.h"
52 #include "AliCentrality.h"
53 #include "AliCFContainer.h"
54 #include "AliCFManager.h"
55 #include "AliESDEvent.h"
56 #include "AliESDInputHandler.h"
57 #include "AliESDtrack.h"
58 #include "AliLog.h"
59 #include "AliMCEvent.h"
60 #include "AliMCEventHandler.h"
61 #include "AliMCParticle.h"
62 #include "AliMultiplicity.h"
63 #include "AliPID.h"
64 #include "AliPIDResponse.h"
65 #include "AliOADBContainer.h"
66 #include "AliStack.h"
67 #include "AliTriggerAnalysis.h"
68 #include "AliVVertex.h"
69
70 #include "AliHFEcollection.h"
71 #include "AliHFEcontainer.h"
72 #include "AliHFEcuts.h"
73 #include "AliHFEelecbackground.h"
74 #include "AliHFENonPhotonicElectron.h"
75 #include "AliHFEmcQA.h"
76 #include "AliHFEpairs.h"
77 #include "AliHFEpid.h"
78 #include "AliHFEpidQAmanager.h"
79 #include "AliHFEpostAnalysis.h"
80 #include "AliHFEsecVtxs.h"
81 #include "AliHFEsecVtx.h"
82 #include "AliHFEsignalCuts.h"
83 #include "AliHFEtaggedTrackAnalysis.h"
84 #include "AliHFEtools.h"
85 #include "AliHFEvarManager.h"
86 #include "AliAnalysisTaskHFE.h"
87 #include "AliAODMCHeader.h"
88 #include "TClonesArray.h"
89
90 ClassImp(AliAnalysisTaskHFE)
91
92 //____________________________________________________________
93 AliAnalysisTaskHFE::AliAnalysisTaskHFE():
94 AliAnalysisTaskSE("PID efficiency Analysis")
95   , fAODMCHeader(NULL)
96   , fAODArrayMCInfo(NULL)
97   , fQAlevel(0)
98   , fPlugins(0)
99   , fFillSignalOnly(kTRUE)
100   , fFillNoCuts(kFALSE)
101   , fUseFilterAOD(kTRUE)
102   , fApplyCutAOD(kFALSE)
103   , fFilter(1<<4)
104   , fBackGroundFactorApply(kFALSE)
105   , fRemovePileUp(kFALSE)
106   , fIdentifiedAsPileUp(kFALSE)
107   , fIdentifiedAsOutInz(kFALSE)
108   , fPassTheEventCut(kFALSE)
109   , fRejectKinkMother(kTRUE)
110   , fisppMultiBin(kFALSE)
111   , fPbPbUserCentralityBinning(kFALSE)
112   , fisNonHFEsystematics(kFALSE)
113   , fSpecialTrigger(NULL)
114   , fCentralityF(-1)
115   , fCentralityPercent(-1)
116   , fContributors(0.5)
117   , fWeightBackGround(0.)
118   , fVz(0.0)
119   , fHadronBackgroundOADB(NULL)
120   , fContainer(NULL)
121   , fVarManager(NULL)
122   , fSignalCuts(NULL)
123   , fCFM(NULL)
124   , fTriggerAnalysis(NULL)
125   , fPID(NULL)
126   , fPIDqa(NULL)
127   , fPIDpreselect(NULL)
128   , fCuts(NULL)
129   , fTaggedTrackCuts(NULL)
130   , fCleanTaggedTrack(kFALSE)
131   , fVariablesTRDTaggedTrack(kFALSE)
132   , fCutspreselect(NULL)
133   , fSecVtx(NULL)
134   , fElecBackGround(NULL)
135   , fMCQA(NULL)
136   , fTaggedTrackAnalysis(NULL)
137   , fExtraCuts(NULL)
138   , fBackgroundSubtraction(NULL)
139   , fQA(NULL)
140   , fOutput(NULL)
141   , fHistMCQA(NULL)
142   , fHistSECVTX(NULL)
143   , fHistELECBACKGROUND(NULL)
144   , fQACollection(NULL)
145   , fQAAODCollection(NULL)
146 {
147   //
148   // Dummy constructor
149   //
150   memset(fElecBackgroundFactor, 0, sizeof(Double_t) * kElecBgSpecies * kBgPtBins * kCentBins * kBgLevels);
151   memset(fkBackGroundFactorArray, 0, sizeof(TF1 *) * 12);
152   memset(fBinLimit, 0, sizeof(Double_t) * (kBgPtBins+1));
153   memset(&fisppMultiBin, kFALSE, sizeof(fisppMultiBin));
154   memset(fCentralityLimits, 0, sizeof(Float_t) * 12);
155
156
157 }
158
159 //____________________________________________________________
160 AliAnalysisTaskHFE::AliAnalysisTaskHFE(const char * name):
161   AliAnalysisTaskSE(name)
162   , fAODMCHeader(NULL)
163   , fAODArrayMCInfo(NULL)
164   , fQAlevel(0)
165   , fPlugins(0)
166   , fFillSignalOnly(kTRUE)
167   , fFillNoCuts(kFALSE)
168   , fUseFilterAOD(kTRUE)
169   , fApplyCutAOD(kFALSE)
170   , fFilter(1<<4)
171   , fBackGroundFactorApply(kFALSE)
172   , fRemovePileUp(kFALSE)
173   , fIdentifiedAsPileUp(kFALSE)
174   , fIdentifiedAsOutInz(kFALSE)
175   , fPassTheEventCut(kFALSE)  
176   , fRejectKinkMother(kTRUE)
177   , fisppMultiBin(kFALSE)
178   , fPbPbUserCentralityBinning(kFALSE)
179   , fisNonHFEsystematics(kFALSE)
180   , fSpecialTrigger(NULL)
181   , fCentralityF(-1)
182   , fCentralityPercent(-1)
183   , fContributors(0.5)
184   , fWeightBackGround(0.)
185   , fVz(0.0)
186   , fHadronBackgroundOADB(NULL)
187   , fContainer(NULL)
188   , fVarManager(NULL)
189   , fSignalCuts(NULL)
190   , fCFM(NULL)
191   , fTriggerAnalysis(NULL)
192   , fPID(NULL)
193   , fPIDqa(NULL)
194   , fPIDpreselect(NULL)
195   , fCuts(NULL)
196   , fTaggedTrackCuts(NULL)
197   , fCleanTaggedTrack(kFALSE)
198   , fVariablesTRDTaggedTrack(kFALSE)
199   , fCutspreselect(NULL)
200   , fSecVtx(NULL)
201   , fElecBackGround(NULL)
202   , fMCQA(NULL)
203   , fTaggedTrackAnalysis(NULL)
204   , fExtraCuts(NULL)
205   , fBackgroundSubtraction(NULL)
206   , fQA(NULL)
207   , fOutput(NULL)
208   , fHistMCQA(NULL)
209   , fHistSECVTX(NULL)
210   , fHistELECBACKGROUND(NULL)
211   , fQACollection(0x0)
212   , fQAAODCollection(NULL)
213 {
214   //
215   // Default constructor
216   // 
217   DefineOutput(1, TList::Class());
218   DefineOutput(2, TList::Class());
219
220   fPID = new AliHFEpid("hfePid");
221   fPIDqa = new AliHFEpidQAmanager;
222   fVarManager = new AliHFEvarManager("hfeVarManager");
223
224   memset(fElecBackgroundFactor, 0, sizeof(Double_t) * kElecBgSpecies * kBgPtBins * kCentBins * kBgLevels);
225   memset(fkBackGroundFactorArray, 0, sizeof(TF1 *) * 12);
226   memset(fBinLimit, 0, sizeof(Double_t) * (kBgPtBins+1));
227   memset(&fisppMultiBin, kFALSE, sizeof(fisppMultiBin));
228   memset(fCentralityLimits, 0, sizeof(Float_t) * 12);
229
230 }
231
232 //____________________________________________________________
233 AliAnalysisTaskHFE::AliAnalysisTaskHFE(const AliAnalysisTaskHFE &ref):
234   AliAnalysisTaskSE(ref)
235   , fAODMCHeader(NULL)
236   , fAODArrayMCInfo(NULL)
237   , fQAlevel(0)
238   , fPlugins(0)
239   , fFillSignalOnly(ref.fFillSignalOnly)
240   , fFillNoCuts(ref.fFillNoCuts)
241   , fUseFilterAOD(ref.fUseFilterAOD)
242   , fApplyCutAOD(ref.fApplyCutAOD)
243   , fFilter(ref.fFilter) 
244   , fBackGroundFactorApply(ref.fBackGroundFactorApply)
245   , fRemovePileUp(ref.fRemovePileUp)
246   , fIdentifiedAsPileUp(ref.fIdentifiedAsPileUp)
247   , fIdentifiedAsOutInz(ref.fIdentifiedAsOutInz)
248   , fPassTheEventCut(ref.fPassTheEventCut)
249   , fRejectKinkMother(ref.fRejectKinkMother)
250   , fisppMultiBin(ref.fisppMultiBin)
251   , fPbPbUserCentralityBinning(ref.fPbPbUserCentralityBinning)
252   , fisNonHFEsystematics(ref.fisNonHFEsystematics)
253   , fSpecialTrigger(ref.fSpecialTrigger)
254   , fCentralityF(ref.fCentralityF)
255   , fCentralityPercent(ref.fCentralityPercent)
256   , fContributors(ref.fContributors)
257   , fWeightBackGround(ref.fWeightBackGround)
258   , fVz(ref.fVz)
259   , fHadronBackgroundOADB(ref.fHadronBackgroundOADB)
260   , fContainer(NULL)
261   , fVarManager(NULL)
262   , fSignalCuts(NULL)
263   , fCFM(NULL)
264   , fTriggerAnalysis(NULL)
265   , fPID(NULL)
266   , fPIDqa(NULL)
267   , fPIDpreselect(NULL)
268   , fCuts(NULL)
269   , fTaggedTrackCuts(NULL)
270   , fCleanTaggedTrack(ref.fCleanTaggedTrack)
271   , fVariablesTRDTaggedTrack(ref.fVariablesTRDTaggedTrack)
272   , fCutspreselect(NULL)
273   , fSecVtx(NULL)
274   , fElecBackGround(NULL)
275   , fMCQA(NULL)
276   , fTaggedTrackAnalysis(NULL)
277   , fExtraCuts(NULL)
278   , fBackgroundSubtraction(NULL)
279   , fQA(NULL)
280   , fOutput(NULL)
281   , fHistMCQA(NULL)
282   , fHistSECVTX(NULL)
283   , fHistELECBACKGROUND(NULL)
284   , fQACollection(NULL)
285   , fQAAODCollection(NULL)
286 {
287   //
288   // Copy Constructor
289   //
290   ref.Copy(*this);
291 }
292
293 //____________________________________________________________
294 AliAnalysisTaskHFE &AliAnalysisTaskHFE::operator=(const AliAnalysisTaskHFE &ref){
295   //
296   // Assignment operator
297   //
298   if(this == &ref) 
299     ref.Copy(*this);
300   return *this;
301 }
302
303 //____________________________________________________________
304 void AliAnalysisTaskHFE::Copy(TObject &o) const {
305   // 
306   // Copy into object o
307   //
308   AliAnalysisTaskHFE &target = dynamic_cast<AliAnalysisTaskHFE &>(o);
309   target.fAODMCHeader = fAODMCHeader;
310   target.fAODArrayMCInfo = fAODArrayMCInfo;
311   target.fQAlevel = fQAlevel;
312   target.fPlugins = fPlugins;
313   target.fFillSignalOnly = fFillSignalOnly;
314   target.fFillNoCuts = fFillNoCuts;
315   target.fUseFilterAOD = fUseFilterAOD;
316   target.fApplyCutAOD = fApplyCutAOD;
317   target.fFilter = fFilter;
318   target.fBackGroundFactorApply = fBackGroundFactorApply;
319   target.fRemovePileUp = fRemovePileUp;
320   target.fIdentifiedAsPileUp = fIdentifiedAsPileUp;
321   target.fIdentifiedAsOutInz = fIdentifiedAsOutInz;
322   target.fPassTheEventCut = fPassTheEventCut;
323   target.fRejectKinkMother = fRejectKinkMother;
324   target.fisppMultiBin =   fisppMultiBin;
325   target.fPbPbUserCentralityBinning = fPbPbUserCentralityBinning;
326   target.fisNonHFEsystematics = fisNonHFEsystematics;
327   target.fSpecialTrigger = fSpecialTrigger;
328   target.fCentralityF = fCentralityF;
329   target.fCentralityPercent = fCentralityPercent;
330   target.fContributors = fContributors;
331   target.fWeightBackGround = fWeightBackGround;
332   target.fVz = fVz;
333   target.fHadronBackgroundOADB = fHadronBackgroundOADB;
334   target.fContainer = fContainer;
335   target.fVarManager = fVarManager;
336   target.fSignalCuts = fSignalCuts;
337   target.fCFM = fCFM;
338   target.fTriggerAnalysis = fTriggerAnalysis;
339   target.fPID = fPID;
340   target.fPIDqa = fPIDqa;
341   target.fPIDpreselect = fPIDpreselect;
342   target.fCuts = fCuts;
343   target.fTaggedTrackCuts = fTaggedTrackCuts;
344   target.fCleanTaggedTrack = fCleanTaggedTrack;
345   target.fVariablesTRDTaggedTrack = fVariablesTRDTaggedTrack;
346   target.fCutspreselect = fCutspreselect;
347   target.fSecVtx = fSecVtx;
348   target.fElecBackGround = fElecBackGround;
349   target.fMCQA = fMCQA;
350   target.fTaggedTrackAnalysis = fTaggedTrackAnalysis;
351   target.fExtraCuts = fExtraCuts;
352   target.fBackgroundSubtraction = fBackgroundSubtraction;
353   target.fQA = fQA;
354   target.fOutput = fOutput;
355   target.fHistMCQA = fHistMCQA;
356   target.fHistSECVTX = fHistSECVTX;
357   target.fHistELECBACKGROUND = fHistELECBACKGROUND;
358   target.fQACollection = fQACollection;
359   target.fQAAODCollection = fQAAODCollection;
360 }
361
362 //____________________________________________________________
363 AliAnalysisTaskHFE::~AliAnalysisTaskHFE(){
364   //
365   // Destructor
366   //
367   if(fPID) delete fPID;
368   if(fPIDpreselect) delete fPIDpreselect;
369   if(fVarManager) delete fVarManager;
370   if(fCFM) delete fCFM;
371   if(fTriggerAnalysis) delete fTriggerAnalysis;
372   if(fSignalCuts) delete fSignalCuts;
373   if(fSecVtx) delete fSecVtx;
374   if(fMCQA) delete fMCQA;
375   if(fElecBackGround) delete fElecBackGround;
376   if(fBackgroundSubtraction) delete fBackgroundSubtraction;
377   if(fSpecialTrigger) delete fSpecialTrigger;
378   // Delete output objects only if we are not running in PROOF mode because otherwise this produces a crash during merging
379   AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
380   if(mgr && mgr->GetAnalysisType() != AliAnalysisManager::kProofAnalysis){
381     if(fPIDqa) delete fPIDqa;
382     if(fOutput) delete fOutput;
383     if(fQA) delete fQA;
384   }
385 }
386
387 //____________________________________________________________
388 void AliAnalysisTaskHFE::UserCreateOutputObjects(){
389   //
390   // Creating output container and output objects
391   // Here we also Initialize the correction framework container and 
392   // the objects for
393   // - PID
394   // - MC QA
395   // - SecVtx
396   // QA histograms are created if requested
397   // Called once per worker
398   //
399   AliDebug(3, "Creating Output Objects");
400   
401   // Make lists for Output
402   if(!fQA) fQA = new TList;
403   fQA->SetOwner();
404   if(!fOutput) fOutput = new TList;
405   fOutput->SetOwner();
406   
407   // Automatic determination of the analysis mode
408   AliVEventHandler *inputHandler = dynamic_cast<AliVEventHandler *>(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler());
409   if(!TString(inputHandler->IsA()->GetName()).CompareTo("AliAODInputHandler")){
410     SetAODAnalysis();
411   } else {
412     SetESDAnalysis();
413     if(AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler())
414       SetHasMCData();
415   }
416   printf("Analysis Mode: %s Analysis\n", IsAODanalysis() ? "AOD" : "ESD");
417   if(IsAODanalysis()) {
418     printf("AOD filter: %s \n", fUseFilterAOD ? "Yes" : "No");
419     if(fUseFilterAOD) printf("AOD filter used: %d \n", fFilter);
420     // First Part: Make QA histograms
421     fQAAODCollection = new AliHFEcollection("TaskQAAOD", "QA histos from the AOD Electron Task");
422     fQAAODCollection->CreateTH1F("Filterorigin", "AOD filter of tracks at the origin", 21, -1, 20);
423     fQAAODCollection->CreateTH1F("Filterend", "AOD filter of tracks after all cuts", 21, -1, 20);
424     fQA->Add(fQAAODCollection);
425   }
426   printf("MC Data available %s\n", HasMCData() ? "Yes" : "No");
427
428   // Enable Trigger Analysis
429   fTriggerAnalysis = new AliTriggerAnalysis;
430   fTriggerAnalysis->EnableHistograms();
431   fTriggerAnalysis->SetAnalyzeMC(HasMCData());
432
433   // First Part: Make QA histograms
434   fQACollection = new AliHFEcollection("TaskQA", "QA histos from the Electron Task");
435   fQACollection->CreateTH1F("nElectronTracksEvent", "Number of Electron Candidates", 100, 0, 100);
436   fQACollection->CreateTH1F("nElectron", "Number of electrons", 100, 0, 100);
437   fQACollection->CreateTH2F("radius", "Production Vertex", 100, 0.0, 5.0, 100, 0.0, 5.0);
438   fQACollection->CreateTH2F("TPCdEdxBeforePID", "TPC dE/dx; p (GeV/c); TPC dE/dx (a.u.)", 1000, 0., 10., 200, 0., 200.); 
439   fQACollection->CreateTH2F("TPCnSigmaBeforePID", "TPC dE/dx; p (GeV/c); TPC dE/dx - <TPC dE/dx>|_{el} (#sigma)", 1000, 0., 10., 1000, -10., 10.);
440  
441   InitPIDperformanceQA();
442   InitContaminationQA();
443   InitHistoITScluster();
444   fQA->Add(fQACollection);
445
446   // Initialize PID
447   fPID->SetHasMCData(HasMCData());
448   if(!fPID->GetNumberOfPIDdetectors()) fPID->AddDetector("TPC", 0);
449   if(IsQAOn(kPIDqa)){
450     AliInfo("PID QA switched on");
451     fPIDqa->Initialize(fPID);
452     fQA->Add(fPIDqa->MakeList("HFEpidQA"));
453   }
454   fPID->SortDetectors();
455
456   // Background subtraction-------------------------------------------------------------------
457   if (GetPlugin(kNonPhotonicElectron)) {
458     if(!fBackgroundSubtraction) fBackgroundSubtraction = new AliHFENonPhotonicElectron();
459     fBackgroundSubtraction->Init();
460     fOutput->Add(fBackgroundSubtraction->GetListOutput());
461   }
462   //------------------------------------------------------------------------------------------
463
464
465   // Initialize correction Framework and Cuts
466   const Int_t kNcutSteps = AliHFEcuts::kNcutStepsMCTrack + AliHFEcuts::kNcutStepsRecTrack + AliHFEcuts::kNcutStepsDETrack + AliHFEcuts::kNcutStepsSecvtxTrack;
467   fCFM = new AliCFManager;
468   fCFM->SetNStepParticle(kNcutSteps);
469   MakeParticleContainer();
470   MakeEventContainer();
471   // Temporary fix: Initialize particle cuts with NULL
472   for(Int_t istep = 0; istep < kNcutSteps; istep++)
473     fCFM->SetParticleCutsList(istep, NULL);
474   if(!fCuts){
475     AliWarning("Cuts not available. Default cuts will be used");
476     fCuts = new AliHFEcuts;
477     fCuts->CreateStandardCuts();
478   }
479   if(IsAODanalysis()) fCuts->SetAOD();
480   // Make clone for V0 tagging step
481   fCuts->Initialize(fCFM);
482   if(fCuts->IsQAOn()) fQA->Add(fCuts->GetQAhistograms());
483   fSignalCuts = new AliHFEsignalCuts("HFEsignalCuts", "HFE MC Signal definition");
484   fVarManager->SetSignalCuts(fSignalCuts);
485  
486   // add output objects to the List
487   fOutput->AddAt(fContainer, 0);
488   fOutput->AddAt(fCFM->GetEventContainer(), 1);
489   
490   // mcQA----------------------------------
491   if (HasMCData() && IsQAOn(kMCqa)) {
492     AliInfo("MC QA on");
493     if(!fMCQA) fMCQA = new AliHFEmcQA;
494     if(!fHistMCQA) fHistMCQA = new TList();
495     fHistMCQA->SetOwner();
496     if(IsPbPb()) fMCQA->SetPbPb();
497     if(fisppMultiBin) fMCQA->SetPPMultiBin();
498     if(TestBit(kTreeStream)){
499       fMCQA->EnableDebugStreamer();
500     }
501     fMCQA->CreatDefaultHistograms(fHistMCQA);
502     fMCQA->SetBackgroundWeightFactor(fElecBackgroundFactor[0][0][0],fBinLimit);
503     fQA->Add(fHistMCQA);
504   } 
505
506   // secvtx----------------------------------
507   if (GetPlugin(kSecVtx)) {
508     AliInfo("Secondary Vertex Analysis on");
509     if(!fSecVtx) fSecVtx = new AliHFEsecVtx;
510     fSecVtx->SetHasMCData(HasMCData());
511
512     if(!fHistSECVTX) fHistSECVTX = new TList();
513     fHistSECVTX->SetOwner();
514     fSecVtx->CreateHistograms(fHistSECVTX);
515     fOutput->Add(fHistSECVTX);
516   }
517
518   // background----------------------------------
519   if (GetPlugin(kIsElecBackGround)) {
520     AliInfo("Electron BackGround Analysis on");
521     if(!fElecBackGround){
522       AliWarning("ElecBackGround not available. Default elecbackground will be used");
523       fElecBackGround = new AliHFEelecbackground;
524     }
525     fElecBackGround->SetHasMCData(HasMCData());
526
527     if(!fHistELECBACKGROUND) fHistELECBACKGROUND = new TList();
528     fHistELECBACKGROUND->SetOwner();
529     fElecBackGround->CreateHistograms(fHistELECBACKGROUND);
530     fOutput->Add(fHistELECBACKGROUND);
531   }  
532
533   // tagged tracks
534   if(GetPlugin(kTaggedTrackAnalysis)){
535     AliInfo("Analysis on V0-tagged tracks enabled");
536     fTaggedTrackAnalysis = new AliHFEtaggedTrackAnalysis(Form("taggedTrackAnalysis%s", GetName()));
537     fTaggedTrackAnalysis->SetCuts(fTaggedTrackCuts);
538     fTaggedTrackAnalysis->SetClean(fCleanTaggedTrack);
539     AliHFEvarManager *varManager = fTaggedTrackAnalysis->GetVarManager();
540     TObjArray *array = fVarManager->GetVariables();
541     Int_t nvars = array->GetEntriesFast();
542     TString namee;
543     for(Int_t v = 0; v < nvars; v++) {
544       AliHFEvarManager::AliHFEvariable *variable = (AliHFEvarManager::AliHFEvariable *) array->At(v);
545       if(!variable) continue;
546       TString name(((AliHFEvarManager::AliHFEvariable *)variable)->GetName());
547       if(!name.CompareTo("source")) namee = TString("species");
548       else namee = TString(name);
549       Int_t nbins = variable->GetNumberOfBins();
550       if(variable->HasUserDefinedBinning()){
551         varManager->AddVariable(namee, nbins, variable->GetBinning());
552       } else {
553         varManager->AddVariable(namee, nbins, variable->GetMinimum(), variable->GetMaximum());
554       }
555       //printf("For AliTaggedTrackAnalysis, had the variable %s and the one used %s\n",(const char*)variable->GetName(),(const char*) namee);
556     }
557     if(fPIDqa->HasHighResolutionHistos()) 
558       fTaggedTrackAnalysis->GetPIDqa()->SetHighResolutionHistos();
559     fTaggedTrackAnalysis->SetPID(fPID);
560     fTaggedTrackAnalysis->SetVariablesTRD(fVariablesTRDTaggedTrack);
561     fTaggedTrackAnalysis->InitContainer();
562     fOutput->Add(fTaggedTrackAnalysis->GetContainer());
563     fQA->Add(fTaggedTrackAnalysis->GetPIDQA());
564     fQA->Add(fTaggedTrackAnalysis->GetCutQA());
565     fQA->Add(fTaggedTrackAnalysis->GetQAcollection());
566   }
567
568   PrintStatus();
569   // Done!!!
570   PostData(1, fOutput);
571   PostData(2, fQA);
572 }
573
574 //____________________________________________________________
575 void AliAnalysisTaskHFE::UserExec(Option_t *){
576   //
577   // Run the analysis
578   // 
579
580   //printf("test00\n");
581
582   AliDebug(3, "Starting Single Event Analysis");
583   if(!fInputEvent){
584     AliError("Reconstructed Event not available");
585     //printf("Reconstructed Event not available");
586     return;
587   }
588   if(HasMCData() && IsESDanalysis()){
589     AliDebug(4, Form("MC Event: %p", fMCEvent));
590     if(!fMCEvent){
591       AliError("No MC Event, but MC Data required");
592       //printf("No MC Event, but MC Data required");
593       return;
594     }
595   }
596   if(!fCuts){
597     AliError("HFE cuts not available");
598     //printf("HFE cuts not available");
599     return;
600   }
601   if(!fPID->IsInitialized()){
602     // Initialize PID with the given run number
603     fPID->InitializePID(fInputEvent->GetRunNumber());
604   }
605
606   //printf("test0\n");
607
608   // Initialize hadronic background from OADB Container
609   AliDebug(2, Form("Apply background factors: %s, OADB Container %p", fBackGroundFactorApply ? "Yes" : "No", fHadronBackgroundOADB));
610   if(fBackGroundFactorApply && !TestBit(kBackgroundInitialized)){ 
611     AliDebug(2, "Initializing Background from OADB");
612     if(!InitializeHadronBackground(fInputEvent->GetRunNumber())) AliError("Failed initializing hadronic background parameterization from OADB");
613     else AliDebug(2, "Successfully loaded Background from OADB");
614     SetBit(kBackgroundInitialized); 
615   }
616
617   //printf("test1\n");
618
619   if(IsESDanalysis() && HasMCData()){
620     // Protect against missing MC trees
621     AliMCEventHandler *mcH = dynamic_cast<AliMCEventHandler *>(AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler());
622     if(!mcH){ 
623       AliError("No MC Event Handler available");
624       return;
625     }
626     if(!mcH->InitOk()) return;
627     if(!mcH->TreeK()) return;
628     if(!mcH->TreeTR()) return;
629     // Background subtraction-------------------------------------------------------------------
630     if(GetPlugin(kNonPhotonicElectron) && fBackgroundSubtraction){
631       fBackgroundSubtraction->SetMCEvent(fMCEvent);
632     }
633     //------------------------------------------------------------------------------------------
634   }
635
636   if(IsAODanalysis() && HasMCData()){
637     // take MC info
638     AliAODEvent *aodE = dynamic_cast<AliAODEvent *>(fInputEvent);
639     if(!aodE){ 
640       AliError("No AOD Event");
641       return;
642     }
643     fAODMCHeader = dynamic_cast<AliAODMCHeader *>(fInputEvent->FindListObject(AliAODMCHeader::StdBranchName()));
644     if(!fAODMCHeader){ 
645       AliError("No AliAODMCHeader");
646       //printf("No AliAODMCHeader");
647       return;
648     }
649     fAODArrayMCInfo = dynamic_cast<TClonesArray *>(fInputEvent->FindListObject(AliAODMCParticle::StdBranchName()));
650     if(!fAODArrayMCInfo){ 
651       AliError("No AOD MC particles");
652       //printf("No AOD MC particles");
653       return;
654     }
655     fSignalCuts->SetMCAODInfo(fAODArrayMCInfo);
656     // Background subtraction-------------------------------------------------------------------
657     if (GetPlugin(kNonPhotonicElectron)) {
658       fBackgroundSubtraction->SetAODArrayMCInfo(fAODArrayMCInfo);
659     }
660     //------------------------------------------------------------------------------------------
661   }
662
663   //printf("test2\n");
664
665   // need the centrality for everything (MC also)
666   fCentralityF = -1;
667   if(!ReadCentrality()) fCentralityF = -1;
668   //printf("pass centrality\n");
669   //printf("Reading fCentralityF %d\n",fCentralityF);
670   
671   // See if pile up and z in the range
672   RejectionPileUpVertexRangeEventCut();
673
674   //printf("test3\n");
675
676   // Protect agains missing 
677   if(HasMCData()){
678     //printf("Has MC data\n");
679     fSignalCuts->SetMCEvent(fMCEvent);
680     ProcessMC();  // Run the MC loop + MC QA in case MC Data are available
681   }
682   
683   AliPIDResponse *pidResponse = fInputHandler->GetPIDResponse();
684   if(!pidResponse){
685     AliDebug(1, "Using default PID Response");
686     pidResponse = AliHFEtools::GetDefaultPID(HasMCData(), fInputEvent->IsA() == AliESDEvent::Class());
687   }
688   fPID->SetPIDResponse(pidResponse);
689   if(fPIDpreselect) fPIDpreselect->SetPIDResponse(pidResponse);
690
691   // Background subtraction-------------------------------------------------------------------
692   if(GetPlugin(kNonPhotonicElectron)) fBackgroundSubtraction->InitRun(fInputEvent,pidResponse);
693   //------------------------------------------------------------------------------------------
694
695   // Event loop
696   if(IsAODanalysis()){
697     //printf("test4\n");
698     ProcessAOD();
699   } else {
700     const char *specialTrigger = GetSpecialTrigger(fInputEvent->GetRunNumber());
701     // Check Trigger selection
702     if(specialTrigger){
703       AliDebug(2, Form("Special Trigger requested: %s", specialTrigger));
704       AliESDEvent *ev = dynamic_cast<AliESDEvent *>(fInputEvent);
705       if(!(ev && ev->IsTriggerClassFired(specialTrigger))){
706         AliDebug(2, "Event not selected"); 
707         return;
708       } else AliDebug(2, "Event Selected");
709     } else AliDebug(2, "No Special Trigger requested");
710     
711     ProcessESD();
712   }
713   // Done!!!
714   PostData(1, fOutput);
715   PostData(2, fQA);
716 }
717
718 //____________________________________________________________
719 void AliAnalysisTaskHFE::Terminate(Option_t *){
720   //
721   // Terminate not implemented at the moment
722   //
723   if(GetPlugin(kPostProcess)){
724     fOutput = dynamic_cast<TList *>(GetOutputData(1));
725     fQA = dynamic_cast<TList *>(GetOutputData(2));
726     if(!fOutput){
727       AliError("Results not available");
728       return;
729     }
730     if(!fQA){
731       AliError("QA output not available");
732       return;
733     }
734     fContainer = dynamic_cast<AliHFEcontainer *>(fOutput->FindObject("trackContainer")); 
735     if(!fContainer){
736       AliError("Track container not found");
737       return;
738     }
739     AliHFEpostAnalysis postanalysis;
740     postanalysis.SetTaskResults(fContainer);
741     TList *qalist = dynamic_cast<TList *>(fQA->FindObject("list_TaskQA"));
742     if(!qalist){
743       AliError("QA List not found");
744       return;
745     }
746     postanalysis.SetTaskQA(qalist);
747     //printf("Running post analysis\n");
748     //if(HasMCData())
749     postanalysis.DrawMCSignal2Background();
750     postanalysis.DrawEfficiency();
751     postanalysis.DrawPIDperformance();
752     postanalysis.DrawCutEfficiency();
753
754     if (GetPlugin(kIsElecBackGround)) {
755       AliHFEelecbackground elecBackGround;
756       TList *oe = 0x0;
757       if(!(oe = (TList*)dynamic_cast<TList *>(fOutput->FindObject("HFEelecbackground")))){
758         return;
759       }
760       elecBackGround.Load(oe);
761       elecBackGround.Plot();
762       elecBackGround.PostProcess();      
763     }
764   }
765 }
766 //_______________________________________________________________
767 Bool_t AliAnalysisTaskHFE::IsEventInBinZero() {
768   //
769   //
770   //
771
772   //printf("test in IsEventInBinZero\n");
773   if(!fInputEvent){
774     AliError("Reconstructed Event not available");
775     return kFALSE;
776   }
777
778   // check vertex
779   const AliVVertex *vertex = fInputEvent->GetPrimaryVertex();
780   if(!vertex) return kTRUE;
781   //if(vertex) return kTRUE;
782
783   // check tracks
784   if(fInputEvent->GetNumberOfTracks()<=0) return kTRUE;
785   //if(fInputEvent->GetNumberOfTracks()>0) return kTRUE;
786   
787   
788   return kFALSE;
789   
790 }
791 //____________________________________________________________
792 void AliAnalysisTaskHFE::ProcessMC(){
793   //
794   // Runs the MC Loop (filling the container for the MC Cut Steps with the observables pt, eta and phi)
795   // In case MC QA is on also MC QA loop is done
796   //
797   AliDebug(3, "Processing MC Information");
798   Double_t eventContainer [4];
799   if(IsESDanalysis()) eventContainer[0] = fMCEvent->GetPrimaryVertex()->GetZ();
800   else eventContainer[0] = fAODMCHeader->GetVtxZ();
801   eventContainer[2] = fCentralityF;
802   eventContainer[3] = fContributors;
803   fVz = eventContainer[0];
804   //printf("z position is %f\n",eventContainer[0]);
805   //if(fCFM->CheckEventCuts(AliHFEcuts::kEventStepGenerated, fMCEvent)) 
806   fCFM->GetEventContainer()->Fill(eventContainer,AliHFEcuts::kEventStepGenerated);
807   Int_t nElectrons = 0;
808   if(IsESDanalysis()){
809    if(!((fIdentifiedAsPileUp) || (TMath::Abs(fVz) > fCuts->GetVertexRange()) || (fCentralityF < 0))){ //kStepMCGeneratedZOutNoPileUpCentralityFine
810     if (HasMCData() && IsQAOn(kMCqa)) {
811       AliDebug(2, "Running MC QA");
812
813       if(fMCEvent->Stack()){
814         fMCQA->SetMCEvent(fMCEvent);
815         fMCQA->SetGenEventHeader(fMCEvent->GenEventHeader());
816         fMCQA->SetCentrality(fCentralityF);
817         fMCQA->SetPercentrality(fCentralityPercent);
818         if(IsPbPb()) { fMCQA->SetPbPb();}
819         else
820         {
821             if(fisppMultiBin) fMCQA->SetPPMultiBin();
822             else fMCQA->SetPP();
823         }
824         fMCQA->Init();
825
826         fMCQA->GetMesonKine();
827
828         // loop over all tracks for decayed electrons
829         for (Int_t igen = 0; igen < fMCEvent->GetNumberOfTracks(); igen++){
830           TParticle* mcpart = fMCEvent->Stack()->Particle(igen);
831           if(!mcpart) continue;
832           fMCQA->GetQuarkKine(mcpart, igen, AliHFEmcQA::kCharm);
833           fMCQA->GetQuarkKine(mcpart, igen, AliHFEmcQA::kBeauty);
834           fMCQA->GetHadronKine(mcpart, AliHFEmcQA::kCharm);
835           fMCQA->GetHadronKine(mcpart, AliHFEmcQA::kBeauty);
836           fMCQA->GetDecayedKine(mcpart, AliHFEmcQA::kCharm,  AliHFEmcQA::kElectronPDG); // no accept cut
837           fMCQA->GetDecayedKine(mcpart, AliHFEmcQA::kBeauty, AliHFEmcQA::kElectronPDG); // no accept cut
838           fMCQA->GetDecayedKine(mcpart, AliHFEmcQA::kOthers, AliHFEmcQA::kElectronPDG); // no accept cut
839         }
840         //fMCQA->EndOfEventAna(AliHFEmcQA::kCharm);
841         //fMCQA->EndOfEventAna(AliHFEmcQA::kBeauty);
842       }
843
844     } // end of MC QA loop
845    }
846    // -----------------------------------------------------------------
847    fCFM->SetMCEventInfo(fMCEvent);
848    // fCFM->CheckEventCuts(AliCFManager::kEvtRecCuts, fESD);
849   } else {
850     fCFM->SetMCEventInfo(fInputEvent);
851   }
852   // Run MC loop
853   AliVParticle *mctrack = NULL;
854   Int_t numberofmctracks = 0;
855   if(IsESDanalysis()){
856     numberofmctracks = fMCEvent->GetNumberOfTracks();
857   }
858   else {
859     numberofmctracks = fAODArrayMCInfo->GetEntriesFast();
860   }
861   AliDebug(3, Form("Number of Tracks: %d",numberofmctracks));
862   //printf("Number of MC track %d\n",numberofmctracks);
863   for(Int_t imc = 0; imc <numberofmctracks; imc++){
864     if(IsESDanalysis()) {
865       if(!(mctrack = fMCEvent->GetTrack(imc))) continue;
866     }
867     else {
868       if(!(mctrack = (AliVParticle *) fAODArrayMCInfo->At(imc))) continue;
869     }
870     //printf("Test in ProcessMC\n");
871     AliDebug(4, "Next MC Track");
872     if(ProcessMCtrack(mctrack)) nElectrons++;
873   }
874
875   // fCFM->CheckEventCuts(AliCFManager::kEvtRecCuts, fESD);
876   fQACollection->Fill("nElectron", nElectrons);
877 }
878
879 //____________________________________________________________
880 void AliAnalysisTaskHFE::ProcessESD(){
881   //
882   // Run Analysis of reconstructed event in ESD Mode
883   // Loop over Tracks, filter according cut steps defined in AliHFEcuts
884   //
885   AliDebug(1, Form("Task %s", GetName()));
886   AliDebug(3, "Processing ESD Event");
887   AliESDEvent *fESD = dynamic_cast<AliESDEvent *>(fInputEvent);
888   if(!fESD){
889     AliError("ESD Event required for ESD Analysis");
890     return;
891   }
892
893   // Set magnetic field if V0 task on
894   if(fTaggedTrackAnalysis) {
895     fTaggedTrackAnalysis->SetMagneticField(fESD->GetMagneticField());
896     fTaggedTrackAnalysis->SetCentrality(fCentralityF);
897     if(IsPbPb()) fTaggedTrackAnalysis->SetPbPb();
898     else fTaggedTrackAnalysis->SetPP();
899   }
900
901   // Do event Normalization
902   Double_t eventContainer[4];
903   eventContainer[0] = 0.; 
904   if(HasMCData()) eventContainer[0] = fVz;
905   else {
906     if(fESD->GetPrimaryVertexSPD()) eventContainer[0] = fESD->GetPrimaryVertexSPD()->GetZ();
907   }
908   eventContainer[1] = 0.;
909   eventContainer[2] = fCentralityF;
910   eventContainer[3] = fContributors;
911   if(fTriggerAnalysis->IsOfflineTriggerFired(fESD, AliTriggerAnalysis::kV0AND))
912     eventContainer[1] = 1.;
913
914   //
915   fCFM->GetEventContainer()->Fill(eventContainer, AliHFEcuts::kEventStepRecNoCut);
916
917   //
918   if(fIdentifiedAsPileUp) return; 
919   fCFM->GetEventContainer()->Fill(eventContainer, AliHFEcuts::kEventStepRecNoPileUp);
920
921   //
922   if(TMath::Abs(fCentralityF) < 0) return; 
923   fCFM->GetEventContainer()->Fill(eventContainer, AliHFEcuts::kEventStepRecCentralityOk);
924   //printf("In ProcessESD %f\n",fCentralityF);
925
926   //
927   if(fIdentifiedAsOutInz) return;
928   fCFM->GetEventContainer()->Fill(eventContainer, AliHFEcuts::kEventStepZRange);  
929
930   //
931   if(!fPassTheEventCut) return;
932   fCFM->GetEventContainer()->Fill(eventContainer, AliHFEcuts::kEventStepReconstructed);
933
934
935   fContainer->NewEvent();
936
937   if (GetPlugin(kIsElecBackGround)) { 
938     fElecBackGround->SetEvent(fESD);
939   }
940   if (GetPlugin(kSecVtx)) {
941     fSecVtx->SetEvent(fESD);
942     fSecVtx->GetPrimaryCondition();
943   }
944
945   if(HasMCData()){
946     if (GetPlugin(kSecVtx)) { 
947       fSecVtx->SetMCEvent(fMCEvent);
948       fSecVtx->SetMCQA(fMCQA); 
949     }
950     if (GetPlugin(kIsElecBackGround)) { 
951       fElecBackGround->SetMCEvent(fMCEvent);
952     }
953   }
954
955   Double_t container[10];
956   memset(container, 0, sizeof(Double_t) * 10);
957   // container for the output THnSparse
958   Double_t dataE[6]; // [pT, eta, Phi, type, 'C' or 'B']
959   Double_t dataDca[6]; // [source, pT, dca, centrality]
960   Int_t nElectronCandidates = 0;
961   AliESDtrack *track = NULL, *htrack = NULL;
962   AliMCParticle *mctrack = NULL;
963   AliMCParticle *mctrackmother = NULL;
964   Int_t pid = 0;
965
966   Bool_t signal = kTRUE;
967
968   fCFM->SetRecEventInfo(fESD);
969
970   // Get Number of contributors to the primary vertex for multiplicity-dependent correction
971   Int_t ncontribVtx = 0;
972   const AliESDVertex *priVtx = fESD->GetPrimaryVertexTracks();
973   if(priVtx){
974     ncontribVtx = priVtx->GetNContributors();
975   }
976
977   // minjung for IP QA(temporary ~ 2weeks)
978   if(!fExtraCuts){
979     fExtraCuts = new AliHFEextraCuts("hfetmpCuts","HFE tmp Cuts");
980   }   
981   fExtraCuts->SetRecEventInfo(fESD);
982
983   // Electron background analysis 
984   if (GetPlugin(kIsElecBackGround)) {
985     
986     AliDebug(2, "Running BackGround Analysis");
987     
988     fElecBackGround->Reset();
989     
990   } // end of electron background analysis
991   
992
993   // Background subtraction-------------------------------------------------------------------
994   if (GetPlugin(kNonPhotonicElectron)) {
995     fBackgroundSubtraction->FillPoolAssociatedTracks(fInputEvent,fCentralityF);
996   }
997   //------------------------------------------------------------------------------------------
998
999   //
1000   // Loop ESD
1001   //
1002   AliDebug(3, Form("Number of Tracks: %d", fESD->GetNumberOfTracks()));
1003   for(Int_t itrack = 0; itrack < fESD->GetNumberOfTracks(); itrack++){
1004     AliDebug(4, "New ESD track");
1005     track = fESD->GetTrack(itrack);
1006     track->SetESDEvent(fESD);
1007
1008     // fill counts of v0-identified particles
1009     Int_t v0pid = -1;
1010     if(track->TestBit(BIT(14))) v0pid = AliPID::kElectron;
1011     else if(track->TestBit(BIT(15))) v0pid = AliPID::kPion;
1012     else if(track->TestBit(BIT(16))) v0pid = AliPID::kProton;
1013     // here the tagged track analysis will run
1014     if(fTaggedTrackAnalysis && v0pid > -1){ 
1015       AliDebug(1, Form("Track identified as %s", AliPID::ParticleName(v0pid)));
1016       fTaggedTrackAnalysis->ProcessTrack(track, v0pid);
1017       AliDebug(1, "V0 PID done");
1018     }
1019  
1020
1021     //Fill non-HFE source containers at reconstructed events cut step
1022     AliDebug(3, Form("Doing track %d, %p", itrack, track));
1023
1024
1025     //////////////////////////////////////
1026     // preselect
1027     //////////////////////////////////////
1028     if(fPIDpreselect || fCutspreselect) {
1029       if(!PreSelectTrack(track)) continue;
1030     }
1031
1032     signal = kTRUE;
1033     
1034     // Fill step without any cut
1035           
1036     if(HasMCData()){
1037       // Check if it is electrons near the vertex
1038       if(!(mctrack = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(TMath::Abs(track->GetLabel()))))) continue;
1039
1040       if(fFillSignalOnly && !fCFM->CheckParticleCuts(AliHFEcuts::kStepMCGenerated, mctrack)) signal = kFALSE; 
1041       else AliDebug(3, "Signal Electron");
1042
1043       // Fill K pt for Ke3 contributions
1044       if(mctrack && (TMath::Abs(mctrack->Particle()->GetPdgCode())==321)) fQACollection->Fill("Kptspectra",mctrack->Pt());
1045       else if(mctrack && (TMath::Abs(mctrack->Particle()->GetPdgCode())==130)) fQACollection->Fill("K0Lptspectra",mctrack->Pt());
1046     } 
1047     // Cache new Track information inside the var manager
1048     fVarManager->NewTrack(track, mctrack, fCentralityF, -1, signal);
1049
1050     if(fFillNoCuts) {
1051       if(signal || !fFillSignalOnly){
1052         fVarManager->FillContainer(fContainer, "recTrackContReco", AliHFEcuts::kStepRecNoCut, kFALSE);
1053         fVarManager->FillContainer(fContainer, "recTrackContMC", AliHFEcuts::kStepRecNoCut, kTRUE);
1054       }
1055     }
1056         
1057     if(fisNonHFEsystematics && IsPbPb())  {
1058       //FillProductionVertex(track);     
1059       if(fMCQA && signal){ 
1060         fMCQA->SetCentrality(fCentralityF);
1061         if(mctrack && (TMath::Abs(mctrack->Particle()->GetPdgCode()) == 11)){
1062           Double_t weightElecBgV0[kBgLevels] = {0.,0.,0.};
1063           
1064           fMCQA->SetTrkKine(track->Pt(),track->Eta(), track->Phi());
1065           fMCQA->SetContainerStep(4);
1066           
1067           weightElecBgV0[0] = fMCQA->GetWeightFactor(mctrack, 0); // positive:conversion e, negative: nonHFE 
1068           
1069           //Fill additional containers for electron source distinction
1070           Int_t elecSource = 0;
1071           elecSource = fMCQA->GetElecSource(mctrack->Particle());
1072           const Char_t *sourceName[kElecBgSpecies]={"Pion","Eta","Omega","Phi","EtaPrime","Rho"};
1073           const Char_t *levelName[kBgLevels]={"Best","Lower","Upper"};
1074           Int_t iName = 0;
1075           for(Int_t iSource = AliHFEmcQA::kPi0; iSource <=  AliHFEmcQA::kGammaRho0; iSource++){
1076             if((iSource == AliHFEmcQA::kElse)||(iSource == AliHFEmcQA::kMisID)) continue;
1077             if(elecSource == iSource){
1078               
1079               if(weightElecBgV0[0]>0){ 
1080                 fVarManager->FillContainer(fContainer, Form("conversionElecs%s%s",sourceName[iName], levelName[0]), 4, kTRUE, weightElecBgV0[0]);
1081               } 
1082               else if(weightElecBgV0[0]<0){ 
1083                 fVarManager->FillContainer(fContainer, Form("mesonElecs%s%s",sourceName[iName], levelName[0]), 4, kTRUE, -1*weightElecBgV0[0]);
1084               }           
1085               break;
1086             }
1087             iName++;
1088             if(iName == kElecBgSpecies)iName = 0;
1089           }
1090         }
1091       }
1092     }
1093   
1094     // RecKine: ITSTPC cuts  
1095     if(!ProcessCutStep(AliHFEcuts::kStepRecKineITSTPC, track)) continue;
1096     
1097     
1098     // RecPrim
1099     if(fRejectKinkMother) { 
1100       if(track->GetKinkIndex(0) != 0) continue; } // Quick and dirty fix to reject both kink mothers and daughters
1101     if(!ProcessCutStep(AliHFEcuts::kStepRecPrim, track)) continue;
1102
1103     // HFEcuts: ITS layers cuts
1104     if(!ProcessCutStep(AliHFEcuts::kStepHFEcutsITS, track)) continue;
1105   
1106     // HFE cuts: TOF PID and mismatch flag
1107     if(!ProcessCutStep(AliHFEcuts::kStepHFEcutsTOF, track)) continue;
1108
1109     // HFE cuts: TPC PID cleanup
1110     if(!ProcessCutStep(AliHFEcuts::kStepHFEcutsTPC, track)) continue;
1111
1112     // HFEcuts: Nb of tracklets TRD0
1113     if(!ProcessCutStep(AliHFEcuts::kStepHFEcutsTRD, track)) continue;
1114
1115     // Fill correlation maps before PID
1116     if(signal && fContainer->GetCorrelationMatrix("correlationstepbeforePID")) {
1117       //printf("Fill correlation maps before PID\n");
1118       fVarManager->FillCorrelationMatrix(fContainer->GetCorrelationMatrix("correlationstepbeforePID"));
1119     }
1120
1121     if(HasMCData()){
1122       FillProductionVertex(track);
1123
1124       if(fMCQA && signal){
1125         fMCQA->SetCentrality(fCentralityF);
1126         if(mctrack && (TMath::Abs(mctrack->Particle()->GetPdgCode()) == 11)){
1127          Double_t weightElecBgV0[kBgLevels] = {0.,0.,0.};
1128          Double_t hfeimpactRtmp=0., hfeimpactnsigmaRtmp=0.;
1129          fExtraCuts->GetHFEImpactParameters(track, hfeimpactRtmp, hfeimpactnsigmaRtmp);
1130          UChar_t itsPixel = track->GetITSClusterMap();
1131          Double_t ilyrhit=0, ilyrstat=0;
1132          for(Int_t ilyr=0; ilyr<6; ilyr++){
1133            if(TESTBIT(itsPixel, ilyr)) ilyrhit += TMath::Power(2,ilyr);
1134            if(fExtraCuts->CheckITSstatus(fExtraCuts->GetITSstatus(track,ilyr))) ilyrstat += TMath::Power(2,ilyr);
1135          }
1136          fMCQA->SetITSInfo(ilyrhit,ilyrstat);
1137          fMCQA->SetHFEImpactParameters(hfeimpactRtmp, hfeimpactnsigmaRtmp);
1138          fMCQA->SetTrkKine(track->Pt(),track->Eta(), track->Phi());
1139          fMCQA->SetContainerStep(3);
1140          for(Int_t iLevel = 0; iLevel < kBgLevels; iLevel++){
1141            weightElecBgV0[iLevel] = fMCQA->GetWeightFactor(mctrack, iLevel); // positive:conversion e, negative: nonHFE 
1142            if(!fisNonHFEsystematics || IsPbPb())break;   
1143          }
1144          
1145          if(fisNonHFEsystematics){
1146            //Fill additional containers for electron source distinction
1147            Int_t elecSource = 0;
1148            elecSource = fMCQA->GetElecSource(mctrack->Particle());
1149            const Char_t *sourceName[kElecBgSpecies]={"Pion","Eta","Omega","Phi","EtaPrime","Rho"};
1150            const Char_t *levelName[kBgLevels]={"Best","Lower","Upper"};
1151            Int_t iName = 0;
1152            for(Int_t iSource = AliHFEmcQA::kPi0; iSource <=  AliHFEmcQA::kGammaRho0; iSource++){
1153              if((iSource == AliHFEmcQA::kElse)||(iSource == AliHFEmcQA::kMisID)) continue;
1154              if(elecSource == iSource){
1155                for(Int_t iLevel = 0; iLevel < kBgLevels; iLevel++){
1156                  if(weightElecBgV0[iLevel]>0){ 
1157                    fVarManager->FillContainer(fContainer, Form("conversionElecs%s%s",sourceName[iName], levelName[iLevel]), 3, kFALSE, weightElecBgV0[iLevel]);
1158                  } 
1159                  else if(weightElecBgV0[iLevel]<0){ 
1160                    fVarManager->FillContainer(fContainer, Form("mesonElecs%s%s",sourceName[iName], levelName[iLevel]), 3, kFALSE, -1*weightElecBgV0[iLevel]);
1161                  }
1162                  if(IsPbPb())break;
1163                }
1164                break;
1165              }
1166              iName++;
1167              if(iName == kElecBgSpecies)iName = 0;
1168            }
1169          }
1170          //else{
1171            if(weightElecBgV0[0]>0) {
1172              fVarManager->FillContainer(fContainer, "conversionElecs", 3, kFALSE, weightElecBgV0[0]);
1173              fVarManager->FillContainer(fContainer, "conversionElecs", 4, kTRUE, weightElecBgV0[0]);
1174            }
1175            else if(weightElecBgV0[0]<0) {
1176              fVarManager->FillContainer(fContainer, "mesonElecs", 3, kFALSE, -1*weightElecBgV0[0]);
1177              fVarManager->FillContainer(fContainer, "mesonElecs", 4, kTRUE, -1*weightElecBgV0[0]);
1178            }
1179            //}
1180         }
1181       }
1182
1183       Double_t hfeimpactR4all=0., hfeimpactnsigmaR4all=0.;
1184       Int_t sourceDca =-1;
1185       if(mctrack && (TMath::Abs(mctrack->Particle()->GetPdgCode()) == 211)){
1186         if(track->Pt()>4.){
1187           fExtraCuts->GetHFEImpactParameters(track, hfeimpactR4all, hfeimpactnsigmaR4all);
1188           dataDca[0]=0; //pion
1189           dataDca[1]=track->Pt();
1190           dataDca[2]=hfeimpactR4all;
1191           dataDca[3]=fCentralityF;
1192           dataDca[4] = v0pid;
1193           dataDca[5] = double(track->Charge());
1194           fQACollection->Fill("Dca", dataDca);
1195         }
1196       }
1197       else if(mctrack && (TMath::Abs(mctrack->Particle()->GetPdgCode()) == 11)){ // to increas statistics for Martin
1198         if(signal){
1199           fExtraCuts->GetHFEImpactParameters(track, hfeimpactR4all, hfeimpactnsigmaR4all);
1200           if(fSignalCuts->IsCharmElectron(track)){
1201             sourceDca=1;
1202           }
1203           else if(fSignalCuts->IsBeautyElectron(track)){
1204             sourceDca=2;
1205           }
1206           else if(fSignalCuts->IsGammaElectron(track)){
1207             sourceDca=3;
1208           }
1209           else if(fSignalCuts->IsNonHFElectron(track)){
1210             sourceDca=4;
1211           }
1212           else if(fSignalCuts->IsJpsiElectron(track)){
1213             sourceDca=5;
1214           }
1215           else {
1216             sourceDca=6;
1217           }
1218           dataDca[0]=sourceDca;
1219           dataDca[1]=track->Pt();
1220           dataDca[2]=hfeimpactR4all;
1221           dataDca[3]=fCentralityF;
1222           dataDca[4] = v0pid;
1223           dataDca[5] = double(track->Charge());
1224           if(signal) fQACollection->Fill("Dca", dataDca);
1225         }
1226       }
1227     }
1228
1229     if(TMath::Abs(track->Eta()) < 0.5){
1230       if(track->GetInnerParam())
1231         fQACollection->Fill("TPCdEdxBeforePID", track->GetInnerParam()->P(), track->GetTPCsignal());
1232       fQACollection->Fill("TPCnSigmaBeforePID", track->P(), fInputHandler->GetPIDResponse()->NumberOfSigmasTPC(track, AliPID::kElectron));
1233     }
1234
1235     AliHFEpidObject hfetrack;
1236     hfetrack.SetAnalysisType(AliHFEpidObject::kESDanalysis);
1237     hfetrack.SetRecTrack(track);
1238     if(HasMCData()) hfetrack.SetMCTrack(mctrack);
1239     hfetrack.SetCentrality(fCentralityF);
1240     hfetrack.SetMulitplicity(ncontribVtx);
1241     if(IsPbPb()) hfetrack.SetPbPb();
1242     else hfetrack.SetPP();
1243     fPID->SetVarManager(fVarManager);
1244     if(!fPID->IsSelected(&hfetrack, fContainer, "recTrackCont", fPIDqa)) continue;
1245     nElectronCandidates++;
1246     
1247     // Background subtraction------------------------------------------------------------------------------------------
1248     if (GetPlugin(kNonPhotonicElectron)) {
1249       Int_t indexmother = -1;
1250       Int_t mcsource = -1;
1251       if(HasMCData()){
1252         mcsource = fBackgroundSubtraction->FindMother(mctrack->GetLabel(),indexmother);
1253       }
1254       fBackgroundSubtraction->LookAtNonHFE(itrack, track, fInputEvent, 1, fCentralityF, -1, mcsource, indexmother);
1255     }
1256     //-----------------------------------------------------------------------------------------------------------------
1257
1258     // Temporary histogram for chi2/ITS cluster
1259     if(IsPbPb()) {
1260             TBits shared = track->GetTPCSharedMap();
1261             Int_t sharebit=0;
1262             if(shared.CountBits() >= 2) sharebit=1;
1263
1264             Double_t itschi2percluster = 0.0;
1265             Double_t itsnbcls = static_cast<Double_t>(track->GetNcls(0));
1266             if(itsnbcls > 0) itschi2percluster = track->GetITSchi2()/itsnbcls;
1267
1268             Double_t itsChi2[7] = {track->Pt(),track->Eta(), track->Phi(),
1269                                    fCentralityF,track->GetTPCsignalN(), sharebit,itschi2percluster};
1270             fQACollection->Fill("fChi2perITScluster", itsChi2);
1271     }
1272     else{
1273
1274       Double_t itschi2percluster = 0.0;
1275       Double_t itsnbcls = static_cast<Double_t>(track->GetNcls(0));
1276       if(itsnbcls > 0) itschi2percluster = track->GetITSchi2()/itsnbcls;
1277
1278       Double_t itsChi2[3] = {track->Pt(), fCentralityF, itschi2percluster};
1279       fQACollection->Fill("fChi2perITScluster", itsChi2);
1280     }
1281
1282     // Fill Histogram for Hadronic Background
1283     if(HasMCData()){
1284       if(mctrack && (TMath::Abs(mctrack->Particle()->GetPdgCode()) != 11))
1285         fVarManager->FillContainer(fContainer, "hadronicBackground", UInt_t(0), kFALSE);
1286       else if(mctrack){
1287         // Fill Ke3 contributions
1288         Int_t glabel=TMath::Abs(mctrack->GetMother());
1289         if((mctrackmother = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(glabel)))){
1290           if(TMath::Abs(mctrackmother->Particle()->GetPdgCode())==321)
1291             fQACollection->Fill("Ke3Kecorr",mctrack->Pt(),mctrackmother->Pt());
1292           else if(TMath::Abs(mctrackmother->Particle()->GetPdgCode())==130)
1293             fQACollection->Fill("Ke3K0Lecorr",mctrack->Pt(),mctrackmother->Pt());
1294         }
1295       }
1296     }
1297
1298     // Fill Containers
1299     if(signal) {
1300       // Apply weight for background contamination
1301             if(fBackGroundFactorApply) {
1302               if(IsPbPb() && fCentralityF >= 0) fWeightBackGround =  fkBackGroundFactorArray[fCentralityF >= 0 ? fCentralityF : 0]->Eval(TMath::Abs(track->P()));
1303               else    fWeightBackGround =  fkBackGroundFactorArray[0]->Eval(TMath::Abs(track->P())); // pp case
1304
1305               if(fWeightBackGround < 0.0) fWeightBackGround = 0.0;
1306               else if(fWeightBackGround > 1.0) fWeightBackGround = 1.0;
1307         // weightBackGround as special weight
1308         fVarManager->FillContainer(fContainer, "hadronicBackground", 1, kFALSE, fWeightBackGround);
1309       }
1310       fVarManager->FillCorrelationMatrix(fContainer->GetCorrelationMatrix("correlationstepafterPID"));
1311     }
1312
1313     Bool_t bTagged=kFALSE;
1314     if(GetPlugin(kSecVtx)) {
1315       AliDebug(2, "Running Secondary Vertex Analysis");
1316       if(fSecVtx->Process(track) && signal) {
1317         fVarManager->FillContainer(fContainer, "recTrackContSecvtxReco", AliHFEcuts::kStepHFEcutsSecvtx, kFALSE);
1318         fVarManager->FillContainer(fContainer, "recTrackContSecvtxMC", AliHFEcuts::kStepHFEcutsSecvtx, kTRUE);
1319         bTagged=kTRUE;
1320       }
1321     }
1322
1323     if(HasMCData()){
1324       dataE[0] = track->Pt();
1325       dataE[1] = track->Eta();
1326       dataE[2] = track->Phi();
1327       dataE[3] = track->Charge();
1328       dataE[4] = -1.;
1329       dataE[5] = -1.;
1330
1331       // Track selected: distinguish between true and fake
1332       AliDebug(1, Form("Candidate Selected, filling THnSparse, PID: %d\n", mctrack->Particle()->GetPdgCode()));
1333       if((pid = TMath::Abs(mctrack->Particle()->GetPdgCode())) == 11){
1334         Int_t type = 0;
1335         if(fSignalCuts->IsCharmElectron(track))
1336           type = 1;
1337         else if(fSignalCuts->IsBeautyElectron(track))
1338           type = 2;
1339         AliDebug(1, Form("Type: %d\n", type));
1340         if(type){
1341                 dataE[5] = type; // beauty[1] or charm[2]
1342                 dataE[4] = 2;  // signal electron
1343         }
1344         else{
1345                 dataE[4] = 1; // not a signal electron
1346                 dataE[5] = 0;
1347         }
1348       } 
1349       else {
1350         // Fill THnSparse with the information for Fake Electrons
1351         dataE[4] = 0;
1352         dataE[5] = 0;
1353       }
1354       // fill the performance THnSparse, if the mc origin could be defined
1355       if(dataE[4] > -1){
1356         AliDebug(1, Form("Entries: [%.3f|%.3f|%.3f|%f|%f|%f]\n", dataE[0],dataE[1],dataE[2],dataE[3],dataE[4],dataE[5]));
1357         fQACollection->Fill("PIDperformance", dataE);
1358       }
1359     }
1360
1361     // Electron background analysis 
1362     if (GetPlugin(kIsElecBackGround)) {
1363       
1364       AliDebug(2, "Running BackGround Analysis");
1365       
1366       for(Int_t jtrack = 0; jtrack < fESD->GetNumberOfTracks(); jtrack++){
1367         htrack = fESD->GetTrack(jtrack);
1368         if ( itrack == jtrack ) continue;  
1369         fElecBackGround->PairAnalysis(track, htrack); 
1370       }
1371     } // end of electron background analysis
1372
1373     if (GetPlugin(kDEstep)) { 
1374       Double_t weightElecBgV0[kBgLevels] = {0.,0.,0.,};
1375       Int_t elecSource = 0;
1376       Double_t hfeimpactR=0., hfeimpactnsigmaR=0.;
1377       fExtraCuts->GetHFEImpactParameters(track, hfeimpactR, hfeimpactnsigmaR);
1378       if(HasMCData())
1379       {
1380         if(mctrack && (TMath::Abs(mctrack->Particle()->GetPdgCode()) != 11)){
1381             fQACollection->Fill("hadronsBeforeIPcut",track->Pt());
1382         } 
1383         if(fMCQA && signal) {
1384           
1385           fMCQA->SetContainerStep(0);
1386           for(Int_t iLevel = 0; iLevel < kBgLevels; iLevel++){
1387             weightElecBgV0[iLevel] = fMCQA->GetWeightFactor(mctrack, iLevel); // positive:conversion e, negative: nonHFE 
1388             if(!fisNonHFEsystematics || IsPbPb())break;        
1389           }
1390           
1391           if(fisNonHFEsystematics){
1392             //Fill additional containers for electron source distinction           
1393             elecSource = fMCQA->GetElecSource(mctrack->Particle());
1394             const Char_t *sourceName[kElecBgSpecies]={"Pion","Eta","Omega","Phi","EtaPrime","Rho"};
1395             const Char_t *levelName[kBgLevels]={"Best","Lower","Upper"};
1396             Int_t iName = 0;
1397             for(Int_t iSource = AliHFEmcQA::kPi0; iSource <=  AliHFEmcQA::kGammaRho0; iSource++){
1398               if((iSource == AliHFEmcQA::kElse)||(iSource == AliHFEmcQA::kMisID)) continue;
1399               if(elecSource == iSource){
1400                 for(Int_t iLevel = 0; iLevel < kBgLevels; iLevel++){
1401                   if(weightElecBgV0[iLevel]>0) fVarManager->FillContainer(fContainer, Form("conversionElecs%s%s",sourceName[iName], levelName[iLevel]), 0, kFALSE, weightElecBgV0[iLevel]);
1402                   else if(weightElecBgV0[iLevel]<0) fVarManager->FillContainer(fContainer, Form("mesonElecs%s%s",sourceName[iName], levelName[iLevel]), 0, kFALSE, -1*weightElecBgV0[iLevel]);
1403                   if(IsPbPb())break;
1404                 }
1405                 break;
1406               }
1407               iName++;
1408               if(iName == kElecBgSpecies)iName = 0;
1409             }
1410           }
1411           //else{
1412           if(weightElecBgV0[0]>0) {
1413             fVarManager->FillContainer(fContainer, "conversionElecs", 0, kFALSE, weightElecBgV0[0]);
1414             fVarManager->FillContainer(fContainer, "conversionElecs", 5, kTRUE, weightElecBgV0[0]);
1415           }
1416           else if(weightElecBgV0[0]<0) {
1417             fVarManager->FillContainer(fContainer, "mesonElecs", 0, kFALSE, -1*weightElecBgV0[0]);
1418             fVarManager->FillContainer(fContainer, "mesonElecs", 5, kTRUE, -1*weightElecBgV0[0]);
1419           }  
1420           //}
1421           if(bTagged){ // bg estimation for the secondary vertex tagged signals
1422             if(weightElecBgV0[0]>0) fVarManager->FillContainer(fContainer, "conversionElecs", 2, kFALSE, weightElecBgV0[0]);
1423             else if(weightElecBgV0[0]<0) fVarManager->FillContainer(fContainer, "mesonElecs", 2, kFALSE, -1*weightElecBgV0[0]);
1424           }
1425         }
1426       } // end of MC
1427
1428       dataDca[0]=-1; //for data, don't know the origin
1429       dataDca[1]=track->Pt();
1430       dataDca[2]=hfeimpactR;
1431       dataDca[3]=fCentralityF;
1432       dataDca[4] = v0pid;
1433       dataDca[5] = double(track->Charge());
1434       if (!HasMCData()) fQACollection->Fill("Dca", dataDca);
1435
1436       // Fill Containers for impact parameter analysis
1437       if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepHFEcutsDca + AliHFEcuts::kNcutStepsMCTrack + AliHFEcuts::kNcutStepsRecTrack,track)) continue;
1438       if(signal) {
1439         // Apply weight for background contamination after ip cut
1440         if(fBackGroundFactorApply) {
1441               fWeightBackGround =  fkBackGroundFactorArray[0]->Eval(TMath::Abs(track->P())); // pp case
1442               if(fWeightBackGround < 0.0) fWeightBackGround = 0.0;
1443               else if(fWeightBackGround > 1.0) fWeightBackGround = 1.0;
1444               // weightBackGround as special weight
1445               fVarManager->FillContainer(fContainer, "hadronicBackground", 2, kFALSE, fWeightBackGround);
1446         }
1447       }
1448
1449       if(HasMCData()){
1450         if(fMCQA && signal) {
1451           fMCQA->SetContainerStep(1);
1452           for(Int_t iLevel = 0; iLevel < kBgLevels; iLevel++){
1453             weightElecBgV0[iLevel] = fMCQA->GetWeightFactor(mctrack, iLevel); // positive:conversion e, negative: nonHFE 
1454             if(!fisNonHFEsystematics || IsPbPb())break;        
1455           }       
1456           if(fisNonHFEsystematics){
1457             //Fill additional containers for electron source distinction             
1458             elecSource = fMCQA->GetElecSource(mctrack->Particle());
1459             const Char_t *sourceName[kElecBgSpecies]={"Pion","Eta","Omega","Phi","EtaPrime","Rho"};
1460             const Char_t *levelName[kBgLevels]={"Best","Lower","Upper"};
1461             Int_t iName = 0;
1462             for(Int_t iSource = AliHFEmcQA::kPi0; iSource <=  AliHFEmcQA::kGammaRho0; iSource++){
1463               if((iSource == AliHFEmcQA::kElse)||(iSource == AliHFEmcQA::kMisID)) continue;
1464               if(elecSource == iSource){
1465                 for(Int_t iLevel = 0; iLevel < kBgLevels; iLevel++){
1466                   if(weightElecBgV0[iLevel]>0) fVarManager->FillContainer(fContainer, Form("conversionElecs%s%s",sourceName[iName], levelName[iLevel]), 1, kFALSE, weightElecBgV0[iLevel]);
1467                   else if(weightElecBgV0[iLevel]<0) fVarManager->FillContainer(fContainer, Form("mesonElecs%s%s",sourceName[iName], levelName[iLevel]), 1, kFALSE, -1*weightElecBgV0[iLevel]);
1468                   if(IsPbPb())break;
1469                 }
1470                 break;
1471               }
1472               iName++;
1473               if(iName == kElecBgSpecies)iName = 0;
1474             }
1475           }
1476           // else{
1477             if(weightElecBgV0[0]>0) {
1478               fVarManager->FillContainer(fContainer, "conversionElecs", 1, kFALSE, weightElecBgV0[0]);
1479               fVarManager->FillContainer(fContainer, "conversionElecs", 6, kTRUE, weightElecBgV0[0]);
1480             }
1481             else if(weightElecBgV0[0]<0) {
1482               fVarManager->FillContainer(fContainer, "mesonElecs", 1, kFALSE, -1*weightElecBgV0[0]);
1483               fVarManager->FillContainer(fContainer, "mesonElecs", 6, kTRUE, -1*weightElecBgV0[0]);
1484             }
1485             //}
1486         }
1487       }
1488       if(signal) {
1489         fVarManager->FillContainer(fContainer, "recTrackContDEReco", AliHFEcuts::kStepHFEcutsDca, kFALSE);
1490         fVarManager->FillContainer(fContainer, "recTrackContDEMC", AliHFEcuts::kStepHFEcutsDca, kTRUE);
1491         fVarManager->FillCorrelationMatrix(fContainer->GetCorrelationMatrix("correlationstepafterDE"));
1492       }
1493       if(HasMCData()){
1494         if(mctrack && (TMath::Abs(mctrack->Particle()->GetPdgCode()) != 11)){
1495           fQACollection->Fill("hadronsAfterIPcut",track->Pt());
1496         }
1497       }
1498     }
1499
1500   }
1501   fQACollection->Fill("nElectronTracksEvent", nElectronCandidates);
1502 }
1503
1504 //____________________________________________________________
1505 void AliAnalysisTaskHFE::ProcessAOD(){
1506   //
1507   // Run Analysis in AOD Mode
1508   // Function is still in development
1509   //
1510   //printf("Process AOD\n");
1511   AliDebug(3, "Processing AOD Event");
1512   Double_t eventContainer[4];
1513   eventContainer[0] = 0.0;
1514   if(HasMCData()) eventContainer[0] = fVz;
1515   else {
1516     if(fInputEvent->GetPrimaryVertex()) eventContainer[0] = fInputEvent->GetPrimaryVertex()->GetZ();
1517   }
1518   eventContainer[1] = 1.; // No Information available in AOD analysis, assume all events have V0AND
1519   eventContainer[2] = fCentralityF; 
1520   eventContainer[3] = fContributors; 
1521   
1522   //printf("value event container %f, %f, %f, %f\n",eventContainer[0],eventContainer[1],eventContainer[2],eventContainer[3]);
1523
1524   AliAODEvent *fAOD = dynamic_cast<AliAODEvent *>(fInputEvent);
1525   if(!fAOD){
1526     AliError("AOD Event required for AOD Analysis");
1527       return;
1528   }
1529   
1530   //printf("Will fill\n");
1531   //
1532   fCFM->GetEventContainer()->Fill(eventContainer, AliHFEcuts::kEventStepRecNoCut);
1533   //printf("Fill\n");
1534   //
1535   if(fIdentifiedAsPileUp) return; 
1536   fCFM->GetEventContainer()->Fill(eventContainer, AliHFEcuts::kEventStepRecNoPileUp);
1537
1538   //
1539   if(fIdentifiedAsOutInz) return;
1540   fCFM->GetEventContainer()->Fill(eventContainer, AliHFEcuts::kEventStepZRange);  
1541
1542   //
1543   if(!fPassTheEventCut) return;
1544   fCFM->GetEventContainer()->Fill(eventContainer, AliHFEcuts::kEventStepReconstructed);
1545   //printf("pass\n");
1546
1547   fContainer->NewEvent();
1548
1549   fCFM->SetRecEventInfo(fAOD);
1550
1551   if(!fExtraCuts){
1552     fExtraCuts = new AliHFEextraCuts("hfeExtraCuts","HFE Extra Cuts");
1553   }
1554   fExtraCuts->SetRecEventInfo(fAOD);
1555
1556   // Get Number of contributors to the primary vertex for multiplicity-dependent correction
1557   Int_t ncontribVtx = 0;
1558   AliAODVertex *priVtx = fAOD->GetPrimaryVertex();
1559   if(priVtx){
1560     ncontribVtx = priVtx->GetNContributors();
1561   }
1562
1563   // Look for kink mother
1564   Int_t numberofvertices = fAOD->GetNumberOfVertices();
1565   Double_t listofmotherkink[numberofvertices];
1566   Int_t numberofmotherkink = 0;
1567   for(Int_t ivertex=0; ivertex < numberofvertices; ivertex++) {
1568     AliAODVertex *aodvertex = fAOD->GetVertex(ivertex);
1569     if(!aodvertex) continue;
1570     if(aodvertex->GetType()==AliAODVertex::kKink) {
1571       AliAODTrack *mother = (AliAODTrack *) aodvertex->GetParent();
1572       if(!mother) continue;
1573       Int_t idmother = mother->GetID();
1574       listofmotherkink[numberofmotherkink] = idmother;
1575       //printf("ID %d\n",idmother);
1576       numberofmotherkink++;
1577     }
1578   }
1579   //printf("Number of kink mother in the events %d\n",numberofmotherkink);
1580
1581   // Background subtraction-------------------------------------------------------------------
1582   if (GetPlugin(kNonPhotonicElectron)) {
1583     fBackgroundSubtraction->FillPoolAssociatedTracks(fInputEvent,fCentralityF);
1584   }
1585   //------------------------------------------------------------------------------------------
1586
1587   // Loop over tracks
1588   AliAODTrack *track = NULL;
1589   AliAODMCParticle *mctrack = NULL;
1590   Double_t dataE[6]; // [pT, eta, Phi, Charge, type, 'C' or 'B']
1591   Double_t dataDca[6]; // [source, pT, dca, centrality]
1592   Int_t nElectronCandidates = 0;
1593   Int_t pid;
1594   Bool_t signal;
1595   //printf("Number of track %d\n",(Int_t) fAOD->GetNumberOfTracks());
1596   for(Int_t itrack = 0; itrack < fAOD->GetNumberOfTracks(); itrack++){
1597     track = fAOD->GetTrack(itrack); mctrack = NULL;
1598     if(!track) continue;
1599     // Begining
1600     Bool_t passone = kFALSE;  
1601     fQAAODCollection->Fill("Filterorigin", -1);
1602     for(Int_t k=0; k<20; k++) {
1603       Int_t u = 1<<k;     
1604       if((track->TestFilterBit(u))) {
1605         fQAAODCollection->Fill("Filterorigin", k);
1606         passone = kTRUE;
1607       }
1608     }
1609     //if(!passone) printf("what is the filter %d\n",track->GetFilterMap());
1610
1611     if(fUseFilterAOD){
1612       //printf("Filter of the track  %d\n",track->GetFilterMap());
1613       if(!(track->TestFilterBit(fFilter))) continue;  // Only process AOD tracks where the HFE is set
1614     }
1615     //printf("Pass the flag\n");
1616     
1617     signal = kTRUE;
1618     if(HasMCData()){
1619
1620       Int_t label = TMath::Abs(track->GetLabel());
1621       if(label && label < fAODArrayMCInfo->GetEntriesFast())
1622         mctrack = dynamic_cast<AliAODMCParticle *>(fAODArrayMCInfo->At(label));
1623         if(fFillSignalOnly && !fCFM->CheckParticleCuts(AliHFEcuts::kStepMCGenerated, mctrack)) signal = kFALSE;
1624     }
1625     
1626     fVarManager->NewTrack(track, mctrack, fCentralityF, -1, signal);
1627     
1628     if(fFillNoCuts) {
1629       if(signal || !fFillSignalOnly){
1630         fVarManager->FillContainer(fContainer, "recTrackContReco", AliHFEcuts::kStepRecNoCut, kFALSE);
1631         fVarManager->FillContainer(fContainer, "recTrackContMC", AliHFEcuts::kStepRecNoCut, kTRUE);
1632       }
1633     }
1634
1635     if(fApplyCutAOD) {
1636       //printf("Apply cuts\n");
1637       // RecKine: ITSTPC cuts  
1638       if(!ProcessCutStep(AliHFEcuts::kStepRecKineITSTPC, track)) continue;
1639
1640       // Reject kink mother
1641       if(fRejectKinkMother) {
1642         Bool_t kinkmotherpass = kTRUE;
1643         for(Int_t kinkmother = 0; kinkmother < numberofmotherkink; kinkmother++) {
1644           if(track->GetID() == listofmotherkink[kinkmother]) {
1645             kinkmotherpass = kFALSE;
1646             continue;
1647           }
1648         }
1649         if(!kinkmotherpass) continue;
1650       }
1651       
1652       // RecPrim
1653       if(!ProcessCutStep(AliHFEcuts::kStepRecPrim, track)) continue;
1654       
1655       // HFEcuts: ITS layers cuts
1656       if(!ProcessCutStep(AliHFEcuts::kStepHFEcutsITS, track)) continue;
1657       
1658       // HFE cuts: TOF PID and mismatch flag
1659       if(!ProcessCutStep(AliHFEcuts::kStepHFEcutsTOF, track)) continue;
1660       
1661       // HFE cuts: TPC PID cleanup
1662       if(!ProcessCutStep(AliHFEcuts::kStepHFEcutsTPC, track)) continue;
1663       
1664       // HFEcuts: Nb of tracklets TRD0
1665       if(!ProcessCutStep(AliHFEcuts::kStepHFEcutsTRD, track)) continue;
1666     }
1667
1668     // Fill correlation maps before PID
1669     if(signal && fContainer->GetCorrelationMatrix("correlationstepbeforePID")) {
1670       //printf("Fill correlation maps before PID\n");
1671       fVarManager->FillCorrelationMatrix(fContainer->GetCorrelationMatrix("correlationstepbeforePID"));
1672     }
1673
1674     if(HasMCData()){
1675       Double_t hfeimpactR4all=0., hfeimpactnsigmaR4all=0.;
1676       Int_t sourceDca =-1;
1677       if(mctrack && (TMath::Abs(mctrack->GetPdgCode()) == 211)){
1678         if(track->Pt()>4.){
1679           fExtraCuts->GetHFEImpactParameters(track, hfeimpactR4all, hfeimpactnsigmaR4all);
1680           dataDca[0]=0; //pion
1681           dataDca[1]=track->Pt();
1682           dataDca[2]=hfeimpactR4all;
1683           dataDca[3]=fCentralityF;
1684           dataDca[4] = -1; // not store V0 for the moment
1685           dataDca[5] = double(track->Charge());
1686           fQACollection->Fill("Dca", dataDca);
1687         }
1688       }
1689       else if(mctrack && (TMath::Abs(mctrack->GetPdgCode()) == 11)){ // to increas statistics for Martin
1690         if(signal){
1691           fExtraCuts->GetHFEImpactParameters(track, hfeimpactR4all, hfeimpactnsigmaR4all);
1692           if(fSignalCuts->IsCharmElectron(track)){
1693             sourceDca=1;
1694           }
1695           else if(fSignalCuts->IsBeautyElectron(track)){
1696             sourceDca=2;
1697           }
1698           else if(fSignalCuts->IsGammaElectron(track)){
1699             sourceDca=3;
1700           }
1701           else if(fSignalCuts->IsNonHFElectron(track)){
1702             sourceDca=4;
1703           }
1704           else if(fSignalCuts->IsJpsiElectron(track)){
1705             sourceDca=5;
1706           }
1707           else {
1708             sourceDca=6;
1709           }
1710           dataDca[0]=sourceDca;
1711           dataDca[1]=track->Pt();
1712           dataDca[2]=hfeimpactR4all;
1713           dataDca[3]=fCentralityF;
1714           dataDca[4] = -1; // not store V0 for the moment
1715           dataDca[5] = double(track->Charge());
1716           if(signal) fQACollection->Fill("Dca", dataDca);
1717         }
1718       }
1719     }
1720
1721     //printf("Will process to PID\n");
1722
1723     // track accepted, do PID
1724     AliHFEpidObject hfetrack;
1725     hfetrack.SetAnalysisType(AliHFEpidObject::kAODanalysis);
1726     hfetrack.SetRecTrack(track);
1727     if(HasMCData()) hfetrack.SetMCTrack(mctrack);
1728     hfetrack.SetCentrality(fCentralityF);
1729     hfetrack.SetMulitplicity(ncontribVtx); // for correction
1730     if(IsPbPb()) hfetrack.SetPbPb();
1731     else hfetrack.SetPP();
1732     fPID->SetVarManager(fVarManager);
1733     if(!fPID->IsSelected(&hfetrack, fContainer, "recTrackCont", fPIDqa)) continue;   
1734     // we will do PID here as soon as possible
1735
1736     // Background subtraction----------------------------------------------------------------------------------------------
1737     if (GetPlugin(kNonPhotonicElectron)) {
1738       Int_t indexmother = -1;
1739       Int_t mcsource = -1;
1740       if(HasMCData())  mcsource = fBackgroundSubtraction->FindMother(mctrack->GetLabel(),indexmother);
1741       fBackgroundSubtraction->LookAtNonHFE(itrack, track, fInputEvent, 1, fCentralityF, -1,mcsource, indexmother);
1742     }
1743     //---------------------------------------------------------------------------------------------------------------------
1744
1745     // end AOD QA
1746     fQAAODCollection->Fill("Filterend", -1);  
1747     for(Int_t k=0; k<20; k++) {
1748       Int_t u = 1<<k;
1749       if((track->TestFilterBit(u))) {
1750         fQAAODCollection->Fill("Filterend", k);
1751       }
1752     }
1753        
1754     // Apply weight for background contamination
1755     //Double_t weightBackGround = 1.0;
1756     if(signal) {
1757       // Apply weight for background contamination
1758       if(fBackGroundFactorApply) {
1759         if(IsPbPb() && fCentralityF >= 0) fWeightBackGround =  fkBackGroundFactorArray[fCentralityF >= 0 ? fCentralityF : 0]->Eval(TMath::Abs(track->P()));
1760         else    fWeightBackGround =  fkBackGroundFactorArray[0]->Eval(TMath::Abs(track->P())); // pp case
1761         
1762         if(fWeightBackGround < 0.0) fWeightBackGround = 0.0;
1763         else if(fWeightBackGround > 1.0) fWeightBackGround = 1.0;
1764         // weightBackGround as special weight
1765         fVarManager->FillContainer(fContainer, "hadronicBackground", 1, kFALSE, fWeightBackGround);
1766       }
1767       fVarManager->FillCorrelationMatrix(fContainer->GetCorrelationMatrix("correlationstepafterPID"));
1768     }
1769     
1770     nElectronCandidates++;    
1771     if(HasMCData()){
1772       dataE[0] = track->Pt();
1773       dataE[1] = track->Eta();
1774       dataE[2] = track->Phi();
1775       dataE[3] = track->Charge();
1776       dataE[4] = -1;
1777       dataE[5] = -1;
1778       // Track selected: distinguish between true and fake
1779       AliDebug(1, Form("Candidate Selected, filling THnSparse, PID: %d\n", mctrack ? mctrack->GetPdgCode(): -1));
1780       if(mctrack && ((pid = TMath::Abs(mctrack->GetPdgCode())) == 11)){
1781       
1782         Int_t type = 0;
1783         if(fSignalCuts->IsCharmElectron(track))
1784           type = 1;
1785         else if(fSignalCuts->IsBeautyElectron(track))
1786           type = 2;
1787         AliDebug(1, Form("Type: %d\n", type));
1788         if(type){
1789                 dataE[5] = type; // beauty[1] or charm[2]
1790                 dataE[4] = 2;  // signal electron
1791         }
1792         else{
1793                 dataE[4] = 1; // not a signal electron
1794                 dataE[5] = 0;
1795         }
1796       } 
1797       else {
1798         // Fill THnSparse with the information for Fake Electrons
1799         dataE[4] = 0;
1800         dataE[5] = 0;
1801       }
1802       // fill the performance THnSparse, if the mc origin could be defined
1803       if(dataE[4] > -1){
1804         AliDebug(1, Form("Entries: [%.3f|%.3f|%.3f|%f|%f|%f]\n", dataE[0],dataE[1],dataE[2],dataE[3],dataE[4],dataE[5]));
1805         fQACollection->Fill("PIDperformance", dataE);
1806       }
1807     }
1808
1809     if (GetPlugin(kDEstep)) {
1810       if (!HasMCData()){
1811         Double_t hfeimpactR=0., hfeimpactnsigmaR=0.;
1812         fExtraCuts->GetHFEImpactParameters(track, hfeimpactR, hfeimpactnsigmaR);
1813         dataDca[0]=-1; //for data, don't know the origin
1814         dataDca[1]=track->Pt();
1815         dataDca[2]=hfeimpactR;
1816         dataDca[3]=fCentralityF;
1817         dataDca[4] = -1; // not store V0 for the moment
1818         dataDca[5] = double(track->Charge());
1819         fQACollection->Fill("Dca", dataDca);
1820       }
1821
1822       // Fill Containers for impact parameter analysis
1823       if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepHFEcutsDca + AliHFEcuts::kNcutStepsMCTrack + AliHFEcuts::kNcutStepsRecTrack,track)) continue;
1824       if(signal) {
1825         // Apply weight for background contamination after ip cut
1826         if(fBackGroundFactorApply) {
1827               fWeightBackGround =  fkBackGroundFactorArray[0]->Eval(TMath::Abs(track->P())); // pp case
1828               if(fWeightBackGround < 0.0) fWeightBackGround = 0.0;
1829               else if(fWeightBackGround > 1.0) fWeightBackGround = 1.0;
1830               // weightBackGround as special weight
1831               fVarManager->FillContainer(fContainer, "hadronicBackground", 2, kFALSE, fWeightBackGround);
1832         }
1833       }
1834     }
1835   }
1836   fQACollection->Fill("nElectronTracksEvent", nElectronCandidates);
1837 }
1838
1839 //____________________________________________________________
1840 Bool_t AliAnalysisTaskHFE::ProcessMCtrack(AliVParticle *track){
1841   //
1842   // Filter the Monte Carlo Track
1843   // Additionally Fill a THnSparse for Signal To Background Studies
1844   // Works for AOD and MC analysis Type
1845   //
1846   fVarManager->NewTrack(track, NULL, fCentralityF, -1, kTRUE);
1847   Double_t signalContainer[6];
1848
1849   signalContainer[0] = track->Pt();
1850   signalContainer[1] = track->Eta();
1851   signalContainer[2] = track->Phi();
1852   signalContainer[3] = track->Charge()/3;
1853
1854   Double_t vertex[3] = {0.,0.,0.}; // Production vertex cut to mask gammas which are NOT supposed to have hits in the first ITS layer(s)
1855   if(IsESDanalysis()){
1856     AliMCParticle *mctrack = dynamic_cast<AliMCParticle *>(track);
1857     if(mctrack){
1858       vertex[0] = mctrack->Particle()->Vx();
1859       vertex[1] = mctrack->Particle()->Vy();
1860     }
1861   } else {
1862     AliAODMCParticle *aodmctrack = dynamic_cast<AliAODMCParticle *>(track);
1863     if(aodmctrack) aodmctrack->XvYvZv(vertex);
1864   }
1865
1866   //printf("MC Generated\n");
1867   if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepMCGenerated, track)) return kFALSE;
1868   //printf("MC Generated pass\n");
1869   fVarManager->FillContainer(fContainer, "MCTrackCont", AliHFEcuts::kStepMCGenerated, kFALSE);
1870   signalContainer[4] = 0;
1871   if(fSignalCuts->IsSelected(track)){
1872     //fVarManager->FillContainer(fContainer, "MCTrackCont", AliHFEcuts::kStepMCsignal, kFALSE);
1873     // Filling of the Signal/Background histogram using the 
1874     // definition of the codes for charm and beauty as below in
1875     // th crearion of the histogram
1876     if(fSignalCuts->IsCharmElectron(track))
1877       signalContainer[4] = 1;
1878     else 
1879       signalContainer[4] = 2;
1880   } else {
1881     signalContainer[4] = 0; // (and other background)
1882   }
1883   signalContainer[5] = 0;
1884   // apply cut on the sqrt of the production vertex
1885   Double_t radVertex = TMath::Sqrt(vertex[0]*vertex[0] + vertex[1] * vertex[1]);
1886   if(radVertex < 3.5){
1887     // Within first ITS layer(2) -> Background we cannot reject by ITS cut, let it pass
1888     signalContainer[5] = 1;
1889   } else if (radVertex < 7.5){
1890     signalContainer[5] = 2;
1891   }
1892   fQACollection->Fill("SignalToBackgroundMC", signalContainer);
1893
1894   // Step GeneratedZOutNoPileUp
1895   if((fIdentifiedAsPileUp) || (TMath::Abs(fVz) > fCuts->GetVertexRange()) || (fCentralityF < 0)) return kFALSE;
1896   fVarManager->FillContainer(fContainer, "MCTrackCont", AliHFEcuts::kStepMCGeneratedZOutNoPileUpCentralityFine, kFALSE);
1897   //printf("In ProcessMCtrack %f\n",fCentralityF);
1898
1899   // Step Generated Event Cut
1900   if(!fPassTheEventCut) return kFALSE;
1901   fVarManager->FillContainer(fContainer, "MCTrackCont", AliHFEcuts::kStepMCGeneratedEventCut, kFALSE);
1902
1903   if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepMCInAcceptance, track)) return kFALSE;
1904   fVarManager->FillContainer(fContainer, "MCTrackCont", AliHFEcuts::kStepMCInAcceptance, kFALSE);
1905   return kTRUE;
1906 }
1907
1908 //____________________________________________________________
1909 Bool_t AliAnalysisTaskHFE::PreSelectTrack(AliESDtrack *track) const {
1910   //
1911   // Preselect tracks
1912   //
1913   
1914
1915   Bool_t survived = kTRUE;
1916
1917   if(fCutspreselect) {
1918     //printf("test preselect\n");
1919     if(!fCutspreselect->IsSelected(track)) survived=kFALSE;
1920   }
1921   //printf("survived %d\n",(Int_t)survived);
1922   
1923   if(survived && fPIDpreselect){
1924     // Apply PID
1925     AliHFEpidObject hfetrack;
1926     hfetrack.SetAnalysisType(AliHFEpidObject::kESDanalysis);
1927     hfetrack.SetRecTrack(track);
1928     if(!fPIDpreselect->IsSelected(&hfetrack)) {
1929       //printf("Did not pass AliHFEcuts::kPID\n");
1930       survived = kFALSE;
1931     }
1932     //else printf("Pass AliHFEcuts::kPID\n");
1933   }
1934
1935   return survived; 
1936       
1937 }
1938 //____________________________________________________________
1939 void AliAnalysisTaskHFE::MakeEventContainer(){
1940   //
1941   // Create the event container for the correction framework and link it
1942   // 1st bin: Vertex z-position
1943   // 2nd bin: V0AND decision (normalization to sigma_inel)
1944   // 3rd bin: Centrality class (for pp defined as number of contributors in vertex.)
1945   // 4th bin: Number of contributors > 0
1946   //
1947   
1948   const Int_t kNvar = 4;  // number of variables on the grid: 
1949   Int_t nBins[kNvar] = {120, 2, 11, 2};
1950   Double_t binMin[kNvar] = {-30. , 0., 0.0, 0.};
1951   Double_t binMax[kNvar] = {30., 2., 11.0, 2.};
1952   
1953   AliCFContainer *evCont = new AliCFContainer("eventContainer", "Container for events", AliHFEcuts::kNcutStepsEvent, kNvar, nBins);
1954   
1955   Double_t *vertexBins = AliHFEtools::MakeLinearBinning(nBins[0], binMin[0], binMax[0]);
1956   Double_t *v0andBins = AliHFEtools::MakeLinearBinning(nBins[1], binMin[1], binMax[1]);
1957   Double_t *centralityBins = AliHFEtools::MakeLinearBinning(nBins[2], binMin[2], binMax[2]);
1958   Double_t *contributorsBins = AliHFEtools::MakeLinearBinning(nBins[3], binMin[3], binMax[3]);
1959   evCont->SetBinLimits(0, vertexBins);
1960   evCont->SetBinLimits(1, v0andBins);
1961   evCont->SetBinLimits(2, centralityBins);
1962   evCont->SetBinLimits(3, contributorsBins);
1963   delete[] vertexBins; delete[] v0andBins; delete[] centralityBins; delete[] contributorsBins;
1964     
1965   fCFM->SetEventContainer(evCont);
1966 }
1967
1968 //____________________________________________________________
1969 void AliAnalysisTaskHFE::MakeParticleContainer(){
1970   //
1971   // Create the particle container for the correction framework manager and 
1972   // link it
1973   //
1974   if(!fContainer) fContainer = new AliHFEcontainer("trackContainer");
1975   fVarManager->DefineVariables(fContainer);
1976
1977   // Create Correction Framework containers
1978   fContainer->CreateContainer("MCTrackCont", "Track Container filled with MC information", AliHFEcuts::kNcutStepsMCTrack);
1979   fContainer->CreateContainer("recTrackContReco", "Track Container filled with MC information", AliHFEcuts::kNcutStepsRecTrack + fPID->GetNumberOfPIDdetectors());
1980   fContainer->CreateContainer("recTrackContMC", "Track Container filled with MC information", AliHFEcuts::kNcutStepsRecTrack + fPID->GetNumberOfPIDdetectors());
1981   
1982   fContainer->CreateContainer("hadronicBackground", "Container for Hadronic Background", 3);
1983   fContainer->CreateContainer("recTrackContDEReco", "Container for displaced electron analysis with Reco information", 1);
1984   fContainer->CreateContainer("recTrackContDEMC", "Container for displaced electron analysis with MC information", 1);
1985   fContainer->CreateContainer("recTrackContSecvtxReco", "Container for secondary vertexing analysis with Reco information", 1);
1986   fContainer->CreateContainer("recTrackContSecvtxMC", "Container for secondary vertexing analysis with MC information", 1);
1987
1988   if(HasMCData()){
1989     fContainer->CreateContainer("conversionElecs", "Container for weighted conversion electrons",7);
1990     fContainer->CreateContainer("mesonElecs", "Container for weighted electrons from meson decays",7);
1991     fContainer->Sumw2("conversionElecs");
1992     fContainer->Sumw2("mesonElecs");
1993    
1994     if(fisNonHFEsystematics){
1995       const Char_t *sourceName[kElecBgSpecies]={"Pion","Eta","Omega","Phi","EtaPrime","Rho"};
1996       const Char_t *levelName[kBgLevels]={"Best","Lower","Upper"};
1997       for(Int_t iSource = 0; iSource < kElecBgSpecies; iSource++){
1998         for(Int_t iLevel = 0; iLevel < kBgLevels; iLevel++){
1999           fContainer->CreateContainer(Form("conversionElecs%s%s",sourceName[iSource],levelName[iLevel]), Form("Container for weighted conversion electrons from %s grandm., %s level",sourceName[iSource],levelName[iLevel]),5);
2000           fContainer->CreateContainer(Form("mesonElecs%s%s",sourceName[iSource],levelName[iLevel]), Form("Container for weighted electrons from %s decays, %s level",sourceName[iSource],levelName[iLevel]),5);
2001           fContainer->Sumw2(Form("conversionElecs%s%s",sourceName[iSource],levelName[iLevel]));
2002           fContainer->Sumw2(Form("mesonElecs%s%s",sourceName[iSource],levelName[iLevel]));
2003           if(IsPbPb())break;
2004         }
2005       }
2006     }
2007     //fContainer->CreateContainer("charmElecs", "Container for weighted charm electrons",2);
2008   }
2009
2010   fContainer->CreateCorrelationMatrix("correlationstepafterPID","THnSparse with correlations");
2011   fContainer->CreateCorrelationMatrix("correlationstepafterDE","THnSparse with correlations");
2012   if(!fVarManager->IsVariableDefined("centrality")) {
2013     //printf("Create the two other correlation maps\n");
2014     fContainer->CreateCorrelationMatrix("correlationstepbeforePID","THnSparse with correlations");
2015     fContainer->CreateCorrelationMatrix("correlationstepafterTOF","THnSparse with correlations");
2016   }
2017
2018   // Define the step names
2019   for(UInt_t istep = 0; istep < AliHFEcuts::kNcutStepsMCTrack; istep++){
2020     fContainer->SetStepTitle("MCTrackCont", AliHFEcuts::MCCutName(istep), istep);
2021   }
2022   for(UInt_t istep = 0; istep < AliHFEcuts::kNcutStepsRecTrack; istep++){
2023     fContainer->SetStepTitle("recTrackContReco", AliHFEcuts::RecoCutName(istep), istep);
2024     fContainer->SetStepTitle("recTrackContMC", AliHFEcuts::RecoCutName(istep), istep);
2025   }
2026   for(UInt_t ipid = 0; ipid < fPID->GetNumberOfPIDdetectors(); ipid++){
2027     fContainer->SetStepTitle("recTrackContReco", fPID->SortedDetectorName(ipid), AliHFEcuts::kNcutStepsRecTrack + ipid);
2028     fContainer->SetStepTitle("recTrackContMC", fPID->SortedDetectorName(ipid), AliHFEcuts::kNcutStepsRecTrack + ipid);
2029   }
2030 }
2031
2032 //____________________________________________________________
2033 void AliAnalysisTaskHFE::InitPIDperformanceQA(){
2034   // Add a histogram for Fake electrons
2035   const Int_t nDim=6;
2036   Int_t nBin[nDim] = {40, 8, 18, 2, 3, 3};
2037   //number of variables on the grid:pt,eta,phi,charge,
2038   const Double_t kPtbound[2] = {0.1, 20.};
2039   const Double_t kEtabound[2] = {-0.8, 0.8};
2040   const Double_t kPhibound[2] = {0., 2. * TMath::Pi()}; 
2041   const Double_t kChargebound[2] = {-1.1, 1.1};
2042   const Double_t kAddInf1bound[2] = {0., 3.};
2043   const Double_t kAddInf2bound[2] = {0., 3.};
2044   Double_t minima[nDim] = {kPtbound[0], kEtabound[0], kPhibound[0], kChargebound[0], kAddInf1bound[0], kAddInf2bound[0]}; 
2045   Double_t maxima[nDim] = {kPtbound[1], kEtabound[1], kPhibound[1], kChargebound[1], kAddInf1bound[1], kAddInf2bound[1]}; 
2046   
2047   fQACollection->CreateTHnSparse("PIDperformance", "PID performance; pT [GeV/c]; theta [rad]; phi [rad]; charge; type (0 - not el, 1 - other el, 2 - HF el; flavor (0 - no, 1 - charm, 2 - bottom)", nDim, nBin, minima, maxima);
2048   fQACollection->CreateTHnSparse("SignalToBackgroundMC", "PID performance; pT [GeV/c]; theta [rad]; phi [rad]; charge; flavor (0 - no, 1 - charm, 2 - bottom); ITS Cluster (0 - no, 1 - first (and maybe second), 2 - second)", nDim, nBin, minima, maxima);
2049
2050   fQACollection->BinLogAxis("PIDperformance", 0);
2051   fQACollection->BinLogAxis("SignalToBackgroundMC", 0);
2052   fQACollection->Sumw2("PIDperformance");
2053   fQACollection->Sumw2("SignalToBackgroundMC");
2054 }
2055
2056 //____________________________________________________________
2057 void AliAnalysisTaskHFE::InitContaminationQA(){
2058   // 
2059   // Add QA for Impact Parameter cut
2060   //
2061
2062   TObjArray *array = fVarManager->GetVariables();
2063   Int_t nvars = array->GetEntriesFast();
2064   for(Int_t v = 0; v < nvars; v++) {
2065     AliHFEvarManager::AliHFEvariable *variable = (AliHFEvarManager::AliHFEvariable *) array->At(v);
2066     if(!variable) continue;
2067     TString name(((AliHFEvarManager::AliHFEvariable *)variable)->GetName());
2068     if(!name.CompareTo("pt")) {
2069       const Int_t nBinPt  = variable->GetNumberOfBins();
2070       const Double_t *kPtRange = variable->GetBinning();
2071
2072       fQACollection->CreateTH1Farray("hadronsBeforeIPcut", "Hadrons before IP cut", nBinPt, kPtRange);
2073       fQACollection->CreateTH1Farray("hadronsAfterIPcut", "Hadrons after IP cut", nBinPt, kPtRange);
2074
2075       fQACollection->CreateTH2Farray("Ke3Kecorr", "Ke3 decay e and K correlation; Ke3K p_{t}; Ke3e p_{t}; ", nBinPt, kPtRange, 20,0.,20.);
2076       fQACollection->CreateTH2Farray("Ke3K0Lecorr", "Ke3 decay e and K0L correlation; Ke3K0L p_{t}; Ke3e p_{t}; ", nBinPt, kPtRange, 20,0.,20.);
2077       fQACollection->CreateTH1Farray("Kptspectra", "Charged Kaons: MC p_{t} ", nBinPt, kPtRange);
2078       fQACollection->CreateTH1Farray("K0Lptspectra", "K0L: MC p_{t} ", nBinPt, kPtRange);
2079
2080       const Double_t kDCAbound[2] = {-0.2, 0.2};
2081
2082       const Int_t nDimDca=6;
2083       const Int_t nBinDca[nDimDca] = { 8, nBinPt, 800, 12,  6, 2};
2084       Double_t minimaDca[nDimDca]  = { -1., 0., kDCAbound[0], -1., -1, -1.1};
2085       Double_t maximaDca[nDimDca]  = { 7., 20., kDCAbound[1], 11.,  5, 1.1};
2086
2087       Double_t *sourceBins = AliHFEtools::MakeLinearBinning(nBinDca[0], minimaDca[0], maximaDca[0]);
2088       Double_t *dcaBins = AliHFEtools::MakeLinearBinning(nBinDca[2], minimaDca[2], maximaDca[2]);
2089       Double_t *centralityBins = AliHFEtools::MakeLinearBinning(nBinDca[3], minimaDca[3], maximaDca[3]);
2090       Double_t *v0PIDBins = AliHFEtools::MakeLinearBinning(nBinDca[4], minimaDca[4], maximaDca[4]);
2091       Double_t *chargeBins = AliHFEtools::MakeLinearBinning(nBinDca[5], minimaDca[5], maximaDca[5]);
2092
2093       fQACollection->CreateTHnSparseNoLimits("Dca", "Dca; source (0-all, 1-charm,etc); pT [GeV/c]; dca; centrality bin; v0pid; charge", nDimDca, nBinDca);
2094       ((THnSparse*)(fQACollection->Get("Dca")))->SetBinEdges(0, sourceBins);
2095       ((THnSparse*)(fQACollection->Get("Dca")))->SetBinEdges(1, kPtRange);
2096       ((THnSparse*)(fQACollection->Get("Dca")))->SetBinEdges(2, dcaBins);
2097       ((THnSparse*)(fQACollection->Get("Dca")))->SetBinEdges(3, centralityBins);
2098       ((THnSparse*)(fQACollection->Get("Dca")))->SetBinEdges(4, v0PIDBins);
2099       ((THnSparse*)(fQACollection->Get("Dca")))->SetBinEdges(5, chargeBins);
2100
2101       break;
2102     }  
2103   }
2104
2105 }
2106
2107 //____________________________________________________________
2108 void AliAnalysisTaskHFE::InitHistoITScluster(){
2109   //
2110     // Initialize a temporary histogram to monitor the chi2/ITS cluster
2111     if(IsPbPb()) {
2112         const Int_t kNDim = 7;
2113         const Int_t kNBins[kNDim] = {88, 20,90,11, 160, 2, 1000};
2114         const Double_t kMin[kNDim] = {0.1, -1,0,  0.,0., 0,  0.};
2115         const Double_t kMax[kNDim] = {20., 1, 2.*TMath::Pi(), 11.,160, 2, 100.};
2116         fQACollection->CreateTHnSparse("fChi2perITScluster", "chi2/ITS cluster; p_{T} (GeV/c);eta;phi; centrality class;nclus;sharebit; #chi^{2}/ITS cluster", kNDim, kNBins, kMin, kMax);
2117         fQACollection->BinLogAxis("fChi2perITScluster", 0);
2118     }
2119     else
2120     {
2121         const Int_t kNDim = 3;
2122         const Int_t kNBins[kNDim] = {44, 11, 1000};
2123         const Double_t kMin[kNDim] = {0.1, 0., 0.};
2124         const Double_t kMax[kNDim] = {20., 11., 100.};
2125         fQACollection->CreateTHnSparse("fChi2perITScluster", "chi2/ITS cluster; p_{T} (GeV/c); centrality class; #chi^{2}/ITS cluster", kNDim, kNBins, kMin, kMax);
2126         fQACollection->BinLogAxis("fChi2perITScluster", 0);
2127     }
2128 }
2129
2130 //____________________________________________________________
2131 void AliAnalysisTaskHFE::SelectSpecialTrigger(const Char_t *trgclust, Int_t runMin, Int_t runMax){
2132   //
2133   // Select only events triggered by a special trigeer cluster
2134   //
2135   if(!fSpecialTrigger) fSpecialTrigger = new AliOADBContainer("SpecialTrigger");
2136   fSpecialTrigger->AppendObject(new TObjString(trgclust), runMin, runMax);
2137 }
2138
2139 //____________________________________________________________
2140 const Char_t * AliAnalysisTaskHFE::GetSpecialTrigger(Int_t run){
2141   //
2142   // Derive selected trigger string for given run
2143   //
2144   if(!fSpecialTrigger) return NULL;
2145   TObjString *trg = dynamic_cast<TObjString *>(fSpecialTrigger->GetObject(run));
2146   if(!trg) return NULL;
2147   return trg->String().Data();
2148 }
2149
2150 //____________________________________________________________
2151 void AliAnalysisTaskHFE::PrintStatus() const {
2152   //
2153   // Print Analysis status
2154   //
2155   printf("\n\tAnalysis Settings\n\t========================================\n\n");
2156   printf("\tSecondary Vertex finding: %s\n", GetPlugin(kSecVtx) ? "YES" : "NO");
2157   printf("\tPrimary Vertex resolution: %s\n", GetPlugin(kPriVtx) ? "YES" : "NO");
2158   printf("\tDisplaced electron analysis step: %s\n", GetPlugin(kDEstep) ? "YES" : "NO");
2159   printf("\tTagged Track Analysis: %s\n", GetPlugin(kTaggedTrackAnalysis) ? "YES" : "NO");
2160   printf("\n");
2161   printf("\tParticle Identification Detectors:\n");
2162   fPID->PrintStatus();
2163   printf("\n");
2164   printf("\tQA: \n");
2165   printf("\t\tPID: %s\n", IsQAOn(kPIDqa) ? "YES" :  "NO");
2166   printf("\t\tCUTS: %s\n", (fCuts != NULL && fCuts->IsQAOn()) ? "YES" : "NO");
2167   printf("\t\tMC: %s\n", IsQAOn(kMCqa) ? "YES" : "NO");
2168   printf("\n");
2169 }
2170
2171 //____________________________________________________________
2172 Bool_t AliAnalysisTaskHFE::FillProductionVertex(const AliVParticle * const track) const{
2173   //
2174   // Find the production vertex of the associated MC track
2175   //
2176   if(!fMCEvent) return kFALSE;
2177   const AliVParticle *mctrack = NULL;
2178   TString objectType = track->IsA()->GetName();
2179   if(objectType.CompareTo("AliESDtrack") == 0 || objectType.CompareTo("AliAODTrack") == 0){
2180     // Reconstructed track
2181     mctrack = fMCEvent->GetTrack(TMath::Abs(track->GetLabel()));
2182   } else {
2183     // MCParticle
2184     mctrack = track;
2185   }
2186
2187   if(!mctrack) return kFALSE;
2188
2189   Double_t xv = 0.0;
2190   Double_t yv = 0.0;
2191  
2192   if(TString(mctrack->IsA()->GetName()).CompareTo("AliMCParticle") == 0){
2193     // case MCParticle
2194     const AliMCParticle *mcpart = dynamic_cast<const AliMCParticle *>(mctrack);
2195     if(mcpart){
2196       xv =  mcpart->Xv();
2197       yv =  mcpart->Yv();
2198     }
2199   } else {
2200     // case AODMCParticle
2201     const AliAODMCParticle *mcpart = dynamic_cast<const AliAODMCParticle *>(mctrack);
2202     if(mcpart){
2203       xv =  mcpart->Xv();
2204       yv =  mcpart->Yv();
2205     }
2206   }
2207
2208   //printf("xv %f, yv %f\n",xv,yv);
2209   fQACollection->Fill("radius", TMath::Abs(xv),TMath::Abs(yv));
2210
2211   return kTRUE;
2212
2213 }
2214 //__________________________________________
2215 void AliAnalysisTaskHFE::SwitchOnPlugin(Int_t plug){
2216   //
2217   // Switch on Plugin
2218   // Available:
2219   //  - Primary vertex studies
2220   //  - Secondary vertex Studies
2221   //  - Post Processing
2222   //
2223   switch(plug){
2224     case kPriVtx: SETBIT(fPlugins, plug); break;
2225     case kSecVtx: SETBIT(fPlugins, plug); break;
2226     case kIsElecBackGround: SETBIT(fPlugins, plug); break;
2227     case kPostProcess: SETBIT(fPlugins, plug); break;
2228     case kDEstep: SETBIT(fPlugins, plug); break;
2229     case kTaggedTrackAnalysis: SETBIT(fPlugins, plug); break;
2230     case kNonPhotonicElectron: SETBIT(fPlugins, plug); break; 
2231     default: AliError("Unknown Plugin");
2232   };
2233 }
2234 //__________________________________________
2235 Bool_t AliAnalysisTaskHFE::ProcessCutStep(Int_t cutStep, AliVParticle *track){
2236   //
2237   // Check single track cuts for a given cut step
2238   // Fill the particle container
2239   //
2240   const Int_t kMCOffset = AliHFEcuts::kNcutStepsMCTrack;
2241   if(!fCFM->CheckParticleCuts(cutStep + kMCOffset, track)) return kFALSE;
2242   if(fVarManager->IsSignalTrack()) {
2243     fVarManager->FillContainer(fContainer, "recTrackContReco", cutStep, kFALSE);
2244     fVarManager->FillContainer(fContainer, "recTrackContMC", cutStep, kTRUE);
2245   }
2246   return kTRUE;
2247 }
2248 //___________________________________________________
2249 Bool_t AliAnalysisTaskHFE::ReadCentrality() {
2250   //
2251   // Recover the centrality of the event from ESD or AOD
2252   //
2253   
2254   Float_t fCentralityLimitstemp[12];
2255   Float_t fCentralityLimitsdefault[12]= {0.,5.,10., 20., 30., 40., 50., 60.,70.,80., 90., 100.};
2256   if(!fPbPbUserCentralityBinning) memcpy(fCentralityLimitstemp,fCentralityLimitsdefault,sizeof(fCentralityLimitsdefault));
2257   else memcpy(fCentralityLimitstemp,fCentralityLimits,sizeof(fCentralityLimitsdefault));
2258   
2259
2260   Int_t bin = -1;
2261   if(IsPbPb()) {
2262     // Centrality
2263     AliCentrality *centrality = fInputEvent->GetCentrality();
2264     fCentralityPercent = centrality->GetCentralityPercentile("V0M");
2265     //printf("centrality %f\n",fCentralityPercent);
2266
2267     for(Int_t ibin = 0; ibin < 11; ibin++){
2268       if(fCentralityPercent >= fCentralityLimitstemp[ibin] && fCentralityPercent < fCentralityLimitstemp[ibin+1]){
2269         bin = ibin;
2270         //printf("test bin %f, low %f, high %f, %d\n",fCentralityPercent,fCentralityLimitstemp[ibin],fCentralityLimitstemp[ibin+1],ibin);
2271         break;
2272       }
2273     }
2274     
2275     if(bin == -1) bin = 11; // Overflow
2276   } else {
2277     // PP: Tracklet multiplicity, use common definition
2278     Int_t itsMultiplicity = GetITSMultiplicity(fInputEvent);
2279     Int_t multiplicityLimits[8] = {0, 1, 9, 17, 25, 36, 60, 500};
2280     for(Int_t ibin = 0; ibin < 7; ibin++){  
2281       if(itsMultiplicity >= multiplicityLimits[ibin] && itsMultiplicity < multiplicityLimits[ibin + 1]){
2282         bin = ibin;
2283         break;
2284       }
2285     }
2286     if(bin == -1) bin = 7;  // Overflow
2287   }
2288   fCentralityF = bin;
2289   AliDebug(2, Form("Centrality class %d\n", fCentralityF));
2290
2291  
2292   // contributors, to be outsourced
2293   const AliVVertex *vtx;
2294   if(IsAODanalysis()){
2295     AliAODEvent *fAOD = dynamic_cast<AliAODEvent *>(fInputEvent);
2296     if(!fAOD){
2297       AliError("AOD Event required for AOD Analysis");
2298       return kFALSE;
2299     }
2300     vtx = fAOD->GetPrimaryVertex();
2301   } else {
2302     AliESDEvent *fESD = dynamic_cast<AliESDEvent *>(fInputEvent);
2303     if(!fESD){
2304       AliError("ESD Event required for ESD Analysis");
2305       return kFALSE;
2306     }
2307     vtx = fESD->GetPrimaryVertexSPD();
2308   }
2309   if(!vtx){ 
2310     fContributors = 0.5;
2311     return kFALSE;
2312   }
2313   else {
2314     Int_t contributorstemp = vtx->GetNContributors();
2315     if( contributorstemp <=  0) {
2316       fContributors =  0.5;
2317       //printf("Number of contributors %d and vz %f\n",contributorstemp,vtx->GetZ());
2318     }
2319     else fContributors = 1.5;
2320     //printf("Number of contributors %d\n",contributorstemp);
2321   }
2322   return kTRUE;
2323 }
2324
2325 //___________________________________________________
2326 Int_t AliAnalysisTaskHFE::GetITSMultiplicity(AliVEvent *ev){
2327   //
2328   // Definition of the Multiplicity according to the JPSI group (F. Kramer)
2329   //
2330   Int_t nTracklets = 0;
2331   Int_t nAcc = 0;
2332   Double_t etaRange = 1.6;
2333
2334   if (ev->IsA() == AliAODEvent::Class()) {
2335     AliAODTracklets *tracklets = ((AliAODEvent*)ev)->GetTracklets();
2336     nTracklets = tracklets->GetNumberOfTracklets();
2337     for (Int_t nn = 0; nn < nTracklets; nn++) {
2338       Double_t theta = tracklets->GetTheta(nn);
2339       Double_t eta = -TMath::Log(TMath::Tan(theta/2.0));
2340       if (TMath::Abs(eta) < etaRange) nAcc++;
2341     }
2342   } else if (ev->IsA() == AliESDEvent::Class()) {
2343     nTracklets = ((AliESDEvent*)ev)->GetMultiplicity()->GetNumberOfTracklets();
2344     for (Int_t nn = 0; nn < nTracklets; nn++) {
2345        Double_t eta = ((AliESDEvent*)ev)->GetMultiplicity()->GetEta(nn);
2346       if (TMath::Abs(eta) < etaRange) nAcc++;
2347     }
2348   } else return -1;
2349
2350   return nAcc;
2351 }
2352
2353 //___________________________________________________
2354 Bool_t AliAnalysisTaskHFE::InitializeHadronBackground(Int_t run){
2355   //
2356   // Initialize background factors array from the AliOADBContainer
2357   // The container is expected to provide a TObjArray with the name
2358   // "hadronBackground" and the size 12 for the given run number
2359   //
2360   AliDebug(1, "Deriving hadronic background parameterization from OADB container");
2361   TObjArray *functions = dynamic_cast<TObjArray *>(fHadronBackgroundOADB->GetObject(run, "hadronBackground"));
2362   if(!functions){
2363     AliDebug(1, "Content in the OADB Container is not a TObjArray");
2364     fBackGroundFactorApply = kFALSE;
2365     return kFALSE;
2366   } 
2367   if(functions->GetSize() < 12){
2368     AliDebug(1, Form("Size not matching: 12 expected, %d provided", functions->GetSize()));
2369     fBackGroundFactorApply = kFALSE;
2370     return kFALSE;
2371   }
2372   for(Int_t icent = 0; icent < 12; icent++) fkBackGroundFactorArray[icent] = dynamic_cast<const TF1 *>(functions->UncheckedAt(icent));
2373   return kTRUE;
2374 }
2375
2376 //___________________________________________________
2377 void AliAnalysisTaskHFE::RejectionPileUpVertexRangeEventCut() {
2378   //
2379   // Recover the centrality of the event from ESD or AOD
2380   //
2381  if(IsAODanalysis()){
2382
2383    AliAODEvent *fAOD = dynamic_cast<AliAODEvent *>(fInputEvent);
2384    if(!fAOD){
2385      AliError("AOD Event required for AOD Analysis");
2386        return;
2387    }
2388    // PileUp
2389    fIdentifiedAsPileUp = kFALSE;
2390    if(fRemovePileUp && fAOD->IsPileupFromSPD()) fIdentifiedAsPileUp = kTRUE; 
2391    // Z vertex
2392    fIdentifiedAsOutInz = kFALSE;
2393    //printf("Z vertex %f and out %f\n",fAOD->GetPrimaryVertex()->GetZ(),fCuts->GetVertexRange());
2394    if(TMath::Abs(fAOD->GetPrimaryVertex()->GetZ()) > fCuts->GetVertexRange()) fIdentifiedAsOutInz = kTRUE;
2395    // Event Cut
2396    fPassTheEventCut = kTRUE;
2397    if(!fCFM->CheckEventCuts(AliHFEcuts::kEventStepReconstructed, fAOD)) fPassTheEventCut = kFALSE; 
2398    
2399    
2400  } else {
2401    
2402    AliDebug(3, "Processing ESD Centrality");
2403    AliESDEvent *fESD = dynamic_cast<AliESDEvent *>(fInputEvent);
2404    if(!fESD){
2405      AliError("ESD Event required for ESD Analysis");
2406        return;
2407    }
2408    // PileUp
2409    fIdentifiedAsPileUp = kFALSE;
2410    if(fRemovePileUp && fESD->IsPileupFromSPD()) fIdentifiedAsPileUp = kTRUE; 
2411    // Z vertex
2412    fIdentifiedAsOutInz = kFALSE;
2413    if (IsPbPb()) {
2414      //printf("PbPb\n");
2415      if(fESD->GetPrimaryVertex()){
2416        if(TMath::Abs(fESD->GetPrimaryVertex()->GetZ()) > fCuts->GetVertexRange()) fIdentifiedAsOutInz = kTRUE;
2417      }
2418    }
2419    else {
2420      //printf("pp\n");
2421      if(fESD->GetPrimaryVertexTracks()){
2422        if(TMath::Abs(fESD->GetPrimaryVertexTracks()->GetZ()) > fCuts->GetVertexRange()) fIdentifiedAsOutInz = kTRUE;
2423      }
2424    }
2425    //Event Cut
2426    fPassTheEventCut = kTRUE;
2427    if(!fCFM->CheckEventCuts(AliHFEcuts::kEventStepReconstructed, fESD)) fPassTheEventCut = kFALSE;   
2428   
2429
2430  }
2431
2432 }
2433