Major update of the HFE package (comments inside the code
authorsma <sma@f7af4fe6-9843-0410-8265-dc069ae4e863>
Wed, 8 Dec 2010 16:36:42 +0000 (16:36 +0000)
committersma <sma@f7af4fe6-9843-0410-8265-dc069ae4e863>
Wed, 8 Dec 2010 16:36:42 +0000 (16:36 +0000)
and contact Markus Fasel for more questions)

72 files changed:
PWG3/hfe/AliAnalysisTaskCheckV0tender.cxx [new file with mode: 0644]
PWG3/hfe/AliAnalysisTaskCheckV0tender.h [new file with mode: 0644]
PWG3/hfe/AliAnalysisTaskCheckV0tenderII.cxx [new file with mode: 0644]
PWG3/hfe/AliAnalysisTaskCheckV0tenderII.h [new file with mode: 0644]
PWG3/hfe/AliAnalysisTaskDCA.cxx
PWG3/hfe/AliAnalysisTaskDisplacedElectrons.cxx
PWG3/hfe/AliAnalysisTaskHFE.cxx
PWG3/hfe/AliAnalysisTaskHFE.h
PWG3/hfe/AliESDv0KineCuts.cxx [new file with mode: 0644]
PWG3/hfe/AliESDv0KineCuts.h [new file with mode: 0644]
PWG3/hfe/AliHFEV0cuts.cxx
PWG3/hfe/AliHFEV0cuts.h
PWG3/hfe/AliHFEV0pid.cxx
PWG3/hfe/AliHFEV0pid.h
PWG3/hfe/AliHFEV0pidMC.cxx
PWG3/hfe/AliHFEcollection.cxx
PWG3/hfe/AliHFEcollection.h
PWG3/hfe/AliHFEcontainer.cxx
PWG3/hfe/AliHFEcontainer.h
PWG3/hfe/AliHFEcutStep.h
PWG3/hfe/AliHFEcuts.cxx
PWG3/hfe/AliHFEcuts.h
PWG3/hfe/AliHFEdetPIDqa.cxx [new file with mode: 0644]
PWG3/hfe/AliHFEdetPIDqa.h [new file with mode: 0644]
PWG3/hfe/AliHFEefficiency.cxx
PWG3/hfe/AliHFEefficiency.h
PWG3/hfe/AliHFEelecbackground.cxx
PWG3/hfe/AliHFEextraCuts.cxx
PWG3/hfe/AliHFEextraCuts.h
PWG3/hfe/AliHFEmcQA.cxx
PWG3/hfe/AliHFEpid.cxx
PWG3/hfe/AliHFEpid.h
PWG3/hfe/AliHFEpidBase.cxx
PWG3/hfe/AliHFEpidBase.h
PWG3/hfe/AliHFEpidITS.cxx
PWG3/hfe/AliHFEpidITS.h
PWG3/hfe/AliHFEpidMC.cxx
PWG3/hfe/AliHFEpidMC.h
PWG3/hfe/AliHFEpidQA.cxx
PWG3/hfe/AliHFEpidQA.h
PWG3/hfe/AliHFEpidQAmanager.cxx [new file with mode: 0644]
PWG3/hfe/AliHFEpidQAmanager.h [new file with mode: 0644]
PWG3/hfe/AliHFEpidTOF.cxx
PWG3/hfe/AliHFEpidTOF.h
PWG3/hfe/AliHFEpidTPC.cxx
PWG3/hfe/AliHFEpidTPC.h
PWG3/hfe/AliHFEpidTRD.cxx
PWG3/hfe/AliHFEpidTRD.h
PWG3/hfe/AliHFEpostAnalysis.cxx
PWG3/hfe/AliHFEpostAnalysis.h
PWG3/hfe/AliHFEpriVtx.cxx
PWG3/hfe/AliHFEpriVtx.h
PWG3/hfe/AliHFEsecVtx.cxx
PWG3/hfe/AliHFEsecVtx.h
PWG3/hfe/AliHFEsignalCuts.cxx [new file with mode: 0644]
PWG3/hfe/AliHFEsignalCuts.h [new file with mode: 0644]
PWG3/hfe/AliHFEspectrum.cxx
PWG3/hfe/AliHFEspectrum.h
PWG3/hfe/AliHFEtaggedTrackAnalysis.cxx [new file with mode: 0644]
PWG3/hfe/AliHFEtaggedTrackAnalysis.h [new file with mode: 0644]
PWG3/hfe/AliHFEtofPIDqa.cxx [new file with mode: 0644]
PWG3/hfe/AliHFEtofPIDqa.h [new file with mode: 0644]
PWG3/hfe/AliHFEtools.cxx
PWG3/hfe/AliHFEtools.h
PWG3/hfe/AliHFEtpcPIDqa.cxx [new file with mode: 0644]
PWG3/hfe/AliHFEtpcPIDqa.h [new file with mode: 0644]
PWG3/hfe/AliHFEtrdPIDqa.cxx
PWG3/hfe/AliHFEtrdPIDqa.h
PWG3/hfe/AliHFEtrdPIDqaV1.cxx [new file with mode: 0644]
PWG3/hfe/AliHFEtrdPIDqaV1.h [new file with mode: 0644]
PWG3/hfe/AliHFEvarManager.cxx [new file with mode: 0644]
PWG3/hfe/AliHFEvarManager.h [new file with mode: 0644]

diff --git a/PWG3/hfe/AliAnalysisTaskCheckV0tender.cxx b/PWG3/hfe/AliAnalysisTaskCheckV0tender.cxx
new file mode 100644 (file)
index 0000000..dbd6322
--- /dev/null
@@ -0,0 +1,471 @@
+/**************************************************************************
+* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+*                                                                        *
+* Author: The ALICE Off-line Project.                                    *
+* Contributors are mentioned in the code where appropriate.              *
+*                                                                        *
+* Permission to use, copy, modify and distribute this software and its   *
+* documentation strictly for non-commercial purposes is hereby granted   *
+* without fee, provided that the above copyright notice appears in all   *
+* copies and that both the copyright notice and this permission notice   *
+* appear in the supporting documentation. The authors make no claims     *
+* about the suitability of this software for any purpose. It is          *
+* provided "as is" without express or implied warranty.                  *
+**************************************************************************/
+//
+// Task fir checking the performance of the V0 tender
+// 
+// 
+// Authors
+//   Matus Kalisky <matus.kalisky@cern.ch>
+//
+
+#include <TH1F.h>
+#include <TList.h>
+
+#include "AliAnalysisManager.h"
+#include "AliMCEventHandler.h"
+#include "AliESDInputHandler.h"
+#include "AliESDv0.h"
+#include "AliESDtrack.h"
+#include "AliMCParticle.h"
+#include "AliMCEvent.h"
+
+#include "AliHFEtools.h"
+#include "AliHFEcollection.h"
+
+#include "AliAnalysisTaskCheckV0tender.h"
+
+ClassImp(AliAnalysisTaskCheckV0tender)
+
+//__________________________________________________________
+AliAnalysisTaskCheckV0tender::AliAnalysisTaskCheckV0tender():
+  AliAnalysisTaskSE("CheckV0tenderTask")
+  , fOutput(0x0)
+  , fColl(0x0)
+  , fCollMC(0x0)
+  , fEvents(0x0)
+{
+  //
+  // Default Constructor
+  //
+}
+//__________________________________________________________
+AliAnalysisTaskCheckV0tender::AliAnalysisTaskCheckV0tender(const Char_t *name):
+  AliAnalysisTaskSE(name)
+  , fOutput(0x0)
+  , fColl(0x0)
+  , fCollMC(0x0)
+  , fEvents(0x0)
+{
+  //
+  // Default Constructor
+  //
+  DefineOutput(1, TH1F::Class());
+  DefineOutput(2, TList::Class());
+
+}
+//__________________________________________________________
+AliAnalysisTaskCheckV0tender::~AliAnalysisTaskCheckV0tender(){
+  //
+  // Destructor
+  //
+
+  if (fOutput) delete fOutput;
+  if (fColl) delete fColl;
+  if (fCollMC) delete fCollMC;
+  if (fEvents) delete fEvents;
+}
+//__________________________________________________________
+void AliAnalysisTaskCheckV0tender::UserCreateOutputObjects(){
+  //
+  // prepare output objects
+  //
+
+  fOutput = new TList();
+  fOutput->SetOwner();
+  // Counter for number of events
+  fEvents = new TH1I("nEvents", "NumberOfEvents", 1, 1, 2);
+
+  fColl = new AliHFEcollection("V0_QA", "tender V0s for data");
+  fCollMC = new AliHFEcollection("V0_MC_QA", "tender V0s for MC");
+
+  // 
+  // Data histos
+  //
+  
+  // total number of tagged V0s
+  fColl->CreateTH1F("h_NumberOf_V0s", "Number of tagged V0s; type; counts", 4, -0.5, 3.5);
+  // pT spectra of the tagged V0s
+  fColl->CreateTH1F("h_Gamma_pt", "p_{T} spectrum of tagged gammas; p_{T} (GeV/c); counts", 20, 0.1, 20, 0);
+  fColl->CreateTH1F("h_K0_pt", "p_{T} spectrum of tagged K0s; p_{T} (GeV/c); counts", 20, 0.1, 20, 0);
+  fColl->CreateTH1F("h_Lambda_pt", "p_{T} spectrum of tagged Lambdas; p_{T} (GeV/c); counts", 20, 0.1, 20, 0);
+  fColl->CreateTH1F("h_ALambda_pt", "p_{T} spectrum of tagged A-Lambdas; p_{T} (GeV/c); counts", 20, 0.1, 20, 0);
+  // invariant mass of the V0s
+  fColl->CreateTH1F("h_Gamma_mass", "Inv. Mass of the ", 100, 0., 0.1);
+  fColl->CreateTH1F("h_K0_mass", "Inv. Mass of the ", 100, 0.45, 0.55);
+  fColl->CreateTH1F("h_Lambda_mass", "Inv. Mass of the ", 100, 1.08, 1.14);
+  fColl->CreateTH1F("h_ALambda_mass", "Inv. Mass of the ", 100, 1.08, 1.14);
+
+  // total number of tagged daughter particles (should correlate with number of V0s !
+  fColl->CreateTH1F("h_NumberOfDaughters", "Number of tagged daughters; type; counts", 3, -0.5, 2.5);
+  // pT spectra of tagged daughter particles
+  fColl->CreateTH1F("h_Electron_pt", "p_{T} spectrum of tagged; p_{T} (GeV/c); counts", 20, 0.1, 20, 0);
+  fColl->CreateTH1F("h_Pion_pt", "p_{T} spectrum of tagged; p_{T} (GeV/c); counts", 20, 0.1, 20, 0);
+  fColl->CreateTH1F("h_Proton_pt", "p_{T} spectrum of tagged; p_{T} (GeV/c); counts", 20, 0.1, 20, 0);
+
+  //
+  // MC histos
+  //
+
+  // pT spectra of the tagged V0s
+  fCollMC->CreateTH1F("h_Gamma_pt_S", "MC-S: p_{T} spectrum of tagged gammas; p_{T} (GeV/c); counts", 20, 0.1, 20, 0);
+  fCollMC->CreateTH1F("h_K0_pt_S", "MC-S: p_{T} spectrum of tagged K0s; p_{T} (GeV/c); counts", 20, 0.1, 20, 0);
+  fCollMC->CreateTH1F("h_Lambda_pt_S", "MC-S: p_{T} spectrum of tagged Lambdas; p_{T} (GeV/c); counts", 20, 0.1, 20, 0);
+  fCollMC->CreateTH1F("h_ALambda_pt_S", "MC-S: p_{T} spectrum of tagged A-Lambdas; p_{T} (GeV/c); counts", 20, 0.1, 20, 0); 
+  fCollMC->CreateTH1F("h_Gamma_pt_B", "MC-B: p_{T} spectrum of tagged gammas; p_{T} (GeV/c); counts", 20, 0.1, 20, 0);
+  fCollMC->CreateTH1F("h_K0_pt_B", "MC-B: p_{T} spectrum of tagged K0s; p_{T} (GeV/c); counts", 20, 0.1, 20, 0);
+  fCollMC->CreateTH1F("h_Lambda_pt_B", "MC-B: p_{T} spectrum of tagged Lambdas; p_{T} (GeV/c); counts", 20, 0.1, 20, 0);
+  fCollMC->CreateTH1F("h_ALambda_pt_B", "MC-B: p_{T} spectrum of tagged A-Lambdas; p_{T} (GeV/c); counts", 20, 0.1, 20, 0); 
+  // invariant mass of the V0s
+  fCollMC->CreateTH1F("h_Gamma_mass_S", "MC-S: Inv. Mass of the gamma; m (GeV/c^{2}); counts", 100, 0., 0.1);
+  fCollMC->CreateTH1F("h_K0_mass_S", "MC-S: Inv. Mass of the K0; m (GeV/c^{2}); counts", 100, 0.45, 0.55);
+  fCollMC->CreateTH1F("h_Lambda_mass_S", "MC-S: Inv. Mass of the Lambda; m (GeV/c^{2}); counts", 100, 1.08, 1.14);
+  fCollMC->CreateTH1F("h_ALambda_mass_S", "MC-S: Inv. Mass of the A-Lambda; m (GeV/c^{2}); counts", 100, 1.08, 1.14);
+  fCollMC->CreateTH1F("h_Gamma_mass_B", "MC-B: Inv. Mass of the gamma; m (GeV/c^{2}); counts", 100, 0., 0.1);
+  fCollMC->CreateTH1F("h_K0_mass_B", "MC-B: Inv. Mass of the K0; m (GeV/c^{2}); counts", 100, 0.45, 0.55);
+  fCollMC->CreateTH1F("h_Lambda_mass_B", "MC-B: Inv. Mass of the Lambda; m (GeV/c^{2}); counts", 100, 1.08, 1.14);
+  fCollMC->CreateTH1F("h_ALambda_mass_B", "MC-B: Inv. Mass of the A-Lambda; m (GeV/c^{2}); counts", 100, 1.08, 1.14);
+  // pT spectra of tagged daughter particles
+  fCollMC->CreateTH1F("h_Electron_pt_S", "MC-S: p_{T} spectrum of tagged electrons; p_{T} (GeV/c); counts", 20, 0.1, 20, 0);
+  fCollMC->CreateTH1F("h_Pion_pt_S", "MC-S: p_{T} spectrum of tagged pions; p_{T} (GeV/c); counts", 20, 0.1, 20, 0);
+  fCollMC->CreateTH1F("h_Proton_pt_S", "MC-S: p_{T} spectrum of tagged protons; p_{T} (GeV/c); counts", 20, 0.1, 20, 0);
+  fCollMC->CreateTH1F("h_Electron_pt_B", "MC-B: p_{T} spectrum of tagged electrons; p_{T} (GeV/c); counts", 20, 0.1, 20, 0);
+  fCollMC->CreateTH1F("h_Pion_pt_B", "MC-B: p_{T} spectrum of tagged pions; p_{T} (GeV/c); counts", 20, 0.1, 20, 0);
+  fCollMC->CreateTH1F("h_Proton_pt_B", "MC-B: p_{T} spectrum of tagged protons; p_{T} (GeV/c); counts", 20, 0.1, 20, 0);
+
+
+  TList *tmp = fColl->GetList();
+  tmp->SetName(fColl->GetName());
+  fOutput->Add(tmp);
+  tmp = 0x0;
+  tmp = fCollMC->GetList();
+  tmp->SetName(fCollMC->GetName());
+  fOutput->Add(tmp);
+  
+  
+}
+//__________________________________________________________
+void AliAnalysisTaskCheckV0tender::UserExec(Option_t *){
+  //
+  // Event Loop
+  // 
+  AliMCEventHandler* mcHandler = (dynamic_cast<AliMCEventHandler*>(AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler()));
+  AliESDInputHandler *inh = dynamic_cast<AliESDInputHandler *>(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler());
+  AliESDpid *workingPID = NULL;
+  if(inh && (workingPID = inh->GetESDpid())) workingPID = inh->GetESDpid();
+  else workingPID = AliHFEtools::GetDefaultPID(mcHandler ? kTRUE : kFALSE);
+     
+  // check the MC data
+  if(fMCEvent && !mcHandler ) return;
+  if(fMCEvent &&  !mcHandler->InitOk() ) return;
+  if(fMCEvent &&  !mcHandler->TreeK() ) return;
+  if(fMCEvent &&  !mcHandler->TreeTR() ) return;
+
+  ProcessV0s();
+  ProcessDaughters();
+
+  if(fMCEvent){
+    ProcessV0sMC();
+    ProcessDaughtersMC();
+  }
+
+  fEvents->Fill(1.1);
+  PostData(1, fEvents);
+  PostData(2, fOutput);
+}
+//__________________________________________________________
+void AliAnalysisTaskCheckV0tender::Terminate(Option_t *){
+  //
+  // Do Post Processing
+  //
+}
+//__________________________________________________________
+void AliAnalysisTaskCheckV0tender::ProcessV0s(){
+  //
+  // loop over the V0s and extract the information about
+  // the V0s tagged by the V0 tender
+  //
+
+  const char * type[4] = {"Gamma", "K0", "Lambda", "ALambda"};
+  char name[256] = "";
+
+  Int_t nV0s = fInputEvent->GetNumberOfV0s();
+  for(Int_t i=0; i<nV0s; ++i){
+    AliESDv0 *esdV0 = (dynamic_cast<AliESDEvent *>(fInputEvent))->GetV0(i);
+    if(!esdV0) continue;
+    if(!esdV0->GetOnFlyStatus()) continue; // Take only V0s from the On-the-fly v0 finder
+    Int_t pid = GetTenderPidV0(esdV0);
+    if(pid < 0) continue;
+    fColl->Fill("h_NumberOf_V0s", pid);
+    sprintf(name, "h_%s_pt", type[pid]);
+    Float_t pT = esdV0->Pt();
+    fColl->Fill(name, pT);
+    Float_t mass = MassV0(esdV0, pid);
+    sprintf(name, "h_%s_mass", type[pid]);
+    fColl->Fill(name, mass);
+  }
+
+}
+//__________________________________________________________
+void AliAnalysisTaskCheckV0tender::ProcessDaughters(){
+  //
+  // produce some check plots for V0 tender tagged single tracks
+  //
+
+  const char * type[3] = {"Electron", "Pion", "Proton"};
+  char name[256] = "";
+
+  Int_t nTracks = fInputEvent->GetNumberOfTracks();
+  for(Int_t i=0; i<nTracks; ++i){
+    AliESDtrack *track = dynamic_cast<AliESDtrack*>(fInputEvent->GetTrack(i));
+    if(!track) continue;
+    Int_t  pid = GetTenderPidDaughter(track);
+    if(pid < 0) continue;
+    fColl->Fill("h_NumberOfDaughters", pid*1.0);
+    Float_t pT = track->Pt();
+    sprintf(name, "h_%s_pt", type[pid]);
+    fColl->Fill(name, pT);
+    
+  }
+}
+//__________________________________________________________
+void AliAnalysisTaskCheckV0tender::ProcessV0sMC(){
+  //
+  // check all V0tender selected V0 on their true identity
+  // 
+
+  const Int_t pid2pdg[4] = {22, 310, 3122, -3122};
+  const char * type[4] = {"Gamma", "K0", "Lambda", "ALambda"};
+  char name[256] = "";
+  Int_t nV0s = fInputEvent->GetNumberOfV0s();
+
+  Int_t nTracks = fInputEvent->GetNumberOfTracks();
+
+  // V0 loop
+  for(Int_t i=0; i<nV0s; ++i){
+    Bool_t id = kFALSE;
+    AliESDv0 *esdV0 = (dynamic_cast<AliESDEvent *>(fInputEvent))->GetV0(i);
+    if(!esdV0) continue;
+    if(!esdV0->GetOnFlyStatus()) continue; // Take only V0s from the On-the-fly v0 finder
+    Int_t pid = GetTenderPidV0(esdV0);
+    if(pid < 0) continue;
+
+    // both ESD daughtr tracks
+    Int_t iN, iP;
+    iN = iP = -1;
+    iP = esdV0->GetPindex();
+    iN = esdV0->GetNindex();    
+    if(iN < 0 || iP < 0) continue;
+    if(iN >= nTracks || iP >= nTracks) continue;    
+    AliESDtrack *dP, *dN;
+    dP = dynamic_cast<AliESDtrack *>(fInputEvent->GetTrack(iP));
+    dN = dynamic_cast<AliESDtrack *>(fInputEvent->GetTrack(iN));  
+    if(!dN || !dP) continue;
+
+    // MC labels of the daughter tracks
+    Int_t lN, lP;
+    lN = dN->GetLabel();
+    lP = dP->GetLabel();
+    if(lN < 0 || lP < 0) continue;
+
+    // MC daughter particles
+    AliMCParticle *mcP, *mcN;
+    mcP = dynamic_cast<AliMCParticle*>(fMCEvent->GetTrack(lP));
+    mcN = dynamic_cast<AliMCParticle*>(fMCEvent->GetTrack(lN));
+    if(!mcP || !mcN) continue;
+
+    // labels of the mother particles
+    Int_t lPm, lNm;
+    lPm = mcP->GetMother();
+    lNm = mcN->GetMother();
+    if(lPm < 0) continue;
+    AliMCParticle *m = dynamic_cast<AliMCParticle*>(fMCEvent->GetTrack(lPm)); 
+    if(!m) continue;
+    Int_t pdg = m->PdgCode();
+    if((lPm == lNm) && (pdg == pid2pdg[pid])) id = kTRUE;
+
+    if(id) sprintf(name, "h_%s_pt_S", type[pid]);
+    else sprintf(name, "h_%s_pt_B", type[pid]);
+    Float_t pT = esdV0->Pt();
+    fCollMC->Fill(name, pT);
+
+    if(id) sprintf(name, "h_%s_mass_S", type[pid]);
+    else sprintf(name, "h_%s_mass_B", type[pid]);
+    Float_t mass = MassV0(esdV0, pid);
+    fCollMC->Fill(name, mass);
+
+   }
+}
+//__________________________________________________________
+void AliAnalysisTaskCheckV0tender::ProcessDaughtersMC(){
+  //
+  // check the identity of the V0tender selected V0 daughters
+  // !!! for positive check only the true identity plays a role here, 
+  // not the true V0 mother identity (e.g. selected electron could come
+  // from primary vertex or pion dalitz deca or true gamma conversion) !!!
+  //
+
+  const Int_t pid2pdg [3] = {11, 211, 2212};
+  const char * type[3] = {"Electron", "Pion", "Proton"};
+  char name[256] = "";
+
+
+  Int_t nTracks = fInputEvent->GetNumberOfTracks();
+  for(Int_t i=0; i<nTracks; ++i){
+    Bool_t id = kFALSE;
+    AliESDtrack *track = dynamic_cast<AliESDtrack*>(fInputEvent->GetTrack(i));
+    if(!track) continue;
+    Int_t  pid = GetTenderPidDaughter(track);
+    if(pid < 0) continue;
+    Float_t pT = track->Pt();
+    Int_t label = track->GetLabel();
+    if(label < 0) continue;
+    AliMCParticle *mcp = 0x0;
+    mcp = dynamic_cast<AliMCParticle*>(fMCEvent->GetTrack(label));
+    if(!mcp) continue;
+    Int_t pdg = TMath::Abs(mcp->PdgCode());
+    if(pdg == pid2pdg[pid]) id = kTRUE;
+    if(id) sprintf(name, "h_%s_pt_S", type[pid]);
+    else sprintf(name, "h_%s_pt_B", type[pid]);
+    fCollMC->Fill(name, pT);
+  }
+}
+//__________________________________________________________
+Int_t AliAnalysisTaskCheckV0tender::GetTenderPidV0(AliESDv0 * const v0){
+  //
+  // retrieve the PID nformation stored in the status flags by the train tender
+  // 
+  Int_t pid = -1;
+  if(!v0){
+    return pid;
+  }
+  Int_t nTimes = 0;
+  if(v0->TestBit(BIT(14))){
+    pid = 0;
+    nTimes++;
+  }
+  if(v0->TestBit(BIT(15))){
+    pid = 1;
+    nTimes++;
+  }
+  if(v0->TestBit(BIT(16))){
+    pid = 2;
+    nTimes++;
+  }
+  if(v0->TestBit(BIT(17))){
+    pid = 3;
+    nTimes++;
+  }
+  if(nTimes > 1){
+    AliWarning("V0 track labeled multiple times by the V0 tender");
+    pid = -1;
+  }    
+
+  //printf(" -D: pid: %i \n", pid);
+
+  return pid;
+}
+//__________________________________________________________
+Int_t AliAnalysisTaskCheckV0tender::GetTenderPidDaughter(AliESDtrack * const track){
+  //
+  // retrieve the PID nformation stored in the status flags by the train tender
+  // 
+
+  Int_t pid = -1;
+  if(!track){
+    return pid;
+  }
+  Int_t nTimes = 0;
+  if(track->TestBit(BIT(14))){
+    pid = 0;
+    nTimes++;
+  }
+  if(track->TestBit(BIT(15))){
+    pid = 1;
+    nTimes++;
+  }
+  if(track->TestBit(BIT(16))){
+    pid = 2;
+    nTimes++;
+  }
+  if(nTimes > 1){
+    AliWarning("V0 track labeled multiple times by the V0 tender");
+    pid = -1;
+  }    
+  return pid;
+}
+//__________________________________________________________
+Float_t AliAnalysisTaskCheckV0tender::MassV0(AliESDv0 * const v0, Int_t id){
+  //
+  // Get the V0 effective mass
+  //
+
+  Float_t mass = -0.1;
+  Bool_t sign = CheckSigns(v0);
+  if(0 == id){
+    mass = v0->GetEffMass(0, 0);
+  }
+  else if(1 == id){
+    mass = v0->GetEffMass(2, 2);
+  }
+  else if(2 == id){
+    mass = (sign) ? v0->GetEffMass(4, 2) : v0->GetEffMass(2, 4);
+  }
+  else if(3 == id){
+    mass = (sign) ? v0->GetEffMass(2, 4) : v0->GetEffMass(4, 2);
+  }
+  else{
+    AliWarning(Form("Unrecognized V0 id: %i", id));
+  }
+
+  return mass;
+
+}
+//__________________________________________________________
+Bool_t AliAnalysisTaskCheckV0tender::CheckSigns(AliESDv0 * const v0){
+  //
+  // check wheter the sign was correctly applied to 
+  // V0 daughter tracks
+  // This function should become obsolete once the V0 finder will be updated (fixed)
+  //
+  
+  Bool_t correct = kFALSE;
+
+  Int_t pIndex = 0, nIndex = 0;
+  pIndex = v0->GetPindex();
+  nIndex = v0->GetNindex();
+  
+  AliESDtrack* d[2];
+  d[0] = dynamic_cast<AliESDtrack*>(fInputEvent->GetTrack(pIndex));
+  d[1] = dynamic_cast<AliESDtrack*>(fInputEvent->GetTrack(nIndex));
+
+  Int_t sign[2];
+  sign[0] = (int)d[0]->GetSign();
+  sign[1] = (int)d[1]->GetSign();
+  
+  if(-1 == sign[0] && 1 == sign[1]){
+    correct = kFALSE;
+    //v0->SetIndex(0, pIndex);  // set the index of the negative v0 track
+    //v0->SetIndex(1, nIndex);  // set the index of the positive v0 track
+  }
+  else{
+    correct = kTRUE;
+  }
+  
+  //pIndex = v0->GetPindex();
+  //nIndex = v0->GetNindex();
+  //printf("-D2: P: %i, N: %i\n", pIndex, nIndex);
+
+  return correct;
+}
diff --git a/PWG3/hfe/AliAnalysisTaskCheckV0tender.h b/PWG3/hfe/AliAnalysisTaskCheckV0tender.h
new file mode 100644 (file)
index 0000000..05de205
--- /dev/null
@@ -0,0 +1,78 @@
+/**************************************************************************
+* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+*                                                                        *
+* Author: The ALICE Off-line Project.                                    *
+* Contributors are mentioned in the code where appropriate.              *
+*                                                                        *
+* Permission to use, copy, modify and distribute this software and its   *
+* documentation strictly for non-commercial purposes is hereby granted   *
+* without fee, provided that the above copyright notice appears in all   *
+* copies and that both the copyright notice and this permission notice   *
+* appear in the supporting documentation. The authors make no claims     *
+* about the suitability of this software for any purpose. It is          *
+* provided "as is" without express or implied warranty.                  *
+**************************************************************************/
+//
+// Task for PID QA
+// Using AliHFEpidQA and AliHFEMCpidQA
+// More information can be found in the source file
+//
+#ifndef ALIANALYSISTASKCHECKV0TENDER_H
+#define ALIANALYSISTASKCHECKV0TENDER_H
+
+#ifndef ALIANALYSISTASKSE_H
+#include "AliAnalysisTaskSE.h"
+#endif
+
+class TH1F;
+class TList;
+class AliHFEcollection;
+
+class AliAnalysisTaskCheckV0tender : public AliAnalysisTaskSE{
+ public:
+   enum{ // Reconstructed V0
+      kRecoGamma = 0,
+      kRecoK0 = 1,
+      kRecoLambda = 2,
+      kRecoALambda = 3
+      
+      };
+  enum{ // Identified Daughter particles
+    kRecoElectron = 0,
+      kRecoPionK0 = 1,
+      kRecoPionL = 2,
+      kRecoProton = 3
+      };
+
+  AliAnalysisTaskCheckV0tender();
+  AliAnalysisTaskCheckV0tender(const Char_t *name);
+  ~AliAnalysisTaskCheckV0tender();
+  
+  virtual void UserCreateOutputObjects();
+  virtual void UserExec(Option_t *);
+  virtual void Terminate(Option_t *);
+  
+  void ProcessV0s();
+  void ProcessDaughters();
+  void ProcessV0sMC();
+  void ProcessDaughtersMC();
+
+  Int_t GetTenderPidV0(AliESDv0 * const v0);
+  Int_t GetTenderPidDaughter(AliESDtrack * const track);
+
+ private:
+  AliAnalysisTaskCheckV0tender(const AliAnalysisTaskCheckV0tender &ref);
+  AliAnalysisTaskCheckV0tender &operator=(const AliAnalysisTaskCheckV0tender &ref);
+
+  Float_t MassV0(AliESDv0 * const v0, Int_t id);
+  Bool_t CheckSigns(AliESDv0 * const v0);
+  TList *fOutput;            //! Container for output histos
+  AliHFEcollection *fColl;   //! collection of Data output
+  AliHFEcollection *fCollMC; //! collection of MC output
+  TH1 *fEvents;              //! Number of Events
+  ClassDef(AliAnalysisTaskCheckV0tender, 1)
+
+};
+
+#endif
diff --git a/PWG3/hfe/AliAnalysisTaskCheckV0tenderII.cxx b/PWG3/hfe/AliAnalysisTaskCheckV0tenderII.cxx
new file mode 100644 (file)
index 0000000..9fe9060
--- /dev/null
@@ -0,0 +1,503 @@
+/**************************************************************************
+* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+*                                                                        *
+* Author: The ALICE Off-line Project.                                    *
+* Contributors are mentioned in the code where appropriate.              *
+*                                                                        *
+* Permission to use, copy, modify and distribute this software and its   *
+* documentation strictly for non-commercial purposes is hereby granted   *
+* without fee, provided that the above copyright notice appears in all   *
+* copies and that both the copyright notice and this permission notice   *
+* appear in the supporting documentation. The authors make no claims     *
+* about the suitability of this software for any purpose. It is          *
+* provided "as is" without express or implied warranty.                  *
+**************************************************************************/
+//
+// Task fir checking the performance of the V0 tender
+// 
+// 
+// Authors
+//   Matus Kalisky <matus.kalisky@cern.ch>
+//
+
+#include <TH1F.h>
+#include <TList.h>
+
+#include "AliAnalysisManager.h"
+#include "AliMCEventHandler.h"
+#include "AliESDInputHandler.h"
+#include "AliESDv0.h"
+#include "AliESDtrack.h"
+#include "AliMCParticle.h"
+#include "AliMCEvent.h"
+#include "AliESDv0KineCuts.h"
+#include "AliKFVertex.h"
+
+#include "AliHFEtools.h"
+#include "AliHFEcollection.h"
+
+#include "AliAnalysisTaskCheckV0tenderII.h"
+
+ClassImp(AliAnalysisTaskCheckV0tenderII)
+
+//__________________________________________________________
+AliAnalysisTaskCheckV0tenderII::AliAnalysisTaskCheckV0tenderII():
+  AliAnalysisTaskSE("CheckV0tenderTask")
+  , fOutput(0x0)
+  , fColl(0x0)
+  , fCollMC(0x0)
+  , fV0cuts(0x0)
+  , fPrimaryVertex(0x0)
+  , fpdgV0(0)
+  , fpdgP(0)
+  , fpdgN(0)
+  , fEvents(0x0)
+{
+  //
+  // Default Constructor
+  //
+
+
+  DefineOutput(1, TH1F::Class());
+  DefineOutput(2, TList::Class());
+
+
+}
+//__________________________________________________________
+AliAnalysisTaskCheckV0tenderII::AliAnalysisTaskCheckV0tenderII(const Char_t *name):
+  AliAnalysisTaskSE(name)
+  , fOutput(0x0)
+  , fColl(0x0)
+  , fCollMC(0x0)
+  , fV0cuts(0x0)
+  , fPrimaryVertex(0x0)
+  , fpdgV0(0)
+  , fpdgP(0)
+  , fpdgN(0)
+  , fEvents(0x0)
+{
+  //
+  // Constructor
+  //
+
+  DefineOutput(1, TH1F::Class());
+  DefineOutput(2, TList::Class());
+
+}
+//__________________________________________________________
+AliAnalysisTaskCheckV0tenderII::~AliAnalysisTaskCheckV0tenderII(){
+  //
+  // Destructor
+  //
+
+  if (fOutput) delete fOutput;
+  if (fColl) delete fColl;
+  if (fCollMC) delete fCollMC;
+  if (fV0cuts) delete fV0cuts;
+  if (fPrimaryVertex) delete fPrimaryVertex;
+  if (fEvents) delete fEvents;
+}
+//__________________________________________________________
+void AliAnalysisTaskCheckV0tenderII::UserCreateOutputObjects(){
+  //
+  // prepare output objects
+  //
+
+  fOutput = new TList();
+  //fOutput->SetOwner();
+  // Counter for number of events
+  fEvents = new TH1I("nEvents", "NumberOfEvents", 1, 1, 2);
+
+  fColl = new AliHFEcollection("V0_QA", "tender V0s for data");
+  fCollMC = new AliHFEcollection("V0_MC_QA", "tender V0s for MC");
+
+  fV0cuts = new AliESDv0KineCuts();
+  if(!fV0cuts){
+    AliError("Failed to initialize AliESDv0KineCuts instance");
+    return;
+  }
+
+  // 
+  // Data histos
+  //
+  
+  // total number of tagged V0s
+  fColl->CreateTH1F("h_NumberOf_V0s", "Number of tagged V0s; type; counts", 4, -0.5, 3.5);
+  // pT spectra of the tagged V0s
+  fColl->CreateTH1F("h_Gamma_pt", "p_{T} spectrum of tagged gammas; p_{T} (GeV/c); counts", 20, 0.1, 20, 0);
+  fColl->CreateTH1F("h_K0_pt", "p_{T} spectrum of tagged K0s; p_{T} (GeV/c); counts", 20, 0.1, 20, 0);
+  fColl->CreateTH1F("h_Lambda_pt", "p_{T} spectrum of tagged Lambdas; p_{T} (GeV/c); counts", 20, 0.1, 20, 0);
+  fColl->CreateTH1F("h_ALambda_pt", "p_{T} spectrum of tagged A-Lambdas; p_{T} (GeV/c); counts", 20, 0.1, 20, 0);
+  // invariant mass of the V0s
+  fColl->CreateTH1F("h_Gamma_mass", "Inv. Mass of the ", 100, 0., 0.1);
+  fColl->CreateTH1F("h_K0_mass", "Inv. Mass of the ", 100, 0.45, 0.55);
+  fColl->CreateTH1F("h_Lambda_mass", "Inv. Mass of the ", 100, 1.08, 1.14);
+  fColl->CreateTH1F("h_ALambda_mass", "Inv. Mass of the ", 100, 1.08, 1.14);
+
+  // total number of tagged daughter particles (should correlate with number of V0s !
+  fColl->CreateTH1F("h_NumberOfDaughters", "Number of tagged daughters; type; counts", 3, -0.5, 2.5);
+  // pT spectra of tagged daughter particles
+  fColl->CreateTH1F("h_Electron_pt", "p_{T} spectrum of tagged; p_{T} (GeV/c); counts", 20, 0.1, 20, 0);
+  fColl->CreateTH1F("h_Pion_pt", "p_{T} spectrum of tagged; p_{T} (GeV/c); counts", 20, 0.1, 20, 0);
+  fColl->CreateTH1F("h_Proton_pt", "p_{T} spectrum of tagged; p_{T} (GeV/c); counts", 20, 0.1, 20, 0);
+
+  //
+  // MC histos
+  //
+
+  // pT spectra of the tagged V0s
+  fCollMC->CreateTH1F("h_Gamma_pt_S", "MC-S: p_{T} spectrum of tagged gammas; p_{T} (GeV/c); counts", 20, 0.1, 20, 0);
+  fCollMC->CreateTH1F("h_K0_pt_S", "MC-S: p_{T} spectrum of tagged K0s; p_{T} (GeV/c); counts", 20, 0.1, 20, 0);
+  fCollMC->CreateTH1F("h_Lambda_pt_S", "MC-S: p_{T} spectrum of tagged Lambdas; p_{T} (GeV/c); counts", 20, 0.1, 20, 0);
+  fCollMC->CreateTH1F("h_ALambda_pt_S", "MC-S: p_{T} spectrum of tagged A-Lambdas; p_{T} (GeV/c); counts", 20, 0.1, 20, 0); 
+  fCollMC->CreateTH1F("h_Gamma_pt_B", "MC-B: p_{T} spectrum of tagged gammas; p_{T} (GeV/c); counts", 20, 0.1, 20, 0);
+  fCollMC->CreateTH1F("h_K0_pt_B", "MC-B: p_{T} spectrum of tagged K0s; p_{T} (GeV/c); counts", 20, 0.1, 20, 0);
+  fCollMC->CreateTH1F("h_Lambda_pt_B", "MC-B: p_{T} spectrum of tagged Lambdas; p_{T} (GeV/c); counts", 20, 0.1, 20, 0);
+  fCollMC->CreateTH1F("h_ALambda_pt_B", "MC-B: p_{T} spectrum of tagged A-Lambdas; p_{T} (GeV/c); counts", 20, 0.1, 20, 0); 
+  // invariant mass of the V0s
+  fCollMC->CreateTH1F("h_Gamma_mass_S", "MC-S: Inv. Mass of the gamma; m (GeV/c^{2}); counts", 100, 0., 0.1);
+  fCollMC->CreateTH1F("h_K0_mass_S", "MC-S: Inv. Mass of the K0; m (GeV/c^{2}); counts", 100, 0.45, 0.55);
+  fCollMC->CreateTH1F("h_Lambda_mass_S", "MC-S: Inv. Mass of the Lambda; m (GeV/c^{2}); counts", 100, 1.08, 1.14);
+  fCollMC->CreateTH1F("h_ALambda_mass_S", "MC-S: Inv. Mass of the A-Lambda; m (GeV/c^{2}); counts", 100, 1.08, 1.14);
+  fCollMC->CreateTH1F("h_Gamma_mass_B", "MC-B: Inv. Mass of the gamma; m (GeV/c^{2}); counts", 100, 0., 0.1);
+  fCollMC->CreateTH1F("h_K0_mass_B", "MC-B: Inv. Mass of the K0; m (GeV/c^{2}); counts", 100, 0.45, 0.55);
+  fCollMC->CreateTH1F("h_Lambda_mass_B", "MC-B: Inv. Mass of the Lambda; m (GeV/c^{2}); counts", 100, 1.08, 1.14);
+  fCollMC->CreateTH1F("h_ALambda_mass_B", "MC-B: Inv. Mass of the A-Lambda; m (GeV/c^{2}); counts", 100, 1.08, 1.14);
+  // pT spectra of tagged daughter particles
+  fCollMC->CreateTH1F("h_Electron_pt_S", "MC-S: p_{T} spectrum of tagged electrons; p_{T} (GeV/c); counts", 20, 0.1, 20, 0);
+  fCollMC->CreateTH1F("h_Pion_pt_S", "MC-S: p_{T} spectrum of tagged pions; p_{T} (GeV/c); counts", 20, 0.1, 20, 0);
+  fCollMC->CreateTH1F("h_Proton_pt_S", "MC-S: p_{T} spectrum of tagged protons; p_{T} (GeV/c); counts", 20, 0.1, 20, 0);
+  fCollMC->CreateTH1F("h_Electron_pt_B", "MC-B: p_{T} spectrum of tagged electrons; p_{T} (GeV/c); counts", 20, 0.1, 20, 0);
+  fCollMC->CreateTH1F("h_Pion_pt_B", "MC-B: p_{T} spectrum of tagged pions; p_{T} (GeV/c); counts", 20, 0.1, 20, 0);
+  fCollMC->CreateTH1F("h_Proton_pt_B", "MC-B: p_{T} spectrum of tagged protons; p_{T} (GeV/c); counts", 20, 0.1, 20, 0);
+
+
+  TList *tmp = fColl->GetList();
+  tmp->SetName(fColl->GetName());
+  fOutput->Add(tmp);
+  tmp = 0x0;
+  tmp = fCollMC->GetList();
+  tmp->SetName(fCollMC->GetName());
+  fOutput->Add(tmp);
+  
+  
+}
+//__________________________________________________________
+void AliAnalysisTaskCheckV0tenderII::UserExec(Option_t *){
+  //
+  // Event Loop
+  // 
+  AliMCEventHandler* mcHandler = (dynamic_cast<AliMCEventHandler*>(AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler()));
+  AliESDInputHandler *inh = dynamic_cast<AliESDInputHandler *>(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler());
+  AliESDpid *workingPID = NULL;
+  if(inh && (workingPID = inh->GetESDpid())) workingPID = inh->GetESDpid();
+  else workingPID = AliHFEtools::GetDefaultPID(mcHandler ? kTRUE : kFALSE);
+     
+  // check the MC data
+  if(fMCEvent && !mcHandler ) return;
+  if(fMCEvent &&  !mcHandler->InitOk() ) return;
+  if(fMCEvent &&  !mcHandler->TreeK() ) return;
+  if(fMCEvent &&  !mcHandler->TreeTR() ) return;
+
+  fPrimaryVertex = new AliKFVertex(*(fInputEvent->GetPrimaryVertex()));
+  if(!fPrimaryVertex) return;
+
+  fV0cuts->SetEvent(fInputEvent);
+  fV0cuts->SetPrimaryVertex(fPrimaryVertex);
+
+  ProcessV0s();
+
+  fEvents->Fill(1.1);
+  PostData(1, fEvents);
+  PostData(2, fOutput);
+}
+//__________________________________________________________
+void AliAnalysisTaskCheckV0tenderII::Terminate(Option_t *){
+  //
+  // Do Post Processing
+  //
+}
+//__________________________________________________________
+void AliAnalysisTaskCheckV0tenderII::ProcessV0s(){
+  //
+  // loop over the V0s and extract the information about
+  // the V0s tagged by the V0 tender
+  //
+
+  const char * type[4] = {"Gamma", "K0", "Lambda", "ALambda"};
+  char name[256] = "";
+
+  Int_t nV0s = fInputEvent->GetNumberOfV0s();
+  for(Int_t i=0; i<nV0s; ++i){
+    AliESDv0 *esdV0 = (dynamic_cast<AliESDEvent *>(fInputEvent))->GetV0(i);
+    if(!esdV0) continue;
+    if(!esdV0->GetOnFlyStatus()) continue; // Take only V0s from the On-the-fly v0 finder
+
+    // New standalone V0 selection software
+    if( ! (fV0cuts->ProcessV0(esdV0, fpdgV0, fpdgP, fpdgN)) ) return;
+    
+    Int_t pid = PDGtoPIDv0(fpdgV0);
+    //printf(" -D: pdg: %i, pid: %i\n", fpdgV0, pid);
+    if(pid <= -1) continue;
+    
+    fColl->Fill("h_NumberOf_V0s", pid);
+    sprintf(name, "h_%s_pt", type[pid]);
+    Float_t pT = esdV0->Pt();
+    fColl->Fill(name, pT);
+    Float_t mass = MassV0(esdV0, pid);
+    sprintf(name, "h_%s_mass", type[pid]);
+    fColl->Fill(name, mass);
+
+    ProcessDaughters(esdV0);
+    if(fMCEvent){
+      ProcessV0sMC(esdV0);
+      ProcessDaughtersMC(esdV0);
+    }
+
+  }
+
+}
+//__________________________________________________________
+void AliAnalysisTaskCheckV0tenderII::ProcessDaughters(AliESDv0 * const v0){
+  //
+  // produce some check plots for V0 tender tagged single tracks
+  //
+
+  const char * type[3] = {"Electron", "Pion", "Proton"};
+  char name[256] = "";
+
+  if(!v0) return;
+
+  // daughter tracks
+  const Int_t nTracks = fInputEvent->GetNumberOfTracks();
+  AliESDtrack *d[2];
+  Int_t iN, iP;
+  iN = iP = -1;
+  iP = v0->GetPindex();
+  iN = v0->GetNindex();
+  if(iN < 0 || iP < 0) return;
+  if(iN >= nTracks || iP >= nTracks) return;
+  d[0] = dynamic_cast<AliESDtrack *>(fInputEvent->GetTrack(iP));
+  d[1] = dynamic_cast<AliESDtrack *>(fInputEvent->GetTrack(iN));  
+  if(!d[0] || !d[1]) return;
+
+  for(Int_t i=0; i<2; ++i){
+    Int_t  pid = (i == 0) ? PDGtoPID(fpdgP) : PDGtoPID(fpdgN);
+    if(pid < 0) continue;
+    fColl->Fill("h_NumberOfDaughters", pid*1.0);
+    Float_t pT = d[i]->Pt();
+    sprintf(name, "h_%s_pt", type[pid]);
+    fColl->Fill(name, pT);
+
+  }
+}
+//__________________________________________________________
+void AliAnalysisTaskCheckV0tenderII::ProcessV0sMC(AliESDv0 * const v0){
+  //
+  // check all V0tender selected V0 on their true identity
+  // 
+
+  const char * type[4] = {"Gamma", "K0", "Lambda", "ALambda"};
+  char name[256] = "";
+
+  
+  Int_t pid = PDGtoPIDv0(fpdgV0);
+  if(pid < 0) return;
+
+  // true if fpdgV0 agrees with MC pdg of the mother
+  Bool_t id = kFALSE;
+  const Int_t nTracks = fInputEvent->GetNumberOfTracks();
+  // both ESD daughtr tracks
+  Int_t iN, iP;
+  iN = iP = -1;
+  iP = v0->GetPindex();
+  iN = v0->GetNindex();    
+  if(iN < 0 || iP < 0) return;
+  if(iN >= nTracks || iP >= nTracks) return;    
+  AliESDtrack *dP, *dN;
+  dP = dynamic_cast<AliESDtrack *>(fInputEvent->GetTrack(iP));
+  dN = dynamic_cast<AliESDtrack *>(fInputEvent->GetTrack(iN));  
+  if(!dN || !dP) return;
+
+  // MC labels of the daughter tracks
+  Int_t lN, lP;
+  lN = dN->GetLabel();
+  lP = dP->GetLabel();
+  if(lN < 0 || lP < 0) return;
+
+  // MC daughter particles
+  AliMCParticle *mcP, *mcN;
+  mcP = dynamic_cast<AliMCParticle*>(fMCEvent->GetTrack(lP));
+  mcN = dynamic_cast<AliMCParticle*>(fMCEvent->GetTrack(lN));
+  if(!mcP || !mcN) return;
+
+  // labels of the mother particles
+  Int_t lPm, lNm;
+  lPm = mcP->GetMother();
+  lNm = mcN->GetMother();
+  AliMCParticle *m = 0x0;
+  // particles without mother particle are most probably
+  // primary particles
+  if(lPm >= 0){
+    m = dynamic_cast<AliMCParticle*>(fMCEvent->GetTrack(lPm)); 
+    if(!m) return;
+  }
+  if(m){
+    Int_t pdg = m->PdgCode();
+    //if(lPm == lNm) printf(" -D: pdg: %i, fpdgV0: %i \n", pdg, fpdgV0);
+    if((lPm == lNm) && (pdg == fpdgV0)) id = kTRUE;
+  }
+  
+  if(id) sprintf(name, "h_%s_pt_S", type[pid]);
+  else sprintf(name, "h_%s_pt_B", type[pid]);
+  Float_t pT = v0->Pt();
+  fCollMC->Fill(name, pT);
+
+  if(id) sprintf(name, "h_%s_mass_S", type[pid]);
+  else sprintf(name, "h_%s_mass_B", type[pid]);
+  Float_t mass = MassV0(v0, pid);
+  fCollMC->Fill(name, mass);
+
+  
+}
+//__________________________________________________________
+void AliAnalysisTaskCheckV0tenderII::ProcessDaughtersMC(AliESDv0 * const v0){
+  //
+  // check the identity of the V0tender selected V0 daughters
+  // !!! for positive check only the true identity plays a role here, 
+  // not the true V0 mother identity (e.g. selected electron could come
+  // from primary vertex or pion dalitz deca or true gamma conversion) !!!
+  //
+
+  const char * type[3] = {"Electron", "Pion", "Proton"};
+  char name[256] = "";
+
+  if(!v0) return;
+
+  // daughter tracks
+  const Int_t nTracks = fInputEvent->GetNumberOfTracks();
+  AliESDtrack *d[2];
+  Int_t iN, iP;
+  iN = iP = -1;
+  iP = v0->GetPindex();
+  iN = v0->GetNindex();
+  if(iN < 0 || iP < 0) return;
+  if(iN >= nTracks || iP >= nTracks) return;
+  d[0] = dynamic_cast<AliESDtrack *>(fInputEvent->GetTrack(iP));
+  d[1] = dynamic_cast<AliESDtrack *>(fInputEvent->GetTrack(iN));  
+  if(!d[0] || !d[1]) return;
+
+  //printf(" *** fpdgV0: %i, fpdgP: %i, fpdgN: %i \n", fpdgV0, fpdgP, fpdgN);
+
+  for(Int_t i=0; i<2; ++i){
+    Bool_t id = kFALSE;
+    Int_t  pid = (i == 0) ? PDGtoPID(fpdgP) : PDGtoPID(fpdgN);
+    Int_t  pdg  = (i == 0) ? fpdgP : fpdgN;
+    if(pid < 0) continue;
+    Float_t pT = d[i]->Pt();
+    Int_t label = d[i]->GetLabel();
+    if(label < 0) continue;
+    AliMCParticle *mcp = 0x0;
+    mcp = dynamic_cast<AliMCParticle*>(fMCEvent->GetTrack(label));
+    if(!mcp) continue;
+    Int_t pdgMC = mcp->PdgCode();
+    //printf("   * pid: %i, pdg: %i, pdgMC: %i \n", pid, pdg, pdgMC);
+    if(pdgMC == pdg) id = kTRUE;
+    if(id) sprintf(name, "h_%s_pt_S", type[pid]);
+    else sprintf(name, "h_%s_pt_B", type[pid]);
+    fCollMC->Fill(name, pT);
+  }
+}
+//__________________________________________________________
+Float_t AliAnalysisTaskCheckV0tenderII::MassV0(AliESDv0 * const v0, Int_t id){
+  //
+  // Get the V0 effective mass
+  //
+
+  Float_t mass = -0.1;
+  Bool_t sign = CheckSigns(v0);
+  if(0 == id){
+    mass = v0->GetEffMass(0, 0);
+  }
+  else if(1 == id){
+    mass = v0->GetEffMass(2, 2);
+  }
+  else if(2 == id){
+    mass = (sign) ? v0->GetEffMass(4, 2) : v0->GetEffMass(2, 4);
+  }
+  else if(3 == id){
+    mass = (sign) ? v0->GetEffMass(2, 4) : v0->GetEffMass(4, 2);
+  }
+  else{
+    AliWarning(Form("Unrecognized V0 id: %i", id));
+  }
+
+  return mass;
+
+}
+//__________________________________________________________
+Bool_t AliAnalysisTaskCheckV0tenderII::CheckSigns(AliESDv0 * const v0){
+  //
+  // check wheter the sign was correctly applied to 
+  // V0 daughter tracks
+  // This function should become obsolete once the V0 finder will be updated (fixed)
+  //
+  
+  Bool_t correct = kFALSE;
+
+  Int_t pIndex = 0, nIndex = 0;
+  pIndex = v0->GetPindex();
+  nIndex = v0->GetNindex();
+  
+  AliESDtrack* d[2];
+  d[0] = dynamic_cast<AliESDtrack*>(fInputEvent->GetTrack(pIndex));
+  d[1] = dynamic_cast<AliESDtrack*>(fInputEvent->GetTrack(nIndex));
+
+  Int_t sign[2];
+  sign[0] = (int)d[0]->GetSign();
+  sign[1] = (int)d[1]->GetSign();
+  
+  if(-1 == sign[0] && 1 == sign[1]){
+    correct = kFALSE;
+    //v0->SetIndex(0, pIndex);  // set the index of the negative v0 track
+    //v0->SetIndex(1, nIndex);  // set the index of the positive v0 track
+  }
+  else{
+    correct = kTRUE;
+  }
+  
+  //pIndex = v0->GetPindex();
+  //nIndex = v0->GetNindex();
+  //printf("-D2: P: %i, N: %i\n", pIndex, nIndex);
+
+  return correct;
+}
+//__________________________________________________________
+const Int_t  AliAnalysisTaskCheckV0tenderII::PDGtoPIDv0(Int_t pdgV0){
+  //
+  // convert thereconstructed V0 pdg to local pid
+  //
+
+  switch(pdgV0){
+  case 22: return 0; break;
+  case 310: return 1; break;
+  case 3122: return 2; break;
+  case -3122: return 3; break;
+  }
+  
+  return -1;
+
+}
+//__________________________________________________________
+const Int_t  AliAnalysisTaskCheckV0tenderII::PDGtoPID(Int_t pdg){
+  //
+  // convert daughter pdg code to local pid
+  //
+  switch(TMath::Abs(pdg)){
+  case 11: return 0; break;
+  case 211: return 1; break;
+  case 2212: return 2; break;
+  }
+  return -1;
+
+}
diff --git a/PWG3/hfe/AliAnalysisTaskCheckV0tenderII.h b/PWG3/hfe/AliAnalysisTaskCheckV0tenderII.h
new file mode 100644 (file)
index 0000000..5563d7a
--- /dev/null
@@ -0,0 +1,90 @@
+/**************************************************************************
+* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+*                                                                        *
+* Author: The ALICE Off-line Project.                                    *
+* Contributors are mentioned in the code where appropriate.              *
+*                                                                        *
+* Permission to use, copy, modify and distribute this software and its   *
+* documentation strictly for non-commercial purposes is hereby granted   *
+* without fee, provided that the above copyright notice appears in all   *
+* copies and that both the copyright notice and this permission notice   *
+* appear in the supporting documentation. The authors make no claims     *
+* about the suitability of this software for any purpose. It is          *
+* provided "as is" without express or implied warranty.                  *
+**************************************************************************/
+//
+// Task for PID QA
+// Using AliHFEpidQA and AliHFEMCpidQA
+// More information can be found in the source file
+//
+#ifndef ALIANALYSISTASKCHECKV0TENDERII_H
+#define ALIANALYSISTASKCHECKV0TENDERII_H
+
+#ifndef ALIANALYSISTASKSE_H
+#include "AliAnalysisTaskSE.h"
+#endif
+
+class TH1F;
+class TList;
+class AliHFEcollection;
+class AliESDv0KineCuts;
+class AliKFVertex;
+
+class AliAnalysisTaskCheckV0tenderII : public AliAnalysisTaskSE{
+ public:
+   enum{ // Reconstructed V0
+      kRecoGamma = 0,
+      kRecoK0 = 1,
+      kRecoLambda = 2,
+      kRecoALambda = 3
+      
+      };
+  enum{ // Identified Daughter particles
+    kRecoElectron = 0,
+      kRecoPionK0 = 1,
+      kRecoPionL = 2,
+      kRecoProton = 3
+      };
+
+  AliAnalysisTaskCheckV0tenderII();
+  AliAnalysisTaskCheckV0tenderII(const Char_t *name);
+  ~AliAnalysisTaskCheckV0tenderII();
+  
+  virtual void UserCreateOutputObjects();
+  virtual void UserExec(Option_t *);
+  virtual void Terminate(Option_t *);
+  
+  void ProcessV0s();
+  void ProcessDaughters(AliESDv0 * const v0);
+  void ProcessV0sMC(AliESDv0 * const v0);
+  void ProcessDaughtersMC(AliESDv0 * const v0);
+
+ private:
+  AliAnalysisTaskCheckV0tenderII(const AliAnalysisTaskCheckV0tenderII &ref);
+  AliAnalysisTaskCheckV0tenderII &operator=(const AliAnalysisTaskCheckV0tenderII &ref);
+
+  Float_t MassV0(AliESDv0 * const v0, Int_t id);
+  Bool_t  CheckSigns(AliESDv0 * const v0);
+
+  const Int_t   PDGtoPIDv0(Int_t pdgV0);
+  const Int_t   PDGtoPID(Int_t pdg);
+  
+
+  TList              *fOutput;        //! Container for output histos
+  AliHFEcollection   *fColl;          //! collection of Data output
+  AliHFEcollection   *fCollMC;        //! collection of MC output
+  AliESDv0KineCuts   *fV0cuts;        //! standalone V0 selection class
+  AliKFVertex        *fPrimaryVertex; //! primary vertex of the current event
+
+  Int_t               fpdgV0;  // PDG code of teh reconstructed V0
+  Int_t               fpdgP;   // PDG code of the positive daughter (sign corrected)
+  Int_t               fpdgN;   // PDG code of the negative daughter (sign coreccted)
+  
+  TH1 *fEvents;              //! Number of Events
+
+  ClassDef(AliAnalysisTaskCheckV0tenderII, 1)
+
+};
+
+#endif
index 2e9c2dd..3fee448 100644 (file)
@@ -322,11 +322,8 @@ void AliAnalysisTaskDCA::UserCreateOutputObjects(){
   
   if(fHFEpid && GetPlugin(kHFEpid)) {      
     fHFEpid->SetHasMCData(HasMCData());
-    if(!fPIDdetectors.Length() && ! fPIDstrategy) AddPIDdetector("TPC");
-    if(fPIDstrategy)
-      fHFEpid->InitializePID(Form("Strategy%d", fPIDstrategy));
-    else
-      fHFEpid->InitializePID(fPIDdetectors.Data());     // Only restrictions to TPC allowed 
+    fHFEpid->AddDetector("TPC", 0);
+    fHFEpid->InitializePID();
   }
 
   // dca study----------------------------------
@@ -502,19 +499,19 @@ void AliAnalysisTaskDCA::ProcessDcaAnalysis(){
     if(HasMCData())mctrack = dynamic_cast<AliMCParticle *>(fMC->GetTrack(TMath::Abs(track->GetLabel())));
 
     // RecPrim: primary cuts
-    if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepRecPrim, track)) continue;
+    if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepRecPrim + AliHFEcuts::kNcutStepsMCTrack, track)) continue;
     // RecKine: ITSTPC cuts  
-    if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepRecKineITSTPC, track)) continue;
+    if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepRecKineITSTPC + AliHFEcuts::kNcutStepsMCTrack, track)) continue;
     // HFEcuts: ITS layers cuts
-    if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepHFEcutsITS, track)) continue;
+    if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepHFEcutsITS + AliHFEcuts::kNcutStepsMCTrack, track)) continue;
     
     if(track->GetITSclusters(0)<=fNclustersITS) continue;  // require number of ITS clusters
     
     // track accepted, do PID
     AliHFEpidObject hfetrack;
-    hfetrack.fAnalysisType = AliHFEpidObject::kESDanalysis;
-    hfetrack.fRecTrack = track;
-    if(HasMCData()) hfetrack.fMCtrack = mctrack;
+    hfetrack.SetAnalysisType(AliHFEpidObject::kESDanalysis);
+    hfetrack.SetRecTrack(track);
+    if(HasMCData()) hfetrack.SetMCTrack(mctrack);
 
     if(HasMCData()){
       if(GetPlugin(kPrimVtx))
@@ -691,7 +688,9 @@ void AliAnalysisTaskDCA::MakeParticleContainer(){
   for(Int_t i=0; i<=iBin[2]; i++) binEdges[2][i]=(Double_t)kPhimin  + (kPhimax-kPhimin)/iBin[2]*(Double_t)i;
 
   //one "container" for MC
-  AliCFContainer* container = new AliCFContainer("container","container for tracks", (AliHFEcuts::kNcutStepsTrack + 1 + 2*(AliHFEcuts::kNcutStepsESDtrack + 1)), kNvar, iBin);
+  const Int_t kNcutStepsESDtrack = AliHFEcuts::kNcutStepsRecTrack + 1;
+  const Int_t kNcutStepsTrack = AliHFEcuts::kNcutStepsMCTrack + kNcutStepsESDtrack;
+  AliCFContainer* container = new AliCFContainer("container","container for tracks", (kNcutStepsTrack + 1 + 2*(kNcutStepsESDtrack + 1)), kNvar, iBin);
 
   //setting the bin limits
   for(Int_t ivar = 0; ivar < kNvar; ivar++)
index 6ea0a9b..f302ebf 100644 (file)
@@ -89,7 +89,7 @@ AliAnalysisTaskDisplacedElectrons::AliAnalysisTaskDisplacedElectrons():
   // Initialize pid
   
   fDeDefaultPID = new AliESDpid;
-  fDePID = new AliHFEpid;
+  fDePID = new AliHFEpid("DEPID");
   
 
 }
@@ -126,7 +126,7 @@ AliAnalysisTaskDisplacedElectrons::AliAnalysisTaskDisplacedElectrons(const char
 
   // Initialize pid
   fDeDefaultPID = new AliESDpid;
-  fDePID = new AliHFEpid;
+  fDePID = new AliHFEpid("DEPID");
 
 }
 
@@ -196,7 +196,7 @@ AliAnalysisTaskDisplacedElectrons::~AliAnalysisTaskDisplacedElectrons(){
   if(fDePID) delete fDePID;
   if(fDeCFM) delete fDeCFM;
   if(fDisplacedElectrons) delete fDisplacedElectrons;  
+  return;
   if(fDeNEvents) delete fDeNEvents;
   if(fElectronsMcPt) delete fElectronsMcPt;
   if(fElectronsEsdPt) delete fElectronsEsdPt;
@@ -264,20 +264,13 @@ void AliAnalysisTaskDisplacedElectrons::UserCreateOutputObjects(){
   
   fDeCuts->Initialize(fDeCFM);
   
-  if(GetPlugin(kDePidQA)){
-    AliInfo("PID QA switched on");
-    // fPID->SetDebugLevel(2);
-    fDePID->SetQAOn();
-    fDeQA->Add(fDePID->GetQAhistograms());
-  }  
-
   fDePID->SetHasMCData(HasMCData());
-  if(!fDePIDdetectors.Length() && ! fDePIDstrategy) AddPIDdetector("TPC");
-  if(fDePIDstrategy)
-    fDePID->InitializePID(Form("Strategy%d", fDePIDstrategy));
-  else
-    fDePID->InitializePID(fDePIDdetectors.Data());     // Only restrictions to TPC allowed 
-  
+  fDePID->AddDetector("TPC", 0);
+  fDePID->AddDetector("TOF", 1);
+  fDePID->ConfigureTPCrejection();
+  fDePID->InitializePID();     // Only restrictions to TPC allowed   
+
+
   // displaced electron study----------------------------------
   if(GetPlugin(kDisplacedElectrons)){
     
@@ -319,13 +312,14 @@ void AliAnalysisTaskDisplacedElectrons::UserExec(Option_t *){
   // from now on, only ESD are analyzed
   // using HFE pid, using HFE cuts
   // using CORRFW
-  
   AliESDpid *workingPID = inH->GetESDpid();
   if(workingPID){
     AliDebug(1, "Using ESD PID from the input handler");
+    //printf("\n ESD PID\n");
     fDePID->SetESDpid(workingPID);
   } else { 
     AliDebug(1, "Using default ESD PID");
+    //printf(" DEFAULT PID!\n\n");
     fDePID->SetESDpid(AliHFEtools::GetDefaultPID(HasMCData()));
   }
 
@@ -459,6 +453,8 @@ void AliAnalysisTaskDisplacedElectrons::ProcessESD(){
   
   // process data: ESD tracks with MC information
   
+  const Int_t kStepPID = AliHFEcuts::kStepHFEcutsTRD + 1;
+
   Double_t esdContainer[4];   // container for the output in THnSparse
   memset(esdContainer, 0, sizeof(Double_t) * 4);
   AliESDEvent *fESD = dynamic_cast<AliESDEvent *>(fInputEvent);
@@ -499,43 +495,43 @@ void AliAnalysisTaskDisplacedElectrons::ProcessESD(){
       alreadyseen = cont.Find(TMath::Abs(track->GetLabel()));  
       cont.Append(TMath::Abs(track->GetLabel()));  // check double counting
       if(alreadyseen) continue;  // avoid double counting
-      if(GetPlugin(kCorrection)) fDeCFM->GetParticleContainer()->Fill(esdContainer, 1+AliHFEcuts::kStepRecNoCut);      
+      if(GetPlugin(kCorrection)) fDeCFM->GetParticleContainer()->Fill(esdContainer, 1+AliHFEcuts::kStepRecNoCut + AliHFEcuts::kNcutStepsMCTrack);      
       
       // 1st track cut
       // RecKine: ITSTPC cuts : ITS & TPC refit, covmatrix: (2, 2, 0.5, 0.5, 2); min_tpccls: 50, chi2_tpccls: 3.5
-      if(!fDeCFM->CheckParticleCuts(AliHFEcuts::kStepRecKineITSTPC, track)) continue;
-      if(GetPlugin(kCorrection)) fDeCFM->GetParticleContainer()->Fill(esdContainer, 1+AliHFEcuts::kStepRecKineITSTPC);
+      if(!fDeCFM->CheckParticleCuts(AliHFEcuts::kStepRecKineITSTPC + AliHFEcuts::kNcutStepsMCTrack, track)) continue;
+      if(GetPlugin(kCorrection)) fDeCFM->GetParticleContainer()->Fill(esdContainer, 1+AliHFEcuts::kStepRecKineITSTPC + AliHFEcuts::kNcutStepsMCTrack);
       
       // 2nd track cut
       // RecPrim: cut on track quality : DCA to vertex max: 3cm and 10cm; reject kink daughters
-      if(!fDeCFM->CheckParticleCuts(AliHFEcuts::kStepRecPrim, track)) continue;
-      if(GetPlugin(kCorrection)) fDeCFM->GetParticleContainer()->Fill(esdContainer, 1+AliHFEcuts::kStepRecPrim);
+      if(!fDeCFM->CheckParticleCuts(AliHFEcuts::kStepRecPrim + AliHFEcuts::kNcutStepsMCTrack, track)) continue;
+      if(GetPlugin(kCorrection)) fDeCFM->GetParticleContainer()->Fill(esdContainer, 1+AliHFEcuts::kStepRecPrim + AliHFEcuts::kNcutStepsMCTrack);
       
       // 3rd track cut
       // HFEcuts: ITS layers cuts: ITS pixel layer: kFirst, kSecond, kBoth, kNone or kAny
-      if(!fDeCFM->CheckParticleCuts(AliHFEcuts::kStepHFEcutsITS, track)) continue;
-      if(GetPlugin(kCorrection))fDeCFM->GetParticleContainer()->Fill(esdContainer, 1+AliHFEcuts::kStepHFEcutsITS);
+      if(!fDeCFM->CheckParticleCuts(AliHFEcuts::kStepHFEcutsITS + AliHFEcuts::kNcutStepsMCTrack, track)) continue;
+      if(GetPlugin(kCorrection))fDeCFM->GetParticleContainer()->Fill(esdContainer, 1+AliHFEcuts::kStepHFEcutsITS + AliHFEcuts::kNcutStepsMCTrack);
 
       /*
       //  4th track cut
       // TRD: number of tracklets in TRD
-      if(!fDeCFM->CheckParticleCuts(AliHFEcuts::kStepHFEcutsTRD, track)) continue;
-      if(GetPlugin(kCorrection)) fDeCFM->GetParticleContainer()->Fill(esdContainer, 1+AliHFEcuts::kStepHFEcutsTRD);
+      if(!fDeCFM->CheckParticleCuts(AliHFEcuts::kStepHFEcutsTRD + AliHFEcuts::kNcutStepsMCTrack, track)) continue;
+      if(GetPlugin(kCorrection)) fDeCFM->GetParticleContainer()->Fill(esdContainer, 1+AliHFEcuts::kStepHFEcutsTRD + AliHFEcuts::kNcutStepsMCTrack);
       */
       
       // 5th track cut
       // track accepted, do PID 
       // --> only electron candidate will be processed
       AliHFEpidObject hfetrack;
-      hfetrack.fAnalysisType = AliHFEpidObject::kESDanalysis;
-      hfetrack.fRecTrack = track;
-      //      if(HasMCData())hfetrack.fMCtrack = mctrack;
+      hfetrack.SetAnalysisType(AliHFEpidObject::kESDanalysis);
+      hfetrack.SetRecTrack(track);
+      //if(HasMCData())hfetrack.SetMCTrack(mctrack);
       
       if(!fDePID->IsSelected(&hfetrack)) continue;
       else if(fDeDebugLevel>=10)
        AliInfo("ESD info: this particle is identified as electron by HFEpid method \n");
-      if(GetPlugin(kCorrection)) fDeCFM->GetParticleContainer()->Fill(esdContainer, 1+AliHFEcuts::kStepPID);
-      
+      if(GetPlugin(kCorrection)) fDeCFM->GetParticleContainer()->Fill(esdContainer, 1+kStepPID + AliHFEcuts::kNcutStepsMCTrack);
+    
       // Fill Containers
       nHFEelectrons++;
       fElectronsEsdPt->Fill(esdContainer[0]);
@@ -556,6 +552,10 @@ void AliAnalysisTaskDisplacedElectrons::ProcessData(){
   // this is a track loop over real data 
   // no MC information at all 
   // HFE pid is used
+  
+  const Int_t kNcutStepsESDtrack = AliHFEcuts::kNcutStepsRecTrack + 1;
+  //const Int_t kNcutStepsTrack = AliHFEcuts::kNcutStepsMCTrack + kNcutStepsESDtrack;
+  const Int_t kStepPID = AliHFEcuts::kStepHFEcutsTRD + 1;
 
   AliESDEvent *fESD = dynamic_cast<AliESDEvent *>(fInputEvent);
   if(!fESD){
@@ -593,32 +593,32 @@ void AliAnalysisTaskDisplacedElectrons::ProcessData(){
       cont.Append(TMath::Abs(track->GetLabel()));
       if(alreadyseen) continue;  // avoid double counting
       if(GetPlugin(kCorrection))fDeCFM->GetParticleContainer()->Fill(&dataContainer[4], 
-                                                                    1+AliHFEcuts::kStepRecNoCut + AliHFEcuts::kNcutStepsESDtrack);
+                                                                    1+AliHFEcuts::kStepRecNoCut + AliHFEcuts::kNcutStepsMCTrack + kNcutStepsESDtrack);
 
       // 1st track cut
       // RecKine: ITSTPC cuts : ITS & TPC refit, covmatrix: (2, 2, 0.5, 0.5, 2); min_tpccls: 50, chi2_tpccls: 3.5
-      if(!fDeCFM->CheckParticleCuts(AliHFEcuts::kStepRecKineITSTPC, track)) continue;
+      if(!fDeCFM->CheckParticleCuts(AliHFEcuts::kStepRecKineITSTPC + AliHFEcuts::kNcutStepsMCTrack, track)) continue;
       if(GetPlugin(kCorrection)) fDeCFM->GetParticleContainer()->Fill(&dataContainer[4], 
-                                                                     1+AliHFEcuts::kStepRecKineITSTPC + AliHFEcuts::kNcutStepsESDtrack);
+                                                                     1+AliHFEcuts::kStepRecKineITSTPC + AliHFEcuts::kNcutStepsMCTrack + kNcutStepsESDtrack);
       
       // 2nd track cut
       // RecPrim: cut on track quality : DCA to vertex max: 3cm and 10cm; reject kink daughters
-      if(!fDeCFM->CheckParticleCuts(AliHFEcuts::kStepRecPrim, track))  continue;
+      if(!fDeCFM->CheckParticleCuts(AliHFEcuts::kStepRecPrim + AliHFEcuts::kNcutStepsMCTrack, track))  continue;
       if(GetPlugin(kCorrection)) fDeCFM->GetParticleContainer()->Fill(&dataContainer[4], 
-                                                                     1+AliHFEcuts::kStepRecPrim + AliHFEcuts::kNcutStepsESDtrack);
+                                                                     1+AliHFEcuts::kStepRecPrim + AliHFEcuts::kNcutStepsMCTrack + kNcutStepsESDtrack);
        
       //  3rd track cut
       // HFEcuts: ITS layers cuts: ITS pixel layer: kFirst, kSecond, kBoth, kNone or kAny
       if(!fDeCFM->CheckParticleCuts(AliHFEcuts::kStepHFEcutsITS, track)) continue;
       if(GetPlugin(kCorrection)) fDeCFM->GetParticleContainer()->Fill(&dataContainer[4],
-                                                                     1+AliHFEcuts::kStepHFEcutsITS + AliHFEcuts::kNcutStepsESDtrack);
+                                                                     1+AliHFEcuts::kStepHFEcutsITS + AliHFEcuts::kNcutStepsMCTrack + kNcutStepsESDtrack);
       
       /*
       //  4th track cut
       // TRD: number of tracklets in TRD0
-      if(!fDeCFM->CheckParticleCuts(AliHFEcuts::kStepHFEcutsTRD, track)) continue;
+      if(!fDeCFM->CheckParticleCuts(AliHFEcuts::kStepHFEcutsTRD + AliHFEcuts::kNcutStepsMCTrack, track)) continue;
       if(GetPlugin(kCorrection)) if(HasMCData())fDeCFM->GetParticleContainer()->Fill(&dataContainer[4], 
-                                                                                    1+AliHFEcuts::kStepHFEcutsTRD + AliHFEcuts::kNcutStepsESDtrack);
+                                                                                    1+AliHFEcuts::kStepHFEcutsTRD + AliHFEcuts::kNcutStepsMCTrack + kNcutStepsESDtrack);
       */
 
 
@@ -626,14 +626,13 @@ void AliAnalysisTaskDisplacedElectrons::ProcessData(){
       // track accepted, do PID --> only electron candidate will be processed
 
       AliHFEpidObject hfetrack;
-      hfetrack.fAnalysisType = AliHFEpidObject::kESDanalysis;
-      hfetrack.fRecTrack = track;
-      //      if(HasMCData())hfetrack.fMCtrack = mctrack;
+      hfetrack.SetAnalysisType(AliHFEpidObject::kESDanalysis);
+      hfetrack.SetRecTrack(track);
       
       if(!fDePID->IsSelected(&hfetrack)) continue;
       else if(fDeDebugLevel>=10)
        AliInfo("ESD info: this particle is identified as electron by HFEpid method \n");
-      if(GetPlugin(kCorrection)) fDeCFM->GetParticleContainer()->Fill(dataContainer,  1+AliHFEcuts::kStepPID + AliHFEcuts::kNcutStepsESDtrack);
+      if(GetPlugin(kCorrection)) fDeCFM->GetParticleContainer()->Fill(dataContainer,  1+kStepPID + AliHFEcuts::kNcutStepsMCTrack + kNcutStepsESDtrack);
 
       nHFEelectrons++;
       fElectronsDataPt->Fill(dataContainer[0]);
@@ -717,6 +716,9 @@ void AliAnalysisTaskDisplacedElectrons::MakeParticleContainer(){
   // Create the particle container for the correction framework manager and 
   // link it
   //
+  const Int_t kNcutStepsESDtrack = AliHFEcuts::kNcutStepsRecTrack + 1;
+  const Int_t kNcutStepsTrack = AliHFEcuts::kNcutStepsMCTrack + kNcutStepsESDtrack;
   const Int_t kNvar   = 4;
   //number of variables on the grid:pt,eta, phi, charge
   const Double_t kPtbound[2] = {0.1, 10.};
@@ -761,7 +763,7 @@ void AliAnalysisTaskDisplacedElectrons::MakeParticleContainer(){
   //------------------------------------------------
 
   AliCFContainer* container = new AliCFContainer("deTrackContainer", "Container for tracks", 
-                                                (1 + AliHFEcuts::kNcutStepsTrack + AliHFEcuts::kNcutStepsESDtrack), kNvar, iBin);
+                                                (1 + kNcutStepsTrack + kNcutStepsESDtrack), kNvar, iBin);
   
   //setting the bin limits
   for(Int_t ivar = 0; ivar < kNvar; ivar++){
index ab885fb..5084850 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,42 +1059,23 @@ 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 {
   //
   // Preselect tracks
@@ -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");
@@ -1354,147 +1225,6 @@ void AliAnalysisTaskHFE::PrintStatus() const {
 }
 
 //____________________________________________________________
-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{
   //
   // Find the production vertex of the associated MC track
@@ -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;   
+  
+
+ }
+
+}
 
index cef17b1..10d0f28 100644 (file)
 #include "AliAnalysisTaskSE.h"
 #endif
 
-#ifndef ROOT_THnSparse
-#include <THnSparse.h>
-#endif
-
-class AliHFEpid;
+class AliHFEcontainer;
+class AliHFEcollection;
 class AliHFEcuts;
+class AliHFEelecbackground;
 class AliHFEmcQA;
+class AliHFEpid;
+class AliHFEpidQAmanager;
 class AliHFEsecVtx;
-class AliHFEelecbackground;
-class AliHFEcollection;
+class AliHFEsignalCuts;
+class AliHFEvarManager;
+class AliHFEtaggedTrackAnalysis;
 class AliCFManager;
 class AliVEvent;
 class AliMCEvent;
@@ -41,8 +42,6 @@ class AliVParticle;
 class AliTriggerAnalysis;
 class TH1I; 
 class TList;
-class TH3D;
-class TF1;
 
 class AliAnalysisTaskHFE : public AliAnalysisTaskSE{
   public:
@@ -54,7 +53,9 @@ class AliAnalysisTaskHFE : public AliAnalysisTaskSE{
       kPriVtx = 0,
       kSecVtx = 1,
       kIsElecBackGround = 2,
-      kPostProcess = 3
+      kPostProcess = 3,
+      kDEstep = 4,
+      kTaggedTrackAnalysis = 5
     };
     enum CreationProcess_t{
       kSignalCharm = 0,
@@ -80,95 +81,77 @@ class AliAnalysisTaskHFE : public AliAnalysisTaskSE{
     Bool_t IsESDanalysis() const { return !TestBit(kAODanalysis); };
     Bool_t HasMCData() const { return TestBit(kHasMCdata); }
     Bool_t GetPlugin(Int_t plug) const { return TESTBIT(fPlugins, plug); };
+
+    // Get Components for configuration
+    AliHFEvarManager *GetVarManager() const { return fVarManager; }
+    AliHFEpid *GetPID() const { return fPID; }
+
     void SetHFECuts(AliHFEcuts * const cuts) { fCuts = cuts; };
+    void SetTaggedTrackCuts(AliHFEcuts * const cuts) { fTaggedTrackCuts = cuts; }
     void SetHFECutsPreselect(AliHFEcuts * const cuts) { fCutspreselect = cuts; };
     void SetHFEElecBackGround(AliHFEelecbackground * const elecBackGround) { fElecBackGround = elecBackGround; };
     void SetQAOn(Int_t qaLevel) { SETBIT(fQAlevel, qaLevel); };
     void SwitchOnPlugin(Int_t plug);
     void SetHasMCData(Bool_t hasMC = kTRUE) { SetBit(kHasMCdata, hasMC); };
-    void SetPIDdetectors(Char_t * const detectors){ fPIDdetectors = detectors; }
-    void SetPIDStrategy(UInt_t strategy) { fPIDstrategy = strategy; }
+    void SetFillSignalOnly(Bool_t signalOnly) { fFillSignalOnly = signalOnly; }
+    void SetRemovePileUp(Bool_t removePileUp) { fRemovePileUp = removePileUp; }
     void SetPIDPreselect(AliHFEpid * const cuts) { fPIDpreselect = cuts; };
-    void AddPIDdetector(TString detector);
     void SetAODAnalysis() { SetBit(kAODanalysis, kTRUE); };
     void SetESDAnalysis() { SetBit(kAODanalysis, kFALSE); };
-    void SetWeightFactors(TH3D * const weightFactors);
-    void SetWeightFactorsFunction(TF1 * const weightFactorsFunction);
     void SetBackGroundFactorsFunction(TF1 * const backGroundFactorsFunction) { fBackGroundFactorsFunction = backGroundFactorsFunction; };
     void PrintStatus() const;
+    void ReadCentrality();
+    void RejectionPileUpVertexRangeEventCut();  
  
   private:
     enum{
       kHasMCdata = BIT(19),
       kAODanalysis = BIT(20)
     };
-    class LabelContainer{
-      public:
-        LabelContainer(Int_t capacity);
-        ~LabelContainer() {delete[] fContainer; };
-
-        Bool_t Append(Int_t label);
-        Bool_t Find(Int_t Label) const;
-        Int_t Next();
-        void ResetIterator(){ fCurrent = fBegin; }
 
-      private:
-        LabelContainer(const LabelContainer &);
-        LabelContainer &operator=(const LabelContainer &);
-        Int_t *fContainer;    // the Container for the labels
-        Int_t *fBegin;        // Pointer to the first entry
-        Int_t *fEnd;          // Pointer to the end of the container
-        Int_t *fLast;         // Pointer to the last entry
-        Int_t *fCurrent;      // Current entry to mimic an iterator
-    };
-
-    Bool_t IsGammaElectron(const AliVParticle * const track) const;
-    Int_t  IsSignalElectron(const AliVParticle * const track) const;
     Bool_t FillProductionVertex(const AliVParticle * const track) const;
-    Double_t FindWeight(Double_t pt, Double_t eta, Double_t phi) const;
     void MakeParticleContainer();
     void MakeEventContainer();
+    void InitPIDperformanceQA();
     void ProcessMC();
     void ProcessESD();
     void ProcessAOD();
-    void FilterTaggedTrack(AliESDtrack *track, Int_t species);
     Bool_t PreSelectTrack(AliESDtrack *track) const;
     Bool_t ProcessMCtrack(AliVParticle *track);
-    Bool_t ProcessCutStep(Int_t cutStep, AliVParticle *track, Double_t *container, Bool_t signal, Bool_t alreadyseen,Double_t weight);
-    
+    Bool_t ProcessCutStep(Int_t cutStep, AliVParticle *track);
     ULong_t fQAlevel;                     // QA level
-    TString fPIDdetectors;                // Detectors for Particle Identification
-    UInt_t fPIDstrategy;                  // PID Strategy
-    Double_t fTPCBetheBlochParameters[5]; // TPC Bethe-Bloch Parameters
     UShort_t fPlugins;                    // Enabled Plugins
-    Bool_t  fWeighting;                   // Weighting or not for the efficiency maps
-    TH3D *fWeightFactors;                 // Weight factors
-    TF1  *fWeightFactorsFunction;         // Weight factors
+    Bool_t fFillSignalOnly;               // Fill container only with MC Signal Tracks
+    Bool_t fRemovePileUp;                 // Remove Pile Up
+    Bool_t fIdentifiedAsPileUp;           // Identified as pile-up
+    Bool_t fIdentifiedAsOutInz;           // Out Of Range in z
+    Bool_t fPassTheEventCut;              // Pass The Event Cut
+    Float_t fCentralityF;                 // Centrality
     TF1  *fBackGroundFactorsFunction;     // BackGround factors
+    AliHFEcontainer *fContainer;          //! The HFE container
+    AliHFEvarManager *fVarManager;        // The var manager as the backbone of the analysis
+    AliHFEsignalCuts *fSignalCuts;        //! MC true signal (electron coming from certain source) 
     AliCFManager *fCFM;                   //! Correction Framework Manager
-    AliCFManager *fV0CF;                  //! Correction Framework Manager for V0-tagged tracks
     AliTriggerAnalysis *fTriggerAnalysis; //! Trigger Analysis for Normalisation
-    AliCFContainer * fHadronicBackground; //! Container for hadronic Background
-    TList *fCorrelation;                  //! response matrix for unfolding  
-    THnSparseF *fPIDperformance;          //! info on contamination and yield of electron spectra
-    THnSparseF *fSignalToBackgroundMC;    //! Signal To Background Studies on pure MC information
-    AliHFEpid *fPID;                      //! PID
-    AliHFEpid *fPIDtagged;                // PID oject for tagged tracks (identical clone without QA)
+    AliHFEpid *fPID;                      // PID
+    AliHFEpidQAmanager *fPIDqa;           //! PID QA
     AliHFEpid *fPIDpreselect;             // PID oject for pre-selected tracks (without QA)
     AliHFEcuts *fCuts;                    // Cut Collection
-    AliHFEcuts *fCutsTagged;              // Cut Collection for tagged tracks
+    AliHFEcuts *fTaggedTrackCuts;         // Cut Collection for V0 tagged tracks
     AliHFEcuts *fCutspreselect;           // Cut Collection for pre-selected tracks
     AliHFEsecVtx *fSecVtx;                //! Secondary Vertex Analysis
     AliHFEelecbackground *fElecBackGround;//! Background analysis
     AliHFEmcQA *fMCQA;                    //! MC QA
-    TH1I *fNEvents;                       //! counter for the number of Events
-    TH1I *fNElectronTracksEvent;          //! Number of Electron candidates after PID decision per Event
+    AliHFEtaggedTrackAnalysis *fTaggedTrackAnalysis;     //!Analyse V0-tagged tracks
+
+    //-----------QA and output---------------
     TList *fQA;                           //! QA histos for the cuts
     TList *fOutput;                       //! Container for Task Output
     TList *fHistMCQA;                     //! Output container for MC QA histograms 
     TList *fHistSECVTX;                   //! Output container for sec. vertexing results
     TList *fHistELECBACKGROUND;           //! Output container for electron background analysis
     AliHFEcollection *fQACollection;      //! Tasks own QA collection
+    //---------------------------------------
 
     ClassDef(AliAnalysisTaskHFE, 2)       // The electron Analysis Task
 };
diff --git a/PWG3/hfe/AliESDv0KineCuts.cxx b/PWG3/hfe/AliESDv0KineCuts.cxx
new file mode 100644 (file)
index 0000000..a06da10
--- /dev/null
@@ -0,0 +1,902 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+/*
+ * author: M.Kalisky@gsi.de
+ * 08/Dec/2010
+ *
+ * Description: This class allows with purely kinematical cuts
+ * to select clean samples of electrons, pions and protons from the
+ * V0 online finder ESD V0 candidates for PID and dectero resonse
+ * studies.
+ */
+
+#include <TVector3.h>
+#include <TDatabasePDG.h>
+
+#include "AliESDv0.h"
+#include "AliESDtrack.h"
+#include "AliESDEvent.h"
+#include "AliLog.h"
+#include "AliKFParticle.h"
+#include "AliVTrack.h"
+#include "AliKFVertex.h"
+
+#include "AliESDv0KineCuts.h"
+
+ClassImp(AliESDv0KineCuts)
+
+//____________________________________________________________________
+AliESDv0KineCuts::AliESDv0KineCuts() :
+  fV0(0x0)
+  , fEvent(0x0)
+  , fPrimaryVertex(0x0)
+{
+  //
+  // Default constructor
+  //
+
+}
+//____________________________________________________________________
+AliESDv0KineCuts::~AliESDv0KineCuts(){
+  //
+  // Destructor
+  //
+
+  if (fV0) delete fV0;
+
+}
+//____________________________________________________________________
+AliESDv0KineCuts::AliESDv0KineCuts(const AliESDv0KineCuts &ref):
+  TObject(ref)
+  , fV0(0x0)
+  , fEvent(0x0)
+  , fPrimaryVertex(0x0)
+{
+  //
+  // Copy operator
+  //
+
+  ref.Copy(*this);
+}
+//____________________________________________________________________
+AliESDv0KineCuts &AliESDv0KineCuts::operator=(const AliESDv0KineCuts &ref){
+  //
+  // assignment operator
+  //
+  if(this != &ref)
+    ref.Copy(*this);
+  return *this; 
+}
+//____________________________________________________________________
+void AliESDv0KineCuts::Copy(TObject &ref) const {
+  //
+  // Performs the copying of the object
+  //
+
+  TObject::Copy(ref);
+
+  AliESDv0KineCuts &target = dynamic_cast<AliESDv0KineCuts &>(ref);
+  if(fV0)
+    target.fV0 = dynamic_cast<AliESDv0 *>(fV0->Clone());
+  else
+    target.fV0 = NULL;
+  
+}
+//____________________________________________________________________
+Bool_t AliESDv0KineCuts::ProcessV0(AliESDv0* const v0, Int_t &pdgV0, Int_t &pdgP, Int_t &pdgN){
+  //
+  // main user function
+  //
+
+  if(!v0) return kFALSE;
+  if(!fEvent){
+    AliErrorClass("No valid Event pointer available, provide it first");
+    return kFALSE;
+  }
+
+  if(!V0CutsCommon(v0)) return kFALSE;
+
+  const Int_t id = PreselectV0(v0);
+
+  if(!SingleTrackCuts(v0)) return kFALSE;
+
+  switch(id){
+  case kUndef:
+    return kFALSE;
+  case kGamma:
+    return CaseGamma(v0, pdgV0, pdgP, pdgN);
+  case kK0:
+    return CaseK0(v0, pdgV0, pdgP, pdgN);
+  case kLambda:
+    return CaseLambda(v0, pdgV0, pdgP, pdgN, 0);
+  case kALambda:
+    return CaseLambda(v0, pdgV0, pdgP, pdgN, 1);
+  default:
+    return kFALSE; 
+  }
+
+  return kFALSE;
+}
+//____________________________________________________________________
+Bool_t AliESDv0KineCuts::ProcessV0(AliESDv0* const v0, Int_t &pdgP, Int_t &pdgN){
+  //
+  // main user function, simplified if the V0 identity is not necessary
+  //
+
+  if(!v0) return kFALSE;
+  if(!fEvent){
+    AliErrorClass("No valid Event pointer available, provide it first");
+    return kFALSE;
+  }
+
+  Int_t idV0 = -1;
+  return ProcessV0(v0, idV0, pdgP, pdgN);
+
+}
+//____________________________________________________________________
+Int_t  AliESDv0KineCuts::PreselectV0(AliESDv0* const v0){
+  //
+  // Make a preselection (exclusive) of the V0 cadidates based on
+  // Armenteros plot
+  //
+  Float_t ap[2] = {-1., -1.};
+  Armenteros(v0, ap);
+  // for clarity
+  const Float_t alpha = ap[0];
+  const Float_t qt = ap[1];
+
+  // selection cuts 
+  // - the reagions for different candidates must not overlap 
+
+  // Gamma cuts
+  const Double_t cutAlphaG = 0.35; 
+  const Double_t cutAlphaG2[2] = {0.6, 0.8};
+  const Double_t cutQTG = 0.05;
+  const Double_t cutQTG2 = 0.04;
+
+  // K0 cuts
+  const Float_t cutQTK0[2] = {0.1075, 0.215};
+  const Float_t cutAPK0[2] = {0.199, 0.8};   // parameters for curved QT cut
+  
+  // Lambda & A-Lambda cuts
+  const Float_t cutQTL = 0.03;
+  const Float_t cutAlphaL[2] = {0.35, 0.7};
+  const Float_t cutAlphaAL[2] = {-0.7,  -0.35};
+  const Float_t cutAPL[3] = {0.107, -0.69, 0.5};  // parameters fir curved QT cut
+
+
+  // Check for Gamma candidates
+  if(qt < cutQTG){
+    if( (TMath::Abs(alpha) < cutAlphaG) ) return kGamma;
+  }
+  // additional region - should help high pT gammas
+  if(qt < cutQTG2){
+    if( (TMath::Abs(alpha) > cutAlphaG2[0]) &&  (TMath::Abs(alpha) < cutAlphaG2[1]) ) return kGamma;
+  }
+
+  
+  // Check for K0 candidates
+  Float_t q = cutAPK0[0] * TMath::Sqrt(TMath::Abs(1 - alpha*alpha/(cutAPK0[1]*cutAPK0[1])));
+  if( (qt > cutQTK0[0]) && (qt < cutQTK0[1]) && (qt > q) ){
+    return kK0;
+  }
+
+  // Check for Lambda candidates
+  q = cutAPL[0] * TMath::Sqrt(TMath::Abs(1 - ( (alpha + cutAPL[1]) * (alpha + cutAPL[1]) ) / (cutAPL[2]*cutAPL[2]) ));
+  if( (alpha > cutAlphaL[0]) && (alpha < cutAlphaL[1]) && (qt > cutQTL) && (qt < q)  ){
+    return kLambda;
+  }
+
+  // Check for A-Lambda candidates
+  q = cutAPL[0] * TMath::Sqrt(TMath::Abs(1 - ( (alpha - cutAPL[1]) * (alpha - cutAPL[1]) ) / (cutAPL[2]*cutAPL[2]) ));
+  if( (alpha > cutAlphaAL[0]) && (alpha < cutAlphaAL[1]) && (qt > cutQTL) && (qt < q)  ){
+    return kALambda;
+  }
+  
+  return kUndef;
+}
+//____________________________________________________________________
+Bool_t AliESDv0KineCuts::SingleTrackCuts(AliESDv0 * const v0){
+  //
+  // apply single track cuts
+  // correct sign not relevat here
+  //
+
+  if(!v0) return kFALSE;
+  
+  Int_t pIndex = 0, nIndex = 0;
+  pIndex = v0->GetPindex();
+  nIndex = v0->GetNindex();
+  AliESDtrack* d[2];
+  d[0] = dynamic_cast<AliESDtrack*>(fEvent->GetTrack(pIndex));
+  d[1] = dynamic_cast<AliESDtrack*>(fEvent->GetTrack(nIndex));
+  
+  for(Int_t i=0; i<2; ++i){
+    if(!d[i]) return kFALSE;
+    
+    // status word
+    ULong_t status = d[i]->GetStatus();
+
+    // No. of TPC clusters leave to the users
+    if(d[i]->GetTPCNcls() < 1) return kFALSE;
+
+    // TPC refit
+    if(!(status & AliESDtrack::kTPCrefit)) return kFALSE;
+  
+    // Chi2 per TPC cluster
+    Int_t nTPCclusters = d[i]->GetTPCNcls();
+    Float_t chi2perTPCcluster = d[i]->GetTPCchi2()/Float_t(nTPCclusters);
+    if(chi2perTPCcluster > 4) return kFALSE;
+
+    // TPC cluster ratio
+    Float_t cRatioTPC = d[i]->GetTPCNclsF() > 0. ? static_cast<Float_t>(d[i]->GetTPCNcls())/static_cast<Float_t> (d[i]->GetTPCNclsF()) : 1.;
+    if(cRatioTPC < 0.6) return kFALSE;
+    
+    // kinks
+    if(d[i]->GetKinkIndex(0) != 0) return kFALSE;
+    
+  }
+
+  return kTRUE;
+}
+//____________________________________________________________________
+Bool_t  AliESDv0KineCuts::CaseGamma(AliESDv0* const v0, Int_t &pdgV0, Int_t &pdgP, Int_t &pdgN){
+  //
+  // process the gamma conversion candidate
+  //
+
+  if(!v0) return kFALSE;
+
+  AliVTrack* daughter[2];
+  Int_t pIndex = 0, nIndex = 0;
+
+  Bool_t sign = CheckSigns(v0);
+  if(sign){
+    pIndex = v0->GetPindex();
+    nIndex = v0->GetNindex();
+  }
+  else{
+    pIndex = v0->GetNindex();
+    nIndex = v0->GetPindex();    
+  }
+  daughter[0] = dynamic_cast<AliVTrack *>(fEvent->GetTrack(pIndex));
+  daughter[1] = dynamic_cast<AliVTrack *>(fEvent->GetTrack(nIndex));
+  if(!daughter[0] || !daughter[1]) return kFALSE;
+
+  AliKFParticle *kfMother = CreateMotherParticle(daughter[0], daughter[1], TMath::Abs(kElectron), TMath::Abs(kElectron));
+  if(!kfMother) return kFALSE;
+
+  AliESDtrack* d[2];
+  d[0] = dynamic_cast<AliESDtrack*>(fEvent->GetTrack(pIndex));
+  d[1] = dynamic_cast<AliESDtrack*>(fEvent->GetTrack(nIndex));
+
+  Float_t iMass = v0->GetEffMass(0, 0);
+
+  // Cut values
+  const Double_t cutMass = 0.05;               // old [0.05]  
+  const Double_t cutChi2NDF = 40.;             // old [7.]  
+  const Double_t cutCosPoint[2] = {0., 0.02};  // old [0., 0.03]
+  const Double_t cutDCA[2] = {0., 0.25};       // old [0., 0.25]
+  const Double_t cutProdVtxR[2] = {8., 90.};   // old [6., 9999]
+  const Double_t cutPsiPair[2] = {0., 0.05};   // old [0. 0.05]
+  const Double_t cutOAngle[2] = {0, 0.1};      // old [0., 0.1]
+
+  // cos pointing angle
+  Double_t cosPoint = v0->GetV0CosineOfPointingAngle();
+  cosPoint = TMath::ACos(cosPoint);
+
+  // DCA between daughters
+  Double_t dca = v0->GetDcaV0Daughters();
+
+  // Production vertex
+  Double_t x, y, z; 
+  v0->GetXYZ(x,y,z);
+  Double_t r = TMath::Sqrt(x*x + y*y);
+
+  Double_t xy[2];
+  Double_t r2 = -1.;
+  if ( GetConvPosXY(d[0], d[1], xy) ){
+    r2 = TMath::Sqrt(xy[0]*xy[0] + xy[1]*xy[1]);
+  }
+
+  // Opening angle
+  Double_t oAngle = OpenAngle(v0);
+
+  // psi pair 
+  Double_t psiPair = PsiPair(v0);
+  
+  // V0 chi2/ndf
+  Double_t chi2ndf = kfMother->GetChi2()/kfMother->GetNDF();
+
+  if(kfMother) delete kfMother; 
+  
+  // apply the cuts
+
+  if(iMass > cutMass) return kFALSE;
+
+  if(chi2ndf > cutChi2NDF) return kFALSE;
+
+  if(cosPoint < cutCosPoint[0] || cosPoint > cutCosPoint[1]) return kFALSE;
+
+  if(dca < cutDCA[0] || dca > cutDCA[1]) return kFALSE;
+
+  if(r < cutProdVtxR[0] || r > cutProdVtxR[1]) return kFALSE;
+
+  if(psiPair < cutPsiPair[0] || psiPair > cutPsiPair[1]) return kFALSE;
+
+  if(oAngle < cutOAngle[0] || oAngle > cutOAngle[1]) return kFALSE;
+  
+  // all cuts passed
+
+  pdgV0 = 22;
+  if(sign){
+    pdgP = -11;
+    pdgN = 11;
+  }
+  else{
+    pdgP = 11;
+    pdgN = -11;
+  }
+
+  return kTRUE;
+}
+//____________________________________________________________________
+Bool_t  AliESDv0KineCuts::CaseK0(AliESDv0* const v0, Int_t &pdgV0, Int_t &pdgP, Int_t &pdgN){
+  //
+  // process the K0 candidate
+  //
+
+  if(!v0) return kFALSE;
+  
+  AliVTrack* daughter[2];
+  Int_t pIndex = 0, nIndex = 0;
+  Bool_t sign = CheckSigns(v0);
+  if(sign){
+    pIndex = v0->GetPindex();
+    nIndex = v0->GetNindex();
+  }
+  else{
+    pIndex = v0->GetNindex();
+    nIndex = v0->GetPindex();    
+  }
+  daughter[0] = dynamic_cast<AliVTrack *>(fEvent->GetTrack(pIndex));
+  daughter[1] = dynamic_cast<AliVTrack *>(fEvent->GetTrack(nIndex));
+  if(!daughter[0] || !daughter[1]) return kFALSE;
+
+  AliKFParticle *kfMother = CreateMotherParticle(daughter[0], daughter[1], TMath::Abs(kPiPlus), TMath::Abs(kPiPlus));
+  if(!kfMother) return kFALSE;
+
+  AliESDtrack* d[2];
+  d[0] = dynamic_cast<AliESDtrack*>(fEvent->GetTrack(pIndex));
+  d[1] = dynamic_cast<AliESDtrack*>(fEvent->GetTrack(nIndex));
+
+  Float_t iMass = v0->GetEffMass(2, 2);
+
+  const Double_t cutMass[2] = {0.486, 0.508};   // ORG [0.485, 0.51]
+  const Double_t cutChi2NDF = 40.;              // ORG [7.]
+  const Double_t cutCosPoint[2] = {0., 0.02};  // ORG [0., 0.03]
+  const Double_t cutDCA[2] = {0., 0.2};        // ORG [0., 0.1]
+  const Double_t cutProdVtxR[2] = {2.0, 30.};   // ORG [0., 8.1]
+  
+  // cos pointing angle
+  Double_t cosPoint = v0->GetV0CosineOfPointingAngle();
+  cosPoint = TMath::ACos(cosPoint);
+
+  // DCA between daughters
+  Double_t dca = v0->GetDcaV0Daughters();
+
+  // Production vertex
+  Double_t x, y, z; 
+  v0->GetXYZ(x,y,z);
+
+  Double_t r = TMath::Sqrt(x*x + y*y);  
+
+  // V0 chi2/ndf
+  Double_t chi2ndf = kfMother->GetChi2()/kfMother->GetNDF();
+  
+  if(kfMother) delete kfMother; 
+
+  //
+  // apply the cuts
+  //
+  if(iMass < cutMass[0] || iMass > cutMass[1]) return kFALSE;
+
+  if(chi2ndf > cutChi2NDF) return kFALSE;
+
+  if(cosPoint < cutCosPoint[0] || cosPoint > cutCosPoint[1]) return kFALSE;
+
+  if(dca < cutDCA[0] || dca > cutDCA[1]) return kFALSE;
+
+  if(r < cutProdVtxR[0] || r > cutProdVtxR[1]) return kFALSE;
+
+  // all cuts passed
+  pdgV0 = 310;
+  if(sign){
+    pdgP = 211;
+    pdgN = -211;
+  }
+  else{
+    pdgP = -211;
+    pdgN = 211;
+  }
+
+  return kTRUE;
+}
+//____________________________________________________________________
+Bool_t  AliESDv0KineCuts::CaseLambda(AliESDv0* const v0, Int_t &pdgV0, Int_t &pdgP, Int_t &pdgN, Int_t id){
+  //
+  // process teh Lambda and Anti-Lambda candidate
+  //
+  
+  if(!v0) return kFALSE;
+
+    const Double_t cL0mass=TDatabasePDG::Instance()->GetParticle(kLambda0)->Mass();  // PDG lambda mass
+
+  AliVTrack* daughter[2];
+  Int_t pIndex = 0, nIndex = 0;
+  Float_t mMass[2] = {-1., -1.};
+  Bool_t sign = CheckSigns(v0);
+  if(sign){
+    pIndex = v0->GetPindex();
+    nIndex = v0->GetNindex();
+    mMass[0] = v0->GetEffMass(4, 2);
+    mMass[1] = v0->GetEffMass(2, 4);
+  }
+  else{
+    pIndex = v0->GetNindex();
+    nIndex = v0->GetPindex();    
+    mMass[0] = v0->GetEffMass(2, 4);
+    mMass[1] = v0->GetEffMass(4, 2);
+  }
+  daughter[0] = dynamic_cast<AliVTrack *>(fEvent->GetTrack(pIndex));
+  daughter[1] = dynamic_cast<AliVTrack *>(fEvent->GetTrack(nIndex));
+  if(!daughter[0] || !daughter[1]) return kFALSE;
+
+  AliKFParticle *kfMother[2] = {0x0, 0x0};
+  // Lambda
+  kfMother[0] = CreateMotherParticle(daughter[0], daughter[1], TMath::Abs(kProton), TMath::Abs(kPiPlus));
+  if(!kfMother[0]) return kFALSE;
+  
+  // Anti-Lambda
+  kfMother[1] = CreateMotherParticle(daughter[0], daughter[1], TMath::Abs(kPiPlus), TMath::Abs(kProton));
+  if(!kfMother[1]) return kFALSE;
+
+  Float_t dMass[2] = {TMath::Abs(mMass[0] - cL0mass), TMath::Abs(mMass[1] - cL0mass)};
+  
+  AliESDtrack* d[2];
+  d[0] = dynamic_cast<AliESDtrack*>(fEvent->GetTrack(pIndex));
+  d[1] = dynamic_cast<AliESDtrack*>(fEvent->GetTrack(nIndex));
+  if(!d[0] || !d[1])    return kFALSE;
+  
+  Float_t p[2] = {d[0]->GetP(), d[1]->GetP()}; 
+
+  // check the 3 lambda - antilambda variables
+  Int_t check[2] = {-1, -1};   // 0 : lambda, 1 : antilambda
+  // 1) momentum of the daughter particles - proton is expected to have higher momentum than pion
+  check[0] = (p[0] > p[1]) ? 0 : 1;
+  // 2) mass of the mother particle
+  check[1] = (dMass[0] < dMass[1]) ? 0 : 1;
+  // require positive correlation of (1) and (2)
+  if(check[0] != check[1]){
+    if(kfMother[0]) delete kfMother[0]; 
+    if(kfMother[1]) delete kfMother[1]; 
+    return kFALSE;
+  }
+
+  // now that the check[0] == check[1]
+  const Int_t type = check[0];
+
+  // require that the input armenteros preselection agree:
+  if(type != id) return kFALSE;
+
+  Float_t iMass =0.;
+  if(sign){
+    iMass = (type == 0) ? v0->GetEffMass(4, 2) : v0->GetEffMass(2, 4);
+  }
+  else{
+    iMass = (type == 0) ? v0->GetEffMass(2, 4) : v0->GetEffMass(4, 2);
+  }
+
+  // Cuts
+  const Double_t cutMass[2] = {1.11, 1.12};   // ORG [1.11, 1.12]
+  const Double_t cutChi2NDF = 40.;              // ORG [5.]
+  const Double_t cutCosPoint[2] = {0., 0.02};  // ORG [0., 0.03]
+  const Double_t cutDCA[2] = {0., 0.2};        // ORG [0., 0.2]
+  const Double_t cutProdVtxR[2] = {2., 40.};   // ORG [0., 24.]
+  // cos pointing angle
+  Double_t cosPoint = v0->GetV0CosineOfPointingAngle();
+  cosPoint = TMath::ACos(cosPoint);
+
+  // DCA between daughters
+  Double_t dca = v0->GetDcaV0Daughters();
+  
+  // Production vertex
+  Double_t x, y, z; 
+  v0->GetXYZ(x,y,z);
+  Double_t r = TMath::Sqrt(x*x + y*y);
+
+  // proton - pion indices
+  Int_t ix[2] = {0, 1};
+  if(1 == type){
+    ix[0] = 1;
+    ix[1] = 0;
+  }
+
+  // V0 chi2/ndf
+  Double_t chi2ndf = kfMother[type]->GetChi2()/kfMother[type]->GetNDF();
+
+  if(kfMother[0]) delete kfMother[0]; 
+  if(kfMother[1]) delete kfMother[1]; 
+
+  //
+  // apply the cuts
+  //
+
+  if(iMass < cutMass[0] || iMass > cutMass[1]) return kFALSE;
+
+  if(chi2ndf > cutChi2NDF) return kFALSE;
+
+  if(cosPoint < cutCosPoint[0] || cosPoint > cutCosPoint[1]) return kFALSE;
+
+  if(dca < cutDCA[0] || dca > cutDCA[1]) return kFALSE;
+
+  if(r < cutProdVtxR[0] || r > cutProdVtxR[1]) return kFALSE;
+
+  // all cuts passed
+
+  if(0 == type){
+    pdgV0 = 3122;
+    if(sign){
+      pdgP = 2212;
+      pdgN = -211;
+    }
+    else{
+      pdgP = -211;
+      pdgN = 2212;
+    }
+  }
+  else{
+    pdgV0 = -3122;
+    if(sign){
+      pdgP = 211;
+      pdgN = -2212;
+    }
+    else{
+      pdgP = -2212;
+      pdgN = 211;
+    }
+  }
+
+  return kTRUE;
+}
+//____________________________________________________________________
+Bool_t AliESDv0KineCuts::V0CutsCommon(const AliESDv0 * const v0){
+  //
+  // V0 cuts common to all V0s
+  //
+
+  AliESDtrack* dN, *dP; 
+  dP = dynamic_cast<AliESDtrack *>(fEvent->GetTrack(v0->GetPindex()));
+  dN = dynamic_cast<AliESDtrack *>(fEvent->GetTrack(v0->GetNindex())); 
+  
+  if(!dN || !dP) return kFALSE;
+
+  Int_t qP = dP->Charge();
+  Int_t qN = dN->Charge();
+
+  if((qP*qN) != -1) return kFALSE;
+
+  return kTRUE;
+}
+//____________________________________________________________________
+void   AliESDv0KineCuts::Armenteros(AliESDv0* const v0, Float_t val[2]){
+  //
+  // computes the Armenteros variables for given V0
+  // fills the histogram
+  // returns the values via "val"
+  //
+  
+  Double_t mn[3] = {0,0,0};
+  Double_t mp[3] = {0,0,0};  
+  Double_t mm[3] = {0,0,0};  
+
+  if(CheckSigns(v0)){
+    v0->GetNPxPyPz(mn[0],mn[1],mn[2]); //reconstructed cartesian momentum components of negative daughter
+    v0->GetPPxPyPz(mp[0],mp[1],mp[2]); //reconstructed cartesian momentum components of positive daughter
+  }
+  else{
+    v0->GetPPxPyPz(mn[0],mn[1],mn[2]); //reconstructed cartesian momentum components of negative daughter
+    v0->GetNPxPyPz(mp[0],mp[1],mp[2]); //reconstructed cartesian momentum components of positive daughter
+  }
+  v0->GetPxPyPz(mm[0],mm[1],mm[2]); //reconstructed cartesian momentum components of mother
+
+  TVector3 vecN(mn[0],mn[1],mn[2]);
+  TVector3 vecP(mp[0],mp[1],mp[2]);
+  TVector3 vecM(mm[0],mm[1],mm[2]);
+  
+  Double_t thetaP = acos((vecP * vecM)/(vecP.Mag() * vecM.Mag()));
+  Double_t thetaN = acos((vecN * vecM)/(vecN.Mag() * vecM.Mag()));
+  
+  Double_t alfa = ((vecP.Mag())*cos(thetaP)-(vecN.Mag())*cos(thetaN))/
+    ((vecP.Mag())*cos(thetaP)+(vecN.Mag())*cos(thetaN)) ;
+  Double_t qt = vecP.Mag()*sin(thetaP);
+
+  val[0] = alfa;
+  val[1] = qt;
+}
+//____________________________________________________________________
+Bool_t AliESDv0KineCuts::CheckSigns(AliESDv0* const v0){
+  //
+  // check wheter the sign was correctly applied to 
+  // V0 daughter tracks
+  //
+  
+  Bool_t correct = kFALSE;
+
+  Int_t pIndex = 0, nIndex = 0;
+  pIndex = v0->GetPindex();
+  nIndex = v0->GetNindex();
+  
+  AliESDtrack* d[2];
+  d[0] = dynamic_cast<AliESDtrack*>(fEvent->GetTrack(pIndex));
+  d[1] = dynamic_cast<AliESDtrack*>(fEvent->GetTrack(nIndex));
+
+  Int_t sign[2];
+  sign[0] = (int)d[0]->GetSign();
+  sign[1] = (int)d[1]->GetSign();
+  
+  if(-1 == sign[0] && 1 == sign[1]){
+    correct = kFALSE;
+  }
+  else{
+    correct = kTRUE;
+  }
+  
+  return correct;
+}
+//____________________________________________________________________
+void   AliESDv0KineCuts::SetEvent(AliESDEvent* const event){
+  //
+  // direct setter of ESD event
+  //
+  if(!event){
+    AliErrorClass("Invalid input event pointer");
+    return;
+  }
+  fEvent = event;
+}
+//____________________________________________________________________
+void   AliESDv0KineCuts::SetEvent(AliVEvent* const event){
+  //
+  // Set the current working ESD event
+  //
+  if(!event){
+    AliErrorClass("Invalid input event pointer");
+    return;
+  }
+  
+  SetEvent(dynamic_cast<AliESDEvent*>(event));
+}
+//________________________________________________________________
+Double_t AliESDv0KineCuts::OpenAngle(AliESDv0 *v0) const {
+  //
+  // Opening angle between two daughter tracks
+  //
+  Double_t mn[3] = {0,0,0};
+  Double_t mp[3] = {0,0,0};
+    
+  
+  v0->GetNPxPyPz(mn[0],mn[1],mn[2]);//reconstructed cartesian momentum components of negative daughter;
+  v0->GetPPxPyPz(mp[0],mp[1],mp[2]);//reconstructed cartesian momentum components of positive daughter;
+
+  
+  Double_t openAngle = TMath::ACos((mp[0]*mn[0] + mp[1]*mn[1] + mp[2]*mn[2])/(TMath::Sqrt(mp[0]*mp[0] + mp[1]*mp[1] + mp[2]*mp[2])*TMath::Sqrt(mn[0]*mn[0] + mn[1]*mn[1] + mn[2]*mn[2])));
+  
+  return TMath::Abs(openAngle);
+}
+//________________________________________________________________
+Double_t AliESDv0KineCuts::PsiPair(AliESDv0* const v0) {
+  //
+  // Angle between daughter momentum plane and plane 
+  // 
+
+  if(!fEvent) return -1.;
+
+  Float_t magField = fEvent->GetMagneticField();
+
+  Int_t pIndex = -1;
+  Int_t nIndex = -1;
+  if(CheckSigns(v0)){
+    pIndex = v0->GetPindex();
+    nIndex = v0->GetNindex();
+  }
+  else{
+    pIndex = v0->GetNindex();
+    nIndex = v0->GetPindex();    
+  }
+
+  AliESDtrack* daughter[2];
+
+  daughter[0] = dynamic_cast<AliESDtrack *>(fEvent->GetTrack(pIndex));
+  daughter[1] = dynamic_cast<AliESDtrack *>(fEvent->GetTrack(nIndex));
+
+  Double_t x, y, z;
+  v0->GetXYZ(x,y,z);//Reconstructed coordinates of V0; to be replaced by Markus Rammler's method in case of conversions!
+  
+  Double_t mn[3] = {0,0,0};
+  Double_t mp[3] = {0,0,0};
+  
+
+  v0->GetNPxPyPz(mn[0],mn[1],mn[2]);//reconstructed cartesian momentum components of negative daughter;
+  v0->GetPPxPyPz(mp[0],mp[1],mp[2]);//reconstructed cartesian momentum components of positive daughter; 
+
+
+  Double_t deltat = 1.;
+  deltat = TMath::ATan(mp[2]/(TMath::Sqrt(mp[0]*mp[0] + mp[1]*mp[1])+1.e-13)) -  TMath::ATan(mn[2]/(TMath::Sqrt(mn[0]*mn[0] + mn[1]*mn[1])+1.e-13));//difference of angles of the two daughter tracks with z-axis
+
+  Double_t radiussum = TMath::Sqrt(x*x + y*y) + 50;//radius to which tracks shall be propagated
+
+  Double_t momPosProp[3];
+  Double_t momNegProp[3];
+    
+  AliExternalTrackParam pt(*daughter[0]), nt(*daughter[1]);
+    
+  Double_t psiPair = 4.;
+
+  if(nt.PropagateTo(radiussum,magField) == 0)//propagate tracks to the outside
+    psiPair =  -5.;
+  if(pt.PropagateTo(radiussum,magField) == 0)
+    psiPair = -5.;
+  pt.GetPxPyPz(momPosProp);//Get momentum vectors of tracks after propagation
+  nt.GetPxPyPz(momNegProp);
+  
+  Double_t pEle =
+    TMath::Sqrt(momNegProp[0]*momNegProp[0]+momNegProp[1]*momNegProp[1]+momNegProp[2]*momNegProp[2]);//absolute momentum value of negative daughter
+  Double_t pPos =
+    TMath::Sqrt(momPosProp[0]*momPosProp[0]+momPosProp[1]*momPosProp[1]+momPosProp[2]*momPosProp[2]);//absolute momentum value of positive daughter
+    
+  Double_t scalarproduct =
+    momPosProp[0]*momNegProp[0]+momPosProp[1]*momNegProp[1]+momPosProp[2]*momNegProp[2];//scalar product of propagated positive and negative daughters' momenta
+    
+  Double_t chipair = TMath::ACos(scalarproduct/(pEle*pPos));//Angle between propagated daughter tracks
+
+  psiPair =  TMath::Abs(TMath::ASin(deltat/chipair));  
+
+  return psiPair; 
+}
+//___________________________________________________________________
+Bool_t AliESDv0KineCuts::GetConvPosXY(AliESDtrack * const ptrack, AliESDtrack * const ntrack, Double_t convpos[2]){
+  //
+  // recalculate the gamma conversion XY postition
+  //
+
+  const Double_t b = fEvent->GetMagneticField();
+
+  Double_t helixcenterpos[2];
+  GetHelixCenter(ptrack,b,ptrack->Charge(),helixcenterpos);
+
+  Double_t helixcenterneg[2];
+  GetHelixCenter(ntrack,b,ntrack->Charge(),helixcenterneg);
+
+  Double_t  poshelix[6];
+  ptrack->GetHelixParameters(poshelix,b);
+  Double_t posradius = TMath::Abs(1./poshelix[4]);
+
+  Double_t  neghelix[6];
+  ntrack->GetHelixParameters(neghelix,b);
+  Double_t negradius = TMath::Abs(1./neghelix[4]);
+
+  Double_t xpos = helixcenterpos[0];
+  Double_t ypos = helixcenterpos[1];
+  Double_t xneg = helixcenterneg[0];
+  Double_t yneg = helixcenterneg[1];
+
+  convpos[0] = (xpos*negradius + xneg*posradius)/(negradius+posradius);
+  convpos[1] = (ypos*negradius+  yneg*posradius)/(negradius+posradius);
+
+  return 1;
+}
+//___________________________________________________________________
+Bool_t AliESDv0KineCuts::GetHelixCenter(AliESDtrack * const track, Double_t b,Int_t charge, Double_t center[2]){
+  //
+  // computes the center of the track helix
+  //
+  
+  Double_t pi = TMath::Pi();
+  
+  Double_t  helix[6];
+  track->GetHelixParameters(helix,b);
+  
+  Double_t xpos =  helix[5];
+  Double_t ypos =  helix[0];
+  Double_t radius = TMath::Abs(1./helix[4]);
+  Double_t phi = helix[2];
+
+  if(phi < 0){
+    phi = phi + 2*pi;
+  }
+
+  phi -= pi/2.;
+  Double_t xpoint =  radius * TMath::Cos(phi);
+  Double_t ypoint =  radius * TMath::Sin(phi);
+
+  if(b<0){
+    if(charge > 0){
+      xpoint = - xpoint;
+      ypoint = - ypoint;
+    }
+
+    if(charge < 0){
+      xpoint =  xpoint;
+      ypoint =  ypoint;
+    }
+  }
+  if(b>0){
+    if(charge > 0){
+      xpoint =  xpoint;
+      ypoint =  ypoint;
+    }
+
+    if(charge < 0){
+      xpoint = - xpoint;
+      ypoint = - ypoint;
+    }
+  }
+  center[0] =  xpos + xpoint;
+  center[1] =  ypos + ypoint;
+
+  return 1;
+}
+//___________________________________________________________________
+AliKFParticle *AliESDv0KineCuts::CreateMotherParticle(const AliVTrack* const pdaughter, const AliVTrack* const ndaughter, Int_t pspec, Int_t nspec){
+  //
+  // Creates a mother particle
+  //
+  AliKFParticle pkfdaughter(*pdaughter, pspec);
+  AliKFParticle nkfdaughter(*ndaughter, nspec);
+  
+  
+  // Create the mother particle 
+  AliKFParticle *m = new AliKFParticle(pkfdaughter, nkfdaughter);
+  // DEBUG - testing
+  if(TMath::Abs(kElectron) == pspec && TMath::Abs(kElectron) == nspec) m->SetMassConstraint(0, 0.001);
+  else if(TMath::Abs(kPiPlus) == pspec && TMath::Abs(kPiPlus) == nspec) m->SetMassConstraint(TDatabasePDG::Instance()->GetParticle(kK0Short)->Mass(), 0.);
+  else if(TMath::Abs(kProton) == pspec && TMath::Abs(kPiPlus) == nspec) m->SetMassConstraint(TDatabasePDG::Instance()->GetParticle(kLambda0)->Mass(), 0.);
+  else if(TMath::Abs(kPiPlus) == pspec && TMath::Abs(kProton) == nspec) m->SetMassConstraint(TDatabasePDG::Instance()->GetParticle(kLambda0)->Mass(), 0.);
+  else{
+    AliErrorClass("Wrong daughter ID - mass constraint can not be set");
+  }
+
+  AliKFVertex improvedVertex = *fPrimaryVertex;
+  improvedVertex += *m;
+  m->SetProductionVertex(improvedVertex);
+  
+  // update 15/06/2010
+  // mother particle will not be added to primary vertex but only to its copy 
+  // as this confilcts with calling
+  // m->SetPrimaryVertex() function and
+  // subsequently removing the mother particle afterwards
+  // Source: Sergey Gorbunov
+
+  return m;
+}
diff --git a/PWG3/hfe/AliESDv0KineCuts.h b/PWG3/hfe/AliESDv0KineCuts.h
new file mode 100644 (file)
index 0000000..1cc1742
--- /dev/null
@@ -0,0 +1,75 @@
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+/*
+ * plesae see source file for more details
+ */
+#ifndef ALIESDV0KINECUTS_H
+#define ALIESDV0KINECUTS_H
+
+#include <TObject.h>
+
+class AliESDv0;
+class AliESDEvent;
+class AliVEvent;
+class AliESDtrack;
+class AliVTrack;
+class AliKFParticle;
+class AliKFVertex;
+
+class AliESDv0KineCuts : public TObject{
+ public:
+  enum{ // Reconstructed V0
+    kUndef = -1,
+      kGamma = 0,
+      kK0 = 1,
+      kLambda = 2,
+      kALambda = 3
+      };
+  
+  AliESDv0KineCuts();
+  virtual ~AliESDv0KineCuts();
+
+  AliESDv0KineCuts(const AliESDv0KineCuts &ref);
+  AliESDv0KineCuts &operator=(const AliESDv0KineCuts &ref);
+
+  Bool_t ProcessV0(AliESDv0* const v0, Int_t &pdgV0, Int_t &pdgP, Int_t &pdgN);
+  Bool_t ProcessV0(AliESDv0* const v0, Int_t &pdgP, Int_t &pdgN);
+
+  Int_t  PreselectV0(AliESDv0* const v0);
+
+  Bool_t CaseGamma(AliESDv0* const v0, Int_t &pdgV0, Int_t &pdgP, Int_t &pdgN);
+  Bool_t CaseK0(AliESDv0* const v0, Int_t &pdgV0, Int_t &pdgP, Int_t &pdgN);
+  Bool_t CaseLambda(AliESDv0* const v0, Int_t &pdgV0, Int_t &pdgP, Int_t &pdgN, Int_t id);
+
+  Bool_t V0CutsCommon(const AliESDv0 * const v0);
+  Bool_t SingleTrackCuts(AliESDv0 * const v0);
+  void   Armenteros(AliESDv0* const v0, Float_t val[2]);
+  Bool_t CheckSigns(AliESDv0* const v0);
+
+  void   SetEvent(AliESDEvent* const event);
+  void   SetEvent(AliVEvent* const event);
+  void   SetPrimaryVertex(AliKFVertex* const v) { fPrimaryVertex = v; };
+
+  Double_t OpenAngle(AliESDv0 *v0) const;//opening angle between V0 daughters; close to zero for conversions
+  Double_t PsiPair(AliESDv0* const v0);
+
+  Bool_t GetConvPosXY(AliESDtrack * const ptrack, AliESDtrack * const ntrack, Double_t convpos[2]);
+  Bool_t GetHelixCenter(AliESDtrack * const track, Double_t b, Int_t charge, Double_t center[2]);
+
+ protected:
+  void Copy(TObject &ref) const;
+
+ private:
+
+  AliKFParticle *CreateMotherParticle(const AliVTrack* const pdaughter, const AliVTrack* const ndaughter, Int_t pspec, Int_t nspec);
+
+ private:
+  AliESDv0              *fV0;             // current V0 candidate
+  AliESDEvent           *fEvent;          // current event
+  AliKFVertex           *fPrimaryVertex;  // primary vertex
+
+  ClassDef(AliESDv0KineCuts, 0);
+
+};
+
+#endif
index 3001426..e219cb6 100644 (file)
@@ -27,6 +27,7 @@
 #include "AliESDv0.h"
 #include "AliKFParticle.h"
 #include "AliKFVertex.h"
+#include "AliLog.h"
 
 #include "AliHFEcollection.h"
 
@@ -37,10 +38,13 @@ ClassImp(AliHFEV0cuts)
 //________________________________________________________________
 AliHFEV0cuts::AliHFEV0cuts():
   fQA(NULL)
+  , fQAmc(NULL)
   , fMCEvent(NULL)
   , fInputEvent(NULL)
   , fPrimaryVertex(NULL)
-  , fIsMC(kFALSE)
+  , fCurrentV0id(0)
+  , fPdaughterPDG(0)
+  , fNdaughterPDG(0)
 {
  
   //
@@ -56,16 +60,20 @@ AliHFEV0cuts::~AliHFEV0cuts()
   // destructor
   //
   if (fQA) delete fQA;
+  if (fQAmc) delete fQAmc;
 }
 
 //________________________________________________________________
 AliHFEV0cuts::AliHFEV0cuts(const AliHFEV0cuts &ref):
   TObject(ref)
   , fQA(NULL)
+  , fQAmc(NULL)
   , fMCEvent(NULL)
   , fInputEvent(NULL)
   , fPrimaryVertex(NULL)
-  , fIsMC(kFALSE)
+  , fCurrentV0id(0)
+  , fPdaughterPDG(0)
+  , fNdaughterPDG(0)
 {
   //
   // Copy constructor
@@ -90,6 +98,8 @@ void AliHFEV0cuts::Copy(TObject &ref) const{
 
   if(fQA) target.fQA = dynamic_cast<AliHFEcollection *>(fQA->Clone());  
 
+  if(fQAmc) target.fQAmc = dynamic_cast<AliHFEcollection *>(fQAmc->Clone());  
+
   if(target.fMCEvent) delete target.fMCEvent;
   target.fMCEvent = new AliMCEvent;
   
@@ -113,6 +123,7 @@ void AliHFEV0cuts::Init(const char* name){
 
   fQA = new AliHFEcollection("fQA", name);
 
+  fQAmc = new AliHFEcollection("fQAmc", name);
 
   // common for all V0s
   fQA->CreateTH2Fvector1(2, "h_all_AP", "armenteros plot for all V0 candidates", 200, -1, 1, 200, 0, 0.25);
@@ -120,31 +131,28 @@ void AliHFEV0cuts::Init(const char* name){
   // gammas
   fQA->CreateTH1Fvector1(2, "h_cut_Gamma_CosPoint", "Gamma Cosine pointing angle; cos point. angle; counts", 100, 0, 0.1);
   fQA->CreateTH1Fvector1(2, "h_cut_Gamma_DCA", "DCA between the gamma daughters; dca (cm); counts", 100, 0, 2);
+  fQA->CreateTH1Fvector1(2, "h_cut_Gamma_VtxR_old", "*old* Radius of the gamma conversion vertex; r (cm); counts", 1000, 0, 100);
   fQA->CreateTH1Fvector1(2, "h_cut_Gamma_VtxR", "Radius of the gamma conversion vertex; r (cm); counts", 1000, 0, 100);
   fQA->CreateTH1Fvector1(2, "h_cut_Gamma_OA", "opening angle of the gamma products; opening angle (rad); counts", 100, 0, 1);
   fQA->CreateTH1Fvector1(2, "h_cut_Gamma_PP", "gamma psi pair angle; psi pairangle (rad); counts", 100, 0, 2);
-  fQA->CreateTH1Fvector1(2, "h_cut_Gamma_Chi2", "gamma Chi2/NDF; Chi2/NDF; counts", 100, 0, 25);
-  fQA->CreateTH1Fvector1(9, "h_Gamma_Mass", "Invariant mass of gammas; mass (GeV/c^{2}); counts", 100, 0, 0.2);
+  fQA->CreateTH1Fvector1(2, "h_cut_Gamma_Chi2", "gamma Chi2/NDF; Chi2/NDF; counts", 100, 0, 50);
+  fQA->CreateTH1Fvector1(7, "h_Gamma_Mass", "Invariant mass of gammas; mass (GeV/c^{2}); counts", 100, 0, 0.2);
 
  
   // kaons
   fQA->CreateTH1Fvector1(2, "h_cut_K0_CosPoint", "K0 Cosine pointing angle; cos point. angle; counts", 100, 0, 0.1);
   fQA->CreateTH1Fvector1(2, "h_cut_K0_DCA", "DCA between the K0 daughters; dca (cm); counts", 100, 0, 2);
   fQA->CreateTH1Fvector1(2, "h_cut_K0_VtxR", "Radius of the K0 decay vertex; r (cm); counts", 1000, 0, 100);
-  fQA->CreateTH1Fvector1(2, "h_cut_K0_Chi2", "K0 Chi2/NDF; Chi2/NDF; counts", 100, 0, 25);
-  fQA->CreateTH2Fvector1(2, "h_cut_K0_AP", "Armenteros plot for K0 candidates; #alpha; q_{T} (GeV/c)", 100, -1, 1, 100, 0, 0.3);
-  fQA->CreateTH1Fvector1(8, "h_K0_Mass", "Invariant mass of K0; mass (GeV/c^{2}); counts", 125, 0.45, 0.55);
+  fQA->CreateTH1Fvector1(2, "h_cut_K0_Chi2", "K0 Chi2/NDF; Chi2/NDF; counts", 100, 0, 50);
+  fQA->CreateTH1Fvector1(5, "h_K0_Mass", "Invariant mass of K0; mass (GeV/c^{2}); counts", 125, 0.45, 0.55);
 
   // lambda
   fQA->CreateTH1Fvector1(2, "h_cut_L_CosPoint", "L Cosine pointing angle; cos point. angle; counts", 100, 0, 0.1);
   fQA->CreateTH1Fvector1(2, "h_cut_L_DCA", "DCA between the L daughters; dca (cm); counts", 100, 0, 2);
   fQA->CreateTH1Fvector1(2, "h_cut_L_VtxR", "Radius of the L decay vertex; r (cm); counts", 1000, 0, 100);
-  fQA->CreateTH1Fvector1(2, "h_cut_L_Chi2", "L Chi2/NDF; Chi2/NDF; counts", 100, 0, 25);
-  fQA->CreateTH2Fvector1(2, "h_cut_L_AP", "Armenteros plot for Lambda candidates; #alpha; q_{T} (GeV/c)", 100, -1, 1, 100, 0, 0.3);
-  fQA->CreateTH2Fvector1(2, "h_cut_AL_AP", "Armenteros plot for anti Lambda candidates; #alpha; q_{T} (GeV/c)", 100, -1, 1, 100, 0, 0.3);
-  fQA->CreateTH2Fvector1(2, "h_cut_Gamma_AP", "Armenteros plot for gamma candidates; #alpha; q_{T} (GeV/c)", 100, -1, 1, 100, 0, 0.3);
-  fQA->CreateTH1Fvector1(9, "h_L_Mass", "Invariant mass of L; mass (GeV/c^{2}); counts", 60, 1.1, 1.13);
-  fQA->CreateTH1Fvector1(9, "h_AL_Mass", "Invariant mass of anti L; mass (GeV/c^{2}); counts", 60, 1.1, 1.13);
+  fQA->CreateTH1Fvector1(2, "h_cut_L_Chi2", "L Chi2/NDF; Chi2/NDF; counts", 100, 0, 50);
+  fQA->CreateTH1Fvector1(5, "h_L_Mass", "Invariant mass of L; mass (GeV/c^{2}); counts", 60, 1.1, 1.13);
+  fQA->CreateTH1Fvector1(5, "h_AL_Mass", "Invariant mass of anti L; mass (GeV/c^{2}); counts", 60, 1.1, 1.13);
 
   fQA->CreateTH2F("h_L_checks", "Lambda candidate check[0] -v- check[1]; check[0]; check[1]", 5, -0.75, 1.75, 6, -0.75, 1.75 );
   
@@ -155,7 +163,7 @@ void AliHFEV0cuts::Init(const char* name){
   fQA->CreateTH1Fvector1(8, "h_PionK0_P", "Momenta of K0 pions -cuts-; P (GeV/c) counts;", 50, 0.1, 20, 0);
   
   // L pions
-  fQA->CreateTH1Fvector1(9, "h_PionL_P", "Momenta of L pions -cuts-; P (GeV/c) counts;", 50, 0.1, 50, 0);
+  fQA->CreateTH1Fvector1(9, "h_PionL_P", "Momenta of L pions -cuts-; P (GeV/c) counts;", 50, 0.1, 20, 0);
   
   // L protons
   fQA->CreateTH1Fvector1(9, "h_ProtonL_P", "Momenta of L protons -cuts-; P (GeV/c) counts;", 50, 0.1, 20, 0);    
@@ -180,7 +188,6 @@ void AliHFEV0cuts::Init(const char* name){
   // Lambda
   fQA->CreateTH2Fvector1(2, "h_cut_L_OAvP", "open. ang. of the L daughters versus L momentum; Lambda p (GeV/c); openeing angle pion-proton (rad)", 100, 0.1, 10, 100, 0, 3.5);
   fQA->CreateTH2Fvector1(2, "h_cut_L_rdp_v_mp", "relative L daughter mom -v- mother mom; L mom (GeV/c); relative daughter mom p2/p1", 100, 0.1, 10, 100, 0, 1);
-  fQA->CreateTH2Fvector1(2, "h_cut_L_qT_v_mp", "A-P q_{T} -v- Lambda momentum; mom (GeV/c); q_{T} GeV/c", 100, 0.1, 10, 50, 0., 0.12);
 
 
   // THnSparse histograms
@@ -197,6 +204,132 @@ void AliHFEV0cuts::Init(const char* name){
     fQA->BinLogAxis("hK0", 1);
   }
 
+
+  // 
+  // MC plots for checking and tuning the V0 cuts
+  //
+  const char *v0[4] = {"G", "K", "L"}; // to keep the names short
+  // number of V0s left after each cut step - for signal and background - within given mass window
+  for(Int_t i=0; i<3; ++i){
+    fQAmc->CreateTH1F(Form("h_%s_cuts_S", v0[i]), Form("h_%s_cuts_S", v0[i]), 10, -0.5, 9.5);
+    fQAmc->CreateTH1F(Form("h_%s_cuts_B", v0[i]), Form("h_%s_cuts_B", v0[i]), 10, -0.5, 9.5);
+  }
+
+  //
+  // cut distributions for signal and background
+  //
+
+  const Float_t pMin = 0.1;
+  const Float_t pMax = 10.;
+  const Int_t pN = 12;
+
+
+  // gamma signal
+  fQAmc->CreateTH2Fvector1(2, "h_cut_Gamma_CosPoint_S", "S - Gamma Cosine pointing angle; mom (GeV/c); cos point. angle",  pN, pMin, pMax, 50, 0, 0.1, 0);
+  fQAmc->CreateTH2Fvector1(2, "h_cut_Gamma_DCA_S", "S - DCA between the gamma daughters; mom (GeV/c); dca (cm)", pN, pMin, pMax, 50, 0, 2, 0);
+  fQAmc->CreateTH2Fvector1(2, "h_cut_Gamma_VtxR_S", "S - Radius of the gamma conversion vertex; mom (GeV/c); r (cm)", pN, pMin, pMax, 100, 0, 100, 0);
+  fQAmc->CreateTH2Fvector1(2, "h_cut_Gamma_OA_S", "S - opening angle of the gamma products; mom (GeV/c); opening angle (rad)", pN, pMin, pMax, 50, 0, 0.3, 0);
+  fQAmc->CreateTH2Fvector1(2, "h_cut_Gamma_PP_S", "S - gamma psi pair angle; mom (GeV/c); psi pairangle (rad)", pN, pMin, pMax, 50, 0, 0.5, 0);
+  fQAmc->CreateTH2Fvector1(2, "h_cut_Gamma_Chi2_S", "S - gamma Chi2/NDF; mom (GeV/c); Chi2/NDF", pN, pMin, pMax, 50, 0, 100, 0);
+
+  fQAmc->CreateTH1Fvector1(8, "h_Gamma_Mass_S", "S - Invariant mass of gammas; mass (GeV/c^{2}); counts", 100, 0, 0.2);
+  // gamma background
+  fQAmc->CreateTH2Fvector1(2, "h_cut_Gamma_CosPoint_B", "B - Gamma Cosine pointing angle; mom (GeV/c); cos point. angle", pN, pMin, pMax, 50, 0, 0.1, 0);
+  fQAmc->CreateTH2Fvector1(2, "h_cut_Gamma_DCA_B", "B - DCA between the gamma daughters; mom (GeV/c); dca (cm)", pN, pMin, pMax, 50, 0, 2, 0);
+  fQAmc->CreateTH2Fvector1(2, "h_cut_Gamma_VtxR_B", "B - Radius of the gamma conversion vertex; mom (GeV/c); r (cm)", pN, pMin, pMax, 100, 0, 100, 0);
+  fQAmc->CreateTH2Fvector1(2, "h_cut_Gamma_OA_B", "B - opening angle of the gamma products; mom (GeV/c); opening angle (rad)", pN, pMin, pMax, 50, 0, 0.3, 0);
+  fQAmc->CreateTH2Fvector1(2, "h_cut_Gamma_PP_B", "B - gamma psi pair angle; mom (GeV/c); psi pairangle (rad)", pN, pMin, pMax, 50, 0, 0.5, 0);
+  fQAmc->CreateTH2Fvector1(2, "h_cut_Gamma_Chi2_B", "B - gamma Chi2/NDF; mom (GeV/c); Chi2/NDF", pN, pMin, pMax, 50, 0, 100, 0);
+
+  fQAmc->CreateTH1Fvector1(8, "h_Gamma_Mass_B", "B - Invariant mass of gammas; mass (GeV/c^{2}); counts", 100, 0, 0.2);  
+  // kaons signal
+  fQAmc->CreateTH2Fvector1(2, "h_cut_K0_CosPoint_S", "S - K0 Cosine pointing angle; mom (GeV/c); cos point. angle", pN, pMin, pMax, 50, 0, 0.1, 0);
+  fQAmc->CreateTH2Fvector1(2, "h_cut_K0_DCA_S", "S - DCA between the K0 daughters; mom (GeV/c); dca (cm)", pN, pMin, pMax, 50, 0, 2, 0);
+  fQAmc->CreateTH2Fvector1(2, "h_cut_K0_VtxR_S", "S - Radius of the K0 decay vertex; mom (GeV/c); r (cm)", pN, pMin, pMax, 50, 0, 100, 0);
+  fQAmc->CreateTH2Fvector1(2, "h_cut_K0_Chi2_S", "S - K0 Chi2/NDF; mom (GeV/c); Chi2/NDF", pN, pMin, pMax, 50, 0, 100, 0);
+  fQAmc->CreateTH2Fvector1(2, "h_cut_K0_OA_S", "S - opening angle of the K0 pions; mom (GeV/c); opening angle (rad)", pN, pMin, pMax, 100, 0, 1, 0);
+
+  fQAmc->CreateTH1Fvector1(5, "h_K0_Mass_S", "S - Invariant mass of K0; mass (GeV/c^{2}); counts", 125, 0.45, 0.55);
+  // kaons background
+  fQAmc->CreateTH2Fvector1(2, "h_cut_K0_CosPoint_B", "B - K0 Cosine pointing angle; mom (GeV/c); cos point. angle", pN, pMin, pMax, 50, 0, 0.1, 0);
+  fQAmc->CreateTH2Fvector1(2, "h_cut_K0_DCA_B", "B - DCA between the K0 daughters; mom (GeV/c); dca (cm)", pN, pMin, pMax, 50, 0, 2, 0);
+  fQAmc->CreateTH2Fvector1(2, "h_cut_K0_VtxR_B", "B - Radius of the K0 decay vertex; mom (GeV/c); r (cm)", pN, pMin, pMax, 50, 0, 100, 0);
+  fQAmc->CreateTH2Fvector1(2, "h_cut_K0_Chi2_B", "B - K0 Chi2/NDF; mom (GeV/c); Chi2/NDF", pN, pMin, pMax, 50, 0, 100, 0);
+  fQAmc->CreateTH2Fvector1(2, "h_cut_K0_OA_B", "B - opening angle of the K0 pions; mom (GeV/c); opening angle (rad)", pN, pMin, pMax, 100, 0, 1, 0);
+
+  fQAmc->CreateTH1Fvector1(5, "h_K0_Mass_B", "B - Invariant mass of K0; mass (GeV/c^{2}); counts", 125, 0.45, 0.55);
+
+  // lambda signal
+  fQAmc->CreateTH2Fvector1(2, "h_cut_L_CosPoint_S", "S - L Cosine pointing angle; mom (GeV/c); cos point. angle", pN, pMin, pMax, 50, 0, 0.1, 0);
+  fQAmc->CreateTH2Fvector1(2, "h_cut_L_DCA_S", "S - DCA between the L daughters; mom (GeV/c); dca (cm)", pN, pMin, pMax, 50, 0, 2, 0);
+  fQAmc->CreateTH2Fvector1(2, "h_cut_L_VtxR_S", "S - Radius of the L decay vertex; mom (GeV/c); r (cm)", pN, pMin, pMax, 50, 0, 100, 0);
+  fQAmc->CreateTH2Fvector1(2, "h_cut_L_Chi2_S", "S - L Chi2/NDF; mom (GeV/c); Chi2/NDF", pN, pMin, pMax, 50, 0, 100, 0);
+  fQAmc->CreateTH2Fvector1(2, "h_cut_L_OA_S", "S - opening angle of the L p-p; mom (GeV/c); opening angle (rad)", pN, pMin, pMax, 100, 0, 1, 0);
+
+  fQAmc->CreateTH1Fvector1(5, "h_L_Mass_S", "S - Invariant mass of L; mass (GeV/c^{2}); counts", 60, 1.1, 1.13);
+  fQAmc->CreateTH1Fvector1(5, "h_AL_Mass_S", "S - Invariant mass of anti L; mass (GeV/c^{2}); counts", 60, 1.1, 1.13);
+  // lambda background
+  fQAmc->CreateTH2Fvector1(2, "h_cut_L_CosPoint_B", "B - L Cosine pointing angle; mom (GeV/c); cos point. angle", pN, pMin, pMax, 50, 0, 0.1, 0);
+  fQAmc->CreateTH2Fvector1(2, "h_cut_L_DCA_B", "B - DCA between the L daughters; mom (GeV/c); dca (cm)", pN, pMin, pMax, 50, 0, 2, 0);
+  fQAmc->CreateTH2Fvector1(2, "h_cut_L_VtxR_B", "B - Radius of the L decay vertex; mom (GeV/c); r (cm)", pN, pMin, pMax, 50, 0, 100, 0);
+  fQAmc->CreateTH2Fvector1(2, "h_cut_L_Chi2_B", "B - L Chi2/NDF; mom (GeV/c); Chi2/NDF", pN, pMin, pMax, 50, 0, 100, 0);
+  fQAmc->CreateTH2Fvector1(2, "h_cut_L_OA_B", "B - opening angle of the L p-p; mom (GeV/c); opening angle (rad)", pN, pMin, pMax, 100, 0, 1, 0);
+
+  fQAmc->CreateTH2Fvector1(2, "h_cut_L_rdp_v_mp_S", "S - relative L daughter mom -v- mother mom; L mom (GeV/c); relative daughter mom p2/p1", 100, 0.1, 10, 100, 0, 1);
+  fQAmc->CreateTH2Fvector1(2, "h_cut_L_rdp_v_mp_B", "B - relative L daughter mom -v- mother mom; L mom (GeV/c); relative daughter mom p2/p1", 100, 0.1, 10, 100, 0, 1);
+  fQAmc->CreateTH1Fvector1(5, "h_LAL_Mass_B", "B - Invariant mass of anti L; mass (GeV/c^{2}); counts", 60, 1.1, 1.13);
+
+
+  // MC tagged daughter track momentum distribution after each cut step
+//   fQAmc->CreateTH1Fvector1(10, "h_electron_p_S", "h_electron_p_S", 20, 0.1, 20, 0);
+//   fQAmc->CreateTH1Fvector1(10, "h_K0pion_p_S", "h_K0pion_p_S", 20, 0.1, 20, 0);
+//   fQAmc->CreateTH1Fvector1(10, "h_Lpion_p_S", "h_Lpion_p_S", 20, 0.1, 20, 0);
+//   fQAmc->CreateTH1Fvector1(10, "h_proton_p_S", "h_proton_p_S", 20, 0.1, 20, 0);
+
+  // V0 momnetum distribution of MC tagged signal and backglound after all cuts
+  fQAmc->CreateTH1F("h_gamma_p_S", "true gammas after all cuts", 20, 0.1, 10, 0);
+  fQAmc->CreateTH1F("h_gamma_p_B", "true gamma BG after all cuts", 20, 0.1, 10, 0);
+  fQAmc->CreateTH1F("h_K0_p_S", "true K0s after all cuts", 20, 0.1, 10, 0);
+  fQAmc->CreateTH1F("h_K0_p_B", "true K0 BG after all cuts", 20, 0.1, 10, 0);
+  fQAmc->CreateTH1F("h_lambda_p_S", "MC true lambdas after all cuts", 20, 0.1, 10, 0);
+  fQAmc->CreateTH1F("h_lambda_p_B", "MC true lambda BG after all cuts", 20, 0.1, 10, 0);
+  fQAmc->CreateTH1F("h_alambda_p_S", "MC true anti-lambdas after all cuts", 20, 0.1, 10, 0);
+  fQAmc->CreateTH1F("h_alambda_p_B", "MC true anti-lambda BG after all cuts", 20, 0.1, 10, 0);  
+
+  // invariant mass ditributions for the V0 for different hypoteses (gamma, K0, L, AL)
+  fQAmc->CreateTH1F("h_Mass_gamma_as_K0","h_Mass_gamma_as_K0", 200, 0, 2);
+  fQAmc->CreateTH1F("h_Mass_gamma_as_L","h_Mass_gamma_as_L", 200, 0, 2);
+  fQAmc->CreateTH1F("h_Mass_K0_as_G", "h_Mass_K0_as_gamma", 200, 0, 2);
+  fQAmc->CreateTH1F("h_Mass_K0_as_L", "h_Mass_K0_as_Lambda", 200, 0, 2);
+  fQAmc->CreateTH1F("h_Mass_L_as_G", "h_Mass_L_as_gamma", 200, 0, 2);
+  fQAmc->CreateTH1F("h_Mass_L_as_K0", "h_Mass_L_as_K0", 200, 0, 2);
+
+  // Invariant mass distribution of MC tagged signal for diffrent momenta
+  fQAmc->CreateTH2F("h_gamma_MvP_S", "mc tagged gammas - signal; p (GeV/c); m (GeV/c^{2})", 12, 0.1, 20, 100, 0., 0.1, 0);
+  fQAmc->CreateTH2F("h_K0_MvP_S", "mc tagged K0s - signal; p (GeV/c); m (GeV/c^{2})", 12, 0.1, 20, 100, 0.45, 0.55, 0);
+  fQAmc->CreateTH2F("h_lambda_MvP_S", "mc tagged Lambdas - signal; p (GeV/c); m (GeV/c^{2})", 12, 0.1, 20, 100, 1.08, 1.14, 0);
+    
+  // electrons
+  fQAmc->CreateTH1Fvector1(8, "h_Electron_P_S", "MC-S momenta of conversion electrons -cuts-; P (GeV/c); counts", 20, 0.1, 20, 0);
+  fQAmc->CreateTH1Fvector1(8, "h_Electron_P_B", "MC-B momenta of conversion electrons -cuts-; P (GeV/c); counts", 20, 0.1, 20, 0);
+
+  // K0 pions
+  fQAmc->CreateTH1Fvector1(7, "h_PionK0_P_S", "MC-S momenta of K0 pions -cuts-; P (GeV/c) counts;", 20, 0.1, 20, 0);
+  fQAmc->CreateTH1Fvector1(7, "h_PionK0_P_B", "MC-B momenta of K0 pions -cuts-; P (GeV/c) counts;", 20, 0.1, 20, 0);
+  
+  // L pions
+  fQAmc->CreateTH1Fvector1(8, "h_PionL_P_S", "MC-S momenta of L pions -cuts-; P (GeV/c) counts;", 20, 0.1, 50, 0);
+  fQAmc->CreateTH1Fvector1(8, "h_PionL_P_B", "MC-B momenta of L pions -cuts-; P (GeV/c) counts;", 20, 0.1, 50, 0);
+  
+  // L protons
+  fQAmc->CreateTH1Fvector1(8, "h_ProtonL_P_S", "MC-S momenta of L protons -cuts-; P (GeV/c) counts;", 20, 0.1, 20, 0);    
+  fQAmc->CreateTH1Fvector1(8, "h_ProtonL_P_B", "MC-B momenta of L protons -cuts-; P (GeV/c) counts;", 20, 0.1, 20, 0);    
+
+
+
+  // cut efficiencies 
 }
 //________________________________________________________________
 Bool_t AliHFEV0cuts::TrackCutsCommon(AliESDtrack* track){
@@ -205,6 +338,7 @@ Bool_t AliHFEV0cuts::TrackCutsCommon(AliESDtrack* track){
   //
 
   if(!track) return kFALSE;
   
   // status word
   ULong_t status = track->GetStatus();
@@ -212,7 +346,7 @@ Bool_t AliHFEV0cuts::TrackCutsCommon(AliESDtrack* track){
 
   // No. of TPC clusters
   fQA->Fill("h_ST_NclsTPC", track->GetTPCNcls());
-  if(track->GetTPCNcls() < 80) return kFALSE;
+  if(track->GetTPCNcls() < 80) return kFALSE;   //
 
   // TPC refit
   if((status & AliESDtrack::kTPCrefit)){
@@ -227,7 +361,7 @@ Bool_t AliHFEV0cuts::TrackCutsCommon(AliESDtrack* track){
   Int_t nTPCclusters = track->GetTPCclusters(0);
   Float_t chi2perTPCcluster = track->GetTPCchi2()/Float_t(nTPCclusters);
   fQA->Fill("h_ST_chi2TPCcls", chi2perTPCcluster);
-  if(chi2perTPCcluster > 3.5) return kFALSE;
+  if(chi2perTPCcluster > 3.5) return kFALSE;   // 4.0
 
   // TPC cluster ratio
   Float_t cRatioTPC = track->GetTPCNclsF() > 0. ? static_cast<Float_t>(track->GetTPCNcls())/static_cast<Float_t> (track->GetTPCNclsF()) : 1.;
@@ -240,7 +374,7 @@ Bool_t AliHFEV0cuts::TrackCutsCommon(AliESDtrack* track){
 
   // pt
   fQA->Fill("h_ST_pt",track->Pt());
-  if(track->Pt() < 0.1 || track->Pt() > 100) return kFALSE;
+  if(track->Pt() < 0.1 || track->Pt() > 100) return kFALSE; //
 
   // eta
   fQA->Fill("h_ST_eta", track->Eta());
@@ -253,7 +387,7 @@ Bool_t AliHFEV0cuts::V0CutsCommon(AliESDv0 *v0){
   //
   // V0 cuts common to all V0s
   //
-  
+
   AliESDtrack* dN, *dP; 
  
   dP = dynamic_cast<AliESDtrack *>(fInputEvent->GetTrack(v0->GetPindex()));
@@ -276,8 +410,16 @@ Bool_t AliHFEV0cuts::GammaCuts(AliESDv0 *v0){
   
   if(!v0) return kFALSE;
 
+  if(fMCEvent){
+    if(1 == fCurrentV0id){
+      fQAmc->Fill("h_Mass_gamma_as_K0",  v0->GetEffMass(2, 2));
+      fQAmc->Fill("h_Mass_gamma_as_L",  v0->GetEffMass(2, 4));
+      fQAmc->Fill("h_Mass_gamma_as_L",  v0->GetEffMass(4, 2));
+    }
+  }
+
   // loose cuts first
-  if(LooseRejectK0(v0) || LooseRejectLambda(v0)) return kFALSE;
+  //if(LooseRejectK0(v0) || LooseRejectLambda(v0)) return kFALSE;
 
   AliVTrack* daughter[2];
   Int_t pIndex = 0, nIndex = 0;
@@ -297,7 +439,7 @@ Bool_t AliHFEV0cuts::GammaCuts(AliESDv0 *v0){
   if(!kfMother) return kFALSE;
   
   // production vertex is set in the 'CreateMotherParticle' function
-  kfMother->SetMassConstraint(0, 0.001);
+  //kfMother->SetMassConstraint(0, 0.001);
 
   AliESDtrack* d[2];
   d[0] = dynamic_cast<AliESDtrack*>(fInputEvent->GetTrack(pIndex));
@@ -307,22 +449,15 @@ Bool_t AliHFEV0cuts::GammaCuts(AliESDv0 *v0){
   Float_t iP = v0->P();
   Float_t p[2] = {d[0]->GetP(), d[1]->GetP()};
 
-  // Armenteros
-  Float_t ap[2];
-  Armenteros(v0, ap);
-
   // Cut values
-  const Double_t cutCosPoint[2] = {0., 0.03};  // ORG [0., 0.03]
+  const Double_t cutChi2NDF = 40.;              // ORG [7.]  
+  const Double_t cutCosPoint[2] = {0., 0.02};  // ORG [0., 0.03]
   const Double_t cutDCA[2] = {0., 0.25};       // ORG [0., 0.25]
-  const Double_t cutProdVtxR[2] = {6., 50.};   // ORG [6., 9999]
-  const Double_t cutOAngle[2] = {0, 0.1};      // ORG [0., 0.1]
+  const Double_t cutProdVtxR[2] = {8., 90.};   // ORG [6., 9999]
   const Double_t cutPsiPair[2] = {0., 0.05};   // ORG [0. 0.05]
+  const Double_t cutOAngle[2] = {0, 0.1};      // ORG [0., 0.1]
+  // mass cut
   const Double_t cutMass = 0.05;               // ORG [0.05]
-  const Double_t cutChi2NDF = 7.;              // ORG [7.]
-  // armenteros cuts
-  const Double_t cutAlpha[2] = {0.35, 0.45};   // [0.35, 0.45]
-  const Double_t cutQT = 0.015;
-  
   // Values
    
   // cos pointing angle
@@ -337,6 +472,13 @@ Bool_t AliHFEV0cuts::GammaCuts(AliESDv0 *v0){
   v0->GetXYZ(x,y,z);
   Double_t r = TMath::Sqrt(x*x + y*y);
 
+  Double_t xy[2];
+  Double_t r2 = -1.;
+  if ( GetConvPosXY(d[0], d[1], xy) ){
+    r2 = TMath::Sqrt(xy[0]*xy[0] + xy[1]*xy[1]);
+  }
+
+
   // Opening angle
   Double_t oAngle = OpenAngle(v0);
 
@@ -352,90 +494,244 @@ Bool_t AliHFEV0cuts::GammaCuts(AliESDv0 *v0){
   // Apply the cuts, produce QA plots (with mass cut)
   //
   fQA->Fill("h_Gamma_Mass", 0, iMass);
+  
+  // MC
+  if(fMCEvent){
+    if(1 == fCurrentV0id){
+      fQAmc->Fill("h_Gamma_Mass_S", 0, iMass);
+      fQAmc->Fill("h_gamma_MvP_S", iP, iMass);
+    }
+    else if(-2 != fCurrentV0id) fQAmc->Fill("h_Gamma_Mass_B", 0, iMass);
+  }
+  // cut distributions
   if(iMass < cutMass){
-    fQA->Fill("h_all_AP", 0, ap[0], ap[1]);
     fQA->Fill("h_Electron_P", 0, p[0]);
     fQA->Fill("h_Electron_P", 0, p[1]);
     fQA->Fill("h_cut_Gamma_CosPoint", 0, cosPoint);
-    fQA->Fill("h_cut_Gamma_CosPoint", 1, cosPoint);
     fQA->Fill("h_cut_Gamma_DCA", 0, dca);
-    fQA->Fill("h_cut_Gamma_VtxR", 0, r);
+    fQA->Fill("h_cut_Gamma_VtxR_old", 0, r);
+    fQA->Fill("h_cut_Gamma_VtxR", 0, r2);
     fQA->Fill("h_cut_Gamma_OA", 0, oAngle);
     fQA->Fill("h_cut_Gamma_PP", 0, psiPair);
     fQA->Fill("h_cut_Gamma_Chi2", 0, chi2ndf);
+    fQA->Fill("h_cut_Gamma_Chi2", 1, chi2ndf, iP);
     fQA->Fill("h_cut_Gamma_OAvP", 0, iP, oAngle);      
-    fQA->Fill("h_cut_Gamma_AP", 0, ap[0], ap[1]);
- }
+   
+    if(fMCEvent){
+      // MC signal
+      if(1 == fCurrentV0id){
+       fQAmc->Fill("h_cut_Gamma_CosPoint_S", 0, iP, cosPoint);
+       fQAmc->Fill("h_cut_Gamma_DCA_S", 0, iP, dca);
+       fQAmc->Fill("h_cut_Gamma_VtxR_S", 0, iP, r2);
+       fQAmc->Fill("h_cut_Gamma_OA_S", 0, iP, oAngle);
+       fQAmc->Fill("h_cut_Gamma_PP_S", 0, iP, psiPair);
+       fQAmc->Fill("h_cut_Gamma_Chi2_S", 0, iP, chi2ndf);
+       fQAmc->Fill("h_cut_Gamma_Chi2_S", 1, iP, chi2ndf);
+       fQAmc->Fill("h_Electron_P_S", 0, p[0]);
+       fQAmc->Fill("h_Electron_P_S", 0, p[1]);
+      }
+      // MC background
+      else if(-2 != fCurrentV0id){
+       fQAmc->Fill("h_cut_Gamma_CosPoint_B", 0, iP, cosPoint);
+       fQAmc->Fill("h_cut_Gamma_DCA_B", 0, iP, dca);
+       fQAmc->Fill("h_cut_Gamma_VtxR_B", 0, iP, r2);
+       fQAmc->Fill("h_cut_Gamma_OA_B", 0, iP, oAngle);
+       fQAmc->Fill("h_cut_Gamma_PP_B", 0, iP, psiPair);
+       fQAmc->Fill("h_cut_Gamma_Chi2_B", 0, iP, chi2ndf);
+       fQAmc->Fill("h_cut_Gamma_Chi2_B", 1, iP, chi2ndf);
+       fQAmc->Fill("h_Electron_P_B", 0, p[0]);
+       fQAmc->Fill("h_Electron_P_B", 0, p[1]); 
+      }
+    }
+  }
 
-  if(cosPoint < cutCosPoint[0] || cosPoint > cutCosPoint[1]) return kFALSE;
+
+  //
+  // Chi2/NDF cut
+  //
+  if(chi2ndf > cutChi2NDF) return kFALSE;
   fQA->Fill("h_Gamma_Mass", 1, iMass);
   if(iMass < cutMass){
+    fQA->Fill("h_cut_Gamma_CosPoint", 1, cosPoint);
     fQA->Fill("h_Electron_P", 1, p[0]);
     fQA->Fill("h_Electron_P", 1, p[1]);
-    fQA->Fill("h_cut_Gamma_DCA", 1, dca);
   }
-  
-  if(dca < cutDCA[0] || dca > cutDCA[1]) return kFALSE;
+  if(fMCEvent){
+    if(1 == fCurrentV0id) fQAmc->Fill("h_Gamma_Mass_S", 1, iMass);
+    else if(-2 != fCurrentV0id) fQAmc->Fill("h_Gamma_Mass_B", 1, iMass);
+    if(iMass < cutMass){
+      if(1 == fCurrentV0id){
+       fQAmc->Fill("h_cut_Gamma_CosPoint_S", 1, iP, cosPoint);
+       fQAmc->Fill("h_Electron_P_S", 1, p[0]);
+       fQAmc->Fill("h_Electron_P_S", 1, p[1]);
+      }
+      else if(-2 != fCurrentV0id){
+       fQAmc->Fill("h_cut_Gamma_CosPoint_B", 1, iP, cosPoint);
+       fQAmc->Fill("h_Electron_P_B", 1, p[0]);
+       fQAmc->Fill("h_Electron_P_B", 1, p[1]);
+      }
+    }
+  }
+
+  //
+  // Cos point cut
+  //
+  if(cosPoint < cutCosPoint[0] || cosPoint > cutCosPoint[1]) return kFALSE;
   fQA->Fill("h_Gamma_Mass", 2, iMass);
   if(iMass < cutMass){
     fQA->Fill("h_Electron_P", 2, p[0]);
     fQA->Fill("h_Electron_P", 2, p[1]);
-    fQA->Fill("h_cut_Gamma_VtxR", 1, r);
+    fQA->Fill("h_cut_Gamma_DCA", 1, dca);
   }
-
-  if(r < cutProdVtxR[0] || r > cutProdVtxR[1]) return kFALSE;
+  if(fMCEvent){
+    if(1 == fCurrentV0id) fQAmc->Fill("h_Gamma_Mass_S", 2, iMass);
+    else if(-2 != fCurrentV0id) fQAmc->Fill("h_Gamma_Mass_B", 2, iMass);
+    if(iMass < cutMass){
+      if(1 == fCurrentV0id){
+       fQAmc->Fill("h_cut_Gamma_DCA_S", 1, iP, dca);
+       fQAmc->Fill("h_Electron_P_S", 2, p[0]);
+       fQAmc->Fill("h_Electron_P_S", 2, p[1]);
+
+      }
+      else if(-2 != fCurrentV0id){
+       fQAmc->Fill("h_cut_Gamma_DCA_B", 1, iP, dca);
+       fQAmc->Fill("h_Electron_P_B", 2, p[0]);
+       fQAmc->Fill("h_Electron_P_B", 2, p[1]);
+
+      }
+    }
+  }
+  
+  //
+  // DCA cut
+  //
+  if(dca < cutDCA[0] || dca > cutDCA[1]) return kFALSE;
   fQA->Fill("h_Gamma_Mass", 3, iMass);
   if(iMass < cutMass){
     fQA->Fill("h_Electron_P", 3, p[0]);
     fQA->Fill("h_Electron_P", 3, p[1]);
-    fQA->Fill("h_cut_Gamma_OA", 1, oAngle);
+    fQA->Fill("h_cut_Gamma_VtxR_old", 1, r);
+    fQA->Fill("h_cut_Gamma_VtxR", 1, r2);
+  }
+  if(fMCEvent){
+    if(1 == fCurrentV0id) fQAmc->Fill("h_Gamma_Mass_S", 3, iMass);
+    else if(-2 != fCurrentV0id) fQAmc->Fill("h_Gamma_Mass_B", 3, iMass);
+    if(iMass < cutMass){
+      if(1 == fCurrentV0id){
+       fQAmc->Fill("h_cut_Gamma_VtxR_S", 1, iP, r2);
+       fQAmc->Fill("h_Electron_P_S", 3, p[0]);
+       fQAmc->Fill("h_Electron_P_S", 3, p[1]);
+
+      }
+      else if(-2 != fCurrentV0id){
+       fQAmc->Fill("h_cut_Gamma_VtxR_B", 1, iP, r2);
+       fQAmc->Fill("h_Electron_P_B", 3, p[0]);
+       fQAmc->Fill("h_Electron_P_B", 3, p[1]); 
+      }
+    }
   }
 
-  if(oAngle < cutOAngle[0] || oAngle > cutOAngle[1]) return kFALSE;
+  //
+  // Vertex radius cut
+  //
+  if(r < cutProdVtxR[0] || r > cutProdVtxR[1]) return kFALSE;
   fQA->Fill("h_Gamma_Mass", 4, iMass);
   if(iMass < cutMass){
+    fQA->Fill("h_cut_Gamma_PP", 1, psiPair);
     fQA->Fill("h_Electron_P", 4, p[0]);
     fQA->Fill("h_Electron_P", 4, p[1]);
-    fQA->Fill("h_cut_Gamma_PP", 1, psiPair);
+  }
+  if(fMCEvent){
+    if(1 == fCurrentV0id) fQAmc->Fill("h_Gamma_Mass_S", 4, iMass);
+    else if(-2 != fCurrentV0id) fQAmc->Fill("h_Gamma_Mass_B", 4, iMass);
+    if(iMass < cutMass){
+      if(1 == fCurrentV0id){
+       fQAmc->Fill("h_cut_Gamma_PP_S", 1, iP, psiPair);
+       fQAmc->Fill("h_Electron_P_S", 4, p[0]);
+       fQAmc->Fill("h_Electron_P_S", 4, p[1]);
+      }
+      else if(-2 != fCurrentV0id){
+       fQAmc->Fill("h_cut_Gamma_PP_B", 1, iP, psiPair);
+       fQAmc->Fill("h_Electron_P_B", 4, p[0]);
+       fQAmc->Fill("h_Electron_P_B", 4, p[1]);
+      }
+    }
   }
 
+
+  //
+  // PsiPair cut
+  //
   if(psiPair < cutPsiPair[0] || psiPair > cutPsiPair[1]) return kFALSE;
   fQA->Fill("h_Gamma_Mass", 5, iMass);
   if(iMass < cutMass){
+    fQA->Fill("h_cut_Gamma_OA", 1, oAngle);
+    fQA->Fill("h_cut_Gamma_OAvP", 1, iP, oAngle);      
     fQA->Fill("h_Electron_P", 5, p[0]);
     fQA->Fill("h_Electron_P", 5, p[1]);
-    fQA->Fill("h_cut_Gamma_Chi2", 1, chi2ndf);
+  }
+  if(fMCEvent){
+    if(1 == fCurrentV0id) fQAmc->Fill("h_Gamma_Mass_S", 5, iMass);
+    else if(-2 != fCurrentV0id)fQAmc->Fill("h_Gamma_Mass_B", 5, iMass);
+    
+    if(iMass < cutMass){
+      if(1 == fCurrentV0id){
+       fQAmc->Fill("h_cut_Gamma_OA_S", 1, iP, oAngle);
+       fQAmc->Fill("h_Electron_P_S", 5, p[0]);
+       fQAmc->Fill("h_Electron_P_S", 5, p[1]);
+      }
+      else if(-2 != fCurrentV0id){
+       fQAmc->Fill("h_cut_Gamma_OA_B", 1, iP, oAngle);
+       fQAmc->Fill("h_Electron_P_B", 5, p[0]);
+       fQAmc->Fill("h_Electron_P_B", 5, p[1]);
+      }
+    }
   }
 
-  if(chi2ndf > cutChi2NDF) return kFALSE;
+  //
+  // Opening angle cut (obsolete?)
+  //
+  if(oAngle < cutOAngle[0] || oAngle > cutOAngle[1]) return kFALSE;
   fQA->Fill("h_Gamma_Mass", 6, iMass);
   if(iMass < cutMass){
     fQA->Fill("h_Electron_P", 6, p[0]);
     fQA->Fill("h_Electron_P", 6, p[1]);
-    fQA->Fill("h_cut_Gamma_OAvP", 1, iP, oAngle);      
-    fQA->Fill("h_all_AP", 1, ap[0], ap[1]);
-    fQA->Fill("h_cut_Gamma_AP", 1, ap[0], ap[1]);
   }
-
-  if(TMath::Abs(ap[0]) > cutAlpha[0] && TMath::Abs(ap[0]) < cutAlpha[1]) return kFALSE;
-  fQA->Fill("h_Gamma_Mass", 7, iMass);
-  if(iMass < cutMass){
-    fQA->Fill("h_Electron_P", 7, p[0]);
-    fQA->Fill("h_Electron_P", 7, p[1]);
-  }
-
-  if(ap[1] > cutQT) return kFALSE;
-  fQA->Fill("h_Gamma_Mass", 8, iMass);
-  if(iMass < cutMass){
-    fQA->Fill("h_Electron_P", 8, p[0]);
-    fQA->Fill("h_Electron_P", 8, p[1]);
+  if(fMCEvent){
+    if(1 == fCurrentV0id) fQAmc->Fill("h_Gamma_Mass_S", 6, iMass);
+    else if(-2 != fCurrentV0id) fQAmc->Fill("h_Gamma_Mass_B", 6, iMass);
+    if(iMass < cutMass){
+      if(1 == fCurrentV0id){
+       fQAmc->Fill("h_Electron_P_S", 6, p[0]);
+       fQAmc->Fill("h_Electron_P_S", 6, p[1]);
+      }
+      else if(-2 != fCurrentV0id){
+       fQAmc->Fill("h_Electron_P_B", 6, p[0]);
+       fQAmc->Fill("h_Electron_P_B", 6, p[1]);
+      }
+    }
   }
   
 
   if(iMass > cutMass) return kFALSE;
 
   // all cuts passed
-    
+
+  
+  // some MC stuff
+  //printf("**D: gamma V0id: %i, P: %i, N: %i \n", fCurrentV0id, fPdaughterPDG, fNdaughterPDG);
+  if(1 == fCurrentV0id){
+    fQAmc->Fill("h_gamma_p_S", iP);
+    fQAmc->Fill("h_Electron_P_S", 7, p[0]);
+    fQAmc->Fill("h_Electron_P_S", 7, p[1]);
+  }
+  else if (-2 != fCurrentV0id){
+    fQAmc->Fill("h_gamma_p_B", iP);
+    fQAmc->Fill("h_Electron_P_B", 7, p[0]);
+    fQAmc->Fill("h_Electron_P_B", 7, p[1]);
+  }
+
+
   return kTRUE;
 }
 //________________________________________________________________
@@ -446,7 +742,15 @@ Bool_t AliHFEV0cuts::K0Cuts(AliESDv0 *v0){
 
   if(!v0) return kFALSE;
 
-  const Double_t cK0mass=TDatabasePDG::Instance()->GetParticle(kK0Short)->Mass();  // PDG K0s mass
+  if(fMCEvent){
+    if(2 == fCurrentV0id){
+      fQAmc->Fill("h_Mass_K0_as_G",  v0->GetEffMass(0, 0));
+      fQAmc->Fill("h_Mass_K0_as_L",  v0->GetEffMass(2, 4));
+      fQAmc->Fill("h_Mass_K0_as_L",  v0->GetEffMass(4, 2));
+    }
+  }
+
+  //const Double_t cK0mass=TDatabasePDG::Instance()->GetParticle(kK0Short)->Mass();  // PDG K0s mass
   AliVTrack* daughter[2];
   Int_t pIndex = 0, nIndex = 0;
   if(CheckSigns(v0)){
@@ -465,7 +769,7 @@ Bool_t AliHFEV0cuts::K0Cuts(AliESDv0 *v0){
   AliKFParticle *kfMother = CreateMotherParticle(daughter[0], daughter[1], TMath::Abs(kPiPlus), TMath::Abs(kPiPlus));
   if(!kfMother) return kFALSE;
   // production vertex is set in the 'CreateMotherParticle' function
-  kfMother->SetMassConstraint(cK0mass, 0.);
+  //kfMother->SetMassConstraint(cK0mass, 0.);
   
   AliESDtrack* d[2];
   d[0] = dynamic_cast<AliESDtrack*>(fInputEvent->GetTrack(pIndex));
@@ -478,18 +782,14 @@ Bool_t AliHFEV0cuts::K0Cuts(AliESDv0 *v0){
   Double_t phi = v0->Phi();
   Double_t pt = v0->Pt();
   Double_t data[4] = {0., 0., 0., 0.};
+
   // Cut values
-  const Double_t cutCosPoint[2] = {0., 0.03};  // ORG [0., 0.03]
+  const Double_t cutChi2NDF = 40.;              // ORG [7.]
+  const Double_t cutCosPoint[2] = {0., 0.02};  // ORG [0., 0.03]
   const Double_t cutDCA[2] = {0., 0.2};        // ORG [0., 0.1]
   const Double_t cutProdVtxR[2] = {2.0, 30.};   // ORG [0., 8.1]
   const Double_t cutMass[2] = {0.49, 0.51};   // ORG [0.485, 0.51]
-  const Double_t cutChi2NDF = 5.;              // ORG [7.]
-  const Double_t cutOAngleP = (1.0/(iP + 0.3) - 0.1); // momentum dependent min. OAngle ~ 1/x
-  // cundidate cuts
-  // armenteros plot
-  const Double_t cutQT = 0.1075;
-  // elipse cut - see bellow
-
+  //const Double_t cutOAngleP = (1.0/(iP + 0.3) - 0.1); // momentum dependent min. OAngle ~ 1/x
   // Values
 
   // cos pointing angle
@@ -513,84 +813,164 @@ Bool_t AliHFEV0cuts::K0Cuts(AliESDv0 *v0){
   // Opening angle
   Double_t oAngle = OpenAngle(v0);
   
-  // Armenteros
-  Float_t ap[2];
-  Armenteros(v0, ap);
-  const Double_t cutAP = 0.22 * TMath::Sqrt( TMath::Abs( (1-ap[0]*ap[0]/(0.92*0.92)) ) );
-  
-
   //
   // Apply the cuts, produce QA plots (with mass cut)
   //
 
   fQA->Fill("h_K0_Mass", 0, iMass);
+  // MC
+  if(fMCEvent){
+    if(2 == fCurrentV0id){
+      fQAmc->Fill("h_K0_Mass_S", 0, iMass);
+      fQAmc->Fill("h_K0_MvP_S", iP, iMass);
+    }
+    else if(-2 != fCurrentV0id) fQAmc->Fill("h_K0_Mass_B", 0, iMass);
+  }
+
   if(iMass > cutMass[0] && iMass < cutMass[1]){
-    fQA->Fill("h_all_AP", 0, ap[0], ap[1]);
     fQA->Fill("h_PionK0_P", 0, p[0]);
     fQA->Fill("h_PionK0_P", 0, p[1]);
     fQA->Fill("h_cut_K0_CosPoint", 0, cosPoint);
-    fQA->Fill("h_cut_K0_CosPoint", 1, cosPoint);
     fQA->Fill("h_cut_K0_DCA", 0, dca);
     fQA->Fill("h_cut_K0_VtxR", 0, r);
     fQA->Fill("h_cut_K0_Chi2", 0, chi2ndf);
-    fQA->Fill("h_cut_K0_OAvP", 0, iP, oAngle);
-    fQA->Fill("h_cut_K0_AP", 0, ap[0], ap[1]);
+    fQA->Fill("h_cut_K0_Chi2", 1, chi2ndf);
+  }
+  
+  // MC
+  if(fMCEvent){
+    if(iMass > cutMass[0] && iMass < cutMass[1]){   
+      if(2 == fCurrentV0id){
+       fQAmc->Fill("h_cut_K0_CosPoint_S", 0, iP, cosPoint);
+       fQAmc->Fill("h_cut_K0_DCA_S", 0, iP, dca);
+       fQAmc->Fill("h_cut_K0_VtxR_S", 0, iP, r);
+       fQAmc->Fill("h_cut_K0_Chi2_S", 0, iP, chi2ndf);
+       fQAmc->Fill("h_cut_K0_Chi2_S", 1, iP, chi2ndf);
+       fQAmc->Fill("h_cut_K0_OA_S", 0, iP, oAngle);
+       fQAmc->Fill("h_PionK0_P_S", 0, p[0]);
+       fQAmc->Fill("h_PionK0_P_S", 0, p[1]);
+       }
+      else if(-2 != fCurrentV0id){
+       fQAmc->Fill("h_cut_K0_CosPoint_B", 0, iP, cosPoint);
+       fQAmc->Fill("h_cut_K0_DCA_B", 0, iP, dca);
+       fQAmc->Fill("h_cut_K0_VtxR_B", 0, iP, r);
+       fQAmc->Fill("h_cut_K0_Chi2_B", 0, iP, chi2ndf);
+       fQAmc->Fill("h_cut_K0_Chi2_B", 1, iP, chi2ndf);
+       fQAmc->Fill("h_cut_K0_OA_B", 0, iP, oAngle);
+       fQAmc->Fill("h_PionK0_P_B", 0, p[0]);
+       fQAmc->Fill("h_PionK0_P_B", 0, p[1]);
+      }  
+    }
   }
 
-  if(cosPoint < cutCosPoint[0] || cosPoint > cutCosPoint[1]) return kFALSE;
+  //
+  // Chi2/NDF cut
+  //
+  if(chi2ndf > cutChi2NDF) return kFALSE;
   fQA->Fill("h_K0_Mass", 1, iMass);
   if(iMass > cutMass[0] && iMass < cutMass[1]){
+    fQA->Fill("h_cut_K0_CosPoint", 1, cosPoint);
     fQA->Fill("h_PionK0_P", 1, p[0]);
     fQA->Fill("h_PionK0_P", 1, p[1]);
-    fQA->Fill("h_cut_K0_DCA", 1, dca);
+  }  
+  if(fMCEvent){
+    if(2 == fCurrentV0id) fQAmc->Fill("h_K0_Mass_S", 1, iMass);
+    else if(-2 != fCurrentV0id) fQAmc->Fill("h_K0_Mass_B", 1, iMass);
+     if(iMass > cutMass[0] && iMass < cutMass[1]){
+       if(2 == fCurrentV0id){
+        fQAmc->Fill("h_cut_K0_CosPoint_S", 1, iP, cosPoint);
+        fQAmc->Fill("h_PionK0_P_S", 1, p[0]);
+        fQAmc->Fill("h_PionK0_P_S", 1, p[1]);
+       }
+       else if(-2 != fCurrentV0id){
+        fQAmc->Fill("h_cut_K0_CosPoint_B", 1, iP, cosPoint);
+        fQAmc->Fill("h_PionK0_P_B", 1, p[0]);
+        fQAmc->Fill("h_PionK0_P_B", 1, p[1]);
+       }
+     }
   }
-  
-  if(dca < cutDCA[0] || dca > cutDCA[1]) return kFALSE;
+
+  //
+  // Cos point cut
+  //
+  if(cosPoint < cutCosPoint[0] || cosPoint > cutCosPoint[1]) return kFALSE;
   fQA->Fill("h_K0_Mass", 2, iMass);
   if(iMass > cutMass[0] && iMass < cutMass[1]){
     fQA->Fill("h_PionK0_P", 2, p[0]);
     fQA->Fill("h_PionK0_P", 2, p[1]);
-    fQA->Fill("h_cut_K0_VtxR", 1, r);
+    fQA->Fill("h_cut_K0_DCA", 1, dca);
+  }
+  if(fMCEvent){
+    if(2 == fCurrentV0id) fQAmc->Fill("h_K0_Mass_S", 2, iMass);
+    else if(-2 != fCurrentV0id) fQAmc->Fill("h_K0_Mass_B", 2, iMass);
+     if(iMass > cutMass[0] && iMass < cutMass[1]){
+       if(2 == fCurrentV0id){
+        fQAmc->Fill("h_cut_K0_DCA_S", 1, iP, dca);
+        fQAmc->Fill("h_PionK0_P_S", 2, p[0]);
+        fQAmc->Fill("h_PionK0_P_S", 2, p[1]);
+       }
+       else if(-2 != fCurrentV0id){
+        fQAmc->Fill("h_cut_K0_DCA_B", 1, iP, dca);
+        fQAmc->Fill("h_PionK0_P_B", 2, p[0]);
+        fQAmc->Fill("h_PionK0_P_B", 2, p[1]);
+       }
+     }
   }
-
   
-  if(r < cutProdVtxR[0] || r > cutProdVtxR[1]) return kFALSE;
+
+  //
+  // DCA cut
+  //
+  if(dca < cutDCA[0] || dca > cutDCA[1]) return kFALSE;
   fQA->Fill("h_K0_Mass", 3, iMass);
   if(iMass > cutMass[0] && iMass < cutMass[1]){
     fQA->Fill("h_PionK0_P", 3, p[0]);
     fQA->Fill("h_PionK0_P", 3, p[1]);
-    fQA->Fill("h_cut_K0_Chi2", 1, chi2ndf);
+    fQA->Fill("h_cut_K0_VtxR", 1, r);
+  }
+  if(fMCEvent){
+    if(2 == fCurrentV0id) fQAmc->Fill("h_K0_Mass_S", 3, iMass);
+    else if(-2 != fCurrentV0id) fQAmc->Fill("h_K0_Mass_B", 3, iMass);
+     if(iMass > cutMass[0] && iMass < cutMass[1]){
+       if(2 == fCurrentV0id){
+        fQAmc->Fill("h_cut_K0_VtxR_S", 1, iP, r);
+        fQAmc->Fill("h_PionK0_P_S", 3, p[0]);
+        fQAmc->Fill("h_PionK0_P_S", 3, p[1]);
+       }
+       else if(-2 != fCurrentV0id){
+        fQAmc->Fill("h_cut_K0_VtxR_B", 1, iP, r);
+        fQAmc->Fill("h_PionK0_P_B", 3, p[0]);
+        fQAmc->Fill("h_PionK0_P_B", 3, p[1]);
+       }
+     }
   }
 
-  if(chi2ndf > cutChi2NDF) return kFALSE;
+  
+  //
+  // Vertex R cut
+  //
+  if(r < cutProdVtxR[0] || r > cutProdVtxR[1]) return kFALSE;
   fQA->Fill("h_K0_Mass", 4, iMass);
   if(iMass > cutMass[0] && iMass < cutMass[1]){
     fQA->Fill("h_PionK0_P", 4, p[0]);
     fQA->Fill("h_PionK0_P", 4, p[1]);
     fQA->Fill("h_cut_K0_OAvP", 1, iP, oAngle);
-  }  
-
-  if(oAngle < cutOAngleP) return kFALSE;
-  fQA->Fill("h_K0_Mass", 5, iMass);
-  if(iMass > cutMass[0] && iMass < cutMass[1]){
-    fQA->Fill("h_PionK0_P", 5, p[0]);
-    fQA->Fill("h_PionK0_P", 5, p[1]);
-    fQA->Fill("h_cut_K0_AP", 1, ap[0], ap[1]);
-    fQA->Fill("h_all_AP", 1, ap[0], ap[1]);
   }
-
-  if(ap[1] < cutQT) return kFALSE;
-  fQA->Fill("h_K0_Mass", 6, iMass);
-  if(iMass > cutMass[0] && iMass < cutMass[1]){
-    fQA->Fill("h_PionK0_P", 6, p[0]);
-    fQA->Fill("h_PionK0_P", 6, p[1]);
-  }
-    
-  if(ap[1] > cutAP) return kFALSE;
-  fQA->Fill("h_K0_Mass", 7, iMass);
-  if(iMass > cutMass[0] && iMass < cutMass[1]){
-    fQA->Fill("h_PionK0_P", 7, p[0]);
-    fQA->Fill("h_PionK0_P", 7, p[1]);
+  if(fMCEvent){
+    if(2 == fCurrentV0id) fQAmc->Fill("h_K0_Mass_S", 4, iMass);
+    else if(-2 != fCurrentV0id) fQAmc->Fill("h_K0_Mass_B", 4, iMass);
+     if(iMass > cutMass[0] && iMass < cutMass[1]){
+       if(2 == fCurrentV0id){
+        fQAmc->Fill("h_cut_K0_OA_S", 1, iP, oAngle);
+        fQAmc->Fill("h_PionK0_P_S", 4, p[0]);
+        fQAmc->Fill("h_PionK0_P_S", 4, p[1]);
+       }
+       else if(-2 != fCurrentV0id){
+        fQAmc->Fill("h_cut_K0_OA_B", 1, iP, oAngle);
+        fQAmc->Fill("h_PionK0_P_B", 4, p[0]);
+        fQAmc->Fill("h_PionK0_P_B", 4, p[1]);
+       }
+     }
   }
 
   data[0] = iMass;
@@ -605,6 +985,18 @@ Bool_t AliHFEV0cuts::K0Cuts(AliESDv0 *v0){
 
   // all cuts passed
   
+  // some MC stuff
+  if(2 == fCurrentV0id){
+    fQAmc->Fill("h_K0_p_S", iP);
+    fQAmc->Fill("h_PionK0_P_S", 5, p[0]);
+    fQAmc->Fill("h_PionK0_P_S", 5, p[1]);
+  }
+  else if (-2 != fCurrentV0id){
+    fQAmc->Fill("h_K0_p_B", iP);
+    fQAmc->Fill("h_PionK0_P_B", 5, p[0]);
+    fQAmc->Fill("h_PionK0_P_B", 5, p[1]);
+  }
+
   return kTRUE;
 }
 //________________________________________________________________
@@ -618,8 +1010,14 @@ Bool_t AliHFEV0cuts::LambdaCuts(AliESDv0 *v0, Bool_t &isLambda ){
 
   if(!v0) return kFALSE;
 
+  if(fMCEvent){
+    if(4 == fCurrentV0id){
+      fQAmc->Fill("h_Mass_L_as_G",  v0->GetEffMass(0, 0));
+      fQAmc->Fill("h_Mass_L_as_K0",  v0->GetEffMass(2, 0));
+    }
+  }
   // loose cuts first
-  if(LooseRejectK0(v0) || LooseRejectGamma(v0)) return kFALSE;
+  //if(LooseRejectK0(v0) || LooseRejectGamma(v0)) return kFALSE;
   
   const Double_t cL0mass=TDatabasePDG::Instance()->GetParticle(kLambda0)->Mass();  // PDG lambda mass
 
@@ -649,13 +1047,13 @@ Bool_t AliHFEV0cuts::LambdaCuts(AliESDv0 *v0, Bool_t &isLambda ){
   if(!kfMother[0]) return kFALSE;
   
   // production vertex is set in the 'CreateMotherParticle' function
-  kfMother[0]->SetMassConstraint(cL0mass, 0.);
+  //kfMother[0]->SetMassConstraint(cL0mass, 0.);
 
   // Anti Lambda
   kfMother[1] = CreateMotherParticle(daughter[0], daughter[1], TMath::Abs(kPiPlus), TMath::Abs(kProton));
   if(!kfMother[1]) return kFALSE;
   // production vertex is set in the 'CreateMotherParticle' function
-  kfMother[1]->SetMassConstraint(cL0mass, 0.);
+  //kfMother[1]->SetMassConstraint(cL0mass, 0.);
 
   Float_t dMass[2] = {TMath::Abs(mMass[0] - cL0mass), TMath::Abs(mMass[1] - cL0mass)};
   
@@ -694,19 +1092,15 @@ Bool_t AliHFEV0cuts::LambdaCuts(AliESDv0 *v0, Bool_t &isLambda ){
   Float_t iP = v0->P();
 
    // Cuts
-  const Double_t cutCosPoint[2] = {0., 0.03};  // ORG [0., 0.03]
+  const Double_t cutChi2NDF = 40.;              // ORG [5.]
+  const Double_t cutCosPoint[2] = {0., 0.02};  // ORG [0., 0.03]
   const Double_t cutDCA[2] = {0., 0.2};        // ORG [0., 0.2]
-  const Double_t cutProdVtxR[2] = {2., 30.};   // ORG [0., 24.]
+  const Double_t cutProdVtxR[2] = {2., 40.};   // ORG [0., 24.]
   const Double_t cutMass[2] = {1.11, 1.12};   // ORG [1.11, 1.12]
-  const Double_t cutChi2NDF = 5.;              // ORG [5.]
   // cundidate cuts
   // opening angle as a function of L momentum
-  const Double_t cutOAngleP = 0.3 - 0.2*iP; // momentum dependent min. OAngle linear cut
+  //const Double_t cutOAngleP = 0.3 - 0.2*iP; // momentum dependent min. OAngle linear cut
   // relative daughter momentum versusu mother momentum
-  // armenteros plot cuts
-  const Double_t cutQT = 0.03;
-  const Double_t cutAlpha = 0.7;  // VERY strong - should supress the overlap with K0
-  // next cut see below
 
   // compute the cut values
   
@@ -722,12 +1116,31 @@ Bool_t AliHFEV0cuts::LambdaCuts(AliESDv0 *v0, Bool_t &isLambda ){
   v0->GetXYZ(x,y,z);
   Double_t r = TMath::Sqrt(x*x + y*y);
 
+  // proton - pion indices
   Int_t ix[2] = {0, 1};
   if(1 == type){
     ix[0] = 1;
     ix[1] = 0;
   }
-  
+
+  // proton - pion indices - based on MC truth
+  // for background use the reconstructed indices
+  Int_t ixMC[2] = {-1, -1}; // {proton, pion}
+  if(fMCEvent){
+    if(4 == fCurrentV0id){
+      ixMC[0] = 0;
+      ixMC[1] = 1;
+    }
+    else if(-4 == fCurrentV0id){
+      ixMC[0] = 1;
+      ixMC[1] = 0;
+    }
+    else{
+      ixMC[0] = ix[0];
+      ixMC[1] = ix[1];
+    }
+  }
+
   // V0 chi2/ndf
   Double_t chi2ndf = kfMother[type]->GetChi2()/kfMother[type]->GetNDF();
 
@@ -740,14 +1153,6 @@ Bool_t AliHFEV0cuts::LambdaCuts(AliESDv0 *v0, Bool_t &isLambda ){
   // Relative daughter momentum
   Double_t rP = (0 == check[0]) ? p[1]/p[0] : p[0]/p[1];
   
-  // Armenteros
-  Float_t ap[2];
-  Armenteros(v0, ap);
-  
-  Double_t cutAP[2]; // a bit of woodoo :-)
-  cutAP[0] = 1.0 - (ap[0]-0.7 * ap[0]-0.7)*1.1 - 0.87;
-  cutAP[1] = 1.0 - (ap[0]+0.7 * ap[0]+0.7)*1.1 - 0.87;
-
 
   //
   // Apply the cuts, produce QA plots (with mass cut)
@@ -755,85 +1160,169 @@ Bool_t AliHFEV0cuts::LambdaCuts(AliESDv0 *v0, Bool_t &isLambda ){
   
   (type == 0) ?   fQA->Fill("h_L_Mass", 0, iMass) :  fQA->Fill("h_AL_Mass", 0, iMass);
 
+
+  // MC
+  if(fMCEvent){
+    if(4 == fCurrentV0id){
+      fQAmc->Fill("h_L_Mass_S", 0, iMass);
+      fQAmc->Fill("h_lambda_MvP_S", iP, iMass);
+    }
+    else if(-4 == fCurrentV0id){
+      fQAmc->Fill("h_AL_Mass_S", 0, iMass);
+      fQAmc->Fill("h_lambda_MvP_S", iP, iMass);
+    }
+    else if(-2 != fCurrentV0id) fQAmc->Fill("h_LAL_Mass_B", 0, iMass);
+  }
+
+
   if(iMass > cutMass[0] && iMass < cutMass[1]){
-    fQA->Fill("h_all_AP", 0, ap[0], ap[1]);
     fQA->Fill("h_ProtonL_P", 0, p[ix[0]]);
     fQA->Fill("h_PionL_P", 0, p[ix[1]]);
     fQA->Fill("h_cut_L_Chi2", 0, chi2ndf);
+    fQA->Fill("h_cut_L_Chi2", 1, chi2ndf);
     fQA->Fill("h_cut_L_CosPoint", 0, cosPoint);
-    fQA->Fill("h_cut_L_CosPoint", 1, cosPoint);
     fQA->Fill("h_cut_L_DCA", 0, dca);
     fQA->Fill("h_cut_L_VtxR", 0, r);
     fQA->Fill("h_cut_L_OAvP", 0, iP, oAngle);
     fQA->Fill("h_cut_L_rdp_v_mp", 0, iP, rP);
-    if(0 ==type)  fQA->Fill("h_cut_L_AP", 0, ap[0], ap[1]);
-    else fQA->Fill("h_cut_AL_AP", 0, ap[0], ap[1]);
-    fQA->Fill("h_cut_L_qT_v_mp", 0, iP, ap[1]);
   }
-
-  if(cosPoint < cutCosPoint[0] || cosPoint > cutCosPoint[1]) return kFALSE;
+  if(fMCEvent){
+    if(iMass > cutMass[0] && iMass < cutMass[1]){
+      if(4 == TMath::Abs(fCurrentV0id)){
+       fQAmc->Fill("h_cut_L_Chi2_S", 0, iP, chi2ndf);
+       fQAmc->Fill("h_cut_L_Chi2_S", 1, iP, chi2ndf);
+       fQAmc->Fill("h_cut_L_CosPoint_S", 0, iP, cosPoint);
+       fQAmc->Fill("h_cut_L_DCA_S", 0, iP, dca);
+       fQAmc->Fill("h_cut_L_VtxR_S", 0, iP, r);
+       fQAmc->Fill("h_cut_L_OA_S", 0, iP, oAngle);
+       fQAmc->Fill("h_cut_L_rdp_v_mp_S", 0, iP, rP);   
+       fQAmc->Fill("h_ProtonL_P_S", 0, p[ixMC[0]]);
+       fQAmc->Fill("h_PionL_P_S", 0, p[ixMC[1]]);
+      }
+      else if(-2 != fCurrentV0id){
+       fQAmc->Fill("h_cut_L_Chi2_B", 0, iP, chi2ndf);
+       fQAmc->Fill("h_cut_L_Chi2_B", 1, iP, chi2ndf);
+       fQAmc->Fill("h_cut_L_CosPoint_B", 0, iP, cosPoint);
+       fQAmc->Fill("h_cut_L_DCA_B", 0, iP, dca);
+       fQAmc->Fill("h_cut_L_VtxR_B", 0, iP, r);
+       fQAmc->Fill("h_cut_L_OA_B", 0, iP, oAngle);
+       fQAmc->Fill("h_cut_L_rdp_v_mp_B", 0, iP, rP);   
+       fQAmc->Fill("h_ProtonL_P_B", 0, p[ixMC[0]]);
+       fQAmc->Fill("h_PionL_P_B", 0, p[ixMC[1]]);
+      }
+    }
+  }
+  //
+  // Chi2/NDF cut
+  //
+  if(chi2ndf > cutChi2NDF) return kFALSE;
   (type == 0) ?   fQA->Fill("h_L_Mass", 1, iMass) :  fQA->Fill("h_AL_Mass", 1, iMass);
   if(iMass > cutMass[0] && iMass < cutMass[1]){
+    fQA->Fill("h_cut_L_CosPoint", 1, cosPoint);
     fQA->Fill("h_ProtonL_P", 1, p[ix[0]]);
     fQA->Fill("h_PionL_P", 1, p[ix[1]]);
-    fQA->Fill("h_cut_L_DCA", 1, dca);
   }
-  
-  if(dca < cutDCA[0] || dca > cutDCA[1]) return kFALSE;
+  if(fMCEvent){
+    if(4 == fCurrentV0id) fQAmc->Fill("h_L_Mass_S", 1, iMass);
+    else if(-4 == fCurrentV0id)  fQAmc->Fill("h_AL_Mass_S", 1, iMass);
+    else if(-2 != fCurrentV0id)  fQAmc->Fill("h_LAL_Mass_B", 1, iMass);
+    if(iMass > cutMass[0] && iMass < cutMass[1]){
+      if(4 == TMath::Abs(fCurrentV0id)){
+       fQAmc->Fill("h_cut_L_CosPoint_S", 1, iP, cosPoint);
+       fQAmc->Fill("h_ProtonL_P_S", 1, p[ixMC[0]]);
+       fQAmc->Fill("h_PionL_P_S", 1, p[ixMC[1]]);
+      }
+      else if(-2 != fCurrentV0id){
+       fQAmc->Fill("h_cut_L_CosPoint_B", 1, iP, cosPoint);
+       fQAmc->Fill("h_ProtonL_P_B", 1, p[ixMC[0]]);
+       fQAmc->Fill("h_PionL_P_B", 1, p[ixMC[1]]);
+      }
+    }
+  }
+
+  //
+  // Cos point cut
+  //
+  if(cosPoint < cutCosPoint[0] || cosPoint > cutCosPoint[1]) return kFALSE;
   (type == 0) ?   fQA->Fill("h_L_Mass", 2, iMass) :  fQA->Fill("h_AL_Mass", 2, iMass);
   if(iMass > cutMass[0] && iMass < cutMass[1]){
     fQA->Fill("h_ProtonL_P", 2, p[ix[0]]);
     fQA->Fill("h_PionL_P", 2, p[ix[1]]);
-     fQA->Fill("h_cut_L_VtxR", 1, r);
+    fQA->Fill("h_cut_L_DCA", 1, dca);
+  }
+  if(fMCEvent){
+    if(4 == fCurrentV0id) fQAmc->Fill("h_L_Mass_S", 2, iMass);
+    else if(-4 == fCurrentV0id)  fQAmc->Fill("h_AL_Mass_S", 2, iMass);
+    else if(-2 != fCurrentV0id)  fQAmc->Fill("h_LAL_Mass_B", 2, iMass);
+    if(iMass > cutMass[0] && iMass < cutMass[1]){
+      if(4 == TMath::Abs(fCurrentV0id)){
+       fQAmc->Fill("h_cut_L_DCA_S", 1, iP, dca);
+       fQAmc->Fill("h_ProtonL_P_S", 2, p[ixMC[0]]);
+       fQAmc->Fill("h_PionL_P_S", 2, p[ixMC[1]]);
+      }
+      else if(-2 != fCurrentV0id){
+       fQAmc->Fill("h_cut_L_DCA_B", 1, iP, dca);
+       fQAmc->Fill("h_ProtonL_P_B", 2, p[ixMC[0]]);
+       fQAmc->Fill("h_PionL_P_B", 2, p[ixMC[1]]);
+      }
+    }
   }
 
-  if(r < cutProdVtxR[0] || r > cutProdVtxR[1]) return kFALSE;
+  //
+  // DCA cut
+  //  
+  if(dca < cutDCA[0] || dca > cutDCA[1]) return kFALSE;
   (type == 0) ?   fQA->Fill("h_L_Mass", 3, iMass) :  fQA->Fill("h_AL_Mass", 3, iMass);
   if(iMass > cutMass[0] && iMass < cutMass[1]){
     fQA->Fill("h_ProtonL_P", 3, p[ix[0]]);
     fQA->Fill("h_PionL_P", 3, p[ix[1]]);
-    fQA->Fill("h_cut_L_Chi2", 1, chi2ndf);
+    fQA->Fill("h_cut_L_VtxR", 1, r);
+  }
+  if(fMCEvent){
+    if(4 == fCurrentV0id) fQAmc->Fill("h_L_Mass_S", 3, iMass);
+    else if(-4 == fCurrentV0id)  fQAmc->Fill("h_AL_Mass_S", 3, iMass);
+    else if(-2 != fCurrentV0id)  fQAmc->Fill("h_LAL_Mass_B", 3, iMass);
+    if(iMass > cutMass[0] && iMass < cutMass[1]){
+      if(4 == TMath::Abs(fCurrentV0id)){
+       fQAmc->Fill("h_cut_L_VtxR_S", 1, iP, r);
+       fQAmc->Fill("h_ProtonL_P_S", 3, p[ixMC[0]]);
+       fQAmc->Fill("h_PionL_P_S", 3, p[ixMC[1]]);
+      }
+      else if(-2 != fCurrentV0id){
+       fQAmc->Fill("h_cut_L_VtxR_B", 1, iP, r);
+       fQAmc->Fill("h_ProtonL_P_B", 3, p[ixMC[0]]);
+       fQAmc->Fill("h_PionL_P_B", 3, p[ixMC[1]]);
+      }
+    }
   }
 
-
-  if(chi2ndf > cutChi2NDF) return kFALSE;
+  //
+  // Vertex radius cut
+  //
+  if(r < cutProdVtxR[0] || r > cutProdVtxR[1]) return kFALSE;
   (type == 0) ?   fQA->Fill("h_L_Mass", 4, iMass) :  fQA->Fill("h_AL_Mass", 4, iMass);
   if(iMass > cutMass[0] && iMass < cutMass[1]){
+    fQA->Fill("h_cut_L_OAvP", 1, iP, oAngle);
     fQA->Fill("h_ProtonL_P", 4, p[ix[0]]);
     fQA->Fill("h_PionL_P", 4, p[ix[1]]);
-    fQA->Fill("h_cut_L_OAvP", 1, iP, oAngle);
-  }
-
-  if(oAngle < cutOAngleP) return kFALSE;
-  (type == 0) ?   fQA->Fill("h_L_Mass", 5, iMass) :  fQA->Fill("h_AL_Mass", 5, iMass);
-  if(iMass > cutMass[0] && iMass < cutMass[1]){
-    fQA->Fill("h_ProtonL_P", 5, p[ix[0]]);
-    fQA->Fill("h_PionL_P", 5, p[ix[1]]);
-    fQA->Fill("h_cut_L_rdp_v_mp", 1, iP, rP);
-    if(0 == type)  fQA->Fill("h_cut_L_AP", 1, ap[0], ap[1]);
-    else fQA->Fill("h_cut_AL_AP", 1, ap[0], ap[1]);
-    fQA->Fill("h_cut_L_qT_v_mp", 1, iP, ap[1]);
-    fQA->Fill("h_all_AP", 1, ap[0], ap[1]);
-  }
-  
-  if(ap[1] < cutQT) return kFALSE;
-  (type == 0) ?   fQA->Fill("h_L_Mass", 6, iMass) :  fQA->Fill("h_AL_Mass", 6, iMass);
-  if(iMass > cutMass[0] && iMass < cutMass[1]){
-    fQA->Fill("h_ProtonL_P", 6, p[ix[0]]);
-    fQA->Fill("h_PionL_P", 6, p[ix[1]]);
   }
-
-  if(ap[1] > cutAP[type]) return kFALSE;
-  (type == 0) ?   fQA->Fill("h_L_Mass", 7, iMass) :  fQA->Fill("h_AL_Mass", 7, iMass);
-  if(iMass > cutMass[0] && iMass < cutMass[1]){
-    fQA->Fill("h_ProtonL_P", 7, p[ix[0]]);
-    fQA->Fill("h_PionL_P", 7, p[ix[1]]);
-  }
-  if(TMath::Abs(ap[0]) > cutAlpha) return kFALSE;
-  (type == 0) ?   fQA->Fill("h_L_Mass", 8, iMass) :  fQA->Fill("h_AL_Mass", 8, iMass);
-  if(iMass > cutMass[0] && iMass < cutMass[1]){
-    fQA->Fill("h_ProtonL_P", 8, p[ix[0]]);
-    fQA->Fill("h_PionL_P", 8, p[ix[1]]);
+  if(fMCEvent){
+    if(4 == fCurrentV0id) fQAmc->Fill("h_L_Mass_S", 4, iMass);
+    else if(-4 == fCurrentV0id)  fQAmc->Fill("h_AL_Mass_S", 4, iMass);
+    else if(-2 != fCurrentV0id)  fQAmc->Fill("h_LAL_Mass_B", 4, iMass);
+    if(iMass > cutMass[0] && iMass < cutMass[1]){
+      if(4 == TMath::Abs(fCurrentV0id)){
+       fQAmc->Fill("h_cut_L_OA_S", 1, iP, oAngle);
+       fQAmc->Fill("h_ProtonL_P_S", 4, p[ixMC[0]]);
+       fQAmc->Fill("h_PionL_P_S", 4, p[ixMC[1]]);
+      }
+      else if(-2 != fCurrentV0id){
+       fQAmc->Fill("h_cut_L_OA_B", 1, iP, oAngle);
+       fQAmc->Fill("h_ProtonL_P_B", 4, p[ixMC[0]]);
+       fQAmc->Fill("h_PionL_P_B", 4, p[ixMC[1]]);
+      }
+    }
   }
 
   if(iMass < cutMass[0] || iMass > cutMass[1]) {
@@ -845,7 +1334,29 @@ Bool_t AliHFEV0cuts::LambdaCuts(AliESDv0 *v0, Bool_t &isLambda ){
   // assign the lambda type value: Lambda: kTRUE, Anti-Lambda: kFALSE
   isLambda = (0 == type) ? kTRUE : kFALSE;
 
-
+  // some MC stuff
+  if(4 == fCurrentV0id){
+    fQAmc->Fill("h_lambda_p_S", iP);
+  }
+  else if(-4 == fCurrentV0id){
+    fQAmc->Fill("h_alambda_p_S", iP);
+  }
+  else if (-2 != fCurrentV0id && 0 == type){
+    fQAmc->Fill("h_lambda_p_B", iP);
+  }
+  else if(-2 != fCurrentV0id && 0 != type ){
+    fQAmc->Fill("h_alambda_p_B", iP);
+  }
+  //
+  if(4 == TMath::Abs(fCurrentV0id)){
+    fQAmc->Fill("h_ProtonL_P_S", 5, p[ixMC[0]]);
+    fQAmc->Fill("h_PionL_P_S", 5, p[ixMC[1]]);
+  }
+  else if(-2 != fCurrentV0id){
+    fQAmc->Fill("h_ProtonL_P_B", 5, p[ixMC[0]]);
+    fQAmc->Fill("h_PionL_P_B", 5, p[ixMC[1]]);
+  }
+  
   return kTRUE;
 }
 //________________________________________________________________
@@ -981,6 +1492,14 @@ AliKFParticle *AliHFEV0cuts::CreateMotherParticle(AliVTrack* const pdaughter, Al
   
   // Create the mother particle 
   AliKFParticle *m = new AliKFParticle(pkfdaughter, nkfdaughter);
+  // DEBUG - testing
+  if(TMath::Abs(kElectron) == pspec && TMath::Abs(kElectron) == nspec) m->SetMassConstraint(0, 0.001);
+  else if(TMath::Abs(kPiPlus) == pspec && TMath::Abs(kPiPlus) == nspec) m->SetMassConstraint(TDatabasePDG::Instance()->GetParticle(kK0Short)->Mass(), 0.);
+  else if(TMath::Abs(kProton) == pspec && TMath::Abs(kPiPlus) == nspec) m->SetMassConstraint(TDatabasePDG::Instance()->GetParticle(kLambda0)->Mass(), 0.);
+  else if(TMath::Abs(kPiPlus) == pspec && TMath::Abs(kProton) == nspec) m->SetMassConstraint(TDatabasePDG::Instance()->GetParticle(kLambda0)->Mass(), 0.);
+  else{
+    AliError("Wrong daughter ID - mass constraint can not be set");
+  }
 
   AliKFVertex improvedVertex = *fPrimaryVertex;
   improvedVertex += *m;
@@ -1102,3 +1621,84 @@ Bool_t AliHFEV0cuts::CheckSigns(AliESDv0* const v0){
 
   return correct;
 }
+//___________________________________________________________________
+Bool_t AliHFEV0cuts::GetConvPosXY(AliESDtrack * const ptrack, AliESDtrack * const ntrack, Double_t convpos[2]){
+  //
+  // recalculate the gamma conversion XY postition
+  //
+
+  const Double_t b = fInputEvent->GetMagneticField();
+
+  Double_t helixcenterpos[2];
+  GetHelixCenter(ptrack,b,ptrack->Charge(),helixcenterpos);
+
+  Double_t helixcenterneg[2];
+  GetHelixCenter(ntrack,b,ntrack->Charge(),helixcenterneg);
+
+  Double_t  poshelix[6];
+  ptrack->GetHelixParameters(poshelix,b);
+  Double_t posradius = TMath::Abs(1./poshelix[4]);
+
+  Double_t  neghelix[6];
+  ntrack->GetHelixParameters(neghelix,b);
+  Double_t negradius = TMath::Abs(1./neghelix[4]);
+
+  Double_t xpos = helixcenterpos[0];
+  Double_t ypos = helixcenterpos[1];
+  Double_t xneg = helixcenterneg[0];
+  Double_t yneg = helixcenterneg[1];
+
+  convpos[0] = (xpos*negradius + xneg*posradius)/(negradius+posradius);
+  convpos[1] = (ypos*negradius+  yneg*posradius)/(negradius+posradius);
+
+  return 1;
+}
+//___________________________________________________________________
+Bool_t AliHFEV0cuts::GetHelixCenter(AliESDtrack * const track, Double_t b,Int_t charge, Double_t center[2]){
+  // see header file for documentation
+  
+  Double_t pi = TMath::Pi();
+  
+  Double_t  helix[6];
+  track->GetHelixParameters(helix,b);
+  
+  Double_t xpos =  helix[5];
+  Double_t ypos =  helix[0];
+  Double_t radius = TMath::Abs(1./helix[4]);
+  Double_t phi = helix[2];
+
+  if(phi < 0){
+    phi = phi + 2*pi;
+  }
+
+  phi -= pi/2.;
+  Double_t xpoint =  radius * TMath::Cos(phi);
+  Double_t ypoint =  radius * TMath::Sin(phi);
+
+  if(b<0){
+    if(charge > 0){
+      xpoint = - xpoint;
+      ypoint = - ypoint;
+    }
+
+    if(charge < 0){
+      xpoint =  xpoint;
+      ypoint =  ypoint;
+    }
+  }
+  if(b>0){
+    if(charge > 0){
+      xpoint =  xpoint;
+      ypoint =  ypoint;
+    }
+
+    if(charge < 0){
+      xpoint = - xpoint;
+      ypoint = - ypoint;
+    }
+  }
+  center[0] =  xpos + xpoint;
+  center[1] =  ypos + ypoint;
+
+  return 1;
+}
index 65a8dc9..82bcdbf 100644 (file)
@@ -34,6 +34,22 @@ class AliVTrack;
 
 class AliHFEV0cuts : public TObject {
  public:
+  enum{ // Reconstructed V0
+    kUndef = 0,
+      kRecoGamma = 1,
+      kRecoK0 = 2,
+      kRecoPhi = 3,
+      kRecoLambda = 4,
+      kRecoALambda = -4
+      
+      };
+  enum{ // Identified Daughter particles
+    kRecoElectron = 0,
+      kRecoPionK0 = 1,
+      kRecoPionL = 2,
+      kRecoKaon = 3,
+      kRecoProton = 4
+      };
   AliHFEV0cuts();
   ~AliHFEV0cuts();
   AliHFEV0cuts(const AliHFEV0cuts &ref);
@@ -42,12 +58,12 @@ class AliHFEV0cuts : public TObject {
   void Init(const char* name);
   
   void RunQA();
-  void SetMC(Bool_t b)                  { fIsMC = b; };
   void SetMCEvent(AliMCEvent* const mce)      { fMCEvent = mce; };
   void SetInputEvent(AliVEvent* const e)      { fInputEvent = e; };
   void SetPrimaryVertex(AliKFVertex* const v) { fPrimaryVertex = v; };
   
-  TList* GetList() { return fQA->GetList(); };
+  TList* GetList()    { return fQA->GetList(); };
+  TList* GetListMC()  { return fQAmc->GetList(); };
   
   Bool_t   TrackCutsCommon(AliESDtrack* track);
   Bool_t   V0CutsCommon(AliESDv0 *v0);
@@ -65,6 +81,13 @@ class AliHFEV0cuts : public TObject {
   Double_t PsiPair(AliESDv0 *v0);
   
   Bool_t   CheckSigns(AliESDv0* const v0);
+  Bool_t   GetConvPosXY(AliESDtrack * const ptrack, AliESDtrack * const ntrack, Double_t convpos[2]);
+  Bool_t   GetHelixCenter(AliESDtrack * const track, Double_t b,Int_t charge, Double_t center[2]);
+
+
+  // MC stuff
+  void     SetCurrentV0id(Int_t id) { fCurrentV0id = id; };
+  void     SetDaughtersID(Int_t d[2]) {fPdaughterPDG = d[0]; fNdaughterPDG = d[1]; };
   
   AliKFParticle *CreateMotherParticle(AliVTrack* const pdaughter, AliVTrack* const ndaughter, Int_t pspec, Int_t nspec);
 
@@ -74,11 +97,15 @@ class AliHFEV0cuts : public TObject {
  private:
   
   AliHFEcollection     *fQA;            // store QA cut histograms
+  AliHFEcollection     *fQAmc;          // store 
   AliMCEvent           *fMCEvent;       // MC event
   AliVEvent            *fInputEvent;    // Input Event
   AliKFVertex          *fPrimaryVertex; // primary vertex
 
-  Bool_t                      fIsMC; // availability of MC information
+  Int_t                fCurrentV0id;   // MC flagged V0    
+  Int_t                fPdaughterPDG;   // MC id of the positive daugeter
+  Int_t                fNdaughterPDG;   // MC id of the negative daugeter
+
 
   ClassDef(AliHFEV0cuts, 1)
 };
index a2b1eed..658fe1f 100644 (file)
@@ -34,6 +34,9 @@
 #include "AliKFVertex.h"
 #include "AliVEvent.h"
 #include "AliVTrack.h"
+#include "AliMCParticle.h"
+#include "AliStack.h"
+#include "AliMCEvent.h"
 
 #include "AliHFEV0cuts.h"
 #include "AliHFEV0info.h"
@@ -46,6 +49,9 @@ ClassImp(AliHFEV0pid)
 AliHFEV0pid::AliHFEV0pid():
   TObject()
   , fInputEvent(NULL)
+  , fNtracks(0)
+  , fMCEvent(NULL)
+  , fMCon(kFALSE)
   , fPrimaryVertex(NULL)
   , fElectrons(NULL)
   , fPionsK0(NULL)
@@ -120,14 +126,15 @@ void AliHFEV0pid::InitQA(){
   fV0cuts->Init("V0cuts");
 
   if(!fQA){
-    fQA = new AliHFEcollection("v0pidQA", "QA histograms for V0 PID");
+    fQA = new AliHFEcollection("v0pidQA", "QA histograms for V0 selection");
 
     fQA->CreateTH1F("h_nV0s", "No. of found and accepted V0s", 5, -0.5, 4.5);
 
     // QA histograms for invariant mass
     fQA->CreateTH1F("h_InvMassGamma", "Gamma invariant mass; inv mass [GeV/c^{2}]; counts", 100, 0, 0.25);
     fQA->CreateTH1F("h_InvMassK0s", "K0s invariant mass; inv mass [GeV/c^{2}]; counts", 200, 0.4, 0.65);
-    fQA->CreateTH1F("h_InvMassLambda", "Lambda invariant mass; inv mass [GeV/c^{2}]; counts", 100, 1.05, 1.15);
+    fQA->CreateTH1F("h_InvMassL", "Lambda invariant mass; inv mass [GeV/c^{2}]; counts", 100, 1.05, 1.15);
+    fQA->CreateTH1F("h_InvMassAL", "Lambda invariant mass; inv mass [GeV/c^{2}]; counts", 100, 1.05, 1.15);
     
     // QA histograms for p distribution (of the daughters)
     fQA->CreateTH1F("h_P_electron", "P distribution of the gamma electrons; p (GeV/c); counts", 100, 0.1, 10);
@@ -138,8 +145,30 @@ void AliHFEV0pid::InitQA(){
     // QA pt of the V0
     fQA->CreateTH1F("h_Pt_Gamma", "Pt of the gamma conversion; p_{T} (GeV/c); counts", 100, 0, 10);
     fQA->CreateTH1F("h_Pt_K0", "Pt of the K0; p_{T} (GeV/c); counts", 100, 0, 10);
-    fQA->CreateTH1F("h_Pt_Lambda", "Pt of the Lambda; p_{T} (GeV/c); counts", 100, 0, 10);    
+    fQA->CreateTH1F("h_Pt_L", "Pt of the Lambda; p_{T} (GeV/c); counts", 100, 0, 10);    
+    fQA->CreateTH1F("h_Pt_AL", "Pt of the Lambda; p_{T} (GeV/c); counts", 100, 0, 10);    
     
+    // Armenteros plot V0 preselection
+    fQA->CreateTH2F("h_AP_all_V0s", "armenteros plot for all V0 candidates; #alpha; Q_{T}", 200, -1, 1, 200, 0, 0.25);
+    fQA->CreateTH2F("h_AP_selected_V0s", "armenteros plot for all V0 candidates; #alpha; Q_{T}", 200, -1, 1, 200, 0, 0.25);
+
+    //
+    // !!! MC plots !!!
+    // 
+    fQA->CreateTH2F("h_AP_MC_all_V0s", "armenteros plot for all MC tagged V0s; #alpha; Q_{T}", 200, -1, 1, 200, 0, 0.25);
+    fQA->CreateTH2F("h_AP_MC_Gamma", "armenteros plot for MC tagged Gammas; #alpha; Q_{T}",  200, -1, 1, 200, 0, 0.25);
+    fQA->CreateTH2F("h_AP_MC_K0", "armenteros plot for MC tagged K0s; #alpha; Q_{T}",  200, -1, 1, 200, 0, 0.25);
+    fQA->CreateTH2F("h_AP_MC_Lambda", "armenteros plot for MC tagged Lambdas; #alpha; Q_{T}",  200, -1, 1, 200, 0, 0.25);
+    fQA->CreateTH2F("h_AP_MC_ALambda", "armenteros plot for MC tagged A-Lambdass; #alpha; Q_{T}",  200, -1, 1, 200, 0, 0.25);
+
+   
+    // armenteros plots for different V0 momenta - MC signal only
+    fQA->CreateTH2Fvector1(12, "h_AP_MC_Gamma_p", "armenteros plot for MC tagged Gammas; #alpha; Q_{T}",  200, -1., 1., 200, 0., 0.25);
+    fQA->CreateTH2Fvector1(12, "h_AP_MC_K0_p", "armenteros plot for MC tagged K0s; #alpha; Q_{T}",  200, -1., 1., 200, 0., 0.25);
+    fQA->CreateTH2Fvector1(12, "h_AP_MC_Lambda_p", "armenteros plot for MC tagged Lambdas; #alpha; Q_{T}",  200, -1., 1., 200, 0., 0.25);
+   //
+
     
   }
 }
@@ -154,11 +183,13 @@ void AliHFEV0pid::Process(AliVEvent * const inputEvent){
   
   Int_t nGamma = 0, nK0s = 0, nLambda = 0, nPhi = 0;
   fInputEvent = inputEvent;
+  fNtracks = fInputEvent->GetNumberOfTracks();
   fIndices->Init(fInputEvent->GetNumberOfV0s() * 2);
   fPrimaryVertex = new AliKFVertex(*(fInputEvent->GetPrimaryVertex()));
   if(!fPrimaryVertex) return;
   fV0cuts->SetInputEvent(fInputEvent);
   fV0cuts->SetPrimaryVertex(fPrimaryVertex);
+  if(fMCEvent) fV0cuts->SetMCEvent(fMCEvent);
   Int_t v0status = 0;
   for(Int_t iv0 = 0; iv0 < fInputEvent->GetNumberOfV0s(); iv0++){
     if(!TString(fInputEvent->IsA()->GetName()).CompareTo("AliESDEvent")){
@@ -174,14 +205,14 @@ void AliHFEV0pid::Process(AliVEvent * const inputEvent){
       AliAODv0 *aodV0 = (dynamic_cast<AliAODEvent *>(fInputEvent))->GetV0(iv0);
       if(aodV0->GetOnFlyStatus()) continue; // Take only V0s from the On-the-fly v0 finder
       v0status = ProcessV0(aodV0);
-      if(kUndef != v0status){
+      if(AliHFEV0cuts::kUndef != v0status){
       }
     }
     switch(v0status){
-    case kRecoGamma: nGamma++; break;
-    case kRecoK0s: nK0s++; break;
-    case kRecoPhi: nPhi++; break;  
-    case kRecoLambda: nLambda++; break;
+    case AliHFEV0cuts::kRecoGamma: nGamma++; break;
+    case AliHFEV0cuts::kRecoK0: nK0s++; break;
+    case AliHFEV0cuts::kRecoPhi: nPhi++; break;  
+    case AliHFEV0cuts::kRecoLambda: nLambda++; break;
     };
   }
 
@@ -210,33 +241,46 @@ Int_t AliHFEV0pid::ProcessV0(TObject *v0){
   AliVTrack* daughter[2];
   daughter[0] = dynamic_cast<AliVTrack *>(fInputEvent->GetTrack((dynamic_cast<AliESDv0 *>(v0))->GetPindex()));
   daughter[1] = dynamic_cast<AliVTrack *>(fInputEvent->GetTrack((dynamic_cast<AliESDv0 *>(v0))->GetNindex()));
-  if(!daughter[0] || !daughter[1]) return kUndef;
+  if(!daughter[0] || !daughter[1]) return AliHFEV0cuts::kUndef;
+
+  if(fMCEvent) fMCon = kTRUE;
+  //printf("-D: fMCEvent %x, fMCon: %i\n", fMCEvent, fMCon);
+
+  Int_t dMC[2] = {-1, -1};
+  Int_t idMC = AliHFEV0cuts::kUndef; 
 
-  
   if(IsESDanalysis()){
+    if(fMCon){
+      idMC = IdentifyV0(v0, dMC);
+      //printf("--D: V0 pid: %i, P: %i, N: %i\n", id, d[0], d[1]);
+      fV0cuts->SetCurrentV0id(idMC);
+      fV0cuts->SetDaughtersID(dMC);
+    }
+    // check common single track cuts
     for(Int_t i=0; i<2; ++i){
-      // check common single track cuts
-      if(!fV0cuts->TrackCutsCommon(dynamic_cast<AliESDtrack*>(daughter[i]))) return kUndef;
-    }    
+      if(!fV0cuts->TrackCutsCommon(dynamic_cast<AliESDtrack*>(daughter[i]))) return AliHFEV0cuts::kUndef;
+    }
     // check commom V0 cuts
-    if(!fV0cuts->V0CutsCommon(dynamic_cast<AliESDv0 *>(v0))) return kUndef;
+    if(!fV0cuts->V0CutsCommon(dynamic_cast<AliESDv0 *>(v0))) return AliHFEV0cuts::kUndef;
   }
 
+  // preselect the V0 candidates based on the Armenteros plot
+  Int_t id = PreselectV0((dynamic_cast<AliESDv0 *>(v0)), idMC);
 
   // store the resutls
-  if(IsGammaConv(v0)){
-    fQA->Fill("h_nV0s", kRecoGamma);
-    return kRecoGamma;
+  if(AliHFEV0cuts::kRecoGamma == id && IsGammaConv(v0)){
+    fQA->Fill("h_nV0s", AliHFEV0cuts::kRecoGamma);
+    return AliHFEV0cuts::kRecoGamma;
   }
-  else if(IsK0s(v0)){
-    fQA->Fill("h_nV0s", kRecoK0s);
-    return kRecoK0s;
+  else if(AliHFEV0cuts::kRecoK0 == id && IsK0s(v0)){
+    fQA->Fill("h_nV0s", AliHFEV0cuts::kRecoK0);
+    return AliHFEV0cuts::kRecoK0;
   }
-  else if(IsLambda(v0)){
-    fQA->Fill("h_nV0s", kRecoLambda);    
-    return kRecoLambda;
+  else if(AliHFEV0cuts::kRecoLambda == TMath::Abs(id) && IsLambda(v0)){
+    fQA->Fill("h_nV0s", AliHFEV0cuts::kRecoLambda);    
+    return AliHFEV0cuts::kRecoLambda;
   }
-  else return kUndef;
+  else return AliHFEV0cuts::kUndef;
     
 }
 //____________________________________________________________
@@ -252,6 +296,111 @@ void AliHFEV0pid::Flush(){
   fIndices->Flush();
 }
 //____________________________________________________________
+Int_t AliHFEV0pid::PreselectV0(AliESDv0 * const v0, Int_t idMC){
+  //
+  // Based on Armenteros plot preselet the possible identity of the V0 candidate
+  //
+
+  if(!v0) return -1;
+
+  // momentum dependent armenteros plots
+  ArmenterosPlotMC(v0, idMC);
+
+  // comupte the armenteros variables
+  Float_t ar[2];
+  fV0cuts->Armenteros(v0, ar);
+  // for clarity
+  const Float_t alpha = ar[0];
+  const Float_t qt = ar[1];
+  //printf(" -D: Alpha: %f, QT: %f \n", alpha, qt);
+
+  if(TMath::Abs(alpha) > 1) return AliHFEV0cuts::kUndef;
+
+  fQA->Fill("h_AP_all_V0s", alpha, qt);
+
+  // fill a few MC tagged histograms - AP plots
+  if(fMCEvent){
+    switch(idMC){
+    case AliHFEV0cuts::kRecoGamma :
+      fQA->Fill("h_AP_MC_all_V0s", alpha, qt);
+      fQA->Fill("h_AP_MC_Gamma", alpha, qt);
+      break;
+    case AliHFEV0cuts::kRecoK0 :
+      fQA->Fill("h_AP_MC_all_V0s", alpha, qt);
+    fQA->Fill("h_AP_MC_K0", alpha, qt);
+      break;
+    case AliHFEV0cuts::kRecoLambda :
+      fQA->Fill("h_AP_MC_all_V0s", alpha, qt);
+      fQA->Fill("h_AP_MC_Lambda", alpha, qt);
+      break;
+    case AliHFEV0cuts::kRecoALambda :
+      fQA->Fill("h_AP_MC_all_V0s", alpha, qt);
+      fQA->Fill("h_AP_MC_ALambda", alpha, qt);
+      break;
+    }
+  }
+
+  // Gamma cuts
+  const Double_t cutAlphaG = 0.35; 
+  const Double_t cutQTG = 0.05;
+  const Double_t cutAlphaG2[2] = {0.6, 0.8};
+  const Double_t cutQTG2 = 0.04;
+
+  // K0 cuts
+  const Float_t cutQTK0[2] = {0.1075, 0.215};
+  const Float_t cutAPK0[2] = {0.199, 0.8};   // parameters for curved QT cut
+  
+  // Lambda & A-Lambda cuts
+  const Float_t cutQTL = 0.03;
+  const Float_t cutAlphaL[2] = {0.35, 0.7};
+  const Float_t cutAlphaAL[2] = {-0.7,  -0.35};
+  const Float_t cutAPL[3] = {0.107, -0.69, 0.5};  // parameters fir curved QT cut
+
+
+  // Check for Gamma candidates
+  if(qt < cutQTG){
+    if( (TMath::Abs(alpha) < cutAlphaG) ){
+      fQA->Fill("h_AP_selected_V0s", alpha, qt);
+      return  AliHFEV0cuts::kRecoGamma;
+    }
+  }
+  // additional region - should help high pT gammas
+  if(qt < cutQTG2){
+    if( (TMath::Abs(alpha) > cutAlphaG2[0]) &&  (TMath::Abs(alpha) < cutAlphaG2[1]) ){
+      fQA->Fill("h_AP_selected_V0s", alpha, qt);
+      return  AliHFEV0cuts::kRecoGamma;
+    }
+  }
+
+
+  // Check for K0 candidates
+  Float_t q = cutAPK0[0] * TMath::Sqrt(TMath::Abs(1 - alpha*alpha/(cutAPK0[1]*cutAPK0[1])));
+  if( (qt > cutQTK0[0]) && (qt < cutQTK0[1]) && (qt > q) ){
+    fQA->Fill("h_AP_selected_V0s", alpha, qt);
+    return AliHFEV0cuts::kRecoK0;
+  }
+  
+  if( (alpha > 0) && (alpha > cutAlphaL[0])  && (alpha < cutAlphaL[1]) && (qt > cutQTL)){
+    q = cutAPL[0] * TMath::Sqrt(1 - ( (alpha + cutAPL[1]) * (alpha + cutAPL[1]))  / (cutAPL[2]*cutAPL[2]) );
+    if( qt < q  ){
+      fQA->Fill("h_AP_selected_V0s", alpha, qt);
+      return AliHFEV0cuts::kRecoLambda;
+    }
+  }
+
+  // Check for A-Lambda candidates
+  if( (alpha < 0) && (alpha > cutAlphaAL[0]) && (alpha < cutAlphaAL[1]) && (qt > cutQTL)){
+    q = cutAPL[0] * TMath::Sqrt(1 - ( (alpha - cutAPL[1]) * (alpha - cutAPL[1]) ) / (cutAPL[2]*cutAPL[2]) );
+    if( qt < q ){
+      fQA->Fill("h_AP_selected_V0s", alpha, qt);
+      return AliHFEV0cuts::kRecoLambda;
+    }
+  }
+  
+  return AliHFEV0cuts::kUndef;
+
+}
+//____________________________________________________________
 Bool_t AliHFEV0pid::IsGammaConv(TObject *v0){
   //
   // Identify Gamma
@@ -294,12 +443,12 @@ Bool_t AliHFEV0pid::IsGammaConv(TObject *v0){
   if(!fIndices->Find(daughter[0]->GetID())){
     AliDebug(1, Form("Gamma identified, daughter IDs: %d,%d", daughter[0]->GetID(), daughter[1]->GetID()));    
     fElectrons->Add(new AliHFEV0info(daughter[0], daughter[1]->GetID(), v0id));
-    fIndices->Add(daughter[0]->GetID(), AliHFEV0pid::kRecoElectron);
+    fIndices->Add(daughter[0]->GetID(), AliHFEV0cuts::kRecoElectron);
   }
   if(!fIndices->Find(daughter[1]->GetID())){
     AliDebug(1, Form("Gamma identified, daughter IDs: %d,%d", daughter[1]->GetID(), daughter[1]->GetID()));
     fElectrons->Add(new AliHFEV0info(daughter[1], daughter[0]->GetID(), v0id));
-    fIndices->Add(daughter[1]->GetID(), AliHFEV0pid::kRecoElectron);
+    fIndices->Add(daughter[1]->GetID(), AliHFEV0cuts::kRecoElectron);
   }
   fGammas->Add(v0);
   
@@ -346,12 +495,12 @@ Bool_t AliHFEV0pid::IsK0s(TObject *v0){
   if(!fIndices->Find(daughter[0]->GetID())){
     AliDebug(1, Form("Adding K0 Pion track with ID %d", daughter[0]->GetID()));
     fPionsK0->Add(new AliHFEV0info(daughter[0], daughter[1]->GetID(), v0id));
-    fIndices->Add(daughter[0]->GetID(), AliHFEV0pid::kRecoPionK0);
+    fIndices->Add(daughter[0]->GetID(), AliHFEV0cuts::kRecoPionK0);
   }
   if(!fIndices->Find(daughter[1]->GetID())){
     AliDebug(1, Form("Adding K0 Pion track with ID %d", daughter[1]->GetID()));
     fPionsK0->Add(new AliHFEV0info(daughter[1], daughter[0]->GetID(), v0id));
-    fIndices->Add(daughter[1]->GetID(), AliHFEV0pid::kRecoPionK0);
+    fIndices->Add(daughter[1]->GetID(), AliHFEV0cuts::kRecoPionK0);
   }
   fK0s->Add(v0);
   return kTRUE; 
@@ -390,12 +539,14 @@ Bool_t AliHFEV0pid::IsLambda(TObject *v0){
   Int_t pIndex = 0, nIndex = 0;
   Double_t invMass = 0.;
   Bool_t isLambda = kTRUE; // Lambda - kTRUE, Anti Lambda - kFALSE
+  Double_t mPt = 0.;
   Int_t v0id = -1;
   if(IsESDanalysis()){
     // ESD - cut V0
     AliESDv0 *esdV0 = dynamic_cast<AliESDv0 *>(v0);
     v0id = esdV0->GetLabel();
     if(!fV0cuts->LambdaCuts(esdV0,isLambda)) return kFALSE; 
+    mPt = esdV0->Pt();
     if(fV0cuts->CheckSigns(esdV0)){
       pIndex = esdV0->GetPindex();
       nIndex = esdV0->GetNindex();
@@ -422,24 +573,29 @@ Bool_t AliHFEV0pid::IsLambda(TObject *v0){
   
   // lambda
   if(isLambda){
+    fQA->Fill("h_Pt_L", mPt);
+    fQA->Fill("h_InvMassL", invMass);
+
     if(!fIndices->Find(daughter[0]->GetID())){
       fProtons->Add(new AliHFEV0info(daughter[0], daughter[1]->GetID(), v0id));
-      fIndices->Add(daughter[0]->GetID(), AliHFEV0pid::kRecoProton);
+      fIndices->Add(daughter[0]->GetID(), AliHFEV0cuts::kRecoProton);
     }
     if(!fIndices->Find(daughter[1]->GetID())){
       fPionsL->Add(new AliHFEV0info(daughter[1], daughter[0]->GetID(), v0id));
-      fIndices->Add(daughter[1]->GetID(), AliHFEV0pid::kRecoPionL);
+      fIndices->Add(daughter[1]->GetID(), AliHFEV0cuts::kRecoPionL);
     }
   }
   // antilambda
   else{
+    fQA->Fill("h_Pt_AL", mPt);
+    fQA->Fill("h_InvMassAL", invMass);
     if(!fIndices->Find(daughter [1]->GetID())){
       fProtons->Add(new AliHFEV0info(daughter[1], daughter[0]->GetID(), v0id));
-      fIndices->Add(daughter[1]->GetID(), AliHFEV0pid::kRecoProton);
+      fIndices->Add(daughter[1]->GetID(), AliHFEV0cuts::kRecoProton);
     }
     if(!fIndices->Find(daughter [0]->GetID())){
       fPionsL->Add(new AliHFEV0info(daughter[0], daughter[1]->GetID(), v0id));
-      fIndices->Add(daughter [0]->GetID(), AliHFEV0pid::kRecoPionL);
+      fIndices->Add(daughter [0]->GetID(), AliHFEV0cuts::kRecoPionL);
     }
   }
   if(isLambda) fLambdas->Add(v0);
@@ -449,6 +605,124 @@ Bool_t AliHFEV0pid::IsLambda(TObject *v0){
 }
 
 //____________________________________________________________
+Int_t AliHFEV0pid::IdentifyV0(TObject *esdV0, Int_t d[2]){
+  //
+  // for MC only, returns the V0 Id
+  //
+
+  //
+  // be carefull about changing the return values - they are used later selectively
+  // In particulra "-2" means that identity of either of the daughters could not be
+  // estimated
+  //
+
+  AliESDv0 *v0 = dynamic_cast<AliESDv0 *>(esdV0);
+  
+  if(!v0) return -1;
+  AliESDtrack* dN, *dP; 
+  Int_t iN, iP;
+  iN = iP = -1;
+  iP = v0->GetPindex();
+  iN = v0->GetNindex();
+  if(iN < 0 || iP < 0) return -1;
+  if(iN >= fNtracks || iP >= fNtracks) return -1;
+  dP = dynamic_cast<AliESDtrack *>(fInputEvent->GetTrack(iP));
+  dN = dynamic_cast<AliESDtrack *>(fInputEvent->GetTrack(iN));  
+  if(!dN || !dP) return -1;
+
+  // as of 26/10/2010
+  // there is still a problem with wrong assignment of positive and negative
+  // V0 daughter in V0 finder - a check is necessary
+  // if the V0 daughters are miss-assigned - swap their labels
+  Bool_t sign = fV0cuts->CheckSigns(v0);
+
+  // get the MC labels
+  Int_t lN, lP;
+  if(sign){
+    lN = dN->GetLabel();
+    lP = dP->GetLabel();
+  }
+  else{
+    lP = dN->GetLabel();
+    lN = dP->GetLabel();
+  }
+  if(lN < 0 || lP < 0) return -2;
+  // get the associated MC particles
+  AliMCParticle *mcP, *mcN;
+  mcP = dynamic_cast<AliMCParticle*>(fMCEvent->GetTrack(lP));
+  mcN = dynamic_cast<AliMCParticle*>(fMCEvent->GetTrack(lN));
+  if(!mcP || !mcN) return -2;
+  
+  // identify the daughter tracks and their mothers
+  Int_t pdgP, pdgN;
+  pdgP = TMath::Abs(mcP->PdgCode());
+  pdgN = TMath::Abs(mcN->PdgCode());
+  // store the daughter ID for later use
+  d[0] = pdgP;
+  d[1] = pdgN;
+  //printf(" -D: pdgP: %i, pdgN: %i\n", pdgP, pdgN);
+  // lablel of the mother particle
+  // -1 may mean it was a primary particle
+  Int_t lPm, lNm;
+  lPm = mcP->GetMother();
+  lNm = mcN->GetMother();
+  if(-1==lPm || -1==lNm) return -3;
+
+  // return if mothers are not the same particle
+  if(lPm != lNm) return -3;
+  // get MC mother particle - now we need only 1
+  AliMCParticle *m = dynamic_cast<AliMCParticle*>(fMCEvent->GetTrack(lPm));
+  if(!m) return -2;
+  // mother PDG
+  Int_t pdgM = m->PdgCode();
+
+  //   if(3122 == TMath::Abs(pdgM)){
+  //     printf("-D: v0 signs: %i\n", fV0cuts->CheckSigns(v0));
+  //     printf("-D: pdgM: %i, pdgN: %i, pdgP: %i \n", pdgM, pdgN, pdgP);
+  //   }
+  
+  // now check the mother and daughters identity
+  if(22 == TMath::Abs(pdgM) && 11 == pdgN && 11 == pdgP) return AliHFEV0cuts::kRecoGamma;
+  if(310 == TMath::Abs(pdgM) && 211 == pdgN && 211 == pdgP) return AliHFEV0cuts::kRecoK0;
+  if(-3122 == pdgM && 2212 == pdgN && 211 == pdgP) return AliHFEV0cuts::kRecoALambda;
+  if(3122 == pdgM && 211 == pdgN && 2212 == pdgP) return AliHFEV0cuts::kRecoLambda;
+    
+  return AliHFEV0cuts::kUndef;
+
+}
+//____________________________________________________________
+void   AliHFEV0pid::ArmenterosPlotMC(AliESDv0 * const v0, Int_t idMC){
+  //
+  // Armenteros plots as a function of Mohter Momentum
+  //
+  //const Float_t minP = 0.1;
+  //const Float_t maxP = 10.;
+  // approx log bins - over the 0.1 - 10 GeV/c
+  const Float_t bins[13] = {0.1, 0.1468, 0.2154, 0.3162, 0.4642, 0.6813, 1.0, 1.4678, 2.1544, 3.1623, 4.6416, 6.8129, 10.0};
+  
+  Float_t ar[2];
+  fV0cuts->Armenteros(v0, ar);
+  Float_t p = v0->P();
+  if( (p <=  bins[0]) || (p >= bins[12])) return;
+
+  Int_t pBin = 0;
+  Float_t tmp = bins[0];
+  while(tmp < p){
+    ++pBin;
+    tmp = bins[pBin];
+  }
+  pBin--;
+
+  if(AliHFEV0cuts::kRecoGamma == idMC) fQA->Fill("h_AP_MC_Gamma_p", pBin, ar[0], ar[1]);
+  if(AliHFEV0cuts::kRecoK0 == idMC) fQA->Fill("h_AP_MC_K0_p", pBin, ar[0], ar[1]);
+  if(AliHFEV0cuts::kRecoLambda == TMath::Abs(idMC)) fQA->Fill("h_AP_MC_Lambda_p", pBin, ar[0], ar[1]);
+  
+  
+
+}
+//____________________________________________________________
 AliHFEV0pid::AliHFEV0pidTrackIndex::AliHFEV0pidTrackIndex():
     fNElectrons(0)
   , fNPionsK0(0)
@@ -518,16 +792,16 @@ void AliHFEV0pid::AliHFEV0pidTrackIndex::Add(Int_t index, Int_t species){
   // Add new index to the list of identified particles
   //
   switch(species){
-    case AliHFEV0pid::kRecoElectron:
+    case AliHFEV0cuts::kRecoElectron:
       fIndexElectron[fNElectrons++] = index;
       break;
-    case AliHFEV0pid::kRecoPionK0:
+    case AliHFEV0cuts::kRecoPionK0:
       fIndexPionK0[fNPionsK0++] = index;
       break;
-    case AliHFEV0pid::kRecoPionL:
+    case AliHFEV0cuts::kRecoPionL:
       fIndexPionL[fNPionsL++] = index;
       break;
-    case AliHFEV0pid::kRecoProton:
+    case AliHFEV0cuts::kRecoProton:
       fIndexProton[fNProtons++] = index;
       break;
   };
@@ -541,19 +815,19 @@ Bool_t AliHFEV0pid::AliHFEV0pidTrackIndex::Find(Int_t index, Int_t species) cons
 
   Int_t *container = NULL; Int_t n = 0;
   switch(species){
-  case AliHFEV0pid::kRecoElectron:
+  case AliHFEV0cuts::kRecoElectron:
     container = fIndexElectron;
     n = fNElectrons;
     break;
-  case AliHFEV0pid::kRecoPionK0:
+  case AliHFEV0cuts::kRecoPionK0:
     container = fIndexPionK0;
     n = fNPionsK0;
     break;
-  case AliHFEV0pid::kRecoPionL:
+  case AliHFEV0cuts::kRecoPionL:
     container = fIndexPionL;
     n = fNPionsL;
     break;
-  case AliHFEV0pid::kRecoProton:
+  case AliHFEV0cuts::kRecoProton:
     container = fIndexProton;
     n = fNProtons;
     break;
@@ -575,10 +849,10 @@ Bool_t AliHFEV0pid::AliHFEV0pidTrackIndex::Find(Int_t index) const {
   // 
   // Find index in all samples
   //
-  if(Find(index, AliHFEV0pid::kRecoElectron)) return kTRUE;
-  else if(Find(index, AliHFEV0pid::kRecoPionK0)) return kTRUE;
-  else if(Find(index, AliHFEV0pid::kRecoPionL)) return kTRUE;
-  else return Find(index, AliHFEV0pid::kRecoProton);
+  if(Find(index, AliHFEV0cuts::kRecoElectron)) return kTRUE;
+  else if(Find(index, AliHFEV0cuts::kRecoPionK0)) return kTRUE;
+  else if(Find(index, AliHFEV0cuts::kRecoPionL)) return kTRUE;
+  else return Find(index, AliHFEV0cuts::kRecoProton);
 }
 
 //____________________________________________________________
@@ -586,7 +860,7 @@ TList *AliHFEV0pid::GetListOfQAhistograms(){
   //
   // Getter for V0 PID QA histograms
   //
-  
+
   TList *tmp = fV0cuts->GetList();
   tmp->SetName("V0cuts");
   fOutput->Add(tmp);
@@ -596,5 +870,11 @@ TList *AliHFEV0pid::GetListOfQAhistograms(){
     tmp->SetName("V0pid");
     fOutput->Add(tmp);
   } 
+  tmp = 0x0;
+  tmp = fV0cuts->GetListMC();
+  tmp->SetName("V0cutsMC");
+  //printf(" -D: adding MC V0 cuts stuff\n");
+  fOutput->Add(tmp);
+  
   return fOutput;
 }
index 8d66402..188ec8c 100644 (file)
@@ -34,27 +34,13 @@ class AliKFParticle;
 class AliKFVertex;
 class AliVEvent;
 class AliVTrack;
+class AliMCEvent;
 
 class AliHFEV0cuts;
 class AliHFEcollection;
 
 class AliHFEV0pid : public TObject{
   public:
-  enum{ // Reconstructed V0
-    kUndef = 0,
-      kRecoGamma = 1,
-      kRecoK0s = 2,
-      kRecoPhi = 3,
-      kRecoLambda = 4
-      
-    };
-    enum{ // Identified Daughter particles
-      kRecoElectron = 0,
-       kRecoPionK0 = 1,
-       kRecoPionL = 2,
-       kRecoKaon = 3,
-       kRecoProton = 4
-       };
     AliHFEV0pid();
     ~AliHFEV0pid();
 
@@ -76,17 +62,24 @@ class AliHFEV0pid : public TObject{
     void     SetAODanalysis(Bool_t isAOD = kTRUE) { SetBit(kAODanalysis, isAOD); };
     void     SetESDanalysis(Bool_t isESD = kTRUE) { SetBit(kAODanalysis, !isESD); }; 
 
+    void     SetMCEvent(AliMCEvent* const ev) { fMCEvent = ev; };
+    
  protected:
     enum{
       kAODanalysis = BIT(14)
        };
-    
+
+    Int_t PreselectV0(AliESDv0 * const v0, Int_t idMC);
+
+    void   ArmenterosPlotMC(AliESDv0 * const v0, Int_t idMC);
     Bool_t IsGammaConv(TObject *v0);
     Bool_t IsK0s(TObject *v0);
     Bool_t IsPhi(TObject *v0);
     Bool_t IsLambda(TObject *v0);        
     TList *GetV0pidQA(); 
 
+    Int_t IdentifyV0(TObject *v0, Int_t d[2]);
+
  private:
     class AliHFEV0pidTrackIndex{
     public:
@@ -121,6 +114,9 @@ class AliHFEV0pid : public TObject{
     AliHFEV0pid&operator=(const AliHFEV0pid &ref);
     
     AliVEvent   *fInputEvent;        // Input Event
+    Int_t        fNtracks;           // number of tracks in current event
+    AliMCEvent  *fMCEvent;           // MC evnet
+    Bool_t       fMCon;              // availability of MC information
     AliKFVertex *fPrimaryVertex;     // Primary Vertex
     TObjArray   *fElectrons;         // List of Electron tracks coming from Conversions
     TObjArray   *fPionsK0;           // List of Pion tracks coming from K0
index 517890a..6ca9d1b 100644 (file)
@@ -62,24 +62,28 @@ void AliHFEV0pidMC::Init(){
   // QA
   fColl->CreateTH1F("h_QA_nParticles", "QA on track processing", 10, -0.5, 9.5);
 
+  const Int_t nBins = 20;
+  const Float_t pMin = 0.1;
+  const Float_t pMax = 10.;
+
   // before PID
-  fColl->CreateTH1F("h_Electron", "all electron candidates (no MC); p (GeV/c); counts", 100, 0.1, 10, 0);
-  fColl->CreateTH1F("h_PionK0", "all K0 pion candidates (no MC); p (GeV/c); counts", 100, 0.1, 10, 0);
-  fColl->CreateTH1F("h_PionL", "all Lambda pion candidates (no MC); p (GeV/c); counts", 100, 0.1, 10, 0);
-  fColl->CreateTH1F("h_Kaon", "all Kaon candidates (no MC); p (GeV/c); counts", 100, 0.1, 10, 0);
-  fColl->CreateTH1F("h_Proton", "all Lambda proton candidates (no MC); p (GeV/c); counts", 100, 0.1, 10, 0);
+  fColl->CreateTH1F("h_Electron", "all electron candidates (no MC); p (GeV/c); counts", nBins, pMin, pMax, 0);
+  fColl->CreateTH1F("h_PionK0", "all K0 pion candidates (no MC); p (GeV/c); counts",  nBins, pMin, pMax, 0);
+  fColl->CreateTH1F("h_PionL", "all Lambda pion candidates (no MC); p (GeV/c); counts", nBins, pMin, pMax, 0);
+  fColl->CreateTH1F("h_Kaon", "all Kaon candidates (no MC); p (GeV/c); counts",  nBins, pMin, pMax, 0);
+  fColl->CreateTH1F("h_Proton", "all Lambda proton candidates (no MC); p (GeV/c); counts",  nBins, pMin, pMax, 0);
   
-  fColl->CreateTH1F("h_mis_Electron", "all NON electron candidates MC tagged; p (GeV/c); counts", 100, 0.1, 10, 0);
-  fColl->CreateTH1F("h_mis_PionK0", "all NON K0 pion candidates MC tagged; p (GeV/c); counts", 100, 0.1, 10, 0);
-  fColl->CreateTH1F("h_mis_PionL", "all NON Lambda pion candidates MC tagged ; p (GeV/c); counts", 100, 0.1, 10, 0);
-  fColl->CreateTH1F("h_mis_Kaon", "all NON Kaon candidates MC tagged; p (GeV/c); counts", 100, 0.1, 10, 0);
-  fColl->CreateTH1F("h_mis_Proton", "all NON Lambda proton candidates MC tagged; p (GeV/c); counts", 100, 0.1, 10, 0);  
-
-  fColl->CreateTH1Fvector1(5, "h_tag_Electron", "electron candidate MC tagged; p (GeV/c); counts", 100, 0.1, 10, 0);
-  fColl->CreateTH1Fvector1(5, "h_tag_PionK0", "K0 pion candidate MC tagged; p (GeV/c); counts", 100, 0.1, 10, 0);
-  fColl->CreateTH1Fvector1(5, "h_tag_PionL", "Lambda pion candidate MC tagged; p (GeV/c); counts", 100, 0.1, 10, 0);
-  fColl->CreateTH1Fvector1(5, "h_tag_Kaon", "kaon candidate MC tagged; p (GeV/c); counts", 100, 0.1, 10, 0);
-  fColl->CreateTH1Fvector1(5, "h_tag_Proton", "Lambda proton candidate MC tagged; p (GeV/c); counts", 100, 0.1, 10, 0);
+  fColl->CreateTH1F("h_mis_Electron", "all NON electron candidates MC tagged; p (GeV/c); counts",  nBins, pMin, pMax, 0);
+  fColl->CreateTH1F("h_mis_PionK0", "all NON K0 pion candidates MC tagged; p (GeV/c); counts",  nBins, pMin, pMax, 0);
+  fColl->CreateTH1F("h_mis_PionL", "all NON Lambda pion candidates MC tagged ; p (GeV/c); counts", nBins, pMin, pMax, 0);
+  fColl->CreateTH1F("h_mis_Kaon", "all NON Kaon candidates MC tagged; p (GeV/c); counts", nBins, pMin, pMax, 0);
+  fColl->CreateTH1F("h_mis_Proton", "all NON Lambda proton candidates MC tagged; p (GeV/c); counts", nBins, pMin, pMax, 0);  
+
+  fColl->CreateTH1Fvector1(5, "h_tag_Electron", "electron candidate MC tagged; p (GeV/c); counts", nBins, pMin, pMax, 0);
+  fColl->CreateTH1Fvector1(5, "h_tag_PionK0", "K0 pion candidate MC tagged; p (GeV/c); counts", nBins, pMin, pMax, 0);
+  fColl->CreateTH1Fvector1(5, "h_tag_PionL", "Lambda pion candidate MC tagged; p (GeV/c); counts", nBins, pMin, pMax, 0);
+  fColl->CreateTH1Fvector1(5, "h_tag_Kaon", "kaon candidate MC tagged; p (GeV/c); counts", nBins, pMin, pMax, 0);
+  fColl->CreateTH1Fvector1(5, "h_tag_Proton", "Lambda proton candidate MC tagged; p (GeV/c); counts", nBins, pMin, pMax, 0);
 
 }
 //____________________________________________________________
index ae8c5e4..b0d57a1 100644 (file)
@@ -49,6 +49,7 @@ AliHFEcollection::AliHFEcollection():
   //
 
   fList = new THashList();
+  fList->SetOwner();
   if(!fList){
     AliError("Initialization of the list failed");
   }
@@ -71,6 +72,7 @@ AliHFEcollection::AliHFEcollection(const char* name, const char* title):
   //
  
   fList = new THashList();
+  fList->SetOwner();
   fList->SetName(Form("list_%s", name));
   if(!fList){
     AliError("Initialization of the list failed");
@@ -125,10 +127,8 @@ AliHFEcollection::~AliHFEcollection(){
   //
   // Destructor
   //
-  if(fList)
-    fList->Delete();
   delete fList;
-  AliInfo("DESTRUCTOR");
+  AliDebug(1, "DESTRUCTOR");
 }
 //___________________________________________________________________
 Bool_t AliHFEcollection::CreateTH1F(const char* name, const char* title, Int_t nBin, Float_t nMin, Float_t nMax, Int_t logAxis){
index 3f673b3..5d2e4a9 100644 (file)
@@ -67,7 +67,7 @@ class AliHFEcollection : public TNamed{
   Long64_t Merge(TCollection *list);
 
   // Get functions
-  TList* GetList()  const  { return fList; }
+  TList* GetList() const { return fList; }
   TObject* Get(const char* name); 
 
   // Fill functions
index 39dab14..6353b29 100644 (file)
@@ -51,6 +51,7 @@ AliHFEcontainer::AliHFEcontainer():
   // Default constructor
   //
   fContainers = new THashList();
+  fContainers->SetOwner();
 }
 
 //__________________________________________________________________
@@ -66,6 +67,7 @@ AliHFEcontainer::AliHFEcontainer(const Char_t *name):
   // Default constructor
   //
   fContainers = new THashList();
+  fContainers->SetOwner();
 }
 
 //__________________________________________________________________
@@ -82,6 +84,7 @@ AliHFEcontainer::AliHFEcontainer(const Char_t *name, UInt_t nVar):
   // Setting Number of Variables too
   //
   fContainers = new THashList();
+  fContainers->SetOwner();
   SetNumberOfVariables(nVar);
 }
 
@@ -104,6 +107,7 @@ AliHFEcontainer::AliHFEcontainer(const AliHFEcontainer &ref):
       fVariables->AddAt(new AliHFEvarInfo(*dynamic_cast<AliHFEvarInfo *>(ref.fVariables->UncheckedAt(ivar))), ivar);
   }
   fContainers = new THashList;
+  fContainers->SetOwner();
   AliCFContainer *ctmp = NULL;
   for(Int_t ien = 0; ien < ref.fContainers->GetEntries(); ien++){
     ctmp = dynamic_cast<AliCFContainer *>(ref.fContainers->At(ien));
@@ -113,6 +117,7 @@ AliHFEcontainer::AliHFEcontainer(const AliHFEcontainer &ref):
   if(ref.fCorrelationMatrices){
     THnSparseF *htmp = NULL;
     fCorrelationMatrices = new THashList;
+    fCorrelationMatrices->SetOwner();
     for(Int_t ien = 0; ien < ref.fCorrelationMatrices->GetEntries(); ien++){
       htmp = dynamic_cast<THnSparseF *>(ref.fCorrelationMatrices->At(ien));
       CreateCorrelationMatrix(htmp->GetName(), htmp->GetTitle());
@@ -139,7 +144,16 @@ AliHFEcontainer &AliHFEcontainer::operator=(const AliHFEcontainer &ref){
   } else {
     fVariables = NULL;
   }
-
+  // Copy also correlation matrices
+  if(ref.fCorrelationMatrices){
+    THnSparseF *htmp = NULL;
+    fCorrelationMatrices = new THashList;
+    fCorrelationMatrices->SetOwner();
+    for(Int_t ien = 0; ien < ref.fCorrelationMatrices->GetEntries(); ien++){
+      htmp = dynamic_cast<THnSparseF *>(ref.fCorrelationMatrices->At(ien));
+      CreateCorrelationMatrix(htmp->GetName(), htmp->GetTitle());
+    }
+  }
   return *this;
 }
 
@@ -148,8 +162,8 @@ AliHFEcontainer::~AliHFEcontainer(){
   //
   // Destructor
   //
-  fContainers->Delete();
   delete fContainers;
+  if(fCorrelationMatrices) delete fCorrelationMatrices;
   if(fVariables){
     fVariables->Delete();
     delete fVariables;
@@ -236,26 +250,26 @@ void AliHFEcontainer::CreateCorrelationMatrix(const Char_t *name, const Char_t *
   if(!fCorrelationMatrices){
     fCorrelationMatrices = new THashList;
     fCorrelationMatrices->SetName("fCorrelationMatrices");
+    fCorrelationMatrices->SetOwner();
   }
 
   Int_t *nBins = new Int_t[2*fNVars];
-  Double_t *binMin = new Double_t[2*fNVars];
-  Double_t *binMax = new Double_t[2*fNVars];
   AliHFEvarInfo *var = NULL;
   for(UInt_t ivar = 0; ivar < fNVars; ivar++){
     var = dynamic_cast<AliHFEvarInfo *>(fVariables->UncheckedAt(ivar));
     nBins[ivar] = var->GetNumberOfBins();
-    binMin[ivar] = var->GetBinning()[0];
-    binMax[ivar] = var->GetBinning()[var->GetNumberOfBins()];
+    nBins[ivar+fNVars] = var->GetNumberOfBins();
   }
 
-  THnSparseF * hTmp = new THnSparseF(name, title, 2*fNVars, nBins, binMin, binMax);
+  THnSparseF * hTmp = new THnSparseF(name, title, 2*fNVars, nBins);
   for(UInt_t ivar = 0; ivar < fNVars; ivar++){
     var = dynamic_cast<AliHFEvarInfo *>(fVariables->UncheckedAt(ivar));
-    hTmp->GetAxis(ivar)->Set(var->GetNumberOfBins(), var->GetBinning());
+    hTmp->SetBinEdges(ivar,var->GetBinning());
+    //hTmp->GetAxis(ivar)->Set(var->GetNumberOfBins(), var->GetBinning());
     hTmp->GetAxis(ivar)->SetTitle(var->GetVarName()->Data());
-    hTmp->GetAxis(ivar + fNVars)->Set(var->GetNumberOfBins(), var->GetBinning());
+    //hTmp->GetAxis(ivar + fNVars)->Set(var->GetNumberOfBins(), var->GetBinning());
     hTmp->GetAxis(ivar + fNVars)->SetTitle(Form("%s_{MC}", var->GetVarName()->Data()));
+    hTmp->SetBinEdges(ivar+fNVars,var->GetBinning());
   }
   hTmp->Sumw2();
   fCorrelationMatrices->AddLast(hTmp);
@@ -278,13 +292,38 @@ THnSparseF *AliHFEcontainer::GetCorrelationMatrix(const Char_t *name) const{
 }
 
 //__________________________________________________________________
-void AliHFEcontainer::FillCFContainer(const Char_t *name, UInt_t step, Double_t *content){
+void AliHFEcontainer::FillCFContainer(const Char_t *name, UInt_t step, Double_t *content, Double_t weight) const {
   //
   // Fill container
   //
   AliCFContainer *cont = GetCFContainer(name);
   if(!cont) return;
-  cont->Fill(content, step);
+  cont->Fill(content, step, weight);
+}
+
+//__________________________________________________________________
+void AliHFEcontainer::FillCFContainerStepname(const Char_t *name, const Char_t *steptitle, Double_t *content, Double_t weight)const{
+  //
+  // Fill container
+  //
+  AliCFContainer *cont = GetCFContainer(name);
+  if(!cont) return;
+  // find the matching step title
+  Int_t mystep = -1;
+  for(Int_t istep = 0; istep < cont->GetNStep(); istep++){
+    TString tstept = cont->GetStepTitle(istep);
+    if(!tstept.CompareTo(steptitle)){
+      mystep = istep;
+      break;
+    }
+  }
+  if(mystep < 0){
+    // step not found
+    AliDebug(1, Form("Step %s not found in container %s", steptitle, name));
+    return;
+  }
+  AliDebug(1, Form("Filling step %s(%d) for container %s", steptitle, mystep, name));
+  cont->Fill(content, mystep, weight);
 }
 
 //__________________________________________________________________
@@ -326,6 +365,18 @@ AliCFContainer *AliHFEcontainer::MakeMergedCFContainer(const Char_t *name, const
   }
   return cmerged;
 }
+
+//__________________________________________________________________
+void AliHFEcontainer::SetStepTitle(const Char_t *contname, const Char_t *steptitle, UInt_t step){
+  //
+  // Set title for given analysis step in container with name contname
+  //
+  AliCFContainer *cont = GetCFContainer(contname);
+  if(!cont) return;
+  if(step >= static_cast<UInt_t>(cont->GetNStep())) return;
+  cont->SetStepTitle(step, steptitle);
+}
+
 //__________________________________________________________________
 void AliHFEcontainer::MakeLinearBinning(UInt_t var, UInt_t nBins, Double_t begin, Double_t end){
   //
index 5c0b0bf..8abea8d 100644 (file)
@@ -58,7 +58,8 @@ class AliHFEcontainer : public TNamed{
     AliCFContainer *GetCFContainer(const Char_t *name) const;
     THnSparseF *GetCorrelationMatrix(const Char_t *name) const;
     THashList *GetListOfCorrelationMatrices() const { return fCorrelationMatrices; }
-    void FillCFContainer(const Char_t *name, UInt_t step, Double_t *content);
+    void FillCFContainer(const Char_t *name, UInt_t step, Double_t *content, Double_t weight = 1.) const;
+    void FillCFContainerStepname(const Char_t *name, const Char_t *step, Double_t *content, Double_t weight = 1.) const;
     AliCFContainer *MakeMergedCFContainer(const Char_t *name, const Char_t *title, const Char_t *contnames);
 
     Int_t GetNumberOfCFContainers() const;
@@ -67,10 +68,11 @@ class AliHFEcontainer : public TNamed{
     void SetNumberOfVariables(UInt_t nVar);
     inline void SetBinning(UInt_t var, UInt_t nBins, Double_t *content);
     void SetVariableName(UInt_t var, const Char_t *varname);
+    void SetStepTitle(const Char_t *contname, const Char_t *steptitle, UInt_t step);
     void MakeLinearBinning(UInt_t var, UInt_t nBins, Double_t begin, Double_t end);
     void MakeLogarithmicBinning(UInt_t var, UInt_t nBins, Double_t begin, Double_t end);
 
-    virtual void Print(const Option_t * opt = 0x0) const;
+    virtual void Print(const Option_t * opt = NULL) const;
 
     struct AliHFEvarInfo : public TObject{
         AliHFEvarInfo();
index 7977614..918b0d2 100644 (file)
@@ -43,7 +43,7 @@ class AliHFEcutStep : public TNamed{
       void SetRecEvent(AliVEvent *mc);
 
     private:
-      TObjArray *fCuts;
+      TObjArray *fCuts; // List of cuts in one cut step
       
       ClassDef(AliHFEcutStep, 1)
 };
index f9cd83e..29a537e 100644 (file)
 
 ClassImp(AliHFEcuts)
 
+const Char_t *AliHFEcuts::fgkMCCutName[AliHFEcuts::kNcutStepsMCTrack] = {
+  "MCGenerated",
+  "MCGeneratedZOutNoPileUp",
+  "MCGeneratedEventCut",
+  "MCInAcceptance"
+};
+
+const Char_t * AliHFEcuts::fgkRecoCutName[AliHFEcuts::kNcutStepsRecTrack] = {
+  "NoCuts",
+  "RecKineITSTPC",
+  "Primary",
+  "HFEITS",
+  "HFETRD"
+};
+
+const Char_t * AliHFEcuts::fgkDECutName[AliHFEcuts::kNcutStepsDETrack] = {
+  "HFEDCA"
+};
+
+const Char_t * AliHFEcuts::fgkEventCutName[AliHFEcuts::kNcutStepsEvent] = {
+  "EventStepGenerated",
+  "EventStepRecNoCut",
+  "EventStepRecNoPileUp",
+  "EventStepZRange",
+  "EventStepReconstructed"
+};
+
+const Char_t * AliHFEcuts::fgkUndefined = "Undefined";
+
 //__________________________________________________________________
 AliHFEcuts::AliHFEcuts():
   TNamed(),
   fRequirements(0),
+  fTPCiter1(kFALSE),
   fMinClustersTPC(0),
+  fMinClustersITS(0),
   fMinTrackletsTRD(0),
   fCutITSPixel(0),
   fCheckITSLayerStatus(kTRUE),
   fMaxChi2clusterTPC(0.),
   fMinClusterRatioTPC(0.),
   fSigmaToVtx(0.),
+  fVertexRangeZ(20.),
   fHistQA(0x0),
   fCutList(0x0),
   fDebugLevel(0)
@@ -94,13 +126,16 @@ AliHFEcuts::AliHFEcuts():
 AliHFEcuts::AliHFEcuts(const Char_t *name, const Char_t *title):
   TNamed(name, title),
   fRequirements(0),
+  fTPCiter1(kFALSE),
   fMinClustersTPC(0),
+  fMinClustersITS(0),
   fMinTrackletsTRD(0),
   fCutITSPixel(0),
   fCheckITSLayerStatus(kTRUE),
   fMaxChi2clusterTPC(0.),
   fMinClusterRatioTPC(0.),
   fSigmaToVtx(0.),
+  fVertexRangeZ(20.),
   fHistQA(0x0),
   fCutList(0x0),
   fDebugLevel(0)
@@ -117,13 +152,16 @@ AliHFEcuts::AliHFEcuts(const Char_t *name, const Char_t *title):
 AliHFEcuts::AliHFEcuts(const AliHFEcuts &c):
   TNamed(c),
   fRequirements(c.fRequirements),
+  fTPCiter1(c.fTPCiter1),
   fMinClustersTPC(0),
+  fMinClustersITS(0),
   fMinTrackletsTRD(0),
   fCutITSPixel(0),
   fCheckITSLayerStatus(0),
   fMaxChi2clusterTPC(0),
   fMinClusterRatioTPC(0),
   fSigmaToVtx(0),
+  fVertexRangeZ(20.),
   fHistQA(0x0),
   fCutList(0x0),
   fDebugLevel(0)
@@ -151,13 +189,16 @@ void AliHFEcuts::Copy(TObject &c) const {
   AliHFEcuts &target = dynamic_cast<AliHFEcuts &>(c);
 
   target.fRequirements = fRequirements;
+  target.fTPCiter1 = fTPCiter1;
   target.fMinClustersTPC = fMinClustersTPC;
+  target.fMinClustersITS = fMinClustersITS;
   target.fMinTrackletsTRD = fMinTrackletsTRD;
   target.fCutITSPixel = fCutITSPixel;
   target.fCheckITSLayerStatus = fCheckITSLayerStatus;
   target.fMaxChi2clusterTPC = fMaxChi2clusterTPC;
   target.fMinClusterRatioTPC = fMinClusterRatioTPC;
   target.fSigmaToVtx = fSigmaToVtx;
+  target.fVertexRangeZ = fVertexRangeZ;
   target.fDebugLevel = 0;
 
   memcpy(target.fProdVtx, fProdVtx, sizeof(Double_t) * 4);
@@ -214,6 +255,8 @@ void AliHFEcuts::Initialize(AliCFManager *cfm){
   // Publishes the cuts to the correction framework manager
   //
   AliDebug(2, "Called");
+  const Int_t kMCOffset = kNcutStepsMCTrack;
+  const Int_t kRecOffset = kNcutStepsRecTrack;
   if(fCutList)
     fCutList->Delete();
   else{
@@ -233,6 +276,7 @@ void AliHFEcuts::Initialize(AliCFManager *cfm){
   SetRecPrimaryCutList();
   SetHFElectronITSCuts();
   SetHFElectronTRDCuts();
+  SetHFElectronDcaCuts();
 
   // Publish to the cuts which analysis type they are (ESD Analysis by default)
   if(IsAOD()){
@@ -251,12 +295,15 @@ void AliHFEcuts::Initialize(AliCFManager *cfm){
   cfm->SetEventCutsList(kEventStepReconstructed, dynamic_cast<TObjArray *>(fCutList->FindObject("fEvRecCuts")));
   
   // Connect the particle cuts
+  // 1st MC
   cfm->SetParticleCutsList(kStepMCGenerated, dynamic_cast<TObjArray *>(fCutList->FindObject("fPartGenCuts")));
   cfm->SetParticleCutsList(kStepMCInAcceptance, dynamic_cast<TObjArray *>(fCutList->FindObject("fPartAccCuts")));
-  cfm->SetParticleCutsList(kStepRecKineITSTPC, dynamic_cast<TObjArray *>(fCutList->FindObject("fPartRecKineITSTPCCuts")));
-  cfm->SetParticleCutsList(kStepRecPrim, dynamic_cast<TObjArray *>(fCutList->FindObject("fPartPrimCuts")));
-  cfm->SetParticleCutsList(kStepHFEcutsITS, dynamic_cast<TObjArray *>(fCutList->FindObject("fPartHFECutsITS")));
-  cfm->SetParticleCutsList(kStepHFEcutsTRD, dynamic_cast<TObjArray *>(fCutList->FindObject("fPartHFECutsTRD")));
+  // 2nd Reco
+  cfm->SetParticleCutsList(kStepRecKineITSTPC + kMCOffset, dynamic_cast<TObjArray *>(fCutList->FindObject("fPartRecKineITSTPCCuts")));
+  cfm->SetParticleCutsList(kStepRecPrim + kMCOffset, dynamic_cast<TObjArray *>(fCutList->FindObject("fPartPrimCuts")));
+  cfm->SetParticleCutsList(kStepHFEcutsITS + kMCOffset, dynamic_cast<TObjArray *>(fCutList->FindObject("fPartHFECutsITS")));
+  cfm->SetParticleCutsList(kStepHFEcutsTRD + kMCOffset, dynamic_cast<TObjArray *>(fCutList->FindObject("fPartHFECutsTRD")));
+  cfm->SetParticleCutsList(kStepHFEcutsDca + kRecOffset + kMCOffset, dynamic_cast<TObjArray *>(fCutList->FindObject("fPartHFECutsDca")));
 
 }
 
@@ -281,6 +328,7 @@ void AliHFEcuts::Initialize(){
   SetRecPrimaryCutList();
   SetHFElectronITSCuts();
   SetHFElectronTRDCuts();
+  SetHFElectronDcaCuts();
 
 }
 
@@ -293,22 +341,24 @@ void AliHFEcuts::SetEventCutList(Int_t istep){
   TObjArray *arr = new TObjArray;
   if(istep == kEventStepGenerated){
     AliCFEventGenCuts *evGenCuts = new AliCFEventGenCuts((Char_t *)"fCutsEvGen", (Char_t *)"Event Generated cuts");
-    evGenCuts->SetNTracksCut(1);
+    //evGenCuts->SetNTracksCut(1);
     evGenCuts->SetRequireVtxCuts(kTRUE);
-    evGenCuts->SetVertexXCut(-1, 1);
-    evGenCuts->SetVertexYCut(-1, 1);
-    evGenCuts->SetVertexZCut(-10, 10);
+    //evGenCuts->SetVertexXCut(-1, 1);
+    //evGenCuts->SetVertexYCut(-1, 1);
+    evGenCuts->SetVertexZCut(-fVertexRangeZ, fVertexRangeZ);
     if(IsQAOn()) evGenCuts->SetQAOn(fHistQA);
 
     arr->SetName("fEvGenCuts");
     arr->AddLast(evGenCuts);
   } else {
     AliCFEventRecCuts *evRecCuts = new AliCFEventRecCuts((Char_t *)"fCutsEvRec", (Char_t *)"Event Reconstructed cuts");
-    evRecCuts->SetNTracksCut(1);
+    //evRecCuts->SetNTracksCut(1);
     evRecCuts->SetRequireVtxCuts(kTRUE);
-    evRecCuts->SetVertexXCut(-1, 1);
-    evRecCuts->SetVertexYCut(-1, 1);
-    evRecCuts->SetVertexZCut(-30, 30);
+    //evRecCuts->SetVertexXCut(-1, 1);
+    //evRecCuts->SetVertexYCut(-1, 1);
+    //evRecCuts->SetVertexZCut(-30, 30);
+    evRecCuts->SetVertexZCut(-fVertexRangeZ, fVertexRangeZ);
+    evRecCuts->SetVertexNContributors(1,(Int_t)1.e9);
     if(IsQAOn()) evRecCuts->SetQAOn(fHistQA);
 
     arr->SetName("fEvRecCuts");
@@ -407,15 +457,22 @@ void AliHFEcuts::SetRecKineITSTPCCutList(){
   //
   AliDebug(2, "Called\n");
   AliCFTrackQualityCuts *trackQuality = new AliCFTrackQualityCuts((Char_t *)"fCutsQualityRec", (Char_t *)"REC Track Quality Cuts");
-  trackQuality->SetMinNClusterITS(4);
-  trackQuality->SetMinNClusterTPC(fMinClustersTPC);
+  trackQuality->SetMinNClusterITS(fMinClustersITS);
   trackQuality->SetMaxChi2PerClusterTPC(fMaxChi2clusterTPC);
   trackQuality->SetStatus(AliESDtrack::kTPCrefit | AliESDtrack::kITSrefit);
-  trackQuality->SetMaxCovDiagonalElements(2., 2., 0.5, 0.5, 2); 
+  //trackQuality->SetMaxCovDiagonalElements(2., 2., 0.5, 0.5, 2); 
 
   AliHFEextraCuts *hfecuts = new AliHFEextraCuts("fCutsHFElectronGroupTPC","Extra cuts from the HFE group");
   if(fMinClusterRatioTPC > 0.) hfecuts->SetClusterRatioTPC(fMinClusterRatioTPC);
   hfecuts->SetDebugLevel(fDebugLevel);
+
+  // Set the cut in the TPC number of clusters
+  if(fTPCiter1){
+    hfecuts->SetMinNClustersTPC(fMinClustersTPC);
+    hfecuts->SetTPCIter1(kTRUE);
+  }
+  else
+    trackQuality->SetMinNClusterTPC(fMinClustersTPC);
   
   AliCFTrackKineCuts *kineCuts = new AliCFTrackKineCuts((Char_t *)"fCutsKineRec", (Char_t *)"REC Kine Cuts");
   kineCuts->SetPtRange(fPtRange[0], fPtRange[1]);
@@ -503,20 +560,38 @@ void AliHFEcuts::SetHFElectronTRDCuts(){
 }
 
 //__________________________________________________________________
-Bool_t AliHFEcuts::CheckParticleCuts(CutStep_t step, TObject *o){
+void AliHFEcuts::SetHFElectronDcaCuts(){
+  //
+  // Special Cuts introduced by the HFElectron Group: minimum of impact parameter
+  //
+  AliDebug(2, "Called\n");
+  AliHFEextraCuts *hfecuts = new AliHFEextraCuts("fCutsHFElectronGroupDCA","Extra cuts from the HFE group");
+  hfecuts->SetMinHFEImpactParamR();
+  //hfecuts->SetMinHFEImpactParamNsigmaR();
+  if(IsQAOn()) hfecuts->SetQAOn(fHistQA);
+  hfecuts->SetDebugLevel(fDebugLevel);
+
+  TObjArray *hfeCuts = new TObjArray;
+  hfeCuts->SetName("fPartHFECutsDca");
+  hfeCuts->AddLast(hfecuts);
+  fCutList->AddLast(hfeCuts);
+}
+
+//__________________________________________________________________
+Bool_t AliHFEcuts::CheckParticleCuts(UInt_t step, TObject *o){
   //
   // Checks the cuts without using the correction framework manager
   // 
   AliDebug(2, "Called\n");
-  TString stepnames[kNcutStepsTrack] = {"fPartGenCuts","fPartSignal","fPartAccCuts","fPartRecNoCuts","fPartRecKineITSTPCCuts", "fPartPrimCuts", "fPartHFECutsITS","fPartHFECutsTRD","fPartHFEPid"};
+  TString stepnames[kNcutStepsMCTrack + kNcutStepsRecTrack + kNcutStepsDETrack + 1] = {"fPartGenCuts","fPartEvCutPileupZ","fPartEvCut","fPartAccCuts","fPartRecNoCuts","fPartRecKineITSTPCCuts", "fPartPrimCuts", "fPartHFECutsITS","fPartHFECutsTRD","fPartHFECutsDca"};
+  AliDebug(2, Form("Doing cut %s", stepnames[step].Data()));
  TObjArray *cuts = dynamic_cast<TObjArray *>(fCutList->FindObject(stepnames[step].Data()));
   if(!cuts) return kTRUE;
-  TIterator *it = cuts->MakeIterator();
+  TIter it(cuts);
   AliCFCutBase *mycut;
   Bool_t status = kTRUE;
-  while((mycut = dynamic_cast<AliCFCutBase *>(it->Next()))){
+  while((mycut = dynamic_cast<AliCFCutBase *>(it()))){
     status &= mycut->IsSelected(o);
   }
-  delete it;
   return status;
 }
index 4db447a..0f54671 100644 (file)
@@ -38,26 +38,32 @@ class TList;
 class AliHFEcuts : public TNamed{
   public:
     typedef enum{
+      kStepRecNoCut = 0,
+      kStepRecKineITSTPC = 1,
+      kStepRecPrim = 2,
+      kStepHFEcutsITS = 3,
+      kStepHFEcutsTRD = 4,
+      kNcutStepsRecTrack = 5
+    } RecoCutStep_t;
+    typedef enum{
+      kStepHFEcutsDca = 0, 
+      kNcutStepsDETrack = 1
+    } DECutStep_t;
+    typedef enum{
       kStepMCGenerated = 0,
-      kStepMCsignal = 1,
-      kStepMCInAcceptance = 2,
-      kStepRecNoCut = 3,
-      kStepRecKineITSTPC = 4,
-      kStepRecPrim = 5,
-      kStepHFEcutsITS = 6,
-      kStepHFEcutsTRD = 7,
-      kStepPID = 8
-    } CutStep_t;
+      kStepMCGeneratedZOutNoPileUp = 1,
+      kStepMCGeneratedEventCut = 2,
+      kStepMCInAcceptance = 3,
+      kNcutStepsMCTrack =  4
+    } MCCutStep_t;
     typedef enum{
       kEventStepGenerated = 0,
       kEventStepRecNoCut = 1,
-      kEventStepReconstructed = 2
+      kEventStepRecNoPileUp = 2,
+      kEventStepZRange = 3,
+      kEventStepReconstructed = 4,
+      kNcutStepsEvent = 5
     } EventCutStep_t;
-    enum{
-      kNcutStepsEvent = 3,
-      kNcutStepsTrack = 9,
-      kNcutStepsESDtrack = 6 
-    };    // Additional constants
 
     AliHFEcuts();
     AliHFEcuts(const Char_t *name, const Char_t *title);
@@ -69,7 +75,7 @@ class AliHFEcuts : public TNamed{
     void Initialize(AliCFManager *cfm);
     void Initialize();
 
-    Bool_t CheckParticleCuts(CutStep_t step, TObject *o);
+    Bool_t CheckParticleCuts(UInt_t step, TObject *o);
   
     TList *GetQAhistograms() const { return fHistQA; }
     
@@ -80,7 +86,25 @@ class AliHFEcuts : public TNamed{
     void SetESD() { SetBit(kAOD, kFALSE); }
     Bool_t IsAOD() const { return TestBit(kAOD); }
     Bool_t IsESD() const { return !TestBit(kAOD); }
-    
+
+    // Cut Names
+    static const Char_t *MCCutName(UInt_t step){
+      if(step >= kNcutStepsMCTrack) return fgkUndefined;
+      return fgkMCCutName[step];
+    };
+    static const Char_t *RecoCutName(UInt_t step){
+      if(step >= kNcutStepsRecTrack) return fgkUndefined;
+      return fgkRecoCutName[step];
+    }
+    static const Char_t *DECutName(UInt_t step){
+      if(step >= kNcutStepsDETrack) return fgkUndefined;
+      return fgkDECutName[step];
+    }
+    static const Char_t *EventCutName(UInt_t step){
+      if(step >= kNcutStepsEvent) return fgkUndefined;
+      return fgkEventCutName[step];
+    }
+   
     // Getters
     Bool_t IsRequireITSpixel() const { return TESTBIT(fRequirements, kITSPixel); };
     Bool_t IsRequireMaxImpactParam() const { return TESTBIT(fRequirements, kMaxImpactParam); };
@@ -89,11 +113,13 @@ class AliHFEcuts : public TNamed{
     Bool_t IsRequireSigmaToVertex() const { return TESTBIT(fRequirements, kSigmaToVertex); };
     Bool_t IsRequireDCAToVertex() const {return TESTBIT(fRequirements, kDCAToVertex); };
     Bool_t IsRequireKineMCCuts() const {return TESTBIT(fRequirements, kKineMCCuts); };
+    Double_t GetVertexRange() const {return fVertexRangeZ; };
     
     // Setters
     inline void SetCutITSpixel(UChar_t cut);
     void SetCheckITSLayerStatus(Bool_t checkITSLayerStatus) { fCheckITSLayerStatus = checkITSLayerStatus; }
     void SetMinNClustersTPC(UChar_t minClustersTPC) { fMinClustersTPC = minClustersTPC; }
+    void SetMinNClustersITS(UChar_t minClustersITS) { fMinClustersITS = minClustersITS; }
     void SetMinNTrackletsTRD(UChar_t minNtrackletsTRD) { fMinTrackletsTRD = minNtrackletsTRD; }
     void SetMaxChi2perClusterTPC(Double_t chi2) { fMaxChi2clusterTPC = chi2; };
     inline void SetMaxImpactParam(Double_t radial, Double_t z);
@@ -101,6 +127,8 @@ class AliHFEcuts : public TNamed{
     void SetPtRange(Double_t ptmin, Double_t ptmax){fPtRange[0] = ptmin; fPtRange[1] = ptmax;};
     inline void SetProductionVertex(Double_t xmin, Double_t xmax, Double_t ymin, Double_t ymax);
     inline void SetSigmaToVertex(Double_t sig);
+    void SetTPCiter1(Bool_t iter1) { fTPCiter1 = iter1; }
+    void SetVertexRange(Double_t zrange){fVertexRangeZ = zrange;};    
     
     inline void CreateStandardCuts();
     
@@ -110,6 +138,7 @@ class AliHFEcuts : public TNamed{
     void SetRequireITSPixel() { SETBIT(fRequirements, kITSPixel); }
     void SetRequireProdVertex() { SETBIT(fRequirements, kProductionVertex); };
     void SetRequireSigmaToVertex() { SETBIT(fRequirements, kSigmaToVertex); CLRBIT(fRequirements, kDCAToVertex); };
+    void UnsetVertexRequirement() { CLRBIT(fRequirements, kDCAToVertex); CLRBIT(fRequirements, kSigmaToVertex); }
     void SetRequireKineMCCuts() { SETBIT(fRequirements, kKineMCCuts); };
 
     void SetDebugLevel(Int_t level) { fDebugLevel = level; };
@@ -135,26 +164,37 @@ class AliHFEcuts : public TNamed{
     void SetRecPrimaryCutList();
     void SetHFElectronITSCuts();
     void SetHFElectronTRDCuts();
+    void SetHFElectronDcaCuts();
     void SetEventCutList(Int_t istep);
+
+    static const Char_t* fgkMCCutName[kNcutStepsMCTrack];     // Cut step names for MC single Track cuts
+    static const Char_t* fgkRecoCutName[kNcutStepsRecTrack];  // Cut step names for Rec single Track cuts
+    static const Char_t* fgkDECutName[kNcutStepsDETrack];     // Cut step names for impact parameter cuts
+    static const Char_t* fgkEventCutName[kNcutStepsEvent];    // Cut step names for Event cuts
+    static const Char_t* fgkUndefined;                        // Name for undefined (overflow)
   
     ULong64_t fRequirements;     // Bitmap for requirements
+    Bool_t fTPCiter1;             // TPC iter1
     Double_t fDCAtoVtx[2];           // DCA to Vertex
     Double_t fProdVtx[4];              // Production Vertex
     Double_t fPtRange[2];              // pt range
     UChar_t fMinClustersTPC;       // Min.Number of TPC clusters
+    UChar_t fMinClustersITS;       // Min.Number of TPC clusters
     UChar_t fMinTrackletsTRD;      // Min. Number of TRD tracklets
     UChar_t fCutITSPixel;              // Cut on ITS pixel
     Bool_t  fCheckITSLayerStatus;       // Check ITS layer status
     Double_t fMaxChi2clusterTPC;       // Max Chi2 per TPC cluster
     Double_t fMinClusterRatioTPC;      // Min. Ratio findable / found TPC clusters
     Double_t fSigmaToVtx;              // Sigma To Vertex
+    Double_t fVertexRangeZ;             // Vertex Range reconstructed
+
     
     TList *fHistQA;                        //! QA Histograms
     TObjArray *fCutList;               //! List of cut objects(Correction Framework Manager)
 
     Int_t fDebugLevel;            // Debug Level
     
-  ClassDef(AliHFEcuts, 1)         // Container for HFE cuts
+  ClassDef(AliHFEcuts, 2)         // Container for HFE cuts
 };
 
 //__________________________________________________________________
@@ -200,10 +240,11 @@ void AliHFEcuts::CreateStandardCuts(){
   //fDCAtoVtx[0] = 0.5;
   //fDCAtoVtx[1] = 1.5;
   fMinClustersTPC = 80;
+  fMinClustersITS = 4;
   fMinTrackletsTRD = 0;
   SetRequireITSPixel();
   fCutITSPixel = AliHFEextraCuts::kFirst;
-  fMaxChi2clusterTPC = 3.5;
+  fMaxChi2clusterTPC = 4.;
   fMinClusterRatioTPC = 0.6;
   fPtRange[0] = 0.1;
   fPtRange[1] = 20.;
diff --git a/PWG3/hfe/AliHFEdetPIDqa.cxx b/PWG3/hfe/AliHFEdetPIDqa.cxx
new file mode 100644 (file)
index 0000000..abc5561
--- /dev/null
@@ -0,0 +1,81 @@
+/**************************************************************************
+* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+*                                                                        *
+* Author: The ALICE Off-line Project.                                    *
+* Contributors are mentioned in the code where appropriate.              *
+*                                                                        *
+* Permission to use, copy, modify and distribute this software and its   *
+* documentation strictly for non-commercial purposes is hereby granted   *
+* without fee, provided that the above copyright notice appears in all   *
+* copies and that both the copyright notice and this permission notice   *
+* appear in the supporting documentation. The authors make no claims     *
+* about the suitability of this software for any purpose. It is          *
+* provided "as is" without express or implied warranty.                  *
+**************************************************************************/
+//
+// Class AliHFEdetPIDqa
+// Base class for detector PID QA describing the interface to the PID QA
+// manager, keeping also commom functionality. The following functions have
+// to be implemented by the detector PID QA classes:
+//   Initialize (basic initialization, i.e. histograms)
+//   ProcessTrack (filling of the QA container)
+// The base class provides the ESD/AOD PID object for all detector PID QA 
+// classes
+//
+// Author:
+//   Markus Fasel <M.Fasel@gsi.de>
+//
+
+#include "AliAODpidUtil.h"
+#include "AliESDpid.h"
+
+#include "AliHFEdetPIDqa.h"
+
+ClassImp(AliHFEdetPIDqa)
+
+//____________________________________________________________
+AliHFEdetPIDqa::AliHFEdetPIDqa():
+    TNamed()
+  , fESDpid(NULL)
+  , fAODpid(NULL)
+{
+  //
+  // Dummy constructor
+  //
+}
+
+//____________________________________________________________
+AliHFEdetPIDqa::AliHFEdetPIDqa(const Char_t *name, const Char_t *title):
+    TNamed(name, title)
+  , fESDpid(NULL)
+  , fAODpid(NULL)
+{
+  //
+  // Default constructor
+  //
+}
+
+//____________________________________________________________
+AliHFEdetPIDqa::AliHFEdetPIDqa(const AliHFEdetPIDqa &o):
+    TNamed(o)
+  , fESDpid(o.fESDpid)
+  , fAODpid(o.fAODpid)
+{
+  //
+  // Copy constructor
+  //
+}
+
+//____________________________________________________________
+AliHFEdetPIDqa &AliHFEdetPIDqa::operator=(const AliHFEdetPIDqa &o){
+  //
+  // Make assignment
+  //
+  TNamed::operator=(o);
+
+  fESDpid = o.fESDpid;
+  fAODpid = o.fAODpid;
+  
+  return *this;
+}
+
diff --git a/PWG3/hfe/AliHFEdetPIDqa.h b/PWG3/hfe/AliHFEdetPIDqa.h
new file mode 100644 (file)
index 0000000..23bcfa7
--- /dev/null
@@ -0,0 +1,59 @@
+/**************************************************************************
+* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+*                                                                        *
+* Author: The ALICE Off-line Project.                                    *
+* Contributors are mentioned in the code where appropriate.              *
+*                                                                        *
+* Permission to use, copy, modify and distribute this software and its   *
+* documentation strictly for non-commercial purposes is hereby granted   *
+* without fee, provided that the above copyright notice appears in all   *
+* copies and that both the copyright notice and this permission notice   *
+* appear in the supporting documentation. The authors make no claims     *
+* about the suitability of this software for any purpose. It is          *
+* provided "as is" without express or implied warranty.                  *
+**************************************************************************/
+//
+// Class AliHFEdetPIDqa
+// Base class for detector PID QA describing the interface to the PID QA
+// manager, keeping also commom functionality
+// More information can be found inside the implementation file
+//
+#ifndef ALIHFEDETPIDQA_H
+#define ALIHFEDETPIDQA_H
+
+#ifndef ROOT_TNamed
+#include <TNamed.h>
+#endif
+
+class AliAODpidUtil;
+class AliESDpid;
+class AliHFEpidObject;
+
+class AliHFEdetPIDqa : public TNamed{
+  public:
+    enum EStep_t{
+      kBeforePID = 0,
+      kAfterPID = 1
+    };
+    AliHFEdetPIDqa();
+    AliHFEdetPIDqa(const Char_t *name, const Char_t *title);
+    AliHFEdetPIDqa(const AliHFEdetPIDqa &c);
+    AliHFEdetPIDqa &operator=(const AliHFEdetPIDqa &o);
+    ~AliHFEdetPIDqa(){}
+
+    virtual void Initialize() = 0;
+    virtual void ProcessTrack(AliHFEpidObject *track, EStep_t step)= 0;
+
+    void SetESDpid(AliESDpid *esdpid) { fESDpid = esdpid; }
+    void SetAODpid(AliAODpidUtil *aodpid) { fAODpid = aodpid; }
+    AliESDpid *GetESDpid() const { return fESDpid; }
+    AliAODpidUtil *GetAODpid() const { return fAODpid; }
+
+  protected:
+    AliESDpid     *fESDpid;       //! ESD PID object
+    AliAODpidUtil *fAODpid;       //! AOD PID object
+  
+    ClassDef(AliHFEdetPIDqa, 1)     // Base class for detector PID QA
+};
+
+#endif
index d128133..54c6ec8 100644 (file)
@@ -229,6 +229,9 @@ void AliHFEefficiency::FilterMC(){
 }
 
 void AliHFEefficiency::Load(const char* filename){
+  //
+  // Load results for post processing
+  //
   TFile *input = TFile::Open(filename);
   AliHFEcontainer *cin = dynamic_cast<AliHFEcontainer *>(input->Get("Efficiency"));
   fEfficiency = dynamic_cast<AliHFEcontainer *>(cin->Clone());
@@ -363,7 +366,7 @@ void AliHFEefficiency::CalculatePTsmearing(){
   delete grid;
 }
 
-void AliHFEefficiency::DrawPtResolution(TList *l){
+void AliHFEefficiency::DrawPtResolution(const TList * const l){
   //
   // Draw pt resolution
   //
index 6de6d7e..ff2f53a 100644 (file)
@@ -53,7 +53,7 @@ class AliHFEefficiency : public AliAnalysisTaskSE{
     void SetRunTerminate(Bool_t terminate = kTRUE) { SetBit(kTerminate, terminate); }
 
     void CalculatePTsmearing();
-    void DrawPtResolution(TList *l);
+    void DrawPtResolution(const TList * const l);
 
   private:
     enum{
index 8306241..bb68be7 100644 (file)
@@ -176,15 +176,17 @@ AliHFEelecbackground::~AliHFEelecbackground()
   if(fPIDMethodPartner) delete fPIDMethodPartner;
   if(fPIDMethodPartnerITS) delete fPIDMethodPartnerITS;
 
-  if(fList){
-    fList->Clear();
-    delete fList;
-  }
-
   if(fListPostProcess){
-    fListPostProcess->Clear();
+    fListPostProcess->SetOwner(kTRUE);
     delete fListPostProcess;
   }
+
+/*
+  if(fhtmp) delete fhtmp;
+  if(fhtmpf) delete fhtmpf;
+  if(fhtmpp) delete fhtmpp;
+*/
+
 }
 //___________________________________________________________________________________________
 Bool_t AliHFEelecbackground::Load(const Char_t * filename)
@@ -1222,8 +1224,8 @@ Bool_t AliHFEelecbackground::PIDTrackCut(AliESDtrack* const trackPart)
     if(fPIDPartner) {
       if(!fPIDMethodPartner) return kFALSE;
       AliHFEpidObject hfetrack;
-      hfetrack.fAnalysisType = AliHFEpidObject::kESDanalysis;
-      hfetrack.fRecTrack = trackPart;
+      hfetrack.SetAnalysisType(AliHFEpidObject::kESDanalysis);
+      hfetrack.SetRecTrack(trackPart);
       //if(HasMCData()) hfetrack.fMCtrack = mctrack;
       if(!fPIDMethodPartner->IsSelected(&hfetrack)) return kFALSE;
       
@@ -1364,7 +1366,8 @@ void AliHFEelecbackground::SetPIDPartner() {
     
     if(!fPIDMethodPartner) {
       fPIDMethodPartner = new AliHFEpid();
-      fPIDMethodPartner->InitializePID("Strategy1");     // 3 sigma cut in TPC
+      fPIDMethodPartner->AddDetector("TPC", 0);
+      fPIDMethodPartner->InitializePID();     // 3 sigma cut in TPC
     }
 
   }
index 41cd385..ed0e7c0 100644 (file)
@@ -22,6 +22,7 @@
 // Authors:
 //   Markus Fasel <M.Fasel@gsi.de>
 //
+#include <TBits.h>
 #include <TClass.h>
 #include <TH1F.h>
 #include <TH2F.h>
 #include <TString.h>
 #include <TMath.h>
 
+#include "AliAODTrack.h"
+#include "AliAODPid.h"
+#include "AliESDEvent.h"
+#include "AliESDVertex.h"
 #include "AliESDtrack.h"
 #include "AliLog.h"
 #include "AliMCParticle.h"
+#include "AliVEvent.h"
+#include "AliVTrack.h"
+#include "AliVParticle.h"
+#include "AliVertexerTracks.h"
+#include "AliVVertex.h"
 
 #include "AliHFEextraCuts.h"
 
@@ -40,8 +50,11 @@ ClassImp(AliHFEextraCuts)
 //______________________________________________________
 AliHFEextraCuts::AliHFEextraCuts(const Char_t *name, const Char_t *title):
   AliCFCutBase(name, title),
+  fEvent(NULL),
   fCutCorrelation(0),
   fRequirements(0),
+  fTPCiter1(kFALSE),
+  fMinNClustersTPC(0),
   fClusterRatioTPC(0.),
   fMinTrackletsTRD(0),
   fPixelITS(0),
@@ -58,8 +71,11 @@ AliHFEextraCuts::AliHFEextraCuts(const Char_t *name, const Char_t *title):
 //______________________________________________________
 AliHFEextraCuts::AliHFEextraCuts(const AliHFEextraCuts &c):
   AliCFCutBase(c),
+  fEvent(c.fEvent),
   fCutCorrelation(c.fCutCorrelation),
   fRequirements(c.fRequirements),
+  fTPCiter1(c.fTPCiter1),
+  fMinNClustersTPC(c.fMinNClustersTPC),
   fClusterRatioTPC(c.fClusterRatioTPC),
   fMinTrackletsTRD(c.fMinTrackletsTRD),
   fPixelITS(c.fPixelITS),
@@ -86,9 +102,12 @@ AliHFEextraCuts &AliHFEextraCuts::operator=(const AliHFEextraCuts &c){
   //
   if(this != &c){
     AliCFCutBase::operator=(c);
+    fEvent = c.fEvent;
     fCutCorrelation = c.fCutCorrelation;
     fRequirements = c.fRequirements;
+    fTPCiter1 = c.fTPCiter1;
     fClusterRatioTPC = c.fClusterRatioTPC;
+    fMinNClustersTPC = c.fMinNClustersTPC;
     fMinTrackletsTRD = c.fMinTrackletsTRD;
     fPixelITS = c.fPixelITS;
     fCheck = c.fCheck;
@@ -108,10 +127,25 @@ AliHFEextraCuts::~AliHFEextraCuts(){
   //
   // Destructor
   //
-  if(fQAlist){
-    fQAlist->Delete();
-    delete fQAlist;
+  if(fQAlist) delete fQAlist;
+}
+
+//______________________________________________________
+void AliHFEextraCuts::SetRecEventInfo(const TObject *event){
+  //
+  // Set Virtual event an make a copy
+  //
+  if (!event) {
+    AliError("Pointer to AliVEvent !");
+    return;
+  }
+  TString className(event->ClassName());
+  if (! (className.CompareTo("AliESDEvent")==0 || className.CompareTo("AliAODEvent")==0)) {
+    AliError("argument must point to an AliESDEvent or AliAODEvent !");
+    return ;
   }
+  fEvent = (AliVEvent*) event;
+
 }
 
 //______________________________________________________
@@ -119,14 +153,16 @@ Bool_t AliHFEextraCuts::IsSelected(TObject *o){
   //
   // Steering function for the track selection
   //
-  if(TString(o->IsA()->GetName()).CompareTo("AliESDtrack") == 0){
-    return CheckESDCuts(dynamic_cast<AliESDtrack *>(o));
+  TString type = o->IsA()->GetName();
+  AliDebug(2, Form("Object type %s", type.Data()));
+  if(!type.CompareTo("AliESDtrack") || !type.CompareTo("AliAODTrack")){
+    return CheckRecCuts(dynamic_cast<AliVTrack *>(o));
   }
-  return CheckMCCuts(dynamic_cast<AliMCParticle *>(o));
+  return CheckMCCuts(dynamic_cast<AliVParticle *>(o));
 }
 
 //______________________________________________________
-Bool_t AliHFEextraCuts::CheckESDCuts(AliESDtrack *track){
+Bool_t AliHFEextraCuts::CheckRecCuts(AliVTrack *track){
   //
   // Checks cuts on reconstructed tracks
   // returns true if track is selected
@@ -135,19 +171,25 @@ Bool_t AliHFEextraCuts::CheckESDCuts(AliESDtrack *track){
   //
   AliDebug(1, "Called");
   ULong64_t survivedCut = 0;   // Bitmap for cuts which are passed by the track, later to be compared with fRequirements
-  if(IsQAOn()) FillQAhistosESD(track, kBeforeCuts);
+  if(IsQAOn()) FillQAhistosRec(track, kBeforeCuts);
   // Apply cuts
   Float_t impactR, impactZ, ratioTPC;
-  track->GetImpactParameters(impactR, impactZ);
+  Double_t hfeimpactR, hfeimpactnsigmaR;
+  Double_t hfeimpactRcut, hfeimpactnsigmaRcut;
+  GetImpactParameters(track, impactR, impactZ);
+  if(TESTBIT(fRequirements, kMinHFEImpactParamR) || TESTBIT(fRequirements, kMinHFEImpactParamNsigmaR)){
+    // Protection for PbPb
+    GetHFEImpactParameterCuts(track, hfeimpactRcut, hfeimpactnsigmaRcut);
+    GetHFEImpactParameters(track, hfeimpactR, hfeimpactnsigmaR);
+  }
+  UInt_t nTPCf = GetTPCfindableClusters(track, fTPCiter1), nclsTPC = GetTPCncls(track, fTPCiter1);
   // printf("Check TPC findable clusters: %d, found Clusters: %d\n", track->GetTPCNclsF(), track->GetTPCNcls());
-  ratioTPC = track->GetTPCNclsF() > 0. ? static_cast<Float_t>(track->GetTPCNcls())/static_cast<Float_t>(track->GetTPCNclsF()) : 1.;
+  ratioTPC = nTPCf > 0. ? static_cast<Float_t>(nclsTPC)/static_cast<Float_t>(nTPCf) : 1.;
   UChar_t trdTracklets;
-  trdTracklets = track->GetTRDntrackletsPID();
+  trdTracklets = GetTRDnTrackletsPID(track);
   UChar_t itsPixel = track->GetITSClusterMap();
-  Int_t det, status1, status2;
-  Float_t xloc, zloc;
-  track->GetITSModuleIndexInfo(0, det, status1, xloc, zloc);
-  track->GetITSModuleIndexInfo(1, det, status2, xloc, zloc);
+  Int_t status1 = GetITSstatus(track, 0);
+  Int_t status2 = GetITSstatus(track, 1);
   Bool_t statusL0 = CheckITSstatus(status1);
   Bool_t statusL1 = CheckITSstatus(status2);
   if(TESTBIT(fRequirements, kMinImpactParamR)){
@@ -166,6 +208,14 @@ Bool_t AliHFEextraCuts::CheckESDCuts(AliESDtrack *track){
     // cut on max. Impact Parameter in Z direction
     if(TMath::Abs(impactZ) <= fImpactParamCut[3]) SETBIT(survivedCut, kMaxImpactParamZ);
   }
+  if(TESTBIT(fRequirements, kMinHFEImpactParamR)){
+    // cut on min. HFE Impact Parameter in Radial direction
+    if(TMath::Abs(hfeimpactR) >= hfeimpactRcut) SETBIT(survivedCut, kMinHFEImpactParamR);
+  }
+  if(TESTBIT(fRequirements, kMinHFEImpactParamNsigmaR)){
+    // cut on max. HFE Impact Parameter n sigma in Radial direction
+    if(TMath::Abs(hfeimpactnsigmaR) >= hfeimpactnsigmaRcut) SETBIT(survivedCut, kMinHFEImpactParamNsigmaR);
+  }
   if(TESTBIT(fRequirements, kClusterRatioTPC)){
     // cut on min ratio of found TPC clusters vs findable TPC clusters
     if(ratioTPC >= fClusterRatioTPC) SETBIT(survivedCut, kClusterRatioTPC);
@@ -175,6 +225,11 @@ Bool_t AliHFEextraCuts::CheckESDCuts(AliESDtrack *track){
     AliDebug(1, Form("Min TRD cut: [%d|%d]\n", fMinTrackletsTRD, trdTracklets));
     if(trdTracklets >= fMinTrackletsTRD) SETBIT(survivedCut, kMinTrackletsTRD);
   }
+  if(TESTBIT(fRequirements, kMinNClustersTPC)){
+    // cut on minimum number of TRD tracklets
+    AliDebug(1, Form("Min TPC cut: [%d|%d]\n", fMinNClustersTPC, nclsTPC));
+    if(nclsTPC >= fMinNClustersTPC) SETBIT(survivedCut, kMinNClustersTPC);
+  }
   if(TESTBIT(fRequirements, kPixelITS)){
     // cut on ITS pixel layers
     AliDebug(1, "ITS cluster Map: ");
@@ -222,15 +277,17 @@ Bool_t AliHFEextraCuts::CheckESDCuts(AliESDtrack *track){
     //
     // Track selected
     //
-    if(IsQAOn()) FillQAhistosESD(track, kAfterCuts);
+    AliDebug(2, "Track Survived cuts\n");
+    if(IsQAOn()) FillQAhistosRec(track, kAfterCuts);
     return kTRUE;
   }
+  AliDebug(2, "Track cut");
   if(IsQAOn()) FillCutCorrelation(survivedCut);
   return kFALSE;
 }
 
 //______________________________________________________
-Bool_t AliHFEextraCuts::CheckMCCuts(AliMCParticle */*track*/) const {
+Bool_t AliHFEextraCuts::CheckMCCuts(AliVParticle */*track*/) const {
   //
   // Checks cuts on Monte Carlo tracks
   // returns true if track is selected
@@ -241,21 +298,23 @@ Bool_t AliHFEextraCuts::CheckMCCuts(AliMCParticle */*track*/) const {
 }
 
 //______________________________________________________
-void AliHFEextraCuts::FillQAhistosESD(AliESDtrack *track, UInt_t when){
+void AliHFEextraCuts::FillQAhistosRec(AliVTrack *track, UInt_t when){
   //
   // Fill the QA histograms for ESD tracks
   // Function can be called before cuts or after cut application (second argument)
   //
-  TList *container = dynamic_cast<TList *>(fQAlist->At(when));
+  const Int_t kNhistos = 6;
   Float_t impactR, impactZ;
-  track->GetImpactParameters(impactR, impactZ);
-  (dynamic_cast<TH1F *>(container->At(0)))->Fill(impactR);
-  (dynamic_cast<TH1F *>(container->At(1)))->Fill(impactZ);
+  GetImpactParameters(track, impactR, impactZ);
+  Int_t nTPCf = GetTPCfindableClusters(track, fTPCiter1), nclsTPC = GetTPCncls(track, fTPCiter1);
+  (dynamic_cast<TH1F *>(fQAlist->At(0 + when * kNhistos)))->Fill(impactR);
+  (dynamic_cast<TH1F *>(fQAlist->At(1 + when * kNhistos)))->Fill(impactZ);
   // printf("TPC findable clusters: %d, found Clusters: %d\n", track->GetTPCNclsF(), track->GetTPCNcls());
-  (dynamic_cast<TH1F *>(container->At(2)))->Fill(track->GetTPCNclsF() > 0. ? static_cast<Float_t>(track->GetTPCNcls())/static_cast<Float_t>(track->GetTPCNclsF()) : 1.);
-  (dynamic_cast<TH1F *>(container->At(3)))->Fill(track->GetTRDntrackletsPID());
+  (dynamic_cast<TH1F *>(fQAlist->At(2 + when * kNhistos)))->Fill(nTPCf > 0. ? static_cast<Float_t>(nclsTPC)/static_cast<Float_t>(nTPCf) : 1.);
+  (dynamic_cast<TH1F *>(fQAlist->At(3 + when * kNhistos)))->Fill(GetTRDnTrackletsPID(track));
+  (dynamic_cast<TH1F *>(fQAlist->At(4 + when * kNhistos)))->Fill(nclsTPC);
   UChar_t itsPixel = track->GetITSClusterMap();
-  TH1 *pixelHist = dynamic_cast<TH1F *>(container->At(4));
+  TH1 *pixelHist = dynamic_cast<TH1F *>(fQAlist->At(5 + when * kNhistos));
   //Int_t firstEntry = pixelHist->GetXaxis()->GetFirst();
   Double_t firstEntry = 0.5;
   if(!((itsPixel & BIT(0)) || (itsPixel & BIT(1))))
@@ -287,13 +346,14 @@ void AliHFEextraCuts::FillCutCorrelation(ULong64_t survivedCut){
   //
   // Fill cut correlation histograms for tracks that didn't pass cuts
   //
-  TH2 *correlation = dynamic_cast<TH2F *>(fQAlist->At(2));
+  const Int_t kNhistos = 6;
+  TH2 *correlation = dynamic_cast<TH2F *>(fQAlist->At(2 * kNhistos));
   for(Int_t icut = 0; icut < kNcuts; icut++){
     if(!TESTBIT(fRequirements, icut)) continue;
     for(Int_t jcut = icut; jcut < kNcuts; jcut++){
       if(!TESTBIT(fRequirements, jcut)) continue;
       if(TESTBIT(survivedCut, icut) && TESTBIT(survivedCut, jcut))
-       correlation->Fill(icut, jcut);
+             correlation->Fill(icut, jcut);
     }
   }
 }
@@ -307,30 +367,36 @@ void AliHFEextraCuts::AddQAHistograms(TList *qaList){
   // Additionally a histogram with the cut correlation is created and stored
   // in the top directory
   //
-  TList *histos[2];
+
+  const Int_t kNhistos = 6;
   TH1 *histo1D = 0x0;
   TH2 *histo2D = 0x0;
-  histos[0] = new TList();
-  histos[0]->SetName(Form("%s_BeforeCut",GetName()));
-  histos[0]->SetOwner();
-  histos[1] = new TList();
-  histos[1]->SetName(Form("%s_AfterCut",GetName()));
-  histos[1]->SetOwner();
   TString cutstr[2] = {"before", "after"};
+
+  if(!fQAlist) fQAlist = new TList;  // for internal representation, not owner
   for(Int_t icond = 0; icond < 2; icond++){
-    histos[icond]->AddAt((histo1D = new TH1F(Form("%s_impactParamR%s",GetName(),cutstr[icond].Data()), "Radial Impact Parameter", 100, 0, 10)), 0);
+    qaList->AddAt((histo1D = new TH1F(Form("%s_impactParamR%s",GetName(),cutstr[icond].Data()), "Radial Impact Parameter", 100, 0, 10)), 0 + icond * kNhistos);
+    fQAlist->AddAt(histo1D, 0 + icond * kNhistos);
     histo1D->GetXaxis()->SetTitle("Impact Parameter");
     histo1D->GetYaxis()->SetTitle("Number of Tracks");
-    histos[icond]->AddAt((histo1D = new TH1F(Form("%s_impactParamZ%s",GetName(),cutstr[icond].Data()), "Z Impact Parameter", 200, 0, 20)), 1);
+    qaList->AddAt((histo1D = new TH1F(Form("%s_impactParamZ%s",GetName(),cutstr[icond].Data()), "Z Impact Parameter", 200, 0, 20)), 1 + icond * kNhistos);
+    fQAlist->AddAt(histo1D, 1 + icond * kNhistos);
     histo1D->GetXaxis()->SetTitle("Impact Parameter");
     histo1D->GetYaxis()->SetTitle("Number of Tracks");
-    histos[icond]->AddAt((histo1D = new TH1F(Form("%s_tpcClr%s",GetName(),cutstr[icond].Data()), "Cluster Ratio TPC", 10, 0, 1)), 2);
+    qaList->AddAt((histo1D = new TH1F(Form("%s_tpcClr%s",GetName(),cutstr[icond].Data()), "Cluster Ratio TPC", 10, 0, 1)), 2 + icond * kNhistos);
+    fQAlist->AddAt(histo1D, 2 + icond * kNhistos);
     histo1D->GetXaxis()->SetTitle("Cluster Ratio TPC");
     histo1D->GetYaxis()->SetTitle("Number of Tracks");
-    histos[icond]->AddAt((histo1D = new TH1F(Form("%s_trdTracklets%s",GetName(),cutstr[icond].Data()), "Number of TRD tracklets", 7, 0, 7)), 3);
+    qaList->AddAt((histo1D = new TH1F(Form("%s_trdTracklets%s",GetName(),cutstr[icond].Data()), "Number of TRD tracklets", 7, 0, 7)), 3 + icond * kNhistos);
+    fQAlist->AddAt(histo1D, 3 + icond * kNhistos);
     histo1D->GetXaxis()->SetTitle("Number of TRD Tracklets");
     histo1D->GetYaxis()->SetTitle("Number of Tracks");
-    histos[icond]->AddAt((histo1D = new TH1F(Form("%s_itsPixel%s",GetName(),cutstr[icond].Data()), "ITS Pixel Hits", 6, 0, 6)), 4);
+    qaList->AddAt((histo1D = new TH1F(Form("%s_tpcClusters%s",GetName(),cutstr[icond].Data()), "Number of TPC clusters", 161, 0, 160)), 4 + icond * kNhistos);
+    fQAlist->AddAt(histo1D, 4 + icond * kNhistos);
+    histo1D->GetXaxis()->SetTitle("Number of TPC clusters");
+    histo1D->GetYaxis()->SetTitle("Number of Tracks");
+    qaList->AddAt((histo1D = new TH1F(Form("%s_itsPixel%s",GetName(),cutstr[icond].Data()), "ITS Pixel Hits", 6, 0, 6)), 5 + icond * kNhistos);
+    fQAlist->AddAt(histo1D, 5 + icond * kNhistos);
     histo1D->GetXaxis()->SetTitle("ITS Pixel");
     histo1D->GetYaxis()->SetTitle("Number of Tracks");
     Int_t first = histo1D->GetXaxis()->GetFirst();
@@ -338,20 +404,15 @@ void AliHFEextraCuts::AddQAHistograms(TList *qaList){
     for(Int_t ilabel = 0; ilabel < 6; ilabel++)
       histo1D->GetXaxis()->SetBinLabel(first + ilabel, binNames[ilabel].Data());
   }
-  fQAlist = new TList();
-  fQAlist->SetOwner();
-  fQAlist->SetName(Form("%s_HFelectronExtraCuts",GetName()));
-  fQAlist->AddAt(histos[0], 0);
-  fQAlist->AddAt(histos[1], 1);
   // Add cut correlation
-  fQAlist->AddAt((histo2D = new TH2F(Form("%s_cutcorrelation",GetName()), "Cut Correlation", kNcuts, 0, kNcuts - 1, kNcuts, 0, kNcuts -1)), 2);
-  TString labels[kNcuts] = {"MinImpactParamR", "MaxImpactParamR", "MinImpactParamZ", "MaxImpactParamZ", "ClusterRatioTPC", "MinTrackletsTRD", "ITSpixel"};
+  qaList->AddAt((histo2D = new TH2F(Form("%s_cutcorrelation",GetName()), "Cut Correlation", kNcuts, 0, kNcuts - 1, kNcuts, 0, kNcuts -1)), 2 * kNhistos);
+  fQAlist->AddAt(histo2D, 2 * kNhistos);
+  TString labels[kNcuts] = {"MinImpactParamR", "MaxImpactParamR", "MinImpactParamZ", "MaxImpactParamZ", "ClusterRatioTPC", "MinTrackletsTRD", "ITSpixel", "kMinHFEImpactParamR", "kMinHFEImpactParamNsigmaR", "TPC Number of clusters"};
   Int_t firstx = histo2D->GetXaxis()->GetFirst(), firsty = histo2D->GetYaxis()->GetFirst();
   for(Int_t icut = 0; icut < kNcuts; icut++){
     histo2D->GetXaxis()->SetBinLabel(firstx + icut, labels[icut].Data());
     histo2D->GetYaxis()->SetBinLabel(firsty + icut, labels[icut].Data());
   }
-  qaList->AddLast(fQAlist);
 }
 
 //______________________________________________________
@@ -375,3 +436,166 @@ Bool_t AliHFEextraCuts::CheckITSstatus(Int_t itsStatus) const {
   }
   return status;
 }
+
+//______________________________________________________
+Int_t AliHFEextraCuts::GetTRDnTrackletsPID(AliVTrack *track){
+       //
+       // Get Number of TRD tracklets
+       //
+       Int_t nTracklets = 0;
+       if(!TString(track->IsA()->GetName()).CompareTo("AliESDtrack")){
+               AliESDtrack *esdtrack = dynamic_cast<AliESDtrack *>(track);
+               nTracklets = esdtrack->GetTRDntrackletsPID();
+       } else if(!TString(track->IsA()->GetName()).CompareTo("AliAODTrack")){
+               AliAODTrack *aodtrack = dynamic_cast<AliAODTrack *>(track);
+               AliAODPid *pidobject = aodtrack->GetDetPid();
+               // this is normally NOT the way to do this, but due to limitation in the
+               // AOD track it is not possible in a different way
+               if(pidobject){
+                       Float_t *trdmom = pidobject->GetTRDmomentum();
+                       for(Int_t ily = 0; ily < 6; ily++){
+                               if(trdmom[ily] > -1) nTracklets++;
+                       }
+               } else nTracklets = 6;  // No Cut possible
+       }
+       return nTracklets;
+}
+
+//______________________________________________________
+Int_t AliHFEextraCuts::GetITSstatus(AliVTrack *track, Int_t layer){
+       //
+       // Check ITS layer status
+       //
+       Int_t status = 0;
+       if(!TString(track->IsA()->GetName()).CompareTo("AliESDtrack")){
+               Int_t det;
+               Float_t xloc, zloc;
+               AliESDtrack *esdtrack = dynamic_cast<AliESDtrack *>(track);
+               esdtrack->GetITSModuleIndexInfo(layer, det, status, xloc, zloc);
+       }
+       return status;
+}
+
+//______________________________________________________
+Int_t AliHFEextraCuts::GetTPCfindableClusters(AliVTrack *track, Bool_t iter1){
+       //
+       // Get Number of findable clusters in the TPC
+       //
+  AliDebug(1, Form("Using TPC clusters from iteration 1: %s", iter1 ? "Yes" : "No"));
+       Int_t nClusters = 159; // in case no Information available consider all clusters findable
+       if(!TString(track->IsA()->GetName()).CompareTo("AliESDtrack")){
+    AliESDtrack *esdtrack = dynamic_cast<AliESDtrack *>(track);
+               nClusters = esdtrack->GetTPCNclsF();
+  }
+       return nClusters;
+}
+
+//______________________________________________________
+Int_t AliHFEextraCuts::GetTPCncls(AliVTrack *track, Bool_t iter1){
+       //
+       // Get Number of findable clusters in the TPC
+       //
+  AliDebug(1, Form("Using TPC clusters from iteration 1: %s", iter1 ? "Yes" : "No"));
+       Int_t nClusters = 0; // in case no Information available consider all clusters findable
+       TString type = track->IsA()->GetName();
+       if(!type.CompareTo("AliESDtrack")){
+    AliESDtrack *esdtrack = dynamic_cast<AliESDtrack *>(track);
+    if(iter1)
+                 nClusters = esdtrack->GetTPCNclsIter1();
+    else
+                 nClusters = esdtrack->GetTPCNcls();
+  }
+       else if(!type.CompareTo("AliAODTrack")){
+               AliAODTrack *aodtrack = dynamic_cast<AliAODTrack *>(track);
+               const TBits &tpcmap = aodtrack->GetTPCClusterMap();
+               for(UInt_t ibit = 0; ibit < tpcmap.GetNbits(); ibit++)
+                       if(tpcmap.TestBitNumber(ibit)) nClusters++;
+
+       }
+       return nClusters;
+}
+
+//______________________________________________________
+void AliHFEextraCuts::GetImpactParameters(AliVTrack *track, Float_t &radial, Float_t &z){
+       //
+       // Get impact parameter
+       //
+       TString type = track->IsA()->GetName();
+       if(!type.CompareTo("AliESDtrack")){
+               AliESDtrack *esdtrack = dynamic_cast<AliESDtrack *>(track);
+               esdtrack->GetImpactParameters(radial, z);
+       }
+       else if(!type.CompareTo("AliAODTrack")){
+               AliAODTrack *aodtrack = dynamic_cast<AliAODTrack *>(track);
+               Double_t xyz[3];
+               aodtrack->XYZAtDCA(xyz);
+               z = xyz[2];
+               radial = TMath::Sqrt(xyz[0]*xyz[0] + xyz[1]+xyz[1]);
+       }
+}
+
+//______________________________________________________
+void AliHFEextraCuts::GetHFEImpactParameters(AliVTrack *track, Double_t &dcaxy, Double_t &dcansigmaxy){
+       //
+       // Get HFE impact parameter (with recalculated primary vertex)
+       //
+       dcaxy=0;
+       dcansigmaxy=0;
+  if(!fEvent){
+    AliDebug(1, "No Input event available\n");
+    return;
+  }
+  const Double_t kBeampiperadius=3.;
+  TString type = track->IsA()->GetName();
+  Double_t dca[2]={-999.,-999.};
+  Double_t cov[3]={-999.,-999.,-999.};
+
+  // recalculate primary vertex
+  AliVertexerTracks vertexer(fEvent->GetMagneticField());
+  vertexer.SetITSMode();
+  vertexer.SetMinClusters(4);
+       Int_t skipped[2];
+  skipped[0] = track->GetID();
+  vertexer.SetSkipTracks(1,skipped);
+  AliVVertex *vtxESDSkip = vertexer.FindPrimaryVertex(fEvent);
+  vertexer.SetSkipTracks(1,skipped);
+  if(vtxESDSkip->GetNContributors()<2) return;
+
+  // Getting the DCA
+  // Propagation always done on a working copy to not disturb the track params of the original track
+  AliESDtrack *esdtrack = NULL;
+  if(!TString(track->IsA()->GetName()).CompareTo("AliESDtrack")){
+    // Case ESD track: take copy constructor
+    esdtrack = new AliESDtrack(*dynamic_cast<AliESDtrack *>(track));
+  } else {
+    // Case AOD track: take different constructor
+    esdtrack = new AliESDtrack(track);
+  }
+  if(esdtrack->PropagateToDCA(vtxESDSkip, fEvent->GetMagneticField(), kBeampiperadius, dca, cov)){
+    // protection
+    dcaxy = dca[0];
+    if(cov[0]) dcansigmaxy = dcaxy/TMath::Sqrt(cov[0]);
+    if(!cov[0]) dcansigmaxy = -99.;
+  }
+  delete esdtrack;
+  delete vtxESDSkip;
+}
+
+
+//______________________________________________________
+void AliHFEextraCuts::GetHFEImpactParameterCuts(AliVTrack *track, Double_t &hfeimpactRcut, Double_t &hfeimpactnsigmaRcut){
+       //
+       // Get HFE impact parameter cut(pt dependent)
+       //
+  
+        TString type = track->IsA()->GetName();
+        if(!type.CompareTo("AliESDtrack")){
+        AliESDtrack *esdtrack = dynamic_cast<AliESDtrack *>(track);
+
+        Double_t pt = esdtrack->Pt();  
+        //hfeimpactRcut=0.0064+0.078*exp(-0.56*pt);  // used Carlo's old parameter 
+        hfeimpactRcut=0.011+0.077*exp(-0.65*pt); // used Carlo's new parameter
+        hfeimpactnsigmaRcut=3; // 3 sigma trail cut
+  }
+}
+
index 58695d4..d912ba3 100644 (file)
@@ -26,8 +26,9 @@
 
 class TList;
 
-class AliESDtrack;
-class AliMCParticle;
+class AliVEvent;
+class AliVParticle;
+class AliVTrack;
 
 class AliHFEextraCuts : public AliCFCutBase{
   public:
@@ -45,6 +46,7 @@ class AliHFEextraCuts : public AliCFCutBase{
     
     virtual Bool_t IsSelected(TObject *o);
     virtual Bool_t IsSelected(TList *) { return kTRUE; };
+    virtual void SetRecEventInfo(const TObject *event);
 
     inline void SetClusterRatioTPC(Double_t ratio);
     inline void SetRequireITSpixel(ITSPixel_t pixel);
@@ -52,7 +54,11 @@ class AliHFEextraCuts : public AliCFCutBase{
     inline void SetMaxImpactParamR(Double_t impactParam);
     inline void SetMinImpactParamZ(Double_t impactParam);
     inline void SetMaxImpactParamZ(Double_t impactParam);
+    inline void SetMinHFEImpactParamR();
+    inline void SetMinHFEImpactParamNsigmaR();
     inline void SetMinTrackletsTRD(Int_t minTracklets);
+    inline void SetMinNClustersTPC(Int_t minclusters);
+    void SetTPCIter1(Bool_t tpcIter1) { fTPCiter1 = tpcIter1; }
 
     void SetCheckITSstatus(Bool_t check) { fCheck = check; };
     Bool_t GetCheckITSstatus() const { return fCheck; };
@@ -62,14 +68,23 @@ class AliHFEextraCuts : public AliCFCutBase{
     
   protected:
     virtual void AddQAHistograms(TList *qaList);
-    Bool_t CheckESDCuts(AliESDtrack *track);
-    Bool_t CheckMCCuts(AliMCParticle * /*track*/) const;
+    Bool_t CheckRecCuts(AliVTrack *track);
+    Bool_t CheckMCCuts(AliVParticle * /*track*/) const;
     Bool_t CheckITSstatus(Int_t itsStatus) const;
-    void FillQAhistosESD(AliESDtrack *track, UInt_t when);
+    void FillQAhistosRec(AliVTrack *track, UInt_t when);
 //     void FillQAhistosMC(AliMCParticle *track, UInt_t when);
     void FillCutCorrelation(ULong64_t survivedCut);
     void PrintBitMap(Int_t bitmap);
     
+    // Getter Functions for ESD/AOD compatible mode
+    Int_t GetTRDnTrackletsPID(AliVTrack *track);
+    Int_t GetITSstatus(AliVTrack *track, Int_t layer);
+    Int_t GetTPCfindableClusters(AliVTrack *track, Bool_t iter1 = kFALSE);
+    Int_t GetTPCncls(AliVTrack *track, Bool_t iter1 = kFALSE);
+    void GetImpactParameters(AliVTrack *track, Float_t &radial, Float_t &z);
+    void GetHFEImpactParameters(AliVTrack *track, Double_t &dcaxy, Double_t &dcansigmaxy);
+    void GetHFEImpactParameterCuts(AliVTrack *track, Double_t &hfeimpactRcut, Double_t &hfeimpactnsigmaRcut);
+
   private:
     typedef enum{
       kMinImpactParamR = 0,
@@ -79,7 +94,10 @@ class AliHFEextraCuts : public AliCFCutBase{
       kClusterRatioTPC = 4,
       kMinTrackletsTRD = 5,
       kPixelITS = 6,
-      kNcuts = 7
+      kMinHFEImpactParamR = 7,
+      kMinHFEImpactParamNsigmaR = 8,
+      kMinNClustersTPC = 9,
+      kNcuts = 10
     } Cut_t;
     enum{
       //
@@ -88,9 +106,12 @@ class AliHFEextraCuts : public AliCFCutBase{
       kBeforeCuts =0,
       kAfterCuts = 1
     };
+    AliVEvent *fEvent;            //! working event
     ULong64_t fCutCorrelation;         // Cut Correlation
     ULong64_t fRequirements;           // Cut Requirements
+    Bool_t fTPCiter1;           // Tracking iteration from which the number of clusters is taken
     Float_t fImpactParamCut[4];                // Impact Parmameter Cut
+    UInt_t fMinNClustersTPC;      // Minimum TPC clusters cut
     Float_t fClusterRatioTPC;          // Ratio of findable vs. found clusters in TPC
     UChar_t fMinTrackletsTRD;          // Min. Number of Tracklets inside TRD
     UChar_t fPixelITS;                 // Cut on ITS Pixels
@@ -139,8 +160,24 @@ void AliHFEextraCuts::SetMaxImpactParamZ(Double_t impactParam){
 }
 
 //__________________________________________________________
+void AliHFEextraCuts::SetMinHFEImpactParamR(){
+  SETBIT(fRequirements, kMinHFEImpactParamR);
+}
+
+//__________________________________________________________
+void AliHFEextraCuts::SetMinHFEImpactParamNsigmaR(){
+  SETBIT(fRequirements, kMinHFEImpactParamNsigmaR);
+}
+
+//__________________________________________________________
 void AliHFEextraCuts::SetMinTrackletsTRD(Int_t minTracklets){
   SETBIT(fRequirements, kMinTrackletsTRD);
   fMinTrackletsTRD = minTracklets;
 }
+
+//__________________________________________________________
+void AliHFEextraCuts::SetMinNClustersTPC(Int_t minClusters){
+  SETBIT(fRequirements, kMinNClustersTPC);
+  fMinNClustersTPC = minClusters;
+}
 #endif
index c513037..87858fd 100644 (file)
@@ -165,20 +165,20 @@ void AliHFEmcQA::CreateHistograms(const Int_t kquark, Int_t icut, TString hnopt)
     kqTypeLabel[kElse-4]="elsee";
     kqTypeLabel[kMisID-4]="miside";
   }
-/*
-  const Double_t kPtbound[2] = {0.001, 50.};
+
+  const Double_t kPtbound[2] = {0.1, 20.}; //bin taken for considering inclusive e analysis binning
   Int_t iBin[1];
-  iBin[0] = 100; // bins in pt
+  iBin[0] = 44; // bins in pt
   Double_t* binEdges[1];
   binEdges[0] =  AliHFEtools::MakeLogarithmicBinning(iBin[0], kPtbound[0], kPtbound[1]);
-  */
+  
   
   TString hname; 
   if(kquark == kOthers){
     for (Int_t iqType = 0; iqType < 4; iqType++ ){
        hname = hnopt+"Pt_"+kqTypeLabel[iqType];
-       //fHist[iq][iqType][icut].fPt = new TH1F(hname,hname+";p_{T} (GeV/c)",iBin[0],binEdges[0]);
-       fHist[iq][iqType][icut].fPt = new TH1F(hname,hname+";p_{T} (GeV/c)",500,0,50);
+       fHist[iq][iqType][icut].fPt = new TH1F(hname,hname+";p_{T} (GeV/c)",iBin[0],binEdges[0]);
+       //fHist[iq][iqType][icut].fPt = new TH1F(hname,hname+";p_{T} (GeV/c)",500,0,50);
        hname = hnopt+"Y_"+kqTypeLabel[iqType];
        fHist[iq][iqType][icut].fY = new TH1F(hname,hname,150,-7.5,7.5);
        hname = hnopt+"Eta_"+kqTypeLabel[iqType];
@@ -193,8 +193,8 @@ void AliHFEmcQA::CreateHistograms(const Int_t kquark, Int_t icut, TString hnopt)
      hname = hnopt+"PdgCode_"+kqTypeLabel[iqType];
      fHist[iq][iqType][icut].fPdgCode = new TH1F(hname,hname,20001,-10000.5,10000.5);
      hname = hnopt+"Pt_"+kqTypeLabel[iqType];
-     //fHist[iq][iqType][icut].fPt = new TH1F(hname,hname+";p_{T} (GeV/c)",iBin[0],binEdges[0]);
-     fHist[iq][iqType][icut].fPt = new TH1F(hname,hname+";p_{T} (GeV/c)",500,0,50);
+     fHist[iq][iqType][icut].fPt = new TH1F(hname,hname+";p_{T} (GeV/c)",iBin[0],binEdges[0]);
+     //fHist[iq][iqType][icut].fPt = new TH1F(hname,hname+";p_{T} (GeV/c)",500,0,50);
      hname = hnopt+"Y_"+kqTypeLabel[iqType];
      fHist[iq][iqType][icut].fY = new TH1F(hname,hname,150,-7.5,7.5);
      hname = hnopt+"Eta_"+kqTypeLabel[iqType];
@@ -366,9 +366,12 @@ void AliHFEmcQA::EndOfEventAna(const Int_t kquark)
      ancestorLabel[i] = 0;
   }
 
+
   // check history of found heavy quarks
   for (Int_t i = 0; i < fIsHeavy[iq]; i++){
 
+     if(!fHeavyQuark[i]) return;
+
      ancestorLabel[0] = i;
      ancestorPdg[0] = fHeavyQuark[i]->GetPdgCode(); 
      ancestorLabel[1] = fHeavyQuark[i]->GetFirstMother(); 
@@ -1039,7 +1042,7 @@ Int_t AliHFEmcQA::GetElecSource(TParticle * const mcpart)
 {
   // decay particle's origin 
 
-  if ( abs(mcpart->GetPdgCode()) != AliHFEmcQA::kElectronPDG ) return -1;
+  if ( abs(mcpart->GetPdgCode()) != AliHFEmcQA::kElectronPDG ) return kMisID;
 
   Int_t origin = -1;
   Bool_t isFinalOpenCharm = kFALSE;
index 31257d5..1ff61a9 100644 (file)
 #include <TAxis.h>
 #include <TClass.h>
 #include <TF1.h>
-#include <THnSparse.h>
 #include <TIterator.h>
 #include <TList.h>
 #include <TObjArray.h>
 #include <TObjString.h>
 #include <TString.h>
 
+#include "AliAODpidUtil.h"
 #include "AliESDpid.h"
-#include "AliESDtrack.h"
 #include "AliLog.h"
 #include "AliPID.h"
+#include "AliVParticle.h"
 
+#include "AliHFEcontainer.h"
 #include "AliHFEpid.h"
 #include "AliHFEpidBase.h"
+#include "AliHFEpidQAmanager.h"
 #include "AliHFEpidITS.h"
 #include "AliHFEpidTPC.h"
 #include "AliHFEpidTRD.h"
 #include "AliHFEpidTOF.h"
 #include "AliHFEpidMC.h"
+#include "AliHFEvarManager.h"
 
 ClassImp(AliHFEpid)
 
+const Char_t* AliHFEpid::fgkDetectorName[AliHFEpid::kNdetectorPID + 1] = {
+  "MCPID",
+  "ESDPID",
+  "ITSPID",
+  "TPCPID",
+  "TRDPID",
+  "TOFPID",
+  "UndefinedPID"
+};
+
 //____________________________________________________________
 AliHFEpid::AliHFEpid():
   TNamed(),
   fEnabledDetectors(0),
-  fPIDstrategy(kUndefined),
-  fQAlist(0x0),
-  fDebugLevel(0),
+  fNPIDdetectors(0),
+  fVarManager(NULL),
   fCommonObjects(NULL)
 {
   //
   // Default constructor
   //
   memset(fDetectorPID, 0, sizeof(AliHFEpidBase *) * kNdetectorPID);
+  memset(fDetectorOrder, kUndefined, sizeof(UInt_t) * kNdetectorPID);
+  memset(fDetectorOrder, 0, sizeof(UInt_t) * kNdetectorPID);
 }
 
 //____________________________________________________________
 AliHFEpid::AliHFEpid(const Char_t *name):
   TNamed(name, ""),
   fEnabledDetectors(0),
-  fPIDstrategy(kUndefined),
-  fQAlist(NULL),
-  fDebugLevel(0),
+  fNPIDdetectors(0),
+  fVarManager(NULL),
   fCommonObjects(NULL)
 {
   //
@@ -76,8 +89,11 @@ AliHFEpid::AliHFEpid(const Char_t *name):
   // Create PID objects for all detectors
   //
   memset(fDetectorPID, 0, sizeof(AliHFEpidBase *) * kNdetectorPID);
+  memset(fDetectorOrder, kUndefined, sizeof(UInt_t) * kNdetectorPID);
+  memset(fSortedOrder, 0, sizeof(UInt_t) * kNdetectorPID);
+
   fDetectorPID[kMCpid] = new AliHFEpidMC("MCPID");
-  fDetectorPID[kTPCpid] = new AliHFEpidTPC("TRDPID");
+  fDetectorPID[kTPCpid] = new AliHFEpidTPC("TPCPID");
   fDetectorPID[kTRDpid] = new AliHFEpidTRD("TRDPID");
   fDetectorPID[kTOFpid] = new AliHFEpidTOF("TOFPID");
 
@@ -87,9 +103,8 @@ AliHFEpid::AliHFEpid(const Char_t *name):
 AliHFEpid::AliHFEpid(const AliHFEpid &c):
   TNamed(c),
   fEnabledDetectors(c.fEnabledDetectors),
-  fPIDstrategy(kUndefined),
-  fQAlist(NULL),
-  fDebugLevel(c.fDebugLevel),
+  fNPIDdetectors(c.fNPIDdetectors),
+  fVarManager(c.fVarManager),
   fCommonObjects(NULL)
 {
   //
@@ -115,7 +130,6 @@ AliHFEpid::~AliHFEpid(){
   //
   for(Int_t idet = 0; idet < kNdetectorPID; idet++)
     if(fDetectorPID[idet]) delete fDetectorPID[idet];
-  if(fQAlist) delete fQAlist; fQAlist = NULL;  // Each detector has to care about its Histograms
   ClearCommonObjects();
 }
 
@@ -130,13 +144,8 @@ void AliHFEpid::Copy(TObject &o) const{
   target.ClearCommonObjects();
 
   target.fEnabledDetectors = fEnabledDetectors;
-  target.fPIDstrategy = fPIDstrategy;
-  if(target.fQAlist){
-    delete target.fQAlist; target.fQAlist = NULL;
-  }
-  if(fQAlist) target.fQAlist = new TList;
-  target.fQAlist = 0x0;
-  target.fDebugLevel = fDebugLevel;
+  target.fNPIDdetectors = fNPIDdetectors;
+  target.fVarManager = fVarManager;
  
   // Copy detector PIDs
   for(Int_t idet = 0; idet < kNdetectorPID; idet++){
@@ -146,6 +155,8 @@ void AliHFEpid::Copy(TObject &o) const{
     if(fDetectorPID[idet]) 
       target.fDetectorPID[idet] = dynamic_cast<AliHFEpidBase *>(fDetectorPID[idet]->Clone());
   }
+  memcpy(target.fDetectorOrder, fDetectorOrder, sizeof(UInt_t) * kNdetectorPID);
+  memcpy(target.fSortedOrder, fSortedOrder, sizeof(UInt_t) * kNdetectorPID);
 }
 
 //____________________________________________________________
@@ -170,235 +181,76 @@ void AliHFEpid::ClearCommonObjects(){
 }
 
 //____________________________________________________________
-Bool_t AliHFEpid::InitializePID(TString arg){
+void AliHFEpid::AddDetector(TString detector, UInt_t position){
   //
-  // Initializes PID Object:
-  // + Defines which detectors to use
-  // + Initializes Detector PID objects
-  // + Handles QA
+  // Add Detector in position 
   //
-  
-  Bool_t initFail = kFALSE;
-  if(arg.BeginsWith("Strategy")){
-    // Initialize detector PIDs according to PID Strategies
-    arg.ReplaceAll("Strategy", "");
-    fPIDstrategy = arg.Atoi();
-    AliDebug(1, Form("%s - PID Strategy %d enabled", GetName(), fPIDstrategy));
-    switch(fPIDstrategy){
-      case 0: SwitchOnDetector(kMCpid); break;    // Pure MC PID - only valid in MC mode
-      case 1: InitStrategy1(); break;
-      case 2: InitStrategy2(); break;
-      case 3: InitStrategy3(); break;
-      case 4: InitStrategy4(); break;
-      case 5: InitStrategy5(); break;
-      case 6: InitStrategy6(); break;
-      case 7: InitStrategy7(); break;
-      case 8: InitStrategy8(); break;
-      default: initFail = kFALSE;
-    }
-  } else {
-    // No Strategy defined, Initialize according to detectors specified
-    AliDebug(1, Form("%s - Doing InitializePID for Detectors %s end", GetName(), arg.Data()));
-  
-    TObjArray *detsEnabled = arg.Tokenize(":");
-    TIterator *detIterator = detsEnabled->MakeIterator();
-    TObjString *det = NULL;
-    Int_t detector = -1;
-    TString detectors[kNdetectorPID] = {"MC", "ESD", "ITS", "TPC", "TRD", "TOF"};
-    Int_t nDetectors = 0;
-    while((det = dynamic_cast<TObjString *>(detIterator->Next()))){
-      TString &detstring = det->String();
-      detector = -1;
-      for(Int_t idet = 0; idet < kNdetectorPID; idet++){
-        if(!detstring.CompareTo(detectors[idet])){
-          detector = idet;
-          break;
-        }
-      }
-      if(detector > -1){
-        SwitchOnDetector(detector);
-        nDetectors++;
-      } else AliError(Form("Detector %s not implemented (yet)", detstring.Data()));
-    }
-    if(!nDetectors) initFail = kTRUE;
-  }
-  if(initFail){
-    AliError("Initializaion of the PID Failed");
-    return kFALSE;
-  }
+  UInt_t detectorID = kUndefined;
+  detector.ToUpper();
+  if(!detector.CompareTo("MC")) detectorID = kMCpid;
+  else if(!detector.CompareTo("TPC")) detectorID = kTPCpid;
+  else if(!detector.CompareTo("TRD")) detectorID = kTRDpid;
+  else if(!detector.CompareTo("TOF")) detectorID = kTOFpid;
+  else AliError("Detector not available");
 
+  if(detectorID == kUndefined) return;
+  if(IsDetectorOn(detectorID)) return;
+  SwitchOnDetector(detectorID);
+  fDetectorOrder[detectorID] = position;
+  fNPIDdetectors++;
+}
+
+//____________________________________________________________
+Bool_t AliHFEpid::InitializePID(){
+  //
+  // Initializes the PID object
+  //
+
+  TMath::Sort(static_cast<UInt_t>(kNdetectorPID), fDetectorOrder, fSortedOrder, kFALSE);
   // Initialize PID Objects
   Bool_t status = kTRUE;
   for(Int_t idet = 0; idet < kNdetectorPID; idet++){
     if(!IsDetectorOn(idet)) continue;
     if(fDetectorPID[idet]){ 
       status &= fDetectorPID[idet]->InitializePID();
-      if(IsQAOn() && status) fDetectorPID[idet]->SetQAOn(fQAlist);
       if(HasMCData() && status) fDetectorPID[idet]->SetHasMCData();
     }
   }
   PrintStatus();
   return status;
-  AliDebug(1, Form("%s - Done", GetName()));
 }
 
 //____________________________________________________________
-Bool_t AliHFEpid::IsSelected(AliHFEpidObject *track){
+Bool_t AliHFEpid::IsSelected(AliHFEpidObject *track, AliHFEcontainer *cont, const Char_t *contname, AliHFEpidQAmanager *pidqa){
   //
-  // Steers PID decision for single detectors respectively combined
-  // PID decision
+  // Select Tracks
   //
-  if(!track->fRecTrack){
-    // MC Event
-    return (TMath::Abs(fDetectorPID[kMCpid]->IsSelected(track)) == 11);
-  }
-  if(fPIDstrategy < 9){
-    AliDebug(1, Form("%s - PID Strategy %d", GetName(), fPIDstrategy));
-    Int_t pid = 0;
-    switch(fPIDstrategy){
-      case 0: pid = IdentifyStrategy0(track); break;
-      case 1: pid = IdentifyStrategy1(track); break;
-      case 2: pid = IdentifyStrategy2(track); break;
-      case 3: pid = IdentifyStrategy3(track); break;
-      case 4: pid = IdentifyStrategy4(track); break;
-      case 5: pid = IdentifyStrategy5(track); break;
-      case 6: pid = IdentifyStrategy6(track); break;
-      case 7: pid = IdentifyStrategy7(track); break;
-      case 8: pid = IdentifyStrategy8(track); break;
-      default: break;
+  Bool_t isSelected = kTRUE;
+  AliDebug(1, Form("Particle used for PID, QA available: %s", pidqa ? "Yes" : "No"));
+  for(UInt_t idet = 0; idet < fNPIDdetectors; idet++){
+    AliDebug(2, Form("Using Detector %s\n", SortedDetectorName(idet)));
+    if(TMath::Abs(fDetectorPID[fSortedOrder[idet]]->IsSelected(track, pidqa)) != 11){
+      isSelected = kFALSE;
+      break;
     }
-    return pid;
-  }
-  if(TESTBIT(fEnabledDetectors, kTPCpid)){
-    if(IsQAOn() && fDebugLevel > 1){ 
-      AliInfo("Filling QA plots");
-      MakePlotsItsTpc(track);  // First fill the QA histograms
+    AliDebug(2, "Particlae selected by detector");
+    if(fVarManager && cont){
+      Char_t reccontname[256];
+      sprintf(reccontname, "%sReco", contname);
+      AliDebug(2, Form("Filling container %s", reccontname));
+      if(fVarManager->IsSignalTrack())
+        fVarManager->FillContainerStepname(cont, reccontname, SortedDetectorName(idet));
+      if(HasMCData()){
+        Char_t mccontname[256];
+        sprintf(mccontname, "%sMC", contname);
+        AliDebug(2, Form("MC Information available, Filling container %s", mccontname));
+        if(fVarManager->IsSignalTrack())
+          fVarManager->FillContainerStepname(cont, mccontname, SortedDetectorName(idet), kTRUE);
+      }
+      // The PID will NOT fill the double counting information
     }
-    if(TESTBIT(fEnabledDetectors, kTOFpid)){
-      // case TPC-TOF
-      return MakePidTpcTof(track);
-    } else if(TESTBIT(fEnabledDetectors, kTRDpid)){
-      // case TPC-TRD with low level detector Signals
-      return MakePidTpcTrd(track);
-    } else
-      return (TMath::Abs(fDetectorPID[kTPCpid]->IsSelected(track)) ==11);
-  } else if(TESTBIT(fEnabledDetectors, kTRDpid)){
-    return (TMath::Abs(fDetectorPID[kTRDpid]->IsSelected(track)) ==11);
-  } else if(TESTBIT(fEnabledDetectors, kTOFpid)){
-    return (TMath::Abs(fDetectorPID[kTOFpid]->IsSelected(track)) ==11);
-  }
-  
-  return kFALSE;
-}
-
-//____________________________________________________________
-Bool_t AliHFEpid::MakePidTpcTof(AliHFEpidObject *track){
-  //
-  // Combines TPC and TOF PID decision
-  //
-  if(track->fAnalysisType != AliHFEpidObject::kESDanalysis) return kFALSE;
-
-  AliHFEpidTOF *tofPID = dynamic_cast<AliHFEpidTOF*>(fDetectorPID[kTOFpid]);
-  if(!tofPID){
-    AliWarning("TOF pid object is NULL");
-    return kFALSE;
-  }
-
-  AliHFEpidTPC *tpcPID = dynamic_cast<AliHFEpidTPC*>(fDetectorPID[kTPCpid]);
-  if(!tpcPID){
-    AliWarning("TPC pid object is NULL");
-    return kFALSE;
-  }
-  
-  // Use TOF PID to select particles with a sigma to the electron line > defined in initialize PID
-  if(TMath::Abs(tofPID->IsSelected(track)) != 11) return kFALSE;
-  // request TOF PID information, reject if no TOF information is available or if TOF identified as Proton or Kaon
-  // apply cut only up to certain upper momentum cut
-  /*Int_t pidTOF = tofPID->IsSelected(track);
-  Bool_t isRejected = kFALSE;
-  switch(TMath::Abs(pidTOF)){
-    case 321:   if(track->fRecTrack->P() < 1.5) isRejected = kTRUE; break;
-    case 2212:  if(track->fRecTrack->P() < 3) isRejected = kTRUE; break;
-    case 0:     if(track->fRecTrack->P() < 3) isRejected = kTRUE; break;  // No TOF information available
-    default: break;
-  };
-  if(isRejected) return kFALSE;*/
-
-  // Particle passed TOF, let TPC decide, no line crossings defined anymore
-  // request the tpc PID information
-  return (TMath::Abs(tpcPID->IsSelected(track)) == 11);
-}
-
-//____________________________________________________________
-Bool_t AliHFEpid::MakePidTpcTrd(AliHFEpidObject *track){
-  //
-  // Combination of TPC and TRD PID
-  // Fills Histograms TPC Signal vs. TRD signal for different
-  // momentum slices
-  //
-  if(track->fAnalysisType != AliHFEpidObject::kESDanalysis) return kFALSE; //AOD based detector PID combination not yet implemented
-  AliDebug(1, "Analysis Type OK, do PID");
-  AliESDtrack *esdTrack = dynamic_cast<AliESDtrack *>(track->fRecTrack);
-  AliHFEpidTRD *trdPid = dynamic_cast<AliHFEpidTRD *>(fDetectorPID[kTRDpid]);
-  Int_t pdg = TMath::Abs(fDetectorPID[kMCpid]->IsSelected(track));
-  Int_t pid = -1;
-  switch(pdg){
-    case 11:    pid = AliPID::kElectron; break;
-    case 13:    pid = AliPID::kMuon; break;
-    case 211:   pid = AliPID::kPion; break;
-    case 321:   pid = AliPID::kKaon; break;
-    case 2212:  pid = AliPID::kProton; break;
-    default:    pid = -1;
-  };
-  Double_t content[10];
-  content[0] = pid;
-  content[1] = esdTrack->P();
-  content[2] = esdTrack->GetTPCsignal();
-  content[3] = trdPid->GetTRDSignalV1(esdTrack, pid);
-  if(IsQAOn() && fDebugLevel > 1){
-    content[4] = trdPid->GetTRDSignalV2(esdTrack, pid);
-    AliDebug(1, Form("Momentum: %f, TRD Signal: Method 1[%f], Method 2[%f]", content[1], content[3], content[4]));
-    (dynamic_cast<THnSparseF *>(fQAlist->At(kTRDSignal)))->Fill(content);
-  }
-  if(content[1] > 2){ // perform combined
-    AliDebug(1, "Momentum bigger 2 GeV/c, doing combined PID"); 
-    if(content[2] > 65 && content[3] > 500) return kTRUE;
-    else return kFALSE;
-  }
-  else {
-    AliDebug(1, "Momentum smaller 2GeV/c, doing TPC alone PID");
-    return fDetectorPID[kTPCpid]->IsSelected(track) == 11;
-  }
-}
-
-//____________________________________________________________
-void AliHFEpid::MakePlotsItsTpc(AliHFEpidObject *track){
-  //
-  // Make a plot ITS signal - TPC signal for several momentum bins
-  //
-  if(track->fAnalysisType != AliHFEpidObject::kESDanalysis) return; //AOD based detector PID combination not yet implemented
-  AliESDtrack * esdTrack = dynamic_cast<AliESDtrack *>(track->fRecTrack);
-   // Fill My Histograms for MC PID
-  Int_t pdg = TMath::Abs(fDetectorPID[kMCpid]->IsSelected(track));
-  Int_t pid = -1;
-  switch(pdg){
-    case 11:    pid = AliPID::kElectron; break;
-    case 13:    pid = AliPID::kMuon; break;
-    case 211:   pid = AliPID::kPion; break;
-    case 321:   pid = AliPID::kKaon; break;
-    case 2212:  pid = AliPID::kProton; break;
-    default:    pid = -1;
-  };
-  if(IsQAOn() && fDebugLevel > 0){
-    Double_t content[10];
-    content[0] = pid;
-    content[1] = esdTrack->GetTPCInnerParam() ? esdTrack->GetTPCInnerParam()->P() : esdTrack->P();
-    content[2] = (dynamic_cast<AliHFEpidITS *>(fDetectorPID[kITSpid]))->GetITSSignalV1(track->fRecTrack, pid);
-    content[3] = esdTrack->GetTPCsignal();
-    AliDebug(1, Form("Momentum %f, TPC Signal %f, ITS Signal %f", content[1], content[2], content[3]));
-    (dynamic_cast<THnSparseF *>(fQAlist->At(kITSSignal)))->Fill(content);
   }
+  return isSelected;
 }
 
 //____________________________________________________________
@@ -412,140 +264,69 @@ void AliHFEpid::SetESDpid(AliESDpid *pid){
 }
 
 //____________________________________________________________
-void AliHFEpid::SetQAOn(){
-  //
-  // Switch on QA
-  //
-  SetBit(kIsQAOn, kTRUE);
-  AliInfo("QA switched on");
-  if(fQAlist) return;
-  fQAlist = new TList;
-  fQAlist->SetName("PIDqa");
-  THnSparseF *histo = NULL;
-
-  // Prepare axis for QA histograms
-  const Int_t kMomentumBins = 41;
-  const Double_t kPtMin = 0.1;
-  const Double_t kPtMax = 10.;
-  Double_t momentumBins[kMomentumBins];
-  for(Int_t ibin = 0; ibin < kMomentumBins; ibin++)
-    momentumBins[ibin] = static_cast<Double_t>(TMath::Power(10,TMath::Log10(kPtMin) + (TMath::Log10(kPtMax)-TMath::Log10(kPtMin))/(kMomentumBins-1)*static_cast<Double_t>(ibin)));
-
-  // Add Histogram for combined TPC-TRD PID
-  if(fDebugLevel > 1){
-    AliDebug(1, "Adding histogram for ITS-TPC investigation");
-    const Int_t kDimensionsTRDsig = 5;
-    Int_t kNbinsTRDsig[kDimensionsTRDsig] = {AliPID::kSPECIES + 1, kMomentumBins - 1, 200, 3000, 3000};
-    Double_t binMinTRDsig[kDimensionsTRDsig] = {-1., 0.1, 0, 0, 0};
-    Double_t binMaxTRDsig[kDimensionsTRDsig] = {AliPID::kSPECIES, 10., 200., 3000., 3000.};
-    fQAlist->AddAt((histo = new THnSparseF("fCombTPCTRDpid", "Combined TPC-TRD PID", kDimensionsTRDsig, kNbinsTRDsig, binMinTRDsig, binMaxTRDsig)), kTRDSignal);
-    histo->GetAxis(1)->Set(kMomentumBins - 1, momentumBins);
-    histo->GetAxis(0)->SetTitle("Particle Species");
-    histo->GetAxis(1)->SetTitle("p / GeV/c");
-    histo->GetAxis(2)->SetTitle("TPC Signal / a.u.");
-    histo->GetAxis(3)->SetTitle("TRD Signal / a.u.");
-    histo->GetAxis(4)->SetTitle("TRD Signal / a.u.");
-  }
-
-  // Add Histogram for combined TPC-ITS PID
-  if(fDebugLevel > 0){
-    AliDebug(1, "Adding histogram for TPC-TRD investigation");
-    const Int_t kDimensionsITSsig = 4;
-    Int_t kNbinsITSsig[kDimensionsITSsig] = {AliPID::kSPECIES + 1, kMomentumBins - 1, 300, 3000};
-    Double_t binMinITSsig[kDimensionsITSsig] = {-1., 0.1, 0., 0.};
-    Double_t binMaxITSsig[kDimensionsITSsig] = {AliPID::kSPECIES, 10., 300., 300.};
-    fQAlist->AddAt((histo = new THnSparseF("fCombTPCITSpid", "Combined TPC-ITS PID", kDimensionsITSsig, kNbinsITSsig, binMinITSsig, binMaxITSsig)), kITSSignal);
-    histo->GetAxis(1)->Set(kMomentumBins - 1, momentumBins);
-    histo->GetAxis(0)->SetTitle("Particle Species");
-    histo->GetAxis(1)->SetTitle("p / GeV/c");
-    histo->GetAxis(2)->SetTitle("ITS Signal / a.u.");
-    histo->GetAxis(3)->SetTitle("TPC Signal / a.u.");
-  }
-}
-
-//____________________________________________________________
-void AliHFEpid::InitStrategy1(){
+void AliHFEpid::SetAODpid(AliAODpidUtil *pid){
   //
-  // TPC alone, 3-sigma cut
+  // Set ESD PID to the Detector PID objects
   //
-  AliHFEpidTPC *pid = dynamic_cast<AliHFEpidTPC *>(fDetectorPID[kTPCpid]);
-  pid->SetTPCnSigma(1);
-  SwitchOnDetector(kTPCpid);
+  for(Int_t idet = 0; idet < kNdetectorPID; idet++){
+    if(fDetectorPID[idet]) fDetectorPID[idet]->SetAODpid(pid);
+  }
 }
 
 //____________________________________________________________
-void AliHFEpid::InitStrategy2(){
+void AliHFEpid::ConfigureTPCasymmetric(Double_t pmin, Double_t pmax, Double_t sigmamin, Double_t sigmamax){
   //
   // TPC alone, symmetric 3 sigma cut and asymmetric sigma cut in the momentum region between 2GeV/c and 10 GeV/c and sigma between -1 and 100
   //
   AliHFEpidTPC *pid = dynamic_cast<AliHFEpidTPC *>(fDetectorPID[kTPCpid]);
   pid->SetTPCnSigma(3);
-  pid->SetAsymmetricTPCsigmaCut(2., 10., 0., 4.);
-  SwitchOnDetector(kTPCpid);
+  pid->SetAsymmetricTPCsigmaCut(pmin, pmax, sigmamin, sigmamax);
 }
 
 //____________________________________________________________
-void AliHFEpid::InitStrategy3(){
+void AliHFEpid::ConfigureTPCrejectionSimple(){
   //
   // TPC alone, symmetric 3 sigma cut and 2 - -100 sigma pion rejection
   //   
   AliHFEpidTPC *pid = dynamic_cast<AliHFEpidTPC *>(fDetectorPID[kTPCpid]);
   pid->SetTPCnSigma(3);
   pid->SetRejectParticle(AliPID::kPion, 0., -100., 10., 1.);
-  SwitchOnDetector(kTPCpid);
 }
 
 //____________________________________________________________
-void AliHFEpid::InitStrategy4(){
-  //
-  // TPC and TRD combined, TPC 3 sigma cut and TRD NN 90% el efficiency level above 2 GeV/c
-  //
-  InitStrategy1();
-  AliHFEpidTRD *trdpid = dynamic_cast<AliHFEpidTRD *>(fDetectorPID[kTRDpid]);
-  trdpid->SetPIDMethod(AliHFEpidTRD::kLQ);
-  trdpid->SetElectronEfficiency(0.71);
-  SwitchOnDetector(kTRDpid);
-}
-
-//____________________________________________________________
-void AliHFEpid::InitStrategy5(){
-  //
-  // TPC and TRD combined, TPC 3 sigma cut and TRD NN 90% el efficiency level above 2 GeV/c
-  //
-  InitStrategy1();
-  SwitchOnDetector(kTRDpid);
-}
-
-//____________________________________________________________
-void AliHFEpid::InitStrategy6(){
+void AliHFEpid::ConfigureTPCrejection(){
   //
   // Combined TPC-TOF PID, combination is discribed in the funtion MakePidTpcTof
   //
+  if(HasMCData()) printf("Configuring TPC for MC\n");
   AliHFEpidTPC *tpcpid = dynamic_cast<AliHFEpidTPC *>(fDetectorPID[kTPCpid]);
   AliHFEpidTOF *tofpid = dynamic_cast<AliHFEpidTOF *>(fDetectorPID[kTOFpid]);
   tpcpid->SetTPCnSigma(2);
   tofpid->SetTOFnSigma(3);
+
   //TF1 *upperCut = new TF1("upperCut", "[0] * TMath::Exp([1]*x)", 0, 20);
   TF1 *upperCut = new TF1("upperCut", "[0]", 0, 20); // Use constant upper cut
   TF1 *lowerCut = new TF1("lowerCut", "[0] * TMath::Exp([1]*x) + [2]", 0, 20);
-  upperCut->SetParameter(0, 5.);
+  upperCut->SetParameter(0, 3.);
   //upperCut->SetParameter(0, 2.7);
   //upperCut->SetParameter(1, -0.4357);
-  lowerCut->SetParameter(0, -2.65);
-  lowerCut->SetParameter(1, -0.8757);
-//  lowerCut->SetParameter(2, -1);
-  if(HasMCData()) lowerCut->SetParameter(2, -0.997);
-  else lowerCut->SetParameter(2, -0.9);
+
+  if(HasMCData()) lowerCut->SetParameter(0, -2.5);
+  else lowerCut->SetParameter(0, -3.7);
+
+  lowerCut->SetParameter(1, -0.8);
+
+  if(HasMCData()) lowerCut->SetParameter(2, -2.2);
+  else lowerCut->SetParameter(2, -0.35);
+
   tpcpid->SetUpperSigmaCut(upperCut);
   tpcpid->SetLowerSigmaCut(lowerCut);
   AddCommonObject(upperCut);
   AddCommonObject(lowerCut);
-  SwitchOnDetector(kTPCpid);
-  SwitchOnDetector(kTOFpid);
 }
 
 //____________________________________________________________
-void AliHFEpid::InitStrategy7(){
+void AliHFEpid::ConfigureTPCstrategyParis(){
   //
   // TPC alone, symmetric 3 sigma cut and 2 - -100 sigma pion rejection
   //   
@@ -553,83 +334,6 @@ void AliHFEpid::InitStrategy7(){
   pid->SetTPCnSigma(2);
   pid->SetRejectParticle(AliPID::kProton, 0., -3., 10., 3.);
   pid->SetRejectParticle(AliPID::kKaon, 0., -3., 10., 3.);
-  SwitchOnDetector(kTPCpid);
-}
-
-//____________________________________________________________
-void AliHFEpid::InitStrategy8(){
-  //
-  // TOF, TRD and TPC together
-  // 
-  AliHFEpidTPC *tpcpid = dynamic_cast<AliHFEpidTPC *>(fDetectorPID[kTPCpid]);
-  AliHFEpidTOF *tofpid = dynamic_cast<AliHFEpidTOF *>(fDetectorPID[kTOFpid]);
-  AliHFEpidTRD *trdpid = dynamic_cast<AliHFEpidTRD *>(fDetectorPID[kTRDpid]);
-
-  tpcpid->SetTPCnSigma(3);
-  tofpid->SetTOFnSigma(3);
-  trdpid->SetPIDMethod(AliHFEpidTRD::kLQ);
-  trdpid->SetElectronEfficiency(0.71);
-  SwitchOnDetector(kTPCpid);
-  SwitchOnDetector(kTOFpid);
-  SwitchOnDetector(kTRDpid);
-}
-
-
-//____________________________________________________________
-Bool_t AliHFEpid::IdentifyStrategy0(AliHFEpidObject *track){
-  return TMath::Abs(fDetectorPID[kMCpid]->IsSelected(track)) == 11;
-}
-
-//____________________________________________________________
-Bool_t AliHFEpid::IdentifyStrategy1(AliHFEpidObject *track){
-  return TMath::Abs(fDetectorPID[kTPCpid]->IsSelected(track)) == 11;
-}
-
-//____________________________________________________________
-Bool_t AliHFEpid::IdentifyStrategy2(AliHFEpidObject *track){
-  return TMath::Abs(fDetectorPID[kTPCpid]->IsSelected(track)) == 11;
-}
-
-//____________________________________________________________
-Bool_t AliHFEpid::IdentifyStrategy3(AliHFEpidObject *track){
-  return TMath::Abs(fDetectorPID[kTPCpid]->IsSelected(track)) == 11;
-}
-
-//____________________________________________________________
-Bool_t AliHFEpid::IdentifyStrategy4(AliHFEpidObject *track){
-  Int_t trdpid = TMath::Abs(fDetectorPID[kTRDpid]->IsSelected(track));
-  return (trdpid == 0 || trdpid == 11) && (TMath::Abs(fDetectorPID[kTPCpid]->IsSelected(track)) == 11);
-}
-
-//____________________________________________________________
-Bool_t AliHFEpid::IdentifyStrategy5(AliHFEpidObject *track){
-  return MakePidTpcTrd(track);
-}
-
-//____________________________________________________________
-Bool_t AliHFEpid::IdentifyStrategy6(AliHFEpidObject *track){
-  return MakePidTpcTof(track);
-}
-
-//____________________________________________________________
-Bool_t AliHFEpid::IdentifyStrategy7(AliHFEpidObject *track){
-  //
-  // Do PID in strategy 7: Proton and Kaon rejection and 
-  // lower cut on TPC Signal
-  //
-  if(!(TMath::Abs(fDetectorPID[kTPCpid]->IsSelected(track)) == 11))
-    return kFALSE;
-  return kTRUE;
-}
-
-//____________________________________________________________
-Bool_t AliHFEpid::IdentifyStrategy8(AliHFEpidObject *track){
-  // 
-  // Identify TPC, TRD, TOF
-  //
-  if(TMath::Abs(fDetectorPID[kTOFpid]->IsSelected(track)) != 11) return kFALSE;
-  Int_t trdpid = TMath::Abs(fDetectorPID[kTRDpid]->IsSelected(track));
-  return (trdpid == 0 || trdpid == 11) && (TMath::Abs(fDetectorPID[kTPCpid]->IsSelected(track)) == 11);
 }
 
 //____________________________________________________________
@@ -639,7 +343,6 @@ void AliHFEpid::PrintStatus() const {
   //
   printf("\n%s: Printing configuration\n", GetName());
   printf("===============================================\n");
-  printf("PID Strategy: %d\n", fPIDstrategy);
   printf("PID Detectors: \n");
   Int_t npid = 0;
   TString detectors[kNdetectorPID] = {"MC", "ESD", "ITS", "TPC", "TRD", "TOF"};
index 6dd0d8c..ea568cd 100644 (file)
 
 #include <climits>
 
+class AliAODpidUtil;
 class AliESDpid;
-class AliESDtrack;
+class AliHFEcontainer;
 class AliHFEpidBase;
+class AliHFEpidQAmanager;
+class AliHFEvarManager;
 class AliVParticle;
 class AliMCParticle;
 
@@ -43,7 +46,7 @@ class AliHFEpid : public TNamed{
     enum{
       kUndefined = UINT_MAX 
     };
-    enum DETtype_t {
+    enum EDETtype_t {
       kMCpid = 0,
       kESDpid = 1,
       kITSpid = 2,
@@ -59,46 +62,39 @@ class AliHFEpid : public TNamed{
     void Copy(TObject &o) const;
     ~AliHFEpid();
     
-    Bool_t InitializePID(TString argument);
-    Bool_t IsSelected(AliHFEpidObject *track);
+    Bool_t InitializePID();
+    Bool_t IsSelected(AliHFEpidObject *track, AliHFEcontainer *cont = NULL, const Char_t *contname = "trackContainer", AliHFEpidQAmanager *qa = NULL);
 
-    Bool_t IsQAOn() const { return TestBit(kIsQAOn); };
     Bool_t HasMCData() const { return TestBit(kHasMCData); };
+
+    void AddDetector(TString detector, UInt_t position);
     void SetESDpid(AliESDpid *pid);
-    void SetDebugLevel(Int_t debugLevel) { fDebugLevel = debugLevel; }
-    void SetQAOn();
+    void SetAODpid(AliAODpidUtil *pid);
+    void SetVarManager(AliHFEvarManager *vm) { fVarManager = vm; }
     void SetHasMCData(Bool_t hasMCdata = kTRUE) { SetBit(kHasMCData, hasMCdata); };
-    TList *GetQAhistograms() const { return fQAlist; };
-    AliHFEpidBase *GetDetPID(DETtype_t det) const { return det < kNdetectorPID ? fDetectorPID[det] : NULL; }
+
+    UInt_t GetNumberOfPIDdetectors() const { return fNPIDdetectors; }
+    Bool_t HasDetector(EDETtype_t det) const { return IsDetectorOn(det); }
+    AliHFEpidBase *GetDetPID(EDETtype_t det) const { return det < kNdetectorPID ? fDetectorPID[det] : NULL; }
+
     void PrintStatus() const;
+    const Char_t *SortedDetectorName(Int_t det) const {
+      if(det < kNdetectorPID) return fgkDetectorName[fSortedOrder[det]]; 
+      else return fgkDetectorName[kNdetectorPID + 1];
+    }    
+    //-----Configure PID detectors with predefined stettings------
+    void ConfigureTPCasymmetric(Double_t pmin = 0.1, Double_t pmax = 20., Double_t sigmamin = -0.2, Double_t sigmamax = 5.);
+    void ConfigureTPCrejectionSimple();
+    void ConfigureTPCrejection();
+    void ConfigureTPCstrategyParis();
+    //------------------------------------------------------------
 
   protected:
     Bool_t MakePidTpcTof(AliHFEpidObject *track);
-    Bool_t MakePidTpcTrd(AliHFEpidObject *track);
-    void MakePlotsItsTpc(AliHFEpidObject *track);
-
-    // Stratgies
-    void InitStrategy1();
-    void InitStrategy2();
-    void InitStrategy3();
-    void InitStrategy4();
-    void InitStrategy5();
-    void InitStrategy6();
-    void InitStrategy7();
-    void InitStrategy8();
-    Bool_t IdentifyStrategy0(AliHFEpidObject *track);
-    Bool_t IdentifyStrategy1(AliHFEpidObject *track);
-    Bool_t IdentifyStrategy2(AliHFEpidObject *track);
-    Bool_t IdentifyStrategy3(AliHFEpidObject *track);
-    Bool_t IdentifyStrategy4(AliHFEpidObject *track);
-    Bool_t IdentifyStrategy5(AliHFEpidObject *track);
-    Bool_t IdentifyStrategy6(AliHFEpidObject *track);
-    Bool_t IdentifyStrategy7(AliHFEpidObject *track);
-    Bool_t IdentifyStrategy8(AliHFEpidObject *track);
+
   private:
     enum{
-      kIsQAOn = BIT(14),
-      kHasMCData = BIT(15)
+      kHasMCData = BIT(14)
     };
     enum{
       kCombinedTPCTRD=0
@@ -122,12 +118,14 @@ class AliHFEpid : public TNamed{
     }
     //--------------------------------------------------
 
-    AliHFEpidBase *fDetectorPID[kNdetectorPID];     //! Detector PID classes
-    UInt_t fEnabledDetectors;                       //  Enabled Detectors
-    UInt_t fPIDstrategy;                            //  PID Strategy
-    TList *fQAlist;                                 //! QA histograms
-    Int_t fDebugLevel;                              //  Debug Level
-    TObjArray *fCommonObjects;                       // Garbage Collector
+    static const Char_t *fgkDetectorName[kNdetectorPID + 1]; // PID Detector Names
+    AliHFEpidBase *fDetectorPID[kNdetectorPID];     //   Detector PID classes
+    UInt_t fDetectorOrder[kNdetectorPID];           //   Position requested by the user
+    UInt_t fSortedOrder[kNdetectorPID];             //   Sorted array of detectorIDs
+    UInt_t fEnabledDetectors;                       //   Enabled Detectors
+    UInt_t fNPIDdetectors;                          //   Number of PID detectors
+    AliHFEvarManager *fVarManager;                  //!  HFE Var Manager
+    TObjArray *fCommonObjects;                      //   Garbage Collector
 
   ClassDef(AliHFEpid, 1)      // Steering class for Electron ID
 };
index 2da8eb5..6ba2e4b 100644 (file)
 // Authors: 
 //   Markus Fasel <M.Fasel@gsi.de> 
 // 
+
+#include "AliAODpidUtil.h"
 #include "AliESDpid.h"
 #include "AliHFEpidBase.h"
+#include "AliHFEtools.h"
 
 ClassImp(AliHFEpidBase)
 
@@ -29,7 +32,7 @@ ClassImp(AliHFEpidBase)
 AliHFEpidBase::AliHFEpidBase():
   TNamed(),
   fESDpid(NULL),
-  fDebugLevel(0)
+  fAODpid(NULL)
 {
   //
   // Default constructor
@@ -40,7 +43,7 @@ AliHFEpidBase::AliHFEpidBase():
 AliHFEpidBase::AliHFEpidBase(const Char_t *name):
   TNamed(name, ""),
   fESDpid(NULL),
-  fDebugLevel(0)
+  fAODpid(NULL)
 {
   //
   // Default constructor
@@ -51,7 +54,7 @@ AliHFEpidBase::AliHFEpidBase(const Char_t *name):
 AliHFEpidBase::AliHFEpidBase(const AliHFEpidBase &c):
   TNamed(),
   fESDpid(NULL),
-  fDebugLevel(0)
+  fAODpid(NULL)
 {
   //
   //Copy constructor
@@ -79,8 +82,30 @@ void AliHFEpidBase::Copy(TObject &ref) const {
   AliHFEpidBase &target = dynamic_cast<AliHFEpidBase &>(ref);
 
   target.fESDpid = fESDpid;
-  target.fDebugLevel = fDebugLevel;
+  target.fAODpid = fAODpid;
 
   TNamed::Copy(ref);
 }
 
+//___________________________________________________________________
+AliHFEpidObject &AliHFEpidObject::operator=(const AliHFEpidObject &ref){
+  //
+  // Assignment operator
+  //
+  if(&ref != this){
+    fkRecTrack = ref.fkRecTrack;
+    fAnalysisType = ref.fAnalysisType;
+    fAbInitioPID = ref.fAbInitioPID;
+    fCentrality = ref.fCentrality;
+  }
+  return *this;
+}
+
+//___________________________________________________________________
+void AliHFEpidObject::SetMCTrack(const AliVParticle *mctrack){
+  //
+  // Set the aprioriPID information coming from the MC truth
+  //
+  if(mctrack) fAbInitioPID = AliHFEtools::PDG2AliPID(AliHFEtools::GetPdg(mctrack));
+}
+