Update of the HFE package
authorsma <sma@f7af4fe6-9843-0410-8265-dc069ae4e863>
Fri, 20 Aug 2010 09:46:39 +0000 (09:46 +0000)
committersma <sma@f7af4fe6-9843-0410-8265-dc069ae4e863>
Fri, 20 Aug 2010 09:46:39 +0000 (09:46 +0000)
51 files changed:
PWG3/PWG3hfeLinkDef.h
PWG3/hfe/AliAnalysisTaskDCA.cxx
PWG3/hfe/AliAnalysisTaskDCA.h
PWG3/hfe/AliAnalysisTaskDisplacedElectrons.cxx
PWG3/hfe/AliAnalysisTaskDisplacedElectrons.h
PWG3/hfe/AliAnalysisTaskHFE.cxx
PWG3/hfe/AliAnalysisTaskHFE.h
PWG3/hfe/AliAnalysisTaskHFEpidQA.cxx
PWG3/hfe/AliAnalysisTaskHFEpidQA.h
PWG3/hfe/AliHFEV0pid.cxx
PWG3/hfe/AliHFEV0pid.h
PWG3/hfe/AliHFEV0pidMC.cxx
PWG3/hfe/AliHFEV0pidMC.h
PWG3/hfe/AliHFEcollection.cxx
PWG3/hfe/AliHFEcollection.h
PWG3/hfe/AliHFEcuts.cxx
PWG3/hfe/AliHFEcuts.h
PWG3/hfe/AliHFEdca.cxx
PWG3/hfe/AliHFEdca.h
PWG3/hfe/AliHFEdisplacedElectrons.cxx
PWG3/hfe/AliHFEdisplacedElectrons.h
PWG3/hfe/AliHFEefficiency.cxx
PWG3/hfe/AliHFEefficiency.h
PWG3/hfe/AliHFEelecbackground.cxx
PWG3/hfe/AliHFEmcQA.cxx
PWG3/hfe/AliHFEmcQA.h
PWG3/hfe/AliHFEpairs.cxx
PWG3/hfe/AliHFEpairs.h
PWG3/hfe/AliHFEpid.cxx
PWG3/hfe/AliHFEpid.h
PWG3/hfe/AliHFEpidBase.cxx
PWG3/hfe/AliHFEpidBase.h
PWG3/hfe/AliHFEpidQA.cxx
PWG3/hfe/AliHFEpidQA.h
PWG3/hfe/AliHFEpidTOF.cxx
PWG3/hfe/AliHFEpidTOF.h
PWG3/hfe/AliHFEpidTPC.cxx
PWG3/hfe/AliHFEpidTPC.h
PWG3/hfe/AliHFEpidTRD.cxx
PWG3/hfe/AliHFEpidTRD.h
PWG3/hfe/AliHFEpostAnalysis.cxx
PWG3/hfe/AliHFEpriVtx.cxx
PWG3/hfe/AliHFEpriVtx.h
PWG3/hfe/AliHFEsecVtx.cxx
PWG3/hfe/AliHFEsecVtx.h
PWG3/hfe/AliHFEsecVtxs.cxx
PWG3/hfe/AliHFEsecVtxs.h
PWG3/hfe/AliHFEtools.cxx
PWG3/hfe/AliHFEtools.h
PWG3/hfe/AliHFEtrackFilter.cxx
PWG3/libPWG3hfe.pkg

index 6798bc8..efeba66 100644 (file)
 #pragma link C++ class  AliHFEsecVtx+;
 #pragma link C++ class  AliHFEpriVtx+;
 #pragma link C++ class  AliHFEelecbackground+;
+#pragma link C++ class  AliHFEspectrum+;
 
+#pragma link C++ class  AliHFEV0info+;
 #pragma link C++ class  AliHFEV0pid+;
+#pragma link C++ class  AliHFEV0cuts+;
 #pragma link C++ class  AliHFEV0pidMC+;
 #pragma link C++ class  AliHFEpidQA+;
+#pragma link C++ class  AliHFEtrdPIDqa+;
 #pragma link C++ class  AliHFEpid+;
 #pragma link C++ class  AliHFEpidBase+;
 #pragma link C++ class  AliHFEpidITS+;
index e3cf8f2..a61a340 100644 (file)
 
 #include <TCanvas.h>
 
+#include "AliAnalysisManager.h"
+
 #include "AliCFManager.h"
-#include "AliMCEvent.h"
+
 #include "AliESDInputHandler.h"
 #include "AliESDtrack.h"
-#include "AliAnalysisManager.h"
+#include "AliVertexerTracks.h"
+#include "AliESDVertex.h"
+
 #include "AliMCEventHandler.h"
+#include "AliMCEvent.h"
 #include "AliMCParticle.h"
 
+#include "AliESDpid.h"
+#include "AliHFEpid.h"
 #include "AliHFEcuts.h"
 #include "AliHFEdca.h"
 
 
 //____________________________________________________________
 AliAnalysisTaskDCA::AliAnalysisTaskDCA():
-  AliAnalysisTask("Impact Parameter Resolution and Pull Analysis", "")
+  AliAnalysisTaskSE("Impact Parameter Resolution and Pull Analysis")
   , fPlugins(0)
-  , fESD(0x0)
-  , fMC(0x0)
   , fCuts(0x0)
+  , fDefaultPID(0x0)
+  , fHFEpid(0x0)
+  , fPIDdetectors("")
+  , fPIDstrategy(0)
   , fCFM(0x0)
   , fDCA(0x0)
-  , fPixelStatus(0x0)
   , fNclustersITS(0x0)
+  , fMinNprimVtxContrbutor(0x0)
   , fNEvents(0x0)
   , fResidualList(0x0)
   , fPullList(0x0)
+  , fDcaList(0x0)
+  , fKfDcaList(0x0)
+  , fMcVertexList(0x0)
+  , fDataDcaList(0x0)
+  , fDataVertexList(0x0)
+  , fDataPullList(0x0)
+  , fMcPidList(0x0) 
+  , fDataPidList(0x0)
+  , fHfeDcaList(0x0)
+  , fHfeDataDcaList(0x0)
   , fOutput(0x0)
 {
   //
   // Dummy constructor
   //
   DefineInput(0, TChain::Class());
-  DefineOutput(0, TH1I::Class());   // event
-  DefineOutput(1, TList::Class());  // output
+  DefineOutput(1, TH1I::Class());
+  DefineOutput(2, TList::Class());
 
-  SetHasMCData();
+  fDefaultPID = new AliESDpid;
+  fHFEpid = new AliHFEpid;
 
 }
 
 //____________________________________________________________
 AliAnalysisTaskDCA::AliAnalysisTaskDCA(const char * name):
-  AliAnalysisTask(name, "")
+  AliAnalysisTaskSE(name)
   , fPlugins(0)
-  , fESD(0x0)
-  , fMC(0x0)
   , fCuts(0x0)
+  , fDefaultPID(0x0)
+  , fHFEpid(0x0)
+  , fPIDdetectors("")
+  , fPIDstrategy(0)
   , fCFM(0x0)
   , fDCA(0x0)
-  , fPixelStatus(0x0)
   , fNclustersITS(0x0)
+  , fMinNprimVtxContrbutor(0x0)
   , fNEvents(0x0)
   , fResidualList(0x0)
   , fPullList(0x0)
+  , fDcaList(0x0) 
+  , fKfDcaList(0x0)
+  , fMcVertexList(0x0)
+  , fDataDcaList(0x0)
+  , fDataVertexList(0x0)
+  , fDataPullList(0x0)
+  , fMcPidList(0x0)
+  , fDataPidList(0x0)
+  , fHfeDcaList(0x0)
+  , fHfeDataDcaList(0x0)
   , fOutput(0x0)
 {
   //
   // Default constructor
   //
   DefineInput(0, TChain::Class());
-  DefineOutput(0, TH1I::Class());
-  DefineOutput(1, TList::Class());
+  DefineOutput(1, TH1I::Class());
+  DefineOutput(2, TList::Class());
+  
+  fDefaultPID = new AliESDpid;
+  fHFEpid = new AliHFEpid;
 
-  SetHasMCData();
 }
 
 //____________________________________________________________
 AliAnalysisTaskDCA::AliAnalysisTaskDCA(const AliAnalysisTaskDCA &ref):
-  AliAnalysisTask(ref)
+  AliAnalysisTaskSE(ref)
   , fPlugins(ref.fPlugins)
-  , fESD(ref.fESD)
-  , fMC(ref.fMC)
-  , fCuts(ref.fCuts)
+  , fCuts(ref.fCuts)  
+  , fDefaultPID(ref.fDefaultPID)
+  , fHFEpid(ref.fHFEpid)
+  , fPIDdetectors(ref.fPIDdetectors)
+  , fPIDstrategy(ref.fPIDstrategy)
   , fCFM(ref.fCFM)
   , fDCA(ref.fDCA)
-  , fPixelStatus(ref.fPixelStatus)
   , fNclustersITS(ref.fNclustersITS)
+  , fMinNprimVtxContrbutor(ref.fMinNprimVtxContrbutor)
   , fNEvents(ref.fNEvents)
   , fResidualList(ref.fResidualList)
   , fPullList(ref.fPullList)
+  , fDcaList(ref.fDcaList)
+  , fKfDcaList(ref.fKfDcaList)
+  , fMcVertexList(ref.fMcVertexList)
+  , fDataDcaList(ref.fDataDcaList)
+  , fDataVertexList(ref.fDataVertexList)
+  , fDataPullList(ref.fDataPullList)
+  , fMcPidList(ref.fMcPidList)
+  , fDataPidList(ref.fDataPidList)
+  , fHfeDcaList(ref.fHfeDcaList)
+  , fHfeDataDcaList(ref.fHfeDataDcaList)
   , fOutput(ref.fOutput)
 {
   //
   // Copy Constructor
   //
+
+  ref.Copy(*this);
 }
 
 //____________________________________________________________
@@ -128,19 +176,31 @@ AliAnalysisTaskDCA &AliAnalysisTaskDCA::operator=(const AliAnalysisTaskDCA &ref)
   // Assignment operator
   //
   if(this == &ref) return *this;
-  AliAnalysisTask::operator=(ref);
+  AliAnalysisTaskSE::operator=(ref);
   fPlugins = ref.fPlugins;
-  fESD = ref.fESD;
-  fMC = ref.fMC;
   fCuts = ref.fCuts;
+  fDefaultPID = ref.fDefaultPID;
+  fHFEpid = ref.fHFEpid;
+  fPIDdetectors = ref.fPIDdetectors;
+  fPIDstrategy = ref.fPIDstrategy;
   fCFM = ref.fCFM;
   fDCA = ref.fDCA;
-  fPixelStatus = ref.fPixelStatus;
   fNclustersITS = ref.fNclustersITS;
+  fMinNprimVtxContrbutor = ref.fMinNprimVtxContrbutor;
   fNEvents = ref.fNEvents;
-  fOutput = ref.fOutput;
   fResidualList = ref.fResidualList;
   fPullList = ref.fPullList;
+  fDcaList = ref.fDcaList;
+  fKfDcaList = ref.fKfDcaList;
+  fMcVertexList = ref.fMcVertexList;
+  fDataDcaList = ref.fDataDcaList;
+  fDataVertexList = ref.fDataVertexList;
+  fDataPullList = ref.fDataPullList;
+  fMcPidList = ref.fMcPidList;
+  fDataPidList = ref.fDataPidList;
+  fHfeDcaList = ref.fHfeDcaList;    
+  fHfeDataDcaList = ref.fHfeDataDcaList;
+  fOutput = ref.fOutput;
 
   return *this;
 }
@@ -151,18 +211,11 @@ AliAnalysisTaskDCA::~AliAnalysisTaskDCA(){
   // Destructor
   //
 
-  if(fESD) delete fESD;
-  if(fMC) delete fMC;
-
+  if(fDefaultPID) delete fDefaultPID;
+  if(fHFEpid) delete fHFEpid;
   if(fCFM) delete fCFM;
-
   if(fDCA) delete fDCA;  
-
-  if(fOutput){ 
-    fOutput->Clear();
-    delete fOutput;
-  }
-  
+  if(fNEvents) delete fNEvents;
   if(fResidualList){ 
     fResidualList->Clear();
     delete fResidualList;
@@ -173,37 +226,79 @@ AliAnalysisTaskDCA::~AliAnalysisTaskDCA(){
     delete fPullList;
   }
   
-  if(fNEvents) delete fNEvents;
-}
+  if(fDcaList){ 
+    fDcaList->Clear();
+    delete fDcaList;
+  }
+  if(fKfDcaList){ 
+    fKfDcaList->Clear();
+    delete fKfDcaList;
+  }
 
-//____________________________________________________________
-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();
+  if(fMcVertexList){
+    fMcVertexList->Clear();
+    delete   fMcVertexList;
   }
-  AliMCEventHandler *mcH = dynamic_cast<AliMCEventHandler *>(AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler());
-  if(!mcH){       
-    AliError("No MC truth handler");
-    return;
-  } else {
-    fMC = mcH->MCEvent();
+
+  if(fDataDcaList){ 
+    fDataDcaList->Clear();
+    delete fDataDcaList;
+  }
+
+  if(fDataVertexList){
+    fDataVertexList->Clear();
+    delete   fDataVertexList;
+  }
+  if(fDataPullList){ 
+    fDataPullList->Clear();
+    delete fDataPullList;
+  }
+
+  if(fMcPidList){
+    fMcPidList -> Clear();
+    delete fMcPidList;
+  }
+  if(fDataPidList){
+    fDataPidList -> Clear();
+    delete fDataPidList;
+  }
+
+  if(fHfeDcaList) {
+    fHfeDcaList->Clear();
+    delete fHfeDcaList;
+  } 
+  
+  if(fHfeDataDcaList) {
+    fHfeDataDcaList->Clear();
+    delete fHfeDataDcaList;
+  } 
+  
+  if(fOutput){ 
+    fOutput->Clear();
+    delete fOutput;
   }
+  
 }
 
 //____________________________________________________________
-void AliAnalysisTaskDCA::CreateOutputObjects(){
+void AliAnalysisTaskDCA::UserCreateOutputObjects(){
   // create output objects
   // fNEvents
   // residual and pull
+  
+  // Automatic determination of the analysis mode
+  AliVEventHandler *inputHandler = dynamic_cast<AliVEventHandler *>(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler());
+    
+  if(!TString(inputHandler->IsA()->GetName()).CompareTo("AliAODInputHandler")){
+    SetAODAnalysis();
+  } else {
+    SetESDAnalysis();
+    if(AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler())
+      SetHasMCData();
+  }
+  
 
-  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
+  fNEvents = new TH1I("nEvents", "Number of Events in the Analysis", 5, -0.5, 4.5); // 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;
@@ -217,56 +312,174 @@ void AliAnalysisTaskDCA::CreateOutputObjects(){
     fCuts->CreateStandardCuts();
   }
   
-  fCuts->SetCutITSpixel(fPixelStatus);
   fCuts->Initialize(fCFM);
   
+  if(!fHFEpid) printf("hallo, fHFEpid is not available\n");
+  
+  if(fHFEpid && GetPlugin(kHFEpid)) {      
+    fHFEpid->SetHasMCData(HasMCData());
+    if(!fPIDdetectors.Length() && ! fPIDstrategy) AddPIDdetector("TPC");
+    if(fPIDstrategy)
+      fHFEpid->InitializePID(Form("Strategy%d", fPIDstrategy));
+    else
+      fHFEpid->InitializePID(fPIDdetectors.Data());     // Only restrictions to TPC allowed 
+  }
 
   // dca study----------------------------------
+
+  
   if(!fDCA) fDCA = new AliHFEdca;
   if(!fResidualList) fResidualList = new TList();
   if(!fPullList) fPullList = new TList();
-
-  fDCA->CreateHistogramsResidual(fResidualList);
-  fDCA->CreateHistogramsPull(fPullList);
+  if(!fDcaList) fDcaList = new TList();
+  if(!fKfDcaList) fKfDcaList = new TList();
+  if(!fMcVertexList) fMcVertexList = new TList();
+  if(!fDataDcaList) fDataDcaList = new TList();
+  if(!fDataVertexList) fDataVertexList = new TList();
+  if(!fDataPullList) fDataPullList = new TList();
+  if(!fMcPidList) fMcPidList = new TList();
+  if(!fDataPidList) fDataPidList = new TList();  
   
-  // add output objects to the List
-  fOutput->AddAt(fResidualList,0);
-  fOutput->AddAt(fPullList,1);
+  if(!fHfeDcaList) fHfeDcaList = new TList();
+  if(!fHfeDataDcaList) fHfeDataDcaList = new TList();
+
+  if(HasMCData()) {    
+    if(GetPlugin(kImpactPar) ) {
+      fDCA->CreateHistogramsResidual(fResidualList);
+      fDCA->CreateHistogramsPull(fPullList);
+      fDCA->CreateHistogramsDca(fDcaList);
+      fOutput->AddAt(fResidualList,0);
+      fOutput->AddAt(fPullList,1);
+      fOutput->AddAt(fDcaList,2);
+    } 
+    if(GetPlugin(kKFdca)){
+      fDCA->CreateHistogramsKfDca(fKfDcaList);
+      fOutput->AddAt(fDcaList,3);
+    }
+    if(GetPlugin(kPrimVtx)){
+      fDCA->CreateHistogramsVertex(fMcVertexList);
+      fOutput->AddAt(fMcVertexList,4);
+    }
+    if(GetPlugin(kCombinedPid)){
+      fDCA->CreateHistogramsPid(fMcPidList);
+      fOutput->AddAt(fMcPidList, 5);
+    }
+    if(GetPlugin(kHFEpid)){
+      fDCA->CreateHistogramsHfeDca(fHfeDcaList);
+      fOutput->AddAt(fHfeDcaList, 6);
+    }
+  } // mc case
+
+  if(!HasMCData())  { 
+    
+    if(GetPlugin(kPrimVtx)){
+      fDCA->CreateHistogramsDataVertex(fDataVertexList);  
+      fOutput->AddAt(fDataVertexList,0);
+    }    
+
+    if(GetPlugin(kCombinedPid)){
+      fDCA->CreateHistogramsDataDca(fDataDcaList);  
+      fDCA->CreateHistogramsDataPull(fDataPullList);  
+      fDCA->CreateHistogramsDataPid(fDataPidList);
+      fOutput->AddAt(fDataDcaList,1);
+      fOutput->AddAt(fDataPullList,2);
+      fOutput->AddAt(fDataPidList, 3);
+    }
+    if(GetPlugin(kHFEpid)){
+      fDCA->CreateHistogramsHfeDataDca(fHfeDataDcaList);
+      fOutput->AddAt(fHfeDataDcaList, 4);
+    }
+    
 
+
+  }  // data case
+  
 }
 
 //____________________________________________________________
-void AliAnalysisTaskDCA::Exec(Option_t *){
+void AliAnalysisTaskDCA::UserExec(Option_t *){
   //
   // Run the analysis
   // 
 
   AliDebug(3, "Processing ESD events");
 
-  if(!fESD){
-    AliError("No ESD Event");
+  if(!fInputEvent){
+    AliError("Reconstructed Event not available");
     return;
   }
-  if(!fMC){
-    AliError("No MC Event");
-    return;
+  if(HasMCData()){
+    AliDebug(4, Form("MC Event: %p", fMCEvent));
+    if(!fMCEvent){
+      AliError("No MC Event, but MC Data required");
+      return;
+    }
   }
+
   if(!fCuts){
     AliError("HFE cuts not available");
     return;
   }
+
+  // protection
+  if(IsESDanalysis() && HasMCData()){
+    // Protect against missing MC trees
+    AliMCEventHandler *mcH = dynamic_cast<AliMCEventHandler *>(AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler());
+    if(!mcH->InitOk()) return;
+    if(!mcH->TreeK()) return;
+    if(!mcH->TreeTR()) return;
+  }
+
+  if(!IsAODanalysis()) {
+    AliESDInputHandler *inH = dynamic_cast<AliESDInputHandler *>(fInputHandler);
+    AliESDpid *workingPID = inH->GetESDpid();
+    if(workingPID){
+      AliDebug(1, "Using ESD PID from the input handler");
+      fHFEpid->SetESDpid(workingPID);
+    } else {
+      AliDebug(1, "Using default ESD PID");
+      fHFEpid->SetESDpid(fDefaultPID);
+    }
+    ProcessDcaAnalysis();
+  }
+
+  
+  PostData(1, fNEvents);
+  PostData(2, fOutput);
+}
+//____________________________________________________________
+void AliAnalysisTaskDCA::ProcessDcaAnalysis(){
 
   //
   // Loop ESD
   //
+  
+  AliMCEvent *fMC = 0x0;
+  AliESDEvent *fESD = dynamic_cast<AliESDEvent *>(fInputEvent);
+  if(HasMCData())fMC = dynamic_cast<AliMCEvent*>(fMCEvent);
+
+  if(!fESD){
+    AliError("ESD Event required for ESD Analysis")
+      return;
+  }
+
+  fNEvents->Fill(1);  // original event number before cut
+  fDCA->ApplyExtraCuts(fESD,fMinNprimVtxContrbutor);  // cut on primVtx contributors
+  fNEvents->Fill(3);  // events number after cut
+
   AliESDtrack *track = 0x0;  
+  AliMCParticle *mctrack = 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);
+    if(HasMCData())mctrack = dynamic_cast<AliMCParticle *>(fMC->GetTrack(TMath::Abs(track->GetLabel())));
 
     // RecPrim: primary cuts
     if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepRecPrim, track)) continue;
@@ -275,20 +488,61 @@ void AliAnalysisTaskDCA::Exec(Option_t *){
     // 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);
-    }   
+    if(track->GetITSclusters(0)<=fNclustersITS) continue;  // require number of ITS clusters
     
-  }  
-  fNEvents->Fill(1);
-  
-  PostData(0, fNEvents);
-  PostData(1, fOutput);
+    // track accepted, do PID
+    AliHFEpidObject hfetrack;
+    hfetrack.fAnalysisType = AliHFEpidObject::kESDanalysis;
+    hfetrack.fRecTrack = track;
+    if(HasMCData()) hfetrack.fMCtrack = mctrack;
+
+    if(HasMCData()){
+      if(GetPlugin(kPrimVtx))
+       fDCA->FillHistogramsVtx(fESD, fMC);
+      if(GetPlugin(kImpactPar)) 
+       fDCA->FillHistogramsDca(fESD, track, fMC);
+      if(GetPlugin(kKFdca)) 
+       fDCA->FillHistogramsKfDca(fESD, track, fMC);
+      if(GetPlugin(kCombinedPid)) 
+       fDCA->FillHistogramsPid(track, fMC);
+      if(GetPlugin(kHFEpid)) {
+       if(fHFEpid->IsSelected(&hfetrack)) 
+         fDCA->FillHistogramsHfeDca(fESD, track, fMC);
+      } // plugin for hfepid 
+    }  // MC
+
+    if(!HasMCData()){
+      if(GetPlugin(kPrimVtx))
+       fDCA->FillHistogramsDataVtx(fESD);
+      if(GetPlugin(kCombinedPid)) {
+
+       // method from Andrea D 28.05.2010
+       AliVertexerTracks *vertexer = new AliVertexerTracks(fESD->GetMagneticField());
+       vertexer->SetITSMode();
+       vertexer->SetMinClusters(fNclustersITS);
+       Int_t skipped[2];
+       skipped[0] = (Int_t)track->GetID();
+       vertexer->SetSkipTracks(1,skipped);
+       AliESDVertex *vtxESDSkip = (AliESDVertex*)vertexer->FindPrimaryVertex(fESD);
+       delete vertexer; vertexer = NULL;
+       if(vtxESDSkip->GetNContributors()<fMinNprimVtxContrbutor) continue;
+
+       fDCA->FillHistogramsDataDca(fESD, track, vtxESDSkip);
+       fDCA->FillHistogramsDataPid(track);
+      }
+      if(GetPlugin(kHFEpid)) {
+       if(fHFEpid->IsSelected(&hfetrack)) {
+         //      printf("Found an electron in p+p collision! from HFE pid \n");
+         fDCA->FillHistogramsHfeDataDca(fESD, track);    
+       } 
+      } // plugin for hfepid
+    }  // data case
+
+  } // track loop
+
 }
 
+
 //____________________________________________________________
 void AliAnalysisTaskDCA::Terminate(Option_t *){
   //
@@ -316,13 +570,6 @@ void AliAnalysisTaskDCA::Load(TString filename){
     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;
   
@@ -335,7 +582,7 @@ void AliAnalysisTaskDCA::PostProcess(){
   // should do fitting here for dca resolution
   // moved to an external macro to do the job
   
-  Load("impactPar.root");
+  Load("HFEdca.root");
   TCanvas *c1 = new TCanvas("c1", "number of analyzed events", 300, 400);
   fNEvents->Draw();
   c1->SaveAs("temp.png");
@@ -352,8 +599,14 @@ 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 Running on %s\n", !HasMCData()?"p+p collision data":"MC sample");
+  printf("\t Cuts: %s\n", (fCuts != NULL) ? "YES" : "NO");
+  printf("\t Impact parameter analysis is %s\n", GetPlugin(kImpactPar)?"ON":"OFF");
+  printf("\t Using AliKFParticle for analysis? %s\n", GetPlugin(kKFdca)?"ON":"OFF");
+  printf("\t Primary vertex analysis is %s\n", GetPlugin(kPrimVtx)?"ON":"OFF");
+  printf("\t Combined pid analysis is %s\n", GetPlugin(kCombinedPid)?"ON":"OFF");
+  printf("\t HFE pid analysis is %s\n", GetPlugin(kHFEpid)?"ON":"OFF");
+  printf("\t Post process analysis is %s\n", GetPlugin(kPostProcess)?"ON":"OFF");
   printf("\t ");
   printf("\n");
 }
@@ -367,10 +620,22 @@ void AliAnalysisTaskDCA::SwitchOnPlugin(Int_t plug){
   //  - Post Processing                                                                      
   
   switch(plug){
+  case kPostProcess: 
+    SETBIT(fPlugins, plug); 
+    break;
   case kImpactPar: 
     SETBIT(fPlugins, plug); 
     break;
-  case kPostProcess: 
+  case kPrimVtx: 
+    SETBIT(fPlugins, plug); 
+    break;
+  case kCombinedPid:
+    SETBIT(fPlugins, plug); 
+    break;
+  case kHFEpid:
+    SETBIT(fPlugins, plug); 
+    break;
+  case kKFdca:
     SETBIT(fPlugins, plug); 
     break;
   default: 
@@ -423,7 +688,18 @@ void AliAnalysisTaskDCA::MakeParticleContainer(){
   }
 
 
-  // add more containers for correction purpose
-
+}
 
+//____________________________________________________________
+void AliAnalysisTaskDCA::AddPIDdetector(TString detector){
+  
+  //
+  // Adding PID detector to the task
+  //
+  
+  if(!fPIDdetectors.Length()) 
+    fPIDdetectors = detector;
+  else
+    fPIDdetectors += ":" + detector;
 }
+
index e6c2b0a..5c746b0 100644 (file)
 
 #ifndef ALIANALYSISTASKDCA_H
 #define ALIANALYSISTASKDCA_H
-
-#ifndef ALIANALYSISTASK_H
-#include "AliAnalysisTask.h"
+#ifndef ALIANALYSISTASKSE_H
+#include "AliAnalysisTaskSE.h"
 #endif
 
 class TH1I; 
 class TH1F; 
 class TList;
 class AliLog;
-
 class AliCFManager;
 class AliESDEvent;
 class AliESDtrackCuts;
 class AliMCEvent;
 class AliVParticle;
 
+class AliVEvent;
+class AliVertexerTracks;
 class AliHFEpid;
 class AliHFEcuts;
 class AliHFEextraCuts;
 
-class AliAnalysisTaskDCA : public AliAnalysisTask{
+class AliAnalysisTaskDCA : public AliAnalysisTaskSE{
  public:
 
   typedef enum{
     kPostProcess = 0,
-    kImpactPar = 1
+    kImpactPar = 1,
+    kPrimVtx = 2,
+    kCombinedPid = 3,
+    kHFEpid = 4, 
+    kKFdca = 5
   }Switches_t;
 
   enum{
@@ -59,9 +63,8 @@ class AliAnalysisTaskDCA : public AliAnalysisTask{
   AliAnalysisTaskDCA& operator=(const AliAnalysisTaskDCA &ref);
   virtual ~AliAnalysisTaskDCA();
   
-  virtual void ConnectInputData(Option_t *);
-  virtual void CreateOutputObjects();
-  virtual void Exec(Option_t *);
+  virtual void UserCreateOutputObjects();
+  virtual void UserExec(Option_t *);
   virtual void Terminate(Option_t *);
 
 
@@ -70,14 +73,21 @@ class AliAnalysisTaskDCA : public AliAnalysisTask{
   void PostProcess();
   void SetHFECuts(AliHFEcuts * const cuts) { fCuts = cuts; };
 
-  void SetPixelStatus(Int_t pixelStatus){ fPixelStatus = pixelStatus;};
   void SetNclustersITS(Int_t nITSclusters){ fNclustersITS = nITSclusters;};
-  
+  void SetMinPrimVtxContrib( Int_t nPrimVtxContrib){ fMinNprimVtxContrbutor = nPrimVtxContrib; };  
+
   Bool_t GetPlugin(Int_t plug) const { return TESTBIT(fPlugins, plug); };
   void SwitchOnPlugin(Int_t plug);
+
+  Bool_t IsAODanalysis() const { return TestBit(kAODanalysis); };
+  Bool_t IsESDanalysis() const { return !TestBit(kAODanalysis); };
   Bool_t HasMCData() const { return TestBit(kHasMCdata); }
   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(TString detector);
+
   void SetAODAnalysis() { SetBit(kAODanalysis, kTRUE); };
   void SetESDAnalysis() { SetBit(kAODanalysis, kFALSE); };
 
@@ -85,24 +95,40 @@ class AliAnalysisTaskDCA : public AliAnalysisTask{
  private:
 
   void MakeParticleContainer();
-  UShort_t fPlugins;                    // Enabled Plugins                                    
-  AliESDEvent *fESD;                    //! The ESD Event
-  AliMCEvent *fMC;                      //! The MC Event
+  void ProcessDcaAnalysis();
+    
+  UShort_t fPlugins;                   // Enabled Plugins 
+  AliHFEcuts *fCuts;                   // Cut Collection
 
-  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
+  AliESDpid *fDefaultPID;               //! Default ESD PID
+  AliHFEpid *fHFEpid;                  //! PID
+  TString fPIDdetectors;               // Detectors for Particle Identification
+  UInt_t fPIDstrategy;                 // PID Strategy
+
+  AliCFManager *fCFM;                  //! Correction Framework Manager
+  AliHFEdca *fDCA;                     // fDCA 
 
-  ClassDef(AliAnalysisTaskDCA, 1);      // The DCA Analysis Task
+  Int_t fNclustersITS;                 // ITS clusters
+  Int_t fMinNprimVtxContrbutor;        // minimum number of primary contributors
+                                               
+  TH1I *fNEvents;                      //! counter for the number of Events
+  TList *fResidualList;                //! histograms for the residuals 
+  TList *fPullList;                    //! histograms for the pull
+  TList *fDcaList;                     //! histograms for the dca
+  TList *fKfDcaList;                     //! histograms for the kf dca
+  TList *fMcVertexList;                //! histograms for the MC vertex  
+  TList *fDataDcaList;                 //! histograms for the data dca
+  TList *fDataVertexList;              //! histograms for the data vertex
+  TList *fDataPullList;                //! histograms for the data pull
+  TList *fMcPidList;                   //! pid - MC: ESD combined pid
+  TList *fDataPidList;                 //! pid -Data: ESD combined pid
+
+  TList *fHfeDcaList;                  //! hfe pid: mc dca 
+  TList *fHfeDataDcaList;              //! hfe pid: data dca 
+
+  TList *fOutput;                      //! Container for Task Output
+
+  ClassDef(AliAnalysisTaskDCA, 1);     // The DCA Analysis Task
 };
 #endif
 
index 1721ab6..3132add 100644 (file)
@@ -20,6 +20,7 @@
 // 
 // Authors:
 //  Hongyan Yang <hongyan@physi.uni-heidelberg.de>
+//  Carlo Bombonati <Carlo.Bombonati@cern.ch>
 //
 
 #include <TChain.h>
 #include <TObjArray.h>
 #include <TParticle.h>
 #include <TString.h>
-
 #include <TCanvas.h>
 
 #include "AliCFManager.h"
 #include "AliMCEvent.h"
 #include "AliMCEventHandler.h"
+#include "AliMCParticle.h"
+#include "AliStack.h"
+
 #include "AliESDEvent.h"
 #include "AliESDInputHandler.h"
 #include "AliESDtrack.h"
-#include "AliAnalysisManager.h"
-#include "AliMCParticle.h"
+#include "AliESDpid.h"
 
+#include "AliAnalysisManager.h"
 
 #include "AliHFEpid.h"
 #include "AliHFEcuts.h"
+#include "AliHFEtools.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)
+  , fDeDebugLevel(0)
+  , fNminITSCluster(0)
+  , fNminPrimVtxContrib(0)
+  , fDePIDdetectors("")
+  , fDePIDstrategy(0)
+  , fDePlugins(0)
+  , fDeCuts(0x0)
+  , fDeDefaultPID(0x0)
+  , fDePID(0x0)
+  , fDeCFM(0x0)
   , fDisplacedElectrons(0x0)
+  , fDeNEvents(0x0)
+  , fElectronsMcPt(0x0)
+  , fElectronsEsdPt(0x0)
+  , fElectronsDataPt(0x0)
+  , fDeCorrection(0x0)
+  , fDeQA(0x0)
   , fHistDisplacedElectrons(0x0)
 {
   //
   // Dummy constructor
   //
   DefineInput(0, TChain::Class());
-  DefineOutput(2, TList::Class());  // output
-  DefineOutput(1, TList::Class());  // output
+  DefineOutput(1, TList::Class());  // displacedElectron
+  DefineOutput(2, TList::Class());  // correction framework
+  DefineOutput(3, TList::Class());  // QA
   
-  SetHasMCData();
-
   // Initialize pid
-  fPID = new AliHFEpid;
+  
+  fDeDefaultPID = new AliESDpid;
+  fDePID = new AliHFEpid;
   
 
 }
@@ -90,49 +97,59 @@ AliAnalysisTaskDisplacedElectrons::AliAnalysisTaskDisplacedElectrons():
 //____________________________________________________________
 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)
+  , fDeDebugLevel(0)
+  , fNminITSCluster(0)
+  , fNminPrimVtxContrib(0)
+  , fDePIDdetectors("")
+  , fDePIDstrategy(0)
+  , fDePlugins(0)
+  , fDeCuts(0x0)
+  , fDeDefaultPID(0x0)
+  , fDePID(0x0)
+  , fDeCFM(0x0)
   , fDisplacedElectrons(0x0)
+  , fDeNEvents(0x0)
+  , fElectronsMcPt(0x0)
+  , fElectronsEsdPt(0x0)
+  , fElectronsDataPt(0x0)
+  , fDeCorrection(0x0)
+  , fDeQA(0x0)
   , fHistDisplacedElectrons(0x0)
 {
   //
   // Default constructor
   //
   DefineInput(0, TChain::Class());
-  DefineOutput(2, TList::Class());
   DefineOutput(1, TList::Class());
+  DefineOutput(2, TList::Class());
+  DefineOutput(3, TList::Class());
+
+  // Initialize pid
+  fDeDefaultPID = new AliESDpid;
+  fDePID = new AliHFEpid;
 
-  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)
+  , fDeDebugLevel(ref.fDeDebugLevel)
+  , fNminITSCluster(ref.fNminITSCluster)
+  , fNminPrimVtxContrib(ref.fNminPrimVtxContrib)
+  , fDePIDdetectors(ref.fDePIDdetectors)
+  , fDePIDstrategy(ref.fDePIDstrategy)
+  , fDePlugins(ref.fDePlugins)
+  , fDeCuts(ref.fDeCuts)
+  , fDeDefaultPID(ref.fDeDefaultPID)
+  , fDePID(ref.fDePID)
+  , fDeCFM(ref.fDeCFM)
   , fDisplacedElectrons(ref.fDisplacedElectrons)
+  , fDeNEvents(ref.fDeNEvents)
+  , fElectronsMcPt(ref.fElectronsMcPt)
+  , fElectronsEsdPt(ref.fElectronsEsdPt)
+  , fElectronsDataPt(ref.fElectronsDataPt)
+  , fDeCorrection(ref.fDeCorrection)
+  , fDeQA(ref.fDeQA)
   , fHistDisplacedElectrons(ref.fHistDisplacedElectrons)
 {
   //
@@ -147,19 +164,23 @@ AliAnalysisTaskDisplacedElectrons &AliAnalysisTaskDisplacedElectrons::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;
+  fDeDebugLevel = ref.fDeDebugLevel;
+  fNminITSCluster = ref.fNminITSCluster;
+  fNminPrimVtxContrib = ref.fNminPrimVtxContrib;
+  fDePIDdetectors = ref.fDePIDdetectors;
+  fDePIDstrategy = ref.fDePIDstrategy;
+  fDePlugins = ref.fDePlugins;
+  fDeDefaultPID = ref.fDeDefaultPID;
+  fDePID = ref.fDePID;
+  fDeCuts = ref.fDeCuts;
+  fDeCFM = ref.fDeCFM;
   fDisplacedElectrons = ref.fDisplacedElectrons;
+  fDeNEvents = ref.fDeNEvents;
+  fElectronsMcPt = ref.fElectronsMcPt;
+  fElectronsEsdPt = ref.fElectronsEsdPt;
+  fElectronsDataPt = ref.fElectronsDataPt;
+  fDeCorrection = ref.fDeCorrection;
+  fDeQA = ref.fDeQA;
   fHistDisplacedElectrons = ref.fHistDisplacedElectrons;
 
   return *this;
@@ -171,101 +192,105 @@ 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(fDeDefaultPID) delete fDeDefaultPID;
+  if(fDePID) delete fDePID;
+  if(fDeCFM) delete fDeCFM;
+  if(fDisplacedElectrons) delete fDisplacedElectrons;  
+  if(fDeNEvents) delete fDeNEvents;
+  if(fElectronsMcPt) delete fElectronsMcPt;
+  if(fElectronsEsdPt) delete fElectronsEsdPt;
+  if(fElectronsDataPt) delete fElectronsDataPt;
+  if(fDeCorrection){
+    fDeCorrection->Clear();
+    delete fDeCorrection;
   }
-  
-
-  if(fCorrection){
-    fCorrection->Clear();
-    delete fCorrection;
+  if(fDeQA){
+    fDeQA->Clear();
+    delete fDeQA;
   }
-  if(fDisplacedElectrons) delete fDisplacedElectrons;  
-
   if(fHistDisplacedElectrons){ 
     fHistDisplacedElectrons->Clear();  
     delete fHistDisplacedElectrons;  
   }
-   
-  
 }
 
 //____________________________________________________________
 void AliAnalysisTaskDisplacedElectrons::UserCreateOutputObjects(){
   // create output objects
-  // fNEvents
+  // fDeNEvents
   // MC and Data containers
 
-  fNEvents = new TH1I("nEvents", "Number of Events in the Analysis", 2, 0, 2); 
+
+  if(!fDeQA) fDeQA = new TList;
+  fDeQA->SetName("variousQAhistograms");
+  
+  fDeNEvents = new TH1I("nDeEvents", "Number of Events in the DE 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);
+  fElectronsMcPt = new TH1F("mcElectronPt", "MC: p_{T} distribution of identified electrons (mcpid);p_{T} (GeV/c);Counts;", nBins-1, ptBins); 
+  fElectronsEsdPt = new TH1F("esdElectronPt", "ESD: p_{T} distribution of identified electrons (hfepid);p_{T} (GeV/c);Counts;", nBins-1, ptBins); 
+  fElectronsDataPt = new TH1F("dataElectronPt", "DATA: p_{T} distribution of identified electrons (hfepid);p_{T} (GeV/c);Counts;", nBins-1, ptBins); 
+  
+  fDeQA->AddAt(fDeNEvents,0);
+  if(HasMCData()){
+    fDeQA->AddAt(fElectronsMcPt, 1);
+    fDeQA->AddAt(fElectronsEsdPt, 2);  
+  }
+  else
+    fDeQA->AddAt(fElectronsDataPt, 1);  
+  
   // Initialize correction Framework and Cuts
-  fCFM = new AliCFManager;
+  fDeCFM = 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){
+  if(!fDeCorrection) fDeCorrection = new TList();
+  fDeCorrection->SetName("deCorrections");
+  fDeCorrection->AddAt(fDeCFM->GetEventContainer(), 0);
+  fDeCorrection->AddAt(fDeCFM->GetParticleContainer(), 1);
+  fDeCorrection->Print();
+
+  for(Int_t istep = 0; istep < fDeCFM->GetEventContainer()->GetNStep(); istep++)
+    fDeCFM->SetEventCutsList(istep, 0x0);
+  for(Int_t istep = 0; istep < fDeCFM->GetParticleContainer()->GetNStep(); istep++)
+    fDeCFM->SetParticleCutsList(istep, 0x0);
+
+  if(!fDeCuts){
     AliWarning("Cuts not available. Default cuts will be used");
-    fCuts = new AliHFEcuts;
-    fCuts->CreateStandardCuts();
-
+    fDeCuts = new AliHFEcuts;
+    fDeCuts->CreateStandardCuts();    
   }
   
-  fCuts->SetCutITSpixel(AliHFEextraCuts::kBoth);
+  fDeCuts->Initialize(fDeCFM);
   
-  fCuts->Initialize(fCFM);
-    
-  fPID->SetHasMCData(HasMCData());
-  if(!fPIDdetectors.Length() && ! fPIDstrategy) AddPIDdetector("TPC");
-  if(fPIDstrategy)
-    fPID->InitializePID(Form("Strategy%d", fPIDstrategy));
+  if(GetPlugin(kDePidQA)){
+    AliInfo("PID QA switched on");
+    // fPID->SetDebugLevel(2);
+    fDePID->SetQAOn();
+    fDeQA->Add(fDePID->GetQAhistograms());
+  }  
+
+  fDePID->SetHasMCData(HasMCData());
+  if(!fDePIDdetectors.Length() && ! fDePIDstrategy) AddPIDdetector("TPC");
+  if(fDePIDstrategy)
+    fDePID->InitializePID(Form("Strategy%d", fDePIDstrategy));
   else
-    fPID->InitializePID(fPIDdetectors.Data());     // Only restrictions to TPC allowed 
-
+    fDePID->InitializePID(fDePIDdetectors.Data());     // Only restrictions to TPC allowed 
+  
   // displaced electron study----------------------------------
   if(GetPlugin(kDisplacedElectrons)){
     
     fDisplacedElectrons = new AliHFEdisplacedElectrons;
-    fDisplacedElectrons->SetDebugLevel(fDebugLevel);
+    fDisplacedElectrons->SetDebugLevel(fDeDebugLevel);
     fDisplacedElectrons->SetHasMCData(HasMCData());
-    
+    fDisplacedElectrons->SetMinPrimVtxContrib(fNminPrimVtxContrib);
+    fDisplacedElectrons->SetNitsCluster(fNminITSCluster);
+  
     if(!fHistDisplacedElectrons) fHistDisplacedElectrons = new TList();
-    
     fDisplacedElectrons->CreateOutputs(fHistDisplacedElectrons);
-    
-    fOutput->AddAt(fHistDisplacedElectrons, 2);
   }
-
-
+  
 }
 
 
@@ -276,224 +301,368 @@ void AliAnalysisTaskDisplacedElectrons::UserExec(Option_t *){
   // Run the analysis
   // 
 
-  AliESDInputHandler *esdH = dynamic_cast<AliESDInputHandler *>(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler());
-  if(!esdH){      
-    AliError("No ESD input handler");
+  if(fDeDebugLevel>=10) AliInfo("analyse single event");
+
+  if(!fInputEvent){
+    AliError("Reconstructed Event not available");
     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;
-  }
+  //  
+  AliESDInputHandler *inH = dynamic_cast<AliESDInputHandler *>(fInputHandler);
   
+  // pure MC analysis: 
+
   if(HasMCData()){
-    if(fDebugLevel>=5)AliInfo(Form("MC Event: %p", fMC));
-    if(!fMC){
+    // Protect against missing MC trees
+    AliMCEventHandler *mcH = dynamic_cast<AliMCEventHandler *>(AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler());
+    if(!mcH->InitOk()) return;
+    if(!mcH->TreeK()) return;
+    if(!mcH->TreeTR()) return;            
+    
+    AliDebug(4, Form("MC Event: %p", fMCEvent));
+    if(!fMCEvent){
       AliError("No MC Event, but MC Data required");
       return;
     }
+    
+    ProcessMC();
   }
-  if(!fCuts){
+
+  
+  // from now on, only ESD are analyzed
+  // using HFE pid, using HFE cuts
+  // using CORRFW
+  
+  AliESDpid *workingPID = inH->GetESDpid();
+  if(workingPID){
+    AliDebug(1, "Using ESD PID from the input handler");
+    fDePID->SetESDpid(workingPID);
+  } else { 
+    AliDebug(1, "Using default ESD PID");
+    fDePID->SetESDpid(AliHFEtools::GetDefaultPID(HasMCData()));
+  }
+
+  if(!fDeCuts){
     AliError("HFE cuts not available");
     return;
   }
+
+  // ESD case with MC
+  if(HasMCData() && IsESDanalysis()) {
+    // Protect against missing MC trees
+    AliMCEventHandler *mcH = dynamic_cast<AliMCEventHandler *>(AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler());
+    if(!mcH->InitOk()) return;
+    if(!mcH->TreeK()) return;
+    if(!mcH->TreeTR()) return;
+
+    AliDebug(4, Form("MC Event: %p", fMCEvent));
+    if(!fMCEvent){
+      AliError("No MC Event, but MC Data required");
+      return;
+    }
+
+    ProcessESD();
+  } 
+  
+  // now only for data ESDs without MC
+  if(!HasMCData() && IsESDanalysis()) {    
+    ProcessData();
+  }
+
+  fDeNEvents->Fill(1);  
+  PostData(1, fHistDisplacedElectrons);
+  PostData(2, fDeCorrection);
+  PostData(3, fDeQA);
+  
+}
+
+//____________________________________________________________
+void AliAnalysisTaskDisplacedElectrons::ProcessMC(){
+  //
+  // handel pure MC analysis
+  //
+
+  Int_t nMCelectrons = 0;
+  AliESDEvent *fESD = dynamic_cast<AliESDEvent *>(fInputEvent);
+
+  Double_t mcContainer[4];   // container for the output in THnSparse
+  memset(mcContainer, 0, sizeof(Double_t) * 4);
+
+  fDeCFM->SetMCEventInfo(fMCEvent);
+
+  Double_t nContributor = 0;
+  const AliVVertex *mcPrimVtx = fMCEvent->GetPrimaryVertex();
+  if(mcPrimVtx) nContributor = mcPrimVtx->GetNContributors();
+  
+  // 
+  // cut at MC event level
+  //
+
+  if(!fDeCFM->CheckEventCuts(AliHFEcuts::kEventStepGenerated, fMCEvent)) return;
+  if(GetPlugin(kCorrection)) fDeCFM->GetEventContainer()->Fill(&nContributor,AliHFEcuts::kEventStepGenerated);
+  
+  AliStack *stack = 0x0;
+  
+  if(!fMCEvent->Stack())return;
+  stack = fMCEvent->Stack();
+  Int_t nTracks = stack->GetNtrack();
+
+  AliMCParticle *mcTrack = 0x0;
+
+  for(Int_t itrack = 0; itrack<nTracks; itrack++){
+    if(!(stack->Particle(itrack))) continue;
+    if(mcTrack)mcTrack = 0x0;
+    mcTrack= dynamic_cast<AliMCParticle*>(fMCEvent->GetTrack(itrack));
+    //TParticle *mcPart = stack->Particle(itrack);
+        
+    mcContainer[0] = mcTrack->Pt();
+    mcContainer[1] = mcTrack->Eta();
+    mcContainer[2] = mcTrack->Phi();
+    mcContainer[3] = mcTrack->Charge();
+    
+
+
+    if (!stack->IsPhysicalPrimary(mcTrack->GetLabel())) continue;
+    // no cut but require primary
+    if(GetPlugin(kCorrection))fDeCFM->GetParticleContainer()->Fill(mcContainer, 0);    
+        
+    // all pions for reference
+    if(TMath::Abs(mcTrack->Particle()->GetPdgCode())==AliHFEdisplacedElectrons::kPDGpion && GetPlugin(kCorrection))
+      fDeCFM->GetParticleContainer()->Fill(mcContainer, 1);
+    
+    // cut for signal: all MC electrons
+    if(TMath::Abs(mcTrack->Particle()->GetPdgCode())==AliHFEdisplacedElectrons::kPDGelectron && GetPlugin(kCorrection)) 
+      fDeCFM->GetParticleContainer()->Fill(mcContainer, 2);
+
+    // cut at track level kinematics: pt and eta
+    if(TMath::Abs(mcContainer[1])>=0.8 || mcContainer[0]>20 || mcContainer[0]<0.1) continue;
+
+    if(TMath::Abs(mcTrack->Particle()->GetPdgCode())==AliHFEdisplacedElectrons::kPDGelectron){
+      nMCelectrons++;
+      fElectronsMcPt->Fill(mcContainer[0]);
+    }  
+
+    if(GetPlugin(kCorrection))fDeCFM->GetParticleContainer()->Fill(mcContainer, 3);
+
+    
+    // fill MC THnSparse
+    fDisplacedElectrons->FillMcOutput(fESD, fMCEvent, mcTrack);
+    
+  }  // mc track loop 
+
+  if(fDeDebugLevel>=10) printf("there are %d electrons in this MC event", nMCelectrons);
+  
+}
+
+//____________________________________________________________
+void AliAnalysisTaskDisplacedElectrons::ProcessESD(){
+  
+  // this is to handel ESD tracks with MC information
+  // MC pid is only used when HFE pid is implemented, for comparison
+  // corrections are taken into account
   
   // 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;
+  Double_t esdContainer[4];   // container for the output in THnSparse
+  memset(esdContainer, 0, sizeof(Double_t) * 4);
+  AliESDEvent *fESD = dynamic_cast<AliESDEvent *>(fInputEvent);
+
+  fDeCFM->SetRecEventInfo(fESD);
+  Double_t nContrib = fESD->GetPrimaryVertex()->GetNContributors();
+
   Bool_t alreadyseen = kFALSE;
   LabelContainer cont(fESD->GetNumberOfTracks());
-
-  Int_t nElectrons=0;
   
+  Int_t nHFEelectrons=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);
+  AliStack *stack = 0x0;
 
+  if(!(stack = fMCEvent->Stack()))return;
+  
+  //
+  // cut at ESD event level
+  //
+  if(!fDeCFM->CheckEventCuts(AliHFEcuts::kEventStepReconstructed, fESD)) return;
+  if(GetPlugin(kCorrection)) fDeCFM->GetEventContainer()->Fill(&nContrib, AliHFEcuts::kEventStepReconstructed);
+  
   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();
+      esdContainer[0] = track->Pt();
+      esdContainer[1] = track->Eta();
+      esdContainer[2] = track->Phi();
+      esdContainer[3] = track->Charge();
       
-      AliStack *stack = fMC->Stack();
-      if(!stack) continue;     
+      // before any cut
+      alreadyseen = cont.Find(TMath::Abs(track->GetLabel()));  
+      cont.Append(TMath::Abs(track->GetLabel()));  // check double counting
+      if(alreadyseen) continue;  // avoid double counting
+      if(GetPlugin(kCorrection)) fDeCFM->GetParticleContainer()->Fill(esdContainer, 1+AliHFEcuts::kStepRecNoCut);      
       
-      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
-
+      // 1st track cut
+      // RecKine: ITSTPC cuts : ITS & TPC refit, covmatrix: (2, 2, 0.5, 0.5, 2); min_tpccls: 50, chi2_tpccls: 3.5
+      if(!fDeCFM->CheckParticleCuts(AliHFEcuts::kStepRecKineITSTPC, track)) continue;
+      if(GetPlugin(kCorrection)) fDeCFM->GetParticleContainer()->Fill(esdContainer, 1+AliHFEcuts::kStepRecKineITSTPC);
       
-      if(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
+      // 2nd track 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);
-       }
-      }
+      if(!fDeCFM->CheckParticleCuts(AliHFEcuts::kStepRecPrim, track)) continue;
+      if(GetPlugin(kCorrection)) fDeCFM->GetParticleContainer()->Fill(esdContainer, 1+AliHFEcuts::kStepRecPrim);
       
-      //  third cut
+      // 3rd track 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);
-       }
-      }
+      if(!fDeCFM->CheckParticleCuts(AliHFEcuts::kStepHFEcutsITS, track)) continue;
+      if(GetPlugin(kCorrection))fDeCFM->GetParticleContainer()->Fill(esdContainer, 1+AliHFEcuts::kStepHFEcutsITS);
+
+      /*
+      //  4th track cut
+      // TRD: number of tracklets in TRD
+      if(!fDeCFM->CheckParticleCuts(AliHFEcuts::kStepHFEcutsTRD, track)) continue;
+      if(GetPlugin(kCorrection)) fDeCFM->GetParticleContainer()->Fill(esdContainer, 1+AliHFEcuts::kStepHFEcutsTRD);
+      */
       
-      fDisplacedElectrons->FillMCOutput(fESD, track, stack);
-      
-      // track accepted, do PID --> only electron candidate will be processed
+      // 5th track cut
+      // 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;
+      //      if(HasMCData())hfetrack.fMCtrack = mctrack;
       
-         // 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)));
-       }
-      }
+      if(!fDePID->IsSelected(&hfetrack)) continue;
       
-      fDisplacedElectrons->FillESDOutput(fESD, track);
+      else if(fDeDebugLevel>=10)
+       AliInfo("ESD info: this particle is identified as electron by HFEpid method \n");
+      if(GetPlugin(kCorrection)) fDeCFM->GetParticleContainer()->Fill(esdContainer, 1+AliHFEcuts::kStepPID);
       
-    } // analyze displaced electrons plugin switched on
+      // Fill Containers
+      nHFEelectrons++;
+      fElectronsEsdPt->Fill(esdContainer[0]);
+      fDisplacedElectrons->FillEsdOutput(fESD, track, stack);
+    
+    }  // displaced electron analysis on ESD with MC plugin
   } // track loop  
+  
+  if(fDeDebugLevel>=10) printf("there are %d HFE electrons in this ESD event", nHFEelectrons);
+  
+}
 
-  if(fDebugLevel>=5)
-    AliInfo(Form("ESD info: number of electrons found in this event: %d\n", nElectrons));
 
 
-  fNEvents->Fill(1);
+//____________________________________________________________
+void AliAnalysisTaskDisplacedElectrons::ProcessData(){
+
+  // this is a track loop over real data 
+  // no MC information at all 
+  // HFE pid is used
+
+  AliESDEvent *fESD = dynamic_cast<AliESDEvent *>(fInputEvent);
+
+  Double_t dataContainer[4];   // container for the output in THnSparse
+  memset(dataContainer, 0, sizeof(Double_t) * 4);
   
-  PostData(1, fOutput);
-  PostData(2, fCorrection);
+  Bool_t alreadyseen = kFALSE;
+  LabelContainer cont(fESD->GetNumberOfTracks());
 
-}
 
-//____________________________________________________________
-void AliAnalysisTaskDisplacedElectrons::Terminate(Option_t *){
-  //
-  // Terminate not implemented at the moment
-  //  
+  AliESDtrack *track = 0x0;
+  Int_t nHFEelectrons= 0;
   
-  if(GetPlugin(kDisplacedElectrons))
-    {
+  fDeCFM->SetRecEventInfo(fESD);
+  Double_t nContrib = fESD->GetPrimaryVertex()->GetNContributors();
+  if(!fDeCFM->CheckEventCuts(AliHFEcuts::kEventStepReconstructed, fESD)) return;
+  if(GetPlugin(kCorrection)) fDeCFM->GetEventContainer()->Fill(&nContrib, AliHFEcuts::kEventStepReconstructed);
+  
+  
+  for(Int_t itrack = 0; itrack < fESD->GetNumberOfTracks(); itrack++){
+    track = fESD->GetTrack(itrack);
+    
+    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;
-      }
+      dataContainer[0] = track->Pt();
+      dataContainer[1] = track->Eta();
+      dataContainer[2] = track->Phi();
+      dataContainer[3] = track->Charge();
+      
+      alreadyseen = cont.Find(TMath::Abs(track->GetLabel()));  // double counted track
+      cont.Append(TMath::Abs(track->GetLabel()));
+      if(alreadyseen) continue;  // avoid double counting
+      if(GetPlugin(kCorrection))fDeCFM->GetParticleContainer()->Fill(&dataContainer[4], 
+                                                                    1+AliHFEcuts::kStepRecNoCut + AliHFEcuts::kNcutStepsESDtrack);
 
-      fOutput->Print();
-      fCorrection->Print();
+      // 1st track cut
+      // RecKine: ITSTPC cuts : ITS & TPC refit, covmatrix: (2, 2, 0.5, 0.5, 2); min_tpccls: 50, chi2_tpccls: 3.5
+      if(!fDeCFM->CheckParticleCuts(AliHFEcuts::kStepRecKineITSTPC, track)) continue;
+      if(GetPlugin(kCorrection)) fDeCFM->GetParticleContainer()->Fill(&dataContainer[4], 
+                                                                     1+AliHFEcuts::kStepRecKineITSTPC + AliHFEcuts::kNcutStepsESDtrack);
       
-      AliInfo("analysis done!\n");
+      // 2nd track cut
+      // RecPrim: cut on track quality : DCA to vertex max: 3cm and 10cm; reject kink daughters
+      if(!fDeCFM->CheckParticleCuts(AliHFEcuts::kStepRecPrim, track))  continue;
+      if(GetPlugin(kCorrection)) fDeCFM->GetParticleContainer()->Fill(&dataContainer[4], 
+                                                                     1+AliHFEcuts::kStepRecPrim + AliHFEcuts::kNcutStepsESDtrack);
+       
+      //  3rd track cut
+      // HFEcuts: ITS layers cuts: ITS pixel layer: kFirst, kSecond, kBoth, kNone or kAny
+      if(!fDeCFM->CheckParticleCuts(AliHFEcuts::kStepHFEcutsITS, track)) continue;
+      if(GetPlugin(kCorrection)) fDeCFM->GetParticleContainer()->Fill(&dataContainer[4],
+                                                                     1+AliHFEcuts::kStepHFEcutsITS + AliHFEcuts::kNcutStepsESDtrack);
       
-    }
-}
+      /*
+      //  4th track cut
+      // TRD: number of tracklets in TRD0
+      if(!fDeCFM->CheckParticleCuts(AliHFEcuts::kStepHFEcutsTRD, track)) continue;
+      if(GetPlugin(kCorrection)) if(HasMCData())fDeCFM->GetParticleContainer()->Fill(&dataContainer[4], 
+                                                                                    1+AliHFEcuts::kStepHFEcutsTRD + AliHFEcuts::kNcutStepsESDtrack);
+      */
+
+
+      // 5th track cut
+      // track accepted, do PID --> only electron candidate will be processed
 
+      AliHFEpidObject hfetrack;
+      hfetrack.fAnalysisType = AliHFEpidObject::kESDanalysis;
+      hfetrack.fRecTrack = track;
+      //      if(HasMCData())hfetrack.fMCtrack = mctrack;
+      
+      if(!fDePID->IsSelected(&hfetrack)) continue;
+      else if(fDeDebugLevel>=10)
+       AliInfo("ESD info: this particle is identified as electron by HFEpid method \n");
+      if(GetPlugin(kCorrection)) fDeCFM->GetParticleContainer()->Fill(dataContainer,  1+AliHFEcuts::kStepPID + AliHFEcuts::kNcutStepsESDtrack);
+
+      nHFEelectrons++;
+      fElectronsDataPt->Fill(dataContainer[0]);
+      fDisplacedElectrons->FillDataOutput(fESD, track);
+    } // analyze displaced electrons plugin switched on
+  } // track loop  
 
+  if(fDeDebugLevel>=10) printf("there are %d HFE electrons in this DATA event", nHFEelectrons);
+}
 
 
+//____________________________________________________________
+void AliAnalysisTaskDisplacedElectrons::Terminate(Option_t *){
+  //
+  // Terminate not implemented at the moment
+  //  
+  
+  fHistDisplacedElectrons = dynamic_cast<TList *>(GetOutputData(1));
+  fDeCorrection = dynamic_cast<TList *>(GetOutputData(2));
+  fDeQA = dynamic_cast<TList *>(GetOutputData(3));
+  if(!fDeCorrection) AliError("correction list not available\n");
+  if(!fHistDisplacedElectrons) AliError("de list not available\n");
+  if(!fDeQA) AliError("qa list is not available\n");
+  
+  fHistDisplacedElectrons->Print();
+  fDeCorrection->Print();
+  fDeQA->Print();
 
+  AliInfo("analysis done!\n");
+  
+}
 
 //____________________________________________________________
 void AliAnalysisTaskDisplacedElectrons::PrintStatus() const {
@@ -501,11 +670,14 @@ 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("\n");
+  printf("\t Analysis Settings\n\t========================================\n");
+  printf("\t running over %s\n", HasMCData()?"MC data":"pp collision data");
+  printf("\t displaced electrons' analysis is %s\n", GetPlugin(kDisplacedElectrons)?"ON":"OFF");
+  printf("\t correction container is %s\n", GetPlugin(kCorrection)?"ON":"OFF");
+  printf("\t hfe pid qa is %s\n", GetPlugin(kDePidQA)?"ON":"OFF");
+  printf("\t post processing  is %s\n", GetPlugin(kPostProcess)?"ON":"OFF");
+  printf("\t cuts: %s\n", (fDeCuts != NULL) ? "YES" : "NO");
   printf("\t ");
   printf("\n");
 }
@@ -521,92 +693,103 @@ void AliAnalysisTaskDisplacedElectrons::SwitchOnPlugin(Int_t plug){
   switch(plug)
     {
     case kDisplacedElectrons: 
-      SETBIT(fPlugins, plug); 
-      break;
-    case kPostProcess: 
-      SETBIT(fPlugins, plug); 
+      SETBIT(fDePlugins, plug); 
       break;
     case kCorrection:
-      SETBIT(fPlugins, plug); 
+      SETBIT(fDePlugins, plug); 
+      break;
+    case kDePidQA:
+      SETBIT(fDePlugins, plug); 
+      break;
+    case kPostProcess: 
+      SETBIT(fDePlugins, plug); 
       break;
     default: 
       AliError("Unknown Plugin");
     };
 }
 
-
 //____________________________________________________________
 void AliAnalysisTaskDisplacedElectrons::MakeParticleContainer(){
   //
-  // Create the particle container (borrowed from AliAnalysisTaskHFE)
+  // Create the particle container for the correction framework manager and 
+  // link it
   //
-  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();
+  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   // used for fixed pt bins
-  //  iBin[0] = 13; //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]=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);
-
+  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+ESD+Data          
+  //----------pure MC track-------------------------
+  // 0: MC generated
+  // 1: MC pion total  ---- be careful!!!!
+  // 2: MC electrons total
+  // 3: MC electrons in acceptance 
+  //-------ESD track with MC info-------------------
+  // 4: ESD track with MC: no cut
+  // 5: ESD track with MC: cut on kine its tpc
+  // 6: ESD track with MC: rec prim
+  // 7: ESD track with MC: hfe cuts its
+  // 8: ESD track with MC: hfe cuts trd
+  // 9: ESD track with MC: hfe pid 
+  //-----------data track---------------------------
+  // 10: DATA track wo MC: no cut
+  // 11: DATA track wo MC: cut on kine its tpc
+  // 12: DATA track wo MC: rec prim
+  // 13: DATA track wo MC: hfe cuts its
+  // 14: DATA track wo MC: hfe cuts trd
+  // 15: DATA track wo MC: hfe pid 
+  //------------------------------------------------
+
+  AliCFContainer* container = new AliCFContainer("deTrackContainer", "Container for tracks", 
+                                                (1 + AliHFEcuts::kNcutStepsTrack + AliHFEcuts::kNcutStepsESDtrack), kNvar, iBin);
+  
   //setting the bin limits
-  for(Int_t ivar = 0; ivar < kNvar; ivar++)
+  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
-
-
+  fDeCFM->SetParticleContainer(container);
 }
 
+
 //____________________________________________________________
 void AliAnalysisTaskDisplacedElectrons::MakeEventContainer(){
   //
   // Create the event container for the correction framework and link it
   //
+  
+  // event container
+  // 0: MC event
+  // 1: ESD event
+
   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);
+  AliCFContainer *evCont = new AliCFContainer("deEventContainer", "Container for DE 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);
+  fDeCFM->SetEventContainer(evCont);
 
 }
 
@@ -617,10 +800,10 @@ void AliAnalysisTaskDisplacedElectrons::AddPIDdetector(TString detector){
   //
   // Adding PID detector to the task
   //
-  if(!fPIDdetectors.Length()) 
-    fPIDdetectors = detector;
+  if(!fDePIDdetectors.Length()) 
+    fDePIDdetectors = detector;
   else
-    fPIDdetectors += ":" + detector;
+    fDePIDdetectors += ":" + detector;
 }
 
 
@@ -663,7 +846,7 @@ Bool_t AliAnalysisTaskDisplacedElectrons::LabelContainer::Find(Int_t label) cons
 }
 
 //____________________________________________________________
-Int_t AliAnalysisTaskDisplacedElectrons::LabelContainer::Next()  { 
+Int_t AliAnalysisTaskDisplacedElectrons::LabelContainer::Next() { 
   //
   // Mimic iterator
   //
index 1750e17..4190d8d 100644 (file)
 // study displaced electrons from beauty and charm 
 // with cut on impact parameters in various pT bins
 // 
+//
+// Authors:
+//  Hongyan Yang <hongyan@physi.uni-heidelberg.de>
+//  Carlo Bombonati <Carlo.Bombonati@cern.ch>
+// 
+
 
 
 #ifndef ALIANALYSISTASKDISPLACEDELECTRONS_H
@@ -53,7 +59,8 @@ class AliAnalysisTaskDisplacedElectrons : public AliAnalysisTaskSE{
   typedef enum{
     kPostProcess = 0,
     kDisplacedElectrons = 1, 
-    kCorrection = 2
+    kCorrection = 2,
+    kDePidQA = 3
   }Switches_t;
 
   enum{
@@ -74,19 +81,30 @@ class AliAnalysisTaskDisplacedElectrons : public AliAnalysisTaskSE{
 
   void PrintStatus() const;
   
-  Bool_t GetPlugin(Int_t plug) const { return TESTBIT(fPlugins, plug); };
+  Bool_t GetPlugin(Int_t plug) const { return TESTBIT(fDePlugins, 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 SetHFECuts(AliHFEcuts * const cuts) { fDeCuts = cuts; };
+  void SetNclustersITS(Int_t nITSclusters){fNminITSCluster = nITSclusters;};
+  void SetMinPrimVtxContrib(Int_t nPrimVtxContrib){fNminPrimVtxContrib = nPrimVtxContrib;};
+  void SetPIDdetectors(Char_t * const detectors){ fDePIDdetectors = detectors; };
+  void SetPIDStrategy(UInt_t strategy) { fDePIDstrategy = strategy; };
+  void SetDBLevel(UInt_t debugLevel) { fDeDebugLevel = debugLevel; };
   void AddPIDdetector(TString detector); 
  
-  Bool_t HasMCData() const { return TestBit(kHasMCdata); };
+  Bool_t IsAODanalysis() const { return TestBit(kAODanalysis); };
+  Bool_t IsESDanalysis() const { return !TestBit(kAODanalysis); };
+  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); };
+
+  void ProcessMC();
+  void ProcessESD();
+  void ProcessData();
+  
+
   
  private:
   
@@ -113,25 +131,27 @@ class AliAnalysisTaskDisplacedElectrons : public AliAnalysisTaskSE{
   void MakeParticleContainer();
   void MakeEventContainer();
 
-  UInt_t fDebugLevel;                   // debug level
-  
-  TString fPIDdetectors;                // Detectors for Particle Identification
-  UInt_t fPIDstrategy;                  // PID Strategy
-  
+  UInt_t fDeDebugLevel;                  // debug level
+  Int_t fNminITSCluster;                 // number of clusters in ITS
+  Int_t fNminPrimVtxContrib;             // number of ncontributor in ITS for prim vtx
+  TString fDePIDdetectors;                // Detectors for Particle Identification
+  UInt_t fDePIDstrategy;                  // PID Strategy
 
-  UShort_t fPlugins;                    // Enabled Plugins                                    
-  AliESDEvent *fESD;                    //! The ESD Event
-  AliMCEvent *fMC;                      //! The MC Event
+  UShort_t fDePlugins;                    // Enabled Plugins    
 
-  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
+  AliHFEcuts *fDeCuts;                    // Cut Collection
+  AliESDpid *fDeDefaultPID;               //! ESD PID method
+  AliHFEpid *fDePID;                      //! PID method
+  AliCFManager *fDeCFM;                   //! Correction Framework Manager
   AliHFEdisplacedElectrons *fDisplacedElectrons;        //! HFE displaced Electrons pointer 
+  
+                                               
+  TH1I *fDeNEvents;                       //! counter for the number of Events
+  TH1F *fElectronsMcPt;                   //! pt distribution of MC electrons (mcpid)
+  TH1F *fElectronsEsdPt;                  //! pt distribution of ESD electrons (hfepid)
+  TH1F *fElectronsDataPt;                  //! pt distribution of DATA electrons (hfepid)
+  TList *fDeCorrection;                   //! Container for correction  Outpu  
+  TList *fDeQA;                          //! container for the PID qa 
   TList *fHistDisplacedElectrons;                      //! list of outputs
  
   ClassDef(AliAnalysisTaskDisplacedElectrons, 1);      // The DisplacedElectrons Analysis Task
index 78b505e..b59edb9 100644 (file)
@@ -33,6 +33,7 @@
 #include <TH1F.h>
 #include <TH1I.h>
 #include <TH2F.h>
+#include <TH3D.h>
 #include <TIterator.h>
 #include <TList.h>
 #include <TLegend.h>
@@ -41,6 +42,7 @@
 #include <TParticle.h>
 #include <TProfile.h>
 #include <TString.h>
+#include <TF1.h>
 #include <TTree.h>
 
 #include "AliAODInputHandler.h"
@@ -50,6 +52,7 @@
 #include "AliCFManager.h"
 #include "AliESDEvent.h"
 #include "AliESDInputHandler.h"
+#include "AliESDpid.h"
 #include "AliESDtrack.h"
 #include "AliLog.h"
 #include "AliAnalysisManager.h"
@@ -72,6 +75,8 @@
 #include "AliHFEtools.h"
 #include "AliAnalysisTaskHFE.h"
 
+ClassImp(AliAnalysisTaskHFE)
+
 //____________________________________________________________
 AliAnalysisTaskHFE::AliAnalysisTaskHFE():
   AliAnalysisTaskSE("PID efficiency Analysis")
@@ -79,7 +84,11 @@ AliAnalysisTaskHFE::AliAnalysisTaskHFE():
   , fPIDdetectors("")
   , fPIDstrategy(0)
   , fPlugins(0)
+  , fWeighting(kFALSE)
+  , fWeightFactors(NULL)
+  , fWeightFactorsFunction(NULL)
   , fCFM(NULL)
+  , fHadronicBackground(NULL)
   , fCorrelation(NULL)
   , fPIDperformance(NULL)
   , fSignalToBackgroundMC(NULL)
@@ -100,13 +109,6 @@ AliAnalysisTaskHFE::AliAnalysisTaskHFE():
   //
   // Dummy constructor
   //
-  DefineOutput(1, TH1I::Class());
-  DefineOutput(2, TList::Class());
-  DefineOutput(3, TList::Class());
-//  DefineOutput(4, TList::Class());
-
-  // Initialize cuts
-  fPID = new AliHFEpid;
 }
 
 //____________________________________________________________
@@ -116,7 +118,11 @@ AliAnalysisTaskHFE::AliAnalysisTaskHFE(const char * name):
   , fPIDdetectors("")
   , fPIDstrategy(0)
   , fPlugins(0)
+  , fWeighting(kFALSE)
+  , fWeightFactors(NULL)
+  , fWeightFactorsFunction(NULL)
   , fCFM(NULL)
+  , fHadronicBackground(NULL)
   , fCorrelation(NULL)
   , fPIDperformance(NULL)
   , fSignalToBackgroundMC(NULL)
@@ -143,37 +149,41 @@ AliAnalysisTaskHFE::AliAnalysisTaskHFE(const char * name):
 //  DefineOutput(4, TList::Class());
 
   // Initialize cuts
-  fPID = new AliHFEpid;
 }
 
 //____________________________________________________________
 AliAnalysisTaskHFE::AliAnalysisTaskHFE(const AliAnalysisTaskHFE &ref):
   AliAnalysisTaskSE(ref)
-  , fQAlevel(ref.fQAlevel)
-  , fPIDdetectors(ref.fPIDdetectors)
-  , fPIDstrategy(ref.fPIDstrategy)
-  , fPlugins(ref.fPlugins)
-  , fCFM(ref.fCFM)
-  , fCorrelation(ref.fCorrelation)
-  , fPIDperformance(ref.fPIDperformance)
-  , fSignalToBackgroundMC(ref.fSignalToBackgroundMC)
-  , fPID(ref.fPID)
-  , fCuts(ref.fCuts)
-  , fSecVtx(ref.fSecVtx)
-  , fElecBackGround(ref.fElecBackGround)
-  , fMCQA(ref.fMCQA)
-  , fNEvents(ref.fNEvents)
-  , fNElectronTracksEvent(ref.fNElectronTracksEvent)
-  , fQA(ref.fQA)
-  , fOutput(ref.fOutput)
-  , fHistMCQA(ref.fHistMCQA)
-  , fHistSECVTX(ref.fHistSECVTX)
-  , fHistELECBACKGROUND(ref.fHistELECBACKGROUND)
+  , fQAlevel(0)
+  , fPIDdetectors()
+  , fPIDstrategy(0)
+  , fPlugins(0)
+  , fWeighting(kFALSE)
+  , fWeightFactors(NULL)
+  , fWeightFactorsFunction(NULL)
+  , fCFM(NULL)
+  , fHadronicBackground(NULL)
+  , fCorrelation(NULL)
+  , fPIDperformance(NULL)
+  , fSignalToBackgroundMC(NULL)
+  , fPID(NULL)
+  , fCuts(NULL)
+  , fSecVtx(NULL)
+  , fElecBackGround(NULL)
+  , fMCQA(NULL)
+  , fNEvents(NULL)
+  , fNElectronTracksEvent(NULL)
+  , fQA(NULL)
+  , fOutput(NULL)
+  , fHistMCQA(NULL)
+  , fHistSECVTX(NULL)
+  , fHistELECBACKGROUND(NULL)
 //  , fQAcoll(ref.fQAcoll)
 {
   //
   // Copy Constructor
   //
+  ref.Copy(*this);
 }
 
 //____________________________________________________________
@@ -181,38 +191,49 @@ AliAnalysisTaskHFE &AliAnalysisTaskHFE::operator=(const AliAnalysisTaskHFE &ref)
   //
   // Assignment operator
   //
-  if(this == &ref) return *this;
-  AliAnalysisTask::operator=(ref);
-  fQAlevel = ref.fQAlevel;
-  fPIDdetectors = ref.fPIDdetectors;
-  fPIDstrategy = ref.fPIDstrategy;
-  fPlugins = ref.fPlugins;
-  fCFM = ref.fCFM;
-  fCorrelation = ref.fCorrelation;
-  fPIDperformance = ref.fPIDperformance;
-  fSignalToBackgroundMC = ref.fSignalToBackgroundMC;
-  fPID = ref.fPID;
-  fCuts = ref.fCuts;
-  fSecVtx = ref.fSecVtx;
-  fElecBackGround = ref.fElecBackGround;
-  fMCQA = ref.fMCQA;
-  fNEvents = ref.fNEvents;
-  fNElectronTracksEvent = ref.fNElectronTracksEvent;
-  fQA = ref.fQA;
-  fOutput = ref.fOutput;
-  fHistMCQA = ref.fHistMCQA;
-  fHistSECVTX = ref.fHistSECVTX;
-  fHistELECBACKGROUND = ref.fHistELECBACKGROUND;
-  
-//  fQAcoll = ref.fQAcoll;
+  if(this == &ref) 
+    ref.Copy(*this);
   return *this;
 }
 
 //____________________________________________________________
+void AliAnalysisTaskHFE::Copy(TObject &o) const {
+  // 
+  // Copy into object o
+  //
+  AliAnalysisTaskHFE &target = dynamic_cast<AliAnalysisTaskHFE &>(o);
+  target.fQAlevel = fQAlevel;
+  target.fPIDdetectors = fPIDdetectors;
+  target.fPIDstrategy = fPIDstrategy;
+  target.fPlugins = fPlugins;
+  target.fWeighting = fWeighting;
+  target.fWeightFactors = fWeightFactors;
+  target.fWeightFactorsFunction = fWeightFactorsFunction;
+  target.fCFM = fCFM;
+  target.fHadronicBackground = fHadronicBackground;
+  target.fCorrelation = fCorrelation;
+  target.fPIDperformance = fPIDperformance;
+  target.fSignalToBackgroundMC = fSignalToBackgroundMC;
+  target.fPID = fPID;
+  target.fCuts = fCuts;
+  target.fSecVtx = fSecVtx;
+  target.fElecBackGround = fElecBackGround;
+  target.fMCQA = fMCQA;
+  target.fNEvents = fNEvents;
+  target.fNElectronTracksEvent = fNElectronTracksEvent;
+  target.fQA = fQA;
+  target.fOutput = fOutput;
+  target.fHistMCQA = fHistMCQA;
+  target.fHistSECVTX = fHistSECVTX;
+  target.fHistELECBACKGROUND = fHistELECBACKGROUND;
+}
+
+//____________________________________________________________
 AliAnalysisTaskHFE::~AliAnalysisTaskHFE(){
   //
   // Destructor
   //
+  return;
   if(fPID) delete fPID;
   if(fQA){
     fQA->Clear();
@@ -222,6 +243,8 @@ AliAnalysisTaskHFE::~AliAnalysisTaskHFE(){
     fOutput->Clear();
     delete fOutput;
   }
+  if(fWeightFactors) delete fWeightFactors;
+  if(fWeightFactorsFunction) delete fWeightFactorsFunction;
   if(fHistMCQA){
     fHistMCQA->Clear();
     delete fHistMCQA;
@@ -245,6 +268,7 @@ AliAnalysisTaskHFE::~AliAnalysisTaskHFE(){
   if(fPIDperformance) delete fPIDperformance;
   if(fSignalToBackgroundMC) delete fSignalToBackgroundMC;
 //  if(fQAcoll) delete fQAcoll;
+
 }
 
 //____________________________________________________________
@@ -259,9 +283,10 @@ void AliAnalysisTaskHFE::UserCreateOutputObjects(){
   // QA histograms are created if requested
   // Called once per worker
   //
+  fPID = new AliHFEpid;
   AliDebug(3, "Creating Output Objects");
   // Automatic determination of the analysis mode
-  AliVEventHandler *inputHandler = AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler();
+  AliVEventHandler *inputHandler = dynamic_cast<AliVEventHandler *>(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler());
   if(!TString(inputHandler->IsA()->GetName()).CompareTo("AliAODInputHandler")){
     SetAODAnalysis();
   } else {
@@ -289,6 +314,9 @@ void AliAnalysisTaskHFE::UserCreateOutputObjects(){
   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);
+  fQA->AddAt(new TH2F("radius", "Production Vertex", 100, 0.0, 5.0, 100, 0.0, 5.0), 8);
+  fQA->AddAt(new TH1F("secvtxept", "pT of tagged e", 500, 0, 50), 9); // mj: will move to another place soon
+  fQA->AddAt(new TH2F("secvtxeTPCsig", "TPC signal for tagged e",125, 0, 25, 200, 0, 200 ), 10); // mj: will move to another place soon 
 
   if(!fOutput) fOutput = new TList;
   // Initialize correction Framework and Cuts
@@ -314,6 +342,7 @@ void AliAnalysisTaskHFE::UserCreateOutputObjects(){
   fOutput->AddAt(fPIDperformance, 3);
   fOutput->AddAt(fSignalToBackgroundMC, 4);
   fOutput->AddAt(fNElectronTracksEvent, 5);
+  fOutput->AddAt(fHadronicBackground, 6);
 
   // Initialize PID
   if(IsQAOn(kPIDqa)){
@@ -337,14 +366,22 @@ void AliAnalysisTaskHFE::UserCreateOutputObjects(){
     fHistMCQA->SetName("MCqa");
     fMCQA->CreateHistograms(AliHFEmcQA::kCharm,0,"mcqa_");               // create histograms for charm
     fMCQA->CreateHistograms(AliHFEmcQA::kBeauty,0,"mcqa_");              // create histograms for beauty
+    fMCQA->CreateHistograms(AliHFEmcQA::kOthers,0,"mcqa_");              // create histograms for beauty
     fMCQA->CreateHistograms(AliHFEmcQA::kCharm,1,"mcqa_barrel_");        // create histograms for charm 
     fMCQA->CreateHistograms(AliHFEmcQA::kBeauty,1,"mcqa_barrel_");       // create histograms for beauty
+    fMCQA->CreateHistograms(AliHFEmcQA::kOthers,1,"mcqa_barrel_");       // create histograms for beauty
     fMCQA->CreateHistograms(AliHFEmcQA::kCharm,2,"mcqa_unitY_");         // create histograms for charm 
     fMCQA->CreateHistograms(AliHFEmcQA::kBeauty,2,"mcqa_unitY_");        // create histograms for beauty
+    fMCQA->CreateHistograms(AliHFEmcQA::kOthers,2,"mcqa_unitY_");        // create histograms for beauty
     fMCQA->CreateHistograms(AliHFEmcQA::kCharm,3,"mcqa_reccut_");        // create histograms for charm 
     fMCQA->CreateHistograms(AliHFEmcQA::kBeauty,3,"mcqa_reccut_");       // create histograms for beauty
+    fMCQA->CreateHistograms(AliHFEmcQA::kOthers,3,"mcqa_reccut_");       // create histograms for beauty
     fMCQA->CreateHistograms(AliHFEmcQA::kCharm,4,"mcqa_recpidcut_");     // create histograms for charm 
     fMCQA->CreateHistograms(AliHFEmcQA::kBeauty,4,"mcqa_recpidcut_");    // create histograms for beauty
+    fMCQA->CreateHistograms(AliHFEmcQA::kOthers,4,"mcqa_recpidcut_");    // create histograms for beauty
+    fMCQA->CreateHistograms(AliHFEmcQA::kCharm,5,"mcqa_secvtxcut_");     // create histograms for charm 
+    fMCQA->CreateHistograms(AliHFEmcQA::kBeauty,5,"mcqa_secvtxcut_");    // create histograms for beauty
+    fMCQA->CreateHistograms(AliHFEmcQA::kOthers,5,"mcqa_secvtxcut_");    // create histograms for beauty
     TIter next(gDirectory->GetList());
     TObject *obj;
     int counter = 0;
@@ -408,10 +445,30 @@ void AliAnalysisTaskHFE::UserExec(Option_t *){
     return;
   }
 
+  if(IsESDanalysis() && HasMCData()){
+    // Protect against missing MC trees
+    AliMCEventHandler *mcH = dynamic_cast<AliMCEventHandler *>(AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler());
+    if(!mcH->InitOk()) return;
+    if(!mcH->TreeK()) return;
+    if(!mcH->TreeTR()) return;
+  }
+
+  // Protect agains missing 
   if(HasMCData()) ProcessMC();  // Run the MC loop + MC QA in case MC Data are available
 
   if(IsAODanalysis()) ProcessAOD();
-  else ProcessESD();
+  else{
+    AliESDInputHandler *inH = dynamic_cast<AliESDInputHandler *>(fInputHandler);
+    AliESDpid *workingPID = inH->GetESDpid();
+    if(workingPID){
+      AliDebug(1, "Using ESD PID from the input handler");
+      fPID->SetESDpid(workingPID);
+    } else { 
+      AliDebug(1, "Using default ESD PID");
+      fPID->SetESDpid(AliHFEtools::GetDefaultPID(HasMCData()));
+    }
+    ProcessESD();
+  }
   // Done!!!
   PostData(1, fNEvents);
   PostData(2, fOutput);
@@ -449,7 +506,31 @@ void AliAnalysisTaskHFE::Terminate(Option_t *){
     }
   }
 }
+//_______________________________________________________________
+Bool_t AliAnalysisTaskHFE::IsEventInBinZero() {
+  //
+  //
+  //
+
+  //printf("test in IsEventInBinZero\n");
+  if(!fInputEvent){
+    AliError("Reconstructed Event not available");
+    return kFALSE;
+  }
 
+  // check vertex
+  const AliVVertex *vertex = fInputEvent->GetPrimaryVertex();
+  if(!vertex) return kTRUE;
+  //if(vertex) return kTRUE;
+
+  // check tracks
+  if(fInputEvent->GetNumberOfTracks()<=0) return kTRUE;
+  //if(fInputEvent->GetNumberOfTracks()>0) return kTRUE;
+  
+  
+  return kFALSE;
+  
+}
 //____________________________________________________________
 void AliAnalysisTaskHFE::ProcessMC(){
   //
@@ -468,7 +549,7 @@ void AliAnalysisTaskHFE::ProcessMC(){
       AliDebug(2, "Running MC QA");
 
       if(fMCEvent->Stack()){
-        fMCQA->SetStack(fMCEvent->Stack());
+       fMCQA->SetMCEvent(fMCEvent);
         fMCQA->SetGenEventHeader(fMCEvent->GenEventHeader());
         fMCQA->Init();
 
@@ -483,13 +564,16 @@ void AliAnalysisTaskHFE::ProcessMC(){
           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
+          fMCQA->GetDecayedKine(mcpart, AliHFEmcQA::kOthers, 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
+            fMCQA->GetDecayedKine(mcpart, AliHFEmcQA::kOthers, AliHFEmcQA::kElectronPDG, 1); // accept |eta|<0.9
           }
           if (TMath::Abs(AliHFEtools::GetRapidity(mcpart)) < 0.5) {
             fMCQA->GetDecayedKine(mcpart, AliHFEmcQA::kCharm,  AliHFEmcQA::kElectronPDG, 2); // accept |y|<0.5
             fMCQA->GetDecayedKine(mcpart, AliHFEmcQA::kBeauty, AliHFEmcQA::kElectronPDG, 2); // accept |y|<0.5
+            fMCQA->GetDecayedKine(mcpart, AliHFEmcQA::kOthers, AliHFEmcQA::kElectronPDG, 2); // accept |y|<0.5
           }
         }
         fMCQA->EndOfEventAna(AliHFEmcQA::kCharm);
@@ -505,8 +589,10 @@ void AliAnalysisTaskHFE::ProcessMC(){
   }
   // Run MC loop
   AliVParticle *mctrack = NULL;
+  AliDebug(3, Form("Number of Tracks: %d", fMCEvent->GetNumberOfTracks()));
   for(Int_t imc = 0; imc <fMCEvent->GetNumberOfTracks(); imc++){
     if(!(mctrack = fMCEvent->GetTrack(imc))) continue;
+    AliDebug(4, "Next Track");
     if(ProcessMCtrack(mctrack)) nElectrons++;
   }
 
@@ -539,7 +625,7 @@ void AliAnalysisTaskHFE::ProcessESD(){
 
   if(HasMCData()){
     if (GetPlugin(kSecVtx)) { 
-      if(fMCEvent->Stack()) fSecVtx->SetStack(fMCEvent->Stack());
+      fSecVtx->SetMCEvent(fMCEvent);
     }
     if (GetPlugin(kIsElecBackGround)) { 
       fElecBackGround->SetMCEvent(fMCEvent);
@@ -547,8 +633,8 @@ void AliAnalysisTaskHFE::ProcessESD(){
   }
 
 
-  Double_t container[8];
-  memset(container, 0, sizeof(Double_t) * 8);
+  Double_t container[10];
+  memset(container, 0, sizeof(Double_t) * 10);
   // container for the output THnSparse
   Double_t dataE[5]; // [pT, eta, Phi, type, 'C' or 'B']
   Int_t nElectronCandidates = 0;
@@ -574,14 +660,18 @@ void AliAnalysisTaskHFE::ProcessESD(){
   //
   // Loop ESD
   //
+  AliDebug(3, Form("Number of Tracks: %d", fESD->GetNumberOfTracks()));
   for(Int_t itrack = 0; itrack < fESD->GetNumberOfTracks(); itrack++){
     
     track = fESD->GetTrack(itrack);
+
+    AliDebug(3, Form("Doing track %d, %p", itrack, track));
           
     container[0] = track->Pt();
     container[1] = track->Eta();
     container[2] = track->Phi();
     container[3] = track->Charge();
+    container[4] = 0;
 
     dataE[0] = track->Pt();
     dataE[1] = track->Eta();
@@ -591,34 +681,51 @@ void AliAnalysisTaskHFE::ProcessESD(){
     dataE[5] = -1;
 
     signal = kTRUE;
-
+    Double_t weight = 1.0;
+    
     // Fill step without any cut
           
     if(HasMCData()){
+      container[4] = container[9] = kOther;
       // Check if it is electrons near the vertex
       if(!(mctrack = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(TMath::Abs(track->GetLabel()))))) continue;
-      mctrack4QA = mctrack->Particle();//fMCEvent->Stack()->Particle(TMath::Abs(track->GetLabel()));
+      mctrack4QA = mctrack->Particle();
+
+      container[5] = mctrack->Pt();
+      container[6] = mctrack->Eta();
+      container[7] = mctrack->Phi();
+      container[8] = mctrack->Charge()/3.;
+
+      if(fWeighting) weight = FindWeight(container[5],container[6],container[7]);    
 
-      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;
+      else AliDebug(3, "Signal Electron");
+      
+      Int_t signalTrack = 0;
+      if((signalTrack = IsSignalElectron(track))){
+        AliDebug(3, Form("Signal: Index = %d\n", signalTrack));
+        switch(signalTrack){
+          case 1: container[4] = container[9] = kSignalCharm; break;
+          case 2: container[4] = container[9] = kSignalBeauty; break;
+          default: container[4] = container[9] = kOther; break;
+        };
+      } else if(IsGammaElectron(track)) container[4] = container[9] = kGammaConv;
+      AliDebug(3, Form("Signal Decision(%f/%f)", container[4], container[9]));
     }
+    AliDebug(3, Form("Weight? %f", weight));
     if(signal) {
       alreadyseen = cont.Find(TMath::Abs(track->GetLabel()));
       cont.Append(TMath::Abs(track->GetLabel()));
       
-      fCFM->GetParticleContainer()->Fill(&container[4], AliHFEcuts::kStepRecNoCut);
-      fCFM->GetParticleContainer()->Fill(&container[0], AliHFEcuts::kStepRecNoCut + 2*AliHFEcuts::kNcutStepsESDtrack);
+      fCFM->GetParticleContainer()->Fill(&container[5], AliHFEcuts::kStepRecNoCut,weight);
+      fCFM->GetParticleContainer()->Fill(&container[0], AliHFEcuts::kStepRecNoCut + 2*AliHFEcuts::kNcutStepsESDtrack,weight);
       if(alreadyseen) {
-        fCFM->GetParticleContainer()->Fill(&container[4], AliHFEcuts::kStepRecNoCut + AliHFEcuts::kNcutStepsESDtrack);
+        fCFM->GetParticleContainer()->Fill(&container[5], AliHFEcuts::kStepRecNoCut + AliHFEcuts::kNcutStepsESDtrack,weight);
       }
     }
 
     // RecKine: ITSTPC cuts  
-    if(!ProcessCutStep(AliHFEcuts::kStepRecKineITSTPC, track, container, signal, alreadyseen)) continue;
+    if(!ProcessCutStep(AliHFEcuts::kStepRecKineITSTPC, track, container, signal, alreadyseen, weight)) continue;
     
     // Check TRD criterions (outside the correction framework)
     if(track->GetTRDncls()){
@@ -631,13 +738,13 @@ void AliAnalysisTaskHFE::ProcessESD(){
 
     
     // RecPrim
-    if(!ProcessCutStep(AliHFEcuts::kStepRecPrim, track, container, signal, alreadyseen)) continue;
+    if(!ProcessCutStep(AliHFEcuts::kStepRecPrim, track, container, signal, alreadyseen,weight)) continue;
 
     // HFEcuts: ITS layers cuts
-    if(!ProcessCutStep(AliHFEcuts::kStepHFEcutsITS, track, container, signal, alreadyseen)) continue;
+    if(!ProcessCutStep(AliHFEcuts::kStepHFEcutsITS, track, container, signal, alreadyseen,weight)) continue;
 
     // HFEcuts: Nb of tracklets TRD0
-    if(!ProcessCutStep(AliHFEcuts::kStepHFEcutsTRD, track, container, signal, alreadyseen)) continue;
+    if(!ProcessCutStep(AliHFEcuts::kStepHFEcutsTRD, track, container, signal, alreadyseen,weight)) continue;
     if(signal) {
       // dimensions 3&4&5 : pt,eta,phi (MC)
       ((THnSparseF *)fCorrelation->At(0))->Fill(container);
@@ -648,8 +755,13 @@ void AliAnalysisTaskHFE::ProcessESD(){
       AliDebug(2, "Running MC QA");
       fMCQA->GetDecayedKine(mctrack4QA, AliHFEmcQA::kCharm,  AliHFEmcQA::kElectronPDG, 3);  // charm
       fMCQA->GetDecayedKine(mctrack4QA, AliHFEmcQA::kBeauty,  AliHFEmcQA::kElectronPDG, 3); // beauty 
+      fMCQA->GetDecayedKine(mctrack4QA, AliHFEmcQA::kOthers,  AliHFEmcQA::kElectronPDG, 3); // beauty 
     } 
 
+    if(HasMCData()){
+      FillProductionVertex(track);
+    }
+
     // track accepted, do PID
     AliHFEpidObject hfetrack;
     hfetrack.fAnalysisType = AliHFEpidObject::kESDanalysis;
@@ -658,51 +770,74 @@ void AliAnalysisTaskHFE::ProcessESD(){
     if(!fPID->IsSelected(&hfetrack)) continue;
     nElectronCandidates++;
 
+    // Fill Histogram for Hadronic Background
+    if(HasMCData()){
+      if(mctrack && (TMath::Abs(mctrack->Particle()->GetPdgCode()) != 11))
+        fHadronicBackground->Fill(container, 0);
+    }
+
     if (HasMCData() && IsQAOn(kMCqa)) {
       // mc qa for after the reconstruction and pid cuts  
       AliDebug(2, "Running MC QA");
       fMCQA->GetDecayedKine(mctrack4QA, AliHFEmcQA::kCharm,  AliHFEmcQA::kElectronPDG, 4);  // charm
       fMCQA->GetDecayedKine(mctrack4QA, AliHFEmcQA::kBeauty,  AliHFEmcQA::kElectronPDG, 4); // beauty 
+      fMCQA->GetDecayedKine(mctrack4QA, AliHFEmcQA::kOthers,  AliHFEmcQA::kElectronPDG, 4); // beauty 
     } 
 
     // Fill Containers
     if(signal) {
-      fCFM->GetParticleContainer()->Fill(container, AliHFEcuts::kStepPID + 2*AliHFEcuts::kNcutStepsESDtrack);
-      fCFM->GetParticleContainer()->Fill(&container[4], AliHFEcuts::kStepPID);
+      fCFM->GetParticleContainer()->Fill(container, AliHFEcuts::kStepPID + 2*AliHFEcuts::kNcutStepsESDtrack,weight);
+      fCFM->GetParticleContainer()->Fill(&container[5], AliHFEcuts::kStepPID,weight);
       if(alreadyseen) {
-        fCFM->GetParticleContainer()->Fill(&container[4], (AliHFEcuts::kStepPID + (AliHFEcuts::kNcutStepsESDtrack)));
+        fCFM->GetParticleContainer()->Fill(&container[5], (AliHFEcuts::kStepPID + (AliHFEcuts::kNcutStepsESDtrack)),weight);
       }
       // dimensions 3&4&5 : pt,eta,phi (MC)
       ((THnSparseF *)fCorrelation->At(1))->Fill(container);
     }
 
-    if(GetPlugin(kSecVtx) && fMCEvent->Stack()) {
+    if(GetPlugin(kSecVtx)) {
       AliDebug(2, "Running Secondary Vertex Analysis");
-      if(track->Pt()>1.0){
+      if(track->Pt()>2.0 && nContrib > 1){ 
         fSecVtx->InitHFEpairs();
         fSecVtx->InitHFEsecvtxs();
         for(Int_t jtrack = 0; jtrack < fESD->GetNumberOfTracks(); jtrack++){
           htrack = fESD->GetTrack(jtrack);
           if ( itrack == jtrack ) continue; // since it is for tagging single electron, don't need additional condition 
-          if (htrack->Pt()<1.0) continue;
+          if (htrack->Pt()<2.0) continue;
           if (!fCFM->CheckParticleCuts(AliHFEcuts::kStepRecKineITSTPC, htrack)) continue;
           if (!fCFM->CheckParticleCuts(AliHFEcuts::kStepRecPrim, htrack)) continue;
           fSecVtx->PairAnalysis(track, htrack, jtrack); // e-h pairing
         }
-        /*for(int ip=0; ip<fSecVtx->HFEpairs()->GetEntriesFast(); ip++){
-          if(HasMCData()){
+        for(int ip=0; ip<fSecVtx->HFEpairs()->GetEntriesFast(); ip++){
+          //if(HasMCData()){
             AliHFEpairs *pair = (AliHFEpairs*) (fSecVtx->HFEpairs()->UncheckedAt(ip));
-            if(!(pair->GetPairCode()>1. && pair->GetPairCode()<4.))  // apply various cuts
+            //if(!(pair->GetPairCode()>1. && pair->GetPairCode()<4.))  // apply various cuts
+            // apply various cuts
+            if(pair->GetKFChi2()>5.) // only apply vertex chi2 cut for the moment
+            //if((pair->GetKFChi2()>5.) || !(pair->GetSignedLxy()>0. && pair->GetSignedLxy()<2.)) 
               fSecVtx->HFEpairs()->RemoveAt(ip);
-          }
-        }*/
+          //}
+        }
         fSecVtx->HFEpairs()->Compress();
-        fSecVtx->RunSECVTX(track); // secondary vertexing with e,h1,h2,.. tracks
+        if(fSecVtx->HFEpairs()->GetEntriesFast()) fSecVtx->RunSECVTX(track); // secondary vertexing with e,h1,h2,.. tracks
         for(int ip=0; ip<fSecVtx->HFEsecvtxs()->GetEntriesFast(); ip++){
           AliHFEsecVtxs *secvtx=0x0;
           secvtx = (AliHFEsecVtxs*) (fSecVtx->HFEsecvtxs()->UncheckedAt(ip));
+          if(!(secvtx->GetInvmass()>2.0 && secvtx->GetInvmass()<5.2) || !(secvtx->GetSignedLxy2()>0.08 && secvtx->GetSignedLxy2()<1.5) || !(secvtx->GetKFIP2()>-0.1 && secvtx->GetKFIP2()<0.1))
+            fSecVtx->HFEsecvtxs()->RemoveAt(ip);
           // here you apply cuts, then if it doesn't pass the cut, remove it from the fSecVtx->HFEsecvtxs() 
         }
+        if(fSecVtx->HFEsecvtxs()->GetEntriesFast()) {
+          (dynamic_cast<TH1F *>(fQA->At(9)))->Fill(track->Pt());
+          (dynamic_cast<TH2F *>(fQA->At(10)))->Fill(track->P(),track->GetTPCsignal());
+          if (HasMCData() && IsQAOn(kMCqa)) {
+            // mc qa for after the reconstruction and pid cuts  
+            AliDebug(2, "Running MC QA");
+            fMCQA->GetDecayedKine(mctrack4QA, AliHFEmcQA::kCharm,  AliHFEmcQA::kElectronPDG, 5);  // charm
+            fMCQA->GetDecayedKine(mctrack4QA, AliHFEmcQA::kBeauty,  AliHFEmcQA::kElectronPDG, 5); // beauty 
+            fMCQA->GetDecayedKine(mctrack4QA, AliHFEmcQA::kOthers,  AliHFEmcQA::kElectronPDG, 5); // beauty 
+          }
+        }
         fSecVtx->DeleteHFEpairs();
         fSecVtx->DeleteHFEsecvtxs();
       }
@@ -770,7 +905,7 @@ void AliAnalysisTaskHFE::ProcessAOD(){
  
   AliAODTrack *track = NULL;
   AliAODMCParticle *mctrack = NULL;
-  Double_t container[8]; memset(container, 0, sizeof(Double_t) * 8);
+  Double_t container[10]; memset(container, 0, sizeof(Double_t) * 10);
   Double_t dataE[6]; // [pT, eta, Phi, Charge, type, 'C' or 'B']
   Int_t nElectronCandidates = 0;
   Int_t pid;
@@ -792,13 +927,23 @@ void AliAnalysisTaskHFE::ProcessAOD(){
     dataE[5] = -1;
     
     if(HasMCData()){
+      Int_t signalTrack = 0;
+      if((signalTrack = IsSignalElectron(track))){
+        switch(signalTrack){
+          case 1: container[4] = container[9] = kSignalCharm; break;
+          case 2: container[4] = container[9] = kSignalBeauty; break;
+        };
+      } else if(IsGammaElectron(track)) 
+        container[4] = container[9] = kGammaConv;
+      else container[4] = container[9] = kOther;
+
       Int_t label = TMath::Abs(track->GetLabel());
       if(label){
         mctrack = dynamic_cast<AliAODMCParticle *>(fMCEvent->GetTrack(label));
-        container[4] = mctrack->Pt();
-        container[5] = mctrack->Eta();
-        container[6] = mctrack->Phi();
-        container[7] = mctrack->Charge();
+        container[5] = mctrack->Pt();
+        container[6] = mctrack->Eta();
+        container[7] = mctrack->Phi();
+        container[8] = mctrack->Charge();
       }
     }
     // track accepted, do PID
@@ -848,7 +993,7 @@ 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[4], signalContainer[6];
+  Double_t container[5], signalContainer[6];
   Double_t vertex[3]; // Production vertex cut to mask gammas which are NOT supposed to have hits in the first ITS layer(s)
   if(IsESDanalysis()){
     AliMCParticle *mctrack = dynamic_cast<AliMCParticle *>(track);
@@ -878,11 +1023,24 @@ Bool_t AliAnalysisTaskHFE::ProcessMCtrack(AliVParticle *track){
 
     aodmctrack->XvYvZv(vertex);
   }
-  if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepMCGenerated, track)) return kFALSE;
+  Int_t signal = 0;
+  if((signal = IsSignalElectron(track))){
+    switch(signal){
+      case 1: container[4] = kSignalCharm; break;
+      case 2: container[4] = kSignalBeauty; break;
+    };
+  }else if(IsGammaElectron(track)) container[4] = kGammaConv;
+  else container[4] = kOther;
+
+  // weight
+  Double_t weight = 1.0;
+  if(fWeighting) weight = FindWeight(container[0],container[1],container[2]);
+
+ if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepMCGenerated, track)) return kFALSE;
   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);
+ fCFM->GetParticleContainer()->Fill(container, AliHFEcuts::kStepMCGenerated,weight);
+  if((signalContainer[4] = static_cast<Double_t >(IsSignalElectron(track))) > 1e-3) fCFM->GetParticleContainer()->Fill(container, AliHFEcuts::kStepMCsignal,weight);
   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]);
@@ -896,7 +1054,7 @@ Bool_t AliAnalysisTaskHFE::ProcessMCtrack(AliVParticle *track){
   (dynamic_cast<TH1F *>(fQA->At(2)))->Fill(container[2] - TMath::Pi());
   //if(IsESDanalysis()){
     if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepMCInAcceptance, track)) return kFALSE;
-    fCFM->GetParticleContainer()->Fill(container, AliHFEcuts::kStepMCInAcceptance);
+    fCFM->GetParticleContainer()->Fill(container, AliHFEcuts::kStepMCInAcceptance,weight);
   //}
   return kTRUE;
 }
@@ -925,7 +1083,8 @@ void AliAnalysisTaskHFE::MakeParticleContainer(){
   // Create the particle container for the correction framework manager and 
   // link it
   //
-  const Int_t kNvar   = 4 ; //number of variables on the grid:pt,eta, phi, charge
+  const Int_t kNvar   = 5;
+  //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()};
@@ -936,6 +1095,7 @@ void AliAnalysisTaskHFE::MakeParticleContainer(){
   iBin[1] =  8; // bins in eta 
   iBin[2] = 18; // bins in phi
   iBin[3] =  2; // bins in charge
+  iBin[4] =  4; // creation process of the electron
 
   //arrays for lower bounds :
   Double_t* binEdges[kNvar];
@@ -943,13 +1103,19 @@ void AliAnalysisTaskHFE::MakeParticleContainer(){
   binEdges[1] = AliHFEtools::MakeLinearBinning(iBin[1], kEtabound[0], kEtabound[1]);
   binEdges[2] = AliHFEtools::MakeLinearBinning(iBin[2], kPhibound[0], kPhibound[1]);
   binEdges[3] = AliHFEtools::MakeLinearBinning(iBin[3], -1.1, 1.1); // Numeric precision
+  binEdges[4] = AliHFEtools::MakeLinearBinning(iBin[4], 0, iBin[4]); // Numeric precision
+  //for(Int_t ib = 0; ib <= iBin[4]; ib++) printf("%f\t", binEdges[4][ib]);
+  //printf("\n");
 
   //one "container" for MC
   AliCFContainer* container = new AliCFContainer("trackContainer", "Container for tracks", (AliHFEcuts::kNcutStepsTrack + 2*AliHFEcuts::kNcutStepsESDtrack), kNvar, iBin);
+  fHadronicBackground = new AliCFContainer("hadronicBackground", "Container for hadronic Background", 1, kNvar, iBin);
 
   //setting the bin limits
-  for(Int_t ivar = 0; ivar < kNvar; ivar++)
+  for(Int_t ivar = 0; ivar < kNvar; ivar++){
     container -> SetBinLimits(ivar, binEdges[ivar]);
+    fHadronicBackground -> SetBinLimits(ivar, binEdges[ivar]);
+  }
   fCFM->SetParticleContainer(container);
 
   //create correlation matrix for unfolding
@@ -1082,7 +1248,7 @@ Int_t AliAnalysisTaskHFE::LabelContainer::Next(){
 }
 
 //____________________________________________________________
-Int_t AliAnalysisTaskHFE::IsSignalElectron(AliVParticle *fTrack) const{
+Int_t AliAnalysisTaskHFE::IsSignalElectron(const AliVParticle * const track) const{
   //
   // Checks whether the identified electron track is coming from heavy flavour
   // returns 0 in case of no signal, 1 in case of charm and 2 in case of Bottom
@@ -1092,67 +1258,134 @@ Int_t AliAnalysisTaskHFE::IsSignalElectron(AliVParticle *fTrack) const{
     kCharm = 1,
     kBeauty = 2
   };
-  TString objname = fTrack->IsA()->GetName();
+
+  if(!fMCEvent) return kNoSignal;
+  const AliVParticle *motherParticle = NULL, *mctrack = NULL;
+  TString objectType = track->IsA()->GetName();
+  Int_t label = 0;
+  if(objectType.CompareTo("AliESDtrack") == 0 || objectType.CompareTo("AliAODTrack") == 0){
+    // Reconstructed track
+    if((label = TMath::Abs(track->GetLabel())) && label < fMCEvent->GetNumberOfTracks())
+      mctrack = fMCEvent->GetTrack(label);
+  } else {
+    // MCParticle
+    mctrack = track;
+  }
+
+  if(!mctrack) return kNoSignal;
+  
   Int_t pid = 0;
-  if(IsESDanalysis()){
-    // ESD Analysis
-    AliMCParticle *mctrack = NULL;
-    if(!objname.CompareTo("AliESDtrack")){
-      AliDebug(2, "Checking signal for ESD track");
-      AliESDtrack *esdtrack = dynamic_cast<AliESDtrack *>(fTrack);
-      mctrack = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(TMath::Abs(esdtrack->GetLabel())));
-    }
-    else if(!objname.CompareTo("AliMCParticle")){
-      AliDebug(2, "Checking signal for MC track");
-      mctrack = dynamic_cast<AliMCParticle *>(fTrack);
-    }
-    else{
-      AliError("Input object not supported");
-      return kNoSignal;
-    }
-    if(!mctrack) return kNoSignal;
-    TParticle *ecand = mctrack->Particle(); 
-    if(TMath::Abs(ecand->GetPdgCode()) != 11) return kNoSignal; // electron candidate not true electron
-    Int_t motherLabel = TMath::Abs(ecand->GetFirstMother());
-    AliDebug(3, Form("mother label: %d\n", motherLabel));
-    if(!motherLabel) return kNoSignal; // mother track unknown
-    AliMCParticle *motherTrack = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(motherLabel));
-    if(!motherTrack) return kNoSignal;
-    TParticle *mparticle = motherTrack->Particle();
-    pid = TMath::Abs(mparticle->GetPdgCode());
+  Int_t daughterPDG = 0, motherLabel = 0;
+  if(TString(mctrack->IsA()->GetName()).CompareTo("AliMCParticle") == 0){
+    // case MC Particle
+    daughterPDG = TMath::Abs((dynamic_cast<const AliMCParticle *>(mctrack))->Particle()->GetPdgCode());
+    motherLabel = (dynamic_cast<const AliMCParticle *>(mctrack))->Particle()->GetFirstMother();
+    if(motherLabel >= 0 && motherLabel < fMCEvent->GetNumberOfTracks())
+      motherParticle = fMCEvent->GetTrack(motherLabel);
+    if(motherParticle)
+      pid = TMath::Abs((dynamic_cast<const AliMCParticle *>(motherParticle))->Particle()->GetPdgCode());
   } else {
-    // AOD Analysis - Different Data handling
-    AliAODMCParticle *aodmc = NULL;
-    if(!objname.CompareTo("AliAODTrack")){
-      AliAODTrack *aodtrack = dynamic_cast<AliAODTrack *>(fTrack);
-      Int_t aodlabel = TMath::Abs(aodtrack->GetLabel());
-      if(aodlabel >= fMCEvent->GetNumberOfTracks()) return kNoSignal;
-      aodmc = dynamic_cast<AliAODMCParticle *>(fMCEvent->GetTrack(aodlabel));
-    } else if(!objname.CompareTo("AliAODMCParticle")){
-      aodmc = dynamic_cast<AliAODMCParticle *>(fTrack);
-    } else{
-      AliError("Input object not supported");
-      return kNoSignal;
-    }
-    if(!aodmc) return kNoSignal;
-    Int_t motherLabel = TMath::Abs(aodmc->GetMother());
-    AliDebug(3, Form("mother label: %d\n", motherLabel));
-    if(!motherLabel || motherLabel >= fMCEvent->GetNumberOfTracks()) return kNoSignal;
-    AliAODMCParticle *aodmother = dynamic_cast<AliAODMCParticle *>(fMCEvent->GetTrack(motherLabel));
-    pid = aodmother->GetPdgCode();
+    // case AODMCParticle
+    daughterPDG = TMath::Abs((dynamic_cast<const AliAODMCParticle *>(mctrack))->GetPdgCode());
+    motherLabel = (dynamic_cast<const AliAODMCParticle *>(mctrack))->GetMother();
+    if(motherLabel >= 0 && motherLabel < fMCEvent->GetNumberOfTracks())
+      motherParticle = fMCEvent->GetTrack(motherLabel);
+    if(motherParticle)
+      pid = TMath::Abs((dynamic_cast<const AliAODMCParticle *>(motherParticle))->GetPdgCode());
   }
+  AliDebug(5, Form("Daughter PDG code: %d", daughterPDG));
+
+  if(!pid) return kNoSignal;
+
   // From here the two analysis modes go together
-  AliDebug(3, Form("PDG code: %d\n", pid));
+  AliDebug(5, Form("Mother PDG code: %d", pid));
 
-  // identify signal according to Pdg Code 
-  if((pid % 1000) / 100 == 4) return kCharm;    // charmed meson, 3rd position in pdg code == 4
+  // identify signal according to Pdg Code - barions higher ranked than mesons 
   if(pid / 1000 == 4) return kCharm;            // charmed baryon, 4th position in pdg code == 4
-  if((pid % 1000) / 100 == 5) return kBeauty;   // beauty meson, 3rd position in pdg code == 5
   if(pid / 1000 == 5) return kBeauty;           // beauty baryon, 4th position in pdg code == 5   
+  if((pid % 1000) / 100 == 4) return kCharm;    // charmed meson, 3rd position in pdg code == 4
+  if((pid % 1000) / 100 == 5) return kBeauty;   // beauty meson, 3rd position in pdg code == 5
   return kNoSignal;
 }
 
 //__________________________________________
+Bool_t AliAnalysisTaskHFE::IsGammaElectron(const AliVParticle * const track) const {
+  //
+  // Check for MC if the electron is coming from Gamma
+  //
+  if(!fMCEvent) return kFALSE;
+  const AliVParticle *motherParticle = NULL, *mctrack = NULL;
+  TString objectType = track->IsA()->GetName();
+  if(objectType.CompareTo("AliESDtrack") == 0 || objectType.CompareTo("AliAODTrack") == 0){
+    // Reconstructed track
+    if(track->GetLabel())
+      mctrack = fMCEvent->GetTrack(TMath::Abs(track->GetLabel()));
+  } else {
+    // MCParticle
+    mctrack = track;
+  }
+
+  if(!mctrack) return kFALSE;
+  
+  Int_t motherPDG = 0;
+  if(TString(mctrack->IsA()->GetName()).CompareTo("AliMCParticle") == 0){
+    // case MC Particle
+    motherParticle = fMCEvent->GetTrack((dynamic_cast<const AliMCParticle *>(mctrack)->Particle()->GetFirstMother()));
+    if(motherParticle)
+      motherPDG = TMath::Abs((dynamic_cast<const AliMCParticle *>(motherParticle))->Particle()->GetPdgCode());
+  } else {
+    // case AODMCParticle
+    motherParticle = fMCEvent->GetTrack((dynamic_cast<const AliAODMCParticle *>(mctrack))->GetMother());
+    if(motherParticle)
+      motherPDG = TMath::Abs((dynamic_cast<const AliAODMCParticle *>(motherParticle))->GetPdgCode());
+  }
+  if(motherPDG!=22) return kFALSE;
+  else return kTRUE;
+}
+//____________________________________________________________
+Bool_t AliAnalysisTaskHFE::FillProductionVertex(const AliVParticle * const track) const{
+  //
+  // Find the production vertex of the associated MC track
+  //
+  if(!fMCEvent) return kFALSE;
+  const AliVParticle *mctrack = NULL;
+  TString objectType = track->IsA()->GetName();
+  if(objectType.CompareTo("AliESDtrack") == 0 || objectType.CompareTo("AliAODTrack") == 0){
+    // Reconstructed track
+    mctrack = fMCEvent->GetTrack(TMath::Abs(track->GetLabel()));
+  } else {
+    // MCParticle
+    mctrack = track;
+  }
+
+  if(!mctrack) return kFALSE;
+
+  Double_t xv = 0.0;
+  Double_t yv = 0.0;
+  if(TString(mctrack->IsA()->GetName()).CompareTo("AliMCParticle") == 0){
+    // case MCParticle
+    xv =  (dynamic_cast<const AliMCParticle *>(mctrack)->Xv());
+    yv =  (dynamic_cast<const AliMCParticle *>(mctrack)->Yv());
+       
+  } else {
+    // case AODMCParticle
+    xv =  (dynamic_cast<const AliAODMCParticle *>(mctrack)->Xv());
+    yv =  (dynamic_cast<const AliAODMCParticle *>(mctrack)->Yv());
+  }
+
+  //printf("xv %f, yv %f\n",xv,yv);
+  TH2F *test = dynamic_cast<TH2F*>(fQA->FindObject("radius"));
+  if(!test) return kFALSE;
+  else {
+    test->Fill(TMath::Abs(xv),TMath::Abs(yv));
+  }
+
+  return kTRUE;
+
+}
+//__________________________________________
 void AliAnalysisTaskHFE::SwitchOnPlugin(Int_t plug){
   //
   // Switch on Plugin
@@ -1169,29 +1402,68 @@ void AliAnalysisTaskHFE::SwitchOnPlugin(Int_t plug){
     default: AliError("Unknown Plugin");
   };
 }
+//_______________________________________________
+void AliAnalysisTaskHFE::SetWeightFactors(TH3D * const weightFactors){
+  //
+  // Set the histos with the weights for the efficiency maps
+  //
+  fWeighting = kTRUE;
+  fWeightFactors = weightFactors;
+}
+//_______________________________________________
+void AliAnalysisTaskHFE::SetWeightFactorsFunction(TF1 * const weightFactorsFunction){
+  //
+  // Set the histos with the weights for the efficiency maps
+  //
+  fWeighting = kTRUE;
+  fWeightFactorsFunction = weightFactorsFunction;
+  //printf("SetWeightFactors\n");
+}
+//_______________________________________________
+Double_t AliAnalysisTaskHFE::FindWeight(Double_t pt, Double_t eta, Double_t phi) const {
+  //
+  // Find the weight corresponding to pt eta and phi in the TH3D
+  //
+  Double_t weight = 1.0;
+  if(fWeightFactors) {
+    
+    TAxis *ptaxis = fWeightFactors->GetXaxis();
+    TAxis *etaaxis = fWeightFactors->GetYaxis();
+    TAxis *phiaxis = fWeightFactors->GetZaxis();
+    
+    Int_t ptbin = ptaxis->FindBin(pt);
+    Int_t etabin = etaaxis->FindBin(eta);
+    Int_t phibin = phiaxis->FindBin(phi);
+
+
+    weight = fWeightFactors->GetBinContent(ptbin,etabin,phibin);
+  }
+  else if(fWeightFactorsFunction) {
+    
+    weight = fWeightFactorsFunction->Eval(pt,eta,phi);
+    //printf("pt %f and weight %f\n",pt,weight);
+
+  }
 
+  //printf("pt %f, eta %f, phi %f, weight %f\n",pt,eta,phi,weight);
+  
+  return weight;  
+
+}
 //__________________________________________
-Bool_t AliAnalysisTaskHFE::ProcessCutStep(Int_t cutStep, AliVParticle *track, Double_t *container, Bool_t signal, Bool_t alreadyseen){
+Bool_t AliAnalysisTaskHFE::ProcessCutStep(Int_t cutStep, AliVParticle *track, Double_t *container, Bool_t signal, Bool_t alreadyseen,Double_t weight){
   //
   // Check single track cuts for a given cut step
   // Fill the particle container
   //
   if(!fCFM->CheckParticleCuts(cutStep, track)) return kFALSE;
   if(signal) {
-    fCFM->GetParticleContainer()->Fill(container, cutStep + 2*AliHFEcuts::kNcutStepsESDtrack);
-    fCFM->GetParticleContainer()->Fill(&container[4], cutStep);
+    fCFM->GetParticleContainer()->Fill(container, cutStep + 2*AliHFEcuts::kNcutStepsESDtrack,weight);
+    fCFM->GetParticleContainer()->Fill(&container[5], cutStep,weight);
     if(alreadyseen) {
-      fCFM->GetParticleContainer()->Fill(&container[4], cutStep + AliHFEcuts::kNcutStepsESDtrack);
+      fCFM->GetParticleContainer()->Fill(&container[5], cutStep + AliHFEcuts::kNcutStepsESDtrack,weight);
     }
   }
   return kTRUE;
 }
 
-//__________________________________________
-void AliAnalysisTaskHFE::SetTPCBetheBlochParameters(Double_t *pars){
-  //
-  // Set Bethe-Bloch Parameters for TPC PID
-  //
-  fPID->SetTPCBetheBlochParameters(pars);
-}
-
index 207410e..84ef254 100644 (file)
@@ -40,6 +40,8 @@ class AliMCEvent;
 class AliVParticle;
 class TH1I; 
 class TList;
+class TH3D;
+class TF1;
 
 class AliAnalysisTaskHFE : public AliAnalysisTaskSE{
   public:
@@ -53,22 +55,30 @@ class AliAnalysisTaskHFE : public AliAnalysisTaskSE{
       kIsElecBackGround = 2,
       kPostProcess = 3
     };
+    enum CreationProcess_t{
+      kSignalCharm = 0,
+      kSignalBeauty = 1,
+      kGammaConv = 2,
+      kOther = 3
+    };
     AliAnalysisTaskHFE();
     AliAnalysisTaskHFE(const char * name);
     AliAnalysisTaskHFE(const AliAnalysisTaskHFE &ref);
     AliAnalysisTaskHFE& operator=(const AliAnalysisTaskHFE &ref);
+    virtual void Copy(TObject &o) const;
     virtual ~AliAnalysisTaskHFE();
 
     virtual void UserCreateOutputObjects();
     virtual void UserExec(Option_t *);
     virtual void Terminate(Option_t *);
 
+    virtual Bool_t IsEventInBinZero();
+
     Bool_t IsQAOn(Int_t qaLevel) const { return TESTBIT(fQAlevel, qaLevel); };
     Bool_t IsAODanalysis() const { return TestBit(kAODanalysis); };
     Bool_t IsESDanalysis() const { return !TestBit(kAODanalysis); };
     Bool_t HasMCData() const { return TestBit(kHasMCdata); }
     Bool_t GetPlugin(Int_t plug) const { return TESTBIT(fPlugins, plug); };
-    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); };
@@ -77,9 +87,10 @@ class AliAnalysisTaskHFE : public AliAnalysisTaskSE{
     void SetPIDdetectors(Char_t * const detectors){ fPIDdetectors = detectors; }
     void SetPIDStrategy(UInt_t strategy) { fPIDstrategy = strategy; }
     void AddPIDdetector(TString detector);
-    void SetTPCBetheBlochParameters(Double_t *pars);
     void SetAODAnalysis() { SetBit(kAODanalysis, kTRUE); };
     void SetESDAnalysis() { SetBit(kAODanalysis, kFALSE); };
+    void SetWeightFactors(TH3D * const weightFactors);
+    void SetWeightFactorsFunction(TF1 * const weightFactorsFunction);
     void PrintStatus() const;
  
   private:
@@ -106,20 +117,29 @@ class AliAnalysisTaskHFE : public AliAnalysisTaskSE{
         Int_t *fLast;         // Pointer to the last entry
         Int_t *fCurrent;      // Current entry to mimic an iterator
     };
+
+    Bool_t IsGammaElectron(const AliVParticle * const track) const;
+    Int_t  IsSignalElectron(const AliVParticle * const track) const;
+    Bool_t FillProductionVertex(const AliVParticle * const track) const;
+    Double_t FindWeight(Double_t pt, Double_t eta, Double_t phi) const;
     void MakeParticleContainer();
     void MakeEventContainer();
     void ProcessMC();
     void ProcessESD();
     void ProcessAOD();
     Bool_t ProcessMCtrack(AliVParticle *track);
-    Bool_t ProcessCutStep(Int_t cutStep, AliVParticle *track, Double_t *container, Bool_t signal, Bool_t alreadyseen);
+    Bool_t ProcessCutStep(Int_t cutStep, AliVParticle *track, Double_t *container, Bool_t signal, Bool_t alreadyseen,Double_t weight);
     
     ULong_t fQAlevel;                     // QA level
     TString fPIDdetectors;                // Detectors for Particle Identification
     UInt_t fPIDstrategy;                  // PID Strategy
     Double_t fTPCBetheBlochParameters[5]; // TPC Bethe-Bloch Parameters
     UShort_t fPlugins;                    // Enabled Plugins
+    Bool_t  fWeighting;                   // Weighting or not for the efficiency maps
+    TH3D *fWeightFactors;                 // Weight factors
+    TF1  *fWeightFactorsFunction;         // Weight factors
     AliCFManager *fCFM;                   //! Correction Framework Manager
+    AliCFContainer * fHadronicBackground; //! Container for hadronic Background
     TList *fCorrelation;                  //! response matrix for unfolding  
     THnSparseF *fPIDperformance;          //! info on contamination and yield of electron spectra
     THnSparseF *fSignalToBackgroundMC;    //! Signal To Background Studies on pure MC information
@@ -137,7 +157,7 @@ class AliAnalysisTaskHFE : public AliAnalysisTaskSE{
     TList *fHistELECBACKGROUND;           //! Output container for electron background analysis
 //    AliHFEcollection *fQAcoll;            //! collection class for basic QA histograms
 
-    ClassDef(AliAnalysisTaskHFE, 1)       // The electron Analysis Task
+    ClassDef(AliAnalysisTaskHFE, 2)       // The electron Analysis Task
 };
 #endif
 
index 79eac72..e5573ff 100644 (file)
 //
 #include <TH1I.h>
 #include <TList.h>
+#include <TFile.h>
 
 #include "AliAnalysisManager.h"
 #include "AliMCEventHandler.h"
-#include "AliLog.h"
-#include "AliAnalysisTaskHFEpidQA.h"
 #include "AliHFEpidQA.h"
-#include "AliESDEvent.h"
-#include "AliMCEvent.h"
+#include "AliHFEtools.h"
+#include "AliESDInputHandler.h"
+
+#include "AliHFEtrdPIDqa.h"
+
+#include "AliAnalysisTaskHFEpidQA.h"
 
 ClassImp(AliAnalysisTaskHFEpidQA)
 
 AliAnalysisTaskHFEpidQA::AliAnalysisTaskHFEpidQA():
-    AliAnalysisTaskSE("pidQAtask")
+  AliAnalysisTaskSE("pidQAtask")
   , fPIDqa(NULL)
   , fOutput(NULL)
   , fEvents(NULL)
+  , fNNref(NULL)
 {
   //
   // Default Constructor
   //
-  DefineOutput(1, TList::Class());
 }
 
 AliAnalysisTaskHFEpidQA::AliAnalysisTaskHFEpidQA(const Char_t *name):
-    AliAnalysisTaskSE(name)
+  AliAnalysisTaskSE(name)
   , fPIDqa(NULL)
   , fOutput(NULL)
   , fEvents(NULL)
+  , fNNref(NULL)
 {
   //
   // Default Constructor
   //
   DefineOutput(1, TList::Class());
+
 }
 
 AliAnalysisTaskHFEpidQA::~AliAnalysisTaskHFEpidQA(){
@@ -79,6 +84,7 @@ void AliAnalysisTaskHFEpidQA::UserCreateOutputObjects(){
   fPIDqa = new AliHFEpidQA;
   if(HasV0pidQA()) fPIDqa->SetV0pidQA();
   if(HasRecalculateTRDpid()) fPIDqa->SetRecalculateTRDpid();
+  if(fNNref) fPIDqa->SetNNref(fNNref);
   fPIDqa->Init();
 
   TList *tmp = fPIDqa->GetOutput();
@@ -96,14 +102,15 @@ void AliAnalysisTaskHFEpidQA::UserCreateOutputObjects(){
     fOutput->Add(tmp);
   }
 
-  
+  // Add TRD PID QA object to the output
+  fOutput->Add(fPIDqa->GetTRDQA());
 }
+
 Bool_t AliAnalysisTaskHFEpidQA::UserNotify(){
-   // DEBUG
+  // DEBUG
   //printf("*****\n");
   //printf(" -D Current File Name: %s \n", CurrentFileName());
   return AliAnalysisTask::Notify();
-
 }
 
 void AliAnalysisTaskHFEpidQA::UserExec(Option_t *){
@@ -111,15 +118,21 @@ void AliAnalysisTaskHFEpidQA::UserExec(Option_t *){
   // Event Loop
   // 
   AliMCEventHandler* mcHandler = (dynamic_cast<AliMCEventHandler*>(AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler()));
+  AliESDInputHandler *inh = dynamic_cast<AliESDInputHandler *>(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler());
+  AliESDpid *workingPID = NULL;
+  if(inh && (workingPID = inh->GetESDpid()))
+    fPIDqa->SetESDpid(workingPID);
+  else fPIDqa->SetESDpid(AliHFEtools::GetDefaultPID(mcHandler ? kTRUE : kFALSE));
+  
   // check the MC data
   if(fMCEvent && !mcHandler ) return;
   if(fMCEvent &&  !mcHandler->InitOk() ) return;
   if(fMCEvent &&  !mcHandler->TreeK() ) return;
   if(fMCEvent &&  !mcHandler->TreeTR() ) return;
   if(fMCEvent) fPIDqa->SetMCEvent(fMCEvent);
-  fPIDqa->SetRun((dynamic_cast<AliESDEvent*>(fInputEvent))->GetRunNumber());
-  fPIDqa->SetT0((dynamic_cast<AliESDEvent*>(fInputEvent))->GetT0());
-  fPIDqa->Process(fInputEvent);
+  
+  fPIDqa->SetEvent(fInputEvent);
+  fPIDqa->Process();
   fEvents->Fill(1.1);
   PostData(1, fOutput);
 }
index 4b2e6c6..2b08443 100644 (file)
 
 class TH1;
 class TList;
+class TFile;
+
+class AliLog;
+class AliMCEvent;
 
 class AliHFEpidQA;
 
@@ -45,6 +49,8 @@ class AliAnalysisTaskHFEpidQA : public AliAnalysisTaskSE{
     void SetV0pidQA(Bool_t v0pidQA = kTRUE) { SetBit(kV0pidQA, v0pidQA); };
     void SetRecalculateTRDpid(Bool_t recal = kTRUE) { SetBit(kRecalculateTRDpid, recal); };
 
+    void SetNNref(TFile *f) { fNNref = f; };
+
   private:
     enum{
       kV0pidQA = BIT(22),
@@ -55,6 +61,7 @@ class AliAnalysisTaskHFEpidQA : public AliAnalysisTaskSE{
     AliHFEpidQA *fPIDqa;    //! The heart of the analysis  
     TList *fOutput;         //! Container for output histos
     TH1 *fEvents;           //! Number of Events
+    TFile  *fNNref;         //  reference file for NN
 
     ClassDef(AliAnalysisTaskHFEpidQA, 1)
 };
index 9956fa2..a2b1eed 100644 (file)
 //    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 "AliHFEV0cuts.h"
+#include "AliHFEV0info.h"
+#include "AliHFEcollection.h"
+
 #include "AliHFEV0pid.h"
 ClassImp(AliHFEV0pid)
 
@@ -57,8 +52,14 @@ AliHFEV0pid::AliHFEV0pid():
   , fPionsL(NULL)
   , fKaons(NULL)
   , fProtons(NULL)
+  , fGammas(NULL)
+  , fK0s(NULL)
+  , fLambdas(NULL)
+  , fAntiLambdas(NULL)
   , fIndices(NULL)
   , fQA(NULL)
+  , fV0cuts(NULL)
+  , fOutput(NULL)
 {
   //
   // Default constructor
@@ -68,7 +69,20 @@ AliHFEV0pid::AliHFEV0pid():
   fPionsL = new TObjArray();
   fKaons = new TObjArray();
   fProtons = new TObjArray();
-  fIndices = new AliHFEV0pidTrackIndex;
+
+  fElectrons->SetOwner();
+  fPionsK0->SetOwner();
+  fProtons->SetOwner();
+  fPionsL->SetOwner();
+  fKaons->SetOwner();
+  
+  fGammas = new TObjArray();
+  fK0s = new TObjArray();
+  fLambdas = new TObjArray();
+  fAntiLambdas = new TObjArray();
+
+  fIndices = new AliHFEV0pidTrackIndex();
+  
 }
 
 //____________________________________________________________
@@ -77,15 +91,21 @@ 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(fGammas) delete fGammas;
+  if(fK0s) delete fK0s;
+  if(fLambdas) delete fLambdas;
+  if(fAntiLambdas) delete fAntiLambdas;
+
   if(fIndices) delete fIndices;
   if(fQA) delete fQA;
+  if(fV0cuts) delete fV0cuts;
+  if(fOutput) delete fOutput;
 }
 
 //____________________________________________________________
@@ -93,19 +113,20 @@ void AliHFEV0pid::InitQA(){
   //
   // Initialize QA histograms
   //
+  
+  fOutput = new TList();
+
+  fV0cuts = new AliHFEV0cuts();
+  fV0cuts->Init("V0cuts");
+
   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);
+    fQA->CreateTH1F("h_nV0s", "No. of found and accepted V0s", 5, -0.5, 4.5);
 
     // QA histograms for invariant mass
     fQA->CreateTH1F("h_InvMassGamma", "Gamma invariant mass; inv mass [GeV/c^{2}]; counts", 100, 0, 0.25);
-    fQA->CreateTH1F("h_InvMassK0s", "K0s invariant mass; inv mass [GeV/c^{2}]; counts", 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_InvMassK0s", "K0s invariant mass; inv mass [GeV/c^{2}]; counts", 200, 0.4, 0.65);
     fQA->CreateTH1F("h_InvMassLambda", "Lambda invariant mass; inv mass [GeV/c^{2}]; counts", 100, 1.05, 1.15);
     
     // QA histograms for p distribution (of the daughters)
@@ -114,31 +135,12 @@ void AliHFEV0pid::InitQA(){
     fQA->CreateTH1F("h_P_Lpion", "P distribution of the Lambda pions; p (GeV/c); counts", 100, 0.1, 10);
     fQA->CreateTH1F("h_P_Lproton", "P distribution of the Lambda protons; p (GeV/c); counts", 100, 0.1, 10);
 
-    // 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.);
+    fQA->CreateTH1F("h_Pt_Lambda", "Pt of the Lambda; p_{T} (GeV/c); counts", 100, 0, 10);    
+    
     
-    // 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);
   }
 }
 
@@ -149,17 +151,21 @@ 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()));
+  if(!fPrimaryVertex) return;
+  fV0cuts->SetInputEvent(fInputEvent);
+  fV0cuts->SetPrimaryVertex(fPrimaryVertex);
   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) continue;
       if(!esdV0->GetOnFlyStatus()) continue; // Take only V0s from the On-the-fly v0 finder
       v0status = ProcessV0(esdV0);
     } else {
@@ -168,6 +174,8 @@ void AliHFEV0pid::Process(AliVEvent * const inputEvent){
       AliAODv0 *aodV0 = (dynamic_cast<AliAODEvent *>(fInputEvent))->GetV0(iv0);
       if(aodV0->GetOnFlyStatus()) continue; // Take only V0s from the On-the-fly v0 finder
       v0status = ProcessV0(aodV0);
+      if(kUndef != v0status){
+      }
     }
     switch(v0status){
     case kRecoGamma: nGamma++; break;
@@ -177,6 +185,7 @@ void AliHFEV0pid::Process(AliVEvent * const inputEvent){
     };
   }
 
+
   AliDebug(1, Form("Number of gammas  : %d", nGamma));
   AliDebug(1, Form("Number of K0s     : %d", nK0s));
   AliDebug(1, Form("Number of Phis    : %d", nPhi));
@@ -200,21 +209,35 @@ Int_t AliHFEV0pid::ProcessV0(TObject *v0){
   //
   AliVTrack* daughter[2];
   daughter[0] = dynamic_cast<AliVTrack *>(fInputEvent->GetTrack((dynamic_cast<AliESDv0 *>(v0))->GetPindex()));
-  daughter[1] = dynamic_cast<AliVTrack *>(fInputEvent->GetTrack((dynamic_cast<AliESDv0 *>(v0))->GetPindex()));
+  daughter[1] = dynamic_cast<AliVTrack *>(fInputEvent->GetTrack((dynamic_cast<AliESDv0 *>(v0))->GetNindex()));
   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;
+      // check common single track cuts
+      if(!fV0cuts->TrackCutsCommon(dynamic_cast<AliESDtrack*>(daughter[i]))) return kUndef;
     }    
+    // check commom V0 cuts
+    if(!fV0cuts->V0CutsCommon(dynamic_cast<AliESDv0 *>(v0))) return kUndef;
   }
 
-  if(IsGammaConv(v0)) return kRecoGamma;
-  else if(IsK0s(v0)) return kRecoK0s;
-  else if(IsLambda(v0)) return kRecoLambda;
+
+  // store the resutls
+  if(IsGammaConv(v0)){
+    fQA->Fill("h_nV0s", kRecoGamma);
+    return kRecoGamma;
+  }
+  else if(IsK0s(v0)){
+    fQA->Fill("h_nV0s", kRecoK0s);
+    return kRecoK0s;
+  }
+  else if(IsLambda(v0)){
+    fQA->Fill("h_nV0s", kRecoLambda);    
+    return kRecoLambda;
+  }
   else return kUndef;
-  
-  
+    
 }
 //____________________________________________________________
 void AliHFEV0pid::Flush(){
@@ -222,13 +245,12 @@ void AliHFEV0pid::Flush(){
   // Clear the Lists
   //
   AliDebug(1, "Flushing containers");
-  fProtons->Clear();
-  fPionsK0->Clear();
-  fPionsL->Clear();
-  fElectrons->Clear();
+  fProtons->Delete();
+  fPionsK0->Delete();
+  fPionsL->Delete();
+  fElectrons->Delete();
   fIndices->Flush();
 }
-
 //____________________________________________________________
 Bool_t AliHFEV0pid::IsGammaConv(TObject *v0){
   //
@@ -237,21 +259,22 @@ Bool_t AliHFEV0pid::IsGammaConv(TObject *v0){
   AliVTrack* daughter[2];
   Int_t pIndex = 0, nIndex = 0;
   Double_t invMass = 0.;
+  Double_t mPt = 0.;
+  Int_t v0id = -1;
   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);
-    //..
-
+    v0id = esdV0->GetLabel();
+    // apply FULL gamma cuts
+    if(!fV0cuts->GammaCuts(esdV0)) return kFALSE;
+    invMass = esdV0->GetEffMass(AliPID::kElectron, AliPID::kElectron);
     pIndex = esdV0->GetPindex();
     nIndex = esdV0->GetNindex();
+    mPt = esdV0->Pt();
   } else {
     // AOD Analysis - not possible to cut
     AliAODv0 *aodV0 = dynamic_cast<AliAODv0 *>(v0);
+    v0id = aodV0->GetID();
     pIndex = aodV0->GetPosID();
     nIndex = aodV0->GetNegID();
     invMass = aodV0->InvMass2Prongs(0, 1, kElectron, kElectron);
@@ -259,61 +282,52 @@ Bool_t AliHFEV0pid::IsGammaConv(TObject *v0){
   daughter[0] = dynamic_cast<AliVTrack *>(fInputEvent->GetTrack(pIndex));
   daughter[1] = dynamic_cast<AliVTrack *>(fInputEvent->GetTrack(nIndex));
   if(!daughter[0] || !daughter[1]) return kFALSE;
+  // DEBUG
+  AliDebug(1, Form("Gamma identified, daughter IDs: %d,%d", daughter[0]->GetID(), daughter[1]->GetID()));
 
-  // 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();
+  // AFTER all gamma cuts
   fQA->Fill("h_Pt_Gamma", mPt);
-  Int_t ptBin = (int)(mPt*10.0);
+  fQA->Fill("h_InvMassGamma", invMass);
 
-  if(fQA) fQA->Fill("h_InvMassGamma", invMass);
-  if(invMass > 0.05) return kFALSE; 
-  fQA->Fill("h_InvMassGamma_pt", ptBin+1, invMass);
-  
-  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]);
+    fElectrons->Add(new AliHFEV0info(daughter[0], daughter[1]->GetID(), v0id));
     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]);
+    fElectrons->Add(new AliHFEV0info(daughter[1], daughter[0]->GetID(), v0id));
     fIndices->Add(daughter[1]->GetID(), AliHFEV0pid::kRecoElectron);
   }
+  fGammas->Add(v0);
+  
   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;
+  Int_t v0id = -1;
   Double_t invMass = 0.;
+  Double_t mPt = 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);
+    if(!fV0cuts->K0Cuts(esdV0)) return kFALSE;
+    v0id = esdV0->GetLabel();
     pIndex = esdV0->GetPindex();
     nIndex = esdV0->GetNindex();
+    invMass = esdV0->GetEffMass(AliPID::kPion, AliPID::kPion);
+    mPt = esdV0->Pt();
   } else {
     // AOD Analysis - not possible to cut
     AliAODv0 *aodV0 = dynamic_cast<AliAODv0 *>(v0);
+    aodV0->GetID();
     pIndex = aodV0->GetPosID();
     nIndex = aodV0->GetNegID();
     invMass = aodV0->MassK0Short();
@@ -322,37 +336,24 @@ Bool_t AliHFEV0pid::IsK0s(TObject *v0){
   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);
+  fQA->Fill("h_InvMassK0s", 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()));
 
+  // AFTER all K0 cuts
   // 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]);
+    fPionsK0->Add(new AliHFEV0info(daughter[0], daughter[1]->GetID(), v0id));
     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]);
+    fPionsK0->Add(new AliHFEV0info(daughter[1], daughter[0]->GetID(), v0id));
     fIndices->Add(daughter[1]->GetID(), AliHFEV0pid::kRecoPionK0);
   }
+  fK0s->Add(v0);
   return kTRUE; 
 }
 
@@ -364,15 +365,12 @@ Bool_t AliHFEV0pid::IsPhi(TObject *v0){
 
   //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 {
@@ -388,473 +386,69 @@ 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;
+  Bool_t isLambda = kTRUE; // Lambda - kTRUE, Anti Lambda - kFALSE
+  Int_t v0id = -1;
   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);
-
+    v0id = esdV0->GetLabel();
+    if(!fV0cuts->LambdaCuts(esdV0,isLambda)) return kFALSE; 
+    if(fV0cuts->CheckSigns(esdV0)){
+      pIndex = esdV0->GetPindex();
+      nIndex = esdV0->GetNindex();
+    }
+    else{
+      pIndex = esdV0->GetNindex();
+      nIndex = esdV0->GetPindex();      
+    }
   } else {
     // PRELIMINARY - !!!
     // AOD Analysis - not possible to cut
     
     // again - two cases as above
     AliAODv0 *aodV0 = dynamic_cast<AliAODv0 *>(v0);
+    v0id = aodV0->GetID();
     pIndex = aodV0->GetPosID();
     nIndex = aodV0->GetNegID();
-    invMassEOD = aodV0->MassLambda();
-  }
-
+    invMass = 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;
+  
+  // lambda
+  if(isLambda){
+    if(!fIndices->Find(daughter[0]->GetID())){
+      fProtons->Add(new AliHFEV0info(daughter[0], daughter[1]->GetID(), v0id));
+      fIndices->Add(daughter[0]->GetID(), AliHFEV0pid::kRecoProton);
     }
-  }
-
-  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;
+    if(!fIndices->Find(daughter[1]->GetID())){
+      fPionsL->Add(new AliHFEV0info(daughter[1], daughter[0]->GetID(), v0id));
+      fIndices->Add(daughter[1]->GetID(), AliHFEV0pid::kRecoPionL);
     }
-  } 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;
-      }
+  // antilambda
+  else{
+    if(!fIndices->Find(daughter [1]->GetID())){
+      fProtons->Add(new AliHFEV0info(daughter[1], daughter[0]->GetID(), v0id));
+      fIndices->Add(daughter[1]->GetID(), AliHFEV0pid::kRecoProton);
+    }
+    if(!fIndices->Find(daughter [0]->GetID())){
+      fPionsL->Add(new AliHFEV0info(daughter[0], daughter[1]->GetID(), v0id));
+      fIndices->Add(daughter [0]->GetID(), AliHFEV0pid::kRecoPionL);
     }
-  } 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); 
+  if(isLambda) fLambdas->Add(v0);
+  else fAntiLambdas->Add(v0);
 
-  // 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)
@@ -988,81 +582,19 @@ Bool_t AliHFEV0pid::AliHFEV0pidTrackIndex::Find(Int_t index) const {
 }
 
 //____________________________________________________________
-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;
+TList *AliHFEV0pid::GetListOfQAhistograms(){
   //
-  //if (fRP[p1]+fRM[p2]<fRP[p2]+fRM[p1]){
-  //  m1 = fPM;
-  //  m2 = fPP;
-  //}
+  // Getter for V0 PID QA histograms
   //
-  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;
+  TList *tmp = fV0cuts->GetList();
+  tmp->SetName("V0cuts");
+  fOutput->Add(tmp);
+  if(fQA){
+    tmp = 0x0;
+    tmp = fQA->GetList();
+    tmp->SetName("V0pid");
+    fOutput->Add(tmp);
+  } 
+  return fOutput;
 }
index 1413ead..8d66402 100644 (file)
 #include <TObject.h>
 #endif
 
-#ifndef ALIHFECOLLECTION_H
-#include "AliHFEcollection.h"
-#endif
-
 class TObjArray;
 class TList;
+class TString;
 
 class AliESDv0;
 class AliESDtrack;
@@ -38,6 +35,9 @@ class AliKFVertex;
 class AliVEvent;
 class AliVTrack;
 
+class AliHFEV0cuts;
+class AliHFEcollection;
+
 class AliHFEV0pid : public TObject{
   public:
   enum{ // Reconstructed V0
@@ -50,22 +50,20 @@ class AliHFEV0pid : public TObject{
     };
     enum{ // Identified Daughter particles
       kRecoElectron = 0,
-           kRecoPionK0 = 1,
-           kRecoPionL = 2,
-           kRecoKaon = 3,
-           kRecoProton = 4
-    };
+       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);
+    void  Process(AliVEvent * const inputEvent);
     Int_t ProcessV0(TObject *v0);
-    void Flush();
+    void  Flush();
 
-    void InitQA();
-    inline TList *GetListOfQAhistograms();
+    void  InitQA();
+    TList *GetListOfQAhistograms();
 
     TObjArray *GetListOfElectrons() const { return fElectrons; }
     TObjArray *GetListOfPionsK0() const { return fPionsK0; }
@@ -73,82 +71,55 @@ class AliHFEV0pid : public TObject{
     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
-   
+    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); }; 
 
-  protected:
+ 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 IsLambda(TObject *v0);        
+    TList *GetV0pidQA(); 
 
-    Bool_t LooseRejectK0(AliESDv0 * const v0) const;
-    Bool_t LooseRejectLambda(AliESDv0 * const v0) const;
-    Bool_t LooseRejectGamma(AliESDv0 * const v0) const;
-
-  private:
+ 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
+    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
     };
-
     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
@@ -156,20 +127,19 @@ class AliHFEV0pid : public TObject{
     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
+
+    TObjArray   *fGammas;            // for MC purposes - list of found gammas
+    TObjArray   *fK0s;               // for MC purposes - list of found K0s
+    TObjArray   *fLambdas;           // for MC purposes - list of found lambdas
+    TObjArray   *fAntiLambdas;       // for MC purposes - list of found anti lambdas
+
     AliHFEV0pidTrackIndex *fIndices; // Container for Track indices
     AliHFEcollection *fQA;           // Collection of QA histograms
+    AliHFEV0cuts     *fV0cuts;       // separate class for studying and applying the V0 cuts
+    TList       *fOutput;            // collection list
 
     ClassDef(AliHFEV0pid, 1)          // V0 PID Class
 
 };
 
-//____________________________________________________________
-TList *AliHFEV0pid::GetListOfQAhistograms(){
-  //
-  // Get QA histograms
-  //
-  if(fQA)
-    return fQA->GetList();
-  return NULL;
-}
 #endif
index 3f6f618..517890a 100644 (file)
 
 #include "TIterator.h"
 
-#include "AliMCEvent.h"
 #include "AliVParticle.h"
 #include "AliESDtrack.h"
 #include "AliMCParticle.h"
+#include "AliMCEvent.h"
+
+#include "AliHFEcollection.h"
 
 #include "AliHFEV0pidMC.h"
 ClassImp(AliHFEV0pidMC)
@@ -34,64 +36,51 @@ ClassImp(AliHFEV0pidMC)
 //____________________________________________________________
   AliHFEV0pidMC::AliHFEV0pidMC():
     fMC(0x0)
-    , fColl(0x0)
+    , fColl(NULL)
+    , fV0cuts(NULL)
 {
   //
   // default constructor
   //
+
 }
 //____________________________________________________________
 AliHFEV0pidMC::~AliHFEV0pidMC(){
   //
   // destructor
   //
-  if(fColl) delete fColl;
+  if (fColl) delete fColl;
+  //if (fV0cuts) delete fV0cuts;
 }
 //____________________________________________________________
 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_Electron", "all electron candidates (no MC); p (GeV/c); counts", 100, 0.1, 10, 0);
+  fColl->CreateTH1F("h_PionK0", "all K0 pion candidates (no MC); p (GeV/c); counts", 100, 0.1, 10, 0);
+  fColl->CreateTH1F("h_PionL", "all Lambda pion candidates (no MC); p (GeV/c); counts", 100, 0.1, 10, 0);
+  fColl->CreateTH1F("h_Kaon", "all Kaon candidates (no MC); p (GeV/c); counts", 100, 0.1, 10, 0);
+  fColl->CreateTH1F("h_Proton", "all Lambda proton candidates (no MC); p (GeV/c); counts", 100, 0.1, 10, 0);
   
-  fColl->CreateTH1F("h_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->CreateTH1F("h_mis_Electron", "all NON electron candidates MC tagged; p (GeV/c); counts", 100, 0.1, 10, 0);
+  fColl->CreateTH1F("h_mis_PionK0", "all NON K0 pion candidates MC tagged; p (GeV/c); counts", 100, 0.1, 10, 0);
+  fColl->CreateTH1F("h_mis_PionL", "all NON Lambda pion candidates MC tagged ; p (GeV/c); counts", 100, 0.1, 10, 0);
+  fColl->CreateTH1F("h_mis_Kaon", "all NON Kaon candidates MC tagged; p (GeV/c); counts", 100, 0.1, 10, 0);
+  fColl->CreateTH1F("h_mis_Proton", "all NON Lambda proton candidates MC tagged; p (GeV/c); counts", 100, 0.1, 10, 0);  
 
-  fColl->CreateTH1Fvector1(5, "h_tag_Electron", "electron candidate MC tagged", 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->CreateTH1Fvector1(5, "h_tag_Electron", "electron candidate MC tagged; p (GeV/c); counts", 100, 0.1, 10, 0);
+  fColl->CreateTH1Fvector1(5, "h_tag_PionK0", "K0 pion candidate MC tagged; p (GeV/c); counts", 100, 0.1, 10, 0);
+  fColl->CreateTH1Fvector1(5, "h_tag_PionL", "Lambda pion candidate MC tagged; p (GeV/c); counts", 100, 0.1, 10, 0);
+  fColl->CreateTH1Fvector1(5, "h_tag_Kaon", "kaon candidate MC tagged; p (GeV/c); counts", 100, 0.1, 10, 0);
+  fColl->CreateTH1Fvector1(5, "h_tag_Proton", "Lambda proton candidate MC tagged; p (GeV/c); counts", 100, 0.1, 10, 0);
 
-  
-  fColl->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){
@@ -135,22 +124,22 @@ Bool_t  AliHFEV0pidMC::Process(TObjArray * const particles, Int_t type){
       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
+    // 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);
-    }
-       
 
+    // for every particle fill detailed information about the missidentified particles
+    sprintf(hname, "h_tag_%s", typeName[type]);       
+    Int_t aliPID = PDGtoAliPID(pdgD);
+    fColl->Fill(hname, aliPID, p);
     
   }// .. loop over array
   
@@ -197,3 +186,26 @@ Int_t AliHFEV0pidMC::PDGtoPIDmother(Int_t pdg) const {
   
   return -1;
 }
+//____________________________________________________________
+Int_t AliHFEV0pidMC::PDGtoAliPID(Int_t pdg) const {
+  //
+  // convert PDG to AliPID
+  //
+  
+  switch (TMath::Abs(pdg)){
+  case 11:
+    return 0; // electron 
+  case 13:
+    return 1; // muon
+  case 211:
+    return 2; // pion 
+  case 321:
+    return 3; // kaon 
+  case 2212:
+    return 4; // proton 
+  default:
+    return -1;
+  };
+  return -1;
+}
+
index f0c59a8..8efffce 100644 (file)
 #include <TObject.h>
 #endif
 
-#ifndef ALIHFECOLLECTION_H
-#include "AliHFEcollection.h"
-#endif
-
 class TList;
 
 class AliMCEvent;
 
+class AliHFEV0cuts;
+class AliHFEcollection;
 
 class AliHFEV0pidMC : public TObject {
 
@@ -52,9 +50,12 @@ class AliHFEV0pidMC : public TObject {
   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
+  Int_t PDGtoAliPID(Int_t pdg) const;         // convert PDG to AliPID
 
   AliMCEvent*         fMC;      // MC event
   AliHFEcollection*   fColl;    // Histogram collection
+  AliHFEV0cuts*       fV0cuts;  // V0 cut class
+
    ClassDef(AliHFEV0pidMC, 1)   // QA class for V0 PID
 };
 //____________________________________________________________
index 012cce6..ef9a6e0 100644 (file)
@@ -61,7 +61,7 @@ AliHFEcollection::AliHFEcollection():
   
 }
 //___________________________________________________________________
-AliHFEcollection::AliHFEcollection(char* name, char* title):
+AliHFEcollection::AliHFEcollection(const char* name, const char* title):
   TNamed(name, title)
   , fList(0x0)
 {
@@ -71,6 +71,7 @@ AliHFEcollection::AliHFEcollection(char* name, char* title):
   //
  
   fList = new THashList();
+  fList->SetName(Form("list_%s", name));
   if(!fList){
     AliError("Initialization of the list failed");
   }
@@ -130,7 +131,7 @@ AliHFEcollection::~AliHFEcollection(){
   AliInfo("DESTRUCTOR");
 }
 //___________________________________________________________________
-Bool_t AliHFEcollection::CreateTH1F(const char* name, const char* title, Int_t nBin, Float_t nMin, Float_t nMax){
+Bool_t AliHFEcollection::CreateTH1F(const char* name, const char* title, Int_t nBin, Float_t nMin, Float_t nMax, Int_t logAxis){
 
   //
   // Creates a TH1F histogram for the collection
@@ -142,11 +143,14 @@ Bool_t AliHFEcollection::CreateTH1F(const char* name, const char* title, Int_t n
   }
   else{
     fList->Add(new TH1F(name, title, nBin, nMin, nMax));
+    if(logAxis >= 0){
+      BinLogAxis(name, logAxis);
+    }
     return CheckObject(name);
   }
 }
 //___________________________________________________________________
-Bool_t AliHFEcollection::CreateTH2F(const char* name, const char* title, Int_t nBinX, Float_t nMinX, Float_t nMaxX, Int_t nBinY, Float_t nMinY, Float_t nMaxY){
+Bool_t AliHFEcollection::CreateTH2F(const char* name, const char* title, Int_t nBinX, Float_t nMinX, Float_t nMaxX, Int_t nBinY, Float_t nMinY, Float_t nMaxY, Int_t logAxis){
 
   //
   // Creates a TH2F histogram for the collection
@@ -157,10 +161,13 @@ Bool_t AliHFEcollection::CreateTH2F(const char* name, const char* title, Int_t n
     return kFALSE;
   }
   fList->Add(new TH2F(name, title, nBinX, nMinX, nMaxX, nBinY, nMinY, nMaxY));
+  if(logAxis >= 0){
+    BinLogAxis(name, logAxis);
+  }
   return CheckObject(name); 
 }
 //___________________________________________________________________
-Bool_t AliHFEcollection::CreateTH1Fvector1(Int_t X, const char* name, const char* title, Int_t nBin, Float_t nMin, Float_t nMax){
+Bool_t AliHFEcollection::CreateTH1Fvector1(Int_t X, const char* name, const char* title, Int_t nBin, Float_t nMin, Float_t nMax, Int_t logAxis){
 
   //
   // create a 1 dimensional array of size [X]
@@ -180,16 +187,16 @@ Bool_t AliHFEcollection::CreateTH1Fvector1(Int_t X, const char* name, const char
     hname.Append(Form("%s_[%d]", name, i));
     //cout<<" -D: name: "<<name.str().c_str()<<endl;
     //cout<<" -D: nBin: "<<_nBin<<" ,Min: "<<_nMin<<" , Max: "<<_nMax<<endl;
-    CreateTH1F(hname.Data(), title, nBin, nMin, nMax);
+    CreateTH1F(hname.Data(), title, nBin, nMin, nMax, logAxis);
     if(!CheckObject(hname.Data())){
-      AliError(Form("Not possible to create object: %s", hname.Data()));
+      AliError(Form("Not possible to create object: ", hname.Data()));
       return kFALSE;
     }    
   }
   return kTRUE;  
 }
 //___________________________________________________________________
-Bool_t AliHFEcollection::CreateTH2Fvector1(Int_t X, const char* name, const char* title, Int_t nBinX, Float_t nMinX, Float_t nMaxX, Int_t nBinY, Float_t nMinY, Float_t nMaxY){
+Bool_t AliHFEcollection::CreateTH2Fvector1(Int_t X, const char* name, const char* title, Int_t nBinX, Float_t nMinX, Float_t nMaxX, Int_t nBinY, Float_t nMinY, Float_t nMaxY, Int_t logAxis){
 
   //
   // create a 1 dimensinal array of TH2F histograms with size [X]
@@ -209,7 +216,7 @@ Bool_t AliHFEcollection::CreateTH2Fvector1(Int_t X, const char* name, const char
     hname.Append(Form("%s_[%d]", name, i));
     //cout<<" -D: name: "<<name<<endl;
     //cout<<" -D: nBin: "<<_nBin<<" ,Min: "<<_nMin<<" , Max: "<<_nMax<<endl;
-    CreateTH2F(hname.Data(), title, nBinX, nMinX, nMaxX, nBinY, nMinY, nMaxY);
+    CreateTH2F(hname.Data(), title, nBinX, nMinX, nMaxX, nBinY, nMinY, nMaxY, logAxis);
     if(!CheckObject(hname.Data())){
       AliError(Form("Not possible to create object: %s", hname.Data()));
       return kFALSE;
@@ -218,7 +225,7 @@ Bool_t AliHFEcollection::CreateTH2Fvector1(Int_t X, const char* name, const char
   return kTRUE;  
 }
 //___________________________________________________________________
-Bool_t AliHFEcollection::CreateTH1Fvector2(Int_t X, Int_t Y, const char* name, const char* title, Int_t nBin, Float_t nMin, Float_t nMax){
+Bool_t AliHFEcollection::CreateTH1Fvector2(Int_t X, Int_t Y, const char* name, const char* title, Int_t nBin, Float_t nMin, Float_t nMax, Int_t logAxis){
 
   //
   // create a 2 dimensional array of histograms of size [X, Y]
@@ -239,7 +246,7 @@ Bool_t AliHFEcollection::CreateTH1Fvector2(Int_t X, Int_t Y, const char* name, c
       hname.Append(Form("%s_[%d][%d]", name, i, j));
       //cout<<" -D: name: "<<name.str().c_str()<<endl;
       //cout<<" -D: nBin: "<<_nBin<<" ,Min: "<<_nMin<<" , Max: "<<_nMax<<endl;
-      CreateTH1F(hname.Data(), title, nBin, nMin, nMax);
+      CreateTH1F(hname.Data(), title, nBin, nMin, nMax, logAxis);
       if(!CheckObject(hname.Data())){
              AliError(Form("Not possible to create object: %s", hname.Data()));
              return kFALSE;
@@ -301,11 +308,12 @@ Bool_t AliHFEcollection::Fill(const char* name, Double_t v){
   // fill function for one TH1 histograms
   //
 
-   if(!CheckObject(name)){
-    AliError(Form("Not possible to return pointer to the object '%s'\n", name));
+  if(!CheckObject(name)){
+    AliError(Form("Not possible to fill the object '%s', the object does not exist\n", name));
     return kFALSE;
   }
 
+
   // chack the possible object types
   if(fList->FindObject(name)->InheritsFrom("TH1")){
     (dynamic_cast<TH1F*>(fList->FindObject(name)))->Fill(v);
@@ -316,6 +324,15 @@ Bool_t AliHFEcollection::Fill(const char* name, Double_t v){
 
 }
 //___________________________________________________________________
+Bool_t AliHFEcollection::Fill(const char* name, Int_t v){
+
+  //
+  // fill function for one TH1 histograms for integer numbers
+  //
+
+  return Fill(name, v*1.0);
+}
+//___________________________________________________________________
 Bool_t AliHFEcollection::Fill(const char* name, Int_t X, Double_t v){
 
   //
@@ -368,8 +385,8 @@ Bool_t AliHFEcollection::Fill(const char* name, Double_t v1, Double_t v2){
   // fill function for TH2 objects
   //
 
-   if(!CheckObject(name)){
-    AliError(Form("Not possible to return pointer to the object '%s'\n", name));
+  if(!CheckObject(name)){
+    AliError(Form("Not possible to fill the object '%s', the object does not exist\n", name));
     return kFALSE;
   }
 
@@ -386,7 +403,24 @@ Bool_t AliHFEcollection::Fill(const char* name, Double_t v1, Double_t v2){
   return kFALSE;
   
 }
+//___________________________________________________________________
+Bool_t AliHFEcollection::Fill(const char* name, Double_t* entry, Double_t weight){
+  //
+  // Fill a THnSparse object
+  //
+
+  if(!CheckObject(name)){
+    AliError(Form("Not possible to fill the object '%s', the object does not exist\n", name));
+    return kFALSE;
+  }
+  
+   if(fList->FindObject(name)->InheritsFrom("THnSparse")){
+     (dynamic_cast<THnSparseF*>(fList->FindObject(name)))->Fill(entry, weight);
+     return kTRUE;
+   }
+   return kFALSE;
 
+}
 //___________________________________________________________________
 Bool_t AliHFEcollection::CheckObject(const char* name){
 
@@ -461,6 +495,10 @@ Bool_t AliHFEcollection::BinLogAxis(const char* name, Int_t dim){
   Int_t bins = axis->GetNbins();
 
   Double_t from = axis->GetXmin();
+  if(from <= 0){
+    AliError(Form(" Log binning not possible for object '%s'because the '%d' axis starts from '%f\n'", name, dim, from));
+    return kFALSE;
+  }
   Double_t to = axis->GetXmax();
   Double_t *newBins = new Double_t[bins+1];
   newBins[0] = from;
@@ -469,7 +507,7 @@ Bool_t AliHFEcollection::BinLogAxis(const char* name, Int_t dim){
     newBins[i] = factor * newBins[i-1];
   }
   axis->Set(bins, newBins);
-  delete [] newBins;
+  delete newBins;
 
   return kTRUE;
 
index 639ee7d..3f673b3 100644 (file)
@@ -41,7 +41,7 @@ class AliHFEcollection : public TNamed{
 
  public:
   AliHFEcollection();
-  AliHFEcollection(char* name, char* title);
+  AliHFEcollection(const char* name, const char* title);
   AliHFEcollection(const AliHFEcollection &c);
   AliHFEcollection &operator=(const AliHFEcollection &c);
   virtual ~AliHFEcollection();
@@ -50,13 +50,13 @@ class AliHFEcollection : public TNamed{
   virtual void Browse(TBrowser *b);
 
   // Set & Create functions
-  Bool_t CreateTH1F(const char* name, const char* title, Int_t nBin, Float_t nMin, Float_t nMax);
+  Bool_t CreateTH1F(const char* name, const char* title, Int_t nBin, Float_t nMin, Float_t nMax, Int_t logAxis = -1);
 
-  Bool_t CreateTH2F(const char* name, const char* title, Int_t nBinX, Float_t nMinX, Float_t nMaxX, Int_t nBinY, Float_t nMinY, Float_t nMaxY);
+  Bool_t CreateTH2F(const char* name, const char* title, Int_t nBinX, Float_t nMinX, Float_t nMaxX, Int_t nBinY, Float_t nMinY, Float_t nMaxY, Int_t logAxis = -1);
 
-  Bool_t CreateTH1Fvector1(Int_t X, const char* name, const char* title, Int_t nBin, Float_t nMin, Float_t nMax);
-  Bool_t CreateTH1Fvector2(Int_t X, Int_t Y, const char* name, const char* title, Int_t nBin, Float_t nMin, Float_t nMax);
-  Bool_t CreateTH2Fvector1(Int_t X, const char* name, const char* title, Int_t nBinX, Float_t nMinX, Float_t nMaxX, Int_t nBinY, Float_t nMinY, Float_t nMaxY);
+  Bool_t CreateTH1Fvector1(Int_t X, const char* name, const char* title, Int_t nBin, Float_t nMin, Float_t nMax, Int_t logAxis = -1);
+  Bool_t CreateTH1Fvector2(Int_t X, Int_t Y, const char* name, const char* title, Int_t nBin, Float_t nMin, Float_t nMax, Int_t logAxis = -1);
+  Bool_t CreateTH2Fvector1(Int_t X, const char* name, const char* title, Int_t nBinX, Float_t nMinX, Float_t nMaxX, Int_t nBinY, Float_t nMinY, Float_t nMaxY, Int_t logAxis = -1);
   Bool_t CreateProfile(const char* name, const char* title, Int_t nbins, Double_t xmin, Double_t xmax);
   Bool_t CreateTHnSparse(const char* name, const char* title, Int_t dim, Int_t* nbins, Double_t* xmin, Double_t* xmax);
 
@@ -72,10 +72,12 @@ class AliHFEcollection : public TNamed{
 
   // Fill functions
   Bool_t Fill(const char* name, Double_t v);
+  Bool_t Fill(const char* name, Int_t v);
   Bool_t Fill(const char* name, Int_t X, Double_t v);
   Bool_t Fill(const char* name, Int_t X, Int_t Y, Double_t v);
   Bool_t Fill(const char* name, Double_t v1, Double_t v2);
   Bool_t Fill(const char* name, Int_t X, Double_t v1, Double_t v2);
+  Bool_t Fill(const char* name, Double_t* entry, Double_t weight = 1);
  private:
   Bool_t CheckObject(const char* name);
    void Copy(TObject &ref) const;
index 6268896..602b9d2 100644 (file)
@@ -139,6 +139,7 @@ void AliHFEcuts::Initialize(AliCFManager *cfm){
   // Initializes the cut objects from the correction framework
   // Publishes the cuts to the correction framework manager
   //
+  AliDebug(2, "Called");
   if(IsInDebugMode()){
      fHistQA = new TList;
     fHistQA->SetName("CutQAhistograms");
@@ -182,6 +183,7 @@ void AliHFEcuts::Initialize(AliCFManager *cfm){
 //__________________________________________________________________
 void AliHFEcuts::Initialize(){
   // Call all the setters for the cuts
+  AliDebug(2, "Called\n");
   SetParticleGenCutList();
   SetAcceptanceCutList();
   SetRecKineITSTPCCutList();
@@ -196,20 +198,20 @@ void AliHFEcuts::SetEventCutList(Int_t istep){
   // 
   // Cuts for Event Selection
   //
+  AliDebug(2, "Called\n");
   TObjArray *arr = new TObjArray;
   if(istep == kEventStepGenerated){
-    AliCFEventGenCuts *evGenCuts = new AliCFEventGenCuts("fCutsEvGen", "Event Generated cuts");
+    AliCFEventGenCuts *evGenCuts = new AliCFEventGenCuts((Char_t *)"fCutsEvGen", (Char_t *)"Event Generated cuts");
     evGenCuts->SetNTracksCut(1);
     evGenCuts->SetRequireVtxCuts(kTRUE);
     evGenCuts->SetVertexXCut(-1, 1);
     evGenCuts->SetVertexYCut(-1, 1);
-    evGenCuts->SetVertexZCut(-30, 30);
+    evGenCuts->SetVertexZCut(-10, 10);
 
     arr->SetName("fEvGenCuts");
     arr->AddLast(evGenCuts);
   } else {
-    AliCFEventRecCuts *evRecCuts = new AliCFEventRecCuts("fCutsEvRec", "Event Reconstructed cuts");
-    evRecCuts->SetUseSPDVertex();
+    AliCFEventRecCuts *evRecCuts = new AliCFEventRecCuts((Char_t *)"fCutsEvRec", (Char_t *)"Event Reconstructed cuts");
     evRecCuts->SetNTracksCut(1);
     evRecCuts->SetRequireVtxCuts(kTRUE);
     evRecCuts->SetVertexXCut(-1, 1);
@@ -231,29 +233,38 @@ void AliHFEcuts::SetParticleGenCutList(){
   // Particle Species: Electrons
   // Eta: < 0.9 (TRD-TOF acceptance)
   //
+  
+  TObjArray *mcCuts = new TObjArray;
+  mcCuts->SetName("fPartGenCuts");
+
+  // 
+  AliDebug(2, "Called\n");
   AliCFParticleGenCuts *genCuts = new AliCFParticleGenCuts("fCutsGenMC", "Particle Generation Cuts");
   genCuts->SetRequireIsCharged();
-  if(IsRequirePrimary()) genCuts->SetRequireIsPrimary();
+  if(IsRequirePrimary()) { 
+    genCuts->SetRequireIsPrimary();
+  }
   if(IsRequireProdVertex()){
+    AliDebug(3, Form("Vertex Range: fProdVtx[0] %f, fProdVtx[1] %f, fProdVtx[2] %f, fProdVtx[3] %f", fProdVtx[0], fProdVtx[1], fProdVtx[2], fProdVtx[3]));
     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.8, 0.8);
+  if(IsInDebugMode()) genCuts->SetQAOn(fHistQA);
 
-  if(IsInDebugMode()){
-    genCuts->SetQAOn(fHistQA);
-    kineMCcuts->SetQAOn(fHistQA);
-  }
-
-  TObjArray *mcCuts = new TObjArray;
-  mcCuts->SetName("fPartGenCuts");
+  // Add
   mcCuts->AddLast(genCuts);
-  mcCuts->AddLast(kineMCcuts);
+  
+  //
+  if(IsRequireKineMCCuts()) {  
+    AliCFTrackKineCuts *kineMCcuts = new AliCFTrackKineCuts((Char_t *)"fCutsKineMC", (Char_t *)"MC Kine Cuts");
+    kineMCcuts->SetPtRange(fPtRange[0], fPtRange[1]);
+    kineMCcuts->SetEtaRange(-0.8, 0.8);
+    if(IsInDebugMode()) kineMCcuts->SetQAOn(fHistQA);
+    mcCuts->AddLast(kineMCcuts);
+  }
+   
   fCutList->AddLast(mcCuts);
 }
 
@@ -267,6 +278,7 @@ void AliHFEcuts::SetAcceptanceCutList(){
   //          TRD [2*nTracklets]
   //          TOF [0]
   //
+  AliDebug(2, "Called\n");
   AliCFAcceptanceCuts *accCuts = new AliCFAcceptanceCuts("fCutsAccMC", "MC Acceptance Cuts");
   accCuts->SetMinNHitITS(3);
   accCuts->SetMinNHitTPC(2);
@@ -301,7 +313,9 @@ void AliHFEcuts::SetRecKineITSTPCCutList(){
   //  Momentum Range: 100MeV - 20GeV
   //  Eta: < 0.9 (TRD-TOF acceptance)
   //
-  AliCFTrackQualityCuts *trackQuality = new AliCFTrackQualityCuts("fCutsQualityRec","REC Track Quality Cuts");
+  AliDebug(2, "Called\n");
+  AliCFTrackQualityCuts *trackQuality = new AliCFTrackQualityCuts((Char_t *)"fCutsQualityRec", (Char_t *)"REC Track Quality Cuts");
+  trackQuality->SetMinNClusterITS(4);
   trackQuality->SetMinNClusterTPC(fMinClustersTPC);
   trackQuality->SetMaxChi2PerClusterTPC(fMaxChi2clusterTPC);
   trackQuality->SetStatus(AliESDtrack::kTPCrefit | AliESDtrack::kITSrefit);
@@ -311,7 +325,7 @@ void AliHFEcuts::SetRecKineITSTPCCutList(){
   if(fMinClusterRatioTPC > 0.) hfecuts->SetClusterRatioTPC(fMinClusterRatioTPC);
   hfecuts->SetDebugLevel(fDebugLevel);
   
-  AliCFTrackKineCuts *kineCuts = new AliCFTrackKineCuts("fCutsKineRec", "REC Kine Cuts");
+  AliCFTrackKineCuts *kineCuts = new AliCFTrackKineCuts((Char_t *)"fCutsKineRec", (Char_t *)"REC Kine Cuts");
   kineCuts->SetPtRange(fPtRange[0], fPtRange[1]);
   kineCuts->SetEtaRange(-0.8, 0.8);
   
@@ -338,7 +352,8 @@ void AliHFEcuts::SetRecPrimaryCutList(){
   //    Z:  10. cm
   //  No Kink daughters
   //
-  AliCFTrackIsPrimaryCuts *primaryCut = new AliCFTrackIsPrimaryCuts("fCutsPrimaryCuts", "REC Primary Cuts");
+  AliDebug(2, "Called\n");
+  AliCFTrackIsPrimaryCuts *primaryCut = new AliCFTrackIsPrimaryCuts((Char_t *)"fCutsPrimaryCuts", (Char_t *)"REC Primary Cuts");
   if(IsRequireDCAToVertex()){
     //primaryCut->SetDCAToVertex2D(kTRUE);
     primaryCut->SetMaxDCAToVertexXY(fDCAtoVtx[0]);
@@ -362,6 +377,7 @@ void AliHFEcuts::SetHFElectronITSCuts(){
   //
   // Special Cuts introduced by the HFElectron Group: ITS
   //
+  AliDebug(2, "Called\n");
   AliHFEextraCuts *hfecuts = new AliHFEextraCuts("fCutsHFElectronGroupPixels","Extra cuts from the HFE group");
   if(IsRequireITSpixel()){
     hfecuts->SetRequireITSpixel(AliHFEextraCuts::ITSPixel_t(fCutITSPixel));
@@ -382,6 +398,7 @@ void AliHFEcuts::SetHFElectronTRDCuts(){
   //
   // Special Cuts introduced by the HFElectron Group: TRD
   //
+  AliDebug(2, "Called\n");
   AliHFEextraCuts *hfecuts = new AliHFEextraCuts("fCutsHFElectronGroupTRD","Extra cuts from the HFE group");
   if(fMinTrackletsTRD > 0.) hfecuts->SetMinTrackletsTRD(fMinTrackletsTRD);
   if(IsInDebugMode()) hfecuts->SetQAOn(fHistQA);
@@ -406,6 +423,7 @@ Bool_t AliHFEcuts::CheckParticleCuts(CutStep_t step, TObject *o){
   //
   // Checks the cuts without using the correction framework manager
   // 
+  AliDebug(2, "Called\n");
   TString stepnames[kNcutStepsTrack] = {"fPartGenCuts", "fPartAccCuts", "fPartRecCuts", "fPartPrimCuts", "fPartHFECuts"};
   TObjArray *cuts = dynamic_cast<TObjArray *>(fCutList->FindObject(stepnames[step].Data()));
   if(!cuts) return kTRUE;
index dc1568b..1981424 100644 (file)
@@ -85,6 +85,7 @@ class AliHFEcuts : public TObject{
     Bool_t IsRequireProdVertex() const { return TESTBIT(fRequirements, kProductionVertex); };
     Bool_t IsRequireSigmaToVertex() const { return TESTBIT(fRequirements, kSigmaToVertex); };
     Bool_t IsRequireDCAToVertex() const {return TESTBIT(fRequirements, kDCAToVertex); };
+    Bool_t IsRequireKineMCCuts() const {return TESTBIT(fRequirements, kKineMCCuts); };
     
     // Setters
     inline void SetCutITSpixel(UChar_t cut);
@@ -106,6 +107,7 @@ class AliHFEcuts : public TObject{
     void SetRequireITSPixel() { SETBIT(fRequirements, kITSPixel); }
     void SetRequireProdVertex() { SETBIT(fRequirements, kProductionVertex); };
     void SetRequireSigmaToVertex() { SETBIT(fRequirements, kSigmaToVertex); };
+    void SetRequireKineMCCuts() { SETBIT(fRequirements, kKineMCCuts); };
 
     void SetDebugLevel(Int_t level) { fDebugLevel = level; };
     Int_t GetDebugLevel() const { return fDebugLevel; };
@@ -121,7 +123,8 @@ class AliHFEcuts : public TObject{
       kSigmaToVertex = 2,
       kDCAToVertex = 3,
       kITSPixel = 4,
-      kMaxImpactParam = 5
+      kMaxImpactParam = 5,
+      kKineMCCuts = 6
     } Require_t;
     void SetParticleGenCutList();
     void SetAcceptanceCutList();
@@ -186,14 +189,14 @@ void AliHFEcuts::CreateStandardCuts(){
   // Standard Cuts defined by the HFE Group
   //
   SetRequireProdVertex();
-  fProdVtx[0] = -3;
+  fProdVtx[0] = 0;
   fProdVtx[1] = 3;
-  fProdVtx[2] = -3;
+  fProdVtx[2] = 0;
   fProdVtx[3] = 3;
-  SetRequireDCAToVertex();
-  fDCAtoVtx[0] = 2.;
-  fDCAtoVtx[1] = 10.;
-  fMinClustersTPC = 50;
+  //SetRequireDCAToVertex();
+  //fDCAtoVtx[0] = 0.5;
+  //fDCAtoVtx[1] = 1.5;
+  fMinClustersTPC = 80;
   fMinTrackletsTRD = 0;
   SetRequireITSPixel();
   fCutITSPixel = AliHFEextraCuts::kFirst;
@@ -201,5 +204,6 @@ void AliHFEcuts::CreateStandardCuts(){
   fMinClusterRatioTPC = 0.6;
   fPtRange[0] = 0.1;
   fPtRange[1] = 20.;
+  SetRequireKineMCCuts();
 }
 #endif
index 040ed6f..02b38d0 100644 (file)
 #include "AliESDtrack.h"
 #include "AliESDEvent.h"
 #include "AliMCEvent.h"
+#include "AliMCVertex.h"
+
+#include "AliKFParticle.h"
+#include "AliKFVertex.h"
+
+#include "AliESDVertex.h"
+
+#include "AliPID.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"
+ // particles name
+ "electron", "muonMinus","pionMinus", "kaonMinus", "protonMinus", 
+ "positron", "muonPlus", "pionPlus", "kaonPlus", "protonPlus",
+ "allNegative", "allPositive"
 };
+
+const Int_t AliHFEdca::fgkPdgParticle[10] = { 
+//   11, 13, -211, -233, -2122,  
+//   -11, -13, 211, 233, 2122};
+ kPDGelectron, kPDGmuon, -kPDGpion, -kPDGkaon, -kPDGproton, 
+ -kPDGelectron, -kPDGmuon, kPDGpion, kPDGkaon, kPDGproton};
+
 //________________________________________________________________________
 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
+ // 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 Float_t AliHFEdca::fgkPtIntv[51] = {
+ // define pT bins
+ 0.10, 0.15, 0.20, 0.25, 0.30, 0.35, 0.40, 0.45, 0.50, 0.55, 
+ 0.60, 0.70, 0.80, 0.90, 1.00, 1.10, 1.20, 1.30, 1.40, 1.50, 
+ 1.70, 1.90, 2.10, 2.30, 2.50, 2.70, 2.90, 3.10, 3.30, 3.50, 
+ 3.80, 4.10, 4.40, 4.70, 5.00, 5.30, 5.60, 5.90, 6.20, 6.50, 
+ 7.00, 7.50, 8.00, 9.00, 10.0, 11.0, 12.0, 13.0, 15.0, 18.0, 
+ 20.00};
 
 //________________________________________________________________________
 const Char_t *AliHFEdca::fgkDcaVar[2] = {
-  "deltaDcaXY",  "deltaDcaZ"};
+ "DcaXY",  "DcaZ"};
 
 //________________________________________________________________________
 const Char_t *AliHFEdca::fgkDcaVarTitle[2] ={
-  ";residual #Delta(d_{xy}) [#mum];couts", ";residual #Delta(d_{z}) [#mum];counts"};
+ ";dca_{xy} [#mum];counts", ";dca_{z} [#mum];counts"};
+
+//________________________________________________________________________
+const Char_t *AliHFEdca::fgkVertexVar[3] = {
+ "VertexX", "VertexY", "VertexZ"};
+
+//________________________________________________________________________
+const Char_t *AliHFEdca::fgkVertexVarTitle[3] ={
+ ";vertex_{x} [#mum];counts", ";vertex_{y} [#mum];counts", ";vertex_{z} [#mum];counts"};
+
+//________________________________________________________________________
+const Char_t *AliHFEdca::fgkResDcaVar[2] = {
+ "deltaDcaXY",  "deltaDcaZ"};
 
+//________________________________________________________________________
+const Char_t *AliHFEdca::fgkResDcaVarTitle[2] ={
+ ";residual #Delta(d_{xy}) [#mum];counts", ";residual #Delta(d_{z}) [#mum];counts"};
 
 //________________________________________________________________________
 const Char_t *AliHFEdca::fgkPullDcaVar[2] = {
-  "pullDcaXY", "pullDcaZ"
+ "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"
+ ";residual dca_{xy}/(error dca_{xy});counts", 
+ ";residual dca_{z}/(error dca_{z});counts"
 };
 
 //________________________________________________________________________
-AliHFEdca::AliHFEdca():
-   fResidualList(0x0)
-  , fPullList(0x0)
+const Char_t *AliHFEdca::fgkPullDataDcaVarTitle[2] = {
+ ";dca_{xy}^{data}/error dca_{xy};counts", 
+ ";dca_{z}^{data}/error dca_{z};counts"
+};
 
+//________________________________________________________________________
+AliHFEdca::AliHFEdca():
+  TObject(),
+  fStat(NULL)
 {
-  // default constructor
+ // default constructor
+
 }
 
 //________________________________________________________________________
-AliHFEdca::AliHFEdca(const AliHFEdca &dca):
-  TObject(dca)
-  , fResidualList(0x0)
-  , fPullList(0x0)
-
+AliHFEdca::AliHFEdca(const AliHFEdca &ref):
+ TObject(ref),
+ fStat(ref.fStat)
 {
-  // copy constructor
+ // copy constructor
 
 }
 //_______________________________________________________________________________________________
-AliHFEdca&
-AliHFEdca::operator=(const AliHFEdca &)
+AliHFEdca&AliHFEdca::operator=(const AliHFEdca &ref)
 {
-  //
-  // Assignment operator
-  //
-  
-  Printf("Not yet implemented.");
-  return *this;
+ //
+ // Assignment operator
+ //
+
+
+ if(this == &ref) return *this;
+ TObject::operator=(ref);
+ return *this;
 }
 
 //________________________________________________________________________
 AliHFEdca::~AliHFEdca()
 {
-  // default destructor
+ // 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(fHistDcaZPull[j][i]) delete fHistDcaZPull[j][i];
+
+     if(fHistDcaXY[j][i]) delete fHistDcaXY[j][i];
+     if(fHistDcaZ[j][i]) delete fHistDcaZ[j][i];
 
-  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(j<(kNParticles-2)){
+       if(fHistEPDcaXYRes[j][i]) delete fHistEPDcaXYRes[j][i];
+       if(fHistEPDcaZRes[j][i]) delete fHistEPDcaZRes[j][i];
+       
+       if(fHistEPDcaXYPull[j][i]) delete fHistEPDcaXYPull[j][i];
+       if(fHistEPDcaZPull[j][i]) delete fHistEPDcaZPull[j][i];
+       
+       if(fHistEPDcaXY[j][i]) delete fHistEPDcaXY[j][i];
+       if(fHistEPDcaZ[j][i]) delete fHistEPDcaZ[j][i];
+     }
+
+     if(fHistKFDcaXY[j][i]) delete fHistKFDcaXY[j][i];
+     if(fHistKFDcaZ[j][i]) delete fHistKFDcaZ[j][i];
+
+     if(fHistDataDcaXY[j][i]) delete fHistDataDcaXY[j][i];
+     if(fHistDataDcaZ[j][i]) delete fHistDataDcaZ[j][i];
+     if(fHistDataWoDcaXY[j][i]) delete fHistDataWoDcaXY[j][i];
+     if(fHistDataWoDcaZ[j][i]) delete fHistDataWoDcaZ[j][i];
+
+     if(fHistDataDcaXYPull[j][i]) delete fHistDataDcaXYPull[j][i];
+     if(fHistDataDcaZPull[j][i]) delete fHistDataDcaZPull[j][i];
+     if(fHistDataWoDcaXYPull[j][i]) delete fHistDataWoDcaXYPull[j][i];
+     if(fHistDataWoDcaZPull[j][i]) delete fHistDataWoDcaZPull[j][i];
+   }
+
+   if(fHistMcPid[j]) delete fHistMcPid[j];
+   if(fHistEsdPid[j]) delete fHistEsdPid[j];
+   if(fHistDataEsdPid[j]) delete fHistDataEsdPid[j];
+ }
+
+ for(Int_t i=0; i<3; i++){
+   if(fHistMCvertex[i]) delete fHistMCvertex[i];
+   if(fHistESDvertex[i]) delete fHistESDvertex[i];
+   if(fHistDatavertex[i]) delete fHistDatavertex[i];    
+ }
+
+ // for the HFEpid
+ for(Int_t iEle=0; iEle<2; iEle++){
+   for(Int_t iPt=0; iPt<kNPtBins; iPt++){
+     if(fHistHPDcaXYRes[iEle][iPt]) delete fHistHPDcaXYRes[iEle][iPt]; 
+     if(fHistHPDcaZRes[iEle][iPt]) delete fHistHPDcaZRes[iEle][iPt];   
+     if(fHistHPDcaXYPull[iEle][iPt]) delete fHistHPDcaXYPull[iEle][iPt]; 
+     if(fHistHPDcaZPull[iEle][iPt]) delete fHistHPDcaZPull[iEle][iPt];  
+     if(fHistHPDcaXY[iEle][iPt]) delete fHistHPDcaXY[iEle][iPt];     
+     if(fHistHPDcaZ[iEle][iPt]) delete fHistHPDcaZ[iEle][iPt];      
+
+
+ // Data
+     if(fHistHPDataDcaXY[iEle][iPt]) delete fHistHPDataDcaXY[iEle][iPt];   
+     if(fHistHPDataDcaZ[iEle][iPt]) delete fHistHPDataDcaZ[iEle][iPt];   
+     if(fHistHPDataDcaXYPull[iEle][iPt]) delete fHistHPDataDcaXYPull[iEle][iPt];   
+     if(fHistHPDataDcaZPull[iEle][iPt]) delete fHistHPDataDcaZPull[iEle][iPt];    
+
+   }
+   for(Int_t i=0; i<2; i++)
+     if(fHistHfePid[iEle][i]) delete fHistHfePid[iEle][i];
+
+   if(fHistDataHfePid[iEle]) delete fHistDataHfePid[iEle];
+
+ }
 
-  if(fResidualList) delete fResidualList;
-  if(fPullList) delete fPullList;
+ if(fStat) delete fStat;
 
-  Printf("analysis done\n");
+ Printf("analysis done\n");
 }
 
 //________________________________________________________________________
 void AliHFEdca::InitAnalysis(){
-  
-  Printf("initialize analysis\n");
+
+ Printf("initialize analysis\n");
 
 }
 
@@ -143,213 +239,1392 @@ void AliHFEdca::InitAnalysis(){
 //________________________________________________________________________
 void AliHFEdca::PostAnalysis() const
 {
-  // do fit
-  // moved to dcaPostAnalysis.C
+ // 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++){
+ // define histogram
+ // 1. residual
+
+ // for residuals
+ fHistDcaXYRes[kNParticles][kNPtBins]=0x0;
+ fHistDcaZRes[kNParticles][kNPtBins]=0x0;
+
+ fHistEPDcaXYRes[kNParticles-2][kNPtBins]=0x0;
+ fHistEPDcaZRes[kNParticles-2][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*)fgkResDcaVarTitle[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]);
+       histName += Form("_MCpid_%s_pT-%.2f-%.2f", (const char*)fgkResDcaVar[k], fgkPtIntv[i], fgkPtIntv[i+1]);
+       TString histEPName((const char*)fgkParticles[j]);
+       histEPName += Form("_ESDpid_%s_pT-%.2f-%.2f", (const char*)fgkResDcaVar[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(j<(kNParticles-2)){
+           fHistEPDcaXYRes[j][i] = new TH1F((const char*)histEPName, (const char*)histTitle, nBins, -maxXYBin, maxXYBin);
+           fHistEPDcaXYRes[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]);
+         if(j<(kNParticles-2)){
+           fHistEPDcaZRes[j][i] = new TH1F((const char*)histEPName, (const char*)histTitle, nBins, -maxZBin, maxZBin);
+           fHistEPDcaZRes[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)
-  
-
-  
+     } // 50 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]);  
+     if(iPart<(kNParticles-2)){
+       residualList->Add(fHistEPDcaXYRes[iPart][iPtBin]);  
+       residualList->Add(fHistEPDcaZRes[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]);
+ // 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;
+
+ fHistEPDcaXYPull[kNParticles-2][kNPtBins]=0x0;
+ fHistEPDcaZPull[kNParticles-2][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++){
        
-       histName += Form("_%s_pT-%.1f-%.1f", (const char*)fgkPullDcaVar[k], fgkPtIntv[i], fgkPtIntv[i+1]);
+       TString histName((const char*)fgkParticles[j]); 
+       histName += Form("_MCpid_%s_pT-%.2f-%.2f", (const char*)fgkPullDcaVar[k], fgkPtIntv[i], fgkPtIntv[i+1]);
+       TString histEPName((const char*)fgkParticles[j]);       
+       histEPName += Form("_ESDpid_%s_pT-%.2f-%.2f", (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(j<(kNParticles-2))    {
+           fHistEPDcaXYPull[j][i] = new TH1F((const char*)histEPName, (const char*)histTitle, nBins, 1-maxXYBin, 1+maxXYBin);
+           fHistEPDcaXYPull[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]);
+         if(j<(kNParticles-2))    {
+           fHistEPDcaZPull[j][i] = new TH1F((const char*)histEPName, (const char*)histTitle, nBins, 1-maxZBin, 1+maxZBin);
+           fHistEPDcaZPull[j][i]->SetLineColor((const int)fgkColorPart[j]);}
+       }   
+     } // 50 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]);  
+     if(iPart<(kNParticles-2)){
+       pullList->Add(fHistDcaXYPull[iPart][iPtBin]);  
+       pullList->Add(fHistDcaZPull[iPart][iPtBin]); }
+   } // loop over pt bins
+ }  // loop over particles (pos, neg)
+
+}
+
+
+//________________________________________________________________________
+void AliHFEdca::CreateHistogramsDca(TList *dcaList){
+ // 
+ // define histograms: MC dca
+ //
+
+ // statistics
+ fStat = 0x0;
+ fStat = new TH1I("fStatistics", "allStatistics;ID;counts", 7, -3.5, 3.5);
+ fStat->SetMarkerStyle(20); 
+ fStat->SetMarkerColor(3); 
+ fStat->SetMarkerSize(1); 
+
+ // for dca
+ fHistDcaXY[kNParticles][kNPtBins]=0x0;
+ fHistDcaZ[kNParticles][kNPtBins]=0x0;
+
+ fHistEPDcaXY[kNParticles-2][kNPtBins]=0x0;
+ fHistEPDcaZ[kNParticles-2][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("_MCpid_%s_pT-%.2f-%.2f", (const char*)fgkDcaVar[k], fgkPtIntv[i], fgkPtIntv[i+1]);
+       
+       TString histNameEP((const char*)fgkParticles[j]);       
+       histNameEP += Form("_ESDpid_%s_pT-%.2f-%.2f", (const char*)fgkDcaVar[k], fgkPtIntv[i], fgkPtIntv[i+1]);
+
+       if(k==0){
+         fHistDcaXY[j][i] = new TH1F((const char*)histName, (const char*)histTitle, nBins, -maxXYBin, maxXYBin);
+         fHistDcaXY[j][i]->SetLineColor((const int)fgkColorPart[j]);
+         
+         if(j<(kNParticles-2)){
+           fHistEPDcaXY[j][i] = new TH1F((const char*)histNameEP, (const char*)histTitle, nBins, -maxXYBin, maxXYBin);
+           fHistEPDcaXY[j][i]->SetLineColor((const int)fgkColorPart[j]);}
+       }           
+       if(k==1){
+         fHistDcaZ[j][i] = new TH1F((const char*)histName, (const char*)histTitle, nBins, -maxZBin, maxZBin);
+         fHistDcaZ[j][i]->SetLineColor((const int)fgkColorPart[j]);
+         if(j<(kNParticles-2)){
+           fHistEPDcaZ[j][i] = new TH1F((const char*)histNameEP, (const char*)histTitle, nBins, -maxZBin, maxZBin);
+           fHistEPDcaZ[j][i]->SetLineColor((const int)fgkColorPart[j]);}
+       }   
+     } // 50 pt bins
+   } //12 nparticles
+ } // 2 dca var
+
+   //  TList *fDcaList = 0;
+ dcaList->SetOwner();
+ dcaList->SetName("mcDcaDistr");
+ for(Int_t iPart=0; iPart<kNParticles; iPart++){
+   for(Int_t iPtBin=0; iPtBin<kNPtBins; iPtBin++){
+     dcaList->Add(fHistDcaXY[iPart][iPtBin]);  
+     dcaList->Add(fHistDcaZ[iPart][iPtBin]);  
+     if(iPart<(kNParticles-2)) {
+       dcaList->Add(fHistEPDcaXY[iPart][iPtBin]);  
+       dcaList->Add(fHistEPDcaZ[iPart][iPtBin]); }
+   } // loop over pt bins
+ }  // loop over particles (pos, neg)
+
+ dcaList->Add(fStat);
+
+}
+
+//________________________________________________________________________
+void AliHFEdca::CreateHistogramsKfDca(TList *kfDcaList){
+ // 
+ // define histograms: MC dca
+ //
+
+ // statistics
+ fStat = 0x0;
+ fStat = new TH1I("fStatistics", "allStatistics;ID;counts", 7, -3.5, 3.5);
+ fStat->SetMarkerStyle(20); 
+ fStat->SetMarkerColor(3); 
+ fStat->SetMarkerSize(1); 
+
+ // for kf dca
+ fHistKFDcaXY[kNParticles][kNPtBins]=0x0;
+ fHistKFDcaZ[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 histNameKF((const char*)fgkParticles[j]);       
+       histNameKF += Form("_MCpid_KF%s_pT-%.2f-%.2f", (const char*)fgkDcaVar[k], fgkPtIntv[i], fgkPtIntv[i+1]);
+       
+       if(k==0){
+         fHistKFDcaXY[j][i] = new TH1F((const char*)histNameKF, (const char*)histTitle, nBins, -maxXYBin, maxXYBin);
+         fHistKFDcaXY[j][i]->SetLineColor((const int)fgkColorPart[j]);
+       }           
+       if(k==1){
+         fHistKFDcaZ[j][i] = new TH1F((const char*)histNameKF, (const char*)histTitle, nBins, -maxZBin, maxZBin);
+         fHistKFDcaZ[j][i]->SetLineColor((const int)fgkColorPart[j]);
+       }   
+     } // 50 pt bins
+   } //12 nparticles
+ } // 2 dca var
+
+ kfDcaList->SetOwner();
+ kfDcaList->SetName("mcKfDcaDistr");
+ for(Int_t iPart=0; iPart<kNParticles; iPart++){
+   for(Int_t iPtBin=0; iPtBin<kNPtBins; iPtBin++){
+     kfDcaList->Add(fHistKFDcaXY[iPart][iPtBin]);  
+     kfDcaList->Add(fHistKFDcaZ[iPart][iPtBin]);  
+   } // loop over pt bins
+ }  // loop over particles (pos, neg)
+
+ kfDcaList->Add(fStat);
+
+}
+
+
+//________________________________________________________________________
+void AliHFEdca::CreateHistogramsDataDca(TList *dataDcaList){
+ //
+ // define histograms: real Data
+ //
+
+ // for dca
+ fHistDataDcaXY[kNParticles][kNPtBins]=0x0;
+ fHistDataDcaZ[kNParticles][kNPtBins]=0x0;
+
+ fHistDataWoDcaXY[kNParticles][kNPtBins]=0x0;
+ fHistDataWoDcaZ[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_Data_pT-%.2f-%.2f", (const char*)fgkDcaVar[k], fgkPtIntv[i], fgkPtIntv[i+1]);
+
+       TString histNameWo((const char*)fgkParticles[j]);       
+       histNameWo += Form("_%s_Data_wo_pT-%.2f-%.2f", (const char*)fgkDcaVar[k], fgkPtIntv[i], fgkPtIntv[i+1]);
+       
+       if(k==0){
+         fHistDataDcaXY[j][i] = new TH1F((const char*)histName, (const char*)histTitle, nBins, -maxXYBin, maxXYBin);
+         fHistDataDcaXY[j][i]->SetLineColor((const int)fgkColorPart[j]);
+
+         fHistDataWoDcaXY[j][i] = new TH1F((const char*)histNameWo, (const char*)histTitle, nBins, -maxXYBin, maxXYBin);
+         fHistDataWoDcaXY[j][i]->SetLineColor((const int)fgkColorPart[j]);
+       }           
+       if(k==1){
+         fHistDataDcaZ[j][i] = new TH1F((const char*)histName, (const char*)histTitle, nBins, -maxZBin, maxZBin);
+         fHistDataDcaZ[j][i]->SetLineColor((const int)fgkColorPart[j]);
+
+         fHistDataWoDcaZ[j][i] = new TH1F((const char*)histNameWo, (const char*)histTitle, nBins, -maxZBin, maxZBin);
+         fHistDataWoDcaZ[j][i]->SetLineColor((const int)fgkColorPart[j]);
+       }   
+     } // 50 pt bins
+   } //12 nparticles
+ } // 2 dca var
+
+   //  TList *fDcaList = 0;
+ dataDcaList->SetOwner();
+ dataDcaList->SetName("dataDcaDistr");
+ for(Int_t iPart=0; iPart<kNParticles; iPart++){
+   for(Int_t iPtBin=0; iPtBin<kNPtBins; iPtBin++){
+     dataDcaList->Add(fHistDataDcaXY[iPart][iPtBin]);  
+     dataDcaList->Add(fHistDataDcaZ[iPart][iPtBin]);  
+
+     dataDcaList->Add(fHistDataWoDcaXY[iPart][iPtBin]);  
+     dataDcaList->Add(fHistDataWoDcaZ[iPart][iPtBin]);  
+   } // loop over pt bins
+ }  // loop over particles (pos, neg)
+
+
+}
+
+
+//________________________________________________________________________
+void AliHFEdca::CreateHistogramsDataPull(TList *dataPullList){
+ // define histogram
+ // 2. pull
+
+ const Int_t nBins = 1000;
+ const Float_t maxXYBin = 20.;
+ const Float_t maxZBin = 20.;
+
+ // for pull -----------------------------------------------------------------------
+ fHistDataDcaXYPull[kNParticles][kNPtBins]=0x0;
+ fHistDataDcaZPull[kNParticles][kNPtBins]=0x0;
+
+ fHistDataWoDcaXYPull[kNParticles][kNPtBins]=0x0;
+ fHistDataWoDcaZPull[kNParticles][kNPtBins]=0x0;
+
+
+ for(Int_t k=0; k<kNDcaVar; k++){
+   TString histTitle((const char*)fgkPullDataDcaVarTitle[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_Data_pT-%.2f-%.2f", (const char*)fgkPullDcaVar[k], fgkPtIntv[i], fgkPtIntv[i+1]);
+
+       TString histNameWo((const char*)fgkParticles[j]);       
+       histNameWo += Form("_%s_Data_wo_pT-%.2f-%.2f", (const char*)fgkPullDcaVar[k], fgkPtIntv[i], fgkPtIntv[i+1]);
+       
+       if(k==0){
+         fHistDataDcaXYPull[j][i] = new TH1F((const char*)histName, (const char*)histTitle, nBins, 1-maxXYBin, 1+maxXYBin);
+         fHistDataDcaXYPull[j][i]->SetLineColor((const int)fgkColorPart[j]);
+
+         fHistDataWoDcaXYPull[j][i] = new TH1F((const char*)histNameWo, (const char*)histTitle, nBins, 1-maxXYBin, 1+maxXYBin);
+         fHistDataWoDcaXYPull[j][i]->SetLineColor((const int)fgkColorPart[j]);
+       }           
+       if(k==1){
+         fHistDataDcaZPull[j][i] = new TH1F((const char*)histName, (const char*)histTitle, nBins, 1-maxZBin, 1+maxZBin);
+         fHistDataDcaZPull[j][i]->SetLineColor((const int)fgkColorPart[j]);
+
+         fHistDataWoDcaZPull[j][i] = new TH1F((const char*)histNameWo, (const char*)histTitle, nBins, 1-maxZBin, 1+maxZBin);
+         fHistDataWoDcaZPull[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)
-  
-  
+     } // 50 pt bins
+   } //6 nparticles
+ } // 2 dca var
+
+ //  TList *fDataPullList = 0;
+ dataPullList->SetOwner();
+ dataPullList->SetName("dataPull");
+ for(Int_t iPart=0; iPart<kNParticles; iPart++){
+   for(Int_t iPtBin=0; iPtBin<kNPtBins; iPtBin++){
+     dataPullList->Add(fHistDataDcaXYPull[iPart][iPtBin]);  
+     dataPullList->Add(fHistDataDcaZPull[iPart][iPtBin]);  
+
+     dataPullList->Add(fHistDataWoDcaXYPull[iPart][iPtBin]);  
+     dataPullList->Add(fHistDataWoDcaZPull[iPart][iPtBin]);  
+   } // loop over pt bins
+ }  // loop over particles (pos, neg)
+
+}
+
+//________________________________________________________________________
+void AliHFEdca::CreateHistogramsVertex(TList *vertexList){
+ //
+ // define histograms: vertex
+ //
+ // for  vertex
+
+ fHistMCvertex[kNVertexVar]=0x0;
+ fHistESDvertex[kNVertexVar]=0x0;
+
+ const Int_t nBins = 1000;
+ const Float_t minXBin = -0.2e4;
+ const Float_t maxXBin = 0.2e4;
+ const Float_t minYBin = -0.5e4;
+ const Float_t maxYBin = 0.5e4;
+ const Float_t minZBin = -1.5e5;
+ const Float_t maxZBin = 1.5e5;
+
+ const Float_t minBin[kNVertexVar] = {minXBin, minYBin, minZBin};
+ const Float_t maxBin[kNVertexVar] = {maxXBin, maxYBin, maxZBin};
+
+ for(Int_t k=0; k<kNVertexVar; k++){
+   TString histTitle((const char*)fgkVertexVarTitle[k]);    
+   TString histNameMC((const char*)fgkVertexVar[k]);
+   histNameMC += Form("_MC");
+   TString histNameESD((const char*)fgkVertexVar[k]);
+   histNameESD += Form("_ESD");
+
+   fHistMCvertex[k] = new TH1F((const char*)histNameMC, (const char*)histTitle, nBins, minBin[k], maxBin[k]);
+   fHistMCvertex[k]->SetLineColor(k+2);
+
+   fHistESDvertex[k] = new TH1F((const char*)histNameESD, (const char*)histTitle, nBins, minBin[k], maxBin[k]);
+   fHistESDvertex[k]->SetLineColor(k+2);
+ } // 3 vertex var
+
+ vertexList->SetOwner();
+ vertexList->SetName("vertexDistr");
+
+ for(Int_t k=0; k<kNVertexVar; k++){
+   vertexList->Add(fHistMCvertex[k]);  
+   vertexList->Add(fHistESDvertex[k]);  
+ }
+
+}
+
+
+
+//________________________________________________________________________
+void AliHFEdca::CreateHistogramsDataVertex(TList *dataVertexList){
+ //
+ // define histograms: vertex
+ //
+ // for data vertex
+
+ fHistDatavertex[kNVertexVar]=0x0;
+
+ const Int_t nBins = 1000;
+ const Float_t minXBin = -0.2e4;
+ const Float_t maxXBin = 0.2e4;
+ const Float_t minYBin = -0.5e4;
+ const Float_t maxYBin = 0.5e4;
+ const Float_t minZBin = -1.5e5;
+ const Float_t maxZBin = 1.5e5;
+
+ const Float_t minBin[kNVertexVar] = {minXBin, minYBin, minZBin};
+ const Float_t maxBin[kNVertexVar] = {maxXBin, maxYBin, maxZBin};
+
+ for(Int_t k=0; k<kNVertexVar; k++){
+   TString histTitle((const char*)fgkVertexVarTitle[k]);    
+   TString histNameDataESD((const char*)fgkVertexVar[k]);
+   histNameDataESD += Form("_data");
+
+   fHistDatavertex[k] = new TH1F((const char*)histNameDataESD, (const char*)histTitle, nBins, minBin[k], maxBin[k]);
+   fHistDatavertex[k]->SetLineColor(k+2);
+ } // 3 vertex var
+
+   //  TList *fVDaraVertexList = 0;
+ dataVertexList->SetOwner();
+ dataVertexList->SetName("dataVertexDistr");
+
+ for(Int_t k=0; k<kNVertexVar; k++){
+   dataVertexList->Add(fHistDatavertex[k]);  
+ }
+
+}
+
+//_______________________________________________________________________________________________
+void AliHFEdca::CreateHistogramsPid(TList *mcPidList){
+ //
+ // define histograms which fills combined PID
+ //
+
+ const Char_t *mcOResd[2]={"mcPt", "esdPt"};
+
+ for(Int_t iPart=0; iPart<kNParticles; iPart++){
+   TString histTitleMc((const char*)fgkParticles[iPart]);
+   TString histTitleEsd((const char*)fgkParticles[iPart]);
+   histTitleMc += Form("_McPid_%s;p_{T} [GeV/c];counts", mcOResd[0]);
+   histTitleEsd += Form("_EsdPid_%s;p_{T} [GeV/c];counts", mcOResd[1]);
+
+   TString histNameMc((const char*)fgkParticles[iPart]);
+   TString histNameEsd((const char*)fgkParticles[iPart]);
+   histNameMc+=Form("_McPid_%s", mcOResd[0]);     
+   histNameEsd+=Form("_EsdPid_%s", mcOResd[1]);     
+
+   fHistMcPid[iPart] = new TH1F(histNameMc, histTitleMc, kNPtBins, fgkPtIntv);
+   fHistEsdPid[iPart] = new TH1F(histNameEsd, histTitleEsd, kNPtBins, fgkPtIntv);
+ }
+
+
+ mcPidList->SetOwner();
+ mcPidList->SetName("combinedPid");
+
+ for(Int_t iPart=0; iPart<kNParticles; iPart++){
+   mcPidList->Add(fHistMcPid[iPart]);
+   mcPidList->Add(fHistEsdPid[iPart]);
+ }
+}
+
+
+//_______________________________________________________________________________________________
+void AliHFEdca::CreateHistogramsDataPid(TList *pidList){
+ //
+ // define histograms which fills combined PID: data
+ //
+
+
+
+ for(Int_t iPart=0; iPart<kNParticles; iPart++){
+     TString histTitleEsd((const char*)fgkParticles[iPart]);
+     histTitleEsd+=Form("_DataEsdPid_esdPt;p_{T} [GeV/c];counts");
+     TString histNameEsd((const char*)fgkParticles[iPart]);
+     histNameEsd+=Form("_DataEsdPid");
+
+     fHistDataEsdPid[iPart] = new TH1F(histNameEsd, histTitleEsd, kNPtBins, fgkPtIntv);
+ }
+
+
+ pidList->SetOwner();
+ pidList->SetName("dataCombinedPid");
+
+ for(Int_t iPart=0; iPart<kNParticles; iPart++)
+   pidList->Add(fHistDataEsdPid[iPart]);
+
+
+}
+
+
+
+//_______________________________________________________________________________________________
+void AliHFEdca::FillHistogramsDca(AliESDEvent * const esdEvent, AliESDtrack * const track, AliMCEvent * const mcEvent)
+{
+ // the kDca plugin
+ // MC vertex
+ AliMCVertex *mcPrimVtx = (AliMCVertex *)mcEvent->GetPrimaryVertex();      
+ Double_t mcPrimV[3];
+ mcPrimV[0] = mcPrimVtx->GetX();
+ mcPrimV[1] = mcPrimVtx->GetY();
+ mcPrimV[2] = mcPrimVtx->GetZ();
+
+ Double_t mcVtxXY = TMath::Abs(mcPrimV[0]*mcPrimV[0] + mcPrimV[1]*mcPrimV[1]);
+
+// 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);  
+
+// obtaining errors of dca ------------------------------------------------------------------
+ const AliESDVertex *primVtx = esdEvent->GetPrimaryVertex();      
+ Double_t primV[3];
+ primV[0] = primVtx->GetXv();
+ primV[1] = primVtx->GetYv();
+ primV[2] = primVtx->GetZv();
+
+ Float_t magneticField = 0;  // initialized as 5kG
+ magneticField = esdEvent->GetMagneticField();  // in kG
+
+ Double_t beampiperadius=3.;
+ Double_t dz[2];   // error of dca in cm
+ Double_t covardz[3];
+
+ if(!track->PropagateToDCA(primVtx,magneticField, beampiperadius, dz, covardz)) return;  // protection
+ track->PropagateToDCA(primVtx,magneticField, beampiperadius, dz, covardz);
 
+ AliMCParticle *mctrack = dynamic_cast<AliMCParticle *>(mcEvent->GetTrack(TMath::Abs(track->GetLabel())));  
+ TParticle *part = mctrack->Particle();
+
+ 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);
+
+ Int_t pdg = part->GetPdgCode();
+ Int_t esdPid = GetCombinedPid(track);
+
+ Int_t charge = 1;
+ if(pdg==kPDGelectron || pdg==kPDGmuon 
+    || pdg==-kPDGpion || pdg==-kPDGkaon || pdg==-kPDGproton) charge = -1;  
+
+ // calculate mcDca ------------------------------------------------------------------ 
+ 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, radius in meter
+
+ Float_t nx = esdpx/mcpt;
+ Float_t ny = esdpy/mcpt;
+
+ Float_t radius;
+ radius = TMath::Abs(radiusMc);
+
+ Double_t dxy = vxy - mcVtxXY;   // in cm
+ Double_t dvx = vx - mcPrimV[0]; // in cm
+ Double_t dvy = vy - mcPrimV[1]; // in cm
+
+ Float_t mcDcaXY = (radius - TMath::Sqrt(dxy*dxy/100./100. + radius*radius + 2*radius*charge*(dvx*ny-dvy*nx)/100.)) ;  // in meters
+
+ 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
+ }
+
+
+ for(Int_t iPart=0; iPart<(kNParticles-2); iPart++){    
+   // identified ones
+   for(Int_t iPtBin=0; iPtBin<kNPtBins; iPtBin++){
+     if(esdpt>fgkPtIntv[iPtBin] && esdpt<=fgkPtIntv[iPtBin+1]){
+       if(pdg==fgkPdgParticle[iPart]) {
+         fHistDcaXYRes[iPart][iPtBin]->Fill(residual[0]*1.0e4);  
+         fHistDcaZRes[iPart][iPtBin]->Fill(residual[1]*1.0e4);   
+         fHistDcaXYPull[iPart][iPtBin]->Fill(pull[0]);  
+         fHistDcaZPull[iPart][iPtBin]->Fill(pull[1]); 
+         fHistDcaXY[iPart][iPtBin]->Fill(dz[0]*1.0e4); 
+         fHistDcaZ[iPart][iPtBin]->Fill(dz[1]*1.0e4);  
+       }  // mc pdg      
+       
+       if(esdPid==fgkPdgParticle[iPart]) {
+         fHistEPDcaXYRes[iPart][iPtBin]->Fill(residual[0]*1.0e4);  
+         fHistEPDcaZRes[iPart][iPtBin]->Fill(residual[1]*1.0e4);   
+         fHistEPDcaXYPull[iPart][iPtBin]->Fill(pull[0]);  
+         fHistEPDcaZPull[iPart][iPtBin]->Fill(pull[1]); 
+         fHistEPDcaXY[iPart][iPtBin]->Fill(dz[0]*1.0e4); 
+         fHistEPDcaZ[iPart][iPtBin]->Fill(dz[1]*1.0e4);  
+       }  // esd pid
+       
+     } // pt range
+
+     else
+       continue;
+   }  // pt loop
+ } // particle id loop
+
+ // for charged particles: no pid
+ 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]);
+     fHistDcaXY[iPart][iPtBin]->Fill(dz[0]*1e4);
+     fHistDcaZ[iPart][iPtBin]->Fill(dz[1]*1e4);      
+   }
+   else
+     continue;
+ } // pt  
+
+}
+
+//_______________________________________________________________________________________________
+void AliHFEdca::FillHistogramsKfDca(AliESDEvent * const esdEvent, AliESDtrack * const track, AliMCEvent * const mcEvent)
+{
+ // the kKfDca plugin
+
+// filling historgams track by track
+
+// obtaining reconstructed dca ------------------------------------------------------------------  
+ const AliESDVertex *primVtx = esdEvent->GetPrimaryVertex();      
+   Float_t magneticField = 0;  // initialized as 5kG
+ magneticField = esdEvent->GetMagneticField();  // in kG
+
+ Float_t esdpx = track->Px();
+ Float_t esdpy = track->Py();
+ Float_t esdpt = TMath::Sqrt(esdpx*esdpx+esdpy*esdpy);  
+
+ Int_t charge = track->Charge();
+
+ Double_t beampiperadius=3.;  
+ Double_t dz[2];   // error of dca in cm
+ Double_t covardz[3];
+ if(!track->PropagateToDCA(primVtx,magneticField, beampiperadius, dz, covardz)) return; // protection 
+ track->PropagateToDCA(primVtx,magneticField,  beampiperadius, dz, covardz);
+
+ AliMCParticle *mctrack = dynamic_cast<AliMCParticle *>(mcEvent->GetTrack(TMath::Abs(track->GetLabel())));  
+ TParticle *part = mctrack->Particle();    
+ Int_t pdg = part->GetPdgCode();
+
+ // calculate dca using AliKFParticle class------------------------------------------------------------------
+ Double_t kfdz[3] = {0, 0, 0};  
+ Double_t kfdzwith[3] = {0, 0, 0};  
+
+ Int_t trkID = track->GetID();
+
+ AliKFParticle::SetField(magneticField);
+ AliKFParticle kfParticle(*track, pdg);
+
+ // prepare kfprimary vertex
+ AliKFVertex kfESDprimary;
+ // Reconstruct Primary Vertex (with ESD tracks)
+ Int_t n=primVtx->GetNIndices();
+ if (n>0 && primVtx->GetStatus()){
+   kfESDprimary = AliKFVertex(*primVtx);
+
+   Double_t dcaXYWithTrk = kfParticle.GetDistanceFromVertexXY(kfESDprimary);
+   Double_t dcaWithTrk = kfParticle.GetDistanceFromVertex(kfESDprimary);
+   Double_t dcaZWithTrk = 0;
+   if(TMath::Abs(dcaWithTrk)>=TMath::Abs(dcaXYWithTrk)) 
+     dcaZWithTrk =TMath::Sqrt(dcaWithTrk*dcaWithTrk-dcaXYWithTrk*dcaXYWithTrk)*((dz[1]*-1<=0)?1:-1);
+   kfdzwith[0] = dcaXYWithTrk;  
+   kfdzwith[1] = dcaZWithTrk; 
+   kfdzwith[2] = dcaWithTrk;  // with current track
+
+   Double_t dcaXYWoTrk = 0;
+   Double_t dcaZWoTrk = 0;
+   Double_t dcaWoTrk = 0;
+
+   UShort_t *priIndex = primVtx->GetIndices();
+
+   for (Int_t i=0;i<n;i++){
+
+     Int_t idx = Int_t(priIndex[i]);
+     if (idx == trkID){
+       kfESDprimary -= kfParticle;
+       dcaXYWoTrk = kfParticle.GetDistanceFromVertexXY(kfESDprimary);
+       dcaWoTrk = kfParticle.GetDistanceFromVertex(kfESDprimary);
+       if((dcaWoTrk-dcaXYWoTrk)>=0)
+         dcaZWoTrk = TMath::Abs(dcaWoTrk*dcaWoTrk - dcaXYWoTrk*dcaXYWoTrk)*((dz[1]*-1<=0)?1:-1);
+     }  // remove current track from this calculation
+   }  // loop over all primary vertex contributors
+
+
+   kfdz[0] = dcaXYWoTrk;  
+   kfdz[1] = dcaZWoTrk;
+   kfdz[2] = dcaWoTrk;  
+
+ }  // only if n contributor > 0 and primVtx constructed
+
+ fStat->Fill(0);
+
+ if(dz[0]!=0 && dz[0]*kfdzwith[0]>0 && TMath::Abs(kfdzwith[0]/dz[0])>0.9999 && TMath::Abs(kfdzwith[0]/dz[0])<1.0001)fStat->Fill(1);; // same 
+ if(dz[0]!=0 && dz[0]*kfdzwith[0]<0 && TMath::Abs(kfdzwith[0]/dz[0])>0.9999 && TMath::Abs(kfdzwith[0]/dz[0])<1.0001) fStat->Fill(2); // swapped sign
+ if(kfdzwith[0]==0 && dz[0]!=0) fStat->Fill(3);  // 0 from KF particle (with current track)
+
+ if(dz[0]!=0 && dz[0]*kfdz[0]>0 && TMath::Abs(kfdz[0]/dz[0])>0.8 && TMath::Abs(kfdz[0]/dz[0])<1.2) fStat->Fill(-1);; // same 
+ if(dz[0]!=0 && dz[0]*kfdz[0]<0 && TMath::Abs(kfdz[0]/dz[0])>0.8 && TMath::Abs(kfdz[0]/dz[0]) <1.2) fStat->Fill(-2); // swapped sign
+ if(kfdz[0]==0 && dz[0]!=0) fStat->Fill(-3);  // 0 from KF particle (without current track)
+
+ for(Int_t iPart=0; iPart<(kNParticles-2); iPart++){    
+   // identified ones
+   for(Int_t iPtBin=0; iPtBin<kNPtBins; iPtBin++){
+     if(esdpt>fgkPtIntv[iPtBin] && esdpt<=fgkPtIntv[iPtBin+1]){
+       if(pdg==fgkPdgParticle[iPart]) {
+         fHistKFDcaXY[iPart][iPtBin]->Fill(kfdzwith[0]*1.0e4); 
+         fHistKFDcaZ[iPart][iPtBin]->Fill(kfdzwith[1]*1.0e4);  
+       }  // mc pdg      
+     } // pt range
+
+     else
+       continue;
+   }  // pt loop
+ } // particle id loop
+
+ // for charged particles: no pid
+ 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;
+     fHistKFDcaXY[iPart][iPtBin]->Fill(kfdzwith[0]*1e4);
+     fHistKFDcaZ[iPart][iPtBin]->Fill(kfdzwith[1]*1e4);
+
+   }
+   else
+     continue;
+ } // pt  
+
+}  // KF dca
+
+
+//_______________________________________________________________________________________________
+void AliHFEdca::FillHistogramsVtx(AliESDEvent *const esdEvent, AliMCEvent *const mcEvent)
+{
+
+ // MC vertex
+ AliMCVertex *mcPrimVtx = (AliMCVertex *)mcEvent->GetPrimaryVertex();      
+ Double_t mcPrimV[3];
+ mcPrimV[0] = mcPrimVtx->GetX();
+ mcPrimV[1] = mcPrimVtx->GetY();
+ mcPrimV[2] = mcPrimVtx->GetZ();
+
+// obtaining errors of dca ------------------------------------------------------------------
+ const AliESDVertex *primVtx = esdEvent->GetPrimaryVertex();      
+ Double_t primV[3];
+ primV[0] = primVtx->GetXv();
+ primV[1] = primVtx->GetYv();
+ primV[2] = primVtx->GetZv();
+
+ for(Int_t i=0; i<kNVertexVar; i++){
+   fHistMCvertex[i]->Fill(mcPrimV[i]*1.0e4); 
+   fHistESDvertex[i]->Fill(primV[i]*1.0e4); 
+ }
+
+}
+
+//_______________________________________________________________________________________________
+void AliHFEdca::FillHistogramsPid(AliESDtrack * const track, AliMCEvent * const mcEvent)
+{
+
+
+// filling historgams track by track
+ Float_t esdpx = track->Px();
+ Float_t esdpy = track->Py();
+ Float_t esdpt = TMath::Sqrt(esdpx*esdpx+esdpy*esdpy);    
+
+ AliMCParticle *mctrack = dynamic_cast<AliMCParticle *>(mcEvent->GetTrack(TMath::Abs(track->GetLabel())));  
+ TParticle *part = mctrack->Particle();
+
+ Float_t mcpx = part->Px();
+ Float_t mcpy = part->Py();
+ Float_t mcpt = TMath::Sqrt(mcpx*mcpx+mcpy*mcpy);
+
+ Int_t pdg = part->GetPdgCode();
+ Int_t esdPid = GetCombinedPid(track);
+
+
+ Double_t ptMom[2] = {mcpt, esdpt};
+ // for combined PID
+ for(Int_t iPart=0; iPart<(kNParticles-2); iPart++){
+   if(pdg==fgkPdgParticle[iPart])                // pid all by MC 
+     fHistMcPid[iPart]->Fill(ptMom[0]);
+
+   if(esdPid==fgkPdgParticle[iPart])             // pid all by combined pid
+     fHistEsdPid[iPart]->Fill(ptMom[1]);    
+ } // loop over particles
+
+ // for charged
+ if(pdg==kPDGelectron || pdg==kPDGmuon || pdg==-kPDGpion || pdg==-kPDGkaon || pdg==-kPDGproton)
+   fHistMcPid[10]->Fill(ptMom[0]);
+ if(pdg==-kPDGelectron || pdg==-kPDGmuon || pdg==kPDGpion || pdg==kPDGkaon || pdg==kPDGproton)
+   fHistMcPid[11]->Fill(ptMom[0]);
+ if(esdPid==kPDGelectron || esdPid==kPDGmuon || esdPid==-kPDGpion || esdPid==-kPDGkaon || esdPid==-kPDGproton)
+   fHistEsdPid[10]->Fill(ptMom[1]);  
+ if(esdPid==-kPDGelectron || esdPid==-kPDGmuon || esdPid==kPDGpion || esdPid==kPDGkaon || esdPid==kPDGproton)
+   fHistEsdPid[11]->Fill(ptMom[1]);  
 }
 
 
+////_______________________________________________________________________________________________
+void AliHFEdca::FillHistogramsDataDca(AliESDEvent * const esdEvent, AliESDtrack * const track, AliESDVertex * const vtxESDSkip)
+{
+// 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);  
+ Int_t charge = track->Charge();
+
+// obtaining errors of dca ------------------------------------------------------------------
+ const AliESDVertex *primVtx = esdEvent->GetPrimaryVertex();      
+ Double_t primV[3];
+ primV[0] = primVtx->GetXv();
+ primV[1] = primVtx->GetYv();
+ primV[2] = primVtx->GetZv();
+
+
+ Float_t magneticField = 0;  // initialized as 5kG
+ magneticField = esdEvent->GetMagneticField();  // in kG
+
+ Double_t beampiperadius=3.;
+ Double_t dz[2];   // error of dca in cm
+ Double_t covardz[3];
+
+ if(!track->PropagateToDCA(primVtx,magneticField, beampiperadius, dz, covardz)) return;  // protection
+ track->PropagateToDCA(primVtx,magneticField, beampiperadius, dz, covardz);
+
+ 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++){
+   if(error[i]!=0)pull[i] = dz[i]/error[i];   // unitless                                                
+ }
+
+ // get dca when current track is not included
+
+ Double_t dzwo[2], covardzwo[3];
+ Double_t pullwo[2] = {0, 0};
+ if(!track->PropagateToDCA(vtxESDSkip, magneticField, beampiperadius, dzwo, covardzwo)) return;   // protection
+ track->PropagateToDCA(vtxESDSkip, magneticField, beampiperadius, dzwo, covardzwo); 
+
+ Double_t errorwo[2] ={TMath::Sqrt(TMath::Abs(covardzwo[0])), TMath::Sqrt(TMath::Abs(covardzwo[2]))};
+ for(Int_t i=0; i<2; i++){
+   if(errorwo[i]!=0) pullwo[i] = dzwo[i]/errorwo[i];   // unitless                                                
+ }
+
+ // do pid 
+ Int_t esdPid = GetCombinedPid(track);
+
+ for(Int_t iPart=0; iPart<(kNParticles-2); iPart++){    
+   // identified ones
+   for(Int_t iPtBin=0; iPtBin<kNPtBins; iPtBin++){
+     if(esdPid==fgkPdgParticle[iPart] && (esdpt>fgkPtIntv[iPtBin] && esdpt<=fgkPtIntv[iPtBin+1])) {
+       fHistDataDcaXY[iPart][iPtBin]->Fill(dz[0]*1e4);
+       fHistDataDcaZ[iPart][iPtBin]->Fill(dz[1]*1e4);      
+       fHistDataDcaXYPull[iPart][iPtBin]->Fill(pull[0]);
+       fHistDataDcaZPull[iPart][iPtBin]->Fill(pull[1]);        
+       // w/o current track
+       fHistDataWoDcaXY[iPart][iPtBin]->Fill(dzwo[0]*1e4);
+       fHistDataWoDcaZ[iPart][iPtBin]->Fill(dzwo[1]*1e4);      
+       fHistDataWoDcaXYPull[iPart][iPtBin]->Fill(pullwo[0]);
+       fHistDataWoDcaZPull[iPart][iPtBin]->Fill(pullwo[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;
+     fHistDataDcaXY[iPart][iPtBin]->Fill(dz[0]*1e4);
+     fHistDataDcaZ[iPart][iPtBin]->Fill(dz[1]*1e4);      
+     fHistDataDcaXYPull[iPart][iPtBin]->Fill(pull[0]);
+     fHistDataDcaZPull[iPart][iPtBin]->Fill(pull[1]);
+     // without current track
+     fHistDataWoDcaXY[iPart][iPtBin]->Fill(dzwo[0]*1e4);
+     fHistDataWoDcaZ[iPart][iPtBin]->Fill(dzwo[1]*1e4);      
+     fHistDataWoDcaXYPull[iPart][iPtBin]->Fill(pullwo[0]);
+     fHistDataWoDcaZPull[iPart][iPtBin]->Fill(pullwo[1]);      
+
+   }
+   else
+     continue;
+ } 
+
+}
+
 //_______________________________________________________________________________________________
-void AliHFEdca::FillHistograms(AliESDEvent * const esdEvent, AliESDtrack * const track, AliMCEvent * const mcEvent)
+void AliHFEdca::FillHistogramsDataVtx(AliESDEvent * const esdEvent)
+{
+
+
+// obtaining errors of dca ------------------------------------------------------------------
+ const AliESDVertex *primVtx = esdEvent->GetPrimaryVertex();      
+ Double_t primV[3];
+ primV[0] = primVtx->GetXv();
+ primV[1] = primVtx->GetYv();
+ primV[2] = primVtx->GetZv();
+
+ // require events with at least 3 contributors for primary vertex construction
+ Int_t nEsdPrimVtxCtrb = primVtx->GetNContributors(); 
+ if(nEsdPrimVtxCtrb<1) return; // for pass 1, no diomond constrain, each event has at least 1 contributor to Vtx
+ for(Int_t i=0; i<kNVertexVar; i++)
+   fHistDatavertex[i]->Fill(primV[i]*1e4);
+
+}
+
+
+////_______________________________________________________________________________________________
+void AliHFEdca::FillHistogramsDataPid(AliESDtrack * const track)
 {
 // 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);  
+ Int_t charge = track->Charge();
+
+ Int_t esdPid = GetCombinedPid(track);
+
+ for(Int_t iPart=0; iPart<kNParticles; iPart++){
+   if(iPart<(kNParticles-2)){
+     if(esdPid==fgkPdgParticle[iPart])  fHistDataEsdPid[iPart]->Fill(esdpt);
+   }     // for identified
 
+   else {
+     if(charge<0) fHistDataEsdPid[10]->Fill(esdpt);
+     if(charge>0) fHistDataEsdPid[11]->Fill(esdpt);
+   }
+ }
+}  
+
+//_________________________________________________________________________________________________
+void AliHFEdca::ApplyExtraCuts(AliESDEvent * const esdEvent, Int_t nMinPrimVtxContributor)
+{ 
+
+ //
+ // only one extra cut, number of contributors to each primary vertex
+ //
+
+ const AliESDVertex *primVtx = esdEvent->GetPrimaryVertex();      
+ Int_t nEsdPrimVtxCtrb = primVtx->GetNContributors(); 
+ if(nEsdPrimVtxCtrb<nMinPrimVtxContributor) return; 
+ // for pass 1, no diomond constrain, each event has at least 1 contributor to Vtx
+
+}
+
+//_____________________________________________________
+Int_t AliHFEdca::GetCombinedPid(AliESDtrack *const track) 
+{
+
+ //combined detector pid             
+ Double_t prob[AliPID::kSPECIES];
+ track->GetESDpid(prob);
+ Double_t priors[5] = {0.01, 0.01, 0.85, 0.10, 0.05};
+
+ Int_t charge = track->Charge();
+ Int_t esdPid = -1; 
+
+ AliPID pid;
+ pid.SetPriors(priors);
+ pid.SetProbabilities(prob);
+
+ // identify particle as the most probable 
+
+ Double_t pelectron = pid.GetProbability(AliPID::kElectron);
+ if(pelectron > pid.GetProbability(AliPID::kMuon) && 
+    pelectron > pid.GetProbability(AliPID::kPion) && 
+    pelectron > pid.GetProbability(AliPID::kKaon) && 
+    pelectron > pid.GetProbability(AliPID::kProton) )  esdPid = -kPDGelectron; 
+
+ Double_t pmuon = pid.GetProbability(AliPID::kMuon);
+ if(pmuon > pid.GetProbability(AliPID::kElectron) && 
+    pmuon > pid.GetProbability(AliPID::kPion) && 
+    pmuon > pid.GetProbability(AliPID::kKaon) && 
+    pmuon > pid.GetProbability(AliPID::kProton) )  esdPid = -kPDGmuon; 
+
+ Double_t ppion = pid.GetProbability(AliPID::kPion);
+ if(ppion > pid.GetProbability(AliPID::kElectron) && 
+    ppion > pid.GetProbability(AliPID::kMuon) && 
+    ppion > pid.GetProbability(AliPID::kKaon) && 
+    ppion > pid.GetProbability(AliPID::kProton) )  esdPid = kPDGpion; 
+
+ Double_t pkaon = pid.GetProbability(AliPID::kKaon);
+ if(pkaon > pid.GetProbability(AliPID::kElectron) && 
+    pkaon > pid.GetProbability(AliPID::kMuon) && 
+    pkaon > pid.GetProbability(AliPID::kPion) && 
+    pkaon > pid.GetProbability(AliPID::kProton) )  esdPid = kPDGkaon; 
+
+ Double_t pproton = pid.GetProbability(AliPID::kProton);
+ if(pproton > pid.GetProbability(AliPID::kElectron) && 
+    pproton > pid.GetProbability(AliPID::kMuon) && 
+    pproton > pid.GetProbability(AliPID::kPion) && 
+    pproton > pid.GetProbability(AliPID::kKaon) )  esdPid = kPDGproton; 
+
+
+ return charge*esdPid;
+
+}
+
+
+// for the HFE pid
+
+//________________________________________________________________________
+void AliHFEdca::CreateHistogramsHfeDca(TList *hfeDcaList){
+ //
+ // define histograms: hfe pid electrons in MC
+ //
+
+ const Int_t nBinsDca = 1000;
+ const Float_t maxXYBinDca = 1000.;
+ const Float_t maxZBinDca = 1000.;
+
+ const Int_t nBinsPull = 1000;
+ const Float_t maxXYBinPull = 20.;
+ const Float_t maxZBinPull = 20.;
+
+ const Char_t *mcOResd[2]={"mcPt", "esdPt"};
+
+ fHistHPDcaXY[2][kNPtBins]=0x0;
+ fHistHPDcaZ[2][kNPtBins]=0x0;
+ fHistHPDcaXYRes[2][kNPtBins]=0x0;
+ fHistHPDcaZRes[2][kNPtBins]=0x0;
+ fHistHPDcaXYPull[2][kNPtBins]=0x0;
+ fHistHPDcaZPull[2][kNPtBins]=0x0;
+
+
+ for(Int_t k=0; k<kNDcaVar; k++){
+
+   TString histTitleDca((const char*)fgkDcaVarTitle[k]);
+   TString histTitleRes((const char*)fgkPullDcaVarTitle[k]);
+   TString histTitlePull((const char*)fgkResDcaVarTitle[k]);
+
+   for(Int_t iPart=0; iPart<2; iPart++){
+     for(Int_t i=0; i<kNPtBins; i++){          
+       TString histHPName((const char*)fgkParticles[iPart*5]);
+       histHPName += Form("_HFEpid_%s_pT-%.2f-%.2f", (const char*)fgkDcaVar[k], fgkPtIntv[i], fgkPtIntv[i+1]);
+       TString histHPNameRes((const char*)fgkParticles[iPart*5]);
+       histHPNameRes += Form("_HFEpid_%s_pT-%.2f-%.2f", (const char*)fgkResDcaVar[k], fgkPtIntv[i], fgkPtIntv[i+1]);
+       TString histHPNamePull((const char*)fgkParticles[iPart*5]);
+       histHPNamePull += Form("_HFEpid_%s_pT-%.2f-%.2f", (const char*)fgkPullDcaVar[k], fgkPtIntv[i], fgkPtIntv[i+1]);
+       
+       if(k==0){
+         fHistHPDcaXY[iPart][i] = new TH1F((const char*)histHPName, (const char*)histTitleDca, nBinsDca, 1-maxXYBinDca, 1+maxXYBinDca);
+         fHistHPDcaXY[iPart][i]->SetLineColor((const int)fgkColorPart[iPart*5]);
+         fHistHPDcaXYRes[iPart][i] = new TH1F((const char*)histHPNameRes, (const char*)histTitleRes, nBinsDca, 1-maxXYBinDca, 1+maxXYBinDca);
+         fHistHPDcaXYRes[iPart][i]->SetLineColor((const int)fgkColorPart[iPart*5]);
+         fHistHPDcaXYPull[iPart][i] = new TH1F((const char*)histHPNamePull, (const char*)histTitlePull, nBinsPull, 1-maxXYBinPull, 1+maxXYBinPull);
+         fHistHPDcaXYPull[iPart][i]->SetLineColor((const int)fgkColorPart[iPart*5]);
+       }
+       
+       if(k==1){
+         fHistHPDcaZ[iPart][i] = new TH1F((const char*)histHPName, (const char*)histTitleDca, nBinsDca, 1-maxZBinDca, 1+maxZBinDca);
+         fHistHPDcaZ[iPart][i]->SetLineColor((const int)fgkColorPart[iPart*5]);
+         fHistHPDcaZRes[iPart][i] = new TH1F((const char*)histHPNameRes, (const char*)histTitleRes, nBinsDca, 1-maxZBinDca, 1+maxZBinDca);
+         fHistHPDcaZRes[iPart][i]->SetLineColor((const int)fgkColorPart[iPart*5]);
+         fHistHPDcaZPull[iPart][i] = new TH1F((const char*)histHPNamePull, (const char*)histTitlePull, nBinsPull, 1-maxZBinPull, 1+maxZBinPull);
+         fHistHPDcaZPull[iPart][i]->SetLineColor((const int)fgkColorPart[iPart*5]);
+       }
+     } // 50 pt bins
+   } //2 nparticles
+ } // 2 dca var
+
+ fHistHfePid[2][2] = 0x0; //!  HFE pid  
+ for(Int_t id=0; id<2; id++){
+   for(Int_t iPart=0; iPart<2; iPart++){
+     TString histTitleHfe((const char*)fgkParticles[iPart*5]);
+     histTitleHfe+=Form("_MC_HfePid_esdPt;p_{T} [GeV/c];counts");
+     TString histNameHfe((const char*)fgkParticles[iPart*5]);
+     histNameHfe+=Form("_MC_HfePid_%s", mcOResd[id]);
+     fHistHfePid[id][iPart] = new TH1F(histNameHfe, histTitleHfe, kNPtBins, fgkPtIntv);
+   }
+ }  
+
+ hfeDcaList->SetOwner();
+ hfeDcaList->SetName("hfeDca");
+ for(Int_t iPart=0; iPart<2; iPart++){
+   for(Int_t iPtBin=0; iPtBin<kNPtBins; iPtBin++){
+     hfeDcaList->Add(fHistHPDcaXY[iPart][iPtBin]);  
+     hfeDcaList->Add(fHistHPDcaZ[iPart][iPtBin]); 
+     hfeDcaList->Add(fHistHPDcaXYRes[iPart][iPtBin]);  
+     hfeDcaList->Add(fHistHPDcaZRes[iPart][iPtBin]); 
+     hfeDcaList->Add(fHistHPDcaXYPull[iPart][iPtBin]);  
+     hfeDcaList->Add(fHistHPDcaZPull[iPart][iPtBin]);
+   }
+   for(Int_t id=0; id<2; id++)
+     hfeDcaList->Add(fHistHfePid[id][iPart]);
+ }
+
+}
+
+
+//________________________________________________________________________
+void AliHFEdca::CreateHistogramsHfeDataDca(TList *hfeDataDcaList){
+ //
+ // define histograms: hfe pid electrons in data
+ //
+
+ const Int_t nBinsDca = 1000;
+ const Float_t maxXYBinDca = 1000.;
+ const Float_t maxZBinDca = 1000.;
+
+ const Int_t nBinsPull = 1000;
+ const Float_t maxXYBinPull = 20.;
+ const Float_t maxZBinPull = 20.;
+
+
+ fHistHPDataDcaXY[2][kNPtBins]=0x0;
+ fHistHPDataDcaZ[2][kNPtBins]=0x0;
+ fHistHPDataDcaXYPull[2][kNPtBins]=0x0;
+ fHistHPDataDcaZPull[2][kNPtBins]=0x0;
+
+ for(Int_t k=0; k<kNDcaVar; k++){
+   TString histTitleDca((const char*)fgkDcaVarTitle[k]);
+   TString histTitlePull((const char*)fgkPullDcaVarTitle[k]);
+   for(Int_t iPart=0; iPart<2; iPart++){
+     for(Int_t i=0; i<kNPtBins; i++){          
+       TString histHPName((const char*)fgkParticles[iPart*5]);
+       histHPName += Form("_HFEpid_%s_pT-%.2f-%.2f", (const char*)fgkDcaVar[k], fgkPtIntv[i], fgkPtIntv[i+1]);
+       TString histHPNamePull((const char*)fgkParticles[iPart*5]);
+       histHPNamePull += Form("_HFEpid_%s_pT-%.2f-%.2f", (const char*)fgkPullDcaVar[k], fgkPtIntv[i], fgkPtIntv[i+1]);
+       
+       if(k==0){
+         fHistHPDataDcaXY[iPart][i] = new TH1F((const char*)histHPName, (const char*)histTitleDca, nBinsDca, 1-maxXYBinDca, 1+maxXYBinDca);
+         fHistHPDataDcaXY[iPart][i]->SetLineColor((const int)fgkColorPart[iPart*5]);
+         fHistHPDataDcaXYPull[iPart][i] = new TH1F((const char*)histHPNamePull, (const char*)histTitlePull, nBinsPull, 1-maxXYBinPull, 1+maxXYBinPull);
+         fHistHPDataDcaXYPull[iPart][i]->SetLineColor((const int)fgkColorPart[iPart*5]);
+       }
+       
+       if(k==1){
+         fHistHPDataDcaZ[iPart][i] = new TH1F((const char*)histHPName, (const char*)histTitleDca, nBinsDca, 1-maxZBinDca, 1+maxZBinDca);
+         fHistHPDataDcaZ[iPart][i]->SetLineColor((const int)fgkColorPart[iPart*5]);
+         fHistHPDataDcaZPull[iPart][i] = new TH1F((const char*)histHPNamePull, (const char*)histTitlePull, nBinsDca, 1-maxZBinPull, 1+maxZBinPull);
+         fHistHPDataDcaZPull[iPart][i]->SetLineColor((const int)fgkColorPart[iPart*5]);
+       }
+       
+     } // 50 pt bins
+   } // 2 particle type
+ } // 2 dca var
+
+ fHistDataHfePid[2] = 0x0; //!  HFE pid  
+ for(Int_t iPart=0; iPart<2; iPart++){
+   TString histTitleHfe((const char*)fgkParticles[iPart*5]);
+   histTitleHfe+=Form("_Data_HfePid_esdPt;p_{T} [GeV/c];counts");
+   TString histNameHfe((const char*)fgkParticles[iPart*5]);
+   histNameHfe+=Form("_Data_HfePid");
+   fHistDataHfePid[iPart] = new TH1F(histNameHfe, histTitleHfe, kNPtBins, fgkPtIntv);
+ }
+
+
+ hfeDataDcaList->SetOwner();
+ hfeDataDcaList->SetName("hfeDataDca");
+ for(Int_t iPart=0; iPart<2; iPart++){
+   for(Int_t iPtBin=0; iPtBin<kNPtBins; iPtBin++){
+     hfeDataDcaList->Add(fHistHPDataDcaXY[iPart][iPtBin]);  
+     hfeDataDcaList->Add(fHistHPDataDcaZ[iPart][iPtBin]); 
+     hfeDataDcaList->Add(fHistHPDataDcaXYPull[iPart][iPtBin]);  
+     hfeDataDcaList->Add(fHistHPDcaZPull[iPart][iPtBin]); 
+
+     hfeDataDcaList->Add(fHistDataHfePid[iPart]);
+   }
+ }
+
+
+}
+
+
+//_______________________________________________________________________________________________
+void AliHFEdca::FillHistogramsHfeDca(AliESDEvent * const esdEvent, AliESDtrack * const track, AliMCEvent * const mcEvent)
+{
+ // the kHFEpid plugin
+
+ AliMCVertex *mcPrimVtx = (AliMCVertex *)mcEvent->GetPrimaryVertex();      
+ Double_t mcPrimV[3];
+ mcPrimV[0] = mcPrimVtx->GetX();
+ mcPrimV[1] = mcPrimVtx->GetY();
+ mcPrimV[2] = mcPrimVtx->GetZ();
+
+ Double_t mcVtxXY = TMath::Abs(mcPrimV[0]*mcPrimV[0] + mcPrimV[1]*mcPrimV[1]);
+
+// 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);
-  
+ Float_t esdpx = track->Px();
+ Float_t esdpy = track->Py();
+ Float_t esdpt = TMath::Sqrt(esdpx*esdpx+esdpy*esdpy);  
+
+// obtaining errors of dca ------------------------------------------------------------------
+ const AliESDVertex *primVtx = esdEvent->GetPrimaryVertex();      
+ Double_t primV[3];
+ primV[0] = primVtx->GetXv();
+ primV[1] = primVtx->GetYv();
+ primV[2] = primVtx->GetZv();
+
+ Float_t magneticField = 0;  // initialized as 5kG
+ magneticField = esdEvent->GetMagneticField();  // in kG
+
+ Double_t beampiperadius=3.;
+ Double_t dz[2];   // error of dca in cm
+ Double_t covardz[3];
+ if(!track->PropagateToDCA(primVtx,magneticField, beampiperadius, dz, covardz)) return; // protection
+ track->PropagateToDCA(primVtx,magneticField, beampiperadius, dz, covardz);
+
+ AliMCParticle *mctrack = dynamic_cast<AliMCParticle *>(mcEvent->GetTrack(TMath::Abs(track->GetLabel())));  
+ TParticle *part = mctrack->Particle();
+
+ 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);
+
+ Int_t pdg = part->GetPdgCode();
+
+ Int_t charge = 1;
+ if(pdg==kPDGelectron || pdg==kPDGmuon 
+    || pdg==-kPDGpion || pdg==-kPDGkaon || pdg==-kPDGproton) charge = -1;
+
+ // calculate mcDca ------------------------------------------------------------------ 
+ 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, radius in meter
+
+ Float_t nx = esdpx/mcpt;
+ Float_t ny = esdpy/mcpt;
+
+ Float_t radius;
+ radius = TMath::Abs(radiusMc);
+
+ Double_t dxy = vxy - mcVtxXY;   // in cm
+ Double_t dvx = vx - mcPrimV[0]; // in cm
+ Double_t dvy = vy - mcPrimV[1]; // in cm
+
+ Float_t mcDcaXY = (radius - TMath::Sqrt(dxy*dxy/100./100. + radius*radius + 2*radius*charge*(dvx*ny-dvy*nx)/100.)) ;  // in meters
+
+ 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
+ }
+
+ Int_t iPart = -1;
+ if(track->Charge()<0) iPart = 0;  // electron
+ if(track->Charge()>0) iPart = 1;  // positron
+ if(track->Charge()==0) {
+   printf("this is not an electron! Check HFEpid method");
+   return;
+ }
+ for(Int_t iPtBin=0; iPtBin<kNPtBins; iPtBin++){
+   if(esdpt>fgkPtIntv[iPtBin] && esdpt<=fgkPtIntv[iPtBin+1]){
+     fHistHPDcaXYRes[iPart][iPtBin]->Fill(residual[0]*1.0e4);  
+     fHistHPDcaZRes[iPart][iPtBin]->Fill(residual[1]*1.0e4);   
+     fHistHPDcaXYPull[iPart][iPtBin]->Fill(pull[0]);  
+     fHistHPDcaZPull[iPart][iPtBin]->Fill(pull[1]); 
+     fHistHPDcaXY[iPart][iPtBin]->Fill(dz[0]*1.0e4); 
+     fHistHPDcaZ[iPart][iPtBin]->Fill(dz[1]*1.0e4);  
+
+   } // pt range
+
+   else
+     continue;
+ }  // pt loop
+
+ fHistHfePid[iPart][0]->Fill(esdpt);
+ fHistHfePid[iPart][1]->Fill(mcpt);
+
+}
+
+
+//_______________________________________________________________________________________________
+void AliHFEdca::FillHistogramsHfeDataDca(AliESDEvent * const esdEvent, AliESDtrack * const track)
+{
+// 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);  
+ Int_t charge = track->Charge();
+
 // 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;
-  } 
-    
+ const AliESDVertex *primVtx = esdEvent->GetPrimaryVertex();      
+ Double_t primV[3];
+ primV[0] = primVtx->GetXv();
+ primV[1] = primVtx->GetYv();
+ primV[2] = primVtx->GetZv();
+
+ Float_t magneticField = 0;  // initialized as 5kG
+ magneticField = esdEvent->GetMagneticField();  // in kG
+ Double_t beampiperadius=3.; 
+ Double_t dz[2];   // error of dca in cm
+ Double_t covardz[3];
+ if(!track->PropagateToDCA(primVtx,magneticField, beampiperadius, dz, covardz)) return; // protection
+ track->PropagateToDCA(primVtx,magneticField, beampiperadius, dz, covardz);
+
+ 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++){
+   if(error[i]!=0)pull[i] = dz[i]/error[i];   // unitless                                                
+ }
+
+ Int_t iPart = -1;
+ if(charge<0) iPart = 0;  // electron
+ if(charge>0) iPart = 1;  // positron
+ if(charge==0) {
+   printf("this is not an electron! Check HFEpid method\n");
+   return;
+ }
+
+ for(Int_t iPtBin=0; iPtBin<kNPtBins; iPtBin++){
+   if(esdpt>fgkPtIntv[iPtBin] && esdpt<=fgkPtIntv[iPtBin+1]) {
+     fHistHPDataDcaXY[iPart][iPtBin]->Fill(dz[0]*1e4);
+     fHistHPDataDcaZ[iPart][iPtBin]->Fill(dz[1]*1e4);      
+     fHistHPDataDcaXYPull[iPart][iPtBin]->Fill(pull[0]);
+     fHistHPDataDcaZPull[iPart][iPtBin]->Fill(pull[1]);                      
+
+   }
+   else
+     continue;
+ }
+
+ fHistDataHfePid[iPart]->Fill(esdpt);
+
 }
 
index f7203e4..a6446b3 100644 (file)
 **************************************************************************/
 //
 // Class for checking impact parameter (DCA) study 
-// Study DCA in rphi (xy) and z
-// resolution and pull
-// 
+// + study DCA in rphi (xy) and z
+// + resolution and pull
+// + handle both MC and data 
+// + add plugin for primary vertex 
+//
 
 #ifndef ALIHFEDCA_H
 #define ALIHFEDCA_H
@@ -35,6 +37,7 @@ class TList;
 class TObjArray;
 class AliStack;
 class AliMCEvent;
+class AliMCVertex;
 
 class AliESDEvent;
 class AliESDtrack;
@@ -53,27 +56,63 @@ class AliHFEdca : public TObject{
  
   enum{
     kNParticles = 12,
-    kNPtBins = 43,   
+    kNPtBins = 50,   
     kNDcaVar = 2, 
+    kNVertexVar = 3,  
     kNPullVar = 2
   };
 
-  AliHFEdca();
-  AliHFEdca(const AliHFEdca &p); // copy constructor
-  AliHFEdca &operator=(const AliHFEdca &); // assignment operator
-
-  virtual ~AliHFEdca();
+  AliHFEdca(); // default constructor
+  AliHFEdca(const AliHFEdca &ref); // copy constructor
+  AliHFEdca &operator=(const AliHFEdca &ref); // assignment operator
+  virtual ~AliHFEdca(); // destructor
 
   void Initialize();
   void CreateHistogramsPull(TList *pullList);  
   void CreateHistogramsResidual(TList *residualList);  
+  void CreateHistogramsDca(TList *dcaList);  
+
+  void CreateHistogramsKfDca(TList *kfDcaList);  
+
+  void CreateHistogramsDataDca(TList *dataDcaList);  
+  void CreateHistogramsDataPull(TList *dataPullList);  
+
+  void CreateHistogramsVertex(TList *vertexList);  
+  void CreateHistogramsDataVertex(TList *vertexList);  
+
+  void CreateHistogramsPid(TList *pidList);
+  void CreateHistogramsDataPid(TList *pidList);
+
+  void CreateHistogramsHfeDca(TList *hfeDcaList);
+  void CreateHistogramsHfeDataDca(TList *hfeDataDcaList);
+
+  
   void InitAnalysis();  
-  void FillHistograms(AliESDEvent *esdEvent,  AliESDtrack *track,  AliMCEvent *mcEvent);
+  void FillHistogramsDca(AliESDEvent *esdEvent,  AliESDtrack *track,  AliMCEvent *mcEvent);
+  void FillHistogramsVtx(AliESDEvent *esdEvent,  AliMCEvent *mcEvent);
+  void FillHistogramsPid(AliESDtrack *track,  AliMCEvent *mcEvent);
+
+  void FillHistogramsKfDca(AliESDEvent *esdEvent,  AliESDtrack *track,  AliMCEvent *mcEvent);
+
+  void FillHistogramsDataDca(AliESDEvent *esdEvent,  AliESDtrack *track, AliESDVertex *vtxESDSkip);
+  void FillHistogramsDataVtx(AliESDEvent *esdEvent);
+  void FillHistogramsDataPid(AliESDtrack *track);
+
+  void FillHistogramsHfeDca(AliESDEvent *esdEvent,  AliESDtrack *track,  AliMCEvent *mcEvent);
+  void FillHistogramsHfeDataDca(AliESDEvent *esdEvent,  AliESDtrack *track);
+
+
+  void ApplyExtraCuts(AliESDEvent * const esdEvent, Int_t nMinPrimVtxContributor);
+
   void PostAnalysis() const;
 
+  Int_t GetCombinedPid(AliESDtrack *track);
 
  private:   
-  static const Char_t *fgkParticles[kNParticles];  // particle names
+
+
+  static const Char_t* fgkParticles[kNParticles];  // particle names
+  static const Int_t fgkPdgParticle[kNParticles-2]; // identified particle's name
   static const Int_t fgkColorPart[kNParticles]; // colors for particles
 
   static const Float_t fgkPtIntv[kNPtBins+1];  // pt intervals
@@ -81,17 +120,76 @@ class AliHFEdca : public TObject{
   static const Char_t* fgkDcaVar[kNDcaVar];  // dca variables
   static const Char_t* fgkDcaVarTitle[kNDcaVar]; // titles for dca variables
 
+  static const Char_t* fgkVertexVar[kNVertexVar];  // dca variables
+  static const Char_t* fgkVertexVarTitle[kNVertexVar]; // titles for dca variables
+
+  static const Char_t* fgkResDcaVar[kNDcaVar];  // dca variables
+  static const Char_t* fgkResDcaVarTitle[kNDcaVar]; // titles for dca variables
+
   static const Char_t* fgkPullDcaVar[kNPullVar];  // pull variables
   static const Char_t* fgkPullDcaVarTitle[kNPullVar]; // titles for pull variables
+  static const Char_t* fgkPullDataDcaVarTitle[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
+  TH1F* fHistDcaXY[kNParticles][kNPtBins]; //! dca XY
+  TH1F* fHistDcaZ[kNParticles][kNPtBins];  //! dca Z
+
+  TH1F* fHistEPDcaXYRes[kNParticles-2][kNPtBins];  //! residuals in XY with esd pid
+  TH1F* fHistEPDcaZRes[kNParticles-2][kNPtBins];   //! residuals in Z with esd pid
+
+  TH1F* fHistEPDcaXYPull[kNParticles-2][kNPtBins]; //! pulls XY with esd pid
+  TH1F* fHistEPDcaZPull[kNParticles-2][kNPtBins];  //! pulls Z with esd pid
+
+  TH1F* fHistEPDcaXY[kNParticles-2][kNPtBins]; //! dca XY with esd pid
+  TH1F* fHistEPDcaZ[kNParticles-2][kNPtBins];  //! dca Z with esd pid
+
+  TH1F* fHistKFDcaXY[kNParticles][kNPtBins]; //! KF dca XY
+  TH1F* fHistKFDcaZ[kNParticles][kNPtBins];  //! KF dca Z
   
+  TH1F* fHistDataDcaXY[kNParticles][kNPtBins]; //! data dca XY
+  TH1F* fHistDataDcaZ[kNParticles][kNPtBins];  //! data dca Z
+  TH1F* fHistDataWoDcaXY[kNParticles][kNPtBins]; //! data dca XY w/o current trk
+  TH1F* fHistDataWoDcaZ[kNParticles][kNPtBins];  //! data dca Z w/o current trk
+
+  TH1F* fHistDataDcaXYPull[kNParticles][kNPtBins]; //! data pull dca XY
+  TH1F* fHistDataDcaZPull[kNParticles][kNPtBins];  //! data pull dca Z 
+  TH1F* fHistDataWoDcaXYPull[kNParticles][kNPtBins]; //! data pull dca XY w/o current trk
+  TH1F* fHistDataWoDcaZPull[kNParticles][kNPtBins];  //! data pull dca Z  w/o current trk
+
+  TH1F* fHistMCvertex[kNVertexVar];    //! vertex MC
+  TH1F* fHistESDvertex[kNVertexVar];   //! vertex ESD
+  TH1F* fHistDatavertex[kNVertexVar];  //! vertex Data
+  
+  TH1F* fHistMcPid[kNParticles];      //! MC pid pt spectra
+  TH1F* fHistEsdPid[kNParticles];     //! ESD pid pt spectra
+
+  TH1F *fHistDataEsdPid[kNParticles];    //! Data ESD pid
+
+  // HFE pid part
+  // MC
+  TH1F* fHistHPDcaXYRes[2][kNPtBins];  //! residuals in XY
+  TH1F* fHistHPDcaZRes[2][kNPtBins];   //! residuals in Z
+  TH1F* fHistHPDcaXYPull[2][kNPtBins]; //! pulls XY
+  TH1F* fHistHPDcaZPull[2][kNPtBins];  //! pulls Z
+  TH1F* fHistHPDcaXY[2][kNPtBins];     //! dca XY
+  TH1F* fHistHPDcaZ[2][kNPtBins];      //! dca Z
+
+  TH1F* fHistHfePid[2][2];             // ! HFE pid pt spectra only for electrons
+
+  // Data
+  TH1F* fHistHPDataDcaXY[2][kNPtBins];     //! data dca XY with HFE pid
+  TH1F* fHistHPDataDcaZ[2][kNPtBins];      //! data dca Z with HFE pid
+  TH1F* fHistHPDataDcaXYPull[2][kNPtBins]; //! data pull dca XY
+  TH1F* fHistHPDataDcaZPull[2][kNPtBins];  //! data pull dca Z 
+
+  TH1F *fHistDataHfePid[2];            //! Data HFE pid
+
+  TH1I* fStat;                         //! counting diff of dca calculated from HF particle and ESD
   ClassDef(AliHFEdca, 1);
 };
 
index aacf6f7..13174da 100644 (file)
@@ -19,6 +19,7 @@
 //
 // Authors:
 //   Hongyan Yang <hongyan@physi.uni-heidelberg.de>
+//   Carlo Bombonati <Carlo.Bombonati@cern.ch>
 //
 
 #include "TMath.h"
 
 #include <TParticle.h>
 #include <TDatabasePDG.h>
-
 #include "THnSparse.h"
+
 #include "AliMCEvent.h"
-#include "AliESDEvent.h"
+#include "AliMCVertex.h"
 #include "AliMCParticle.h"
+#include "AliStack.h" 
+
+#include "AliESDEvent.h"
 #include "AliESDtrack.h"
 
-#include "AliStack.h" 
+#include "AliKFParticle.h"
+#include "AliKFVertex.h"
+
+#include "AliVertexerTracks.h"
+
 
 #include "AliHFEdisplacedElectrons.h"
 
@@ -79,11 +87,13 @@ const Char_t *AliHFEdisplacedElectrons::fgkKineVarTitle[3] ={
 
 //__________________________________________________________
 AliHFEdisplacedElectrons::AliHFEdisplacedElectrons():
-  fDebugLevel(0)
-  , fTHnSparseDcaMcPionInfo(NULL)
+  fDeDebugLevel(0)
+  , fNclustersITS(0)
+  , fMinNprimVtxContributor(1)
   , fTHnSparseDcaMcEleInfo(NULL)
+  , fTHnSparseDcaEsdEleInfo(NULL)
   , fTHnSparseDcaDataEleInfo(NULL)
-  , fOutputList(0x0)
+  , fDeOutputList(0x0)
 {
   //
   // default constructor
@@ -94,11 +104,13 @@ AliHFEdisplacedElectrons::AliHFEdisplacedElectrons():
 //__________________________________________________________
 AliHFEdisplacedElectrons::AliHFEdisplacedElectrons(const AliHFEdisplacedElectrons &ref):
   TObject(ref)
-  , fDebugLevel(ref.fDebugLevel)
-  , fTHnSparseDcaMcPionInfo(ref.fTHnSparseDcaMcPionInfo)
+  , fDeDebugLevel(ref.fDeDebugLevel)
+  , fNclustersITS(ref.fNclustersITS)
+  , fMinNprimVtxContributor(ref.fMinNprimVtxContributor)
   , fTHnSparseDcaMcEleInfo(ref.fTHnSparseDcaMcEleInfo)
+  , fTHnSparseDcaEsdEleInfo(ref.fTHnSparseDcaEsdEleInfo)
   , fTHnSparseDcaDataEleInfo(ref.fTHnSparseDcaDataEleInfo)
-  , fOutputList(ref.fOutputList)
+  , fDeOutputList(ref.fDeOutputList)
   
 {
   //
@@ -117,12 +129,13 @@ AliHFEdisplacedElectrons&AliHFEdisplacedElectrons::operator=(const AliHFEdisplac
   if(this == &ref) return *this;
   AliHFEdisplacedElectrons::operator=(ref);
 
-  fDebugLevel = ref.fDebugLevel;
-
-  fTHnSparseDcaMcPionInfo = ref.fTHnSparseDcaMcPionInfo;
+  fDeDebugLevel = ref.fDeDebugLevel;
+  fNclustersITS = ref.fNclustersITS;
+  fMinNprimVtxContributor = ref.fMinNprimVtxContributor;
   fTHnSparseDcaMcEleInfo = ref.fTHnSparseDcaMcEleInfo;
+  fTHnSparseDcaEsdEleInfo = ref.fTHnSparseDcaEsdEleInfo;
   fTHnSparseDcaDataEleInfo = ref.fTHnSparseDcaDataEleInfo;
-  fOutputList = ref.fOutputList;
+  fDeOutputList = ref.fDeOutputList;
 
   return *this;
 }
@@ -134,16 +147,16 @@ AliHFEdisplacedElectrons::~AliHFEdisplacedElectrons()
   // default constructor
   //
 
-  if(fTHnSparseDcaMcPionInfo) 
-    delete fTHnSparseDcaMcPionInfo;
   if(fTHnSparseDcaMcEleInfo) 
     delete fTHnSparseDcaMcEleInfo;
+  if(fTHnSparseDcaEsdEleInfo) 
+    delete fTHnSparseDcaEsdEleInfo;
   if(fTHnSparseDcaDataEleInfo) 
     delete fTHnSparseDcaDataEleInfo;
     
-  if(fOutputList){
-    fOutputList->Clear();
-    delete fOutputList;
+  if(fDeOutputList){
+    fDeOutputList->Clear();
+    delete fDeOutputList;
     
   }
 
@@ -166,13 +179,12 @@ void AliHFEdisplacedElectrons::InitAnalysis(){
 void AliHFEdisplacedElectrons::CreateOutputs(TList* const displacedList){
 
   //
-  //  create output fOutputList
+  //  create output fDeOutputList
   //
 
   // 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
+  // 8+? interested electron sources: others, photon conv, direct photon,  pi0, eta, b, b->c, c + pion or missid, and missid pion
+  // 41 possible DCA cuts XY: 
   // 13 pT bins
   // 10 rapidity bins
   // 10 azimuthal angle phi bins
@@ -180,29 +192,36 @@ void AliHFEdisplacedElectrons::CreateOutputs(TList* const displacedList){
 
   if(!displacedList) return;
 
-  fOutputList = displacedList;
-  fOutputList -> SetName("information");
+  fDeOutputList = displacedList;
+  fDeOutputList -> SetName("displacedElectrons");
 
   // electron source 
-  Int_t nBinsEleSource = 8;
+  Int_t nBinsEleSource = 10;
   Double_t minEleSource = -1.5; 
-  Double_t maxEleSource = 6.5;  
+  Double_t maxEleSource = 9.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;
+  // dca bins:  XY 
+  Int_t nBinsDcaXY = kNDcaMin-1;  // 41 bins
+  Double_t minDcaXY = -20.5; 
+  Double_t maxDcaXY = 20.5; 
+  Double_t dcaXYBinWidth = (maxDcaXY-minDcaXY)/nBinsDcaXY;
+  Double_t *binLimDcaXY = new Double_t[nBinsDcaXY+1];
+  for(Int_t i=0; i<=nBinsDcaXY; i++)
+    binLimDcaXY[i] = minDcaXY + i*dcaXYBinWidth;
+
+
+  // dca bins:  Z
+  Int_t nBinsDcaZ = kNDcaMin/2;  // 21 bins
+  Double_t minDcaZ = -10.5; 
+  Double_t maxDcaZ = 10.5; 
+  Double_t dcaZBinWidth = (maxDcaZ-minDcaZ)/nBinsDcaZ;
+  Double_t *binLimDcaZ = new Double_t[nBinsDcaZ+1];
+  for(Int_t i=0; i<=nBinsDcaZ; i++)
+    binLimDcaZ[i] = minDcaZ + i*dcaZBinWidth;
   
-
  // pt bins
   Int_t nBinsPt = kNPtIntv-1;
   Double_t *binLimPt = new Double_t[nBinsPt+1];
@@ -226,140 +245,267 @@ void AliHFEdisplacedElectrons::CreateOutputs(TList* const displacedList){
     binLimPhi[i] = minPhi + i*(maxPhi-minPhi)/nBinsPhi;
 
 
+  fTHnSparseDcaMcEleInfo = 0x0;
+  fTHnSparseDcaEsdEleInfo = 0x0;
+  fTHnSparseDcaDataEleInfo = 0x0;
 
-  //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 only: MC electron ID
+  const Int_t nVarMc = 6;
+  Int_t iBinMc[nVarMc] = {nBinsEleSource, nBinsDcaXY, nBinsDcaZ, nBinsPt, nBinsRap, nBinsPhi};
+     
+  fTHnSparseDcaMcEleInfo = new THnSparseF("dcaMcElectronInfo", 
+                                          "MC electrons;electron source ID;mc dcaXY [50 #mum];mc dcaZ [100 #mum];mc pT [GeV/c];mc y [rapidity];mc #phi [rad];",        
+                                          nVarMc, iBinMc);
+  fTHnSparseDcaMcEleInfo->SetBinEdges(0, binLimEleSource); // electron source
+  fTHnSparseDcaMcEleInfo->SetBinEdges(1, binLimDcaXY);  // dca xy cut
+  fTHnSparseDcaMcEleInfo->SetBinEdges(2, binLimDcaZ);  // dca z cut
+  fTHnSparseDcaMcEleInfo->SetBinEdges(3, binLimPt);   // pt
+  fTHnSparseDcaMcEleInfo->SetBinEdges(4, binLimRap);  // rapidity
+  fTHnSparseDcaMcEleInfo->SetBinEdges(5, binLimPhi);  // phi
+  fTHnSparseDcaMcEleInfo->Sumw2();
+  
+  // for ESD with MC: HFE pid and MC pid
+  const Int_t nVarEsd = 7;
+  Int_t iBin[nVarEsd] = {nBinsEleSource,nBinsDcaXY, nBinsDcaZ, nBinsDcaXY, nBinsPt, nBinsRap, nBinsPhi};
+  
+  fTHnSparseDcaEsdEleInfo 
+    = new THnSparseF("dcaEsdElectronInfo", 
+                    "ESD electrons;electron source ID;esd dcaXY [50 #mum];esd dcaZ [100 #mum];esd dcaXY KF [50 #mum];pT [GeV/c];y [rapidity];#phi [rad];",             
+                    nVarEsd, iBin);
+
+  fTHnSparseDcaEsdEleInfo->SetBinEdges(0, binLimEleSource); // electron source
+  fTHnSparseDcaEsdEleInfo->SetBinEdges(1, binLimDcaXY);  // dca xy without current track
+  fTHnSparseDcaEsdEleInfo->SetBinEdges(2, binLimDcaZ);  // dca z without current track
+  fTHnSparseDcaEsdEleInfo->SetBinEdges(3, binLimDcaXY);  // dca xy kf without current track
+  fTHnSparseDcaEsdEleInfo->SetBinEdges(4, binLimPt);   // pt esd
+  fTHnSparseDcaEsdEleInfo->SetBinEdges(5, binLimRap);  // rapidity esd
+  fTHnSparseDcaEsdEleInfo->SetBinEdges(6, binLimPhi);  // phi esd
+  fTHnSparseDcaEsdEleInfo->Sumw2();
+  
+  // for ESD data: HFE pid
+  const Int_t nVarData = 6;
+  Int_t iBinData[nVarData] = {nBinsDcaXY, nBinsDcaZ, nBinsDcaXY, nBinsPt, nBinsRap, nBinsPhi};  
+  
+  fTHnSparseDcaDataEleInfo 
+    = new THnSparseF("dcaDataElectronInfo", 
+                    "Data electrons;dcaXY [50 #mum];dcaZ [100 #mum];dcaXYkf [50 #mum];pT [GeV/c];y [rapidity];#phi [rad];",
+                    nVarData, iBinData);    
+  fTHnSparseDcaDataEleInfo->SetBinEdges(0, binLimDcaXY);  // dca xy cut w/o
+  fTHnSparseDcaDataEleInfo->SetBinEdges(1, binLimDcaZ);  // dca z cut w/o
+  fTHnSparseDcaDataEleInfo->SetBinEdges(2, binLimDcaXY);  // dca xy kf cut 
+  fTHnSparseDcaDataEleInfo->SetBinEdges(3, binLimPt);   // pt
+  fTHnSparseDcaDataEleInfo->SetBinEdges(4, binLimRap);  // rapidity
+  fTHnSparseDcaDataEleInfo->SetBinEdges(5, binLimPhi);  // phi
+  fTHnSparseDcaDataEleInfo->Sumw2();
 
-  // 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);
-  }
+  fDeOutputList -> AddAt(fTHnSparseDcaMcEleInfo, kMcElectron);
+  fDeOutputList -> AddAt(fTHnSparseDcaEsdEleInfo, kEsdElectron);
+  fDeOutputList -> AddAt(fTHnSparseDcaDataEleInfo, kDataElectron);
+  
+  AliInfo("THnSparse histograms are created\n");
+  fDeOutputList->Print();
+
+}
 
+
+//__________________________________________________________
+void AliHFEdisplacedElectrons::FillMcOutput(AliESDEvent *const fESD, AliMCEvent* const fMC, AliMCParticle* const mctrack)
+{
+
+  // fill output
+  //0. after mc event cut
+  //1. after checking stack, mcpart etc are valid
+  //2. after PID
+  //3. after event and track selection 
+
+  AliStack *stack = fMC->Stack();
+  TParticle *part = mctrack->Particle();
+
+  // obtain impact parameters in xy and z
+  AliMCVertex *mcPrimVtx = (AliMCVertex *)fMC->GetPrimaryVertex();      
+  Double_t mcPrimV[3];
+  mcPrimV[0] = mcPrimVtx->GetX();
+  mcPrimV[1] = mcPrimVtx->GetY();
+  mcPrimV[2] = mcPrimVtx->GetZ();
+
+ Double_t mcVtxXY = TMath::Abs(mcPrimV[0]*mcPrimV[0] + mcPrimV[1]*mcPrimV[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);
+  Float_t mceta = part->Eta();
+  Float_t mcphi = part->Phi();
+
+  Int_t pdg = part->GetPdgCode();
+  
+  Int_t charge = 1;
+  if(pdg==kPDGelectron || pdg==-kPDGpion) charge = -1;  
+  
+  // calculate mcDca ------------------------------------------------------------------ 
+  const Float_t conv[2] = {1.783/1.6, 2.99792458};
+  Float_t magneticField = 0;  // initialized as 5kG
+  magneticField = fESD->GetMagneticField();  // in kG
+  Float_t radiusMc = mcpt/(TMath::Abs(magneticField)/10.)*conv[0]*conv[1]; // pt in GeV/c, magnetic field in Tesla, radius in meter
+  
+  Float_t radius;
+  radius = TMath::Abs(radiusMc);
+  Float_t nx = mcpx/mcpt;
+  Float_t ny = mcpy/mcpt;
+  Double_t dxy = vxy - mcVtxXY;   // in cm
+  Double_t dvx = vx - mcPrimV[0]; // in cm
+  Double_t dvy = vy - mcPrimV[1]; // in cm
+  Float_t mcDcaXYm = (radius - TMath::Sqrt(dxy*dxy/100./100. + radius*radius + 2*radius*charge*(dvx*ny-dvy*nx)/100.)) ;  // in meters
+  Double_t mcDca[2] = {mcDcaXYm*100, vz};  // in cm
+  Double_t mcDcaXY = mcDca[0]*1.0e4;  // conv dca in cm to dca in micron 
+  Double_t mcDcaZ = mcDca[1]*1.0e4;
+    
+  const Int_t nvarMC=6;
+  Double_t var[nvarMC];
+  var[0] = -1;
   
-  // for ESD: HFE pid
+  if(TMath::Abs(pdg)==kPDGelectron) {
 
-  //  THnSparseF *fTHnSparseDcaDataEleInfo = NULL;  // empty for the moment
-  const Int_t nVarData = 5;
-  Int_t iBinData[nVarData] = {nBinsDca, nBinsDca, nBinsPt, nBinsRap, nBinsPhi};  
+    Int_t eleLabel = mctrack->GetLabel();
+    Int_t sourcePdg = ElectronFromSource(stack, eleLabel);     
+    
+    if(sourcePdg==kPDGgamma){ // check direct photon or not 
+      if(ElePhotonDirect(stack, eleLabel)!=-1) 
+       var[0] = kEleDirectPhotonConv;    
+      else     
+       var[0] = kElePhotonConv;     
+      if(fDeDebugLevel>=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(fDeDebugLevel>=10) printf("pi0======this electron %d is from %d, source id=%.1f\n", eleLabel, sourcePdg, var[0]);    
+    } 
+    
+    if(sourcePdg==kPDGeta){ 
+      var[0] = kEleEta;     
+      if(fDeDebugLevel>=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(fDeDebugLevel>=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(fDeDebugLevel>=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(fDeDebugLevel>=10) printf("others----->electron %d has mother %d is from %.1f\n", eleLabel, ElectronFromSource(stack, eleLabel), var[0]);
+  } // electron source endif 
   
-  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();
+  else
+    if(TMath::Abs(pdg)==kPDGpion)
+      var[0] = kPion;
   
-  fOutputList -> AddAt(fTHnSparseDcaDataEleInfo, kData);
+  if(TMath::Abs(mcDcaXY)<1000) var[1] = Int_t(mcDcaXY)/50;   // larger than 1mm should go to the last bin
+  else
+    var[1] = ((mcDcaXY>0)?1:-1)*20;
   
-  AliInfo("THnSparse histograms are created\n");
-  fOutputList->Print();
+  if(TMath::Abs(mcDcaZ)<1000) var[2] = Int_t(mcDcaZ)/100;
+  else
+    var[2] = ((mcDcaZ>0)?1:-1)*10;
+        
+    var[3] = mcpt;  // pt 
+    var[4] = mceta; // eta
+    var[5] = mcphi; // phi    
 
+    (dynamic_cast<THnSparseF *>(fDeOutputList->At(kMcElectron)))->Fill(var);
 }
 
 
+
 //__________________________________________________________
-void AliHFEdisplacedElectrons::FillMCOutput(AliESDEvent * const fESDEvent, AliESDtrack* const esdTrack, AliStack * const stack)
+void AliHFEdisplacedElectrons::FillEsdOutput(AliESDEvent * const fESDEvent, AliESDtrack* const esdTrack, AliStack * const stack)
 {
+  // after esd event selection, esd track cuts, and hfe pid 
+  // this is the case for ESD tracks, with MC information
 
-  // 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;  
+  Int_t eleLabel = track->GetLabel();
+  if(eleLabel<0 || eleLabel>stack->GetNtrack()) return;  
 
-  TParticle *particle = stack->Particle(label);
+  TParticle *particle = stack->Particle(eleLabel);
   if(!particle) return;
-
-  // obtain impact parameters in xy and y
-  const AliESDVertex *primVtx = fESDEvent->GetPrimaryVertex();      
 
+  // obtain impact parameters in xy and z
+  
   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 beampiperadius=3.;  
+  const AliESDVertex *primVtx = fESDEvent->GetPrimaryVertex();      
 
-  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 nvarESD = 7;
+  Double_t var[nvarESD];
+  var[0] = -1;
 
-  // do PID with MC
+  Int_t sourcePdg = -1;
 
-  if(HasMCData() && TMath::Abs(GetMCpid(stack, label))==kPDGelectron){
+  if(TMath::Abs(particle->GetPdgCode())!=kPDGelectron)
+    if(TMath::Abs(particle->GetPdgCode())!=kPDGpion)
+      var[0] = kEleMissID;
+    else
+      var[0] = kEleMissIDpion;
   
-    Int_t eleLabel = label; 
+  else {
+    sourcePdg = ElectronFromSource(stack, eleLabel);     
     
-    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(sourcePdg==kPDGgamma){ // check direct photon or not 
       if(ElePhotonDirect(stack, eleLabel)!=-1) 
        var[0] = kEleDirectPhotonConv;    
       else     
        var[0] = kElePhotonConv;     
-      if(fDebugLevel>=10) 
+      if(fDeDebugLevel>=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(fDeDebugLevel>=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) 
+      if(fDeDebugLevel>=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) 
+      if(fDeDebugLevel>=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**      
@@ -371,61 +517,87 @@ void AliHFEdisplacedElectrons::FillMCOutput(AliESDEvent * const fESDEvent, AliES
       //            electron from c->e     
       if(ElectronFromCharm(stack, eleLabel)!=-1){
        var[0] = ElectronFromCharm(stack, eleLabel);
-       if(fDebugLevel>=10)
+       if(fDeDebugLevel>=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
+  }  // correct pid 
     
-    (dynamic_cast<THnSparseF *>(fOutputList->At(kMCpion)))->Fill(varPion);
+  // excluding current track
+  // ---- beginning --- method from Andrea D 28.05.2010
+  AliVertexerTracks *vertexer = new AliVertexerTracks(magneticField);
+  vertexer->SetITSMode();
+  vertexer->SetMinClusters(fNclustersITS);
+  Int_t skipped[2];
+  skipped[0] = (Int_t)track->GetID();
+  vertexer->SetSkipTracks(1,skipped);
+  AliESDVertex *vtxESDSkip = (AliESDVertex*)vertexer->FindPrimaryVertex(fESDEvent);
+  delete vertexer; vertexer = NULL;
+  if(vtxESDSkip->GetNContributors()<fMinNprimVtxContributor) return;
+  // -- ending --- method from Andrea D 28.05.2010 
+  
+  Double_t dz[2];   // error of dca in cm
+  Double_t covardz[3];
+  if(!track->PropagateToDCA(vtxESDSkip,magneticField, beampiperadius, dz, covardz)) return; // protection    
+  
+  Double_t dcaXY = dz[0]*1.0e4;  // conv dca in cm to dca in micron 
+  Double_t dcaZ = dz[1]*1.0e4;  
+  
+  if(fDeDebugLevel>=10) printf("others----->electron %d has mother %d is from %.1f\n", eleLabel, ElectronFromSource(stack, eleLabel), var[0]);
+  
+  if(TMath::Abs(dcaXY)<1000) var[1] = Int_t(dcaXY)/50;   // larger than 1mm should go to the last bin
+  else
+    var[1] = ((dcaXY>0)?1:-1)*20;
+  
+  if(TMath::Abs(dcaZ)<1000) var[2] = Int_t(dcaZ)/100;
+  else
+    var[2] = ((dcaZ>0)?1:-1)*10;
+  
+  // calculate dca using AliKFParticle class------------------------------------------------------------------
+  Float_t  kfDcaXY = 0;
+  Int_t trkID = track->GetID();  
+  AliKFParticle::SetField(magneticField);
+  AliKFParticle kfParticle(*track, particle->GetPdgCode());  
+  // prepare kfprimary vertex
+  AliKFVertex kfESDprimary;
+  // Reconstruct Primary Vertex (with ESD tracks)
+  Int_t n=primVtx->GetNIndices();
+  if (n>0 && primVtx->GetStatus()){
+    kfESDprimary = AliKFVertex(*primVtx);        
+    UShort_t *priIndex = primVtx->GetIndices();    
+    for (Int_t i=0;i<n;i++){
+      Int_t idx = Int_t(priIndex[i]);
+      if (idx == trkID){
+       kfESDprimary -= kfParticle;
+       kfDcaXY = kfParticle.GetDistanceFromVertexXY(kfESDprimary)*1e4;
+      }  // remove current track from this calculation
+    }  // loop over all primary vertex contributors    
   }
+  // end of KF dca
+  
+  if(TMath::Abs(kfDcaXY)<1000) 
+    var[3] = Int_t(kfDcaXY)/50;
+  else
+    var[3] = (kfDcaXY>0?1:-1)*20;
+  
+  var[4] = pt;  // pt 
+  var[5] = eta; // eta
+  var[6] = phi; // phi    
+  
+  (dynamic_cast<THnSparseF *>(fDeOutputList->At(kEsdElectron)))->Fill(var);
   
 }
 
-
-
 //__________________________________________________________
-void AliHFEdisplacedElectrons::FillESDOutput(AliESDEvent * const fESDEvent, AliESDtrack* const esdTrack)
+void AliHFEdisplacedElectrons::FillDataOutput(AliESDEvent * const fESDEvent, AliESDtrack* const esdTrack)
 {
+  
+  // this is pure data, without MC information at all
+  // fill output: with HFE pid selection of electrons after all track quality cuts 
 
-  // fill output
   if(!esdTrack) return;
   AliESDtrack *track = esdTrack;
-
+  
   Double_t pt   = track->Pt();
   Double_t eta = track->Eta();
   Double_t phi = track->Phi();
@@ -435,30 +607,75 @@ void AliHFEdisplacedElectrons::FillESDOutput(AliESDEvent * const fESDEvent, AliE
   
   Float_t magneticField = 5;  // initialized as 5kG
   magneticField = fESDEvent->GetMagneticField();  // in kG 
+  Double_t beampiperadius=3.;     
+  
+  const Int_t nvarData = 6;
+  Double_t varData[nvarData]; 
+    
+  //
+  // excluding current track
+  //
+  
+  //------ beginning --- method from Andrea D 28.05.2010
+  AliVertexerTracks *vertexer = new AliVertexerTracks(fESDEvent->GetMagneticField());
+  vertexer->SetITSMode();
+  vertexer->SetMinClusters(fNclustersITS);
+  Int_t skipped[2];
+  skipped[0] = (Int_t)track->GetID();
+  vertexer->SetSkipTracks(1,skipped);
+  AliESDVertex *vtxESDSkip = (AliESDVertex*)vertexer->FindPrimaryVertex(fESDEvent);
+  delete vertexer; vertexer = NULL;
+  if(vtxESDSkip->GetNContributors()<fMinNprimVtxContributor) return;
+  //------ ending --- method from Andrea D 28.05.2010 
   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);
+
+  if(!track->PropagateToDCA(vtxESDSkip,magneticField, beampiperadius, dz, covardz)) return; // protection 
   
-  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 
+  Double_t dcaXY = dz[0]*1.0e4;  // conv dca in cm to dca in micron 
+  Double_t dcaZ = dz[1]*1.0e4;
+   
+  if(TMath::Abs(dcaXY)<1000) varData[0] = Int_t(dcaXY)/50;   // larger than 1mm should go to the last bin
+  else
+    varData[0] = (dcaXY>0?1:-1)*20;
+  if(TMath::Abs(dcaZ)<1000) varData[1] = Int_t(dcaZ)/100;
+  else
+    varData[1] = (dcaZ>0?1:-1)*10;
+
+
+  // calculate dca using AliKFParticle class------------------------------------------------------------------
+  Float_t  kfDcaXY = 0;
+  Int_t trkID = track->GetID();  
+  AliKFParticle::SetField(magneticField);
+  AliKFParticle kfParticle(*track, -11*track->Charge());  
+  // prepare kfprimary vertex
+  AliKFVertex kfESDprimary;
+  // Reconstruct Primary Vertex (with ESD tracks)
+  Int_t n=primVtx->GetNIndices();
+  if (n>0 && primVtx->GetStatus()){
+    kfESDprimary = AliKFVertex(*primVtx);        
+    UShort_t *priIndex = primVtx->GetIndices();    
+    for (Int_t i=0;i<n;i++){
+      Int_t idx = Int_t(priIndex[i]);
+      if (idx == trkID){
+         kfESDprimary -= kfParticle;
+         kfDcaXY = kfParticle.GetDistanceFromVertexXY(kfESDprimary)*1e4;
+      }  // remove current track from this calculation
+    }  // loop over all primary vertex contributors    
+  }
+  if(TMath::Abs(kfDcaXY)<1000)
+    varData[2] = Int_t(kfDcaXY)/50;
   else
-    varData[1] = 20;
+    varData[2] = ((kfDcaXY)>0?1:-1)*20;
+  // end of KF dca
 
-  varData[2] = pt; // pt 
-  varData[3] = eta; //eta
-  varData[4] = phi; // phi
+  varData[3] = pt; // pt 
+  varData[4] = eta; //eta
+  varData[5] = phi; // phi
   
-  (dynamic_cast<THnSparseF *>(fOutputList->At(kData)))->Fill(varData);
+  (dynamic_cast<THnSparseF *>(fDeOutputList->At(kDataElectron)))->Fill(varData);
 
 }
 
@@ -487,7 +704,7 @@ Int_t AliHFEdisplacedElectrons::ElectronFromSource(AliStack * const stack, Int_t
   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",
+    if(fDeDebugLevel>=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);
   }
@@ -515,7 +732,7 @@ Int_t AliHFEdisplacedElectrons::ElectronFromCharm(AliStack * const stack, Int_t
   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);
+    if(fDeDebugLevel>=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
   
index 8ab6928..cba6f1e 100644 (file)
@@ -18,7 +18,8 @@
 // by DCA cuts, background subtraction 
 //
 // Authors:
-//   Hongyan Yang <hongyan@physi.uni-heidelberg.de>
+//  Hongyan Yang <hongyan@physi.uni-heidelberg.de>
+//  Carlo Bombonati <Carlo.Bombonati@cern.ch>
 // 
 
 #ifndef ALIHFEDISPLACEDELECTRONS_H
@@ -49,6 +50,7 @@ class TObjArray;
 class AliStack;
 class AliMCEvent;
 class AliESDEvent;
+class AliVEvent;
 
 class AliESDtrack;
 class AliESDVertex;
@@ -76,14 +78,17 @@ class AliHFEdisplacedElectrons : public TObject{
   void InitAnalysis();  
   void CreateOutputs(TList* const displacedList);
 
-  void FillMCOutput(AliESDEvent* fESDEvent, AliESDtrack *track, AliStack *stack);
-  void FillESDOutput(AliESDEvent* fESDEvent, AliESDtrack *track);
+  void FillMcOutput(AliESDEvent* fESD, AliMCEvent* fMC, AliMCParticle* mctrack);
+  void FillEsdOutput(AliESDEvent* fESDEvent, AliESDtrack *track, AliStack *stack);
+  void FillDataOutput(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 SetDebugLevel(Int_t debugLevel){ fDeDebugLevel = debugLevel; };
+  void SetNitsCluster(Int_t nITScls){ fNclustersITS = nITScls;};
+  void SetMinPrimVtxContrib(Int_t nContrib){fMinNprimVtxContributor = nContrib;};
 
   void PostAnalysis() const;
 
@@ -104,23 +109,25 @@ class AliHFEdisplacedElectrons : public TObject{
     kEleEta = 3, 
     kEleB = 4, 
     kEleC = 5, 
-    kEleBC = 6
+    kEleBC = 6,
+    kEleMissID = 7,
+    kEleMissIDpion = 8,
+    kPion = 8
   };  // electron source index
   
   enum{
-    kMCpion = 0, 
-    kMCelectron = 1, 
-    kData = 2
+    kMcElectron = 0, 
+    kEsdElectron = 1, 
+    kDataElectron = 2
   };  // MC or Data
 
   enum{
-    kNDcaMin = 21, 
+    kNDcaMin = 42, 
     kNPtIntv = 14, 
     kNKineVar = 3
   };   // several constant to be used
  
-  UInt_t fDebugLevel;   // debug level
-
   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;
@@ -136,12 +143,16 @@ class AliHFEdisplacedElectrons : public TObject{
 
   static const Char_t *fgkKineVar[kNKineVar];  // particle names
   static const Char_t *fgkKineVarTitle[kNKineVar];  // particle names
+  
+  UInt_t fDeDebugLevel;   // debug level
+  Int_t fNclustersITS;  // ITS clusters
+  Int_t fMinNprimVtxContributor;      // minimum number of contributors to the primary vtx
 
-  THnSparseF *fTHnSparseDcaMcPionInfo;   //! container for MC pion part
-  THnSparseF *fTHnSparseDcaMcEleInfo;   //! container for MC electron part
+  THnSparseF *fTHnSparseDcaMcEleInfo;   //! container for MC pion part
+  THnSparseF *fTHnSparseDcaEsdEleInfo;   //! container for MC electron part
   THnSparseF *fTHnSparseDcaDataEleInfo; //! container for Data electron part
 
-  TList *fOutputList;  //! output container
+  TList *fDeOutputList;  //! output container
   ClassDef(AliHFEdisplacedElectrons, 0);
 };
 
index fac7f61..d128133 100644 (file)
@@ -77,6 +77,8 @@ AliHFEefficiency::AliHFEefficiency(const Char_t *name):
   //
   DefineOutput(1, AliHFEcontainer::Class());
   DefineOutput(2, TList::Class());
+
+  SetRunTerminate();
 }
 
 AliHFEefficiency::~AliHFEefficiency(){
@@ -136,13 +138,11 @@ void AliHFEefficiency::UserCreateOutputObjects(){
   // 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("hPt","Pt of the tracks", 40, 0.1, 10, 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);
+  fOutput->CreateTH2F("ptres", "Pt Resolution", 40, 0.1, 10, 200, -1.5, 1.5, 0);
 }
 
 void AliHFEefficiency::UserExec(Option_t *){
@@ -172,14 +172,16 @@ void AliHFEefficiency::UserExec(Option_t *){
       fOutput->Fill("itspixel",1);
     else
       fOutput->Fill("itspixel",0);
-    AliMCParticle *mctrack = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(TMath::Abs(track->GetLabel())));
-    if(mctrack){
-      Int_t motherLabel = mctrack->Particle()->GetFirstMother();
-      if(motherLabel){
-        AliMCParticle *mother = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(motherLabel));
-        fOutput->Fill("mcmother", mother->Particle()->GetPdgCode());
+    if(fMCEvent){
+      AliMCParticle *mctrack = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(TMath::Abs(track->GetLabel())));
+      if(mctrack){
+        Int_t motherLabel = mctrack->Particle()->GetFirstMother();
+        if(motherLabel){
+          AliMCParticle *mother = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(motherLabel));
+          if(mother)fOutput->Fill("mcmother", mother->Particle()->GetPdgCode());
+        }
+        fOutput->Fill("ptres", mctrack->Pt(), (track->Pt() - mctrack->Pt())/mctrack->Pt());
       }
-      fOutput->Fill("ptres", mctrack->Pt(), (track->Pt() - mctrack->Pt())/mctrack->Pt());
     }
   }
   delete iter;
@@ -193,7 +195,12 @@ void AliHFEefficiency::Terminate(Option_t *){
   // Evaluate Results
   //
   fEfficiency = dynamic_cast<AliHFEcontainer *>(GetOutputData(1));
-  if(!fEfficiency) return;
+  if(!fEfficiency){
+    AliError("No Output data available");
+    return;
+  }
+
+  if(!IsRunningTerminate()) return;
   PostProcess();
 
   TList *l = dynamic_cast<TList *>(GetOutputData(2));
index 6de24e3..6de6d7e 100644 (file)
@@ -49,6 +49,8 @@ class AliHFEefficiency : public AliAnalysisTaskSE{
 
     void Load(const char* filename = "EffTask.root");
     void PostProcess();
+    Bool_t IsRunningTerminate() const { return TestBit(kTerminate); }
+    void SetRunTerminate(Bool_t terminate = kTRUE) { SetBit(kTerminate, terminate); }
 
     void CalculatePTsmearing();
     void DrawPtResolution(TList *l);
@@ -58,6 +60,9 @@ class AliHFEefficiency : public AliAnalysisTaskSE{
       kNTracks,
       kPt
     };
+    enum{ // Bit Definition
+      kTerminate = BIT(18)
+    };
     AliHFEefficiency(const AliHFEefficiency &);
     AliHFEefficiency &operator=(const AliHFEefficiency &);
     void DrawSignalEfficiency(AliCFEffGrid *eff, AliCFContainer *cont, Int_t var);
index a6d887b..baa05f5 100644 (file)
@@ -1064,7 +1064,7 @@ Bool_t AliHFEelecbackground::SingleTrackCut(AliESDtrack* const trackPart) const
     ////////////////////
     
     if(fRequireITSStandalone==1) {
-      if(((status & AliESDtrack::kITSin) == 0 || (trackPart->IsPureITSStandalone()) || ((status&AliESDtrack::kITSrefit) ==0))) return kFALSE;
+      if(((status & AliESDtrack::kITSin) == 0 || (trackPart->IsPureITSStandalone()) || ((status&AliESDtrack::kITSrefit)==0))) return kFALSE;
     }
     
     if(fRequireITSStandalone==2) {
index b430e5b..a9ed852 100644 (file)
@@ -34,7 +34,7 @@
 #include <TParticle.h>
 
 #include <AliLog.h>
-#include <AliStack.h>
+#include <AliMCEvent.h>
 #include <AliGenEventHeader.h>
 #include <AliAODMCParticle.h>
 
@@ -50,7 +50,7 @@ ClassImp(AliHFEmcQA)
 
 //_______________________________________________________________________________________________
 AliHFEmcQA::AliHFEmcQA() : 
-        fStack(NULL) 
+       fMCEvent(NULL) 
         ,fMCHeader(NULL)
         ,fMCArray(NULL)
         ,fQAhistos(NULL)
@@ -63,7 +63,7 @@ AliHFEmcQA::AliHFEmcQA() :
 //_______________________________________________________________________________________________
 AliHFEmcQA::AliHFEmcQA(const AliHFEmcQA&p):
         TObject(p)
-        ,fStack(NULL) 
+        ,fMCEvent(NULL) 
         ,fMCHeader(NULL)
         ,fMCArray(NULL)
         ,fQAhistos(p.fQAhistos)
@@ -100,7 +100,7 @@ void AliHFEmcQA::CreateHistograms(const Int_t kquark, Int_t icut, TString hnopt)
 {
   // create histograms
 
-  if (kquark != kCharm && kquark != kBeauty) {
+  if (!(kquark == kCharm || kquark == kBeauty || kquark == kOthers)) {
     AliDebug(1, "This task is only for heavy quark QA, return\n");
     return; 
   }
@@ -123,16 +123,42 @@ void AliHFEmcQA::CreateHistograms(const Int_t kquark, Int_t icut, TString hnopt)
     kqTypeLabel[kDeHadron]="bDeHadron";
     kqTypeLabel[kElectron]="be";
     kqTypeLabel[kElectron2nd]="bce";
+  } else if (kquark == kOthers){
+    kqTypeLabel[kGamma-4]="gammae";
+    kqTypeLabel[kPi0-4]="pi0e";
+    kqTypeLabel[kElse-4]="elsee";
+    kqTypeLabel[kMisID-4]="miside";
   }
-
-
+/*
+  const Double_t kPtbound[2] = {0.001, 50.};
+  Int_t iBin[1];
+  iBin[0] = 100; // bins in pt
+  Double_t* binEdges[1];
+  binEdges[0] =  AliHFEtools::MakeLogarithmicBinning(iBin[0], kPtbound[0], kPtbound[1]);
+  */
+  
   TString hname; 
+  if(kquark == kOthers){
+    for (Int_t iqType = 0; iqType < 4; iqType++ ){
+       hname = hnopt+"Pt_"+kqTypeLabel[iqType];
+       //fHist[iq][iqType][icut].fPt = new TH1F(hname,hname+";p_{T} (GeV/c)",iBin[0],binEdges[0]);
+       fHist[iq][iqType][icut].fPt = new TH1F(hname,hname+";p_{T} (GeV/c)",500,0,50);
+       hname = hnopt+"Y_"+kqTypeLabel[iqType];
+       fHist[iq][iqType][icut].fY = new TH1F(hname,hname,150,-7.5,7.5);
+       hname = hnopt+"Eta_"+kqTypeLabel[iqType];
+       fHist[iq][iqType][icut].fEta = new TH1F(hname,hname,150,-7.5,7.5);
+       // Fill List
+       if(fQAhistos) fHist[iq][iqType][icut].FillList(fQAhistos);
+    }
+    return;
+  }
   for (Int_t iqType = 0; iqType < fgkqType; iqType++ ){
      if (iqType < keHadron && icut > 0) continue; // don't duplicate histogram for quark and hadron
      hname = hnopt+"PdgCode_"+kqTypeLabel[iqType];
      fHist[iq][iqType][icut].fPdgCode = new TH1F(hname,hname,20001,-10000.5,10000.5);
      hname = hnopt+"Pt_"+kqTypeLabel[iqType];
-     fHist[iq][iqType][icut].fPt = new TH1F(hname,hname+";p_{T} (GeV/c)",250,0,50);
+     //fHist[iq][iqType][icut].fPt = new TH1F(hname,hname+";p_{T} (GeV/c)",iBin[0],binEdges[0]);
+     fHist[iq][iqType][icut].fPt = new TH1F(hname,hname+";p_{T} (GeV/c)",500,0,50);
      hname = hnopt+"Y_"+kqTypeLabel[iqType];
      fHist[iq][iqType][icut].fY = new TH1F(hname,hname,150,-7.5,7.5);
      hname = hnopt+"Eta_"+kqTypeLabel[iqType];
@@ -198,12 +224,12 @@ void AliHFEmcQA::GetQuarkKine(TParticle *part, Int_t iTrack, const Int_t kquark)
     }
     Int_t iq = kquark - kCharm; 
 
-    if (iTrack < 0) { 
-      AliDebug(1, "Stack label is negative, return\n");
+    if (iTrack < 0 || !part) { 
+      AliDebug(1, "Stack label is negative or no mcparticle, return\n");
       return; 
     }
 
-    //TParticle *part = fStack->Particle(iTrack); 
+    AliMCParticle *mctrack = NULL;
     Int_t partPdgcode = TMath::Abs(part->GetPdgCode());
 
     // select heavy hadron or not fragmented heavy quark 
@@ -217,7 +243,8 @@ void AliHFEmcQA::GetQuarkKine(TParticle *part, Int_t iTrack, const Int_t kquark)
         iLabel = iTrack;
       } else{ // in case of heavy hadron, start to search for mother heavy parton 
         iLabel = part->GetFirstMother(); 
-        if (iLabel>-1) { partMother = fStack->Particle(iLabel); }
+        if(!(mctrack = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(TMath::Abs(iLabel))))) return; 
+        if (iLabel>-1) { partMother = mctrack->Particle(); }
         else {
           AliDebug(1, "Stack label is negative, return\n");
           return; 
@@ -236,7 +263,8 @@ void AliHFEmcQA::GetQuarkKine(TParticle *part, Int_t iTrack, const Int_t kquark)
           Bool_t isSameString = kTRUE; 
           for (Int_t i=1; i<fgkMaxIter; i++){
              iLabel = iLabel - 1;
-             if (iLabel>-1) { partMother = fStack->Particle(iLabel); }
+             if(!(mctrack = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(TMath::Abs(iLabel))))) return; 
+             if (iLabel>-1) { partMother = mctrack->Particle(); }
              else {
                AliDebug(1, "Stack label is negative, return\n");
                return; 
@@ -391,7 +419,10 @@ void AliHFEmcQA::GetHadronKine(TParticle* mcpart, const Int_t kquark)
     }
     Int_t iq = kquark - kCharm;
 
-    //TParticle* mcpart = fStack->Particle(iTrack);
+    if(!mcpart){
+      AliDebug(1, "no mc particle, return\n");
+      return;
+    }
 
     Int_t iLabel = mcpart->GetFirstMother();
     if (iLabel<0){
@@ -403,6 +434,8 @@ void AliHFEmcQA::GetHadronKine(TParticle* mcpart, const Int_t kquark)
     Int_t pdgcode = mcpart->GetPdgCode();
     Int_t pdgcodeCopy = pdgcode;
 
+    AliMCParticle *mctrack = NULL;
+
     // if the mother is charmed hadron  
     Bool_t isDirectCharm = kFALSE;
     if ( int(abs(pdgcode)/100.) == kCharm || int(abs(pdgcode)/1000.) == kCharm ) {
@@ -420,7 +453,8 @@ void AliHFEmcQA::GetHadronKine(TParticle* mcpart, const Int_t kquark)
                return;
              }
              // if there is an ancester
-             TParticle* mother = fStack->Particle(jLabel);
+             if(!(mctrack = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(TMath::Abs(jLabel))))) return; 
+             TParticle* mother = mctrack->Particle();
              Int_t motherPDG = mother->GetPdgCode();
     
              for (Int_t j=0; j<fNparents; j++){
@@ -450,21 +484,33 @@ void AliHFEmcQA::GetDecayedKine(TParticle* mcpart, const Int_t kquark, Int_t kde
 {
     // decay electron kinematics
     
-    if (kquark != kCharm && kquark != kBeauty) {
+    if (!(kquark == kCharm || kquark == kBeauty || kquark == kOthers)){
       AliDebug(1, "This task is only for heavy quark QA, return\n");
       return; 
     }
     Int_t iq = kquark - kCharm; 
     Bool_t isFinalOpenCharm = kFALSE;
 
-/*
-    if (iTrack < 0) { 
-      AliDebug(1, "Stack label is negative, return\n");
-      return; 
+    if(!mcpart){
+      AliDebug(1, "no mcparticle, return\n");
+      return;
     }
-    */
 
-    //TParticle* mcpart = fStack->Particle(iTrack);
+    if(kquark==kOthers){
+      Int_t esource = -1;
+      if ( abs(mcpart->GetPdgCode()) != kdecayed ) esource = kMisID-4;
+      else esource =GetSource(mcpart)-4; // return for the cases kGamma=4, kPi0=5, kElse=6
+      if(esource==0|| esource==1 || esource==2 || esource==3){
+        fHist[iq][esource][icut].fPt->Fill(mcpart->Pt());
+        fHist[iq][esource][icut].fY->Fill(AliHFEtools::GetRapidity(mcpart));
+        fHist[iq][esource][icut].fEta->Fill(mcpart->Eta());
+        return; 
+      }
+      else {
+        AliDebug(1, "e source is out of defined ranges, return\n");
+        return;
+      }
+    }
 
     if ( abs(mcpart->GetPdgCode()) != kdecayed ) return;
 
@@ -474,12 +520,15 @@ void AliHFEmcQA::GetDecayedKine(TParticle* mcpart, const Int_t kquark, Int_t kde
       return; 
     }
 
-    TParticle *partMother = fStack->Particle(iLabel);
+    AliMCParticle *mctrack = NULL;
+    if(!(mctrack = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(TMath::Abs(iLabel))))) return; 
+    TParticle *partMother = mctrack->Particle();
     TParticle *partMotherCopy = partMother;
     Int_t maPdgcode = partMother->GetPdgCode();
     Int_t maPdgcodeCopy = maPdgcode;
 
     // get mc primary vertex
+    /*
     TArrayF mcPrimVtx;
     if(fMCHeader) fMCHeader->PrimaryVertex(mcPrimVtx);
 
@@ -489,6 +538,8 @@ void AliHFEmcQA::GetDecayedKine(TParticle* mcpart, const Int_t kquark, Int_t kde
 
     // calculated production vertex to primary vertex (in xy plane)
     Float_t decayLxy = TMath::Sqrt((mcPrimVtx[0]-ePoint[0])*(mcPrimVtx[0]-ePoint[0])+(mcPrimVtx[1]-ePoint[1])*(mcPrimVtx[1]-ePoint[1]));
+    */ 
+    Float_t decayLxy = 0;
 
     // if the mother is charmed hadron  
     Bool_t isMotherDirectCharm = kFALSE;
@@ -515,7 +566,8 @@ void AliHFEmcQA::GetDecayedKine(TParticle* mcpart, const Int_t kquark, Int_t kde
              }
 
              // if there is an ancester
-             TParticle* grandMa = fStack->Particle(jLabel);
+             if(!(mctrack = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(TMath::Abs(jLabel))))) return; 
+             TParticle* grandMa = mctrack->Particle();
              Int_t grandMaPDG = grandMa->GetPdgCode();
 
              for (Int_t j=0; j<fNparents; j++){
@@ -585,6 +637,11 @@ void  AliHFEmcQA::GetDecayedKine(AliAODMCParticle *mcpart, const Int_t kquark, I
   Int_t iq = kquark - kCharm;
   Bool_t isFinalOpenCharm = kFALSE;
 
+  if(!mcpart){
+    AliDebug(1, "no mcparticle, return\n");
+    return;
+  }
+
   if ( abs(mcpart->GetPdgCode()) != kdecayed ) return;
 
   // mother
@@ -679,7 +736,9 @@ void AliHFEmcQA::IdentifyMother(Int_t motherlabel, Int_t &motherpdg, Int_t &gran
          AliDebug(1, "Stack label is negative, return\n");
          return; 
        }
-       TParticle *heavysMother = fStack->Particle(motherlabel);
+       AliMCParticle *mctrack = NULL;
+       if(!(mctrack = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(TMath::Abs(motherlabel))))) return; 
+       TParticle *heavysMother = mctrack->Particle();
        motherpdg = heavysMother->GetPdgCode();
        grandmotherlabel = heavysMother->GetFirstMother();
        AliDebug(1,Form("ancestor pdg code= %d\n",motherpdg));
@@ -690,8 +749,12 @@ void AliHFEmcQA::HardScattering(const Int_t kquark, Int_t &motherID, Int_t &moth
 {
        // mothertype -1 means this heavy quark coming from hard vertex
 
-       TParticle *afterinitialrad1  = fStack->Particle(4);
-       TParticle *afterinitialrad2  = fStack->Particle(5);
+       AliMCParticle *mctrack1 = NULL;
+       AliMCParticle *mctrack2 = NULL;
+       if(!(mctrack1 = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(TMath::Abs(4))))) return; 
+       if(!(mctrack2 = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(TMath::Abs(5))))) return; 
+       TParticle *afterinitialrad1  = mctrack1->Particle();
+       TParticle *afterinitialrad2  = mctrack2->Particle();
            
        motherlabel = -1;
 
@@ -723,8 +786,10 @@ Bool_t AliHFEmcQA::IsFromInitialShower(Int_t inputmotherlabel, Int_t &motherID,
 {
        // mothertype -2 means this heavy quark coming from initial state 
 
+       AliMCParticle *mctrack = NULL;
        if (inputmotherlabel==2 || inputmotherlabel==3){ // mother exist before initial state radiation
-         TParticle *heavysMother = fStack->Particle(inputmotherlabel);
+         if(!(mctrack = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(TMath::Abs(inputmotherlabel))))) return kFALSE; 
+         TParticle *heavysMother = mctrack->Particle();
          motherID = heavysMother->GetPdgCode(); 
          mothertype = -2; // there is mother before initial state radiation
          motherlabel = inputmotherlabel;
@@ -741,8 +806,10 @@ Bool_t AliHFEmcQA::IsFromFinalParton(Int_t inputmotherlabel, Int_t &motherID, In
 {
        // mothertype 2 means this heavy quark coming from final state 
 
+       AliMCParticle *mctrack = NULL;
        if (inputmotherlabel > 5){ // mother exist after hard scattering
-         TParticle *heavysMother = fStack->Particle(inputmotherlabel);
+         if(!(mctrack = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(TMath::Abs(inputmotherlabel))))) return kFALSE; 
+         TParticle *heavysMother = mctrack->Particle();
          motherID = heavysMother->GetPdgCode(); 
          mothertype = 2; // 
          motherlabel = inputmotherlabel;
@@ -774,6 +841,11 @@ Int_t AliHFEmcQA::GetSource(AliAODMCParticle * const mcpart)
   Int_t origin = -1;
   Bool_t isFinalOpenCharm = kFALSE;
 
+  if(!mcpart){
+    AliDebug(1, "Stack label is negative or no mcparticle, return\n");
+    return -1;
+  }
+
   // mother
   Int_t iLabel = mcpart->GetMother();
   if (iLabel<0){
@@ -851,13 +923,20 @@ Int_t AliHFEmcQA::GetSource(TParticle * const mcpart)
   Int_t origin = -1;
   Bool_t isFinalOpenCharm = kFALSE;
 
+  if(!mcpart){
+    AliDebug(1, "no mcparticle, return\n");
+    return -1;
+  }
+
   Int_t iLabel = mcpart->GetFirstMother();
   if (iLabel<0){
     AliDebug(1, "Stack label is negative, return\n");
     return -1;
   }
 
-  TParticle *partMother = fStack->Particle(iLabel);
+  AliMCParticle *mctrack = NULL;
+  if(!(mctrack = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(TMath::Abs(iLabel))))) return -1; 
+  TParticle *partMother = mctrack->Particle();
   Int_t maPdgcode = partMother->GetPdgCode();
 
    // if the mother is charmed hadron  
@@ -884,7 +963,8 @@ Int_t AliHFEmcQA::GetSource(TParticle * const mcpart)
         }
 
         // if there is an ancester
-        TParticle* grandMa = fStack->Particle(jLabel);
+        if(!(mctrack = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(TMath::Abs(jLabel))))) return -1; 
+        TParticle* grandMa = mctrack->Particle();
         Int_t grandMaPDG = grandMa->GetPdgCode();
 
         for (Int_t j=0; j<fNparents; j++){
index 118ecc1..dc3fa5b 100644 (file)
@@ -35,7 +35,7 @@ class TH2F;
 class TList;
 class TParticle;
 class TString;
-class AliStack;
+class AliMCEvent;
 class AliGenEventHeader;
 class AliAODMCParticle;
 
@@ -43,9 +43,9 @@ class AliAODMCParticle;
 class AliHFEmcQA: public TObject {
 
   public: 
-    enum heavyType {kCharm=4, kBeauty=5, kElectronPDG=11};
+    enum heavyType {kCharm=4, kBeauty=5, kOthers=6, kElectronPDG=11};
     enum qType {kQuark, kantiQuark, kHadron, keHadron, kDeHadron, kElectron, kElectron2nd};
-    enum SourceType {kDirectCharm=1, kDirectBeauty=2, kBeautyCharm=3, kGamma=4, kPi0=5, kElse=6};
+    enum SourceType {kDirectCharm=1, kDirectBeauty=2, kBeautyCharm=3, kGamma=4, kPi0=5, kElse=6, kMisID=7};
     enum ProcessType {
       kPairCreationFromq,  kPairCreationFromg,  kFlavourExitation,  kGluonSplitting, kInitialPartonShower, kLightQuarkShower
     };
@@ -60,7 +60,7 @@ class AliHFEmcQA: public TObject {
     TList *GetList() const { return fQAhistos; };
     void PostAnalyze() const;
     void CreateHistograms(const Int_t kquark, Int_t icut, TString hnopt=""); // create histograms for mc qa analysis
-    void SetStack(AliStack* const stack){fStack=stack;} // set stack pointer
+    void SetMCEvent(AliMCEvent* const mcEvent){fMCEvent = mcEvent;} 
     void SetGenEventHeader(AliGenEventHeader* const mcHeader){fMCHeader=mcHeader;} // set stack pointer
     void SetMCArray(TClonesArray* const mcarry){fMCArray=mcarry;} // set mcarray pointer
     void Init();
@@ -80,7 +80,7 @@ class AliHFEmcQA: public TObject {
     Bool_t IsFromInitialShower(Int_t inputmotherlabel, Int_t &motherID, Int_t &mothertype, Int_t &motherlabel); // check if the quark is produced from initial parton shower 
     Bool_t IsFromFinalParton(Int_t inputmotherlabel, Int_t &motherID, Int_t &mothertype, Int_t &motherlabel); // check if the quark is produced from final parton shower
 
-    AliStack* fStack; // stack pointer           
+    AliMCEvent* fMCEvent; // mcevent pointer
     AliGenEventHeader* fMCHeader; // mcheader pointer
     TClonesArray *fMCArray; // mc array pointer
 
@@ -154,8 +154,8 @@ class AliHFEmcQA: public TObject {
       void FillList(TList *l) const;
     };
 
-    AliHists fHist[2][7][5]; // struct of histograms to store kinematics of given particles
-    AliHistsComm fHistComm[2][5]; // struct of additional histograms of given particles
+    AliHists fHist[3][7][6]; // struct of histograms to store kinematics of given particles
+    AliHistsComm fHistComm[2][6]; // struct of additional histograms of given particles
 
     TList *fQAhistos;           // Container for QA histos
     TParticle *fHeavyQuark[50]; // store pointer of heavy flavour quark 
index 0e71983..c2d6c0f 100644 (file)
@@ -35,7 +35,9 @@ AliHFEpairs::AliHFEpairs():
   ,fOpenangle(0)
   ,fCosOpenangle(0)
   ,fSignedLxy(0)
+  ,fSignedLxy2(0)
   ,fKFIP(0)
+  ,fKFIP2(0)
 { 
   //
   // Default constructor
@@ -52,7 +54,9 @@ AliHFEpairs::AliHFEpairs(const AliHFEpairs &p):
   ,fOpenangle(p.fOpenangle)
   ,fCosOpenangle(p.fCosOpenangle)
   ,fSignedLxy(p.fSignedLxy)
+  ,fSignedLxy2(p.fSignedLxy2)
   ,fKFIP(p.fKFIP)
+  ,fKFIP2(p.fKFIP2)
 { 
   //
   // Copy constructor
index ff33df9..abae1c3 100644 (file)
@@ -41,7 +41,9 @@ class AliHFEpairs : public TObject {
                 Double_t GetOpenangle() const {return fOpenangle;}
                 Double_t GetCosOpenangle() const {return fCosOpenangle;}
                 Double_t GetSignedLxy() const {return fSignedLxy;}
+                Double_t GetSignedLxy2() const {return fSignedLxy2;}
                 Double_t GetKFIP() const {return fKFIP;}
+                Double_t GetKFIP2() const {return fKFIP2;}
 
                 void SetTrkLabel(Int_t label) {fTrkLabel = label;}
                 void SetInvmass(Double_t invmass) {fInvmass = invmass;}
@@ -49,7 +51,9 @@ class AliHFEpairs : public TObject {
                 void SetOpenangle(Double_t openangle) {fOpenangle = openangle;}
                 void SetCosOpenangle(Double_t cosopenangle) {fCosOpenangle = cosopenangle;}
                 void SetSignedLxy(Double_t signedlxy) {fSignedLxy = signedlxy;}
+                void SetSignedLxy2(Double_t signedlxy2) {fSignedLxy2 = signedlxy2;}
                 void SetKFIP(Double_t kfip) {fKFIP = kfip;}
+                void SetKFIP2(Double_t kfip2) {fKFIP2 = kfip2;}
                 void SetPairCode(Int_t paircode) {fPairCode = paircode;}
 
         protected:
@@ -61,7 +65,9 @@ class AliHFEpairs : public TObject {
                 Double_t fOpenangle;    // pair opening angle 
                 Double_t fCosOpenangle; // pair cos(opening angle)
                 Double_t fSignedLxy;    // pair signed Lxy
+                Double_t fSignedLxy2;   // recalculated pair signed Lxy
                 Double_t fKFIP;         // impact parameter of the pair
+                Double_t fKFIP2;        // recalculated impact parameter of the pair
 
         private:
 
index 9e216bb..41d4365 100644 (file)
@@ -24,6 +24,7 @@
 //
 #include <TAxis.h>
 #include <TClass.h>
+#include <TF1.h>
 #include <THnSparse.h>
 #include <TIterator.h>
 #include <TList.h>
@@ -31,6 +32,7 @@
 #include <TObjString.h>
 #include <TString.h>
 
+#include "AliESDpid.h"
 #include "AliESDtrack.h"
 #include "AliLog.h"
 #include "AliPID.h"
@@ -50,13 +52,13 @@ AliHFEpid::AliHFEpid():
   fEnabledDetectors(0),
   fPIDstrategy(0),
   fQAlist(0x0),
-  fDebugLevel(0)
+  fDebugLevel(0),
+  fCommonObjects(NULL)
 {
   //
   // Default constructor
   //
   memset(fDetectorPID, 0, sizeof(AliHFEpidBase *) * kNdetectorPID);
-  memset(fTPCBetheBlochParameters, 0, sizeof(Double_t) * 5);
 }
 
 //____________________________________________________________
@@ -65,13 +67,13 @@ AliHFEpid::AliHFEpid(const AliHFEpid &c):
   fEnabledDetectors(c.fEnabledDetectors),
   fPIDstrategy(0),
   fQAlist(0x0),
-  fDebugLevel(c.fDebugLevel)
+  fDebugLevel(c.fDebugLevel),
+  fCommonObjects(NULL)
 {
   //
   // Copy Constructor
   //
   memset(fDetectorPID, 0, sizeof(AliHFEpidBase *) * kNdetectorPID);
-  memcpy(fTPCBetheBlochParameters, c.fTPCBetheBlochParameters, sizeof(Double_t)*5);
   if(c.fDetectorPID[kMCpid])
     fDetectorPID[kMCpid] = new AliHFEpidMC(*(dynamic_cast<AliHFEpidMC *>(c.fDetectorPID[kMCpid])));
   if(c.fDetectorPID[kTPCpid])
@@ -102,13 +104,10 @@ AliHFEpid& AliHFEpid::operator=(const AliHFEpid &c){
     fDebugLevel = c.fDebugLevel;
   
     memset(fDetectorPID, 0, sizeof(AliHFEpidBase *) * kNdetectorPID);
-    memcpy(fTPCBetheBlochParameters, c.fTPCBetheBlochParameters, sizeof(Double_t)*5);
     if(c.fDetectorPID[kMCpid])
       fDetectorPID[kMCpid] = new AliHFEpidMC(*(dynamic_cast<AliHFEpidMC *>(c.fDetectorPID[kMCpid])));
     if(c.fDetectorPID[kTPCpid])
       fDetectorPID[kTPCpid] = new AliHFEpidTPC(*(dynamic_cast<AliHFEpidTPC *>(c.fDetectorPID[kTPCpid])));
-      if(fTPCBetheBlochParameters[0] > 1e-6)
-        (dynamic_cast<AliHFEpidTPC *>(fDetectorPID[kTPCpid])->SetBetheBlochParameters(fTPCBetheBlochParameters));
     if(c.fDetectorPID[kTRDpid])
       fDetectorPID[kTRDpid] = new AliHFEpidTRD(*(dynamic_cast<AliHFEpidTRD *>(c.fDetectorPID[kTOFpid])));
     if(c.fDetectorPID[kTOFpid])
@@ -133,6 +132,28 @@ AliHFEpid::~AliHFEpid(){
       delete fDetectorPID[idet];
   } 
   if(fQAlist) delete fQAlist; fQAlist = 0x0;  // Each detector has to care about its Histograms
+  ClearCommonObjects();
+}
+
+//____________________________________________________________
+void AliHFEpid::AddCommonObject(TObject * const o){
+  //
+  // Add common object to the garbage collection
+  //
+  if(!fCommonObjects) fCommonObjects = new TObjArray;
+  fCommonObjects->Add(o);
+}
+
+//____________________________________________________________
+void AliHFEpid::ClearCommonObjects(){
+  //
+  // empty garbage collection
+  //
+  if(fCommonObjects){
+    fCommonObjects->Delete();
+    delete fCommonObjects;
+    fCommonObjects = NULL;
+  }
 }
 
 //____________________________________________________________
@@ -152,12 +173,14 @@ Bool_t AliHFEpid::InitializePID(TString arg){
     AliInfo(Form("PID Strategy %d enabled", fPIDstrategy));
     Int_t strategyStatus = kTRUE;
     switch(fPIDstrategy){
+      case 0: break;    // Pure MC PID - only valid in MC mode
       case 1: InitStrategy1(); break;
       case 2: InitStrategy2(); break;
       case 3: InitStrategy3(); break;
       case 4: InitStrategy4(); break;
       case 5: InitStrategy5(); break;
       case 6: InitStrategy6(); break;
+      case 7: InitStrategy7(); break;
       default: strategyStatus = kFALSE;
     }
     return strategyStatus;
@@ -174,8 +197,6 @@ Bool_t AliHFEpid::InitializePID(TString arg){
     if(det->String().CompareTo("TPC") == 0){
       AliInfo("Doing TPC PID");
       fDetectorPID[kTPCpid] = new AliHFEpidTPC("TPC PID");
-      if(fTPCBetheBlochParameters[0] > 1e-6)
-        (dynamic_cast<AliHFEpidTPC *>(fDetectorPID[kTPCpid])->SetBetheBlochParameters(fTPCBetheBlochParameters));
       SETBIT(fEnabledDetectors, kTPCpid);
     } else if(det->String().CompareTo("TRD") == 0){
       fDetectorPID[kTRDpid] = new AliHFEpidTRD("TRD PID");
@@ -209,15 +230,17 @@ Bool_t AliHFEpid::IsSelected(AliHFEpidObject *track){
     // MC Event
     return (TMath::Abs(fDetectorPID[kMCpid]->IsSelected(track)) == 11);
   }
-  if(fPIDstrategy > 0 && fPIDstrategy < 7){
+  if(fPIDstrategy < 8){
     Int_t pid = 0;
     switch(fPIDstrategy){
+      case 0: pid = IdentifyStrategy0(track); break;
       case 1: pid = IdentifyStrategy1(track); break;
       case 2: pid = IdentifyStrategy2(track); break;
       case 3: pid = IdentifyStrategy3(track); break;
       case 4: pid = IdentifyStrategy4(track); break;
       case 5: pid = IdentifyStrategy5(track); break;
       case 6: pid = IdentifyStrategy6(track); break;
+      case 7: pid = IdentifyStrategy7(track); break;
       default: break;
     }
     return pid;
@@ -252,6 +275,8 @@ Bool_t AliHFEpid::MakePidTpcTof(AliHFEpidObject *track){
   if(track->fAnalysisType != AliHFEpidObject::kESDanalysis) return kFALSE;
   AliESDtrack *esdTrack = dynamic_cast<AliESDtrack *>(track->fRecTrack);
   if(!esdTrack) return kFALSE;
+  // return if TOF information not available
+  if(!(esdTrack->GetStatus() & AliESDtrack::kTOFpid)) return kFALSE;
 
   AliHFEpidTOF *tofPID = dynamic_cast<AliHFEpidTOF*>(fDetectorPID[kTOFpid]);
   if(!tofPID){
@@ -259,62 +284,30 @@ Bool_t AliHFEpid::MakePidTpcTof(AliHFEpidObject *track){
     return kFALSE;
   }
 
-  
   AliHFEpidTPC *tpcPID = dynamic_cast<AliHFEpidTPC*>(fDetectorPID[kTPCpid]);
   if(!tpcPID){
     AliWarning("TPC pid object is NULL");
     return kFALSE;
   }
   
-  // charge of the particle
-  Int_t charge = 0;
-  if(esdTrack->GetOuterParam()) charge = esdTrack->GetOuterParam()->Charge();
-  else charge = esdTrack->GetInnerParam()->Charge();
-  
-  // setup the TPC PID
-  const Int_t cTPCsigma = 2;
-  // set the number of sigmas in the TPC 
-  tpcPID->SetTPCnSigma(cTPCsigma);
-  // turn on the the dEdx line crossing for kaons and protons
-  tpcPID->AddTPCdEdxLineCrossing(3, cTPCsigma);  // for kaons
-  tpcPID->AddTPCdEdxLineCrossing(4, cTPCsigma);  // for protons
-  // request the tpc PID information
-  Int_t pidTPC = tpcPID->IsSelected(track);
-
-  // without TPC pid it makes no sense to look at the TOF pid with this detector combination
-  //if(0 == pidTPC){
-  //  return kFALSE;
-  //}
+  // Use TOF PID to select particles with a sigma to the electron line > defined in initialize PID
+  if(TMath::Abs(tofPID->IsSelected(track)) != 11) return kFALSE;
+  // request TOF PID information, reject if no TOF information is available or if TOF identified as Proton or Kaon
+  // apply cut only up to certain upper momentum cut
+  /*Int_t pidTOF = tofPID->IsSelected(track);
+  Bool_t isRejected = kFALSE;
+  switch(TMath::Abs(pidTOF)){
+    case 321:   if(track->fRecTrack->P() < 1.5) isRejected = kTRUE; break;
+    case 2212:  if(track->fRecTrack->P() < 3) isRejected = kTRUE; break;
+    case 0:     if(track->fRecTrack->P() < 3) isRejected = kTRUE; break;  // No TOF information available
+    default: break;
+  };
+  if(isRejected) return kFALSE;*/
 
-  // is the TPC in the crossing line region? 0 - no crossing, otherwise the AliPID of the crossing
-  // particle returned - 3 for Kaon and 4 for Proton
-  Int_t crossing = tpcPID->GetCrossingType();
+  // Particle passed TOF, let TPC decide, no line crossings defined anymore
  
-  // setup the TOF pid
-  const Int_t cTOFsigma = 3;
-  tofPID->SetTOFnSigma(cTOFsigma);
-  // request TOF PID information
-  Int_t pidTOF = tofPID->IsSelected(track);
-  // case that the TOF for some reason does not deliver a PID information 
-  // or the TPC is not in the crossing point region, only the TPC will be used
-  if(0 != pidTOF && 0 != crossing){
-    if(3 == crossing){
-      return (321 == pidTOF) ? kFALSE : kTRUE;
-    }
-    else if(4 == crossing){
-      return (2212 == pidTOF) ? kFALSE : kTRUE;
-    }    
-    else{
-      // something went wrong
-      AliError("Wrong crossing type returned from AliHFEpidTPC - check your code!!");
-      return kFALSE;
-    }
-  }
-  else{
-    // tpc ONLY
-    return (11 == pidTPC) ? kTRUE : kFALSE;   
-  }
+  // request the tpc PID information
+  return (TMath::Abs(tpcPID->IsSelected(track)) == 11);
 }
 
 //____________________________________________________________
@@ -389,6 +382,16 @@ void AliHFEpid::MakePlotsItsTpc(AliHFEpidObject *track){
 }
 
 //____________________________________________________________
+void AliHFEpid::SetESDpid(AliESDpid *pid){
+  //
+  // Set ESD PID to the Detector PID objects
+  //
+  for(Int_t idet = 0; idet < kNdetectorPID; idet++){
+    if(fDetectorPID[idet]) fDetectorPID[idet]->SetESDpid(pid);
+  }
+}
+
+//____________________________________________________________
 void AliHFEpid::SetQAOn(){
   //
   // Switch on QA
@@ -446,8 +449,6 @@ void AliHFEpid::InitStrategy1(){
   // TPC alone, 3-sigma cut
   //
   AliHFEpidTPC *pid = new AliHFEpidTPC("strat1TPCpid");
-  if(fTPCBetheBlochParameters[0] > 1e-6)
-    pid->SetBetheBlochParameters(fTPCBetheBlochParameters);
   pid->SetTPCnSigma(1);
   Bool_t status = pid->InitializePID();
   if(IsQAOn() && status) pid->SetQAOn(fQAlist);
@@ -461,8 +462,6 @@ void AliHFEpid::InitStrategy2(){
   // TPC alone, symmetric 3 sigma cut and asymmetric sigma cut in the momentum region between 2GeV/c and 10 GeV/c and sigma between -1 and 100
   //
   AliHFEpidTPC *pid = new AliHFEpidTPC("strat2TPCpid");
-  if(fTPCBetheBlochParameters[0] > 1e-6)
-    pid->SetBetheBlochParameters(fTPCBetheBlochParameters);
   pid->SetTPCnSigma(3);
   pid->SetAsymmetricTPCsigmaCut(2., 10., 0., 4.);
   Bool_t status = pid->InitializePID();
@@ -477,8 +476,6 @@ void AliHFEpid::InitStrategy3(){
   // TPC alone, symmetric 3 sigma cut and 2 - -100 sigma pion rejection
   //   
   AliHFEpidTPC *pid = new AliHFEpidTPC("strat3TPCpid");
-  if(fTPCBetheBlochParameters[0] > 1e-6)
-    pid->SetBetheBlochParameters(fTPCBetheBlochParameters);
   pid->SetTPCnSigma(3);
   pid->SetRejectParticle(AliPID::kPion, 0., -100., 10., 1.);
   Bool_t status = pid->InitializePID();
@@ -519,10 +516,22 @@ void AliHFEpid::InitStrategy6(){
   // Combined TPC-TOF PID, combination is discribed in the funtion MakePidTpcTof
   //
   AliHFEpidTPC *tpcpid = new AliHFEpidTPC("strat6TPCpid");
-  if(fTPCBetheBlochParameters[0] > 1e-6)
-    tpcpid->SetBetheBlochParameters(fTPCBetheBlochParameters);
   AliHFEpidTOF *tofpid = new AliHFEpidTOF("strat6TOFpid");
+  tpcpid->SetTPCnSigma(2);
+  tofpid->SetTOFnSigma(3);
   Bool_t status = tpcpid->InitializePID();
+  //TF1 *upperCut = new TF1("upperCut", "[0] * TMath::Exp([1]*x)", 0, 20);
+  TF1 *upperCut = new TF1("upperCut", "[0]", 0, 20); // Use constant upper cut
+  TF1 *lowerCut = new TF1("lowerCut", "[0] * TMath::Exp([1]*x)", 0, 20);
+  upperCut->SetParameter(0, 3.);
+  //upperCut->SetParameter(0, 2.7);
+  //upperCut->SetParameter(1, -0.4357);
+  lowerCut->SetParameter(0, -2.7);
+  lowerCut->SetParameter(1, -0.4357);
+  tpcpid->SetUpperSigmaCut(upperCut);
+  tpcpid->SetLowerSigmaCut(lowerCut);
+  AddCommonObject(upperCut);
+  AddCommonObject(lowerCut);
   if(!status)
     AliError("Initialization of TPC PID failed");
   Bool_t status1 = tofpid->InitializePID();
@@ -542,6 +551,27 @@ void AliHFEpid::InitStrategy6(){
 }
 
 //____________________________________________________________
+void AliHFEpid::InitStrategy7(){
+  //
+  // TPC alone, symmetric 3 sigma cut and 2 - -100 sigma pion rejection
+  //   
+  AliHFEpidTPC *pid = new AliHFEpidTPC("strat7TPCpid");
+  pid->SetTPCnSigma(2);
+  pid->SetRejectParticle(AliPID::kProton, 0., -3., 10., 3.);
+  pid->SetRejectParticle(AliPID::kKaon, 0., -3., 10., 3.);
+  Bool_t status = pid->InitializePID();
+  if(IsQAOn() && status) pid->SetQAOn(fQAlist);
+  if(HasMCData() && status) pid->SetHasMCData();
+  fDetectorPID[kTPCpid] = pid;
+}
+
+
+//____________________________________________________________
+Bool_t AliHFEpid::IdentifyStrategy0(AliHFEpidObject *track){
+  return TMath::Abs(fDetectorPID[kMCpid]->IsSelected(track)) == 11;
+}
+
+//____________________________________________________________
 Bool_t AliHFEpid::IdentifyStrategy1(AliHFEpidObject *track){
   return TMath::Abs(fDetectorPID[kTPCpid]->IsSelected(track)) == 11;
 }
@@ -572,3 +602,14 @@ Bool_t AliHFEpid::IdentifyStrategy6(AliHFEpidObject *track){
   return MakePidTpcTof(track);
 }
 
+//____________________________________________________________
+Bool_t AliHFEpid::IdentifyStrategy7(AliHFEpidObject *track){
+  //
+  // Do PID in strategy 7: Proton and Kaon rejection and 
+  // lower cut on TPC Signal
+  //
+  if(!(TMath::Abs(fDetectorPID[kTPCpid]->IsSelected(track)) == 11))
+    return kFALSE;
+  return kTRUE;
+}
+
index 80a8f23..bce1e20 100644 (file)
@@ -28,7 +28,9 @@
 #include "AliHFEpidBase.h"
 #endif
 
+class AliESDpid;
 class AliESDtrack;
+class AliHFEpidBase;
 class AliVParticle;
 class AliMCParticle;
 
@@ -46,12 +48,12 @@ class AliHFEpid : public TObject{
 
     Bool_t IsQAOn() const { return TestBit(kIsQAOn); };
     Bool_t HasMCData() const { return TestBit(kHasMCData); };
+    void SetESDpid(AliESDpid *pid);
     void SetDebugLevel(Int_t debugLevel) { fDebugLevel = debugLevel; }
     void SetQAOn();
     void SetHasMCData(Bool_t hasMCdata = kTRUE) { SetBit(kHasMCData, hasMCdata); };
     TList *GetQAhistograms() const { return fQAlist; };
 
-    inline void SetTPCBetheBlochParameters(Double_t *pars);
   protected:
     Bool_t MakePidTpcTof(AliHFEpidObject *track);
     Bool_t MakePidTpcTrd(AliHFEpidObject *track);
@@ -64,12 +66,15 @@ class AliHFEpid : public TObject{
     void InitStrategy4();
     void InitStrategy5();
     void InitStrategy6();
+    void InitStrategy7();
+    Bool_t IdentifyStrategy0(AliHFEpidObject *track);
     Bool_t IdentifyStrategy1(AliHFEpidObject *track);
     Bool_t IdentifyStrategy2(AliHFEpidObject *track);
     Bool_t IdentifyStrategy3(AliHFEpidObject *track);
     Bool_t IdentifyStrategy4(AliHFEpidObject *track);
     Bool_t IdentifyStrategy5(AliHFEpidObject *track);
     Bool_t IdentifyStrategy6(AliHFEpidObject *track);
+    Bool_t IdentifyStrategy7(AliHFEpidObject *track);
   private:
     enum{
       kIsQAOn = BIT(14),
@@ -91,18 +96,18 @@ class AliHFEpid : public TObject{
       kTRDSignal = 0,
       kITSSignal = 1
     };
+
+    void AddCommonObject(TObject * const o);
+    void ClearCommonObjects();
+
     AliHFEpidBase *fDetectorPID[kNdetectorPID];     //! Detector PID classes
     UInt_t fEnabledDetectors;                       //  Enabled Detectors
     UInt_t fPIDstrategy;                            //  PID Strategy
-    Double_t fTPCBetheBlochParameters[5];           //  TPC Bethe-Bloch Parameters
     TList *fQAlist;                                 //! QA histograms
     Int_t fDebugLevel;                              //  Debug Level
+    TObjArray *fCommonObjects;                       // Garbage Collector
 
   ClassDef(AliHFEpid, 1)      // Steering class for Electron ID
 };
 
-void AliHFEpid::SetTPCBetheBlochParameters(Double_t *pars){
-  memcpy(fTPCBetheBlochParameters, pars, sizeof(Double_t)*5);
-}
-
 #endif
index 8a86011..2da8eb5 100644 (file)
 // Authors: 
 //   Markus Fasel <M.Fasel@gsi.de> 
 // 
+#include "AliESDpid.h"
 #include "AliHFEpidBase.h"
 
 ClassImp(AliHFEpidBase)
 
 //___________________________________________________________________
+AliHFEpidBase::AliHFEpidBase():
+  TNamed(),
+  fESDpid(NULL),
+  fDebugLevel(0)
+{
+  //
+  // Default constructor
+  //
+}
+
+//___________________________________________________________________
 AliHFEpidBase::AliHFEpidBase(const Char_t *name):
   TNamed(name, ""),
+  fESDpid(NULL),
   fDebugLevel(0)
 {
   //
@@ -37,6 +50,7 @@ AliHFEpidBase::AliHFEpidBase(const Char_t *name):
 //___________________________________________________________________
 AliHFEpidBase::AliHFEpidBase(const AliHFEpidBase &c):
   TNamed(),
+  fESDpid(NULL),
   fDebugLevel(0)
 {
   //
@@ -64,6 +78,7 @@ void AliHFEpidBase::Copy(TObject &ref) const {
   //
   AliHFEpidBase &target = dynamic_cast<AliHFEpidBase &>(ref);
 
+  target.fESDpid = fESDpid;
   target.fDebugLevel = fDebugLevel;
 
   TNamed::Copy(ref);
index fd7eff8..9967009 100644 (file)
@@ -24,6 +24,7 @@
  #endif
 
 class TList;
+class AliESDpid;
 class AliVParticle;
 class AliMCParticle;
 
@@ -40,6 +41,7 @@ struct AliHFEpidObject{
 
 class AliHFEpidBase : public TNamed{
   public:
+    AliHFEpidBase();
     AliHFEpidBase(const Char_t *name);
     AliHFEpidBase(const AliHFEpidBase &c);
     AliHFEpidBase &operator=(const AliHFEpidBase &c);
@@ -53,11 +55,13 @@ class AliHFEpidBase : public TNamed{
     Bool_t IsQAon() const { return TestBit(kQAon);};
     Bool_t HasMCData() const { return TestBit(kHasMCData); };
 
+    void SetESDpid(AliESDpid * const pid) { fESDpid = pid; }
     void SetDebugLevel(Int_t debugLevel) { fDebugLevel = debugLevel; }; 
     inline void SetQAOn(TList *fQAlist);
     void SetHasMCData(Bool_t hasMCdata = kTRUE) { SetBit(kHasMCData,hasMCdata); };
 
   protected:
+    AliESDpid *fESDpid;                         // ESD PID object
     void Copy(TObject &ref) const;
     virtual void AddQAhistograms(TList *){};
   private:
index 38b3a51..206da73 100644 (file)
@@ -1,17 +1,17 @@
 /**************************************************************************
-* 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.                  *
-**************************************************************************/
+ * 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 PID QA
 // Several studies done on clean samples of electrons, pions and kaons
 //    Markus Heide <mheide@uni-muenster.de>
 //    Markus Fasel <M.Fasel@gsi.de>