diff --git a/Analysis/DataModel/include/AnalysisDataModel/HFCandidateSelectionTables.h b/Analysis/DataModel/include/AnalysisDataModel/HFCandidateSelectionTables.h index cd45f99573411..6780e2c324968 100644 --- a/Analysis/DataModel/include/AnalysisDataModel/HFCandidateSelectionTables.h +++ b/Analysis/DataModel/include/AnalysisDataModel/HFCandidateSelectionTables.h @@ -39,9 +39,11 @@ DECLARE_SOA_TABLE(HFSelLcCandidate, "AOD", "HFSELLCCAND", //! namespace hf_selcandidate_jpsi { DECLARE_SOA_COLUMN(IsSelJpsiToEE, isSelJpsiToEE, int); //! +DECLARE_SOA_COLUMN(IsSelJpsiToMuMu, isSelJpsiToMuMu, int); //! } // namespace hf_selcandidate_jpsi -DECLARE_SOA_TABLE(HFSelJpsiToEECandidate, "AOD", "HFSELJPSICAND", //! - hf_selcandidate_jpsi::IsSelJpsiToEE); +DECLARE_SOA_TABLE(HFSelJpsiCandidate, "AOD", "HFSELJPSICAND", //! + hf_selcandidate_jpsi::IsSelJpsiToEE, + hf_selcandidate_jpsi::IsSelJpsiToMuMu); namespace hf_selcandidate_lc_k0sp { diff --git a/Analysis/DataModel/include/AnalysisDataModel/HFSecondaryVertex.h b/Analysis/DataModel/include/AnalysisDataModel/HFSecondaryVertex.h index c6814461b288a..1db71decd538b 100644 --- a/Analysis/DataModel/include/AnalysisDataModel/HFSecondaryVertex.h +++ b/Analysis/DataModel/include/AnalysisDataModel/HFSecondaryVertex.h @@ -297,7 +297,7 @@ auto InvMassJpsiToEE(const T& candidate) return candidate.m(array{RecoDecay::getMassPDG(kElectron), RecoDecay::getMassPDG(kElectron)}); } -// J/ψ → µ+ µ− +// J/ψ → μ+ μ− template auto InvMassJpsiToMuMu(const T& candidate) diff --git a/Analysis/Tasks/PWGHF/CMakeLists.txt b/Analysis/Tasks/PWGHF/CMakeLists.txt index 6d97dbd3a1e5b..4786abcd788d1 100644 --- a/Analysis/Tasks/PWGHF/CMakeLists.txt +++ b/Analysis/Tasks/PWGHF/CMakeLists.txt @@ -68,8 +68,8 @@ o2_add_dpl_workflow(hf-lc-candidate-selector PUBLIC_LINK_LIBRARIES O2::Framework O2::AnalysisDataModel O2::AnalysisCore O2::DetectorsVertexing COMPONENT_NAME Analysis) -o2_add_dpl_workflow(hf-jpsi-toee-candidate-selector - SOURCES HFJpsiToEECandidateSelector.cxx +o2_add_dpl_workflow(hf-jpsi-candidate-selector + SOURCES HFJpsiCandidateSelector.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2::AnalysisDataModel O2::AnalysisCore O2::DetectorsVertexing O2::ALICE3Analysis COMPONENT_NAME Analysis) diff --git a/Analysis/Tasks/PWGHF/HFCandidateCreatorX.cxx b/Analysis/Tasks/PWGHF/HFCandidateCreatorX.cxx index 77f54977d0b92..f257cdbba0329 100644 --- a/Analysis/Tasks/PWGHF/HFCandidateCreatorX.cxx +++ b/Analysis/Tasks/PWGHF/HFCandidateCreatorX.cxx @@ -68,7 +68,7 @@ struct HFCandidateCreatorX { void process(aod::Collision const& collision, soa::Filtered> const& jpsiCands, + aod::HFSelJpsiCandidate>> const& jpsiCands, aod::BigTracks const& tracks) { // 2-prong vertex fitter (to rebuild Jpsi vertex) diff --git a/Analysis/Tasks/PWGHF/HFJpsiToEECandidateSelector.cxx b/Analysis/Tasks/PWGHF/HFJpsiCandidateSelector.cxx similarity index 70% rename from Analysis/Tasks/PWGHF/HFJpsiToEECandidateSelector.cxx rename to Analysis/Tasks/PWGHF/HFJpsiCandidateSelector.cxx index 0f6eb8e393dbe..054be874f1a4c 100644 --- a/Analysis/Tasks/PWGHF/HFJpsiToEECandidateSelector.cxx +++ b/Analysis/Tasks/PWGHF/HFJpsiCandidateSelector.cxx @@ -8,7 +8,7 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -/// \file HFJpsiToEECandidateSelector.cxx +/// \file HFJpsiCandidateSelector.cxx /// \brief J/ψ → e+ e− selection task /// /// \author Biao Zhang , CCNU @@ -88,16 +88,16 @@ struct Alice3PidIndexBuilder { }; /// Struct for applying J/ψ → e+ e− selection cuts -struct HFJpsiToEECandidateSelector { - Produces hfSelJpsiToEECandidate; +struct HFJpsiCandidateSelector { + Produces hfSelJpsiCandidate; + Configurable isALICE3{"isALICE3", false, "Switch between ALICE 2 and ALICE 3 detector setup"}; 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_nSigmaTPC{"d_nSigmaTPC", 3., "Nsigma cut on TPC only"}; - //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"}; @@ -107,18 +107,17 @@ struct HFJpsiToEECandidateSelector { 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"}; - // 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"}; /// Conjugate-independent topological cuts /// \param candidate is candidate - /// \param trackPositron is the track with the positron hypothesis - /// \param trackElectron is the track with the electron hypothesis + /// \param trackPos is the positive track + /// \param trackNeg is the negative track /// \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& trackPos, const T2& trackNeg, int& selEE, int& selMuMu) { auto candpT = candidate.pt(); auto pTBin = findBin(pTBins, candpT); @@ -131,23 +130,32 @@ struct HFJpsiToEECandidateSelector { return false; } - // cut on invariant mass + // cut on e+ e− invariant mass if (std::abs(InvMassJpsiToEE(candidate) - RecoDecay::getMassPDG(pdg::Code::kJpsi)) > cuts->get(pTBin, "m")) { + selEE = 0; + } + + // cut on μ+ μ− invariant mass + if (std::abs(InvMassJpsiToMuMu(candidate) - RecoDecay::getMassPDG(pdg::Code::kJpsi)) > cuts->get(pTBin, "m")) { + selMuMu = 0; + } + + if (selEE == 0 && selMuMu == 0) { return false; } - // cut on daughter pT - if (trackElectron.pt() < cuts->get(pTBin, "pT El") || trackPositron.pt() < cuts->get(pTBin, "pT El")) { + // cut on daughter pT (same cut used for both channels) + if (trackNeg.pt() < cuts->get(pTBin, "pT El") || trackPos.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(trackNeg.dcaPrim0()) > cuts->get(pTBin, "DCA_xy") || std::abs(trackPos.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(trackNeg.dcaPrim1()) > cuts->get(pTBin, "DCA_z") || std::abs(trackPos.dcaPrim1()) > cuts->get(pTBin, "DCA_z")) { return false; } @@ -176,54 +184,65 @@ struct HFJpsiToEECandidateSelector { // looping over 2-prong candidates for (auto& candidate : candidates) { + if (!(candidate.hfflag() & 1 << DecayType::JpsiToEE) && !(candidate.hfflag() & 1 << DecayType::JpsiToMuMu)) { + hfSelJpsiCandidate(0, 0); + continue; + } + auto trackPos = candidate.index0_as(); // positive daughter auto trackNeg = candidate.index1_as(); // negative daughter - if (!(candidate.hfflag() & 1 << DecayType::JpsiToEE)) { - hfSelJpsiToEECandidate(0); - continue; - } + int selectedEE = 1; + int selectedMuMu = 1; // track selection level need to add special cuts (additional cuts on decay length and d0 norm) - if (!selectionTopol(candidate, trackPos, trackNeg)) { - hfSelJpsiToEECandidate(0); + if (!selectionTopol(candidate, trackPos, trackNeg, selectedEE, selectedMuMu)) { + hfSelJpsiCandidate(0, 0); continue; } - // 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 + // track-level electron PID TOF selection if (selectorElectron.getStatusTrackPIDTOF(trackPos) == TrackSelectorPID::Status::PIDRejected || selectorElectron.getStatusTrackPIDTOF(trackNeg) == TrackSelectorPID::Status::PIDRejected) { - hfSelJpsiToEECandidate(0); - continue; + selectedEE = 0; } - // track-level PID RICH selection - if (selectorElectron.getStatusTrackPIDRICH(trackPos) == TrackSelectorPID::Status::PIDRejected || - selectorElectron.getStatusTrackPIDRICH(trackNeg) == TrackSelectorPID::Status::PIDRejected) { - hfSelJpsiToEECandidate(0); + if (selectedEE == 0 && selectedMuMu == 0) { + hfSelJpsiCandidate(0, 0); 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; + if (isALICE3) { // ALICE 3 detectors + // track-level electron PID RICH selection + if (selectorElectron.getStatusTrackPIDRICH(trackPos) == TrackSelectorPID::Status::PIDRejected || + selectorElectron.getStatusTrackPIDRICH(trackNeg) == TrackSelectorPID::Status::PIDRejected) { + selectedEE = 0; + } + + if (selectedEE == 0 && selectedMuMu == 0) { + hfSelJpsiCandidate(0, 0); + 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"); + selectedMuMu = 0; + } + //LOGF(info, "Muon selection: Selected"); + + } else { // ALICE 2 detectors + // track-level electron PID TPC selection + if (selectorElectron.getStatusTrackPIDTPC(trackPos) == TrackSelectorPID::Status::PIDRejected || + selectorElectron.getStatusTrackPIDTPC(trackNeg) == TrackSelectorPID::Status::PIDRejected) { + selectedEE = 0; + } } - //LOGF(info, "Muon selection: Selected"); - hfSelJpsiToEECandidate(1); + hfSelJpsiCandidate(selectedEE, selectedMuMu); } } }; @@ -234,5 +253,5 @@ WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) //adaptAnalysisTask(cfgc), //adaptAnalysisTask(cfgc), adaptAnalysisTask(cfgc), - adaptAnalysisTask(cfgc, TaskName{"hf-jpsi-toee-candidate-selector"})}; + adaptAnalysisTask(cfgc, TaskName{"hf-jpsi-candidate-selector"})}; } diff --git a/Analysis/Tasks/PWGHF/HFXToJpsiPiPiCandidateSelector.cxx b/Analysis/Tasks/PWGHF/HFXToJpsiPiPiCandidateSelector.cxx index 39a5b9675cffd..0efd8a6dbe538 100644 --- a/Analysis/Tasks/PWGHF/HFXToJpsiPiPiCandidateSelector.cxx +++ b/Analysis/Tasks/PWGHF/HFXToJpsiPiPiCandidateSelector.cxx @@ -10,7 +10,7 @@ /// \file HFXToJpsiPiPiCandidateSelector.cxx /// \brief X(3872) selection task. -/// \note Adapted from HFJpsiToEECandidateSelector.cxx +/// \note Adapted from HFJpsiCandidateSelector.cxx /// \author Rik Spijkers , Utrecht University #include "Framework/runDataProcessing.h" diff --git a/Analysis/Tasks/PWGHF/taskJpsi.cxx b/Analysis/Tasks/PWGHF/taskJpsi.cxx index c7cc6827e3183..57679acb28054 100644 --- a/Analysis/Tasks/PWGHF/taskJpsi.cxx +++ b/Analysis/Tasks/PWGHF/taskJpsi.cxx @@ -63,7 +63,7 @@ struct TaskJpsi { Filter filterSelectCandidates = (aod::hf_selcandidate_jpsi::isSelJpsiToEE >= d_selectionFlagJpsi); - void process(soa::Filtered> const& candidates) + void process(soa::Filtered> const& candidates) { for (auto& candidate : candidates) { if (!(candidate.hfflag() & 1 << DecayType::JpsiToEE)) { @@ -134,7 +134,7 @@ struct TaskJpsiMC { Filter filterSelectCandidates = (aod::hf_selcandidate_jpsi::isSelJpsiToEE >= d_selectionFlagJpsi); - void process(soa::Filtered> const& candidates, + void process(soa::Filtered> const& candidates, soa::Join const& particlesMC, aod::BigTracksMC const& tracks) { // MC rec.