]> git.uio.no Git - u/mrichter/AliRoot.git/commitdiff
New package for heavy flavour electrons analysis (M.Fasel)
authordainese <dainese@f7af4fe6-9843-0410-8265-dc069ae4e863>
Thu, 4 Jun 2009 08:46:22 +0000 (08:46 +0000)
committerdainese <dainese@f7af4fe6-9843-0410-8265-dc069ae4e863>
Thu, 4 Jun 2009 08:46:22 +0000 (08:46 +0000)
24 files changed:
PWG3/hfe/AliAnalysisElectronTask.cxx [new file with mode: 0644]
PWG3/hfe/AliAnalysisElectronTask.h [new file with mode: 0644]
PWG3/hfe/AliAnalysisTaskHFE.cxx [new file with mode: 0644]
PWG3/hfe/AliAnalysisTaskHFE.h [new file with mode: 0644]
PWG3/hfe/AliHFEcollection.cxx [new file with mode: 0644]
PWG3/hfe/AliHFEcollection.h [new file with mode: 0644]
PWG3/hfe/AliHFEcuts.cxx [new file with mode: 0644]
PWG3/hfe/AliHFEcuts.h [new file with mode: 0644]
PWG3/hfe/AliHFEextraCuts.cxx [new file with mode: 0644]
PWG3/hfe/AliHFEextraCuts.h [new file with mode: 0644]
PWG3/hfe/AliHFEpid.cxx [new file with mode: 0644]
PWG3/hfe/AliHFEpid.h [new file with mode: 0644]
PWG3/hfe/AliHFEpidBase.cxx [new file with mode: 0644]
PWG3/hfe/AliHFEpidBase.h [new file with mode: 0644]
PWG3/hfe/AliHFEpidMC.cxx [new file with mode: 0644]
PWG3/hfe/AliHFEpidMC.h [new file with mode: 0644]
PWG3/hfe/AliHFEpidTOF.cxx [new file with mode: 0644]
PWG3/hfe/AliHFEpidTOF.h [new file with mode: 0644]
PWG3/hfe/AliHFEpidTPC.cxx [new file with mode: 0644]
PWG3/hfe/AliHFEpidTPC.h [new file with mode: 0644]
PWG3/hfe/AliHFEpidTRD.cxx [new file with mode: 0644]
PWG3/hfe/AliHFEpidTRD.h [new file with mode: 0644]
PWG3/hfe/TRD.PIDthresholds.root [new file with mode: 0644]
PWG3/hfe/runElectronTask.C [new file with mode: 0644]

diff --git a/PWG3/hfe/AliAnalysisElectronTask.cxx b/PWG3/hfe/AliAnalysisElectronTask.cxx
new file mode 100644 (file)
index 0000000..af91dbd
--- /dev/null
@@ -0,0 +1,263 @@
+/**************************************************************************
+* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+*                                                                        *
+* Author: The ALICE Off-line Project.                                    *
+* Contributors are mentioned in the code where appropriate.              *
+*                                                                        *
+* Permission to use, copy, modify and distribute this software and its   *
+* documentation strictly for non-commercial purposes is hereby granted   *
+* without fee, provided that the above copyright notice appears in all   *
+* copies and that both the copyright notice and this permission notice   *
+* appear in the supporting documentation. The authors make no claims     *
+* about the suitability of this software for any purpose. It is          *
+* provided "as is" without express or implied warranty.                  *
+**************************************************************************/
+/*
+ * The analysis task:
+ * Filling an AliCFContainer with the quantities pt, eta and phi
+ * for tracks which survivied the particle cuts (MC resp. ESD tracks)
+ * Track selection is done using the AliHFE package
+ * 
+ * Author:
+ *  Markus Fasel <M.Fasel@gsi.de>
+ */
+#include <TAxis.h>
+#include <TCanvas.h>
+#include <TChain.h>
+#include <TH1F.h>
+#include <TH1I.h>
+#include <TH2F.h>
+#include <TIterator.h>
+#include <TList.h>
+#include <TLegend.h>
+#include <TMath.h>
+#include <TObjArray.h>
+#include <TParticle.h>
+#include <TProfile.h>
+#include <TTree.h>
+
+#include "AliCFContainer.h"
+#include "AliCFManager.h"
+#include "AliESDEvent.h"
+#include "AliESDInputHandler.h"
+#include "AliESDtrack.h"
+#include "AliESDtrackCuts.h"
+#include "AliLog.h"
+#include "AliAnalysisManager.h"
+#include "AliMCEvent.h"
+#include "AliMCEventHandler.h"
+#include "AliMCParticle.h"
+#include "AliPID.h"
+
+#include "AliHFEpid.h"
+#include "AliHFEcuts.h"
+#include "AliAnalysisElectronTask.h"
+
+//____________________________________________________________
+AliAnalysisElectronTask::AliAnalysisElectronTask():
+       AliAnalysisTask("PID efficiency Analysis", "")
+       , fESD(0x0)
+       , fMC(0x0)
+       , fCFM(0x0)
+       , fPID(0x0)
+  , fCuts(0x0)
+       , fNEvents(0x0)
+       , fQA(0x0)
+{
+       DefineInput(0, TChain::Class());
+       DefineOutput(0, TH1I::Class());
+       DefineOutput(1, AliCFContainer::Class());
+       DefineOutput(2, TList::Class());
+
+  // Initialize cuts
+  fCuts = new AliHFEcuts;
+  fPID = new AliHFEpid;
+}
+
+//____________________________________________________________
+AliAnalysisElectronTask::~AliAnalysisElectronTask(){
+       if(fESD) delete fESD;
+       if(fMC) delete fMC;
+       if(fPID) delete fPID;
+       if(fQA) delete fQA;
+  if(fCuts) delete fCuts;
+       if(fNEvents) delete fNEvents;
+       fQA = 0x0; fMC = 0x0; fESD = 0x0; fCFM = 0x0; fPID = 0x0; fCuts = 0x0;
+}
+
+//____________________________________________________________
+void AliAnalysisElectronTask::ConnectInputData(Option_t *){
+       TTree *esdchain = dynamic_cast<TChain *>(GetInputData(0));
+       if(!esdchain){
+               AliError("ESD chain empty");
+               return;
+       } else {
+               esdchain->SetBranchStatus("Tracks", 1);
+       }
+       AliESDInputHandler *esdH = dynamic_cast<AliESDInputHandler *>(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler());
+       if(!esdH){      
+               AliError("No ESD input handler");
+               return;
+       } else {
+               fESD = esdH->GetEvent();
+       }
+       AliMCEventHandler *mcH = dynamic_cast<AliMCEventHandler *>(AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler());
+       if(!mcH){       
+               AliError("No MC truth handler");
+               return;
+       } else {
+               fMC = mcH->MCEvent();
+       }
+}
+
+//____________________________________________________________
+void AliAnalysisElectronTask::CreateOutputObjects(){
+       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
+       // First Step: TRD alone
+       if(!fQA) fQA = new TList;
+       fQA->AddAt(new TProfile("conr", "Electron PID contamination", 20, 0, 20), 0);
+       fQA->AddAt(new TH1F("alpha_rec", "Alpha from reconstructed tracks with TRD hits", 36, -TMath::Pi(), TMath::Pi()), 1);
+       fQA->AddAt(new TH1F("alpha_sim", "Alpha from simulated electron tracks", 36, -TMath::Pi(), TMath::Pi()), 2);
+       fQA->AddAt(new TH1F("nElectron", "Number of electrons", 100, 0, 100), 3);
+       fQA->AddAt(new TProfile("pidquality", "TRD PID quality as function of momentum", 20, 0, 20), 4);
+       fQA->AddAt(new TProfile("ntrdclusters", "Number of TRD clusters as function of momentum", 20, 0, 20), 5);
+       fQA->AddAt(new TH1F("chi2TRD","#chi2 per TRD cluster", 20, 0, 20), 6);
+
+  // Initialize correction Framework and Cuts
+  fCFM = new AliCFManager;
+  MakeParticleContainer();
+  // Temporary fix: Initialize particle cuts with 0x0
+  for(Int_t istep = 0; istep < fCFM->GetParticleContainer()->GetNStep(); istep++)
+    fCFM->SetParticleCutsList(istep, 0x0);
+  if(IsQAOn()){
+    fCuts->SetDebugMode();
+    fQA->AddAt(fCuts->GetQAhistograms(), 7);
+  }
+  fCuts->CreateStandardCuts();
+  fCuts->Initialize(fCFM);
+
+  // Initialize PID
+  if(IsQAOn()){
+    fPID->SetQAOn();
+    fQA->AddAt(fPID->GetQAhistograms(), 8);
+  }
+  fPID->SetHasMCData(kTRUE);
+  fPID->InitializePID("TRD");
+}
+
+//____________________________________________________________
+void AliAnalysisElectronTask::Exec(Option_t *){
+       //
+       // Run the analysis
+       //
+       if(!fESD){
+               AliError("No ESD Event");
+               return;
+       }
+       if(!fMC){
+               AliError("No MC Event");
+               return;
+       }
+       fCFM->SetEventInfo(fMC);
+  fPID->SetMCEvent(fMC);
+
+       //fCFM->CheckEventCuts(AliCFManager::kEvtGenCuts, fMC);
+
+       Double_t pt = 0;
+       Double_t container[3];
+
+       // Loop over the Monte Carlo tracks to see whether we have overlooked any track
+       AliMCParticle *mctrack = 0x0;
+       Int_t nElectrons = 0;
+       for(Int_t imc = fMC->GetNumberOfTracks(); imc--;){
+               mctrack = fMC->GetTrack(imc);
+               container[0] = mctrack->Pt();
+               container[1] = mctrack->Eta();
+    container[2] = mctrack->Phi();
+
+               if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepMCGenerated, mctrack)) continue;
+               fCFM->GetParticleContainer()->Fill(container, AliHFEcuts::kStepMCGenerated);
+               (dynamic_cast<TH1F *>(fQA->At(2)))->Fill(mctrack->Phi() - TMath::Pi());
+               if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepMCInAcceptance, mctrack)) continue;
+               // find the label in the vector
+               fCFM->GetParticleContainer()->Fill(container, AliHFEcuts::kStepMCInAcceptance);
+               nElectrons++;
+       }
+       (dynamic_cast<TH1F *>(fQA->At(3)))->Fill(nElectrons);
+
+       // fCFM->CheckEventCuts(AliCFManager::kEvtRecCuts, fESD);
+       AliESDtrack *track = 0x0;
+       for(Int_t itrack = 0; itrack < fESD->GetNumberOfTracks(); itrack++){
+               track = fESD->GetTrack(itrack);
+               container[0] = track->Pt();
+               container[1] = track->Eta();
+    container[2] = track->Phi();
+               if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepRecKine, track)) continue;
+               fCFM->GetParticleContainer()->Fill(container, AliHFEcuts::kStepRecKine);
+
+               // Check TRD criterions (outside the correction framework)
+               if(track->GetTRDncls()){
+                       (dynamic_cast<TH1F *>(fQA->At(6)))->Fill(track->GetTRDchi2()/track->GetTRDncls());
+                       (dynamic_cast<TH1F *>(fQA->At(1)))->Fill(track->GetAlpha());    // Check the acceptance without tight cuts
+                       (dynamic_cast<TProfile *>(fQA->At(4)))->Fill(container[0], track->GetTRDpidQuality());
+                       (dynamic_cast<TProfile *>(fQA->At(5)))->Fill(container[0], track->GetTRDncls());
+               }
+               if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepRecPrim, track)) continue;
+    fCFM->GetParticleContainer()->Fill(container, AliHFEcuts::kStepRecPrim);
+    if(fCFM->CheckParticleCuts(AliHFEcuts::kStepHFEcuts, track)) continue;
+    fCFM->GetParticleContainer()->Fill(container, AliHFEcuts::kStepHFEcuts);
+    // track accepted, do PID
+               if(!fPID->IsSelected(track)) continue;
+       fCFM->GetParticleContainer()->Fill(container, AliHFEcuts::kStepHFEcuts + 1);
+       }
+       fNEvents->Fill(1);
+
+       // Done!!!
+       PostData(0, fNEvents);
+       PostData(1, fCFM->GetParticleContainer());
+       PostData(2, fQA);
+}
+
+//____________________________________________________________
+void AliAnalysisElectronTask::Terminate(Option_t *){
+       //
+       // Terminate not implemented at the moment
+       //
+}
+
+//____________________________________________________________
+void AliAnalysisElectronTask::MakeParticleContainer(){
+  //
+  // Create the particle container for the correction framework manager and 
+  // link it
+  //
+  const Int_t nvar   = 3 ; //number of variables on the grid:pt,eta, phi
+  const Double_t ptmin = 0., ptmax = 10.;
+  const Double_t etamin = -0.9, etamax = 0.9;
+  const Double_t phimin = 0., phimax = 2. * TMath::Pi();
+  
+
+  //arrays for the number of bins in each dimension
+  Int_t iBin[nvar];
+  iBin[0] = 20; //bins in pt
+  iBin[1] =  8; //bins in eta 
+  iBin[2] = 18; // bins in phi
+
+  //arrays for lower bounds :
+  Double_t *binLim1 = new Double_t[iBin[0] + 1];
+  Double_t *binLim2 = new Double_t[iBin[1] + 1];
+  Double_t *binLim3 = new Double_t[iBin[2] + 1];
+
+  //values for bin lower bounds
+  for(Int_t i=0; i<=iBin[0]; i++) binLim1[i]=(Double_t)ptmin + (ptmax-ptmin)/iBin[0]*(Double_t)i; 
+  for(Int_t i=0; i<=iBin[1]; i++) binLim2[i]=(Double_t)etamin  + (etamax-etamin)/iBin[1]*(Double_t)i;
+  for(Int_t i=0; i<=iBin[2]; i++) binLim3[i]=(Double_t)phimin  + (phimax-phimin)/iBin[2]*(Double_t)i;
+
+  //one "container" for MC
+  AliCFContainer* container = new AliCFContainer("container","container for tracks", AliHFEcuts::kNcutSteps + 1, nvar, iBin);
+  //setting the bin limits
+  container -> SetBinLimits(0,binLim1);
+  container -> SetBinLimits(1,binLim2);
+  container -> SetBinLimits(2,binLim3);
+  fCFM->SetParticleContainer(container);
+}
diff --git a/PWG3/hfe/AliAnalysisElectronTask.h b/PWG3/hfe/AliAnalysisElectronTask.h
new file mode 100644 (file)
index 0000000..e861d49
--- /dev/null
@@ -0,0 +1,58 @@
+/**************************************************************************
+* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+*                                                                        *
+* Author: The ALICE Off-line Project.                                    *
+* Contributors are mentioned in the code where appropriate.              *
+*                                                                        *
+* Permission to use, copy, modify and distribute this software and its   *
+* documentation strictly for non-commercial purposes is hereby granted   *
+* without fee, provided that the above copyright notice appears in all   *
+* copies and that both the copyright notice and this permission notice   *
+* appear in the supporting documentation. The authors make no claims     *
+* about the suitability of this software for any purpose. It is          *
+* provided "as is" without express or implied warranty.                  *
+**************************************************************************/
+#ifndef ALIANALYSEPIDEFFICIENCY_H
+#define ALIANALYSEPIDEFFICIENCY_H
+
+#include "AliAnalysisTask.h"
+
+class AliHFEpid;
+class AliHFEcuts;
+class AliCFManager;
+class AliESDEvent;
+class AliESDtrackCuts;
+class AliMCEvent;
+class TH1I; 
+class TList;
+
+class AliAnalysisElectronTask : public AliAnalysisTask{
+  enum{
+    kIsQAOn = BIT(14)
+  };
+       public:
+               AliAnalysisElectronTask();
+               ~AliAnalysisElectronTask();
+
+               virtual void ConnectInputData(Option_t *);
+               virtual void CreateOutputObjects();
+               virtual void Exec(Option_t *);
+               virtual void Terminate(Option_t *);
+
+    void SetQAOn() { SetBit(kIsQAOn, kTRUE); };
+    Bool_t IsQAOn() const { return TestBit(kIsQAOn); };
+
+       private:
+    void MakeParticleContainer();
+
+               AliESDEvent *fESD;                              //! The ESD Event
+               AliMCEvent *fMC;                                  //! The MC Event
+               AliCFManager *fCFM;                             //! Correction Framework Manager
+               AliHFEpid *fPID;         //! PID
+    AliHFEcuts *fCuts;     //! Cut Collection
+               TH1I *fNEvents;                                   //! counter for the number of Events
+               TList *fQA;                                           //! QA histos for the cuts
+
+       ClassDef(AliAnalysisElectronTask, 1)    // The electron Analysis Task
+};
+#endif
diff --git a/PWG3/hfe/AliAnalysisTaskHFE.cxx b/PWG3/hfe/AliAnalysisTaskHFE.cxx
new file mode 100644 (file)
index 0000000..13939ec
--- /dev/null
@@ -0,0 +1,263 @@
+/**************************************************************************
+* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+*                                                                        *
+* Author: The ALICE Off-line Project.                                    *
+* Contributors are mentioned in the code where appropriate.              *
+*                                                                        *
+* Permission to use, copy, modify and distribute this software and its   *
+* documentation strictly for non-commercial purposes is hereby granted   *
+* without fee, provided that the above copyright notice appears in all   *
+* copies and that both the copyright notice and this permission notice   *
+* appear in the supporting documentation. The authors make no claims     *
+* about the suitability of this software for any purpose. It is          *
+* provided "as is" without express or implied warranty.                  *
+**************************************************************************/
+/*
+ * The analysis task:
+ * Filling an AliCFContainer with the quantities pt, eta and phi
+ * for tracks which survivied the particle cuts (MC resp. ESD tracks)
+ * Track selection is done using the AliHFE package
+ * 
+ * Author:
+ *  Markus Fasel <M.Fasel@gsi.de>
+ */
+#include <TAxis.h>
+#include <TCanvas.h>
+#include <TChain.h>
+#include <TH1F.h>
+#include <TH1I.h>
+#include <TH2F.h>
+#include <TIterator.h>
+#include <TList.h>
+#include <TLegend.h>
+#include <TMath.h>
+#include <TObjArray.h>
+#include <TParticle.h>
+#include <TProfile.h>
+#include <TTree.h>
+
+#include "AliCFContainer.h"
+#include "AliCFManager.h"
+#include "AliESDEvent.h"
+#include "AliESDInputHandler.h"
+#include "AliESDtrack.h"
+#include "AliESDtrackCuts.h"
+#include "AliLog.h"
+#include "AliAnalysisManager.h"
+#include "AliMCEvent.h"
+#include "AliMCEventHandler.h"
+#include "AliMCParticle.h"
+#include "AliPID.h"
+
+#include "AliHFEpid.h"
+#include "AliHFEcuts.h"
+#include "AliAnalysisTaskHFE.h"
+
+//____________________________________________________________
+AliAnalysisTaskHFE::AliAnalysisTaskHFE():
+       AliAnalysisTask("PID efficiency Analysis", "")
+       , fESD(0x0)
+       , fMC(0x0)
+       , fCFM(0x0)
+       , fPID(0x0)
+  , fCuts(0x0)
+       , fNEvents(0x0)
+       , fQA(0x0)
+{
+       DefineInput(0, TChain::Class());
+       DefineOutput(0, TH1I::Class());
+       DefineOutput(1, AliCFContainer::Class());
+       DefineOutput(2, TList::Class());
+
+  // Initialize cuts
+  fCuts = new AliHFEcuts;
+  fPID = new AliHFEpid;
+}
+
+//____________________________________________________________
+AliAnalysisTaskHFE::~AliAnalysisTaskHFE(){
+       if(fESD) delete fESD;
+       if(fMC) delete fMC;
+       if(fPID) delete fPID;
+       if(fQA) delete fQA;
+  if(fCuts) delete fCuts;
+       if(fNEvents) delete fNEvents;
+       fQA = 0x0; fMC = 0x0; fESD = 0x0; fCFM = 0x0; fPID = 0x0; fCuts = 0x0;
+}
+
+//____________________________________________________________
+void AliAnalysisTaskHFE::ConnectInputData(Option_t *){
+       TTree *esdchain = dynamic_cast<TChain *>(GetInputData(0));
+       if(!esdchain){
+               AliError("ESD chain empty");
+               return;
+       } else {
+               esdchain->SetBranchStatus("Tracks", 1);
+       }
+       AliESDInputHandler *esdH = dynamic_cast<AliESDInputHandler *>(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler());
+       if(!esdH){      
+               AliError("No ESD input handler");
+               return;
+       } else {
+               fESD = esdH->GetEvent();
+       }
+       AliMCEventHandler *mcH = dynamic_cast<AliMCEventHandler *>(AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler());
+       if(!mcH){       
+               AliError("No MC truth handler");
+               return;
+       } else {
+               fMC = mcH->MCEvent();
+       }
+}
+
+//____________________________________________________________
+void AliAnalysisTaskHFE::CreateOutputObjects(){
+       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
+       // First Step: TRD alone
+       if(!fQA) fQA = new TList;
+       fQA->AddAt(new TProfile("conr", "Electron PID contamination", 20, 0, 20), 0);
+       fQA->AddAt(new TH1F("alpha_rec", "Alpha from reconstructed tracks with TRD hits", 36, -TMath::Pi(), TMath::Pi()), 1);
+       fQA->AddAt(new TH1F("alpha_sim", "Alpha from simulated electron tracks", 36, -TMath::Pi(), TMath::Pi()), 2);
+       fQA->AddAt(new TH1F("nElectron", "Number of electrons", 100, 0, 100), 3);
+       fQA->AddAt(new TProfile("pidquality", "TRD PID quality as function of momentum", 20, 0, 20), 4);
+       fQA->AddAt(new TProfile("ntrdclusters", "Number of TRD clusters as function of momentum", 20, 0, 20), 5);
+       fQA->AddAt(new TH1F("chi2TRD","#chi2 per TRD cluster", 20, 0, 20), 6);
+
+  // Initialize correction Framework and Cuts
+  fCFM = new AliCFManager;
+  MakeParticleContainer();
+  // Temporary fix: Initialize particle cuts with 0x0
+  for(Int_t istep = 0; istep < fCFM->GetParticleContainer()->GetNStep(); istep++)
+    fCFM->SetParticleCutsList(istep, 0x0);
+  if(IsQAOn()){
+    fCuts->SetDebugMode();
+    fQA->AddAt(fCuts->GetQAhistograms(), 7);
+  }
+  fCuts->CreateStandardCuts();
+  fCuts->Initialize(fCFM);
+
+  // Initialize PID
+  if(IsQAOn()){
+    fPID->SetQAOn();
+    fQA->AddAt(fPID->GetQAhistograms(), 8);
+  }
+  fPID->SetHasMCData(kTRUE);
+  fPID->InitializePID("TRD");
+}
+
+//____________________________________________________________
+void AliAnalysisTaskHFE::Exec(Option_t *){
+       //
+       // Run the analysis
+       //
+       if(!fESD){
+               AliError("No ESD Event");
+               return;
+       }
+       if(!fMC){
+               AliError("No MC Event");
+               return;
+       }
+       fCFM->SetEventInfo(fMC);
+  fPID->SetMCEvent(fMC);
+
+       //fCFM->CheckEventCuts(AliCFManager::kEvtGenCuts, fMC);
+
+       Double_t pt = 0;
+       Double_t container[3];
+
+       // Loop over the Monte Carlo tracks to see whether we have overlooked any track
+       AliMCParticle *mctrack = 0x0;
+       Int_t nElectrons = 0;
+       for(Int_t imc = fMC->GetNumberOfTracks(); imc--;){
+               mctrack = fMC->GetTrack(imc);
+               container[0] = mctrack->Pt();
+               container[1] = mctrack->Eta();
+    container[2] = mctrack->Phi();
+
+               if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepMCGenerated, mctrack)) continue;
+               fCFM->GetParticleContainer()->Fill(container, AliHFEcuts::kStepMCGenerated);
+               (dynamic_cast<TH1F *>(fQA->At(2)))->Fill(mctrack->Phi() - TMath::Pi());
+               if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepMCInAcceptance, mctrack)) continue;
+               // find the label in the vector
+               fCFM->GetParticleContainer()->Fill(container, AliHFEcuts::kStepMCInAcceptance);
+               nElectrons++;
+       }
+       (dynamic_cast<TH1F *>(fQA->At(3)))->Fill(nElectrons);
+
+       // fCFM->CheckEventCuts(AliCFManager::kEvtRecCuts, fESD);
+       AliESDtrack *track = 0x0;
+       for(Int_t itrack = 0; itrack < fESD->GetNumberOfTracks(); itrack++){
+               track = fESD->GetTrack(itrack);
+               container[0] = track->Pt();
+               container[1] = track->Eta();
+    container[2] = track->Phi();
+               if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepRecKine, track)) continue;
+               fCFM->GetParticleContainer()->Fill(container, AliHFEcuts::kStepRecKine);
+
+               // Check TRD criterions (outside the correction framework)
+               if(track->GetTRDncls()){
+                       (dynamic_cast<TH1F *>(fQA->At(6)))->Fill(track->GetTRDchi2()/track->GetTRDncls());
+                       (dynamic_cast<TH1F *>(fQA->At(1)))->Fill(track->GetAlpha());    // Check the acceptance without tight cuts
+                       (dynamic_cast<TProfile *>(fQA->At(4)))->Fill(container[0], track->GetTRDpidQuality());
+                       (dynamic_cast<TProfile *>(fQA->At(5)))->Fill(container[0], track->GetTRDncls());
+               }
+               if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepRecPrim, track)) continue;
+    fCFM->GetParticleContainer()->Fill(container, AliHFEcuts::kStepRecPrim);
+    if(fCFM->CheckParticleCuts(AliHFEcuts::kStepHFEcuts, track)) continue;
+    fCFM->GetParticleContainer()->Fill(container, AliHFEcuts::kStepHFEcuts);
+    // track accepted, do PID
+               if(!fPID->IsSelected(track)) continue;
+       fCFM->GetParticleContainer()->Fill(container, AliHFEcuts::kStepHFEcuts + 1);
+       }
+       fNEvents->Fill(1);
+
+       // Done!!!
+       PostData(0, fNEvents);
+       PostData(1, fCFM->GetParticleContainer());
+       PostData(2, fQA);
+}
+
+//____________________________________________________________
+void AliAnalysisTaskHFE::Terminate(Option_t *){
+       //
+       // Terminate not implemented at the moment
+       //
+}
+
+//____________________________________________________________
+void AliAnalysisTaskHFE::MakeParticleContainer(){
+  //
+  // Create the particle container for the correction framework manager and 
+  // link it
+  //
+  const Int_t nvar   = 3 ; //number of variables on the grid:pt,eta, phi
+  const Double_t ptmin = 0., ptmax = 10.;
+  const Double_t etamin = -0.9, etamax = 0.9;
+  const Double_t phimin = 0., phimax = 2. * TMath::Pi();
+  
+
+  //arrays for the number of bins in each dimension
+  Int_t iBin[nvar];
+  iBin[0] = 20; //bins in pt
+  iBin[1] =  8; //bins in eta 
+  iBin[2] = 18; // bins in phi
+
+  //arrays for lower bounds :
+  Double_t *binLim1 = new Double_t[iBin[0] + 1];
+  Double_t *binLim2 = new Double_t[iBin[1] + 1];
+  Double_t *binLim3 = new Double_t[iBin[2] + 1];
+
+  //values for bin lower bounds
+  for(Int_t i=0; i<=iBin[0]; i++) binLim1[i]=(Double_t)ptmin + (ptmax-ptmin)/iBin[0]*(Double_t)i; 
+  for(Int_t i=0; i<=iBin[1]; i++) binLim2[i]=(Double_t)etamin  + (etamax-etamin)/iBin[1]*(Double_t)i;
+  for(Int_t i=0; i<=iBin[2]; i++) binLim3[i]=(Double_t)phimin  + (phimax-phimin)/iBin[2]*(Double_t)i;
+
+  //one "container" for MC
+  AliCFContainer* container = new AliCFContainer("container","container for tracks", AliHFEcuts::kNcutSteps + 1, nvar, iBin);
+  //setting the bin limits
+  container -> SetBinLimits(0,binLim1);
+  container -> SetBinLimits(1,binLim2);
+  container -> SetBinLimits(2,binLim3);
+  fCFM->SetParticleContainer(container);
+}
diff --git a/PWG3/hfe/AliAnalysisTaskHFE.h b/PWG3/hfe/AliAnalysisTaskHFE.h
new file mode 100644 (file)
index 0000000..9c0dddb
--- /dev/null
@@ -0,0 +1,58 @@
+/**************************************************************************
+* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+*                                                                        *
+* Author: The ALICE Off-line Project.                                    *
+* Contributors are mentioned in the code where appropriate.              *
+*                                                                        *
+* Permission to use, copy, modify and distribute this software and its   *
+* documentation strictly for non-commercial purposes is hereby granted   *
+* without fee, provided that the above copyright notice appears in all   *
+* copies and that both the copyright notice and this permission notice   *
+* appear in the supporting documentation. The authors make no claims     *
+* about the suitability of this software for any purpose. It is          *
+* provided "as is" without express or implied warranty.                  *
+**************************************************************************/
+#ifndef ALIANALYSISTASKHFE_H
+#define ALIANALYSISTASKHFE_H
+
+#include "AliAnalysisTask.h"
+
+class AliHFEpid;
+class AliHFEcuts;
+class AliCFManager;
+class AliESDEvent;
+class AliESDtrackCuts;
+class AliMCEvent;
+class TH1I; 
+class TList;
+
+class AliAnalysisTaskHFE : public AliAnalysisTask{
+  enum{
+    kIsQAOn = BIT(14)
+  };
+       public:
+               AliAnalysisTaskHFE();
+               ~AliAnalysisTaskHFE();
+
+               virtual void ConnectInputData(Option_t *);
+               virtual void CreateOutputObjects();
+               virtual void Exec(Option_t *);
+               virtual void Terminate(Option_t *);
+
+    void SetQAOn() { SetBit(kIsQAOn, kTRUE); };
+    Bool_t IsQAOn() const { return TestBit(kIsQAOn); };
+
+       private:
+    void MakeParticleContainer();
+
+               AliESDEvent *fESD;                              //! The ESD Event
+               AliMCEvent *fMC;                                  //! The MC Event
+               AliCFManager *fCFM;                             //! Correction Framework Manager
+               AliHFEpid *fPID;         //! PID
+    AliHFEcuts *fCuts;     //! Cut Collection
+               TH1I *fNEvents;                                   //! counter for the number of Events
+               TList *fQA;                                           //! QA histos for the cuts
+
+       ClassDef(AliAnalysisTaskHFE, 1)    // The electron Analysis Task
+};
+#endif
diff --git a/PWG3/hfe/AliHFEcollection.cxx b/PWG3/hfe/AliHFEcollection.cxx
new file mode 100644 (file)
index 0000000..91a0261
--- /dev/null
@@ -0,0 +1,288 @@
+/**************************************************************************
+* 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.                  *
+**************************************************************************/
+
+#include <iostream>
+
+#include <TH1F.h>
+#include <TH2F.h>
+#include <TList.h>
+#include <TString.h>
+#include <TBrowser.h>
+#include <TIterator.h>
+
+#include "AliLog.h"
+#include "AliHFEcollection.h"
+
+using namespace std;
+
+
+ClassImp(AliHFEcollection)
+
+//___________________________________________________________________
+AliHFEcollection::AliHFEcollection():
+  TNamed()
+  , fListE(0x0)
+{
+  //
+  // default constructor
+  //
+
+  fListE = new TList();
+  if(!fListE){
+    AliError("Initialization of the list failed");
+  }
+  else{
+    // list is owner of the objects. Once list is deleted, the objects
+    // it contains will be deleted too
+    fListE->SetOwner(kTRUE);
+  }
+  //Printf("%s:%d,%p",(char*)__FILE__,__LINE__,fInstance);
+  
+}
+//___________________________________________________________________
+AliHFEcollection::AliHFEcollection(char* name, char* title):
+  TNamed(name, title)
+  , fListE(0x0)
+{
+  //
+  // constructor
+  //
+  fListE = new TList();
+  if(!fListE){
+    AliError("Initialization of the list failed");
+  }
+  else{
+    // list is owner of the objects. Once list is deleted, the objects
+    // it contains will be deleted too
+    fListE->SetOwner(kTRUE);
+  }
+}
+//___________________________________________________________________
+AliHFEcollection::AliHFEcollection(const AliHFEcollection &c) :
+  TNamed(c)
+  , fListE(0x0)
+{
+
+  //
+  // copy operator
+  // 
+  
+  c.Copy(*this);
+}
+//___________________________________________________________________
+AliHFEcollection &AliHFEcollection::operator=(const AliHFEcollection &ref)
+{
+  //
+  // Assignment operator
+  //
+  
+  if(this != &ref){
+    ref.Copy(*this);
+  }
+  return *this;
+}
+//___________________________________________________________________
+void AliHFEcollection::Copy(TObject &ref) const {
+  //
+  // Performs the copying of the object
+  //
+  AliHFEcollection &target = dynamic_cast<AliHFEcollection &>(ref);
+
+  target.fListE = fListE;          
+}
+//___________________________________________________________________
+AliHFEcollection::~AliHFEcollection(){
+  AliInfo("DESTRUCTOR");
+}
+//___________________________________________________________________
+Bool_t AliHFEcollection::CreateTH1F(const char* _name, const char* _title, Int_t _nBin, Float_t _nMin, Float_t _nMax){
+  
+  if(!fListE){
+    AliError("No TList pointer ! ");
+    return kFALSE;
+  }
+  else{
+    fListE->Add(new TH1F(_name, _title, _nBin, _nMin, _nMax));
+     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){
+  
+  if(!fListE){
+    AliError("No TList pointer ! ");
+    return kFALSE;
+  }
+  fListE->Add(new TH2F(_name, _title, _nBinX, _nMinX, _nMaxX, _nBinY, _nMinY, _nMaxY));
+  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){
+
+  // create a 1 dimensional array of size [_X]
+  
+  if(!fListE){
+    AliError("No TList pointer ! ");
+    return kFALSE;
+  }
+  if(_X <=0){
+    AliError("can not create array with negative or zero size ");
+    return kFALSE;
+  }
+  TString name;
+  for(Int_t i=0; i<_X; ++i){
+    name = "";
+    name.Append(Form("%s_[%d]", _name, i));
+    //cout<<" -D: name: "<<name.str().c_str()<<endl;
+    //cout<<" -D: nBin: "<<_nBin<<" ,Min: "<<_nMin<<" , Max: "<<_nMax<<endl;
+    CreateTH1F(name.Data(), _title, _nBin, _nMin, _nMax);
+    if(!CheckObject(name.Data())){
+      AliError(Form("Not possible to create object: ", name.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){
+
+  // create a 1 dimensinal array of TH2F histograms with size [_X]
+  if(!fListE){
+    AliError("No TList pointer !");
+    return kFALSE;
+  }
+  if(_X <=0){
+    AliError("can not create array with negative or zero size ");
+    return kFALSE;
+  }
+  TString name;
+  for(Int_t i=0; i<_X; ++i){
+    name = "";
+    name.Append(Form("%s_[%d]", _name, i));
+    //cout<<" -D: name: "<<name<<endl;
+    //cout<<" -D: nBin: "<<_nBin<<" ,Min: "<<_nMin<<" , Max: "<<_nMax<<endl;
+    CreateTH2F(name.Data(), _title, _nBinX, _nMinX, _nMaxX, _nBinY, _nMinY, _nMaxY);
+    if(!CheckObject(name.Data())){
+      AliError(Form("Not possible to create object: %s", name.Data()));
+      return kFALSE;
+    }    
+  }
+  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){
+
+  // create a 2 dimensional array of histograms of size [_X, _Y]
+  if(!fListE){
+    AliError("No TList pointer ! ");
+    return kFALSE;
+  }
+  if(_X <=0 || _Y <=0){
+    AliError("can not create array with negative or zero size ");
+    return kFALSE;
+  }
+  TString name;
+  for(Int_t i=0; i<_X; ++i){
+    for(Int_t j=0; j<_Y; ++j){
+      name = "";
+      name.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(name.Data(), _title, _nBin, _nMin, _nMax);
+      if(!CheckObject(name.Data())){
+             AliError(Form("Not possible to create object: %s", name.Data()));
+             return kFALSE;
+      }
+    }
+  }
+  return kTRUE;
+  
+  
+}
+//___________________________________________________________________
+TObject* AliHFEcollection::Get(const char* _name, Int_t _X){
+  
+  TString name = _name;
+  name.Append(Form("_[%d]", _X));
+  if(!CheckObject(name.Data())){
+    AliError("No such object found in the list");
+    return 0x0;
+  }
+  else{
+    return Get(name.Data());
+  }
+}
+//___________________________________________________________________
+TObject* AliHFEcollection::Get(const char* _name, Int_t _X, Int_t _Y){
+  
+  TString name = _name;
+  name.Append(Form("_[%d][%d]", _X, _Y));
+  if(!CheckObject(name.Data())){
+    AliError("No such object found in the list");
+    AliError(Form("name: %s", name.Data()));
+    return 0x0;
+  }
+  else{
+    return Get(name.Data());
+  }
+}
+//___________________________________________________________________
+Bool_t AliHFEcollection::CheckObject(const char* _name){
+
+  // check wheter the creation of the histogram was succesfull
+  
+  if(!fListE){
+    AliError("No TList pointer ! ");
+    return kFALSE;
+  }
+  
+  if(!fListE->FindObject(_name)){
+    AliError("Creating or Finding the object failed");
+    return kFALSE;
+  }
+  return kTRUE;
+}
+//___________________________________________________________________
+TObject* AliHFEcollection::Get(const char* _name){ 
+  return fListE->FindObject(_name); 
+}
+//___________________________________________________________________
+Long64_t AliHFEcollection::Merge(TCollection *list){
+
+  if(!fListE){
+    AliError("AliHFEcollection::Merge : No TList pointer ! ");
+    return 0;
+  }
+
+  return fListE->Merge(list);
+  
+}
+//____________________________________________________________________
+void AliHFEcollection::Browse(TBrowser *b)
+{
+   // Browse the content of the directory.
+
+   if (b) {
+      TObject *obj = 0;
+      TIter nextin(fListE);
+
+      //Add objects that are only in memory
+      while ((obj = nextin())) {
+         b->Add(obj, obj->GetName());
+      }
+   }
+}
diff --git a/PWG3/hfe/AliHFEcollection.h b/PWG3/hfe/AliHFEcollection.h
new file mode 100644 (file)
index 0000000..cbe4874
--- /dev/null
@@ -0,0 +1,79 @@
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice      
+ */
+
+/************************************************************************
+ *                                                                      *
+ * Class for AliHFEcollection                                           *
+ * Serves as a data container - currently based on internal TList       *
+ *                                                                      *
+ * Authors:                                                             *
+ *   Markus Fasel  <M.Fasel@gsi.de>                                     *
+ *   Matus Kalisky <matus.kalisky@cern.ch>  (contact)                   *
+ ************************************************************************/
+
+/*
+ * Provides an option for storing and creating histograms outside the
+ * analysis class
+ * the performance will be improved once the TMap is used insted of TTree
+ */
+
+/*
+ * vesion: 1.0.1
+ */
+
+
+#ifndef __ALIHFECOLLECTION_H__
+#define __ALIHFECOLLECTION_H__
+
+#ifndef ROOT_TNamed
+#include "TNamed.h"
+#endif
+
+class TList;
+class TCollection;
+class TBrowser;
+
+class AliHFEcollection : public TNamed{
+
+ public:
+  AliHFEcollection();
+  AliHFEcollection(char* name, char* title);
+  AliHFEcollection(const AliHFEcollection &c);
+  AliHFEcollection &operator=(const AliHFEcollection &c);
+  virtual ~AliHFEcollection();
+  
+
+  virtual void Browse(TBrowser*);
+
+  // Set & Create functions
+  Bool_t CreateTH1F(const char* name, const char* title, Int_t nBin, Float_t nMin, Float_t nMax);
+
+  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 CreateTH1Fvector1(Int_t _X, 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 CreateTH1Fvector2(Int_t _X, Int_t _Y, const char* _name, const char* _title, Int_t _nBin, Float_t _nMin, Float_t _nMax);
+  
+
+  Long64_t Merge(TCollection *list);
+
+  // Get functions
+  TList* GetList()  const  { return fListE; }
+  TObject* Get(const char* name); 
+  TObject* Get(const char* name, Int_t _X);
+  TObject* Get(const char* name, Int_t _X, Int_t _Y);
+
+ private:
+  Bool_t CheckObject(const char*);
+   void Copy(TObject &ref) const;
+
+ private:
+  TList*                           fListE;
+
+  ClassDef(AliHFEcollection, 1)
+
+};
+
+#endif
diff --git a/PWG3/hfe/AliHFEcuts.cxx b/PWG3/hfe/AliHFEcuts.cxx
new file mode 100644 (file)
index 0000000..6561c76
--- /dev/null
@@ -0,0 +1,314 @@
+/**************************************************************************
+* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+*                                                                        *
+* Author: The ALICE Off-line Project.                                    *
+* Contributors are mentioned in the code where appropriate.              *
+*                                                                        *
+* Permission to use, copy, modify and distribute this software and its   *
+* documentation strictly for non-commercial purposes is hereby granted   *
+* without fee, provided that the above copyright notice appears in all   *
+* copies and that both the copyright notice and this permission notice   *
+* appear in the supporting documentation. The authors make no claims     *
+* about the suitability of this software for any purpose. It is          *
+* provided "as is" without express or implied warranty.                  *
+**************************************************************************/
+/************************************************************************
+ *                                                                      *
+ * Cut menagement class implemented by the                              *
+ * ALICE Heavy Flavour Electron Group                                   *
+ *                                                                      *
+ * Authors:                                                             *
+ *   Markus Fasel <M.Fasel@gsi.de>                                      *
+ *   Markus Heide <mheide@uni-muenster.de>                              *
+ *   Matus Kalisky <m.kalisky@uni-muenster.de>                          *
+ *                                                                      *
+ ************************************************************************/
+#include <TClass.h>
+#include <TList.h>
+#include <TObjArray.h>
+#include <TString.h>
+
+#include "AliCFAcceptanceCuts.h"
+#include "AliCFCutBase.h"
+#include "AliCFManager.h"
+#include "AliCFParticleGenCuts.h"
+#include "AliCFTrackIsPrimaryCuts.h"
+#include "AliCFTrackKineCuts.h"
+#include "AliCFTrackQualityCuts.h"
+#include "AliESDtrack.h"
+#include "AliMCParticle.h"
+
+#include "AliHFEcuts.h"
+
+ClassImp(AliHFEcuts)
+
+const Int_t AliHFEcuts::kNcutSteps = 5;
+
+//__________________________________________________________________
+AliHFEcuts::AliHFEcuts():
+  fRequirements(0),
+  fMinClustersTPC(0),
+  fMinTrackletsTRD(0),
+  fCutITSPixel(0),
+  fMaxChi2clusterTPC(0.),
+  fMinClusterRatioTPC(0.),
+  fSigmaToVtx(0.),
+  fMaxImpactParamR(0.),
+  fMaxImpactParamZ(0.),
+  fHistQA(0x0),
+  fCutList(0x0)
+{
+  //
+  // Default Constructor
+  //
+  memset(fProdVtx, 0, sizeof(Double_t) * 4);
+  memset(fDCAtoVtx, 0, sizeof(Double_t) * 2);
+  memset(fPtRange, 0, sizeof(Double_t) * 2);
+  fCutList = new TObjArray();
+  fCutList->SetOwner();
+}
+
+//__________________________________________________________________
+AliHFEcuts::AliHFEcuts(const AliHFEcuts &c):
+  TObject(c),
+  fRequirements(c.fRequirements),
+  fMinClustersTPC(c.fMinClustersTPC),
+  fMinTrackletsTRD(c.fMinTrackletsTRD),
+  fCutITSPixel(c.fCutITSPixel),
+  fMaxChi2clusterTPC(c.fMaxChi2clusterTPC),
+  fMinClusterRatioTPC(c.fMinClusterRatioTPC),
+  fSigmaToVtx(c.fSigmaToVtx),
+  fMaxImpactParamR(c.fMaxImpactParamR),
+  fMaxImpactParamZ(c.fMaxImpactParamZ),
+  fHistQA(0x0),
+  fCutList(0x0)
+{
+  //
+  // Copy Constructor
+  //
+  memcpy(fProdVtx, c.fProdVtx, sizeof(Double_t) * 4);
+  memcpy(fDCAtoVtx, c.fDCAtoVtx, sizeof(Double_t) * 4);
+  memcpy(fPtRange, c.fPtRange, sizeof(Double_t) *2);
+  fCutList = dynamic_cast<TObjArray *>(c.fCutList->Clone());
+  fCutList->SetOwner();
+}
+
+//__________________________________________________________________
+AliHFEcuts::~AliHFEcuts(){
+  //
+  // Destruktor
+  //
+  if(fCutList){
+    fCutList->Delete();
+    delete fCutList;
+  }
+  fCutList = 0x0;
+  if(fHistQA) fHistQA->Clear();
+  delete fHistQA;
+}
+
+//__________________________________________________________________
+void AliHFEcuts::Initialize(AliCFManager *cfm){
+  // Call all the setters for the cuts
+  SetParticleGenCutList();
+  SetAcceptanceCutList();
+  SetRecKineCutList();
+  SetRecPrimaryCutList();
+  SetHFElectronCuts();
+  
+  // Connect the cuts
+  cfm->SetParticleCutsList(kStepMCGenerated, dynamic_cast<TObjArray *>(fCutList->FindObject("fPartGenCuts")));
+  cfm->SetParticleCutsList(kStepMCInAcceptance, dynamic_cast<TObjArray *>(fCutList->FindObject("fPartAccCuts")));
+  cfm->SetParticleCutsList(kStepRecKine, dynamic_cast<TObjArray *>(fCutList->FindObject("fPartRecCuts")));
+  cfm->SetParticleCutsList(kStepRecPrim, dynamic_cast<TObjArray *>(fCutList->FindObject("fPartPrimCuts")));
+  cfm->SetParticleCutsList(kStepHFEcuts, dynamic_cast<TObjArray *>(fCutList->FindObject("fPartHFECuts")));
+}
+
+//__________________________________________________________________
+void AliHFEcuts::Initialize(){
+  // Call all the setters for the cuts
+  SetParticleGenCutList();
+  SetAcceptanceCutList();
+  SetRecKineCutList();
+  SetRecPrimaryCutList();
+  SetHFElectronCuts();
+}
+
+//__________________________________________________________________
+void AliHFEcuts::SetParticleGenCutList(){
+  //
+  // Initialize Particle Cuts for Monte Carlo Tracks
+  // Production Vertex: < 1cm (Beampipe)
+  // Particle Species: Electrons
+  // Eta: < 0.9 (TRD-TOF acceptance)
+  //
+  AliCFParticleGenCuts *genCuts = new AliCFParticleGenCuts("fCutsGenMC", "Particle Generation Cuts");
+  genCuts->SetRequireIsCharged();
+  if(IsRequirePrimary()) genCuts->SetRequireIsPrimary();
+  if(IsRequireProdVertex()){
+    genCuts->SetProdVtxRangeX(fProdVtx[0], fProdVtx[1]);
+    genCuts->SetProdVtxRangeY(fProdVtx[2], fProdVtx[3]);
+  }
+  genCuts->SetRequirePdgCode(11/*, kTRUE*/);
+  
+  AliCFTrackKineCuts *kineMCcuts = new AliCFTrackKineCuts("fCutsKineMC","MC Kine Cuts");
+  kineMCcuts->SetPtRange(fPtRange[0], fPtRange[1]);
+  kineMCcuts->SetEtaRange(-0.9, 0.9);
+
+  if(IsInDebugMode()){
+    genCuts->SetQAOn(fHistQA);
+    kineMCcuts->SetQAOn(fHistQA);
+  }
+
+  TObjArray *mcCuts = new TObjArray;
+  mcCuts->SetName("fPartGenCuts");
+  mcCuts->AddLast(genCuts);
+  mcCuts->AddLast(kineMCcuts);
+  fCutList->AddLast(mcCuts);
+}
+
+//__________________________________________________________________
+void AliHFEcuts::SetAcceptanceCutList(){
+  //
+  // Initialize Particle (Monte Carlo) acceptance cuts
+  // Min. Required Hist for Detectors:
+  //          ITS [3]
+  //          TPC [2]
+  //          TRD [12]
+  //          TOF [0]
+  //
+  AliCFAcceptanceCuts *accCuts = new AliCFAcceptanceCuts("fCutsAccMC", "MC Acceptance Cuts");
+  accCuts->SetMinNHitITS(3);
+  accCuts->SetMinNHitTPC(2);
+  accCuts->SetMinNHitTRD(12);
+  if(IsInDebugMode()) accCuts->SetQAOn(fHistQA);
+  
+  TObjArray *PartAccCuts = new TObjArray();
+  PartAccCuts->SetName("fPartAccCuts");
+  PartAccCuts->AddLast(accCuts);
+  fCutList->AddLast(PartAccCuts);
+}
+
+//__________________________________________________________________
+void AliHFEcuts::SetRecKineCutList(){
+  //
+  // Track Kinematics and Quality cuts (Based on the Standard cuts from PWG0)
+  //
+  // Variances:
+  //  y: 2
+  //  z: 2
+  //  sin(phi): 0.5
+  //  tan(theta): 0.5
+  //  1/pt: 2
+  // Min. Number of Clusters:
+  //  TPC: 50
+  // RefitRequired:
+  //  ITS
+  //  TPC
+  // Chi2 per TPC cluster: 3.5
+  //
+  // Kinematics:
+  //  Momentum Range: 100MeV - 20GeV
+  //  Eta: < 0.9 (TRD-TOF acceptance)
+  //
+  AliCFTrackQualityCuts *trackQuality = new AliCFTrackQualityCuts("fCutsQualityRec","REC Track Quality Cuts");
+  trackQuality->SetMinNClusterTPC(fMinClustersTPC);
+  trackQuality->SetMaxChi2PerClusterTPC(fMaxChi2clusterTPC);
+  trackQuality->SetStatus(AliESDtrack::kTPCrefit & AliESDtrack::kITSrefit);
+  trackQuality->SetMaxCovDiagonalElements(2., 2., 0.5, 0.5, 2); 
+
+  AliCFTrackKineCuts *kineCuts = new AliCFTrackKineCuts("fCutsKineRec", "REC Kine Cuts");
+  kineCuts->SetPtRange(fPtRange[0], fPtRange[1]);
+  kineCuts->SetEtaRange(-0.9, 0.9);
+  
+  if(IsInDebugMode()){
+    trackQuality->SetQAOn(fHistQA);
+    kineCuts->SetQAOn(fHistQA);
+  }
+  
+  TObjArray *recCuts = new TObjArray;
+  recCuts->SetName("fPartRecCuts");
+  recCuts->AddLast(trackQuality);
+  recCuts->AddLast(kineCuts);
+  fCutList->AddLast(recCuts);
+}
+
+//__________________________________________________________________
+void AliHFEcuts::SetRecPrimaryCutList(){
+  //
+  // Primary cuts (based on standard cuts from PWG0):
+  //  DCA to Vertex: 
+  //    XY: 3. cm
+  //    Z:  10. cm
+  //  No Kink daughters
+  //
+  AliCFTrackIsPrimaryCuts *primaryCut = new AliCFTrackIsPrimaryCuts("fCutsPrimaryCuts", "REC Primary Cuts");
+  if(IsRequireDCAToVertex()){
+    primaryCut->SetDCAToVertex2D(kTRUE);
+    primaryCut->SetMaxDCAToVertexXY(fDCAtoVtx[0]);
+    primaryCut->SetMaxDCAToVertexZ(fDCAtoVtx[1]);
+  }
+  if(IsRequireSigmaToVertex()){
+    primaryCut->SetRequireSigmaToVertex(kTRUE);
+    primaryCut->SetMaxNSigmaToVertex(fSigmaToVtx);
+  }
+  primaryCut->SetAcceptKinkDaughters(kFALSE);
+  if(IsInDebugMode()) primaryCut->SetQAOn(fHistQA);
+  
+  TObjArray *primCuts = new TObjArray;
+  primCuts->SetName("fPartPrimCuts");
+  primCuts->AddLast(primaryCut);
+  fCutList->AddLast(primCuts);
+}
+
+//__________________________________________________________________
+void AliHFEcuts::SetHFElectronCuts(){
+  //
+  // Special Cuts introduced by the HFElectron Group
+  //
+  AliHFEextraCuts *hfecuts = new AliHFEextraCuts("fCutsHFElectronGroup","Extra cuts from the HFE group");
+  if(IsRequireITSpixel()){
+    hfecuts->SetRequireITSpixel(AliHFEextraCuts::ITSPixel_t(fCutITSPixel));
+  }
+  if(IsRequireMaxImpactParam()){
+    hfecuts->SetMaxImpactParamR(fMaxImpactParamR);
+    hfecuts->SetMaxImpactParamZ(fMaxImpactParamZ);
+  }
+  if(fMinTrackletsTRD) hfecuts->SetMinTrackletsTRD(fMinTrackletsTRD);
+  if(fMinClusterRatioTPC > 0.) hfecuts->SetClusterRatioTPC(fMinClusterRatioTPC);
+  if(IsInDebugMode()) hfecuts->SetQAOn(fHistQA);
+  
+  TObjArray *hfeCuts = new TObjArray;
+  hfeCuts->SetName("fPartHFECuts");
+  hfeCuts->AddLast(hfecuts);
+  fCutList->AddLast(hfeCuts);
+}
+
+//__________________________________________________________________
+void AliHFEcuts::SetDebugMode(){ 
+  //
+  // Switch on QA
+  //
+  SetBit(kDebugMode, kTRUE); 
+  fHistQA = new TList;
+  fHistQA->SetName("CutQAhistograms");
+  fHistQA->SetOwner(kFALSE);
+}
+
+//__________________________________________________________________
+Bool_t AliHFEcuts::CheckParticleCuts(CutStep_t step, TObject *o){
+  //
+  // Checks the cuts without using the correction framework manager
+  // 
+  TString stepnames[kNcutSteps] = {"fPartGenCuts", "fPartAccCuts", "fPartRecCuts", "fPartPrimCuts", "fPartHFECuts"};
+  TObjArray *cuts = dynamic_cast<TObjArray *>(fCutList->FindObject(stepnames[step].Data()));
+  if(!cuts) return kTRUE;
+  TIterator *it = cuts->MakeIterator();
+  AliCFCutBase *mycut;
+  Bool_t status = kTRUE;
+  while((mycut = dynamic_cast<AliCFCutBase *>(it->Next()))){
+    status &= mycut->IsSelected(o);
+  }
+  delete it;
+  return status;
+}
diff --git a/PWG3/hfe/AliHFEcuts.h b/PWG3/hfe/AliHFEcuts.h
new file mode 100644 (file)
index 0000000..f49ba35
--- /dev/null
@@ -0,0 +1,182 @@
+/**************************************************************************
+* 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.                  *
+**************************************************************************/
+#ifndef __ALIHFECUTS_H__
+#define __ALIHFECUTS_H__
+
+#ifndef ROOT_TObject
+#include <TObject.h>
+#endif
+
+#ifndef __ALIHFELECTRONEXTRACUTS_H__
+#include "AliHFEextraCuts.h"
+#endif
+
+class AliCFManager;
+class AliESDtrack;
+class AliMCParticle;
+
+class TObjArray;
+class TList;
+
+class AliHFEcuts : public TObject{
+  enum{
+    kDebugMode = BIT(14)
+      };
+  typedef enum{
+    kPrimary = 0,
+      kProductionVertex = 1,
+      kSigmaToVertex = 2,
+      kDCAToVertex = 3,
+      kITSPixel = 4,
+      kMaxImpactParam = 5
+      } Require_t;
+ public:
+
+  typedef enum{
+    kStepMCGenerated = 0,
+      kStepMCInAcceptance = 1,
+      kStepRecKine = 2,
+      kStepRecPrim = 3,
+      kStepHFEcuts = 4
+      } CutStep_t;
+
+  static const Int_t kNcutSteps;
+
+  AliHFEcuts();
+  AliHFEcuts(const AliHFEcuts &c);
+  AliHFEcuts &operator=(const AliHFEcuts &c);
+  ~AliHFEcuts();
+    
+  void Initialize(AliCFManager *cfm);
+  void Initialize();
+
+  Bool_t CheckParticleCuts(CutStep_t step, TObject *o);
+
+  TList *GetQAhistograms() const { return fHistQA; }
+    
+  void SetDebugMode();
+  void UnsetDebugMode() { SetBit(kDebugMode, kFALSE); }
+  Bool_t IsInDebugMode() const { return TestBit(kDebugMode); };
+    
+  // Getters
+  Bool_t IsRequireITSpixel() const { return TESTBIT(fRequirements, kITSPixel); };
+  Bool_t IsRequireMaxImpactParam() const { return TESTBIT(fRequirements, kMaxImpactParam); };
+  Bool_t IsRequirePrimary() const { return TESTBIT(fRequirements, kPrimary); };
+  Bool_t IsRequireProdVertex() const { return TESTBIT(fRequirements, kProductionVertex); };
+  Bool_t IsRequireSigmaToVertex() const { return TESTBIT(fRequirements, kSigmaToVertex); };
+  Bool_t IsRequireDCAToVertex() const {return TESTBIT(fRequirements, kDCAToVertex); };
+    
+  // Setters
+  inline void SetCutITSpixel(UChar_t cut);
+  void SetMinNClustersTPC(UChar_t minClustersTPC) { fMinClustersTPC = minClustersTPC; }
+  void SetMinNTrackletsTRD(UChar_t minNtrackletsTRD) { fMinTrackletsTRD = minNtrackletsTRD; }
+  void SetMaxChi2perClusterTPC(Double_t chi2) { fMaxChi2clusterTPC = chi2; };
+  inline void SetMaxImpactParam(Double_t radial, Double_t z);
+  void SetMinRatioTPCclusters(Double_t minRatioTPC) { fMinClusterRatioTPC = minRatioTPC; };
+  void SetPtRange(Double_t ptmin, Double_t ptmax){fPtRange[0] = ptmin; fPtRange[1] = ptmax;};
+  inline void SetProductionVertex(Double_t xmin, Double_t xmax, Double_t ymin, Double_t ymax);
+  inline void SetSigmaToVertex(Double_t sig);
+    
+  inline void CreateStandardCuts();
+    
+  // Requirements
+  void SetRequireDCAToVertex() { SETBIT(fRequirements, kDCAToVertex); };
+  void SetRequireIsPrimary() { SETBIT(fRequirements, kPrimary); };
+  void SetRequireITSPixel() { SETBIT(fRequirements, kITSPixel); }
+  void SetRequireMaxImpactParam() { SETBIT(fRequirements, kMaxImpactParam); };
+  void SetRequireProdVetrex() { SETBIT(fRequirements, kProductionVertex); };
+  void SetRequireSigmaToVertex() { SETBIT(fRequirements, kSigmaToVertex); };
+    
+ private:
+  void SetParticleGenCutList();
+  void SetAcceptanceCutList();
+  void SetRecKineCutList();
+  void SetRecPrimaryCutList();
+  void SetHFElectronCuts();
+    
+  ULong64_t fRequirements;     // Bitmap for requirements
+  Double_t fDCAtoVtx[2];       // DCA to Vertex
+  Double_t fProdVtx[4];        // Production Vertex
+  Double_t fPtRange[2];        // pt range
+  UChar_t fMinClustersTPC;     // Min.Number of TPC clusters
+  UChar_t fMinTrackletsTRD;    // Min. Number of TRD tracklets
+  UChar_t fCutITSPixel;        // Cut on ITS pixel
+  Double_t fMaxChi2clusterTPC; // Max Chi2 per TPC cluster
+  Double_t fMinClusterRatioTPC;        // Min. Ratio findable / found TPC clusters
+  Double_t fSigmaToVtx;        // Sigma To Vertex
+  Double_t fMaxImpactParamR;   // Max. Impact Parameter in Radial Direction
+  Double_t fMaxImpactParamZ;   // Max. Impact Parameter in Z Direction
+    
+  TList *fHistQA;              //! QA Histograms
+  TObjArray *fCutList; //! List of cut objects(Correction Framework Manager)
+    
+  ClassDef(AliHFEcuts, 1)   // Container for HFE cuts
+    };
+
+    //__________________________________________________________________
+    void AliHFEcuts::SetProductionVertex(Double_t xmin, Double_t xmax, Double_t ymin, Double_t ymax){
+      // Set the production vertex constraint
+      SetRequireProdVetrex();
+      fProdVtx[0] = xmin;
+      fProdVtx[1] = xmax;
+      fProdVtx[2] = ymin;
+      fProdVtx[3] = ymax;
+    }
+
+//__________________________________________________________________
+void AliHFEcuts::SetSigmaToVertex(Double_t sig){
+  SetRequireSigmaToVertex();
+  fSigmaToVtx = sig;
+}
+
+//__________________________________________________________________
+void AliHFEcuts::SetMaxImpactParam(Double_t radial, Double_t z){
+  SetRequireMaxImpactParam();
+  fMaxImpactParamR = radial;
+  fMaxImpactParamZ = z;
+}
+
+//__________________________________________________________________
+void AliHFEcuts::SetCutITSpixel(UChar_t cut){
+  SetRequireITSPixel();
+  fCutITSPixel = cut;
+}
+
+//__________________________________________________________________
+void AliHFEcuts::CreateStandardCuts(){
+  //
+  // Standard Cuts defined by the HFE Group
+  //
+  SetRequireProdVetrex();
+  fProdVtx[0] = -1;
+  fProdVtx[1] = 1;
+  fProdVtx[2] = -1;
+  fProdVtx[3] = 1;
+  SetRequireDCAToVertex();
+  fDCAtoVtx[0] = 4.;
+  fDCAtoVtx[1] = 10.;
+  fMinClustersTPC = 50;
+  fMinTrackletsTRD = 6;
+  fCutITSPixel = AliHFEextraCuts::kAny;
+  fMaxChi2clusterTPC = 3.5;
+  fMinClusterRatioTPC = 0.6;
+  fPtRange[0] = 0.1;
+  fPtRange[1] = 20.;
+  fSigmaToVtx = 4.;
+  SetRequireMaxImpactParam();
+  fMaxImpactParamR = 3.;
+  fMaxImpactParamZ = 12.;
+}
+#endif
diff --git a/PWG3/hfe/AliHFEextraCuts.cxx b/PWG3/hfe/AliHFEextraCuts.cxx
new file mode 100644 (file)
index 0000000..0043891
--- /dev/null
@@ -0,0 +1,323 @@
+/**************************************************************************
+* 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.                  *
+**************************************************************************/
+/************************************************************************
+ *                                                                      *
+ * Extra cuts implemented by the ALICE Heavy Flavour Electron Group     *
+ * Cuts stored here:                                                    *
+ * - ITS pixels                                                         *
+ * - TPC cluster ratio                                                  *
+ * - TRD tracklets                                                      *
+ *                                                                      *
+ * Authors:                                                             *
+ *   Markus Fasel <M.Fasel@gsi.de>                                      *
+ *                                                                      *
+ ************************************************************************/
+#include <TAxis.h>
+#include <TClass.h>
+#include <TH1F.h>
+#include <TH2F.h>
+#include <TList.h>
+#include <TString.h>
+
+#include "AliESDtrack.h"
+#include "AliLog.h"
+#include "AliMCParticle.h"
+
+#include "AliHFEextraCuts.h"
+
+ClassImp(AliHFEextraCuts)
+
+//______________________________________________________
+AliHFEextraCuts::AliHFEextraCuts(const Char_t *name, const Char_t *title):
+  AliCFCutBase(name, title),
+  fCutCorrelation(0),
+  fRequirements(0),
+  fClusterRatioTPC(0.),
+  fMinTrackletsTRD(0),
+  fPixelITS(0),
+  fQAlist(0x0)
+{
+  //
+  // Default Constructor
+  //
+  memset(fImpactParamCut, 0, sizeof(Float_t) * 4);
+}
+
+//______________________________________________________
+AliHFEextraCuts::AliHFEextraCuts(const AliHFEextraCuts &c):
+  AliCFCutBase(c),
+  fCutCorrelation(c.fCutCorrelation),
+  fRequirements(c.fRequirements),
+  fClusterRatioTPC(c.fClusterRatioTPC),
+  fMinTrackletsTRD(c.fMinTrackletsTRD),
+  fPixelITS(c.fPixelITS),
+  fQAlist(0x0)
+{
+  //
+  // Copy constructor
+  // Performs a deep copy
+  //
+  memcpy(fImpactParamCut, c.fImpactParamCut, sizeof(Float_t) * 4);
+  if(IsQAOn()){
+    fIsQAOn = kTRUE;
+    fQAlist = dynamic_cast<TList *>(c.fQAlist->Clone());
+    fQAlist->SetOwner();
+  }
+}
+
+//______________________________________________________
+AliHFEextraCuts &AliHFEextraCuts::operator=(const AliHFEextraCuts &c){
+  //
+  // Assignment operator
+  //
+  if(this != &c){
+    AliCFCutBase::operator=(c);
+    fCutCorrelation = c.fCutCorrelation;
+    fRequirements = c.fRequirements;
+    fClusterRatioTPC = c.fClusterRatioTPC;
+    fMinTrackletsTRD = c.fMinTrackletsTRD;
+    fPixelITS = c.fPixelITS;
+
+    memcpy(fImpactParamCut, c.fImpactParamCut, sizeof(Float_t) * 4);
+    if(IsQAOn()){
+      fIsQAOn = kTRUE;
+      fQAlist = dynamic_cast<TList *>(c.fQAlist->Clone());
+      fQAlist->SetOwner();
+    }else fQAlist = 0x0;
+  }
+  return *this;
+}
+
+//______________________________________________________
+AliHFEextraCuts::~AliHFEextraCuts(){
+  //
+  // Destructor
+  //
+  if(fQAlist){
+    fQAlist->Delete();
+    delete fQAlist;
+  }
+}
+
+//______________________________________________________
+Bool_t AliHFEextraCuts::IsSelected(TObject *o){
+  //
+  // Steering function for the track selection
+  //
+  if(TString(o->IsA()->GetName()).CompareTo("AliESDtrack") == 0){
+    return CheckESDCuts(dynamic_cast<AliESDtrack *>(o));
+  }
+  return CheckMCCuts(dynamic_cast<AliMCParticle *>(o));
+}
+
+//______________________________________________________
+Bool_t AliHFEextraCuts::CheckESDCuts(AliESDtrack *track){
+  //
+  // Checks cuts on reconstructed tracks
+  // returns true if track is selected
+  // QA histograms are filled before track selection and for
+  // selected tracks after track selection
+  //
+  ULong64_t survivedCut = 0;   // Bitmap for cuts which are passed by the track, later to be compared with fRequirements
+  if(IsQAOn()) FillQAhistosESD(track, kBeforeCuts);
+  // Apply cuts
+  Float_t impact_r, impact_z, ratioTPC;
+  track->GetImpactParameters(impact_r, impact_z);
+  // printf("Check TPC findable clusters: %d, found Clusters: %d\n", track->GetTPCNclsF(), track->GetTPCNcls());
+  ratioTPC = track->GetTPCNclsF() > 0. ? static_cast<Float_t>(track->GetTPCNcls())/static_cast<Float_t>(track->GetTPCNclsF()) : 1.;
+  UChar_t trdTracklets;
+  #ifdef TRUNK
+  trdTracklets = track->GetTRDntrackletsPID();
+  #else
+  trdTracklets = track->GetTRDpidQuality();
+  #endif  
+  UChar_t itsPixel = track->GetITSClusterMap();
+  if(TESTBIT(fRequirements, kMinImpactParamR)){
+    // cut on min. Impact Parameter in Radial direction
+    if(impact_r >= fImpactParamCut[0]) SETBIT(survivedCut, kMinImpactParamR);
+  }
+  if(TESTBIT(fRequirements, kMinImpactParamZ)){
+    // cut on min. Impact Parameter in Z direction
+    if(impact_z >= fImpactParamCut[1]) SETBIT(survivedCut, kMinImpactParamZ);
+  }
+  if(TESTBIT(fRequirements, kMaxImpactParamR)){
+    // cut on max. Impact Parameter in Radial direction
+    if(impact_r <= fImpactParamCut[2]) SETBIT(survivedCut, kMaxImpactParamR);
+  }
+  if(TESTBIT(fRequirements, kMaxImpactParamZ)){
+    // cut on max. Impact Parameter in Z direction
+    if(impact_z <= fImpactParamCut[3]) SETBIT(survivedCut, kMaxImpactParamZ);
+  }
+  if(TESTBIT(fRequirements, kClusterRatioTPC)){
+    // cut on min ratio of found TPC clusters vs findable TPC clusters
+    if(ratioTPC >= fClusterRatioTPC) SETBIT(survivedCut, kClusterRatioTPC);
+  }
+  if(TESTBIT(fRequirements, kMinTrackletsTRD)){
+    // cut on minimum number of TRD tracklets
+    if(trdTracklets >= fMinTrackletsTRD) SETBIT(survivedCut, kMinTrackletsTRD);
+  }
+  if(TESTBIT(fRequirements, kPixelITS)){
+    // cut on ITS pixel layers
+    if(fPixelITS == kFirst)
+    switch(fPixelITS){
+      case kFirst: if(itsPixel & BIT(0)) SETBIT(survivedCut, kPixelITS);
+                  break;
+      case kSecond: if(itsPixel & BIT(1)) SETBIT(survivedCut, kPixelITS);
+                  break;
+      case kBoth: if((itsPixel & BIT(0)) && (itsPixel & BIT(1))) SETBIT(survivedCut, kPixelITS);
+                 break;
+      case kAny: if((itsPixel & BIT(0)) || (itsPixel & BIT(1))) SETBIT(survivedCut, kPixelITS);
+                break;
+      default: break;
+    }
+  }
+  if(fRequirements == survivedCut){
+    //
+    // Track selected
+    //
+    if(IsQAOn()) FillQAhistosESD(track, kAfterCuts);
+    return kTRUE;
+  }
+  if(IsQAOn()) FillCutCorrelation(survivedCut);
+  return kFALSE;
+}
+
+//______________________________________________________
+Bool_t AliHFEextraCuts::CheckMCCuts(AliMCParticle */*track*/){
+  //
+  // Checks cuts on Monte Carlo tracks
+  // returns true if track is selected
+  // QA histograms are filled before track selection and for
+  // selected tracks after track selection
+  //
+  return kTRUE;        // not yet implemented
+}
+
+//______________________________________________________
+void AliHFEextraCuts::FillQAhistosESD(AliESDtrack *track, UInt_t when){
+  //
+  // Fill the QA histograms for ESD tracks
+  // Function can be called before cuts or after cut application (second argument)
+  //
+  TList *container = dynamic_cast<TList *>(fQAlist->At(when));
+  Float_t impact_r, impact_z;
+  track->GetImpactParameters(impact_r, impact_z);
+  (dynamic_cast<TH1F *>(container->At(0)))->Fill(impact_r);
+  (dynamic_cast<TH1F *>(container->At(1)))->Fill(impact_z);
+  // printf("TPC findable clusters: %d, found Clusters: %d\n", track->GetTPCNclsF(), track->GetTPCNcls());
+  (dynamic_cast<TH1F *>(container->At(2)))->Fill(track->GetTPCNclsF() > 0. ? static_cast<Float_t>(track->GetTPCNcls())/static_cast<Float_t>(track->GetTPCNclsF()) : 1.);
+  #ifdef TRUNK
+  (dynamic_cast<TH1F *>(container->At(3)))->Fill(track->GetTRDntrackletsPID());
+  #else
+  (dynamic_cast<TH1F *>(container->At(3)))->Fill(track->GetTRDpidQuality());
+  #endif
+  UChar_t itsPixel = track->GetITSClusterMap();
+  TH1 *pixelHist = dynamic_cast<TH1F *>(container->At(4));
+  Int_t firstEntry = pixelHist->GetXaxis()->GetFirst();
+  if(!((itsPixel & BIT(0)) || (itsPixel & BIT(1))))
+    pixelHist->Fill(firstEntry + 3);
+  else{
+    if(itsPixel & BIT(0)){
+      pixelHist->Fill(firstEntry);
+      if(itsPixel & BIT(1)) pixelHist->Fill(firstEntry + 2);
+      else pixelHist->Fill(firstEntry + 4);
+    }
+    if(itsPixel & BIT(1)){
+      pixelHist->Fill(firstEntry + 1);
+      if(!(itsPixel & BIT(0))) pixelHist->Fill(firstEntry + 5);
+    }
+  }
+}
+
+// //______________________________________________________
+// void AliHFEextraCuts::FillQAhistosMC(AliMCParticle *track, UInt_t when){
+//   //
+//   // Fill the QA histograms for MC tracks
+//   // Function can be called before cuts or after cut application (second argument)
+//   // Not yet implemented
+//   //
+// }
+
+//______________________________________________________
+void AliHFEextraCuts::FillCutCorrelation(ULong64_t survivedCut){
+  //
+  // Fill cut correlation histograms for tracks that didn't pass cuts
+  //
+  TH2 *correlation = dynamic_cast<TH2F *>(fQAlist->At(2));
+  for(Int_t icut = 0; icut < kNcuts; icut++){
+    if(!TESTBIT(fRequirements, icut)) continue;
+    for(Int_t jcut = icut; jcut < kNcuts; jcut++){
+      if(!TESTBIT(fRequirements, jcut)) continue;
+      if(TESTBIT(survivedCut, icut) && TESTBIT(survivedCut, jcut))
+       correlation->Fill(icut, jcut);
+    }
+  }
+}
+
+//______________________________________________________
+void AliHFEextraCuts::AddQAHistograms(TList *qaList){
+  //
+  // Add QA histograms
+  // For each cut a histogram before and after track cut is created
+  // Histos before respectively after cut are stored in different lists
+  // Additionally a histogram with the cut correlation is created and stored
+  // in the top directory
+  //
+  TList *histos[2];
+  TH1 *histo1D = 0x0;
+  TH2 *histo2D = 0x0;
+  histos[0] = new TList();
+  histos[0]->SetName("BeforeCut");
+  histos[0]->SetOwner();
+  histos[1] = new TList();
+  histos[1]->SetName("AfterCut");
+  histos[1]->SetOwner();
+  TString cutstr[2] = {"before", "after"};
+  for(Int_t icond = 0; icond < 2; icond++){
+    histos[icond]->AddAt((histo1D = new TH1F(Form("impactParamR%s", cutstr[icond].Data()), "Radial Impact Parameter", 100, 0, 10)), 0);
+    histo1D->GetXaxis()->SetTitle("Impact Parameter");
+    histo1D->GetYaxis()->SetTitle("Number of Tracks");
+    histos[icond]->AddAt((histo1D = new TH1F(Form("impactParamZ%s", cutstr[icond].Data()), "Z Impact Parameter", 200, 0, 20)), 1);
+    histo1D->GetXaxis()->SetTitle("Impact Parameter");
+    histo1D->GetYaxis()->SetTitle("Number of Tracks");
+    histos[icond]->AddAt((histo1D = new TH1F(Form("tpcClr%s", cutstr[icond].Data()), "Cluster Ratio TPC", 10, 0, 1)), 2);
+    histo1D->GetXaxis()->SetTitle("Cluster Ratio TPC");
+    histo1D->GetYaxis()->SetTitle("Number of Tracks");
+    histos[icond]->AddAt((histo1D = new TH1F(Form("trdTracklets%s", cutstr[icond].Data()), "Number of TRD tracklets", 7, 0, 7)), 3);
+    histo1D->GetXaxis()->SetTitle("Number of TRD Tracklets");
+    histo1D->GetYaxis()->SetTitle("Number of Tracks");
+    histos[icond]->AddAt((histo1D = new TH1F(Form("itsPixel%s", cutstr[icond].Data()), "ITS Pixel Hits", 6, 0, 6)), 4);
+    histo1D->GetXaxis()->SetTitle("ITS Pixel");
+    histo1D->GetYaxis()->SetTitle("Number of Tracks");
+    Int_t first = histo1D->GetXaxis()->GetFirst();
+    TString binNames[6] = { "First", "Second", "Both", "None", "Exclusive First", "Exclusive Second"};
+    for(Int_t ilabel = 0; ilabel < 6; ilabel++)
+      histo1D->GetXaxis()->SetBinLabel(first + ilabel, binNames[ilabel].Data());
+  }
+  fQAlist = new TList();
+  fQAlist->SetOwner();
+  fQAlist->SetName("HFelectronExtraCuts");
+  fQAlist->AddAt(histos[0], 0);
+  fQAlist->AddAt(histos[1], 1);
+  // Add cut correlation
+  fQAlist->AddAt((histo2D = new TH2F("cutcorrellation", "Cut Correlation", kNcuts, 0, kNcuts - 1, kNcuts, 0, kNcuts -1)), 2);
+  TString labels[kNcuts] = {"MinImpactParamR", "MaxImpactParamR", "MinImpactParamZ", "MaxImpactParamZ", "ClusterRatioTPC", "MinTrackletsTRD", "ITSpixel"};
+  Int_t firstx = histo2D->GetXaxis()->GetFirst(), firsty = histo2D->GetYaxis()->GetFirst();
+  for(Int_t icut = 0; icut < kNcuts; icut++){
+    histo2D->GetXaxis()->SetBinLabel(firstx + icut, labels[icut].Data());
+    histo2D->GetYaxis()->SetBinLabel(firsty + icut, labels[icut].Data());
+  }
+  qaList->AddLast(fQAlist);
+}
diff --git a/PWG3/hfe/AliHFEextraCuts.h b/PWG3/hfe/AliHFEextraCuts.h
new file mode 100644 (file)
index 0000000..8a22fff
--- /dev/null
@@ -0,0 +1,131 @@
+/**************************************************************************
+* 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.                  *
+**************************************************************************/
+#ifndef __ALIHFEEXTRACUTS_H__
+#define __ALIHFEEXTRACUTS_H__
+
+// #ifndef ALICFCUTBASE_H
+#include "AliCFCutBase.h"
+// #endif
+
+class TList;
+
+class AliESDtrack;
+class AliMCParticle;
+
+class AliHFEextraCuts : public AliCFCutBase{
+  public:
+    typedef enum{
+      kFirst = 0,
+      kSecond = 1,
+      kBoth = 2,
+      kNone = 3,
+      kAny = 4
+    } ITSPixel_t;
+    AliHFEextraCuts(const Char_t *name, const Char_t *title);
+    AliHFEextraCuts(const AliHFEextraCuts &c);
+    AliHFEextraCuts &operator=(const AliHFEextraCuts &c);
+    ~AliHFEextraCuts();
+    
+    virtual Bool_t IsSelected(TObject *o);
+    virtual Bool_t IsSelected(TList *) { return kTRUE; };
+
+    inline void SetClusterRatioTPC(Double_t ratio);
+    inline void SetRequireITSpixel(ITSPixel_t pixel);
+    inline void SetMinImpactParamR(Double_t impactParam);
+    inline void SetMaxImpactParamR(Double_t impactParam);
+    inline void SetMinImpactParamZ(Double_t impactParam);
+    inline void SetMaxImpactParamZ(Double_t impactParam);
+    inline void SetMinTrackletsTRD(Int_t minTracklets);
+    
+  protected:
+    virtual void AddQAHistograms(TList *qaList);
+    Bool_t CheckESDCuts(AliESDtrack *track);
+    Bool_t CheckMCCuts(AliMCParticle */*track*/);
+    void FillQAhistosESD(AliESDtrack *track, UInt_t when);
+//     void FillQAhistosMC(AliMCParticle *track, UInt_t when);
+    void FillCutCorrelation(ULong64_t survivedCut);
+    
+  private:
+    typedef enum{
+      kMinImpactParamR = 0,
+      kMaxImpactParamR = 1,
+      kMinImpactParamZ = 2,
+      kMaxImpactParamZ = 3,
+      kClusterRatioTPC = 4,
+      kMinTrackletsTRD = 5,
+      kPixelITS = 6,
+      kNcuts = 7
+    } Cut_t;
+    enum{
+      //
+      // Common Constants
+      //
+      kBeforeCuts =0,
+      kAfterCuts = 1
+    };
+    ULong64_t fCutCorrelation;         // Cut Correlation
+    ULong64_t fRequirements;           // Cut Requirements
+    Float_t fImpactParamCut[4];                // Impact Parmameter Cut
+    Float_t fClusterRatioTPC;          // Ratio of findable vs. found clusters in TPC
+    UChar_t fMinTrackletsTRD;          // Min. Number of Tracklets inside TRD
+    UChar_t fPixelITS;                 // Cut on ITS Pixels
+    
+    TList *fQAlist;                    //! Directory for QA histograms
+  
+  ClassDef(AliHFEextraCuts, 1)      // Additional cuts implemented by the ALICE HFE group
+};
+
+//__________________________________________________________
+void AliHFEextraCuts::SetClusterRatioTPC(Double_t ratio) {
+  SETBIT(fRequirements, kClusterRatioTPC);
+  fClusterRatioTPC = ratio; 
+}
+
+//__________________________________________________________
+void AliHFEextraCuts::SetRequireITSpixel(ITSPixel_t pixel) {
+  SETBIT(fRequirements, kPixelITS);
+  fPixelITS = pixel; 
+}
+
+//__________________________________________________________
+void AliHFEextraCuts::SetMinImpactParamR(Double_t impactParam){
+  SETBIT(fRequirements, kMinImpactParamR);
+  fImpactParamCut[0] = impactParam;
+}
+
+//__________________________________________________________
+void AliHFEextraCuts::SetMaxImpactParamR(Double_t impactParam){
+  SETBIT(fRequirements, kMaxImpactParamR);
+  fImpactParamCut[1] = impactParam;
+}
+
+//__________________________________________________________
+void AliHFEextraCuts::SetMinImpactParamZ(Double_t impactParam){
+  SETBIT(fRequirements, kMinImpactParamZ);
+  fImpactParamCut[2] = impactParam;
+}
+
+//__________________________________________________________
+void AliHFEextraCuts::SetMaxImpactParamZ(Double_t impactParam){
+  SETBIT(fRequirements, kMaxImpactParamZ);
+  fImpactParamCut[3] = impactParam;
+}
+
+//__________________________________________________________
+void AliHFEextraCuts::SetMinTrackletsTRD(Int_t minTracklets){
+  SETBIT(fRequirements, kMinTrackletsTRD);
+  fMinTrackletsTRD = minTracklets;
+}
+#endif
diff --git a/PWG3/hfe/AliHFEpid.cxx b/PWG3/hfe/AliHFEpid.cxx
new file mode 100644 (file)
index 0000000..ef26747
--- /dev/null
@@ -0,0 +1,207 @@
+/**************************************************************************
+* 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.                  *
+**************************************************************************/
+/************************************************************************
+ *                                                                      *
+ * PID Steering Class                                                   *
+ * Interface to the user task                                           *
+ *                                                                      *
+ * Authors:                                                             *
+ *   Markus Fasel <M.Fasel@gsi.de>                                      *
+ *                                                                      *
+ ************************************************************************/
+#include <TClass.h>
+#include <TIterator.h>
+#include <TList.h>
+#include <TObjArray.h>
+#include <TObjString.h>
+#include <TString.h>
+
+#include "AliESDtrack.h"
+
+#include "AliHFEpid.h"
+#include "AliHFEpidBase.h"
+#include "AliHFEpidTPC.h"
+#include "AliHFEpidTRD.h"
+#include "AliHFEpidTOF.h"
+#include "AliHFEpidMC.h"
+
+ClassImp(AliHFEpid)
+
+//____________________________________________________________
+AliHFEpid::AliHFEpid():
+  fEnabledDetectors(0),
+  fQAlist(0x0)
+{
+  //
+  // Default constructor
+  //
+  memset(fDetectorPID, 0, sizeof(AliHFEpidBase *) * kNdetectorPID);
+}
+
+//____________________________________________________________
+AliHFEpid::AliHFEpid(const AliHFEpid &c):
+  TObject(c),
+  fEnabledDetectors(c.fEnabledDetectors),
+  fQAlist(0x0)
+{
+  //
+  // Copy Constructor
+  //
+  memset(fDetectorPID, 0, sizeof(AliHFEpidBase *) * kNdetectorPID);
+  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(c.fDetectorPID[kTRDpid])
+    fDetectorPID[kTRDpid] = new AliHFEpidTRD(*(dynamic_cast<AliHFEpidTRD *>(c.fDetectorPID[kTOFpid])));
+  if(c.fDetectorPID[kTOFpid])
+    fDetectorPID[kTOFpid] = new AliHFEpidTOF(*(dynamic_cast<AliHFEpidTOF *>(c.fDetectorPID[kTOFpid])));
+  if(c.IsQAOn()) SetQAOn();
+  if(c.HasMCData()) SetHasMCData(kTRUE);
+  for(Int_t idet = 0; idet < kNdetectorPID; idet++){
+    if(c.IsQAOn() && fDetectorPID[idet]) fDetectorPID[idet]->SetQAOn(fQAlist);
+    if(c.HasMCData() && fDetectorPID[idet]) fDetectorPID[idet]->SetHasMCData(kTRUE);
+  }
+}
+
+//____________________________________________________________
+AliHFEpid& AliHFEpid::operator=(const AliHFEpid &c){
+  //
+  // Assignment operator
+  //
+  TObject::operator=(c);
+
+  if(this != &c){
+    fEnabledDetectors = c.fEnabledDetectors;
+    fQAlist = 0x0;
+  
+    memset(fDetectorPID, 0, sizeof(AliHFEpidBase *) * kNdetectorPID);
+    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(c.fDetectorPID[kTRDpid])
+      fDetectorPID[kTRDpid] = new AliHFEpidTRD(*(dynamic_cast<AliHFEpidTRD *>(c.fDetectorPID[kTOFpid])));
+    if(c.fDetectorPID[kTOFpid])
+      fDetectorPID[kTOFpid] = new AliHFEpidTOF(*(dynamic_cast<AliHFEpidTOF *>(c.fDetectorPID[kTOFpid])));
+    if(c.IsQAOn()) SetQAOn();
+    if(c.HasMCData()) SetHasMCData(kTRUE);
+    for(Int_t idet = 0; idet < kNdetectorPID; idet++){
+      if(c.IsQAOn() && fDetectorPID[idet]) fDetectorPID[idet]->SetQAOn(fQAlist);
+      if(c.HasMCData() && fDetectorPID[idet]) fDetectorPID[idet]->SetHasMCData();
+    }
+  }
+  return *this; 
+}
+
+//____________________________________________________________
+AliHFEpid::~AliHFEpid(){
+  //
+  // Destructor
+  //
+  if(fQAlist) delete fQAlist; fQAlist = 0x0;  // Each detector has to care about its Histograms
+  for(Int_t idet = 0; idet < kNdetectorPID; idet++){
+    if(fDetectorPID[idet]) delete fDetectorPID[idet];
+  }
+}
+
+//____________________________________________________________
+Bool_t AliHFEpid::InitializePID(TString detectors){
+  //
+  // Initializes PID Object:
+  // + Defines which detectors to use
+  // + Initializes Detector PID objects
+  // + Handles QA
+  //
+  fDetectorPID[kMCpid] = new AliHFEpidMC("Monte Carlo PID"); // Always there
+  SETBIT(fEnabledDetectors, kMCpid);
+  
+  TObjArray *detsEnabled = detectors.Tokenize(":");
+  TIterator *detIterator = detsEnabled->MakeIterator();
+  TObjString *det = 0x0;
+  while((det = dynamic_cast<TObjString *>(detIterator->Next()))){
+    if(det->String().CompareTo("TPC") == 0){
+      fDetectorPID[kTPCpid] = new AliHFEpidTPC("TPC PID");
+      SETBIT(fEnabledDetectors, kTPCpid);
+    } else if(det->String().CompareTo("TRD") == 0){
+      fDetectorPID[kTRDpid] = new AliHFEpidTRD("TRD PID");
+      SETBIT(fEnabledDetectors, kTRDpid);
+    } else if(det->String().CompareTo("TOF") == 0){
+      fDetectorPID[kTOFpid] = new AliHFEpidTOF("TOF PID");
+      SETBIT(fEnabledDetectors, kTOFpid);
+    }
+    // Here is still space for ESD PID
+  }
+  // Initialize PID Objects
+  Bool_t status = kTRUE;
+  for(Int_t idet = 0; idet < kNdetectorPID; idet++){
+    if(fDetectorPID[idet]){ 
+      status &= fDetectorPID[idet]->InitializePID();
+      if(IsQAOn() && status) fDetectorPID[idet]->SetQAOn(fQAlist);
+      if(HasMCData() && status) fDetectorPID[idet]->SetHasMCData();
+    }
+  }
+  return status;
+}
+
+//____________________________________________________________
+Bool_t AliHFEpid::IsSelected(AliVParticle *track){
+  //
+  // Steers PID decision for single detectors respectively combined
+  // PID decision
+  //
+  
+  if(TString(track->IsA()->GetName()).CompareTo("AliMCparticle") == 0){
+    return (TMath::Abs(fDetectorPID[kMCpid]->IsSelected(track)) == 11);
+  }
+  if(TString(track->IsA()->GetName()).CompareTo("AliESDtrack") == 0){
+    if(TESTBIT(fEnabledDetectors, kTPCpid) && TESTBIT(fEnabledDetectors, kTOFpid)){
+      // case TPC-TOF
+      return MakePID_TPC_TOF(dynamic_cast<AliESDtrack *>(track));
+    } else if(TESTBIT(fEnabledDetectors, kTPCpid)){
+      return (TMath::Abs(fDetectorPID[kTPCpid]->IsSelected(track)) ==11);
+    } else if(TESTBIT(fEnabledDetectors, kTRDpid)){
+      return (TMath::Abs(fDetectorPID[kTRDpid]->IsSelected(track)) ==11);
+    } else if(TESTBIT(fEnabledDetectors, kTOFpid)){
+      return (TMath::Abs(fDetectorPID[kTOFpid]->IsSelected(track)) ==11);
+    }
+    
+  }
+  return kFALSE;
+}
+
+//____________________________________________________________
+Bool_t AliHFEpid::MakePID_TPC_TOF(AliESDtrack *track){
+  //
+  // Combines TPC and TOF PID decision
+  //
+  if(fDetectorPID[kTOFpid]->IsSelected(track)) return fDetectorPID[kTPCpid]->IsSelected(track);
+  return kFALSE;
+}
+
+//____________________________________________________________
+void AliHFEpid::SetQAOn(){
+  //
+  // Switch on QA
+  //
+  SetBit(kIsQAOn);
+  fQAlist = new TList;
+  fQAlist->SetName("PIDqa");
+}
+
+void AliHFEpid::SetMCEvent(AliMCEvent *event){
+  for(Int_t idet = 0; idet < kNdetectorPID; idet++)
+    if(fDetectorPID[idet]) fDetectorPID[idet]->SetMCEvent(event);
+}
diff --git a/PWG3/hfe/AliHFEpid.h b/PWG3/hfe/AliHFEpid.h
new file mode 100644 (file)
index 0000000..90a57b9
--- /dev/null
@@ -0,0 +1,68 @@
+/**************************************************************************
+* 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.                  *
+**************************************************************************/
+#ifndef __ALIHFEPID_H__
+#define __ALIHFEPID_H__
+
+#ifndef ROOT_TObject
+#include <TObject.h>
+#endif
+
+class AliHFEpidBase;
+class AliESDtrack;
+class AliVParticle;
+class AliMCEvent;
+
+class TList;
+
+class AliHFEpid : public TObject{
+  enum{
+    kIsQAOn = BIT(14),
+    kHasMCData = BIT(15)
+  };
+  enum{
+    kMCpid = 0,
+    kESDpid = 1,
+    kTPCpid = 2,
+    kTRDpid = 3,
+    kTOFpid = 4,
+    kNdetectorPID = 5
+  };
+  public:
+    AliHFEpid();
+    AliHFEpid(const AliHFEpid &c);
+    AliHFEpid &operator=(const AliHFEpid &c);
+    ~AliHFEpid();
+    
+    Bool_t InitializePID(TString detectors);
+    Bool_t IsSelected(AliVParticle *track);
+    void SetMCEvent(AliMCEvent *mc);
+
+    Bool_t IsQAOn() const { return TestBit(kIsQAOn); };
+    Bool_t HasMCData() const { return TestBit(kHasMCData); };
+    void SetQAOn();
+    void SetHasMCData(Bool_t hasMCdata = kTRUE) { SetBit(kHasMCData, hasMCdata); };
+    TList *GetQAhistograms() const { return fQAlist; };
+
+  protected:
+    Bool_t MakePID_TPC_TOF(AliESDtrack *track);
+  private:
+    AliHFEpidBase *fDetectorPID[kNdetectorPID];    //! Detector PID classes
+    UInt_t fEnabledDetectors;             // Enabled Detectors
+    TList *fQAlist;                       //! QA histograms
+
+  ClassDef(AliHFEpid, 1)      // Steering class for Electron ID
+};
+
+#endif
diff --git a/PWG3/hfe/AliHFEpidBase.cxx b/PWG3/hfe/AliHFEpidBase.cxx
new file mode 100644 (file)
index 0000000..6118013
--- /dev/null
@@ -0,0 +1,93 @@
+/**************************************************************************
+* 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.                  *
+**************************************************************************/
+/************************************************************************
+ *                                                                      *
+ * Abstract PID base class for Detector PID classes                     *
+ * Supplies detector PID classes with basic informations (i.e. Debug    *
+ * Level)                                                               *
+ *                                                                      *
+ * Authors:                                                             *
+ *   Markus Fasel <M.Fasel@gsi.de>                                      *
+ *                                                                      *
+ ************************************************************************/
+#include <TParticle.h>
+
+#include "AliESDtrack.h"
+#include "AliMCParticle.h"
+#include "AliMCEvent.h"
+
+#include "AliHFEpidBase.h"
+
+ClassImp(AliHFEpidBase)
+
+//___________________________________________________________________
+AliHFEpidBase::AliHFEpidBase(const Char_t *name):
+  TNamed(name, ""),
+  fMCEvent(0x0),
+  fDebugLevel(0)
+{
+  //
+  // Default constructor
+  //
+}
+
+//___________________________________________________________________
+AliHFEpidBase::AliHFEpidBase(const AliHFEpidBase &c):
+  TNamed(),
+  fMCEvent(0x0),
+  fDebugLevel(0)
+{
+  //
+  //Copy constructor
+  //
+  c.Copy(*this);
+}
+
+//___________________________________________________________________
+AliHFEpidBase &AliHFEpidBase::operator=(const AliHFEpidBase &ref){
+  //
+  // Assignment operator
+  //
+  if(this != &ref){
+    ref.Copy(*this);
+  }
+
+  return *this;
+  }
+
+//___________________________________________________________________
+void AliHFEpidBase::Copy(TObject &ref) const {
+  AliHFEpidBase &target = dynamic_cast<AliHFEpidBase &>(ref);
+
+  target.fMCEvent = fMCEvent;
+  target.fDebugLevel = fDebugLevel;
+
+  TNamed::Copy(ref);
+}
+
+//___________________________________________________________________
+Int_t AliHFEpidBase::GetPdgCode(AliVParticle *track){
+  //
+  // returns the MC PDG code of the particle species
+  //
+  if(!fMCEvent) return 0;
+  AliMCParticle *mctrack = 0x0;
+  if(TString(track->IsA()->GetName()).CompareTo("AliESDtrack") == 0)
+    mctrack = fMCEvent->GetTrack(TMath::Abs((dynamic_cast<AliESDtrack *>(track))->GetLabel()));
+  else if(TString(track->IsA()->GetName()).CompareTo("AliESDtrack") == 0)
+    mctrack = dynamic_cast<AliMCParticle *>(track);
+  if(!mctrack) return 0;
+  return mctrack->Particle()->GetPdgCode();
+}
diff --git a/PWG3/hfe/AliHFEpidBase.h b/PWG3/hfe/AliHFEpidBase.h
new file mode 100644 (file)
index 0000000..4f070e1
--- /dev/null
@@ -0,0 +1,71 @@
+/**************************************************************************
+* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+*                                                                        *
+* Author: The ALICE Off-line Project.                                    *
+* Contributors are mentioned in the code where appropriate.              *
+*                                                                        *
+* Permission to use, copy, modify and distribute this software and its   *
+* documentation strictly for non-commercial purposes is hereby granted   *
+* without fee, provided that the above copyright notice appears in all   *
+* copies and that both the copyright notice and this permission notice   *
+* appear in the supporting documentation. The authors make no claims     *
+* about the suitability of this software for any purpose. It is          *
+* provided "as is" without express or implied warranty.                  *
+**************************************************************************/
+#ifndef __ALIHFEPIDBASE_H__
+#define __ALIHFEPIDBASE_H__
+ #ifndef ROOT_TNamed
+ #include <TNamed.h>
+ #endif
+
+class TList;
+class AliVParticle;
+class AliMCEvent;
+
+class AliHFEpidBase : public TNamed{
+  enum{
+    kQAon = BIT(14),
+    kHasMCData = BIT(15)
+  };
+  public:
+    AliHFEpidBase(const Char_t *name);
+    AliHFEpidBase(const AliHFEpidBase &c);
+    AliHFEpidBase &operator=(const AliHFEpidBase &c);
+    virtual ~AliHFEpidBase() {};
+    // Framework functions that have to be implemented by the detector PID classes
+    virtual Bool_t InitializePID() = 0;
+    virtual Int_t IsSelected(AliVParticle *track) = 0;
+    virtual Bool_t HasQAhistos() const = 0;
+
+    Int_t GetDebugLevel() const { return fDebugLevel; };
+    Bool_t IsQAon() const { return TestBit(kQAon);};
+    Bool_t HasMCData() const { return TestBit(kHasMCData); };
+
+    void SetDebugLevel(Int_t debugLevel) { fDebugLevel = debugLevel; }; 
+    inline void SetQAOn(TList *fQAlist);
+    void SetHasMCData(Bool_t hasMCdata = kTRUE) { SetBit(kHasMCData,hasMCdata); };
+    void SetMCEvent(AliMCEvent *mcEvent) { fMCEvent = mcEvent; };
+
+  protected:
+    void Copy(TObject &ref) const;
+    virtual void AddQAhistograms(TList *){};
+    Int_t GetPdgCode(AliVParticle *track);
+  private:
+    AliMCEvent *fMCEvent;       //! Monte Carlo Event
+    Int_t fDebugLevel;          // Debug Level
+
+    ClassDef(AliHFEpidBase, 1)    // Base class for detector Electron ID
+};
+
+//___________________________________________________________________
+void AliHFEpidBase::SetQAOn(TList *qaList){
+  //
+  // Initialize QA for Detector PID class
+  //
+  if(HasQAhistos()){
+    SetBit(kQAon, kTRUE);
+    AddQAhistograms(qaList);
+  }
+}
+#endif
diff --git a/PWG3/hfe/AliHFEpidMC.cxx b/PWG3/hfe/AliHFEpidMC.cxx
new file mode 100644 (file)
index 0000000..1319cc8
--- /dev/null
@@ -0,0 +1,64 @@
+/**************************************************************************
+* 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 TRD PID                                                    *
+ * Implements the abstract base class AliHFEpidBase                     *
+ * Make PID does the PID decision                                       *
+ * Class further contains TRD specific cuts and QA histograms           *
+ *                                                                      *
+ * Authors:                                                             *
+ *   Markus Fasel <M.Fasel@gsi.de>                                      *
+ *                                                                      *
+ ************************************************************************/
+#include <TMath.h>
+#include <TParticle.h>
+
+#include "AliMCParticle.h"
+#include "AliVParticle.h"
+
+#include "AliHFEpidMC.h"
+
+ClassImp(AliHFEpidMC)
+
+//___________________________________________________________________
+AliHFEpidMC::AliHFEpidMC(const Char_t *name):
+  AliHFEpidBase(name)
+{
+  //
+  // Default constructor
+  //
+}
+
+//___________________________________________________________________
+Bool_t AliHFEpidMC::InitializePID(){
+  // 
+  // Implementation of the framework function InitializePID
+  // Not yet anything to implement in case of MC PID
+  //
+  return kTRUE;
+}
+
+//___________________________________________________________________
+Int_t AliHFEpidMC::IsSelected(AliVParticle *track){
+  //
+  // PID decision for Monte Carlo particles
+  // return true if PDG Code is +/-11 (electron)
+  // otherwise return false
+  //
+  AliMCParticle *mctrack = 0x0;
+  if(!(mctrack = dynamic_cast<AliMCParticle *>(track))) return 0;
+  return mctrack->Particle()->GetPdgCode();
+}
diff --git a/PWG3/hfe/AliHFEpidMC.h b/PWG3/hfe/AliHFEpidMC.h
new file mode 100644 (file)
index 0000000..b231847
--- /dev/null
@@ -0,0 +1,38 @@
+/**************************************************************************
+* 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.                  *
+**************************************************************************/
+#ifndef __ALIHFEPIDMC_H__
+#define __ALIHFEPIDMC_H__
+
+ #ifndef __ALIHFEPIDBASE_H__
+ #include "AliHFEpidBase.h"
+ #endif
+
+class AliVParticle;
+
+class AliHFEpidMC : public AliHFEpidBase{
+  public:
+    AliHFEpidMC(const Char_t *name);
+    virtual ~AliHFEpidMC(){};
+    
+    virtual Bool_t InitializePID();
+    virtual Int_t IsSelected(AliVParticle *track);
+    virtual Bool_t HasQAhistos() const { return kFALSE; };
+
+  private:
+
+  ClassDef(AliHFEpidMC, 1)    // MC electron ID class
+};
+
+#endif
diff --git a/PWG3/hfe/AliHFEpidTOF.cxx b/PWG3/hfe/AliHFEpidTOF.cxx
new file mode 100644 (file)
index 0000000..ab4b5cc
--- /dev/null
@@ -0,0 +1,177 @@
+/**************************************************************************
+* 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.                  *
+**************************************************************************/
+
+#include <TH2F.h>
+#include <TList.h>
+#include <TMath.h>
+
+#include "AliESDtrack.h"
+#include "AliVParticle.h"
+#include "AliPID.h"
+
+#include "AliHFEpidTOF.h"
+#include "AliHFEpidBase.h"
+
+
+ClassImp(AliHFEpidTOF)
+  
+//___________________________________________________________________
+AliHFEpidTOF::AliHFEpidTOF(const Char_t *name):
+  AliHFEpidBase(name)
+  , fPID(0x0)
+  , fQAList(0x0)
+{
+  //
+  // Constructor
+  //
+}
+//___________________________________________________________________
+AliHFEpidTOF::AliHFEpidTOF(const AliHFEpidTOF &c):
+  AliHFEpidBase("")
+  , fPID(0x0)
+  , fQAList(0x0)
+{  
+  // 
+  // Copy operator
+  //
+
+  c.Copy(*this);
+}
+//___________________________________________________________________
+AliHFEpidTOF &AliHFEpidTOF::operator=(const AliHFEpidTOF &ref){
+  //
+  // Assignment operator
+  //
+
+  if(this != &ref){
+    ref.Copy(*this);
+  }
+
+  return *this;
+}
+//___________________________________________________________________
+AliHFEpidTOF::~AliHFEpidTOF(){
+  //
+  // Destructor
+  //
+  if(fPID) delete fPID;
+  if(fQAList){
+    fQAList->Delete();
+    delete fQAList;
+  }
+}
+//___________________________________________________________________
+void AliHFEpidTOF::Copy(TObject &ref) const {
+  //
+  // Performs the copying of the object
+  //
+  AliHFEpidTOF &target = dynamic_cast<AliHFEpidTOF &>(ref);
+
+  target.fPID = fPID;          
+  target.fQAList = fQAList;
+
+  AliHFEpidBase::Copy(ref);
+}
+//___________________________________________________________________
+Bool_t AliHFEpidTOF::InitializePID(){
+  //
+  // InitializePID: TOF experts have to implement code here
+  //
+  return kTRUE;
+}
+
+//___________________________________________________________________
+Int_t AliHFEpidTOF::IsSelected(AliVParticle *_track)
+{
+
+  //
+  // as of 22/05/2006 :
+  // returns AliPID based on the ESD TOF PID decision
+  // the ESD PID will be checked and if necessary improved 
+  // in the mean time. Best of luck
+  //
+  // returns 10 (== kUnknown)if PID can not be assigned
+  //
+
+  AliESDtrack *track = dynamic_cast<AliESDtrack*>(_track);
+  
+  if(!AliESDtrack::kTOFout) return AliPID::kUnknown;
+  
+  (dynamic_cast<TH1F *>(fQAList->At(kHistTOFpidFlags)))->Fill(0.);
+
+  Double_t ItrackL = track->GetIntegratedLength();
+  Double_t TOFsignal = track->GetTOFsignal();
+  Double_t TOF = TOFsignal;
+
+  if(ItrackL > 0)
+    (dynamic_cast<TH1F *>(fQAList->At(kHistTOFpidFlags)))->Fill(1.);
+
+  if(TOFsignal > 0)
+    (dynamic_cast<TH1F *>(fQAList->At(kHistTOFpidFlags)))->Fill(2.);
+  
+
+  if(ItrackL <=0 || TOFsignal <=0) return AliPID::kUnknown;
+
+  (dynamic_cast<TH1F *>(fQAList->At(kHistTOFpidFlags)))->Fill(3.);
+  (dynamic_cast<TH1F *>(fQAList->At(kHistTOFsignal)))->Fill(TOFsignal/1000.);
+  (dynamic_cast<TH1F *>(fQAList->At(kHistTOFlength)))->Fill(ItrackL);
+  // get the TOF pid probabilities
+  Double_t ESDpid[5] = {0., 0., 0., 0., 0.};
+  Float_t TOFpid_sum = 0.;
+  // find the largest PID probability
+  track->GetTOFpid(ESDpid);
+  Double_t MAXpid = 0.;
+  Int_t MAXindex = -1;
+  for(Int_t i=0; i<5; ++i){
+    TOFpid_sum += ESDpid[i];
+    if(ESDpid[i] > MAXpid){
+      MAXpid = ESDpid[i];
+      MAXindex = i;
+    }
+  }
+  
+  Double_t P = track->GetOuterParam()->P();
+  Double_t beta = (ItrackL/100.)/(TMath::C()*(TOFsignal/1e12));
+  
+  if(TMath::Abs(TOFpid_sum - 1) > 0.01) return AliPID::kUnknown;
+  else{
+    // should be the same as AliPID flags
+    
+    (dynamic_cast<TH2F *>(fQAList->At(kHistTOFpid_0+MAXindex)))->Fill(beta, P);
+    (dynamic_cast<TH2F *>(fQAList->At(kHistTOFpid_beta_v_P)))->Fill(beta, P);
+    return MAXindex;
+  }
+}
+
+//___________________________________________________________________
+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), kHistTOFpid_beta_v_P);
+  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), kHistTOFpid_0);
+  fQAList->AddAt(new TH2F("hTOFpid_muon", "TOF reco muon; beta ; momentum [GeV/c]", 120, 0, 1.2, 200, 0, 5), kHistTOFpid_1);
+  fQAList->AddAt(new TH2F("hTOFpid_pion", "TOF reco pion; beta ; momentum [GeV/c]", 120, 0, 1.2, 200, 0, 5), kHistTOFpid_2);
+  fQAList->AddAt(new TH2F("hTOFpid_kaon", "TOF reco kaon; beta ; momentum [GeV/c]", 120, 0, 1.2, 200, 0, 5), kHistTOFpid_3);
+  fQAList->AddAt(new TH2F("hTOFpid_proton", "TOF reco proton; beta ; momentum [GeV/c]", 120, 0, 1.2, 200, 0, 5), kHistTOFpid_4);
+
+  qaList->AddLast(fQAList);
+}
diff --git a/PWG3/hfe/AliHFEpidTOF.h b/PWG3/hfe/AliHFEpidTOF.h
new file mode 100644 (file)
index 0000000..0ddf15a
--- /dev/null
@@ -0,0 +1,62 @@
+#ifndef __ALIHFEPIDTOF_H__
+#define __ALIHFEPIDTOF_H__
+
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice   */   
+
+/************************************************************************
+ *                                                                      *
+ * Class for TOF PID                                                    *
+ * Implements the abstract base class AliHFEpidBase                     *
+ * IsInitialized() does the PID decision                                *
+ *                                                                      *
+ * Authors:                                                             *
+ *   Markus Fasel  <M.Fasel@gsi.de>                                     *
+ *   Matus Kalisky <matus.kalisky@cern.ch>  (contact)                   *
+ ************************************************************************/
+#ifndef __ALIHFEPIDBASE_H__
+#include "AliHFEpidBase.h"
+#endif
+
+class TList;
+class TH2F;
+
+class AliVParticle;
+
+class AliHFEpidTOF : public AliHFEpidBase{
+  typedef enum{
+    kHistTOFpidFlags = 0,
+      kHistTOFpid_beta_v_P = 1,
+      kHistTOFsignal = 2,
+      kHistTOFlength =3,
+      kHistTOFpid_0 = 4,
+      kHistTOFpid_1 = 5,
+      kHistTOFpid_2 = 6,
+      kHistTOFpid_3 = 7,
+      kHistTOFpid_4 = 8
+      
+      } QAHist_t;
+ public:
+  AliHFEpidTOF(const Char_t *name);
+  virtual ~AliHFEpidTOF();
+  AliHFEpidTOF(const AliHFEpidTOF &c);
+  AliHFEpidTOF &operator=(const AliHFEpidTOF &c);
+  
+  virtual Bool_t    InitializePID();
+  virtual Int_t     IsSelected(AliVParticle *track);
+  virtual Bool_t    HasQAhistos() const { return kTRUE; };
+  
+  
+ protected:
+  void Copy(TObject &ref) const;
+  void AddQAhistograms(TList *qaHist);
+  
+ private:
+  
+  AliPID *fPID;           //! PID Object
+  TList *fQAList;         //! QA histograms
+  ClassDef(AliHFEpidTOF, 1)
+};
+
+#endif
diff --git a/PWG3/hfe/AliHFEpidTPC.cxx b/PWG3/hfe/AliHFEpidTPC.cxx
new file mode 100644 (file)
index 0000000..6ef479b
--- /dev/null
@@ -0,0 +1,372 @@
+/**************************************************************************
+* 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 TPC PID                                                    *
+ * Implements the abstract base class AliHFEpidBase                     *
+ *                                                                      *
+ * Class contains TPC specific cuts and QA histograms                   *
+ * Two selection strategies are offered: Selection of certain value     *
+ * regions in the TPC dE/dx (by IsSelected), and likelihoods            *
+ *                                                                      *
+ * Authors:                                                             *
+ *                                                                      *
+ *   Markus Fasel <M.Fasel@gsi.de>                                      *
+ *   Markus Heide <mheide@uni-muenster.de>                              *
+ *                                                                      *
+ *                                                                      *
+ ************************************************************************/
+#include <TH2I.h>
+#include <TList.h>
+#include <TMath.h>
+
+#include "AliESDtrack.h"
+#include "AliExternalTrackParam.h"
+#include "AliLog.h"
+#include "AliPID.h"
+#include "AliTPCpidESD.h"
+#include "AliVParticle.h"
+
+#include "AliHFEpidTPC.h"
+
+
+
+//___________________________________________________________________
+AliHFEpidTPC::AliHFEpidTPC(const char* name) :
+  // add a list here
+    AliHFEpidBase(name)
+  , fLineCrossingsEnabled(0)
+  , fNsigmaTPC(2)
+  , fPID(0x0)
+  , fPIDtpcESD(0x0)
+  , fQAList(0x0)
+{
+  //
+  // default  constructor
+  // 
+  memset(fLineCrossingCenter, 0, sizeof(Double_t) * AliPID::kSPECIES);
+  memset(fLineCrossingSigma, 0, sizeof(Double_t) * AliPID::kSPECIES);
+  fPID = new AliPID;
+  fPIDtpcESD = new AliTPCpidESD;
+}
+
+//___________________________________________________________________
+AliHFEpidTPC::AliHFEpidTPC(const AliHFEpidTPC &ref) :
+    AliHFEpidBase("")
+  , fLineCrossingsEnabled(0)
+  , fNsigmaTPC(2)
+  , fPID(0x0)
+  , fPIDtpcESD(0x0)
+  , fQAList(0x0)
+{
+  //
+  // Copy constructor
+  //
+  ref.Copy(*this);
+}
+
+//___________________________________________________________________
+AliHFEpidTPC &AliHFEpidTPC::operator=(const AliHFEpidTPC &ref){
+  //
+  // Assignment operator
+  //
+  if(this != &ref){
+    ref.Copy(*this);
+  } 
+  return *this;
+}
+
+void AliHFEpidTPC::Copy(TObject &o) const{
+  //
+  // Copy function 
+  // called in copy constructor and assigment operator
+  //
+  AliHFEpidTPC &target = dynamic_cast<AliHFEpidTPC &>(o);
+
+  target.fLineCrossingsEnabled = fLineCrossingsEnabled;
+  target.fNsigmaTPC = fNsigmaTPC;
+  target.fPID = new AliPID(*fPID);
+  target.fPIDtpcESD = new AliTPCpidESD(*fPIDtpcESD);
+  target.fQAList = dynamic_cast<TList *>(fQAList->Clone());
+
+  AliHFEpidBase::Copy(target);
+}
+
+//___________________________________________________________________
+AliHFEpidTPC::~AliHFEpidTPC(){
+  //
+  // Destructor
+  //
+  if(fPID) delete fPID;
+  if(fPIDtpcESD) delete fPIDtpcESD;
+  if(fQAList){
+    fQAList->Delete();
+    delete fQAList;
+  }
+}
+
+//___________________________________________________________________
+Bool_t AliHFEpidTPC::InitializePID(){
+  //
+  // Add TPC dE/dx Line crossings
+  //
+  AddTPCdEdxLineCrossing(AliPID::kKaon, 0.3, 0.018);
+  AddTPCdEdxLineCrossing(AliPID::kProton, 0.9, 0.054);
+  return kTRUE;
+}
+
+//___________________________________________________________________
+Int_t AliHFEpidTPC::IsSelected(AliVParticle *track)
+{
+  //
+  // For the TPC pid we use the 2-sigma band around the bethe bloch curve
+  // for electrons
+  // exclusion of the crossing points
+  //
+  AliESDtrack *esdTrack = 0x0;
+  if(!(esdTrack = dynamic_cast<AliESDtrack *>(track))) return kFALSE;
+  if(IsQAon()) FillTPChistograms(esdTrack);
+  Double_t TPCsignal = esdTrack->GetTPCsignal();
+  // exclude crossing points:
+  // Determine the bethe values for each particle species
+  Double_t p = esdTrack->GetInnerParam()->P();
+  Bool_t isLineCrossing = kFALSE;
+  for(Int_t ispecies = 0; ispecies < AliPID::kSPECIES; ispecies++){
+    if(!(fLineCrossingsEnabled & 1 << ispecies)) continue;
+    if(TMath::Abs(p - fLineCrossingCenter[ispecies]) < fLineCrossingSigma[ispecies]){
+      // Point in a line crossing region, no PID possible
+      isLineCrossing = kTRUE;
+      break;
+    }
+  }
+  if(isLineCrossing) return 0;
+  // Check whether distance from the electron line is smaller than n-sigma
+  Double_t beta = p/fPID->ParticleMass(AliPID::kElectron);
+  if(TMath::Abs(TPCsignal - 50*fPIDtpcESD->Bethe(beta)) < GetTPCsigma(p,0)) return 11;
+  return 0;
+}
+
+//___________________________________________________________________
+void AliHFEpidTPC::AddTPCdEdxLineCrossing(Int_t species, Double_t p, Double_t sigma_p){
+  //
+  // Add exclusion point for the TPC PID where a dEdx line crosses the electron line
+  // Stores line center and line sigma
+  //
+  if(species >= AliPID::kSPECIES){
+    AliError("Species doesn't exist");
+    return;
+  }
+  fLineCrossingsEnabled |= 1 << species;
+  fLineCrossingCenter[species] = p;
+  fLineCrossingSigma[species] = sigma_p;
+}
+
+//___________________________________________________________________
+Double_t AliHFEpidTPC::GetTPCsigma(Double_t p, Int_t species){
+  //
+  // return the TPC sigma, momentum dependent
+  //
+  if(p < 0.1 || p > 20.) return 0.;
+  Double_t beta = p/fPID->ParticleMass(species);
+  
+  return 50*fPIDtpcESD->Bethe(beta) * 0.06;
+}
+
+//___________________________________________________________________
+Double_t AliHFEpidTPC::Likelihood(const AliESDtrack *track, Int_t species, Float_t rsig)
+{
+  //gives probability for track to come from a certain particle species;
+  //no priors considered -> probabilities for equal abundances of all species!
+  //optional restriction to r-sigma bands of different particle species; default: rsig = 2. (see below)
+
+  //IMPORTANT: Tracks which are judged to be outliers get negative likelihoods -> unusable for combination with further detectors!
+  
+  if(!track) return -1.;
+  Int_t hypo; //marks particle hypotheses for 2-sigma bands
+  Double_t beta;//well o.k., it corresponds to gamma * beta
+  Double_t p = track->GetInnerParam()->P();
+  Double_t TPCsignal = track->GetTPCsignal();
+  Bool_t outlier = kTRUE;
+  // Check whether distance from the respective particle line is smaller than r sigma
+  for(hypo = 0; hypo < 5; hypo++)
+    {
+      beta = p/fPID->ParticleMass(hypo);
+      if(TMath::Abs(TPCsignal - (GetTPCsigma(p, hypo))/0.06) > (rsig * GetTPCsigma(p,hypo)))
+       outlier = kTRUE;
+      else 
+       {
+         outlier = kFALSE;
+         break;
+       }
+    }
+  if(outlier)
+    return -2.;
+
+  Double_t TPCprob[5];
+
+  track->GetTPCpid(TPCprob);
+
+  return TPCprob[species];
+}
+//___________________________________________________________________
+Double_t AliHFEpidTPC::Likelihood(const AliESDtrack *track, Int_t species)
+{
+  //default: rsig = 2.
+  // for everything else, see above!
+
+  if(!track) return -1.;
+  Int_t hypo; //marks particle hypotheses for 2-sigma bands
+  Double_t beta;
+  Double_t p = track->GetInnerParam()->P();
+  Double_t TPCsignal = track->GetTPCsignal();
+  Bool_t outlier = kTRUE;
+  // Check whether distance from the respective particle line is smaller than 2 sigma
+  for(hypo = 0; hypo < 5; hypo++)
+    {
+      beta = p/fPID->ParticleMass(hypo);
+     
+      if(TMath::Abs(TPCsignal - (GetTPCsigma(p, hypo))/0.06) > (2. * GetTPCsigma(p,hypo)))
+       outlier = kTRUE;
+      else 
+       {
+         outlier = kFALSE;
+         break;
+       }
+    }
+  if(outlier == kTRUE)
+    return -2.;
+
+  Double_t TPCprob[5];
+
+  track->GetTPCpid(TPCprob);
+
+  return TPCprob[species];
+}
+//___________________________________________________________________
+Double_t  AliHFEpidTPC::Suppression(const AliESDtrack *track, Int_t species)
+{
+  //ratio of likelihoods to be whatever species/to be an electron;
+  //as a cross-check for possible particle type suppression compared to electrons
+  if(!track) return -20;
+  if((Likelihood(track,species) == -2.)||(Likelihood(track,0)== -2.))
+    return -30;
+  if(Likelihood(track,species) == 0.)
+    return -10;
+  if (Likelihood(track,0) == 0.)
+    return 10.;
+  else
+    return TMath::Log10(Likelihood(track,species)/(Likelihood(track,0)));
+
+
+}
+//___________________________________________________________________
+void AliHFEpidTPC::FillTPChistograms(const AliESDtrack *track){
+  //
+  if(!track)
+    return;
+  Double_t tpc_signal = track->GetTPCsignal();
+  Double_t p = track->GetInnerParam() ? track->GetInnerParam()->P() : track->P();
+  if(HasMCData()){
+    switch(TMath::Abs(GetPdgCode(const_cast<AliESDtrack *>(track)))){
+      case 11:   (dynamic_cast<TH2I *>(fQAList->At(kHistTPCelectron)))->Fill(p, tpc_signal);
+       (dynamic_cast<TH2F *>(fQAList->At(kHistTPCprobEl)))->Fill(p, Likelihood(track, 0));
+       //histograms with ratio of likelihood to be electron/to be other species (a check for quality of likelihood PID);
+       (dynamic_cast<TH2F *>(fQAList->At(kHistTPCenhanceElPi)))->Fill(p, -Suppression(track, 2));
+       (dynamic_cast<TH2F *>(fQAList->At(kHistTPCenhanceElMu)))->Fill(p, -Suppression(track, 1));
+       (dynamic_cast<TH2F *>(fQAList->At(kHistTPCenhanceElKa)))->Fill(p, -Suppression(track, 3));
+       (dynamic_cast<TH2F *>(fQAList->At(kHistTPCenhanceElPro)))->Fill(p, -Suppression(track, 4));
+       //___________________________________________________________________________________________
+       //Likelihoods for electrons to be other particle species
+       (dynamic_cast<TH2F *>(fQAList->At(kHistTPCElprobPi)))->Fill(p, Likelihood(track, 2));
+       (dynamic_cast<TH2F *>(fQAList->At(kHistTPCElprobMu)))->Fill(p, Likelihood(track, 1));
+       (dynamic_cast<TH2F *>(fQAList->At(kHistTPCElprobKa)))->Fill(p, Likelihood(track, 3));
+       (dynamic_cast<TH2F *>(fQAList->At(kHistTPCElprobPro)))->Fill(p, Likelihood(track, 4));
+       break;
+       //___________________________________________________________________________________________
+    case 13: (dynamic_cast<TH2I *>(fQAList->At(kHistTPCmuon)))->Fill(p, tpc_signal);
+      //Likelihood of muon to be an electron
+      (dynamic_cast<TH2F *>(fQAList->At(kHistTPCprobMu)))->Fill(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
+       (dynamic_cast<TH2F *>(fQAList->At(kHistTPCsuppressMu)))->Fill(p, Suppression(track, 1));
+      break;
+      case 211:  (dynamic_cast<TH2I *>(fQAList->At(kHistTPCpion)))->Fill(p, tpc_signal);
+       (dynamic_cast<TH2F *>(fQAList->At(kHistTPCprobPi)))->Fill(p, Likelihood(track, 0));
+       (dynamic_cast<TH2F *>(fQAList->At(kHistTPCsuppressPi)))->Fill(p, Suppression(track, 2));
+          break;
+      case 321:  (dynamic_cast<TH2I *>(fQAList->At(kHistTPCkaon)))->Fill(p, tpc_signal);
+       (dynamic_cast<TH2F *>(fQAList->At(kHistTPCprobKa)))->Fill(p, Likelihood(track, 0));
+       (dynamic_cast<TH2F *>(fQAList->At(kHistTPCsuppressKa)))->Fill(p, Suppression(track, 3));
+          break;
+      case 2212: (dynamic_cast<TH2I *>(fQAList->At(kHistTPCproton)))->Fill(p, tpc_signal);
+       (dynamic_cast<TH2F *>(fQAList->At(kHistTPCprobPro)))->Fill(p, Likelihood(track, 0));
+       (dynamic_cast<TH2F *>(fQAList->At(kHistTPCsuppressPro)))->Fill(p, Suppression(track, 4));
+          break;
+      default: (dynamic_cast<TH2I *>(fQAList->At(kHistTPCothers)))->Fill(p, tpc_signal);
+       (dynamic_cast<TH2F *>(fQAList->At(kHistTPCprobOth)))->Fill(p, Likelihood(track, 0));
+
+       break;
+    }
+  }
+  //TPC signal and Likelihood to be electron for all tracks (independent of MC information)
+  (dynamic_cast<TH2I *>(fQAList->At(kHistTPCall)))->Fill(p, tpc_signal);
+ (dynamic_cast<TH2F *>(fQAList->At(kHistTPCprobAll)))->Fill(p, Likelihood(track, 0));
+
+  
+}
+
+//___________________________________________________________________
+void AliHFEpidTPC::AddQAhistograms(TList *qaList){
+  fQAList = new TList;
+  fQAList->SetName("fTPCqaHistos");
+
+  fQAList->AddAt(new TH2I("fHistTPCelectron","TPC signal for Electrons", 200, 0, 20, 60, 0, 600), kHistTPCelectron); 
+  fQAList->AddAt(new TH2I("fHistTPCmuon","TPC signal for Muons", 200, 0, 20, 60, 0, 600), kHistTPCmuon);
+  fQAList->AddAt(new TH2I("fHistTPCpion","TPC signal for Pions", 200, 0, 20, 60, 0, 600), kHistTPCpion);
+  fQAList->AddAt(new TH2I("fHistTPCkaon","TPC signal for Kaons", 200, 0, 20, 60, 0, 600), kHistTPCkaon);
+  fQAList->AddAt(new TH2I("fHistTPCproton","TPC signal for Protons", 200, 0, 20, 60, 0, 600), kHistTPCproton);
+  fQAList->AddAt(new TH2I("fHistTPCothers","TPC signal for other species", 200, 0, 20, 60, 0, 600), kHistTPCothers);
+  fQAList->AddAt(new TH2I("fHistTPCall","TPC signal for all species", 200, 0, 20, 60, 0, 600), kHistTPCall);
+
+  fQAList->AddAt(new TH2F("fHistTPCprobEl","TPC likelihood for electrons to be an electron vs. p", 200, 0.,20.,200,0.,1.), kHistTPCprobEl);
+  fQAList->AddAt(new TH2F("fHistTPCprobPi","TPC likelihood for pions to be an electron vs. p",  200, 0.,20.,200, 0.,1.), kHistTPCprobPi);
+  fQAList->AddAt(new TH2F("fHistTPCprobMu","TPC likelihood for muons to be an electron vs. p",  200, 0.,20.,200, 0.,1.), kHistTPCprobMu);
+  fQAList->AddAt(new TH2F("fHistTPCprobKa","TPC likelihood for kaons to be an electron vs. p",  200, 0.,20.,200, 0.,1.), kHistTPCprobKa);
+  fQAList->AddAt(new TH2F("fHistTPCprobPro","TPC likelihood for protons to be an electron vs. p",  200, 0.,20.,200, 0.,1.), kHistTPCprobPro);
+  fQAList->AddAt(new TH2F("fHistTPCprobOth","TPC likelihood for other particles to be an electron vs. p",  200, 0.,20.,200, 0.,1.), kHistTPCprobOth);
+  fQAList->AddAt(new TH2F("fHistTPCprobAll","TPC likelihood for all particles to be an electron vs. p",  200, 0.,20.,200, 0.,1.), kHistTPCprobAll);
+
+
+ fQAList->AddAt(new TH2F("fHistTPCsuppressPi","log10 of TPC Likelihood(pion)/Likelihood(elec) for pions vs. p", 200, 0.,20.,200,-1.,5.8), kHistTPCsuppressPi);
+ fQAList->AddAt(new TH2F("fHistTPCsuppressMu","log10 of TPC Likelihood(muon)/Likelihood(elec) for muons vs. p", 200, 0.,20.,200,-1.,5.8), kHistTPCsuppressMu);
+ fQAList->AddAt(new TH2F("fHistTPCsuppressKa","log10 of TPC Likelihood(kaon)/Likelihood(elec) for kaons vs. p", 200, 0.,20.,200,-1.,5.8), kHistTPCsuppressKa);
+ fQAList->AddAt(new TH2F("fHistTPCsuppressPro","log10 of TPC Likelihood(proton)/Likelihood(elec)for protons vs. p", 200, 0.,20.,200,-1.,5.8), kHistTPCsuppressPro);
+
+ fQAList->AddAt(new TH2F("fHistTPCenhanceElPi","log10 of TPC Likelihood(elec)/Likelihood(pion) for electrons vs. p", 200, 0.,20.,200,-1.,5.8), kHistTPCsuppressPi);
+ fQAList->AddAt(new TH2F("fHistTPCenhanceElMu","log10 of TPC Likelihood(elec)/Likelihood(muon) for electrons vs. p", 200, 0.,20.,200,-1.,5.8), kHistTPCsuppressMu);
+ fQAList->AddAt(new TH2F("fHistTPCenhanceElKa","log10 of TPC Likelihood(elec)/Likelihood(kaon) for electrons vs. p", 200, 0.,20.,200,-1.,5.8), kHistTPCsuppressKa);
+ fQAList->AddAt(new TH2F("fHistTPCenhanceElPro","log10 of TPC Likelihood(elec)/Likelihood(proton) for electrons vs. p", 200, 0.,20.,200,-1.,5.8), kHistTPCsuppressPro);
+
+ fQAList->AddAt(new TH2F("fHistTPCElprobPi","TPC likelihood for electrons to be a pion vs. p", 200, 0.,20.,200,0.,1.), kHistTPCElprobPi);
+ fQAList->AddAt(new TH2F("fHistTPCElprobMu","TPC likelihood for electrons to be a muon vs. p", 200, 0.,20.,200,0.,1.), kHistTPCElprobMu);
+ fQAList->AddAt(new TH2F("fHistTPCElprobKa","TPC likelihood for electrons to be a kaon vs. p", 200, 0.,20.,200,0.,1.), kHistTPCElprobKa);
+ fQAList->AddAt(new TH2F("fHistTPCElprobPro","TPC likelihood for electrons to be a proton vs. p", 200, 0.,20.,200,0.,1.), kHistTPCElprobPro);
+
+
+  qaList->AddLast(fQAList);
+}
diff --git a/PWG3/hfe/AliHFEpidTPC.h b/PWG3/hfe/AliHFEpidTPC.h
new file mode 100644 (file)
index 0000000..ddd0f04
--- /dev/null
@@ -0,0 +1,94 @@
+/**************************************************************************
+* 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.                  *
+**************************************************************************/
+#ifndef __ALIHFEPIDTPC_H__
+#define __ALIHFEPIDTPC_H__
+
+#ifndef __ALIHFEPIDBASE_H__
+#include "AliHFEpidBase.h"
+#endif
+
+#ifndef ALIPID_H
+#include "AliPID.h"
+#endif
+
+class TList;
+class AliESDtrack;
+class AliTPCpidESD;
+class AliVParticle;
+
+class AliHFEpidTPC : public AliHFEpidBase{
+  typedef enum{
+    kHistTPCelectron = 0,
+    kHistTPCpion = 1,
+    kHistTPCmuon = 2,
+      kHistTPCkaon = 3,
+      kHistTPCproton = 4,
+      kHistTPCothers = 5,
+      kHistTPCall = 6,
+      kHistTPCprobEl = 7,
+      kHistTPCprobPi = 8,
+      kHistTPCprobMu = 9,
+      kHistTPCprobKa = 10,
+      kHistTPCprobPro = 11,
+      kHistTPCprobOth = 12,
+      kHistTPCprobAll = 13,
+      kHistTPCsuppressPi = 14,
+      kHistTPCsuppressMu = 15,
+      kHistTPCsuppressKa = 16,
+      kHistTPCsuppressPro = 17,
+      kHistTPCenhanceElPi = 18,
+      kHistTPCenhanceElMu = 19,
+      kHistTPCenhanceElKa = 20,
+      kHistTPCenhanceElPro = 21,
+      kHistTPCElprobPi = 22,
+      kHistTPCElprobMu = 23,
+      kHistTPCElprobKa = 24,
+      kHistTPCElprobPro = 25
+  } QAHist_t;
+  public:
+    AliHFEpidTPC(const Char_t *name);
+    AliHFEpidTPC(const AliHFEpidTPC &ref);
+    AliHFEpidTPC &operator=(const AliHFEpidTPC &ref);
+    virtual ~AliHFEpidTPC();
+    
+    virtual Bool_t InitializePID();
+    virtual Int_t IsSelected(AliVParticle *track);
+    virtual Bool_t HasQAhistos() const { return kTRUE; };
+
+    void AddTPCdEdxLineCrossing(Int_t species, Double_t p, Double_t sigma_p);
+    void SetTPCnSigma(Short_t nSigma) { fNsigmaTPC = nSigma; };
+    Double_t Likelihood(const AliESDtrack *track, Int_t species);
+    Double_t Likelihood(const AliESDtrack *track, Int_t species, Float_t rsig);
+
+    Double_t Suppression(const AliESDtrack *track, Int_t species);
+
+  protected:
+    void Copy(TObject &o) const;
+    void AddQAhistograms(TList *qaList);
+    void FillTPChistograms(const AliESDtrack *track);
+    Double_t GetTPCsigma(Double_t p, Int_t species);
+  private:
+    Double_t fLineCrossingCenter[AliPID::kSPECIES];         // Line crossing ExclusionPoints
+    Double_t fLineCrossingSigma[AliPID::kSPECIES];          // with of the exclusion point
+    UChar_t fLineCrossingsEnabled;                          // Bitmap showing which line crossing is set
+    Short_t fNsigmaTPC;                                     // TPC sigma band
+    AliPID *fPID;                                           //! PID Object
+    AliTPCpidESD *fPIDtpcESD;                               //! TPC PID object
+    TList *fQAList;                                         //! QA histograms
+
+  ClassDef(AliHFEpidTPC, 1)   // TPC Electron ID class
+};
+#endif
diff --git a/PWG3/hfe/AliHFEpidTRD.cxx b/PWG3/hfe/AliHFEpidTRD.cxx
new file mode 100644 (file)
index 0000000..89973d5
--- /dev/null
@@ -0,0 +1,239 @@
+/**************************************************************************
+* 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 TRD PID                                                    *
+ * Implements the abstract base class AliHFEpidbase        *
+ * Make PID does the PID decision                                       *
+ * Class further contains TRD specific cuts and QA histograms           *
+ *                                                                      *
+ * Authors:                                                             *
+ *   Markus Fasel <M.Fasel@gsi.de>                                      *
+ *                                                                      *
+ ************************************************************************/
+#include <TAxis.h>
+#include <TFile.h>
+#include <TH1F.h>
+#include <TIterator.h>
+#include <TKey.h>
+#include <TMap.h>
+#include <TObjArray.h>
+#include <TObjString.h>
+#include <TString.h>
+#include <TROOT.h>
+
+#include "AliESDtrack.h"
+#include "AliPID.h"
+
+#include "AliHFEpidTRD.h"
+
+ClassImp(AliHFEpidTRD)
+
+//___________________________________________________________________
+AliHFEpidTRD::AliHFEpidTRD(const char* name) :
+    AliHFEpidBase(name)
+  , fThresholdFile("TRD.PIDthresholds.root")
+  , fPIDMethod(kNN)
+  , fTRDthresholds(0x0)
+  , fTRDelectronEfficiencies(0x0)
+{
+  //
+  // default  constructor
+  // 
+  fTRDthresholds = new TMap();
+}
+
+//___________________________________________________________________
+AliHFEpidTRD::AliHFEpidTRD(const AliHFEpidTRD &ref):
+    AliHFEpidBase("")
+  , fThresholdFile("")
+  , fPIDMethod(kLQ)
+  , fTRDthresholds(0x0)
+  , fTRDelectronEfficiencies(0x0)
+{
+  //
+  // Copy constructor
+  //
+  ref.Copy(*this);
+}
+
+//___________________________________________________________________
+AliHFEpidTRD &AliHFEpidTRD::operator=(const AliHFEpidTRD &ref){
+  //
+  // Assignment operator
+  //
+  if(this != &ref){
+    ref.Copy(*this);
+  }
+  return *this;
+}
+
+//___________________________________________________________________
+void AliHFEpidTRD::Copy(TObject &ref) const {
+  //
+  // Performs the copying of the object
+  //
+  AliHFEpidTRD &target = dynamic_cast<AliHFEpidTRD &>(ref);
+
+  target.fThresholdFile = fThresholdFile;
+  target.fPIDMethod = fPIDMethod;
+  if(fTRDthresholds){
+    target.fTRDthresholds = dynamic_cast<TMap *>(fTRDthresholds->Clone());
+  }
+  if(fTRDelectronEfficiencies){
+    target.fTRDelectronEfficiencies = new TAxis(*fTRDelectronEfficiencies);
+  }
+  AliHFEpidBase::Copy(ref);
+}
+
+//___________________________________________________________________
+AliHFEpidTRD::~AliHFEpidTRD(){
+  //
+  // Destructor
+  //
+  if(fTRDthresholds){
+    fTRDthresholds->Delete();
+    delete fTRDthresholds;
+  }
+  if(fTRDelectronEfficiencies) delete fTRDelectronEfficiencies;
+}
+
+//______________________________________________________
+Bool_t AliHFEpidTRD::InitializePID(){
+  //
+  // InitializePID: Load TRD thresholds and create the electron efficiency axis
+  // to navigate 
+  //
+  LoadTRDthresholds();
+  // Fill the electron efficiencies axis for the TRD alone PID
+  Int_t nEffs = fTRDthresholds->GetEntries() + 1;
+  TIterator* thres =fTRDthresholds->MakeIterator();
+  TObjString *key = 0x0;
+  Double_t *tmp = new Double_t[nEffs], *titer = tmp;
+  while((key = dynamic_cast<TObjString *>((*thres)()))){
+    (*titer++) = static_cast<Double_t>(key->String().Atoi())/100.;
+  }
+  delete thres;
+  *titer = 1.;
+  // Sort the electron efficiencies and put them into the TAxis for later navigation
+  Int_t *ind = new Int_t[nEffs], *iiter = ind;
+  TMath::Sort(nEffs, tmp, ind, kFALSE);
+  Double_t *eleffs = new Double_t[nEffs], *eiter = eleffs;
+  while(eiter < &eleffs[nEffs]) *(eiter++) = tmp[*(iiter++)];
+  // print the content
+  Int_t cnt = 0;
+  if(GetDebugLevel() > 1){
+    printf("Printing electron efficiency bins:\n");
+    eiter = eleffs;
+    thres = fTRDthresholds->MakeIterator();
+    TObject *object = 0x0;
+    while(eiter < &eleffs[nEffs - 1]){
+      printf("eleffs[%d] = %f", cnt++, *(eiter++));
+      key = dynamic_cast<TObjString *>(thres->Next());
+      object = fTRDthresholds->GetValue(key->String().Data());
+      printf(", Content: %p\n", (void *)object);
+    }
+  }
+  delete[] tmp; delete[] ind;
+  fTRDelectronEfficiencies = new TAxis(nEffs - 1, eleffs);
+  if(GetDebugLevel() > 1){
+    printf("Printing axis content:\n");
+    for(Int_t ibin = fTRDelectronEfficiencies->GetFirst(); ibin <= fTRDelectronEfficiencies->GetLast(); ibin++)
+      printf("%d.) minimum: %f, maximum? %f\n", ibin, fTRDelectronEfficiencies->GetBinLowEdge(ibin), fTRDelectronEfficiencies->GetBinUpEdge(ibin));
+  }
+  delete[] eleffs;
+  return kTRUE;
+}
+
+//______________________________________________________
+Int_t AliHFEpidTRD::IsSelected(AliVParticle *track){
+  //
+  // Does PID for TRD alone:
+  // PID thresholds based on 90% Electron Efficiency level approximated by a linear 
+  // step function
+  //
+  AliESDtrack *esdTrack = 0x0;
+  if(!(esdTrack = dynamic_cast<AliESDtrack *>(track))) return kFALSE;
+  Double_t p = esdTrack->GetOuterParam() ? esdTrack->GetOuterParam()->P() : esdTrack->P();
+  if(p < 0.6) return 0;
+
+  // Get the Histograms
+  TH1 *threshist = GetTRDthresholds(0.91);
+  Int_t bin = 0;
+  if(p > threshist->GetXaxis()->GetXmax()) 
+    bin = threshist->GetXaxis()->GetLast();
+  else if(p < threshist->GetXaxis()->GetXmin()) 
+    bin = threshist->GetXaxis()->GetFirst();
+  else
+    bin = threshist->GetXaxis()->FindBin(p);
+
+  Double_t pidProbs[AliPID::kSPECIES];
+  esdTrack->GetTRDpid(pidProbs);
+  if(pidProbs[AliPID::kElectron] > threshist->GetBinContent(bin)) return 11;
+  return 0;
+}
+
+//___________________________________________________________________
+void AliHFEpidTRD::LoadTRDthresholds(){
+  //
+  // Load TRD threshold histograms from File
+  //
+  TFile *mythresholds = TFile::Open(fThresholdFile);
+  TKey *object = 0x0;
+  TString electron_eff;
+  TObjArray *histos = 0x0;
+  Float_t eff;
+  TH1F *refhist = 0x0;
+  TIterator *keyIterator = mythresholds->GetListOfKeys()->MakeIterator();
+  TString histnames[2] = {"fHistThreshLQ", "fHistThreshNN"};
+  gROOT->cd();
+  while((object = dynamic_cast<TKey *>((*keyIterator)()))){
+    // Get the electron efficiency bin this histogram was taken with
+    electron_eff = object->GetName();
+    electron_eff = electron_eff.Remove(0,3);
+    eff = static_cast<Float_t>(electron_eff.Atoi())/100.;
+
+    // Get the threshold according to the selected 
+    histos = dynamic_cast<TObjArray *>(object->ReadObj());
+    refhist = dynamic_cast<TH1F *>(histos->FindObject(histnames[fPIDMethod].Data()));
+    SetTRDthresholds(refhist, eff);
+    histos->Delete();
+    delete histos;
+  }
+  delete keyIterator;
+  mythresholds->Close();
+  delete mythresholds;
+}
+
+//___________________________________________________________________
+void AliHFEpidTRD::SetTRDthresholds(TH1F *thresholds, Float_t electronEff){
+  //
+  // Set the threshold histogram for the TRD pid
+  //
+  fTRDthresholds->Add(new TObjString(Form("%d", TMath::Nint(electronEff * 100.))), new TH1F(*thresholds));
+}
+
+//___________________________________________________________________
+TH1F *AliHFEpidTRD::GetTRDthresholds(Float_t electronEff){ 
+  Int_t bin = 0;
+  if(electronEff < fTRDelectronEfficiencies->GetXmin()) bin = fTRDelectronEfficiencies->GetFirst();
+  else if(electronEff > fTRDelectronEfficiencies->GetXmax()) bin = fTRDelectronEfficiencies->GetLast();
+  else bin = fTRDelectronEfficiencies->FindBin(electronEff);
+ TObjString keyname = Form("%d", TMath::Nint(fTRDelectronEfficiencies->GetBinLowEdge(bin)* 100.));
+/*  printf("Key: %s\n", keyname.String().Data());*/
+  TH1F *thresholds = dynamic_cast<TH1F *>((dynamic_cast<TPair *>(fTRDthresholds->FindObject(&keyname)))->Value());
+/*  printf("thresholds: %p\n", thresholds);*/
+  return thresholds;
+}
diff --git a/PWG3/hfe/AliHFEpidTRD.h b/PWG3/hfe/AliHFEpidTRD.h
new file mode 100644 (file)
index 0000000..e9757d4
--- /dev/null
@@ -0,0 +1,62 @@
+/**************************************************************************
+* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+*                                                                        *
+* Author: The ALICE Off-line Project.                                    *
+* Contributors are mentioned in the code where appropriate.              *
+*                                                                        *
+* Permission to use, copy, modify and distribute this software and its   *
+* documentation strictly for non-commercial purposes is hereby granted   *
+* without fee, provided that the above copyright notice appears in all   *
+* copies and that both the copyright notice and this permission notice   *
+* appear in the supporting documentation. The authors make no claims     *
+* about the suitability of this software for any purpose. It is          *
+* provided "as is" without express or implied warranty.                  *
+**************************************************************************/
+#ifndef __ALIHFEPIDTRD_H__
+#define __ALIHFEPIDTRD_H__
+
+ #ifndef __ALIHFEPIDBASE_H__
+ #include "AliHFEpidBase.h"
+ #endif
+
+class TAxis;
+class TH1F;
+class TMap;
+class TString;
+class AliVParticle;
+
+class AliHFEpidTRD : public AliHFEpidBase{
+  public:
+    typedef enum{
+      kLQ = 0,
+      kNN = 1
+    } PIDMethodTRD_t;
+    AliHFEpidTRD(const Char_t *name);
+    AliHFEpidTRD(const AliHFEpidTRD &ref);
+    AliHFEpidTRD& operator=(const AliHFEpidTRD &ref);
+    virtual ~AliHFEpidTRD();
+    
+    virtual Bool_t InitializePID();
+    virtual Int_t IsSelected(AliVParticle *track);
+    virtual Bool_t HasQAhistos() const { return kFALSE; };
+
+    void LoadTRDthresholds();
+
+    void SetPIDMethod(PIDMethodTRD_t method) { fPIDMethod = method; };
+    void SetThresholdFile(Char_t *thresholdFile) { fThresholdFile = thresholdFile; };
+
+  protected:
+    void Copy(TObject &ref) const;
+    TH1F *GetTRDthresholds(Float_t electronEff);
+    void SetTRDthresholds(TH1F *thresholds, Float_t electronEff);
+
+  private:
+    TString fThresholdFile;                                 // Threshold file name
+    PIDMethodTRD_t fPIDMethod;                              // PID Method: 2D Likelihood or Neural Network
+    TMap *fTRDthresholds;                                   //! TRD Thresholds
+    TAxis *fTRDelectronEfficiencies;                        //! Electron Efficiencies corresponding to reference histos
+
+  ClassDef(AliHFEpidTRD, 1)     // TRD electron ID class
+};
+
+#endif
diff --git a/PWG3/hfe/TRD.PIDthresholds.root b/PWG3/hfe/TRD.PIDthresholds.root
new file mode 100644 (file)
index 0000000..19250b6
Binary files /dev/null and b/PWG3/hfe/TRD.PIDthresholds.root differ
diff --git a/PWG3/hfe/runElectronTask.C b/PWG3/hfe/runElectronTask.C
new file mode 100644 (file)
index 0000000..0660aad
--- /dev/null
@@ -0,0 +1,156 @@
+void SetupPar(char* pararchivename);
+TChain * CreateXMLChain(char* xmlfile);
+
+void runElectronTask(const char *treelist = 0x0){
+  if(!treelist){
+    printf("Error: No ESD list specified\n");
+    return;
+  }
+  if(gSystem->Getenv("ALICE_ROOT")){
+    gSystem->Load("libANALYSIS");
+    gSystem->Load("libANALYSISalice");
+    gSystem->Load("libCORRFW");
+  }
+  else{
+    SetupPar("STEERBase");
+    SetupPar("ESD");
+    SetupPar("AOD");
+    SetupPar("ANALYSIS");
+    SetupPar("ANALYSISalice");
+    SetupPar("CORRFW");
+    SetupPar("Util");
+  }
+  SetupPar("HFE");
+  gROOT->LoadMacro("AliAnalysisElectronTask.cxx++");
+  AliLog::SetGlobalLogLevel(AliLog::kError);
+  
+  // Make the ESD chain
+  TString treename = treelist;
+  TChain *esdchain = 0x0;
+  if(treename.EndsWith(".xml"))
+    esdchain = CreateXMLChain(treelist);
+  else{
+    gROOT->LoadMacro("CreateESDChain.C");
+    esdchain = CreateESDChain(treelist, -1);
+  }
+  //esdchain->SetBranchStatus("*", 0);
+  esdchain->SetBranchStatus("Calo*", 0);
+  esdchain->SetBranchStatus("*FMD*", 1);
+  esdchain->SetBranchStatus("Tracks", 1);
+  
+  // Start the Analysis Manager and Create Handlers
+  AliAnalysisManager *pidEffManager = new AliAnalysisManager("PID efficiency studies");
+  pidEffManager->SetInputEventHandler(new AliESDInputHandler);
+  pidEffManager->SetMCtruthEventHandler(new AliMCEventHandler);
+  AliAnalysisElectronTask *task = new AliAnalysisElectronTask;
+  pidEffManager->AddTask(task);
+  task->ConnectInput(0, pidEffManager->CreateContainer("esdTree", TChain::Class(), AliAnalysisManager::kInputContainer));
+  task->ConnectOutput(0, pidEffManager->CreateContainer("nEvents", TH1I::Class(), AliAnalysisManager::kOutputContainer, "HFEtask.root"));
+  task->ConnectOutput(1, pidEffManager->CreateContainer("Results", AliCFContainer::Class(), AliAnalysisManager::kOutputContainer, "HFEtask.root"));
+  task->ConnectOutput(2, pidEffManager->CreateContainer("QA", TList::Class(), AliAnalysisManager::kOutputContainer, "HFEtask.root"));
+  
+  // Run the Analysis
+  if(pidEffManager->InitAnalysis()){  
+    TStopwatch timer;
+    timer.Start();
+    pidEffManager->StartAnalysis("local", esdchain);
+    timer.Stop();
+    timer.Print();
+  }
+}
+
+//____________________________________________
+TChain * CreateXMLChain(char* xmlfile)
+{
+
+  //TChain *chain = 0x0;
+  const char *chainname="esdTree";
+  TChain* chain = new TChain(chainname);
+  TString input =xmlfile;
+  cout<<" the input is::"<< xmlfile<<endl;
+
+  char kXML  [1000];
+  if(gSystem->Getenv("XML") )
+    kXML = gSystem->Getenv("XML");
+  else
+    sprintf(kXML, xmlfile) ; 
+
+  //    sprintf(kXML, "collection.xml") ; 
+  
+  cout<<"XML file "<<kXML<<endl;
+  
+  if (!TFile::Open(kXML)) {
+    printf("No collection file with name -- %s -- was found\n",kXML);
+    return ;
+  }
+  gSystem->Load("libNetx.so") ;
+  gSystem->Load("libRAliEn.so");
+  TGrid::Connect("alien://") ;
+
+
+
+  //  TGridCollection * collection =  (TGridCollection*)gROOT->ProcessLine(Form("TAlienCollection::Open(\"%s\", 0)", kXML));
+  TGridCollection * collection = (TGridCollection*) TAlienCollection::Open(kXML);
+  if (! collection) {
+    AliError(Form("%s not found", kXML)) ; 
+    return kFALSE ; 
+  }
+  //collection->CheckIfOnline();
+
+  TGridResult* result = collection->GetGridResult("",0 ,0);
+
+  //  TList* analysisfilelist = result->GetFileInfoList();
+  
+  // Makes the ESD chain 
+  printf("*** Getting the Chain       ***\n");
+
+  for (Int_t index = 0; index < result->GetEntries(); index++) {
+    TString alienURL = result->GetKey(index, "turl") ; 
+    cout << "================== " << alienURL << endl ; 
+    chain->Add(alienURL) ; 
+    //alienURL.ReplaceAll("AliESDs.root",kXSFileName);
+    // chainxs->Add(alienURL) ; 
+  }
+
+
+  //  chain->AddFileInfoList(analysisfilelist);
+  if (chain) chain->ls();
+  chain->SetBranchStatus("*Calo*",0);
+  chain->SetBranchStatus("*FMD*",0);
+  return chain;
+}
+
+//______________________________________________________________________________
+void SetupPar(char* pararchivename)
+{
+  if (pararchivename) {
+    char processline[1024];
+    sprintf(processline,".! tar xvzf %s.par",pararchivename);
+    gROOT->ProcessLine(processline);
+    TString ocwd = gSystem->WorkingDirectory();
+    gSystem->ChangeDirectory(pararchivename);
+    
+    // check for BUILD.sh and execute
+    if (!gSystem->AccessPathName("PROOF-INF/BUILD.sh")) {
+      printf("*******************************\n");
+      printf("*** Building PAR archive    ***\n");
+      printf("*******************************\n");
+      
+      if (gSystem->Exec("PROOF-INF/BUILD.sh")) {
+       Error("runProcess","Cannot Build the PAR Archive! - Abort!");
+       return -1;
+      }
+    }
+    // check for SETUP.C and execute
+    if (!gSystem->AccessPathName("PROOF-INF/SETUP.C")) {
+      printf("*******************************\n");
+      printf("*** Setup PAR archive       ***\n");
+      printf("*******************************\n");
+      gROOT->Macro("PROOF-INF/SETUP.C");
+    }
+    
+    gSystem->ChangeDirectory(ocwd.Data());
+    printf("Current dir: %s\n", ocwd.Data());
+  }
+}