From 3a72645a6af8c16f05dcfce102fd2b900545a472 Mon Sep 17 00:00:00 2001 From: sma Date: Wed, 8 Dec 2010 16:36:42 +0000 Subject: [PATCH] Major update of the HFE package (comments inside the code and contact Markus Fasel for more questions) --- PWG3/hfe/AliAnalysisTaskCheckV0tender.cxx | 471 +++++++ PWG3/hfe/AliAnalysisTaskCheckV0tender.h | 78 ++ PWG3/hfe/AliAnalysisTaskCheckV0tenderII.cxx | 503 +++++++ PWG3/hfe/AliAnalysisTaskCheckV0tenderII.h | 90 ++ PWG3/hfe/AliAnalysisTaskDCA.cxx | 23 +- .../hfe/AliAnalysisTaskDisplacedElectrons.cxx | 90 +- PWG3/hfe/AliAnalysisTaskHFE.cxx | 1204 +++++++---------- PWG3/hfe/AliAnalysisTaskHFE.h | 95 +- PWG3/hfe/AliESDv0KineCuts.cxx | 902 ++++++++++++ PWG3/hfe/AliESDv0KineCuts.h | 75 + PWG3/hfe/AliHFEV0cuts.cxx | 972 ++++++++++--- PWG3/hfe/AliHFEV0cuts.h | 33 +- PWG3/hfe/AliHFEV0pid.cxx | 370 ++++- PWG3/hfe/AliHFEV0pid.h | 28 +- PWG3/hfe/AliHFEV0pidMC.cxx | 36 +- PWG3/hfe/AliHFEcollection.cxx | 6 +- PWG3/hfe/AliHFEcollection.h | 2 +- PWG3/hfe/AliHFEcontainer.cxx | 73 +- PWG3/hfe/AliHFEcontainer.h | 6 +- PWG3/hfe/AliHFEcutStep.h | 2 +- PWG3/hfe/AliHFEcuts.cxx | 115 +- PWG3/hfe/AliHFEcuts.h | 79 +- PWG3/hfe/AliHFEdetPIDqa.cxx | 81 ++ PWG3/hfe/AliHFEdetPIDqa.h | 59 + PWG3/hfe/AliHFEefficiency.cxx | 5 +- PWG3/hfe/AliHFEefficiency.h | 2 +- PWG3/hfe/AliHFEelecbackground.cxx | 21 +- PWG3/hfe/AliHFEextraCuts.cxx | 318 ++++- PWG3/hfe/AliHFEextraCuts.h | 49 +- PWG3/hfe/AliHFEmcQA.cxx | 21 +- PWG3/hfe/AliHFEpid.cxx | 499 ++----- PWG3/hfe/AliHFEpid.h | 74 +- PWG3/hfe/AliHFEpidBase.cxx | 33 +- PWG3/hfe/AliHFEpidBase.h | 70 +- PWG3/hfe/AliHFEpidITS.cxx | 70 +- PWG3/hfe/AliHFEpidITS.h | 16 +- PWG3/hfe/AliHFEpidMC.cxx | 25 +- PWG3/hfe/AliHFEpidMC.h | 6 +- PWG3/hfe/AliHFEpidQA.cxx | 105 +- PWG3/hfe/AliHFEpidQA.h | 22 +- PWG3/hfe/AliHFEpidQAmanager.cxx | 178 +++ PWG3/hfe/AliHFEpidQAmanager.h | 71 + PWG3/hfe/AliHFEpidTOF.cxx | 355 +---- PWG3/hfe/AliHFEpidTOF.h | 39 +- PWG3/hfe/AliHFEpidTPC.cxx | 234 +--- PWG3/hfe/AliHFEpidTPC.h | 18 +- PWG3/hfe/AliHFEpidTRD.cxx | 180 +-- PWG3/hfe/AliHFEpidTRD.h | 16 +- PWG3/hfe/AliHFEpostAnalysis.cxx | 72 +- PWG3/hfe/AliHFEpostAnalysis.h | 8 +- PWG3/hfe/AliHFEpriVtx.cxx | 4 +- PWG3/hfe/AliHFEpriVtx.h | 4 +- PWG3/hfe/AliHFEsecVtx.cxx | 137 +- PWG3/hfe/AliHFEsecVtx.h | 13 +- PWG3/hfe/AliHFEsignalCuts.cxx | 309 +++++ PWG3/hfe/AliHFEsignalCuts.h | 62 + PWG3/hfe/AliHFEspectrum.cxx | 923 +++++++------ PWG3/hfe/AliHFEspectrum.h | 56 +- PWG3/hfe/AliHFEtaggedTrackAnalysis.cxx | 235 ++++ PWG3/hfe/AliHFEtaggedTrackAnalysis.h | 65 + PWG3/hfe/AliHFEtofPIDqa.cxx | 251 ++++ PWG3/hfe/AliHFEtofPIDqa.h | 59 + PWG3/hfe/AliHFEtools.cxx | 81 +- PWG3/hfe/AliHFEtools.h | 14 +- PWG3/hfe/AliHFEtpcPIDqa.cxx | 269 ++++ PWG3/hfe/AliHFEtpcPIDqa.h | 58 + PWG3/hfe/AliHFEtrdPIDqa.cxx | 32 +- PWG3/hfe/AliHFEtrdPIDqa.h | 6 +- PWG3/hfe/AliHFEtrdPIDqaV1.cxx | 295 ++++ PWG3/hfe/AliHFEtrdPIDqaV1.h | 56 + PWG3/hfe/AliHFEvarManager.cxx | 425 ++++++ PWG3/hfe/AliHFEvarManager.h | 119 ++ 72 files changed, 8287 insertions(+), 3086 deletions(-) create mode 100644 PWG3/hfe/AliAnalysisTaskCheckV0tender.cxx create mode 100644 PWG3/hfe/AliAnalysisTaskCheckV0tender.h create mode 100644 PWG3/hfe/AliAnalysisTaskCheckV0tenderII.cxx create mode 100644 PWG3/hfe/AliAnalysisTaskCheckV0tenderII.h create mode 100644 PWG3/hfe/AliESDv0KineCuts.cxx create mode 100644 PWG3/hfe/AliESDv0KineCuts.h create mode 100644 PWG3/hfe/AliHFEdetPIDqa.cxx create mode 100644 PWG3/hfe/AliHFEdetPIDqa.h create mode 100644 PWG3/hfe/AliHFEpidQAmanager.cxx create mode 100644 PWG3/hfe/AliHFEpidQAmanager.h create mode 100644 PWG3/hfe/AliHFEsignalCuts.cxx create mode 100644 PWG3/hfe/AliHFEsignalCuts.h create mode 100644 PWG3/hfe/AliHFEtaggedTrackAnalysis.cxx create mode 100644 PWG3/hfe/AliHFEtaggedTrackAnalysis.h create mode 100644 PWG3/hfe/AliHFEtofPIDqa.cxx create mode 100644 PWG3/hfe/AliHFEtofPIDqa.h create mode 100644 PWG3/hfe/AliHFEtpcPIDqa.cxx create mode 100644 PWG3/hfe/AliHFEtpcPIDqa.h create mode 100644 PWG3/hfe/AliHFEtrdPIDqaV1.cxx create mode 100644 PWG3/hfe/AliHFEtrdPIDqaV1.h create mode 100644 PWG3/hfe/AliHFEvarManager.cxx create mode 100644 PWG3/hfe/AliHFEvarManager.h diff --git a/PWG3/hfe/AliAnalysisTaskCheckV0tender.cxx b/PWG3/hfe/AliAnalysisTaskCheckV0tender.cxx new file mode 100644 index 00000000000..dbd63222efb --- /dev/null +++ b/PWG3/hfe/AliAnalysisTaskCheckV0tender.cxx @@ -0,0 +1,471 @@ +/************************************************************************** +* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * +* * +* Author: The ALICE Off-line Project. * +* Contributors are mentioned in the code where appropriate. * +* * +* Permission to use, copy, modify and distribute this software and its * +* documentation strictly for non-commercial purposes is hereby granted * +* without fee, provided that the above copyright notice appears in all * +* copies and that both the copyright notice and this permission notice * +* appear in the supporting documentation. The authors make no claims * +* about the suitability of this software for any purpose. It is * +* provided "as is" without express or implied warranty. * +**************************************************************************/ +// +// Task fir checking the performance of the V0 tender +// +// +// Authors +// Matus Kalisky +// + +#include +#include + +#include "AliAnalysisManager.h" +#include "AliMCEventHandler.h" +#include "AliESDInputHandler.h" +#include "AliESDv0.h" +#include "AliESDtrack.h" +#include "AliMCParticle.h" +#include "AliMCEvent.h" + +#include "AliHFEtools.h" +#include "AliHFEcollection.h" + +#include "AliAnalysisTaskCheckV0tender.h" + +ClassImp(AliAnalysisTaskCheckV0tender) + +//__________________________________________________________ +AliAnalysisTaskCheckV0tender::AliAnalysisTaskCheckV0tender(): + AliAnalysisTaskSE("CheckV0tenderTask") + , fOutput(0x0) + , fColl(0x0) + , fCollMC(0x0) + , fEvents(0x0) +{ + // + // Default Constructor + // +} +//__________________________________________________________ +AliAnalysisTaskCheckV0tender::AliAnalysisTaskCheckV0tender(const Char_t *name): + AliAnalysisTaskSE(name) + , fOutput(0x0) + , fColl(0x0) + , fCollMC(0x0) + , fEvents(0x0) +{ + // + // Default Constructor + // + DefineOutput(1, TH1F::Class()); + DefineOutput(2, TList::Class()); + +} +//__________________________________________________________ +AliAnalysisTaskCheckV0tender::~AliAnalysisTaskCheckV0tender(){ + // + // Destructor + // + + if (fOutput) delete fOutput; + if (fColl) delete fColl; + if (fCollMC) delete fCollMC; + if (fEvents) delete fEvents; +} +//__________________________________________________________ +void AliAnalysisTaskCheckV0tender::UserCreateOutputObjects(){ + // + // prepare output objects + // + + fOutput = new TList(); + fOutput->SetOwner(); + // Counter for number of events + fEvents = new TH1I("nEvents", "NumberOfEvents", 1, 1, 2); + + fColl = new AliHFEcollection("V0_QA", "tender V0s for data"); + fCollMC = new AliHFEcollection("V0_MC_QA", "tender V0s for MC"); + + // + // Data histos + // + + // total number of tagged V0s + fColl->CreateTH1F("h_NumberOf_V0s", "Number of tagged V0s; type; counts", 4, -0.5, 3.5); + // pT spectra of the tagged V0s + fColl->CreateTH1F("h_Gamma_pt", "p_{T} spectrum of tagged gammas; p_{T} (GeV/c); counts", 20, 0.1, 20, 0); + fColl->CreateTH1F("h_K0_pt", "p_{T} spectrum of tagged K0s; p_{T} (GeV/c); counts", 20, 0.1, 20, 0); + fColl->CreateTH1F("h_Lambda_pt", "p_{T} spectrum of tagged Lambdas; p_{T} (GeV/c); counts", 20, 0.1, 20, 0); + fColl->CreateTH1F("h_ALambda_pt", "p_{T} spectrum of tagged A-Lambdas; p_{T} (GeV/c); counts", 20, 0.1, 20, 0); + // invariant mass of the V0s + fColl->CreateTH1F("h_Gamma_mass", "Inv. Mass of the ", 100, 0., 0.1); + fColl->CreateTH1F("h_K0_mass", "Inv. Mass of the ", 100, 0.45, 0.55); + fColl->CreateTH1F("h_Lambda_mass", "Inv. Mass of the ", 100, 1.08, 1.14); + fColl->CreateTH1F("h_ALambda_mass", "Inv. Mass of the ", 100, 1.08, 1.14); + + // total number of tagged daughter particles (should correlate with number of V0s ! + fColl->CreateTH1F("h_NumberOfDaughters", "Number of tagged daughters; type; counts", 3, -0.5, 2.5); + // pT spectra of tagged daughter particles + fColl->CreateTH1F("h_Electron_pt", "p_{T} spectrum of tagged; p_{T} (GeV/c); counts", 20, 0.1, 20, 0); + fColl->CreateTH1F("h_Pion_pt", "p_{T} spectrum of tagged; p_{T} (GeV/c); counts", 20, 0.1, 20, 0); + fColl->CreateTH1F("h_Proton_pt", "p_{T} spectrum of tagged; p_{T} (GeV/c); counts", 20, 0.1, 20, 0); + + // + // MC histos + // + + // pT spectra of the tagged V0s + fCollMC->CreateTH1F("h_Gamma_pt_S", "MC-S: p_{T} spectrum of tagged gammas; p_{T} (GeV/c); counts", 20, 0.1, 20, 0); + fCollMC->CreateTH1F("h_K0_pt_S", "MC-S: p_{T} spectrum of tagged K0s; p_{T} (GeV/c); counts", 20, 0.1, 20, 0); + fCollMC->CreateTH1F("h_Lambda_pt_S", "MC-S: p_{T} spectrum of tagged Lambdas; p_{T} (GeV/c); counts", 20, 0.1, 20, 0); + fCollMC->CreateTH1F("h_ALambda_pt_S", "MC-S: p_{T} spectrum of tagged A-Lambdas; p_{T} (GeV/c); counts", 20, 0.1, 20, 0); + fCollMC->CreateTH1F("h_Gamma_pt_B", "MC-B: p_{T} spectrum of tagged gammas; p_{T} (GeV/c); counts", 20, 0.1, 20, 0); + fCollMC->CreateTH1F("h_K0_pt_B", "MC-B: p_{T} spectrum of tagged K0s; p_{T} (GeV/c); counts", 20, 0.1, 20, 0); + fCollMC->CreateTH1F("h_Lambda_pt_B", "MC-B: p_{T} spectrum of tagged Lambdas; p_{T} (GeV/c); counts", 20, 0.1, 20, 0); + fCollMC->CreateTH1F("h_ALambda_pt_B", "MC-B: p_{T} spectrum of tagged A-Lambdas; p_{T} (GeV/c); counts", 20, 0.1, 20, 0); + // invariant mass of the V0s + fCollMC->CreateTH1F("h_Gamma_mass_S", "MC-S: Inv. Mass of the gamma; m (GeV/c^{2}); counts", 100, 0., 0.1); + fCollMC->CreateTH1F("h_K0_mass_S", "MC-S: Inv. Mass of the K0; m (GeV/c^{2}); counts", 100, 0.45, 0.55); + fCollMC->CreateTH1F("h_Lambda_mass_S", "MC-S: Inv. Mass of the Lambda; m (GeV/c^{2}); counts", 100, 1.08, 1.14); + fCollMC->CreateTH1F("h_ALambda_mass_S", "MC-S: Inv. Mass of the A-Lambda; m (GeV/c^{2}); counts", 100, 1.08, 1.14); + fCollMC->CreateTH1F("h_Gamma_mass_B", "MC-B: Inv. Mass of the gamma; m (GeV/c^{2}); counts", 100, 0., 0.1); + fCollMC->CreateTH1F("h_K0_mass_B", "MC-B: Inv. Mass of the K0; m (GeV/c^{2}); counts", 100, 0.45, 0.55); + fCollMC->CreateTH1F("h_Lambda_mass_B", "MC-B: Inv. Mass of the Lambda; m (GeV/c^{2}); counts", 100, 1.08, 1.14); + fCollMC->CreateTH1F("h_ALambda_mass_B", "MC-B: Inv. Mass of the A-Lambda; m (GeV/c^{2}); counts", 100, 1.08, 1.14); + // pT spectra of tagged daughter particles + fCollMC->CreateTH1F("h_Electron_pt_S", "MC-S: p_{T} spectrum of tagged electrons; p_{T} (GeV/c); counts", 20, 0.1, 20, 0); + fCollMC->CreateTH1F("h_Pion_pt_S", "MC-S: p_{T} spectrum of tagged pions; p_{T} (GeV/c); counts", 20, 0.1, 20, 0); + fCollMC->CreateTH1F("h_Proton_pt_S", "MC-S: p_{T} spectrum of tagged protons; p_{T} (GeV/c); counts", 20, 0.1, 20, 0); + fCollMC->CreateTH1F("h_Electron_pt_B", "MC-B: p_{T} spectrum of tagged electrons; p_{T} (GeV/c); counts", 20, 0.1, 20, 0); + fCollMC->CreateTH1F("h_Pion_pt_B", "MC-B: p_{T} spectrum of tagged pions; p_{T} (GeV/c); counts", 20, 0.1, 20, 0); + fCollMC->CreateTH1F("h_Proton_pt_B", "MC-B: p_{T} spectrum of tagged protons; p_{T} (GeV/c); counts", 20, 0.1, 20, 0); + + + TList *tmp = fColl->GetList(); + tmp->SetName(fColl->GetName()); + fOutput->Add(tmp); + tmp = 0x0; + tmp = fCollMC->GetList(); + tmp->SetName(fCollMC->GetName()); + fOutput->Add(tmp); + + +} +//__________________________________________________________ +void AliAnalysisTaskCheckV0tender::UserExec(Option_t *){ + // + // Event Loop + // + AliMCEventHandler* mcHandler = (dynamic_cast(AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler())); + AliESDInputHandler *inh = dynamic_cast(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler()); + AliESDpid *workingPID = NULL; + if(inh && (workingPID = inh->GetESDpid())) workingPID = inh->GetESDpid(); + else workingPID = AliHFEtools::GetDefaultPID(mcHandler ? kTRUE : kFALSE); + + // check the MC data + if(fMCEvent && !mcHandler ) return; + if(fMCEvent && !mcHandler->InitOk() ) return; + if(fMCEvent && !mcHandler->TreeK() ) return; + if(fMCEvent && !mcHandler->TreeTR() ) return; + + ProcessV0s(); + ProcessDaughters(); + + if(fMCEvent){ + ProcessV0sMC(); + ProcessDaughtersMC(); + } + + fEvents->Fill(1.1); + PostData(1, fEvents); + PostData(2, fOutput); +} +//__________________________________________________________ +void AliAnalysisTaskCheckV0tender::Terminate(Option_t *){ + // + // Do Post Processing + // +} +//__________________________________________________________ +void AliAnalysisTaskCheckV0tender::ProcessV0s(){ + // + // loop over the V0s and extract the information about + // the V0s tagged by the V0 tender + // + + const char * type[4] = {"Gamma", "K0", "Lambda", "ALambda"}; + char name[256] = ""; + + Int_t nV0s = fInputEvent->GetNumberOfV0s(); + for(Int_t i=0; i(fInputEvent))->GetV0(i); + if(!esdV0) continue; + if(!esdV0->GetOnFlyStatus()) continue; // Take only V0s from the On-the-fly v0 finder + Int_t pid = GetTenderPidV0(esdV0); + if(pid < 0) continue; + fColl->Fill("h_NumberOf_V0s", pid); + sprintf(name, "h_%s_pt", type[pid]); + Float_t pT = esdV0->Pt(); + fColl->Fill(name, pT); + Float_t mass = MassV0(esdV0, pid); + sprintf(name, "h_%s_mass", type[pid]); + fColl->Fill(name, mass); + } + +} +//__________________________________________________________ +void AliAnalysisTaskCheckV0tender::ProcessDaughters(){ + // + // produce some check plots for V0 tender tagged single tracks + // + + const char * type[3] = {"Electron", "Pion", "Proton"}; + char name[256] = ""; + + Int_t nTracks = fInputEvent->GetNumberOfTracks(); + for(Int_t i=0; i(fInputEvent->GetTrack(i)); + if(!track) continue; + Int_t pid = GetTenderPidDaughter(track); + if(pid < 0) continue; + fColl->Fill("h_NumberOfDaughters", pid*1.0); + Float_t pT = track->Pt(); + sprintf(name, "h_%s_pt", type[pid]); + fColl->Fill(name, pT); + + } +} +//__________________________________________________________ +void AliAnalysisTaskCheckV0tender::ProcessV0sMC(){ + // + // check all V0tender selected V0 on their true identity + // + + const Int_t pid2pdg[4] = {22, 310, 3122, -3122}; + const char * type[4] = {"Gamma", "K0", "Lambda", "ALambda"}; + char name[256] = ""; + Int_t nV0s = fInputEvent->GetNumberOfV0s(); + + Int_t nTracks = fInputEvent->GetNumberOfTracks(); + + // V0 loop + for(Int_t i=0; i(fInputEvent))->GetV0(i); + if(!esdV0) continue; + if(!esdV0->GetOnFlyStatus()) continue; // Take only V0s from the On-the-fly v0 finder + Int_t pid = GetTenderPidV0(esdV0); + if(pid < 0) continue; + + // both ESD daughtr tracks + Int_t iN, iP; + iN = iP = -1; + iP = esdV0->GetPindex(); + iN = esdV0->GetNindex(); + if(iN < 0 || iP < 0) continue; + if(iN >= nTracks || iP >= nTracks) continue; + AliESDtrack *dP, *dN; + dP = dynamic_cast(fInputEvent->GetTrack(iP)); + dN = dynamic_cast(fInputEvent->GetTrack(iN)); + if(!dN || !dP) continue; + + // MC labels of the daughter tracks + Int_t lN, lP; + lN = dN->GetLabel(); + lP = dP->GetLabel(); + if(lN < 0 || lP < 0) continue; + + // MC daughter particles + AliMCParticle *mcP, *mcN; + mcP = dynamic_cast(fMCEvent->GetTrack(lP)); + mcN = dynamic_cast(fMCEvent->GetTrack(lN)); + if(!mcP || !mcN) continue; + + // labels of the mother particles + Int_t lPm, lNm; + lPm = mcP->GetMother(); + lNm = mcN->GetMother(); + if(lPm < 0) continue; + AliMCParticle *m = dynamic_cast(fMCEvent->GetTrack(lPm)); + if(!m) continue; + Int_t pdg = m->PdgCode(); + if((lPm == lNm) && (pdg == pid2pdg[pid])) id = kTRUE; + + if(id) sprintf(name, "h_%s_pt_S", type[pid]); + else sprintf(name, "h_%s_pt_B", type[pid]); + Float_t pT = esdV0->Pt(); + fCollMC->Fill(name, pT); + + if(id) sprintf(name, "h_%s_mass_S", type[pid]); + else sprintf(name, "h_%s_mass_B", type[pid]); + Float_t mass = MassV0(esdV0, pid); + fCollMC->Fill(name, mass); + + } +} +//__________________________________________________________ +void AliAnalysisTaskCheckV0tender::ProcessDaughtersMC(){ + // + // check the identity of the V0tender selected V0 daughters + // !!! for positive check only the true identity plays a role here, + // not the true V0 mother identity (e.g. selected electron could come + // from primary vertex or pion dalitz deca or true gamma conversion) !!! + // + + const Int_t pid2pdg [3] = {11, 211, 2212}; + const char * type[3] = {"Electron", "Pion", "Proton"}; + char name[256] = ""; + + + Int_t nTracks = fInputEvent->GetNumberOfTracks(); + for(Int_t i=0; i(fInputEvent->GetTrack(i)); + if(!track) continue; + Int_t pid = GetTenderPidDaughter(track); + if(pid < 0) continue; + Float_t pT = track->Pt(); + Int_t label = track->GetLabel(); + if(label < 0) continue; + AliMCParticle *mcp = 0x0; + mcp = dynamic_cast(fMCEvent->GetTrack(label)); + if(!mcp) continue; + Int_t pdg = TMath::Abs(mcp->PdgCode()); + if(pdg == pid2pdg[pid]) id = kTRUE; + if(id) sprintf(name, "h_%s_pt_S", type[pid]); + else sprintf(name, "h_%s_pt_B", type[pid]); + fCollMC->Fill(name, pT); + } +} +//__________________________________________________________ +Int_t AliAnalysisTaskCheckV0tender::GetTenderPidV0(AliESDv0 * const v0){ + // + // retrieve the PID nformation stored in the status flags by the train tender + // + Int_t pid = -1; + if(!v0){ + return pid; + } + Int_t nTimes = 0; + if(v0->TestBit(BIT(14))){ + pid = 0; + nTimes++; + } + if(v0->TestBit(BIT(15))){ + pid = 1; + nTimes++; + } + if(v0->TestBit(BIT(16))){ + pid = 2; + nTimes++; + } + if(v0->TestBit(BIT(17))){ + pid = 3; + nTimes++; + } + if(nTimes > 1){ + AliWarning("V0 track labeled multiple times by the V0 tender"); + pid = -1; + } + + //printf(" -D: pid: %i \n", pid); + + return pid; +} +//__________________________________________________________ +Int_t AliAnalysisTaskCheckV0tender::GetTenderPidDaughter(AliESDtrack * const track){ + // + // retrieve the PID nformation stored in the status flags by the train tender + // + + Int_t pid = -1; + if(!track){ + return pid; + } + Int_t nTimes = 0; + if(track->TestBit(BIT(14))){ + pid = 0; + nTimes++; + } + if(track->TestBit(BIT(15))){ + pid = 1; + nTimes++; + } + if(track->TestBit(BIT(16))){ + pid = 2; + nTimes++; + } + if(nTimes > 1){ + AliWarning("V0 track labeled multiple times by the V0 tender"); + pid = -1; + } + return pid; +} +//__________________________________________________________ +Float_t AliAnalysisTaskCheckV0tender::MassV0(AliESDv0 * const v0, Int_t id){ + // + // Get the V0 effective mass + // + + Float_t mass = -0.1; + Bool_t sign = CheckSigns(v0); + if(0 == id){ + mass = v0->GetEffMass(0, 0); + } + else if(1 == id){ + mass = v0->GetEffMass(2, 2); + } + else if(2 == id){ + mass = (sign) ? v0->GetEffMass(4, 2) : v0->GetEffMass(2, 4); + } + else if(3 == id){ + mass = (sign) ? v0->GetEffMass(2, 4) : v0->GetEffMass(4, 2); + } + else{ + AliWarning(Form("Unrecognized V0 id: %i", id)); + } + + return mass; + +} +//__________________________________________________________ +Bool_t AliAnalysisTaskCheckV0tender::CheckSigns(AliESDv0 * const v0){ + // + // check wheter the sign was correctly applied to + // V0 daughter tracks + // This function should become obsolete once the V0 finder will be updated (fixed) + // + + Bool_t correct = kFALSE; + + Int_t pIndex = 0, nIndex = 0; + pIndex = v0->GetPindex(); + nIndex = v0->GetNindex(); + + AliESDtrack* d[2]; + d[0] = dynamic_cast(fInputEvent->GetTrack(pIndex)); + d[1] = dynamic_cast(fInputEvent->GetTrack(nIndex)); + + Int_t sign[2]; + sign[0] = (int)d[0]->GetSign(); + sign[1] = (int)d[1]->GetSign(); + + if(-1 == sign[0] && 1 == sign[1]){ + correct = kFALSE; + //v0->SetIndex(0, pIndex); // set the index of the negative v0 track + //v0->SetIndex(1, nIndex); // set the index of the positive v0 track + } + else{ + correct = kTRUE; + } + + //pIndex = v0->GetPindex(); + //nIndex = v0->GetNindex(); + //printf("-D2: P: %i, N: %i\n", pIndex, nIndex); + + return correct; +} diff --git a/PWG3/hfe/AliAnalysisTaskCheckV0tender.h b/PWG3/hfe/AliAnalysisTaskCheckV0tender.h new file mode 100644 index 00000000000..05de205684a --- /dev/null +++ b/PWG3/hfe/AliAnalysisTaskCheckV0tender.h @@ -0,0 +1,78 @@ +/************************************************************************** +* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * +* * +* Author: The ALICE Off-line Project. * +* Contributors are mentioned in the code where appropriate. * +* * +* Permission to use, copy, modify and distribute this software and its * +* documentation strictly for non-commercial purposes is hereby granted * +* without fee, provided that the above copyright notice appears in all * +* copies and that both the copyright notice and this permission notice * +* appear in the supporting documentation. The authors make no claims * +* about the suitability of this software for any purpose. It is * +* provided "as is" without express or implied warranty. * +**************************************************************************/ +// +// Task for PID QA +// Using AliHFEpidQA and AliHFEMCpidQA +// More information can be found in the source file +// +#ifndef ALIANALYSISTASKCHECKV0TENDER_H +#define ALIANALYSISTASKCHECKV0TENDER_H + +#ifndef ALIANALYSISTASKSE_H +#include "AliAnalysisTaskSE.h" +#endif + +class TH1F; +class TList; +class AliHFEcollection; + +class AliAnalysisTaskCheckV0tender : public AliAnalysisTaskSE{ + public: + enum{ // Reconstructed V0 + kRecoGamma = 0, + kRecoK0 = 1, + kRecoLambda = 2, + kRecoALambda = 3 + + }; + enum{ // Identified Daughter particles + kRecoElectron = 0, + kRecoPionK0 = 1, + kRecoPionL = 2, + kRecoProton = 3 + }; + + AliAnalysisTaskCheckV0tender(); + AliAnalysisTaskCheckV0tender(const Char_t *name); + ~AliAnalysisTaskCheckV0tender(); + + virtual void UserCreateOutputObjects(); + virtual void UserExec(Option_t *); + virtual void Terminate(Option_t *); + + + void ProcessV0s(); + void ProcessDaughters(); + void ProcessV0sMC(); + void ProcessDaughtersMC(); + + Int_t GetTenderPidV0(AliESDv0 * const v0); + Int_t GetTenderPidDaughter(AliESDtrack * const track); + + private: + AliAnalysisTaskCheckV0tender(const AliAnalysisTaskCheckV0tender &ref); + AliAnalysisTaskCheckV0tender &operator=(const AliAnalysisTaskCheckV0tender &ref); + + Float_t MassV0(AliESDv0 * const v0, Int_t id); + Bool_t CheckSigns(AliESDv0 * const v0); + TList *fOutput; //! Container for output histos + AliHFEcollection *fColl; //! collection of Data output + AliHFEcollection *fCollMC; //! collection of MC output + TH1 *fEvents; //! Number of Events + ClassDef(AliAnalysisTaskCheckV0tender, 1) + +}; + +#endif diff --git a/PWG3/hfe/AliAnalysisTaskCheckV0tenderII.cxx b/PWG3/hfe/AliAnalysisTaskCheckV0tenderII.cxx new file mode 100644 index 00000000000..9fe9060a895 --- /dev/null +++ b/PWG3/hfe/AliAnalysisTaskCheckV0tenderII.cxx @@ -0,0 +1,503 @@ +/************************************************************************** +* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * +* * +* Author: The ALICE Off-line Project. * +* Contributors are mentioned in the code where appropriate. * +* * +* Permission to use, copy, modify and distribute this software and its * +* documentation strictly for non-commercial purposes is hereby granted * +* without fee, provided that the above copyright notice appears in all * +* copies and that both the copyright notice and this permission notice * +* appear in the supporting documentation. The authors make no claims * +* about the suitability of this software for any purpose. It is * +* provided "as is" without express or implied warranty. * +**************************************************************************/ +// +// Task fir checking the performance of the V0 tender +// +// +// Authors +// Matus Kalisky +// + +#include +#include + +#include "AliAnalysisManager.h" +#include "AliMCEventHandler.h" +#include "AliESDInputHandler.h" +#include "AliESDv0.h" +#include "AliESDtrack.h" +#include "AliMCParticle.h" +#include "AliMCEvent.h" +#include "AliESDv0KineCuts.h" +#include "AliKFVertex.h" + +#include "AliHFEtools.h" +#include "AliHFEcollection.h" + +#include "AliAnalysisTaskCheckV0tenderII.h" + +ClassImp(AliAnalysisTaskCheckV0tenderII) + +//__________________________________________________________ +AliAnalysisTaskCheckV0tenderII::AliAnalysisTaskCheckV0tenderII(): + AliAnalysisTaskSE("CheckV0tenderTask") + , fOutput(0x0) + , fColl(0x0) + , fCollMC(0x0) + , fV0cuts(0x0) + , fPrimaryVertex(0x0) + , fpdgV0(0) + , fpdgP(0) + , fpdgN(0) + , fEvents(0x0) +{ + // + // Default Constructor + // + + + DefineOutput(1, TH1F::Class()); + DefineOutput(2, TList::Class()); + + +} +//__________________________________________________________ +AliAnalysisTaskCheckV0tenderII::AliAnalysisTaskCheckV0tenderII(const Char_t *name): + AliAnalysisTaskSE(name) + , fOutput(0x0) + , fColl(0x0) + , fCollMC(0x0) + , fV0cuts(0x0) + , fPrimaryVertex(0x0) + , fpdgV0(0) + , fpdgP(0) + , fpdgN(0) + , fEvents(0x0) +{ + // + // Constructor + // + + DefineOutput(1, TH1F::Class()); + DefineOutput(2, TList::Class()); + +} +//__________________________________________________________ +AliAnalysisTaskCheckV0tenderII::~AliAnalysisTaskCheckV0tenderII(){ + // + // Destructor + // + + if (fOutput) delete fOutput; + if (fColl) delete fColl; + if (fCollMC) delete fCollMC; + if (fV0cuts) delete fV0cuts; + if (fPrimaryVertex) delete fPrimaryVertex; + if (fEvents) delete fEvents; +} +//__________________________________________________________ +void AliAnalysisTaskCheckV0tenderII::UserCreateOutputObjects(){ + // + // prepare output objects + // + + fOutput = new TList(); + //fOutput->SetOwner(); + // Counter for number of events + fEvents = new TH1I("nEvents", "NumberOfEvents", 1, 1, 2); + + fColl = new AliHFEcollection("V0_QA", "tender V0s for data"); + fCollMC = new AliHFEcollection("V0_MC_QA", "tender V0s for MC"); + + fV0cuts = new AliESDv0KineCuts(); + if(!fV0cuts){ + AliError("Failed to initialize AliESDv0KineCuts instance"); + return; + } + + // + // Data histos + // + + // total number of tagged V0s + fColl->CreateTH1F("h_NumberOf_V0s", "Number of tagged V0s; type; counts", 4, -0.5, 3.5); + // pT spectra of the tagged V0s + fColl->CreateTH1F("h_Gamma_pt", "p_{T} spectrum of tagged gammas; p_{T} (GeV/c); counts", 20, 0.1, 20, 0); + fColl->CreateTH1F("h_K0_pt", "p_{T} spectrum of tagged K0s; p_{T} (GeV/c); counts", 20, 0.1, 20, 0); + fColl->CreateTH1F("h_Lambda_pt", "p_{T} spectrum of tagged Lambdas; p_{T} (GeV/c); counts", 20, 0.1, 20, 0); + fColl->CreateTH1F("h_ALambda_pt", "p_{T} spectrum of tagged A-Lambdas; p_{T} (GeV/c); counts", 20, 0.1, 20, 0); + // invariant mass of the V0s + fColl->CreateTH1F("h_Gamma_mass", "Inv. Mass of the ", 100, 0., 0.1); + fColl->CreateTH1F("h_K0_mass", "Inv. Mass of the ", 100, 0.45, 0.55); + fColl->CreateTH1F("h_Lambda_mass", "Inv. Mass of the ", 100, 1.08, 1.14); + fColl->CreateTH1F("h_ALambda_mass", "Inv. Mass of the ", 100, 1.08, 1.14); + + // total number of tagged daughter particles (should correlate with number of V0s ! + fColl->CreateTH1F("h_NumberOfDaughters", "Number of tagged daughters; type; counts", 3, -0.5, 2.5); + // pT spectra of tagged daughter particles + fColl->CreateTH1F("h_Electron_pt", "p_{T} spectrum of tagged; p_{T} (GeV/c); counts", 20, 0.1, 20, 0); + fColl->CreateTH1F("h_Pion_pt", "p_{T} spectrum of tagged; p_{T} (GeV/c); counts", 20, 0.1, 20, 0); + fColl->CreateTH1F("h_Proton_pt", "p_{T} spectrum of tagged; p_{T} (GeV/c); counts", 20, 0.1, 20, 0); + + // + // MC histos + // + + // pT spectra of the tagged V0s + fCollMC->CreateTH1F("h_Gamma_pt_S", "MC-S: p_{T} spectrum of tagged gammas; p_{T} (GeV/c); counts", 20, 0.1, 20, 0); + fCollMC->CreateTH1F("h_K0_pt_S", "MC-S: p_{T} spectrum of tagged K0s; p_{T} (GeV/c); counts", 20, 0.1, 20, 0); + fCollMC->CreateTH1F("h_Lambda_pt_S", "MC-S: p_{T} spectrum of tagged Lambdas; p_{T} (GeV/c); counts", 20, 0.1, 20, 0); + fCollMC->CreateTH1F("h_ALambda_pt_S", "MC-S: p_{T} spectrum of tagged A-Lambdas; p_{T} (GeV/c); counts", 20, 0.1, 20, 0); + fCollMC->CreateTH1F("h_Gamma_pt_B", "MC-B: p_{T} spectrum of tagged gammas; p_{T} (GeV/c); counts", 20, 0.1, 20, 0); + fCollMC->CreateTH1F("h_K0_pt_B", "MC-B: p_{T} spectrum of tagged K0s; p_{T} (GeV/c); counts", 20, 0.1, 20, 0); + fCollMC->CreateTH1F("h_Lambda_pt_B", "MC-B: p_{T} spectrum of tagged Lambdas; p_{T} (GeV/c); counts", 20, 0.1, 20, 0); + fCollMC->CreateTH1F("h_ALambda_pt_B", "MC-B: p_{T} spectrum of tagged A-Lambdas; p_{T} (GeV/c); counts", 20, 0.1, 20, 0); + // invariant mass of the V0s + fCollMC->CreateTH1F("h_Gamma_mass_S", "MC-S: Inv. Mass of the gamma; m (GeV/c^{2}); counts", 100, 0., 0.1); + fCollMC->CreateTH1F("h_K0_mass_S", "MC-S: Inv. Mass of the K0; m (GeV/c^{2}); counts", 100, 0.45, 0.55); + fCollMC->CreateTH1F("h_Lambda_mass_S", "MC-S: Inv. Mass of the Lambda; m (GeV/c^{2}); counts", 100, 1.08, 1.14); + fCollMC->CreateTH1F("h_ALambda_mass_S", "MC-S: Inv. Mass of the A-Lambda; m (GeV/c^{2}); counts", 100, 1.08, 1.14); + fCollMC->CreateTH1F("h_Gamma_mass_B", "MC-B: Inv. Mass of the gamma; m (GeV/c^{2}); counts", 100, 0., 0.1); + fCollMC->CreateTH1F("h_K0_mass_B", "MC-B: Inv. Mass of the K0; m (GeV/c^{2}); counts", 100, 0.45, 0.55); + fCollMC->CreateTH1F("h_Lambda_mass_B", "MC-B: Inv. Mass of the Lambda; m (GeV/c^{2}); counts", 100, 1.08, 1.14); + fCollMC->CreateTH1F("h_ALambda_mass_B", "MC-B: Inv. Mass of the A-Lambda; m (GeV/c^{2}); counts", 100, 1.08, 1.14); + // pT spectra of tagged daughter particles + fCollMC->CreateTH1F("h_Electron_pt_S", "MC-S: p_{T} spectrum of tagged electrons; p_{T} (GeV/c); counts", 20, 0.1, 20, 0); + fCollMC->CreateTH1F("h_Pion_pt_S", "MC-S: p_{T} spectrum of tagged pions; p_{T} (GeV/c); counts", 20, 0.1, 20, 0); + fCollMC->CreateTH1F("h_Proton_pt_S", "MC-S: p_{T} spectrum of tagged protons; p_{T} (GeV/c); counts", 20, 0.1, 20, 0); + fCollMC->CreateTH1F("h_Electron_pt_B", "MC-B: p_{T} spectrum of tagged electrons; p_{T} (GeV/c); counts", 20, 0.1, 20, 0); + fCollMC->CreateTH1F("h_Pion_pt_B", "MC-B: p_{T} spectrum of tagged pions; p_{T} (GeV/c); counts", 20, 0.1, 20, 0); + fCollMC->CreateTH1F("h_Proton_pt_B", "MC-B: p_{T} spectrum of tagged protons; p_{T} (GeV/c); counts", 20, 0.1, 20, 0); + + + TList *tmp = fColl->GetList(); + tmp->SetName(fColl->GetName()); + fOutput->Add(tmp); + tmp = 0x0; + tmp = fCollMC->GetList(); + tmp->SetName(fCollMC->GetName()); + fOutput->Add(tmp); + + +} +//__________________________________________________________ +void AliAnalysisTaskCheckV0tenderII::UserExec(Option_t *){ + // + // Event Loop + // + AliMCEventHandler* mcHandler = (dynamic_cast(AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler())); + AliESDInputHandler *inh = dynamic_cast(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler()); + AliESDpid *workingPID = NULL; + if(inh && (workingPID = inh->GetESDpid())) workingPID = inh->GetESDpid(); + else workingPID = AliHFEtools::GetDefaultPID(mcHandler ? kTRUE : kFALSE); + + // check the MC data + if(fMCEvent && !mcHandler ) return; + if(fMCEvent && !mcHandler->InitOk() ) return; + if(fMCEvent && !mcHandler->TreeK() ) return; + if(fMCEvent && !mcHandler->TreeTR() ) return; + + fPrimaryVertex = new AliKFVertex(*(fInputEvent->GetPrimaryVertex())); + if(!fPrimaryVertex) return; + + fV0cuts->SetEvent(fInputEvent); + fV0cuts->SetPrimaryVertex(fPrimaryVertex); + + ProcessV0s(); + + fEvents->Fill(1.1); + PostData(1, fEvents); + PostData(2, fOutput); +} +//__________________________________________________________ +void AliAnalysisTaskCheckV0tenderII::Terminate(Option_t *){ + // + // Do Post Processing + // +} +//__________________________________________________________ +void AliAnalysisTaskCheckV0tenderII::ProcessV0s(){ + // + // loop over the V0s and extract the information about + // the V0s tagged by the V0 tender + // + + const char * type[4] = {"Gamma", "K0", "Lambda", "ALambda"}; + char name[256] = ""; + + Int_t nV0s = fInputEvent->GetNumberOfV0s(); + for(Int_t i=0; i(fInputEvent))->GetV0(i); + if(!esdV0) continue; + if(!esdV0->GetOnFlyStatus()) continue; // Take only V0s from the On-the-fly v0 finder + + // New standalone V0 selection software + if( ! (fV0cuts->ProcessV0(esdV0, fpdgV0, fpdgP, fpdgN)) ) return; + + Int_t pid = PDGtoPIDv0(fpdgV0); + //printf(" -D: pdg: %i, pid: %i\n", fpdgV0, pid); + if(pid <= -1) continue; + + fColl->Fill("h_NumberOf_V0s", pid); + sprintf(name, "h_%s_pt", type[pid]); + Float_t pT = esdV0->Pt(); + fColl->Fill(name, pT); + Float_t mass = MassV0(esdV0, pid); + sprintf(name, "h_%s_mass", type[pid]); + fColl->Fill(name, mass); + + ProcessDaughters(esdV0); + if(fMCEvent){ + ProcessV0sMC(esdV0); + ProcessDaughtersMC(esdV0); + } + + } + +} +//__________________________________________________________ +void AliAnalysisTaskCheckV0tenderII::ProcessDaughters(AliESDv0 * const v0){ + // + // produce some check plots for V0 tender tagged single tracks + // + + const char * type[3] = {"Electron", "Pion", "Proton"}; + char name[256] = ""; + + if(!v0) return; + + // daughter tracks + const Int_t nTracks = fInputEvent->GetNumberOfTracks(); + AliESDtrack *d[2]; + Int_t iN, iP; + iN = iP = -1; + iP = v0->GetPindex(); + iN = v0->GetNindex(); + if(iN < 0 || iP < 0) return; + if(iN >= nTracks || iP >= nTracks) return; + d[0] = dynamic_cast(fInputEvent->GetTrack(iP)); + d[1] = dynamic_cast(fInputEvent->GetTrack(iN)); + if(!d[0] || !d[1]) return; + + for(Int_t i=0; i<2; ++i){ + Int_t pid = (i == 0) ? PDGtoPID(fpdgP) : PDGtoPID(fpdgN); + if(pid < 0) continue; + fColl->Fill("h_NumberOfDaughters", pid*1.0); + Float_t pT = d[i]->Pt(); + sprintf(name, "h_%s_pt", type[pid]); + fColl->Fill(name, pT); + + } +} +//__________________________________________________________ +void AliAnalysisTaskCheckV0tenderII::ProcessV0sMC(AliESDv0 * const v0){ + // + // check all V0tender selected V0 on their true identity + // + + const char * type[4] = {"Gamma", "K0", "Lambda", "ALambda"}; + char name[256] = ""; + + + Int_t pid = PDGtoPIDv0(fpdgV0); + if(pid < 0) return; + + // true if fpdgV0 agrees with MC pdg of the mother + Bool_t id = kFALSE; + const Int_t nTracks = fInputEvent->GetNumberOfTracks(); + // both ESD daughtr tracks + Int_t iN, iP; + iN = iP = -1; + iP = v0->GetPindex(); + iN = v0->GetNindex(); + if(iN < 0 || iP < 0) return; + if(iN >= nTracks || iP >= nTracks) return; + AliESDtrack *dP, *dN; + dP = dynamic_cast(fInputEvent->GetTrack(iP)); + dN = dynamic_cast(fInputEvent->GetTrack(iN)); + if(!dN || !dP) return; + + // MC labels of the daughter tracks + Int_t lN, lP; + lN = dN->GetLabel(); + lP = dP->GetLabel(); + if(lN < 0 || lP < 0) return; + + // MC daughter particles + AliMCParticle *mcP, *mcN; + mcP = dynamic_cast(fMCEvent->GetTrack(lP)); + mcN = dynamic_cast(fMCEvent->GetTrack(lN)); + if(!mcP || !mcN) return; + + // labels of the mother particles + Int_t lPm, lNm; + lPm = mcP->GetMother(); + lNm = mcN->GetMother(); + AliMCParticle *m = 0x0; + // particles without mother particle are most probably + // primary particles + if(lPm >= 0){ + m = dynamic_cast(fMCEvent->GetTrack(lPm)); + if(!m) return; + } + if(m){ + Int_t pdg = m->PdgCode(); + //if(lPm == lNm) printf(" -D: pdg: %i, fpdgV0: %i \n", pdg, fpdgV0); + if((lPm == lNm) && (pdg == fpdgV0)) id = kTRUE; + } + + if(id) sprintf(name, "h_%s_pt_S", type[pid]); + else sprintf(name, "h_%s_pt_B", type[pid]); + Float_t pT = v0->Pt(); + fCollMC->Fill(name, pT); + + if(id) sprintf(name, "h_%s_mass_S", type[pid]); + else sprintf(name, "h_%s_mass_B", type[pid]); + Float_t mass = MassV0(v0, pid); + fCollMC->Fill(name, mass); + + +} +//__________________________________________________________ +void AliAnalysisTaskCheckV0tenderII::ProcessDaughtersMC(AliESDv0 * const v0){ + // + // check the identity of the V0tender selected V0 daughters + // !!! for positive check only the true identity plays a role here, + // not the true V0 mother identity (e.g. selected electron could come + // from primary vertex or pion dalitz deca or true gamma conversion) !!! + // + + const char * type[3] = {"Electron", "Pion", "Proton"}; + char name[256] = ""; + + if(!v0) return; + + // daughter tracks + const Int_t nTracks = fInputEvent->GetNumberOfTracks(); + AliESDtrack *d[2]; + Int_t iN, iP; + iN = iP = -1; + iP = v0->GetPindex(); + iN = v0->GetNindex(); + if(iN < 0 || iP < 0) return; + if(iN >= nTracks || iP >= nTracks) return; + d[0] = dynamic_cast(fInputEvent->GetTrack(iP)); + d[1] = dynamic_cast(fInputEvent->GetTrack(iN)); + if(!d[0] || !d[1]) return; + + //printf(" *** fpdgV0: %i, fpdgP: %i, fpdgN: %i \n", fpdgV0, fpdgP, fpdgN); + + for(Int_t i=0; i<2; ++i){ + Bool_t id = kFALSE; + Int_t pid = (i == 0) ? PDGtoPID(fpdgP) : PDGtoPID(fpdgN); + Int_t pdg = (i == 0) ? fpdgP : fpdgN; + if(pid < 0) continue; + Float_t pT = d[i]->Pt(); + Int_t label = d[i]->GetLabel(); + if(label < 0) continue; + AliMCParticle *mcp = 0x0; + mcp = dynamic_cast(fMCEvent->GetTrack(label)); + if(!mcp) continue; + Int_t pdgMC = mcp->PdgCode(); + //printf(" * pid: %i, pdg: %i, pdgMC: %i \n", pid, pdg, pdgMC); + if(pdgMC == pdg) id = kTRUE; + if(id) sprintf(name, "h_%s_pt_S", type[pid]); + else sprintf(name, "h_%s_pt_B", type[pid]); + fCollMC->Fill(name, pT); + } +} +//__________________________________________________________ +Float_t AliAnalysisTaskCheckV0tenderII::MassV0(AliESDv0 * const v0, Int_t id){ + // + // Get the V0 effective mass + // + + Float_t mass = -0.1; + Bool_t sign = CheckSigns(v0); + if(0 == id){ + mass = v0->GetEffMass(0, 0); + } + else if(1 == id){ + mass = v0->GetEffMass(2, 2); + } + else if(2 == id){ + mass = (sign) ? v0->GetEffMass(4, 2) : v0->GetEffMass(2, 4); + } + else if(3 == id){ + mass = (sign) ? v0->GetEffMass(2, 4) : v0->GetEffMass(4, 2); + } + else{ + AliWarning(Form("Unrecognized V0 id: %i", id)); + } + + return mass; + +} +//__________________________________________________________ +Bool_t AliAnalysisTaskCheckV0tenderII::CheckSigns(AliESDv0 * const v0){ + // + // check wheter the sign was correctly applied to + // V0 daughter tracks + // This function should become obsolete once the V0 finder will be updated (fixed) + // + + Bool_t correct = kFALSE; + + Int_t pIndex = 0, nIndex = 0; + pIndex = v0->GetPindex(); + nIndex = v0->GetNindex(); + + AliESDtrack* d[2]; + d[0] = dynamic_cast(fInputEvent->GetTrack(pIndex)); + d[1] = dynamic_cast(fInputEvent->GetTrack(nIndex)); + + Int_t sign[2]; + sign[0] = (int)d[0]->GetSign(); + sign[1] = (int)d[1]->GetSign(); + + if(-1 == sign[0] && 1 == sign[1]){ + correct = kFALSE; + //v0->SetIndex(0, pIndex); // set the index of the negative v0 track + //v0->SetIndex(1, nIndex); // set the index of the positive v0 track + } + else{ + correct = kTRUE; + } + + //pIndex = v0->GetPindex(); + //nIndex = v0->GetNindex(); + //printf("-D2: P: %i, N: %i\n", pIndex, nIndex); + + return correct; +} +//__________________________________________________________ +const Int_t AliAnalysisTaskCheckV0tenderII::PDGtoPIDv0(Int_t pdgV0){ + // + // convert thereconstructed V0 pdg to local pid + // + + switch(pdgV0){ + case 22: return 0; break; + case 310: return 1; break; + case 3122: return 2; break; + case -3122: return 3; break; + } + + return -1; + +} +//__________________________________________________________ +const Int_t AliAnalysisTaskCheckV0tenderII::PDGtoPID(Int_t pdg){ + // + // convert daughter pdg code to local pid + // + switch(TMath::Abs(pdg)){ + case 11: return 0; break; + case 211: return 1; break; + case 2212: return 2; break; + } + return -1; + +} diff --git a/PWG3/hfe/AliAnalysisTaskCheckV0tenderII.h b/PWG3/hfe/AliAnalysisTaskCheckV0tenderII.h new file mode 100644 index 00000000000..5563d7ae966 --- /dev/null +++ b/PWG3/hfe/AliAnalysisTaskCheckV0tenderII.h @@ -0,0 +1,90 @@ +/************************************************************************** +* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * +* * +* Author: The ALICE Off-line Project. * +* Contributors are mentioned in the code where appropriate. * +* * +* Permission to use, copy, modify and distribute this software and its * +* documentation strictly for non-commercial purposes is hereby granted * +* without fee, provided that the above copyright notice appears in all * +* copies and that both the copyright notice and this permission notice * +* appear in the supporting documentation. The authors make no claims * +* about the suitability of this software for any purpose. It is * +* provided "as is" without express or implied warranty. * +**************************************************************************/ +// +// Task for PID QA +// Using AliHFEpidQA and AliHFEMCpidQA +// More information can be found in the source file +// +#ifndef ALIANALYSISTASKCHECKV0TENDERII_H +#define ALIANALYSISTASKCHECKV0TENDERII_H + +#ifndef ALIANALYSISTASKSE_H +#include "AliAnalysisTaskSE.h" +#endif + +class TH1F; +class TList; +class AliHFEcollection; +class AliESDv0KineCuts; +class AliKFVertex; + +class AliAnalysisTaskCheckV0tenderII : public AliAnalysisTaskSE{ + public: + enum{ // Reconstructed V0 + kRecoGamma = 0, + kRecoK0 = 1, + kRecoLambda = 2, + kRecoALambda = 3 + + }; + enum{ // Identified Daughter particles + kRecoElectron = 0, + kRecoPionK0 = 1, + kRecoPionL = 2, + kRecoProton = 3 + }; + + AliAnalysisTaskCheckV0tenderII(); + AliAnalysisTaskCheckV0tenderII(const Char_t *name); + ~AliAnalysisTaskCheckV0tenderII(); + + virtual void UserCreateOutputObjects(); + virtual void UserExec(Option_t *); + virtual void Terminate(Option_t *); + + + void ProcessV0s(); + void ProcessDaughters(AliESDv0 * const v0); + void ProcessV0sMC(AliESDv0 * const v0); + void ProcessDaughtersMC(AliESDv0 * const v0); + + private: + AliAnalysisTaskCheckV0tenderII(const AliAnalysisTaskCheckV0tenderII &ref); + AliAnalysisTaskCheckV0tenderII &operator=(const AliAnalysisTaskCheckV0tenderII &ref); + + Float_t MassV0(AliESDv0 * const v0, Int_t id); + Bool_t CheckSigns(AliESDv0 * const v0); + + const Int_t PDGtoPIDv0(Int_t pdgV0); + const Int_t PDGtoPID(Int_t pdg); + + + TList *fOutput; //! Container for output histos + AliHFEcollection *fColl; //! collection of Data output + AliHFEcollection *fCollMC; //! collection of MC output + AliESDv0KineCuts *fV0cuts; //! standalone V0 selection class + AliKFVertex *fPrimaryVertex; //! primary vertex of the current event + + Int_t fpdgV0; // PDG code of teh reconstructed V0 + Int_t fpdgP; // PDG code of the positive daughter (sign corrected) + Int_t fpdgN; // PDG code of the negative daughter (sign coreccted) + + TH1 *fEvents; //! Number of Events + + ClassDef(AliAnalysisTaskCheckV0tenderII, 1) + +}; + +#endif diff --git a/PWG3/hfe/AliAnalysisTaskDCA.cxx b/PWG3/hfe/AliAnalysisTaskDCA.cxx index 2e9c2ddd327..3fee448648e 100644 --- a/PWG3/hfe/AliAnalysisTaskDCA.cxx +++ b/PWG3/hfe/AliAnalysisTaskDCA.cxx @@ -322,11 +322,8 @@ void AliAnalysisTaskDCA::UserCreateOutputObjects(){ if(fHFEpid && GetPlugin(kHFEpid)) { fHFEpid->SetHasMCData(HasMCData()); - if(!fPIDdetectors.Length() && ! fPIDstrategy) AddPIDdetector("TPC"); - if(fPIDstrategy) - fHFEpid->InitializePID(Form("Strategy%d", fPIDstrategy)); - else - fHFEpid->InitializePID(fPIDdetectors.Data()); // Only restrictions to TPC allowed + fHFEpid->AddDetector("TPC", 0); + fHFEpid->InitializePID(); } // dca study---------------------------------- @@ -502,19 +499,19 @@ void AliAnalysisTaskDCA::ProcessDcaAnalysis(){ if(HasMCData())mctrack = dynamic_cast(fMC->GetTrack(TMath::Abs(track->GetLabel()))); // RecPrim: primary cuts - if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepRecPrim, track)) continue; + if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepRecPrim + AliHFEcuts::kNcutStepsMCTrack, track)) continue; // RecKine: ITSTPC cuts - if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepRecKineITSTPC, track)) continue; + if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepRecKineITSTPC + AliHFEcuts::kNcutStepsMCTrack, track)) continue; // HFEcuts: ITS layers cuts - if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepHFEcutsITS, track)) continue; + if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepHFEcutsITS + AliHFEcuts::kNcutStepsMCTrack, track)) continue; if(track->GetITSclusters(0)<=fNclustersITS) continue; // require number of ITS clusters // track accepted, do PID AliHFEpidObject hfetrack; - hfetrack.fAnalysisType = AliHFEpidObject::kESDanalysis; - hfetrack.fRecTrack = track; - if(HasMCData()) hfetrack.fMCtrack = mctrack; + hfetrack.SetAnalysisType(AliHFEpidObject::kESDanalysis); + hfetrack.SetRecTrack(track); + if(HasMCData()) hfetrack.SetMCTrack(mctrack); if(HasMCData()){ if(GetPlugin(kPrimVtx)) @@ -691,7 +688,9 @@ void AliAnalysisTaskDCA::MakeParticleContainer(){ for(Int_t i=0; i<=iBin[2]; i++) binEdges[2][i]=(Double_t)kPhimin + (kPhimax-kPhimin)/iBin[2]*(Double_t)i; //one "container" for MC - AliCFContainer* container = new AliCFContainer("container","container for tracks", (AliHFEcuts::kNcutStepsTrack + 1 + 2*(AliHFEcuts::kNcutStepsESDtrack + 1)), kNvar, iBin); + const Int_t kNcutStepsESDtrack = AliHFEcuts::kNcutStepsRecTrack + 1; + const Int_t kNcutStepsTrack = AliHFEcuts::kNcutStepsMCTrack + kNcutStepsESDtrack; + AliCFContainer* container = new AliCFContainer("container","container for tracks", (kNcutStepsTrack + 1 + 2*(kNcutStepsESDtrack + 1)), kNvar, iBin); //setting the bin limits for(Int_t ivar = 0; ivar < kNvar; ivar++) diff --git a/PWG3/hfe/AliAnalysisTaskDisplacedElectrons.cxx b/PWG3/hfe/AliAnalysisTaskDisplacedElectrons.cxx index 6ea0a9b92d0..f302ebf374d 100644 --- a/PWG3/hfe/AliAnalysisTaskDisplacedElectrons.cxx +++ b/PWG3/hfe/AliAnalysisTaskDisplacedElectrons.cxx @@ -89,7 +89,7 @@ AliAnalysisTaskDisplacedElectrons::AliAnalysisTaskDisplacedElectrons(): // Initialize pid fDeDefaultPID = new AliESDpid; - fDePID = new AliHFEpid; + fDePID = new AliHFEpid("DEPID"); } @@ -126,7 +126,7 @@ AliAnalysisTaskDisplacedElectrons::AliAnalysisTaskDisplacedElectrons(const char // Initialize pid fDeDefaultPID = new AliESDpid; - fDePID = new AliHFEpid; + fDePID = new AliHFEpid("DEPID"); } @@ -196,7 +196,7 @@ AliAnalysisTaskDisplacedElectrons::~AliAnalysisTaskDisplacedElectrons(){ if(fDePID) delete fDePID; if(fDeCFM) delete fDeCFM; if(fDisplacedElectrons) delete fDisplacedElectrons; - + return; if(fDeNEvents) delete fDeNEvents; if(fElectronsMcPt) delete fElectronsMcPt; if(fElectronsEsdPt) delete fElectronsEsdPt; @@ -264,20 +264,13 @@ void AliAnalysisTaskDisplacedElectrons::UserCreateOutputObjects(){ fDeCuts->Initialize(fDeCFM); - if(GetPlugin(kDePidQA)){ - AliInfo("PID QA switched on"); - // fPID->SetDebugLevel(2); - fDePID->SetQAOn(); - fDeQA->Add(fDePID->GetQAhistograms()); - } - fDePID->SetHasMCData(HasMCData()); - if(!fDePIDdetectors.Length() && ! fDePIDstrategy) AddPIDdetector("TPC"); - if(fDePIDstrategy) - fDePID->InitializePID(Form("Strategy%d", fDePIDstrategy)); - else - fDePID->InitializePID(fDePIDdetectors.Data()); // Only restrictions to TPC allowed - + fDePID->AddDetector("TPC", 0); + fDePID->AddDetector("TOF", 1); + fDePID->ConfigureTPCrejection(); + fDePID->InitializePID(); // Only restrictions to TPC allowed + + // displaced electron study---------------------------------- if(GetPlugin(kDisplacedElectrons)){ @@ -319,13 +312,14 @@ void AliAnalysisTaskDisplacedElectrons::UserExec(Option_t *){ // from now on, only ESD are analyzed // using HFE pid, using HFE cuts // using CORRFW - AliESDpid *workingPID = inH->GetESDpid(); if(workingPID){ AliDebug(1, "Using ESD PID from the input handler"); + //printf("\n ESD PID\n"); fDePID->SetESDpid(workingPID); } else { AliDebug(1, "Using default ESD PID"); + //printf(" DEFAULT PID!\n\n"); fDePID->SetESDpid(AliHFEtools::GetDefaultPID(HasMCData())); } @@ -459,6 +453,8 @@ void AliAnalysisTaskDisplacedElectrons::ProcessESD(){ // process data: ESD tracks with MC information + const Int_t kStepPID = AliHFEcuts::kStepHFEcutsTRD + 1; + Double_t esdContainer[4]; // container for the output in THnSparse memset(esdContainer, 0, sizeof(Double_t) * 4); AliESDEvent *fESD = dynamic_cast(fInputEvent); @@ -499,43 +495,43 @@ void AliAnalysisTaskDisplacedElectrons::ProcessESD(){ alreadyseen = cont.Find(TMath::Abs(track->GetLabel())); cont.Append(TMath::Abs(track->GetLabel())); // check double counting if(alreadyseen) continue; // avoid double counting - if(GetPlugin(kCorrection)) fDeCFM->GetParticleContainer()->Fill(esdContainer, 1+AliHFEcuts::kStepRecNoCut); + if(GetPlugin(kCorrection)) fDeCFM->GetParticleContainer()->Fill(esdContainer, 1+AliHFEcuts::kStepRecNoCut + AliHFEcuts::kNcutStepsMCTrack); // 1st track cut // RecKine: ITSTPC cuts : ITS & TPC refit, covmatrix: (2, 2, 0.5, 0.5, 2); min_tpccls: 50, chi2_tpccls: 3.5 - if(!fDeCFM->CheckParticleCuts(AliHFEcuts::kStepRecKineITSTPC, track)) continue; - if(GetPlugin(kCorrection)) fDeCFM->GetParticleContainer()->Fill(esdContainer, 1+AliHFEcuts::kStepRecKineITSTPC); + if(!fDeCFM->CheckParticleCuts(AliHFEcuts::kStepRecKineITSTPC + AliHFEcuts::kNcutStepsMCTrack, track)) continue; + if(GetPlugin(kCorrection)) fDeCFM->GetParticleContainer()->Fill(esdContainer, 1+AliHFEcuts::kStepRecKineITSTPC + AliHFEcuts::kNcutStepsMCTrack); // 2nd track cut // RecPrim: cut on track quality : DCA to vertex max: 3cm and 10cm; reject kink daughters - if(!fDeCFM->CheckParticleCuts(AliHFEcuts::kStepRecPrim, track)) continue; - if(GetPlugin(kCorrection)) fDeCFM->GetParticleContainer()->Fill(esdContainer, 1+AliHFEcuts::kStepRecPrim); + if(!fDeCFM->CheckParticleCuts(AliHFEcuts::kStepRecPrim + AliHFEcuts::kNcutStepsMCTrack, track)) continue; + if(GetPlugin(kCorrection)) fDeCFM->GetParticleContainer()->Fill(esdContainer, 1+AliHFEcuts::kStepRecPrim + AliHFEcuts::kNcutStepsMCTrack); // 3rd track cut // HFEcuts: ITS layers cuts: ITS pixel layer: kFirst, kSecond, kBoth, kNone or kAny - if(!fDeCFM->CheckParticleCuts(AliHFEcuts::kStepHFEcutsITS, track)) continue; - if(GetPlugin(kCorrection))fDeCFM->GetParticleContainer()->Fill(esdContainer, 1+AliHFEcuts::kStepHFEcutsITS); + if(!fDeCFM->CheckParticleCuts(AliHFEcuts::kStepHFEcutsITS + AliHFEcuts::kNcutStepsMCTrack, track)) continue; + if(GetPlugin(kCorrection))fDeCFM->GetParticleContainer()->Fill(esdContainer, 1+AliHFEcuts::kStepHFEcutsITS + AliHFEcuts::kNcutStepsMCTrack); /* // 4th track cut // TRD: number of tracklets in TRD - if(!fDeCFM->CheckParticleCuts(AliHFEcuts::kStepHFEcutsTRD, track)) continue; - if(GetPlugin(kCorrection)) fDeCFM->GetParticleContainer()->Fill(esdContainer, 1+AliHFEcuts::kStepHFEcutsTRD); + if(!fDeCFM->CheckParticleCuts(AliHFEcuts::kStepHFEcutsTRD + AliHFEcuts::kNcutStepsMCTrack, track)) continue; + if(GetPlugin(kCorrection)) fDeCFM->GetParticleContainer()->Fill(esdContainer, 1+AliHFEcuts::kStepHFEcutsTRD + AliHFEcuts::kNcutStepsMCTrack); */ // 5th track cut // track accepted, do PID // --> only electron candidate will be processed AliHFEpidObject hfetrack; - hfetrack.fAnalysisType = AliHFEpidObject::kESDanalysis; - hfetrack.fRecTrack = track; - // if(HasMCData())hfetrack.fMCtrack = mctrack; + hfetrack.SetAnalysisType(AliHFEpidObject::kESDanalysis); + hfetrack.SetRecTrack(track); + //if(HasMCData())hfetrack.SetMCTrack(mctrack); if(!fDePID->IsSelected(&hfetrack)) continue; else if(fDeDebugLevel>=10) AliInfo("ESD info: this particle is identified as electron by HFEpid method \n"); - if(GetPlugin(kCorrection)) fDeCFM->GetParticleContainer()->Fill(esdContainer, 1+AliHFEcuts::kStepPID); - + if(GetPlugin(kCorrection)) fDeCFM->GetParticleContainer()->Fill(esdContainer, 1+kStepPID + AliHFEcuts::kNcutStepsMCTrack); + // Fill Containers nHFEelectrons++; fElectronsEsdPt->Fill(esdContainer[0]); @@ -556,6 +552,10 @@ void AliAnalysisTaskDisplacedElectrons::ProcessData(){ // this is a track loop over real data // no MC information at all // HFE pid is used + + const Int_t kNcutStepsESDtrack = AliHFEcuts::kNcutStepsRecTrack + 1; + //const Int_t kNcutStepsTrack = AliHFEcuts::kNcutStepsMCTrack + kNcutStepsESDtrack; + const Int_t kStepPID = AliHFEcuts::kStepHFEcutsTRD + 1; AliESDEvent *fESD = dynamic_cast(fInputEvent); if(!fESD){ @@ -593,32 +593,32 @@ void AliAnalysisTaskDisplacedElectrons::ProcessData(){ cont.Append(TMath::Abs(track->GetLabel())); if(alreadyseen) continue; // avoid double counting if(GetPlugin(kCorrection))fDeCFM->GetParticleContainer()->Fill(&dataContainer[4], - 1+AliHFEcuts::kStepRecNoCut + AliHFEcuts::kNcutStepsESDtrack); + 1+AliHFEcuts::kStepRecNoCut + AliHFEcuts::kNcutStepsMCTrack + kNcutStepsESDtrack); // 1st track cut // RecKine: ITSTPC cuts : ITS & TPC refit, covmatrix: (2, 2, 0.5, 0.5, 2); min_tpccls: 50, chi2_tpccls: 3.5 - if(!fDeCFM->CheckParticleCuts(AliHFEcuts::kStepRecKineITSTPC, track)) continue; + if(!fDeCFM->CheckParticleCuts(AliHFEcuts::kStepRecKineITSTPC + AliHFEcuts::kNcutStepsMCTrack, track)) continue; if(GetPlugin(kCorrection)) fDeCFM->GetParticleContainer()->Fill(&dataContainer[4], - 1+AliHFEcuts::kStepRecKineITSTPC + AliHFEcuts::kNcutStepsESDtrack); + 1+AliHFEcuts::kStepRecKineITSTPC + AliHFEcuts::kNcutStepsMCTrack + kNcutStepsESDtrack); // 2nd track cut // RecPrim: cut on track quality : DCA to vertex max: 3cm and 10cm; reject kink daughters - if(!fDeCFM->CheckParticleCuts(AliHFEcuts::kStepRecPrim, track)) continue; + if(!fDeCFM->CheckParticleCuts(AliHFEcuts::kStepRecPrim + AliHFEcuts::kNcutStepsMCTrack, track)) continue; if(GetPlugin(kCorrection)) fDeCFM->GetParticleContainer()->Fill(&dataContainer[4], - 1+AliHFEcuts::kStepRecPrim + AliHFEcuts::kNcutStepsESDtrack); + 1+AliHFEcuts::kStepRecPrim + AliHFEcuts::kNcutStepsMCTrack + kNcutStepsESDtrack); // 3rd track cut // HFEcuts: ITS layers cuts: ITS pixel layer: kFirst, kSecond, kBoth, kNone or kAny if(!fDeCFM->CheckParticleCuts(AliHFEcuts::kStepHFEcutsITS, track)) continue; if(GetPlugin(kCorrection)) fDeCFM->GetParticleContainer()->Fill(&dataContainer[4], - 1+AliHFEcuts::kStepHFEcutsITS + AliHFEcuts::kNcutStepsESDtrack); + 1+AliHFEcuts::kStepHFEcutsITS + AliHFEcuts::kNcutStepsMCTrack + kNcutStepsESDtrack); /* // 4th track cut // TRD: number of tracklets in TRD0 - if(!fDeCFM->CheckParticleCuts(AliHFEcuts::kStepHFEcutsTRD, track)) continue; + if(!fDeCFM->CheckParticleCuts(AliHFEcuts::kStepHFEcutsTRD + AliHFEcuts::kNcutStepsMCTrack, track)) continue; if(GetPlugin(kCorrection)) if(HasMCData())fDeCFM->GetParticleContainer()->Fill(&dataContainer[4], - 1+AliHFEcuts::kStepHFEcutsTRD + AliHFEcuts::kNcutStepsESDtrack); + 1+AliHFEcuts::kStepHFEcutsTRD + AliHFEcuts::kNcutStepsMCTrack + kNcutStepsESDtrack); */ @@ -626,14 +626,13 @@ void AliAnalysisTaskDisplacedElectrons::ProcessData(){ // track accepted, do PID --> only electron candidate will be processed AliHFEpidObject hfetrack; - hfetrack.fAnalysisType = AliHFEpidObject::kESDanalysis; - hfetrack.fRecTrack = track; - // if(HasMCData())hfetrack.fMCtrack = mctrack; + hfetrack.SetAnalysisType(AliHFEpidObject::kESDanalysis); + hfetrack.SetRecTrack(track); if(!fDePID->IsSelected(&hfetrack)) continue; else if(fDeDebugLevel>=10) AliInfo("ESD info: this particle is identified as electron by HFEpid method \n"); - if(GetPlugin(kCorrection)) fDeCFM->GetParticleContainer()->Fill(dataContainer, 1+AliHFEcuts::kStepPID + AliHFEcuts::kNcutStepsESDtrack); + if(GetPlugin(kCorrection)) fDeCFM->GetParticleContainer()->Fill(dataContainer, 1+kStepPID + AliHFEcuts::kNcutStepsMCTrack + kNcutStepsESDtrack); nHFEelectrons++; fElectronsDataPt->Fill(dataContainer[0]); @@ -717,6 +716,9 @@ void AliAnalysisTaskDisplacedElectrons::MakeParticleContainer(){ // Create the particle container for the correction framework manager and // link it // + const Int_t kNcutStepsESDtrack = AliHFEcuts::kNcutStepsRecTrack + 1; + const Int_t kNcutStepsTrack = AliHFEcuts::kNcutStepsMCTrack + kNcutStepsESDtrack; + const Int_t kNvar = 4; //number of variables on the grid:pt,eta, phi, charge const Double_t kPtbound[2] = {0.1, 10.}; @@ -761,7 +763,7 @@ void AliAnalysisTaskDisplacedElectrons::MakeParticleContainer(){ //------------------------------------------------ AliCFContainer* container = new AliCFContainer("deTrackContainer", "Container for tracks", - (1 + AliHFEcuts::kNcutStepsTrack + AliHFEcuts::kNcutStepsESDtrack), kNvar, iBin); + (1 + kNcutStepsTrack + kNcutStepsESDtrack), kNvar, iBin); //setting the bin limits for(Int_t ivar = 0; ivar < kNvar; ivar++){ diff --git a/PWG3/hfe/AliAnalysisTaskHFE.cxx b/PWG3/hfe/AliAnalysisTaskHFE.cxx index ab885fb3d10..508485043a6 100644 --- a/PWG3/hfe/AliAnalysisTaskHFE.cxx +++ b/PWG3/hfe/AliAnalysisTaskHFE.cxx @@ -29,10 +29,6 @@ #include #include #include -#include -#include -#include -#include #include #include #include @@ -54,6 +50,7 @@ #include "AliESDInputHandler.h" #include "AliESDpid.h" #include "AliESDtrack.h" +#include "AliESDCentrality.h" #include "AliLog.h" #include "AliAnalysisManager.h" #include "AliMCEvent.h" @@ -64,16 +61,21 @@ #include "AliTriggerAnalysis.h" #include "AliVVertex.h" -#include "AliHFEpid.h" #include "AliHFEcollection.h" +#include "AliHFEcontainer.h" #include "AliHFEcuts.h" +#include "AliHFEelecbackground.h" #include "AliHFEmcQA.h" #include "AliHFEpairs.h" +#include "AliHFEpid.h" +#include "AliHFEpidQAmanager.h" #include "AliHFEpostAnalysis.h" #include "AliHFEsecVtxs.h" #include "AliHFEsecVtx.h" -#include "AliHFEelecbackground.h" +#include "AliHFEsignalCuts.h" +#include "AliHFEtaggedTrackAnalysis.h" #include "AliHFEtools.h" +#include "AliHFEvarManager.h" #include "AliAnalysisTaskHFE.h" ClassImp(AliAnalysisTaskHFE) @@ -82,31 +84,29 @@ ClassImp(AliAnalysisTaskHFE) AliAnalysisTaskHFE::AliAnalysisTaskHFE(): AliAnalysisTaskSE("PID efficiency Analysis") , fQAlevel(0) - , fPIDdetectors("") - , fPIDstrategy(0) , fPlugins(0) - , fWeighting(kFALSE) - , fWeightFactors(NULL) - , fWeightFactorsFunction(NULL) + , fFillSignalOnly(kTRUE) + , fRemovePileUp(kFALSE) + , fIdentifiedAsPileUp(kFALSE) + , fIdentifiedAsOutInz(kFALSE) + , fPassTheEventCut(kFALSE) + , fCentralityF(99.0) , fBackGroundFactorsFunction(NULL) + , fContainer(NULL) + , fVarManager(NULL) + , fSignalCuts(NULL) , fCFM(NULL) - , fV0CF(NULL) , fTriggerAnalysis(NULL) - , fHadronicBackground(NULL) - , fCorrelation(NULL) - , fPIDperformance(NULL) - , fSignalToBackgroundMC(NULL) , fPID(NULL) - , fPIDtagged(NULL) + , fPIDqa(NULL) , fPIDpreselect(NULL) , fCuts(NULL) - , fCutsTagged(NULL) + , fTaggedTrackCuts(NULL) , fCutspreselect(NULL) , fSecVtx(NULL) , fElecBackGround(NULL) , fMCQA(NULL) - , fNEvents(NULL) - , fNElectronTracksEvent(NULL) + , fTaggedTrackAnalysis(NULL) , fQA(NULL) , fOutput(NULL) , fHistMCQA(NULL) @@ -123,31 +123,29 @@ AliAnalysisTaskHFE::AliAnalysisTaskHFE(): AliAnalysisTaskHFE::AliAnalysisTaskHFE(const char * name): AliAnalysisTaskSE(name) , fQAlevel(0) - , fPIDdetectors("") - , fPIDstrategy(0) , fPlugins(0) - , fWeighting(kFALSE) - , fWeightFactors(NULL) - , fWeightFactorsFunction(NULL) + , fFillSignalOnly(kTRUE) + , fRemovePileUp(kFALSE) + , fIdentifiedAsPileUp(kFALSE) + , fIdentifiedAsOutInz(kFALSE) + , fPassTheEventCut(kFALSE) + , fCentralityF(99.0) , fBackGroundFactorsFunction(NULL) + , fContainer(NULL) + , fVarManager(NULL) + , fSignalCuts(NULL) , fCFM(NULL) - , fV0CF(NULL) , fTriggerAnalysis(NULL) - , fHadronicBackground(NULL) - , fCorrelation(NULL) - , fPIDperformance(NULL) - , fSignalToBackgroundMC(NULL) , fPID(NULL) - , fPIDtagged(NULL) + , fPIDqa(NULL) , fPIDpreselect(NULL) , fCuts(NULL) - , fCutsTagged(NULL) + , fTaggedTrackCuts(NULL) , fCutspreselect(NULL) , fSecVtx(NULL) , fElecBackGround(NULL) , fMCQA(NULL) - , fNEvents(NULL) - , fNElectronTracksEvent(NULL) + , fTaggedTrackAnalysis(NULL) , fQA(NULL) , fOutput(NULL) , fHistMCQA(NULL) @@ -158,42 +156,40 @@ AliAnalysisTaskHFE::AliAnalysisTaskHFE(const char * name): // // Default constructor // - DefineOutput(1, TH1I::Class()); + DefineOutput(1, TList::Class()); DefineOutput(2, TList::Class()); - DefineOutput(3, TList::Class()); - // Initialize cuts + fPID = new AliHFEpid("hfePid"); + fVarManager = new AliHFEvarManager("hfeVarManager"); } //____________________________________________________________ AliAnalysisTaskHFE::AliAnalysisTaskHFE(const AliAnalysisTaskHFE &ref): AliAnalysisTaskSE(ref) , fQAlevel(0) - , fPIDdetectors() - , fPIDstrategy(0) , fPlugins(0) - , fWeighting(kFALSE) - , fWeightFactors(NULL) - , fWeightFactorsFunction(NULL) + , fFillSignalOnly(ref.fFillSignalOnly) + , fRemovePileUp(ref.fRemovePileUp) + , fIdentifiedAsPileUp(ref.fIdentifiedAsPileUp) + , fIdentifiedAsOutInz(ref.fIdentifiedAsOutInz) + , fPassTheEventCut(ref.fPassTheEventCut) + , fCentralityF(ref.fCentralityF) , fBackGroundFactorsFunction(NULL) + , fContainer(NULL) + , fVarManager(NULL) + , fSignalCuts(NULL) , fCFM(NULL) - , fV0CF(NULL) , fTriggerAnalysis(NULL) - , fHadronicBackground(NULL) - , fCorrelation(NULL) - , fPIDperformance(NULL) - , fSignalToBackgroundMC(NULL) , fPID(NULL) - , fPIDtagged(NULL) + , fPIDqa(NULL) , fPIDpreselect(NULL) , fCuts(NULL) - , fCutsTagged(NULL) + , fTaggedTrackCuts(NULL) , fCutspreselect(NULL) , fSecVtx(NULL) , fElecBackGround(NULL) , fMCQA(NULL) - , fNEvents(NULL) - , fNElectronTracksEvent(NULL) + , fTaggedTrackAnalysis(NULL) , fQA(NULL) , fOutput(NULL) , fHistMCQA(NULL) @@ -224,30 +220,29 @@ void AliAnalysisTaskHFE::Copy(TObject &o) const { // AliAnalysisTaskHFE &target = dynamic_cast(o); target.fQAlevel = fQAlevel; - target.fPIDdetectors = fPIDdetectors; - target.fPIDstrategy = fPIDstrategy; target.fPlugins = fPlugins; - target.fWeighting = fWeighting; - target.fWeightFactors = fWeightFactors; - target.fWeightFactorsFunction = fWeightFactorsFunction; + target.fFillSignalOnly = fFillSignalOnly; + target.fRemovePileUp = fRemovePileUp; + target.fIdentifiedAsPileUp = fIdentifiedAsPileUp; + target.fIdentifiedAsOutInz = fIdentifiedAsOutInz; + target.fPassTheEventCut = fPassTheEventCut; + target.fCentralityF = fCentralityF; target.fBackGroundFactorsFunction = fBackGroundFactorsFunction; + target.fContainer = fContainer; + target.fVarManager = fVarManager; + target.fSignalCuts = fSignalCuts; target.fCFM = fCFM; - target.fV0CF = fV0CF; target.fTriggerAnalysis = fTriggerAnalysis; - target.fHadronicBackground = fHadronicBackground; - target.fCorrelation = fCorrelation; - target.fPIDperformance = fPIDperformance; - target.fSignalToBackgroundMC = fSignalToBackgroundMC; target.fPID = fPID; - target.fPIDtagged = fPIDtagged; + target.fPIDqa = fPIDqa; target.fPIDpreselect = fPIDpreselect; target.fCuts = fCuts; + target.fTaggedTrackCuts = fTaggedTrackCuts; target.fCutspreselect = fCutspreselect; target.fSecVtx = fSecVtx; target.fElecBackGround = fElecBackGround; target.fMCQA = fMCQA; - target.fNEvents = fNEvents; - target.fNElectronTracksEvent = fNElectronTracksEvent; + target.fTaggedTrackAnalysis = fTaggedTrackAnalysis; target.fQA = fQA; target.fOutput = fOutput; target.fHistMCQA = fHistMCQA; @@ -261,44 +256,18 @@ AliAnalysisTaskHFE::~AliAnalysisTaskHFE(){ // // Destructor // - return; if(fPID) delete fPID; - if(fPIDtagged) delete fPIDtagged; - if(fQA){ - fQA->Clear(); - delete fQA; - } - if(fOutput){ - fOutput->Clear(); - delete fOutput; - } - if(fWeightFactors) delete fWeightFactors; - if(fWeightFactorsFunction) delete fWeightFactorsFunction; - if(fBackGroundFactorsFunction) delete fBackGroundFactorsFunction; - if(fHistMCQA){ - fHistMCQA->Clear(); - delete fHistMCQA; - } - if(fHistSECVTX){ - fHistSECVTX->Clear(); - delete fHistSECVTX; - } - if(fHistELECBACKGROUND){ - fHistELECBACKGROUND->Clear(); - delete fHistELECBACKGROUND; - } + if(fVarManager) delete fVarManager; + if(fPIDqa) delete fPIDqa; + if(fSignalCuts) delete fSignalCuts; + if(fCFM) delete fCFM; if(fSecVtx) delete fSecVtx; - if(fElecBackGround) delete fElecBackGround; if(fMCQA) delete fMCQA; - if(fNEvents) delete fNEvents; - if(fCorrelation){ - fCorrelation->Clear(); - delete fCorrelation; - } - if(fPIDperformance) delete fPIDperformance; - if(fSignalToBackgroundMC) delete fSignalToBackgroundMC; -// if(fQAcoll) delete fQAcoll; - + if(fElecBackGround) delete fElecBackGround; + if(fTriggerAnalysis) delete fTriggerAnalysis; + if(fPIDpreselect) delete fPIDpreselect; + if(fQA) delete fQA; + if(fOutput) delete fOutput; } //____________________________________________________________ @@ -313,7 +282,6 @@ void AliAnalysisTaskHFE::UserCreateOutputObjects(){ // QA histograms are created if requested // Called once per worker // - fPID = new AliHFEpid("standardPID"); fPIDtagged = new AliHFEpid("taggedPID"); AliDebug(3, "Creating Output Objects"); // Automatic determination of the analysis mode AliVEventHandler *inputHandler = dynamic_cast(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler()); @@ -327,23 +295,21 @@ void AliAnalysisTaskHFE::UserCreateOutputObjects(){ printf("Analysis Mode: %s Analysis\n", IsAODanalysis() ? "AOD" : "ESD"); printf("MC Data available %s\n", HasMCData() ? "Yes" : "No"); - // example how to use the AliHFEcollection - //fQAcoll = new AliHFEcollection("fQAcoll", "QA"); - //fQAcoll->CreateTH1F("fNevents", "Number of Events in the Analysis", 2, 0, 2); - //fQAcoll->CreateProfile("fNtrdclusters", "Number of TRD clusters as function of momentum; p[GeV/c]", 20, 0, 20); - // Enable Trigger Analysis fTriggerAnalysis = new AliTriggerAnalysis; fTriggerAnalysis->EnableHistograms(); fTriggerAnalysis->SetAnalyzeMC(HasMCData()); - // Make QA histograms - fNEvents = new TH1I("nEvents", "Number of Events in the Analysis", 2, 0, 2); // Number of Events neccessary for the analysis and not a QA histogram - fNElectronTracksEvent = new TH1I("nElectronTracksEvent", "Number of Electron Candidates", 100, 0, 100); - // First Step: TRD alone + + // Make lists for Output if(!fQA) fQA = new TList; + fQA->SetOwner(); + if(!fOutput) fOutput = new TList; + fOutput->SetOwner(); + // First Part: Make QA histograms fQACollection = new AliHFEcollection("TaskQA", "QA histos from the Electron Task"); + fQACollection->CreateTH1F("nElectronTracksEvent", "Number of Electron Candidates", 100, 0, 100); fQACollection->CreateProfile("conr", "Electron PID contamination", 20, 0, 20); fQACollection->CreateTH1F("alpha_rec", "Alpha from reconstructed tracks with TRD hits", 36, -TMath::Pi(), TMath::Pi()); fQACollection->CreateTH1F("alpha_sim", "Alpha from simulated electron tracks", 36, -TMath::Pi(), TMath::Pi()); @@ -353,18 +319,28 @@ void AliAnalysisTaskHFE::UserCreateOutputObjects(){ fQACollection->CreateTH1F("chi2TRD","#chi2 per TRD cluster", 20, 0, 20); fQACollection->CreateTH1F("mccharge", "MC Charge", 200, -100, 100); fQACollection->CreateTH2F("radius", "Production Vertex", 100, 0.0, 5.0, 100, 0.0, 5.0); - fQACollection->CreateTH1F("secvtxept", "pT of tagged e", 500, 0, 50); // mj: will move to another place soon - fQACollection->CreateTH2F("secvtxeTPCsig", "TPC signal for tagged e",125, 0, 25, 200, 0, 200 ); // mj: will move to another place soon + InitPIDperformanceQA(); fQA->Add(fQACollection->GetList()); - if(!fOutput) fOutput = new TList; + // Initialize PID + fPID->SetHasMCData(HasMCData()); + if(!fPID->GetNumberOfPIDdetectors()) fPID->AddDetector("TPC", 0); + fPID->InitializePID(); + if(IsQAOn(kPIDqa)){ + AliInfo("PID QA switched on"); + fPIDqa = new AliHFEpidQAmanager; + fPIDqa->Initialize(fPID); + fQA->Add(fPIDqa->MakeList("HFEpidQA")); + } + // Initialize correction Framework and Cuts + const Int_t kNcutSteps = AliHFEcuts::kNcutStepsMCTrack + AliHFEcuts::kNcutStepsRecTrack + AliHFEcuts::kNcutStepsDETrack; fCFM = new AliCFManager; - fV0CF = new AliCFManager; + fCFM->SetNStepParticle(kNcutSteps); MakeParticleContainer(); MakeEventContainer(); // Temporary fix: Initialize particle cuts with NULL - for(Int_t istep = 0; istep < fCFM->GetParticleContainer()->GetNStep(); istep++) + for(Int_t istep = 0; istep < kNcutSteps; istep++) fCFM->SetParticleCutsList(istep, NULL); if(!fCuts){ AliWarning("Cuts not available. Default cuts will be used"); @@ -373,46 +349,21 @@ void AliAnalysisTaskHFE::UserCreateOutputObjects(){ } if(IsAODanalysis()) fCuts->SetAOD(); // Make clone for V0 tagging step - fCutsTagged = new AliHFEcuts(*fCuts); - fCutsTagged->SetName("hfeV0Cuts"); - fCutsTagged->SetTitle("Cuts for tagged Particles"); fCuts->Initialize(fCFM); - fCutsTagged->Initialize(fV0CF); if(fCuts->IsQAOn()) fQA->Add(fCuts->GetQAhistograms()); - if(fCutsTagged->IsQAOn()) fQA->Add(fCutsTagged->GetQAhistograms()); + fSignalCuts = new AliHFEsignalCuts("HFEsignalCuts", "HFE MC Signal definition"); + fVarManager->SetSignalCuts(fSignalCuts); // add output objects to the List - fOutput->AddAt(fCFM->GetParticleContainer(), 0); + fOutput->AddAt(fContainer, 0); fOutput->AddAt(fCFM->GetEventContainer(), 1); - fOutput->AddAt(fCorrelation, 2); - fOutput->AddAt(fPIDperformance, 3); - fOutput->AddAt(fSignalToBackgroundMC, 4); - fOutput->AddAt(fNElectronTracksEvent, 5); - fOutput->AddAt(fHadronicBackground, 6); - fOutput->AddAt(fV0CF, 7); - // Initialize PID - if(IsQAOn(kPIDqa)){ - AliInfo("PID QA switched on"); - //fPID->SetDebugLevel(2); - fPID->SetQAOn(); - fQA->Add(fPID->GetQAhistograms()); - } - fPID->SetHasMCData(HasMCData()); - if(!fPIDdetectors.Length() && ! fPIDstrategy) AddPIDdetector("TPC"); - if(fPIDstrategy){ - fPID->InitializePID(Form("Strategy%d", fPIDstrategy)); - fPIDtagged->InitializePID(Form("Strategy%d", fPIDstrategy)); - } - else{ - fPID->InitializePID(fPIDdetectors.Data()); // Only restrictions to TPC allowed - fPIDtagged->InitializePID(fPIDdetectors.Data()); // Only restrictions to TPC allowed - } - + // mcQA---------------------------------- if (HasMCData() && IsQAOn(kMCqa)) { AliInfo("MC QA on"); if(!fMCQA) fMCQA = new AliHFEmcQA; if(!fHistMCQA) fHistMCQA = new TList(); + fHistMCQA->SetOwner(); fMCQA->CreatDefaultHistograms(fHistMCQA); fQA->Add(fHistMCQA); } @@ -424,6 +375,7 @@ void AliAnalysisTaskHFE::UserCreateOutputObjects(){ fSecVtx->SetHasMCData(HasMCData()); if(!fHistSECVTX) fHistSECVTX = new TList(); + fHistSECVTX->SetOwner(); fSecVtx->CreateHistograms(fHistSECVTX); fOutput->Add(fHistSECVTX); } @@ -438,9 +390,23 @@ void AliAnalysisTaskHFE::UserCreateOutputObjects(){ fElecBackGround->SetHasMCData(HasMCData()); if(!fHistELECBACKGROUND) fHistELECBACKGROUND = new TList(); + fHistELECBACKGROUND->SetOwner(); fElecBackGround->CreateHistograms(fHistELECBACKGROUND); fOutput->Add(fHistELECBACKGROUND); } + + // tagged tracks + if(GetPlugin(kTaggedTrackAnalysis)){ + AliInfo("Analysis on V0-tagged tracks enabled"); + fTaggedTrackAnalysis = new AliHFEtaggedTrackAnalysis; + fTaggedTrackAnalysis->SetCuts(fTaggedTrackCuts); + fTaggedTrackAnalysis->SetPID(fPID); + fTaggedTrackAnalysis->InitContainer(); + fOutput->Add(fTaggedTrackAnalysis->GetContainer()); + fQA->Add(fTaggedTrackAnalysis->GetPIDQA()); + fQA->Add(fTaggedTrackAnalysis->GetCutQA()); + } + PrintStatus(); } //____________________________________________________________ @@ -477,35 +443,48 @@ void AliAnalysisTaskHFE::UserExec(Option_t *){ if(!mcH->TreeTR()) return; } + // need the centrality for everything (MC also) + fCentralityF = 99.0; + ReadCentrality(); + + // See if pile up and z in the range + RejectionPileUpVertexRangeEventCut(); + // Protect agains missing - if(HasMCData()) ProcessMC(); // Run the MC loop + MC QA in case MC Data are available + if(HasMCData()){ + fSignalCuts->SetMCEvent(fMCEvent); + ProcessMC(); // Run the MC loop + MC QA in case MC Data are available + } - if(IsAODanalysis()) ProcessAOD(); - else{ + if(IsAODanalysis()){ + AliAODpidUtil *aodworkingpid = AliHFEtools::GetDefaultAODPID(HasMCData()); + fPID->SetAODpid(aodworkingpid); + if(fPIDqa) fPIDqa->SetAODpid(aodworkingpid); + if(fTaggedTrackAnalysis) fTaggedTrackAnalysis->GetPIDqa()->SetAODpid(aodworkingpid); + ProcessAOD(); + } else { AliESDInputHandler *inH = dynamic_cast(fInputHandler); if(!inH){ AliError("No ESD Input handler available"); return; } AliESDpid *workingPID = inH->GetESDpid(); - if(workingPID){ - AliDebug(1, "Using ESD PID from the input handler"); - fPID->SetESDpid(workingPID); - fPIDtagged->SetESDpid(workingPID); - if(fPIDpreselect) fPIDpreselect->SetESDpid(workingPID); - } else { + if(!workingPID){ AliDebug(1, "Using default ESD PID"); - fPID->SetESDpid(AliHFEtools::GetDefaultPID(HasMCData())); - fPIDtagged->SetESDpid(AliHFEtools::GetDefaultPID(HasMCData())); - if(fPIDpreselect) fPIDpreselect->SetESDpid(AliHFEtools::GetDefaultPID(HasMCData())); + workingPID = AliHFEtools::GetDefaultPID(HasMCData()); + } else { + AliDebug(1, "Using ESD PID from the input handler"); } + fPID->SetESDpid(workingPID); + if(fPIDqa) fPIDqa->SetESDpid(workingPID); + if(fTaggedTrackAnalysis) fTaggedTrackAnalysis->GetPIDqa()->SetESDpid(workingPID); + if(fPIDpreselect) fPIDpreselect->SetESDpid(workingPID); + ProcessESD(); } // Done!!! - PostData(1, fNEvents); - PostData(2, fOutput); - PostData(3, fQA); -// PostData(4, fQAcoll->GetList()); + PostData(1, fOutput); + PostData(2, fQA); } //____________________________________________________________ @@ -514,14 +493,32 @@ void AliAnalysisTaskHFE::Terminate(Option_t *){ // Terminate not implemented at the moment // if(GetPlugin(kPostProcess)){ - fOutput = dynamic_cast(GetOutputData(2)); + fOutput = dynamic_cast(GetOutputData(1)); + fQA = dynamic_cast(GetOutputData(2)); if(!fOutput){ AliError("Results not available"); return; } + if(!fQA){ + AliError("QA output not available"); + return; + } + fContainer = dynamic_cast(fOutput->FindObject("trackContainer")); + if(!fContainer){ + AliError("Track container not found"); + return; + } AliHFEpostAnalysis postanalysis; - postanalysis.SetResults(fOutput); - if(HasMCData())postanalysis.DrawMCSignal2Background(); + postanalysis.SetTaskResults(fContainer); + TList *qalist = dynamic_cast(fQA->FindObject("list_TaskQA")); + if(!qalist){ + AliError("QA List not found"); + return; + } + postanalysis.SetTaskQA(qalist); + printf("Running post analysis\n"); + //if(HasMCData()) + postanalysis.DrawMCSignal2Background(); postanalysis.DrawEfficiency(); postanalysis.DrawPIDperformance(); postanalysis.DrawCutEfficiency(); @@ -570,8 +567,9 @@ void AliAnalysisTaskHFE::ProcessMC(){ // In case MC QA is on also MC QA loop is done // AliDebug(3, "Processing MC Information"); - Double_t eventContainer [2]; + Double_t eventContainer [3]; eventContainer[0] = fMCEvent->GetPrimaryVertex()->GetZ(); + eventContainer[2] = fCentralityF; if(fCFM->CheckEventCuts(AliHFEcuts::kEventStepGenerated, fMCEvent)) fCFM->GetEventContainer()->Fill(eventContainer,AliHFEcuts::kEventStepGenerated); Int_t nElectrons = 0; @@ -623,7 +621,7 @@ void AliAnalysisTaskHFE::ProcessMC(){ AliDebug(3, Form("Number of Tracks: %d", fMCEvent->GetNumberOfTracks())); for(Int_t imc = 0; imc GetNumberOfTracks(); imc++){ if(!(mctrack = fMCEvent->GetTrack(imc))) continue; - AliDebug(4, "Next Track"); + AliDebug(4, "Next MC Track"); if(ProcessMCtrack(mctrack)) nElectrons++; } @@ -645,15 +643,32 @@ void AliAnalysisTaskHFE::ProcessESD(){ } // Do event Normalization - Double_t eventContainer[2]; + Double_t eventContainer[3]; eventContainer[0] = fInputEvent->GetPrimaryVertex()->GetZ(); eventContainer[1] = 0.; + eventContainer[2] = fCentralityF; if(fTriggerAnalysis->IsOfflineTriggerFired(fESD, AliTriggerAnalysis::kV0AND)) eventContainer[1] = 1.; + + // fCFM->GetEventContainer()->Fill(eventContainer, AliHFEcuts::kEventStepRecNoCut); - if(!fCFM->CheckEventCuts(AliHFEcuts::kEventStepReconstructed, fInputEvent)) return; + + // + if(fIdentifiedAsPileUp) return; + fCFM->GetEventContainer()->Fill(eventContainer, AliHFEcuts::kEventStepRecNoPileUp); + + // + if(fIdentifiedAsOutInz) return; + fCFM->GetEventContainer()->Fill(eventContainer, AliHFEcuts::kEventStepZRange); + + // + if(!fPassTheEventCut) return; fCFM->GetEventContainer()->Fill(eventContainer, AliHFEcuts::kEventStepReconstructed); + + + fContainer->NewEvent(); + if (GetPlugin(kIsElecBackGround)) { fElecBackGround->SetEvent(fESD); } @@ -665,13 +680,13 @@ void AliAnalysisTaskHFE::ProcessESD(){ if(HasMCData()){ if (GetPlugin(kSecVtx)) { fSecVtx->SetMCEvent(fMCEvent); + fSecVtx->SetMCQA(fMCQA); } if (GetPlugin(kIsElecBackGround)) { fElecBackGround->SetMCEvent(fMCEvent); } } - Double_t nContrib = fInputEvent->GetPrimaryVertex()->GetNContributors(); Double_t container[10]; memset(container, 0, sizeof(Double_t) * 10); // container for the output THnSparse @@ -681,9 +696,6 @@ void AliAnalysisTaskHFE::ProcessESD(){ AliMCParticle *mctrack = NULL; TParticle* mctrack4QA = NULL; Int_t pid = 0; - // For double counted tracks - LabelContainer cont(fESD->GetNumberOfTracks()); - Bool_t alreadyseen = kFALSE; Bool_t signal = kTRUE; @@ -701,6 +713,7 @@ void AliAnalysisTaskHFE::ProcessESD(){ // AliDebug(3, Form("Number of Tracks: %d", fESD->GetNumberOfTracks())); for(Int_t itrack = 0; itrack < fESD->GetNumberOfTracks(); itrack++){ + AliDebug(4, "New ESD track"); track = fESD->GetTrack(itrack); // fill counts of v0-identified particles @@ -708,8 +721,11 @@ void AliAnalysisTaskHFE::ProcessESD(){ if(track->TestBit(BIT(14))) v0pid = AliPID::kElectron; else if(track->TestBit(BIT(15))) v0pid = AliPID::kPion; else if(track->TestBit(BIT(16))) v0pid = AliPID::kProton; - if(v0pid > -1) - FilterTaggedTrack(track, v0pid); + // here the tagged track analysis will run + if(fTaggedTrackAnalysis && v0pid > -1){ + AliDebug(1, Form("Track identified as %s", AliPID::ParticleName(v0pid))); + fTaggedTrackAnalysis->ProcessTrack(track, v0pid); + } AliDebug(3, Form("Doing track %d, %p", itrack, track)); @@ -719,66 +735,29 @@ void AliAnalysisTaskHFE::ProcessESD(){ if(fPIDpreselect && fCutspreselect) { if(!PreSelectTrack(track)) continue; } - - container[0] = track->Pt(); - container[1] = track->Eta(); - container[2] = track->Phi(); - container[3] = track->Charge(); - container[4] = 0; - - dataE[0] = track->Pt(); - dataE[1] = track->Eta(); - dataE[2] = track->Phi(); - dataE[3] = track->Charge(); - dataE[4] = -1; - dataE[5] = -1; signal = kTRUE; - Double_t weight = 1.0; // Fill step without any cut if(HasMCData()){ - container[4] = container[9] = kOther; // Check if it is electrons near the vertex if(!(mctrack = dynamic_cast(fMCEvent->GetTrack(TMath::Abs(track->GetLabel()))))) continue; mctrack4QA = mctrack->Particle(); - container[5] = mctrack->Pt(); - container[6] = mctrack->Eta(); - container[7] = mctrack->Phi(); - container[8] = mctrack->Charge()/3.; - - if(fWeighting) weight = FindWeight(container[5],container[6],container[7]); - - if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepMCGenerated, mctrack)) signal = kFALSE; + if(fFillSignalOnly && !fCFM->CheckParticleCuts(AliHFEcuts::kStepMCGenerated, mctrack)) signal = kFALSE; else AliDebug(3, "Signal Electron"); - - Int_t signalTrack = 0; - if((signalTrack = IsSignalElectron(track))){ - AliDebug(3, Form("Signal: Index = %d\n", signalTrack)); - switch(signalTrack){ - case 1: container[4] = container[9] = kSignalCharm; break; - case 2: container[4] = container[9] = kSignalBeauty; break; - default: container[4] = container[9] = kOther; break; - }; - } else if(IsGammaElectron(track)) container[4] = container[9] = kGammaConv; - AliDebug(3, Form("Signal Decision(%f/%f)", container[4], container[9])); } - AliDebug(3, Form("Weight? %f", weight)); + // Cache new Track information inside the var manager + fVarManager->NewTrack(track, mctrack, fCentralityF, -1, signal); + if(signal) { - alreadyseen = cont.Find(TMath::Abs(track->GetLabel())); - cont.Append(TMath::Abs(track->GetLabel())); - - fCFM->GetParticleContainer()->Fill(&container[5], AliHFEcuts::kStepRecNoCut,weight); - fCFM->GetParticleContainer()->Fill(&container[0], AliHFEcuts::kStepRecNoCut + 2*AliHFEcuts::kNcutStepsESDtrack,weight); - if(alreadyseen) { - fCFM->GetParticleContainer()->Fill(&container[5], AliHFEcuts::kStepRecNoCut + AliHFEcuts::kNcutStepsESDtrack,weight); - } + fVarManager->FillContainer(fContainer, "recTrackContReco", AliHFEcuts::kStepRecNoCut, kFALSE); + fVarManager->FillContainer(fContainer, "recTrackContMC", AliHFEcuts::kStepRecNoCut, kTRUE); } // RecKine: ITSTPC cuts - if(!ProcessCutStep(AliHFEcuts::kStepRecKineITSTPC, track, container, signal, alreadyseen, weight)) continue; + if(!ProcessCutStep(AliHFEcuts::kStepRecKineITSTPC, track)) continue; // Check TRD criterions (outside the correction framework) if(track->GetTRDncls()){ @@ -790,17 +769,10 @@ void AliAnalysisTaskHFE::ProcessESD(){ // RecPrim - if(!ProcessCutStep(AliHFEcuts::kStepRecPrim, track, container, signal, alreadyseen,weight)) continue; + if(!ProcessCutStep(AliHFEcuts::kStepRecPrim, track)) continue; // HFEcuts: ITS layers cuts - if(!ProcessCutStep(AliHFEcuts::kStepHFEcutsITS, track, container, signal, alreadyseen,weight)) continue; - - // HFEcuts: Nb of tracklets TRD0 - if(!ProcessCutStep(AliHFEcuts::kStepHFEcutsTRD, track, container, signal, alreadyseen,weight)) continue; - if(signal) { - // dimensions 3&4&5 : pt,eta,phi (MC) - ((THnSparseF *)fCorrelation->At(0))->Fill(container); - } + if(!ProcessCutStep(AliHFEcuts::kStepHFEcutsITS, track)) continue; if(HasMCData() && IsQAOn(kMCqa)) { // mc qa for after the reconstruction cuts @@ -808,7 +780,18 @@ void AliAnalysisTaskHFE::ProcessESD(){ fMCQA->GetDecayedKine(mctrack4QA, AliHFEmcQA::kCharm, AliHFEmcQA::kElectronPDG, 3); // charm fMCQA->GetDecayedKine(mctrack4QA, AliHFEmcQA::kBeauty, AliHFEmcQA::kElectronPDG, 3); // beauty fMCQA->GetDecayedKine(mctrack4QA, AliHFEmcQA::kOthers, AliHFEmcQA::kElectronPDG, 3); // beauty - } + } + + // HFEcuts: Nb of tracklets TRD0 + if(!ProcessCutStep(AliHFEcuts::kStepHFEcutsTRD, track)) continue; + + if (HasMCData() && IsQAOn(kMCqa)) { + // mc qa for after the reconstruction and pid cuts + AliDebug(2, "Running MC QA"); + fMCQA->GetDecayedKine(mctrack4QA, AliHFEmcQA::kCharm, AliHFEmcQA::kElectronPDG, 4); // charm + fMCQA->GetDecayedKine(mctrack4QA, AliHFEmcQA::kBeauty, AliHFEmcQA::kElectronPDG, 4); // beauty + fMCQA->GetDecayedKine(mctrack4QA, AliHFEmcQA::kOthers, AliHFEmcQA::kElectronPDG, 4); // beauty + } if(HasMCData()){ FillProductionVertex(track); @@ -816,98 +799,54 @@ void AliAnalysisTaskHFE::ProcessESD(){ // track accepted, do PID AliHFEpidObject hfetrack; - hfetrack.fAnalysisType = AliHFEpidObject::kESDanalysis; - hfetrack.fRecTrack = track; - if(HasMCData()) hfetrack.fMCtrack = mctrack; - if(!fPID->IsSelected(&hfetrack)) continue; + hfetrack.SetAnalysisType(AliHFEpidObject::kESDanalysis); + hfetrack.SetRecTrack(track); + if(HasMCData()) hfetrack.SetMCTrack(mctrack); + hfetrack.SetCentrality(fCentralityF); + fPID->SetVarManager(fVarManager); + if(!fPID->IsSelected(&hfetrack, fContainer, "recTrackCont", fPIDqa)) continue; nElectronCandidates++; // Fill Histogram for Hadronic Background if(HasMCData()){ if(mctrack && (TMath::Abs(mctrack->Particle()->GetPdgCode()) != 11)) - fHadronicBackground->Fill(container, 0); + fVarManager->FillContainer(fContainer, "hadronicBackground", UInt_t(0), kFALSE); } - if (HasMCData() && IsQAOn(kMCqa)) { - // mc qa for after the reconstruction and pid cuts - AliDebug(2, "Running MC QA"); - fMCQA->GetDecayedKine(mctrack4QA, AliHFEmcQA::kCharm, AliHFEmcQA::kElectronPDG, 4); // charm - fMCQA->GetDecayedKine(mctrack4QA, AliHFEmcQA::kBeauty, AliHFEmcQA::kElectronPDG, 4); // beauty - fMCQA->GetDecayedKine(mctrack4QA, AliHFEmcQA::kOthers, AliHFEmcQA::kElectronPDG, 4); // beauty - } - // Fill Containers if(signal) { // Apply weight for background contamination if(fBackGroundFactorsFunction) { - Double_t weightBackGround = fBackGroundFactorsFunction->Eval(TMath::Abs(track->P())); - if(weightBackGround < 0.0) weightBackGround = 0.0; - else if(weightBackGround > 1.0) weightBackGround = 0.0; - fHadronicBackground->Fill(container, 1, weight * weightBackGround); - } - // - fCFM->GetParticleContainer()->Fill(container, AliHFEcuts::kStepPID + 2*AliHFEcuts::kNcutStepsESDtrack, weight); - fCFM->GetParticleContainer()->Fill(&container[5], AliHFEcuts::kStepPID, weight); - if(alreadyseen) { - fCFM->GetParticleContainer()->Fill(&container[5], (AliHFEcuts::kStepPID + (AliHFEcuts::kNcutStepsESDtrack)),weight); + Double_t weightBackGround = fBackGroundFactorsFunction->Eval(TMath::Abs(track->P())); + if(weightBackGround < 0.0) weightBackGround = 0.0; + else if(weightBackGround > 1.0) weightBackGround = 1.0; + // weightBackGround as special weight + fVarManager->FillContainer(fContainer, "hadronicBackground", 1, kFALSE, weightBackGround); } - // dimensions 3&4&5 : pt,eta,phi (MC) - ((THnSparseF *)fCorrelation->At(1))->Fill(container); + fVarManager->FillCorrelationMatrix(fContainer->GetCorrelationMatrix("correlationstepafterPID")); } if(GetPlugin(kSecVtx)) { AliDebug(2, "Running Secondary Vertex Analysis"); - if(track->Pt()>2.0 && nContrib > 1){ - fSecVtx->InitHFEpairs(); - fSecVtx->InitHFEsecvtxs(); - for(Int_t jtrack = 0; jtrack < fESD->GetNumberOfTracks(); jtrack++){ - htrack = fESD->GetTrack(jtrack); - if ( itrack == jtrack ) continue; // since it is for tagging single electron, don't need additional condition - if (htrack->Pt()<2.0) continue; - if (!fCFM->CheckParticleCuts(AliHFEcuts::kStepRecKineITSTPC, htrack)) continue; - if (!fCFM->CheckParticleCuts(AliHFEcuts::kStepRecPrim, htrack)) continue; - fSecVtx->PairAnalysis(track, htrack, jtrack); // e-h pairing - } - for(int ip=0; ipHFEpairs()->GetEntriesFast(); ip++){ - //if(HasMCData()){ - AliHFEpairs *pair = (AliHFEpairs*) (fSecVtx->HFEpairs()->UncheckedAt(ip)); - //if(!(pair->GetPairCode()>1. && pair->GetPairCode()<4.)) // apply various cuts - // apply various cuts - if(pair->GetKFChi2()>5.) // only apply vertex chi2 cut for the moment - //if((pair->GetKFChi2()>5.) || !(pair->GetSignedLxy()>0. && pair->GetSignedLxy()<2.)) - fSecVtx->HFEpairs()->RemoveAt(ip); - //} - } - fSecVtx->HFEpairs()->Compress(); - if(fSecVtx->HFEpairs()->GetEntriesFast()) fSecVtx->RunSECVTX(track); // secondary vertexing with e,h1,h2,.. tracks - for(int ip=0; ipHFEsecvtxs()->GetEntriesFast(); ip++){ - AliHFEsecVtxs *secvtx=0x0; - secvtx = (AliHFEsecVtxs*) (fSecVtx->HFEsecvtxs()->UncheckedAt(ip)); - if(!(secvtx->GetInvmass()>2.0 && secvtx->GetInvmass()<5.2) || !(secvtx->GetSignedLxy2()>0.08 && secvtx->GetSignedLxy2()<1.5) || !(secvtx->GetKFIP2()>-0.1 && secvtx->GetKFIP2()<0.1)) - fSecVtx->HFEsecvtxs()->RemoveAt(ip); - // here you apply cuts, then if it doesn't pass the cut, remove it from the fSecVtx->HFEsecvtxs() - } - if(fSecVtx->HFEsecvtxs()->GetEntriesFast()) { - fQACollection->Fill("secvtxpt", track->Pt()); - fQACollection->Fill("secvtxTPCsig", track->P(),track->GetTPCsignal()); - if (HasMCData() && IsQAOn(kMCqa)) { - // mc qa for after the reconstruction and pid cuts - AliDebug(2, "Running MC QA"); - fMCQA->GetDecayedKine(mctrack4QA, AliHFEmcQA::kCharm, AliHFEmcQA::kElectronPDG, 5); // charm - fMCQA->GetDecayedKine(mctrack4QA, AliHFEmcQA::kBeauty, AliHFEmcQA::kElectronPDG, 5); // beauty - fMCQA->GetDecayedKine(mctrack4QA, AliHFEmcQA::kOthers, AliHFEmcQA::kElectronPDG, 5); // beauty - } - } - fSecVtx->DeleteHFEpairs(); - fSecVtx->DeleteHFEsecvtxs(); - } + fSecVtx->Process(track); } if(HasMCData()){ + dataE[0] = track->Pt(); + dataE[1] = track->Eta(); + dataE[2] = track->Phi(); + dataE[3] = track->Charge(); + dataE[4] = -1.; + dataE[5] = -1.; + // Track selected: distinguish between true and fake AliDebug(1, Form("Candidate Selected, filling THnSparse, PID: %d\n", mctrack->Particle()->GetPdgCode())); if((pid = TMath::Abs(mctrack->Particle()->GetPdgCode())) == 11){ - Int_t type = IsSignalElectron(track); + Int_t type = 0; + if(fSignalCuts->IsCharmElectron(track)) + type = 1; + else if(fSignalCuts->IsBeautyElectron(track)) + type = 2; AliDebug(1, Form("Type: %d\n", type)); if(type){ dataE[5] = type; // beauty[1] or charm[2] @@ -926,7 +865,7 @@ void AliAnalysisTaskHFE::ProcessESD(){ // fill the performance THnSparse, if the mc origin could be defined if(dataE[4] > -1){ AliDebug(1, Form("Entries: [%.3f|%.3f|%.3f|%f|%f|%f]\n", dataE[0],dataE[1],dataE[2],dataE[3],dataE[4],dataE[5])); - fPIDperformance->Fill(dataE); + fQACollection->Fill("PIDperformance", dataE); } } // Electron background analysis @@ -941,10 +880,22 @@ void AliAnalysisTaskHFE::ProcessESD(){ } } // end of electron background analysis + if (GetPlugin(kDEstep)) { + // Fill Containers for impact parameter analysis + if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepHFEcutsDca + AliHFEcuts::kNcutStepsMCTrack + AliHFEcuts::kNcutStepsRecTrack,track)) continue; + if(signal) { + fVarManager->FillContainer(fContainer, "recTrackContDEReco", AliHFEcuts::kStepHFEcutsDca, kFALSE); + fVarManager->FillContainer(fContainer, "recTrackContDEMC", AliHFEcuts::kStepHFEcutsDca, kTRUE); + fVarManager->FillCorrelationMatrix(fContainer->GetCorrelationMatrix("correlationstepafterDE")); + } + if(HasMCData()){ + if(mctrack && (TMath::Abs(mctrack->Particle()->GetPdgCode()) != 11)) + fVarManager->FillContainer(fContainer, "hadronicBackground", 2, kFALSE); + } + } + } - fNEvents->Fill(1); - //fQAcoll->Fill("fNevents", 1); - fNElectronTracksEvent->Fill(nElectronCandidates); + fQACollection->Fill("nElectronTracksEvent", nElectronCandidates); } //____________________________________________________________ @@ -957,78 +908,82 @@ void AliAnalysisTaskHFE::ProcessAOD(){ Double_t eventContainer[2]; eventContainer[0] = fInputEvent->GetPrimaryVertex()->GetZ(); eventContainer[1] = 1.; // No Information available in AOD analysis, assume all events have V0AND - fCFM->GetEventContainer()->Fill(eventContainer,AliHFEcuts::kEventStepRecNoCut); - if(!fCFM->CheckEventCuts(AliHFEcuts::kEventStepReconstructed, fInputEvent)) return; - fCFM->GetEventContainer()->Fill(eventContainer,AliHFEcuts::kEventStepReconstructed); + AliAODEvent *fAOD = dynamic_cast(fInputEvent); if(!fAOD){ AliError("AOD Event required for AOD Analysis") - return; + return; } + + // + fCFM->GetEventContainer()->Fill(eventContainer, AliHFEcuts::kEventStepRecNoCut); + + // + if(fIdentifiedAsPileUp) return; + fCFM->GetEventContainer()->Fill(eventContainer, AliHFEcuts::kEventStepRecNoPileUp); + + // + if(fIdentifiedAsOutInz) return; + fCFM->GetEventContainer()->Fill(eventContainer, AliHFEcuts::kEventStepZRange); + + // + if(!fPassTheEventCut) return; + fCFM->GetEventContainer()->Fill(eventContainer, AliHFEcuts::kEventStepReconstructed); + + fContainer->NewEvent(); AliAODTrack *track = NULL; AliAODMCParticle *mctrack = NULL; - Double_t container[10]; memset(container, 0, sizeof(Double_t) * 10); Double_t dataE[6]; // [pT, eta, Phi, Charge, type, 'C' or 'B'] Int_t nElectronCandidates = 0; Int_t pid; + Bool_t signal; for(Int_t itrack = 0; itrack < fAOD->GetNumberOfTracks(); itrack++){ track = fAOD->GetTrack(itrack); if(!track) continue; if(track->GetFlags() != 1<<4) continue; // Only process AOD tracks where the HFE is set - container[0] = track->Pt(); - container[1] = track->Eta(); - container[2] = track->Phi(); - container[3] = track->Charge(); - - dataE[0] = track->Pt(); - dataE[1] = track->Eta(); - dataE[2] = track->Phi(); - dataE[3] = track->Charge(); - dataE[4] = -1; - dataE[5] = -1; - + signal = kTRUE; if(HasMCData()){ - Int_t signalTrack = 0; - if((signalTrack = IsSignalElectron(track))){ - switch(signalTrack){ - case 1: container[4] = container[9] = kSignalCharm; break; - case 2: container[4] = container[9] = kSignalBeauty; break; - }; - } else if(IsGammaElectron(track)) - container[4] = container[9] = kGammaConv; - else container[4] = container[9] = kOther; Int_t label = TMath::Abs(track->GetLabel()); - if(label){ + if(label) mctrack = dynamic_cast(fMCEvent->GetTrack(label)); - container[5] = mctrack->Pt(); - container[6] = mctrack->Eta(); - container[7] = mctrack->Phi(); - container[8] = mctrack->Charge(); - } + if(fFillSignalOnly && !fCFM->CheckParticleCuts(AliHFEcuts::kStepMCGenerated, mctrack)) signal = kFALSE; } + fVarManager->NewTrack(track, mctrack, fCentralityF, -1, kTRUE); // track accepted, do PID AliHFEpidObject hfetrack; - hfetrack.fAnalysisType = AliHFEpidObject::kAODanalysis; - hfetrack.fRecTrack = track; - if(HasMCData()) hfetrack.fMCtrack = mctrack; - //if(!fPID->IsSelected(&hfetrack)) continue; // we will do PID here as soon as possible - // Particle identified - Fill CF Container + hfetrack.SetAnalysisType(AliHFEpidObject::kAODanalysis); + hfetrack.SetRecTrack(track); + if(HasMCData()) hfetrack.SetMCTrack(mctrack); + hfetrack.SetCentrality(fCentralityF); + fPID->SetVarManager(fVarManager); + if(!fPID->IsSelected(&hfetrack, fContainer, "recTrackCont", fPIDqa)) continue; // we will do PID here as soon as possible // Apply weight for background contamination Double_t weightBackGround = 1.0; if(fBackGroundFactorsFunction) { - weightBackGround = weightBackGround - fBackGroundFactorsFunction->Eval(TMath::Abs(track->P())); - if(weightBackGround < 0.0) weightBackGround = 1.0; + weightBackGround = fBackGroundFactorsFunction->Eval(TMath::Abs(track->P())); + if(weightBackGround < 0.0) weightBackGround = 0.0; } - fCFM->GetParticleContainer()->Fill(container, AliHFEcuts::kStepPID + 2*AliHFEcuts::kNcutStepsESDtrack, weightBackGround); + fVarManager->FillContainer(fContainer, "hadronicBackground", 1, kFALSE); nElectronCandidates++; if(HasMCData()){ - // Track selected: distinguish between true and fake + dataE[0] = track->Pt(); + dataE[1] = track->Eta(); + dataE[2] = track->Phi(); + dataE[3] = track->Charge(); + dataE[4] = -1; + dataE[5] = -1; + // Track selected: distinguish between true and fake AliDebug(1, Form("Candidate Selected, filling THnSparse, PID: %d\n", mctrack->GetPdgCode())); if((pid = TMath::Abs(mctrack->GetPdgCode())) == 11){ - Int_t type = IsSignalElectron(track); + + Int_t type = 0; + if(fSignalCuts->IsCharmElectron(track)) + type = 1; + else if(fSignalCuts->IsBeautyElectron(track)) + type = 2; AliDebug(1, Form("Type: %d\n", type)); if(type){ dataE[5] = type; // beauty[1] or charm[2] @@ -1047,12 +1002,11 @@ void AliAnalysisTaskHFE::ProcessAOD(){ // fill the performance THnSparse, if the mc origin could be defined if(dataE[4] > -1){ AliDebug(1, Form("Entries: [%.3f|%.3f|%.3f|%f|%f|%f]\n", dataE[0],dataE[1],dataE[2],dataE[3],dataE[4],dataE[5])); - fPIDperformance->Fill(dataE); + fQACollection->Fill("PIDperformance", dataE); } } } - fNEvents->Fill(1); - fNElectronTracksEvent->Fill(nElectronCandidates); + fQACollection->Fill("nElectronTracksEvent", nElectronCandidates); } //____________________________________________________________ @@ -1062,53 +1016,40 @@ Bool_t AliAnalysisTaskHFE::ProcessMCtrack(AliVParticle *track){ // Additionally Fill a THnSparse for Signal To Background Studies // Works for AOD and MC analysis Type // - Double_t container[5], signalContainer[6]; - Double_t vertex[3]; // Production vertex cut to mask gammas which are NOT supposed to have hits in the first ITS layer(s) - if(IsESDanalysis()){ - AliMCParticle *mctrack = dynamic_cast(track); - container[0] = mctrack->Pt(); - container[1] = mctrack->Eta(); - container[2] = mctrack->Phi(); - container[3] = mctrack->Charge()/3; + fVarManager->NewTrack(track, NULL, -1, kTRUE); + Double_t signalContainer[6]; - signalContainer[0] = mctrack->Pt(); - signalContainer[1] = mctrack->Eta(); - signalContainer[2] = mctrack->Phi(); - signalContainer[3] = mctrack->Charge()/3; + signalContainer[0] = track->Pt(); + signalContainer[1] = track->Eta(); + signalContainer[2] = track->Phi(); + signalContainer[3] = track->Charge()/3; + Double_t vertex[3]; // Production vertex cut to mask gammas which are NOT supposed to have hits in the first ITS layer(s) + if(IsESDanalysis()){ + AliMCParticle *mctrack = dynamic_cast(track); vertex[0] = mctrack->Particle()->Vx(); vertex[1] = mctrack->Particle()->Vy(); } else { AliAODMCParticle *aodmctrack = dynamic_cast(track); - container[0] = aodmctrack->Pt(); - container[1] = aodmctrack->Eta(); - container[2] = aodmctrack->Phi(); - container[3] = aodmctrack->Charge()/3; - - signalContainer[0] = aodmctrack->Pt(); - signalContainer[1] = aodmctrack->Eta(); - signalContainer[2] = aodmctrack->Phi(); - signalContainer[3] = aodmctrack->Charge()/3; - aodmctrack->XvYvZv(vertex); } - Int_t signal = 0; - if((signal = IsSignalElectron(track))){ - switch(signal){ - case 1: container[4] = kSignalCharm; break; - case 2: container[4] = kSignalBeauty; break; - }; - }else if(IsGammaElectron(track)) container[4] = kGammaConv; - else container[4] = kOther; - - // weight - Double_t weight = 1.0; - if(fWeighting) weight = FindWeight(container[0],container[1],container[2]); - - if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepMCGenerated, track)) return kFALSE; - fQACollection->Fill("mccharge", signalContainer[3]); - fCFM->GetParticleContainer()->Fill(container, AliHFEcuts::kStepMCGenerated,weight); - if((signalContainer[4] = static_cast(IsSignalElectron(track))) > 1e-3) fCFM->GetParticleContainer()->Fill(container, AliHFEcuts::kStepMCsignal,weight); + + if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepMCGenerated, track)) return kFALSE; + fQACollection->Fill("mccharge", signalContainer[3]); + fVarManager->FillContainer(fContainer, "MCTrackCont", AliHFEcuts::kStepMCGenerated, kFALSE); + signalContainer[4] = 0; + if(fSignalCuts->IsSelected(track)){ + //fVarManager->FillContainer(fContainer, "MCTrackCont", AliHFEcuts::kStepMCsignal, kFALSE); + // Filling of the Signal/Background histogram using the + // definition of the codes for charm and beauty as below in + // th crearion of the histogram + if(fSignalCuts->IsCharmElectron(track)) + signalContainer[4] = 1; + else + signalContainer[4] = 2; + } else { + signalContainer[4] = 0; // (and other background) + } signalContainer[5] = 0; // apply cut on the sqrt of the production vertex Double_t radVertex = TMath::Sqrt(vertex[0]*vertex[0] + vertex[1] * vertex[1]); @@ -1118,41 +1059,22 @@ Bool_t AliAnalysisTaskHFE::ProcessMCtrack(AliVParticle *track){ } else if (radVertex < 7.5){ signalContainer[5] = 2; } - fSignalToBackgroundMC->Fill(signalContainer); - fQACollection->Fill("alpha_sim", container[2] - TMath::Pi()); - //if(IsESDanalysis()){ - if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepMCInAcceptance, track)) return kFALSE; - fCFM->GetParticleContainer()->Fill(container, AliHFEcuts::kStepMCInAcceptance,weight); - //} + fQACollection->Fill("SignalToBackgroundMC", signalContainer); + fQACollection->Fill("alpha_sim", track->Phi() - TMath::Pi()); + + // Step GeneratedZOutNoPileUp + if((fIdentifiedAsPileUp) || (fIdentifiedAsOutInz)) return kFALSE; + fVarManager->FillContainer(fContainer, "MCTrackCont", AliHFEcuts::kStepMCGeneratedZOutNoPileUp, kFALSE); + + // Step Generated Event Cut + if(!fPassTheEventCut) return kFALSE; + fVarManager->FillContainer(fContainer, "MCTrackCont", AliHFEcuts::kStepMCGeneratedEventCut, kFALSE); + + if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepMCInAcceptance, track)) return kFALSE; + fVarManager->FillContainer(fContainer, "MCTrackCont", AliHFEcuts::kStepMCInAcceptance, kFALSE); return kTRUE; } -//____________________________________________________________ -void AliAnalysisTaskHFE::FilterTaggedTrack(AliESDtrack *track, Int_t species){ - // - // Filter tracks tagged by V0 PID class - // - Int_t offset = AliHFEcuts::kStepRecKineITSTPC; - Double_t container[5] ={track->Pt(), track->Eta(), track->Phi(), track->Charge(), species}; - fV0CF->GetParticleContainer()->Fill(container, 0); // Fill Container without filtering - Bool_t survived = kTRUE; - for(Int_t icut = AliHFEcuts::kStepRecKineITSTPC; icut < AliHFEcuts::kStepPID; icut++){ - AliDebug(2, Form("Checking cut %d for species %s", icut, AliPID::ParticleName(species))); - if(!fV0CF->CheckParticleCuts(icut, track)){ - survived = kFALSE; - break; - } - AliDebug(2, Form("Cut passed, filling container %d", icut - offset + 1)); - fV0CF->GetParticleContainer()->Fill(container, icut - offset + 1); - } - if(survived){ - // Apply PID - AliHFEpidObject hfetrack; - hfetrack.fAnalysisType = AliHFEpidObject::kESDanalysis; - hfetrack.fRecTrack = track; - if(fPIDtagged->IsSelected(&hfetrack)) fV0CF->GetParticleContainer()->Fill(container, AliHFEcuts::kStepPID - offset + 1); - } -} //____________________________________________________________ Bool_t AliAnalysisTaskHFE::PreSelectTrack(AliESDtrack *track) const { // @@ -1186,8 +1108,8 @@ Bool_t AliAnalysisTaskHFE::PreSelectTrack(AliESDtrack *track) const { if(survived){ // Apply PID AliHFEpidObject hfetrack; - hfetrack.fAnalysisType = AliHFEpidObject::kESDanalysis; - hfetrack.fRecTrack = track; + hfetrack.SetAnalysisType(AliHFEpidObject::kESDanalysis); + hfetrack.SetRecTrack(track); if(!fPIDpreselect->IsSelected(&hfetrack)) { //printf("Did not pass AliHFEcuts::kPID\n"); survived = kFALSE; @@ -1202,11 +1124,14 @@ Bool_t AliAnalysisTaskHFE::PreSelectTrack(AliESDtrack *track) const { void AliAnalysisTaskHFE::MakeEventContainer(){ // // Create the event container for the correction framework and link it + // 1st bin: Vertex z-position + // 2nd bin: V0AND decision (normalization to sigma_inel) + // 3rd bin: Centrality class (for pp defined as 99.) // - const Int_t kNvar = 2; // number of variables on the grid: - Int_t nBins[kNvar] = {120, 2}; - Double_t binMin[kNvar] = {-30. , 0.}; - Double_t binMax[kNvar] = {30., 2.}; + const Int_t kNvar = 3; // number of variables on the grid: + Int_t nBins[kNvar] = {120, 2, 20}; + Double_t binMin[kNvar] = {-30. , 0., 0.}; + Double_t binMax[kNvar] = {30., 2., 100}; AliCFContainer *evCont = new AliCFContainer("eventContainer", "Container for events", AliHFEcuts::kNcutStepsEvent, kNvar, nBins); @@ -1225,111 +1150,57 @@ void AliAnalysisTaskHFE::MakeParticleContainer(){ // Create the particle container for the correction framework manager and // link it // - const Int_t kNvar = 5; - //number of variables on the grid:pt,eta, phi, charge - const Double_t kPtbound[2] = {0.1, 20.}; - const Double_t kEtabound[2] = {-0.8, 0.8}; - const Double_t kPhibound[2] = {0., 2. * TMath::Pi()}; - - //arrays for the number of bins in each dimension - Int_t iBin[kNvar]; - iBin[0] = 44; // bins in pt - iBin[1] = 8; // bins in eta - iBin[2] = 18; // bins in phi - iBin[3] = 2; // bins in charge - iBin[4] = 4; // creation process of the electron - - //arrays for lower bounds : - Double_t* binEdges[kNvar]; - binEdges[0] = AliHFEtools::MakeLogarithmicBinning(iBin[0], kPtbound[0], kPtbound[1]); - binEdges[1] = AliHFEtools::MakeLinearBinning(iBin[1], kEtabound[0], kEtabound[1]); - binEdges[2] = AliHFEtools::MakeLinearBinning(iBin[2], kPhibound[0], kPhibound[1]); - binEdges[3] = AliHFEtools::MakeLinearBinning(iBin[3], -1.1, 1.1); // Numeric precision - binEdges[4] = AliHFEtools::MakeLinearBinning(iBin[4], 0, iBin[4]); // Numeric precision - //for(Int_t ib = 0; ib <= iBin[4]; ib++) printf("%f\t", binEdges[4][ib]); - //printf("\n"); - - //one "container" for MC - AliCFContainer* container = new AliCFContainer("trackContainer", "Container for tracks", (AliHFEcuts::kNcutStepsTrack + 2*AliHFEcuts::kNcutStepsESDtrack), kNvar, iBin); - fHadronicBackground = new AliCFContainer("hadronicBackground", "Container for hadronic Background", 2, kNvar, iBin); - - //setting the bin limits - for(Int_t ivar = 0; ivar < kNvar; ivar++){ - container -> SetBinLimits(ivar, binEdges[ivar]); - fHadronicBackground -> SetBinLimits(ivar, binEdges[ivar]); + + if(!fContainer) fContainer = new AliHFEcontainer("trackContainer"); + fVarManager->DefineVariables(fContainer); + + // Create Correction Framework containers + fContainer->CreateContainer("MCTrackCont", "Track Container filled with MC information", AliHFEcuts::kNcutStepsMCTrack); + fContainer->CreateContainer("recTrackContReco", "Track Container filled with MC information", AliHFEcuts::kNcutStepsRecTrack + fPID->GetNumberOfPIDdetectors()); + fContainer->CreateContainer("recTrackContMC", "Track Container filled with MC information", AliHFEcuts::kNcutStepsRecTrack + fPID->GetNumberOfPIDdetectors()); + + fContainer->CreateContainer("hadronicBackground", "Container for Hadronic Background", 3); + fContainer->CreateContainer("recTrackContDEReco", "Container for displaced electron analysis with Reco information", 1); + fContainer->CreateContainer("recTrackContDEMC", "Container for displaced electron analysis with MC information", 1); + fContainer->CreateCorrelationMatrix("correlationstepafterPID","THnSparse with correlations"); + fContainer->CreateCorrelationMatrix("correlationstepafterDE","THnSparse with correlations"); + + // Define the step names + for(UInt_t istep = 0; istep < AliHFEcuts::kNcutStepsMCTrack; istep++){ + fContainer->SetStepTitle("MCTrackCont", AliHFEcuts::MCCutName(istep), istep); } - fCFM->SetParticleContainer(container); - - //create correlation matrix for unfolding - Int_t thnDim[2*kNvar]; - for (int k=0; kSetStepTitle("recTrackContReco", AliHFEcuts::RecoCutName(istep), istep); + fContainer->SetStepTitle("recTrackContMC", AliHFEcuts::RecoCutName(istep), istep); } - - if(!fCorrelation) fCorrelation = new TList(); - fCorrelation->SetName("correlation"); - - THnSparseF *correlation0 = new THnSparseF("correlationstepbeforePID","THnSparse with correlations",2*kNvar,thnDim); - THnSparseF *correlation1 = new THnSparseF("correlationstepafterPID","THnSparse with correlations",2*kNvar,thnDim); - for (int k=0; kSetBinEdges(k,binEdges[k]); - correlation0->SetBinEdges(k+kNvar,binEdges[k]); - correlation1->SetBinEdges(k,binEdges[k]); - correlation1->SetBinEdges(k+kNvar,binEdges[k]); + for(UInt_t ipid = 0; ipid < fPID->GetNumberOfPIDdetectors(); ipid++){ + fContainer->SetStepTitle("recTrackContReco", fPID->SortedDetectorName(ipid), AliHFEcuts::kNcutStepsRecTrack + ipid); + fContainer->SetStepTitle("recTrackContMC", fPID->SortedDetectorName(ipid), AliHFEcuts::kNcutStepsRecTrack + ipid); } - correlation0->Sumw2(); - correlation1->Sumw2(); - - fCorrelation->AddAt(correlation0,0); - fCorrelation->AddAt(correlation1,1); - +} + +//____________________________________________________________ +void AliAnalysisTaskHFE::InitPIDperformanceQA(){ // Add a histogram for Fake electrons const Int_t nDim=6; Int_t nBin[nDim] = {40, 8, 18, 2, 3, 3}; - Double_t* binEdges2[nDim]; - - //values for bin lower bounds - for(Int_t ivar = 0; ivar < kNvar; ivar++) - binEdges2[ivar] = binEdges[ivar]; - binEdges2[4] = AliHFEtools::MakeLinearBinning(nBin[4], 0, nBin[4]); - binEdges2[5] = AliHFEtools::MakeLinearBinning(nBin[5], 0, nBin[5]); - - fPIDperformance = new THnSparseF("PIDperformance", "PID performance; pT [GeV/c]; theta [rad]; phi [rad]; charge; type (0 - not el, 1 - other el, 2 - HF el; flavor (0 - no, 1 - charm, 2 - bottom)", nDim, nBin); - fPIDperformance->Sumw2(); - fSignalToBackgroundMC = new THnSparseF("SignalToBackgroundMC", "PID performance; pT [GeV/c]; theta [rad]; phi [rad]; charge; flavor (0 - no, 1 - charm, 2 - bottom); ITS Cluster (0 - no, 1 - first (and maybe second), 2 - second)", nDim, nBin); - fSignalToBackgroundMC->Sumw2(); - for(Int_t idim = 0; idim < nDim; idim++){ - fPIDperformance->SetBinEdges(idim, binEdges2[idim]); - fSignalToBackgroundMC->SetBinEdges(idim, binEdges2[idim]); - } - - // create correction framework container for V0-tagged particles, new bin limits in 4th bin - iBin[4] = 5; - delete binEdges[4]; - binEdges[4] = AliHFEtools::MakeLinearBinning(iBin[4], 0, iBin[4]); // Numeric precision - AliCFContainer *tagged = new AliCFContainer("taggedTrackContainer", "Correction Framework Container for tagged tracks", AliHFEcuts::kNcutStepsESDtrack, kNvar, iBin); - for(Int_t ivar = 0; ivar < kNvar; ivar++) - tagged->SetBinLimits(ivar, binEdges[ivar]); - fV0CF->SetParticleContainer(tagged); - - for(Int_t ivar = 0; ivar < kNvar; ivar++) - delete binEdges[ivar]; - for(Int_t ivar = kNvar; ivar < nDim; ivar++) - delete binEdges2[ivar]; -} + //number of variables on the grid:pt,eta,phi,charge, + const Double_t kPtbound[2] = {0.1, 20.}; + const Double_t kEtabound[2] = {-0.8, 0.8}; + const Double_t kPhibound[2] = {0., 2. * TMath::Pi()}; + const Double_t kChargebound[2] = {-1.1, 1.1}; + const Double_t kAddInf1bound[2] = {0., 3.}; + const Double_t kAddInf2bound[2] = {0., 3.}; + Double_t minima[nDim] = {kPtbound[0], kEtabound[0], kPhibound[0], kChargebound[0], kAddInf1bound[0], kAddInf2bound[0]}; + Double_t maxima[nDim] = {kPtbound[1], kEtabound[1], kPhibound[1], kChargebound[1], kAddInf1bound[1], kAddInf2bound[1]}; + + fQACollection->CreateTHnSparse("PIDperformance", "PID performance; pT [GeV/c]; theta [rad]; phi [rad]; charge; type (0 - not el, 1 - other el, 2 - HF el; flavor (0 - no, 1 - charm, 2 - bottom)", nDim, nBin, minima, maxima); + fQACollection->CreateTHnSparse("SignalToBackgroundMC", "PID performance; pT [GeV/c]; theta [rad]; phi [rad]; charge; flavor (0 - no, 1 - charm, 2 - bottom); ITS Cluster (0 - no, 1 - first (and maybe second), 2 - second)", nDim, nBin, minima, maxima); -//____________________________________________________________ -void AliAnalysisTaskHFE::AddPIDdetector(TString detector){ - // - // Adding PID detector to the task - // - if(!fPIDdetectors.Length()) - fPIDdetectors = detector; - else - fPIDdetectors += ":" + detector; + fQACollection->BinLogAxis("PIDperformance", 0); + fQACollection->BinLogAxis("SignalToBackgroundMC", 0); + fQACollection->Sumw2("PIDperformance"); + fQACollection->Sumw2("SignalToBackgroundMC"); } //____________________________________________________________ @@ -1340,11 +1211,11 @@ void AliAnalysisTaskHFE::PrintStatus() const { printf("\n\tAnalysis Settings\n\t========================================\n\n"); printf("\tSecondary Vertex finding: %s\n", GetPlugin(kSecVtx) ? "YES" : "NO"); printf("\tPrimary Vertex resolution: %s\n", GetPlugin(kPriVtx) ? "YES" : "NO"); + printf("\tDisplaced electron analysis step: %s\n", GetPlugin(kDEstep) ? "YES" : "NO"); + printf("\tTagged Track Analysis: %s\n", GetPlugin(kTaggedTrackAnalysis) ? "YES" : "NO"); printf("\n"); printf("\tParticle Identification Detectors:\n"); - TObjArray *detectors = fPIDdetectors.Tokenize(":"); - for(Int_t idet = 0; idet < detectors->GetEntries(); idet++) - printf("\t\t%s\n", (dynamic_cast(detectors->At(idet)))->String().Data()); + fPID->PrintStatus(); printf("\n"); printf("\tQA: \n"); printf("\t\tPID: %s\n", IsQAOn(kPIDqa) ? "YES" : "NO"); @@ -1353,147 +1224,6 @@ void AliAnalysisTaskHFE::PrintStatus() const { printf("\n"); } -//____________________________________________________________ -AliAnalysisTaskHFE::LabelContainer::LabelContainer(Int_t capacity): - fContainer(NULL), - fBegin(NULL), - fEnd(NULL), - fLast(NULL), - fCurrent(NULL) -{ - // - // Default constructor - // - fContainer = new Int_t[capacity]; - fBegin = &fContainer[0]; - fEnd = &fContainer[capacity - 1]; - fLast = fCurrent = fBegin; -} - -//____________________________________________________________ -Bool_t AliAnalysisTaskHFE::LabelContainer::Append(Int_t label){ - // - // Add Label to the container - // - if(fLast > fEnd) return kFALSE; - *fLast++ = label; - return kTRUE; -} - -//____________________________________________________________ -Bool_t AliAnalysisTaskHFE::LabelContainer::Find(Int_t label) const { - // - // Find track in the list of labels - // - for(Int_t *entry = fBegin; entry <= fLast; entry++) - if(*entry == label) return kTRUE; - return kFALSE; -} - -//____________________________________________________________ -Int_t AliAnalysisTaskHFE::LabelContainer::Next(){ - // - // Mimic iterator - // - if(fCurrent > fLast) return -1; - return *fCurrent++; -} - -//____________________________________________________________ -Int_t AliAnalysisTaskHFE::IsSignalElectron(const AliVParticle * const track) const{ - // - // Checks whether the identified electron track is coming from heavy flavour - // returns 0 in case of no signal, 1 in case of charm and 2 in case of Bottom - // - enum{ - kNoSignal = 0, - kCharm = 1, - kBeauty = 2 - }; - - if(!fMCEvent) return kNoSignal; - const AliVParticle *motherParticle = NULL, *mctrack = NULL; - TString objectType = track->IsA()->GetName(); - Int_t label = 0; - if(objectType.CompareTo("AliESDtrack") == 0 || objectType.CompareTo("AliAODTrack") == 0){ - // Reconstructed track - if((label = TMath::Abs(track->GetLabel())) && label < fMCEvent->GetNumberOfTracks()) - mctrack = fMCEvent->GetTrack(label); - } else { - // MCParticle - mctrack = track; - } - - if(!mctrack) return kNoSignal; - - Int_t pid = 0; - Int_t daughterPDG = 0, motherLabel = 0; - if(TString(mctrack->IsA()->GetName()).CompareTo("AliMCParticle") == 0){ - // case MC Particle - daughterPDG = TMath::Abs((dynamic_cast(mctrack))->Particle()->GetPdgCode()); - motherLabel = (dynamic_cast(mctrack))->Particle()->GetFirstMother(); - if(motherLabel >= 0 && motherLabel < fMCEvent->GetNumberOfTracks()) - motherParticle = fMCEvent->GetTrack(motherLabel); - if(motherParticle) - pid = TMath::Abs((dynamic_cast(motherParticle))->Particle()->GetPdgCode()); - } else { - // case AODMCParticle - daughterPDG = TMath::Abs((dynamic_cast(mctrack))->GetPdgCode()); - motherLabel = (dynamic_cast(mctrack))->GetMother(); - if(motherLabel >= 0 && motherLabel < fMCEvent->GetNumberOfTracks()) - motherParticle = fMCEvent->GetTrack(motherLabel); - if(motherParticle) - pid = TMath::Abs((dynamic_cast(motherParticle))->GetPdgCode()); - } - AliDebug(5, Form("Daughter PDG code: %d", daughterPDG)); - - if(!pid) return kNoSignal; - - // From here the two analysis modes go together - AliDebug(5, Form("Mother PDG code: %d", pid)); - - // identify signal according to Pdg Code - barions higher ranked than mesons - if(pid / 1000 == 4) return kCharm; // charmed baryon, 4th position in pdg code == 4 - if(pid / 1000 == 5) return kBeauty; // beauty baryon, 4th position in pdg code == 5 - if((pid % 1000) / 100 == 4) return kCharm; // charmed meson, 3rd position in pdg code == 4 - if((pid % 1000) / 100 == 5) return kBeauty; // beauty meson, 3rd position in pdg code == 5 - return kNoSignal; -} - -//__________________________________________ -Bool_t AliAnalysisTaskHFE::IsGammaElectron(const AliVParticle * const track) const { - // - // Check for MC if the electron is coming from Gamma - // - if(!fMCEvent) return kFALSE; - const AliVParticle *motherParticle = NULL, *mctrack = NULL; - TString objectType = track->IsA()->GetName(); - if(objectType.CompareTo("AliESDtrack") == 0 || objectType.CompareTo("AliAODTrack") == 0){ - // Reconstructed track - if(track->GetLabel()) - mctrack = fMCEvent->GetTrack(TMath::Abs(track->GetLabel())); - } else { - // MCParticle - mctrack = track; - } - - if(!mctrack) return kFALSE; - - Int_t motherPDG = 0; - if(TString(mctrack->IsA()->GetName()).CompareTo("AliMCParticle") == 0){ - // case MC Particle - motherParticle = fMCEvent->GetTrack((dynamic_cast(mctrack)->Particle()->GetFirstMother())); - if(motherParticle) - motherPDG = TMath::Abs((dynamic_cast(motherParticle))->Particle()->GetPdgCode()); - } else { - // case AODMCParticle - motherParticle = fMCEvent->GetTrack((dynamic_cast(mctrack))->GetMother()); - if(motherParticle) - motherPDG = TMath::Abs((dynamic_cast(motherParticle))->GetPdgCode()); - } - if(motherPDG!=22) return kFALSE; - else return kTRUE; -} //____________________________________________________________ Bool_t AliAnalysisTaskHFE::FillProductionVertex(const AliVParticle * const track) const{ // @@ -1546,71 +1276,103 @@ void AliAnalysisTaskHFE::SwitchOnPlugin(Int_t plug){ case kSecVtx: SETBIT(fPlugins, plug); break; case kIsElecBackGround: SETBIT(fPlugins, plug); break; case kPostProcess: SETBIT(fPlugins, plug); break; + case kDEstep: SETBIT(fPlugins, plug); break; + case kTaggedTrackAnalysis: SETBIT(fPlugins, plug); break; default: AliError("Unknown Plugin"); }; } -//_______________________________________________ -void AliAnalysisTaskHFE::SetWeightFactors(TH3D * const weightFactors){ - // - // Set the histos with the weights for the efficiency maps - // - fWeighting = kTRUE; - fWeightFactors = weightFactors; -} -//_______________________________________________ -void AliAnalysisTaskHFE::SetWeightFactorsFunction(TF1 * const weightFactorsFunction){ - // - // Set the histos with the weights for the efficiency maps - // - fWeighting = kTRUE; - fWeightFactorsFunction = weightFactorsFunction; - //printf("SetWeightFactors\n"); -} -//_______________________________________________ -Double_t AliAnalysisTaskHFE::FindWeight(Double_t pt, Double_t eta, Double_t phi) const { - // - // Find the weight corresponding to pt eta and phi in the TH3D - // - Double_t weight = 1.0; - if(fWeightFactors) { - - TAxis *ptaxis = fWeightFactors->GetXaxis(); - TAxis *etaaxis = fWeightFactors->GetYaxis(); - TAxis *phiaxis = fWeightFactors->GetZaxis(); - - Int_t ptbin = ptaxis->FindBin(pt); - Int_t etabin = etaaxis->FindBin(eta); - Int_t phibin = phiaxis->FindBin(phi); - - - weight = fWeightFactors->GetBinContent(ptbin,etabin,phibin); - } - else if(fWeightFactorsFunction) { - - weight = fWeightFactorsFunction->Eval(pt,eta,phi); - //printf("pt %f and weight %f\n",pt,weight); - - } - - //printf("pt %f, eta %f, phi %f, weight %f\n",pt,eta,phi,weight); - - return weight; - -} //__________________________________________ -Bool_t AliAnalysisTaskHFE::ProcessCutStep(Int_t cutStep, AliVParticle *track, Double_t *container, Bool_t signal, Bool_t alreadyseen,Double_t weight){ +Bool_t AliAnalysisTaskHFE::ProcessCutStep(Int_t cutStep, AliVParticle *track){ // // Check single track cuts for a given cut step // Fill the particle container // - if(!fCFM->CheckParticleCuts(cutStep, track)) return kFALSE; - if(signal) { - fCFM->GetParticleContainer()->Fill(container, cutStep + 2*AliHFEcuts::kNcutStepsESDtrack,weight); - fCFM->GetParticleContainer()->Fill(&container[5], cutStep,weight); - if(alreadyseen) { - fCFM->GetParticleContainer()->Fill(&container[5], cutStep + AliHFEcuts::kNcutStepsESDtrack,weight); - } + const Int_t kMCOffset = AliHFEcuts::kNcutStepsMCTrack; + if(!fCFM->CheckParticleCuts(cutStep + kMCOffset, track)) return kFALSE; + if(fVarManager->IsSignalTrack()) { + fVarManager->FillContainer(fContainer, "recTrackContReco", cutStep, kFALSE); + fVarManager->FillContainer(fContainer, "recTrackContMC", cutStep, kTRUE); } return kTRUE; } +//___________________________________________________ +void AliAnalysisTaskHFE::ReadCentrality() { + // + // Recover the centrality of the event from ESD or AOD + // + if(IsAODanalysis()){ + + AliAODEvent *fAOD = dynamic_cast(fInputEvent); + if(!fAOD){ + AliError("AOD Event required for AOD Analysis") + return; + } + // Centrality + //AliAODCentrality *aodCentrality = fAOD->GetCentrality(); + //Double_t fCentralityF = aodCentrality->GetCentralityPercentile("V0M"); + fCentralityF = 99.0; // Fake for the moment + + + } else { + + AliDebug(3, "Processing ESD Centrality"); + AliESDEvent *fESD = dynamic_cast(fInputEvent); + if(!fESD){ + AliError("ESD Event required for ESD Analysis") + return; + } + // Centrality + AliESDCentrality *esdCentrality = fESD->GetCentrality(); + fCentralityF = esdCentrality->GetCentralityPercentile("V0M"); + + //printf("centrality %f\n",fCentralityF); + + } + +} +//___________________________________________________ +void AliAnalysisTaskHFE::RejectionPileUpVertexRangeEventCut() { + // + // Recover the centrality of the event from ESD or AOD + // + if(IsAODanalysis()){ + + AliAODEvent *fAOD = dynamic_cast(fInputEvent); + if(!fAOD){ + AliError("AOD Event required for AOD Analysis") + return; + } + // PileUp + if(fRemovePileUp && fAOD->IsPileupFromSPD()) fIdentifiedAsPileUp = kTRUE; + // Z vertex + if(TMath::Abs(fAOD->GetPrimaryVertex()->GetZ()) > fCuts->GetVertexRange()) fIdentifiedAsOutInz = kTRUE; + // Event Cut + fPassTheEventCut = kTRUE; + if(!fCFM->CheckEventCuts(AliHFEcuts::kEventStepReconstructed, fAOD)) fPassTheEventCut = kFALSE; + + + } else { + + AliDebug(3, "Processing ESD Centrality"); + AliESDEvent *fESD = dynamic_cast(fInputEvent); + if(!fESD){ + AliError("ESD Event required for ESD Analysis") + return; + } + // PileUp + fIdentifiedAsPileUp = kFALSE; + if(fRemovePileUp && fESD->IsPileupFromSPD()) fIdentifiedAsPileUp = kTRUE; + // Z vertex + fIdentifiedAsOutInz = kFALSE; + if(fESD->GetPrimaryVertexTracks()){ + if(TMath::Abs(fESD->GetPrimaryVertexTracks()->GetZ()) > fCuts->GetVertexRange()) fIdentifiedAsOutInz = kTRUE; + } + //Event Cut + fPassTheEventCut = kTRUE; + if(!fCFM->CheckEventCuts(AliHFEcuts::kEventStepReconstructed, fESD)) fPassTheEventCut = kFALSE; + + + } + +} diff --git a/PWG3/hfe/AliAnalysisTaskHFE.h b/PWG3/hfe/AliAnalysisTaskHFE.h index cef17b12a5b..10d0f28371c 100644 --- a/PWG3/hfe/AliAnalysisTaskHFE.h +++ b/PWG3/hfe/AliAnalysisTaskHFE.h @@ -24,16 +24,17 @@ #include "AliAnalysisTaskSE.h" #endif -#ifndef ROOT_THnSparse -#include -#endif - -class AliHFEpid; +class AliHFEcontainer; +class AliHFEcollection; class AliHFEcuts; +class AliHFEelecbackground; class AliHFEmcQA; +class AliHFEpid; +class AliHFEpidQAmanager; class AliHFEsecVtx; -class AliHFEelecbackground; -class AliHFEcollection; +class AliHFEsignalCuts; +class AliHFEvarManager; +class AliHFEtaggedTrackAnalysis; class AliCFManager; class AliVEvent; class AliMCEvent; @@ -41,8 +42,6 @@ class AliVParticle; class AliTriggerAnalysis; class TH1I; class TList; -class TH3D; -class TF1; class AliAnalysisTaskHFE : public AliAnalysisTaskSE{ public: @@ -54,7 +53,9 @@ class AliAnalysisTaskHFE : public AliAnalysisTaskSE{ kPriVtx = 0, kSecVtx = 1, kIsElecBackGround = 2, - kPostProcess = 3 + kPostProcess = 3, + kDEstep = 4, + kTaggedTrackAnalysis = 5 }; enum CreationProcess_t{ kSignalCharm = 0, @@ -80,95 +81,77 @@ class AliAnalysisTaskHFE : public AliAnalysisTaskSE{ Bool_t IsESDanalysis() const { return !TestBit(kAODanalysis); }; Bool_t HasMCData() const { return TestBit(kHasMCdata); } Bool_t GetPlugin(Int_t plug) const { return TESTBIT(fPlugins, plug); }; + + // Get Components for configuration + AliHFEvarManager *GetVarManager() const { return fVarManager; } + AliHFEpid *GetPID() const { return fPID; } + void SetHFECuts(AliHFEcuts * const cuts) { fCuts = cuts; }; + void SetTaggedTrackCuts(AliHFEcuts * const cuts) { fTaggedTrackCuts = cuts; } void SetHFECutsPreselect(AliHFEcuts * const cuts) { fCutspreselect = cuts; }; void SetHFEElecBackGround(AliHFEelecbackground * const elecBackGround) { fElecBackGround = elecBackGround; }; void SetQAOn(Int_t qaLevel) { SETBIT(fQAlevel, qaLevel); }; void SwitchOnPlugin(Int_t plug); void SetHasMCData(Bool_t hasMC = kTRUE) { SetBit(kHasMCdata, hasMC); }; - void SetPIDdetectors(Char_t * const detectors){ fPIDdetectors = detectors; } - void SetPIDStrategy(UInt_t strategy) { fPIDstrategy = strategy; } + void SetFillSignalOnly(Bool_t signalOnly) { fFillSignalOnly = signalOnly; } + void SetRemovePileUp(Bool_t removePileUp) { fRemovePileUp = removePileUp; } void SetPIDPreselect(AliHFEpid * const cuts) { fPIDpreselect = cuts; }; - void AddPIDdetector(TString detector); void SetAODAnalysis() { SetBit(kAODanalysis, kTRUE); }; void SetESDAnalysis() { SetBit(kAODanalysis, kFALSE); }; - void SetWeightFactors(TH3D * const weightFactors); - void SetWeightFactorsFunction(TF1 * const weightFactorsFunction); void SetBackGroundFactorsFunction(TF1 * const backGroundFactorsFunction) { fBackGroundFactorsFunction = backGroundFactorsFunction; }; void PrintStatus() const; + void ReadCentrality(); + void RejectionPileUpVertexRangeEventCut(); private: enum{ kHasMCdata = BIT(19), kAODanalysis = BIT(20) }; - class LabelContainer{ - public: - LabelContainer(Int_t capacity); - ~LabelContainer() {delete[] fContainer; }; - - Bool_t Append(Int_t label); - Bool_t Find(Int_t Label) const; - Int_t Next(); - void ResetIterator(){ fCurrent = fBegin; } - private: - LabelContainer(const LabelContainer &); - LabelContainer &operator=(const LabelContainer &); - Int_t *fContainer; // the Container for the labels - Int_t *fBegin; // Pointer to the first entry - Int_t *fEnd; // Pointer to the end of the container - Int_t *fLast; // Pointer to the last entry - Int_t *fCurrent; // Current entry to mimic an iterator - }; - - Bool_t IsGammaElectron(const AliVParticle * const track) const; - Int_t IsSignalElectron(const AliVParticle * const track) const; Bool_t FillProductionVertex(const AliVParticle * const track) const; - Double_t FindWeight(Double_t pt, Double_t eta, Double_t phi) const; void MakeParticleContainer(); void MakeEventContainer(); + void InitPIDperformanceQA(); void ProcessMC(); void ProcessESD(); void ProcessAOD(); - void FilterTaggedTrack(AliESDtrack *track, Int_t species); Bool_t PreSelectTrack(AliESDtrack *track) const; Bool_t ProcessMCtrack(AliVParticle *track); - Bool_t ProcessCutStep(Int_t cutStep, AliVParticle *track, Double_t *container, Bool_t signal, Bool_t alreadyseen,Double_t weight); - + Bool_t ProcessCutStep(Int_t cutStep, AliVParticle *track); ULong_t fQAlevel; // QA level - TString fPIDdetectors; // Detectors for Particle Identification - UInt_t fPIDstrategy; // PID Strategy - Double_t fTPCBetheBlochParameters[5]; // TPC Bethe-Bloch Parameters UShort_t fPlugins; // Enabled Plugins - Bool_t fWeighting; // Weighting or not for the efficiency maps - TH3D *fWeightFactors; // Weight factors - TF1 *fWeightFactorsFunction; // Weight factors + Bool_t fFillSignalOnly; // Fill container only with MC Signal Tracks + Bool_t fRemovePileUp; // Remove Pile Up + Bool_t fIdentifiedAsPileUp; // Identified as pile-up + Bool_t fIdentifiedAsOutInz; // Out Of Range in z + Bool_t fPassTheEventCut; // Pass The Event Cut + Float_t fCentralityF; // Centrality TF1 *fBackGroundFactorsFunction; // BackGround factors + AliHFEcontainer *fContainer; //! The HFE container + AliHFEvarManager *fVarManager; // The var manager as the backbone of the analysis + AliHFEsignalCuts *fSignalCuts; //! MC true signal (electron coming from certain source) AliCFManager *fCFM; //! Correction Framework Manager - AliCFManager *fV0CF; //! Correction Framework Manager for V0-tagged tracks AliTriggerAnalysis *fTriggerAnalysis; //! Trigger Analysis for Normalisation - AliCFContainer * fHadronicBackground; //! Container for hadronic Background - TList *fCorrelation; //! response matrix for unfolding - THnSparseF *fPIDperformance; //! info on contamination and yield of electron spectra - THnSparseF *fSignalToBackgroundMC; //! Signal To Background Studies on pure MC information - AliHFEpid *fPID; //! PID - AliHFEpid *fPIDtagged; // PID oject for tagged tracks (identical clone without QA) + AliHFEpid *fPID; // PID + AliHFEpidQAmanager *fPIDqa; //! PID QA AliHFEpid *fPIDpreselect; // PID oject for pre-selected tracks (without QA) AliHFEcuts *fCuts; // Cut Collection - AliHFEcuts *fCutsTagged; // Cut Collection for tagged tracks + AliHFEcuts *fTaggedTrackCuts; // Cut Collection for V0 tagged tracks AliHFEcuts *fCutspreselect; // Cut Collection for pre-selected tracks AliHFEsecVtx *fSecVtx; //! Secondary Vertex Analysis AliHFEelecbackground *fElecBackGround;//! Background analysis AliHFEmcQA *fMCQA; //! MC QA - TH1I *fNEvents; //! counter for the number of Events - TH1I *fNElectronTracksEvent; //! Number of Electron candidates after PID decision per Event + AliHFEtaggedTrackAnalysis *fTaggedTrackAnalysis; //!Analyse V0-tagged tracks + + //-----------QA and output--------------- TList *fQA; //! QA histos for the cuts TList *fOutput; //! Container for Task Output TList *fHistMCQA; //! Output container for MC QA histograms TList *fHistSECVTX; //! Output container for sec. vertexing results TList *fHistELECBACKGROUND; //! Output container for electron background analysis AliHFEcollection *fQACollection; //! Tasks own QA collection + //--------------------------------------- ClassDef(AliAnalysisTaskHFE, 2) // The electron Analysis Task }; diff --git a/PWG3/hfe/AliESDv0KineCuts.cxx b/PWG3/hfe/AliESDv0KineCuts.cxx new file mode 100644 index 00000000000..a06da103b37 --- /dev/null +++ b/PWG3/hfe/AliESDv0KineCuts.cxx @@ -0,0 +1,902 @@ +/************************************************************************** + * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ + +/* + * author: M.Kalisky@gsi.de + * 08/Dec/2010 + * + * Description: This class allows with purely kinematical cuts + * to select clean samples of electrons, pions and protons from the + * V0 online finder ESD V0 candidates for PID and dectero resonse + * studies. + */ + +#include +#include + +#include "AliESDv0.h" +#include "AliESDtrack.h" +#include "AliESDEvent.h" +#include "AliLog.h" +#include "AliKFParticle.h" +#include "AliVTrack.h" +#include "AliKFVertex.h" + +#include "AliESDv0KineCuts.h" + +ClassImp(AliESDv0KineCuts) + +//____________________________________________________________________ +AliESDv0KineCuts::AliESDv0KineCuts() : + fV0(0x0) + , fEvent(0x0) + , fPrimaryVertex(0x0) +{ + // + // Default constructor + // + +} +//____________________________________________________________________ +AliESDv0KineCuts::~AliESDv0KineCuts(){ + // + // Destructor + // + + if (fV0) delete fV0; + +} +//____________________________________________________________________ +AliESDv0KineCuts::AliESDv0KineCuts(const AliESDv0KineCuts &ref): + TObject(ref) + , fV0(0x0) + , fEvent(0x0) + , fPrimaryVertex(0x0) +{ + // + // Copy operator + // + + ref.Copy(*this); +} +//____________________________________________________________________ +AliESDv0KineCuts &AliESDv0KineCuts::operator=(const AliESDv0KineCuts &ref){ + // + // assignment operator + // + if(this != &ref) + ref.Copy(*this); + return *this; +} +//____________________________________________________________________ +void AliESDv0KineCuts::Copy(TObject &ref) const { + // + // Performs the copying of the object + // + + TObject::Copy(ref); + + AliESDv0KineCuts &target = dynamic_cast(ref); + if(fV0) + target.fV0 = dynamic_cast(fV0->Clone()); + else + target.fV0 = NULL; + +} +//____________________________________________________________________ +Bool_t AliESDv0KineCuts::ProcessV0(AliESDv0* const v0, Int_t &pdgV0, Int_t &pdgP, Int_t &pdgN){ + // + // main user function + // + + if(!v0) return kFALSE; + if(!fEvent){ + AliErrorClass("No valid Event pointer available, provide it first"); + return kFALSE; + } + + if(!V0CutsCommon(v0)) return kFALSE; + + const Int_t id = PreselectV0(v0); + + if(!SingleTrackCuts(v0)) return kFALSE; + + switch(id){ + case kUndef: + return kFALSE; + case kGamma: + return CaseGamma(v0, pdgV0, pdgP, pdgN); + case kK0: + return CaseK0(v0, pdgV0, pdgP, pdgN); + case kLambda: + return CaseLambda(v0, pdgV0, pdgP, pdgN, 0); + case kALambda: + return CaseLambda(v0, pdgV0, pdgP, pdgN, 1); + default: + return kFALSE; + } + + return kFALSE; +} +//____________________________________________________________________ +Bool_t AliESDv0KineCuts::ProcessV0(AliESDv0* const v0, Int_t &pdgP, Int_t &pdgN){ + // + // main user function, simplified if the V0 identity is not necessary + // + + if(!v0) return kFALSE; + if(!fEvent){ + AliErrorClass("No valid Event pointer available, provide it first"); + return kFALSE; + } + + Int_t idV0 = -1; + return ProcessV0(v0, idV0, pdgP, pdgN); + +} +//____________________________________________________________________ +Int_t AliESDv0KineCuts::PreselectV0(AliESDv0* const v0){ + // + // Make a preselection (exclusive) of the V0 cadidates based on + // Armenteros plot + // + + Float_t ap[2] = {-1., -1.}; + Armenteros(v0, ap); + // for clarity + const Float_t alpha = ap[0]; + const Float_t qt = ap[1]; + + // selection cuts + // - the reagions for different candidates must not overlap + + // Gamma cuts + const Double_t cutAlphaG = 0.35; + const Double_t cutAlphaG2[2] = {0.6, 0.8}; + const Double_t cutQTG = 0.05; + const Double_t cutQTG2 = 0.04; + + // K0 cuts + const Float_t cutQTK0[2] = {0.1075, 0.215}; + const Float_t cutAPK0[2] = {0.199, 0.8}; // parameters for curved QT cut + + // Lambda & A-Lambda cuts + const Float_t cutQTL = 0.03; + const Float_t cutAlphaL[2] = {0.35, 0.7}; + const Float_t cutAlphaAL[2] = {-0.7, -0.35}; + const Float_t cutAPL[3] = {0.107, -0.69, 0.5}; // parameters fir curved QT cut + + + // Check for Gamma candidates + if(qt < cutQTG){ + if( (TMath::Abs(alpha) < cutAlphaG) ) return kGamma; + } + // additional region - should help high pT gammas + if(qt < cutQTG2){ + if( (TMath::Abs(alpha) > cutAlphaG2[0]) && (TMath::Abs(alpha) < cutAlphaG2[1]) ) return kGamma; + } + + + // Check for K0 candidates + Float_t q = cutAPK0[0] * TMath::Sqrt(TMath::Abs(1 - alpha*alpha/(cutAPK0[1]*cutAPK0[1]))); + if( (qt > cutQTK0[0]) && (qt < cutQTK0[1]) && (qt > q) ){ + return kK0; + } + + // Check for Lambda candidates + q = cutAPL[0] * TMath::Sqrt(TMath::Abs(1 - ( (alpha + cutAPL[1]) * (alpha + cutAPL[1]) ) / (cutAPL[2]*cutAPL[2]) )); + if( (alpha > cutAlphaL[0]) && (alpha < cutAlphaL[1]) && (qt > cutQTL) && (qt < q) ){ + return kLambda; + } + + // Check for A-Lambda candidates + q = cutAPL[0] * TMath::Sqrt(TMath::Abs(1 - ( (alpha - cutAPL[1]) * (alpha - cutAPL[1]) ) / (cutAPL[2]*cutAPL[2]) )); + if( (alpha > cutAlphaAL[0]) && (alpha < cutAlphaAL[1]) && (qt > cutQTL) && (qt < q) ){ + return kALambda; + } + + return kUndef; +} +//____________________________________________________________________ +Bool_t AliESDv0KineCuts::SingleTrackCuts(AliESDv0 * const v0){ + // + // apply single track cuts + // correct sign not relevat here + // + + if(!v0) return kFALSE; + + Int_t pIndex = 0, nIndex = 0; + pIndex = v0->GetPindex(); + nIndex = v0->GetNindex(); + AliESDtrack* d[2]; + d[0] = dynamic_cast(fEvent->GetTrack(pIndex)); + d[1] = dynamic_cast(fEvent->GetTrack(nIndex)); + + for(Int_t i=0; i<2; ++i){ + if(!d[i]) return kFALSE; + + // status word + ULong_t status = d[i]->GetStatus(); + + // No. of TPC clusters leave to the users + if(d[i]->GetTPCNcls() < 1) return kFALSE; + + // TPC refit + if(!(status & AliESDtrack::kTPCrefit)) return kFALSE; + + // Chi2 per TPC cluster + Int_t nTPCclusters = d[i]->GetTPCNcls(); + Float_t chi2perTPCcluster = d[i]->GetTPCchi2()/Float_t(nTPCclusters); + if(chi2perTPCcluster > 4) return kFALSE; + + // TPC cluster ratio + Float_t cRatioTPC = d[i]->GetTPCNclsF() > 0. ? static_cast(d[i]->GetTPCNcls())/static_cast (d[i]->GetTPCNclsF()) : 1.; + if(cRatioTPC < 0.6) return kFALSE; + + // kinks + if(d[i]->GetKinkIndex(0) != 0) return kFALSE; + + } + + return kTRUE; +} +//____________________________________________________________________ +Bool_t AliESDv0KineCuts::CaseGamma(AliESDv0* const v0, Int_t &pdgV0, Int_t &pdgP, Int_t &pdgN){ + // + // process the gamma conversion candidate + // + + if(!v0) return kFALSE; + + AliVTrack* daughter[2]; + Int_t pIndex = 0, nIndex = 0; + + Bool_t sign = CheckSigns(v0); + if(sign){ + pIndex = v0->GetPindex(); + nIndex = v0->GetNindex(); + } + else{ + pIndex = v0->GetNindex(); + nIndex = v0->GetPindex(); + } + daughter[0] = dynamic_cast(fEvent->GetTrack(pIndex)); + daughter[1] = dynamic_cast(fEvent->GetTrack(nIndex)); + if(!daughter[0] || !daughter[1]) return kFALSE; + + AliKFParticle *kfMother = CreateMotherParticle(daughter[0], daughter[1], TMath::Abs(kElectron), TMath::Abs(kElectron)); + if(!kfMother) return kFALSE; + + AliESDtrack* d[2]; + d[0] = dynamic_cast(fEvent->GetTrack(pIndex)); + d[1] = dynamic_cast(fEvent->GetTrack(nIndex)); + + Float_t iMass = v0->GetEffMass(0, 0); + + // Cut values + const Double_t cutMass = 0.05; // old [0.05] + const Double_t cutChi2NDF = 40.; // old [7.] + const Double_t cutCosPoint[2] = {0., 0.02}; // old [0., 0.03] + const Double_t cutDCA[2] = {0., 0.25}; // old [0., 0.25] + const Double_t cutProdVtxR[2] = {8., 90.}; // old [6., 9999] + const Double_t cutPsiPair[2] = {0., 0.05}; // old [0. 0.05] + const Double_t cutOAngle[2] = {0, 0.1}; // old [0., 0.1] + + // cos pointing angle + Double_t cosPoint = v0->GetV0CosineOfPointingAngle(); + cosPoint = TMath::ACos(cosPoint); + + // DCA between daughters + Double_t dca = v0->GetDcaV0Daughters(); + + // Production vertex + Double_t x, y, z; + v0->GetXYZ(x,y,z); + Double_t r = TMath::Sqrt(x*x + y*y); + + Double_t xy[2]; + Double_t r2 = -1.; + if ( GetConvPosXY(d[0], d[1], xy) ){ + r2 = TMath::Sqrt(xy[0]*xy[0] + xy[1]*xy[1]); + } + + // Opening angle + Double_t oAngle = OpenAngle(v0); + + // psi pair + Double_t psiPair = PsiPair(v0); + + // V0 chi2/ndf + Double_t chi2ndf = kfMother->GetChi2()/kfMother->GetNDF(); + + if(kfMother) delete kfMother; + + // apply the cuts + + if(iMass > cutMass) return kFALSE; + + if(chi2ndf > cutChi2NDF) return kFALSE; + + if(cosPoint < cutCosPoint[0] || cosPoint > cutCosPoint[1]) return kFALSE; + + if(dca < cutDCA[0] || dca > cutDCA[1]) return kFALSE; + + if(r < cutProdVtxR[0] || r > cutProdVtxR[1]) return kFALSE; + + if(psiPair < cutPsiPair[0] || psiPair > cutPsiPair[1]) return kFALSE; + + if(oAngle < cutOAngle[0] || oAngle > cutOAngle[1]) return kFALSE; + + // all cuts passed + + pdgV0 = 22; + if(sign){ + pdgP = -11; + pdgN = 11; + } + else{ + pdgP = 11; + pdgN = -11; + } + + return kTRUE; +} +//____________________________________________________________________ +Bool_t AliESDv0KineCuts::CaseK0(AliESDv0* const v0, Int_t &pdgV0, Int_t &pdgP, Int_t &pdgN){ + // + // process the K0 candidate + // + + if(!v0) return kFALSE; + + AliVTrack* daughter[2]; + Int_t pIndex = 0, nIndex = 0; + Bool_t sign = CheckSigns(v0); + if(sign){ + pIndex = v0->GetPindex(); + nIndex = v0->GetNindex(); + } + else{ + pIndex = v0->GetNindex(); + nIndex = v0->GetPindex(); + } + + daughter[0] = dynamic_cast(fEvent->GetTrack(pIndex)); + daughter[1] = dynamic_cast(fEvent->GetTrack(nIndex)); + if(!daughter[0] || !daughter[1]) return kFALSE; + + AliKFParticle *kfMother = CreateMotherParticle(daughter[0], daughter[1], TMath::Abs(kPiPlus), TMath::Abs(kPiPlus)); + if(!kfMother) return kFALSE; + + AliESDtrack* d[2]; + d[0] = dynamic_cast(fEvent->GetTrack(pIndex)); + d[1] = dynamic_cast(fEvent->GetTrack(nIndex)); + + Float_t iMass = v0->GetEffMass(2, 2); + + const Double_t cutMass[2] = {0.486, 0.508}; // ORG [0.485, 0.51] + const Double_t cutChi2NDF = 40.; // ORG [7.] + const Double_t cutCosPoint[2] = {0., 0.02}; // ORG [0., 0.03] + const Double_t cutDCA[2] = {0., 0.2}; // ORG [0., 0.1] + const Double_t cutProdVtxR[2] = {2.0, 30.}; // ORG [0., 8.1] + + // cos pointing angle + Double_t cosPoint = v0->GetV0CosineOfPointingAngle(); + cosPoint = TMath::ACos(cosPoint); + + // DCA between daughters + Double_t dca = v0->GetDcaV0Daughters(); + + // Production vertex + Double_t x, y, z; + v0->GetXYZ(x,y,z); + + Double_t r = TMath::Sqrt(x*x + y*y); + + // V0 chi2/ndf + Double_t chi2ndf = kfMother->GetChi2()/kfMother->GetNDF(); + + if(kfMother) delete kfMother; + + // + // apply the cuts + // + if(iMass < cutMass[0] || iMass > cutMass[1]) return kFALSE; + + if(chi2ndf > cutChi2NDF) return kFALSE; + + if(cosPoint < cutCosPoint[0] || cosPoint > cutCosPoint[1]) return kFALSE; + + if(dca < cutDCA[0] || dca > cutDCA[1]) return kFALSE; + + if(r < cutProdVtxR[0] || r > cutProdVtxR[1]) return kFALSE; + + // all cuts passed + pdgV0 = 310; + if(sign){ + pdgP = 211; + pdgN = -211; + } + else{ + pdgP = -211; + pdgN = 211; + } + + return kTRUE; +} +//____________________________________________________________________ +Bool_t AliESDv0KineCuts::CaseLambda(AliESDv0* const v0, Int_t &pdgV0, Int_t &pdgP, Int_t &pdgN, Int_t id){ + // + // process teh Lambda and Anti-Lambda candidate + // + + if(!v0) return kFALSE; + + const Double_t cL0mass=TDatabasePDG::Instance()->GetParticle(kLambda0)->Mass(); // PDG lambda mass + + AliVTrack* daughter[2]; + Int_t pIndex = 0, nIndex = 0; + Float_t mMass[2] = {-1., -1.}; + Bool_t sign = CheckSigns(v0); + if(sign){ + pIndex = v0->GetPindex(); + nIndex = v0->GetNindex(); + mMass[0] = v0->GetEffMass(4, 2); + mMass[1] = v0->GetEffMass(2, 4); + } + else{ + pIndex = v0->GetNindex(); + nIndex = v0->GetPindex(); + mMass[0] = v0->GetEffMass(2, 4); + mMass[1] = v0->GetEffMass(4, 2); + } + + daughter[0] = dynamic_cast(fEvent->GetTrack(pIndex)); + daughter[1] = dynamic_cast(fEvent->GetTrack(nIndex)); + if(!daughter[0] || !daughter[1]) return kFALSE; + + AliKFParticle *kfMother[2] = {0x0, 0x0}; + // Lambda + kfMother[0] = CreateMotherParticle(daughter[0], daughter[1], TMath::Abs(kProton), TMath::Abs(kPiPlus)); + if(!kfMother[0]) return kFALSE; + + // Anti-Lambda + kfMother[1] = CreateMotherParticle(daughter[0], daughter[1], TMath::Abs(kPiPlus), TMath::Abs(kProton)); + if(!kfMother[1]) return kFALSE; + + Float_t dMass[2] = {TMath::Abs(mMass[0] - cL0mass), TMath::Abs(mMass[1] - cL0mass)}; + + AliESDtrack* d[2]; + d[0] = dynamic_cast(fEvent->GetTrack(pIndex)); + d[1] = dynamic_cast(fEvent->GetTrack(nIndex)); + if(!d[0] || !d[1]) return kFALSE; + + Float_t p[2] = {d[0]->GetP(), d[1]->GetP()}; + + // check the 3 lambda - antilambda variables + Int_t check[2] = {-1, -1}; // 0 : lambda, 1 : antilambda + // 1) momentum of the daughter particles - proton is expected to have higher momentum than pion + check[0] = (p[0] > p[1]) ? 0 : 1; + // 2) mass of the mother particle + check[1] = (dMass[0] < dMass[1]) ? 0 : 1; + + // require positive correlation of (1) and (2) + if(check[0] != check[1]){ + if(kfMother[0]) delete kfMother[0]; + if(kfMother[1]) delete kfMother[1]; + return kFALSE; + } + + // now that the check[0] == check[1] + const Int_t type = check[0]; + + // require that the input armenteros preselection agree: + if(type != id) return kFALSE; + + Float_t iMass =0.; + if(sign){ + iMass = (type == 0) ? v0->GetEffMass(4, 2) : v0->GetEffMass(2, 4); + } + else{ + iMass = (type == 0) ? v0->GetEffMass(2, 4) : v0->GetEffMass(4, 2); + } + + // Cuts + const Double_t cutMass[2] = {1.11, 1.12}; // ORG [1.11, 1.12] + const Double_t cutChi2NDF = 40.; // ORG [5.] + const Double_t cutCosPoint[2] = {0., 0.02}; // ORG [0., 0.03] + const Double_t cutDCA[2] = {0., 0.2}; // ORG [0., 0.2] + const Double_t cutProdVtxR[2] = {2., 40.}; // ORG [0., 24.] + + // cos pointing angle + Double_t cosPoint = v0->GetV0CosineOfPointingAngle(); + cosPoint = TMath::ACos(cosPoint); + + // DCA between daughters + Double_t dca = v0->GetDcaV0Daughters(); + + // Production vertex + Double_t x, y, z; + v0->GetXYZ(x,y,z); + Double_t r = TMath::Sqrt(x*x + y*y); + + // proton - pion indices + Int_t ix[2] = {0, 1}; + if(1 == type){ + ix[0] = 1; + ix[1] = 0; + } + + // V0 chi2/ndf + Double_t chi2ndf = kfMother[type]->GetChi2()/kfMother[type]->GetNDF(); + + if(kfMother[0]) delete kfMother[0]; + if(kfMother[1]) delete kfMother[1]; + + // + // apply the cuts + // + + if(iMass < cutMass[0] || iMass > cutMass[1]) return kFALSE; + + if(chi2ndf > cutChi2NDF) return kFALSE; + + if(cosPoint < cutCosPoint[0] || cosPoint > cutCosPoint[1]) return kFALSE; + + if(dca < cutDCA[0] || dca > cutDCA[1]) return kFALSE; + + if(r < cutProdVtxR[0] || r > cutProdVtxR[1]) return kFALSE; + + // all cuts passed + + if(0 == type){ + pdgV0 = 3122; + if(sign){ + pdgP = 2212; + pdgN = -211; + } + else{ + pdgP = -211; + pdgN = 2212; + } + } + else{ + pdgV0 = -3122; + if(sign){ + pdgP = 211; + pdgN = -2212; + } + else{ + pdgP = -2212; + pdgN = 211; + } + } + + return kTRUE; +} +//____________________________________________________________________ +Bool_t AliESDv0KineCuts::V0CutsCommon(const AliESDv0 * const v0){ + // + // V0 cuts common to all V0s + // + + AliESDtrack* dN, *dP; + + dP = dynamic_cast(fEvent->GetTrack(v0->GetPindex())); + dN = dynamic_cast(fEvent->GetTrack(v0->GetNindex())); + + if(!dN || !dP) return kFALSE; + + Int_t qP = dP->Charge(); + Int_t qN = dN->Charge(); + + if((qP*qN) != -1) return kFALSE; + + return kTRUE; +} +//____________________________________________________________________ +void AliESDv0KineCuts::Armenteros(AliESDv0* const v0, Float_t val[2]){ + // + // computes the Armenteros variables for given V0 + // fills the histogram + // returns the values via "val" + // + + Double_t mn[3] = {0,0,0}; + Double_t mp[3] = {0,0,0}; + Double_t mm[3] = {0,0,0}; + + if(CheckSigns(v0)){ + v0->GetNPxPyPz(mn[0],mn[1],mn[2]); //reconstructed cartesian momentum components of negative daughter + v0->GetPPxPyPz(mp[0],mp[1],mp[2]); //reconstructed cartesian momentum components of positive daughter + } + else{ + v0->GetPPxPyPz(mn[0],mn[1],mn[2]); //reconstructed cartesian momentum components of negative daughter + v0->GetNPxPyPz(mp[0],mp[1],mp[2]); //reconstructed cartesian momentum components of positive daughter + } + v0->GetPxPyPz(mm[0],mm[1],mm[2]); //reconstructed cartesian momentum components of mother + + TVector3 vecN(mn[0],mn[1],mn[2]); + TVector3 vecP(mp[0],mp[1],mp[2]); + TVector3 vecM(mm[0],mm[1],mm[2]); + + Double_t thetaP = acos((vecP * vecM)/(vecP.Mag() * vecM.Mag())); + Double_t thetaN = acos((vecN * vecM)/(vecN.Mag() * vecM.Mag())); + + Double_t alfa = ((vecP.Mag())*cos(thetaP)-(vecN.Mag())*cos(thetaN))/ + ((vecP.Mag())*cos(thetaP)+(vecN.Mag())*cos(thetaN)) ; + Double_t qt = vecP.Mag()*sin(thetaP); + + val[0] = alfa; + val[1] = qt; +} +//____________________________________________________________________ +Bool_t AliESDv0KineCuts::CheckSigns(AliESDv0* const v0){ + // + // check wheter the sign was correctly applied to + // V0 daughter tracks + // + + Bool_t correct = kFALSE; + + Int_t pIndex = 0, nIndex = 0; + pIndex = v0->GetPindex(); + nIndex = v0->GetNindex(); + + AliESDtrack* d[2]; + d[0] = dynamic_cast(fEvent->GetTrack(pIndex)); + d[1] = dynamic_cast(fEvent->GetTrack(nIndex)); + + Int_t sign[2]; + sign[0] = (int)d[0]->GetSign(); + sign[1] = (int)d[1]->GetSign(); + + if(-1 == sign[0] && 1 == sign[1]){ + correct = kFALSE; + } + else{ + correct = kTRUE; + } + + return correct; +} +//____________________________________________________________________ +void AliESDv0KineCuts::SetEvent(AliESDEvent* const event){ + // + // direct setter of ESD event + // + if(!event){ + AliErrorClass("Invalid input event pointer"); + return; + } + fEvent = event; +} +//____________________________________________________________________ +void AliESDv0KineCuts::SetEvent(AliVEvent* const event){ + // + // Set the current working ESD event + // + if(!event){ + AliErrorClass("Invalid input event pointer"); + return; + } + + SetEvent(dynamic_cast(event)); +} +//________________________________________________________________ +Double_t AliESDv0KineCuts::OpenAngle(AliESDv0 *v0) const { + // + // Opening angle between two daughter tracks + // + Double_t mn[3] = {0,0,0}; + Double_t mp[3] = {0,0,0}; + + + v0->GetNPxPyPz(mn[0],mn[1],mn[2]);//reconstructed cartesian momentum components of negative daughter; + v0->GetPPxPyPz(mp[0],mp[1],mp[2]);//reconstructed cartesian momentum components of positive daughter; + + + Double_t openAngle = TMath::ACos((mp[0]*mn[0] + mp[1]*mn[1] + mp[2]*mn[2])/(TMath::Sqrt(mp[0]*mp[0] + mp[1]*mp[1] + mp[2]*mp[2])*TMath::Sqrt(mn[0]*mn[0] + mn[1]*mn[1] + mn[2]*mn[2]))); + + return TMath::Abs(openAngle); +} +//________________________________________________________________ +Double_t AliESDv0KineCuts::PsiPair(AliESDv0* const v0) { + // + // Angle between daughter momentum plane and plane + // + + if(!fEvent) return -1.; + + Float_t magField = fEvent->GetMagneticField(); + + Int_t pIndex = -1; + Int_t nIndex = -1; + if(CheckSigns(v0)){ + pIndex = v0->GetPindex(); + nIndex = v0->GetNindex(); + } + else{ + pIndex = v0->GetNindex(); + nIndex = v0->GetPindex(); + } + + + AliESDtrack* daughter[2]; + + daughter[0] = dynamic_cast(fEvent->GetTrack(pIndex)); + daughter[1] = dynamic_cast(fEvent->GetTrack(nIndex)); + + Double_t x, y, z; + v0->GetXYZ(x,y,z);//Reconstructed coordinates of V0; to be replaced by Markus Rammler's method in case of conversions! + + Double_t mn[3] = {0,0,0}; + Double_t mp[3] = {0,0,0}; + + + v0->GetNPxPyPz(mn[0],mn[1],mn[2]);//reconstructed cartesian momentum components of negative daughter; + v0->GetPPxPyPz(mp[0],mp[1],mp[2]);//reconstructed cartesian momentum components of positive daughter; + + + Double_t deltat = 1.; + deltat = TMath::ATan(mp[2]/(TMath::Sqrt(mp[0]*mp[0] + mp[1]*mp[1])+1.e-13)) - TMath::ATan(mn[2]/(TMath::Sqrt(mn[0]*mn[0] + mn[1]*mn[1])+1.e-13));//difference of angles of the two daughter tracks with z-axis + + Double_t radiussum = TMath::Sqrt(x*x + y*y) + 50;//radius to which tracks shall be propagated + + Double_t momPosProp[3]; + Double_t momNegProp[3]; + + AliExternalTrackParam pt(*daughter[0]), nt(*daughter[1]); + + Double_t psiPair = 4.; + + if(nt.PropagateTo(radiussum,magField) == 0)//propagate tracks to the outside + psiPair = -5.; + if(pt.PropagateTo(radiussum,magField) == 0) + psiPair = -5.; + pt.GetPxPyPz(momPosProp);//Get momentum vectors of tracks after propagation + nt.GetPxPyPz(momNegProp); + + Double_t pEle = + TMath::Sqrt(momNegProp[0]*momNegProp[0]+momNegProp[1]*momNegProp[1]+momNegProp[2]*momNegProp[2]);//absolute momentum value of negative daughter + Double_t pPos = + TMath::Sqrt(momPosProp[0]*momPosProp[0]+momPosProp[1]*momPosProp[1]+momPosProp[2]*momPosProp[2]);//absolute momentum value of positive daughter + + Double_t scalarproduct = + momPosProp[0]*momNegProp[0]+momPosProp[1]*momNegProp[1]+momPosProp[2]*momNegProp[2];//scalar product of propagated positive and negative daughters' momenta + + Double_t chipair = TMath::ACos(scalarproduct/(pEle*pPos));//Angle between propagated daughter tracks + + psiPair = TMath::Abs(TMath::ASin(deltat/chipair)); + + return psiPair; +} +//___________________________________________________________________ +Bool_t AliESDv0KineCuts::GetConvPosXY(AliESDtrack * const ptrack, AliESDtrack * const ntrack, Double_t convpos[2]){ + // + // recalculate the gamma conversion XY postition + // + + const Double_t b = fEvent->GetMagneticField(); + + Double_t helixcenterpos[2]; + GetHelixCenter(ptrack,b,ptrack->Charge(),helixcenterpos); + + Double_t helixcenterneg[2]; + GetHelixCenter(ntrack,b,ntrack->Charge(),helixcenterneg); + + Double_t poshelix[6]; + ptrack->GetHelixParameters(poshelix,b); + Double_t posradius = TMath::Abs(1./poshelix[4]); + + Double_t neghelix[6]; + ntrack->GetHelixParameters(neghelix,b); + Double_t negradius = TMath::Abs(1./neghelix[4]); + + Double_t xpos = helixcenterpos[0]; + Double_t ypos = helixcenterpos[1]; + Double_t xneg = helixcenterneg[0]; + Double_t yneg = helixcenterneg[1]; + + convpos[0] = (xpos*negradius + xneg*posradius)/(negradius+posradius); + convpos[1] = (ypos*negradius+ yneg*posradius)/(negradius+posradius); + + return 1; +} +//___________________________________________________________________ +Bool_t AliESDv0KineCuts::GetHelixCenter(AliESDtrack * const track, Double_t b,Int_t charge, Double_t center[2]){ + // + // computes the center of the track helix + // + + Double_t pi = TMath::Pi(); + + Double_t helix[6]; + track->GetHelixParameters(helix,b); + + Double_t xpos = helix[5]; + Double_t ypos = helix[0]; + Double_t radius = TMath::Abs(1./helix[4]); + Double_t phi = helix[2]; + + if(phi < 0){ + phi = phi + 2*pi; + } + + phi -= pi/2.; + Double_t xpoint = radius * TMath::Cos(phi); + Double_t ypoint = radius * TMath::Sin(phi); + + if(b<0){ + if(charge > 0){ + xpoint = - xpoint; + ypoint = - ypoint; + } + + if(charge < 0){ + xpoint = xpoint; + ypoint = ypoint; + } + } + if(b>0){ + if(charge > 0){ + xpoint = xpoint; + ypoint = ypoint; + } + + if(charge < 0){ + xpoint = - xpoint; + ypoint = - ypoint; + } + } + center[0] = xpos + xpoint; + center[1] = ypos + ypoint; + + return 1; +} +//___________________________________________________________________ +AliKFParticle *AliESDv0KineCuts::CreateMotherParticle(const AliVTrack* const pdaughter, const AliVTrack* const ndaughter, Int_t pspec, Int_t nspec){ + // + // Creates a mother particle + // + AliKFParticle pkfdaughter(*pdaughter, pspec); + AliKFParticle nkfdaughter(*ndaughter, nspec); + + + // Create the mother particle + AliKFParticle *m = new AliKFParticle(pkfdaughter, nkfdaughter); + // DEBUG - testing + if(TMath::Abs(kElectron) == pspec && TMath::Abs(kElectron) == nspec) m->SetMassConstraint(0, 0.001); + else if(TMath::Abs(kPiPlus) == pspec && TMath::Abs(kPiPlus) == nspec) m->SetMassConstraint(TDatabasePDG::Instance()->GetParticle(kK0Short)->Mass(), 0.); + else if(TMath::Abs(kProton) == pspec && TMath::Abs(kPiPlus) == nspec) m->SetMassConstraint(TDatabasePDG::Instance()->GetParticle(kLambda0)->Mass(), 0.); + else if(TMath::Abs(kPiPlus) == pspec && TMath::Abs(kProton) == nspec) m->SetMassConstraint(TDatabasePDG::Instance()->GetParticle(kLambda0)->Mass(), 0.); + else{ + AliErrorClass("Wrong daughter ID - mass constraint can not be set"); + } + + AliKFVertex improvedVertex = *fPrimaryVertex; + improvedVertex += *m; + m->SetProductionVertex(improvedVertex); + + // update 15/06/2010 + // mother particle will not be added to primary vertex but only to its copy + // as this confilcts with calling + // m->SetPrimaryVertex() function and + // subsequently removing the mother particle afterwards + // Source: Sergey Gorbunov + + return m; +} diff --git a/PWG3/hfe/AliESDv0KineCuts.h b/PWG3/hfe/AliESDv0KineCuts.h new file mode 100644 index 00000000000..1cc174295dc --- /dev/null +++ b/PWG3/hfe/AliESDv0KineCuts.h @@ -0,0 +1,75 @@ +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ +/* + * plesae see source file for more details + */ +#ifndef ALIESDV0KINECUTS_H +#define ALIESDV0KINECUTS_H + +#include + +class AliESDv0; +class AliESDEvent; +class AliVEvent; +class AliESDtrack; +class AliVTrack; +class AliKFParticle; +class AliKFVertex; + +class AliESDv0KineCuts : public TObject{ + public: + enum{ // Reconstructed V0 + kUndef = -1, + kGamma = 0, + kK0 = 1, + kLambda = 2, + kALambda = 3 + }; + + AliESDv0KineCuts(); + virtual ~AliESDv0KineCuts(); + + AliESDv0KineCuts(const AliESDv0KineCuts &ref); + AliESDv0KineCuts &operator=(const AliESDv0KineCuts &ref); + + Bool_t ProcessV0(AliESDv0* const v0, Int_t &pdgV0, Int_t &pdgP, Int_t &pdgN); + Bool_t ProcessV0(AliESDv0* const v0, Int_t &pdgP, Int_t &pdgN); + + Int_t PreselectV0(AliESDv0* const v0); + + Bool_t CaseGamma(AliESDv0* const v0, Int_t &pdgV0, Int_t &pdgP, Int_t &pdgN); + Bool_t CaseK0(AliESDv0* const v0, Int_t &pdgV0, Int_t &pdgP, Int_t &pdgN); + Bool_t CaseLambda(AliESDv0* const v0, Int_t &pdgV0, Int_t &pdgP, Int_t &pdgN, Int_t id); + + Bool_t V0CutsCommon(const AliESDv0 * const v0); + Bool_t SingleTrackCuts(AliESDv0 * const v0); + void Armenteros(AliESDv0* const v0, Float_t val[2]); + Bool_t CheckSigns(AliESDv0* const v0); + + void SetEvent(AliESDEvent* const event); + void SetEvent(AliVEvent* const event); + void SetPrimaryVertex(AliKFVertex* const v) { fPrimaryVertex = v; }; + + Double_t OpenAngle(AliESDv0 *v0) const;//opening angle between V0 daughters; close to zero for conversions + Double_t PsiPair(AliESDv0* const v0); + + Bool_t GetConvPosXY(AliESDtrack * const ptrack, AliESDtrack * const ntrack, Double_t convpos[2]); + Bool_t GetHelixCenter(AliESDtrack * const track, Double_t b, Int_t charge, Double_t center[2]); + + protected: + void Copy(TObject &ref) const; + + private: + + AliKFParticle *CreateMotherParticle(const AliVTrack* const pdaughter, const AliVTrack* const ndaughter, Int_t pspec, Int_t nspec); + + private: + AliESDv0 *fV0; // current V0 candidate + AliESDEvent *fEvent; // current event + AliKFVertex *fPrimaryVertex; // primary vertex + + ClassDef(AliESDv0KineCuts, 0); + +}; + +#endif diff --git a/PWG3/hfe/AliHFEV0cuts.cxx b/PWG3/hfe/AliHFEV0cuts.cxx index 30014269154..e219cb66f90 100644 --- a/PWG3/hfe/AliHFEV0cuts.cxx +++ b/PWG3/hfe/AliHFEV0cuts.cxx @@ -27,6 +27,7 @@ #include "AliESDv0.h" #include "AliKFParticle.h" #include "AliKFVertex.h" +#include "AliLog.h" #include "AliHFEcollection.h" @@ -37,10 +38,13 @@ ClassImp(AliHFEV0cuts) //________________________________________________________________ AliHFEV0cuts::AliHFEV0cuts(): fQA(NULL) + , fQAmc(NULL) , fMCEvent(NULL) , fInputEvent(NULL) , fPrimaryVertex(NULL) - , fIsMC(kFALSE) + , fCurrentV0id(0) + , fPdaughterPDG(0) + , fNdaughterPDG(0) { // @@ -56,16 +60,20 @@ AliHFEV0cuts::~AliHFEV0cuts() // destructor // if (fQA) delete fQA; + if (fQAmc) delete fQAmc; } //________________________________________________________________ AliHFEV0cuts::AliHFEV0cuts(const AliHFEV0cuts &ref): TObject(ref) , fQA(NULL) + , fQAmc(NULL) , fMCEvent(NULL) , fInputEvent(NULL) , fPrimaryVertex(NULL) - , fIsMC(kFALSE) + , fCurrentV0id(0) + , fPdaughterPDG(0) + , fNdaughterPDG(0) { // // Copy constructor @@ -90,6 +98,8 @@ void AliHFEV0cuts::Copy(TObject &ref) const{ if(fQA) target.fQA = dynamic_cast(fQA->Clone()); + if(fQAmc) target.fQAmc = dynamic_cast(fQAmc->Clone()); + if(target.fMCEvent) delete target.fMCEvent; target.fMCEvent = new AliMCEvent; @@ -113,6 +123,7 @@ void AliHFEV0cuts::Init(const char* name){ fQA = new AliHFEcollection("fQA", name); + fQAmc = new AliHFEcollection("fQAmc", name); // common for all V0s fQA->CreateTH2Fvector1(2, "h_all_AP", "armenteros plot for all V0 candidates", 200, -1, 1, 200, 0, 0.25); @@ -120,31 +131,28 @@ void AliHFEV0cuts::Init(const char* name){ // gammas fQA->CreateTH1Fvector1(2, "h_cut_Gamma_CosPoint", "Gamma Cosine pointing angle; cos point. angle; counts", 100, 0, 0.1); fQA->CreateTH1Fvector1(2, "h_cut_Gamma_DCA", "DCA between the gamma daughters; dca (cm); counts", 100, 0, 2); + fQA->CreateTH1Fvector1(2, "h_cut_Gamma_VtxR_old", "*old* Radius of the gamma conversion vertex; r (cm); counts", 1000, 0, 100); fQA->CreateTH1Fvector1(2, "h_cut_Gamma_VtxR", "Radius of the gamma conversion vertex; r (cm); counts", 1000, 0, 100); fQA->CreateTH1Fvector1(2, "h_cut_Gamma_OA", "opening angle of the gamma products; opening angle (rad); counts", 100, 0, 1); fQA->CreateTH1Fvector1(2, "h_cut_Gamma_PP", "gamma psi pair angle; psi pairangle (rad); counts", 100, 0, 2); - fQA->CreateTH1Fvector1(2, "h_cut_Gamma_Chi2", "gamma Chi2/NDF; Chi2/NDF; counts", 100, 0, 25); - fQA->CreateTH1Fvector1(9, "h_Gamma_Mass", "Invariant mass of gammas; mass (GeV/c^{2}); counts", 100, 0, 0.2); + fQA->CreateTH1Fvector1(2, "h_cut_Gamma_Chi2", "gamma Chi2/NDF; Chi2/NDF; counts", 100, 0, 50); + fQA->CreateTH1Fvector1(7, "h_Gamma_Mass", "Invariant mass of gammas; mass (GeV/c^{2}); counts", 100, 0, 0.2); // kaons fQA->CreateTH1Fvector1(2, "h_cut_K0_CosPoint", "K0 Cosine pointing angle; cos point. angle; counts", 100, 0, 0.1); fQA->CreateTH1Fvector1(2, "h_cut_K0_DCA", "DCA between the K0 daughters; dca (cm); counts", 100, 0, 2); fQA->CreateTH1Fvector1(2, "h_cut_K0_VtxR", "Radius of the K0 decay vertex; r (cm); counts", 1000, 0, 100); - fQA->CreateTH1Fvector1(2, "h_cut_K0_Chi2", "K0 Chi2/NDF; Chi2/NDF; counts", 100, 0, 25); - fQA->CreateTH2Fvector1(2, "h_cut_K0_AP", "Armenteros plot for K0 candidates; #alpha; q_{T} (GeV/c)", 100, -1, 1, 100, 0, 0.3); - fQA->CreateTH1Fvector1(8, "h_K0_Mass", "Invariant mass of K0; mass (GeV/c^{2}); counts", 125, 0.45, 0.55); + fQA->CreateTH1Fvector1(2, "h_cut_K0_Chi2", "K0 Chi2/NDF; Chi2/NDF; counts", 100, 0, 50); + fQA->CreateTH1Fvector1(5, "h_K0_Mass", "Invariant mass of K0; mass (GeV/c^{2}); counts", 125, 0.45, 0.55); // lambda fQA->CreateTH1Fvector1(2, "h_cut_L_CosPoint", "L Cosine pointing angle; cos point. angle; counts", 100, 0, 0.1); fQA->CreateTH1Fvector1(2, "h_cut_L_DCA", "DCA between the L daughters; dca (cm); counts", 100, 0, 2); fQA->CreateTH1Fvector1(2, "h_cut_L_VtxR", "Radius of the L decay vertex; r (cm); counts", 1000, 0, 100); - fQA->CreateTH1Fvector1(2, "h_cut_L_Chi2", "L Chi2/NDF; Chi2/NDF; counts", 100, 0, 25); - fQA->CreateTH2Fvector1(2, "h_cut_L_AP", "Armenteros plot for Lambda candidates; #alpha; q_{T} (GeV/c)", 100, -1, 1, 100, 0, 0.3); - fQA->CreateTH2Fvector1(2, "h_cut_AL_AP", "Armenteros plot for anti Lambda candidates; #alpha; q_{T} (GeV/c)", 100, -1, 1, 100, 0, 0.3); - fQA->CreateTH2Fvector1(2, "h_cut_Gamma_AP", "Armenteros plot for gamma candidates; #alpha; q_{T} (GeV/c)", 100, -1, 1, 100, 0, 0.3); - fQA->CreateTH1Fvector1(9, "h_L_Mass", "Invariant mass of L; mass (GeV/c^{2}); counts", 60, 1.1, 1.13); - fQA->CreateTH1Fvector1(9, "h_AL_Mass", "Invariant mass of anti L; mass (GeV/c^{2}); counts", 60, 1.1, 1.13); + fQA->CreateTH1Fvector1(2, "h_cut_L_Chi2", "L Chi2/NDF; Chi2/NDF; counts", 100, 0, 50); + fQA->CreateTH1Fvector1(5, "h_L_Mass", "Invariant mass of L; mass (GeV/c^{2}); counts", 60, 1.1, 1.13); + fQA->CreateTH1Fvector1(5, "h_AL_Mass", "Invariant mass of anti L; mass (GeV/c^{2}); counts", 60, 1.1, 1.13); fQA->CreateTH2F("h_L_checks", "Lambda candidate check[0] -v- check[1]; check[0]; check[1]", 5, -0.75, 1.75, 6, -0.75, 1.75 ); @@ -155,7 +163,7 @@ void AliHFEV0cuts::Init(const char* name){ fQA->CreateTH1Fvector1(8, "h_PionK0_P", "Momenta of K0 pions -cuts-; P (GeV/c) counts;", 50, 0.1, 20, 0); // L pions - fQA->CreateTH1Fvector1(9, "h_PionL_P", "Momenta of L pions -cuts-; P (GeV/c) counts;", 50, 0.1, 50, 0); + fQA->CreateTH1Fvector1(9, "h_PionL_P", "Momenta of L pions -cuts-; P (GeV/c) counts;", 50, 0.1, 20, 0); // L protons fQA->CreateTH1Fvector1(9, "h_ProtonL_P", "Momenta of L protons -cuts-; P (GeV/c) counts;", 50, 0.1, 20, 0); @@ -180,7 +188,6 @@ void AliHFEV0cuts::Init(const char* name){ // Lambda fQA->CreateTH2Fvector1(2, "h_cut_L_OAvP", "open. ang. of the L daughters versus L momentum; Lambda p (GeV/c); openeing angle pion-proton (rad)", 100, 0.1, 10, 100, 0, 3.5); fQA->CreateTH2Fvector1(2, "h_cut_L_rdp_v_mp", "relative L daughter mom -v- mother mom; L mom (GeV/c); relative daughter mom p2/p1", 100, 0.1, 10, 100, 0, 1); - fQA->CreateTH2Fvector1(2, "h_cut_L_qT_v_mp", "A-P q_{T} -v- Lambda momentum; mom (GeV/c); q_{T} GeV/c", 100, 0.1, 10, 50, 0., 0.12); // THnSparse histograms @@ -197,6 +204,132 @@ void AliHFEV0cuts::Init(const char* name){ fQA->BinLogAxis("hK0", 1); } + + // + // MC plots for checking and tuning the V0 cuts + // + + const char *v0[4] = {"G", "K", "L"}; // to keep the names short + // number of V0s left after each cut step - for signal and background - within given mass window + for(Int_t i=0; i<3; ++i){ + fQAmc->CreateTH1F(Form("h_%s_cuts_S", v0[i]), Form("h_%s_cuts_S", v0[i]), 10, -0.5, 9.5); + fQAmc->CreateTH1F(Form("h_%s_cuts_B", v0[i]), Form("h_%s_cuts_B", v0[i]), 10, -0.5, 9.5); + } + + // + // cut distributions for signal and background + // + + const Float_t pMin = 0.1; + const Float_t pMax = 10.; + const Int_t pN = 12; + + + // gamma signal + fQAmc->CreateTH2Fvector1(2, "h_cut_Gamma_CosPoint_S", "S - Gamma Cosine pointing angle; mom (GeV/c); cos point. angle", pN, pMin, pMax, 50, 0, 0.1, 0); + fQAmc->CreateTH2Fvector1(2, "h_cut_Gamma_DCA_S", "S - DCA between the gamma daughters; mom (GeV/c); dca (cm)", pN, pMin, pMax, 50, 0, 2, 0); + fQAmc->CreateTH2Fvector1(2, "h_cut_Gamma_VtxR_S", "S - Radius of the gamma conversion vertex; mom (GeV/c); r (cm)", pN, pMin, pMax, 100, 0, 100, 0); + fQAmc->CreateTH2Fvector1(2, "h_cut_Gamma_OA_S", "S - opening angle of the gamma products; mom (GeV/c); opening angle (rad)", pN, pMin, pMax, 50, 0, 0.3, 0); + fQAmc->CreateTH2Fvector1(2, "h_cut_Gamma_PP_S", "S - gamma psi pair angle; mom (GeV/c); psi pairangle (rad)", pN, pMin, pMax, 50, 0, 0.5, 0); + fQAmc->CreateTH2Fvector1(2, "h_cut_Gamma_Chi2_S", "S - gamma Chi2/NDF; mom (GeV/c); Chi2/NDF", pN, pMin, pMax, 50, 0, 100, 0); + + fQAmc->CreateTH1Fvector1(8, "h_Gamma_Mass_S", "S - Invariant mass of gammas; mass (GeV/c^{2}); counts", 100, 0, 0.2); + // gamma background + fQAmc->CreateTH2Fvector1(2, "h_cut_Gamma_CosPoint_B", "B - Gamma Cosine pointing angle; mom (GeV/c); cos point. angle", pN, pMin, pMax, 50, 0, 0.1, 0); + fQAmc->CreateTH2Fvector1(2, "h_cut_Gamma_DCA_B", "B - DCA between the gamma daughters; mom (GeV/c); dca (cm)", pN, pMin, pMax, 50, 0, 2, 0); + fQAmc->CreateTH2Fvector1(2, "h_cut_Gamma_VtxR_B", "B - Radius of the gamma conversion vertex; mom (GeV/c); r (cm)", pN, pMin, pMax, 100, 0, 100, 0); + fQAmc->CreateTH2Fvector1(2, "h_cut_Gamma_OA_B", "B - opening angle of the gamma products; mom (GeV/c); opening angle (rad)", pN, pMin, pMax, 50, 0, 0.3, 0); + fQAmc->CreateTH2Fvector1(2, "h_cut_Gamma_PP_B", "B - gamma psi pair angle; mom (GeV/c); psi pairangle (rad)", pN, pMin, pMax, 50, 0, 0.5, 0); + fQAmc->CreateTH2Fvector1(2, "h_cut_Gamma_Chi2_B", "B - gamma Chi2/NDF; mom (GeV/c); Chi2/NDF", pN, pMin, pMax, 50, 0, 100, 0); + + fQAmc->CreateTH1Fvector1(8, "h_Gamma_Mass_B", "B - Invariant mass of gammas; mass (GeV/c^{2}); counts", 100, 0, 0.2); + + // kaons signal + fQAmc->CreateTH2Fvector1(2, "h_cut_K0_CosPoint_S", "S - K0 Cosine pointing angle; mom (GeV/c); cos point. angle", pN, pMin, pMax, 50, 0, 0.1, 0); + fQAmc->CreateTH2Fvector1(2, "h_cut_K0_DCA_S", "S - DCA between the K0 daughters; mom (GeV/c); dca (cm)", pN, pMin, pMax, 50, 0, 2, 0); + fQAmc->CreateTH2Fvector1(2, "h_cut_K0_VtxR_S", "S - Radius of the K0 decay vertex; mom (GeV/c); r (cm)", pN, pMin, pMax, 50, 0, 100, 0); + fQAmc->CreateTH2Fvector1(2, "h_cut_K0_Chi2_S", "S - K0 Chi2/NDF; mom (GeV/c); Chi2/NDF", pN, pMin, pMax, 50, 0, 100, 0); + fQAmc->CreateTH2Fvector1(2, "h_cut_K0_OA_S", "S - opening angle of the K0 pions; mom (GeV/c); opening angle (rad)", pN, pMin, pMax, 100, 0, 1, 0); + + fQAmc->CreateTH1Fvector1(5, "h_K0_Mass_S", "S - Invariant mass of K0; mass (GeV/c^{2}); counts", 125, 0.45, 0.55); + // kaons background + fQAmc->CreateTH2Fvector1(2, "h_cut_K0_CosPoint_B", "B - K0 Cosine pointing angle; mom (GeV/c); cos point. angle", pN, pMin, pMax, 50, 0, 0.1, 0); + fQAmc->CreateTH2Fvector1(2, "h_cut_K0_DCA_B", "B - DCA between the K0 daughters; mom (GeV/c); dca (cm)", pN, pMin, pMax, 50, 0, 2, 0); + fQAmc->CreateTH2Fvector1(2, "h_cut_K0_VtxR_B", "B - Radius of the K0 decay vertex; mom (GeV/c); r (cm)", pN, pMin, pMax, 50, 0, 100, 0); + fQAmc->CreateTH2Fvector1(2, "h_cut_K0_Chi2_B", "B - K0 Chi2/NDF; mom (GeV/c); Chi2/NDF", pN, pMin, pMax, 50, 0, 100, 0); + fQAmc->CreateTH2Fvector1(2, "h_cut_K0_OA_B", "B - opening angle of the K0 pions; mom (GeV/c); opening angle (rad)", pN, pMin, pMax, 100, 0, 1, 0); + + fQAmc->CreateTH1Fvector1(5, "h_K0_Mass_B", "B - Invariant mass of K0; mass (GeV/c^{2}); counts", 125, 0.45, 0.55); + + // lambda signal + fQAmc->CreateTH2Fvector1(2, "h_cut_L_CosPoint_S", "S - L Cosine pointing angle; mom (GeV/c); cos point. angle", pN, pMin, pMax, 50, 0, 0.1, 0); + fQAmc->CreateTH2Fvector1(2, "h_cut_L_DCA_S", "S - DCA between the L daughters; mom (GeV/c); dca (cm)", pN, pMin, pMax, 50, 0, 2, 0); + fQAmc->CreateTH2Fvector1(2, "h_cut_L_VtxR_S", "S - Radius of the L decay vertex; mom (GeV/c); r (cm)", pN, pMin, pMax, 50, 0, 100, 0); + fQAmc->CreateTH2Fvector1(2, "h_cut_L_Chi2_S", "S - L Chi2/NDF; mom (GeV/c); Chi2/NDF", pN, pMin, pMax, 50, 0, 100, 0); + fQAmc->CreateTH2Fvector1(2, "h_cut_L_OA_S", "S - opening angle of the L p-p; mom (GeV/c); opening angle (rad)", pN, pMin, pMax, 100, 0, 1, 0); + + fQAmc->CreateTH1Fvector1(5, "h_L_Mass_S", "S - Invariant mass of L; mass (GeV/c^{2}); counts", 60, 1.1, 1.13); + fQAmc->CreateTH1Fvector1(5, "h_AL_Mass_S", "S - Invariant mass of anti L; mass (GeV/c^{2}); counts", 60, 1.1, 1.13); + // lambda background + fQAmc->CreateTH2Fvector1(2, "h_cut_L_CosPoint_B", "B - L Cosine pointing angle; mom (GeV/c); cos point. angle", pN, pMin, pMax, 50, 0, 0.1, 0); + fQAmc->CreateTH2Fvector1(2, "h_cut_L_DCA_B", "B - DCA between the L daughters; mom (GeV/c); dca (cm)", pN, pMin, pMax, 50, 0, 2, 0); + fQAmc->CreateTH2Fvector1(2, "h_cut_L_VtxR_B", "B - Radius of the L decay vertex; mom (GeV/c); r (cm)", pN, pMin, pMax, 50, 0, 100, 0); + fQAmc->CreateTH2Fvector1(2, "h_cut_L_Chi2_B", "B - L Chi2/NDF; mom (GeV/c); Chi2/NDF", pN, pMin, pMax, 50, 0, 100, 0); + fQAmc->CreateTH2Fvector1(2, "h_cut_L_OA_B", "B - opening angle of the L p-p; mom (GeV/c); opening angle (rad)", pN, pMin, pMax, 100, 0, 1, 0); + + fQAmc->CreateTH2Fvector1(2, "h_cut_L_rdp_v_mp_S", "S - relative L daughter mom -v- mother mom; L mom (GeV/c); relative daughter mom p2/p1", 100, 0.1, 10, 100, 0, 1); + fQAmc->CreateTH2Fvector1(2, "h_cut_L_rdp_v_mp_B", "B - relative L daughter mom -v- mother mom; L mom (GeV/c); relative daughter mom p2/p1", 100, 0.1, 10, 100, 0, 1); + fQAmc->CreateTH1Fvector1(5, "h_LAL_Mass_B", "B - Invariant mass of anti L; mass (GeV/c^{2}); counts", 60, 1.1, 1.13); + + + // MC tagged daughter track momentum distribution after each cut step +// fQAmc->CreateTH1Fvector1(10, "h_electron_p_S", "h_electron_p_S", 20, 0.1, 20, 0); +// fQAmc->CreateTH1Fvector1(10, "h_K0pion_p_S", "h_K0pion_p_S", 20, 0.1, 20, 0); +// fQAmc->CreateTH1Fvector1(10, "h_Lpion_p_S", "h_Lpion_p_S", 20, 0.1, 20, 0); +// fQAmc->CreateTH1Fvector1(10, "h_proton_p_S", "h_proton_p_S", 20, 0.1, 20, 0); + + // V0 momnetum distribution of MC tagged signal and backglound after all cuts + fQAmc->CreateTH1F("h_gamma_p_S", "true gammas after all cuts", 20, 0.1, 10, 0); + fQAmc->CreateTH1F("h_gamma_p_B", "true gamma BG after all cuts", 20, 0.1, 10, 0); + fQAmc->CreateTH1F("h_K0_p_S", "true K0s after all cuts", 20, 0.1, 10, 0); + fQAmc->CreateTH1F("h_K0_p_B", "true K0 BG after all cuts", 20, 0.1, 10, 0); + fQAmc->CreateTH1F("h_lambda_p_S", "MC true lambdas after all cuts", 20, 0.1, 10, 0); + fQAmc->CreateTH1F("h_lambda_p_B", "MC true lambda BG after all cuts", 20, 0.1, 10, 0); + fQAmc->CreateTH1F("h_alambda_p_S", "MC true anti-lambdas after all cuts", 20, 0.1, 10, 0); + fQAmc->CreateTH1F("h_alambda_p_B", "MC true anti-lambda BG after all cuts", 20, 0.1, 10, 0); + + // invariant mass ditributions for the V0 for different hypoteses (gamma, K0, L, AL) + fQAmc->CreateTH1F("h_Mass_gamma_as_K0","h_Mass_gamma_as_K0", 200, 0, 2); + fQAmc->CreateTH1F("h_Mass_gamma_as_L","h_Mass_gamma_as_L", 200, 0, 2); + fQAmc->CreateTH1F("h_Mass_K0_as_G", "h_Mass_K0_as_gamma", 200, 0, 2); + fQAmc->CreateTH1F("h_Mass_K0_as_L", "h_Mass_K0_as_Lambda", 200, 0, 2); + fQAmc->CreateTH1F("h_Mass_L_as_G", "h_Mass_L_as_gamma", 200, 0, 2); + fQAmc->CreateTH1F("h_Mass_L_as_K0", "h_Mass_L_as_K0", 200, 0, 2); + + // Invariant mass distribution of MC tagged signal for diffrent momenta + fQAmc->CreateTH2F("h_gamma_MvP_S", "mc tagged gammas - signal; p (GeV/c); m (GeV/c^{2})", 12, 0.1, 20, 100, 0., 0.1, 0); + fQAmc->CreateTH2F("h_K0_MvP_S", "mc tagged K0s - signal; p (GeV/c); m (GeV/c^{2})", 12, 0.1, 20, 100, 0.45, 0.55, 0); + fQAmc->CreateTH2F("h_lambda_MvP_S", "mc tagged Lambdas - signal; p (GeV/c); m (GeV/c^{2})", 12, 0.1, 20, 100, 1.08, 1.14, 0); + + // electrons + fQAmc->CreateTH1Fvector1(8, "h_Electron_P_S", "MC-S momenta of conversion electrons -cuts-; P (GeV/c); counts", 20, 0.1, 20, 0); + fQAmc->CreateTH1Fvector1(8, "h_Electron_P_B", "MC-B momenta of conversion electrons -cuts-; P (GeV/c); counts", 20, 0.1, 20, 0); + + // K0 pions + fQAmc->CreateTH1Fvector1(7, "h_PionK0_P_S", "MC-S momenta of K0 pions -cuts-; P (GeV/c) counts;", 20, 0.1, 20, 0); + fQAmc->CreateTH1Fvector1(7, "h_PionK0_P_B", "MC-B momenta of K0 pions -cuts-; P (GeV/c) counts;", 20, 0.1, 20, 0); + + // L pions + fQAmc->CreateTH1Fvector1(8, "h_PionL_P_S", "MC-S momenta of L pions -cuts-; P (GeV/c) counts;", 20, 0.1, 50, 0); + fQAmc->CreateTH1Fvector1(8, "h_PionL_P_B", "MC-B momenta of L pions -cuts-; P (GeV/c) counts;", 20, 0.1, 50, 0); + + // L protons + fQAmc->CreateTH1Fvector1(8, "h_ProtonL_P_S", "MC-S momenta of L protons -cuts-; P (GeV/c) counts;", 20, 0.1, 20, 0); + fQAmc->CreateTH1Fvector1(8, "h_ProtonL_P_B", "MC-B momenta of L protons -cuts-; P (GeV/c) counts;", 20, 0.1, 20, 0); + + + + // cut efficiencies } //________________________________________________________________ Bool_t AliHFEV0cuts::TrackCutsCommon(AliESDtrack* track){ @@ -205,6 +338,7 @@ Bool_t AliHFEV0cuts::TrackCutsCommon(AliESDtrack* track){ // if(!track) return kFALSE; + // status word ULong_t status = track->GetStatus(); @@ -212,7 +346,7 @@ Bool_t AliHFEV0cuts::TrackCutsCommon(AliESDtrack* track){ // No. of TPC clusters fQA->Fill("h_ST_NclsTPC", track->GetTPCNcls()); - if(track->GetTPCNcls() < 80) return kFALSE; + if(track->GetTPCNcls() < 80) return kFALSE; // // TPC refit if((status & AliESDtrack::kTPCrefit)){ @@ -227,7 +361,7 @@ Bool_t AliHFEV0cuts::TrackCutsCommon(AliESDtrack* track){ Int_t nTPCclusters = track->GetTPCclusters(0); Float_t chi2perTPCcluster = track->GetTPCchi2()/Float_t(nTPCclusters); fQA->Fill("h_ST_chi2TPCcls", chi2perTPCcluster); - if(chi2perTPCcluster > 3.5) return kFALSE; + if(chi2perTPCcluster > 3.5) return kFALSE; // 4.0 // TPC cluster ratio Float_t cRatioTPC = track->GetTPCNclsF() > 0. ? static_cast(track->GetTPCNcls())/static_cast (track->GetTPCNclsF()) : 1.; @@ -240,7 +374,7 @@ Bool_t AliHFEV0cuts::TrackCutsCommon(AliESDtrack* track){ // pt fQA->Fill("h_ST_pt",track->Pt()); - if(track->Pt() < 0.1 || track->Pt() > 100) return kFALSE; + if(track->Pt() < 0.1 || track->Pt() > 100) return kFALSE; // // eta fQA->Fill("h_ST_eta", track->Eta()); @@ -253,7 +387,7 @@ Bool_t AliHFEV0cuts::V0CutsCommon(AliESDv0 *v0){ // // V0 cuts common to all V0s // - + AliESDtrack* dN, *dP; dP = dynamic_cast(fInputEvent->GetTrack(v0->GetPindex())); @@ -276,8 +410,16 @@ Bool_t AliHFEV0cuts::GammaCuts(AliESDv0 *v0){ if(!v0) return kFALSE; + if(fMCEvent){ + if(1 == fCurrentV0id){ + fQAmc->Fill("h_Mass_gamma_as_K0", v0->GetEffMass(2, 2)); + fQAmc->Fill("h_Mass_gamma_as_L", v0->GetEffMass(2, 4)); + fQAmc->Fill("h_Mass_gamma_as_L", v0->GetEffMass(4, 2)); + } + } + // loose cuts first - if(LooseRejectK0(v0) || LooseRejectLambda(v0)) return kFALSE; + //if(LooseRejectK0(v0) || LooseRejectLambda(v0)) return kFALSE; AliVTrack* daughter[2]; Int_t pIndex = 0, nIndex = 0; @@ -297,7 +439,7 @@ Bool_t AliHFEV0cuts::GammaCuts(AliESDv0 *v0){ if(!kfMother) return kFALSE; // production vertex is set in the 'CreateMotherParticle' function - kfMother->SetMassConstraint(0, 0.001); + //kfMother->SetMassConstraint(0, 0.001); AliESDtrack* d[2]; d[0] = dynamic_cast(fInputEvent->GetTrack(pIndex)); @@ -307,22 +449,15 @@ Bool_t AliHFEV0cuts::GammaCuts(AliESDv0 *v0){ Float_t iP = v0->P(); Float_t p[2] = {d[0]->GetP(), d[1]->GetP()}; - // Armenteros - Float_t ap[2]; - Armenteros(v0, ap); - // Cut values - const Double_t cutCosPoint[2] = {0., 0.03}; // ORG [0., 0.03] + const Double_t cutChi2NDF = 40.; // ORG [7.] + const Double_t cutCosPoint[2] = {0., 0.02}; // ORG [0., 0.03] const Double_t cutDCA[2] = {0., 0.25}; // ORG [0., 0.25] - const Double_t cutProdVtxR[2] = {6., 50.}; // ORG [6., 9999] - const Double_t cutOAngle[2] = {0, 0.1}; // ORG [0., 0.1] + const Double_t cutProdVtxR[2] = {8., 90.}; // ORG [6., 9999] const Double_t cutPsiPair[2] = {0., 0.05}; // ORG [0. 0.05] + const Double_t cutOAngle[2] = {0, 0.1}; // ORG [0., 0.1] + // mass cut const Double_t cutMass = 0.05; // ORG [0.05] - const Double_t cutChi2NDF = 7.; // ORG [7.] - // armenteros cuts - const Double_t cutAlpha[2] = {0.35, 0.45}; // [0.35, 0.45] - const Double_t cutQT = 0.015; - // Values // cos pointing angle @@ -337,6 +472,13 @@ Bool_t AliHFEV0cuts::GammaCuts(AliESDv0 *v0){ v0->GetXYZ(x,y,z); Double_t r = TMath::Sqrt(x*x + y*y); + Double_t xy[2]; + Double_t r2 = -1.; + if ( GetConvPosXY(d[0], d[1], xy) ){ + r2 = TMath::Sqrt(xy[0]*xy[0] + xy[1]*xy[1]); + } + + // Opening angle Double_t oAngle = OpenAngle(v0); @@ -352,90 +494,244 @@ Bool_t AliHFEV0cuts::GammaCuts(AliESDv0 *v0){ // Apply the cuts, produce QA plots (with mass cut) // fQA->Fill("h_Gamma_Mass", 0, iMass); + + // MC + if(fMCEvent){ + if(1 == fCurrentV0id){ + fQAmc->Fill("h_Gamma_Mass_S", 0, iMass); + fQAmc->Fill("h_gamma_MvP_S", iP, iMass); + } + else if(-2 != fCurrentV0id) fQAmc->Fill("h_Gamma_Mass_B", 0, iMass); + } + // cut distributions if(iMass < cutMass){ - fQA->Fill("h_all_AP", 0, ap[0], ap[1]); fQA->Fill("h_Electron_P", 0, p[0]); fQA->Fill("h_Electron_P", 0, p[1]); fQA->Fill("h_cut_Gamma_CosPoint", 0, cosPoint); - fQA->Fill("h_cut_Gamma_CosPoint", 1, cosPoint); fQA->Fill("h_cut_Gamma_DCA", 0, dca); - fQA->Fill("h_cut_Gamma_VtxR", 0, r); + fQA->Fill("h_cut_Gamma_VtxR_old", 0, r); + fQA->Fill("h_cut_Gamma_VtxR", 0, r2); fQA->Fill("h_cut_Gamma_OA", 0, oAngle); fQA->Fill("h_cut_Gamma_PP", 0, psiPair); fQA->Fill("h_cut_Gamma_Chi2", 0, chi2ndf); + fQA->Fill("h_cut_Gamma_Chi2", 1, chi2ndf, iP); fQA->Fill("h_cut_Gamma_OAvP", 0, iP, oAngle); - fQA->Fill("h_cut_Gamma_AP", 0, ap[0], ap[1]); - } + + if(fMCEvent){ + // MC signal + if(1 == fCurrentV0id){ + fQAmc->Fill("h_cut_Gamma_CosPoint_S", 0, iP, cosPoint); + fQAmc->Fill("h_cut_Gamma_DCA_S", 0, iP, dca); + fQAmc->Fill("h_cut_Gamma_VtxR_S", 0, iP, r2); + fQAmc->Fill("h_cut_Gamma_OA_S", 0, iP, oAngle); + fQAmc->Fill("h_cut_Gamma_PP_S", 0, iP, psiPair); + fQAmc->Fill("h_cut_Gamma_Chi2_S", 0, iP, chi2ndf); + fQAmc->Fill("h_cut_Gamma_Chi2_S", 1, iP, chi2ndf); + fQAmc->Fill("h_Electron_P_S", 0, p[0]); + fQAmc->Fill("h_Electron_P_S", 0, p[1]); + } + // MC background + else if(-2 != fCurrentV0id){ + fQAmc->Fill("h_cut_Gamma_CosPoint_B", 0, iP, cosPoint); + fQAmc->Fill("h_cut_Gamma_DCA_B", 0, iP, dca); + fQAmc->Fill("h_cut_Gamma_VtxR_B", 0, iP, r2); + fQAmc->Fill("h_cut_Gamma_OA_B", 0, iP, oAngle); + fQAmc->Fill("h_cut_Gamma_PP_B", 0, iP, psiPair); + fQAmc->Fill("h_cut_Gamma_Chi2_B", 0, iP, chi2ndf); + fQAmc->Fill("h_cut_Gamma_Chi2_B", 1, iP, chi2ndf); + fQAmc->Fill("h_Electron_P_B", 0, p[0]); + fQAmc->Fill("h_Electron_P_B", 0, p[1]); + } + } + } - if(cosPoint < cutCosPoint[0] || cosPoint > cutCosPoint[1]) return kFALSE; + + // + // Chi2/NDF cut + // + if(chi2ndf > cutChi2NDF) return kFALSE; fQA->Fill("h_Gamma_Mass", 1, iMass); if(iMass < cutMass){ + fQA->Fill("h_cut_Gamma_CosPoint", 1, cosPoint); fQA->Fill("h_Electron_P", 1, p[0]); fQA->Fill("h_Electron_P", 1, p[1]); - fQA->Fill("h_cut_Gamma_DCA", 1, dca); } - - if(dca < cutDCA[0] || dca > cutDCA[1]) return kFALSE; + if(fMCEvent){ + if(1 == fCurrentV0id) fQAmc->Fill("h_Gamma_Mass_S", 1, iMass); + else if(-2 != fCurrentV0id) fQAmc->Fill("h_Gamma_Mass_B", 1, iMass); + if(iMass < cutMass){ + if(1 == fCurrentV0id){ + fQAmc->Fill("h_cut_Gamma_CosPoint_S", 1, iP, cosPoint); + fQAmc->Fill("h_Electron_P_S", 1, p[0]); + fQAmc->Fill("h_Electron_P_S", 1, p[1]); + } + else if(-2 != fCurrentV0id){ + fQAmc->Fill("h_cut_Gamma_CosPoint_B", 1, iP, cosPoint); + fQAmc->Fill("h_Electron_P_B", 1, p[0]); + fQAmc->Fill("h_Electron_P_B", 1, p[1]); + } + } + } + + // + // Cos point cut + // + if(cosPoint < cutCosPoint[0] || cosPoint > cutCosPoint[1]) return kFALSE; fQA->Fill("h_Gamma_Mass", 2, iMass); if(iMass < cutMass){ fQA->Fill("h_Electron_P", 2, p[0]); fQA->Fill("h_Electron_P", 2, p[1]); - fQA->Fill("h_cut_Gamma_VtxR", 1, r); + fQA->Fill("h_cut_Gamma_DCA", 1, dca); } - - if(r < cutProdVtxR[0] || r > cutProdVtxR[1]) return kFALSE; + if(fMCEvent){ + if(1 == fCurrentV0id) fQAmc->Fill("h_Gamma_Mass_S", 2, iMass); + else if(-2 != fCurrentV0id) fQAmc->Fill("h_Gamma_Mass_B", 2, iMass); + if(iMass < cutMass){ + if(1 == fCurrentV0id){ + fQAmc->Fill("h_cut_Gamma_DCA_S", 1, iP, dca); + fQAmc->Fill("h_Electron_P_S", 2, p[0]); + fQAmc->Fill("h_Electron_P_S", 2, p[1]); + + } + else if(-2 != fCurrentV0id){ + fQAmc->Fill("h_cut_Gamma_DCA_B", 1, iP, dca); + fQAmc->Fill("h_Electron_P_B", 2, p[0]); + fQAmc->Fill("h_Electron_P_B", 2, p[1]); + + } + } + } + + // + // DCA cut + // + if(dca < cutDCA[0] || dca > cutDCA[1]) return kFALSE; fQA->Fill("h_Gamma_Mass", 3, iMass); if(iMass < cutMass){ fQA->Fill("h_Electron_P", 3, p[0]); fQA->Fill("h_Electron_P", 3, p[1]); - fQA->Fill("h_cut_Gamma_OA", 1, oAngle); + fQA->Fill("h_cut_Gamma_VtxR_old", 1, r); + fQA->Fill("h_cut_Gamma_VtxR", 1, r2); + } + if(fMCEvent){ + if(1 == fCurrentV0id) fQAmc->Fill("h_Gamma_Mass_S", 3, iMass); + else if(-2 != fCurrentV0id) fQAmc->Fill("h_Gamma_Mass_B", 3, iMass); + if(iMass < cutMass){ + if(1 == fCurrentV0id){ + fQAmc->Fill("h_cut_Gamma_VtxR_S", 1, iP, r2); + fQAmc->Fill("h_Electron_P_S", 3, p[0]); + fQAmc->Fill("h_Electron_P_S", 3, p[1]); + + } + else if(-2 != fCurrentV0id){ + fQAmc->Fill("h_cut_Gamma_VtxR_B", 1, iP, r2); + fQAmc->Fill("h_Electron_P_B", 3, p[0]); + fQAmc->Fill("h_Electron_P_B", 3, p[1]); + } + } } - if(oAngle < cutOAngle[0] || oAngle > cutOAngle[1]) return kFALSE; + // + // Vertex radius cut + // + if(r < cutProdVtxR[0] || r > cutProdVtxR[1]) return kFALSE; fQA->Fill("h_Gamma_Mass", 4, iMass); if(iMass < cutMass){ + fQA->Fill("h_cut_Gamma_PP", 1, psiPair); fQA->Fill("h_Electron_P", 4, p[0]); fQA->Fill("h_Electron_P", 4, p[1]); - fQA->Fill("h_cut_Gamma_PP", 1, psiPair); + } + if(fMCEvent){ + if(1 == fCurrentV0id) fQAmc->Fill("h_Gamma_Mass_S", 4, iMass); + else if(-2 != fCurrentV0id) fQAmc->Fill("h_Gamma_Mass_B", 4, iMass); + if(iMass < cutMass){ + if(1 == fCurrentV0id){ + fQAmc->Fill("h_cut_Gamma_PP_S", 1, iP, psiPair); + fQAmc->Fill("h_Electron_P_S", 4, p[0]); + fQAmc->Fill("h_Electron_P_S", 4, p[1]); + } + else if(-2 != fCurrentV0id){ + fQAmc->Fill("h_cut_Gamma_PP_B", 1, iP, psiPair); + fQAmc->Fill("h_Electron_P_B", 4, p[0]); + fQAmc->Fill("h_Electron_P_B", 4, p[1]); + } + } } + + // + // PsiPair cut + // if(psiPair < cutPsiPair[0] || psiPair > cutPsiPair[1]) return kFALSE; fQA->Fill("h_Gamma_Mass", 5, iMass); if(iMass < cutMass){ + fQA->Fill("h_cut_Gamma_OA", 1, oAngle); + fQA->Fill("h_cut_Gamma_OAvP", 1, iP, oAngle); fQA->Fill("h_Electron_P", 5, p[0]); fQA->Fill("h_Electron_P", 5, p[1]); - fQA->Fill("h_cut_Gamma_Chi2", 1, chi2ndf); + } + if(fMCEvent){ + if(1 == fCurrentV0id) fQAmc->Fill("h_Gamma_Mass_S", 5, iMass); + else if(-2 != fCurrentV0id)fQAmc->Fill("h_Gamma_Mass_B", 5, iMass); + + if(iMass < cutMass){ + if(1 == fCurrentV0id){ + fQAmc->Fill("h_cut_Gamma_OA_S", 1, iP, oAngle); + fQAmc->Fill("h_Electron_P_S", 5, p[0]); + fQAmc->Fill("h_Electron_P_S", 5, p[1]); + } + else if(-2 != fCurrentV0id){ + fQAmc->Fill("h_cut_Gamma_OA_B", 1, iP, oAngle); + fQAmc->Fill("h_Electron_P_B", 5, p[0]); + fQAmc->Fill("h_Electron_P_B", 5, p[1]); + } + } } - if(chi2ndf > cutChi2NDF) return kFALSE; + // + // Opening angle cut (obsolete?) + // + if(oAngle < cutOAngle[0] || oAngle > cutOAngle[1]) return kFALSE; fQA->Fill("h_Gamma_Mass", 6, iMass); if(iMass < cutMass){ fQA->Fill("h_Electron_P", 6, p[0]); fQA->Fill("h_Electron_P", 6, p[1]); - fQA->Fill("h_cut_Gamma_OAvP", 1, iP, oAngle); - fQA->Fill("h_all_AP", 1, ap[0], ap[1]); - fQA->Fill("h_cut_Gamma_AP", 1, ap[0], ap[1]); } - - if(TMath::Abs(ap[0]) > cutAlpha[0] && TMath::Abs(ap[0]) < cutAlpha[1]) return kFALSE; - fQA->Fill("h_Gamma_Mass", 7, iMass); - if(iMass < cutMass){ - fQA->Fill("h_Electron_P", 7, p[0]); - fQA->Fill("h_Electron_P", 7, p[1]); - } - - if(ap[1] > cutQT) return kFALSE; - fQA->Fill("h_Gamma_Mass", 8, iMass); - if(iMass < cutMass){ - fQA->Fill("h_Electron_P", 8, p[0]); - fQA->Fill("h_Electron_P", 8, p[1]); + if(fMCEvent){ + if(1 == fCurrentV0id) fQAmc->Fill("h_Gamma_Mass_S", 6, iMass); + else if(-2 != fCurrentV0id) fQAmc->Fill("h_Gamma_Mass_B", 6, iMass); + if(iMass < cutMass){ + if(1 == fCurrentV0id){ + fQAmc->Fill("h_Electron_P_S", 6, p[0]); + fQAmc->Fill("h_Electron_P_S", 6, p[1]); + } + else if(-2 != fCurrentV0id){ + fQAmc->Fill("h_Electron_P_B", 6, p[0]); + fQAmc->Fill("h_Electron_P_B", 6, p[1]); + } + } } if(iMass > cutMass) return kFALSE; // all cuts passed - + + + // some MC stuff + //printf("**D: gamma V0id: %i, P: %i, N: %i \n", fCurrentV0id, fPdaughterPDG, fNdaughterPDG); + if(1 == fCurrentV0id){ + fQAmc->Fill("h_gamma_p_S", iP); + fQAmc->Fill("h_Electron_P_S", 7, p[0]); + fQAmc->Fill("h_Electron_P_S", 7, p[1]); + } + else if (-2 != fCurrentV0id){ + fQAmc->Fill("h_gamma_p_B", iP); + fQAmc->Fill("h_Electron_P_B", 7, p[0]); + fQAmc->Fill("h_Electron_P_B", 7, p[1]); + } + + return kTRUE; } //________________________________________________________________ @@ -446,7 +742,15 @@ Bool_t AliHFEV0cuts::K0Cuts(AliESDv0 *v0){ if(!v0) return kFALSE; - const Double_t cK0mass=TDatabasePDG::Instance()->GetParticle(kK0Short)->Mass(); // PDG K0s mass + if(fMCEvent){ + if(2 == fCurrentV0id){ + fQAmc->Fill("h_Mass_K0_as_G", v0->GetEffMass(0, 0)); + fQAmc->Fill("h_Mass_K0_as_L", v0->GetEffMass(2, 4)); + fQAmc->Fill("h_Mass_K0_as_L", v0->GetEffMass(4, 2)); + } + } + + //const Double_t cK0mass=TDatabasePDG::Instance()->GetParticle(kK0Short)->Mass(); // PDG K0s mass AliVTrack* daughter[2]; Int_t pIndex = 0, nIndex = 0; if(CheckSigns(v0)){ @@ -465,7 +769,7 @@ Bool_t AliHFEV0cuts::K0Cuts(AliESDv0 *v0){ AliKFParticle *kfMother = CreateMotherParticle(daughter[0], daughter[1], TMath::Abs(kPiPlus), TMath::Abs(kPiPlus)); if(!kfMother) return kFALSE; // production vertex is set in the 'CreateMotherParticle' function - kfMother->SetMassConstraint(cK0mass, 0.); + //kfMother->SetMassConstraint(cK0mass, 0.); AliESDtrack* d[2]; d[0] = dynamic_cast(fInputEvent->GetTrack(pIndex)); @@ -478,18 +782,14 @@ Bool_t AliHFEV0cuts::K0Cuts(AliESDv0 *v0){ Double_t phi = v0->Phi(); Double_t pt = v0->Pt(); Double_t data[4] = {0., 0., 0., 0.}; + // Cut values - const Double_t cutCosPoint[2] = {0., 0.03}; // ORG [0., 0.03] + const Double_t cutChi2NDF = 40.; // ORG [7.] + const Double_t cutCosPoint[2] = {0., 0.02}; // ORG [0., 0.03] const Double_t cutDCA[2] = {0., 0.2}; // ORG [0., 0.1] const Double_t cutProdVtxR[2] = {2.0, 30.}; // ORG [0., 8.1] const Double_t cutMass[2] = {0.49, 0.51}; // ORG [0.485, 0.51] - const Double_t cutChi2NDF = 5.; // ORG [7.] - const Double_t cutOAngleP = (1.0/(iP + 0.3) - 0.1); // momentum dependent min. OAngle ~ 1/x - // cundidate cuts - // armenteros plot - const Double_t cutQT = 0.1075; - // elipse cut - see bellow - + //const Double_t cutOAngleP = (1.0/(iP + 0.3) - 0.1); // momentum dependent min. OAngle ~ 1/x // Values // cos pointing angle @@ -513,84 +813,164 @@ Bool_t AliHFEV0cuts::K0Cuts(AliESDv0 *v0){ // Opening angle Double_t oAngle = OpenAngle(v0); - // Armenteros - Float_t ap[2]; - Armenteros(v0, ap); - const Double_t cutAP = 0.22 * TMath::Sqrt( TMath::Abs( (1-ap[0]*ap[0]/(0.92*0.92)) ) ); - - // // Apply the cuts, produce QA plots (with mass cut) // fQA->Fill("h_K0_Mass", 0, iMass); + // MC + if(fMCEvent){ + if(2 == fCurrentV0id){ + fQAmc->Fill("h_K0_Mass_S", 0, iMass); + fQAmc->Fill("h_K0_MvP_S", iP, iMass); + } + else if(-2 != fCurrentV0id) fQAmc->Fill("h_K0_Mass_B", 0, iMass); + } + if(iMass > cutMass[0] && iMass < cutMass[1]){ - fQA->Fill("h_all_AP", 0, ap[0], ap[1]); fQA->Fill("h_PionK0_P", 0, p[0]); fQA->Fill("h_PionK0_P", 0, p[1]); fQA->Fill("h_cut_K0_CosPoint", 0, cosPoint); - fQA->Fill("h_cut_K0_CosPoint", 1, cosPoint); fQA->Fill("h_cut_K0_DCA", 0, dca); fQA->Fill("h_cut_K0_VtxR", 0, r); fQA->Fill("h_cut_K0_Chi2", 0, chi2ndf); - fQA->Fill("h_cut_K0_OAvP", 0, iP, oAngle); - fQA->Fill("h_cut_K0_AP", 0, ap[0], ap[1]); + fQA->Fill("h_cut_K0_Chi2", 1, chi2ndf); + } + + // MC + if(fMCEvent){ + if(iMass > cutMass[0] && iMass < cutMass[1]){ + if(2 == fCurrentV0id){ + fQAmc->Fill("h_cut_K0_CosPoint_S", 0, iP, cosPoint); + fQAmc->Fill("h_cut_K0_DCA_S", 0, iP, dca); + fQAmc->Fill("h_cut_K0_VtxR_S", 0, iP, r); + fQAmc->Fill("h_cut_K0_Chi2_S", 0, iP, chi2ndf); + fQAmc->Fill("h_cut_K0_Chi2_S", 1, iP, chi2ndf); + fQAmc->Fill("h_cut_K0_OA_S", 0, iP, oAngle); + fQAmc->Fill("h_PionK0_P_S", 0, p[0]); + fQAmc->Fill("h_PionK0_P_S", 0, p[1]); + } + else if(-2 != fCurrentV0id){ + fQAmc->Fill("h_cut_K0_CosPoint_B", 0, iP, cosPoint); + fQAmc->Fill("h_cut_K0_DCA_B", 0, iP, dca); + fQAmc->Fill("h_cut_K0_VtxR_B", 0, iP, r); + fQAmc->Fill("h_cut_K0_Chi2_B", 0, iP, chi2ndf); + fQAmc->Fill("h_cut_K0_Chi2_B", 1, iP, chi2ndf); + fQAmc->Fill("h_cut_K0_OA_B", 0, iP, oAngle); + fQAmc->Fill("h_PionK0_P_B", 0, p[0]); + fQAmc->Fill("h_PionK0_P_B", 0, p[1]); + } + } } - if(cosPoint < cutCosPoint[0] || cosPoint > cutCosPoint[1]) return kFALSE; + // + // Chi2/NDF cut + // + if(chi2ndf > cutChi2NDF) return kFALSE; fQA->Fill("h_K0_Mass", 1, iMass); if(iMass > cutMass[0] && iMass < cutMass[1]){ + fQA->Fill("h_cut_K0_CosPoint", 1, cosPoint); fQA->Fill("h_PionK0_P", 1, p[0]); fQA->Fill("h_PionK0_P", 1, p[1]); - fQA->Fill("h_cut_K0_DCA", 1, dca); + } + if(fMCEvent){ + if(2 == fCurrentV0id) fQAmc->Fill("h_K0_Mass_S", 1, iMass); + else if(-2 != fCurrentV0id) fQAmc->Fill("h_K0_Mass_B", 1, iMass); + if(iMass > cutMass[0] && iMass < cutMass[1]){ + if(2 == fCurrentV0id){ + fQAmc->Fill("h_cut_K0_CosPoint_S", 1, iP, cosPoint); + fQAmc->Fill("h_PionK0_P_S", 1, p[0]); + fQAmc->Fill("h_PionK0_P_S", 1, p[1]); + } + else if(-2 != fCurrentV0id){ + fQAmc->Fill("h_cut_K0_CosPoint_B", 1, iP, cosPoint); + fQAmc->Fill("h_PionK0_P_B", 1, p[0]); + fQAmc->Fill("h_PionK0_P_B", 1, p[1]); + } + } } - - if(dca < cutDCA[0] || dca > cutDCA[1]) return kFALSE; + + // + // Cos point cut + // + if(cosPoint < cutCosPoint[0] || cosPoint > cutCosPoint[1]) return kFALSE; fQA->Fill("h_K0_Mass", 2, iMass); if(iMass > cutMass[0] && iMass < cutMass[1]){ fQA->Fill("h_PionK0_P", 2, p[0]); fQA->Fill("h_PionK0_P", 2, p[1]); - fQA->Fill("h_cut_K0_VtxR", 1, r); + fQA->Fill("h_cut_K0_DCA", 1, dca); + } + if(fMCEvent){ + if(2 == fCurrentV0id) fQAmc->Fill("h_K0_Mass_S", 2, iMass); + else if(-2 != fCurrentV0id) fQAmc->Fill("h_K0_Mass_B", 2, iMass); + if(iMass > cutMass[0] && iMass < cutMass[1]){ + if(2 == fCurrentV0id){ + fQAmc->Fill("h_cut_K0_DCA_S", 1, iP, dca); + fQAmc->Fill("h_PionK0_P_S", 2, p[0]); + fQAmc->Fill("h_PionK0_P_S", 2, p[1]); + } + else if(-2 != fCurrentV0id){ + fQAmc->Fill("h_cut_K0_DCA_B", 1, iP, dca); + fQAmc->Fill("h_PionK0_P_B", 2, p[0]); + fQAmc->Fill("h_PionK0_P_B", 2, p[1]); + } + } } - - if(r < cutProdVtxR[0] || r > cutProdVtxR[1]) return kFALSE; + + // + // DCA cut + // + if(dca < cutDCA[0] || dca > cutDCA[1]) return kFALSE; fQA->Fill("h_K0_Mass", 3, iMass); if(iMass > cutMass[0] && iMass < cutMass[1]){ fQA->Fill("h_PionK0_P", 3, p[0]); fQA->Fill("h_PionK0_P", 3, p[1]); - fQA->Fill("h_cut_K0_Chi2", 1, chi2ndf); + fQA->Fill("h_cut_K0_VtxR", 1, r); + } + if(fMCEvent){ + if(2 == fCurrentV0id) fQAmc->Fill("h_K0_Mass_S", 3, iMass); + else if(-2 != fCurrentV0id) fQAmc->Fill("h_K0_Mass_B", 3, iMass); + if(iMass > cutMass[0] && iMass < cutMass[1]){ + if(2 == fCurrentV0id){ + fQAmc->Fill("h_cut_K0_VtxR_S", 1, iP, r); + fQAmc->Fill("h_PionK0_P_S", 3, p[0]); + fQAmc->Fill("h_PionK0_P_S", 3, p[1]); + } + else if(-2 != fCurrentV0id){ + fQAmc->Fill("h_cut_K0_VtxR_B", 1, iP, r); + fQAmc->Fill("h_PionK0_P_B", 3, p[0]); + fQAmc->Fill("h_PionK0_P_B", 3, p[1]); + } + } } - if(chi2ndf > cutChi2NDF) return kFALSE; + + // + // Vertex R cut + // + if(r < cutProdVtxR[0] || r > cutProdVtxR[1]) return kFALSE; fQA->Fill("h_K0_Mass", 4, iMass); if(iMass > cutMass[0] && iMass < cutMass[1]){ fQA->Fill("h_PionK0_P", 4, p[0]); fQA->Fill("h_PionK0_P", 4, p[1]); fQA->Fill("h_cut_K0_OAvP", 1, iP, oAngle); - } - - if(oAngle < cutOAngleP) return kFALSE; - fQA->Fill("h_K0_Mass", 5, iMass); - if(iMass > cutMass[0] && iMass < cutMass[1]){ - fQA->Fill("h_PionK0_P", 5, p[0]); - fQA->Fill("h_PionK0_P", 5, p[1]); - fQA->Fill("h_cut_K0_AP", 1, ap[0], ap[1]); - fQA->Fill("h_all_AP", 1, ap[0], ap[1]); } - - if(ap[1] < cutQT) return kFALSE; - fQA->Fill("h_K0_Mass", 6, iMass); - if(iMass > cutMass[0] && iMass < cutMass[1]){ - fQA->Fill("h_PionK0_P", 6, p[0]); - fQA->Fill("h_PionK0_P", 6, p[1]); - } - - if(ap[1] > cutAP) return kFALSE; - fQA->Fill("h_K0_Mass", 7, iMass); - if(iMass > cutMass[0] && iMass < cutMass[1]){ - fQA->Fill("h_PionK0_P", 7, p[0]); - fQA->Fill("h_PionK0_P", 7, p[1]); + if(fMCEvent){ + if(2 == fCurrentV0id) fQAmc->Fill("h_K0_Mass_S", 4, iMass); + else if(-2 != fCurrentV0id) fQAmc->Fill("h_K0_Mass_B", 4, iMass); + if(iMass > cutMass[0] && iMass < cutMass[1]){ + if(2 == fCurrentV0id){ + fQAmc->Fill("h_cut_K0_OA_S", 1, iP, oAngle); + fQAmc->Fill("h_PionK0_P_S", 4, p[0]); + fQAmc->Fill("h_PionK0_P_S", 4, p[1]); + } + else if(-2 != fCurrentV0id){ + fQAmc->Fill("h_cut_K0_OA_B", 1, iP, oAngle); + fQAmc->Fill("h_PionK0_P_B", 4, p[0]); + fQAmc->Fill("h_PionK0_P_B", 4, p[1]); + } + } } data[0] = iMass; @@ -605,6 +985,18 @@ Bool_t AliHFEV0cuts::K0Cuts(AliESDv0 *v0){ // all cuts passed + // some MC stuff + if(2 == fCurrentV0id){ + fQAmc->Fill("h_K0_p_S", iP); + fQAmc->Fill("h_PionK0_P_S", 5, p[0]); + fQAmc->Fill("h_PionK0_P_S", 5, p[1]); + } + else if (-2 != fCurrentV0id){ + fQAmc->Fill("h_K0_p_B", iP); + fQAmc->Fill("h_PionK0_P_B", 5, p[0]); + fQAmc->Fill("h_PionK0_P_B", 5, p[1]); + } + return kTRUE; } //________________________________________________________________ @@ -618,8 +1010,14 @@ Bool_t AliHFEV0cuts::LambdaCuts(AliESDv0 *v0, Bool_t &isLambda ){ if(!v0) return kFALSE; + if(fMCEvent){ + if(4 == fCurrentV0id){ + fQAmc->Fill("h_Mass_L_as_G", v0->GetEffMass(0, 0)); + fQAmc->Fill("h_Mass_L_as_K0", v0->GetEffMass(2, 0)); + } + } // loose cuts first - if(LooseRejectK0(v0) || LooseRejectGamma(v0)) return kFALSE; + //if(LooseRejectK0(v0) || LooseRejectGamma(v0)) return kFALSE; const Double_t cL0mass=TDatabasePDG::Instance()->GetParticle(kLambda0)->Mass(); // PDG lambda mass @@ -649,13 +1047,13 @@ Bool_t AliHFEV0cuts::LambdaCuts(AliESDv0 *v0, Bool_t &isLambda ){ if(!kfMother[0]) return kFALSE; // production vertex is set in the 'CreateMotherParticle' function - kfMother[0]->SetMassConstraint(cL0mass, 0.); + //kfMother[0]->SetMassConstraint(cL0mass, 0.); // Anti Lambda kfMother[1] = CreateMotherParticle(daughter[0], daughter[1], TMath::Abs(kPiPlus), TMath::Abs(kProton)); if(!kfMother[1]) return kFALSE; // production vertex is set in the 'CreateMotherParticle' function - kfMother[1]->SetMassConstraint(cL0mass, 0.); + //kfMother[1]->SetMassConstraint(cL0mass, 0.); Float_t dMass[2] = {TMath::Abs(mMass[0] - cL0mass), TMath::Abs(mMass[1] - cL0mass)}; @@ -694,19 +1092,15 @@ Bool_t AliHFEV0cuts::LambdaCuts(AliESDv0 *v0, Bool_t &isLambda ){ Float_t iP = v0->P(); // Cuts - const Double_t cutCosPoint[2] = {0., 0.03}; // ORG [0., 0.03] + const Double_t cutChi2NDF = 40.; // ORG [5.] + const Double_t cutCosPoint[2] = {0., 0.02}; // ORG [0., 0.03] const Double_t cutDCA[2] = {0., 0.2}; // ORG [0., 0.2] - const Double_t cutProdVtxR[2] = {2., 30.}; // ORG [0., 24.] + const Double_t cutProdVtxR[2] = {2., 40.}; // ORG [0., 24.] const Double_t cutMass[2] = {1.11, 1.12}; // ORG [1.11, 1.12] - const Double_t cutChi2NDF = 5.; // ORG [5.] // cundidate cuts // opening angle as a function of L momentum - const Double_t cutOAngleP = 0.3 - 0.2*iP; // momentum dependent min. OAngle linear cut + //const Double_t cutOAngleP = 0.3 - 0.2*iP; // momentum dependent min. OAngle linear cut // relative daughter momentum versusu mother momentum - // armenteros plot cuts - const Double_t cutQT = 0.03; - const Double_t cutAlpha = 0.7; // VERY strong - should supress the overlap with K0 - // next cut see below // compute the cut values @@ -722,12 +1116,31 @@ Bool_t AliHFEV0cuts::LambdaCuts(AliESDv0 *v0, Bool_t &isLambda ){ v0->GetXYZ(x,y,z); Double_t r = TMath::Sqrt(x*x + y*y); + // proton - pion indices Int_t ix[2] = {0, 1}; if(1 == type){ ix[0] = 1; ix[1] = 0; } - + + // proton - pion indices - based on MC truth + // for background use the reconstructed indices + Int_t ixMC[2] = {-1, -1}; // {proton, pion} + if(fMCEvent){ + if(4 == fCurrentV0id){ + ixMC[0] = 0; + ixMC[1] = 1; + } + else if(-4 == fCurrentV0id){ + ixMC[0] = 1; + ixMC[1] = 0; + } + else{ + ixMC[0] = ix[0]; + ixMC[1] = ix[1]; + } + } + // V0 chi2/ndf Double_t chi2ndf = kfMother[type]->GetChi2()/kfMother[type]->GetNDF(); @@ -740,14 +1153,6 @@ Bool_t AliHFEV0cuts::LambdaCuts(AliESDv0 *v0, Bool_t &isLambda ){ // Relative daughter momentum Double_t rP = (0 == check[0]) ? p[1]/p[0] : p[0]/p[1]; - // Armenteros - Float_t ap[2]; - Armenteros(v0, ap); - - Double_t cutAP[2]; // a bit of woodoo :-) - cutAP[0] = 1.0 - (ap[0]-0.7 * ap[0]-0.7)*1.1 - 0.87; - cutAP[1] = 1.0 - (ap[0]+0.7 * ap[0]+0.7)*1.1 - 0.87; - // // Apply the cuts, produce QA plots (with mass cut) @@ -755,85 +1160,169 @@ Bool_t AliHFEV0cuts::LambdaCuts(AliESDv0 *v0, Bool_t &isLambda ){ (type == 0) ? fQA->Fill("h_L_Mass", 0, iMass) : fQA->Fill("h_AL_Mass", 0, iMass); + + + // MC + if(fMCEvent){ + if(4 == fCurrentV0id){ + fQAmc->Fill("h_L_Mass_S", 0, iMass); + fQAmc->Fill("h_lambda_MvP_S", iP, iMass); + } + else if(-4 == fCurrentV0id){ + fQAmc->Fill("h_AL_Mass_S", 0, iMass); + fQAmc->Fill("h_lambda_MvP_S", iP, iMass); + } + else if(-2 != fCurrentV0id) fQAmc->Fill("h_LAL_Mass_B", 0, iMass); + } + + if(iMass > cutMass[0] && iMass < cutMass[1]){ - fQA->Fill("h_all_AP", 0, ap[0], ap[1]); fQA->Fill("h_ProtonL_P", 0, p[ix[0]]); fQA->Fill("h_PionL_P", 0, p[ix[1]]); fQA->Fill("h_cut_L_Chi2", 0, chi2ndf); + fQA->Fill("h_cut_L_Chi2", 1, chi2ndf); fQA->Fill("h_cut_L_CosPoint", 0, cosPoint); - fQA->Fill("h_cut_L_CosPoint", 1, cosPoint); fQA->Fill("h_cut_L_DCA", 0, dca); fQA->Fill("h_cut_L_VtxR", 0, r); fQA->Fill("h_cut_L_OAvP", 0, iP, oAngle); fQA->Fill("h_cut_L_rdp_v_mp", 0, iP, rP); - if(0 ==type) fQA->Fill("h_cut_L_AP", 0, ap[0], ap[1]); - else fQA->Fill("h_cut_AL_AP", 0, ap[0], ap[1]); - fQA->Fill("h_cut_L_qT_v_mp", 0, iP, ap[1]); } - - if(cosPoint < cutCosPoint[0] || cosPoint > cutCosPoint[1]) return kFALSE; + if(fMCEvent){ + if(iMass > cutMass[0] && iMass < cutMass[1]){ + if(4 == TMath::Abs(fCurrentV0id)){ + fQAmc->Fill("h_cut_L_Chi2_S", 0, iP, chi2ndf); + fQAmc->Fill("h_cut_L_Chi2_S", 1, iP, chi2ndf); + fQAmc->Fill("h_cut_L_CosPoint_S", 0, iP, cosPoint); + fQAmc->Fill("h_cut_L_DCA_S", 0, iP, dca); + fQAmc->Fill("h_cut_L_VtxR_S", 0, iP, r); + fQAmc->Fill("h_cut_L_OA_S", 0, iP, oAngle); + fQAmc->Fill("h_cut_L_rdp_v_mp_S", 0, iP, rP); + fQAmc->Fill("h_ProtonL_P_S", 0, p[ixMC[0]]); + fQAmc->Fill("h_PionL_P_S", 0, p[ixMC[1]]); + } + else if(-2 != fCurrentV0id){ + fQAmc->Fill("h_cut_L_Chi2_B", 0, iP, chi2ndf); + fQAmc->Fill("h_cut_L_Chi2_B", 1, iP, chi2ndf); + fQAmc->Fill("h_cut_L_CosPoint_B", 0, iP, cosPoint); + fQAmc->Fill("h_cut_L_DCA_B", 0, iP, dca); + fQAmc->Fill("h_cut_L_VtxR_B", 0, iP, r); + fQAmc->Fill("h_cut_L_OA_B", 0, iP, oAngle); + fQAmc->Fill("h_cut_L_rdp_v_mp_B", 0, iP, rP); + fQAmc->Fill("h_ProtonL_P_B", 0, p[ixMC[0]]); + fQAmc->Fill("h_PionL_P_B", 0, p[ixMC[1]]); + } + } + } + // + // Chi2/NDF cut + // + if(chi2ndf > cutChi2NDF) return kFALSE; (type == 0) ? fQA->Fill("h_L_Mass", 1, iMass) : fQA->Fill("h_AL_Mass", 1, iMass); if(iMass > cutMass[0] && iMass < cutMass[1]){ + fQA->Fill("h_cut_L_CosPoint", 1, cosPoint); fQA->Fill("h_ProtonL_P", 1, p[ix[0]]); fQA->Fill("h_PionL_P", 1, p[ix[1]]); - fQA->Fill("h_cut_L_DCA", 1, dca); } - - if(dca < cutDCA[0] || dca > cutDCA[1]) return kFALSE; + if(fMCEvent){ + if(4 == fCurrentV0id) fQAmc->Fill("h_L_Mass_S", 1, iMass); + else if(-4 == fCurrentV0id) fQAmc->Fill("h_AL_Mass_S", 1, iMass); + else if(-2 != fCurrentV0id) fQAmc->Fill("h_LAL_Mass_B", 1, iMass); + if(iMass > cutMass[0] && iMass < cutMass[1]){ + if(4 == TMath::Abs(fCurrentV0id)){ + fQAmc->Fill("h_cut_L_CosPoint_S", 1, iP, cosPoint); + fQAmc->Fill("h_ProtonL_P_S", 1, p[ixMC[0]]); + fQAmc->Fill("h_PionL_P_S", 1, p[ixMC[1]]); + } + else if(-2 != fCurrentV0id){ + fQAmc->Fill("h_cut_L_CosPoint_B", 1, iP, cosPoint); + fQAmc->Fill("h_ProtonL_P_B", 1, p[ixMC[0]]); + fQAmc->Fill("h_PionL_P_B", 1, p[ixMC[1]]); + } + } + } + + // + // Cos point cut + // + if(cosPoint < cutCosPoint[0] || cosPoint > cutCosPoint[1]) return kFALSE; (type == 0) ? fQA->Fill("h_L_Mass", 2, iMass) : fQA->Fill("h_AL_Mass", 2, iMass); if(iMass > cutMass[0] && iMass < cutMass[1]){ fQA->Fill("h_ProtonL_P", 2, p[ix[0]]); fQA->Fill("h_PionL_P", 2, p[ix[1]]); - fQA->Fill("h_cut_L_VtxR", 1, r); + fQA->Fill("h_cut_L_DCA", 1, dca); + } + if(fMCEvent){ + if(4 == fCurrentV0id) fQAmc->Fill("h_L_Mass_S", 2, iMass); + else if(-4 == fCurrentV0id) fQAmc->Fill("h_AL_Mass_S", 2, iMass); + else if(-2 != fCurrentV0id) fQAmc->Fill("h_LAL_Mass_B", 2, iMass); + if(iMass > cutMass[0] && iMass < cutMass[1]){ + if(4 == TMath::Abs(fCurrentV0id)){ + fQAmc->Fill("h_cut_L_DCA_S", 1, iP, dca); + fQAmc->Fill("h_ProtonL_P_S", 2, p[ixMC[0]]); + fQAmc->Fill("h_PionL_P_S", 2, p[ixMC[1]]); + } + else if(-2 != fCurrentV0id){ + fQAmc->Fill("h_cut_L_DCA_B", 1, iP, dca); + fQAmc->Fill("h_ProtonL_P_B", 2, p[ixMC[0]]); + fQAmc->Fill("h_PionL_P_B", 2, p[ixMC[1]]); + } + } } - if(r < cutProdVtxR[0] || r > cutProdVtxR[1]) return kFALSE; + // + // DCA cut + // + if(dca < cutDCA[0] || dca > cutDCA[1]) return kFALSE; (type == 0) ? fQA->Fill("h_L_Mass", 3, iMass) : fQA->Fill("h_AL_Mass", 3, iMass); if(iMass > cutMass[0] && iMass < cutMass[1]){ fQA->Fill("h_ProtonL_P", 3, p[ix[0]]); fQA->Fill("h_PionL_P", 3, p[ix[1]]); - fQA->Fill("h_cut_L_Chi2", 1, chi2ndf); + fQA->Fill("h_cut_L_VtxR", 1, r); + } + if(fMCEvent){ + if(4 == fCurrentV0id) fQAmc->Fill("h_L_Mass_S", 3, iMass); + else if(-4 == fCurrentV0id) fQAmc->Fill("h_AL_Mass_S", 3, iMass); + else if(-2 != fCurrentV0id) fQAmc->Fill("h_LAL_Mass_B", 3, iMass); + if(iMass > cutMass[0] && iMass < cutMass[1]){ + if(4 == TMath::Abs(fCurrentV0id)){ + fQAmc->Fill("h_cut_L_VtxR_S", 1, iP, r); + fQAmc->Fill("h_ProtonL_P_S", 3, p[ixMC[0]]); + fQAmc->Fill("h_PionL_P_S", 3, p[ixMC[1]]); + } + else if(-2 != fCurrentV0id){ + fQAmc->Fill("h_cut_L_VtxR_B", 1, iP, r); + fQAmc->Fill("h_ProtonL_P_B", 3, p[ixMC[0]]); + fQAmc->Fill("h_PionL_P_B", 3, p[ixMC[1]]); + } + } } - - if(chi2ndf > cutChi2NDF) return kFALSE; + // + // Vertex radius cut + // + if(r < cutProdVtxR[0] || r > cutProdVtxR[1]) return kFALSE; (type == 0) ? fQA->Fill("h_L_Mass", 4, iMass) : fQA->Fill("h_AL_Mass", 4, iMass); if(iMass > cutMass[0] && iMass < cutMass[1]){ + fQA->Fill("h_cut_L_OAvP", 1, iP, oAngle); fQA->Fill("h_ProtonL_P", 4, p[ix[0]]); fQA->Fill("h_PionL_P", 4, p[ix[1]]); - fQA->Fill("h_cut_L_OAvP", 1, iP, oAngle); - } - - if(oAngle < cutOAngleP) return kFALSE; - (type == 0) ? fQA->Fill("h_L_Mass", 5, iMass) : fQA->Fill("h_AL_Mass", 5, iMass); - if(iMass > cutMass[0] && iMass < cutMass[1]){ - fQA->Fill("h_ProtonL_P", 5, p[ix[0]]); - fQA->Fill("h_PionL_P", 5, p[ix[1]]); - fQA->Fill("h_cut_L_rdp_v_mp", 1, iP, rP); - if(0 == type) fQA->Fill("h_cut_L_AP", 1, ap[0], ap[1]); - else fQA->Fill("h_cut_AL_AP", 1, ap[0], ap[1]); - fQA->Fill("h_cut_L_qT_v_mp", 1, iP, ap[1]); - fQA->Fill("h_all_AP", 1, ap[0], ap[1]); - } - - if(ap[1] < cutQT) return kFALSE; - (type == 0) ? fQA->Fill("h_L_Mass", 6, iMass) : fQA->Fill("h_AL_Mass", 6, iMass); - if(iMass > cutMass[0] && iMass < cutMass[1]){ - fQA->Fill("h_ProtonL_P", 6, p[ix[0]]); - fQA->Fill("h_PionL_P", 6, p[ix[1]]); } - - if(ap[1] > cutAP[type]) return kFALSE; - (type == 0) ? fQA->Fill("h_L_Mass", 7, iMass) : fQA->Fill("h_AL_Mass", 7, iMass); - if(iMass > cutMass[0] && iMass < cutMass[1]){ - fQA->Fill("h_ProtonL_P", 7, p[ix[0]]); - fQA->Fill("h_PionL_P", 7, p[ix[1]]); - } - if(TMath::Abs(ap[0]) > cutAlpha) return kFALSE; - (type == 0) ? fQA->Fill("h_L_Mass", 8, iMass) : fQA->Fill("h_AL_Mass", 8, iMass); - if(iMass > cutMass[0] && iMass < cutMass[1]){ - fQA->Fill("h_ProtonL_P", 8, p[ix[0]]); - fQA->Fill("h_PionL_P", 8, p[ix[1]]); + if(fMCEvent){ + if(4 == fCurrentV0id) fQAmc->Fill("h_L_Mass_S", 4, iMass); + else if(-4 == fCurrentV0id) fQAmc->Fill("h_AL_Mass_S", 4, iMass); + else if(-2 != fCurrentV0id) fQAmc->Fill("h_LAL_Mass_B", 4, iMass); + if(iMass > cutMass[0] && iMass < cutMass[1]){ + if(4 == TMath::Abs(fCurrentV0id)){ + fQAmc->Fill("h_cut_L_OA_S", 1, iP, oAngle); + fQAmc->Fill("h_ProtonL_P_S", 4, p[ixMC[0]]); + fQAmc->Fill("h_PionL_P_S", 4, p[ixMC[1]]); + } + else if(-2 != fCurrentV0id){ + fQAmc->Fill("h_cut_L_OA_B", 1, iP, oAngle); + fQAmc->Fill("h_ProtonL_P_B", 4, p[ixMC[0]]); + fQAmc->Fill("h_PionL_P_B", 4, p[ixMC[1]]); + } + } } if(iMass < cutMass[0] || iMass > cutMass[1]) { @@ -845,7 +1334,29 @@ Bool_t AliHFEV0cuts::LambdaCuts(AliESDv0 *v0, Bool_t &isLambda ){ // assign the lambda type value: Lambda: kTRUE, Anti-Lambda: kFALSE isLambda = (0 == type) ? kTRUE : kFALSE; - + // some MC stuff + if(4 == fCurrentV0id){ + fQAmc->Fill("h_lambda_p_S", iP); + } + else if(-4 == fCurrentV0id){ + fQAmc->Fill("h_alambda_p_S", iP); + } + else if (-2 != fCurrentV0id && 0 == type){ + fQAmc->Fill("h_lambda_p_B", iP); + } + else if(-2 != fCurrentV0id && 0 != type ){ + fQAmc->Fill("h_alambda_p_B", iP); + } + // + if(4 == TMath::Abs(fCurrentV0id)){ + fQAmc->Fill("h_ProtonL_P_S", 5, p[ixMC[0]]); + fQAmc->Fill("h_PionL_P_S", 5, p[ixMC[1]]); + } + else if(-2 != fCurrentV0id){ + fQAmc->Fill("h_ProtonL_P_B", 5, p[ixMC[0]]); + fQAmc->Fill("h_PionL_P_B", 5, p[ixMC[1]]); + } + return kTRUE; } //________________________________________________________________ @@ -981,6 +1492,14 @@ AliKFParticle *AliHFEV0cuts::CreateMotherParticle(AliVTrack* const pdaughter, Al // Create the mother particle AliKFParticle *m = new AliKFParticle(pkfdaughter, nkfdaughter); + // DEBUG - testing + if(TMath::Abs(kElectron) == pspec && TMath::Abs(kElectron) == nspec) m->SetMassConstraint(0, 0.001); + else if(TMath::Abs(kPiPlus) == pspec && TMath::Abs(kPiPlus) == nspec) m->SetMassConstraint(TDatabasePDG::Instance()->GetParticle(kK0Short)->Mass(), 0.); + else if(TMath::Abs(kProton) == pspec && TMath::Abs(kPiPlus) == nspec) m->SetMassConstraint(TDatabasePDG::Instance()->GetParticle(kLambda0)->Mass(), 0.); + else if(TMath::Abs(kPiPlus) == pspec && TMath::Abs(kProton) == nspec) m->SetMassConstraint(TDatabasePDG::Instance()->GetParticle(kLambda0)->Mass(), 0.); + else{ + AliError("Wrong daughter ID - mass constraint can not be set"); + } AliKFVertex improvedVertex = *fPrimaryVertex; improvedVertex += *m; @@ -1102,3 +1621,84 @@ Bool_t AliHFEV0cuts::CheckSigns(AliESDv0* const v0){ return correct; } +//___________________________________________________________________ +Bool_t AliHFEV0cuts::GetConvPosXY(AliESDtrack * const ptrack, AliESDtrack * const ntrack, Double_t convpos[2]){ + // + // recalculate the gamma conversion XY postition + // + + const Double_t b = fInputEvent->GetMagneticField(); + + Double_t helixcenterpos[2]; + GetHelixCenter(ptrack,b,ptrack->Charge(),helixcenterpos); + + Double_t helixcenterneg[2]; + GetHelixCenter(ntrack,b,ntrack->Charge(),helixcenterneg); + + Double_t poshelix[6]; + ptrack->GetHelixParameters(poshelix,b); + Double_t posradius = TMath::Abs(1./poshelix[4]); + + Double_t neghelix[6]; + ntrack->GetHelixParameters(neghelix,b); + Double_t negradius = TMath::Abs(1./neghelix[4]); + + Double_t xpos = helixcenterpos[0]; + Double_t ypos = helixcenterpos[1]; + Double_t xneg = helixcenterneg[0]; + Double_t yneg = helixcenterneg[1]; + + convpos[0] = (xpos*negradius + xneg*posradius)/(negradius+posradius); + convpos[1] = (ypos*negradius+ yneg*posradius)/(negradius+posradius); + + return 1; +} +//___________________________________________________________________ +Bool_t AliHFEV0cuts::GetHelixCenter(AliESDtrack * const track, Double_t b,Int_t charge, Double_t center[2]){ + // see header file for documentation + + Double_t pi = TMath::Pi(); + + Double_t helix[6]; + track->GetHelixParameters(helix,b); + + Double_t xpos = helix[5]; + Double_t ypos = helix[0]; + Double_t radius = TMath::Abs(1./helix[4]); + Double_t phi = helix[2]; + + if(phi < 0){ + phi = phi + 2*pi; + } + + phi -= pi/2.; + Double_t xpoint = radius * TMath::Cos(phi); + Double_t ypoint = radius * TMath::Sin(phi); + + if(b<0){ + if(charge > 0){ + xpoint = - xpoint; + ypoint = - ypoint; + } + + if(charge < 0){ + xpoint = xpoint; + ypoint = ypoint; + } + } + if(b>0){ + if(charge > 0){ + xpoint = xpoint; + ypoint = ypoint; + } + + if(charge < 0){ + xpoint = - xpoint; + ypoint = - ypoint; + } + } + center[0] = xpos + xpoint; + center[1] = ypos + ypoint; + + return 1; +} diff --git a/PWG3/hfe/AliHFEV0cuts.h b/PWG3/hfe/AliHFEV0cuts.h index 65a8dc9bc0a..82bcdbf886b 100644 --- a/PWG3/hfe/AliHFEV0cuts.h +++ b/PWG3/hfe/AliHFEV0cuts.h @@ -34,6 +34,22 @@ class AliVTrack; class AliHFEV0cuts : public TObject { public: + enum{ // Reconstructed V0 + kUndef = 0, + kRecoGamma = 1, + kRecoK0 = 2, + kRecoPhi = 3, + kRecoLambda = 4, + kRecoALambda = -4 + + }; + enum{ // Identified Daughter particles + kRecoElectron = 0, + kRecoPionK0 = 1, + kRecoPionL = 2, + kRecoKaon = 3, + kRecoProton = 4 + }; AliHFEV0cuts(); ~AliHFEV0cuts(); AliHFEV0cuts(const AliHFEV0cuts &ref); @@ -42,12 +58,12 @@ class AliHFEV0cuts : public TObject { void Init(const char* name); void RunQA(); - void SetMC(Bool_t b) { fIsMC = b; }; void SetMCEvent(AliMCEvent* const mce) { fMCEvent = mce; }; void SetInputEvent(AliVEvent* const e) { fInputEvent = e; }; void SetPrimaryVertex(AliKFVertex* const v) { fPrimaryVertex = v; }; - TList* GetList() { return fQA->GetList(); }; + TList* GetList() { return fQA->GetList(); }; + TList* GetListMC() { return fQAmc->GetList(); }; Bool_t TrackCutsCommon(AliESDtrack* track); Bool_t V0CutsCommon(AliESDv0 *v0); @@ -65,6 +81,13 @@ class AliHFEV0cuts : public TObject { Double_t PsiPair(AliESDv0 *v0); Bool_t CheckSigns(AliESDv0* const v0); + Bool_t GetConvPosXY(AliESDtrack * const ptrack, AliESDtrack * const ntrack, Double_t convpos[2]); + Bool_t GetHelixCenter(AliESDtrack * const track, Double_t b,Int_t charge, Double_t center[2]); + + + // MC stuff + void SetCurrentV0id(Int_t id) { fCurrentV0id = id; }; + void SetDaughtersID(Int_t d[2]) {fPdaughterPDG = d[0]; fNdaughterPDG = d[1]; }; AliKFParticle *CreateMotherParticle(AliVTrack* const pdaughter, AliVTrack* const ndaughter, Int_t pspec, Int_t nspec); @@ -74,11 +97,15 @@ class AliHFEV0cuts : public TObject { private: AliHFEcollection *fQA; // store QA cut histograms + AliHFEcollection *fQAmc; // store AliMCEvent *fMCEvent; // MC event AliVEvent *fInputEvent; // Input Event AliKFVertex *fPrimaryVertex; // primary vertex - Bool_t fIsMC; // availability of MC information + Int_t fCurrentV0id; // MC flagged V0 + Int_t fPdaughterPDG; // MC id of the positive daugeter + Int_t fNdaughterPDG; // MC id of the negative daugeter + ClassDef(AliHFEV0cuts, 1) }; diff --git a/PWG3/hfe/AliHFEV0pid.cxx b/PWG3/hfe/AliHFEV0pid.cxx index a2b1eed7816..658fe1f7719 100644 --- a/PWG3/hfe/AliHFEV0pid.cxx +++ b/PWG3/hfe/AliHFEV0pid.cxx @@ -34,6 +34,9 @@ #include "AliKFVertex.h" #include "AliVEvent.h" #include "AliVTrack.h" +#include "AliMCParticle.h" +#include "AliStack.h" +#include "AliMCEvent.h" #include "AliHFEV0cuts.h" #include "AliHFEV0info.h" @@ -46,6 +49,9 @@ ClassImp(AliHFEV0pid) AliHFEV0pid::AliHFEV0pid(): TObject() , fInputEvent(NULL) + , fNtracks(0) + , fMCEvent(NULL) + , fMCon(kFALSE) , fPrimaryVertex(NULL) , fElectrons(NULL) , fPionsK0(NULL) @@ -120,14 +126,15 @@ void AliHFEV0pid::InitQA(){ fV0cuts->Init("V0cuts"); if(!fQA){ - fQA = new AliHFEcollection("v0pidQA", "QA histograms for V0 PID"); + fQA = new AliHFEcollection("v0pidQA", "QA histograms for V0 selection"); fQA->CreateTH1F("h_nV0s", "No. of found and accepted V0s", 5, -0.5, 4.5); // QA histograms for invariant mass fQA->CreateTH1F("h_InvMassGamma", "Gamma invariant mass; inv mass [GeV/c^{2}]; counts", 100, 0, 0.25); fQA->CreateTH1F("h_InvMassK0s", "K0s invariant mass; inv mass [GeV/c^{2}]; counts", 200, 0.4, 0.65); - fQA->CreateTH1F("h_InvMassLambda", "Lambda invariant mass; inv mass [GeV/c^{2}]; counts", 100, 1.05, 1.15); + fQA->CreateTH1F("h_InvMassL", "Lambda invariant mass; inv mass [GeV/c^{2}]; counts", 100, 1.05, 1.15); + fQA->CreateTH1F("h_InvMassAL", "Lambda invariant mass; inv mass [GeV/c^{2}]; counts", 100, 1.05, 1.15); // QA histograms for p distribution (of the daughters) fQA->CreateTH1F("h_P_electron", "P distribution of the gamma electrons; p (GeV/c); counts", 100, 0.1, 10); @@ -138,8 +145,30 @@ void AliHFEV0pid::InitQA(){ // QA pt of the V0 fQA->CreateTH1F("h_Pt_Gamma", "Pt of the gamma conversion; p_{T} (GeV/c); counts", 100, 0, 10); fQA->CreateTH1F("h_Pt_K0", "Pt of the K0; p_{T} (GeV/c); counts", 100, 0, 10); - fQA->CreateTH1F("h_Pt_Lambda", "Pt of the Lambda; p_{T} (GeV/c); counts", 100, 0, 10); + fQA->CreateTH1F("h_Pt_L", "Pt of the Lambda; p_{T} (GeV/c); counts", 100, 0, 10); + fQA->CreateTH1F("h_Pt_AL", "Pt of the Lambda; p_{T} (GeV/c); counts", 100, 0, 10); + // Armenteros plot V0 preselection + fQA->CreateTH2F("h_AP_all_V0s", "armenteros plot for all V0 candidates; #alpha; Q_{T}", 200, -1, 1, 200, 0, 0.25); + fQA->CreateTH2F("h_AP_selected_V0s", "armenteros plot for all V0 candidates; #alpha; Q_{T}", 200, -1, 1, 200, 0, 0.25); + + // + // !!! MC plots !!! + // + fQA->CreateTH2F("h_AP_MC_all_V0s", "armenteros plot for all MC tagged V0s; #alpha; Q_{T}", 200, -1, 1, 200, 0, 0.25); + fQA->CreateTH2F("h_AP_MC_Gamma", "armenteros plot for MC tagged Gammas; #alpha; Q_{T}", 200, -1, 1, 200, 0, 0.25); + fQA->CreateTH2F("h_AP_MC_K0", "armenteros plot for MC tagged K0s; #alpha; Q_{T}", 200, -1, 1, 200, 0, 0.25); + fQA->CreateTH2F("h_AP_MC_Lambda", "armenteros plot for MC tagged Lambdas; #alpha; Q_{T}", 200, -1, 1, 200, 0, 0.25); + fQA->CreateTH2F("h_AP_MC_ALambda", "armenteros plot for MC tagged A-Lambdass; #alpha; Q_{T}", 200, -1, 1, 200, 0, 0.25); + + + + // armenteros plots for different V0 momenta - MC signal only + fQA->CreateTH2Fvector1(12, "h_AP_MC_Gamma_p", "armenteros plot for MC tagged Gammas; #alpha; Q_{T}", 200, -1., 1., 200, 0., 0.25); + fQA->CreateTH2Fvector1(12, "h_AP_MC_K0_p", "armenteros plot for MC tagged K0s; #alpha; Q_{T}", 200, -1., 1., 200, 0., 0.25); + fQA->CreateTH2Fvector1(12, "h_AP_MC_Lambda_p", "armenteros plot for MC tagged Lambdas; #alpha; Q_{T}", 200, -1., 1., 200, 0., 0.25); + // + } } @@ -154,11 +183,13 @@ void AliHFEV0pid::Process(AliVEvent * const inputEvent){ Int_t nGamma = 0, nK0s = 0, nLambda = 0, nPhi = 0; fInputEvent = inputEvent; + fNtracks = fInputEvent->GetNumberOfTracks(); fIndices->Init(fInputEvent->GetNumberOfV0s() * 2); fPrimaryVertex = new AliKFVertex(*(fInputEvent->GetPrimaryVertex())); if(!fPrimaryVertex) return; fV0cuts->SetInputEvent(fInputEvent); fV0cuts->SetPrimaryVertex(fPrimaryVertex); + if(fMCEvent) fV0cuts->SetMCEvent(fMCEvent); Int_t v0status = 0; for(Int_t iv0 = 0; iv0 < fInputEvent->GetNumberOfV0s(); iv0++){ if(!TString(fInputEvent->IsA()->GetName()).CompareTo("AliESDEvent")){ @@ -174,14 +205,14 @@ void AliHFEV0pid::Process(AliVEvent * const inputEvent){ AliAODv0 *aodV0 = (dynamic_cast(fInputEvent))->GetV0(iv0); if(aodV0->GetOnFlyStatus()) continue; // Take only V0s from the On-the-fly v0 finder v0status = ProcessV0(aodV0); - if(kUndef != v0status){ + if(AliHFEV0cuts::kUndef != v0status){ } } switch(v0status){ - case kRecoGamma: nGamma++; break; - case kRecoK0s: nK0s++; break; - case kRecoPhi: nPhi++; break; - case kRecoLambda: nLambda++; break; + case AliHFEV0cuts::kRecoGamma: nGamma++; break; + case AliHFEV0cuts::kRecoK0: nK0s++; break; + case AliHFEV0cuts::kRecoPhi: nPhi++; break; + case AliHFEV0cuts::kRecoLambda: nLambda++; break; }; } @@ -210,33 +241,46 @@ Int_t AliHFEV0pid::ProcessV0(TObject *v0){ AliVTrack* daughter[2]; daughter[0] = dynamic_cast(fInputEvent->GetTrack((dynamic_cast(v0))->GetPindex())); daughter[1] = dynamic_cast(fInputEvent->GetTrack((dynamic_cast(v0))->GetNindex())); - if(!daughter[0] || !daughter[1]) return kUndef; + if(!daughter[0] || !daughter[1]) return AliHFEV0cuts::kUndef; + + if(fMCEvent) fMCon = kTRUE; + //printf("-D: fMCEvent %x, fMCon: %i\n", fMCEvent, fMCon); + + Int_t dMC[2] = {-1, -1}; + Int_t idMC = AliHFEV0cuts::kUndef; - if(IsESDanalysis()){ + if(fMCon){ + idMC = IdentifyV0(v0, dMC); + //printf("--D: V0 pid: %i, P: %i, N: %i\n", id, d[0], d[1]); + fV0cuts->SetCurrentV0id(idMC); + fV0cuts->SetDaughtersID(dMC); + } + // check common single track cuts for(Int_t i=0; i<2; ++i){ - // check common single track cuts - if(!fV0cuts->TrackCutsCommon(dynamic_cast(daughter[i]))) return kUndef; - } + if(!fV0cuts->TrackCutsCommon(dynamic_cast(daughter[i]))) return AliHFEV0cuts::kUndef; + } // check commom V0 cuts - if(!fV0cuts->V0CutsCommon(dynamic_cast(v0))) return kUndef; + if(!fV0cuts->V0CutsCommon(dynamic_cast(v0))) return AliHFEV0cuts::kUndef; } + // preselect the V0 candidates based on the Armenteros plot + Int_t id = PreselectV0((dynamic_cast(v0)), idMC); // store the resutls - if(IsGammaConv(v0)){ - fQA->Fill("h_nV0s", kRecoGamma); - return kRecoGamma; + if(AliHFEV0cuts::kRecoGamma == id && IsGammaConv(v0)){ + fQA->Fill("h_nV0s", AliHFEV0cuts::kRecoGamma); + return AliHFEV0cuts::kRecoGamma; } - else if(IsK0s(v0)){ - fQA->Fill("h_nV0s", kRecoK0s); - return kRecoK0s; + else if(AliHFEV0cuts::kRecoK0 == id && IsK0s(v0)){ + fQA->Fill("h_nV0s", AliHFEV0cuts::kRecoK0); + return AliHFEV0cuts::kRecoK0; } - else if(IsLambda(v0)){ - fQA->Fill("h_nV0s", kRecoLambda); - return kRecoLambda; + else if(AliHFEV0cuts::kRecoLambda == TMath::Abs(id) && IsLambda(v0)){ + fQA->Fill("h_nV0s", AliHFEV0cuts::kRecoLambda); + return AliHFEV0cuts::kRecoLambda; } - else return kUndef; + else return AliHFEV0cuts::kUndef; } //____________________________________________________________ @@ -252,6 +296,111 @@ void AliHFEV0pid::Flush(){ fIndices->Flush(); } //____________________________________________________________ +Int_t AliHFEV0pid::PreselectV0(AliESDv0 * const v0, Int_t idMC){ + // + // Based on Armenteros plot preselet the possible identity of the V0 candidate + // + + if(!v0) return -1; + + // momentum dependent armenteros plots + ArmenterosPlotMC(v0, idMC); + + // comupte the armenteros variables + Float_t ar[2]; + fV0cuts->Armenteros(v0, ar); + // for clarity + const Float_t alpha = ar[0]; + const Float_t qt = ar[1]; + //printf(" -D: Alpha: %f, QT: %f \n", alpha, qt); + + if(TMath::Abs(alpha) > 1) return AliHFEV0cuts::kUndef; + + fQA->Fill("h_AP_all_V0s", alpha, qt); + + // fill a few MC tagged histograms - AP plots + if(fMCEvent){ + switch(idMC){ + case AliHFEV0cuts::kRecoGamma : + fQA->Fill("h_AP_MC_all_V0s", alpha, qt); + fQA->Fill("h_AP_MC_Gamma", alpha, qt); + break; + case AliHFEV0cuts::kRecoK0 : + fQA->Fill("h_AP_MC_all_V0s", alpha, qt); + fQA->Fill("h_AP_MC_K0", alpha, qt); + break; + case AliHFEV0cuts::kRecoLambda : + fQA->Fill("h_AP_MC_all_V0s", alpha, qt); + fQA->Fill("h_AP_MC_Lambda", alpha, qt); + break; + case AliHFEV0cuts::kRecoALambda : + fQA->Fill("h_AP_MC_all_V0s", alpha, qt); + fQA->Fill("h_AP_MC_ALambda", alpha, qt); + break; + } + } + + // Gamma cuts + const Double_t cutAlphaG = 0.35; + const Double_t cutQTG = 0.05; + const Double_t cutAlphaG2[2] = {0.6, 0.8}; + const Double_t cutQTG2 = 0.04; + + // K0 cuts + const Float_t cutQTK0[2] = {0.1075, 0.215}; + const Float_t cutAPK0[2] = {0.199, 0.8}; // parameters for curved QT cut + + // Lambda & A-Lambda cuts + const Float_t cutQTL = 0.03; + const Float_t cutAlphaL[2] = {0.35, 0.7}; + const Float_t cutAlphaAL[2] = {-0.7, -0.35}; + const Float_t cutAPL[3] = {0.107, -0.69, 0.5}; // parameters fir curved QT cut + + + // Check for Gamma candidates + if(qt < cutQTG){ + if( (TMath::Abs(alpha) < cutAlphaG) ){ + fQA->Fill("h_AP_selected_V0s", alpha, qt); + return AliHFEV0cuts::kRecoGamma; + } + } + // additional region - should help high pT gammas + if(qt < cutQTG2){ + if( (TMath::Abs(alpha) > cutAlphaG2[0]) && (TMath::Abs(alpha) < cutAlphaG2[1]) ){ + fQA->Fill("h_AP_selected_V0s", alpha, qt); + return AliHFEV0cuts::kRecoGamma; + } + } + + + // Check for K0 candidates + Float_t q = cutAPK0[0] * TMath::Sqrt(TMath::Abs(1 - alpha*alpha/(cutAPK0[1]*cutAPK0[1]))); + if( (qt > cutQTK0[0]) && (qt < cutQTK0[1]) && (qt > q) ){ + fQA->Fill("h_AP_selected_V0s", alpha, qt); + return AliHFEV0cuts::kRecoK0; + } + + if( (alpha > 0) && (alpha > cutAlphaL[0]) && (alpha < cutAlphaL[1]) && (qt > cutQTL)){ + q = cutAPL[0] * TMath::Sqrt(1 - ( (alpha + cutAPL[1]) * (alpha + cutAPL[1])) / (cutAPL[2]*cutAPL[2]) ); + if( qt < q ){ + fQA->Fill("h_AP_selected_V0s", alpha, qt); + return AliHFEV0cuts::kRecoLambda; + } + } + + // Check for A-Lambda candidates + if( (alpha < 0) && (alpha > cutAlphaAL[0]) && (alpha < cutAlphaAL[1]) && (qt > cutQTL)){ + q = cutAPL[0] * TMath::Sqrt(1 - ( (alpha - cutAPL[1]) * (alpha - cutAPL[1]) ) / (cutAPL[2]*cutAPL[2]) ); + if( qt < q ){ + fQA->Fill("h_AP_selected_V0s", alpha, qt); + return AliHFEV0cuts::kRecoLambda; + } + } + + return AliHFEV0cuts::kUndef; + +} +//____________________________________________________________ Bool_t AliHFEV0pid::IsGammaConv(TObject *v0){ // // Identify Gamma @@ -294,12 +443,12 @@ Bool_t AliHFEV0pid::IsGammaConv(TObject *v0){ if(!fIndices->Find(daughter[0]->GetID())){ AliDebug(1, Form("Gamma identified, daughter IDs: %d,%d", daughter[0]->GetID(), daughter[1]->GetID())); fElectrons->Add(new AliHFEV0info(daughter[0], daughter[1]->GetID(), v0id)); - fIndices->Add(daughter[0]->GetID(), AliHFEV0pid::kRecoElectron); + fIndices->Add(daughter[0]->GetID(), AliHFEV0cuts::kRecoElectron); } if(!fIndices->Find(daughter[1]->GetID())){ AliDebug(1, Form("Gamma identified, daughter IDs: %d,%d", daughter[1]->GetID(), daughter[1]->GetID())); fElectrons->Add(new AliHFEV0info(daughter[1], daughter[0]->GetID(), v0id)); - fIndices->Add(daughter[1]->GetID(), AliHFEV0pid::kRecoElectron); + fIndices->Add(daughter[1]->GetID(), AliHFEV0cuts::kRecoElectron); } fGammas->Add(v0); @@ -346,12 +495,12 @@ Bool_t AliHFEV0pid::IsK0s(TObject *v0){ if(!fIndices->Find(daughter[0]->GetID())){ AliDebug(1, Form("Adding K0 Pion track with ID %d", daughter[0]->GetID())); fPionsK0->Add(new AliHFEV0info(daughter[0], daughter[1]->GetID(), v0id)); - fIndices->Add(daughter[0]->GetID(), AliHFEV0pid::kRecoPionK0); + fIndices->Add(daughter[0]->GetID(), AliHFEV0cuts::kRecoPionK0); } if(!fIndices->Find(daughter[1]->GetID())){ AliDebug(1, Form("Adding K0 Pion track with ID %d", daughter[1]->GetID())); fPionsK0->Add(new AliHFEV0info(daughter[1], daughter[0]->GetID(), v0id)); - fIndices->Add(daughter[1]->GetID(), AliHFEV0pid::kRecoPionK0); + fIndices->Add(daughter[1]->GetID(), AliHFEV0cuts::kRecoPionK0); } fK0s->Add(v0); return kTRUE; @@ -390,12 +539,14 @@ Bool_t AliHFEV0pid::IsLambda(TObject *v0){ Int_t pIndex = 0, nIndex = 0; Double_t invMass = 0.; Bool_t isLambda = kTRUE; // Lambda - kTRUE, Anti Lambda - kFALSE + Double_t mPt = 0.; Int_t v0id = -1; if(IsESDanalysis()){ // ESD - cut V0 AliESDv0 *esdV0 = dynamic_cast(v0); v0id = esdV0->GetLabel(); if(!fV0cuts->LambdaCuts(esdV0,isLambda)) return kFALSE; + mPt = esdV0->Pt(); if(fV0cuts->CheckSigns(esdV0)){ pIndex = esdV0->GetPindex(); nIndex = esdV0->GetNindex(); @@ -422,24 +573,29 @@ Bool_t AliHFEV0pid::IsLambda(TObject *v0){ // lambda if(isLambda){ + fQA->Fill("h_Pt_L", mPt); + fQA->Fill("h_InvMassL", invMass); + if(!fIndices->Find(daughter[0]->GetID())){ fProtons->Add(new AliHFEV0info(daughter[0], daughter[1]->GetID(), v0id)); - fIndices->Add(daughter[0]->GetID(), AliHFEV0pid::kRecoProton); + fIndices->Add(daughter[0]->GetID(), AliHFEV0cuts::kRecoProton); } if(!fIndices->Find(daughter[1]->GetID())){ fPionsL->Add(new AliHFEV0info(daughter[1], daughter[0]->GetID(), v0id)); - fIndices->Add(daughter[1]->GetID(), AliHFEV0pid::kRecoPionL); + fIndices->Add(daughter[1]->GetID(), AliHFEV0cuts::kRecoPionL); } } // antilambda else{ + fQA->Fill("h_Pt_AL", mPt); + fQA->Fill("h_InvMassAL", invMass); if(!fIndices->Find(daughter [1]->GetID())){ fProtons->Add(new AliHFEV0info(daughter[1], daughter[0]->GetID(), v0id)); - fIndices->Add(daughter[1]->GetID(), AliHFEV0pid::kRecoProton); + fIndices->Add(daughter[1]->GetID(), AliHFEV0cuts::kRecoProton); } if(!fIndices->Find(daughter [0]->GetID())){ fPionsL->Add(new AliHFEV0info(daughter[0], daughter[1]->GetID(), v0id)); - fIndices->Add(daughter [0]->GetID(), AliHFEV0pid::kRecoPionL); + fIndices->Add(daughter [0]->GetID(), AliHFEV0cuts::kRecoPionL); } } if(isLambda) fLambdas->Add(v0); @@ -448,6 +604,124 @@ Bool_t AliHFEV0pid::IsLambda(TObject *v0){ return kTRUE; } +//____________________________________________________________ +Int_t AliHFEV0pid::IdentifyV0(TObject *esdV0, Int_t d[2]){ + // + // for MC only, returns the V0 Id + // + + // + // be carefull about changing the return values - they are used later selectively + // In particulra "-2" means that identity of either of the daughters could not be + // estimated + // + + AliESDv0 *v0 = dynamic_cast(esdV0); + + if(!v0) return -1; + AliESDtrack* dN, *dP; + Int_t iN, iP; + iN = iP = -1; + iP = v0->GetPindex(); + iN = v0->GetNindex(); + if(iN < 0 || iP < 0) return -1; + if(iN >= fNtracks || iP >= fNtracks) return -1; + dP = dynamic_cast(fInputEvent->GetTrack(iP)); + dN = dynamic_cast(fInputEvent->GetTrack(iN)); + if(!dN || !dP) return -1; + + // as of 26/10/2010 + // there is still a problem with wrong assignment of positive and negative + // V0 daughter in V0 finder - a check is necessary + // if the V0 daughters are miss-assigned - swap their labels + Bool_t sign = fV0cuts->CheckSigns(v0); + + // get the MC labels + Int_t lN, lP; + if(sign){ + lN = dN->GetLabel(); + lP = dP->GetLabel(); + } + else{ + lP = dN->GetLabel(); + lN = dP->GetLabel(); + } + if(lN < 0 || lP < 0) return -2; + // get the associated MC particles + AliMCParticle *mcP, *mcN; + mcP = dynamic_cast(fMCEvent->GetTrack(lP)); + mcN = dynamic_cast(fMCEvent->GetTrack(lN)); + if(!mcP || !mcN) return -2; + + // identify the daughter tracks and their mothers + Int_t pdgP, pdgN; + pdgP = TMath::Abs(mcP->PdgCode()); + pdgN = TMath::Abs(mcN->PdgCode()); + // store the daughter ID for later use + d[0] = pdgP; + d[1] = pdgN; + //printf(" -D: pdgP: %i, pdgN: %i\n", pdgP, pdgN); + // lablel of the mother particle + // -1 may mean it was a primary particle + Int_t lPm, lNm; + lPm = mcP->GetMother(); + lNm = mcN->GetMother(); + if(-1==lPm || -1==lNm) return -3; + + // return if mothers are not the same particle + if(lPm != lNm) return -3; + // get MC mother particle - now we need only 1 + AliMCParticle *m = dynamic_cast(fMCEvent->GetTrack(lPm)); + if(!m) return -2; + // mother PDG + Int_t pdgM = m->PdgCode(); + + // if(3122 == TMath::Abs(pdgM)){ + // printf("-D: v0 signs: %i\n", fV0cuts->CheckSigns(v0)); + // printf("-D: pdgM: %i, pdgN: %i, pdgP: %i \n", pdgM, pdgN, pdgP); + // } + + + // now check the mother and daughters identity + if(22 == TMath::Abs(pdgM) && 11 == pdgN && 11 == pdgP) return AliHFEV0cuts::kRecoGamma; + if(310 == TMath::Abs(pdgM) && 211 == pdgN && 211 == pdgP) return AliHFEV0cuts::kRecoK0; + if(-3122 == pdgM && 2212 == pdgN && 211 == pdgP) return AliHFEV0cuts::kRecoALambda; + if(3122 == pdgM && 211 == pdgN && 2212 == pdgP) return AliHFEV0cuts::kRecoLambda; + + return AliHFEV0cuts::kUndef; + +} +//____________________________________________________________ +void AliHFEV0pid::ArmenterosPlotMC(AliESDv0 * const v0, Int_t idMC){ + // + // Armenteros plots as a function of Mohter Momentum + // + //const Float_t minP = 0.1; + //const Float_t maxP = 10.; + // approx log bins - over the 0.1 - 10 GeV/c + const Float_t bins[13] = {0.1, 0.1468, 0.2154, 0.3162, 0.4642, 0.6813, 1.0, 1.4678, 2.1544, 3.1623, 4.6416, 6.8129, 10.0}; + + Float_t ar[2]; + fV0cuts->Armenteros(v0, ar); + Float_t p = v0->P(); + + if( (p <= bins[0]) || (p >= bins[12])) return; + + Int_t pBin = 0; + Float_t tmp = bins[0]; + while(tmp < p){ + ++pBin; + tmp = bins[pBin]; + } + pBin--; + + if(AliHFEV0cuts::kRecoGamma == idMC) fQA->Fill("h_AP_MC_Gamma_p", pBin, ar[0], ar[1]); + if(AliHFEV0cuts::kRecoK0 == idMC) fQA->Fill("h_AP_MC_K0_p", pBin, ar[0], ar[1]); + if(AliHFEV0cuts::kRecoLambda == TMath::Abs(idMC)) fQA->Fill("h_AP_MC_Lambda_p", pBin, ar[0], ar[1]); + + + +} //____________________________________________________________ AliHFEV0pid::AliHFEV0pidTrackIndex::AliHFEV0pidTrackIndex(): fNElectrons(0) @@ -518,16 +792,16 @@ void AliHFEV0pid::AliHFEV0pidTrackIndex::Add(Int_t index, Int_t species){ // Add new index to the list of identified particles // switch(species){ - case AliHFEV0pid::kRecoElectron: + case AliHFEV0cuts::kRecoElectron: fIndexElectron[fNElectrons++] = index; break; - case AliHFEV0pid::kRecoPionK0: + case AliHFEV0cuts::kRecoPionK0: fIndexPionK0[fNPionsK0++] = index; break; - case AliHFEV0pid::kRecoPionL: + case AliHFEV0cuts::kRecoPionL: fIndexPionL[fNPionsL++] = index; break; - case AliHFEV0pid::kRecoProton: + case AliHFEV0cuts::kRecoProton: fIndexProton[fNProtons++] = index; break; }; @@ -541,19 +815,19 @@ Bool_t AliHFEV0pid::AliHFEV0pidTrackIndex::Find(Int_t index, Int_t species) cons Int_t *container = NULL; Int_t n = 0; switch(species){ - case AliHFEV0pid::kRecoElectron: + case AliHFEV0cuts::kRecoElectron: container = fIndexElectron; n = fNElectrons; break; - case AliHFEV0pid::kRecoPionK0: + case AliHFEV0cuts::kRecoPionK0: container = fIndexPionK0; n = fNPionsK0; break; - case AliHFEV0pid::kRecoPionL: + case AliHFEV0cuts::kRecoPionL: container = fIndexPionL; n = fNPionsL; break; - case AliHFEV0pid::kRecoProton: + case AliHFEV0cuts::kRecoProton: container = fIndexProton; n = fNProtons; break; @@ -575,10 +849,10 @@ Bool_t AliHFEV0pid::AliHFEV0pidTrackIndex::Find(Int_t index) const { // // Find index in all samples // - if(Find(index, AliHFEV0pid::kRecoElectron)) return kTRUE; - else if(Find(index, AliHFEV0pid::kRecoPionK0)) return kTRUE; - else if(Find(index, AliHFEV0pid::kRecoPionL)) return kTRUE; - else return Find(index, AliHFEV0pid::kRecoProton); + if(Find(index, AliHFEV0cuts::kRecoElectron)) return kTRUE; + else if(Find(index, AliHFEV0cuts::kRecoPionK0)) return kTRUE; + else if(Find(index, AliHFEV0cuts::kRecoPionL)) return kTRUE; + else return Find(index, AliHFEV0cuts::kRecoProton); } //____________________________________________________________ @@ -586,7 +860,7 @@ TList *AliHFEV0pid::GetListOfQAhistograms(){ // // Getter for V0 PID QA histograms // - + TList *tmp = fV0cuts->GetList(); tmp->SetName("V0cuts"); fOutput->Add(tmp); @@ -596,5 +870,11 @@ TList *AliHFEV0pid::GetListOfQAhistograms(){ tmp->SetName("V0pid"); fOutput->Add(tmp); } + tmp = 0x0; + tmp = fV0cuts->GetListMC(); + tmp->SetName("V0cutsMC"); + //printf(" -D: adding MC V0 cuts stuff\n"); + fOutput->Add(tmp); + return fOutput; } diff --git a/PWG3/hfe/AliHFEV0pid.h b/PWG3/hfe/AliHFEV0pid.h index 8d66402d163..188ec8ce330 100644 --- a/PWG3/hfe/AliHFEV0pid.h +++ b/PWG3/hfe/AliHFEV0pid.h @@ -34,27 +34,13 @@ class AliKFParticle; class AliKFVertex; class AliVEvent; class AliVTrack; +class AliMCEvent; class AliHFEV0cuts; class AliHFEcollection; class AliHFEV0pid : public TObject{ public: - enum{ // Reconstructed V0 - kUndef = 0, - kRecoGamma = 1, - kRecoK0s = 2, - kRecoPhi = 3, - kRecoLambda = 4 - - }; - enum{ // Identified Daughter particles - kRecoElectron = 0, - kRecoPionK0 = 1, - kRecoPionL = 2, - kRecoKaon = 3, - kRecoProton = 4 - }; AliHFEV0pid(); ~AliHFEV0pid(); @@ -76,17 +62,24 @@ class AliHFEV0pid : public TObject{ void SetAODanalysis(Bool_t isAOD = kTRUE) { SetBit(kAODanalysis, isAOD); }; void SetESDanalysis(Bool_t isESD = kTRUE) { SetBit(kAODanalysis, !isESD); }; + void SetMCEvent(AliMCEvent* const ev) { fMCEvent = ev; }; + protected: enum{ kAODanalysis = BIT(14) }; - + + Int_t PreselectV0(AliESDv0 * const v0, Int_t idMC); + + void ArmenterosPlotMC(AliESDv0 * const v0, Int_t idMC); Bool_t IsGammaConv(TObject *v0); Bool_t IsK0s(TObject *v0); Bool_t IsPhi(TObject *v0); Bool_t IsLambda(TObject *v0); TList *GetV0pidQA(); + Int_t IdentifyV0(TObject *v0, Int_t d[2]); + private: class AliHFEV0pidTrackIndex{ public: @@ -121,6 +114,9 @@ class AliHFEV0pid : public TObject{ AliHFEV0pid&operator=(const AliHFEV0pid &ref); AliVEvent *fInputEvent; // Input Event + Int_t fNtracks; // number of tracks in current event + AliMCEvent *fMCEvent; // MC evnet + Bool_t fMCon; // availability of MC information AliKFVertex *fPrimaryVertex; // Primary Vertex TObjArray *fElectrons; // List of Electron tracks coming from Conversions TObjArray *fPionsK0; // List of Pion tracks coming from K0 diff --git a/PWG3/hfe/AliHFEV0pidMC.cxx b/PWG3/hfe/AliHFEV0pidMC.cxx index 517890a8f59..6ca9d1b6f9d 100644 --- a/PWG3/hfe/AliHFEV0pidMC.cxx +++ b/PWG3/hfe/AliHFEV0pidMC.cxx @@ -62,24 +62,28 @@ void AliHFEV0pidMC::Init(){ // QA fColl->CreateTH1F("h_QA_nParticles", "QA on track processing", 10, -0.5, 9.5); + const Int_t nBins = 20; + const Float_t pMin = 0.1; + const Float_t pMax = 10.; + // before PID - fColl->CreateTH1F("h_Electron", "all electron candidates (no MC); p (GeV/c); counts", 100, 0.1, 10, 0); - fColl->CreateTH1F("h_PionK0", "all K0 pion candidates (no MC); p (GeV/c); counts", 100, 0.1, 10, 0); - fColl->CreateTH1F("h_PionL", "all Lambda pion candidates (no MC); p (GeV/c); counts", 100, 0.1, 10, 0); - fColl->CreateTH1F("h_Kaon", "all Kaon candidates (no MC); p (GeV/c); counts", 100, 0.1, 10, 0); - fColl->CreateTH1F("h_Proton", "all Lambda proton candidates (no MC); p (GeV/c); counts", 100, 0.1, 10, 0); + fColl->CreateTH1F("h_Electron", "all electron candidates (no MC); p (GeV/c); counts", nBins, pMin, pMax, 0); + fColl->CreateTH1F("h_PionK0", "all K0 pion candidates (no MC); p (GeV/c); counts", nBins, pMin, pMax, 0); + fColl->CreateTH1F("h_PionL", "all Lambda pion candidates (no MC); p (GeV/c); counts", nBins, pMin, pMax, 0); + fColl->CreateTH1F("h_Kaon", "all Kaon candidates (no MC); p (GeV/c); counts", nBins, pMin, pMax, 0); + fColl->CreateTH1F("h_Proton", "all Lambda proton candidates (no MC); p (GeV/c); counts", nBins, pMin, pMax, 0); - fColl->CreateTH1F("h_mis_Electron", "all NON electron candidates MC tagged; p (GeV/c); counts", 100, 0.1, 10, 0); - fColl->CreateTH1F("h_mis_PionK0", "all NON K0 pion candidates MC tagged; p (GeV/c); counts", 100, 0.1, 10, 0); - fColl->CreateTH1F("h_mis_PionL", "all NON Lambda pion candidates MC tagged ; p (GeV/c); counts", 100, 0.1, 10, 0); - fColl->CreateTH1F("h_mis_Kaon", "all NON Kaon candidates MC tagged; p (GeV/c); counts", 100, 0.1, 10, 0); - fColl->CreateTH1F("h_mis_Proton", "all NON Lambda proton candidates MC tagged; p (GeV/c); counts", 100, 0.1, 10, 0); - - fColl->CreateTH1Fvector1(5, "h_tag_Electron", "electron candidate MC tagged; p (GeV/c); counts", 100, 0.1, 10, 0); - fColl->CreateTH1Fvector1(5, "h_tag_PionK0", "K0 pion candidate MC tagged; p (GeV/c); counts", 100, 0.1, 10, 0); - fColl->CreateTH1Fvector1(5, "h_tag_PionL", "Lambda pion candidate MC tagged; p (GeV/c); counts", 100, 0.1, 10, 0); - fColl->CreateTH1Fvector1(5, "h_tag_Kaon", "kaon candidate MC tagged; p (GeV/c); counts", 100, 0.1, 10, 0); - fColl->CreateTH1Fvector1(5, "h_tag_Proton", "Lambda proton candidate MC tagged; p (GeV/c); counts", 100, 0.1, 10, 0); + fColl->CreateTH1F("h_mis_Electron", "all NON electron candidates MC tagged; p (GeV/c); counts", nBins, pMin, pMax, 0); + fColl->CreateTH1F("h_mis_PionK0", "all NON K0 pion candidates MC tagged; p (GeV/c); counts", nBins, pMin, pMax, 0); + fColl->CreateTH1F("h_mis_PionL", "all NON Lambda pion candidates MC tagged ; p (GeV/c); counts", nBins, pMin, pMax, 0); + fColl->CreateTH1F("h_mis_Kaon", "all NON Kaon candidates MC tagged; p (GeV/c); counts", nBins, pMin, pMax, 0); + fColl->CreateTH1F("h_mis_Proton", "all NON Lambda proton candidates MC tagged; p (GeV/c); counts", nBins, pMin, pMax, 0); + + fColl->CreateTH1Fvector1(5, "h_tag_Electron", "electron candidate MC tagged; p (GeV/c); counts", nBins, pMin, pMax, 0); + fColl->CreateTH1Fvector1(5, "h_tag_PionK0", "K0 pion candidate MC tagged; p (GeV/c); counts", nBins, pMin, pMax, 0); + fColl->CreateTH1Fvector1(5, "h_tag_PionL", "Lambda pion candidate MC tagged; p (GeV/c); counts", nBins, pMin, pMax, 0); + fColl->CreateTH1Fvector1(5, "h_tag_Kaon", "kaon candidate MC tagged; p (GeV/c); counts", nBins, pMin, pMax, 0); + fColl->CreateTH1Fvector1(5, "h_tag_Proton", "Lambda proton candidate MC tagged; p (GeV/c); counts", nBins, pMin, pMax, 0); } //____________________________________________________________ diff --git a/PWG3/hfe/AliHFEcollection.cxx b/PWG3/hfe/AliHFEcollection.cxx index ae8c5e4b497..b0d57a135f2 100644 --- a/PWG3/hfe/AliHFEcollection.cxx +++ b/PWG3/hfe/AliHFEcollection.cxx @@ -49,6 +49,7 @@ AliHFEcollection::AliHFEcollection(): // fList = new THashList(); + fList->SetOwner(); if(!fList){ AliError("Initialization of the list failed"); } @@ -71,6 +72,7 @@ AliHFEcollection::AliHFEcollection(const char* name, const char* title): // fList = new THashList(); + fList->SetOwner(); fList->SetName(Form("list_%s", name)); if(!fList){ AliError("Initialization of the list failed"); @@ -125,10 +127,8 @@ AliHFEcollection::~AliHFEcollection(){ // // Destructor // - if(fList) - fList->Delete(); delete fList; - AliInfo("DESTRUCTOR"); + AliDebug(1, "DESTRUCTOR"); } //___________________________________________________________________ Bool_t AliHFEcollection::CreateTH1F(const char* name, const char* title, Int_t nBin, Float_t nMin, Float_t nMax, Int_t logAxis){ diff --git a/PWG3/hfe/AliHFEcollection.h b/PWG3/hfe/AliHFEcollection.h index 3f673b34637..5d2e4a99944 100644 --- a/PWG3/hfe/AliHFEcollection.h +++ b/PWG3/hfe/AliHFEcollection.h @@ -67,7 +67,7 @@ class AliHFEcollection : public TNamed{ Long64_t Merge(TCollection *list); // Get functions - TList* GetList() const { return fList; } + TList* GetList() const { return fList; } TObject* Get(const char* name); // Fill functions diff --git a/PWG3/hfe/AliHFEcontainer.cxx b/PWG3/hfe/AliHFEcontainer.cxx index 39dab143e92..6353b2983cb 100644 --- a/PWG3/hfe/AliHFEcontainer.cxx +++ b/PWG3/hfe/AliHFEcontainer.cxx @@ -51,6 +51,7 @@ AliHFEcontainer::AliHFEcontainer(): // Default constructor // fContainers = new THashList(); + fContainers->SetOwner(); } //__________________________________________________________________ @@ -66,6 +67,7 @@ AliHFEcontainer::AliHFEcontainer(const Char_t *name): // Default constructor // fContainers = new THashList(); + fContainers->SetOwner(); } //__________________________________________________________________ @@ -82,6 +84,7 @@ AliHFEcontainer::AliHFEcontainer(const Char_t *name, UInt_t nVar): // Setting Number of Variables too // fContainers = new THashList(); + fContainers->SetOwner(); SetNumberOfVariables(nVar); } @@ -104,6 +107,7 @@ AliHFEcontainer::AliHFEcontainer(const AliHFEcontainer &ref): fVariables->AddAt(new AliHFEvarInfo(*dynamic_cast(ref.fVariables->UncheckedAt(ivar))), ivar); } fContainers = new THashList; + fContainers->SetOwner(); AliCFContainer *ctmp = NULL; for(Int_t ien = 0; ien < ref.fContainers->GetEntries(); ien++){ ctmp = dynamic_cast(ref.fContainers->At(ien)); @@ -113,6 +117,7 @@ AliHFEcontainer::AliHFEcontainer(const AliHFEcontainer &ref): if(ref.fCorrelationMatrices){ THnSparseF *htmp = NULL; fCorrelationMatrices = new THashList; + fCorrelationMatrices->SetOwner(); for(Int_t ien = 0; ien < ref.fCorrelationMatrices->GetEntries(); ien++){ htmp = dynamic_cast(ref.fCorrelationMatrices->At(ien)); CreateCorrelationMatrix(htmp->GetName(), htmp->GetTitle()); @@ -139,7 +144,16 @@ AliHFEcontainer &AliHFEcontainer::operator=(const AliHFEcontainer &ref){ } else { fVariables = NULL; } - + // Copy also correlation matrices + if(ref.fCorrelationMatrices){ + THnSparseF *htmp = NULL; + fCorrelationMatrices = new THashList; + fCorrelationMatrices->SetOwner(); + for(Int_t ien = 0; ien < ref.fCorrelationMatrices->GetEntries(); ien++){ + htmp = dynamic_cast(ref.fCorrelationMatrices->At(ien)); + CreateCorrelationMatrix(htmp->GetName(), htmp->GetTitle()); + } + } return *this; } @@ -148,8 +162,8 @@ AliHFEcontainer::~AliHFEcontainer(){ // // Destructor // - fContainers->Delete(); delete fContainers; + if(fCorrelationMatrices) delete fCorrelationMatrices; if(fVariables){ fVariables->Delete(); delete fVariables; @@ -236,26 +250,26 @@ void AliHFEcontainer::CreateCorrelationMatrix(const Char_t *name, const Char_t * if(!fCorrelationMatrices){ fCorrelationMatrices = new THashList; fCorrelationMatrices->SetName("fCorrelationMatrices"); + fCorrelationMatrices->SetOwner(); } Int_t *nBins = new Int_t[2*fNVars]; - Double_t *binMin = new Double_t[2*fNVars]; - Double_t *binMax = new Double_t[2*fNVars]; AliHFEvarInfo *var = NULL; for(UInt_t ivar = 0; ivar < fNVars; ivar++){ var = dynamic_cast(fVariables->UncheckedAt(ivar)); nBins[ivar] = var->GetNumberOfBins(); - binMin[ivar] = var->GetBinning()[0]; - binMax[ivar] = var->GetBinning()[var->GetNumberOfBins()]; + nBins[ivar+fNVars] = var->GetNumberOfBins(); } - THnSparseF * hTmp = new THnSparseF(name, title, 2*fNVars, nBins, binMin, binMax); + THnSparseF * hTmp = new THnSparseF(name, title, 2*fNVars, nBins); for(UInt_t ivar = 0; ivar < fNVars; ivar++){ var = dynamic_cast(fVariables->UncheckedAt(ivar)); - hTmp->GetAxis(ivar)->Set(var->GetNumberOfBins(), var->GetBinning()); + hTmp->SetBinEdges(ivar,var->GetBinning()); + //hTmp->GetAxis(ivar)->Set(var->GetNumberOfBins(), var->GetBinning()); hTmp->GetAxis(ivar)->SetTitle(var->GetVarName()->Data()); - hTmp->GetAxis(ivar + fNVars)->Set(var->GetNumberOfBins(), var->GetBinning()); + //hTmp->GetAxis(ivar + fNVars)->Set(var->GetNumberOfBins(), var->GetBinning()); hTmp->GetAxis(ivar + fNVars)->SetTitle(Form("%s_{MC}", var->GetVarName()->Data())); + hTmp->SetBinEdges(ivar+fNVars,var->GetBinning()); } hTmp->Sumw2(); fCorrelationMatrices->AddLast(hTmp); @@ -278,13 +292,38 @@ THnSparseF *AliHFEcontainer::GetCorrelationMatrix(const Char_t *name) const{ } //__________________________________________________________________ -void AliHFEcontainer::FillCFContainer(const Char_t *name, UInt_t step, Double_t *content){ +void AliHFEcontainer::FillCFContainer(const Char_t *name, UInt_t step, Double_t *content, Double_t weight) const { // // Fill container // AliCFContainer *cont = GetCFContainer(name); if(!cont) return; - cont->Fill(content, step); + cont->Fill(content, step, weight); +} + +//__________________________________________________________________ +void AliHFEcontainer::FillCFContainerStepname(const Char_t *name, const Char_t *steptitle, Double_t *content, Double_t weight)const{ + // + // Fill container + // + AliCFContainer *cont = GetCFContainer(name); + if(!cont) return; + // find the matching step title + Int_t mystep = -1; + for(Int_t istep = 0; istep < cont->GetNStep(); istep++){ + TString tstept = cont->GetStepTitle(istep); + if(!tstept.CompareTo(steptitle)){ + mystep = istep; + break; + } + } + if(mystep < 0){ + // step not found + AliDebug(1, Form("Step %s not found in container %s", steptitle, name)); + return; + } + AliDebug(1, Form("Filling step %s(%d) for container %s", steptitle, mystep, name)); + cont->Fill(content, mystep, weight); } //__________________________________________________________________ @@ -326,6 +365,18 @@ AliCFContainer *AliHFEcontainer::MakeMergedCFContainer(const Char_t *name, const } return cmerged; } + +//__________________________________________________________________ +void AliHFEcontainer::SetStepTitle(const Char_t *contname, const Char_t *steptitle, UInt_t step){ + // + // Set title for given analysis step in container with name contname + // + AliCFContainer *cont = GetCFContainer(contname); + if(!cont) return; + if(step >= static_cast(cont->GetNStep())) return; + cont->SetStepTitle(step, steptitle); +} + //__________________________________________________________________ void AliHFEcontainer::MakeLinearBinning(UInt_t var, UInt_t nBins, Double_t begin, Double_t end){ // diff --git a/PWG3/hfe/AliHFEcontainer.h b/PWG3/hfe/AliHFEcontainer.h index 5c0b0bfb7e9..8abea8d63ed 100644 --- a/PWG3/hfe/AliHFEcontainer.h +++ b/PWG3/hfe/AliHFEcontainer.h @@ -58,7 +58,8 @@ class AliHFEcontainer : public TNamed{ AliCFContainer *GetCFContainer(const Char_t *name) const; THnSparseF *GetCorrelationMatrix(const Char_t *name) const; THashList *GetListOfCorrelationMatrices() const { return fCorrelationMatrices; } - void FillCFContainer(const Char_t *name, UInt_t step, Double_t *content); + void FillCFContainer(const Char_t *name, UInt_t step, Double_t *content, Double_t weight = 1.) const; + void FillCFContainerStepname(const Char_t *name, const Char_t *step, Double_t *content, Double_t weight = 1.) const; AliCFContainer *MakeMergedCFContainer(const Char_t *name, const Char_t *title, const Char_t *contnames); Int_t GetNumberOfCFContainers() const; @@ -67,10 +68,11 @@ class AliHFEcontainer : public TNamed{ void SetNumberOfVariables(UInt_t nVar); inline void SetBinning(UInt_t var, UInt_t nBins, Double_t *content); void SetVariableName(UInt_t var, const Char_t *varname); + void SetStepTitle(const Char_t *contname, const Char_t *steptitle, UInt_t step); void MakeLinearBinning(UInt_t var, UInt_t nBins, Double_t begin, Double_t end); void MakeLogarithmicBinning(UInt_t var, UInt_t nBins, Double_t begin, Double_t end); - virtual void Print(const Option_t * opt = 0x0) const; + virtual void Print(const Option_t * opt = NULL) const; struct AliHFEvarInfo : public TObject{ AliHFEvarInfo(); diff --git a/PWG3/hfe/AliHFEcutStep.h b/PWG3/hfe/AliHFEcutStep.h index 7977614cc14..918b0d23a1c 100644 --- a/PWG3/hfe/AliHFEcutStep.h +++ b/PWG3/hfe/AliHFEcutStep.h @@ -43,7 +43,7 @@ class AliHFEcutStep : public TNamed{ void SetRecEvent(AliVEvent *mc); private: - TObjArray *fCuts; + TObjArray *fCuts; // List of cuts in one cut step ClassDef(AliHFEcutStep, 1) }; diff --git a/PWG3/hfe/AliHFEcuts.cxx b/PWG3/hfe/AliHFEcuts.cxx index f9cd83e458b..29a537e55bd 100644 --- a/PWG3/hfe/AliHFEcuts.cxx +++ b/PWG3/hfe/AliHFEcuts.cxx @@ -70,17 +70,49 @@ ClassImp(AliHFEcuts) +const Char_t *AliHFEcuts::fgkMCCutName[AliHFEcuts::kNcutStepsMCTrack] = { + "MCGenerated", + "MCGeneratedZOutNoPileUp", + "MCGeneratedEventCut", + "MCInAcceptance" +}; + +const Char_t * AliHFEcuts::fgkRecoCutName[AliHFEcuts::kNcutStepsRecTrack] = { + "NoCuts", + "RecKineITSTPC", + "Primary", + "HFEITS", + "HFETRD" +}; + +const Char_t * AliHFEcuts::fgkDECutName[AliHFEcuts::kNcutStepsDETrack] = { + "HFEDCA" +}; + +const Char_t * AliHFEcuts::fgkEventCutName[AliHFEcuts::kNcutStepsEvent] = { + "EventStepGenerated", + "EventStepRecNoCut", + "EventStepRecNoPileUp", + "EventStepZRange", + "EventStepReconstructed" +}; + +const Char_t * AliHFEcuts::fgkUndefined = "Undefined"; + //__________________________________________________________________ AliHFEcuts::AliHFEcuts(): TNamed(), fRequirements(0), + fTPCiter1(kFALSE), fMinClustersTPC(0), + fMinClustersITS(0), fMinTrackletsTRD(0), fCutITSPixel(0), fCheckITSLayerStatus(kTRUE), fMaxChi2clusterTPC(0.), fMinClusterRatioTPC(0.), fSigmaToVtx(0.), + fVertexRangeZ(20.), fHistQA(0x0), fCutList(0x0), fDebugLevel(0) @@ -94,13 +126,16 @@ AliHFEcuts::AliHFEcuts(): AliHFEcuts::AliHFEcuts(const Char_t *name, const Char_t *title): TNamed(name, title), fRequirements(0), + fTPCiter1(kFALSE), fMinClustersTPC(0), + fMinClustersITS(0), fMinTrackletsTRD(0), fCutITSPixel(0), fCheckITSLayerStatus(kTRUE), fMaxChi2clusterTPC(0.), fMinClusterRatioTPC(0.), fSigmaToVtx(0.), + fVertexRangeZ(20.), fHistQA(0x0), fCutList(0x0), fDebugLevel(0) @@ -117,13 +152,16 @@ AliHFEcuts::AliHFEcuts(const Char_t *name, const Char_t *title): AliHFEcuts::AliHFEcuts(const AliHFEcuts &c): TNamed(c), fRequirements(c.fRequirements), + fTPCiter1(c.fTPCiter1), fMinClustersTPC(0), + fMinClustersITS(0), fMinTrackletsTRD(0), fCutITSPixel(0), fCheckITSLayerStatus(0), fMaxChi2clusterTPC(0), fMinClusterRatioTPC(0), fSigmaToVtx(0), + fVertexRangeZ(20.), fHistQA(0x0), fCutList(0x0), fDebugLevel(0) @@ -151,13 +189,16 @@ void AliHFEcuts::Copy(TObject &c) const { AliHFEcuts &target = dynamic_cast(c); target.fRequirements = fRequirements; + target.fTPCiter1 = fTPCiter1; target.fMinClustersTPC = fMinClustersTPC; + target.fMinClustersITS = fMinClustersITS; target.fMinTrackletsTRD = fMinTrackletsTRD; target.fCutITSPixel = fCutITSPixel; target.fCheckITSLayerStatus = fCheckITSLayerStatus; target.fMaxChi2clusterTPC = fMaxChi2clusterTPC; target.fMinClusterRatioTPC = fMinClusterRatioTPC; target.fSigmaToVtx = fSigmaToVtx; + target.fVertexRangeZ = fVertexRangeZ; target.fDebugLevel = 0; memcpy(target.fProdVtx, fProdVtx, sizeof(Double_t) * 4); @@ -214,6 +255,8 @@ void AliHFEcuts::Initialize(AliCFManager *cfm){ // Publishes the cuts to the correction framework manager // AliDebug(2, "Called"); + const Int_t kMCOffset = kNcutStepsMCTrack; + const Int_t kRecOffset = kNcutStepsRecTrack; if(fCutList) fCutList->Delete(); else{ @@ -233,6 +276,7 @@ void AliHFEcuts::Initialize(AliCFManager *cfm){ SetRecPrimaryCutList(); SetHFElectronITSCuts(); SetHFElectronTRDCuts(); + SetHFElectronDcaCuts(); // Publish to the cuts which analysis type they are (ESD Analysis by default) if(IsAOD()){ @@ -251,12 +295,15 @@ void AliHFEcuts::Initialize(AliCFManager *cfm){ cfm->SetEventCutsList(kEventStepReconstructed, dynamic_cast(fCutList->FindObject("fEvRecCuts"))); // Connect the particle cuts + // 1st MC cfm->SetParticleCutsList(kStepMCGenerated, dynamic_cast(fCutList->FindObject("fPartGenCuts"))); cfm->SetParticleCutsList(kStepMCInAcceptance, dynamic_cast(fCutList->FindObject("fPartAccCuts"))); - cfm->SetParticleCutsList(kStepRecKineITSTPC, dynamic_cast(fCutList->FindObject("fPartRecKineITSTPCCuts"))); - cfm->SetParticleCutsList(kStepRecPrim, dynamic_cast(fCutList->FindObject("fPartPrimCuts"))); - cfm->SetParticleCutsList(kStepHFEcutsITS, dynamic_cast(fCutList->FindObject("fPartHFECutsITS"))); - cfm->SetParticleCutsList(kStepHFEcutsTRD, dynamic_cast(fCutList->FindObject("fPartHFECutsTRD"))); + // 2nd Reco + cfm->SetParticleCutsList(kStepRecKineITSTPC + kMCOffset, dynamic_cast(fCutList->FindObject("fPartRecKineITSTPCCuts"))); + cfm->SetParticleCutsList(kStepRecPrim + kMCOffset, dynamic_cast(fCutList->FindObject("fPartPrimCuts"))); + cfm->SetParticleCutsList(kStepHFEcutsITS + kMCOffset, dynamic_cast(fCutList->FindObject("fPartHFECutsITS"))); + cfm->SetParticleCutsList(kStepHFEcutsTRD + kMCOffset, dynamic_cast(fCutList->FindObject("fPartHFECutsTRD"))); + cfm->SetParticleCutsList(kStepHFEcutsDca + kRecOffset + kMCOffset, dynamic_cast(fCutList->FindObject("fPartHFECutsDca"))); } @@ -281,6 +328,7 @@ void AliHFEcuts::Initialize(){ SetRecPrimaryCutList(); SetHFElectronITSCuts(); SetHFElectronTRDCuts(); + SetHFElectronDcaCuts(); } @@ -293,22 +341,24 @@ void AliHFEcuts::SetEventCutList(Int_t istep){ TObjArray *arr = new TObjArray; if(istep == kEventStepGenerated){ AliCFEventGenCuts *evGenCuts = new AliCFEventGenCuts((Char_t *)"fCutsEvGen", (Char_t *)"Event Generated cuts"); - evGenCuts->SetNTracksCut(1); + //evGenCuts->SetNTracksCut(1); evGenCuts->SetRequireVtxCuts(kTRUE); - evGenCuts->SetVertexXCut(-1, 1); - evGenCuts->SetVertexYCut(-1, 1); - evGenCuts->SetVertexZCut(-10, 10); + //evGenCuts->SetVertexXCut(-1, 1); + //evGenCuts->SetVertexYCut(-1, 1); + evGenCuts->SetVertexZCut(-fVertexRangeZ, fVertexRangeZ); if(IsQAOn()) evGenCuts->SetQAOn(fHistQA); arr->SetName("fEvGenCuts"); arr->AddLast(evGenCuts); } else { AliCFEventRecCuts *evRecCuts = new AliCFEventRecCuts((Char_t *)"fCutsEvRec", (Char_t *)"Event Reconstructed cuts"); - evRecCuts->SetNTracksCut(1); + //evRecCuts->SetNTracksCut(1); evRecCuts->SetRequireVtxCuts(kTRUE); - evRecCuts->SetVertexXCut(-1, 1); - evRecCuts->SetVertexYCut(-1, 1); - evRecCuts->SetVertexZCut(-30, 30); + //evRecCuts->SetVertexXCut(-1, 1); + //evRecCuts->SetVertexYCut(-1, 1); + //evRecCuts->SetVertexZCut(-30, 30); + evRecCuts->SetVertexZCut(-fVertexRangeZ, fVertexRangeZ); + evRecCuts->SetVertexNContributors(1,(Int_t)1.e9); if(IsQAOn()) evRecCuts->SetQAOn(fHistQA); arr->SetName("fEvRecCuts"); @@ -407,15 +457,22 @@ void AliHFEcuts::SetRecKineITSTPCCutList(){ // AliDebug(2, "Called\n"); AliCFTrackQualityCuts *trackQuality = new AliCFTrackQualityCuts((Char_t *)"fCutsQualityRec", (Char_t *)"REC Track Quality Cuts"); - trackQuality->SetMinNClusterITS(4); - trackQuality->SetMinNClusterTPC(fMinClustersTPC); + trackQuality->SetMinNClusterITS(fMinClustersITS); trackQuality->SetMaxChi2PerClusterTPC(fMaxChi2clusterTPC); trackQuality->SetStatus(AliESDtrack::kTPCrefit | AliESDtrack::kITSrefit); - trackQuality->SetMaxCovDiagonalElements(2., 2., 0.5, 0.5, 2); + //trackQuality->SetMaxCovDiagonalElements(2., 2., 0.5, 0.5, 2); AliHFEextraCuts *hfecuts = new AliHFEextraCuts("fCutsHFElectronGroupTPC","Extra cuts from the HFE group"); if(fMinClusterRatioTPC > 0.) hfecuts->SetClusterRatioTPC(fMinClusterRatioTPC); hfecuts->SetDebugLevel(fDebugLevel); + + // Set the cut in the TPC number of clusters + if(fTPCiter1){ + hfecuts->SetMinNClustersTPC(fMinClustersTPC); + hfecuts->SetTPCIter1(kTRUE); + } + else + trackQuality->SetMinNClusterTPC(fMinClustersTPC); AliCFTrackKineCuts *kineCuts = new AliCFTrackKineCuts((Char_t *)"fCutsKineRec", (Char_t *)"REC Kine Cuts"); kineCuts->SetPtRange(fPtRange[0], fPtRange[1]); @@ -503,20 +560,38 @@ void AliHFEcuts::SetHFElectronTRDCuts(){ } //__________________________________________________________________ -Bool_t AliHFEcuts::CheckParticleCuts(CutStep_t step, TObject *o){ +void AliHFEcuts::SetHFElectronDcaCuts(){ + // + // Special Cuts introduced by the HFElectron Group: minimum of impact parameter + // + AliDebug(2, "Called\n"); + AliHFEextraCuts *hfecuts = new AliHFEextraCuts("fCutsHFElectronGroupDCA","Extra cuts from the HFE group"); + hfecuts->SetMinHFEImpactParamR(); + //hfecuts->SetMinHFEImpactParamNsigmaR(); + if(IsQAOn()) hfecuts->SetQAOn(fHistQA); + hfecuts->SetDebugLevel(fDebugLevel); + + TObjArray *hfeCuts = new TObjArray; + hfeCuts->SetName("fPartHFECutsDca"); + hfeCuts->AddLast(hfecuts); + fCutList->AddLast(hfeCuts); +} + +//__________________________________________________________________ +Bool_t AliHFEcuts::CheckParticleCuts(UInt_t step, TObject *o){ // // Checks the cuts without using the correction framework manager // AliDebug(2, "Called\n"); - TString stepnames[kNcutStepsTrack] = {"fPartGenCuts","fPartSignal","fPartAccCuts","fPartRecNoCuts","fPartRecKineITSTPCCuts", "fPartPrimCuts", "fPartHFECutsITS","fPartHFECutsTRD","fPartHFEPid"}; + TString stepnames[kNcutStepsMCTrack + kNcutStepsRecTrack + kNcutStepsDETrack + 1] = {"fPartGenCuts","fPartEvCutPileupZ","fPartEvCut","fPartAccCuts","fPartRecNoCuts","fPartRecKineITSTPCCuts", "fPartPrimCuts", "fPartHFECutsITS","fPartHFECutsTRD","fPartHFECutsDca"}; + AliDebug(2, Form("Doing cut %s", stepnames[step].Data())); TObjArray *cuts = dynamic_cast(fCutList->FindObject(stepnames[step].Data())); if(!cuts) return kTRUE; - TIterator *it = cuts->MakeIterator(); + TIter it(cuts); AliCFCutBase *mycut; Bool_t status = kTRUE; - while((mycut = dynamic_cast(it->Next()))){ + while((mycut = dynamic_cast(it()))){ status &= mycut->IsSelected(o); } - delete it; return status; } diff --git a/PWG3/hfe/AliHFEcuts.h b/PWG3/hfe/AliHFEcuts.h index 4db447a027a..0f5467141d3 100644 --- a/PWG3/hfe/AliHFEcuts.h +++ b/PWG3/hfe/AliHFEcuts.h @@ -37,27 +37,33 @@ class TList; class AliHFEcuts : public TNamed{ public: + typedef enum{ + kStepRecNoCut = 0, + kStepRecKineITSTPC = 1, + kStepRecPrim = 2, + kStepHFEcutsITS = 3, + kStepHFEcutsTRD = 4, + kNcutStepsRecTrack = 5 + } RecoCutStep_t; + typedef enum{ + kStepHFEcutsDca = 0, + kNcutStepsDETrack = 1 + } DECutStep_t; typedef enum{ kStepMCGenerated = 0, - kStepMCsignal = 1, - kStepMCInAcceptance = 2, - kStepRecNoCut = 3, - kStepRecKineITSTPC = 4, - kStepRecPrim = 5, - kStepHFEcutsITS = 6, - kStepHFEcutsTRD = 7, - kStepPID = 8 - } CutStep_t; + kStepMCGeneratedZOutNoPileUp = 1, + kStepMCGeneratedEventCut = 2, + kStepMCInAcceptance = 3, + kNcutStepsMCTrack = 4 + } MCCutStep_t; typedef enum{ kEventStepGenerated = 0, kEventStepRecNoCut = 1, - kEventStepReconstructed = 2 + kEventStepRecNoPileUp = 2, + kEventStepZRange = 3, + kEventStepReconstructed = 4, + kNcutStepsEvent = 5 } EventCutStep_t; - enum{ - kNcutStepsEvent = 3, - kNcutStepsTrack = 9, - kNcutStepsESDtrack = 6 - }; // Additional constants AliHFEcuts(); AliHFEcuts(const Char_t *name, const Char_t *title); @@ -69,7 +75,7 @@ class AliHFEcuts : public TNamed{ void Initialize(AliCFManager *cfm); void Initialize(); - Bool_t CheckParticleCuts(CutStep_t step, TObject *o); + Bool_t CheckParticleCuts(UInt_t step, TObject *o); TList *GetQAhistograms() const { return fHistQA; } @@ -80,7 +86,25 @@ class AliHFEcuts : public TNamed{ void SetESD() { SetBit(kAOD, kFALSE); } Bool_t IsAOD() const { return TestBit(kAOD); } Bool_t IsESD() const { return !TestBit(kAOD); } - + + // Cut Names + static const Char_t *MCCutName(UInt_t step){ + if(step >= kNcutStepsMCTrack) return fgkUndefined; + return fgkMCCutName[step]; + }; + static const Char_t *RecoCutName(UInt_t step){ + if(step >= kNcutStepsRecTrack) return fgkUndefined; + return fgkRecoCutName[step]; + } + static const Char_t *DECutName(UInt_t step){ + if(step >= kNcutStepsDETrack) return fgkUndefined; + return fgkDECutName[step]; + } + static const Char_t *EventCutName(UInt_t step){ + if(step >= kNcutStepsEvent) return fgkUndefined; + return fgkEventCutName[step]; + } + // Getters Bool_t IsRequireITSpixel() const { return TESTBIT(fRequirements, kITSPixel); }; Bool_t IsRequireMaxImpactParam() const { return TESTBIT(fRequirements, kMaxImpactParam); }; @@ -89,11 +113,13 @@ class AliHFEcuts : public TNamed{ Bool_t IsRequireSigmaToVertex() const { return TESTBIT(fRequirements, kSigmaToVertex); }; Bool_t IsRequireDCAToVertex() const {return TESTBIT(fRequirements, kDCAToVertex); }; Bool_t IsRequireKineMCCuts() const {return TESTBIT(fRequirements, kKineMCCuts); }; + Double_t GetVertexRange() const {return fVertexRangeZ; }; // Setters inline void SetCutITSpixel(UChar_t cut); void SetCheckITSLayerStatus(Bool_t checkITSLayerStatus) { fCheckITSLayerStatus = checkITSLayerStatus; } void SetMinNClustersTPC(UChar_t minClustersTPC) { fMinClustersTPC = minClustersTPC; } + void SetMinNClustersITS(UChar_t minClustersITS) { fMinClustersITS = minClustersITS; } void SetMinNTrackletsTRD(UChar_t minNtrackletsTRD) { fMinTrackletsTRD = minNtrackletsTRD; } void SetMaxChi2perClusterTPC(Double_t chi2) { fMaxChi2clusterTPC = chi2; }; inline void SetMaxImpactParam(Double_t radial, Double_t z); @@ -101,6 +127,8 @@ class AliHFEcuts : public TNamed{ void SetPtRange(Double_t ptmin, Double_t ptmax){fPtRange[0] = ptmin; fPtRange[1] = ptmax;}; inline void SetProductionVertex(Double_t xmin, Double_t xmax, Double_t ymin, Double_t ymax); inline void SetSigmaToVertex(Double_t sig); + void SetTPCiter1(Bool_t iter1) { fTPCiter1 = iter1; } + void SetVertexRange(Double_t zrange){fVertexRangeZ = zrange;}; inline void CreateStandardCuts(); @@ -110,6 +138,7 @@ class AliHFEcuts : public TNamed{ void SetRequireITSPixel() { SETBIT(fRequirements, kITSPixel); } void SetRequireProdVertex() { SETBIT(fRequirements, kProductionVertex); }; void SetRequireSigmaToVertex() { SETBIT(fRequirements, kSigmaToVertex); CLRBIT(fRequirements, kDCAToVertex); }; + void UnsetVertexRequirement() { CLRBIT(fRequirements, kDCAToVertex); CLRBIT(fRequirements, kSigmaToVertex); } void SetRequireKineMCCuts() { SETBIT(fRequirements, kKineMCCuts); }; void SetDebugLevel(Int_t level) { fDebugLevel = level; }; @@ -135,26 +164,37 @@ class AliHFEcuts : public TNamed{ void SetRecPrimaryCutList(); void SetHFElectronITSCuts(); void SetHFElectronTRDCuts(); + void SetHFElectronDcaCuts(); void SetEventCutList(Int_t istep); + + static const Char_t* fgkMCCutName[kNcutStepsMCTrack]; // Cut step names for MC single Track cuts + static const Char_t* fgkRecoCutName[kNcutStepsRecTrack]; // Cut step names for Rec single Track cuts + static const Char_t* fgkDECutName[kNcutStepsDETrack]; // Cut step names for impact parameter cuts + static const Char_t* fgkEventCutName[kNcutStepsEvent]; // Cut step names for Event cuts + static const Char_t* fgkUndefined; // Name for undefined (overflow) ULong64_t fRequirements; // Bitmap for requirements + Bool_t fTPCiter1; // TPC iter1 Double_t fDCAtoVtx[2]; // DCA to Vertex Double_t fProdVtx[4]; // Production Vertex Double_t fPtRange[2]; // pt range UChar_t fMinClustersTPC; // Min.Number of TPC clusters + UChar_t fMinClustersITS; // Min.Number of TPC clusters UChar_t fMinTrackletsTRD; // Min. Number of TRD tracklets UChar_t fCutITSPixel; // Cut on ITS pixel Bool_t fCheckITSLayerStatus; // Check ITS layer status Double_t fMaxChi2clusterTPC; // Max Chi2 per TPC cluster Double_t fMinClusterRatioTPC; // Min. Ratio findable / found TPC clusters Double_t fSigmaToVtx; // Sigma To Vertex + Double_t fVertexRangeZ; // Vertex Range reconstructed + TList *fHistQA; //! QA Histograms TObjArray *fCutList; //! List of cut objects(Correction Framework Manager) Int_t fDebugLevel; // Debug Level - ClassDef(AliHFEcuts, 1) // Container for HFE cuts + ClassDef(AliHFEcuts, 2) // Container for HFE cuts }; //__________________________________________________________________ @@ -200,10 +240,11 @@ void AliHFEcuts::CreateStandardCuts(){ //fDCAtoVtx[0] = 0.5; //fDCAtoVtx[1] = 1.5; fMinClustersTPC = 80; + fMinClustersITS = 4; fMinTrackletsTRD = 0; SetRequireITSPixel(); fCutITSPixel = AliHFEextraCuts::kFirst; - fMaxChi2clusterTPC = 3.5; + fMaxChi2clusterTPC = 4.; fMinClusterRatioTPC = 0.6; fPtRange[0] = 0.1; fPtRange[1] = 20.; diff --git a/PWG3/hfe/AliHFEdetPIDqa.cxx b/PWG3/hfe/AliHFEdetPIDqa.cxx new file mode 100644 index 00000000000..abc55616cc2 --- /dev/null +++ b/PWG3/hfe/AliHFEdetPIDqa.cxx @@ -0,0 +1,81 @@ +/************************************************************************** +* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * +* * +* Author: The ALICE Off-line Project. * +* Contributors are mentioned in the code where appropriate. * +* * +* Permission to use, copy, modify and distribute this software and its * +* documentation strictly for non-commercial purposes is hereby granted * +* without fee, provided that the above copyright notice appears in all * +* copies and that both the copyright notice and this permission notice * +* appear in the supporting documentation. The authors make no claims * +* about the suitability of this software for any purpose. It is * +* provided "as is" without express or implied warranty. * +**************************************************************************/ +// +// Class AliHFEdetPIDqa +// Base class for detector PID QA describing the interface to the PID QA +// manager, keeping also commom functionality. The following functions have +// to be implemented by the detector PID QA classes: +// Initialize (basic initialization, i.e. histograms) +// ProcessTrack (filling of the QA container) +// The base class provides the ESD/AOD PID object for all detector PID QA +// classes +// +// Author: +// Markus Fasel +// + +#include "AliAODpidUtil.h" +#include "AliESDpid.h" + +#include "AliHFEdetPIDqa.h" + +ClassImp(AliHFEdetPIDqa) + +//____________________________________________________________ +AliHFEdetPIDqa::AliHFEdetPIDqa(): + TNamed() + , fESDpid(NULL) + , fAODpid(NULL) +{ + // + // Dummy constructor + // +} + +//____________________________________________________________ +AliHFEdetPIDqa::AliHFEdetPIDqa(const Char_t *name, const Char_t *title): + TNamed(name, title) + , fESDpid(NULL) + , fAODpid(NULL) +{ + // + // Default constructor + // +} + +//____________________________________________________________ +AliHFEdetPIDqa::AliHFEdetPIDqa(const AliHFEdetPIDqa &o): + TNamed(o) + , fESDpid(o.fESDpid) + , fAODpid(o.fAODpid) +{ + // + // Copy constructor + // +} + +//____________________________________________________________ +AliHFEdetPIDqa &AliHFEdetPIDqa::operator=(const AliHFEdetPIDqa &o){ + // + // Make assignment + // + TNamed::operator=(o); + + fESDpid = o.fESDpid; + fAODpid = o.fAODpid; + + return *this; +} + diff --git a/PWG3/hfe/AliHFEdetPIDqa.h b/PWG3/hfe/AliHFEdetPIDqa.h new file mode 100644 index 00000000000..23bcfa7873e --- /dev/null +++ b/PWG3/hfe/AliHFEdetPIDqa.h @@ -0,0 +1,59 @@ +/************************************************************************** +* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * +* * +* Author: The ALICE Off-line Project. * +* Contributors are mentioned in the code where appropriate. * +* * +* Permission to use, copy, modify and distribute this software and its * +* documentation strictly for non-commercial purposes is hereby granted * +* without fee, provided that the above copyright notice appears in all * +* copies and that both the copyright notice and this permission notice * +* appear in the supporting documentation. The authors make no claims * +* about the suitability of this software for any purpose. It is * +* provided "as is" without express or implied warranty. * +**************************************************************************/ +// +// Class AliHFEdetPIDqa +// Base class for detector PID QA describing the interface to the PID QA +// manager, keeping also commom functionality +// More information can be found inside the implementation file +// +#ifndef ALIHFEDETPIDQA_H +#define ALIHFEDETPIDQA_H + +#ifndef ROOT_TNamed +#include +#endif + +class AliAODpidUtil; +class AliESDpid; +class AliHFEpidObject; + +class AliHFEdetPIDqa : public TNamed{ + public: + enum EStep_t{ + kBeforePID = 0, + kAfterPID = 1 + }; + AliHFEdetPIDqa(); + AliHFEdetPIDqa(const Char_t *name, const Char_t *title); + AliHFEdetPIDqa(const AliHFEdetPIDqa &c); + AliHFEdetPIDqa &operator=(const AliHFEdetPIDqa &o); + ~AliHFEdetPIDqa(){} + + virtual void Initialize() = 0; + virtual void ProcessTrack(AliHFEpidObject *track, EStep_t step)= 0; + + void SetESDpid(AliESDpid *esdpid) { fESDpid = esdpid; } + void SetAODpid(AliAODpidUtil *aodpid) { fAODpid = aodpid; } + AliESDpid *GetESDpid() const { return fESDpid; } + AliAODpidUtil *GetAODpid() const { return fAODpid; } + + protected: + AliESDpid *fESDpid; //! ESD PID object + AliAODpidUtil *fAODpid; //! AOD PID object + + ClassDef(AliHFEdetPIDqa, 1) // Base class for detector PID QA +}; + +#endif diff --git a/PWG3/hfe/AliHFEefficiency.cxx b/PWG3/hfe/AliHFEefficiency.cxx index d12813349ac..54c6ec83b58 100644 --- a/PWG3/hfe/AliHFEefficiency.cxx +++ b/PWG3/hfe/AliHFEefficiency.cxx @@ -229,6 +229,9 @@ void AliHFEefficiency::FilterMC(){ } void AliHFEefficiency::Load(const char* filename){ + // + // Load results for post processing + // TFile *input = TFile::Open(filename); AliHFEcontainer *cin = dynamic_cast(input->Get("Efficiency")); fEfficiency = dynamic_cast(cin->Clone()); @@ -363,7 +366,7 @@ void AliHFEefficiency::CalculatePTsmearing(){ delete grid; } -void AliHFEefficiency::DrawPtResolution(TList *l){ +void AliHFEefficiency::DrawPtResolution(const TList * const l){ // // Draw pt resolution // diff --git a/PWG3/hfe/AliHFEefficiency.h b/PWG3/hfe/AliHFEefficiency.h index 6de6d7eff23..ff2f53a9263 100644 --- a/PWG3/hfe/AliHFEefficiency.h +++ b/PWG3/hfe/AliHFEefficiency.h @@ -53,7 +53,7 @@ class AliHFEefficiency : public AliAnalysisTaskSE{ void SetRunTerminate(Bool_t terminate = kTRUE) { SetBit(kTerminate, terminate); } void CalculatePTsmearing(); - void DrawPtResolution(TList *l); + void DrawPtResolution(const TList * const l); private: enum{ diff --git a/PWG3/hfe/AliHFEelecbackground.cxx b/PWG3/hfe/AliHFEelecbackground.cxx index 8306241e340..bb68be70b47 100644 --- a/PWG3/hfe/AliHFEelecbackground.cxx +++ b/PWG3/hfe/AliHFEelecbackground.cxx @@ -176,15 +176,17 @@ AliHFEelecbackground::~AliHFEelecbackground() if(fPIDMethodPartner) delete fPIDMethodPartner; if(fPIDMethodPartnerITS) delete fPIDMethodPartnerITS; - if(fList){ - fList->Clear(); - delete fList; - } - if(fListPostProcess){ - fListPostProcess->Clear(); + fListPostProcess->SetOwner(kTRUE); delete fListPostProcess; } + +/* + if(fhtmp) delete fhtmp; + if(fhtmpf) delete fhtmpf; + if(fhtmpp) delete fhtmpp; +*/ + } //___________________________________________________________________________________________ Bool_t AliHFEelecbackground::Load(const Char_t * filename) @@ -1222,8 +1224,8 @@ Bool_t AliHFEelecbackground::PIDTrackCut(AliESDtrack* const trackPart) if(fPIDPartner) { if(!fPIDMethodPartner) return kFALSE; AliHFEpidObject hfetrack; - hfetrack.fAnalysisType = AliHFEpidObject::kESDanalysis; - hfetrack.fRecTrack = trackPart; + hfetrack.SetAnalysisType(AliHFEpidObject::kESDanalysis); + hfetrack.SetRecTrack(trackPart); //if(HasMCData()) hfetrack.fMCtrack = mctrack; if(!fPIDMethodPartner->IsSelected(&hfetrack)) return kFALSE; @@ -1364,7 +1366,8 @@ void AliHFEelecbackground::SetPIDPartner() { if(!fPIDMethodPartner) { fPIDMethodPartner = new AliHFEpid(); - fPIDMethodPartner->InitializePID("Strategy1"); // 3 sigma cut in TPC + fPIDMethodPartner->AddDetector("TPC", 0); + fPIDMethodPartner->InitializePID(); // 3 sigma cut in TPC } } diff --git a/PWG3/hfe/AliHFEextraCuts.cxx b/PWG3/hfe/AliHFEextraCuts.cxx index 41cd38572cb..ed0e7c036e2 100644 --- a/PWG3/hfe/AliHFEextraCuts.cxx +++ b/PWG3/hfe/AliHFEextraCuts.cxx @@ -22,6 +22,7 @@ // Authors: // Markus Fasel // +#include #include #include #include @@ -29,9 +30,18 @@ #include #include +#include "AliAODTrack.h" +#include "AliAODPid.h" +#include "AliESDEvent.h" +#include "AliESDVertex.h" #include "AliESDtrack.h" #include "AliLog.h" #include "AliMCParticle.h" +#include "AliVEvent.h" +#include "AliVTrack.h" +#include "AliVParticle.h" +#include "AliVertexerTracks.h" +#include "AliVVertex.h" #include "AliHFEextraCuts.h" @@ -40,8 +50,11 @@ ClassImp(AliHFEextraCuts) //______________________________________________________ AliHFEextraCuts::AliHFEextraCuts(const Char_t *name, const Char_t *title): AliCFCutBase(name, title), + fEvent(NULL), fCutCorrelation(0), fRequirements(0), + fTPCiter1(kFALSE), + fMinNClustersTPC(0), fClusterRatioTPC(0.), fMinTrackletsTRD(0), fPixelITS(0), @@ -58,8 +71,11 @@ AliHFEextraCuts::AliHFEextraCuts(const Char_t *name, const Char_t *title): //______________________________________________________ AliHFEextraCuts::AliHFEextraCuts(const AliHFEextraCuts &c): AliCFCutBase(c), + fEvent(c.fEvent), fCutCorrelation(c.fCutCorrelation), fRequirements(c.fRequirements), + fTPCiter1(c.fTPCiter1), + fMinNClustersTPC(c.fMinNClustersTPC), fClusterRatioTPC(c.fClusterRatioTPC), fMinTrackletsTRD(c.fMinTrackletsTRD), fPixelITS(c.fPixelITS), @@ -86,9 +102,12 @@ AliHFEextraCuts &AliHFEextraCuts::operator=(const AliHFEextraCuts &c){ // if(this != &c){ AliCFCutBase::operator=(c); + fEvent = c.fEvent; fCutCorrelation = c.fCutCorrelation; fRequirements = c.fRequirements; + fTPCiter1 = c.fTPCiter1; fClusterRatioTPC = c.fClusterRatioTPC; + fMinNClustersTPC = c.fMinNClustersTPC; fMinTrackletsTRD = c.fMinTrackletsTRD; fPixelITS = c.fPixelITS; fCheck = c.fCheck; @@ -108,10 +127,25 @@ AliHFEextraCuts::~AliHFEextraCuts(){ // // Destructor // - if(fQAlist){ - fQAlist->Delete(); - delete fQAlist; + if(fQAlist) delete fQAlist; +} + +//______________________________________________________ +void AliHFEextraCuts::SetRecEventInfo(const TObject *event){ + // + // Set Virtual event an make a copy + // + if (!event) { + AliError("Pointer to AliVEvent !"); + return; + } + TString className(event->ClassName()); + if (! (className.CompareTo("AliESDEvent")==0 || className.CompareTo("AliAODEvent")==0)) { + AliError("argument must point to an AliESDEvent or AliAODEvent !"); + return ; } + fEvent = (AliVEvent*) event; + } //______________________________________________________ @@ -119,14 +153,16 @@ Bool_t AliHFEextraCuts::IsSelected(TObject *o){ // // Steering function for the track selection // - if(TString(o->IsA()->GetName()).CompareTo("AliESDtrack") == 0){ - return CheckESDCuts(dynamic_cast(o)); + TString type = o->IsA()->GetName(); + AliDebug(2, Form("Object type %s", type.Data())); + if(!type.CompareTo("AliESDtrack") || !type.CompareTo("AliAODTrack")){ + return CheckRecCuts(dynamic_cast(o)); } - return CheckMCCuts(dynamic_cast(o)); + return CheckMCCuts(dynamic_cast(o)); } //______________________________________________________ -Bool_t AliHFEextraCuts::CheckESDCuts(AliESDtrack *track){ +Bool_t AliHFEextraCuts::CheckRecCuts(AliVTrack *track){ // // Checks cuts on reconstructed tracks // returns true if track is selected @@ -135,19 +171,25 @@ Bool_t AliHFEextraCuts::CheckESDCuts(AliESDtrack *track){ // AliDebug(1, "Called"); ULong64_t survivedCut = 0; // Bitmap for cuts which are passed by the track, later to be compared with fRequirements - if(IsQAOn()) FillQAhistosESD(track, kBeforeCuts); + if(IsQAOn()) FillQAhistosRec(track, kBeforeCuts); // Apply cuts Float_t impactR, impactZ, ratioTPC; - track->GetImpactParameters(impactR, impactZ); + Double_t hfeimpactR, hfeimpactnsigmaR; + Double_t hfeimpactRcut, hfeimpactnsigmaRcut; + GetImpactParameters(track, impactR, impactZ); + if(TESTBIT(fRequirements, kMinHFEImpactParamR) || TESTBIT(fRequirements, kMinHFEImpactParamNsigmaR)){ + // Protection for PbPb + GetHFEImpactParameterCuts(track, hfeimpactRcut, hfeimpactnsigmaRcut); + GetHFEImpactParameters(track, hfeimpactR, hfeimpactnsigmaR); + } + UInt_t nTPCf = GetTPCfindableClusters(track, fTPCiter1), nclsTPC = GetTPCncls(track, fTPCiter1); // printf("Check TPC findable clusters: %d, found Clusters: %d\n", track->GetTPCNclsF(), track->GetTPCNcls()); - ratioTPC = track->GetTPCNclsF() > 0. ? static_cast(track->GetTPCNcls())/static_cast(track->GetTPCNclsF()) : 1.; + ratioTPC = nTPCf > 0. ? static_cast(nclsTPC)/static_cast(nTPCf) : 1.; UChar_t trdTracklets; - trdTracklets = track->GetTRDntrackletsPID(); + trdTracklets = GetTRDnTrackletsPID(track); UChar_t itsPixel = track->GetITSClusterMap(); - Int_t det, status1, status2; - Float_t xloc, zloc; - track->GetITSModuleIndexInfo(0, det, status1, xloc, zloc); - track->GetITSModuleIndexInfo(1, det, status2, xloc, zloc); + Int_t status1 = GetITSstatus(track, 0); + Int_t status2 = GetITSstatus(track, 1); Bool_t statusL0 = CheckITSstatus(status1); Bool_t statusL1 = CheckITSstatus(status2); if(TESTBIT(fRequirements, kMinImpactParamR)){ @@ -166,6 +208,14 @@ Bool_t AliHFEextraCuts::CheckESDCuts(AliESDtrack *track){ // cut on max. Impact Parameter in Z direction if(TMath::Abs(impactZ) <= fImpactParamCut[3]) SETBIT(survivedCut, kMaxImpactParamZ); } + if(TESTBIT(fRequirements, kMinHFEImpactParamR)){ + // cut on min. HFE Impact Parameter in Radial direction + if(TMath::Abs(hfeimpactR) >= hfeimpactRcut) SETBIT(survivedCut, kMinHFEImpactParamR); + } + if(TESTBIT(fRequirements, kMinHFEImpactParamNsigmaR)){ + // cut on max. HFE Impact Parameter n sigma in Radial direction + if(TMath::Abs(hfeimpactnsigmaR) >= hfeimpactnsigmaRcut) SETBIT(survivedCut, kMinHFEImpactParamNsigmaR); + } if(TESTBIT(fRequirements, kClusterRatioTPC)){ // cut on min ratio of found TPC clusters vs findable TPC clusters if(ratioTPC >= fClusterRatioTPC) SETBIT(survivedCut, kClusterRatioTPC); @@ -175,6 +225,11 @@ Bool_t AliHFEextraCuts::CheckESDCuts(AliESDtrack *track){ AliDebug(1, Form("Min TRD cut: [%d|%d]\n", fMinTrackletsTRD, trdTracklets)); if(trdTracklets >= fMinTrackletsTRD) SETBIT(survivedCut, kMinTrackletsTRD); } + if(TESTBIT(fRequirements, kMinNClustersTPC)){ + // cut on minimum number of TRD tracklets + AliDebug(1, Form("Min TPC cut: [%d|%d]\n", fMinNClustersTPC, nclsTPC)); + if(nclsTPC >= fMinNClustersTPC) SETBIT(survivedCut, kMinNClustersTPC); + } if(TESTBIT(fRequirements, kPixelITS)){ // cut on ITS pixel layers AliDebug(1, "ITS cluster Map: "); @@ -222,15 +277,17 @@ Bool_t AliHFEextraCuts::CheckESDCuts(AliESDtrack *track){ // // Track selected // - if(IsQAOn()) FillQAhistosESD(track, kAfterCuts); + AliDebug(2, "Track Survived cuts\n"); + if(IsQAOn()) FillQAhistosRec(track, kAfterCuts); return kTRUE; } + AliDebug(2, "Track cut"); if(IsQAOn()) FillCutCorrelation(survivedCut); return kFALSE; } //______________________________________________________ -Bool_t AliHFEextraCuts::CheckMCCuts(AliMCParticle */*track*/) const { +Bool_t AliHFEextraCuts::CheckMCCuts(AliVParticle */*track*/) const { // // Checks cuts on Monte Carlo tracks // returns true if track is selected @@ -241,21 +298,23 @@ Bool_t AliHFEextraCuts::CheckMCCuts(AliMCParticle */*track*/) const { } //______________________________________________________ -void AliHFEextraCuts::FillQAhistosESD(AliESDtrack *track, UInt_t when){ +void AliHFEextraCuts::FillQAhistosRec(AliVTrack *track, UInt_t when){ // // Fill the QA histograms for ESD tracks // Function can be called before cuts or after cut application (second argument) // - TList *container = dynamic_cast(fQAlist->At(when)); + const Int_t kNhistos = 6; Float_t impactR, impactZ; - track->GetImpactParameters(impactR, impactZ); - (dynamic_cast(container->At(0)))->Fill(impactR); - (dynamic_cast(container->At(1)))->Fill(impactZ); + GetImpactParameters(track, impactR, impactZ); + Int_t nTPCf = GetTPCfindableClusters(track, fTPCiter1), nclsTPC = GetTPCncls(track, fTPCiter1); + (dynamic_cast(fQAlist->At(0 + when * kNhistos)))->Fill(impactR); + (dynamic_cast(fQAlist->At(1 + when * kNhistos)))->Fill(impactZ); // printf("TPC findable clusters: %d, found Clusters: %d\n", track->GetTPCNclsF(), track->GetTPCNcls()); - (dynamic_cast(container->At(2)))->Fill(track->GetTPCNclsF() > 0. ? static_cast(track->GetTPCNcls())/static_cast(track->GetTPCNclsF()) : 1.); - (dynamic_cast(container->At(3)))->Fill(track->GetTRDntrackletsPID()); + (dynamic_cast(fQAlist->At(2 + when * kNhistos)))->Fill(nTPCf > 0. ? static_cast(nclsTPC)/static_cast(nTPCf) : 1.); + (dynamic_cast(fQAlist->At(3 + when * kNhistos)))->Fill(GetTRDnTrackletsPID(track)); + (dynamic_cast(fQAlist->At(4 + when * kNhistos)))->Fill(nclsTPC); UChar_t itsPixel = track->GetITSClusterMap(); - TH1 *pixelHist = dynamic_cast(container->At(4)); + TH1 *pixelHist = dynamic_cast(fQAlist->At(5 + when * kNhistos)); //Int_t firstEntry = pixelHist->GetXaxis()->GetFirst(); Double_t firstEntry = 0.5; if(!((itsPixel & BIT(0)) || (itsPixel & BIT(1)))) @@ -287,13 +346,14 @@ void AliHFEextraCuts::FillCutCorrelation(ULong64_t survivedCut){ // // Fill cut correlation histograms for tracks that didn't pass cuts // - TH2 *correlation = dynamic_cast(fQAlist->At(2)); + const Int_t kNhistos = 6; + TH2 *correlation = dynamic_cast(fQAlist->At(2 * kNhistos)); for(Int_t icut = 0; icut < kNcuts; icut++){ if(!TESTBIT(fRequirements, icut)) continue; for(Int_t jcut = icut; jcut < kNcuts; jcut++){ if(!TESTBIT(fRequirements, jcut)) continue; if(TESTBIT(survivedCut, icut) && TESTBIT(survivedCut, jcut)) - correlation->Fill(icut, jcut); + correlation->Fill(icut, jcut); } } } @@ -307,30 +367,36 @@ void AliHFEextraCuts::AddQAHistograms(TList *qaList){ // Additionally a histogram with the cut correlation is created and stored // in the top directory // - TList *histos[2]; + + const Int_t kNhistos = 6; TH1 *histo1D = 0x0; TH2 *histo2D = 0x0; - histos[0] = new TList(); - histos[0]->SetName(Form("%s_BeforeCut",GetName())); - histos[0]->SetOwner(); - histos[1] = new TList(); - histos[1]->SetName(Form("%s_AfterCut",GetName())); - histos[1]->SetOwner(); TString cutstr[2] = {"before", "after"}; + + if(!fQAlist) fQAlist = new TList; // for internal representation, not owner for(Int_t icond = 0; icond < 2; icond++){ - histos[icond]->AddAt((histo1D = new TH1F(Form("%s_impactParamR%s",GetName(),cutstr[icond].Data()), "Radial Impact Parameter", 100, 0, 10)), 0); + qaList->AddAt((histo1D = new TH1F(Form("%s_impactParamR%s",GetName(),cutstr[icond].Data()), "Radial Impact Parameter", 100, 0, 10)), 0 + icond * kNhistos); + fQAlist->AddAt(histo1D, 0 + icond * kNhistos); histo1D->GetXaxis()->SetTitle("Impact Parameter"); histo1D->GetYaxis()->SetTitle("Number of Tracks"); - histos[icond]->AddAt((histo1D = new TH1F(Form("%s_impactParamZ%s",GetName(),cutstr[icond].Data()), "Z Impact Parameter", 200, 0, 20)), 1); + qaList->AddAt((histo1D = new TH1F(Form("%s_impactParamZ%s",GetName(),cutstr[icond].Data()), "Z Impact Parameter", 200, 0, 20)), 1 + icond * kNhistos); + fQAlist->AddAt(histo1D, 1 + icond * kNhistos); histo1D->GetXaxis()->SetTitle("Impact Parameter"); histo1D->GetYaxis()->SetTitle("Number of Tracks"); - histos[icond]->AddAt((histo1D = new TH1F(Form("%s_tpcClr%s",GetName(),cutstr[icond].Data()), "Cluster Ratio TPC", 10, 0, 1)), 2); + qaList->AddAt((histo1D = new TH1F(Form("%s_tpcClr%s",GetName(),cutstr[icond].Data()), "Cluster Ratio TPC", 10, 0, 1)), 2 + icond * kNhistos); + fQAlist->AddAt(histo1D, 2 + icond * kNhistos); histo1D->GetXaxis()->SetTitle("Cluster Ratio TPC"); histo1D->GetYaxis()->SetTitle("Number of Tracks"); - histos[icond]->AddAt((histo1D = new TH1F(Form("%s_trdTracklets%s",GetName(),cutstr[icond].Data()), "Number of TRD tracklets", 7, 0, 7)), 3); + qaList->AddAt((histo1D = new TH1F(Form("%s_trdTracklets%s",GetName(),cutstr[icond].Data()), "Number of TRD tracklets", 7, 0, 7)), 3 + icond * kNhistos); + fQAlist->AddAt(histo1D, 3 + icond * kNhistos); histo1D->GetXaxis()->SetTitle("Number of TRD Tracklets"); histo1D->GetYaxis()->SetTitle("Number of Tracks"); - histos[icond]->AddAt((histo1D = new TH1F(Form("%s_itsPixel%s",GetName(),cutstr[icond].Data()), "ITS Pixel Hits", 6, 0, 6)), 4); + qaList->AddAt((histo1D = new TH1F(Form("%s_tpcClusters%s",GetName(),cutstr[icond].Data()), "Number of TPC clusters", 161, 0, 160)), 4 + icond * kNhistos); + fQAlist->AddAt(histo1D, 4 + icond * kNhistos); + histo1D->GetXaxis()->SetTitle("Number of TPC clusters"); + histo1D->GetYaxis()->SetTitle("Number of Tracks"); + qaList->AddAt((histo1D = new TH1F(Form("%s_itsPixel%s",GetName(),cutstr[icond].Data()), "ITS Pixel Hits", 6, 0, 6)), 5 + icond * kNhistos); + fQAlist->AddAt(histo1D, 5 + icond * kNhistos); histo1D->GetXaxis()->SetTitle("ITS Pixel"); histo1D->GetYaxis()->SetTitle("Number of Tracks"); Int_t first = histo1D->GetXaxis()->GetFirst(); @@ -338,20 +404,15 @@ void AliHFEextraCuts::AddQAHistograms(TList *qaList){ for(Int_t ilabel = 0; ilabel < 6; ilabel++) histo1D->GetXaxis()->SetBinLabel(first + ilabel, binNames[ilabel].Data()); } - fQAlist = new TList(); - fQAlist->SetOwner(); - fQAlist->SetName(Form("%s_HFelectronExtraCuts",GetName())); - fQAlist->AddAt(histos[0], 0); - fQAlist->AddAt(histos[1], 1); // Add cut correlation - fQAlist->AddAt((histo2D = new TH2F(Form("%s_cutcorrelation",GetName()), "Cut Correlation", kNcuts, 0, kNcuts - 1, kNcuts, 0, kNcuts -1)), 2); - TString labels[kNcuts] = {"MinImpactParamR", "MaxImpactParamR", "MinImpactParamZ", "MaxImpactParamZ", "ClusterRatioTPC", "MinTrackletsTRD", "ITSpixel"}; + qaList->AddAt((histo2D = new TH2F(Form("%s_cutcorrelation",GetName()), "Cut Correlation", kNcuts, 0, kNcuts - 1, kNcuts, 0, kNcuts -1)), 2 * kNhistos); + fQAlist->AddAt(histo2D, 2 * kNhistos); + TString labels[kNcuts] = {"MinImpactParamR", "MaxImpactParamR", "MinImpactParamZ", "MaxImpactParamZ", "ClusterRatioTPC", "MinTrackletsTRD", "ITSpixel", "kMinHFEImpactParamR", "kMinHFEImpactParamNsigmaR", "TPC Number of clusters"}; Int_t firstx = histo2D->GetXaxis()->GetFirst(), firsty = histo2D->GetYaxis()->GetFirst(); for(Int_t icut = 0; icut < kNcuts; icut++){ histo2D->GetXaxis()->SetBinLabel(firstx + icut, labels[icut].Data()); histo2D->GetYaxis()->SetBinLabel(firsty + icut, labels[icut].Data()); } - qaList->AddLast(fQAlist); } //______________________________________________________ @@ -375,3 +436,166 @@ Bool_t AliHFEextraCuts::CheckITSstatus(Int_t itsStatus) const { } return status; } + +//______________________________________________________ +Int_t AliHFEextraCuts::GetTRDnTrackletsPID(AliVTrack *track){ + // + // Get Number of TRD tracklets + // + Int_t nTracklets = 0; + if(!TString(track->IsA()->GetName()).CompareTo("AliESDtrack")){ + AliESDtrack *esdtrack = dynamic_cast(track); + nTracklets = esdtrack->GetTRDntrackletsPID(); + } else if(!TString(track->IsA()->GetName()).CompareTo("AliAODTrack")){ + AliAODTrack *aodtrack = dynamic_cast(track); + AliAODPid *pidobject = aodtrack->GetDetPid(); + // this is normally NOT the way to do this, but due to limitation in the + // AOD track it is not possible in a different way + if(pidobject){ + Float_t *trdmom = pidobject->GetTRDmomentum(); + for(Int_t ily = 0; ily < 6; ily++){ + if(trdmom[ily] > -1) nTracklets++; + } + } else nTracklets = 6; // No Cut possible + } + return nTracklets; +} + +//______________________________________________________ +Int_t AliHFEextraCuts::GetITSstatus(AliVTrack *track, Int_t layer){ + // + // Check ITS layer status + // + Int_t status = 0; + if(!TString(track->IsA()->GetName()).CompareTo("AliESDtrack")){ + Int_t det; + Float_t xloc, zloc; + AliESDtrack *esdtrack = dynamic_cast(track); + esdtrack->GetITSModuleIndexInfo(layer, det, status, xloc, zloc); + } + return status; +} + +//______________________________________________________ +Int_t AliHFEextraCuts::GetTPCfindableClusters(AliVTrack *track, Bool_t iter1){ + // + // Get Number of findable clusters in the TPC + // + AliDebug(1, Form("Using TPC clusters from iteration 1: %s", iter1 ? "Yes" : "No")); + Int_t nClusters = 159; // in case no Information available consider all clusters findable + if(!TString(track->IsA()->GetName()).CompareTo("AliESDtrack")){ + AliESDtrack *esdtrack = dynamic_cast(track); + nClusters = esdtrack->GetTPCNclsF(); + } + return nClusters; +} + +//______________________________________________________ +Int_t AliHFEextraCuts::GetTPCncls(AliVTrack *track, Bool_t iter1){ + // + // Get Number of findable clusters in the TPC + // + AliDebug(1, Form("Using TPC clusters from iteration 1: %s", iter1 ? "Yes" : "No")); + Int_t nClusters = 0; // in case no Information available consider all clusters findable + TString type = track->IsA()->GetName(); + if(!type.CompareTo("AliESDtrack")){ + AliESDtrack *esdtrack = dynamic_cast(track); + if(iter1) + nClusters = esdtrack->GetTPCNclsIter1(); + else + nClusters = esdtrack->GetTPCNcls(); + } + else if(!type.CompareTo("AliAODTrack")){ + AliAODTrack *aodtrack = dynamic_cast(track); + const TBits &tpcmap = aodtrack->GetTPCClusterMap(); + for(UInt_t ibit = 0; ibit < tpcmap.GetNbits(); ibit++) + if(tpcmap.TestBitNumber(ibit)) nClusters++; + + } + return nClusters; +} + +//______________________________________________________ +void AliHFEextraCuts::GetImpactParameters(AliVTrack *track, Float_t &radial, Float_t &z){ + // + // Get impact parameter + // + TString type = track->IsA()->GetName(); + if(!type.CompareTo("AliESDtrack")){ + AliESDtrack *esdtrack = dynamic_cast(track); + esdtrack->GetImpactParameters(radial, z); + } + else if(!type.CompareTo("AliAODTrack")){ + AliAODTrack *aodtrack = dynamic_cast(track); + Double_t xyz[3]; + aodtrack->XYZAtDCA(xyz); + z = xyz[2]; + radial = TMath::Sqrt(xyz[0]*xyz[0] + xyz[1]+xyz[1]); + } +} + +//______________________________________________________ +void AliHFEextraCuts::GetHFEImpactParameters(AliVTrack *track, Double_t &dcaxy, Double_t &dcansigmaxy){ + // + // Get HFE impact parameter (with recalculated primary vertex) + // + dcaxy=0; + dcansigmaxy=0; + if(!fEvent){ + AliDebug(1, "No Input event available\n"); + return; + } + const Double_t kBeampiperadius=3.; + TString type = track->IsA()->GetName(); + Double_t dca[2]={-999.,-999.}; + Double_t cov[3]={-999.,-999.,-999.}; + + // recalculate primary vertex + AliVertexerTracks vertexer(fEvent->GetMagneticField()); + vertexer.SetITSMode(); + vertexer.SetMinClusters(4); + Int_t skipped[2]; + skipped[0] = track->GetID(); + vertexer.SetSkipTracks(1,skipped); + AliVVertex *vtxESDSkip = vertexer.FindPrimaryVertex(fEvent); + vertexer.SetSkipTracks(1,skipped); + if(vtxESDSkip->GetNContributors()<2) return; + + // Getting the DCA + // Propagation always done on a working copy to not disturb the track params of the original track + AliESDtrack *esdtrack = NULL; + if(!TString(track->IsA()->GetName()).CompareTo("AliESDtrack")){ + // Case ESD track: take copy constructor + esdtrack = new AliESDtrack(*dynamic_cast(track)); + } else { + // Case AOD track: take different constructor + esdtrack = new AliESDtrack(track); + } + if(esdtrack->PropagateToDCA(vtxESDSkip, fEvent->GetMagneticField(), kBeampiperadius, dca, cov)){ + // protection + dcaxy = dca[0]; + if(cov[0]) dcansigmaxy = dcaxy/TMath::Sqrt(cov[0]); + if(!cov[0]) dcansigmaxy = -99.; + } + delete esdtrack; + delete vtxESDSkip; +} + + +//______________________________________________________ +void AliHFEextraCuts::GetHFEImpactParameterCuts(AliVTrack *track, Double_t &hfeimpactRcut, Double_t &hfeimpactnsigmaRcut){ + // + // Get HFE impact parameter cut(pt dependent) + // + + TString type = track->IsA()->GetName(); + if(!type.CompareTo("AliESDtrack")){ + AliESDtrack *esdtrack = dynamic_cast(track); + + Double_t pt = esdtrack->Pt(); + //hfeimpactRcut=0.0064+0.078*exp(-0.56*pt); // used Carlo's old parameter + hfeimpactRcut=0.011+0.077*exp(-0.65*pt); // used Carlo's new parameter + hfeimpactnsigmaRcut=3; // 3 sigma trail cut + } +} + diff --git a/PWG3/hfe/AliHFEextraCuts.h b/PWG3/hfe/AliHFEextraCuts.h index 58695d40bea..d912ba37027 100644 --- a/PWG3/hfe/AliHFEextraCuts.h +++ b/PWG3/hfe/AliHFEextraCuts.h @@ -26,8 +26,9 @@ class TList; -class AliESDtrack; -class AliMCParticle; +class AliVEvent; +class AliVParticle; +class AliVTrack; class AliHFEextraCuts : public AliCFCutBase{ public: @@ -45,6 +46,7 @@ class AliHFEextraCuts : public AliCFCutBase{ virtual Bool_t IsSelected(TObject *o); virtual Bool_t IsSelected(TList *) { return kTRUE; }; + virtual void SetRecEventInfo(const TObject *event); inline void SetClusterRatioTPC(Double_t ratio); inline void SetRequireITSpixel(ITSPixel_t pixel); @@ -52,7 +54,11 @@ class AliHFEextraCuts : public AliCFCutBase{ inline void SetMaxImpactParamR(Double_t impactParam); inline void SetMinImpactParamZ(Double_t impactParam); inline void SetMaxImpactParamZ(Double_t impactParam); + inline void SetMinHFEImpactParamR(); + inline void SetMinHFEImpactParamNsigmaR(); inline void SetMinTrackletsTRD(Int_t minTracklets); + inline void SetMinNClustersTPC(Int_t minclusters); + void SetTPCIter1(Bool_t tpcIter1) { fTPCiter1 = tpcIter1; } void SetCheckITSstatus(Bool_t check) { fCheck = check; }; Bool_t GetCheckITSstatus() const { return fCheck; }; @@ -62,14 +68,23 @@ class AliHFEextraCuts : public AliCFCutBase{ protected: virtual void AddQAHistograms(TList *qaList); - Bool_t CheckESDCuts(AliESDtrack *track); - Bool_t CheckMCCuts(AliMCParticle * /*track*/) const; + Bool_t CheckRecCuts(AliVTrack *track); + Bool_t CheckMCCuts(AliVParticle * /*track*/) const; Bool_t CheckITSstatus(Int_t itsStatus) const; - void FillQAhistosESD(AliESDtrack *track, UInt_t when); + void FillQAhistosRec(AliVTrack *track, UInt_t when); // void FillQAhistosMC(AliMCParticle *track, UInt_t when); void FillCutCorrelation(ULong64_t survivedCut); void PrintBitMap(Int_t bitmap); + // Getter Functions for ESD/AOD compatible mode + Int_t GetTRDnTrackletsPID(AliVTrack *track); + Int_t GetITSstatus(AliVTrack *track, Int_t layer); + Int_t GetTPCfindableClusters(AliVTrack *track, Bool_t iter1 = kFALSE); + Int_t GetTPCncls(AliVTrack *track, Bool_t iter1 = kFALSE); + void GetImpactParameters(AliVTrack *track, Float_t &radial, Float_t &z); + void GetHFEImpactParameters(AliVTrack *track, Double_t &dcaxy, Double_t &dcansigmaxy); + void GetHFEImpactParameterCuts(AliVTrack *track, Double_t &hfeimpactRcut, Double_t &hfeimpactnsigmaRcut); + private: typedef enum{ kMinImpactParamR = 0, @@ -79,7 +94,10 @@ class AliHFEextraCuts : public AliCFCutBase{ kClusterRatioTPC = 4, kMinTrackletsTRD = 5, kPixelITS = 6, - kNcuts = 7 + kMinHFEImpactParamR = 7, + kMinHFEImpactParamNsigmaR = 8, + kMinNClustersTPC = 9, + kNcuts = 10 } Cut_t; enum{ // @@ -88,9 +106,12 @@ class AliHFEextraCuts : public AliCFCutBase{ kBeforeCuts =0, kAfterCuts = 1 }; + AliVEvent *fEvent; //! working event ULong64_t fCutCorrelation; // Cut Correlation ULong64_t fRequirements; // Cut Requirements + Bool_t fTPCiter1; // Tracking iteration from which the number of clusters is taken Float_t fImpactParamCut[4]; // Impact Parmameter Cut + UInt_t fMinNClustersTPC; // Minimum TPC clusters cut Float_t fClusterRatioTPC; // Ratio of findable vs. found clusters in TPC UChar_t fMinTrackletsTRD; // Min. Number of Tracklets inside TRD UChar_t fPixelITS; // Cut on ITS Pixels @@ -138,9 +159,25 @@ void AliHFEextraCuts::SetMaxImpactParamZ(Double_t impactParam){ fImpactParamCut[3] = impactParam; } +//__________________________________________________________ +void AliHFEextraCuts::SetMinHFEImpactParamR(){ + SETBIT(fRequirements, kMinHFEImpactParamR); +} + +//__________________________________________________________ +void AliHFEextraCuts::SetMinHFEImpactParamNsigmaR(){ + SETBIT(fRequirements, kMinHFEImpactParamNsigmaR); +} + //__________________________________________________________ void AliHFEextraCuts::SetMinTrackletsTRD(Int_t minTracklets){ SETBIT(fRequirements, kMinTrackletsTRD); fMinTrackletsTRD = minTracklets; } + +//__________________________________________________________ +void AliHFEextraCuts::SetMinNClustersTPC(Int_t minClusters){ + SETBIT(fRequirements, kMinNClustersTPC); + fMinNClustersTPC = minClusters; +} #endif diff --git a/PWG3/hfe/AliHFEmcQA.cxx b/PWG3/hfe/AliHFEmcQA.cxx index c5130371f8c..87858fd4c22 100644 --- a/PWG3/hfe/AliHFEmcQA.cxx +++ b/PWG3/hfe/AliHFEmcQA.cxx @@ -165,20 +165,20 @@ void AliHFEmcQA::CreateHistograms(const Int_t kquark, Int_t icut, TString hnopt) kqTypeLabel[kElse-4]="elsee"; kqTypeLabel[kMisID-4]="miside"; } -/* - const Double_t kPtbound[2] = {0.001, 50.}; + + const Double_t kPtbound[2] = {0.1, 20.}; //bin taken for considering inclusive e analysis binning Int_t iBin[1]; - iBin[0] = 100; // bins in pt + iBin[0] = 44; // bins in pt Double_t* binEdges[1]; binEdges[0] = AliHFEtools::MakeLogarithmicBinning(iBin[0], kPtbound[0], kPtbound[1]); - */ + TString hname; if(kquark == kOthers){ for (Int_t iqType = 0; iqType < 4; iqType++ ){ hname = hnopt+"Pt_"+kqTypeLabel[iqType]; - //fHist[iq][iqType][icut].fPt = new TH1F(hname,hname+";p_{T} (GeV/c)",iBin[0],binEdges[0]); - fHist[iq][iqType][icut].fPt = new TH1F(hname,hname+";p_{T} (GeV/c)",500,0,50); + fHist[iq][iqType][icut].fPt = new TH1F(hname,hname+";p_{T} (GeV/c)",iBin[0],binEdges[0]); + //fHist[iq][iqType][icut].fPt = new TH1F(hname,hname+";p_{T} (GeV/c)",500,0,50); hname = hnopt+"Y_"+kqTypeLabel[iqType]; fHist[iq][iqType][icut].fY = new TH1F(hname,hname,150,-7.5,7.5); hname = hnopt+"Eta_"+kqTypeLabel[iqType]; @@ -193,8 +193,8 @@ void AliHFEmcQA::CreateHistograms(const Int_t kquark, Int_t icut, TString hnopt) hname = hnopt+"PdgCode_"+kqTypeLabel[iqType]; fHist[iq][iqType][icut].fPdgCode = new TH1F(hname,hname,20001,-10000.5,10000.5); hname = hnopt+"Pt_"+kqTypeLabel[iqType]; - //fHist[iq][iqType][icut].fPt = new TH1F(hname,hname+";p_{T} (GeV/c)",iBin[0],binEdges[0]); - fHist[iq][iqType][icut].fPt = new TH1F(hname,hname+";p_{T} (GeV/c)",500,0,50); + fHist[iq][iqType][icut].fPt = new TH1F(hname,hname+";p_{T} (GeV/c)",iBin[0],binEdges[0]); + //fHist[iq][iqType][icut].fPt = new TH1F(hname,hname+";p_{T} (GeV/c)",500,0,50); hname = hnopt+"Y_"+kqTypeLabel[iqType]; fHist[iq][iqType][icut].fY = new TH1F(hname,hname,150,-7.5,7.5); hname = hnopt+"Eta_"+kqTypeLabel[iqType]; @@ -366,9 +366,12 @@ void AliHFEmcQA::EndOfEventAna(const Int_t kquark) ancestorLabel[i] = 0; } + // check history of found heavy quarks for (Int_t i = 0; i < fIsHeavy[iq]; i++){ + if(!fHeavyQuark[i]) return; + ancestorLabel[0] = i; ancestorPdg[0] = fHeavyQuark[i]->GetPdgCode(); ancestorLabel[1] = fHeavyQuark[i]->GetFirstMother(); @@ -1039,7 +1042,7 @@ Int_t AliHFEmcQA::GetElecSource(TParticle * const mcpart) { // decay particle's origin - if ( abs(mcpart->GetPdgCode()) != AliHFEmcQA::kElectronPDG ) return -1; + if ( abs(mcpart->GetPdgCode()) != AliHFEmcQA::kElectronPDG ) return kMisID; Int_t origin = -1; Bool_t isFinalOpenCharm = kFALSE; diff --git a/PWG3/hfe/AliHFEpid.cxx b/PWG3/hfe/AliHFEpid.cxx index 31257d560d8..1ff61a90847 100644 --- a/PWG3/hfe/AliHFEpid.cxx +++ b/PWG3/hfe/AliHFEpid.cxx @@ -25,50 +25,63 @@ #include #include #include -#include #include #include #include #include #include +#include "AliAODpidUtil.h" #include "AliESDpid.h" -#include "AliESDtrack.h" #include "AliLog.h" #include "AliPID.h" +#include "AliVParticle.h" +#include "AliHFEcontainer.h" #include "AliHFEpid.h" #include "AliHFEpidBase.h" +#include "AliHFEpidQAmanager.h" #include "AliHFEpidITS.h" #include "AliHFEpidTPC.h" #include "AliHFEpidTRD.h" #include "AliHFEpidTOF.h" #include "AliHFEpidMC.h" +#include "AliHFEvarManager.h" ClassImp(AliHFEpid) +const Char_t* AliHFEpid::fgkDetectorName[AliHFEpid::kNdetectorPID + 1] = { + "MCPID", + "ESDPID", + "ITSPID", + "TPCPID", + "TRDPID", + "TOFPID", + "UndefinedPID" +}; + //____________________________________________________________ AliHFEpid::AliHFEpid(): TNamed(), fEnabledDetectors(0), - fPIDstrategy(kUndefined), - fQAlist(0x0), - fDebugLevel(0), + fNPIDdetectors(0), + fVarManager(NULL), fCommonObjects(NULL) { // // Default constructor // memset(fDetectorPID, 0, sizeof(AliHFEpidBase *) * kNdetectorPID); + memset(fDetectorOrder, kUndefined, sizeof(UInt_t) * kNdetectorPID); + memset(fDetectorOrder, 0, sizeof(UInt_t) * kNdetectorPID); } //____________________________________________________________ AliHFEpid::AliHFEpid(const Char_t *name): TNamed(name, ""), fEnabledDetectors(0), - fPIDstrategy(kUndefined), - fQAlist(NULL), - fDebugLevel(0), + fNPIDdetectors(0), + fVarManager(NULL), fCommonObjects(NULL) { // @@ -76,8 +89,11 @@ AliHFEpid::AliHFEpid(const Char_t *name): // Create PID objects for all detectors // memset(fDetectorPID, 0, sizeof(AliHFEpidBase *) * kNdetectorPID); + memset(fDetectorOrder, kUndefined, sizeof(UInt_t) * kNdetectorPID); + memset(fSortedOrder, 0, sizeof(UInt_t) * kNdetectorPID); + fDetectorPID[kMCpid] = new AliHFEpidMC("MCPID"); - fDetectorPID[kTPCpid] = new AliHFEpidTPC("TRDPID"); + fDetectorPID[kTPCpid] = new AliHFEpidTPC("TPCPID"); fDetectorPID[kTRDpid] = new AliHFEpidTRD("TRDPID"); fDetectorPID[kTOFpid] = new AliHFEpidTOF("TOFPID"); @@ -87,9 +103,8 @@ AliHFEpid::AliHFEpid(const Char_t *name): AliHFEpid::AliHFEpid(const AliHFEpid &c): TNamed(c), fEnabledDetectors(c.fEnabledDetectors), - fPIDstrategy(kUndefined), - fQAlist(NULL), - fDebugLevel(c.fDebugLevel), + fNPIDdetectors(c.fNPIDdetectors), + fVarManager(c.fVarManager), fCommonObjects(NULL) { // @@ -115,7 +130,6 @@ AliHFEpid::~AliHFEpid(){ // for(Int_t idet = 0; idet < kNdetectorPID; idet++) if(fDetectorPID[idet]) delete fDetectorPID[idet]; - if(fQAlist) delete fQAlist; fQAlist = NULL; // Each detector has to care about its Histograms ClearCommonObjects(); } @@ -130,13 +144,8 @@ void AliHFEpid::Copy(TObject &o) const{ target.ClearCommonObjects(); target.fEnabledDetectors = fEnabledDetectors; - target.fPIDstrategy = fPIDstrategy; - if(target.fQAlist){ - delete target.fQAlist; target.fQAlist = NULL; - } - if(fQAlist) target.fQAlist = new TList; - target.fQAlist = 0x0; - target.fDebugLevel = fDebugLevel; + target.fNPIDdetectors = fNPIDdetectors; + target.fVarManager = fVarManager; // Copy detector PIDs for(Int_t idet = 0; idet < kNdetectorPID; idet++){ @@ -146,6 +155,8 @@ void AliHFEpid::Copy(TObject &o) const{ if(fDetectorPID[idet]) target.fDetectorPID[idet] = dynamic_cast(fDetectorPID[idet]->Clone()); } + memcpy(target.fDetectorOrder, fDetectorOrder, sizeof(UInt_t) * kNdetectorPID); + memcpy(target.fSortedOrder, fSortedOrder, sizeof(UInt_t) * kNdetectorPID); } //____________________________________________________________ @@ -170,235 +181,76 @@ void AliHFEpid::ClearCommonObjects(){ } //____________________________________________________________ -Bool_t AliHFEpid::InitializePID(TString arg){ +void AliHFEpid::AddDetector(TString detector, UInt_t position){ // - // Initializes PID Object: - // + Defines which detectors to use - // + Initializes Detector PID objects - // + Handles QA + // Add Detector in position // - - Bool_t initFail = kFALSE; - if(arg.BeginsWith("Strategy")){ - // Initialize detector PIDs according to PID Strategies - arg.ReplaceAll("Strategy", ""); - fPIDstrategy = arg.Atoi(); - AliDebug(1, Form("%s - PID Strategy %d enabled", GetName(), fPIDstrategy)); - switch(fPIDstrategy){ - case 0: SwitchOnDetector(kMCpid); break; // Pure MC PID - only valid in MC mode - case 1: InitStrategy1(); break; - case 2: InitStrategy2(); break; - case 3: InitStrategy3(); break; - case 4: InitStrategy4(); break; - case 5: InitStrategy5(); break; - case 6: InitStrategy6(); break; - case 7: InitStrategy7(); break; - case 8: InitStrategy8(); break; - default: initFail = kFALSE; - } - } else { - // No Strategy defined, Initialize according to detectors specified - AliDebug(1, Form("%s - Doing InitializePID for Detectors %s end", GetName(), arg.Data())); - - TObjArray *detsEnabled = arg.Tokenize(":"); - TIterator *detIterator = detsEnabled->MakeIterator(); - TObjString *det = NULL; - Int_t detector = -1; - TString detectors[kNdetectorPID] = {"MC", "ESD", "ITS", "TPC", "TRD", "TOF"}; - Int_t nDetectors = 0; - while((det = dynamic_cast(detIterator->Next()))){ - TString &detstring = det->String(); - detector = -1; - for(Int_t idet = 0; idet < kNdetectorPID; idet++){ - if(!detstring.CompareTo(detectors[idet])){ - detector = idet; - break; - } - } - if(detector > -1){ - SwitchOnDetector(detector); - nDetectors++; - } else AliError(Form("Detector %s not implemented (yet)", detstring.Data())); - } - if(!nDetectors) initFail = kTRUE; - } - if(initFail){ - AliError("Initializaion of the PID Failed"); - return kFALSE; - } + UInt_t detectorID = kUndefined; + detector.ToUpper(); + if(!detector.CompareTo("MC")) detectorID = kMCpid; + else if(!detector.CompareTo("TPC")) detectorID = kTPCpid; + else if(!detector.CompareTo("TRD")) detectorID = kTRDpid; + else if(!detector.CompareTo("TOF")) detectorID = kTOFpid; + else AliError("Detector not available"); + if(detectorID == kUndefined) return; + if(IsDetectorOn(detectorID)) return; + SwitchOnDetector(detectorID); + fDetectorOrder[detectorID] = position; + fNPIDdetectors++; +} + +//____________________________________________________________ +Bool_t AliHFEpid::InitializePID(){ + // + // Initializes the PID object + // + + TMath::Sort(static_cast(kNdetectorPID), fDetectorOrder, fSortedOrder, kFALSE); // Initialize PID Objects Bool_t status = kTRUE; for(Int_t idet = 0; idet < kNdetectorPID; idet++){ if(!IsDetectorOn(idet)) continue; if(fDetectorPID[idet]){ status &= fDetectorPID[idet]->InitializePID(); - if(IsQAOn() && status) fDetectorPID[idet]->SetQAOn(fQAlist); if(HasMCData() && status) fDetectorPID[idet]->SetHasMCData(); } } PrintStatus(); return status; - AliDebug(1, Form("%s - Done", GetName())); } //____________________________________________________________ -Bool_t AliHFEpid::IsSelected(AliHFEpidObject *track){ +Bool_t AliHFEpid::IsSelected(AliHFEpidObject *track, AliHFEcontainer *cont, const Char_t *contname, AliHFEpidQAmanager *pidqa){ // - // Steers PID decision for single detectors respectively combined - // PID decision + // Select Tracks // - if(!track->fRecTrack){ - // MC Event - return (TMath::Abs(fDetectorPID[kMCpid]->IsSelected(track)) == 11); - } - if(fPIDstrategy < 9){ - AliDebug(1, Form("%s - PID Strategy %d", GetName(), fPIDstrategy)); - Int_t pid = 0; - switch(fPIDstrategy){ - case 0: pid = IdentifyStrategy0(track); break; - case 1: pid = IdentifyStrategy1(track); break; - case 2: pid = IdentifyStrategy2(track); break; - case 3: pid = IdentifyStrategy3(track); break; - case 4: pid = IdentifyStrategy4(track); break; - case 5: pid = IdentifyStrategy5(track); break; - case 6: pid = IdentifyStrategy6(track); break; - case 7: pid = IdentifyStrategy7(track); break; - case 8: pid = IdentifyStrategy8(track); break; - default: break; + Bool_t isSelected = kTRUE; + AliDebug(1, Form("Particle used for PID, QA available: %s", pidqa ? "Yes" : "No")); + for(UInt_t idet = 0; idet < fNPIDdetectors; idet++){ + AliDebug(2, Form("Using Detector %s\n", SortedDetectorName(idet))); + if(TMath::Abs(fDetectorPID[fSortedOrder[idet]]->IsSelected(track, pidqa)) != 11){ + isSelected = kFALSE; + break; } - return pid; - } - if(TESTBIT(fEnabledDetectors, kTPCpid)){ - if(IsQAOn() && fDebugLevel > 1){ - AliInfo("Filling QA plots"); - MakePlotsItsTpc(track); // First fill the QA histograms + AliDebug(2, "Particlae selected by detector"); + if(fVarManager && cont){ + Char_t reccontname[256]; + sprintf(reccontname, "%sReco", contname); + AliDebug(2, Form("Filling container %s", reccontname)); + if(fVarManager->IsSignalTrack()) + fVarManager->FillContainerStepname(cont, reccontname, SortedDetectorName(idet)); + if(HasMCData()){ + Char_t mccontname[256]; + sprintf(mccontname, "%sMC", contname); + AliDebug(2, Form("MC Information available, Filling container %s", mccontname)); + if(fVarManager->IsSignalTrack()) + fVarManager->FillContainerStepname(cont, mccontname, SortedDetectorName(idet), kTRUE); + } + // The PID will NOT fill the double counting information } - if(TESTBIT(fEnabledDetectors, kTOFpid)){ - // case TPC-TOF - return MakePidTpcTof(track); - } else if(TESTBIT(fEnabledDetectors, kTRDpid)){ - // case TPC-TRD with low level detector Signals - return MakePidTpcTrd(track); - } else - return (TMath::Abs(fDetectorPID[kTPCpid]->IsSelected(track)) ==11); - } else if(TESTBIT(fEnabledDetectors, kTRDpid)){ - return (TMath::Abs(fDetectorPID[kTRDpid]->IsSelected(track)) ==11); - } else if(TESTBIT(fEnabledDetectors, kTOFpid)){ - return (TMath::Abs(fDetectorPID[kTOFpid]->IsSelected(track)) ==11); - } - - return kFALSE; -} - -//____________________________________________________________ -Bool_t AliHFEpid::MakePidTpcTof(AliHFEpidObject *track){ - // - // Combines TPC and TOF PID decision - // - if(track->fAnalysisType != AliHFEpidObject::kESDanalysis) return kFALSE; - - AliHFEpidTOF *tofPID = dynamic_cast(fDetectorPID[kTOFpid]); - if(!tofPID){ - AliWarning("TOF pid object is NULL"); - return kFALSE; - } - - AliHFEpidTPC *tpcPID = dynamic_cast(fDetectorPID[kTPCpid]); - if(!tpcPID){ - AliWarning("TPC pid object is NULL"); - return kFALSE; - } - - // Use TOF PID to select particles with a sigma to the electron line > defined in initialize PID - if(TMath::Abs(tofPID->IsSelected(track)) != 11) return kFALSE; - // request TOF PID information, reject if no TOF information is available or if TOF identified as Proton or Kaon - // apply cut only up to certain upper momentum cut - /*Int_t pidTOF = tofPID->IsSelected(track); - Bool_t isRejected = kFALSE; - switch(TMath::Abs(pidTOF)){ - case 321: if(track->fRecTrack->P() < 1.5) isRejected = kTRUE; break; - case 2212: if(track->fRecTrack->P() < 3) isRejected = kTRUE; break; - case 0: if(track->fRecTrack->P() < 3) isRejected = kTRUE; break; // No TOF information available - default: break; - }; - if(isRejected) return kFALSE;*/ - - // Particle passed TOF, let TPC decide, no line crossings defined anymore - - // request the tpc PID information - return (TMath::Abs(tpcPID->IsSelected(track)) == 11); -} - -//____________________________________________________________ -Bool_t AliHFEpid::MakePidTpcTrd(AliHFEpidObject *track){ - // - // Combination of TPC and TRD PID - // Fills Histograms TPC Signal vs. TRD signal for different - // momentum slices - // - if(track->fAnalysisType != AliHFEpidObject::kESDanalysis) return kFALSE; //AOD based detector PID combination not yet implemented - AliDebug(1, "Analysis Type OK, do PID"); - AliESDtrack *esdTrack = dynamic_cast(track->fRecTrack); - AliHFEpidTRD *trdPid = dynamic_cast(fDetectorPID[kTRDpid]); - Int_t pdg = TMath::Abs(fDetectorPID[kMCpid]->IsSelected(track)); - Int_t pid = -1; - switch(pdg){ - case 11: pid = AliPID::kElectron; break; - case 13: pid = AliPID::kMuon; break; - case 211: pid = AliPID::kPion; break; - case 321: pid = AliPID::kKaon; break; - case 2212: pid = AliPID::kProton; break; - default: pid = -1; - }; - Double_t content[10]; - content[0] = pid; - content[1] = esdTrack->P(); - content[2] = esdTrack->GetTPCsignal(); - content[3] = trdPid->GetTRDSignalV1(esdTrack, pid); - if(IsQAOn() && fDebugLevel > 1){ - content[4] = trdPid->GetTRDSignalV2(esdTrack, pid); - AliDebug(1, Form("Momentum: %f, TRD Signal: Method 1[%f], Method 2[%f]", content[1], content[3], content[4])); - (dynamic_cast(fQAlist->At(kTRDSignal)))->Fill(content); - } - if(content[1] > 2){ // perform combined - AliDebug(1, "Momentum bigger 2 GeV/c, doing combined PID"); - if(content[2] > 65 && content[3] > 500) return kTRUE; - else return kFALSE; - } - else { - AliDebug(1, "Momentum smaller 2GeV/c, doing TPC alone PID"); - return fDetectorPID[kTPCpid]->IsSelected(track) == 11; - } -} - -//____________________________________________________________ -void AliHFEpid::MakePlotsItsTpc(AliHFEpidObject *track){ - // - // Make a plot ITS signal - TPC signal for several momentum bins - // - if(track->fAnalysisType != AliHFEpidObject::kESDanalysis) return; //AOD based detector PID combination not yet implemented - AliESDtrack * esdTrack = dynamic_cast(track->fRecTrack); - // Fill My Histograms for MC PID - Int_t pdg = TMath::Abs(fDetectorPID[kMCpid]->IsSelected(track)); - Int_t pid = -1; - switch(pdg){ - case 11: pid = AliPID::kElectron; break; - case 13: pid = AliPID::kMuon; break; - case 211: pid = AliPID::kPion; break; - case 321: pid = AliPID::kKaon; break; - case 2212: pid = AliPID::kProton; break; - default: pid = -1; - }; - if(IsQAOn() && fDebugLevel > 0){ - Double_t content[10]; - content[0] = pid; - content[1] = esdTrack->GetTPCInnerParam() ? esdTrack->GetTPCInnerParam()->P() : esdTrack->P(); - content[2] = (dynamic_cast(fDetectorPID[kITSpid]))->GetITSSignalV1(track->fRecTrack, pid); - content[3] = esdTrack->GetTPCsignal(); - AliDebug(1, Form("Momentum %f, TPC Signal %f, ITS Signal %f", content[1], content[2], content[3])); - (dynamic_cast(fQAlist->At(kITSSignal)))->Fill(content); } + return isSelected; } //____________________________________________________________ @@ -412,140 +264,69 @@ void AliHFEpid::SetESDpid(AliESDpid *pid){ } //____________________________________________________________ -void AliHFEpid::SetQAOn(){ - // - // Switch on QA - // - SetBit(kIsQAOn, kTRUE); - AliInfo("QA switched on"); - if(fQAlist) return; - fQAlist = new TList; - fQAlist->SetName("PIDqa"); - THnSparseF *histo = NULL; - - // Prepare axis for QA histograms - const Int_t kMomentumBins = 41; - const Double_t kPtMin = 0.1; - const Double_t kPtMax = 10.; - Double_t momentumBins[kMomentumBins]; - for(Int_t ibin = 0; ibin < kMomentumBins; ibin++) - momentumBins[ibin] = static_cast(TMath::Power(10,TMath::Log10(kPtMin) + (TMath::Log10(kPtMax)-TMath::Log10(kPtMin))/(kMomentumBins-1)*static_cast(ibin))); - - // Add Histogram for combined TPC-TRD PID - if(fDebugLevel > 1){ - AliDebug(1, "Adding histogram for ITS-TPC investigation"); - const Int_t kDimensionsTRDsig = 5; - Int_t kNbinsTRDsig[kDimensionsTRDsig] = {AliPID::kSPECIES + 1, kMomentumBins - 1, 200, 3000, 3000}; - Double_t binMinTRDsig[kDimensionsTRDsig] = {-1., 0.1, 0, 0, 0}; - Double_t binMaxTRDsig[kDimensionsTRDsig] = {AliPID::kSPECIES, 10., 200., 3000., 3000.}; - fQAlist->AddAt((histo = new THnSparseF("fCombTPCTRDpid", "Combined TPC-TRD PID", kDimensionsTRDsig, kNbinsTRDsig, binMinTRDsig, binMaxTRDsig)), kTRDSignal); - histo->GetAxis(1)->Set(kMomentumBins - 1, momentumBins); - histo->GetAxis(0)->SetTitle("Particle Species"); - histo->GetAxis(1)->SetTitle("p / GeV/c"); - histo->GetAxis(2)->SetTitle("TPC Signal / a.u."); - histo->GetAxis(3)->SetTitle("TRD Signal / a.u."); - histo->GetAxis(4)->SetTitle("TRD Signal / a.u."); - } - - // Add Histogram for combined TPC-ITS PID - if(fDebugLevel > 0){ - AliDebug(1, "Adding histogram for TPC-TRD investigation"); - const Int_t kDimensionsITSsig = 4; - Int_t kNbinsITSsig[kDimensionsITSsig] = {AliPID::kSPECIES + 1, kMomentumBins - 1, 300, 3000}; - Double_t binMinITSsig[kDimensionsITSsig] = {-1., 0.1, 0., 0.}; - Double_t binMaxITSsig[kDimensionsITSsig] = {AliPID::kSPECIES, 10., 300., 300.}; - fQAlist->AddAt((histo = new THnSparseF("fCombTPCITSpid", "Combined TPC-ITS PID", kDimensionsITSsig, kNbinsITSsig, binMinITSsig, binMaxITSsig)), kITSSignal); - histo->GetAxis(1)->Set(kMomentumBins - 1, momentumBins); - histo->GetAxis(0)->SetTitle("Particle Species"); - histo->GetAxis(1)->SetTitle("p / GeV/c"); - histo->GetAxis(2)->SetTitle("ITS Signal / a.u."); - histo->GetAxis(3)->SetTitle("TPC Signal / a.u."); - } -} - -//____________________________________________________________ -void AliHFEpid::InitStrategy1(){ +void AliHFEpid::SetAODpid(AliAODpidUtil *pid){ // - // TPC alone, 3-sigma cut + // Set ESD PID to the Detector PID objects // - AliHFEpidTPC *pid = dynamic_cast(fDetectorPID[kTPCpid]); - pid->SetTPCnSigma(1); - SwitchOnDetector(kTPCpid); + for(Int_t idet = 0; idet < kNdetectorPID; idet++){ + if(fDetectorPID[idet]) fDetectorPID[idet]->SetAODpid(pid); + } } //____________________________________________________________ -void AliHFEpid::InitStrategy2(){ +void AliHFEpid::ConfigureTPCasymmetric(Double_t pmin, Double_t pmax, Double_t sigmamin, Double_t sigmamax){ // // TPC alone, symmetric 3 sigma cut and asymmetric sigma cut in the momentum region between 2GeV/c and 10 GeV/c and sigma between -1 and 100 // AliHFEpidTPC *pid = dynamic_cast(fDetectorPID[kTPCpid]); pid->SetTPCnSigma(3); - pid->SetAsymmetricTPCsigmaCut(2., 10., 0., 4.); - SwitchOnDetector(kTPCpid); + pid->SetAsymmetricTPCsigmaCut(pmin, pmax, sigmamin, sigmamax); } //____________________________________________________________ -void AliHFEpid::InitStrategy3(){ +void AliHFEpid::ConfigureTPCrejectionSimple(){ // // TPC alone, symmetric 3 sigma cut and 2 - -100 sigma pion rejection // AliHFEpidTPC *pid = dynamic_cast(fDetectorPID[kTPCpid]); pid->SetTPCnSigma(3); pid->SetRejectParticle(AliPID::kPion, 0., -100., 10., 1.); - SwitchOnDetector(kTPCpid); } //____________________________________________________________ -void AliHFEpid::InitStrategy4(){ - // - // TPC and TRD combined, TPC 3 sigma cut and TRD NN 90% el efficiency level above 2 GeV/c - // - InitStrategy1(); - AliHFEpidTRD *trdpid = dynamic_cast(fDetectorPID[kTRDpid]); - trdpid->SetPIDMethod(AliHFEpidTRD::kLQ); - trdpid->SetElectronEfficiency(0.71); - SwitchOnDetector(kTRDpid); -} - -//____________________________________________________________ -void AliHFEpid::InitStrategy5(){ - // - // TPC and TRD combined, TPC 3 sigma cut and TRD NN 90% el efficiency level above 2 GeV/c - // - InitStrategy1(); - SwitchOnDetector(kTRDpid); -} - -//____________________________________________________________ -void AliHFEpid::InitStrategy6(){ +void AliHFEpid::ConfigureTPCrejection(){ // // Combined TPC-TOF PID, combination is discribed in the funtion MakePidTpcTof // + if(HasMCData()) printf("Configuring TPC for MC\n"); AliHFEpidTPC *tpcpid = dynamic_cast(fDetectorPID[kTPCpid]); AliHFEpidTOF *tofpid = dynamic_cast(fDetectorPID[kTOFpid]); tpcpid->SetTPCnSigma(2); tofpid->SetTOFnSigma(3); + //TF1 *upperCut = new TF1("upperCut", "[0] * TMath::Exp([1]*x)", 0, 20); TF1 *upperCut = new TF1("upperCut", "[0]", 0, 20); // Use constant upper cut TF1 *lowerCut = new TF1("lowerCut", "[0] * TMath::Exp([1]*x) + [2]", 0, 20); - upperCut->SetParameter(0, 5.); + upperCut->SetParameter(0, 3.); //upperCut->SetParameter(0, 2.7); //upperCut->SetParameter(1, -0.4357); - lowerCut->SetParameter(0, -2.65); - lowerCut->SetParameter(1, -0.8757); -// lowerCut->SetParameter(2, -1); - if(HasMCData()) lowerCut->SetParameter(2, -0.997); - else lowerCut->SetParameter(2, -0.9); + + if(HasMCData()) lowerCut->SetParameter(0, -2.5); + else lowerCut->SetParameter(0, -3.7); + + lowerCut->SetParameter(1, -0.8); + + if(HasMCData()) lowerCut->SetParameter(2, -2.2); + else lowerCut->SetParameter(2, -0.35); + tpcpid->SetUpperSigmaCut(upperCut); tpcpid->SetLowerSigmaCut(lowerCut); AddCommonObject(upperCut); AddCommonObject(lowerCut); - SwitchOnDetector(kTPCpid); - SwitchOnDetector(kTOFpid); } //____________________________________________________________ -void AliHFEpid::InitStrategy7(){ +void AliHFEpid::ConfigureTPCstrategyParis(){ // // TPC alone, symmetric 3 sigma cut and 2 - -100 sigma pion rejection // @@ -553,83 +334,6 @@ void AliHFEpid::InitStrategy7(){ pid->SetTPCnSigma(2); pid->SetRejectParticle(AliPID::kProton, 0., -3., 10., 3.); pid->SetRejectParticle(AliPID::kKaon, 0., -3., 10., 3.); - SwitchOnDetector(kTPCpid); -} - -//____________________________________________________________ -void AliHFEpid::InitStrategy8(){ - // - // TOF, TRD and TPC together - // - AliHFEpidTPC *tpcpid = dynamic_cast(fDetectorPID[kTPCpid]); - AliHFEpidTOF *tofpid = dynamic_cast(fDetectorPID[kTOFpid]); - AliHFEpidTRD *trdpid = dynamic_cast(fDetectorPID[kTRDpid]); - - tpcpid->SetTPCnSigma(3); - tofpid->SetTOFnSigma(3); - trdpid->SetPIDMethod(AliHFEpidTRD::kLQ); - trdpid->SetElectronEfficiency(0.71); - SwitchOnDetector(kTPCpid); - SwitchOnDetector(kTOFpid); - SwitchOnDetector(kTRDpid); -} - - -//____________________________________________________________ -Bool_t AliHFEpid::IdentifyStrategy0(AliHFEpidObject *track){ - return TMath::Abs(fDetectorPID[kMCpid]->IsSelected(track)) == 11; -} - -//____________________________________________________________ -Bool_t AliHFEpid::IdentifyStrategy1(AliHFEpidObject *track){ - return TMath::Abs(fDetectorPID[kTPCpid]->IsSelected(track)) == 11; -} - -//____________________________________________________________ -Bool_t AliHFEpid::IdentifyStrategy2(AliHFEpidObject *track){ - return TMath::Abs(fDetectorPID[kTPCpid]->IsSelected(track)) == 11; -} - -//____________________________________________________________ -Bool_t AliHFEpid::IdentifyStrategy3(AliHFEpidObject *track){ - return TMath::Abs(fDetectorPID[kTPCpid]->IsSelected(track)) == 11; -} - -//____________________________________________________________ -Bool_t AliHFEpid::IdentifyStrategy4(AliHFEpidObject *track){ - Int_t trdpid = TMath::Abs(fDetectorPID[kTRDpid]->IsSelected(track)); - return (trdpid == 0 || trdpid == 11) && (TMath::Abs(fDetectorPID[kTPCpid]->IsSelected(track)) == 11); -} - -//____________________________________________________________ -Bool_t AliHFEpid::IdentifyStrategy5(AliHFEpidObject *track){ - return MakePidTpcTrd(track); -} - -//____________________________________________________________ -Bool_t AliHFEpid::IdentifyStrategy6(AliHFEpidObject *track){ - return MakePidTpcTof(track); -} - -//____________________________________________________________ -Bool_t AliHFEpid::IdentifyStrategy7(AliHFEpidObject *track){ - // - // Do PID in strategy 7: Proton and Kaon rejection and - // lower cut on TPC Signal - // - if(!(TMath::Abs(fDetectorPID[kTPCpid]->IsSelected(track)) == 11)) - return kFALSE; - return kTRUE; -} - -//____________________________________________________________ -Bool_t AliHFEpid::IdentifyStrategy8(AliHFEpidObject *track){ - // - // Identify TPC, TRD, TOF - // - if(TMath::Abs(fDetectorPID[kTOFpid]->IsSelected(track)) != 11) return kFALSE; - Int_t trdpid = TMath::Abs(fDetectorPID[kTRDpid]->IsSelected(track)); - return (trdpid == 0 || trdpid == 11) && (TMath::Abs(fDetectorPID[kTPCpid]->IsSelected(track)) == 11); } //____________________________________________________________ @@ -639,7 +343,6 @@ void AliHFEpid::PrintStatus() const { // printf("\n%s: Printing configuration\n", GetName()); printf("===============================================\n"); - printf("PID Strategy: %d\n", fPIDstrategy); printf("PID Detectors: \n"); Int_t npid = 0; TString detectors[kNdetectorPID] = {"MC", "ESD", "ITS", "TPC", "TRD", "TOF"}; diff --git a/PWG3/hfe/AliHFEpid.h b/PWG3/hfe/AliHFEpid.h index 6dd0d8c4567..ea568cdc55d 100644 --- a/PWG3/hfe/AliHFEpid.h +++ b/PWG3/hfe/AliHFEpid.h @@ -30,9 +30,12 @@ #include +class AliAODpidUtil; class AliESDpid; -class AliESDtrack; +class AliHFEcontainer; class AliHFEpidBase; +class AliHFEpidQAmanager; +class AliHFEvarManager; class AliVParticle; class AliMCParticle; @@ -43,7 +46,7 @@ class AliHFEpid : public TNamed{ enum{ kUndefined = UINT_MAX }; - enum DETtype_t { + enum EDETtype_t { kMCpid = 0, kESDpid = 1, kITSpid = 2, @@ -59,46 +62,39 @@ class AliHFEpid : public TNamed{ void Copy(TObject &o) const; ~AliHFEpid(); - Bool_t InitializePID(TString argument); - Bool_t IsSelected(AliHFEpidObject *track); + Bool_t InitializePID(); + Bool_t IsSelected(AliHFEpidObject *track, AliHFEcontainer *cont = NULL, const Char_t *contname = "trackContainer", AliHFEpidQAmanager *qa = NULL); - Bool_t IsQAOn() const { return TestBit(kIsQAOn); }; Bool_t HasMCData() const { return TestBit(kHasMCData); }; + + void AddDetector(TString detector, UInt_t position); void SetESDpid(AliESDpid *pid); - void SetDebugLevel(Int_t debugLevel) { fDebugLevel = debugLevel; } - void SetQAOn(); + void SetAODpid(AliAODpidUtil *pid); + void SetVarManager(AliHFEvarManager *vm) { fVarManager = vm; } void SetHasMCData(Bool_t hasMCdata = kTRUE) { SetBit(kHasMCData, hasMCdata); }; - TList *GetQAhistograms() const { return fQAlist; }; - AliHFEpidBase *GetDetPID(DETtype_t det) const { return det < kNdetectorPID ? fDetectorPID[det] : NULL; } + + UInt_t GetNumberOfPIDdetectors() const { return fNPIDdetectors; } + Bool_t HasDetector(EDETtype_t det) const { return IsDetectorOn(det); } + AliHFEpidBase *GetDetPID(EDETtype_t det) const { return det < kNdetectorPID ? fDetectorPID[det] : NULL; } + void PrintStatus() const; + const Char_t *SortedDetectorName(Int_t det) const { + if(det < kNdetectorPID) return fgkDetectorName[fSortedOrder[det]]; + else return fgkDetectorName[kNdetectorPID + 1]; + } + //-----Configure PID detectors with predefined stettings------ + void ConfigureTPCasymmetric(Double_t pmin = 0.1, Double_t pmax = 20., Double_t sigmamin = -0.2, Double_t sigmamax = 5.); + void ConfigureTPCrejectionSimple(); + void ConfigureTPCrejection(); + void ConfigureTPCstrategyParis(); + //------------------------------------------------------------ protected: Bool_t MakePidTpcTof(AliHFEpidObject *track); - Bool_t MakePidTpcTrd(AliHFEpidObject *track); - void MakePlotsItsTpc(AliHFEpidObject *track); - - // Stratgies - void InitStrategy1(); - void InitStrategy2(); - void InitStrategy3(); - void InitStrategy4(); - void InitStrategy5(); - void InitStrategy6(); - void InitStrategy7(); - void InitStrategy8(); - Bool_t IdentifyStrategy0(AliHFEpidObject *track); - Bool_t IdentifyStrategy1(AliHFEpidObject *track); - Bool_t IdentifyStrategy2(AliHFEpidObject *track); - Bool_t IdentifyStrategy3(AliHFEpidObject *track); - Bool_t IdentifyStrategy4(AliHFEpidObject *track); - Bool_t IdentifyStrategy5(AliHFEpidObject *track); - Bool_t IdentifyStrategy6(AliHFEpidObject *track); - Bool_t IdentifyStrategy7(AliHFEpidObject *track); - Bool_t IdentifyStrategy8(AliHFEpidObject *track); + private: enum{ - kIsQAOn = BIT(14), - kHasMCData = BIT(15) + kHasMCData = BIT(14) }; enum{ kCombinedTPCTRD=0 @@ -122,12 +118,14 @@ class AliHFEpid : public TNamed{ } //-------------------------------------------------- - AliHFEpidBase *fDetectorPID[kNdetectorPID]; //! Detector PID classes - UInt_t fEnabledDetectors; // Enabled Detectors - UInt_t fPIDstrategy; // PID Strategy - TList *fQAlist; //! QA histograms - Int_t fDebugLevel; // Debug Level - TObjArray *fCommonObjects; // Garbage Collector + static const Char_t *fgkDetectorName[kNdetectorPID + 1]; // PID Detector Names + AliHFEpidBase *fDetectorPID[kNdetectorPID]; // Detector PID classes + UInt_t fDetectorOrder[kNdetectorPID]; // Position requested by the user + UInt_t fSortedOrder[kNdetectorPID]; // Sorted array of detectorIDs + UInt_t fEnabledDetectors; // Enabled Detectors + UInt_t fNPIDdetectors; // Number of PID detectors + AliHFEvarManager *fVarManager; //! HFE Var Manager + TObjArray *fCommonObjects; // Garbage Collector ClassDef(AliHFEpid, 1) // Steering class for Electron ID }; diff --git a/PWG3/hfe/AliHFEpidBase.cxx b/PWG3/hfe/AliHFEpidBase.cxx index 2da8eb52a69..6ba2e4bd782 100644 --- a/PWG3/hfe/AliHFEpidBase.cxx +++ b/PWG3/hfe/AliHFEpidBase.cxx @@ -20,8 +20,11 @@ // Authors: // Markus Fasel // + +#include "AliAODpidUtil.h" #include "AliESDpid.h" #include "AliHFEpidBase.h" +#include "AliHFEtools.h" ClassImp(AliHFEpidBase) @@ -29,7 +32,7 @@ ClassImp(AliHFEpidBase) AliHFEpidBase::AliHFEpidBase(): TNamed(), fESDpid(NULL), - fDebugLevel(0) + fAODpid(NULL) { // // Default constructor @@ -40,7 +43,7 @@ AliHFEpidBase::AliHFEpidBase(): AliHFEpidBase::AliHFEpidBase(const Char_t *name): TNamed(name, ""), fESDpid(NULL), - fDebugLevel(0) + fAODpid(NULL) { // // Default constructor @@ -51,7 +54,7 @@ AliHFEpidBase::AliHFEpidBase(const Char_t *name): AliHFEpidBase::AliHFEpidBase(const AliHFEpidBase &c): TNamed(), fESDpid(NULL), - fDebugLevel(0) + fAODpid(NULL) { // //Copy constructor @@ -79,8 +82,30 @@ void AliHFEpidBase::Copy(TObject &ref) const { AliHFEpidBase &target = dynamic_cast(ref); target.fESDpid = fESDpid; - target.fDebugLevel = fDebugLevel; + target.fAODpid = fAODpid; TNamed::Copy(ref); } +//___________________________________________________________________ +AliHFEpidObject &AliHFEpidObject::operator=(const AliHFEpidObject &ref){ + // + // Assignment operator + // + if(&ref != this){ + fkRecTrack = ref.fkRecTrack; + fAnalysisType = ref.fAnalysisType; + fAbInitioPID = ref.fAbInitioPID; + fCentrality = ref.fCentrality; + } + return *this; +} + +//___________________________________________________________________ +void AliHFEpidObject::SetMCTrack(const AliVParticle *mctrack){ + // + // Set the aprioriPID information coming from the MC truth + // + if(mctrack) fAbInitioPID = AliHFEtools::PDG2AliPID(AliHFEtools::GetPdg(mctrack)); +} + diff --git a/PWG3/hfe/AliHFEpidBase.h b/PWG3/hfe/AliHFEpidBase.h index 99670098a4d..720e8fb8218 100644 --- a/PWG3/hfe/AliHFEpidBase.h +++ b/PWG3/hfe/AliHFEpidBase.h @@ -24,19 +24,52 @@ #endif class TList; +class AliAODpidUtil; class AliESDpid; class AliVParticle; class AliMCParticle; +class AliHFEpidQAmanager; -struct AliHFEpidObject{ +class AliHFEpidObject{ + public: typedef enum{ kESDanalysis, kAODanalysis }AnalysisType_t; - AliVParticle *fRecTrack; // Reconstructed track - AliVParticle *fMCtrack; // Monte Carlo track + AliHFEpidObject(): + fkRecTrack(NULL), + fAnalysisType(kESDanalysis), + fAbInitioPID(-1), + fCentrality(99.) + { + } + AliHFEpidObject(const AliHFEpidObject &ref): + fkRecTrack(ref.fkRecTrack), + fAnalysisType(ref.fAnalysisType), + fAbInitioPID(ref.fAbInitioPID), + fCentrality(ref.fCentrality) + { + } + AliHFEpidObject &operator=(const AliHFEpidObject &ref); + ~AliHFEpidObject(){}; + + void SetRecTrack(const AliVParticle * recTrack) {fkRecTrack = recTrack; } + void SetMCTrack(const AliVParticle * mcTrack); + void SetAnalysisType(AnalysisType_t type) { fAnalysisType = type; } + void SetAbInitioPID(Int_t abInitioPID) { fAbInitioPID = abInitioPID; } + void SetCentrality(Float_t centrality) { fCentrality = centrality; } + + const AliVParticle *GetRecTrack() const { return fkRecTrack; } + Int_t GetAbInitioPID() const { return fAbInitioPID; } + Float_t GetCentrality() const { return fCentrality; } + Bool_t IsAODanalysis() const { return fAnalysisType == static_cast(kAODanalysis); } + Bool_t IsESDanalysis() const { return fAnalysisType == static_cast(kESDanalysis); } + + private: + const AliVParticle *fkRecTrack; // Reconstructed track UChar_t fAnalysisType; // Analysis Mode (ESD or AOD) - AliHFEpidObject():fRecTrack(NULL), fMCtrack(NULL), fAnalysisType(kESDanalysis){} + Int_t fAbInitioPID; // AbInitio PID + Float_t fCentrality; // Centrality Information }; class AliHFEpidBase : public TNamed{ @@ -48,41 +81,24 @@ class AliHFEpidBase : public TNamed{ virtual ~AliHFEpidBase() {}; // Framework functions that have to be implemented by the detector PID classes virtual Bool_t InitializePID() = 0; - virtual Int_t IsSelected(AliHFEpidObject *track) = 0; - virtual Bool_t HasQAhistos() const = 0; + virtual Int_t IsSelected(AliHFEpidObject *track, AliHFEpidQAmanager *pidqa = NULL) = 0; - Int_t GetDebugLevel() const { return fDebugLevel; }; - Bool_t IsQAon() const { return TestBit(kQAon);}; Bool_t HasMCData() const { return TestBit(kHasMCData); }; void SetESDpid(AliESDpid * const pid) { fESDpid = pid; } - void SetDebugLevel(Int_t debugLevel) { fDebugLevel = debugLevel; }; - inline void SetQAOn(TList *fQAlist); + void SetAODpid(AliAODpidUtil * const pid) { fAODpid = pid; } void SetHasMCData(Bool_t hasMCdata = kTRUE) { SetBit(kHasMCData,hasMCdata); }; protected: AliESDpid *fESDpid; // ESD PID object + AliAODpidUtil *fAODpid; // AOD PID object void Copy(TObject &ref) const; - virtual void AddQAhistograms(TList *){}; + private: enum{ - kQAon = BIT(14), - kHasMCData = BIT(15) + kHasMCData = BIT(14) }; - Int_t fDebugLevel; // Debug Level - - ClassDef(AliHFEpidBase, 1) // Base class for detector Electron ID + ClassDef(AliHFEpidBase, 2) // Base class for detector Electron ID }; - -//___________________________________________________________________ -void AliHFEpidBase::SetQAOn(TList *qaList){ - // - // Initialize QA for Detector PID class - // - if(HasQAhistos()){ - SetBit(kQAon, kTRUE); - AddQAhistograms(qaList); - } -} #endif diff --git a/PWG3/hfe/AliHFEpidITS.cxx b/PWG3/hfe/AliHFEpidITS.cxx index ecd215c75c6..8b9bc84cd87 100644 --- a/PWG3/hfe/AliHFEpidITS.cxx +++ b/PWG3/hfe/AliHFEpidITS.cxx @@ -34,10 +34,11 @@ #include "AliHFEpidITS.h" +ClassImp(AliHFEpidITS) + //___________________________________________________________________ AliHFEpidITS::AliHFEpidITS(const Char_t *name): AliHFEpidBase(name) - , fQAlist(0x0) { // // Default constructor @@ -47,7 +48,6 @@ AliHFEpidITS::AliHFEpidITS(const Char_t *name): //___________________________________________________________________ AliHFEpidITS::AliHFEpidITS(const AliHFEpidITS &ref): AliHFEpidBase("") - , fQAlist(0x0) { // // Copy constructor @@ -69,10 +69,6 @@ AliHFEpidITS::~AliHFEpidITS(){ // // Destructor // - if(fQAlist){ - fQAlist->Clear(); - delete fQAlist; - } } //___________________________________________________________________ @@ -81,10 +77,7 @@ void AliHFEpidITS::Copy(TObject &o) const { // Copy function // Provides a deep copy // - AliHFEpidITS &target = dynamic_cast(o); - - target.fQAlist = dynamic_cast(fQAlist->Clone()); - AliHFEpidBase::Copy(target); + AliHFEpidBase::Copy(o); } //___________________________________________________________________ @@ -97,7 +90,7 @@ Bool_t AliHFEpidITS::InitializePID(){ //___________________________________________________________________ -Int_t AliHFEpidITS::IsSelected(AliHFEpidObject* /*track*/){ +Int_t AliHFEpidITS::IsSelected(AliHFEpidObject* /*track*/, AliHFEpidQAmanager* /*pidqa*/){ // // Does PID decision for ITS // @@ -105,42 +98,11 @@ Int_t AliHFEpidITS::IsSelected(AliHFEpidObject* /*track*/){ } //___________________________________________________________________ -void AliHFEpidITS::AddQAhistograms(TList *l){ - // - // Adding QA histograms for ITS PID - // - // QA histograms are: - // - all Particles ITS signal vs. p (both methods) - // - single particle ITS signal vs. p (both methods) - // - if(!fQAlist) fQAlist = new TList; - fQAlist->SetName("fITSqaHistograms"); - - // prepare axis - const Int_t kMomentumBins = 41; - const Double_t kPtMin = 0.1; - const Double_t kPtMax = 10.; - const Int_t kSigBins = 300; - Double_t momentumBins[kMomentumBins]; - for(Int_t ibin = 0; ibin < kMomentumBins; ibin++) - momentumBins[ibin] = static_cast(TMath::Power(10,TMath::Log10(kPtMin) + (TMath::Log10(kPtMax)-TMath::Log10(kPtMin))/(kMomentumBins-1)*static_cast(ibin))); - - TH2 *histo = NULL; - fQAlist->AddAt((histo = new TH2F("fITSsigV1all", "ITS signal vs. p (all species, Method1):p / GeV/c:ITS signal / a.u.", kMomentumBins - 1, momentumBins, kSigBins, 0., kSigBins)), kITSsigV1); - fQAlist->AddAt((histo = new TH2F("fITSsigV2all", "ITS signal vs. p (all species, Method2):p / GeV/c:ITS signal / a.u.", kMomentumBins - 1, momentumBins, kSigBins, 0., kSigBins)), kITSsigV2); - for(Int_t ispec = 0; ispec < AliPID::kSPECIES; ispec++){ - fQAlist->AddAt((histo = new TH2F(Form("fITSsigV1%s", AliPID::ParticleName(ispec)), Form("ITS signal vs. p (%s, Method1):p / GeV/c:ITS signal / a.u.", AliPID::ParticleName(ispec)), kMomentumBins - 1, momentumBins, kSigBins, 0., kSigBins)), 2 * ispec + kHistosSigAll); - fQAlist->AddAt((histo = new TH2F(Form("fITSsigV2%s", AliPID::ParticleName(ispec)), Form("ITS signal vs. p (%s, Method2):p / GeV/c:ITS signal / a.u.", AliPID::ParticleName(ispec)), kMomentumBins - 1, momentumBins, kSigBins, 0., kSigBins)), 2 * ispec + 1 + kHistosSigAll); - } - l->Add(fQAlist); -} - -//___________________________________________________________________ -Double_t AliHFEpidITS::GetITSSignalV1(AliVParticle *vtrack, Int_t mcPID){ +Double_t AliHFEpidITS::GetITSSignalV1(AliVParticle *vtrack){ // // Calculate the ITS signal according to the mean charge of the clusters // - if(!TString(vtrack->IsA()->GetName()).CompareTo("AliAODtrack")){ + if(!TString(vtrack->IsA()->GetName()).CompareTo("AliAODTrack")){ AliError("PID for AODs not implemented yet"); return 0.; } @@ -155,16 +117,15 @@ Double_t AliHFEpidITS::GetITSSignalV1(AliVParticle *vtrack, Int_t mcPID){ #endif Double_t p = track->GetTPCInnerParam() ? track->GetTPCInnerParam()->P() : track->P(); AliDebug(1, Form("Momentum: %f, ITS Signal: %f", p, signal)); - if(IsQAon()) FillHistogramsSignalV1(p, signal, mcPID); return signal; } //___________________________________________________________________ -Double_t AliHFEpidITS::GetITSSignalV2(AliVParticle *vtrack, Int_t mcPID){ +Double_t AliHFEpidITS::GetITSSignalV2(AliVParticle *vtrack){ // // Calculates the ITS signal. Truncated mean is used. // - if(!TString(vtrack->IsA()->GetName()).CompareTo("AliAODtrack")){ + if(!TString(vtrack->IsA()->GetName()).CompareTo("AliAODTrack")){ AliError("PID for AODs not implemented yet"); return 0.; } @@ -177,21 +138,6 @@ Double_t AliHFEpidITS::GetITSSignalV2(AliVParticle *vtrack, Int_t mcPID){ Double_t signal = TMath::Mean(3, dedx); Double_t p = track->GetTPCInnerParam() ? track->GetTPCInnerParam()->P() : track->P(); AliDebug(1, Form("Momentum: %f, ITS Signal: %f", p, signal)); - if(IsQAon()) FillHistogramsSignalV2(p, signal, mcPID); return signal; } -//___________________________________________________________________ -void AliHFEpidITS::FillHistogramsSignalV1(Double_t p, Double_t signal, Int_t species){ - (dynamic_cast(fQAlist->At(kITSsigV1)))->Fill(p, signal); - if(species >= 0 && species < AliPID::kSPECIES) - (dynamic_cast(fQAlist->At(kHistosSigAll + 2 * species)))->Fill(p, signal); -} - -//___________________________________________________________________ -void AliHFEpidITS::FillHistogramsSignalV2(Double_t p, Double_t signal, Int_t species){ - (dynamic_cast(fQAlist->At(kITSsigV2)))->Fill(p, signal); - if(species >= 0 && species < AliPID::kSPECIES) - (dynamic_cast(fQAlist->At(kHistosSigAll + 2 * species + 1)))->Fill(p, signal); -} - diff --git a/PWG3/hfe/AliHFEpidITS.h b/PWG3/hfe/AliHFEpidITS.h index 7bfd9d1a7bf..55c1db6849c 100644 --- a/PWG3/hfe/AliHFEpidITS.h +++ b/PWG3/hfe/AliHFEpidITS.h @@ -24,7 +24,7 @@ #endif class AliVParticle; -class TList; +class AliHFEpidQAmanager; class AliHFEpidITS : public AliHFEpidBase{ public: @@ -34,23 +34,17 @@ class AliHFEpidITS : public AliHFEpidBase{ virtual ~AliHFEpidITS(); virtual Bool_t InitializePID(); - virtual Int_t IsSelected(AliHFEpidObject *track); - virtual Bool_t HasQAhistos() const { return kTRUE; }; + virtual Int_t IsSelected(AliHFEpidObject *track, AliHFEpidQAmanager *pidqa); - Double_t GetITSSignalV1(AliVParticle *track, Int_t mcPID); - Double_t GetITSSignalV2(AliVParticle *track, Int_t mcPID); + Double_t GetITSSignalV1(AliVParticle *track); + Double_t GetITSSignalV2(AliVParticle *track); protected: - virtual void AddQAhistograms(TList *l); void Copy(TObject &o) const; - void FillHistogramsSignalV1(Double_t p, Double_t signal, Int_t species); - void FillHistogramsSignalV2(Double_t p, Double_t signal, Int_t species); private: enum{ kITSsigV1 = 0, - kITSsigV2 = 1, - kHistosSigAll = 2 + kITSsigV2 = 1 }; - TList *fQAlist; // QA histograms for ITS pid ClassDef(AliHFEpidITS, 0) // PID class for ITS }; diff --git a/PWG3/hfe/AliHFEpidMC.cxx b/PWG3/hfe/AliHFEpidMC.cxx index 36fc56c1856..2ce9e70faa5 100644 --- a/PWG3/hfe/AliHFEpidMC.cxx +++ b/PWG3/hfe/AliHFEpidMC.cxx @@ -28,15 +28,25 @@ //#include "AliVParticle.h" #include "AliHFEpidMC.h" +#include "AliHFEtools.h" ClassImp(AliHFEpidMC) +//___________________________________________________________________ +AliHFEpidMC::AliHFEpidMC(): + AliHFEpidBase() +{ + // + // Default constructor + // +} + //___________________________________________________________________ AliHFEpidMC::AliHFEpidMC(const Char_t *name): AliHFEpidBase(name) { // - // Default constructor + // Standard constructor // } @@ -50,20 +60,11 @@ Bool_t AliHFEpidMC::InitializePID(){ } //___________________________________________________________________ -Int_t AliHFEpidMC::IsSelected(AliHFEpidObject *track){ +Int_t AliHFEpidMC::IsSelected(AliHFEpidObject *track, AliHFEpidQAmanager * /*pidqa*/){ // // returns MC PDG Code // Functionality implemented in the base class // (necessary for PID QA) // - if(track->fAnalysisType == AliHFEpidObject::kESDanalysis){ - AliMCParticle *mc = dynamic_cast(track->fMCtrack); - if(!mc) return 0; - return mc->Particle()->GetPdgCode(); - } - else{ - AliAODMCParticle *aodmc = dynamic_cast(track->fMCtrack); - if(!aodmc) return 0; - return aodmc->GetPdgCode(); - } + return AliHFEtools::GetPdg(track->GetRecTrack()); } diff --git a/PWG3/hfe/AliHFEpidMC.h b/PWG3/hfe/AliHFEpidMC.h index 9299883c12d..843eee59ccc 100644 --- a/PWG3/hfe/AliHFEpidMC.h +++ b/PWG3/hfe/AliHFEpidMC.h @@ -24,14 +24,16 @@ #include "AliHFEpidBase.h" #endif +class AliHFEpidQAmanager; + class AliHFEpidMC : public AliHFEpidBase{ public: + AliHFEpidMC(); AliHFEpidMC(const Char_t *name); virtual ~AliHFEpidMC(){}; virtual Bool_t InitializePID(); - virtual Int_t IsSelected(AliHFEpidObject *track); - virtual Bool_t HasQAhistos() const { return kFALSE; }; + virtual Int_t IsSelected(AliHFEpidObject *track, AliHFEpidQAmanager *pidqa); private: diff --git a/PWG3/hfe/AliHFEpidQA.cxx b/PWG3/hfe/AliHFEpidQA.cxx index f0bdf822545..66020385e3e 100644 --- a/PWG3/hfe/AliHFEpidQA.cxx +++ b/PWG3/hfe/AliHFEpidQA.cxx @@ -49,6 +49,7 @@ #include "AliHFEV0info.h" #include "AliHFEV0pid.h" #include "AliHFEV0pidMC.h" +#include "AliHFEV0cuts.h" #include "AliHFEtrdPIDqa.h" @@ -155,8 +156,9 @@ void AliHFEpidQA::Init(){ // Prepare task output // + // load networks if(fNNref){ - for(Int_t mom = 0; mom < 11; mom++){ // load networks + for(Int_t mom = 0; mom < 11; mom++){ fNet[mom] = (TMultiLayerPerceptron*) fNNref->Get(Form("NN_Mom%d", mom)); if(!fNet[mom]){ AliError(Form("No reference network for momentum bin %d!", mom)); @@ -164,7 +166,7 @@ void AliHFEpidQA::Init(){ } } - fV0pid = new AliHFEV0pid; + fV0pid = new AliHFEV0pid(); if(HasV0pidQA()) fV0pid->InitQA(); fV0pidMC = new AliHFEV0pidMC(); fV0pidMC->Init(); @@ -276,6 +278,7 @@ void AliHFEpidQA::Init(){ } // TRD THnSparse - entries per tracklet // species, p, tracklet position, number of PID tracklets, number of slices (non 0), number of clusters, electron likelihood, + { Int_t nbins[7] = {5, 20, 6, 7, 9, 45, 100}; Double_t min[7] = {-0.5, 0.5, -0.5, -0.5, -0.5, -0.5, 0.}; @@ -307,7 +310,9 @@ void AliHFEpidQA::Process(){ AliError("AliVEvent not available, returning"); } + if(fMC) fV0pidMC->SetMCEvent(fMC); + if(fMC) fV0pid->SetMCEvent(fMC); fV0pid->Process(fEvent); TObjArray *hfeelectrons = fV0pid->GetListOfElectrons(); @@ -323,10 +328,10 @@ void AliHFEpidQA::Process(){ TObjArray *cleanElectrons = MakeCleanListElectrons(hfeelectrons); if(fMC){ - fV0pidMC->Process(electrons, AliHFEV0pid::kRecoElectron); - fV0pidMC->Process(pionsK0, AliHFEV0pid::kRecoPionK0); - fV0pidMC->Process(pionsL, AliHFEV0pid::kRecoPionL); - fV0pidMC->Process(protons, AliHFEV0pid::kRecoProton); + fV0pidMC->Process(electrons, AliHFEV0cuts::kRecoElectron); + fV0pidMC->Process(pionsK0, AliHFEV0cuts::kRecoPionK0); + fV0pidMC->Process(pionsL, AliHFEV0cuts::kRecoPionL); + fV0pidMC->Process(protons, AliHFEV0cuts::kRecoProton); } AliDebug(2, Form("Number of Electrons : %d", electrons->GetEntries())); @@ -336,20 +341,20 @@ void AliHFEpidQA::Process(){ if(fMC){ AliDebug(2, "MC Information available. Doing Purity checks..."); // Calculate the purity of the clean samples using MC - MakePurity(electrons, AliHFEV0pid::kRecoElectron); - MakePurity(pionsK0, AliHFEV0pid::kRecoPionK0); - MakePurity(pionsL, AliHFEV0pid::kRecoPionL); - MakePurity(protons, AliHFEV0pid::kRecoProton); + MakePurity(electrons, AliHFEV0cuts::kRecoElectron); + MakePurity(pionsK0, AliHFEV0cuts::kRecoPionK0); + MakePurity(pionsL, AliHFEV0cuts::kRecoPionL); + MakePurity(protons, AliHFEV0cuts::kRecoProton); } // some event wise checks CheckEvent(); // Make Illumination Plot - FillIllumination(electrons, AliHFEV0pid::kRecoElectron); - FillIllumination(pionsK0, AliHFEV0pid::kRecoPionK0); - FillIllumination(pionsL, AliHFEV0pid::kRecoPionL); - FillIllumination(protons, AliHFEV0pid::kRecoProton); + FillIllumination(electrons, AliHFEV0cuts::kRecoElectron); + FillIllumination(pionsK0, AliHFEV0cuts::kRecoPionK0); + FillIllumination(pionsL, AliHFEV0cuts::kRecoPionL); + FillIllumination(protons, AliHFEV0cuts::kRecoProton); // Now we can do studies on the PID itself // For TRD use the TRD PID QA object @@ -358,21 +363,21 @@ void AliHFEpidQA::Process(){ fTRDpidQA->ProcessTracks(pionsL, AliPID::kPion); fTRDpidQA->ProcessTracks(protons, AliPID::kProton); - FillElectronLikelihoods(electrons, AliHFEV0pid::kRecoElectron); - FillElectronLikelihoods(pionsK0, AliHFEV0pid::kRecoPionK0); - FillElectronLikelihoods(pionsL, AliHFEV0pid::kRecoPionL); - FillElectronLikelihoods(protons, AliHFEV0pid::kRecoProton); + FillElectronLikelihoods(electrons, AliHFEV0cuts::kRecoElectron); + FillElectronLikelihoods(pionsK0, AliHFEV0cuts::kRecoPionK0); + FillElectronLikelihoods(pionsL, AliHFEV0cuts::kRecoPionL); + FillElectronLikelihoods(protons, AliHFEV0cuts::kRecoProton); - FillPIDresponse(electrons, AliHFEV0pid::kRecoElectron); - FillPIDresponse(pionsK0, AliHFEV0pid::kRecoPionK0); - FillPIDresponse(pionsL, AliHFEV0pid::kRecoPionL); - FillPIDresponse(protons, AliHFEV0pid::kRecoProton); + FillPIDresponse(electrons, AliHFEV0cuts::kRecoElectron); + FillPIDresponse(pionsK0, AliHFEV0cuts::kRecoPionK0); + FillPIDresponse(pionsL, AliHFEV0cuts::kRecoPionL); + FillPIDresponse(protons, AliHFEV0cuts::kRecoProton); // check the tender V0s - CheckTenderV0pid(electrons, AliHFEV0pid::kRecoElectron); - CheckTenderV0pid(pionsK0, AliHFEV0pid::kRecoPionK0); - CheckTenderV0pid(pionsL, AliHFEV0pid::kRecoPionL); - CheckTenderV0pid(protons, AliHFEV0pid::kRecoProton); + CheckTenderV0pid(electrons, AliHFEV0cuts::kRecoElectron); + CheckTenderV0pid(pionsK0, AliHFEV0cuts::kRecoPionK0); + CheckTenderV0pid(pionsL, AliHFEV0cuts::kRecoPionL); + CheckTenderV0pid(protons, AliHFEV0cuts::kRecoProton); // Analysis done, flush the containers fV0pid->Flush(); @@ -385,7 +390,7 @@ void AliHFEpidQA::Process(){ } //__________________________________________ -void AliHFEpidQA::FillIllumination(TObjArray * const tracks, Int_t species){ +void AliHFEpidQA::FillIllumination(const TObjArray * const tracks, Int_t species){ // // Fill Illumination Plot // @@ -450,7 +455,7 @@ void AliHFEpidQA::FillTPCinfo(AliESDtrack *const esdtrack, Int_t species){ } //__________________________________________ -void AliHFEpidQA::MakePurity(TObjArray *tracks, Int_t species){ +void AliHFEpidQA::MakePurity(const TObjArray *tracks, Int_t species){ // // Fill the QA histos for a given species // @@ -460,16 +465,16 @@ void AliHFEpidQA::MakePurity(TObjArray *tracks, Int_t species){ Char_t hname[256]; switch(species){ - case AliHFEV0pid::kRecoElectron: + case AliHFEV0cuts::kRecoElectron: sprintf(hname, "purityElectron"); break; - case AliHFEV0pid::kRecoPionK0: + case AliHFEV0cuts::kRecoPionK0: sprintf(hname, "purityPionK0"); break; - case AliHFEV0pid::kRecoPionL: + case AliHFEV0cuts::kRecoPionL: sprintf(hname, "purityPionL"); break; - case AliHFEV0pid::kRecoProton: + case AliHFEV0cuts::kRecoProton: sprintf(hname, "purityProton"); break; default: // non investigated species @@ -510,7 +515,7 @@ void AliHFEpidQA::MakePurity(TObjArray *tracks, Int_t species){ } //__________________________________________ -void AliHFEpidQA::FillElectronLikelihoods(TObjArray * const particles, Int_t species){ +void AliHFEpidQA::FillElectronLikelihoods(const TObjArray * const particles, Int_t species){ // // Fill electron Likelihoods for the ITS, TPC and TOF // Required for the calculation of the electron efficiency, @@ -521,16 +526,16 @@ void AliHFEpidQA::FillElectronLikelihoods(TObjArray * const particles, Int_t spe Char_t specname[256]; switch(species){ - case AliHFEV0pid::kRecoElectron: + case AliHFEV0cuts::kRecoElectron: sprintf(specname, "Electron"); break; - case AliHFEV0pid::kRecoPionK0: + case AliHFEV0cuts::kRecoPionK0: sprintf(specname, "PionK0"); break; - case AliHFEV0pid::kRecoPionL: + case AliHFEV0cuts::kRecoPionL: sprintf(specname, "PionL"); break; - case AliHFEV0pid::kRecoProton: + case AliHFEV0cuts::kRecoProton: sprintf(specname, "Proton"); break; default: @@ -605,7 +610,7 @@ void AliHFEpidQA::FillElectronLikelihoods(TObjArray * const particles, Int_t spe }//.. while tracks } //__________________________________________ -void AliHFEpidQA::FillPIDresponse(TObjArray * const particles, Int_t species){ +void AliHFEpidQA::FillPIDresponse(const TObjArray * const particles, Int_t species){ // // Fill the PID response of different detectors to V0 daughter particles // @@ -950,7 +955,7 @@ Float_t AliHFEpidQA::TOFbeta(AliESDtrack * const track) const { return beta; } //____________________________________________ -Int_t AliHFEpidQA::GetMaxPID(Double_t *pidProbs) const { +Int_t AliHFEpidQA::GetMaxPID(const Double_t *pidProbs) const { // // return the index of maximal PID probability // @@ -973,16 +978,16 @@ Int_t AliHFEpidQA::GetPDG(Int_t species){ Int_t pdg = 0; switch(species){ - case AliHFEV0pid::kRecoElectron: + case AliHFEV0cuts::kRecoElectron: pdg = TMath::Abs(kElectron); break; - case AliHFEV0pid::kRecoPionK0: + case AliHFEV0cuts::kRecoPionK0: pdg = TMath::Abs(kPiPlus); break; - case AliHFEV0pid::kRecoPionL: + case AliHFEV0cuts::kRecoPionL: pdg = TMath::Abs(kPiPlus); break; - case AliHFEV0pid::kRecoProton: + case AliHFEV0cuts::kRecoProton: pdg = TMath::Abs(kProton); break; default: // non investigated species @@ -995,7 +1000,7 @@ Int_t AliHFEpidQA::GetPDG(Int_t species){ } //_____________________________________________ -TObjArray * AliHFEpidQA::MakeTrackList(TObjArray *tracks) const { +TObjArray * AliHFEpidQA::MakeTrackList(const TObjArray *tracks) const { // // convert list of AliHFEV0Info into a list of AliVParticle // @@ -1009,7 +1014,7 @@ TObjArray * AliHFEpidQA::MakeTrackList(TObjArray *tracks) const { } //_____________________________________________ -TObjArray * AliHFEpidQA::MakeCleanListElectrons(TObjArray *electrons) const { +TObjArray * AliHFEpidQA::MakeCleanListElectrons(const TObjArray *electrons) const { // // Cleanup electron sample using TPC PID // PID requirement will allways be implemented to the pair @@ -1021,9 +1026,9 @@ TObjArray * AliHFEpidQA::MakeCleanListElectrons(TObjArray *electrons) const { AliHFEV0info *hfetrack; // const Double_t kSigmaTight = 1.; // const Double_t kSigmaLoose = 4.; - const Double_t kSigmaTight = 0.5; - const Double_t kSigmaLoose = 0.5; - const Double_t shift = 1.; + const Double_t kSigmaTight = 2.; + const Double_t kSigmaLoose = 2.; + const Double_t shift = 0.57; if((esd = dynamic_cast(fEvent))){ AliESDtrack *track = NULL, *partnerTrack = NULL; while((hfetrack = dynamic_cast(candidates()))){ @@ -1046,7 +1051,7 @@ TObjArray * AliHFEpidQA::MakeCleanListElectrons(TObjArray *electrons) const { return tracks; } //___________________________________________________________ -void AliHFEpidQA::CheckTenderV0pid(TObjArray * const particles, Int_t species){ +void AliHFEpidQA::CheckTenderV0pid(const TObjArray * const particles, Int_t species){ // // retrieve the status bits from the TObject used to flag @@ -1167,7 +1172,7 @@ Double_t AliHFEpidQA::TRDlikeTracklet(Int_t layer, AliESDtrack * const track, Do return sum; } //__________________________________________________________________________ -Int_t AliHFEpidQA::TRDmomBin(Double_t p){ +const Int_t AliHFEpidQA::TRDmomBin(Double_t p){ // // compute the momentum bin position // diff --git a/PWG3/hfe/AliHFEpidQA.h b/PWG3/hfe/AliHFEpidQA.h index 9c2c2b21a9a..cde8b86f5c8 100644 --- a/PWG3/hfe/AliHFEpidQA.h +++ b/PWG3/hfe/AliHFEpidQA.h @@ -90,25 +90,25 @@ class AliHFEpidQA : public TObject{ kTOF = 3 }; - TObjArray *MakeTrackList(TObjArray *tracks) const; - TObjArray *MakeCleanListElectrons(TObjArray *tracks) const; - - void MakePurity(TObjArray *tracks, Int_t species); - TObjArray *MakeCleanListForTRD(TObjArray * const track, Int_t species); - void FillElectronLikelihoods(TObjArray * const particles, Int_t species); - void FillPIDresponse(TObjArray * const particles, Int_t species); - void FillIllumination(TObjArray *const particles, Int_t species); + TObjArray *MakeTrackList(const TObjArray *tracks) const; + TObjArray *MakeCleanListElectrons(const TObjArray *tracks) const; + + void MakePurity(const TObjArray *tracks, Int_t species); + TObjArray *MakeCleanListForTRD(const TObjArray * const track, Int_t species); + void FillElectronLikelihoods(const TObjArray * const particles, Int_t species); + void FillPIDresponse(const TObjArray * const particles, Int_t species); + void FillIllumination(const TObjArray *const particles, Int_t species); void FillTPCinfo(AliESDtrack * const track, Int_t species); void RecalculateTRDpid(AliESDtrack *track, Double_t *pidProbs) const; void RecalculateTRDpid(AliAODTrack *track, Double_t *pidProbs) const; - void CheckTenderV0pid(TObjArray * const particles, Int_t species); + void CheckTenderV0pid(const TObjArray * const particles, Int_t species); Int_t GetTenderV0pid(AliESDtrack * const track); Double_t TRDlikeTracklet(Int_t layer, AliESDtrack * const track, Double_t *likelihood); - Int_t TRDmomBin(Double_t p); + const Int_t TRDmomBin(Double_t p); protected: - Int_t GetMaxPID(Double_t *pidProbs) const; + Int_t GetMaxPID(const Double_t *pidProbs) const; Int_t GetPDG(Int_t index); private: diff --git a/PWG3/hfe/AliHFEpidQAmanager.cxx b/PWG3/hfe/AliHFEpidQAmanager.cxx new file mode 100644 index 00000000000..66abec4c1cb --- /dev/null +++ b/PWG3/hfe/AliHFEpidQAmanager.cxx @@ -0,0 +1,178 @@ +/************************************************************************** +* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * +* * +* Author: The ALICE Off-line Project. * +* Contributors are mentioned in the code where appropriate. * +* * +* Permission to use, copy, modify and distribute this software and its * +* documentation strictly for non-commercial purposes is hereby granted * +* without fee, provided that the above copyright notice appears in all * +* copies and that both the copyright notice and this permission notice * +* appear in the supporting documentation. The authors make no claims * +* about the suitability of this software for any purpose. It is * +* provided "as is" without express or implied warranty. * +**************************************************************************/ +// +// Class AliHFEpidQAmanager +// Does steering of the PID QA. The PID QA manager is initialized according +// to the configuration used for PID. It contains PID objects inheriting +// from AliHFEdetPIDqa, which are +// AliHFEtpcPIDqa +// AliHFEtrdPIDqaV1 +// AliHFEtofPIDqa +// PID QA objects are filled for every detector before PID decision and +// after PID decision for tracks which are selected by the given detector +// as electron candidates. +// +// Author +// Markus Fasel +// +#include + +#include "AliAODpidUtil.h" +#include "AliESDpid.h" +#include "AliVParticle.h" + +#include "AliHFEtpcPIDqa.h" +#include "AliHFEtrdPIDqaV1.h" +#include "AliHFEtofPIDqa.h" +#include "AliHFEpidQAmanager.h" + +ClassImp(AliHFEpidQAmanager) + +//____________________________________________________________ +AliHFEpidQAmanager::AliHFEpidQAmanager(): + TObject() +{ + // + // Dummy constructor + // + memset(fDetPIDqa, 0, sizeof(AliHFEdetPIDqa *) * AliHFEpid::kNdetectorPID); + SetOwner(); +} + +//____________________________________________________________ +AliHFEpidQAmanager::AliHFEpidQAmanager(const AliHFEpidQAmanager &ref): + TObject(ref) +{ + // + // Copy constructor + // + ref.Copy(*this); + SetOwner(); +} + +//____________________________________________________________ +AliHFEpidQAmanager &AliHFEpidQAmanager::operator=(const AliHFEpidQAmanager &ref){ + // + // Assignment operator + // + if(this != &ref) ref.Copy(*this); + SetOwner(); + return *this; +} + +//____________________________________________________________ +void AliHFEpidQAmanager::Copy(TObject &o) const{ + // + // Make copy + // + TObject::Copy(o); + AliHFEpidQAmanager &target = dynamic_cast(o); + + for(Int_t idet = 0; idet < AliHFEpid::kNdetectorPID; idet++){ + if(target.fDetPIDqa[idet]) delete target.fDetPIDqa[idet]; + if(fDetPIDqa[idet]) target.CreateDetPIDqa(static_cast(idet)); + } +} + +//____________________________________________________________ +AliHFEpidQAmanager::~AliHFEpidQAmanager(){ + // + // Destructor + // + if(IsOwner()) + for(Int_t idet = 0; idet < AliHFEpid::kNdetectorPID; idet++){ + if(fDetPIDqa[idet]) delete fDetPIDqa[idet]; + } +} + +//____________________________________________________________ +void AliHFEpidQAmanager::Initialize(AliHFEpid *pid){ + // + // Initialize PID QA manager according to the detector + // configuration used in the PID + // + for(Int_t idet = 0; idet < AliHFEpid::kNdetectorPID; idet++) + if(pid->HasDetector(static_cast(idet))){ + CreateDetPIDqa(static_cast(idet)); + fDetPIDqa[idet]->Initialize(); + } +} + +//____________________________________________________________ +void AliHFEpidQAmanager::CreateDetPIDqa(AliHFEpid::EDETtype_t idet){ + // + // Create new PID QA object + // + switch(idet){ + case AliHFEpid::kTPCpid: + fDetPIDqa[idet] = new AliHFEtpcPIDqa("TPCQA"); + break; + case AliHFEpid::kTRDpid: + fDetPIDqa[idet] = new AliHFEtrdPIDqaV1("TRDQA"); + break; + case AliHFEpid::kTOFpid: + fDetPIDqa[idet] = new AliHFEtofPIDqa("TOFQA"); + break; + default: + break; + }; +} + +//____________________________________________________________ +void AliHFEpidQAmanager::ProcessTrack(AliHFEpidObject *track, AliHFEpid::EDETtype_t det, AliHFEdetPIDqa::EStep_t step){ + // + // Process single Track + // + if(!fDetPIDqa[det]){ + AliDebug(1, Form("QA for detector %d not available", det)); + return; + } + AliDebug(1, Form("Doing QA for detector %d\n", det)); + fDetPIDqa[det]->ProcessTrack(track, step); +} + +//____________________________________________________________ +TList *AliHFEpidQAmanager::MakeList(const Char_t *name){ + // + // Make List of PID QA objects + // + TList *list = new TList; + list->SetName(name); + list->SetOwner(); + for(Int_t idet = 0; idet < AliHFEpid::kNdetectorPID; idet++){ + if(fDetPIDqa[idet]) list->Add(fDetPIDqa[idet]); + } + ReleaseOwnerShip(); + return list; +} + +//____________________________________________________________ +void AliHFEpidQAmanager::SetESDpid(AliESDpid *esdpid){ + // + // Publish ESD PID + // + for(Int_t idet = 0; idet < AliHFEpid::kNdetectorPID; idet++) + if(fDetPIDqa[idet]) fDetPIDqa[idet]->SetESDpid(esdpid); +} + +//____________________________________________________________ +void AliHFEpidQAmanager::SetAODpid(AliAODpidUtil *aodpid){ + // + // Publish AOD PID + // + for(Int_t idet = 0; idet < AliHFEpid::kNdetectorPID; idet++) + if(fDetPIDqa[idet]) fDetPIDqa[idet]->SetAODpid(aodpid); +} + diff --git a/PWG3/hfe/AliHFEpidQAmanager.h b/PWG3/hfe/AliHFEpidQAmanager.h new file mode 100644 index 00000000000..1e6d6e0399e --- /dev/null +++ b/PWG3/hfe/AliHFEpidQAmanager.h @@ -0,0 +1,71 @@ +/************************************************************************** +* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * +* * +* Author: The ALICE Off-line Project. * +* Contributors are mentioned in the code where appropriate. * +* * +* Permission to use, copy, modify and distribute this software and its * +* documentation strictly for non-commercial purposes is hereby granted * +* without fee, provided that the above copyright notice appears in all * +* copies and that both the copyright notice and this permission notice * +* appear in the supporting documentation. The authors make no claims * +* about the suitability of this software for any purpose. It is * +* provided "as is" without express or implied warranty. * +**************************************************************************/ +// +// Class AliHFEpidQAmanager +// Steering PID QA +// More information can be found inside the implementation file +// +#ifndef ALIHFEPIDQAMANAGER_H +#define ALIHFEPIDQAMANAGER_H + +#ifndef ROOT_TObject +#include +#endif + +#ifndef ALIHFEPID_H +#include "AliHFEpid.h" +#endif + +#ifndef ALIHFEDETPIDQA_H +#include "AliHFEdetPIDqa.h" +#endif + +class TList; +class AliVParticle; +class AliESDpid; +class AliAODpidUtil; +class AliHFEpidObject; + +class AliHFEpidQAmanager : public TObject{ + public: + AliHFEpidQAmanager(); + AliHFEpidQAmanager(const AliHFEpidQAmanager &ref); + AliHFEpidQAmanager &operator=(const AliHFEpidQAmanager &ref); + void Copy(TObject &o) const; + ~AliHFEpidQAmanager(); + + void Initialize(AliHFEpid *pid); + void ProcessTrack(AliHFEpidObject *track, AliHFEpid::EDETtype_t det, AliHFEdetPIDqa::EStep_t step); + AliHFEdetPIDqa *GetDetectorPIDqa(AliHFEpid::EDETtype_t detector) const { return fDetPIDqa[detector]; } + TList *MakeList(const Char_t *name); + + void SetESDpid(AliESDpid *esdpid); + void SetAODpid(AliAODpidUtil *aodpid); + + protected: + enum{ + kIsOwner = BIT(14) + }; + Bool_t IsOwner() const { return TestBit(kIsOwner); } + void SetOwner() { SetBit(kIsOwner, kTRUE); } + void ReleaseOwnerShip() { SetBit(kIsOwner, kFALSE); } + void CreateDetPIDqa(AliHFEpid::EDETtype_t detector); + + private: + AliHFEdetPIDqa *fDetPIDqa[AliHFEpid::kNdetectorPID]; //! + + ClassDef(AliHFEpidQAmanager, 0) +}; +#endif diff --git a/PWG3/hfe/AliHFEpidTOF.cxx b/PWG3/hfe/AliHFEpidTOF.cxx index 38ac77f4e75..9f749b164f2 100644 --- a/PWG3/hfe/AliHFEpidTOF.cxx +++ b/PWG3/hfe/AliHFEpidTOF.cxx @@ -22,41 +22,47 @@ // Matus Kalisky (contact) // -#include #include -#include -#include +#include "AliAODpidUtil.h" #include "AliAODTrack.h" -#include "AliAODMCParticle.h" +#include "AliESDpid.h" #include "AliESDtrack.h" -#include "AliMCParticle.h" #include "AliPID.h" -#include "AliESDpid.h" -#include "AliHFEcollection.h" +#include "AliHFEdetPIDqa.h" #include "AliHFEpidTOF.h" -#include "AliHFEpidBase.h" +#include "AliHFEpidQAmanager.h" ClassImp(AliHFEpidTOF) - + +//___________________________________________________________________ +AliHFEpidTOF::AliHFEpidTOF(): + AliHFEpidBase() + , fPID(NULL) + , fNsigmaTOF(3) +{ + // + // Constructor + // +} + //___________________________________________________________________ AliHFEpidTOF::AliHFEpidTOF(const Char_t *name): AliHFEpidBase(name) - , fPID(0x0) - , fQAList(0x0) + , fPID(NULL) , fNsigmaTOF(3) { // // Constructor // } + //___________________________________________________________________ AliHFEpidTOF::AliHFEpidTOF(const AliHFEpidTOF &c): AliHFEpidBase("") - , fPID(0x0) - , fQAList(0x0) + , fPID(NULL) , fNsigmaTOF(3) { // @@ -83,10 +89,6 @@ AliHFEpidTOF::~AliHFEpidTOF(){ // Destructor // if(fPID) delete fPID; - if(fQAList){ - fQAList->Delete(); - delete fQAList; - } } //___________________________________________________________________ void AliHFEpidTOF::Copy(TObject &ref) const { @@ -96,7 +98,6 @@ void AliHFEpidTOF::Copy(TObject &ref) const { AliHFEpidTOF &target = dynamic_cast(ref); target.fPID = fPID; - target.fQAList = fQAList; target.fNsigmaTOF = fNsigmaTOF; AliHFEpidBase::Copy(ref); @@ -110,313 +111,47 @@ Bool_t AliHFEpidTOF::InitializePID(){ } //___________________________________________________________________ -Int_t AliHFEpidTOF::IsSelected(AliHFEpidObject *vtrack) +Int_t AliHFEpidTOF::IsSelected(AliHFEpidObject *track, AliHFEpidQAmanager *pidqa) { - - // - // as of 22/05/2006 : - // returns AliPID based on the ESD TOF PID decision - // the ESD PID will be checked and if necessary improved - // in the mean time. Best of luck - // - // returns 10 (== kUnknown)if PID can not be assigned for whatever reason - // - - if(vtrack->fAnalysisType == AliHFEpidObject::kESDanalysis){ - AliESDtrack *esdTrack = dynamic_cast(vtrack->fRecTrack); - if(!esdTrack) return 0; - AliMCParticle *mcTrack = dynamic_cast(vtrack->fMCtrack); - return MakePIDesdV3(esdTrack, mcTrack); - } else { - AliAODTrack *aodTrack = dynamic_cast(vtrack->fRecTrack); - if(!aodTrack) return 0; - AliAODMCParticle *aodmc = dynamic_cast(vtrack->fMCtrack); - return MakePIDaod(aodTrack, aodmc); - } -} - -//___________________________________________________________________ -Int_t AliHFEpidTOF::MakePIDesd(AliESDtrack *track, AliMCParticle * /*mcTrack*/){ - // - // Does particle identification as discribed in IsSelected - // - if(!fESDpid){ - AliError("No ESD PID object available"); - return kFALSE; - } - Long_t status = 0; - status = track->GetStatus(); - - if(!(status & AliESDtrack::kTOFout)) return 0; - - if(IsQAon()) fQAList->Fill("hTOF_flags", 0.); - - Double_t tItrackL = track->GetIntegratedLength(); - Double_t tTOFsignal = track->GetTOFsignal(); - - if(IsQAon()){ - if(tItrackL > 0) - fQAList->Fill("hTOF_flags", 1.); - - if(tTOFsignal > 0) - fQAList->Fill("hTOF_flags", 2.); - } - - - if(tItrackL <=0 || tTOFsignal <=0) return 0; - - if(IsQAon()){ - fQAList->Fill("hTOF_flags", 3.); - fQAList->Fill("hTOF_signal", tTOFsignal/1000.); - fQAList->Fill("hTOF_length", tItrackL); - } - // get the TOF pid probabilities - Double_t tESDpid[5] = {0., 0., 0., 0., 0.}; - Float_t tTOFpidSum = 0.; - // find the largest PID probability - track->GetTOFpid(tESDpid); - Double_t tMAXpid = 0.; - Int_t tMAXindex = -1; - for(Int_t i=0; i<5; ++i){ - tTOFpidSum += tESDpid[i]; - if(tESDpid[i] > tMAXpid){ - tMAXpid = tESDpid[i]; - tMAXindex = i; - } - } - - Int_t pdg = 0; - - TString specname; - switch(tMAXindex){ - case 0: pdg = 11; specname = "electron"; break; - case 1: pdg = 13; specname = "muon"; break; - case 2: pdg = 211; specname = "pion"; break; - case 3: pdg = 321; specname = "kaon"; break; - case 4: pdg = 2212; specname = "proton"; break; - default: pdg = 0; - }; - - - Double_t p = track->GetOuterParam()->P(); - Double_t beta = (tItrackL/100.)/(TMath::C()*(tTOFsignal/1e12)); - - // sanity check, should not be necessary - if(TMath::Abs(tTOFpidSum - 1) > 0.01) return 0; - - Double_t nSigmas = fESDpid->NumberOfSigmasTOF(track, (AliPID::EParticleType)tMAXindex, 0.); - if(TMath::Abs(nSigmas) > fNsigmaTOF) return 0; - - - // should be the same as AliPID flags - - if(IsQAon()){ - TString histname = "hTOFpid_" + specname; - fQAList->Fill(histname.Data(), beta, p); - fQAList->Fill("fTOFbeta_v_P_no", beta, p); - } - //return tMAXindex; - return pdg; - -} -//__________________________________________________________________ -Int_t AliHFEpidTOF::MakePIDesdV2(AliESDtrack *track, AliMCParticle * /*mcTrack*/){ - // - // Computes the PID response based on TOF & T0 signal - // - - if(!fESDpid){ - AliError("No ESD PID object available"); - return kFALSE; - } - Long_t status = 0; - status = track->GetStatus(); - if(!(status & AliESDtrack::kTOFpid)) return 0; - - Double_t p = track->GetOuterParam()->P(); - // track integrated times for 5 different hypothesis and T0 time - Double_t times[5]; - track->GetIntegratedTimes(times); - Double_t tItrackL = track->GetIntegratedLength(); - Double_t tTOFsignal = track->GetTOFsignal(); - Double_t t0 = fESDpid->GetTOFResponse().GetTimeZero(); - //printf("-D: tof: %f, T0: %f\n", tTOFsignal, t0); - // suppress missing or wrong T0 information - if(t0 > 999990.0) return 0; - Double_t tof = tTOFsignal - t0; - Double_t beta = (tItrackL/100.)/((TMath::C()*tof)/1e12); - //if(IsQAon())fQAList->Fill("hTOFbetaV2all", p, beta); - - const Int_t pdg[5] = {11, 13, 211, 321, 2212}; - const Double_t invMass[5] = {TDatabasePDG::Instance()->GetParticle(11)->Mass(), - TDatabasePDG::Instance()->GetParticle(13)->Mass(), - TDatabasePDG::Instance()->GetParticle(211)->Mass(), - TDatabasePDG::Instance()->GetParticle(321)->Mass(), - TDatabasePDG::Instance()->GetParticle(2212)->Mass()}; - - - // accepted beta bands as function of momentum - parameters - // line: par[0]/p + par[1] + expected_tof - const Double_t bMin[5][2] = {{0., -0.03}, {-0.005, -0.02}, {-0.005, -0.02}, {-0.02, -0.006}, {-0.03, -0.005}}; - const Double_t bMax[5][2] = {{0., 0.03}, {0.005, 0.02}, {0.005, 0.02}, {0.02, 0.006}, {0.03, 0.005}}; - - Int_t index = -1; - Double_t rdiff = 1.; - for(Int_t i=0; i<5; ++i){ - Double_t d = (TMath::Abs(times[i] - tof))/times[i]; - if(d < rdiff){ - rdiff = d; - index = i; - } - } - - // stupid and unnecessary complicated - to be improved soon - Double_t a = p/(invMass[index]); - a *= a; - Double_t betaMatch = TMath::Sqrt(a/(1+a)); - - // check wheter the most probable match is within allowed region of beta for given momentum and species - Double_t min = bMin[index][0]/p + bMin[index][1] + betaMatch; - Double_t max = bMax[index][0]/p + bMax[index][1] + betaMatch; - - // debug - //printf("-D: p: %f, beta: %f, pdg: %i, min: %f, max: %f\n", p, beta, pdg[index], min, max); - - // - // PID decision - can be simpler than the QA histograms above could indicate ! - // - - // suppress nonsense - if(beta < 0.2) return 0; - - // 1) Simple version - protect electrons - if(beta > (1+bMin[0][1]) && beta < (1+bMax[0][1])){ - //if(IsQAon())fQAList->Fill("hTOFbetaV2electron", p, beta); - return 11; - } - else return 0; - - - // NOT ACTIVE when (1) activated - // 2) more complex version - return true PID of the particle based on the best TOF estimate - // under development - still keep protecting electrons - if(beta > (1+bMin[0][1]) && beta < (1+bMax[0][1])){ - if(IsQAon())fQAList->Fill("hTOFbetaV2_electron", p, beta); - return 11; - } - // above 3 GeV/c the supression gets weak - if(p > 3.0) return 0; - if(beta > min && beta < max) { - if(IsQAon())fQAList->Fill("hTOFbetaV2selected", p, beta); - return pdg[index]; - } - - - return 0; -} - -//___________________________________________________________________ -Int_t AliHFEpidTOF::MakePIDesdV3(AliESDtrack *track, AliMCParticle * /*mctrack*/){ // // TOF PID based on n-Sigma cut // Selects Protons and Kaons via n-sigma cut up to 3 GeV/c // In addition histos for n-sigma before (all species) and after (only closest species) are filled // - if(!fESDpid){ - AliError("No ESD pid Object available. Return"); - return 0; - } - if(!(track->GetStatus() & AliESDtrack::kTOFpid)) return 0; + if((!fESDpid && track->IsESDanalysis()) || (!fAODpid && track->IsAODanalysis())) return 0; + AliDebug(2, "PID object available"); - Double_t t0 = fESDpid->GetTOFResponse().GetTimeZero(); - Double_t p = track->GetOuterParam() ? track->GetOuterParam()->P() : track->P(); + AliHFEpidObject::AnalysisType_t anaType = track->IsESDanalysis() ? AliHFEpidObject::kESDanalysis : AliHFEpidObject::kAODanalysis; + if(!((dynamic_cast(track->GetRecTrack()))->GetStatus() & AliESDtrack::kTOFpid)) return 0; + AliDebug(2, "Track Has TOF PID"); + + if(pidqa) pidqa->ProcessTrack(track, AliHFEpid::kTOFpid, AliHFEdetPIDqa::kBeforePID); // Fill before selection - Double_t sigEle = fESDpid->NumberOfSigmasTOF(track, AliPID::kElectron, t0); - //printf("-D: p: %f, t0: %f, nSigma: %f\n", p, t0, sigEle); + Double_t sigEle = NumberOfSigmas(track->GetRecTrack(), AliPID::kElectron, anaType); + AliDebug(2, Form("Number of sigmas in TOF: %f", sigEle)); Int_t pdg = 0; - if(TMath::Abs(sigEle) < fNsigmaTOF) + if(TMath::Abs(sigEle) < fNsigmaTOF){ pdg = 11; - if(IsQAon()){ - // Draw TPC cleanup - Double_t nsigTPC = fESDpid->NumberOfSigmasTPC(track, AliPID::kElectron); - if(nsigTPC > -3 && nsigTPC < 5) fQAList->Fill("hTOFsigmaTPCcleanup", p, sigEle); - // Draw TOF signal - Double_t hcontent[3] = {p, sigEle, 0}; - THnSparseF * hptr = dynamic_cast(fQAList->Get("hTOFsigmaElectron")); - hptr->Fill(hcontent); - if(pdg == 11){ - hcontent[2] = 1; - hptr->Fill(hcontent); - } + if(pidqa) pidqa->ProcessTrack(track, AliHFEpid::kTOFpid, AliHFEdetPIDqa::kAfterPID); } return pdg; } -//___________________________________________________________________ -Double_t AliHFEpidTOF::Likelihood(const AliESDtrack *track, Int_t species, Float_t rsig){ - - //gives probability for track to come from a certain particle species; - //no priors considered -> probabilities for equal abundances of all species! - //optional restriction to r-sigma bands of different particle species; default: rsig = 2. (see below) - - //IMPORTANT: Tracks which are judged to be outliers get negative likelihoods -> unusable for combination with further detectors! - - if(!track) return -1.; - Bool_t outlier = kTRUE; - // Check whether distance from the respective particle line is smaller than r sigma - for(Int_t hypo = 0; hypo < AliPID::kSPECIES; hypo++){ - if(TMath::Abs(fESDpid->NumberOfSigmasTOF(track, (AliPID::EParticleType)hypo, 0.)) > rsig) - outlier = kTRUE; - else { - outlier = kFALSE; - break; - } - } - if(outlier) - return -2.; - - Double_t tofProb[5]; - - track->GetTOFpid(tofProb); - - return tofProb[species]; -} -//___________________________________________________________________ -Int_t AliHFEpidTOF::MakePIDaod(AliAODTrack * /*aodTrack*/, AliAODMCParticle * /*mcTrack*/){ - AliError("AOD PID not yet implemented"); - return 0; -} //___________________________________________________________________ -void AliHFEpidTOF::AddQAhistograms(TList *qaList){ - // - // Create QA histograms for TOF PID - // - - fQAList = new AliHFEcollection("TOFqaHistos", "Collection for TOF PID histograms"); - //fQAList->SetName("fTOFqaHistos"); - fQAList->CreateTH1F("hTOF_flags", "TOF flags;flags (see code for info);counts", 10, -0.25, 4.75); - fQAList->CreateTH2F("fTOFbeta_v_P_no","beta -v- P; beta;momentum [GeV/c]", 120, 0, 1.2, 200, 0, 20); - fQAList->CreateTH1F("hTOF_signal", "TOF signal; TOF signal [ns];counts", 1000, 12, 50); - fQAList->CreateTH1F("hTOF_length", "TOF track length; length [cm];counts", 400, 300, 700); - fQAList->CreateTH2F("hTOFpid_electron", "TOF reco electron; beta ; momentum [GeV/c]", 120, 0, 1.2, 200, 0, 5); - fQAList->CreateTH2F("hTOFpid_muon", "TOF reco muon; beta ; momentum [GeV/c]", 120, 0, 1.2, 200, 0, 5); - fQAList->CreateTH2F("hTOFpid_pion", "TOF reco pion; beta ; momentum [GeV/c]", 120, 0, 1.2, 200, 0, 5); - fQAList->CreateTH2F("hTOFpid_kaon", "TOF reco kaon; beta ; momentum [GeV/c]", 120, 0, 1.2, 200, 0, 5); - fQAList->CreateTH2F("hTOFpid_proton", "TOF reco proton; beta ; momentum [GeV/c]", 120, 0, 1.2, 200, 0, 5); - //fQAList->CreateTH2F("hTOFbetaV2all", "TOF #beta vs p for all tracks; momentum [GeV/c]; beta ", 400, 0.1, 10., 1200, 0, 1.2, 0); - //fQAList->CreateTH2F("hTOFbetaV2electron", "TOF #beta vs p for selected electron tracks; momentum [GeV/c]; beta", 400, 0.1, 10., 1200, 0, 1.2, 0); - - // histograms for sigma cut - const Int_t kNdim= 3; - Int_t nBins[kNdim] = {1000, 1400, 2}; - Double_t binMin[kNdim] = {0.1, -12., 0}; - Double_t binMax[kNdim] = {20, 12., 2}; - fQAList->CreateTHnSparse("hTOFsigmaElectron", "TOF N#sigma around the Electron Line for all tracks; p (GeV/c); N sigma; Selection Step", kNdim, nBins, binMin, binMax); - fQAList->CreateTH2F("hTOFsigmaTPCcleanup", "TOF N#sigma around the Electron Line for all tracks after TPC cleanup; p (GeV/c); N sigma;", 100, 0.1, 20, 140, -12, 12); - - qaList->AddLast(fQAList->GetList()); +Double_t AliHFEpidTOF::NumberOfSigmas(const AliVParticle *track, AliPID::EParticleType species, AliHFEpidObject::AnalysisType_t anaType){ + // + // Get the number of sigmas + // + Double_t nSigmas = 100; + if(anaType == AliHFEpidObject::kESDanalysis){ + // ESD analysis + const AliESDtrack *esdtrack = dynamic_cast(track); + if(esdtrack && fESDpid) nSigmas = fESDpid->NumberOfSigmasTOF(esdtrack, species, fESDpid->GetTOFResponse().GetTimeZero()); + } else { + const AliAODTrack *aodtrack = dynamic_cast(track); + if(aodtrack && fAODpid) nSigmas = fAODpid->NumberOfSigmasTOF(aodtrack, species); + } + return nSigmas; } - - diff --git a/PWG3/hfe/AliHFEpidTOF.h b/PWG3/hfe/AliHFEpidTOF.h index a64b1b7dd7c..829bb5233ff 100644 --- a/PWG3/hfe/AliHFEpidTOF.h +++ b/PWG3/hfe/AliHFEpidTOF.h @@ -13,56 +13,29 @@ #include "AliHFEpidBase.h" #endif -class TList; -class TH2F; +class AliVParticle; +class AliPID; -class AliAODTrack; -class AliAODMCParticle; -class AliESDtrack; -class AliMCParticle; -class AliESDpid; -class AliLog; - -class AliHFEcollection; +class AliHFEpidQAmanager; class AliHFEpidTOF : public AliHFEpidBase{ public: + AliHFEpidTOF(); AliHFEpidTOF(const Char_t *name); virtual ~AliHFEpidTOF(); AliHFEpidTOF(const AliHFEpidTOF &c); AliHFEpidTOF &operator=(const AliHFEpidTOF &c); virtual Bool_t InitializePID(); - virtual Int_t IsSelected(AliHFEpidObject *track); - virtual Bool_t HasQAhistos() const { return kTRUE; }; + virtual Int_t IsSelected(AliHFEpidObject *track, AliHFEpidQAmanager *piqa); void SetTOFnSigma(Short_t nSigma) { fNsigmaTOF = nSigma; }; - Double_t Likelihood(const AliESDtrack *track, Int_t species, Float_t rsig = 2.); - protected: void Copy(TObject &ref) const; - void AddQAhistograms(TList *qaHist); - Int_t MakePIDesd(AliESDtrack *esdTrack, AliMCParticle *mcTrack); - Int_t MakePIDesdV2(AliESDtrack *esdTrack, AliMCParticle *mcTrack); - Int_t MakePIDesdV3(AliESDtrack *esdTrack, AliMCParticle *mcTrack); - Int_t MakePIDaod(AliAODTrack *aodTrack, AliAODMCParticle *mcTrack); - + Double_t NumberOfSigmas(const AliVParticle *track, AliPID::EParticleType species, AliHFEpidObject::AnalysisType_t anaType); private: - typedef enum{ - kHistTOFpidFlags = 0, - kHistTOFpidBetavP = 1, - kHistTOFsignal = 2, - kHistTOFlength =3, - kHistTOFpid0 = 4, - kHistTOFpid1 = 5, - kHistTOFpid2 = 6, - kHistTOFpid3 = 7, - kHistTOFpid4 = 8 - } QAHist_t; - AliPID *fPID; //! PID Object - AliHFEcollection *fQAList; //! QA histograms Short_t fNsigmaTOF; // TOF sigma band diff --git a/PWG3/hfe/AliHFEpidTPC.cxx b/PWG3/hfe/AliHFEpidTPC.cxx index d5397f88468..a0e3b4dfaf9 100644 --- a/PWG3/hfe/AliHFEpidTPC.cxx +++ b/PWG3/hfe/AliHFEpidTPC.cxx @@ -26,10 +26,9 @@ // Markus Heide // #include -#include #include -#include +#include "AliAODpidUtil.h" #include "AliAODTrack.h" #include "AliAODMCParticle.h" #include "AliESDtrack.h" @@ -39,11 +38,28 @@ #include "AliPID.h" #include "AliESDpid.h" -#include "AliHFEcollection.h" #include "AliHFEpidTPC.h" +#include "AliHFEpidQAmanager.h" ClassImp(AliHFEpidTPC) +//___________________________________________________________________ +AliHFEpidTPC::AliHFEpidTPC() : + // add a list here + AliHFEpidBase() + , fLineCrossingType(0) + , fLineCrossingsEnabled(0) + , fUpperSigmaCut(NULL) + , fLowerSigmaCut(NULL) + , fNsigmaTPC(3) + , fRejectionEnabled(0) + , fPID(NULL) +{ + // + // default constructor + // +} + //___________________________________________________________________ AliHFEpidTPC::AliHFEpidTPC(const char* name) : // add a list here @@ -55,7 +71,6 @@ AliHFEpidTPC::AliHFEpidTPC(const char* name) : , fNsigmaTPC(3) , fRejectionEnabled(0) , fPID(NULL) - , fQAList(NULL) { // // default constructor @@ -76,7 +91,6 @@ AliHFEpidTPC::AliHFEpidTPC(const AliHFEpidTPC &ref) : , fNsigmaTPC(2) , fRejectionEnabled(0) , fPID(NULL) - , fQAList(NULL) { // // Copy constructor @@ -108,7 +122,6 @@ void AliHFEpidTPC::Copy(TObject &o) const{ target.fNsigmaTPC = fNsigmaTPC; target.fRejectionEnabled = fRejectionEnabled; target.fPID = new AliPID(*fPID); - target.fQAList = new AliHFEcollection(*fQAList); memcpy(target.fLineCrossingSigma, fLineCrossingSigma, sizeof(Double_t) * AliPID::kSPECIES); memcpy(target.fPAsigCut, fPAsigCut, sizeof(Float_t) * 2); memcpy(target.fNAsigmaTPC, fNAsigmaTPC, sizeof(Float_t) * 2); @@ -122,9 +135,6 @@ AliHFEpidTPC::~AliHFEpidTPC(){ // Destructor // if(fPID) delete fPID; - if(fQAList){ - delete fQAList; - } } //___________________________________________________________________ @@ -138,37 +148,22 @@ Bool_t AliHFEpidTPC::InitializePID(){ } //___________________________________________________________________ -Int_t AliHFEpidTPC::IsSelected(AliHFEpidObject *track) +Int_t AliHFEpidTPC::IsSelected(AliHFEpidObject *track, AliHFEpidQAmanager *pidqa) { // // For the TPC pid we use the 2-sigma band around the bethe bloch curve // for electrons // exclusion of the crossing points // - if(track->fAnalysisType == AliHFEpidObject::kESDanalysis){ - AliESDtrack *esdTrack = NULL; - if(!(esdTrack = dynamic_cast(track->fRecTrack))) return 0; - AliMCParticle *mctrack = dynamic_cast(track->fMCtrack); - return MakePIDesd(esdTrack, mctrack); - }else{ - AliAODTrack *aodtrack = NULL; - if(!(aodtrack = dynamic_cast(track->fRecTrack))) return 0; - AliAODMCParticle *aodmctrack = dynamic_cast(track->fMCtrack); - return MakePIDaod(aodtrack, aodmctrack); - } -} -//___________________________________________________________________ -Int_t AliHFEpidTPC::MakePIDesd(AliESDtrack *esdTrack, AliMCParticle *mctrack){ - // - // Doing TPC PID as explained in IsSelected for ESD tracks - // - if(!fESDpid){ - AliError("No ESD PID object available"); - return kFALSE; - } + + if((!fESDpid && track->IsESDanalysis()) || (!fAODpid && track->IsAODanalysis())) return 0; + + // QA before selection + if(pidqa) pidqa->ProcessTrack(track, AliHFEpid::kTPCpid, AliHFEdetPIDqa::kBeforePID); AliDebug(1, "Doing TPC PID based on n-Sigma cut approach"); - Float_t nsigma = fESDpid->NumberOfSigmasTPC(esdTrack, AliPID::kElectron); - if(IsQAon()) FillTPChistograms(esdTrack, mctrack, kFALSE); + AliHFEpidObject::AnalysisType_t anatype = track->IsESDanalysis() ? AliHFEpidObject::kESDanalysis : AliHFEpidObject::kAODanalysis; + Float_t nsigma = NumberOfSigmas(track->GetRecTrack(), AliPID::kElectron, anatype); + AliDebug(1, Form("TPC NSigma: %f", nsigma)); // exclude crossing points: // Determine the bethe values for each particle species Bool_t isLineCrossing = kFALSE; @@ -176,7 +171,7 @@ Int_t AliHFEpidTPC::MakePIDesd(AliESDtrack *esdTrack, AliMCParticle *mctrack){ for(Int_t ispecies = 0; ispecies < AliPID::kSPECIES; ispecies++){ if(ispecies == AliPID::kElectron) continue; if(!(fLineCrossingsEnabled & 1 << ispecies)) continue; - if(TMath::Abs(fESDpid->NumberOfSigmasTPC(esdTrack, (AliPID::EParticleType)ispecies)) < fLineCrossingSigma[ispecies] && TMath::Abs(nsigma) < fNsigmaTPC){ + if(TMath::Abs(NumberOfSigmas(track->GetRecTrack(), (AliPID::EParticleType)ispecies, anatype)) < fLineCrossingSigma[ispecies] && TMath::Abs(nsigma) < fNsigmaTPC){ // Point in a line crossing region, no PID possible, but !PID still possible ;-) isLineCrossing = kTRUE; fLineCrossingType = ispecies; @@ -187,58 +182,53 @@ Int_t AliHFEpidTPC::MakePIDesd(AliESDtrack *esdTrack, AliMCParticle *mctrack){ // Check particle rejection if(HasParticleRejection()){ - Int_t reject = Reject(esdTrack); + Int_t reject = Reject(track->GetRecTrack(), anatype); if(reject != 0) return reject; } // Check if we have an asymmetric sigma model set Int_t pdg = 0; if(fUpperSigmaCut || fLowerSigmaCut){ - pdg = CutSigmaModel(esdTrack) ? 11 : 0; + pdg = CutSigmaModel(track->GetRecTrack(), anatype) ? 11 : 0; } else { // Perform Asymmetric n-sigma cut if required, else perform symmetric TPC sigma cut Float_t p = 0.; - if(HasAsymmetricSigmaCut() && (p = esdTrack->P()) >= fPAsigCut[0] && p <= fPAsigCut[1]){ + if(HasAsymmetricSigmaCut() && (p = track->GetRecTrack()->P()) >= fPAsigCut[0] && p <= fPAsigCut[1]){ if(nsigma >= fNAsigmaTPC[0] && nsigma <= fNAsigmaTPC[1]) pdg = 11; } else { if(TMath::Abs(nsigma) < fNsigmaTPC ) pdg = 11; } } - if(IsQAon() && pdg != 0) FillTPChistograms(esdTrack, mctrack, kTRUE); + if(pidqa && pdg != 0) pidqa->ProcessTrack(track, AliHFEpid::kTPCpid, AliHFEdetPIDqa::kAfterPID); return pdg; -} -//___________________________________________________________________ -Int_t AliHFEpidTPC::MakePIDaod(AliAODTrack * /*aodTrack*/, AliAODMCParticle * /*mctrack*/){ - AliError("AOD PID not yet implemented"); - return 0; } //___________________________________________________________________ -Bool_t AliHFEpidTPC::CutSigmaModel(AliESDtrack *track){ +Bool_t AliHFEpidTPC::CutSigmaModel(const AliVParticle *track, AliHFEpidObject::AnalysisType_t anaType){ // // N SigmaCut using parametrization of the cuts // Bool_t isSelected = kTRUE; - Float_t nsigma = fESDpid->NumberOfSigmasTPC(track, AliPID::kElectron); - Double_t p = track->GetInnerParam() ? track->GetInnerParam()->P() : track->P(); + Float_t nsigma = NumberOfSigmas(track, AliPID::kElectron, anaType); + Double_t p = track->P(); if(fUpperSigmaCut && nsigma > fUpperSigmaCut->Eval(p)) isSelected = kFALSE; if(fLowerSigmaCut && nsigma < fLowerSigmaCut->Eval(p)) isSelected = kFALSE; return isSelected; } //___________________________________________________________________ -Int_t AliHFEpidTPC::Reject(AliESDtrack *track){ +Int_t AliHFEpidTPC::Reject(const AliVParticle *track, AliHFEpidObject::AnalysisType_t anaType){ // // reject particles based on asymmetric sigma cut // Int_t pdc[AliPID::kSPECIES] = {11,13,211,321,2212}; - Double_t p = track->GetOuterParam() ? track->GetOuterParam()->P() : track->P(); + Double_t p = track->P(); for(Int_t ispec = 0; ispec < AliPID::kSPECIES; ispec++){ if(!TESTBIT(fRejectionEnabled, ispec)) continue; // Particle rejection enabled if(p < fRejection[4*ispec] || p > fRejection[4*ispec+2]) continue; - Double_t sigma = fESDpid->NumberOfSigmasTPC(track, static_cast(ispec)); + Double_t sigma = NumberOfSigmas(track, static_cast(ispec), anaType); if(sigma >= fRejection[4*ispec+1] && sigma <= fRejection[4*ispec+3]) return pdc[ispec] * track->Charge(); } return 0; @@ -259,140 +249,18 @@ void AliHFEpidTPC::AddTPCdEdxLineCrossing(Int_t species, Double_t sigma){ } //___________________________________________________________________ -Double_t AliHFEpidTPC::Likelihood(const AliESDtrack *track, Int_t species, Float_t rsig) -{ - //gives probability for track to come from a certain particle species; - //no priors considered -> probabilities for equal abundances of all species! - //optional restriction to r-sigma bands of different particle species; default: rsig = 2. (see below) - - //IMPORTANT: Tracks which are judged to be outliers get negative likelihoods -> unusable for combination with further detectors! - - if(!track) return -1.; - Bool_t outlier = kTRUE; - // Check whether distance from the respective particle line is smaller than r sigma - for(Int_t hypo = 0; hypo < AliPID::kSPECIES; hypo++){ - if(TMath::Abs(fESDpid->NumberOfSigmasTPC(track, (AliPID::EParticleType)hypo)) > rsig) - outlier = kTRUE; - else { - outlier = kFALSE; - break; - } - } - if(outlier) - return -2.; - - Double_t tpcProb[5]; - - track->GetTPCpid(tpcProb); - - return tpcProb[species]; -} - -//___________________________________________________________________ -Double_t AliHFEpidTPC::Suppression(const AliESDtrack *track, Int_t species) -{ - //ratio of likelihoods to be whatever species/to be an electron; - //as a cross-check for possible particle type suppression compared to electrons - const Double_t kVerySmall = 1e-10; - if(!track) return -20; - if((TMath::Abs(Likelihood(track,species) + 2) < kVerySmall)||(TMath::Abs(Likelihood(track,0) + 2 ) < kVerySmall)) - return -30; - if(TMath::Abs(Likelihood(track,species)) < kVerySmall) - return -10; - if (TMath::Abs(Likelihood(track,0)) < kVerySmall) - return 10.; - else - return TMath::Log10(Likelihood(track,species)/(Likelihood(track,0))); - - -} - -//___________________________________________________________________ -void AliHFEpidTPC::FillTPChistograms(const AliESDtrack *track, const AliMCParticle *mctrack, Bool_t stepSelected){ - // - // Fill the QA histogtrams +Double_t AliHFEpidTPC::NumberOfSigmas(const AliVParticle *track, AliPID::EParticleType species, AliHFEpidObject::AnalysisType_t anaType){ + // + // Get the number of sigmas // - if(!track) - return; - - Double_t tpcSignal = track->GetTPCsignal(); - Double_t p = track->GetInnerParam() ? track->GetInnerParam()->P() : track->P(); - Int_t species = -1; - THnSparse *hptr = NULL; - if(HasMCData() && mctrack){ - switch(TMath::Abs(mctrack->Particle()->GetPdgCode())){ - case 11: - species = AliPID::kElectron; - if(!stepSelected){ - Double_t contentElHist[4]; - for(Int_t ispec = AliPID::kMuon; ispec < AliPID::kSPECIES; ispec++){ - contentElHist[0] = ispec; - contentElHist[1] = p; - contentElHist[2] = -Suppression(track, ispec); - contentElHist[3] = Likelihood(track, ispec); - hptr = dynamic_cast(fQAList->Get("fHistTPCel")); - hptr->Fill(contentElHist); - } - } - break; - case 13: species = AliPID::kMuon; break; - case 211: species = AliPID::kPion; break; - case 321: species = AliPID::kKaon; break; - case 2212: species = AliPID::kProton; break; - default: species = -1; break; - } - if(!stepSelected){ - // Fill Probability Histogram - Double_t contentProb[3] = {species , p, Likelihood(track, 0)}; - hptr = dynamic_cast(fQAList->Get("fHistTPCprob")); - hptr->Fill(contentProb); - // Fill suppression Histogram - if(species > 0 && species < AliPID::kSPECIES){ - Double_t contentSup[3] = {species, p, Suppression(track, species)}; - hptr = dynamic_cast(fQAList->Get("fHistTPCsuppression")); - hptr->Fill(contentSup); - } - } + Double_t nSigmas = 100; + if(anaType == AliHFEpidObject::kESDanalysis){ + // ESD analysis + const AliESDtrack *esdtrack = dynamic_cast(track); + if(esdtrack && fESDpid) nSigmas = fESDpid->NumberOfSigmasTPC(esdtrack, species); + } else { + const AliAODTrack *aodtrack = dynamic_cast(track); + if(aodtrack && fAODpid) nSigmas = fAODpid->NumberOfSigmasTPC(aodtrack, species); } - - // Fill signal histogram - Double_t contentSignal[5] = {species, p, tpcSignal, fESDpid->NumberOfSigmasTPC(track, AliPID::kElectron), stepSelected ? 1 : 0}; - hptr = dynamic_cast(fQAList->Get("fHistTPCsignal")); - hptr->Fill(contentSignal); + return nSigmas; } - -//___________________________________________________________________ -void AliHFEpidTPC::AddQAhistograms(TList *qaList){ - // - // Create QA histograms for TPC PID - // - fQAList = new AliHFEcollection("fQAhistosTPC", "TPC QA histos"); - - // First THnSparse we fill with the signal - const Int_t kNdimSignal = 5; - Int_t nBins[kNdimSignal]; - Double_t binMin[kNdimSignal], binMax[kNdimSignal]; - nBins[0] = AliPID::kSPECIES + 1; binMin[0] = -1.; binMax[0] = AliPID::kSPECIES; // MC Species; - nBins[1] = 1000; binMin[1] = 0.; binMax[1] = 20.; - nBins[2] = 6000; binMin[2] = 0.; binMax[2] = 600.; - nBins[3] = 1400; binMin[3] = -12.; binMax[3] = 12.; - nBins[4] = 2; binMin[4] = 0.; binMax[4] = nBins[4]; // Selected or not - fQAList->CreateTHnSparse("fHistTPCsignal", "TPC signal; Species; p [GeV/c]; TPC Signal [a.u.]; Normalized TPC distance to the electron Line [#sigma]; Selection Status", kNdimSignal, nBins, binMin, binMax); - - const Int_t kNdimProbEl = 3; - nBins[2] = 200; binMin[2] = 0.; binMax[2] = 1.; - fQAList->CreateTHnSparse("fHistTPCprob", "TPC Likelihood to be an electron; Species; p [GeV/c]; TPC Likelihood [a.u.]", kNdimProbEl, nBins, binMin, binMax); - - const Int_t kNdimSuppression = 3; - nBins[2] = 200; binMin[2] = -1.; binMax[2] = 5.8; // log10 of TPC Likelihood(species)/Likelihood(elec) for species i neq electron - fQAList->CreateTHnSparse("fHistTPCsuppression", "TPC non-electron Suppression; Species; p [GeV/c]; Suppression [a.u.]", kNdimSuppression, nBins, binMin, binMax); - - const Int_t kNdimEle = 4; - nBins[0] = AliPID::kSPECIES - 1; binMin[0] = 1.; binMax[0] = AliPID::kSPECIES; - nBins[2] = 100; binMin[2] = -1.; binMax[2] = 5.8; - nBins[3] = 200; binMin[3] = 0.; binMax[3] = 1.; - fQAList->CreateTHnSparse("fHistTPCel", "TPC electron Histogram; Species; p [GeV/c]; Electron Enhancement:Electron Likelihood", kNdimEle, nBins, binMin, binMax); - - qaList->AddLast(fQAList->GetList()); -} - diff --git a/PWG3/hfe/AliHFEpidTPC.h b/PWG3/hfe/AliHFEpidTPC.h index 6fe69397c13..94f2c43ac2f 100644 --- a/PWG3/hfe/AliHFEpidTPC.h +++ b/PWG3/hfe/AliHFEpidTPC.h @@ -33,20 +33,20 @@ class AliAODTrack; class AliAODMCParticle; class AliESDtrack; class AliMCParticle; -class AliESDpid; class AliVParticle; class AliHFEcollection; +class AliHFEpidQAmanager; class AliHFEpidTPC : public AliHFEpidBase{ public: + AliHFEpidTPC(); AliHFEpidTPC(const Char_t *name); AliHFEpidTPC(const AliHFEpidTPC &ref); AliHFEpidTPC &operator=(const AliHFEpidTPC &ref); virtual ~AliHFEpidTPC(); virtual Bool_t InitializePID(); - virtual Int_t IsSelected(AliHFEpidObject *track); - virtual Bool_t HasQAhistos() const { return kTRUE; }; + virtual Int_t IsSelected(AliHFEpidObject *track, AliHFEpidQAmanager *pidqa); Int_t GetCrossingType() const {return fLineCrossingType; } @@ -62,15 +62,10 @@ class AliHFEpidTPC : public AliHFEpidBase{ protected: void Copy(TObject &o) const; - void AddQAhistograms(TList *qaList); - void FillTPChistograms(const AliESDtrack *track, const AliMCParticle *mctrack, Bool_t stepSelected = kFALSE); - Int_t MakePIDaod(AliAODTrack *aodTrack, AliAODMCParticle *mcTrack); - Int_t MakePIDesd(AliESDtrack *esdTrack, AliMCParticle *mcTrack); - Int_t Reject(AliESDtrack *track); - Double_t Likelihood(const AliESDtrack *track, Int_t species, Float_t rsig = 2.); - Double_t Suppression(const AliESDtrack *track, Int_t species); + Double_t NumberOfSigmas(const AliVParticle *track, AliPID::EParticleType species, AliHFEpidObject::AnalysisType_t); + Int_t Reject(const AliVParticle *track, AliHFEpidObject::AnalysisType_t anaType); - Bool_t CutSigmaModel(AliESDtrack *track); + Bool_t CutSigmaModel(const AliVParticle *track, AliHFEpidObject::AnalysisType_t anaType); private: enum{ @@ -88,7 +83,6 @@ class AliHFEpidTPC : public AliHFEpidBase{ Float_t fRejection[4*AliPID::kSPECIES]; // All informations for Particle Rejection, order pmin, sigmin, pmax, sigmax UChar_t fRejectionEnabled; // Bitmap for enabled particle rejection AliPID *fPID; //! PID Object - AliHFEcollection *fQAList; //! QA histograms ClassDef(AliHFEpidTPC, 1) // TPC Electron ID class }; diff --git a/PWG3/hfe/AliHFEpidTRD.cxx b/PWG3/hfe/AliHFEpidTRD.cxx index 6e78b9e7a63..73b3cb8f400 100644 --- a/PWG3/hfe/AliHFEpidTRD.cxx +++ b/PWG3/hfe/AliHFEpidTRD.cxx @@ -27,6 +27,7 @@ #include #include +#include "AliAODpidUtil.h" #include "AliAODTrack.h" #include "AliAODMCParticle.h" #include "AliESDtrack.h" @@ -35,7 +36,7 @@ #include "AliMCParticle.h" #include "AliPID.h" -#include "AliHFEcollection.h" +#include "AliHFEpidQAmanager.h" #include "AliHFEpidTRD.h" ClassImp(AliHFEpidTRD) @@ -48,12 +49,10 @@ AliHFEpidTRD::AliHFEpidTRD() : , fMinP(1.) , fElectronEfficiency(0.91) , fPIDMethod(kNN) - , fContainer(NULL) { // // default constructor // - memset(fThreshParams, 0, sizeof(Double_t) * kThreshParams); } //___________________________________________________________________ @@ -62,7 +61,6 @@ AliHFEpidTRD::AliHFEpidTRD(const char* name) : , fMinP(1.) , fElectronEfficiency(0.91) , fPIDMethod(kNN) - , fContainer(NULL) { // // default constructor @@ -76,7 +74,6 @@ AliHFEpidTRD::AliHFEpidTRD(const AliHFEpidTRD &ref): , fMinP(ref.fMinP) , fElectronEfficiency(ref.fElectronEfficiency) , fPIDMethod(ref.fPIDMethod) - , fContainer(NULL) { // // Copy constructor @@ -107,7 +104,6 @@ void AliHFEpidTRD::Copy(TObject &ref) const { target.fPIDMethod = fPIDMethod; target.fElectronEfficiency = fElectronEfficiency; memcpy(target.fThreshParams, fThreshParams, sizeof(Double_t) * kThreshParams); - if(fContainer) target.fContainer = dynamic_cast(fContainer->Clone()); AliHFEpidBase::Copy(ref); } @@ -116,8 +112,6 @@ AliHFEpidTRD::~AliHFEpidTRD(){ // // Destructor // - if(fContainer) - delete fContainer; } //______________________________________________________ @@ -134,55 +128,35 @@ Bool_t AliHFEpidTRD::InitializePID(){ } //______________________________________________________ -Int_t AliHFEpidTRD::IsSelected(AliHFEpidObject *track){ +Int_t AliHFEpidTRD::IsSelected(AliHFEpidObject *track, AliHFEpidQAmanager *pidqa){ // // Does PID for TRD alone: // PID thresholds based on 90% Electron Efficiency level approximated by a linear // step function // - if(track->fAnalysisType == AliHFEpidObject::kESDanalysis){ - AliESDtrack *esdTrack = dynamic_cast(track->fRecTrack); - if(!esdTrack) return 0; - AliMCParticle *esdmc = dynamic_cast(track->fMCtrack); - return MakePIDesd(esdTrack, esdmc); - } else { - AliAODTrack *aodTrack = dynamic_cast(track->fRecTrack); - if(!aodTrack) return 0; - AliAODMCParticle *aodmc = dynamic_cast(track->fMCtrack); - return MakePIDaod(aodTrack, aodmc); - } -} - -//______________________________________________________ -Int_t AliHFEpidTRD::MakePIDaod(AliAODTrack * /*aodTrack*/, AliAODMCParticle * /*aodmc*/){ - // - // Does PID decision for AOD tracks as discribed above - // - AliError("AOD PID not yet implemented"); - return 0; -} + AliDebug(1, "Applying TRD PID"); + if((!fESDpid && track->IsESDanalysis()) || (!fAODpid && track->IsAODanalysis())){ + AliDebug(1, "Cannot process track"); + return 0; + } -//______________________________________________________ -Int_t AliHFEpidTRD::MakePIDesd(AliESDtrack *esdTrack, AliMCParticle * /*mcTrack*/){ - // - // Does PID decision for ESD tracks as discribed above - // - Double_t p = esdTrack->GetOuterParam() ? esdTrack->GetOuterParam()->P() : esdTrack->P(); - if(IsQAon()) - FillStandardQA(0, esdTrack); - if(p < fMinP) return 0; + AliHFEpidObject::AnalysisType_t anatype = track->IsESDanalysis() ? AliHFEpidObject::kESDanalysis: AliHFEpidObject::kAODanalysis; + Double_t p = GetP(track->GetRecTrack(), anatype); + if(p < fMinP){ + AliDebug(1, Form("Track momentum below %f", fMinP)); + return 0; + } - Double_t pidProbs[AliPID::kSPECIES]; - esdTrack->GetTRDpid(pidProbs); + if(pidqa) pidqa->ProcessTrack(track, AliHFEpid::kTRDpid, AliHFEdetPIDqa::kBeforePID); + Double_t electronLike = GetElectronLikelihood(track->GetRecTrack(), anatype); Double_t threshold = GetTRDthresholds(fElectronEfficiency, p); AliDebug(1, Form("Threshold: %f\n", threshold)); - if(IsQAon()) fContainer->Fill("fTRDthresholds", p, threshold); - if(pidProbs[AliPID::kElectron] > threshold){ - if(IsQAon()) - FillStandardQA(1, esdTrack); + if(electronLike > threshold){ + if(pidqa) pidqa->ProcessTrack(track, AliHFEpid::kTRDpid, AliHFEdetPIDqa::kAfterPID); return 11; } return 211; + } //___________________________________________________________________ @@ -275,7 +249,39 @@ void AliHFEpidTRD::GetParameters(Double_t electronEff, Double_t *parameters){ } //___________________________________________________________________ -Double_t AliHFEpidTRD::GetTRDSignalV1(AliESDtrack *track, Int_t mcPID){ +Double_t AliHFEpidTRD::GetElectronLikelihood(const AliVParticle *track, AliHFEpidObject::AnalysisType_t anaType){ + // + // Get TRD likelihoods for ESD respectively AOD tracks + // + Double_t pidProbs[AliPID::kSPECIES]; memset(pidProbs, 0, sizeof(Double_t) * AliPID::kSPECIES); + if(anaType == AliHFEpidObject::kESDanalysis){ + const AliESDtrack *esdtrack = dynamic_cast(track); + esdtrack->GetTRDpid(pidProbs); + } else { + const AliAODTrack *aodtrack = dynamic_cast(track); + fAODpid->MakeTRDPID(const_cast(aodtrack), pidProbs); + } + return pidProbs[AliPID::kElectron]; +} + +//___________________________________________________________________ +Double_t AliHFEpidTRD::GetP(const AliVParticle *track, AliHFEpidObject::AnalysisType_t anaType){ + // + // Get the Momentum in the TRD + // + Double_t p = 0.; + if(anaType == AliHFEpidObject::kESDanalysis){ + const AliESDtrack *esdtrack = dynamic_cast(track); + p = esdtrack->GetOuterParam() ? esdtrack->GetOuterParam()->P() : esdtrack->P(); + } else { + const AliAODTrack *aodtrack = dynamic_cast(track); + p = aodtrack->P(); + } + return p; +} + +//___________________________________________________________________ +Double_t AliHFEpidTRD::GetTRDSignalV1(const AliESDtrack *track){ // // Calculation of the TRD Signal via truncated mean // Method 1: Take all Slices available @@ -304,12 +310,11 @@ Double_t AliHFEpidTRD::GetTRDSignalV1(AliESDtrack *track, Int_t mcPID){ Double_t trdSignal = TMath::Mean(static_cast(static_cast(icnt) * 2./3.), trdSlices); Double_t mom = track->GetOuterParam() ? track->GetOuterParam()->P() : -1; AliDebug(3, Form("PID Meth. 1: p[%f], TRDSignal[%f]", mom, trdSignal)); - if(IsQAon() && mom > 0.) FillHistogramsTRDSignal(trdSignal, mom, mcPID, 1); return trdSignal; } //___________________________________________________________________ -Double_t AliHFEpidTRD::GetTRDSignalV2(AliESDtrack *track, Int_t mcPID){ +Double_t AliHFEpidTRD::GetTRDSignalV2(const AliESDtrack *track){ // // Calculation of the TRD Signal via truncated mean // Method 2: Take only first 5 slices per chamber @@ -339,84 +344,5 @@ Double_t AliHFEpidTRD::GetTRDSignalV2(AliESDtrack *track, Int_t mcPID){ Double_t trdSignal = TMath::Mean(cntRemaining, trdSlicesRemaining); Double_t mom = track->GetOuterParam() ? track->GetOuterParam()->P() : -1; AliDebug(3, Form("PID Meth. 2: p[%f], TRDSignal[%f]", mom, trdSignal)); - if(IsQAon() && mom > 0.) FillHistogramsTRDSignal(trdSignal, mom, mcPID, 2); return trdSignal; } - -//___________________________________________________________________ -void AliHFEpidTRD::FillHistogramsTRDSignal(Double_t signal, Double_t p, Int_t species, UInt_t version){ - // - // Fill histograms for TRD Signal from Method 2 vs. p for different particle species - // Non-standard QA content - // - if(version == 0 || version > 2) return; - if(species >= AliPID::kSPECIES || species < -1) species = -1; - Double_t content[3] = {species, p, signal}; - Char_t histname[256]; sprintf(histname, "fTRDsignalV%d", version); - THnSparseF *hsig = dynamic_cast(fContainer->Get(histname)); - if(hsig) hsig->Fill(content); -} - -//___________________________________________________________________ -void AliHFEpidTRD::AddQAhistograms(TList *l){ - // - // Adding QA histograms for the TRD PID - // QA histograms are: - // + TRD Signal from Meth. 1 vs p for all species - // + TRD Signal from Meth. 2 vs p for all species - // + For each species - // - TRD Signal from Meth. 1 vs p - // - TRD Signal from Meth. 2 vs p - // - const Int_t kMomentumBins = 100; - const Double_t kPtMin = 0.1; - const Double_t kPtMax = 20.; - - if(!fContainer) fContainer = new AliHFEcollection("fQAhistosTRD", "TRD QA histos"); - fContainer->CreateTH2F("fTRDlikeBefore", "TRD Electron Likelihood before cut; p [GeV/c]; TRD Electron Likelihood", kMomentumBins, kPtMin, kPtMax, 1000, 0, 1); - fContainer->CreateTH2F("fTRDlikeAfter", "TRD Electron Likelihood after cut; p [GeV/c]; TRD Electron Likelihood", kMomentumBins, kPtMin, kPtMax, 1000, 0, 1); - fContainer->CreateTH2F("fTRDthresholds", "TRD Electron Thresholds; p [GeV/c]; Thresholds", kMomentumBins, kPtMin, kPtMax, 1000, 0., 1.); - fContainer->CreateTH2F("fTPCsignalBefore", "TPC dEdx Spectrum before TRD PID; p [GeV/c]; TPC Signal [a.u.]", kMomentumBins, kPtMin, kPtMax, 100, 0., 100.); - fContainer->CreateTH2F("fTPCsignalAfter", "TPC dEdx Spectrum before TRD PID; p [GeV/c]; TPC Signal [a.u.]", kMomentumBins, kPtMin, kPtMax, 100, 0., 100.); - fContainer->CreateTH2F("fTPCsigmaBefore", "TPC dEdx before TRD PID; p [GeV/c]; Normalized TPC distance to the electron line [n#sigma]", kMomentumBins, kPtMin, kPtMax, 100, -10., 10.); - fContainer->CreateTH2F("fTPCsigmaAfter", "TPC dEdx Spectrum before TRD PID; p [GeV/c]; Normalized TPC distance to the electron line [n#sigma]", kMomentumBins, kPtMin, kPtMax, 100, -10., 10.); - - // Monitor THnSparse for TRD Signal - const Int_t kBinsTRDsignal = 3; - Int_t nBins[kBinsTRDsignal] = {AliPID::kSPECIES +1, kMomentumBins, 100}; - Double_t binMin[kBinsTRDsignal] = {-1, kPtMin, 0}; - Double_t binMax[kBinsTRDsignal] = {AliPID::kSPECIES, kPtMax, 1000}; - fContainer->CreateTHnSparse("fTRDsignalV1", "TRD Signal V1", kBinsTRDsignal, nBins, binMin, binMax); - fContainer->CreateTHnSparse("fTRDsignalV2", "TRD Signal V2", kBinsTRDsignal, nBins, binMin, binMax); - - // Make logatithmic binning - TString hnames[7] = {"fTRDlikeBefore", "fTRDlikeAfter", "fTRDthresholds", "fTRDsignalBefore", "fTRDsignalAfter", "fTPCsigmaBefore", "fTPCsigmaAfter"}; - for(Int_t ihist = 0; ihist < 7; ihist++) - fContainer->BinLogAxis(hnames[ihist].Data(), 0); - fContainer->BinLogAxis("fTRDsignalV1", 1); - fContainer->BinLogAxis("fTRDsignalV2", 1); - - l->Add(fContainer->GetList()); -} - -//___________________________________________________________________ -void AliHFEpidTRD::FillStandardQA(Int_t whenFilled, AliESDtrack *esdTrack){ - // - // Fill Likelihood Histogram before respectively after decision - // - Double_t p = esdTrack->P(); - Double_t like[AliPID::kSPECIES]; - esdTrack->GetTRDpid(like); - TString step; - if(whenFilled) - step = "After"; - else - step = "Before"; - TString histos[3] = {"fTRDlike", "fTPCsignal", "fTPCsigma"}; - for(Int_t ihist = 0; ihist < 3; ihist++) histos[ihist] += step; - fContainer->Fill(histos[0].Data(), esdTrack->P(), like[AliPID::kElectron]); - fContainer->Fill(histos[1].Data(), p, esdTrack->GetTPCsignal()); - const Double_t sigmaShift = 1.; - if(fESDpid) - fContainer->Fill(histos[2].Data(), p, fESDpid->NumberOfSigmasTPC(esdTrack, AliPID::kElectron) - sigmaShift); -} diff --git a/PWG3/hfe/AliHFEpidTRD.h b/PWG3/hfe/AliHFEpidTRD.h index 84d73575354..6c8988776d0 100644 --- a/PWG3/hfe/AliHFEpidTRD.h +++ b/PWG3/hfe/AliHFEpidTRD.h @@ -57,11 +57,10 @@ class AliHFEpidTRD : public AliHFEpidBase{ virtual ~AliHFEpidTRD(); virtual Bool_t InitializePID(); - virtual Int_t IsSelected(AliHFEpidObject *track); - virtual Bool_t HasQAhistos() const { return kTRUE; }; + virtual Int_t IsSelected(AliHFEpidObject *track, AliHFEpidQAmanager *pidqa); - Double_t GetTRDSignalV1(AliESDtrack *track, Int_t mcPID); - Double_t GetTRDSignalV2(AliESDtrack *track, Int_t mcPID); + Double_t GetTRDSignalV1(const AliESDtrack *track); + Double_t GetTRDSignalV2(const AliESDtrack *track); Bool_t IsCalculateTRDSignals() const { return TestBit(kTRDsignals); } void SetPIDMethod(PIDMethodTRD_t method) { fPIDMethod = method; }; @@ -75,23 +74,18 @@ class AliHFEpidTRD : public AliHFEpidBase{ kTRDsignals = BIT(16) }; void Copy(TObject &ref) const; - Int_t MakePIDesd(AliESDtrack *esdTrack, AliMCParticle *mcTrack); - Int_t MakePIDaod(AliAODTrack *aofTrack, AliAODMCParticle *aodMC); - Int_t GetMCpid(AliESDtrack *track); + Double_t GetElectronLikelihood(const AliVParticle *track, AliHFEpidObject::AnalysisType_t anaType); + Double_t GetP(const AliVParticle *track, AliHFEpidObject::AnalysisType_t anaType); void InitParameters(); void InitParameters1DLQ(); - virtual void AddQAhistograms(TList *l); void GetParameters(Double_t electronEff, Double_t *parameters); - void FillStandardQA(Int_t whenFilled, AliESDtrack *esdTrack); - void FillHistogramsTRDSignal(Double_t signal, Double_t p, Int_t species, UInt_t version); private: static const Double_t fgkVerySmall; // Check for 0 Double_t fMinP; // Minimum momentum above which TRD PID is applied Double_t fElectronEfficiency; // Cut on electron efficiency PIDMethodTRD_t fPIDMethod; // PID Method: 2D Likelihood or Neural Network Double_t fThreshParams[kThreshParams]; // Threshold parametrisation - AliHFEcollection *fContainer; // QA Histogram Container ClassDef(AliHFEpidTRD, 1) // TRD electron ID class }; diff --git a/PWG3/hfe/AliHFEpostAnalysis.cxx b/PWG3/hfe/AliHFEpostAnalysis.cxx index 728ad02c14f..9ac3adab9f0 100644 --- a/PWG3/hfe/AliHFEpostAnalysis.cxx +++ b/PWG3/hfe/AliHFEpostAnalysis.cxx @@ -22,6 +22,7 @@ // // Autor: Markus Fasel // + #include #include #include @@ -31,6 +32,7 @@ #include "AliCFContainer.h" #include "AliCFEffGrid.h" +#include "AliHFEcontainer.h" #include "AliHFEcuts.h" #include "AliHFEpostAnalysis.h" @@ -87,18 +89,11 @@ AliHFEpostAnalysis::~AliHFEpostAnalysis(){ } //____________________________________________________________ -Int_t AliHFEpostAnalysis::SetResults(TList *input){ +Int_t AliHFEpostAnalysis::SetTaskQA(const TList *input){ // // Publish the results to the post analysis // Int_t nFound = 0; - fEfficiencyContainer = dynamic_cast(input->FindObject("trackContainer")); - if(!fEfficiencyContainer){ - AliError("Efficiency Correction Framework Container not found in the list of outputs"); - } else { - SETBIT(fAnalysisObjects, kCFC); - nFound++; - } fPIDperformance = dynamic_cast(input->FindObject("PIDperformance")); if(!fPIDperformance){ AliError("Histogram fPIDperformance not found in the List of Outputs"); @@ -233,7 +228,8 @@ void AliHFEpostAnalysis::DrawEfficiency(){ TCanvas *cEff = new TCanvas("cEff", "Efficiency", 800, 600); cEff->Divide(2,2); if(!fEfficiencyContainer) return; - AliCFEffGrid *effCalc = new AliCFEffGrid("effCalc", "Efficiency Calculation Grid", *fEfficiencyContainer); + AliCFContainer *tracks = fEfficiencyContainer->MakeMergedCFContainer("trackContCombined", "MC + Rec(reco) Track Information", "MCTrackCont:recTrackContReco"); + AliCFEffGrid *effCalc = new AliCFEffGrid("effCalc", "Efficiency Calculation Grid", *tracks); effCalc->CalculateEfficiency(AliHFEcuts::kStepMCInAcceptance, AliHFEcuts::kStepMCGenerated); TH1 *effReconstructibleP = effCalc->Project(0); effReconstructibleP->SetName("effReconstructibleP"); @@ -247,7 +243,7 @@ void AliHFEpostAnalysis::DrawEfficiency(){ effReconstructibleP->SetStats(kFALSE); cEff->cd(1); effReconstructibleP->Draw("e"); - effCalc->CalculateEfficiency(AliHFEcuts::kStepMCsignal, AliHFEcuts::kStepMCGenerated); + effCalc->CalculateEfficiency(AliHFEcuts::kStepMCGeneratedZOutNoPileUp, AliHFEcuts::kStepMCGenerated); TH1 *effSignal = effCalc->Project(0); effSignal->SetName("effSignal"); effSignal->SetTitle("Efficiency of Signal Electrons"); @@ -260,7 +256,7 @@ void AliHFEpostAnalysis::DrawEfficiency(){ effSignal->SetStats(kFALSE); cEff->cd(2); effSignal->Draw("e"); - effCalc->CalculateEfficiency(AliHFEcuts::kStepPID + 2*AliHFEcuts::kNcutStepsESDtrack, AliHFEcuts::kStepMCGenerated); + effCalc->CalculateEfficiency(tracks->GetNStep() - 1, AliHFEcuts::kStepMCGenerated); TH1 *effPIDP = effCalc->Project(0); effPIDP->SetName("effPIDP"); effPIDP->SetTitle("Efficiency of selected tracks"); @@ -273,7 +269,7 @@ void AliHFEpostAnalysis::DrawEfficiency(){ effPIDP->SetStats(kFALSE); cEff->cd(3); effPIDP->Draw("e"); - effCalc->CalculateEfficiency(AliHFEcuts::kStepPID + 2*AliHFEcuts::kNcutStepsESDtrack, AliHFEcuts::kStepMCInAcceptance); + effCalc->CalculateEfficiency(tracks->GetNStep() - 1, AliHFEcuts::kStepMCInAcceptance); TH1 *effPIDAcc = effCalc->Project(0); effPIDAcc->SetName("effPIDAcc"); effPIDAcc->SetTitle("Efficiency of selected tracks in acceptance"); @@ -422,68 +418,72 @@ void AliHFEpostAnalysis::DrawCutEfficiency(Bool_t MC, Int_t source){ leg->SetBorderSize(0); leg->SetFillColor(kWhite); leg->SetFillStyle(0); - const char* names[AliHFEcuts::kNcutStepsTrack - 1] = {"Acceptance", "No Cuts", "Rec Tracks" "Rec Kine(TPC/ITS)", "Primary", "HFE ITS", "HFE TRD", "PID", }; - Color_t color[AliHFEcuts::kNcutStepsTrack - 1] = {kRed, kGreen, kMagenta, kBlack, kOrange, kTeal, kViolet, kBlue}; - Marker_t marker[AliHFEcuts::kNcutStepsTrack - 1] = {24, 25, 26, 27, 28, 29, 30}; + + AliCFContainer *tracks = fEfficiencyContainer->MakeMergedCFContainer("mergedTracks", "Container for MC and reconstructed Track information", "MCTrackCont:recTrackContReco"); + Int_t nStepMC = fEfficiencyContainer->GetCFContainer("MCTrackCont")->GetNStep(); + AliDebug(1, Form("Number of MC Cut Steps: %d", nStepMC)); + const Int_t markerStart = 24; + const Int_t colorStart = 1; TH1 *hTemp = NULL; if(MC){ if(source > -1 && source < 4){ AliInfo(Form("Setting source to %d", source)) - for(Int_t istep = 0; istep < fEfficiencyContainer->GetNStep(); istep++) fEfficiencyContainer->GetAxis(4, istep)->SetRange(source + 1, source + 1); + for(Int_t istep = 0; istep < tracks->GetNStep(); istep++) tracks->GetAxis(4, istep)->SetRange(source + 1, source + 1); } } - AliCFEffGrid effcalc("cutEfficiency", "Cut step efficiency calculation", *fEfficiencyContainer); + AliCFEffGrid effcalc("cutEfficiency", "Cut step efficiency calculation", *tracks); Bool_t first = kTRUE; // Calculate efficiency for MC Steps + Int_t histcounter = 0; if(MC){ // // Draw plots related to MC values // effcalc.CalculateEfficiency(AliHFEcuts::kStepMCInAcceptance, AliHFEcuts::kStepMCGenerated); hTemp = effcalc.Project(0); - hTemp->SetName("hEff1"); + hTemp->SetName(Form("hEff%d", histcounter)); hTemp->SetTitle("Cut Step Efficiency"); - hTemp->SetMarkerColor(color[0]); - hTemp->SetMarkerStyle(marker[0]); - hTemp->GetXaxis()->SetTitle("P / GeV/c"); + hTemp->SetMarkerColor(colorStart + histcounter); + hTemp->SetMarkerStyle(markerStart + histcounter); + hTemp->GetXaxis()->SetTitle("p / GeV/c"); hTemp->GetYaxis()->SetTitle("Efficiency"); hTemp->GetYaxis()->SetRangeUser(0., 2.); hTemp->SetStats(kFALSE); hTemp->Draw("ep"); - leg->AddEntry(hTemp, names[0], "p"); - effcalc.CalculateEfficiency(AliHFEcuts::kStepRecNoCut + 2*AliHFEcuts::kNcutStepsESDtrack, AliHFEcuts::kStepMCGenerated); + leg->AddEntry(hTemp, tracks->GetStepTitle(AliHFEcuts::kStepMCInAcceptance), "p"); + histcounter++; + effcalc.CalculateEfficiency(nStepMC, AliHFEcuts::kStepMCGenerated); hTemp = effcalc.Project(0); hTemp->SetName("hEff2"); hTemp->SetTitle("Cut Step Efficiency"); - hTemp->SetMarkerColor(color[1]); - hTemp->SetMarkerStyle(marker[1]); - hTemp->GetXaxis()->SetTitle("P / GeV/c"); + hTemp->SetMarkerColor(colorStart + histcounter); + hTemp->SetMarkerStyle(markerStart + histcounter); + hTemp->GetXaxis()->SetTitle("p / GeV/c"); hTemp->GetYaxis()->SetTitle("Efficiency"); hTemp->GetYaxis()->SetRangeUser(0., 2.); hTemp->SetStats(kFALSE); hTemp->Draw("epsame"); - leg->AddEntry(hTemp, names[1], "p"); + leg->AddEntry(hTemp, tracks->GetStepTitle(nStepMC), "p"); first = kFALSE; + histcounter++; } - for(Int_t istep = AliHFEcuts::kStepRecKineITSTPC; istep <= AliHFEcuts::kStepPID; istep++){ - effcalc.CalculateEfficiency(istep + 2*AliHFEcuts::kNcutStepsESDtrack, istep-1 + 2*AliHFEcuts::kNcutStepsESDtrack); + for(Int_t istep = nStepMC+1; istep < tracks->GetNStep(); istep++){ + effcalc.CalculateEfficiency(istep, istep - 1); hTemp = effcalc.Project(0); hTemp->SetName(Form("hEff%d", istep)); hTemp->SetTitle("Cut Step Efficiency"); - hTemp->SetMarkerColor(color[istep-2]); - hTemp->SetMarkerStyle(marker[istep-2]); + hTemp->SetMarkerColor(colorStart + histcounter); + hTemp->SetMarkerStyle(markerStart + histcounter); hTemp->SetStats(kFALSE); hTemp->Draw(first ? "ep" : "epsame"); hTemp->GetXaxis()->SetTitle("P / GeV/c"); hTemp->GetYaxis()->SetTitle("Efficiency"); hTemp->GetYaxis()->SetRangeUser(0., 2.); - leg->AddEntry(hTemp, names[istep-2], "p"); + leg->AddEntry(hTemp, tracks->GetStepTitle(istep), "p"); first = kFALSE; + histcounter++; } leg->Draw(); - // undo axis restriction - if(MC && source > -1 && source < 4){ - for(Int_t istep = 0; istep < fEfficiencyContainer->GetNStep(); istep++) fEfficiencyContainer->GetAxis(4, istep)->SetRange(0, 4); - } + delete tracks; } diff --git a/PWG3/hfe/AliHFEpostAnalysis.h b/PWG3/hfe/AliHFEpostAnalysis.h index b2da25a7983..dae9ecf380e 100644 --- a/PWG3/hfe/AliHFEpostAnalysis.h +++ b/PWG3/hfe/AliHFEpostAnalysis.h @@ -24,9 +24,10 @@ #include #endif -class AliCFContainer; +class AliHFEcontainer; class TH1; class TList; + class AliHFEpostAnalysis : public TObject{ public: AliHFEpostAnalysis(); @@ -34,7 +35,8 @@ class AliHFEpostAnalysis : public TObject{ AliHFEpostAnalysis &operator=(const AliHFEpostAnalysis &ref); ~AliHFEpostAnalysis(); - Int_t SetResults(TList *input); + Int_t SetTaskResults(AliHFEcontainer *trackContainer) { fEfficiencyContainer = trackContainer; return 1; }; + Int_t SetTaskQA(const TList *qa); void StoreOutput(const char *filename = "HFEresults.root"); void DrawMCSignal2Background(); @@ -52,7 +54,7 @@ class AliHFEpostAnalysis : public TObject{ TList *fResults; // Container for output objects UChar_t fAnalysisObjects; // S - AliCFContainer *fEfficiencyContainer; // Task Results + AliHFEcontainer *fEfficiencyContainer; // Task Results THnSparseF *fPIDperformance; // PID Performance Studies THnSparseF *fSignalToBackgroundMC; // Signal To Background Studies diff --git a/PWG3/hfe/AliHFEpriVtx.cxx b/PWG3/hfe/AliHFEpriVtx.cxx index d416cb1d820..71870201581 100644 --- a/PWG3/hfe/AliHFEpriVtx.cxx +++ b/PWG3/hfe/AliHFEpriVtx.cxx @@ -195,7 +195,7 @@ void AliHFEpriVtx::FillNtracks() } //_______________________________________________________________________________________________ -Int_t AliHFEpriVtx::GetMCPID(AliESDtrack *track) +Int_t AliHFEpriVtx::GetMCPID(AliESDtrack const *track) { // // get MC pid @@ -340,7 +340,7 @@ Double_t AliHFEpriVtx::GetDistanceFromRecalVertexXY(AliESDtrack * const ESDelect } -void AliHFEpriVtx::RecalcPrimvtx(Int_t nkftrk, Int_t * const trkid, AliKFParticle * const kftrk) +void AliHFEpriVtx::RecalcPrimvtx(Int_t nkftrk, const Int_t * const trkid, const AliKFParticle * const kftrk) { // // recalculate primary vertex after removing the input track diff --git a/PWG3/hfe/AliHFEpriVtx.h b/PWG3/hfe/AliHFEpriVtx.h index abbc3d2b349..c47236c4da3 100644 --- a/PWG3/hfe/AliHFEpriVtx.h +++ b/PWG3/hfe/AliHFEpriVtx.h @@ -51,7 +51,7 @@ class AliHFEpriVtx : public TObject { void FillNtracks(); // fill counted number of tracks void CountPriVxtElecContributor(AliESDtrack *ESDelectron, Int_t sourcePart, Int_t recpid, Double_t recprob); void FillNprimVtxContributor() const; - void RecalcPrimvtx(Int_t nkftrk, Int_t * const, AliKFParticle * const); //recalculate primary vertex after removing given tracks + void RecalcPrimvtx(Int_t nkftrk, const Int_t * const, const AliKFParticle * const); //recalculate primary vertex after removing given tracks void RecalcPrimvtx(AliESDtrack * const ESDelectron); //recalculate primary vertex after removing given track void GetRecalcPrimvtx(Double_t privtx[3]) const { privtx[0]=fPVxRe; privtx[1]=fPVyRe; privtx[2]=fPVzRe; @@ -59,7 +59,7 @@ class AliHFEpriVtx : public TObject { void GetNPriVxtContributor(); Double_t GetDistanceFromRecalVertexXY(AliESDtrack * const ESDelectron); Int_t GetNsectrk2prim() const {return fNsectrk2prim;}; - Int_t GetMCPID(AliESDtrack *track); // return mc pid + Int_t GetMCPID(AliESDtrack const *track); // return mc pid private: diff --git a/PWG3/hfe/AliHFEsecVtx.cxx b/PWG3/hfe/AliHFEsecVtx.cxx index 4cc3dc34ccc..9396dd2601e 100644 --- a/PWG3/hfe/AliHFEsecVtx.cxx +++ b/PWG3/hfe/AliHFEsecVtx.cxx @@ -40,6 +40,8 @@ #include "AliHFEpairs.h" #include "AliHFEsecVtxs.h" #include "AliHFEtrackFilter.h" +#include "AliHFEmcQA.h" +#include "AliHFEtools.h" ClassImp(AliHFEsecVtx) @@ -49,6 +51,7 @@ AliHFEsecVtx::AliHFEsecVtx(): ,fESD1(0x0) ,fAOD1(0x0) ,fMCEvent(0x0) + ,fMCQA(0x0) ,fUseMCPID(kFALSE) ,fkSourceLabel() ,fNparents(0) @@ -94,6 +97,7 @@ AliHFEsecVtx::AliHFEsecVtx(const AliHFEsecVtx &p): ,fESD1(0x0) ,fAOD1(0x0) ,fMCEvent(0x0) + ,fMCQA(0x0) ,fUseMCPID(p.fUseMCPID) ,fkSourceLabel() ,fNparents(p.fNparents) @@ -205,8 +209,13 @@ void AliHFEsecVtx::Process(AliVTrack *signalTrack){ // // Run Process // - if(signalTrack->Pt() < 1.0) return; + //if(signalTrack->Pt() < 1.0) return; + + AliESDtrack *track = dynamic_cast(signalTrack); + + FillHistos(0,track); // wo any cuts + InitHFEpairs(); InitHFEsecvtxs(); AliESDtrack *htrack = 0x0; @@ -220,20 +229,29 @@ void AliHFEsecVtx::Process(AliVTrack *signalTrack){ PairAnalysis(track, htrack, htrack->GetID()); // e-h pairing } delete trackIter; - /*for(int ip=0; ipHFEpairs()->GetEntriesFast(); ip++){ - if(HasMCData()){ - AliHFEpairs *pair = (AliHFEpairs*) (fSecVtx->HFEpairs()->UncheckedAt(ip)); - if(!(pair->GetPairCode()>1. && pair->GetPairCode()<4.)) // apply various cuts - fSecVtx->HFEpairs()->RemoveAt(ip); - } - }*/ + for(int ip=0; ipGetEntriesFast(); ip++){ + //if(HasMCData()){ + AliHFEpairs *pair = (AliHFEpairs*) (HFEpairs()->UncheckedAt(ip)); + //if(!(pair->GetPairCode()>1. && pair->GetPairCode()<4.)) // apply various cuts + if(pair->GetKFChi2()>5.) // only apply vertex chi2 cut for the moment + HFEpairs()->RemoveAt(ip); + //} + } HFEpairs()->Compress(); - RunSECVTX(track); // secondary vertexing with e,h1,h2,.. tracks + if(HFEpairs()->GetEntriesFast()) FillHistos(1,track); // after paired + if(HFEpairs()->GetEntriesFast()) RunSECVTX(track); // secondary vertexing with e,h1,h2,.. tracks + if(HFEsecvtxs()->GetEntriesFast()) FillHistos(2,track); // after secvtxing for(int ip=0; ipGetEntriesFast(); ip++){ AliHFEsecVtxs *secvtx=0x0; secvtx = (AliHFEsecVtxs*) (HFEsecvtxs()->UncheckedAt(ip)); - // here you apply cuts, then if it doesn't pass the cut, remove it from the fSecVtx->HFEsecvtxs() + // here you apply cuts, then if it doesn't pass the cut, remove it from the HFEsecvtxs() + if(!(secvtx->GetInvmass()>2.0 && secvtx->GetInvmass()<5.2) || !(secvtx->GetSignedLxy2()>0.08 && secvtx->GetSignedLxy2()<1.5) || !(secvtx->GetKFIP2()>-0.1 && secvtx->GetKFIP2()<0.1)) + HFEsecvtxs()->RemoveAt(ip); } + + // fill histos for raw spectra + if(HFEsecvtxs()->GetEntriesFast()) FillHistos(3,track); //after secvtx cut + DeleteHFEpairs(); DeleteHFEsecvtxs(); } @@ -251,6 +269,11 @@ void AliHFEsecVtx::CreateHistograms(TList * const qaList) fSecVtxList->SetName("SecVtx"); MakeContainer(); + MakeHistos(0); + MakeHistos(1); + MakeHistos(2); + MakeHistos(3); + /* fkSourceLabel[kAll]="all"; fkSourceLabel[kDirectCharm]="directCharm"; @@ -929,7 +952,10 @@ void AliHFEsecVtx::CalcSECVTXProperty(AliVTrack* track1, AliVTrack* track2, AliV } //_______________________________________________________________________________________________ -void AliHFEsecVtx::RecalcPrimvtx(Int_t nkftrk, Int_t * const trkid, AliKFParticle * const kftrk){ +void AliHFEsecVtx::RecalcPrimvtx(Int_t nkftrk, const Int_t * const trkid, const AliKFParticle * const kftrk){ + // + // reccalculate primary vertex after removing considering track in the calculation + // const AliESDVertex *primvtx = fESD1->GetPrimaryVertex(); @@ -959,7 +985,7 @@ void AliHFEsecVtx::RecalcPrimvtx(Int_t nkftrk, Int_t * const trkid, AliKFParticl } //_______________________________________________________________________________________________ -Int_t AliHFEsecVtx::GetMCPID(AliESDtrack *track) +Int_t AliHFEsecVtx::GetMCPID(const AliESDtrack *track) { // // return mc pid @@ -1403,7 +1429,7 @@ Int_t AliHFEsecVtx::GetPDG(AliVTrack *track) } //_______________________________________________________________________________________________ -Int_t AliHFEsecVtx::GetMCPDG(AliVTrack *track) +Int_t AliHFEsecVtx::GetMCPDG(const AliVTrack *track) { // // return mc pdg code @@ -1552,25 +1578,6 @@ void AliHFEsecVtx::InitHFEsecvtxs() fNoOfHFEsecvtxs = 0; } -//_______________________________________________________________________________________________ -Bool_t AliHFEsecVtx::SingleTrackCut(AliESDtrack* track) const -{ - //if (track->Pt() < 1.0) return kFALSE; - //if (TMath::Abs(track->Eta()) > 0.9) return kFALSE; - //if (!(track->GetStatus() & AliESDtrack::kITSrefit)) return kFALSE; - //if (!(track->GetStatus() & AliESDtrack::kTPCrefit)) return kFALSE; - if (!(TESTBIT(track->GetITSClusterMap(),0))) return kFALSE; // ask hit on the first pixel layer - //if (!(TESTBIT(track->GetITSClusterMap(),0) | TESTBIT(track->GetITSClusterMap(),1))) return kFALSE; - -/* - Float_t dcaR=-1; - Float_t dcaZ=-1; - track->GetImpactParameters(dcaR,dcaZ); - if (TMath::Abs(TMath::Sqrt(dcaR*dcaR + dcaZ*dcaZ)) < 0.005) return kFALSE; - if (TMath::Abs(TMath::Sqrt(dcaR*dcaR + dcaZ*dcaZ)) > 0.3) return kFALSE; -*/ - return kTRUE; -} //____________________________________________________________ void AliHFEsecVtx::MakeContainer(){ @@ -1644,3 +1651,69 @@ void AliHFEsecVtx::MakeContainer(){ for(Int_t ivar = 0; ivar < nDimSecvtx; ivar++) delete binEdgesSecvtx[ivar]; } + +//____________________________________________________________ +void AliHFEsecVtx::MakeHistos(Int_t step){ + + // + // make container + // + + TString hname=Form("step%d",step); + step = step*7; + + const Double_t kPtbound[2] = {0.1, 20.}; + Int_t iBin[1]; + iBin[0] = 44; // bins in pt + Double_t* binEdges[1]; + binEdges[0] = AliHFEtools::MakeLogarithmicBinning(iBin[0], kPtbound[0], kPtbound[1]); + + fSecVtxList->AddAt(new TH1F(hname+"taggedElec", "pT of e", iBin[0],binEdges[0]), step); + fSecVtxList->AddAt(new TH1F(hname+"charmElec", "pT of e", iBin[0],binEdges[0]), step+1); + fSecVtxList->AddAt(new TH1F(hname+"beautyElec", "pT of e", iBin[0],binEdges[0]), step+2); + fSecVtxList->AddAt(new TH1F(hname+"conversionElec", "pT of e", iBin[0],binEdges[0]), step+3); + fSecVtxList->AddAt(new TH1F(hname+"ebgElec", "pT of e", iBin[0],binEdges[0]), step+4); + fSecVtxList->AddAt(new TH1F(hname+"hcontaminElec", "pT of e", iBin[0],binEdges[0]), step+5); + fSecVtxList->AddAt(new TH1F(hname+"elseElec", "pT of e", iBin[0],binEdges[0]), step+6); +} + +//____________________________________________________________ +void AliHFEsecVtx::FillHistos(Int_t step, const AliESDtrack *track){ + + // + // make container + // + + step = step*7; + + AliMCParticle *mctrack = NULL; + TParticle* mcpart = NULL; + + (dynamic_cast(fSecVtxList->At(step)))->Fill(track->Pt()); // electrons tagged + + if(HasMCData()){ + if(!(mctrack = dynamic_cast(fMCEvent->GetTrack(TMath::Abs(track->GetLabel()))))) return; + mcpart = mctrack->Particle(); + + Int_t esource=fMCQA->GetElecSource(mcpart); + if(esource==1) { + (dynamic_cast(fSecVtxList->At(step+1)))->Fill(mcpart->Pt()); //charm + } + else if(esource==2 || esource==3) { + (dynamic_cast(fSecVtxList->At(step+2)))->Fill(mcpart->Pt()); //beauty + } + else if(esource==4) { + (dynamic_cast(fSecVtxList->At(step+3)))->Fill(mcpart->Pt()); //conversion + } + else if(esource==7) { + (dynamic_cast(fSecVtxList->At(step+5)))->Fill(mcpart->Pt()); //contamination + } + else if(!(esource<0)) { + (dynamic_cast(fSecVtxList->At(step+4)))->Fill(mcpart->Pt()); //e backgrounds + } + else { + (dynamic_cast(fSecVtxList->At(step+6)))->Fill(mcpart->Pt()); //something else? + } + } + +} diff --git a/PWG3/hfe/AliHFEsecVtx.h b/PWG3/hfe/AliHFEsecVtx.h index cfac67b3935..c8fb79a3885 100644 --- a/PWG3/hfe/AliHFEsecVtx.h +++ b/PWG3/hfe/AliHFEsecVtx.h @@ -42,6 +42,7 @@ class AliHFEtrackFilter; class AliHFEpairs; class AliHFEsecVtxs; class AliKFParticle; +class AliHFEmcQA; //________________________________________________________________ class AliHFEsecVtx : public TObject { @@ -68,10 +69,11 @@ class AliHFEsecVtx : public TObject { void SetMCEvent(AliMCEvent* const mcEvent){fMCEvent=mcEvent;}; // set stack pointer void SetMCArray(TClonesArray* const mcarry){fMCArray=mcarry;} // set mcarray pointer void SetUseMCPID(Bool_t usemcpid){fUseMCPID=usemcpid;}; + void SetMCQA(AliHFEmcQA * const mcqa){fMCQA=mcqa;}; // set mcqa pointer - Int_t GetMCPID(AliESDtrack *track); // return MC pid - Int_t GetMCPDG(AliVTrack *track); // return MC pid + Int_t GetMCPID(const AliESDtrack *track); // return MC pid + Int_t GetMCPDG(const AliVTrack *track); // return MC pid Int_t GetPairOriginESD(AliESDtrack* track1, AliESDtrack* track2); // return pair origin as a pdg code Int_t GetPairOriginAOD(AliAODTrack* track1, AliAODTrack* track2); // return pair origin as a pdg code Int_t GetPairCode(const AliVTrack* const track1, const AliVTrack* const track2); // return corresponding pair code to pdg code @@ -79,7 +81,7 @@ class AliHFEsecVtx : public TObject { Int_t GetPDG(AliVTrack *track); // return pdg void GetESDPID(AliESDtrack *track, Int_t &recpid, Double_t &recprob); //return esd pid likelihood void GetPrimaryCondition(); - void RecalcPrimvtx(Int_t nkftrk, Int_t * const, AliKFParticle * const); //recalculate primary vertex + void RecalcPrimvtx(Int_t nkftrk, const Int_t * const, const AliKFParticle * const); //recalculate primary vertex TClonesArray *HFEpairs(); TClonesArray *HFEsecvtxs(); @@ -93,11 +95,12 @@ class AliHFEsecVtx : public TObject { void DeleteHFEpairs(); void DeleteHFEsecvtxs(); - Bool_t SingleTrackCut(AliESDtrack* track1) const; // single track cut void PairAnalysis(AliVTrack* ESDtrack1, AliVTrack* ESDtrack2, Int_t index2); // do e-h analysis void RunSECVTX(AliVTrack *track); // run secondary vertexing algorithm void MakeContainer(); // make containers + void MakeHistos(Int_t step); // make histograms for different steps + void FillHistos(Int_t step, const AliESDtrack *track); // fill histograms for different steps protected: void Init(); @@ -122,6 +125,8 @@ class AliHFEsecVtx : public TObject { AliAODEvent* fAOD1; // AOD pointer AliMCEvent* fMCEvent; // MCEvent pointer + AliHFEmcQA* fMCQA; // mcqa pointer + Bool_t fUseMCPID; // if use MC pid TString fkSourceLabel[10]; // electron source label diff --git a/PWG3/hfe/AliHFEsignalCuts.cxx b/PWG3/hfe/AliHFEsignalCuts.cxx new file mode 100644 index 00000000000..0d25d7bb849 --- /dev/null +++ b/PWG3/hfe/AliHFEsignalCuts.cxx @@ -0,0 +1,309 @@ +/************************************************************************** +* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * +* * +* Author: The ALICE Off-line Project. * +* Contributors are mentioned in the code where appropriate. * +* * +* Permission to use, copy, modify and distribute this software and its * +* documentation strictly for non-commercial purposes is hereby granted * +* without fee, provided that the above copyright notice appears in all * +* copies and that both the copyright notice and this permission notice * +* appear in the supporting documentation. The authors make no claims * +* about the suitability of this software for any purpose. It is * +* provided "as is" without express or implied warranty. * +**************************************************************************/ +// +// Signal cuts +// Checks whether a particle (reconstructed or MC) is coming from MC Signal +// For more information see implementation file +// +// Autor: +// Markus Fasel +// +#include +#include +#include +#include + +#include "AliAODMCParticle.h" +#include "AliLog.h" +#include "AliMCEvent.h" +#include "AliMCParticle.h" +#include "AliVParticle.h" + +#include "AliHFEsignalCuts.h" +#include "AliHFEmcQA.h" + +ClassImp(AliHFEsignalCuts) + +//____________________________________________________________ +AliHFEsignalCuts::AliHFEsignalCuts(): + AliAnalysisCuts(), + fMC(NULL), + fMCQA(NULL) +{ + // + // Dummy constructor + // +} + +//____________________________________________________________ +AliHFEsignalCuts::AliHFEsignalCuts(const Char_t *name, const Char_t *title): + AliAnalysisCuts(name, title), + fMC(NULL), + fMCQA(NULL) +{ + // + // Default constructor + // + fMCQA = new AliHFEmcQA; + if(fMCQA) fMCQA->Init(); +} + +//____________________________________________________________ +AliHFEsignalCuts::AliHFEsignalCuts(const AliHFEsignalCuts &ref): + AliAnalysisCuts(ref), + fMC(ref.fMC), + fMCQA(ref.fMCQA) +{ + // + // Copy constructor + // +} + +//____________________________________________________________ +AliHFEsignalCuts &AliHFEsignalCuts::operator=(const AliHFEsignalCuts &ref){ + // + // Assignment operator + // + if(this != &ref){ + fMC = ref.fMC; + fMCQA = ref.fMCQA; + } + return *this; +} + +//____________________________________________________________ +AliHFEsignalCuts::~AliHFEsignalCuts(){ + // + // Destructor + // + if(fMCQA) delete fMCQA; +} + +//____________________________________________________________ +void AliHFEsignalCuts::SetMCEvent(AliMCEvent *mc){ + // + // Set mc event + // + fMC = mc; + if(fMCQA) fMCQA->SetMCEvent(mc); +} + +//____________________________________________________________ +Bool_t AliHFEsignalCuts::IsSelected(TObject *o){ + // + // Define signal as electron coming from charm or beauty + // @TODO: Implement setter so that also either of them can be defined + // as signal alone + + + return IsCharmElectron(o) || IsBeautyElectron(o); +/* + //saving time? + Int_t esources = GetElecSource(dynamic_cast(o)); + if(esources>0)printf("esources= %d\n",esources); + if(esources == AliHFEmcQA::kDirectCharm || esources == AliHFEmcQA::kDirectBeauty || esources == AliHFEmcQA::kBeautyCharm) // 1: direct D->e, 2: B->e 3: B->D->e + return kTRUE; + else + return kFALSE; +*/ + +} + +//____________________________________________________________ +Bool_t AliHFEsignalCuts::IsCharmElectron(const TObject * const o) const { + // + // Check if mother is coming from Charm + // + Int_t esources = GetElecSource(dynamic_cast(o)); + if(esources == AliHFEmcQA::kDirectCharm) // 1: direct D->e + return kTRUE; + else + return kFALSE; +} + +//____________________________________________________________ +Bool_t AliHFEsignalCuts::IsBeautyElectron(const TObject * const o) const { + // + // Check if mother is coming from Beauty + // + Int_t esources = GetElecSource(dynamic_cast(o)); + if(esources == AliHFEmcQA::kDirectBeauty || esources == AliHFEmcQA::kBeautyCharm) // 2: B->e 3: B->D->e + return kTRUE; + else + return kFALSE; +} + +//____________________________________________________________ +Bool_t AliHFEsignalCuts::IsGammaElectron(const TObject * const o) const { + // + // Check for MC if the electron is coming from Gamma + // + Int_t esources = GetElecSource(dynamic_cast(o)); + if(esources == AliHFEmcQA::kGamma) // 4: conversion electrons + return kTRUE; + else + return kFALSE; +} + +/* +//____________________________________________________________ +Bool_t AliHFEsignalCuts::IsCharmElectron(const TObject * const o) const { + // + // Check if mother is coming from Charm + // + if(TMath::Abs(GetTrackPDG(dynamic_cast(o))) != 11) return kFALSE; + Int_t motherpdg = TMath::Abs(GetMotherPDG(dynamic_cast(o))); + AliDebug(1, Form("Mother PDG %d\n", motherpdg)); + + if((motherpdg % 1000) / 100 == 4) return kTRUE; // charmed meson, 3rd position in pdg code == 4 + if(motherpdg / 1000 == 4) return kTRUE; // charmed baryon, 4th position in pdg code == 4 + AliDebug(1, "No Charm\n"); + return kFALSE; +} + +//____________________________________________________________ +Bool_t AliHFEsignalCuts::IsBeautyElectron(const TObject * const o) const { + // + // Check if mother is coming from Beauty + // + if(TMath::Abs(GetTrackPDG(dynamic_cast(o))) != 11) return kFALSE; + Int_t motherpdg = TMath::Abs(GetMotherPDG(dynamic_cast(o))); + AliDebug(1, Form("Mother PDG %d\n", motherpdg)); + + if((motherpdg % 1000) / 100 == 5) return kTRUE; // beauty meson, 3rd position in pdg code == 5 + if(motherpdg / 1000 == 5) return kTRUE; // beauty baryon, 4th position in pdg code == 5 + AliDebug(1, "No Beauty\n"); + return kFALSE; +} + +//____________________________________________________________ +Bool_t AliHFEsignalCuts::IsGammaElectron(const TObject * const o) const { + // + // Check for MC if the electron is coming from Gamma + // + if(TMath::Abs(GetTrackPDG(dynamic_cast(o))) != 11) return kFALSE; + Int_t motherpdg = TMath::Abs(GetMotherPDG(dynamic_cast(o))); + AliDebug(1, Form("Mother PDG %d\n", motherpdg)); + + if(motherpdg!=22){ + AliDebug(1, "No Gamma"); + return kFALSE; + } else { + AliDebug(1, "Gamma"); + return kTRUE; + } +} +*/ + +//____________________________________________________________ +Int_t AliHFEsignalCuts::GetMotherPDG(const AliVParticle * const track) const { + // + // Get Mother Pdg code for reconstructed respectively MC tracks + // + if(!fMC){ + AliDebug(1, "No MC Event Available\n"); + return 0; + } + const AliVParticle *motherParticle = NULL, *mctrack = NULL; + TString objectType = track->IsA()->GetName(); + if(objectType.CompareTo("AliESDtrack") == 0 || objectType.CompareTo("AliAODTrack") == 0){ + // Reconstructed track + if(track->GetLabel()) + mctrack = fMC->GetTrack(TMath::Abs(track->GetLabel())); + } else { + // MCParticle + mctrack = track; + } + + if(!mctrack) return 0; + + Int_t motherPDG = 0; + if(TString(mctrack->IsA()->GetName()).CompareTo("AliMCParticle") == 0){ + // case MC Particle + motherParticle = fMC->GetTrack((dynamic_cast(mctrack)->Particle()->GetFirstMother())); + if(motherParticle) + motherPDG = TMath::Abs((dynamic_cast(motherParticle))->Particle()->GetPdgCode()); + } else { + // case AODMCParticle + motherParticle = fMC->GetTrack((dynamic_cast(mctrack))->GetMother()); + if(motherParticle) + motherPDG = TMath::Abs((dynamic_cast(motherParticle))->GetPdgCode()); + } + return motherPDG; +} + +//____________________________________________________________ +Int_t AliHFEsignalCuts::GetTrackPDG(const AliVParticle * const track) const { + // + // Return PDG code of a particle itself + // + if(!fMC){ + AliDebug(1, "No MC Event Available\n"); + return 0; + } + TString sourcetype = track->IsA()->GetName(); + const AliVParticle *mctrack = NULL; + if(!sourcetype.CompareTo("AliESDtrack") || !sourcetype.CompareTo("AliAODTrack")){ + mctrack = fMC->GetTrack(TMath::Abs(track->GetLabel())); + } else mctrack = track; + if(!mctrack) return 0; + + TString mctype = mctrack->IsA()->GetName(); + Int_t trackPdg = 0; + if(!mctype.CompareTo("AliMCParticle")){ + const AliMCParticle *esdmc = dynamic_cast(mctrack); + trackPdg = esdmc->Particle()->GetPdgCode(); + } else { + const AliAODMCParticle *aodmc = dynamic_cast< const AliAODMCParticle *>(mctrack); + trackPdg = aodmc->GetPdgCode(); + } + return trackPdg; +} + +//____________________________________________________________ +Int_t AliHFEsignalCuts::GetElecSource(const AliVParticle * const track) const { + // + // Return PDG code of a particle itself + // + + if(!fMC){ + AliDebug(1, "No MC Event Available\n"); + return 0; + } + if(!fMCQA){ + AliDebug(1, "No MCQA Available\n"); + return 0; + } + + TString sourcetype = track->IsA()->GetName(); + const AliVParticle *mctrack = NULL; + TParticle *mcpart = NULL; + if(!sourcetype.CompareTo("AliESDtrack") || !sourcetype.CompareTo("AliAODTrack")){ + mctrack = fMC->GetTrack(TMath::Abs(track->GetLabel())); + } else mctrack = track; + if(!mctrack) return 0; + + TString mctype = mctrack->IsA()->GetName(); + Int_t eSource = 0; + if(!mctype.CompareTo("AliMCParticle")){ + const AliMCParticle *esdmc = dynamic_cast(mctrack); + mcpart = esdmc->Particle(); + eSource=fMCQA->GetElecSource(mcpart); + } else { + return -1; + } + + return eSource; +} diff --git a/PWG3/hfe/AliHFEsignalCuts.h b/PWG3/hfe/AliHFEsignalCuts.h new file mode 100644 index 00000000000..3afa91cebb5 --- /dev/null +++ b/PWG3/hfe/AliHFEsignalCuts.h @@ -0,0 +1,62 @@ +/************************************************************************** +* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * +* * +* Author: The ALICE Off-line Project. * +* Contributors are mentioned in the code where appropriate. * +* * +* Permission to use, copy, modify and distribute this software and its * +* documentation strictly for non-commercial purposes is hereby granted * +* without fee, provided that the above copyright notice appears in all * +* copies and that both the copyright notice and this permission notice * +* appear in the supporting documentation. The authors make no claims * +* about the suitability of this software for any purpose. It is * +* provided "as is" without express or implied warranty. * +**************************************************************************/ +// +// Signal cuts +// Checks whether a particle (reconstructed or MC) is coming from MC Signal +// For more information see implementation file +// +#ifndef ALIHFESIGNALCUTS_H +#define ALIHFESIGNALCUTS_H + +#ifndef ALIANALYSISCUTS_H +#include "AliAnalysisCuts.h" +#endif + +class TList; +class AliMCEvent; +class AliVParticle; +class AliHFEmcQA; + +class AliHFEsignalCuts : public AliAnalysisCuts{ + public: + AliHFEsignalCuts(); + AliHFEsignalCuts(const Char_t *name, const Char_t *title); + AliHFEsignalCuts(const AliHFEsignalCuts &ref); + AliHFEsignalCuts &operator=(const AliHFEsignalCuts &ref); + virtual ~AliHFEsignalCuts(); + + virtual Bool_t IsSelected(TObject *o); + virtual Bool_t IsSelected(TList * /*l*/) { return kTRUE; }; + + Bool_t IsCharmElectron(const TObject * const o) const; + Bool_t IsBeautyElectron(const TObject * const o) const; + Bool_t IsGammaElectron(const TObject * const o) const; + + //void SetMCEvent(AliMCEvent *mc) { fMC = mc; } + void SetMCEvent(AliMCEvent *mc); + + protected: + Int_t GetMotherPDG(const AliVParticle * const track) const; + Int_t GetTrackPDG(const AliVParticle * const track) const; + Int_t GetElecSource(const AliVParticle * const track) const ; + + private: + AliMCEvent *fMC; //! MC event + AliHFEmcQA *fMCQA; //! MC QA + + ClassDef(AliHFEsignalCuts, 2) +}; +#endif + diff --git a/PWG3/hfe/AliHFEspectrum.cxx b/PWG3/hfe/AliHFEspectrum.cxx index 7f0312df30e..218164b7a60 100644 --- a/PWG3/hfe/AliHFEspectrum.cxx +++ b/PWG3/hfe/AliHFEspectrum.cxx @@ -42,7 +42,7 @@ #include #include - +#include "AliPID.h" #include "AliCFContainer.h" #include "AliCFDataGrid.h" #include "AliCFEffGrid.h" @@ -51,6 +51,8 @@ #include "AliLog.h" #include "AliHFEspectrum.h" +#include "AliHFEcuts.h" +#include "AliHFEcontainer.h" ClassImp(AliHFEspectrum) @@ -61,14 +63,18 @@ AliHFEspectrum::AliHFEspectrum(const char *name): fTemporaryObjects(NULL), fCorrelation(NULL), fBackground(NULL), - fBackgroundSource(kMCbackground), + fInclusiveSpectrum(kTRUE), fDumpToFile(kFALSE), + fNbDimensions(1), fNEvents(0), fStepMC(-1), fStepTrue(-1), fStepData(-1), + fStepBeforeCutsV0(-1), + fStepAfterCutsV0(-1), fStepGuessedUnfolding(-1), - fNumberOfIterations(5) + fNumberOfIterations(5), + fDebugLevel(0) { // // Default constructor @@ -86,9 +92,125 @@ AliHFEspectrum::~AliHFEspectrum(){ delete fTemporaryObjects; } } +//____________________________________________________________ +Bool_t AliHFEspectrum::Init(AliHFEcontainer *datahfecontainer,AliHFEcontainer *mchfecontainer,AliHFEcontainer *v0hfecontainer){ + // + // Init what we need for the correction: + // + // Raw spectrum, hadron contamination + // MC efficiency maps, correlation matrix + // V0 efficiency if wanted + // + // This for a given dimension. + // If no inclusive spectrum, then take only efficiency map for beauty electron + // and the appropriate correlation matrix + // + + // Get the requested format + Int_t dims[3]; + switch(fNbDimensions){ + case 1: dims[0] = 0; + break; + case 2: for(Int_t i = 0; i < 2; i++) dims[i] = i; + break; + case 3: for(Int_t i = 0; i < 3; i++) dims[i] = i; + break; + default: + AliError("Container with this number of dimensions not foreseen (yet)"); + return kFALSE; + }; + + // Data container: raw spectrum + hadron contamination + AliCFContainer *datacontainer = datahfecontainer->GetCFContainer("recTrackContReco"); + AliCFContainer *contaminationcontainer = datahfecontainer->GetCFContainer("hadronicBackground"); + if((!datacontainer) || (!contaminationcontainer)) return kFALSE; + + AliCFContainer *datacontainerD = GetSlicedContainer(datacontainer, fNbDimensions, dims); + AliCFContainer *contaminationcontainerD = GetSlicedContainer(contaminationcontainer, fNbDimensions, dims); + if((!datacontainerD) || (!contaminationcontainerD)) return kFALSE; + SetContainer(datacontainerD,AliHFEspectrum::kDataContainer); + SetContainer(contaminationcontainerD,AliHFEspectrum::kBackgroundData); + + // MC container: ESD/MC efficiency maps + MC/MC efficiency maps + AliCFContainer *mccontaineresd = 0x0; + AliCFContainer *mccontainermc = 0x0; + if(fInclusiveSpectrum) { + mccontaineresd = mchfecontainer->MakeMergedCFContainer("sumesd","sumesd","MCTrackCont:recTrackContReco"); + mccontainermc = mchfecontainer->MakeMergedCFContainer("summc","summc","MCTrackCont:recTrackContMC"); + } + else { + mccontaineresd = mchfecontainer->MakeMergedCFContainer("sumesd","sumesd","MCTrackCont:recTrackContReco:recTrackContDEReco"); + mccontainermc = mchfecontainer->MakeMergedCFContainer("summc","summc","MCTrackCont:recTrackContMC:recTrackContDEMC"); + } + if((!mccontaineresd) || (!mccontainermc)) return kFALSE; + + Int_t source = -1; + if(!fInclusiveSpectrum) source = 1; + AliCFContainer *mccontaineresdD = GetSlicedContainer(mccontaineresd, fNbDimensions, dims, source); + AliCFContainer *mccontainermcD = GetSlicedContainer(mccontainermc, fNbDimensions, dims, source); + if((!mccontaineresdD) || (!mccontainermcD)) return kFALSE; + SetContainer(mccontainermcD,AliHFEspectrum::kMCContainerMC); + SetContainer(mccontaineresdD,AliHFEspectrum::kMCContainerESD); + + // MC container: correlation matrix + THnSparseF *mccorrelation = 0x0; + if(fInclusiveSpectrum) mccorrelation = mchfecontainer->GetCorrelationMatrix("correlationstepafterPID"); + else mccorrelation = mchfecontainer->GetCorrelationMatrix("correlationstepafterDE"); + if(!mccorrelation) return kFALSE; + THnSparseF *mccorrelationD = GetSlicedCorrelation(mccorrelation, fNbDimensions, dims); + if(!mccorrelationD) { + printf("No correlation\n"); + return kFALSE; + } + SetCorrelation(mccorrelationD); + + // V0 container Electron, pt eta phi + if(v0hfecontainer) { + AliCFContainer *containerV0 = v0hfecontainer->GetCFContainer("taggedTrackContainerReco"); + if(!containerV0) return kFALSE; + AliCFContainer *containerV0Electron = GetSlicedContainer(containerV0, fNbDimensions, dims, AliPID::kElectron+1); + if(!containerV0Electron) return kFALSE; + SetContainer(containerV0Electron,AliHFEspectrum::kDataContainerV0); + } + + if(fDebugLevel>0){ + + AliCFDataGrid *contaminationspectrum = (AliCFDataGrid *) ((AliCFDataGrid *)GetSpectrum(contaminationcontainer,1))->Clone(); + contaminationspectrum->SetName("contaminationspectrum"); + TCanvas * ccontaminationspectrum = new TCanvas("contaminationspectrum","contaminationspectrum",1000,700); + ccontaminationspectrum->Divide(3,1); + ccontaminationspectrum->cd(1); + TH2D * contaminationspectrum2dpteta = contaminationspectrum->Project(1,0); + TH2D * contaminationspectrum2dptphi = contaminationspectrum->Project(2,0); + TH2D * contaminationspectrum2detaphi = contaminationspectrum->Project(1,2); + contaminationspectrum2dpteta->SetStats(0); + contaminationspectrum2dpteta->SetTitle(""); + contaminationspectrum2dpteta->GetXaxis()->SetTitle("#eta"); + contaminationspectrum2dpteta->GetYaxis()->SetTitle("p_{T} [GeV/c]"); + contaminationspectrum2dptphi->SetStats(0); + contaminationspectrum2dptphi->SetTitle(""); + contaminationspectrum2dptphi->GetXaxis()->SetTitle("#phi [rad]"); + contaminationspectrum2dptphi->GetYaxis()->SetTitle("p_{T} [GeV/c]"); + contaminationspectrum2detaphi->SetStats(0); + contaminationspectrum2detaphi->SetTitle(""); + contaminationspectrum2detaphi->GetXaxis()->SetTitle("#eta"); + contaminationspectrum2detaphi->GetYaxis()->SetTitle("#phi [rad]"); + contaminationspectrum2dptphi->Draw("colz"); + ccontaminationspectrum->cd(2); + contaminationspectrum2dpteta->Draw("colz"); + ccontaminationspectrum->cd(3); + contaminationspectrum2detaphi->Draw("colz"); + + } + + + return kTRUE; + + +} //____________________________________________________________ -void AliHFEspectrum::Correct(AliCFContainer *datacontainer,AliCFContainer *mccontainer,THnSparseF *mccorrelation, AliCFContainer *contaminationcontainer){ +Bool_t AliHFEspectrum::Correct(Bool_t subtractcontamination){ // // Correct the spectrum for efficiency and unfolding // with both method and compare @@ -101,71 +223,184 @@ void AliHFEspectrum::Correct(AliCFContainer *datacontainer,AliCFContainer *mccon gStyle->SetPadLeftMargin(0.13); gStyle->SetPadRightMargin(0.13); - SetMCEffStep(8); - SetMCTruthStep(0); - SetNumberOfIteration(5); - SetStepGuessedUnfolding(16); - SetNumberOfIteration(5); - SetStepToCorrect(20); - - ////////////////// - // Take only pt - ///////////////// - - AliCFDataGrid *dataspectrumbeforesubstraction = (AliCFDataGrid *) ((AliCFDataGrid *)GetSpectrum(datacontainer,20))->Clone(); - dataspectrumbeforesubstraction->SetName("dataspectrumbeforesubstraction"); + /////////////////////////// + // Check initialization + /////////////////////////// - // + if((!GetContainer(kDataContainer)) || (!GetContainer(kMCContainerMC)) || (!GetContainer(kMCContainerESD))){ + AliInfo("You have to init before"); + return kFALSE; + } + + if((fStepTrue == 0) && (fStepMC == 0) && (fStepData == 0)) { + AliInfo("You have to set the steps before: SetMCTruthStep, SetMCEffStep, SetStepToCorrect"); + return kFALSE; + } + + SetNumberOfIteration(50); + SetStepGuessedUnfolding(AliHFEcuts::kStepRecKineITSTPC + AliHFEcuts::kNcutStepsMCTrack); + + AliCFDataGrid *dataGridAfterFirstSteps = 0x0; + ////////////////////////////////// + // Subtract hadron background + ///////////////////////////////// AliCFDataGrid *dataspectrumaftersubstraction = 0x0; - SetCorrelation(mccorrelation); - SetContainer(datacontainer,AliHFEspectrum::kDataContainer); - SetContainer(mccontainer,AliHFEspectrum::kMCContainer); - if(contaminationcontainer) { - SetContainer(contaminationcontainer,AliHFEspectrum::kBackgroundData); - SetBackgroundSource(AliHFEspectrum::kDataBackground); - dataspectrumaftersubstraction = SubtractBackground(1,kTRUE); + if(subtractcontamination) { + dataspectrumaftersubstraction = SubtractBackground(kTRUE); + dataGridAfterFirstSteps = dataspectrumaftersubstraction; + } + + //////////////////////////////////////////////// + // Correct for TPC efficiency from V0 + /////////////////////////////////////////////// + AliCFDataGrid *dataspectrumafterV0efficiencycorrection = 0x0; + AliCFContainer *dataContainerV0 = GetContainer(kDataContainerV0); + if(dataContainerV0){ + dataspectrumafterV0efficiencycorrection = CorrectV0Efficiency(dataspectrumaftersubstraction); + dataGridAfterFirstSteps = dataspectrumafterV0efficiencycorrection; } + /////////////// // Unfold - - TList *listunfolded = Unfold(1,dataspectrumaftersubstraction); + ////////////// + TList *listunfolded = Unfold(dataGridAfterFirstSteps); if(!listunfolded){ printf("Unfolded failed\n"); - return; + return kFALSE; } THnSparse *correctedspectrum = (THnSparse *) listunfolded->At(0); THnSparse *residualspectrum = (THnSparse *) listunfolded->At(1); if(!correctedspectrum){ AliError("No corrected spectrum\n"); - return; + return kFALSE; } if(!residualspectrum){ AliError("No residul spectrum\n"); - return; + return kFALSE; } + ///////////////////// // Simply correct - SetMCEffStep(20); - AliCFDataGrid *alltogetherCorrection = CorrectForEfficiency(1,dataspectrumaftersubstraction); + //////////////////// + AliCFDataGrid *alltogetherCorrection = CorrectForEfficiency(dataGridAfterFirstSteps); + ////////// // Plot ////////// - AliCFDataGrid *dataspectrum = 0x0; - TH1D *measuredTH1Daftersubstraction = 0x0; - TH1D *measuredTH1Dbeforesubstraction = 0x0; - TH1D *measuredTH1background = 0x0; - AliCFDataGrid *contaminationspectrum = 0x0; - if(dataspectrumaftersubstraction) dataspectrum = dataspectrumaftersubstraction; - else dataspectrum = dataspectrumbeforesubstraction; - - if(dataspectrumaftersubstraction) { + if(fDebugLevel > 0.0) { + + TCanvas * ccorrected = new TCanvas("corrected","corrected",1000,700); + ccorrected->Divide(2,1); + ccorrected->cd(1); + gPad->SetLogy(); + TGraphErrors* correctedspectrumD = Normalize(correctedspectrum); + correctedspectrumD->SetTitle(""); + correctedspectrumD->GetYaxis()->SetTitleOffset(1.5); + correctedspectrumD->GetYaxis()->SetRangeUser(0.000000001,1.0); + correctedspectrumD->SetMarkerStyle(26); + correctedspectrumD->SetMarkerColor(kBlue); + correctedspectrumD->SetLineColor(kBlue); + correctedspectrumD->Draw("AP"); + TGraphErrors* alltogetherspectrumD = Normalize(alltogetherCorrection); + alltogetherspectrumD->SetTitle(""); + alltogetherspectrumD->GetYaxis()->SetTitleOffset(1.5); + alltogetherspectrumD->GetYaxis()->SetRangeUser(0.000000001,1.0); + alltogetherspectrumD->SetMarkerStyle(25); + alltogetherspectrumD->SetMarkerColor(kBlack); + alltogetherspectrumD->SetLineColor(kBlack); + alltogetherspectrumD->Draw("P"); + TLegend *legcorrected = new TLegend(0.4,0.6,0.89,0.89); + legcorrected->AddEntry(correctedspectrumD,"Corrected","p"); + legcorrected->AddEntry(alltogetherspectrumD,"Alltogether","p"); + legcorrected->Draw("same"); + ccorrected->cd(2); + TH1D *correctedTH1D = correctedspectrum->Projection(0); + TH1D *alltogetherTH1D = alltogetherCorrection->Project(0); + TH1D* ratiocorrected = (TH1D*)correctedTH1D->Clone(); + ratiocorrected->SetName("ratiocorrected"); + ratiocorrected->SetTitle(""); + ratiocorrected->GetYaxis()->SetTitle("Unfolded/DirectCorrected"); + ratiocorrected->GetXaxis()->SetTitle("p_{T} [GeV/c]"); + ratiocorrected->Divide(correctedTH1D,alltogetherTH1D,1,1); + ratiocorrected->SetStats(0); + ratiocorrected->Draw(); + + + // Dump to file if needed + + if(fDumpToFile) { + + TFile *out = new TFile("finalSpectrum.root","recreate"); + out->cd(); + // + correctedspectrumD->SetName("UnfoldingCorrectedSpectrum"); + correctedspectrumD->Write(); + alltogetherspectrumD->SetName("AlltogetherSpectrum"); + alltogetherspectrumD->Write(); + ratiocorrected->SetName("RatioUnfoldingAlltogetherSpectrum"); + ratiocorrected->Write(); + // + correctedspectrum->SetName("UnfoldingCorrectedNotNormalizedSpectrum"); + correctedspectrum->Write(); + alltogetherCorrection->SetName("AlltogetherCorrectedNotNormalizedSpectrum"); + alltogetherCorrection->Write(); + // + out->Close(); delete out; + } + + + } + + + + + return kTRUE; +} +//____________________________________________________________ +AliCFDataGrid* AliHFEspectrum::SubtractBackground(Bool_t setBackground){ + // + // Apply background subtraction + // + + // Raw spectrum + AliCFContainer *dataContainer = GetContainer(kDataContainer); + if(!dataContainer){ + AliError("Data Container not available"); + return NULL; + } + AliCFDataGrid *spectrumSubtracted = new AliCFDataGrid("spectrumSubtracted", "Data Grid for spectrum after Background subtraction", *dataContainer,fStepData); + + AliCFDataGrid *dataspectrumbeforesubstraction = (AliCFDataGrid *) ((AliCFDataGrid *)GetSpectrum(GetContainer(kDataContainer),fStepData))->Clone(); + dataspectrumbeforesubstraction->SetName("dataspectrumbeforesubstraction"); + + // Background Estimate + AliCFContainer *backgroundContainer = GetContainer(kBackgroundData); + if(!backgroundContainer){ + AliError("MC background container not found"); + return NULL; + } + + Int_t stepbackground = 1; + if(!fInclusiveSpectrum) stepbackground = 2; + AliCFDataGrid *backgroundGrid = new AliCFDataGrid("ContaminationGrid","ContaminationGrid",*backgroundContainer,stepbackground); + + // Subtract + spectrumSubtracted->Add(backgroundGrid,-1.0); + if(setBackground){ + if(fBackground) delete fBackground; + fBackground = backgroundGrid; + } else delete backgroundGrid; + + + if(fDebugLevel > 0) { TCanvas * cbackgroundsubtraction = new TCanvas("backgroundsubtraction","backgroundsubtraction",1000,700); - if(fBackground) cbackgroundsubtraction->Divide(3,1); + cbackgroundsubtraction->Divide(3,1); cbackgroundsubtraction->cd(1); - measuredTH1Daftersubstraction = (TH1D*)dataspectrumaftersubstraction->Project(0); - measuredTH1Dbeforesubstraction = (TH1D*)dataspectrumbeforesubstraction->Project(0); + gPad->SetLogy(); + TH1D *measuredTH1Daftersubstraction = spectrumSubtracted->Project(0); + TH1D *measuredTH1Dbeforesubstraction = dataspectrumbeforesubstraction->Project(0); CorrectFromTheWidth(measuredTH1Daftersubstraction); CorrectFromTheWidth(measuredTH1Dbeforesubstraction); measuredTH1Daftersubstraction->SetStats(0); @@ -185,10 +420,11 @@ void AliHFEspectrum::Correct(AliCFContainer *datacontainer,AliCFContainer *mccon measuredTH1Daftersubstraction->Draw(); measuredTH1Dbeforesubstraction->Draw("same"); TLegend *legsubstraction = new TLegend(0.4,0.6,0.89,0.89); - legsubstraction->AddEntry(measuredTH1Dbeforesubstraction,"before substraction","p"); - legsubstraction->AddEntry(measuredTH1Daftersubstraction,"after substraction","p"); + legsubstraction->AddEntry(measuredTH1Dbeforesubstraction,"With hadron contamination","p"); + legsubstraction->AddEntry(measuredTH1Daftersubstraction,"Without hadron contamination ","p"); legsubstraction->Draw("same"); cbackgroundsubtraction->cd(2); + gPad->SetLogy(); TH1D* ratiomeasuredcontamination = (TH1D*)measuredTH1Dbeforesubstraction->Clone(); ratiomeasuredcontamination->SetName("ratiomeasuredcontamination"); ratiomeasuredcontamination->SetTitle(""); @@ -201,270 +437,109 @@ void AliHFEspectrum::Correct(AliCFContainer *datacontainer,AliCFContainer *mccon ratiomeasuredcontamination->SetMarkerColor(kBlack); ratiomeasuredcontamination->SetLineColor(kBlack); ratiomeasuredcontamination->Draw(); - if(fBackground) { - cbackgroundsubtraction->cd(3); - measuredTH1background = (TH1D*)fBackground->Project(0); - CorrectFromTheWidth(measuredTH1background); - measuredTH1background->SetStats(0); - measuredTH1background->SetTitle(""); - measuredTH1background->GetYaxis()->SetTitle("dN/dp_{T} [(GeV/c)^{-1}]"); - measuredTH1background->GetXaxis()->SetTitle("p_{T} [GeV/c]"); - measuredTH1background->SetMarkerStyle(26); - measuredTH1background->SetMarkerColor(kBlack); - measuredTH1background->SetLineColor(kBlack); - measuredTH1background->Draw(); - } - - contaminationspectrum = (AliCFDataGrid *) ((AliCFDataGrid *)GetSpectrum(contaminationcontainer,1))->Clone(); - contaminationspectrum->SetName("contaminationspectrum"); - TCanvas * ccontaminationspectrum = new TCanvas("contaminationspectrum","contaminationspectrum",1000,700); - ccontaminationspectrum->Divide(3,1); - ccontaminationspectrum->cd(1); - TH2D * contaminationspectrum2dpteta = (TH2D*)contaminationspectrum->Project(1,0); - TH2D * contaminationspectrum2dptphi = (TH2D*)contaminationspectrum->Project(2,0); - TH2D * contaminationspectrum2detaphi = (TH2D*)contaminationspectrum->Project(1,2); - contaminationspectrum2dpteta->SetStats(0); - contaminationspectrum2dpteta->SetTitle(""); - contaminationspectrum2dpteta->GetXaxis()->SetTitle("#eta"); - contaminationspectrum2dpteta->GetYaxis()->SetTitle("p_{T} [GeV/c]"); - contaminationspectrum2dptphi->SetStats(0); - contaminationspectrum2dptphi->SetTitle(""); - contaminationspectrum2dptphi->GetXaxis()->SetTitle("#phi [rad]"); - contaminationspectrum2dptphi->GetYaxis()->SetTitle("p_{T} [GeV/c]"); - contaminationspectrum2detaphi->SetStats(0); - contaminationspectrum2detaphi->SetTitle(""); - contaminationspectrum2detaphi->GetXaxis()->SetTitle("#eta"); - contaminationspectrum2detaphi->GetYaxis()->SetTitle("#phi [rad]"); - contaminationspectrum2dptphi->Draw("colz"); - ccontaminationspectrum->cd(2); - contaminationspectrum2dpteta->Draw("colz"); - ccontaminationspectrum->cd(3); - contaminationspectrum2detaphi->Draw("colz"); - + cbackgroundsubtraction->cd(3); + TH1D *measuredTH1background = backgroundGrid->Project(0); + CorrectFromTheWidth(measuredTH1background); + measuredTH1background->SetStats(0); + measuredTH1background->SetTitle(""); + measuredTH1background->GetYaxis()->SetTitle("dN/dp_{T} [(GeV/c)^{-1}]"); + measuredTH1background->GetXaxis()->SetTitle("p_{T} [GeV/c]"); + measuredTH1background->SetMarkerStyle(26); + measuredTH1background->SetMarkerColor(kBlack); + measuredTH1background->SetLineColor(kBlack); + measuredTH1background->Draw(); + } - - TCanvas * cresidual = new TCanvas("residual","residual",1000,700); - cresidual->Divide(2,1); - cresidual->cd(1); - gPad->SetLogy(); - TGraphErrors* residualspectrumD = Normalize(residualspectrum); - if(!residualspectrumD) { - AliError("Number of Events not set for the normalization"); - return; - } - residualspectrumD->SetTitle(""); - residualspectrumD->GetYaxis()->SetTitleOffset(1.5); - residualspectrumD->GetYaxis()->SetRangeUser(0.000000001,1.0); - residualspectrumD->SetMarkerStyle(26); - residualspectrumD->SetMarkerColor(kBlue); - residualspectrumD->SetLineColor(kBlue); - residualspectrumD->Draw("AP"); - TGraphErrors* measuredspectrumD = Normalize(dataspectrum); - measuredspectrumD->SetTitle(""); - measuredspectrumD->GetYaxis()->SetTitleOffset(1.5); - measuredspectrumD->GetYaxis()->SetRangeUser(0.000000001,1.0); - measuredspectrumD->SetMarkerStyle(25); - measuredspectrumD->SetMarkerColor(kBlack); - measuredspectrumD->SetLineColor(kBlack); - measuredspectrumD->Draw("P"); - TLegend *legres = new TLegend(0.4,0.6,0.89,0.89); - legres->AddEntry(residualspectrumD,"Residual","p"); - legres->AddEntry(measuredspectrumD,"Measured","p"); - legres->Draw("same"); - cresidual->cd(2); - TH1D *residualTH1D = residualspectrum->Projection(0); - TH1D *measuredTH1D = (TH1D*)dataspectrum->Project(0); - TH1D* ratioresidual = (TH1D*)residualTH1D->Clone(); - ratioresidual->SetName("ratioresidual"); - ratioresidual->SetTitle(""); - ratioresidual->GetYaxis()->SetTitle("Folded/Measured"); - ratioresidual->GetXaxis()->SetTitle("p_{T} [GeV/c]"); - ratioresidual->Divide(residualTH1D,measuredTH1D,1,1); - ratioresidual->SetStats(0); - ratioresidual->Draw(); - - // - - TCanvas * ccorrected = new TCanvas("corrected","corrected",1000,700); - ccorrected->Divide(2,1); - ccorrected->cd(1); - gPad->SetLogy(); - TGraphErrors* correctedspectrumD = Normalize(correctedspectrum); - correctedspectrumD->SetTitle(""); - correctedspectrumD->GetYaxis()->SetTitleOffset(1.5); - correctedspectrumD->GetYaxis()->SetRangeUser(0.000000001,1.0); - correctedspectrumD->SetMarkerStyle(26); - correctedspectrumD->SetMarkerColor(kBlue); - correctedspectrumD->SetLineColor(kBlue); - correctedspectrumD->Draw("AP"); - TGraphErrors* alltogetherspectrumD = Normalize(alltogetherCorrection); - alltogetherspectrumD->SetTitle(""); - alltogetherspectrumD->GetYaxis()->SetTitleOffset(1.5); - alltogetherspectrumD->GetYaxis()->SetRangeUser(0.000000001,1.0); - alltogetherspectrumD->SetMarkerStyle(25); - alltogetherspectrumD->SetMarkerColor(kBlack); - alltogetherspectrumD->SetLineColor(kBlack); - alltogetherspectrumD->Draw("P"); - TLegend *legcorrected = new TLegend(0.4,0.6,0.89,0.89); - legcorrected->AddEntry(correctedspectrumD,"Corrected","p"); - legcorrected->AddEntry(alltogetherspectrumD,"Alltogether","p"); - legcorrected->Draw("same"); - ccorrected->cd(2); - TH1D *correctedTH1D = correctedspectrum->Projection(0); - TH1D *alltogetherTH1D = (TH1D*)alltogetherCorrection->Project(0); - TH1D* ratiocorrected = (TH1D*)correctedTH1D->Clone(); - ratiocorrected->SetName("ratiocorrected"); - ratiocorrected->SetTitle(""); - ratiocorrected->GetYaxis()->SetTitle("Unfolded/DirectCorrected"); - ratiocorrected->GetXaxis()->SetTitle("p_{T} [GeV/c]"); - ratiocorrected->Divide(correctedTH1D,alltogetherTH1D,1,1); - ratiocorrected->SetStats(0); - ratiocorrected->Draw(); - - // Efficiency correction - - AliCFEffGrid *efficiencymcPID = (AliCFEffGrid*) GetEfficiency(mccontainer,8,7); - AliCFEffGrid *efficiencymctrackinggeo = (AliCFEffGrid*) GetEfficiency(mccontainer,7,0); - AliCFEffGrid *efficiencymcall = (AliCFEffGrid*) GetEfficiency(mccontainer,8,0); - - AliCFEffGrid *efficiencyesdall = (AliCFEffGrid*) GetEfficiency(mccontainer,20,0); - - TCanvas * cefficiency = new TCanvas("efficiency","efficiency",1000,700); - cefficiency->cd(1); - TH1D* efficiencymcPIDD = (TH1D*)efficiencymcPID->Project(0); - efficiencymcPIDD->SetTitle(""); - efficiencymcPIDD->SetStats(0); - efficiencymcPIDD->SetMarkerStyle(25); - efficiencymcPIDD->Draw(); - TH1D* efficiencymctrackinggeoD = (TH1D*)efficiencymctrackinggeo->Project(0); - efficiencymctrackinggeoD->SetTitle(""); - efficiencymctrackinggeoD->SetStats(0); - efficiencymctrackinggeoD->SetMarkerStyle(26); - efficiencymctrackinggeoD->Draw("same"); - TH1D* efficiencymcallD = (TH1D*)efficiencymcall->Project(0); - efficiencymcallD->SetTitle(""); - efficiencymcallD->SetStats(0); - efficiencymcallD->SetMarkerStyle(27); - efficiencymcallD->Draw("same"); - TH1D* efficiencyesdallD = (TH1D*)efficiencyesdall->Project(0); - efficiencyesdallD->SetTitle(""); - efficiencyesdallD->SetStats(0); - efficiencyesdallD->SetMarkerStyle(24); - efficiencyesdallD->Draw("same"); - TLegend *legeff = new TLegend(0.4,0.6,0.89,0.89); - legeff->AddEntry(efficiencymcPIDD,"PID efficiency","p"); - legeff->AddEntry(efficiencymctrackinggeoD,"Tracking geometry efficiency","p"); - legeff->AddEntry(efficiencymcallD,"Overall efficiency","p"); - legeff->AddEntry(efficiencyesdallD,"Overall efficiency ESD","p"); - legeff->Draw("same"); - - // Dump to file if needed - - if(fDumpToFile) { - - TFile *out = new TFile("finalSpectrum.root","recreate"); - out->cd(); - // - residualspectrumD->SetName("UnfoldingResidualSpectrum"); - residualspectrumD->Write(); - measuredspectrumD->SetName("MeasuredSpectrum"); - measuredspectrumD->Write(); - ratioresidual->SetName("RatioResidualSpectrum"); - ratioresidual->Write(); - // - correctedspectrumD->SetName("UnfoldingCorrectedSpectrum"); - correctedspectrumD->Write(); - alltogetherspectrumD->SetName("AlltogetherSpectrum"); - alltogetherspectrumD->Write(); - ratiocorrected->SetName("RatioUnfoldingAlltogetherSpectrum"); - ratiocorrected->Write(); - // - correctedspectrum->SetName("UnfoldingCorrectedNotNormalizedSpectrum"); - correctedspectrum->Write(); - alltogetherCorrection->SetName("AlltogetherCorrectedNotNormalizedSpectrum"); - alltogetherCorrection->Write(); - // - if(measuredTH1Daftersubstraction && measuredTH1Dbeforesubstraction) { - measuredTH1Daftersubstraction->SetName("Rawptspectrummeasuredaftersubtraction"); - measuredTH1Daftersubstraction->Write(); - measuredTH1Dbeforesubstraction->SetName("Rawptspectrummeasuredbeforesubtraction"); - measuredTH1Dbeforesubstraction->Write(); - } - if(measuredTH1background) { - measuredTH1background->SetName("Rawptspectrummeasuredbackground"); - measuredTH1background->Write(); - } - // - out->Close(); delete out; - - - } + return spectrumSubtracted; } //____________________________________________________________ -AliCFDataGrid* AliHFEspectrum::SubtractBackground(Int_t dimensions, Bool_t setBackground){ +AliCFDataGrid *AliHFEspectrum::CorrectV0Efficiency(AliCFDataGrid* const bgsubpectrum){ + // - // Apply background subtraction + // Apply TPC pid efficiency correction from V0 // - AliCFContainer *dataContainer = GetContainer(kDataContainer); - if(!dataContainer){ - AliError("Data Container not available"); + AliCFContainer *v0Container = GetContainer(kDataContainerV0); + if(!v0Container){ + AliError("V0 Container not available"); return NULL; } - - // Get the data grid in the requested format - Bool_t initContainer = kFALSE; - Int_t dims[3]; - switch(dimensions){ - case 1: dims[0] = 0; - initContainer = kTRUE; - break; - case 3: for(Int_t i = 0; i < 3; i++) dims[i] = i; - initContainer = kTRUE; - break; - default: - AliError("Container with this number of dimensions not foreseen (yet)"); - }; - if(!initContainer){ - AliError("Creation of the sliced containers failed. Background estimation not possible"); - return NULL; - } - AliCFContainer *spectrumSliced = GetSlicedContainer(dataContainer, dimensions, dims); - - // Make Background Estimate - AliCFDataGrid *backgroundGrid = NULL; - if(fBackgroundSource == kDataBackground) - backgroundGrid = TakeBackgroundFromData(dimensions); - else - backgroundGrid = MakeBackgroundEstimateFromMC(dimensions); - if(!backgroundGrid){ - AliError("Background Estimate not created"); - ClearObject(spectrumSliced); - return NULL; + + // Efficiency + AliCFEffGrid* efficiencyD = new AliCFEffGrid("efficiency","",*v0Container); + efficiencyD->CalculateEfficiency(fStepAfterCutsV0,fStepBeforeCutsV0); + + // Data in the right format + AliCFDataGrid *dataGrid = 0x0; + if(bgsubpectrum) { + dataGrid = bgsubpectrum; } + else { + + AliCFContainer *dataContainer = GetContainer(kDataContainer); + if(!dataContainer){ + AliError("Data Container not available"); + return NULL; + } + dataGrid = new AliCFDataGrid("dataGrid","dataGrid",*dataContainer, fStepData); + } - AliCFDataGrid *spectrumSubtracted = new AliCFDataGrid("spectrumSubtracted", "Data Grid for spectrum after Background subtraction", *spectrumSliced,fStepData); - //spectrumSubtracted->ApplyBGCorrection(*backgroundGrid); - spectrumSubtracted->Add(backgroundGrid,-1.0); - if(setBackground){ - if(fBackground) delete fBackground; - fBackground = backgroundGrid; - } else delete backgroundGrid; + // Correct + AliCFDataGrid *result = (AliCFDataGrid *) dataGrid->Clone(); + result->ApplyEffCorrection(*efficiencyD); - return spectrumSubtracted; -} + if(fDebugLevel > 0) { + + TCanvas * cV0Efficiency = new TCanvas("V0Efficiency","V0Efficiency",1000,700); + cV0Efficiency->Divide(2,1); + cV0Efficiency->cd(1); + TH1D *afterE = result->Project(0); + TH1D *beforeE = dataGrid->Project(0); + afterE->SetStats(0); + afterE->SetTitle(""); + afterE->GetYaxis()->SetTitle("dN/dp_{T} [(GeV/c)^{-1}]"); + afterE->GetXaxis()->SetTitle("p_{T} [GeV/c]"); + afterE->SetMarkerStyle(25); + afterE->SetMarkerColor(kBlack); + afterE->SetLineColor(kBlack); + beforeE->SetStats(0); + beforeE->SetTitle(""); + beforeE->GetYaxis()->SetTitle("dN/dp_{T} [(GeV/c)^{-1}]"); + beforeE->GetXaxis()->SetTitle("p_{T} [GeV/c]"); + beforeE->SetMarkerStyle(24); + beforeE->SetMarkerColor(kBlue); + beforeE->SetLineColor(kBlue); + afterE->Draw(); + beforeE->Draw("same"); + TLegend *legV0efficiency = new TLegend(0.4,0.6,0.89,0.89); + legV0efficiency->AddEntry(beforeE,"Before Efficiency correction","p"); + legV0efficiency->AddEntry(afterE,"After Efficiency correction","p"); + legV0efficiency->Draw("same"); + cV0Efficiency->cd(2); + TH1D* efficiencyDproj = efficiencyD->Project(0); + efficiencyDproj->SetTitle(""); + efficiencyDproj->SetStats(0); + efficiencyDproj->SetMarkerStyle(25); + efficiencyDproj->Draw(); + + } + + + return result; + +} //____________________________________________________________ -TList *AliHFEspectrum::Unfold(Int_t dimensions,AliCFDataGrid* const bgsubpectrum){ +TList *AliHFEspectrum::Unfold(AliCFDataGrid* const bgsubpectrum){ // // Unfold and eventually correct for efficiency the bgsubspectrum // - AliCFContainer *mcContainer = GetContainer(kMCContainer); + AliCFContainer *mcContainer = GetContainer(kMCContainerMC); if(!mcContainer){ AliError("MC Container not available"); return NULL; @@ -475,35 +550,10 @@ TList *AliHFEspectrum::Unfold(Int_t dimensions,AliCFDataGrid* const bgsubpectrum return NULL; } - // Get the mc grid in the requested format - Bool_t initContainer = kFALSE; - Int_t dims[3]; - switch(dimensions){ - case 1: dims[0] = 0; - initContainer = kTRUE; - break; - case 3: for(Int_t i = 0; i < 3; i++) dims[i] = i; - initContainer = kTRUE; - break; - default: - AliError("Container with this number of dimensions not foreseen (yet)"); - }; - if(!initContainer){ - AliError("Creation of the sliced containers failed. Background estimation not possible"); - return NULL; - } - AliCFContainer *mcContainerD = GetSlicedContainer(mcContainer, dimensions, dims); - THnSparse *correlationD = GetSlicedCorrelation(dimensions, dims); - - // Data in the right format + // Data AliCFDataGrid *dataGrid = 0x0; if(bgsubpectrum) { - if(bgsubpectrum->GetNVar()!= dimensions) { - AliError("Not the expected number of dimensions for the AliCFDataGrid\n"); - return NULL; - } dataGrid = bgsubpectrum; - } else { @@ -513,23 +563,20 @@ TList *AliHFEspectrum::Unfold(Int_t dimensions,AliCFDataGrid* const bgsubpectrum return NULL; } - AliCFContainer *dataContainerD = GetSlicedContainer(dataContainer, dimensions, dims); - dataGrid = new AliCFDataGrid("dataGrid","dataGrid",*dataContainerD, fStepData); - + dataGrid = new AliCFDataGrid("dataGrid","dataGrid",*dataContainer, fStepData); } - // Guessed - AliCFDataGrid* guessedGrid = new AliCFDataGrid("guessed","",*mcContainerD, fStepGuessedUnfolding); + AliCFDataGrid* guessedGrid = new AliCFDataGrid("guessed","",*mcContainer, fStepGuessedUnfolding); THnSparse* guessedTHnSparse = ((AliCFGridSparse*)guessedGrid->GetData())->GetGrid(); // Efficiency - AliCFEffGrid* efficiencyD = new AliCFEffGrid("efficiency","",*mcContainerD); + AliCFEffGrid* efficiencyD = new AliCFEffGrid("efficiency","",*mcContainer); efficiencyD->CalculateEfficiency(fStepMC,fStepTrue); // Unfold - AliCFUnfolding unfolding("unfolding","",dimensions,correlationD,efficiencyD->GetGrid(),dataGrid->GetGrid(),guessedTHnSparse); + AliCFUnfolding unfolding("unfolding","",fNbDimensions,fCorrelation,efficiencyD->GetGrid(),dataGrid->GetGrid(),guessedTHnSparse); unfolding.SetMaxNumberOfIterations(fNumberOfIterations); unfolding.UseSmoothing(); unfolding.Unfold(); @@ -542,77 +589,135 @@ TList *AliHFEspectrum::Unfold(Int_t dimensions,AliCFDataGrid* const bgsubpectrum listofresults->AddAt((THnSparse*)result->Clone(),0); listofresults->AddAt((THnSparse*)residual->Clone(),1); + if(fDebugLevel > 0) { + + TCanvas * cresidual = new TCanvas("residual","residual",1000,700); + cresidual->Divide(2,1); + cresidual->cd(1); + gPad->SetLogy(); + TGraphErrors* residualspectrumD = Normalize(residual); + if(!residualspectrumD) { + AliError("Number of Events not set for the normalization"); + return kFALSE; + } + residualspectrumD->SetTitle(""); + residualspectrumD->GetYaxis()->SetTitleOffset(1.5); + residualspectrumD->GetYaxis()->SetRangeUser(0.000000001,1.0); + residualspectrumD->SetMarkerStyle(26); + residualspectrumD->SetMarkerColor(kBlue); + residualspectrumD->SetLineColor(kBlue); + residualspectrumD->Draw("AP"); + AliCFDataGrid *dataGridBis = (AliCFDataGrid *) (dataGrid->Clone()); + dataGridBis->SetName("dataGridBis"); + TGraphErrors* measuredspectrumD = Normalize(dataGridBis); + measuredspectrumD->SetTitle(""); + measuredspectrumD->GetYaxis()->SetTitleOffset(1.5); + measuredspectrumD->GetYaxis()->SetRangeUser(0.000000001,1.0); + measuredspectrumD->SetMarkerStyle(25); + measuredspectrumD->SetMarkerColor(kBlack); + measuredspectrumD->SetLineColor(kBlack); + measuredspectrumD->Draw("P"); + TLegend *legres = new TLegend(0.4,0.6,0.89,0.89); + legres->AddEntry(residualspectrumD,"Residual","p"); + legres->AddEntry(measuredspectrumD,"Measured","p"); + legres->Draw("same"); + cresidual->cd(2); + TH1D *residualTH1D = residual->Projection(0); + TH1D *measuredTH1D = dataGridBis->Project(0); + TH1D* ratioresidual = (TH1D*)residualTH1D->Clone(); + ratioresidual->SetName("ratioresidual"); + ratioresidual->SetTitle(""); + ratioresidual->GetYaxis()->SetTitle("Folded/Measured"); + ratioresidual->GetXaxis()->SetTitle("p_{T} [GeV/c]"); + ratioresidual->Divide(residualTH1D,measuredTH1D,1,1); + ratioresidual->SetStats(0); + ratioresidual->Draw(); + + } + return listofresults; } //____________________________________________________________ -AliCFDataGrid *AliHFEspectrum::CorrectForEfficiency(Int_t dimensions,AliCFDataGrid* const bgsubpectrum){ +AliCFDataGrid *AliHFEspectrum::CorrectForEfficiency(AliCFDataGrid* const bgsubpectrum){ // // Apply unfolding and efficiency correction together to bgsubspectrum // - AliCFContainer *mcContainer = GetContainer(kMCContainer); + AliCFContainer *mcContainer = GetContainer(kMCContainerESD); if(!mcContainer){ AliError("MC Container not available"); return NULL; } - // Get the data grid in the requested format - Bool_t initContainer = kFALSE; - Int_t dims[3]; - switch(dimensions){ - case 1: dims[0] = 0; - initContainer = kTRUE; - break; - case 3: for(Int_t i = 0; i < 3; i++) dims[i] = i; - initContainer = kTRUE; - break; - default: - AliError("Container with this number of dimensions not foreseen (yet)"); - }; - if(!initContainer){ - AliError("Creation of the sliced containers failed. Background estimation not possible"); - return NULL; - } - AliCFContainer *mcContainerD = GetSlicedContainer(mcContainer, dimensions, dims); - // Efficiency - AliCFEffGrid* efficiencyD = new AliCFEffGrid("efficiency","",*mcContainerD); + AliCFEffGrid* efficiencyD = new AliCFEffGrid("efficiency","",*mcContainer); efficiencyD->CalculateEfficiency(fStepMC,fStepTrue); // Data in the right format AliCFDataGrid *dataGrid = 0x0; if(bgsubpectrum) { - if(bgsubpectrum->GetNVar()!= dimensions) { - AliError("Not the expected number of dimensions for the AliCFDataGrid\n"); - return NULL; - } dataGrid = bgsubpectrum; - } else { - + AliCFContainer *dataContainer = GetContainer(kDataContainer); if(!dataContainer){ AliError("Data Container not available"); return NULL; } - AliCFContainer *dataContainerD = GetSlicedContainer(dataContainer, dimensions, dims); - dataGrid = new AliCFDataGrid("dataGrid","dataGrid",*dataContainerD, fStepData); - + dataGrid = new AliCFDataGrid("dataGrid","dataGrid",*dataContainer, fStepData); } // Correct AliCFDataGrid *result = (AliCFDataGrid *) dataGrid->Clone(); result->ApplyEffCorrection(*efficiencyD); - + if(fDebugLevel > 0) { + + AliCFEffGrid *efficiencymcPID = (AliCFEffGrid*) GetEfficiency(GetContainer(kMCContainerMC),fStepMC,AliHFEcuts::kStepHFEcutsTRD + AliHFEcuts::kNcutStepsMCTrack); + AliCFEffGrid *efficiencymctrackinggeo = (AliCFEffGrid*) GetEfficiency(GetContainer(kMCContainerMC),AliHFEcuts::kStepHFEcutsTRD + AliHFEcuts::kNcutStepsMCTrack,fStepTrue); + AliCFEffGrid *efficiencymcall = (AliCFEffGrid*) GetEfficiency(GetContainer(kMCContainerMC),fStepMC,fStepTrue); + + AliCFEffGrid *efficiencyesdall = (AliCFEffGrid*) GetEfficiency(GetContainer(kMCContainerESD),fStepMC,fStepTrue); + + TCanvas * cefficiency = new TCanvas("efficiency","efficiency",1000,700); + cefficiency->cd(1); + TH1D* efficiencymcPIDD = efficiencymcPID->Project(0); + efficiencymcPIDD->SetTitle(""); + efficiencymcPIDD->SetStats(0); + efficiencymcPIDD->SetMarkerStyle(25); + efficiencymcPIDD->Draw(); + TH1D* efficiencymctrackinggeoD = efficiencymctrackinggeo->Project(0); + efficiencymctrackinggeoD->SetTitle(""); + efficiencymctrackinggeoD->SetStats(0); + efficiencymctrackinggeoD->SetMarkerStyle(26); + efficiencymctrackinggeoD->Draw("same"); + TH1D* efficiencymcallD = efficiencymcall->Project(0); + efficiencymcallD->SetTitle(""); + efficiencymcallD->SetStats(0); + efficiencymcallD->SetMarkerStyle(27); + efficiencymcallD->Draw("same"); + TH1D* efficiencyesdallD = efficiencyesdall->Project(0); + efficiencyesdallD->SetTitle(""); + efficiencyesdallD->SetStats(0); + efficiencyesdallD->SetMarkerStyle(24); + efficiencyesdallD->Draw("same"); + TLegend *legeff = new TLegend(0.4,0.6,0.89,0.89); + legeff->AddEntry(efficiencymcPIDD,"PID efficiency","p"); + legeff->AddEntry(efficiencymctrackinggeoD,"Tracking geometry efficiency","p"); + legeff->AddEntry(efficiencymcallD,"Overall efficiency","p"); + legeff->AddEntry(efficiencyesdallD,"Overall efficiency ESD","p"); + legeff->Draw("same"); + } + return result; } + //__________________________________________________________________________________ TGraphErrors *AliHFEspectrum::Normalize(THnSparse * const spectrum) const { // @@ -641,7 +746,7 @@ TGraphErrors *AliHFEspectrum::Normalize(AliCFDataGrid * const spectrum) const { // if(fNEvents > 0) { - TH1D* projection = (TH1D*)spectrum->Project(0); + TH1D* projection = spectrum->Project(0); CorrectFromTheWidth(projection); TGraphErrors *graphError = NormalizeTH1(projection); return graphError; @@ -712,93 +817,10 @@ AliCFContainer *AliHFEspectrum::GetContainer(AliHFEspectrum::CFContainer_t type) if(!fCFContainers) return NULL; return dynamic_cast(fCFContainers->At(type)); } - //____________________________________________________________ -AliCFDataGrid *AliHFEspectrum::TakeBackgroundFromData(Int_t nDim) { - // - // Take Background Estimate from Data +AliCFContainer *AliHFEspectrum::GetSlicedContainer(AliCFContainer *container, Int_t nDim, Int_t *dimensions,Int_t source) { // - - AliCFContainer *backgroundContainer = GetContainer(kBackgroundData); - if(!backgroundContainer){ - AliError("MC background container not found"); - return NULL; - } - AliInfo(Form("Making background Estimate from Data in %d Dimensions", nDim)); - - Bool_t initContainer = kFALSE; - Int_t dimensions[3]; - switch(nDim){ - case 1: dimensions[0] = 0; - initContainer = kTRUE; - break; - case 3: for(Int_t i = 0; i < 3; i++) dimensions[i] = i; - initContainer = kTRUE; - break; - default: - AliError("Container with this number of dimensions not foreseen (yet)"); - }; - if(!initContainer){ - AliError("Creation of the sliced containers failed. Background estimation not possible"); - return NULL; - } - AliCFContainer *slicedBackground = GetSlicedContainer(backgroundContainer, nDim, dimensions); - AliCFDataGrid *contaminationspectrum = new AliCFDataGrid("ContaminationGrid","ContaminationGrid",*slicedBackground,1); - - return contaminationspectrum; -} - -//____________________________________________________________ -AliCFDataGrid *AliHFEspectrum::MakeBackgroundEstimateFromMC(Int_t nDim){ - // - // Make Background Estimate using MC - // Calculate ratio of hadronic background from MC and - // apply this on data - // - AliCFContainer *backgroundContainer = GetContainer(kBackgroundMC); - AliCFContainer *dataContainer = GetContainer(kDataContainer); - if(!backgroundContainer){ - AliError("MC background container not found"); - return NULL; - } - if(!dataContainer){ - AliError("Data container not found"); - return NULL; - } - AliInfo(Form("Making background Estimate from MC in %d Dimensions", nDim)); - - Bool_t initContainer = kFALSE; - Int_t dimensions[3]; - switch(nDim){ - case 1: dimensions[0] = 1; - initContainer = kTRUE; - break; - case 3: for(Int_t i = 0; i < 3; i++) dimensions[i] = i; - initContainer = kTRUE; - break; - default: - AliError("Container with this number of dimensions not foreseen (yet)"); - }; - if(!initContainer){ - AliError("Creation of the sliced containers failed. Background estimation not possible"); - return NULL; - } - AliCFContainer *slicedBackground = GetSlicedContainer(backgroundContainer, nDim, dimensions); - AliCFContainer *slicedData = GetSlicedContainer(dataContainer, nDim, dimensions); - - // Create Efficiency Grid and data grid - AliCFEffGrid backgroundRatio("backgroundRatio", "BackgroundRatio", *slicedBackground); - backgroundRatio.CalculateEfficiency(1, 0); - AliCFDataGrid *backgroundEstimate = new AliCFDataGrid("backgroundEstimate", "Grid for Background Estimate", *slicedData, fStepData); - backgroundEstimate->ApplyEffCorrection(backgroundRatio); - - return backgroundEstimate; -} - -//____________________________________________________________ -AliCFContainer *AliHFEspectrum::GetSlicedContainer(AliCFContainer *container, Int_t nDim, Int_t *dimensions) { - // - // Slice Pt bin + // Slice bin for a given source of electron // Double_t *varMin = new Double_t[container->GetNVar()], @@ -809,8 +831,15 @@ AliCFContainer *AliHFEspectrum::GetSlicedContainer(AliCFContainer *container, In binLimits = new Double_t[container->GetNBins(ivar)+1]; container->GetBinLimits(ivar,binLimits); - varMin[ivar] = binLimits[0]; - varMax[ivar] = binLimits[container->GetNBins(ivar)]; + if((ivar == 4) && ((source>= 0) && (sourceGetNBins(ivar)))) { + varMin[ivar] = binLimits[source]; + varMax[ivar] = binLimits[source]; + } + else { + varMin[ivar] = binLimits[0]; + varMax[ivar] = binLimits[container->GetNBins(ivar)]; + } + delete[] binLimits; } @@ -823,12 +852,12 @@ AliCFContainer *AliHFEspectrum::GetSlicedContainer(AliCFContainer *container, In } //_________________________________________________________________________ -THnSparse *AliHFEspectrum::GetSlicedCorrelation(Int_t nDim, Int_t *dimensions) const { +THnSparseF *AliHFEspectrum::GetSlicedCorrelation(THnSparseF *correlationmatrix, Int_t nDim, Int_t *dimensions) const { // - // Slice Pt correlation + // Slice correlation // - Int_t ndimensions = fCorrelation->GetNdimensions(); + Int_t ndimensions = correlationmatrix->GetNdimensions(); printf("Number of dimension %d correlation map\n",ndimensions); if(ndimensions < (2*nDim)) { AliError("Problem in the dimensions"); @@ -844,7 +873,7 @@ THnSparse *AliHFEspectrum::GetSlicedCorrelation(Int_t nDim, Int_t *dimensions) c printf("For iter %d: %d and iter+nDim %d: %d\n",iter,dimensions[iter],iter+nDim,ndimensionsContainer + dimensions[iter]); } - THnSparse *k = fCorrelation->Projection(nDim*2,dim); + THnSparseF *k = (THnSparseF *) correlationmatrix->Projection(nDim*2,dim); delete[] dim; return k; @@ -900,7 +929,7 @@ TObject* AliHFEspectrum::GetSpectrum(AliCFContainer * const c, Int_t step) { return data; } //_________________________________________________________________________ -TObject* AliHFEspectrum::GetEfficiency(AliCFContainer * const c, Int_t step, Int_t step0) { +TObject* AliHFEspectrum::GetEfficiency(AliCFContainer * const c, Int_t step, Int_t step0){ // // Create efficiency grid and calculate efficiency // of step to step0 diff --git a/PWG3/hfe/AliHFEspectrum.h b/PWG3/hfe/AliHFEspectrum.h index 31c09742012..c18d9b39c71 100644 --- a/PWG3/hfe/AliHFEspectrum.h +++ b/PWG3/hfe/AliHFEspectrum.h @@ -30,52 +30,59 @@ class TObject; class TH1; class TList; class AliCFContainer; +class AliHFEcontainer; class AliCFDataGrid; class AliCFEffGrid; class AliHFEspectrum : public TNamed{ public: enum CFContainer_t{ - kDataContainer = 0, - kMCContainer = 1, - kBackgroundData = 2, - kBackgroundMC = 3 - }; - enum BackgroundSource_t{ - kMCbackground = 0, - kDataBackground = 1 + kDataContainer = 0, + kBackgroundData = 1, + kMCContainerMC = 2, + kMCContainerESD = 3, + kDataContainerV0 = 4 }; + AliHFEspectrum(const char* name); ~AliHFEspectrum(); + - void Correct(AliCFContainer *datacontainer,AliCFContainer *mccontainer,THnSparseF *mccorrelation,AliCFContainer *contaminationcontainer=0x0); - AliCFDataGrid *SubtractBackground(Int_t dimensions, Bool_t setBackground = kFALSE); - AliCFDataGrid *TakeBackgroundFromData(Int_t nDim); - - TList *Unfold(Int_t dimensions, AliCFDataGrid* const bgsubpectrum = 0x0); - AliCFDataGrid *CorrectForEfficiency(Int_t dimensions, AliCFDataGrid* const bgsubpectrum = 0x0); - + Bool_t Init(AliHFEcontainer *datahfecontainer,AliHFEcontainer *mchfecontainer,AliHFEcontainer *v0hfecontainer=0x0); + Bool_t Correct(Bool_t subtractcontamination=kTRUE); + + AliCFDataGrid *SubtractBackground(Bool_t setBackground = kFALSE); + + AliCFDataGrid *CorrectV0Efficiency(AliCFDataGrid* const bgsubpectrum = 0x0); + + TList *Unfold(AliCFDataGrid* const bgsubpectrum = 0x0); + AliCFDataGrid *CorrectForEfficiency(AliCFDataGrid* const bgsubpectrum = 0x0); + TGraphErrors *Normalize(THnSparse * const spectrum) const; TGraphErrors *Normalize(AliCFDataGrid * const spectrum) const; - + void SetCorrelation(THnSparseF * const correlation) {fCorrelation = correlation; }; void SetContainer(AliCFContainer *cont, AliHFEspectrum::CFContainer_t type); + void SetNumberOfEvents(Int_t nEvents) { fNEvents = nEvents; } - void SetBackgroundSource(BackgroundSource_t source) { fBackgroundSource = source; }; void SetMCEffStep(Int_t step) { fStepMC = step; }; void SetMCTruthStep(Int_t step) { fStepTrue = step; }; void SetStepToCorrect(Int_t step) { fStepData = step; }; + void SetStepBeforeCutsV0(Int_t step) { fStepBeforeCutsV0 = step; }; + void SetStepAfterCutsV0(Int_t step) { fStepAfterCutsV0 = step; }; + void SetStepGuessedUnfolding(Int_t stepGuessedUnfolding) { fStepGuessedUnfolding = stepGuessedUnfolding; }; void SetNumberOfIteration(Int_t numberOfIteration) { fNumberOfIterations = numberOfIteration; }; + void SetDumpToFile(Bool_t dumpToFile) { fDumpToFile=dumpToFile; }; + void SetDebugLevel(Int_t debugLevel) { fDebugLevel = debugLevel; }; protected: - AliCFDataGrid *MakeBackgroundEstimateFromMC(Int_t nDimensions); - + AliCFContainer *GetContainer(AliHFEspectrum::CFContainer_t contt); - AliCFContainer *GetSlicedContainer(AliCFContainer *cont, Int_t ndim, Int_t *dimensions); - THnSparse *GetSlicedCorrelation(Int_t nDim, Int_t *dimensions) const; + AliCFContainer *GetSlicedContainer(AliCFContainer *cont, Int_t ndim, Int_t *dimensions,Int_t source=-1); + THnSparseF *GetSlicedCorrelation(THnSparseF *correlationmatrix,Int_t nDim, Int_t *dimensions) const; TObject* GetSpectrum(AliCFContainer * const c, Int_t step); TObject* GetEfficiency(AliCFContainer * const c, Int_t step, Int_t step0); @@ -95,17 +102,20 @@ class AliHFEspectrum : public TNamed{ THnSparseF *fCorrelation; // Correlation Matrices AliCFDataGrid *fBackground; // Background Grid - BackgroundSource_t fBackgroundSource; // Source for the background estimate - + Bool_t fInclusiveSpectrum; // Inclusive Spectrum Bool_t fDumpToFile; // Write Result in a file + Int_t fNbDimensions; // Number of dimensions for the correction Int_t fNEvents; // Number of Events Int_t fStepMC; // MC step (for unfolding) Int_t fStepTrue; // MC step of the final spectrum Int_t fStepData; // Data Step (various applications) + Int_t fStepBeforeCutsV0; // Before cuts V0 + Int_t fStepAfterCutsV0; // After cuts V0 Int_t fStepGuessedUnfolding; // Step for first guessed unfolding Int_t fNumberOfIterations; // Number of iterations + Int_t fDebugLevel; // Debug Level ClassDef(AliHFEspectrum, 1) }; diff --git a/PWG3/hfe/AliHFEtaggedTrackAnalysis.cxx b/PWG3/hfe/AliHFEtaggedTrackAnalysis.cxx new file mode 100644 index 00000000000..86725e28290 --- /dev/null +++ b/PWG3/hfe/AliHFEtaggedTrackAnalysis.cxx @@ -0,0 +1,235 @@ +/************************************************************************** +* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * +* * +* Author: The ALICE Off-line Project. * +* Contributors are mentioned in the code where appropriate. * +* * +* Permission to use, copy, modify and distribute this software and its * +* documentation strictly for non-commercial purposes is hereby granted * +* without fee, provided that the above copyright notice appears in all * +* copies and that both the copyright notice and this permission notice * +* appear in the supporting documentation. The authors make no claims * +* about the suitability of this software for any purpose. It is * +* provided "as is" without express or implied warranty. * +**************************************************************************/ +// +// Class AliHFEtaggedTrackAnalysis +// Analyses tracks with an apriori PID information (i.e. using the daugther +// tracks from well-identified decays of neutral charged particles). Tracks +// are processed in the Process function, where given tracks are filtered +// via the track cuts and used for PID later. The plugin fills Correction +// Framework containers and additional PID QA containers +// +// Author: +// Markus Fasel +// +#include "AliCFCutBase.h" +#include "AliCFContainer.h" +#include "AliCFManager.h" +#include "AliLog.h" +#include "AliPID.h" + +#include "AliHFEcontainer.h" +#include "AliHFEcuts.h" +#include "AliHFEpid.h" +#include "AliHFEpidQAmanager.h" +#include "AliHFEtaggedTrackAnalysis.h" +#include "AliHFEvarManager.h" + +ClassImp(AliHFEtaggedTrackAnalysis) + +//____________________________________________________________ +AliHFEtaggedTrackAnalysis::AliHFEtaggedTrackAnalysis(): + TObject() + , fVarManager(NULL) + , fContainer(NULL) + , fPID(NULL) + , fPIDqa(NULL) + , fCuts(NULL) + , fCFM(NULL) +{ + // + // Default constructor + // + fVarManager = new AliHFEvarManager("taggedTrackVarManager"); + fVarManager->AddVariable("pt"); + fVarManager->AddVariable("eta"); + fVarManager->AddVariable("phi"); + fVarManager->AddVariable("charge"); + fVarManager->AddVariable("species"); + fPIDqa = new AliHFEpidQAmanager; + fCFM = new AliCFManager; + SetBit(kIsOwner, kTRUE); +} + +//____________________________________________________________ +AliHFEtaggedTrackAnalysis::AliHFEtaggedTrackAnalysis(const AliHFEtaggedTrackAnalysis &ref): + TObject(ref) + , fVarManager(ref.fVarManager) + , fContainer(NULL) + , fPID(ref.fPID) + , fPIDqa(ref.fPIDqa) + , fCuts(ref.fCuts) + , fCFM(ref.fCFM) +{ + // + // Copy constructor + // + if(ref.fContainer){ + InitContainer(); + } + SetBit(kIsOwner, kFALSE); +} + +//____________________________________________________________ +AliHFEtaggedTrackAnalysis &AliHFEtaggedTrackAnalysis::operator=(const AliHFEtaggedTrackAnalysis &ref){ + // + // Assignment operator + // + if(&ref != this){ + fVarManager = ref.fVarManager; + fPID = ref.fPID; + fPIDqa = ref.fPIDqa; + fCuts = ref.fCuts; + fCFM = ref.fCFM; + + if(ref.fContainer) InitContainer(); + + SetBit(kIsOwner, kFALSE); + SetBit(kIsOwnerCuts, kFALSE); + } + return *this; +} + +//____________________________________________________________ +AliHFEtaggedTrackAnalysis::~AliHFEtaggedTrackAnalysis(){ + // + // Destructor + // + if(TestBit(kIsOwner)){ + if(fVarManager) delete fVarManager; + if(fPIDqa) delete fPIDqa; + } + if(TestBit(kIsOwnerCuts)) delete fCuts; + if(fContainer) delete fContainer; +} + +//____________________________________________________________ +void AliHFEtaggedTrackAnalysis::InitContainer(){ + // + // Initialize output container + // + if(fContainer) return; + Int_t nStepPID = 0; + if(!fPID){ + AliError("No PID set - defining container without PID steps"); + } else { + nStepPID = fPID->GetNumberOfPIDdetectors(); + } + fContainer = new AliHFEcontainer("containerV0"); + fVarManager->DefineVariables(fContainer); + fContainer->CreateContainer("taggedTrackContainerReco", "Container for Tagged Tracks", AliHFEcuts::kNcutStepsRecTrack + nStepPID); + + // Set the step titles + for(Int_t istep = 0; istep < AliHFEcuts::kNcutStepsRecTrack; istep++) + fContainer->SetStepTitle("taggedTrackContainerReco", AliHFEcuts::RecoCutName(istep), istep); + for(Int_t ipid = 0; ipid < nStepPID; ipid++){ + fContainer->SetStepTitle("taggedTrackContainerReco", fPID->SortedDetectorName(ipid), ipid + AliHFEcuts::kNcutStepsRecTrack); + } + fCFM->SetParticleContainer(fContainer->GetCFContainer("taggedTrackContainerReco")); +} + +//____________________________________________________________ +void AliHFEtaggedTrackAnalysis::ProcessTrack(AliVParticle *track, Int_t abinitioPID){ + // + // Filter tracks tagged by V0 PID class + // + fVarManager->NewTrack(track, NULL, 0., abinitioPID, kTRUE); + Int_t offset = AliHFEcuts::kStepRecKineITSTPC; + fVarManager->FillContainer(fCFM->GetParticleContainer(), 0); // Fill Container without filtering + + Bool_t survived = kTRUE; + for(Int_t icut = AliHFEcuts::kStepRecKineITSTPC; icut <= AliHFEcuts::kStepHFEcutsTRD; icut++){ + AliDebug(2, Form("Checking cut %d for species %s", icut + AliHFEcuts::kNcutStepsMCTrack, AliPID::ParticleName(abinitioPID))); + /* + TObjArray *cutlist = fCFM->GetParticleCutsList(icut + AliHFEcuts::kNcutStepsMCTrack); + if(!cutlist){ + AliDebug(2, Form("No cuts for step %d set", icut + AliHFEcuts::kNcutStepsMCTrack)); + } else { + AliDebug(2, Form("Cut Collection %s", cutlist->GetName())); + TIter cutiter(cutlist); + AliCFCutBase *cut; + while((cut = dynamic_cast(cutiter()))){ + AliDebug(2, Form("Cut object %s, QA on? %s", cut->GetName(), cut->IsQAOn() ? "yes" : "no")); + } + } + */ + //if(!fCFM->CheckParticleCuts(icut + AliHFEcuts::kNcutStepsMCTrack, (TObject *)track)){ + if(!fCuts->CheckParticleCuts(icut + AliHFEcuts::kNcutStepsMCTrack, (TObject *)track)){ + AliDebug(2, Form("Track didn' survive cut %d", icut + AliHFEcuts::kNcutStepsMCTrack)); + survived = kFALSE; + break; + } + AliDebug(2, Form("Cut passed, filling container %d", icut - offset + 1)); + fVarManager->FillContainer(fCFM->GetParticleContainer(), icut - offset + 1); + } + if(survived){ + AliDebug(2, "Use track in the PID"); + // Apply PID + AliHFEpidObject hfetrack; + hfetrack.SetAnalysisType(AliHFEpidObject::kESDanalysis); + hfetrack.SetRecTrack(track); + hfetrack.SetAbInitioPID(abinitioPID); + fPID->SetVarManager(fVarManager); + fPID->IsSelected(&hfetrack, fContainer, "taggedTrackContainer", fPIDqa); + } +} + +//____________________________________________________________ +void AliHFEtaggedTrackAnalysis::SetCuts(AliHFEcuts *cuts){ + // + // Set HFE cuts to be used to filter the tagged tracks + // + if(!cuts){ + AliWarning("Nob cuts provided - Using standard cuts"); + fCuts = new AliHFEcuts("cutsTagged", "HFE Cuts for the V0 tagged tracks"); + fCuts->CreateStandardCuts(); + fCuts->SetQAOn(); + SetBit(kIsOwnerCuts); + } + AliDebug(1, "Setting single track cuts"); + fCuts = cuts; + const Int_t kNcutSteps = AliHFEcuts::kNcutStepsMCTrack + AliHFEcuts::kNcutStepsRecTrack + AliHFEcuts::kNcutStepsDETrack; + printf("Setting Number of cut steps %d\n", kNcutSteps); + fCFM->SetNStepParticle(kNcutSteps); + for(Int_t istep = 0; istep < kNcutSteps; istep++) + fCFM->SetParticleCutsList(istep, NULL); + + fCuts->Initialize(fCFM); +} + +//____________________________________________________________ +void AliHFEtaggedTrackAnalysis::SetPID(AliHFEpid *pid){ + // + // Set the PID and initialize the the QA manager + // + fPID = pid; + fPIDqa->Initialize(fPID); +} + +//____________________________________________________________ +TList *AliHFEtaggedTrackAnalysis::GetPIDQA() const { + // + // return PID QA + // + return fPIDqa->MakeList("PIDqa_taggedTracks"); +} + +//____________________________________________________________ +TList *AliHFEtaggedTrackAnalysis::GetCutQA() const { + // + // return Cut QA + // + return fCuts->GetQAhistograms(); +} + diff --git a/PWG3/hfe/AliHFEtaggedTrackAnalysis.h b/PWG3/hfe/AliHFEtaggedTrackAnalysis.h new file mode 100644 index 00000000000..32eff8fd4f9 --- /dev/null +++ b/PWG3/hfe/AliHFEtaggedTrackAnalysis.h @@ -0,0 +1,65 @@ +/************************************************************************** +* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * +* * +* Author: The ALICE Off-line Project. * +* Contributors are mentioned in the code where appropriate. * +* * +* Permission to use, copy, modify and distribute this software and its * +* documentation strictly for non-commercial purposes is hereby granted * +* without fee, provided that the above copyright notice appears in all * +* copies and that both the copyright notice and this permission notice * +* appear in the supporting documentation. The authors make no claims * +* about the suitability of this software for any purpose. It is * +* provided "as is" without express or implied warranty. * +**************************************************************************/ +// +// Class AliHFEtaggedTrackAnalysis +// Analyses tracks with an apriori PID information (i.e. using the daugther +// tracks from well-identified decays of neutral charged particles). +// More information can be found inside the implementation file. +// +#ifndef ALIHFETAGGEDTRACKANALYSIS_H +#define ALIHFETAGGEDTRACKANALYSIS_H + +#ifndef ROOT_TObject +#include +#endif + +class AliHFEcontainer; +class AliHFEcuts; +class AliHFEpid; +class AliHFEpidQAmanager; +class AliHFEvarManager; + +class AliHFEtaggedTrackAnalysis : public TObject{ + public: + AliHFEtaggedTrackAnalysis(); + AliHFEtaggedTrackAnalysis(const AliHFEtaggedTrackAnalysis &ref); + AliHFEtaggedTrackAnalysis &operator=(const AliHFEtaggedTrackAnalysis &ref); + ~AliHFEtaggedTrackAnalysis(); + + void InitContainer(); + void ProcessTrack(AliVParticle *track, Int_t abinitioPID); + + AliHFEcontainer *GetContainer() const { return fContainer; } + AliHFEpidQAmanager *GetPIDqa() const { return fPIDqa; } + TList * GetPIDQA() const; + TList * GetCutQA() const; + void SetCuts(AliHFEcuts *cuts); + void SetPID(AliHFEpid *pid); + + private: + enum{ + kIsOwner = BIT(14), + kIsOwnerCuts = BIT(15) + }; + AliHFEvarManager *fVarManager; // Variable Manager + AliHFEcontainer *fContainer; // Output container + AliHFEpid *fPID; // PID selection + AliHFEpidQAmanager *fPIDqa; // PID monitoring + AliHFEcuts *fCuts; // Single track cuts + AliCFManager *fCFM; // CF Manager used for the track filtering + + ClassDef(AliHFEtaggedTrackAnalysis, 0) +}; +#endif diff --git a/PWG3/hfe/AliHFEtofPIDqa.cxx b/PWG3/hfe/AliHFEtofPIDqa.cxx new file mode 100644 index 00000000000..5c46166e872 --- /dev/null +++ b/PWG3/hfe/AliHFEtofPIDqa.cxx @@ -0,0 +1,251 @@ +/************************************************************************** +* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * +* * +* Author: The ALICE Off-line Project. * +* Contributors are mentioned in the code where appropriate. * +* * +* Permission to use, copy, modify and distribute this software and its * +* documentation strictly for non-commercial purposes is hereby granted * +* without fee, provided that the above copyright notice appears in all * +* copies and that both the copyright notice and this permission notice * +* appear in the supporting documentation. The authors make no claims * +* about the suitability of this software for any purpose. It is * +* provided "as is" without express or implied warranty. * +**************************************************************************/ +// +// Class AliHFEtofPIDqa +// +// Monitoring TOF PID in the HFE PID montioring framework. The following +// quantities are monitored: +// TOF time distance to electron hypothesis (Number of sigmas) +// TOF time distance to the pion hypothesis (Absolute value) +// TPC dE/dx (Number of sigmas, as control histogram) +// (Always as function of momentum, particle species and centrality +// before and after cut) +// More information about the PID monitoring framework can be found in +// AliHFEpidQAmanager.cxx and AliHFEdetPIDqa.cxx +// +// Author: +// +// Markus Fasel +#include +#include +#include +#include + +#include "AliAODTrack.h" +#include "AliESDtrack.h" +#include "AliESDpid.h" +#include "AliLog.h" +#include "AliPID.h" +#include "AliTOFPIDResponse.h" + +#include "AliHFEcollection.h" +#include "AliHFEpidBase.h" +#include "AliHFEtools.h" +#include "AliHFEtofPIDqa.h" + +//_________________________________________________________ +AliHFEtofPIDqa::AliHFEtofPIDqa(): + AliHFEdetPIDqa() + , fHistos(NULL) +{ + // + // Dummy constructor + // +} + +//_________________________________________________________ +AliHFEtofPIDqa::AliHFEtofPIDqa(const char* name): + AliHFEdetPIDqa(name, "QA for TPC") + , fHistos(NULL) +{ + // + // Default constructor + // +} + +//_________________________________________________________ +AliHFEtofPIDqa::AliHFEtofPIDqa(const AliHFEtofPIDqa &o): + AliHFEdetPIDqa(o) + , fHistos() +{ + // + // Copy constructor + // + o.Copy(*this); +} + +//_________________________________________________________ +AliHFEtofPIDqa &AliHFEtofPIDqa::operator=(const AliHFEtofPIDqa &o){ + // + // Do assignment + // + AliHFEdetPIDqa::operator=(o); + if(&o != this) o.Copy(*this); + return *this; +} + +//_________________________________________________________ +AliHFEtofPIDqa::~AliHFEtofPIDqa(){ + // + // Destructor + // + if(fHistos) delete fHistos; +} + +//_________________________________________________________ +void AliHFEtofPIDqa::Copy(TObject &o) const { + // + // Make copy + // + AliHFEtofPIDqa &target = dynamic_cast(o); + if(target.fHistos){ + delete target.fHistos; + target.fHistos = NULL; + } + if(fHistos) target.fHistos = new AliHFEcollection(*fHistos); +} + +//_________________________________________________________ +Long64_t AliHFEtofPIDqa::Merge(TCollection *coll){ + // + // Merge with other objects + // + if(!coll) return 0; + if(coll->IsEmpty()) return 1; + + TIter it(coll); + AliHFEtofPIDqa *refQA = NULL; + TObject *o = NULL; + Long64_t count = 0; + TList listHistos; + while((o = it())){ + refQA = dynamic_cast(o); + if(!refQA) continue; + + listHistos.Add(refQA->fHistos); + count++; + } + fHistos->Merge(&listHistos); + return count + 1; +} + +//_________________________________________________________ +void AliHFEtofPIDqa::Initialize(){ + // + // Define Histograms + // + + fHistos = new AliHFEcollection("tofqahistos", "Collection of TOF QA histograms"); + + // Make common binning + const Int_t kPIDbins = AliPID::kSPECIES + 1; + const Int_t kPbins = 1000; + const Int_t kSteps = 2; + const Double_t kMinPID = -1; + const Double_t kMinP = 0.; + const Double_t kMaxPID = (Double_t)AliPID::kSPECIES; + const Double_t kMaxP = 20.; + + // 1st histogram: TOF sigmas: (species, p nsigma, step) + const Int_t kSigmaBins = 1400; + Int_t nBinsSigma[4] = {kPIDbins, kPbins, kSigmaBins, kSteps}; + Double_t minSigma[4] = {kMinPID, kMinP, -12., 0}; + Double_t maxSigma[4] = {kMaxPID, kMaxP, 12., 2.}; + fHistos->CreateTHnSparse("tofnSigma", "TOF signal; species; p [GeV/c]; TOF signal [a.u.]; Selection Step", 4, nBinsSigma, minSigma, maxSigma); + + // 2nd histogram: TOF time - pion hypothesis (TOF Time Resolution Monitor) + fHistos->CreateTH2F("tofTimeRes", "Difference between measured and expected time for Pions; p [GeV/c]; #Deltat [ps]", 100, 0.1, 10, 100, -200, 200); + + // 3rd histogram: TPC sigmas to the electron line: (species, p nsigma, step - only filled if apriori PID information available) + fHistos->CreateTHnSparse("tofMonitorTPC", "TPC signal; species; p [GeV/c]; TPC signal [a.u.]; Selection Step", 4, nBinsSigma, minSigma, maxSigma); +} + +//_________________________________________________________ +void AliHFEtofPIDqa::ProcessTrack(AliHFEpidObject *track, AliHFEdetPIDqa::EStep_t step){ + // + // Fill TPC histograms + // + const AliVParticle *rectrack = track->GetRecTrack(); + Int_t species = track->GetAbInitioPID(); + if(species >= AliPID::kSPECIES) species = -1; + if(!TString(rectrack->IsA()->GetName()).CompareTo("AliESDtrack")) ProcessESDtrack(dynamic_cast(rectrack), step, species); + else if(!TString(rectrack->IsA()->GetName()).CompareTo("AliAODTrack")) ProcessAODtrack(dynamic_cast(rectrack), step, species); + else AliWarning(Form("Object type %s not supported\n", rectrack->IsA()->GetName())); +} + +//_________________________________________________________ +void AliHFEtofPIDqa::ProcessESDtrack(const AliESDtrack *track, AliHFEdetPIDqa::EStep_t step, Int_t species){ + // + // Process track as ESD track + // + if(!fESDpid){ + AliError("No ESD PID object available"); + return; + } + AliDebug(1, Form("Monitoring particle of type %d for step %d", species, step)); + + Double_t contentSignal[4]; + contentSignal[0] = species; + contentSignal[1] = track->GetInnerParam() ? track->GetInnerParam()->P() : track->P(); + contentSignal[2] = fESDpid->NumberOfSigmasTOF(track, AliPID::kElectron, fESDpid->GetTOFResponse().GetTimeZero()); + contentSignal[3] = step; + (dynamic_cast(fHistos->Get("tofnSigma")))->Fill(contentSignal); + Double_t tof = track->GetTOFsignal() - fESDpid->GetTOFResponse().GetTimeZero(); + Double_t times[AliPID::kSPECIES]; track->GetIntegratedTimes(times); + fHistos->Fill("tofTimeRes",contentSignal[1], tof - times[AliPID::kPion]); + if(species > -1){ + contentSignal[2] = fESDpid->NumberOfSigmasTPC(track, AliPID::kElectron); + fHistos->Fill("tofMonitorTPC", contentSignal); + } +} + +//_________________________________________________________ +void AliHFEtofPIDqa::ProcessAODtrack(const AliAODTrack * /*track*/, AliHFEdetPIDqa::EStep_t /*step*/, Int_t /*species*/){ + // + // Process track as AOD track + // + AliInfo("Method implemented soon!"); +} + +//_________________________________________________________ +TH2 *AliHFEtofPIDqa::MakeSpectrumNSigma(AliHFEdetPIDqa::EStep_t istep, Int_t species){ + // + // Plot the Spectrum + // + THnSparseF *hSignal = dynamic_cast(fHistos->Get("tofnSigma")); + hSignal->GetAxis(3)->SetRange(istep + 1, istep + 1); + if(species > 0 && species < AliPID::kSPECIES) + hSignal->GetAxis(0)->SetRange(2 + species, 2 + species); + TH2 *hTmp = hSignal->Projection(2,1); + Char_t hname[256], htitle[256]; + sprintf(hname, "hTPCsigma%s", istep == AliHFEdetPIDqa::kBeforePID ? "before" : "after"); + sprintf(htitle, "TPC dE/dx Spectrum[#sigma] %s selection", istep == AliHFEdetPIDqa::kBeforePID ? "before" : "after"); + if(species > -1){ + strncat(hname, AliPID::ParticleName(species), strlen(AliPID::ParticleName(species))); + Char_t speciesname[256]; + sprintf(speciesname, " for %ss", AliPID::ParticleName(species)); + strncat(htitle, speciesname, strlen(speciesname)); + } + hTmp->SetName(hname); + hTmp->SetTitle(htitle); + hTmp->SetStats(kFALSE); + hTmp->GetXaxis()->SetTitle("p [GeV/c]"); + hTmp->GetYaxis()->SetTitle("TOF time|_{el} - expected time|_{el} [#sigma]"); + hSignal->GetAxis(3)->SetRange(0, hSignal->GetAxis(3)->GetNbins()); + hSignal->GetAxis(0)->SetRange(0, hSignal->GetAxis(0)->GetNbins()); + return hTmp; +} + +//_________________________________________________________ +TH1 *AliHFEtofPIDqa::GetHistogram(const char *name){ + // + // Get the histogram + // + if(!fHistos) return NULL; + TObject *histo = fHistos->Get(name); + if(!histo->InheritsFrom("TH1")) return NULL; + return dynamic_cast(histo); +} + diff --git a/PWG3/hfe/AliHFEtofPIDqa.h b/PWG3/hfe/AliHFEtofPIDqa.h new file mode 100644 index 00000000000..8c11187807e --- /dev/null +++ b/PWG3/hfe/AliHFEtofPIDqa.h @@ -0,0 +1,59 @@ +/************************************************************************** +* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * +* * +* Author: The ALICE Off-line Project. * +* Contributors are mentioned in the code where appropriate. * +* * +* Permission to use, copy, modify and distribute this software and its * +* documentation strictly for non-commercial purposes is hereby granted * +* without fee, provided that the above copyright notice appears in all * +* copies and that both the copyright notice and this permission notice * +* appear in the supporting documentation. The authors make no claims * +* about the suitability of this software for any purpose. It is * +* provided "as is" without express or implied warranty. * +**************************************************************************/ +// +// Class AliHFEtofPIDqa +// Monitoring TPC PID in the HFE PID montioring framework +// More information can be found inside the implementation file +// +#ifndef ALIHFETOFPIDQA_H +#define ALIHFETOFPIDQA_H + +#ifndef ALIHFEDETPIDQA_H +#include "AliHFEdetPIDqa.h" +#endif + +class TH1; +class TH2; +class AliHFEcollection; +class AliHFEpidObject; +class AliESDtrack; +class AliAODTrack; + +class AliHFEtofPIDqa : public AliHFEdetPIDqa{ + public: + AliHFEtofPIDqa(); + AliHFEtofPIDqa(const char*name); + AliHFEtofPIDqa(const AliHFEtofPIDqa &o); + AliHFEtofPIDqa &operator=(const AliHFEtofPIDqa &o); + ~AliHFEtofPIDqa(); + void Copy(TObject &o) const; + virtual Long64_t Merge(TCollection *col); + + virtual void Initialize(); + virtual void ProcessTrack(AliHFEpidObject *track, AliHFEdetPIDqa::EStep_t step); + + TH2 *MakeSpectrumNSigma(AliHFEdetPIDqa::EStep_t step, Int_t species = -1); + TH1 *GetHistogram(const char *name); + AliHFEcollection *GetHistoCollection() const { return fHistos; } + + protected: + void ProcessESDtrack(const AliESDtrack *track, AliHFEdetPIDqa::EStep_t step, Int_t species); + void ProcessAODtrack(const AliAODTrack *track, AliHFEdetPIDqa::EStep_t step, Int_t species); + private: + AliHFEcollection *fHistos; // Container for Histograms + + ClassDef(AliHFEtofPIDqa, 1); +}; +#endif diff --git a/PWG3/hfe/AliHFEtools.cxx b/PWG3/hfe/AliHFEtools.cxx index 01afd2cd1df..13596180f22 100644 --- a/PWG3/hfe/AliHFEtools.cxx +++ b/PWG3/hfe/AliHFEtools.cxx @@ -28,8 +28,10 @@ #include "TAxis.h" #include "AliAODMCParticle.h" +#include "AliAODpidUtil.h" #include "AliESDpid.h" #include "AliLog.h" +#include "AliTPCPIDResponse.h" #include "AliTOFPIDResponse.h" #include "AliHFEtools.h" @@ -37,6 +39,7 @@ ClassImp(AliHFEtools) AliESDpid *AliHFEtools::fgDefaultPID = NULL; +AliAODpidUtil *AliHFEtools::fgDefaultPIDaod = NULL; Int_t AliHFEtools::fgLogLevel = 0; //__________________________________________ @@ -133,7 +136,7 @@ Bool_t AliHFEtools::BinLogAxis(TObject *o, Int_t dim){ } //__________________________________________ -Float_t AliHFEtools::GetRapidity(TParticle *part){ +Float_t AliHFEtools::GetRapidity(const TParticle *part){ // // return rapidity // @@ -144,7 +147,7 @@ Float_t AliHFEtools::GetRapidity(TParticle *part){ } //__________________________________________ -Float_t AliHFEtools::GetRapidity(AliAODMCParticle *part){ +Float_t AliHFEtools::GetRapidity(const AliAODMCParticle *part){ // return rapidity Float_t rapidity; @@ -193,6 +196,45 @@ AliESDpid* AliHFEtools::GetDefaultPID(Bool_t isMC){ return fgDefaultPID; } +//__________________________________________ +AliAODpidUtil* AliHFEtools::GetDefaultAODPID(Bool_t isMC){ + // + // Get the default PID as singleton instance + // + if(!fgDefaultPID){ + fgDefaultPIDaod = new AliAODpidUtil; + Double_t tres = isMC ? 80. : 130.; + fgDefaultPIDaod->GetTOFResponse().SetTimeResolution(tres); + + // TPC Bethe Bloch parameters + Double_t alephParameters[5]; + if(isMC){ + // simulation + alephParameters[0] = 2.15898e+00/50.; + alephParameters[1] = 1.75295e+01; + alephParameters[2] = 3.40030e-09; + alephParameters[3] = 1.96178e+00; + alephParameters[4] = 3.91720e+00; + } else { + alephParameters[0] = 0.0283086/0.97; + //alephParameters[0] = 0.0283086; + alephParameters[1] = 2.63394e+01; + alephParameters[2] = 5.04114e-11; + alephParameters[3] = 2.12543e+00; + alephParameters[4] = 4.88663e+00; + } + fgDefaultPIDaod->GetTPCResponse().SetBetheBlochParameters(alephParameters[0],alephParameters[1],alephParameters[2], alephParameters[3],alephParameters[4]); + fgDefaultPIDaod->GetTPCResponse().SetSigma(3.79301e-03, 2.21280e+04); + } + if(fgLogLevel){ + printf("Error - You are using the default PID: You should use the PID coming from the tender\n"); + printf("Error - Arrrrrrrrr...\n"); + printf("Error - Please rethink your program logic. Using default PID is really dangerous\n"); + printf("Error - TOF PID is adapted to Monte Carlo\n"); + } + return fgDefaultPIDaod; +} + //__________________________________________ void AliHFEtools::DestroyDefaultPID(){ // @@ -200,4 +242,39 @@ void AliHFEtools::DestroyDefaultPID(){ // if(fgDefaultPID) delete fgDefaultPID; fgDefaultPID = NULL; + if(fgDefaultPIDaod) delete fgDefaultPIDaod; + fgDefaultPIDaod = NULL; +} + +//__________________________________________ +Int_t AliHFEtools::GetPdg(const AliVParticle *track){ + // + // Get MC PDG code (only MC particles supported) + // + Int_t pdg = 0; + if(!TString(track->IsA()->GetName()).CompareTo("AliMCParticle")){ + const AliMCParticle *mctrack = dynamic_cast(track); + pdg = mctrack->Particle()->GetPdgCode(); + } else if(!TString(track->IsA()->GetName()).CompareTo("AliAODMCParticle")){ + const AliAODMCParticle *aodmctrack = dynamic_cast(track); + pdg = aodmctrack->GetPdgCode(); + } + return pdg; +} + +//__________________________________________ +Int_t AliHFEtools::PDG2AliPID(Int_t pdg){ + // + // Helper function to convert MC PID codes into AliPID codes + // + Int_t pid = -1; + switch(TMath::Abs(pdg)){ + case 11: pid = AliPID::kElectron; break; + case 13: pid = AliPID::kMuon; break; + case 211: pid = AliPID::kPion; break; + case 321: pid = AliPID::kKaon; break; + case 2212: pid = AliPID::kProton; break; + default: pid = -1; break; + }; + return pid; } diff --git a/PWG3/hfe/AliHFEtools.h b/PWG3/hfe/AliHFEtools.h index 6c4527ac8aa..0dc6dec5d56 100644 --- a/PWG3/hfe/AliHFEtools.h +++ b/PWG3/hfe/AliHFEtools.h @@ -25,6 +25,8 @@ class TParticle; class AliAODMCParticle; class AliESDpid; +class AliAODpidUtil; +class AliVParticle; class AliHFEtools : public TObject{ public: @@ -34,15 +36,19 @@ class AliHFEtools : public TObject{ static Double_t *MakeLinearBinning(Int_t nBins, Double_t ymin, Double_t ymax); static Double_t *MakeLogarithmicBinning(Int_t nBins, Double_t ymin, Double_t ymax); Bool_t BinLogAxis(TObject *o, Int_t dim); - static Float_t GetRapidity(TParticle *part); - static Float_t GetRapidity(AliAODMCParticle *part); // return rapidity + static Float_t GetRapidity(const TParticle *part); + static Float_t GetRapidity(const AliAODMCParticle *part); // return rapidity + static Int_t GetPdg(const AliVParticle *track); + static Int_t PDG2AliPID(Int_t pdg); static AliESDpid *GetDefaultPID(Bool_t isMC = kTRUE); + static AliAODpidUtil *GetDefaultAODPID(Bool_t isMC = kTRUE); static void DestroyDefaultPID(); static void SetLogLevel(Int_t loglevel) { fgLogLevel = loglevel ;} private: - static AliESDpid *fgDefaultPID; // Default PID object - static Int_t fgLogLevel; // Log Level + static AliESDpid *fgDefaultPID; // Default PID object + static AliAODpidUtil *fgDefaultPIDaod; // Default PID object + static Int_t fgLogLevel; // Log Level ClassDef(AliHFEtools, 0) }; diff --git a/PWG3/hfe/AliHFEtpcPIDqa.cxx b/PWG3/hfe/AliHFEtpcPIDqa.cxx new file mode 100644 index 00000000000..0b19a9eb7ed --- /dev/null +++ b/PWG3/hfe/AliHFEtpcPIDqa.cxx @@ -0,0 +1,269 @@ +/************************************************************************** +* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * +* * +* Author: The ALICE Off-line Project. * +* Contributors are mentioned in the code where appropriate. * +* * +* Permission to use, copy, modify and distribute this software and its * +* documentation strictly for non-commercial purposes is hereby granted * +* without fee, provided that the above copyright notice appears in all * +* copies and that both the copyright notice and this permission notice * +* appear in the supporting documentation. The authors make no claims * +* about the suitability of this software for any purpose. It is * +* provided "as is" without express or implied warranty. * +**************************************************************************/ +// +// Class AliHFEtpcPIDqa +// Monitoring TPC PID in the HFE PID montioring framework. The following +// quantities are monitored: +// TPC dE/dx (Number of sigmas) +// TPC dE/dx (Absolute values) +// (Always as function of momentum, particle species and centrality +// before and after cut) +// More information about the PID monitoring framework can be found in +// AliHFEpidQAmanager.cxx and AliHFEdetPIDqa.cxx +// +// Author: +// Markus Fasel +// +#include +#include +#include +#include + +#include "AliAODTrack.h" +#include "AliESDtrack.h" +#include "AliESDpid.h" +#include "AliLog.h" +#include "AliPID.h" + +#include "AliHFEcollection.h" +#include "AliHFEpidBase.h" +#include "AliHFEtools.h" +#include "AliHFEtpcPIDqa.h" + +//_________________________________________________________ +AliHFEtpcPIDqa::AliHFEtpcPIDqa(): + AliHFEdetPIDqa() + , fHistos(NULL) +{ + // + // Dummy constructor + // +} + +//_________________________________________________________ +AliHFEtpcPIDqa::AliHFEtpcPIDqa(const char* name): + AliHFEdetPIDqa(name, "QA for TPC") + , fHistos(NULL) +{ + // + // Default constructor + // +} + +//_________________________________________________________ +AliHFEtpcPIDqa::AliHFEtpcPIDqa(const AliHFEtpcPIDqa &o): + AliHFEdetPIDqa(o) + , fHistos() +{ + // + // Copy constructor + // + o.Copy(*this); +} + +//_________________________________________________________ +AliHFEtpcPIDqa &AliHFEtpcPIDqa::operator=(const AliHFEtpcPIDqa &o){ + // + // Do assignment + // + AliHFEdetPIDqa::operator=(o); + if(&o != this) o.Copy(*this); + return *this; +} + +//_________________________________________________________ +AliHFEtpcPIDqa::~AliHFEtpcPIDqa(){ + // + // Destructor + // + if(fHistos) delete fHistos; +} + +//_________________________________________________________ +void AliHFEtpcPIDqa::Copy(TObject &o) const { + // + // Make copy + // + AliHFEtpcPIDqa &target = dynamic_cast(o); + if(target.fHistos){ + delete target.fHistos; + target.fHistos = NULL; + } + if(fHistos) target.fHistos = new AliHFEcollection(*fHistos); +} + +//_________________________________________________________ +Long64_t AliHFEtpcPIDqa::Merge(TCollection *coll){ + // + // Merge with other objects + // + if(!coll) return 0; + if(coll->IsEmpty()) return 1; + + TIter it(coll); + AliHFEtpcPIDqa *refQA = NULL; + TObject *o = NULL; + Long64_t count = 0; + TList listHistos; + while((o = it())){ + refQA = dynamic_cast(o); + if(!refQA) continue; + + listHistos.Add(refQA->fHistos); + count++; + } + fHistos->Merge(&listHistos); + return count + 1; +} + +//_________________________________________________________ +void AliHFEtpcPIDqa::Initialize(){ + // + // Define Histograms + // + + fHistos = new AliHFEcollection("tpcqahistos", "Collection of TPC QA histograms"); + + // Make common binning + const Int_t kNdim = 5; + const Int_t kPIDbins = AliPID::kSPECIES + 1; + const Int_t kPbins = 1000; + const Int_t kSteps = 2; + const Int_t kCentralityBins = 20; + const Double_t kMinPID = -1; + const Double_t kMinP = 0.; + const Double_t kMaxPID = (Double_t)AliPID::kSPECIES; + const Double_t kMaxP = 20.; + + // 1st histogram: TPC dEdx: (species, p, dEdx, step) + const Int_t kDedxbins = 600; + Int_t nBinsdEdx[kNdim] = {kPIDbins, kPbins, kDedxbins, kSteps, kCentralityBins}; + Double_t mindEdx[kNdim] = {kMinPID, kMinP, 0., 0., 0.}; + Double_t maxdEdx[kNdim] = {kMaxPID, kMaxP, 300, 2., 100.}; + fHistos->CreateTHnSparse("tpcDedx", "TPC signal; species; p [GeV/c]; TPC signal [a.u.]; Centrality; Selection Step", kNdim, nBinsdEdx, mindEdx, maxdEdx); + // 2nd histogram: TPC sigmas: (species, p nsigma, step) + const Int_t kSigmaBins = 1400; + Int_t nBinsSigma[kNdim] = {kPIDbins, kPbins, kSigmaBins, kSteps, kCentralityBins}; + Double_t minSigma[kNdim] = {kMinPID, kMinP, -12., 0., 0.}; + Double_t maxSigma[kNdim] = {kMaxPID, kMaxP, 12., 2., 100.}; + fHistos->CreateTHnSparse("tpcnSigma", "TPC signal; species; p [GeV/c]; TPC signal [a.u.]; Centrality; Selection Step", kNdim, nBinsSigma, minSigma, maxSigma); + + // General TPC QA +} + +//_________________________________________________________ +void AliHFEtpcPIDqa::ProcessTrack(AliHFEpidObject *track, AliHFEdetPIDqa::EStep_t step){ + // + // Fill TPC histograms + // + AliDebug(1, Form("QA started for TPC PID for step %d", (Int_t)step)); + Int_t species = track->GetAbInitioPID(); + Float_t centrality = track->GetCentrality(); + const AliVParticle *rectrack = track->GetRecTrack(); + if(species >= AliPID::kSPECIES) species = -1; + if(!TString(rectrack->IsA()->GetName()).CompareTo("AliESDtrack")) ProcessESDtrack(dynamic_cast(rectrack), step, species, centrality); + else if(!TString(rectrack->IsA()->GetName()).CompareTo("AliAODTrack")) ProcessAODtrack(dynamic_cast(rectrack), step, species, centrality); + else AliWarning(Form("Object type %s not supported\n", rectrack->IsA()->GetName())); +} + +//_________________________________________________________ +void AliHFEtpcPIDqa::ProcessESDtrack(const AliESDtrack *track, AliHFEdetPIDqa::EStep_t step, Int_t species, Float_t centrality){ + // + // Process track as ESD track + // + if(!fESDpid){ + AliError("No ESD PID object available"); + return; + } + AliDebug(1, Form("Monitoring particle of type %d for step %d", species, step)); + + Double_t contentSignal[5]; + contentSignal[0] = species; + contentSignal[1] = track->GetInnerParam() ? track->GetInnerParam()->P() : track->P(); + contentSignal[2] = track->GetTPCsignal(); + contentSignal[3] = step; + contentSignal[4] = centrality; + (dynamic_cast(fHistos->Get("tpcDedx")))->Fill(contentSignal); + + contentSignal[2] = fESDpid->NumberOfSigmasTPC(track, AliPID::kElectron); + (dynamic_cast(fHistos->Get("tpcnSigma")))->Fill(contentSignal); +} + +//_________________________________________________________ +void AliHFEtpcPIDqa::ProcessAODtrack(const AliAODTrack * /*track*/, AliHFEdetPIDqa::EStep_t /*step*/, Int_t /*species*/, Float_t /*centrality*/){ + // + // Process track as AOD track + // + AliInfo("Method implemented soon!"); +} + +//_________________________________________________________ +TH2 *AliHFEtpcPIDqa::MakeSpectrumdEdx(AliHFEdetPIDqa::EStep_t istep, Int_t species){ + // + // Plot the Spectrum + // + THnSparseF *hSignal = dynamic_cast(fHistos->Get("tpcDedx")); + hSignal->GetAxis(3)->SetRange(istep + 1, istep + 1); + if(species > 0 && species < AliPID::kSPECIES) + hSignal->GetAxis(0)->SetRange(2 + species, 2 + species); + TH2 *hTmp = hSignal->Projection(2,1); + Char_t hname[256], htitle[256]; + sprintf(hname, "hTPCsignal%s", istep == AliHFEdetPIDqa::kBeforePID ? "before" : "after"); + sprintf(htitle, "TPC dE/dx Spectrum %s selection", istep == AliHFEdetPIDqa::kBeforePID ? "before" : "after"); + if(species > -1){ + strncat(hname, AliPID::ParticleName(species), strlen(AliPID::ParticleName(species))); + Char_t speciesname[256]; + sprintf(speciesname, " for %ss", AliPID::ParticleName(species)); + strncat(htitle, speciesname, strlen(speciesname)); + } + hTmp->SetName(hname); + hTmp->SetTitle(htitle); + hTmp->SetStats(kFALSE); + hTmp->GetXaxis()->SetTitle("p [GeV/c]"); + hTmp->GetYaxis()->SetTitle("TPC signal [a.u.]"); + hSignal->GetAxis(3)->SetRange(0, hSignal->GetAxis(3)->GetNbins()); + hSignal->GetAxis(0)->SetRange(0, hSignal->GetAxis(0)->GetNbins()); + return hTmp; +} + +//_________________________________________________________ +TH2 *AliHFEtpcPIDqa::MakeSpectrumNSigma(AliHFEdetPIDqa::EStep_t istep, Int_t species){ + // + // Plot the Spectrum + // + THnSparseF *hSignal = dynamic_cast(fHistos->Get("tpcnSigma")); + hSignal->GetAxis(3)->SetRange(istep + 1, istep + 1); + if(species >= 0 && species < AliPID::kSPECIES) + hSignal->GetAxis(0)->SetRange(2 + species, 2 + species); + TH2 *hTmp = hSignal->Projection(2,1); + Char_t hname[256], htitle[256]; + sprintf(hname, "hTPCsigma%s", istep == AliHFEdetPIDqa::kBeforePID ? "before" : "after"); + sprintf(htitle, "TPC dE/dx Spectrum[#sigma] %s selection", istep == AliHFEdetPIDqa::kBeforePID ? "before" : "after"); + if(species > -1){ + strncat(hname, AliPID::ParticleName(species), strlen(AliPID::ParticleName(species))); + Char_t speciesname[256]; + sprintf(speciesname, " for %ss", AliPID::ParticleName(species)); + strncat(htitle, speciesname, strlen(speciesname)); + } + hTmp->SetName(hname); + hTmp->SetTitle(htitle); + hTmp->SetStats(kFALSE); + hTmp->GetXaxis()->SetTitle("p [GeV/c]"); + hTmp->GetYaxis()->SetTitle("TPC dE/dx - |_{el} [#sigma]"); + hSignal->GetAxis(3)->SetRange(0, hSignal->GetAxis(3)->GetNbins()); + hSignal->GetAxis(0)->SetRange(0, hSignal->GetAxis(0)->GetNbins()); + return hTmp; +} + diff --git a/PWG3/hfe/AliHFEtpcPIDqa.h b/PWG3/hfe/AliHFEtpcPIDqa.h new file mode 100644 index 00000000000..dc3c909536e --- /dev/null +++ b/PWG3/hfe/AliHFEtpcPIDqa.h @@ -0,0 +1,58 @@ +/************************************************************************** +* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * +* * +* Author: The ALICE Off-line Project. * +* Contributors are mentioned in the code where appropriate. * +* * +* Permission to use, copy, modify and distribute this software and its * +* documentation strictly for non-commercial purposes is hereby granted * +* without fee, provided that the above copyright notice appears in all * +* copies and that both the copyright notice and this permission notice * +* appear in the supporting documentation. The authors make no claims * +* about the suitability of this software for any purpose. It is * +* provided "as is" without express or implied warranty. * +**************************************************************************/ +// +// Class AliHFEtpcPIDqa +// Monitoring TPC PID in the HFE PID montioring framework +// More information can be found inside the implementation file +// +#ifndef ALIHFETPCPIDQA_H +#define ALIHFETPCPIDQA_H + +#ifndef ALIHFEDETPIDQA_H +#include "AliHFEdetPIDqa.h" +#endif + +class TH2; +class AliHFEcollection; +class AliHFEpidObject; +class AliESDtrack; +class AliAODTrack; + +class AliHFEtpcPIDqa : public AliHFEdetPIDqa{ + public: + AliHFEtpcPIDqa(); + AliHFEtpcPIDqa(const char*name); + AliHFEtpcPIDqa(const AliHFEtpcPIDqa &o); + AliHFEtpcPIDqa &operator=(const AliHFEtpcPIDqa &o); + ~AliHFEtpcPIDqa(); + void Copy(TObject &o) const; + virtual Long64_t Merge(TCollection *col); + + virtual void Initialize(); + virtual void ProcessTrack(AliHFEpidObject *track, AliHFEdetPIDqa::EStep_t step); + + AliHFEcollection *GetHistograms() const { return fHistos; } + TH2 *MakeSpectrumdEdx(AliHFEdetPIDqa::EStep_t step, Int_t species = -1); + TH2 *MakeSpectrumNSigma(AliHFEdetPIDqa::EStep_t step, Int_t species = -1); + + protected: + void ProcessESDtrack(const AliESDtrack *track, AliHFEdetPIDqa::EStep_t step, Int_t species, Float_t centrality); + void ProcessAODtrack(const AliAODTrack *track, AliHFEdetPIDqa::EStep_t step, Int_t species, Float_t centrality); + private: + AliHFEcollection *fHistos; // Container for Histograms + + ClassDef(AliHFEtpcPIDqa, 1); +}; +#endif diff --git a/PWG3/hfe/AliHFEtrdPIDqa.cxx b/PWG3/hfe/AliHFEtrdPIDqa.cxx index 08412e7b2af..9e5f170903a 100644 --- a/PWG3/hfe/AliHFEtrdPIDqa.cxx +++ b/PWG3/hfe/AliHFEtrdPIDqa.cxx @@ -252,10 +252,15 @@ void AliHFEtrdPIDqa::CreatedEdxHistogram(){ AliDebug(1, "Called"); Int_t nbins[kQuantitiesdEdx]; memcpy(nbins, fgkNBinsCommon, sizeof(Int_t) * kQuantitiesCommon); nbins[kdEdx] = 100; + nbins[kNclusters] = 261; + nbins[kNonZeroSlices] = 9; Double_t binMin[kQuantitiesdEdx]; memcpy(binMin, fgkMinBinCommon, sizeof(Double_t) * kQuantitiesCommon); - binMin[kdEdx] = 0.; + binMin[kdEdx] = 0.; + binMin[kNclusters] = 0; Double_t binMax[kQuantitiesdEdx]; memcpy(binMax, fgkMaxBinCommon, sizeof(Double_t) * kQuantitiesCommon); binMax[kdEdx] = 100000.; + binMax[kNclusters] = 260.; + binMax[kNonZeroSlices] = 8.; fQAdEdx = new THnSparseF("fQAdEdx","TRD summed dEdx", kQuantitiesdEdx, nbins, binMin, binMax); Double_t *binLog = AliHFEtools::MakeLogarithmicBinning(nbins[kP], binMin[kP], binMax[kP]); @@ -393,25 +398,34 @@ void AliHFEtrdPIDqa::FillTRDQAplots(AliESDtrack *track, Int_t species){ quantitiesQA[kNTracklets] = quantitiesdEdx[kNTracklets] = quantitiesTruncMean[kNTracklets] = track->GetTRDntrackletsPID(); - quantitiesQA[kNClusters] = track->GetTRDncls(); + quantitiesQA[kNClusters] = quantitiesdEdx[kNclusters] = track->GetTRDncls(); + - Double_t dEdxSum; - Int_t ntrackletsNonZero = 0, nSlices = track->GetNumberOfTRDslices(); + Double_t dEdxSum = 0., qSlice = 0.; + // remove the last slice from the histogram + Int_t ntrackletsNonZero = 0, nSlices = track->GetNumberOfTRDslices() - 1, nSlicesNonZero = 0; for(Int_t iplane = 0; iplane < AliESDtrack::kTRDnPlanes; iplane++){ dEdxSum = 0.; - for(Int_t islice = 0; islice < nSlices; islice++) - dEdxSum += track->GetTRDslice(iplane, islice); + for(Int_t islice = 0; islice < nSlices; islice++){ + qSlice = track->GetTRDslice(iplane, islice); + if(qSlice > 1e-1){ + // cut out 0 slices + nSlicesNonZero++; + dEdxSum += qSlice; + } + } + quantitiesdEdx[kNonZeroSlices] = nSlicesNonZero; quantitiesdEdx[kdEdx] = dEdxSum; if(dEdxSum) ntrackletsNonZero++; // Fill dEdx histogram - fQAdEdx->Fill(quantitiesdEdx); + if(dEdxSum > 1e-1) fQAdEdx->Fill(quantitiesdEdx); // Cut out 0 entries } quantitiesQA[kNonZeroTrackletCharge] = ntrackletsNonZero; fQAtrack->Fill(quantitiesQA); quantitiesTruncMean[kTPCdEdx] = track->GetTPCsignal(); - quantitiesTruncMean[kTRDdEdxMethod1] = fTRDpid->GetTRDSignalV1(track, -1); - quantitiesTruncMean[kTRDdEdxMethod2] = fTRDpid->GetTRDSignalV2(track, -1); + quantitiesTruncMean[kTRDdEdxMethod1] = fTRDpid->GetTRDSignalV1(track); + quantitiesTruncMean[kTRDdEdxMethod2] = fTRDpid->GetTRDSignalV2(track); fTRDtruncMean->Fill(quantitiesTruncMean); } diff --git a/PWG3/hfe/AliHFEtrdPIDqa.h b/PWG3/hfe/AliHFEtrdPIDqa.h index 45b3170c0d8..b4e7b6f6e96 100644 --- a/PWG3/hfe/AliHFEtrdPIDqa.h +++ b/PWG3/hfe/AliHFEtrdPIDqa.h @@ -90,8 +90,10 @@ class AliHFEtrdPIDqa : public TNamed{ kQuantitiesQA = 5 }; enum QuantitiesdEdx_t{ - kdEdx = 3, - kQuantitiesdEdx = 4 + kNclusters = 3, + kNonZeroSlices = 4, + kdEdx = 5, + kQuantitiesdEdx = 6 }; enum QuantitiesTruncMean_t{ kTPCdEdx = 3, diff --git a/PWG3/hfe/AliHFEtrdPIDqaV1.cxx b/PWG3/hfe/AliHFEtrdPIDqaV1.cxx new file mode 100644 index 00000000000..72fb7590f44 --- /dev/null +++ b/PWG3/hfe/AliHFEtrdPIDqaV1.cxx @@ -0,0 +1,295 @@ +/************************************************************************** +* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * +* * +* Author: The ALICE Off-line Project. * +* Contributors are mentioned in the code where appropriate. * +* * +* Permission to use, copy, modify and distribute this software and its * +* documentation strictly for non-commercial purposes is hereby granted * +* without fee, provided that the above copyright notice appears in all * +* copies and that both the copyright notice and this permission notice * +* appear in the supporting documentation. The authors make no claims * +* about the suitability of this software for any purpose. It is * +* provided "as is" without express or implied warranty. * +**************************************************************************/ +// +// Class AliHFEtrdPIDqaV1 +// Monitoring TRD PID in the HFE PID montioring framework. The following +// quantities are monitored: +// TRD electron likelihood +// TRD dE/dx (Absolute values) +// TPC dE/dx (Number of sigmas, control histogram) +// (Always as function of momentum, particle species and centrality +// before and after cut) +// More information about the PID monitoring framework can be found in +// AliHFEpidQAmanager.cxx and AliHFEdetPIDqa.cxx +// +// Author: +// Markus Fasel +// + +#include +#include +#include +#include + +#include "AliAODTrack.h" +#include "AliESDtrack.h" +#include "AliESDpid.h" +#include "AliExternalTrackParam.h" +#include "AliPID.h" + +#include "AliHFEcollection.h" +#include "AliHFEpidBase.h" +#include "AliHFEtrdPIDqaV1.h" + +ClassImp(AliHFEtrdPIDqaV1) + +//____________________________________________________________ +AliHFEtrdPIDqaV1::AliHFEtrdPIDqaV1(): + AliHFEdetPIDqa(), + fHistos(NULL) +{ + // + // Dummy constructor + // +} + +//____________________________________________________________ +AliHFEtrdPIDqaV1::AliHFEtrdPIDqaV1(const Char_t *name): + AliHFEdetPIDqa(name, "QA for TRD"), + fHistos(NULL) +{ + // + // Default constructor + // +} + +//____________________________________________________________ +AliHFEtrdPIDqaV1::AliHFEtrdPIDqaV1(const AliHFEtrdPIDqaV1 &o): + AliHFEdetPIDqa(o), + fHistos(NULL) +{ + // + // Copy constructor + // +} + +//____________________________________________________________ +AliHFEtrdPIDqaV1 &AliHFEtrdPIDqaV1::operator=(const AliHFEtrdPIDqaV1 &o){ + // + // Make assignment + // + AliHFEdetPIDqa::operator=(o); + fHistos = o.fHistos; + + return *this; +} + +//_________________________________________________________ +Long64_t AliHFEtrdPIDqaV1::Merge(TCollection *coll){ + // + // Merge with other objects + // + if(!coll) return 0; + if(coll->IsEmpty()) return 1; + + TIter it(coll); + AliHFEtrdPIDqaV1 *refQA = NULL; + TObject *o = NULL; + Long64_t count = 0; + TList listHistos; + while((o = it())){ + refQA = dynamic_cast(o); + if(!refQA) continue; + + listHistos.Add(refQA->fHistos); + count++; + } + fHistos->Merge(&listHistos); + return count + 1; +} + +//____________________________________________________________ +void AliHFEtrdPIDqaV1::Initialize(){ + // + // Initialize QA histos for TRD PID + // + + AliDebug(1, "Initializing PID QA for TRD"); + // Make common binning + const Int_t kPIDbins = AliPID::kSPECIES + 1; + const Int_t kPbins = 100; + const Int_t kSteps = 2; + const Double_t kMinPID = -1; + const Double_t kMinP = 0.; + const Double_t kMaxPID = (Double_t)AliPID::kSPECIES; + const Double_t kMaxP = 20.; + + fHistos = new AliHFEcollection("trdqahistos", "Collection of TRD QA histograms"); + + // Create Control Histogram monitoring the TPC sigma between the selection steps + const Int_t kTPCSigmaBins = 140; + Int_t nBinsTPCSigma[4] = {kPIDbins, kPbins, kTPCSigmaBins, kSteps}; + Double_t minTPCSigma[4] = {kMinPID, kMinP, -12., 0}; + Double_t maxTPCSigma[4] = {kMaxPID, kMaxP, 12., 2.}; + fHistos->CreateTHnSparse("hTPCsigma", "TPC sigma; species p [GeV/c]; TPC dEdx - |_{el} [#sigma]; selection step", 4, nBinsTPCSigma, minTPCSigma, maxTPCSigma); + // Create Monitoring histogram for the Likelihood distribution + const Int_t kTRDLikelihoodBins = 100; + Int_t nBinsTRDlike[4] = {kPIDbins, kPbins, kTRDLikelihoodBins, kSteps}; + Double_t minTRDlike[4] = {kMinPID, kMinP, 0., 0.}; + Double_t maxTRDlike[4] = {kMaxPID, kMaxP, 1., 2.}; + fHistos->CreateTHnSparse("hTRDlikelihood", "TRD Likelihood Distribution; species; p [GeV/c]; TRD electron Likelihood; selection step", 4, nBinsTRDlike, minTRDlike, maxTRDlike); + // Create Monitoring histogram for the TRD total charge + const Int_t kTRDchargeBins = 1000; + Int_t nBinsTRDcharge[4] = {kPIDbins, kPbins, kTRDchargeBins, kSteps}; + Double_t minTRDcharge[4] = {kMinPID, kMinP, 0., 0.}; + Double_t maxTRDcharge[4] = {kMaxPID, kMaxP, 100000., 2.}; + fHistos->CreateTHnSparse("hTRDcharge", "Total TRD charge; species; p [GeV/c]; TRD charge [a.u.]; selection step", 4, nBinsTRDcharge, minTRDcharge, maxTRDcharge); +} + +//____________________________________________________________ +void AliHFEtrdPIDqaV1::ProcessTrack(AliHFEpidObject *track, AliHFEdetPIDqa::EStep_t step){ + // + // Process the track, fill the containers + // + AliDebug(1, Form("QA started for TRD PID for step %d", (Int_t)step)); + Int_t species = track->GetAbInitioPID(); + const AliVParticle *rectrack = track->GetRecTrack(); + if(species >= AliPID::kSPECIES) species = -1; + if(!TString(rectrack->IsA()->GetName()).CompareTo("AliESDtrack")) ProcessESDtrack(dynamic_cast(rectrack), step, species); + else if(!TString(rectrack->IsA()->GetName()).CompareTo("AliAODTrack")) ProcessAODtrack(dynamic_cast(rectrack), step, species); + else AliWarning(Form("Object type %s not supported\n", rectrack->IsA()->GetName())); +} + +//____________________________________________________________ +void AliHFEtrdPIDqaV1::ProcessESDtrack(const AliESDtrack *track, AliHFEdetPIDqa::EStep_t step, Int_t species){ + // + // Fill QA histograms + // + Double_t container[4]; + container[0] = species; + container[1] = track->GetOuterParam() ? track->GetOuterParam()->P() : track->P(); + container[2] = fESDpid->NumberOfSigmasTPC(track, AliPID::kElectron); + container[3] = step; + fHistos->Fill("hTPCsigma", container); + + Double_t pid[5]; + track->GetTRDpid(pid); + container[2] = pid[AliPID::kElectron]; + fHistos->Fill("hTRDlikelihood", container); + + Double_t charge = 0.; + for(Int_t ily = 0; ily < 6; ily++){ + charge = 0.; + for(Int_t isl = 0; isl < track->GetNumberOfTRDslices(); isl++){ + charge += track->GetTRDslice(ily, isl); + } + fHistos->Fill("hTRDcharge", container); + } +} + +//_________________________________________________________ +void AliHFEtrdPIDqaV1::ProcessAODtrack(const AliAODTrack * /*track*/, AliHFEdetPIDqa::EStep_t /*step*/, Int_t /*species*/){ + // + // To be implemented + // +} + +//_________________________________________________________ +TH2 *AliHFEtrdPIDqaV1::MakeTPCspectrumNsigma(AliHFEdetPIDqa::EStep_t step, Int_t species){ + // + // Get the TPC control histogram for the TRD selection step (either before or after PID) + // + printf("histos :%p\n", fHistos); + THnSparseF *histo = dynamic_cast(fHistos->Get("hTPCsigma")); + if(!histo){ + AliError("QA histogram monitoring TPC nSigma not available"); + return NULL; + } + if(species > -1 && species < AliPID::kSPECIES){ + // cut on species (if available) + histo->GetAxis(0)->SetRange(species + 2, species + 2); // undef + underflow + } + histo->GetAxis(3)->SetRangeUser(species + 1, species + 1); + + TH2 *hSpec = histo->Projection(2, 1); + // construct title and name + TString stepname = step ? "before" : "after"; + TString speciesname = species > -1 && species < AliPID::kSPECIES ? AliPID::ParticleName(species) : "all Particles"; + TString specID = species > -1 && species < AliPID::kSPECIES ? AliPID::ParticleName(species) : "unid"; + TString histname = Form("hSigmaTPC%s%s", specID.Data(), stepname.Data()); + TString histtitle = Form("TPC Sigma for %s %s PID", speciesname.Data(), stepname.Data()); + hSpec->SetName(histname.Data()); + hSpec->SetTitle(histtitle.Data()); + + // Unset range on the original histogram + histo->GetAxis(0)->SetRange(0, histo->GetAxis(0)->GetNbins()); + histo->GetAxis(2)->SetRange(0, histo->GetAxis(2)->GetNbins()); + return hSpec; +} + +//_________________________________________________________ +TH2 *AliHFEtrdPIDqaV1::MakeTRDlikelihoodDistribution(AliHFEdetPIDqa::EStep_t step, Int_t species){ + // + // Make Histogram for TRD Likelihood distribution + // + THnSparseF *histo = dynamic_cast(fHistos->Get("hTRDlikelihood")); + if(!histo){ + AliError("QA histogram monitoring TRD Electron Likelihood not available"); + return NULL; + } + if(species > -1 && species < AliPID::kSPECIES){ + // cut on species (if available) + histo->GetAxis(0)->SetRange(species + 2, species + 2); // undef + underflow + } + histo->GetAxis(3)->SetRangeUser(species + 1, species + 1); + + TH2 *hSpec = histo->Projection(2, 1); + // construct title and name + TString stepname = step ? "before" : "after"; + TString speciesname = species > -1 && species < AliPID::kSPECIES ? AliPID::ParticleName(species) : "all Particles"; + TString specID = species > -1 && species < AliPID::kSPECIES ? AliPID::ParticleName(species) : "unid"; + TString histname = Form("hLikeElTRD%s%s", specID.Data(), stepname.Data()); + TString histtitle = Form("TRD electron Likelihood for %s %s PID", speciesname.Data(), stepname.Data()); + hSpec->SetName(histname.Data()); + hSpec->SetTitle(histtitle.Data()); + + // Unset range on the original histogram + histo->GetAxis(0)->SetRange(0, histo->GetAxis(0)->GetNbins()); + histo->GetAxis(2)->SetRange(0, histo->GetAxis(2)->GetNbins()); + return hSpec; +} + +//_________________________________________________________ +TH2 *AliHFEtrdPIDqaV1::MakeTRDchargeDistribution(AliHFEdetPIDqa::EStep_t step, Int_t species){ + // + // Make Histogram for TRD Likelihood distribution + // + THnSparseF *histo = dynamic_cast(fHistos->Get("hTRDcharge")); + if(!histo){ + AliError("QA histogram monitoring TRD total charge not available"); + return NULL; + } + if(species > -1 && species < AliPID::kSPECIES){ + // cut on species (if available) + histo->GetAxis(0)->SetRange(species + 2, species + 2); // undef + underflow + } + histo->GetAxis(3)->SetRangeUser(species + 1, species + 1); + + TH2 *hSpec = histo->Projection(2, 1); + // construct title and name + TString stepname = step ? "before" : "after"; + TString speciesname = species > -1 && species < AliPID::kSPECIES ? AliPID::ParticleName(species) : "all Particles"; + TString specID = species > -1 && species < AliPID::kSPECIES ? AliPID::ParticleName(species) : "unid"; + TString histname = Form("hChargeTRD%s%s", specID.Data(), stepname.Data()); + TString histtitle = Form("TRD total charge for %s %s PID", speciesname.Data(), stepname.Data()); + hSpec->SetName(histname.Data()); + hSpec->SetTitle(histtitle.Data()); + + // Unset range on the original histogram + histo->GetAxis(0)->SetRange(0, histo->GetAxis(0)->GetNbins()); + histo->GetAxis(2)->SetRange(0, histo->GetAxis(2)->GetNbins()); + return hSpec; +} + diff --git a/PWG3/hfe/AliHFEtrdPIDqaV1.h b/PWG3/hfe/AliHFEtrdPIDqaV1.h new file mode 100644 index 00000000000..a02ea15eed6 --- /dev/null +++ b/PWG3/hfe/AliHFEtrdPIDqaV1.h @@ -0,0 +1,56 @@ +/************************************************************************** +* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * +* * +* Author: The ALICE Off-line Project. * +* Contributors are mentioned in the code where appropriate. * +* * +* Permission to use, copy, modify and distribute this software and its * +* documentation strictly for non-commercial purposes is hereby granted * +* without fee, provided that the above copyright notice appears in all * +* copies and that both the copyright notice and this permission notice * +* appear in the supporting documentation. The authors make no claims * +* about the suitability of this software for any purpose. It is * +* provided "as is" without express or implied warranty. * +**************************************************************************/ +// +// Class AliHFEtrdPIDqaV1 +// Monitoring TRD PID in the HFE PID montioring framework. +// More information can be found inside the implementation file +// +#ifndef ALIHFETRDPIDQAV1_H +#define ALIHFETRDPIDQAV1_H + +#ifndef ALIHFEDETPIDQAV1_H +#include "AliHFEdetPIDqa.h" +#endif + +class AliESDtrack; +class AliAODTrack; +class AliHFEcollection; +class AliHFEpidObject; +class TCollection; + +class AliHFEtrdPIDqaV1 : public AliHFEdetPIDqa{ + public: + AliHFEtrdPIDqaV1(); + AliHFEtrdPIDqaV1(const Char_t *name); + AliHFEtrdPIDqaV1(const AliHFEtrdPIDqaV1 &c); + AliHFEtrdPIDqaV1 &operator=(const AliHFEtrdPIDqaV1 &o); + ~AliHFEtrdPIDqaV1(){} + + virtual void Initialize(); + virtual Long64_t Merge(TCollection *coll); + virtual void ProcessTrack(AliHFEpidObject *track, AliHFEdetPIDqa::EStep_t step); + + TH2 *MakeTPCspectrumNsigma(AliHFEdetPIDqa::EStep_t step, Int_t species = -1); + TH2 *MakeTRDlikelihoodDistribution(AliHFEdetPIDqa::EStep_t step, Int_t species = -1); + TH2 *MakeTRDchargeDistribution(AliHFEdetPIDqa::EStep_t step, Int_t species = -1); + protected: + void ProcessESDtrack(const AliESDtrack *esdtrack, AliHFEdetPIDqa::EStep_t step, Int_t species); + void ProcessAODtrack(const AliAODTrack *aodtrack, AliHFEdetPIDqa::EStep_t step, Int_t species); + AliHFEcollection *fHistos; // QA histograms + + ClassDef(AliHFEtrdPIDqaV1, 1) // Base class for detector PID QA +}; + +#endif diff --git a/PWG3/hfe/AliHFEvarManager.cxx b/PWG3/hfe/AliHFEvarManager.cxx new file mode 100644 index 00000000000..c3ed37b6f8e --- /dev/null +++ b/PWG3/hfe/AliHFEvarManager.cxx @@ -0,0 +1,425 @@ +/************************************************************************** +* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * +* * +* Author: The ALICE Off-line Project. * +* Contributors are mentioned in the code where appropriate. * +* * +* Permission to use, copy, modify and distribute this software and its * +* documentation strictly for non-commercial purposes is hereby granted * +* without fee, provided that the above copyright notice appears in all * +* copies and that both the copyright notice and this permission notice * +* appear in the supporting documentation. The authors make no claims * +* about the suitability of this software for any purpose. It is * +* provided "as is" without express or implied warranty. * +**************************************************************************/ +// +// Class AliHFEvarManager: +// Contains definition of the variables which are filled into the +// Correction framework container. The class handles both AliCFContainer and +// AliHFEcontainer. +// Defining a new variable which has to be monitored can be done via the +// function AddVariable. This function also defines a new dimension for the +// particle container and appends it to the list of variables. For a new +// track the function NewTrack caches the values to be filled into the +// correction framework container. With FillContainer the specified +// correction framework container is filled. The VarManager also handles +// the filling of the correlation matrices +// +// Author: +// Markus Fasel +// +#include +#include +#include +#include +#include +#include + +#include "AliCFContainer.h" +#include "AliLog.h" +#include "AliVParticle.h" + +#include "AliHFEcontainer.h" +#include "AliHFEsignalCuts.h" +#include "AliHFEvarManager.h" + +ClassImp(AliHFEvarManager) +ClassImp(AliHFEvarManager::AliHFEvariable); + +//____________________________________________________________ +AliHFEvarManager::AliHFEvarManager(): + TNamed(), + fVariables(NULL), + fContent(NULL), + fContentMC(NULL), + fWeightFactor(1.), + fSignalTrack(kTRUE), + fWeighting(kFALSE), + fSignal(NULL), + fWeightFactors(NULL), + fWeightFactorsFunction(NULL) +{ + // + // Dummy constructor + // + SetOwner(); +} + +//____________________________________________________________ +AliHFEvarManager::AliHFEvarManager(const Char_t *name): + TNamed(name, ""), + fVariables(NULL), + fContent(NULL), + fContentMC(NULL), + fWeightFactor(1.), + fSignalTrack(kTRUE), + fWeighting(kFALSE), + fSignal(NULL), + fWeightFactors(NULL), + fWeightFactorsFunction(NULL) +{ + // + // Default constructor + // + fVariables = new TObjArray; + SetOwner(); +} + +//____________________________________________________________ +AliHFEvarManager::AliHFEvarManager(const AliHFEvarManager &ref): + TNamed(ref), + fVariables(NULL), + fContent(NULL), + fContentMC(NULL), + fWeightFactor(ref.fWeightFactor), + fSignalTrack(ref.fSignalTrack), + fWeighting(ref.fWeighting), + fSignal(NULL), + fWeightFactors(NULL), + fWeightFactorsFunction(NULL) +{ + // + // Copy Constructor + // + ref.Copy(*this); +} + +//____________________________________________________________ +AliHFEvarManager &AliHFEvarManager::operator=(const AliHFEvarManager &ref){ + // + // Assignment operator + // + if(&ref != this){ + this->~AliHFEvarManager(); + ref.Copy(*this); + } + return *this; +} + +//____________________________________________________________ +AliHFEvarManager::~AliHFEvarManager(){ + // + // Destructor + // + if(IsOwner()){ + if(fVariables) delete fVariables; + } + if(fContent) delete[] fContent; + if(fContentMC) delete[] fContentMC; +} + +//____________________________________________________________ +void AliHFEvarManager::Copy(TObject &o) const{ + // + // Make Copy + // + AliHFEvarManager &target = dynamic_cast(o); + target.fVariables = fVariables; + target.fContent = new Double_t[sizeof(fContent)/sizeof(Double_t)]; + target.fContentMC = new Double_t[sizeof(fContentMC)/sizeof(Double_t)]; + target.fWeightFactor = fWeightFactor; + target.fSignalTrack = fSignalTrack; + target.fWeighting = fWeighting; + target.fSignal = fSignal; + target.fWeightFactors = fWeightFactors; + target.fWeightFactorsFunction = fWeightFactorsFunction; + target.SetOwner(kFALSE); +} + +//____________________________________________________________ +void AliHFEvarManager::AddVariable(TString name){ + // + // Add new variable to the var manager + // Value derived via GetValue() + // + AliDebug(1, Form("Var Name: %s", name.Data())); + + if(!name.CompareTo("pt")) + fVariables->AddLast(new AliHFEvariable("pt", "pt", kPt, 44, 0.1, 20, kTRUE)); + else if(!name.CompareTo("eta")) + fVariables->AddLast(new AliHFEvariable("eta", "eta", kEta, 8, -0.8, 0.8)); + else if(!name.CompareTo("phi")) + fVariables->AddLast(new AliHFEvariable("phi", "phi", kPhi, 18, -0, 2*TMath::Pi())); + else if(!name.CompareTo("charge")) + fVariables->AddLast(new AliHFEvariable("charge", "charge", kCharge, 2, -1.1, 1.1)); + else if(!name.CompareTo("source")) + fVariables->AddLast(new AliHFEvariable("source", "source", kSource, 4, 0, 4)); + else if(!name.CompareTo("centrality")) + fVariables->AddLast(new AliHFEvariable("centrality", "centrality", kCentrality, 20, 0.0, 100.0)); + else if(!name.CompareTo("species")) + fVariables->AddLast(new AliHFEvariable("species", "species", kSpecies, 6, -1, 5)); + + // More to come ... +} + +//____________________________________________________________ +void AliHFEvarManager::DefineVariables(AliHFEcontainer *cont){ + // + // Define Variables + // + Int_t nVars = fVariables->GetEntriesFast(); + cont->SetNumberOfVariables(nVars); + TIter vars(fVariables); + AliHFEvariable *var; + Int_t counter = 0; + while((var = dynamic_cast(vars()))){ + cont->SetVariableName(counter, var->GetName()); + if(var->IsLogarithmic()) + cont->MakeLogarithmicBinning(counter, var->GetNumberOfBins(), var->GetMinimum(), var->GetMaximum()); + else + cont->MakeLinearBinning(counter, var->GetNumberOfBins(), var->GetMinimum(), var->GetMaximum()); + counter++; + } + fContent = new Double_t[nVars]; + memset(fContent, 0, sizeof(Double_t) * nVars); + fContentMC = new Double_t[nVars]; + memset(fContentMC, 0, sizeof(Double_t) * nVars); +} + +//____________________________________________________________ +void AliHFEvarManager::NewTrack(AliVParticle *recTrack, AliVParticle *mcTrack, Float_t centrality, Int_t aprioriPID, Bool_t signal){ + // + // Cache information for new track pair + // + AliDebug(1, "Filling new Track"); + fSignalTrack = signal; + FillArray(recTrack, fContent, centrality, aprioriPID); + if(mcTrack) FillArray(mcTrack, fContentMC, centrality, aprioriPID); + if(fWeighting){ + Int_t indexpt = -1, indexeta = -1, indexphi = -1, counter = 0; + AliHFEvariable *var = NULL; + TIter vars(fVariables); + while((var = dynamic_cast(vars()))){ + switch(var->GetVarCode()){ + case kPt: indexpt = counter; break; + case kEta: indexeta = counter; break; + case kPhi: indexphi = counter; break; + }; + if(indexpt >= 0 && indexeta >= 0 && indexphi >= 0) // all dimensions found + break; + counter++; + } + if(indexpt >= 0 && indexeta >= 0 && indexphi >= 0) + fWeightFactor = FindWeight(fContent[indexpt], fContent[indexeta], fContent[indexphi]); + } +} + +//____________________________________________________________ +Double_t AliHFEvarManager::GetValue(AliVParticle *track, UInt_t code, Float_t centrality, Int_t aprioriPID) const { + // + // Definition of the variables + // + if(!track) return 0.; + Double_t value = 0.; + switch(code){ + case kPt: value = track->Pt(); break; + case kEta: value = track->Eta(); break; + case kPhi: value = track->Phi(); break; + case kCharge:{ + value = track->Charge(); + if(TString(track->IsA()->GetName()).Contains("MC")) value /= 3; + break; + } + case kSource:{ + if(fSignal){ + if(fSignal->IsCharmElectron(track)) value = 0; + else if(fSignal->IsBeautyElectron(track)) value = 1; + else if(fSignal->IsGammaElectron(track)) value = 2; + else value = 3; + } + break; + } + case kSpecies: value = aprioriPID; break; + case kCentrality: value = centrality; break; + }; + return value; +} + +//____________________________________________________________ +void AliHFEvarManager::FillArray(AliVParticle *track, Double_t* container, Float_t centrality, Int_t aprioriPID) const{ + // + // Fill array with variables + // + TIter vars(fVariables); + AliHFEvariable *var = NULL; + Int_t counter = 0; + while((var = dynamic_cast(vars()))) + container[counter++] = GetValue(track , var->GetVarCode(), centrality, aprioriPID); +} + +//____________________________________________________________ +void AliHFEvarManager::FillContainer(AliCFContainer *cont, Int_t step, Bool_t useMC) const{ + // + // Fill CF container with defined content + // + + // Do reweighting if necessary + Double_t *content = fContent; + if(useMC) content = fContentMC; + cont->Fill(content, step, fWeightFactor); +} + +//____________________________________________________________ +void AliHFEvarManager::FillContainer(AliHFEcontainer *cont, const Char_t *contname, UInt_t step, Bool_t useMC, Double_t externalWeight) const { + // + // Fill CF container with defined content + // + + // Do reweighting if necessary + Double_t *content = fContent; + if(useMC) content = fContentMC; + cont->FillCFContainer(contname, step, content, fWeightFactor * externalWeight); +} + +//____________________________________________________________ +void AliHFEvarManager::FillContainerStepname(AliHFEcontainer *cont, const Char_t *contname, const Char_t *step, Bool_t useMC, Double_t externalWeight) const { + // + // Fill CF container with defined content + // + + // Do reweighting if necessary + Double_t *content = fContent; + if(useMC) content = fContentMC; + cont->FillCFContainerStepname(contname, step, content, fWeightFactor * externalWeight); +} + +//____________________________________________________________ +void AliHFEvarManager::FillCorrelationMatrix(THnSparseF *matrix) const { + // + // Fill Correlation Matrix + // + + // Do reweighting if necessary + Double_t content[10]; + memcpy(content, fContent, sizeof(Double_t) * 5); + memcpy(&content[5], fContentMC, sizeof(Double_t) * 5); + matrix->Fill(content, fWeightFactor); +} + +//_______________________________________________ +void AliHFEvarManager::SetWeightFactors(TH3F *weightFactors){ + // + // Set the histos with the weights for the efficiency maps + // + fWeighting = kTRUE; + fWeightFactors = weightFactors; +} + +//_______________________________________________ +void AliHFEvarManager::SetWeightFactorsFunction(TF3 *weightFactorsFunction){ + // + // Set the histos with the weights for the efficiency maps + // + fWeighting = kTRUE; + fWeightFactorsFunction = weightFactorsFunction; +} + +//_______________________________________________ +Double_t AliHFEvarManager::FindWeight(Double_t pt, Double_t eta, Double_t phi) const { + // + // Find the weight corresponding to pt eta and phi in the TH3D + // + Double_t weight = 1.0; + if(fWeightFactors) { + + TAxis *ptaxis = fWeightFactors->GetXaxis(); + TAxis *etaaxis = fWeightFactors->GetYaxis(); + TAxis *phiaxis = fWeightFactors->GetZaxis(); + + Int_t ptbin = ptaxis->FindBin(pt); + Int_t etabin = etaaxis->FindBin(eta); + Int_t phibin = phiaxis->FindBin(phi); + + + weight = fWeightFactors->GetBinContent(ptbin,etabin,phibin); + } + else if(fWeightFactorsFunction) { + + weight = fWeightFactorsFunction->Eval(pt,eta,phi); + + } + + AliDebug(2, Form("pt %f, eta %f, phi %f, weight %f",pt,eta,phi,weight)); + + return weight; +} + +//_______________________________________________ +AliHFEvarManager::AliHFEvariable::AliHFEvariable(): + TNamed() + , fCode(0) + , fNBins(0) + , fMin(0) + , fMax(0) + , fIsLogarithmic(kFALSE) +{ + // + // Dummy constructor + // +} + +//_______________________________________________ +AliHFEvarManager::AliHFEvariable::AliHFEvariable(const Char_t *name, const Char_t *title, UInt_t code, UInt_t nBins, Double_t min, Double_t max, Bool_t isLogarithmic): + TNamed(name, title) + , fCode(code) + , fNBins(nBins) + , fMin(min) + , fMax(max) + , fIsLogarithmic(isLogarithmic) +{ + // + // Default constructor + // +} + +//_______________________________________________ +AliHFEvarManager::AliHFEvariable::AliHFEvariable(const AliHFEvarManager::AliHFEvariable &ref): + TNamed(ref) + , fCode(ref.fCode) + , fNBins(ref.fNBins) + , fMin(ref.fMin) + , fMax(ref.fMax) + , fIsLogarithmic(ref.fIsLogarithmic) +{ + // + // Copy constructor + // +} + +//_______________________________________________ +AliHFEvarManager::AliHFEvariable& AliHFEvarManager::AliHFEvariable::operator=(const AliHFEvarManager::AliHFEvariable &ref){ + // + // Assignment operator + // + + if(&ref != this){ + TNamed::operator=(ref); + fCode = ref.fCode; + fNBins = ref.fNBins; + fMax = ref.fMax; + fMin = ref.fMin; + fIsLogarithmic = ref.fIsLogarithmic; + } + return *this; +} + diff --git a/PWG3/hfe/AliHFEvarManager.h b/PWG3/hfe/AliHFEvarManager.h new file mode 100644 index 00000000000..93424906beb --- /dev/null +++ b/PWG3/hfe/AliHFEvarManager.h @@ -0,0 +1,119 @@ +/************************************************************************** +* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * +* * +* Author: The ALICE Off-line Project. * +* Contributors are mentioned in the code where appropriate. * +* * +* Permission to use, copy, modify and distribute this software and its * +* documentation strictly for non-commercial purposes is hereby granted * +* without fee, provided that the above copyright notice appears in all * +* copies and that both the copyright notice and this permission notice * +* appear in the supporting documentation. The authors make no claims * +* about the suitability of this software for any purpose. It is * +* provided "as is" without express or implied warranty. * +**************************************************************************/ +// +// Class AliHFEvarManager +// Common place for definiton of variables to be filled into the +// correction framework container +// More information can be found inside the implementation file +// +#ifndef ALIHFEVARMANAGER_H +#define ALIHFEVARMANAGER_H + +#ifndef ROOT_TNamed +#include +#endif + +template +class THnSparseT; +class TArrayF; +typedef class THnSparseT THnSparseF; +class TH3F; +class TF3; +class AliCFContainer; +class AliHFEcontainer; +class AliHFEsignalCuts; +class AliVParticle; + + +class AliHFEvarManager : public TNamed{ +public: + enum EVarCode_t{ + kPt = 1, + kEta, + kPhi, + kCharge, + kSource, + kCentrality, + kSpecies, + }; + AliHFEvarManager(); + AliHFEvarManager(const Char_t *name); + AliHFEvarManager(const AliHFEvarManager &ref); + AliHFEvarManager &operator=(const AliHFEvarManager &ref); + void Copy(TObject &o) const; + ~AliHFEvarManager(); + + void SetOwner(Bool_t owner = kTRUE) { SetBit(kOwner, owner); } + Bool_t IsOwner() const { return TestBit(kOwner); } + + void AddVariable(TString name); + void DefineVariables(AliHFEcontainer *cont); + void NewTrack(AliVParticle *track, AliVParticle *mcTrack = NULL, Float_t centrality = 99.0, Int_t aprioriPID = -1, Bool_t signal = kTRUE); + Bool_t IsSignalTrack() const { return fSignalTrack; } + void FillContainer(AliCFContainer *cont, Int_t step, Bool_t useMC = kFALSE) const; + void FillContainer(AliHFEcontainer *cont, const Char_t *contname, UInt_t step, Bool_t useMC = kFALSE, Double_t externalWeight = 1.) const; + void FillContainerStepname(AliHFEcontainer *cont, const Char_t *contname, const Char_t *step, Bool_t useMC = kFALSE, Double_t externalWeight = 1.) const; + void FillCorrelationMatrix(THnSparseF *matrix) const; + + void SetSignalCuts(AliHFEsignalCuts *signal) { fSignal = signal; } + void SetWeightFactors(TH3F *weightFactors); + void SetWeightFactorsFunction(TF3*weightFactorsFunction); + + struct AliHFEvariable : public TNamed{ + public: + AliHFEvariable(); + AliHFEvariable(const Char_t *name, const Char_t *title, UInt_t fCode, UInt_t nBins, Double_t min, Double_t max, Bool_t isLogarithmic = kFALSE); + AliHFEvariable(const AliHFEvariable &ref); + AliHFEvariable &operator=(const AliHFEvariable &ref); + ~AliHFEvariable(){} + + UInt_t GetVarCode() const { return fCode; } + UInt_t GetNumberOfBins() const { return fNBins; } + Double_t GetMinimum() const { return fMin; } + Double_t GetMaximum() const { return fMax; } + Int_t IsLogarithmic() const { return fIsLogarithmic; } + private: + UInt_t fCode; // Unique variable code + UInt_t fNBins; // Number of bins + Double_t fMin; // Minimum + Double_t fMax; // Maximum + Bool_t fIsLogarithmic; // Logarithmic binning + + ClassDef(AliHFEvarManager::AliHFEvariable, 1) // HFE variable definition + }; + +protected: + Double_t GetValue(AliVParticle *track, UInt_t code, Float_t centrality = 99.0, Int_t aprioriPID = -1) const; + void FillArray(AliVParticle *track, Double_t *container, Float_t centrality = 99.0, Int_t aprioriPID = -1) const; + Double_t FindWeight(Double_t pt, Double_t eta, Double_t phi) const; + +private: + enum{ + kOwner = BIT(14) + }; + TObjArray *fVariables; // Variables to process + Double_t *fContent; //! Cache values for track in classmember + Double_t *fContentMC; //! Cache content of the asssociated MC track in class member + Double_t fWeightFactor; // Cache weighting factor + Bool_t fSignalTrack; // Signal Track + Bool_t fWeighting; // Weighting or not for the efficiency maps + AliHFEsignalCuts *fSignal; // MC Signal Definition + TH3F *fWeightFactors; // Weight factors + TF3 *fWeightFactorsFunction; // Weight factors + + ClassDef(AliHFEvarManager, 1) // The variable Manager for the HFE Analysis +}; + +#endif /* ALIHFEVARMANAGER_H */ -- 2.43.0