]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - PWG3/hfe/AliAnalysisTaskHFE.cxx
Update of the HFE package
[u/mrichter/AliRoot.git] / PWG3 / hfe / AliAnalysisTaskHFE.cxx
index da3edcab30f83c0082d67d43c4e7a850ffc4f1c2..5bb8956a29effca81cd63f9149251586f01e57b1 100644 (file)
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/
-/*
- * The analysis task:
- * Filling an AliCFContainer with the quantities pt, eta and phi
- * for tracks which survivied the particle cuts (MC resp. ESD tracks)
- * Track selection is done using the AliHFE package
- * 
- * Author:
- *  Raphaelle Bailhache <R.Bailhache@gsi.de>
- *  Markus Fasel <M.Fasel@gsi.de>
- *  Matus Kalisky <matus.kalisky@cern.ch>
- *  MinJung Kweon <minjung@physi.uni-heidelberg.de>
- */
+//
+// The analysis task:
+// Filling an AliCFContainer with the quantities pt, eta and phi
+// for tracks which survivied the particle cuts (MC resp. ESD tracks)
+// Track selection is done using the AliHFE package
+// 
+// Author:
+//  Raphaelle Bailhache <R.Bailhache@gsi.de>
+//  Markus Fasel <M.Fasel@gsi.de>
+//  Matus Kalisky <matus.kalisky@cern.ch>
+//  MinJung Kweon <minjung@physi.uni-heidelberg.de>
+//
 #include <TAxis.h>
 #include <TCanvas.h>
 #include <TChain.h>
 #include <TString.h>
 #include <TTree.h>
 
+#include "AliAODInputHandler.h"
+#include "AliAODMCParticle.h"
+#include "AliAODTrack.h"
 #include "AliCFContainer.h"
 #include "AliCFManager.h"
-#include "AliCFEffGrid.h"
 #include "AliESDEvent.h"
 #include "AliESDInputHandler.h"
 #include "AliESDtrack.h"
-#include "AliESDtrackCuts.h"
 #include "AliLog.h"
 #include "AliAnalysisManager.h"
 #include "AliMCEvent.h"
 #include "AliMCParticle.h"
 #include "AliPID.h"
 #include "AliStack.h"
+#include "AliVVertex.h"
 
 #include "AliHFEpid.h"
+#include "AliHFEcollection.h"
 #include "AliHFEcuts.h"
 #include "AliHFEmcQA.h"
+#include "AliHFEpairs.h"
+#include "AliHFEpostAnalysis.h"
+#include "AliHFEsecVtxs.h"
 #include "AliHFEsecVtx.h"
+#include "AliHFEelecbackground.h"
+#include "AliHFEtools.h"
 #include "AliAnalysisTaskHFE.h"
 
 //____________________________________________________________
 AliAnalysisTaskHFE::AliAnalysisTaskHFE():
-  AliAnalysisTask("PID efficiency Analysis", "")
+  AliAnalysisTaskSE("PID efficiency Analysis")
   , fQAlevel(0)
   , fPIDdetectors("")
-  , fESD(0x0)
-  , fMC(0x0)
-  , fCFM(0x0)
-  , fCorrelation(0x0)
-  , fPIDperformance(0x0)
-  , fPID(0x0)
-  , fCuts(0x0)
-  , fSecVtx(0x0)
-  , fMCQA(0x0)
-  , fNEvents(0x0)
-  , fNElectronTracksEvent(0x0)
-  , fQA(0x0)
-  , fOutput(0x0)
-  , fHistMCQA(0x0)
-  , fHistSECVTX(0x0)
+  , fPIDstrategy(0)
+  , fPlugins(0)
+  , fCFM(NULL)
+  , fCorrelation(NULL)
+  , fPIDperformance(NULL)
+  , fSignalToBackgroundMC(NULL)
+  , fPID(NULL)
+  , fCuts(NULL)
+  , fSecVtx(NULL)
+  , fElecBackGround(NULL)
+  , fMCQA(NULL)
+  , fNEvents(NULL)
+  , fNElectronTracksEvent(NULL)
+  , fQA(NULL)
+  , fOutput(NULL)
+  , fHistMCQA(NULL)
+  , fHistSECVTX(NULL)
+  , fHistELECBACKGROUND(NULL)
+//  , fQAcoll(0x0)
 {
   //
-  // Default constructor
+  // Dummy constructor
   //
-  DefineInput(0, TChain::Class());
-  DefineOutput(0, TH1I::Class());
-  DefineOutput(1, TList::Class());
+  DefineOutput(1, TH1I::Class());
   DefineOutput(2, TList::Class());
+  DefineOutput(3, TList::Class());
+//  DefineOutput(4, TList::Class());
 
   // Initialize cuts
   fPID = new AliHFEpid;
+}
 
-  SetHasMCData();
+//____________________________________________________________
+AliAnalysisTaskHFE::AliAnalysisTaskHFE(const char * name):
+  AliAnalysisTaskSE(name)
+  , fQAlevel(0)
+  , fPIDdetectors("")
+  , fPIDstrategy(0)
+  , fPlugins(0)
+  , fCFM(NULL)
+  , fCorrelation(NULL)
+  , fPIDperformance(NULL)
+  , fSignalToBackgroundMC(NULL)
+  , fPID(NULL)
+  , fCuts(NULL)
+  , fSecVtx(NULL)
+  , fElecBackGround(NULL)
+  , fMCQA(NULL)
+  , fNEvents(NULL)
+  , fNElectronTracksEvent(NULL)
+  , fQA(NULL)
+  , fOutput(NULL)
+  , fHistMCQA(NULL)
+  , fHistSECVTX(NULL)
+  , fHistELECBACKGROUND(NULL)
+//  , fQAcoll(0x0)
+{
+  //
+  // Default constructor
+  // 
+  DefineOutput(1, TH1I::Class());
+  DefineOutput(2, TList::Class());
+  DefineOutput(3, TList::Class());
+//  DefineOutput(4, TList::Class());
+
+  // Initialize cuts
+  fPID = new AliHFEpid;
 }
 
 //____________________________________________________________
 AliAnalysisTaskHFE::AliAnalysisTaskHFE(const AliAnalysisTaskHFE &ref):
-  AliAnalysisTask(ref)
+  AliAnalysisTaskSE(ref)
   , fQAlevel(ref.fQAlevel)
   , fPIDdetectors(ref.fPIDdetectors)
-  , fESD(ref.fESD)
-  , fMC(ref.fMC)
+  , fPIDstrategy(ref.fPIDstrategy)
+  , fPlugins(ref.fPlugins)
   , fCFM(ref.fCFM)
   , fCorrelation(ref.fCorrelation)
   , fPIDperformance(ref.fPIDperformance)
+  , fSignalToBackgroundMC(ref.fSignalToBackgroundMC)
   , fPID(ref.fPID)
   , fCuts(ref.fCuts)
   , fSecVtx(ref.fSecVtx)
+  , fElecBackGround(ref.fElecBackGround)
   , fMCQA(ref.fMCQA)
   , fNEvents(ref.fNEvents)
   , fNElectronTracksEvent(ref.fNElectronTracksEvent)
@@ -119,6 +168,8 @@ AliAnalysisTaskHFE::AliAnalysisTaskHFE(const AliAnalysisTaskHFE &ref):
   , fOutput(ref.fOutput)
   , fHistMCQA(ref.fHistMCQA)
   , fHistSECVTX(ref.fHistSECVTX)
+  , fHistELECBACKGROUND(ref.fHistELECBACKGROUND)
+//  , fQAcoll(ref.fQAcoll)
 {
   //
   // Copy Constructor
@@ -134,14 +185,16 @@ AliAnalysisTaskHFE &AliAnalysisTaskHFE::operator=(const AliAnalysisTaskHFE &ref)
   AliAnalysisTask::operator=(ref);
   fQAlevel = ref.fQAlevel;
   fPIDdetectors = ref.fPIDdetectors;
-  fESD = ref.fESD;
-  fMC = ref.fMC;
+  fPIDstrategy = ref.fPIDstrategy;
+  fPlugins = ref.fPlugins;
   fCFM = ref.fCFM;
   fCorrelation = ref.fCorrelation;
   fPIDperformance = ref.fPIDperformance;
+  fSignalToBackgroundMC = ref.fSignalToBackgroundMC;
   fPID = ref.fPID;
   fCuts = ref.fCuts;
   fSecVtx = ref.fSecVtx;
+  fElecBackGround = ref.fElecBackGround;
   fMCQA = ref.fMCQA;
   fNEvents = ref.fNEvents;
   fNElectronTracksEvent = ref.fNElectronTracksEvent;
@@ -149,6 +202,9 @@ AliAnalysisTaskHFE &AliAnalysisTaskHFE::operator=(const AliAnalysisTaskHFE &ref)
   fOutput = ref.fOutput;
   fHistMCQA = ref.fHistMCQA;
   fHistSECVTX = ref.fHistSECVTX;
+  fHistELECBACKGROUND = ref.fHistELECBACKGROUND;
+  
+//  fQAcoll = ref.fQAcoll;
   return *this;
 }
 
@@ -157,8 +213,6 @@ AliAnalysisTaskHFE::~AliAnalysisTaskHFE(){
   //
   // Destructor
   //
-  if(fESD) delete fESD;
-  if(fMC) delete fMC;
   if(fPID) delete fPID;
   if(fQA){
     fQA->Clear();
@@ -176,7 +230,12 @@ AliAnalysisTaskHFE::~AliAnalysisTaskHFE(){
     fHistSECVTX->Clear();
     delete fHistSECVTX;
   }
+  if(fHistELECBACKGROUND){
+    fHistELECBACKGROUND->Clear();
+    delete fHistELECBACKGROUND;
+  }
   if(fSecVtx) delete fSecVtx;
+  if(fElecBackGround) delete fElecBackGround;
   if(fMCQA) delete fMCQA;
   if(fNEvents) delete fNEvents;
   if(fCorrelation){
@@ -184,36 +243,40 @@ AliAnalysisTaskHFE::~AliAnalysisTaskHFE(){
     delete fCorrelation;
   }
   if(fPIDperformance) delete fPIDperformance;
+  if(fSignalToBackgroundMC) delete fSignalToBackgroundMC;
+//  if(fQAcoll) delete fQAcoll;
 }
 
 //____________________________________________________________
-void AliAnalysisTaskHFE::ConnectInputData(Option_t *){
-/*  TTree *esdchain = dynamic_cast<TChain *>(GetInputData(0));
-  if(!esdchain){
-    AliError("ESD chain empty");
-    return;
-  } else {
-    esdchain->SetBranchStatus("Tracks", 1);
-  }
-*/
-  AliESDInputHandler *esdH = dynamic_cast<AliESDInputHandler *>(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler());
-  if(!esdH){      
-    AliError("No ESD input handler");
-    return;
-  } else {
-    fESD = esdH->GetEvent();
-  }
-  AliMCEventHandler *mcH = dynamic_cast<AliMCEventHandler *>(AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler());
-  if(!mcH){       
-    AliError("No MC truth handler");
-    return;
+void AliAnalysisTaskHFE::UserCreateOutputObjects(){
+  //
+  // Creating output container and output objects
+  // Here we also Initialize the correction framework container and 
+  // the objects for
+  // - PID
+  // - MC QA
+  // - SecVtx
+  // QA histograms are created if requested
+  // Called once per worker
+  //
+  AliDebug(3, "Creating Output Objects");
+  // Automatic determination of the analysis mode
+  AliVEventHandler *inputHandler = AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler();
+  if(!TString(inputHandler->IsA()->GetName()).CompareTo("AliAODInputHandler")){
+    SetAODAnalysis();
   } else {
-    fMC = mcH->MCEvent();
+    SetESDAnalysis();
+    if(AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler())
+      SetHasMCData();
   }
-}
+  printf("Analysis Mode: %s Analysis\n", IsAODanalysis() ? "AOD" : "ESD");
+  printf("MC Data available %s\n", HasMCData() ? "Yes" : "No");
+
+  // example how to use the AliHFEcollection
+  //fQAcoll = new AliHFEcollection("fQAcoll", "QA");
+  //fQAcoll->CreateTH1F("fNevents", "Number of Events in the Analysis", 2, 0, 2);
+  //fQAcoll->CreateProfile("fNtrdclusters", "Number of TRD clusters as function of momentum; p[GeV/c]", 20, 0, 20);
 
-//____________________________________________________________
-void AliAnalysisTaskHFE::CreateOutputObjects(){
   fNEvents = new TH1I("nEvents", "Number of Events in the Analysis", 2, 0, 2); // Number of Events neccessary for the analysis and not a QA histogram
   fNElectronTracksEvent = new TH1I("nElectronTracksEvent", "Number of Electron Candidates", 100, 0, 100);
   // First Step: TRD alone
@@ -225,27 +288,32 @@ void AliAnalysisTaskHFE::CreateOutputObjects(){
   fQA->AddAt(new TProfile("pidquality", "TRD PID quality as function of momentum", 20, 0, 20), 4);
   fQA->AddAt(new TProfile("ntrdclusters", "Number of TRD clusters as function of momentum", 20, 0, 20), 5);
   fQA->AddAt(new TH1F("chi2TRD","#chi2 per TRD cluster", 20, 0, 20), 6);
+  fQA->AddAt(new TH1I("mccharge", "MC Charge", 200, -100, 100), 7);
 
   if(!fOutput) fOutput = new TList;
   // Initialize correction Framework and Cuts
   fCFM = new AliCFManager;
   MakeParticleContainer();
-  // Temporary fix: Initialize particle cuts with 0x0
+  MakeEventContainer();
+  // Temporary fix: Initialize particle cuts with NULL
   for(Int_t istep = 0; istep < fCFM->GetParticleContainer()->GetNStep(); istep++)
-    fCFM->SetParticleCutsList(istep, 0x0);
-  if(fCuts){
-    fCuts->Initialize(fCFM);
-    if(fCuts->IsInDebugMode()){
-      fQA->Add(fCuts->GetQAhistograms());
-    }
-  } else {
-    AliError("Cuts not available. Output will be meaningless");
+    fCFM->SetParticleCutsList(istep, NULL);
+  if(!fCuts){
+    AliWarning("Cuts not available. Default cuts will be used");
+    fCuts = new AliHFEcuts;
+    fCuts->CreateStandardCuts();
   }
+  if(IsAODanalysis()) fCuts->SetAOD();
+  fCuts->Initialize(fCFM);
+  if(fCuts->IsInDebugMode()) fQA->Add(fCuts->GetQAhistograms());
   // add output objects to the List
   fOutput->AddAt(fCFM->GetParticleContainer(), 0);
-  fOutput->AddAt(fCorrelation, 1);
-  fOutput->AddAt(fPIDperformance, 2);
-  fOutput->AddAt(fNElectronTracksEvent, 3);
+  fOutput->AddAt(fCFM->GetEventContainer(), 1);
+  fOutput->AddAt(fCorrelation, 2);
+  fOutput->AddAt(fPIDperformance, 3);
+  fOutput->AddAt(fSignalToBackgroundMC, 4);
+  fOutput->AddAt(fNElectronTracksEvent, 5);
 
   // Initialize PID
   if(IsQAOn(kPIDqa)){
@@ -255,11 +323,14 @@ void AliAnalysisTaskHFE::CreateOutputObjects(){
     fQA->Add(fPID->GetQAhistograms());
   }
   fPID->SetHasMCData(HasMCData());
-  if(!fPIDdetectors.Length()) AddPIDdetector("TPC");
-  fPID->InitializePID(fPIDdetectors.Data());     // Only restrictions to TPC allowed 
+  if(!fPIDdetectors.Length() && ! fPIDstrategy) AddPIDdetector("TPC");
+  if(fPIDstrategy)
+    fPID->InitializePID(Form("Strategy%d", fPIDstrategy));
+  else
+    fPID->InitializePID(fPIDdetectors.Data());     // Only restrictions to TPC allowed 
 
   // mcQA----------------------------------
-  if (IsQAOn(kMCqa)) {
+  if (HasMCData() && IsQAOn(kMCqa)) {
     AliInfo("MC QA on");
     if(!fMCQA) fMCQA = new AliHFEmcQA;
     if(!fHistMCQA) fHistMCQA = new TList();
@@ -268,8 +339,12 @@ void AliAnalysisTaskHFE::CreateOutputObjects(){
     fMCQA->CreateHistograms(AliHFEmcQA::kBeauty,0,"mcqa_");              // create histograms for beauty
     fMCQA->CreateHistograms(AliHFEmcQA::kCharm,1,"mcqa_barrel_");        // create histograms for charm 
     fMCQA->CreateHistograms(AliHFEmcQA::kBeauty,1,"mcqa_barrel_");       // create histograms for beauty
-    fMCQA->CreateHistograms(AliHFEmcQA::kCharm,2,"mcqa_unitY_");        // create histograms for charm 
-    fMCQA->CreateHistograms(AliHFEmcQA::kBeauty,2,"mcqa_unitY_");       // create histograms for beauty
+    fMCQA->CreateHistograms(AliHFEmcQA::kCharm,2,"mcqa_unitY_");         // create histograms for charm 
+    fMCQA->CreateHistograms(AliHFEmcQA::kBeauty,2,"mcqa_unitY_");        // create histograms for beauty
+    fMCQA->CreateHistograms(AliHFEmcQA::kCharm,3,"mcqa_reccut_");        // create histograms for charm 
+    fMCQA->CreateHistograms(AliHFEmcQA::kBeauty,3,"mcqa_reccut_");       // create histograms for beauty
+    fMCQA->CreateHistograms(AliHFEmcQA::kCharm,4,"mcqa_recpidcut_");     // create histograms for charm 
+    fMCQA->CreateHistograms(AliHFEmcQA::kBeauty,4,"mcqa_recpidcut_");    // create histograms for beauty
     TIter next(gDirectory->GetList());
     TObject *obj;
     int counter = 0;
@@ -286,124 +361,200 @@ void AliAnalysisTaskHFE::CreateOutputObjects(){
   } 
 
   // secvtx----------------------------------
-  if (IsSecVtxOn()) {
+  if (GetPlugin(kSecVtx)) {
     AliInfo("Secondary Vertex Analysis on");
     fSecVtx = new AliHFEsecVtx;
+    fSecVtx->SetHasMCData(HasMCData());
 
     if(!fHistSECVTX) fHistSECVTX = new TList();
-    fHistSECVTX->SetName("SecVtx");
-    fSecVtx->CreateHistograms("secvtx_");
-    TIter next(gDirectory->GetList());
-    TObject *obj;
-    int counter = 0;
-    TString objname;
-    while ((obj = next.Next())) {
-      objname = obj->GetName();
-      TObjArray *toks = objname.Tokenize("_");
-      if (toks->GetEntriesFast()){
-        TObjString *fpart = (TObjString *)(toks->UncheckedAt(0));
-        if ((fpart->String()).CompareTo("secvtx") == 0) fHistSECVTX->AddAt(obj, counter++);
-      }
-    }
+    fSecVtx->CreateHistograms(fHistSECVTX);
     fOutput->Add(fHistSECVTX);
-  } 
+  }
+  
+  // background----------------------------------
+  if (GetPlugin(kIsElecBackGround)) {
+    AliInfo("Electron BackGround Analysis on");
+    if(!fElecBackGround){
+      AliWarning("ElecBackGround not available. Default elecbackground will be used");
+      fElecBackGround = new AliHFEelecbackground;
+    }
+    fElecBackGround->SetHasMCData(HasMCData());
+
+    if(!fHistELECBACKGROUND) fHistELECBACKGROUND = new TList();
+    fElecBackGround->CreateHistograms(fHistELECBACKGROUND);
+    fOutput->Add(fHistELECBACKGROUND);
+  }  
 }
 
 //____________________________________________________________
-void AliAnalysisTaskHFE::Exec(Option_t *){
+void AliAnalysisTaskHFE::UserExec(Option_t *){
   //
   // Run the analysis
   // 
-  if(!fESD){
-    AliError("No ESD Event");
+  AliDebug(3, "Starting Single Event Analysis");
+  if(!fInputEvent){
+    AliError("Reconstructed Event not available");
     return;
   }
-  if(!fMC){
-    AliError("No MC Event");
-    return;
+  if(HasMCData()){
+    AliDebug(4, Form("MC Event: %p", fMCEvent));
+    if(!fMCEvent){
+      AliError("No MC Event, but MC Data required");
+      return;
+    }
   }
   if(!fCuts){
     AliError("HFE cuts not available");
     return;
   }
-  fCFM->SetEventInfo(fMC);
 
-  //fCFM->CheckEventCuts(AliCFManager::kEvtGenCuts, fMC);
-  Double_t container[6];
-  // container for the output THnSparse
-  Double_t dataE[5]; // [pT, eta, Phi, type, 'C' or 'B']
-
-  // Loop over the Monte Carlo tracks to see whether we have overlooked any track
-  AliMCParticle *mctrack = 0x0;
-  Int_t nElectrons = 0;
+  if(HasMCData()) ProcessMC();  // Run the MC loop + MC QA in case MC Data are available
 
-  if (IsSecVtxOn()) { 
-    fSecVtx->SetEvent(fESD);
-    fSecVtx->SetStack(fMC->Stack());
-  }
+  if(IsAODanalysis()) ProcessAOD();
+  else ProcessESD();
+  // Done!!!
+  PostData(1, fNEvents);
+  PostData(2, fOutput);
+  PostData(3, fQA);
+//  PostData(4, fQAcoll->GetList());
+}
 
-  // run mc QA ------------------------------------------------
-  if (IsQAOn(kMCqa)) {
-    AliDebug(2, "Running MC QA");
-
-    fMCQA->SetStack(fMC->Stack());
-    fMCQA->Init();
-
-    Int_t nMCTracks = fMC->Stack()->GetNtrack();
-
-    // loop over all tracks for decayed electrons
-    for (Int_t igen = 0; igen < nMCTracks; igen++){
-      TParticle* mcpart = fMC->Stack()->Particle(igen);
-      fMCQA->GetQuarkKine(mcpart, igen, AliHFEmcQA::kCharm);
-      fMCQA->GetQuarkKine(mcpart, igen, AliHFEmcQA::kBeauty);
-      fMCQA->GetHadronKine(mcpart, AliHFEmcQA::kCharm);
-      fMCQA->GetHadronKine(mcpart, AliHFEmcQA::kBeauty);
-      fMCQA->GetDecayedKine(mcpart, AliHFEmcQA::kCharm,  AliHFEmcQA::kElectronPDG, 0); // no accept cut
-      fMCQA->GetDecayedKine(mcpart, AliHFEmcQA::kBeauty, AliHFEmcQA::kElectronPDG, 0); // no accept cut
-      if (TMath::Abs(mcpart->Eta()) < 0.9) {
-        fMCQA->GetDecayedKine(mcpart, AliHFEmcQA::kCharm,  AliHFEmcQA::kElectronPDG, 1); // accept |eta|<0.9
-        fMCQA->GetDecayedKine(mcpart, AliHFEmcQA::kBeauty, AliHFEmcQA::kElectronPDG, 1); // accept |eta|<0.9
-      }
-      if (TMath::Abs(GetRapidity(mcpart)) < 0.5) {
-        fMCQA->GetDecayedKine(mcpart, AliHFEmcQA::kCharm,  AliHFEmcQA::kElectronPDG, 2); // accept |y|<0.5
-        fMCQA->GetDecayedKine(mcpart, AliHFEmcQA::kBeauty, AliHFEmcQA::kElectronPDG, 2); // accept |y|<0.5
+//____________________________________________________________
+void AliAnalysisTaskHFE::Terminate(Option_t *){
+  //
+  // Terminate not implemented at the moment
+  //
+  if(GetPlugin(kPostProcess)){
+    fOutput = dynamic_cast<TList *>(GetOutputData(2));
+    if(!fOutput){
+      AliError("Results not available");
+      return;
+    }
+    AliHFEpostAnalysis postanalysis;
+    postanalysis.SetResults(fOutput);
+    if(HasMCData())postanalysis.DrawMCSignal2Background();
+    postanalysis.DrawEfficiency();
+    postanalysis.DrawPIDperformance();
+    postanalysis.DrawCutEfficiency();
+
+    if (GetPlugin(kIsElecBackGround)) {
+      AliHFEelecbackground elecBackGround;
+      TList *oe = 0x0;
+      if(!(oe = (TList*)dynamic_cast<TList *>(fOutput->FindObject("HFEelecbackground")))){
+       return;
       }
+      elecBackGround.Load(oe);
+      elecBackGround.Plot();
+      elecBackGround.PostProcess();      
     }
-    fMCQA->EndOfEventAna(AliHFEmcQA::kCharm);
-    fMCQA->EndOfEventAna(AliHFEmcQA::kBeauty);
-
-  } // end of MC QA loop
-  // -----------------------------------------------------------------
+  }
+}
 
+//____________________________________________________________
+void AliAnalysisTaskHFE::ProcessMC(){
   //
-  // Loop MC
+  // Runs the MC Loop (filling the container for the MC Cut Steps with the observables pt, eta and phi)
+  // In case MC QA is on also MC QA loop is done
   //
-  for(Int_t imc = fMC->GetNumberOfTracks(); imc--;){
-    mctrack = dynamic_cast<AliMCParticle *>(fMC->GetTrack(imc));
-
-    container[0] = mctrack->Pt();
-    container[1] = mctrack->Eta();
-    container[2] = mctrack->Phi();
+  AliDebug(3, "Processing MC Information");
+  Double_t nContrib = 0;
+  const AliVVertex *pVertex = fMCEvent->GetPrimaryVertex();
+  if(pVertex) nContrib = pVertex->GetNContributors();
+  if(!fCFM->CheckEventCuts(AliHFEcuts::kEventStepGenerated, fMCEvent)) return;
+  fCFM->GetEventContainer()->Fill(&nContrib,AliHFEcuts::kEventStepGenerated);
+  Int_t nElectrons = 0;
+  if(IsESDanalysis()){
+    if (HasMCData() && IsQAOn(kMCqa)) {
+      AliDebug(2, "Running MC QA");
+
+      if(fMCEvent->Stack()){
+        fMCQA->SetStack(fMCEvent->Stack());
+        fMCQA->SetGenEventHeader(fMCEvent->GenEventHeader());
+        fMCQA->Init();
+
+        Int_t nMCTracks = fMCEvent->Stack()->GetNtrack();
+
+        // loop over all tracks for decayed electrons
+        for (Int_t igen = 0; igen < nMCTracks; igen++){
+          TParticle* mcpart = fMCEvent->Stack()->Particle(igen);
+          fMCQA->GetQuarkKine(mcpart, igen, AliHFEmcQA::kCharm);
+          fMCQA->GetQuarkKine(mcpart, igen, AliHFEmcQA::kBeauty);
+          fMCQA->GetHadronKine(mcpart, AliHFEmcQA::kCharm);
+          fMCQA->GetHadronKine(mcpart, AliHFEmcQA::kBeauty);
+          fMCQA->GetDecayedKine(mcpart, AliHFEmcQA::kCharm,  AliHFEmcQA::kElectronPDG, 0); // no accept cut
+          fMCQA->GetDecayedKine(mcpart, AliHFEmcQA::kBeauty, AliHFEmcQA::kElectronPDG, 0); // no accept cut
+          if (TMath::Abs(mcpart->Eta()) < 0.9) {
+            fMCQA->GetDecayedKine(mcpart, AliHFEmcQA::kCharm,  AliHFEmcQA::kElectronPDG, 1); // accept |eta|<0.9
+            fMCQA->GetDecayedKine(mcpart, AliHFEmcQA::kBeauty, AliHFEmcQA::kElectronPDG, 1); // accept |eta|<0.9
+          }
+          if (TMath::Abs(AliHFEtools::GetRapidity(mcpart)) < 0.5) {
+            fMCQA->GetDecayedKine(mcpart, AliHFEmcQA::kCharm,  AliHFEmcQA::kElectronPDG, 2); // accept |y|<0.5
+            fMCQA->GetDecayedKine(mcpart, AliHFEmcQA::kBeauty, AliHFEmcQA::kElectronPDG, 2); // accept |y|<0.5
+          }
+        }
+        fMCQA->EndOfEventAna(AliHFEmcQA::kCharm);
+        fMCQA->EndOfEventAna(AliHFEmcQA::kBeauty);
+      }
 
-    if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepMCGenerated, mctrack)) continue;
-    fCFM->GetParticleContainer()->Fill(container, AliHFEcuts::kStepMCGenerated);
-    if(IsSignalElectron(mctrack)) fCFM->GetParticleContainer()->Fill(container, AliHFEcuts::kStepMCsignal);
-    (dynamic_cast<TH1F *>(fQA->At(2)))->Fill(mctrack->Phi() - TMath::Pi());
-    if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepMCInAcceptance, mctrack)) continue;
-    // find the label in the vector
-    fCFM->GetParticleContainer()->Fill(container, AliHFEcuts::kStepMCInAcceptance);
-    nElectrons++;
+    } // end of MC QA loop
+    // -----------------------------------------------------------------
+    fCFM->SetMCEventInfo(fMCEvent);
+    // fCFM->CheckEventCuts(AliCFManager::kEvtRecCuts, fESD);
+  } else {
+    fCFM->SetMCEventInfo(fInputEvent);
+  }
+  // Run MC loop
+  AliVParticle *mctrack = NULL;
+  for(Int_t imc = 0; imc <fMCEvent->GetNumberOfTracks(); imc++){
+    if(!(mctrack = fMCEvent->GetTrack(imc))) continue;
+    if(ProcessMCtrack(mctrack)) nElectrons++;
   }
-  (dynamic_cast<TH1F *>(fQA->At(3)))->Fill(nElectrons);
 
   // fCFM->CheckEventCuts(AliCFManager::kEvtRecCuts, fESD);
-        
+  (dynamic_cast<TH1F *>(fQA->At(3)))->Fill(nElectrons);
+}
 
+//____________________________________________________________
+void AliAnalysisTaskHFE::ProcessESD(){
   //
-  // Loop ESD
+  // Run Analysis of reconstructed event in ESD Mode
+  // Loop over Tracks, filter according cut steps defined in AliHFEcuts
   //
+  AliDebug(3, "Processing ESD Event");
+  Double_t nContrib = fInputEvent->GetPrimaryVertex()->GetNContributors();
+  if(!fCFM->CheckEventCuts(AliHFEcuts::kEventStepReconstructed, fInputEvent)) return;
+  fCFM->GetEventContainer()->Fill(&nContrib, AliHFEcuts::kEventStepReconstructed);
+  AliESDEvent *fESD = dynamic_cast<AliESDEvent *>(fInputEvent);
+  if(!fESD){
+    AliError("ESD Event required for ESD Analysis")
+    return;
+  }
+  if (GetPlugin(kIsElecBackGround)) { 
+    fElecBackGround->SetEvent(fESD);
+  }
+  if (GetPlugin(kSecVtx)) {
+    fSecVtx->SetEvent(fESD);
+    fSecVtx->GetPrimaryCondition();
+  }
+
+  if(HasMCData()){
+    if (GetPlugin(kSecVtx)) { 
+      if(fMCEvent->Stack()) fSecVtx->SetStack(fMCEvent->Stack());
+    }
+    if (GetPlugin(kIsElecBackGround)) { 
+      fElecBackGround->SetMCEvent(fMCEvent);
+    }
+  }
+
+
+  Double_t container[8];
+  memset(container, 0, sizeof(Double_t) * 8);
+  // container for the output THnSparse
+  Double_t dataE[5]; // [pT, eta, Phi, type, 'C' or 'B']
   Int_t nElectronCandidates = 0;
-  AliESDtrack *track = 0x0, *htrack = 0x0;
+  AliESDtrack *track = NULL, *htrack = NULL;
+  AliMCParticle *mctrack = NULL;
+  TParticle* mctrack4QA = NULL;
   Int_t pid = 0;
   // For double counted tracks
   LabelContainer cont(fESD->GetNumberOfTracks());
@@ -411,6 +562,18 @@ void AliAnalysisTaskHFE::Exec(Option_t *){
 
   Bool_t signal = kTRUE;
 
+  fCFM->SetRecEventInfo(fESD);
+  // Electron background analysis 
+  if (GetPlugin(kIsElecBackGround)) {
+    
+    AliDebug(2, "Running BackGround Analysis");
+    
+    fElecBackGround->Reset();
+    
+  } // end of electron background analysis
+  //
+  // Loop ESD
+  //
   for(Int_t itrack = 0; itrack < fESD->GetNumberOfTracks(); itrack++){
     
     track = fESD->GetTrack(itrack);
@@ -418,80 +581,74 @@ void AliAnalysisTaskHFE::Exec(Option_t *){
     container[0] = track->Pt();
     container[1] = track->Eta();
     container[2] = track->Phi();
+    container[3] = track->Charge();
 
     dataE[0] = track->Pt();
     dataE[1] = track->Eta();
     dataE[2] = track->Phi();
-    dataE[3] = -1;
+    dataE[3] = track->Charge();
     dataE[4] = -1;
+    dataE[5] = -1;
 
     signal = kTRUE;
-          
-    // RecKine: ITSTPC cuts  
-    if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepRecKineITSTPC, track)) continue;
-    
-    // Check if it is electrons near the vertex
-    if(!(mctrack = dynamic_cast<AliMCParticle *>(fMC->GetTrack(TMath::Abs(track->GetLabel()))))) continue;
 
-    container[3] = mctrack->Pt();
-    container[4] = mctrack->Eta();
-    container[5] = mctrack->Phi();
-    
-    if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepMCGenerated, mctrack)) signal = kFALSE;
+    // Fill step without any cut
+          
+    if(HasMCData()){
+      // Check if it is electrons near the vertex
+      if(!(mctrack = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(TMath::Abs(track->GetLabel()))))) continue;
+      mctrack4QA = mctrack->Particle();//fMCEvent->Stack()->Particle(TMath::Abs(track->GetLabel()));
+
+      container[4] = mctrack->Pt();
+      container[5] = mctrack->Eta();
+      container[6] = mctrack->Phi();
+      container[7] = mctrack->Charge()/3.;
     
+      if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepMCGenerated, mctrack)) signal = kFALSE;
+    }
     if(signal) {
       alreadyseen = cont.Find(TMath::Abs(track->GetLabel()));
       cont.Append(TMath::Abs(track->GetLabel()));
       
-      fCFM->GetParticleContainer()->Fill(&container[3], AliHFEcuts::kStepRecKineITSTPC);
-      fCFM->GetParticleContainer()->Fill(&container[0], (AliHFEcuts::kStepRecKineITSTPC + 2*(AliHFEcuts::kNcutESDSteps + 1)));
+      fCFM->GetParticleContainer()->Fill(&container[4], AliHFEcuts::kStepRecNoCut);
+      fCFM->GetParticleContainer()->Fill(&container[0], AliHFEcuts::kStepRecNoCut + 2*AliHFEcuts::kNcutStepsESDtrack);
       if(alreadyseen) {
-        fCFM->GetParticleContainer()->Fill(&container[3], (AliHFEcuts::kStepRecKineITSTPC + (AliHFEcuts::kNcutESDSteps + 1)));
+        fCFM->GetParticleContainer()->Fill(&container[4], AliHFEcuts::kStepRecNoCut + AliHFEcuts::kNcutStepsESDtrack);
       }
     }
 
+    // RecKine: ITSTPC cuts  
+    if(!ProcessCutStep(AliHFEcuts::kStepRecKineITSTPC, track, container, signal, alreadyseen)) continue;
+    
     // Check TRD criterions (outside the correction framework)
     if(track->GetTRDncls()){
       (dynamic_cast<TH1F *>(fQA->At(6)))->Fill(track->GetTRDchi2()/track->GetTRDncls());
       (dynamic_cast<TH1F *>(fQA->At(1)))->Fill(track->GetAlpha());    // Check the acceptance without tight cuts
       (dynamic_cast<TProfile *>(fQA->At(4)))->Fill(container[0], track->GetTRDpidQuality());
       (dynamic_cast<TProfile *>(fQA->At(5)))->Fill(container[0], track->GetTRDncls());
+      //fQAcoll->Fill("fNtrdclusters", container[0], track->GetTRDncls());
     }
 
     
     // RecPrim
-    if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepRecPrim, track)) continue;
-    if(signal) {
-      fCFM->GetParticleContainer()->Fill(container, AliHFEcuts::kStepRecPrim + 2*(AliHFEcuts::kNcutESDSteps + 1));
-      fCFM->GetParticleContainer()->Fill(&container[3], AliHFEcuts::kStepRecPrim);
-      if(alreadyseen) {
-        fCFM->GetParticleContainer()->Fill(&container[3], AliHFEcuts::kStepRecPrim + AliHFEcuts::kNcutESDSteps + 1);
-      }
-    }
-
+    if(!ProcessCutStep(AliHFEcuts::kStepRecPrim, track, container, signal, alreadyseen)) continue;
 
     // HFEcuts: ITS layers cuts
-    if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepHFEcutsITS, track)) continue;
-    if(signal) {
-      fCFM->GetParticleContainer()->Fill(container, AliHFEcuts::kStepHFEcutsITS + 2*(AliHFEcuts::kNcutESDSteps + 1));
-      fCFM->GetParticleContainer()->Fill(&container[3], AliHFEcuts::kStepHFEcutsITS);
-      if(alreadyseen) {
-        fCFM->GetParticleContainer()->Fill(&container[3], AliHFEcuts::kStepHFEcutsITS + AliHFEcuts::kNcutESDSteps + 1);
-      }
-    }
+    if(!ProcessCutStep(AliHFEcuts::kStepHFEcutsITS, track, container, signal, alreadyseen)) continue;
 
     // HFEcuts: Nb of tracklets TRD0
-    if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepHFEcutsTRD, track)) continue;
+    if(!ProcessCutStep(AliHFEcuts::kStepHFEcutsTRD, track, container, signal, alreadyseen)) continue;
     if(signal) {
-      fCFM->GetParticleContainer()->Fill(container, AliHFEcuts::kStepHFEcutsTRD + 2*(AliHFEcuts::kNcutESDSteps + 1));
-      fCFM->GetParticleContainer()->Fill(&container[3], AliHFEcuts::kStepHFEcutsTRD);
-      if(alreadyseen) {
-        fCFM->GetParticleContainer()->Fill(&container[3], (AliHFEcuts::kStepHFEcutsTRD + (AliHFEcuts::kNcutESDSteps + 1)));
-      }
       // dimensions 3&4&5 : pt,eta,phi (MC)
       ((THnSparseF *)fCorrelation->At(0))->Fill(container);
     }
 
+    if(HasMCData() && IsQAOn(kMCqa)) {
+      // mc qa for after the reconstruction cuts  
+      AliDebug(2, "Running MC QA");
+      fMCQA->GetDecayedKine(mctrack4QA, AliHFEmcQA::kCharm,  AliHFEmcQA::kElectronPDG, 3);  // charm
+      fMCQA->GetDecayedKine(mctrack4QA, AliHFEmcQA::kBeauty,  AliHFEmcQA::kElectronPDG, 3); // beauty 
+    } 
 
     // track accepted, do PID
     AliHFEpidObject hfetrack;
@@ -501,307 +658,266 @@ void AliAnalysisTaskHFE::Exec(Option_t *){
     if(!fPID->IsSelected(&hfetrack)) continue;
     nElectronCandidates++;
 
+    if (HasMCData() && IsQAOn(kMCqa)) {
+      // mc qa for after the reconstruction and pid cuts  
+      AliDebug(2, "Running MC QA");
+      fMCQA->GetDecayedKine(mctrack4QA, AliHFEmcQA::kCharm,  AliHFEmcQA::kElectronPDG, 4);  // charm
+      fMCQA->GetDecayedKine(mctrack4QA, AliHFEmcQA::kBeauty,  AliHFEmcQA::kElectronPDG, 4); // beauty 
+    } 
 
     // Fill Containers
     if(signal) {
-      fCFM->GetParticleContainer()->Fill(container, AliHFEcuts::kStepHFEcutsTRD +1 + 2*(AliHFEcuts::kNcutESDSteps + 1));
-      fCFM->GetParticleContainer()->Fill(&container[3], AliHFEcuts::kStepHFEcutsTRD + 1);
+      fCFM->GetParticleContainer()->Fill(container, AliHFEcuts::kStepPID + 2*AliHFEcuts::kNcutStepsESDtrack);
+      fCFM->GetParticleContainer()->Fill(&container[4], AliHFEcuts::kStepPID);
       if(alreadyseen) {
-        fCFM->GetParticleContainer()->Fill(&container[3], (AliHFEcuts::kStepHFEcutsTRD + 1 + (AliHFEcuts::kNcutESDSteps + 1)));
+        fCFM->GetParticleContainer()->Fill(&container[4], (AliHFEcuts::kStepPID + (AliHFEcuts::kNcutStepsESDtrack)));
       }
       // dimensions 3&4&5 : pt,eta,phi (MC)
       ((THnSparseF *)fCorrelation->At(1))->Fill(container);
     }
 
-    // Track selected: distinguish between true and fake
-    AliDebug(1, Form("Candidate Selected, filling THnSparse, PID: %d\n", mctrack->Particle()->GetPdgCode()));
-    if((pid = TMath::Abs(mctrack->Particle()->GetPdgCode())) == 11){
-      Int_t type = IsSignalElectron(track);
-      AliDebug(1, Form("Type: %d\n", type));
-      if(type){
-             dataE[4] = type; // beauty[1] or charm[2]
-             dataE[3] = 2;  // signal electron
-      }
-      else{
-             dataE[3] = 1; // not a signal electron
-             dataE[4] = 0;
-      }
-      // pair analysis [mj]
-      if (IsSecVtxOn()) {
-        AliDebug(2, "Running Secondary Vertex Analysis");
-        fSecVtx->InitAnaPair();
+    if(GetPlugin(kSecVtx) && fMCEvent->Stack()) {
+      AliDebug(2, "Running Secondary Vertex Analysis");
+      if(track->Pt()>1.0){
+        fSecVtx->InitHFEpairs();
+        fSecVtx->InitHFEsecvtxs();
+        AliESDtrack *htrack = 0x0; 
         for(Int_t jtrack = 0; jtrack < fESD->GetNumberOfTracks(); jtrack++){
           htrack = fESD->GetTrack(jtrack);
-          if ( itrack == jtrack ) continue;
-          //if( fPID->IsSelected(htrack) && (itrack < jtrack)) continue;
-          if( abs(fSecVtx->GetMCPID(track)) == 11 && (itrack < jtrack)) continue;
-          fSecVtx->AnaPair(track, htrack, jtrack);
+          if ( itrack == jtrack ) continue; // since it is for tagging single electron, don't need additional condition 
+          if (htrack->Pt()<1.0) continue;
+          if (!fCFM->CheckParticleCuts(AliHFEcuts::kStepRecKineITSTPC, htrack)) continue;
+          if (!fCFM->CheckParticleCuts(AliHFEcuts::kStepRecPrim, htrack)) continue;
+          fSecVtx->PairAnalysis(track, htrack, jtrack); // e-h pairing
         }
-        // based on the partner of e info, you run secandary vertexing function
-        fSecVtx->RunSECVTX(track);
-      } // end of pair analysis
-    } 
-    else {
-      // Fill THnSparse with the information for Fake Electrons
-      dataE[3] = 0;
-      dataE[4] = 0;
+        /*for(int ip=0; ip<fSecVtx->HFEpairs()->GetEntriesFast(); ip++){
+          if(HasMCData()){
+            AliHFEpairs *pair = (AliHFEpairs*) (fSecVtx->HFEpairs()->UncheckedAt(ip));
+            if(!(pair->GetPairCode()>1. && pair->GetPairCode()<4.))  // apply various cuts
+              fSecVtx->HFEpairs()->RemoveAt(ip);
+          }
+        }*/
+        fSecVtx->HFEpairs()->Compress();
+        fSecVtx->RunSECVTX(track); // secondary vertexing with e,h1,h2,.. tracks
+        for(int ip=0; ip<fSecVtx->HFEsecvtxs()->GetEntriesFast(); ip++){
+          AliHFEsecVtxs *secvtx=0x0;
+          secvtx = (AliHFEsecVtxs*) (fSecVtx->HFEsecvtxs()->UncheckedAt(ip));
+          // here you apply cuts, then if it doesn't pass the cut, remove it from the fSecVtx->HFEsecvtxs() 
+        }
+        fSecVtx->DeleteHFEpairs();
+        fSecVtx->DeleteHFEsecvtxs();
+      }
     }
-    // fill the performance THnSparse, if the mc origin could be defined
-    if(dataE[3] > -1){
-      AliDebug(1, Form("Entries: [%.3f|%.3f|%.3f|%f|%f]\n", dataE[0],dataE[1],dataE[2],dataE[3],dataE[4]));
-      fPIDperformance->Fill(dataE);
+
+    if(HasMCData()){
+      // Track selected: distinguish between true and fake
+      AliDebug(1, Form("Candidate Selected, filling THnSparse, PID: %d\n", mctrack->Particle()->GetPdgCode()));
+      if((pid = TMath::Abs(mctrack->Particle()->GetPdgCode())) == 11){
+        Int_t type = IsSignalElectron(track);
+        AliDebug(1, Form("Type: %d\n", type));
+        if(type){
+               dataE[5] = type; // beauty[1] or charm[2]
+               dataE[4] = 2;  // signal electron
+        }
+        else{
+               dataE[4] = 1; // not a signal electron
+               dataE[5] = 0;
+        }
+      } 
+      else {
+        // Fill THnSparse with the information for Fake Electrons
+        dataE[4] = 0;
+        dataE[5] = 0;
+      }
+      // fill the performance THnSparse, if the mc origin could be defined
+      if(dataE[4] > -1){
+        AliDebug(1, Form("Entries: [%.3f|%.3f|%.3f|%f|%f|%f]\n", dataE[0],dataE[1],dataE[2],dataE[3],dataE[4],dataE[5]));
+        fPIDperformance->Fill(dataE);
+      }
     }
+    // Electron background analysis 
+    if (GetPlugin(kIsElecBackGround)) {
+      
+      AliDebug(2, "Running BackGround Analysis");
+      
+      for(Int_t jtrack = 0; jtrack < fESD->GetNumberOfTracks(); jtrack++){
+             htrack = fESD->GetTrack(jtrack);
+       if ( itrack == jtrack ) continue;  
+       fElecBackGround->PairAnalysis(track, htrack); 
+      }
+    } // end of electron background analysis
+
   }
-  
   fNEvents->Fill(1);
+  //fQAcoll->Fill("fNevents", 1);
   fNElectronTracksEvent->Fill(nElectronCandidates);
-  
-  // Done!!!
-  PostData(0, fNEvents);
-  PostData(1, fOutput);
-  PostData(2, fQA);
 }
 
 //____________________________________________________________
-void AliAnalysisTaskHFE::Terminate(Option_t *){
+void AliAnalysisTaskHFE::ProcessAOD(){
   //
-  // Terminate not implemented at the moment
+  // Run Analysis in AOD Mode
+  // Function is still in development
   //
-  if(IsRunningPostProcess()){
-    fOutput = dynamic_cast<TList *>(GetOutputData(1));
-    if(!fOutput){
-      AliError("Results not available");
-      return;
+  AliDebug(3, "Processing AOD Event");
+  Double_t nContrib = fInputEvent->GetPrimaryVertex()->GetNContributors();
+  if(!fCFM->CheckEventCuts(AliHFEcuts::kEventStepReconstructed, fInputEvent)) return;
+  fCFM->GetEventContainer()->Fill(&nContrib,AliHFEcuts::kEventStepReconstructed);
+  AliAODEvent *fAOD = dynamic_cast<AliAODEvent *>(fInputEvent);
+  if(!fAOD){
+    AliError("AOD Event required for AOD Analysis")
+    return;
+  }
+  AliAODTrack *track = NULL;
+  AliAODMCParticle *mctrack = NULL;
+  Double_t container[8]; memset(container, 0, sizeof(Double_t) * 8);
+  Double_t dataE[6]; // [pT, eta, Phi, Charge, type, 'C' or 'B']
+  Int_t nElectronCandidates = 0;
+  Int_t pid;
+  for(Int_t itrack = 0; itrack < fAOD->GetNumberOfTracks(); itrack++){
+    track = fAOD->GetTrack(itrack);
+    if(!track) continue;
+    if(track->GetFlags() != 1<<4) continue;  // Only process AOD tracks where the HFE is set
+
+    container[0] = track->Pt();
+    container[1] = track->Eta();
+    container[2] = track->Phi();
+    container[3] = track->Charge();
+
+    dataE[0] = track->Pt();
+    dataE[1] = track->Eta();
+    dataE[2] = track->Phi();
+    dataE[3] = track->Charge();
+    dataE[4] = -1;
+    dataE[5] = -1;
+    
+    if(HasMCData()){
+      Int_t label = TMath::Abs(track->GetLabel());
+      if(label){
+        mctrack = dynamic_cast<AliAODMCParticle *>(fMCEvent->GetTrack(label));
+        container[4] = mctrack->Pt();
+        container[5] = mctrack->Eta();
+        container[6] = mctrack->Phi();
+        container[7] = mctrack->Charge();
+      }
+    }
+    // track accepted, do PID
+    AliHFEpidObject hfetrack;
+    hfetrack.fAnalysisType = AliHFEpidObject::kAODanalysis;
+    hfetrack.fRecTrack = track;
+    if(HasMCData()) hfetrack.fMCtrack = mctrack;
+    //if(!fPID->IsSelected(&hfetrack)) continue;    // we will do PID here as soon as possible
+    // Particle identified - Fill CF Container
+    fCFM->GetParticleContainer()->Fill(container, AliHFEcuts::kStepPID + 2*AliHFEcuts::kNcutStepsESDtrack);
+    nElectronCandidates++;    
+    if(HasMCData()){
+      // Track selected: distinguish between true and fake
+      AliDebug(1, Form("Candidate Selected, filling THnSparse, PID: %d\n", mctrack->GetPdgCode()));
+      if((pid = TMath::Abs(mctrack->GetPdgCode())) == 11){
+        Int_t type = IsSignalElectron(track);
+        AliDebug(1, Form("Type: %d\n", type));
+        if(type){
+               dataE[5] = type; // beauty[1] or charm[2]
+               dataE[4] = 2;  // signal electron
+        }
+        else{
+               dataE[4] = 1; // not a signal electron
+               dataE[5] = 0;
+        }
+      } 
+      else {
+        // Fill THnSparse with the information for Fake Electrons
+        dataE[4] = 0;
+        dataE[5] = 0;
+      }
+      // fill the performance THnSparse, if the mc origin could be defined
+      if(dataE[4] > -1){
+        AliDebug(1, Form("Entries: [%.3f|%.3f|%.3f|%f|%f|%f]\n", dataE[0],dataE[1],dataE[2],dataE[3],dataE[4],dataE[5]));
+        fPIDperformance->Fill(dataE);
+      }
     }
-    PostProcess();
   }
+  fNEvents->Fill(1);
+  fNElectronTracksEvent->Fill(nElectronCandidates);
 }
 
 //____________________________________________________________
-void AliAnalysisTaskHFE::Load(TString filename){
+Bool_t AliAnalysisTaskHFE::ProcessMCtrack(AliVParticle *track){
   //
-  // Load Results into the task
+  // Filter the Monte Carlo Track
+  // Additionally Fill a THnSparse for Signal To Background Studies
+  // Works for AOD and MC analysis Type
   //
-  fQA = NULL; fOutput = NULL; fNEvents = NULL;
-  TFile *input = TFile::Open(filename.Data());
-  if(!input || input->IsZombie()){
-    AliError("Cannot read file");
-    return;
+  Double_t container[4], signalContainer[6];
+  Double_t vertex[3]; // Production vertex cut to mask gammas which are NOT supposed to have hits in the first ITS layer(s)
+  if(IsESDanalysis()){
+    AliMCParticle *mctrack = dynamic_cast<AliMCParticle *>(track);
+    container[0] = mctrack->Pt();
+    container[1] = mctrack->Eta();
+    container[2] = mctrack->Phi();
+    container[3] = mctrack->Charge()/3;
+
+    signalContainer[0] = mctrack->Pt();
+    signalContainer[1] = mctrack->Eta();
+    signalContainer[2] = mctrack->Phi();
+    signalContainer[3] = mctrack->Charge()/3;
+
+    vertex[0] = mctrack->Particle()->Vx();
+    vertex[1] = mctrack->Particle()->Vy();
+  } else {
+    AliAODMCParticle *aodmctrack = dynamic_cast<AliAODMCParticle *>(track);
+    container[0] = aodmctrack->Pt();
+    container[1] = aodmctrack->Eta();
+    container[2] = aodmctrack->Phi();
+    container[3] = aodmctrack->Charge()/3;
+
+    signalContainer[0] = aodmctrack->Pt();
+    signalContainer[1] = aodmctrack->Eta();
+    signalContainer[2] = aodmctrack->Phi();
+    signalContainer[3] = aodmctrack->Charge()/3;
+
+    aodmctrack->XvYvZv(vertex);
   }
-  TH1 *htmp = dynamic_cast<TH1I *>(input->Get("nEvents"));
-  if(htmp)
-    fNEvents = dynamic_cast<TH1I *>(htmp->Clone());
-  else
-    AliError("Event Counter histogram not found"); 
-  TList *ltmp = dynamic_cast<TList *>(input->Get("Results"));
-  if(ltmp)
-    fOutput = dynamic_cast<TList *>(ltmp->Clone());
-  else
-    AliError("Output Histograms not found");
-  ltmp = dynamic_cast<TList *>(input->Get("QA"));
-  if(ltmp)
-    fQA = dynamic_cast<TList *>(ltmp->Clone());
-  else
-    AliError("QA histograms not found");
-  input->Close();
-  delete input;
-  Int_t nObjects = 0;
-  if(fNEvents) nObjects++;  
-  if(fOutput) nObjects++;
-  if(fQA) nObjects++;
-  AliInfo(Form("Loaded %d Objects into task", nObjects));
+  if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepMCGenerated, track)) return kFALSE;
+  TH1 *test = dynamic_cast<TH1I*>(fQA->FindObject("mccharge"));
+  test->Fill(signalContainer[3]);
+ fCFM->GetParticleContainer()->Fill(container, AliHFEcuts::kStepMCGenerated);
+  if((signalContainer[4] = static_cast<Double_t >(IsSignalElectron(track))) > 1e-3) fCFM->GetParticleContainer()->Fill(container, AliHFEcuts::kStepMCsignal);
+  signalContainer[5] = 0;
+  // apply cut on the sqrt of the production vertex
+  Double_t radVertex = TMath::Sqrt(vertex[0]*vertex[0] + vertex[1] * vertex[1]);
+  if(radVertex < 3.5){
+    // Within first ITS layer(2) -> Background we cannot reject by ITS cut, let it pass
+    signalContainer[5] = 1;
+  } else if (radVertex < 7.5){
+    signalContainer[5] = 2;
+  }
+  fSignalToBackgroundMC->Fill(signalContainer);
+  (dynamic_cast<TH1F *>(fQA->At(2)))->Fill(container[2] - TMath::Pi());
+  //if(IsESDanalysis()){
+    if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepMCInAcceptance, track)) return kFALSE;
+    fCFM->GetParticleContainer()->Fill(container, AliHFEcuts::kStepMCInAcceptance);
+  //}
+  return kTRUE;
 }
 
 //____________________________________________________________
-void AliAnalysisTaskHFE::PostProcess(){
-  //
-  // Plotting Ratio histograms
-  // + All electrons / all candidates (Purity for Electrons)
-  // + All signal electrons / all electrons (Purity for signals)
-  // For this the following pt-histograms have to be projected from the THnSparse
-  // + All Electron candidates
-  // + All Real electrons
-  // + All Signal Electrons
-  // + All misidentified electrons
-  // Additionally we draw Efficiency histograms:
-  // + Reconstructible Electrons
-  // + Signal Electrons
-  // + Selected Electrons
-  // + Selected Electrons in Acceptance
-  //
-
-  fPIDperformance = dynamic_cast<THnSparseF *>(fOutput->FindObject("PIDperformance"));
-  if(!fPIDperformance){
-    AliError("PID Performance histogram not found in the output container");
-    return;
-  }
-  // Make projection
-  // always project to pt dimension
-  // get the histograms under our control
-  TH1 *allCandidates = NULL, *allElectrons = NULL, *allSignals = NULL, *allFakes = NULL;
-  allCandidates = fPIDperformance->Projection(0);
-  allCandidates->SetName("hAllCandidates");
-  allCandidates->SetTitle("All Candidates");
-  allCandidates->Sumw2();
-  Int_t firstDim3 = fPIDperformance->GetAxis(3)->GetFirst(), lastDim3 = fPIDperformance->GetAxis(3)->GetLast();
-  fPIDperformance->GetAxis(3)->SetRange(firstDim3 + 1, lastDim3);
-  allElectrons = fPIDperformance->Projection(0);
-  allElectrons->Sumw2();
-  allElectrons->SetName("hAllElectrons");
-  allElectrons->SetTitle("All Electrons");
-  Int_t firstDim4 = fPIDperformance->GetAxis(4)->GetFirst(), lastDim4 = fPIDperformance->GetAxis(4)->GetLast();
-  fPIDperformance->GetAxis(4)->SetRange(firstDim4 + 1, lastDim4);
-  allSignals = fPIDperformance->Projection(0);
-  allSignals->Sumw2();
-  allSignals->SetName("hAllSignals");
-  allSignals->SetTitle("All Signal Electrons");
-  fPIDperformance->GetAxis(4)->SetRange(firstDim4, lastDim4);       // Reset 4th axis
-  fPIDperformance->GetAxis(3)->SetRange(firstDim3, firstDim3);  // Select fakes
-  allFakes = fPIDperformance->Projection(0);
-  allFakes->Sumw2();
-  allFakes->SetName("hAllFakes");
-  allFakes->SetTitle("All Fakes");
-  fPIDperformance->GetAxis(3)->SetRange(firstDim3, lastDim3);       // Reset also 3rd axis
-
-  // Make Ratios
-  TH1D *electronPurity = dynamic_cast<TH1D *>(allElectrons->Clone());
-  electronPurity->Divide(allCandidates);
-  electronPurity->SetName("electronPurity");
-  electronPurity->SetTitle("Electron Purity");
-  electronPurity->GetXaxis()->SetTitle("p_{T} / GeV/c");
-  electronPurity->GetYaxis()->SetTitle("Purity / %");
-  TH1D *signalPurity = dynamic_cast<TH1D *>(allSignals->Clone());
-  signalPurity->Divide(allElectrons);
-  signalPurity->SetName("signalPurity");
-  signalPurity->SetTitle("Purity of Electrons coming from Heavy flavours");
-  signalPurity->GetXaxis()->SetTitle("p_{T} / GeV/c");
-  signalPurity->GetYaxis()->SetTitle("Purity / %");
-  TH1D *fakeContamination = dynamic_cast<TH1D *>(allFakes->Clone());
-  fakeContamination->Divide(allCandidates);
-  fakeContamination->SetName("fakeContamination");
-  fakeContamination->SetTitle("Contamination of misidentified hadrons");
-  fakeContamination->GetXaxis()->SetTitle("p_{T} / GeV/c");
-  fakeContamination->GetYaxis()->SetTitle("Purity / %");
-
-  // Graphics settings
-  const Int_t nHistos = 7;
-  TH1 *hptr[7] = {allCandidates, allElectrons, allSignals, allFakes, electronPurity, signalPurity, fakeContamination}, *histo;
-  for(Int_t ihist = 0; ihist < nHistos; ihist++){
-    (histo = hptr[ihist])->SetStats(kFALSE);
-    histo->SetLineColor(kBlack);
-    histo->SetMarkerColor(kBlue);
-    histo->SetMarkerStyle(22);
-  }
+void AliAnalysisTaskHFE::MakeEventContainer(){
+  //
+  // Create the event container for the correction framework and link it
+  //
+  const Int_t kNvar = 1;  // number of variables on the grid: number of tracks per event
+  const Double_t kNTrackBound[2] = {-0.5, 200.5};
+  const Int_t kNBins = 201;
 
-  // Make percent output
-  electronPurity->Scale(100);
-  signalPurity->Scale(100);
-  fakeContamination->Scale(100);
-  
-  // Draw output
-  TCanvas *cSpectra = new TCanvas("cSpectra","pt Spectra", 800, 600);
-  cSpectra->Divide(2,2);
-  TCanvas *cRatios = new TCanvas("cRatios", "Ratio Plots", 800, 600);
-  cRatios->Divide(2,2);
-  cSpectra->cd(1);
-  gPad->SetLogy();
-  allCandidates->GetXaxis()->SetTitle("p_{T} / GeV/c");
-  allCandidates->GetYaxis()->SetTitle("dN/dp_{T} 1/GeV/c");
-  allCandidates->Draw("e");
-  cSpectra->cd(2);
-  gPad->SetLogy();
-  allElectrons->GetXaxis()->SetTitle("p_{T} / GeV/c");
-  allElectrons->GetYaxis()->SetTitle("dN/dp_{T} 1/GeV/c");
-  allElectrons->Draw("e");
-  cSpectra->cd(3);
-  gPad->SetLogy();
-  allSignals->GetXaxis()->SetTitle("p_{T} / GeV/c");
-  allSignals->GetYaxis()->SetTitle("dN/dp_{T} 1/GeV/c");
-  allSignals->Draw("e");
-  cSpectra->cd(4);
-  gPad->SetLogy();
-  allFakes->GetXaxis()->SetTitle("p_{T} / GeV/c");
-  allFakes->GetYaxis()->SetTitle("dN/dp_{T} 1/GeV/c");
-  allFakes->Draw("e");
-  cRatios->cd(1);
-  electronPurity->Draw("e");
-  cRatios->cd(2);
-  signalPurity->Draw("e");
-  cRatios->cd(3);
-  fakeContamination->Draw("e");
-
-  // Now draw the Efficiency
-  // We show: 
-  // + InAcceptance / Generated
-  // + Signal / Generated
-  // + Selected / Generated
-  // + Selected / InAcceptance (Reconstructible)
-  TCanvas *cEff = new TCanvas("cEff", "Efficiency", 800, 600);
-  cEff->Divide(2,2);
-  AliCFContainer *effc = dynamic_cast<AliCFContainer *>(fOutput->At(0));
-  if(!effc){
-    AliError("Efficiency Container not found in Output Container");
-    return;
-  }
-  AliCFEffGrid *effCalc = new AliCFEffGrid("effCalc", "Efficiency Calculation Grid", *effc);
-  effCalc->CalculateEfficiency(AliHFEcuts::kStepMCInAcceptance, AliHFEcuts::kStepMCGenerated);
-  TH1 *effReconstructibleP = effCalc->Project(0);
-  effReconstructibleP->SetName("effReconstructibleP");
-  effReconstructibleP->SetTitle("Efficiency of reconstructible tracks");
-  effReconstructibleP->GetXaxis()->SetTitle("p_{T} / GeV/c");
-  effReconstructibleP->GetYaxis()->SetTitle("Efficiency");
-  effReconstructibleP->GetYaxis()->SetRangeUser(0.,1.);
-  effReconstructibleP->SetMarkerStyle(22);
-  effReconstructibleP->SetMarkerColor(kBlue);
-  effReconstructibleP->SetLineColor(kBlack);
-  effReconstructibleP->SetStats(kFALSE);
-  cEff->cd(1);
-  effReconstructibleP->Draw("e");
-  effCalc->CalculateEfficiency(AliHFEcuts::kStepMCsignal, AliHFEcuts::kStepMCGenerated);
-  TH1 *effSignal = effCalc->Project(0);
-  effSignal->SetName("effSignal");
-  effSignal->SetTitle("Efficiency of Signal Electrons");
-  effSignal->GetXaxis()->SetTitle("p_{T} / GeV/c");
-  effSignal->GetYaxis()->SetTitle("Efficiency");
-  effSignal->GetYaxis()->SetRangeUser(0., 1.);
-  effSignal->SetMarkerStyle(22);
-  effSignal->SetMarkerColor(kBlue);
-  effSignal->SetLineColor(kBlack);
-  effSignal->SetStats(kFALSE);
-  cEff->cd(2);
-  effSignal->Draw("e");
-  effCalc->CalculateEfficiency(AliHFEcuts::kStepHFEcutsTRD + 1, AliHFEcuts::kStepMCGenerated);
-  TH1 *effPIDP = effCalc->Project(0);
-  effPIDP->SetName("effPIDP");
-  effPIDP->SetTitle("Efficiency of selected tracks");
-  effPIDP->GetXaxis()->SetTitle("p_{T} / GeV/c");
-  effPIDP->GetYaxis()->SetTitle("Efficiency");
-  effPIDP->GetYaxis()->SetRangeUser(0.,1.);
-  effPIDP->SetMarkerStyle(22);
-  effPIDP->SetMarkerColor(kBlue);
-  effPIDP->SetLineColor(kBlack);
-  effPIDP->SetStats(kFALSE);
-  cEff->cd(3);
-  effPIDP->Draw("e");
-  effCalc->CalculateEfficiency(AliHFEcuts::kStepHFEcutsTRD + 1, AliHFEcuts::kStepMCInAcceptance);
-  TH1 *effPIDAcc = effCalc->Project(0);
-  effPIDAcc->SetName("effPIDAcc");
-  effPIDAcc->SetTitle("Efficiency of selected tracks in acceptance");
-  effPIDAcc->GetXaxis()->SetTitle("p_{T} / GeV/c");
-  effPIDAcc->GetYaxis()->SetTitle("Efficiency");
-  effPIDAcc->GetYaxis()->SetRangeUser(0.,1.);
-  effPIDAcc->SetMarkerStyle(22);
-  effPIDAcc->SetMarkerColor(kBlue);
-  effPIDAcc->SetLineColor(kBlack);
-  effPIDAcc->SetStats(kFALSE);
-  cEff->cd(4);
-  effPIDAcc->Draw("e");
-  delete effCalc;
-
-  // cleanup
-  //delete allCandidates; delete allElectrons; delete allSignals; delete allFakes;
-  //delete electronPurity; delete signalPurity; delete fakeContamination;
+  AliCFContainer *evCont = new AliCFContainer("eventContainer", "Container for events", AliHFEcuts::kNcutStepsEvent, kNvar, &kNBins);
+
+  Double_t *trackBins = AliHFEtools::MakeLinearBinning(kNBins, kNTrackBound[0], kNTrackBound[1]);
+  evCont->SetBinLimits(0,trackBins);
+  delete[] trackBins;
+
+  fCFM->SetEventContainer(evCont);
 }
 
 //____________________________________________________________
@@ -810,29 +926,27 @@ void AliAnalysisTaskHFE::MakeParticleContainer(){
   // Create the particle container for the correction framework manager and 
   // link it
   //
-  const Int_t kNvar   = 3 ; //number of variables on the grid:pt,eta, phi
-  const Double_t kPtmin = 0.1, kPtmax = 10.;
-  const Double_t kEtamin = -0.9, kEtamax = 0.9;
-  const Double_t kPhimin = 0., kPhimax = 2. * TMath::Pi();
+  const Int_t kNvar   = 4 ; //number of variables on the grid:pt,eta, phi, charge
+  const Double_t kPtbound[2] = {0.1, 10.};
+  const Double_t kEtabound[2] = {-0.8, 0.8};
+  const Double_t kPhibound[2] = {0., 2. * TMath::Pi()};
 
   //arrays for the number of bins in each dimension
   Int_t iBin[kNvar];
-  iBin[0] = 40; //bins in pt
-  iBin[1] =  8; //bins in eta 
+  iBin[0] = 40; // bins in pt
+  iBin[1] =  8; // bins in eta 
   iBin[2] = 18; // bins in phi
+  iBin[3] =  2; // bins in charge
 
   //arrays for lower bounds :
   Double_t* binEdges[kNvar];
-  for(Int_t ivar = 0; ivar < kNvar; ivar++)
-    binEdges[ivar] = new Double_t[iBin[ivar] + 1];
-
-  //values for bin lower bounds
-  for(Int_t i=0; i<=iBin[0]; i++) binEdges[0][i]=(Double_t)TMath::Power(10,TMath::Log10(kPtmin) + (TMath::Log10(kPtmax)-TMath::Log10(kPtmin))/iBin[0]*(Double_t)i);  
-  for(Int_t i=0; i<=iBin[1]; i++) binEdges[1][i]=(Double_t)kEtamin  + (kEtamax-kEtamin)/iBin[1]*(Double_t)i;
-  for(Int_t i=0; i<=iBin[2]; i++) binEdges[2][i]=(Double_t)kPhimin  + (kPhimax-kPhimin)/iBin[2]*(Double_t)i;
+  binEdges[0] = AliHFEtools::MakeLogarithmicBinning(iBin[0], kPtbound[0], kPtbound[1]);
+  binEdges[1] = AliHFEtools::MakeLinearBinning(iBin[1], kEtabound[0], kEtabound[1]);
+  binEdges[2] = AliHFEtools::MakeLinearBinning(iBin[2], kPhibound[0], kPhibound[1]);
+  binEdges[3] = AliHFEtools::MakeLinearBinning(iBin[3], -1.1, 1.1); // Numeric precision
 
   //one "container" for MC
-  AliCFContainer* container = new AliCFContainer("container","container for tracks", (AliHFEcuts::kNcutSteps + 1 + 2*(AliHFEcuts::kNcutESDSteps + 1)), kNvar, iBin);
+  AliCFContainer* container = new AliCFContainer("trackContainer", "Container for tracks", (AliHFEcuts::kNcutStepsTrack + 2*AliHFEcuts::kNcutStepsESDtrack), kNvar, iBin);
 
   //setting the bin limits
   for(Int_t ivar = 0; ivar < kNvar; ivar++)
@@ -866,39 +980,49 @@ void AliAnalysisTaskHFE::MakeParticleContainer(){
   fCorrelation->AddAt(correlation1,1);
   
   // Add a histogram for Fake electrons
-  const Int_t nDim=5;
-  Int_t nBin[nDim] = {40, 8, 18, 3, 3};
+  const Int_t nDim=6;
+  Int_t nBin[nDim] = {40, 8, 18, 2, 3, 3};
   Double_t* binEdges2[nDim];
-  for(Int_t ivar = 0; ivar < nDim; ivar++)
-    binEdges2[ivar] = new Double_t[nBin[ivar] + 1];
 
   //values for bin lower bounds
-  for(Int_t i=0; i<=nBin[0]; i++) binEdges2[0][i]=(Double_t)TMath::Power(10,TMath::Log10(kPtmin) + (TMath::Log10(kPtmax)-TMath::Log10(kPtmin))/nBin[0]*(Double_t)i);  
-  for(Int_t i=0; i<=nBin[1]; i++) binEdges2[1][i]=(Double_t)kEtamin  + (kEtamax-kEtamin)/nBin[1]*(Double_t)i;
-  for(Int_t i=0; i<=nBin[2]; i++) binEdges2[2][i]=(Double_t)kPhimin  + (kPhimax-kPhimin)/nBin[2]*(Double_t)i;
-  for(Int_t i=0; i<=nBin[3]; i++) binEdges2[3][i] = i;
-  for(Int_t i=0; i<=nBin[4]; i++) binEdges2[4][i] = i;
-
-  fPIDperformance = new THnSparseF("PIDperformance", "PID performance; pT [GeV/c]; theta [rad]; phi [rad] type (0 - not el, 1 - other el, 2 - HF el; flavor (0 - no, 1 - charm, 2 - bottom)", nDim, nBin);
-  for(Int_t idim = 0; idim < nDim; idim++)
+  for(Int_t ivar = 0; ivar < kNvar; ivar++)
+    binEdges2[ivar] = binEdges[ivar];
+  binEdges2[4] = AliHFEtools::MakeLinearBinning(nBin[4], 0, nBin[4]);
+  binEdges2[5] = AliHFEtools::MakeLinearBinning(nBin[5], 0, nBin[5]);
+
+  fPIDperformance = new THnSparseF("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);
+  fPIDperformance->Sumw2();
+  fSignalToBackgroundMC = new THnSparseF("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);
+  fSignalToBackgroundMC->Sumw2();
+  for(Int_t idim = 0; idim < nDim; idim++){
     fPIDperformance->SetBinEdges(idim, binEdges2[idim]);
+    fSignalToBackgroundMC->SetBinEdges(idim, binEdges2[idim]); 
+  }
+  for(Int_t ivar = 0; ivar < kNvar; ivar++)
+    delete binEdges[ivar];
+  for(Int_t ivar = kNvar; ivar < nDim; ivar++)
+    delete binEdges2[ivar];
 }
 
-void AliAnalysisTaskHFE::AddPIDdetector(Char_t *detector){
+//____________________________________________________________
+void AliAnalysisTaskHFE::AddPIDdetector(TString detector){
+  //
+  // Adding PID detector to the task
+  //
   if(!fPIDdetectors.Length()) 
     fPIDdetectors = detector;
   else
-    fPIDdetectors += Form(":%s", detector);
+    fPIDdetectors += ":" + detector;
 }
 
 //____________________________________________________________
-void AliAnalysisTaskHFE::PrintStatus(){
+void AliAnalysisTaskHFE::PrintStatus() const {
   //
   // Print Analysis status
   //
   printf("\n\tAnalysis Settings\n\t========================================\n\n");
-  printf("\tSecondary Vertex finding: %s\n", IsSecVtxOn() ? "YES" : "NO");
-  printf("\tPrimary Vertex resolution: %s\n", IsPriVtxOn() ? "YES" : "NO");
+  printf("\tSecondary Vertex finding: %s\n", GetPlugin(kSecVtx) ? "YES" : "NO");
+  printf("\tPrimary Vertex resolution: %s\n", GetPlugin(kPriVtx) ? "YES" : "NO");
   printf("\n");
   printf("\tParticle Identification Detectors:\n");
   TObjArray *detectors = fPIDdetectors.Tokenize(":");
@@ -907,7 +1031,7 @@ void AliAnalysisTaskHFE::PrintStatus(){
   printf("\n");
   printf("\tQA: \n");
   printf("\t\tPID: %s\n", IsQAOn(kPIDqa) ? "YES" :  "NO");
-  printf("\t\tCUTS: %s\n", fCuts != NULL & fCuts->IsInDebugMode() ? "YES" : "NO");
+  printf("\t\tCUTS: %s\n", (fCuts != NULL && fCuts->IsInDebugMode()) ? "YES" : "NO");
   printf("\t\tMC: %s\n", IsQAOn(kMCqa) ? "YES" : "NO");
   printf("\n");
 }
@@ -940,7 +1064,7 @@ Bool_t AliAnalysisTaskHFE::LabelContainer::Append(Int_t label){
 }
 
 //____________________________________________________________
-Bool_t AliAnalysisTaskHFE::LabelContainer::Find(Int_t label){
+Bool_t AliAnalysisTaskHFE::LabelContainer::Find(Int_t label) const {
   //
   // Find track in the list of labels
   //
@@ -969,35 +1093,56 @@ Int_t AliAnalysisTaskHFE::IsSignalElectron(AliVParticle *fTrack) const{
     kCharm = 1,
     kBeauty = 2
   };
-  AliMCParticle *mctrack = NULL;
   TString objname = fTrack->IsA()->GetName();
-  if(!objname.CompareTo("AliESDtrack")){
-    AliDebug(2, "Checking signal for ESD track");
-    AliESDtrack *esdtrack = dynamic_cast<AliESDtrack *>(fTrack);
-    mctrack = dynamic_cast<AliMCParticle *>(fMC->GetTrack(TMath::Abs(esdtrack->GetLabel())));
-  }
-  else if(!objname.CompareTo("AliAODtrack")){
-    AliError("AOD Analysis not implemented yet");
-    return kNoSignal;
-  }
-  else if(!objname.CompareTo("AliMCParticle")){
-    AliDebug(2, "Checking signal for MC track");
-    mctrack = dynamic_cast<AliMCParticle *>(fTrack);
-  }
-  else{
-    AliError("Input object not supported");
-    return kNoSignal;
+  Int_t pid = 0;
+  if(IsESDanalysis()){
+    // ESD Analysis
+    AliMCParticle *mctrack = NULL;
+    if(!objname.CompareTo("AliESDtrack")){
+      AliDebug(2, "Checking signal for ESD track");
+      AliESDtrack *esdtrack = dynamic_cast<AliESDtrack *>(fTrack);
+      mctrack = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(TMath::Abs(esdtrack->GetLabel())));
+    }
+    else if(!objname.CompareTo("AliMCParticle")){
+      AliDebug(2, "Checking signal for MC track");
+      mctrack = dynamic_cast<AliMCParticle *>(fTrack);
+    }
+    else{
+      AliError("Input object not supported");
+      return kNoSignal;
+    }
+    if(!mctrack) return kNoSignal;
+    TParticle *ecand = mctrack->Particle(); 
+    if(TMath::Abs(ecand->GetPdgCode()) != 11) return kNoSignal; // electron candidate not true electron
+    Int_t motherLabel = TMath::Abs(ecand->GetFirstMother());
+    AliDebug(3, Form("mother label: %d\n", motherLabel));
+    if(!motherLabel) return kNoSignal; // mother track unknown
+    AliMCParticle *motherTrack = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(motherLabel));
+    if(!motherTrack) return kNoSignal;
+    TParticle *mparticle = motherTrack->Particle();
+    pid = TMath::Abs(mparticle->GetPdgCode());
+  } else {
+    // AOD Analysis - Different Data handling
+    AliAODMCParticle *aodmc = NULL;
+    if(!objname.CompareTo("AliAODTrack")){
+      AliAODTrack *aodtrack = dynamic_cast<AliAODTrack *>(fTrack);
+      Int_t aodlabel = TMath::Abs(aodtrack->GetLabel());
+      if(aodlabel >= fMCEvent->GetNumberOfTracks()) return kNoSignal;
+      aodmc = dynamic_cast<AliAODMCParticle *>(fMCEvent->GetTrack(aodlabel));
+    } else if(!objname.CompareTo("AliAODMCParticle")){
+      aodmc = dynamic_cast<AliAODMCParticle *>(fTrack);
+    } else{
+      AliError("Input object not supported");
+      return kNoSignal;
+    }
+    if(!aodmc) return kNoSignal;
+    Int_t motherLabel = TMath::Abs(aodmc->GetMother());
+    AliDebug(3, Form("mother label: %d\n", motherLabel));
+    if(!motherLabel || motherLabel >= fMCEvent->GetNumberOfTracks()) return kNoSignal;
+    AliAODMCParticle *aodmother = dynamic_cast<AliAODMCParticle *>(fMCEvent->GetTrack(motherLabel));
+    pid = aodmother->GetPdgCode();
   }
-  if(!mctrack) return kNoSignal;
-  TParticle *ecand = mctrack->Particle(); 
-  if(TMath::Abs(ecand->GetPdgCode()) != 11) return kNoSignal; // electron candidate not true electron
-  Int_t motherLabel = TMath::Abs(ecand->GetFirstMother());
-  AliDebug(3, Form("mother label: %d\n", motherLabel));
-  if(!motherLabel) return kNoSignal; // mother track unknown
-  AliMCParticle *motherTrack = dynamic_cast<AliMCParticle *>(fMC->GetTrack(motherLabel));
-  if(!motherTrack) return kNoSignal;
-  TParticle *mparticle = motherTrack->Particle();
-  Int_t pid = TMath::Abs(mparticle->GetPdgCode());
+  // From here the two analysis modes go together
   AliDebug(3, Form("PDG code: %d\n", pid));
 
   // identify signal according to Pdg Code 
@@ -1009,13 +1154,45 @@ Int_t AliAnalysisTaskHFE::IsSignalElectron(AliVParticle *fTrack) const{
 }
 
 //__________________________________________
-Float_t AliAnalysisTaskHFE::GetRapidity(TParticle *part)
-{
-      // return rapidity
+void AliAnalysisTaskHFE::SwitchOnPlugin(Int_t plug){
+  //
+  // Switch on Plugin
+  // Available:
+  //  - Primary vertex studies
+  //  - Secondary vertex Studies
+  //  - Post Processing
+  //
+  switch(plug){
+    case kPriVtx: SETBIT(fPlugins, plug); break;
+    case kSecVtx: SETBIT(fPlugins, plug); break;
+    case kIsElecBackGround: SETBIT(fPlugins, plug); break;
+    case kPostProcess: SETBIT(fPlugins, plug); break;
+    default: AliError("Unknown Plugin");
+  };
+}
+
+//__________________________________________
+Bool_t AliAnalysisTaskHFE::ProcessCutStep(Int_t cutStep, AliVParticle *track, Double_t *container, Bool_t signal, Bool_t alreadyseen){
+  //
+  // Check single track cuts for a given cut step
+  // Fill the particle container
+  //
+  if(!fCFM->CheckParticleCuts(cutStep, track)) return kFALSE;
+  if(signal) {
+    fCFM->GetParticleContainer()->Fill(container, cutStep + 2*AliHFEcuts::kNcutStepsESDtrack);
+    fCFM->GetParticleContainer()->Fill(&container[4], cutStep);
+    if(alreadyseen) {
+      fCFM->GetParticleContainer()->Fill(&container[4], cutStep + AliHFEcuts::kNcutStepsESDtrack);
+    }
+  }
+  return kTRUE;
+}
 
-       Float_t rapidity;
-       if(part->Energy() - part->Pz() == 0 || part->Energy() + part->Pz() == 0) rapidity=-999;
-       else rapidity = 0.5*(TMath::Log((part->Energy()+part->Pz()) / (part->Energy()-part->Pz())));
-       return rapidity;
+//__________________________________________
+void AliAnalysisTaskHFE::SetTPCBetheBlochParameters(Double_t *pars){
+  //
+  // Set Bethe-Bloch Parameters for TPC PID
+  //
+  fPID->SetTPCBetheBlochParameters(pars);
 }