Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 30 additions & 1 deletion PWGHF/D2H/Tasks/taskB0.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ struct HfTaskB0 {
Configurable<double> yCandMax{"yCandMax", 1.44, "max. cand. rapidity"};
Configurable<std::vector<double>> binsPt{"binsPt", std::vector<double>{hf_cuts_b0_to_d_pi::vecBinsPt}, "pT bin limits"};

float etaMaxAcceptance = 0.8;
float ptMinAcceptance = 0.1;

using TracksWithSel = soa::Join<aod::BigTracksExtended, aod::TrackSelection>;

Filter filterSelectCandidates = (aod::hf_sel_candidate_b0::isSelB0ToDPi >= selectionFlagB0);
Expand Down Expand Up @@ -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<double>)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<double>)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<double>)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<double>)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<double>)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<double>)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<double>)binsPt, "#it{p}_{T} (GeV/#it{c})"}}});
Expand Down Expand Up @@ -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 <typename T = float>
bool isProngInAcceptance(const T& etaProng, const T& ptProng)
{
if (etaProng > etaMaxAcceptance || ptProng < ptMinAcceptance) {
return false;
}
return true;
}

void process(soa::Filtered<soa::Join<aod::HfCandB0, aod::HfSelB0ToDPi>> const& candidates, soa::Join<aod::HfCand3Prong, aod::HfSelDplusToPiKPi> const&, TracksWithSel const&)
Expand Down Expand Up @@ -219,7 +238,9 @@ struct HfTaskB0 {
continue;
}

float ptProngs[2], yProngs[2], etaProngs[2];
std::array<float, 2> ptProngs;
std::array<float, 2> yProngs;
std::array<float, 2> etaProngs;
int counter = 0;
for (auto const& daught : particle.daughters_as<aod::McParticles>()) {
ptProngs[counter] = daught.pt();
Expand All @@ -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
Expand Down
99 changes: 67 additions & 32 deletions PWGHF/TableProducer/candidateSelectorB0ToDPi.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -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<bool> activateQA{"activateQA", false, "Flag to enable QA histogram"};

TrackSelectorPID selectorPion;

using TracksPIDWithSel = soa::Join<aod::BigTracksPIDExtended, aod::TrackSelection>;

/*
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<double>)binsPt, "#it{p}_{T} (GeV/#it{c})"}}});
for (int iBin = 0; iBin < kNBinsSelections; ++iBin) {
registry.get<TH2>(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<RunningWorkflowInfo const>();
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<int>();
LOGF(info, "selectionFlagD = %d", selectionFlagD);
}
/*int selectionFlagD = -1;
auto& workflows = initContext.services().get<RunningWorkflowInfo const>();
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<int>();
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
Expand Down Expand Up @@ -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<soa::Join<aod::HfCand3Prong, aod::HfSelDplusToPiKPi>>();
auto trackPi = hfCandB0.prong1_as<TracksPIDWithSel>();
Expand All @@ -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) {
Expand All @@ -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);
Expand Down
61 changes: 51 additions & 10 deletions PWGHF/TableProducer/candidateSelectorDplusToPiKPi.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,42 @@ struct HfCandidateSelectorDplusToPiKPi {
// topological cuts
Configurable<std::vector<double>> binsPt{"binsPt", std::vector<double>{hf_cuts_dplus_to_pi_k_pi::vecBinsPt}, "pT bin limits"};
Configurable<LabeledArray<double>> cuts{"cuts", {hf_cuts_dplus_to_pi_k_pi::cuts[0], nBinsPt, nCutVars, labelsPt, labelsCutVar}, "Dplus candidate selection per pT bin"};
// QA switch
Configurable<bool> 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<double>)binsPt, "#it{p}_{T} (GeV/#it{c})"}}});
for (int iBin = 0; iBin < kNBinsSelections; ++iBin) {
registry.get<TH2>(HIST("hSelections"))->GetXaxis()->SetBinLabel(iBin + 1, labels[iBin].data());
}
}
}

/*
/// Selection on goodness of daughter tracks
Expand Down Expand Up @@ -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<aod::BigTracksPID>(); // positive daughter (negative for the antiparticles)
auto trackNeg = candidate.prong1_as<aod::BigTracksPID>(); // negative daughter (positive for the antiparticles)
Expand All @@ -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);
Expand All @@ -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);
}
Expand Down