Skip to content
Merged
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
180 changes: 180 additions & 0 deletions PWGHF/Core/DecayChannels.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
// All rights not expressly granted are reserved.
//
// This software is distributed under the terms of the GNU General Public
// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
//
// 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 DecayChannels.h
/// \brief Definitions of constants for MC flagging of HF decay channels.
/// \author Vít Kučera <vit.kucera@cern.ch>, Inha University
/// \note DecayChannelMain enums define unique combinations of the mother and the daughters for main channels.
/// \note DecayChannelResonant enums define unique combinations of the mother and the daughters for resonant channels.
/// \note Value 0 is reserved to indicate no match.
/// \note Daughter ordering convention: (charm|strange|π±|K±|π0), (baryon|meson), (+|−)

#ifndef PWGHF_CORE_DECAYCHANNELS_H_
#define PWGHF_CORE_DECAYCHANNELS_H_

#include <cstdint>

namespace o2::hf_decay
{

// TODO
// - HF cascades (Λc+ → p K0short)
// - HF cascades to LF cascades (Ωc0/Ξc0 → Ξ+ π−, Ξc+ → Ξ+ π− π+)
// - Σc

namespace hf_cand_2prong
{
/// @brief 2-prong candidates: main channels
enum DecayChannelMain : int8_t {
// D0
D0ToPiK = 1, // π+ K−
D0ToPiKPi0, // π+ K− π0
D0ToPiPi, // π+ π−
D0ToPiPiPi0, // π+ π− π0
D0ToKK, // K+ K−
//
LastChannelMain
};
/// @brief 2-prong candidates: resonant channels
enum DecayChannelResonant : int8_t {
// D0
D0ToRhoplusPi = 1, // ρ+ π−
D0ToRhoplusK, // ρ+ K−
D0ToKstar0Pi0, // anti-K*0 π0
D0ToKstarPi, // K*− π+
//
LastChannelResonant
};
} // namespace hf_cand_2prong

namespace hf_cand_3prong
{
/// @brief 3-prong candidates: main channels
enum DecayChannelMain : int8_t {
// D+
DplusToPiKPi = 1, // π+ K− π+
DplusToPiKPiPi0, // π+ K− π+ π0
DplusToPiPiPi, // π+ π− π+
DplusToPiKK, // π+ K− K+
// Ds+
DsToPiKK, // π+ K− K+
DsToPiKKPi0, // π+ K− K+ π0
DsToPiPiK, // π+ π− K+
DsToPiPiPi, // π+ π− π+
DsToPiPiPiPi0, // π+ π− π+ π0
// D*+
DstarToPiKPi, // π+ K− π+ (from [(D0 → π+ K−) π+])
// Λc+
LcToPKPi, // p K− π+
LcToPKPiPi0, // p K− π+ π0
LcToPPiPi, // p π− π+
LcToPKK, // p K− K+
// Ξc+
XicToPKPi, // p K− π+
XicToPKK, // p K− K+
XicToSPiPi, // Σ+ π− π+
//
LastChannelMain
};
/// @brief 3-prong candidates: resonant channels
enum DecayChannelResonant : int8_t {
// D+
DplusToPhiPi = 1, // φ π+
DplusToKstar0K, // anti-K*0 K+
DplusToKstar1430_0K, // anti-K*0(1430) K+
DplusToRho0Pi, // ρ0 π+
DplusToF2_1270Pi, // f2(1270) π+
// Ds+
DsToPhiPi, // φ π+
DsToPhiRhoplus, // φ ρ+
DsToKstar0K, // anti-K*0 K+
DsToKstar0Pi, // anti-K*0 π+
DsToRho0Pi, // ρ0 π+
DsToRho0K, // ρ0 K+
DsToF2_1270Pi, // f2(1270) π+
DsToF0_1370K, // f0(1370) K+
DsToEtaPi, // η π+
// Λc+
LcToPKstar0, // p K*0(892)
LcToDeltaplusplusK, // Δ++ K−
LcToL1520Pi, // Λ(1520) π+
// Ξc+
XicToPKstar0, // p anti-K*0(892)
XicToPPhi, // p φ
//
LastChannelResonant
};
} // namespace hf_cand_3prong

namespace hf_cand_dstar
{
/// @brief D*+ candidates: main channels
enum DecayChannelMain : int8_t {
// D*+
DstarToPiKPi = 1, // π+ K− π+ (from [(D0 → π+ K−) π+])
DstarToPiKPiPi0, // π+ K− π+ π0 (from [(D0 → π+ K− π0) π+] or [(D+ → π+ K− π+) π0])
//
LastChannelMain
};
} // namespace hf_cand_dstar

namespace hf_cand_beauty
{
/// @brief beauty candidates: main channels
enum DecayChannelMain : int8_t {
// B0
B0ToDminusPi = 1, // D− π+
B0ToDminusPiPi0, // D− π+ π0
B0ToDminusPiGamma, // D− π+ γ0
B0ToDminusK, // D− K+
B0ToD0PiPi, // anti-D0 π+ π−
// Bs0
BsToDsPi, // Ds− π+
BsToDsPiPi0, // Ds− π+ π0
BsToDsPiGamma, // Ds− π+ γ0
BsToDsK, // Ds− K+
// Λb0
LbToLcPi, // Λc+ π−
LbToLcPiPi0, // Λc+ π− π0
LbToLcPiGamma, // Λc+ π− γ0
LbToLcK, // Λc+ K−
LbToLcKPi0, // Λc+ K− π0
// B+
BplusToD0Pi, // anti-D0 π+
BplusToD0PiPi0, // anti-D0 π+ π0
BplusToD0PiGamma, // anti-D0 π+ γ0
BplusToD0K, // anti-D0 K+
//
LastChannelMain
};
/// @brief beauty candidates: resonant channels
enum DecayChannelResonant : int8_t {
// B0
B0ToDminusRhoplus = 1, // D− ρ+
B0ToDstarminusPi, // D*− π+
// Bs0
BsToDsRhoplus, // Ds− ρ+
BsToDsstarPi, // Ds*− π+
// Λb0
LbToLcRhoplus, // Λc+ ρ−
LbToScPi, // Σc+ π−
LbToScK, // Σc+ K−
LbToSc0Pi0, // Σc0 π0
// B+
BplusToD0Rhoplus, // anti-D0 ρ+
BplusToDstar0Pi, // anti-D*0 π+
//
LastChannelResonant
};
} // namespace hf_cand_beauty
} // namespace o2::hf_decay

#endif // PWGHF_CORE_DECAYCHANNELS_H_
16 changes: 8 additions & 8 deletions PWGHF/D2H/Tasks/taskCharmPolarisation.cxx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2019-2020 CERN and copyright holders of ALICE O2.

Check failure on line 1 in PWGHF/D2H/Tasks/taskCharmPolarisation.cxx

View workflow job for this annotation

GitHub Actions / O2 linter

[name/workflow-file]

Name of a workflow file must match the name of the main struct in it (without the PWG prefix). (Class implementation files should be in "Core" directories.)
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
// All rights not expressly granted are reserved.
//
Expand Down Expand Up @@ -120,7 +120,7 @@
Configurable<bool> selectionFlagDstarToD0Pi{"selectionFlagDstarToD0Pi", true, "Selection Flag for D* decay to D0 Pi"};
Configurable<int> selectionFlagLcToPKPi{"selectionFlagLcToPKPi", 1, "Selection Flag for Lc decay to P K Pi"};

ConfigurableAxis configThnAxisInvMass{"configThnAxisInvMass", {200, 0.139f, 0.179f}, "#it{M} (GeV/#it{c}^{2})"};

Check failure on line 123 in PWGHF/D2H/Tasks/taskCharmPolarisation.cxx

View workflow job for this annotation

GitHub Actions / O2 linter

[pdg/explicit-mass]

Avoid hard-coded particle masses. Use o2::constants::physics::Mass... instead.
ConfigurableAxis configThnAxisPt{"configThnAxisPt", {100, 0.f, 100.f}, "#it{p}_{T} (GeV/#it{c})"};
ConfigurableAxis configThnAxisY{"configThnAxisY", {20, -1.f, 1.f}, "#it{y}"};
ConfigurableAxis configThnAxisCosThetaStarHelicity{"configThnAxisCosThetaStarHelicity", {20, -1.f, 1.f}, "cos(#vartheta_{helicity})"};
Expand Down Expand Up @@ -993,11 +993,11 @@
bool isInSignalRegion(float invMass)
{
if constexpr (channel == charm_polarisation::DecayChannel::DstarToDzeroPi) { // D*+
if (0.142f < invMass && invMass < 0.15f) {

Check failure on line 996 in PWGHF/D2H/Tasks/taskCharmPolarisation.cxx

View workflow job for this annotation

GitHub Actions / O2 linter

[magic-number]

Avoid magic numbers in expressions. Assign the value to a clearly named variable or constant.
return true;
}
} else if constexpr (channel == charm_polarisation::DecayChannel::LcToPKPi) { // Lc+ (to be tuned!)
if (2.25f < invMass && invMass < 2.35f) {

Check failure on line 1000 in PWGHF/D2H/Tasks/taskCharmPolarisation.cxx

View workflow job for this annotation

GitHub Actions / O2 linter

[magic-number]

Avoid magic numbers in expressions. Assign the value to a clearly named variable or constant.
return true;
}
}
Expand Down Expand Up @@ -1086,8 +1086,8 @@
bool partRecoDstar{false};
if constexpr (doMc) {
if constexpr (channel == charm_polarisation::DecayChannel::DstarToDzeroPi) {
partRecoDstar = TESTBIT(std::abs(candidate.flagMcMatchRec()), aod::hf_cand_dstar::DecayType::DstarToD0PiPi0) && TESTBIT(std::abs(candidate.flagMcMatchRecD0()), aod::hf_cand_dstar::DecayType::D0ToPiKPi0);
bool signalDstar = TESTBIT(std::abs(candidate.flagMcMatchRec()), aod::hf_cand_dstar::DecayType::DstarToD0Pi) && TESTBIT(std::abs(candidate.flagMcMatchRecD0()), aod::hf_cand_dstar::DecayType::D0ToPiK);
partRecoDstar = std::abs(candidate.flagMcMatchRec()) == hf_decay::hf_cand_dstar::DecayChannelMain::DstarToPiKPiPi0 && std::abs(candidate.flagMcMatchRecD0()) == hf_decay::hf_cand_2prong::DecayChannelMain::D0ToPiKPi0;
bool signalDstar = std::abs(candidate.flagMcMatchRec()) == hf_decay::hf_cand_dstar::DecayChannelMain::DstarToPiKPi && std::abs(candidate.flagMcMatchRecD0()) == hf_decay::hf_cand_2prong::DecayChannelMain::D0ToPiK;
if (!signalDstar && (!partRecoDstar || !activatePartRecoDstar)) { // this candidate is not signal and not partially reconstructed signal, skip
return isCandidateInSignalRegion;
}
Expand All @@ -1095,12 +1095,12 @@
ptBhadMother = candidate.ptBhadMotherPart();
int pdgBhadMother = candidate.pdgBhadMotherPart();
// For unknown reasons there are charm hadrons coming directly from beauty diquarks without an intermediate B-hadron which have an unreasonable correlation between the pT of the charm hadron and the beauty mother. We also remove charm hadrons from quarkonia.
if (origin == RecoDecay::OriginType::NonPrompt && (pdgBhadMother == 5101 || pdgBhadMother == 5103 || pdgBhadMother == 5201 || pdgBhadMother == 5203 || pdgBhadMother == 5301 || pdgBhadMother == 5303 || pdgBhadMother == 5401 || pdgBhadMother == 5403 || pdgBhadMother == 5503 || pdgBhadMother == 553 || pdgBhadMother == 555 || pdgBhadMother == 553 || pdgBhadMother == 557)) {

Check failure on line 1098 in PWGHF/D2H/Tasks/taskCharmPolarisation.cxx

View workflow job for this annotation

GitHub Actions / O2 linter

[magic-number]

Avoid magic numbers in expressions. Assign the value to a clearly named variable or constant.

Check failure on line 1098 in PWGHF/D2H/Tasks/taskCharmPolarisation.cxx

View workflow job for this annotation

GitHub Actions / O2 linter

[pdg/explicit-code]

Avoid hard-coded PDG codes. Use named values from PDG_t or o2::constants::physics::Pdg instead.
return isCandidateInSignalRegion;
}
} else if constexpr (channel == charm_polarisation::DecayChannel::LcToPKPi) {
if constexpr (!studyLcPKPiBkgMc) { // skip this if studyLcPKPiBkgMc is true, since we are interested in background
if (!TESTBIT(std::abs(candidate.flagMcMatchRec()), aod::hf_cand_3prong::DecayType::LcToPKPi)) { // this candidate is not signal, skip
if constexpr (!studyLcPKPiBkgMc) { // skip this if studyLcPKPiBkgMc is true, since we are interested in background
if (std::abs(candidate.flagMcMatchRec()) != hf_decay::hf_cand_3prong::DecayChannelMain::LcToPKPi) { // this candidate is not signal, skip
return isCandidateInSignalRegion;
}
origin = candidate.originMcRec();
Expand Down Expand Up @@ -1241,7 +1241,7 @@
invMassCharmHadForSparse = hfHelper.invMassLcToPKPi(candidate);
}
if constexpr (withMl) {
if (candidate.mlProbLcToPKPi().size() == 3) {

Check failure on line 1244 in PWGHF/D2H/Tasks/taskCharmPolarisation.cxx

View workflow job for this annotation

GitHub Actions / O2 linter

[magic-number]

Avoid magic numbers in expressions. Assign the value to a clearly named variable or constant.
// protect from empty vectors
// the BDT output score might be empty if no preselections were enabled (selectionFlag null)
// !!! NB: each rotated candidates inherits the BDT scores of the original candidate, even if the candidate pt changed after the rotation of the kaon-track pt !!!
Expand Down Expand Up @@ -1275,7 +1275,7 @@
invMassCharmHadForSparse = hfHelper.invMassLcToPiKP(candidate);
}
if constexpr (withMl) {
if (candidate.mlProbLcToPiKP().size() == 3) {

Check failure on line 1278 in PWGHF/D2H/Tasks/taskCharmPolarisation.cxx

View workflow job for this annotation

GitHub Actions / O2 linter

[magic-number]

Avoid magic numbers in expressions. Assign the value to a clearly named variable or constant.
// protect from empty vectors
// the BDT output score might be empty if no preselections were enabled (selectionFlag null)
// !!! NB: each rotated candidates inherits the BDT scores of the original candidate, even if the candidate pt changed after the rotation of the kaon-track pt !!!
Expand Down Expand Up @@ -1501,7 +1501,7 @@

/// check if the pKpi triplet is a Lc->pKpi
int8_t isRealLcPKPi = 0;
if (isRealPKPi && TESTBIT(std::abs(candidate.flagMcMatchRec()), aod::hf_cand_3prong::DecayType::LcToPKPi)) {
if (isRealPKPi && (std::abs(candidate.flagMcMatchRec()) == hf_decay::hf_cand_3prong::DecayChannelMain::LcToPKPi)) {
isRealLcPKPi = 1;
}

Expand Down Expand Up @@ -1607,8 +1607,8 @@
int8_t charge = -99;
bool partRecoDstar{false};
if constexpr (channel == charm_polarisation::DecayChannel::DstarToDzeroPi) {
partRecoDstar = TESTBIT(std::abs(mcParticle.flagMcMatchGen()), aod::hf_cand_dstar::DecayType::DstarToD0PiPi0) && TESTBIT(std::abs(mcParticle.flagMcMatchGenD0()), aod::hf_cand_dstar::DecayType::D0ToPiKPi0);
bool signalDstar = TESTBIT(std::abs(mcParticle.flagMcMatchGen()), aod::hf_cand_dstar::DecayType::DstarToD0Pi) && TESTBIT(std::abs(mcParticle.flagMcMatchGenD0()), aod::hf_cand_dstar::DecayType::D0ToPiK);
partRecoDstar = TESTBIT(std::abs(mcParticle.flagMcMatchGen()), hf_decay::hf_cand_dstar::DecayChannelMain::DstarToPiKPiPi0) && TESTBIT(std::abs(mcParticle.flagMcMatchGenD0()), hf_decay::hf_cand_2prong::DecayChannelMain::D0ToPiKPi0);
bool signalDstar = TESTBIT(std::abs(mcParticle.flagMcMatchGen()), hf_decay::hf_cand_dstar::DecayChannelMain::DstarToPiKPi) && TESTBIT(std::abs(mcParticle.flagMcMatchGenD0()), hf_decay::hf_cand_2prong::DecayChannelMain::D0ToPiK);

if (!signalDstar && (!activatePartRecoDstar || !partRecoDstar)) { // this particle is not signal and not partially reconstructed signal, skip
return;
Expand All @@ -1618,7 +1618,7 @@
auto bHadMother = mcParticles.rawIteratorAt(mcParticle.idxBhadMotherPart() - mcParticles.offset());
int pdgBhadMother = std::abs(bHadMother.pdgCode());
// For unknown reasons there are charm hadrons coming directly from beauty diquarks without an intermediate B-hadron which have an unreasonable correlation between the pT of the charm hadron and the beauty mother. We also remove charm hadrons from quarkonia.
if (pdgBhadMother == 5101 || pdgBhadMother == 5103 || pdgBhadMother == 5201 || pdgBhadMother == 5203 || pdgBhadMother == 5301 || pdgBhadMother == 5303 || pdgBhadMother == 5401 || pdgBhadMother == 5403 || pdgBhadMother == 5503 || pdgBhadMother == 553 || pdgBhadMother == 555 || pdgBhadMother == 553 || pdgBhadMother == 557) {

Check failure on line 1621 in PWGHF/D2H/Tasks/taskCharmPolarisation.cxx

View workflow job for this annotation

GitHub Actions / O2 linter

[magic-number]

Avoid magic numbers in expressions. Assign the value to a clearly named variable or constant.

Check failure on line 1621 in PWGHF/D2H/Tasks/taskCharmPolarisation.cxx

View workflow job for this annotation

GitHub Actions / O2 linter

[pdg/explicit-code]

Avoid hard-coded PDG codes. Use named values from PDG_t or o2::constants::physics::Pdg instead.
return;
}
ptBhadMother = bHadMother.pt();
Expand All @@ -1629,7 +1629,7 @@
massDau = massPi;
massCharmHad = massDstar;
} else if constexpr (channel == charm_polarisation::DecayChannel::LcToPKPi) {
if (!TESTBIT(std::abs(mcParticle.flagMcMatchGen()), aod::hf_cand_3prong::DecayType::LcToPKPi)) { // this particle is not signal, skip
if (std::abs(mcParticle.flagMcMatchGen()) != hf_decay::hf_cand_3prong::DecayChannelMain::LcToPKPi) { // this particle is not signal, skip
return;
}
origin = mcParticle.originMcGen();
Expand Down
10 changes: 5 additions & 5 deletions PWGHF/D2H/Tasks/taskDplus.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -74,12 +74,12 @@ struct HfTaskDplus {
Partition<CandDplusDataWithMl> selectedDPlusCandidatesWithMl = aod::hf_sel_candidate_dplus::isSelDplusToPiKPi >= selectionFlagDplus;

// Matched MC
Partition<CandDplusMcReco> recoDPlusCandidates = nabs(aod::hf_cand_3prong::flagMcMatchRec) == static_cast<int8_t>(BIT(aod::hf_cand_3prong::DecayType::DplusToPiKPi)) && aod::hf_sel_candidate_dplus::isSelDplusToPiKPi >= selectionFlagDplus;
Partition<CandDplusMcRecoWithMl> recoDPlusCandidatesWithMl = nabs(aod::hf_cand_3prong::flagMcMatchRec) == static_cast<int8_t>(BIT(aod::hf_cand_3prong::DecayType::DplusToPiKPi)) && aod::hf_sel_candidate_dplus::isSelDplusToPiKPi >= selectionFlagDplus;
Partition<CandDplusMcReco> recoDPlusCandidates = nabs(aod::hf_cand_3prong::flagMcMatchRec) == static_cast<int8_t>(hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKPi) && aod::hf_sel_candidate_dplus::isSelDplusToPiKPi >= selectionFlagDplus;
Partition<CandDplusMcRecoWithMl> recoDPlusCandidatesWithMl = nabs(aod::hf_cand_3prong::flagMcMatchRec) == static_cast<int8_t>(hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKPi) && aod::hf_sel_candidate_dplus::isSelDplusToPiKPi >= selectionFlagDplus;

// MC Bkg
Partition<CandDplusMcReco> recoBkgCandidates = nabs(aod::hf_cand_3prong::flagMcMatchRec) != static_cast<int8_t>(BIT(aod::hf_cand_3prong::DecayType::DplusToPiKPi)) && aod::hf_sel_candidate_dplus::isSelDplusToPiKPi >= selectionFlagDplus;
Partition<CandDplusMcRecoWithMl> recoBkgCandidatesWithMl = nabs(aod::hf_cand_3prong::flagMcMatchRec) != static_cast<int8_t>(BIT(aod::hf_cand_3prong::DecayType::DplusToPiKPi)) && aod::hf_sel_candidate_dplus::isSelDplusToPiKPi >= selectionFlagDplus;
Partition<CandDplusMcReco> recoBkgCandidates = nabs(aod::hf_cand_3prong::flagMcMatchRec) != static_cast<int8_t>(hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKPi) && aod::hf_sel_candidate_dplus::isSelDplusToPiKPi >= selectionFlagDplus;
Partition<CandDplusMcRecoWithMl> recoBkgCandidatesWithMl = nabs(aod::hf_cand_3prong::flagMcMatchRec) != static_cast<int8_t>(hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKPi) && aod::hf_sel_candidate_dplus::isSelDplusToPiKPi >= selectionFlagDplus;

ConfigurableAxis thnConfigAxisY{"thnConfigAxisY", {40, -1, 1}, "Cand. rapidity bins"};
ConfigurableAxis thnConfigAxisCent{"thnConfigAxisCent", {110, 0., 110.}, ""};
Expand Down Expand Up @@ -569,7 +569,7 @@ struct HfTaskDplus {
ptGenB = -1;
flagGenB = -1;
auto yGen = RecoDecay::y(particle.pVector(), o2::constants::physics::MassDPlus);
if ((yCandGenMax >= 0. && std::abs(yGen) > yCandGenMax) || (std::abs(particle.flagMcMatchGen()) != 1 << aod::hf_cand_3prong::DecayType::DplusToPiKPi)) {
if ((yCandGenMax >= 0. && std::abs(yGen) > yCandGenMax) || (std::abs(particle.flagMcMatchGen()) != hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKPi)) {
continue;
}
if (particle.originMcGen() == RecoDecay::OriginType::NonPrompt) {
Expand Down
38 changes: 27 additions & 11 deletions PWGHF/D2H/Tasks/taskDs.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,19 @@ enum DataType { Data = 0,
McBkg,
kDataTypes };

enum Mother : int8_t {
Ds,
Dplus
};

enum ResonantChannel : int8_t {
PhiPi = 1,
Kstar0K = 2
};

static std::unordered_map<int8_t, std::unordered_map<int8_t, int8_t>> channelsResonant = {{{Mother::Ds, {{ResonantChannel::PhiPi, hf_decay::hf_cand_3prong::DecayChannelResonant::DsToPhiPi}, {ResonantChannel::Kstar0K, hf_decay::hf_cand_3prong::DecayChannelResonant::DsToKstar0K}}},
{Mother::Dplus, {{ResonantChannel::PhiPi, hf_decay::hf_cand_3prong::DecayChannelResonant::DplusToPhiPi}, {ResonantChannel::Kstar0K, hf_decay::hf_cand_3prong::DecayChannelResonant::DplusToKstar0K}}}}};

template <typename T>
concept hasDsMlInfo = requires(T candidate) {
candidate.mlProbDsToKKPi();
Expand All @@ -66,7 +79,7 @@ concept hasDsMlInfo = requires(T candidate) {
/// Ds± analysis task
struct HfTaskDs {

Configurable<int> decayChannel{"decayChannel", 1, "Switch between decay channels: 1 for Ds/Dplus->PhiPi->KKpi, 2 for Ds/Dplus->K0*K->KKPi"};
Configurable<int> decayChannel{"decayChannel", 1, "Switch between resonant decay channels: 1 for Ds/Dplus->PhiPi->KKpi, 2 for Ds/Dplus->K0*K->KKPi"};
Configurable<bool> fillDplusMc{"fillDplusMc", true, "Switch to fill Dplus MC information"};
Configurable<int> selectionFlagDs{"selectionFlagDs", 7, "Selection Flag for Ds"};
Configurable<std::vector<int>> classMl{"classMl", {0, 2, 3}, "Indexes of ML scores to be stored. Three indexes max."};
Expand Down Expand Up @@ -128,7 +141,6 @@ struct HfTaskDs {
ConfigurableAxis axisCentrality{"axisCentrality", {100, 0., 1.}, "axis for centrality/multiplicity"};
ConfigurableAxis axisOccupancy{"axisOccupancy", {14, 0., 14000.}, "axis for occupancy"};

int offsetDplusDecayChannel = aod::hf_cand_3prong::DecayChannelDToKKPi::DplusToPhiPi - aod::hf_cand_3prong::DecayChannelDToKKPi::DsToPhiPi; // Offset between Dplus and Ds to use the same decay channel. See aod::hf_cand_3prong::DecayChannelDToKKPi
int mRunNumber{0};
bool lCalibLoaded;
TList* lCalibObjects;
Expand Down Expand Up @@ -162,6 +174,10 @@ struct HfTaskDs {
LOGP(fatal, "No process function enabled");
}

if (decayChannel != ResonantChannel::PhiPi && decayChannel != ResonantChannel::Kstar0K) {
LOGP(fatal, "Invalid value of decayChannel");
}

AxisSpec ptbins{axisPt, "#it{p}_{T} (GeV/#it{c})"};
AxisSpec ptBHad{axisPtBHad, "#it{p}_{T}(B) (GeV/#it{c})"};
AxisSpec flagBHad{axisFlagBHad, "B Hadron flag"};
Expand Down Expand Up @@ -272,37 +288,37 @@ struct HfTaskDs {
template <typename CandDs>
bool isDsPrompt(const CandDs& candidate)
{
return std::abs(candidate.flagMcMatchRec()) == static_cast<int8_t>(BIT(aod::hf_cand_3prong::DecayType::DsToKKPi)) && candidate.flagMcDecayChanRec() == decayChannel && candidate.originMcRec() == RecoDecay::OriginType::Prompt;
return std::abs(candidate.flagMcMatchRec()) == static_cast<int8_t>(hf_decay::hf_cand_3prong::DecayChannelMain::DsToPiKK) && candidate.flagMcDecayChanRec() == channelsResonant[Mother::Ds][decayChannel] && candidate.originMcRec() == RecoDecay::OriginType::Prompt;
}

template <typename CandDs>
bool isDplusPrompt(const CandDs& candidate)
{
return std::abs(candidate.flagMcMatchRec()) == static_cast<int8_t>(BIT(aod::hf_cand_3prong::DecayType::DsToKKPi)) && candidate.flagMcDecayChanRec() == decayChannel + offsetDplusDecayChannel && candidate.originMcRec() == RecoDecay::OriginType::Prompt;
return std::abs(candidate.flagMcMatchRec()) == static_cast<int8_t>(hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKK) && candidate.flagMcDecayChanRec() == channelsResonant[Mother::Dplus][decayChannel] && candidate.originMcRec() == RecoDecay::OriginType::Prompt;
}

template <typename CandDs>
bool isDsNonPrompt(const CandDs& candidate)
{
return std::abs(candidate.flagMcMatchRec()) == static_cast<int8_t>(BIT(aod::hf_cand_3prong::DecayType::DsToKKPi)) && candidate.flagMcDecayChanRec() == decayChannel && candidate.originMcRec() == RecoDecay::OriginType::NonPrompt;
return std::abs(candidate.flagMcMatchRec()) == static_cast<int8_t>(hf_decay::hf_cand_3prong::DecayChannelMain::DsToPiKK) && candidate.flagMcDecayChanRec() == channelsResonant[Mother::Ds][decayChannel] && candidate.originMcRec() == RecoDecay::OriginType::NonPrompt;
}

template <typename CandDs>
bool isDplusNonPrompt(const CandDs& candidate)
{
return std::abs(candidate.flagMcMatchRec()) == static_cast<int8_t>(BIT(aod::hf_cand_3prong::DecayType::DsToKKPi)) && candidate.flagMcDecayChanRec() == decayChannel + offsetDplusDecayChannel && candidate.originMcRec() == RecoDecay::OriginType::NonPrompt;
return std::abs(candidate.flagMcMatchRec()) == static_cast<int8_t>(hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKK) && candidate.flagMcDecayChanRec() == channelsResonant[Mother::Dplus][decayChannel] && candidate.originMcRec() == RecoDecay::OriginType::NonPrompt;
}

template <typename CandDs>
bool isDplusBkg(const CandDs& candidate)
{
return std::abs(candidate.flagMcMatchRec()) == static_cast<int8_t>(BIT(aod::hf_cand_3prong::DecayType::DplusToPiKPi));
return std::abs(candidate.flagMcMatchRec()) == static_cast<int8_t>(hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKPi);
}

template <typename CandDs>
bool isLcBkg(const CandDs& candidate)
{
return std::abs(candidate.flagMcMatchRec()) == static_cast<int8_t>(BIT(aod::hf_cand_3prong::DecayType::LcToPKPi));
return std::abs(candidate.flagMcMatchRec()) == static_cast<int8_t>(hf_decay::hf_cand_3prong::DecayChannelMain::LcToPKPi);
}

/// Checks whether the candidate is in the signal region of either the Ds or D+ decay
Expand Down Expand Up @@ -673,9 +689,9 @@ struct HfTaskDs {
// MC gen.
for (const auto& particle : mcParticles) {

if (std::abs(particle.flagMcMatchGen()) == 1 << aod::hf_cand_3prong::DecayType::DsToKKPi) {
if (std::abs(particle.flagMcMatchGen()) == hf_decay::hf_cand_3prong::DecayChannelMain::DsToPiKK || std::abs(particle.flagMcMatchGen()) == hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKK) {
const auto& recoCollsPerMcColl = recoCollisions.sliceBy(colPerMcCollision, particle.mcCollision().globalIndex());
if (particle.flagMcDecayChanGen() == decayChannel || (fillDplusMc && particle.flagMcDecayChanGen() == (decayChannel + offsetDplusDecayChannel))) {
if (particle.flagMcDecayChanGen() == channelsResonant[Mother::Ds][decayChannel] || (fillDplusMc && particle.flagMcDecayChanGen() == channelsResonant[Mother::Dplus][decayChannel])) {
auto pt = particle.pt();
double y{0.f};

Expand All @@ -689,7 +705,7 @@ struct HfTaskDs {
occ = o2::hf_occupancy::getOccupancyGenColl(recoCollsPerMcColl, occEstimator);
}

if (particle.flagMcDecayChanGen() == decayChannel) {
if (particle.flagMcDecayChanGen() == channelsResonant[Mother::Ds][decayChannel]) {
y = RecoDecay::y(particle.pVector(), o2::constants::physics::MassDS);
if (yCandGenMax >= 0. && std::abs(y) > yCandGenMax) {
continue;
Expand Down
Loading
Loading