]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - PWG3/hfe/AliAnalysisTaskHFE.cxx
Major update of the HFE package (comments inside the code
[u/mrichter/AliRoot.git] / PWG3 / hfe / AliAnalysisTaskHFE.cxx
index ab885fb3d108025981a11c8ec2170d0fdee26f0d..508485043a6e170c6dd8728bbcce264949016443 100644 (file)
 #include <TChain.h>
 #include <TDirectory.h>
 #include <TFile.h>
-#include <TH1D.h>
-#include <TH1F.h>
-#include <TH1I.h>
-#include <TH2F.h>
 #include <TH3D.h>
 #include <TIterator.h>
 #include <TList.h>
@@ -54,6 +50,7 @@
 #include "AliESDInputHandler.h"
 #include "AliESDpid.h"
 #include "AliESDtrack.h"
+#include "AliESDCentrality.h"
 #include "AliLog.h"
 #include "AliAnalysisManager.h"
 #include "AliMCEvent.h"
 #include "AliTriggerAnalysis.h"
 #include "AliVVertex.h"
 
-#include "AliHFEpid.h"
 #include "AliHFEcollection.h"
+#include "AliHFEcontainer.h"
 #include "AliHFEcuts.h"
+#include "AliHFEelecbackground.h"
 #include "AliHFEmcQA.h"
 #include "AliHFEpairs.h"
+#include "AliHFEpid.h"
+#include "AliHFEpidQAmanager.h"
 #include "AliHFEpostAnalysis.h"
 #include "AliHFEsecVtxs.h"
 #include "AliHFEsecVtx.h"
-#include "AliHFEelecbackground.h"
+#include "AliHFEsignalCuts.h"
+#include "AliHFEtaggedTrackAnalysis.h"
 #include "AliHFEtools.h"
+#include "AliHFEvarManager.h"
 #include "AliAnalysisTaskHFE.h"
 
 ClassImp(AliAnalysisTaskHFE)
@@ -82,31 +84,29 @@ ClassImp(AliAnalysisTaskHFE)
 AliAnalysisTaskHFE::AliAnalysisTaskHFE():
   AliAnalysisTaskSE("PID efficiency Analysis")
   , fQAlevel(0)
-  , fPIDdetectors("")
-  , fPIDstrategy(0)
   , fPlugins(0)
-  , fWeighting(kFALSE)
-  , fWeightFactors(NULL)
-  , fWeightFactorsFunction(NULL)
+  , fFillSignalOnly(kTRUE)
+  , fRemovePileUp(kFALSE)
+  , fIdentifiedAsPileUp(kFALSE)
+  , fIdentifiedAsOutInz(kFALSE)
+  , fPassTheEventCut(kFALSE)
+  , fCentralityF(99.0)
   , fBackGroundFactorsFunction(NULL)
+  , fContainer(NULL)
+  , fVarManager(NULL)
+  , fSignalCuts(NULL)
   , fCFM(NULL)
-  , fV0CF(NULL)
   , fTriggerAnalysis(NULL)
-  , fHadronicBackground(NULL)
-  , fCorrelation(NULL)
-  , fPIDperformance(NULL)
-  , fSignalToBackgroundMC(NULL)
   , fPID(NULL)
-  , fPIDtagged(NULL)
+  , fPIDqa(NULL)
   , fPIDpreselect(NULL)
   , fCuts(NULL)
-  , fCutsTagged(NULL)
+  , fTaggedTrackCuts(NULL)
   , fCutspreselect(NULL)
   , fSecVtx(NULL)
   , fElecBackGround(NULL)
   , fMCQA(NULL)
-  , fNEvents(NULL)
-  , fNElectronTracksEvent(NULL)
+  , fTaggedTrackAnalysis(NULL)
   , fQA(NULL)
   , fOutput(NULL)
   , fHistMCQA(NULL)
@@ -123,31 +123,29 @@ AliAnalysisTaskHFE::AliAnalysisTaskHFE():
 AliAnalysisTaskHFE::AliAnalysisTaskHFE(const char * name):
   AliAnalysisTaskSE(name)
   , fQAlevel(0)
-  , fPIDdetectors("")
-  , fPIDstrategy(0)
   , fPlugins(0)
-  , fWeighting(kFALSE)
-  , fWeightFactors(NULL)
-  , fWeightFactorsFunction(NULL)
+  , fFillSignalOnly(kTRUE)
+  , fRemovePileUp(kFALSE)
+  , fIdentifiedAsPileUp(kFALSE)
+  , fIdentifiedAsOutInz(kFALSE)
+  , fPassTheEventCut(kFALSE)  
+  , fCentralityF(99.0)
   , fBackGroundFactorsFunction(NULL)
+  , fContainer(NULL)
+  , fVarManager(NULL)
+  , fSignalCuts(NULL)
   , fCFM(NULL)
-  , fV0CF(NULL)
   , fTriggerAnalysis(NULL)
-  , fHadronicBackground(NULL)
-  , fCorrelation(NULL)
-  , fPIDperformance(NULL)
-  , fSignalToBackgroundMC(NULL)
   , fPID(NULL)
-  , fPIDtagged(NULL)
+  , fPIDqa(NULL)
   , fPIDpreselect(NULL)
   , fCuts(NULL)
-  , fCutsTagged(NULL)
+  , fTaggedTrackCuts(NULL)
   , fCutspreselect(NULL)
   , fSecVtx(NULL)
   , fElecBackGround(NULL)
   , fMCQA(NULL)
-  , fNEvents(NULL)
-  , fNElectronTracksEvent(NULL)
+  , fTaggedTrackAnalysis(NULL)
   , fQA(NULL)
   , fOutput(NULL)
   , fHistMCQA(NULL)
@@ -158,42 +156,40 @@ AliAnalysisTaskHFE::AliAnalysisTaskHFE(const char * name):
   //
   // Default constructor
   // 
-  DefineOutput(1, TH1I::Class());
+  DefineOutput(1, TList::Class());
   DefineOutput(2, TList::Class());
-  DefineOutput(3, TList::Class());
 
-  // Initialize cuts
+  fPID = new AliHFEpid("hfePid");
+  fVarManager = new AliHFEvarManager("hfeVarManager");
 }
 
 //____________________________________________________________
 AliAnalysisTaskHFE::AliAnalysisTaskHFE(const AliAnalysisTaskHFE &ref):
   AliAnalysisTaskSE(ref)
   , fQAlevel(0)
-  , fPIDdetectors()
-  , fPIDstrategy(0)
   , fPlugins(0)
-  , fWeighting(kFALSE)
-  , fWeightFactors(NULL)
-  , fWeightFactorsFunction(NULL)
+  , fFillSignalOnly(ref.fFillSignalOnly)
+  , fRemovePileUp(ref.fRemovePileUp)
+  , fIdentifiedAsPileUp(ref.fIdentifiedAsPileUp)
+  , fIdentifiedAsOutInz(ref.fIdentifiedAsOutInz)
+  , fPassTheEventCut(ref.fPassTheEventCut)
+  , fCentralityF(ref.fCentralityF)
   , fBackGroundFactorsFunction(NULL)
+  , fContainer(NULL)
+  , fVarManager(NULL)
+  , fSignalCuts(NULL)
   , fCFM(NULL)
-  , fV0CF(NULL)
   , fTriggerAnalysis(NULL)
-  , fHadronicBackground(NULL)
-  , fCorrelation(NULL)
-  , fPIDperformance(NULL)
-  , fSignalToBackgroundMC(NULL)
   , fPID(NULL)
-  , fPIDtagged(NULL)
+  , fPIDqa(NULL)
   , fPIDpreselect(NULL)
   , fCuts(NULL)
-  , fCutsTagged(NULL)
+  , fTaggedTrackCuts(NULL)
   , fCutspreselect(NULL)
   , fSecVtx(NULL)
   , fElecBackGround(NULL)
   , fMCQA(NULL)
-  , fNEvents(NULL)
-  , fNElectronTracksEvent(NULL)
+  , fTaggedTrackAnalysis(NULL)
   , fQA(NULL)
   , fOutput(NULL)
   , fHistMCQA(NULL)
@@ -224,30 +220,29 @@ void AliAnalysisTaskHFE::Copy(TObject &o) const {
   //
   AliAnalysisTaskHFE &target = dynamic_cast<AliAnalysisTaskHFE &>(o);
   target.fQAlevel = fQAlevel;
-  target.fPIDdetectors = fPIDdetectors;
-  target.fPIDstrategy = fPIDstrategy;
   target.fPlugins = fPlugins;
-  target.fWeighting = fWeighting;
-  target.fWeightFactors = fWeightFactors;
-  target.fWeightFactorsFunction = fWeightFactorsFunction;
+  target.fFillSignalOnly = fFillSignalOnly;
+  target.fRemovePileUp = fRemovePileUp;
+  target.fIdentifiedAsPileUp = fIdentifiedAsPileUp;
+  target.fIdentifiedAsOutInz = fIdentifiedAsOutInz;
+  target.fPassTheEventCut = fPassTheEventCut;
+  target.fCentralityF = fCentralityF;
   target.fBackGroundFactorsFunction = fBackGroundFactorsFunction;
+  target.fContainer = fContainer;
+  target.fVarManager = fVarManager;
+  target.fSignalCuts = fSignalCuts;
   target.fCFM = fCFM;
-  target.fV0CF = fV0CF;
   target.fTriggerAnalysis = fTriggerAnalysis;
-  target.fHadronicBackground = fHadronicBackground;
-  target.fCorrelation = fCorrelation;
-  target.fPIDperformance = fPIDperformance;
-  target.fSignalToBackgroundMC = fSignalToBackgroundMC;
   target.fPID = fPID;
-  target.fPIDtagged = fPIDtagged;
+  target.fPIDqa = fPIDqa;
   target.fPIDpreselect = fPIDpreselect;
   target.fCuts = fCuts;
+  target.fTaggedTrackCuts = fTaggedTrackCuts;
   target.fCutspreselect = fCutspreselect;
   target.fSecVtx = fSecVtx;
   target.fElecBackGround = fElecBackGround;
   target.fMCQA = fMCQA;
-  target.fNEvents = fNEvents;
-  target.fNElectronTracksEvent = fNElectronTracksEvent;
+  target.fTaggedTrackAnalysis = fTaggedTrackAnalysis;
   target.fQA = fQA;
   target.fOutput = fOutput;
   target.fHistMCQA = fHistMCQA;
@@ -261,44 +256,18 @@ AliAnalysisTaskHFE::~AliAnalysisTaskHFE(){
   //
   // Destructor
   //
-  return;
   if(fPID) delete fPID;
-  if(fPIDtagged) delete fPIDtagged;
-  if(fQA){
-    fQA->Clear();
-    delete fQA;
-  }
-  if(fOutput){ 
-    fOutput->Clear();
-    delete fOutput;
-  }
-  if(fWeightFactors) delete fWeightFactors;
-  if(fWeightFactorsFunction) delete fWeightFactorsFunction;
-  if(fBackGroundFactorsFunction) delete fBackGroundFactorsFunction;
-  if(fHistMCQA){
-    fHistMCQA->Clear();
-    delete fHistMCQA;
-  }
-  if(fHistSECVTX){
-    fHistSECVTX->Clear();
-    delete fHistSECVTX;
-  }
-  if(fHistELECBACKGROUND){
-    fHistELECBACKGROUND->Clear();
-    delete fHistELECBACKGROUND;
-  }
+  if(fVarManager) delete fVarManager;
+  if(fPIDqa) delete fPIDqa;
+  if(fSignalCuts) delete fSignalCuts;
+  if(fCFM) delete fCFM;
   if(fSecVtx) delete fSecVtx;
-  if(fElecBackGround) delete fElecBackGround;
   if(fMCQA) delete fMCQA;
-  if(fNEvents) delete fNEvents;
-  if(fCorrelation){
-    fCorrelation->Clear();
-    delete fCorrelation;
-  }
-  if(fPIDperformance) delete fPIDperformance;
-  if(fSignalToBackgroundMC) delete fSignalToBackgroundMC;
-//  if(fQAcoll) delete fQAcoll;
-
+  if(fElecBackGround) delete fElecBackGround;
+  if(fTriggerAnalysis) delete fTriggerAnalysis;
+  if(fPIDpreselect) delete fPIDpreselect;
+  if(fQA) delete fQA;
+  if(fOutput) delete fOutput;
 }
 
 //____________________________________________________________
@@ -313,7 +282,6 @@ void AliAnalysisTaskHFE::UserCreateOutputObjects(){
   // QA histograms are created if requested
   // Called once per worker
   //
-  fPID = new AliHFEpid("standardPID"); fPIDtagged = new AliHFEpid("taggedPID");
   AliDebug(3, "Creating Output Objects");
   // Automatic determination of the analysis mode
   AliVEventHandler *inputHandler = dynamic_cast<AliVEventHandler *>(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler());
@@ -327,23 +295,21 @@ void AliAnalysisTaskHFE::UserCreateOutputObjects(){
   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);
-
   // Enable Trigger Analysis
   fTriggerAnalysis = new AliTriggerAnalysis;
   fTriggerAnalysis->EnableHistograms();
   fTriggerAnalysis->SetAnalyzeMC(HasMCData());
 
-  // Make QA histograms
-  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
+
+  // Make lists for Output
   if(!fQA) fQA = new TList;
+  fQA->SetOwner();
+  if(!fOutput) fOutput = new TList;
+  fOutput->SetOwner();
 
+  // First Part: Make QA histograms
   fQACollection = new AliHFEcollection("TaskQA", "QA histos from the Electron Task");
+  fQACollection->CreateTH1F("nElectronTracksEvent", "Number of Electron Candidates", 100, 0, 100);
   fQACollection->CreateProfile("conr", "Electron PID contamination", 20, 0, 20);
   fQACollection->CreateTH1F("alpha_rec", "Alpha from reconstructed tracks with TRD hits", 36, -TMath::Pi(), TMath::Pi());
   fQACollection->CreateTH1F("alpha_sim", "Alpha from simulated electron tracks", 36, -TMath::Pi(), TMath::Pi());
@@ -353,18 +319,28 @@ void AliAnalysisTaskHFE::UserCreateOutputObjects(){
   fQACollection->CreateTH1F("chi2TRD","#chi2 per TRD cluster", 20, 0, 20);
   fQACollection->CreateTH1F("mccharge", "MC Charge", 200, -100, 100);
   fQACollection->CreateTH2F("radius", "Production Vertex", 100, 0.0, 5.0, 100, 0.0, 5.0);
-  fQACollection->CreateTH1F("secvtxept", "pT of tagged e", 500, 0, 50); // mj: will move to another place soon
-  fQACollection->CreateTH2F("secvtxeTPCsig", "TPC signal for tagged e",125, 0, 25, 200, 0, 200 ); // mj: will move to another place soon 
+  InitPIDperformanceQA();
   fQA->Add(fQACollection->GetList());
 
-  if(!fOutput) fOutput = new TList;
+  // Initialize PID
+  fPID->SetHasMCData(HasMCData());
+  if(!fPID->GetNumberOfPIDdetectors()) fPID->AddDetector("TPC", 0);
+  fPID->InitializePID();
+  if(IsQAOn(kPIDqa)){
+    AliInfo("PID QA switched on");
+    fPIDqa = new AliHFEpidQAmanager;
+    fPIDqa->Initialize(fPID);
+    fQA->Add(fPIDqa->MakeList("HFEpidQA"));
+  }
+
   // Initialize correction Framework and Cuts
+  const Int_t kNcutSteps = AliHFEcuts::kNcutStepsMCTrack + AliHFEcuts::kNcutStepsRecTrack + AliHFEcuts::kNcutStepsDETrack;
   fCFM = new AliCFManager;
-  fV0CF = new AliCFManager;
+  fCFM->SetNStepParticle(kNcutSteps);
   MakeParticleContainer();
   MakeEventContainer();
   // Temporary fix: Initialize particle cuts with NULL
-  for(Int_t istep = 0; istep < fCFM->GetParticleContainer()->GetNStep(); istep++)
+  for(Int_t istep = 0; istep < kNcutSteps; istep++)
     fCFM->SetParticleCutsList(istep, NULL);
   if(!fCuts){
     AliWarning("Cuts not available. Default cuts will be used");
@@ -373,46 +349,21 @@ void AliAnalysisTaskHFE::UserCreateOutputObjects(){
   }
   if(IsAODanalysis()) fCuts->SetAOD();
   // Make clone for V0 tagging step
-  fCutsTagged = new AliHFEcuts(*fCuts);
-  fCutsTagged->SetName("hfeV0Cuts");
-  fCutsTagged->SetTitle("Cuts for tagged Particles");
   fCuts->Initialize(fCFM);
-  fCutsTagged->Initialize(fV0CF);
   if(fCuts->IsQAOn()) fQA->Add(fCuts->GetQAhistograms());
-  if(fCutsTagged->IsQAOn()) fQA->Add(fCutsTagged->GetQAhistograms());
+  fSignalCuts = new AliHFEsignalCuts("HFEsignalCuts", "HFE MC Signal definition");
+  fVarManager->SetSignalCuts(fSignalCuts);
  
   // add output objects to the List
-  fOutput->AddAt(fCFM->GetParticleContainer(), 0);
+  fOutput->AddAt(fContainer, 0);
   fOutput->AddAt(fCFM->GetEventContainer(), 1);
-  fOutput->AddAt(fCorrelation, 2);
-  fOutput->AddAt(fPIDperformance, 3);
-  fOutput->AddAt(fSignalToBackgroundMC, 4);
-  fOutput->AddAt(fNElectronTracksEvent, 5);
-  fOutput->AddAt(fHadronicBackground, 6);
-  fOutput->AddAt(fV0CF, 7);
-  // Initialize PID
-  if(IsQAOn(kPIDqa)){
-    AliInfo("PID QA switched on");
-    //fPID->SetDebugLevel(2);
-    fPID->SetQAOn();
-    fQA->Add(fPID->GetQAhistograms());
-  }
-  fPID->SetHasMCData(HasMCData());
-  if(!fPIDdetectors.Length() && ! fPIDstrategy) AddPIDdetector("TPC");
-  if(fPIDstrategy){
-    fPID->InitializePID(Form("Strategy%d", fPIDstrategy));
-    fPIDtagged->InitializePID(Form("Strategy%d", fPIDstrategy));
-  }
-  else{
-    fPID->InitializePID(fPIDdetectors.Data());     // Only restrictions to TPC allowed 
-    fPIDtagged->InitializePID(fPIDdetectors.Data());     // Only restrictions to TPC allowed 
-  }
-
+  
   // mcQA----------------------------------
   if (HasMCData() && IsQAOn(kMCqa)) {
     AliInfo("MC QA on");
     if(!fMCQA) fMCQA = new AliHFEmcQA;
     if(!fHistMCQA) fHistMCQA = new TList();
+    fHistMCQA->SetOwner();
     fMCQA->CreatDefaultHistograms(fHistMCQA);
     fQA->Add(fHistMCQA);
   } 
@@ -424,6 +375,7 @@ void AliAnalysisTaskHFE::UserCreateOutputObjects(){
     fSecVtx->SetHasMCData(HasMCData());
 
     if(!fHistSECVTX) fHistSECVTX = new TList();
+    fHistSECVTX->SetOwner();
     fSecVtx->CreateHistograms(fHistSECVTX);
     fOutput->Add(fHistSECVTX);
   }
@@ -438,9 +390,23 @@ void AliAnalysisTaskHFE::UserCreateOutputObjects(){
     fElecBackGround->SetHasMCData(HasMCData());
 
     if(!fHistELECBACKGROUND) fHistELECBACKGROUND = new TList();
+    fHistELECBACKGROUND->SetOwner();
     fElecBackGround->CreateHistograms(fHistELECBACKGROUND);
     fOutput->Add(fHistELECBACKGROUND);
   }  
+
+  // tagged tracks
+  if(GetPlugin(kTaggedTrackAnalysis)){
+    AliInfo("Analysis on V0-tagged tracks enabled");
+    fTaggedTrackAnalysis = new AliHFEtaggedTrackAnalysis;
+    fTaggedTrackAnalysis->SetCuts(fTaggedTrackCuts);
+    fTaggedTrackAnalysis->SetPID(fPID);
+    fTaggedTrackAnalysis->InitContainer();
+    fOutput->Add(fTaggedTrackAnalysis->GetContainer());
+    fQA->Add(fTaggedTrackAnalysis->GetPIDQA());
+    fQA->Add(fTaggedTrackAnalysis->GetCutQA());
+  }
+  PrintStatus();
 }
 
 //____________________________________________________________
@@ -477,35 +443,48 @@ void AliAnalysisTaskHFE::UserExec(Option_t *){
     if(!mcH->TreeTR()) return;
   }
 
+  // need the centrality for everything (MC also)
+  fCentralityF = 99.0;
+  ReadCentrality();
+  
+  // See if pile up and z in the range
+  RejectionPileUpVertexRangeEventCut();
+
   // Protect agains missing 
-  if(HasMCData()) ProcessMC();  // Run the MC loop + MC QA in case MC Data are available
+  if(HasMCData()){
+    fSignalCuts->SetMCEvent(fMCEvent);
+    ProcessMC();  // Run the MC loop + MC QA in case MC Data are available
+  }
 
-  if(IsAODanalysis()) ProcessAOD();
-  else{
+  if(IsAODanalysis()){
+    AliAODpidUtil *aodworkingpid = AliHFEtools::GetDefaultAODPID(HasMCData());
+    fPID->SetAODpid(aodworkingpid); 
+    if(fPIDqa) fPIDqa->SetAODpid(aodworkingpid);
+    if(fTaggedTrackAnalysis) fTaggedTrackAnalysis->GetPIDqa()->SetAODpid(aodworkingpid);
+    ProcessAOD();
+  } else {
     AliESDInputHandler *inH = dynamic_cast<AliESDInputHandler *>(fInputHandler);
     if(!inH){
       AliError("No ESD Input handler available");
       return;
     }
     AliESDpid *workingPID = inH->GetESDpid();
-    if(workingPID){
-      AliDebug(1, "Using ESD PID from the input handler");
-      fPID->SetESDpid(workingPID);
-      fPIDtagged->SetESDpid(workingPID);
-      if(fPIDpreselect) fPIDpreselect->SetESDpid(workingPID);
-    } else { 
+    if(!workingPID){
       AliDebug(1, "Using default ESD PID");
-      fPID->SetESDpid(AliHFEtools::GetDefaultPID(HasMCData()));
-      fPIDtagged->SetESDpid(AliHFEtools::GetDefaultPID(HasMCData()));
-      if(fPIDpreselect) fPIDpreselect->SetESDpid(AliHFEtools::GetDefaultPID(HasMCData())); 
+      workingPID = AliHFEtools::GetDefaultPID(HasMCData());
+    } else { 
+      AliDebug(1, "Using ESD PID from the input handler");
     }
+    fPID->SetESDpid(workingPID);
+    if(fPIDqa) fPIDqa->SetESDpid(workingPID);
+    if(fTaggedTrackAnalysis) fTaggedTrackAnalysis->GetPIDqa()->SetESDpid(workingPID);
+    if(fPIDpreselect) fPIDpreselect->SetESDpid(workingPID);
+
     ProcessESD();
   }
   // Done!!!
-  PostData(1, fNEvents);
-  PostData(2, fOutput);
-  PostData(3, fQA);
-//  PostData(4, fQAcoll->GetList());
+  PostData(1, fOutput);
+  PostData(2, fQA);
 }
 
 //____________________________________________________________
@@ -514,14 +493,32 @@ void AliAnalysisTaskHFE::Terminate(Option_t *){
   // Terminate not implemented at the moment
   //
   if(GetPlugin(kPostProcess)){
-    fOutput = dynamic_cast<TList *>(GetOutputData(2));
+    fOutput = dynamic_cast<TList *>(GetOutputData(1));
+    fQA = dynamic_cast<TList *>(GetOutputData(2));
     if(!fOutput){
       AliError("Results not available");
       return;
     }
+    if(!fQA){
+      AliError("QA output not available");
+      return;
+    }
+    fContainer = dynamic_cast<AliHFEcontainer *>(fOutput->FindObject("trackContainer")); 
+    if(!fContainer){
+      AliError("Track container not found");
+      return;
+    }
     AliHFEpostAnalysis postanalysis;
-    postanalysis.SetResults(fOutput);
-    if(HasMCData())postanalysis.DrawMCSignal2Background();
+    postanalysis.SetTaskResults(fContainer);
+    TList *qalist = dynamic_cast<TList *>(fQA->FindObject("list_TaskQA"));
+    if(!qalist){
+      AliError("QA List not found");
+      return;
+    }
+    postanalysis.SetTaskQA(qalist);
+    printf("Running post analysis\n");
+    //if(HasMCData())
+    postanalysis.DrawMCSignal2Background();
     postanalysis.DrawEfficiency();
     postanalysis.DrawPIDperformance();
     postanalysis.DrawCutEfficiency();
@@ -570,8 +567,9 @@ void AliAnalysisTaskHFE::ProcessMC(){
   // In case MC QA is on also MC QA loop is done
   //
   AliDebug(3, "Processing MC Information");
-  Double_t eventContainer [2];
+  Double_t eventContainer [3];
   eventContainer[0] = fMCEvent->GetPrimaryVertex()->GetZ();
+  eventContainer[2] = fCentralityF;
   if(fCFM->CheckEventCuts(AliHFEcuts::kEventStepGenerated, fMCEvent)) 
     fCFM->GetEventContainer()->Fill(eventContainer,AliHFEcuts::kEventStepGenerated);
   Int_t nElectrons = 0;
@@ -623,7 +621,7 @@ void AliAnalysisTaskHFE::ProcessMC(){
   AliDebug(3, Form("Number of Tracks: %d", fMCEvent->GetNumberOfTracks()));
   for(Int_t imc = 0; imc <fMCEvent->GetNumberOfTracks(); imc++){
     if(!(mctrack = fMCEvent->GetTrack(imc))) continue;
-    AliDebug(4, "Next Track");
+    AliDebug(4, "Next MC Track");
     if(ProcessMCtrack(mctrack)) nElectrons++;
   }
 
@@ -645,15 +643,32 @@ void AliAnalysisTaskHFE::ProcessESD(){
   }
 
   // Do event Normalization
-  Double_t eventContainer[2];
+  Double_t eventContainer[3];
   eventContainer[0] = fInputEvent->GetPrimaryVertex()->GetZ();
   eventContainer[1] = 0.;
+  eventContainer[2] = fCentralityF;
   if(fTriggerAnalysis->IsOfflineTriggerFired(fESD, AliTriggerAnalysis::kV0AND))
     eventContainer[1] = 1.;
+
+  //
   fCFM->GetEventContainer()->Fill(eventContainer, AliHFEcuts::kEventStepRecNoCut);
-  if(!fCFM->CheckEventCuts(AliHFEcuts::kEventStepReconstructed, fInputEvent)) return;
+
+  //
+  if(fIdentifiedAsPileUp) return; 
+  fCFM->GetEventContainer()->Fill(eventContainer, AliHFEcuts::kEventStepRecNoPileUp);
+
+  //
+  if(fIdentifiedAsOutInz) return;
+  fCFM->GetEventContainer()->Fill(eventContainer, AliHFEcuts::kEventStepZRange);  
+
+  //
+  if(!fPassTheEventCut) return;
   fCFM->GetEventContainer()->Fill(eventContainer, AliHFEcuts::kEventStepReconstructed);
 
+
+  fContainer->NewEvent();
+
   if (GetPlugin(kIsElecBackGround)) { 
     fElecBackGround->SetEvent(fESD);
   }
@@ -665,13 +680,13 @@ void AliAnalysisTaskHFE::ProcessESD(){
   if(HasMCData()){
     if (GetPlugin(kSecVtx)) { 
       fSecVtx->SetMCEvent(fMCEvent);
+      fSecVtx->SetMCQA(fMCQA); 
     }
     if (GetPlugin(kIsElecBackGround)) { 
       fElecBackGround->SetMCEvent(fMCEvent);
     }
   }
 
-  Double_t nContrib = fInputEvent->GetPrimaryVertex()->GetNContributors();
   Double_t container[10];
   memset(container, 0, sizeof(Double_t) * 10);
   // container for the output THnSparse
@@ -681,9 +696,6 @@ void AliAnalysisTaskHFE::ProcessESD(){
   AliMCParticle *mctrack = NULL;
   TParticle* mctrack4QA = NULL;
   Int_t pid = 0;
-  // For double counted tracks
-  LabelContainer cont(fESD->GetNumberOfTracks());
-  Bool_t alreadyseen = kFALSE;
 
   Bool_t signal = kTRUE;
 
@@ -701,6 +713,7 @@ void AliAnalysisTaskHFE::ProcessESD(){
   //
   AliDebug(3, Form("Number of Tracks: %d", fESD->GetNumberOfTracks()));
   for(Int_t itrack = 0; itrack < fESD->GetNumberOfTracks(); itrack++){
+    AliDebug(4, "New ESD track");
     track = fESD->GetTrack(itrack);
 
     // fill counts of v0-identified particles
@@ -708,8 +721,11 @@ void AliAnalysisTaskHFE::ProcessESD(){
     if(track->TestBit(BIT(14))) v0pid = AliPID::kElectron;
     else if(track->TestBit(BIT(15))) v0pid = AliPID::kPion;
     else if(track->TestBit(BIT(16))) v0pid = AliPID::kProton;
-    if(v0pid > -1)
-      FilterTaggedTrack(track, v0pid);
+    // here the tagged track analysis will run
+    if(fTaggedTrackAnalysis && v0pid > -1){ 
+      AliDebug(1, Form("Track identified as %s", AliPID::ParticleName(v0pid)));
+      fTaggedTrackAnalysis->ProcessTrack(track, v0pid);
+    }
  
     AliDebug(3, Form("Doing track %d, %p", itrack, track));
      
@@ -719,66 +735,29 @@ void AliAnalysisTaskHFE::ProcessESD(){
     if(fPIDpreselect && fCutspreselect) {
       if(!PreSelectTrack(track)) continue;
     }
-     
-    container[0] = track->Pt();
-    container[1] = track->Eta();
-    container[2] = track->Phi();
-    container[3] = track->Charge();
-    container[4] = 0;
-
-    dataE[0] = track->Pt();
-    dataE[1] = track->Eta();
-    dataE[2] = track->Phi();
-    dataE[3] = track->Charge();
-    dataE[4] = -1;
-    dataE[5] = -1;
 
     signal = kTRUE;
-    Double_t weight = 1.0;
     
     // Fill step without any cut
           
     if(HasMCData()){
-      container[4] = container[9] = kOther;
       // Check if it is electrons near the vertex
       if(!(mctrack = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(TMath::Abs(track->GetLabel()))))) continue;
       mctrack4QA = mctrack->Particle();
 
-      container[5] = mctrack->Pt();
-      container[6] = mctrack->Eta();
-      container[7] = mctrack->Phi();
-      container[8] = mctrack->Charge()/3.;
-
-      if(fWeighting) weight = FindWeight(container[5],container[6],container[7]);    
-
-      if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepMCGenerated, mctrack)) signal = kFALSE;
+      if(fFillSignalOnly && !fCFM->CheckParticleCuts(AliHFEcuts::kStepMCGenerated, mctrack)) signal = kFALSE;
       else AliDebug(3, "Signal Electron");
-      
-      Int_t signalTrack = 0;
-      if((signalTrack = IsSignalElectron(track))){
-        AliDebug(3, Form("Signal: Index = %d\n", signalTrack));
-        switch(signalTrack){
-          case 1: container[4] = container[9] = kSignalCharm; break;
-          case 2: container[4] = container[9] = kSignalBeauty; break;
-          default: container[4] = container[9] = kOther; break;
-        };
-      } else if(IsGammaElectron(track)) container[4] = container[9] = kGammaConv;
-      AliDebug(3, Form("Signal Decision(%f/%f)", container[4], container[9]));
     } 
-    AliDebug(3, Form("Weight? %f", weight));
+    // Cache new Track information inside the var manager
+    fVarManager->NewTrack(track, mctrack, fCentralityF, -1, signal);
+
     if(signal) {
-      alreadyseen = cont.Find(TMath::Abs(track->GetLabel()));
-      cont.Append(TMath::Abs(track->GetLabel()));
-      
-      fCFM->GetParticleContainer()->Fill(&container[5], AliHFEcuts::kStepRecNoCut,weight);
-      fCFM->GetParticleContainer()->Fill(&container[0], AliHFEcuts::kStepRecNoCut + 2*AliHFEcuts::kNcutStepsESDtrack,weight);
-      if(alreadyseen) {
-        fCFM->GetParticleContainer()->Fill(&container[5], AliHFEcuts::kStepRecNoCut + AliHFEcuts::kNcutStepsESDtrack,weight);
-      }
+      fVarManager->FillContainer(fContainer, "recTrackContReco", AliHFEcuts::kStepRecNoCut, kFALSE);
+      fVarManager->FillContainer(fContainer, "recTrackContMC", AliHFEcuts::kStepRecNoCut, kTRUE);
     }
 
     // RecKine: ITSTPC cuts  
-    if(!ProcessCutStep(AliHFEcuts::kStepRecKineITSTPC, track, container, signal, alreadyseen, weight)) continue;
+    if(!ProcessCutStep(AliHFEcuts::kStepRecKineITSTPC, track)) continue;
     
     // Check TRD criterions (outside the correction framework)
     if(track->GetTRDncls()){
@@ -790,17 +769,10 @@ void AliAnalysisTaskHFE::ProcessESD(){
 
     
     // RecPrim
-    if(!ProcessCutStep(AliHFEcuts::kStepRecPrim, track, container, signal, alreadyseen,weight)) continue;
+    if(!ProcessCutStep(AliHFEcuts::kStepRecPrim, track)) continue;
 
     // HFEcuts: ITS layers cuts
-    if(!ProcessCutStep(AliHFEcuts::kStepHFEcutsITS, track, container, signal, alreadyseen,weight)) continue;
-
-    // HFEcuts: Nb of tracklets TRD0
-    if(!ProcessCutStep(AliHFEcuts::kStepHFEcutsTRD, track, container, signal, alreadyseen,weight)) continue;
-    if(signal) {
-      // dimensions 3&4&5 : pt,eta,phi (MC)
-      ((THnSparseF *)fCorrelation->At(0))->Fill(container);
-    }
+    if(!ProcessCutStep(AliHFEcuts::kStepHFEcutsITS, track)) continue;
 
     if(HasMCData() && IsQAOn(kMCqa)) {
       // mc qa for after the reconstruction cuts  
@@ -808,7 +780,18 @@ void AliAnalysisTaskHFE::ProcessESD(){
       fMCQA->GetDecayedKine(mctrack4QA, AliHFEmcQA::kCharm,  AliHFEmcQA::kElectronPDG, 3);  // charm
       fMCQA->GetDecayedKine(mctrack4QA, AliHFEmcQA::kBeauty,  AliHFEmcQA::kElectronPDG, 3); // beauty 
       fMCQA->GetDecayedKine(mctrack4QA, AliHFEmcQA::kOthers,  AliHFEmcQA::kElectronPDG, 3); // beauty 
-    } 
+    }
+
+    // HFEcuts: Nb of tracklets TRD0
+    if(!ProcessCutStep(AliHFEcuts::kStepHFEcutsTRD, track)) continue;
+
+    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 
+      fMCQA->GetDecayedKine(mctrack4QA, AliHFEmcQA::kOthers,  AliHFEmcQA::kElectronPDG, 4); // beauty 
+    }
 
     if(HasMCData()){
       FillProductionVertex(track);
@@ -816,98 +799,54 @@ void AliAnalysisTaskHFE::ProcessESD(){
 
     // track accepted, do PID
     AliHFEpidObject hfetrack;
-    hfetrack.fAnalysisType = AliHFEpidObject::kESDanalysis;
-    hfetrack.fRecTrack = track;
-    if(HasMCData()) hfetrack.fMCtrack = mctrack;
-    if(!fPID->IsSelected(&hfetrack)) continue;
+    hfetrack.SetAnalysisType(AliHFEpidObject::kESDanalysis);
+    hfetrack.SetRecTrack(track);
+    if(HasMCData()) hfetrack.SetMCTrack(mctrack);
+    hfetrack.SetCentrality(fCentralityF);
+    fPID->SetVarManager(fVarManager);
+    if(!fPID->IsSelected(&hfetrack, fContainer, "recTrackCont", fPIDqa)) continue;
     nElectronCandidates++;
 
     // Fill Histogram for Hadronic Background
     if(HasMCData()){
       if(mctrack && (TMath::Abs(mctrack->Particle()->GetPdgCode()) != 11))
-        fHadronicBackground->Fill(container, 0);
+        fVarManager->FillContainer(fContainer, "hadronicBackground", UInt_t(0), kFALSE);
     }
 
-    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 
-      fMCQA->GetDecayedKine(mctrack4QA, AliHFEmcQA::kOthers,  AliHFEmcQA::kElectronPDG, 4); // beauty 
-    } 
-
     // Fill Containers
     if(signal) {
       // Apply weight for background contamination
       if(fBackGroundFactorsFunction) {
-             Double_t weightBackGround = fBackGroundFactorsFunction->Eval(TMath::Abs(track->P()));
-             if(weightBackGround < 0.0) weightBackGround = 0.0;
-        else if(weightBackGround > 1.0) weightBackGround = 0.0;
-        fHadronicBackground->Fill(container, 1, weight * weightBackGround);
-      }
-      //      
-      fCFM->GetParticleContainer()->Fill(container, AliHFEcuts::kStepPID + 2*AliHFEcuts::kNcutStepsESDtrack, weight);
-      fCFM->GetParticleContainer()->Fill(&container[5], AliHFEcuts::kStepPID, weight);
-      if(alreadyseen) {
-        fCFM->GetParticleContainer()->Fill(&container[5], (AliHFEcuts::kStepPID + (AliHFEcuts::kNcutStepsESDtrack)),weight);
+       Double_t weightBackGround = fBackGroundFactorsFunction->Eval(TMath::Abs(track->P()));
+       if(weightBackGround < 0.0) weightBackGround = 0.0;
+        else if(weightBackGround > 1.0) weightBackGround = 1.0;
+        // weightBackGround as special weight
+        fVarManager->FillContainer(fContainer, "hadronicBackground", 1, kFALSE, weightBackGround);
       }
-      // dimensions 3&4&5 : pt,eta,phi (MC)
-      ((THnSparseF *)fCorrelation->At(1))->Fill(container);
+      fVarManager->FillCorrelationMatrix(fContainer->GetCorrelationMatrix("correlationstepafterPID"));
     }
 
     if(GetPlugin(kSecVtx)) {
       AliDebug(2, "Running Secondary Vertex Analysis");
-      if(track->Pt()>2.0 && nContrib > 1){ 
-        fSecVtx->InitHFEpairs();
-        fSecVtx->InitHFEsecvtxs();
-        for(Int_t jtrack = 0; jtrack < fESD->GetNumberOfTracks(); jtrack++){
-          htrack = fESD->GetTrack(jtrack);
-          if ( itrack == jtrack ) continue; // since it is for tagging single electron, don't need additional condition 
-          if (htrack->Pt()<2.0) continue;
-          if (!fCFM->CheckParticleCuts(AliHFEcuts::kStepRecKineITSTPC, htrack)) continue;
-          if (!fCFM->CheckParticleCuts(AliHFEcuts::kStepRecPrim, htrack)) continue;
-          fSecVtx->PairAnalysis(track, htrack, jtrack); // e-h pairing
-        }
-        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
-            // apply various cuts
-            if(pair->GetKFChi2()>5.) // only apply vertex chi2 cut for the moment
-            //if((pair->GetKFChi2()>5.) || !(pair->GetSignedLxy()>0. && pair->GetSignedLxy()<2.)) 
-              fSecVtx->HFEpairs()->RemoveAt(ip);
-          //}
-        }
-        fSecVtx->HFEpairs()->Compress();
-        if(fSecVtx->HFEpairs()->GetEntriesFast()) 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));
-          if(!(secvtx->GetInvmass()>2.0 && secvtx->GetInvmass()<5.2) || !(secvtx->GetSignedLxy2()>0.08 && secvtx->GetSignedLxy2()<1.5) || !(secvtx->GetKFIP2()>-0.1 && secvtx->GetKFIP2()<0.1))
-            fSecVtx->HFEsecvtxs()->RemoveAt(ip);
-          // here you apply cuts, then if it doesn't pass the cut, remove it from the fSecVtx->HFEsecvtxs() 
-        }
-        if(fSecVtx->HFEsecvtxs()->GetEntriesFast()) {
-          fQACollection->Fill("secvtxpt", track->Pt());
-          fQACollection->Fill("secvtxTPCsig", track->P(),track->GetTPCsignal());
-          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, 5);  // charm
-            fMCQA->GetDecayedKine(mctrack4QA, AliHFEmcQA::kBeauty,  AliHFEmcQA::kElectronPDG, 5); // beauty 
-            fMCQA->GetDecayedKine(mctrack4QA, AliHFEmcQA::kOthers,  AliHFEmcQA::kElectronPDG, 5); // beauty 
-          }
-        }
-        fSecVtx->DeleteHFEpairs();
-        fSecVtx->DeleteHFEsecvtxs();
-      }
+      fSecVtx->Process(track);
     }
 
     if(HasMCData()){
+      dataE[0] = track->Pt();
+      dataE[1] = track->Eta();
+      dataE[2] = track->Phi();
+      dataE[3] = track->Charge();
+      dataE[4] = -1.;
+      dataE[5] = -1.;
+
       // 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);
+        Int_t type = 0;
+        if(fSignalCuts->IsCharmElectron(track))
+          type = 1;
+        else if(fSignalCuts->IsBeautyElectron(track))
+          type = 2;
         AliDebug(1, Form("Type: %d\n", type));
         if(type){
                dataE[5] = type; // beauty[1] or charm[2]
@@ -926,7 +865,7 @@ void AliAnalysisTaskHFE::ProcessESD(){
       // 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);
+        fQACollection->Fill("PIDperformance", dataE);
       }
     }
     // Electron background analysis 
@@ -941,10 +880,22 @@ void AliAnalysisTaskHFE::ProcessESD(){
       }
     } // end of electron background analysis
 
+    if (GetPlugin(kDEstep)) { 
+      // Fill Containers for impact parameter analysis
+      if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepHFEcutsDca + AliHFEcuts::kNcutStepsMCTrack + AliHFEcuts::kNcutStepsRecTrack,track)) continue;
+      if(signal) {
+        fVarManager->FillContainer(fContainer, "recTrackContDEReco", AliHFEcuts::kStepHFEcutsDca, kFALSE);
+        fVarManager->FillContainer(fContainer, "recTrackContDEMC", AliHFEcuts::kStepHFEcutsDca, kTRUE);
+        fVarManager->FillCorrelationMatrix(fContainer->GetCorrelationMatrix("correlationstepafterDE"));
+      }
+      if(HasMCData()){
+        if(mctrack && (TMath::Abs(mctrack->Particle()->GetPdgCode()) != 11))
+          fVarManager->FillContainer(fContainer, "hadronicBackground", 2, kFALSE);
+      }
+    }
+
   }
-  fNEvents->Fill(1);
-  //fQAcoll->Fill("fNevents", 1);
-  fNElectronTracksEvent->Fill(nElectronCandidates);
+  fQACollection->Fill("nElectronTracksEvent", nElectronCandidates);
 }
 
 //____________________________________________________________
@@ -957,78 +908,82 @@ void AliAnalysisTaskHFE::ProcessAOD(){
   Double_t eventContainer[2];
   eventContainer[0] = fInputEvent->GetPrimaryVertex()->GetZ();
   eventContainer[1] = 1.; // No Information available in AOD analysis, assume all events have V0AND
-  fCFM->GetEventContainer()->Fill(eventContainer,AliHFEcuts::kEventStepRecNoCut);
-  if(!fCFM->CheckEventCuts(AliHFEcuts::kEventStepReconstructed, fInputEvent)) return;
-  fCFM->GetEventContainer()->Fill(eventContainer,AliHFEcuts::kEventStepReconstructed);
+
   AliAODEvent *fAOD = dynamic_cast<AliAODEvent *>(fInputEvent);
   if(!fAOD){
     AliError("AOD Event required for AOD Analysis")
-    return;
+      return;
   }
+  
+  //
+  fCFM->GetEventContainer()->Fill(eventContainer, AliHFEcuts::kEventStepRecNoCut);
+
+  //
+  if(fIdentifiedAsPileUp) return; 
+  fCFM->GetEventContainer()->Fill(eventContainer, AliHFEcuts::kEventStepRecNoPileUp);
+
+  //
+  if(fIdentifiedAsOutInz) return;
+  fCFM->GetEventContainer()->Fill(eventContainer, AliHFEcuts::kEventStepZRange);  
+
+  //
+  if(!fPassTheEventCut) return;
+  fCFM->GetEventContainer()->Fill(eventContainer, AliHFEcuts::kEventStepReconstructed);
+
+  fContainer->NewEvent();
  
   AliAODTrack *track = NULL;
   AliAODMCParticle *mctrack = NULL;
-  Double_t container[10]; memset(container, 0, sizeof(Double_t) * 10);
   Double_t dataE[6]; // [pT, eta, Phi, Charge, type, 'C' or 'B']
   Int_t nElectronCandidates = 0;
   Int_t pid;
+  Bool_t signal;
   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;
-    
+    signal = kTRUE;
     if(HasMCData()){
-      Int_t signalTrack = 0;
-      if((signalTrack = IsSignalElectron(track))){
-        switch(signalTrack){
-          case 1: container[4] = container[9] = kSignalCharm; break;
-          case 2: container[4] = container[9] = kSignalBeauty; break;
-        };
-      } else if(IsGammaElectron(track)) 
-        container[4] = container[9] = kGammaConv;
-      else container[4] = container[9] = kOther;
 
       Int_t label = TMath::Abs(track->GetLabel());
-      if(label){
+      if(label)
         mctrack = dynamic_cast<AliAODMCParticle *>(fMCEvent->GetTrack(label));
-        container[5] = mctrack->Pt();
-        container[6] = mctrack->Eta();
-        container[7] = mctrack->Phi();
-        container[8] = mctrack->Charge();
-      }
+        if(fFillSignalOnly && !fCFM->CheckParticleCuts(AliHFEcuts::kStepMCGenerated, mctrack)) signal = kFALSE;
     }
+    fVarManager->NewTrack(track, mctrack, fCentralityF, -1, kTRUE);
     // 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
+    hfetrack.SetAnalysisType(AliHFEpidObject::kAODanalysis);
+    hfetrack.SetRecTrack(track);
+    if(HasMCData()) hfetrack.SetMCTrack(mctrack);
+    hfetrack.SetCentrality(fCentralityF);
+    fPID->SetVarManager(fVarManager);
+    if(!fPID->IsSelected(&hfetrack, fContainer, "recTrackCont", fPIDqa)) continue;    // we will do PID here as soon as possible
     // Apply weight for background contamination
     Double_t weightBackGround = 1.0;
     if(fBackGroundFactorsFunction) {
-      weightBackGround = weightBackGround - fBackGroundFactorsFunction->Eval(TMath::Abs(track->P()));
-      if(weightBackGround < 0.0) weightBackGround = 1.0;
+      weightBackGround = fBackGroundFactorsFunction->Eval(TMath::Abs(track->P()));
+      if(weightBackGround < 0.0) weightBackGround = 0.0;
     }
-    fCFM->GetParticleContainer()->Fill(container, AliHFEcuts::kStepPID + 2*AliHFEcuts::kNcutStepsESDtrack, weightBackGround);
+    fVarManager->FillContainer(fContainer, "hadronicBackground", 1, kFALSE);
     nElectronCandidates++;    
     if(HasMCData()){
-      // Track selected: distinguish between true and fake
+      dataE[0] = track->Pt();
+      dataE[1] = track->Eta();
+      dataE[2] = track->Phi();
+      dataE[3] = track->Charge();
+      dataE[4] = -1;
+      dataE[5] = -1;
+     // 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);
+      
+        Int_t type = 0;
+        if(fSignalCuts->IsCharmElectron(track))
+          type = 1;
+        else if(fSignalCuts->IsBeautyElectron(track))
+          type = 2;
         AliDebug(1, Form("Type: %d\n", type));
         if(type){
                dataE[5] = type; // beauty[1] or charm[2]
@@ -1047,12 +1002,11 @@ void AliAnalysisTaskHFE::ProcessAOD(){
       // 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);
+        fQACollection->Fill("PIDperformance", dataE);
       }
     }
   }
-  fNEvents->Fill(1);
-  fNElectronTracksEvent->Fill(nElectronCandidates);
+  fQACollection->Fill("nElectronTracksEvent", nElectronCandidates);
 }
 
 //____________________________________________________________
@@ -1062,53 +1016,40 @@ Bool_t AliAnalysisTaskHFE::ProcessMCtrack(AliVParticle *track){
   // Additionally Fill a THnSparse for Signal To Background Studies
   // Works for AOD and MC analysis Type
   //
-  Double_t container[5], 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;
+  fVarManager->NewTrack(track, NULL, -1, kTRUE);
+  Double_t signalContainer[6];
 
-    signalContainer[0] = mctrack->Pt();
-    signalContainer[1] = mctrack->Eta();
-    signalContainer[2] = mctrack->Phi();
-    signalContainer[3] = mctrack->Charge()/3;
+  signalContainer[0] = track->Pt();
+  signalContainer[1] = track->Eta();
+  signalContainer[2] = track->Phi();
+  signalContainer[3] = track->Charge()/3;
 
+ 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);
     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);
   }
-  Int_t signal = 0;
-  if((signal = IsSignalElectron(track))){
-    switch(signal){
-      case 1: container[4] = kSignalCharm; break;
-      case 2: container[4] = kSignalBeauty; break;
-    };
-  }else if(IsGammaElectron(track)) container[4] = kGammaConv;
-  else container[4] = kOther;
-
-  // weight
-  Double_t weight = 1.0;
-  if(fWeighting) weight = FindWeight(container[0],container[1],container[2]);
-
if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepMCGenerated, track)) return kFALSE;
- fQACollection->Fill("mccharge", signalContainer[3]);
- fCFM->GetParticleContainer()->Fill(container, AliHFEcuts::kStepMCGenerated,weight);
-  if((signalContainer[4] = static_cast<Double_t >(IsSignalElectron(track))) > 1e-3) fCFM->GetParticleContainer()->Fill(container, AliHFEcuts::kStepMCsignal,weight);
+
+  if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepMCGenerated, track)) return kFALSE;
+  fQACollection->Fill("mccharge", signalContainer[3]);
+  fVarManager->FillContainer(fContainer, "MCTrackCont", AliHFEcuts::kStepMCGenerated, kFALSE);
+  signalContainer[4] = 0;
+  if(fSignalCuts->IsSelected(track)){
+    //fVarManager->FillContainer(fContainer, "MCTrackCont", AliHFEcuts::kStepMCsignal, kFALSE);
+    // Filling of the Signal/Background histogram using the 
+    // definition of the codes for charm and beauty as below in
+    // th crearion of the histogram
+    if(fSignalCuts->IsCharmElectron(track))
+      signalContainer[4] = 1;
+    else 
     signalContainer[4] = 2;
+  } else {
+    signalContainer[4] = 0; // (and other background)
+  }
   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]);
@@ -1118,41 +1059,22 @@ Bool_t AliAnalysisTaskHFE::ProcessMCtrack(AliVParticle *track){
   } else if (radVertex < 7.5){
     signalContainer[5] = 2;
   }
-  fSignalToBackgroundMC->Fill(signalContainer);
-  fQACollection->Fill("alpha_sim", container[2] - TMath::Pi());
-  //if(IsESDanalysis()){
-    if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepMCInAcceptance, track)) return kFALSE;
-    fCFM->GetParticleContainer()->Fill(container, AliHFEcuts::kStepMCInAcceptance,weight);
-  //}
+  fQACollection->Fill("SignalToBackgroundMC", signalContainer);
+  fQACollection->Fill("alpha_sim", track->Phi() - TMath::Pi());
+
+  // Step GeneratedZOutNoPileUp
+  if((fIdentifiedAsPileUp) || (fIdentifiedAsOutInz)) return kFALSE;
+  fVarManager->FillContainer(fContainer, "MCTrackCont", AliHFEcuts::kStepMCGeneratedZOutNoPileUp, kFALSE);
+
+  // Step Generated Event Cut
+  if(!fPassTheEventCut) return kFALSE;
+  fVarManager->FillContainer(fContainer, "MCTrackCont", AliHFEcuts::kStepMCGeneratedEventCut, kFALSE);
+
+  if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepMCInAcceptance, track)) return kFALSE;
+  fVarManager->FillContainer(fContainer, "MCTrackCont", AliHFEcuts::kStepMCInAcceptance, kFALSE);
   return kTRUE;
 }
 
-//____________________________________________________________
-void AliAnalysisTaskHFE::FilterTaggedTrack(AliESDtrack *track, Int_t species){
-  //
-  // Filter tracks tagged by V0 PID class
-  //
-  Int_t offset = AliHFEcuts::kStepRecKineITSTPC;
-  Double_t container[5] ={track->Pt(), track->Eta(), track->Phi(), track->Charge(), species};
-  fV0CF->GetParticleContainer()->Fill(container, 0); // Fill Container without filtering
-  Bool_t survived = kTRUE;
-  for(Int_t icut = AliHFEcuts::kStepRecKineITSTPC; icut < AliHFEcuts::kStepPID; icut++){
-    AliDebug(2, Form("Checking cut %d for species %s", icut, AliPID::ParticleName(species)));
-    if(!fV0CF->CheckParticleCuts(icut, track)){
-      survived = kFALSE;
-      break;
-    }
-    AliDebug(2, Form("Cut passed, filling container %d", icut - offset + 1));
-    fV0CF->GetParticleContainer()->Fill(container, icut - offset + 1);
-  }
-  if(survived){
-    // Apply PID
-    AliHFEpidObject hfetrack;
-    hfetrack.fAnalysisType = AliHFEpidObject::kESDanalysis;
-    hfetrack.fRecTrack = track;
-    if(fPIDtagged->IsSelected(&hfetrack)) fV0CF->GetParticleContainer()->Fill(container, AliHFEcuts::kStepPID - offset + 1); 
-  } 
-}
 //____________________________________________________________
 Bool_t AliAnalysisTaskHFE::PreSelectTrack(AliESDtrack *track) const {
   //
@@ -1186,8 +1108,8 @@ Bool_t AliAnalysisTaskHFE::PreSelectTrack(AliESDtrack *track) const {
   if(survived){
     // Apply PID
     AliHFEpidObject hfetrack;
-    hfetrack.fAnalysisType = AliHFEpidObject::kESDanalysis;
-    hfetrack.fRecTrack = track;
+    hfetrack.SetAnalysisType(AliHFEpidObject::kESDanalysis);
+    hfetrack.SetRecTrack(track);
     if(!fPIDpreselect->IsSelected(&hfetrack)) {
       //printf("Did not pass AliHFEcuts::kPID\n");
       survived = kFALSE;
@@ -1202,11 +1124,14 @@ Bool_t AliAnalysisTaskHFE::PreSelectTrack(AliESDtrack *track) const {
 void AliAnalysisTaskHFE::MakeEventContainer(){
   //
   // Create the event container for the correction framework and link it
+  // 1st bin: Vertex z-position
+  // 2nd bin: V0AND decision (normalization to sigma_inel)
+  // 3rd bin: Centrality class (for pp defined as 99.)
   //
-  const Int_t kNvar = 2;  // number of variables on the grid: 
-  Int_t nBins[kNvar] = {120, 2};
-  Double_t binMin[kNvar] = {-30. , 0.};
-  Double_t binMax[kNvar] = {30., 2.};
+  const Int_t kNvar = 3;  // number of variables on the grid: 
+  Int_t nBins[kNvar] = {120, 2, 20};
+  Double_t binMin[kNvar] = {-30. , 0., 0.};
+  Double_t binMax[kNvar] = {30., 2., 100};
 
   AliCFContainer *evCont = new AliCFContainer("eventContainer", "Container for events", AliHFEcuts::kNcutStepsEvent, kNvar, nBins);
 
@@ -1225,111 +1150,57 @@ void AliAnalysisTaskHFE::MakeParticleContainer(){
   // Create the particle container for the correction framework manager and 
   // link it
   //
-  const Int_t kNvar   = 5;
-  //number of variables on the grid:pt,eta, phi, charge
-  const Double_t kPtbound[2] = {0.1, 20.};
-  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] = 44; // bins in pt
-  iBin[1] =  8; // bins in eta 
-  iBin[2] = 18; // bins in phi
-  iBin[3] =  2; // bins in charge
-  iBin[4] =  4; // creation process of the electron
-
-  //arrays for lower bounds :
-  Double_t* binEdges[kNvar];
-  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
-  binEdges[4] = AliHFEtools::MakeLinearBinning(iBin[4], 0, iBin[4]); // Numeric precision
-  //for(Int_t ib = 0; ib <= iBin[4]; ib++) printf("%f\t", binEdges[4][ib]);
-  //printf("\n");
-
-  //one "container" for MC
-  AliCFContainer* container = new AliCFContainer("trackContainer", "Container for tracks", (AliHFEcuts::kNcutStepsTrack + 2*AliHFEcuts::kNcutStepsESDtrack), kNvar, iBin);
-  fHadronicBackground = new AliCFContainer("hadronicBackground", "Container for hadronic Background", 2, kNvar, iBin);
-
-  //setting the bin limits
-  for(Int_t ivar = 0; ivar < kNvar; ivar++){
-    container -> SetBinLimits(ivar, binEdges[ivar]);
-    fHadronicBackground -> SetBinLimits(ivar, binEdges[ivar]);
+  
+  if(!fContainer) fContainer = new AliHFEcontainer("trackContainer");
+  fVarManager->DefineVariables(fContainer);
+
+  // Create Correction Framework containers
+  fContainer->CreateContainer("MCTrackCont", "Track Container filled with MC information", AliHFEcuts::kNcutStepsMCTrack);
+  fContainer->CreateContainer("recTrackContReco", "Track Container filled with MC information", AliHFEcuts::kNcutStepsRecTrack + fPID->GetNumberOfPIDdetectors());
+  fContainer->CreateContainer("recTrackContMC", "Track Container filled with MC information", AliHFEcuts::kNcutStepsRecTrack + fPID->GetNumberOfPIDdetectors());
+  
+  fContainer->CreateContainer("hadronicBackground", "Container for Hadronic Background", 3);
+  fContainer->CreateContainer("recTrackContDEReco", "Container for displaced electron analysis with Reco information", 1);
+  fContainer->CreateContainer("recTrackContDEMC", "Container for displaced electron analysis with MC information", 1);
+  fContainer->CreateCorrelationMatrix("correlationstepafterPID","THnSparse with correlations");
+  fContainer->CreateCorrelationMatrix("correlationstepafterDE","THnSparse with correlations");
+
+  // Define the step names
+  for(UInt_t istep = 0; istep < AliHFEcuts::kNcutStepsMCTrack; istep++){
+    fContainer->SetStepTitle("MCTrackCont", AliHFEcuts::MCCutName(istep), istep);
   }
-  fCFM->SetParticleContainer(container);
-
-  //create correlation matrix for unfolding
-  Int_t thnDim[2*kNvar];
-  for (int k=0; k<kNvar; k++) {
-    //first half  : reconstructed 
-    //second half : MC
-    thnDim[k]      = iBin[k];
-    thnDim[k+kNvar] = iBin[k];
+  for(UInt_t istep = 0; istep < AliHFEcuts::kNcutStepsRecTrack; istep++){
+    fContainer->SetStepTitle("recTrackContReco", AliHFEcuts::RecoCutName(istep), istep);
+    fContainer->SetStepTitle("recTrackContMC", AliHFEcuts::RecoCutName(istep), istep);
   }
-
-  if(!fCorrelation) fCorrelation = new TList();
-  fCorrelation->SetName("correlation");
-
-  THnSparseF *correlation0 = new THnSparseF("correlationstepbeforePID","THnSparse with correlations",2*kNvar,thnDim);
-  THnSparseF *correlation1 = new THnSparseF("correlationstepafterPID","THnSparse with correlations",2*kNvar,thnDim);
-  for (int k=0; k<kNvar; k++) {
-    correlation0->SetBinEdges(k,binEdges[k]);
-    correlation0->SetBinEdges(k+kNvar,binEdges[k]);
-    correlation1->SetBinEdges(k,binEdges[k]);
-    correlation1->SetBinEdges(k+kNvar,binEdges[k]);
+  for(UInt_t ipid = 0; ipid < fPID->GetNumberOfPIDdetectors(); ipid++){
+    fContainer->SetStepTitle("recTrackContReco", fPID->SortedDetectorName(ipid), AliHFEcuts::kNcutStepsRecTrack + ipid);
+    fContainer->SetStepTitle("recTrackContMC", fPID->SortedDetectorName(ipid), AliHFEcuts::kNcutStepsRecTrack + ipid);
   }
-  correlation0->Sumw2();
-  correlation1->Sumw2();
-  
-  fCorrelation->AddAt(correlation0,0);
-  fCorrelation->AddAt(correlation1,1);
-  
+}
+
+//____________________________________________________________
+void AliAnalysisTaskHFE::InitPIDperformanceQA(){
   // Add a histogram for Fake electrons
   const Int_t nDim=6;
   Int_t nBin[nDim] = {40, 8, 18, 2, 3, 3};
-  Double_t* binEdges2[nDim];
-
-  //values for bin lower bounds
-  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]); 
-  }
-
-  // create correction framework container for V0-tagged particles, new bin limits in 4th bin
-  iBin[4] = 5;
-  delete binEdges[4];
-  binEdges[4] = AliHFEtools::MakeLinearBinning(iBin[4], 0, iBin[4]); // Numeric precision
-  AliCFContainer *tagged = new AliCFContainer("taggedTrackContainer", "Correction Framework Container for tagged tracks", AliHFEcuts::kNcutStepsESDtrack, kNvar, iBin);
-  for(Int_t ivar = 0; ivar < kNvar; ivar++)
-    tagged->SetBinLimits(ivar, binEdges[ivar]);
-  fV0CF->SetParticleContainer(tagged);
-
-  for(Int_t ivar = 0; ivar < kNvar; ivar++)
-    delete binEdges[ivar];
-  for(Int_t ivar = kNvar; ivar < nDim; ivar++)
-    delete binEdges2[ivar];
-}
+  //number of variables on the grid:pt,eta,phi,charge,
+  const Double_t kPtbound[2] = {0.1, 20.};
+  const Double_t kEtabound[2] = {-0.8, 0.8};
+  const Double_t kPhibound[2] = {0., 2. * TMath::Pi()}; 
+  const Double_t kChargebound[2] = {-1.1, 1.1};
+  const Double_t kAddInf1bound[2] = {0., 3.};
+  const Double_t kAddInf2bound[2] = {0., 3.};
+  Double_t minima[nDim] = {kPtbound[0], kEtabound[0], kPhibound[0], kChargebound[0], kAddInf1bound[0], kAddInf2bound[0]}; 
+  Double_t maxima[nDim] = {kPtbound[1], kEtabound[1], kPhibound[1], kChargebound[1], kAddInf1bound[1], kAddInf2bound[1]}; 
+  
+  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);
+  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);
 
-//____________________________________________________________
-void AliAnalysisTaskHFE::AddPIDdetector(TString detector){
-  //
-  // Adding PID detector to the task
-  //
-  if(!fPIDdetectors.Length()) 
-    fPIDdetectors = detector;
-  else
-    fPIDdetectors += ":" + detector;
+  fQACollection->BinLogAxis("PIDperformance", 0);
+  fQACollection->BinLogAxis("SignalToBackgroundMC", 0);
+  fQACollection->Sumw2("PIDperformance");
+  fQACollection->Sumw2("SignalToBackgroundMC");
 }
 
 //____________________________________________________________
@@ -1340,11 +1211,11 @@ void AliAnalysisTaskHFE::PrintStatus() const {
   printf("\n\tAnalysis Settings\n\t========================================\n\n");
   printf("\tSecondary Vertex finding: %s\n", GetPlugin(kSecVtx) ? "YES" : "NO");
   printf("\tPrimary Vertex resolution: %s\n", GetPlugin(kPriVtx) ? "YES" : "NO");
+  printf("\tDisplaced electron analysis step: %s\n", GetPlugin(kDEstep) ? "YES" : "NO");
+  printf("\tTagged Track Analysis: %s\n", GetPlugin(kTaggedTrackAnalysis) ? "YES" : "NO");
   printf("\n");
   printf("\tParticle Identification Detectors:\n");
-  TObjArray *detectors = fPIDdetectors.Tokenize(":");
-  for(Int_t idet = 0; idet < detectors->GetEntries(); idet++)
-    printf("\t\t%s\n", (dynamic_cast<TObjString *>(detectors->At(idet)))->String().Data());
+  fPID->PrintStatus();
   printf("\n");
   printf("\tQA: \n");
   printf("\t\tPID: %s\n", IsQAOn(kPIDqa) ? "YES" :  "NO");
@@ -1353,147 +1224,6 @@ void AliAnalysisTaskHFE::PrintStatus() const {
   printf("\n");
 }
 
-//____________________________________________________________
-AliAnalysisTaskHFE::LabelContainer::LabelContainer(Int_t capacity):
-  fContainer(NULL),
-  fBegin(NULL),
-  fEnd(NULL),
-  fLast(NULL),
-  fCurrent(NULL)
-{
-  //
-  // Default constructor
-  //
-  fContainer = new Int_t[capacity];
-  fBegin = &fContainer[0];
-  fEnd = &fContainer[capacity - 1];
-  fLast = fCurrent = fBegin;
-}
-
-//____________________________________________________________
-Bool_t AliAnalysisTaskHFE::LabelContainer::Append(Int_t label){
-  //
-  // Add Label to the container
-  //
-  if(fLast > fEnd) return kFALSE;
-  *fLast++ = label;
-  return kTRUE;
-}
-
-//____________________________________________________________
-Bool_t AliAnalysisTaskHFE::LabelContainer::Find(Int_t label) const {
-  //
-  // Find track in the list of labels
-  //
-  for(Int_t *entry = fBegin; entry <= fLast; entry++) 
-    if(*entry == label) return kTRUE;
-  return kFALSE;
-}
-
-//____________________________________________________________
-Int_t AliAnalysisTaskHFE::LabelContainer::Next(){
-  //
-  // Mimic iterator
-  //
-  if(fCurrent > fLast) return -1; 
-  return *fCurrent++;
-}
-
-//____________________________________________________________
-Int_t AliAnalysisTaskHFE::IsSignalElectron(const AliVParticle * const track) const{
-  //
-  // Checks whether the identified electron track is coming from heavy flavour
-  // returns 0 in case of no signal, 1 in case of charm and 2 in case of Bottom
-  //
-  enum{
-    kNoSignal = 0,
-    kCharm = 1,
-    kBeauty = 2
-  };
-
-  if(!fMCEvent) return kNoSignal;
-  const AliVParticle *motherParticle = NULL, *mctrack = NULL;
-  TString objectType = track->IsA()->GetName();
-  Int_t label = 0;
-  if(objectType.CompareTo("AliESDtrack") == 0 || objectType.CompareTo("AliAODTrack") == 0){
-    // Reconstructed track
-    if((label = TMath::Abs(track->GetLabel())) && label < fMCEvent->GetNumberOfTracks())
-      mctrack = fMCEvent->GetTrack(label);
-  } else {
-    // MCParticle
-    mctrack = track;
-  }
-
-  if(!mctrack) return kNoSignal;
-  
-  Int_t pid = 0;
-  Int_t daughterPDG = 0, motherLabel = 0;
-  if(TString(mctrack->IsA()->GetName()).CompareTo("AliMCParticle") == 0){
-    // case MC Particle
-    daughterPDG = TMath::Abs((dynamic_cast<const AliMCParticle *>(mctrack))->Particle()->GetPdgCode());
-    motherLabel = (dynamic_cast<const AliMCParticle *>(mctrack))->Particle()->GetFirstMother();
-    if(motherLabel >= 0 && motherLabel < fMCEvent->GetNumberOfTracks())
-      motherParticle = fMCEvent->GetTrack(motherLabel);
-    if(motherParticle)
-      pid = TMath::Abs((dynamic_cast<const AliMCParticle *>(motherParticle))->Particle()->GetPdgCode());
-  } else {
-    // case AODMCParticle
-    daughterPDG = TMath::Abs((dynamic_cast<const AliAODMCParticle *>(mctrack))->GetPdgCode());
-    motherLabel = (dynamic_cast<const AliAODMCParticle *>(mctrack))->GetMother();
-    if(motherLabel >= 0 && motherLabel < fMCEvent->GetNumberOfTracks())
-      motherParticle = fMCEvent->GetTrack(motherLabel);
-    if(motherParticle)
-      pid = TMath::Abs((dynamic_cast<const AliAODMCParticle *>(motherParticle))->GetPdgCode());
-  }
-  AliDebug(5, Form("Daughter PDG code: %d", daughterPDG));
-
-  if(!pid) return kNoSignal;
-
-  // From here the two analysis modes go together
-  AliDebug(5, Form("Mother PDG code: %d", pid));
-
-  // identify signal according to Pdg Code - barions higher ranked than mesons 
-  if(pid / 1000 == 4) return kCharm;            // charmed baryon, 4th position in pdg code == 4
-  if(pid / 1000 == 5) return kBeauty;           // beauty baryon, 4th position in pdg code == 5   
-  if((pid % 1000) / 100 == 4) return kCharm;    // charmed meson, 3rd position in pdg code == 4
-  if((pid % 1000) / 100 == 5) return kBeauty;   // beauty meson, 3rd position in pdg code == 5
-  return kNoSignal;
-}
-
-//__________________________________________
-Bool_t AliAnalysisTaskHFE::IsGammaElectron(const AliVParticle * const track) const {
-  //
-  // Check for MC if the electron is coming from Gamma
-  //
-  if(!fMCEvent) return kFALSE;
-  const AliVParticle *motherParticle = NULL, *mctrack = NULL;
-  TString objectType = track->IsA()->GetName();
-  if(objectType.CompareTo("AliESDtrack") == 0 || objectType.CompareTo("AliAODTrack") == 0){
-    // Reconstructed track
-    if(track->GetLabel())
-      mctrack = fMCEvent->GetTrack(TMath::Abs(track->GetLabel()));
-  } else {
-    // MCParticle
-    mctrack = track;
-  }
-
-  if(!mctrack) return kFALSE;
-  
-  Int_t motherPDG = 0;
-  if(TString(mctrack->IsA()->GetName()).CompareTo("AliMCParticle") == 0){
-    // case MC Particle
-    motherParticle = fMCEvent->GetTrack((dynamic_cast<const AliMCParticle *>(mctrack)->Particle()->GetFirstMother()));
-    if(motherParticle)
-      motherPDG = TMath::Abs((dynamic_cast<const AliMCParticle *>(motherParticle))->Particle()->GetPdgCode());
-  } else {
-    // case AODMCParticle
-    motherParticle = fMCEvent->GetTrack((dynamic_cast<const AliAODMCParticle *>(mctrack))->GetMother());
-    if(motherParticle)
-      motherPDG = TMath::Abs((dynamic_cast<const AliAODMCParticle *>(motherParticle))->GetPdgCode());
-  }
-  if(motherPDG!=22) return kFALSE;
-  else return kTRUE;
-}
 //____________________________________________________________
 Bool_t AliAnalysisTaskHFE::FillProductionVertex(const AliVParticle * const track) const{
   //
@@ -1546,71 +1276,103 @@ void AliAnalysisTaskHFE::SwitchOnPlugin(Int_t plug){
     case kSecVtx: SETBIT(fPlugins, plug); break;
     case kIsElecBackGround: SETBIT(fPlugins, plug); break;
     case kPostProcess: SETBIT(fPlugins, plug); break;
+    case kDEstep: SETBIT(fPlugins, plug); break;
+    case kTaggedTrackAnalysis: SETBIT(fPlugins, plug); break;
     default: AliError("Unknown Plugin");
   };
 }
-//_______________________________________________
-void AliAnalysisTaskHFE::SetWeightFactors(TH3D * const weightFactors){
-  //
-  // Set the histos with the weights for the efficiency maps
-  //
-  fWeighting = kTRUE;
-  fWeightFactors = weightFactors;
-}
-//_______________________________________________
-void AliAnalysisTaskHFE::SetWeightFactorsFunction(TF1 * const weightFactorsFunction){
-  //
-  // Set the histos with the weights for the efficiency maps
-  //
-  fWeighting = kTRUE;
-  fWeightFactorsFunction = weightFactorsFunction;
-  //printf("SetWeightFactors\n");
-}
-//_______________________________________________
-Double_t AliAnalysisTaskHFE::FindWeight(Double_t pt, Double_t eta, Double_t phi) const {
-  //
-  // Find the weight corresponding to pt eta and phi in the TH3D
-  //
-  Double_t weight = 1.0;
-  if(fWeightFactors) {
-    
-    TAxis *ptaxis = fWeightFactors->GetXaxis();
-    TAxis *etaaxis = fWeightFactors->GetYaxis();
-    TAxis *phiaxis = fWeightFactors->GetZaxis();
-    
-    Int_t ptbin = ptaxis->FindBin(pt);
-    Int_t etabin = etaaxis->FindBin(eta);
-    Int_t phibin = phiaxis->FindBin(phi);
-
-
-    weight = fWeightFactors->GetBinContent(ptbin,etabin,phibin);
-  }
-  else if(fWeightFactorsFunction) {
-    
-    weight = fWeightFactorsFunction->Eval(pt,eta,phi);
-    //printf("pt %f and weight %f\n",pt,weight);
-
-  }
-
-  //printf("pt %f, eta %f, phi %f, weight %f\n",pt,eta,phi,weight);
-  
-  return weight;  
-
-}
 //__________________________________________
-Bool_t AliAnalysisTaskHFE::ProcessCutStep(Int_t cutStep, AliVParticle *track, Double_t *container, Bool_t signal, Bool_t alreadyseen,Double_t weight){
+Bool_t AliAnalysisTaskHFE::ProcessCutStep(Int_t cutStep, AliVParticle *track){
   //
   // 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,weight);
-    fCFM->GetParticleContainer()->Fill(&container[5], cutStep,weight);
-    if(alreadyseen) {
-      fCFM->GetParticleContainer()->Fill(&container[5], cutStep + AliHFEcuts::kNcutStepsESDtrack,weight);
-    }
+  const Int_t kMCOffset = AliHFEcuts::kNcutStepsMCTrack;
+  if(!fCFM->CheckParticleCuts(cutStep + kMCOffset, track)) return kFALSE;
+  if(fVarManager->IsSignalTrack()) {
+    fVarManager->FillContainer(fContainer, "recTrackContReco", cutStep, kFALSE);
+    fVarManager->FillContainer(fContainer, "recTrackContMC", cutStep, kTRUE);
   }
   return kTRUE;
 }
+//___________________________________________________
+void AliAnalysisTaskHFE::ReadCentrality() {
+  //
+  // Recover the centrality of the event from ESD or AOD
+  //
+ if(IsAODanalysis()){
+
+   AliAODEvent *fAOD = dynamic_cast<AliAODEvent *>(fInputEvent);
+   if(!fAOD){
+     AliError("AOD Event required for AOD Analysis")
+       return;
+   }
+   // Centrality
+   //AliAODCentrality *aodCentrality = fAOD->GetCentrality();
+   //Double_t fCentralityF = aodCentrality->GetCentralityPercentile("V0M");
+   fCentralityF = 99.0; // Fake for the moment
+   
+   
+ } else {
+   
+   AliDebug(3, "Processing ESD Centrality");
+   AliESDEvent *fESD = dynamic_cast<AliESDEvent *>(fInputEvent);
+   if(!fESD){
+     AliError("ESD Event required for ESD Analysis")
+       return;
+   }
+   // Centrality
+  AliESDCentrality *esdCentrality = fESD->GetCentrality();
+  fCentralityF = esdCentrality->GetCentralityPercentile("V0M");
+
+  //printf("centrality %f\n",fCentralityF);
+
+ }
+
+}
+//___________________________________________________
+void AliAnalysisTaskHFE::RejectionPileUpVertexRangeEventCut() {
+  //
+  // Recover the centrality of the event from ESD or AOD
+  //
+ if(IsAODanalysis()){
+
+   AliAODEvent *fAOD = dynamic_cast<AliAODEvent *>(fInputEvent);
+   if(!fAOD){
+     AliError("AOD Event required for AOD Analysis")
+       return;
+   }
+   // PileUp
+   if(fRemovePileUp && fAOD->IsPileupFromSPD()) fIdentifiedAsPileUp = kTRUE; 
+   // Z vertex
+   if(TMath::Abs(fAOD->GetPrimaryVertex()->GetZ()) > fCuts->GetVertexRange()) fIdentifiedAsOutInz = kTRUE;
+   // Event Cut
+   fPassTheEventCut = kTRUE;
+   if(!fCFM->CheckEventCuts(AliHFEcuts::kEventStepReconstructed, fAOD)) fPassTheEventCut = kFALSE; 
+   
+   
+ } else {
+   
+   AliDebug(3, "Processing ESD Centrality");
+   AliESDEvent *fESD = dynamic_cast<AliESDEvent *>(fInputEvent);
+   if(!fESD){
+     AliError("ESD Event required for ESD Analysis")
+       return;
+   }
+   // PileUp
+   fIdentifiedAsPileUp = kFALSE;
+   if(fRemovePileUp && fESD->IsPileupFromSPD()) fIdentifiedAsPileUp = kTRUE; 
+   // Z vertex
+   fIdentifiedAsOutInz = kFALSE;
+   if(fESD->GetPrimaryVertexTracks()){
+     if(TMath::Abs(fESD->GetPrimaryVertexTracks()->GetZ()) > fCuts->GetVertexRange()) fIdentifiedAsOutInz = kTRUE;
+   }
+   //Event Cut
+   fPassTheEventCut = kTRUE;
+   if(!fCFM->CheckEventCuts(AliHFEcuts::kEventStepReconstructed, fESD)) fPassTheEventCut = kFALSE;   
+  
+
+ }
+
+}