diff --git a/PWGHF/D2H/Tasks/taskB0.cxx b/PWGHF/D2H/Tasks/taskB0.cxx index 4b6d1e5c6e8..497ba6491ab 100644 --- a/PWGHF/D2H/Tasks/taskB0.cxx +++ b/PWGHF/D2H/Tasks/taskB0.cxx @@ -37,6 +37,9 @@ struct HfTaskB0 { Configurable yCandMax{"yCandMax", 1.44, "max. cand. rapidity"}; Configurable> binsPt{"binsPt", std::vector{hf_cuts_b0_to_d_pi::vecBinsPt}, "pT bin limits"}; + float etaMaxAcceptance = 0.8; + float ptMinAcceptance = 0.1; + using TracksWithSel = soa::Join; Filter filterSelectCandidates = (aod::hf_sel_candidate_b0::isSelB0ToDPi >= selectionFlagB0); @@ -65,6 +68,8 @@ struct HfTaskB0 { registry.add("hEtaGen", "MC particles (generated);B^{0} candidate #it{#eta}^{gen};entries", {HistType::kTH2F, {{100, -2., 2.}, {(std::vector)binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); registry.add("hYGen", "MC particles (generated);B^{0} candidate #it{y}^{gen};entries", {HistType::kTH2F, {{100, -2., 2.}, {(std::vector)binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("hEtaGenWithProngsInAcceptance", "MC particles (generated-daughters in acceptance);B^{0} candidate #it{#eta}^{gen};entries", {HistType::kTH2F, {{100, -2., 2.}, {(std::vector)binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("hYGenWithProngsInAcceptance", "MC particles (generated-daughters in acceptance);B^{0} candidate #it{y}^{gen};entries", {HistType::kTH2F, {{100, -2., 2.}, {(std::vector)binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); registry.add("hPtProng0Gen", "MC particles (generated);prong 0 (D^{#minus}) #it{p}_{T}^{gen} (GeV/#it{c});entries", {HistType::kTH2F, {{100, 0., 10.}, {(std::vector)binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); registry.add("hPtProng1Gen", "MC particles (generated);prong 1 (#pi^{-}) #it{p}_{T}^{gen} (GeV/#it{c});entries", {HistType::kTH2F, {{100, 0., 10.}, {(std::vector)binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); registry.add("hYProng0Gen", "MC particles (generated);prong 0 (D^{#minus}) #it{y}^{gen};entries", {HistType::kTH2F, {{100, -2, 2}, {(std::vector)binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); @@ -110,6 +115,20 @@ struct HfTaskB0 { registry.add("hPtRecBg", "B0 candidates (unmatched);candidate #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{300, 0., 30.}}}); registry.add("hPtGenSig", "B0 candidates (gen+rec);candidate #it{p}_{T}^{gen.} (GeV/#it{c});entries", {HistType::kTH1F, {{300, 0., 10.}}}); registry.add("hPtGen", "MC particles (generated);candidate #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{300, 0., 30.}}}); + registry.add("hPtGenWithProngsInAcceptance", "MC particles (generated-daughters in acceptance);candidate #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{300, 0., 30.}}}); + } + + /// Selection of B0 daughter in geometrical acceptance + /// \param etaProng is the pseudorapidity of B0 prong + /// \param ptProng is the pT of B0 prong + /// \return true if prong is in geometrical acceptance + template + bool isProngInAcceptance(const T& etaProng, const T& ptProng) + { + if (etaProng > etaMaxAcceptance || ptProng < ptMinAcceptance) { + return false; + } + return true; } void process(soa::Filtered> const& candidates, soa::Join const&, TracksWithSel const&) @@ -219,7 +238,9 @@ struct HfTaskB0 { continue; } - float ptProngs[2], yProngs[2], etaProngs[2]; + std::array ptProngs; + std::array yProngs; + std::array etaProngs; int counter = 0; for (auto const& daught : particle.daughters_as()) { ptProngs[counter] = daught.pt(); @@ -241,6 +262,14 @@ struct HfTaskB0 { registry.fill(HIST("hPtGen"), ptParticle); registry.fill(HIST("hYGen"), yParticle, ptParticle); registry.fill(HIST("hEtaGen"), particle.eta(), ptParticle); + + // reject B0 daughters that are not in geometrical acceptance + if (!isProngInAcceptance(etaProngs[0], ptProngs[0]) || !isProngInAcceptance(etaProngs[1], ptProngs[1])) { + continue; + } + registry.fill(HIST("hPtGenWithProngsInAcceptance"), ptParticle); + registry.fill(HIST("hYGenWithProngsInAcceptance"), yParticle, ptParticle); + registry.fill(HIST("hEtaGenWithProngsInAcceptance"), particle.eta(), ptParticle); } } // gen } // process diff --git a/PWGHF/TableProducer/candidateSelectorB0ToDPi.cxx b/PWGHF/TableProducer/candidateSelectorB0ToDPi.cxx index e1630c34034..536c3271de0 100644 --- a/PWGHF/TableProducer/candidateSelectorB0ToDPi.cxx +++ b/PWGHF/TableProducer/candidateSelectorB0ToDPi.cxx @@ -67,34 +67,64 @@ struct HfCandidateSelectorB0ToDPi { bool selectionFlagDAndUsePidInSync = true; // FIXME: store B0 creator configurable (until https://alice.its.cern.ch/jira/browse/O2-3582 solved) int mySelectionFlagD = -1; + // QA switch + Configurable activateQA{"activateQA", false, "Flag to enable QA histogram"}; + + TrackSelectorPID selectorPion; using TracksPIDWithSel = soa::Join; - /* + HistogramRegistry registry{"registry"}; + + void init(InitContext const& initContext) + { + if (usePid) { + selectorPion.setPDG(kPiPlus); + selectorPion.setRangePtTPC(ptPidTpcMin, ptPidTpcMax); + selectorPion.setRangeNSigmaTPC(-nSigmaTpcMax, nSigmaTpcMax); + selectorPion.setRangeNSigmaTPCCondTOF(-nSigmaTpcCombinedMax, nSigmaTpcCombinedMax); + selectorPion.setRangePtTOF(ptPidTofMin, ptPidTofMax); + selectorPion.setRangeNSigmaTOF(-nSigmaTofMax, nSigmaTofMax); + selectorPion.setRangeNSigmaTOFCondTPC(-nSigmaTofCombinedMax, nSigmaTofCombinedMax); + } + + if (activateQA) { + constexpr int kNBinsSelections = 1 + SelectionStep::NSelectionSteps; + std::string labels[kNBinsSelections]; + labels[0] = "No selection"; + labels[1 + SelectionStep::RecoSkims] = "Skims selection"; + labels[1 + SelectionStep::RecoTopol] = "Skims & Topological selections"; + labels[1 + SelectionStep::RecoPID] = "Skims & Topological & PID selections"; + static const AxisSpec axisSelections = {kNBinsSelections, 0.5, kNBinsSelections + 0.5, ""}; + registry.add("hSelections", "Selections;;#it{p}_{T} (GeV/#it{c})", {HistType::kTH2F, {axisSelections, {(std::vector)binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); + for (int iBin = 0; iBin < kNBinsSelections; ++iBin) { + registry.get(HIST("hSelections"))->GetXaxis()->SetBinLabel(iBin + 1, labels[iBin].data()); + } + } + // FIXME: will be uncommented once https://alice.its.cern.ch/jira/browse/O2-3582 is solved - void init(InitContext const& initContext) { - int selectionFlagD = -1; - auto& workflows = initContext.services().get(); - for (DeviceSpec const& device : workflows.devices) { - if (device.name.compare("hf-candidate-creator-b0") == 0) { - for (auto const& option : device.options) { - if (option.name.compare("selectionFlagD") == 0) { - selectionFlagD = option.defaultValue.get(); - LOGF(info, "selectionFlagD = %d", selectionFlagD); - } + /*int selectionFlagD = -1; + auto& workflows = initContext.services().get(); + for (DeviceSpec const& device : workflows.devices) { + if (device.name.compare("hf-candidate-creator-b0") == 0) { + for (auto const& option : device.options) { + if (option.name.compare("selectionFlagD") == 0) { + selectionFlagD = option.defaultValue.get(); + LOGF(info, "selectionFlagD = %d", selectionFlagD); } } } + } - if (usePid && !TESTBIT(selectionFlagD, SelectionStep::RecoPID)) { - selectionFlagDAndUsePidInSync = false; - LOG(warning) << "PID selections required on B0 daughters (usePid=true) but no PID selections on D candidates were required a priori (selectionFlagD<7). Set selectionFlagD=7 in hf-candidate-creator-b0"; - } - if (!usePid && TESTBIT(selectionFlagD, SelectionStep::RecoPID)) { - selectionFlagDAndUsePidInSync = false; - LOG(warning) << "No PID selections required on B0 daughters (usePid=false) but PID selections on D candidates were required a priori (selectionFlagD=7). Set selectionFlagD<7 in hf-candidate-creator-b0"; - } + if (usePid && !TESTBIT(selectionFlagD, SelectionStep::RecoPID)) { + selectionFlagDAndUsePidInSync = false; + LOG(warning) << "PID selections required on B0 daughters (usePid=true) but no PID selections on D candidates were required a priori (selectionFlagD<7). Set selectionFlagD=7 in hf-candidate-creator-b0"; + } + if (!usePid && TESTBIT(selectionFlagD, SelectionStep::RecoPID)) { + selectionFlagDAndUsePidInSync = false; + LOG(warning) << "No PID selections required on B0 daughters (usePid=false) but PID selections on D candidates were required a priori (selectionFlagD=7). Set selectionFlagD<7 in hf-candidate-creator-b0"; }*/ + } /// Apply topological cuts as defined in SelectorCuts.h /// \param hfCandB0 is the B0 candidate @@ -205,24 +235,23 @@ struct HfCandidateSelectorB0ToDPi { } } - int statusB0ToDPi = 0; - - TrackSelectorPID selectorPion(kPiPlus); - selectorPion.setRangePtTPC(ptPidTpcMin, ptPidTpcMax); - selectorPion.setRangeNSigmaTPC(-nSigmaTpcMax, nSigmaTpcMax); - selectorPion.setRangeNSigmaTPCCondTOF(-nSigmaTpcCombinedMax, nSigmaTpcCombinedMax); - selectorPion.setRangePtTOF(ptPidTofMin, ptPidTofMax); - selectorPion.setRangeNSigmaTOF(-nSigmaTofMax, nSigmaTofMax); - selectorPion.setRangeNSigmaTOFCondTPC(-nSigmaTofCombinedMax, nSigmaTofCombinedMax); - for (const auto& hfCandB0 : hfCandsB0) { + int statusB0ToDPi = 0; + auto ptCandB0 = hfCandB0.pt(); + // check if flagged as B0 → D π if (!TESTBIT(hfCandB0.hfflag(), hf_cand_b0::DecayType::B0ToDPi)) { hfSelB0ToDPiCandidate(statusB0ToDPi); + if (activateQA) { + registry.fill(HIST("hSelections"), 0, ptCandB0); + } // LOGF(info, "B0 candidate selection failed at hfflag check"); continue; } - SETBIT(statusB0ToDPi, aod::SelectionStep::RecoSkims); // RecoSkims = 0 --> statusB0ToDPi = 1 + SETBIT(statusB0ToDPi, SelectionStep::RecoSkims); // RecoSkims = 0 --> statusB0ToDPi = 1 + if (activateQA) { + registry.fill(HIST("hSelections"), 1 + SelectionStep::RecoSkims, ptCandB0); + } auto candD = hfCandB0.prong0_as>(); auto trackPi = hfCandB0.prong1_as(); @@ -233,7 +262,10 @@ struct HfCandidateSelectorB0ToDPi { // LOGF(info, "B0 candidate selection failed at topology selection"); continue; } - SETBIT(statusB0ToDPi, aod::SelectionStep::RecoTopol); // RecoTopol = 1 --> statusB0ToDPi = 3 + SETBIT(statusB0ToDPi, SelectionStep::RecoTopol); // RecoTopol = 1 --> statusB0ToDPi = 3 + if (activateQA) { + registry.fill(HIST("hSelections"), 1 + SelectionStep::RecoTopol, ptCandB0); + } // checking if selectionFlagD and usePid are in sync if (!selectionFlagDAndUsePidInSync) { @@ -248,7 +280,10 @@ struct HfCandidateSelectorB0ToDPi { hfSelB0ToDPiCandidate(statusB0ToDPi); continue; } - SETBIT(statusB0ToDPi, aod::SelectionStep::RecoPID); // RecoPID = 2 --> statusB0ToDPi = 7 + SETBIT(statusB0ToDPi, SelectionStep::RecoPID); // RecoPID = 2 --> statusB0ToDPi = 7 + if (activateQA) { + registry.fill(HIST("hSelections"), 1 + SelectionStep::RecoPID, ptCandB0); + } } hfSelB0ToDPiCandidate(statusB0ToDPi); diff --git a/PWGHF/TableProducer/candidateSelectorDplusToPiKPi.cxx b/PWGHF/TableProducer/candidateSelectorDplusToPiKPi.cxx index 9e0ee06db1d..68369114aca 100644 --- a/PWGHF/TableProducer/candidateSelectorDplusToPiKPi.cxx +++ b/PWGHF/TableProducer/candidateSelectorDplusToPiKPi.cxx @@ -45,6 +45,42 @@ struct HfCandidateSelectorDplusToPiKPi { // topological cuts Configurable> binsPt{"binsPt", std::vector{hf_cuts_dplus_to_pi_k_pi::vecBinsPt}, "pT bin limits"}; Configurable> cuts{"cuts", {hf_cuts_dplus_to_pi_k_pi::cuts[0], nBinsPt, nCutVars, labelsPt, labelsCutVar}, "Dplus candidate selection per pT bin"}; + // QA switch + Configurable activateQA{"activateQA", false, "Flag to enable QA histogram"}; + + TrackSelectorPID selectorPion; + TrackSelectorPID selectorKaon; + + HistogramRegistry registry{"registry"}; + + void init(InitContext const&) + { + selectorPion.setPDG(kPiPlus); + selectorPion.setRangePtTPC(ptPidTpcMin, ptPidTpcMax); + selectorPion.setRangeNSigmaTPC(-nSigmaTpcMax, nSigmaTpcMax); + selectorPion.setRangePtTOF(ptPidTofMin, ptPidTofMax); + selectorPion.setRangeNSigmaTOF(-nSigmaTofMax, nSigmaTofMax); + + selectorKaon.setPDG(kKPlus); + selectorKaon.setRangePtTPC(ptPidTpcMin, ptPidTpcMax); + selectorKaon.setRangeNSigmaTPC(-nSigmaTpcMax, nSigmaTpcMax); + selectorKaon.setRangePtTOF(ptPidTofMin, ptPidTofMax); + selectorKaon.setRangeNSigmaTOF(-nSigmaTofMax, nSigmaTofMax); + + if (activateQA) { + constexpr int kNBinsSelections = 1 + aod::SelectionStep::NSelectionSteps; + std::string labels[kNBinsSelections]; + labels[0] = "No selection"; + labels[1 + aod::SelectionStep::RecoSkims] = "Skims selection"; + labels[1 + aod::SelectionStep::RecoTopol] = "Skims & Topological selections"; + labels[1 + aod::SelectionStep::RecoPID] = "Skims & Topological & PID selections"; + static const AxisSpec axisSelections = {kNBinsSelections, 0.5, kNBinsSelections + 0.5, ""}; + registry.add("hSelections", "Selections;;#it{p}_{T} (GeV/#it{c})", {HistType::kTH2F, {axisSelections, {(std::vector)binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); + for (int iBin = 0; iBin < kNBinsSelections; ++iBin) { + registry.get(HIST("hSelections"))->GetXaxis()->SetBinLabel(iBin + 1, labels[iBin].data()); + } + } + } /* /// Selection on goodness of daughter tracks @@ -131,26 +167,25 @@ struct HfCandidateSelectorDplusToPiKPi { void process(aod::HfCand3Prong const& candidates, aod::BigTracksPID const&) { - TrackSelectorPID selectorPion(kPiPlus); - selectorPion.setRangePtTPC(ptPidTpcMin, ptPidTpcMax); - selectorPion.setRangeNSigmaTPC(-nSigmaTpcMax, nSigmaTpcMax); - selectorPion.setRangePtTOF(ptPidTofMin, ptPidTofMax); - selectorPion.setRangeNSigmaTOF(-nSigmaTofMax, nSigmaTofMax); - - TrackSelectorPID selectorKaon(selectorPion); - selectorKaon.setPDG(kKPlus); - // looping over 3-prong candidates for (auto& candidate : candidates) { // final selection flag: auto statusDplusToPiKPi = 0; - if (!(candidate.hfflag() & 1 << DecayType::DplusToPiKPi)) { + auto ptCand = candidate.pt(); + + if (!TESTBIT(candidate.hfflag(), DecayType::DplusToPiKPi)) { hfSelDplusToPiKPiCandidate(statusDplusToPiKPi); + if (activateQA) { + registry.fill(HIST("hSelections"), 0, ptCand); + } continue; } SETBIT(statusDplusToPiKPi, aod::SelectionStep::RecoSkims); + if (activateQA) { + registry.fill(HIST("hSelections"), 1 + aod::SelectionStep::RecoSkims, ptCand); + } auto trackPos1 = candidate.prong0_as(); // positive daughter (negative for the antiparticles) auto trackNeg = candidate.prong1_as(); // negative daughter (positive for the antiparticles) @@ -172,6 +207,9 @@ struct HfCandidateSelectorDplusToPiKPi { continue; } SETBIT(statusDplusToPiKPi, aod::SelectionStep::RecoTopol); + if (activateQA) { + registry.fill(HIST("hSelections"), 1 + aod::SelectionStep::RecoTopol, ptCand); + } // track-level PID selection int pidTrackPos1Pion = selectorPion.getStatusTrackPIDTpcAndTof(trackPos1); @@ -183,6 +221,9 @@ struct HfCandidateSelectorDplusToPiKPi { continue; } SETBIT(statusDplusToPiKPi, aod::SelectionStep::RecoPID); + if (activateQA) { + registry.fill(HIST("hSelections"), 1 + aod::SelectionStep::RecoPID, ptCand); + } hfSelDplusToPiKPiCandidate(statusDplusToPiKPi); }