]> git.uio.no Git - u/mrichter/AliRoot.git/commitdiff
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 2e9c2ddd3274c33a9ab0c2f48b959c14afae894e..3fee448648ea61e5c6de843364bbdd583f8f28a7 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 6ea0a9b92d0cad48bcbf7c2994e20da360ae7d33..f302ebf374d63eed797e4b02845583463fc09288 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 ab885fb3d108025981a11c8ec2170d0fdee26f0d..508485043a6e170c6dd8728bbcce264949016443 100644 (file)
 #include <TChain.h>
 #include <TDirectory.h>
 #include <TFile.h>
-#include <TH1D.h>
-#include <TH1F.h>
-#include <TH1I.h>
-#include <TH2F.h>
 #include <TH3D.h>
 #include <TIterator.h>
 #include <TList.h>
@@ -54,6 +50,7 @@
 #include "AliESDInputHandler.h"
 #include "AliESDpid.h"
 #include "AliESDtrack.h"
+#include "AliESDCentrality.h"
 #include "AliLog.h"
 #include "AliAnalysisManager.h"
 #include "AliMCEvent.h"
 #include "AliTriggerAnalysis.h"
 #include "AliVVertex.h"
 
-#include "AliHFEpid.h"
 #include "AliHFEcollection.h"
+#include "AliHFEcontainer.h"
 #include "AliHFEcuts.h"
+#include "AliHFEelecbackground.h"
 #include "AliHFEmcQA.h"
 #include "AliHFEpairs.h"
+#include "AliHFEpid.h"
+#include "AliHFEpidQAmanager.h"
 #include "AliHFEpostAnalysis.h"
 #include "AliHFEsecVtxs.h"
 #include "AliHFEsecVtx.h"
-#include "AliHFEelecbackground.h"
+#include "AliHFEsignalCuts.h"
+#include "AliHFEtaggedTrackAnalysis.h"
 #include "AliHFEtools.h"
+#include "AliHFEvarManager.h"
 #include "AliAnalysisTaskHFE.h"
 
 ClassImp(AliAnalysisTaskHFE)
@@ -82,31 +84,29 @@ ClassImp(AliAnalysisTaskHFE)
 AliAnalysisTaskHFE::AliAnalysisTaskHFE():
   AliAnalysisTaskSE("PID efficiency Analysis")
   , fQAlevel(0)
-  , fPIDdetectors("")
-  , fPIDstrategy(0)
   , fPlugins(0)
-  , fWeighting(kFALSE)
-  , fWeightFactors(NULL)
-  , fWeightFactorsFunction(NULL)
+  , fFillSignalOnly(kTRUE)
+  , fRemovePileUp(kFALSE)
+  , fIdentifiedAsPileUp(kFALSE)
+  , fIdentifiedAsOutInz(kFALSE)
+  , fPassTheEventCut(kFALSE)
+  , fCentralityF(99.0)
   , fBackGroundFactorsFunction(NULL)
+  , fContainer(NULL)
+  , fVarManager(NULL)
+  , fSignalCuts(NULL)
   , fCFM(NULL)
-  , fV0CF(NULL)
   , fTriggerAnalysis(NULL)
-  , fHadronicBackground(NULL)
-  , fCorrelation(NULL)
-  , fPIDperformance(NULL)
-  , fSignalToBackgroundMC(NULL)
   , fPID(NULL)
-  , fPIDtagged(NULL)
+  , fPIDqa(NULL)
   , fPIDpreselect(NULL)
   , fCuts(NULL)
-  , fCutsTagged(NULL)
+  , fTaggedTrackCuts(NULL)
   , fCutspreselect(NULL)
   , fSecVtx(NULL)
   , fElecBackGround(NULL)
   , fMCQA(NULL)
-  , fNEvents(NULL)
-  , fNElectronTracksEvent(NULL)
+  , fTaggedTrackAnalysis(NULL)
   , fQA(NULL)
   , fOutput(NULL)
   , fHistMCQA(NULL)
@@ -123,31 +123,29 @@ AliAnalysisTaskHFE::AliAnalysisTaskHFE():
 AliAnalysisTaskHFE::AliAnalysisTaskHFE(const char * name):
   AliAnalysisTaskSE(name)
   , fQAlevel(0)
-  , fPIDdetectors("")
-  , fPIDstrategy(0)
   , fPlugins(0)
-  , fWeighting(kFALSE)
-  , fWeightFactors(NULL)
-  , fWeightFactorsFunction(NULL)
+  , fFillSignalOnly(kTRUE)
+  , fRemovePileUp(kFALSE)
+  , fIdentifiedAsPileUp(kFALSE)
+  , fIdentifiedAsOutInz(kFALSE)
+  , fPassTheEventCut(kFALSE)  
+  , fCentralityF(99.0)
   , fBackGroundFactorsFunction(NULL)
+  , fContainer(NULL)
+  , fVarManager(NULL)
+  , fSignalCuts(NULL)
   , fCFM(NULL)
-  , fV0CF(NULL)
   , fTriggerAnalysis(NULL)
-  , fHadronicBackground(NULL)
-  , fCorrelation(NULL)
-  , fPIDperformance(NULL)
-  , fSignalToBackgroundMC(NULL)
   , fPID(NULL)
-  , fPIDtagged(NULL)
+  , fPIDqa(NULL)
   , fPIDpreselect(NULL)
   , fCuts(NULL)
-  , fCutsTagged(NULL)
+  , fTaggedTrackCuts(NULL)
   , fCutspreselect(NULL)
   , fSecVtx(NULL)
   , fElecBackGround(NULL)
   , fMCQA(NULL)
-  , fNEvents(NULL)
-  , fNElectronTracksEvent(NULL)
+  , fTaggedTrackAnalysis(NULL)
   , fQA(NULL)
   , fOutput(NULL)
   , fHistMCQA(NULL)
@@ -158,42 +156,40 @@ AliAnalysisTaskHFE::AliAnalysisTaskHFE(const char * name):
   //
   // Default constructor
   // 
-  DefineOutput(1, TH1I::Class());
+  DefineOutput(1, TList::Class());
   DefineOutput(2, TList::Class());
-  DefineOutput(3, TList::Class());
 
-  // Initialize cuts
+  fPID = new AliHFEpid("hfePid");
+  fVarManager = new AliHFEvarManager("hfeVarManager");
 }
 
 //____________________________________________________________
 AliAnalysisTaskHFE::AliAnalysisTaskHFE(const AliAnalysisTaskHFE &ref):
   AliAnalysisTaskSE(ref)
   , fQAlevel(0)
-  , fPIDdetectors()
-  , fPIDstrategy(0)
   , fPlugins(0)
-  , fWeighting(kFALSE)
-  , fWeightFactors(NULL)
-  , fWeightFactorsFunction(NULL)
+  , fFillSignalOnly(ref.fFillSignalOnly)
+  , fRemovePileUp(ref.fRemovePileUp)
+  , fIdentifiedAsPileUp(ref.fIdentifiedAsPileUp)
+  , fIdentifiedAsOutInz(ref.fIdentifiedAsOutInz)
+  , fPassTheEventCut(ref.fPassTheEventCut)
+  , fCentralityF(ref.fCentralityF)
   , fBackGroundFactorsFunction(NULL)
+  , fContainer(NULL)
+  , fVarManager(NULL)
+  , fSignalCuts(NULL)
   , fCFM(NULL)
-  , fV0CF(NULL)
   , fTriggerAnalysis(NULL)
-  , fHadronicBackground(NULL)
-  , fCorrelation(NULL)
-  , fPIDperformance(NULL)
-  , fSignalToBackgroundMC(NULL)
   , fPID(NULL)
-  , fPIDtagged(NULL)
+  , fPIDqa(NULL)
   , fPIDpreselect(NULL)
   , fCuts(NULL)
-  , fCutsTagged(NULL)
+  , fTaggedTrackCuts(NULL)
   , fCutspreselect(NULL)
   , fSecVtx(NULL)
   , fElecBackGround(NULL)
   , fMCQA(NULL)
-  , fNEvents(NULL)
-  , fNElectronTracksEvent(NULL)
+  , fTaggedTrackAnalysis(NULL)
   , fQA(NULL)
   , fOutput(NULL)
   , fHistMCQA(NULL)
@@ -224,30 +220,29 @@ void AliAnalysisTaskHFE::Copy(TObject &o) const {
   //
   AliAnalysisTaskHFE &target = dynamic_cast<AliAnalysisTaskHFE &>(o);
   target.fQAlevel = fQAlevel;
-  target.fPIDdetectors = fPIDdetectors;
-  target.fPIDstrategy = fPIDstrategy;
   target.fPlugins = fPlugins;
-  target.fWeighting = fWeighting;
-  target.fWeightFactors = fWeightFactors;
-  target.fWeightFactorsFunction = fWeightFactorsFunction;
+  target.fFillSignalOnly = fFillSignalOnly;
+  target.fRemovePileUp = fRemovePileUp;
+  target.fIdentifiedAsPileUp = fIdentifiedAsPileUp;
+  target.fIdentifiedAsOutInz = fIdentifiedAsOutInz;
+  target.fPassTheEventCut = fPassTheEventCut;
+  target.fCentralityF = fCentralityF;
   target.fBackGroundFactorsFunction = fBackGroundFactorsFunction;
+  target.fContainer = fContainer;
+  target.fVarManager = fVarManager;
+  target.fSignalCuts = fSignalCuts;
   target.fCFM = fCFM;
-  target.fV0CF = fV0CF;
   target.fTriggerAnalysis = fTriggerAnalysis;
-  target.fHadronicBackground = fHadronicBackground;
-  target.fCorrelation = fCorrelation;
-  target.fPIDperformance = fPIDperformance;
-  target.fSignalToBackgroundMC = fSignalToBackgroundMC;
   target.fPID = fPID;
-  target.fPIDtagged = fPIDtagged;
+  target.fPIDqa = fPIDqa;
   target.fPIDpreselect = fPIDpreselect;
   target.fCuts = fCuts;
+  target.fTaggedTrackCuts = fTaggedTrackCuts;
   target.fCutspreselect = fCutspreselect;
   target.fSecVtx = fSecVtx;
   target.fElecBackGround = fElecBackGround;
   target.fMCQA = fMCQA;
-  target.fNEvents = fNEvents;
-  target.fNElectronTracksEvent = fNElectronTracksEvent;
+  target.fTaggedTrackAnalysis = fTaggedTrackAnalysis;
   target.fQA = fQA;
   target.fOutput = fOutput;
   target.fHistMCQA = fHistMCQA;
@@ -261,44 +256,18 @@ AliAnalysisTaskHFE::~AliAnalysisTaskHFE(){
   //
   // Destructor
   //
-  return;
   if(fPID) delete fPID;
-  if(fPIDtagged) delete fPIDtagged;
-  if(fQA){
-    fQA->Clear();
-    delete fQA;
-  }
-  if(fOutput){ 
-    fOutput->Clear();
-    delete fOutput;
-  }
-  if(fWeightFactors) delete fWeightFactors;
-  if(fWeightFactorsFunction) delete fWeightFactorsFunction;
-  if(fBackGroundFactorsFunction) delete fBackGroundFactorsFunction;
-  if(fHistMCQA){
-    fHistMCQA->Clear();
-    delete fHistMCQA;
-  }
-  if(fHistSECVTX){
-    fHistSECVTX->Clear();
-    delete fHistSECVTX;
-  }
-  if(fHistELECBACKGROUND){
-    fHistELECBACKGROUND->Clear();
-    delete fHistELECBACKGROUND;
-  }
+  if(fVarManager) delete fVarManager;
+  if(fPIDqa) delete fPIDqa;
+  if(fSignalCuts) delete fSignalCuts;
+  if(fCFM) delete fCFM;
   if(fSecVtx) delete fSecVtx;
-  if(fElecBackGround) delete fElecBackGround;
   if(fMCQA) delete fMCQA;
-  if(fNEvents) delete fNEvents;
-  if(fCorrelation){
-    fCorrelation->Clear();
-    delete fCorrelation;
-  }
-  if(fPIDperformance) delete fPIDperformance;
-  if(fSignalToBackgroundMC) delete fSignalToBackgroundMC;
-//  if(fQAcoll) delete fQAcoll;
-
+  if(fElecBackGround) delete fElecBackGround;
+  if(fTriggerAnalysis) delete fTriggerAnalysis;
+  if(fPIDpreselect) delete fPIDpreselect;
+  if(fQA) delete fQA;
+  if(fOutput) delete fOutput;
 }
 
 //____________________________________________________________
@@ -313,7 +282,6 @@ void AliAnalysisTaskHFE::UserCreateOutputObjects(){
   // QA histograms are created if requested
   // Called once per worker
   //
-  fPID = new AliHFEpid("standardPID"); fPIDtagged = new AliHFEpid("taggedPID");
   AliDebug(3, "Creating Output Objects");
   // Automatic determination of the analysis mode
   AliVEventHandler *inputHandler = dynamic_cast<AliVEventHandler *>(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler());
@@ -327,23 +295,21 @@ void AliAnalysisTaskHFE::UserCreateOutputObjects(){
   printf("Analysis Mode: %s Analysis\n", IsAODanalysis() ? "AOD" : "ESD");
   printf("MC Data available %s\n", HasMCData() ? "Yes" : "No");
 
-  // example how to use the AliHFEcollection
-  //fQAcoll = new AliHFEcollection("fQAcoll", "QA");
-  //fQAcoll->CreateTH1F("fNevents", "Number of Events in the Analysis", 2, 0, 2);
-  //fQAcoll->CreateProfile("fNtrdclusters", "Number of TRD clusters as function of momentum; p[GeV/c]", 20, 0, 20);
-
   // Enable Trigger Analysis
   fTriggerAnalysis = new AliTriggerAnalysis;
   fTriggerAnalysis->EnableHistograms();
   fTriggerAnalysis->SetAnalyzeMC(HasMCData());
 
-  // Make QA histograms
-  fNEvents = new TH1I("nEvents", "Number of Events in the Analysis", 2, 0, 2); // Number of Events neccessary for the analysis and not a QA histogram
-  fNElectronTracksEvent = new TH1I("nElectronTracksEvent", "Number of Electron Candidates", 100, 0, 100);
-  // First Step: TRD alone
+
+  // Make lists for Output
   if(!fQA) fQA = new TList;
+  fQA->SetOwner();
+  if(!fOutput) fOutput = new TList;
+  fOutput->SetOwner();
 
+  // First Part: Make QA histograms
   fQACollection = new AliHFEcollection("TaskQA", "QA histos from the Electron Task");
+  fQACollection->CreateTH1F("nElectronTracksEvent", "Number of Electron Candidates", 100, 0, 100);
   fQACollection->CreateProfile("conr", "Electron PID contamination", 20, 0, 20);
   fQACollection->CreateTH1F("alpha_rec", "Alpha from reconstructed tracks with TRD hits", 36, -TMath::Pi(), TMath::Pi());
   fQACollection->CreateTH1F("alpha_sim", "Alpha from simulated electron tracks", 36, -TMath::Pi(), TMath::Pi());
@@ -353,18 +319,28 @@ void AliAnalysisTaskHFE::UserCreateOutputObjects(){
   fQACollection->CreateTH1F("chi2TRD","#chi2 per TRD cluster", 20, 0, 20);
   fQACollection->CreateTH1F("mccharge", "MC Charge", 200, -100, 100);
   fQACollection->CreateTH2F("radius", "Production Vertex", 100, 0.0, 5.0, 100, 0.0, 5.0);
-  fQACollection->CreateTH1F("secvtxept", "pT of tagged e", 500, 0, 50); // mj: will move to another place soon
-  fQACollection->CreateTH2F("secvtxeTPCsig", "TPC signal for tagged e",125, 0, 25, 200, 0, 200 ); // mj: will move to another place soon 
+  InitPIDperformanceQA();
   fQA->Add(fQACollection->GetList());
 
-  if(!fOutput) fOutput = new TList;
+  // Initialize PID
+  fPID->SetHasMCData(HasMCData());
+  if(!fPID->GetNumberOfPIDdetectors()) fPID->AddDetector("TPC", 0);
+  fPID->InitializePID();
+  if(IsQAOn(kPIDqa)){
+    AliInfo("PID QA switched on");
+    fPIDqa = new AliHFEpidQAmanager;
+    fPIDqa->Initialize(fPID);
+    fQA->Add(fPIDqa->MakeList("HFEpidQA"));
+  }
+
   // Initialize correction Framework and Cuts
+  const Int_t kNcutSteps = AliHFEcuts::kNcutStepsMCTrack + AliHFEcuts::kNcutStepsRecTrack + AliHFEcuts::kNcutStepsDETrack;
   fCFM = new AliCFManager;
-  fV0CF = new AliCFManager;
+  fCFM->SetNStepParticle(kNcutSteps);
   MakeParticleContainer();
   MakeEventContainer();
   // Temporary fix: Initialize particle cuts with NULL
-  for(Int_t istep = 0; istep < fCFM->GetParticleContainer()->GetNStep(); istep++)
+  for(Int_t istep = 0; istep < kNcutSteps; istep++)
     fCFM->SetParticleCutsList(istep, NULL);
   if(!fCuts){
     AliWarning("Cuts not available. Default cuts will be used");
@@ -373,46 +349,21 @@ void AliAnalysisTaskHFE::UserCreateOutputObjects(){
   }
   if(IsAODanalysis()) fCuts->SetAOD();
   // Make clone for V0 tagging step
-  fCutsTagged = new AliHFEcuts(*fCuts);
-  fCutsTagged->SetName("hfeV0Cuts");
-  fCutsTagged->SetTitle("Cuts for tagged Particles");
   fCuts->Initialize(fCFM);
-  fCutsTagged->Initialize(fV0CF);
   if(fCuts->IsQAOn()) fQA->Add(fCuts->GetQAhistograms());
-  if(fCutsTagged->IsQAOn()) fQA->Add(fCutsTagged->GetQAhistograms());
+  fSignalCuts = new AliHFEsignalCuts("HFEsignalCuts", "HFE MC Signal definition");
+  fVarManager->SetSignalCuts(fSignalCuts);
  
   // add output objects to the List
-  fOutput->AddAt(fCFM->GetParticleContainer(), 0);
+  fOutput->AddAt(fContainer, 0);
   fOutput->AddAt(fCFM->GetEventContainer(), 1);
-  fOutput->AddAt(fCorrelation, 2);
-  fOutput->AddAt(fPIDperformance, 3);
-  fOutput->AddAt(fSignalToBackgroundMC, 4);
-  fOutput->AddAt(fNElectronTracksEvent, 5);
-  fOutput->AddAt(fHadronicBackground, 6);
-  fOutput->AddAt(fV0CF, 7);
-  // Initialize PID
-  if(IsQAOn(kPIDqa)){
-    AliInfo("PID QA switched on");
-    //fPID->SetDebugLevel(2);
-    fPID->SetQAOn();
-    fQA->Add(fPID->GetQAhistograms());
-  }
-  fPID->SetHasMCData(HasMCData());
-  if(!fPIDdetectors.Length() && ! fPIDstrategy) AddPIDdetector("TPC");
-  if(fPIDstrategy){
-    fPID->InitializePID(Form("Strategy%d", fPIDstrategy));
-    fPIDtagged->InitializePID(Form("Strategy%d", fPIDstrategy));
-  }
-  else{
-    fPID->InitializePID(fPIDdetectors.Data());     // Only restrictions to TPC allowed 
-    fPIDtagged->InitializePID(fPIDdetectors.Data());     // Only restrictions to TPC allowed 
-  }
-
+  
   // mcQA----------------------------------
   if (HasMCData() && IsQAOn(kMCqa)) {
     AliInfo("MC QA on");
     if(!fMCQA) fMCQA = new AliHFEmcQA;
     if(!fHistMCQA) fHistMCQA = new TList();
+    fHistMCQA->SetOwner();
     fMCQA->CreatDefaultHistograms(fHistMCQA);
     fQA->Add(fHistMCQA);
   } 
@@ -424,6 +375,7 @@ void AliAnalysisTaskHFE::UserCreateOutputObjects(){
     fSecVtx->SetHasMCData(HasMCData());
 
     if(!fHistSECVTX) fHistSECVTX = new TList();
+    fHistSECVTX->SetOwner();
     fSecVtx->CreateHistograms(fHistSECVTX);
     fOutput->Add(fHistSECVTX);
   }
@@ -438,9 +390,23 @@ void AliAnalysisTaskHFE::UserCreateOutputObjects(){
     fElecBackGround->SetHasMCData(HasMCData());
 
     if(!fHistELECBACKGROUND) fHistELECBACKGROUND = new TList();
+    fHistELECBACKGROUND->SetOwner();
     fElecBackGround->CreateHistograms(fHistELECBACKGROUND);
     fOutput->Add(fHistELECBACKGROUND);
   }  
+
+  // tagged tracks
+  if(GetPlugin(kTaggedTrackAnalysis)){
+    AliInfo("Analysis on V0-tagged tracks enabled");
+    fTaggedTrackAnalysis = new AliHFEtaggedTrackAnalysis;
+    fTaggedTrackAnalysis->SetCuts(fTaggedTrackCuts);
+    fTaggedTrackAnalysis->SetPID(fPID);
+    fTaggedTrackAnalysis->InitContainer();
+    fOutput->Add(fTaggedTrackAnalysis->GetContainer());
+    fQA->Add(fTaggedTrackAnalysis->GetPIDQA());
+    fQA->Add(fTaggedTrackAnalysis->GetCutQA());
+  }
+  PrintStatus();
 }
 
 //____________________________________________________________
@@ -477,35 +443,48 @@ void AliAnalysisTaskHFE::UserExec(Option_t *){
     if(!mcH->TreeTR()) return;
   }
 
+  // need the centrality for everything (MC also)
+  fCentralityF = 99.0;
+  ReadCentrality();
+  
+  // See if pile up and z in the range
+  RejectionPileUpVertexRangeEventCut();
+
   // Protect agains missing 
-  if(HasMCData()) ProcessMC();  // Run the MC loop + MC QA in case MC Data are available
+  if(HasMCData()){
+    fSignalCuts->SetMCEvent(fMCEvent);
+    ProcessMC();  // Run the MC loop + MC QA in case MC Data are available
+  }
 
-  if(IsAODanalysis()) ProcessAOD();
-  else{
+  if(IsAODanalysis()){
+    AliAODpidUtil *aodworkingpid = AliHFEtools::GetDefaultAODPID(HasMCData());
+    fPID->SetAODpid(aodworkingpid); 
+    if(fPIDqa) fPIDqa->SetAODpid(aodworkingpid);
+    if(fTaggedTrackAnalysis) fTaggedTrackAnalysis->GetPIDqa()->SetAODpid(aodworkingpid);
+    ProcessAOD();
+  } else {
     AliESDInputHandler *inH = dynamic_cast<AliESDInputHandler *>(fInputHandler);
     if(!inH){
       AliError("No ESD Input handler available");
       return;
     }
     AliESDpid *workingPID = inH->GetESDpid();
-    if(workingPID){
-      AliDebug(1, "Using ESD PID from the input handler");
-      fPID->SetESDpid(workingPID);
-      fPIDtagged->SetESDpid(workingPID);
-      if(fPIDpreselect) fPIDpreselect->SetESDpid(workingPID);
-    } else { 
+    if(!workingPID){
       AliDebug(1, "Using default ESD PID");
-      fPID->SetESDpid(AliHFEtools::GetDefaultPID(HasMCData()));
-      fPIDtagged->SetESDpid(AliHFEtools::GetDefaultPID(HasMCData()));
-      if(fPIDpreselect) fPIDpreselect->SetESDpid(AliHFEtools::GetDefaultPID(HasMCData())); 
+      workingPID = AliHFEtools::GetDefaultPID(HasMCData());
+    } else { 
+      AliDebug(1, "Using ESD PID from the input handler");
     }
+    fPID->SetESDpid(workingPID);
+    if(fPIDqa) fPIDqa->SetESDpid(workingPID);
+    if(fTaggedTrackAnalysis) fTaggedTrackAnalysis->GetPIDqa()->SetESDpid(workingPID);
+    if(fPIDpreselect) fPIDpreselect->SetESDpid(workingPID);
+
     ProcessESD();
   }
   // Done!!!
-  PostData(1, fNEvents);
-  PostData(2, fOutput);
-  PostData(3, fQA);
-//  PostData(4, fQAcoll->GetList());
+  PostData(1, fOutput);
+  PostData(2, fQA);
 }
 
 //____________________________________________________________
@@ -514,14 +493,32 @@ void AliAnalysisTaskHFE::Terminate(Option_t *){
   // Terminate not implemented at the moment
   //
   if(GetPlugin(kPostProcess)){
-    fOutput = dynamic_cast<TList *>(GetOutputData(2));
+    fOutput = dynamic_cast<TList *>(GetOutputData(1));
+    fQA = dynamic_cast<TList *>(GetOutputData(2));
     if(!fOutput){
       AliError("Results not available");
       return;
     }
+    if(!fQA){
+      AliError("QA output not available");
+      return;
+    }
+    fContainer = dynamic_cast<AliHFEcontainer *>(fOutput->FindObject("trackContainer")); 
+    if(!fContainer){
+      AliError("Track container not found");
+      return;
+    }
     AliHFEpostAnalysis postanalysis;
-    postanalysis.SetResults(fOutput);
-    if(HasMCData())postanalysis.DrawMCSignal2Background();
+    postanalysis.SetTaskResults(fContainer);
+    TList *qalist = dynamic_cast<TList *>(fQA->FindObject("list_TaskQA"));
+    if(!qalist){
+      AliError("QA List not found");
+      return;
+    }
+    postanalysis.SetTaskQA(qalist);
+    printf("Running post analysis\n");
+    //if(HasMCData())
+    postanalysis.DrawMCSignal2Background();
     postanalysis.DrawEfficiency();
     postanalysis.DrawPIDperformance();
     postanalysis.DrawCutEfficiency();
@@ -570,8 +567,9 @@ void AliAnalysisTaskHFE::ProcessMC(){
   // In case MC QA is on also MC QA loop is done
   //
   AliDebug(3, "Processing MC Information");
-  Double_t eventContainer [2];
+  Double_t eventContainer [3];
   eventContainer[0] = fMCEvent->GetPrimaryVertex()->GetZ();
+  eventContainer[2] = fCentralityF;
   if(fCFM->CheckEventCuts(AliHFEcuts::kEventStepGenerated, fMCEvent)) 
     fCFM->GetEventContainer()->Fill(eventContainer,AliHFEcuts::kEventStepGenerated);
   Int_t nElectrons = 0;
@@ -623,7 +621,7 @@ void AliAnalysisTaskHFE::ProcessMC(){
   AliDebug(3, Form("Number of Tracks: %d", fMCEvent->GetNumberOfTracks()));
   for(Int_t imc = 0; imc <fMCEvent->GetNumberOfTracks(); imc++){
     if(!(mctrack = fMCEvent->GetTrack(imc))) continue;
-    AliDebug(4, "Next Track");
+    AliDebug(4, "Next MC Track");
     if(ProcessMCtrack(mctrack)) nElectrons++;
   }
 
@@ -645,15 +643,32 @@ void AliAnalysisTaskHFE::ProcessESD(){
   }
 
   // Do event Normalization
-  Double_t eventContainer[2];
+  Double_t eventContainer[3];
   eventContainer[0] = fInputEvent->GetPrimaryVertex()->GetZ();
   eventContainer[1] = 0.;
+  eventContainer[2] = fCentralityF;
   if(fTriggerAnalysis->IsOfflineTriggerFired(fESD, AliTriggerAnalysis::kV0AND))
     eventContainer[1] = 1.;
+
+  //
   fCFM->GetEventContainer()->Fill(eventContainer, AliHFEcuts::kEventStepRecNoCut);
-  if(!fCFM->CheckEventCuts(AliHFEcuts::kEventStepReconstructed, fInputEvent)) return;
+
+  //
+  if(fIdentifiedAsPileUp) return; 
+  fCFM->GetEventContainer()->Fill(eventContainer, AliHFEcuts::kEventStepRecNoPileUp);
+
+  //
+  if(fIdentifiedAsOutInz) return;
+  fCFM->GetEventContainer()->Fill(eventContainer, AliHFEcuts::kEventStepZRange);  
+
+  //
+  if(!fPassTheEventCut) return;
   fCFM->GetEventContainer()->Fill(eventContainer, AliHFEcuts::kEventStepReconstructed);
 
+
+  fContainer->NewEvent();
+
   if (GetPlugin(kIsElecBackGround)) { 
     fElecBackGround->SetEvent(fESD);
   }
@@ -665,13 +680,13 @@ void AliAnalysisTaskHFE::ProcessESD(){
   if(HasMCData()){
     if (GetPlugin(kSecVtx)) { 
       fSecVtx->SetMCEvent(fMCEvent);
+      fSecVtx->SetMCQA(fMCQA); 
     }
     if (GetPlugin(kIsElecBackGround)) { 
       fElecBackGround->SetMCEvent(fMCEvent);
     }
   }
 
-  Double_t nContrib = fInputEvent->GetPrimaryVertex()->GetNContributors();
   Double_t container[10];
   memset(container, 0, sizeof(Double_t) * 10);
   // container for the output THnSparse
@@ -681,9 +696,6 @@ void AliAnalysisTaskHFE::ProcessESD(){
   AliMCParticle *mctrack = NULL;
   TParticle* mctrack4QA = NULL;
   Int_t pid = 0;
-  // For double counted tracks
-  LabelContainer cont(fESD->GetNumberOfTracks());
-  Bool_t alreadyseen = kFALSE;
 
   Bool_t signal = kTRUE;
 
@@ -701,6 +713,7 @@ void AliAnalysisTaskHFE::ProcessESD(){
   //
   AliDebug(3, Form("Number of Tracks: %d", fESD->GetNumberOfTracks()));
   for(Int_t itrack = 0; itrack < fESD->GetNumberOfTracks(); itrack++){
+    AliDebug(4, "New ESD track");
     track = fESD->GetTrack(itrack);
 
     // fill counts of v0-identified particles
@@ -708,8 +721,11 @@ void AliAnalysisTaskHFE::ProcessESD(){
     if(track->TestBit(BIT(14))) v0pid = AliPID::kElectron;
     else if(track->TestBit(BIT(15))) v0pid = AliPID::kPion;
     else if(track->TestBit(BIT(16))) v0pid = AliPID::kProton;
-    if(v0pid > -1)
-      FilterTaggedTrack(track, v0pid);
+    // here the tagged track analysis will run
+    if(fTaggedTrackAnalysis && v0pid > -1){ 
+      AliDebug(1, Form("Track identified as %s", AliPID::ParticleName(v0pid)));
+      fTaggedTrackAnalysis->ProcessTrack(track, v0pid);
+    }
  
     AliDebug(3, Form("Doing track %d, %p", itrack, track));
      
@@ -719,66 +735,29 @@ void AliAnalysisTaskHFE::ProcessESD(){
     if(fPIDpreselect && fCutspreselect) {
       if(!PreSelectTrack(track)) continue;
     }
-     
-    container[0] = track->Pt();
-    container[1] = track->Eta();
-    container[2] = track->Phi();
-    container[3] = track->Charge();
-    container[4] = 0;
-
-    dataE[0] = track->Pt();
-    dataE[1] = track->Eta();
-    dataE[2] = track->Phi();
-    dataE[3] = track->Charge();
-    dataE[4] = -1;
-    dataE[5] = -1;
 
     signal = kTRUE;
-    Double_t weight = 1.0;
     
     // Fill step without any cut
           
     if(HasMCData()){
-      container[4] = container[9] = kOther;
       // Check if it is electrons near the vertex
       if(!(mctrack = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(TMath::Abs(track->GetLabel()))))) continue;
       mctrack4QA = mctrack->Particle();
 
-      container[5] = mctrack->Pt();
-      container[6] = mctrack->Eta();
-      container[7] = mctrack->Phi();
-      container[8] = mctrack->Charge()/3.;
-
-      if(fWeighting) weight = FindWeight(container[5],container[6],container[7]);    
-
-      if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepMCGenerated, mctrack)) signal = kFALSE;
+      if(fFillSignalOnly && !fCFM->CheckParticleCuts(AliHFEcuts::kStepMCGenerated, mctrack)) signal = kFALSE;
       else AliDebug(3, "Signal Electron");
-      
-      Int_t signalTrack = 0;
-      if((signalTrack = IsSignalElectron(track))){
-        AliDebug(3, Form("Signal: Index = %d\n", signalTrack));
-        switch(signalTrack){
-          case 1: container[4] = container[9] = kSignalCharm; break;
-          case 2: container[4] = container[9] = kSignalBeauty; break;
-          default: container[4] = container[9] = kOther; break;
-        };
-      } else if(IsGammaElectron(track)) container[4] = container[9] = kGammaConv;
-      AliDebug(3, Form("Signal Decision(%f/%f)", container[4], container[9]));
     } 
-    AliDebug(3, Form("Weight? %f", weight));
+    // Cache new Track information inside the var manager
+    fVarManager->NewTrack(track, mctrack, fCentralityF, -1, signal);
+
     if(signal) {
-      alreadyseen = cont.Find(TMath::Abs(track->GetLabel()));
-      cont.Append(TMath::Abs(track->GetLabel()));
-      
-      fCFM->GetParticleContainer()->Fill(&container[5], AliHFEcuts::kStepRecNoCut,weight);
-      fCFM->GetParticleContainer()->Fill(&container[0], AliHFEcuts::kStepRecNoCut + 2*AliHFEcuts::kNcutStepsESDtrack,weight);
-      if(alreadyseen) {
-        fCFM->GetParticleContainer()->Fill(&container[5], AliHFEcuts::kStepRecNoCut + AliHFEcuts::kNcutStepsESDtrack,weight);
-      }
+      fVarManager->FillContainer(fContainer, "recTrackContReco", AliHFEcuts::kStepRecNoCut, kFALSE);
+      fVarManager->FillContainer(fContainer, "recTrackContMC", AliHFEcuts::kStepRecNoCut, kTRUE);
     }
 
     // RecKine: ITSTPC cuts  
-    if(!ProcessCutStep(AliHFEcuts::kStepRecKineITSTPC, track, container, signal, alreadyseen, weight)) continue;
+    if(!ProcessCutStep(AliHFEcuts::kStepRecKineITSTPC, track)) continue;
     
     // Check TRD criterions (outside the correction framework)
     if(track->GetTRDncls()){
@@ -790,17 +769,10 @@ void AliAnalysisTaskHFE::ProcessESD(){
 
     
     // RecPrim
-    if(!ProcessCutStep(AliHFEcuts::kStepRecPrim, track, container, signal, alreadyseen,weight)) continue;
+    if(!ProcessCutStep(AliHFEcuts::kStepRecPrim, track)) continue;
 
     // HFEcuts: ITS layers cuts
-    if(!ProcessCutStep(AliHFEcuts::kStepHFEcutsITS, track, container, signal, alreadyseen,weight)) continue;
-
-    // HFEcuts: Nb of tracklets TRD0
-    if(!ProcessCutStep(AliHFEcuts::kStepHFEcutsTRD, track, container, signal, alreadyseen,weight)) continue;
-    if(signal) {
-      // dimensions 3&4&5 : pt,eta,phi (MC)
-      ((THnSparseF *)fCorrelation->At(0))->Fill(container);
-    }
+    if(!ProcessCutStep(AliHFEcuts::kStepHFEcutsITS, track)) continue;
 
     if(HasMCData() && IsQAOn(kMCqa)) {
       // mc qa for after the reconstruction cuts  
@@ -808,7 +780,18 @@ void AliAnalysisTaskHFE::ProcessESD(){
       fMCQA->GetDecayedKine(mctrack4QA, AliHFEmcQA::kCharm,  AliHFEmcQA::kElectronPDG, 3);  // charm
       fMCQA->GetDecayedKine(mctrack4QA, AliHFEmcQA::kBeauty,  AliHFEmcQA::kElectronPDG, 3); // beauty 
       fMCQA->GetDecayedKine(mctrack4QA, AliHFEmcQA::kOthers,  AliHFEmcQA::kElectronPDG, 3); // beauty 
-    } 
+    }
+
+    // HFEcuts: Nb of tracklets TRD0
+    if(!ProcessCutStep(AliHFEcuts::kStepHFEcutsTRD, track)) continue;
+
+    if (HasMCData() && IsQAOn(kMCqa)) {
+      // mc qa for after the reconstruction and pid cuts  
+      AliDebug(2, "Running MC QA");
+      fMCQA->GetDecayedKine(mctrack4QA, AliHFEmcQA::kCharm,  AliHFEmcQA::kElectronPDG, 4);  // charm
+      fMCQA->GetDecayedKine(mctrack4QA, AliHFEmcQA::kBeauty,  AliHFEmcQA::kElectronPDG, 4); // beauty 
+      fMCQA->GetDecayedKine(mctrack4QA, AliHFEmcQA::kOthers,  AliHFEmcQA::kElectronPDG, 4); // beauty 
+    }
 
     if(HasMCData()){
       FillProductionVertex(track);
@@ -816,98 +799,54 @@ void AliAnalysisTaskHFE::ProcessESD(){
 
     // track accepted, do PID
     AliHFEpidObject hfetrack;
-    hfetrack.fAnalysisType = AliHFEpidObject::kESDanalysis;
-    hfetrack.fRecTrack = track;
-    if(HasMCData()) hfetrack.fMCtrack = mctrack;
-    if(!fPID->IsSelected(&hfetrack)) continue;
+    hfetrack.SetAnalysisType(AliHFEpidObject::kESDanalysis);
+    hfetrack.SetRecTrack(track);
+    if(HasMCData()) hfetrack.SetMCTrack(mctrack);
+    hfetrack.SetCentrality(fCentralityF);
+    fPID->SetVarManager(fVarManager);
+    if(!fPID->IsSelected(&hfetrack, fContainer, "recTrackCont", fPIDqa)) continue;
     nElectronCandidates++;
 
     // Fill Histogram for Hadronic Background
     if(HasMCData()){
       if(mctrack && (TMath::Abs(mctrack->Particle()->GetPdgCode()) != 11))
-        fHadronicBackground->Fill(container, 0);
+        fVarManager->FillContainer(fContainer, "hadronicBackground", UInt_t(0), kFALSE);
     }
 
-    if (HasMCData() && IsQAOn(kMCqa)) {
-      // mc qa for after the reconstruction and pid cuts  
-      AliDebug(2, "Running MC QA");
-      fMCQA->GetDecayedKine(mctrack4QA, AliHFEmcQA::kCharm,  AliHFEmcQA::kElectronPDG, 4);  // charm
-      fMCQA->GetDecayedKine(mctrack4QA, AliHFEmcQA::kBeauty,  AliHFEmcQA::kElectronPDG, 4); // beauty 
-      fMCQA->GetDecayedKine(mctrack4QA, AliHFEmcQA::kOthers,  AliHFEmcQA::kElectronPDG, 4); // beauty 
-    } 
-
     // Fill Containers
     if(signal) {
       // Apply weight for background contamination
       if(fBackGroundFactorsFunction) {
-             Double_t weightBackGround = fBackGroundFactorsFunction->Eval(TMath::Abs(track->P()));
-             if(weightBackGround < 0.0) weightBackGround = 0.0;
-        else if(weightBackGround > 1.0) weightBackGround = 0.0;
-        fHadronicBackground->Fill(container, 1, weight * weightBackGround);
-      }
-      //      
-      fCFM->GetParticleContainer()->Fill(container, AliHFEcuts::kStepPID + 2*AliHFEcuts::kNcutStepsESDtrack, weight);
-      fCFM->GetParticleContainer()->Fill(&container[5], AliHFEcuts::kStepPID, weight);
-      if(alreadyseen) {
-        fCFM->GetParticleContainer()->Fill(&container[5], (AliHFEcuts::kStepPID + (AliHFEcuts::kNcutStepsESDtrack)),weight);
+       Double_t weightBackGround = fBackGroundFactorsFunction->Eval(TMath::Abs(track->P()));
+       if(weightBackGround < 0.0) weightBackGround = 0.0;
+        else if(weightBackGround > 1.0) weightBackGround = 1.0;
+        // weightBackGround as special weight
+        fVarManager->FillContainer(fContainer, "hadronicBackground", 1, kFALSE, weightBackGround);
       }
-      // dimensions 3&4&5 : pt,eta,phi (MC)
-      ((THnSparseF *)fCorrelation->At(1))->Fill(container);
+      fVarManager->FillCorrelationMatrix(fContainer->GetCorrelationMatrix("correlationstepafterPID"));
     }
 
     if(GetPlugin(kSecVtx)) {
       AliDebug(2, "Running Secondary Vertex Analysis");
-      if(track->Pt()>2.0 && nContrib > 1){ 
-        fSecVtx->InitHFEpairs();
-        fSecVtx->InitHFEsecvtxs();
-        for(Int_t jtrack = 0; jtrack < fESD->GetNumberOfTracks(); jtrack++){
-          htrack = fESD->GetTrack(jtrack);
-          if ( itrack == jtrack ) continue; // since it is for tagging single electron, don't need additional condition 
-          if (htrack->Pt()<2.0) continue;
-          if (!fCFM->CheckParticleCuts(AliHFEcuts::kStepRecKineITSTPC, htrack)) continue;
-          if (!fCFM->CheckParticleCuts(AliHFEcuts::kStepRecPrim, htrack)) continue;
-          fSecVtx->PairAnalysis(track, htrack, jtrack); // e-h pairing
-        }
-        for(int ip=0; ip<fSecVtx->HFEpairs()->GetEntriesFast(); ip++){
-          //if(HasMCData()){
-            AliHFEpairs *pair = (AliHFEpairs*) (fSecVtx->HFEpairs()->UncheckedAt(ip));
-            //if(!(pair->GetPairCode()>1. && pair->GetPairCode()<4.))  // apply various cuts
-            // apply various cuts
-            if(pair->GetKFChi2()>5.) // only apply vertex chi2 cut for the moment
-            //if((pair->GetKFChi2()>5.) || !(pair->GetSignedLxy()>0. && pair->GetSignedLxy()<2.)) 
-              fSecVtx->HFEpairs()->RemoveAt(ip);
-          //}
-        }
-        fSecVtx->HFEpairs()->Compress();
-        if(fSecVtx->HFEpairs()->GetEntriesFast()) fSecVtx->RunSECVTX(track); // secondary vertexing with e,h1,h2,.. tracks
-        for(int ip=0; ip<fSecVtx->HFEsecvtxs()->GetEntriesFast(); ip++){
-          AliHFEsecVtxs *secvtx=0x0;
-          secvtx = (AliHFEsecVtxs*) (fSecVtx->HFEsecvtxs()->UncheckedAt(ip));
-          if(!(secvtx->GetInvmass()>2.0 && secvtx->GetInvmass()<5.2) || !(secvtx->GetSignedLxy2()>0.08 && secvtx->GetSignedLxy2()<1.5) || !(secvtx->GetKFIP2()>-0.1 && secvtx->GetKFIP2()<0.1))
-            fSecVtx->HFEsecvtxs()->RemoveAt(ip);
-          // here you apply cuts, then if it doesn't pass the cut, remove it from the fSecVtx->HFEsecvtxs() 
-        }
-        if(fSecVtx->HFEsecvtxs()->GetEntriesFast()) {
-          fQACollection->Fill("secvtxpt", track->Pt());
-          fQACollection->Fill("secvtxTPCsig", track->P(),track->GetTPCsignal());
-          if (HasMCData() && IsQAOn(kMCqa)) {
-            // mc qa for after the reconstruction and pid cuts  
-            AliDebug(2, "Running MC QA");
-            fMCQA->GetDecayedKine(mctrack4QA, AliHFEmcQA::kCharm,  AliHFEmcQA::kElectronPDG, 5);  // charm
-            fMCQA->GetDecayedKine(mctrack4QA, AliHFEmcQA::kBeauty,  AliHFEmcQA::kElectronPDG, 5); // beauty 
-            fMCQA->GetDecayedKine(mctrack4QA, AliHFEmcQA::kOthers,  AliHFEmcQA::kElectronPDG, 5); // beauty 
-          }
-        }
-        fSecVtx->DeleteHFEpairs();
-        fSecVtx->DeleteHFEsecvtxs();
-      }
+      fSecVtx->Process(track);
     }
 
     if(HasMCData()){
+      dataE[0] = track->Pt();
+      dataE[1] = track->Eta();
+      dataE[2] = track->Phi();
+      dataE[3] = track->Charge();
+      dataE[4] = -1.;
+      dataE[5] = -1.;
+
       // Track selected: distinguish between true and fake
       AliDebug(1, Form("Candidate Selected, filling THnSparse, PID: %d\n", mctrack->Particle()->GetPdgCode()));
       if((pid = TMath::Abs(mctrack->Particle()->GetPdgCode())) == 11){
-        Int_t type = IsSignalElectron(track);
+        Int_t type = 0;
+        if(fSignalCuts->IsCharmElectron(track))
+          type = 1;
+        else if(fSignalCuts->IsBeautyElectron(track))
+          type = 2;
         AliDebug(1, Form("Type: %d\n", type));
         if(type){
                dataE[5] = type; // beauty[1] or charm[2]
@@ -926,7 +865,7 @@ void AliAnalysisTaskHFE::ProcessESD(){
       // fill the performance THnSparse, if the mc origin could be defined
       if(dataE[4] > -1){
         AliDebug(1, Form("Entries: [%.3f|%.3f|%.3f|%f|%f|%f]\n", dataE[0],dataE[1],dataE[2],dataE[3],dataE[4],dataE[5]));
-        fPIDperformance->Fill(dataE);
+        fQACollection->Fill("PIDperformance", dataE);
       }
     }
     // Electron background analysis 
@@ -941,10 +880,22 @@ void AliAnalysisTaskHFE::ProcessESD(){
       }
     } // end of electron background analysis
 
+    if (GetPlugin(kDEstep)) { 
+      // Fill Containers for impact parameter analysis
+      if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepHFEcutsDca + AliHFEcuts::kNcutStepsMCTrack + AliHFEcuts::kNcutStepsRecTrack,track)) continue;
+      if(signal) {
+        fVarManager->FillContainer(fContainer, "recTrackContDEReco", AliHFEcuts::kStepHFEcutsDca, kFALSE);
+        fVarManager->FillContainer(fContainer, "recTrackContDEMC", AliHFEcuts::kStepHFEcutsDca, kTRUE);
+        fVarManager->FillCorrelationMatrix(fContainer->GetCorrelationMatrix("correlationstepafterDE"));
+      }
+      if(HasMCData()){
+        if(mctrack && (TMath::Abs(mctrack->Particle()->GetPdgCode()) != 11))
+          fVarManager->FillContainer(fContainer, "hadronicBackground", 2, kFALSE);
+      }
+    }
+
   }
-  fNEvents->Fill(1);
-  //fQAcoll->Fill("fNevents", 1);
-  fNElectronTracksEvent->Fill(nElectronCandidates);
+  fQACollection->Fill("nElectronTracksEvent", nElectronCandidates);
 }
 
 //____________________________________________________________
@@ -957,78 +908,82 @@ void AliAnalysisTaskHFE::ProcessAOD(){
   Double_t eventContainer[2];
   eventContainer[0] = fInputEvent->GetPrimaryVertex()->GetZ();
   eventContainer[1] = 1.; // No Information available in AOD analysis, assume all events have V0AND
-  fCFM->GetEventContainer()->Fill(eventContainer,AliHFEcuts::kEventStepRecNoCut);
-  if(!fCFM->CheckEventCuts(AliHFEcuts::kEventStepReconstructed, fInputEvent)) return;
-  fCFM->GetEventContainer()->Fill(eventContainer,AliHFEcuts::kEventStepReconstructed);
+
   AliAODEvent *fAOD = dynamic_cast<AliAODEvent *>(fInputEvent);
   if(!fAOD){
     AliError("AOD Event required for AOD Analysis")
-    return;
+      return;
   }
+  
+  //
+  fCFM->GetEventContainer()->Fill(eventContainer, AliHFEcuts::kEventStepRecNoCut);
+
+  //
+  if(fIdentifiedAsPileUp) return; 
+  fCFM->GetEventContainer()->Fill(eventContainer, AliHFEcuts::kEventStepRecNoPileUp);
+
+  //
+  if(fIdentifiedAsOutInz) return;
+  fCFM->GetEventContainer()->Fill(eventContainer, AliHFEcuts::kEventStepZRange);  
+
+  //
+  if(!fPassTheEventCut) return;
+  fCFM->GetEventContainer()->Fill(eventContainer, AliHFEcuts::kEventStepReconstructed);
+
+  fContainer->NewEvent();
  
   AliAODTrack *track = NULL;
   AliAODMCParticle *mctrack = NULL;
-  Double_t container[10]; memset(container, 0, sizeof(Double_t) * 10);
   Double_t dataE[6]; // [pT, eta, Phi, Charge, type, 'C' or 'B']
   Int_t nElectronCandidates = 0;
   Int_t pid;
+  Bool_t signal;
   for(Int_t itrack = 0; itrack < fAOD->GetNumberOfTracks(); itrack++){
     track = fAOD->GetTrack(itrack);
     if(!track) continue;
     if(track->GetFlags() != 1<<4) continue;  // Only process AOD tracks where the HFE is set
 
-    container[0] = track->Pt();
-    container[1] = track->Eta();
-    container[2] = track->Phi();
-    container[3] = track->Charge();
-
-    dataE[0] = track->Pt();
-    dataE[1] = track->Eta();
-    dataE[2] = track->Phi();
-    dataE[3] = track->Charge();
-    dataE[4] = -1;
-    dataE[5] = -1;
-    
+    signal = kTRUE;
     if(HasMCData()){
-      Int_t signalTrack = 0;
-      if((signalTrack = IsSignalElectron(track))){
-        switch(signalTrack){
-          case 1: container[4] = container[9] = kSignalCharm; break;
-          case 2: container[4] = container[9] = kSignalBeauty; break;
-        };
-      } else if(IsGammaElectron(track)) 
-        container[4] = container[9] = kGammaConv;
-      else container[4] = container[9] = kOther;
 
       Int_t label = TMath::Abs(track->GetLabel());
-      if(label){
+      if(label)
         mctrack = dynamic_cast<AliAODMCParticle *>(fMCEvent->GetTrack(label));
-        container[5] = mctrack->Pt();
-        container[6] = mctrack->Eta();
-        container[7] = mctrack->Phi();
-        container[8] = mctrack->Charge();
-      }
+        if(fFillSignalOnly && !fCFM->CheckParticleCuts(AliHFEcuts::kStepMCGenerated, mctrack)) signal = kFALSE;
     }
+    fVarManager->NewTrack(track, mctrack, fCentralityF, -1, kTRUE);
     // track accepted, do PID
     AliHFEpidObject hfetrack;
-    hfetrack.fAnalysisType = AliHFEpidObject::kAODanalysis;
-    hfetrack.fRecTrack = track;
-    if(HasMCData()) hfetrack.fMCtrack = mctrack;
-    //if(!fPID->IsSelected(&hfetrack)) continue;    // we will do PID here as soon as possible
-    // Particle identified - Fill CF Container
+    hfetrack.SetAnalysisType(AliHFEpidObject::kAODanalysis);
+    hfetrack.SetRecTrack(track);
+    if(HasMCData()) hfetrack.SetMCTrack(mctrack);
+    hfetrack.SetCentrality(fCentralityF);
+    fPID->SetVarManager(fVarManager);
+    if(!fPID->IsSelected(&hfetrack, fContainer, "recTrackCont", fPIDqa)) continue;    // we will do PID here as soon as possible
     // Apply weight for background contamination
     Double_t weightBackGround = 1.0;
     if(fBackGroundFactorsFunction) {
-      weightBackGround = weightBackGround - fBackGroundFactorsFunction->Eval(TMath::Abs(track->P()));
-      if(weightBackGround < 0.0) weightBackGround = 1.0;
+      weightBackGround = fBackGroundFactorsFunction->Eval(TMath::Abs(track->P()));
+      if(weightBackGround < 0.0) weightBackGround = 0.0;
     }
-    fCFM->GetParticleContainer()->Fill(container, AliHFEcuts::kStepPID + 2*AliHFEcuts::kNcutStepsESDtrack, weightBackGround);
+    fVarManager->FillContainer(fContainer, "hadronicBackground", 1, kFALSE);
     nElectronCandidates++;    
     if(HasMCData()){
-      // Track selected: distinguish between true and fake
+      dataE[0] = track->Pt();
+      dataE[1] = track->Eta();
+      dataE[2] = track->Phi();
+      dataE[3] = track->Charge();
+      dataE[4] = -1;
+      dataE[5] = -1;
+     // Track selected: distinguish between true and fake
       AliDebug(1, Form("Candidate Selected, filling THnSparse, PID: %d\n", mctrack->GetPdgCode()));
       if((pid = TMath::Abs(mctrack->GetPdgCode())) == 11){
-        Int_t type = IsSignalElectron(track);
+      
+        Int_t type = 0;
+        if(fSignalCuts->IsCharmElectron(track))
+          type = 1;
+        else if(fSignalCuts->IsBeautyElectron(track))
+          type = 2;
         AliDebug(1, Form("Type: %d\n", type));
         if(type){
                dataE[5] = type; // beauty[1] or charm[2]
@@ -1047,12 +1002,11 @@ void AliAnalysisTaskHFE::ProcessAOD(){
       // fill the performance THnSparse, if the mc origin could be defined
       if(dataE[4] > -1){
         AliDebug(1, Form("Entries: [%.3f|%.3f|%.3f|%f|%f|%f]\n", dataE[0],dataE[1],dataE[2],dataE[3],dataE[4],dataE[5]));
-        fPIDperformance->Fill(dataE);
+        fQACollection->Fill("PIDperformance", dataE);
       }
     }
   }
-  fNEvents->Fill(1);
-  fNElectronTracksEvent->Fill(nElectronCandidates);
+  fQACollection->Fill("nElectronTracksEvent", nElectronCandidates);
 }
 
 //____________________________________________________________
@@ -1062,53 +1016,40 @@ Bool_t AliAnalysisTaskHFE::ProcessMCtrack(AliVParticle *track){
   // Additionally Fill a THnSparse for Signal To Background Studies
   // Works for AOD and MC analysis Type
   //
-  Double_t container[5], signalContainer[6];
-  Double_t vertex[3]; // Production vertex cut to mask gammas which are NOT supposed to have hits in the first ITS layer(s)
-  if(IsESDanalysis()){
-    AliMCParticle *mctrack = dynamic_cast<AliMCParticle *>(track);
-    container[0] = mctrack->Pt();
-    container[1] = mctrack->Eta();
-    container[2] = mctrack->Phi();
-    container[3] = mctrack->Charge()/3;
+  fVarManager->NewTrack(track, NULL, -1, kTRUE);
+  Double_t signalContainer[6];
 
-    signalContainer[0] = mctrack->Pt();
-    signalContainer[1] = mctrack->Eta();
-    signalContainer[2] = mctrack->Phi();
-    signalContainer[3] = mctrack->Charge()/3;
+  signalContainer[0] = track->Pt();
+  signalContainer[1] = track->Eta();
+  signalContainer[2] = track->Phi();
+  signalContainer[3] = track->Charge()/3;
 
+ Double_t vertex[3]; // Production vertex cut to mask gammas which are NOT supposed to have hits in the first ITS layer(s)
+  if(IsESDanalysis()){
+    AliMCParticle *mctrack = dynamic_cast<AliMCParticle *>(track);
     vertex[0] = mctrack->Particle()->Vx();
     vertex[1] = mctrack->Particle()->Vy();
   } else {
     AliAODMCParticle *aodmctrack = dynamic_cast<AliAODMCParticle *>(track);
-    container[0] = aodmctrack->Pt();
-    container[1] = aodmctrack->Eta();
-    container[2] = aodmctrack->Phi();
-    container[3] = aodmctrack->Charge()/3;
-
-    signalContainer[0] = aodmctrack->Pt();
-    signalContainer[1] = aodmctrack->Eta();
-    signalContainer[2] = aodmctrack->Phi();
-    signalContainer[3] = aodmctrack->Charge()/3;
-
     aodmctrack->XvYvZv(vertex);
   }
-  Int_t signal = 0;
-  if((signal = IsSignalElectron(track))){
-    switch(signal){
-      case 1: container[4] = kSignalCharm; break;
-      case 2: container[4] = kSignalBeauty; break;
-    };
-  }else if(IsGammaElectron(track)) container[4] = kGammaConv;
-  else container[4] = kOther;
-
-  // weight
-  Double_t weight = 1.0;
-  if(fWeighting) weight = FindWeight(container[0],container[1],container[2]);
-
if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepMCGenerated, track)) return kFALSE;
- fQACollection->Fill("mccharge", signalContainer[3]);
- fCFM->GetParticleContainer()->Fill(container, AliHFEcuts::kStepMCGenerated,weight);
-  if((signalContainer[4] = static_cast<Double_t >(IsSignalElectron(track))) > 1e-3) fCFM->GetParticleContainer()->Fill(container, AliHFEcuts::kStepMCsignal,weight);
+
+  if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepMCGenerated, track)) return kFALSE;
+  fQACollection->Fill("mccharge", signalContainer[3]);
+  fVarManager->FillContainer(fContainer, "MCTrackCont", AliHFEcuts::kStepMCGenerated, kFALSE);
+  signalContainer[4] = 0;
+  if(fSignalCuts->IsSelected(track)){
+    //fVarManager->FillContainer(fContainer, "MCTrackCont", AliHFEcuts::kStepMCsignal, kFALSE);
+    // Filling of the Signal/Background histogram using the 
+    // definition of the codes for charm and beauty as below in
+    // th crearion of the histogram
+    if(fSignalCuts->IsCharmElectron(track))
+      signalContainer[4] = 1;
+    else 
     signalContainer[4] = 2;
+  } else {
+    signalContainer[4] = 0; // (and other background)
+  }
   signalContainer[5] = 0;
   // apply cut on the sqrt of the production vertex
   Double_t radVertex = TMath::Sqrt(vertex[0]*vertex[0] + vertex[1] * vertex[1]);
@@ -1118,41 +1059,22 @@ Bool_t AliAnalysisTaskHFE::ProcessMCtrack(AliVParticle *track){
   } else if (radVertex < 7.5){
     signalContainer[5] = 2;
   }
-  fSignalToBackgroundMC->Fill(signalContainer);
-  fQACollection->Fill("alpha_sim", container[2] - TMath::Pi());
-  //if(IsESDanalysis()){
-    if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepMCInAcceptance, track)) return kFALSE;
-    fCFM->GetParticleContainer()->Fill(container, AliHFEcuts::kStepMCInAcceptance,weight);
-  //}
+  fQACollection->Fill("SignalToBackgroundMC", signalContainer);
+  fQACollection->Fill("alpha_sim", track->Phi() - TMath::Pi());
+
+  // Step GeneratedZOutNoPileUp
+  if((fIdentifiedAsPileUp) || (fIdentifiedAsOutInz)) return kFALSE;
+  fVarManager->FillContainer(fContainer, "MCTrackCont", AliHFEcuts::kStepMCGeneratedZOutNoPileUp, kFALSE);
+
+  // Step Generated Event Cut
+  if(!fPassTheEventCut) return kFALSE;
+  fVarManager->FillContainer(fContainer, "MCTrackCont", AliHFEcuts::kStepMCGeneratedEventCut, kFALSE);
+
+  if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepMCInAcceptance, track)) return kFALSE;
+  fVarManager->FillContainer(fContainer, "MCTrackCont", AliHFEcuts::kStepMCInAcceptance, kFALSE);
   return kTRUE;
 }
 
-//____________________________________________________________
-void AliAnalysisTaskHFE::FilterTaggedTrack(AliESDtrack *track, Int_t species){
-  //
-  // Filter tracks tagged by V0 PID class
-  //
-  Int_t offset = AliHFEcuts::kStepRecKineITSTPC;
-  Double_t container[5] ={track->Pt(), track->Eta(), track->Phi(), track->Charge(), species};
-  fV0CF->GetParticleContainer()->Fill(container, 0); // Fill Container without filtering
-  Bool_t survived = kTRUE;
-  for(Int_t icut = AliHFEcuts::kStepRecKineITSTPC; icut < AliHFEcuts::kStepPID; icut++){
-    AliDebug(2, Form("Checking cut %d for species %s", icut, AliPID::ParticleName(species)));
-    if(!fV0CF->CheckParticleCuts(icut, track)){
-      survived = kFALSE;
-      break;
-    }
-    AliDebug(2, Form("Cut passed, filling container %d", icut - offset + 1));
-    fV0CF->GetParticleContainer()->Fill(container, icut - offset + 1);
-  }
-  if(survived){
-    // Apply PID
-    AliHFEpidObject hfetrack;
-    hfetrack.fAnalysisType = AliHFEpidObject::kESDanalysis;
-    hfetrack.fRecTrack = track;
-    if(fPIDtagged->IsSelected(&hfetrack)) fV0CF->GetParticleContainer()->Fill(container, AliHFEcuts::kStepPID - offset + 1); 
-  } 
-}
 //____________________________________________________________
 Bool_t AliAnalysisTaskHFE::PreSelectTrack(AliESDtrack *track) const {
   //
@@ -1186,8 +1108,8 @@ Bool_t AliAnalysisTaskHFE::PreSelectTrack(AliESDtrack *track) const {
   if(survived){
     // Apply PID
     AliHFEpidObject hfetrack;
-    hfetrack.fAnalysisType = AliHFEpidObject::kESDanalysis;
-    hfetrack.fRecTrack = track;
+    hfetrack.SetAnalysisType(AliHFEpidObject::kESDanalysis);
+    hfetrack.SetRecTrack(track);
     if(!fPIDpreselect->IsSelected(&hfetrack)) {
       //printf("Did not pass AliHFEcuts::kPID\n");
       survived = kFALSE;
@@ -1202,11 +1124,14 @@ Bool_t AliAnalysisTaskHFE::PreSelectTrack(AliESDtrack *track) const {
 void AliAnalysisTaskHFE::MakeEventContainer(){
   //
   // Create the event container for the correction framework and link it
+  // 1st bin: Vertex z-position
+  // 2nd bin: V0AND decision (normalization to sigma_inel)
+  // 3rd bin: Centrality class (for pp defined as 99.)
   //
-  const Int_t kNvar = 2;  // number of variables on the grid: 
-  Int_t nBins[kNvar] = {120, 2};
-  Double_t binMin[kNvar] = {-30. , 0.};
-  Double_t binMax[kNvar] = {30., 2.};
+  const Int_t kNvar = 3;  // number of variables on the grid: 
+  Int_t nBins[kNvar] = {120, 2, 20};
+  Double_t binMin[kNvar] = {-30. , 0., 0.};
+  Double_t binMax[kNvar] = {30., 2., 100};
 
   AliCFContainer *evCont = new AliCFContainer("eventContainer", "Container for events", AliHFEcuts::kNcutStepsEvent, kNvar, nBins);
 
@@ -1225,111 +1150,57 @@ void AliAnalysisTaskHFE::MakeParticleContainer(){
   // Create the particle container for the correction framework manager and 
   // link it
   //
-  const Int_t kNvar   = 5;
-  //number of variables on the grid:pt,eta, phi, charge
-  const Double_t kPtbound[2] = {0.1, 20.};
-  const Double_t kEtabound[2] = {-0.8, 0.8};
-  const Double_t kPhibound[2] = {0., 2. * TMath::Pi()};
-
-  //arrays for the number of bins in each dimension
-  Int_t iBin[kNvar];
-  iBin[0] = 44; // bins in pt
-  iBin[1] =  8; // bins in eta 
-  iBin[2] = 18; // bins in phi
-  iBin[3] =  2; // bins in charge
-  iBin[4] =  4; // creation process of the electron
-
-  //arrays for lower bounds :
-  Double_t* binEdges[kNvar];
-  binEdges[0] = AliHFEtools::MakeLogarithmicBinning(iBin[0], kPtbound[0], kPtbound[1]);
-  binEdges[1] = AliHFEtools::MakeLinearBinning(iBin[1], kEtabound[0], kEtabound[1]);
-  binEdges[2] = AliHFEtools::MakeLinearBinning(iBin[2], kPhibound[0], kPhibound[1]);
-  binEdges[3] = AliHFEtools::MakeLinearBinning(iBin[3], -1.1, 1.1); // Numeric precision
-  binEdges[4] = AliHFEtools::MakeLinearBinning(iBin[4], 0, iBin[4]); // Numeric precision
-  //for(Int_t ib = 0; ib <= iBin[4]; ib++) printf("%f\t", binEdges[4][ib]);
-  //printf("\n");
-
-  //one "container" for MC
-  AliCFContainer* container = new AliCFContainer("trackContainer", "Container for tracks", (AliHFEcuts::kNcutStepsTrack + 2*AliHFEcuts::kNcutStepsESDtrack), kNvar, iBin);
-  fHadronicBackground = new AliCFContainer("hadronicBackground", "Container for hadronic Background", 2, kNvar, iBin);
-
-  //setting the bin limits
-  for(Int_t ivar = 0; ivar < kNvar; ivar++){
-    container -> SetBinLimits(ivar, binEdges[ivar]);
-    fHadronicBackground -> SetBinLimits(ivar, binEdges[ivar]);
+  
+  if(!fContainer) fContainer = new AliHFEcontainer("trackContainer");
+  fVarManager->DefineVariables(fContainer);
+
+  // Create Correction Framework containers
+  fContainer->CreateContainer("MCTrackCont", "Track Container filled with MC information", AliHFEcuts::kNcutStepsMCTrack);
+  fContainer->CreateContainer("recTrackContReco", "Track Container filled with MC information", AliHFEcuts::kNcutStepsRecTrack + fPID->GetNumberOfPIDdetectors());
+  fContainer->CreateContainer("recTrackContMC", "Track Container filled with MC information", AliHFEcuts::kNcutStepsRecTrack + fPID->GetNumberOfPIDdetectors());
+  
+  fContainer->CreateContainer("hadronicBackground", "Container for Hadronic Background", 3);
+  fContainer->CreateContainer("recTrackContDEReco", "Container for displaced electron analysis with Reco information", 1);
+  fContainer->CreateContainer("recTrackContDEMC", "Container for displaced electron analysis with MC information", 1);
+  fContainer->CreateCorrelationMatrix("correlationstepafterPID","THnSparse with correlations");
+  fContainer->CreateCorrelationMatrix("correlationstepafterDE","THnSparse with correlations");
+
+  // Define the step names
+  for(UInt_t istep = 0; istep < AliHFEcuts::kNcutStepsMCTrack; istep++){
+    fContainer->SetStepTitle("MCTrackCont", AliHFEcuts::MCCutName(istep), istep);
   }
-  fCFM->SetParticleContainer(container);
-
-  //create correlation matrix for unfolding
-  Int_t thnDim[2*kNvar];
-  for (int k=0; k<kNvar; k++) {
-    //first half  : reconstructed 
-    //second half : MC
-    thnDim[k]      = iBin[k];
-    thnDim[k+kNvar] = iBin[k];
+  for(UInt_t istep = 0; istep < AliHFEcuts::kNcutStepsRecTrack; istep++){
+    fContainer->SetStepTitle("recTrackContReco", AliHFEcuts::RecoCutName(istep), istep);
+    fContainer->SetStepTitle("recTrackContMC", AliHFEcuts::RecoCutName(istep), istep);
   }
-
-  if(!fCorrelation) fCorrelation = new TList();
-  fCorrelation->SetName("correlation");
-
-  THnSparseF *correlation0 = new THnSparseF("correlationstepbeforePID","THnSparse with correlations",2*kNvar,thnDim);
-  THnSparseF *correlation1 = new THnSparseF("correlationstepafterPID","THnSparse with correlations",2*kNvar,thnDim);
-  for (int k=0; k<kNvar; k++) {
-    correlation0->SetBinEdges(k,binEdges[k]);
-    correlation0->SetBinEdges(k+kNvar,binEdges[k]);
-    correlation1->SetBinEdges(k,binEdges[k]);
-    correlation1->SetBinEdges(k+kNvar,binEdges[k]);
+  for(UInt_t ipid = 0; ipid < fPID->GetNumberOfPIDdetectors(); ipid++){
+    fContainer->SetStepTitle("recTrackContReco", fPID->SortedDetectorName(ipid), AliHFEcuts::kNcutStepsRecTrack + ipid);
+    fContainer->SetStepTitle("recTrackContMC", fPID->SortedDetectorName(ipid), AliHFEcuts::kNcutStepsRecTrack + ipid);
   }
-  correlation0->Sumw2();
-  correlation1->Sumw2();
-  
-  fCorrelation->AddAt(correlation0,0);
-  fCorrelation->AddAt(correlation1,1);
-  
+}
+
+//____________________________________________________________
+void AliAnalysisTaskHFE::InitPIDperformanceQA(){
   // Add a histogram for Fake electrons
   const Int_t nDim=6;
   Int_t nBin[nDim] = {40, 8, 18, 2, 3, 3};
-  Double_t* binEdges2[nDim];
-
-  //values for bin lower bounds
-  for(Int_t ivar = 0; ivar < kNvar; ivar++)
-    binEdges2[ivar] = binEdges[ivar];
-  binEdges2[4] = AliHFEtools::MakeLinearBinning(nBin[4], 0, nBin[4]);
-  binEdges2[5] = AliHFEtools::MakeLinearBinning(nBin[5], 0, nBin[5]);
-
-  fPIDperformance = new THnSparseF("PIDperformance", "PID performance; pT [GeV/c]; theta [rad]; phi [rad]; charge; type (0 - not el, 1 - other el, 2 - HF el; flavor (0 - no, 1 - charm, 2 - bottom)", nDim, nBin);
-  fPIDperformance->Sumw2();
-  fSignalToBackgroundMC = new THnSparseF("SignalToBackgroundMC", "PID performance; pT [GeV/c]; theta [rad]; phi [rad]; charge; flavor (0 - no, 1 - charm, 2 - bottom); ITS Cluster (0 - no, 1 - first (and maybe second), 2 - second)", nDim, nBin);
-  fSignalToBackgroundMC->Sumw2();
-  for(Int_t idim = 0; idim < nDim; idim++){
-    fPIDperformance->SetBinEdges(idim, binEdges2[idim]);
-    fSignalToBackgroundMC->SetBinEdges(idim, binEdges2[idim]); 
-  }
-
-  // create correction framework container for V0-tagged particles, new bin limits in 4th bin
-  iBin[4] = 5;
-  delete binEdges[4];
-  binEdges[4] = AliHFEtools::MakeLinearBinning(iBin[4], 0, iBin[4]); // Numeric precision
-  AliCFContainer *tagged = new AliCFContainer("taggedTrackContainer", "Correction Framework Container for tagged tracks", AliHFEcuts::kNcutStepsESDtrack, kNvar, iBin);
-  for(Int_t ivar = 0; ivar < kNvar; ivar++)
-    tagged->SetBinLimits(ivar, binEdges[ivar]);
-  fV0CF->SetParticleContainer(tagged);
-
-  for(Int_t ivar = 0; ivar < kNvar; ivar++)
-    delete binEdges[ivar];
-  for(Int_t ivar = kNvar; ivar < nDim; ivar++)
-    delete binEdges2[ivar];
-}
+  //number of variables on the grid:pt,eta,phi,charge,
+  const Double_t kPtbound[2] = {0.1, 20.};
+  const Double_t kEtabound[2] = {-0.8, 0.8};
+  const Double_t kPhibound[2] = {0., 2. * TMath::Pi()}; 
+  const Double_t kChargebound[2] = {-1.1, 1.1};
+  const Double_t kAddInf1bound[2] = {0., 3.};
+  const Double_t kAddInf2bound[2] = {0., 3.};
+  Double_t minima[nDim] = {kPtbound[0], kEtabound[0], kPhibound[0], kChargebound[0], kAddInf1bound[0], kAddInf2bound[0]}; 
+  Double_t maxima[nDim] = {kPtbound[1], kEtabound[1], kPhibound[1], kChargebound[1], kAddInf1bound[1], kAddInf2bound[1]}; 
+  
+  fQACollection->CreateTHnSparse("PIDperformance", "PID performance; pT [GeV/c]; theta [rad]; phi [rad]; charge; type (0 - not el, 1 - other el, 2 - HF el; flavor (0 - no, 1 - charm, 2 - bottom)", nDim, nBin, minima, maxima);
+  fQACollection->CreateTHnSparse("SignalToBackgroundMC", "PID performance; pT [GeV/c]; theta [rad]; phi [rad]; charge; flavor (0 - no, 1 - charm, 2 - bottom); ITS Cluster (0 - no, 1 - first (and maybe second), 2 - second)", nDim, nBin, minima, maxima);
 
-//____________________________________________________________
-void AliAnalysisTaskHFE::AddPIDdetector(TString detector){
-  //
-  // Adding PID detector to the task
-  //
-  if(!fPIDdetectors.Length()) 
-    fPIDdetectors = detector;
-  else
-    fPIDdetectors += ":" + detector;
+  fQACollection->BinLogAxis("PIDperformance", 0);
+  fQACollection->BinLogAxis("SignalToBackgroundMC", 0);
+  fQACollection->Sumw2("PIDperformance");
+  fQACollection->Sumw2("SignalToBackgroundMC");
 }
 
 //____________________________________________________________
@@ -1340,11 +1211,11 @@ void AliAnalysisTaskHFE::PrintStatus() const {
   printf("\n\tAnalysis Settings\n\t========================================\n\n");
   printf("\tSecondary Vertex finding: %s\n", GetPlugin(kSecVtx) ? "YES" : "NO");
   printf("\tPrimary Vertex resolution: %s\n", GetPlugin(kPriVtx) ? "YES" : "NO");
+  printf("\tDisplaced electron analysis step: %s\n", GetPlugin(kDEstep) ? "YES" : "NO");
+  printf("\tTagged Track Analysis: %s\n", GetPlugin(kTaggedTrackAnalysis) ? "YES" : "NO");
   printf("\n");
   printf("\tParticle Identification Detectors:\n");
-  TObjArray *detectors = fPIDdetectors.Tokenize(":");
-  for(Int_t idet = 0; idet < detectors->GetEntries(); idet++)
-    printf("\t\t%s\n", (dynamic_cast<TObjString *>(detectors->At(idet)))->String().Data());
+  fPID->PrintStatus();
   printf("\n");
   printf("\tQA: \n");
   printf("\t\tPID: %s\n", IsQAOn(kPIDqa) ? "YES" :  "NO");
@@ -1353,147 +1224,6 @@ void AliAnalysisTaskHFE::PrintStatus() const {
   printf("\n");
 }
 
-//____________________________________________________________
-AliAnalysisTaskHFE::LabelContainer::LabelContainer(Int_t capacity):
-  fContainer(NULL),
-  fBegin(NULL),
-  fEnd(NULL),
-  fLast(NULL),
-  fCurrent(NULL)
-{
-  //
-  // Default constructor
-  //
-  fContainer = new Int_t[capacity];
-  fBegin = &fContainer[0];
-  fEnd = &fContainer[capacity - 1];
-  fLast = fCurrent = fBegin;
-}
-
-//____________________________________________________________
-Bool_t AliAnalysisTaskHFE::LabelContainer::Append(Int_t label){
-  //
-  // Add Label to the container
-  //
-  if(fLast > fEnd) return kFALSE;
-  *fLast++ = label;
-  return kTRUE;
-}
-
-//____________________________________________________________
-Bool_t AliAnalysisTaskHFE::LabelContainer::Find(Int_t label) const {
-  //
-  // Find track in the list of labels
-  //
-  for(Int_t *entry = fBegin; entry <= fLast; entry++) 
-    if(*entry == label) return kTRUE;
-  return kFALSE;
-}
-
-//____________________________________________________________
-Int_t AliAnalysisTaskHFE::LabelContainer::Next(){
-  //
-  // Mimic iterator
-  //
-  if(fCurrent > fLast) return -1; 
-  return *fCurrent++;
-}
-
-//____________________________________________________________
-Int_t AliAnalysisTaskHFE::IsSignalElectron(const AliVParticle * const track) const{
-  //
-  // Checks whether the identified electron track is coming from heavy flavour
-  // returns 0 in case of no signal, 1 in case of charm and 2 in case of Bottom
-  //
-  enum{
-    kNoSignal = 0,
-    kCharm = 1,
-    kBeauty = 2
-  };
-
-  if(!fMCEvent) return kNoSignal;
-  const AliVParticle *motherParticle = NULL, *mctrack = NULL;
-  TString objectType = track->IsA()->GetName();
-  Int_t label = 0;
-  if(objectType.CompareTo("AliESDtrack") == 0 || objectType.CompareTo("AliAODTrack") == 0){
-    // Reconstructed track
-    if((label = TMath::Abs(track->GetLabel())) && label < fMCEvent->GetNumberOfTracks())
-      mctrack = fMCEvent->GetTrack(label);
-  } else {
-    // MCParticle
-    mctrack = track;
-  }
-
-  if(!mctrack) return kNoSignal;
-  
-  Int_t pid = 0;
-  Int_t daughterPDG = 0, motherLabel = 0;
-  if(TString(mctrack->IsA()->GetName()).CompareTo("AliMCParticle") == 0){
-    // case MC Particle
-    daughterPDG = TMath::Abs((dynamic_cast<const AliMCParticle *>(mctrack))->Particle()->GetPdgCode());
-    motherLabel = (dynamic_cast<const AliMCParticle *>(mctrack))->Particle()->GetFirstMother();
-    if(motherLabel >= 0 && motherLabel < fMCEvent->GetNumberOfTracks())
-      motherParticle = fMCEvent->GetTrack(motherLabel);
-    if(motherParticle)
-      pid = TMath::Abs((dynamic_cast<const AliMCParticle *>(motherParticle))->Particle()->GetPdgCode());
-  } else {
-    // case AODMCParticle
-    daughterPDG = TMath::Abs((dynamic_cast<const AliAODMCParticle *>(mctrack))->GetPdgCode());
-    motherLabel = (dynamic_cast<const AliAODMCParticle *>(mctrack))->GetMother();
-    if(motherLabel >= 0 && motherLabel < fMCEvent->GetNumberOfTracks())
-      motherParticle = fMCEvent->GetTrack(motherLabel);
-    if(motherParticle)
-      pid = TMath::Abs((dynamic_cast<const AliAODMCParticle *>(motherParticle))->GetPdgCode());
-  }
-  AliDebug(5, Form("Daughter PDG code: %d", daughterPDG));
-
-  if(!pid) return kNoSignal;
-
-  // From here the two analysis modes go together
-  AliDebug(5, Form("Mother PDG code: %d", pid));
-
-  // identify signal according to Pdg Code - barions higher ranked than mesons 
-  if(pid / 1000 == 4) return kCharm;            // charmed baryon, 4th position in pdg code == 4
-  if(pid / 1000 == 5) return kBeauty;           // beauty baryon, 4th position in pdg code == 5   
-  if((pid % 1000) / 100 == 4) return kCharm;    // charmed meson, 3rd position in pdg code == 4
-  if((pid % 1000) / 100 == 5) return kBeauty;   // beauty meson, 3rd position in pdg code == 5
-  return kNoSignal;
-}
-
-//__________________________________________
-Bool_t AliAnalysisTaskHFE::IsGammaElectron(const AliVParticle * const track) const {
-  //
-  // Check for MC if the electron is coming from Gamma
-  //
-  if(!fMCEvent) return kFALSE;
-  const AliVParticle *motherParticle = NULL, *mctrack = NULL;
-  TString objectType = track->IsA()->GetName();
-  if(objectType.CompareTo("AliESDtrack") == 0 || objectType.CompareTo("AliAODTrack") == 0){
-    // Reconstructed track
-    if(track->GetLabel())
-      mctrack = fMCEvent->GetTrack(TMath::Abs(track->GetLabel()));
-  } else {
-    // MCParticle
-    mctrack = track;
-  }
-
-  if(!mctrack) return kFALSE;
-  
-  Int_t motherPDG = 0;
-  if(TString(mctrack->IsA()->GetName()).CompareTo("AliMCParticle") == 0){
-    // case MC Particle
-    motherParticle = fMCEvent->GetTrack((dynamic_cast<const AliMCParticle *>(mctrack)->Particle()->GetFirstMother()));
-    if(motherParticle)
-      motherPDG = TMath::Abs((dynamic_cast<const AliMCParticle *>(motherParticle))->Particle()->GetPdgCode());
-  } else {
-    // case AODMCParticle
-    motherParticle = fMCEvent->GetTrack((dynamic_cast<const AliAODMCParticle *>(mctrack))->GetMother());
-    if(motherParticle)
-      motherPDG = TMath::Abs((dynamic_cast<const AliAODMCParticle *>(motherParticle))->GetPdgCode());
-  }
-  if(motherPDG!=22) return kFALSE;
-  else return kTRUE;
-}
 //____________________________________________________________
 Bool_t AliAnalysisTaskHFE::FillProductionVertex(const AliVParticle * const track) const{
   //
@@ -1546,71 +1276,103 @@ void AliAnalysisTaskHFE::SwitchOnPlugin(Int_t plug){
     case kSecVtx: SETBIT(fPlugins, plug); break;
     case kIsElecBackGround: SETBIT(fPlugins, plug); break;
     case kPostProcess: SETBIT(fPlugins, plug); break;
+    case kDEstep: SETBIT(fPlugins, plug); break;
+    case kTaggedTrackAnalysis: SETBIT(fPlugins, plug); break;
     default: AliError("Unknown Plugin");
   };
 }
-//_______________________________________________
-void AliAnalysisTaskHFE::SetWeightFactors(TH3D * const weightFactors){
-  //
-  // Set the histos with the weights for the efficiency maps
-  //
-  fWeighting = kTRUE;
-  fWeightFactors = weightFactors;
-}
-//_______________________________________________
-void AliAnalysisTaskHFE::SetWeightFactorsFunction(TF1 * const weightFactorsFunction){
-  //
-  // Set the histos with the weights for the efficiency maps
-  //
-  fWeighting = kTRUE;
-  fWeightFactorsFunction = weightFactorsFunction;
-  //printf("SetWeightFactors\n");
-}
-//_______________________________________________
-Double_t AliAnalysisTaskHFE::FindWeight(Double_t pt, Double_t eta, Double_t phi) const {
-  //
-  // Find the weight corresponding to pt eta and phi in the TH3D
-  //
-  Double_t weight = 1.0;
-  if(fWeightFactors) {
-    
-    TAxis *ptaxis = fWeightFactors->GetXaxis();
-    TAxis *etaaxis = fWeightFactors->GetYaxis();
-    TAxis *phiaxis = fWeightFactors->GetZaxis();
-    
-    Int_t ptbin = ptaxis->FindBin(pt);
-    Int_t etabin = etaaxis->FindBin(eta);
-    Int_t phibin = phiaxis->FindBin(phi);
-
-
-    weight = fWeightFactors->GetBinContent(ptbin,etabin,phibin);
-  }
-  else if(fWeightFactorsFunction) {
-    
-    weight = fWeightFactorsFunction->Eval(pt,eta,phi);
-    //printf("pt %f and weight %f\n",pt,weight);
-
-  }
-
-  //printf("pt %f, eta %f, phi %f, weight %f\n",pt,eta,phi,weight);
-  
-  return weight;  
-
-}
 //__________________________________________
-Bool_t AliAnalysisTaskHFE::ProcessCutStep(Int_t cutStep, AliVParticle *track, Double_t *container, Bool_t signal, Bool_t alreadyseen,Double_t weight){
+Bool_t AliAnalysisTaskHFE::ProcessCutStep(Int_t cutStep, AliVParticle *track){
   //
   // Check single track cuts for a given cut step
   // Fill the particle container
   //
-  if(!fCFM->CheckParticleCuts(cutStep, track)) return kFALSE;
-  if(signal) {
-    fCFM->GetParticleContainer()->Fill(container, cutStep + 2*AliHFEcuts::kNcutStepsESDtrack,weight);
-    fCFM->GetParticleContainer()->Fill(&container[5], cutStep,weight);
-    if(alreadyseen) {
-      fCFM->GetParticleContainer()->Fill(&container[5], cutStep + AliHFEcuts::kNcutStepsESDtrack,weight);
-    }
+  const Int_t kMCOffset = AliHFEcuts::kNcutStepsMCTrack;
+  if(!fCFM->CheckParticleCuts(cutStep + kMCOffset, track)) return kFALSE;
+  if(fVarManager->IsSignalTrack()) {
+    fVarManager->FillContainer(fContainer, "recTrackContReco", cutStep, kFALSE);
+    fVarManager->FillContainer(fContainer, "recTrackContMC", cutStep, kTRUE);
   }
   return kTRUE;
 }
+//___________________________________________________
+void AliAnalysisTaskHFE::ReadCentrality() {
+  //
+  // Recover the centrality of the event from ESD or AOD
+  //
+ if(IsAODanalysis()){
+
+   AliAODEvent *fAOD = dynamic_cast<AliAODEvent *>(fInputEvent);
+   if(!fAOD){
+     AliError("AOD Event required for AOD Analysis")
+       return;
+   }
+   // Centrality
+   //AliAODCentrality *aodCentrality = fAOD->GetCentrality();
+   //Double_t fCentralityF = aodCentrality->GetCentralityPercentile("V0M");
+   fCentralityF = 99.0; // Fake for the moment
+   
+   
+ } else {
+   
+   AliDebug(3, "Processing ESD Centrality");
+   AliESDEvent *fESD = dynamic_cast<AliESDEvent *>(fInputEvent);
+   if(!fESD){
+     AliError("ESD Event required for ESD Analysis")
+       return;
+   }
+   // Centrality
+  AliESDCentrality *esdCentrality = fESD->GetCentrality();
+  fCentralityF = esdCentrality->GetCentralityPercentile("V0M");
+
+  //printf("centrality %f\n",fCentralityF);
+
+ }
+
+}
+//___________________________________________________
+void AliAnalysisTaskHFE::RejectionPileUpVertexRangeEventCut() {
+  //
+  // Recover the centrality of the event from ESD or AOD
+  //
+ if(IsAODanalysis()){
+
+   AliAODEvent *fAOD = dynamic_cast<AliAODEvent *>(fInputEvent);
+   if(!fAOD){
+     AliError("AOD Event required for AOD Analysis")
+       return;
+   }
+   // PileUp
+   if(fRemovePileUp && fAOD->IsPileupFromSPD()) fIdentifiedAsPileUp = kTRUE; 
+   // Z vertex
+   if(TMath::Abs(fAOD->GetPrimaryVertex()->GetZ()) > fCuts->GetVertexRange()) fIdentifiedAsOutInz = kTRUE;
+   // Event Cut
+   fPassTheEventCut = kTRUE;
+   if(!fCFM->CheckEventCuts(AliHFEcuts::kEventStepReconstructed, fAOD)) fPassTheEventCut = kFALSE; 
+   
+   
+ } else {
+   
+   AliDebug(3, "Processing ESD Centrality");
+   AliESDEvent *fESD = dynamic_cast<AliESDEvent *>(fInputEvent);
+   if(!fESD){
+     AliError("ESD Event required for ESD Analysis")
+       return;
+   }
+   // PileUp
+   fIdentifiedAsPileUp = kFALSE;
+   if(fRemovePileUp && fESD->IsPileupFromSPD()) fIdentifiedAsPileUp = kTRUE; 
+   // Z vertex
+   fIdentifiedAsOutInz = kFALSE;
+   if(fESD->GetPrimaryVertexTracks()){
+     if(TMath::Abs(fESD->GetPrimaryVertexTracks()->GetZ()) > fCuts->GetVertexRange()) fIdentifiedAsOutInz = kTRUE;
+   }
+   //Event Cut
+   fPassTheEventCut = kTRUE;
+   if(!fCFM->CheckEventCuts(AliHFEcuts::kEventStepReconstructed, fESD)) fPassTheEventCut = kFALSE;   
+  
+
+ }
+
+}
 
index cef17b12a5b4feb22b4e938938a09b76d1df34a7..10d0f28371cf773882acade99fe6266a51f64dc5 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 30014269154d8a96d390bc87c7fc10e64a80ca82..e219cb66f90deff90c2b9943aec361b22ea25a5c 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 65a8dc9bc0a7361d481e287dacc0f15cb11a1ced..82bcdbf886bcd6356be882f79257641288f7acaf 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 a2b1eed78166519c6b6407a8eb215348e224191e..658fe1f7719c88b952c74af7fd9071fd2c47cee2 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);
@@ -448,6 +604,124 @@ Bool_t AliHFEV0pid::IsLambda(TObject *v0){
   return kTRUE;
 }
 
+//____________________________________________________________
+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)
@@ -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 8d66402d16341398f594e537874248ea3d5a0496..188ec8ce330cbee66df935b5a8b33a59dac7fe34 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 517890a8f5960212dcebb85f886819ae9c0aeb20..6ca9d1b6f9d0fa104be7654e13b63ef0a476bdee 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 ae8c5e4b4977b7d67c0fa30ce9d292d313757208..b0d57a135f2304ec210cc770da96dc5bbf4d5c6c 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 3f673b34637df3ef6e697c41560494a5bffe8753..5d2e4a999443a7a5fb371f0ef5dcd9596d912492 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 39dab143e9206ef373b39c3558a2de0c965bc5aa..6353b2983cb44d6bd27d1847c080054e3bf9208e 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 5c0b0bfb7e90b6750e44b1652dbdd31c5f85f92a..8abea8d63ed4de81690b4d0722c19a31b05bf530 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 7977614cc14eaa2171026f8155fed9639bc1dfa3..918b0d23a1c38406a37defb4d8a403d6589f2819 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 f9cd83e458b0c9e2c8bcd35ac7cd53d7af09d236..29a537e55bd08f7c364ad669a6740d5564fbf609 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 4db447a027ade879ddec2d660ce76b1299ec5565..0f5467141d388b133d77fe4bd25c6423fb3bd3c3 100644 (file)
@@ -37,27 +37,33 @@ 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 d12813349acf67cab9ed3294ce84517474a12551..54c6ec83b581687e912820a9a295d23d584f73db 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 6de6d7eff231088d5b2959a61a0255eb41bdfe98..ff2f53a92633e1aa3da972bef43c4ab071d60010 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 8306241e340e7b2f3691889546c038515657e650..bb68be70b47852ff3fe49d9ac53712af6fe6d77c 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 41cd38572cbbcf4d396d7dafdfd4431a45337eb2..ed0e7c036e2e96c2b62a5bdacae9d7b199030bf2 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 58695d40beaab6630f1f153f16736fdb141a0564..d912ba370271bb2de9c9a280a37d9c9885ef32d3 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
@@ -138,9 +159,25 @@ void AliHFEextraCuts::SetMaxImpactParamZ(Double_t impactParam){
   fImpactParamCut[3] = 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 c5130371f8cd335ccf975cc989f12e6fae0e4ea1..87858fd4c220d7189073cecc1b67e0ba9f2b0202 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 31257d560d88e7525978c04a80752846e5b0b27c..1ff61a908475fe03aea29158350cb56519517382 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 6dd0d8c45671eeb889c6414023ed23c4893fa42f..ea568cdc55dbff76af3e9e73f89be5f5801c4c66 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 2da8eb52a69eda53786e784cae00a94ff87b51ef..6ba2e4bd7824bf3586e107a24567866eba3f74b1 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));
+}
+
index 99670098a4dba0d636ceebf83e5f1e6a1a7f1648..720e8fb8218b3f98ebfd3acdd4198e09cb96b8ad 100644 (file)
  #endif
 
 class TList;
+class AliAODpidUtil;
 class AliESDpid;
 class AliVParticle;
 class AliMCParticle;
+class AliHFEpidQAmanager;
 
-struct AliHFEpidObject{
+class AliHFEpidObject{
+  public:
     typedef enum{ 
       kESDanalysis,
       kAODanalysis
     }AnalysisType_t;
-    AliVParticle *fRecTrack;    // Reconstructed track
-    AliVParticle *fMCtrack;     // Monte Carlo track
+    AliHFEpidObject():
+      fkRecTrack(NULL), 
+      fAnalysisType(kESDanalysis),
+      fAbInitioPID(-1),
+      fCentrality(99.)
+      {
+      }
+    AliHFEpidObject(const AliHFEpidObject &ref):
+      fkRecTrack(ref.fkRecTrack), 
+      fAnalysisType(ref.fAnalysisType),
+      fAbInitioPID(ref.fAbInitioPID),
+      fCentrality(ref.fCentrality)
+      {
+      }
+    AliHFEpidObject &operator=(const AliHFEpidObject &ref);
+    ~AliHFEpidObject(){};
+
+    void SetRecTrack(const AliVParticle * recTrack) {fkRecTrack = recTrack; }
+    void SetMCTrack(const AliVParticle * mcTrack);
+    void SetAnalysisType(AnalysisType_t type) { fAnalysisType = type; }
+    void SetAbInitioPID(Int_t abInitioPID) { fAbInitioPID = abInitioPID; }
+    void SetCentrality(Float_t centrality) { fCentrality = centrality; }
+
+    const AliVParticle *GetRecTrack() const { return fkRecTrack; }
+    Int_t GetAbInitioPID() const { return fAbInitioPID; }
+    Float_t GetCentrality() const { return fCentrality; }
+    Bool_t IsAODanalysis() const { return fAnalysisType == static_cast<UChar_t>(kAODanalysis); }
+    Bool_t IsESDanalysis() const { return fAnalysisType == static_cast<UChar_t>(kESDanalysis); }
+
+  private:
+    const AliVParticle *fkRecTrack;    // Reconstructed track
     UChar_t fAnalysisType;      // Analysis Mode (ESD or AOD)
-    AliHFEpidObject():fRecTrack(NULL), fMCtrack(NULL), fAnalysisType(kESDanalysis){}
+    Int_t fAbInitioPID;         // AbInitio PID
+    Float_t fCentrality;        // Centrality Information
 };
 
 class AliHFEpidBase : public TNamed{
@@ -48,41 +81,24 @@ class AliHFEpidBase : public TNamed{
     virtual ~AliHFEpidBase() {};
     // Framework functions that have to be implemented by the detector PID classes
     virtual Bool_t InitializePID() = 0;
-    virtual Int_t IsSelected(AliHFEpidObject *track) = 0;
-    virtual Bool_t HasQAhistos() const = 0;
+    virtual Int_t IsSelected(AliHFEpidObject *track, AliHFEpidQAmanager *pidqa = NULL) = 0;
 
-    Int_t GetDebugLevel() const { return fDebugLevel; };
-    Bool_t IsQAon() const { return TestBit(kQAon);};
     Bool_t HasMCData() const { return TestBit(kHasMCData); };
 
     void SetESDpid(AliESDpid * const pid) { fESDpid = pid; }
-    void SetDebugLevel(Int_t debugLevel) { fDebugLevel = debugLevel; }; 
-    inline void SetQAOn(TList *fQAlist);
+    void SetAODpid(AliAODpidUtil * const pid) { fAODpid = pid; }
     void SetHasMCData(Bool_t hasMCdata = kTRUE) { SetBit(kHasMCData,hasMCdata); };
 
   protected:
     AliESDpid *fESDpid;                         // ESD PID object
+    AliAODpidUtil *fAODpid;                     // AOD PID object
     void Copy(TObject &ref) const;
-    virtual void AddQAhistograms(TList *){};
+
   private:
     enum{
-      kQAon = BIT(14),
-      kHasMCData = BIT(15)
+      kHasMCData = BIT(14)
     };
 
-    Int_t fDebugLevel;              // Debug Level
-
-    ClassDef(AliHFEpidBase, 1)      // Base class for detector Electron ID
+    ClassDef(AliHFEpidBase, 2)      // Base class for detector Electron ID
 };
-
-//___________________________________________________________________
-void AliHFEpidBase::SetQAOn(TList *qaList){
-  //
-  // Initialize QA for Detector PID class
-  //
-  if(HasQAhistos()){
-    SetBit(kQAon, kTRUE);
-    AddQAhistograms(qaList);
-  }
-}
 #endif
index ecd215c75c64e463b23a4d18f3e1cc74c0c54244..8b9bc84cd8712564c2979833fc99e591e34ca285 100644 (file)
 
 #include "AliHFEpidITS.h"
 
+ClassImp(AliHFEpidITS)
+
 //___________________________________________________________________
 AliHFEpidITS::AliHFEpidITS(const Char_t *name):
     AliHFEpidBase(name)
-  , fQAlist(0x0)
 {
   //
   // Default constructor
@@ -47,7 +48,6 @@ AliHFEpidITS::AliHFEpidITS(const Char_t *name):
 //___________________________________________________________________
 AliHFEpidITS::AliHFEpidITS(const AliHFEpidITS &ref):
     AliHFEpidBase("")
-  , fQAlist(0x0)
 {
   //
   // Copy constructor
@@ -69,10 +69,6 @@ AliHFEpidITS::~AliHFEpidITS(){
   //
   // Destructor
   //
-  if(fQAlist){
-    fQAlist->Clear();
-    delete fQAlist;
-  }
 }
 
 //___________________________________________________________________
@@ -81,10 +77,7 @@ void AliHFEpidITS::Copy(TObject &o) const {
   // Copy function
   // Provides a deep copy
   //
-  AliHFEpidITS &target = dynamic_cast<AliHFEpidITS &>(o);
-
-  target.fQAlist = dynamic_cast<TList *>(fQAlist->Clone());
-  AliHFEpidBase::Copy(target);
+  AliHFEpidBase::Copy(o);
 }
 
 //___________________________________________________________________
@@ -97,7 +90,7 @@ Bool_t AliHFEpidITS::InitializePID(){
 
 
 //___________________________________________________________________
-Int_t AliHFEpidITS::IsSelected(AliHFEpidObject* /*track*/){
+Int_t AliHFEpidITS::IsSelected(AliHFEpidObject* /*track*/, AliHFEpidQAmanager* /*pidqa*/){
   //
   // Does PID decision for ITS
   // 
@@ -105,42 +98,11 @@ Int_t AliHFEpidITS::IsSelected(AliHFEpidObject* /*track*/){
 }
 
 //___________________________________________________________________
-void AliHFEpidITS::AddQAhistograms(TList *l){
-  //
-  // Adding QA histograms for ITS PID
-  //
-  // QA histograms are:
-  // - all Particles ITS signal vs. p (both methods)
-  // - single particle ITS signal vs. p (both methods)
-  // 
-  if(!fQAlist) fQAlist = new TList;
-  fQAlist->SetName("fITSqaHistograms");
-
-  // prepare axis
-  const Int_t kMomentumBins = 41;
-  const Double_t kPtMin = 0.1;
-  const Double_t kPtMax = 10.;
-  const Int_t kSigBins = 300;
-  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)));
-
-  TH2 *histo = NULL;
-  fQAlist->AddAt((histo = new TH2F("fITSsigV1all", "ITS signal vs. p (all species, Method1):p / GeV/c:ITS signal / a.u.", kMomentumBins - 1, momentumBins, kSigBins, 0., kSigBins)), kITSsigV1);
-  fQAlist->AddAt((histo = new TH2F("fITSsigV2all", "ITS signal vs. p (all species, Method2):p / GeV/c:ITS signal / a.u.", kMomentumBins - 1, momentumBins, kSigBins, 0., kSigBins)), kITSsigV2);
-  for(Int_t ispec = 0; ispec < AliPID::kSPECIES; ispec++){
-    fQAlist->AddAt((histo = new TH2F(Form("fITSsigV1%s", AliPID::ParticleName(ispec)), Form("ITS signal vs. p (%s, Method1):p / GeV/c:ITS signal / a.u.", AliPID::ParticleName(ispec)), kMomentumBins - 1, momentumBins, kSigBins, 0., kSigBins)), 2 * ispec + kHistosSigAll);
-    fQAlist->AddAt((histo = new TH2F(Form("fITSsigV2%s", AliPID::ParticleName(ispec)), Form("ITS signal vs. p (%s, Method2):p / GeV/c:ITS signal / a.u.", AliPID::ParticleName(ispec)), kMomentumBins - 1, momentumBins, kSigBins, 0., kSigBins)), 2 * ispec + 1 + kHistosSigAll);
-  }
-  l->Add(fQAlist);
-}
-
-//___________________________________________________________________
-Double_t AliHFEpidITS::GetITSSignalV1(AliVParticle *vtrack, Int_t mcPID){
+Double_t AliHFEpidITS::GetITSSignalV1(AliVParticle *vtrack){
   //
   // Calculate the ITS signal according to the mean charge of the clusters
   //
-  if(!TString(vtrack->IsA()->GetName()).CompareTo("AliAODtrack")){
+  if(!TString(vtrack->IsA()->GetName()).CompareTo("AliAODTrack")){
     AliError("PID for AODs not implemented yet");
     return 0.;
   }
@@ -155,16 +117,15 @@ Double_t AliHFEpidITS::GetITSSignalV1(AliVParticle *vtrack, Int_t mcPID){
 #endif
   Double_t p = track->GetTPCInnerParam() ? track->GetTPCInnerParam()->P() : track->P();
   AliDebug(1, Form("Momentum: %f, ITS Signal: %f", p, signal));
-  if(IsQAon()) FillHistogramsSignalV1(p, signal, mcPID);
   return signal;
 }
 
 //___________________________________________________________________
-Double_t AliHFEpidITS::GetITSSignalV2(AliVParticle *vtrack, Int_t mcPID){
+Double_t AliHFEpidITS::GetITSSignalV2(AliVParticle *vtrack){
   //
   // Calculates the ITS signal. Truncated mean is used.
   //
-  if(!TString(vtrack->IsA()->GetName()).CompareTo("AliAODtrack")){
+  if(!TString(vtrack->IsA()->GetName()).CompareTo("AliAODTrack")){
     AliError("PID for AODs not implemented yet");
     return 0.;
   }
@@ -177,21 +138,6 @@ Double_t AliHFEpidITS::GetITSSignalV2(AliVParticle *vtrack, Int_t mcPID){
   Double_t signal = TMath::Mean(3, dedx); 
   Double_t p = track->GetTPCInnerParam() ? track->GetTPCInnerParam()->P() : track->P();
   AliDebug(1, Form("Momentum: %f, ITS Signal: %f", p, signal));
-  if(IsQAon()) FillHistogramsSignalV2(p, signal, mcPID);
   return signal;
 }
 
-//___________________________________________________________________
-void AliHFEpidITS::FillHistogramsSignalV1(Double_t p, Double_t signal, Int_t species){
-  (dynamic_cast<TH2 *>(fQAlist->At(kITSsigV1)))->Fill(p, signal);
-  if(species >= 0 && species < AliPID::kSPECIES)
-    (dynamic_cast<TH2 *>(fQAlist->At(kHistosSigAll + 2 * species)))->Fill(p, signal);
-}
-
-//___________________________________________________________________
-void AliHFEpidITS::FillHistogramsSignalV2(Double_t p, Double_t signal, Int_t species){
-  (dynamic_cast<TH2 *>(fQAlist->At(kITSsigV2)))->Fill(p, signal);
-  if(species >= 0 && species < AliPID::kSPECIES)
-    (dynamic_cast<TH2 *>(fQAlist->At(kHistosSigAll + 2 * species + 1)))->Fill(p, signal);
-}
-
index 7bfd9d1a7bf4c8c42487177598f8300e5f53cf48..55c1db6849c0deed528e9443eff60d3608e77d7f 100644 (file)
@@ -24,7 +24,7 @@
 #endif
 
 class AliVParticle;
-class TList;
+class AliHFEpidQAmanager;
 
 class AliHFEpidITS : public AliHFEpidBase{
   public:
@@ -34,23 +34,17 @@ class AliHFEpidITS : public AliHFEpidBase{
     virtual ~AliHFEpidITS();
 
     virtual Bool_t InitializePID();
-    virtual Int_t IsSelected(AliHFEpidObject *track);
-    virtual Bool_t HasQAhistos() const { return kTRUE; };
+    virtual Int_t IsSelected(AliHFEpidObject *track, AliHFEpidQAmanager *pidqa);
 
-    Double_t GetITSSignalV1(AliVParticle *track, Int_t mcPID);
-    Double_t GetITSSignalV2(AliVParticle *track, Int_t mcPID);
+    Double_t GetITSSignalV1(AliVParticle *track);
+    Double_t GetITSSignalV2(AliVParticle *track);
   protected:
-    virtual void AddQAhistograms(TList *l);
     void Copy(TObject &o) const;
-    void FillHistogramsSignalV1(Double_t p, Double_t signal, Int_t species);
-    void FillHistogramsSignalV2(Double_t p, Double_t signal, Int_t species);
   private:
     enum{
       kITSsigV1 = 0,
-      kITSsigV2 = 1,
-      kHistosSigAll = 2
+      kITSsigV2 = 1
     };
-    TList *fQAlist;      // QA histograms for ITS pid
 
     ClassDef(AliHFEpidITS, 0)  // PID class for ITS
 };
index 36fc56c18569954dc1c31bb0f8f93af1b4ce225f..2ce9e70faa571fba6d79b3b6d8a03431012cb0e7 100644 (file)
 //#include "AliVParticle.h"
 
 #include "AliHFEpidMC.h"
+#include "AliHFEtools.h"
 
 ClassImp(AliHFEpidMC)
 
+//___________________________________________________________________
+AliHFEpidMC::AliHFEpidMC():
+  AliHFEpidBase()
+{
+  //
+  // Default constructor
+  //
+}
+
 //___________________________________________________________________
 AliHFEpidMC::AliHFEpidMC(const Char_t *name):
   AliHFEpidBase(name)
 {
   //
-  // Default constructor
+  // Standard constructor
   //
 }
 
@@ -50,20 +60,11 @@ Bool_t AliHFEpidMC::InitializePID(){
 }
 
 //___________________________________________________________________
-Int_t AliHFEpidMC::IsSelected(AliHFEpidObject *track){
+Int_t AliHFEpidMC::IsSelected(AliHFEpidObject *track, AliHFEpidQAmanager * /*pidqa*/){
   //
   // returns MC PDG Code
   // Functionality implemented in the base class
   // (necessary for PID QA)
   //
-  if(track->fAnalysisType == AliHFEpidObject::kESDanalysis){
-    AliMCParticle *mc = dynamic_cast<AliMCParticle *>(track->fMCtrack);
-    if(!mc) return 0;
-    return mc->Particle()->GetPdgCode();
-  }
-  else{
-    AliAODMCParticle *aodmc = dynamic_cast<AliAODMCParticle *>(track->fMCtrack);
-    if(!aodmc) return 0;
-    return aodmc->GetPdgCode();
-  } 
+  return AliHFEtools::GetPdg(track->GetRecTrack());
 }
index 9299883c12df688f7b3f1538e2ffb38d15e6add6..843eee59cccfa49b708787c7ac5898e0ec923d29 100644 (file)
  #include "AliHFEpidBase.h"
  #endif
 
+class AliHFEpidQAmanager;
+
 class AliHFEpidMC : public AliHFEpidBase{
   public:
+    AliHFEpidMC();
     AliHFEpidMC(const Char_t *name);
     virtual ~AliHFEpidMC(){};
     
     virtual Bool_t InitializePID();
-    virtual Int_t IsSelected(AliHFEpidObject *track);
-    virtual Bool_t HasQAhistos() const { return kFALSE; };
+    virtual Int_t IsSelected(AliHFEpidObject *track, AliHFEpidQAmanager *pidqa);
 
   private:
 
index f0bdf8225450fe6884d2090b7b53e1af3abe9ee5..66020385e3effab5b1d6d197500c6f62adae709a 100644 (file)
@@ -49,6 +49,7 @@
 #include "AliHFEV0info.h"
 #include "AliHFEV0pid.h"
 #include "AliHFEV0pidMC.h"
+#include "AliHFEV0cuts.h"
 #include "AliHFEtrdPIDqa.h"
 
 
@@ -155,8 +156,9 @@ void AliHFEpidQA::Init(){
   // Prepare task output
   //
 
+  // load networks
   if(fNNref){
-    for(Int_t mom = 0; mom < 11; mom++){                      // load networks
+    for(Int_t mom = 0; mom < 11; mom++){                      
       fNet[mom] = (TMultiLayerPerceptron*) fNNref->Get(Form("NN_Mom%d", mom));
       if(!fNet[mom]){
        AliError(Form("No reference network for momentum bin %d!", mom));
@@ -164,7 +166,7 @@ void AliHFEpidQA::Init(){
     }
   }
   
-  fV0pid = new AliHFEV0pid;
+  fV0pid = new AliHFEV0pid();
   if(HasV0pidQA()) fV0pid->InitQA();
   fV0pidMC = new AliHFEV0pidMC();
   fV0pidMC->Init();
@@ -276,6 +278,7 @@ void AliHFEpidQA::Init(){
   }
   // TRD THnSparse - entries per tracklet
   // species, p, tracklet position, number of PID tracklets, number of slices (non 0), number of clusters, electron likelihood, 
+
   {
     Int_t nbins[7] = {5, 20, 6, 7, 9, 45, 100};
     Double_t min[7] = {-0.5, 0.5, -0.5, -0.5, -0.5, -0.5, 0.};
@@ -307,7 +310,9 @@ void AliHFEpidQA::Process(){
     AliError("AliVEvent not available, returning");
   }
 
+
   if(fMC) fV0pidMC->SetMCEvent(fMC);
+  if(fMC) fV0pid->SetMCEvent(fMC);
 
   fV0pid->Process(fEvent);
   TObjArray *hfeelectrons = fV0pid->GetListOfElectrons();
@@ -323,10 +328,10 @@ void AliHFEpidQA::Process(){
   TObjArray *cleanElectrons = MakeCleanListElectrons(hfeelectrons);
 
   if(fMC){
-    fV0pidMC->Process(electrons, AliHFEV0pid::kRecoElectron);
-    fV0pidMC->Process(pionsK0, AliHFEV0pid::kRecoPionK0);
-    fV0pidMC->Process(pionsL, AliHFEV0pid::kRecoPionL);
-    fV0pidMC->Process(protons, AliHFEV0pid::kRecoProton);
+    fV0pidMC->Process(electrons, AliHFEV0cuts::kRecoElectron);
+    fV0pidMC->Process(pionsK0, AliHFEV0cuts::kRecoPionK0);
+    fV0pidMC->Process(pionsL, AliHFEV0cuts::kRecoPionL);
+    fV0pidMC->Process(protons, AliHFEV0cuts::kRecoProton);
   }
 
   AliDebug(2, Form("Number of Electrons      : %d", electrons->GetEntries()));
@@ -336,20 +341,20 @@ void AliHFEpidQA::Process(){
   if(fMC){
     AliDebug(2, "MC Information available. Doing Purity checks...");
     // Calculate the purity of the clean samples using MC 
-    MakePurity(electrons, AliHFEV0pid::kRecoElectron);
-    MakePurity(pionsK0,  AliHFEV0pid::kRecoPionK0);
-    MakePurity(pionsL,  AliHFEV0pid::kRecoPionL);
-    MakePurity(protons,  AliHFEV0pid::kRecoProton);
+    MakePurity(electrons, AliHFEV0cuts::kRecoElectron);
+    MakePurity(pionsK0,  AliHFEV0cuts::kRecoPionK0);
+    MakePurity(pionsL,  AliHFEV0cuts::kRecoPionL);
+    MakePurity(protons,  AliHFEV0cuts::kRecoProton);
   }
 
   // some event wise checks
   CheckEvent();
 
   // Make Illumination Plot
-  FillIllumination(electrons, AliHFEV0pid::kRecoElectron);
-  FillIllumination(pionsK0, AliHFEV0pid::kRecoPionK0);
-  FillIllumination(pionsL, AliHFEV0pid::kRecoPionL);
-  FillIllumination(protons, AliHFEV0pid::kRecoProton);
+  FillIllumination(electrons, AliHFEV0cuts::kRecoElectron);
+  FillIllumination(pionsK0, AliHFEV0cuts::kRecoPionK0);
+  FillIllumination(pionsL, AliHFEV0cuts::kRecoPionL);
+  FillIllumination(protons, AliHFEV0cuts::kRecoProton);
 
   // Now we can do studies on the PID itself
   // For TRD use the TRD PID QA object
@@ -358,21 +363,21 @@ void AliHFEpidQA::Process(){
   fTRDpidQA->ProcessTracks(pionsL, AliPID::kPion);
   fTRDpidQA->ProcessTracks(protons, AliPID::kProton);
 
-  FillElectronLikelihoods(electrons,  AliHFEV0pid::kRecoElectron); 
-  FillElectronLikelihoods(pionsK0,  AliHFEV0pid::kRecoPionK0); 
-  FillElectronLikelihoods(pionsL,  AliHFEV0pid::kRecoPionL); 
-  FillElectronLikelihoods(protons,  AliHFEV0pid::kRecoProton); 
+  FillElectronLikelihoods(electrons,  AliHFEV0cuts::kRecoElectron); 
+  FillElectronLikelihoods(pionsK0,  AliHFEV0cuts::kRecoPionK0); 
+  FillElectronLikelihoods(pionsL,  AliHFEV0cuts::kRecoPionL); 
+  FillElectronLikelihoods(protons,  AliHFEV0cuts::kRecoProton); 
   
-  FillPIDresponse(electrons, AliHFEV0pid::kRecoElectron);
-  FillPIDresponse(pionsK0, AliHFEV0pid::kRecoPionK0);
-  FillPIDresponse(pionsL, AliHFEV0pid::kRecoPionL);
-  FillPIDresponse(protons, AliHFEV0pid::kRecoProton);
+  FillPIDresponse(electrons, AliHFEV0cuts::kRecoElectron);
+  FillPIDresponse(pionsK0, AliHFEV0cuts::kRecoPionK0);
+  FillPIDresponse(pionsL, AliHFEV0cuts::kRecoPionL);
+  FillPIDresponse(protons, AliHFEV0cuts::kRecoProton);
 
   // check the tender V0s
-  CheckTenderV0pid(electrons, AliHFEV0pid::kRecoElectron);
-  CheckTenderV0pid(pionsK0, AliHFEV0pid::kRecoPionK0);
-  CheckTenderV0pid(pionsL, AliHFEV0pid::kRecoPionL);
-  CheckTenderV0pid(protons, AliHFEV0pid::kRecoProton);
+  CheckTenderV0pid(electrons, AliHFEV0cuts::kRecoElectron);
+  CheckTenderV0pid(pionsK0, AliHFEV0cuts::kRecoPionK0);
+  CheckTenderV0pid(pionsL, AliHFEV0cuts::kRecoPionL);
+  CheckTenderV0pid(protons, AliHFEV0cuts::kRecoProton);
 
   // Analysis done, flush the containers
   fV0pid->Flush();
@@ -385,7 +390,7 @@ void AliHFEpidQA::Process(){
 }
 
 //__________________________________________
-void AliHFEpidQA::FillIllumination(TObjArray * const tracks, Int_t species){
+void AliHFEpidQA::FillIllumination(const TObjArray * const tracks, Int_t species){
   //
   // Fill Illumination Plot
   //
@@ -450,7 +455,7 @@ void AliHFEpidQA::FillTPCinfo(AliESDtrack *const esdtrack, Int_t species){
 }
 
 //__________________________________________
-void AliHFEpidQA::MakePurity(TObjArray *tracks, Int_t species){
+void AliHFEpidQA::MakePurity(const TObjArray *tracks, Int_t species){
   //
   // Fill the QA histos for a given species
   //
@@ -460,16 +465,16 @@ void AliHFEpidQA::MakePurity(TObjArray *tracks, Int_t species){
   Char_t hname[256];
 
   switch(species){
-  case  AliHFEV0pid::kRecoElectron:
+  case  AliHFEV0cuts::kRecoElectron:
     sprintf(hname, "purityElectron");
     break;
-  case  AliHFEV0pid::kRecoPionK0:
+  case  AliHFEV0cuts::kRecoPionK0:
     sprintf(hname, "purityPionK0");
     break;
-  case  AliHFEV0pid::kRecoPionL:
+  case  AliHFEV0cuts::kRecoPionL:
     sprintf(hname, "purityPionL");
     break;
-  case  AliHFEV0pid::kRecoProton:
+  case  AliHFEV0cuts::kRecoProton:
     sprintf(hname, "purityProton");
     break;
   default:  // non investigated species
@@ -510,7 +515,7 @@ void AliHFEpidQA::MakePurity(TObjArray *tracks, Int_t species){
 }
 
 //__________________________________________
-void AliHFEpidQA::FillElectronLikelihoods(TObjArray * const particles, Int_t species){
+void AliHFEpidQA::FillElectronLikelihoods(const TObjArray * const particles, Int_t species){
   //
   // Fill electron Likelihoods for the ITS, TPC and TOF
   // Required for the calculation of the electron efficiency, 
@@ -521,16 +526,16 @@ void AliHFEpidQA::FillElectronLikelihoods(TObjArray * const particles, Int_t spe
   Char_t specname[256];
 
   switch(species){
-  case  AliHFEV0pid::kRecoElectron:
+  case  AliHFEV0cuts::kRecoElectron:
     sprintf(specname, "Electron");
     break;
-  case  AliHFEV0pid::kRecoPionK0:
+  case  AliHFEV0cuts::kRecoPionK0:
     sprintf(specname, "PionK0");
     break;
-  case  AliHFEV0pid::kRecoPionL:
+  case  AliHFEV0cuts::kRecoPionL:
     sprintf(specname, "PionL");
     break;
-  case  AliHFEV0pid::kRecoProton:
+  case  AliHFEV0cuts::kRecoProton:
     sprintf(specname, "Proton");
     break;
   default:
@@ -605,7 +610,7 @@ void AliHFEpidQA::FillElectronLikelihoods(TObjArray * const particles, Int_t spe
   }//.. while tracks 
 }
 //__________________________________________
-void AliHFEpidQA::FillPIDresponse(TObjArray * const particles, Int_t species){
+void AliHFEpidQA::FillPIDresponse(const TObjArray * const particles, Int_t species){
   //
   // Fill the PID response of different detectors to V0 daughter particles
   //
@@ -950,7 +955,7 @@ Float_t AliHFEpidQA::TOFbeta(AliESDtrack * const track) const {
   return beta;
 }
 //____________________________________________
-Int_t AliHFEpidQA::GetMaxPID(Double_t *pidProbs) const {
+Int_t AliHFEpidQA::GetMaxPID(const Double_t *pidProbs) const {
   //
   // return the index of maximal PID probability
   //
@@ -973,16 +978,16 @@ Int_t AliHFEpidQA::GetPDG(Int_t species){
   Int_t pdg = 0;
 
   switch(species){
-  case  AliHFEV0pid::kRecoElectron:
+  case  AliHFEV0cuts::kRecoElectron:
     pdg = TMath::Abs(kElectron);
     break;
-  case  AliHFEV0pid::kRecoPionK0:
+  case  AliHFEV0cuts::kRecoPionK0:
     pdg = TMath::Abs(kPiPlus);
     break;
-  case  AliHFEV0pid::kRecoPionL:
+  case  AliHFEV0cuts::kRecoPionL:
     pdg = TMath::Abs(kPiPlus);
     break;
-  case  AliHFEV0pid::kRecoProton:
+  case  AliHFEV0cuts::kRecoProton:
     pdg = TMath::Abs(kProton);
     break;
   default:  // non investigated species
@@ -995,7 +1000,7 @@ Int_t AliHFEpidQA::GetPDG(Int_t species){
 }
 
 //_____________________________________________
-TObjArray * AliHFEpidQA::MakeTrackList(TObjArray *tracks) const {
+TObjArray * AliHFEpidQA::MakeTrackList(const TObjArray *tracks) const {
   //
   // convert list of AliHFEV0Info into a list of AliVParticle
   //
@@ -1009,7 +1014,7 @@ TObjArray * AliHFEpidQA::MakeTrackList(TObjArray *tracks) const {
 }
 
 //_____________________________________________
-TObjArray * AliHFEpidQA::MakeCleanListElectrons(TObjArray *electrons) const {
+TObjArray * AliHFEpidQA::MakeCleanListElectrons(const TObjArray *electrons) const {
   //
   // Cleanup electron sample using TPC PID
   // PID requirement will allways be implemented to the pair
@@ -1021,9 +1026,9 @@ TObjArray * AliHFEpidQA::MakeCleanListElectrons(TObjArray *electrons) const {
   AliHFEV0info *hfetrack;
   // const Double_t kSigmaTight = 1.;
   // const Double_t kSigmaLoose = 4.;
-  const Double_t kSigmaTight = 0.5;
-  const Double_t kSigmaLoose = 0.5;
-  const Double_t shift = 1.;
+  const Double_t kSigmaTight = 2.;
+  const Double_t kSigmaLoose = 2.;
+  const Double_t shift = 0.57;
   if((esd = dynamic_cast<AliESDEvent *>(fEvent))){
     AliESDtrack *track = NULL, *partnerTrack = NULL;
     while((hfetrack = dynamic_cast<AliHFEV0info *>(candidates()))){
@@ -1046,7 +1051,7 @@ TObjArray * AliHFEpidQA::MakeCleanListElectrons(TObjArray *electrons) const {
   return tracks;
 }
 //___________________________________________________________
-void AliHFEpidQA::CheckTenderV0pid(TObjArray * const particles, Int_t species){
+void AliHFEpidQA::CheckTenderV0pid(const TObjArray * const particles, Int_t species){
 
   //
   // retrieve the status bits from the TObject used to flag
@@ -1167,7 +1172,7 @@ Double_t AliHFEpidQA::TRDlikeTracklet(Int_t layer, AliESDtrack * const track, Do
   return sum;
 }
 //__________________________________________________________________________
-Int_t  AliHFEpidQA::TRDmomBin(Double_t p){
+const Int_t AliHFEpidQA::TRDmomBin(Double_t p){
   //
   // compute the momentum bin position
   // 
index 9c2c2b21a9a097220a59aff47ff058c5d59ce538..cde8b86f5c8db8c11d6f9c82c7ea58d2aa0dbbf3 100644 (file)
@@ -90,25 +90,25 @@ class AliHFEpidQA : public TObject{
       kTOF = 3
     };
 
-    TObjArray *MakeTrackList(TObjArray *tracks) const;
-    TObjArray *MakeCleanListElectrons(TObjArray *tracks) const;
-
-    void MakePurity(TObjArray *tracks, Int_t species);
-    TObjArray *MakeCleanListForTRD(TObjArray * const track, Int_t species);
-    void FillElectronLikelihoods(TObjArray * const particles, Int_t species);
-    void FillPIDresponse(TObjArray * const particles, Int_t species);
-    void FillIllumination(TObjArray *const particles, Int_t species);
+    TObjArray *MakeTrackList(const TObjArray *tracks) const;
+    TObjArray *MakeCleanListElectrons(const TObjArray *tracks) const;
+
+    void MakePurity(const TObjArray *tracks, Int_t species);
+    TObjArray *MakeCleanListForTRD(const TObjArray * const track, Int_t species);
+    void FillElectronLikelihoods(const TObjArray * const particles, Int_t species);
+    void FillPIDresponse(const TObjArray * const particles, Int_t species);
+    void FillIllumination(const TObjArray *const particles, Int_t species);
     void FillTPCinfo(AliESDtrack * const track, Int_t species);
     void RecalculateTRDpid(AliESDtrack *track, Double_t *pidProbs) const;
     void RecalculateTRDpid(AliAODTrack *track, Double_t *pidProbs) const;
-    void CheckTenderV0pid(TObjArray * const particles, Int_t species);
+    void CheckTenderV0pid(const TObjArray * const particles, Int_t species);
     Int_t GetTenderV0pid(AliESDtrack * const track);
     
     Double_t TRDlikeTracklet(Int_t layer, AliESDtrack * const track, Double_t *likelihood);
-    Int_t  TRDmomBin(Double_t p);
+    const Int_t  TRDmomBin(Double_t p);
 
  protected:
-    Int_t GetMaxPID(Double_t *pidProbs) const;
+    Int_t GetMaxPID(const Double_t *pidProbs) const;
     Int_t GetPDG(Int_t index);
     
   private:
diff --git a/PWG3/hfe/AliHFEpidQAmanager.cxx b/PWG3/hfe/AliHFEpidQAmanager.cxx
new file mode 100644 (file)
index 0000000..66abec4
--- /dev/null
@@ -0,0 +1,178 @@
+/**************************************************************************
+* 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 AliHFEpidQAmanager
+// Does steering of the PID QA. The PID QA manager is initialized according
+// to the configuration used for PID. It contains PID objects inheriting 
+// from AliHFEdetPIDqa, which are
+//     AliHFEtpcPIDqa
+//     AliHFEtrdPIDqaV1
+//     AliHFEtofPIDqa
+// PID QA objects are filled for every detector before PID decision and 
+// after PID decision for tracks which are selected by the given detector
+// as electron candidates.
+//
+// Author
+//   Markus Fasel <M.Fasel@gsi.de>
+//
+#include <TList.h>
+
+#include "AliAODpidUtil.h"
+#include "AliESDpid.h"
+#include "AliVParticle.h"
+
+#include "AliHFEtpcPIDqa.h"
+#include "AliHFEtrdPIDqaV1.h"
+#include "AliHFEtofPIDqa.h"
+#include "AliHFEpidQAmanager.h"
+
+ClassImp(AliHFEpidQAmanager)
+
+//____________________________________________________________
+AliHFEpidQAmanager::AliHFEpidQAmanager():
+  TObject()
+{
+  //
+  // Dummy constructor
+  //
+  memset(fDetPIDqa, 0, sizeof(AliHFEdetPIDqa *) * AliHFEpid::kNdetectorPID);
+  SetOwner(); 
+}
+
+//____________________________________________________________
+AliHFEpidQAmanager::AliHFEpidQAmanager(const AliHFEpidQAmanager &ref):
+  TObject(ref)
+{
+  //
+  // Copy constructor
+  //
+  ref.Copy(*this);
+  SetOwner();
+}
+
+//____________________________________________________________
+AliHFEpidQAmanager &AliHFEpidQAmanager::operator=(const AliHFEpidQAmanager &ref){
+  //
+  // Assignment operator
+  //
+  if(this != &ref) ref.Copy(*this);
+  SetOwner();
+  return *this;
+}
+
+//____________________________________________________________
+void AliHFEpidQAmanager::Copy(TObject &o) const{
+  //
+  // Make copy
+  //
+  TObject::Copy(o);
+  AliHFEpidQAmanager &target = dynamic_cast<AliHFEpidQAmanager &>(o);
+
+  for(Int_t idet = 0; idet < AliHFEpid::kNdetectorPID; idet++){
+    if(target.fDetPIDqa[idet]) delete target.fDetPIDqa[idet];
+    if(fDetPIDqa[idet]) target.CreateDetPIDqa(static_cast<AliHFEpid::EDETtype_t>(idet));
+  }
+}
+
+//____________________________________________________________
+AliHFEpidQAmanager::~AliHFEpidQAmanager(){
+  //
+  // Destructor
+  //
+  if(IsOwner())
+    for(Int_t idet = 0; idet < AliHFEpid::kNdetectorPID; idet++){
+      if(fDetPIDqa[idet]) delete fDetPIDqa[idet];
+    }
+}
+
+//____________________________________________________________
+void AliHFEpidQAmanager::Initialize(AliHFEpid *pid){
+  //
+  // Initialize PID QA manager according to the detector
+  // configuration used in the PID
+  //
+  for(Int_t idet = 0; idet < AliHFEpid::kNdetectorPID; idet++)
+    if(pid->HasDetector(static_cast<AliHFEpid::EDETtype_t>(idet))){
+      CreateDetPIDqa(static_cast<AliHFEpid::EDETtype_t>(idet));
+      fDetPIDqa[idet]->Initialize();
+    }
+}
+
+//____________________________________________________________
+void AliHFEpidQAmanager::CreateDetPIDqa(AliHFEpid::EDETtype_t idet){
+  //
+  // Create new PID QA object
+  //
+  switch(idet){
+    case AliHFEpid::kTPCpid: 
+          fDetPIDqa[idet] = new AliHFEtpcPIDqa("TPCQA"); 
+          break;
+    case AliHFEpid::kTRDpid: 
+          fDetPIDqa[idet] = new AliHFEtrdPIDqaV1("TRDQA"); 
+          break;
+    case AliHFEpid::kTOFpid: 
+          fDetPIDqa[idet] = new AliHFEtofPIDqa("TOFQA"); 
+          break;
+    default:
+          break;
+  };
+}
+
+//____________________________________________________________
+void AliHFEpidQAmanager::ProcessTrack(AliHFEpidObject *track, AliHFEpid::EDETtype_t det, AliHFEdetPIDqa::EStep_t step){
+  //
+  // Process single Track
+  //
+  if(!fDetPIDqa[det]){
+    AliDebug(1, Form("QA for detector %d not available", det));
+    return;
+  }
+  AliDebug(1, Form("Doing QA for detector %d\n", det));
+  fDetPIDqa[det]->ProcessTrack(track, step);
+}
+
+//____________________________________________________________
+TList *AliHFEpidQAmanager::MakeList(const Char_t *name){
+  //
+  // Make List of PID QA objects
+  //
+  TList *list = new TList;
+  list->SetName(name);
+  list->SetOwner();
+  for(Int_t idet = 0; idet < AliHFEpid::kNdetectorPID; idet++){
+    if(fDetPIDqa[idet]) list->Add(fDetPIDqa[idet]);
+  }
+  ReleaseOwnerShip();
+  return list;
+}
+
+//____________________________________________________________
+void AliHFEpidQAmanager::SetESDpid(AliESDpid *esdpid){
+  //
+  // Publish ESD PID
+  //
+  for(Int_t idet = 0; idet < AliHFEpid::kNdetectorPID; idet++)
+    if(fDetPIDqa[idet]) fDetPIDqa[idet]->SetESDpid(esdpid);
+}
+
+//____________________________________________________________
+void AliHFEpidQAmanager::SetAODpid(AliAODpidUtil *aodpid){
+  //
+  // Publish AOD PID
+  //
+  for(Int_t idet = 0; idet < AliHFEpid::kNdetectorPID; idet++)
+    if(fDetPIDqa[idet]) fDetPIDqa[idet]->SetAODpid(aodpid);
+}
+
diff --git a/PWG3/hfe/AliHFEpidQAmanager.h b/PWG3/hfe/AliHFEpidQAmanager.h
new file mode 100644 (file)
index 0000000..1e6d6e0
--- /dev/null
@@ -0,0 +1,71 @@
+/**************************************************************************
+* 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 AliHFEpidQAmanager
+// Steering PID QA
+// More information can be found inside the implementation file
+//
+#ifndef ALIHFEPIDQAMANAGER_H
+#define ALIHFEPIDQAMANAGER_H
+
+#ifndef ROOT_TObject
+#include <TObject.h>
+#endif
+
+#ifndef ALIHFEPID_H
+#include "AliHFEpid.h"
+#endif
+
+#ifndef ALIHFEDETPIDQA_H
+#include "AliHFEdetPIDqa.h"
+#endif
+
+class TList; 
+class AliVParticle;
+class AliESDpid;
+class AliAODpidUtil;
+class AliHFEpidObject;
+
+class AliHFEpidQAmanager : public TObject{
+  public:
+    AliHFEpidQAmanager();
+    AliHFEpidQAmanager(const AliHFEpidQAmanager &ref);
+    AliHFEpidQAmanager &operator=(const AliHFEpidQAmanager &ref);
+    void Copy(TObject &o) const;
+    ~AliHFEpidQAmanager();
+
+    void Initialize(AliHFEpid *pid);
+    void ProcessTrack(AliHFEpidObject *track, AliHFEpid::EDETtype_t det, AliHFEdetPIDqa::EStep_t step);
+    AliHFEdetPIDqa *GetDetectorPIDqa(AliHFEpid::EDETtype_t detector) const { return fDetPIDqa[detector]; }
+    TList *MakeList(const Char_t *name);
+
+    void SetESDpid(AliESDpid *esdpid);
+    void SetAODpid(AliAODpidUtil *aodpid);
+
+  protected:
+    enum{
+      kIsOwner = BIT(14)
+    };
+    Bool_t IsOwner() const { return TestBit(kIsOwner); }
+    void SetOwner() { SetBit(kIsOwner, kTRUE); }
+    void ReleaseOwnerShip() { SetBit(kIsOwner, kFALSE); }
+    void CreateDetPIDqa(AliHFEpid::EDETtype_t detector);
+
+  private:
+    AliHFEdetPIDqa *fDetPIDqa[AliHFEpid::kNdetectorPID]; //!
+
+  ClassDef(AliHFEpidQAmanager, 0)
+};
+#endif
index 38ac77f4e7570f907cbf65a94d421b1f5d777063..9f749b164f229127880a90fc9b85bd770d1143ba 100644 (file)
 //   Matus Kalisky <matus.kalisky@cern.ch>  (contact)
 //
 
-#include <TList.h>
 #include <TMath.h>
-#include <THnSparse.h>
-#include <TDatabasePDG.h>
 
+#include "AliAODpidUtil.h"
 #include "AliAODTrack.h"
-#include "AliAODMCParticle.h"
+#include "AliESDpid.h"
 #include "AliESDtrack.h"
-#include "AliMCParticle.h"
 #include "AliPID.h"
-#include "AliESDpid.h"
 
-#include "AliHFEcollection.h"
+#include "AliHFEdetPIDqa.h"
 #include "AliHFEpidTOF.h"
-#include "AliHFEpidBase.h"
+#include "AliHFEpidQAmanager.h"
 
 
 ClassImp(AliHFEpidTOF)
-  
+
+//___________________________________________________________________
+AliHFEpidTOF::AliHFEpidTOF():
+  AliHFEpidBase()
+  , fPID(NULL)
+  , fNsigmaTOF(3)
+{
+  //
+  // Constructor
+  //
+} 
+
 //___________________________________________________________________
 AliHFEpidTOF::AliHFEpidTOF(const Char_t *name):
   AliHFEpidBase(name)
-  , fPID(0x0)
-  , fQAList(0x0)
+  , fPID(NULL)
   , fNsigmaTOF(3)
 {
   //
   // Constructor
   //
 }
+
 //___________________________________________________________________
 AliHFEpidTOF::AliHFEpidTOF(const AliHFEpidTOF &c):
   AliHFEpidBase("")
-  , fPID(0x0)
-  , fQAList(0x0)
+  , fPID(NULL)
   , fNsigmaTOF(3)
 {  
   // 
@@ -83,10 +89,6 @@ AliHFEpidTOF::~AliHFEpidTOF(){
   // Destructor
   //
   if(fPID) delete fPID;
-  if(fQAList){
-    fQAList->Delete();
-    delete fQAList;
-  }
 }
 //___________________________________________________________________
 void AliHFEpidTOF::Copy(TObject &ref) const {
@@ -96,7 +98,6 @@ void AliHFEpidTOF::Copy(TObject &ref) const {
   AliHFEpidTOF &target = dynamic_cast<AliHFEpidTOF &>(ref);
 
   target.fPID = fPID;          
-  target.fQAList = fQAList;
   target.fNsigmaTOF = fNsigmaTOF;
 
   AliHFEpidBase::Copy(ref);
@@ -110,313 +111,47 @@ Bool_t AliHFEpidTOF::InitializePID(){
 }
 
 //___________________________________________________________________
-Int_t AliHFEpidTOF::IsSelected(AliHFEpidObject *vtrack)
+Int_t AliHFEpidTOF::IsSelected(AliHFEpidObject *track, AliHFEpidQAmanager *pidqa)
 {
-
-  //
-  // as of 22/05/2006 :
-  // returns AliPID based on the ESD TOF PID decision
-  // the ESD PID will be checked and if necessary improved 
-  // in the mean time. Best of luck
-  //
-  // returns 10 (== kUnknown)if PID can not be assigned for whatever reason
-  //
-
-  if(vtrack->fAnalysisType == AliHFEpidObject::kESDanalysis){
-    AliESDtrack *esdTrack = dynamic_cast<AliESDtrack *>(vtrack->fRecTrack);
-    if(!esdTrack) return 0;
-    AliMCParticle *mcTrack = dynamic_cast<AliMCParticle *>(vtrack->fMCtrack);
-    return MakePIDesdV3(esdTrack, mcTrack);
-  } else {
-    AliAODTrack *aodTrack = dynamic_cast<AliAODTrack *>(vtrack->fRecTrack);
-    if(!aodTrack) return 0;
-    AliAODMCParticle *aodmc = dynamic_cast<AliAODMCParticle *>(vtrack->fMCtrack);
-    return MakePIDaod(aodTrack, aodmc);
-  }
-}
-
-//___________________________________________________________________
-Int_t AliHFEpidTOF::MakePIDesd(AliESDtrack *track, AliMCParticle * /*mcTrack*/){
-  //
-  // Does particle identification as discribed in IsSelected
-  //
-  if(!fESDpid){
-    AliError("No ESD PID object available");
-    return kFALSE;
-  }
-  Long_t status = 0;
-  status = track->GetStatus(); 
-
-  if(!(status & AliESDtrack::kTOFout)) return 0;
-  
-  if(IsQAon()) fQAList->Fill("hTOF_flags", 0.);
-
-  Double_t tItrackL = track->GetIntegratedLength();
-  Double_t tTOFsignal = track->GetTOFsignal();
-  
-  if(IsQAon()){
-    if(tItrackL > 0)
-      fQAList->Fill("hTOF_flags", 1.);
-
-    if(tTOFsignal > 0)
-      fQAList->Fill("hTOF_flags", 2.);
-  }
-  
-
-  if(tItrackL <=0 || tTOFsignal <=0) return 0;
-
-  if(IsQAon()){
-    fQAList->Fill("hTOF_flags", 3.);
-    fQAList->Fill("hTOF_signal", tTOFsignal/1000.);
-    fQAList->Fill("hTOF_length", tItrackL);
-  }
-  // get the TOF pid probabilities
-  Double_t tESDpid[5] = {0., 0., 0., 0., 0.};
-  Float_t tTOFpidSum = 0.;
-  // find the largest PID probability
-  track->GetTOFpid(tESDpid);
-  Double_t tMAXpid = 0.;
-  Int_t tMAXindex = -1;
-  for(Int_t i=0; i<5; ++i){
-    tTOFpidSum += tESDpid[i];
-    if(tESDpid[i] > tMAXpid){
-      tMAXpid = tESDpid[i];
-      tMAXindex = i;
-    }
-  }
-
-  Int_t pdg = 0;
-
-  TString specname;
-  switch(tMAXindex){
-    case 0:    pdg = 11; specname = "electron";  break;
-    case 1:    pdg = 13; specname = "muon"; break;
-    case 2:    pdg = 211; specname = "pion"; break;
-    case 3:    pdg = 321; specname = "kaon"; break;
-    case 4:    pdg = 2212; specname = "proton"; break;
-    default:   pdg = 0;
-  };
-
-  
-  Double_t p = track->GetOuterParam()->P();
-  Double_t beta = (tItrackL/100.)/(TMath::C()*(tTOFsignal/1e12));
-  
-  // sanity check, should not be necessary
-  if(TMath::Abs(tTOFpidSum - 1) > 0.01) return 0;
-
-  Double_t nSigmas = fESDpid->NumberOfSigmasTOF(track, (AliPID::EParticleType)tMAXindex, 0.);
-  if(TMath::Abs(nSigmas) > fNsigmaTOF) return 0;
-
-  
-  // should be the same as AliPID flags
-  
-  if(IsQAon()){
-    TString histname = "hTOFpid_" + specname;
-    fQAList->Fill(histname.Data(), beta, p);
-    fQAList->Fill("fTOFbeta_v_P_no", beta, p);
-  }
-  //return tMAXindex;
-  return pdg;
-  
-}
-//__________________________________________________________________
-Int_t AliHFEpidTOF::MakePIDesdV2(AliESDtrack *track, AliMCParticle * /*mcTrack*/){
-  //
-  // Computes the PID response based on TOF & T0 signal
-  //
-  
-  if(!fESDpid){
-    AliError("No ESD PID object available");
-    return kFALSE;
-  }
-  Long_t status = 0;
-  status = track->GetStatus(); 
-  if(!(status & AliESDtrack::kTOFpid)) return 0;
-
-  Double_t p = track->GetOuterParam()->P();  
-  // track integrated times for 5 different hypothesis and T0 time
-  Double_t times[5];
-  track->GetIntegratedTimes(times);
-  Double_t tItrackL = track->GetIntegratedLength();
-  Double_t tTOFsignal = track->GetTOFsignal();
-  Double_t t0 = fESDpid->GetTOFResponse().GetTimeZero();
-  //printf("-D: tof: %f, T0: %f\n", tTOFsignal, t0);
-  // suppress missing or wrong T0 information
-  if(t0 > 999990.0) return 0;
-  Double_t tof = tTOFsignal - t0;
-  Double_t beta = (tItrackL/100.)/((TMath::C()*tof)/1e12);
-  //if(IsQAon())fQAList->Fill("hTOFbetaV2all", p, beta);  
-
-  const Int_t pdg[5] = {11, 13, 211, 321, 2212};
-  const Double_t invMass[5] = {TDatabasePDG::Instance()->GetParticle(11)->Mass(),
-                              TDatabasePDG::Instance()->GetParticle(13)->Mass(),
-                              TDatabasePDG::Instance()->GetParticle(211)->Mass(),
-                              TDatabasePDG::Instance()->GetParticle(321)->Mass(),
-                              TDatabasePDG::Instance()->GetParticle(2212)->Mass()};
-
-
-  // accepted beta bands as function of momentum - parameters
-  // line: par[0]/p + par[1] + expected_tof
-  const Double_t bMin[5][2] = {{0., -0.03}, {-0.005, -0.02}, {-0.005, -0.02}, {-0.02, -0.006}, {-0.03, -0.005}}; 
-  const Double_t bMax[5][2] = {{0., 0.03}, {0.005, 0.02}, {0.005, 0.02}, {0.02, 0.006}, {0.03, 0.005}};             
-            
-  Int_t index = -1;
-  Double_t rdiff = 1.;
-  for(Int_t i=0; i<5; ++i){
-    Double_t d = (TMath::Abs(times[i] - tof))/times[i];
-    if(d < rdiff){
-      rdiff = d;
-      index = i;
-    }
-  }
-
-  // stupid and unnecessary complicated - to be improved soon
-  Double_t a = p/(invMass[index]);
-  a *= a;
-  Double_t betaMatch = TMath::Sqrt(a/(1+a));
-
-  // check wheter the most probable match is within allowed region of beta for given momentum and species
-  Double_t min = bMin[index][0]/p + bMin[index][1] + betaMatch;
-  Double_t max = bMax[index][0]/p + bMax[index][1] + betaMatch;  
-
-  // debug
-  //printf("-D: p: %f, beta: %f, pdg: %i, min: %f, max: %f\n", p, beta, pdg[index], min, max);
-
-  //
-  // PID decision - can be simpler than the QA histograms above could indicate !
-  // 
-  
-  // suppress nonsense
-  if(beta < 0.2) return 0;  
-
-  // 1) Simple version - protect electrons
-  if(beta > (1+bMin[0][1]) && beta < (1+bMax[0][1])){
-    //if(IsQAon())fQAList->Fill("hTOFbetaV2electron", p, beta);
-    return 11;
-  }
-  else return 0;
-  
-  // NOT ACTIVE when (1) activated
-  // 2) more complex version - return true PID of the particle based on the best TOF estimate
-  // under development - still keep protecting electrons
-  if(beta > (1+bMin[0][1]) && beta < (1+bMax[0][1])){
-    if(IsQAon())fQAList->Fill("hTOFbetaV2_electron", p, beta);
-    return 11;
-  }
-  // above 3 GeV/c the supression gets weak
-  if(p > 3.0) return 0;
-  if(beta > min && beta < max) {
-    if(IsQAon())fQAList->Fill("hTOFbetaV2selected", p, beta);
-    return pdg[index];
-  }
-  
-
-  return 0;
-}
-
-//___________________________________________________________________
-Int_t AliHFEpidTOF::MakePIDesdV3(AliESDtrack *track, AliMCParticle * /*mctrack*/){
   //
   // TOF PID based on n-Sigma cut
   // Selects Protons and Kaons via n-sigma cut up to 3 GeV/c
   // In addition histos for n-sigma before (all species) and after (only closest species) are filled
   //
-  if(!fESDpid){
-    AliError("No ESD pid Object available. Return");
-    return 0;
-  }
-  if(!(track->GetStatus() & AliESDtrack::kTOFpid)) return 0;
+  if((!fESDpid && track->IsESDanalysis()) || (!fAODpid && track->IsAODanalysis())) return 0;
+  AliDebug(2, "PID object available");
 
-  Double_t t0 = fESDpid->GetTOFResponse().GetTimeZero();
-  Double_t p = track->GetOuterParam() ? track->GetOuterParam()->P() : track->P();
+  AliHFEpidObject::AnalysisType_t anaType = track->IsESDanalysis() ? AliHFEpidObject::kESDanalysis : AliHFEpidObject::kAODanalysis;
+  if(!((dynamic_cast<const AliVTrack *>(track->GetRecTrack()))->GetStatus() & AliESDtrack::kTOFpid)) return 0;
+  AliDebug(2, "Track Has TOF PID");
+
+  if(pidqa) pidqa->ProcessTrack(track, AliHFEpid::kTOFpid, AliHFEdetPIDqa::kBeforePID);
 
   // Fill before selection
-  Double_t sigEle = fESDpid->NumberOfSigmasTOF(track, AliPID::kElectron, t0);
-  //printf("-D: p: %f, t0: %f, nSigma: %f\n", p, t0, sigEle);
+  Double_t sigEle = NumberOfSigmas(track->GetRecTrack(), AliPID::kElectron, anaType);
+  AliDebug(2, Form("Number of sigmas in TOF: %f", sigEle));
   Int_t pdg = 0;
-  if(TMath::Abs(sigEle) < fNsigmaTOF)
+  if(TMath::Abs(sigEle) < fNsigmaTOF){
     pdg = 11;
-  if(IsQAon()){
-    // Draw TPC cleanup
-    Double_t nsigTPC = fESDpid->NumberOfSigmasTPC(track, AliPID::kElectron);
-    if(nsigTPC > -3 && nsigTPC < 5) fQAList->Fill("hTOFsigmaTPCcleanup", p, sigEle);
-    // Draw TOF signal
-    Double_t hcontent[3] = {p, sigEle, 0};
-    THnSparseF * hptr = dynamic_cast<THnSparseF *>(fQAList->Get("hTOFsigmaElectron"));
-    hptr->Fill(hcontent);
-    if(pdg == 11){
-      hcontent[2] = 1;
-      hptr->Fill(hcontent);
-    }
+    if(pidqa) pidqa->ProcessTrack(track, AliHFEpid::kTOFpid, AliHFEdetPIDqa::kAfterPID);
   }
  
   return pdg;
 }
-//___________________________________________________________________
-Double_t AliHFEpidTOF::Likelihood(const AliESDtrack *track, Int_t species, Float_t rsig){
-  
-  //gives probability for track to come from a certain particle species;
-  //no priors considered -> probabilities for equal abundances of all species!
-  //optional restriction to r-sigma bands of different particle species; default: rsig = 2. (see below)
-  
-  //IMPORTANT: Tracks which are judged to be outliers get negative likelihoods -> unusable for combination with further detectors!
-  
-  if(!track) return -1.;
-  Bool_t outlier = kTRUE;
-  // Check whether distance from the respective particle line is smaller than r sigma
-  for(Int_t hypo = 0; hypo < AliPID::kSPECIES; hypo++){
-    if(TMath::Abs(fESDpid->NumberOfSigmasTOF(track, (AliPID::EParticleType)hypo, 0.)) > rsig)
-      outlier = kTRUE;
-    else {
-      outlier = kFALSE;
-      break;
-    }
-  }
-  if(outlier)
-    return -2.;
-  
-  Double_t tofProb[5];
-  
-  track->GetTOFpid(tofProb);
-  
-  return tofProb[species];
-}
-//___________________________________________________________________
-Int_t AliHFEpidTOF::MakePIDaod(AliAODTrack * /*aodTrack*/, AliAODMCParticle * /*mcTrack*/){
-  AliError("AOD PID not yet implemented");
-  return 0;
-}
 
 //___________________________________________________________________
-void AliHFEpidTOF::AddQAhistograms(TList *qaList){
-  //
-  // Create QA histograms for TOF PID
-  //
-
-  fQAList = new AliHFEcollection("TOFqaHistos", "Collection for TOF PID histograms");
-  //fQAList->SetName("fTOFqaHistos");
-  fQAList->CreateTH1F("hTOF_flags", "TOF flags;flags (see code for info);counts", 10, -0.25, 4.75);
-  fQAList->CreateTH2F("fTOFbeta_v_P_no","beta -v- P; beta;momentum [GeV/c]", 120, 0, 1.2, 200, 0, 20);
-  fQAList->CreateTH1F("hTOF_signal", "TOF signal; TOF signal [ns];counts", 1000, 12, 50);
-  fQAList->CreateTH1F("hTOF_length", "TOF track length; length [cm];counts", 400, 300, 700);
-  fQAList->CreateTH2F("hTOFpid_electron", "TOF reco electron; beta ; momentum [GeV/c]", 120, 0, 1.2, 200, 0, 5);
-  fQAList->CreateTH2F("hTOFpid_muon", "TOF reco muon; beta ; momentum [GeV/c]", 120, 0, 1.2, 200, 0, 5);
-  fQAList->CreateTH2F("hTOFpid_pion", "TOF reco pion; beta ; momentum [GeV/c]", 120, 0, 1.2, 200, 0, 5);
-  fQAList->CreateTH2F("hTOFpid_kaon", "TOF reco kaon; beta ; momentum [GeV/c]", 120, 0, 1.2, 200, 0, 5);
-  fQAList->CreateTH2F("hTOFpid_proton", "TOF reco proton; beta ; momentum [GeV/c]", 120, 0, 1.2, 200, 0, 5);
-  //fQAList->CreateTH2F("hTOFbetaV2all", "TOF #beta vs p for all tracks; momentum [GeV/c]; beta ", 400, 0.1, 10., 1200, 0, 1.2, 0);
-  //fQAList->CreateTH2F("hTOFbetaV2electron", "TOF #beta vs p for selected electron tracks; momentum [GeV/c]; beta", 400, 0.1, 10., 1200, 0, 1.2, 0);
-
-  // histograms for sigma cut
-  const Int_t kNdim= 3;
-  Int_t nBins[kNdim] = {1000, 1400, 2};
-  Double_t binMin[kNdim] = {0.1, -12., 0};
-  Double_t binMax[kNdim] = {20, 12., 2};
-  fQAList->CreateTHnSparse("hTOFsigmaElectron", "TOF N#sigma around the Electron Line for all tracks; p (GeV/c); N sigma; Selection Step", kNdim, nBins, binMin, binMax);
-  fQAList->CreateTH2F("hTOFsigmaTPCcleanup", "TOF N#sigma around the Electron Line for all tracks after TPC cleanup; p (GeV/c); N sigma;", 100, 0.1, 20, 140, -12, 12);
-
-  qaList->AddLast(fQAList->GetList());
+Double_t AliHFEpidTOF::NumberOfSigmas(const AliVParticle *track, AliPID::EParticleType species, AliHFEpidObject::AnalysisType_t anaType){
+  //    
+  // Get the number of sigmas
+  //
+  Double_t nSigmas = 100;
+  if(anaType == AliHFEpidObject::kESDanalysis){
+    // ESD analysis
+    const AliESDtrack *esdtrack = dynamic_cast<const AliESDtrack *>(track);
+    if(esdtrack && fESDpid) nSigmas = fESDpid->NumberOfSigmasTOF(esdtrack, species, fESDpid->GetTOFResponse().GetTimeZero());
+  } else {
+    const AliAODTrack *aodtrack = dynamic_cast<const AliAODTrack *>(track);
+    if(aodtrack && fAODpid) nSigmas = fAODpid->NumberOfSigmasTOF(aodtrack, species);
+  }
+  return nSigmas;
 }
-
-
index a64b1b7dd7c9cdde567e81a7072da7f7613093d2..829bb5233ff9a3fb14e3bd5cfb2570a5cb4ccad0 100644 (file)
 #include "AliHFEpidBase.h"
 #endif
 
-class TList;
-class TH2F;
+class AliVParticle;
+class AliPID;
 
-class AliAODTrack;
-class AliAODMCParticle;
-class AliESDtrack;
-class AliMCParticle;
-class AliESDpid;
-class AliLog;
-
-class AliHFEcollection;
+class AliHFEpidQAmanager;
 
 class AliHFEpidTOF : public AliHFEpidBase{
   public:
+    AliHFEpidTOF();
     AliHFEpidTOF(const Char_t *name);
     virtual ~AliHFEpidTOF();
     AliHFEpidTOF(const AliHFEpidTOF &c);
     AliHFEpidTOF &operator=(const AliHFEpidTOF &c);
   
     virtual Bool_t    InitializePID();
-    virtual Int_t     IsSelected(AliHFEpidObject *track);
-    virtual Bool_t    HasQAhistos() const { return kTRUE; };
+    virtual Int_t     IsSelected(AliHFEpidObject *track, AliHFEpidQAmanager *piqa);
   
     void SetTOFnSigma(Short_t nSigma) { fNsigmaTOF = nSigma; };
 
-    Double_t Likelihood(const AliESDtrack *track, Int_t species, Float_t rsig = 2.); 
   protected:
     void Copy(TObject &ref) const;
-    void AddQAhistograms(TList *qaHist);
-    Int_t MakePIDesd(AliESDtrack *esdTrack, AliMCParticle *mcTrack);
-    Int_t MakePIDesdV2(AliESDtrack *esdTrack, AliMCParticle *mcTrack);
-    Int_t MakePIDesdV3(AliESDtrack *esdTrack, AliMCParticle *mcTrack);
-    Int_t MakePIDaod(AliAODTrack *aodTrack, AliAODMCParticle *mcTrack);
-  
+    Double_t NumberOfSigmas(const AliVParticle *track, AliPID::EParticleType species, AliHFEpidObject::AnalysisType_t anaType);
   private:
-    typedef enum{
-      kHistTOFpidFlags = 0,
-      kHistTOFpidBetavP = 1,
-      kHistTOFsignal = 2,
-      kHistTOFlength =3,
-      kHistTOFpid0 = 4,
-      kHistTOFpid1 = 5,
-      kHistTOFpid2 = 6,
-      kHistTOFpid3 = 7,
-      kHistTOFpid4 = 8
-    } QAHist_t;
-  
     AliPID        *fPID;           //! PID Object
-    AliHFEcollection *fQAList;     //! QA histograms
 
     Short_t    fNsigmaTOF;         // TOF sigma band
 
index d5397f884680c8d9c41b674310ffd4a1081fb36b..a0e3b4dfaf988a90b26456c30984cf07dcb91e29 100644 (file)
 //   Markus Heide <mheide@uni-muenster.de> 
 //  
 #include <TF1.h>
-#include <TList.h>
 #include <TMath.h>
-#include <THnSparse.h>
 
+#include "AliAODpidUtil.h"
 #include "AliAODTrack.h"
 #include "AliAODMCParticle.h"
 #include "AliESDtrack.h"
 #include "AliPID.h"
 #include "AliESDpid.h"
 
-#include "AliHFEcollection.h"
 #include "AliHFEpidTPC.h"
+#include "AliHFEpidQAmanager.h"
 
 ClassImp(AliHFEpidTPC)
 
+//___________________________________________________________________
+AliHFEpidTPC::AliHFEpidTPC() :
+  // add a list here
+  AliHFEpidBase()
+  , fLineCrossingType(0)
+  , fLineCrossingsEnabled(0)
+  , fUpperSigmaCut(NULL)
+  , fLowerSigmaCut(NULL)
+  , fNsigmaTPC(3)
+  , fRejectionEnabled(0)
+  , fPID(NULL)
+{
+  //
+  // default  constructor
+  // 
+}
+
 //___________________________________________________________________
 AliHFEpidTPC::AliHFEpidTPC(const char* name) :
   // add a list here
@@ -55,7 +71,6 @@ AliHFEpidTPC::AliHFEpidTPC(const char* name) :
   , fNsigmaTPC(3)
   , fRejectionEnabled(0)
   , fPID(NULL)
-  , fQAList(NULL)
 {
   //
   // default  constructor
@@ -76,7 +91,6 @@ AliHFEpidTPC::AliHFEpidTPC(const AliHFEpidTPC &ref) :
   , fNsigmaTPC(2)
   , fRejectionEnabled(0)
   , fPID(NULL)
-  , fQAList(NULL)
 {
   //
   // Copy constructor
@@ -108,7 +122,6 @@ void AliHFEpidTPC::Copy(TObject &o) const{
   target.fNsigmaTPC = fNsigmaTPC;
   target.fRejectionEnabled = fRejectionEnabled;
   target.fPID = new AliPID(*fPID);
-  target.fQAList = new AliHFEcollection(*fQAList);
   memcpy(target.fLineCrossingSigma, fLineCrossingSigma, sizeof(Double_t) * AliPID::kSPECIES);
   memcpy(target.fPAsigCut, fPAsigCut, sizeof(Float_t) * 2);
   memcpy(target.fNAsigmaTPC, fNAsigmaTPC, sizeof(Float_t) * 2);
@@ -122,9 +135,6 @@ AliHFEpidTPC::~AliHFEpidTPC(){
   // Destructor
   //
   if(fPID) delete fPID;
-  if(fQAList){
-    delete fQAList;
-  }
 }
 
 //___________________________________________________________________
@@ -138,37 +148,22 @@ Bool_t AliHFEpidTPC::InitializePID(){
 }
 
 //___________________________________________________________________
-Int_t AliHFEpidTPC::IsSelected(AliHFEpidObject *track)
+Int_t AliHFEpidTPC::IsSelected(AliHFEpidObject *track, AliHFEpidQAmanager *pidqa)
 {
   //
   // For the TPC pid we use the 2-sigma band around the bethe bloch curve
   // for electrons
   // exclusion of the crossing points
   //
-  if(track->fAnalysisType == AliHFEpidObject::kESDanalysis){
-    AliESDtrack *esdTrack = NULL;
-    if(!(esdTrack = dynamic_cast<AliESDtrack *>(track->fRecTrack))) return 0;
-    AliMCParticle *mctrack = dynamic_cast<AliMCParticle *>(track->fMCtrack);
-    return MakePIDesd(esdTrack, mctrack);
-  }else{
-    AliAODTrack *aodtrack = NULL;
-    if(!(aodtrack = dynamic_cast<AliAODTrack *>(track->fRecTrack))) return 0;
-    AliAODMCParticle *aodmctrack = dynamic_cast<AliAODMCParticle *>(track->fMCtrack);
-    return MakePIDaod(aodtrack, aodmctrack);
-  }
-}
-//___________________________________________________________________
-Int_t AliHFEpidTPC::MakePIDesd(AliESDtrack *esdTrack, AliMCParticle *mctrack){
-  //
-  //  Doing TPC PID as explained in IsSelected for ESD tracks
-  //
-  if(!fESDpid){
-    AliError("No ESD PID object available");
-    return kFALSE;
-  }
+
+  if((!fESDpid && track->IsESDanalysis()) || (!fAODpid && track->IsAODanalysis())) return 0;
+  
+  // QA before selection
+  if(pidqa) pidqa->ProcessTrack(track, AliHFEpid::kTPCpid, AliHFEdetPIDqa::kBeforePID);
   AliDebug(1, "Doing TPC PID based on n-Sigma cut approach");
-  Float_t nsigma = fESDpid->NumberOfSigmasTPC(esdTrack, AliPID::kElectron);
-  if(IsQAon()) FillTPChistograms(esdTrack, mctrack, kFALSE);
+  AliHFEpidObject::AnalysisType_t anatype = track->IsESDanalysis() ? AliHFEpidObject::kESDanalysis : AliHFEpidObject::kAODanalysis;
+  Float_t nsigma = NumberOfSigmas(track->GetRecTrack(), AliPID::kElectron, anatype);
+  AliDebug(1, Form("TPC NSigma: %f", nsigma));
   // exclude crossing points:
   // Determine the bethe values for each particle species
   Bool_t isLineCrossing = kFALSE;
@@ -176,7 +171,7 @@ Int_t AliHFEpidTPC::MakePIDesd(AliESDtrack *esdTrack, AliMCParticle *mctrack){
   for(Int_t ispecies = 0; ispecies < AliPID::kSPECIES; ispecies++){
     if(ispecies == AliPID::kElectron) continue;
     if(!(fLineCrossingsEnabled & 1 << ispecies)) continue;
-    if(TMath::Abs(fESDpid->NumberOfSigmasTPC(esdTrack, (AliPID::EParticleType)ispecies)) < fLineCrossingSigma[ispecies] && TMath::Abs(nsigma) < fNsigmaTPC){
+    if(TMath::Abs(NumberOfSigmas(track->GetRecTrack(), (AliPID::EParticleType)ispecies, anatype)) < fLineCrossingSigma[ispecies] && TMath::Abs(nsigma) < fNsigmaTPC){
       // Point in a line crossing region, no PID possible, but !PID still possible ;-)
       isLineCrossing = kTRUE;      
       fLineCrossingType = ispecies;
@@ -187,58 +182,53 @@ Int_t AliHFEpidTPC::MakePIDesd(AliESDtrack *esdTrack, AliMCParticle *mctrack){
 
   // Check particle rejection
   if(HasParticleRejection()){
-    Int_t reject = Reject(esdTrack);
+    Int_t reject = Reject(track->GetRecTrack(), anatype);
     if(reject != 0) return reject;
   }
 
   // Check if we have an asymmetric sigma model set
   Int_t pdg = 0;
   if(fUpperSigmaCut || fLowerSigmaCut){
-    pdg = CutSigmaModel(esdTrack) ? 11 : 0;
+    pdg = CutSigmaModel(track->GetRecTrack(), anatype) ? 11 : 0;
   } else { 
     // Perform Asymmetric n-sigma cut if required, else perform symmetric TPC sigma cut
     Float_t p = 0.;
-    if(HasAsymmetricSigmaCut() && (p = esdTrack->P()) >= fPAsigCut[0] && p <= fPAsigCut[1]){ 
+    if(HasAsymmetricSigmaCut() && (p = track->GetRecTrack()->P()) >= fPAsigCut[0] && p <= fPAsigCut[1]){ 
       if(nsigma >= fNAsigmaTPC[0] && nsigma <= fNAsigmaTPC[1]) pdg = 11; 
     } else {
       if(TMath::Abs(nsigma) < fNsigmaTPC ) pdg = 11;
     }
   }
-  if(IsQAon() && pdg != 0) FillTPChistograms(esdTrack, mctrack, kTRUE);
+  if(pidqa && pdg != 0) pidqa->ProcessTrack(track, AliHFEpid::kTPCpid, AliHFEdetPIDqa::kAfterPID);
   return pdg;
-}
 
-//___________________________________________________________________
-Int_t AliHFEpidTPC::MakePIDaod(AliAODTrack * /*aodTrack*/, AliAODMCParticle * /*mctrack*/){
-  AliError("AOD PID not yet implemented");
-  return 0;
 }
 
 //___________________________________________________________________
-Bool_t AliHFEpidTPC::CutSigmaModel(AliESDtrack *track){
+Bool_t AliHFEpidTPC::CutSigmaModel(const AliVParticle *track, AliHFEpidObject::AnalysisType_t anaType){
   //
   // N SigmaCut using parametrization of the cuts
   //
   Bool_t isSelected = kTRUE;
-  Float_t nsigma = fESDpid->NumberOfSigmasTPC(track, AliPID::kElectron);
-  Double_t p =  track->GetInnerParam() ? track->GetInnerParam()->P() : track->P();
+  Float_t nsigma = NumberOfSigmas(track, AliPID::kElectron, anaType);
+  Double_t p = track->P();
   if(fUpperSigmaCut && nsigma > fUpperSigmaCut->Eval(p)) isSelected = kFALSE;
   if(fLowerSigmaCut && nsigma < fLowerSigmaCut->Eval(p)) isSelected = kFALSE;
   return isSelected;
 }
 
 //___________________________________________________________________
-Int_t AliHFEpidTPC::Reject(AliESDtrack *track){
+Int_t AliHFEpidTPC::Reject(const AliVParticle *track, AliHFEpidObject::AnalysisType_t anaType){
   //
   // reject particles based on asymmetric sigma cut
   //
   Int_t pdc[AliPID::kSPECIES] = {11,13,211,321,2212};
-  Double_t p = track->GetOuterParam() ? track->GetOuterParam()->P() : track->P();
+  Double_t p = track->P();
   for(Int_t ispec = 0; ispec < AliPID::kSPECIES; ispec++){
     if(!TESTBIT(fRejectionEnabled, ispec)) continue;
     // Particle rejection enabled
     if(p < fRejection[4*ispec] || p > fRejection[4*ispec+2]) continue;
-    Double_t sigma = fESDpid->NumberOfSigmasTPC(track, static_cast<AliPID::EParticleType>(ispec));
+    Double_t sigma = NumberOfSigmas(track, static_cast<AliPID::EParticleType>(ispec), anaType);
     if(sigma >= fRejection[4*ispec+1] && sigma <= fRejection[4*ispec+3]) return pdc[ispec] * track->Charge();
   }
   return 0;
@@ -259,140 +249,18 @@ void AliHFEpidTPC::AddTPCdEdxLineCrossing(Int_t species, Double_t sigma){
 }
 
 //___________________________________________________________________
-Double_t AliHFEpidTPC::Likelihood(const AliESDtrack *track, Int_t species, Float_t rsig)
-{
-  //gives probability for track to come from a certain particle species;
-  //no priors considered -> probabilities for equal abundances of all species!
-  //optional restriction to r-sigma bands of different particle species; default: rsig = 2. (see below)
-
-  //IMPORTANT: Tracks which are judged to be outliers get negative likelihoods -> unusable for combination with further detectors!
-  
-  if(!track) return -1.;
-  Bool_t outlier = kTRUE;
-  // Check whether distance from the respective particle line is smaller than r sigma
-  for(Int_t hypo = 0; hypo < AliPID::kSPECIES; hypo++){
-    if(TMath::Abs(fESDpid->NumberOfSigmasTPC(track, (AliPID::EParticleType)hypo)) > rsig)
-      outlier = kTRUE;
-    else {
-           outlier = kFALSE;
-           break;
-         }
-  }
-  if(outlier)
-    return -2.;
-
-  Double_t tpcProb[5];
-
-  track->GetTPCpid(tpcProb);
-
-  return tpcProb[species];
-}
-
-//___________________________________________________________________
-Double_t  AliHFEpidTPC::Suppression(const AliESDtrack *track, Int_t species)
-{
-  //ratio of likelihoods to be whatever species/to be an electron;
-  //as a cross-check for possible particle type suppression compared to electrons
-  const Double_t kVerySmall = 1e-10;
-  if(!track) return -20;
-  if((TMath::Abs(Likelihood(track,species) + 2) < kVerySmall)||(TMath::Abs(Likelihood(track,0) + 2 ) < kVerySmall))
-    return -30;
-  if(TMath::Abs(Likelihood(track,species)) < kVerySmall)
-    return -10;
-  if (TMath::Abs(Likelihood(track,0)) < kVerySmall)
-    return 10.;
-  else
-    return TMath::Log10(Likelihood(track,species)/(Likelihood(track,0)));
-
-
-}
-
-//___________________________________________________________________
-void AliHFEpidTPC::FillTPChistograms(const AliESDtrack *track, const AliMCParticle *mctrack, Bool_t stepSelected){
-  // 
-  // Fill the QA histogtrams
+Double_t AliHFEpidTPC::NumberOfSigmas(const AliVParticle *track, AliPID::EParticleType species, AliHFEpidObject::AnalysisType_t anaType){
+  //    
+  // Get the number of sigmas
   //
-  if(!track)
-    return;
-  Double_t tpcSignal = track->GetTPCsignal();
-  Double_t p = track->GetInnerParam() ? track->GetInnerParam()->P() : track->P();
-  Int_t species = -1;
-  THnSparse *hptr = NULL;
-  if(HasMCData() && mctrack){
-    switch(TMath::Abs(mctrack->Particle()->GetPdgCode())){
-      case 11:   
-        species = AliPID::kElectron;
-        if(!stepSelected){
-          Double_t contentElHist[4];
-          for(Int_t ispec = AliPID::kMuon; ispec < AliPID::kSPECIES; ispec++){
-            contentElHist[0] = ispec;
-            contentElHist[1] = p;
-            contentElHist[2] = -Suppression(track, ispec);
-            contentElHist[3] = Likelihood(track, ispec);
-            hptr = dynamic_cast<THnSparseF *>(fQAList->Get("fHistTPCel"));
-            hptr->Fill(contentElHist);
-          }
-        }
-             break;
-      case 13:    species = AliPID::kMuon; break;
-      case 211:   species = AliPID::kPion; break;
-      case 321:   species = AliPID::kKaon; break;
-      case 2212:  species = AliPID::kProton; break; 
-      default:    species = -1; break;
-    }
-    if(!stepSelected){
-      // Fill Probability Histogram
-      Double_t contentProb[3] = {species , p, Likelihood(track, 0)};
-      hptr = dynamic_cast<THnSparseF *>(fQAList->Get("fHistTPCprob"));
-      hptr->Fill(contentProb);
-      // Fill suppression Histogram
-      if(species > 0 && species < AliPID::kSPECIES){
-        Double_t contentSup[3] = {species, p, Suppression(track, species)};
-        hptr = dynamic_cast<THnSparseF *>(fQAList->Get("fHistTPCsuppression"));
-        hptr->Fill(contentSup);
-      }
-    }
+  Double_t nSigmas = 100;
+  if(anaType == AliHFEpidObject::kESDanalysis){
+    // ESD analysis
+    const AliESDtrack *esdtrack = dynamic_cast<const AliESDtrack *>(track);
+    if(esdtrack && fESDpid) nSigmas = fESDpid->NumberOfSigmasTPC(esdtrack, species);
+  } else {
+    const AliAODTrack *aodtrack = dynamic_cast<const AliAODTrack *>(track);
+    if(aodtrack && fAODpid) nSigmas = fAODpid->NumberOfSigmasTPC(aodtrack, species);
   }
-  
-  // Fill signal histogram
-  Double_t contentSignal[5] = {species, p, tpcSignal, fESDpid->NumberOfSigmasTPC(track, AliPID::kElectron), stepSelected ? 1 : 0};
-  hptr = dynamic_cast<THnSparseF *>(fQAList->Get("fHistTPCsignal"));
-  hptr->Fill(contentSignal);
+  return nSigmas;
 }
-
-//___________________________________________________________________
-void AliHFEpidTPC::AddQAhistograms(TList *qaList){
-  //
-  // Create QA histograms for TPC PID
-  //
-  fQAList = new AliHFEcollection("fQAhistosTPC", "TPC QA histos");
-  
-  // First THnSparse we fill with the signal
-  const Int_t kNdimSignal  = 5;
-  Int_t nBins[kNdimSignal];
-  Double_t binMin[kNdimSignal], binMax[kNdimSignal];
-  nBins[0] = AliPID::kSPECIES + 1; binMin[0] = -1.; binMax[0] = AliPID::kSPECIES; // MC Species;
-  nBins[1] = 1000; binMin[1] = 0.; binMax[1] = 20.; 
-  nBins[2] = 6000; binMin[2] = 0.; binMax[2] = 600.;
-  nBins[3] = 1400; binMin[3] = -12.; binMax[3] = 12.;
-  nBins[4] = 2; binMin[4] = 0.; binMax[4] = nBins[4];  // Selected or not
-  fQAList->CreateTHnSparse("fHistTPCsignal", "TPC signal; Species; p [GeV/c]; TPC Signal [a.u.]; Normalized TPC distance to the electron Line [#sigma]; Selection Status", kNdimSignal, nBins, binMin, binMax);
-
-  const Int_t kNdimProbEl = 3;
-  nBins[2] = 200; binMin[2] = 0.; binMax[2] = 1.;
-  fQAList->CreateTHnSparse("fHistTPCprob", "TPC Likelihood to be an electron; Species; p [GeV/c]; TPC Likelihood [a.u.]", kNdimProbEl, nBins, binMin, binMax);
-
-  const Int_t kNdimSuppression = 3;
-  nBins[2] = 200; binMin[2] = -1.; binMax[2] = 5.8;  // log10 of TPC Likelihood(species)/Likelihood(elec) for species i neq electron
-  fQAList->CreateTHnSparse("fHistTPCsuppression", "TPC non-electron Suppression; Species; p [GeV/c]; Suppression [a.u.]", kNdimSuppression, nBins, binMin, binMax);
-
-  const Int_t kNdimEle = 4;
-  nBins[0] = AliPID::kSPECIES - 1; binMin[0] = 1.; binMax[0] = AliPID::kSPECIES;
-  nBins[2] = 100; binMin[2] = -1.; binMax[2] = 5.8;
-  nBins[3] = 200; binMin[3] = 0.; binMax[3] = 1.; 
-  fQAList->CreateTHnSparse("fHistTPCel", "TPC electron Histogram; Species; p [GeV/c]; Electron Enhancement:Electron Likelihood", kNdimEle, nBins, binMin, binMax);
-
-  qaList->AddLast(fQAList->GetList());
-}
-
index 6fe69397c1384e4e580bc8b486759dcdda6005e1..94f2c43ac2f5c05e49af656774a79010d7053cac 100644 (file)
@@ -33,20 +33,20 @@ class AliAODTrack;
 class AliAODMCParticle;
 class AliESDtrack;
 class AliMCParticle;
-class AliESDpid;
 class AliVParticle;
 class AliHFEcollection;
+class AliHFEpidQAmanager;
 
 class AliHFEpidTPC : public AliHFEpidBase{
   public:
+    AliHFEpidTPC();
     AliHFEpidTPC(const Char_t *name);
     AliHFEpidTPC(const AliHFEpidTPC &ref);
     AliHFEpidTPC &operator=(const AliHFEpidTPC &ref);
     virtual ~AliHFEpidTPC();
     
     virtual Bool_t InitializePID();
-    virtual Int_t IsSelected(AliHFEpidObject *track);
-    virtual Bool_t HasQAhistos() const { return kTRUE; };
+    virtual Int_t IsSelected(AliHFEpidObject *track, AliHFEpidQAmanager *pidqa);
 
     Int_t GetCrossingType() const {return fLineCrossingType; }
 
@@ -62,15 +62,10 @@ class AliHFEpidTPC : public AliHFEpidBase{
 
   protected:
     void Copy(TObject &o) const;
-    void AddQAhistograms(TList *qaList);
-    void FillTPChistograms(const AliESDtrack *track, const AliMCParticle *mctrack, Bool_t stepSelected = kFALSE);
-    Int_t MakePIDaod(AliAODTrack *aodTrack, AliAODMCParticle *mcTrack);
-    Int_t MakePIDesd(AliESDtrack *esdTrack, AliMCParticle *mcTrack);
-    Int_t Reject(AliESDtrack *track);
-    Double_t Likelihood(const AliESDtrack *track, Int_t species, Float_t rsig = 2.);
-    Double_t Suppression(const AliESDtrack *track, Int_t species);
+    Double_t NumberOfSigmas(const AliVParticle *track, AliPID::EParticleType species, AliHFEpidObject::AnalysisType_t);
+    Int_t Reject(const AliVParticle *track, AliHFEpidObject::AnalysisType_t anaType);
 
-    Bool_t CutSigmaModel(AliESDtrack *track);
+    Bool_t CutSigmaModel(const AliVParticle *track, AliHFEpidObject::AnalysisType_t anaType);
 
   private:
     enum{
@@ -88,7 +83,6 @@ class AliHFEpidTPC : public AliHFEpidBase{
     Float_t fRejection[4*AliPID::kSPECIES];                 // All informations for Particle Rejection, order pmin, sigmin, pmax, sigmax
     UChar_t fRejectionEnabled;                              // Bitmap for enabled particle rejection
     AliPID *fPID;                                           //! PID Object
-    AliHFEcollection *fQAList;                              //! QA histograms
 
   ClassDef(AliHFEpidTPC, 1)   // TPC Electron ID class
 };
index 6e78b9e7a63c3fd4f19b2c212e37287bac9604bd..73b3cb8f40014b7c57987bc2ea396b174d983b7b 100644 (file)
@@ -27,6 +27,7 @@
 #include <TList.h>
 #include <TString.h>
 
+#include "AliAODpidUtil.h"
 #include "AliAODTrack.h"
 #include "AliAODMCParticle.h"
 #include "AliESDtrack.h"
@@ -35,7 +36,7 @@
 #include "AliMCParticle.h"
 #include "AliPID.h"
 
-#include "AliHFEcollection.h"
+#include "AliHFEpidQAmanager.h"
 #include "AliHFEpidTRD.h"
 
 ClassImp(AliHFEpidTRD)
@@ -48,12 +49,10 @@ AliHFEpidTRD::AliHFEpidTRD() :
   , fMinP(1.)
   , fElectronEfficiency(0.91)
   , fPIDMethod(kNN)
-  , fContainer(NULL)
 {
   //
   // default  constructor
   // 
-  memset(fThreshParams, 0, sizeof(Double_t) * kThreshParams);
 }
 
 //___________________________________________________________________
@@ -62,7 +61,6 @@ AliHFEpidTRD::AliHFEpidTRD(const char* name) :
   , fMinP(1.)
   , fElectronEfficiency(0.91)
   , fPIDMethod(kNN)
-  , fContainer(NULL)
 {
   //
   // default  constructor
@@ -76,7 +74,6 @@ AliHFEpidTRD::AliHFEpidTRD(const AliHFEpidTRD &ref):
   , fMinP(ref.fMinP)
   , fElectronEfficiency(ref.fElectronEfficiency)
   , fPIDMethod(ref.fPIDMethod)
-  , fContainer(NULL)
 {
   //
   // Copy constructor
@@ -107,7 +104,6 @@ void AliHFEpidTRD::Copy(TObject &ref) const {
   target.fPIDMethod = fPIDMethod;
   target.fElectronEfficiency = fElectronEfficiency;
   memcpy(target.fThreshParams, fThreshParams, sizeof(Double_t) * kThreshParams);
-  if(fContainer) target.fContainer = dynamic_cast<AliHFEcollection *>(fContainer->Clone());
   AliHFEpidBase::Copy(ref);
 }
 
@@ -116,8 +112,6 @@ AliHFEpidTRD::~AliHFEpidTRD(){
   //
   // Destructor
   //
-  if(fContainer)
-    delete fContainer;
 }
 
 //______________________________________________________
@@ -134,55 +128,35 @@ Bool_t AliHFEpidTRD::InitializePID(){
 }
 
 //______________________________________________________
-Int_t AliHFEpidTRD::IsSelected(AliHFEpidObject *track){
+Int_t AliHFEpidTRD::IsSelected(AliHFEpidObject *track, AliHFEpidQAmanager *pidqa){
   //
   // Does PID for TRD alone:
   // PID thresholds based on 90% Electron Efficiency level approximated by a linear 
   // step function
   //
-  if(track->fAnalysisType == AliHFEpidObject::kESDanalysis){
-      AliESDtrack *esdTrack = dynamic_cast<AliESDtrack *>(track->fRecTrack);
-      if(!esdTrack) return 0;
-      AliMCParticle *esdmc = dynamic_cast<AliMCParticle *>(track->fMCtrack);
-      return MakePIDesd(esdTrack, esdmc);
-   } else {
-     AliAODTrack *aodTrack = dynamic_cast<AliAODTrack *>(track->fRecTrack);
-     if(!aodTrack) return 0;
-     AliAODMCParticle *aodmc = dynamic_cast<AliAODMCParticle *>(track->fMCtrack);
-     return MakePIDaod(aodTrack, aodmc);
-   }
-}
-
-//______________________________________________________
-Int_t AliHFEpidTRD::MakePIDaod(AliAODTrack * /*aodTrack*/, AliAODMCParticle * /*aodmc*/){
-  //
-  // Does PID decision for AOD tracks as discribed above
-  //
-  AliError("AOD PID not yet implemented");
-  return 0;
-}
+  AliDebug(1, "Applying TRD PID");
+  if((!fESDpid && track->IsESDanalysis()) || (!fAODpid && track->IsAODanalysis())){ 
+    AliDebug(1, "Cannot process track");
+    return 0;
+  }
 
-//______________________________________________________
-Int_t AliHFEpidTRD::MakePIDesd(AliESDtrack *esdTrack, AliMCParticle * /*mcTrack*/){
-  //
-  // Does PID decision for ESD tracks as discribed above
-  //
-  Double_t p = esdTrack->GetOuterParam() ? esdTrack->GetOuterParam()->P() : esdTrack->P();
-  if(IsQAon())
-    FillStandardQA(0, esdTrack);
-  if(p < fMinP) return 0;
+  AliHFEpidObject::AnalysisType_t anatype = track->IsESDanalysis() ? AliHFEpidObject::kESDanalysis: AliHFEpidObject::kAODanalysis;
+  Double_t p = GetP(track->GetRecTrack(), anatype);
+  if(p < fMinP){ 
+    AliDebug(1, Form("Track momentum below %f", fMinP));
+    return 0;
+  }
 
-  Double_t pidProbs[AliPID::kSPECIES];
-  esdTrack->GetTRDpid(pidProbs);
+  if(pidqa) pidqa->ProcessTrack(track, AliHFEpid::kTRDpid, AliHFEdetPIDqa::kBeforePID); 
+  Double_t electronLike = GetElectronLikelihood(track->GetRecTrack(), anatype);
   Double_t threshold = GetTRDthresholds(fElectronEfficiency, p);
   AliDebug(1, Form("Threshold: %f\n", threshold));
-  if(IsQAon()) fContainer->Fill("fTRDthresholds", p, threshold);
-  if(pidProbs[AliPID::kElectron] > threshold){
-    if(IsQAon()) 
-      FillStandardQA(1, esdTrack);
+  if(electronLike > threshold){
+    if(pidqa) pidqa->ProcessTrack(track, AliHFEpid::kTRDpid, AliHFEdetPIDqa::kAfterPID);
     return 11;
   }
   return 211;
+
 }
 
 //___________________________________________________________________
@@ -275,7 +249,39 @@ void AliHFEpidTRD::GetParameters(Double_t electronEff, Double_t *parameters){
 }
 
 //___________________________________________________________________
-Double_t AliHFEpidTRD::GetTRDSignalV1(AliESDtrack *track, Int_t mcPID){
+Double_t AliHFEpidTRD::GetElectronLikelihood(const AliVParticle *track, AliHFEpidObject::AnalysisType_t anaType){
+  //
+  // Get TRD likelihoods for ESD respectively AOD tracks
+  //
+  Double_t pidProbs[AliPID::kSPECIES]; memset(pidProbs, 0, sizeof(Double_t) * AliPID::kSPECIES);
+  if(anaType == AliHFEpidObject::kESDanalysis){
+    const AliESDtrack *esdtrack = dynamic_cast<const AliESDtrack *>(track);
+    esdtrack->GetTRDpid(pidProbs);
+  } else {
+    const AliAODTrack *aodtrack = dynamic_cast<const AliAODTrack *>(track);
+    fAODpid->MakeTRDPID(const_cast<AliAODTrack *>(aodtrack), pidProbs);
+  }
+  return pidProbs[AliPID::kElectron];
+}
+
+//___________________________________________________________________
+Double_t AliHFEpidTRD::GetP(const AliVParticle *track, AliHFEpidObject::AnalysisType_t anaType){
+  //
+  // Get the Momentum in the TRD
+  //
+  Double_t p = 0.;
+  if(anaType == AliHFEpidObject::kESDanalysis){
+    const AliESDtrack *esdtrack = dynamic_cast<const AliESDtrack *>(track);
+    p = esdtrack->GetOuterParam() ? esdtrack->GetOuterParam()->P() : esdtrack->P();
+  } else {
+    const AliAODTrack *aodtrack = dynamic_cast<const AliAODTrack *>(track);
+    p = aodtrack->P();
+  }
+  return p;
+}
+
+//___________________________________________________________________
+Double_t AliHFEpidTRD::GetTRDSignalV1(const AliESDtrack *track){
   //
   // Calculation of the TRD Signal via truncated mean
   // Method 1: Take all Slices available
@@ -304,12 +310,11 @@ Double_t AliHFEpidTRD::GetTRDSignalV1(AliESDtrack *track, Int_t mcPID){
   Double_t trdSignal = TMath::Mean(static_cast<Int_t>(static_cast<Double_t>(icnt) * 2./3.), trdSlices);
   Double_t mom = track->GetOuterParam() ? track->GetOuterParam()->P() : -1;
   AliDebug(3, Form("PID Meth. 1: p[%f], TRDSignal[%f]", mom, trdSignal));
-  if(IsQAon() && mom > 0.) FillHistogramsTRDSignal(trdSignal, mom, mcPID, 1);
   return trdSignal;
 }
 
 //___________________________________________________________________
-Double_t AliHFEpidTRD::GetTRDSignalV2(AliESDtrack *track, Int_t mcPID){
+Double_t AliHFEpidTRD::GetTRDSignalV2(const AliESDtrack *track){
   //
   // Calculation of the TRD Signal via truncated mean
   // Method 2: Take only first 5 slices per chamber
@@ -339,84 +344,5 @@ Double_t AliHFEpidTRD::GetTRDSignalV2(AliESDtrack *track, Int_t mcPID){
   Double_t trdSignal = TMath::Mean(cntRemaining, trdSlicesRemaining);
   Double_t mom = track->GetOuterParam() ? track->GetOuterParam()->P() : -1;
   AliDebug(3, Form("PID Meth. 2: p[%f], TRDSignal[%f]", mom, trdSignal));
-  if(IsQAon() && mom > 0.) FillHistogramsTRDSignal(trdSignal, mom, mcPID, 2);
   return trdSignal;
 }
-
-//___________________________________________________________________
-void AliHFEpidTRD::FillHistogramsTRDSignal(Double_t signal, Double_t p, Int_t species, UInt_t version){
-  //
-  // Fill histograms for TRD Signal from Method 2 vs. p for different particle species
-  // Non-standard QA content
-  //
-  if(version == 0 || version > 2) return;
-  if(species >= AliPID::kSPECIES || species < -1) species = -1;
-  Double_t content[3] = {species, p, signal};
-  Char_t histname[256]; sprintf(histname, "fTRDsignalV%d", version);
-  THnSparseF *hsig = dynamic_cast<THnSparseF *>(fContainer->Get(histname));
-  if(hsig) hsig->Fill(content);
-}
-
-//___________________________________________________________________
-void AliHFEpidTRD::AddQAhistograms(TList *l){
-  //
-  // Adding QA histograms for the TRD PID
-  // QA histograms are:
-  // + TRD Signal from Meth. 1 vs p for all species
-  // + TRD Signal from Meth. 2 vs p for all species
-  // + For each species
-  //    - TRD Signal from Meth. 1 vs p
-  //    - TRD Signal from Meth. 2 vs p
-  //
-  const Int_t kMomentumBins = 100;
-  const Double_t kPtMin = 0.1;
-  const Double_t kPtMax = 20.;
-  
-  if(!fContainer) fContainer = new AliHFEcollection("fQAhistosTRD", "TRD QA histos");
-  fContainer->CreateTH2F("fTRDlikeBefore", "TRD Electron Likelihood before cut; p [GeV/c]; TRD Electron Likelihood", kMomentumBins, kPtMin, kPtMax, 1000, 0, 1);
-  fContainer->CreateTH2F("fTRDlikeAfter", "TRD Electron Likelihood after cut; p [GeV/c]; TRD Electron Likelihood", kMomentumBins, kPtMin, kPtMax, 1000, 0, 1);
-  fContainer->CreateTH2F("fTRDthresholds", "TRD Electron Thresholds; p [GeV/c]; Thresholds", kMomentumBins, kPtMin, kPtMax, 1000, 0., 1.);
-  fContainer->CreateTH2F("fTPCsignalBefore", "TPC dEdx Spectrum before TRD PID; p [GeV/c]; TPC Signal [a.u.]", kMomentumBins, kPtMin, kPtMax, 100, 0., 100.);
-  fContainer->CreateTH2F("fTPCsignalAfter", "TPC dEdx Spectrum before TRD PID; p [GeV/c]; TPC Signal [a.u.]", kMomentumBins, kPtMin, kPtMax, 100, 0., 100.);
-  fContainer->CreateTH2F("fTPCsigmaBefore", "TPC dEdx before TRD PID; p [GeV/c]; Normalized TPC distance to the electron line [n#sigma]", kMomentumBins, kPtMin, kPtMax, 100, -10., 10.);
-  fContainer->CreateTH2F("fTPCsigmaAfter", "TPC dEdx Spectrum before TRD PID; p [GeV/c]; Normalized TPC distance to the electron line [n#sigma]", kMomentumBins, kPtMin, kPtMax, 100, -10., 10.);
-
-  // Monitor THnSparse for TRD Signal
-  const Int_t kBinsTRDsignal = 3; 
-  Int_t nBins[kBinsTRDsignal] = {AliPID::kSPECIES +1, kMomentumBins, 100};
-  Double_t binMin[kBinsTRDsignal] = {-1, kPtMin, 0};
-  Double_t binMax[kBinsTRDsignal] = {AliPID::kSPECIES, kPtMax, 1000};
-  fContainer->CreateTHnSparse("fTRDsignalV1", "TRD Signal V1", kBinsTRDsignal, nBins, binMin, binMax);
-  fContainer->CreateTHnSparse("fTRDsignalV2", "TRD Signal V2", kBinsTRDsignal, nBins, binMin, binMax);
-
-  // Make logatithmic binning
-  TString hnames[7] = {"fTRDlikeBefore", "fTRDlikeAfter", "fTRDthresholds", "fTRDsignalBefore", "fTRDsignalAfter", "fTPCsigmaBefore", "fTPCsigmaAfter"};
-  for(Int_t ihist = 0; ihist < 7; ihist++)
-    fContainer->BinLogAxis(hnames[ihist].Data(), 0);
-  fContainer->BinLogAxis("fTRDsignalV1", 1);
-  fContainer->BinLogAxis("fTRDsignalV2", 1);
-
-  l->Add(fContainer->GetList());
-}
-
-//___________________________________________________________________
-void AliHFEpidTRD::FillStandardQA(Int_t whenFilled, AliESDtrack *esdTrack){
-  //
-  // Fill Likelihood Histogram before respectively after decision
-  //
-  Double_t p =  esdTrack->P();
-  Double_t like[AliPID::kSPECIES];
-  esdTrack->GetTRDpid(like);
-  TString step;
-  if(whenFilled)
-    step = "After";
-  else
-    step = "Before";
-  TString histos[3] = {"fTRDlike", "fTPCsignal", "fTPCsigma"};
-  for(Int_t ihist = 0; ihist < 3; ihist++) histos[ihist] += step;
-  fContainer->Fill(histos[0].Data(), esdTrack->P(), like[AliPID::kElectron]);
-  fContainer->Fill(histos[1].Data(), p, esdTrack->GetTPCsignal());
-  const Double_t sigmaShift = 1.;
-  if(fESDpid)
-    fContainer->Fill(histos[2].Data(), p, fESDpid->NumberOfSigmasTPC(esdTrack, AliPID::kElectron) - sigmaShift);
-}
index 84d73575354d4e2d614537eddc20fdd911f445d7..6c8988776d02c2cb6e61abbe6c3fc3b915a888e7 100644 (file)
@@ -57,11 +57,10 @@ class AliHFEpidTRD : public AliHFEpidBase{
     virtual ~AliHFEpidTRD();
     
     virtual Bool_t InitializePID();
-    virtual Int_t IsSelected(AliHFEpidObject *track);
-    virtual Bool_t HasQAhistos() const { return kTRUE; };
+    virtual Int_t IsSelected(AliHFEpidObject *track, AliHFEpidQAmanager *pidqa);
 
-    Double_t GetTRDSignalV1(AliESDtrack *track, Int_t mcPID);
-    Double_t GetTRDSignalV2(AliESDtrack *track, Int_t mcPID);
+    Double_t GetTRDSignalV1(const AliESDtrack *track);
+    Double_t GetTRDSignalV2(const AliESDtrack *track);
 
     Bool_t IsCalculateTRDSignals() const { return TestBit(kTRDsignals); }
     void SetPIDMethod(PIDMethodTRD_t method) { fPIDMethod = method; };
@@ -75,23 +74,18 @@ class AliHFEpidTRD : public AliHFEpidBase{
       kTRDsignals = BIT(16)
     };
     void Copy(TObject &ref) const;
-    Int_t MakePIDesd(AliESDtrack *esdTrack, AliMCParticle *mcTrack);
-    Int_t MakePIDaod(AliAODTrack *aofTrack, AliAODMCParticle *aodMC);
-    Int_t GetMCpid(AliESDtrack *track);
+    Double_t GetElectronLikelihood(const AliVParticle *track, AliHFEpidObject::AnalysisType_t anaType);
+    Double_t GetP(const AliVParticle *track, AliHFEpidObject::AnalysisType_t anaType);
     void InitParameters();
     void InitParameters1DLQ();
-    virtual void AddQAhistograms(TList *l);
     void GetParameters(Double_t electronEff, Double_t *parameters);
 
-    void FillStandardQA(Int_t whenFilled, AliESDtrack *esdTrack);
-    void FillHistogramsTRDSignal(Double_t signal, Double_t p, Int_t species, UInt_t version);
   private:
     static const Double_t fgkVerySmall;                       // Check for 0
     Double_t fMinP;                                         // Minimum momentum above which TRD PID is applied
     Double_t fElectronEfficiency;                           // Cut on electron efficiency
     PIDMethodTRD_t fPIDMethod;                              // PID Method: 2D Likelihood or Neural Network
     Double_t fThreshParams[kThreshParams];                  // Threshold parametrisation
-    AliHFEcollection *fContainer;                                      // QA  Histogram Container
   ClassDef(AliHFEpidTRD, 1)     // TRD electron ID class
 };
 
index 728ad02c14fcd08b77a8ccc07f1cb5950c14c5ca..9ac3adab9f0d3b6ab0fc05c90e74019dc58303c9 100644 (file)
@@ -22,6 +22,7 @@
 //
 //  Autor: Markus Fasel
 //
+
 #include <TAxis.h>
 #include <TCanvas.h>
 #include <TFile.h>
@@ -31,6 +32,7 @@
 #include "AliCFContainer.h"
 #include "AliCFEffGrid.h"
 
+#include "AliHFEcontainer.h"
 #include "AliHFEcuts.h"
 #include "AliHFEpostAnalysis.h"
 
@@ -87,18 +89,11 @@ AliHFEpostAnalysis::~AliHFEpostAnalysis(){
 }
 
 //____________________________________________________________
-Int_t AliHFEpostAnalysis::SetResults(TList *input){
+Int_t AliHFEpostAnalysis::SetTaskQA(const TList *input){
   //
   // Publish the results to the post analysis
   //
   Int_t nFound = 0;
-  fEfficiencyContainer = dynamic_cast<AliCFContainer *>(input->FindObject("trackContainer"));
-  if(!fEfficiencyContainer){
-    AliError("Efficiency Correction Framework Container not found in the list of outputs");
-  } else {
-    SETBIT(fAnalysisObjects, kCFC);
-    nFound++;
-  }
   fPIDperformance = dynamic_cast<THnSparseF *>(input->FindObject("PIDperformance"));
   if(!fPIDperformance){
     AliError("Histogram fPIDperformance not found in the List of Outputs");
@@ -233,7 +228,8 @@ void AliHFEpostAnalysis::DrawEfficiency(){
   TCanvas *cEff = new TCanvas("cEff", "Efficiency", 800, 600);
   cEff->Divide(2,2);
   if(!fEfficiencyContainer) return;
-  AliCFEffGrid *effCalc = new AliCFEffGrid("effCalc", "Efficiency Calculation Grid", *fEfficiencyContainer);
+  AliCFContainer *tracks = fEfficiencyContainer->MakeMergedCFContainer("trackContCombined", "MC + Rec(reco) Track Information", "MCTrackCont:recTrackContReco");
+  AliCFEffGrid *effCalc = new AliCFEffGrid("effCalc", "Efficiency Calculation Grid", *tracks);
   effCalc->CalculateEfficiency(AliHFEcuts::kStepMCInAcceptance, AliHFEcuts::kStepMCGenerated);
   TH1 *effReconstructibleP = effCalc->Project(0);
   effReconstructibleP->SetName("effReconstructibleP");
@@ -247,7 +243,7 @@ void AliHFEpostAnalysis::DrawEfficiency(){
   effReconstructibleP->SetStats(kFALSE);
   cEff->cd(1);
   effReconstructibleP->Draw("e");
-  effCalc->CalculateEfficiency(AliHFEcuts::kStepMCsignal, AliHFEcuts::kStepMCGenerated);
+  effCalc->CalculateEfficiency(AliHFEcuts::kStepMCGeneratedZOutNoPileUp, AliHFEcuts::kStepMCGenerated);
   TH1 *effSignal = effCalc->Project(0);
   effSignal->SetName("effSignal");
   effSignal->SetTitle("Efficiency of Signal Electrons");
@@ -260,7 +256,7 @@ void AliHFEpostAnalysis::DrawEfficiency(){
   effSignal->SetStats(kFALSE);
   cEff->cd(2);
   effSignal->Draw("e");
-  effCalc->CalculateEfficiency(AliHFEcuts::kStepPID + 2*AliHFEcuts::kNcutStepsESDtrack, AliHFEcuts::kStepMCGenerated);
+  effCalc->CalculateEfficiency(tracks->GetNStep() - 1, AliHFEcuts::kStepMCGenerated);
   TH1 *effPIDP = effCalc->Project(0);
   effPIDP->SetName("effPIDP");
   effPIDP->SetTitle("Efficiency of selected tracks");
@@ -273,7 +269,7 @@ void AliHFEpostAnalysis::DrawEfficiency(){
   effPIDP->SetStats(kFALSE);
   cEff->cd(3);
   effPIDP->Draw("e");
-  effCalc->CalculateEfficiency(AliHFEcuts::kStepPID + 2*AliHFEcuts::kNcutStepsESDtrack, AliHFEcuts::kStepMCInAcceptance);
+  effCalc->CalculateEfficiency(tracks->GetNStep() - 1, AliHFEcuts::kStepMCInAcceptance);
   TH1 *effPIDAcc = effCalc->Project(0);
   effPIDAcc->SetName("effPIDAcc");
   effPIDAcc->SetTitle("Efficiency of selected tracks in acceptance");
@@ -422,68 +418,72 @@ void AliHFEpostAnalysis::DrawCutEfficiency(Bool_t MC, Int_t source){
   leg->SetBorderSize(0);
   leg->SetFillColor(kWhite);
   leg->SetFillStyle(0);
-  const char* names[AliHFEcuts::kNcutStepsTrack - 1] = {"Acceptance", "No Cuts", "Rec Tracks" "Rec Kine(TPC/ITS)", "Primary", "HFE ITS", "HFE TRD", "PID", };
-  Color_t color[AliHFEcuts::kNcutStepsTrack - 1] = {kRed, kGreen, kMagenta, kBlack, kOrange, kTeal, kViolet, kBlue};
-  Marker_t marker[AliHFEcuts::kNcutStepsTrack - 1] = {24, 25, 26, 27, 28, 29, 30}; 
+
+  AliCFContainer *tracks = fEfficiencyContainer->MakeMergedCFContainer("mergedTracks", "Container for MC and reconstructed Track information", "MCTrackCont:recTrackContReco");
+  Int_t nStepMC = fEfficiencyContainer->GetCFContainer("MCTrackCont")->GetNStep();
+  AliDebug(1, Form("Number of MC Cut Steps: %d", nStepMC));
+  const Int_t markerStart = 24;
+  const Int_t colorStart = 1;
   TH1 *hTemp = NULL;
 
   if(MC){
     if(source > -1 && source < 4){
       AliInfo(Form("Setting source to %d", source))
-      for(Int_t istep = 0; istep < fEfficiencyContainer->GetNStep(); istep++) fEfficiencyContainer->GetAxis(4, istep)->SetRange(source + 1, source + 1);
+      for(Int_t istep = 0; istep < tracks->GetNStep(); istep++) tracks->GetAxis(4, istep)->SetRange(source + 1, source + 1);
     }
   }
-  AliCFEffGrid effcalc("cutEfficiency", "Cut step efficiency calculation", *fEfficiencyContainer);
+  AliCFEffGrid effcalc("cutEfficiency", "Cut step efficiency calculation", *tracks);
   Bool_t first = kTRUE;
   // Calculate efficiency for MC Steps
+  Int_t histcounter = 0;
   if(MC){
     //
     // Draw plots related to MC values
     //
     effcalc.CalculateEfficiency(AliHFEcuts::kStepMCInAcceptance, AliHFEcuts::kStepMCGenerated);
     hTemp = effcalc.Project(0);
-    hTemp->SetName("hEff1");
+    hTemp->SetName(Form("hEff%d", histcounter));
     hTemp->SetTitle("Cut Step Efficiency");
-    hTemp->SetMarkerColor(color[0]);
-    hTemp->SetMarkerStyle(marker[0]);
-    hTemp->GetXaxis()->SetTitle("P / GeV/c");
+    hTemp->SetMarkerColor(colorStart + histcounter);
+    hTemp->SetMarkerStyle(markerStart + histcounter);
+    hTemp->GetXaxis()->SetTitle("p / GeV/c");
     hTemp->GetYaxis()->SetTitle("Efficiency");
     hTemp->GetYaxis()->SetRangeUser(0., 2.);
     hTemp->SetStats(kFALSE);
     hTemp->Draw("ep");
-    leg->AddEntry(hTemp, names[0], "p");
-    effcalc.CalculateEfficiency(AliHFEcuts::kStepRecNoCut + 2*AliHFEcuts::kNcutStepsESDtrack, AliHFEcuts::kStepMCGenerated);
+    leg->AddEntry(hTemp, tracks->GetStepTitle(AliHFEcuts::kStepMCInAcceptance), "p");
+    histcounter++;
+    effcalc.CalculateEfficiency(nStepMC, AliHFEcuts::kStepMCGenerated);
     hTemp = effcalc.Project(0);
     hTemp->SetName("hEff2");
     hTemp->SetTitle("Cut Step Efficiency");
-    hTemp->SetMarkerColor(color[1]);
-    hTemp->SetMarkerStyle(marker[1]);
-    hTemp->GetXaxis()->SetTitle("P / GeV/c");
+    hTemp->SetMarkerColor(colorStart + histcounter);
+    hTemp->SetMarkerStyle(markerStart + histcounter);
+    hTemp->GetXaxis()->SetTitle("p / GeV/c");
     hTemp->GetYaxis()->SetTitle("Efficiency");
     hTemp->GetYaxis()->SetRangeUser(0., 2.);
     hTemp->SetStats(kFALSE);
     hTemp->Draw("epsame");
-    leg->AddEntry(hTemp, names[1], "p");
+    leg->AddEntry(hTemp, tracks->GetStepTitle(nStepMC), "p");
     first = kFALSE;
+    histcounter++;
   }
-  for(Int_t istep = AliHFEcuts::kStepRecKineITSTPC; istep <= AliHFEcuts::kStepPID; istep++){
-    effcalc.CalculateEfficiency(istep + 2*AliHFEcuts::kNcutStepsESDtrack, istep-1 + 2*AliHFEcuts::kNcutStepsESDtrack); 
+  for(Int_t istep = nStepMC+1; istep < tracks->GetNStep(); istep++){
+    effcalc.CalculateEfficiency(istep, istep - 1); 
     hTemp = effcalc.Project(0);
     hTemp->SetName(Form("hEff%d", istep));
     hTemp->SetTitle("Cut Step Efficiency");
-    hTemp->SetMarkerColor(color[istep-2]);
-    hTemp->SetMarkerStyle(marker[istep-2]);
+    hTemp->SetMarkerColor(colorStart + histcounter);
+    hTemp->SetMarkerStyle(markerStart + histcounter);
     hTemp->SetStats(kFALSE);
     hTemp->Draw(first ? "ep" : "epsame");
     hTemp->GetXaxis()->SetTitle("P / GeV/c");
     hTemp->GetYaxis()->SetTitle("Efficiency");
     hTemp->GetYaxis()->SetRangeUser(0., 2.);
-    leg->AddEntry(hTemp, names[istep-2], "p");
+    leg->AddEntry(hTemp, tracks->GetStepTitle(istep), "p");
     first = kFALSE;
+    histcounter++;
   }
   leg->Draw();
-  // undo axis restriction
-  if(MC && source > -1 && source < 4){
-    for(Int_t istep = 0; istep < fEfficiencyContainer->GetNStep(); istep++) fEfficiencyContainer->GetAxis(4, istep)->SetRange(0, 4);
-  }
+  delete tracks;
 }
index b2da25a7983c5478fe2c5cb1f379d1d8a6a9d280..dae9ecf380ebb512ae90fce617d520bc78b424c5 100644 (file)
 #include <THnSparse.h>
 #endif
 
-class AliCFContainer;
+class AliHFEcontainer;
 class TH1;
 class TList;
+
 class AliHFEpostAnalysis : public TObject{
   public:
     AliHFEpostAnalysis();
@@ -34,7 +35,8 @@ class AliHFEpostAnalysis : public TObject{
     AliHFEpostAnalysis &operator=(const AliHFEpostAnalysis &ref);
     ~AliHFEpostAnalysis();
 
-    Int_t SetResults(TList *input);
+    Int_t SetTaskResults(AliHFEcontainer *trackContainer) { fEfficiencyContainer = trackContainer; return 1; };
+    Int_t SetTaskQA(const TList *qa);
     void StoreOutput(const char *filename = "HFEresults.root");
 
     void DrawMCSignal2Background();
@@ -52,7 +54,7 @@ class AliHFEpostAnalysis : public TObject{
 
     TList *fResults;                          // Container for output objects
     UChar_t fAnalysisObjects;                       // S
-    AliCFContainer *fEfficiencyContainer;     // Task Results
+    AliHFEcontainer *fEfficiencyContainer;     // Task Results
     THnSparseF *fPIDperformance;              // PID Performance Studies
     THnSparseF *fSignalToBackgroundMC;        // Signal To Background Studies
 
index d416cb1d8207d81a5c7b661738c1bf81d924a78c..71870201581ad3f0c96a26cb88572b2431e12efd 100644 (file)
@@ -195,7 +195,7 @@ void AliHFEpriVtx::FillNtracks()
 }
 
 //_______________________________________________________________________________________________
-Int_t AliHFEpriVtx::GetMCPID(AliESDtrack *track) 
+Int_t AliHFEpriVtx::GetMCPID(AliESDtrack const *track)
 {
         //
         // get MC pid
@@ -340,7 +340,7 @@ Double_t AliHFEpriVtx::GetDistanceFromRecalVertexXY(AliESDtrack * const ESDelect
 
 }
 
-void AliHFEpriVtx::RecalcPrimvtx(Int_t nkftrk, Int_t * const trkid, AliKFParticle * const kftrk)
+void AliHFEpriVtx::RecalcPrimvtx(Int_t nkftrk, const Int_t * const trkid, const AliKFParticle * const kftrk)
 {
         //
         // recalculate primary vertex after removing the input track
index abbc3d2b3497b98b0ef63b7c6e7168ac96520766..c47236c4da3b53d18e03e348eccf2758681b8663 100644 (file)
@@ -51,7 +51,7 @@ class AliHFEpriVtx : public TObject {
                 void FillNtracks(); // fill counted number of tracks
                 void CountPriVxtElecContributor(AliESDtrack *ESDelectron, Int_t sourcePart, Int_t recpid, Double_t recprob); 
                 void FillNprimVtxContributor() const;
-                void RecalcPrimvtx(Int_t nkftrk, Int_t * const, AliKFParticle * const); //recalculate primary vertex after removing given tracks
+                void RecalcPrimvtx(Int_t nkftrk, const Int_t * const, const AliKFParticle * const); //recalculate primary vertex after removing given tracks
                 void RecalcPrimvtx(AliESDtrack * const ESDelectron); //recalculate primary vertex after removing given track
                 void GetRecalcPrimvtx(Double_t privtx[3]) const {
                     privtx[0]=fPVxRe; privtx[1]=fPVyRe; privtx[2]=fPVzRe;
@@ -59,7 +59,7 @@ class AliHFEpriVtx : public TObject {
                 void GetNPriVxtContributor();
                 Double_t GetDistanceFromRecalVertexXY(AliESDtrack * const ESDelectron);
                            Int_t GetNsectrk2prim() const {return fNsectrk2prim;}; 
-                Int_t GetMCPID(AliESDtrack *track); // return mc pid
+                Int_t GetMCPID(AliESDtrack const *track); // return mc pid
 
 
         private:
index 4cc3dc34ccc6e96b35428600b58ecd08a67b09ca..9396dd2601e45538a08cabe7620502c9ca981f8a 100644 (file)
@@ -40,6 +40,8 @@
 #include "AliHFEpairs.h"
 #include "AliHFEsecVtxs.h"
 #include "AliHFEtrackFilter.h"
+#include "AliHFEmcQA.h"
+#include "AliHFEtools.h"
 
 ClassImp(AliHFEsecVtx)
 
@@ -49,6 +51,7 @@ AliHFEsecVtx::AliHFEsecVtx():
   ,fESD1(0x0)
   ,fAOD1(0x0)
   ,fMCEvent(0x0)
+  ,fMCQA(0x0)
   ,fUseMCPID(kFALSE)
   ,fkSourceLabel()
   ,fNparents(0)
@@ -94,6 +97,7 @@ AliHFEsecVtx::AliHFEsecVtx(const AliHFEsecVtx &p):
   ,fESD1(0x0)
   ,fAOD1(0x0)
   ,fMCEvent(0x0)
+  ,fMCQA(0x0)
   ,fUseMCPID(p.fUseMCPID)
   ,fkSourceLabel()
   ,fNparents(p.fNparents)
@@ -205,8 +209,13 @@ void AliHFEsecVtx::Process(AliVTrack *signalTrack){
   //
   // Run Process
   //
-  if(signalTrack->Pt() < 1.0) return;
+  //if(signalTrack->Pt() < 1.0) return;
+  
+
   AliESDtrack *track = dynamic_cast<AliESDtrack *>(signalTrack);
+
+  FillHistos(0,track); // wo any cuts
+
   InitHFEpairs();
   InitHFEsecvtxs();
   AliESDtrack *htrack = 0x0; 
@@ -220,20 +229,29 @@ void AliHFEsecVtx::Process(AliVTrack *signalTrack){
     PairAnalysis(track, htrack, htrack->GetID()); // e-h pairing
   }
   delete trackIter;
-  /*for(int ip=0; ip<fSecVtx->HFEpairs()->GetEntriesFast(); ip++){
-      if(HasMCData()){
-        AliHFEpairs *pair = (AliHFEpairs*) (fSecVtx->HFEpairs()->UncheckedAt(ip));
-        if(!(pair->GetPairCode()>1. && pair->GetPairCode()<4.))  // apply various cuts
-        fSecVtx->HFEpairs()->RemoveAt(ip);
-      }
-    }*/
+  for(int ip=0; ip<HFEpairs()->GetEntriesFast(); ip++){
+    //if(HasMCData()){
+    AliHFEpairs *pair = (AliHFEpairs*) (HFEpairs()->UncheckedAt(ip));
+    //if(!(pair->GetPairCode()>1. && pair->GetPairCode()<4.))  // apply various cuts
+    if(pair->GetKFChi2()>5.) // only apply vertex chi2 cut for the moment
+      HFEpairs()->RemoveAt(ip);
+    //}
+  }
   HFEpairs()->Compress();
-  RunSECVTX(track); // secondary vertexing with e,h1,h2,.. tracks
+  if(HFEpairs()->GetEntriesFast()) FillHistos(1,track); // after paired 
+  if(HFEpairs()->GetEntriesFast()) RunSECVTX(track); // secondary vertexing with e,h1,h2,.. tracks
+  if(HFEsecvtxs()->GetEntriesFast()) FillHistos(2,track); // after secvtxing
   for(int ip=0; ip<HFEsecvtxs()->GetEntriesFast(); ip++){
     AliHFEsecVtxs *secvtx=0x0;
     secvtx = (AliHFEsecVtxs*) (HFEsecvtxs()->UncheckedAt(ip));
-    // here you apply cuts, then if it doesn't pass the cut, remove it from the fSecVtx->HFEsecvtxs() 
+    // here you apply cuts, then if it doesn't pass the cut, remove it from the HFEsecvtxs() 
+    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))
+      HFEsecvtxs()->RemoveAt(ip);
   }
+
+  // fill histos for raw spectra
+  if(HFEsecvtxs()->GetEntriesFast()) FillHistos(3,track); //after secvtx cut
+    
   DeleteHFEpairs();
   DeleteHFEsecvtxs();
 }
@@ -251,6 +269,11 @@ void AliHFEsecVtx::CreateHistograms(TList * const qaList)
   fSecVtxList->SetName("SecVtx");
 
   MakeContainer();
+  MakeHistos(0);
+  MakeHistos(1);
+  MakeHistos(2);
+  MakeHistos(3);
+
   /*
   fkSourceLabel[kAll]="all";
   fkSourceLabel[kDirectCharm]="directCharm";
@@ -929,7 +952,10 @@ void AliHFEsecVtx::CalcSECVTXProperty(AliVTrack* track1, AliVTrack* track2, AliV
 }
 
 //_______________________________________________________________________________________________
-void AliHFEsecVtx::RecalcPrimvtx(Int_t nkftrk, Int_t * const trkid, AliKFParticle * const kftrk){
+void AliHFEsecVtx::RecalcPrimvtx(Int_t nkftrk, const Int_t * const trkid, const AliKFParticle * const kftrk){
+  //
+  // reccalculate primary vertex after removing considering track in the calculation
+  //
 
   const AliESDVertex *primvtx = fESD1->GetPrimaryVertex();
 
@@ -959,7 +985,7 @@ void AliHFEsecVtx::RecalcPrimvtx(Int_t nkftrk, Int_t * const trkid, AliKFParticl
 }
 
 //_______________________________________________________________________________________________
-Int_t AliHFEsecVtx::GetMCPID(AliESDtrack *track) 
+Int_t AliHFEsecVtx::GetMCPID(const AliESDtrack *track) 
 {
   //      
   // return mc pid
@@ -1403,7 +1429,7 @@ Int_t AliHFEsecVtx::GetPDG(AliVTrack *track)
 }
 
 //_______________________________________________________________________________________________
-Int_t AliHFEsecVtx::GetMCPDG(AliVTrack *track)
+Int_t AliHFEsecVtx::GetMCPDG(const AliVTrack *track)
 {
   //
   // return mc pdg code
@@ -1552,25 +1578,6 @@ void AliHFEsecVtx::InitHFEsecvtxs()
   fNoOfHFEsecvtxs = 0;
 }
 
-//_______________________________________________________________________________________________
-Bool_t AliHFEsecVtx::SingleTrackCut(AliESDtrack* track) const
-{
-  //if (track->Pt() < 1.0) return kFALSE;
-  //if (TMath::Abs(track->Eta()) > 0.9) return kFALSE;
-  //if (!(track->GetStatus() & AliESDtrack::kITSrefit)) return kFALSE;
-  //if (!(track->GetStatus() & AliESDtrack::kTPCrefit)) return kFALSE;
-  if (!(TESTBIT(track->GetITSClusterMap(),0))) return kFALSE; // ask hit on the first pixel layer
-  //if (!(TESTBIT(track->GetITSClusterMap(),0) | TESTBIT(track->GetITSClusterMap(),1))) return kFALSE;
-
-/*
-  Float_t dcaR=-1;
-  Float_t dcaZ=-1;
-  track->GetImpactParameters(dcaR,dcaZ);
-  if (TMath::Abs(TMath::Sqrt(dcaR*dcaR + dcaZ*dcaZ)) < 0.005) return kFALSE;
-  if (TMath::Abs(TMath::Sqrt(dcaR*dcaR + dcaZ*dcaZ)) > 0.3) return kFALSE;
-*/
-  return kTRUE;
-}
 //____________________________________________________________
 void AliHFEsecVtx::MakeContainer(){
 
@@ -1644,3 +1651,69 @@ void AliHFEsecVtx::MakeContainer(){
   for(Int_t ivar = 0; ivar < nDimSecvtx; ivar++)
     delete binEdgesSecvtx[ivar];
 }
+
+//____________________________________________________________
+void AliHFEsecVtx::MakeHistos(Int_t step){
+
+  //
+  // make container
+  //
+  
+  TString hname=Form("step%d",step);
+  step = step*7;
+
+  const Double_t kPtbound[2] = {0.1, 20.};
+  Int_t iBin[1];
+  iBin[0] = 44; // bins in pt
+  Double_t* binEdges[1];
+  binEdges[0] =  AliHFEtools::MakeLogarithmicBinning(iBin[0], kPtbound[0], kPtbound[1]);
+
+  fSecVtxList->AddAt(new TH1F(hname+"taggedElec", "pT of e", iBin[0],binEdges[0]), step);
+  fSecVtxList->AddAt(new TH1F(hname+"charmElec", "pT of e", iBin[0],binEdges[0]), step+1);
+  fSecVtxList->AddAt(new TH1F(hname+"beautyElec", "pT of e", iBin[0],binEdges[0]), step+2);
+  fSecVtxList->AddAt(new TH1F(hname+"conversionElec", "pT of e", iBin[0],binEdges[0]), step+3);
+  fSecVtxList->AddAt(new TH1F(hname+"ebgElec", "pT of e", iBin[0],binEdges[0]), step+4);
+  fSecVtxList->AddAt(new TH1F(hname+"hcontaminElec", "pT of e", iBin[0],binEdges[0]), step+5);
+  fSecVtxList->AddAt(new TH1F(hname+"elseElec", "pT of e", iBin[0],binEdges[0]), step+6);
+}
+
+//____________________________________________________________
+void AliHFEsecVtx::FillHistos(Int_t step, const AliESDtrack *track){
+
+  //
+  // make container
+  //
+  
+  step = step*7;
+
+  AliMCParticle *mctrack = NULL;
+  TParticle* mcpart = NULL;
+
+  (dynamic_cast<TH1F *>(fSecVtxList->At(step)))->Fill(track->Pt()); // electrons tagged
+
+  if(HasMCData()){
+    if(!(mctrack = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(TMath::Abs(track->GetLabel()))))) return;
+    mcpart = mctrack->Particle();
+
+    Int_t esource=fMCQA->GetElecSource(mcpart);
+    if(esource==1) {
+      (dynamic_cast<TH1F *>(fSecVtxList->At(step+1)))->Fill(mcpart->Pt()); //charm
+    }
+    else if(esource==2 || esource==3) {
+      (dynamic_cast<TH1F *>(fSecVtxList->At(step+2)))->Fill(mcpart->Pt()); //beauty
+    }
+    else if(esource==4) {
+      (dynamic_cast<TH1F *>(fSecVtxList->At(step+3)))->Fill(mcpart->Pt()); //conversion
+    }
+    else if(esource==7) {
+      (dynamic_cast<TH1F *>(fSecVtxList->At(step+5)))->Fill(mcpart->Pt()); //contamination
+    }
+    else if(!(esource<0)) {
+      (dynamic_cast<TH1F *>(fSecVtxList->At(step+4)))->Fill(mcpart->Pt()); //e backgrounds
+    }
+    else {
+      (dynamic_cast<TH1F *>(fSecVtxList->At(step+6)))->Fill(mcpart->Pt()); //something else?
+    }
+  }
+
+} 
index cfac67b3935f88c2488feed42f803c3c4496c714..c8fb79a388555b3226adaed77fb6da9ee6f9b58a 100644 (file)
@@ -42,6 +42,7 @@ class AliHFEtrackFilter;
 class AliHFEpairs;
 class AliHFEsecVtxs;
 class AliKFParticle;
+class AliHFEmcQA;
 
 //________________________________________________________________
 class AliHFEsecVtx : public TObject {
@@ -68,10 +69,11 @@ class AliHFEsecVtx : public TObject {
     void SetMCEvent(AliMCEvent* const mcEvent){fMCEvent=mcEvent;};  // set stack pointer
     void SetMCArray(TClonesArray* const mcarry){fMCArray=mcarry;} // set mcarray pointer
     void SetUseMCPID(Bool_t usemcpid){fUseMCPID=usemcpid;};
+    void SetMCQA(AliHFEmcQA * const mcqa){fMCQA=mcqa;};    // set mcqa pointer
 
 
-    Int_t GetMCPID(AliESDtrack *track); // return MC pid
-               Int_t GetMCPDG(AliVTrack *track);   // return MC pid
+    Int_t GetMCPID(const AliESDtrack *track); // return MC pid
+               Int_t GetMCPDG(const AliVTrack *track);   // return MC pid
     Int_t GetPairOriginESD(AliESDtrack* track1, AliESDtrack* track2); // return pair origin as a pdg code
     Int_t GetPairOriginAOD(AliAODTrack* track1, AliAODTrack* track2); // return pair origin as a pdg code
     Int_t GetPairCode(const AliVTrack* const track1, const AliVTrack* const track2); // return corresponding pair code to pdg code
@@ -79,7 +81,7 @@ class AliHFEsecVtx : public TObject {
     Int_t GetPDG(AliVTrack *track);     // return pdg 
                void GetESDPID(AliESDtrack *track, Int_t &recpid, Double_t &recprob); //return esd pid likelihood
     void GetPrimaryCondition();
-    void RecalcPrimvtx(Int_t nkftrk, Int_t * const, AliKFParticle * const); //recalculate primary vertex
+    void RecalcPrimvtx(Int_t nkftrk, const Int_t * const, const AliKFParticle * const); //recalculate primary vertex
 
     TClonesArray *HFEpairs();
     TClonesArray *HFEsecvtxs();
@@ -93,11 +95,12 @@ class AliHFEsecVtx : public TObject {
     void DeleteHFEpairs();
     void DeleteHFEsecvtxs();
 
-    Bool_t SingleTrackCut(AliESDtrack* track1) const; // single track cut
     void PairAnalysis(AliVTrack* ESDtrack1, AliVTrack* ESDtrack2, Int_t index2); // do e-h analysis
     void RunSECVTX(AliVTrack *track); // run secondary vertexing algorithm
 
     void MakeContainer(); // make containers
+    void MakeHistos(Int_t step); // make histograms for different steps
+    void FillHistos(Int_t step, const AliESDtrack *track); // fill histograms for different steps
 
   protected:
     void Init();
@@ -122,6 +125,8 @@ class AliHFEsecVtx : public TObject {
     AliAODEvent* fAOD1; // AOD pointer             
     AliMCEvent* fMCEvent;   // MCEvent pointer              
 
+    AliHFEmcQA* fMCQA;  // mcqa pointer
+
     Bool_t fUseMCPID;   // if use MC pid 
 
     TString fkSourceLabel[10]; // electron source label
diff --git a/PWG3/hfe/AliHFEsignalCuts.cxx b/PWG3/hfe/AliHFEsignalCuts.cxx
new file mode 100644 (file)
index 0000000..0d25d7b
--- /dev/null
@@ -0,0 +1,309 @@
+/**************************************************************************
+* 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.                  *
+**************************************************************************/
+//
+// Signal cuts
+// Checks whether a particle (reconstructed or MC) is coming from MC Signal
+// For more information see implementation file
+//
+// Autor:
+//   Markus Fasel <M.Fasel@gsi.de>
+//
+#include <TClass.h>
+#include <TMath.h>
+#include <TParticle.h>
+#include <TString.h>
+
+#include "AliAODMCParticle.h"
+#include "AliLog.h"
+#include "AliMCEvent.h"
+#include "AliMCParticle.h"
+#include "AliVParticle.h"
+
+#include "AliHFEsignalCuts.h"
+#include "AliHFEmcQA.h"
+
+ClassImp(AliHFEsignalCuts)
+
+//____________________________________________________________
+AliHFEsignalCuts::AliHFEsignalCuts():
+  AliAnalysisCuts(),
+  fMC(NULL),
+  fMCQA(NULL)
+{
+  //
+  // Dummy constructor
+  //
+}
+
+//____________________________________________________________
+AliHFEsignalCuts::AliHFEsignalCuts(const Char_t *name, const Char_t *title):
+  AliAnalysisCuts(name, title),
+  fMC(NULL),
+  fMCQA(NULL)
+{
+  //
+  // Default constructor
+  //
+  fMCQA = new AliHFEmcQA;
+  if(fMCQA) fMCQA->Init();
+}
+
+//____________________________________________________________
+AliHFEsignalCuts::AliHFEsignalCuts(const AliHFEsignalCuts &ref):
+  AliAnalysisCuts(ref),
+  fMC(ref.fMC),
+  fMCQA(ref.fMCQA)
+{
+  //
+  // Copy constructor
+  //
+}
+
+//____________________________________________________________
+AliHFEsignalCuts &AliHFEsignalCuts::operator=(const AliHFEsignalCuts &ref){
+  //
+  // Assignment operator
+  //
+  if(this != &ref){
+    fMC = ref.fMC; 
+    fMCQA = ref.fMCQA; 
+  }
+  return *this;
+}
+
+//____________________________________________________________
+AliHFEsignalCuts::~AliHFEsignalCuts(){
+  //
+  // Destructor
+  //
+  if(fMCQA) delete fMCQA;
+}
+
+//____________________________________________________________
+void AliHFEsignalCuts::SetMCEvent(AliMCEvent *mc){ 
+  //
+  // Set mc event
+  //
+  fMC = mc; 
+  if(fMCQA) fMCQA->SetMCEvent(mc);
+}
+
+//____________________________________________________________
+Bool_t AliHFEsignalCuts::IsSelected(TObject *o){
+  //
+  // Define signal as electron coming from charm or beauty
+  // @TODO: Implement setter so that also either of them can be defined
+  // as signal alone
+  
+
+  return IsCharmElectron(o) || IsBeautyElectron(o);
+/*  
+  //saving time?
+  Int_t esources = GetElecSource(dynamic_cast<const AliVParticle *>(o));
+  if(esources>0)printf("esources= %d\n",esources);
+  if(esources == AliHFEmcQA::kDirectCharm || esources == AliHFEmcQA::kDirectBeauty || esources == AliHFEmcQA::kBeautyCharm)  // 1: direct D->e, 2: B->e 3: B->D->e
+    return kTRUE;
+  else
+    return kFALSE;
+*/
+
+}
+
+//____________________________________________________________
+Bool_t AliHFEsignalCuts::IsCharmElectron(const TObject * const o) const {
+  //
+  // Check if mother is coming from Charm
+  //
+  Int_t esources = GetElecSource(dynamic_cast<const AliVParticle *>(o));
+  if(esources == AliHFEmcQA::kDirectCharm)  // 1: direct D->e
+    return kTRUE;
+  else
+    return kFALSE;
+}
+
+//____________________________________________________________
+Bool_t AliHFEsignalCuts::IsBeautyElectron(const TObject * const o) const {
+  //
+  // Check if mother is coming from Beauty
+  //
+  Int_t esources = GetElecSource(dynamic_cast<const AliVParticle *>(o));
+  if(esources == AliHFEmcQA::kDirectBeauty || esources == AliHFEmcQA::kBeautyCharm)  // 2: B->e 3: B->D->e
+    return kTRUE;
+  else
+    return kFALSE;
+}
+
+//____________________________________________________________
+Bool_t AliHFEsignalCuts::IsGammaElectron(const TObject * const o) const {
+  //
+  // Check for MC if the electron is coming from Gamma
+  //
+  Int_t esources = GetElecSource(dynamic_cast<const AliVParticle *>(o));
+  if(esources == AliHFEmcQA::kGamma)  // 4: conversion electrons
+    return kTRUE;
+  else
+    return kFALSE;
+}
+
+/*
+//____________________________________________________________
+Bool_t AliHFEsignalCuts::IsCharmElectron(const TObject * const o) const {
+  //
+  // Check if mother is coming from Charm
+  //
+  if(TMath::Abs(GetTrackPDG(dynamic_cast<const AliVParticle *>(o))) != 11) return kFALSE;
+  Int_t motherpdg = TMath::Abs(GetMotherPDG(dynamic_cast<const AliVParticle *>(o)));
+  AliDebug(1, Form("Mother PDG %d\n", motherpdg));
+
+  if((motherpdg % 1000) / 100 == 4) return kTRUE;    // charmed meson, 3rd position in pdg code == 4
+  if(motherpdg / 1000 == 4) return kTRUE;            // charmed baryon, 4th position in pdg code == 4
+  AliDebug(1, "No Charm\n");
+  return kFALSE;
+}
+
+//____________________________________________________________
+Bool_t AliHFEsignalCuts::IsBeautyElectron(const TObject * const o) const {
+  //
+  // Check if mother is coming from Beauty
+  //
+  if(TMath::Abs(GetTrackPDG(dynamic_cast<const AliVParticle *>(o))) != 11) return kFALSE;
+  Int_t motherpdg = TMath::Abs(GetMotherPDG(dynamic_cast<const AliVParticle *>(o)));
+  AliDebug(1, Form("Mother PDG %d\n", motherpdg));
+
+  if((motherpdg % 1000) / 100 == 5) return kTRUE;   // beauty meson, 3rd position in pdg code == 5
+  if(motherpdg / 1000 == 5) return kTRUE;           // beauty baryon, 4th position in pdg code == 5   
+  AliDebug(1, "No Beauty\n");
+  return kFALSE;
+}
+
+//____________________________________________________________
+Bool_t AliHFEsignalCuts::IsGammaElectron(const TObject * const o) const {
+  //
+  // Check for MC if the electron is coming from Gamma
+  //
+  if(TMath::Abs(GetTrackPDG(dynamic_cast<const AliVParticle *>(o))) != 11) return kFALSE;
+  Int_t motherpdg = TMath::Abs(GetMotherPDG(dynamic_cast<const AliVParticle *>(o)));
+  AliDebug(1, Form("Mother PDG %d\n", motherpdg));
+
+  if(motherpdg!=22){
+    AliDebug(1, "No Gamma");
+    return kFALSE;
+  } else { 
+    AliDebug(1, "Gamma");
+    return kTRUE;
+  }
+}
+*/
+
+//____________________________________________________________
+Int_t AliHFEsignalCuts::GetMotherPDG(const AliVParticle * const track) const {
+  //
+  // Get Mother Pdg code for reconstructed respectively MC tracks
+  // 
+  if(!fMC){
+    AliDebug(1, "No MC Event Available\n");
+    return 0;
+  }
+  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 = fMC->GetTrack(TMath::Abs(track->GetLabel()));
+  } else {
+    // MCParticle
+    mctrack = track;
+  }
+
+  if(!mctrack) return 0;
+  
+  Int_t motherPDG = 0;
+  if(TString(mctrack->IsA()->GetName()).CompareTo("AliMCParticle") == 0){
+    // case MC Particle
+    motherParticle = fMC->GetTrack((dynamic_cast<const AliMCParticle *>(mctrack)->Particle()->GetFirstMother()));
+    if(motherParticle)
+      motherPDG = TMath::Abs((dynamic_cast<const AliMCParticle *>(motherParticle))->Particle()->GetPdgCode());
+  } else {
+    // case AODMCParticle
+    motherParticle = fMC->GetTrack((dynamic_cast<const AliAODMCParticle *>(mctrack))->GetMother());
+    if(motherParticle)
+      motherPDG = TMath::Abs((dynamic_cast<const AliAODMCParticle *>(motherParticle))->GetPdgCode());
+  }
+  return motherPDG;
+}
+
+//____________________________________________________________
+Int_t AliHFEsignalCuts::GetTrackPDG(const AliVParticle * const track) const {
+       //
+       // Return PDG code of a particle itself
+       //
+  if(!fMC){
+    AliDebug(1, "No MC Event Available\n");
+    return 0;
+  }
+       TString sourcetype = track->IsA()->GetName();
+       const AliVParticle *mctrack = NULL;
+       if(!sourcetype.CompareTo("AliESDtrack") || !sourcetype.CompareTo("AliAODTrack")){
+               mctrack = fMC->GetTrack(TMath::Abs(track->GetLabel()));
+       } else  mctrack = track;
+       if(!mctrack) return 0;
+
+       TString mctype = mctrack->IsA()->GetName();
+       Int_t trackPdg = 0;
+       if(!mctype.CompareTo("AliMCParticle")){
+               const AliMCParticle *esdmc = dynamic_cast<const AliMCParticle *>(mctrack);
+               trackPdg = esdmc->Particle()->GetPdgCode();
+       } else {
+               const AliAODMCParticle *aodmc = dynamic_cast< const AliAODMCParticle *>(mctrack);
+               trackPdg = aodmc->GetPdgCode();
+       }
+       return trackPdg;
+}
+
+//____________________________________________________________
+Int_t AliHFEsignalCuts::GetElecSource(const AliVParticle * const track) const {
+       //
+       // Return PDG code of a particle itself
+       //
+       
+        if(!fMC){
+          AliDebug(1, "No MC Event Available\n");
+          return 0;
+        }
+        if(!fMCQA){
+          AliDebug(1, "No MCQA Available\n");
+          return 0;
+        }
+
+        TString sourcetype = track->IsA()->GetName();
+        const AliVParticle *mctrack = NULL;
+        TParticle *mcpart = NULL;
+        if(!sourcetype.CompareTo("AliESDtrack") || !sourcetype.CompareTo("AliAODTrack")){
+                mctrack = fMC->GetTrack(TMath::Abs(track->GetLabel()));
+        } else  mctrack = track;
+        if(!mctrack) return 0;
+
+        TString mctype = mctrack->IsA()->GetName();
+        Int_t eSource = 0;
+        if(!mctype.CompareTo("AliMCParticle")){
+                const AliMCParticle *esdmc = dynamic_cast<const AliMCParticle *>(mctrack);
+                mcpart = esdmc->Particle();
+               eSource=fMCQA->GetElecSource(mcpart);
+        } else {
+                return -1;
+        }
+          
+        return eSource;
+}      
diff --git a/PWG3/hfe/AliHFEsignalCuts.h b/PWG3/hfe/AliHFEsignalCuts.h
new file mode 100644 (file)
index 0000000..3afa91c
--- /dev/null
@@ -0,0 +1,62 @@
+/**************************************************************************
+* 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.                  *
+**************************************************************************/
+//
+// Signal cuts
+// Checks whether a particle (reconstructed or MC) is coming from MC Signal
+// For more information see implementation file
+//
+#ifndef ALIHFESIGNALCUTS_H
+#define ALIHFESIGNALCUTS_H
+
+#ifndef ALIANALYSISCUTS_H
+#include "AliAnalysisCuts.h"
+#endif
+
+class TList;
+class AliMCEvent;
+class AliVParticle;
+class AliHFEmcQA;
+
+class AliHFEsignalCuts : public AliAnalysisCuts{
+  public: 
+    AliHFEsignalCuts();
+    AliHFEsignalCuts(const Char_t *name, const Char_t *title);
+    AliHFEsignalCuts(const AliHFEsignalCuts &ref);
+    AliHFEsignalCuts &operator=(const AliHFEsignalCuts &ref);
+    virtual ~AliHFEsignalCuts();
+
+    virtual Bool_t IsSelected(TObject *o);
+    virtual Bool_t IsSelected(TList * /*l*/) { return kTRUE; };
+
+    Bool_t IsCharmElectron(const TObject * const o) const;
+    Bool_t IsBeautyElectron(const TObject * const o) const;
+    Bool_t IsGammaElectron(const TObject * const o) const;
+
+    //void SetMCEvent(AliMCEvent *mc) { fMC = mc; }
+    void SetMCEvent(AliMCEvent *mc);
+  
+  protected:
+    Int_t GetMotherPDG(const AliVParticle * const track) const;
+    Int_t GetTrackPDG(const AliVParticle * const track) const;
+    Int_t GetElecSource(const AliVParticle * const track) const ;
+
+  private:
+    AliMCEvent *fMC;   //! MC event
+    AliHFEmcQA *fMCQA; //! MC QA
+
+    ClassDef(AliHFEsignalCuts, 2)
+};
+#endif
+
index 7f0312df30e2616e0a0dda52f1584c62f6f1f051..218164b7a60237a206e1bd00453bf9d6a1e46b33 100644 (file)
@@ -42,7 +42,7 @@
 #include <TPad.h>
 #include <TH2D.h>
 
-
+#include "AliPID.h"
 #include "AliCFContainer.h"
 #include "AliCFDataGrid.h"
 #include "AliCFEffGrid.h"
@@ -51,6 +51,8 @@
 #include "AliLog.h"
 
 #include "AliHFEspectrum.h"
+#include "AliHFEcuts.h"
+#include "AliHFEcontainer.h"
 
 ClassImp(AliHFEspectrum)
 
@@ -61,14 +63,18 @@ AliHFEspectrum::AliHFEspectrum(const char *name):
   fTemporaryObjects(NULL),
   fCorrelation(NULL),
   fBackground(NULL),
-  fBackgroundSource(kMCbackground),
+  fInclusiveSpectrum(kTRUE),
   fDumpToFile(kFALSE),
+  fNbDimensions(1),
   fNEvents(0),
   fStepMC(-1),
   fStepTrue(-1),
   fStepData(-1),
+  fStepBeforeCutsV0(-1),
+  fStepAfterCutsV0(-1),
   fStepGuessedUnfolding(-1),
-  fNumberOfIterations(5)
+  fNumberOfIterations(5),
+  fDebugLevel(0)
 {
   //
   // Default constructor
@@ -86,9 +92,125 @@ AliHFEspectrum::~AliHFEspectrum(){
     delete fTemporaryObjects;
   }
 }
+//____________________________________________________________
+Bool_t AliHFEspectrum::Init(AliHFEcontainer *datahfecontainer,AliHFEcontainer *mchfecontainer,AliHFEcontainer *v0hfecontainer){
+  //
+  // Init what we need for the correction:
+  //
+  // Raw spectrum, hadron contamination
+  // MC efficiency maps, correlation matrix
+  // V0 efficiency if wanted
+  //
+  // This for a given dimension.
+  // If no inclusive spectrum, then take only efficiency map for beauty electron
+  // and the appropriate correlation matrix
+  //
+
+  // Get the requested format
+  Int_t dims[3];
+  switch(fNbDimensions){
+  case 1:   dims[0] = 0;
+    break;
+  case 2:   for(Int_t i = 0; i < 2; i++) dims[i] = i;
+    break;
+  case 3:   for(Int_t i = 0; i < 3; i++) dims[i] = i;
+    break;
+  default:
+    AliError("Container with this number of dimensions not foreseen (yet)");
+    return kFALSE;
+  };
+  
+  // Data container: raw spectrum + hadron contamination  
+  AliCFContainer *datacontainer = datahfecontainer->GetCFContainer("recTrackContReco");
+  AliCFContainer *contaminationcontainer = datahfecontainer->GetCFContainer("hadronicBackground");
+  if((!datacontainer) || (!contaminationcontainer)) return kFALSE;
+
+  AliCFContainer *datacontainerD = GetSlicedContainer(datacontainer, fNbDimensions, dims);
+  AliCFContainer *contaminationcontainerD = GetSlicedContainer(contaminationcontainer, fNbDimensions, dims);
+  if((!datacontainerD) || (!contaminationcontainerD)) return kFALSE;
+  SetContainer(datacontainerD,AliHFEspectrum::kDataContainer);
+  SetContainer(contaminationcontainerD,AliHFEspectrum::kBackgroundData);
+
+  // MC container: ESD/MC efficiency maps + MC/MC efficiency maps 
+  AliCFContainer *mccontaineresd = 0x0;
+  AliCFContainer *mccontainermc = 0x0;
+  if(fInclusiveSpectrum) {
+    mccontaineresd = mchfecontainer->MakeMergedCFContainer("sumesd","sumesd","MCTrackCont:recTrackContReco");
+    mccontainermc = mchfecontainer->MakeMergedCFContainer("summc","summc","MCTrackCont:recTrackContMC");
+  }
+  else {
+    mccontaineresd = mchfecontainer->MakeMergedCFContainer("sumesd","sumesd","MCTrackCont:recTrackContReco:recTrackContDEReco");
+    mccontainermc = mchfecontainer->MakeMergedCFContainer("summc","summc","MCTrackCont:recTrackContMC:recTrackContDEMC");
+  }
+  if((!mccontaineresd) || (!mccontainermc)) return kFALSE;  
+
+  Int_t source = -1;
+  if(!fInclusiveSpectrum) source = 1;
+  AliCFContainer *mccontaineresdD = GetSlicedContainer(mccontaineresd, fNbDimensions, dims, source);
+  AliCFContainer *mccontainermcD = GetSlicedContainer(mccontainermc, fNbDimensions, dims, source);
+  if((!mccontaineresdD) || (!mccontainermcD)) return kFALSE;
+  SetContainer(mccontainermcD,AliHFEspectrum::kMCContainerMC);
+  SetContainer(mccontaineresdD,AliHFEspectrum::kMCContainerESD);
+
+  // MC container: correlation matrix
+  THnSparseF *mccorrelation = 0x0;
+  if(fInclusiveSpectrum) mccorrelation = mchfecontainer->GetCorrelationMatrix("correlationstepafterPID");
+  else mccorrelation = mchfecontainer->GetCorrelationMatrix("correlationstepafterDE");
+  if(!mccorrelation) return kFALSE;
+  THnSparseF *mccorrelationD = GetSlicedCorrelation(mccorrelation, fNbDimensions, dims);
+  if(!mccorrelationD) {
+    printf("No correlation\n");
+    return kFALSE;
+  }
+  SetCorrelation(mccorrelationD);
+
+  // V0 container Electron, pt eta phi
+  if(v0hfecontainer) {
+    AliCFContainer *containerV0 = v0hfecontainer->GetCFContainer("taggedTrackContainerReco");
+    if(!containerV0) return kFALSE;
+    AliCFContainer *containerV0Electron = GetSlicedContainer(containerV0, fNbDimensions, dims, AliPID::kElectron+1);
+    if(!containerV0Electron) return kFALSE;
+    SetContainer(containerV0Electron,AliHFEspectrum::kDataContainerV0);
+  } 
+
+  if(fDebugLevel>0){
+   
+    AliCFDataGrid *contaminationspectrum = (AliCFDataGrid *) ((AliCFDataGrid *)GetSpectrum(contaminationcontainer,1))->Clone();
+    contaminationspectrum->SetName("contaminationspectrum");
+    TCanvas * ccontaminationspectrum = new TCanvas("contaminationspectrum","contaminationspectrum",1000,700);
+    ccontaminationspectrum->Divide(3,1);
+    ccontaminationspectrum->cd(1);
+    TH2D * contaminationspectrum2dpteta = contaminationspectrum->Project(1,0);
+    TH2D * contaminationspectrum2dptphi = contaminationspectrum->Project(2,0);
+    TH2D * contaminationspectrum2detaphi = contaminationspectrum->Project(1,2);
+    contaminationspectrum2dpteta->SetStats(0);
+    contaminationspectrum2dpteta->SetTitle("");
+    contaminationspectrum2dpteta->GetXaxis()->SetTitle("#eta");
+    contaminationspectrum2dpteta->GetYaxis()->SetTitle("p_{T} [GeV/c]");
+    contaminationspectrum2dptphi->SetStats(0);
+    contaminationspectrum2dptphi->SetTitle("");
+    contaminationspectrum2dptphi->GetXaxis()->SetTitle("#phi [rad]");
+    contaminationspectrum2dptphi->GetYaxis()->SetTitle("p_{T} [GeV/c]");
+    contaminationspectrum2detaphi->SetStats(0);
+    contaminationspectrum2detaphi->SetTitle("");
+    contaminationspectrum2detaphi->GetXaxis()->SetTitle("#eta");
+    contaminationspectrum2detaphi->GetYaxis()->SetTitle("#phi [rad]");
+    contaminationspectrum2dptphi->Draw("colz");
+    ccontaminationspectrum->cd(2);
+    contaminationspectrum2dpteta->Draw("colz");
+    ccontaminationspectrum->cd(3);
+    contaminationspectrum2detaphi->Draw("colz");
+
+  }
+
+
+  return kTRUE;
+  
+}
 
 //____________________________________________________________
-void AliHFEspectrum::Correct(AliCFContainer *datacontainer,AliCFContainer *mccontainer,THnSparseF *mccorrelation, AliCFContainer *contaminationcontainer){
+Bool_t AliHFEspectrum::Correct(Bool_t subtractcontamination){
   //
   // Correct the spectrum for efficiency and unfolding
   // with both method and compare
@@ -101,71 +223,184 @@ void AliHFEspectrum::Correct(AliCFContainer *datacontainer,AliCFContainer *mccon
   gStyle->SetPadLeftMargin(0.13);
   gStyle->SetPadRightMargin(0.13);
 
-  SetMCEffStep(8);
-  SetMCTruthStep(0);
-  SetNumberOfIteration(5);
-  SetStepGuessedUnfolding(16);
-  SetNumberOfIteration(5);
-  SetStepToCorrect(20);
-  
-  //////////////////
-  // Take only pt
-  /////////////////
-  
-  AliCFDataGrid *dataspectrumbeforesubstraction = (AliCFDataGrid *) ((AliCFDataGrid *)GetSpectrum(datacontainer,20))->Clone();
-  dataspectrumbeforesubstraction->SetName("dataspectrumbeforesubstraction");
+  ///////////////////////////
+  // Check initialization
+  ///////////////////////////
 
-  //
+  if((!GetContainer(kDataContainer)) || (!GetContainer(kMCContainerMC)) || (!GetContainer(kMCContainerESD))){
+    AliInfo("You have to init before");
+    return kFALSE;
+  }
+  
+  if((fStepTrue == 0) && (fStepMC == 0) && (fStepData == 0)) {
+    AliInfo("You have to set the steps before: SetMCTruthStep, SetMCEffStep, SetStepToCorrect");
+    return kFALSE;
+  }
+  SetNumberOfIteration(50);
+  SetStepGuessedUnfolding(AliHFEcuts::kStepRecKineITSTPC + AliHFEcuts::kNcutStepsMCTrack);
+    
+  AliCFDataGrid *dataGridAfterFirstSteps = 0x0;
+  //////////////////////////////////
+  // Subtract hadron background
+  /////////////////////////////////
   AliCFDataGrid *dataspectrumaftersubstraction = 0x0;
-  SetCorrelation(mccorrelation);
-  SetContainer(datacontainer,AliHFEspectrum::kDataContainer);
-  SetContainer(mccontainer,AliHFEspectrum::kMCContainer);
-  if(contaminationcontainer) {
-    SetContainer(contaminationcontainer,AliHFEspectrum::kBackgroundData);
-    SetBackgroundSource(AliHFEspectrum::kDataBackground);
-    dataspectrumaftersubstraction = SubtractBackground(1,kTRUE);
+  if(subtractcontamination) {
+    dataspectrumaftersubstraction = SubtractBackground(kTRUE);
+    dataGridAfterFirstSteps = dataspectrumaftersubstraction;
+  }
+
+  ////////////////////////////////////////////////
+  // Correct for TPC efficiency from V0
+  ///////////////////////////////////////////////
+  AliCFDataGrid *dataspectrumafterV0efficiencycorrection = 0x0;
+  AliCFContainer *dataContainerV0 = GetContainer(kDataContainerV0);
+  if(dataContainerV0){
+    dataspectrumafterV0efficiencycorrection = CorrectV0Efficiency(dataspectrumaftersubstraction);
+    dataGridAfterFirstSteps = dataspectrumafterV0efficiencycorrection;  
   }
   
+  ///////////////
   // Unfold
-  
-  TList *listunfolded = Unfold(1,dataspectrumaftersubstraction);
+  //////////////
+  TList *listunfolded = Unfold(dataGridAfterFirstSteps);
   if(!listunfolded){
     printf("Unfolded failed\n");
-    return;
+    return kFALSE;
   }
   THnSparse *correctedspectrum = (THnSparse *) listunfolded->At(0);
   THnSparse *residualspectrum = (THnSparse *) listunfolded->At(1);
   if(!correctedspectrum){
     AliError("No corrected spectrum\n");
-    return;
+    return kFALSE;
   }
   if(!residualspectrum){
     AliError("No residul spectrum\n");
-    return;
+    return kFALSE;
   }   
   
+  /////////////////////
   // Simply correct
-  SetMCEffStep(20);  
-  AliCFDataGrid *alltogetherCorrection = CorrectForEfficiency(1,dataspectrumaftersubstraction);
+  ////////////////////
+  AliCFDataGrid *alltogetherCorrection = CorrectForEfficiency(dataGridAfterFirstSteps);
   
+
   //////////
   // Plot
   //////////
-  AliCFDataGrid *dataspectrum = 0x0;
-  TH1D *measuredTH1Daftersubstraction = 0x0;
-  TH1D *measuredTH1Dbeforesubstraction = 0x0;
-  TH1D *measuredTH1background = 0x0;
-  AliCFDataGrid *contaminationspectrum = 0x0;
-  if(dataspectrumaftersubstraction) dataspectrum = dataspectrumaftersubstraction;
-  else dataspectrum = dataspectrumbeforesubstraction;
-
-  if(dataspectrumaftersubstraction) {
+  if(fDebugLevel > 0.0) {
+  
+    TCanvas * ccorrected = new TCanvas("corrected","corrected",1000,700);
+    ccorrected->Divide(2,1);
+    ccorrected->cd(1);
+    gPad->SetLogy();
+    TGraphErrors* correctedspectrumD = Normalize(correctedspectrum);
+    correctedspectrumD->SetTitle("");
+    correctedspectrumD->GetYaxis()->SetTitleOffset(1.5);
+    correctedspectrumD->GetYaxis()->SetRangeUser(0.000000001,1.0);
+    correctedspectrumD->SetMarkerStyle(26);
+    correctedspectrumD->SetMarkerColor(kBlue);
+    correctedspectrumD->SetLineColor(kBlue);
+    correctedspectrumD->Draw("AP");
+    TGraphErrors* alltogetherspectrumD = Normalize(alltogetherCorrection);
+    alltogetherspectrumD->SetTitle("");
+    alltogetherspectrumD->GetYaxis()->SetTitleOffset(1.5);
+    alltogetherspectrumD->GetYaxis()->SetRangeUser(0.000000001,1.0);
+    alltogetherspectrumD->SetMarkerStyle(25);
+    alltogetherspectrumD->SetMarkerColor(kBlack);
+    alltogetherspectrumD->SetLineColor(kBlack);
+    alltogetherspectrumD->Draw("P");
+    TLegend *legcorrected = new TLegend(0.4,0.6,0.89,0.89);
+    legcorrected->AddEntry(correctedspectrumD,"Corrected","p");
+    legcorrected->AddEntry(alltogetherspectrumD,"Alltogether","p");
+    legcorrected->Draw("same");
+    ccorrected->cd(2);
+    TH1D *correctedTH1D = correctedspectrum->Projection(0);
+    TH1D *alltogetherTH1D = alltogetherCorrection->Project(0);
+    TH1D* ratiocorrected = (TH1D*)correctedTH1D->Clone();
+    ratiocorrected->SetName("ratiocorrected");
+    ratiocorrected->SetTitle("");
+    ratiocorrected->GetYaxis()->SetTitle("Unfolded/DirectCorrected");
+    ratiocorrected->GetXaxis()->SetTitle("p_{T} [GeV/c]");
+    ratiocorrected->Divide(correctedTH1D,alltogetherTH1D,1,1);
+    ratiocorrected->SetStats(0);
+    ratiocorrected->Draw();
+
+
+    // Dump to file if needed
+
+    if(fDumpToFile) {
+      
+      TFile *out = new TFile("finalSpectrum.root","recreate");
+      out->cd();
+      //
+      correctedspectrumD->SetName("UnfoldingCorrectedSpectrum");
+      correctedspectrumD->Write();
+      alltogetherspectrumD->SetName("AlltogetherSpectrum");
+      alltogetherspectrumD->Write();
+      ratiocorrected->SetName("RatioUnfoldingAlltogetherSpectrum");
+      ratiocorrected->Write();
+      //
+      correctedspectrum->SetName("UnfoldingCorrectedNotNormalizedSpectrum");
+      correctedspectrum->Write();
+      alltogetherCorrection->SetName("AlltogetherCorrectedNotNormalizedSpectrum");
+      alltogetherCorrection->Write();
+      //
+      out->Close(); delete out;
+    }
+  
+
+  }
+
+
+  
+
+  return kTRUE;
+}
+//____________________________________________________________
+AliCFDataGrid* AliHFEspectrum::SubtractBackground(Bool_t setBackground){
+  //
+  // Apply background subtraction
+  //
+  
+  // Raw spectrum
+  AliCFContainer *dataContainer = GetContainer(kDataContainer);
+  if(!dataContainer){
+    AliError("Data Container not available");
+    return NULL;
+  }
+  AliCFDataGrid *spectrumSubtracted = new AliCFDataGrid("spectrumSubtracted", "Data Grid for spectrum after Background subtraction", *dataContainer,fStepData);
+
+  AliCFDataGrid *dataspectrumbeforesubstraction = (AliCFDataGrid *) ((AliCFDataGrid *)GetSpectrum(GetContainer(kDataContainer),fStepData))->Clone();
+  dataspectrumbeforesubstraction->SetName("dataspectrumbeforesubstraction"); 
+  // Background Estimate
+  AliCFContainer *backgroundContainer = GetContainer(kBackgroundData);
+  if(!backgroundContainer){
+    AliError("MC background container not found");
+    return NULL;
+  }
+  Int_t stepbackground = 1;
+  if(!fInclusiveSpectrum) stepbackground = 2;
+  AliCFDataGrid *backgroundGrid = new AliCFDataGrid("ContaminationGrid","ContaminationGrid",*backgroundContainer,stepbackground);
+
+  // Subtract
+  spectrumSubtracted->Add(backgroundGrid,-1.0);
+  if(setBackground){
+    if(fBackground) delete fBackground;
+    fBackground = backgroundGrid;
+  } else delete backgroundGrid;
+
+
+  if(fDebugLevel > 0) {
     
     TCanvas * cbackgroundsubtraction = new TCanvas("backgroundsubtraction","backgroundsubtraction",1000,700);
-    if(fBackground) cbackgroundsubtraction->Divide(3,1);
+    cbackgroundsubtraction->Divide(3,1);
     cbackgroundsubtraction->cd(1);
-    measuredTH1Daftersubstraction = (TH1D*)dataspectrumaftersubstraction->Project(0);
-    measuredTH1Dbeforesubstraction = (TH1D*)dataspectrumbeforesubstraction->Project(0);
+    gPad->SetLogy();
+    TH1D *measuredTH1Daftersubstraction = spectrumSubtracted->Project(0);
+    TH1D *measuredTH1Dbeforesubstraction = dataspectrumbeforesubstraction->Project(0);
     CorrectFromTheWidth(measuredTH1Daftersubstraction);
     CorrectFromTheWidth(measuredTH1Dbeforesubstraction);
     measuredTH1Daftersubstraction->SetStats(0);
@@ -185,10 +420,11 @@ void AliHFEspectrum::Correct(AliCFContainer *datacontainer,AliCFContainer *mccon
     measuredTH1Daftersubstraction->Draw();
     measuredTH1Dbeforesubstraction->Draw("same");
     TLegend *legsubstraction = new TLegend(0.4,0.6,0.89,0.89);
-    legsubstraction->AddEntry(measuredTH1Dbeforesubstraction,"before substraction","p");
-    legsubstraction->AddEntry(measuredTH1Daftersubstraction,"after substraction","p");
+    legsubstraction->AddEntry(measuredTH1Dbeforesubstraction,"With hadron contamination","p");
+    legsubstraction->AddEntry(measuredTH1Daftersubstraction,"Without hadron contamination ","p");
     legsubstraction->Draw("same");
     cbackgroundsubtraction->cd(2);
+    gPad->SetLogy();
     TH1D* ratiomeasuredcontamination = (TH1D*)measuredTH1Dbeforesubstraction->Clone();
     ratiomeasuredcontamination->SetName("ratiomeasuredcontamination");
     ratiomeasuredcontamination->SetTitle("");
@@ -201,270 +437,109 @@ void AliHFEspectrum::Correct(AliCFContainer *datacontainer,AliCFContainer *mccon
     ratiomeasuredcontamination->SetMarkerColor(kBlack);
     ratiomeasuredcontamination->SetLineColor(kBlack);
     ratiomeasuredcontamination->Draw();
-    if(fBackground) {
-      cbackgroundsubtraction->cd(3);
-      measuredTH1background = (TH1D*)fBackground->Project(0);
-      CorrectFromTheWidth(measuredTH1background);
-      measuredTH1background->SetStats(0);
-      measuredTH1background->SetTitle("");
-      measuredTH1background->GetYaxis()->SetTitle("dN/dp_{T} [(GeV/c)^{-1}]");
-      measuredTH1background->GetXaxis()->SetTitle("p_{T} [GeV/c]");
-      measuredTH1background->SetMarkerStyle(26);
-      measuredTH1background->SetMarkerColor(kBlack);
-      measuredTH1background->SetLineColor(kBlack);
-      measuredTH1background->Draw();
-    }
-    
-    contaminationspectrum = (AliCFDataGrid *) ((AliCFDataGrid *)GetSpectrum(contaminationcontainer,1))->Clone();
-    contaminationspectrum->SetName("contaminationspectrum");
-    TCanvas * ccontaminationspectrum = new TCanvas("contaminationspectrum","contaminationspectrum",1000,700);
-    ccontaminationspectrum->Divide(3,1);
-    ccontaminationspectrum->cd(1);
-    TH2D * contaminationspectrum2dpteta = (TH2D*)contaminationspectrum->Project(1,0);
-    TH2D * contaminationspectrum2dptphi = (TH2D*)contaminationspectrum->Project(2,0);
-    TH2D * contaminationspectrum2detaphi = (TH2D*)contaminationspectrum->Project(1,2);
-    contaminationspectrum2dpteta->SetStats(0);
-    contaminationspectrum2dpteta->SetTitle("");
-    contaminationspectrum2dpteta->GetXaxis()->SetTitle("#eta");
-    contaminationspectrum2dpteta->GetYaxis()->SetTitle("p_{T} [GeV/c]");
-    contaminationspectrum2dptphi->SetStats(0);
-    contaminationspectrum2dptphi->SetTitle("");
-    contaminationspectrum2dptphi->GetXaxis()->SetTitle("#phi [rad]");
-    contaminationspectrum2dptphi->GetYaxis()->SetTitle("p_{T} [GeV/c]");
-    contaminationspectrum2detaphi->SetStats(0);
-    contaminationspectrum2detaphi->SetTitle("");
-    contaminationspectrum2detaphi->GetXaxis()->SetTitle("#eta");
-    contaminationspectrum2detaphi->GetYaxis()->SetTitle("#phi [rad]");
-    contaminationspectrum2dptphi->Draw("colz");
-    ccontaminationspectrum->cd(2);
-    contaminationspectrum2dpteta->Draw("colz");
-    ccontaminationspectrum->cd(3);
-    contaminationspectrum2detaphi->Draw("colz");
-
+    cbackgroundsubtraction->cd(3);
+    TH1D *measuredTH1background = backgroundGrid->Project(0);
+    CorrectFromTheWidth(measuredTH1background);
+    measuredTH1background->SetStats(0);
+    measuredTH1background->SetTitle("");
+    measuredTH1background->GetYaxis()->SetTitle("dN/dp_{T} [(GeV/c)^{-1}]");
+    measuredTH1background->GetXaxis()->SetTitle("p_{T} [GeV/c]");
+    measuredTH1background->SetMarkerStyle(26);
+    measuredTH1background->SetMarkerColor(kBlack);
+    measuredTH1background->SetLineColor(kBlack);
+    measuredTH1background->Draw();
+       
   }
   
-  
-  TCanvas * cresidual = new TCanvas("residual","residual",1000,700);
-  cresidual->Divide(2,1);
-  cresidual->cd(1);
-  gPad->SetLogy();
-  TGraphErrors* residualspectrumD = Normalize(residualspectrum);
-  if(!residualspectrumD) {
-    AliError("Number of Events not set for the normalization");
-    return;
-  }
-  residualspectrumD->SetTitle("");
-  residualspectrumD->GetYaxis()->SetTitleOffset(1.5);
-  residualspectrumD->GetYaxis()->SetRangeUser(0.000000001,1.0);
-  residualspectrumD->SetMarkerStyle(26);
-  residualspectrumD->SetMarkerColor(kBlue);
-  residualspectrumD->SetLineColor(kBlue);
-  residualspectrumD->Draw("AP");
-  TGraphErrors* measuredspectrumD = Normalize(dataspectrum);
-  measuredspectrumD->SetTitle("");  
-  measuredspectrumD->GetYaxis()->SetTitleOffset(1.5);
-  measuredspectrumD->GetYaxis()->SetRangeUser(0.000000001,1.0);
-  measuredspectrumD->SetMarkerStyle(25);
-  measuredspectrumD->SetMarkerColor(kBlack);
-  measuredspectrumD->SetLineColor(kBlack);
-  measuredspectrumD->Draw("P");
-  TLegend *legres = new TLegend(0.4,0.6,0.89,0.89);
-  legres->AddEntry(residualspectrumD,"Residual","p");
-  legres->AddEntry(measuredspectrumD,"Measured","p");
-  legres->Draw("same");
-  cresidual->cd(2);
-  TH1D *residualTH1D = residualspectrum->Projection(0);
-  TH1D *measuredTH1D = (TH1D*)dataspectrum->Project(0);
-  TH1D* ratioresidual = (TH1D*)residualTH1D->Clone();
-  ratioresidual->SetName("ratioresidual");
-  ratioresidual->SetTitle("");
-  ratioresidual->GetYaxis()->SetTitle("Folded/Measured");
-  ratioresidual->GetXaxis()->SetTitle("p_{T} [GeV/c]");
-  ratioresidual->Divide(residualTH1D,measuredTH1D,1,1);
-  ratioresidual->SetStats(0);
-  ratioresidual->Draw();
-
-  //
 
-  
-  TCanvas * ccorrected = new TCanvas("corrected","corrected",1000,700);
-  ccorrected->Divide(2,1);
-  ccorrected->cd(1);
-  gPad->SetLogy();
-  TGraphErrors* correctedspectrumD = Normalize(correctedspectrum);
-  correctedspectrumD->SetTitle("");
-  correctedspectrumD->GetYaxis()->SetTitleOffset(1.5);
-  correctedspectrumD->GetYaxis()->SetRangeUser(0.000000001,1.0);
-  correctedspectrumD->SetMarkerStyle(26);
-  correctedspectrumD->SetMarkerColor(kBlue);
-  correctedspectrumD->SetLineColor(kBlue);
-  correctedspectrumD->Draw("AP");
-  TGraphErrors* alltogetherspectrumD = Normalize(alltogetherCorrection);
-  alltogetherspectrumD->SetTitle("");
-  alltogetherspectrumD->GetYaxis()->SetTitleOffset(1.5);
-  alltogetherspectrumD->GetYaxis()->SetRangeUser(0.000000001,1.0);
-  alltogetherspectrumD->SetMarkerStyle(25);
-  alltogetherspectrumD->SetMarkerColor(kBlack);
-  alltogetherspectrumD->SetLineColor(kBlack);
-  alltogetherspectrumD->Draw("P");
-  TLegend *legcorrected = new TLegend(0.4,0.6,0.89,0.89);
-  legcorrected->AddEntry(correctedspectrumD,"Corrected","p");
-  legcorrected->AddEntry(alltogetherspectrumD,"Alltogether","p");
-  legcorrected->Draw("same");
-  ccorrected->cd(2);
-  TH1D *correctedTH1D = correctedspectrum->Projection(0);
-  TH1D *alltogetherTH1D = (TH1D*)alltogetherCorrection->Project(0);
-  TH1D* ratiocorrected = (TH1D*)correctedTH1D->Clone();
-  ratiocorrected->SetName("ratiocorrected");
-  ratiocorrected->SetTitle("");
-  ratiocorrected->GetYaxis()->SetTitle("Unfolded/DirectCorrected");
-  ratiocorrected->GetXaxis()->SetTitle("p_{T} [GeV/c]");
-  ratiocorrected->Divide(correctedTH1D,alltogetherTH1D,1,1);
-  ratiocorrected->SetStats(0);
-  ratiocorrected->Draw();
-  
-  // Efficiency correction
-
-  AliCFEffGrid  *efficiencymcPID = (AliCFEffGrid*)  GetEfficiency(mccontainer,8,7);
-  AliCFEffGrid  *efficiencymctrackinggeo = (AliCFEffGrid*)  GetEfficiency(mccontainer,7,0);
-  AliCFEffGrid  *efficiencymcall = (AliCFEffGrid*)  GetEfficiency(mccontainer,8,0);
-  
-  AliCFEffGrid  *efficiencyesdall = (AliCFEffGrid*)  GetEfficiency(mccontainer,20,0);
-  
-  TCanvas * cefficiency = new TCanvas("efficiency","efficiency",1000,700);
-  cefficiency->cd(1);
-  TH1D* efficiencymcPIDD = (TH1D*)efficiencymcPID->Project(0);
-  efficiencymcPIDD->SetTitle("");
-  efficiencymcPIDD->SetStats(0);
-  efficiencymcPIDD->SetMarkerStyle(25);
-  efficiencymcPIDD->Draw();
-  TH1D* efficiencymctrackinggeoD = (TH1D*)efficiencymctrackinggeo->Project(0);
-  efficiencymctrackinggeoD->SetTitle("");
-  efficiencymctrackinggeoD->SetStats(0);
-  efficiencymctrackinggeoD->SetMarkerStyle(26);
-  efficiencymctrackinggeoD->Draw("same");
-  TH1D* efficiencymcallD = (TH1D*)efficiencymcall->Project(0);
-  efficiencymcallD->SetTitle("");
-  efficiencymcallD->SetStats(0);
-  efficiencymcallD->SetMarkerStyle(27);
-  efficiencymcallD->Draw("same");
-  TH1D* efficiencyesdallD = (TH1D*)efficiencyesdall->Project(0);
-  efficiencyesdallD->SetTitle("");
-  efficiencyesdallD->SetStats(0);
-  efficiencyesdallD->SetMarkerStyle(24);
-  efficiencyesdallD->Draw("same");
-  TLegend *legeff = new TLegend(0.4,0.6,0.89,0.89);
-  legeff->AddEntry(efficiencymcPIDD,"PID efficiency","p");
-  legeff->AddEntry(efficiencymctrackinggeoD,"Tracking geometry efficiency","p");
-  legeff->AddEntry(efficiencymcallD,"Overall efficiency","p");
-  legeff->AddEntry(efficiencyesdallD,"Overall efficiency ESD","p");
-  legeff->Draw("same");
-
-  // Dump to file if needed
-
-  if(fDumpToFile) {
-    
-    TFile *out = new TFile("finalSpectrum.root","recreate");
-    out->cd();
-    //
-    residualspectrumD->SetName("UnfoldingResidualSpectrum");
-    residualspectrumD->Write();
-    measuredspectrumD->SetName("MeasuredSpectrum");
-    measuredspectrumD->Write();
-    ratioresidual->SetName("RatioResidualSpectrum");
-    ratioresidual->Write();
-    //
-    correctedspectrumD->SetName("UnfoldingCorrectedSpectrum");
-    correctedspectrumD->Write();
-    alltogetherspectrumD->SetName("AlltogetherSpectrum");
-    alltogetherspectrumD->Write();
-    ratiocorrected->SetName("RatioUnfoldingAlltogetherSpectrum");
-    ratiocorrected->Write();
-    //
-    correctedspectrum->SetName("UnfoldingCorrectedNotNormalizedSpectrum");
-    correctedspectrum->Write();
-    alltogetherCorrection->SetName("AlltogetherCorrectedNotNormalizedSpectrum");
-    alltogetherCorrection->Write();
-    //
-    if(measuredTH1Daftersubstraction && measuredTH1Dbeforesubstraction) {
-      measuredTH1Daftersubstraction->SetName("Rawptspectrummeasuredaftersubtraction");
-      measuredTH1Daftersubstraction->Write();
-      measuredTH1Dbeforesubstraction->SetName("Rawptspectrummeasuredbeforesubtraction");
-      measuredTH1Dbeforesubstraction->Write();
-    }
-    if(measuredTH1background) {
-      measuredTH1background->SetName("Rawptspectrummeasuredbackground");
-      measuredTH1background->Write();
-    }
-    //
-    out->Close(); delete out;
-
-    
-  }
+  return spectrumSubtracted;
 }
 //____________________________________________________________
-AliCFDataGrid* AliHFEspectrum::SubtractBackground(Int_t dimensions, Bool_t setBackground){
+AliCFDataGrid *AliHFEspectrum::CorrectV0Efficiency(AliCFDataGrid* const bgsubpectrum){
+  
   //
-  // Apply background subtraction
+  // Apply TPC pid efficiency correction from V0
   //
 
-  AliCFContainer *dataContainer = GetContainer(kDataContainer);
-  if(!dataContainer){
-    AliError("Data Container not available");
+  AliCFContainer *v0Container = GetContainer(kDataContainerV0);
+  if(!v0Container){
+    AliError("V0 Container not available");
     return NULL;
   }
-  // Get the data grid in the requested format
-  Bool_t initContainer = kFALSE;
-  Int_t dims[3];
-  switch(dimensions){
-    case 1:   dims[0] = 0;
-              initContainer = kTRUE;
-              break;
-    case 3:   for(Int_t i = 0; i < 3; i++) dims[i] = i;
-              initContainer = kTRUE;
-              break;
-    default:
-              AliError("Container with this number of dimensions not foreseen (yet)");
-  };
-  if(!initContainer){
-    AliError("Creation of the sliced containers failed. Background estimation not possible");
-    return NULL;
-  }
-  AliCFContainer *spectrumSliced = GetSlicedContainer(dataContainer, dimensions, dims);
-
-  // Make Background Estimate
-  AliCFDataGrid *backgroundGrid = NULL;
-  if(fBackgroundSource == kDataBackground)
-    backgroundGrid = TakeBackgroundFromData(dimensions);
-  else
-    backgroundGrid = MakeBackgroundEstimateFromMC(dimensions);
-  if(!backgroundGrid){
-    AliError("Background Estimate not created");
-    ClearObject(spectrumSliced);
-    return NULL;
+
+  // Efficiency
+  AliCFEffGrid* efficiencyD = new AliCFEffGrid("efficiency","",*v0Container);
+  efficiencyD->CalculateEfficiency(fStepAfterCutsV0,fStepBeforeCutsV0);
+
+  // Data in the right format
+  AliCFDataGrid *dataGrid = 0x0;  
+  if(bgsubpectrum) {
+    dataGrid = bgsubpectrum;
   }
+  else {
+    
+    AliCFContainer *dataContainer = GetContainer(kDataContainer);
+    if(!dataContainer){
+      AliError("Data Container not available");
+      return NULL;
+    }
 
+    dataGrid = new AliCFDataGrid("dataGrid","dataGrid",*dataContainer, fStepData);
+  } 
 
-  AliCFDataGrid *spectrumSubtracted = new AliCFDataGrid("spectrumSubtracted", "Data Grid for spectrum after Background subtraction", *spectrumSliced,fStepData);
-  //spectrumSubtracted->ApplyBGCorrection(*backgroundGrid);
-  spectrumSubtracted->Add(backgroundGrid,-1.0);
-  if(setBackground){
-    if(fBackground) delete fBackground;
-    fBackground = backgroundGrid;
-  } else delete backgroundGrid;
+  // Correct
+  AliCFDataGrid *result = (AliCFDataGrid *) dataGrid->Clone();
+  result->ApplyEffCorrection(*efficiencyD);
 
-  return spectrumSubtracted;
-}
+  if(fDebugLevel > 0) {
+    
+    TCanvas * cV0Efficiency = new TCanvas("V0Efficiency","V0Efficiency",1000,700);
+    cV0Efficiency->Divide(2,1);
+    cV0Efficiency->cd(1);
+    TH1D *afterE = result->Project(0);
+    TH1D *beforeE = dataGrid->Project(0);
+    afterE->SetStats(0);
+    afterE->SetTitle("");
+    afterE->GetYaxis()->SetTitle("dN/dp_{T} [(GeV/c)^{-1}]");
+    afterE->GetXaxis()->SetTitle("p_{T} [GeV/c]");
+    afterE->SetMarkerStyle(25);
+    afterE->SetMarkerColor(kBlack);
+    afterE->SetLineColor(kBlack);
+    beforeE->SetStats(0);
+    beforeE->SetTitle("");
+    beforeE->GetYaxis()->SetTitle("dN/dp_{T} [(GeV/c)^{-1}]");
+    beforeE->GetXaxis()->SetTitle("p_{T} [GeV/c]");
+    beforeE->SetMarkerStyle(24);
+    beforeE->SetMarkerColor(kBlue);
+    beforeE->SetLineColor(kBlue);
+    afterE->Draw();
+    beforeE->Draw("same");
+    TLegend *legV0efficiency = new TLegend(0.4,0.6,0.89,0.89);
+    legV0efficiency->AddEntry(beforeE,"Before Efficiency correction","p");
+    legV0efficiency->AddEntry(afterE,"After Efficiency correction","p");
+    legV0efficiency->Draw("same");
+    cV0Efficiency->cd(2);
+    TH1D* efficiencyDproj = efficiencyD->Project(0);
+    efficiencyDproj->SetTitle("");
+    efficiencyDproj->SetStats(0);
+    efficiencyDproj->SetMarkerStyle(25);
+    efficiencyDproj->Draw();
 
+
+  }
+
+  
+  return result;
+
+}
 //____________________________________________________________
-TList *AliHFEspectrum::Unfold(Int_t dimensions,AliCFDataGrid* const bgsubpectrum){
+TList *AliHFEspectrum::Unfold(AliCFDataGrid* const bgsubpectrum){
   
   //
   // Unfold and eventually correct for efficiency the bgsubspectrum
   //
 
-  AliCFContainer *mcContainer = GetContainer(kMCContainer);
+  AliCFContainer *mcContainer = GetContainer(kMCContainerMC);
   if(!mcContainer){
     AliError("MC Container not available");
     return NULL;
@@ -475,35 +550,10 @@ TList *AliHFEspectrum::Unfold(Int_t dimensions,AliCFDataGrid* const bgsubpectrum
     return NULL;
   }
 
-  // Get the mc grid in the requested format
-  Bool_t initContainer = kFALSE;
-  Int_t dims[3];
-  switch(dimensions){
-    case 1:   dims[0] = 0;
-              initContainer = kTRUE;
-              break;
-    case 3:   for(Int_t i = 0; i < 3; i++) dims[i] = i;
-              initContainer = kTRUE;
-              break;
-    default:
-              AliError("Container with this number of dimensions not foreseen (yet)");
-  };
-  if(!initContainer){
-    AliError("Creation of the sliced containers failed. Background estimation not possible");
-    return NULL;
-  }
-  AliCFContainer *mcContainerD = GetSlicedContainer(mcContainer, dimensions, dims);
-  THnSparse *correlationD = GetSlicedCorrelation(dimensions, dims);
-
-  // Data in the right format
+  // Data 
   AliCFDataGrid *dataGrid = 0x0;  
   if(bgsubpectrum) {
-    if(bgsubpectrum->GetNVar()!= dimensions) {
-      AliError("Not the expected number of dimensions for the AliCFDataGrid\n");
-      return NULL;
-    }
     dataGrid = bgsubpectrum;
-    
   }
   else {
 
@@ -513,23 +563,20 @@ TList *AliHFEspectrum::Unfold(Int_t dimensions,AliCFDataGrid* const bgsubpectrum
       return NULL;
     }
 
-    AliCFContainer *dataContainerD = GetSlicedContainer(dataContainer, dimensions, dims);
-    dataGrid = new AliCFDataGrid("dataGrid","dataGrid",*dataContainerD, fStepData);
-    
+    dataGrid = new AliCFDataGrid("dataGrid","dataGrid",*dataContainer, fStepData);
   } 
   
-  
   // Guessed
-  AliCFDataGrid* guessedGrid = new AliCFDataGrid("guessed","",*mcContainerD, fStepGuessedUnfolding);
+  AliCFDataGrid* guessedGrid = new AliCFDataGrid("guessed","",*mcContainer, fStepGuessedUnfolding);
   THnSparse* guessedTHnSparse = ((AliCFGridSparse*)guessedGrid->GetData())->GetGrid();
 
   // Efficiency
-  AliCFEffGrid* efficiencyD = new AliCFEffGrid("efficiency","",*mcContainerD);
+  AliCFEffGrid* efficiencyD = new AliCFEffGrid("efficiency","",*mcContainer);
   efficiencyD->CalculateEfficiency(fStepMC,fStepTrue);
 
   // Unfold 
   
-  AliCFUnfolding unfolding("unfolding","",dimensions,correlationD,efficiencyD->GetGrid(),dataGrid->GetGrid(),guessedTHnSparse);
+  AliCFUnfolding unfolding("unfolding","",fNbDimensions,fCorrelation,efficiencyD->GetGrid(),dataGrid->GetGrid(),guessedTHnSparse);
   unfolding.SetMaxNumberOfIterations(fNumberOfIterations);
   unfolding.UseSmoothing();
   unfolding.Unfold();
@@ -542,77 +589,135 @@ TList *AliHFEspectrum::Unfold(Int_t dimensions,AliCFDataGrid* const bgsubpectrum
   listofresults->AddAt((THnSparse*)result->Clone(),0);
   listofresults->AddAt((THnSparse*)residual->Clone(),1);
 
+  if(fDebugLevel > 0) {
+    
+    TCanvas * cresidual = new TCanvas("residual","residual",1000,700);
+    cresidual->Divide(2,1);
+    cresidual->cd(1);
+    gPad->SetLogy();
+    TGraphErrors* residualspectrumD = Normalize(residual);
+    if(!residualspectrumD) {
+      AliError("Number of Events not set for the normalization");
+      return kFALSE;
+    }
+    residualspectrumD->SetTitle("");
+    residualspectrumD->GetYaxis()->SetTitleOffset(1.5);
+    residualspectrumD->GetYaxis()->SetRangeUser(0.000000001,1.0);
+    residualspectrumD->SetMarkerStyle(26);
+    residualspectrumD->SetMarkerColor(kBlue);
+    residualspectrumD->SetLineColor(kBlue);
+    residualspectrumD->Draw("AP");
+    AliCFDataGrid *dataGridBis = (AliCFDataGrid *) (dataGrid->Clone());
+    dataGridBis->SetName("dataGridBis"); 
+    TGraphErrors* measuredspectrumD = Normalize(dataGridBis);
+    measuredspectrumD->SetTitle("");  
+    measuredspectrumD->GetYaxis()->SetTitleOffset(1.5);
+    measuredspectrumD->GetYaxis()->SetRangeUser(0.000000001,1.0);
+    measuredspectrumD->SetMarkerStyle(25);
+    measuredspectrumD->SetMarkerColor(kBlack);
+    measuredspectrumD->SetLineColor(kBlack);
+    measuredspectrumD->Draw("P");
+    TLegend *legres = new TLegend(0.4,0.6,0.89,0.89);
+    legres->AddEntry(residualspectrumD,"Residual","p");
+    legres->AddEntry(measuredspectrumD,"Measured","p");
+    legres->Draw("same");
+    cresidual->cd(2);
+    TH1D *residualTH1D = residual->Projection(0);
+    TH1D *measuredTH1D = dataGridBis->Project(0);
+    TH1D* ratioresidual = (TH1D*)residualTH1D->Clone();
+    ratioresidual->SetName("ratioresidual");
+    ratioresidual->SetTitle("");
+    ratioresidual->GetYaxis()->SetTitle("Folded/Measured");
+    ratioresidual->GetXaxis()->SetTitle("p_{T} [GeV/c]");
+    ratioresidual->Divide(residualTH1D,measuredTH1D,1,1);
+    ratioresidual->SetStats(0);
+    ratioresidual->Draw();
+    
+  }
+
   return listofresults;
 
 }
 
 //____________________________________________________________
-AliCFDataGrid *AliHFEspectrum::CorrectForEfficiency(Int_t dimensions,AliCFDataGrid* const bgsubpectrum){
+AliCFDataGrid *AliHFEspectrum::CorrectForEfficiency(AliCFDataGrid* const bgsubpectrum){
   
   //
   // Apply unfolding and efficiency correction together to bgsubspectrum
   //
 
-  AliCFContainer *mcContainer = GetContainer(kMCContainer);
+  AliCFContainer *mcContainer = GetContainer(kMCContainerESD);
   if(!mcContainer){
     AliError("MC Container not available");
     return NULL;
   }
 
-  // Get the data grid in the requested format
-  Bool_t initContainer = kFALSE;
-  Int_t dims[3];
-  switch(dimensions){
-    case 1:   dims[0] = 0;
-              initContainer = kTRUE;
-              break;
-    case 3:   for(Int_t i = 0; i < 3; i++) dims[i] = i;
-              initContainer = kTRUE;
-              break;
-    default:
-              AliError("Container with this number of dimensions not foreseen (yet)");
-  };
-  if(!initContainer){
-    AliError("Creation of the sliced containers failed. Background estimation not possible");
-    return NULL;
-  }
-  AliCFContainer *mcContainerD = GetSlicedContainer(mcContainer, dimensions, dims);
-
   // Efficiency
-  AliCFEffGrid* efficiencyD = new AliCFEffGrid("efficiency","",*mcContainerD);
+  AliCFEffGrid* efficiencyD = new AliCFEffGrid("efficiency","",*mcContainer);
   efficiencyD->CalculateEfficiency(fStepMC,fStepTrue);
 
   // Data in the right format
   AliCFDataGrid *dataGrid = 0x0;  
   if(bgsubpectrum) {
-    if(bgsubpectrum->GetNVar()!= dimensions) {
-      AliError("Not the expected number of dimensions for the AliCFDataGrid\n");
-      return NULL;
-    }
     dataGrid = bgsubpectrum;
-    
   }
   else {
-
+    
     AliCFContainer *dataContainer = GetContainer(kDataContainer);
     if(!dataContainer){
       AliError("Data Container not available");
       return NULL;
     }
 
-    AliCFContainer *dataContainerD = GetSlicedContainer(dataContainer, dimensions, dims);
-    dataGrid = new AliCFDataGrid("dataGrid","dataGrid",*dataContainerD, fStepData);
-    
+    dataGrid = new AliCFDataGrid("dataGrid","dataGrid",*dataContainer, fStepData);
   } 
 
   // Correct
   AliCFDataGrid *result = (AliCFDataGrid *) dataGrid->Clone();
   result->ApplyEffCorrection(*efficiencyD);
-  
 
+  if(fDebugLevel > 0) {
+    
+    AliCFEffGrid  *efficiencymcPID = (AliCFEffGrid*)  GetEfficiency(GetContainer(kMCContainerMC),fStepMC,AliHFEcuts::kStepHFEcutsTRD + AliHFEcuts::kNcutStepsMCTrack);
+    AliCFEffGrid  *efficiencymctrackinggeo = (AliCFEffGrid*)  GetEfficiency(GetContainer(kMCContainerMC),AliHFEcuts::kStepHFEcutsTRD + AliHFEcuts::kNcutStepsMCTrack,fStepTrue);
+    AliCFEffGrid  *efficiencymcall = (AliCFEffGrid*)  GetEfficiency(GetContainer(kMCContainerMC),fStepMC,fStepTrue);
+    
+    AliCFEffGrid  *efficiencyesdall = (AliCFEffGrid*)  GetEfficiency(GetContainer(kMCContainerESD),fStepMC,fStepTrue);
+    
+    TCanvas * cefficiency = new TCanvas("efficiency","efficiency",1000,700);
+    cefficiency->cd(1);
+    TH1D* efficiencymcPIDD = efficiencymcPID->Project(0);
+    efficiencymcPIDD->SetTitle("");
+    efficiencymcPIDD->SetStats(0);
+    efficiencymcPIDD->SetMarkerStyle(25);
+    efficiencymcPIDD->Draw();
+    TH1D* efficiencymctrackinggeoD = efficiencymctrackinggeo->Project(0);
+    efficiencymctrackinggeoD->SetTitle("");
+    efficiencymctrackinggeoD->SetStats(0);
+    efficiencymctrackinggeoD->SetMarkerStyle(26);
+    efficiencymctrackinggeoD->Draw("same");
+    TH1D* efficiencymcallD = efficiencymcall->Project(0);
+    efficiencymcallD->SetTitle("");
+    efficiencymcallD->SetStats(0);
+    efficiencymcallD->SetMarkerStyle(27);
+    efficiencymcallD->Draw("same");
+    TH1D* efficiencyesdallD = efficiencyesdall->Project(0);
+    efficiencyesdallD->SetTitle("");
+    efficiencyesdallD->SetStats(0);
+    efficiencyesdallD->SetMarkerStyle(24);
+    efficiencyesdallD->Draw("same");
+    TLegend *legeff = new TLegend(0.4,0.6,0.89,0.89);
+    legeff->AddEntry(efficiencymcPIDD,"PID efficiency","p");
+    legeff->AddEntry(efficiencymctrackinggeoD,"Tracking geometry efficiency","p");
+    legeff->AddEntry(efficiencymcallD,"Overall efficiency","p");
+    legeff->AddEntry(efficiencyesdallD,"Overall efficiency ESD","p");
+    legeff->Draw("same");
+  }
+  
   return result;
 
 }
+
 //__________________________________________________________________________________
 TGraphErrors *AliHFEspectrum::Normalize(THnSparse * const spectrum) const {
   //
@@ -641,7 +746,7 @@ TGraphErrors *AliHFEspectrum::Normalize(AliCFDataGrid * const spectrum) const {
   //
   if(fNEvents > 0) {
 
-    TH1D* projection = (TH1D*)spectrum->Project(0);
+    TH1D* projection = spectrum->Project(0);
     CorrectFromTheWidth(projection);
     TGraphErrors *graphError = NormalizeTH1(projection);
     return graphError;
@@ -712,93 +817,10 @@ AliCFContainer *AliHFEspectrum::GetContainer(AliHFEspectrum::CFContainer_t type)
   if(!fCFContainers) return NULL;
   return dynamic_cast<AliCFContainer *>(fCFContainers->At(type));
 }
-
 //____________________________________________________________
-AliCFDataGrid *AliHFEspectrum::TakeBackgroundFromData(Int_t nDim) {
-  // 
-  // Take Background Estimate from Data
+AliCFContainer *AliHFEspectrum::GetSlicedContainer(AliCFContainer *container, Int_t nDim, Int_t *dimensions,Int_t source) {
   //
-  AliCFContainer *backgroundContainer = GetContainer(kBackgroundData);
-  if(!backgroundContainer){
-    AliError("MC background container not found");
-    return NULL;
-  }
-  AliInfo(Form("Making background Estimate from Data in %d Dimensions", nDim));
-
-  Bool_t initContainer = kFALSE;
-  Int_t dimensions[3];
-  switch(nDim){
-    case 1:   dimensions[0] = 0;
-              initContainer = kTRUE;
-              break;
-    case 3:   for(Int_t i = 0; i < 3; i++) dimensions[i] = i;
-              initContainer = kTRUE;
-              break;
-    default:
-              AliError("Container with this number of dimensions not foreseen (yet)");
-  };
-  if(!initContainer){
-    AliError("Creation of the sliced containers failed. Background estimation not possible");
-    return NULL;
-  }
-  AliCFContainer *slicedBackground = GetSlicedContainer(backgroundContainer, nDim, dimensions);
-  AliCFDataGrid *contaminationspectrum = new AliCFDataGrid("ContaminationGrid","ContaminationGrid",*slicedBackground,1);
-  
-  return contaminationspectrum;
-}
-
-//____________________________________________________________
-AliCFDataGrid *AliHFEspectrum::MakeBackgroundEstimateFromMC(Int_t nDim){
-  //
-  // Make Background Estimate using MC
-  // Calculate ratio of hadronic background from MC and 
-  // apply this on data
-  //
-  AliCFContainer *backgroundContainer = GetContainer(kBackgroundMC);
-  AliCFContainer *dataContainer = GetContainer(kDataContainer);
-  if(!backgroundContainer){
-    AliError("MC background container not found");
-    return NULL;
-  }
-  if(!dataContainer){
-    AliError("Data container not found");
-    return NULL;
-  }
-  AliInfo(Form("Making background Estimate from MC in %d Dimensions", nDim));
-
-  Bool_t initContainer = kFALSE;
-  Int_t dimensions[3];
-  switch(nDim){
-    case 1:   dimensions[0] = 1;
-              initContainer = kTRUE;
-              break;
-    case 3:   for(Int_t i = 0; i < 3; i++) dimensions[i] = i;
-              initContainer = kTRUE;
-              break;
-    default:
-              AliError("Container with this number of dimensions not foreseen (yet)");
-  };
-  if(!initContainer){
-    AliError("Creation of the sliced containers failed. Background estimation not possible");
-    return NULL;
-  }
-  AliCFContainer *slicedBackground = GetSlicedContainer(backgroundContainer, nDim, dimensions);
-  AliCFContainer *slicedData = GetSlicedContainer(dataContainer, nDim, dimensions);
-  
-  // Create Efficiency Grid and data grid
-  AliCFEffGrid backgroundRatio("backgroundRatio", "BackgroundRatio", *slicedBackground);
-  backgroundRatio.CalculateEfficiency(1, 0);
-  AliCFDataGrid *backgroundEstimate = new AliCFDataGrid("backgroundEstimate", "Grid for Background Estimate", *slicedData, fStepData);
-  backgroundEstimate->ApplyEffCorrection(backgroundRatio);
-
-  return backgroundEstimate;
-}
-
-//____________________________________________________________
-AliCFContainer *AliHFEspectrum::GetSlicedContainer(AliCFContainer *container, Int_t nDim, Int_t *dimensions) {
-  //
-  // Slice Pt bin
+  // Slice bin for a given source of electron
   //
   
   Double_t *varMin = new Double_t[container->GetNVar()],
@@ -809,8 +831,15 @@ AliCFContainer *AliHFEspectrum::GetSlicedContainer(AliCFContainer *container, In
     
     binLimits = new Double_t[container->GetNBins(ivar)+1];
     container->GetBinLimits(ivar,binLimits);
-    varMin[ivar] = binLimits[0];
-    varMax[ivar] = binLimits[container->GetNBins(ivar)];
+    if((ivar == 4) && ((source>= 0) && (source<container->GetNBins(ivar)))) {
+      varMin[ivar] = binLimits[source];
+      varMax[ivar] = binLimits[source];
+    }
+    else {
+      varMin[ivar] = binLimits[0];
+      varMax[ivar] = binLimits[container->GetNBins(ivar)];
+    }
+
     delete[] binLimits;
   }
   
@@ -823,12 +852,12 @@ AliCFContainer *AliHFEspectrum::GetSlicedContainer(AliCFContainer *container, In
 }
 
 //_________________________________________________________________________
-THnSparse *AliHFEspectrum::GetSlicedCorrelation(Int_t nDim, Int_t *dimensions) const {
+THnSparseF *AliHFEspectrum::GetSlicedCorrelation(THnSparseF *correlationmatrix, Int_t nDim, Int_t *dimensions) const {
   //
-  // Slice Pt correlation
+  // Slice correlation
   //
 
-  Int_t ndimensions = fCorrelation->GetNdimensions();
+  Int_t ndimensions = correlationmatrix->GetNdimensions();
   printf("Number of dimension %d correlation map\n",ndimensions);
   if(ndimensions < (2*nDim)) {
     AliError("Problem in the dimensions");
@@ -844,7 +873,7 @@ THnSparse *AliHFEspectrum::GetSlicedCorrelation(Int_t nDim, Int_t *dimensions) c
     printf("For iter %d: %d and iter+nDim %d: %d\n",iter,dimensions[iter],iter+nDim,ndimensionsContainer + dimensions[iter]);
   }
     
-  THnSparse *k = fCorrelation->Projection(nDim*2,dim);
+  THnSparseF *k = (THnSparseF *) correlationmatrix->Projection(nDim*2,dim);
 
   delete[] dim; 
   return k;
@@ -900,7 +929,7 @@ TObject* AliHFEspectrum::GetSpectrum(AliCFContainer * const c, Int_t step) {
   return data;
 }
 //_________________________________________________________________________
-TObject* AliHFEspectrum::GetEfficiency(AliCFContainer * const c, Int_t step, Int_t step0) {
+TObject* AliHFEspectrum::GetEfficiency(AliCFContainer * const c, Int_t step, Int_t step0){
   // 
   // Create efficiency grid and calculate efficiency
   // of step to step0
index 31c097420128fae714598817623e2b20d6effa04..c18d9b39c71deed73ba8c140bf1448d26cb37506 100644 (file)
@@ -30,52 +30,59 @@ class TObject;
 class TH1;
 class TList;
 class AliCFContainer;
+class AliHFEcontainer;
 class AliCFDataGrid;
 class AliCFEffGrid;
 
 class AliHFEspectrum : public TNamed{
   public:
     enum CFContainer_t{
-      kDataContainer = 0,
-      kMCContainer = 1,
-      kBackgroundData = 2,
-      kBackgroundMC = 3
-    };
-    enum BackgroundSource_t{
-      kMCbackground = 0,
-      kDataBackground = 1
+      kDataContainer  = 0,
+      kBackgroundData = 1,
+      kMCContainerMC = 2,
+      kMCContainerESD = 3,
+      kDataContainerV0 = 4
     };
+   
     AliHFEspectrum(const char* name);
     ~AliHFEspectrum();
+    
 
-    void Correct(AliCFContainer *datacontainer,AliCFContainer *mccontainer,THnSparseF *mccorrelation,AliCFContainer *contaminationcontainer=0x0);
-    AliCFDataGrid *SubtractBackground(Int_t dimensions, Bool_t setBackground = kFALSE);
-    AliCFDataGrid *TakeBackgroundFromData(Int_t nDim);    
-
-    TList *Unfold(Int_t dimensions, AliCFDataGrid* const bgsubpectrum = 0x0);
-    AliCFDataGrid *CorrectForEfficiency(Int_t dimensions, AliCFDataGrid* const bgsubpectrum = 0x0);
+    Bool_t Init(AliHFEcontainer *datahfecontainer,AliHFEcontainer *mchfecontainer,AliHFEcontainer *v0hfecontainer=0x0);
+    Bool_t Correct(Bool_t subtractcontamination=kTRUE);
+   
+    AliCFDataGrid *SubtractBackground(Bool_t setBackground = kFALSE);
+    
+    AliCFDataGrid *CorrectV0Efficiency(AliCFDataGrid* const bgsubpectrum = 0x0);
+   
+    TList *Unfold(AliCFDataGrid* const bgsubpectrum = 0x0);
+    AliCFDataGrid *CorrectForEfficiency(AliCFDataGrid* const bgsubpectrum = 0x0);
+   
     TGraphErrors *Normalize(THnSparse * const spectrum) const;
     TGraphErrors *Normalize(AliCFDataGrid * const spectrum) const;
+    
     void SetCorrelation(THnSparseF * const correlation) {fCorrelation = correlation; };
     void SetContainer(AliCFContainer *cont, AliHFEspectrum::CFContainer_t type);
+    
     void SetNumberOfEvents(Int_t nEvents) { fNEvents = nEvents; }
-    void SetBackgroundSource(BackgroundSource_t source) { fBackgroundSource = source; };
     void SetMCEffStep(Int_t step) { fStepMC = step; };
     void SetMCTruthStep(Int_t step) { fStepTrue = step; };
     void SetStepToCorrect(Int_t step) { fStepData = step; };
+    void SetStepBeforeCutsV0(Int_t step) { fStepBeforeCutsV0 = step; };
+    void SetStepAfterCutsV0(Int_t step) { fStepAfterCutsV0 = step; };
+
     void SetStepGuessedUnfolding(Int_t stepGuessedUnfolding) { fStepGuessedUnfolding = stepGuessedUnfolding; };
     void SetNumberOfIteration(Int_t numberOfIteration) { fNumberOfIterations = numberOfIteration; };
+    
     void SetDumpToFile(Bool_t dumpToFile) { fDumpToFile=dumpToFile; }; 
   
+    void SetDebugLevel(Int_t debugLevel) { fDebugLevel = debugLevel; };
 
   protected:
-    AliCFDataGrid *MakeBackgroundEstimateFromMC(Int_t nDimensions);
-    
+       
     AliCFContainer *GetContainer(AliHFEspectrum::CFContainer_t contt);
-    AliCFContainer *GetSlicedContainer(AliCFContainer *cont, Int_t ndim, Int_t *dimensions);
-    THnSparse *GetSlicedCorrelation(Int_t nDim, Int_t *dimensions) const;
+    AliCFContainer *GetSlicedContainer(AliCFContainer *cont, Int_t ndim, Int_t *dimensions,Int_t source=-1);
+    THnSparseF *GetSlicedCorrelation(THnSparseF *correlationmatrix,Int_t nDim, Int_t *dimensions) const;
     TObject* GetSpectrum(AliCFContainer * const c, Int_t step);
     TObject* GetEfficiency(AliCFContainer * const c, Int_t step, Int_t step0);
  
@@ -95,17 +102,20 @@ class AliHFEspectrum : public TNamed{
     THnSparseF *fCorrelation;     // Correlation Matrices
     AliCFDataGrid *fBackground;   // Background Grid
 
-    BackgroundSource_t fBackgroundSource;   // Source for the background estimate
-
+    Bool_t fInclusiveSpectrum;     // Inclusive Spectrum
     Bool_t fDumpToFile;           // Write Result in a file
 
+    Int_t fNbDimensions;          // Number of dimensions for the correction
     Int_t fNEvents;               // Number of Events
     Int_t fStepMC;                // MC step (for unfolding)
     Int_t fStepTrue;              // MC step of the final spectrum
     Int_t fStepData;              // Data Step (various applications)
+    Int_t fStepBeforeCutsV0;      // Before cuts V0
+    Int_t fStepAfterCutsV0;       // After cuts V0
     Int_t fStepGuessedUnfolding;  // Step for first guessed unfolding
     Int_t fNumberOfIterations;    // Number of iterations
 
+    Int_t fDebugLevel;            // Debug Level
 
     ClassDef(AliHFEspectrum, 1) 
 };
diff --git a/PWG3/hfe/AliHFEtaggedTrackAnalysis.cxx b/PWG3/hfe/AliHFEtaggedTrackAnalysis.cxx
new file mode 100644 (file)
index 0000000..86725e2
--- /dev/null
@@ -0,0 +1,235 @@
+/**************************************************************************
+* 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 AliHFEtaggedTrackAnalysis
+// Analyses tracks with an apriori PID information (i.e. using the daugther
+// tracks from well-identified decays of neutral charged particles). Tracks
+// are processed in the Process function, where given tracks are filtered 
+// via the track cuts and used for PID later. The plugin fills Correction
+// Framework containers and additional PID QA containers
+//
+// Author:
+//   Markus Fasel <M.Fasel@gsi.de>
+//
+#include "AliCFCutBase.h"
+#include "AliCFContainer.h"
+#include "AliCFManager.h"
+#include "AliLog.h"
+#include "AliPID.h"
+
+#include "AliHFEcontainer.h"
+#include "AliHFEcuts.h"
+#include "AliHFEpid.h"
+#include "AliHFEpidQAmanager.h"
+#include "AliHFEtaggedTrackAnalysis.h"
+#include "AliHFEvarManager.h"
+
+ClassImp(AliHFEtaggedTrackAnalysis)
+
+//____________________________________________________________
+AliHFEtaggedTrackAnalysis::AliHFEtaggedTrackAnalysis():
+    TObject()
+  , fVarManager(NULL)
+  , fContainer(NULL)
+  , fPID(NULL)
+  , fPIDqa(NULL)
+  , fCuts(NULL)
+  , fCFM(NULL)
+{
+  //
+  // Default constructor
+  //
+  fVarManager = new AliHFEvarManager("taggedTrackVarManager");
+  fVarManager->AddVariable("pt");
+  fVarManager->AddVariable("eta");
+  fVarManager->AddVariable("phi");
+  fVarManager->AddVariable("charge");
+  fVarManager->AddVariable("species");
+  fPIDqa = new AliHFEpidQAmanager;
+  fCFM = new AliCFManager;
+  SetBit(kIsOwner, kTRUE);
+}
+
+//____________________________________________________________
+AliHFEtaggedTrackAnalysis::AliHFEtaggedTrackAnalysis(const AliHFEtaggedTrackAnalysis &ref):
+    TObject(ref)
+  , fVarManager(ref.fVarManager)
+  , fContainer(NULL)
+  , fPID(ref.fPID)
+  , fPIDqa(ref.fPIDqa)
+  , fCuts(ref.fCuts)
+  , fCFM(ref.fCFM)
+{
+  //
+  // Copy constructor
+  //
+  if(ref.fContainer){
+    InitContainer();
+  }
+  SetBit(kIsOwner, kFALSE);
+}
+
+//____________________________________________________________
+AliHFEtaggedTrackAnalysis &AliHFEtaggedTrackAnalysis::operator=(const AliHFEtaggedTrackAnalysis &ref){
+  //
+  // Assignment operator
+  //
+  if(&ref != this){
+    fVarManager = ref.fVarManager;
+    fPID = ref.fPID;
+    fPIDqa = ref.fPIDqa;
+    fCuts = ref.fCuts;
+    fCFM = ref.fCFM;
+
+    if(ref.fContainer) InitContainer();
+   
+    SetBit(kIsOwner, kFALSE); 
+    SetBit(kIsOwnerCuts, kFALSE);
+  }
+  return *this;
+}
+
+//____________________________________________________________
+AliHFEtaggedTrackAnalysis::~AliHFEtaggedTrackAnalysis(){
+  //
+  // Destructor
+  //
+  if(TestBit(kIsOwner)){
+    if(fVarManager) delete fVarManager;
+    if(fPIDqa) delete fPIDqa;
+  }
+  if(TestBit(kIsOwnerCuts)) delete fCuts;
+  if(fContainer) delete fContainer;
+}
+
+//____________________________________________________________
+void AliHFEtaggedTrackAnalysis::InitContainer(){
+  //
+  // Initialize output container
+  //
+  if(fContainer) return;
+  Int_t nStepPID = 0;
+  if(!fPID){
+    AliError("No PID set - defining container without PID steps");
+  } else {
+    nStepPID = fPID->GetNumberOfPIDdetectors();
+  }
+  fContainer = new AliHFEcontainer("containerV0");
+  fVarManager->DefineVariables(fContainer);
+  fContainer->CreateContainer("taggedTrackContainerReco", "Container for Tagged Tracks", AliHFEcuts::kNcutStepsRecTrack + nStepPID);
+
+  // Set the step titles
+  for(Int_t istep = 0; istep < AliHFEcuts::kNcutStepsRecTrack; istep++)
+    fContainer->SetStepTitle("taggedTrackContainerReco", AliHFEcuts::RecoCutName(istep), istep);
+  for(Int_t ipid = 0; ipid < nStepPID; ipid++){
+    fContainer->SetStepTitle("taggedTrackContainerReco", fPID->SortedDetectorName(ipid), ipid + AliHFEcuts::kNcutStepsRecTrack);
+  }
+  fCFM->SetParticleContainer(fContainer->GetCFContainer("taggedTrackContainerReco"));
+}
+
+//____________________________________________________________
+void AliHFEtaggedTrackAnalysis::ProcessTrack(AliVParticle *track, Int_t abinitioPID){
+  //
+  // Filter tracks tagged by V0 PID class
+  //
+  fVarManager->NewTrack(track, NULL, 0., abinitioPID, kTRUE);
+  Int_t offset = AliHFEcuts::kStepRecKineITSTPC;
+  fVarManager->FillContainer(fCFM->GetParticleContainer(), 0); // Fill Container without filtering
+  
+  Bool_t survived = kTRUE;
+  for(Int_t icut = AliHFEcuts::kStepRecKineITSTPC; icut <= AliHFEcuts::kStepHFEcutsTRD; icut++){
+    AliDebug(2, Form("Checking cut %d for species %s", icut + AliHFEcuts::kNcutStepsMCTrack, AliPID::ParticleName(abinitioPID)));
+  /*
+    TObjArray *cutlist = fCFM->GetParticleCutsList(icut + AliHFEcuts::kNcutStepsMCTrack);
+    if(!cutlist){
+      AliDebug(2, Form("No cuts for step %d set", icut + AliHFEcuts::kNcutStepsMCTrack));
+    } else {
+      AliDebug(2, Form("Cut Collection %s", cutlist->GetName()));
+      TIter cutiter(cutlist);
+      AliCFCutBase *cut;
+      while((cut = dynamic_cast<AliCFCutBase *>(cutiter()))){
+        AliDebug(2, Form("Cut object %s, QA on? %s", cut->GetName(), cut->IsQAOn() ? "yes" : "no"));
+      }
+    }
+  */
+    //if(!fCFM->CheckParticleCuts(icut + AliHFEcuts::kNcutStepsMCTrack, (TObject *)track)){
+    if(!fCuts->CheckParticleCuts(icut + AliHFEcuts::kNcutStepsMCTrack, (TObject *)track)){
+      AliDebug(2, Form("Track didn' survive cut %d", icut + AliHFEcuts::kNcutStepsMCTrack));
+      survived = kFALSE;
+      break;
+    }
+    AliDebug(2, Form("Cut passed, filling container %d", icut - offset + 1));
+    fVarManager->FillContainer(fCFM->GetParticleContainer(), icut - offset + 1);
+  }
+  if(survived){
+    AliDebug(2, "Use track in the PID");
+    // Apply PID
+    AliHFEpidObject hfetrack;
+    hfetrack.SetAnalysisType(AliHFEpidObject::kESDanalysis);
+    hfetrack.SetRecTrack(track);
+    hfetrack.SetAbInitioPID(abinitioPID);
+    fPID->SetVarManager(fVarManager);
+    fPID->IsSelected(&hfetrack, fContainer, "taggedTrackContainer", fPIDqa);
+  }
+}
+
+//____________________________________________________________
+void AliHFEtaggedTrackAnalysis::SetCuts(AliHFEcuts *cuts){
+  //
+  // Set HFE cuts to be used to filter the tagged tracks
+  //
+  if(!cuts){
+    AliWarning("Nob cuts provided - Using standard cuts");
+    fCuts = new AliHFEcuts("cutsTagged", "HFE Cuts for the V0 tagged tracks");
+    fCuts->CreateStandardCuts();
+    fCuts->SetQAOn();
+    SetBit(kIsOwnerCuts);
+  }
+  AliDebug(1, "Setting single track cuts");
+  fCuts = cuts;
+  const Int_t kNcutSteps = AliHFEcuts::kNcutStepsMCTrack + AliHFEcuts::kNcutStepsRecTrack + AliHFEcuts::kNcutStepsDETrack;
+  printf("Setting Number of cut steps %d\n", kNcutSteps);
+  fCFM->SetNStepParticle(kNcutSteps);
+  for(Int_t istep = 0; istep < kNcutSteps; istep++)
+    fCFM->SetParticleCutsList(istep, NULL);
+
+  fCuts->Initialize(fCFM); 
+}
+
+//____________________________________________________________
+void AliHFEtaggedTrackAnalysis::SetPID(AliHFEpid *pid){
+  //
+  // Set the PID and initialize the the QA manager
+  //
+  fPID = pid;
+  fPIDqa->Initialize(fPID);
+}
+
+//____________________________________________________________
+TList *AliHFEtaggedTrackAnalysis::GetPIDQA() const {
+  //
+  // return PID QA 
+  //
+  return fPIDqa->MakeList("PIDqa_taggedTracks");
+}
+
+//____________________________________________________________
+TList *AliHFEtaggedTrackAnalysis::GetCutQA() const {
+  //
+  // return Cut QA
+  //
+  return fCuts->GetQAhistograms();
+}
+
diff --git a/PWG3/hfe/AliHFEtaggedTrackAnalysis.h b/PWG3/hfe/AliHFEtaggedTrackAnalysis.h
new file mode 100644 (file)
index 0000000..32eff8f
--- /dev/null
@@ -0,0 +1,65 @@
+/**************************************************************************
+* 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 AliHFEtaggedTrackAnalysis
+// Analyses tracks with an apriori PID information (i.e. using the daugther
+// tracks from well-identified decays of neutral charged particles).
+// More information can be found inside the implementation file.
+//
+#ifndef ALIHFETAGGEDTRACKANALYSIS_H
+#define ALIHFETAGGEDTRACKANALYSIS_H
+
+#ifndef ROOT_TObject
+#include <TObject.h>
+#endif
+
+class AliHFEcontainer;
+class AliHFEcuts;
+class AliHFEpid;
+class AliHFEpidQAmanager;
+class AliHFEvarManager;
+
+class AliHFEtaggedTrackAnalysis : public TObject{
+  public:
+    AliHFEtaggedTrackAnalysis();
+    AliHFEtaggedTrackAnalysis(const AliHFEtaggedTrackAnalysis &ref);
+    AliHFEtaggedTrackAnalysis &operator=(const AliHFEtaggedTrackAnalysis &ref);
+    ~AliHFEtaggedTrackAnalysis();
+    
+    void InitContainer();
+    void ProcessTrack(AliVParticle *track, Int_t abinitioPID);
+
+    AliHFEcontainer *GetContainer() const { return fContainer; }
+    AliHFEpidQAmanager *GetPIDqa() const { return fPIDqa; }
+    TList * GetPIDQA() const;
+    TList * GetCutQA() const;
+    void SetCuts(AliHFEcuts *cuts);
+    void SetPID(AliHFEpid *pid);
+
+  private:
+    enum{
+      kIsOwner = BIT(14),
+      kIsOwnerCuts = BIT(15)
+    };
+    AliHFEvarManager    *fVarManager;   // Variable Manager
+    AliHFEcontainer     *fContainer;    // Output container
+    AliHFEpid           *fPID;          // PID selection
+    AliHFEpidQAmanager  *fPIDqa;        // PID monitoring
+    AliHFEcuts          *fCuts;         // Single track cuts
+    AliCFManager        *fCFM;          // CF Manager used for the track filtering
+    
+  ClassDef(AliHFEtaggedTrackAnalysis, 0)
+};
+#endif
diff --git a/PWG3/hfe/AliHFEtofPIDqa.cxx b/PWG3/hfe/AliHFEtofPIDqa.cxx
new file mode 100644 (file)
index 0000000..5c46166
--- /dev/null
@@ -0,0 +1,251 @@
+/**************************************************************************
+* 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 AliHFEtofPIDqa
+//
+// Monitoring TOF PID in the HFE PID montioring framework. The following
+// quantities are monitored:
+//   TOF time distance to electron hypothesis (Number of sigmas)
+//   TOF time distance to the pion hypothesis (Absolute value)
+//   TPC dE/dx (Number of sigmas, as control histogram)
+// (Always as function of momentum, particle species and centrality 
+// before and after cut)
+// More information about the PID monitoring framework can be found in
+// AliHFEpidQAmanager.cxx and AliHFEdetPIDqa.cxx
+//
+// Author:
+//
+//   Markus Fasel <M.Fasel@gsi.de>
+#include <TClass.h>
+#include <TH2.h>
+#include <THnSparse.h>
+#include <TString.h>
+
+#include "AliAODTrack.h"
+#include "AliESDtrack.h"
+#include "AliESDpid.h"
+#include "AliLog.h"
+#include "AliPID.h"
+#include "AliTOFPIDResponse.h"
+
+#include "AliHFEcollection.h"
+#include "AliHFEpidBase.h"
+#include "AliHFEtools.h"
+#include "AliHFEtofPIDqa.h"
+
+//_________________________________________________________
+AliHFEtofPIDqa::AliHFEtofPIDqa():
+    AliHFEdetPIDqa()
+  , fHistos(NULL)
+{
+  //
+  // Dummy constructor
+  //
+}
+
+//_________________________________________________________
+AliHFEtofPIDqa::AliHFEtofPIDqa(const char* name):
+    AliHFEdetPIDqa(name, "QA for TPC")
+  , fHistos(NULL)
+{
+  //
+  // Default constructor
+  //
+}
+
+//_________________________________________________________
+AliHFEtofPIDqa::AliHFEtofPIDqa(const AliHFEtofPIDqa &o):
+    AliHFEdetPIDqa(o)
+  , fHistos()
+{
+  //
+  // Copy constructor
+  //
+  o.Copy(*this);
+}
+
+//_________________________________________________________
+AliHFEtofPIDqa &AliHFEtofPIDqa::operator=(const AliHFEtofPIDqa &o){
+  //
+  // Do assignment
+  //
+  AliHFEdetPIDqa::operator=(o);
+  if(&o != this) o.Copy(*this);
+  return *this;
+}
+
+//_________________________________________________________
+AliHFEtofPIDqa::~AliHFEtofPIDqa(){
+  //
+  // Destructor
+  //
+  if(fHistos) delete fHistos;
+}
+
+//_________________________________________________________
+void AliHFEtofPIDqa::Copy(TObject &o) const {
+  //
+  // Make copy
+  //
+  AliHFEtofPIDqa &target = dynamic_cast<AliHFEtofPIDqa &>(o);
+  if(target.fHistos){
+    delete target.fHistos;
+    target.fHistos = NULL;
+  }
+  if(fHistos) target.fHistos = new AliHFEcollection(*fHistos);
+}
+
+//_________________________________________________________
+Long64_t AliHFEtofPIDqa::Merge(TCollection *coll){
+  //
+  // Merge with other objects
+  //
+  if(!coll) return 0;
+  if(coll->IsEmpty()) return 1;
+
+  TIter it(coll);
+  AliHFEtofPIDqa *refQA = NULL;
+  TObject *o = NULL;
+  Long64_t count = 0;
+  TList listHistos;
+  while((o = it())){
+    refQA = dynamic_cast<AliHFEtofPIDqa *>(o);
+    if(!refQA) continue;
+
+    listHistos.Add(refQA->fHistos);
+    count++; 
+  }
+  fHistos->Merge(&listHistos);
+  return count + 1;
+}
+
+//_________________________________________________________
+void AliHFEtofPIDqa::Initialize(){
+  //
+  // Define Histograms
+  //
+
+  fHistos = new AliHFEcollection("tofqahistos", "Collection of TOF QA histograms");
+
+  // Make common binning
+  const Int_t kPIDbins = AliPID::kSPECIES + 1;
+  const Int_t kPbins = 1000;
+  const Int_t kSteps = 2;
+  const Double_t kMinPID = -1;
+  const Double_t kMinP = 0.;
+  const Double_t kMaxPID = (Double_t)AliPID::kSPECIES;
+  const Double_t kMaxP = 20.;
+  
+  // 1st histogram: TOF sigmas: (species, p nsigma, step)
+  const Int_t kSigmaBins = 1400;
+  Int_t nBinsSigma[4] = {kPIDbins, kPbins, kSigmaBins, kSteps};
+  Double_t minSigma[4] = {kMinPID, kMinP, -12., 0};
+  Double_t maxSigma[4] = {kMaxPID, kMaxP, 12., 2.};
+  fHistos->CreateTHnSparse("tofnSigma", "TOF signal; species; p [GeV/c]; TOF signal [a.u.]; Selection Step", 4, nBinsSigma, minSigma, maxSigma);
+
+  // 2nd histogram: TOF time - pion hypothesis (TOF Time Resolution Monitor)
+  fHistos->CreateTH2F("tofTimeRes", "Difference between measured and expected time for Pions; p [GeV/c]; #Deltat [ps]", 100, 0.1, 10, 100, -200, 200); 
+  
+  // 3rd histogram: TPC sigmas to the electron line: (species, p nsigma, step - only filled if apriori PID information available)
+  fHistos->CreateTHnSparse("tofMonitorTPC", "TPC signal; species; p [GeV/c]; TPC signal [a.u.]; Selection Step", 4, nBinsSigma, minSigma, maxSigma);
+}
+
+//_________________________________________________________
+void AliHFEtofPIDqa::ProcessTrack(AliHFEpidObject *track, AliHFEdetPIDqa::EStep_t step){
+  //
+  // Fill TPC histograms
+  //
+  const AliVParticle *rectrack = track->GetRecTrack();
+  Int_t species = track->GetAbInitioPID();
+  if(species >= AliPID::kSPECIES) species = -1;
+  if(!TString(rectrack->IsA()->GetName()).CompareTo("AliESDtrack")) ProcessESDtrack(dynamic_cast<const AliESDtrack *>(rectrack), step, species);
+  else if(!TString(rectrack->IsA()->GetName()).CompareTo("AliAODTrack")) ProcessAODtrack(dynamic_cast<const AliAODTrack *>(rectrack), step, species);
+  else  AliWarning(Form("Object type %s not supported\n", rectrack->IsA()->GetName()));
+}
+
+//_________________________________________________________
+void AliHFEtofPIDqa::ProcessESDtrack(const AliESDtrack *track, AliHFEdetPIDqa::EStep_t step, Int_t species){
+  //
+  // Process track as ESD track
+  //
+  if(!fESDpid){
+    AliError("No ESD PID object available");
+    return;
+  }
+  AliDebug(1, Form("Monitoring particle of type %d for step %d", species, step));
+  
+  Double_t contentSignal[4];
+  contentSignal[0] = species;
+  contentSignal[1] = track->GetInnerParam() ? track->GetInnerParam()->P() : track->P();
+  contentSignal[2] = fESDpid->NumberOfSigmasTOF(track, AliPID::kElectron, fESDpid->GetTOFResponse().GetTimeZero()); 
+  contentSignal[3] = step;
+  (dynamic_cast<THnSparseF *>(fHistos->Get("tofnSigma")))->Fill(contentSignal);
+  Double_t tof = track->GetTOFsignal() - fESDpid->GetTOFResponse().GetTimeZero();
+  Double_t times[AliPID::kSPECIES]; track->GetIntegratedTimes(times);
+  fHistos->Fill("tofTimeRes",contentSignal[1], tof - times[AliPID::kPion]);
+  if(species > -1){
+    contentSignal[2] = fESDpid->NumberOfSigmasTPC(track, AliPID::kElectron);
+    fHistos->Fill("tofMonitorTPC", contentSignal);
+  }
+}
+
+//_________________________________________________________
+void AliHFEtofPIDqa::ProcessAODtrack(const AliAODTrack * /*track*/, AliHFEdetPIDqa::EStep_t /*step*/, Int_t /*species*/){
+  //
+  // Process track as AOD track
+  //
+  AliInfo("Method implemented soon!");
+}
+
+//_________________________________________________________
+TH2 *AliHFEtofPIDqa::MakeSpectrumNSigma(AliHFEdetPIDqa::EStep_t istep, Int_t species){
+  //
+  // Plot the Spectrum
+  //
+  THnSparseF *hSignal = dynamic_cast<THnSparseF *>(fHistos->Get("tofnSigma"));
+  hSignal->GetAxis(3)->SetRange(istep + 1, istep + 1);
+  if(species > 0 && species < AliPID::kSPECIES)
+    hSignal->GetAxis(0)->SetRange(2 + species, 2 + species);
+  TH2 *hTmp = hSignal->Projection(2,1);
+  Char_t hname[256], htitle[256];
+  sprintf(hname, "hTPCsigma%s", istep == AliHFEdetPIDqa::kBeforePID ? "before" : "after");
+  sprintf(htitle, "TPC dE/dx Spectrum[#sigma] %s selection", istep == AliHFEdetPIDqa::kBeforePID ? "before" : "after");
+  if(species > -1){
+    strncat(hname, AliPID::ParticleName(species), strlen(AliPID::ParticleName(species)));
+     Char_t speciesname[256];
+     sprintf(speciesname, " for %ss", AliPID::ParticleName(species));
+     strncat(htitle, speciesname, strlen(speciesname));
+  }
+  hTmp->SetName(hname);
+  hTmp->SetTitle(htitle);
+  hTmp->SetStats(kFALSE);
+  hTmp->GetXaxis()->SetTitle("p [GeV/c]");
+  hTmp->GetYaxis()->SetTitle("TOF time|_{el} - expected time|_{el} [#sigma]");
+  hSignal->GetAxis(3)->SetRange(0, hSignal->GetAxis(3)->GetNbins());
+  hSignal->GetAxis(0)->SetRange(0, hSignal->GetAxis(0)->GetNbins());
+  return hTmp;
+}
+
+//_________________________________________________________
+TH1 *AliHFEtofPIDqa::GetHistogram(const char *name){
+  // 
+  // Get the histogram
+  //
+  if(!fHistos) return NULL;
+  TObject *histo = fHistos->Get(name);
+  if(!histo->InheritsFrom("TH1")) return NULL;
+  return dynamic_cast<TH1 *>(histo);
+}
+
diff --git a/PWG3/hfe/AliHFEtofPIDqa.h b/PWG3/hfe/AliHFEtofPIDqa.h
new file mode 100644 (file)
index 0000000..8c11187
--- /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 AliHFEtofPIDqa
+// Monitoring TPC PID in the HFE PID montioring framework
+// More information can be found inside the implementation file
+//
+#ifndef ALIHFETOFPIDQA_H
+#define ALIHFETOFPIDQA_H
+
+#ifndef ALIHFEDETPIDQA_H
+#include "AliHFEdetPIDqa.h"
+#endif
+
+class TH1;
+class TH2;
+class AliHFEcollection;
+class AliHFEpidObject;
+class AliESDtrack;
+class AliAODTrack;
+
+class AliHFEtofPIDqa : public AliHFEdetPIDqa{
+  public:
+    AliHFEtofPIDqa();
+    AliHFEtofPIDqa(const char*name);
+    AliHFEtofPIDqa(const AliHFEtofPIDqa &o);
+    AliHFEtofPIDqa &operator=(const AliHFEtofPIDqa &o);
+    ~AliHFEtofPIDqa();
+    void Copy(TObject &o) const;
+    virtual Long64_t Merge(TCollection *col);
+  
+    virtual void Initialize();
+    virtual void ProcessTrack(AliHFEpidObject *track, AliHFEdetPIDqa::EStep_t step);
+
+    TH2 *MakeSpectrumNSigma(AliHFEdetPIDqa::EStep_t step, Int_t species = -1);
+    TH1 *GetHistogram(const char *name);
+    AliHFEcollection *GetHistoCollection() const { return fHistos; }
+
+  protected:
+    void ProcessESDtrack(const AliESDtrack *track, AliHFEdetPIDqa::EStep_t step, Int_t species);
+    void ProcessAODtrack(const AliAODTrack *track, AliHFEdetPIDqa::EStep_t step, Int_t species);
+  private:
+    AliHFEcollection *fHistos;        // Container for Histograms
+
+    ClassDef(AliHFEtofPIDqa, 1);
+};
+#endif
index 01afd2cd1df23964af4b01b1c3e295848cd381c0..13596180f220af6a63871acfe256744c740eb54b 100644 (file)
 #include "TAxis.h"
 
 #include "AliAODMCParticle.h"
+#include "AliAODpidUtil.h"
 #include "AliESDpid.h"
 #include "AliLog.h"
+#include "AliTPCPIDResponse.h"
 #include "AliTOFPIDResponse.h"
 
 #include "AliHFEtools.h"
@@ -37,6 +39,7 @@
 ClassImp(AliHFEtools)
 
 AliESDpid *AliHFEtools::fgDefaultPID = NULL;
+AliAODpidUtil *AliHFEtools::fgDefaultPIDaod = NULL;
 Int_t AliHFEtools::fgLogLevel = 0;
 
 //__________________________________________
@@ -133,7 +136,7 @@ Bool_t AliHFEtools::BinLogAxis(TObject *o, Int_t dim){
 }
 
 //__________________________________________
-Float_t AliHFEtools::GetRapidity(TParticle *part){
+Float_t AliHFEtools::GetRapidity(const TParticle *part){
   //
   // return rapidity
   //
@@ -144,7 +147,7 @@ Float_t AliHFEtools::GetRapidity(TParticle *part){
 }
 
 //__________________________________________
-Float_t AliHFEtools::GetRapidity(AliAODMCParticle *part){
+Float_t AliHFEtools::GetRapidity(const AliAODMCParticle *part){
   // return rapidity
 
   Float_t rapidity;        
@@ -193,6 +196,45 @@ AliESDpid* AliHFEtools::GetDefaultPID(Bool_t isMC){
   return fgDefaultPID;
 }
 
+//__________________________________________
+AliAODpidUtil* AliHFEtools::GetDefaultAODPID(Bool_t isMC){
+  //
+  // Get the default PID as singleton instance
+  //
+  if(!fgDefaultPID){
+    fgDefaultPIDaod = new AliAODpidUtil;
+    Double_t tres = isMC ? 80. : 130.;
+    fgDefaultPIDaod->GetTOFResponse().SetTimeResolution(tres);
+
+    // TPC Bethe Bloch parameters
+    Double_t alephParameters[5];
+    if(isMC){
+      // simulation
+      alephParameters[0] = 2.15898e+00/50.;
+      alephParameters[1] = 1.75295e+01;
+      alephParameters[2] = 3.40030e-09;
+      alephParameters[3] = 1.96178e+00;
+      alephParameters[4] = 3.91720e+00;
+    } else {
+      alephParameters[0] = 0.0283086/0.97;
+      //alephParameters[0] = 0.0283086;
+      alephParameters[1] = 2.63394e+01;
+      alephParameters[2] = 5.04114e-11;
+      alephParameters[3] = 2.12543e+00;
+      alephParameters[4] = 4.88663e+00;
+    }
+    fgDefaultPIDaod->GetTPCResponse().SetBetheBlochParameters(alephParameters[0],alephParameters[1],alephParameters[2], alephParameters[3],alephParameters[4]);
+    fgDefaultPIDaod->GetTPCResponse().SetSigma(3.79301e-03, 2.21280e+04);
+  }
+  if(fgLogLevel){
+    printf("Error - You are using the default PID: You should use the PID coming from the tender\n");
+    printf("Error - Arrrrrrrrr...\n");
+    printf("Error - Please rethink your program logic. Using default PID is really dangerous\n");
+    printf("Error - TOF PID is adapted to Monte Carlo\n");
+  }
+  return fgDefaultPIDaod;
+}
+
 //__________________________________________
 void AliHFEtools::DestroyDefaultPID(){
   //
@@ -200,4 +242,39 @@ void AliHFEtools::DestroyDefaultPID(){
   //
   if(fgDefaultPID) delete fgDefaultPID;
   fgDefaultPID = NULL;
+  if(fgDefaultPIDaod) delete fgDefaultPIDaod;
+  fgDefaultPIDaod = NULL;
+}
+
+//__________________________________________
+Int_t AliHFEtools::GetPdg(const AliVParticle *track){
+  // 
+  // Get MC PDG code (only MC particles supported)
+  //
+  Int_t pdg = 0;
+  if(!TString(track->IsA()->GetName()).CompareTo("AliMCParticle")){
+    const AliMCParticle *mctrack = dynamic_cast<const AliMCParticle *>(track);
+    pdg = mctrack->Particle()->GetPdgCode();
+  } else if(!TString(track->IsA()->GetName()).CompareTo("AliAODMCParticle")){
+    const AliAODMCParticle *aodmctrack = dynamic_cast<const AliAODMCParticle *>(track);
+    pdg = aodmctrack->GetPdgCode();
+  }
+  return pdg;
+}
+
+//__________________________________________
+Int_t AliHFEtools::PDG2AliPID(Int_t pdg){
+  // 
+  // Helper function to convert MC PID codes into AliPID codes
+  //
+  Int_t pid = -1;
+  switch(TMath::Abs(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; break;
+  };
+  return pid;
 }
index 6c4527ac8aa2b950f6b1fc53fb500113f3547699..0dc6dec5d56ddf1b4ba2c205b239b4cbdc8c8157 100644 (file)
@@ -25,6 +25,8 @@
 class TParticle;
 class AliAODMCParticle;
 class AliESDpid;
+class AliAODpidUtil;
+class AliVParticle;
 
 class AliHFEtools : public TObject{
   public:
@@ -34,15 +36,19 @@ class AliHFEtools : public TObject{
     static Double_t *MakeLinearBinning(Int_t nBins, Double_t ymin, Double_t ymax);
     static Double_t *MakeLogarithmicBinning(Int_t nBins, Double_t ymin, Double_t ymax);
     Bool_t    BinLogAxis(TObject *o, Int_t dim);
-    static Float_t GetRapidity(TParticle *part);
-    static Float_t GetRapidity(AliAODMCParticle *part); // return rapidity
+    static Float_t GetRapidity(const TParticle *part);
+    static Float_t GetRapidity(const AliAODMCParticle *part); // return rapidity
+    static Int_t GetPdg(const AliVParticle *track);
+    static Int_t PDG2AliPID(Int_t pdg);
     static AliESDpid *GetDefaultPID(Bool_t isMC = kTRUE);
+    static AliAODpidUtil *GetDefaultAODPID(Bool_t isMC = kTRUE);
     static void DestroyDefaultPID();
     static void SetLogLevel(Int_t loglevel) { fgLogLevel = loglevel ;}
 
   private:
-      static AliESDpid *fgDefaultPID;   // Default PID object
-      static Int_t fgLogLevel;          // Log Level
+      static AliESDpid *fgDefaultPID;           // Default PID object
+      static AliAODpidUtil *fgDefaultPIDaod;    // Default PID object
+      static Int_t fgLogLevel;                  // Log Level
 
     ClassDef(AliHFEtools, 0)
 };
diff --git a/PWG3/hfe/AliHFEtpcPIDqa.cxx b/PWG3/hfe/AliHFEtpcPIDqa.cxx
new file mode 100644 (file)
index 0000000..0b19a9e
--- /dev/null
@@ -0,0 +1,269 @@
+/**************************************************************************
+* 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 AliHFEtpcPIDqa
+// Monitoring TPC PID in the HFE PID montioring framework. The following
+// quantities are monitored:
+//   TPC dE/dx (Number of sigmas)
+//   TPC dE/dx (Absolute values)
+// (Always as function of momentum, particle species and centrality 
+// before and after cut)
+// More information about the PID monitoring framework can be found in
+// AliHFEpidQAmanager.cxx and AliHFEdetPIDqa.cxx
+//
+// Author:
+//    Markus Fasel <M.Fasel@gsi.de>
+//
+#include <TClass.h>
+#include <TH2.h>
+#include <THnSparse.h>
+#include <TString.h>
+
+#include "AliAODTrack.h"
+#include "AliESDtrack.h"
+#include "AliESDpid.h"
+#include "AliLog.h"
+#include "AliPID.h"
+
+#include "AliHFEcollection.h"
+#include "AliHFEpidBase.h"
+#include "AliHFEtools.h"
+#include "AliHFEtpcPIDqa.h"
+
+//_________________________________________________________
+AliHFEtpcPIDqa::AliHFEtpcPIDqa():
+    AliHFEdetPIDqa()
+  , fHistos(NULL)
+{
+  //
+  // Dummy constructor
+  //
+}
+
+//_________________________________________________________
+AliHFEtpcPIDqa::AliHFEtpcPIDqa(const char* name):
+    AliHFEdetPIDqa(name, "QA for TPC")
+  , fHistos(NULL)
+{
+  //
+  // Default constructor
+  //
+}
+
+//_________________________________________________________
+AliHFEtpcPIDqa::AliHFEtpcPIDqa(const AliHFEtpcPIDqa &o):
+    AliHFEdetPIDqa(o)
+  , fHistos()
+{
+  //
+  // Copy constructor
+  //
+  o.Copy(*this);
+}
+
+//_________________________________________________________
+AliHFEtpcPIDqa &AliHFEtpcPIDqa::operator=(const AliHFEtpcPIDqa &o){
+  //
+  // Do assignment
+  //
+  AliHFEdetPIDqa::operator=(o);
+  if(&o != this) o.Copy(*this);
+  return *this;
+}
+
+//_________________________________________________________
+AliHFEtpcPIDqa::~AliHFEtpcPIDqa(){
+  //
+  // Destructor
+  //
+  if(fHistos) delete fHistos;
+}
+
+//_________________________________________________________
+void AliHFEtpcPIDqa::Copy(TObject &o) const {
+  //
+  // Make copy
+  //
+  AliHFEtpcPIDqa &target = dynamic_cast<AliHFEtpcPIDqa &>(o);
+  if(target.fHistos){
+    delete target.fHistos;
+    target.fHistos = NULL;
+  }
+  if(fHistos) target.fHistos = new AliHFEcollection(*fHistos);
+}
+
+//_________________________________________________________
+Long64_t AliHFEtpcPIDqa::Merge(TCollection *coll){
+  //
+  // Merge with other objects
+  //
+  if(!coll) return 0;
+  if(coll->IsEmpty()) return 1;
+
+  TIter it(coll);
+  AliHFEtpcPIDqa *refQA = NULL;
+  TObject *o = NULL;
+  Long64_t count = 0;
+  TList listHistos;
+  while((o = it())){
+    refQA = dynamic_cast<AliHFEtpcPIDqa *>(o);
+    if(!refQA) continue;
+
+    listHistos.Add(refQA->fHistos);
+    count++; 
+  }
+  fHistos->Merge(&listHistos);
+  return count + 1;
+}
+
+//_________________________________________________________
+void AliHFEtpcPIDqa::Initialize(){
+  //
+  // Define Histograms
+  //
+
+  fHistos = new AliHFEcollection("tpcqahistos", "Collection of TPC QA histograms");
+
+  // Make common binning
+  const Int_t kNdim = 5;
+  const Int_t kPIDbins = AliPID::kSPECIES + 1;
+  const Int_t kPbins = 1000;
+  const Int_t kSteps = 2;
+  const Int_t kCentralityBins = 20;
+  const Double_t kMinPID = -1;
+  const Double_t kMinP = 0.;
+  const Double_t kMaxPID = (Double_t)AliPID::kSPECIES;
+  const Double_t kMaxP = 20.;
+  
+  // 1st histogram: TPC dEdx: (species, p, dEdx, step)
+  const Int_t kDedxbins = 600;
+  Int_t nBinsdEdx[kNdim] = {kPIDbins, kPbins, kDedxbins, kSteps, kCentralityBins};
+  Double_t mindEdx[kNdim] =  {kMinPID, kMinP, 0., 0., 0.};
+  Double_t maxdEdx[kNdim] =  {kMaxPID, kMaxP, 300, 2., 100.}; 
+  fHistos->CreateTHnSparse("tpcDedx", "TPC signal; species; p [GeV/c]; TPC signal [a.u.]; Centrality; Selection Step", kNdim, nBinsdEdx, mindEdx, maxdEdx);
+  // 2nd histogram: TPC sigmas: (species, p nsigma, step)
+  const Int_t kSigmaBins = 1400;
+  Int_t nBinsSigma[kNdim] = {kPIDbins, kPbins, kSigmaBins, kSteps, kCentralityBins};
+  Double_t minSigma[kNdim] = {kMinPID, kMinP, -12., 0., 0.};
+  Double_t maxSigma[kNdim] = {kMaxPID, kMaxP, 12., 2., 100.};
+  fHistos->CreateTHnSparse("tpcnSigma", "TPC signal; species; p [GeV/c]; TPC signal [a.u.]; Centrality; Selection Step", kNdim, nBinsSigma, minSigma, maxSigma);
+
+  // General TPC QA
+}
+
+//_________________________________________________________
+void AliHFEtpcPIDqa::ProcessTrack(AliHFEpidObject *track, AliHFEdetPIDqa::EStep_t step){
+  //
+  // Fill TPC histograms
+  //
+  AliDebug(1, Form("QA started for TPC PID for step %d", (Int_t)step));
+  Int_t species = track->GetAbInitioPID();
+  Float_t centrality = track->GetCentrality();
+  const AliVParticle *rectrack = track->GetRecTrack();
+  if(species >= AliPID::kSPECIES) species = -1;
+  if(!TString(rectrack->IsA()->GetName()).CompareTo("AliESDtrack")) ProcessESDtrack(dynamic_cast<const AliESDtrack *>(rectrack), step, species, centrality);
+  else if(!TString(rectrack->IsA()->GetName()).CompareTo("AliAODTrack")) ProcessAODtrack(dynamic_cast<const AliAODTrack *>(rectrack), step, species, centrality);
+  else  AliWarning(Form("Object type %s not supported\n", rectrack->IsA()->GetName()));
+}
+
+//_________________________________________________________
+void AliHFEtpcPIDqa::ProcessESDtrack(const AliESDtrack *track, AliHFEdetPIDqa::EStep_t step, Int_t species, Float_t centrality){
+  //
+  // Process track as ESD track
+  //
+  if(!fESDpid){
+    AliError("No ESD PID object available");
+    return;
+  }
+  AliDebug(1, Form("Monitoring particle of type %d for step %d", species, step));
+  
+  Double_t contentSignal[5];
+  contentSignal[0] = species;
+  contentSignal[1] = track->GetInnerParam() ? track->GetInnerParam()->P() : track->P();
+  contentSignal[2] = track->GetTPCsignal();
+  contentSignal[3] = step;
+  contentSignal[4] = centrality;
+  (dynamic_cast<THnSparseF *>(fHistos->Get("tpcDedx")))->Fill(contentSignal);
+
+  contentSignal[2] = fESDpid->NumberOfSigmasTPC(track, AliPID::kElectron); 
+  (dynamic_cast<THnSparseF *>(fHistos->Get("tpcnSigma")))->Fill(contentSignal);
+}
+
+//_________________________________________________________
+void AliHFEtpcPIDqa::ProcessAODtrack(const AliAODTrack * /*track*/, AliHFEdetPIDqa::EStep_t /*step*/, Int_t /*species*/, Float_t /*centrality*/){
+  //
+  // Process track as AOD track
+  //
+  AliInfo("Method implemented soon!");
+}
+
+//_________________________________________________________
+TH2 *AliHFEtpcPIDqa::MakeSpectrumdEdx(AliHFEdetPIDqa::EStep_t istep, Int_t species){
+  //
+  // Plot the Spectrum
+  //
+  THnSparseF *hSignal = dynamic_cast<THnSparseF *>(fHistos->Get("tpcDedx"));
+  hSignal->GetAxis(3)->SetRange(istep + 1, istep + 1);
+  if(species > 0 && species < AliPID::kSPECIES)
+    hSignal->GetAxis(0)->SetRange(2 + species, 2 + species);
+  TH2 *hTmp = hSignal->Projection(2,1);
+  Char_t hname[256], htitle[256];
+  sprintf(hname, "hTPCsignal%s", istep == AliHFEdetPIDqa::kBeforePID ? "before" : "after");
+  sprintf(htitle, "TPC dE/dx Spectrum %s selection", istep == AliHFEdetPIDqa::kBeforePID ? "before" : "after");
+  if(species > -1){
+    strncat(hname, AliPID::ParticleName(species), strlen(AliPID::ParticleName(species)));
+     Char_t speciesname[256];
+     sprintf(speciesname, " for %ss", AliPID::ParticleName(species));
+     strncat(htitle, speciesname, strlen(speciesname));
+  }
+  hTmp->SetName(hname);
+  hTmp->SetTitle(htitle);
+  hTmp->SetStats(kFALSE);
+  hTmp->GetXaxis()->SetTitle("p [GeV/c]");
+  hTmp->GetYaxis()->SetTitle("TPC signal [a.u.]");
+  hSignal->GetAxis(3)->SetRange(0, hSignal->GetAxis(3)->GetNbins());
+  hSignal->GetAxis(0)->SetRange(0, hSignal->GetAxis(0)->GetNbins());
+  return hTmp;
+}
+
+//_________________________________________________________
+TH2 *AliHFEtpcPIDqa::MakeSpectrumNSigma(AliHFEdetPIDqa::EStep_t istep, Int_t species){
+  //
+  // Plot the Spectrum
+  //
+  THnSparseF *hSignal = dynamic_cast<THnSparseF *>(fHistos->Get("tpcnSigma"));
+  hSignal->GetAxis(3)->SetRange(istep + 1, istep + 1);
+  if(species >= 0 && species < AliPID::kSPECIES)
+    hSignal->GetAxis(0)->SetRange(2 + species, 2 + species);
+  TH2 *hTmp = hSignal->Projection(2,1);
+  Char_t hname[256], htitle[256];
+  sprintf(hname, "hTPCsigma%s", istep == AliHFEdetPIDqa::kBeforePID ? "before" : "after");
+  sprintf(htitle, "TPC dE/dx Spectrum[#sigma] %s selection", istep == AliHFEdetPIDqa::kBeforePID ? "before" : "after");
+  if(species > -1){
+    strncat(hname, AliPID::ParticleName(species), strlen(AliPID::ParticleName(species)));
+     Char_t speciesname[256];
+     sprintf(speciesname, " for %ss", AliPID::ParticleName(species));
+     strncat(htitle, speciesname, strlen(speciesname));
+  }
+  hTmp->SetName(hname);
+  hTmp->SetTitle(htitle);
+  hTmp->SetStats(kFALSE);
+  hTmp->GetXaxis()->SetTitle("p [GeV/c]");
+  hTmp->GetYaxis()->SetTitle("TPC dE/dx - <dE/dx>|_{el} [#sigma]");
+  hSignal->GetAxis(3)->SetRange(0, hSignal->GetAxis(3)->GetNbins());
+  hSignal->GetAxis(0)->SetRange(0, hSignal->GetAxis(0)->GetNbins());
+  return hTmp;
+}
+
diff --git a/PWG3/hfe/AliHFEtpcPIDqa.h b/PWG3/hfe/AliHFEtpcPIDqa.h
new file mode 100644 (file)
index 0000000..dc3c909
--- /dev/null
@@ -0,0 +1,58 @@
+/**************************************************************************
+* 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 AliHFEtpcPIDqa
+// Monitoring TPC PID in the HFE PID montioring framework
+// More information can be found inside the implementation file
+//
+#ifndef ALIHFETPCPIDQA_H
+#define ALIHFETPCPIDQA_H
+
+#ifndef ALIHFEDETPIDQA_H
+#include "AliHFEdetPIDqa.h"
+#endif
+
+class TH2;
+class AliHFEcollection;
+class AliHFEpidObject;
+class AliESDtrack;
+class AliAODTrack;
+
+class AliHFEtpcPIDqa : public AliHFEdetPIDqa{
+  public:
+    AliHFEtpcPIDqa();
+    AliHFEtpcPIDqa(const char*name);
+    AliHFEtpcPIDqa(const AliHFEtpcPIDqa &o);
+    AliHFEtpcPIDqa &operator=(const AliHFEtpcPIDqa &o);
+    ~AliHFEtpcPIDqa();
+    void Copy(TObject &o) const;
+    virtual Long64_t Merge(TCollection *col);
+  
+    virtual void Initialize();
+    virtual void ProcessTrack(AliHFEpidObject *track, AliHFEdetPIDqa::EStep_t step);
+
+    AliHFEcollection *GetHistograms() const { return fHistos; }
+    TH2 *MakeSpectrumdEdx(AliHFEdetPIDqa::EStep_t step, Int_t species = -1);
+    TH2 *MakeSpectrumNSigma(AliHFEdetPIDqa::EStep_t step, Int_t species = -1);
+
+  protected:
+    void ProcessESDtrack(const AliESDtrack *track, AliHFEdetPIDqa::EStep_t step, Int_t species, Float_t centrality);
+    void ProcessAODtrack(const AliAODTrack *track, AliHFEdetPIDqa::EStep_t step, Int_t species, Float_t centrality);
+  private:
+    AliHFEcollection *fHistos;        // Container for Histograms
+
+    ClassDef(AliHFEtpcPIDqa, 1);
+};
+#endif
index 08412e7b2af9f4db18d618e97e433bec47285174..9e5f170903a391ebb0a4483b8e0d5bb5b57aa5b3 100644 (file)
@@ -252,10 +252,15 @@ void AliHFEtrdPIDqa::CreatedEdxHistogram(){
   AliDebug(1, "Called");
   Int_t nbins[kQuantitiesdEdx]; memcpy(nbins, fgkNBinsCommon, sizeof(Int_t) * kQuantitiesCommon);
   nbins[kdEdx] = 100;
+  nbins[kNclusters] = 261;
+  nbins[kNonZeroSlices] = 9; 
   Double_t binMin[kQuantitiesdEdx]; memcpy(binMin, fgkMinBinCommon, sizeof(Double_t) * kQuantitiesCommon);
-  binMin[kdEdx] = 0.;      
+  binMin[kdEdx] = 0.;     
+  binMin[kNclusters] = 0;
   Double_t binMax[kQuantitiesdEdx]; memcpy(binMax, fgkMaxBinCommon, sizeof(Double_t) * kQuantitiesCommon);
   binMax[kdEdx] = 100000.;
+  binMax[kNclusters] = 260.;
+  binMax[kNonZeroSlices] = 8.;
 
   fQAdEdx = new THnSparseF("fQAdEdx","TRD summed dEdx", kQuantitiesdEdx, nbins, binMin, binMax);
   Double_t *binLog = AliHFEtools::MakeLogarithmicBinning(nbins[kP], binMin[kP], binMax[kP]);
@@ -393,25 +398,34 @@ void AliHFEtrdPIDqa::FillTRDQAplots(AliESDtrack *track, Int_t species){
   quantitiesQA[kNTracklets] = quantitiesdEdx[kNTracklets] 
                             = quantitiesTruncMean[kNTracklets]
                             = track->GetTRDntrackletsPID();
-  quantitiesQA[kNClusters] = track->GetTRDncls();
+  quantitiesQA[kNClusters] = quantitiesdEdx[kNclusters] = track->GetTRDncls();
+  
 
-  Double_t dEdxSum;
-  Int_t ntrackletsNonZero = 0, nSlices = track->GetNumberOfTRDslices();
+  Double_t dEdxSum = 0., qSlice = 0.;
+  // remove the last slice from the histogram
+  Int_t ntrackletsNonZero = 0, nSlices = track->GetNumberOfTRDslices() - 1, nSlicesNonZero = 0;
   for(Int_t iplane = 0; iplane < AliESDtrack::kTRDnPlanes; iplane++){
     dEdxSum = 0.;
-    for(Int_t islice = 0; islice < nSlices; islice++)
-      dEdxSum += track->GetTRDslice(iplane, islice);
+    for(Int_t islice = 0; islice < nSlices; islice++){
+      qSlice = track->GetTRDslice(iplane, islice);
+      if(qSlice > 1e-1){
+        // cut out 0 slices
+        nSlicesNonZero++;
+        dEdxSum += qSlice;
+      }
+    }
+    quantitiesdEdx[kNonZeroSlices] = nSlicesNonZero;
     quantitiesdEdx[kdEdx] = dEdxSum;
     if(dEdxSum) ntrackletsNonZero++;
     // Fill dEdx histogram
-    fQAdEdx->Fill(quantitiesdEdx);
+    if(dEdxSum > 1e-1) fQAdEdx->Fill(quantitiesdEdx); // Cut out 0 entries
   }
   quantitiesQA[kNonZeroTrackletCharge] = ntrackletsNonZero;
   fQAtrack->Fill(quantitiesQA);
 
   quantitiesTruncMean[kTPCdEdx] = track->GetTPCsignal();
-  quantitiesTruncMean[kTRDdEdxMethod1] = fTRDpid->GetTRDSignalV1(track, -1);
-  quantitiesTruncMean[kTRDdEdxMethod2] = fTRDpid->GetTRDSignalV2(track, -1);
+  quantitiesTruncMean[kTRDdEdxMethod1] = fTRDpid->GetTRDSignalV1(track);
+  quantitiesTruncMean[kTRDdEdxMethod2] = fTRDpid->GetTRDSignalV2(track);
   fTRDtruncMean->Fill(quantitiesTruncMean);
 }
 
index 45b3170c0d8530384932949a11bbe24493af51f4..b4e7b6f6e96a8801429d882ea10ebad13de54392 100644 (file)
@@ -90,8 +90,10 @@ class AliHFEtrdPIDqa : public TNamed{
       kQuantitiesQA = 5
     };
     enum QuantitiesdEdx_t{
-      kdEdx = 3,
-      kQuantitiesdEdx = 4
+      kNclusters = 3,
+      kNonZeroSlices = 4,
+      kdEdx = 5,
+      kQuantitiesdEdx = 6
     };
     enum QuantitiesTruncMean_t{
       kTPCdEdx = 3,
diff --git a/PWG3/hfe/AliHFEtrdPIDqaV1.cxx b/PWG3/hfe/AliHFEtrdPIDqaV1.cxx
new file mode 100644 (file)
index 0000000..72fb759
--- /dev/null
@@ -0,0 +1,295 @@
+/**************************************************************************
+* 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 AliHFEtrdPIDqaV1
+// Monitoring TRD PID in the HFE PID montioring framework. The following
+// quantities are monitored:
+//   TRD electron likelihood
+//   TRD dE/dx (Absolute values)
+//   TPC dE/dx (Number of sigmas, control histogram)
+// (Always as function of momentum, particle species and centrality 
+// before and after cut)
+// More information about the PID monitoring framework can be found in
+// AliHFEpidQAmanager.cxx and AliHFEdetPIDqa.cxx
+//
+// Author:
+//    Markus Fasel <M.Fasel@gsi.de>
+//
+
+#include <TAxis.h>
+#include <TH2.h>
+#include <THnSparse.h>
+#include <TString.h>
+
+#include "AliAODTrack.h"
+#include "AliESDtrack.h"
+#include "AliESDpid.h"
+#include "AliExternalTrackParam.h"
+#include "AliPID.h"
+
+#include "AliHFEcollection.h"
+#include "AliHFEpidBase.h"
+#include "AliHFEtrdPIDqaV1.h"
+
+ClassImp(AliHFEtrdPIDqaV1)
+
+//____________________________________________________________
+AliHFEtrdPIDqaV1::AliHFEtrdPIDqaV1():
+    AliHFEdetPIDqa(),
+    fHistos(NULL)
+{
+  //
+  // Dummy constructor
+  //
+}
+
+//____________________________________________________________
+AliHFEtrdPIDqaV1::AliHFEtrdPIDqaV1(const Char_t *name):
+    AliHFEdetPIDqa(name, "QA for TRD"),
+    fHistos(NULL)
+{
+  //
+  // Default constructor
+  //
+}
+
+//____________________________________________________________
+AliHFEtrdPIDqaV1::AliHFEtrdPIDqaV1(const AliHFEtrdPIDqaV1 &o):
+    AliHFEdetPIDqa(o),
+    fHistos(NULL)
+{
+  //
+  // Copy constructor
+  //
+}
+
+//____________________________________________________________
+AliHFEtrdPIDqaV1 &AliHFEtrdPIDqaV1::operator=(const AliHFEtrdPIDqaV1 &o){
+  //
+  // Make assignment
+  //
+  AliHFEdetPIDqa::operator=(o);
+  fHistos = o.fHistos;
+  
+  return *this;
+}
+
+//_________________________________________________________
+Long64_t AliHFEtrdPIDqaV1::Merge(TCollection *coll){
+  //
+  // Merge with other objects
+  //
+  if(!coll) return 0;
+  if(coll->IsEmpty()) return 1;
+
+  TIter it(coll);
+  AliHFEtrdPIDqaV1 *refQA = NULL;
+  TObject *o = NULL;
+  Long64_t count = 0;
+  TList listHistos;
+  while((o = it())){
+    refQA = dynamic_cast<AliHFEtrdPIDqaV1 *>(o);
+    if(!refQA) continue;
+
+    listHistos.Add(refQA->fHistos);
+    count++; 
+  }
+  fHistos->Merge(&listHistos);
+  return count + 1;
+}
+
+//____________________________________________________________
+void AliHFEtrdPIDqaV1::Initialize(){
+  //
+  // Initialize QA histos for TRD PID
+  //
+
+  AliDebug(1, "Initializing PID QA for TRD");
+  // Make common binning
+  const Int_t kPIDbins = AliPID::kSPECIES + 1;
+  const Int_t kPbins = 100;
+  const Int_t kSteps = 2;
+  const Double_t kMinPID = -1;
+  const Double_t kMinP = 0.;
+  const Double_t kMaxPID = (Double_t)AliPID::kSPECIES;
+  const Double_t kMaxP = 20.;
+
+  fHistos = new AliHFEcollection("trdqahistos", "Collection of TRD QA histograms");
+  
+  // Create Control Histogram monitoring the TPC sigma between the selection steps
+  const Int_t kTPCSigmaBins = 140;
+  Int_t nBinsTPCSigma[4] = {kPIDbins, kPbins, kTPCSigmaBins, kSteps};
+  Double_t minTPCSigma[4] = {kMinPID, kMinP, -12., 0};
+  Double_t maxTPCSigma[4] = {kMaxPID, kMaxP, 12., 2.};
+  fHistos->CreateTHnSparse("hTPCsigma", "TPC sigma; species p [GeV/c]; TPC dEdx - <dE/dx>|_{el} [#sigma]; selection step", 4, nBinsTPCSigma, minTPCSigma, maxTPCSigma);
+  // Create Monitoring histogram for the Likelihood distribution
+  const Int_t kTRDLikelihoodBins = 100;
+  Int_t nBinsTRDlike[4] = {kPIDbins, kPbins, kTRDLikelihoodBins, kSteps};
+  Double_t minTRDlike[4] = {kMinPID, kMinP, 0., 0.};
+  Double_t maxTRDlike[4] = {kMaxPID, kMaxP, 1., 2.};
+  fHistos->CreateTHnSparse("hTRDlikelihood", "TRD Likelihood Distribution; species; p [GeV/c]; TRD electron Likelihood; selection step", 4, nBinsTRDlike, minTRDlike, maxTRDlike);
+  // Create Monitoring histogram for the TRD total charge
+  const Int_t kTRDchargeBins = 1000;
+  Int_t nBinsTRDcharge[4] = {kPIDbins, kPbins, kTRDchargeBins, kSteps};
+  Double_t minTRDcharge[4] = {kMinPID, kMinP, 0., 0.};
+  Double_t maxTRDcharge[4] = {kMaxPID, kMaxP, 100000., 2.};
+  fHistos->CreateTHnSparse("hTRDcharge", "Total TRD charge; species; p [GeV/c]; TRD charge [a.u.]; selection step", 4, nBinsTRDcharge, minTRDcharge, maxTRDcharge);
+}
+
+//____________________________________________________________
+void AliHFEtrdPIDqaV1::ProcessTrack(AliHFEpidObject *track, AliHFEdetPIDqa::EStep_t step){
+  //
+  // Process the track, fill the containers 
+  //
+  AliDebug(1, Form("QA started for TRD PID for step %d", (Int_t)step));
+  Int_t species = track->GetAbInitioPID();
+  const AliVParticle *rectrack = track->GetRecTrack();
+  if(species >= AliPID::kSPECIES) species = -1;
+  if(!TString(rectrack->IsA()->GetName()).CompareTo("AliESDtrack")) ProcessESDtrack(dynamic_cast<const AliESDtrack *>(rectrack), step, species);
+  else if(!TString(rectrack->IsA()->GetName()).CompareTo("AliAODTrack")) ProcessAODtrack(dynamic_cast<const AliAODTrack *>(rectrack), step, species);
+  else  AliWarning(Form("Object type %s not supported\n", rectrack->IsA()->GetName()));
+}
+
+//____________________________________________________________
+void AliHFEtrdPIDqaV1::ProcessESDtrack(const AliESDtrack *track, AliHFEdetPIDqa::EStep_t step, Int_t species){
+  //
+  // Fill QA histograms
+  //
+  Double_t container[4];
+  container[0] = species;
+  container[1] = track->GetOuterParam() ? track->GetOuterParam()->P() : track->P();
+  container[2] = fESDpid->NumberOfSigmasTPC(track, AliPID::kElectron);
+  container[3] = step;
+  fHistos->Fill("hTPCsigma", container);
+
+  Double_t pid[5];
+  track->GetTRDpid(pid);
+  container[2] = pid[AliPID::kElectron];
+  fHistos->Fill("hTRDlikelihood", container);
+
+  Double_t charge = 0.;
+  for(Int_t ily = 0; ily < 6; ily++){
+    charge = 0.;
+    for(Int_t isl = 0; isl < track->GetNumberOfTRDslices(); isl++){
+      charge += track->GetTRDslice(ily, isl);
+    }
+    fHistos->Fill("hTRDcharge", container);
+  }
+}
+
+//_________________________________________________________
+void AliHFEtrdPIDqaV1::ProcessAODtrack(const AliAODTrack * /*track*/, AliHFEdetPIDqa::EStep_t /*step*/, Int_t /*species*/){
+  //
+  // To be implemented
+  //
+}
+
+//_________________________________________________________
+TH2 *AliHFEtrdPIDqaV1::MakeTPCspectrumNsigma(AliHFEdetPIDqa::EStep_t step, Int_t species){
+  //
+  // Get the TPC control histogram for the TRD selection step (either before or after PID)
+  //
+  printf("histos :%p\n", fHistos);
+  THnSparseF *histo = dynamic_cast<THnSparseF *>(fHistos->Get("hTPCsigma"));
+  if(!histo){
+    AliError("QA histogram monitoring TPC nSigma not available");
+    return NULL;
+  }
+  if(species > -1 && species < AliPID::kSPECIES){
+    // cut on species (if available)
+    histo->GetAxis(0)->SetRange(species + 2, species + 2); // undef + underflow
+  }
+  histo->GetAxis(3)->SetRangeUser(species + 1, species + 1);
+
+  TH2 *hSpec = histo->Projection(2, 1);
+  // construct title and name
+  TString stepname = step ? "before" : "after";
+  TString speciesname = species > -1 && species < AliPID::kSPECIES ? AliPID::ParticleName(species) : "all Particles";
+  TString specID = species > -1 && species < AliPID::kSPECIES ? AliPID::ParticleName(species) : "unid";
+  TString histname = Form("hSigmaTPC%s%s", specID.Data(), stepname.Data());
+  TString histtitle = Form("TPC Sigma for %s %s PID", speciesname.Data(), stepname.Data());
+  hSpec->SetName(histname.Data());
+  hSpec->SetTitle(histtitle.Data());
+
+  // Unset range on the original histogram
+  histo->GetAxis(0)->SetRange(0, histo->GetAxis(0)->GetNbins());
+  histo->GetAxis(2)->SetRange(0, histo->GetAxis(2)->GetNbins());
+  return hSpec; 
+}
+
+//_________________________________________________________
+TH2 *AliHFEtrdPIDqaV1::MakeTRDlikelihoodDistribution(AliHFEdetPIDqa::EStep_t step, Int_t species){
+  //
+  // Make Histogram for TRD Likelihood distribution
+  //
+  THnSparseF *histo = dynamic_cast<THnSparseF *>(fHistos->Get("hTRDlikelihood"));
+  if(!histo){
+    AliError("QA histogram monitoring TRD Electron Likelihood not available");
+    return NULL;
+  }
+  if(species > -1 && species < AliPID::kSPECIES){
+    // cut on species (if available)
+    histo->GetAxis(0)->SetRange(species + 2, species + 2); // undef + underflow
+  }
+  histo->GetAxis(3)->SetRangeUser(species + 1, species + 1);
+
+  TH2 *hSpec = histo->Projection(2, 1);
+  // construct title and name
+  TString stepname = step ? "before" : "after";
+  TString speciesname = species > -1 && species < AliPID::kSPECIES ? AliPID::ParticleName(species) : "all Particles";
+  TString specID = species > -1 && species < AliPID::kSPECIES ? AliPID::ParticleName(species) : "unid";
+  TString histname = Form("hLikeElTRD%s%s", specID.Data(), stepname.Data());
+  TString histtitle = Form("TRD electron Likelihood for %s %s PID", speciesname.Data(), stepname.Data());
+  hSpec->SetName(histname.Data());
+  hSpec->SetTitle(histtitle.Data());
+
+  // Unset range on the original histogram
+  histo->GetAxis(0)->SetRange(0, histo->GetAxis(0)->GetNbins());
+  histo->GetAxis(2)->SetRange(0, histo->GetAxis(2)->GetNbins());
+  return hSpec; 
+}
+
+//_________________________________________________________
+TH2 *AliHFEtrdPIDqaV1::MakeTRDchargeDistribution(AliHFEdetPIDqa::EStep_t step, Int_t species){
+  //
+  // Make Histogram for TRD Likelihood distribution
+  //
+  THnSparseF *histo = dynamic_cast<THnSparseF *>(fHistos->Get("hTRDcharge"));
+  if(!histo){
+    AliError("QA histogram monitoring TRD total charge not available");
+    return NULL;
+  }
+  if(species > -1 && species < AliPID::kSPECIES){
+    // cut on species (if available)
+    histo->GetAxis(0)->SetRange(species + 2, species + 2); // undef + underflow
+  }
+  histo->GetAxis(3)->SetRangeUser(species + 1, species + 1);
+
+  TH2 *hSpec = histo->Projection(2, 1);
+  // construct title and name
+  TString stepname = step ? "before" : "after";
+  TString speciesname = species > -1 && species < AliPID::kSPECIES ? AliPID::ParticleName(species) : "all Particles";
+  TString specID = species > -1 && species < AliPID::kSPECIES ? AliPID::ParticleName(species) : "unid";
+  TString histname = Form("hChargeTRD%s%s", specID.Data(), stepname.Data());
+  TString histtitle = Form("TRD total charge for %s %s PID", speciesname.Data(), stepname.Data());
+  hSpec->SetName(histname.Data());
+  hSpec->SetTitle(histtitle.Data());
+
+  // Unset range on the original histogram
+  histo->GetAxis(0)->SetRange(0, histo->GetAxis(0)->GetNbins());
+  histo->GetAxis(2)->SetRange(0, histo->GetAxis(2)->GetNbins());
+  return hSpec; 
+}
+
diff --git a/PWG3/hfe/AliHFEtrdPIDqaV1.h b/PWG3/hfe/AliHFEtrdPIDqaV1.h
new file mode 100644 (file)
index 0000000..a02ea15
--- /dev/null
@@ -0,0 +1,56 @@
+/**************************************************************************
+* 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 AliHFEtrdPIDqaV1
+// Monitoring TRD PID in the HFE PID montioring framework. 
+// More information can be found inside the implementation file
+//
+#ifndef ALIHFETRDPIDQAV1_H
+#define ALIHFETRDPIDQAV1_H
+
+#ifndef ALIHFEDETPIDQAV1_H
+#include "AliHFEdetPIDqa.h"
+#endif
+
+class AliESDtrack;
+class AliAODTrack;
+class AliHFEcollection;
+class AliHFEpidObject;
+class TCollection;
+
+class AliHFEtrdPIDqaV1 : public AliHFEdetPIDqa{
+  public:
+    AliHFEtrdPIDqaV1();
+    AliHFEtrdPIDqaV1(const Char_t *name);
+    AliHFEtrdPIDqaV1(const AliHFEtrdPIDqaV1 &c);
+    AliHFEtrdPIDqaV1 &operator=(const AliHFEtrdPIDqaV1 &o);
+    ~AliHFEtrdPIDqaV1(){}
+
+    virtual void Initialize();
+    virtual Long64_t Merge(TCollection *coll);
+    virtual void ProcessTrack(AliHFEpidObject *track, AliHFEdetPIDqa::EStep_t step);
+
+    TH2 *MakeTPCspectrumNsigma(AliHFEdetPIDqa::EStep_t step, Int_t species = -1);
+    TH2 *MakeTRDlikelihoodDistribution(AliHFEdetPIDqa::EStep_t step, Int_t species = -1);
+    TH2 *MakeTRDchargeDistribution(AliHFEdetPIDqa::EStep_t step, Int_t species = -1);
+  protected:
+    void ProcessESDtrack(const AliESDtrack *esdtrack, AliHFEdetPIDqa::EStep_t step, Int_t species);
+    void ProcessAODtrack(const AliAODTrack *aodtrack, AliHFEdetPIDqa::EStep_t step, Int_t species);
+    AliHFEcollection *fHistos; // QA histograms
+
+    ClassDef(AliHFEtrdPIDqaV1, 1)     // Base class for detector PID QA
+};
+
+#endif
diff --git a/PWG3/hfe/AliHFEvarManager.cxx b/PWG3/hfe/AliHFEvarManager.cxx
new file mode 100644 (file)
index 0000000..c3ed37b
--- /dev/null
@@ -0,0 +1,425 @@
+/**************************************************************************
+* 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 AliHFEvarManager:
+// Contains definition of the variables which are filled into the 
+// Correction framework container. The class handles both AliCFContainer and
+// AliHFEcontainer.
+// Defining a new variable which has to be monitored can be done via the
+// function AddVariable. This function also defines a new dimension for the
+// particle container and appends it to the list of variables. For a new
+// track the function NewTrack caches the values to be filled into the 
+// correction framework container. With FillContainer the specified 
+// correction framework container is filled. The VarManager also handles
+// the filling of the correlation matrices
+//
+// Author:
+//   Markus Fasel <M.Fasel@gsi.de>
+//
+#include <TClass.h>
+#include <TH3.h>
+#include <TF3.h>
+#include <TMath.h>
+#include <THnSparse.h>
+#include <TString.h>
+
+#include "AliCFContainer.h"
+#include "AliLog.h"
+#include "AliVParticle.h"
+
+#include "AliHFEcontainer.h"
+#include "AliHFEsignalCuts.h"
+#include "AliHFEvarManager.h"
+
+ClassImp(AliHFEvarManager)
+ClassImp(AliHFEvarManager::AliHFEvariable);
+
+//____________________________________________________________
+AliHFEvarManager::AliHFEvarManager():
+  TNamed(),
+  fVariables(NULL),
+  fContent(NULL),
+  fContentMC(NULL),
+  fWeightFactor(1.),
+  fSignalTrack(kTRUE),
+       fWeighting(kFALSE),
+  fSignal(NULL),
+       fWeightFactors(NULL),
+       fWeightFactorsFunction(NULL)
+{
+       //
+       // Dummy constructor
+  //
+  SetOwner();
+}
+
+//____________________________________________________________
+AliHFEvarManager::AliHFEvarManager(const Char_t *name):
+  TNamed(name, ""),
+  fVariables(NULL),
+  fContent(NULL),
+  fContentMC(NULL),
+  fWeightFactor(1.),
+  fSignalTrack(kTRUE),
+       fWeighting(kFALSE),
+  fSignal(NULL),
+       fWeightFactors(NULL),
+       fWeightFactorsFunction(NULL)
+{
+       //
+       // Default constructor
+  //
+  fVariables = new TObjArray;
+  SetOwner();
+}
+
+//____________________________________________________________
+AliHFEvarManager::AliHFEvarManager(const AliHFEvarManager &ref):
+  TNamed(ref),
+  fVariables(NULL),
+  fContent(NULL),
+  fContentMC(NULL),
+  fWeightFactor(ref.fWeightFactor),
+  fSignalTrack(ref.fSignalTrack),
+       fWeighting(ref.fWeighting),
+  fSignal(NULL),
+       fWeightFactors(NULL),
+       fWeightFactorsFunction(NULL)
+{
+  //
+  // Copy Constructor
+  //
+  ref.Copy(*this);
+}
+
+//____________________________________________________________
+AliHFEvarManager &AliHFEvarManager::operator=(const AliHFEvarManager &ref){
+  //
+  // Assignment operator
+  //
+  if(&ref != this){ 
+    this->~AliHFEvarManager();
+    ref.Copy(*this);
+  }
+  return *this;
+}
+
+//____________________________________________________________
+AliHFEvarManager::~AliHFEvarManager(){
+       //
+       // Destructor
+       //
+  if(IsOwner()){
+    if(fVariables) delete fVariables;
+  }
+  if(fContent) delete[] fContent;
+  if(fContentMC) delete[] fContentMC;
+}
+
+//____________________________________________________________
+void AliHFEvarManager::Copy(TObject &o) const{
+  //
+  // Make Copy
+  //
+  AliHFEvarManager &target = dynamic_cast<AliHFEvarManager &>(o);
+  target.fVariables = fVariables;
+  target.fContent = new Double_t[sizeof(fContent)/sizeof(Double_t)]; 
+  target.fContentMC = new Double_t[sizeof(fContentMC)/sizeof(Double_t)];
+  target.fWeightFactor = fWeightFactor;
+  target.fSignalTrack = fSignalTrack;
+       target.fWeighting = fWeighting;
+  target.fSignal = fSignal;
+       target.fWeightFactors = fWeightFactors;
+  target.fWeightFactorsFunction = fWeightFactorsFunction; 
+  target.SetOwner(kFALSE);
+}
+
+//____________________________________________________________
+void AliHFEvarManager::AddVariable(TString name){
+  //
+  // Add new variable to the var manager
+  // Value derived via GetValue()
+  //
+   AliDebug(1, Form("Var Name: %s", name.Data()));
+
+  if(!name.CompareTo("pt")) 
+    fVariables->AddLast(new AliHFEvariable("pt", "pt", kPt, 44, 0.1, 20, kTRUE));
+  else if(!name.CompareTo("eta"))
+    fVariables->AddLast(new AliHFEvariable("eta", "eta", kEta, 8, -0.8, 0.8));
+  else if(!name.CompareTo("phi"))
+    fVariables->AddLast(new AliHFEvariable("phi", "phi", kPhi, 18, -0, 2*TMath::Pi()));
+  else if(!name.CompareTo("charge"))
+    fVariables->AddLast(new AliHFEvariable("charge", "charge", kCharge, 2, -1.1, 1.1));
+  else if(!name.CompareTo("source"))
+    fVariables->AddLast(new AliHFEvariable("source", "source", kSource, 4, 0, 4));
+  else if(!name.CompareTo("centrality"))
+    fVariables->AddLast(new AliHFEvariable("centrality", "centrality", kCentrality, 20, 0.0, 100.0));
+  else if(!name.CompareTo("species"))
+    fVariables->AddLast(new AliHFEvariable("species", "species", kSpecies, 6, -1, 5));
+
+  // More to come ...
+}
+
+//____________________________________________________________
+void AliHFEvarManager::DefineVariables(AliHFEcontainer *cont){
+       //
+       // Define Variables
+       //
+  Int_t nVars = fVariables->GetEntriesFast();
+  cont->SetNumberOfVariables(nVars);
+  TIter vars(fVariables);
+  AliHFEvariable *var;
+  Int_t counter = 0;
+  while((var = dynamic_cast<AliHFEvariable *>(vars()))){
+    cont->SetVariableName(counter, var->GetName());
+    if(var->IsLogarithmic())
+      cont->MakeLogarithmicBinning(counter, var->GetNumberOfBins(), var->GetMinimum(), var->GetMaximum());
+    else
+      cont->MakeLinearBinning(counter, var->GetNumberOfBins(), var->GetMinimum(), var->GetMaximum());
+    counter++;
+  }
+       fContent = new Double_t[nVars]; 
+  memset(fContent, 0, sizeof(Double_t) * nVars);
+  fContentMC = new Double_t[nVars]; 
+  memset(fContentMC, 0, sizeof(Double_t) * nVars);
+}
+
+//____________________________________________________________
+void AliHFEvarManager::NewTrack(AliVParticle *recTrack, AliVParticle *mcTrack, Float_t centrality, Int_t aprioriPID, Bool_t signal){
+  //
+  // Cache information for new track pair
+  //
+  AliDebug(1, "Filling new Track");
+  fSignalTrack = signal;
+  FillArray(recTrack, fContent, centrality, aprioriPID);
+  if(mcTrack) FillArray(mcTrack, fContentMC, centrality, aprioriPID);
+  if(fWeighting){
+    Int_t indexpt = -1, indexeta = -1, indexphi = -1, counter = 0;
+    AliHFEvariable *var = NULL;
+    TIter vars(fVariables);
+    while((var = dynamic_cast<AliHFEvariable *>(vars()))){
+      switch(var->GetVarCode()){
+        case kPt:   indexpt = counter;  break;
+        case kEta:  indexeta = counter; break;
+        case kPhi:  indexphi = counter; break;
+      };
+      if(indexpt >= 0 && indexeta >= 0 && indexphi >= 0) // all dimensions found
+        break;
+      counter++;
+    }
+    if(indexpt >= 0 && indexeta >= 0 && indexphi >= 0)
+      fWeightFactor = FindWeight(fContent[indexpt], fContent[indexeta], fContent[indexphi]);
+  }
+}
+
+//____________________________________________________________
+Double_t AliHFEvarManager::GetValue(AliVParticle *track, UInt_t code, Float_t centrality, Int_t aprioriPID) const {
+  //
+  // Definition of the variables
+  //
+  if(!track) return 0.;
+  Double_t value = 0.;
+  switch(code){
+    case kPt:       value = track->Pt();  break;
+    case kEta:      value = track->Eta(); break;
+    case kPhi:      value = track->Phi(); break;
+    case kCharge:{
+      value = track->Charge();
+      if(TString(track->IsA()->GetName()).Contains("MC")) value /= 3;
+      break;
+    }
+    case kSource:{
+      if(fSignal){
+             if(fSignal->IsCharmElectron(track)) value = 0;
+             else if(fSignal->IsBeautyElectron(track)) value = 1;
+             else if(fSignal->IsGammaElectron(track)) value = 2;
+             else value = 3;
+      }
+      break;
+    }
+    case kSpecies:  value = aprioriPID; break; 
+    case kCentrality:  value = centrality; break;  
+  };
+  return value;
+}
+
+//____________________________________________________________
+void AliHFEvarManager::FillArray(AliVParticle *track, Double_t* container, Float_t centrality, Int_t aprioriPID) const{
+       //
+       // Fill array with variables
+       //
+  TIter vars(fVariables);
+  AliHFEvariable *var = NULL;
+  Int_t counter = 0;
+  while((var = dynamic_cast<AliHFEvariable *>(vars())))
+    container[counter++] = GetValue(track , var->GetVarCode(), centrality, aprioriPID);
+}
+
+//____________________________________________________________
+void AliHFEvarManager::FillContainer(AliCFContainer *cont, Int_t step, Bool_t useMC) const{
+       //
+       // Fill CF container with defined content
+       //
+
+       // Do reweighting if necessary
+  Double_t *content = fContent;
+  if(useMC) content = fContentMC;
+       cont->Fill(content, step, fWeightFactor);
+}
+
+//____________________________________________________________
+void AliHFEvarManager::FillContainer(AliHFEcontainer *cont, const Char_t *contname, UInt_t step, Bool_t useMC, Double_t externalWeight) const {
+       //
+       // Fill CF container with defined content
+       //
+
+  // Do reweighting if necessary
+  Double_t *content = fContent;
+  if(useMC) content = fContentMC;
+       cont->FillCFContainer(contname, step, content, fWeightFactor * externalWeight);
+}  
+
+//____________________________________________________________
+void AliHFEvarManager::FillContainerStepname(AliHFEcontainer *cont, const Char_t *contname, const Char_t *step, Bool_t useMC, Double_t externalWeight) const {
+       //
+       // Fill CF container with defined content
+       //
+
+  // Do reweighting if necessary
+  Double_t *content = fContent;
+  if(useMC) content = fContentMC;
+       cont->FillCFContainerStepname(contname, step, content, fWeightFactor * externalWeight);
+}  
+
+//____________________________________________________________
+void AliHFEvarManager::FillCorrelationMatrix(THnSparseF *matrix) const {
+       //
+       // Fill Correlation Matrix
+       //
+
+       // Do reweighting if necessary
+  Double_t content[10];
+  memcpy(content, fContent, sizeof(Double_t) * 5);
+  memcpy(&content[5], fContentMC, sizeof(Double_t) * 5);
+       matrix->Fill(content, fWeightFactor);
+}
+
+//_______________________________________________
+void AliHFEvarManager::SetWeightFactors(TH3F *weightFactors){
+       //
+       // Set the histos with the weights for the efficiency maps
+       //
+       fWeighting = kTRUE;
+       fWeightFactors = weightFactors;
+}
+
+//_______________________________________________
+void AliHFEvarManager::SetWeightFactorsFunction(TF3 *weightFactorsFunction){
+       //
+       // Set the histos with the weights for the efficiency maps
+       //
+       fWeighting = kTRUE;
+       fWeightFactorsFunction = weightFactorsFunction;
+}
+
+//_______________________________________________
+Double_t AliHFEvarManager::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);
+
+       }
+
+       AliDebug(2, Form("pt %f, eta %f, phi %f, weight %f",pt,eta,phi,weight));
+
+       return weight;
+}
+
+//_______________________________________________
+AliHFEvarManager::AliHFEvariable::AliHFEvariable():
+    TNamed()
+  , fCode(0)
+  , fNBins(0)
+  , fMin(0)
+  , fMax(0)
+  , fIsLogarithmic(kFALSE)
+{
+  // 
+  // Dummy constructor
+  //
+}
+
+//_______________________________________________
+AliHFEvarManager::AliHFEvariable::AliHFEvariable(const Char_t *name, const Char_t *title, UInt_t code, UInt_t nBins, Double_t min, Double_t max, Bool_t isLogarithmic):
+    TNamed(name, title)
+  , fCode(code)
+  , fNBins(nBins)
+  , fMin(min)
+  , fMax(max)
+  , fIsLogarithmic(isLogarithmic)
+{
+  // 
+  // Default constructor
+  //
+}
+
+//_______________________________________________
+AliHFEvarManager::AliHFEvariable::AliHFEvariable(const AliHFEvarManager::AliHFEvariable &ref):
+    TNamed(ref)
+  , fCode(ref.fCode)
+  , fNBins(ref.fNBins)
+  , fMin(ref.fMin)
+  , fMax(ref.fMax)
+  , fIsLogarithmic(ref.fIsLogarithmic)
+{
+  // 
+  // Copy constructor
+  //
+}
+
+//_______________________________________________
+AliHFEvarManager::AliHFEvariable& AliHFEvarManager::AliHFEvariable::operator=(const AliHFEvarManager::AliHFEvariable &ref){
+  //
+  // Assignment operator
+  //
+  
+  if(&ref != this){
+    TNamed::operator=(ref);
+    fCode = ref.fCode;
+    fNBins = ref.fNBins;
+    fMax = ref.fMax;
+    fMin = ref.fMin;
+    fIsLogarithmic = ref.fIsLogarithmic;
+  }
+  return *this;
+}
+
diff --git a/PWG3/hfe/AliHFEvarManager.h b/PWG3/hfe/AliHFEvarManager.h
new file mode 100644 (file)
index 0000000..9342490
--- /dev/null
@@ -0,0 +1,119 @@
+/**************************************************************************
+* 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 AliHFEvarManager
+// Common place for definiton of variables to be filled into the 
+// correction framework container
+// More information can be found inside the implementation file
+//
+#ifndef ALIHFEVARMANAGER_H
+#define ALIHFEVARMANAGER_H
+
+#ifndef ROOT_TNamed
+#include <TNamed.h>
+#endif
+
+template <class X>
+class THnSparseT;
+class TArrayF;
+typedef class THnSparseT<TArrayF> THnSparseF;
+class TH3F;
+class TF3;
+class AliCFContainer;
+class AliHFEcontainer;
+class AliHFEsignalCuts;
+class AliVParticle;
+
+
+class AliHFEvarManager : public TNamed{
+public:
+  enum EVarCode_t{
+    kPt = 1,
+    kEta,
+    kPhi,
+    kCharge,
+    kSource,
+    kCentrality,
+    kSpecies,
+  };
+       AliHFEvarManager();
+       AliHFEvarManager(const Char_t *name);
+  AliHFEvarManager(const AliHFEvarManager &ref);
+  AliHFEvarManager &operator=(const AliHFEvarManager &ref);
+  void Copy(TObject &o) const;
+       ~AliHFEvarManager();
+  
+  void SetOwner(Bool_t owner = kTRUE) { SetBit(kOwner, owner); }
+  Bool_t IsOwner() const { return TestBit(kOwner); }
+
+  void AddVariable(TString name);
+  void DefineVariables(AliHFEcontainer *cont);
+  void NewTrack(AliVParticle *track, AliVParticle *mcTrack = NULL, Float_t centrality = 99.0, Int_t aprioriPID = -1, Bool_t signal = kTRUE);
+  Bool_t IsSignalTrack() const { return fSignalTrack; }
+  void FillContainer(AliCFContainer *cont, Int_t step, Bool_t useMC = kFALSE) const;
+  void FillContainer(AliHFEcontainer *cont, const Char_t *contname, UInt_t step, Bool_t useMC = kFALSE, Double_t externalWeight = 1.) const;
+  void FillContainerStepname(AliHFEcontainer *cont, const Char_t *contname, const Char_t *step, Bool_t useMC = kFALSE, Double_t externalWeight = 1.) const;
+  void FillCorrelationMatrix(THnSparseF *matrix) const;
+  
+  void SetSignalCuts(AliHFEsignalCuts *signal) { fSignal = signal; }
+  void SetWeightFactors(TH3F *weightFactors);
+  void SetWeightFactorsFunction(TF3*weightFactorsFunction);
+  
+  struct AliHFEvariable : public TNamed{
+    public:
+      AliHFEvariable();
+      AliHFEvariable(const Char_t *name, const Char_t *title, UInt_t fCode, UInt_t nBins, Double_t min, Double_t max, Bool_t isLogarithmic = kFALSE);
+      AliHFEvariable(const AliHFEvariable &ref);
+      AliHFEvariable &operator=(const AliHFEvariable &ref);
+      ~AliHFEvariable(){}
+
+      UInt_t GetVarCode() const { return fCode; }
+      UInt_t GetNumberOfBins() const { return fNBins; }
+      Double_t GetMinimum() const { return fMin; }
+      Double_t GetMaximum() const { return fMax; } 
+      Int_t IsLogarithmic() const { return fIsLogarithmic; }
+    private:
+      UInt_t    fCode;              // Unique variable code
+      UInt_t    fNBins;             // Number of bins
+      Double_t  fMin;               // Minimum
+      Double_t  fMax;               // Maximum
+      Bool_t    fIsLogarithmic;     // Logarithmic binning
+
+      ClassDef(AliHFEvarManager::AliHFEvariable, 1) // HFE variable definition
+  };
+protected:
+  Double_t GetValue(AliVParticle *track, UInt_t code, Float_t centrality = 99.0, Int_t aprioriPID = -1) const;
+  void FillArray(AliVParticle *track, Double_t *container, Float_t centrality = 99.0, Int_t aprioriPID = -1) const;
+  Double_t FindWeight(Double_t pt, Double_t eta, Double_t phi) const;
+
+private:
+  enum{
+    kOwner = BIT(14)
+  };
+  TObjArray *fVariables;                // Variables to process
+  Double_t *fContent;                   //! Cache values for track in classmember 
+  Double_t *fContentMC;                 //! Cache content of the asssociated MC track in class member
+  Double_t fWeightFactor;               // Cache weighting factor
+  Bool_t  fSignalTrack;                 // Signal Track
+       Bool_t  fWeighting;                   // Weighting or not for the efficiency maps
+  AliHFEsignalCuts *fSignal;            // MC Signal Definition
+       TH3F *fWeightFactors;                 // Weight factors
+       TF3  *fWeightFactorsFunction;         // Weight factors
+
+       ClassDef(AliHFEvarManager, 1)         // The variable Manager for the HFE Analysis
+};
+
+#endif /* ALIHFEVARMANAGER_H */