From b95a7bd47aaa4df58e30e0196ea6e09a9648d713 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=20Ku=C4=8Dera?= Date: Sat, 5 Jun 2021 15:35:15 +0200 Subject: [PATCH 1/8] Fix format and TPC in selector --- .../PWGHF/HFJpsiToEECandidateSelector.cxx | 107 ++++++++---------- 1 file changed, 45 insertions(+), 62 deletions(-) diff --git a/Analysis/Tasks/PWGHF/HFJpsiToEECandidateSelector.cxx b/Analysis/Tasks/PWGHF/HFJpsiToEECandidateSelector.cxx index 932c824de1c30..6624ccab5b9b7 100644 --- a/Analysis/Tasks/PWGHF/HFJpsiToEECandidateSelector.cxx +++ b/Analysis/Tasks/PWGHF/HFJpsiToEECandidateSelector.cxx @@ -15,12 +15,12 @@ /// \author Nima Zardoshti , CERN /// \author Vít Kučera , CERN -#include "ALICE3Analysis/RICH.h" -#include "AnalysisCore/TrackSelectorPID.h" -#include "AnalysisDataModel/HFCandidateSelectionTables.h" -#include "AnalysisDataModel/HFSecondaryVertex.h" -#include "Framework/AnalysisTask.h" #include "Framework/runDataProcessing.h" +#include "Framework/AnalysisTask.h" +#include "AnalysisDataModel/HFSecondaryVertex.h" +#include "AnalysisDataModel/HFCandidateSelectionTables.h" +#include "AnalysisCore/TrackSelectorPID.h" +#include "ALICE3Analysis/RICH.h" using namespace o2; using namespace o2::framework; @@ -49,43 +49,25 @@ struct RICHindexbuilder { struct HFJpsiToEECandidateSelector { Produces hfSelJpsiToEECandidate; - Configurable d_pTCandMin{"d_pTCandMin", 0., - "Lower bound of candidate pT"}; - Configurable d_pTCandMax{"d_pTCandMax", 50., - "Upper bound of candidate pT"}; + Configurable d_pTCandMin{"d_pTCandMin", 0., "Lower bound of candidate pT"}; + Configurable d_pTCandMax{"d_pTCandMax", 50., "Upper bound of candidate pT"}; // TPC - Configurable d_pidTPCMinpT{"d_pidTPCMinpT", 0.15, - "Lower bound of track pT for TPC PID"}; - Configurable d_pidTPCMaxpT{"d_pidTPCMaxpT", 10., - "Upper bound of track pT for TPC PID"}; + Configurable d_pidTPCMinpT{"d_pidTPCMinpT", 0.15, "Lower bound of track pT for TPC PID"}; + Configurable d_pidTPCMaxpT{"d_pidTPCMaxpT", 10., "Upper bound of track pT for TPC PID"}; Configurable d_nSigmaTPC{"d_nSigmaTPC", 3., "Nsigma cut on TPC only"}; - - Configurable d_pidTOFMinpT{"d_pidTOFMinpT", 0.15, - "Lower bound of track pT for TOF PID"}; - Configurable d_pidTOFMaxpT{"d_pidTOFMaxpT", 5., - "Upper bound of track pT for TOF PID"}; + //Configurable d_TPCNClsFindablePIDCut{"d_TPCNClsFindablePIDCut", 70., "Lower bound of TPC findable clusters for good PID"}; + // TOF + Configurable d_pidTOFMinpT{"d_pidTOFMinpT", 0.15, "Lower bound of track pT for TOF PID"}; + Configurable d_pidTOFMaxpT{"d_pidTOFMaxpT", 5., "Upper bound of track pT for TOF PID"}; Configurable d_nSigmaTOF{"d_nSigmaTOF", 3., "Nsigma cut on TOF only"}; - - Configurable d_pidRICHMinpT{"d_pidRICHMinpT", 0.15, - "Lower bound of track pT for RICH PID"}; - Configurable d_pidRICHMaxpT{"d_pidRICHMaxpT", 10., - "Upper bound of track pT for RICH PID"}; - Configurable d_nSigmaRICH{"d_nSigmaRICH", 3., - "Nsigma cut on RICH only"}; - Configurable d_nSigmaTOFCombined{ - "d_nSigmaTOFCombined", 5., "Nsigma cut on TOF combined with TPC"}; - // Configurable - // d_TPCNClsFindablePIDCut{"d_TPCNClsFindablePIDCut", 70., "Lower bound of TPC - // findable clusters for good PID"}; + // RICH + Configurable d_pidRICHMinpT{"d_pidRICHMinpT", 0.15, "Lower bound of track pT for RICH PID"}; + Configurable d_pidRICHMaxpT{"d_pidRICHMaxpT", 10., "Upper bound of track pT for RICH PID"}; + Configurable d_nSigmaRICH{"d_nSigmaRICH", 3., "Nsigma cut on RICH only"}; + Configurable d_nSigmaTOFCombined{"d_nSigmaTOFCombined", 5., "Nsigma cut on TOF combined with TPC"}; // topological cuts - Configurable> pTBins{ - "pTBins", std::vector{hf_cuts_jpsi_toee::pTBins_v}, - "pT bin limits"}; - Configurable> cuts{ - "Jpsi_to_ee_cuts", - {hf_cuts_jpsi_toee::cuts[0], npTBins, nCutVars, pTBinLabels, - cutVarLabels}, - "Jpsi candidate selection per pT bin"}; + Configurable> pTBins{"pTBins", std::vector{hf_cuts_jpsi_toee::pTBins_v}, "pT bin limits"}; + Configurable> cuts{"Jpsi_to_ee_cuts", {hf_cuts_jpsi_toee::cuts[0], npTBins, nCutVars, pTBinLabels, cutVarLabels}, "Jpsi candidate selection per pT bin"}; /// Conjugate-independent topological cuts /// \param candidate is candidate @@ -93,8 +75,7 @@ struct HFJpsiToEECandidateSelector { /// \param trackElectron is the track with the electron hypothesis /// \return true if candidate passes all cuts template - bool selectionTopol(const T1& candidate, const T2& trackPositron, - const T2& trackElectron) + bool selectionTopol(const T1& candidate, const T2& trackPositron, const T2& trackElectron) { auto candpT = candidate.pt(); auto pTBin = findBin(pTBins, candpT); @@ -108,27 +89,22 @@ struct HFJpsiToEECandidateSelector { } // cut on invariant mass - if (std::abs(InvMassJpsiToEE(candidate) - - RecoDecay::getMassPDG(pdg::Code::kJpsi)) > - cuts->get(pTBin, "m")) { + if (std::abs(InvMassJpsiToEE(candidate) - RecoDecay::getMassPDG(pdg::Code::kJpsi)) > cuts->get(pTBin, "m")) { return false; } // cut on daughter pT - if (trackElectron.pt() < cuts->get(pTBin, "pT El") || - trackPositron.pt() < cuts->get(pTBin, "pT El")) { + if (trackElectron.pt() < cuts->get(pTBin, "pT El") || trackPositron.pt() < cuts->get(pTBin, "pT El")) { return false; } // cut on daughter DCA - need to add secondary vertex constraint here - if (std::abs(trackElectron.dcaPrim0()) > cuts->get(pTBin, "DCA_xy") || - std::abs(trackPositron.dcaPrim0()) > cuts->get(pTBin, "DCA_xy")) { + if (std::abs(trackElectron.dcaPrim0()) > cuts->get(pTBin, "DCA_xy") || std::abs(trackPositron.dcaPrim0()) > cuts->get(pTBin, "DCA_xy")) { return false; } // cut on daughter DCA - need to add secondary vertex constraint here - if (std::abs(trackElectron.dcaPrim1()) > cuts->get(pTBin, "DCA_z") || - std::abs(trackPositron.dcaPrim1()) > cuts->get(pTBin, "DCA_z")) { + if (std::abs(trackElectron.dcaPrim1()) > cuts->get(pTBin, "DCA_z") || std::abs(trackPositron.dcaPrim1()) > cuts->get(pTBin, "DCA_z")) { return false; } @@ -138,6 +114,7 @@ struct HFJpsiToEECandidateSelector { } return true; } + template bool validRICHPID(const T& track) { @@ -148,14 +125,15 @@ struct HFJpsiToEECandidateSelector { } using Trks = soa::Join; - void process(aod::HfCandProng2 const& candidates, const Trks& tracks, - aod::RICHs const&) + + void process(aod::HfCandProng2 const& candidates, const Trks& tracks, aod::RICHs const&) { TrackSelectorPID selectorElectron(kElectron); + selectorElectron.setRangePtTPC(d_pidTPCMinpT, d_pidTPCMaxpT); + selectorElectron.setRangeNSigmaTPC(-d_nSigmaTPC, d_nSigmaTPC); selectorElectron.setRangePtTOF(d_pidTOFMinpT, d_pidTOFMaxpT); selectorElectron.setRangeNSigmaTOF(-d_nSigmaTOF, d_nSigmaTOF); - selectorElectron.setRangeNSigmaTOFCondTPC(-d_nSigmaTOFCombined, - d_nSigmaTOFCombined); + selectorElectron.setRangeNSigmaTOFCondTPC(-d_nSigmaTOFCombined, d_nSigmaTOFCombined); // looping over 2-prong candidates for (auto& candidate : candidates) { @@ -167,23 +145,29 @@ struct HFJpsiToEECandidateSelector { continue; } - // track selection level need to add special cuts (additional cuts on - // decay length and d0 norm) + // track selection level need to add special cuts (additional cuts on decay length and d0 norm) if (!selectionTopol(candidate, trackPos, trackNeg)) { hfSelJpsiToEECandidate(0); continue; } - // track-level PID selection - if (selectorElectron.getStatusTrackPIDTOF(trackPos) == - TrackSelectorPID::Status::PIDRejected || - selectorElectron.getStatusTrackPIDTOF(trackNeg) == - TrackSelectorPID::Status::PIDRejected) { + // track-level PID TPC selection + // FIXME: temporarily disabled for ALICE 3 development + //if (selectorElectron.getStatusTrackPIDTPC(trackPos) == TrackSelectorPID::Status::PIDRejected || + // selectorElectron.getStatusTrackPIDTPC(trackNeg) == TrackSelectorPID::Status::PIDRejected) { + // hfSelJpsiToEECandidate(0); + // continue; + //} + + // track-level PID TOF selection + if (selectorElectron.getStatusTrackPIDTOF(trackPos) == TrackSelectorPID::Status::PIDRejected || + selectorElectron.getStatusTrackPIDTOF(trackNeg) == TrackSelectorPID::Status::PIDRejected) { hfSelJpsiToEECandidate(0); continue; } + // track-level PID RICH selection bool pidrichPos = validRICHPID(trackPos); bool pidrichNeg = validRICHPID(trackNeg); if (pidrichPos && pidrichNeg) { @@ -215,6 +199,5 @@ struct HFJpsiToEECandidateSelector { WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { return WorkflowSpec{adaptAnalysisTask(cfgc), - adaptAnalysisTask( - cfgc, TaskName{"hf-jpsi-toee-candidate-selector"})}; + adaptAnalysisTask(cfgc, TaskName{"hf-jpsi-toee-candidate-selector"})}; } From 3900dc8cffccf978ea13af56397f2145a46656d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=20Ku=C4=8Dera?= Date: Fri, 4 Jun 2021 17:34:17 +0200 Subject: [PATCH 2/8] Add MID table and functions in track selector --- Analysis/ALICE3/include/ALICE3Analysis/MID.h | 43 +++++++++++++++++ .../include/AnalysisCore/TrackSelectorPID.h | 32 +++++++++++++ Analysis/Tasks/PWGHF/CMakeLists.txt | 1 - .../PWGHF/HFJpsiToEECandidateSelector.cxx | 48 +++++++++++++++---- 4 files changed, 115 insertions(+), 9 deletions(-) create mode 100644 Analysis/ALICE3/include/ALICE3Analysis/MID.h diff --git a/Analysis/ALICE3/include/ALICE3Analysis/MID.h b/Analysis/ALICE3/include/ALICE3Analysis/MID.h new file mode 100644 index 0000000000000..b6964d056467c --- /dev/null +++ b/Analysis/ALICE3/include/ALICE3Analysis/MID.h @@ -0,0 +1,43 @@ +// Copyright CERN and copyright holders of ALICE O2. This software is +// distributed under the terms of the GNU General Public License v3 (GPL +// Version 3), copied verbatim in the file "COPYING". +// +// See http://alice-o2.web.cern.ch/license for full licensing information. +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// +/// \file MID.h +/// \author Vít Kučera +/// \note Based on RICH.h +/// \brief Set of tables for the ALICE3 MID information +/// + +#ifndef O2_ANALYSIS_ALICE3_MID_H_ +#define O2_ANALYSIS_ALICE3_MID_H_ + +// O2 includes +#include "Framework/AnalysisDataModel.h" + +namespace o2::aod +{ +namespace alice3mid +{ +DECLARE_SOA_INDEX_COLUMN(Collision, collision); //! +DECLARE_SOA_INDEX_COLUMN(Track, track); //! +DECLARE_SOA_COLUMN(MIDIsMuon, midIsMuon, uint8_t); //! FIXME: To be changed to bool once bool columns are groupable. +} // namespace alice3mid + +DECLARE_SOA_TABLE(MIDs, "AOD", "MID", //! + o2::soa::Index<>, + alice3mid::CollisionId, + alice3mid::TrackId, + alice3mid::MIDIsMuon); + +using MID = MIDs::iterator; + +} // namespace o2::aod + +#endif // O2_ANALYSIS_ALICE3_MID_H_ diff --git a/Analysis/Core/include/AnalysisCore/TrackSelectorPID.h b/Analysis/Core/include/AnalysisCore/TrackSelectorPID.h index 1c9cf29269dcf..eeff0eb849dc3 100644 --- a/Analysis/Core/include/AnalysisCore/TrackSelectorPID.h +++ b/Analysis/Core/include/AnalysisCore/TrackSelectorPID.h @@ -251,6 +251,38 @@ class TrackSelectorPID } } + // MID + + /// Checks if track is compatible with muon hypothesis in the MID detector. + /// \param track track + /// \return true if track has been identified as muon by the MID detector + template + bool isSelectedTrackPIDMID(const T& track) + { + if (mPdg != kMuonMinus) { + return false; + } + return track.mid().midIsMuon() == 1; // FIXME: change to return track.midIsMuon() once the column is bool. + } + + /// Returns status of MID PID selection for a given track. + /// \param track track + /// \return MID selection status (see TrackSelectorPID::Status) + template + int getStatusTrackPIDMID(const T& track) + { + if (mPdg != kMuonMinus) { + return Status::PIDRejected; + } + if (isSelectedTrackPIDMID(track)) { + return Status::PIDAccepted; // accepted + } else { + return Status::PIDRejected; // rejected + } + } + + // Combined selection + /// Returns status of combined PID selection for a given track. /// \param track track /// \return combined-selection status (see TrackSelectorPID::Status) diff --git a/Analysis/Tasks/PWGHF/CMakeLists.txt b/Analysis/Tasks/PWGHF/CMakeLists.txt index dced3cc182a51..6d97dbd3a1e5b 100644 --- a/Analysis/Tasks/PWGHF/CMakeLists.txt +++ b/Analysis/Tasks/PWGHF/CMakeLists.txt @@ -132,4 +132,3 @@ o2_add_dpl_workflow(hf-task-lc-tok0sp SOURCES taskLcK0sP.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2::AnalysisDataModel O2::AnalysisCore O2::DetectorsVertexing O2::AnalysisTasksUtils COMPONENT_NAME Analysis) - diff --git a/Analysis/Tasks/PWGHF/HFJpsiToEECandidateSelector.cxx b/Analysis/Tasks/PWGHF/HFJpsiToEECandidateSelector.cxx index 6624ccab5b9b7..5ff4fa9fc0b26 100644 --- a/Analysis/Tasks/PWGHF/HFJpsiToEECandidateSelector.cxx +++ b/Analysis/Tasks/PWGHF/HFJpsiToEECandidateSelector.cxx @@ -21,6 +21,7 @@ #include "AnalysisDataModel/HFCandidateSelectionTables.h" #include "AnalysisCore/TrackSelectorPID.h" #include "ALICE3Analysis/RICH.h" +#include "ALICE3Analysis/MID.h" using namespace o2; using namespace o2::framework; @@ -30,14 +31,14 @@ using namespace o2::analysis::hf_cuts_jpsi_toee; namespace o2::aod { -namespace indices +namespace indices_rich { DECLARE_SOA_INDEX_COLUMN(Track, track); DECLARE_SOA_INDEX_COLUMN(RICH, rich); -} // namespace indices +} // namespace indices_rich DECLARE_SOA_INDEX_TABLE_USER(RICHTracksIndex, Tracks, "RICHTRK", - indices::TrackId, indices::RICHId); + indices_rich::TrackId, indices_rich::RICHId); } // namespace o2::aod struct RICHindexbuilder { @@ -45,6 +46,24 @@ struct RICHindexbuilder { void init(o2::framework::InitContext&) {} }; +namespace o2::aod +{ + +namespace indices_mid +{ +DECLARE_SOA_INDEX_COLUMN(Track, track); +DECLARE_SOA_INDEX_COLUMN(MID, mid); +} // namespace indices_mid + +DECLARE_SOA_INDEX_TABLE_USER(MIDTracksIndex, Tracks, "MIDTRK", + indices_mid::TrackId, indices_mid::MIDId); +} // namespace o2::aod + +struct MidIndexBuilder { + Builds ind; + void init(o2::framework::InitContext&) {} +}; + /// Struct for applying J/ψ → e+ e− selection cuts struct HFJpsiToEECandidateSelector { Produces hfSelJpsiToEECandidate; @@ -65,6 +84,7 @@ struct HFJpsiToEECandidateSelector { Configurable d_pidRICHMaxpT{"d_pidRICHMaxpT", 10., "Upper bound of track pT for RICH PID"}; Configurable d_nSigmaRICH{"d_nSigmaRICH", 3., "Nsigma cut on RICH only"}; Configurable d_nSigmaTOFCombined{"d_nSigmaTOFCombined", 5., "Nsigma cut on TOF combined with TPC"}; + // topological cuts Configurable> pTBins{"pTBins", std::vector{hf_cuts_jpsi_toee::pTBins_v}, "pT bin limits"}; Configurable> cuts{"Jpsi_to_ee_cuts", {hf_cuts_jpsi_toee::cuts[0], npTBins, nCutVars, pTBinLabels, cutVarLabels}, "Jpsi candidate selection per pT bin"}; @@ -109,7 +129,7 @@ struct HFJpsiToEECandidateSelector { } // cut on chi2 point of closest approach - if (std::abs(candidate.chi2PCA()) > cuts->get(pTBin, "chi2PCA")){ + if (std::abs(candidate.chi2PCA()) > cuts->get(pTBin, "chi2PCA")) { return false; } return true; @@ -124,9 +144,9 @@ struct HFJpsiToEECandidateSelector { return true; } - using Trks = soa::Join; + using Trks = soa::Join; - void process(aod::HfCandProng2 const& candidates, const Trks& tracks, aod::RICHs const&) + void process(aod::HfCandProng2 const& candidates, Trks const&, aod::RICHs const&, aod::MIDs const&) { TrackSelectorPID selectorElectron(kElectron); selectorElectron.setRangePtTPC(d_pidTPCMinpT, d_pidTPCMaxpT); @@ -134,6 +154,9 @@ struct HFJpsiToEECandidateSelector { selectorElectron.setRangePtTOF(d_pidTOFMinpT, d_pidTOFMaxpT); selectorElectron.setRangeNSigmaTOF(-d_nSigmaTOF, d_nSigmaTOF); selectorElectron.setRangeNSigmaTOFCondTPC(-d_nSigmaTOFCombined, d_nSigmaTOFCombined); + + TrackSelectorPID selectorMuon(kMuonMinus); + // looping over 2-prong candidates for (auto& candidate : candidates) { @@ -191,6 +214,13 @@ struct HFJpsiToEECandidateSelector { } } + // track-level muon PID selection + if (selectorMuon.getStatusTrackPIDMID(trackPos) == TrackSelectorPID::Status::PIDRejected || + selectorMuon.getStatusTrackPIDMID(trackNeg) == TrackSelectorPID::Status::PIDRejected) { + hfSelJpsiToEECandidate(0); + continue; + } + hfSelJpsiToEECandidate(1); } } @@ -198,6 +228,8 @@ struct HFJpsiToEECandidateSelector { WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { - return WorkflowSpec{adaptAnalysisTask(cfgc), - adaptAnalysisTask(cfgc, TaskName{"hf-jpsi-toee-candidate-selector"})}; + return WorkflowSpec{ + adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc, TaskName{"hf-jpsi-toee-candidate-selector"})}; } From 24028489b8f30b910751ae12cc33bf92ed8cabbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=20Ku=C4=8Dera?= Date: Sat, 5 Jun 2021 18:50:15 +0200 Subject: [PATCH 3/8] Add RICH in TrackSelectorPID --- .../include/AnalysisCore/TrackSelectorPID.h | 116 +++++++++++++++++- .../PWGHF/HFJpsiToEECandidateSelector.cxx | 40 ++---- 2 files changed, 121 insertions(+), 35 deletions(-) diff --git a/Analysis/Core/include/AnalysisCore/TrackSelectorPID.h b/Analysis/Core/include/AnalysisCore/TrackSelectorPID.h index eeff0eb849dc3..762f5594b7073 100644 --- a/Analysis/Core/include/AnalysisCore/TrackSelectorPID.h +++ b/Analysis/Core/include/AnalysisCore/TrackSelectorPID.h @@ -251,6 +251,108 @@ class TrackSelectorPID } } + // RICH + + /// Set pT range where RICH PID is applicable. + void setRangePtRICH(float ptMin, float ptMax) + { + mPtRICHMin = ptMin; + mPtRICHMax = ptMax; + } + + /// Set RICH nσ range in which a track should be accepted. + void setRangeNSigmaRICH(float nsMin, float nsMax) + { + mNSigmaRICHMin = nsMin; + mNSigmaRICHMax = nsMax; + } + + /// Set RICH nσ range in which a track should be conditionally accepted if combined with TOF. + void setRangeNSigmaRICHCondTOF(float nsMin, float nsMax) + { + mNSigmaRICHMinCondTOF = nsMin; + mNSigmaRICHMaxCondTOF = nsMax; + } + + /// Checks if track is OK for RICH PID. + /// \param track track + /// \return true if track is OK for RICH PID + template + bool isValidTrackPIDRICH(const T& track) + { + auto pt = track.pt(); + return mPtRICHMin <= pt && pt <= mPtRICHMax; + } + + /// Checks if track is compatible with given particle species hypothesis within given RICH nσ range. + /// \param track track + /// \param conditionalTOF variable to store the result of selection with looser cuts for conditional accepting of track if combined with TOF + /// \return true if track satisfies RICH PID hypothesis for given RICH nσ range + template + bool isSelectedTrackPIDRICH(const T& track, bool& conditionalTOF) + { + // Accept if selection is disabled via large values. + if (mNSigmaRICHMin < -999. && mNSigmaRICHMax > 999.) { + return true; + } + + // Get nσ for a given particle hypothesis. + double nSigma = 100.; + switch (mPdg) { + case kElectron: { + nSigma = track.rich().richNsigmaEl(); + break; + } + case kMuonMinus: { + nSigma = track.rich().richNsigmaMu(); + break; + } + case kPiPlus: { + nSigma = track.rich().richNsigmaPi(); + break; + } + case kKPlus: { + nSigma = track.rich().richNsigmaKa(); + break; + } + case kProton: { + nSigma = track.rich().richNsigmaPr(); + break; + } + default: { + LOGF(error, "ERROR: RICH PID not implemented for PDG %d", mPdg); + assert(false); + } + } + + if (mNSigmaRICHMinCondTOF < -999. && mNSigmaRICHMaxCondTOF > 999.) { + conditionalTOF = true; + } else { + conditionalTOF = mNSigmaRICHMinCondTOF <= nSigma && nSigma <= mNSigmaRICHMaxCondTOF; + } + return mNSigmaRICHMin <= nSigma && nSigma <= mNSigmaRICHMax; + } + + /// Returns status of RICH PID selection for a given track. + /// \param track track + /// \return RICH selection status (see TrackSelectorPID::Status) + template + int getStatusTrackPIDRICH(const T& track) + { + if (isValidTrackPIDRICH(track)) { + bool condTOF = false; + if (isSelectedTrackPIDRICH(track, condTOF)) { + return Status::PIDAccepted; // accepted + } else if (condTOF) { + return Status::PIDConditional; // potential to be accepted if combined with TOF + } else { + return Status::PIDRejected; // rejected + } + } else { + return Status::PIDNotApplicable; // PID not applicable + } + } + // MID /// Checks if track is compatible with muon hypothesis in the MID detector. @@ -281,11 +383,11 @@ class TrackSelectorPID } } - // Combined selection + // Combined selection (TPC + TOF) - /// Returns status of combined PID selection for a given track. + /// Returns status of combined PID (TPC + TOF) selection for a given track. /// \param track track - /// \return combined-selection status (see TrackSelectorPID::Status) + /// \return status of combined PID (TPC + TOF) (see TrackSelectorPID::Status) template int getStatusTrackPIDAll(const T& track) { @@ -322,6 +424,14 @@ class TrackSelectorPID float mNSigmaTOFMax = 3.; ///< maximum number of TOF σ float mNSigmaTOFMinCondTPC = -1000.; ///< minimum number of TOF σ if combined with TPC float mNSigmaTOFMaxCondTPC = 1000.; ///< maximum number of TOF σ if combined with TPC + + // RICH + float mPtRICHMin = 0.; ///< minimum pT for RICH PID [GeV/c] + float mPtRICHMax = 100.; ///< maximum pT for RICH PID [GeV/c] + float mNSigmaRICHMin = -3.; ///< minimum number of RICH σ + float mNSigmaRICHMax = 3.; ///< maximum number of RICH σ + float mNSigmaRICHMinCondTOF = -1000.; ///< minimum number of RICH σ if combined with TOF + float mNSigmaRICHMaxCondTOF = 1000.; ///< maximum number of RICH σ if combined with TOF }; #endif // O2_ANALYSIS_TRACKSELECTORPID_H_ diff --git a/Analysis/Tasks/PWGHF/HFJpsiToEECandidateSelector.cxx b/Analysis/Tasks/PWGHF/HFJpsiToEECandidateSelector.cxx index 5ff4fa9fc0b26..672bff89c2810 100644 --- a/Analysis/Tasks/PWGHF/HFJpsiToEECandidateSelector.cxx +++ b/Analysis/Tasks/PWGHF/HFJpsiToEECandidateSelector.cxx @@ -79,11 +79,11 @@ struct HFJpsiToEECandidateSelector { Configurable d_pidTOFMinpT{"d_pidTOFMinpT", 0.15, "Lower bound of track pT for TOF PID"}; Configurable d_pidTOFMaxpT{"d_pidTOFMaxpT", 5., "Upper bound of track pT for TOF PID"}; Configurable d_nSigmaTOF{"d_nSigmaTOF", 3., "Nsigma cut on TOF only"}; + Configurable d_nSigmaTOFCombined{"d_nSigmaTOFCombined", 5., "Nsigma cut on TOF combined with TPC"}; // RICH Configurable d_pidRICHMinpT{"d_pidRICHMinpT", 0.15, "Lower bound of track pT for RICH PID"}; Configurable d_pidRICHMaxpT{"d_pidRICHMaxpT", 10., "Upper bound of track pT for RICH PID"}; Configurable d_nSigmaRICH{"d_nSigmaRICH", 3., "Nsigma cut on RICH only"}; - Configurable d_nSigmaTOFCombined{"d_nSigmaTOFCombined", 5., "Nsigma cut on TOF combined with TPC"}; // topological cuts Configurable> pTBins{"pTBins", std::vector{hf_cuts_jpsi_toee::pTBins_v}, "pT bin limits"}; @@ -135,15 +135,6 @@ struct HFJpsiToEECandidateSelector { return true; } - template - bool validRICHPID(const T& track) - { - if (track.pt() < d_pidRICHMinpT || track.pt() >= d_pidRICHMaxpT) { - return false; - } - return true; - } - using Trks = soa::Join; void process(aod::HfCandProng2 const& candidates, Trks const&, aod::RICHs const&, aod::MIDs const&) @@ -154,6 +145,8 @@ struct HFJpsiToEECandidateSelector { selectorElectron.setRangePtTOF(d_pidTOFMinpT, d_pidTOFMaxpT); selectorElectron.setRangeNSigmaTOF(-d_nSigmaTOF, d_nSigmaTOF); selectorElectron.setRangeNSigmaTOFCondTPC(-d_nSigmaTOFCombined, d_nSigmaTOFCombined); + selectorElectron.setRangePtRICH(d_pidRICHMinpT, d_pidRICHMaxpT); + selectorElectron.setRangeNSigmaRICH(-d_nSigmaRICH, d_nSigmaRICH); TrackSelectorPID selectorMuon(kMuonMinus); @@ -191,30 +184,13 @@ struct HFJpsiToEECandidateSelector { } // track-level PID RICH selection - bool pidrichPos = validRICHPID(trackPos); - bool pidrichNeg = validRICHPID(trackNeg); - if (pidrichPos && pidrichNeg) { - // LOGF(info, "both good rich tracks"); - } - - // LOGF(info, "cut %f, val pos %f, val neg %f", d_nSigmaRICH, - // trackPos.rich().richNsigmaEl(), trackNeg.rich().richNsigmaEl()); - if (pidrichPos && pidrichNeg) { - bool selpidrichPos = abs(trackPos.rich().richNsigmaEl()) < d_nSigmaRICH; - bool selpidrichNeg = abs(trackNeg.rich().richNsigmaEl()) < d_nSigmaRICH; - // LOGF(info, "pos %d, neg %d", selpidrichPos, selpidrichNeg); - bool selpidrich = selpidrichPos && selpidrichNeg; - if (selpidrich) { - // LOGF(info, "both sel rich tracks"); - } - if (!selpidrich) { - hfSelJpsiToEECandidate(0); - // LOGF(info, "not selectedtracks"); - continue; - } + if (selectorElectron.getStatusTrackPIDRICH(trackPos) != TrackSelectorPID::Status::PIDAccepted || + selectorElectron.getStatusTrackPIDRICH(trackNeg) != TrackSelectorPID::Status::PIDAccepted) { + hfSelJpsiToEECandidate(0); + continue; } - // track-level muon PID selection + // track-level muon PID MID selection if (selectorMuon.getStatusTrackPIDMID(trackPos) == TrackSelectorPID::Status::PIDRejected || selectorMuon.getStatusTrackPIDMID(trackNeg) == TrackSelectorPID::Status::PIDRejected) { hfSelJpsiToEECandidate(0); From 40cb39e737047baba97ba2ea7c2e14fd10d40c67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=20Ku=C4=8Dera?= Date: Sun, 6 Jun 2021 17:53:35 +0200 Subject: [PATCH 4/8] Add debugging messages --- .../include/AnalysisCore/TrackSelectorPID.h | 8 ++++++++ .../Tasks/PWGHF/HFJpsiToEECandidateSelector.cxx | 17 ++++++++++------- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/Analysis/Core/include/AnalysisCore/TrackSelectorPID.h b/Analysis/Core/include/AnalysisCore/TrackSelectorPID.h index 762f5594b7073..6a49faba59d11 100644 --- a/Analysis/Core/include/AnalysisCore/TrackSelectorPID.h +++ b/Analysis/Core/include/AnalysisCore/TrackSelectorPID.h @@ -362,8 +362,12 @@ class TrackSelectorPID bool isSelectedTrackPIDMID(const T& track) { if (mPdg != kMuonMinus) { + LOGF(info, "isSelectedTrackPIDMID: Not a muon hypothesis"); return false; } + LOGF(info, "isSelectedTrackPIDMID: Getting muon response"); + LOGF(info, "isSelectedTrackPIDMID: Got: %d", track.mid().midIsMuon()); + LOGF(info, "isSelectedTrackPIDMID: Return: %d", track.mid().midIsMuon() == 1); return track.mid().midIsMuon() == 1; // FIXME: change to return track.midIsMuon() once the column is bool. } @@ -373,12 +377,16 @@ class TrackSelectorPID template int getStatusTrackPIDMID(const T& track) { + LOGF(info, "getStatusTrackPIDMID: Start"); if (mPdg != kMuonMinus) { + LOGF(info, "getStatusTrackPIDMID: Not a muon hypothesis"); return Status::PIDRejected; } if (isSelectedTrackPIDMID(track)) { + LOGF(info, "getStatusTrackPIDMID: Accepted"); return Status::PIDAccepted; // accepted } else { + LOGF(info, "getStatusTrackPIDMID: Rejected"); return Status::PIDRejected; // rejected } } diff --git a/Analysis/Tasks/PWGHF/HFJpsiToEECandidateSelector.cxx b/Analysis/Tasks/PWGHF/HFJpsiToEECandidateSelector.cxx index 672bff89c2810..62f08ce550455 100644 --- a/Analysis/Tasks/PWGHF/HFJpsiToEECandidateSelector.cxx +++ b/Analysis/Tasks/PWGHF/HFJpsiToEECandidateSelector.cxx @@ -161,6 +161,16 @@ struct HFJpsiToEECandidateSelector { continue; } + LOGF(info, "Muon selection: Start"); + // track-level muon PID MID selection + if (selectorMuon.getStatusTrackPIDMID(trackPos) == TrackSelectorPID::Status::PIDRejected || + selectorMuon.getStatusTrackPIDMID(trackNeg) == TrackSelectorPID::Status::PIDRejected) { + LOGF(info, "Muon selection: Rejected"); + hfSelJpsiToEECandidate(0); + continue; + } + LOGF(info, "Muon selection: Selected"); + // track selection level need to add special cuts (additional cuts on decay length and d0 norm) if (!selectionTopol(candidate, trackPos, trackNeg)) { @@ -190,13 +200,6 @@ struct HFJpsiToEECandidateSelector { continue; } - // track-level muon PID MID selection - if (selectorMuon.getStatusTrackPIDMID(trackPos) == TrackSelectorPID::Status::PIDRejected || - selectorMuon.getStatusTrackPIDMID(trackNeg) == TrackSelectorPID::Status::PIDRejected) { - hfSelJpsiToEECandidate(0); - continue; - } - hfSelJpsiToEECandidate(1); } } From c5435f37f1a57788ccf76c85c05e130e1bb92d9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=20Ku=C4=8Dera?= Date: Sun, 6 Jun 2021 19:07:56 +0200 Subject: [PATCH 5/8] Define a single table for ALICE 3 PID track indices --- .../PWGHF/HFJpsiToEECandidateSelector.cxx | 38 ++++++++++++++++--- 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/Analysis/Tasks/PWGHF/HFJpsiToEECandidateSelector.cxx b/Analysis/Tasks/PWGHF/HFJpsiToEECandidateSelector.cxx index 62f08ce550455..71ebf528d6600 100644 --- a/Analysis/Tasks/PWGHF/HFJpsiToEECandidateSelector.cxx +++ b/Analysis/Tasks/PWGHF/HFJpsiToEECandidateSelector.cxx @@ -28,6 +28,7 @@ using namespace o2::framework; using namespace o2::aod::hf_cand_prong2; using namespace o2::analysis::hf_cuts_jpsi_toee; +/* namespace o2::aod { @@ -63,6 +64,28 @@ struct MidIndexBuilder { Builds ind; void init(o2::framework::InitContext&) {} }; +*/ + +namespace o2::aod +{ + +namespace hf_track_index_alice3_pid +{ +DECLARE_SOA_INDEX_COLUMN(Track, track); //! +DECLARE_SOA_INDEX_COLUMN(RICH, rich); //! +DECLARE_SOA_INDEX_COLUMN(MID, mid); //! +} // namespace hf_track_index_alice3_pid + +DECLARE_SOA_INDEX_TABLE_USER(HfTrackIndexALICE3PID, Tracks, "HFTRKIDXA3PID", //! + hf_track_index_alice3_pid::TrackId, + hf_track_index_alice3_pid::RICHId, + hf_track_index_alice3_pid::MIDId); +} // namespace o2::aod + +struct Alice3PidIndexBuilder { + Builds index; + void init(o2::framework::InitContext&) {} +}; /// Struct for applying J/ψ → e+ e− selection cuts struct HFJpsiToEECandidateSelector { @@ -135,9 +158,9 @@ struct HFJpsiToEECandidateSelector { return true; } - using Trks = soa::Join; + using TracksPID = soa::Join; - void process(aod::HfCandProng2 const& candidates, Trks const&, aod::RICHs const&, aod::MIDs const&) + void process(aod::HfCandProng2 const& candidates, TracksPID const&, aod::RICHs const&, aod::MIDs const&) { TrackSelectorPID selectorElectron(kElectron); selectorElectron.setRangePtTPC(d_pidTPCMinpT, d_pidTPCMaxpT); @@ -153,14 +176,15 @@ struct HFJpsiToEECandidateSelector { // looping over 2-prong candidates for (auto& candidate : candidates) { - auto trackPos = candidate.index0_as(); // positive daughter - auto trackNeg = candidate.index1_as(); // negative daughter + auto trackPos = candidate.index0_as(); // positive daughter + auto trackNeg = candidate.index1_as(); // negative daughter if (!(candidate.hfflag() & 1 << DecayType::JpsiToEE)) { hfSelJpsiToEECandidate(0); continue; } + /* LOGF(info, "Muon selection: Start"); // track-level muon PID MID selection if (selectorMuon.getStatusTrackPIDMID(trackPos) == TrackSelectorPID::Status::PIDRejected || @@ -170,6 +194,7 @@ struct HFJpsiToEECandidateSelector { continue; } LOGF(info, "Muon selection: Selected"); + */ // track selection level need to add special cuts (additional cuts on decay length and d0 norm) @@ -208,7 +233,8 @@ struct HFJpsiToEECandidateSelector { WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { return WorkflowSpec{ - adaptAnalysisTask(cfgc), - adaptAnalysisTask(cfgc), + //adaptAnalysisTask(cfgc), + //adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc), adaptAnalysisTask(cfgc, TaskName{"hf-jpsi-toee-candidate-selector"})}; } From 3adb861816975a7ad299683917200b4855392fda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=20Ku=C4=8Dera?= Date: Sun, 6 Jun 2021 19:11:15 +0200 Subject: [PATCH 6/8] Mute debugging messages --- .../include/AnalysisCore/TrackSelectorPID.h | 16 +++++++------- .../PWGHF/HFJpsiToEECandidateSelector.cxx | 22 +++++++++---------- 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/Analysis/Core/include/AnalysisCore/TrackSelectorPID.h b/Analysis/Core/include/AnalysisCore/TrackSelectorPID.h index 6a49faba59d11..f2c958b5143fb 100644 --- a/Analysis/Core/include/AnalysisCore/TrackSelectorPID.h +++ b/Analysis/Core/include/AnalysisCore/TrackSelectorPID.h @@ -362,12 +362,12 @@ class TrackSelectorPID bool isSelectedTrackPIDMID(const T& track) { if (mPdg != kMuonMinus) { - LOGF(info, "isSelectedTrackPIDMID: Not a muon hypothesis"); + //LOGF(info, "isSelectedTrackPIDMID: Not a muon hypothesis"); return false; } - LOGF(info, "isSelectedTrackPIDMID: Getting muon response"); - LOGF(info, "isSelectedTrackPIDMID: Got: %d", track.mid().midIsMuon()); - LOGF(info, "isSelectedTrackPIDMID: Return: %d", track.mid().midIsMuon() == 1); + //LOGF(info, "isSelectedTrackPIDMID: Getting muon response"); + //LOGF(info, "isSelectedTrackPIDMID: Got: %d", track.mid().midIsMuon()); + //LOGF(info, "isSelectedTrackPIDMID: Return: %d", track.mid().midIsMuon() == 1); return track.mid().midIsMuon() == 1; // FIXME: change to return track.midIsMuon() once the column is bool. } @@ -377,16 +377,16 @@ class TrackSelectorPID template int getStatusTrackPIDMID(const T& track) { - LOGF(info, "getStatusTrackPIDMID: Start"); + //LOGF(info, "getStatusTrackPIDMID: Start"); if (mPdg != kMuonMinus) { - LOGF(info, "getStatusTrackPIDMID: Not a muon hypothesis"); + //LOGF(info, "getStatusTrackPIDMID: Not a muon hypothesis"); return Status::PIDRejected; } if (isSelectedTrackPIDMID(track)) { - LOGF(info, "getStatusTrackPIDMID: Accepted"); + //LOGF(info, "getStatusTrackPIDMID: Accepted"); return Status::PIDAccepted; // accepted } else { - LOGF(info, "getStatusTrackPIDMID: Rejected"); + //LOGF(info, "getStatusTrackPIDMID: Rejected"); return Status::PIDRejected; // rejected } } diff --git a/Analysis/Tasks/PWGHF/HFJpsiToEECandidateSelector.cxx b/Analysis/Tasks/PWGHF/HFJpsiToEECandidateSelector.cxx index 71ebf528d6600..cd6db64a5047f 100644 --- a/Analysis/Tasks/PWGHF/HFJpsiToEECandidateSelector.cxx +++ b/Analysis/Tasks/PWGHF/HFJpsiToEECandidateSelector.cxx @@ -184,18 +184,6 @@ struct HFJpsiToEECandidateSelector { continue; } - /* - LOGF(info, "Muon selection: Start"); - // track-level muon PID MID selection - if (selectorMuon.getStatusTrackPIDMID(trackPos) == TrackSelectorPID::Status::PIDRejected || - selectorMuon.getStatusTrackPIDMID(trackNeg) == TrackSelectorPID::Status::PIDRejected) { - LOGF(info, "Muon selection: Rejected"); - hfSelJpsiToEECandidate(0); - continue; - } - LOGF(info, "Muon selection: Selected"); - */ - // track selection level need to add special cuts (additional cuts on decay length and d0 norm) if (!selectionTopol(candidate, trackPos, trackNeg)) { @@ -225,6 +213,16 @@ struct HFJpsiToEECandidateSelector { continue; } + // track-level muon PID MID selection + //LOGF(info, "Muon selection: Start"); + if (selectorMuon.getStatusTrackPIDMID(trackPos) == TrackSelectorPID::Status::PIDRejected || + selectorMuon.getStatusTrackPIDMID(trackNeg) == TrackSelectorPID::Status::PIDRejected) { + //LOGF(info, "Muon selection: Rejected"); + hfSelJpsiToEECandidate(0); + continue; + } + //LOGF(info, "Muon selection: Selected"); + hfSelJpsiToEECandidate(1); } } From 9b8a3a8b70e9b6afce7590ebbc32a6d4790c570d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=20Ku=C4=8Dera?= Date: Sun, 6 Jun 2021 19:14:01 +0200 Subject: [PATCH 7/8] Accept only both accepted tracks for MID --- Analysis/Tasks/PWGHF/HFJpsiToEECandidateSelector.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Analysis/Tasks/PWGHF/HFJpsiToEECandidateSelector.cxx b/Analysis/Tasks/PWGHF/HFJpsiToEECandidateSelector.cxx index cd6db64a5047f..e72df773d0713 100644 --- a/Analysis/Tasks/PWGHF/HFJpsiToEECandidateSelector.cxx +++ b/Analysis/Tasks/PWGHF/HFJpsiToEECandidateSelector.cxx @@ -215,8 +215,8 @@ struct HFJpsiToEECandidateSelector { // track-level muon PID MID selection //LOGF(info, "Muon selection: Start"); - if (selectorMuon.getStatusTrackPIDMID(trackPos) == TrackSelectorPID::Status::PIDRejected || - selectorMuon.getStatusTrackPIDMID(trackNeg) == TrackSelectorPID::Status::PIDRejected) { + if (selectorMuon.getStatusTrackPIDMID(trackPos) != TrackSelectorPID::Status::PIDAccepted || + selectorMuon.getStatusTrackPIDMID(trackNeg) != TrackSelectorPID::Status::PIDAccepted) { //LOGF(info, "Muon selection: Rejected"); hfSelJpsiToEECandidate(0); continue; From 5a0fd604d9db0f4cac2491cdd3ec0948426af688 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=20Ku=C4=8Dera?= Date: Sun, 6 Jun 2021 19:17:22 +0200 Subject: [PATCH 8/8] Apply clang-format --- Analysis/Tasks/PWGHF/HFJpsiToEECandidateSelector.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Analysis/Tasks/PWGHF/HFJpsiToEECandidateSelector.cxx b/Analysis/Tasks/PWGHF/HFJpsiToEECandidateSelector.cxx index e72df773d0713..5d99fa6c1b9bc 100644 --- a/Analysis/Tasks/PWGHF/HFJpsiToEECandidateSelector.cxx +++ b/Analysis/Tasks/PWGHF/HFJpsiToEECandidateSelector.cxx @@ -72,8 +72,8 @@ namespace o2::aod namespace hf_track_index_alice3_pid { DECLARE_SOA_INDEX_COLUMN(Track, track); //! -DECLARE_SOA_INDEX_COLUMN(RICH, rich); //! -DECLARE_SOA_INDEX_COLUMN(MID, mid); //! +DECLARE_SOA_INDEX_COLUMN(RICH, rich); //! +DECLARE_SOA_INDEX_COLUMN(MID, mid); //! } // namespace hf_track_index_alice3_pid DECLARE_SOA_INDEX_TABLE_USER(HfTrackIndexALICE3PID, Tracks, "HFTRKIDXA3PID", //!