]> git.uio.no Git - u/mrichter/AliRoot.git/commitdiff
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 6798bc89b50a5320738cec46706bb5753a5c5e96..efeba665a3d8397f3d5dfcb35577020108048247 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 e3cf8f2b3ad5a16167d693eec6baf090d2f616d0..a61a340de2cf0b240c0317c825d3b589474ce88a 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 e6c2b0a548b7b5424aaaea5a0fd6a243e420b05e..5c746b0dfba313761512233bf3d00fc0826df23d 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 1721ab655ebfdc9cb94570148d4afa8818e89c7a..3132add1fc137f51193749000b7a1c01be60218e 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 1750e170b725d205ddd1dcc4e69b266ce9bfcbbd..4190d8da5ee7e6528f7f13b5d06d747685935aa3 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 78b505e92fd52dd1ae10328884a3189f234252ec..b59edb96a7c704be41be5e8380aba7bb9436bafe 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,66 +1258,133 @@ 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){
   //
@@ -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 207410e17b491aacd6276e8bad8e76e5024b3b43..84ef254e9d8cfda8d2bbefe36456def0c36325c3 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 79eac727395398c5e090c4de9a26736cbd6eeab2..e5573ffdcda3fc89d9cbbdbc59049846afd2df2f 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 4b2e6c63c50812c88cf7f640ed3ee634de6662ca..2b084431e666cfa475f163aa245e3a8425c339fd 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 9956fa2b169bc635f70338f7700eeff5406b194e..a2b1eed78166519c6b6407a8eb215348e224191e 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,472 +386,68 @@ 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)
@@ -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 1413ead040f45bccf5d5c13d969479ec2b4e9971..8d66402d16341398f594e537874248ea3d5a0496 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 3f6f6186b592870a46f4c9c964386cf2b12f88e4..517890a8f5960212dcebb85f886819ae9c0aeb20 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 f0c59a82a14a412ecf89fe2317ea2ece9c47794c..8efffce37dd429730f4f1441d1f5f5c449fff134 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 012cce65df8c53701f941e0f4fe68d7fc0ec5104..ef9a6e0c6a7e90a21e7033c445b99f0b0f76f66c 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 639ee7dc955a1c95d44b7b5989bc76bdd652e16f..3f673b34637df3ef6e697c41560494a5bffe8753 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 626889650835ff25e4adf1154a9fae5d926a79f5..602b9d2b0952d2a65236d31e74e8668d8d54f432 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 dc1568b32dc7f5c4d99ff409078a9075b7ce265d..198142406470be5deb7af8de7cc5451711f0aaaf 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 040ed6fc138e4af01bc52bf67e517797d82cc57c..02b38d0157e3ec311a2bc415a7052b0ff3ca9cbc 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 f7203e4b405b1a909803196f7f0e1afc822333f7..a6446b3fa3666f35fd5da6b41b6aa8d49926a566 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 aacf6f7d69424215d3b5841101e130f5ddcee6e1..13174da436ce2c389e5ba9a881b3b44160491816 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 8ab69284024e93fa7bbf2646447803a601759399..cba6f1e0272e53aed5ab7b277a893cdb0b3a9e4e 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 fac7f61e004ed0c0163961e164cd8fdaa9048a6a..d12813349acf67cab9ed3294ce84517474a12551 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 6de24e3d225fa53c67ee6fd08bd3281f568cce50..6de6d7eff231088d5b2959a61a0255eb41bdfe98 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 a6d887b82c79d3b75fe7b54ca86a1ec716864721..baa05f5c67efeda3bf497d17cd5d03c3dfe093c7 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 b430e5b9cc41ad937aebcd71ad7705abc02474bb..a9ed852b673ad9a288c06dea870c71e54beb9ed1 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 118ecc1906c5a94cf31ab89bb40744824a885e87..dc3fa5b0a8531f6b3aa4dc7840d456302ffdde62 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 0e71983d7c10ea69dcc2ce81ea257f0b894eb233..c2d6c0fb59b225f917549b789d114af3a578f5de 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 ff33df9a9b668f610ad89f4186b556e67b8a5514..abae1c39f0cf63a1f765ce4387f12d709d58a8e3 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 9e216bb84047b33adf25ce1b6ef2555f56fd96ae..41d4365eb59a4c26a1025fbf00e368bebdf83920 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);
 }
 
 //____________________________________________________________
@@ -388,6 +381,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(){
   //
@@ -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();
@@ -541,6 +550,27 @@ void AliHFEpid::InitStrategy6(){
   fDetectorPID[kTOFpid] = tofpid;
 }
 
+//____________________________________________________________
+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 80a8f23200fb289695716ee0886441b664c53997..bce1e20a0b98ed11f8fbd2ed416aba3396de5e67 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 8a86011e6d26aa946ebe1bcd188664c32d8a6b99..2da8eb52a69eda53786e784cae00a94ff87b51ef 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 fd7eff88a1dfb50ac4a7f23aed4f3326ae4ae589..99670098a4dba0d636ceebf83e5f1e6a1a7f1648 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 38b3a51cc06d08d026267de1a3ae9aa35fad46c0..206da7339c67226e5164af4fb5e78b8586df58fe 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>
 //
-#include <TClass.h>
-#include <TIterator.h>
-#include <TList.h>
+
+
 #include <TMath.h>
 #include <TObjArray.h>
-#include <TParticle.h>
 #include <TPDGCode.h>
 #include <TString.h>
+#include <TMultiLayerPerceptron.h>
+#include <TFile.h>
 
 #include "AliAODMCParticle.h"
-#include "AliAODPid.h"
+#include "AliAODEvent.h"
 #include "AliAODTrack.h"
 #include "AliESDtrack.h"
-#include "AliLog.h"
+#include "AliESDEvent.h"
 #include "AliMCEvent.h"
 #include "AliMCParticle.h"
 #include "AliPID.h"
 #include "AliESDpid.h"
-//#include "AliTRDPIDResponseLQ1D.h"
-#include "AliVEvent.h"
 #include "AliVParticle.h"
-#include "AliExternalTrackParam.h"
 
 
 #include "AliHFEcollection.h"
 #include "AliHFEpidQA.h"
+#include "AliHFEV0info.h"
 #include "AliHFEV0pid.h"
 #include "AliHFEV0pidMC.h"
-#include "AliHFEpidTRD.h"
+#include "AliHFEtrdPIDqa.h"
+
 
 ClassImp(AliHFEpidQA)
 
-//__________________________________________
-AliHFEpidQA::AliHFEpidQA():
-  fMC(NULL)
-  , fV0pid(NULL)
-  , fV0pidMC(NULL)
-  , fOutput(NULL)
-  , fT0(0)
-  , fRun(0)
-  , fESDpid(NULL)
+  //__________________________________________
+  AliHFEpidQA::AliHFEpidQA():
+    fEvent(NULL),
+    fMC(NULL), 
+    fV0pid(NULL), 
+    fV0pidMC(NULL), 
+    fTRDpidQA(NULL), 
+    fOutput(NULL), 
+    fESDpid(NULL),
+    fNNref(NULL)
 {
   //
   // Default constructor
   //
-  fESDpid = new AliESDpid;
+  for(Int_t mom = 0; mom < 11; mom++){
+    fNet[mom] = NULL;
+  }
+}
+
+//__________________________________________
+AliHFEpidQA::AliHFEpidQA(const AliHFEpidQA &ref):
+  TObject(ref),
+  fEvent(NULL), 
+  fMC(NULL),
+  fV0pid(NULL),
+  fV0pidMC(NULL), 
+  fTRDpidQA(NULL),
+  fOutput(NULL), 
+  fESDpid(NULL),
+  fNNref(NULL)
+{
+  //
+  // Copy constructor
+  //
+  for(Int_t mom = 0; mom < 11; mom++){
+    fNet[mom] = NULL;
+  }
+  ref.Copy(*this);
+}
+
+//__________________________________________
+AliHFEpidQA &AliHFEpidQA::operator=(const AliHFEpidQA &ref){
+  //
+  // Assignment operator
+  //
+  if(this != &ref)
+    ref.Copy(*this);
+  return *this;
 }
 
 //__________________________________________
@@ -78,9 +111,42 @@ AliHFEpidQA::~AliHFEpidQA(){
   //
   if(fV0pid) delete fV0pid;
   if(fV0pidMC) delete fV0pidMC;
+  if(fTRDpidQA) delete fTRDpidQA;
   if(fOutput) delete fOutput;
-  if(fESDpid) delete fESDpid;
-//  if(fTRDpidResponse) delete fTRDpidResponse; 
+  //  if(fTRDpidResponse) delete fTRDpidResponse; 
+}
+
+//__________________________________________
+void AliHFEpidQA::Copy(TObject &o) const {
+  //
+  // Copy function
+  //
+  
+  TObject::Copy(o);
+
+  AliHFEpidQA &target = dynamic_cast<AliHFEpidQA &>(o);
+  target.fMC = fMC;
+
+  if(target.fESDpid) delete target.fESDpid;
+  target.fESDpid = new AliESDpid;
+  if(target.fV0pid) delete target.fV0pid;
+  if(fV0pid)
+    target.fV0pid = dynamic_cast<AliHFEV0pid *>(fV0pid->Clone());
+  else
+    target.fV0pid = NULL;
+  if(target.fV0pidMC) delete target.fV0pidMC;
+  if(fV0pidMC) 
+    target.fV0pidMC = dynamic_cast<AliHFEV0pidMC *>(fV0pidMC->Clone());
+  else
+    target.fV0pidMC = NULL;
+  if(target.fTRDpidQA) delete target.fTRDpidQA;
+  if(fTRDpidQA)
+    target.fTRDpidQA = dynamic_cast<AliHFEtrdPIDqa *>(fTRDpidQA->Clone());
+  else
+    target.fTRDpidQA = NULL;
+  if(target.fOutput) delete target.fOutput;
+  if(fOutput)
+    target.fOutput = dynamic_cast<AliHFEcollection *>(fOutput->Clone());
 }
 
 //__________________________________________
@@ -89,131 +155,172 @@ void AliHFEpidQA::Init(){
   // Prepare task output
   //
 
+  if(fNNref){
+    for(Int_t mom = 0; mom < 11; mom++){                      // load networks
+      fNet[mom] = (TMultiLayerPerceptron*) fNNref->Get(Form("NN_Mom%d", mom));
+      if(!fNet[mom]){
+       AliError(Form("No reference network for momentum bin %d!", mom));
+      }
+    }
+  }
+  
   fV0pid = new AliHFEV0pid;
   if(HasV0pidQA()) fV0pid->InitQA();
   fV0pidMC = new AliHFEV0pidMC();
   fV0pidMC->Init();
 
+  fTRDpidQA = new AliHFEtrdPIDqa;
+  fTRDpidQA->Init();
+
   fOutput = new AliHFEcollection("pidQA", "PID QA output");
 
-  // 1st: Histos for purity studies 
-  fOutput->CreateTH2F("purityElectron", "Electron Putrity", 2, -0.5, 1.5, 20, 0.1, 10);
-  fOutput->BinLogAxis("purityElectron" ,1);
-  fOutput->CreateTH2F("purityPionK0", "K0 Pion Putrity", 2, -0.5, 1.5, 20, 0.1, 10);
-  fOutput->BinLogAxis("purityPionK0" ,1);
-  fOutput->CreateTH2F("purityPionL", "Lambda Pion Putrity", 2, -0.5, 1.5, 20, 0.1, 10);
-  fOutput->BinLogAxis("purityPionL" ,1);
-  fOutput->CreateTH2F("purityProton", "Proton Putrity", 2, -0.5, 1.5, 20, 0.1, 10);
-  fOutput->BinLogAxis("purityProton" ,1);
-
-  // Histograms for TRD Electron Likelihood
-  fOutput->CreateTH2F("hTRDelLikeElectron", "TRD Electron Likelihoods for Electrons; p (GeV/c); likelihood", 20, 0.1, 10, 100, 0., 1.);
-  fOutput->BinLogAxis("hTRDelLikeElectron", 0);
-  fOutput->CreateTH2F("hTRDelLikePionK0", "TRD Electron Likelihoods for K0 Pions; p (GeV/c); likelihood", 20, 0.1, 10, 100, 0., 1.);
-  fOutput->BinLogAxis("hTRDelLikePionK0", 0);
-  fOutput->CreateTH2F("hTRDelLikePionL", "TRD Electron Likelihoods for Lambda Pions; p (GeV/c); likelihood", 20, 0.1, 10, 100, 0., 1.);
-  fOutput->BinLogAxis("hTRDelLikePionL", 0);
-  fOutput->CreateTH2F("hTRDelLikeProton", "TRD Electron Likelihoods for Protons; p (GeV/c); likelihood", 20, 0.1, 10, 100, 0., 1.);
-  fOutput->BinLogAxis("hTRDelLikeProton", 0);
-
-  // TPC pid response
-  fOutput->CreateTH2F("hTPC_dEdx_Electron", "TPC dEdx for conversion electrons; p (GeV/c); dEdx (a.u.)", 20, 0.1, 10, 200, 0, 200);
-  fOutput->BinLogAxis("hTPC_dEdx_Electron", 0);
-  fOutput->CreateTH2F("hTPC_dEdx_PionK0", "TPC dEdx for K0 pions; p (GeV/c); dEdx (a.u.)", 20, 0.1, 10, 200, 0, 200);
-  fOutput->BinLogAxis("hTPC_dEdx_PionK0", 0);
-  fOutput->CreateTH2F("hTPC_dEdx_PionL", "TPC dEdx for Lambda pions; p (GeV/c); dEdx (a.u.)", 20, 0.1, 10, 200, 0, 200);
-  fOutput->BinLogAxis("hTPC_dEdx_PionL", 0);
-  fOutput->CreateTH2F("hTPC_dEdx_Proton", "TPC dEdx for Lambda proton; p (GeV/c); dEdx (a.u.)", 20, 0.1, 10, 200, 0, 200);
-  fOutput->BinLogAxis("hTPC_dEdx_Proton", 0);
-
- fOutput->CreateTH2F("hTPCnSigmaElectron", "TPC number of sigmas for conversion electrons; p (GeV/c); number of sigmas", 20, 0.1, 10, 100, -7, 7);
- fOutput->BinLogAxis("hTPCnSigmaElectron", 0);
- fOutput->CreateTH2F("hTPCnSigmaPionK0", "TPC number of sigmas for K0 pions; p (GeV/c); number of sigmas", 20, 0.1, 10, 100, -7, 7);
- fOutput->BinLogAxis("hTPCnSigmaPionK0", 0);
- fOutput->CreateTH2F("hTPCnSigmaPionL", "TPC number of sigmas for Lambda pions; p (GeV/c); number of sigmas", 20, 0.1, 10, 100, -7, 7);
- fOutput->BinLogAxis("hTPCnSigmaPionL", 0);
- fOutput->CreateTH2F("hTPCnSigmaProton", "TPC number of sigmas for Lambda protons; p (GeV/c); number of sigmas", 20, 0.1, 10, 100, -7, 7);
- fOutput->BinLogAxis("hTPCnSigmaProton", 0);
+  const char *name[4] = {"Electron", "PionK0", "PionL", "Proton"};
+  const char *title[4] = {"Electron", "K0 Pion", "Lambda Pion", "Proton"};
+  const char *det[4] = {"ITS", "TPC", "TRD", "TOF"};
+  for(Int_t i = 0; i < 4; i++){
+    fOutput->CreateTH2F(Form("purity%s", name[i]), Form("%s Purity", title[i]), 2, -0.5, 1.5, 20, 0.1, 10, 1);
+
+    for(Int_t idet = 0; idet < 4; idet++){
+      // create all the histograms which all the detectors have in common
+      if(idet != 2){ // no nSigma histogram for TRD
+        fOutput->CreateTH2F(Form("h%s_nSigma_%s", det[idet], name[i]), Form("%s number of sigmas for %ss; p (GeV/c); number of sigmas", det[idet], title[i]), 20, 0.1, 10, 100, -7, 7, 0);
+      }
+      fOutput->CreateTH2F(Form("h%s_PID_p_%s", det[idet], name[i]), Form("%s PID for %ss; p (GeV/c); ITS PID", det[idet], title[i]), 100, 0.1, 10, 5, -0.5, 4.5, 0);
+      fOutput->CreateTH2F(Form("h%s_El_like_%s", det[idet], name[i]), Form("%s Electron Likelihoods for %ss; p (GeV/c); likelihood", det[idet], title[i]), 25, 0.1, 10, 1000, 0., 1., 0);
+      fOutput->CreateTH2F(Form("h%s_El_like_MC_%s", det[idet], name[i]), Form("%s Electron Likelihoods for MC %ss; p (GeV/c); likelihood", det[idet], title[i]), 25, 0.1, 10, 1000, 0., 1., 0);
+    }
 
+    //
+    // ITS pid response
+    //
+    fOutput->CreateTH2F(Form("hITS_Signal_%s", name[i]), Form("ITS Signal org. for %ss", title[i]), 40, 0.1, 10, 400, 0, 1000, 0);
+    fOutput->CreateTH2Fvector1(5, Form("hITS_dEdx_%s", name[i]), Form("ITS dEdx for %ss; p (GeV/c); dEdx (a.u.)", title[i]), 40, 0.1, 10, 400, 0, 1000, 0);
+    
+    //
+    // TPC pid response
+    //
+    fOutput->CreateTH2F(Form("hTPC_dEdx_%s", name[i]), Form("TPC dEdx for %ss; p (GeV/c); dEdx (a.u.)", title[i]), 20, 0.1, 10, 200, 0, 200, 0);
+
+    //
+    // TRD pid response 
+    //
+    fOutput->CreateTH2F(Form("hTRD_trk_%s", name[i]), Form("%s PID tracklets; p (GeV/c); N TRD tracklets", title[i]), 100, 0.1, 10, 7, -0.5, 6.5, 0);
+    // number of the non 0 slices per tracklet
+    fOutput->CreateTH2F(Form("hTRD_Nslc_%s", name[i]), Form("%s PID slices > 0; p (GeV/c); N slc > 0", title[i]), 100, 0.1, 10, 9, -0.5, 8.5, 0);
+    // location of the slices > 0 - where are the emtpy slices located ?
+    fOutput->CreateTH2F(Form("hTRD_slc_%s", name[i]), Form("%s PID slices > 0 position; p (GeV/c); slice", title[i]), 100, 0.1, 10, 9, -0.5, 8.5, 0);
+    fOutput->CreateTH2F(Form("hTRD_cls_%s", name[i]), Form("TRD clusters for %s candidates; p (GeV/c); N cls", title[i]), 25, 0.1, 10, 1000, 0, 1000);
+    fOutput->CreateTH2F(Form("hTRD_dEdx_%s", name[i]), Form("TRD dEdx (trk) for %s candidates; p (GeV/c); tracklet dEdx (a.u.)", title[i]), 25, 0.1, 10, 1000, 0, 100000, 0);
+    //
+    // TOF pid response
+    //
+    fOutput->CreateTH2F(Form("hTOF_beta_%s", name[i]), Form("TOF beta for %s; p (GeV/c); #beta", title[i]),  50, 0.1, 5, 350, 0.4, 1.1, 0);
+  }//.. loop over identified particle species
+
+  // Global histograms
+  fOutput->CreateTH1F("hITS_dEdx_nSamples", "ITS - number of non 0 dEdx samples", 4, 0.5, 4.5);
   fOutput->CreateTH2F("hTPC_PID", "TPC pid all tracks; tpc pid probability; species",100, 0, 1, 5, -0.5, 4.5 );
-  fOutput->CreateTH2F("hTPC_PID_p_Electron", "TPC PID for conversion electrons; p (GeV/c); TPC PID", 100, 0.1, 10, 5, -0.5, 4.5);
-  fOutput->BinLogAxis("hTPC_PID_p_Electron", 0);
-  fOutput->CreateTH2F("hTPC_PID_p_PionK0", "TPC PID for K0 pions; p (GeV/c); TPC PID", 100, 0.1, 10, 5, -0.5, 4.5);
-  fOutput->BinLogAxis("hTPC_PID_p_PionK0", 0);
-  fOutput->CreateTH2F("hTPC_PID_p_PionL", "TPC PID for Lambda pions; p (GeV/c); TPC PID", 100, 0.1, 10, 5, -0.5, 4.5);
-  fOutput->BinLogAxis("hTPC_PID_p_PionL", 0);
-  fOutput->CreateTH2F("hTPC_PID_p_Proton", "TPC PID for Lambda protons; p (GeV/c); TPC PID", 100, 0.1, 10, 5, -0.5, 4.5);
-  fOutput->BinLogAxis("hTPC_PID_p_Proton", 0);
-
-
-  // TRD pid response
-  fOutput->CreateTH2F("hTRD_Electron_trk", "all Electron candidate tracklets; p (GeV/c); N TRD tracklets", 100, 0.1, 10, 7, -0.5, 6.5);
-  fOutput->BinLogAxis("hTRD_Electron_trk", 0);
-  fOutput->CreateTH1F("hTRD_Electron_Y_like", "YES - V0 electron eff. for fixed likelihood cut; p (GeV/c); counts", 25, 0.1, 10);
-  fOutput->BinLogAxis("hTRD_Electron_Y_like", 0);
-  fOutput->CreateTH1F("hTRD_Electron_N_like", "NO - V0 electron eff. for fixed likelihood cut; p (GeV/c); counts", 25, 0.1, 10);
-  fOutput->BinLogAxis("hTRD_Electron_N_like", 0);
-  fOutput->CreateTH2F("hTRD_El_like_Electron", "V0 electron likelihoods for electrons; p (GeV/c); likelihood", 25, 0.1, 10, 1000, 0., 1.);
-  fOutput->BinLogAxis("hTRD_El_like_Electron", 0);
-  fOutput->CreateTH2F("hTRD_El_like_Pion", "V0 electron likelihoods for poins; p (GeV/c); likelihood", 25, 0.1, 10, 1000, 0., 1.);
-  fOutput->BinLogAxis("hTRD_El_like_Pion", 0);
-  fOutput->CreateTH2F("hTRD_El_like_Proton", "V0 electron likelihoods for protons; p (GeV/c); likelihood", 25, 0.1, 10, 1000, 0., 1.);
-  fOutput->BinLogAxis("hTRD_El_like_Proton", 0);
-
-
-  // TOF pid response
-  
   fOutput->CreateTH2F("hTOF_PID", "TOF pid all tracks; tof pid probability; species",100, 0, 1,5,  -0.5, 4.5 );
-
-  fOutput->CreateTH2F("hTOF_PID_p_Electron", "TOF PID for gamma converisons; p_T (GeV/c); counts", 100, 0.1, 10, 5, -0.5, 4.5);
-  fOutput->BinLogAxis("hTOF_PID_p_Electron", 0);
-  fOutput->CreateTH2F("hTOF_PID_p_PionK0", "TOF PID for K0 pions; p_T (GeV/c); counts", 100, 0.1, 10, 5, -0.5, 4.5);
-  fOutput->BinLogAxis("hTOF_PID_p_PionK0", 0);
-  fOutput->CreateTH2F("hTOF_PID_p_PionL", "TOF PID for Lambda pions; p_T (GeV/c); counts", 100, 0.1, 10, 5, -0.5, 4.5);
-  fOutput->BinLogAxis("hTOF_PID_p_PionL", 0);
-  fOutput->CreateTH2F("hTOF_PID_p_Proton", "TOF PID for Lambda protons; p_T (GeV/c); counts", 100, 0.1, 10, 5, -0.5, 4.5);
-  fOutput->BinLogAxis("hTOF_PID_p_Proton", 0);
-
-  fOutput->CreateTH2F("hTOF_beta_Electron", "TOF beta for gamma conversions; #beta; p (GeV/c)", 120, 0, 1.2, 100, 0.1, 10);
-  fOutput->BinLogAxis("hTOF_beta_Electron", 1);
-  fOutput->CreateTH2F("hTOF_beta_PionK0", "TOF beta for K0 pions; #beta; p (GeV/c)", 120, 0, 1.2, 100, 0.1, 10);
-  fOutput->BinLogAxis("hTOF_beta_PionK0", 1);
-  fOutput->CreateTH2F("hTOF_beta_PionL", "TOF beta Lambda pions; #beta; p (GeV/c)", 120, 0, 1.2, 100, 0.1, 10);
-  fOutput->BinLogAxis("hTOF_beta_PionL", 1);
-  fOutput->CreateTH2F("hTOF_beta_Proton", "TOF beta for Lambda protons; #beta; p (GeV/c)", 120, 0, 1.2, 100, 0.1, 10);
-  fOutput->BinLogAxis("hTOF_beta_Proton", 1);
+  fOutput->CreateTH2F("hTOF_beta_all", "TOF beta for all nice single tracks; p (GeV/c); #beta", 100, 0.1, 10, 480, 0, 1.2, 0);
+  fOutput->CreateTH2F("hTOF_qa_TmT0mT", "TOF (t - t0 - t[pion]) qa verus run",  10000, 114000, 124000, 200, -200, 200);
+  fOutput->CreateTH2F("hTOF_qa_length", "TOF track length verus run",  10000, 114000, 112400, 200, 0, 1000);
+  
+  //
+  // debug histograms
+  //
+  fOutput->CreateTH2F("hITS_kFlags", "ITS flags; flag; V0 candidates", 5, 0.5, 5.5, 5, -0.5, 4.5);  
+  fOutput->CreateTH2F("hTPC_kFlags", "TPC flags; flag; V0 candidates", 5, 0.5, 5.5, 5, -0.5, 4.5);
+  fOutput->CreateTH2F("hTRD_kFlags", "TRD flags; flag; V0 candidates", 5, 0.5, 5.5, 5, -0.5, 4.5);
+  fOutput->CreateTH2F("hTOF_kFlags", "TOF flags; flag; V0 candidates", 5, 0.5, 5.5, 5, -0.5, 4.5);
   
 
+  //
+  // event based histograms
+  //
+  Int_t n_T0[2] = {10000, 100};
+  Double_t min_T0[2] = {114500, -1000};
+  Double_t max_T0[2] = {124500, 1000};
+  fOutput->CreateTHnSparse("hEvent_T0", "T0 as a function of run number; run number; T0 (ns)", 2, n_T0, min_T0, max_T0);
+
+  //
+  // test the tender V0 supply
+  //
+  fOutput->CreateTH2F("h_tender_check_01", "tender -vs- HFEpidQA; HFEpidQA V0 candiadates; tender V0 candidates", 4, -1.5, 2.5, 4, -1.5, 2.5);
+  fOutput->CreateTH2Fvector1(3, "h_tender_check_02", "tender -vs- HFEpidQA per type; AliHFEpidQA V0 ; tender V0", 4, -1.5, 2.5, 4, -1.5, 2.5);
 
-  // Prepare TRD PID
-/*  if(HasRecalculateTRDpid()){
-    fTRDpidResponse = new AliTRDPIDResponseLQ1D;
-    fTRDpidResponse->LoadReferences();
-  }*/
-}
 
-//__________________________________________
-void AliHFEpidQA::Process(AliVEvent *inputEvent){
   //
-  // Run PID QA
+  // THnSpasre objects
   //
 
-  if(fRun >= 104065 && fRun <= 104892){
-    CorrectT0();
+  // Create Illumination Plot
+  // bins: species, pt, eta, phi, TPC status, TRD status
+  {
+    Int_t nbins[6] = {4, 40, 16, 72, 2, 2};
+    Double_t min[6] = { 0, 0.1, -0.8, 0., 0., 0.};
+    Double_t max[6] = { 4., 20., 0.8, 2*TMath::Pi(), 2., 2.};
+    fOutput->CreateTHnSparse("hIllumination", "Illumination", 6, nbins, min, max);
+    fOutput->BinLogAxis("hIllumination", 1);
+  }
+
+  // TPC THnSparse
+  // bins: species, pt, n TPC clusters., TPC electron likelihood, TPC n sigmas, TPC signal
+  {
+    Int_t nbins[6] = { 5, 40, 20, 100, 100, 200};
+    Double_t min[6] = { -0.5, 0.1, 0., 0., -5., 0.};
+    Double_t max[6] = { 4.5, 20., 200, 1., 5., 120.};
+    TString htitle = "TPC info sparse; VO identified species; p (GeV/c); n TPC clusters; TPC N sigma; TPC signal";
+    fOutput->CreateTHnSparse("hTPCclusters",htitle,6, nbins, min, max);
+    fOutput->BinLogAxis("hTPCclusters", 1);
+  }
+  // TRD THnSparse - entries per tracklet
+  // species, p, tracklet position, number of PID tracklets, number of slices (non 0), number of clusters, electron likelihood, 
+  {
+    Int_t nbins[7] = {5, 20, 6, 7, 9, 45, 100};
+    Double_t min[7] = {-0.5, 0.5, -0.5, -0.5, -0.5, -0.5, 0.};
+    Double_t max[7] = {4.5, 10, 5.5, 6.5, 8.5, 179.5, 1.};
+    TString htitle = "TRD tracklets; VO identified species; p (GeV/c); tracklet position; No. PID tacklets; No. slices; No. clusters; El. likelihood";
+    fOutput->CreateTHnSparse("hTRDtracklets",htitle,7, nbins, min, max);
+    fOutput->BinLogAxis("hTRDtracklets", 1);
   }
+  
+
+}
+//__________________________________________
+void AliHFEpidQA::Process(){
+  //
+  // Run PID QA
+  //
 
   if(!fV0pid){
     AliError("V0pid not available! Forgotten to initialize?");
     return;
   }
+  if(!fESDpid){
+    AliError("fESDpid not initialized, I am leaving this!");
+    return;
+  }
+
+  // to be udpated to AOD save mdoe
+  if(!fEvent){
+    AliError("AliVEvent not available, returning");
+  }
 
   if(fMC) fV0pidMC->SetMCEvent(fMC);
 
-  fV0pid->Process(inputEvent);
-  TObjArray *electrons = fV0pid->GetListOfElectrons();
-  TObjArray *pionsK0 = fV0pid->GetListOfPionsK0();
-  TObjArray *pionsL = fV0pid->GetListOfPionsL();
-  TObjArray *protons = fV0pid->GetListOfProtons();
+  fV0pid->Process(fEvent);
+  TObjArray *hfeelectrons = fV0pid->GetListOfElectrons();
+  TObjArray *hfepionsK0 = fV0pid->GetListOfPionsK0();
+  TObjArray *hfepionsL = fV0pid->GetListOfPionsL();
+  TObjArray *hfeprotons = fV0pid->GetListOfProtons();
+
+  // Get Track list for normal purpose
+  TObjArray *electrons = MakeTrackList(hfeelectrons);
+  TObjArray *pionsK0 = MakeTrackList(hfepionsK0);
+  TObjArray *pionsL = MakeTrackList(hfepionsL);
+  TObjArray *protons = MakeTrackList(hfeprotons);
+  TObjArray *cleanElectrons = MakeCleanListElectrons(hfeelectrons);
 
   if(fMC){
     fV0pidMC->Process(electrons, AliHFEV0pid::kRecoElectron);
@@ -234,20 +341,112 @@ void AliHFEpidQA::Process(AliVEvent *inputEvent){
     MakePurity(pionsL,  AliHFEV0pid::kRecoPionL);
     MakePurity(protons,  AliHFEV0pid::kRecoProton);
   }
+
+  // some event wise checks
+  CheckEvent();
+
+  // Make Illumination Plot
+  FillIllumination(electrons, AliHFEV0pid::kRecoElectron);
+  FillIllumination(pionsK0, AliHFEV0pid::kRecoPionK0);
+  FillIllumination(pionsL, AliHFEV0pid::kRecoPionL);
+  FillIllumination(protons, AliHFEV0pid::kRecoProton);
+
   // Now we can do studies on the PID itself
-  // TRD PID: Fill electron Likelihoods for the particle species
-  FillTRDelectronLikelihoods(electrons,  AliHFEV0pid::kRecoElectron);
-  FillTRDelectronLikelihoods(pionsK0,  AliHFEV0pid::kRecoPionK0);
-  FillTRDelectronLikelihoods(pionsL,  AliHFEV0pid::kRecoPionL);
-  FillTRDelectronLikelihoods(protons,  AliHFEV0pid::kRecoProton);
+  // For TRD use the TRD PID QA object
+  fTRDpidQA->ProcessTracks(cleanElectrons, AliPID::kElectron);
+  fTRDpidQA->ProcessTracks(pionsK0, AliPID::kPion);
+  fTRDpidQA->ProcessTracks(pionsL, AliPID::kPion);
+  fTRDpidQA->ProcessTracks(protons, AliPID::kProton);
+
+  FillElectronLikelihoods(electrons,  AliHFEV0pid::kRecoElectron); 
+  FillElectronLikelihoods(pionsK0,  AliHFEV0pid::kRecoPionK0); 
+  FillElectronLikelihoods(pionsL,  AliHFEV0pid::kRecoPionL); 
+  FillElectronLikelihoods(protons,  AliHFEV0pid::kRecoProton); 
   
   FillPIDresponse(electrons, AliHFEV0pid::kRecoElectron);
   FillPIDresponse(pionsK0, AliHFEV0pid::kRecoPionK0);
   FillPIDresponse(pionsL, AliHFEV0pid::kRecoPionL);
   FillPIDresponse(protons, AliHFEV0pid::kRecoProton);
 
+  // check the tender V0s
+  CheckTenderV0pid(electrons, AliHFEV0pid::kRecoElectron);
+  CheckTenderV0pid(pionsK0, AliHFEV0pid::kRecoPionK0);
+  CheckTenderV0pid(pionsL, AliHFEV0pid::kRecoPionL);
+  CheckTenderV0pid(protons, AliHFEV0pid::kRecoProton);
+
   // Analysis done, flush the containers
   fV0pid->Flush();
+
+  delete electrons;
+  delete pionsL;
+  delete pionsK0;
+  delete protons;
+  delete cleanElectrons;
+}
+
+//__________________________________________
+void AliHFEpidQA::FillIllumination(TObjArray * const tracks, Int_t species){
+  //
+  // Fill Illumination Plot
+  //
+  THnSparseF *hIllumination = dynamic_cast<THnSparseF *>(fOutput->Get("hIllumination"));
+  if(!hIllumination) return;
+
+  Double_t quantities[6]; memset(quantities, 0, sizeof(Double_t) *6);
+  TIter trackIter(tracks);
+
+  quantities[0] = species;
+  TObject *o = NULL; AliESDtrack *esdtrack = NULL;
+  while((o = trackIter())){
+    if(!TString(o->IsA()->GetName()).CompareTo("AliESDtrack")){
+      // work on local copy in order to not spoil others
+      esdtrack = new AliESDtrack(*(dynamic_cast<AliESDtrack *>(o)));
+    } else if(!TString(o->IsA()->GetName()).CompareTo("AliAODrack")){
+      // Bad hack: Fill ESD track with AOD information
+      esdtrack = new AliESDtrack(dynamic_cast<AliAODTrack *>(o));
+    } else {
+      // Non usable
+      continue;
+    }
+
+    // Propagate to the entrance of the TRD
+    esdtrack->PropagateTo(300, fEvent->GetMagneticField());
+    quantities[1] = esdtrack->Pt();
+    quantities[2] = esdtrack->Eta();
+    quantities[3] = esdtrack->Phi();
+    quantities[4] = (esdtrack->GetStatus() & AliESDtrack::kTPCrefit) ? 1 : 0;
+    quantities[5] = (esdtrack->GetStatus() & AliESDtrack::kTRDout) ? 1. : 0.;
+    hIllumination->Fill(quantities);
+
+    delete esdtrack;
+  }
+}
+//__________________________________________
+void AliHFEpidQA::FillTPCinfo(AliESDtrack *const esdtrack, Int_t species){
+  //
+  // Fill TPC Cluster Plots
+  //
+  THnSparseF *hTPCclusters = dynamic_cast<THnSparseF *>(fOutput->Get("hTPCclusters"));
+  if(!hTPCclusters) return;
+
+  Double_t quantities[6]; memset(quantities, 0, sizeof(Double_t) *6);
+  
+  Double_t pidProbs[5];
+  const Int_t typePID[5] = {0, 2, 2, 3, 4};
+
+
+  quantities[0] = species;
+
+  
+  esdtrack->GetTPCpid(pidProbs);   
+    
+  quantities[1] = esdtrack->P();
+  quantities[2] = esdtrack->GetTPCNcls();
+  quantities[3] = pidProbs[0];
+  quantities[4] = fESDpid->NumberOfSigmasTPC(esdtrack,(AliPID::EParticleType)typePID[species]);
+  quantities[5] = esdtrack->GetTPCsignal();
+  hTPCclusters->Fill(quantities);
+
 }
 
 //__________________________________________
@@ -257,33 +456,31 @@ void AliHFEpidQA::MakePurity(TObjArray *tracks, Int_t species){
   //
   if(!fMC) return;
   AliDebug(3, Form("Doing Purity checks for species %d", species));
-  Int_t pdg = 0;
+  Int_t pdg = GetPDG(species);
   Char_t hname[256];
+
   switch(species){
-    case  AliHFEV0pid::kRecoElectron:
-      pdg = TMath::Abs(kElectron);
-      sprintf(hname, "purityElectron");
-      break;
-    case  AliHFEV0pid::kRecoPionK0:
-      pdg = TMath::Abs(kPiPlus);
-      sprintf(hname, "purityPionK0");
-      break;
-    case  AliHFEV0pid::kRecoPionL:
-      pdg = TMath::Abs(kPiPlus);
-      sprintf(hname, "purityPionL");
-      break;
-    case  AliHFEV0pid::kRecoProton:
-      pdg = TMath::Abs(kProton);
-      sprintf(hname, "purityProton");
-      break;
-    default:  // non investigated species
-      AliDebug(3, "Species not investigated");
-      return;
-  }
+  case  AliHFEV0pid::kRecoElectron:
+    sprintf(hname, "purityElectron");
+    break;
+  case  AliHFEV0pid::kRecoPionK0:
+    sprintf(hname, "purityPionK0");
+    break;
+  case  AliHFEV0pid::kRecoPionL:
+    sprintf(hname, "purityPionL");
+    break;
+  case  AliHFEV0pid::kRecoProton:
+    sprintf(hname, "purityProton");
+    break;
+  default:  // non investigated species
+    AliDebug(3, "Species not investigated");
+    return;
+  }  
+
   AliDebug(3, Form("Number of tracks: %d", tracks->GetEntries()));
-  TIterator *trackIter = tracks->MakeIterator();
+  TIter trackIter(tracks);
   AliVParticle *recTrack = NULL, *mcTrack = NULL;
-  while((recTrack = dynamic_cast<AliVParticle *>(trackIter->Next()))){
+  while((recTrack = dynamic_cast<AliVParticle *>(trackIter()))){
     Int_t label = recTrack->GetLabel();
     AliDebug(4, Form("MC Label %d", label));
     mcTrack =fMC->GetTrack(TMath::Abs(label));
@@ -304,77 +501,108 @@ void AliHFEpidQA::MakePurity(TObjArray *tracks, Int_t species){
       trackPdg = TMath::Abs(aodmcp->GetPdgCode());
     }
     if(trackPdg == pdg)    // Correct identification
-      fOutput->Fill(hname, 0., recTrack->Pt());
+      {
+       fOutput->Fill(hname, 0., recTrack->Pt());
+      }
     else  // Wrong identification
       fOutput->Fill(hname, 1., recTrack->Pt());
   }
-  delete trackIter;
 }
 
 //__________________________________________
-void AliHFEpidQA::FillTRDelectronLikelihoods(TObjArray * const particles, Int_t species){
+void AliHFEpidQA::FillElectronLikelihoods(TObjArray * const particles, Int_t species){
   //
-  // Fill electron Likelihoods for the TRD
+  // Fill electron Likelihoods for the ITS, TPC and TOF
   // Required for the calculation of the electron efficiency, 
   // pion and proton efficiency and the thresholds
   //
-  Char_t hname[256] = "hTRDelLike";
+  Long_t status = 0;
+  Char_t *detname[4] = {"ITS", "TPC", "TRD", "TOF"};
+  Char_t specname[256];
+
   switch(species){
-    case  AliHFEV0pid::kRecoElectron:
-      sprintf(hname, "%sElectron", hname);
-      break;
-    case  AliHFEV0pid::kRecoPionK0:
-      sprintf(hname, "%sPionK0", hname);
-      break;
-    case  AliHFEV0pid::kRecoPionL:
-      sprintf(hname, "%sPionL", hname);
-      break;
-    case  AliHFEV0pid::kRecoProton:
-      sprintf(hname, "%sProton", hname);
-      break;
-    default:
-      AliDebug(2, Form("Species %d not investigated", species));
-      return;
+  case  AliHFEV0pid::kRecoElectron:
+    sprintf(specname, "Electron");
+    break;
+  case  AliHFEV0pid::kRecoPionK0:
+    sprintf(specname, "PionK0");
+    break;
+  case  AliHFEV0pid::kRecoPionL:
+    sprintf(specname, "PionL");
+    break;
+  case  AliHFEV0pid::kRecoProton:
+    sprintf(specname, "Proton");
+    break;
+  default:
+    AliDebug(2, Form("Species %d not investigated", species));
+    return;
   };
   AliVParticle *recTrack = NULL;
-  TIterator *trackIter = particles->MakeIterator();
-  Double_t quantities[2] = {0., 0.};
-  Double_t trdPidProbs[5];
-  while((recTrack = dynamic_cast<AliVParticle *>(trackIter->Next()))){
+  //  mcTrack =fMC->GetTrack(TMath::Abs(label));
+  //   if(!mcTrack){
+  //     AliDebug(4, "MC track not available");
+  //     continue; // we don't know
+  //   }
+
+  TIter trackIter(particles);
+
+  Double_t quantities[2];
+  Double_t pidProbs[5];
+
+  while((recTrack = dynamic_cast<AliVParticle *>(trackIter()))){
     if(!TString(recTrack->IsA()->GetName()).CompareTo("AliESDtrack")){
       // case ESD
       AliESDtrack *esdTrack = dynamic_cast<AliESDtrack *>(recTrack);
-      if(!esdTrack->GetTRDntracklets()) continue; // require at least 1 tracklet
-      // take momentum at the innermost TRD layer
-      Double_t p = 0.;
-      for(Int_t ily = 0; ily < 6; ily++){
-        if((p = esdTrack->GetTRDmomentum(ily)) > 1e-6) break;
-      }
-      quantities[0] = p;
-      if(HasRecalculateTRDpid()) 
-        RecalculateTRDpid(esdTrack, trdPidProbs);
-      else
-        esdTrack->GetTRDpid(trdPidProbs);
-      quantities[1] = trdPidProbs[ AliPID::kElectron];
-    }
-    else{
-      AliAODTrack *aodTrack = dynamic_cast<AliAODTrack *>(recTrack);
-      if(!aodTrack->GetDetPid()) continue;
-      Float_t *trdMom = aodTrack->GetDetPid()->GetTRDmomentum(), p = 0.;
-      for(Int_t ily = 0; ily < 6; ily++){
-        if((p = trdMom[ily]) > 1e-6) break;
+      status = esdTrack->GetStatus();
+
+      //TPC momentum and likelihoods
+      Double_t pTPC = 0.;
+      pTPC = esdTrack->GetInnerParam() ? esdTrack->GetInnerParam()->P() : esdTrack->P();
+      Bool_t mcFound = kFALSE;
+      if(fMC){
+       Int_t label = esdTrack->GetLabel();
+       AliMCParticle *mcTrack = dynamic_cast<AliMCParticle *>(fMC->GetTrack(label));
+       Int_t pdg = GetPDG(species);
+       Int_t trackPdg = 0; 
+       if(mcTrack){
+         trackPdg = TMath::Abs(mcTrack->Particle()->GetPdgCode());
+       }
+       if(pdg == trackPdg) mcFound = kTRUE;    
       }
-      quantities[0] = p;
-      // case AOD (for the moment lacks)
-      if(HasRecalculateTRDpid()){
-        RecalculateTRDpid(aodTrack, trdPidProbs); 
-        quantities[1] = trdPidProbs[AliPID::kElectron];
+      quantities[0] = pTPC;
+      Bool_t detFlagSet = kFALSE;
+      for(Int_t idet = 0; idet < 4; idet++){
+        Char_t histname[256], histnameMC[256];
+        sprintf(histname, "h%s_El_like_%s", detname[idet], specname);
+        sprintf(histnameMC, "h%s_El_like_MC_%s", detname[idet], specname);
+        switch(idet){
+          case kITS:  esdTrack->GetITSpid(pidProbs);
+                      detFlagSet = status & AliESDtrack::kITSpid;
+                      break;
+          case kTPC:  esdTrack->GetTPCpid(pidProbs);
+                      detFlagSet = status & AliESDtrack::kTPCpid;
+                      break;
+          case kTRD:  esdTrack->GetTRDpid(pidProbs);
+                      detFlagSet = status & AliESDtrack::kTRDpid;
+                      break;
+          case kTOF:  esdTrack->GetTOFpid(pidProbs);  
+                      detFlagSet = status & AliESDtrack::kTOFpid;
+                      break;
+        };
+        quantities[1] = pidProbs[AliPID::kElectron];
+       // in case of TRD require 6 PID tracklets
+       if(kTRD == idet && esdTrack->GetTRDntrackletsPID() != 6) continue;
+        if(detFlagSet){
+         fOutput->Fill(histname, quantities[0], quantities[1]);
+         if(mcFound)
+           fOutput->Fill(histnameMC, quantities[0], quantities[1]);
+        }
       }
-      else
-        continue;
-    }
-    fOutput->Fill(hname, quantities[0], quantities[1]);
-  }
+    }//.. ESD
+    else{
+      //AOD
+    }//.. aod 
+  }//.. while tracks 
 }
 //__________________________________________
 void AliHFEpidQA::FillPIDresponse(TObjArray * const particles, Int_t species){
@@ -382,102 +610,261 @@ void AliHFEpidQA::FillPIDresponse(TObjArray * const particles, Int_t species){
   // Fill the PID response of different detectors to V0 daughter particles
   //
   Char_t hname[256] = "";
+  Char_t hname2[256] = "";
+  Char_t hname3[256] = "";
+   
   const Char_t *typeName[5] = {"Electron", "PionK0", "PionL", "Kaon", "Proton"};
   const Int_t typePID[5] = {0, 2, 2, 3, 4};
-  
-  AliHFEpidTRD *pidTRD = new AliHFEpidTRD("TRDpid");
-  
+
+  // PID THnSparse
+  // axes:
+  // 0) species,  1) momentum, 2) DCA xy, 3) DCA z 
+  // 4) ITS signal 
+  // 5) TPC Ncls 6) TPC signal 7) TPC nSigma, 
+  // 8) TRD Ntrk, 9) TRD Ncls, 10) TRD dEdx, 
+
+  Double_t data[12];
+  memset(data, -99, sizeof(Double_t) *12);
+
+  Int_t run = fEvent->GetRunNumber();
+    
   AliVParticle *recTrack = NULL;
-  TIterator *trackIter = particles->MakeIterator(); 
-  while((recTrack = dynamic_cast<AliVParticle *>(trackIter->Next()))){
+  TIter trackIter(particles); 
+  while((recTrack = dynamic_cast<AliVParticle *>(trackIter()))){
+    memset(data, -99, sizeof(Double_t) *10);
     // ESD
     if(!TString(recTrack->IsA()->GetName()).CompareTo("AliESDtrack")){
       // case ESD
       AliESDtrack *esdTrack = dynamic_cast<AliESDtrack *>(recTrack);
-      const AliExternalTrackParam *tpcIn = esdTrack->GetTPCInnerParam();
-      if(!tpcIn) continue;
+      if(!esdTrack) continue;
       
-      // track kinematics
-      Double_t p = tpcIn->P();
-      //Double_t pt = tpcIn->Pt();
-
-      // TPC dEdx
-      Double_t dEdx = esdTrack->GetTPCsignal();
-      sprintf(hname, "hTPC_dEdx_%s", typeName[species]);
-      fOutput->Fill(hname, p, dEdx);
-
-      //TPC number of sigmas
-      Double_t nsigma = fESDpid->NumberOfSigmasTPC(esdTrack,(AliPID::EParticleType)typePID[species]);
-      sprintf(hname, "hTPCnSigma%s",  typeName[species]);
-      fOutput->Fill(hname, p, nsigma);
-
-      // TPC PID response
-      sprintf(hname, "hTPC_PID_p_%s", typeName[species]);
-      Double_t tpcPID[5] = {-1, -1, -1, -1, -1};
-      esdTrack->GetTPCpid(tpcPID);
-      Int_t ix = 0;
-      Double_t tmp = 0.;
-      for(Int_t k=0; k<5; ++k){
-       if(tpcPID[k] > tmp){
-         ix = k;
-         tmp = tpcPID[k];
+      // for the PID THnSparse
+      data[0] = species;
+      data[1] = esdTrack->P();
+      Float_t impactR = -1.;
+      Float_t impactZ = -1.;
+      esdTrack->GetImpactParameters(impactR, impactZ);
+      data[2] = impactR;
+      data[3] = impactZ;
+      data[11] = 0; // initialize the TOF pid cut on elecgrons to false
+      // use ONLY tracks with PID flag TRUE
+      ULong_t status = 0;
+      status = esdTrack->GetStatus();
+
+      //
+      // DEBUG 
+      //
+      
+      fOutput->Fill("hITS_kFlags", 5., species);
+      if(status & AliESDtrack::kITSin)    fOutput->Fill("hITS_kFlags", 1., species);
+      if(status & AliESDtrack::kITSout)   fOutput->Fill("hITS_kFlags", 2., species);
+      if(status & AliESDtrack::kITSrefit) fOutput->Fill("hITS_kFlags", 3., species);
+      if(status & AliESDtrack::kITSpid)   fOutput->Fill("hITS_kFlags", 4., species);
+      
+      fOutput->Fill("hTPC_kFlags", 5., species);
+      if(status & AliESDtrack::kTPCin)    fOutput->Fill("hTPC_kFlags", 1., species);
+      if(status & AliESDtrack::kTPCout)   fOutput->Fill("hTPC_kFlags", 2., species);
+      if(status & AliESDtrack::kTPCrefit) fOutput->Fill("hTPC_kFlags", 3., species);
+      if(status & AliESDtrack::kTPCpid)   fOutput->Fill("hTPC_kFlags", 4., species);
+
+      fOutput->Fill("hTRD_kFlags", 5., species);
+      if(status & AliESDtrack::kTRDin)    fOutput->Fill("hTRD_kFlags", 1., species);
+      if(status & AliESDtrack::kTRDout)   fOutput->Fill("hTRD_kFlags", 2., species);
+      if(status & AliESDtrack::kTRDrefit) fOutput->Fill("hTRD_kFlags", 3., species);
+      if(status & AliESDtrack::kTRDpid)   fOutput->Fill("hTRD_kFlags", 4., species);
+
+      fOutput->Fill("hTOF_kFlags", 5., species);
+      if(status & AliESDtrack::kTOFin)    fOutput->Fill("hTOF_kFlags", 1., species);
+      if(status & AliESDtrack::kTOFout)   fOutput->Fill("hTOF_kFlags", 2., species);
+      if(status & AliESDtrack::kTOFrefit) fOutput->Fill("hTOF_kFlags", 3., species);
+      if(status & AliESDtrack::kTOFpid)   fOutput->Fill("hTOF_kFlags", 4., species);
+
+      
+      //
+      // ITS - 
+      //
+      if(status & AliESDtrack::kITSpid){
+       Double_t p = esdTrack->P();
+
+       // ITS signal
+       //Double_t itsSignal = esdTrack->GetITSsignal();
+       
+       // ITS dEdx
+       Double_t dEdxSamples[4];
+       esdTrack->GetITSdEdxSamples(dEdxSamples);
+       Int_t nSamples = 0;
+       Double_t dEdxSum = 0.;
+       sprintf(hname, "hITS_dEdx_%s", typeName[species]);
+       for(Int_t i=0; i<4; ++i){
+         if(dEdxSamples[i] > 0){
+           nSamples++;
+           fOutput->Fill(hname, i+1, p, dEdxSamples[i]);
+           dEdxSum += dEdxSamples[i];
+         }
        }
-       fOutput->Fill("hTPC_PID", tpcPID[k], k);
-      }
-      if(tpcPID[ix] > 0){
+       if(4 == nSamples)fOutput->Fill(hname, 0, p, dEdxSum);
+       fOutput->Fill("hITS_dEdx_nSamples", nSamples);
+
+       Double_t signal = esdTrack->GetITSsignal();
+       sprintf(hname, "hITS_Signal_%s", typeName[species]);
+       fOutput->Fill(hname, p, signal);
+       data[4] = signal;
+       
+       // ITS number of signas
+       Double_t nsigma = fESDpid->NumberOfSigmasITS(esdTrack,(AliPID::EParticleType)typePID[species]);
+       sprintf(hname, "hITS_nSigma_%s",  typeName[species]);
+       fOutput->Fill(hname, p, nsigma);
+       
+       // ITS PID response
+       Double_t itsPID[5] = {-1, -1, -1, -1, -1};
+       esdTrack->GetITSpid(itsPID);
+       Int_t ix = GetMaxPID(itsPID);
+       sprintf(hname, "hITS_PID_p_%s", typeName[species]);
        fOutput->Fill(hname, p, ix);
-      }
+      }//.. kITSpid
+      
+      //
+      // TPC
+      //
+      if(status & AliESDtrack::kTPCpid){
+       // Make TPC clusters Plot
+       data[5] = esdTrack->GetTPCNcls();
+       FillTPCinfo(esdTrack, species);
 
-      // TOF PID response
-      sprintf(hname, "hTOF_PID_p_%s", typeName[species]);
-      Double_t tofPID[5] = {-1., -1., -1., -1., -1};
-      esdTrack->GetTOFpid(tofPID);
-      tmp = 0.;
-      for(Int_t k=0; k<5; ++k){
-       if(tofPID[k] > tmp){
-         ix = k;
-         tmp = tofPID[k];
-       }
-       if(tofPID[k] > 0)
-         fOutput->Fill("hTOF_PID", tofPID[k], k);
-      }
-      if(tofPID[ix] > 0){
+       Double_t p = esdTrack->GetInnerParam() ? esdTrack->GetInnerParam()->P() : esdTrack->P();
+       // TPC dEdx
+       Double_t dEdx = esdTrack->GetTPCsignal();
+       sprintf(hname, "hTPC_dEdx_%s", typeName[species]);
+       fOutput->Fill(hname, p, dEdx);
+       data[6] = dEdx;
+       
+       //TPC number of sigmas
+       Double_t nsigma = fESDpid->NumberOfSigmasTPC(esdTrack,(AliPID::EParticleType)typePID[species]);
+       sprintf(hname, "hTPC_nSigma_%s",  typeName[species]);
+       fOutput->Fill(hname, p, nsigma);
+       data[7] = nsigma;
+
+       // TPC PID response
+       sprintf(hname, "hTPC_PID_p_%s", typeName[species]);
+       Double_t tpcPID[5] = {-1, -1, -1, -1, -1};
+       esdTrack->GetTPCpid(tpcPID);
+       Int_t ix = GetMaxPID(tpcPID);
+       fOutput->Fill(hname, p, ix);    
+      }//.. kTPCpid
+      
+      //
+      // TRD
+      //
+      
+      if(status & AliESDtrack::kTRDpid){
+       Double_t p = esdTrack->GetOuterParam() ? esdTrack->GetOuterParam()->P() : esdTrack->P();
+       
+       // TRD number of tracklets
+       Int_t ntrk = esdTrack->GetTRDntrackletsPID();
+       sprintf(hname, "hTRD_trk_%s", typeName[species]);
+       fOutput->Fill(hname, p, ntrk);
+       data[8] = ntrk;
+
+       // TRD PID response
+       sprintf(hname, "hTRD_PID_p_%s", typeName[species]);
+       Double_t trdPID[5] = {-1., -1., -1., -1., -1};
+       esdTrack->GetTRDpid(trdPID);
+       Int_t ix = GetMaxPID(trdPID);
        fOutput->Fill(hname, p, ix);
-      }
+       // TRD n clusters
+       Int_t ncls = esdTrack->GetTRDncls();
+       sprintf(hname, "hTRD_cls_%s", typeName[species]);
+       fOutput->Fill(hname, p, ncls);
+       data[9] = ncls;
+
+       // TRD - per tracklet - dEdx per, likelihood
+       sprintf(hname, "hTRD_Nslc_%s", typeName[species]);
+       sprintf(hname2, "hTRD_slc_%s", typeName[species]);
+       sprintf(hname3, "hTRD_dEdx_%s", typeName[species]);
+       Int_t nSlices = esdTrack->GetNumberOfTRDslices();
+       Double_t sumTot = 0.;
+       Int_t not0Tot = 0;
+       for(Int_t l=0; l< 6; ++l){
+         Double_t trkData[7] = {-1.,-1, -1, -1, -1, -1, -1};
+         trkData[0] = species;
+         trkData[1] = p;
+         trkData[2] = l;
+         trkData[3] = ntrk;
+         trkData[5] = ncls;        
+         Double_t sum = 0.;
+         Int_t not0 = 0;
+         for(Int_t s=0; s<nSlices; ++s){
+           Double_t slice = esdTrack->GetTRDslice(l, s);
+           sum += slice;
+           if(slice > 0){
+             not0 += 1;
+             fOutput->Fill(hname2, p, s);
+           }
+         }//..slices
+
+         trkData[4] = not0;
+         fOutput->Fill(hname, p, not0);
+         fOutput->Fill(hname3, p, sum);
+         if(sum > 0){
+           sumTot += sum;
+           not0Tot += 1;
+         }
+         // lkelihoods per layer
+         if(not0Tot > 0 && fNNref){
+           Double_t likelihoods[5] = {-1., -1., -1., -1., -1};
+           TRDlikeTracklet(l, esdTrack, likelihoods);
+           trkData[6] = likelihoods[0];
+           //printf(" -D: species: %i, P; %f : %f, s: %f\n", species, p, likelihoods[0], s);
+         }
+         if(not0Tot) fOutput->Fill("hTRDtracklets", trkData);
+       }//..layers
+       // average dEx per number of tracklets
+       if(0 < not0Tot)
+         data[10] = sumTot / not0Tot;
+      }//.. kTRDpid
       
-      //TRD first electron only
-      Int_t nTRK = (int)esdTrack->GetTRDntrackletsPID();
-      if(AliHFEV0pid::kRecoElectron == species){
-       sprintf(hname, "hTRD_%s_trk", typeName[species]);
-       fOutput->Fill(hname, p, nTRK);
-      }
-      Char_t n1[256] = "";
-      Char_t n2[256] = "";     
-      Double_t pidProbs[AliPID::kSPECIES];
-      esdTrack->GetTRDpid(pidProbs);
-      Double_t threshold = pidTRD->GetTRDthresholds(0.9, p);
-      if(AliHFEV0pid::kRecoElectron == species && 6 == nTRK){
-       sprintf(n1, "hTRD_%s_Y_like", typeName[species]);
-       sprintf(n2, "hTRD_%s_N_like", typeName[species]);
-       if(pidProbs[typePID[0]] > threshold) fOutput->Fill(n1, p);
-       else fOutput->Fill(n2, p);
-       sprintf(hname, "hTRD_El_like_Electron");
-       fOutput->Fill(hname, p, pidProbs[typePID[species]]);
-      }
-      if( ((AliHFEV0pid::kRecoPionK0 == species) || (AliHFEV0pid::kRecoPionL == species)) && 6 == nTRK ){
-       sprintf(hname, "hTRD_El_like_Pion");
-       fOutput->Fill(hname, p, pidProbs[typePID[0]]);
-      }
-      if(AliHFEV0pid::kRecoProton == species && 6 == nTRK){
-       sprintf(hname,"hTRD_El_like_Proton");
-       fOutput->Fill(hname, p, pidProbs[typePID[0]]);
-      }
-    
+      
+      //
+      // TOF
+      //
+      if(status & AliESDtrack::kTOFpid){
+       Double_t p = esdTrack->GetOuterParam() ? esdTrack->GetOuterParam()->P() : esdTrack->P();
+       Double_t t0 = fESDpid->GetTOFResponse().GetTimeZero();
+
+       //TOF beta
+       sprintf(hname, "hTOF_beta_%s", typeName[species]);
+       Float_t beta = TOFbeta(esdTrack);       
+       fOutput->Fill(hname, p, beta);
+       fOutput->Fill("hTOF_beta_all", p, beta);
+       // TOF nSigma
+       Double_t nsigma = fESDpid->NumberOfSigmasTOF(esdTrack,(AliPID::EParticleType)typePID[species], t0);
+       sprintf(hname, "hTOF_nSigma_%s",  typeName[species]);
+       fOutput->Fill(hname, p, nsigma);
+       if(beta > 0.97 && beta < 1.03){
+         data[11] = 1;
+       }
+       
+       // TOF PID response
+       sprintf(hname, "hTOF_PID_p_%s", typeName[species]);
+       Double_t tofPID[5] = {-1., -1., -1., -1., -1};
+       esdTrack->GetTOFpid(tofPID);
+       Int_t ix = GetMaxPID(tofPID);
+       fOutput->Fill(hname, p, ix);
+       
+       // time of flight QA
+       // - distribution of (time - t0 - pion_time)
+       Double_t times[5];
+       esdTrack->GetIntegratedTimes(times);
+       Double_t tItrackL = esdTrack->GetIntegratedLength();
+       Double_t tTOFsignal = esdTrack->GetTOFsignal();
+       Double_t dT = tTOFsignal - t0 - times[2];
+       fOutput->Fill("hTOF_qa_TmT0mT", run*1.0, dT);
+       fOutput->Fill("hTOF_qa_length", run*1.0, tItrackL);
 
-      //TOF beta
-      sprintf(hname, "hTOF_beta_%s", typeName[species]);
-      Float_t beta = TOFbeta(esdTrack);
-      fOutput->Fill(hname, beta, p);
+       
+      }//.. kTOFpid
+      // temporary - the PIDsparse needs rebuilding
+      //fOutput->Fill("PIDsparse", data);
     }
     // AOD - comming soon
     else{
@@ -485,10 +872,22 @@ void AliHFEpidQA::FillPIDresponse(TObjArray * const particles, Int_t species){
     }
   }// .. tracks in TObjArray
   
-  if(pidTRD) delete pidTRD;
 
 }
+//__________________________________________
+void AliHFEpidQA:: CheckEvent(){
+  //
+  // check some event variables
+  //
 
+  // check the T0 as a function of run number (less than one bin per number
+  Double_t t0 = fESDpid->GetTOFResponse().GetTimeZero();
+  Int_t run = fEvent->GetRunNumber();
+  Double_t data[2] = {run*1.0, t0*1000.};
+  fOutput->Fill("hEvent_T0", data);
+  
+
+}
 //__________________________________________
 TList *AliHFEpidQA::GetOutput(){
   //
@@ -517,86 +916,27 @@ TList *AliHFEpidQA::GetV0pidMC(){
 
 //__________________________________________
 void AliHFEpidQA::RecalculateTRDpid(AliESDtrack * /*track*/, Double_t * /*pidProbs*/) const{
-//  fTRDpidResponse->MakePID(track);
-//  track->GetTRDpid(pidProbs);
+  //  fTRDpidResponse->MakePID(track);
+  //  track->GetTRDpid(pidProbs);
 }
 
 //__________________________________________
 void AliHFEpidQA::RecalculateTRDpid(AliAODTrack * /*track*/, Double_t * /*pidProbs*/) const{
-//  fTRDpidResponse->MakePID(track, pidProbs);
-}
-//___________________________________________________________________
-void AliHFEpidQA::CorrectT0(){
-  // temporary solutions for correction the T0 for pass4 & pass5
-  // returns corrected T0 for known runs
-  // returns 0 if the correction failed
-  if(! fRun > 0){
-    AliError("Run number not set");
-    fT0 = 0.;
-    return;
-  }
-  Bool_t runFound = kFALSE;
-  const Int_t corr[31][2] = {{104065, 1771614},
-                            {104068, 1771603},
-                            {104070, 1771594},
-                            {104073, 1771610},
-                            {104080, 1771305},
-                            {104083, 1771613},
-                            {104157, 1771665},
-                            {104159, 1771679},
-                            {104160, 1771633},
-                            {104316, 1764344},
-                            {104320, 1764342},
-                            {104321, 1764371},
-                            {104439, 1771750},
-                            {104792, 1771755},
-                            {104793, 1771762},
-                            {104799, 1771828},
-                            {104800, 1771788},
-                            {104801, 1771796},
-                            {104802, 1771775},
-                            {104803, 1771795},
-                            {104824, 1771751},
-                            {104825, 1771763},
-                            {104845, 1771792},
-                            {104852, 1771817},
-                            {104864, 1771825},
-                            {104865, 1771827},
-                            {104867, 1771841},
-                            {104876, 1771856},
-                            {104878, 1771847},
-                            {104879, 1771830},
-                            {104892, 1771837}};
-  for(Int_t i=0; i<31; ++i){
-    if(fRun == corr[i][0]){
-      runFound = kTRUE;
-      fT0 = (float)corr[i][1];
-      // for the pass4 & pass5
-      fT0 -= 37*1024*24.4 - 170.;
-      //..
-      break;
-    }
-  }
-
-  if(!runFound){
-    TString error = "Setting T0 correction FAILED, no TOF pid available for run: ";
-    error += fRun;
-    AliError(error);
-    fT0 = 0.;
-  }
-  //cout<<" -D: run: "<<current_run<<" , fT0: "<<fT0<<endl;
-  
+  //  fTRDpidResponse->MakePID(track, pidProbs);
 }
 //___________________________________________________________________
 Float_t AliHFEpidQA::TOFbeta(AliESDtrack * const track) const {
   // computes the TOF beta
   Double_t l = track->GetIntegratedLength();  // cm
   Double_t t = track->GetTOFsignal();
-  Double_t t0 = fT0; // ps
+  Double_t t0 = fESDpid->GetTOFResponse().GetTimeZero(); // ps
+
+  //printf("-D: l: %f, t: %f, t0: %f\n", l, t, t0);
+
   if(l < 360. || l > 800.) return 0.;
   if(t <= 0.) return 0.;
-  if(t0 <= 0.) return 0.;
+  if(t0 >999990.0) return 0.;
+  
 
   t -= t0; // subtract the T0
 
@@ -609,4 +949,255 @@ Float_t AliHFEpidQA::TOFbeta(AliESDtrack * const track) const {
 
   return beta;
 }
+//____________________________________________
+Int_t AliHFEpidQA::GetMaxPID(Double_t *pidProbs) const {
+  //
+  // return the index of maximal PID probability
+  //
+  Int_t ix = -1;
+  Double_t tmp = 0.2;
+  for(Int_t i=0; i<5; ++i){
+    if(pidProbs[i] > tmp){
+      ix = i;
+      tmp = pidProbs[i];
+    }
+  }
+  return ix;
+}
+//_____________________________________________
+Int_t AliHFEpidQA::GetPDG(Int_t species){
+  //
+  // return the PDG particle code
+  //
+
+  Int_t pdg = 0;
+
+  switch(species){
+  case  AliHFEV0pid::kRecoElectron:
+    pdg = TMath::Abs(kElectron);
+    break;
+  case  AliHFEV0pid::kRecoPionK0:
+    pdg = TMath::Abs(kPiPlus);
+    break;
+  case  AliHFEV0pid::kRecoPionL:
+    pdg = TMath::Abs(kPiPlus);
+    break;
+  case  AliHFEV0pid::kRecoProton:
+    pdg = TMath::Abs(kProton);
+    break;
+  default:  // non investigated species
+    AliDebug(3, "Species not recognised");
+    return 0;
+  }  
+
+  return pdg;
+
+}
+
+//_____________________________________________
+TObjArray * AliHFEpidQA::MakeTrackList(TObjArray *tracks) const {
+  //
+  // convert list of AliHFEV0Info into a list of AliVParticle
+  //
+  TObjArray *output = new TObjArray;
+  TIter trackInfos(tracks);
+  AliHFEV0info *trackInfo = NULL;
+  while((trackInfo = dynamic_cast<AliHFEV0info *>(trackInfos())))
+    output->Add(trackInfo->GetTrack());
+
+  return output;
+}
+
+//_____________________________________________
+TObjArray * AliHFEpidQA::MakeCleanListElectrons(TObjArray *electrons) const {
+  //
+  // Cleanup electron sample using TPC PID
+  // PID requirement will allways be implemented to the pair
+  // Strategy
+  //
+  TObjArray *tracks = new TObjArray;
+  TIter candidates(electrons);
+  AliESDEvent *esd; AliAODEvent *aod;
+  AliHFEV0info *hfetrack;
+  if((esd = dynamic_cast<AliESDEvent *>(fEvent))){
+    AliESDtrack *track = NULL, *partnerTrack = NULL;
+    while((hfetrack = dynamic_cast<AliHFEV0info *>(candidates()))){
+      track = dynamic_cast<AliESDtrack *>(hfetrack->GetTrack());
+      partnerTrack = esd->GetTrack(hfetrack->GetPartnerID());
+      Double_t nSigmaTrack = TMath::Abs(fESDpid->NumberOfSigmasTPC(track, AliPID::kElectron));
+      Double_t nSigmaPartner = TMath::Abs(fESDpid->NumberOfSigmasTPC(partnerTrack, AliPID::kElectron));
+      if((nSigmaTrack < 1 && nSigmaPartner < 4) || (nSigmaTrack < 4 && nSigmaPartner < 1))
+        tracks->Add(track);
+    }
+  } else {
+    aod = dynamic_cast<AliAODEvent *>(fEvent);
+    AliAODTrack *track = NULL, *partnerTrack = NULL;
+    while((hfetrack = dynamic_cast<AliHFEV0info *>(candidates()))){
+      track = dynamic_cast<AliAODTrack *>(hfetrack->GetTrack());
+      partnerTrack = aod->GetTrack(hfetrack->GetPartnerID());
+      // will be coming soon
+    }
+  }
+  return tracks;
+}
+//___________________________________________________________
+void AliHFEpidQA::CheckTenderV0pid(TObjArray * const particles, Int_t species){
+
+  //
+  // retrieve the status bits from the TObject used to flag
+  // the V0 daughter tracks and return the found PID
+  // 0 - electron, 1 - pion, 2 - proton
+  // 
+
+  const Int_t id[5] = {0, 1, 1, -1, 2}; // convert AliHFEpid to simple 0, 1, 2
+
+  AliVParticle *recTrack = NULL;
+  TIter trackIter(particles); 
+  while((recTrack = dynamic_cast<AliVParticle *>(trackIter()))){
+    if(!TString(recTrack->IsA()->GetName()).CompareTo("AliESDtrack")){
+      // case ESD
+      AliESDtrack *track = dynamic_cast<AliESDtrack *>(recTrack);
+      if(!track) continue;
+      Int_t tPID = GetTenderV0pid(track);
+      fOutput->Fill("h_tender_check_01", id[species]*1.0, tPID);
+      fOutput->Fill("h_tender_check_02", id[species], id[species]*1.0, tPID);
+      
+    } //.. case ESD      
+    
+  }//.. iterate of tracks  
+}
+//___________________________________________________________
+Int_t AliHFEpidQA::GetTenderV0pid(AliESDtrack * const track){
+  //
+  // retrieve the PID nformation stored in the status flags by the train tender
+  //
+  
+
+  Int_t pid = -1;
+  if(!track){
+    return pid;
+  }
+  
+  Int_t nTimes = 0;
+  
+  if(track->TestBit(2<<14)){
+    pid = 0;
+    nTimes++;
+  }
+  if(track->TestBit(2<<15)){
+    pid = 1;
+    nTimes++;
+  }
+  if(track->TestBit(2<<16)){
+    pid = 2;
+    nTimes++;
+  }
+  
+  if(nTimes > 1){
+    AliWarning("V0 track labeled multiple times by the V0 tender");
+    pid = -1;
+  }
+    
+  return pid;
+
+}
+//___________________________________________________________
+Double_t AliHFEpidQA::TRDlikeTracklet(Int_t layer, AliESDtrack * const track, Double_t *likelihood){
+  //
+  // compute the TRD electron likelihoods for 1 tracklet
+  // based on teh AliTRDpidRecalculator in train/until/tender
+  // returns sum of the likelihoods (which should be 1)
+  //
+
+  const Double_t cScaleGain = 1./ 16000.;
+  const Float_t pBins[11] ={0.6, 0.8, 1.0, 1.5, 2.0, 3.0, 4.0, 5.0, 6.0, 8.0, 10.0}; // momentum bins
+
+  if(!track) return kFALSE;
+  Float_t p = track->GetTRDmomentum(layer); // momentum for a tracklet in the ESDtrack
+  if(p < 0) return kFALSE;
+
+  Int_t mombin = TRDmomBin(p);  // momentum bin
+  Float_t dEdxTRDsum = 0;              // dEdxTRDsum for checking if tracklet is available
+  Float_t dEdxTRD[8];           // dEdx for a tracklet in the ESD slices
+  Double_t ddEdxTRD[8];         // dEdx as Double_t for TMultiLayerPerceptron::Evaluate()
+  
+  Double_t prob[AliPID::kSPECIES];  // probabilities for all species in all layers
+
+  for(Int_t is = 0; is < AliPID::kSPECIES; is++){
+    likelihood[is] = 0.2;               // init probabilities
+    prob[is] = 0.2; 
+  }
+
+  Double_t sum = 0.;
+
+  for(Int_t islice = 0; islice<8; islice++){
+    dEdxTRD[islice]=0.;                                    // init dE/dx
+    ddEdxTRD[islice]=0.;                                   // init dE/dx
+    dEdxTRD[islice]=track->GetTRDslice(layer,islice);       // get the dE/dx values
+    dEdxTRDsum += dEdxTRD[islice];
+    ddEdxTRD[islice]=(Double_t)dEdxTRD[islice]*cScaleGain;            // rescale dE/dx
+    
+  }
+  for(Int_t is = 0; is < AliPID::kSPECIES; is++){
+    Double_t probloc1, probloc2; 
+    if(mombin == 0 && mombin < pBins[0]){          //  calculate PID for p > 0.6 GeV/c
+      prob[is] = fNet[mombin]->Evaluate(is, ddEdxTRD);
+    }
+    else if(mombin == 10 && mombin >= pBins[10]){   //  calculate PID for p >= 10.0 GeV/c
+      prob[is] = fNet[mombin]->Evaluate(is, ddEdxTRD);
+    }
+    else{                                                    //  standard calculation
+      Int_t mombin1 = 0, mombin2 = 0;             // lower and upper momentum bin      
+      if(p < pBins[mombin]) {mombin1 = mombin -1; mombin2 = mombin;}
+      if(p >= pBins[mombin]) {mombin1 = mombin; mombin2 = mombin+1;}
+      probloc1 = fNet[mombin1]->Evaluate(is, ddEdxTRD);
+      probloc2 = fNet[mombin2]->Evaluate(is, ddEdxTRD);
+      // weighting of the probability with regard to the track momentum
+      prob[is] = probloc1 + (probloc2-probloc1)*(p-pBins[mombin1])/(pBins[mombin2]-pBins[mombin1]);
+    }
+    likelihood[is] = prob[is];
+    sum += likelihood[is];
+  }     
+  
+  return sum;
+}
+//__________________________________________________________________________
+Int_t  AliHFEpidQA::TRDmomBin(Double_t p){
+  //
+  // compute the momentum bin position
+  // 
+
+  const Float_t pBins[11] ={0.6, 0.8, 1.0, 1.5, 2.0, 3.0, 4.0, 5.0, 6.0, 8.0, 10.0}; // momentum bins
+  
+  Int_t pBin1 = -1;                                    // check bin1
+  Int_t pBin2 = -1;                                    // check bin2
+
+  if(p < 0) return -1;                                 // return -1 if momentum < 0
+  if(p < pBins[0]) return 0;                                      // smallest momentum bin
+  if(p >= pBins[10]) return 10; // largest momentum bin
+
+
+  // calculate momentum bin for non extremal momenta
+  for(Int_t iMomBin = 1; iMomBin < 11; iMomBin++){
+    if(p < pBins[iMomBin]){
+      pBin1 = iMomBin - 1;
+      pBin2 = iMomBin;
+    }
+    else
+      continue;
+
+    if(p - pBins[pBin1] >= pBins[pBin2] - p){
+      return pBin2;
+    }
+    else{
+      return pBin1;
+    }
+  }
+
+  return -1;
+
+
+}
+//__________________________________________________________________________
+
+
index 0434c56cccd8f432ee7eb040626f8324fea9c7c9..9c2c2b21a9a097220a59aff47ff058c5d59ce538 100644 (file)
 
 class TList;
 class TObjArray;
+class TPDGCode;
+class TParticle;
+class TFile;
+class TMultiLayerPerceptron;
 
 class AliAODTrack;
 class AliESDtrack;
-class AliHFEcollection;
-class AliHFEV0pid;
 class AliMCEvent;
-//class AliTRDPIDResponseLQ1D;
 class AliVEvent;
 class AliESDpid;
+class AliExternalTrackParam;
+class AliLog;
+
 class AliHFEV0pidMC;
+class AliHFEcollection;
+class AliHFEtrdPIDqa;
+class AliHFEV0pid;
+class AliHFEpidTRD;
+
 
 class AliHFEpidQA : public TObject{
   public:
     AliHFEpidQA();
     ~AliHFEpidQA();
+    AliHFEpidQA(const AliHFEpidQA &ref);
+    AliHFEpidQA &operator=(const AliHFEpidQA &ref);
+    virtual void Copy(TObject &o) const;
 
     void Init();
-    void Process(AliVEvent *inputEvent);
+    void Process();
 
     TList *GetOutput();
     TList *GetV0pidQA();
@@ -53,15 +65,18 @@ class AliHFEpidQA : public TObject{
     Bool_t   HasV0pidQA() const { return TestBit(kV0pidQA); };
     Bool_t   HasRecalculateTRDpid() const { return TestBit(kRecalculateTRDpid); };
 
+    void     SetEvent(AliVEvent* const ev) { fEvent = ev; };
     void     SetMCEvent(AliMCEvent * const mc) { fMC = mc; };
     void     SetV0pidQA(Bool_t v0pidQA = kTRUE) { SetBit(kV0pidQA, v0pidQA); };
     void     SetRecalculateTRDpid(Bool_t recal = kTRUE) { SetBit(kRecalculateTRDpid, recal); };
 
-    void     SetRun(Int_t run) { fRun = run; };
-    // temporary solutions for correction the T0 for pass4 & pass5
-    void     CorrectT0();
-    void     SetT0(Float_t t0) { fT0 = t0; };
-    Float_t  TOFbeta(AliESDtrack *const track) const;
+    void     SetESDpid(AliESDpid* const pid) { fESDpid = pid; }
+    Float_t  TOFbeta(AliESDtrack* const track) const;
+
+    void     CheckEvent();
+    void     SetNNref(TFile *f) { fNNref = f; };
+    
+    AliHFEtrdPIDqa *GetTRDQA() const { return fTRDpidQA; }
 
   protected:
     enum{
@@ -72,27 +87,41 @@ class AliHFEpidQA : public TObject{
       kITS = 0,
       kTPC = 1,
       kTRD = 2,
-      kTOF = 4
+      kTOF = 3
     };
 
+    TObjArray *MakeTrackList(TObjArray *tracks) const;
+    TObjArray *MakeCleanListElectrons(TObjArray *tracks) const;
+
     void MakePurity(TObjArray *tracks, Int_t species);
-    void FillTRDelectronLikelihoods(TObjArray * const particles, Int_t species);
+    TObjArray *MakeCleanListForTRD(TObjArray * const track, Int_t species);
+    void FillElectronLikelihoods(TObjArray * const particles, Int_t species);
     void FillPIDresponse(TObjArray * const particles, Int_t species);
+    void FillIllumination(TObjArray *const particles, Int_t species);
+    void FillTPCinfo(AliESDtrack * const track, Int_t species);
     void RecalculateTRDpid(AliESDtrack *track, Double_t *pidProbs) const;
     void RecalculateTRDpid(AliAODTrack *track, Double_t *pidProbs) const;
+    void CheckTenderV0pid(TObjArray * const particles, Int_t species);
+    Int_t GetTenderV0pid(AliESDtrack * const track);
+    
+    Double_t TRDlikeTracklet(Int_t layer, AliESDtrack * const track, Double_t *likelihood);
+    Int_t  TRDmomBin(Double_t p);
 
+ protected:
+    Int_t GetMaxPID(Double_t *pidProbs) const;
+    Int_t GetPDG(Int_t index);
+    
   private:
-    AliHFEpidQA(const AliHFEpidQA &ref);
-    AliHFEpidQA &operator=(const AliHFEpidQA &ref);
-
+    AliVEvent         *fEvent;        // event pointer
     AliMCEvent        *fMC;           // MC Event
     AliHFEV0pid       *fV0pid;        // V0 PID 
     AliHFEV0pidMC     *fV0pidMC;      // V0 MC PID
-    //AliTRDPIDResponseLQ1D *fTRDpidResponse;   // TRD PID
+    AliHFEtrdPIDqa    *fTRDpidQA;     //! TRD PID QA object
     AliHFEcollection  *fOutput;       // Output container
-    Float_t            fT0;           // corrected T0 for pass4 & pass5
-    Int_t              fRun;          // Run Number
-    AliESDpid *fESDpid;               // ESD PID object
+    AliESDpid         *fESDpid;       // ESD PID object
+ private:
+    TFile             *fNNref;        // reference file for NN pid 
+    TMultiLayerPerceptron *fNet[11];  //  reference networks
   
   ClassDef(AliHFEpidQA, 1)            // PID QA tool
 };
index 11e10e9d63507ef66aa54ea2bc5d67ced8e4e9fd..a29990a2e34635f0aeccda04d49b9137d4717401 100644 (file)
 //   Matus Kalisky <matus.kalisky@cern.ch>  (contact)
 //
 
-#include <TH2F.h>
 #include <TList.h>
 #include <TMath.h>
+#include <THnSparse.h>
+#include <TDatabasePDG.h>
 
 #include "AliAODTrack.h"
 #include "AliAODMCParticle.h"
 #include "AliESDtrack.h"
-#include "AliLog.h"
 #include "AliMCParticle.h"
 #include "AliPID.h"
 #include "AliESDpid.h"
 
+#include "AliHFEcollection.h"
 #include "AliHFEpidTOF.h"
 #include "AliHFEpidBase.h"
 
@@ -45,22 +46,17 @@ AliHFEpidTOF::AliHFEpidTOF(const Char_t *name):
   AliHFEpidBase(name)
   , fPID(0x0)
   , fQAList(0x0)
-  , fESDpid(NULL)
   , fNsigmaTOF(3)
 {
   //
   // Constructor
   //
-
-  fESDpid = new AliESDpid;
-
 }
 //___________________________________________________________________
 AliHFEpidTOF::AliHFEpidTOF(const AliHFEpidTOF &c):
   AliHFEpidBase("")
   , fPID(0x0)
   , fQAList(0x0)
-  , fESDpid(NULL)
   , fNsigmaTOF(3)
 {  
   // 
@@ -87,7 +83,6 @@ AliHFEpidTOF::~AliHFEpidTOF(){
   // Destructor
   //
   if(fPID) delete fPID;
-  if(fESDpid) delete fESDpid;
   if(fQAList){
     fQAList->Delete();
     delete fQAList;
@@ -102,7 +97,6 @@ void AliHFEpidTOF::Copy(TObject &ref) const {
 
   target.fPID = fPID;          
   target.fQAList = fQAList;
-  target.fESDpid = new AliESDpid(*fESDpid); 
 
   AliHFEpidBase::Copy(ref);
 }
@@ -131,7 +125,7 @@ Int_t AliHFEpidTOF::IsSelected(AliHFEpidObject *vtrack)
     AliESDtrack *esdTrack = dynamic_cast<AliESDtrack *>(vtrack->fRecTrack);
     if(!esdTrack) return 0;
     AliMCParticle *mcTrack = dynamic_cast<AliMCParticle *>(vtrack->fMCtrack);
-    return MakePIDesd(esdTrack, mcTrack);
+    return MakePIDesdV3(esdTrack, mcTrack);
   } else {
     AliAODTrack *aodTrack = dynamic_cast<AliAODTrack *>(vtrack->fRecTrack);
     if(!aodTrack) return 0;
@@ -145,31 +139,35 @@ Int_t AliHFEpidTOF::MakePIDesd(AliESDtrack *track, AliMCParticle * /*mcTrack*/){
   //
   // Does particle identification as discribed in IsSelected
   //
+  if(!fESDpid){
+    AliError("No ESD PID object available");
+    return kFALSE;
+  }
   Long_t status = 0;
   status = track->GetStatus(); 
 
   if(!(status & AliESDtrack::kTOFout)) return 0;
   
-  if(IsQAon())(dynamic_cast<TH1F *>(fQAList->At(kHistTOFpidFlags)))->Fill(0.);
+  if(IsQAon()) fQAList->Fill("hTOF_flags", 0.);
 
   Double_t tItrackL = track->GetIntegratedLength();
   Double_t tTOFsignal = track->GetTOFsignal();
   
   if(IsQAon()){
     if(tItrackL > 0)
-      (dynamic_cast<TH1F *>(fQAList->At(kHistTOFpidFlags)))->Fill(1.);
+      fQAList->Fill("hTOF_flags", 1.);
 
     if(tTOFsignal > 0)
-      (dynamic_cast<TH1F *>(fQAList->At(kHistTOFpidFlags)))->Fill(2.);
+      fQAList->Fill("hTOF_flags", 2.);
   }
   
 
   if(tItrackL <=0 || tTOFsignal <=0) return 0;
 
   if(IsQAon()){
-    (dynamic_cast<TH1F *>(fQAList->At(kHistTOFpidFlags)))->Fill(3.);
-    (dynamic_cast<TH1F *>(fQAList->At(kHistTOFsignal)))->Fill(tTOFsignal/1000.);
-    (dynamic_cast<TH1F *>(fQAList->At(kHistTOFlength)))->Fill(tItrackL);
+    fQAList->Fill("hTOF_flags", 3.);
+    fQAList->Fill("hTOF_signal", tTOFsignal/1000.);
+    fQAList->Fill("hTOF_length", tItrackL);
   }
   // get the TOF pid probabilities
   Double_t tESDpid[5] = {0., 0., 0., 0., 0.};
@@ -188,12 +186,13 @@ Int_t AliHFEpidTOF::MakePIDesd(AliESDtrack *track, AliMCParticle * /*mcTrack*/){
 
   Int_t pdg = 0;
 
+  TString specname;
   switch(tMAXindex){
-    case 0:    pdg = 11; break;
-    case 1:    pdg = 13; break;
-    case 2:    pdg = 211; break;
-    case 3:    pdg = 321; break;
-    case 4:    pdg = 2212; break;
+    case 0:    pdg = 11; specname = "electron";  break;
+    case 1:    pdg = 13; specname = "muon"; break;
+    case 2:    pdg = 211; specname = "pion"; break;
+    case 3:    pdg = 321; specname = "kaon"; break;
+    case 4:    pdg = 2212; specname = "proton"; break;
     default:   pdg = 0;
   };
 
@@ -211,13 +210,146 @@ Int_t AliHFEpidTOF::MakePIDesd(AliESDtrack *track, AliMCParticle * /*mcTrack*/){
   // should be the same as AliPID flags
   
   if(IsQAon()){
-    (dynamic_cast<TH2F *>(fQAList->At(kHistTOFpid0+tMAXindex)))->Fill(beta, p);
-    (dynamic_cast<TH2F *>(fQAList->At(kHistTOFpidBetavP)))->Fill(beta, p);
+    TString histname = "hTOFpid_" + specname;
+    fQAList->Fill(histname.Data(), beta, p);
+    fQAList->Fill("fTOFbeta_v_P_no", beta, p);
   }
   //return tMAXindex;
   return pdg;
   
 }
+//__________________________________________________________________
+Int_t AliHFEpidTOF::MakePIDesdV2(AliESDtrack *track, AliMCParticle * /*mcTrack*/){
+  //
+  // Computes the PID response based on TOF & T0 signal
+  //
+  
+  if(!fESDpid){
+    AliError("No ESD PID object available");
+    return kFALSE;
+  }
+  Long_t status = 0;
+  status = track->GetStatus(); 
+  if(!(status & AliESDtrack::kTOFpid)) return 0;
+
+  Double_t p = track->GetOuterParam()->P();  
+  // track integrated times for 5 different hypothesis and T0 time
+  Double_t times[5];
+  track->GetIntegratedTimes(times);
+  Double_t tItrackL = track->GetIntegratedLength();
+  Double_t tTOFsignal = track->GetTOFsignal();
+  Double_t t0 = fESDpid->GetTOFResponse().GetTimeZero();
+  //printf("-D: tof: %f, T0: %f\n", tTOFsignal, t0);
+  // suppress missing or wrong T0 information
+  if(t0 > 999990.0) return 0;
+  Double_t tof = tTOFsignal - t0;
+  Double_t beta = (tItrackL/100.)/((TMath::C()*tof)/1e12);
+  //if(IsQAon())fQAList->Fill("hTOFbetaV2all", p, beta);  
+
+  const Int_t pdg[5] = {11, 13, 211, 321, 2212};
+  const Double_t invMass[5] = {TDatabasePDG::Instance()->GetParticle(11)->Mass(),
+                              TDatabasePDG::Instance()->GetParticle(13)->Mass(),
+                              TDatabasePDG::Instance()->GetParticle(211)->Mass(),
+                              TDatabasePDG::Instance()->GetParticle(321)->Mass(),
+                              TDatabasePDG::Instance()->GetParticle(2212)->Mass()};
+
+
+  // accepted beta bands as function of momentum - parameters
+  // line: par[0]/p + par[1] + expected_tof
+  const Double_t bMin[5][2] = {{0., -0.03}, {-0.005, -0.02}, {-0.005, -0.02}, {-0.02, -0.006}, {-0.03, -0.005}}; 
+  const Double_t bMax[5][2] = {{0., 0.03}, {0.005, 0.02}, {0.005, 0.02}, {0.02, 0.006}, {0.03, 0.005}};             
+            
+  Int_t index = -1;
+  Double_t rdiff = 1.;
+  for(Int_t i=0; i<5; ++i){
+    Double_t d = (TMath::Abs(times[i] - tof))/times[i];
+    if(d < rdiff){
+      rdiff = d;
+      index = i;
+    }
+  }
+
+  // stupid and unnecessary complicated - to be improved soon
+  Double_t a = p/(invMass[index]);
+  a *= a;
+  Double_t betaMatch = TMath::Sqrt(a/(1+a));
+
+  // check wheter the most probable match is within allowed region of beta for given momentum and species
+  Double_t min = bMin[index][0]/p + bMin[index][1] + betaMatch;
+  Double_t max = bMax[index][0]/p + bMax[index][1] + betaMatch;  
+
+  // debug
+  //printf("-D: p: %f, beta: %f, pdg: %i, min: %f, max: %f\n", p, beta, pdg[index], min, max);
+
+  //
+  // PID decision - can be simpler than the QA histograms above could indicate !
+  // 
+  
+  // suppress nonsense
+  if(beta < 0.2) return 0;  
+
+  // 1) Simple version - protect electrons
+  if(beta > (1+bMin[0][1]) && beta < (1+bMax[0][1])){
+    //if(IsQAon())fQAList->Fill("hTOFbetaV2electron", p, beta);
+    return 11;
+  }
+  else return 0;
+  
+  // NOT ACTIVE when (1) activated
+  // 2) more complex version - return true PID of the particle based on the best TOF estimate
+  // under development - still keep protecting electrons
+  if(beta > (1+bMin[0][1]) && beta < (1+bMax[0][1])){
+    if(IsQAon())fQAList->Fill("hTOFbetaV2_electron", p, beta);
+    return 11;
+  }
+  // above 3 GeV/c the supression gets weak
+  if(p > 3.0) return 0;
+  if(beta > min && beta < max) {
+    if(IsQAon())fQAList->Fill("hTOFbetaV2selected", p, beta);
+    return pdg[index];
+  }
+  
+
+  return 0;
+}
+
+//___________________________________________________________________
+Int_t AliHFEpidTOF::MakePIDesdV3(AliESDtrack *track, AliMCParticle * /*mctrack*/){
+  //
+  // TOF PID based on n-Sigma cut
+  // Selects Protons and Kaons via n-sigma cut up to 3 GeV/c
+  // In addition histos for n-sigma before (all species) and after (only closest species) are filled
+  //
+  if(!fESDpid){
+    AliError("No ESD pid Object available. Return");
+    return 0;
+  }
+  if(!(track->GetStatus() & AliESDtrack::kTOFpid)) return 0;
+  Double_t t0 = fESDpid->GetTOFResponse().GetTimeZero();
+  Double_t p = track->GetOuterParam() ? track->GetOuterParam()->P() : track->P();
+
+  // Fill before selection
+  Double_t sigEle = fESDpid->NumberOfSigmasTOF(track, AliPID::kElectron, t0);
+  //printf("-D: p: %f, t0: %f, nSigma: %f\n", p, t0, sigEle);
+  Int_t pdg = 0;
+  if(TMath::Abs(sigEle) < fNsigmaTOF)
+    pdg = 11;
+  if(IsQAon()){
+    Double_t hcontent[3] = {p, sigEle, 0};
+    hcontent[0] = p;
+    hcontent[1] = sigEle;
+    hcontent[2] = 0;
+    THnSparseF * hptr = dynamic_cast<THnSparseF *>(fQAList->Get("hTOFsigmaElectron"));
+    hptr->Fill(hcontent);
+    if(pdg == 11){
+      hcontent[2] = 1;
+      hptr->Fill(hcontent);
+    }
+  }
+  return pdg;
+}
 //___________________________________________________________________
 Double_t AliHFEpidTOF::Likelihood(const AliESDtrack *track, Int_t species, Float_t rsig){
   
@@ -259,19 +391,28 @@ void AliHFEpidTOF::AddQAhistograms(TList *qaList){
   // Create QA histograms for TOF PID
   //
 
-  fQAList = new TList;
-  fQAList->SetName("fTOFqaHistos");
-  fQAList->AddAt(new TH1F("hTOF_flags", "TOF flags;flags (see code for info);counts", 10, -0.25, 4.75), kHistTOFpidFlags);
-  fQAList->AddAt(new TH2F("fTOFbeta_v_P_no","beta -v- P; beta;momentum [GeV/c]", 120, 0, 1.2, 200, 0, 20), kHistTOFpidBetavP);
-  fQAList->AddAt(new TH1F("hTOF_signal", "TOF signal; TOF signal [ns];counts", 1000, 12, 50), kHistTOFsignal);
-  fQAList->AddAt(new TH1F("hTOF_length", "TOF track length; length [cm];counts", 400, 300, 700), kHistTOFlength);
-  fQAList->AddAt(new TH2F("hTOFpid_electron", "TOF reco electron; beta ; momentum [GeV/c]", 120, 0, 1.2, 200, 0, 5), kHistTOFpid0);
-  fQAList->AddAt(new TH2F("hTOFpid_muon", "TOF reco muon; beta ; momentum [GeV/c]", 120, 0, 1.2, 200, 0, 5), kHistTOFpid1);
-  fQAList->AddAt(new TH2F("hTOFpid_pion", "TOF reco pion; beta ; momentum [GeV/c]", 120, 0, 1.2, 200, 0, 5), kHistTOFpid2);
-  fQAList->AddAt(new TH2F("hTOFpid_kaon", "TOF reco kaon; beta ; momentum [GeV/c]", 120, 0, 1.2, 200, 0, 5), kHistTOFpid3);
-  fQAList->AddAt(new TH2F("hTOFpid_proton", "TOF reco proton; beta ; momentum [GeV/c]", 120, 0, 1.2, 200, 0, 5), kHistTOFpid4);
-
-  qaList->AddLast(fQAList);
+  fQAList = new AliHFEcollection("TOFqaHistos", "Collection for TOF PID histograms");
+  //fQAList->SetName("fTOFqaHistos");
+  fQAList->CreateTH1F("hTOF_flags", "TOF flags;flags (see code for info);counts", 10, -0.25, 4.75);
+  fQAList->CreateTH2F("fTOFbeta_v_P_no","beta -v- P; beta;momentum [GeV/c]", 120, 0, 1.2, 200, 0, 20);
+  fQAList->CreateTH1F("hTOF_signal", "TOF signal; TOF signal [ns];counts", 1000, 12, 50);
+  fQAList->CreateTH1F("hTOF_length", "TOF track length; length [cm];counts", 400, 300, 700);
+  fQAList->CreateTH2F("hTOFpid_electron", "TOF reco electron; beta ; momentum [GeV/c]", 120, 0, 1.2, 200, 0, 5);
+  fQAList->CreateTH2F("hTOFpid_muon", "TOF reco muon; beta ; momentum [GeV/c]", 120, 0, 1.2, 200, 0, 5);
+  fQAList->CreateTH2F("hTOFpid_pion", "TOF reco pion; beta ; momentum [GeV/c]", 120, 0, 1.2, 200, 0, 5);
+  fQAList->CreateTH2F("hTOFpid_kaon", "TOF reco kaon; beta ; momentum [GeV/c]", 120, 0, 1.2, 200, 0, 5);
+  fQAList->CreateTH2F("hTOFpid_proton", "TOF reco proton; beta ; momentum [GeV/c]", 120, 0, 1.2, 200, 0, 5);
+  //fQAList->CreateTH2F("hTOFbetaV2all", "TOF #beta vs p for all tracks; momentum [GeV/c]; beta ", 400, 0.1, 10., 1200, 0, 1.2, 0);
+  //fQAList->CreateTH2F("hTOFbetaV2electron", "TOF #beta vs p for selected electron tracks; momentum [GeV/c]; beta", 400, 0.1, 10., 1200, 0, 1.2, 0);
+
+  // histograms for sigma cut
+  const Int_t kNdim= 3;
+  Int_t nBins[kNdim] = {1000, 1400, 2};
+  Double_t binMin[kNdim] = {0.1, -12., 0};
+  Double_t binMax[kNdim] = {20, 12., 2};
+  fQAList->CreateTHnSparse("hTOFsigmaElectron", "TOF N#sigma around the Electron Line for all tracks; p (GeV/c); N sigma; Selection Step", kNdim, nBins, binMin, binMax);
+
+  qaList->AddLast(fQAList->GetList());
 }
 
 
index 234816efd2e53199d4f36efc08e851499f677c9f..a64b1b7dd7c9cdde567e81a7072da7f7613093d2 100644 (file)
@@ -21,6 +21,9 @@ class AliAODMCParticle;
 class AliESDtrack;
 class AliMCParticle;
 class AliESDpid;
+class AliLog;
+
+class AliHFEcollection;
 
 class AliHFEpidTOF : public AliHFEpidBase{
   public:
@@ -41,6 +44,8 @@ class AliHFEpidTOF : public AliHFEpidBase{
     void Copy(TObject &ref) const;
     void AddQAhistograms(TList *qaHist);
     Int_t MakePIDesd(AliESDtrack *esdTrack, AliMCParticle *mcTrack);
+    Int_t MakePIDesdV2(AliESDtrack *esdTrack, AliMCParticle *mcTrack);
+    Int_t MakePIDesdV3(AliESDtrack *esdTrack, AliMCParticle *mcTrack);
     Int_t MakePIDaod(AliAODTrack *aodTrack, AliAODMCParticle *mcTrack);
   
   private:
@@ -57,10 +62,9 @@ class AliHFEpidTOF : public AliHFEpidBase{
     } QAHist_t;
   
     AliPID        *fPID;           //! PID Object
-    TList         *fQAList;        //! QA histograms
-    AliESDpid *fESDpid;            //! ESD pid object
+    AliHFEcollection *fQAList;     //! QA histograms
 
-    Short_t fNsigmaTOF;            // TOF sigma band
+    Short_t    fNsigmaTOF;         // TOF sigma band
 
     ClassDef(AliHFEpidTOF, 1)
 };
index c8bdd8d1089d8abc6ec309d0b171b4afb4c3ccf1..41cae9411e510007ecb75ade5cc340ca0e71d42f 100644 (file)
 //   Markus Fasel <M.Fasel@gsi.de> 
 //   Markus Heide <mheide@uni-muenster.de> 
 //  
-#include <TH2I.h>
+#include <TF1.h>
 #include <TList.h>
 #include <TMath.h>
-//#include <TParticle.h>
+#include <THnSparse.h>
 
 #include "AliAODTrack.h"
 #include "AliAODMCParticle.h"
 #include "AliMCParticle.h"
 #include "AliPID.h"
 #include "AliESDpid.h"
-//#include "AliVParticle.h"
 
 #include "AliHFEcollection.h"
 #include "AliHFEpidTPC.h"
 
-
+ClassImp(AliHFEpidTPC)
 
 //___________________________________________________________________
 AliHFEpidTPC::AliHFEpidTPC(const char* name) :
@@ -51,10 +50,11 @@ AliHFEpidTPC::AliHFEpidTPC(const char* name) :
   AliHFEpidBase(name)
   , fLineCrossingType(0)
   , fLineCrossingsEnabled(0)
+  , fUpperSigmaCut(NULL)
+  , fLowerSigmaCut(NULL)
   , fNsigmaTPC(3)
   , fRejectionEnabled(0)
   , fPID(NULL)
-  , fESDpid(NULL)
   , fQAList(NULL)
 {
   //
@@ -64,7 +64,6 @@ AliHFEpidTPC::AliHFEpidTPC(const char* name) :
   memset(fPAsigCut, 0, sizeof(Float_t) * 2);
   memset(fNAsigmaTPC, 0, sizeof(Float_t) * 2);
   fPID = new AliPID;
-  fESDpid = new AliESDpid;
 }
 
 //___________________________________________________________________
@@ -72,10 +71,11 @@ AliHFEpidTPC::AliHFEpidTPC(const AliHFEpidTPC &ref) :
   AliHFEpidBase("")
   , fLineCrossingType(0)
   , fLineCrossingsEnabled(0)
+  , fUpperSigmaCut(NULL)
+  , fLowerSigmaCut(NULL)
   , fNsigmaTPC(2)
   , fRejectionEnabled(0)
   , fPID(NULL)
-  , fESDpid(NULL)
   , fQAList(NULL)
 {
   //
@@ -94,7 +94,6 @@ AliHFEpidTPC &AliHFEpidTPC::operator=(const AliHFEpidTPC &ref){
   } 
   return *this;
 }
-
 //___________________________________________________________________
 void AliHFEpidTPC::Copy(TObject &o) const{
   //
@@ -104,10 +103,11 @@ void AliHFEpidTPC::Copy(TObject &o) const{
   AliHFEpidTPC &target = dynamic_cast<AliHFEpidTPC &>(o);
 
   target.fLineCrossingsEnabled = fLineCrossingsEnabled;
+  target.fUpperSigmaCut = fUpperSigmaCut;
+  target.fLowerSigmaCut = fLowerSigmaCut;
   target.fNsigmaTPC = fNsigmaTPC;
   target.fRejectionEnabled = fRejectionEnabled;
   target.fPID = new AliPID(*fPID);
-  target.fESDpid = new AliESDpid(*fESDpid);
   target.fQAList = new AliHFEcollection(*fQAList);
   memcpy(target.fLineCrossingSigma, fLineCrossingSigma, sizeof(Double_t) * AliPID::kSPECIES);
   memcpy(target.fPAsigCut, fPAsigCut, sizeof(Float_t) * 2);
@@ -122,7 +122,6 @@ AliHFEpidTPC::~AliHFEpidTPC(){
   // Destructor
   //
   if(fPID) delete fPID;
-  if(fESDpid) delete fESDpid;
   if(fQAList){
     delete fQAList;
   }
@@ -163,11 +162,12 @@ Int_t AliHFEpidTPC::MakePIDesd(AliESDtrack *esdTrack, AliMCParticle *mctrack){
   //
   //  Doing TPC PID as explained in IsSelected for ESD tracks
   //
-  Float_t nsigma = fESDpid->NumberOfSigmasTPC(esdTrack, AliPID::kElectron);
-  if(IsQAon()){
-    FillTPChistograms(esdTrack, mctrack);
-    fQAList->Fill("fHistSigmaElectronAll",  esdTrack->GetInnerParam() ? esdTrack->GetInnerParam()->P() : esdTrack->P(), nsigma);
+  if(!fESDpid){
+    AliError("No ESD PID object available");
+    return kFALSE;
   }
+  Float_t nsigma = fESDpid->NumberOfSigmasTPC(esdTrack, AliPID::kElectron);
+  if(IsQAon()) FillTPChistograms(esdTrack, mctrack, kFALSE);
   // exclude crossing points:
   // Determine the bethe values for each particle species
   Bool_t isLineCrossing = kFALSE;
@@ -189,21 +189,21 @@ Int_t AliHFEpidTPC::MakePIDesd(AliESDtrack *esdTrack, AliMCParticle *mctrack){
     Int_t reject = Reject(esdTrack);
     if(reject != 0) return reject;
   }
-  // Check whether distance from the electron line is smaller than n-sigma
 
-  // Perform Asymmetric n-sigma cut if required, else perform symmetric TPC sigma cut
-  Float_t p = 0.;
+  // Check if we have an asymmetric sigma model set
   Int_t pdg = 0;
-  if(HasAsymmetricSigmaCut() && (p = esdTrack->P()) >= fPAsigCut[0] && p <= fPAsigCut[1]){ 
-    if(nsigma >= fNAsigmaTPC[0] && nsigma <= fNAsigmaTPC[1]) pdg = 11; 
-  } else {
-    if(TMath::Abs(nsigma) < fNsigmaTPC ) pdg = 11;
-  }
-  if(IsQAon() && pdg != 0){ 
-    fQAList->Fill("fHistTPCselected", esdTrack->GetInnerParam() ? esdTrack->GetInnerParam()->P() : esdTrack->P(), esdTrack->GetTPCsignal());
-    fQAList->Fill("fHistSigmaElectronSelected",  esdTrack->GetInnerParam() ? esdTrack->GetInnerParam()->P() : esdTrack->P(), nsigma);
+  if(fUpperSigmaCut || fLowerSigmaCut){
+    pdg = CutSigmaModel(esdTrack) ? 11 : 0;
+  } else { 
+    // Perform Asymmetric n-sigma cut if required, else perform symmetric TPC sigma cut
+    Float_t p = 0.;
+    if(HasAsymmetricSigmaCut() && (p = esdTrack->P()) >= fPAsigCut[0] && p <= fPAsigCut[1]){ 
+      if(nsigma >= fNAsigmaTPC[0] && nsigma <= fNAsigmaTPC[1]) pdg = 11; 
+    } else {
+      if(TMath::Abs(nsigma) < fNsigmaTPC ) pdg = 11;
+    }
   }
-
+  if(IsQAon() && pdg != 0) FillTPChistograms(esdTrack, mctrack, kTRUE);
   return pdg;
 }
 
@@ -213,6 +213,19 @@ Int_t AliHFEpidTPC::MakePIDaod(AliAODTrack * /*aodTrack*/, AliAODMCParticle * /*
   return 0;
 }
 
+//___________________________________________________________________
+Bool_t AliHFEpidTPC::CutSigmaModel(AliESDtrack *track){
+  //
+  // N SigmaCut using parametrization of the cuts
+  //
+  Bool_t isSelected = kTRUE;
+  Float_t nsigma = fESDpid->NumberOfSigmasTPC(track, AliPID::kElectron);
+  Double_t p =  track->GetInnerParam() ? track->GetInnerParam()->P() : track->P();
+  if(fUpperSigmaCut && nsigma > fUpperSigmaCut->Eval(p)) isSelected = kFALSE;
+  if(fLowerSigmaCut && nsigma < fLowerSigmaCut->Eval(p)) isSelected = kFALSE;
+  return isSelected;
+}
+
 //___________________________________________________________________
 Int_t AliHFEpidTPC::Reject(AliESDtrack *track){
   //
@@ -294,7 +307,7 @@ Double_t  AliHFEpidTPC::Suppression(const AliESDtrack *track, Int_t species)
 }
 
 //___________________________________________________________________
-void AliHFEpidTPC::FillTPChistograms(const AliESDtrack *track, const AliMCParticle *mctrack){
+void AliHFEpidTPC::FillTPChistograms(const AliESDtrack *track, const AliMCParticle *mctrack, Bool_t stepSelected){
   // 
   // Fill the QA histogtrams
   //
@@ -303,51 +316,48 @@ void AliHFEpidTPC::FillTPChistograms(const AliESDtrack *track, const AliMCPartic
  
   Double_t tpcSignal = track->GetTPCsignal();
   Double_t p = track->GetInnerParam() ? track->GetInnerParam()->P() : track->P();
-  if(HasMCData()){
+  Int_t species = -1;
+  THnSparse *hptr = NULL;
+  if(HasMCData() && mctrack){
     switch(TMath::Abs(mctrack->Particle()->GetPdgCode())){
-      case 11:    fQAList->Fill("fHistTPCelectron", p, tpcSignal);
-                       fQAList->Fill("fHistTPCprobEl", p, Likelihood(track, 0));
-                       //histograms with ratio of likelihood to be electron/to be other species (a check for quality of likelihood PID);
-                       fQAList->Fill("fHistTPCenhanceElPi", p, -Suppression(track, 2));
-                       fQAList->Fill("fHistTPCenhanceElMu", p, -Suppression(track, 1));
-                       fQAList->Fill("fHistTPCenhanceElKa", p, -Suppression(track, 3));
-                       fQAList->Fill("fHistTPCenhanceElPro", p, -Suppression(track, 4));
-                       //___________________________________________________________________________________________
-                       //Likelihoods for electrons to be other particle species
-                       fQAList->Fill("fHistTPCElprobPi", p, Likelihood(track, 2));
-                       fQAList->Fill("fHistTPCElprobMu", p, Likelihood(track, 1));
-                       fQAList->Fill("fHistTPCElprobKa", p, Likelihood(track, 3));
-                       fQAList->Fill("fHistTPCElprobPro", p, Likelihood(track, 4));
-                       break;
-           //___________________________________________________________________________________________
-      case 13:    fQAList->Fill("fHistTPCmuon", p, tpcSignal);
-                  //Likelihood of muon to be an electron
-                  fQAList->Fill("fHistTPCprobMu", p, Likelihood(track, 0));
-                  //ratio of likelihood for muon to be a muon/an electron -> indicator for quality of muon suppression
-                  //below functions are the same for other species
-                       fQAList->Fill("fHistTPCsuppressMu", p, Suppression(track, 1));
-                  break;
-      case 211:   fQAList->Fill("fHistTPCpion", p, tpcSignal);
-                       fQAList->Fill("fHistTPCprobPi", p, Likelihood(track, 0));
-                       fQAList->Fill("fHistTPCsuppressPi", p, Suppression(track, 2));
-                  break;
-      case 321:   fQAList->Fill("fHistTPCkaon", p, tpcSignal);
-                       fQAList->Fill("fHistTPCprobKa", p, Likelihood(track, 0));
-                       fQAList->Fill("fHistTPCsuppressKa", p, Suppression(track, 3));
-                  break;
-      case 2212:  fQAList->Fill("fHistTPCproton", p, tpcSignal);
-                       fQAList->Fill("fHistTPCprobPro", p, Likelihood(track, 0));
-                       fQAList->Fill("fHistTPCsuppressPro", p, Suppression(track, 4));
-                  break;
-      default:    fQAList->Fill("fHistTPCothers", p, tpcSignal);
-                       fQAList->Fill("fHistTPCprobOth", p, Likelihood(track, 0));
-
-                       break;
+      case 11:   
+        species = AliPID::kElectron;
+        if(!stepSelected){
+          Double_t contentElHist[4];
+          for(Int_t ispec = AliPID::kMuon; ispec < AliPID::kSPECIES; ispec++){
+            contentElHist[0] = ispec;
+            contentElHist[1] = p;
+            contentElHist[2] = -Suppression(track, ispec);
+            contentElHist[3] = Likelihood(track, ispec);
+            hptr = dynamic_cast<THnSparseF *>(fQAList->Get("fHistTPCel"));
+            hptr->Fill(contentElHist);
+          }
+        }
+             break;
+      case 13:    species = AliPID::kMuon; break;
+      case 211:   species = AliPID::kPion; break;
+      case 321:   species = AliPID::kKaon; break;
+      case 2212:  species = AliPID::kProton; break; 
+      default:    species = -1; break;
+    }
+    if(!stepSelected){
+      // Fill Probability Histogram
+      Double_t contentProb[3] = {species , p, Likelihood(track, 0)};
+      hptr = dynamic_cast<THnSparseF *>(fQAList->Get("fHistTPCprob"));
+      hptr->Fill(contentProb);
+      // Fill suppression Histogram
+      if(species > 0 && species < AliPID::kSPECIES){
+        Double_t contentSup[3] = {species, p, Suppression(track, species)};
+        hptr = dynamic_cast<THnSparseF *>(fQAList->Get("fHistTPCsuppression"));
+        hptr->Fill(contentSup);
+      }
     }
   }
-  //TPC signal and Likelihood to be electron for all tracks (independent of MC information)
-  fQAList->Fill("fHistTPCall", p, tpcSignal);
-  fQAList->Fill("kHistTPCprobAll", p, Likelihood(track, 0));
+  
+  // Fill signal histogram
+  Double_t contentSignal[5] = {species, p, tpcSignal, fESDpid->NumberOfSigmasTPC(track, AliPID::kElectron), stepSelected ? 1 : 0};
+  hptr = dynamic_cast<THnSparseF *>(fQAList->Get("fHistTPCsignal"));
+  hptr->Fill(contentSignal);
 }
 
 //___________________________________________________________________
@@ -355,50 +365,33 @@ void AliHFEpidTPC::AddQAhistograms(TList *qaList){
   //
   // Create QA histograms for TPC PID
   //
-  fQAList = new AliHFEcollection;
-
-  fQAList->CreateTH2F("fHistTPCelectron","TPC signal for Electrons", 200, 0, 20, 60, 0, 600); 
-  fQAList->CreateTH2F("fHistTPCmuon","TPC signal for Muons", 200, 0, 20, 60, 0, 600);
-  fQAList->CreateTH2F("fHistTPCpion","TPC signal for Pions", 200, 0, 20, 60, 0, 600);
-  fQAList->CreateTH2F("fHistTPCkaon","TPC signal for Kaons", 200, 0, 20, 60, 0, 600);
-  fQAList->CreateTH2F("fHistTPCproton","TPC signal for Protons", 200, 0, 20, 60, 0, 600);
-  fQAList->CreateTH2F("fHistTPCothers","TPC signal for other species", 200, 0, 20, 60, 0, 600);
-  fQAList->CreateTH2F("fHistTPCall","TPC signal for all species", 200, 0, 20, 60, 0, 600);
-  fQAList->CreateTH2F("fHistTPCselected","TPC signal for all selected particles", 200, 0, 20, 60, 0, 600);
-
-  fQAList->CreateTH2F("fHistTPCprobEl","TPC likelihood for electrons to be an electron vs. p", 200, 0.,20.,200,0.,1.);
-  fQAList->CreateTH2F("fHistTPCprobPi","TPC likelihood for pions to be an electron vs. p",  200, 0.,20.,200, 0.,1.);
-  fQAList->CreateTH2F("fHistTPCprobMu","TPC likelihood for muons to be an electron vs. p",  200, 0.,20.,200, 0.,1.);
-  fQAList->CreateTH2F("fHistTPCprobKa","TPC likelihood for kaons to be an electron vs. p",  200, 0.,20.,200, 0.,1.);
-  fQAList->CreateTH2F("fHistTPCprobPro","TPC likelihood for protons to be an electron vs. p",  200, 0.,20.,200, 0.,1.);
-  fQAList->CreateTH2F("fHistTPCprobOth","TPC likelihood for other particles to be an electron vs. p",  200, 0.,20.,200, 0.,1.);
-  fQAList->CreateTH2F("fHistTPCprobAll","TPC likelihood for all particles to be an electron vs. p",  200, 0.,20.,200, 0.,1.);
-
-  fQAList->CreateTH2F("fHistTPCsuppressPi","log10 of TPC Likelihood(pion)/Likelihood(elec) for pions vs. p", 200, 0.,20.,200,-1.,5.8);
-  fQAList->CreateTH2F("fHistTPCsuppressMu","log10 of TPC Likelihood(muon)/Likelihood(elec) for muons vs. p", 200, 0.,20.,200,-1.,5.8);
-  fQAList->CreateTH2F("fHistTPCsuppressKa","log10 of TPC Likelihood(kaon)/Likelihood(elec) for kaons vs. p", 200, 0.,20.,200,-1.,5.8);
-  fQAList->CreateTH2F("fHistTPCsuppressPro","log10 of TPC Likelihood(proton)/Likelihood(elec)for protons vs. p", 200, 0.,20.,200,-1.,5.8);
-
-  fQAList->CreateTH2F("fHistTPCenhanceElPi","log10 of TPC Likelihood(elec)/Likelihood(pion) for electrons vs. p", 200, 0.,20.,200,-1.,5.8);
-  fQAList->CreateTH2F("fHistTPCenhanceElMu","log10 of TPC Likelihood(elec)/Likelihood(muon) for electrons vs. p", 200, 0.,20.,200,-1.,5.8);
-  fQAList->CreateTH2F("fHistTPCenhanceElKa","log10 of TPC Likelihood(elec)/Likelihood(kaon) for electrons vs. p", 200, 0.,20.,200,-1.,5.8);
-  fQAList->CreateTH2F("fHistTPCenhanceElPro","log10 of TPC Likelihood(elec)/Likelihood(proton) for electrons vs. p", 200, 0.,20.,200,-1.,5.8);
-
-  fQAList->CreateTH2F("fHistTPCElprobPi","TPC likelihood for electrons to be a pion vs. p", 200, 0.,20.,200,0.,1.);
-  fQAList->CreateTH2F("fHistTPCElprobMu","TPC likelihood for electrons to be a muon vs. p", 200, 0.,20.,200,0.,1.);
-  fQAList->CreateTH2F("fHistTPCElprobKa","TPC likelihood for electrons to be a kaon vs. p", 200, 0.,20.,200,0.,1.);
-  fQAList->CreateTH2F("fHistTPCElprobPro","TPC likelihood for electrons to be a proton vs. p", 200, 0.,20.,200,0.,1.);
-
-  fQAList->CreateTH2F("fHistSigmaElectronAll", "TPC NSigma around the Electron Line", 200, 0, 20, 40, -10, 10);
-  fQAList->CreateTH2F("fHistSigmaElectronSelected", "TPC NSigma around the Electron Line for selected Tracks", 200, 0, 20, 40, -10, 10);
+  fQAList = new AliHFEcollection("fQAhistosTPC", "TPC QA histos");
+  
+  // First THnSparse we fill with the signal
+  const Int_t kNdimSignal  = 5;
+  Int_t nBins[kNdimSignal];
+  Double_t binMin[kNdimSignal], binMax[kNdimSignal];
+  nBins[0] = AliPID::kSPECIES + 1; binMin[0] = -1.; binMax[0] = AliPID::kSPECIES; // MC Species;
+  nBins[1] = 1000; binMin[1] = 0.; binMax[1] = 20.; 
+  nBins[2] = 6000; binMin[2] = 0.; binMax[2] = 600.;
+  nBins[3] = 1400; binMin[3] = -12.; binMax[3] = 12.;
+  nBins[4] = 2; binMin[4] = 0.; binMax[4] = nBins[4];  // Selected or not
+  fQAList->CreateTHnSparse("fHistTPCsignal", "TPC signal; Species; p [GeV/c]; TPC Signal [a.u.]; Normalized TPC distance to the electron Line [#sigma]; Selection Status", kNdimSignal, nBins, binMin, binMax);
+
+  const Int_t kNdimProbEl = 3;
+  nBins[2] = 200; binMin[2] = 0.; binMax[2] = 1.;
+  fQAList->CreateTHnSparse("fHistTPCprob", "TPC Likelihood to be an electron; Species; p [GeV/c]; TPC Likelihood [a.u.]", kNdimProbEl, nBins, binMin, binMax);
+
+  const Int_t kNdimSuppression = 3;
+  nBins[2] = 200; binMin[2] = -1.; binMax[2] = 5.8;  // log10 of TPC Likelihood(species)/Likelihood(elec) for species i neq electron
+  fQAList->CreateTHnSparse("fHistTPCsuppression", "TPC non-electron Suppression; Species; p [GeV/c]; Suppression [a.u.]", kNdimSuppression, nBins, binMin, binMax);
+
+  const Int_t kNdimEle = 4;
+  nBins[0] = AliPID::kSPECIES - 1; binMin[0] = 1.; binMax[0] = AliPID::kSPECIES;
+  nBins[2] = 100; binMin[2] = -1.; binMax[2] = 5.8;
+  nBins[3] = 200; binMin[3] = 0.; binMax[3] = 1.; 
+  fQAList->CreateTHnSparse("fHistTPCel", "TPC electron Histogram; Species; p [GeV/c]; Electron Enhancement:Electron Likelihood", kNdimEle, nBins, binMin, binMax);
 
   qaList->AddLast(fQAList->GetList());
 }
 
-//___________________________________________________________________
-void AliHFEpidTPC::SetBetheBlochParameters(Double_t *pars){
-  //
-  // Set non-default Bethe-Bloch Parameters
-  //
-  fESDpid->GetTPCResponse().SetBetheBlochParameters(pars[0], pars[1], pars[2], pars[3], pars[4]);
-}
index d0c3307b085940df264f555273a9650ae0af10a8..6fe69397c1384e4e580bc8b486759dcdda6005e1 100644 (file)
@@ -54,20 +54,24 @@ class AliHFEpidTPC : public AliHFEpidBase{
     Bool_t HasAsymmetricSigmaCut() const { return TestBit(kAsymmetricSigmaCut);}
     Bool_t HasParticleRejection() const { return TestBit(kRejection); }
     void SetTPCnSigma(Short_t nSigma) { fNsigmaTPC = nSigma; };
-    void SetBetheBlochParameters(Double_t *pars);
     inline void SetAsymmetricTPCsigmaCut(Float_t pmin, Float_t pmax, Float_t sigmaMin, Float_t sigmaMax);
     inline void SetRejectParticle(Int_t species, Float_t pmin, Float_t sigmaMin, Float_t pmax, Float_t sigmaMax);
 
+    void SetUpperSigmaCut(TF1 * const model) { fUpperSigmaCut = model; }
+    void SetLowerSigmaCut(TF1 * const model) { fLowerSigmaCut = model; }
+
   protected:
     void Copy(TObject &o) const;
     void AddQAhistograms(TList *qaList);
-    void FillTPChistograms(const AliESDtrack *track, const AliMCParticle *mctrack);
+    void FillTPChistograms(const AliESDtrack *track, const AliMCParticle *mctrack, Bool_t stepSelected = kFALSE);
     Int_t MakePIDaod(AliAODTrack *aodTrack, AliAODMCParticle *mcTrack);
     Int_t MakePIDesd(AliESDtrack *esdTrack, AliMCParticle *mcTrack);
     Int_t Reject(AliESDtrack *track);
     Double_t Likelihood(const AliESDtrack *track, Int_t species, Float_t rsig = 2.);
     Double_t Suppression(const AliESDtrack *track, Int_t species);
 
+    Bool_t CutSigmaModel(AliESDtrack *track);
+
   private:
     enum{
       kAsymmetricSigmaCut = BIT(20),
@@ -76,13 +80,14 @@ class AliHFEpidTPC : public AliHFEpidBase{
     Double_t fLineCrossingSigma[AliPID::kSPECIES];          // with of the exclusion point
     Int_t    fLineCrossingType;                             // 0 for no line crossing, otherwise AliPID of the particle crossing the electron dEdx band
     UChar_t fLineCrossingsEnabled;                          // Bitmap showing which line crossing is set
+    TF1 *fUpperSigmaCut;                                    // Upper Sigma Cut
+    TF1 *fLowerSigmaCut;                                    // Lower Sigma Cut
     Float_t fPAsigCut[2];                                   // Momentum region where to perform asymmetric sigma cut
     Float_t fNAsigmaTPC[2];                                 // Asymmetric TPC Sigma band        
     Short_t fNsigmaTPC;                                     // TPC sigma band
     Float_t fRejection[4*AliPID::kSPECIES];                 // All informations for Particle Rejection, order pmin, sigmin, pmax, sigmax
     UChar_t fRejectionEnabled;                              // Bitmap for enabled particle rejection
     AliPID *fPID;                                           //! PID Object
-    AliESDpid *fESDpid;                                     //! TPC PID object
     AliHFEcollection *fQAList;                              //! QA histograms
 
   ClassDef(AliHFEpidTPC, 1)   // TPC Electron ID class
index e2b0ae73ca9f91c9c67b478fa06906808e703c3a..663b5a945893dd58ec8265331e6b7e1b729323bf 100644 (file)
@@ -39,6 +39,18 @@ ClassImp(AliHFEpidTRD)
 
 const Double_t AliHFEpidTRD::fgkVerySmall = 1e-12;
 
+//___________________________________________________________________
+AliHFEpidTRD::AliHFEpidTRD() :
+    AliHFEpidBase()
+  , fPIDMethod(kNN)
+  , fContainer(0x0)
+{
+  //
+  // default  constructor
+  // 
+  memset(fThreshParams, 0, sizeof(Double_t) * kThreshParams);
+}
+
 //___________________________________________________________________
 AliHFEpidTRD::AliHFEpidTRD(const char* name) :
     AliHFEpidBase(name)
index 68afe68915e8b1eb9f3128e15287172d5409c224..60296b3481be37be4fff26f24a544740e3e2ed9e 100644 (file)
@@ -49,6 +49,7 @@ class AliHFEpidTRD : public AliHFEpidBase{
       kHistTRDSigV2 = 4,
       kHistOverallSpecies = 5
     };
+    AliHFEpidTRD();
     AliHFEpidTRD(const Char_t *name);
     AliHFEpidTRD(const AliHFEpidTRD &ref);
     AliHFEpidTRD& operator=(const AliHFEpidTRD &ref);
index 4892dc6ff434f439ca9470fadac4cd0c7304f665..1e30dafa3defbcb8565bdaf95dd17eaccf2e03f4 100644 (file)
@@ -337,16 +337,19 @@ TH1 *AliHFEpostAnalysis::CreateHistoPIDperformance(Int_t mode, Int_t charge){
   //
   // Make Histograms for PID performance plots
   //
+  fPIDperformance->GetAxis(4)->SetRange(0, fPIDperformance->GetAxis(4)->GetNbins()+1);
+  fPIDperformance->GetAxis(3)->SetRange(0, fPIDperformance->GetAxis(3)->GetNbins() + 1);
+
   TH1 *hNom = NULL, *hDenom = NULL;
   char hname[256], htitle[256], cname[256];
   Color_t mycolor = kBlack;
-  if(charge) fSignalToBackgroundMC->GetAxis(3)->SetRange(charge, charge);
+  if(charge) fPIDperformance->GetAxis(3)->SetRange(charge, charge);
   // Normalisation by all candidates - no restriction in axis 4 - only for mode == 1 
-  if(mode == 1) fPIDperformance->GetAxis(4)->SetRange(2,2);
+  if(mode == 1) fPIDperformance->GetAxis(4)->SetRange(2,3);
   hDenom = fPIDperformance->Projection(0);
   hDenom->Sumw2();
   hDenom->SetName("hDenom");
-  if(mode == 1) fPIDperformance->GetAxis(4)->SetRange(0, fPIDperformance->GetAxis(4)->GetLast() + 1);
+  if(mode == 1) fPIDperformance->GetAxis(4)->SetRange(0, fPIDperformance->GetAxis(4)->GetNbins() + 1);
   // Nominator need a restriction in the 4th axis
   switch(mode){
     case 0: // Electron purity
@@ -385,8 +388,8 @@ TH1 *AliHFEpostAnalysis::CreateHistoPIDperformance(Int_t mode, Int_t charge){
   hNom->Sumw2();
   hNom->SetName("hNom");
   // Reset axis
-  fPIDperformance->GetAxis(4)->SetRange(0, fPIDperformance->GetAxis(4)->GetLast() + 1);
-  if(charge) fSignalToBackgroundMC->GetAxis(3)->SetRange(0, fSignalToBackgroundMC->GetAxis(3)->GetLast() + 1);
+  fPIDperformance->GetAxis(4)->SetRange(0, fPIDperformance->GetAxis(4)->GetNbins()+1);
+  if(charge) fPIDperformance->GetAxis(3)->SetRange(0, fPIDperformance->GetAxis(3)->GetNbins() + 1);
 
   // Create Efficiency histogram
   TH1 *hEff = dynamic_cast<TH1D *>(hNom->Clone());
index be2ddd5d3ac634600d213172d748e3785111a372..d416cb1d8207d81a5c7b661738c1bf81d924a78c 100644 (file)
@@ -27,7 +27,7 @@
 
 #include "AliESDEvent.h"
 #include <AliESDtrack.h>
-#include <AliStack.h>
+#include <AliMCEvent.h>
 
 #include <AliLog.h>
 #include <AliKFParticle.h>
@@ -41,13 +41,17 @@ ClassImp(AliHFEpriVtx)
 //_______________________________________________________________________________________________
 AliHFEpriVtx::AliHFEpriVtx():
         fESD1(0x0)
-        ,fStack(0x0)
+        ,fMCEvent(0x0)
         ,fNtrackswoPid(0)
         ,fHNtrackswoPid(0x0)
         ,fNESDprimVtxContributor(0x0)
         ,fNESDprimVtxIndices(0x0)
         ,fDiffDCAvsPt(0x0)
         ,fDiffDCAvsNt(0x0)
+        ,fNsectrk2prim(0)
+        ,fPVxRe(-999.)
+        ,fPVyRe(-999.)
+        ,fPVzRe(-999.)
 { 
         //
         // Default constructor
@@ -61,13 +65,17 @@ AliHFEpriVtx::AliHFEpriVtx():
 AliHFEpriVtx::AliHFEpriVtx(const AliHFEpriVtx &p):
          TObject(p)
         ,fESD1(0x0)
-        ,fStack(0x0)
+        ,fMCEvent(0x0)
         ,fNtrackswoPid(p.fNtrackswoPid)
         ,fHNtrackswoPid(0x0)
         ,fNESDprimVtxContributor(0x0)
         ,fNESDprimVtxIndices(0x0)
         ,fDiffDCAvsPt(0x0)
         ,fDiffDCAvsNt(0x0)
+        ,fNsectrk2prim(p.fNsectrk2prim)
+        ,fPVxRe(p.fPVxRe)
+        ,fPVyRe(p.fPVyRe)
+        ,fPVzRe(p.fPVzRe)
 {
         //
         // Copy constructor
@@ -193,8 +201,10 @@ Int_t AliHFEpriVtx::GetMCPID(AliESDtrack *track)
         // get MC pid
         //
 
-        Int_t label = TMath::Abs(track->GetLabel());
-        TParticle* mcpart = fStack->Particle(label);
+       AliMCParticle *mctrack = NULL;
+       if(!(mctrack = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(TMath::Abs(track->GetLabel()))))) return 0; 
+       TParticle *mcpart = mctrack->Particle();
+
         if ( !mcpart ) return 0;
         Int_t pdgCode = mcpart->GetPdgCode();
 
@@ -226,8 +236,15 @@ void AliHFEpriVtx::CountPriVxtElecContributor(AliESDtrack *ESDelectron, Int_t so
         // get track id of our selected electron
         Int_t elecTrkID = ESDelectron->GetID();
 
-        Int_t label = TMath::Abs(ESDelectron->GetLabel());
-        TParticle* mcpart = fStack->Particle(label);
+       AliMCParticle *mctrack = NULL;
+       if(!(mctrack = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(TMath::Abs(ESDelectron->GetLabel()))))) return; 
+       TParticle *mcpart = mctrack->Particle();
+
+
+        if(!mcpart){
+          AliDebug(1, "no mc particle, return\n");
+          return;
+        }
 
         AliKFParticle::SetField(fESD1->GetMagneticField());
         AliKFParticle kfElectron(*ESDelectron,11);
@@ -284,7 +301,7 @@ void AliHFEpriVtx::FillNprimVtxContributor() const
 }
 
 //_______________________________________________________________________________________________
-Double_t AliHFEpriVtx::GetDistanceFromRecalVertexXY(AliESDtrack *ESDelectron) 
+Double_t AliHFEpriVtx::GetDistanceFromRecalVertexXY(AliESDtrack * const ESDelectron) 
 {
         //
         // return recalculated DCA after removing input track from the primary vertex
@@ -319,6 +336,80 @@ Double_t AliHFEpriVtx::GetDistanceFromRecalVertexXY(AliESDtrack *ESDelectron)
                         }
                 } 
         }  
-       return -1;
+             return -1;
+
+}
+
+void AliHFEpriVtx::RecalcPrimvtx(Int_t nkftrk, Int_t * const trkid, AliKFParticle * const kftrk)
+{
+        //
+        // recalculate primary vertex after removing the input track
+        //
+
+        const AliESDVertex *primvtx = fESD1->GetPrimaryVertex();
+
+        AliKFVertex kfESDprimary;
+        Int_t n = primvtx->GetNIndices();
+        fNsectrk2prim = 0;
+        fPVxRe = -999.;
+        fPVyRe = -999.;
+        fPVyRe = -999.;
+
+        if (n>0 && primvtx->GetStatus()){
+          kfESDprimary = AliKFVertex(*primvtx);
+          UShort_t *priIndex = primvtx->GetIndices();
+          for (Int_t j=0; j<nkftrk; j++){
+            for (Int_t i=0;i<n;i++){
+              Int_t idx = Int_t(priIndex[i]);
+              if (idx == trkid[j]){
+                kfESDprimary -= kftrk[j];
+                fNsectrk2prim++;
+              }
+            }
+          }
+        }
+
+        fPVxRe = kfESDprimary.GetX();
+        fPVyRe = kfESDprimary.GetY();
+        fPVzRe = kfESDprimary.GetZ();
+
+}
+
+
+//_______________________________________________________________________________________________
+void AliHFEpriVtx::RecalcPrimvtx(AliESDtrack * const ESDelectron)
+{
+        //
+        // recalculate primary vertex after removing the input track
+        //
+
+        // get track id of our selected electron
+        Int_t elecTrkID = ESDelectron->GetID();
+
+        AliKFParticle::SetField(fESD1->GetMagneticField());
+        AliKFParticle kfElectron(*ESDelectron,11);
+
+        const AliESDVertex *primvtx = fESD1->GetPrimaryVertex();
+
+        AliKFVertex kfESDprimary;
+        Int_t n = primvtx->GetNIndices();
+        fPVxRe = -999.;
+        fPVyRe = -999.;
+        fPVyRe = -999.;
+        
+        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 == elecTrkID){
+              kfESDprimary -= kfElectron;
+            }
+          }
+        }     
+        
+        fPVxRe = kfESDprimary.GetX();
+        fPVyRe = kfESDprimary.GetY();
+        fPVzRe = kfESDprimary.GetZ();
 
 }
index 380c839853df62c84b8a10cfb5fe93da978ee987..abbc3d2b3497b98b0ef63b7c6e7168ac96520766 100644 (file)
@@ -31,7 +31,8 @@ class TH2F;
 class TString;
 class AliESDEvent;
 class AliESDtrack;
-class AliStack;
+class AliMCEvent;
+class AliKFParticle;
 
 //________________________________________________________________
 class AliHFEpriVtx : public TObject {
@@ -45,20 +46,26 @@ class AliHFEpriVtx : public TObject {
                 void CreateHistograms(TString hnopt=""); // create histograms
                 void Init();
                 void SetEvent(AliESDEvent * const ESD){fESD1=ESD;}; // set ESD pointer
-                void SetStack(AliStack * const stack){fStack=stack;} // set stack pointer
+                void SetMCEvent(AliMCEvent * const mcEvent){fMCEvent=mcEvent;} // set stack pointer
                 void CountNtracks(Int_t sourcePart, Int_t recpid, Double_t recprob); // count number of tracks passed certain cut
                 void FillNtracks(); // fill counted number of tracks
                 void CountPriVxtElecContributor(AliESDtrack *ESDelectron, Int_t sourcePart, Int_t recpid, Double_t recprob); 
-                void GetNPriVxtContributor();
                 void FillNprimVtxContributor() const;
-               Double_t GetDistanceFromRecalVertexXY(AliESDtrack *ESDelectron); 
-
+                void RecalcPrimvtx(Int_t nkftrk, Int_t * const, AliKFParticle * const); //recalculate primary vertex after removing given tracks
+                void RecalcPrimvtx(AliESDtrack * const ESDelectron); //recalculate primary vertex after removing given track
+                void GetRecalcPrimvtx(Double_t privtx[3]) const {
+                    privtx[0]=fPVxRe; privtx[1]=fPVyRe; privtx[2]=fPVzRe;
+                }
+                void GetNPriVxtContributor();
+                Double_t GetDistanceFromRecalVertexXY(AliESDtrack * const ESDelectron);
+                           Int_t GetNsectrk2prim() const {return fNsectrk2prim;}; 
                 Int_t GetMCPID(AliESDtrack *track); // return mc pid
 
+
         private:
 
                 AliESDEvent* fESD1; // ESD event 
-                AliStack* fStack; // MC Stack
+                AliMCEvent* fMCEvent; // MC Event
 
                 TString fkSourceLabel[10]; // storing source label
 
@@ -108,6 +115,10 @@ class AliHFEpriVtx : public TObject {
                 TH2F *fDiffDCAvsPt; // histogram to fill DCA difference as a function of pT
                 TH2F *fDiffDCAvsNt; // histogram to fill DCA difference as a function of pT
 
+                Int_t fNsectrk2prim; // # of secvtx tracks contributing to primvtx calculation
+                Double_t fPVxRe;     // recalculated primary vertex x 
+                Double_t fPVyRe;     // recalculated primary vertex y 
+                Double_t fPVzRe;     // recalculated primary vertex z  
 
         ClassDef(AliHFEpriVtx,0);
 };
index 817303e3d623e24b831538b0bbd04fcc3da6d692..3c73c1a4feea2a2de34d82411db198c8fde5ca52 100644 (file)
@@ -25,6 +25,7 @@
 #include <TIterator.h>
 #include <TParticle.h>
 
+#include <AliESDVertex.h>
 #include <AliESDEvent.h>
 #include <AliAODEvent.h>
 #include <AliVTrack.h>
@@ -34,7 +35,7 @@
 #include <AliKFParticle.h>
 #include <AliKFVertex.h>
 #include <AliLog.h>
-#include <AliStack.h>
+#include <AliMCEvent.h>
 #include <AliAODMCParticle.h>
 #include "AliHFEpairs.h"
 #include "AliHFEsecVtxs.h"
@@ -47,7 +48,7 @@ AliHFEsecVtx::AliHFEsecVtx():
   fFilter(0x0)
   ,fESD1(0x0)
   ,fAOD1(0x0)
-  ,fStack(0x0)
+  ,fMCEvent(0x0)
   ,fUseMCPID(kFALSE)
   ,fkSourceLabel()
   ,fNparents(0)
@@ -56,17 +57,25 @@ AliHFEsecVtx::AliHFEsecVtx():
   ,fDcaCut()
   ,fNoOfHFEpairs(0)
   ,fNoOfHFEsecvtxs(0)
+  ,fArethereSecVtx(0)
   ,fHFEpairs(0x0)
   ,fHFEsecvtxs(0x0)
   ,fMCArray(0x0)
-  ,fPVx(0)
-  ,fPVy(0)
+  ,fPVx(-999)
+  ,fPVy(-999)
+  ,fPVx2(999)
+  ,fPVy2(-999)
   ,fCosPhi(-1)
   ,fSignedLxy(-1)
+  ,fSignedLxy2(-1)
   ,fKFchi2(-1)
   ,fInvmass(-1)
   ,fInvmassSigma(-1)
   ,fKFip(0)
+  ,fKFip2(0)
+  ,fNsectrk2prim(0)
+  ,fVtxchi2Tightcut(3.)
+  ,fVtxchi2Loosecut(5.)
   ,fPairQA(0x0)
   ,fSecvtxQA(0x0)
   ,fSecVtxList(0x0)
@@ -84,7 +93,7 @@ AliHFEsecVtx::AliHFEsecVtx(const AliHFEsecVtx &p):
   ,fFilter(0x0)
   ,fESD1(0x0)
   ,fAOD1(0x0)
-  ,fStack(0x0)
+  ,fMCEvent(0x0)
   ,fUseMCPID(p.fUseMCPID)
   ,fkSourceLabel()
   ,fNparents(p.fNparents)
@@ -93,17 +102,25 @@ AliHFEsecVtx::AliHFEsecVtx(const AliHFEsecVtx &p):
   ,fDcaCut()
   ,fNoOfHFEpairs(p.fNoOfHFEpairs)
   ,fNoOfHFEsecvtxs(p.fNoOfHFEsecvtxs)
+  ,fArethereSecVtx(p.fArethereSecVtx)
   ,fHFEpairs(0x0)
   ,fHFEsecvtxs(0x0)
   ,fMCArray(0x0)
   ,fPVx(p.fPVx)
   ,fPVy(p.fPVy)
+  ,fPVx2(p.fPVx2)
+  ,fPVy2(p.fPVy2)
   ,fCosPhi(p.fCosPhi)
   ,fSignedLxy(p.fSignedLxy)
+  ,fSignedLxy2(p.fSignedLxy2)
   ,fKFchi2(p.fKFchi2)
   ,fInvmass(p.fInvmass)
   ,fInvmassSigma(p.fInvmassSigma)
   ,fKFip(p.fKFip)
+  ,fKFip2(p.fKFip2)
+  ,fNsectrk2prim(p.fNsectrk2prim)
+  ,fVtxchi2Tightcut(p.fVtxchi2Tightcut)
+  ,fVtxchi2Loosecut(p.fVtxchi2Loosecut)
   ,fPairQA(0x0)
   ,fSecvtxQA(0x0)
   ,fSecVtxList(0x0)
@@ -185,6 +202,9 @@ void AliHFEsecVtx::Init()
 } 
 
 void AliHFEsecVtx::Process(AliVTrack *signalTrack){ 
+  //
+  // Run Process
+  //
   if(signalTrack->Pt() < 1.0) return;
   AliESDtrack *track = dynamic_cast<AliESDtrack *>(signalTrack);
   InitHFEpairs();
@@ -261,13 +281,13 @@ void AliHFEsecVtx::GetPrimaryCondition()
     AliKFVertex primVtxCopy(*(fESD1->GetPrimaryVertex()));
     if( primVtxCopy.GetNDF() <1 ) return;
     fPVx = primVtxCopy.GetX();
-    fPVx = primVtxCopy.GetY();
+    fPVy = primVtxCopy.GetY();
   }
   else if(fAOD1) {
     AliKFVertex primVtxCopy(*(fAOD1->GetPrimaryVertex()));
     if( primVtxCopy.GetNDF() <1 ) return;
     fPVx = primVtxCopy.GetX();
-    fPVx = primVtxCopy.GetY();
+    fPVy = primVtxCopy.GetY();
   }
 }
 
@@ -282,11 +302,15 @@ void AliHFEsecVtx::PairAnalysis(AliVTrack* track1, AliVTrack* track2, Int_t inde
   Float_t dca1[2]={-999.,-999.}, dca2[2]={-999.,-999.};
   Float_t cov1[3]={-999.,-999.,-999.}, cov2[3]={-999.,-999.,-999.};
 
+  Double_t dca1aod[2]={-999.,-999.}, dca2aod[2]={-999.,-999.};
+  Double_t cov1aod[3]={-999.,-999.,-999.}, cov2aod[3]={-999.,-999.,-999.};
+
   if (IsAODanalysis()){
+    const AliAODVertex *primVtx = fAOD1->GetPrimaryVertex();
     AliESDtrack esdTrk1(track1);
     AliESDtrack esdTrk2(track2);
-    esdTrk1.PropagateToDCA(fAOD1->GetPrimaryVertex(),0,10000,(Double_t*)dca1,(Double_t*)cov1);
-    esdTrk2.PropagateToDCA(fAOD1->GetPrimaryVertex(),0,10000,(Double_t*)dca2,(Double_t*)cov2);
+    esdTrk1.PropagateToDCA(primVtx,0.,10000.,dca1aod,cov1aod);
+    esdTrk2.PropagateToDCA(primVtx,0.,10000.,dca2aod,cov2aod);
   }
   else {
     ((AliESDtrack*)track1)->GetImpactParameters(dca1,cov1);
@@ -294,9 +318,9 @@ void AliHFEsecVtx::PairAnalysis(AliVTrack* track1, AliVTrack* track2, Int_t inde
   }
 
   // apply pt dependent dca cut on hadrons
-  for(int ibin=0; ibin<6; ibin++){
+  /*for(int ibin=0; ibin<6; ibin++){
     if((track2->Pt()>fPtRng[ibin] && track2->Pt()<fPtRng[ibin+1]) && TMath::Abs(dca2[0])<fDcaCut[ibin]) return;
-  }
+  }*/
 
   // get KF particle input pid
   Int_t pdg1 = GetPDG(track1);
@@ -310,10 +334,12 @@ void AliHFEsecVtx::PairAnalysis(AliVTrack* track1, AliVTrack* track2, Int_t inde
   // create KF particle of pair
   if(IsAODanalysis()) AliKFParticle::SetField(fAOD1->GetMagneticField());
   else AliKFParticle::SetField(fESD1->GetMagneticField()); 
-  AliKFParticle kfTrack1(*track1, pdg1);
-  AliKFParticle kfTrack2(*track2, pdg2);
 
-  AliKFParticle kfSecondary(kfTrack1,kfTrack2);
+  AliKFParticle kfTrack[2];
+  kfTrack[0] = AliKFParticle(*track1, pdg1);
+  kfTrack[1] = AliKFParticle(*track2, pdg2);
+  
+  AliKFParticle kfSecondary(kfTrack[0],kfTrack[1]);
 
   //secondary vertex point from kf particle
   Double_t kfx = kfSecondary.GetX();
@@ -325,6 +351,22 @@ void AliHFEsecVtx::PairAnalysis(AliVTrack* track1, AliVTrack* track2, Int_t inde
   Double_t kfpy = kfSecondary.GetPy();
   //Double_t kfpz = kfSecondary.GetPz();
 
+
+/* //directly use of ESD vertex 
+  const AliESDVertex *pvertex = fESD1->GetPrimaryVertex();
+  Double_t xyzVtx[3];
+  pvertex->GetXYZ(xyzVtx);
+
+  Double_t dx = kfx-xyzVtx[0];
+  Double_t dy = kfy-xyzVtx[1];*/
+
+  AliKFVertex primVtxCopy(*(fESD1->GetPrimaryVertex()));
+  if( primVtxCopy.GetNDF() <1 ) return;
+  fPVx = primVtxCopy.GetX();
+  fPVy = primVtxCopy.GetY();
+
+ // printf("esdx= %lf kfx= %lf esdy= %lf kfy= %lf\n",xyzVtx[0],fPVx,xyzVtx[1],fPVy);
+
   Double_t dx = kfx-fPVx;
   Double_t dy = kfy-fPVy;
 
@@ -339,9 +381,13 @@ void AliHFEsecVtx::PairAnalysis(AliVTrack* track1, AliVTrack* track2, Int_t inde
   if(kfSecondary.GetNDF()>0) kfchi2 = TMath::Sqrt(TMath::Abs(kfSecondary.GetChi2()/kfSecondary.GetNDF()));
 
   // opening angle between two particles in XY plane
-  Double_t phi = kfTrack1.GetAngleXY(kfTrack2);
+  Double_t phi = kfTrack[0].GetAngleXY(kfTrack[1]);
   Double_t cosphi = TMath::Cos(phi);
 
+  // DCA from primary to e-h KF particle (impact parameter of KF particle)
+  Double_t vtx[2]={fPVx, fPVy};
+  Double_t kfip = kfSecondary.GetDistanceFromVertexXY(vtx);
+
   // projection of kf vertex vector to the kf momentum direction 
   Double_t signedLxy=-999.;
   if((dx*kfpx+dy*kfpy)>0) signedLxy = TMath::Sqrt(dx*dx+dy*dy);  
@@ -350,9 +396,24 @@ void AliHFEsecVtx::PairAnalysis(AliVTrack* track1, AliVTrack* track2, Int_t inde
   //Double_t psqr = kfpx*kfpx+kfpy*kfpy;
   //if(psqr>0) signedLxy=(dx*kfpx+dy*kfpy)/TMath::Sqrt(psqr);  
 
-  // DCA from primary to e-h KF particle (impact parameter of KF particle)
-  Double_t vtx[2]={fPVx, fPVy}; 
-  Double_t kfip = kfSecondary.GetDistanceFromVertexXY(vtx);
+  //recalculating primary vertex after removing secvtx tracks --------------------------
+  Int_t trkid[2];
+  trkid[0] = track1->GetID();
+  trkid[1] = track2->GetID();
+
+  RecalcPrimvtx(2, trkid, kfTrack);
+  Double_t dx2 = kfx-fPVx2;
+  Double_t dy2 = kfy-fPVy2;
+
+  // IP of sec particle recalculated based on recalculated primary vertex
+  Double_t vtx2[2]={fPVx2, fPVy2};
+  Double_t kfip2 = kfSecondary.GetDistanceFromVertexXY(vtx2);
+  // signed Lxy recalculated based on recalculated primary vertex
+  Double_t signedLxy2=-999.;
+  if((dx2*kfpx+dy2*kfpy)>0) signedLxy2 = TMath::Sqrt(dx2*dx2+dy2*dy2);
+  if((dx2*kfpx+dy2*kfpy)<0) signedLxy2 = -1*TMath::Sqrt(dx2*dx2+dy2*dy2);
+  //------------------------------------------------------------------------------------
+
 
   Int_t paircode = -1;
   if (HasMCData()) paircode = GetPairCode(track1,track2); 
@@ -364,7 +425,9 @@ void AliHFEsecVtx::PairAnalysis(AliVTrack* track1, AliVTrack* track2, Int_t inde
   hfepair.SetOpenangle(phi);
   hfepair.SetCosOpenangle(cosphi);
   hfepair.SetSignedLxy(signedLxy);
+  hfepair.SetSignedLxy2(signedLxy2);
   hfepair.SetKFIP(kfip);
+  hfepair.SetKFIP2(kfip2);
   hfepair.SetPairCode(paircode);
   AddHFEpairToArray(&hfepair);
   fNoOfHFEpairs++; 
@@ -374,17 +437,18 @@ void AliHFEsecVtx::PairAnalysis(AliVTrack* track1, AliVTrack* track2, Int_t inde
   dataE[0]=invmass;
   dataE[1]=kfchi2;
   dataE[2]=phi;
-  dataE[3]=signedLxy;
-  dataE[4]=kfip;
+  dataE[3]=signedLxy2;
+  dataE[4]=kfip2;
   dataE[5]=paircode;
-  /*
-  dataE[6]=TMath::Abs(dca1[0]);
-  dataE[7]=TMath::Abs(dca2[0]);
   //if(cov1[0]>0) dataE[6]=Double_t(dca1[0]/cov1[0]);
   //if(cov2[0]>0) dataE[7]=Double_t(dca2[0]/cov2[0]);
-  dataE[8]=track1->Pt();
-  dataE[9]=track2->Pt();
-  */
+  //dataE[6]=track1->Pt();
+  //dataE[7]=track2->Pt();
+  //dataE[6]=dca1[0]; //mjtmp
+  //dataE[7]=dca2[0]; //mjtmp
+  //dataE[8]=TMath::Abs(dca1[0]);
+  //dataE[9]=TMath::Abs(dca2[0]);
+
   fPairQA->Fill(dataE);
 
 }
@@ -408,9 +472,14 @@ void AliHFEsecVtx::FindSECVTXCandid(AliVTrack *track)
   //
 
   AliVTrack *htrack[20];
-  Int_t htracklabel[20];
-  Double_t vtxchi2cut=3.; // testing cut 
-  Double_t dataE[6]={-999.,-999.,-999.,-999.,-1.,0};  
+  //Int_t htracklabel[20];
+  //Int_t paircode[20];
+  //Double_t vtxchi2[20]; 
+  //Double_t dataE[7]={-999.,-999.,-999.,-999.,-1.,0,0};  
+
+  fVtxchi2Tightcut=3.; // tight cut for pair
+  fVtxchi2Loosecut=5.; // loose cut for secvtx 
+
   if (HFEpairs()->GetEntriesFast()>20){
     AliDebug(3, "number of paired hadron is over maximum(20)");
     return; 
@@ -421,68 +490,280 @@ void AliHFEsecVtx::FindSECVTXCandid(AliVTrack *track)
   if (IsAODanalysis()){
     for (int ip=0; ip<HFEpairs()->GetEntriesFast(); ip++){
        pair = (AliHFEpairs*) (HFEpairs()->UncheckedAt(ip));
-       htracklabel[ip] = pair->GetTrkLabel();
+       //htracklabel[ip] = pair->GetTrkLabel();
        htrack[ip] = fAOD1->GetTrack(pair->GetTrkLabel());
+       //if(pair->GetPairCode()==2 || pair->GetPairCode()==3) paircode[ip]=1;
+       //else paircode[ip]=0;
+       //vtxchi2[ip] = pair->GetKFChi2();
     }
   }
   else{
     for (int ip=0; ip<HFEpairs()->GetEntriesFast(); ip++){
        pair = (AliHFEpairs*) (HFEpairs()->UncheckedAt(ip));
-       htracklabel[ip] = pair->GetTrkLabel();
+       //htracklabel[ip] = pair->GetTrkLabel();
        htrack[ip] = fESD1->GetTrack(pair->GetTrkLabel());
+       //if(pair->GetPairCode()==2 || pair->GetPairCode()==3) paircode[ip]=1;
+       //else paircode[ip]=0;
+       //vtxchi2[ip] = pair->GetKFChi2();
     }
   }
-  // in case there is only one paired track with the electron, put pair characteristics into secvtx container
-  // for the moment, I only apply pair vertex chi2 cut
-  if (HFEpairs()->GetEntriesFast() == 1){
-    if (pair->GetKFChi2()<vtxchi2cut) { // you can also put single track cut
-      AliHFEsecVtxs hfesecvtx;
-      hfesecvtx.SetTrkLabel1(pair->GetTrkLabel());
-      hfesecvtx.SetTrkLabel2(-999);
-      hfesecvtx.SetInvmass(pair->GetInvmass());
-      hfesecvtx.SetKFChi2(pair->GetKFChi2());
-      hfesecvtx.SetSignedLxy(pair->GetSignedLxy());
-      hfesecvtx.SetKFIP(pair->GetKFIP());
-      AddHFEsecvtxToArray(&hfesecvtx);
-      fNoOfHFEsecvtxs++; 
-
-      dataE[0]=pair->GetInvmass();
-      dataE[1]=pair->GetKFChi2();
-      dataE[2]=pair->GetSignedLxy();
-      dataE[3]=pair->GetKFIP();
-      if(HasMCData()) dataE[4]=GetElectronSource(TMath::Abs(track->GetLabel()));
-      dataE[5]=2;
-      fSecvtxQA->Fill(dataE);
+
+  Int_t nPairs = HFEpairs()->GetEntriesFast(); 
+
+
+  // 1 electron candidate + 1 track 
+  if (nPairs == 1){
+    if (pair->GetKFChi2() < fVtxchi2Tightcut) { // you can also put single track cut -> here you apply very tight cut for the pair
+      Fill2TrkSECVTX(track, pair);
     }
     return;
   }
+  //--------------------------------------------------------------
+
+  // 1 electron candidate + 2 tracks 
+  if (nPairs == 2){
+    CalcSECVTXProperty(track, htrack[0], htrack[1]); // calculate secondary vertex property
+
+    if (fKFchi2 < fVtxchi2Loosecut) { // -> here you apply rather loose cut
+      Fill3TrkSECVTX(track, 0, 1);
+    }
+    else{ // if doesn't pass the sec vtx chi2 cut
+      for(int jp=0; jp<2; jp++){
+         pair = (AliHFEpairs*) (HFEpairs()->UncheckedAt(jp));
+         if (pair->GetKFChi2() < fVtxchi2Tightcut){
+           Fill2TrkSECVTX(track, pair);
+         } 
+      }  
+    }
+    return;
+  }
+  //--------------------------------------------------------------
+
+  // 1 electron candidate + 3 tracks 
+  if (nPairs == 3){
+    CalcSECVTXProperty(track, htrack[0], htrack[1], htrack[2]); // calculate secondary vertex property
 
-  // in case there are multiple paired track with the electron, calculate secvtx characteristics
-  // put the secvtx characteristics into container if it passes cuts
-  for (int i=0; i<HFEpairs()->GetEntriesFast()-1; i++){
-     for (int j=i+1; j<HFEpairs()->GetEntriesFast(); j++){
-        CalcSECVTXProperty(track, htrack[i], htrack[j]);
-        if (fKFchi2<vtxchi2cut) {
-          AliHFEsecVtxs hfesecvtx;
-          hfesecvtx.SetTrkLabel1(htracklabel[i]);
-          hfesecvtx.SetTrkLabel2(htracklabel[j]);
-          hfesecvtx.SetKFChi2(fKFchi2);
-          hfesecvtx.SetInvmass(fInvmass);
-          hfesecvtx.SetSignedLxy(fSignedLxy);
-          hfesecvtx.SetKFIP(fKFip);
-          AddHFEsecvtxToArray(&hfesecvtx);
-          fNoOfHFEsecvtxs++; 
-
-          dataE[0]=fInvmass;
-          dataE[1]=fKFchi2;
-          dataE[2]=fSignedLxy;
-          dataE[3]=fKFip;
-          if(HasMCData()) dataE[4]=GetElectronSource(TMath::Abs(track->GetLabel()));
-          dataE[5]=3;
-          fSecvtxQA->Fill(dataE);
+    if (fKFchi2 < fVtxchi2Loosecut) {
+      Fill4TrkSECVTX(track, 0, 1, 2);
+    }
+    else {
+      fArethereSecVtx=0;
+      for (int i=0; i<nPairs-1; i++){
+         for (int j=i+1; j<nPairs; j++){
+            CalcSECVTXProperty(track, htrack[i], htrack[j]);
+            if (fKFchi2 < fVtxchi2Loosecut) {
+              fArethereSecVtx++;
+              Fill3TrkSECVTX(track, i, j);
+            }
+         } 
+      }
+      if(!fArethereSecVtx){ 
+        for(int jp=0; jp<nPairs; jp++){
+           pair = (AliHFEpairs*) (HFEpairs()->UncheckedAt(jp));
+           if (pair->GetKFChi2() < fVtxchi2Tightcut){
+             Fill2TrkSECVTX(track, pair);
+           }
+        }  
+      }
+    }
+    return;
+  }
+  //--------------------------------------------------------------
+
+  // 1 electron candidate + more than 3 tracks 
+  if (nPairs > 3){
+    fArethereSecVtx=0;
+    for (int ih1=0; ih1<nPairs-2; ih1++){
+      for (int ih2=ih1+1; ih2<nPairs-1; ih2++){
+        for (int ih3=ih2+1; ih3<nPairs; ih3++){
+          CalcSECVTXProperty(track, htrack[ih1], htrack[ih2], htrack[ih3]); // calculate secondary vertex property
+          if (fKFchi2 < fVtxchi2Loosecut) {
+            fArethereSecVtx++;
+            Fill4TrkSECVTX(track, ih1, ih2, ih3);
+          }
         }
-     }
+      }
+    }
+    if (!fArethereSecVtx){
+      fArethereSecVtx=0;
+      for (int i=0; i<nPairs-1; i++){
+        for (int j=i+1; j<nPairs; j++){
+          CalcSECVTXProperty(track, htrack[i], htrack[j]);
+          if (fKFchi2 < fVtxchi2Loosecut) {
+            fArethereSecVtx++;
+            Fill3TrkSECVTX(track, i, j);
+          }
+        }
+      }
+    }
+    if (!fArethereSecVtx){
+      for(int jp=0; jp<nPairs; jp++){
+        pair = (AliHFEpairs*) (HFEpairs()->UncheckedAt(jp));
+        if (pair->GetKFChi2() < fVtxchi2Tightcut){
+          Fill2TrkSECVTX(track, pair);
+        }
+      }
+    }
+    return;
+  }
+  //--------------------------------------------------------------
+
+}
+
+//_______________________________________________________________________________________________
+void AliHFEsecVtx::Fill4TrkSECVTX(AliVTrack* track, Int_t ipair, Int_t jpair, Int_t kpair)
+{
+  //
+  // fill 3 tracks' secondary vertex properties
+  //
+
+  Double_t dataE[9]={-999.,-999.,-999.,-999.,-1.,0,0,-999.,-999.};
+
+  Int_t paircode1 = 0, paircode2 = 0, paircode3 = 0;
+  Int_t htracklabel1 = 0, htracklabel2= 0;
+
+  if (HasMCData()){
+    AliHFEpairs *pair1=0x0;
+    AliHFEpairs *pair2=0x0;
+    AliHFEpairs *pair3=0x0;
+    pair1 = (AliHFEpairs*) (HFEpairs()->UncheckedAt(ipair));
+    pair2 = (AliHFEpairs*) (HFEpairs()->UncheckedAt(jpair));
+    pair3 = (AliHFEpairs*) (HFEpairs()->UncheckedAt(kpair));
+
+    htracklabel1 = pair1->GetTrkLabel();
+    htracklabel2 = pair2->GetTrkLabel();
+
+    if (pair1->GetPairCode()==2 || pair1->GetPairCode()==3) paircode1=1;
+    else paircode1=0;
+    if (pair2->GetPairCode()==2 || pair2->GetPairCode()==3) paircode2=1;
+    else paircode2=0;
+    if (pair3->GetPairCode()==2 || pair3->GetPairCode()==3) paircode3=1;
+    else paircode3=0;
   }
+
+  AliHFEsecVtxs hfesecvtx;
+  hfesecvtx.SetTrkLabel1(htracklabel1); // mj: not much meaningful for the moment
+  hfesecvtx.SetTrkLabel2(htracklabel2); // mj: not much meaningful for the moment
+  if(HasMCData()) hfesecvtx.SetMCCode(GetElectronSource(TMath::Abs(track->GetLabel())));
+  hfesecvtx.SetKFChi2(fKFchi2);
+  hfesecvtx.SetInvmass(fInvmass);
+  hfesecvtx.SetSignedLxy(fSignedLxy);
+  hfesecvtx.SetSignedLxy2(fSignedLxy2);
+  hfesecvtx.SetKFIP(fKFip);
+  hfesecvtx.SetKFIP2(fKFip2);
+  AddHFEsecvtxToArray(&hfesecvtx);
+  fNoOfHFEsecvtxs++;
+
+  dataE[0]=fInvmass;
+  dataE[1]=fKFchi2;
+  dataE[2]=fSignedLxy;
+  dataE[3]=fKFip;
+  if(HasMCData()) dataE[4]=GetElectronSource(TMath::Abs(track->GetLabel()));
+  dataE[5]=4; //# of associated tracks
+  if(paircode1 & paircode2 & paircode3) dataE[6]=1;
+  else if(!paircode1 & !paircode2 & !paircode3) dataE[6]=0;
+  else dataE[6]=3;
+  dataE[7]=fSignedLxy2;
+  dataE[8]=track->Pt();
+  fSecvtxQA->Fill(dataE);
+}
+
+//_______________________________________________________________________________________________
+void AliHFEsecVtx::Fill3TrkSECVTX(AliVTrack* track, Int_t ipair, Int_t jpair)
+{
+  //
+  // fill 3 tracks' secondary vertex properties
+  //
+
+  Double_t dataE[9]={-999.,-999.,-999.,-999.,-1.,0,0,-999.,-999.};
+
+  Int_t paircode1 = 0, paircode2 = 0;
+  Int_t htracklabel1 = 0, htracklabel2 = 0; 
+
+  if (HasMCData()){
+    AliHFEpairs *pair1=0x0;
+    AliHFEpairs *pair2=0x0;
+    pair1 = (AliHFEpairs*) (HFEpairs()->UncheckedAt(ipair));
+    pair2 = (AliHFEpairs*) (HFEpairs()->UncheckedAt(jpair));
+
+    htracklabel1 = pair1->GetTrkLabel();
+    htracklabel2 = pair2->GetTrkLabel();
+
+    if (pair1->GetPairCode()==2 || pair1->GetPairCode()==3) paircode1=1;
+    else paircode1=0;
+    if (pair2->GetPairCode()==2 || pair2->GetPairCode()==3) paircode2=1;
+    else paircode2=0;
+  }
+
+  // fill secondary vertex container
+  AliHFEsecVtxs hfesecvtx;
+  hfesecvtx.SetTrkLabel1(htracklabel1);
+  hfesecvtx.SetTrkLabel2(htracklabel2);
+  if(HasMCData()) hfesecvtx.SetMCCode(GetElectronSource(TMath::Abs(track->GetLabel())));
+  hfesecvtx.SetKFChi2(fKFchi2);
+  hfesecvtx.SetInvmass(fInvmass);
+  hfesecvtx.SetSignedLxy(fSignedLxy);
+  hfesecvtx.SetSignedLxy2(fSignedLxy2);
+  hfesecvtx.SetKFIP(fKFip);
+  hfesecvtx.SetKFIP2(fKFip2);
+  AddHFEsecvtxToArray(&hfesecvtx);
+  fNoOfHFEsecvtxs++;
+
+  // fill debugging THnSparse 
+  dataE[0]=fInvmass;
+  dataE[1]=fKFchi2;
+  dataE[2]=fSignedLxy;
+  dataE[3]=fKFip;
+  if(HasMCData()) dataE[4]=GetElectronSource(TMath::Abs(track->GetLabel()));
+  dataE[5]=3;
+  if(paircode1 & paircode2) dataE[6]=1;
+  else if(!paircode1 & !paircode2) dataE[6]=0;
+  else dataE[6]=3;
+  dataE[7]=fSignedLxy2;
+  dataE[8]=track->Pt();
+  fSecvtxQA->Fill(dataE);
+
+}
+
+//_______________________________________________________________________________________________
+void AliHFEsecVtx::Fill2TrkSECVTX(AliVTrack* track, AliHFEpairs *pair)
+{
+  //
+  // fill 2 tracks' secondary vertex properties
+  //
+
+  Double_t dataE[9]={-999.,-999.,-999.,-999.,-1.,0,0,-999.,-999.};
+
+  Int_t paircode;
+  if (pair->GetPairCode()==2 || pair->GetPairCode()==3) paircode=1;
+  else paircode=0;
+
+  // fill secondary vertex container
+  AliHFEsecVtxs hfesecvtx;
+  hfesecvtx.SetTrkLabel1(pair->GetTrkLabel());
+  hfesecvtx.SetTrkLabel2(-999);
+  if(HasMCData()) hfesecvtx.SetMCCode(GetElectronSource(TMath::Abs(track->GetLabel())));
+  hfesecvtx.SetInvmass(pair->GetInvmass());
+  hfesecvtx.SetKFChi2(pair->GetKFChi2());
+  hfesecvtx.SetSignedLxy(pair->GetSignedLxy());
+  hfesecvtx.SetSignedLxy2(pair->GetSignedLxy2());
+  hfesecvtx.SetKFIP(pair->GetKFIP());
+  hfesecvtx.SetKFIP2(pair->GetKFIP2());
+  AddHFEsecvtxToArray(&hfesecvtx);
+  fNoOfHFEsecvtxs++;
+
+  // fill debugging THnSparse 
+  dataE[0]=pair->GetInvmass();
+  dataE[1]=pair->GetKFChi2();
+  dataE[2]=pair->GetSignedLxy();
+  dataE[3]=pair->GetKFIP();
+  if (HasMCData()) dataE[4]=GetElectronSource(TMath::Abs(track->GetLabel()));
+  dataE[5]=2;              //# of associated tracks
+  dataE[6]=paircode;
+  dataE[7]=pair->GetSignedLxy2();
+  dataE[8]=track->Pt();
+  fSecvtxQA->Fill(dataE);
+
 }
 
 //_______________________________________________________________________________________________
@@ -505,11 +786,13 @@ void AliHFEsecVtx::CalcSECVTXProperty(AliVTrack* track1, AliVTrack* track2, AliV
   // create KF particle of pair
   if(IsAODanalysis()) AliKFParticle::SetField(fAOD1->GetMagneticField());
   else AliKFParticle::SetField(fESD1->GetMagneticField());
-  AliKFParticle kfTrack1(*track1, pdg1);
-  AliKFParticle kfTrack2(*track2, pdg2);
-  AliKFParticle kfTrack3(*track3, pdg3);
+  AliKFParticle kfTrack[3];
+  kfTrack[0] = AliKFParticle(*track1, pdg1);
+  kfTrack[1] = AliKFParticle(*track2, pdg2);
+  kfTrack[2] = AliKFParticle(*track3, pdg3);
 
-  AliKFParticle kfSecondary(kfTrack1,kfTrack2,kfTrack3);
+  AliKFParticle kfSecondary(kfTrack[0],kfTrack[1],kfTrack[2]);
+  //AliKFParticle kfSecondary(kfTrack1,kfTrack2,kfTrack3);
         
   //secondary vertex point from kf particle
   Double_t kfx = kfSecondary.GetX();
@@ -540,6 +823,137 @@ void AliHFEsecVtx::CalcSECVTXProperty(AliVTrack* track1, AliVTrack* track2, AliV
   //[the other way to think about] - projection of kf vertex vector to the kf momentum direction
   //Double_t psqr = kfpx*kfpx+kfpy*kfpy;
   //if(psqr>0) fSignedLxy=(dx*kfpx+dy*kfpy)/TMath::Sqrt(psqr);  
+
+
+  //recalculating primary vertex after removing secvtx tracks --------------------------
+  Int_t trkid[3];
+  trkid[0] = track1->GetID();
+  trkid[1] = track2->GetID();
+  trkid[2] = track3->GetID();
+
+  RecalcPrimvtx(3, trkid, kfTrack);
+  Double_t dx2 = kfx-fPVx2;
+  Double_t dy2 = kfy-fPVy2;
+
+  // IP of sec particle recalculated based on recalculated primary vertex
+  Double_t vtx2[2]={fPVx2, fPVy2};
+  fKFip2 = kfSecondary.GetDistanceFromVertexXY(vtx2);
+  // signed Lxy recalculated based on recalculated primary vertex
+  if((dx2*kfpx+dy2*kfpy)>0) fSignedLxy2= TMath::Sqrt(dx2*dx2+dy2*dy2);
+  if((dx2*kfpx+dy2*kfpy)<0) fSignedLxy2= -1*TMath::Sqrt(dx2*dx2+dy2*dy2);
+  //------------------------------------------------------------------------------------
+  
+}
+
+//_______________________________________________________________________________________________
+void AliHFEsecVtx::CalcSECVTXProperty(AliVTrack* track1, AliVTrack* track2, AliVTrack* track3, AliVTrack* track4)
+{
+  //
+  // calculate secondary vertex properties
+  //
+
+  // get KF particle input pid
+  Int_t pdg1 = GetPDG(track1);
+  Int_t pdg2 = GetPDG(track2);
+  Int_t pdg3 = GetPDG(track3);
+  Int_t pdg4 = GetPDG(track4);
+
+  if(pdg1==-1 || pdg2==-1 || pdg3==-1 || pdg4==-1) {
+    //printf("out if considered pid range \n");
+    return;
+  }
+
+  // create KF particle of pair
+  if(IsAODanalysis()) AliKFParticle::SetField(fAOD1->GetMagneticField());
+  else AliKFParticle::SetField(fESD1->GetMagneticField());
+
+  AliKFParticle kfTrack[4];
+  kfTrack[0] = AliKFParticle(*track1, pdg1);
+  kfTrack[1] = AliKFParticle(*track2, pdg2);
+  kfTrack[2] = AliKFParticle(*track3, pdg3);
+  kfTrack[3] = AliKFParticle(*track4, pdg4);
+
+  AliKFParticle kfSecondary(kfTrack[0],kfTrack[1],kfTrack[2],kfTrack[3]);
+
+  //secondary vertex point from kf particle
+  Double_t kfx = kfSecondary.GetX();
+  Double_t kfy = kfSecondary.GetY();
+  //Double_t kfz = kfSecondary.GetZ();
+
+  //momentum at the decay point from kf particle
+  Double_t kfpx = kfSecondary.GetPx();
+  Double_t kfpy = kfSecondary.GetPy();
+  //Double_t kfpz = kfSecondary.GetPz();
+
+  Double_t dx = kfx-fPVx;
+  Double_t dy = kfy-fPVy;
+
+  // discriminating variables ----------------------------------------------------------
+
+  if(kfSecondary.GetNDF()>0) fKFchi2 = TMath::Sqrt(TMath::Abs(kfSecondary.GetChi2()/kfSecondary.GetNDF())); 
+
+  // invariant mass of the KF particle
+  kfSecondary.GetMass(fInvmass,fInvmassSigma);
+
+  // DCA from primary to e-h KF particle (impact parameter of KF particle)
+  Double_t vtx[2]={fPVx, fPVy};
+  fKFip = kfSecondary.GetDistanceFromVertexXY(vtx);
+
+  if((dx*kfpx+dy*kfpy)>0) fSignedLxy= TMath::Sqrt(dx*dx+dy*dy);
+  if((dx*kfpx+dy*kfpy)<0) fSignedLxy= -1*TMath::Sqrt(dx*dx+dy*dy);
+  //[the other way to think about] - projection of kf vertex vector to the kf momentum direction
+  //Double_t psqr = kfpx*kfpx+kfpy*kfpy;
+  //if(psqr>0) fSignedLxy=(dx*kfpx+dy*kfpy)/TMath::Sqrt(psqr);  
+
+  //recalculating primary vertex after removing secvtx tracks --------------------------
+  Int_t trkid[4];
+  trkid[0] = track1->GetID();
+  trkid[1] = track2->GetID();
+  trkid[2] = track3->GetID();
+  trkid[3] = track4->GetID();
+
+  RecalcPrimvtx(4, trkid, kfTrack);
+  Double_t dx2 = kfx-fPVx2;
+  Double_t dy2 = kfy-fPVy2;
+
+  // IP of sec particle recalculated based on recalculated primary vertex
+  Double_t vtx2[2]={fPVx2, fPVy2};
+  fKFip2 = kfSecondary.GetDistanceFromVertexXY(vtx2);
+  // signed Lxy recalculated based on recalculated primary vertex
+  if((dx2*kfpx+dy2*kfpy)>0) fSignedLxy2= TMath::Sqrt(dx2*dx2+dy2*dy2);
+  if((dx2*kfpx+dy2*kfpy)<0) fSignedLxy2= -1*TMath::Sqrt(dx2*dx2+dy2*dy2);
+  //------------------------------------------------------------------------------------
+
+}
+
+//_______________________________________________________________________________________________
+void AliHFEsecVtx::RecalcPrimvtx(Int_t nkftrk, Int_t * const trkid, AliKFParticle * const kftrk){
+
+  const AliESDVertex *primvtx = fESD1->GetPrimaryVertex();
+
+  AliKFVertex kfESDprimary;
+  Int_t n = primvtx->GetNIndices();
+  fNsectrk2prim = 0;
+  fPVx2 = -999.;
+  fPVy2 = -999.;
+
+  if (n>0 && primvtx->GetStatus()){
+    kfESDprimary = AliKFVertex(*primvtx);
+    UShort_t *priIndex = primvtx->GetIndices();
+    for(Int_t j=0; j<nkftrk; j++){
+      for (Int_t i=0;i<n;i++){
+        Int_t idx = Int_t(priIndex[i]);
+        if (idx == trkid[j]){
+          kfESDprimary -= kftrk[j];
+          fNsectrk2prim++;
+        }
+      }
+    }
+  }
+
+  fPVx2 = kfESDprimary.GetX();
+  fPVy2 = kfESDprimary.GetY();
+
 }
 
 //_______________________________________________________________________________________________
@@ -549,8 +963,10 @@ Int_t AliHFEsecVtx::GetMCPID(AliESDtrack *track)
   // return mc pid
   //      
 
-  Int_t label = TMath::Abs(track->GetLabel());
-  TParticle* mcpart = fStack->Particle(label);
+  AliMCParticle *mctrack = NULL;
+  if(!(mctrack = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(TMath::Abs(track->GetLabel()))))) return 0; 
+  TParticle *mcpart = mctrack->Particle();
+
   if ( !mcpart ) return 0;
   Int_t pdgCode = mcpart->GetPdgCode();
 
@@ -580,8 +996,15 @@ Int_t AliHFEsecVtx::GetPairOriginESD(AliESDtrack* trk1, AliESDtrack* trk2)
   //           
 
   if (trk1->GetLabel()<0 || trk2->GetLabel()<0) return 0;
-  TParticle* part1 = fStack->Particle(trk1->GetLabel());
-  TParticle* part2 = fStack->Particle(trk2->GetLabel());
+
+  AliMCParticle *mctrack = NULL;
+  AliMCParticle *mctrack1 = NULL;
+  AliMCParticle *mctrack2 = NULL;
+  if(!(mctrack1 = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(TMath::Abs(trk1->GetLabel()))))) return 0; 
+  if(!(mctrack2 = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(TMath::Abs(trk2->GetLabel()))))) return 0; 
+  TParticle *part1 = mctrack1->Particle();
+  TParticle *part2 = mctrack2->Particle();
+
   TParticle* part2cp = part2;
   if (!(part1) || !(part2)) return 0;
 
@@ -598,7 +1021,9 @@ Int_t AliHFEsecVtx::GetPairOriginESD(AliESDtrack* trk1, AliESDtrack* trk2)
         if (label2 < 0) break; 
 
         if (label1 == label2){ //check if two tracks are originated from same mother
-          TParticle* commonmom = fStack->Particle(label2); 
+          if(!(mctrack = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(TMath::Abs(label2))))) return 0; 
+         TParticle* commonmom = mctrack->Particle();
+
           srcpdg = abs(commonmom->GetPdgCode()); 
 
           //check ancester to see if it is originally from beauty 
@@ -606,7 +1031,9 @@ Int_t AliHFEsecVtx::GetPairOriginESD(AliESDtrack* trk1, AliESDtrack* trk2)
              Int_t ancesterlabel = commonmom->GetFirstMother();
              if (ancesterlabel < 0) return srcpdg; // if there is no more commonancester, return commonmom's pdg  
 
-             TParticle* commonancester = fStack->Particle(ancesterlabel);
+             if(!(mctrack = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(TMath::Abs(ancesterlabel))))) return 0; 
+            TParticle* commonancester = mctrack->Particle();
+
              Int_t ancesterpdg = abs(commonancester->GetPdgCode());
 
              for (Int_t l=0; l<fNparents; l++){
@@ -618,10 +1045,13 @@ Int_t AliHFEsecVtx::GetPairOriginESD(AliESDtrack* trk1, AliESDtrack* trk2)
              commonmom = commonancester;
           }
         }
-        part2 = fStack->Particle(label2); //if their mother is different, go to earlier generation of 2nd particle
+       if(!(mctrack = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(TMath::Abs(label2))))) return 0; 
+       part2 = mctrack->Particle(); //if their mother is different, go to earlier generation of 2nd particle
+
         if (!(part2)) break;
      }
-     part1 = fStack->Particle(label1); //if their mother is different, go to earlier generation of 1st particle
+     if(!(mctrack = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(TMath::Abs(label1))))) return 0; 
+     part1 = mctrack->Particle(); //if their mother is different, go to earlier generation of 1st particle
      part2 = part2cp;
      if (!(part1)) return 0;
   }
@@ -748,7 +1178,16 @@ Int_t AliHFEsecVtx::GetElectronSource(Int_t iTrack)
     return -1;
   }
 
-  TParticle* mcpart = fStack->Particle(iTrack);
+  AliMCParticle *mctrack = NULL;
+  if(!(mctrack = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(TMath::Abs(iTrack))))) return -1; 
+  TParticle *mcpart = mctrack->Particle();
+
+  if(!mcpart){
+    AliDebug(1, "no mc particle, return\n");
+    return -1;
+  } 
+
+  if ( abs(mcpart->GetPdgCode()) != 11 ) return kMisID;
 
 //  if ( abs(mcpart->GetPdgCode()) != 11 ) return -1; // check if it is electron !
 
@@ -761,7 +1200,9 @@ Int_t AliHFEsecVtx::GetElectronSource(Int_t iTrack)
   Int_t origin = -1;
   Bool_t isFinalOpenCharm = kFALSE;
 
-  TParticle *partMother = fStack->Particle(iLabel);
+  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  
@@ -788,7 +1229,9 @@ Int_t AliHFEsecVtx::GetElectronSource(Int_t iTrack)
       }
 
       // 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++){
@@ -828,7 +1271,9 @@ Int_t AliHFEsecVtx::GetElectronSource(Int_t iTrack)
       }
 
       // 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++){
@@ -862,7 +1307,9 @@ Int_t AliHFEsecVtx::GetElectronSource(Int_t iTrack)
       }
 
       // 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++){
@@ -894,7 +1341,9 @@ Int_t AliHFEsecVtx::GetElectronSource(Int_t iTrack)
       }
 
       // 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++){
@@ -960,6 +1409,7 @@ Int_t AliHFEsecVtx::GetMCPDG(AliVTrack *track)
 
   Int_t label = TMath::Abs(track->GetLabel());
   Int_t pdgCode; 
+  AliMCParticle *mctrack = NULL;
 
   if (IsAODanalysis()) {
     AliAODMCParticle *mcpart = (AliAODMCParticle*)fMCArray->At(label);
@@ -967,7 +1417,9 @@ Int_t AliHFEsecVtx::GetMCPDG(AliVTrack *track)
       pdgCode = mcpart->GetPdgCode();
   }
   else {
-    TParticle* mcpart = fStack->Particle(label);
+    if(!(mctrack = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(TMath::Abs(label))))) return 0; 
+    TParticle *mcpart = mctrack->Particle();
+
     if ( !mcpart ) return 0;
       pdgCode = mcpart->GetPdgCode();
   }
@@ -1125,16 +1577,16 @@ void AliHFEsecVtx::MakeContainer(){
   //
 
   const Int_t nDimPair=6;
-  Int_t nBinPair[nDimPair] = {200, 500, 314, 2000, 2000, 11};
-  //Int_t nBinPair[nDimPair] = {200, 500, 314, 2000, 2000, 11, 1000, 1000, 60, 60};
+  Int_t nBinPair[nDimPair] = {200, 500, 314, 2000, 2000, 13};
+  //Int_t nBinPair[nDimPair] = {200, 500, 314, 2000, 2000, 13, 60, 60, 2000, 2000};
   const Double_t kInvmassmin = 0., kInvmassmax = 20.;
   const Double_t kKFChi2min = 0, kKFChi2max= 50;
   const Double_t kOpenanglemin = 0, kOpenanglemax = 3.14;
   const Double_t kSignedLxymin = -10, kSignedLxymax= 10;
   const Double_t kKFIPmin = -10, kKFIPmax= 10;
-  const Double_t kPairCodemin = -1, kPairCodemax= 10;
-  //const Double_t kDCAsigmin = 0, kDCAsigmax= 5;
+  const Double_t kPairCodemin = -1, kPairCodemax= 12;
   //const Double_t kPtmin = 0, kPtmax= 30;
+  //const Double_t kDCAsigmin = -5, kDCAsigmax= 5;
 
   Double_t* binEdgesPair[nDimPair];
   for(Int_t ivar = 0; ivar < nDimPair; ivar++)
@@ -1146,23 +1598,25 @@ void AliHFEsecVtx::MakeContainer(){
   for(Int_t i=0; i<=nBinPair[3]; i++) binEdgesPair[3][i]=(Double_t)kSignedLxymin + (kSignedLxymax - kSignedLxymin)/nBinPair[3]*(Double_t)i;
   for(Int_t i=0; i<=nBinPair[4]; i++) binEdgesPair[4][i]=(Double_t)kKFIPmin + (kKFIPmax - kKFIPmin)/nBinPair[4]*(Double_t)i;
   for(Int_t i=0; i<=nBinPair[5]; i++) binEdgesPair[5][i]=(Double_t)kPairCodemin + (kPairCodemax - kPairCodemin)/nBinPair[5]*(Double_t)i;
-  /*for(Int_t i=0; i<=nBinPair[6]; i++) binEdgesPair[6][i]=(Double_t)kDCAsigmin + (kDCAsigmax - kDCAsigmin)/nBinPair[6]*(Double_t)i;
-  for(Int_t i=0; i<=nBinPair[7]; i++) binEdgesPair[7][i]=binEdgesPair[6][i];
-  for(Int_t i=0; i<=nBinPair[8]; i++) binEdgesPair[8][i]=(Double_t)kPtmin + (kPtmax - kPtmin)/nBinPair[8]*(Double_t)i;
-  for(Int_t i=0; i<=nBinPair[9]; i++) binEdgesPair[9][i]=binEdgesPair[8][i];*/
+  //for(Int_t i=0; i<=nBinPair[6]; i++) binEdgesPair[6][i]=(Double_t)kPtmin + (kPtmax - kPtmin)/nBinPair[6]*(Double_t)i;
+  //for(Int_t i=0; i<=nBinPair[7]; i++) binEdgesPair[7][i]=binEdgesPair[6][i];
+  //for(Int_t i=0; i<=nBinPair[6]; i++) binEdgesPair[6][i]=(Double_t)kDCAsigmin + (kDCAsigmax - kDCAsigmin)/nBinPair[6]*(Double_t)i;
+  //for(Int_t i=0; i<=nBinPair[7]; i++) binEdgesPair[7][i]=binEdgesPair[6][i];
 
-  fPairQA = new THnSparseF("pairQA", "QA for Pair; invmass[GeV/c^2]; KF chi2; opening angle; signed Lxy; KF ip; pair code", nDimPair, nBinPair);
-  //fPairQA = new THnSparseF("pairQA", "QA for Pair; invmass[GeV/c^2]; KF chi2; opening angle; signed Lxy; KF ip; pair code; dca sig trk1; dca sig trk2; pt trk1; pt trk2 ", nDimPair, nBinPair);
+  fPairQA = new THnSparseF("pairQA", "QA for Pair; invmass[GeV/c^2]; KF chi2; opening angle; signed Lxy; KF ip; pair code; dca1; dca2", nDimPair, nBinPair);
+  //fPairQA = new THnSparseF("pairQA", "QA for Pair; invmass[GeV/c^2]; KF chi2; opening angle; signed Lxy; KF ip; pair code; pt1; pt2; dca1; dca2", nDimPair, nBinPair);
   for(Int_t idim = 0; idim < nDimPair; idim++){
     fPairQA->SetBinEdges(idim, binEdgesPair[idim]);
   }
 
   fSecVtxList->AddAt(fPairQA,0);
 
-  const Int_t nDimSecvtx=6;
+  const Int_t nDimSecvtx=9;
   Double_t* binEdgesSecvtx[nDimSecvtx];
-  Int_t nBinSecvtx[nDimSecvtx] = {200, 500, 2000, 2000, 11, 3};
-  const Double_t kNtrksmin = 0, kNtrksmax= 3;
+  Int_t nBinSecvtx[nDimSecvtx] = {200, 500, 2000, 2000, 13, 10, 4, 2000, 500};
+  const Double_t kNtrksmin = 0, kNtrksmax= 10;
+  const Double_t kTrueBmin = 0, kTrueBmax= 4;
+  const Double_t kPtmin = 0, kPtmax= 50;
   for(Int_t ivar = 0; ivar < nDimSecvtx; ivar++)
     binEdgesSecvtx[ivar] = new Double_t[nBinSecvtx[ivar] + 1];
 
@@ -1172,6 +1626,9 @@ void AliHFEsecVtx::MakeContainer(){
   for(Int_t i=0; i<=nBinSecvtx[3]; i++) binEdgesSecvtx[3][i]=binEdgesPair[4][i];
   for(Int_t i=0; i<=nBinSecvtx[4]; i++) binEdgesSecvtx[4][i]=binEdgesPair[5][i];
   for(Int_t i=0; i<=nBinSecvtx[5]; i++) binEdgesSecvtx[5][i]=(Double_t)kNtrksmin + (kNtrksmax - kNtrksmin)/nBinSecvtx[5]*(Double_t)i;
+  for(Int_t i=0; i<=nBinSecvtx[6]; i++) binEdgesSecvtx[6][i]=(Double_t)kTrueBmin + (kTrueBmax - kTrueBmin)/nBinSecvtx[6]*(Double_t)i;
+  for(Int_t i=0; i<=nBinSecvtx[7]; i++) binEdgesSecvtx[7][i]=binEdgesPair[3][i];
+  for(Int_t i=0; i<=nBinSecvtx[8]; i++) binEdgesSecvtx[8][i]=(Double_t)kPtmin + (kPtmax - kPtmin)/nBinSecvtx[8]*(Double_t)i;
 
   fSecvtxQA = new THnSparseF("secvtxQA", "QA for Secvtx; invmass[GeV/c^2]; KF chi2; signed Lxy; KF ip; pair code; n tracks ", nDimSecvtx, nBinSecvtx);
   for(Int_t idim = 0; idim < nDimSecvtx; idim++){
@@ -1179,6 +1636,7 @@ void AliHFEsecVtx::MakeContainer(){
   }
 
   fSecVtxList->AddAt(fSecvtxQA,1);
+
   for(Int_t ivar = 0; ivar < nDimPair; ivar++)
     delete binEdgesPair[ivar];
   for(Int_t ivar = 0; ivar < nDimSecvtx; ivar++)
index f316fdce8731d15efc14cdce05eaca1946fa0b5c..45dde233d2fc0ea82bba14cc04c76afa5e6017bf 100644 (file)
@@ -37,10 +37,11 @@ class AliAODEvent;
 class AliVTrack;
 class AliESDtrack;
 class AliAODTrack;
-class AliStack;
+class AliMCEvent;
 class AliHFEtrackFilter;
 class AliHFEpairs;
 class AliHFEsecVtxs;
+class AliKFParticle;
 
 //________________________________________________________________
 class AliHFEsecVtx : public TObject {
@@ -64,7 +65,7 @@ class AliHFEsecVtx : public TObject {
     void SetESDAnalysis() { SetBit(kAODanalysis, kFALSE); };
     void SetEvent(AliESDEvent* const ESD){fESD1=ESD;};    // set ESD pointer
     void SetEventAOD(AliAODEvent* const AOD){fAOD1=AOD;}; // set ESD pointer
-    void SetStack(AliStack* const stack){fStack=stack;};  // set stack pointer
+    void SetMCEvent(AliMCEvent* const mcEvent){fMCEvent=mcEvent;};  // set stack pointer
     void SetMCArray(TClonesArray* const mcarry){fMCArray=mcarry;} // set mcarray pointer
     void SetUseMCPID(Bool_t usemcpid){fUseMCPID=usemcpid;};
 
@@ -78,6 +79,7 @@ class AliHFEsecVtx : public TObject {
     Int_t GetPDG(AliVTrack *track);     // return pdg 
                void GetESDPID(AliESDtrack *track, Int_t &recpid, Double_t &recprob); //return esd pid likelihood
     void GetPrimaryCondition();
+    void RecalcPrimvtx(Int_t nkftrk, Int_t * const, AliKFParticle * const); //recalculate primary vertex
 
     TClonesArray *HFEpairs();
     TClonesArray *HFEsecvtxs();
@@ -101,20 +103,24 @@ class AliHFEsecVtx : public TObject {
     void Init();
     void FindSECVTXCandid(AliVTrack *track);
     void CalcSECVTXProperty(AliVTrack* track1, AliVTrack* track2, AliVTrack* track3); // calculated distinctive variables
+    void CalcSECVTXProperty(AliVTrack* track1, AliVTrack* track2, AliVTrack* track3, AliVTrack* track4); // calculated distinctive variables
 
+    void Fill4TrkSECVTX(AliVTrack* track, Int_t ipair, Int_t jpair, Int_t kpair);
+    void Fill3TrkSECVTX(AliVTrack* track, Int_t ipair, Int_t jpair);
+    void Fill2TrkSECVTX(AliVTrack* track, AliHFEpairs *pair);
 
   private:
     enum{
       kHasMCData = BIT(15),     // bitset for mc data usage
       kAODanalysis = BIT(16)    // bitset for aod analysis
     };
-    enum {kAll, kDirectCharm, kDirectBeauty, kBeautyCharm, kGamma, kPi0, kElse, kBeautyGamma, kBeautyPi0, kBeautyElse}; // electron origin 
+    enum {kAll, kDirectCharm, kDirectBeauty, kBeautyCharm, kGamma, kPi0, kElse, kBeautyGamma, kBeautyPi0, kBeautyElse, kMisID}; // electron origin 
     enum {kCharm=4, kBeauty=5}; // quark flavor
 
     AliHFEtrackFilter *fFilter; // filter Tracks to combine the signal track with
     AliESDEvent* fESD1; // ESD pointer             
     AliAODEvent* fAOD1; // AOD pointer             
-    AliStack* fStack;   // stack pointer              
+    AliMCEvent* fMCEvent;   // MCEvent pointer              
 
     Bool_t fUseMCPID;   // if use MC pid 
 
@@ -127,6 +133,7 @@ class AliHFEsecVtx : public TObject {
 
     Int_t fNoOfHFEpairs;       // number of e-h pairs  
     Int_t fNoOfHFEsecvtxs;     // number of secondary vertexes
+    Int_t fArethereSecVtx;     // checker
 
     TClonesArray *fHFEpairs;   //! Array of pair 
     TClonesArray *fHFEsecvtxs; //! Array of secondary vertexes 
@@ -134,12 +141,21 @@ class AliHFEsecVtx : public TObject {
 
                Double_t fPVx;          // primary vertex copy x 
                Double_t fPVy;          // primary vertex copy y
+               Double_t fPVx2;         // recalculated primary vertex x 
+               Double_t fPVy2;         // recalculated primary vertex y
     Double_t fCosPhi;       // cos of opening angle of two pair vertex
     Double_t fSignedLxy;    // signed Lxy of secondary vertex
+    Double_t fSignedLxy2;   // signed Lxy of secondary vertex based on recalculated primary vertex
     Double_t fKFchi2;       // chi2 of secondary vertex
     Double_t fInvmass;      // invariant mass of secondary vertex
     Double_t fInvmassSigma; // invariant mass sigma of secondary vertex
     Double_t fKFip;         // impact parameter of secondary vertex track
+    Double_t fKFip2;        // impact parameter of secondary vertex track based on recalculated primary vertex
+
+    Int_t fNsectrk2prim;    // # of secvtx tracks contributing to primvtx calculation
+
+    Double_t fVtxchi2Tightcut; // pair vertex chi2 cut
+    Double_t fVtxchi2Loosecut; // secvtx vertex chi2 cut
 
     THnSparseF *fPairQA;    // qa histos for pair analysis 
     THnSparseF *fSecvtxQA;  // qa histos for secvtx
index 8ec88b8a3e6bcfc74e93b926fff9000bde32417f..66a5a8ad0d8f2b430667eb759b7c9696c35d6639 100644 (file)
@@ -30,10 +30,13 @@ ClassImp(AliHFEsecVtxs)
 AliHFEsecVtxs::AliHFEsecVtxs():
   fTrkLabel1(0)
   ,fTrkLabel2(0)
+  ,fMCCode(0)
   ,fInvmass(0)
   ,fKFChi2(0)
   ,fSignedLxy(0)
+  ,fSignedLxy2(0)
   ,fKFIP(0)
+  ,fKFIP2(0)
 { 
   //
   // Default constructor
@@ -45,10 +48,13 @@ AliHFEsecVtxs::AliHFEsecVtxs(const AliHFEsecVtxs &p):
   TObject(p)
   ,fTrkLabel1(p.fTrkLabel1)
   ,fTrkLabel2(p.fTrkLabel2)
+  ,fMCCode(p.fMCCode)
   ,fInvmass(p.fInvmass)
   ,fKFChi2(p.fKFChi2)
   ,fSignedLxy(p.fSignedLxy)
+  ,fSignedLxy2(p.fSignedLxy2)
   ,fKFIP(p.fKFIP)
+  ,fKFIP2(p.fKFIP2)
 { 
   //
   // Copy constructor
index 24a9449523936d231229f734c564b3b4578f911b..9815b669bcb73a91bac6cb518cf88e13791775a8 100644 (file)
@@ -36,29 +36,38 @@ class AliHFEsecVtxs : public TObject {
 
                 Int_t GetTrkLabel1() const {return fTrkLabel1;}
                 Int_t GetTrkLabel2() const {return fTrkLabel2;}
+                Int_t GetMCCode() const {return fMCCode;}
                 Double_t GetInvmass() const {return fInvmass;}
                 Double_t GetKFChi2() const {return fKFChi2;}
                 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 SetTrkLabel1(Int_t label) {fTrkLabel1 = label;}
                 void SetTrkLabel2(Int_t label) {fTrkLabel2 = label;}
                 void SetInvmass(Double_t invmass) {fInvmass = invmass;}
                 void SetKFChi2(Double_t kfchi2) {fKFChi2 = kfchi2;}
                 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 SetMCCode(Int_t mccode) {fMCCode = mccode;}
 
         protected:
                 Int_t fTrkLabel1;    // track 1 label associated to secvtx 
                 Int_t fTrkLabel2;    // track 2 label associated to secvtx
+                Int_t fMCCode;       // track mc code
                 Double_t fInvmass;   // secvtx invariant mass
                 Double_t fKFChi2;    // secvtx chi2 
                 Double_t fSignedLxy; // secvtx signed Lxy
-                Double_t fKFIP;      // secvtx impact parameter 
+                Double_t fSignedLxy2; // recalculated secvtx signed Lxy
+                Double_t fKFIP;       // secvtx impact parameter 
+                Double_t fKFIP2;      // recalculated secvtx impact parameter 
 
         private:
 
-        ClassDef(AliHFEsecVtxs,0);
+        ClassDef(AliHFEsecVtxs,1);
 };
 
 #endif
index 1d5e5c289ea6c5ecc927b76e39798baf8dcbf5a5..91af78ad4fdf2704cac97f306e1225786259bc87 100644 (file)
 #include "TAxis.h"
 
 #include "AliAODMCParticle.h"
+#include "AliESDpid.h"
 #include "AliLog.h"
+#include "AliTOFPIDResponse.h"
 
 #include "AliHFEtools.h"
 
 ClassImp(AliHFEtools)
 
+AliESDpid *AliHFEtools::fgDefaultPID = NULL;
+Int_t AliHFEtools::fgLogLevel = 1;
+
 //__________________________________________
 AliHFEtools::AliHFEtools():
   TObject()
@@ -148,3 +153,50 @@ Float_t AliHFEtools::GetRapidity(AliAODMCParticle *part){
   return rapidity;
 }
 
+//__________________________________________
+AliESDpid* AliHFEtools::GetDefaultPID(Bool_t isMC){
+  //
+  // Get the default PID as singleton instance
+  //
+  if(!fgDefaultPID){
+    fgDefaultPID = new AliESDpid;
+    Double_t tres = isMC ? 80. : 130.;
+    fgDefaultPID->GetTOFResponse().SetTimeResolution(tres);
+
+    // TPC Bethe Bloch parameters
+    Double_t alephParameters[5];
+    if(isMC){
+      // simulation
+      alephParameters[0] = 2.15898e+00/50.;
+      alephParameters[1] = 1.75295e+01;
+      alephParameters[2] = 3.40030e-09;
+      alephParameters[3] = 1.96178e+00;
+      alephParameters[4] = 3.91720e+00;
+    } else {
+      alephParameters[0] = 0.0283086/0.97;
+      //alephParameters[0] = 0.0283086;
+      alephParameters[1] = 2.63394e+01;
+      alephParameters[2] = 5.04114e-11;
+      alephParameters[3] = 2.12543e+00;
+      alephParameters[4] = 4.88663e+00;
+    }
+    fgDefaultPID->GetTPCResponse().SetBetheBlochParameters(alephParameters[0],alephParameters[1],alephParameters[2], alephParameters[3],alephParameters[4]);
+
+  }
+  if(fgLogLevel){
+    printf("Error - You are using the default PID: You should use the PID coming from the tender");
+    printf("Error - Arrrrrrrrr...");
+    printf("Error - Please rethink your program logic. Using default PID is really dangerous");
+    printf("Error - TOF PID is adapted to Monte Carlo");
+  }
+  return fgDefaultPID;
+}
+
+//__________________________________________
+void AliHFEtools::DestroyDefaultPID(){
+  //
+  // Destroy default PID object if existing
+  //
+  if(fgDefaultPID) delete fgDefaultPID;
+  fgDefaultPID = NULL;
+}
index 3aa47883077bcd115fb7c892683360dc7955761c..6c4527ac8aa2b950f6b1fc53fb500113f3547699 100644 (file)
@@ -24,6 +24,7 @@
 
 class TParticle;
 class AliAODMCParticle;
+class AliESDpid;
 
 class AliHFEtools : public TObject{
   public:
@@ -35,6 +36,13 @@ class AliHFEtools : public TObject{
     Bool_t    BinLogAxis(TObject *o, Int_t dim);
     static Float_t GetRapidity(TParticle *part);
     static Float_t GetRapidity(AliAODMCParticle *part); // return rapidity
+    static AliESDpid *GetDefaultPID(Bool_t isMC = kTRUE);
+    static void DestroyDefaultPID();
+    static void SetLogLevel(Int_t loglevel) { fgLogLevel = loglevel ;}
+
+  private:
+      static AliESDpid *fgDefaultPID;   // Default PID object
+      static Int_t fgLogLevel;          // Log Level
 
     ClassDef(AliHFEtools, 0)
 };
index 2fe5bbcff18bb18616cd2e0ce1d9cb36f7221465..e7c37707e33320845811fc3c49093a763877782f 100644 (file)
@@ -383,8 +383,8 @@ AliHFEcutStep *AliHFEtrackFilter::MakeCutStepRecKineITSTPC(){
   //
   AliHFEcutStep *fCutStep = new AliHFEcutStep("RecKineITSTPC");
 
-  AliCFTrackQualityCuts *trackQuality = new AliCFTrackQualityCuts("QualityRec","REC Track Quality Cuts");
-  trackQuality->SetMinNClusterTPC(50);
+  AliCFTrackQualityCuts *trackQuality = new AliCFTrackQualityCuts((Char_t *)"QualityRec", (Char_t *)"REC Track Quality Cuts");
+  trackQuality->SetMinNClusterTPC(80);
   trackQuality->SetMaxChi2PerClusterTPC(3.5);
   trackQuality->SetStatus(AliESDtrack::kTPCrefit | AliESDtrack::kITSrefit);
   trackQuality->SetMaxCovDiagonalElements(2., 2., 0.5, 0.5, 2); 
@@ -394,9 +394,9 @@ AliHFEcutStep *AliHFEtrackFilter::MakeCutStepRecKineITSTPC(){
   hfecuts->SetClusterRatioTPC(0.6);
   fCutStep->AddCut(hfecuts);
   
-  AliCFTrackKineCuts *kineCuts = new AliCFTrackKineCuts("RecKine", "REC Kine Cuts");
-  kineCuts->SetPtRange(0.1, 10);
-  kineCuts->SetEtaRange(-0.9, 0.9);
+  AliCFTrackKineCuts *kineCuts = new AliCFTrackKineCuts((Char_t *)"RecKine", (Char_t *)"REC Kine Cuts");
+  kineCuts->SetPtRange(0.1, 20);
+  kineCuts->SetEtaRange(-0.8, 0.8);
   fCutStep->AddCut(kineCuts); 
 
   AddCutStep(fCutStep);
@@ -411,9 +411,9 @@ AliHFEcutStep *AliHFEtrackFilter::MakeCutStepPrimary(){
   //
   AliHFEcutStep *fCutStep = new AliHFEcutStep("Primary");
 
-  AliCFTrackIsPrimaryCuts *primaryCut = new AliCFTrackIsPrimaryCuts("PrimaryCuts", "REC Primary Cuts");
-  primaryCut->SetMaxDCAToVertexXY(2.);
-  primaryCut->SetMaxDCAToVertexZ(10.);
+  AliCFTrackIsPrimaryCuts *primaryCut = new AliCFTrackIsPrimaryCuts((Char_t *)"PrimaryCuts", (Char_t *)"REC Primary Cuts");
+  primaryCut->SetMaxDCAToVertexXY(0.5);
+  primaryCut->SetMaxDCAToVertexZ(5.);
   primaryCut->SetAcceptKinkDaughters(kFALSE);
   fCutStep->AddCut(primaryCut);
 
@@ -429,7 +429,7 @@ AliHFEcutStep *AliHFEtrackFilter::MakeCutStepHFEITS(){
   //
   AliHFEcutStep *fCutStep = new AliHFEcutStep("HFEITS");
 
-  AliHFEextraCuts *hfecuts = new AliHFEextraCuts("HFEPixelsCuts","Extra cuts from the HFE group");
+  AliHFEextraCuts *hfecuts = new AliHFEextraCuts((Char_t *)"HFEPixelsCuts",(Char_t *)"Extra cuts from the HFE group");
   hfecuts->SetRequireITSpixel(AliHFEextraCuts::kFirst);
   //hfecuts->SetCheckITSstatus(kTRUE);
   fCutStep->AddCut(hfecuts);
@@ -461,17 +461,18 @@ AliHFEcutStep *AliHFEtrackFilter::MakeMCSignalCuts(){
   // Cut step is already included in the filter
   //
   fMCsignal = new AliHFEcutStep("MCSignal");
-  AliCFParticleGenCuts *genCuts = new AliCFParticleGenCuts("fCutsGenMC", "Particle Generation Cuts");
+  AliCFParticleGenCuts *genCuts = new AliCFParticleGenCuts((Char_t *)"fCutsGenMC", (Char_t *)"Particle Generation Cuts");
   genCuts->SetRequireIsCharged();
   genCuts->SetRequireIsPrimary();
-  genCuts->SetProdVtxRangeX(-2, 2);
-  genCuts->SetProdVtxRangeY(-2, 2);
+  genCuts->SetProdVtxRange2D();
+  genCuts->SetProdVtxRangeX(0, 1);
+  genCuts->SetProdVtxRangeY(0, 1);
   genCuts->SetRequirePdgCode(11, kTRUE);
   fMCsignal->AddCut(genCuts);
   
-  AliCFTrackKineCuts *kineMCcuts = new AliCFTrackKineCuts("fCutsKineMC","MC Kine Cuts");
-  kineMCcuts->SetPtRange(0.1, 10.);
-  kineMCcuts->SetEtaRange(-0.9, 0.9);
+  AliCFTrackKineCuts *kineMCcuts = new AliCFTrackKineCuts((Char_t *)"fCutsKineMC",(Char_t *)"MC Kine Cuts");
+  kineMCcuts->SetPtRange(0.1, 20.);
+  kineMCcuts->SetEtaRange(-0.8, 0.8);
   fMCsignal->AddCut(kineMCcuts);
 
   return fMCsignal;
index 845f4aa5dc2f7468cce6ae7c46d496948be7baa5..211a6820da1a7b662cb9aa912543fc3481d5cf63 100644 (file)
@@ -9,8 +9,11 @@ SRCS=hfe/AliHFEtools.cxx \
      hfe/AliHFEsecVtx.cxx \
      hfe/AliHFEpriVtx.cxx \
      hfe/AliHFEelecbackground.cxx \
+     hfe/AliHFEspectrum.cxx \
+     hfe/AliHFEV0info.cxx \
      hfe/AliHFEV0pid.cxx \
      hfe/AliHFEpidQA.cxx \
+     hfe/AliHFEtrdPIDqa.cxx \
      hfe/AliHFEpid.cxx \
      hfe/AliHFEpidBase.cxx \
      hfe/AliHFEpidITS.cxx \
@@ -30,7 +33,8 @@ SRCS=hfe/AliHFEtools.cxx \
      hfe/AliAnalysisTaskHFEpidQA.cxx \
      hfe/AliHFEefficiency.cxx \
      hfe/AliAnalysisTaskHFE.cxx \
-     hfe/AliHFEV0pidMC.cxx
+     hfe/AliHFEV0pidMC.cxx \
+     hfe/AliHFEV0cuts.cxx
 HDRS= $(SRCS:.cxx=.h)
 
 DHDR= PWG3hfeLinkDef.h