Update of the HFE package
authorsma <sma@f7af4fe6-9843-0410-8265-dc069ae4e863>
Mon, 12 Apr 2010 12:11:06 +0000 (12:11 +0000)
committersma <sma@f7af4fe6-9843-0410-8265-dc069ae4e863>
Mon, 12 Apr 2010 12:11:06 +0000 (12:11 +0000)
54 files changed:
PWG3/PWG3hfeLinkDef.h
PWG3/hfe/AliAnalysisTaskDCA.cxx [new file with mode: 0644]
PWG3/hfe/AliAnalysisTaskDCA.h [new file with mode: 0644]
PWG3/hfe/AliAnalysisTaskDisplacedElectrons.cxx [new file with mode: 0644]
PWG3/hfe/AliAnalysisTaskDisplacedElectrons.h [new file with mode: 0644]
PWG3/hfe/AliAnalysisTaskHFE.cxx
PWG3/hfe/AliAnalysisTaskHFE.h
PWG3/hfe/AliAnalysisTaskHFEpidQA.cxx [new file with mode: 0644]
PWG3/hfe/AliAnalysisTaskHFEpidQA.h [new file with mode: 0644]
PWG3/hfe/AliHFEV0pid.cxx [new file with mode: 0644]
PWG3/hfe/AliHFEV0pid.h [new file with mode: 0644]
PWG3/hfe/AliHFEV0pidMC.cxx [new file with mode: 0644]
PWG3/hfe/AliHFEV0pidMC.h [new file with mode: 0644]
PWG3/hfe/AliHFEcollection.cxx
PWG3/hfe/AliHFEcollection.h
PWG3/hfe/AliHFEcontainer.cxx [new file with mode: 0644]
PWG3/hfe/AliHFEcontainer.h [new file with mode: 0644]
PWG3/hfe/AliHFEcutStep.cxx [new file with mode: 0644]
PWG3/hfe/AliHFEcutStep.h [new file with mode: 0644]
PWG3/hfe/AliHFEcuts.cxx
PWG3/hfe/AliHFEcuts.h
PWG3/hfe/AliHFEdca.cxx [new file with mode: 0644]
PWG3/hfe/AliHFEdca.h [new file with mode: 0644]
PWG3/hfe/AliHFEdisplacedElectrons.cxx [new file with mode: 0644]
PWG3/hfe/AliHFEdisplacedElectrons.h [new file with mode: 0644]
PWG3/hfe/AliHFEefficiency.cxx [new file with mode: 0644]
PWG3/hfe/AliHFEefficiency.h [new file with mode: 0644]
PWG3/hfe/AliHFEelecbackground.cxx
PWG3/hfe/AliHFEelecbackground.h
PWG3/hfe/AliHFEextraCuts.cxx
PWG3/hfe/AliHFEextraCuts.h
PWG3/hfe/AliHFEmcQA.cxx
PWG3/hfe/AliHFEmcQA.h
PWG3/hfe/AliHFEpid.cxx
PWG3/hfe/AliHFEpid.h
PWG3/hfe/AliHFEpidESD.h [new file with mode: 0644]
PWG3/hfe/AliHFEpidQA.cxx [new file with mode: 0644]
PWG3/hfe/AliHFEpidQA.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.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/AliHFEtools.cxx [new file with mode: 0644]
PWG3/hfe/AliHFEtools.h [new file with mode: 0644]
PWG3/hfe/AliHFEtrackFilter.cxx [new file with mode: 0644]
PWG3/hfe/AliHFEtrackFilter.h [new file with mode: 0644]
PWG3/libPWG3hfe.pkg

index 6f796c6..6798bc8 100644 (file)
@@ -6,7 +6,10 @@
 #pragma link off all classes;
 #pragma link off all functions;
 
+#pragma link C++ class  AliHFEtools+;
 #pragma link C++ class  AliHFEcollection+;
+#pragma link C++ class  AliHFEcontainer+;
+#pragma link C++ class  AliHFEcontainer::AliHFEvarInfo+;
 #pragma link C++ class  AliHFEmcQA+;
 #pragma link C++ class  AliHFEpairs+;
 #pragma link C++ class  AliHFEsecVtxs+;
@@ -14,6 +17,9 @@
 #pragma link C++ class  AliHFEpriVtx+;
 #pragma link C++ class  AliHFEelecbackground+;
 
+#pragma link C++ class  AliHFEV0pid+;
+#pragma link C++ class  AliHFEV0pidMC+;
+#pragma link C++ class  AliHFEpidQA+;
 #pragma link C++ class  AliHFEpid+;
 #pragma link C++ class  AliHFEpidBase+;
 #pragma link C++ class  AliHFEpidITS+;
 #pragma link C++ class  AliHFEpidMC+;
 
 #pragma link C++ class  AliHFEcuts+;
+#pragma link C++ class  AliHFEcutStep+;
+#pragma link C++ class  AliHFEtrackFilter+;
 #pragma link C++ class  AliHFEextraCuts+;
+
+#pragma link C++ class  AliHFEdca+;
+#pragma link C++ class  AliAnalysisTaskDCA+;
+
 #pragma link C++ class  AliHFEpostAnalysis+;
 #pragma link C++ class  AliAnalysisTaskHFE+;
+#pragma link C++ class  AliAnalysisTaskHFEpidQA+;
+#pragma link C++ class  AliHFEefficiency+;
+
+#pragma link C++ class  AliHFEdisplacedElectrons+;
+#pragma link C++ class  AliAnalysisTaskDisplacedElectrons+;
+
+
 #endif
diff --git a/PWG3/hfe/AliAnalysisTaskDCA.cxx b/PWG3/hfe/AliAnalysisTaskDCA.cxx
new file mode 100644 (file)
index 0000000..e3cf8f2
--- /dev/null
@@ -0,0 +1,429 @@
+/**************************************************************************
+* 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.                  *
+**************************************************************************/
+//
+// The analysis task:
+// impact parameter resolution and pull study
+// for tracks which survivied the particle cuts
+// 
+// 
+// Authors:
+//  Hongyan Yang <hongyan@physi.uni-heidelberg.de>
+//  Carlo Bombonati <carlo.bombonati@cern.ch>
+//
+#include <TChain.h>
+#include <TFile.h>
+#include <TH1F.h>
+#include <TH1I.h>
+#include <TList.h>
+#include <TMath.h>
+#include <TObjArray.h>
+#include <TParticle.h>
+#include <TString.h>
+
+#include <TCanvas.h>
+
+#include "AliCFManager.h"
+#include "AliMCEvent.h"
+#include "AliESDInputHandler.h"
+#include "AliESDtrack.h"
+#include "AliAnalysisManager.h"
+#include "AliMCEventHandler.h"
+#include "AliMCParticle.h"
+
+#include "AliHFEcuts.h"
+#include "AliHFEdca.h"
+
+#include "AliAnalysisTaskDCA.h"
+
+
+//____________________________________________________________
+AliAnalysisTaskDCA::AliAnalysisTaskDCA():
+  AliAnalysisTask("Impact Parameter Resolution and Pull Analysis", "")
+  , fPlugins(0)
+  , fESD(0x0)
+  , fMC(0x0)
+  , fCuts(0x0)
+  , fCFM(0x0)
+  , fDCA(0x0)
+  , fPixelStatus(0x0)
+  , fNclustersITS(0x0)
+  , fNEvents(0x0)
+  , fResidualList(0x0)
+  , fPullList(0x0)
+  , fOutput(0x0)
+{
+  //
+  // Dummy constructor
+  //
+  DefineInput(0, TChain::Class());
+  DefineOutput(0, TH1I::Class());   // event
+  DefineOutput(1, TList::Class());  // output
+
+  SetHasMCData();
+
+}
+
+//____________________________________________________________
+AliAnalysisTaskDCA::AliAnalysisTaskDCA(const char * name):
+  AliAnalysisTask(name, "")
+  , fPlugins(0)
+  , fESD(0x0)
+  , fMC(0x0)
+  , fCuts(0x0)
+  , fCFM(0x0)
+  , fDCA(0x0)
+  , fPixelStatus(0x0)
+  , fNclustersITS(0x0)
+  , fNEvents(0x0)
+  , fResidualList(0x0)
+  , fPullList(0x0)
+  , fOutput(0x0)
+{
+  //
+  // Default constructor
+  //
+  DefineInput(0, TChain::Class());
+  DefineOutput(0, TH1I::Class());
+  DefineOutput(1, TList::Class());
+
+  SetHasMCData();
+}
+
+//____________________________________________________________
+AliAnalysisTaskDCA::AliAnalysisTaskDCA(const AliAnalysisTaskDCA &ref):
+  AliAnalysisTask(ref)
+  , fPlugins(ref.fPlugins)
+  , fESD(ref.fESD)
+  , fMC(ref.fMC)
+  , fCuts(ref.fCuts)
+  , fCFM(ref.fCFM)
+  , fDCA(ref.fDCA)
+  , fPixelStatus(ref.fPixelStatus)
+  , fNclustersITS(ref.fNclustersITS)
+  , fNEvents(ref.fNEvents)
+  , fResidualList(ref.fResidualList)
+  , fPullList(ref.fPullList)
+  , fOutput(ref.fOutput)
+{
+  //
+  // Copy Constructor
+  //
+}
+
+//____________________________________________________________
+AliAnalysisTaskDCA &AliAnalysisTaskDCA::operator=(const AliAnalysisTaskDCA &ref){
+  //
+  // Assignment operator
+  //
+  if(this == &ref) return *this;
+  AliAnalysisTask::operator=(ref);
+  fPlugins = ref.fPlugins;
+  fESD = ref.fESD;
+  fMC = ref.fMC;
+  fCuts = ref.fCuts;
+  fCFM = ref.fCFM;
+  fDCA = ref.fDCA;
+  fPixelStatus = ref.fPixelStatus;
+  fNclustersITS = ref.fNclustersITS;
+  fNEvents = ref.fNEvents;
+  fOutput = ref.fOutput;
+  fResidualList = ref.fResidualList;
+  fPullList = ref.fPullList;
+
+  return *this;
+}
+
+//____________________________________________________________
+AliAnalysisTaskDCA::~AliAnalysisTaskDCA(){
+  //
+  // Destructor
+  //
+
+  if(fESD) delete fESD;
+  if(fMC) delete fMC;
+
+  if(fCFM) delete fCFM;
+
+  if(fDCA) delete fDCA;  
+
+  if(fOutput){ 
+    fOutput->Clear();
+    delete fOutput;
+  }
+  
+  if(fResidualList){ 
+    fResidualList->Clear();
+    delete fResidualList;
+  }
+
+  if(fPullList){ 
+    fPullList->Clear();
+    delete fPullList;
+  }
+  
+  if(fNEvents) delete fNEvents;
+}
+
+//____________________________________________________________
+void AliAnalysisTaskDCA::ConnectInputData(Option_t *){
+  //
+  // Connecting the input
+  
+  AliESDInputHandler *esdH = dynamic_cast<AliESDInputHandler *>(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler());
+  if(!esdH){      
+    AliError("No ESD input handler");
+    return;
+  } else {
+    fESD = esdH->GetEvent();
+  }
+  AliMCEventHandler *mcH = dynamic_cast<AliMCEventHandler *>(AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler());
+  if(!mcH){       
+    AliError("No MC truth handler");
+    return;
+  } else {
+    fMC = mcH->MCEvent();
+  }
+}
+
+//____________________________________________________________
+void AliAnalysisTaskDCA::CreateOutputObjects(){
+  // create output objects
+  // fNEvents
+  // residual and pull
+
+  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
+  if(!fOutput) fOutput = new TList;
+  // Initialize correction Framework and Cuts
+  fCFM = new AliCFManager;
+  MakeParticleContainer();
+  // Temporary fix: Initialize particle cuts with 0x0
+  for(Int_t istep = 0; istep < fCFM->GetParticleContainer()->GetNStep(); istep++)
+    fCFM->SetParticleCutsList(istep, 0x0);
+  if(!fCuts){
+    AliWarning("Cuts not available. Default cuts will be used");
+    fCuts = new AliHFEcuts;
+    fCuts->CreateStandardCuts();
+  }
+  
+  fCuts->SetCutITSpixel(fPixelStatus);
+  fCuts->Initialize(fCFM);
+  
+
+  // dca study----------------------------------
+  if(!fDCA) fDCA = new AliHFEdca;
+  if(!fResidualList) fResidualList = new TList();
+  if(!fPullList) fPullList = new TList();
+
+  fDCA->CreateHistogramsResidual(fResidualList);
+  fDCA->CreateHistogramsPull(fPullList);
+  
+  // add output objects to the List
+  fOutput->AddAt(fResidualList,0);
+  fOutput->AddAt(fPullList,1);
+
+}
+
+//____________________________________________________________
+void AliAnalysisTaskDCA::Exec(Option_t *){
+  //
+  // Run the analysis
+  // 
+
+  AliDebug(3, "Processing ESD events");
+
+  if(!fESD){
+    AliError("No ESD Event");
+    return;
+  }
+  if(!fMC){
+    AliError("No MC Event");
+    return;
+  }
+  if(!fCuts){
+    AliError("HFE cuts not available");
+    return;
+  }
+
+  //
+  // Loop ESD
+  //
+  AliESDtrack *track = 0x0;  
+  fCFM->SetRecEventInfo(fESD);
+  // event cut level
+  if(!fCFM->CheckEventCuts(AliHFEcuts::kEventStepReconstructed, fESD)) return;
+
+  for(Int_t itrack = 0; itrack < fESD->GetNumberOfTracks(); itrack++){
+
+    track = fESD->GetTrack(itrack);
+
+    // RecPrim: primary cuts
+    if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepRecPrim, track)) continue;
+    // RecKine: ITSTPC cuts  
+    if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepRecKineITSTPC, track)) continue;
+    // HFEcuts: ITS layers cuts
+    if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepHFEcutsITS, track)) continue;
+    
+    if(track->GetITSclusters(0)<=fNclustersITS) continue;  // require 6 hits on all pixel layers
+
+    if(GetPlugin(kImpactPar)) {
+      //      Printf("analysis on impact parameter is ON");
+      fDCA->FillHistograms(fESD, track, fMC);
+    }   
+    
+  }  
+  fNEvents->Fill(1);
+  
+  PostData(0, fNEvents);
+  PostData(1, fOutput);
+}
+
+//____________________________________________________________
+void AliAnalysisTaskDCA::Terminate(Option_t *){
+  //
+  // Terminate not implemented at the moment
+  //  
+  
+  if(GetPlugin(kPostProcess)){
+    fOutput = dynamic_cast<TList *>(GetOutputData(1));
+    if(!fOutput){
+      AliError("Results not available");
+      return;
+    }
+    PostProcess();
+  }
+  
+}
+
+
+//____________________________________________________________
+void AliAnalysisTaskDCA::Load(TString filename){
+  // no need for postprocessing for the moment
+  TFile *input = TFile::Open(filename.Data());
+  if(!input || input->IsZombie()){
+    AliError("Cannot read file");
+    return;
+  }
+
+  /* 
+  TH1 *htmp = dynamic_cast<TH1I *>(input->Get("nEvents"));
+  if(htmp)
+    fNEvents = dynamic_cast<TH1I *>(htmp->Clone());
+  else
+    AliError("Event Counter histogram not found"); 
+  */
+  input->Close();
+  delete input;
+  
+  
+}
+
+//____________________________________________________________
+void AliAnalysisTaskDCA::PostProcess(){
+  // do post processing
+  // should do fitting here for dca resolution
+  // moved to an external macro to do the job
+  
+  Load("impactPar.root");
+  TCanvas *c1 = new TCanvas("c1", "number of analyzed events", 300, 400);
+  fNEvents->Draw();
+  c1->SaveAs("temp.png");
+}
+
+
+
+
+//____________________________________________________________
+void AliAnalysisTaskDCA::PrintStatus() const {
+  
+  //
+  // Print Analysis status
+  //
+  printf("\n\tAnalysis Settings\n\t========================================\n");
+  printf("\timpact parameter analysis is %s\n", GetPlugin(kImpactPar)?"ON":"OFF");
+  printf("\tcuts: %s\n", (fCuts != NULL) ? "YES" : "NO");
+  printf("\t ");
+  printf("\n");
+}
+
+//__________________________________________                                                  
+void AliAnalysisTaskDCA::SwitchOnPlugin(Int_t plug){
+  //                                            
+  // Switch on Plugin          
+  // Available:                                  
+  //  - analyze impact parameter
+  //  - Post Processing                                                                      
+  
+  switch(plug){
+  case kImpactPar: 
+    SETBIT(fPlugins, plug); 
+    break;
+  case kPostProcess: 
+    SETBIT(fPlugins, plug); 
+    break;
+  default: 
+    AliError("Unknown Plugin");
+  };
+}
+
+
+//____________________________________________________________
+void AliAnalysisTaskDCA::MakeParticleContainer(){
+  //
+  // Create the particle container (borrowed from AliAnalysisTaskHFE)
+  //
+  const Int_t kNvar   = 3 ; //number of variables on the grid:pt,eta, phi
+  const Double_t kPtmin = 0.1, kPtmax = 10.;
+  const Double_t kEtamin = -0.9, kEtamax = 0.9;
+  const Double_t kPhimin = 0., kPhimax = 2. * TMath::Pi();
+
+  //arrays for the number of bins in each dimension
+  Int_t iBin[kNvar];
+  iBin[0] = 40; //bins in pt
+  iBin[1] =  8; //bins in eta 
+  iBin[2] = 18; // bins in phi
+
+  //arrays for lower bounds :
+  Double_t* binEdges[kNvar];
+  for(Int_t ivar = 0; ivar < kNvar; ivar++)
+    binEdges[ivar] = new Double_t[iBin[ivar] + 1];
+
+  //values for bin lower bounds
+  for(Int_t i=0; i<=iBin[0]; i++) binEdges[0][i]=(Double_t)TMath::Power(10,TMath::Log10(kPtmin) + (TMath::Log10(kPtmax)-TMath::Log10(kPtmin))/iBin[0]*(Double_t)i);  
+  for(Int_t i=0; i<=iBin[1]; i++) binEdges[1][i]=(Double_t)kEtamin  + (kEtamax-kEtamin)/iBin[1]*(Double_t)i;
+  for(Int_t i=0; i<=iBin[2]; i++) binEdges[2][i]=(Double_t)kPhimin  + (kPhimax-kPhimin)/iBin[2]*(Double_t)i;
+
+  //one "container" for MC
+  AliCFContainer* container = new AliCFContainer("container","container for tracks", (AliHFEcuts::kNcutStepsTrack + 1 + 2*(AliHFEcuts::kNcutStepsESDtrack + 1)), kNvar, iBin);
+
+  //setting the bin limits
+  for(Int_t ivar = 0; ivar < kNvar; ivar++)
+    container -> SetBinLimits(ivar, binEdges[ivar]);
+  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];
+  }
+
+
+  // add more containers for correction purpose
+
+
+}
diff --git a/PWG3/hfe/AliAnalysisTaskDCA.h b/PWG3/hfe/AliAnalysisTaskDCA.h
new file mode 100644 (file)
index 0000000..e6c2b0a
--- /dev/null
@@ -0,0 +1,108 @@
+/**************************************************************************
+* 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 impact parameter (DCA) analysis
+// study DCA in rphi (xy) and z: resolution and pull 
+// For further information see implementation file
+
+
+#ifndef ALIANALYSISTASKDCA_H
+#define ALIANALYSISTASKDCA_H
+
+#ifndef ALIANALYSISTASK_H
+#include "AliAnalysisTask.h"
+#endif
+
+class TH1I; 
+class TH1F; 
+class TList;
+class AliLog;
+
+class AliCFManager;
+class AliESDEvent;
+class AliESDtrackCuts;
+class AliMCEvent;
+class AliVParticle;
+
+class AliHFEpid;
+class AliHFEcuts;
+class AliHFEextraCuts;
+
+class AliAnalysisTaskDCA : public AliAnalysisTask{
+ public:
+
+  typedef enum{
+    kPostProcess = 0,
+    kImpactPar = 1
+  }Switches_t;
+
+  enum{
+    kHasMCdata = BIT(19),
+    kAODanalysis = BIT(20)
+  };
+  
+  AliAnalysisTaskDCA();
+  AliAnalysisTaskDCA(const char * name);
+  AliAnalysisTaskDCA(const AliAnalysisTaskDCA &ref);
+  AliAnalysisTaskDCA& operator=(const AliAnalysisTaskDCA &ref);
+  virtual ~AliAnalysisTaskDCA();
+  
+  virtual void ConnectInputData(Option_t *);
+  virtual void CreateOutputObjects();
+  virtual void Exec(Option_t *);
+  virtual void Terminate(Option_t *);
+
+
+  void PrintStatus() const;
+  void Load(TString filename = "impactPar.root");
+  void PostProcess();
+  void SetHFECuts(AliHFEcuts * const cuts) { fCuts = cuts; };
+
+  void SetPixelStatus(Int_t pixelStatus){ fPixelStatus = pixelStatus;};
+  void SetNclustersITS(Int_t nITSclusters){ fNclustersITS = nITSclusters;};
+  
+  Bool_t GetPlugin(Int_t plug) const { return TESTBIT(fPlugins, plug); };
+  void SwitchOnPlugin(Int_t plug);
+  Bool_t HasMCData() const { return TestBit(kHasMCdata); }
+  void SetHasMCData(Bool_t hasMC = kTRUE) { SetBit(kHasMCdata, hasMC); };
+  void SetAODAnalysis() { SetBit(kAODanalysis, kTRUE); };
+  void SetESDAnalysis() { SetBit(kAODanalysis, kFALSE); };
+
+
+ private:
+
+  void MakeParticleContainer();
+  UShort_t fPlugins;                    // Enabled Plugins                                    
+  AliESDEvent *fESD;                    //! The ESD Event
+  AliMCEvent *fMC;                      //! The MC Event
+
+  AliHFEcuts *fCuts;                    // Cut Collection
+  AliCFManager *fCFM;                   //! Correction Framework Manager
+  AliHFEdca *fDCA;                      // fDCA 
+  
+  
+  Int_t fPixelStatus;                      // pixel layer
+  Int_t fNclustersITS;                    // ITS clusters
+                                               
+  TH1I *fNEvents;                       //! counter for the number of Events
+  TList *fResidualList;                 //! histograms for the residuals 
+  TList *fPullList;                     //! histograms for the pull
+  TList *fOutput;                       //! Container for Task Output
+
+  ClassDef(AliAnalysisTaskDCA, 1);      // The DCA Analysis Task
+};
+#endif
+
diff --git a/PWG3/hfe/AliAnalysisTaskDisplacedElectrons.cxx b/PWG3/hfe/AliAnalysisTaskDisplacedElectrons.cxx
new file mode 100644 (file)
index 0000000..1721ab6
--- /dev/null
@@ -0,0 +1,672 @@
+/**************************************************************************
+* 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.                  *
+**************************************************************************/
+//
+// The analysis task:
+// study displaced electrons from beauty and charm 
+// with cut on impact parameters in various pT bins
+// 
+// 
+// Authors:
+//  Hongyan Yang <hongyan@physi.uni-heidelberg.de>
+//
+
+#include <TChain.h>
+#include <TFile.h>
+#include <TH1F.h>
+#include <TH1I.h>
+#include "AliLog.h"
+
+#include <TList.h>
+#include <TMath.h>
+#include <TObjArray.h>
+#include <TParticle.h>
+#include <TString.h>
+
+#include <TCanvas.h>
+
+#include "AliCFManager.h"
+#include "AliMCEvent.h"
+#include "AliMCEventHandler.h"
+#include "AliESDEvent.h"
+#include "AliESDInputHandler.h"
+#include "AliESDtrack.h"
+#include "AliAnalysisManager.h"
+#include "AliMCParticle.h"
+
+
+#include "AliHFEpid.h"
+#include "AliHFEcuts.h"
+#include "AliHFEdisplacedElectrons.h"
+
+#include "AliAnalysisTaskDisplacedElectrons.h"
+
+
+//____________________________________________________________
+AliAnalysisTaskDisplacedElectrons::AliAnalysisTaskDisplacedElectrons():
+  AliAnalysisTaskSE("Task for displaced electron study")
+  , fDebugLevel(0)
+  , fPIDdetectors("")
+  , fPIDstrategy(0)
+  , fPlugins(0)
+  , fESD(0x0)
+  , fMC(0x0)
+  , fCuts(0x0)
+  , fPID(0x0)
+  , fCFM(0x0)
+  , fNEvents(0x0)
+  , fElectronsPt(0x0)
+  , fOutput(0x0)
+  , fCorrection(0x0)
+  , fDisplacedElectrons(0x0)
+  , fHistDisplacedElectrons(0x0)
+{
+  //
+  // Dummy constructor
+  //
+  DefineInput(0, TChain::Class());
+  DefineOutput(2, TList::Class());  // output
+  DefineOutput(1, TList::Class());  // output
+  
+  SetHasMCData();
+
+  // Initialize pid
+  fPID = new AliHFEpid;
+  
+
+}
+
+//____________________________________________________________
+AliAnalysisTaskDisplacedElectrons::AliAnalysisTaskDisplacedElectrons(const char * name):
+  AliAnalysisTaskSE(name)
+  , fDebugLevel(0)
+  , fPIDdetectors("")
+  , fPIDstrategy(0)
+  , fPlugins(0)
+  , fESD(0x0)
+  , fMC(0x0)
+  , fCuts(0x0)
+  , fPID(0x0)
+  , fCFM(0x0)
+  , fNEvents(0x0)
+  , fElectronsPt(0x0)
+  , fOutput(0x0)
+  , fCorrection(0x0)
+  , fDisplacedElectrons(0x0)
+  , fHistDisplacedElectrons(0x0)
+{
+  //
+  // Default constructor
+  //
+  DefineInput(0, TChain::Class());
+  DefineOutput(2, TList::Class());
+  DefineOutput(1, TList::Class());
+
+  SetHasMCData();
+}
+
+//____________________________________________________________
+AliAnalysisTaskDisplacedElectrons::AliAnalysisTaskDisplacedElectrons(const AliAnalysisTaskDisplacedElectrons &ref):
+  AliAnalysisTaskSE(ref)
+  , fDebugLevel(ref.fDebugLevel)
+  , fPIDdetectors(ref.fPIDdetectors)
+  , fPIDstrategy(ref.fPIDstrategy)
+  , fPlugins(ref.fPlugins)
+  , fESD(ref.fESD)
+  , fMC(ref.fMC)
+  , fCuts(ref.fCuts)
+  , fPID(ref.fPID)
+  , fCFM(ref.fCFM)
+  , fNEvents(ref.fNEvents)
+  , fElectronsPt(ref.fElectronsPt)
+  , fOutput(ref.fOutput)
+  , fCorrection(ref.fCorrection)
+  , fDisplacedElectrons(ref.fDisplacedElectrons)
+  , fHistDisplacedElectrons(ref.fHistDisplacedElectrons)
+{
+  //
+  // Copy Constructor
+  //
+}
+
+//____________________________________________________________
+AliAnalysisTaskDisplacedElectrons &AliAnalysisTaskDisplacedElectrons::operator=(const AliAnalysisTaskDisplacedElectrons &ref){
+  //
+  // Assignment operator
+  //
+  if(this == &ref) return *this;
+  AliAnalysisTask::operator=(ref);
+  fDebugLevel = ref.fDebugLevel;
+  fPIDdetectors = ref.fPIDdetectors;
+  fPIDstrategy = ref.fPIDstrategy;
+  fPlugins = ref.fPlugins;
+  fESD = ref.fESD;
+  fMC = ref.fMC;
+  fPID = ref.fPID;
+  fCuts = ref.fCuts;
+  fCFM = ref.fCFM;
+  fNEvents = ref.fNEvents;
+  fOutput = ref.fOutput;
+  fCorrection = ref.fCorrection;
+  fDisplacedElectrons = ref.fDisplacedElectrons;
+  fHistDisplacedElectrons = ref.fHistDisplacedElectrons;
+
+  return *this;
+}
+
+//____________________________________________________________
+AliAnalysisTaskDisplacedElectrons::~AliAnalysisTaskDisplacedElectrons(){
+  //
+  // Destructor
+  //
+
+  if(fPID) delete fPID;
+  
+  if(fESD) delete fESD;
+  if(fMC) delete fMC;
+
+  if(fCFM) delete fCFM;
+
+  if(fNEvents) delete fNEvents;
+  
+  if(fElectronsPt) delete fElectronsPt;
+
+  if(fOutput){ 
+    fOutput->Clear();
+    delete fOutput;
+  }
+  
+
+  if(fCorrection){
+    fCorrection->Clear();
+    delete fCorrection;
+  }
+  if(fDisplacedElectrons) delete fDisplacedElectrons;  
+
+  if(fHistDisplacedElectrons){ 
+    fHistDisplacedElectrons->Clear();  
+    delete fHistDisplacedElectrons;  
+  }
+   
+  
+}
+
+//____________________________________________________________
+void AliAnalysisTaskDisplacedElectrons::UserCreateOutputObjects(){
+  // create output objects
+  // fNEvents
+  // MC and Data containers
+
+  fNEvents = new TH1I("nEvents", "Number of Events in the Analysis", 2, 0, 2); 
+  const Int_t nBins = 14;
+  const Float_t ptBins[nBins] = {0.0,0.5,1.0,1.5,2.0,2.5,3.0,4.0,5.0,7.0,9.0,12.0,16.0,20.0};
+  fElectronsPt = new TH1F("esdPt", "p_{T} distribution of identified electrons (HFEpid);p_{T} (GeV/c);dN/dp_{T};", nBins-1, ptBins); 
+  if(!fOutput) fOutput = new TList;
+  fOutput->SetName("results");
+  fOutput->AddAt(fElectronsPt,0);
+  fOutput->AddAt(fNEvents,1);
+  // Initialize correction Framework and Cuts
+  fCFM = new AliCFManager;
+  MakeEventContainer();
+  MakeParticleContainer();
+  if(!fCorrection) fCorrection = new TList();
+  fCorrection->SetName("corrections");
+  fCorrection->AddAt(fCFM->GetEventContainer(), 0);
+  fCorrection->AddAt(fCFM->GetParticleContainer(), 1);
+  fCorrection->Print();
+
+  // Temporary fix: Initialize particle cuts with 0x0
+  for(Int_t istep = 0; istep < fCFM->GetEventContainer()->GetNStep(); istep++)
+    fCFM->SetEventCutsList(istep, 0x0);
+  for(Int_t istep = 0; istep < fCFM->GetParticleContainer()->GetNStep(); istep++)
+    fCFM->SetParticleCutsList(istep, 0x0);
+  if(!fCuts){
+    AliWarning("Cuts not available. Default cuts will be used");
+    fCuts = new AliHFEcuts;
+    fCuts->CreateStandardCuts();
+
+  }
+  
+  fCuts->SetCutITSpixel(AliHFEextraCuts::kBoth);
+  
+  fCuts->Initialize(fCFM);
+    
+  fPID->SetHasMCData(HasMCData());
+  if(!fPIDdetectors.Length() && ! fPIDstrategy) AddPIDdetector("TPC");
+  if(fPIDstrategy)
+    fPID->InitializePID(Form("Strategy%d", fPIDstrategy));
+  else
+    fPID->InitializePID(fPIDdetectors.Data());     // Only restrictions to TPC allowed 
+
+  // displaced electron study----------------------------------
+  if(GetPlugin(kDisplacedElectrons)){
+    
+    fDisplacedElectrons = new AliHFEdisplacedElectrons;
+    fDisplacedElectrons->SetDebugLevel(fDebugLevel);
+    fDisplacedElectrons->SetHasMCData(HasMCData());
+    
+    if(!fHistDisplacedElectrons) fHistDisplacedElectrons = new TList();
+    
+    fDisplacedElectrons->CreateOutputs(fHistDisplacedElectrons);
+    
+    fOutput->AddAt(fHistDisplacedElectrons, 2);
+  }
+
+
+}
+
+
+
+//____________________________________________________________
+void AliAnalysisTaskDisplacedElectrons::UserExec(Option_t *){
+  //
+  // Run the analysis
+  // 
+
+  AliESDInputHandler *esdH = dynamic_cast<AliESDInputHandler *>(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler());
+  if(!esdH){      
+    AliError("No ESD input handler");
+    return;
+  } else {
+    fESD = esdH->GetEvent();
+  }
+  AliMCEventHandler *mcH = dynamic_cast<AliMCEventHandler *>(AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler());
+  if(!mcH){       
+    AliError("No MC truth handler");
+    return;
+  } else {
+    fMC = mcH->MCEvent();
+  }
+  
+  if(fDebugLevel>=5)AliInfo("Processing ESD events");
+  if(!fESD){
+    AliError("No ESD Event");
+    return;
+  }
+  
+  if(HasMCData()){
+    if(fDebugLevel>=5)AliInfo(Form("MC Event: %p", fMC));
+    if(!fMC){
+      AliError("No MC Event, but MC Data required");
+      return;
+    }
+  }
+  if(!fCuts){
+    AliError("HFE cuts not available");
+    return;
+  }
+  
+  // process data: ESD tracks with MC information
+  Double_t container[8];   // container for the output in THnSparse
+  memset(container, 0, sizeof(Double_t) * 8);
+  
+  Bool_t signal = kTRUE;
+  Bool_t alreadyseen = kFALSE;
+  LabelContainer cont(fESD->GetNumberOfTracks());
+
+  Int_t nElectrons=0;
+  
+  AliESDtrack *track = 0x0;    
+  
+  Double_t nContrib = fESD->GetPrimaryVertex()->GetNContributors();
+  if(!fCFM->CheckEventCuts(AliHFEcuts::kEventStepReconstructed, fESD)) return;
+  if(GetPlugin(kCorrection)){
+    fCFM->GetEventContainer()->Fill(&nContrib, AliHFEcuts::kEventStepReconstructed);
+  }
+  fCFM->SetRecEventInfo(fESD);
+
+  for(Int_t itrack = 0; itrack < fESD->GetNumberOfTracks(); itrack++){
+    track = fESD->GetTrack(itrack);
+    
+    //
+    //  track quality cut: 1st step: ITS and TPC cut; 2nd step: Rec prim; 3rd step: hfe cut on ITS pixel layer
+    //
+    // require within rapidity range +/-0.9
+
+    //   if((TMath::Abs(track->Eta()))>0.9) continue;
+
+       
+    if(GetPlugin(kDisplacedElectrons)) {
+
+      // 1st cut
+      // RecKine: ITSTPC cuts : ITS & TPC refit, covmatrix: (2, 2, 0.5, 0.5, 2); min_tpccls: 50, chi2_tpccls: 3.5
+      if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepRecKineITSTPC, track)){
+       signal = kFALSE;
+       continue;
+      }
+      
+      container[0] = track->Pt();
+      container[1] = track->Eta();
+      container[2] = track->Phi();
+      container[3] = track->Charge();
+      
+      AliStack *stack = fMC->Stack();
+      if(!stack) continue;     
+      
+      AliMCParticle *mctrack = NULL;
+      if(HasMCData() ){ 
+       mctrack = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(TMath::Abs(track->GetLabel())));
+       if(!mctrack)  continue;                 
+       
+       container[4] = mctrack->Pt();
+       container[5] = mctrack->Eta();
+       container[6] = mctrack->Phi();
+       container[7] = mctrack->Charge();
+
+       //      if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepMCGenerated, mctrack)) signal = kFALSE;
+       if(TMath::Abs(mctrack->Eta())>0.9) {
+         signal = kFALSE;
+         continue;
+       }  // cut on kinematics
+
+      }  // has MC data
+
+      
+      if(signal && GetPlugin(kCorrection)){
+       alreadyseen = cont.Find(TMath::Abs(track->GetLabel()));  // double counted track
+       cont.Append(TMath::Abs(track->GetLabel()));
+       fCFM->GetParticleContainer()->Fill(&container[4], AliHFEcuts::kStepRecKineITSTPC);
+       fCFM->GetParticleContainer()->Fill(&container[0], AliHFEcuts::kStepRecKineITSTPC + 2*AliHFEcuts::kNcutStepsESDtrack);
+       if(alreadyseen) 
+         fCFM->GetParticleContainer()->Fill(&container[4], AliHFEcuts::kStepRecKineITSTPC + AliHFEcuts::kNcutStepsESDtrack);
+       
+      }  // fill correction --- 1st
+    
+      // second cut
+      // RecPrim: cut on track quality : DCA to vertex max: 3cm and 10cm; reject kink daughters
+      if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepRecPrim, track)) { 
+       signal = kFALSE;
+       continue;
+      }
+
+      if(signal) {
+       alreadyseen = cont.Find(TMath::Abs(track->GetLabel()));
+       cont.Append(TMath::Abs(track->GetLabel()));
+       
+       fCFM->GetParticleContainer()->Fill(&container[4], AliHFEcuts::kStepRecPrim);
+       fCFM->GetParticleContainer()->Fill(&container[0], AliHFEcuts::kStepRecPrim + 2*AliHFEcuts::kNcutStepsESDtrack);
+       if(alreadyseen) {
+         fCFM->GetParticleContainer()->Fill(&container[4], AliHFEcuts::kStepRecPrim + AliHFEcuts::kNcutStepsESDtrack);
+       }
+      }
+      
+      //  third cut
+      // HFEcuts: ITS layers cuts: ITS pixel layer: kFirst, kSecond, kBoth, kNone or kAny
+      if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepHFEcutsITS, track)){
+       signal = kFALSE;
+       continue;
+      }
+
+      if(signal) {
+       alreadyseen = cont.Find(TMath::Abs(track->GetLabel()));
+       cont.Append(TMath::Abs(track->GetLabel()));
+       
+       fCFM->GetParticleContainer()->Fill(&container[4], AliHFEcuts::kStepHFEcutsITS);
+       fCFM->GetParticleContainer()->Fill(&container[0], AliHFEcuts::kStepHFEcutsITS + 2*AliHFEcuts::kNcutStepsESDtrack);
+       if(alreadyseen) {
+         fCFM->GetParticleContainer()->Fill(&container[4], AliHFEcuts::kStepHFEcutsITS + AliHFEcuts::kNcutStepsESDtrack);
+       }
+      }
+      
+      fDisplacedElectrons->FillMCOutput(fESD, track, stack);
+      
+      // track accepted, do PID --> only electron candidate will be processed
+      AliHFEpidObject hfetrack;
+      hfetrack.fAnalysisType = AliHFEpidObject::kESDanalysis;
+      hfetrack.fRecTrack = track;
+      if((fPID->IsSelected(&hfetrack)==kTRUE))
+       if(fDebugLevel>=10)
+         AliInfo(Form("ESD info: this particle is %s identified as electron by HFEpid method \n", (fPID->IsSelected(&hfetrack)==kTRUE)?" ":" NOT "));
+      if(!fPID->IsSelected(&hfetrack))   continue;
+      
+         // Fill Containers
+
+      nElectrons++;
+
+      fElectronsPt->Fill(track->Pt());
+
+      if(signal) {
+       fCFM->GetParticleContainer()->Fill(container, AliHFEcuts::kStepPID + 2*AliHFEcuts::kNcutStepsESDtrack);
+       fCFM->GetParticleContainer()->Fill(&container[4], AliHFEcuts::kStepPID);
+       if(alreadyseen) {
+         fCFM->GetParticleContainer()->Fill(&container[4], (AliHFEcuts::kStepPID + (AliHFEcuts::kNcutStepsESDtrack)));
+       }
+      }
+      
+      fDisplacedElectrons->FillESDOutput(fESD, track);
+      
+    } // analyze displaced electrons plugin switched on
+  } // track loop  
+
+  if(fDebugLevel>=5)
+    AliInfo(Form("ESD info: number of electrons found in this event: %d\n", nElectrons));
+
+
+  fNEvents->Fill(1);
+  
+  PostData(1, fOutput);
+  PostData(2, fCorrection);
+
+}
+
+//____________________________________________________________
+void AliAnalysisTaskDisplacedElectrons::Terminate(Option_t *){
+  //
+  // Terminate not implemented at the moment
+  //  
+  
+  if(GetPlugin(kDisplacedElectrons))
+    {
+      
+      fOutput = dynamic_cast<TList *>(GetOutputData(1));
+      fCorrection= dynamic_cast<TList *>(GetOutputData(2));
+
+      if(!fOutput || !fCorrection){
+       if(!fCorrection) AliError("correction list not available\n");
+       if(!fOutput) AliError("output list not available\n");
+       
+       return;
+      }
+
+      fOutput->Print();
+      fCorrection->Print();
+      
+      AliInfo("analysis done!\n");
+      
+    }
+}
+
+
+
+
+
+
+//____________________________________________________________
+void AliAnalysisTaskDisplacedElectrons::PrintStatus() const {
+  
+  //
+  // Print Analysis status
+  //
+  printf("\n\tAnalysis Settings\n\t========================================\n");
+  printf("\tdisplaced electrons' analysis is %s\n", GetPlugin(kDisplacedElectrons)?"ON":"OFF");
+  printf("\tcorrection container  is %s\n", GetPlugin(kCorrection)?"ON":"OFF");
+  printf("\tpost processing  is %s\n", GetPlugin(kPostProcess)?"ON":"OFF");
+  printf("\tcuts: %s\n", (fCuts != NULL) ? "YES" : "NO");
+  printf("\t ");
+  printf("\n");
+}
+
+//__________________________________________                                                  
+void AliAnalysisTaskDisplacedElectrons::SwitchOnPlugin(Int_t plug){
+  //                                            
+  // Switch on Plugin          
+  // Available:                                  
+  //  - analyze impact parameter
+  //  - Post Processing                                                                      
+  
+  switch(plug)
+    {
+    case kDisplacedElectrons: 
+      SETBIT(fPlugins, plug); 
+      break;
+    case kPostProcess: 
+      SETBIT(fPlugins, plug); 
+      break;
+    case kCorrection:
+      SETBIT(fPlugins, plug); 
+      break;
+    default: 
+      AliError("Unknown Plugin");
+    };
+}
+
+
+//____________________________________________________________
+void AliAnalysisTaskDisplacedElectrons::MakeParticleContainer(){
+  //
+  // Create the particle container (borrowed from AliAnalysisTaskHFE)
+  //
+  const Int_t kNvar   = 4; //number of variables on the grid:pt,eta, phi
+  const Double_t kPtmin = 0.1, kPtmax = 20.;   // used for fixed pt bins
+  //  const Float_t ptBins[14] = {0.0,0.5,1.0,1.5,2.0,2.5,3.0,4.0,5.0,7.0,9.0,12.0,16.0,20.0};
+  const Double_t kEtamin = -0.9, kEtamax = 0.9;
+  const Double_t kPhimin = 0., kPhimax = 2. * TMath::Pi();
+
+  //arrays for the number of bins in each dimension
+  Int_t iBin[kNvar];
+  iBin[0] = 40; //bins in pt   // used for fixed pt bins
+  //  iBin[0] = 13; //bins in pt
+  iBin[1] =  8; //bins in eta 
+  iBin[2] = 18; // bins in phi
+  iBin[3] =  2; // bins in charge
+  
+  //arrays for lower bounds :
+  Double_t* binEdges[kNvar];
+  for(Int_t ivar = 0; ivar < kNvar; ivar++)
+    binEdges[ivar] = new Double_t[iBin[ivar] + 1];
+
+  //values for bin lower bounds
+  //  for(Int_t i=0; i<=iBin[0]; i++) binEdges[0][i]=ptBins[i];  // using variable bins
+  for(Int_t i=0; i<=iBin[0]; i++) 
+     binEdges[0][i]=(Double_t)TMath::Power(10,TMath::Log10(kPtmin) + (TMath::Log10(kPtmax)-TMath::Log10(kPtmin))/iBin[0]*(Double_t)i);   // fixed pt bin
+  for(Int_t i=0; i<=iBin[1]; i++) binEdges[1][i]=(Double_t)kEtamin  + (kEtamax-kEtamin)/iBin[1]*(Double_t)i;
+  for(Int_t i=0; i<=iBin[2]; i++) binEdges[2][i]=(Double_t)kPhimin  + (kPhimax-kPhimin)/iBin[2]*(Double_t)i;
+  for(Int_t i=0; i<=iBin[3]; i++) binEdges[3][i]=1.1*i-1.1; // Numeric precision
+  
+  //one "container" for MC
+  AliCFContainer* container = new AliCFContainer("container","container for tracks", 
+                                                (AliHFEcuts::kNcutStepsTrack + 1 + 2*(AliHFEcuts::kNcutStepsESDtrack + 1)), 
+                                                kNvar, iBin);
+
+  //setting the bin limits
+  for(Int_t ivar = 0; ivar < kNvar; ivar++)
+    container -> SetBinLimits(ivar, binEdges[ivar]);
+  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];
+  }
+
+  // add more containers
+
+
+}
+
+//____________________________________________________________
+void AliAnalysisTaskDisplacedElectrons::MakeEventContainer(){
+  //
+  // Create the event container for the correction framework and link it
+  //
+  const Int_t kNvar = 1;  // number of variables on the grid: number of tracks per event
+  const Double_t kNTrackBound[2] = {-0.5, 200.5};
+  const Int_t kNBins = 201;
+
+  AliCFContainer *evCont = new AliCFContainer("eventContainer", "Container for events", AliHFEcuts::kNcutStepsEvent, kNvar, &kNBins);
+
+  Double_t trackBins[kNBins];
+  for(Int_t ibin = 0; ibin < kNBins; ibin++) trackBins[ibin] = kNTrackBound[0] + static_cast<Double_t>(ibin);
+  evCont->SetBinLimits(0,trackBins);
+
+  fCFM->SetEventContainer(evCont);
+
+}
+
+
+
+//__________________________________________________________
+void AliAnalysisTaskDisplacedElectrons::AddPIDdetector(TString detector){
+  //
+  // Adding PID detector to the task
+  //
+  if(!fPIDdetectors.Length()) 
+    fPIDdetectors = detector;
+  else
+    fPIDdetectors += ":" + detector;
+}
+
+
+
+//____________________________________________________________
+AliAnalysisTaskDisplacedElectrons::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 AliAnalysisTaskDisplacedElectrons::LabelContainer::Append(Int_t label){
+  //
+  // Add Label to the container
+  //
+  if(fLast > fEnd) return kFALSE;
+  *fLast++ = label;
+  return kTRUE;
+}
+
+//____________________________________________________________
+Bool_t AliAnalysisTaskDisplacedElectrons::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 AliAnalysisTaskDisplacedElectrons::LabelContainer::Next()  { 
+  //
+  // Mimic iterator
+  //
+  if(fCurrent > fLast) return -1; 
+  return *fCurrent++;
+}
diff --git a/PWG3/hfe/AliAnalysisTaskDisplacedElectrons.h b/PWG3/hfe/AliAnalysisTaskDisplacedElectrons.h
new file mode 100644 (file)
index 0000000..1750e17
--- /dev/null
@@ -0,0 +1,140 @@
+/**************************************************************************
+* 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.                  *
+**************************************************************************/
+//
+// Analysis task: 
+// study displaced electrons from beauty and charm 
+// with cut on impact parameters in various pT bins
+// 
+
+
+#ifndef ALIANALYSISTASKDISPLACEDELECTRONS_H
+#define ALIANALYSISTASKDISPLACEDELECTRONS_H
+
+#ifndef ALIANALYSISTASKSE_H
+#include "AliAnalysisTaskSE.h"
+#endif
+
+#ifndef ROOT_THnSparse
+#include <THnSparse.h>
+#endif
+
+class TH1I; 
+class TH1F;
+class TList;
+class AliLog;
+
+class AliCFManager;
+class AliESDEvent;
+class AliESDtrackCuts;
+class AliMCEvent;
+class AliVParticle;
+
+class AliStack;
+
+class AliHFEpid;
+class AliHFEcuts;
+class AliHFEdisplacedElectrons;
+
+class AliAnalysisTaskDisplacedElectrons : public AliAnalysisTaskSE{
+ public:
+
+  typedef enum{
+    kPostProcess = 0,
+    kDisplacedElectrons = 1, 
+    kCorrection = 2
+  }Switches_t;
+
+  enum{
+    kHasMCdata = BIT(19),
+    kAODanalysis = BIT(20)
+  };
+  
+  AliAnalysisTaskDisplacedElectrons();
+  AliAnalysisTaskDisplacedElectrons(const char * name);
+  AliAnalysisTaskDisplacedElectrons(const AliAnalysisTaskDisplacedElectrons &ref);
+  AliAnalysisTaskDisplacedElectrons& operator=(const AliAnalysisTaskDisplacedElectrons &ref);
+  virtual ~AliAnalysisTaskDisplacedElectrons();
+  
+  virtual void UserCreateOutputObjects();
+  virtual void UserExec(Option_t *);
+  //  virtual void ConnectInputData(Option_t *);
+  virtual void Terminate(Option_t *);
+
+  void PrintStatus() const;
+  
+  Bool_t GetPlugin(Int_t plug) const { return TESTBIT(fPlugins, plug); };
+  void SwitchOnPlugin(Int_t plug);
+
+  void SetHFECuts(AliHFEcuts * const cuts) { fCuts = cuts; };
+  
+  void SetPIDdetectors(Char_t * const detectors){ fPIDdetectors = detectors; };
+  void SetPIDStrategy(UInt_t strategy) { fPIDstrategy = strategy; };
+  void SetDBLevel(UInt_t debugLevel) { fDebugLevel = debugLevel; };
+  void AddPIDdetector(TString detector); 
+  Bool_t HasMCData() const { return TestBit(kHasMCdata); };
+  void SetHasMCData(Bool_t hasMC = kTRUE) { SetBit(kHasMCdata, hasMC); };
+  
+  
+ private:
+  
+  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
+  };
+    
+  void MakeParticleContainer();
+  void MakeEventContainer();
+
+  UInt_t fDebugLevel;                   // debug level
+  
+  TString fPIDdetectors;                // Detectors for Particle Identification
+  UInt_t fPIDstrategy;                  // PID Strategy
+  
+
+  UShort_t fPlugins;                    // Enabled Plugins                                    
+  AliESDEvent *fESD;                    //! The ESD Event
+  AliMCEvent *fMC;                      //! The MC Event
+
+  AliHFEcuts *fCuts;                    // Cut Collection
+  AliHFEpid *fPID;                      // PID method
+  AliCFManager *fCFM;                   //! Correction Framework Manager
+                                               
+  TH1I *fNEvents;                       //! counter for the number of Events
+  TH1F *fElectronsPt;                       //! pt distribution of electrons (hfepid)
+  TList *fOutput;                       //! Container for this Task Output
+  TList *fCorrection;                       //! Container for correction  Output
+  AliHFEdisplacedElectrons *fDisplacedElectrons;        //! HFE displaced Electrons pointer 
+  TList *fHistDisplacedElectrons;                      //! list of outputs
+  ClassDef(AliAnalysisTaskDisplacedElectrons, 1);      // The DisplacedElectrons Analysis Task
+};
+#endif
+
index a07e6c3..5bb8956 100644 (file)
@@ -58,6 +58,7 @@
 #include "AliMCParticle.h"
 #include "AliPID.h"
 #include "AliStack.h"
+#include "AliVVertex.h"
 
 #include "AliHFEpid.h"
 #include "AliHFEcollection.h"
@@ -68,6 +69,7 @@
 #include "AliHFEsecVtxs.h"
 #include "AliHFEsecVtx.h"
 #include "AliHFEelecbackground.h"
+#include "AliHFEtools.h"
 #include "AliAnalysisTaskHFE.h"
 
 //____________________________________________________________
@@ -258,6 +260,15 @@ void AliAnalysisTaskHFE::UserCreateOutputObjects(){
   // Called once per worker
   //
   AliDebug(3, "Creating Output Objects");
+  // Automatic determination of the analysis mode
+  AliVEventHandler *inputHandler = AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler();
+  if(!TString(inputHandler->IsA()->GetName()).CompareTo("AliAODInputHandler")){
+    SetAODAnalysis();
+  } else {
+    SetESDAnalysis();
+    if(AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler())
+      SetHasMCData();
+  }
   printf("Analysis Mode: %s Analysis\n", IsAODanalysis() ? "AOD" : "ESD");
   printf("MC Data available %s\n", HasMCData() ? "Yes" : "No");
 
@@ -277,11 +288,13 @@ void AliAnalysisTaskHFE::UserCreateOutputObjects(){
   fQA->AddAt(new TProfile("pidquality", "TRD PID quality as function of momentum", 20, 0, 20), 4);
   fQA->AddAt(new TProfile("ntrdclusters", "Number of TRD clusters as function of momentum", 20, 0, 20), 5);
   fQA->AddAt(new TH1F("chi2TRD","#chi2 per TRD cluster", 20, 0, 20), 6);
+  fQA->AddAt(new TH1I("mccharge", "MC Charge", 200, -100, 100), 7);
 
   if(!fOutput) fOutput = new TList;
   // Initialize correction Framework and Cuts
   fCFM = new AliCFManager;
   MakeParticleContainer();
+  MakeEventContainer();
   // Temporary fix: Initialize particle cuts with NULL
   for(Int_t istep = 0; istep < fCFM->GetParticleContainer()->GetNStep(); istep++)
     fCFM->SetParticleCutsList(istep, NULL);
@@ -296,10 +309,11 @@ void AliAnalysisTaskHFE::UserCreateOutputObjects(){
  
   // add output objects to the List
   fOutput->AddAt(fCFM->GetParticleContainer(), 0);
-  fOutput->AddAt(fCorrelation, 1);
-  fOutput->AddAt(fPIDperformance, 2);
-  fOutput->AddAt(fSignalToBackgroundMC, 3);
-  fOutput->AddAt(fNElectronTracksEvent, 4);
+  fOutput->AddAt(fCFM->GetEventContainer(), 1);
+  fOutput->AddAt(fCorrelation, 2);
+  fOutput->AddAt(fPIDperformance, 3);
+  fOutput->AddAt(fSignalToBackgroundMC, 4);
+  fOutput->AddAt(fNElectronTracksEvent, 5);
 
   // Initialize PID
   if(IsQAOn(kPIDqa)){
@@ -360,7 +374,10 @@ void AliAnalysisTaskHFE::UserCreateOutputObjects(){
   // background----------------------------------
   if (GetPlugin(kIsElecBackGround)) {
     AliInfo("Electron BackGround Analysis on");
-    fElecBackGround = new AliHFEelecbackground;
+    if(!fElecBackGround){
+      AliWarning("ElecBackGround not available. Default elecbackground will be used");
+      fElecBackGround = new AliHFEelecbackground;
+    }
     fElecBackGround->SetHasMCData(HasMCData());
 
     if(!fHistELECBACKGROUND) fHistELECBACKGROUND = new TList();
@@ -408,7 +425,7 @@ void AliAnalysisTaskHFE::Terminate(Option_t *){
   // Terminate not implemented at the moment
   //
   if(GetPlugin(kPostProcess)){
-    fOutput = dynamic_cast<TList *>(GetOutputData(1));
+    fOutput = dynamic_cast<TList *>(GetOutputData(2));
     if(!fOutput){
       AliError("Results not available");
       return;
@@ -418,6 +435,18 @@ void AliAnalysisTaskHFE::Terminate(Option_t *){
     if(HasMCData())postanalysis.DrawMCSignal2Background();
     postanalysis.DrawEfficiency();
     postanalysis.DrawPIDperformance();
+    postanalysis.DrawCutEfficiency();
+
+    if (GetPlugin(kIsElecBackGround)) {
+      AliHFEelecbackground elecBackGround;
+      TList *oe = 0x0;
+      if(!(oe = (TList*)dynamic_cast<TList *>(fOutput->FindObject("HFEelecbackground")))){
+       return;
+      }
+      elecBackGround.Load(oe);
+      elecBackGround.Plot();
+      elecBackGround.PostProcess();      
+    }
   }
 }
 
@@ -428,37 +457,44 @@ void AliAnalysisTaskHFE::ProcessMC(){
   // In case MC QA is on also MC QA loop is done
   //
   AliDebug(3, "Processing MC Information");
+  Double_t nContrib = 0;
+  const AliVVertex *pVertex = fMCEvent->GetPrimaryVertex();
+  if(pVertex) nContrib = pVertex->GetNContributors();
+  if(!fCFM->CheckEventCuts(AliHFEcuts::kEventStepGenerated, fMCEvent)) return;
+  fCFM->GetEventContainer()->Fill(&nContrib,AliHFEcuts::kEventStepGenerated);
   Int_t nElectrons = 0;
   if(IsESDanalysis()){
     if (HasMCData() && IsQAOn(kMCqa)) {
       AliDebug(2, "Running MC QA");
 
-      fMCQA->SetStack(fMCEvent->Stack());
-      fMCQA->SetGenEventHeader(fMCEvent->GenEventHeader());
-      fMCQA->Init();
-
-      Int_t nMCTracks = fMCEvent->Stack()->GetNtrack();
-
-      // loop over all tracks for decayed electrons
-      for (Int_t igen = 0; igen < nMCTracks; igen++){
-        TParticle* mcpart = fMCEvent->Stack()->Particle(igen);
-        fMCQA->GetQuarkKine(mcpart, igen, AliHFEmcQA::kCharm);
-        fMCQA->GetQuarkKine(mcpart, igen, AliHFEmcQA::kBeauty);
-        fMCQA->GetHadronKine(mcpart, AliHFEmcQA::kCharm);
-        fMCQA->GetHadronKine(mcpart, AliHFEmcQA::kBeauty);
-        fMCQA->GetDecayedKine(mcpart, AliHFEmcQA::kCharm,  AliHFEmcQA::kElectronPDG, 0); // no accept cut
-        fMCQA->GetDecayedKine(mcpart, AliHFEmcQA::kBeauty, AliHFEmcQA::kElectronPDG, 0); // no accept cut
-        if (TMath::Abs(mcpart->Eta()) < 0.9) {
-          fMCQA->GetDecayedKine(mcpart, AliHFEmcQA::kCharm,  AliHFEmcQA::kElectronPDG, 1); // accept |eta|<0.9
-          fMCQA->GetDecayedKine(mcpart, AliHFEmcQA::kBeauty, AliHFEmcQA::kElectronPDG, 1); // accept |eta|<0.9
+      if(fMCEvent->Stack()){
+        fMCQA->SetStack(fMCEvent->Stack());
+        fMCQA->SetGenEventHeader(fMCEvent->GenEventHeader());
+        fMCQA->Init();
+
+        Int_t nMCTracks = fMCEvent->Stack()->GetNtrack();
+
+        // loop over all tracks for decayed electrons
+        for (Int_t igen = 0; igen < nMCTracks; igen++){
+          TParticle* mcpart = fMCEvent->Stack()->Particle(igen);
+          fMCQA->GetQuarkKine(mcpart, igen, AliHFEmcQA::kCharm);
+          fMCQA->GetQuarkKine(mcpart, igen, AliHFEmcQA::kBeauty);
+          fMCQA->GetHadronKine(mcpart, AliHFEmcQA::kCharm);
+          fMCQA->GetHadronKine(mcpart, AliHFEmcQA::kBeauty);
+          fMCQA->GetDecayedKine(mcpart, AliHFEmcQA::kCharm,  AliHFEmcQA::kElectronPDG, 0); // no accept cut
+          fMCQA->GetDecayedKine(mcpart, AliHFEmcQA::kBeauty, AliHFEmcQA::kElectronPDG, 0); // no accept cut
+          if (TMath::Abs(mcpart->Eta()) < 0.9) {
+            fMCQA->GetDecayedKine(mcpart, AliHFEmcQA::kCharm,  AliHFEmcQA::kElectronPDG, 1); // accept |eta|<0.9
+            fMCQA->GetDecayedKine(mcpart, AliHFEmcQA::kBeauty, AliHFEmcQA::kElectronPDG, 1); // accept |eta|<0.9
+          }
+          if (TMath::Abs(AliHFEtools::GetRapidity(mcpart)) < 0.5) {
+            fMCQA->GetDecayedKine(mcpart, AliHFEmcQA::kCharm,  AliHFEmcQA::kElectronPDG, 2); // accept |y|<0.5
+            fMCQA->GetDecayedKine(mcpart, AliHFEmcQA::kBeauty, AliHFEmcQA::kElectronPDG, 2); // accept |y|<0.5
           }
-        if (TMath::Abs(GetRapidity(mcpart)) < 0.5) {
-          fMCQA->GetDecayedKine(mcpart, AliHFEmcQA::kCharm,  AliHFEmcQA::kElectronPDG, 2); // accept |y|<0.5
-          fMCQA->GetDecayedKine(mcpart, AliHFEmcQA::kBeauty, AliHFEmcQA::kElectronPDG, 2); // accept |y|<0.5
         }
+        fMCQA->EndOfEventAna(AliHFEmcQA::kCharm);
+        fMCQA->EndOfEventAna(AliHFEmcQA::kBeauty);
       }
-      fMCQA->EndOfEventAna(AliHFEmcQA::kCharm);
-      fMCQA->EndOfEventAna(AliHFEmcQA::kBeauty);
 
     } // end of MC QA loop
     // -----------------------------------------------------------------
@@ -468,8 +504,10 @@ void AliAnalysisTaskHFE::ProcessMC(){
     fCFM->SetMCEventInfo(fInputEvent);
   }
   // Run MC loop
-  for(Int_t imc = fMCEvent->GetNumberOfTracks(); imc--;){
-    if(ProcessMCtrack(fMCEvent->GetTrack(imc))) nElectrons++;
+  AliVParticle *mctrack = NULL;
+  for(Int_t imc = 0; imc <fMCEvent->GetNumberOfTracks(); imc++){
+    if(!(mctrack = fMCEvent->GetTrack(imc))) continue;
+    if(ProcessMCtrack(mctrack)) nElectrons++;
   }
 
   // fCFM->CheckEventCuts(AliCFManager::kEvtRecCuts, fESD);
@@ -483,6 +521,9 @@ void AliAnalysisTaskHFE::ProcessESD(){
   // Loop over Tracks, filter according cut steps defined in AliHFEcuts
   //
   AliDebug(3, "Processing ESD Event");
+  Double_t nContrib = fInputEvent->GetPrimaryVertex()->GetNContributors();
+  if(!fCFM->CheckEventCuts(AliHFEcuts::kEventStepReconstructed, fInputEvent)) return;
+  fCFM->GetEventContainer()->Fill(&nContrib, AliHFEcuts::kEventStepReconstructed);
   AliESDEvent *fESD = dynamic_cast<AliESDEvent *>(fInputEvent);
   if(!fESD){
     AliError("ESD Event required for ESD Analysis")
@@ -498,7 +539,7 @@ void AliAnalysisTaskHFE::ProcessESD(){
 
   if(HasMCData()){
     if (GetPlugin(kSecVtx)) { 
-      fSecVtx->SetStack(fMCEvent->Stack());
+      if(fMCEvent->Stack()) fSecVtx->SetStack(fMCEvent->Stack());
     }
     if (GetPlugin(kIsElecBackGround)) { 
       fElecBackGround->SetMCEvent(fMCEvent);
@@ -506,8 +547,8 @@ void AliAnalysisTaskHFE::ProcessESD(){
   }
 
 
-  Double_t container[6];
-  memset(container, 0, sizeof(Double_t) * 6);
+  Double_t container[8];
+  memset(container, 0, sizeof(Double_t) * 8);
   // container for the output THnSparse
   Double_t dataE[5]; // [pT, eta, Phi, type, 'C' or 'B']
   Int_t nElectronCandidates = 0;
@@ -540,41 +581,45 @@ void AliAnalysisTaskHFE::ProcessESD(){
     container[0] = track->Pt();
     container[1] = track->Eta();
     container[2] = track->Phi();
+    container[3] = track->Charge();
 
     dataE[0] = track->Pt();
     dataE[1] = track->Eta();
     dataE[2] = track->Phi();
-    dataE[3] = -1;
+    dataE[3] = track->Charge();
     dataE[4] = -1;
+    dataE[5] = -1;
 
     signal = kTRUE;
+
+    // Fill step without any cut
           
-    // RecKine: ITSTPC cuts  
-    if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepRecKineITSTPC, track)) continue;
-    
     if(HasMCData()){
       // Check if it is electrons near the vertex
       if(!(mctrack = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(TMath::Abs(track->GetLabel()))))) continue;
-      mctrack4QA = fMCEvent->Stack()->Particle(TMath::Abs(track->GetLabel()));
+      mctrack4QA = mctrack->Particle();//fMCEvent->Stack()->Particle(TMath::Abs(track->GetLabel()));
 
-      container[3] = mctrack->Pt();
-      container[4] = mctrack->Eta();
-      container[5] = mctrack->Phi();
+      container[4] = mctrack->Pt();
+      container[5] = mctrack->Eta();
+      container[6] = mctrack->Phi();
+      container[7] = mctrack->Charge()/3.;
     
       if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepMCGenerated, mctrack)) signal = kFALSE;
     }
-    
     if(signal) {
       alreadyseen = cont.Find(TMath::Abs(track->GetLabel()));
       cont.Append(TMath::Abs(track->GetLabel()));
       
-      fCFM->GetParticleContainer()->Fill(&container[3], AliHFEcuts::kStepRecKineITSTPC);
-      fCFM->GetParticleContainer()->Fill(&container[0], (AliHFEcuts::kStepRecKineITSTPC + 2*(AliHFEcuts::kNcutESDSteps + 1)));
+      fCFM->GetParticleContainer()->Fill(&container[4], AliHFEcuts::kStepRecNoCut);
+      fCFM->GetParticleContainer()->Fill(&container[0], AliHFEcuts::kStepRecNoCut + 2*AliHFEcuts::kNcutStepsESDtrack);
       if(alreadyseen) {
-        fCFM->GetParticleContainer()->Fill(&container[3], (AliHFEcuts::kStepRecKineITSTPC + (AliHFEcuts::kNcutESDSteps + 1)));
+        fCFM->GetParticleContainer()->Fill(&container[4], AliHFEcuts::kStepRecNoCut + AliHFEcuts::kNcutStepsESDtrack);
       }
     }
 
+    // RecKine: ITSTPC cuts  
+    if(!ProcessCutStep(AliHFEcuts::kStepRecKineITSTPC, track, container, signal, alreadyseen)) continue;
+    
     // Check TRD criterions (outside the correction framework)
     if(track->GetTRDncls()){
       (dynamic_cast<TH1F *>(fQA->At(6)))->Fill(track->GetTRDchi2()/track->GetTRDncls());
@@ -622,31 +667,32 @@ void AliAnalysisTaskHFE::ProcessESD(){
 
     // Fill Containers
     if(signal) {
-      fCFM->GetParticleContainer()->Fill(container, AliHFEcuts::kStepHFEcutsTRD +1 + 2*(AliHFEcuts::kNcutESDSteps + 1));
-      fCFM->GetParticleContainer()->Fill(&container[3], AliHFEcuts::kStepHFEcutsTRD + 1);
+      fCFM->GetParticleContainer()->Fill(container, AliHFEcuts::kStepPID + 2*AliHFEcuts::kNcutStepsESDtrack);
+      fCFM->GetParticleContainer()->Fill(&container[4], AliHFEcuts::kStepPID);
       if(alreadyseen) {
-        fCFM->GetParticleContainer()->Fill(&container[3], (AliHFEcuts::kStepHFEcutsTRD + 1 + (AliHFEcuts::kNcutESDSteps + 1)));
+        fCFM->GetParticleContainer()->Fill(&container[4], (AliHFEcuts::kStepPID + (AliHFEcuts::kNcutStepsESDtrack)));
       }
       // dimensions 3&4&5 : pt,eta,phi (MC)
       ((THnSparseF *)fCorrelation->At(1))->Fill(container);
     }
 
-    if(GetPlugin(kSecVtx)) {
+    if(GetPlugin(kSecVtx) && fMCEvent->Stack()) {
       AliDebug(2, "Running Secondary Vertex Analysis");
-      if(track->Pt()>0.5){
+      if(track->Pt()>1.0){
         fSecVtx->InitHFEpairs();
         fSecVtx->InitHFEsecvtxs();
+        AliESDtrack *htrack = 0x0; 
         for(Int_t jtrack = 0; jtrack < fESD->GetNumberOfTracks(); jtrack++){
           htrack = fESD->GetTrack(jtrack);
           if ( itrack == jtrack ) continue; // since it is for tagging single electron, don't need additional condition 
-          if (htrack->Pt()<0.5) continue;
+          if (htrack->Pt()<1.0) continue;
           if (!fCFM->CheckParticleCuts(AliHFEcuts::kStepRecKineITSTPC, htrack)) continue;
           if (!fCFM->CheckParticleCuts(AliHFEcuts::kStepRecPrim, htrack)) continue;
           fSecVtx->PairAnalysis(track, htrack, jtrack); // e-h pairing
         }
         /*for(int ip=0; ip<fSecVtx->HFEpairs()->GetEntriesFast(); ip++){
-          AliHFEpairs *pair = (AliHFEpairs*) (fSecVtx->HFEpairs()->UncheckedAt(ip));
           if(HasMCData()){
+            AliHFEpairs *pair = (AliHFEpairs*) (fSecVtx->HFEpairs()->UncheckedAt(ip));
             if(!(pair->GetPairCode()>1. && pair->GetPairCode()<4.))  // apply various cuts
               fSecVtx->HFEpairs()->RemoveAt(ip);
           }
@@ -670,22 +716,22 @@ void AliAnalysisTaskHFE::ProcessESD(){
         Int_t type = IsSignalElectron(track);
         AliDebug(1, Form("Type: %d\n", type));
         if(type){
-               dataE[4] = type; // beauty[1] or charm[2]
-               dataE[3] = 2;  // signal electron
+               dataE[5] = type; // beauty[1] or charm[2]
+               dataE[4] = 2;  // signal electron
         }
         else{
-               dataE[3] = 1; // not a signal electron
-               dataE[4] = 0;
+               dataE[4] = 1; // not a signal electron
+               dataE[5] = 0;
         }
       } 
       else {
         // Fill THnSparse with the information for Fake Electrons
-        dataE[3] = 0;
         dataE[4] = 0;
+        dataE[5] = 0;
       }
       // fill the performance THnSparse, if the mc origin could be defined
-      if(dataE[3] > -1){
-        AliDebug(1, Form("Entries: [%.3f|%.3f|%.3f|%f|%f]\n", dataE[0],dataE[1],dataE[2],dataE[3],dataE[4]));
+      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);
       }
     }
@@ -714,6 +760,9 @@ void AliAnalysisTaskHFE::ProcessAOD(){
   // Function is still in development
   //
   AliDebug(3, "Processing AOD Event");
+  Double_t nContrib = fInputEvent->GetPrimaryVertex()->GetNContributors();
+  if(!fCFM->CheckEventCuts(AliHFEcuts::kEventStepReconstructed, fInputEvent)) return;
+  fCFM->GetEventContainer()->Fill(&nContrib,AliHFEcuts::kEventStepReconstructed);
   AliAODEvent *fAOD = dynamic_cast<AliAODEvent *>(fInputEvent);
   if(!fAOD){
     AliError("AOD Event required for AOD Analysis")
@@ -722,8 +771,8 @@ void AliAnalysisTaskHFE::ProcessAOD(){
  
   AliAODTrack *track = NULL;
   AliAODMCParticle *mctrack = NULL;
-  Double_t container[6]; memset(container, 0, sizeof(Double_t) * 6);
-  Double_t dataE[5]; // [pT, eta, Phi, type, 'C' or 'B']
+  Double_t container[8]; memset(container, 0, sizeof(Double_t) * 8);
+  Double_t dataE[6]; // [pT, eta, Phi, Charge, type, 'C' or 'B']
   Int_t nElectronCandidates = 0;
   Int_t pid;
   for(Int_t itrack = 0; itrack < fAOD->GetNumberOfTracks(); itrack++){
@@ -734,20 +783,23 @@ void AliAnalysisTaskHFE::ProcessAOD(){
     container[0] = track->Pt();
     container[1] = track->Eta();
     container[2] = track->Phi();
+    container[3] = track->Charge();
 
     dataE[0] = track->Pt();
     dataE[1] = track->Eta();
     dataE[2] = track->Phi();
-    dataE[3] = -1;
+    dataE[3] = track->Charge();
     dataE[4] = -1;
+    dataE[5] = -1;
     
     if(HasMCData()){
       Int_t label = TMath::Abs(track->GetLabel());
       if(label){
         mctrack = dynamic_cast<AliAODMCParticle *>(fMCEvent->GetTrack(label));
-        container[3] = mctrack->Pt();
-        container[4] = mctrack->Eta();
-        container[5] = mctrack->Phi();
+        container[4] = mctrack->Pt();
+        container[5] = mctrack->Eta();
+        container[6] = mctrack->Phi();
+        container[7] = mctrack->Charge();
       }
     }
     // track accepted, do PID
@@ -757,7 +809,7 @@ void AliAnalysisTaskHFE::ProcessAOD(){
     if(HasMCData()) hfetrack.fMCtrack = mctrack;
     //if(!fPID->IsSelected(&hfetrack)) continue;    // we will do PID here as soon as possible
     // Particle identified - Fill CF Container
-    fCFM->GetParticleContainer()->Fill(container, AliHFEcuts::kStepHFEcutsTRD +1 + 2*(AliHFEcuts::kNcutESDSteps + 1));
+    fCFM->GetParticleContainer()->Fill(container, AliHFEcuts::kStepPID + 2*AliHFEcuts::kNcutStepsESDtrack);
     nElectronCandidates++;    
     if(HasMCData()){
       // Track selected: distinguish between true and fake
@@ -766,22 +818,22 @@ void AliAnalysisTaskHFE::ProcessAOD(){
         Int_t type = IsSignalElectron(track);
         AliDebug(1, Form("Type: %d\n", type));
         if(type){
-               dataE[4] = type; // beauty[1] or charm[2]
-               dataE[3] = 2;  // signal electron
+               dataE[5] = type; // beauty[1] or charm[2]
+               dataE[4] = 2;  // signal electron
         }
         else{
-               dataE[3] = 1; // not a signal electron
-               dataE[4] = 0;
+               dataE[4] = 1; // not a signal electron
+               dataE[5] = 0;
         }
       } 
       else {
         // Fill THnSparse with the information for Fake Electrons
-        dataE[3] = 0;
         dataE[4] = 0;
+        dataE[5] = 0;
       }
       // fill the performance THnSparse, if the mc origin could be defined
-      if(dataE[3] > -1){
-        AliDebug(1, Form("Entries: [%.3f|%.3f|%.3f|%f|%f]\n", dataE[0],dataE[1],dataE[2],dataE[3],dataE[4]));
+      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);
       }
     }
@@ -797,17 +849,19 @@ 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[3], signalContainer[5];
+  Double_t container[4], signalContainer[6];
   Double_t vertex[3]; // Production vertex cut to mask gammas which are NOT supposed to have hits in the first ITS layer(s)
   if(IsESDanalysis()){
     AliMCParticle *mctrack = dynamic_cast<AliMCParticle *>(track);
     container[0] = mctrack->Pt();
     container[1] = mctrack->Eta();
     container[2] = mctrack->Phi();
+    container[3] = mctrack->Charge()/3;
 
     signalContainer[0] = mctrack->Pt();
     signalContainer[1] = mctrack->Eta();
     signalContainer[2] = mctrack->Phi();
+    signalContainer[3] = mctrack->Charge()/3;
 
     vertex[0] = mctrack->Particle()->Vx();
     vertex[1] = mctrack->Particle()->Vy();
@@ -816,25 +870,28 @@ Bool_t AliAnalysisTaskHFE::ProcessMCtrack(AliVParticle *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);
   }
-
   if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepMCGenerated, track)) return kFALSE;
-  fCFM->GetParticleContainer()->Fill(container, AliHFEcuts::kStepMCGenerated);
-  if((signalContainer[3] = static_cast<Double_t >(IsSignalElectron(track))) > 1e-3) fCFM->GetParticleContainer()->Fill(container, AliHFEcuts::kStepMCsignal);
-  signalContainer[4] = 0;
+  TH1 *test = dynamic_cast<TH1I*>(fQA->FindObject("mccharge"));
+  test->Fill(signalContainer[3]);
+ fCFM->GetParticleContainer()->Fill(container, AliHFEcuts::kStepMCGenerated);
+  if((signalContainer[4] = static_cast<Double_t >(IsSignalElectron(track))) > 1e-3) fCFM->GetParticleContainer()->Fill(container, AliHFEcuts::kStepMCsignal);
+  signalContainer[5] = 0;
   // apply cut on the sqrt of the production vertex
   Double_t radVertex = TMath::Sqrt(vertex[0]*vertex[0] + vertex[1] * vertex[1]);
   if(radVertex < 3.5){
     // Within first ITS layer(2) -> Background we cannot reject by ITS cut, let it pass
-    signalContainer[4] = 1;
+    signalContainer[5] = 1;
   } else if (radVertex < 7.5){
-    signalContainer[4] = 2;
+    signalContainer[5] = 2;
   }
   fSignalToBackgroundMC->Fill(signalContainer);
   (dynamic_cast<TH1F *>(fQA->At(2)))->Fill(container[2] - TMath::Pi());
@@ -846,34 +903,50 @@ Bool_t AliAnalysisTaskHFE::ProcessMCtrack(AliVParticle *track){
 }
 
 //____________________________________________________________
+void AliAnalysisTaskHFE::MakeEventContainer(){
+  //
+  // Create the event container for the correction framework and link it
+  //
+  const Int_t kNvar = 1;  // number of variables on the grid: number of tracks per event
+  const Double_t kNTrackBound[2] = {-0.5, 200.5};
+  const Int_t kNBins = 201;
+
+  AliCFContainer *evCont = new AliCFContainer("eventContainer", "Container for events", AliHFEcuts::kNcutStepsEvent, kNvar, &kNBins);
+
+  Double_t *trackBins = AliHFEtools::MakeLinearBinning(kNBins, kNTrackBound[0], kNTrackBound[1]);
+  evCont->SetBinLimits(0,trackBins);
+  delete[] trackBins;
+
+  fCFM->SetEventContainer(evCont);
+}
+
+//____________________________________________________________
 void AliAnalysisTaskHFE::MakeParticleContainer(){
   //
   // Create the particle container for the correction framework manager and 
   // link it
   //
-  const Int_t kNvar   = 3 ; //number of variables on the grid:pt,eta, phi
-  const Double_t kPtmin = 0.1, kPtmax = 10.;
-  const Double_t kEtamin = -0.9, kEtamax = 0.9;
-  const Double_t kPhimin = 0., kPhimax = 2. * TMath::Pi();
+  const Int_t kNvar   = 4 ; //number of variables on the grid:pt,eta, phi, charge
+  const Double_t kPtbound[2] = {0.1, 10.};
+  const Double_t kEtabound[2] = {-0.8, 0.8};
+  const Double_t kPhibound[2] = {0., 2. * TMath::Pi()};
 
   //arrays for the number of bins in each dimension
   Int_t iBin[kNvar];
-  iBin[0] = 40; //bins in pt
-  iBin[1] =  8; //bins in eta 
+  iBin[0] = 40; // bins in pt
+  iBin[1] =  8; // bins in eta 
   iBin[2] = 18; // bins in phi
+  iBin[3] =  2; // bins in charge
 
   //arrays for lower bounds :
   Double_t* binEdges[kNvar];
-  for(Int_t ivar = 0; ivar < kNvar; ivar++)
-    binEdges[ivar] = new Double_t[iBin[ivar] + 1];
-
-  //values for bin lower bounds
-  for(Int_t i=0; i<=iBin[0]; i++) binEdges[0][i]=(Double_t)TMath::Power(10,TMath::Log10(kPtmin) + (TMath::Log10(kPtmax)-TMath::Log10(kPtmin))/iBin[0]*(Double_t)i);  
-  for(Int_t i=0; i<=iBin[1]; i++) binEdges[1][i]=(Double_t)kEtamin  + (kEtamax-kEtamin)/iBin[1]*(Double_t)i;
-  for(Int_t i=0; i<=iBin[2]; i++) binEdges[2][i]=(Double_t)kPhimin  + (kPhimax-kPhimin)/iBin[2]*(Double_t)i;
+  binEdges[0] = AliHFEtools::MakeLogarithmicBinning(iBin[0], kPtbound[0], kPtbound[1]);
+  binEdges[1] = AliHFEtools::MakeLinearBinning(iBin[1], kEtabound[0], kEtabound[1]);
+  binEdges[2] = AliHFEtools::MakeLinearBinning(iBin[2], kPhibound[0], kPhibound[1]);
+  binEdges[3] = AliHFEtools::MakeLinearBinning(iBin[3], -1.1, 1.1); // Numeric precision
 
   //one "container" for MC
-  AliCFContainer* container = new AliCFContainer("container","container for tracks", (AliHFEcuts::kNcutSteps + 1 + 2*(AliHFEcuts::kNcutESDSteps + 1)), kNvar, iBin);
+  AliCFContainer* container = new AliCFContainer("trackContainer", "Container for tracks", (AliHFEcuts::kNcutStepsTrack + 2*AliHFEcuts::kNcutStepsESDtrack), kNvar, iBin);
 
   //setting the bin limits
   for(Int_t ivar = 0; ivar < kNvar; ivar++)
@@ -907,38 +980,39 @@ void AliAnalysisTaskHFE::MakeParticleContainer(){
   fCorrelation->AddAt(correlation1,1);
   
   // Add a histogram for Fake electrons
-  const Int_t nDim=5;
-  Int_t nBin[nDim] = {40, 8, 18, 3, 3};
+  const Int_t nDim=6;
+  Int_t nBin[nDim] = {40, 8, 18, 2, 3, 3};
   Double_t* binEdges2[nDim];
-  for(Int_t ivar = 0; ivar < nDim; ivar++)
-    binEdges2[ivar] = new Double_t[nBin[ivar] + 1];
 
   //values for bin lower bounds
-  for(Int_t i=0; i<=nBin[0]; i++) binEdges2[0][i]=(Double_t)TMath::Power(10,TMath::Log10(kPtmin) + (TMath::Log10(kPtmax)-TMath::Log10(kPtmin))/nBin[0]*(Double_t)i);  
-  for(Int_t i=0; i<=nBin[1]; i++) binEdges2[1][i]=(Double_t)kEtamin  + (kEtamax-kEtamin)/nBin[1]*(Double_t)i;
-  for(Int_t i=0; i<=nBin[2]; i++) binEdges2[2][i]=(Double_t)kPhimin  + (kPhimax-kPhimin)/nBin[2]*(Double_t)i;
-  for(Int_t i=0; i<=nBin[3]; i++) binEdges2[3][i] = i;
-  for(Int_t i=0; i<=nBin[4]; i++) binEdges2[4][i] = i;
+  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]; type (0 - not el, 1 - other el, 2 - HF el; flavor (0 - no, 1 - charm, 2 - bottom)", nDim, nBin);
+  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]; flavor (0 - no, 1 - charm, 2 - bottom); ITS Cluster (0 - no, 1 - first (and maybe second), 2 - second)", nDim, nBin);
+  fSignalToBackgroundMC = new THnSparseF("SignalToBackgroundMC", "PID performance; pT [GeV/c]; theta [rad]; phi [rad]; charge; flavor (0 - no, 1 - charm, 2 - bottom); ITS Cluster (0 - no, 1 - first (and maybe second), 2 - second)", nDim, nBin);
   fSignalToBackgroundMC->Sumw2();
   for(Int_t idim = 0; idim < nDim; idim++){
     fPIDperformance->SetBinEdges(idim, binEdges2[idim]);
     fSignalToBackgroundMC->SetBinEdges(idim, binEdges2[idim]); 
   }
+  for(Int_t ivar = 0; ivar < kNvar; ivar++)
+    delete binEdges[ivar];
+  for(Int_t ivar = kNvar; ivar < nDim; ivar++)
+    delete binEdges2[ivar];
 }
 
 //____________________________________________________________
-void AliAnalysisTaskHFE::AddPIDdetector(Char_t *detector){
+void AliAnalysisTaskHFE::AddPIDdetector(TString detector){
   //
   // Adding PID detector to the task
   //
   if(!fPIDdetectors.Length()) 
     fPIDdetectors = detector;
   else
-    fPIDdetectors += Form(":%s", detector);
+    fPIDdetectors += ":" + detector;
 }
 
 //____________________________________________________________
@@ -1080,18 +1154,6 @@ Int_t AliAnalysisTaskHFE::IsSignalElectron(AliVParticle *fTrack) const{
 }
 
 //__________________________________________
-Float_t AliAnalysisTaskHFE::GetRapidity(TParticle *part) const
-{
-  //
-  // return rapidity
-  //
-  Float_t rapidity;
-  if(!((part->Energy() - part->Pz())*(part->Energy() + part->Pz())>0)) rapidity=-999;
-  else rapidity = 0.5*(TMath::Log((part->Energy()+part->Pz()) / (part->Energy()-part->Pz())));
-  return rapidity;
-}
-
-//__________________________________________
 void AliAnalysisTaskHFE::SwitchOnPlugin(Int_t plug){
   //
   // Switch on Plugin
@@ -1117,11 +1179,20 @@ Bool_t AliAnalysisTaskHFE::ProcessCutStep(Int_t cutStep, AliVParticle *track, Do
   //
   if(!fCFM->CheckParticleCuts(cutStep, track)) return kFALSE;
   if(signal) {
-    fCFM->GetParticleContainer()->Fill(container, cutStep + 2*(AliHFEcuts::kNcutESDSteps + 1));
-    fCFM->GetParticleContainer()->Fill(&container[3], cutStep);
+    fCFM->GetParticleContainer()->Fill(container, cutStep + 2*AliHFEcuts::kNcutStepsESDtrack);
+    fCFM->GetParticleContainer()->Fill(&container[4], cutStep);
     if(alreadyseen) {
-      fCFM->GetParticleContainer()->Fill(&container[3], cutStep + AliHFEcuts::kNcutESDSteps + 1);
+      fCFM->GetParticleContainer()->Fill(&container[4], cutStep + AliHFEcuts::kNcutStepsESDtrack);
     }
   }
   return kTRUE;
 }
+
+//__________________________________________
+void AliAnalysisTaskHFE::SetTPCBetheBlochParameters(Double_t *pars){
+  //
+  // Set Bethe-Bloch Parameters for TPC PID
+  //
+  fPID->SetTPCBetheBlochParameters(pars);
+}
+
index 962ba0c..207410e 100644 (file)
@@ -70,16 +70,17 @@ class AliAnalysisTaskHFE : public AliAnalysisTaskSE{
     Bool_t GetPlugin(Int_t plug) const { return TESTBIT(fPlugins, plug); };
     Int_t IsSignalElectron(AliVParticle *fTrack) const;
     void SetHFECuts(AliHFEcuts * const cuts) { fCuts = 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 AddPIDdetector(Char_t *detector);
+    void AddPIDdetector(TString detector);
+    void SetTPCBetheBlochParameters(Double_t *pars);
     void SetAODAnalysis() { SetBit(kAODanalysis, kTRUE); };
     void SetESDAnalysis() { SetBit(kAODanalysis, kFALSE); };
     void PrintStatus() const;
-    Float_t GetRapidity(TParticle *part) const;
  
   private:
     enum{
@@ -106,6 +107,7 @@ class AliAnalysisTaskHFE : public AliAnalysisTaskSE{
         Int_t *fCurrent;      // Current entry to mimic an iterator
     };
     void MakeParticleContainer();
+    void MakeEventContainer();
     void ProcessMC();
     void ProcessESD();
     void ProcessAOD();
@@ -115,6 +117,7 @@ class AliAnalysisTaskHFE : public AliAnalysisTaskSE{
     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
     AliCFManager *fCFM;                   //! Correction Framework Manager
     TList *fCorrelation;                  //! response matrix for unfolding  
diff --git a/PWG3/hfe/AliAnalysisTaskHFEpidQA.cxx b/PWG3/hfe/AliAnalysisTaskHFEpidQA.cxx
new file mode 100644 (file)
index 0000000..67b8b48
--- /dev/null
@@ -0,0 +1,115 @@
+/**************************************************************************
+* 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
+// 
+// Authors
+//   Matus Kalisky <matus.kalisky@cern.ch>
+//   Markus Heide <mheide@uni-muenster.de>
+//   Markus Fasel <M.Fasel@gsi.de>
+//
+#include <TH1I.h>
+#include <TList.h>
+
+#include "AliAnalysisTaskHFEpidQA.h"
+#include "AliHFEpidQA.h"
+#include "AliESDEvent.h"
+#include "AliMCEvent.h"
+
+ClassImp(AliAnalysisTaskHFEpidQA)
+
+AliAnalysisTaskHFEpidQA::AliAnalysisTaskHFEpidQA():
+    AliAnalysisTaskSE("pidQAtask")
+  , fPIDqa(NULL)
+  , fOutput(NULL)
+  , fEvents(NULL)
+{
+  //
+  // Default Constructor
+  //
+  DefineOutput(1, TList::Class());
+}
+
+AliAnalysisTaskHFEpidQA::AliAnalysisTaskHFEpidQA(const Char_t *name):
+    AliAnalysisTaskSE(name)
+  , fPIDqa(NULL)
+  , fOutput(NULL)
+  , fEvents(NULL)
+{
+  //
+  // Default Constructor
+  //
+  DefineOutput(1, TList::Class());
+}
+
+AliAnalysisTaskHFEpidQA::~AliAnalysisTaskHFEpidQA(){
+  //
+  // Destructor
+  //
+  if(fPIDqa) delete fPIDqa;
+  if(fOutput) delete fOutput;
+}
+
+void AliAnalysisTaskHFEpidQA::UserCreateOutputObjects(){
+  //
+  // Create the output
+  // Initialize PID QA
+  //
+  fOutput = new TList;
+
+  // Counter for number of events
+  fOutput->Add((fEvents = new TH1I("nEvents", "NumberOfEvents", 1, 1, 2)));
+
+  fPIDqa = new AliHFEpidQA;
+  if(HasV0pidQA()) fPIDqa->SetV0pidQA();
+  if(HasRecalculateTRDpid()) fPIDqa->SetRecalculateTRDpid();
+  fPIDqa->Init();
+
+  TList *tmp = fPIDqa->GetOutput();
+  tmp->SetName("PIDqa");
+  fOutput->Add(tmp);
+  if(HasV0pidQA()){
+    tmp = fPIDqa->GetV0pidQA();
+    tmp->SetName("V0pidQA");
+    fOutput->Add(tmp);
+  }
+  tmp = 0x0;
+  tmp = fPIDqa->GetV0pidMC();
+  if(tmp){
+    tmp->SetName("V0pidMC");
+    fOutput->Add(tmp);
+  }
+  
+}
+
+void AliAnalysisTaskHFEpidQA::UserExec(Option_t *){
+  //
+  // Event Loop
+  //
+  if(fMCEvent) fPIDqa->SetMCEvent(fMCEvent);
+  fPIDqa->SetRun((dynamic_cast<AliESDEvent*>(fInputEvent))->GetRunNumber());
+  fPIDqa->SetT0((dynamic_cast<AliESDEvent*>(fInputEvent))->GetT0());
+  fPIDqa->Process(fInputEvent);
+  fEvents->Fill(1.1);
+  PostData(1, fOutput);
+}
+
+void AliAnalysisTaskHFEpidQA::Terminate(Option_t *){
+  //
+  // Do Post Processing
+  //
+}
+
diff --git a/PWG3/hfe/AliAnalysisTaskHFEpidQA.h b/PWG3/hfe/AliAnalysisTaskHFEpidQA.h
new file mode 100644 (file)
index 0000000..1083674
--- /dev/null
@@ -0,0 +1,43 @@
+#ifndef ALIANALYSISTASKHFEPIDQA_H
+#define ALIANALYSISTASKHFEPIDQA_H
+
+#ifndef ALIANALYSISTASKSE_H
+#include "AliAnalysisTaskSE.h"
+#endif
+
+class TH1;
+class TList;
+
+class AliHFEpidQA;
+
+class AliAnalysisTaskHFEpidQA : public AliAnalysisTaskSE{
+  enum{
+    kV0pidQA = BIT(22),
+    kRecalculateTRDpid = BIT(23)
+  };
+  public:
+    AliAnalysisTaskHFEpidQA();
+    AliAnalysisTaskHFEpidQA(const Char_t *name);
+    ~AliAnalysisTaskHFEpidQA();
+
+    void UserCreateOutputObjects();
+    virtual void UserExec(Option_t *);
+    virtual void Terminate(Option_t *);
+
+    Bool_t HasV0pidQA() const { return TestBit(kV0pidQA); };
+    Bool_t HasRecalculateTRDpid() const { return TestBit(kRecalculateTRDpid); };
+    void SetV0pidQA(Bool_t v0pidQA = kTRUE) { SetBit(kV0pidQA, v0pidQA); };
+    void SetRecalculateTRDpid(Bool_t recal = kTRUE) { SetBit(kRecalculateTRDpid, recal); };
+
+  private:
+    AliAnalysisTaskHFEpidQA(const AliAnalysisTaskHFEpidQA &ref);
+    AliAnalysisTaskHFEpidQA &operator=(const AliAnalysisTaskHFEpidQA &ref);
+    AliHFEpidQA *fPIDqa;    //! The heart of the analysis  
+    TList *fOutput;         //! Container for output histos
+    TH1 *fEvents;           //! Number of Events
+
+    ClassDef(AliAnalysisTaskHFEpidQA, 1)
+};
+
+#endif
+
diff --git a/PWG3/hfe/AliHFEV0pid.cxx b/PWG3/hfe/AliHFEV0pid.cxx
new file mode 100644 (file)
index 0000000..80ae970
--- /dev/null
@@ -0,0 +1,1062 @@
+/*************************************************************************
+* 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.                  *
+**************************************************************************/
+//
+// Utility class for V0 PID
+// Identifies Electrons, Pions and Protons using gamma conversions and
+// the decays of K0s and Lambdas
+// Containers with samples of Electrons, Pions and Protons can be accessed
+// via GetListOfElectrons() etc.
+//
+// Authors:
+//    Matus Kalisky <matus.kalisky@cern.ch>
+//    Markus Heide <mheide@uni-muenster.de>
+//    Markus Fasel <M.Fasel@gsi.de>
+//
+#include <TDatabasePDG.h>
+#include <TObjArray.h>
+#include <TPDGCode.h>
+#include <TString.h>
+
+#include <TDatabasePDG.h>
+
+#include "AliAODEvent.h"
+#include "AliAODTrack.h"
+#include "AliAODv0.h"
+#include "AliAODVertex.h"
+#include "AliESDEvent.h"
+#include "AliESDtrack.h"
+#include "AliESDv0.h"
+#include "AliESDVertex.h"
+#include "AliKFParticle.h"
+#include "AliKFVertex.h"
+#include "AliVEvent.h"
+#include "AliVTrack.h"
+
+#include "AliHFEV0pid.h"
+ClassImp(AliHFEV0pid)
+
+//____________________________________________________________
+AliHFEV0pid::AliHFEV0pid():
+  TObject()
+  , fInputEvent(NULL)
+  , fPrimaryVertex(NULL)
+  , fElectrons(NULL)
+  , fPionsK0(NULL)
+  , fPionsL(NULL)
+  , fKaons(NULL)
+  , fProtons(NULL)
+  , fIndices(NULL)
+  , fQA(NULL)
+{
+  //
+  // Default constructor
+  //
+  fElectrons = new TObjArray();
+  fPionsK0 = new TObjArray();
+  fPionsL = new TObjArray();
+  fKaons = new TObjArray();
+  fProtons = new TObjArray();
+  fIndices = new AliHFEV0pidTrackIndex;
+}
+
+//____________________________________________________________
+AliHFEV0pid::~AliHFEV0pid(){
+  //
+  // Destructor
+  // Remove Containers
+  //
+  if(fInputEvent) delete fInputEvent;
+  //if(fPrimaryVertex) delete fPrimaryVertex;
+  if(fElectrons) delete fElectrons;
+  if(fPionsK0) delete fPionsK0;
+  if(fPionsL) delete fPionsL;
+  if(fKaons) delete fKaons;
+  if(fProtons) delete fProtons;
+  if(fIndices) delete fIndices;
+  if(fQA) delete fQA;
+}
+
+//____________________________________________________________
+void AliHFEV0pid::InitQA(){
+  //
+  // Initialize QA histograms
+  //
+  if(!fQA){
+    fQA = new AliHFEcollection("v0pidQA", "QA histograms for V0 PID");
+
+    // QA histograms for cut statistics
+    fQA->CreateTH1F("h_cutEfficiencyGamma", "Cut Efficiency for Gammas", 10, 0, 10);
+    fQA->CreateTH1F("h_cutEfficiencyK0s", "Cut Efficiency for K0s", 10, 0, 10);
+    fQA->CreateTH1F("h_cutEfficiencyPhi", "Cut Efficiency for Phi", 10, 0, 10);
+    fQA->CreateTH1F("h_cutEfficiencyLambda", "Cut Efficiency for Lambdas", 10, 0, 10);
+
+    // QA histograms for invariant mass
+    fQA->CreateTH1F("h_InvMassGamma", "Gamma invariant mass; inv mass {[eV/c^{2}]; counts", 100, 0, 0.25);
+    fQA->CreateTH1F("h_InvMassK0s", "K0s invariant mass; inv mass [GeV/c^{2}]; counts", 100, 0.4, 0.65);
+    fQA->CreateTH1F("h_InvMassPhi", "Phi invariant mass; inv mass [GeV/c^{2}]; counts", 100, 0.4, 0.65);
+    fQA->CreateTH1F("h_InvMassLambda", "Lambda invariant mass; inv mass [GeV/c^{2}]; counts", 100, 1.05, 1.15);
+    
+    // QA invariant mass as a functin of pt
+    fQA->CreateTH1Fvector1(20, "h_InvMassGamma_pt", "Gamma invarinat mass in pt bins; inv mass [GeV/c^{2}]; counts", 250, 0, 2);
+    fQA->CreateTH1Fvector1(20, "h_InvMassK0_pt", "K0 invarinat mass in pt bins; inv mass [GeV/c^{2}]; counts", 250, 0, 2);
+    fQA->CreateTH1Fvector1(20, "h_InvMassPhi_pt", "Phi invarinat mass in pt bins; inv mass [GeV/c^{2}]; counts", 250, 0, 2);
+    fQA->CreateTH1Fvector1(20, "h_InvMassLambda_pt", "Lambda invarinat mass in pt bins; inv mass [GeV/c^{2}]; counts", 250, 0, 2);
+
+    // 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_Phi", "Pt of the Phi; 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_electrons", "Pt of the conversion electrons; p_{T} (GeV/c); counts");
+    //fQA->CreateTH1F("h_Pt_pionsK0", "Pt of the K0 pions; p_{T} (GeV/c); counts");
+    //fQA->CreateTH1F("h_Pt_pionsL", "Pt of the Lambda pions; p_{T} (GeV/c); counts");
+    //fQA->CreateTH1F("h_Pt_protons", "Pt of the Lambda protons; p_{T} (GeV/c); counts");
+
+
+    // QA histogram for both Lambda candidate combinations - 
+    fQA->CreateTH2F("h_L0_dca_v_dMass", "L0 dca verus dMass; dMass [GeV/c^{2}]; dDCA [cm]; ", 100, -1., 1., 100, 0., 5.);
+    
+    // Chi2 histograms
+    fQA->CreateTH1F("h_chi2_gamma", "Chi2 for gammas", 10000, 0, 1000);
+    fQA->CreateTH1F("h_chi2_K0s", "Chi2 for K0s", 10000, 0, 500);
+    fQA->CreateTH1F("h_chi2_Phi", "Chi2 for K0s", 10000, 0, 500);
+    fQA->CreateTH1F("h_chi2_Lambda", "Chi2 for Lambdas", 10000, 0, 1000);
+  }
+}
+
+//____________________________________________________________
+void AliHFEV0pid::Process(AliVEvent * const inputEvent){
+
+  //
+  // Find protons, pions and electrons using V0 decays and 
+  // store the pointers in the TObjArray
+  //
+  Int_t nGamma = 0, nK0s = 0, nLambda = 0, nPhi = 0;
+  fInputEvent = inputEvent;
+  
+  fIndices->Init(fInputEvent->GetNumberOfV0s() * 2);
+  fPrimaryVertex = new AliKFVertex(*(fInputEvent->GetPrimaryVertex()));
+  Int_t v0status = 0;
+  for(Int_t iv0 = 0; iv0 < fInputEvent->GetNumberOfV0s(); iv0++){
+    if(!TString(fInputEvent->IsA()->GetName()).CompareTo("AliESDEvent")){
+      // case ESD
+      SetESDanalysis();
+      AliESDv0 *esdV0 = (dynamic_cast<AliESDEvent *>(fInputEvent))->GetV0(iv0);
+      if(!esdV0->GetOnFlyStatus()) continue; // Take only V0s from the On-the-fly v0 finder
+      v0status = ProcessV0(esdV0);
+    } else {
+      // case AOD
+      SetAODanalysis();
+      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);
+    }
+    switch(v0status){
+    case kRecoGamma: nGamma++; break;
+    case kRecoK0s: nK0s++; break;
+    case kRecoPhi: nPhi++; break;  
+    case kRecoLambda: nLambda++; break;
+    };
+  }
+
+  AliDebug(1, Form("Number of gammas  : %d", nGamma));
+  AliDebug(1, Form("Number of K0s     : %d", nK0s));
+  AliDebug(1, Form("Number of Phis    : %d", nPhi));
+  AliDebug(1, Form("Number of Lambdas : %d", nLambda));
+
+  AliDebug(1, "Number of stored tracks:");
+  AliDebug(1, Form("Number of electrons      : %d", fElectrons->GetEntries()));
+  AliDebug(1, Form("Number of K0 pions       : %d", fPionsK0->GetEntries()));
+  AliDebug(1, Form("Number of Lambda pions   : %d", fPionsL->GetEntries()));
+  AliDebug(1, Form("Number of Phi kaons      : %d", fKaons->GetEntries()));
+  AliDebug(1, Form("Number of protons        : %d", fProtons->GetEntries()));
+  
+  delete  fPrimaryVertex;
+}
+
+//____________________________________________________________
+Int_t AliHFEV0pid::ProcessV0(TObject *v0){
+  //
+  // Process single V0
+  // Apply general cut and special cuts for gamma, K0s, Lambda
+  //
+  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))->GetPindex()));
+  if(!daughter[0] || !daughter[1]) return kUndef;
+
+  if(IsESDanalysis()){
+    for(Int_t i=0; i<2; ++i){
+      if(!CutESDtrack(dynamic_cast<AliESDtrack*>(daughter[i]))) return kUndef;
+    }    
+  }
+
+  if(IsGammaConv(v0)) return kRecoGamma;
+  else if(IsK0s(v0)) return kRecoK0s;
+  else if(IsLambda(v0)) return kRecoLambda;
+  else return kUndef;
+  
+  
+}
+//____________________________________________________________
+void AliHFEV0pid::Flush(){
+  //
+  // Clear the Lists
+  //
+  AliDebug(1, "Flushing containers");
+  fProtons->Clear();
+  fPionsK0->Clear();
+  fPionsL->Clear();
+  fElectrons->Clear();
+  fIndices->Flush();
+}
+
+//____________________________________________________________
+Bool_t AliHFEV0pid::IsGammaConv(TObject *v0){
+  //
+  // Identify Gamma
+  //
+  AliVTrack* daughter[2];
+  Int_t pIndex = 0, nIndex = 0;
+  Double_t invMass = 0.;
+  if(IsESDanalysis()){
+    // ESD - cut V0
+    AliESDv0 *esdV0 = dynamic_cast<AliESDv0 *>(v0);
+    if(!CutV0(esdV0, kRecoGamma)) return kFALSE; 
+    if(LooseRejectK0(esdV0) || LooseRejectLambda(esdV0)) return kFALSE;
+    // DEBUG
+    //invMass = esdV0->GetEffMass(AliPID::kElectron, AliPID::kElectron);
+    invMass = GetEffMass(esdV0, AliPID::kElectron, AliPID::kElectron);
+    //..
+
+    pIndex = esdV0->GetPindex();
+    nIndex = esdV0->GetNindex();
+  } else {
+    // AOD Analysis - not possible to cut
+    AliAODv0 *aodV0 = dynamic_cast<AliAODv0 *>(v0);
+    pIndex = aodV0->GetPosID();
+    nIndex = aodV0->GetNegID();
+    invMass = aodV0->InvMass2Prongs(0, 1, kElectron, kElectron);
+  }
+  daughter[0] = dynamic_cast<AliVTrack *>(fInputEvent->GetTrack(pIndex));
+  daughter[1] = dynamic_cast<AliVTrack *>(fInputEvent->GetTrack(nIndex));
+  if(!daughter[0] || !daughter[1]) return kFALSE;
+
+  // Get Invariant mass and chi2/ndf 
+  AliKFParticle *kfMother = CreateMotherParticle(daughter[0], daughter[1], TMath::Abs(kElectron), TMath::Abs(kElectron));
+  kfMother->SetProductionVertex(*fPrimaryVertex);
+  kfMother->SetMassConstraint(0, 1.);
+  Double_t ndf = kfMother->GetNDF();
+  Double_t chi2 = kfMother->GetChi2();
+  delete kfMother; 
+
+  if(fQA) fQA->Fill("h_chi2_gamma", chi2/ndf);
+  if(chi2/ndf > 7) return kFALSE;
+  Double_t mPt = kfMother->GetPt();
+  fQA->Fill("h_Pt_Gamma", mPt);
+  Int_t ptBin = (int)(mPt*10.0);
+  fQA->Fill("h_InvMassGamma_pt", ptBin+1, invMass);
+
+  if(fQA) fQA->Fill("h_InvMassGamma", invMass);
+  if(invMass > 0.05) return kFALSE; 
+
+  AliDebug(1, Form("Gamma identified, daughter IDs: %d,%d", daughter[0]->GetID(), daughter[1]->GetID()));
+  // Identified gamma - store tracks in the electron containers
+  if(!fIndices->Find(daughter[0]->GetID())){
+    AliDebug(1, Form("Gamma identified, daughter IDs: %d,%d", daughter[0]->GetID(), daughter[1]->GetID()));    
+    fElectrons->Add(daughter[0]);
+    fIndices->Add(daughter[0]->GetID(), AliHFEV0pid::kRecoElectron);
+  }
+  if(!fIndices->Find(daughter[1]->GetID())){
+    AliDebug(1, Form("Gamma identified, daughter IDs: %d,%d", daughter[1]->GetID(), daughter[1]->GetID()));
+    fElectrons->Add(daughter[1]);
+    fIndices->Add(daughter[1]->GetID(), AliHFEV0pid::kRecoElectron);
+  }
+  return kTRUE;
+}
+
+
+
+//____________________________________________________________
+Bool_t AliHFEV0pid::IsK0s(TObject *v0){
+  //
+  // Identify K0s
+  //
+  const Double_t kK0smass=TDatabasePDG::Instance()->GetParticle(kK0Short)->Mass();  // PDG K0s mass
+  AliVTrack* daughter[2];
+  Int_t pIndex = 0, nIndex = 0;
+  Double_t invMass = 0.;
+  if(IsESDanalysis()){
+    // ESD - cut V0
+    AliESDv0 *esdV0 = dynamic_cast<AliESDv0 *>(v0);
+    if(!CutV0(esdV0, kRecoK0s)) return kFALSE; 
+    invMass = esdV0->GetEffMass(AliPID::kPion, AliPID::kPion);
+    pIndex = esdV0->GetPindex();
+    nIndex = esdV0->GetNindex();
+  } else {
+    // AOD Analysis - not possible to cut
+    AliAODv0 *aodV0 = dynamic_cast<AliAODv0 *>(v0);
+    pIndex = aodV0->GetPosID();
+    nIndex = aodV0->GetNegID();
+    invMass = aodV0->MassK0Short();
+  }
+  daughter[0] = dynamic_cast<AliVTrack *>(fInputEvent->GetTrack(pIndex));
+  daughter[1] = dynamic_cast<AliVTrack *>(fInputEvent->GetTrack(nIndex));
+  if(!daughter[0] || !daughter[1]) return kFALSE;
+
+  // Get Invariant mass and chi2/ndf 
+  AliKFParticle *kfMother = CreateMotherParticle(daughter[0], daughter[1], TMath::Abs(kPiPlus), TMath::Abs(kPiPlus));
+  kfMother->SetProductionVertex(*fPrimaryVertex);
+  kfMother->SetMassConstraint(kK0smass, 0.);
+  Double_t ndf = kfMother->GetNDF();
+  Double_t chi2 = kfMother->GetChi2();
+  delete kfMother; 
+
+  if(fQA) fQA->Fill("h_chi2_K0s", chi2/ndf);
+  if(chi2/ndf > 5) return kFALSE;
+  Double_t mPt = kfMother->GetPt();
+  fQA->Fill("h_Pt_K0", mPt);
+  Int_t ptBin = (int)(mPt*10.0);
+  fQA->Fill("h_InvMassK0_pt", ptBin+1, invMass);
+
+  if(fQA) fQA->Fill("h_InvMassK0s", invMass);
+
+  if(invMass < 0.485 || invMass > 0.51) return kFALSE; 
+  AliDebug(1, Form("K0 identified, daughter IDs: %d,%d", daughter[0]->GetID(), daughter[1]->GetID()));
+
+  // Identified gamma - store tracks in the electron containers
+  if(!fIndices->Find(daughter[0]->GetID())){
+    AliDebug(1, Form("Adding K0 Pion track with ID %d", daughter[0]->GetID()));
+    fPionsK0->Add(daughter[0]);
+    fIndices->Add(daughter[0]->GetID(), AliHFEV0pid::kRecoPionK0);
+  }
+  if(!fIndices->Find(daughter[1]->GetID())){
+    AliDebug(1, Form("Adding K0 Pion track with ID %d", daughter[1]->GetID()));
+    fPionsK0->Add(daughter[1]);
+    fIndices->Add(daughter[1]->GetID(), AliHFEV0pid::kRecoPionK0);
+  }
+  return kTRUE; 
+}
+
+//____________________________________________________________
+Bool_t AliHFEV0pid::IsPhi(TObject *v0){
+  //
+  // Identify Phi - very preliminary - requires diffrent approach (V0 fnder is not effective)
+  //
+
+  //const Double_t kPhiMass=TDatabasePDG::Instance()->GetParticle(333)->Mass();  // PDG phi mass
+  //AliVTrack* daughter[2];
+  //AliKFParticle *mother = NULL;
+  //Double_t invMass = 0.;
+  Int_t pIndex = 0, nIndex = 0;
+  if(IsESDanalysis()){
+    // ESD - cut V0
+    AliESDv0 *esdV0 = dynamic_cast<AliESDv0 *>(v0);
+    if(!CutV0(esdV0, kRecoPhi)) return kFALSE; 
+    if(LooseRejectGamma(esdV0) || LooseRejectK0(esdV0)) return kFALSE;
+    pIndex = esdV0->GetPindex();
+    nIndex = esdV0->GetNindex();
+  } else {
+    // PRELIMINARY - !!!
+    // AOD Analysis - not possible to cut
+  } 
+
+  return kTRUE;
+}
+
+//____________________________________________________________
+Bool_t AliHFEV0pid::IsLambda(TObject *v0){
+  //
+  // Identify Lambda
+  //
+  const Double_t kL0mass=TDatabasePDG::Instance()->GetParticle(kLambda0)->Mass();  // PDG lambda mass
+  AliVTrack* daughter[2];
+  Int_t pIndex = 0, nIndex = 0;
+  AliKFParticle *mother[2] = {NULL, NULL};
+  Float_t dMass[2]; // lambda mass difference for the two hypoteses
+  //Int_t   lambda = 0; // [1] for lambda and [-1] for anti-lambda
+  Double_t chi2 = 0.;
+
+  Double_t invMass = 0.;
+  Double_t invMassEOD = 0;
+  if(IsESDanalysis()){
+    // ESD - cut V0
+    AliESDv0 *esdV0 = dynamic_cast<AliESDv0 *>(v0);
+    if(!CutV0(esdV0, kRecoLambda)) return kFALSE; 
+    if(LooseRejectK0(esdV0) || LooseRejectGamma(esdV0)) return kFALSE;
+    pIndex = esdV0->GetPindex();
+    nIndex = esdV0->GetNindex();
+    
+    //invMass = esdV0->GetEffMass(AliPID::kPion, AliPID::kPion);
+
+  } else {
+    // PRELIMINARY - !!!
+    // AOD Analysis - not possible to cut
+    
+    // again - two cases as above
+    AliAODv0 *aodV0 = dynamic_cast<AliAODv0 *>(v0);
+    pIndex = aodV0->GetPosID();
+    nIndex = aodV0->GetNegID();
+    invMassEOD = aodV0->MassLambda();
+  }
+
+  daughter[0] = dynamic_cast<AliVTrack *>(fInputEvent->GetTrack(pIndex));
+  daughter[1] = dynamic_cast<AliVTrack *>(fInputEvent->GetTrack(nIndex));
+  if(!daughter[0] || !daughter[1]) return kFALSE;
+
+  //
+  // now - go over two case - Lambda and AntiLambda
+  // choose the on ewhere the resulting lambda mass is close to the
+  // expected value and at the same time points closer to the primary vertex in XY plane
+  //
+  // A)      lambda -> proton + negative-pion
+  // B) anti-lambda -> anti-proton + positive-pion
+  //    
+
+  //
+  // A) :: proton
+  //
+  mother[0] = CreateMotherParticle(daughter[0], daughter[1], TMath::Abs(kProton), TMath::Abs(kPiPlus));
+  AliHFELambdaInf lambda0(mother[0], fPrimaryVertex);
+
+  // Undo changes
+  *fPrimaryVertex -= *mother[0];
+  AddTrackToKFVertex(daughter[0], TMath::Abs(kProton));
+  AddTrackToKFVertex(daughter[1], TMath::Abs(kPiPlus));
+
+  //
+  // B) :: anti-proton
+  //
+  mother[1] = CreateMotherParticle(daughter[0], daughter[1], TMath::Abs(kPiPlus), TMath::Abs(kProton));
+  AliHFELambdaInf lambda1(mother[1], fPrimaryVertex);
+
+  // qa histograms
+  dMass[0] = lambda0.GetInvariantMass() - kL0mass;
+  dMass[1] = lambda1.GetInvariantMass() - kL0mass;
+  fQA->Fill("h_L0_dca_v_dMass", dMass[0], lambda0.GetDistanceFromPrimaryVertex());
+  fQA->Fill("h_L0_dca_v_dMass", dMass[1], lambda1.GetDistanceFromPrimaryVertex());
+
+  //
+  // decide on the true Lambda candidate bsaed on
+  // - mass difference
+  // - vertex dca  (testing needed first)
+  //
+  AliHFELambdaInf *lambdaInf[2] = {&lambda0, &lambda1};
+  Bool_t isLambda = kFALSE;
+  Int_t index = -1;
+  index = (dMass[0] <dMass[1]) ? 0 : 1;
+  invMass = lambdaInf[index]->GetInvariantMass();
+  chi2 = lambdaInf[index]->GetChi2NDF();
+  //if(!IsESDanalysis()){
+  //  invMass = invMassEOD;
+  //}
+  //else{
+  //  invMass = mother[index]->GetMass();
+  //}
+  if(fQA) fQA->Fill("h_chi2_Lambda", chi2);
+  if(chi2 < 3){
+    if(fQA) fQA->Fill("h_InvMassLambda", invMass);
+    Double_t mPt = mother[index]->GetPt();
+    fQA->Fill("h_Pt_Lambda", mPt);
+    Int_t ptBin = (int)(mPt*10.0);
+    fQA->Fill("h_InvMassLambda_pt", ptBin+1, invMass);
+    
+    // cut on the invariant mass for the proton and pion selection
+    if(invMass > 1.11 || invMass < 1.12){
+      // Identified lambdas - store the protons and pions and update primary vertex
+      *fPrimaryVertex += *mother[index];
+    
+      // lambda
+      if(0 == index){
+        if(!fIndices->Find(daughter[0]->GetID())){
+               fProtons->Add(daughter[0]);
+               fIndices->Add(daughter[0]->GetID(), AliHFEV0pid::kRecoProton);
+        }
+        if(!fIndices->Find(daughter[1]->GetID())){
+               fPionsL->Add(daughter[1]);
+               fIndices->Add(daughter[1]->GetID(), AliHFEV0pid::kRecoPionL);
+        }
+      }
+      // antilambda
+      if(1 == index){
+        if(!fIndices->Find(daughter [1]->GetID())){
+               fProtons->Add(daughter[1]);
+               fIndices->Add(daughter[1]->GetID(), AliHFEV0pid::kRecoProton);
+        }
+        if(!fIndices->Find(daughter [0]->GetID())){
+               fPionsL->Add(daughter[0]);
+               fIndices->Add(daughter [0]->GetID(), AliHFEV0pid::kRecoPionL);
+        }
+      }
+      isLambda = kTRUE;
+    }
+  }
+
+  if(!isLambda){
+    // Add the daughters again to the primary vertex
+    AddTrackToKFVertex(daughter[0], TMath::Abs(kPiPlus));
+    AddTrackToKFVertex(daughter[1], TMath::Abs(kProton));
+  }
+  // remove the objects
+  for(Int_t i=0; i<2; ++i){
+    if (mother[i]) delete mother[i];
+  }
+  return isLambda;
+}
+
+//____________________________________________________________
+AliKFParticle *AliHFEV0pid::CreateMotherParticle(AliVTrack *pdaughter, AliVTrack *ndaughter, Int_t pspec, Int_t nspec){
+  //
+  // Creates a mother particle
+  //
+  AliKFParticle pkfdaughter(*pdaughter, pspec);
+  AliKFParticle nkfdaughter(*ndaughter, nspec);
+
+  // check if the daughter particles are coming from the primary vertex
+  if(IsESDanalysis()){
+    // ESD Analyis
+    const AliESDVertex *esdvertex = dynamic_cast<const AliESDVertex *>(fInputEvent->GetPrimaryVertex());
+    UShort_t *contrib = esdvertex->GetIndices();
+
+    Int_t nfound = 0;
+    for(Int_t id = 0; id < esdvertex->GetNIndices(); id++){
+      if(contrib[id] == pdaughter->GetID()){
+        *fPrimaryVertex -= pkfdaughter;
+        nfound++;
+      }
+      if(contrib[id] == ndaughter->GetID()){
+        *fPrimaryVertex -= nkfdaughter;
+        nfound++;
+      }
+      if(nfound == 2) break;
+    }
+  } else {
+    // AOD Analysis: AOD Vertex 
+    const AliAODVertex *aodvertex = dynamic_cast<const AliAODVertex *>(fInputEvent->GetPrimaryVertex());
+    if(aodvertex->HasDaughter(pdaughter))
+      *fPrimaryVertex -= pkfdaughter;
+    if(aodvertex->HasDaughter(ndaughter))
+      *fPrimaryVertex -= nkfdaughter;
+  }
+
+  // Create the mother particle and add them to the primary vertex
+  AliKFParticle *mother = new AliKFParticle(pkfdaughter, nkfdaughter);
+  *fPrimaryVertex += *mother;
+
+  return mother;
+}
+
+//____________________________________________________________
+void AliHFEV0pid::AddTrackToKFVertex(AliVTrack *track, Int_t species){
+  //
+  // Add track to the primary vertex (if it was used in the vertex
+  // calculation)
+  //
+  Bool_t isAdd = kFALSE;
+  if(IsESDanalysis()){
+     const AliESDVertex *esdvertex = dynamic_cast<const AliESDVertex *>(fInputEvent->GetPrimaryVertex());
+    UShort_t *contrib = esdvertex->GetIndices();
+    for(Int_t id = 0; id < esdvertex->GetNIndices(); id++){
+      if(contrib[id] == track->GetID()){
+        isAdd = kTRUE;
+        break;
+      }
+    }
+  } else {
+    const AliAODVertex *aodvertex = dynamic_cast<const AliAODVertex *>(fInputEvent->GetPrimaryVertex());
+    if(aodvertex->HasDaughter(track)) isAdd = kTRUE;
+  }
+  if(isAdd){
+    AliKFParticle kftrack(*track, species);
+    *fPrimaryVertex += kftrack;
+  }
+}
+
+//____________________________________________________________
+Bool_t AliHFEV0pid::CutV0(AliESDv0 *v0, Int_t V0species){
+  //
+  // Cut the V0
+  //
+  Int_t cutRequired = 0;
+  // For cut always take min and max
+  Double_t  cutCosPoint[2] = {0., 0.}, 
+  cutDCA[2] = {0., 0.}, 
+  cutProdVtx[2] = {0., 0.},
+       cutOpAng[2] = {0., 0.},
+       cutPsiPair[2] = {0., 0.};
+         
+  switch(V0species){
+  case kRecoGamma:
+    cutCosPoint[1] = 0.03;
+    SETBIT(cutRequired, 1);
+    cutDCA[1] = 0.25;
+    SETBIT(cutRequired, 3);
+    cutProdVtx[0] = 6;
+    SETBIT(cutRequired, 4);
+    cutOpAng[1] = 0.1;
+    SETBIT(cutRequired, 7);
+    cutPsiPair[1] = 0.05;
+    SETBIT(cutRequired, 9);
+    break;
+  case kRecoK0s:
+    cutCosPoint[1] = 0.03;
+    SETBIT(cutRequired, 1);
+    cutDCA[1] = 0.1;
+    SETBIT(cutRequired, 3);
+    cutProdVtx[1] = 8.1;
+    SETBIT(cutRequired, 5);
+    break;
+  case kRecoPhi:
+    break;
+  case kRecoLambda:
+    cutCosPoint[1] = 0.03;
+    SETBIT(cutRequired, 1);
+    cutDCA[1] = 0.2;
+    SETBIT(cutRequired, 3);
+    cutProdVtx[1] = 24;
+    SETBIT(cutRequired, 5);
+    break;
+  default:
+    // unidentified, return
+    return kFALSE;
+  };
+  
+  Char_t hname[256];
+  const Char_t *specname[4] = {"Gamma", "K0s", ", Phi", "Lambda"};
+  sprintf(hname, "h_cutEfficiency%s", specname[V0species-1]);
+
+  // Cut on pointing angle
+  Double_t cosPoint = v0->GetV0CosineOfPointingAngle();
+  if(TESTBIT(cutRequired, 0) && TMath::ACos(cosPoint) < cutCosPoint[0]) return kFALSE; 
+  if(fQA) fQA->Fill(hname, 0);
+  if(TESTBIT(cutRequired, 1) && TMath::ACos(cosPoint) > cutCosPoint[1]) return kFALSE;
+  if(fQA) fQA->Fill(hname, 1); 
+
+  // Cut on DCA between daughters
+  Double_t dca = v0->GetDcaV0Daughters();
+  if(TESTBIT(cutRequired, 2) && dca < cutDCA[0]) return kFALSE;
+  if(fQA) fQA->Fill(hname, 2);
+  if(TESTBIT(cutRequired, 3) && dca > cutDCA[1]) return kFALSE;
+  if(fQA) fQA->Fill(hname, 3);
+
+  // Cut on reconstructed verted position
+  Double_t x, y, z; 
+  v0->GetXYZ(x,y,z);
+  Double_t r = TMath::Sqrt(x*x + y*y);
+  if(TESTBIT(cutRequired, 4) && r < cutProdVtx[0]) return kFALSE;
+  if(fQA) fQA->Fill(hname, 4);
+  if(TESTBIT(cutRequired, 5) && r > cutProdVtx[1]) return kFALSE;
+  if(fQA) fQA->Fill(hname, 5);
+
+  //Cut on Opening angle (conversions only)
+  if(TESTBIT(cutRequired, 6) && OpenAngle(v0) < cutOpAng[0]) return kFALSE;
+  if(fQA) fQA->Fill(hname, 6);
+  if(TESTBIT(cutRequired, 7) && OpenAngle(v0) > cutOpAng[1]) return kFALSE;
+  if(fQA) fQA->Fill(hname, 7);
+
+  //Cut on PsiPair angle (conversons only)
+  if(TESTBIT(cutRequired, 8) && PsiPair(v0) < cutPsiPair[0]) return kFALSE;
+  if(fQA) fQA->Fill(hname, 8);
+  if(TESTBIT(cutRequired, 9) && PsiPair(v0) > cutPsiPair[1]) return kFALSE;
+  if(fQA) fQA->Fill(hname, 9);
+  return kTRUE;
+}
+
+//____________________________________________________________
+Bool_t AliHFEV0pid::CutESDtrack(AliESDtrack *track){
+  // 
+  // Single track cuts
+  //
+  // Hard coaded cut values for the beginning 
+  //
+
+  if(!track) return kFALSE;
+  
+  // status word
+  ULong_t status = track->GetStatus();
+
+  // DCA - to Vertex R & Z
+  Float_t dcaR = -1.;
+  Float_t dcaZ = -1.;
+  track->GetImpactParameters(dcaR, dcaZ);
+  //if(dcaR > 4.0) return kFALSE;
+  //if(dcaZ > 10.0) return kFALSE;
+
+  // No. of TPC clusters
+  if(track->GetTPCNcls() < 80) return kFALSE;
+
+  // TPC refit
+  if(!(status & AliESDtrack::kTPCrefit)) return kFALSE;
+
+  // Chi2 per TPC cluster
+  Int_t nTPCclusters = track->GetTPCclusters(0);
+  Float_t chi2perTPCcluster = track->GetTPCchi2()/Float_t(nTPCclusters);
+  if(chi2perTPCcluster > 3.5) return kFALSE;
+
+  // TPC cluster ratio
+  Float_t cRatioTPC = track->GetTPCNclsF() > 0. ? static_cast<Float_t>(track->GetTPCNcls())/static_cast<Float_t> (track->GetTPCNclsF()) : 1.;
+  if(cRatioTPC < 0.6) return kFALSE;
+
+  // kinks
+  if(track->GetKinkIndex(0) != 0) return kFALSE;
+
+  // Covariance matrix - TO BE RECONSIDERED
+  Double_t extCov[15];
+  track->GetExternalCovariance(extCov);
+  //if(extCov[0]  > 2. ) return kFALSE;
+  //if(extCov[2]  > 2. ) return kFALSE;
+  //if(extCov[5]  > 0.5) return kFALSE;
+  //if(extCov[9]  > 0.5) return kFALSE;
+  //if(extCov[14] > 2. ) return kFALSE;
+  
+  // pt
+  if(track->Pt() < 0.1 || track->Pt() > 100) return kFALSE;
+
+  // eta
+  if(TMath::Abs(track->Eta()) > 0.9) return kFALSE;
+
+  // the track made it through! :-)
+  return kTRUE;
+}
+
+//_________________________________________________
+Bool_t AliHFEV0pid::LooseRejectK0(AliESDv0 * const v0) const {
+  //
+  // Reject K0 based on loose cuts
+  //
+  Double_t mass = v0->GetEffMass(AliPID::kPion, AliPID::kPion);
+  if(mass > 0.494 && mass < 0.501) return kTRUE;
+  return kFALSE;
+}
+
+//_________________________________________________
+Bool_t AliHFEV0pid::LooseRejectLambda(AliESDv0 * const v0) const {
+  //
+  // Reject Lambda based on loose cuts
+  //
+  Double_t mass1 = v0->GetEffMass(AliPID::kPion, AliPID::kProton);
+  Double_t mass2 = v0->GetEffMass(AliPID::kProton, AliPID::kPion);
+  
+  if(mass1 > 1.1 && mass1 < 1.12) return kTRUE;
+  if(mass2 > 1.1 && mass2 < 1.12) return kTRUE;
+  return kFALSE;
+}
+
+//_________________________________________________
+Bool_t AliHFEV0pid::LooseRejectGamma(AliESDv0 * const v0) const {
+  //
+  // Reject Lambda based on loose cuts
+  //
+  //Double_t mass = v0->GetEffMass(AliPID::kElectron, AliPID::kElectron);
+  // DEBUG temporary solution, see the comment in GetEffMass
+  Double_t mass = GetEffMass(v0, AliPID::kElectron, AliPID::kElectron);
+  //..
+  if(mass < 0.02) return kTRUE;
+  return kFALSE;
+}
+
+//_________________________________________________
+Float_t AliHFEV0pid::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;
+
+  
+  Float_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);
+}
+
+//_________________________________________________
+Float_t AliHFEV0pid::PsiPair(AliESDv0 *v0) {
+  //
+  // Angle between daughter momentum plane and plane 
+  // 
+  Float_t magField = fInputEvent->GetMagneticField();
+
+  Int_t pIndex = v0->GetPindex();
+  Int_t nIndex = v0->GetNindex();
+
+  AliESDtrack* daughter[2];
+
+  daughter[0] = dynamic_cast<AliESDtrack *>(fInputEvent->GetTrack(pIndex));
+  daughter[1] = dynamic_cast<AliESDtrack *>(fInputEvent->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]);
+    
+  Float_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; 
+}
+
+//____________________________________________________________
+AliHFEV0pid::AliHFEV0pidTrackIndex::AliHFEV0pidTrackIndex():
+    fNElectrons(0)
+  , fNPionsK0(0)
+  , fNPionsL(0)
+  , fNKaons(0)
+  , fNProtons(0)
+  , fIndexElectron(NULL)
+  , fIndexPionK0(NULL)
+  , fIndexPionL(NULL)
+  , fIndexKaon(NULL)
+  , fIndexProton(NULL)
+{
+  //
+  // Default Constructor
+  //
+}
+
+//____________________________________________________________
+AliHFEV0pid::AliHFEV0pidTrackIndex::~AliHFEV0pidTrackIndex(){
+  //
+  // Destructor
+  //
+  if(fIndexElectron) delete[] fIndexElectron;
+  if(fIndexPionK0) delete[] fIndexPionK0;
+  if(fIndexPionL) delete[] fIndexPionL;
+  if(fIndexProton) delete[] fIndexProton;
+}
+
+//____________________________________________________________
+void AliHFEV0pid::AliHFEV0pidTrackIndex::Flush(){
+  //
+  // Reset containers
+  //
+  
+  if(fIndexElectron) delete[] fIndexElectron;
+  fIndexElectron = NULL;
+  if(fIndexPionK0) delete[] fIndexPionK0;
+  fIndexPionK0 = NULL;
+  if(fIndexPionL) delete[] fIndexPionL;
+  fIndexPionL = NULL;
+  if(fIndexKaon) delete[] fIndexKaon;
+  fIndexKaon = NULL;
+  if(fIndexProton) delete[] fIndexProton;
+  fIndexProton = NULL;
+
+  fNElectrons = 0;
+  fNPionsK0 = 0;
+  fNPionsL = 0;
+  fNKaons = 0;
+  fNProtons = 0;
+}
+
+//____________________________________________________________
+void AliHFEV0pid::AliHFEV0pidTrackIndex::Init(Int_t capacity){
+  //
+  // Initialize container
+  //
+  fIndexElectron = new Int_t[capacity];
+  fIndexPionK0 = new Int_t[capacity];
+  fIndexPionL = new Int_t[capacity];
+  fIndexProton = new Int_t[capacity];
+}
+
+//____________________________________________________________
+void AliHFEV0pid::AliHFEV0pidTrackIndex::Add(Int_t index, Int_t species){
+  //
+  // Add new index to the list of identified particles
+  //
+  switch(species){
+    case AliHFEV0pid::kRecoElectron:
+      fIndexElectron[fNElectrons++] = index;
+      break;
+    case AliHFEV0pid::kRecoPionK0:
+      fIndexPionK0[fNPionsK0++] = index;
+      break;
+    case AliHFEV0pid::kRecoPionL:
+      fIndexPionL[fNPionsL++] = index;
+      break;
+    case AliHFEV0pid::kRecoProton:
+      fIndexProton[fNProtons++] = index;
+      break;
+  };
+}
+
+//____________________________________________________________
+Bool_t AliHFEV0pid::AliHFEV0pidTrackIndex::Find(Int_t index, Int_t species) const {
+  //
+  // Find track index in the specific sample of particles
+  //
+
+  Int_t *container = NULL; Int_t n = 0;
+  switch(species){
+  case AliHFEV0pid::kRecoElectron:
+    container = fIndexElectron;
+    n = fNElectrons;
+    break;
+  case AliHFEV0pid::kRecoPionK0:
+    container = fIndexPionK0;
+    n = fNPionsK0;
+    break;
+  case AliHFEV0pid::kRecoPionL:
+    container = fIndexPionL;
+    n = fNPionsL;
+    break;
+  case AliHFEV0pid::kRecoProton:
+    container = fIndexProton;
+    n = fNProtons;
+    break;
+  }
+  if(!container) return kFALSE;
+  if(n == 0) return kFALSE;
+  Bool_t found = kFALSE;
+  for(Int_t i = 0; i < n; i++){
+    if(container[i] == index){
+      found = kTRUE;
+      break;
+    }
+  }
+  return found;
+}
+
+//____________________________________________________________
+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);
+}
+
+//____________________________________________________________
+AliHFEV0pid::AliHFELambdaInf::AliHFELambdaInf(AliKFParticle *mother, AliKFVertex * const primaryVertex):
+  fInvariantMass(0.),
+  fChi2NDF(0.),
+  fDistVtx(0.)
+{
+  //
+  // Constructor
+  // Fill infos
+  //
+  const Double_t kL0mass=TDatabasePDG::Instance()->GetParticle(kLambda0)->Mass();  // PDG lambda mass
+  fInvariantMass = mother->GetMass();
+  // distance frm the privary vertex and mass difference for the (A) case
+  fDistVtx = mother->GetDistanceFromVertex(*primaryVertex);
+  // apply constraints for the fit
+  mother->SetMassConstraint(kL0mass, 0.);
+  mother->SetProductionVertex(*primaryVertex);
+  fChi2NDF = mother->GetChi2()/mother->GetNDF();
+}
+//____________________________________________________________
+AliHFEV0pid::AliHFELambdaInf::~AliHFELambdaInf(){
+  //
+  // destructor
+  //
+}
+//____________________________________________________________
+// DEBUG
+//____________________________________________________________
+Double_t AliHFEV0pid::GetEffMass(AliESDv0 *v0, UInt_t p1, UInt_t p2) const{
+  //
+  // TEMPORARY - this function should become obsolete with v4-18-Rev-10 or 11
+  // calculate effective mass
+  //
+  const Double_t kpmass[5] = {TDatabasePDG::Instance()->GetParticle(kElectron)->Mass(),
+                            TDatabasePDG::Instance()->GetParticle(kMuonMinus)->Mass(),
+                            TDatabasePDG::Instance()->GetParticle(kPiPlus)->Mass(),
+                            TDatabasePDG::Instance()->GetParticle(kKPlus)->Mass(),
+                             TDatabasePDG::Instance()->GetParticle(kProton)->Mass()}; // float
+  if (p1>4) return -1;
+  if (p2>4) return -1;
+  Double_t mass1 = kpmass[p1]; // float
+  Double_t mass2 = kpmass[p2]; // float  
+
+  Double_t pMom[3];
+  Double_t nMom[3];
+  
+  v0->GetPPxPyPz(pMom[0], pMom[1], pMom[2]);
+  v0->GetNPxPyPz(nMom[0], nMom[1], nMom[2]);
+  
+
+  const Double_t *m1 = pMom;
+  const Double_t *m2 = nMom;
+  //
+  //if (fRP[p1]+fRM[p2]<fRP[p2]+fRM[p1]){
+  //  m1 = fPM;
+  //  m2 = fPP;
+  //}
+  //
+  Double_t e1    = TMath::Sqrt(mass1*mass1+
+                              m1[0]*m1[0]+
+                              m1[1]*m1[1]+
+                              m1[2]*m1[2]); // float
+  Double_t e2    = TMath::Sqrt(mass2*mass2+
+                              m2[0]*m2[0]+
+                              m2[1]*m2[1]+
+                              m2[2]*m2[2]); // float
+  Double_t mass =  
+    (m2[0]+m1[0])*(m2[0]+m1[0])+
+    (m2[1]+m1[1])*(m2[1]+m1[1])+
+    (m2[2]+m1[2])*(m2[2]+m1[2]); // float
+
+  
+  mass = (e1+e2)*(e1+e2)-mass;
+  //if(mass < 0.00001){
+  //  printf("-D: mass: %f\n", mass);
+  // }
+  mass = TMath::Sqrt(mass);
+  return mass;
+}
diff --git a/PWG3/hfe/AliHFEV0pid.h b/PWG3/hfe/AliHFEV0pid.h
new file mode 100644 (file)
index 0000000..1413ead
--- /dev/null
@@ -0,0 +1,175 @@
+/**************************************************************************
+* 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.                  *
+**************************************************************************/
+//
+// Utility class for V0 PID
+// Provides smaples of electrons, pions and protons
+// More information can be found in the implementation file
+//
+#ifndef ALIHFEV0PID_H
+#define ALIHFEV0PID_H
+
+#ifndef ROOT_TObject
+#include <TObject.h>
+#endif
+
+#ifndef ALIHFECOLLECTION_H
+#include "AliHFEcollection.h"
+#endif
+
+class TObjArray;
+class TList;
+
+class AliESDv0;
+class AliESDtrack;
+class AliKFParticle;
+class AliKFVertex;
+class AliVEvent;
+class AliVTrack;
+
+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();
+
+    Double_t  GetEffMass(AliESDv0 *v0, UInt_t p1, UInt_t p2) const;
+
+    void Process(AliVEvent * const inputEvent);
+    Int_t ProcessV0(TObject *v0);
+    void Flush();
+
+    void InitQA();
+    inline TList *GetListOfQAhistograms();
+
+    TObjArray *GetListOfElectrons() const { return fElectrons; }
+    TObjArray *GetListOfPionsK0() const { return fPionsK0; }
+    TObjArray *GetListOfPionsL() const { return fPionsL; }
+    TObjArray *GetListOfKaons() const { return fKaons; }
+    TObjArray *GetListOfProtons() const { return fProtons; }
+
+    Bool_t IsAODanalysis() const { return TestBit(kAODanalysis); }
+    Bool_t IsESDanalysis() const { return !TestBit(kAODanalysis); }
+    void SetAODanalysis(Bool_t isAOD = kTRUE) { SetBit(kAODanalysis, isAOD); };
+    void SetESDanalysis(Bool_t isESD = kTRUE) { SetBit(kAODanalysis, !isESD); }; 
+ private:
+    Float_t PsiPair(AliESDv0 *esdv0);//angle between daughters in plane perpendicular to magnetic field (characteristically around zero for conversions)
+    Float_t OpenAngle(AliESDv0 *esdv0) const;//opening angle between V0 daughters; close to zero for conversions
+   
+
+  protected:
+    enum{
+      kAODanalysis = BIT(14)
+    };
+    AliKFParticle *CreateMotherParticle(AliVTrack *pdaughter, AliVTrack *ndaughter, Int_t pspec, Int_t nspec);
+    void AddTrackToKFVertex(AliVTrack *track, Int_t species);
+
+    Bool_t IsGammaConv(TObject *v0);
+    Bool_t IsK0s(TObject *v0);
+    Bool_t IsPhi(TObject *v0);
+    Bool_t IsLambda(TObject *v0);
+
+    Bool_t CutESDtrack(AliESDtrack *track);
+    Bool_t CutV0(AliESDv0 *v0, Int_t species);
+
+    Bool_t LooseRejectK0(AliESDv0 * const v0) const;
+    Bool_t LooseRejectLambda(AliESDv0 * const v0) const;
+    Bool_t LooseRejectGamma(AliESDv0 * const v0) const;
+
+  private:
+    class AliHFEV0pidTrackIndex{
+      public:
+        AliHFEV0pidTrackIndex();
+        ~AliHFEV0pidTrackIndex();
+        void Init(Int_t capacity);
+        void Add(Int_t index, Int_t species);
+        Bool_t Find(Int_t index) const;
+        Bool_t Find(Int_t index, Int_t species) const;
+        Int_t GetNumberOfElectrons() const { return fNElectrons; };
+        Int_t GetNumberOfPionsK0() const { return fNPionsK0; };
+        Int_t GetNumberOfPionsL() const { return fNPionsL; };
+             Int_t GetNumberOfKaons() const { return fNKaons; };
+        Int_t GetNumberOfProtons() const { return fNProtons; };
+        void Flush();
+
+      private:
+        AliHFEV0pidTrackIndex(const AliHFEV0pidTrackIndex &ref);
+        AliHFEV0pidTrackIndex &operator=(const AliHFEV0pidTrackIndex &ref);
+        Int_t fNElectrons;        // Number of identified electrons
+        Int_t fNPionsK0;          // Number of identified pions from K0s
+        Int_t fNPionsL;           // Lumber of identified pions from Lambda
+             Int_t fNKaons;            // Number of identified kaons
+        Int_t fNProtons;          // Number of identified protons
+        Int_t *fIndexElectron;    // Indices of identified electrons
+        Int_t *fIndexPionK0;      // Indices of identified pions from K0s
+        Int_t *fIndexPionL;       // Indices of identified pions from Lambda
+             Int_t *fIndexKaon;        // Indices of identified kaons
+        Int_t *fIndexProton;      // Indices of identified protons
+    };
+
+    class AliHFELambdaInf{
+      public:
+        AliHFELambdaInf(AliKFParticle *track, AliKFVertex * const primaryVertex);
+        ~AliHFELambdaInf();
+
+        Double_t GetInvariantMass() const { return fInvariantMass; };
+        Double_t GetChi2NDF() const { return fChi2NDF; };
+        Double_t GetDistanceFromPrimaryVertex() const { return fDistVtx; };
+      private:
+        Double_t fInvariantMass;    // invariant mass before constraint
+        Double_t fChi2NDF;          // chi2/ndf after constraints
+        Double_t fDistVtx;          // Distance to primary Vertex
+    };
+
+    AliHFEV0pid(const AliHFEV0pid &ref);
+    AliHFEV0pid&operator=(const AliHFEV0pid &ref);
+
+    AliVEvent   *fInputEvent;        // Input Event
+    AliKFVertex *fPrimaryVertex;     // Primary Vertex
+    TObjArray   *fElectrons;         // List of Electron tracks coming from Conversions
+    TObjArray   *fPionsK0;           // List of Pion tracks coming from K0
+    TObjArray   *fPionsL;            // List of Pion tracks coming from L
+    TObjArray   *fKaons;             // List of Kaon tracks from Phi decay
+    TObjArray   *fProtons;           // List of Proton Tracks coming from Lambdas
+    AliHFEV0pidTrackIndex *fIndices; // Container for Track indices
+    AliHFEcollection *fQA;           // Collection of QA histograms
+
+    ClassDef(AliHFEV0pid, 1)          // V0 PID Class
+
+};
+
+//____________________________________________________________
+TList *AliHFEV0pid::GetListOfQAhistograms(){
+  //
+  // Get QA histograms
+  //
+  if(fQA)
+    return fQA->GetList();
+  return NULL;
+}
+#endif
diff --git a/PWG3/hfe/AliHFEV0pidMC.cxx b/PWG3/hfe/AliHFEV0pidMC.cxx
new file mode 100644 (file)
index 0000000..3f6f618
--- /dev/null
@@ -0,0 +1,199 @@
+/**************************************************************************
+* 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 to benchmark the V0 pid capabilties
+// runs over reconstructed V0 candidates and uses MC information for 
+// further analysis [purity, PID perfortmance]
+//
+// authors:
+//    Matus Kalisky <matus.kalisky@cern.ch>
+//
+
+#include "TIterator.h"
+
+#include "AliMCEvent.h"
+#include "AliVParticle.h"
+#include "AliESDtrack.h"
+#include "AliMCParticle.h"
+
+#include "AliHFEV0pidMC.h"
+ClassImp(AliHFEV0pidMC)
+
+//____________________________________________________________
+  AliHFEV0pidMC::AliHFEV0pidMC():
+    fMC(0x0)
+    , fColl(0x0)
+{
+  //
+  // default constructor
+  //
+}
+//____________________________________________________________
+AliHFEV0pidMC::~AliHFEV0pidMC(){
+  //
+  // destructor
+  //
+  if(fColl) delete fColl;
+}
+//____________________________________________________________
+void AliHFEV0pidMC::Init(){
+  //
+  // initialize objects
+  //
+  fColl = new AliHFEcollection("V0pidMC", "MC based V0 benchmarking");
+  // QA
+  fColl->CreateTH1F("h_QA_nParticles", "QA on track processing", 10, -0.5, 9.5);
+
+  // before PID
+  fColl->CreateTH1F("h_Electron", "all electron candidates (no MC)", 100, 0.1, 10);
+  fColl->CreateTH1F("h_PionK0", "all K0 pion candidates (no MC)", 100, 0.1, 10);
+  fColl->CreateTH1F("h_PionL", "all Lambda pion candidates (no MC)", 100, 0.1, 10);
+  fColl->CreateTH1F("h_Kaon", "all Kaon candidates (no MC)", 100, 0.1, 10);
+  fColl->CreateTH1F("h_Proton", "all Lambda proton candidates (no MC)", 100, 0.1, 10);
+  
+  fColl->CreateTH1F("h_mis_Electron", "all NON electron candidates (no MC)", 100, 0.1, 10);
+  fColl->CreateTH1F("h_mis_PionK0", "all NON K0 pion candidates (no MC)", 100, 0.1, 10);
+  fColl->CreateTH1F("h_mis_PionL", "all NON Lambda pion candidates (no MC)", 100, 0.1, 10);
+  fColl->CreateTH1F("h_mis_Kaon", "all NON Kaon candidates (no MC)", 100, 0.1, 10);
+  fColl->CreateTH1F("h_mis_Proton", "all NON Lambda proton candidates (no MC)", 100, 0.1, 10);  
+
+  fColl->CreateTH1Fvector1(5, "h_tag_Electron", "electron candidate MC tagged", 100, 0.1, 10);
+  fColl->CreateTH1Fvector1(5, "h_tag_PionK0", "K0 pion candidate MC tagged", 100, 0.1, 10);
+  fColl->CreateTH1Fvector1(5, "h_tag_PionL", "Lambda pion candidate MC tagged", 100, 0.1, 10);
+  fColl->CreateTH1Fvector1(5, "h_tag_Kaon", "kaon candidate MC tagged", 100, 0.1, 10);
+  fColl->CreateTH1Fvector1(5, "h_tag_Proton", "Lambda proton candidate MC tagged", 100, 0.1, 10);
+
+  
+  fColl->BinLogAxis("h_Electron", 0);
+  fColl->BinLogAxis("h_PionK0", 0);
+  fColl->BinLogAxis("h_PionL", 0);
+  fColl->BinLogAxis("h_Kaon", 0);
+  fColl->BinLogAxis("h_Proton", 0);
+  fColl->BinLogAxis("h_mis_Electron", 0);
+  fColl->BinLogAxis("h_mis_PionK0", 0);
+  fColl->BinLogAxis("h_mis_PionL", 0);
+  fColl->BinLogAxis("h_mis_Kaon", 0);
+  fColl->BinLogAxis("h_mis_Proton", 0);
+//   fColl->BinLogAxis(, 0);
+//   fColl->BinLogAxis(, 0);
+//   fColl->BinLogAxis(, 0);
+//   fColl->BinLogAxis(, 0);
+//   fColl->BinLogAxis(, 0);
+  
+}
+//____________________________________________________________
+Bool_t  AliHFEV0pidMC::Process(TObjArray * const particles, Int_t type){
+  //
+  // process the selected V0 daughter tracks
+  //
+  
+  Char_t hname[256] = "";
+  const Char_t *typeName[5] = {"Electron", "PionK0", "PionL", "Kaon", "Proton"};
+  const Int_t  typePID[5] = {0, 2, 2, 3, 4};
+
+  if(!fMC) return kFALSE;
+  if(!particles) return kFALSE;
+  
+  AliVParticle *recTrack = NULL;
+  TIterator *trackIter = particles->MakeIterator(); 
+  while((recTrack = dynamic_cast<AliVParticle *>(trackIter->Next()))){
+    fColl->Fill("h_QA_nParticles", 0);
+    // only ESD for now
+    AliESDtrack *track = dynamic_cast<AliESDtrack *>(recTrack);
+    const AliExternalTrackParam *ext = track->GetOuterParam();
+    if(!ext) continue;
+    // MC label
+    Int_t label = track->GetLabel();
+    if(label <0){
+       fColl->Fill("h_QA_nParticles", 1);
+      continue;
+    }
+    AliMCParticle *mcpD = dynamic_cast<AliMCParticle*>(fMC->GetTrack(label));
+    if(!mcpD){
+      fColl->Fill("h_QA_nParticles", 2);
+      continue;
+    }
+
+    Float_t p = ext->P();
+    //Short_t charge = ext->Charge();
+    Int_t pdgD = mcpD->PdgCode();
+    AliMCParticle *mcpM = dynamic_cast<AliMCParticle*>(fMC->GetTrack(mcpD->GetMother()));
+    if(!mcpM){
+      fColl->Fill("h_QA_nParticles", 3);
+      continue;
+    }
+    //Int_t pdgM = mcpM->PdgCode();
+    // all candidates
+    sprintf(hname, "h_%s", typeName[type]);
+    fColl->Fill(hname, p);
+    Int_t pidD = PDGtoPIDdaughter(pdgD);
+    
+   // all misidentified candidates
+    sprintf(hname, "h_mis_%s", typeName[type]);
+    if(typePID[type] != pidD){
+      fColl->Fill(hname, p);
+    }
+    sprintf(hname, "h_tag_%s", typeName[type]);
+    if(pidD >=0){
+      fColl->Fill(hname, pidD, p);
+    }
+       
+
+    
+  }// .. loop over array
+  
+  
+  return kTRUE;
+}  
+//____________________________________________________________
+Int_t AliHFEV0pidMC::PDGtoPIDdaughter(Int_t pdg) const {
+  //
+  // convert PDG to local pid 
+  //
+  switch (TMath::Abs(pdg)){
+  case 11:
+    return 0;  // electron gamma
+  case 211:
+    return 2; // pion K0 or pion Lambda
+  case 321:
+    return 3; //kaon Phi
+  case 2212:
+    return 4; // proton Lambda
+  default:
+    return -1;
+  };
+  
+  return -1;
+}
+//____________________________________________________________
+Int_t AliHFEV0pidMC::PDGtoPIDmother(Int_t pdg) const {
+  //
+  // convert PDG to local pid
+  //
+  switch (TMath::Abs(pdg)){
+  case 22:
+      return 0; // gamma
+    case 310: 
+    return 1; // K0s
+  case 333:
+    return 2; // Phi
+  case 3122:
+    return 3; // Lambda
+  default:
+    return -1;
+  };
+  
+  return -1;
+}
diff --git a/PWG3/hfe/AliHFEV0pidMC.h b/PWG3/hfe/AliHFEV0pidMC.h
new file mode 100644 (file)
index 0000000..f0c59a8
--- /dev/null
@@ -0,0 +1,69 @@
+/**************************************************************************
+* 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.                  *
+**************************************************************************/
+//
+// Benchmarking class for V0 finder and PID. 
+// Relies on MC information
+// For more see source file
+//
+
+#ifndef ALIHFEV0PIDMC_H
+#define ALIHFEV0PIDMC_H
+
+#ifndef ROOT_TObject
+#include <TObject.h>
+#endif
+
+#ifndef ALIHFECOLLECTION_H
+#include "AliHFEcollection.h"
+#endif
+
+class TList;
+
+class AliMCEvent;
+
+
+class AliHFEV0pidMC : public TObject {
+
+ public:
+  AliHFEV0pidMC();
+  ~AliHFEV0pidMC();
+  
+  void    Init();
+  Bool_t  Process(TObjArray * const array, Int_t type);  
+
+  void     SetMCEvent(AliMCEvent * const mc) { fMC = mc; };
+
+  inline TList* GetListOfQAhistograms();
+
+ private:
+  AliHFEV0pidMC(const AliHFEV0pidMC &);
+  AliHFEV0pidMC &operator=(const AliHFEV0pidMC &);
+  Int_t PDGtoPIDdaughter(Int_t pdg) const;    // convert the PDG code to local PID
+  Int_t PDGtoPIDmother(Int_t pdg) const;      // convert the PDG code to local PID
+
+  AliMCEvent*         fMC;      // MC event
+  AliHFEcollection*   fColl;    // Histogram collection
+   ClassDef(AliHFEV0pidMC, 1)   // QA class for V0 PID
+};
+//____________________________________________________________
+TList *AliHFEV0pidMC::GetListOfQAhistograms(){
+  //
+  // Get QA histograms
+  //
+  if(fColl)
+    return fColl->GetList();
+  return NULL;
+}
+#endif
index 03d23f3..e131bfe 100644 (file)
@@ -26,7 +26,6 @@
 #include <TH2F.h>
 #include <THnSparse.h>
 #include <TProfile.h>
-#include <TList.h>
 #include <TString.h>
 #include <TBrowser.h>
 #include <TMath.h>
@@ -49,14 +48,14 @@ AliHFEcollection::AliHFEcollection():
   // default constructor
   //
 
-  fList = new TList();
+  fList = new THashList();
   if(!fList){
     AliError("Initialization of the list failed");
   }
   else{
     // list is owner of the objects. Once list is deleted, the objects
     // it contains will be deleted too
-    fList->SetOwner(kTRUE);
+    //fList->SetOwner(kTRUE);
   }
   //Printf("%s:%d,%p",(char*)__FILE__,__LINE__,fInstance);
   
@@ -71,14 +70,14 @@ AliHFEcollection::AliHFEcollection(char* name, char* title):
   // constructor
   //
  
-  fList = new TList();
+  fList = new THashList();
   if(!fList){
     AliError("Initialization of the list failed");
   }
   else{
     // list is owner of the objects. Once list is deleted, the objects
     // it contains will be deleted too
-    fList->SetOwner(kTRUE);
+    // fList->SetOwner(kTRUE);
   }
 }
 //___________________________________________________________________
@@ -114,7 +113,10 @@ void AliHFEcollection::Copy(TObject &ref) const {
 
   AliHFEcollection &target = dynamic_cast<AliHFEcollection &>(ref);
 
-  target.fList = fList;          
+  // Clone List Content
+  target.fList = new THashList();          
+  for(Int_t ien = 0; ien < fList->GetEntries(); ien++)
+    target.fList->Add(fList->At(ien)->Clone());
 }
 //___________________________________________________________________
 AliHFEcollection::~AliHFEcollection(){
@@ -122,7 +124,9 @@ AliHFEcollection::~AliHFEcollection(){
   //
   // Destructor
   //
-
+  if(fList)
+    fList->Delete();
+  delete fList;
   AliInfo("DESTRUCTOR");
 }
 //___________________________________________________________________
@@ -283,7 +287,7 @@ TObject* AliHFEcollection::Get(const char* name){
   
 
   if(!CheckObject(name)){
-    AliError(Form("Not possible to return pointer to the object '%s'\n", name));
+    AliWarning(Form("Not possible to return pointer to the object '%s'\n", name));
     return 0;
   }
 
@@ -328,6 +332,10 @@ Bool_t AliHFEcollection::Fill(const char* name, Int_t X, Double_t v){
 }
 //___________________________________________________________________
 Bool_t AliHFEcollection::Fill(const char* name, Int_t X, Int_t Y, Double_t v){
+
+  //
+  // Fill function fir 2 dimensional TH1 arrays
+  //
   
   const char* n = Form("%s_[%d][%d]", name, X, Y);
   TObject *o = Get(n);
@@ -392,12 +400,27 @@ Bool_t AliHFEcollection::CheckObject(const char* name){
   }
   
   if(!fList->FindObject(name)){
-    AliError(Form("Creating or Finding the object '%s' failed\n", name));
+    AliWarning(Form("Creating or Finding the object '%s' failed\n", name));
     return kFALSE;
   }
   return kTRUE;
 }
 //___________________________________________________________________
+Bool_t AliHFEcollection::Sumw2(const char* name){
+  //
+  // Set Sumw2 for the given object
+  //
+  if(!CheckObject(name)){
+    return kFALSE;
+  }
+
+  TObject *o = Get(name);
+  if(o->InheritsFrom("THnSparse")){
+    (dynamic_cast<THnSparse*>(o))->Sumw2();
+  }
+  return kTRUE;
+}
+//___________________________________________________________________
 Bool_t AliHFEcollection::BinLogAxis(const char* name, Int_t dim){
 
   // 
@@ -458,14 +481,24 @@ Long64_t AliHFEcollection::Merge(TCollection *list){
   //
   // Merge the collections
   //
-
-  if(!fList){
-    AliError("AliHFEcollection::Merge : No TList pointer ! ");
+  if(!list)
     return 0;
-  }
-
-  return fList->Merge(list);
+  if(list->IsEmpty())
+    return 1;
   
+  TIterator *iter = list->MakeIterator();
+  TObject *o = NULL;
+  Int_t index = 0;
+  while((o = iter->Next())){
+    AliHFEcollection *coll = dynamic_cast<AliHFEcollection *>(o);
+    if(!coll) continue; 
+    TList templist;       // Create temporary list containing all the lists to merge
+    templist.Add(coll->fList);
+    fList->Merge(&templist);
+    index++;
+  }
+  delete iter;
+  return index + 1;
 }
 //____________________________________________________________________
 void AliHFEcollection::Browse(TBrowser *b)
index bd9424e..639ee7d 100644 (file)
 #include "TNamed.h"
 #endif
 
-class TList;
+#ifndef ROOT_THashList
+#include "THashList.h"
+#endif
+
 class TCollection;
 class TBrowser;
 
@@ -58,6 +61,7 @@ class AliHFEcollection : public TNamed{
   Bool_t CreateTHnSparse(const char* name, const char* title, Int_t dim, Int_t* nbins, Double_t* xmin, Double_t* xmax);
 
   Bool_t BinLogAxis(const char* name, Int_t dim);
+  Bool_t Sumw2(const char*name);
     
 
   Long64_t Merge(TCollection *list);
@@ -77,7 +81,7 @@ class AliHFEcollection : public TNamed{
    void Copy(TObject &ref) const;
 
  private:
-  TList*                           fList;      //! Object container
+  THashList*                           fList;      // Object container
 
   ClassDef(AliHFEcollection, 1)
 
diff --git a/PWG3/hfe/AliHFEcontainer.cxx b/PWG3/hfe/AliHFEcontainer.cxx
new file mode 100644 (file)
index 0000000..0cb937e
--- /dev/null
@@ -0,0 +1,405 @@
+/**************************************************************************
+* 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.                  *
+**************************************************************************/
+//
+// HFE correction framework container
+// Contains many single containers
+// Extra fuctionality like appending added
+//
+// Author:
+//   Markus Fasel <M.Fasel@gsi.de>
+//
+#include <iostream>
+#include <TAxis.h>
+#include <TClass.h>
+#include <TCollection.h>
+#include <THashList.h>
+#include <TList.h>
+#include <TObjArray.h>
+#include <TObjString.h>
+#include <TString.h>
+
+#include "AliCFContainer.h"
+#include "AliHFEcontainer.h"
+#include "AliHFEtools.h"
+
+ClassImp(AliHFEcontainer)
+ClassImp(AliHFEcontainer::AliHFEvarInfo)
+
+//__________________________________________________________________
+AliHFEcontainer::AliHFEcontainer():
+  TNamed("HFEcontainer", ""),
+  fContainers(NULL),
+  fVariables(NULL),
+  fNVars(0),
+  fNEvents(0)
+{
+  //
+  // Default constructor
+  //
+  fContainers = new THashList();
+}
+
+//__________________________________________________________________
+AliHFEcontainer::AliHFEcontainer(const Char_t *name):
+  TNamed(name, ""),
+  fContainers(NULL),
+  fVariables(NULL),
+  fNVars(0),
+  fNEvents(0)
+{
+  //
+  // Default constructor
+  //
+  fContainers = new THashList();
+}
+
+//__________________________________________________________________
+AliHFEcontainer::AliHFEcontainer(const Char_t *name, UInt_t nVar):
+  TNamed(name, ""),
+  fContainers(NULL),
+  fVariables(NULL),
+  fNVars(0),
+  fNEvents(0)
+{
+  //
+  // Constructor
+  // Setting Number of Variables too
+  //
+  fContainers = new THashList();
+  SetNumberOfVariables(nVar);
+}
+
+//__________________________________________________________________
+AliHFEcontainer::AliHFEcontainer(const AliHFEcontainer &ref):
+  TNamed(ref),
+  fContainers(NULL),
+  fVariables(NULL),
+  fNVars(ref.fNVars),
+  fNEvents(ref.fNEvents)
+{
+  //
+  // Copy constructor
+  // creates a new object with new containers
+  //
+  fContainers = new THashList;
+  for(Int_t ien = 0; ien < ref.fContainers->GetEntries(); ien++)
+    fContainers->Add(new AliCFContainer(*dynamic_cast<AliCFContainer *>(ref.fContainers->At(ien))));
+  if(fNVars){
+    fVariables = new TObjArray(fNVars);
+    for(UInt_t ivar = 0; ivar < fNVars; ivar++)
+      fVariables->AddAt(new AliHFEvarInfo(*dynamic_cast<AliHFEvarInfo *>(ref.fVariables->UncheckedAt(ivar))), ivar);
+  }
+}
+
+//__________________________________________________________________
+AliHFEcontainer &AliHFEcontainer::operator=(const AliHFEcontainer &ref){
+  //
+  // Assignment operator
+  // Cleanup old object, create a new one with new containers inside
+  //
+  this->~AliHFEcontainer(); // cleanup old object before creating the new onwe
+  TNamed::operator=(ref);
+  fContainers = new THashList();
+  fNVars = ref.fNVars;
+  for(Int_t ien = 0; ien < ref.fContainers->GetEntries(); ien++)
+    fContainers->Add(new AliCFContainer(*dynamic_cast<AliCFContainer *>(ref.fContainers->At(ien))));
+  if(fNVars){
+    fVariables = new TObjArray(fNVars);
+    for(UInt_t ivar = 0; ivar < fNVars; ivar++)
+      fVariables->AddAt(new AliHFEvarInfo(*dynamic_cast<AliHFEvarInfo *>(ref.fVariables->UncheckedAt(ivar))), ivar);
+  } else {
+    fVariables = NULL;
+  }
+
+  return *this;
+}
+
+//__________________________________________________________________
+AliHFEcontainer::~AliHFEcontainer(){
+  //
+  // Destructor
+  //
+  fContainers->Delete();
+  delete fContainers;
+  if(fVariables){
+    fVariables->Delete();
+    delete fVariables;
+  }
+}
+
+//__________________________________________________________________
+Long64_t AliHFEcontainer::Merge(TCollection *coll){
+  //
+  // Merge Container
+  //
+  if(!coll)
+    return 0;
+  if(coll->IsEmpty())
+    return 1;
+
+  TIterator *iter = coll->MakeIterator();
+  TObject *o = NULL;
+  Long64_t count = 0;
+  while((o = iter->Next())){
+    AliHFEcontainer *cont = dynamic_cast<AliHFEcontainer *>(o);
+    if(!cont) continue;
+
+    // Merge the two TObjArrays
+    TList containers;
+    containers.Add(cont->fContainers);
+    fContainers->Merge(&containers);
+
+    fNEvents += cont->GetNumberOfEvents();
+    count++;
+  }
+  return count + 1;
+}
+
+//__________________________________________________________________
+void AliHFEcontainer::SetNumberOfVariables(UInt_t nVar){
+  //
+  // Define the number of variables 
+  // Initialize containers for the variable informations
+  //
+  if(fNVars) return;
+
+  fNVars = nVar;
+  fVariables = new TObjArray(nVar);
+  for(UInt_t ivar = 0; ivar < nVar; ivar++)
+    fVariables->AddAt(new AliHFEvarInfo, ivar);
+}
+
+//__________________________________________________________________
+void AliHFEcontainer::CreateContainer(const Char_t *name, const Char_t *title, UInt_t nStep){
+  //
+  // Create a new Correction Framework Container and store it 
+  //
+  if(fContainers->FindObject(name)){
+    AliError(Form("Container %s already exists. Cannot replace it!", name));
+    return;
+  }
+  
+  Int_t *nBins = new Int_t[fNVars];
+  for(UInt_t ivar = 0; ivar < fNVars; ivar++) nBins[ivar] = (dynamic_cast<AliHFEvarInfo *>(fVariables->UncheckedAt(ivar)))->GetNumberOfBins();
+  AliHFEvarInfo *var = NULL;
+  AliCFContainer *cont = new AliCFContainer(name, title, nStep, fNVars, nBins);
+  for(UInt_t ivar = 0; ivar < fNVars; ivar++){
+    var = dynamic_cast<AliHFEvarInfo *>(fVariables->UncheckedAt(ivar));
+    cont->SetBinLimits(ivar, var->GetBinning());
+    cont->SetVarTitle(ivar, var->GetVarName()->Data());
+  }
+  delete[] nBins;
+  fContainers->Add(cont);
+  AliInfo(Form("Container %s created with %d cut steps", name, nStep));
+}
+
+//__________________________________________________________________
+AliCFContainer *AliHFEcontainer::GetCFContainer(const Char_t *name){
+  //
+  // Find a given container 
+  //
+  return dynamic_cast<AliCFContainer *>(fContainers->FindObject(name));
+}
+
+//__________________________________________________________________
+void AliHFEcontainer::FillCFContainer(const Char_t *name, UInt_t step, Double_t *content){
+  //
+  // Fill container
+  //
+  AliCFContainer *cont = GetCFContainer(name);
+  if(!cont) return;
+  cont->Fill(content, step);
+}
+
+//__________________________________________________________________
+AliCFContainer *AliHFEcontainer::MakeMergedCFContainer(const Char_t *name, const Char_t *title, const Char_t* contnames){
+  //
+  // Merge CF Container out of several containers 
+  // Container names are separated by :
+  // returns a new object which has to be taken care of by the user
+  //
+
+  TObjArray *containers = TString(contnames).Tokenize(":");
+  // we first need the size of the container to be merged
+  Int_t nStepMerged = 0;
+  AliCFContainer *ctemp = NULL;
+  TObjString *cname = NULL;
+  for(Int_t icont = 0; icont < containers->GetEntries(); icont++){
+    cname = dynamic_cast<TObjString *>(containers->At(icont));
+    ctemp = dynamic_cast<AliCFContainer *>(fContainers->FindObject(cname->String().Data()));
+    if(!ctemp){
+      AliWarning(Form("Container %s not found. It will be unprocessed", cname->String().Data()));
+      continue;
+    }
+    nStepMerged += ctemp->GetNStep(); 
+  }
+  AliInfo("Please Ignore the messgae comming from AliCFContainer!");
+  Int_t *dummyBinning = new Int_t[fNVars];
+  for(UInt_t ibin = 0; ibin < fNVars; ibin++) dummyBinning[ibin] = 1;
+  AliCFContainer *cmerged = new AliCFContainer(name, title, nStepMerged, fNVars, dummyBinning);
+  delete dummyBinning;
+  // cleanup old container content so that we can fill it with the new content
+  AliInfo("Removing temporary grids");
+  for(Int_t istep = 0; istep < cmerged->GetNStep(); istep++){
+    AliCFGridSparse *grid = cmerged->GetGrid(istep);
+    delete grid;
+  }
+  // Fill container with content
+  AliInfo("Filling new container");
+  Int_t cstep = 0;
+  for(Int_t icont = 0; icont < containers->GetEntries(); icont++){
+    cname = dynamic_cast<TObjString *>(containers->At(icont));
+    ctemp = dynamic_cast<AliCFContainer *>(fContainers->FindObject(cname->String().Data()));
+    if(!ctemp) continue;
+    for(Int_t istep = 0; istep < ctemp->GetNStep(); istep++)
+      cmerged->SetGrid(cstep++, new AliCFGridSparse(*ctemp->GetGrid(istep)));
+  }
+  return cmerged;
+}
+//__________________________________________________________________
+void AliHFEcontainer::MakeLinearBinning(UInt_t var, UInt_t nBins, Double_t begin, Double_t end){
+  //
+  // Set Linear binning for the given container
+  //
+  (dynamic_cast<AliHFEvarInfo *>(fVariables->UncheckedAt(var)))->SetBinning(nBins, AliHFEtools::MakeLinearBinning(nBins, begin, end));
+}
+
+//__________________________________________________________________
+void AliHFEcontainer::MakeLogarithmicBinning(UInt_t var, UInt_t nBins, Double_t begin, Double_t end){
+  //
+  // Set Logarithmic binning for the given container
+  //
+  (dynamic_cast<AliHFEvarInfo *>(fVariables->UncheckedAt(var)))->SetBinning(nBins, AliHFEtools::MakeLogarithmicBinning(nBins, begin, end));
+}
+
+//__________________________________________________________________
+void AliHFEcontainer::SetVariableName(UInt_t var, const Char_t *varname){
+  //
+  // Variable name
+  // 
+  (dynamic_cast<AliHFEvarInfo *>(fVariables->UncheckedAt(var)))->SetVarName(varname);
+}
+
+//__________________________________________________________________
+Int_t AliHFEcontainer::GetNumberOfCFContainers() const{
+  //
+  // Get the number of entries
+  //
+  return fContainers->GetEntries();
+}
+
+//__________________________________________________________________
+void AliHFEcontainer::Print(const Option_t *)const{
+  //
+  // Print Container Status
+  //
+  std::cout << "Container status: " << std::endl;
+  std::cout << "=====================================================\n";
+  std::cout << "Number of variables: " << fNVars << std::endl;
+  if(fNVars){
+    UInt_t nVars = fVariables ? fVariables->GetEntriesFast() : 0;
+    if(nVars != fNVars)
+      std::cout << "Inconsistency in number of Variables [" << fNVars << "|" << nVars << "]" << std::endl;
+    AliHFEvarInfo *var = NULL;
+    for(UInt_t ivar = 0; ivar < fNVars; ivar++){
+      var = dynamic_cast<AliHFEvarInfo *>(fVariables->UncheckedAt(ivar));
+      std::cout << "Variable " << ivar << ": Name: " << var->GetVarName()->Data() << ", Number of Bins: " << var->GetNumberOfBins() << std::endl;
+    }
+  }
+  std::cout << std::endl;
+
+  // Print CF Containers:
+  std::cout << "Containers[" << fContainers->GetEntries() << "]: "<< std::endl;
+  std::cout << "=====================================================\n";
+  for(Int_t icont = 0; icont < fContainers->GetEntries(); icont++){
+    AliCFContainer *c = dynamic_cast<AliCFContainer *>(fContainers->At(icont));
+    std::cout << "Name: " << c->GetName() << ", Title: "  << c->GetTitle() << std::endl;
+    for(Int_t istep = 0; istep < c->GetNStep(); istep++)
+      std::cout << "Step " << istep << ": Title " << c->GetStepTitle(istep) << std::endl;
+    std::cout << "------------------------------------------------------\n";
+  }
+  std::cout << "Number of Events: " << fNEvents << std::endl;
+}
+
+//------------------------------------ Content of class AliHFEvarInfo -----------------------------------
+//__________________________________________________________________
+AliHFEcontainer::AliHFEvarInfo::AliHFEvarInfo():
+  TObject(),
+  fVarName(NULL),
+  fBinning(NULL)
+{
+  // Default constructor
+  fBinning = new TArrayD;
+  fVarName = new TString;
+}
+
+//__________________________________________________________________
+AliHFEcontainer::AliHFEvarInfo::AliHFEvarInfo(const Char_t *name):
+  TObject(),
+  fVarName(NULL),
+  fBinning(NULL)
+{
+  fBinning = new TArrayD;
+  fVarName = new TString(name);
+}
+
+//__________________________________________________________________
+AliHFEcontainer::AliHFEvarInfo::AliHFEvarInfo(const AliHFEvarInfo &ref):
+  TObject(ref),
+  fVarName(NULL),
+  fBinning(NULL)
+{
+  //
+  // Constructor
+  //
+  fVarName = new TString(*(ref.fVarName));
+  fBinning = new TArrayD(*(ref.fBinning));
+}
+
+//__________________________________________________________________
+AliHFEcontainer::AliHFEvarInfo &AliHFEcontainer::AliHFEvarInfo::operator=(const AliHFEvarInfo &ref){
+  //
+  // Assignment operator
+  //
+  TObject::operator=(ref);
+  *fVarName = *(ref.fVarName);
+  *fBinning = *(ref.fBinning);
+  return *this;
+}
+
+//__________________________________________________________________
+AliHFEcontainer::AliHFEvarInfo::~AliHFEvarInfo(){
+  //
+  // Destructor
+  //
+  delete fVarName;
+  delete fBinning;
+}
+
+//__________________________________________________________________
+void AliHFEcontainer::AliHFEvarInfo::SetVarName(const Char_t *name){
+  //
+  // Setter for var name
+  //
+  *fVarName = name;
+}
+
+//__________________________________________________________________
+void AliHFEcontainer::AliHFEvarInfo::SetBinning(UInt_t nBins, Double_t *content){
+  // Setter for binning
+  //
+  fBinning->Set(nBins + 1, content);
+}
+
diff --git a/PWG3/hfe/AliHFEcontainer.h b/PWG3/hfe/AliHFEcontainer.h
new file mode 100644 (file)
index 0000000..ad00cb0
--- /dev/null
@@ -0,0 +1,107 @@
+/**************************************************************************
+* 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.                  *
+**************************************************************************/
+//
+// HFE correction framework container
+// Contains many single containers
+// Extra fuctionality like appending added
+//
+#ifndef ALIHFECONTAINER_H
+#define ALIHFECONTAINER_H
+
+#ifndef ROOT_TNamed
+#include <TNamed.h>
+#endif
+
+#ifndef ROOT_TObjArray
+#include <TObjArray.h>
+#endif
+
+#ifndef ROOT_TArrayD
+#include <TArrayD.h>
+#endif
+
+class TCollection;
+class TList;
+class THashList;
+class TString;
+class AliCFContainer;
+
+class AliHFEcontainer : public TNamed{
+  public:
+    AliHFEcontainer();
+    AliHFEcontainer(const Char_t *name);
+    AliHFEcontainer(const Char_t *name, UInt_t nVar);
+    AliHFEcontainer(const AliHFEcontainer &ref);
+    AliHFEcontainer& operator=(const AliHFEcontainer &ref);
+    ~AliHFEcontainer();
+
+    virtual Long64_t Merge(TCollection *coll);
+
+    void CreateContainer(const Char_t *name, const Char_t *title, UInt_t nStep);
+    AliCFContainer *GetCFContainer(const Char_t *name);
+    void FillCFContainer(const Char_t *name, UInt_t step, Double_t *content);
+    AliCFContainer *MakeMergedCFContainer(const Char_t *name, const Char_t *title, const Char_t *contnames);
+
+    Int_t GetNumberOfCFContainers() const;
+    Int_t GetNumberOfEvents() const { return fNEvents; };
+    void NewEvent() { fNEvents++; };
+    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 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;
+
+    struct AliHFEvarInfo : public TObject{
+        AliHFEvarInfo();
+        AliHFEvarInfo(const Char_t *name);
+        AliHFEvarInfo(const AliHFEvarInfo &ref);
+        AliHFEvarInfo &operator=(const AliHFEvarInfo &ref);
+        ~AliHFEvarInfo();
+
+        UInt_t GetNumberOfBins() const { return fBinning->GetSize() ? fBinning->GetSize() - 1 : 0; };
+        Double_t *GetBinning() const { return fBinning->GetArray(); };
+        TString *GetVarName() const { return fVarName; };
+
+        void SetVarName(const Char_t *name);
+        void SetBinning(UInt_t nBins, Double_t *binning);
+      private:
+        TString *fVarName;  // Variable Name
+        TArrayD *fBinning;  // Binning
+        
+        ClassDef(AliHFEcontainer::AliHFEvarInfo, 1)  // Variable information
+    };
+
+  private:
+    THashList*fContainers;      // TObjArray for Containers
+    TObjArray *fVariables;      // Variable Information
+    UInt_t fNVars;              // Number of Variables
+    Int_t fNEvents;             // Number of Events
+
+    ClassDef(AliHFEcontainer, 1)  // HFE Efficiency Container
+};
+
+//__________________________________________________________________
+void AliHFEcontainer::SetBinning(UInt_t var, UInt_t nBins, Double_t *content){
+  //
+  // Set Binning for a given variable
+  //
+  if(var >= fNVars) return;
+  AliHFEvarInfo *inf = dynamic_cast<AliHFEvarInfo *>(fVariables->UncheckedAt(var));
+  if(!inf) return;
+  inf->SetBinning(nBins, content); 
+}
+#endif
diff --git a/PWG3/hfe/AliHFEcutStep.cxx b/PWG3/hfe/AliHFEcutStep.cxx
new file mode 100644 (file)
index 0000000..e0e49c6
--- /dev/null
@@ -0,0 +1,138 @@
+/**************************************************************************
+* 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.                  *
+**************************************************************************/
+//
+// Cut step class
+// Select all tracks surviving cuts in one special cut step
+// Used in AliHFEtrackFilter
+// 
+// Author:
+//   Markus Fasel <M.Fasel@gsi.de>
+//
+#include <TObjArray.h>
+
+#include "AliAnalysisCuts.h"
+#include "AliCFCutBase.h"
+#include "AliHFEcutStep.h"
+#include "AliLog.h"
+#include "AliMCEvent.h"
+
+ClassImp(AliHFEcutStep)
+
+//__________________________________________________________________
+AliHFEcutStep::AliHFEcutStep(const Char_t *name):
+  TNamed(name, ""),
+  fCuts(NULL)
+{
+  //
+  // Default Constructor
+  //
+  fCuts = new TObjArray;
+}
+
+//__________________________________________________________________
+AliHFEcutStep::AliHFEcutStep(const AliHFEcutStep &o):
+  TNamed(o),
+  fCuts(NULL)
+{
+  //
+  // Copy constructor
+  //
+  o.Copy(*this);
+}
+
+//__________________________________________________________________
+AliHFEcutStep &AliHFEcutStep::operator=(const AliHFEcutStep &o){
+  //
+  // Assignment operator
+  //
+  if(this != &o)
+    o.Copy(*this);
+  return *this;
+}
+//__________________________________________________________________
+AliHFEcutStep::~AliHFEcutStep(){
+  //
+  // destructor
+  //
+  delete fCuts;
+}
+
+//__________________________________________________________________
+void AliHFEcutStep::Copy(TObject &o) const{
+  //
+  // Copy into content into object o
+  //
+  TNamed::Copy(o);
+  AliHFEcutStep &target = dynamic_cast<AliHFEcutStep &>(o);
+
+  // Make copy
+  target.fCuts = dynamic_cast<TObjArray *>(fCuts->Clone());
+}
+
+//__________________________________________________________________
+Bool_t AliHFEcutStep::IsSelected(TObject *o){
+  //
+  // Filter tracks in the given cut step
+  // Apply all cut objects
+  //
+  AliInfo(Form("Cut Step %s: Number of cut objects: %d", GetName(), fCuts->GetEntriesFast()));
+  if(!fCuts->GetEntriesFast()) return kTRUE;
+  Bool_t isSelected = kTRUE;
+  for(Int_t iCut = 0; iCut < fCuts->GetEntriesFast(); iCut++){
+    if(!(dynamic_cast<AliAnalysisCuts *>(fCuts->UncheckedAt(iCut)))->IsSelected(o)) isSelected = kFALSE;
+  }
+  AliInfo(Form("Accepted: %s", isSelected ? "yes" : "no"));
+  return isSelected;
+} 
+
+//__________________________________________________________________
+AliAnalysisCuts *AliHFEcutStep::GetCut(const Char_t *cutName){
+  //
+  // return cut object
+  //
+  return dynamic_cast<AliAnalysisCuts *>(fCuts->FindObject(cutName));
+}
+
+//__________________________________________________________________
+void AliHFEcutStep::AddCut(AliAnalysisCuts *cut){
+  //
+  // Add cut object to the cut step
+  //
+  fCuts->Add(cut);
+}
+
+//__________________________________________________________________
+void AliHFEcutStep::SetMC(AliMCEvent *mc){
+  //
+  // Set MC information to the cuts in the cut step
+  //
+  for(Int_t icut = 0; icut < fCuts->GetEntriesFast(); icut++){
+    if(fCuts->UncheckedAt(icut)->InheritsFrom("AliCFCutBase"))
+      (dynamic_cast<AliCFCutBase *>(fCuts->UncheckedAt(icut)))->SetMCEventInfo(mc);
+  }
+}
+
+//__________________________________________________________________
+void AliHFEcutStep::SetRecEvent(AliVEvent *rec){
+  //
+  // Publish rec event to the cut step
+  //
+  for(Int_t icut = 0; icut < fCuts->GetEntriesFast(); icut++){
+    if(fCuts->UncheckedAt(icut)->InheritsFrom("AliCFCutBase"))
+      (dynamic_cast<AliCFCutBase *>(fCuts->UncheckedAt(icut)))->SetRecEventInfo(rec);
+  }
+}
+
diff --git a/PWG3/hfe/AliHFEcutStep.h b/PWG3/hfe/AliHFEcutStep.h
new file mode 100644 (file)
index 0000000..7977614
--- /dev/null
@@ -0,0 +1,51 @@
+/**************************************************************************
+* 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.                  *
+**************************************************************************/
+//
+// Cut step class
+// Select all tracks surviving cuts in one special cut step
+// Used in AliHFEtrackFilter
+// 
+#ifndef ALIHFECUTSTEP_H
+#define ALIHFECUTSTEP_H
+
+#include <TNamed.h>
+
+class TObjArray;
+class AliAnalysisCuts;
+class AliMCEvent;
+class AliVEvent;
+
+class AliHFEcutStep : public TNamed{
+    public:
+      AliHFEcutStep(const Char_t *name);
+      AliHFEcutStep(const AliHFEcutStep &o);
+      AliHFEcutStep &operator=(const AliHFEcutStep &o);
+      virtual void Copy(TObject &o) const;
+      ~AliHFEcutStep();
+      
+      void AddCut(AliAnalysisCuts *cut);
+      AliAnalysisCuts *GetCut(const Char_t *name);
+      Bool_t IsSelected(TObject *o);
+
+      void SetMC(AliMCEvent *mc);
+      void SetRecEvent(AliVEvent *mc);
+
+    private:
+      TObjArray *fCuts;
+      
+      ClassDef(AliHFEcutStep, 1)
+};
+#endif
+
index 9f411b1..6268896 100644 (file)
 //   Markus Heide <mheide@uni-muenster.de>
 //   Matus Kalisky <m.kalisky@uni-muenster.de>
 //
+// Overview over the 18 steps in the correction Framework
+// 0. Generated Electrons
+// 1. Signal Electrons
+// 2. Electron in Acceptance
+// ------------------------------------------------------------
+// 3. Rec without cuts (MC information)
+// 4. Rec Kine ITS/TPC (MC Information)
+// 5. Rec Primary (MC Information)
+// 6. HFE ITS (MC Information)
+// 7. HFE TRD (MC Information)
+// 8. PID (MC Information) 
+// ............................................................
+// 9. Rec without cuts(MC Information for tracks which are already registered)
+// 10. Rec Kine ITS/TPC (MC Information for tracks which are already registered)
+// 11. RecPrimary (MC Information for tracks which are already registered)
+// 12. HFE ITS (MC Information for tracks which are already registered)
+// 13. HFE TPC (MC Information for tracks which are already registered)
+// 14. PID (MC Information for tracks which are already registered)
+// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+// 15. Rec without cuts
+// 16. Rec Kine ITS/TPC 
+// 17. Rec Primary
+// 18. HFE ITS
+// 19. HFE TRD
+// 20. PID
+//
 #include <TClass.h>
 #include <TList.h>
 #include <TObjArray.h>
@@ -138,10 +164,10 @@ void AliHFEcuts::Initialize(AliCFManager *cfm){
   }
 
   // Connect the event cuts
-  /*SetEventCutList(kEventStepGenerated);
+  SetEventCutList(kEventStepGenerated);
   SetEventCutList(kEventStepReconstructed);
   cfm->SetEventCutsList(kEventStepGenerated, dynamic_cast<TObjArray *>(fCutList->FindObject("fEvGenCuts")));
-  cfm->SetEventCutsList(kEventStepReconstructed, dynamic_cast<TObjArray *>(fCutList->FindObject("fEvRecCuts")));*/
+  cfm->SetEventCutsList(kEventStepReconstructed, dynamic_cast<TObjArray *>(fCutList->FindObject("fEvRecCuts")));
   
   // Connect the particle cuts
   cfm->SetParticleCutsList(kStepMCGenerated, dynamic_cast<TObjArray *>(fCutList->FindObject("fPartGenCuts")));
@@ -211,12 +237,13 @@ void AliHFEcuts::SetParticleGenCutList(){
   if(IsRequireProdVertex()){
     genCuts->SetProdVtxRangeX(fProdVtx[0], fProdVtx[1]);
     genCuts->SetProdVtxRangeY(fProdVtx[2], fProdVtx[3]);
+    genCuts->SetProdVtxRange2D(kTRUE);  // Use ellipse
   }
   genCuts->SetRequirePdgCode(11, kTRUE);
   
   AliCFTrackKineCuts *kineMCcuts = new AliCFTrackKineCuts("fCutsKineMC","MC Kine Cuts");
   kineMCcuts->SetPtRange(fPtRange[0], fPtRange[1]);
-  kineMCcuts->SetEtaRange(-0.9, 0.9);
+  kineMCcuts->SetEtaRange(-0.8, 0.8);
 
   if(IsInDebugMode()){
     genCuts->SetQAOn(fHistQA);
@@ -286,7 +313,7 @@ void AliHFEcuts::SetRecKineITSTPCCutList(){
   
   AliCFTrackKineCuts *kineCuts = new AliCFTrackKineCuts("fCutsKineRec", "REC Kine Cuts");
   kineCuts->SetPtRange(fPtRange[0], fPtRange[1]);
-  kineCuts->SetEtaRange(-0.9, 0.9);
+  kineCuts->SetEtaRange(-0.8, 0.8);
   
   if(IsInDebugMode()){
     trackQuality->SetQAOn(fHistQA);
@@ -379,7 +406,7 @@ Bool_t AliHFEcuts::CheckParticleCuts(CutStep_t step, TObject *o){
   //
   // Checks the cuts without using the correction framework manager
   // 
-  TString stepnames[kNcutSteps] = {"fPartGenCuts", "fPartAccCuts", "fPartRecCuts", "fPartPrimCuts", "fPartHFECuts"};
+  TString stepnames[kNcutStepsTrack] = {"fPartGenCuts", "fPartAccCuts", "fPartRecCuts", "fPartPrimCuts", "fPartHFECuts"};
   TObjArray *cuts = dynamic_cast<TObjArray *>(fCutList->FindObject(stepnames[step].Data()));
   if(!cuts) return kTRUE;
   TIterator *it = cuts->MakeIterator();
index caf8ad7..dc1568b 100644 (file)
@@ -41,18 +41,21 @@ class AliHFEcuts : public TObject{
       kStepMCGenerated = 0,
       kStepMCsignal = 1,
       kStepMCInAcceptance = 2,
-      kStepRecKineITSTPC = 3,
-      kStepRecPrim = 4,
-      kStepHFEcutsITS = 5,
-      kStepHFEcutsTRD = 6
+      kStepRecNoCut = 3,
+      kStepRecKineITSTPC = 4,
+      kStepRecPrim = 5,
+      kStepHFEcutsITS = 6,
+      kStepHFEcutsTRD = 7,
+      kStepPID = 8
     } CutStep_t;
     typedef enum{
       kEventStepGenerated = 0,
       kEventStepReconstructed = 1
     } EventCutStep_t;
     enum{
-      kNcutSteps = 7,
-      kNcutESDSteps = 4
+      kNcutStepsEvent = 2,
+      kNcutStepsTrack = 9,
+      kNcutStepsESDtrack = 6 
     };    // Additional constants
 
     AliHFEcuts();
diff --git a/PWG3/hfe/AliHFEdca.cxx b/PWG3/hfe/AliHFEdca.cxx
new file mode 100644 (file)
index 0000000..040ed6f
--- /dev/null
@@ -0,0 +1,355 @@
+/*************************************************************************
+* 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 for impact parameter (DCA) of charged particles
+// Study resolution and pull: prepare for beauty study
+//
+// Authors:
+//   Hongyan Yang <hongyan@physi.uni-heidelberg.de>
+//   Carlo Bombonati <carlo.bombonati@cern.ch>
+//
+
+#include "TMath.h"
+#include "TH1F.h"
+#include "TList.h"
+#include <TParticle.h>
+#include "AliMCParticle.h"
+#include "AliESDtrack.h"
+#include "AliESDEvent.h"
+#include "AliMCEvent.h"
+
+#include "AliHFEdca.h"
+
+ClassImp(AliHFEdca)
+
+//________________________________________________________________________
+const Char_t* AliHFEdca::fgkParticles[12] = {
+  // particles name
+  "electron", "muonMinus","pionMinus", "kaonMinus", "protonMinus", 
+  "positron", "muonPlus", "pionPlus", "kaonPlus", "protonPlus",
+  "allNegative", "allPositive"
+};
+//________________________________________________________________________
+const Int_t AliHFEdca::fgkColorPart[12] = { 
+  // colors assigned to particles
+  kRed, kBlue, kGreen+2, kYellow+2, kMagenta, 
+  kRed+2, kBlue+2, kGreen+4, kYellow+4, kMagenta+2,
+  kBlack, kGray+1
+};
+
+
+
+//________________________________________________________________________
+const Float_t AliHFEdca::fgkPtIntv[44] = {
+  // define pT bins
+  0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9,
+  1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 
+  3.0, 3.3, 3.6, 3.9, 4.2, 4.5, 5.0, 5.5, 6.0, 6.5, 
+  7.0, 8.0, 9.0, 10., 11., 12., 13., 14., 15., 16., 
+  17., 18., 19., 20.};
+
+//________________________________________________________________________
+const Char_t *AliHFEdca::fgkDcaVar[2] = {
+  "deltaDcaXY",  "deltaDcaZ"};
+
+//________________________________________________________________________
+const Char_t *AliHFEdca::fgkDcaVarTitle[2] ={
+  ";residual #Delta(d_{xy}) [#mum];couts", ";residual #Delta(d_{z}) [#mum];counts"};
+
+
+//________________________________________________________________________
+const Char_t *AliHFEdca::fgkPullDcaVar[2] = {
+  "pullDcaXY", "pullDcaZ"
+};
+
+//________________________________________________________________________
+const Char_t *AliHFEdca::fgkPullDcaVarTitle[2] = {
+  ";(dca_{xy}^{ESD}-dca_{xy}^{MC})/(#sigma_{track}#oplus#sigma_{Vxy});counts",
+  ";(dca_{z}^{ESD}-dca_{z}^{MC})/(#sigma_{track}#oplus#sigma_{Vz}); counts"
+};
+
+//________________________________________________________________________
+AliHFEdca::AliHFEdca():
+   fResidualList(0x0)
+  , fPullList(0x0)
+
+{
+  // default constructor
+}
+
+//________________________________________________________________________
+AliHFEdca::AliHFEdca(const AliHFEdca &dca):
+  TObject(dca)
+  , fResidualList(0x0)
+  , fPullList(0x0)
+
+{
+  // copy constructor
+
+}
+//_______________________________________________________________________________________________
+AliHFEdca&
+AliHFEdca::operator=(const AliHFEdca &)
+{
+  //
+  // Assignment operator
+  //
+  
+  Printf("Not yet implemented.");
+  return *this;
+}
+
+//________________________________________________________________________
+AliHFEdca::~AliHFEdca()
+{
+  // default destructor
+
+  for(Int_t j=0; j<kNParticles; j++){
+    for(Int_t i=0; i<kNPtBins; i++){
+      if(fHistDcaXYRes[j][i]) delete fHistDcaXYRes[j][i];
+      if(fHistDcaZRes[j][i]) delete fHistDcaZRes[j][i];
+      if(fHistDcaXYPull[j][i]) delete fHistDcaXYPull[j][i];
+      if(fHistDcaXYPull[j][i]) delete fHistDcaZPull[j][i];
+    }
+  }
+
+  if(fResidualList) delete fResidualList;
+  if(fPullList) delete fPullList;
+
+  Printf("analysis done\n");
+}
+
+//________________________________________________________________________
+void AliHFEdca::InitAnalysis(){
+  
+  Printf("initialize analysis\n");
+
+}
+
+
+//________________________________________________________________________
+void AliHFEdca::PostAnalysis() const
+{
+  // do fit
+  // moved to dcaPostAnalysis.C
+
+}
+//________________________________________________________________________
+void AliHFEdca::CreateHistogramsResidual(TList *residualList){
+  // define histogram
+  // 1. residual
+
+  // for residuals
+  fHistDcaXYRes[kNParticles][kNPtBins]=0x0;
+  fHistDcaZRes[kNParticles][kNPtBins]=0x0;
+  
+  const Int_t nBins = 1000;
+  const Float_t maxXYBin = 1000.;
+  const Float_t maxZBin = 1000.;
+
+  
+  for(Int_t k=0; k<kNDcaVar; k++){
+    TString histTitle((const char*)fgkDcaVarTitle[k]);
+    
+    for(Int_t j=0; j<kNParticles; j++){
+      for(Int_t i=0; i<kNPtBins; i++){
+       
+       TString histName((const char*)fgkParticles[j]);
+       
+       histName += Form("_%s_pT-%.1f-%.1f", (const char*)fgkDcaVar[k], fgkPtIntv[i], fgkPtIntv[i+1]);
+       
+       if(k==0){
+         fHistDcaXYRes[j][i] = new TH1F((const char*)histName, (const char*)histTitle, nBins, -maxXYBin, maxXYBin);
+         fHistDcaXYRes[j][i]->SetLineColor((const int)fgkColorPart[j]);
+       }           
+       if(k==1){
+         fHistDcaZRes[j][i] = new TH1F((const char*)histName, (const char*)histTitle, nBins, -maxZBin, maxZBin);
+         fHistDcaZRes[j][i]->SetLineColor((const int)fgkColorPart[j]);
+       }   
+      } // 43 pt bins
+    } //12 nparticles
+  } // 2 dca var
+  
+  //  TList *fResidualList = 0;
+  residualList->SetOwner();
+  residualList->SetName("residual");
+  for(Int_t iPart=0; iPart<kNParticles; iPart++){
+    for(Int_t iPtBin=0; iPtBin<kNPtBins; iPtBin++){
+      residualList->Add(fHistDcaXYRes[iPart][iPtBin]);  
+      residualList->Add(fHistDcaZRes[iPart][iPtBin]);  
+    } // loop over pt bins
+  }  // loop over particles (pos, neg)
+  
+
+  
+
+}
+
+
+//________________________________________________________________________
+void AliHFEdca::CreateHistogramsPull(TList *pullList){
+  // define histogram
+  // 2. pull
+
+  const Int_t nBins = 1000;
+  const Float_t maxXYBin = 20.;
+  const Float_t maxZBin = 20.;
+
+  
+  // for pull -----------------------------------------------------------------------
+  fHistDcaXYPull[kNParticles][kNPtBins]=0x0;
+  fHistDcaZPull[kNParticles][kNPtBins]=0x0;
+
+  
+  for(Int_t k=0; k<kNDcaVar; k++){
+    TString histTitle((const char*)fgkPullDcaVarTitle[k]);
+    
+    for(Int_t j=0; j<kNParticles; j++){
+      for(Int_t i=0; i<kNPtBins; i++){
+       
+       TString histName((const char*)fgkParticles[j]);
+       
+       histName += Form("_%s_pT-%.1f-%.1f", (const char*)fgkPullDcaVar[k], fgkPtIntv[i], fgkPtIntv[i+1]);
+       
+       if(k==0){
+         fHistDcaXYPull[j][i] = new TH1F((const char*)histName, (const char*)histTitle, nBins, 1-maxXYBin, 1+maxXYBin);
+         fHistDcaXYPull[j][i]->SetLineColor((const int)fgkColorPart[j]);
+       }           
+       if(k==1){
+         fHistDcaZPull[j][i] = new TH1F((const char*)histName, (const char*)histTitle, nBins, 1-maxZBin, 1+maxZBin);
+         fHistDcaZPull[j][i]->SetLineColor((const int)fgkColorPart[j]);
+       }   
+      } // 43 pt bins
+    } //6 nparticles
+  } // 2 dca var
+  
+  //  TList *fPullList = 0;
+  pullList->SetOwner();
+  pullList->SetName("pull");
+  for(Int_t iPart=0; iPart<kNParticles; iPart++){
+    for(Int_t iPtBin=0; iPtBin<kNPtBins; iPtBin++){
+      pullList->Add(fHistDcaXYPull[iPart][iPtBin]);  
+      pullList->Add(fHistDcaZPull[iPart][iPtBin]);  
+    } // loop over pt bins
+  }  // loop over particles (pos, neg)
+  
+  
+
+}
+
+
+//_______________________________________________________________________________________________
+void AliHFEdca::FillHistograms(AliESDEvent * const esdEvent, AliESDtrack * const track, AliMCEvent * const mcEvent)
+{
+// filling historgams track by track
+
+// obtaining reconstructed dca ------------------------------------------------------------------
+  Float_t esdpx = track->Px();
+  Float_t esdpy = track->Py();
+  Float_t esdpt = TMath::Sqrt(esdpx*esdpx+esdpy*esdpy);  
+  Float_t b[2];  // dca in cm
+  Float_t bCov[3];  // covariance matrix
+  track->GetImpactParameters(b,bCov);
+  
+// obtaining errors of dca ------------------------------------------------------------------
+  const AliESDVertex *primVtx = esdEvent->GetPrimaryVertex();      
+  Float_t magneticField = 5;  // initialized as 5kG
+  magneticField = esdEvent->GetMagneticField();  // in kG
+  Double_t dz[2];   // error of dca in cm
+  Double_t covardz[3];
+  track->PropagateToDCA(primVtx,magneticField, 1000., dz, covardz);
+
+  // calculate mcDca ------------------------------------------------------------------
+  
+  AliMCParticle *mctrack = dynamic_cast<AliMCParticle *>(mcEvent->GetTrack(TMath::Abs(track->GetLabel())));  
+  TParticle *part = mctrack->Particle();
+  Int_t pdg = part->GetPdgCode();
+  Int_t charge = 1;
+  if(pdg==kPDGelectron || pdg==kPDGmuon 
+     || pdg==-kPDGpion || pdg==-kPDGkaon || pdg==-kPDGproton) charge = -1;
+
+  Float_t vx = part->Vx();  // in cm
+  Float_t vy = part->Vy();  // in cm
+  Float_t vz = part->Vz();   // in cm
+  
+  Float_t vxy = TMath::Sqrt(vx*vx+vy*vy);
+  
+  Float_t mcpx = part->Px();
+  Float_t mcpy = part->Py();
+  Float_t mcpt = TMath::Sqrt(mcpx*mcpx+mcpy*mcpy);
+  
+  const Float_t conv[2] = {1.783/1.6, 2.99792458};
+  Float_t radiusMc = mcpt/(TMath::Abs(magneticField)/10.)*conv[0]*conv[1]; // pt in GeV/c, magnetic field in Tesla
+  
+  Float_t nx = esdpx/mcpt;
+  Float_t ny = esdpy/mcpt;
+    
+  Float_t radius;
+  radius = TMath::Abs(radiusMc);
+  Float_t mcDcaXY = (radius - TMath::Sqrt(vxy*vxy/100./100. + radius*radius + 2*radius*charge*(vx*ny-vy*nx)/100.)) ;  // in meters
+
+//   printf("magnetic Field = %.3f \t", magneticField);
+//   printf("pt=esd  %.3f/mc  %.3f GeV/c, radius=esd  %.3f/mc  %.3f meter \n", esdpt, mcpt, radiusEsd, radiusMc);
+//   printf("mcDcaXY=%.5f micron, esdDcaXY=%.5f micron \t ",  mcDcaXY*1.e6, b[0]*1e4);
+//   printf("mcDcaZ=%.5f micron, esdDcaZ=%.5f micron\n\n", vz*1e6, b[1]*1e4);
+  
+  Double_t mcDca[2] = {mcDcaXY*100, vz};  // in cm
+  
+  Double_t residual[2] = {0, 0};
+  Double_t pull[2] = {0, 0};
+  Double_t error[2] ={TMath::Sqrt(covardz[0]), TMath::Sqrt(covardz[2])};
+  for(Int_t i=0; i<2; i++){
+    residual[i] = dz[i] - mcDca[i]; // in centimeters       
+    if(error[i]!=0)pull[i] = residual[i]/error[i];   // unitless
+    //    printf("error[%d]=%.6f  residual[%d]=%.6f   pull[%d]=%.6f\n", i, error[i], i, residual[i], i, pull[i]);
+  }
+
+  Int_t fPdgParticle[10] = { 
+    kPDGelectron, kPDGmuon, -kPDGpion, -kPDGkaon, -kPDGproton, 
+    -kPDGelectron, -kPDGmuon, kPDGpion, kPDGkaon, kPDGproton};
+    
+  for(Int_t iPart=0; iPart<kNParticles-2; iPart++){
+    
+    // identified ones
+    for(Int_t iPtBin=0; iPtBin<kNPtBins; iPtBin++){
+      if(pdg==fPdgParticle[iPart] && (esdpt>fgkPtIntv[iPtBin] && esdpt<=fgkPtIntv[iPtBin+1])) {
+       fHistDcaXYRes[iPart][iPtBin]->Fill(residual[0]*1.0e4);  // in microns
+       fHistDcaZRes[iPart][iPtBin]->Fill(residual[1]*1.0e4);   // in microns
+       fHistDcaXYPull[iPart][iPtBin]->Fill(pull[0]);
+       fHistDcaZPull[iPart][iPtBin]->Fill(pull[1]);
+      }
+      else
+       continue;
+    }
+  }
+    
+  // for charged particles
+  for(Int_t iPtBin=0; iPtBin<kNPtBins; iPtBin++){
+    if(esdpt>fgkPtIntv[iPtBin] && esdpt<=fgkPtIntv[iPtBin+1]){
+      Int_t iPart = 10;
+      if(charge>0) iPart = 11;
+      fHistDcaXYRes[iPart][iPtBin]->Fill(residual[0]*1e4);
+      fHistDcaZRes[iPart][iPtBin]->Fill(residual[1]*1e4);
+      fHistDcaXYPull[iPart][iPtBin]->Fill(pull[0]);
+      fHistDcaZPull[iPart][iPtBin]->Fill(pull[1]);
+    }
+    else
+      continue;
+  } 
+    
+}
+
diff --git a/PWG3/hfe/AliHFEdca.h b/PWG3/hfe/AliHFEdca.h
new file mode 100644 (file)
index 0000000..f7203e4
--- /dev/null
@@ -0,0 +1,98 @@
+/**************************************************************************
+* 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 for checking impact parameter (DCA) study 
+// Study DCA in rphi (xy) and z
+// resolution and pull
+// 
+
+#ifndef ALIHFEDCA_H
+#define ALIHFEDCA_H
+
+#ifndef ROOT_TObject
+#include <TObject.h>
+#endif
+
+class TChain;
+class TTree;
+class TFile;
+
+class TString;
+class TList;
+
+class TObjArray;
+class AliStack;
+class AliMCEvent;
+
+class AliESDEvent;
+class AliESDtrack;
+class AliESDVertex;
+
+class AliHFEdca : public TObject{
+
+ public:  
+  enum{
+    kPDGelectron = 11,
+    kPDGmuon = 13,
+    kPDGpion = 211,
+    kPDGkaon = 321,
+    kPDGproton = 2212
+  };
+  enum{
+    kNParticles = 12,
+    kNPtBins = 43,   
+    kNDcaVar = 2, 
+    kNPullVar = 2
+  };
+
+  AliHFEdca();
+  AliHFEdca(const AliHFEdca &p); // copy constructor
+  AliHFEdca &operator=(const AliHFEdca &); // assignment operator
+
+  virtual ~AliHFEdca();
+
+  void Initialize();
+  void CreateHistogramsPull(TList *pullList);  
+  void CreateHistogramsResidual(TList *residualList);  
+  void InitAnalysis();  
+  void FillHistograms(AliESDEvent *esdEvent,  AliESDtrack *track,  AliMCEvent *mcEvent);
+  void PostAnalysis() const;
+
+
+ private:   
+  static const Char_t *fgkParticles[kNParticles];  // particle names
+  static const Int_t fgkColorPart[kNParticles]; // colors for particles
+
+  static const Float_t fgkPtIntv[kNPtBins+1];  // pt intervals
+
+  static const Char_t* fgkDcaVar[kNDcaVar];  // dca variables
+  static const Char_t* fgkDcaVarTitle[kNDcaVar]; // titles for dca variables
+
+  static const Char_t* fgkPullDcaVar[kNPullVar];  // pull variables
+  static const Char_t* fgkPullDcaVarTitle[kNPullVar]; // titles for pull variables
+
+  TH1F* fHistDcaXYRes[kNParticles][kNPtBins];  //! residuals in XY
+  TH1F* fHistDcaZRes[kNParticles][kNPtBins];   //! residuals in Z
+  TH1F* fHistDcaXYPull[kNParticles][kNPtBins]; //! pulls XY
+  TH1F* fHistDcaZPull[kNParticles][kNPtBins];  //! pulls Z
+
+  TList *fResidualList;   //! collection of histograms of residual
+  TList *fPullList;       //! collection of histograms of pull
+  
+  ClassDef(AliHFEdca, 1);
+};
+
+#endif
diff --git a/PWG3/hfe/AliHFEdisplacedElectrons.cxx b/PWG3/hfe/AliHFEdisplacedElectrons.cxx
new file mode 100644 (file)
index 0000000..127ce10
--- /dev/null
@@ -0,0 +1,683 @@
+/*************************************************************************
+* 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 for electrons from beauty study
+// Counting electrons from beauty
+// by DCA cuts, background subtraction 
+//
+// Authors:
+//   Hongyan Yang <hongyan@physi.uni-heidelberg.de>
+//
+
+#include "TMath.h"
+#include "TList.h"
+#include "AliLog.h"
+
+#include <TParticle.h>
+#include <TDatabasePDG.h>
+
+#include "THnSparse.h"
+#include "AliMCEvent.h"
+#include "AliESDEvent.h"
+#include "AliMCParticle.h"
+#include "AliESDtrack.h"
+
+#include "AliStack.h" 
+
+#include "AliHFEdisplacedElectrons.h"
+
+ClassImp(AliHFEdisplacedElectrons)
+
+//__________________________________________________________
+const Float_t AliHFEdisplacedElectrons::fgkDcaMinPtIntv[13] = {
+  // 
+  // define DCA low limits for single electrons cut in each Pt bin 
+  // preliminary numbers 
+  // these numbers should be replaced by the best numbers determined by 
+  // cut efficiency study: signal/background  (not used right now)
+  //
+  450, // 0.0 - 0.5
+  450, // 0.5 - 1.0
+  450, // 1.0 - 1.5
+  500, // 1.5 - 2.0
+  400, // 2.0 - 2.5
+  300, // 2.5 - 3.0
+  300, // 3.0 - 4.0
+  300, // 4.0 - 5.0
+  200, // 5.0 - 7.0
+  150, // 7.0 - 9.0
+  150, // 9.0 - 12.0
+  100, //12.0 - 16.0
+  50}; //16.0 - 20.0
+//__________________________________________________________
+const Float_t AliHFEdisplacedElectrons::fgkPtIntv[14] = {
+  //
+  // define pT bins for spectra of single electrons 
+  //
+  0.0,0.5,1.0,1.5,2.0,2.5,3.0,4.0,5.0,7.0,9.0,12.0,16.0,20.0};
+
+//__________________________________________________________
+const Char_t *AliHFEdisplacedElectrons::fgkKineVar[3] = {
+  "y", "phi", "pt"};
+
+//__________________________________________________________
+const Char_t *AliHFEdisplacedElectrons::fgkKineVarTitle[3] ={
+  "rapidity;y;dN/dy",   "azimuthal;#phi;dN/d#phi",   "transverse momentum;p_{T};dN/dp_{T}", 
+};
+
+//__________________________________________________________
+AliHFEdisplacedElectrons::AliHFEdisplacedElectrons():
+  fDebugLevel(0)
+  , fESD(0x0)
+  , fMC(0x0)
+  , fTHnSparseDcaMcPionInfo(NULL)
+  , fTHnSparseDcaMcEleInfo(NULL)
+  , fTHnSparseDcaDataEleInfo(NULL)
+  , fOutputList(0x0)
+{
+  //
+  // default constructor
+  //
+
+}
+
+//__________________________________________________________
+AliHFEdisplacedElectrons::AliHFEdisplacedElectrons(const AliHFEdisplacedElectrons &displacedElectrons):
+  TObject(displacedElectrons)
+  , fDebugLevel(0)
+  , fESD(0x0)
+  , fMC(0x0)
+  , fTHnSparseDcaMcPionInfo(NULL)
+  , fTHnSparseDcaMcEleInfo(NULL)
+  , fTHnSparseDcaDataEleInfo(NULL)
+  , fOutputList(0x0)
+  
+{
+  //
+  // copy constructor
+  //
+}
+
+
+//__________________________________________________________
+AliHFEdisplacedElectrons&AliHFEdisplacedElectrons::operator=(const AliHFEdisplacedElectrons &)
+{
+  //
+  // Assignment operator
+  //
+  Printf("Not yet implemented.");
+  return *this;
+}
+
+//__________________________________________________________
+AliHFEdisplacedElectrons::~AliHFEdisplacedElectrons()
+{
+  //
+  // default constructor
+  //
+
+  if(fTHnSparseDcaMcPionInfo) 
+    delete fTHnSparseDcaMcPionInfo;
+  if(fTHnSparseDcaMcEleInfo) 
+    delete fTHnSparseDcaMcEleInfo;
+  if(fTHnSparseDcaDataEleInfo) 
+    delete fTHnSparseDcaDataEleInfo;
+    
+  if(fOutputList){
+    fOutputList->Clear();
+    delete fOutputList;
+    
+  }
+
+  Printf("analysis done\n");
+}
+
+//__________________________________________________________
+void AliHFEdisplacedElectrons::InitAnalysis(){
+  //
+  // init analysis (no intialization yet)
+  //
+  
+
+  Printf("initialize analysis\n");
+
+}
+
+
+//__________________________________________________________
+void AliHFEdisplacedElectrons::CreateOutputs(TList* const displacedList){
+
+  //
+  //  create output fOutputList
+  //
+
+  // THnSparseF
+  // 8 interested electron sources: others, photon conv, direct photon,  pi0, eta, b, b->c, c
+  // 21 possible DCA cuts XY
+  // 21 possible DCA cuts Z
+  // 13 pT bins
+  // 10 rapidity bins
+  // 10 azimuthal angle phi bins
+
+
+  if(!displacedList) return;
+
+  fOutputList = displacedList;
+  fOutputList -> SetName("information");
+
+  // electron source 
+  Int_t nBinsEleSource = 8;
+  Double_t minEleSource = -1.5; 
+  Double_t maxEleSource = 6.5;  
+  Double_t *binLimEleSource = new Double_t[nBinsEleSource+1];
+  for(Int_t i=0; i<=nBinsEleSource; i++)
+    binLimEleSource[i] = minEleSource + i*(maxEleSource-minEleSource)/nBinsEleSource;
+
+  // dca bins: the same as XY and Z
+  // these should be variable bins as well
+  Int_t nBinsDca = kNDcaMin-1;  // 12 bins
+  Double_t minDca = -0.5; 
+  Double_t maxDca = 20.5; 
+  Double_t dcaBinWidth = (maxDca-minDca)/nBinsDca;
+  Double_t *binLimDca = new Double_t[nBinsDca+1];
+  for(Int_t i=0; i<=nBinsDca; i++)
+    binLimDca[i] = minDca + i*dcaBinWidth;
+  
+
+ // pt bins
+  Int_t nBinsPt = kNPtIntv-1;
+  Double_t *binLimPt = new Double_t[nBinsPt+1];
+  for(Int_t i=0; i<=nBinsPt; i++)
+    binLimPt[i] = fgkPtIntv[i];  // variable bins
+
+  // rapidity bins
+  Int_t nBinsRap = 10;
+  Double_t minRap = -1.0; 
+  Double_t maxRap = 1.0;
+  Double_t *binLimRap = new Double_t[nBinsRap+1];
+  for(Int_t i=0; i<=nBinsRap; i++)
+    binLimRap[i] = minRap + i*(maxRap-minRap)/nBinsRap;
+
+  // azumuthal phi angle
+  Int_t nBinsPhi = 10;
+  Double_t minPhi = 0; 
+  Double_t maxPhi = 2*TMath::Pi();
+  Double_t *binLimPhi = new Double_t[nBinsPhi+1];
+  for(Int_t i=0; i<=nBinsPhi; i++)
+    binLimPhi[i] = minPhi + i*(maxPhi-minPhi)/nBinsPhi;
+
+
+
+  //for MC pionss
+  const Int_t nVarPion = 5;
+  Int_t iBinPion[nVarPion] = {nBinsDca, nBinsDca, nBinsPt, nBinsRap, nBinsPhi};
+   
+  THnSparseF *fTHnSparseDcaMcPionInfo = NULL; // empty for the moment 
+  if(HasMCData()){
+    fTHnSparseDcaMcPionInfo = new THnSparseF("dcaMcPionInfo", 
+                                            "MC info:;dcaXY [50 #mum];dcaZ [50 #mum];pT [GeV/c];y [rapidity];#phi [rad];",     
+                                            nVarPion, iBinPion);
+    fTHnSparseDcaMcPionInfo->SetBinEdges(0, binLimDca);  // dca xy cut
+    fTHnSparseDcaMcPionInfo->SetBinEdges(1, binLimDca);  // dca z cut
+    fTHnSparseDcaMcPionInfo->SetBinEdges(2, binLimPt);   // pt
+    fTHnSparseDcaMcPionInfo->SetBinEdges(3, binLimRap);  // rapidity
+    fTHnSparseDcaMcPionInfo->SetBinEdges(4, binLimPhi);  // phi
+    fTHnSparseDcaMcPionInfo->Sumw2();
+
+    fOutputList -> AddAt(fTHnSparseDcaMcPionInfo, kMCpion);
+  }
+
+  // for MC electrons
+  const Int_t nVar = 6;
+  Int_t iBin[nVar] = {nBinsEleSource,nBinsDca, nBinsDca, nBinsPt, nBinsRap, nBinsPhi};
+  
+  THnSparseF *fTHnSparseDcaMcEleInfo = NULL; // empty for the moment 
+  if(HasMCData()){
+    fTHnSparseDcaMcEleInfo = new THnSparseF("dcaMcElectronInfo", 
+                                        "MC info:;ID [electron source id];dcaXY [50 #mum];dcaZ [50 #mum];pT [GeV/c];y [rapidity];#phi [rad];",         
+                                        nVar, iBin);
+    fTHnSparseDcaMcEleInfo->SetBinEdges(0, binLimEleSource); // electron source
+    fTHnSparseDcaMcEleInfo->SetBinEdges(1, binLimDca);  // dca xy cut
+    fTHnSparseDcaMcEleInfo->SetBinEdges(2, binLimDca);  // dca z cut
+    fTHnSparseDcaMcEleInfo->SetBinEdges(3, binLimPt);   // pt
+    fTHnSparseDcaMcEleInfo->SetBinEdges(4, binLimRap);  // rapidity
+    fTHnSparseDcaMcEleInfo->SetBinEdges(5, binLimPhi);  // phi
+    fTHnSparseDcaMcEleInfo->Sumw2();
+    fOutputList -> AddAt(fTHnSparseDcaMcEleInfo, kMCelectron);
+  }
+
+  
+  // for ESD: HFE pid
+
+  THnSparseF *fTHnSparseDcaDataEleInfo = NULL;  // empty for the moment
+  const Int_t nVarData = 5;
+  Int_t iBinData[nVarData] = {nBinsDca, nBinsDca, nBinsPt, nBinsRap, nBinsPhi};  
+  
+  fTHnSparseDcaDataEleInfo = new THnSparseF("dcaDataElectronInfo", 
+                                        "Data info:;dcaXY [50 #mum];dcaZ [50 #mum];pT [GeV/c];y [rapidity];#phi [rad];",               
+                                        nVarData, iBinData);    
+  fTHnSparseDcaDataEleInfo->SetBinEdges(0, binLimDca);  // dca xy cut
+  fTHnSparseDcaDataEleInfo->SetBinEdges(1, binLimDca);  // dca z cut
+  fTHnSparseDcaDataEleInfo->SetBinEdges(2, binLimPt);   // pt
+  fTHnSparseDcaDataEleInfo->SetBinEdges(3, binLimRap);  // rapidity
+  fTHnSparseDcaDataEleInfo->SetBinEdges(4, binLimPhi);  // phi
+  fTHnSparseDcaDataEleInfo->Sumw2();
+  
+  fOutputList -> AddAt(fTHnSparseDcaDataEleInfo, kData);
+  
+  AliInfo("THnSparse histograms are created\n");
+  fOutputList->Print();
+
+}
+
+
+//__________________________________________________________
+void AliHFEdisplacedElectrons::FillMCOutput(AliESDEvent * const fESDEvent, AliESDtrack* const esdTrack, AliStack * const stack)
+{
+
+  // fill output
+  if(!esdTrack) return;
+  AliESDtrack *track = esdTrack;
+  Double_t pt   = track->Pt();
+  Double_t eta = track->Eta();
+  Double_t phi = track->Phi();
+  
+  Int_t label = track->GetLabel();
+  if(label<0 || label>stack->GetNtrack()) return;  
+
+  TParticle *particle = stack->Particle(label);
+  if(!particle) return;
+
+  // obtain impact parameters in xy and y
+  const AliESDVertex *primVtx = fESDEvent->GetPrimaryVertex();      
+
+  Float_t magneticField = 5;  // initialized as 5kG
+  magneticField = fESDEvent->GetMagneticField();  // in kG 
+  
+
+  Double_t dz[2];   // error of dca in cm
+  Double_t covardz[3];
+  track->PropagateToDCA(primVtx,magneticField, 1000., dz, covardz); 
+
+
+  Double_t dcaXY = TMath::Abs(dz[0])*1.0e4;  // conv dca in cm to dca in micron 
+  Double_t dcaZ = TMath::Abs(dz[1])*1.0e4;
+
+  // do PID with MC
+
+  if(HasMCData() && TMath::Abs(GetMCpid(stack, label))==kPDGelectron){
+  
+    Int_t eleLabel = label; 
+    
+    const Int_t nvarMC=6;
+    Double_t var[nvarMC];
+    var[0] = -1;
+    Int_t sourcePdg = ElectronFromSource(stack, eleLabel);     
+
+    if(sourcePdg==kPDGgamma){ // check direct photon or not  // fixme      
+      if(ElePhotonDirect(stack, eleLabel)!=-1) 
+       var[0] = kEleDirectPhotonConv;    
+      else     
+       var[0] = kElePhotonConv;     
+      if(fDebugLevel>=10) 
+       printf("photonconv=====this electron %d is from %d, source id=%.1f\n", eleLabel, sourcePdg, var[0]);   
+    }   // photon or direct photon -> e
+    
+    if(sourcePdg==kPDGpi0){      
+      var[0] = kElePi0;   
+      if(fDebugLevel>=10) printf("pi0======this electron %d is from %d, source id=%.1f\n", eleLabel, sourcePdg, var[0]);    
+    } 
+
+    if(sourcePdg==kPDGeta){ 
+      var[0] = kEleEta;     
+      if(fDebugLevel>=10) 
+       printf("eta=====this electron %d is from %d, source id=%.1f\n", eleLabel, sourcePdg, var[0]);    
+    }   // from eta -> e
+
+    if(TMath::Abs(sourcePdg%10000)/100==kPDGbeauty ||    // for special intermediate meson states: like 100553       
+       TMath::Abs(sourcePdg)/1000==kPDGbeauty ||      
+       TMath::Abs(sourcePdg)/100==kPDGbeauty ||     
+       TMath::Abs(sourcePdg)==kPDGbeauty){     
+      var[0]=kEleB;       
+      if(fDebugLevel>=10) 
+       printf("beauty======electron %d is from %d with id %.1f\n", eleLabel, ElectronFromSource(stack, eleLabel), var[0]);   
+    } // direct beauty  -> e      
+    if(TMath::Abs(sourcePdg%10000)/100==kPDGcharm ||    // for special intermediate meson states: like 1004**      
+       TMath::Abs(sourcePdg)/1000==kPDGcharm ||       
+       TMath::Abs(sourcePdg)/100==kPDGcharm ||        
+       TMath::Abs(sourcePdg)==kPDGcharm){           
+      // two cases: 
+      //            electron from b->c->e     
+      //            electron from c->e     
+      if(ElectronFromCharm(stack, eleLabel)!=-1){
+       var[0] = ElectronFromCharm(stack, eleLabel);
+       if(fDebugLevel>=10)
+         printf("charm----->electron %d has mother %d is from %.1f\n", eleLabel, ElectronFromSource(stack, eleLabel), var[0]);
+      } 
+    }  // charm electrons: b->c->e or c->e
+
+    if(fDebugLevel>=10) printf("others----->electron %d has mother %d is from %.1f\n", eleLabel, ElectronFromSource(stack, eleLabel), var[0]);
+    
+    if(dcaXY<1000) var[1] = Int_t(dcaXY)/50;   // larger than 1mm should go to the last bin
+    else
+      var[1] = 20;
+    if(dcaZ<1000) var[2] = Int_t(dcaZ)/50;
+    else
+      var[2] = 20;
+
+    var[3] = pt; // pt 
+    var[4] = eta; // eta
+    var[5] = phi; // phi
+
+    (dynamic_cast<THnSparseF *>(fOutputList->At(kMCelectron)))->Fill(var);
+  }
+
+  if(HasMCData() && TMath::Abs(GetMCpid(stack, label))==kPDGpion){
+      
+    const Int_t nvarPionMC=5;
+    Double_t varPion[nvarPionMC];
+    if(dcaXY<1000)
+      varPion[0] = Int_t(dcaXY)/50; // dca xy 
+    else
+      varPion[0] = 20;
+    if(dcaZ<1000)
+      varPion[1] = Int_t(dcaZ)/50; // dca Z 
+    else
+      varPion[1] = 20;
+    
+//     varPion[0] = TMath::Abs(dcaXY); // dca xy 
+//     varPion[1] = TMath::Abs(dcaZ); // dca z    
+    varPion[2] = pt; // pt 
+    varPion[3] = eta; //eta
+    varPion[4] = phi; // phi
+    
+    (dynamic_cast<THnSparseF *>(fOutputList->At(kMCpion)))->Fill(varPion);
+  }
+  
+}
+
+
+
+//__________________________________________________________
+void AliHFEdisplacedElectrons::FillESDOutput(AliESDEvent * const fESD, AliESDtrack* const esdTrack)
+{
+
+  // fill output
+  if(!esdTrack) return;
+  AliESDtrack *track = esdTrack;
+
+  Double_t pt   = track->Pt();
+  Double_t eta = track->Eta();
+  Double_t phi = track->Phi();
+  
+  // obtain impact parameters in xy and y
+  const AliESDVertex *primVtx = fESD->GetPrimaryVertex();    
+  
+  Float_t magneticField = 5;  // initialized as 5kG
+  magneticField = fESD->GetMagneticField();  // in kG 
+  Double_t dz[2];   // error of dca in cm
+  Double_t covardz[3];
+  track->PropagateToDCA(primVtx,magneticField, 1000., dz, covardz); 
+  Double_t dcaXY = TMath::Abs(dz[0]*1.0e4);  // conv dca in cm to dca in micron 
+  Double_t dcaZ = TMath::Abs(dz[1]*1.0e4);
+  
+  const Int_t nvarData = 5;
+  Double_t varData[nvarData]; 
+  // fixme
+  if(dcaXY<1000)
+    varData[0] = Int_t(dcaXY)/50; // dca xy 
+  else 
+    varData[0] = 20;
+  if(dcaZ<1000)
+    varData[1] = Int_t(dcaZ)/50; // dca Z 
+  else
+    varData[1] = 20;
+
+  varData[2] = pt; // pt 
+  varData[3] = eta; //eta
+  varData[4] = phi; // phi
+  
+  (dynamic_cast<THnSparseF *>(fOutputList->At(kData)))->Fill(varData);
+
+}
+
+//__________________________________________________________
+Int_t AliHFEdisplacedElectrons::ElectronFromSource(AliStack * const stack, Int_t label) const
+{
+
+  //
+  //  return electron source label via electron label
+  //
+
+  // kEleSource is supposed to be either photon conv, direct photon conv, pi0, eta, beauty --> 0, 1, 2, 3, 4
+
+  Int_t eleLabel = label;
+
+  if(eleLabel<0 || eleLabel>stack->GetNtrack()) return -1;
+
+  TParticle *particle = stack->Particle(eleLabel);
+  if(!particle) return -1;
+
+  Int_t motherLabel = particle->GetFirstMother();
+  if(motherLabel<0 || motherLabel>stack->GetNtrack()) return -1;
+  TParticle *motherPart = stack->Particle(motherLabel);
+  if(!motherPart) return -1;
+
+  Int_t pdgCode = TMath::Abs(motherPart->GetPdgCode());
+
+  if(pdgCode==kPDGelectron) {
+    if(fDebugLevel>=10) printf("particle label: %d...(motherLabel=%d : motherPdg=%d)  grandmother's pdg code was returned...%d \n",
+                              label, motherLabel, pdgCode, ElectronFromSource(stack, motherLabel));
+    return ElectronFromSource(stack, motherLabel);
+  }
+
+  return pdgCode;    
+
+}
+
+//__________________________________________________________
+Int_t AliHFEdisplacedElectrons::ElectronFromCharm(AliStack * const stack, Int_t label) const
+{
+  //
+  //  separate electron: kEleC from c->eX, kEleBC from b->c->eX
+  //
+
+  Int_t motherLabel = label;
+  TParticle *motherParticle = stack->Particle(motherLabel);  // mother part
+  if(!motherParticle) return -1;
+  Int_t gMotherLabel = motherParticle->GetFirstMother();  // grand mother
+  if(gMotherLabel<0 || gMotherLabel>stack->GetNtrack()) return -1;
+  
+  TParticle *gMotherPart = stack->Particle(gMotherLabel);
+  if(!gMotherPart) return -1;
+  
+  Int_t pdgCode = gMotherPart->GetPdgCode();
+  if(TMath::Abs(pdgCode%10000)/100==kPDGbeauty ||    // for special intermediate meson states: like 100553
+     TMath::Abs(pdgCode)/1000==kPDGbeauty || TMath::Abs(pdgCode)/100==kPDGbeauty || TMath::Abs(pdgCode)==kPDGbeauty) {
+    if(fDebugLevel>=10)  printf("this electron label %d is from mother %d, and finally from %d\n", label, ElectronFromSource(stack, label), pdgCode);
+    return kEleBC;
+  }  // for sure it is from BC
+  
+  else 
+    if(TMath::Abs(pdgCode%10000)/100==kPDGcharm ||  // for special intermediate meson states: like 100443, 10443, 204*3 (*=1, 2, 3, 4)
+       TMath::Abs(pdgCode)/1000==kPDGcharm || 
+       TMath::Abs(pdgCode)/100==kPDGcharm || 
+       TMath::Abs(pdgCode)==kPDGcharm){
+      
+      if(CharmFromBeauty(stack, gMotherLabel)!=-1)
+       return kEleBC;
+      else
+       return kEleC;
+      
+    }
+  
+    else
+      return -1;
+     
+}
+
+//__________________________________________________________
+Int_t AliHFEdisplacedElectrons::CharmFromBeauty(AliStack * const stack, Int_t hfLabel) const
+{
+
+  //
+  //  check if charm meson/hadron is from beauty decay
+  //  -1, not from beauty  
+  //  return the label of the mother of this charm hadron
+  //
+
+  Int_t charmLabel = hfLabel;
+  
+  //  AliStack *stack = fMC->Stack();
+  if(charmLabel<0 || charmLabel>stack->GetNtrack()) return -1;
+  TParticle *particle = stack->Particle(charmLabel);
+  if(!particle) return -1;
+
+  Int_t motherCharmLabel = particle->GetFirstMother();
+  if(motherCharmLabel<0 || motherCharmLabel>stack->GetNtrack()) return -1;
+
+  TParticle *motherCharmPart = stack->Particle(motherCharmLabel);
+  if(!motherCharmPart) return -1;
+
+  Int_t pdgCode = motherCharmPart->GetPdgCode();
+  
+  if(TMath::Abs(pdgCode%10000)/100==kPDGbeauty ||   // for special intermediate meson states: like 100553
+     TMath::Abs(pdgCode)/1000==kPDGbeauty || 
+     TMath::Abs(pdgCode)/100==kPDGbeauty || 
+     TMath::Abs(pdgCode)==kPDGbeauty) 
+    return motherCharmLabel;  
+  else 
+    if(TMath::Abs(pdgCode%10000)/100==kPDGcharm ||    // for special intermediate meson states: like 100443, 10443, 204*3 (*=1, 2, 3, 4)
+       TMath::Abs(pdgCode)/1000==kPDGcharm || 
+       TMath::Abs(pdgCode)/100==kPDGcharm) 
+      return CharmFromBeauty(stack, motherCharmLabel);   // loop over to see if charm is from beauty -- if yes, return the label of mother of the charm
+  
+    else
+      return -1;
+}
+
+//__________________________________________________________
+Int_t AliHFEdisplacedElectrons::ElePhotonDirect(AliStack * const stack, Int_t label) const 
+{
+  //
+  // electron is from photon, and check if this photon is direct
+  //
+
+  Int_t eleLabel = label;
+  
+  TParticle *particle = stack->Particle(eleLabel);
+  if(particle->GetFirstMother()<0 || particle->GetFirstMother()>stack->GetNtrack())
+    return -1;
+  
+  TParticle *photonPart = stack->Particle(particle->GetFirstMother());
+  if(!photonPart) 
+    return -1;
+  Int_t motherPhotonLabel = photonPart->GetFirstMother();
+  if(motherPhotonLabel<0 || motherPhotonLabel>stack->GetNtrack())
+    return -1;
+
+  TParticle *motherPhotonPart = stack->Particle(motherPhotonLabel);
+  if(!motherPhotonPart) 
+    return -1;
+  
+  Int_t pdgMotherPhoton = motherPhotonPart->GetPdgCode();
+  if(TMath::Abs(pdgMotherPhoton)<=10 || TMath::Abs(pdgMotherPhoton)==21)
+    return 1;
+
+  else 
+    return -1;
+
+
+}
+
+//__________________________________________________________
+Int_t AliHFEdisplacedElectrons::GetMCpid(AliStack* const stack, Int_t partLabel) const
+{
+
+  //
+  // Simply pdg code
+  //
+  
+  Int_t label = partLabel;
+//   AliStack* stack = fMC->Stack();
+  if((label < 0) || (label >= stack->GetNtrack())) return -1;  
+
+  // MC Information
+  TParticle * particle = stack->Particle(label);
+  if(!particle) return -1;
+  Int_t pdg = particle->GetPdgCode();
+
+  return pdg;
+}
+
+//__________________________________________________________
+Int_t AliHFEdisplacedElectrons::GetMotherLabel(AliStack *const stack, Int_t eleLabel) const 
+{
+  //
+  // Simply label of mother
+  //
+
+
+  Int_t label = eleLabel;
+  //  AliStack* stack = fMC->Stack();
+  if((label < 0) || (label >= stack->GetNtrack())) return -1;  
+
+  // MC Information
+  TParticle * particle = stack->Particle(label);
+  if(!particle) return -1;
+
+  return particle->GetFirstMother();
+}
+
+
+//__________________________________________________________
+Float_t AliHFEdisplacedElectrons::GetRapidity(TParticle *part) const
+{
+  // return rapidity
+  
+  Float_t rapidity = -999;        
+  if((part->Energy() - part->Pz())*(part->Energy() + part->Pz())>0)
+    rapidity = 0.5*(TMath::Log((part->Energy()+part->Pz()) / (part->Energy()-part->Pz()))); 
+  
+  return rapidity;
+}
+
+
+//__________________________________________________________
+Float_t AliHFEdisplacedElectrons::GetTrackRapidity(AliESDtrack * const track) const
+{
+  // return rapidity of electron
+  
+  Float_t px = track->Px();
+  Float_t py = track->Py();
+  Float_t pz = track->Pz();
+
+  // electron mass 0.00051099906 GeV/c2
+  TParticlePDG* electron = TDatabasePDG::Instance()->GetParticle(kPDGelectron);
+  Double_t mass = electron->Mass();
+  
+  Float_t en = TMath::Sqrt(px*px + py*py + pz*pz + mass*mass);
+
+  Float_t rapidity = -999;        
+  if((en - pz)*(en + pz)>0)
+    rapidity = 0.5*(TMath::Log((en - pz)*(en + pz))); 
+  
+  return rapidity;
+}
diff --git a/PWG3/hfe/AliHFEdisplacedElectrons.h b/PWG3/hfe/AliHFEdisplacedElectrons.h
new file mode 100644 (file)
index 0000000..88fe574
--- /dev/null
@@ -0,0 +1,151 @@
+/**************************************************************************
+* 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 for electrons from beauty study
+// Counting electrons from beauty
+// by DCA cuts, background subtraction 
+//
+// Authors:
+//   Hongyan Yang <hongyan@physi.uni-heidelberg.de>
+// 
+
+#ifndef ALIHFEDISPLACEDELECTRONS_H
+#define ALIHFEDISPLACEDELECTRONS_H
+
+#ifndef ROOT_TObject
+#include <TObject.h>
+#endif
+
+#ifndef ROOT_TPDGCode
+#include <TPDGCode.h>
+#endif
+
+class TChain;
+class TTree;
+class TFile;
+
+class TPDGCode;
+
+class TString;
+class TList;
+
+class AliLog;
+
+class THnSparse;
+
+class TObjArray;
+class AliStack;
+class AliMCEvent;
+class AliESDEvent;
+
+class AliESDtrack;
+class AliESDVertex;
+
+class AliHFEdisplacedElectrons : public TObject{
+
+ public:  
+
+  enum{
+    kPDGelectron = kElectron,
+    kPDGgamma = kGamma,
+    kPDGpi0 = kPi0,
+    kPDGpion = kPiPlus, 
+    kPDGeta = 221,
+    kPDGcharm = kCharm,
+    kPDGbeauty = kBottom
+  };  // PDG codes to be used
+
+  AliHFEdisplacedElectrons();
+  AliHFEdisplacedElectrons(const AliHFEdisplacedElectrons &p); // copy constructor
+  AliHFEdisplacedElectrons &operator=(const AliHFEdisplacedElectrons &); // assignment operator
+
+  virtual ~AliHFEdisplacedElectrons();
+
+  void InitAnalysis();  
+  void CreateOutputs(TList* const displacedList);
+
+  void FillMCOutput(AliESDEvent* fESDEvent, AliESDtrack *track, AliStack *stack);
+  void FillESDOutput(AliESDEvent* fESDEvent, AliESDtrack *track);
+
+  Int_t GetMCpid(AliStack* stack, Int_t label) const;
+
+  Bool_t HasMCData() const { return TestBit(kHasMCData); };
+  void SetHasMCData(Bool_t hasMCdata = kTRUE) { SetBit(kHasMCData,hasMCdata); };
+  void SetDebugLevel(Int_t debugLevel){ fDebugLevel = debugLevel; };
+
+  void PostAnalysis() const;
+
+
+ private:
+
+  enum{
+    kHasMCData = BIT(15),             // bitset for mc data usage
+    kHasESDData = BIT(16)
+  };
+   
+
+
+  enum{
+    kElePhotonConv = 0,
+    kEleDirectPhotonConv = 1,
+    kElePi0 = 2,
+    kEleEta = 3, 
+    kEleB = 4, 
+    kEleC = 5, 
+    kEleBC = 6
+  };  // electron source index
+  
+  enum{
+    kMCpion = 0, 
+    kMCelectron = 1, 
+    kData = 2
+  };  // MC or Data
+
+  enum{
+    kNDcaMin = 21, 
+    kNPtIntv = 14, 
+    kNKineVar = 3
+  };   // several constant to be used
+  UInt_t fDebugLevel;   // debug level
+  AliESDEvent* fESD;              //! ESD pointer              
+  AliMCEvent*  fMC;           //! MC event             
+  const AliESDVertex *fkVertex;    //! Primary vertex
+
+  Int_t ElectronFromSource(AliStack *stack, Int_t eleLabel) const;
+  Int_t ElePhotonDirect(AliStack *stack, Int_t label) const;
+  Int_t ElectronFromCharm(AliStack *stack, Int_t eleLabel) const;
+  Int_t CharmFromBeauty(AliStack *stack, Int_t charmLabel) const;
+  
+  Int_t GetMotherLabel(AliStack *stack, Int_t label) const;
+  Float_t GetRapidity(TParticle *part) const;
+  Float_t GetTrackRapidity(AliESDtrack *track) const;
+
+  static const Float_t fgkDcaMinIntv[kNDcaMin];  // DCA cut min limit
+  static const Float_t fgkDcaMinPtIntv[kNPtIntv-1]; // DCA cut min limit in different pT bins
+  static const Float_t fgkPtIntv[kNPtIntv]; // all pt bins
+
+  static const Char_t *fgkKineVar[kNKineVar];  // particle names
+  static const Char_t *fgkKineVarTitle[kNKineVar];  // particle names
+
+  THnSparseF *fTHnSparseDcaMcPionInfo;   //! container for MC part
+  THnSparseF *fTHnSparseDcaMcEleInfo;   //! container for MC part
+  THnSparseF *fTHnSparseDcaDataEleInfo; //! container for Data part
+
+  TList *fOutputList;  //! output container
+  ClassDef(AliHFEdisplacedElectrons, 0);
+};
+
+#endif
diff --git a/PWG3/hfe/AliHFEefficiency.cxx b/PWG3/hfe/AliHFEefficiency.cxx
new file mode 100644 (file)
index 0000000..79c995c
--- /dev/null
@@ -0,0 +1,381 @@
+/**************************************************************************
+* 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 Efficiency studies
+// Used for testing classes AliHFEcontainer and AliHFEfilter
+// Creates Efficiency Histograms
+//
+// Author:
+//   Markus Fasel <M.Fasel@gsi.de>
+//
+#include <TAxis.h>
+#include <TCanvas.h>
+#include <TFile.h>
+#include <TGraphErrors.h>
+#include <TH1F.h>
+#include <TH2.h>
+#include <TIterator.h>
+#include <TLegend.h>
+#include <TObjArray.h>
+#include <TPad.h>
+
+#include "AliCFAcceptanceCuts.h"
+#include "AliCFContainer.h"
+#include "AliCFEffGrid.h"
+#include "AliESDEvent.h"
+#include "AliHFEcollection.h"
+#include "AliHFEcontainer.h"
+#include "AliHFEcutStep.h"
+#include "AliHFEefficiency.h"
+#include "AliHFEextraCuts.h"
+#include "AliHFEtrackFilter.h"
+#include "AliHFEtools.h"
+#include "AliMCEvent.h"
+
+ClassImp(AliHFEefficiency)
+
+AliHFEefficiency::AliHFEefficiency():
+  AliAnalysisTaskSE(),
+  fFilter(NULL),
+  fMCcut(NULL),
+  fAcceptanceCuts(NULL),
+  fEfficiency(NULL),
+  fOutput(NULL),
+  fCutTRD(kFALSE)
+{
+  //
+  // Default constructor
+  //
+}
+
+AliHFEefficiency::AliHFEefficiency(const Char_t *name):
+  AliAnalysisTaskSE(name),
+  fFilter(NULL),
+  fMCcut(NULL),
+  fAcceptanceCuts(NULL),
+  fEfficiency(NULL),
+  fOutput(NULL),
+  fCutTRD(kFALSE)
+{
+  //
+  // Main Constructor
+  //
+  DefineOutput(1, AliHFEcontainer::Class());
+  DefineOutput(2, TList::Class());
+}
+
+AliHFEefficiency::~AliHFEefficiency(){
+  //
+  // Destructor
+  //
+  if(fFilter) delete fFilter;
+  if(fEfficiency) delete fEfficiency;
+  if(fAcceptanceCuts) delete fAcceptanceCuts;
+  if(fOutput) delete fOutput;
+}
+
+void AliHFEefficiency::UserCreateOutputObjects(){
+  //
+  // Create the output objects
+  //
+  fEfficiency = new AliHFEcontainer("Efficiency");
+  fEfficiency->SetNumberOfVariables(4);
+  // InitializeVariables
+  fEfficiency->SetVariableName(0, "pt");
+  fEfficiency->MakeLogarithmicBinning(0, 40, 0.1, 10);
+  fEfficiency->SetVariableName(1, "Eta");
+  fEfficiency->MakeLinearBinning(1, 20, -0.9, 0.9);
+  fEfficiency->SetVariableName(2, "phi");
+  fEfficiency->MakeLinearBinning(2 , 18, 0, 2 * TMath::Pi());
+  fEfficiency->SetVariableName(3, "Charge");
+  fEfficiency->MakeLinearBinning(3, 2, -1.1, 1.1);
+  // New container
+  fEfficiency->CreateContainer("MCFilter", "Efficiency for MC Studies", 2);
+  AliCFContainer *cont = fEfficiency->GetCFContainer("MCFilter");
+  cont->SetStepTitle(0, "MC Signal");
+  cont->SetStepTitle(1, "MC Signal in acceptance");
+
+  fFilter = new AliHFEtrackFilter("testfilter");
+  fFilter->GenerateCutSteps();
+  fFilter->InitCF(fEfficiency);
+  fMCcut = fFilter->GetMCSignalCuts();
+  if(fCutTRD){
+    AliHFEcutStep *hfeTRD = fFilter->GetCutStep("HFETRD");
+    AliHFEextraCuts *hfecuts = dynamic_cast<AliHFEextraCuts *>(hfeTRD->GetCut("HFETRDCuts"));
+    hfecuts->SetMinTrackletsTRD(4);
+  }
+  AliHFEcutStep *hfeITS = fFilter->GetCutStep("HFEITS");
+  AliHFEextraCuts *hfeitscuts = dynamic_cast<AliHFEextraCuts *>(hfeITS->GetCut("HFEPixelsCuts"));
+  hfeitscuts->SetRequireITSpixel(AliHFEextraCuts::kFirst);
+
+  fAcceptanceCuts = new AliCFAcceptanceCuts("Acceptance", "MC Acceptance Cuts");
+  fAcceptanceCuts->SetMinNHitITS(3);
+  fAcceptanceCuts->SetMinNHitTPC(2);
+  fAcceptanceCuts->SetMinNHitTRD(0);
+
+  // create additional histos for testing purpose
+  fOutput = new AliHFEcollection("histos", "QA histograms");
+  fOutput->CreateTH1F("hNtracks","Number of Tracks per Event", 100, 0, 100);
+  fOutput->CreateTH1F("hPt","Pt of the tracks", 40, 0.1, 10);
+  fOutput->BinLogAxis("hPt", 0);
+  fOutput->CreateTH1F("kinkIndex", "Kink Index", 400, -200, 200);
+  fOutput->CreateTH1F("itspixel", "ITS PIXEL", 2, 0, 2);
+  fOutput->CreateTH1F("mcmother", "Mother PDG", 1000, -500, 500);
+  fOutput->CreateTH2F("ptres", "Pt Resolution", 40, 0.1, 10, 200, -1.5, 1.5);
+  fOutput->BinLogAxis("ptres", 0);
+}
+
+void AliHFEefficiency::UserExec(Option_t *){
+  //
+  // Event Loop
+  // Filter track, fill Efficiency container
+  //
+  fEfficiency->NewEvent();
+  fFilter->SetRecEvent(fInputEvent);
+  if(fMCEvent){
+    fFilter->SetMC(fMCEvent);
+    FilterMC();
+  }
+  fFilter->FilterTracks(dynamic_cast<AliESDEvent *>(fInputEvent));
+  TObjArray *tracks = fFilter->GetFilteredTracks();
+  TIterator *iter = tracks->MakeIterator();
+  fOutput->Fill("hNtracks", tracks->GetEntriesFast());
+  AliESDtrack *track = NULL;
+  while((track = dynamic_cast<AliESDtrack *>(iter->Next()))){
+    fOutput->Fill("hPt", track->Pt());  
+    fOutput->Fill("kinkIndex", track->GetKinkIndex(0));
+    if(TESTBIT(track->GetITSClusterMap(), 0))
+      fOutput->Fill("itspixel",1);
+    else
+      fOutput->Fill("itspixel",0);
+    AliMCParticle *mctrack = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(TMath::Abs(track->GetLabel())));
+    AliMCParticle *mother = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(mctrack->Particle()->GetFirstMother()));
+    fOutput->Fill("mcmother", mother->Particle()->GetPdgCode());
+    fOutput->Fill("ptres", mctrack->Pt(), (track->Pt() - mctrack->Pt())/mctrack->Pt());
+  }
+  delete iter;
+  fFilter->Flush();
+  PostData(1, fEfficiency);
+  PostData(2, fOutput->GetList());
+}
+
+void AliHFEefficiency::Terminate(Option_t *){
+  //
+  // Evaluate Results
+  //
+  fEfficiency = dynamic_cast<AliHFEcontainer *>(GetOutputData(1));
+  if(!fEfficiency) return;
+  PostProcess();
+
+  TList *l = dynamic_cast<TList *>(GetOutputData(2));
+  DrawPtResolution(l);
+}
+
+void AliHFEefficiency::FilterMC(){
+  //
+  // Cut MC tracks
+  //
+  Double_t cont[4] = {0., 0., 0., 0.};
+  AliMCParticle *track = NULL;
+  for(Int_t itrack = 0; itrack < fMCEvent->GetNumberOfTracks(); itrack++){
+    track = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(itrack));
+    if(!fMCcut->IsSelected(track)) continue;
+    cont[0] = track->Pt();
+    cont[1] = track->Eta();
+    cont[2] = track->Phi();
+    cont[3] = track->Charge()/3;
+    //AliMCParticle *mother = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(track->Particle()->GetFirstMother()));
+    //if(TMath::Abs(mother->Particle()->GetPdgCode()) != 443) continue;
+    fEfficiency->FillCFContainer("MCFilter", 0, cont);
+    if(!fAcceptanceCuts->IsSelected(track)) continue;
+    fEfficiency->FillCFContainer("MCFilter", 1, cont);
+  }
+}
+
+void AliHFEefficiency::Load(const char* filename){
+  TFile *input = TFile::Open(filename);
+  AliHFEcontainer *cin = dynamic_cast<AliHFEcontainer *>(input->Get("Efficiency"));
+  fEfficiency = dynamic_cast<AliHFEcontainer *>(cin->Clone());
+  input->Close();
+  delete input;
+}
+
+void AliHFEefficiency::PostProcess(){
+  //
+  // Calculate Efficiencies
+  //
+  fEfficiency->Print();
+
+  // Prepare containers
+  AliCFContainer *crec  = fEfficiency->MakeMergedCFContainer("merged", "Merged Container", "MCFilter:testfilter_container_signal");
+  AliCFContainer *cmc   = fEfficiency->MakeMergedCFContainer("merged", "Merged Container", "MCFilter:testfilter_container_signalMC");
+  AliCFEffGrid *gridRec = new AliCFEffGrid("effrec", "Efficiency Calculation using rec vars", *crec);
+  AliCFEffGrid *gridMC  = new AliCFEffGrid("effmc", "Efficiency Calculation using mc vars", *cmc);
+
+  TCanvas *ctmp = NULL;
+  for(Int_t ivar = 0; ivar < crec->GetNVar(); ivar++){
+    ctmp = new TCanvas(Form("cEffSignal%s", crec->GetVarTitle(ivar)), Form("Signal Efficiency (%s)", crec->GetVarTitle(ivar)));
+    ctmp->cd();
+    DrawSignalEfficiency(gridRec, crec, ivar);
+    
+    ctmp = new TCanvas(Form("cCutEff%s", crec->GetVarTitle(ivar)), Form("Cut Step Efficiency (%s)", crec->GetVarTitle(ivar)));
+    ctmp->cd();
+    DrawCutEfficiency(gridRec, crec, ivar);
+  
+    ctmp = new TCanvas(Form("cEffSignalMC%s", crec->GetVarTitle(ivar)), Form("Signal Efficiency (%s, MC)", crec->GetVarTitle(ivar)));
+    ctmp->cd();
+    DrawSignalEfficiency(gridMC, cmc, ivar);
+
+    ctmp = new TCanvas(Form("cCutEffMC%s", crec->GetVarTitle(ivar)), Form("Cut Step Efficiency (%s, MC)", crec->GetVarTitle(ivar)));
+    ctmp->cd();
+    DrawCutEfficiency(gridMC, cmc, ivar);
+  } 
+
+  CalculatePTsmearing();
+
+  delete gridRec;
+  delete gridMC;
+  delete crec;
+  delete cmc;
+}
+
+void AliHFEefficiency::DrawSignalEfficiency(AliCFEffGrid *eff, AliCFContainer *cont, Int_t var){
+  //
+  // Efficiency of a cut step with respect to the signal
+  //
+  TH1 *hEff = NULL;
+  Bool_t kFirst = kTRUE;
+  TLegend *leg = new TLegend(0.5, 0.7, 0.89, 0.89);
+  for(Int_t istep = 1; istep < cont->GetNStep(); istep++){
+    eff->CalculateEfficiency(istep, 0);
+    hEff = eff->Project(var);
+    hEff->SetTitle(Form("Signal Efficiency (%s)", cont->GetVarTitle(var)));
+    hEff->GetYaxis()->SetRangeUser(0., 1.6);
+    hEff->GetYaxis()->SetTitle("Efficiency");
+    hEff->SetStats(kFALSE);
+    hEff->SetMarkerStyle(20+istep);
+    hEff->SetMarkerColor(kBlue - 5 + istep);
+    hEff->Draw(kFirst ? "ep" : "epsame");
+    kFirst = kFALSE;
+    leg->AddEntry(hEff, cont->GetStepTitle(istep), "p");
+  }
+  leg->SetBorderSize(0);
+  leg->SetFillStyle(0);
+  leg->Draw();
+  gPad->Update();
+}
+
+void AliHFEefficiency::DrawCutEfficiency(AliCFEffGrid *eff, AliCFContainer *cont, Int_t var){
+  //
+  // Efficiency of a cut step with respect to the previous one
+  //
+  Bool_t kFirst = kTRUE;
+  TH1 *hEff = NULL;
+  TLegend *leg = new TLegend(0.5, 0.7, 0.89, 0.89);
+  TString effTitle;
+  Int_t start = 0, length = 0;
+  for(Int_t istep = 1; istep < cont->GetNStep(); istep++){
+    eff->CalculateEfficiency(istep, istep -1);
+    hEff = eff->Project(var);
+    effTitle = hEff->GetTitle();
+    start = effTitle.Index("projected"); length = effTitle.Length() - start;
+    effTitle.Remove(start - 1, length + 1);
+    effTitle.ReplaceAll("Efficiency: ", "");
+    hEff->SetTitle(Form("Cut Efficiency (%s)", cont->GetVarTitle(var)));
+    hEff->GetYaxis()->SetRangeUser(0., 1.6);
+    hEff->GetYaxis()->SetTitle("Efficiency");
+    hEff->SetStats(kFALSE);
+    hEff->SetMarkerStyle(20+istep);
+    hEff->SetMarkerColor(kBlue - 5 + istep);
+    hEff->Draw(kFirst ? "ep" : "epsame");
+    kFirst = kFALSE;
+    leg->AddEntry(hEff, effTitle.Data(), "p");
+  }
+  leg->SetBorderSize(0);
+  leg->SetFillStyle(0);
+  leg->Draw();
+  gPad->Update();
+}
+
+void AliHFEefficiency::CalculatePTsmearing(){
+  //
+  // Efficiency of a cut step with respect to the same cut step filled with MC 
+  // Information
+  //
+  AliCFContainer *cont = fEfficiency->MakeMergedCFContainer("merged", "Merged Container", "testfilter_container_signal:testfilter_container_signalMC");
+  AliCFEffGrid *grid = new AliCFEffGrid("effc", "Efficiency Calculation", *cont);
+  Bool_t kFirst = kTRUE;
+  TH1 *hEff = NULL;
+  TCanvas *c2 = new TCanvas("cSmear", "pT modification");
+  c2->cd();
+  TLegend *leg1 = new TLegend(0.5, 0.7, 0.89, 0.89);
+  Int_t nStep = cont->GetNStep()/2;
+  for(Int_t istep = 0; istep < nStep; istep++){
+    grid->CalculateEfficiency(istep, istep + nStep);
+    hEff = grid->Project(0);
+    hEff->SetStats(kFALSE);
+    hEff->SetMarkerStyle(20+istep);
+    hEff->SetMarkerColor(kBlue - 5 + istep);
+    hEff->Draw(kFirst ? "ep" : "epsame");
+    kFirst = kFALSE;
+    leg1->AddEntry(hEff, cont->GetStepTitle(istep), "p");
+  }
+  leg1->Draw();
+  gPad->Update();
+
+  delete cont;
+  delete grid;
+}
+
+void AliHFEefficiency::DrawPtResolution(TList *l){
+  //
+  // Draw pt resolution
+  //
+  TH2 *h2 = dynamic_cast<TH2 *>(l->FindObject("ptres"));
+  TGraphErrors *mean = new TGraphErrors(h2->GetNbinsX());
+  TGraphErrors *rms = new TGraphErrors(h2->GetNbinsX());
+
+  Double_t pt = 0., pterr = 0., mymean = 0., myrms = 0., mymeanerr = 0., myrmserr = 0.;
+  TH1 *htmp = NULL;
+  for(Int_t imom = 1; imom <= h2->GetXaxis()->GetLast(); imom++){
+    pt = h2->GetXaxis()->GetBinCenter(imom);
+    pterr = h2->GetXaxis()->GetBinWidth(imom)/2.;
+    htmp = h2->ProjectionY("py", imom, imom);
+    mymean = htmp->GetMean();
+    myrms = htmp->GetRMS();
+    mymeanerr = htmp->GetMeanError();
+    myrmserr = htmp->GetRMSError();
+    delete htmp;
+    mean->SetPoint(imom -1, pt, mymean);
+    rms->SetPoint(imom -1, pt, myrms);
+    mean->SetPointError(imom-1,pterr,mymeanerr);
+    rms->SetPointError(imom-1,pterr,myrmserr);
+  }
+
+  TCanvas *c1 = new TCanvas("cPtShift", "pT Shift");
+  c1->cd();
+  mean->SetMarkerStyle(22);
+  mean->SetMarkerColor(kBlue);
+  mean->Draw("ape");
+  rms->SetMarkerStyle(22);
+  rms->SetMarkerColor(kBlack);
+  rms->Draw("pesame");
+  TLegend *leg = new TLegend(0.5, 0.7, 0.89, 0.89);
+  leg->AddEntry(mean, "Mean", "lp");
+  leg->AddEntry(rms, "RMS", "lp");
+  leg->Draw();
+  gPad->Update();
+} 
+
diff --git a/PWG3/hfe/AliHFEefficiency.h b/PWG3/hfe/AliHFEefficiency.h
new file mode 100644 (file)
index 0000000..6de24e3
--- /dev/null
@@ -0,0 +1,75 @@
+/**************************************************************************
+* 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 Efficiency studies
+// Used for testing classes AliHFEcontainer and AliHFEfilter
+// Creates Efficiency Histograms
+//
+#ifndef ALIHFEEFFICIENCY_H
+#define ALIHFEEFFICIENCY_H
+
+#include "AliAnalysisTaskSE.h"
+
+class TList;
+class TObjArray;
+class AliCFAcceptanceCuts;
+class AliCFEffGrid;
+class AliCFContainer;
+class AliHFEcollection;
+class AliHFEcontainer;
+class AliHFEtrackFilter;
+
+class AliHFEefficiency : public AliAnalysisTaskSE{
+  public:
+    AliHFEefficiency();
+    AliHFEefficiency(const Char_t *name);
+    ~AliHFEefficiency();
+
+    virtual void UserCreateOutputObjects(); 
+    virtual void UserExec(Option_t *);
+    virtual void Terminate(Option_t *);
+
+    void FilterMC();
+    void CutTRD() { fCutTRD = kTRUE; }
+
+    void SetHFEcontainer(AliHFEcontainer * const cont) { fEfficiency = cont; };
+    void UnsetHFEcontainer() { fEfficiency = NULL; }
+
+    void Load(const char* filename = "EffTask.root");
+    void PostProcess();
+
+    void CalculatePTsmearing();
+    void DrawPtResolution(TList *l);
+
+  private:
+    enum{
+      kNTracks,
+      kPt
+    };
+    AliHFEefficiency(const AliHFEefficiency &);
+    AliHFEefficiency &operator=(const AliHFEefficiency &);
+    void DrawSignalEfficiency(AliCFEffGrid *eff, AliCFContainer *cont, Int_t var);
+    void DrawCutEfficiency(AliCFEffGrid *eff, AliCFContainer *cont, Int_t var);
+
+    AliHFEtrackFilter *fFilter;           //! Track Filter
+    AliHFEcutStep *fMCcut;                //! MC Signal
+    AliCFAcceptanceCuts *fAcceptanceCuts; //! MC Acceptance cuts
+    AliHFEcontainer *fEfficiency;         //! Efficiency container
+    AliHFEcollection *fOutput;            //! QA histo container
+    Bool_t fCutTRD;                       //  Apply TRD cuts
+
+    ClassDef(AliHFEefficiency, 1);
+};
+#endif
index a5d9be0..b1b9d11 100644 (file)
 #include <TAxis.h>
 #include <TH1D.h>
 #include <TH2D.h>
+#include <TH1F.h>
+#include <TH2F.h>
+#include <TF1.h>
 #include <TString.h>
 #include <TLegend.h>
+#include <TStyle.h>
 
 #include <AliESDEvent.h>
 #include <AliAODEvent.h>
 #include "AliHFEelecbackground.h"
 #include <AliMCEvent.h>
 #include <AliStack.h>
-
+#include <AliKFParticle.h>
+#include "AliCFContainer.h"
+#include "AliHFEpid.h"
+#include "AliESDpid.h"
+#include "AliITSPIDResponse.h"
+#include "AliTPCPIDResponse.h"
 
 ClassImp(AliHFEelecbackground)
 
@@ -70,6 +79,19 @@ AliHFEelecbackground::AliHFEelecbackground():
   ,fMotherEta(-1)
   ,fIsPartner(kFALSE)
   ,fIsSplittedTrack(kFALSE)
+  ,fOpeningAngleCut(0.35)
+  ,fInvMassCut(140.0)
+  ,fChi2NdfCut(999999999.0)
+  ,fUseAliKFCode(kTRUE)
+  ,fSharedClusterCut(kFALSE)
+  ,fRequireITSStandalone(0)
+  ,fMinNbCls(2)
+  ,fMinITSChi2(10.0)
+  ,fMinNbClsSDDSPD(2)
+  ,fPIDPartner(kFALSE)
+  ,fPIDMethodPartner(0x0)
+  ,fPIDMethodPartnerITS(0x0)
+  ,fDebugLevel(0)
   ,fList(0x0)
   ,fListPostProcess(0x0)
 { 
@@ -99,6 +121,19 @@ AliHFEelecbackground::AliHFEelecbackground(const AliHFEelecbackground &p):
   ,fMotherEta(-1)
   ,fIsPartner(kFALSE)
   ,fIsSplittedTrack(kFALSE)
+  ,fOpeningAngleCut(0.35)
+  ,fInvMassCut(140.0)
+  ,fChi2NdfCut(999999999.0)
+  ,fUseAliKFCode(kTRUE)
+  ,fSharedClusterCut(kFALSE)
+  ,fRequireITSStandalone(0)
+  ,fMinNbCls(2)
+  ,fMinITSChi2(10.0)
+  ,fMinNbClsSDDSPD(2)
+  ,fPIDPartner(kFALSE)
+  ,fPIDMethodPartner(0x0)
+  ,fPIDMethodPartnerITS(0x0)
+  ,fDebugLevel(0)
   ,fList(0x0)  
   ,fListPostProcess(0x0)
 { 
@@ -125,6 +160,8 @@ AliHFEelecbackground::~AliHFEelecbackground()
   //
   // Destructor
   //
+  if(fPIDMethodPartner) delete fPIDMethodPartner;
+  if(fPIDMethodPartnerITS) delete fPIDMethodPartnerITS;
 
   if(fList){
     fList->Clear();
@@ -137,7 +174,7 @@ AliHFEelecbackground::~AliHFEelecbackground()
   }
 }
 //___________________________________________________________________________________________
-Bool_t AliHFEelecbackground::Load(const Char_t *filename)
+Bool_t AliHFEelecbackground::Load(const Char_t * filename)
 {
   //
   // Generic container loader
@@ -158,6 +195,16 @@ Bool_t AliHFEelecbackground::Load(const Char_t *filename)
   gFile->Close();
   return kTRUE;
 }
+//___________________________________________________________________________________________
+Bool_t AliHFEelecbackground::Load(TList * const outputlist)
+{
+  //
+  // Generic container loader
+  //
+  if(!outputlist) return kFALSE;
+  else   fList = (TList*)outputlist->Clone("HFEelecbackground");
+  return kTRUE;
+}
 //_______________________________________________________________________________________________
 void AliHFEelecbackground::Reset()
 {
@@ -176,25 +223,34 @@ void AliHFEelecbackground::Reset()
   fMotherEta = -1;
   fIsPartner = kFALSE;
   fIsSplittedTrack = kFALSE;
+  for(Int_t id = 0; id < 10; id++) {
+    fCuts[id] = kFALSE;
+  }
  
 }
 //_______________________________________________________________________________________________
-void AliHFEelecbackground::CreateHistograms(TList* const qaList)
+void AliHFEelecbackground::CreateHistograms(TList * const qaList)
 { 
   //
   // create histograms
   //
   if(!qaList) return;
-  
+
   fList = qaList;
-  fList->SetName("HFEelecbackground");
-  
+  fList->SetName("HFEelecbackground");  
+
+  //////////
   // bins
+  /////////
 
   Int_t nBinsPt = 25;
-  Double_t minPt = 0.001;
+  Double_t minPt = 0.01;
   Double_t maxPt = 10.0;
   
+  Int_t nBinsPtMore = 100;
+  Double_t minPtMore = 0.01;
+  Double_t maxPtMore = 10.0;
+  
   Int_t nBinsInv = 50;
   Double_t minInv = 0.0;
   Double_t maxInv = 0.2;
@@ -203,239 +259,269 @@ void AliHFEelecbackground::CreateHistograms(TList* const qaList)
   Double_t minOp = 0.0;
   Double_t maxOp = 2;
 
+  Int_t nBinsCh = 4;
+  Double_t minCh = 0.0;
+  Double_t maxCh = 4.0;
+  
   Double_t *binLimLogPt = new Double_t[nBinsPt+1];
   Double_t *binLimPt    = new Double_t[nBinsPt+1];
   for(Int_t i=0; i<=nBinsPt; i++) binLimLogPt[i]=(Double_t)TMath::Log10(minPt) + (TMath::Log10(maxPt)-TMath::Log10(minPt))/nBinsPt*(Double_t)i ;
   for(Int_t i=0; i<=nBinsPt; i++) binLimPt[i]=(Double_t)TMath::Power(10,binLimLogPt[i]);
 
+  Double_t *binLimLogPtMore = new Double_t[nBinsPtMore+1];
+  Double_t *binLimPtMore    = new Double_t[nBinsPtMore+1];
+  for(Int_t i=0; i<=nBinsPtMore; i++) binLimLogPtMore[i]=(Double_t)TMath::Log10(minPtMore) + (TMath::Log10(maxPtMore)-TMath::Log10(minPtMore))/nBinsPtMore*(Double_t)i ;
+  for(Int_t i=0; i<=nBinsPtMore; i++) binLimPtMore[i]=(Double_t)TMath::Power(10,binLimLogPtMore[i]);
+
   Double_t *binLimInv    = new Double_t[nBinsInv+1];
   for(Int_t i=0; i<=nBinsInv; i++) binLimInv[i]=(Double_t)minInv  + (maxInv-minInv)  /nBinsInv*(Double_t)i ;
   
   Double_t *binLimOp    = new Double_t[nBinsOp+1];
   for(Int_t i=0; i<=nBinsOp; i++) binLimOp[i]=(Double_t)minOp  + (maxOp-minOp) /nBinsOp*(Double_t)i ;
   
+  Double_t *binLimCh    = new Double_t[nBinsCh+1];
+  for(Int_t i=0; i<=nBinsCh; i++) binLimCh[i]=(Double_t)minCh  + (maxCh-minCh) /nBinsCh*(Double_t)i ;
   
-  const Int_t nvarO = 3; // ptrectaggede, ptrecmother, openingangle or invmass
+  const Int_t nvarData = 5;
+  // pt reconstructed tagged e
+  // pt reconstructed mother
+  // opening angle
+  // invariant mass 
+  // Data: charge (0-opposite sign, 1-like sign ++, 2-like sign --, 3-rotated tracks)
 
-  Int_t iBinOInv[nvarO];
-  iBinOInv[0]=nBinsPt;
-  iBinOInv[1]=nBinsPt;
-  iBinOInv[2]=nBinsInv;
+  Int_t iBinData[nvarData];
+  iBinData[0]=nBinsPt;
+  iBinData[1]=nBinsPt;
+  iBinData[2]=nBinsOp;
+  iBinData[3]=nBinsInv;
+  iBinData[4]=nBinsCh;
   
-  Int_t iBinOOp[nvarO];
-  iBinOOp[0]=nBinsPt;
-  iBinOOp[1]=nBinsPt;
-  iBinOOp[2]=nBinsOp;
-  
-  //
   //
+  // Opening angle and invariant mass
   //
   
-  THnSparseF *openinganglepp = new THnSparseF("openinganglepp","",nvarO,iBinOOp);
-  openinganglepp->SetBinEdges(0,binLimPt);
-  openinganglepp->SetBinEdges(1,binLimPt);
-  openinganglepp->SetBinEdges(2,binLimOp);
-  openinganglepp->Sumw2();
-  
-  THnSparseF *openinganglenn = new THnSparseF("openinganglenn","",nvarO,iBinOOp);
-  openinganglenn->SetBinEdges(0,binLimPt);
-  openinganglenn->SetBinEdges(1,binLimPt);
-  openinganglenn->SetBinEdges(2,binLimOp);
-  openinganglenn->Sumw2();
-  
-  THnSparseF *openingangless = new THnSparseF("openingangless","",nvarO,iBinOOp);
-  openingangless->SetBinEdges(0,binLimPt);
-  openingangless->SetBinEdges(1,binLimPt);
-  openingangless->SetBinEdges(2,binLimOp);
-  openingangless->Sumw2();
-  
-  THnSparseF *openingangler = new THnSparseF("openingangler","",nvarO,iBinOOp);
-  openingangler->SetBinEdges(0,binLimPt);
-  openingangler->SetBinEdges(1,binLimPt);
-  openingangler->SetBinEdges(2,binLimOp);
-  openingangler->Sumw2();
-  
-  THnSparseF *openingangleos = new THnSparseF("openingangleos","",nvarO,iBinOOp);
-  openingangleos->SetBinEdges(0,binLimPt);
-  openingangleos->SetBinEdges(1,binLimPt);
-  openingangleos->SetBinEdges(2,binLimOp);
-  openingangleos->Sumw2();
+  THnSparseF *hsSparseData = new THnSparseF("OpeningangleinvmassData","",nvarData,iBinData);
+  hsSparseData->SetBinEdges(0,binLimPt);
+  hsSparseData->SetBinEdges(1,binLimPt);
+  hsSparseData->SetBinEdges(2,binLimOp);
+  hsSparseData->SetBinEdges(3,binLimInv);
+  hsSparseData->SetBinEdges(4,binLimCh);
+  hsSparseData->Sumw2();
 
-  THnSparseF *openinganglepi0=0x0;
-  THnSparseF *openingangleeta=0x0;
-  THnSparseF *openinganglegamma=0x0;
-  THnSparseF *openingangleC=0x0;
-  THnSparseF *openingangleB=0x0;
-  THnSparseF *openingangleSplittedTrackss=0x0;
-  THnSparseF *openingangleSplittedTrackos=0x0;
+  fList->AddAt(hsSparseData,kDatai);
 
-  if(HasMCData()) {
+  //
+  // Radius, DCA and Chi2Ndf
+  //
 
-    openinganglepi0 = new THnSparseF("openinganglepi0","",nvarO,iBinOOp);
-    openinganglepi0->SetBinEdges(0,binLimPt);
-    openinganglepi0->SetBinEdges(1,binLimPt);
-    openinganglepi0->SetBinEdges(2,binLimOp);
-    openinganglepi0->Sumw2();
-    
-    openingangleeta = new THnSparseF("openingangleeta","",nvarO,iBinOOp);
-    openingangleeta->SetBinEdges(0,binLimPt);
-    openingangleeta->SetBinEdges(1,binLimPt);
-    openingangleeta->SetBinEdges(2,binLimOp);
-    openingangleeta->Sumw2();    
-
-    openinganglegamma = new THnSparseF("openinganglegamma","",nvarO,iBinOOp);
-    openinganglegamma->SetBinEdges(0,binLimPt);
-    openinganglegamma->SetBinEdges(1,binLimPt);
-    openinganglegamma->SetBinEdges(2,binLimOp);
-    openinganglegamma->Sumw2();
-
-    openingangleC = new THnSparseF("openingangleC","",nvarO,iBinOOp);
-    openingangleC->SetBinEdges(0,binLimPt);
-    openingangleC->SetBinEdges(1,binLimPt);
-    openingangleC->SetBinEdges(2,binLimOp);
-    openingangleC->Sumw2();
-
-    openingangleB = new THnSparseF("openingangleB","",nvarO,iBinOOp);
-    openingangleB->SetBinEdges(0,binLimPt);
-    openingangleB->SetBinEdges(1,binLimPt);
-    openingangleB->SetBinEdges(2,binLimOp);
-    openingangleB->Sumw2();
-
-    openingangleSplittedTrackss = new THnSparseF("openingangleSplittedTrackss","",nvarO,iBinOOp);
-    openingangleSplittedTrackss->SetBinEdges(0,binLimPt);
-    openingangleSplittedTrackss->SetBinEdges(1,binLimPt);
-    openingangleSplittedTrackss->SetBinEdges(2,binLimOp);
-    openingangleSplittedTrackss->Sumw2();
-
-    openingangleSplittedTrackos = new THnSparseF("openingangleSplittedTrackos","",nvarO,iBinOOp);
-    openingangleSplittedTrackos->SetBinEdges(0,binLimPt);
-    openingangleSplittedTrackos->SetBinEdges(1,binLimPt);
-    openingangleSplittedTrackos->SetBinEdges(2,binLimOp);
-    openingangleSplittedTrackos->Sumw2();
+  TH1F *dataRadiusHisto = new TH1F("DataRadius","", 200, 0.0, 200.0); // recontructed radius from the AliKF of the e+e- pair
+  fList->AddAt(dataRadiusHisto,kDatar);
 
-  }
+  TH1F *dataDcaHisto = new TH1F("DataDCA","", 100, 0.0, 6.0); // dca distribution
+  fList->AddAt(dataDcaHisto,kDatadca); 
   
-  //
-  
-  THnSparseF *invmasspp = new THnSparseF("invmasspp","",nvarO,iBinOInv);
-  invmasspp->SetBinEdges(0,binLimPt);
-  invmasspp->SetBinEdges(1,binLimPt);
-  invmasspp->SetBinEdges(2,binLimInv);
-  invmasspp->Sumw2();
-  
-  THnSparseF *invmassnn = new THnSparseF("invmassnn","",nvarO,iBinOInv);
-  invmassnn->SetBinEdges(0,binLimPt);
-  invmassnn->SetBinEdges(1,binLimPt);
-  invmassnn->SetBinEdges(2,binLimInv);
-  invmassnn->Sumw2();
-  
-  THnSparseF *invmassss = new THnSparseF("invmassss","",nvarO,iBinOInv);
-  invmassss->SetBinEdges(0,binLimPt);
-  invmassss->SetBinEdges(1,binLimPt);
-  invmassss->SetBinEdges(2,binLimInv);
-  invmassss->Sumw2();
-  
-  THnSparseF *invmassr = new THnSparseF("invmassr","",nvarO,iBinOInv);
-  invmassr->SetBinEdges(0,binLimPt);
-  invmassr->SetBinEdges(1,binLimPt);
-  invmassr->SetBinEdges(2,binLimInv);
-  invmassr->Sumw2();
-  
-  THnSparseF *invmassos = new THnSparseF("invmassos","",nvarO,iBinOInv);
-  invmassos->SetBinEdges(0,binLimPt);
-  invmassos->SetBinEdges(1,binLimPt);
-  invmassos->SetBinEdges(2,binLimInv);
-  invmassos->Sumw2();
-
-  THnSparseF *invmasspi0=0x0;
-  THnSparseF *invmasseta=0x0;
-  THnSparseF *invmassgamma=0x0;
-  THnSparseF *invmassC=0x0;
-  THnSparseF *invmassB=0x0;
-  THnSparseF *invmassSplittedTrackss=0x0;
-  THnSparseF *invmassSplittedTrackos=0x0;
+  TH1F *dataChi2NdfHisto = new TH1F("DataChi2Ndf","", 100, 0.0, 5.0); // chi2Ndf distribution    
+  fList->AddAt(dataChi2NdfHisto,kDatachi2Ndf); 
   
+
   if(HasMCData()) {
+
+    //
+    // Opening angle and invariant mass with MC infos
+    //
+
+    const Int_t nvarMCo = 6;
+    // pt reconstructed tagged e
+    // pt reconstructed mother
+    // opening angle
+    // invariant mass 
+    // MC: 0-FromBackground, 1-FromGamma, 2-FromPi0, 3-FromEta, 4-FromC, 5-FromB
+    // MCSplitted: 0-not, 1-splittedOs, 2-ksplittedSs
     
-    invmasspi0 = new THnSparseF("invmasspi0","",nvarO,iBinOInv);
-    invmasspi0->SetBinEdges(0,binLimPt);
-    invmasspi0->SetBinEdges(1,binLimPt);
-    invmasspi0->SetBinEdges(2,binLimInv);
-    invmasspi0->Sumw2();
-    
-    invmasseta = new THnSparseF("invmasseta","",nvarO,iBinOInv);
-    invmasseta->SetBinEdges(0,binLimPt);
-    invmasseta->SetBinEdges(1,binLimPt);
-    invmasseta->SetBinEdges(2,binLimInv);
-    invmasseta->Sumw2();
-    
-    invmassgamma = new THnSparseF("invmassgamma","",nvarO,iBinOInv);
-    invmassgamma->SetBinEdges(0,binLimPt);
-    invmassgamma->SetBinEdges(1,binLimPt);
-    invmassgamma->SetBinEdges(2,binLimInv);
-    invmassgamma->Sumw2();
-
-    invmassC = new THnSparseF("invmassC","",nvarO,iBinOInv);
-    invmassC->SetBinEdges(0,binLimPt);
-    invmassC->SetBinEdges(1,binLimPt);
-    invmassC->SetBinEdges(2,binLimInv);
-    invmassC->Sumw2();
-
-    invmassB = new THnSparseF("invmassB","",nvarO,iBinOInv);
-    invmassB->SetBinEdges(0,binLimPt);
-    invmassB->SetBinEdges(1,binLimPt);
-    invmassB->SetBinEdges(2,binLimInv);
-    invmassB->Sumw2();
-
-    invmassSplittedTrackss = new THnSparseF("invmassSplittedTrackss","",nvarO,iBinOInv);
-    invmassSplittedTrackss->SetBinEdges(0,binLimPt);
-    invmassSplittedTrackss->SetBinEdges(1,binLimPt);
-    invmassSplittedTrackss->SetBinEdges(2,binLimInv);
-    invmassSplittedTrackss->Sumw2();
-
-    invmassSplittedTrackos = new THnSparseF("invmassSplittedTrackos","",nvarO,iBinOInv);
-    invmassSplittedTrackos->SetBinEdges(0,binLimPt);
-    invmassSplittedTrackos->SetBinEdges(1,binLimPt);
-    invmassSplittedTrackos->SetBinEdges(2,binLimInv);
-    invmassSplittedTrackos->Sumw2();
-  
-  }
-  
-  //
-  //
-  //
 
-  fList->AddAt(openinganglepp,kPp);
-  fList->AddAt(openinganglenn,kNn);
-  fList->AddAt(openingangless,kSs);
-  fList->AddAt(openingangler,kR);
-  fList->AddAt(openingangleos,kOs);
-  
-  fList->AddAt(invmasspp,kNSignComb+kPp);
-  fList->AddAt(invmassnn,kNSignComb+kNn);
-  fList->AddAt(invmassss,kNSignComb+kSs);
-  fList->AddAt(invmassr,kNSignComb+kR);
-  fList->AddAt(invmassos,kNSignComb+kOs);
+    Int_t nBinsMCOrigin = 6;
+    Double_t minMCOrigin = 0.0;
+    Double_t maxMCOrigin = 6.0;
+    
+    Double_t *binLimMCOrigin = new Double_t[nBinsMCOrigin+1];
+    for(Int_t i=0; i<=nBinsMCOrigin; i++) binLimMCOrigin[i]=(Double_t)minMCOrigin  + (maxMCOrigin-minMCOrigin) /nBinsMCOrigin*(Double_t)i ;
 
-  if(HasMCData()) {
-    fList->AddAt(openinganglegamma,2*kNSignComb+kElectronFromGamma);
-    fList->AddAt(openinganglepi0,2*kNSignComb+kElectronFromPi0);
-    fList->AddAt(openingangleC,2*kNSignComb+kElectronFromC);
-    fList->AddAt(openingangleB,2*kNSignComb+kElectronFromB);
-    fList->AddAt(openingangleeta,2*kNSignComb+kElectronFromEta);
-    fList->AddAt(openingangleSplittedTrackss,2*kNSignComb+kSplittedTrackss);
-    fList->AddAt(openingangleSplittedTrackos,2*kNSignComb+kSplittedTrackos);
-
-    fList->AddAt(invmassgamma,2*kNSignComb+kNMCInfo+kElectronFromGamma);
-    fList->AddAt(invmasspi0,2*kNSignComb+kNMCInfo+kElectronFromPi0);
-    fList->AddAt(invmassC,2*kNSignComb+kNMCInfo+kElectronFromC);
-    fList->AddAt(invmassB,2*kNSignComb+kNMCInfo+kElectronFromB);
-    fList->AddAt(invmasseta,2*kNSignComb+kNMCInfo+kElectronFromEta);
-    fList->AddAt(invmassSplittedTrackss,2*kNSignComb+kNMCInfo+kSplittedTrackss);
-    fList->AddAt(invmassSplittedTrackos,2*kNSignComb+kNMCInfo+kSplittedTrackos);
+    Int_t nBinsMCSplitted = 3;
+    Double_t minMCSplitted = 0.0;
+    Double_t maxMCSplitted = 3.0;
+    
+    Double_t *binLimMCSplitted = new Double_t[nBinsMCSplitted+1];
+    for(Int_t i=0; i<=nBinsMCSplitted; i++) binLimMCSplitted[i]=(Double_t)minMCSplitted  + (maxMCSplitted-minMCSplitted) /nBinsMCSplitted*(Double_t)i ;
+    
+    Int_t iBinMCo[nvarMCo];
+    iBinMCo[0]=nBinsPt;
+    iBinMCo[1]=nBinsPt;
+    iBinMCo[2]=nBinsOp;
+    iBinMCo[3]=nBinsInv;
+    iBinMCo[4]=nBinsMCOrigin;
+    iBinMCo[5]=nBinsMCSplitted;
+        
+    THnSparseF *hsSparseMCo = new THnSparseF("OpeningangleinvmassMC","",nvarMCo,iBinMCo);
+    hsSparseMCo->SetBinEdges(0,binLimPt);
+    hsSparseMCo->SetBinEdges(1,binLimPt);
+    hsSparseMCo->SetBinEdges(2,binLimOp);
+    hsSparseMCo->SetBinEdges(3,binLimInv);
+    hsSparseMCo->SetBinEdges(4,binLimMCOrigin);
+    hsSparseMCo->SetBinEdges(5,binLimMCSplitted);
+    hsSparseMCo->Sumw2();
+
+    fList->AddAt(hsSparseMCo,kMCo);
+
+    //
+    // Radius, DCA and Chi2Ndf with MC info
+    //
+
+    TH2F *mcRadiusHisto = new TH2F("MCRadius","", 200, 0.0, 200.0,6,-0.5,5.5); // recontructed radius from the AliKF of the e+e- pair
+    fList->AddAt(mcRadiusHisto,kMCr);
+    
+    TH2F *mcDcaHisto = new TH2F("MCDCA","", 100, 0.0, 6.0,6,-0.5,5.5); // dca distribution
+    fList->AddAt(mcDcaHisto,kMCdca); 
+    
+    TH2F *mcChi2NdfHisto = new TH2F("MCChi2Ndf","", 100, 0.0, 5.0,6,-0.5,5.5); // chi2Ndf distribution    
+    fList->AddAt(mcChi2NdfHisto,kMCchi2Ndf); 
+
+    //////////////////////////////////////////////////////////
+    // if fDebugLevel 1: Rejection efficiencies of the cuts
+    //////////////////////////////////////////////////////////
+
+    if(fDebugLevel > 0) {
+
+      if(HasMCData()) {
+       
+       const Int_t nvarMCe = 3;
+       // pt reconstructed tagged e
+       // cut passed: 0-all, 1-Partner tracked, 2-Opposite-sign, 3-SingleTrackCutPart, 4-ShareCluster, 5-PID, 6-DCA, 7-chi2Ndf AliKF, 8-Openingangle, 9-Invmass
+       // MC: 0-FromBackground, 1-FromGamma, 2-FromPi0, 3-FromEta, 4-FromC, 5-FromB
+      
+      Int_t nBinsMCCutPassed = 10;
+      Double_t minMCCutPassed = -0.5;
+      Double_t maxMCCutPassed = 9.5;
+      
+      Double_t *binLimMCCutPassed = new Double_t[nBinsMCCutPassed+1];
+      for(Int_t i=0; i<=nBinsMCCutPassed; i++) binLimMCCutPassed[i]=(Double_t)minMCCutPassed  + (maxMCCutPassed-minMCCutPassed) /nBinsMCCutPassed*(Double_t)i ;
+      
+      Int_t iBinMCe[nvarMCe];
+      iBinMCe[0]=nBinsPt;
+      iBinMCe[1]=nBinsMCCutPassed;
+      iBinMCe[2]=nBinsMCOrigin;
+      
+      THnSparseF *hsSparseMCe = new THnSparseF("CutPassedMC","",nvarMCe,iBinMCe);
+      hsSparseMCe->SetBinEdges(0,binLimPt);
+      hsSparseMCe->SetBinEdges(1,binLimMCCutPassed);
+      hsSparseMCe->SetBinEdges(2,binLimMCOrigin);
+      hsSparseMCe->Sumw2();
+      
+      fList->AddAt(hsSparseMCe,kMCe); 
+      
+      }
+    }
+
+    /////////////////////////////////////////////////////////////////
+    // if fDebugLevel 1: PIDPartCut and ShareClusters
+    /////////////////////////////////////////////////////////////////
+
+    if(fDebugLevel > 1) {
+
+      if(!fRequireITSStandalone){
+       
+       //
+       // TPC 
+       //
+
+       TH2F *tpcPartner0 = new TH2F("TPCPartner0","", nBinsPtMore, binLimPtMore, 200, 0.0, 700.0); 
+       fList->AddAt(tpcPartner0,kMCcutPart0); 
+       TH2F *tpcPartner1 = new TH2F("TPCPartner1","", nBinsPtMore, binLimPtMore, 200, 0.0, 700.0); 
+       fList->AddAt(tpcPartner1,kMCcutPart1); 
+      
+      }
+      else {
+
+       //
+       // ITS
+       //
+
+       TH2F *itsPartner0 = new TH2F("ITSPartner0","", nBinsPtMore, binLimPtMore, 200, 0.0, 700.0); 
+       fList->AddAt(itsPartner0,kMCcutPart0); 
+       TH2F *itsPartner1 = new TH2F("ITSPartner1","", nBinsPtMore, binLimPtMore, 200, 0.0, 700.0); 
+       fList->AddAt(itsPartner1,kMCcutPart1); 
+
+       /////////////////////////////////////////////////////
+               // dEdx of the four layers for the track partner
+       /////////////////////////////////////////////////////
+       const Int_t nvarITSsignal = 5;
+       
+       Int_t nBinsITSsignal  = 100;
+       Double_t minITSsignal = 0.0;
+       Double_t maxITSsignal = 350.0;
+       
+       Double_t *binLimITSsignal = new Double_t[nBinsITSsignal+1];
+       for(Int_t i=0; i<=nBinsITSsignal; i++) binLimITSsignal[i]=(Double_t)minITSsignal  + (maxITSsignal-minITSsignal) /nBinsITSsignal*(Double_t)i ;
+       
+       Int_t iBinITSsignal[nvarITSsignal];
+       iBinITSsignal[0]=nBinsPt;
+       iBinITSsignal[1]=nBinsITSsignal;
+       iBinITSsignal[2]=nBinsITSsignal;
+       iBinITSsignal[3]=nBinsITSsignal;
+       iBinITSsignal[4]=nBinsITSsignal;
+       
+       THnSparseF *hsSparseITSpid = new THnSparseF("SparseITSsignal","",nvarITSsignal,iBinITSsignal);
+       hsSparseITSpid->SetBinEdges(0,binLimPt);
+       hsSparseITSpid->SetBinEdges(1,binLimITSsignal);
+       hsSparseITSpid->SetBinEdges(2,binLimITSsignal);
+       hsSparseITSpid->SetBinEdges(3,binLimITSsignal);
+       hsSparseITSpid->SetBinEdges(4,binLimITSsignal);
+       hsSparseITSpid->Sumw2();
+       
+       fList->AddAt(hsSparseITSpid,kMCcutPart2); 
+
+       ///////////////////////////////////////////////////////////////////////////////////////
+       // dEdx of the four layers for the track partner and track to reject splitted track
+       ///////////////////////////////////////////////////////////////////////////////////////
+       const Int_t nvarITSsignalSplit = 5;
+
+       Int_t nBinsITSSplit  = 2;
+       Double_t minITSSplit = 0.0;
+       Double_t maxITSSplit = 2.0;
+       
+       Double_t *binLimITSSplit = new Double_t[nBinsITSSplit+1];
+       for(Int_t i=0; i<=nBinsITSSplit; i++) binLimITSSplit[i]=(Double_t)minITSSplit  + (maxITSSplit-minITSSplit) /nBinsITSSplit*(Double_t)i ;
+
+
+       Int_t nBinsITSsignalSplit  = 50;
+       Double_t minITSsignalSplit = -25.0;
+       Double_t maxITSsignalSplit = 25.0;
+       
+       Double_t *binLimITSsignalSplit = new Double_t[nBinsITSsignalSplit+1];
+       for(Int_t i=0; i<=nBinsITSsignalSplit; i++) binLimITSsignalSplit[i]=(Double_t)minITSsignalSplit  + (maxITSsignalSplit-minITSsignalSplit) /nBinsITSsignalSplit*(Double_t)i ;
+       
+       Int_t iBinITSsignalSplit[nvarITSsignalSplit];
+       iBinITSsignalSplit[0]=nBinsITSSplit;
+       for(Int_t k = 1; k < 5; k++){
+         iBinITSsignalSplit[k]=nBinsITSsignalSplit;
+       }
+       
+       THnSparseF *hsSparseITSpidSplit = new THnSparseF("SparseITSsignalSplit","",nvarITSsignalSplit,iBinITSsignalSplit);
+       hsSparseITSpidSplit->SetBinEdges(0,binLimITSSplit);
+       for(Int_t k = 1; k < 5; k++) {
+         hsSparseITSpidSplit->SetBinEdges(k,binLimITSsignalSplit);
+       }
+       hsSparseITSpidSplit->Sumw2();
+       
+       fList->AddAt(hsSparseITSpidSplit,kMCcutPart3); 
+       
+      }
+
+    }
     
   }
 
+  //qaList->Add(fList);
+
 }
 //_______________________________________________________________________________________________
 void AliHFEelecbackground::PairAnalysis(AliESDtrack* const track, AliESDtrack* const trackPart)
@@ -443,18 +529,22 @@ void AliHFEelecbackground::PairAnalysis(AliESDtrack* const track, AliESDtrack* c
   //
   // calculate (tagged e-partner) dca, opening angle, invariant mass 
   //
-  
-  ////////////////////////
-  // Partner track cut
-  ////////////////////////
-  if(!SingleTrackCut(trackPart)) return;
 
+  /////////////////////
+  // pt tagged
+  //////////////////////
+  TVector3 v3Dtagged;
+  Double_t *pxyz = new Double_t[3];
+  track->PxPyPz(pxyz);
+  v3Dtagged.SetXYZ(pxyz[0],pxyz[1],pxyz[2]);
+  fPtESD = TMath::Sqrt(pxyz[0]*pxyz[0]+pxyz[1]*pxyz[1]); 
+  
   ////////////////////////
   // Take label
   ////////////////////////
   Int_t indexTrack = TMath::Abs(track->GetLabel());
   Int_t indexTrackPart = TMath::Abs(trackPart->GetLabel());
-
+  
   /////////////////////////
   // If MC data
   ////////////////////////
@@ -463,8 +553,12 @@ void AliHFEelecbackground::PairAnalysis(AliESDtrack* const track, AliESDtrack* c
     
     // Take info track if not already done 
     if(indexTrack!= fIndexTrack) {
+
+      for(Int_t id = 0; id < 10; id++) {
+       fCuts[id] = kFALSE;
+      }
       
-      fIsFrom = -1;
+      fIsFrom = kElectronFromBackground;
           
       fPdg = GetPdg(indexTrack); 
       fLabMother = GetLabMother(indexTrack);
@@ -511,7 +605,7 @@ void AliHFEelecbackground::PairAnalysis(AliESDtrack* const track, AliESDtrack* c
     if(indexTrackPart == fIndexTrack) fIsSplittedTrack = kTRUE;
     
   }
+
   //////////////////////
   // Sign
   /////////////////////
@@ -519,102 +613,319 @@ void AliHFEelecbackground::PairAnalysis(AliESDtrack* const track, AliESDtrack* c
   if((track->Charge() > 0.0) && (trackPart->Charge() > 0.0)) sign = kPp; 
   if((track->Charge() < 0.0) && (trackPart->Charge() < 0.0)) sign = kNn; 
   if(((track->Charge() > 0.0) && (trackPart->Charge() < 0.0)) || ((track->Charge() < 0.0) && (trackPart->Charge() > 0.0))) sign = kOs; 
-       
+  
+  /////////////////////////
+  // Cut effects
+  ////////////////////////   
+  Double_t cuteffect[3];
+
+  if(fDebugLevel > 0) {  
+    if(HasMCData()) {
+      cuteffect[0] = fPtESD;
+      cuteffect[1] = 0.0;
+      cuteffect[2] = fIsFrom;
+      if(!fCuts[0]) {
+       (dynamic_cast<THnSparseF *>(fList->At(kMCe)))->Fill(cuteffect);
+       fCuts[0] = kTRUE;
+      }
+    }
+  }
+
+
+  ///////////////////////////////
+  // Cut effect: Partner track 
+  ///////////////////////////////   
+  
+  if(fDebugLevel > 0) {  
+    if(HasMCData() && fIsPartner) {
+      cuteffect[1] = 1.0;
+      if(!fCuts[1]) {
+       (dynamic_cast<THnSparseF *>(fList->At(kMCe)))->Fill(cuteffect);
+       fCuts[1] = kTRUE;
+      }
+    }
+  }
+
+  ///////////////////////////////
+  // Cut effect: Opposite sign 
+  ///////////////////////////////   
+  
+  if(fDebugLevel > 0) {  
+    if(HasMCData() && fIsPartner && (sign == kOs)) {
+      cuteffect[1] = 2.0;
+      if(!fCuts[2]) {
+       (dynamic_cast<THnSparseF *>(fList->At(kMCe)))->Fill(cuteffect);
+       fCuts[2] = kTRUE;
+      }
+    }
+  }
+
+  ////////////////////////
+  // Partner track cut
+  ////////////////////////
+  if(!SingleTrackCut(trackPart)) return;
+
+  if(fDebugLevel > 0) {  
+    if(HasMCData() && fIsPartner && (sign==kOs)) {
+      cuteffect[1] = 3.0;
+      if(!fCuts[3]) {
+       (dynamic_cast<THnSparseF *>(fList->At(kMCe)))->Fill(cuteffect);
+       fCuts[3] = kTRUE;
+      }
+    }
+  }
+  
+  /////////////////////////
+  // shared clusters cut
+  /////////////////////////
+  if(fSharedClusterCut && ShareCluster(track,trackPart)) return;
+
+  if(fDebugLevel > 0) {  
+    if(HasMCData() && fIsPartner && (sign==kOs)) {
+      cuteffect[1] = 4.0;
+      if(!fCuts[4]) {
+       (dynamic_cast<THnSparseF *>(fList->At(kMCe)))->Fill(cuteffect);
+       fCuts[4] = kTRUE;
+      }
+    } 
+  }
+
+  ////////////////////////
+  // PID Partner track 
+  ////////////////////////
+  if(!PIDTrackCut(trackPart)) return;
+
+  if(fDebugLevel > 0) {  
+    if(HasMCData() && fIsPartner && (sign==kOs)) {
+      cuteffect[1] = 5.0;
+      if(!fCuts[5]) {
+       (dynamic_cast<THnSparseF *>(fList->At(kMCe)))->Fill(cuteffect);
+       fCuts[5] = kTRUE;
+      }
+    }
+  }
+
+  
   //////////////////////
   // DCA
   /////////////////////
   
   Double_t xthis,xp;
   Double_t dca = track->GetDCA(trackPart,fBz,xthis,xp);
+  (dynamic_cast<TH1F *>(fList->At(kDatadca)))->Fill(dca);
+  if(HasMCData()) {
+    //printf("has MC data for DCA\n");
+    //printf("IsPartner %d and isfrom %d\n",fIsPartner,fIsFrom);
+    if(fIsFrom==kElectronFromBackground) (dynamic_cast<TH2F *>(fList->At(kMCdca)))->Fill(dca,fIsFrom);
+    else {
+      if(fIsPartner) (dynamic_cast<TH2F *>(fList->At(kMCdca)))->Fill(dca,fIsFrom);
+    }
+  }
   if(TMath::Abs(dca) > 3.0) return;
-  
-  /////////////////////////////
-  // Propagate
-  ////////////////////////////
-      
-  Double_t norradius = TMath::Sqrt(fkVertex->GetX()*fkVertex->GetX()+fkVertex->GetY()*fkVertex->GetY());
-  
-  AliESDtrack *trackCopy = new AliESDtrack(*track);
-  AliESDtrack *trackPartCopy = new AliESDtrack(*trackPart);
-  Bool_t propagateok = kTRUE;
-  if((!(trackPartCopy->PropagateTo(norradius,fBz))) || (!(trackCopy->PropagateTo(norradius,fBz)))) propagateok = kFALSE;
-  if(!propagateok) {
-    if(trackCopy) delete trackCopy;
-    if(trackPartCopy) delete trackPartCopy;
-    return;
-  }  
-  
+
+  if(fDebugLevel > 0) {  
+    if(HasMCData() && fIsPartner && (sign==kOs)) {
+      cuteffect[1] = 6.0;
+      if(!fCuts[6]) {
+       (dynamic_cast<THnSparseF *>(fList->At(kMCe)))->Fill(cuteffect);
+       fCuts[6] = kTRUE;
+      }
+    }
+  }
+
   ///////////////////////////////////
   // Calcul mother variables
   ///////////////////////////////////
   Double_t results[5];
   Double_t resultsr[5];
+
   
-  CalculateMotherVariable(trackCopy,trackPartCopy,&results[0]);
-  CalculateMotherVariableR(trackCopy,trackPartCopy,&resultsr[0]);
+  if(!fUseAliKFCode) {
+    
+    /////////////////////////////
+    // Propagate
+    ////////////////////////////
+    
+    Double_t norradius = TMath::Sqrt(fkVertex->GetX()*fkVertex->GetX()+fkVertex->GetY()*fkVertex->GetY());
+    
+    AliESDtrack *trackCopy = new AliESDtrack(*track);
+    AliESDtrack *trackPartCopy = new AliESDtrack(*trackPart);
+    Bool_t propagateok = kTRUE;
+    if((!(trackPartCopy->PropagateTo(norradius,fBz))) || (!(trackCopy->PropagateTo(norradius,fBz)))) propagateok = kFALSE;
+    if(!propagateok) {
+      if(trackCopy) delete trackCopy;
+      if(trackPartCopy) delete trackPartCopy;
+      return;
+    }  
+  
+    CalculateMotherVariable(trackCopy,trackPartCopy,&results[0]);
+    CalculateMotherVariableR(trackCopy,trackPartCopy,&resultsr[0]);
+    
+    if(trackCopy) delete trackCopy;
+    if(trackPartCopy) delete trackPartCopy;
+    
+  }
+  else {
+    
+    if(!CalculateMotherVariable(track,trackPart,&results[0])) return;
+    if(fDebugLevel > 0) {     
+      if(HasMCData() && fIsPartner && (sign==kOs)) {
+       cuteffect[1] = 7.0;
+       if(!fCuts[7]) {
+         (dynamic_cast<THnSparseF *>(fList->At(kMCe)))->Fill(cuteffect);
+         fCuts[7] = kTRUE;
+       }
+      }
+    }
+  
+  }
   
   /////////////////////////////////////
   // Fill
   /////////////////////////////////////
    
   FillOutput(results, resultsr, sign);
+
+  if(fDebugLevel > 0) {  
+    if(HasMCData() && fIsPartner && (sign==kOs)) {
+      
+      if(TMath::Abs(results[4]) < fOpeningAngleCut) {
+       
+       cuteffect[1] = 8.0;
+       if(!fCuts[8]) {
+         (dynamic_cast<THnSparseF *>(fList->At(kMCe)))->Fill(cuteffect);
+         fCuts[8] = kTRUE;
+       }
+       if(TMath::Abs(results[1]) < fInvMassCut) {
+         cuteffect[1] = 9.0;
+         if(!fCuts[9]) {
+           (dynamic_cast<THnSparseF *>(fList->At(kMCe)))->Fill(cuteffect);
+           fCuts[9] = kTRUE;
+         }
+       }
+      }
+    }    
+  }
   
-  if(trackCopy) delete trackCopy;
-  if(trackPartCopy) delete trackPartCopy;
-  
 }
 //_____________________________________________________________________________________
-void AliHFEelecbackground::CalculateMotherVariable(AliESDtrack* const track, AliESDtrack* const trackpart, Double_t *results)
+Bool_t AliHFEelecbackground::CalculateMotherVariable(AliESDtrack* const track, AliESDtrack* const trackpart, Double_t *results)
 {
   //
   // variables mother and take the pt of the track
   //
   // results contain: ptmother, invmass, etamother, phimother, openingangle
   //
+  // with a chi2Ndf cut for AliKF code
+  //
   
-  TVector3 v3Dtagged;
-  TVector3 v3Dpart;
-  
-  Double_t *pxyz = new Double_t[3];
-  track->PxPyPz(pxyz);
-  v3Dtagged.SetXYZ(pxyz[0],pxyz[1],pxyz[2]);
-  fPtESD = TMath::Sqrt(pxyz[0]*pxyz[0]+pxyz[1]*pxyz[1]); 
-
-  Double_t *pxyzpart = new Double_t[3];
-  trackpart->PxPyPz(pxyzpart);
-  v3Dpart.SetXYZ(pxyzpart[0],pxyzpart[1],pxyzpart[2]);
+  if(!fUseAliKFCode) {
+    
+    TVector3 v3Dtagged;
+    TVector3 v3Dpart;
+    
+    Double_t *pxyz = new Double_t[3];
+    track->PxPyPz(pxyz);
+    v3Dtagged.SetXYZ(pxyz[0],pxyz[1],pxyz[2]);
+    
+    Double_t *pxyzpart = new Double_t[3];
+    trackpart->PxPyPz(pxyzpart);
+    v3Dpart.SetXYZ(pxyzpart[0],pxyzpart[1],pxyzpart[2]);
+    
+    
+    TVector3 motherrec = v3Dtagged + v3Dpart;
+    
+    Double_t etaESDmother = motherrec.Eta();
+    Double_t ptESDmother  = motherrec.Pt();
+    Double_t phiESDmother = motherrec.Phi();
+    if(phiESDmother > TMath::Pi()) phiESDmother = phiESDmother - (2*TMath::Pi());
+    
+    
+    // openinganglepropagated
+    Double_t openingangle = v3Dtagged.Angle(v3Dpart);
+    
+    // invmass
+    Double_t pESD      = TMath::Sqrt(pxyz[0]*pxyz[0]+pxyz[1]*pxyz[1]+pxyz[2]*pxyz[2]);
+    Double_t pESDpart  = TMath::Sqrt(pxyzpart[0]*pxyzpart[0]+pxyzpart[1]*pxyzpart[1]+pxyzpart[2]*pxyzpart[2]);
+    
+    // e propagate
+    Double_t eESD     = TMath::Sqrt(pESD*pESD+fgkMe*fgkMe);
+    Double_t eESDpart = TMath::Sqrt(pESDpart*pESDpart+fgkMe*fgkMe);
+    
+    Double_t invmass = TMath::Sqrt((eESD+eESDpart)*(eESD+eESDpart)-(motherrec.Px()*motherrec.Px()+motherrec.Py()*motherrec.Py()+motherrec.Pz()*motherrec.Pz()));
+    
+    if(!results) return kFALSE;
 
-  
-  TVector3 motherrec = v3Dtagged + v3Dpart;
-  
-  Double_t etaESDmother = motherrec.Eta();
-  Double_t ptESDmother  = motherrec.Pt();
-  Double_t phiESDmother = motherrec.Phi();
-  if(phiESDmother > TMath::Pi()) phiESDmother = phiESDmother - (2*TMath::Pi());
-  
-  
-  // openinganglepropagated
-  Double_t openingangle = v3Dtagged.Angle(v3Dpart);
-  
-  // invmass
-  Double_t pESD      = TMath::Sqrt(pxyz[0]*pxyz[0]+pxyz[1]*pxyz[1]+pxyz[2]*pxyz[2]);
-  Double_t pESDpart  = TMath::Sqrt(pxyzpart[0]*pxyzpart[0]+pxyzpart[1]*pxyzpart[1]+pxyzpart[2]*pxyzpart[2]);
-  
-  // e propagate
-  Double_t eESD     = TMath::Sqrt(pESD*pESD+fgkMe*fgkMe);
-  Double_t eESDpart = TMath::Sqrt(pESDpart*pESDpart+fgkMe*fgkMe);
-           
-  Double_t invmass = TMath::Sqrt((eESD+eESDpart)*(eESD+eESDpart)-(motherrec.Px()*motherrec.Px()+motherrec.Py()*motherrec.Py()+motherrec.Pz()*motherrec.Pz()));
+    results[0] = ptESDmother;
+    results[1] = etaESDmother;
+    results[2] = phiESDmother;
+    results[3] = invmass;
+    results[4] = openingangle;
+    
+    return kTRUE;
 
-  if(!results) {
-    results = new Double_t[5];
   }
-  results[0] = ptESDmother;
-  results[1] = etaESDmother;
-  results[2] = phiESDmother;
-  results[3] = invmass;
-  results[4] = openingangle;
+  else {
+    
+    AliKFParticle pair;
+    pair.Initialize();
+    
+    // pid
+    Int_t pid1 = -11;
+    if(track->Charge() > 0.0) pid1 = 11;
+    Int_t pid2 = -11;
+    if(trackpart->Charge() > 0.0) pid2 = 11;
+    
+    
+    // daughters
+    AliKFParticle kf(*track,pid1);
+    AliKFParticle kfpart(*trackpart,pid2);
+    
+    pair.AddDaughter(kf);
+    pair.AddDaughter(kfpart);
+    
+    // variables
+    Double_t openingangle = kf.GetAngle(kfpart);
+    Double_t chi2ndf = pair.GetChi2()/pair.GetNDF();
+    //Double_t decayLength = pair.GetDecayLength();
+    Double_t radius = pair.GetR();
+    //Double_t masserror = pair.GetErrMass()>0?pair.GetErrMass()/pair.GetMass():1000000;
+    Double_t ptpair = pair.GetPt();
+    Double_t etapair = pair.GetEta();
+    Double_t phipair = pair.GetPhi();
+    Double_t masspair = pair.GetMass();
+    
+    // Put them
+    if(!results) return kFALSE;
+
+    results[0] = ptpair;
+    results[1] = etapair;
+    results[2] = phipair;
+    results[3] = masspair;
+    results[4] = openingangle;
+
+    // chi2Ndf cut
+    (dynamic_cast<TH1F *>(fList->At(kDatachi2Ndf)))->Fill(chi2ndf);
+    if(HasMCData()){
+      if(fIsFrom==kElectronFromBackground) (dynamic_cast<TH2F *>(fList->At(kMCchi2Ndf)))->Fill(chi2ndf,fIsFrom);
+      else {
+       if(fIsPartner) (dynamic_cast<TH2F *>(fList->At(kMCchi2Ndf)))->Fill(chi2ndf,fIsFrom);
+      }
+    }
+    if(chi2ndf > fChi2NdfCut) return kFALSE;
+    else {
+      (dynamic_cast<TH1F *>(fList->At(kDatar)))->Fill(radius);
+      if(HasMCData()) {
+       if(fIsFrom==kElectronFromBackground) (dynamic_cast<TH2F *>(fList->At(kMCr)))->Fill(radius,fIsFrom);
+       else {
+         if(fIsPartner) (dynamic_cast<TH2F *>(fList->At(kMCr)))->Fill(radius,fIsFrom);
+       }
+      }
+      return kTRUE;
+    }
+    
+  }
   
 }
 //_____________________________________________________________________________________
@@ -624,178 +935,396 @@ void AliHFEelecbackground::CalculateMotherVariableR(AliESDtrack* const track, Al
   // variables mother
   //
   // results contain: ptmother, invmass, etamother, phimother, openingangle
+  // Implemented only for no AliKF
   //
-  
-  TVector3 v3Dtagged;
-  TVector3 v3Dpart;
-  
-  Double_t *pxyz = new Double_t[3];
-  track->PxPyPz(pxyz);
-  v3Dtagged.SetXYZ(pxyz[0],pxyz[1],pxyz[2]);
-  Double_t *pxyzpart = new Double_t[3];
-  trackpart->PxPyPz(pxyzpart);
-  v3Dpart.SetXYZ(pxyzpart[0],pxyzpart[1],pxyzpart[2]);
-
-  // rotate the partner
-  v3Dpart.RotateZ(TMath::Pi());
-  v3Dpart.GetXYZ(pxyzpart);
-
-  
-  TVector3 motherrec = v3Dtagged + v3Dpart;
-  
-  Double_t etaESDmother = motherrec.Eta();
-  Double_t ptESDmother  = motherrec.Pt();
-  Double_t phiESDmother = motherrec.Phi();
-  if(phiESDmother > TMath::Pi()) phiESDmother = phiESDmother - (2*TMath::Pi());
-  
-  
-  // openinganglepropagated
-  Double_t openingangle = v3Dtagged.Angle(v3Dpart);
-  //printf("Openingangle %f\n",openingangle);
-  
-  // invmass
-  Double_t pESD      = TMath::Sqrt(pxyz[0]*pxyz[0]+pxyz[1]*pxyz[1]+pxyz[2]*pxyz[2]);
-  Double_t pESDpart  = TMath::Sqrt(pxyzpart[0]*pxyzpart[0]+pxyzpart[1]*pxyzpart[1]+pxyzpart[2]*pxyzpart[2]);
-  // e propagate
-  Double_t eESD     = TMath::Sqrt(pESD*pESD+fgkMe*fgkMe);
-  Double_t eESDpart = TMath::Sqrt(pESDpart*pESDpart+fgkMe*fgkMe);
-  
-  Double_t invmass = TMath::Sqrt((eESD+eESDpart)*(eESD+eESDpart)-(motherrec.Px()*motherrec.Px()+motherrec.Py()*motherrec.Py()+motherrec.Pz()*motherrec.Pz()));
 
-  if(!results) {
-    results = new Double_t[5];
+  if(!fUseAliKFCode) {
+    
+    TVector3 v3Dtagged;
+    TVector3 v3Dpart;
+    
+    Double_t *pxyz = new Double_t[3];
+    track->PxPyPz(pxyz);
+    v3Dtagged.SetXYZ(pxyz[0],pxyz[1],pxyz[2]);
+    Double_t *pxyzpart = new Double_t[3];
+    trackpart->PxPyPz(pxyzpart);
+    v3Dpart.SetXYZ(pxyzpart[0],pxyzpart[1],pxyzpart[2]);
+    
+    // rotate the partner
+    v3Dpart.RotateZ(TMath::Pi());
+    v3Dpart.GetXYZ(pxyzpart);
+    
+    
+    TVector3 motherrec = v3Dtagged + v3Dpart;
+    
+    Double_t etaESDmother = motherrec.Eta();
+    Double_t ptESDmother  = motherrec.Pt();
+    Double_t phiESDmother = motherrec.Phi();
+    if(phiESDmother > TMath::Pi()) phiESDmother = phiESDmother - (2*TMath::Pi());
+    
+    
+    // openinganglepropagated
+    Double_t openingangle = v3Dtagged.Angle(v3Dpart);
+    //printf("Openingangle %f\n",openingangle);
+    
+    // invmass
+    Double_t pESD      = TMath::Sqrt(pxyz[0]*pxyz[0]+pxyz[1]*pxyz[1]+pxyz[2]*pxyz[2]);
+    Double_t pESDpart  = TMath::Sqrt(pxyzpart[0]*pxyzpart[0]+pxyzpart[1]*pxyzpart[1]+pxyzpart[2]*pxyzpart[2]);
+    // e propagate
+    Double_t eESD     = TMath::Sqrt(pESD*pESD+fgkMe*fgkMe);
+    Double_t eESDpart = TMath::Sqrt(pESDpart*pESDpart+fgkMe*fgkMe);
+    
+    Double_t invmass = TMath::Sqrt((eESD+eESDpart)*(eESD+eESDpart)-(motherrec.Px()*motherrec.Px()+motherrec.Py()*motherrec.Py()+motherrec.Pz()*motherrec.Pz()));
+    
+    if(!results) return;
+    
+    results[0] = ptESDmother;
+    results[1] = etaESDmother;
+    results[2] = phiESDmother;
+    results[3] = invmass;
+    results[4] = openingangle;
+    
   }
-  results[0] = ptESDmother;
-  results[1] = etaESDmother;
-  results[2] = phiESDmother;
-  results[3] = invmass;
-  results[4] = openingangle;
-
   
 }
 //_________________________________________________________________________________
 void AliHFEelecbackground::FillOutput(Double_t *results, Double_t *resultsr, Int_t sign) 
 {
   //
-  // Fill the invariant mass and opening angle distributions 
+  // Fill the Data and MC THnSparseF 
   //
+
+  if((!results) || (!resultsr)) return;
   
-  Double_t co[3];
+  Double_t co[6];
   co[0] = fPtESD;
-   
-  switch(sign){
-       
-      case kPp:
-       co[1] = results[0];
-       co[2] = TMath::Abs(results[4]);
-       (dynamic_cast<THnSparseF *>(fList->At(kPp)))->Fill(co);
-       (dynamic_cast<THnSparseF *>(fList->At(kSs)))->Fill(co);
-       if(HasMCData()){
-         if(fIsSplittedTrack) (dynamic_cast<THnSparseF *>(fList->At(2*kNSignComb+kSplittedTrackss)))->Fill(co);
-       }
+  co[1] = results[0];
+  co[2] = TMath::Abs(results[4]);
+  co[3] = results[3];
+  co[4] = sign;
+  co[5] = 0.0;
 
+  (dynamic_cast<THnSparseF *>(fList->At(kDatai)))->Fill(co);
 
-       co[2] = results[3];     
-       if(TMath::Abs(results[4]) < 0.8){
-         (dynamic_cast<THnSparseF *>(fList->At(kPp+kNSignComb)))->Fill(co);
-         (dynamic_cast<THnSparseF *>(fList->At(kSs+kNSignComb)))->Fill(co);
-         if(HasMCData()){
-           if(fIsSplittedTrack) (dynamic_cast<THnSparseF *>(fList->At(2*kNSignComb+kSplittedTrackss+kNMCInfo)))->Fill(co);
-         }
-       }
-
-       break;
-       
-      case kNn:
-       co[1] = results[0];
-       co[2] = TMath::Abs(results[4]); 
-       (dynamic_cast<THnSparseF *>(fList->At(kNn)))->Fill(co);
-       (dynamic_cast<THnSparseF *>(fList->At(kSs)))->Fill(co);
-       if(HasMCData()){
-         if(fIsSplittedTrack) (dynamic_cast<THnSparseF *>(fList->At(2*kNSignComb+kSplittedTrackss)))->Fill(co);
-       }
-       
-               co[2] = results[3];     
-       if(TMath::Abs(results[4]) < 0.8){
-         (dynamic_cast<THnSparseF *>(fList->At(kNn+kNSignComb)))->Fill(co);
-         (dynamic_cast<THnSparseF *>(fList->At(kSs+kNSignComb)))->Fill(co);
-         if(HasMCData()){
-           if(fIsSplittedTrack) (dynamic_cast<THnSparseF *>(fList->At(2*kNSignComb+kSplittedTrackss+kNMCInfo)))->Fill(co);
-         }
-       }
-       break;
-       
-      case kOs:
-       co[1] = results[0];
-       co[2] = TMath::Abs(results[4]); 
-       (dynamic_cast<THnSparseF *>(fList->At(kOs)))->Fill(co);
-       if(HasMCData()) {
-         if((fIsFrom == kElectronFromPi0) && (fIsPartner)) (dynamic_cast<THnSparseF *>(fList->At(2*kNSignComb+kElectronFromPi0)))->Fill(co);
-         if((fIsFrom == kElectronFromEta) && (fIsPartner)) (dynamic_cast<THnSparseF *>(fList->At(2*kNSignComb+kElectronFromEta)))->Fill(co);
-         if((fIsFrom == kElectronFromGamma) && (fIsPartner)) (dynamic_cast<THnSparseF *>(fList->At(2*kNSignComb+kElectronFromGamma)))->Fill(co);
-         if((fIsFrom == kElectronFromC) && (fIsPartner)) (dynamic_cast<THnSparseF *>(fList->At(2*kNSignComb+kElectronFromC)))->Fill(co);
-         if((fIsFrom == kElectronFromB) && (fIsPartner)) (dynamic_cast<THnSparseF *>(fList->At(2*kNSignComb+kElectronFromB)))->Fill(co);
-         if(fIsSplittedTrack) (dynamic_cast<THnSparseF *>(fList->At(2*kNSignComb+kSplittedTrackos)))->Fill(co);
-       }       
-       
-       co[2] = results[3];     
-       if(TMath::Abs(results[4]) < 0.8){
-         (dynamic_cast<THnSparseF *>(fList->At(kOs+kNSignComb)))->Fill(co);
-         if(HasMCData()) {
-           if((fIsFrom == kElectronFromPi0) && (fIsPartner)) (dynamic_cast<THnSparseF *>(fList->At(2*kNSignComb+kElectronFromPi0+kNMCInfo)))->Fill(co);
-           if((fIsFrom == kElectronFromEta) && (fIsPartner)) (dynamic_cast<THnSparseF *>(fList->At(2*kNSignComb+kElectronFromEta+kNMCInfo)))->Fill(co);
-           if((fIsFrom == kElectronFromGamma) && (fIsPartner)) (dynamic_cast<THnSparseF *>(fList->At(2*kNSignComb+kElectronFromGamma+kNMCInfo)))->Fill(co);
-           if((fIsFrom == kElectronFromC) && (fIsPartner)) (dynamic_cast<THnSparseF *>(fList->At(2*kNSignComb+kElectronFromC+kNMCInfo)))->Fill(co);
-           if((fIsFrom == kElectronFromB) && (fIsPartner)) (dynamic_cast<THnSparseF *>(fList->At(2*kNSignComb+kElectronFromB+kNMCInfo)))->Fill(co);
-           if(fIsSplittedTrack) (dynamic_cast<THnSparseF *>(fList->At(2*kNSignComb+kSplittedTrackos+kNMCInfo)))->Fill(co);
-         }     
-       }
+  if((sign==kOs) && (!fUseAliKFCode)) {
+    
+    co[1] = resultsr[0];
+    co[2] = TMath::Abs(resultsr[4]);
+    co[3] = resultsr[3];
+    co[4] = kR;
+    co[5] = 0.0;
 
-       // rotated
-       co[1] = resultsr[0];
-       co[2] = TMath::Abs(resultsr[4]);
+    (dynamic_cast<THnSparseF *>(fList->At(kDatai)))->Fill(co);
+    
+  }
+  
+  if(HasMCData()){
 
-       (dynamic_cast<THnSparseF *>(fList->At(kR)))->Fill(co);
+    // Reset
+    co[1] = results[0];
+    co[2] = TMath::Abs(results[4]);
+    co[3] = results[3];
 
-       co[2] = resultsr[3];    
-       if(TMath::Abs(resultsr[4]) < 0.8){
-         (dynamic_cast<THnSparseF *>(fList->At(kR+kNSignComb)))->Fill(co);
-       }
-       break;
-       
-  default:
-    
-    break;
+    // Origin
+    co[4] = kElectronFromBackground;
+    if((sign==kOs) && fIsPartner) co[4] = fIsFrom;
     
+    // Splitted tracks
+    co[5] = kNotSplitted;
+    if(fIsSplittedTrack) {
+      if(sign==kOs){
+       co[5] = kSplittedOs;
+      }
+      else {
+       co[5] = kSplittedSs;
+      }
+    }
+
+    (dynamic_cast<THnSparseF *>(fList->At(kMCo)))->Fill(co);
+
   }
-}      
+}    
 //_______________________________________________________________________________________________
-Bool_t AliHFEelecbackground::SingleTrackCut(AliESDtrack* const track) const
+Bool_t AliHFEelecbackground::SingleTrackCut(AliESDtrack* const trackPart) const
 {
   //
   // Return minimum quality for the partner
   //
   
-  //if(track->GetKinkIndex(0)>0) return kFALSE;
+  if(trackPart->GetKinkIndex(0)>0) return kFALSE;
 
-  UInt_t status = track->GetStatus();
-  
-  if(((status & AliESDtrack::kTPCin)==0) && (status & AliESDtrack::kITSin)) {
+
+  UInt_t status = trackPart->GetStatus();
+
+  if(fRequireITSStandalone > 0) {
+
+    /////////////////////
+    // ITS Standalone
+    ////////////////////
+    
+    if(fRequireITSStandalone==1) {
+      if(((status & AliESDtrack::kITSin) == 0 || (trackPart->IsPureITSStandalone()) || status&AliESDtrack::kITSrefit==0)) return kFALSE;
+    }
+    
+    if(fRequireITSStandalone==2) {
+      if(!trackPart->IsPureITSStandalone() || ((status&AliESDtrack::kITSrefit)==0)) return kFALSE;
+    }
+    
+    // Chi2
+    Double_t chi2 = trackPart->GetITSchi2();
+    if(chi2 > fMinITSChi2) return kFALSE;
+
+    // Min Nb of clusters
+    Int_t nbcl = trackPart->GetITSclusters(0);
+    if(nbcl < fMinNbCls)  return kFALSE;  
+
+    // Min Nb of points in SDD and SPD
+    Int_t nbSDDSPD = 0;
+    for(Int_t layer = 0; layer < 4; layer++){
+      if(trackPart->HasPointOnITSLayer(layer)) nbSDDSPD++;
+    }
+    if(nbSDDSPD < fMinNbClsSDDSPD) return kFALSE;
+    
     
-    Int_t nbcl = track->GetITSclusters(0);
-    if(nbcl > 1) return kTRUE;
-    else return kFALSE;
-  
   }
+  else {
+
+    /////////
+    // TPC
+    /////////
+    
+    if((status&AliESDtrack::kTPCrefit)==0) return kFALSE;
+
+    // Min Nb of clusters
+    Int_t nbcl = trackPart->GetTPCclusters(0);
+    if(nbcl < fMinNbCls) return kFALSE;   
+    
+  }
+
+  return kTRUE;
+
+}  
+//_______________________________________________________________________________________________
+Bool_t AliHFEelecbackground::PIDTrackCut(AliESDtrack* const trackPart)
+{
+  //
+  // PID for the partner using TPC or ITS
+  //
   
-  if(status & AliESDtrack::kTPCin) {
-  
-    if(status & AliESDtrack::kTPCrefit)  return kTRUE;
-    else return kFALSE;
+  if(fRequireITSStandalone > 0) {
+
+    /////////////////////
+    // ITS Standalone
+    ////////////////////
+    
+    // signal
+    Double_t itsSignal = trackPart->GetITSsignal();
+    Double_t p = trackPart->P();
+    
+    if(fDebugLevel > 1) {        
+      (dynamic_cast<TH2F *>(fList->At(kMCcutPart0)))->Fill(p,itsSignal);
+    }
+
+    ///////////
+    // PID
+    //////////
+    if(fPIDPartner) {
+      
+      // Take signal trackPart
+      Double_t dEdxSamplesPart[4];
+      trackPart->GetITSdEdxSamples(dEdxSamplesPart);
+
+      // Cut at 2 sigma
+      if(!fPIDMethodPartnerITS) fPIDMethodPartnerITS = new AliESDpid;
+      Float_t nsigma = fPIDMethodPartnerITS->NumberOfSigmasITS(trackPart, AliPID::kElectron);
+      if(TMath::Abs(nsigma) > 2.0) return kFALSE;
+      
+      // fill signal
+      if(fDebugLevel > 1) {        
+       
+       Double_t entries[5];
+       entries[0] = p;
+       entries[1] = dEdxSamplesPart[0];
+       entries[2] = dEdxSamplesPart[1];
+       entries[3] = dEdxSamplesPart[2];
+       entries[4] = dEdxSamplesPart[3];
+
+       (dynamic_cast<TH2F *>(fList->At(kMCcutPart1)))->Fill(p,itsSignal);
+       (dynamic_cast<THnSparseF *>(fList->At(kMCcutPart2)))->Fill(entries);
+       
+      }
+      
+    }
+    
+  }
+  else {
+
+    /////////
+    // TPC
+    /////////
+    
+    Double_t tpcSignal = trackPart->GetTPCsignal();
+    Double_t p = trackPart->GetInnerParam() ? trackPart->GetInnerParam()->P() : trackPart->P();
+
+    if(fDebugLevel > 1) {        
+      //printf("tpcSignal %f\n",tpcSignal);
+      (dynamic_cast<TH2F *>(fList->At(kMCcutPart0)))->Fill(p,tpcSignal);
+    }
+
+    // PID
+    if(fPIDPartner) {
+      if(!fPIDMethodPartner) return kFALSE;
+      AliHFEpidObject hfetrack;
+      hfetrack.fAnalysisType = AliHFEpidObject::kESDanalysis;
+      hfetrack.fRecTrack = trackPart;
+      //if(HasMCData()) hfetrack.fMCtrack = mctrack;
+      if(!fPIDMethodPartner->IsSelected(&hfetrack)) return kFALSE;
+      
+      if(fDebugLevel > 1) {  
+       (dynamic_cast<TH2F *>(fList->At(kMCcutPart1)))->Fill(p,tpcSignal);
+      }
+    }   
+    
+  }
+
+  return kTRUE;
+
+}
+//__________________________________________________________________________________________
+Bool_t AliHFEelecbackground::ShareCluster(AliESDtrack * const track1,AliESDtrack * const track2) const
+{
+  //
+  // Look if the two tracks shared clusters in the TPC or in the ITS depending on the method
+  //
+  // For TPC:
+  // hsfval: number of shared clusters 
+  // hsmval: quality of the tracks
+  //
+  // For ITS:
+  // compare the dEdx in the ITS
+  //
+
+  if(!fRequireITSStandalone) {
+
+    //////////
+    // TPC
+    //////////
+
+    
+    Int_t nh = 0;
+    Int_t an = 0;
+    Int_t ns = 0;
+    Float_t hsmval = 0.0;
+    Float_t hsfval = 0.0;
+   
+    for(unsigned int imap=0;imap<track1->GetTPCClusterMap().GetNbits(); imap++) {
+      if(track1->GetTPCClusterMap().TestBitNumber(imap) &&
+         track2->GetTPCClusterMap().TestBitNumber(imap)) {
+        // Do they share it ?
+        if (track1->GetTPCSharedMap().TestBitNumber(imap) &&
+            track2->GetTPCSharedMap().TestBitNumber(imap))
+          {
+            an++;
+            nh+=2;
+            ns+=2;
+          }
+       else {
+          an--;
+          nh+=2;
+        }
+      }
+      else if (track1->GetTPCClusterMap().TestBitNumber(imap) ||
+               track2->GetTPCClusterMap().TestBitNumber(imap)) {
+       an++;
+        nh++;
+      }
+    }
+
+    if (nh >0) {
+      hsmval = an*1.0/nh;
+      hsfval = ns*1.0/nh;
+    }
+    
+    
+    if((hsfval > 0.15) || (hsmval > -0.15)) return kTRUE; //they share cluster 
+    else return kFALSE;   
   
   }
+  else {
+
+    
+    //////////
+    // ITS
+    /////////
+
+    // Take signals 
+    Double_t dEdxSamples1[4];
+    track1->GetITSdEdxSamples(dEdxSamples1);
+    Double_t dEdxSamples2[4];
+    track2->GetITSdEdxSamples(dEdxSamples2);
+    
+    // If there are matching
+    Int_t nbClusters = 0;
+    Bool_t match[4] = {kTRUE,kTRUE,kTRUE,kTRUE};
+    Double_t limit[4] = {1.5,1.5,1.5,1.5};
+    for(Int_t layer = 0; layer < 4; layer++) {
+      if(track1->HasPointOnITSLayer(layer+2) && track2->HasPointOnITSLayer(layer+2)) {
+       if(TMath::Abs(dEdxSamples1[layer]-dEdxSamples2[layer])>limit[layer]) match[layer] = kFALSE;
+       nbClusters++;
+      }
+    }
+    //printf("nbClusters %d\n",nbClusters);
+    
+    // fill signal   
+    if(fDebugLevel > 1) {        
+      Double_t entriesSplit[5];
+      entriesSplit[0] = 0.0;
+      if(fIsSplittedTrack) entriesSplit[0] = 1.0; 
+      
+      for(Int_t layer = 0; layer < 4; layer++) {
+       if(track1->HasPointOnITSLayer(layer+2) && track2->HasPointOnITSLayer(layer+2)) {
+         entriesSplit[layer+1] = dEdxSamples1[layer]-dEdxSamples2[layer];
+       }
+       else entriesSplit[layer+1] = -100.0;
+      }
+      (dynamic_cast<THnSparseF *>(fList->At(kMCcutPart3)))->Fill(entriesSplit);
+    }
+
+    // Return
+    Int_t nbClustersNotClose = 0;
+    for(Int_t layer = 0; layer < 4; layer++) {
+      if(!match[layer]) nbClustersNotClose++;
+    }
+    if((nbClusters > 1) && (nbClustersNotClose > 0.75*nbClusters)) return kFALSE;
+    else return kTRUE;
+    
+  }   
   
-  return kFALSE;
+}
+//____________________________________________________________________________________________________________
+void AliHFEelecbackground::SetPIDPartner() {
+
+  //
+  // Init the stuff for PID on the partner track
+  //
+
+  fPIDPartner = kTRUE;
+
+  if(fRequireITSStandalone == 0) {
+    
+    if(!fPIDMethodPartner) {
+      fPIDMethodPartner = new AliHFEpid();
+      fPIDMethodPartner->InitializePID("Strategy1");     // 3 sigma cut in TPC
+    }
+
+  }
+  else {
+    
+    if(!fPIDMethodPartnerITS) fPIDMethodPartnerITS = new AliESDpid;
+    
+  }
   
 }
 //______________________________________________________________________________________________
@@ -991,20 +1520,40 @@ void AliHFEelecbackground::PostProcess()
 
   if(!fList) return;
 
-  // invariant mass input spectra
-  THnSparseF *invmassss = dynamic_cast<THnSparseF *>(fList->FindObject("invmassss"));
-  THnSparseF *invmassr  = dynamic_cast<THnSparseF *>(fList->FindObject("invmassr"));
-  THnSparseF *invmassos = dynamic_cast<THnSparseF *>(fList->FindObject("invmassos"));
-  THnSparseF *invmassgamma = dynamic_cast<THnSparseF *>(fList->FindObject("invmassgamma"));
-  THnSparseF *invmasspi0 = dynamic_cast<THnSparseF *>(fList->FindObject("invmasspi0"));
-  THnSparseF *invmasseta = dynamic_cast<THnSparseF *>(fList->FindObject("invmasseta"));
-  THnSparseF *invmassC = dynamic_cast<THnSparseF *>(fList->FindObject("invmassC"));
-  THnSparseF *invmassB = dynamic_cast<THnSparseF *>(fList->FindObject("invmassB"));
-  
-  TAxis *ptaxisinvmass = invmassss->GetAxis(0);
+  gStyle->SetPalette(1);
+  gStyle->SetOptStat(1111);
+  gStyle->SetPadBorderMode(0);
+  gStyle->SetCanvasColor(10);
+  gStyle->SetPadLeftMargin(0.13);
+  gStyle->SetPadRightMargin(0.13);
+
+  /////////////////////////
+  // Take the THnSparseF
+  /////////////////////////
+  THnSparseF *hsSparseData = dynamic_cast<THnSparseF *>(fList->FindObject("OpeningangleinvmassData")); 
+  THnSparseF *hsSparseMC = dynamic_cast<THnSparseF *>(fList->FindObject("OpeningangleinvmassMC")); 
+  THnSparseF *hsSparseCutPassedMC = dynamic_cast<THnSparseF *>(fList->FindObject("CutPassedMC")); 
+
+  /////////////////////////////////
+  // Cuts on the opening angle
+  ////////////////////////////////
+  TAxis *axisOpeningAngleData = hsSparseData->GetAxis(2);
+  Int_t binCutData = axisOpeningAngleData->FindBin(fOpeningAngleCut);
+  hsSparseData->GetAxis(2)->SetRange(1,binCutData);
+
+  if(hsSparseMC) {
+    TAxis *axisOpeningAngleMC = hsSparseMC->GetAxis(2);
+    Int_t binCutMC = axisOpeningAngleMC->FindBin(fOpeningAngleCut);
+    hsSparseMC->GetAxis(2)->SetRange(1,binCutMC);
+  }
+  
+  /////////////////////////
+  // Prepare the histos
+  ////////////////////////  
+
+  TAxis *ptaxisinvmass = hsSparseData->GetAxis(3);
   Int_t  nbinsptinvmass = ptaxisinvmass->GetNbins();  
   
-  // outputs
   TH1D **invmassosptproj = new TH1D*[nbinsptinvmass];
   TH1D **invmassssptproj = new TH1D*[nbinsptinvmass];
   TH1D **invmassrptproj = new TH1D*[nbinsptinvmass];
@@ -1015,55 +1564,70 @@ void AliHFEelecbackground::PostProcess()
   TH1D **invmassCptproj = new TH1D*[nbinsptinvmass];
   TH1D **invmassBptproj = new TH1D*[nbinsptinvmass];
 
-  TH1D *yieldPtFound = (TH1D *) invmassss->Projection(0);
+  TH1D *yieldPtFound = (TH1D *) hsSparseData->Projection(0);
   yieldPtFound->SetName("Found yield");
   yieldPtFound->Reset();
 
   TH1D *yieldPtSourcesMC = 0x0;
-  if(invmasspi0 && invmasseta && invmassgamma) {
-    yieldPtSourcesMC = (TH1D *) invmassss->Projection(0);
+  TH1D *yieldPtSignalCutMC = 0x0;
+  if(hsSparseMC) {
+    yieldPtSourcesMC = (TH1D *) hsSparseMC->Projection(0);
     yieldPtSourcesMC->SetName("Found yield");
     yieldPtSourcesMC->Reset();
-  }
-
-  TH1D *yieldPtSignalCutMC = 0x0;
-  if(invmassC && invmassB) {
-    yieldPtSignalCutMC = (TH1D *) invmassss->Projection(0);
+    
+    yieldPtSignalCutMC = (TH1D *) hsSparseMC->Projection(0);
     yieldPtSignalCutMC->SetName("Found yield");
     yieldPtSignalCutMC->Reset();
   }
-
+  
+  ////////////
   // canvas
+  ///////////
   Int_t nbrow = (Int_t) (nbinsptinvmass/5);
-  TString namecanvas("Invmassnamecanvas");
+  TString namecanvas("InvMassSpectra");
   TCanvas * canvas =new TCanvas(namecanvas,namecanvas,800,800);
   canvas->Divide(5,nbrow+1);
 
+  /////////////////////////////
+  // Loop on pt bins
+  /////////////////////////////
 
-  // loop on pt bins
   for(Int_t k=1; k <= nbinsptinvmass; k++){
 
     Double_t lowedge = ptaxisinvmass->GetBinLowEdge(k);
     Double_t upedge  = ptaxisinvmass->GetBinUpEdge(k);
+
+    // Pt bin
+    hsSparseData->GetAxis(0)->SetRange(k,k);
+    if(hsSparseMC) hsSparseMC->GetAxis(0)->SetRange(k,k);
     
-    ((TAxis *)invmassss->GetAxis(0))->SetRange(k,k);
-    ((TAxis *)invmassr->GetAxis(0))->SetRange(k,k);
-    ((TAxis *)invmassos->GetAxis(0))->SetRange(k,k);
-     
-    invmassosptproj[k-1] = invmassos->Projection(2);
-    invmassssptproj[k-1] = invmassss->Projection(2);
-    invmassrptproj[k-1]  = invmassr->Projection(2);
+    // 
+    hsSparseData->GetAxis(4)->SetRange(kOs+1,kOs+1);
+    invmassosptproj[k-1] = hsSparseData->Projection(3);
+    hsSparseData->GetAxis(4)->SetRange(kPp+1,kNn+1);
+    invmassssptproj[k-1] = hsSparseData->Projection(3);
+    hsSparseData->GetAxis(4)->SetRange(kR+1,kR+1);
+    invmassrptproj[k-1]  = hsSparseData->Projection(3);
+    hsSparseData->GetAxis(4)->SetRange(1,hsSparseData->GetAxis(4)->GetNbins()); 
     invmassgammaptproj[k-1] = 0x0;
     invmasspi0ptproj[k-1] = 0x0;
     invmassetaptproj[k-1] = 0x0;
     invmassCptproj[k-1] = 0x0;
     invmassBptproj[k-1] = 0x0;
-    if(invmassgamma) invmassgammaptproj[k-1] = invmassgamma->Projection(2);
-    if(invmasspi0) invmasspi0ptproj[k-1] = invmasspi0->Projection(2);
-    if(invmasseta) invmassetaptproj[k-1] = invmasseta->Projection(2);
-    if(invmassC) invmassCptproj[k-1] = invmassC->Projection(2);
-    if(invmassB) invmassBptproj[k-1] = invmassB->Projection(2);
-    
+    if(hsSparseMC) {
+      hsSparseMC->GetAxis(4)->SetRange(kElectronFromGamma+1,kElectronFromGamma+1);
+      invmassgammaptproj[k-1] = hsSparseMC->Projection(3);
+      hsSparseMC->GetAxis(4)->SetRange(kElectronFromPi0+1,kElectronFromPi0+1);
+      invmasspi0ptproj[k-1] = hsSparseMC->Projection(3);
+      hsSparseMC->GetAxis(4)->SetRange(kElectronFromEta+1,kElectronFromEta+1);
+      invmassetaptproj[k-1] = hsSparseMC->Projection(3);
+      hsSparseMC->GetAxis(4)->SetRange(kElectronFromC+1,kElectronFromC+1);
+      invmassCptproj[k-1] = hsSparseMC->Projection(3);
+      hsSparseMC->GetAxis(4)->SetRange(kElectronFromB+1,kElectronFromB+1);
+      invmassBptproj[k-1] = hsSparseMC->Projection(3);
+      hsSparseMC->GetAxis(4)->SetRange(1,hsSparseMC->GetAxis(4)->GetNbins()); 
+    }      
+
     invmassdiffptproj[k-1] = (TH1D *) invmassosptproj[k-1]->Clone();
     TString name("Invmassdiffptbin");
     name += k;
@@ -1085,9 +1649,7 @@ void AliHFEelecbackground::PostProcess()
     if(invmassetaptproj[k-1]) invmassetaptproj[k-1]->SetTitle((const char*)namee);
     if(invmassCptproj[k-1]) invmassCptproj[k-1]->SetTitle((const char*)namee);
     if(invmassBptproj[k-1]) invmassBptproj[k-1]->SetTitle((const char*)namee);
-        
-
-
+    
     invmassosptproj[k-1]->SetStats(0);
     invmassssptproj[k-1]->SetStats(0);
     invmassrptproj[k-1]->SetStats(0);
@@ -1124,26 +1686,48 @@ void AliHFEelecbackground::PostProcess()
     if(invmassetaptproj[k-1]) legiv->AddEntry(invmassetaptproj[k-1],"e^{+}e^{-} from #eta","p"); 
     legiv->Draw("same");
   
+    hsSparseData->GetAxis(0)->SetRange(1,hsSparseData->GetAxis(0)->GetNbins()); 
+    if(hsSparseMC) hsSparseMC->GetAxis(0)->SetRange(1,hsSparseMC->GetAxis(0)->GetNbins()); 
+
   }
 
+  ////////////////////////////////////////////////////
+  // End of plotting: do subtraction of background
+  ///////////////////////////////////////////////////
+
   yieldPtFound->SetStats(0);
   if(yieldPtSourcesMC) yieldPtSourcesMC->SetStats(0); 
   if(yieldPtSignalCutMC) yieldPtSignalCutMC->SetStats(0);  
 
-  TCanvas * canvasfin =new TCanvas("results","results",800,800);
+  TCanvas * canvasfin =new TCanvas("ResultsElecBackGround","ResultsElecBackGround",800,800);
   canvasfin->cd(1);
   yieldPtFound->Draw();
   if(yieldPtSourcesMC && yieldPtSignalCutMC) {
     yieldPtSourcesMC->Draw("same");
     yieldPtSignalCutMC->Draw("same");
     TLegend *lega = new TLegend(0.4,0.6,0.89,0.89);
-    lega->AddEntry(yieldPtFound,"Contributions found","p"); 
-    lega->AddEntry(yieldPtSourcesMC,"Contributions of e^{+}e^{-} from #gamma, #pi^{0} and #eta","p"); 
-    lega->AddEntry(yieldPtSignalCutMC,"Contributions of e^{+}e^{-} from C and B","p"); 
+    lega->AddEntry(yieldPtFound,"Contributions found","l"); 
+    lega->AddEntry(yieldPtSourcesMC,"Contributions of e^{+}e^{-} from #gamma, #pi^{0} and #eta","l"); 
+    lega->AddEntry(yieldPtSignalCutMC,"Contributions of e^{+}e^{-} from C and B","l"); 
     lega->Draw("same");
   }
   
+  if(hsSparseCutPassedMC){
+    hsSparseCutPassedMC->GetAxis(1)->SetRange(1,1); 
+    hsSparseCutPassedMC->GetAxis(2)->SetRange(1,4); 
+    TH1D *hsSparseCutPassedMCproj = hsSparseCutPassedMC->Projection(0);
+
+    TH1D *cYieldPtFound = (TH1D*)yieldPtFound->Clone("RatioEfficiency");
+    if(hsSparseCutPassedMCproj->Integral() > 0.0) cYieldPtFound->Divide(hsSparseCutPassedMCproj);
 
+    TCanvas * canvasfratio =new TCanvas("RatioEfficiency","RatioEfficiency",800,800);
+    canvasfratio->cd(1);
+    cYieldPtFound->Draw();
+  }
+
+  //////////////////////////
+  // fListPostProcess
+  /////////////////////////
   
   if(!fListPostProcess) fListPostProcess = new TList();
   fListPostProcess->SetName("ListPostProcess");
@@ -1184,46 +1768,37 @@ void AliHFEelecbackground::Plot() const
   //
   
   if(!fList) return;
-  
-  // opening angle 
-  THnSparseF *openinganglepp = dynamic_cast<THnSparseF *>(fList->FindObject("openinganglepp"));
-  THnSparseF *openinganglenn = dynamic_cast<THnSparseF *>(fList->FindObject("openinganglenn"));
-  THnSparseF *openingangless = dynamic_cast<THnSparseF *>(fList->FindObject("openingangless"));
-  THnSparseF *openingangler  = dynamic_cast<THnSparseF *>(fList->FindObject("openingangler"));
-  THnSparseF *openingangleos = dynamic_cast<THnSparseF *>(fList->FindObject("openingangleos"));
-  
-  THnSparseF *openinganglegamma = dynamic_cast<THnSparseF *>(fList->FindObject("openinganglegamma"));
-  THnSparseF *openinganglepi0 = dynamic_cast<THnSparseF *>(fList->FindObject("openinganglepi0"));
-  THnSparseF *openingangleC = dynamic_cast<THnSparseF *>(fList->FindObject("openingangleC"));
-  THnSparseF *openingangleB = dynamic_cast<THnSparseF *>(fList->FindObject("openingangleB"));
-  THnSparseF *openingangleeta = dynamic_cast<THnSparseF *>(fList->FindObject("openingangleeta"));  
-
-  THnSparseF *openingangleSplittedTrackss = dynamic_cast<THnSparseF *>(fList->FindObject("openingangleSplittedTrackss"));  
-  THnSparseF *openingangleSplittedTrackos = dynamic_cast<THnSparseF *>(fList->FindObject("openingangleSplittedTrackos"));  
-
-
-  // invariant mass
-  THnSparseF *invmasspp = dynamic_cast<THnSparseF *>(fList->FindObject("invmasspp"));
-  THnSparseF *invmassnn = dynamic_cast<THnSparseF *>(fList->FindObject("invmassnn"));
-  THnSparseF *invmassss = dynamic_cast<THnSparseF *>(fList->FindObject("invmassss"));
-  THnSparseF *invmassr  = dynamic_cast<THnSparseF *>(fList->FindObject("invmassr"));
-  THnSparseF *invmassos = dynamic_cast<THnSparseF *>(fList->FindObject("invmassos"));
-  
-  THnSparseF *invmassgamma = dynamic_cast<THnSparseF *>(fList->FindObject("invmassgamma"));
-  THnSparseF *invmasspi0 = dynamic_cast<THnSparseF *>(fList->FindObject("invmasspi0"));
-  THnSparseF *invmassC = dynamic_cast<THnSparseF *>(fList->FindObject("invmassC"));
-  THnSparseF *invmassB = dynamic_cast<THnSparseF *>(fList->FindObject("invmassB"));
-  THnSparseF *invmasseta = dynamic_cast<THnSparseF *>(fList->FindObject("invmasseta"));
-
-  THnSparseF *invmassSplittedTrackss = dynamic_cast<THnSparseF *>(fList->FindObject("invmassSplittedTrackss"));
-  THnSparseF *invmassSplittedTrackos = dynamic_cast<THnSparseF *>(fList->FindObject("invmassSplittedTrackos"));
-
-  // Projection over all pt
-  TH1D *openingangleppproj = openinganglepp->Projection(2);
-  TH1D *openinganglennproj = openinganglenn->Projection(2);
-  TH1D *openinganglessproj = openingangless->Projection(2);
-  TH1D *openinganglerproj  = openingangler->Projection(2);
-  TH1D *openingangleosproj = openingangleos->Projection(2);
+
+  gStyle->SetPalette(1);
+  gStyle->SetOptStat(1111);
+  gStyle->SetPadBorderMode(0);
+  gStyle->SetCanvasColor(10);
+  gStyle->SetPadLeftMargin(0.13);
+  gStyle->SetPadRightMargin(0.13);
+
+
+  /////////////////////////
+  // Take the THnSparseF
+  /////////////////////////
+  THnSparseF *hsSparseData = dynamic_cast<THnSparseF *>(fList->FindObject("OpeningangleinvmassData")); 
+  THnSparseF *hsSparseMC = dynamic_cast<THnSparseF *>(fList->FindObject("OpeningangleinvmassMC")); 
+  
+  ////////////////////
+  // Opening angle
+  ////////////////////
+
+  // Opening angle one direction
+  hsSparseData->GetAxis(4)->SetRange(kPp+1,kPp+1);  
+  TH1D *openingangleppproj = hsSparseData->Projection(2);
+  hsSparseData->GetAxis(4)->SetRange(kNn+1,kNn+1);  
+  TH1D *openinganglennproj = hsSparseData->Projection(2);
+  hsSparseData->GetAxis(4)->SetRange(kPp+1,kNn+1);  
+  TH1D *openinganglessproj = hsSparseData->Projection(2);
+  hsSparseData->GetAxis(4)->SetRange(kR+1,kR+1);  
+  TH1D *openinganglerproj  = hsSparseData->Projection(2);
+  hsSparseData->GetAxis(4)->SetRange(kOs+1,kOs+1);  
+  TH1D *openingangleosproj = hsSparseData->Projection(2);
+  hsSparseData->GetAxis(4)->SetRange(1,hsSparseData->GetAxis(4)->GetNbins()); 
 
   TH1D *openinganglegammaproj = 0x0;
   TH1D *openinganglepi0proj = 0x0;
@@ -1232,36 +1807,90 @@ void AliHFEelecbackground::Plot() const
   TH1D *openingangleetaproj = 0x0;
   TH1D *openingangleSplittedTrackssproj = 0x0;
   TH1D *openingangleSplittedTrackosproj = 0x0;
-  if(openinganglegamma) openinganglegammaproj = openinganglegamma->Projection(2);
-  if(openinganglepi0) openinganglepi0proj = openinganglepi0->Projection(2);
-  if(openingangleC) openingangleCproj = openingangleC->Projection(2);
-  if(openingangleB) openingangleBproj = openingangleB->Projection(2);
-  if(openingangleeta) openingangleetaproj = openingangleeta->Projection(2);
-  if(openingangleSplittedTrackss) openingangleSplittedTrackssproj = openingangleSplittedTrackss->Projection(2);
-  if(openingangleSplittedTrackos) openingangleSplittedTrackosproj = openingangleSplittedTrackos->Projection(2);
+  if(hsSparseMC) {
+    hsSparseMC->GetAxis(4)->SetRange(kElectronFromGamma+1,kElectronFromGamma+1);  
+    openinganglegammaproj = hsSparseMC->Projection(2);
+    hsSparseMC->GetAxis(4)->SetRange(kElectronFromPi0+1,kElectronFromPi0+1);  
+    openinganglepi0proj = hsSparseMC->Projection(2);
+    hsSparseMC->GetAxis(4)->SetRange(kElectronFromEta+1,kElectronFromEta+1);  
+    openingangleetaproj = hsSparseMC->Projection(2);
+    hsSparseMC->GetAxis(4)->SetRange(kElectronFromC+1,kElectronFromC+1);  
+    openingangleCproj = hsSparseMC->Projection(2);
+    hsSparseMC->GetAxis(4)->SetRange(kElectronFromB+1,kElectronFromB+1);  
+    openingangleBproj = hsSparseMC->Projection(2);
+    hsSparseMC->GetAxis(4)->SetRange(1,hsSparseMC->GetAxis(4)->GetNbins());  
+    hsSparseMC->GetAxis(5)->SetRange(kSplittedSs+1,kSplittedSs+1);  
+    openingangleSplittedTrackssproj = hsSparseMC->Projection(2);
+    hsSparseMC->GetAxis(5)->SetRange(kSplittedOs+1,kSplittedOs+1);  
+    openingangleSplittedTrackosproj = hsSparseMC->Projection(2);
+    hsSparseMC->GetAxis(5)->SetRange(1,hsSparseMC->GetAxis(5)->GetNbins()); 
+  }
 
+  // Projection pt-opening angle
+  hsSparseData->GetAxis(4)->SetRange(kPp+1,kPp+1); 
+  TH2D *openingangleppproj2D = hsSparseData->Projection(0,2);
+  hsSparseData->GetAxis(4)->SetRange(kNn+1,kNn+1); 
+  TH2D *openinganglennproj2D = hsSparseData->Projection(0,2);
+  hsSparseData->GetAxis(4)->SetRange(kPp+1,kNn+1); 
+  TH2D *openinganglessproj2D = hsSparseData->Projection(0,2);
+  hsSparseData->GetAxis(4)->SetRange(kR+1,kR+1); 
+  TH2D *openinganglerproj2D  = hsSparseData->Projection(0,2);
+  hsSparseData->GetAxis(4)->SetRange(kOs+1,kOs+1); 
+  TH2D *openingangleosproj2D = hsSparseData->Projection(0,2);
+  hsSparseData->GetAxis(4)->SetRange(1,hsSparseData->GetAxis(4)->GetNbins()); 
 
-  TH1D *invmassppproj = invmasspp->Projection(2);
-  TH1D *invmassnnproj = invmassnn->Projection(2);
-  TH1D *invmassssproj = invmassss->Projection(2);
-  TH1D *invmassrproj  = invmassr->Projection(2);
-  TH1D *invmassosproj = invmassos->Projection(2);
+  TH2D *openinganglegammaproj2D = 0x0;
+  TH2D *openinganglepi0proj2D = 0x0;
+  TH2D *openingangleCproj2D = 0x0;
+  TH2D *openingangleBproj2D = 0x0;
+  TH2D *openingangleetaproj2D = 0x0;
+  TH2D *openingangleSplittedTrackssproj2D = 0x0;
+  TH2D *openingangleSplittedTrackosproj2D = 0x0;
+  if(hsSparseMC) {
+    hsSparseMC->GetAxis(4)->SetRange(kElectronFromGamma+1,kElectronFromGamma+1); 
+    openinganglegammaproj2D = hsSparseMC->Projection(0,2);
+    hsSparseMC->GetAxis(4)->SetRange(kElectronFromPi0+1,kElectronFromPi0+1); 
+    openinganglepi0proj2D = hsSparseMC->Projection(0,2);
+    hsSparseMC->GetAxis(4)->SetRange(kElectronFromEta+1,kElectronFromEta+1); 
+    openingangleetaproj2D = hsSparseMC->Projection(0,2);
+    hsSparseMC->GetAxis(4)->SetRange(kElectronFromC+1,kElectronFromC+1); 
+    openingangleCproj2D = hsSparseMC->Projection(0,2);
+    hsSparseMC->GetAxis(4)->SetRange(kElectronFromB+1,kElectronFromB+1); 
+    openingangleBproj2D = hsSparseMC->Projection(0,2);
+    hsSparseMC->GetAxis(4)->SetRange(1, hsSparseMC->GetAxis(4)->GetNbins());  
+    hsSparseMC->GetAxis(5)->SetRange(kSplittedSs+1,kSplittedSs+1); 
+    openingangleSplittedTrackssproj2D = hsSparseMC->Projection(0,2);
+    hsSparseMC->GetAxis(5)->SetRange(kSplittedOs+1,kSplittedOs+1); 
+    openingangleSplittedTrackosproj2D = hsSparseMC->Projection(0,2);
+    hsSparseMC->GetAxis(5)->SetRange(1,hsSparseMC->GetAxis(5)->GetNbins());
+  }
+
+  openingangleppproj2D->SetStats(0);
+  openinganglennproj2D->SetStats(0);
+  openinganglessproj2D->SetStats(0);
+  openinganglerproj2D->SetStats(0);
+  openingangleosproj2D->SetStats(0);
+  if(openinganglegammaproj2D) openinganglegammaproj2D->SetStats(0);
+  if(openinganglepi0proj2D) openinganglepi0proj2D->SetStats(0);
+  if(openingangleCproj2D) openingangleCproj2D->SetStats(0);
+  if(openingangleBproj2D) openingangleBproj2D->SetStats(0);
+  if(openingangleetaproj2D) openingangleetaproj2D->SetStats(0);
+  if(openingangleSplittedTrackssproj2D) openingangleSplittedTrackssproj2D->SetStats(0);
+  if(openingangleSplittedTrackosproj2D) openingangleSplittedTrackosproj2D->SetStats(0);
+
+  openingangleppproj2D->SetTitle("openingangleppproj2D");
+  openinganglennproj2D->SetTitle("openinganglennproj2D");
+  openinganglessproj2D->SetTitle("openinganglessproj2D");
+  openinganglerproj2D->SetTitle("openinganglerproj2D");
+  openingangleosproj2D->SetTitle("openingangleosproj2D");
+  if(openinganglegammaproj2D) openinganglegammaproj2D->SetTitle("openinganglegammaproj2D");
+  if(openinganglepi0proj2D) openinganglepi0proj2D->SetTitle("openinganglepi0proj2D");
+  if(openingangleCproj2D) openingangleCproj2D->SetTitle("openingangleCproj2D");
+  if(openingangleBproj2D) openingangleBproj2D->SetTitle("openingangleBproj2D");
+  if(openingangleetaproj2D) openingangleetaproj2D->SetTitle("openingangleetaproj2D");
+  if(openingangleSplittedTrackssproj2D) openingangleSplittedTrackssproj2D->SetTitle("openingangleSplittedTrackssproj2D");
+  if(openingangleSplittedTrackosproj2D) openingangleSplittedTrackosproj2D->SetTitle("openingangleSplittedTrackosproj2D");  
 
-  TH1D *invmassgammaproj = 0x0;
-  TH1D *invmasspi0proj = 0x0;
-  TH1D *invmassCproj = 0x0;
-  TH1D *invmassBproj = 0x0;
-  TH1D *invmassetaproj = 0x0;
-  TH1D *invmassSplittedTrackssproj = 0x0;
-  TH1D *invmassSplittedTrackosproj = 0x0;
-  if(invmassgamma) invmassgammaproj = invmassgamma->Projection(2);
-  if(invmasspi0) invmasspi0proj = invmasspi0->Projection(2);
-  if(invmassC) invmassCproj = invmassC->Projection(2);
-  if(invmassB) invmassBproj = invmassB->Projection(2);
-  if(invmasseta) invmassetaproj = invmasseta->Projection(2);
-  if(invmassSplittedTrackss) invmassSplittedTrackssproj = invmassSplittedTrackss->Projection(2);
-  if(invmassSplittedTrackos) invmassSplittedTrackosproj = invmassSplittedTrackos->Projection(2);
-  
   openingangleppproj->SetStats(0);
   openinganglennproj->SetStats(0);
   openinganglessproj->SetStats(0);
@@ -1274,19 +1903,6 @@ void AliHFEelecbackground::Plot() const
   if(openingangleetaproj) openingangleetaproj->SetStats(0);
   if(openingangleSplittedTrackssproj) openingangleSplittedTrackssproj->SetStats(0);
   if(openingangleSplittedTrackosproj) openingangleSplittedTrackosproj->SetStats(0);
-  
-  invmassppproj->SetStats(0);
-  invmassnnproj->SetStats(0);
-  invmassssproj->SetStats(0);
-  invmassrproj->SetStats(0);
-  invmassosproj->SetStats(0);
-  if(invmassgammaproj) invmassgammaproj->SetStats(0);
-  if(invmasspi0proj) invmasspi0proj->SetStats(0);
-  if(invmassCproj) invmassCproj->SetStats(0);
-  if(invmassBproj) invmassBproj->SetStats(0);
-  if(invmassetaproj) invmassetaproj->SetStats(0);
-  if(invmassSplittedTrackssproj) invmassSplittedTrackssproj->SetStats(0);
-  if(invmassSplittedTrackosproj) invmassSplittedTrackosproj->SetStats(0);
 
   openingangleppproj->SetTitle("");
   openinganglennproj->SetTitle("");
@@ -1301,6 +1917,77 @@ void AliHFEelecbackground::Plot() const
   if(openingangleSplittedTrackssproj) openingangleSplittedTrackssproj->SetTitle("");
   if(openingangleSplittedTrackosproj) openingangleSplittedTrackosproj->SetTitle("");
 
+  ////////////////////////////
+  // Invariant mass
+  ///////////////////////////
+
+  // Cuts on the opening angle
+  TAxis *axisOpeningAngleData = hsSparseData->GetAxis(2);
+  Int_t binCutData = axisOpeningAngleData->FindBin(fOpeningAngleCut);
+  hsSparseData->GetAxis(2)->SetRange(1,binCutData);
+  
+  // Debug
+  //printf("Get Bin low edge %f, Get Bin Up edge %f for hsSparseData\n",axisOpeningAngleData->GetBinLowEdge(binCutData),axisOpeningAngleData->GetBinUpEdge(binCutData));
+
+  // Invariant mass
+  hsSparseData->GetAxis(4)->SetRange(kPp+1,kPp+1);  
+  TH1D *invmassppproj = hsSparseData->Projection(3);
+  hsSparseData->GetAxis(4)->SetRange(kNn+1,kNn+1);  
+  TH1D *invmassnnproj = hsSparseData->Projection(3);
+  hsSparseData->GetAxis(4)->SetRange(kPp+1,kNn+1);  
+  TH1D *invmassssproj = hsSparseData->Projection(3);
+  hsSparseData->GetAxis(4)->SetRange(kR+1,kR+1);  
+  TH1D *invmassrproj  = hsSparseData->Projection(3);
+  hsSparseData->GetAxis(4)->SetRange(kOs+1,kOs+1);  
+  TH1D *invmassosproj = hsSparseData->Projection(3);
+  hsSparseData->GetAxis(4)->SetRange(1,hsSparseData->GetAxis(4)->GetNbins()); 
+
+  TH1D *invmassgammaproj = 0x0;
+  TH1D *invmasspi0proj = 0x0;
+  TH1D *invmassCproj = 0x0;
+  TH1D *invmassBproj = 0x0;
+  TH1D *invmassetaproj = 0x0;
+  TH1D *invmassSplittedTrackssproj = 0x0;
+  TH1D *invmassSplittedTrackosproj = 0x0;
+  if(hsSparseMC) {
+    TAxis *axisOpeningAngleMC = hsSparseMC->GetAxis(2);
+    Int_t binCutMC = axisOpeningAngleMC->FindBin(fOpeningAngleCut);
+    hsSparseMC->GetAxis(2)->SetRange(1,binCutMC);
+    
+    // Debug
+    //printf("Get Bin low edge %f, Get Bin Up edge %f for hsSparseMC\n",axisOpeningAngleMC->GetBinLowEdge(binCutMC),axisOpeningAngleMC->GetBinUpEdge(binCutMC));
+    
+    hsSparseMC->GetAxis(4)->SetRange(kElectronFromGamma+1,kElectronFromGamma+1);  
+    invmassgammaproj = hsSparseMC->Projection(3);
+    hsSparseMC->GetAxis(4)->SetRange(kElectronFromPi0+1,kElectronFromPi0+1);  
+    invmasspi0proj = hsSparseMC->Projection(3);
+    hsSparseMC->GetAxis(4)->SetRange(kElectronFromEta+1,kElectronFromEta+1);  
+    invmassetaproj = hsSparseMC->Projection(3);
+    hsSparseMC->GetAxis(4)->SetRange(kElectronFromC+1,kElectronFromC+1);  
+    invmassCproj = hsSparseMC->Projection(3);
+    hsSparseMC->GetAxis(4)->SetRange(kElectronFromB+1,kElectronFromB+1);  
+    invmassBproj = hsSparseMC->Projection(3);
+    hsSparseMC->GetAxis(4)->SetRange(1,hsSparseMC->GetAxis(4)->GetNbins()); 
+    hsSparseMC->GetAxis(5)->SetRange(kSplittedSs+1,kSplittedSs+1);  
+    invmassSplittedTrackssproj = hsSparseMC->Projection(3);
+    hsSparseMC->GetAxis(5)->SetRange(kSplittedOs+1,kSplittedOs+1);  
+    invmassSplittedTrackosproj = hsSparseMC->Projection(3);
+    hsSparseMC->GetAxis(5)->SetRange(1,hsSparseMC->GetAxis(5)->GetNbins());
+  }
+  
+  invmassppproj->SetStats(0);
+  invmassnnproj->SetStats(0);
+  invmassssproj->SetStats(0);
+  invmassrproj->SetStats(0);
+  invmassosproj->SetStats(0);
+  if(invmassgammaproj) invmassgammaproj->SetStats(0);
+  if(invmasspi0proj) invmasspi0proj->SetStats(0);
+  if(invmassCproj) invmassCproj->SetStats(0);
+  if(invmassBproj) invmassBproj->SetStats(0);
+  if(invmassetaproj) invmassetaproj->SetStats(0);
+  if(invmassSplittedTrackssproj) invmassSplittedTrackssproj->SetStats(0);
+  if(invmassSplittedTrackosproj) invmassSplittedTrackosproj->SetStats(0);
+
   invmassppproj->SetTitle("");
   invmassnnproj->SetTitle("");
   invmassssproj->SetTitle("");
@@ -1314,34 +2001,18 @@ void AliHFEelecbackground::Plot() const
   if(invmassSplittedTrackssproj) invmassSplittedTrackssproj->SetTitle("");
   if(invmassSplittedTrackosproj) invmassSplittedTrackosproj->SetTitle("");
 
-  // Projection pttagged variable
-  TH2D *openingangleppproj2D = openinganglepp->Projection(0,2);
-  TH2D *openinganglennproj2D = openinganglenn->Projection(0,2);
-  TH2D *openinganglessproj2D = openingangless->Projection(0,2);
-  TH2D *openinganglerproj2D  = openingangler->Projection(0,2);
-  TH2D *openingangleosproj2D = openingangleos->Projection(0,2);
-
-  TH2D *openinganglegammaproj2D = 0x0;
-  TH2D *openinganglepi0proj2D = 0x0;
-  TH2D *openingangleCproj2D = 0x0;
-  TH2D *openingangleBproj2D = 0x0;
-  TH2D *openingangleetaproj2D = 0x0;
-  TH2D *openingangleSplittedTrackssproj2D = 0x0;
-  TH2D *openingangleSplittedTrackosproj2D = 0x0;
-  if(openinganglegamma) openinganglegammaproj2D = openinganglegamma->Projection(0,2);
-  if(openinganglepi0) openinganglepi0proj2D = openinganglepi0->Projection(0,2);
-  if(openingangleC) openingangleCproj2D = openingangleC->Projection(0,2);
-  if(openingangleB) openingangleBproj2D = openingangleB->Projection(0,2);
-  if(openingangleeta) openingangleetaproj2D = openingangleeta->Projection(0,2);
-  if(openingangleSplittedTrackss) openingangleSplittedTrackssproj2D = openingangleSplittedTrackss->Projection(0,2);
-  if(openingangleSplittedTrackos) openingangleSplittedTrackosproj2D = openingangleSplittedTrackos->Projection(0,2);
-
-
-  TH2D *invmassppproj2D = invmasspp->Projection(0,2);
-  TH2D *invmassnnproj2D = invmassnn->Projection(0,2);
-  TH2D *invmassssproj2D = invmassss->Projection(0,2);
-  TH2D *invmassrproj2D  = invmassr->Projection(0,2);
-  TH2D *invmassosproj2D = invmassos->Projection(0,2);
+  // Projection pt-invariant mass angle
+  hsSparseData->GetAxis(4)->SetRange(kPp+1,kPp+1); 
+  TH2D *invmassppproj2D = hsSparseData->Projection(0,3);
+  hsSparseData->GetAxis(4)->SetRange(kNn+1,kNn+1); 
+  TH2D *invmassnnproj2D = hsSparseData->Projection(0,3);
+  hsSparseData->GetAxis(4)->SetRange(kPp+1,kNn+1); 
+  TH2D *invmassssproj2D = hsSparseData->Projection(0,3);
+  hsSparseData->GetAxis(4)->SetRange(kR+1,kR+1); 
+  TH2D *invmassrproj2D  = hsSparseData->Projection(0,3);
+  hsSparseData->GetAxis(4)->SetRange(kOs+1,kOs+1); 
+  TH2D *invmassosproj2D = hsSparseData->Projection(0,3);
+  hsSparseData->GetAxis(4)->SetRange(1,hsSparseData->GetAxis(4)->GetNbins()); 
 
   TH2D *invmassgammaproj2D = 0x0;
   TH2D *invmasspi0proj2D = 0x0;
@@ -1350,26 +2021,25 @@ void AliHFEelecbackground::Plot() const
   TH2D *invmassetaproj2D = 0x0;
   TH2D *invmassSplittedTrackssproj2D = 0x0;
   TH2D *invmassSplittedTrackosproj2D = 0x0;
-  if(invmassgamma) invmassgammaproj2D = invmassgamma->Projection(0,2);
-  if(invmasspi0) invmasspi0proj2D = invmasspi0->Projection(0,2);
-  if(invmassC) invmassCproj2D = invmassC->Projection(0,2);
-  if(invmassB) invmassBproj2D = invmassB->Projection(0,2);
-  if(invmasseta) invmassetaproj2D = invmasseta->Projection(0,2);
-  if(invmassSplittedTrackss) invmassSplittedTrackssproj2D = invmassSplittedTrackss->Projection(0,2);
-  if(invmassSplittedTrackos) invmassSplittedTrackosproj2D = invmassSplittedTrackos->Projection(0,2);
-  
-  openingangleppproj2D->SetStats(0);
-  openinganglennproj2D->SetStats(0);
-  openinganglessproj2D->SetStats(0);
-  openinganglerproj2D->SetStats(0);
-  openingangleosproj2D->SetStats(0);
-  if(openinganglegammaproj2D) openinganglegammaproj2D->SetStats(0);
-  if(openinganglepi0proj2D) openinganglepi0proj2D->SetStats(0);
-  if(openingangleCproj2D) openingangleCproj2D->SetStats(0);
-  if(openingangleBproj2D) openingangleBproj2D->SetStats(0);
-  if(openingangleetaproj2D) openingangleetaproj2D->SetStats(0);
-  if(openingangleSplittedTrackssproj2D) openingangleSplittedTrackssproj2D->SetStats(0);
-  if(openingangleSplittedTrackosproj2D) openingangleSplittedTrackosproj2D->SetStats(0);
+  if(hsSparseMC) {
+    hsSparseMC->GetAxis(4)->SetRange(kElectronFromGamma+1,kElectronFromGamma+1); 
+    invmassgammaproj2D = hsSparseMC->Projection(0,3);
+    hsSparseMC->GetAxis(4)->SetRange(kElectronFromPi0+1,kElectronFromPi0+1); 
+    invmasspi0proj2D = hsSparseMC->Projection(0,3);
+    hsSparseMC->GetAxis(4)->SetRange(kElectronFromEta+1,kElectronFromEta+1); 
+    invmassetaproj2D = hsSparseMC->Projection(0,3);
+    hsSparseMC->GetAxis(4)->SetRange(kElectronFromC+1,kElectronFromC+1); 
+    invmassCproj2D = hsSparseMC->Projection(0,3);
+    hsSparseMC->GetAxis(4)->SetRange(kElectronFromB+1,kElectronFromB+1); 
+    invmassBproj2D = hsSparseMC->Projection(0,3);
+    hsSparseMC->GetAxis(4)->SetRange(1,hsSparseMC->GetAxis(4)->GetNbins()); 
+    hsSparseMC->GetAxis(5)->SetRange(kSplittedSs+1,kSplittedSs+1); 
+    invmassSplittedTrackssproj2D = hsSparseMC->Projection(0,3);
+    hsSparseMC->GetAxis(5)->SetRange(kSplittedOs+1,kSplittedOs+1); 
+    invmassSplittedTrackosproj2D = hsSparseMC->Projection(0,3);
+    hsSparseMC->GetAxis(5)->SetRange(1,hsSparseMC->GetAxis(5)->GetNbins()); 
+  }
+
   
   invmassppproj2D->SetStats(0);
   invmassnnproj2D->SetStats(0);
@@ -1383,20 +2053,7 @@ void AliHFEelecbackground::Plot() const
   if(invmassetaproj2D) invmassetaproj2D->SetStats(0);
   if(invmassSplittedTrackssproj2D) invmassSplittedTrackssproj2D->SetStats(0);
   if(invmassSplittedTrackosproj2D) invmassSplittedTrackosproj2D->SetStats(0);
-
-  openingangleppproj2D->SetTitle("openingangleppproj2D");
-  openinganglennproj2D->SetTitle("openinganglennproj2D");
-  openinganglessproj2D->SetTitle("openinganglessproj2D");
-  openinganglerproj2D->SetTitle("openinganglerproj2D");
-  openingangleosproj2D->SetTitle("openingangleosproj2D");
-  if(openinganglegammaproj2D) openinganglegammaproj2D->SetTitle("openinganglegammaproj2D");
-  if(openinganglepi0proj2D) openinganglepi0proj2D->SetTitle("openinganglepi0proj2D");
-  if(openingangleCproj2D) openingangleCproj2D->SetTitle("openingangleCproj2D");
-  if(openingangleBproj2D) openingangleBproj2D->SetTitle("openingangleBproj2D");
-  if(openingangleetaproj2D) openingangleetaproj2D->SetTitle("openingangleetaproj2D");
-  if(openingangleSplittedTrackssproj2D) openingangleSplittedTrackssproj2D->SetTitle("openingangleSplittedTrackssproj2D");
-  if(openingangleSplittedTrackosproj2D) openingangleSplittedTrackosproj2D->SetTitle("openingangleSplittedTrackosproj2D");
-
+  
   invmassppproj2D->SetTitle("invmassppproj2D");
   invmassnnproj2D->SetTitle("invmassnnproj2D");
   invmassssproj2D->SetTitle("invmassssproj2D");
@@ -1411,66 +2068,72 @@ void AliHFEelecbackground::Plot() const
   if(invmassSplittedTrackosproj2D) invmassSplittedTrackosproj2D->SetTitle("invmassSplittedTrackosproj2D");
 
 
+  /////////////
+  // Plot 
+  ////////////
+
   // Draw histograms for opening angle
   TCanvas * copeningangle =new TCanvas("openingangle","Openingangle",800,800);
   copeningangle->cd();
-  openingangleppproj->Draw();
-  openinganglennproj->Draw("same");
-  openinganglessproj->Draw("same");
-  openinganglerproj->Draw("same");
+  //openingangleppproj->Draw();
+  //openinganglennproj->Draw("same");
+  openinganglessproj->Draw();
+  //openinganglerproj->Draw("same");
   openingangleosproj->Draw("same");
   if(openinganglegammaproj) openinganglegammaproj->Draw("same");
   if(openinganglepi0proj) openinganglepi0proj->Draw("same");
-  if(openingangleCproj) openingangleCproj->Draw("same");
-  if(openingangleBproj) openingangleBproj->Draw("same");
+  //if(openingangleCproj) openingangleCproj->Draw("same");
+  //if(openingangleBproj) openingangleBproj->Draw("same");
   if(openingangleetaproj) openingangleetaproj->Draw("same");
   if(openingangleSplittedTrackssproj) openingangleSplittedTrackssproj->Draw("same");
   if(openingangleSplittedTrackosproj) openingangleSplittedTrackosproj->Draw("same");
   TLegend *lego = new TLegend(0.4,0.6,0.89,0.89);
-  lego->AddEntry(openingangleppproj,"positive-positive","p");
-  lego->AddEntry(openinganglennproj,"negative-negative","p");
+  //lego->AddEntry(openingangleppproj,"positive-positive","p");
+  //lego->AddEntry(openinganglennproj,"negative-negative","p");
   lego->AddEntry(openinganglessproj,"same-sign","p");
-  lego->AddEntry(openinganglerproj,"rotated","p");
+  //lego->AddEntry(openinganglerproj,"rotated","p");
   lego->AddEntry(openingangleosproj,"positive-negative","p");
   if(openinganglegammaproj) lego->AddEntry(openinganglegammaproj,"e^{+}e^{-} from #gamma","p");
   if(openinganglepi0proj) lego->AddEntry(openinganglepi0proj,"e^{+}e^{-} from #pi^{0}","p");
-  if(openingangleCproj) lego->AddEntry(openingangleCproj,"e^{+}e^{-} from c","p");
-  if(openingangleBproj) lego->AddEntry(openingangleBproj,"e^{+}e^{-} from b","p");
+  //if(openingangleCproj) lego->AddEntry(openingangleCproj,"e^{+}e^{-} from c","p");
+  //if(openingangleBproj) lego->AddEntry(openingangleBproj,"e^{+}e^{-} from b","p");
   if(openingangleetaproj) lego->AddEntry(openingangleetaproj,"e^{+}e^{-} from #eta","p");
   if(openingangleSplittedTrackssproj) lego->AddEntry(openingangleSplittedTrackssproj,"Splitted tracks same sign","p");
   if(openingangleSplittedTrackosproj) lego->AddEntry(openingangleSplittedTrackosproj,"Splitted tracks opposite sign","p");
   lego->Draw("same");
-
+  
   // Draw histograms for invariant mass
   TCanvas * cinvmass =new TCanvas("invmass","Invmass",800,800);
   cinvmass->cd();
-  invmassppproj->Draw();
-  invmassnnproj->Draw("same");
-  invmassssproj->Draw("same");
-  invmassrproj->Draw("same");
+  //invmassppproj->Draw();
+  //invmassnnproj->Draw("same");
+  invmassssproj->Draw();
+  //invmassrproj->Draw("same");
   invmassosproj->Draw("same");
   if(invmassgammaproj) invmassgammaproj->Draw("same");
   if(invmasspi0proj) invmasspi0proj->Draw("same");
-  if(invmassCproj) invmassCproj->Draw("same");
-  if(invmassBproj) invmassBproj->Draw("same");
+  //if(invmassCproj) invmassCproj->Draw("same");
+  //if(invmassBproj) invmassBproj->Draw("same");
   if(invmassetaproj) invmassetaproj->Draw("same");
   if(invmassSplittedTrackssproj) invmassSplittedTrackssproj->Draw("same");
   if(invmassSplittedTrackosproj) invmassSplittedTrackosproj->Draw("same");
   TLegend *legi = new TLegend(0.4,0.6,0.89,0.89);
-  legi->AddEntry(invmassppproj,"positive-positive","p");
-  legi->AddEntry(invmassnnproj,"negative-negative","p");
+  //legi->AddEntry(invmassppproj,"positive-positive","p");
+  //legi->AddEntry(invmassnnproj,"negative-negative","p");
   legi->AddEntry(invmassssproj,"same-sign","p");
-  legi->AddEntry(invmassrproj,"rotated","p");
+  //legi->AddEntry(invmassrproj,"rotated","p");
   legi->AddEntry(invmassosproj,"positive-negative","p");
   if(invmassgammaproj) legi->AddEntry(invmassgammaproj,"e^{+}e^{-} from #gamma","p");
   if(invmasspi0proj) legi->AddEntry(invmasspi0proj,"e^{+}e^{-} from #pi^{0}","p");
-  if(invmassCproj) legi->AddEntry(invmassCproj,"e^{+}e^{-} from c","p");
-  if(invmassBproj) legi->AddEntry(invmassBproj,"e^{+}e^{-} from b","p");
+  //if(invmassCproj) legi->AddEntry(invmassCproj,"e^{+}e^{-} from c","p");
+  //if(invmassBproj) legi->AddEntry(invmassBproj,"e^{+}e^{-} from b","p");
   if(invmassetaproj) legi->AddEntry(invmassetaproj,"e^{+}e^{-} from #eta","p");
   if(invmassSplittedTrackssproj) legi->AddEntry(invmassSplittedTrackssproj,"Splitted tracks same sign","p");
   if(invmassSplittedTrackosproj) legi->AddEntry(invmassSplittedTrackosproj,"Splitted tracks opposite sign","p");
   legi->Draw("same");
 
+  
+
   // Draw histograms for opening angle 2D
   TCanvas * copeningangle2D =new TCanvas("openingangle2D","Openingangle2D",800,800);
   copeningangle2D->Divide(6,2);
@@ -1526,5 +2189,649 @@ void AliHFEelecbackground::Plot() const
   if(invmassSplittedTrackssproj2D) invmassSplittedTrackssproj2D->Draw("lego");
   cinvmass2D->cd(12);
   if(invmassSplittedTrackosproj2D) invmassSplittedTrackosproj2D->Draw("lego");
+
+
+  ////////////////////////
+  // Cut efficiencies
+  ////////////////////////
+
+  THnSparseF *hsSparseMCe = dynamic_cast<THnSparseF *>(fList->FindObject("CutPassedMC"));
+  
+  if(hsSparseMCe) {
+
+    // init histos
+    TAxis *axissources = hsSparseMCe->GetAxis(2);
+    Int_t  nbsources = axissources->GetNbins(); 
+    TAxis *axiscuts = hsSparseMCe->GetAxis(1);
+    Int_t  nbcuts = axiscuts->GetNbins(); 
+    TH1D **histopassedcuts = new TH1D*[nbsources*nbcuts];  
+    Double_t *nbEntriesCuts = new Double_t[nbsources*nbcuts]; 
+
+    //printf("Number of cuts %d\n",nbcuts);
+
+    // canvas
+    TCanvas * chsSparseMCeeff =new TCanvas("hsSparseMCeeffDebug","hsSparseMCeeffDebug",800,800);
+    chsSparseMCeeff->Divide(3,1);
+    // histos
+    for(Int_t sourceid = 0; sourceid < nbsources; sourceid++) {
+      hsSparseMCe->GetAxis(2)->SetRange(sourceid+1,sourceid+1);  
+      for(Int_t cut = 0; cut < nbcuts; cut++){
+       hsSparseMCe->GetAxis(1)->SetRange(cut+1,cut+1); 
+       histopassedcuts[sourceid*nbcuts+cut] = hsSparseMCe->Projection(0);
+       hsSparseMCe->GetAxis(1)->SetRange(1,hsSparseMCe->GetAxis(1)->GetNbins()); 
+      }
+      hsSparseMCe->GetAxis(2)->SetRange(1,hsSparseMCe->GetAxis(2)->GetNbins());  
+    }
+
+    // calcul efficiencies
+    ///////////////////////
+    // histos
+    for(Int_t sourceid = 0; sourceid < nbsources; sourceid++) {
+      // Next is compared to the partner tracked
+      for(Int_t cut = 2; cut < nbcuts; cut++){
+       nbEntriesCuts[sourceid*nbcuts+cut] = histopassedcuts[sourceid*nbcuts+cut]->GetEntries();
+       if(histopassedcuts[sourceid*nbcuts+1]->GetEntries() > 0.0) histopassedcuts[sourceid*nbcuts+cut]->Divide(histopassedcuts[sourceid*nbcuts+1]);
+      }
+      // First one is if the partner is tracked.
+      nbEntriesCuts[sourceid*nbcuts+1] = histopassedcuts[sourceid*nbcuts+1]->GetEntries();
+      if(histopassedcuts[sourceid*nbcuts]->GetEntries() > 0.0) histopassedcuts[sourceid*nbcuts+1]->Divide(histopassedcuts[sourceid*nbcuts]);
+      // First one is input
+      nbEntriesCuts[sourceid*nbcuts] = histopassedcuts[sourceid*nbcuts]->GetEntries();
+    }
+    
+    /////////////
+    // ratios
+    ////////////
+    for(Int_t sourceid = 0; sourceid < nbsources; sourceid++) {
+      for(Int_t cut = 1; cut < nbcuts; cut++){
+       if(nbEntriesCuts[sourceid*nbcuts] > 0.0) nbEntriesCuts[sourceid*nbcuts+cut] = nbEntriesCuts[sourceid*nbcuts+cut]/nbEntriesCuts[sourceid*nbcuts]; 
+      }
+    }
+    TH1F *ratioHistoEntriesGamma = new TH1F("ratioHistoEntriesGamma","", nbcuts-1, 0.0, nbcuts-1.0);
+    TH1F *ratioHistoEntriesPi0 = new TH1F("ratioHistoEntriesPi0","", nbcuts-1, 0.0, nbcuts-1.0);
+    TH1F *ratioHistoEntriesC = new TH1F("ratioHistoEntriesC","", nbcuts-1, 0.0, nbcuts-1.0);
+    for(Int_t k = 1; k < nbcuts; k++){
+      ratioHistoEntriesGamma->SetBinContent(k,nbEntriesCuts[nbcuts+k]);
+      ratioHistoEntriesPi0->SetBinContent(k,nbEntriesCuts[2*nbcuts+k]);
+      ratioHistoEntriesC->SetBinContent(k,nbEntriesCuts[4*nbcuts+k]);
+    }     
+    //
+    TAxis *xAxisGamma = ratioHistoEntriesGamma->GetXaxis();
+    xAxisGamma->SetBinLabel(1,"Partner tracked");
+    xAxisGamma->SetBinLabel(2,"Opposite sign");
+    xAxisGamma->SetBinLabel(3,"Single Track Cut");
+    xAxisGamma->SetBinLabel(4,"Shared Clusters");
+    xAxisGamma->SetBinLabel(5,"PID");
+    xAxisGamma->SetBinLabel(6,"DCA");
+    xAxisGamma->SetBinLabel(7,"Chi^{2}/Ndf");
+    xAxisGamma->SetBinLabel(8,"Opening angle");
+    xAxisGamma->SetBinLabel(9,"Invariant mass");
+    //
+    TAxis *xAxisPi0 = ratioHistoEntriesPi0->GetXaxis();
+    xAxisPi0->SetBinLabel(1,"Partner tracked");
+    xAxisPi0->SetBinLabel(2,"Opposite sign");
+    xAxisPi0->SetBinLabel(3,"Single Track Cut");
+    xAxisPi0->SetBinLabel(4,"Shared Clusters");
+    xAxisPi0->SetBinLabel(5,"PID");
+    xAxisPi0->SetBinLabel(6,"DCA");
+    xAxisPi0->SetBinLabel(7,"Chi^{2}/Ndf");
+    xAxisPi0->SetBinLabel(8,"Opening angle");
+    xAxisPi0->SetBinLabel(9,"Invariant mass");
+    //
+    TAxis *xAxisC = ratioHistoEntriesC->GetXaxis();
+    xAxisC->SetBinLabel(1,"Partner tracked");
+    xAxisC->SetBinLabel(2,"Opposite sign");
+    xAxisC->SetBinLabel(3,"Single Track Cut");
+    xAxisC->SetBinLabel(4,"Shared Clusters");
+    xAxisC->SetBinLabel(5,"PID");
+    xAxisC->SetBinLabel(6,"DCA");
+    xAxisC->SetBinLabel(7,"Chi^{2}/Ndf");
+    xAxisC->SetBinLabel(8,"Opening angle");
+    xAxisC->SetBinLabel(9,"Invariant mass");
+    //
+    TCanvas * cRatioHistoEntries =new TCanvas("cRatioHistoEntries","cRatioHistoEntries",800,800);
+    cRatioHistoEntries->cd(1);
+    ratioHistoEntriesGamma->SetStats(0);
+    ratioHistoEntriesGamma->Draw();
+    ratioHistoEntriesPi0->SetStats(0);
+    ratioHistoEntriesPi0->Draw("same");
+    ratioHistoEntriesC->SetStats(0);
+    //ratioHistoEntriesC->Draw("same");
+    TLegend *legEntries = new TLegend(0.4,0.6,0.89,0.89);
+    legEntries->AddEntry(ratioHistoEntriesGamma,"#gamma","l");
+    legEntries->AddEntry(ratioHistoEntriesPi0,"#pi^{0}","l");
+    //legEntries->AddEntry(ratioHistoEntriesC,"c","p");
+    legEntries->Draw("same"); 
+
+    ////////////////////
+    // plot Debug
+    ///////////////////
+    Int_t source = 1;
+    chsSparseMCeeff->cd(1);
+    histopassedcuts[source*nbcuts+0]->SetTitle("#gamma");
+    histopassedcuts[source*nbcuts+1]->SetTitle("#gamma");
+    histopassedcuts[source*nbcuts+2]->SetTitle("#gamma");
+    histopassedcuts[source*nbcuts+3]->SetTitle("#gamma");
+    histopassedcuts[source*nbcuts+4]->SetTitle("#gamma");
+    histopassedcuts[source*nbcuts+5]->SetTitle("#gamma");
+    histopassedcuts[source*nbcuts+6]->SetTitle("#gamma");
+    histopassedcuts[source*nbcuts+7]->SetTitle("#gamma");
+    histopassedcuts[source*nbcuts+8]->SetTitle("#gamma");
+    histopassedcuts[source*nbcuts+9]->SetTitle("#gamma");
+    //histopassedcuts[source*nbcuts+0]->SetStats(0);
+    histopassedcuts[source*nbcuts+1]->SetStats(0);
+    histopassedcuts[source*nbcuts+2]->SetStats(0);
+    histopassedcuts[source*nbcuts+3]->SetStats(0);
+    histopassedcuts[source*nbcuts+4]->SetStats(0);
+    histopassedcuts[source*nbcuts+5]->SetStats(0);
+    histopassedcuts[source*nbcuts+6]->SetStats(0);
+    histopassedcuts[source*nbcuts+7]->SetStats(0);
+    histopassedcuts[source*nbcuts+8]->SetStats(0);
+    histopassedcuts[source*nbcuts+9]->SetStats(0);
+    //histopassedcuts[source*nbcuts+0]->Draw();
+    //histopassedcuts[source*nbcuts+1]->Draw("");
+    histopassedcuts[source*nbcuts+2]->Draw();
+    histopassedcuts[source*nbcuts+3]->Draw("same");
+    //histopassedcuts[source*nbcuts+4]->Draw("same");
+    histopassedcuts[source*nbcuts+5]->Draw("same");
+    histopassedcuts[source*nbcuts+6]->Draw("same");
+    //histopassedcuts[source*nbcuts+7]->Draw("same");
+    histopassedcuts[source*nbcuts+8]->Draw("same");
+    histopassedcuts[source*nbcuts+9]->Draw("same");
+    TLegend *legb = new TLegend(0.4,0.6,0.89,0.89);
+    //legb->AddEntry(histopassedcuts[source*nbcuts+0],"all","p");
+    //legb->AddEntry(histopassedcuts[source*nbcuts+1],"Partner tracked","p");
+    legb->AddEntry(histopassedcuts[source*nbcuts+2],"Opposite sign","p");
+    legb->AddEntry(histopassedcuts[source*nbcuts+3],"SingleTrackPart","p");
+    //legb->AddEntry(histopassedcuts[source*nbcuts+4],"SharedCluster","p");
+    legb->AddEntry(histopassedcuts[source*nbcuts+5],"PID","p");
+    legb->AddEntry(histopassedcuts[source*nbcuts+6],"DCA","p");
+    //legb->AddEntry(histopassedcuts[source*nbcuts+7],"Chi2Ndf","p");
+    legb->AddEntry(histopassedcuts[source*nbcuts+8],"OpeningAngle","p");
+    legb->AddEntry(histopassedcuts[source*nbcuts+9],"InvMass","p");
+    legb->Draw("same");
+
+    source = 2;
+    chsSparseMCeeff->cd(2);
+    histopassedcuts[source*nbcuts+0]->SetTitle("#pi^{0}");
+    histopassedcuts[source*nbcuts+1]->SetTitle("#pi^{0}");
+    histopassedcuts[source*nbcuts+2]->SetTitle("#pi^{0}");
+    histopassedcuts[source*nbcuts+3]->SetTitle("#pi^{0}");
+    histopassedcuts[source*nbcuts+4]->SetTitle("#pi^{0}");
+    histopassedcuts[source*nbcuts+5]->SetTitle("#pi^{0}");
+    histopassedcuts[source*nbcuts+6]->SetTitle("#pi^{0}");
+    histopassedcuts[source*nbcuts+7]->SetTitle("#pi^{0}");
+    histopassedcuts[source*nbcuts+8]->SetTitle("#pi^{0}");
+    histopassedcuts[source*nbcuts+9]->SetTitle("#pi^{0}");
+    //histopassedcuts[source*nbcuts+0]->SetStats(0);
+    histopassedcuts[source*nbcuts+1]->SetStats(0);
+    histopassedcuts[source*nbcuts+2]->SetStats(0);
+    histopassedcuts[source*nbcuts+3]->SetStats(0);
+    histopassedcuts[source*nbcuts+4]->SetStats(0);
+    histopassedcuts[source*nbcuts+5]->SetStats(0);
+    histopassedcuts[source*nbcuts+6]->SetStats(0);
+    histopassedcuts[source*nbcuts+7]->SetStats(0);
+    histopassedcuts[source*nbcuts+8]->SetStats(0);
+    histopassedcuts[source*nbcuts+9]->SetStats(0);
+    //histopassedcuts[source*nbcuts+0]->Draw();
+    //histopassedcuts[source*nbcuts+1]->Draw();
+    histopassedcuts[source*nbcuts+2]->Draw();
+    histopassedcuts[source*nbcuts+3]->Draw("same");
+    //histopassedcuts[source*nbcuts+4]->Draw("same");
+    histopassedcuts[source*nbcuts+5]->Draw("same");
+    histopassedcuts[source*nbcuts+6]->Draw("same");
+    //histopassedcuts[source*nbcuts+7]->Draw("same");
+    histopassedcuts[source*nbcuts+8]->Draw("same");
+    histopassedcuts[source*nbcuts+9]->Draw("same");
+    TLegend *legc = new TLegend(0.4,0.6,0.89,0.89);
+    //legc->AddEntry(histopassedcuts[source*nbcuts+0],"all","p");
+    //legc->AddEntry(histopassedcuts[source*nbcuts+1],"Partner tracked","p");
+    legc->AddEntry(histopassedcuts[source*nbcuts+2],"Opposite sign","p");
+    legc->AddEntry(histopassedcuts[source*nbcuts+3],"SingleTrackPart","p");
+    //legc->AddEntry(histopassedcuts[source*nbcuts+4],"SharedCluster","p");
+    legc->AddEntry(histopassedcuts[source*nbcuts+5],"PID","p");
+    legc->AddEntry(histopassedcuts[source*nbcuts+6],"DCA","p");
+    //legc->AddEntry(histopassedcuts[source*nbcuts+7],"Chi2Ndf","p");
+    legc->AddEntry(histopassedcuts[source*nbcuts+8],"OpeningAngle","p");
+    legc->AddEntry(histopassedcuts[source*nbcuts+9],"InvMass","p");
+    legc->Draw("same");
+
+    source = 4;
+    chsSparseMCeeff->cd(3);
+    histopassedcuts[source*nbcuts+0]->SetTitle("C");
+    histopassedcuts[source*nbcuts+1]->SetTitle("C");
+    histopassedcuts[source*nbcuts+2]->SetTitle("C");
+    histopassedcuts[source*nbcuts+3]->SetTitle("C");
+    histopassedcuts[source*nbcuts+4]->SetTitle("C");
+    histopassedcuts[source*nbcuts+5]->SetTitle("C");
+    histopassedcuts[source*nbcuts+6]->SetTitle("C");
+    histopassedcuts[source*nbcuts+7]->SetTitle("C");
+    histopassedcuts[source*nbcuts+8]->SetTitle("C");
+    histopassedcuts[source*nbcuts+9]->SetTitle("C");
+    //histopassedcuts[source*nbcuts+0]->SetStats(0);
+    histopassedcuts[source*nbcuts+1]->SetStats(0);
+    histopassedcuts[source*nbcuts+2]->SetStats(0);
+    histopassedcuts[source*nbcuts+3]->SetStats(0);
+    histopassedcuts[source*nbcuts+4]->SetStats(0);
+    histopassedcuts[source*nbcuts+5]->SetStats(0);
+    histopassedcuts[source*nbcuts+6]->SetStats(0);
+    histopassedcuts[source*nbcuts+7]->SetStats(0);
+    histopassedcuts[source*nbcuts+8]->SetStats(0);
+    histopassedcuts[source*nbcuts+9]->SetStats(0);
+    //histopassedcuts[source*nbcuts+0]->Draw();
+    //histopassedcuts[source*nbcuts+1]->Draw();
+    histopassedcuts[source*nbcuts+2]->Draw();
+    histopassedcuts[source*nbcuts+3]->Draw("same");
+    //histopassedcuts[source*nbcuts+4]->Draw("same");
+    histopassedcuts[source*nbcuts+5]->Draw("same");
+    histopassedcuts[source*nbcuts+6]->Draw("same");
+    //histopassedcuts[source*nbcuts+7]->Draw("same");
+    histopassedcuts[source*nbcuts+8]->Draw("same");
+    histopassedcuts[source*nbcuts+9]->Draw("same");
+    TLegend *lege = new TLegend(0.4,0.6,0.89,0.89);
+    //lege->AddEntry(histopassedcuts[source*nbcuts+0],"all","p");
+    //lege->AddEntry(histopassedcuts[source*nbcuts+1],"Partner tracked","p");
+    lege->AddEntry(histopassedcuts[source*nbcuts+2],"Opposite sign","p");
+    lege->AddEntry(histopassedcuts[source*nbcuts+3],"SingleTrackPart","p");
+    //lege->AddEntry(histopassedcuts[source*nbcuts+4],"SharedCluster","p");
+    lege->AddEntry(histopassedcuts[source*nbcuts+5],"PID","p");
+    lege->AddEntry(histopassedcuts[source*nbcuts+6],"DCA","p");
+    //lege->AddEntry(histopassedcuts[source*nbcuts+7],"Chi2Ndf","p");
+    lege->AddEntry(histopassedcuts[source*nbcuts+8],"OpeningAngle","p");
+    lege->AddEntry(histopassedcuts[source*nbcuts+9],"InvMass","p");
+    lege->Draw("same");
+
+    //////////////////////
+    // Input
+    //////////////////////
+
+    TCanvas * chsSparseMCein =new TCanvas("hsSparseMCeinput","hsSparseMCeinput",800,800);
+    chsSparseMCein->cd(1);
+    Double_t nbGamma = 0.0;
+    source = 1;
+    nbGamma = histopassedcuts[source*nbcuts+0]->GetEntries();
+    histopassedcuts[source*nbcuts+0]->SetStats(0);
+    histopassedcuts[source*nbcuts+0]->Draw();
+    TLegend *leginput = new TLegend(0.4,0.6,0.89,0.89);
+    leginput->AddEntry(histopassedcuts[source*nbcuts+0],"#gamma","p");
+    Double_t nbPi0 = 0.0;
+    source = 2;
+    nbPi0 = histopassedcuts[source*nbcuts+0]->GetEntries();
+    histopassedcuts[source*nbcuts+0]->SetStats(0);
+    histopassedcuts[source*nbcuts+0]->Draw("same");
+    leginput->AddEntry(histopassedcuts[source*nbcuts+0],"#pi^{0}","p");
+    Double_t nbEta = 0.0;
+    source = 3;
+    nbEta = histopassedcuts[source*nbcuts+0]->GetEntries();
+    histopassedcuts[source*nbcuts+0]->SetStats(0);
+    histopassedcuts[source*nbcuts+0]->Draw("same");
+    leginput->AddEntry(histopassedcuts[source*nbcuts+0],"#eta","p");
+    Double_t nbC = 0.0;
+    source = 4;
+    nbC = histopassedcuts[source*nbcuts+0]->GetEntries();
+    histopassedcuts[source*nbcuts+0]->SetStats(0);
+    histopassedcuts[source*nbcuts+0]->Draw("same");
+    leginput->AddEntry(histopassedcuts[source*nbcuts+0],"c","p");
+    leginput->Draw("same");
+
+    //printf("Gamma %f, pi^{0} %f and #eta %f, c %f\n",nbGamma,nbPi0,nbEta,nbC);
+
+    //////////////////////
+    // Tracked
+    //////////////////////
+
+    TCanvas * cTracked = new TCanvas("cTracked","cTracked",800,800);
+    cTracked->cd(1);
+    source = 1;
+    histopassedcuts[source*nbcuts+1]->Draw();
+    TLegend *legTracked = new TLegend(0.4,0.6,0.89,0.89);
+    legTracked->AddEntry(histopassedcuts[source*nbcuts+1],"#gamma","p");
+    source = 2;
+    histopassedcuts[source*nbcuts+1]->Draw("same");
+    legTracked->AddEntry(histopassedcuts[source*nbcuts+1],"#pi^{0}","p");
+    legTracked->Draw("same");
+  
+  }
+
+  /////////////////////////////////////
+  // Data Radius and chi2Ndf if AliKF
+  ////////////////////////////////////
+  
+  TH1F *hDataRadius = dynamic_cast<TH1F *>(fList->FindObject("DataRadius")); 
+  TH1F *hDataChi2Ndf = dynamic_cast<TH1F *>(fList->FindObject("DataChi2Ndf")); 
+
+  if(hDataRadius || hDataChi2Ndf) {
+    TCanvas * cDataRadiusChi2Ndf =new TCanvas("CanvasDataRadiusChi2Ndf","CanvasDataRadiusChi2Ndf",800,800);
+    cDataRadiusChi2Ndf->Divide(2,1);
+    cDataRadiusChi2Ndf->cd(1);
+    if(hDataRadius) hDataRadius->Draw();
+    cDataRadiusChi2Ndf->cd(2);
+    if(hDataChi2Ndf) hDataChi2Ndf->Draw();
+  }
+
+  ///////////////////////
+  // Data DCA
+  //////////////////////
  
+  TH1F *hDataDCA = dynamic_cast<TH1F *>(fList->FindObject("DataDCA")); 
+  
+  if(hDataDCA) {
+    TCanvas * cDataDCA =new TCanvas("CanvasDataDCA","CanvasDataDCA",800,800);
+    cDataDCA->cd(1);
+    hDataDCA->Draw();
+  }
+
+  /////////////////////////////////////
+  // MC Radius and chi2Ndf if AliKF
+  ////////////////////////////////////
+  
+  TH2F *hMCRadius = dynamic_cast<TH2F *>(fList->FindObject("MCRadius")); 
+  TH2F *hMCChi2Ndf = dynamic_cast<TH2F *>(fList->FindObject("MCChi2Ndf")); 
+
+  if(hMCRadius || hMCChi2Ndf) {
+    TCanvas * cMCRadiusChi2Ndf =new TCanvas("CanvasMCRadiusChi2Ndf","CanvasMCRadiusChi2Ndf",800,800);
+    cMCRadiusChi2Ndf->Divide(2,1);
+    cMCRadiusChi2Ndf->cd(1);
+    //TH1D *hMCRadiusBackground = hMCRadius->ProjectionX("MCRadiusBackGround",1,1,"e");
+    TH1D *hMCRadiusGamma = hMCRadius->ProjectionX("MCRadiusGamma",2,2,"e");
+    TH1D *hMCRadiusPi0 = hMCRadius->ProjectionX("MCRadiusPi0",3,3,"e");
+    TH1D *hMCRadiusEta = hMCRadius->ProjectionX("MCRadiusEta",4,4,"e");
+    TH1D *hMCRadiusC = hMCRadius->ProjectionX("MCRadiusC",5,5,"e");
+    TH1D *hMCRadiusB = hMCRadius->ProjectionX("MCRadiusB",6,6,"e");
+    //hMCRadiusBackground->Draw();
+    hMCRadiusGamma->Draw();
+    hMCRadiusPi0->Draw("same");
+    hMCRadiusEta->Draw("same");
+    hMCRadiusC->Draw("same");
+    hMCRadiusB->Draw("same");
+    TLegend *legRadius = new TLegend(0.4,0.6,0.89,0.89);
+    //legRadius->AddEntry(hMCRadiusBackground,"Background","p");
+    legRadius->AddEntry(hMCRadiusGamma,"#gamma","p");
+    legRadius->AddEntry(hMCRadiusPi0,"#pi^{0}","p");
+    legRadius->AddEntry(hMCRadiusEta,"#eta","p");
+    legRadius->AddEntry(hMCRadiusC,"c","p");
+    legRadius->AddEntry(hMCRadiusB,"b","p");
+    legRadius->Draw("same");
+    cMCRadiusChi2Ndf->cd(2);
+    //TH1D *hMCChi2NdfBackground = hMCChi2Ndf->ProjectionX("MCChi2NdfBackGround",1,1,"e");
+    TH1D *hMCChi2NdfGamma = hMCChi2Ndf->ProjectionX("MCChi2NdfGamma",2,2,"e");
+    TH1D *hMCChi2NdfPi0 = hMCChi2Ndf->ProjectionX("MCChi2NdfPi0",3,3,"e");
+    TH1D *hMCChi2NdfEta = hMCChi2Ndf->ProjectionX("MCChi2NdfEta",4,4,"e");
+    TH1D *hMCChi2NdfC = hMCChi2Ndf->ProjectionX("MCChi2NdfC",5,5,"e");
+    TH1D *hMCChi2NdfB = hMCChi2Ndf->ProjectionX("MCChi2NdfB",6,6,"e");
+    //hMCChi2NdfBackground->Draw();
+    hMCChi2NdfGamma->Draw();
+    hMCChi2NdfPi0->Draw("same");
+    hMCChi2NdfEta->Draw("same");
+    hMCChi2NdfC->Draw("same");
+    hMCChi2NdfB->Draw("same");
+    TLegend *legChi2Ndf = new TLegend(0.4,0.6,0.89,0.89);
+    //legChi2Ndf->AddEntry(hMCChi2NdfBackground,"Background","p");
+    legChi2Ndf->AddEntry(hMCChi2NdfGamma,"#gamma","p");
+    legChi2Ndf->AddEntry(hMCChi2NdfPi0,"#pi^{0}","p");
+    legChi2Ndf->AddEntry(hMCChi2NdfEta,"#eta","p");
+    legChi2Ndf->AddEntry(hMCChi2NdfC,"c","p");
+    legChi2Ndf->AddEntry(hMCChi2NdfB,"b","p");
+    legChi2Ndf->Draw("same");
+  }
+
+  ///////////////////////
+  // MC DCA
+  //////////////////////
+  
+  TH2F *hMCDCA = dynamic_cast<TH2F *>(fList->FindObject("MCDCA")); 
+  
+  if(hMCDCA) {
+    TCanvas * cMCDCA =new TCanvas("CanvasMCDCA","CanvasMCDCA",800,800);
+    cMCDCA->cd(1);
+    //TH1D *hMCDCABackground = hMCDCA->ProjectionX("MCDCABackGround",1,1,"e");
+    TH1D *hMCDCAGamma = hMCDCA->ProjectionX("MCDCAGamma",2,2,"e");
+    TH1D *hMCDCAPi0 = hMCDCA->ProjectionX("MCDCAPi0",3,3,"e");
+    TH1D *hMCDCAEta = hMCDCA->ProjectionX("MCDCAEta",4,4,"e");
+    TH1D *hMCDCAC = hMCDCA->ProjectionX("MCDCAC",5,5,"e");
+    TH1D *hMCDCAB = hMCDCA->ProjectionX("MCDCAB",6,6,"e");
+    //hMCDCABackground->Draw();
+    hMCDCAGamma->Draw();
+    hMCDCAPi0->Draw("same");
+    hMCDCAEta->Draw("same");
+    hMCDCAC->Draw("same");
+    hMCDCAB->Draw("same");
+    TLegend *legDCA = new TLegend(0.4,0.6,0.89,0.89);
+    //legDCA->AddEntry(hMCDCABackground,"Background","p");
+    legDCA->AddEntry(hMCDCAGamma,"#gamma","p");
+    legDCA->AddEntry(hMCDCAPi0,"#pi^{0}","p");
+    legDCA->AddEntry(hMCDCAEta,"#eta","p");
+    legDCA->AddEntry(hMCDCAC,"c","p");
+    legDCA->AddEntry(hMCDCAB,"b","p");
+    legDCA->Draw("same");
+  }
+
+
+  /////////////////////////
+  // PID Partner Signal
+  /////////////////////////
+  TF1 *betheBlochElectron = 0x0;
+  TF1 *betheBlochMuon = 0x0;
+  TF1 *betheBlochPion = 0x0;
+  TF1 *betheBlochKaon = 0x0;
+  TF1 *betheBlochProton = 0x0;
+
+  TH2F *hsignalPidPartner0 = dynamic_cast<TH2F *>(fList->FindObject("TPCPartner0")); 
+  TH2F *hsignalPidPartner1 = dynamic_cast<TH2F *>(fList->FindObject("TPCPartner1"));
+  if((!hsignalPidPartner0) && (!hsignalPidPartner1)) {
+    hsignalPidPartner0 = dynamic_cast<TH2F *>(fList->FindObject("ITSPartner0")); 
+    hsignalPidPartner1 = dynamic_cast<TH2F *>(fList->FindObject("ITSPartner1"));
+    
+    betheBlochElectron = new TF1("betheBlochElectron",BetheBlochElectronITS,0.1,10.0,0);
+    betheBlochMuon = new TF1("betheBlochMuon",BetheBlochMuonITS,0.1,10.0,0);
+    betheBlochPion = new TF1("betheBlochPion",BetheBlochPionITS,0.1,10.0,0);
+    betheBlochKaon = new TF1("betheBlochKaon",BetheBlochKaonITS,0.1,10.0,0);
+    betheBlochProton = new TF1("betheBlochProton",BetheBlochProtonITS,0.1,10.0,0);
+
+  }
+  else {
+
+    betheBlochElectron = new TF1("betheBlochElectron",BetheBlochElectronTPC,0.1,10.0,0);
+    betheBlochMuon = new TF1("betheBlochMuon",BetheBlochMuonTPC,0.1,10.0,0);
+    betheBlochPion = new TF1("betheBlochPion",BetheBlochPionTPC,0.1,10.0,0);
+    betheBlochKaon = new TF1("betheBlochKaon",BetheBlochKaonTPC,0.1,10.0,0);
+    betheBlochProton = new TF1("betheBlochProton",BetheBlochProtonTPC,0.1,10.0,0);
+
+  }
+
+
+  if((hsignalPidPartner0) || (hsignalPidPartner1)) {
+    TCanvas * cPidSignal =new TCanvas("cPidSignal","cPidSignal",800,800);
+    cPidSignal->Divide(2,1);
+    cPidSignal->cd(1);
+    if(hsignalPidPartner0) hsignalPidPartner0->Draw("colz");
+    if(betheBlochElectron) betheBlochElectron->Draw("same");
+    if(betheBlochMuon) betheBlochMuon->Draw("same");
+    if(betheBlochPion) betheBlochPion->Draw("same");
+    if(betheBlochKaon) betheBlochKaon->Draw("same");
+    if(betheBlochProton) betheBlochProton->Draw("same");
+    cPidSignal->cd(2);
+    if(hsignalPidPartner1) hsignalPidPartner1->Draw("colz");
+    if(betheBlochElectron) betheBlochElectron->Draw("same");
+    if(betheBlochMuon) betheBlochMuon->Draw("same");
+    if(betheBlochPion) betheBlochPion->Draw("same");
+    if(betheBlochKaon) betheBlochKaon->Draw("same");
+    if(betheBlochProton) betheBlochProton->Draw("same");
+  }
+  
+  THnSparseF *hsSparseITSsignal = dynamic_cast<THnSparseF *>(fList->FindObject("SparseITSsignal"));
+  if(hsSparseITSsignal) {
+
+   
+    TH2D *sddsdd = hsSparseITSsignal->Projection(1,2);
+    TH2D *ssdssd = hsSparseITSsignal->Projection(3,4);
+    TH2D *sddssda = hsSparseITSsignal->Projection(1,3);    
+    TH2D *sddssdb = hsSparseITSsignal->Projection(2,4);    
+    TH2D *sddssdc = hsSparseITSsignal->Projection(1,4);   
+    TH2D *sddssdd = hsSparseITSsignal->Projection(2,3);    
+
+    TCanvas * cITSSignal =new TCanvas("cITSSignal","cITSSignal",800,800);
+    cITSSignal->Divide(2,3);
+    cITSSignal->cd(1);
+    sddsdd->Draw("colz");
+    cITSSignal->cd(2);
+    ssdssd->Draw("colz");
+    cITSSignal->cd(3);
+    sddssda->Draw("colz");
+    cITSSignal->cd(4);
+    sddssdb->Draw("colz");
+    cITSSignal->cd(5);
+    sddssdc->Draw("colz");
+    cITSSignal->cd(6);
+    sddssdd->Draw("colz");
+  
+  } 
+
+  THnSparseF *hsSparseITSsignalSplit = dynamic_cast<THnSparseF *>(fList->FindObject("SparseITSsignalSplit"));
+  if(hsSparseITSsignalSplit) {
+
+    // no splitted
+    hsSparseITSsignalSplit->GetAxis(0)->SetRange(1,1);
+    
+    TH1D *layerITS2 = hsSparseITSsignalSplit->Projection(1);
+    TH1D *layerITS3 = hsSparseITSsignalSplit->Projection(2);
+    TH1D *layerITS4 = hsSparseITSsignalSplit->Projection(3);
+    TH1D *layerITS5 = hsSparseITSsignalSplit->Projection(4);
+
+    // splitted
+    hsSparseITSsignalSplit->GetAxis(0)->SetRange(2,2);
+    
+    TH1D *layerITS2s = hsSparseITSsignalSplit->Projection(1);
+    TH1D *layerITS3s = hsSparseITSsignalSplit->Projection(2);
+    TH1D *layerITS4s = hsSparseITSsignalSplit->Projection(3);
+    TH1D *layerITS5s = hsSparseITSsignalSplit->Projection(4);
+    
+    TCanvas * cITSSignalSplit =new TCanvas("cITSSignalSplit","cITSSignalSplit",800,800);
+    cITSSignalSplit->Divide(2,2);
+    cITSSignalSplit->cd(1);
+    layerITS2->Draw();
+    layerITS2s->Draw("same");
+    TLegend *legITS2 = new TLegend(0.4,0.6,0.89,0.89);
+    legITS2->AddEntry(layerITS2,"No splitted","p");
+    legITS2->AddEntry(layerITS2s,"Splitted","p");
+    legITS2->Draw("same");
+    cITSSignalSplit->cd(2);
+    layerITS3->Draw();
+    layerITS3s->Draw("same");
+    TLegend *legITS3 = new TLegend(0.4,0.6,0.89,0.89);
+    legITS3->AddEntry(layerITS3,"No splitted","p");
+    legITS3->AddEntry(layerITS3s,"Splitted","p");
+    legITS3->Draw("same");
+    cITSSignalSplit->cd(3);
+    layerITS4->Draw();
+    layerITS4s->Draw("same");
+    TLegend *legITS4 = new TLegend(0.4,0.6,0.89,0.89);
+    legITS4->AddEntry(layerITS4,"No splitted","p");
+    legITS4->AddEntry(layerITS4s,"Splitted","p");
+    legITS4->Draw("same");
+    cITSSignalSplit->cd(4);
+    layerITS5->Draw();
+    layerITS5s->Draw("same");
+    TLegend *legITS5 = new TLegend(0.4,0.6,0.89,0.89);
+    legITS5->AddEntry(layerITS5,"No splitted","p");
+    legITS5->AddEntry(layerITS5s,"Splitted","p");
+    legITS5->Draw("same");
+
+  
+  }  
+
+}
+//_____________________________________________________________________________
+Double_t AliHFEelecbackground::BetheBlochElectronITS(const Double_t *x, const Double_t * /*par*/) 
+{
+  //
+  // Bethe Bloch for ITS
+  //
+  static AliITSPIDResponse itsPidResponse;
+  return itsPidResponse.Bethe(x[0],AliPID::ParticleMass(0));
+}
+//_____________________________________________________________________________
+Double_t AliHFEelecbackground::BetheBlochMuonITS(const Double_t *x, const Double_t * /*par*/) 
+{
+  //
+  // Bethe Bloch for ITS
+  //
+  static AliITSPIDResponse itsPidResponse;
+  return itsPidResponse.Bethe(x[0],AliPID::ParticleMass(1));
+}
+//_____________________________________________________________________________
+Double_t AliHFEelecbackground::BetheBlochPionITS(const Double_t *x, const Double_t * /*par*/) 
+{
+  //
+  // Bethe Bloch for ITS
+  //
+  static AliITSPIDResponse itsPidResponse;
+  return itsPidResponse.Bethe(x[0],AliPID::ParticleMass(2));
+}
+//_____________________________________________________________________________
+Double_t AliHFEelecbackground::BetheBlochKaonITS(const Double_t *x, const Double_t * /*par*/) 
+{
+  //
+  // Bethe Bloch for ITS
+  //
+  static AliITSPIDResponse itsPidResponse;
+  return itsPidResponse.Bethe(x[0],AliPID::ParticleMass(3));
+}
+//_____________________________________________________________________________
+Double_t AliHFEelecbackground::BetheBlochProtonITS(const Double_t *x, const Double_t * /*par*/) 
+{
+  //
+  // Bethe Bloch for ITS
+  //
+  static AliITSPIDResponse itsPidResponse;
+  return itsPidResponse.Bethe(x[0],AliPID::ParticleMass(4));
+}
+//_____________________________________________________________________________
+Double_t AliHFEelecbackground::BetheBlochElectronTPC(const Double_t *x, const Double_t * /*par*/) 
+{
+  //
+  // Bethe Bloch for TPC
+  //
+  static AliTPCPIDResponse tpcPidResponse;
+  return tpcPidResponse.GetExpectedSignal(x[0],AliPID::kElectron);
+}
+//_____________________________________________________________________________
+Double_t AliHFEelecbackground::BetheBlochMuonTPC(const Double_t *x, const Double_t * /*par*/) 
+{
+  //
+  // Bethe Bloch for TPC
+  //
+  static AliTPCPIDResponse tpcPidResponse;
+  return tpcPidResponse.GetExpectedSignal(x[0],AliPID::kMuon);
+}
+//_____________________________________________________________________________
+Double_t AliHFEelecbackground::BetheBlochPionTPC(const Double_t *x, const Double_t * /*par*/) 
+{
+  //
+  // Bethe Bloch for TPC
+  //
+  static AliTPCPIDResponse tpcPidResponse;
+  return tpcPidResponse.GetExpectedSignal(x[0],AliPID::kPion);
+}
+//_____________________________________________________________________________
+Double_t AliHFEelecbackground::BetheBlochKaonTPC(const Double_t *x, const Double_t * /*par*/) 
+{
+  //
+  // Bethe Bloch for TPC
+  //
+  static AliTPCPIDResponse tpcPidResponse;
+  return tpcPidResponse.GetExpectedSignal(x[0],AliPID::kKaon);
+}
+//_____________________________________________________________________________
+Double_t AliHFEelecbackground::BetheBlochProtonTPC(const Double_t *x, const Double_t * /*par*/) 
+{
+  //
+  // Bethe Bloch for TPC
+  //
+  static AliTPCPIDResponse tpcPidResponse;
+  return tpcPidResponse.GetExpectedSignal(x[0],AliPID::kProton);
 }
+
+
+
index 918a175..1e32f42 100644 (file)
 #endif
 
 class AliESDEvent;
+class AliESDpid;
 class AliESDVertex;
 class AliAODEvent;
 class AliESDtrack;
 class AliAODTrack;
 class AliMCEvent;
 
+class AliHFEpid;
+
+
 //________________________________________________________________
 class AliHFEelecbackground : public TObject {
-
-        public: 
-                AliHFEelecbackground();
-                AliHFEelecbackground(const AliHFEelecbackground &p);
-                AliHFEelecbackground &operator=(const AliHFEelecbackground &);
-                virtual ~AliHFEelecbackground();
+  public: 
+    AliHFEelecbackground();
+    AliHFEelecbackground(const AliHFEelecbackground &p);
+    AliHFEelecbackground &operator=(const AliHFEelecbackground &);
+    virtual ~AliHFEelecbackground();
                virtual Bool_t Load(const Char_t *filename);
+               virtual Bool_t Load(TList * const outputlist);
 
-                void CreateHistograms(TList* const qaList);
+    void CreateHistograms(TList * const qaList);
                void Reset();
 
-                Bool_t HasMCData() const { return TestBit(kHasMCData); };
-                Bool_t IsAODanalysis() const { return TestBit(kAODanalysis); };
-                Bool_t IsESDanalysis() const { return !TestBit(kAODanalysis); };
-
-               void SetHasMCData(Bool_t hasMCdata = kTRUE) { SetBit(kHasMCData,hasMCdata); };
-                void SetAODAnalysis() { SetBit(kAODanalysis, kTRUE); };
-                void SetESDAnalysis() { SetBit(kAODanalysis, kFALSE); };
-                void SetEvent(AliESDEvent* const ESD); 
-                void SetEventAOD(AliAODEvent* const AOD){fAOD1=AOD;}; 
-                void SetMCEvent(AliMCEvent* const mcEvent){fMCEvent=mcEvent;};  
+    Bool_t HasMCData() const { return TestBit(kHasMCData); };
+    Bool_t IsAODanalysis() const { return TestBit(kAODanalysis); };
+    Bool_t IsESDanalysis() const { return !TestBit(kAODanalysis); };
+
+    void SetHasMCData(Bool_t hasMCdata = kTRUE) { SetBit(kHasMCData,hasMCdata); };
+    void SetAODAnalysis() { SetBit(kAODanalysis, kTRUE); };
+    void SetESDAnalysis() { SetBit(kAODanalysis, kFALSE); };
+    void SetEvent(AliESDEvent* const ESD); 
+    void SetEventAOD(AliAODEvent* const AOD){fAOD1=AOD;}; 
+    void SetMCEvent(AliMCEvent* const mcEvent){fMCEvent=mcEvent;};  
+
+    void SetOpeningAngleCut(Double_t openingAngleCut){fOpeningAngleCut = openingAngleCut;};
+               void SetInvMassCut(Double_t invMassCut){fInvMassCut = invMassCut;};
+               void SetChi2NdfCut(Double_t chi2NdfCut){fChi2NdfCut = chi2NdfCut;};
+               void SetUseAliKFCode(Bool_t useAliKFCode){fUseAliKFCode = useAliKFCode;};    
+               void SetSharedClusterCut(Bool_t sharedClusterCut){fSharedClusterCut = sharedClusterCut;};
+               void SetRequireITSStandalone(Short_t requireITSStandalone){fRequireITSStandalone = requireITSStandalone;};
+               void SetMinITSChi2(Double_t minITSChi2) {fMinITSChi2 = minITSChi2;};
+               void SetMinNbCls(Int_t minNbCls){fMinNbCls = minNbCls;};
+               void SetMinNbClsSDDSPD(Int_t minNbClsSDDSPD){fMinNbClsSDDSPD = minNbClsSDDSPD;};
+               void SetPIDPartner();
+               void SetPIDMethodPartner(AliHFEpid * const pid) {fPIDMethodPartner = pid;};
+               void SetPIDMethodPartnerITS(AliESDpid * const pid) {fPIDMethodPartnerITS = pid;};
+               void SetDebugLevel(Short_t debugLevel) { fDebugLevel = debugLevel;};
+       
+               Double_t GetOpeningAngleCut() const { return fOpeningAngleCut; };
+               Double_t GetInvMassCut() const { return fInvMassCut; };
+               Double_t GetChi2NdfCut() const { return fChi2NdfCut; };
+               Bool_t GetUseAliKFCode() const { return fUseAliKFCode; };
+               Bool_t GetSharedClusterCut() const { return fSharedClusterCut; };
+               Short_t GetRequireITSStandalone() const { return fRequireITSStandalone; };
+               Int_t GetMinNbCls() const { return fMinNbCls;};
+               Double_t GetMinITSChi2() const { return fMinITSChi2; };
+               Int_t GetMinNbClsSDDSPD() const { return fMinNbClsSDDSPD;};
+               Bool_t GetPIDPartner() const { return fPIDPartner;};
 
                TList *GetList()  const           { return fList; };
                TList *GetListPostProcess() const { return fListPostProcess; };
 
-               Bool_t SingleTrackCut(AliESDtrack* const track1) const; 
-                void PairAnalysis(AliESDtrack* const track, AliESDtrack* const trackpart); 
+               Bool_t SingleTrackCut(AliESDtrack* const trackPart) const;
+               Bool_t ShareCluster(AliESDtrack * const track1,AliESDtrack * const track2) const; 
+               Bool_t PIDTrackCut(AliESDtrack* const trackPart);
+               void PairAnalysis(AliESDtrack* const track, AliESDtrack* const trackpart); 
                void FillOutput(Double_t *results, Double_t *resultsr, Int_t sign); 
-                void PostProcess();
+    void PostProcess();
                void Plot() const;
 
-
  private:
-
-                enum{
-                    kHasMCData = BIT(15),     // bitset for mc data usage
-                   kAODanalysis = BIT(16)    // bitset for aod analysis
-                   };
-               enum {kPp=0, kNn=1, kSs=2, kR=3, kOs=4};
-               enum {kOos=0, kOss=1, kOr=2, kOdiff=3};  // outputs 
+    enum{
+      kHasMCData = BIT(15),             // bitset for mc data usage
+                 kAODanalysis = BIT(16)            // bitset for aod analysis
+               };
+               enum {kDatai=0, kDatar=1, kDatadca=2, kDatachi2Ndf=3, kMCo=4, kMCr=5, kMCdca=6, kMCchi2Ndf=7, kMCe=8, kMCcutPart0=9, kMCcutPart1=10, kMCcutPart2=11, kMCcutPart3=12};   // In the fList Data/MC
+               enum {kOs=0, kPp=1, kNn=2, kR=3};            // In the last dimension Charge
+               enum {kOos=0, kOss=1, kOr=2, kOdiff=3};      // outputs 
+               enum {kNOutput=4,kNMCInfo=5};                // Nb of outputs
                enum{
-                 kElectronFromGamma = 0,
-                   kElectronFromPi0 = 1,
-                   kElectronFromC = 2,
-                   kElectronFromB = 3,
-                   kElectronFromEta = 4,
-                   kSplittedTrackss =5,
-                   kSplittedTrackos =6
-                   };
-               enum {kNOutput=4, kNSignComb=5, kNMCInfo=7}; 
+                 kElectronFromBackground = 0,
+                 kElectronFromGamma = 1,
+                 kElectronFromPi0 = 2,
+                 kElectronFromEta = 3,
+                 kElectronFromC = 4,
+                 kElectronFromB = 5              
+               };                                // MC: Origin 
+               enum {kNotSplitted=0, kSplittedOs=1, kSplittedSs=2}; // MC: splitted 
                
-               void CalculateMotherVariable(AliESDtrack* const track, AliESDtrack* const trackpart, Double_t *results);
+               Bool_t CalculateMotherVariable(AliESDtrack* const track, AliESDtrack* const trackpart, Double_t *results);
                void CalculateMotherVariableR(AliESDtrack* const track, AliESDtrack* const trackpart, Double_t *results);
                Int_t IsMotherGamma(Int_t tr);
                Int_t IsMotherPi0(Int_t tr);
@@ -94,33 +124,62 @@ class AliHFEelecbackground : public TObject {
                Int_t IsMotherB(Int_t tr);
                Int_t GetPdg(Int_t tr);
                Int_t GetLabMother(Int_t tr);
-
-
-                AliESDEvent* fESD1;              // ESD pointer             
-                AliAODEvent* fAOD1;              // AOD pointer             
-                AliMCEvent*  fMCEvent;           // MC event             
+               
+         static Double_t BetheBlochElectronITS(const Double_t *x, const Double_t * /*par*/);
+               static Double_t BetheBlochMuonITS(const Double_t *x, const Double_t * /*par*/);
+               static Double_t BetheBlochPionITS(const Double_t *x, const Double_t * /*par*/);
+               static Double_t BetheBlochKaonITS(const Double_t *x, const Double_t * /*par*/);
+               static Double_t BetheBlochProtonITS(const Double_t *x, const Double_t * /*par*/); 
+
+               static Double_t BetheBlochElectronTPC(const Double_t *x, const Double_t * /*par*/);
+               static Double_t BetheBlochMuonTPC(const Double_t *x, const Double_t * /*par*/);
+               static Double_t BetheBlochPionTPC(const Double_t *x, const Double_t * /*par*/);
+               static Double_t BetheBlochKaonTPC(const Double_t *x, const Double_t * /*par*/);
+               static Double_t BetheBlochProtonTPC(const Double_t *x, const Double_t * /*par*/); 
+
+    AliESDEvent* fESD1;              //! ESD pointer             
+    AliAODEvent* fAOD1;              //! AOD pointer             
+    AliMCEvent*  fMCEvent;           //! MC event             
                Double_t fBz;                    // Magnetic field 
-               const AliESDVertex *fkVertex;     // Primary vertex
-               static const Double_t    fgkMe;  //  Mass of the electron
+               const AliESDVertex *fkVertex;    //! Primary vertex
+               static const Double_t fgkMe;     //!  Mass of the electron
                
-               Double_t fPtESD;                 // pt of tagged electron
-               Int_t fIndexTrack;               // index track
-               Int_t fPdg;                      // pdg code track 
-               Int_t fLabMother;                // label first mother track 
-               Int_t fIsFrom;                   // is track from
-               Int_t fMotherGamma;              // Gamma, mother of track
-               Int_t fMotherPi0;                // Pi0, mother of track
-               Int_t fMotherC;                  // C, mother of track
-               Int_t fMotherB;                  // B, mother of track
-               Int_t fMotherEta;                // eta, mother of track
-               Bool_t fIsPartner;               // Are partners
-               Bool_t fIsSplittedTrack;         // Are splitted track
+               Double_t fPtESD;                 //! pt of tagged electron
+               Int_t fIndexTrack;               //! index track
+               Int_t fPdg;                      //! pdg code track 
+               Int_t fLabMother;                //! label first mother track 
+               Int_t fIsFrom;                   //! is track from
+               Int_t fMotherGamma;              //! Gamma, mother of track
+               Int_t fMotherPi0;                //! Pi0, mother of track
+               Int_t fMotherC;                  //! C, mother of track
+               Int_t fMotherB;                  //! B, mother of track
+               Int_t fMotherEta;                //! eta, mother of track
+               Bool_t fIsPartner;               //! Are partners
+               Bool_t fIsSplittedTrack;         //! Are splitted track
    
+               Double_t fOpeningAngleCut;       //! Opening angle cut
+               Double_t fInvMassCut;            //! Inv mass cut
+               Double_t fChi2NdfCut;            //! chi2ndf cut for KF code
+
+               Bool_t   fUseAliKFCode;          //! Use AliKF code to calculate the pair properties
+
+               Bool_t  fSharedClusterCut;       //! Shared Cluster Cut
+               Short_t fRequireITSStandalone;   //! ITS standalone: 1 and 2 (pureITSStandalone)
+               Int_t  fMinNbCls;                //! Min Nb of clusters ITS or TPC
+               Double_t fMinITSChi2;            //! ITS chi2 min
+               Int_t  fMinNbClsSDDSPD;          //! Min Nb of clusters ITS SDD&SPD
+               Bool_t fPIDPartner;              //! PID partner
+               AliHFEpid *fPIDMethodPartner;    //! PID cuts
+               AliESDpid *fPIDMethodPartnerITS; //! PID cuts ITS
+
+               Short_t fDebugLevel;             //! Debug Level
+
+               Bool_t   fCuts[10];               //! Cut passed already
                
-                TList *fList;                    // list for outputs
-               TList *fListPostProcess;         // list for postprocess
+    TList *fList;                    //! list for outputs
+               TList *fListPostProcess;         //! list for postprocess
 
-               static Bool_t  fgUseMCPID;    // flag to use MC PID for tagged electron
+               static Bool_t  fgUseMCPID;       // flag to use MC PID for tagged electron
     
     ClassDef(AliHFEelecbackground,0);
 };
index 54f522a..aa3a6ad 100644 (file)
@@ -30,6 +30,7 @@
 #include <TMath.h>
 
 #include "AliESDtrack.h"
+#include "AliLog.h"
 #include "AliMCParticle.h"
 
 #include "AliHFEextraCuts.h"
@@ -44,8 +45,8 @@ AliHFEextraCuts::AliHFEextraCuts(const Char_t *name, const Char_t *title):
   fClusterRatioTPC(0.),
   fMinTrackletsTRD(0),
   fPixelITS(0),
-  fCheck(kTRUE),
-  fQAlist(0x0),
+  fCheck(kFALSE),
+  fQAlist(0x0) ,
   fDebugLevel(0)
 {
   //
@@ -64,7 +65,7 @@ AliHFEextraCuts::AliHFEextraCuts(const AliHFEextraCuts &c):
   fPixelITS(c.fPixelITS),
   fCheck(c.fCheck),
   fQAlist(0x0),
-  fDebugLevel(c.fDebugLevel)
+  fDebugLevel(0)
 {
   //
   // Copy constructor
@@ -92,7 +93,6 @@ AliHFEextraCuts &AliHFEextraCuts::operator=(const AliHFEextraCuts &c){
     fPixelITS = c.fPixelITS;
     fCheck = c.fCheck;
     fDebugLevel = c.fDebugLevel;
-
     memcpy(fImpactParamCut, c.fImpactParamCut, sizeof(Float_t) * 4);
     if(IsQAOn()){
       fIsQAOn = kTRUE;
@@ -133,6 +133,7 @@ Bool_t AliHFEextraCuts::CheckESDCuts(AliESDtrack *track){
   // QA histograms are filled before track selection and for
   // selected tracks after track selection
   //
+  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);
   // Apply cuts
@@ -147,6 +148,8 @@ Bool_t AliHFEextraCuts::CheckESDCuts(AliESDtrack *track){
   Float_t xloc, zloc;
   track->GetITSModuleIndexInfo(0, det, status1, xloc, zloc);
   track->GetITSModuleIndexInfo(1, det, status2, xloc, zloc);
+  Bool_t statusL0 = CheckITSstatus(status1);
+  Bool_t statusL1 = CheckITSstatus(status2);
   if(TESTBIT(fRequirements, kMinImpactParamR)){
     // cut on min. Impact Parameter in Radial direction
     if(TMath::Abs(impactR) >= fImpactParamCut[0]) SETBIT(survivedCut, kMinImpactParamR);
@@ -169,83 +172,51 @@ Bool_t AliHFEextraCuts::CheckESDCuts(AliESDtrack *track){
   }
   if(TESTBIT(fRequirements, kMinTrackletsTRD)){
     // cut on minimum number of TRD tracklets
-    if(fDebugLevel > 0){
-      printf("Min TRD cut: [%d|%d]\n", fMinTrackletsTRD, trdTracklets);
-    }
+    AliDebug(1, Form("Min TRD cut: [%d|%d]\n", fMinTrackletsTRD, trdTracklets));
     if(trdTracklets >= fMinTrackletsTRD) SETBIT(survivedCut, kMinTrackletsTRD);
   }
   if(TESTBIT(fRequirements, kPixelITS)){
     // cut on ITS pixel layers
-    if(fDebugLevel > 0){
-      printf("ITS cluster Map: ");
-      PrintBitMap(itsPixel);
-    }
+    AliDebug(1, "ITS cluster Map: ");
+    //PrintBitMap(itsPixel);
     switch(fPixelITS){
-      case kFirst: 
-       if(!TESTBIT(itsPixel, 0)) {
-         if(fCheck){
-           if(!CheckITSstatus(status1)) {
-             SETBIT(survivedCut, kPixelITS);
-           }
-         }
-       }
-       else {
-         SETBIT(survivedCut, kPixelITS);
-       }
+      case kFirst:
+        AliDebug(2, "First");
+             if(TESTBIT(itsPixel, 0)) 
+               SETBIT(survivedCut, kPixelITS);
+        else
+               if(fCheck && !statusL0)
+                 SETBIT(survivedCut, kPixelITS);
                    break;
       case kSecond: 
-       if(!TESTBIT(itsPixel, 1)) {
-         if(fCheck) {
-           if(!CheckITSstatus(status2)) {
-             SETBIT(survivedCut, kPixelITS);
-           }
-         }
-       }
-       else { 
-         SETBIT(survivedCut, kPixelITS);
-       }
+        AliDebug(2, "Second");
+             if(TESTBIT(itsPixel, 1))
+               SETBIT(survivedCut, kPixelITS);
+        else
+               if(fCheck && !statusL1)
+                 SETBIT(survivedCut, kPixelITS);
                    break;
       case kBoth: 
-       if(!(TESTBIT(track->GetITSClusterMap(),0))) {
-         if(fCheck) {  
-           if(!CheckITSstatus(status1)) {
-             if(!(TESTBIT(track->GetITSClusterMap(),1))) {
-               if(!CheckITSstatus(status2)) {
-                 SETBIT(survivedCut, kPixelITS);
-               }
-             }
-             else SETBIT(survivedCut, kPixelITS);
-           }
-         }
-       }
-       else {
-         
-         if(!(TESTBIT(track->GetITSClusterMap(),1))) {
-           if(fCheck) {
-