diff --git a/PWGHF/D2H/Tasks/taskSigmac.cxx b/PWGHF/D2H/Tasks/taskSigmac.cxx index b7d77b1fea6..e7083d7283e 100644 --- a/PWGHF/D2H/Tasks/taskSigmac.cxx +++ b/PWGHF/D2H/Tasks/taskSigmac.cxx @@ -15,6 +15,8 @@ /// /// \author Mattia Faggin , University and INFN PADOVA +#include + #include "CommonConstants/PhysicsConstants.h" #include "Framework/AnalysisTask.h" #include "Framework/HistogramRegistry.h" @@ -39,9 +41,15 @@ struct HfTaskSigmac { /// consider the new parametrization of the fiducial acceptance (to be seen for reco signal in MC) Configurable yCandGenMax{"yCandGenMax", -1, "Maximum generated Sc rapidity"}; Configurable yCandRecoMax{"yCandRecoMax", -1, "Maximum Sc candidate rapidity"}; + Configurable enableTHn{"enableTHn", false, "enable the usage of THn for Λc+ and Σc0,++"}; + + HfHelper hfHelper; + bool isMc; + static constexpr std::size_t NDaughters{2u}; + + using RecoLc = soa::Join; /// THn for candidate Λc+ and Σc0,++ cut variation - Configurable enableTHn{"enableTHn", false, "enable the usage of THn for Λc+ and Σc0,++"}; ConfigurableAxis thnConfigAxisPt{"thnConfigAxisPt", {16, 0, 16}, ""}; ConfigurableAxis thnConfigAxisGenPt{"thnConfigAxisGenPt", {240, 0, 24}, "Gen pt prompt"}; ConfigurableAxis thnConfigAxisGenPtB{"thnConfigAxisGenPtB", {800, 0, 80}, "Gen pt non-prompt"}; @@ -53,8 +61,23 @@ struct HfTaskSigmac { ConfigurableAxis configAxisDeltaMassSigmaC{"configAxisDeltaMassSigmaC", {200, 0.13, 0.23}, ""}; ConfigurableAxis thnConfigAxisBdtScoreLcBkg{"thnConfigAxisBdtScoreLcBkg", {100, 0., 1.}, ""}; ConfigurableAxis thnConfigAxisBdtScoreLcNonPrompt{"thnConfigAxisBdtScoreLcNonPrompt", {100, 0., 1.}, ""}; - - HfHelper hfHelper; + const AxisSpec thnAxisMassLambdaC{configAxisMassLambdaC, "inv. mass (p K #pi) (GeV/#it{c}^{2})"}; + const AxisSpec thnAxisPtLambdaC{thnConfigAxisPt, "#it{p}_{T}(#Lambda_{c}^{+}) (GeV/#it{c})"}; + const AxisSpec thnAxisPtSigmaC{thnConfigAxisPt, "#it{p}_{T}(#Sigma_{c}^{0,++}) (GeV/#it{c})"}; + const AxisSpec thnAxisDecLength{thnConfigAxisDecLength, "decay length #Lambda_{c}^{+} (cm)"}; + const AxisSpec thnAxisDecLengthXY{thnConfigAxisDecLengthXY, "decay length XY #Lambda_{c}^{+} (cm)"}; + const AxisSpec thnAxisCPA{thnConfigAxisCPA, "cosine of pointing angle #Lambda_{c}^{+}"}; + const AxisSpec thnAxisCPAXY{thnConfigAxisCPAXY, "cosine of pointing angle XY #Lambda_{c}^{+}"}; + const AxisSpec thnAxisOriginMc{3, -0.5, 2.5, "0: none, 1: prompt, 2: non-prompt"}; + const AxisSpec thnAxisChargeSigmaC{3, -0.5, 2.5, "#Sigma_{c}-baryon charge"}; + const AxisSpec thnAxisChannel{4, -0.5, 3.5, "0: direct 1,2,3: resonant"}; + const AxisSpec thnAxisBdtScoreLcBkg{thnConfigAxisBdtScoreLcBkg, "BDT bkg score (Lc)"}; + const AxisSpec thnAxisBdtScoreLcNonPrompt{thnConfigAxisBdtScoreLcNonPrompt, "BDT non-prompt score (Lc)"}; + const AxisSpec thnAxisGenPtLambdaC{thnConfigAxisGenPt, "#it{p}_{T}^{gen}(#Lambda_{c}^{+}) (GeV/#it{c})"}; + const AxisSpec thnAxisGenPtSigmaC{thnConfigAxisGenPt, "#it{p}_{T}^{gen}(#Sigma_{c}^{0,++}) (GeV/#it{c})"}; + const AxisSpec thnAxisGenPtLambdaCBMother{thnConfigAxisGenPtB, "#it{p}_{T}^{gen}(#Lambda_{c}^{+} B mother) (GeV/#it{c})"}; + const AxisSpec thnAxisGenPtSigmaCBMother{thnConfigAxisGenPtB, "#it{p}_{T}^{gen}(#Sigma_{c}^{0,++} B mother) (GeV/#it{c})"}; + const AxisSpec thnAxisGenSigmaCSpecies = {o2::aod::hf_cand_sigmac::Species::NSpecies, -0.5f, +o2::aod::hf_cand_sigmac::Species::NSpecies - 0.5f, "bin 1: #Sigma_{c}(2455), bin 2: #Sigma_{c}(2520)"}; /// analysis histograms HistogramRegistry registry{ @@ -99,10 +122,6 @@ struct HfTaskSigmac { {"Data/hPhiLcFromSc0PlusPlus", "#Lambda_{c}^{+} #leftarrow #Sigma_{c}^{0,++} candidates; #varphi(#Lambda_{c}^{+} #leftarrow #Sigma_{c}^{0,++}); entries;", {HistType::kTH1D, {{72, 0, constants::math::TwoPI}}}}}}; //{"Data/hDeltaMassLcFromSc0PlusPlus", "#Lambda_{c}^{+} #leftarrow #Sigma_{c}^{0,++} candidates; #it{M}(pK#pi#pi) - #it{M}(pK#pi) (GeV/#it{c}^{2}); #it{p}_{T}(#Lambda_{c}^{+} #leftarrow #Sigma_{c}^{0,++}) (GeV/#it{c});", {HistType::kTH2D, {axisDeltaMassSigmaC, {36, 0., 36.}}}}}}; - using RecoLc = soa::Join; - - bool isMc; - /// @brief init function, to define the additional analysis histograms /// @param void init(InitContext&) @@ -246,37 +265,23 @@ struct HfTaskSigmac { /// THn for candidate Λc+ and Σc0,++ cut variation if (enableTHn) { - const AxisSpec thnAxisMassLambdaC{configAxisMassLambdaC, "inv. mass (p K #pi) (GeV/#it{c}^{2})"}; - const AxisSpec thnAxisPtLambdaC{thnConfigAxisPt, "#it{p}_{T}(#Lambda_{c}^{+}) (GeV/#it{c})"}; - const AxisSpec thnAxisPtSigmaC{thnConfigAxisPt, "#it{p}_{T}(#Sigma_{c}^{0,++}) (GeV/#it{c})"}; - const AxisSpec thnAxisDecLength{thnConfigAxisDecLength, "decay length #Lambda_{c}^{+} (cm)"}; - const AxisSpec thnAxisDecLengthXY{thnConfigAxisDecLengthXY, "decay length XY #Lambda_{c}^{+} (cm)"}; - const AxisSpec thnAxisCPA{thnConfigAxisCPA, "cosine of pointing angle #Lambda_{c}^{+}"}; - const AxisSpec thnAxisCPAXY{thnConfigAxisCPAXY, "cosine of pointing angle XY #Lambda_{c}^{+}"}; - const AxisSpec thnAxisOriginMc{3, -0.5, 2.5, "0: none, 1: prompt, 2: non-prompt"}; - const AxisSpec thnAxisChargeSigmaC{3, -0.5, 2.5, "#Sigma_{c}-baryon charge"}; - const AxisSpec thnAxisChannel{4, -0.5, 3.5, "0: direct 1,2,3: resonant"}; - const AxisSpec thnAxisBdtScoreLcBkg{thnConfigAxisBdtScoreLcBkg, "BDT bkg score (Lc)"}; - const AxisSpec thnAxisBdtScoreLcNonPrompt{thnConfigAxisBdtScoreLcNonPrompt, "BDT non-prompt score (Lc)"}; - const AxisSpec thnAxisGenPtLambdaC{thnConfigAxisGenPt, "#it{p}_{T}^{gen}(#Lambda_{c}^{+}) (GeV/#it{c})"}; - const AxisSpec thnAxisGenPtSigmaC{thnConfigAxisGenPt, "#it{p}_{T}^{gen}(#Sigma_{c}^{0,++}) (GeV/#it{c})"}; - const AxisSpec thnAxisGenPtLambdaCBMother{thnConfigAxisGenPtB, "#it{p}_{T}^{gen}(#Lambda_{c}^{+} B mother) (GeV/#it{c})"}; - const AxisSpec thnAxisGenPtSigmaCBMother{thnConfigAxisGenPtB, "#it{p}_{T}^{gen}(#Sigma_{c}^{0,++} B mother) (GeV/#it{c})"}; std::vector axesLambdaCWithMl = {thnAxisPtLambdaC, thnAxisMassLambdaC, thnAxisBdtScoreLcBkg, thnAxisBdtScoreLcNonPrompt, thnAxisOriginMc, thnAxisChannel}; std::vector axesSigmaCWithMl = {thnAxisPtLambdaC, axisDeltaMassSigmaC, thnAxisBdtScoreLcBkg, thnAxisBdtScoreLcNonPrompt, thnAxisOriginMc, thnAxisChannel, thnAxisPtSigmaC, thnAxisChargeSigmaC}; std::vector axesLambdaCWoMl = {thnAxisPtLambdaC, thnAxisMassLambdaC, thnAxisDecLength, thnAxisDecLengthXY, thnAxisCPA, thnAxisCPAXY, thnAxisOriginMc, thnAxisChannel}; std::vector axesSigmaCWoMl = {thnAxisPtLambdaC, axisDeltaMassSigmaC, thnAxisDecLength, thnAxisDecLengthXY, thnAxisCPA, thnAxisCPAXY, thnAxisOriginMc, thnAxisChannel, thnAxisPtSigmaC, thnAxisChargeSigmaC}; if (isMc) { - registry.add("hnLambdaCGen", "THn for Lambdac gen", HistType::kTHnSparseF, {thnAxisGenPtLambdaC, thnAxisGenPtLambdaCBMother, thnAxisOriginMc, thnAxisChannel}); - registry.add("hnSigmaCGen", "THn for Sigmac gen", HistType::kTHnSparseF, {thnAxisGenPtSigmaC, thnAxisGenPtSigmaCBMother, thnAxisOriginMc, thnAxisChannel, thnAxisGenPtLambdaC, thnAxisChargeSigmaC}); + registry.add("MC/generated/hnLambdaCGen", "THn for Lambdac gen", HistType::kTHnSparseF, {thnAxisGenPtLambdaC, thnAxisGenPtLambdaCBMother, thnAxisOriginMc, thnAxisChannel}); + registry.add("MC/generated/hnSigmaCGen", "THn for Sigmac gen", HistType::kTHnSparseF, {thnAxisGenPtSigmaC, thnAxisGenPtSigmaCBMother, thnAxisOriginMc, thnAxisChannel, thnAxisGenPtLambdaC, thnAxisChargeSigmaC, thnAxisGenSigmaCSpecies}); if (doprocessMcWithMl) { axesLambdaCWithMl.push_back(thnAxisGenPtLambdaCBMother); axesSigmaCWithMl.push_back(thnAxisGenPtSigmaCBMother); + axesSigmaCWithMl.push_back(thnAxisGenSigmaCSpecies); registry.add("hnLambdaC", "THn for Lambdac", HistType::kTHnSparseF, axesLambdaCWithMl); registry.add("hnSigmaC", "THn for Sigmac", HistType::kTHnSparseF, axesSigmaCWithMl); } else { axesLambdaCWoMl.push_back(thnAxisGenPtLambdaCBMother); axesSigmaCWoMl.push_back(thnAxisGenPtSigmaCBMother); + axesSigmaCWoMl.push_back(thnAxisGenSigmaCSpecies); registry.add("hnLambdaC", "THn for Lambdac", HistType::kTHnSparseF, axesLambdaCWoMl); registry.add("hnSigmaC", "THn for Sigmac", HistType::kTHnSparseF, axesSigmaCWoMl); } @@ -300,16 +305,16 @@ struct HfTaskSigmac { /// @param candSc Sc candidate /// @return 0: none; 1: only Λc+ → pK-π+ possible; 2: Λc+ → π+K-p possible; 3: both possible template - int isDecayToPKPiToPiKP(L& candidateLc, S& candSc) + int8_t isDecayToPKPiToPiKP(L& candidateLc, S& candSc) { - int channel = 0; + int8_t channel = 0; if ((candidateLc.isSelLcToPKPi() >= 1) && candSc.statusSpreadLcMinvPKPiFromPDG()) { // Λc+ → pK-π+ and within the requested mass to build the Σc0,++ - channel += 1; + SETBIT(channel, o2::aod::hf_cand_sigmac::Decays::PKPi); } if ((candidateLc.isSelLcToPiKP() >= 1) && candSc.statusSpreadLcMinvPiKPFromPDG()) { // Λc+ → π+K-p and within the requested mass to build the Σc0,++ - channel += 2; + SETBIT(channel, o2::aod::hf_cand_sigmac::Decays::PiKP); } return channel; /// 0: none; 1: pK-π+ only; 2: π+K-p only; 3: both possible } @@ -326,6 +331,12 @@ struct HfTaskSigmac { /// loop over the candidate Σc0,++ for (const auto& candSc : candidatesSc) { + /// rapidity selection on Σc0,++ + /// NB: since in data we cannot tag Sc(2455) and Sc(2520), then we use only Sc(2455) for y selection on reconstructed signal + if (yCandRecoMax >= 0. && std::abs(hfHelper.ySc0(candSc)) > yCandRecoMax && std::abs(hfHelper.yScPlusPlus(candSc)) > yCandRecoMax) { + continue; + } + const int8_t chargeSc = candSc.charge(); // either Σc0 or Σc++ /// get the candidate Λc+ used to build the candidate Σc0,++ @@ -333,7 +344,7 @@ struct HfTaskSigmac { const auto& candidateLc = candSc.prongLc_as(); // const int iscandidateLcpKpi = (candidateLc.isSelLcToPKPi() >= 1) && candSc.statusSpreadLcMinvPKPiFromPDG(); // Λc+ → pK-π+ and within the requested mass to build the Σc0,++ // const int iscandidateLcpiKp = (candidateLc.isSelLcToPiKP() >= 1) && candSc.statusSpreadLcMinvPiKPFromPDG(); // Λc+ → π+K-p and within the requested mass to build the Σc0,++ - const int isCandPKPiPiKP = isDecayToPKPiToPiKP(candidateLc, candSc); + const int8_t isCandPKPiPiKP = isDecayToPKPiToPiKP(candidateLc, candSc); double massSc(-1.), massLc(-1.), deltaMass(-1.); double ptSc(candSc.pt()), ptLc(candidateLc.pt()); double etaSc(candSc.eta()), etaLc(candidateLc.eta()); @@ -342,12 +353,12 @@ struct HfTaskSigmac { double decLengthLc(candidateLc.decayLength()), decLengthXYLc(candidateLc.decayLengthXY()); double cpaLc(candidateLc.cpa()), cpaXYLc(candidateLc.cpaXY()); /// candidate Λc+ → pK-π+ (and charge conjugate) within the range of M(pK-π+) chosen in the Σc0,++ builder - if (isCandPKPiPiKP == 1 || isCandPKPiPiKP == 3) { + if (TESTBIT(isCandPKPiPiKP, o2::aod::hf_cand_sigmac::Decays::PKPi)) { massSc = hfHelper.invMassScRecoLcToPKPi(candSc, candidateLc); massLc = hfHelper.invMassLcToPKPi(candidateLc); deltaMass = massSc - massLc; /// fill the histograms - if (chargeSc == 0) { + if (chargeSc == o2::aod::hf_cand_sigmac::ChargeNull) { registry.fill(HIST("Data/hPtSc0"), ptSc); registry.fill(HIST("Data/hEtaSc0"), etaSc); registry.fill(HIST("Data/hPhiSc0"), phiSc); @@ -415,12 +426,12 @@ struct HfTaskSigmac { } } /// end candidate Λc+ → pK-π+ (and charge conjugate) /// candidate Λc+ → π+K-p (and charge conjugate) within the range of M(π+K-p) chosen in the Σc0,++ builder - if (isCandPKPiPiKP == 2 || isCandPKPiPiKP == 3) { + if (TESTBIT(isCandPKPiPiKP, o2::aod::hf_cand_sigmac::Decays::PiKP)) { massSc = hfHelper.invMassScRecoLcToPiKP(candSc, candidateLc); massLc = hfHelper.invMassLcToPiKP(candidateLc); deltaMass = massSc - massLc; /// fill the histograms - if (chargeSc == 0) { + if (chargeSc == o2::aod::hf_cand_sigmac::ChargeNull) { registry.fill(HIST("Data/hPtSc0"), ptSc); registry.fill(HIST("Data/hEtaSc0"), etaSc); registry.fill(HIST("Data/hPhiSc0"), phiSc); @@ -487,7 +498,7 @@ struct HfTaskSigmac { } } } /// end candidate Λc+ → π+K-p (and charge conjugate) - } /// end loop over the candidate Σc0,++ + } /// end loop over the candidate Σc0,++ /// THn for candidate Λc+ cut variation w/o Σc0,++ mass-window cut if (enableTHn) { @@ -534,7 +545,7 @@ struct HfTaskSigmac { } } } /// end THn for candidate Λc+ cut variation w/o Σc0,++ mass-window cut - }; /// end fillHistosData + }; /// end fillHistosData /// @brief function to fill the histograms needed in analysis (MC) /// @param candidatesSc are the reconstructed candidate Σc0,++ with MC info @@ -553,9 +564,11 @@ struct HfTaskSigmac { for (const auto& particle : mcParticlesSc) { /// reject immediately particles different from Σc0,++ - bool isSc0Gen = (std::abs(particle.flagMcMatchGen()) == (1 << aod::hf_cand_sigmac::DecayType::Sc0ToPKPiPi)); - bool isScPlusPlusGen = (std::abs(particle.flagMcMatchGen()) == (1 << aod::hf_cand_sigmac::DecayType::ScplusplusToPKPiPi)); - if (!isSc0Gen && !isScPlusPlusGen) + bool isSc0Gen = (std::abs(particle.flagMcMatchGen()) == BIT(aod::hf_cand_sigmac::DecayType::Sc0ToPKPiPi)); + bool isScStar0Gen = (std::abs(particle.flagMcMatchGen()) == BIT(aod::hf_cand_sigmac::DecayType::ScStar0ToPKPiPi)); + bool isScPlusPlusGen = (std::abs(particle.flagMcMatchGen()) == BIT(aod::hf_cand_sigmac::DecayType::ScplusplusToPKPiPi)); + bool isScStarPlusPlusGen = (std::abs(particle.flagMcMatchGen()) == BIT(aod::hf_cand_sigmac::DecayType::ScStarPlusPlusToPKPiPi)); + if (!isSc0Gen && !isScPlusPlusGen && !isScStar0Gen && !isScStarPlusPlusGen) continue; /// look for generated particles in acceptance @@ -569,8 +582,20 @@ struct HfTaskSigmac { OR consider the new parametrization of the fiducial acceptance (to be seen for reco signal in MC) */ - if (yCandGenMax >= 0. && std::abs(RecoDecay::y(particle.pVector(), o2::constants::physics::MassSigmaC0)) > yCandGenMax) { - continue; + if (yCandGenMax >= 0.) { + double mass = -1; + if (isSc0Gen) { + mass = o2::constants::physics::MassSigmaC0; + } else if (isScPlusPlusGen) { + mass = o2::constants::physics::MassSigmaCPlusPlus; + } else if (isScStar0Gen) { + mass = o2::constants::physics::MassSigmaCStar0; + } else if (isScStarPlusPlusGen) { + mass = o2::constants::physics::MassSigmaCStarPlusPlus; + } + if (mass > -1. && std::abs(RecoDecay::y(particle.pVector(), mass)) > yCandGenMax) { + continue; + } } /// Get the kinematic information of Σc0,++ and the daughters @@ -579,7 +604,7 @@ struct HfTaskSigmac { double ptGenSc(particle.pt()), etaGenSc(particle.eta()), phiGenSc(particle.phi()); double ptGenScBMother(-1.); auto arrayDaughtersIds = particle.daughtersIds(); - if (arrayDaughtersIds.size() != 2) { + if (arrayDaughtersIds.size() != NDaughters) { /// This should never happen LOG(fatal) << "generated Σc0,++ has a number of daughter particles different than 2"; continue; @@ -617,7 +642,13 @@ struct HfTaskSigmac { } /// Fill histograms - if (isSc0Gen) { + int sigmacSpecies = -1; + if (isSc0Gen || isScPlusPlusGen) { + sigmacSpecies = o2::aod::hf_cand_sigmac::Sc2455; + } else if (isScStar0Gen || isScStarPlusPlusGen) { + sigmacSpecies = o2::aod::hf_cand_sigmac::Sc2520; + } + if (isSc0Gen || isScStar0Gen) { /// Generated Σc0 and Λc+ ← Σc0 signals registry.fill(HIST("MC/generated/hPtGenSc0Sig"), ptGenSc, origin, channel); registry.fill(HIST("MC/generated/hEtaGenSc0Sig"), etaGenSc, origin, channel); @@ -639,12 +670,19 @@ struct HfTaskSigmac { registry.fill(HIST("MC/generated/hEtaGenLcFromSc0PlusPlusSig"), etaGenLc, origin, channel); registry.fill(HIST("MC/generated/hPhiGenLcFromSc0PlusPlusSig"), phiGenLc, origin, channel); /// Generated Λc+ ← Σc0,++ signal if (origin == RecoDecay::OriginType::Prompt) { - registry.fill(HIST("hnSigmaCGen"), ptGenSc, ptGenScBMother, origin, channel, ptGenLc, 0); + registry.fill(HIST("MC/generated/hnSigmaCGen"), ptGenSc, ptGenScBMother, origin, channel, ptGenLc, 0, sigmacSpecies); } else { ptGenScBMother = mcParticlesSc.rawIteratorAt(particle.idxBhadMotherPart()).pt(); - registry.fill(HIST("hnSigmaCGen"), ptGenSc, ptGenScBMother, origin, channel, ptGenLc, 0); + registry.fill(HIST("MC/generated/hnSigmaCGen"), ptGenSc, ptGenScBMother, origin, channel, ptGenLc, 0, sigmacSpecies); } - } else if (isScPlusPlusGen) { + + // debug -- uncomment if needed + // it should be solved after the implementation of ev. selection for generated SigmaC particles + // if(origin != RecoDecay::OriginType::Prompt && origin != RecoDecay::OriginType::NonPrompt) { + // LOG(info) << " --> (Sc0 gen) origin " << static_cast(origin) << ", particle.originMcGen() " << static_cast(particle.originMcGen()) << ", particle.flagMcMatchGen() " << static_cast(particle.flagMcMatchGen()) << ", pdg " << particle.pdgCode(); + //} + + } else if (isScPlusPlusGen || isScStarPlusPlusGen) { /// Generated Σc++ and Λc+ ← Σc++ signals registry.fill(HIST("MC/generated/hPtGenScPlusPlusSig"), ptGenSc, origin, channel); registry.fill(HIST("MC/generated/hEtaGenScPlusPlusSig"), etaGenSc, origin, channel); @@ -666,18 +704,24 @@ struct HfTaskSigmac { registry.fill(HIST("MC/generated/hEtaGenLcFromSc0PlusPlusSig"), etaGenLc, origin, channel); registry.fill(HIST("MC/generated/hPhiGenLcFromSc0PlusPlusSig"), phiGenLc, origin, channel); /// Generated Λc+ ← Σc0,++ signal if (origin == RecoDecay::OriginType::Prompt) { - registry.fill(HIST("hnSigmaCGen"), ptGenSc, ptGenScBMother, origin, channel, ptGenLc, 2); + registry.fill(HIST("MC/generated/hnSigmaCGen"), ptGenSc, ptGenScBMother, origin, channel, ptGenLc, 2, sigmacSpecies); } else { ptGenScBMother = mcParticlesSc.rawIteratorAt(particle.idxBhadMotherPart()).pt(); - registry.fill(HIST("hnSigmaCGen"), ptGenSc, ptGenScBMother, origin, channel, ptGenLc, 2); + registry.fill(HIST("MC/generated/hnSigmaCGen"), ptGenSc, ptGenScBMother, origin, channel, ptGenLc, 2, sigmacSpecies); } + + // debug -- uncomment if needed + // it should be solved after the implementation of ev. selection for generated SigmaC particles + // if(origin != RecoDecay::OriginType::Prompt && origin != RecoDecay::OriginType::NonPrompt) { + // LOG(info) << " --> (Sc++ gen) origin " << static_cast(origin) << ", particle.originMcGen() " << static_cast(particle.originMcGen()) << ", particle.flagMcMatchGen() " << static_cast(particle.flagMcMatchGen()) << ", pdg " << particle.pdgCode(); + //} } } /// end loop over Sc generated particles /// loop over Lc generated particles for (const auto& particle : mcParticlesLc) { - if (std::abs(particle.flagMcMatchGen()) != 1 << aod::hf_cand_3prong::DecayType::LcToPKPi) { + if (std::abs(particle.flagMcMatchGen()) != BIT(aod::hf_cand_3prong::DecayType::LcToPKPi)) { continue; } if (yCandGenMax >= 0. && std::abs(RecoDecay::y(particle.pVector(), o2::constants::physics::MassLambdaCPlus)) > yCandGenMax) { @@ -687,10 +731,10 @@ struct HfTaskSigmac { int origin = particle.originMcGen(); int channel = particle.flagMcDecayChanGen(); if (origin == RecoDecay::OriginType::Prompt) { - registry.fill(HIST("hnLambdaCGen"), ptGenLc, ptGenLcBMother, origin, channel); + registry.fill(HIST("MC/generated/hnLambdaCGen"), ptGenLc, ptGenLcBMother, origin, channel); } else { ptGenLcBMother = mcParticlesLc.rawIteratorAt(particle.idxBhadMotherPart()).pt(); - registry.fill(HIST("hnLambdaCGen"), ptGenLc, ptGenLcBMother, origin, channel); + registry.fill(HIST("MC/generated/hnLambdaCGen"), ptGenLc, ptGenLcBMother, origin, channel); } } /// end loop over Lc generated particles @@ -698,10 +742,12 @@ struct HfTaskSigmac { for (const auto& candSc : candidatesSc) { /// Candidate selected as Σc0 and/or Σc++ - if (!(candSc.hfflag() & 1 << aod::hf_cand_sigmac::DecayType::Sc0ToPKPiPi) && !(candSc.hfflag() & 1 << aod::hf_cand_sigmac::DecayType::ScplusplusToPKPiPi)) { + if (!(candSc.hfflag() & BIT(aod::hf_cand_sigmac::DecayType::Sc0ToPKPiPi)) && !(candSc.hfflag() & BIT(aod::hf_cand_sigmac::DecayType::ScplusplusToPKPiPi)) && // Σc0,++(2455) + !(candSc.hfflag() & BIT(aod::hf_cand_sigmac::DecayType::ScStar0ToPKPiPi)) && !(candSc.hfflag() & BIT(aod::hf_cand_sigmac::DecayType::ScStarPlusPlusToPKPiPi))) { // Σc0,++(2520) continue; } /// rapidity selection on Σc0,++ + /// NB: since in data we cannot tag Sc(2455) and Sc(2520), then we use only Sc(2455) for y selection on reconstructed signal if (yCandRecoMax >= 0. && std::abs(hfHelper.ySc0(candSc)) > yCandRecoMax && std::abs(hfHelper.yScPlusPlus(candSc)) > yCandRecoMax) { continue; } @@ -712,14 +758,28 @@ struct HfTaskSigmac { /// get the candidate Λc+ used to build the Σc0 /// and understand which mass hypotheses are possible const auto& candidateLc = candSc.prongLc_as(); - const int isCandPKPiPiKP = isDecayToPKPiToPiKP(candidateLc, candSc); + const int8_t isCandPKPiPiKP = isDecayToPKPiToPiKP(candidateLc, candSc); // candidateLc.flagMcDecayChanRec(); - /// Reconstructed Σc0 signal - if (std::abs(candSc.flagMcMatchRec()) == 1 << aod::hf_cand_sigmac::DecayType::Sc0ToPKPiPi && (chargeSc == 0)) { + bool isTrueSc0Reco = std::abs(candSc.flagMcMatchRec()) == BIT(aod::hf_cand_sigmac::DecayType::Sc0ToPKPiPi); + bool isTrueScStar0Reco = std::abs(candSc.flagMcMatchRec()) == BIT(aod::hf_cand_sigmac::DecayType::ScStar0ToPKPiPi); + bool isTrueScPlusPlusReco = std::abs(candSc.flagMcMatchRec()) == BIT(aod::hf_cand_sigmac::DecayType::ScplusplusToPKPiPi); + bool isTrueScStarPlusPlusReco = std::abs(candSc.flagMcMatchRec()) == BIT(aod::hf_cand_sigmac::DecayType::ScStarPlusPlusToPKPiPi); + int sigmacSpecies = -1; + if ((isTrueSc0Reco || isTrueScStar0Reco) && (chargeSc == o2::aod::hf_cand_sigmac::ChargeNull)) { + /// Reconstructed Σc0 signal // Get the corresponding MC particle for Sc, found as the mother of the soft pion - auto indexMcScRec = RecoDecay::getMother(mcParticles, candSc.prong1_as().mcParticle(), o2::constants::physics::Pdg::kSigmaC0, true); + int indexMcScRec = -1; + if (isTrueSc0Reco) { + // Σc0(2455) + indexMcScRec = RecoDecay::getMother(mcParticles, candSc.prong1_as().mcParticle(), o2::constants::physics::Pdg::kSigmaC0, true); + sigmacSpecies = o2::aod::hf_cand_sigmac::Sc2455; + } else if (isTrueScStar0Reco) { + // Σc0(2520) + indexMcScRec = RecoDecay::getMother(mcParticles, candSc.prong1_as().mcParticle(), o2::constants::physics::Pdg::kSigmaCStar0, true); + sigmacSpecies = o2::aod::hf_cand_sigmac::Sc2520; + } auto particleSc = mcParticles.rawIteratorAt(indexMcScRec); // Get the corresponding MC particle for Lc auto arrayDaughtersLc = std::array{candidateLc.template prong0_as(), candidateLc.template prong1_as(), candidateLc.template prong2_as()}; @@ -743,7 +803,7 @@ struct HfTaskSigmac { auto channel = candidateLc.flagMcDecayChanRec(); /// 0: direct; 1: Λc± → p± K*; 2: Λc± → Δ(1232)±± K∓; 3: Λc± → Λ(1520) π± /// candidate Λc+ → pK-π+ (and charge conjugate) within the range of M(pK-π+) chosen in the Σc0,++ builder - if ((isCandPKPiPiKP == 1 || isCandPKPiPiKP == 3) && std::abs(candidateLc.template prong0_as().mcParticle().pdgCode()) == kProton) { + if ((TESTBIT(isCandPKPiPiKP, o2::aod::hf_cand_sigmac::Decays::PKPi)) && std::abs(candidateLc.template prong0_as().mcParticle().pdgCode()) == kProton) { massSc = hfHelper.invMassScRecoLcToPKPi(candSc, candidateLc); massLc = hfHelper.invMassLcToPKPi(candidateLc); deltaMass = massSc - massLc; @@ -808,16 +868,16 @@ struct HfTaskSigmac { outputMl.at(0) = candidateLc.mlProbLcToPKPi()[0]; /// bkg score outputMl.at(1) = candidateLc.mlProbLcToPKPi()[2]; /// non-prompt score } - registry.get(HIST("hnSigmaC"))->Fill(ptLc, deltaMass, outputMl.at(0), outputMl.at(1), origin, channel, ptSc, std::abs(chargeSc), candSc.ptBhadMotherPart()); + registry.get(HIST("hnSigmaC"))->Fill(ptLc, deltaMass, outputMl.at(0), outputMl.at(1), origin, channel, ptSc, std::abs(chargeSc), candSc.ptBhadMotherPart(), sigmacSpecies); } else { /// fill w/o BDT information - registry.get(HIST("hnSigmaC"))->Fill(ptLc, deltaMass, decLengthLc, decLengthXYLc, cpaLc, cpaXYLc, origin, channel, ptSc, std::abs(chargeSc), candSc.ptBhadMotherPart()); + registry.get(HIST("hnSigmaC"))->Fill(ptLc, deltaMass, decLengthLc, decLengthXYLc, cpaLc, cpaXYLc, origin, channel, ptSc, std::abs(chargeSc), candSc.ptBhadMotherPart(), sigmacSpecies); } } } /// end candidate Λc+ → pK-π+ (and charge conjugate) /// candidate Λc+ → π+K-p (and charge conjugate) within the range of M(π+K-p) chosen in the Σc0,++ builder - if ((isCandPKPiPiKP == 2 || isCandPKPiPiKP == 3) && std::abs(candidateLc.template prong0_as().mcParticle().pdgCode()) == kPiPlus) { + if ((TESTBIT(isCandPKPiPiKP, o2::aod::hf_cand_sigmac::Decays::PiKP)) && std::abs(candidateLc.template prong0_as().mcParticle().pdgCode()) == kPiPlus) { massSc = hfHelper.invMassScRecoLcToPiKP(candSc, candidateLc); massLc = hfHelper.invMassLcToPiKP(candidateLc); deltaMass = massSc - massLc; @@ -882,19 +942,28 @@ struct HfTaskSigmac { outputMl.at(0) = candidateLc.mlProbLcToPiKP()[0]; /// bkg score outputMl.at(1) = candidateLc.mlProbLcToPiKP()[2]; /// non-prompt score } - registry.get(HIST("hnSigmaC"))->Fill(ptLc, deltaMass, outputMl.at(0), outputMl.at(1), origin, channel, ptSc, std::abs(chargeSc), candSc.ptBhadMotherPart()); + registry.get(HIST("hnSigmaC"))->Fill(ptLc, deltaMass, outputMl.at(0), outputMl.at(1), origin, channel, ptSc, std::abs(chargeSc), candSc.ptBhadMotherPart(), sigmacSpecies); } else { /// fill w/o BDT information - registry.get(HIST("hnSigmaC"))->Fill(ptLc, deltaMass, decLengthLc, decLengthXYLc, cpaLc, cpaXYLc, origin, channel, ptSc, std::abs(chargeSc), candSc.ptBhadMotherPart()); + registry.get(HIST("hnSigmaC"))->Fill(ptLc, deltaMass, decLengthLc, decLengthXYLc, cpaLc, cpaXYLc, origin, channel, ptSc, std::abs(chargeSc), candSc.ptBhadMotherPart(), sigmacSpecies); } } } /// end candidate Λc+ → π+K-p (and charge conjugate) /// end reconstructed Σc0 signal - } else if (std::abs(candSc.flagMcMatchRec()) == 1 << aod::hf_cand_sigmac::DecayType::ScplusplusToPKPiPi && (std::abs(chargeSc) == 2)) { + } else if ((isTrueScPlusPlusReco || isTrueScStarPlusPlusReco) && (std::abs(chargeSc) == o2::aod::hf_cand_sigmac::ChargePlusPlus)) { /// Reconstructed Σc++ signal // Get the corresponding MC particle for Sc, found as the mother of the soft pion - auto indexMcScRec = RecoDecay::getMother(mcParticles, candSc.prong1_as().mcParticle(), o2::constants::physics::Pdg::kSigmaCPlusPlus, true); + int indexMcScRec = -1; + if (isTrueScPlusPlusReco) { + // Σc0(2455) + indexMcScRec = RecoDecay::getMother(mcParticles, candSc.prong1_as().mcParticle(), o2::constants::physics::Pdg::kSigmaCPlusPlus, true); + sigmacSpecies = o2::aod::hf_cand_sigmac::Sc2455; + } else if (isTrueScStarPlusPlusReco) { + // Σc0(2520) + indexMcScRec = RecoDecay::getMother(mcParticles, candSc.prong1_as().mcParticle(), o2::constants::physics::Pdg::kSigmaCStarPlusPlus, true); + sigmacSpecies = o2::aod::hf_cand_sigmac::Sc2520; + } auto particleSc = mcParticles.rawIteratorAt(indexMcScRec); // Get the corresponding MC particle for Lc auto arrayDaughtersLc = std::array{candidateLc.template prong0_as(), candidateLc.template prong1_as(), candidateLc.template prong2_as()}; @@ -918,7 +987,7 @@ struct HfTaskSigmac { auto channel = candidateLc.flagMcDecayChanRec(); /// 0: direct; 1: Λc± → p± K*; 2: Λc± → Δ(1232)±± K∓; 3: Λc± → Λ(1520) π± /// candidate Λc+ → pK-π+ (and charge conjugate) within the range of M(pK-π+) chosen in the Σc0,++ builder - if ((isCandPKPiPiKP == 1 || isCandPKPiPiKP == 3) && std::abs(candidateLc.template prong0_as().mcParticle().pdgCode()) == kProton) { + if ((TESTBIT(isCandPKPiPiKP, o2::aod::hf_cand_sigmac::Decays::PKPi)) && std::abs(candidateLc.template prong0_as().mcParticle().pdgCode()) == kProton) { massSc = hfHelper.invMassScRecoLcToPKPi(candSc, candidateLc); massLc = hfHelper.invMassLcToPKPi(candidateLc); deltaMass = massSc - massLc; @@ -983,16 +1052,16 @@ struct HfTaskSigmac { outputMl.at(0) = candidateLc.mlProbLcToPKPi()[0]; /// bkg score outputMl.at(1) = candidateLc.mlProbLcToPKPi()[2]; /// non-prompt score } - registry.get(HIST("hnSigmaC"))->Fill(ptLc, deltaMass, outputMl.at(0), outputMl.at(1), origin, channel, ptSc, std::abs(chargeSc), candSc.ptBhadMotherPart()); + registry.get(HIST("hnSigmaC"))->Fill(ptLc, deltaMass, outputMl.at(0), outputMl.at(1), origin, channel, ptSc, std::abs(chargeSc), candSc.ptBhadMotherPart(), sigmacSpecies); } else { /// fill w/o BDT information - registry.get(HIST("hnSigmaC"))->Fill(ptLc, deltaMass, decLengthLc, decLengthXYLc, cpaLc, cpaXYLc, origin, channel, ptSc, std::abs(chargeSc), candSc.ptBhadMotherPart()); + registry.get(HIST("hnSigmaC"))->Fill(ptLc, deltaMass, decLengthLc, decLengthXYLc, cpaLc, cpaXYLc, origin, channel, ptSc, std::abs(chargeSc), candSc.ptBhadMotherPart(), sigmacSpecies); } } } /// end candidate Λc+ → pK-π+ (and charge conjugate) /// candidate Λc+ → π+K-p (and charge conjugate) within the range of M(π+K-p) chosen in the Σc0,++ builder - if ((isCandPKPiPiKP == 2 || isCandPKPiPiKP == 3) && std::abs(candidateLc.template prong0_as().mcParticle().pdgCode()) == kPiPlus) { + if ((TESTBIT(isCandPKPiPiKP, o2::aod::hf_cand_sigmac::Decays::PiKP)) && std::abs(candidateLc.template prong0_as().mcParticle().pdgCode()) == kPiPlus) { massSc = hfHelper.invMassScRecoLcToPiKP(candSc, candidateLc); massLc = hfHelper.invMassLcToPiKP(candidateLc); deltaMass = massSc - massLc; @@ -1055,15 +1124,15 @@ struct HfTaskSigmac { outputMl.at(0) = candidateLc.mlProbLcToPiKP()[0]; /// bkg score outputMl.at(1) = candidateLc.mlProbLcToPiKP()[2]; /// non-prompt score } - registry.get(HIST("hnSigmaC"))->Fill(ptLc, deltaMass, outputMl.at(0), outputMl.at(1), origin, channel, ptSc, std::abs(chargeSc), candSc.ptBhadMotherPart()); + registry.get(HIST("hnSigmaC"))->Fill(ptLc, deltaMass, outputMl.at(0), outputMl.at(1), origin, channel, ptSc, std::abs(chargeSc), candSc.ptBhadMotherPart(), sigmacSpecies); } else { /// fill w/o BDT information - registry.get(HIST("hnSigmaC"))->Fill(ptLc, deltaMass, decLengthLc, decLengthXYLc, cpaLc, cpaXYLc, origin, channel, ptSc, std::abs(chargeSc), candSc.ptBhadMotherPart()); + registry.get(HIST("hnSigmaC"))->Fill(ptLc, deltaMass, decLengthLc, decLengthXYLc, cpaLc, cpaXYLc, origin, channel, ptSc, std::abs(chargeSc), candSc.ptBhadMotherPart(), sigmacSpecies); } } } /// end candidate Λc+ → π+K-p (and charge conjugate) - } /// end reconstructed Σc++ signal + } /// end reconstructed Σc++ signal } /// end loop on reconstructed Σc0,++ diff --git a/PWGHF/DataModel/CandidateReconstructionTables.h b/PWGHF/DataModel/CandidateReconstructionTables.h index 7ee144ca397..754de37ec45 100644 --- a/PWGHF/DataModel/CandidateReconstructionTables.h +++ b/PWGHF/DataModel/CandidateReconstructionTables.h @@ -2064,7 +2064,17 @@ DECLARE_SOA_COLUMN(OriginMcGen, originMcGen, int8_t); //! particle origin, // mapping of decay types enum DecayType { Sc0ToPKPiPi = 0, - ScplusplusToPKPiPi }; + ScplusplusToPKPiPi, + ScStar0ToPKPiPi, + ScStarPlusPlusToPKPiPi }; +enum Species : int { Sc2455 = 0, + Sc2520, + NSpecies }; +enum Decays : int { PKPi = 0, + PiKP, + NDecays }; +constexpr int ChargeNull = 0; +constexpr int ChargePlusPlus = 2; } // namespace hf_cand_sigmac // declare dedicated Σc0,++ decay candidate table @@ -2293,8 +2303,8 @@ DECLARE_SOA_DYNAMIC_COLUMN(PtSoftPi, ptSoftPi, [](float pxSoftPi, float pySoftPi DECLARE_SOA_DYNAMIC_COLUMN(PVecSoftPi, pVecSoftPi, [](float px, float py, float pz) -> std::array { return std::array{px, py, pz}; }); // MC matching result: -DECLARE_SOA_COLUMN(FlagMcMatchRec, flagMcMatchRec, int8_t); //! reconstruction level -DECLARE_SOA_COLUMN(FlagMcMatchGen, flagMcMatchGen, int8_t); //! generator level +DECLARE_SOA_COLUMN(FlagMcMatchRec, flagMcMatchRec, int8_t); //! reconstruction level +DECLARE_SOA_COLUMN(FlagMcMatchGen, flagMcMatchGen, int8_t); //! generator level DECLARE_SOA_COLUMN(FlagMcMatchRecD0, flagMcMatchRecD0, int8_t); //! reconstruction level DECLARE_SOA_COLUMN(FlagMcMatchGenD0, flagMcMatchGenD0, int8_t); //! generator level diff --git a/PWGHF/TableProducer/candidateCreatorSigmac0plusplus.cxx b/PWGHF/TableProducer/candidateCreatorSigmac0plusplus.cxx index e882dcd2dba..c3cfe2d6049 100644 --- a/PWGHF/TableProducer/candidateCreatorSigmac0plusplus.cxx +++ b/PWGHF/TableProducer/candidateCreatorSigmac0plusplus.cxx @@ -39,6 +39,7 @@ #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" #include "PWGHF/Utils/utilsBfieldCCDB.h" // for dca recalculation +#include "PWGHF/Utils/utilsEvSelHf.h" using namespace o2; using namespace o2::analysis; @@ -142,7 +143,8 @@ struct HfCandidateCreatorSigmac0plusplus { softPiCuts.SetMaxChi2PerClusterITS(softPiChi2Max); // ITS hitmap std::set setSoftPiItsHitMap; // = {}; - for (int idItsLayer = 0; idItsLayer < 7; idItsLayer++) { + constexpr std::size_t NLayersIts = 7; + for (std::size_t idItsLayer = 0u; idItsLayer < NLayersIts; idItsLayer++) { if (TESTBIT(softPiItsHitMap, idItsLayer)) { setSoftPiItsHitMap.insert(static_cast(idItsLayer)); } @@ -178,7 +180,7 @@ struct HfCandidateCreatorSigmac0plusplus { /// keep only the candidates flagged as possible Λc+ (and charge conj.) decaying into a charged pion, kaon and proton /// if not selected, skip it and go to the next one - if (!(candLc.hfflag() & 1 << aod::hf_cand_3prong::DecayType::LcToPKPi)) { + if (!(candLc.hfflag() & BIT(aod::hf_cand_3prong::DecayType::LcToPKPi))) { continue; } /// keep only the candidates Λc+ (and charge conj.) within the desired rapidity @@ -234,7 +236,7 @@ struct HfCandidateCreatorSigmac0plusplus { int chargeLc = candLc.template prong0_as().sign() + candLc.template prong1_as().sign() + candLc.template prong2_as().sign(); int chargeSoftPi = trackSoftPi.sign(); int8_t chargeSigmac = chargeLc + chargeSoftPi; - if (std::abs(chargeSigmac) != 0 && std::abs(chargeSigmac) != 2) { + if (std::abs(chargeSigmac) != o2::aod::hf_cand_sigmac::ChargeNull && std::abs(chargeSigmac) != o2::aod::hf_cand_sigmac::ChargePlusPlus) { /// this shall never happen LOG(fatal) << ">>> Sc candidate with charge +1 built, not possible! Charge Lc: " << chargeLc << ", charge soft pion: " << chargeSoftPi; } @@ -387,26 +389,31 @@ struct HfCandidateSigmac0plusplusMc { Produces rowMCMatchScRec; Produces rowMCMatchScGen; + o2::hf_evsel::HfEventSelectionMc hfEvSelMc; // mc event selection and monitoring + + using BCsInfo = soa::Join; using LambdacMc = soa::Join; // using LambdacMcGen = soa::Join; + using McCollisionsNoCents = soa::Join; + + PresliceUnsorted colPerMcCollision = aod::mccollisionlabel::mcCollisionId; - float zPvPosMax{1000.f}; + HistogramRegistry registry{"registry"}; /// @brief init function void init(InitContext& initContext) { const auto& workflows = initContext.services().get(); for (const DeviceSpec& device : workflows.devices) { - if (device.name.compare("hf-candidate-creator-3prong") == 0) { // here we assume that the hf-candidate-creator-3prong is in the workflow - for (const auto& option : device.options) { - if (option.name.compare("hfEvSel.zPvPosMax") == 0) { - zPvPosMax = option.defaultValue.get(); - break; - } - } + // here we assume that the hf-candidate-creator-3prong is in the workflow + // configure the ev. sel from that workflow + if (device.name.compare("hf-candidate-creator-3prong") == 0) { + hfEvSelMc.configureFromDevice(device); break; } } + + hfEvSelMc.addHistograms(registry); // particles monitoring } /// @brief dummy process function, to be run on data @@ -419,7 +426,9 @@ struct HfCandidateSigmac0plusplusMc { void processMc(aod::McParticles const& mcParticles, aod::TracksWMc const& tracks, LambdacMc const& candsLc /*, const LambdacMcGen&*/, - aod::McCollisions const&) + McCollisionsNoCents const& collInfos, + aod::McCollisions const&, + BCsInfo const&) { // Match reconstructed candidates. @@ -442,7 +451,7 @@ struct HfCandidateSigmac0plusplusMc { /// skip immediately the candidate Σc0,++ w/o a Λc+ matched to MC auto candLc = candSigmac.prongLc_as(); - if (!(std::abs(candLc.flagMcMatchRec()) == 1 << aod::hf_cand_3prong::DecayType::LcToPKPi)) { /// (*) + if (!(std::abs(candLc.flagMcMatchRec()) == BIT(aod::hf_cand_3prong::DecayType::LcToPKPi))) { /// (*) rowMCMatchScRec(flag, origin, -1.f, 0); continue; } @@ -453,25 +462,46 @@ struct HfCandidateSigmac0plusplusMc { candLc.prong2_as(), candSigmac.prong1_as()}; chargeSigmac = candSigmac.charge(); - if (chargeSigmac == 0) { + if (chargeSigmac == o2::aod::hf_cand_sigmac::ChargeNull) { /// candidate Σc0 /// 3 levels: /// 1. Σc0 → Λc+ π-,+ /// 2. Λc+ → pK-π+ direct (i) or Λc+ → resonant channel Λc± → p± K*, Λc± → Δ(1232)±± K∓ or Λc± → Λ(1520) π± (ii) /// 3. in case of (ii): resonant channel to pK-π+ + + /// look for Σc0(2455) indexRec = RecoDecay::getMatchedMCRec(mcParticles, arrayDaughters, Pdg::kSigmaC0, std::array{+kProton, -kKPlus, +kPiPlus, -kPiPlus}, true, &sign, 3); if (indexRec > -1) { /// due to (*) no need to check anything for LambdaC - flag = sign * (1 << aod::hf_cand_sigmac::DecayType::Sc0ToPKPiPi); + flag = sign * BIT(aod::hf_cand_sigmac::DecayType::Sc0ToPKPiPi); + } + + /// look for Σc0(2520) + if (flag == 0) { + indexRec = RecoDecay::getMatchedMCRec(mcParticles, arrayDaughters, Pdg::kSigmaCStar0, std::array{+kProton, -kKPlus, +kPiPlus, -kPiPlus}, true, &sign, 3); + if (indexRec > -1) { /// due to (*) no need to check anything for LambdaC + flag = sign * BIT(aod::hf_cand_sigmac::DecayType::ScStar0ToPKPiPi); + } } - } else if (std::abs(chargeSigmac) == 2) { + + } else if (std::abs(chargeSigmac) == o2::aod::hf_cand_sigmac::ChargePlusPlus) { /// candidate Σc++ /// 3 levels: /// 1. Σc0 → Λc+ π-,+ /// 2. Λc+ → pK-π+ direct (i) or Λc+ → resonant channel Λc± → p± K*, Λc± → Δ(1232)±± K∓ or Λc± → Λ(1520) π± (ii) /// 3. in case of (ii): resonant channel to pK-π+ + + /// look for Σc++(2455) indexRec = RecoDecay::getMatchedMCRec(mcParticles, arrayDaughters, Pdg::kSigmaCPlusPlus, std::array{+kProton, -kKPlus, +kPiPlus, +kPiPlus}, true, &sign, 3); if (indexRec > -1) { /// due to (*) no need to check anything for LambdaC - flag = sign * (1 << aod::hf_cand_sigmac::DecayType::ScplusplusToPKPiPi); + flag = sign * BIT(aod::hf_cand_sigmac::DecayType::ScplusplusToPKPiPi); + } + + /// look for Σc++(2520) + if (flag == 0) { + indexRec = RecoDecay::getMatchedMCRec(mcParticles, arrayDaughters, Pdg::kSigmaCStarPlusPlus, std::array{+kProton, -kKPlus, +kPiPlus, +kPiPlus}, true, &sign, 3); + if (indexRec > -1) { /// due to (*) no need to check anything for LambdaC + flag = sign * BIT(aod::hf_cand_sigmac::DecayType::ScStarPlusPlusToPKPiPi); + } } } @@ -495,9 +525,16 @@ struct HfCandidateSigmac0plusplusMc { origin = 0; std::vector idxBhadMothers{}; + /// MC ev. selection done w/o centrality estimator + /// In case of need, readapt the code templetizing the function auto mcCollision = particle.mcCollision(); - float zPv = mcCollision.posZ(); - if (zPv < -zPvPosMax || zPv > zPvPosMax) { // to avoid counting particles in collisions with Zvtx larger than the maximum, we do not match them + float centrality{-1.f}; + uint16_t rejectionMask{0}; + const auto collSlice = collInfos.sliceBy(colPerMcCollision, mcCollision.globalIndex()); + rejectionMask = hfEvSelMc.getHfMcCollisionRejectionMask(mcCollision, collSlice, centrality); + hfEvSelMc.fillHistograms(mcCollision, rejectionMask, 0); + if (rejectionMask != 0) { + // at least one event selection not satisfied --> reject gen particles from this collision rowMCMatchScGen(flag, origin, -1); continue; } @@ -507,36 +544,63 @@ struct HfCandidateSigmac0plusplusMc { /// 2. Λc+ → pK-π+ direct (i) or Λc+ → resonant channel Λc± → p± K*, Λc± → Δ(1232)±± K∓ or Λc± → Λ(1520) π± (ii) /// 3. in case of (ii): resonant channel to pK-π+ /// → here we check level 1. first, and then levels 2. and 3. are inherited by the Λc+ → pK-π+ MC matching in candidateCreator3Prong.cxx + + /// look for Σc0,++(2455) if (RecoDecay::isMatchedMCGen(mcParticles, particle, Pdg::kSigmaC0, std::array{static_cast(Pdg::kLambdaCPlus), static_cast(kPiMinus)}, true, &sign, 1)) { - // generated Σc0 - // for (const auto& daughter : particle.daughters_as()) { + // generated Σc0(2455) for (const auto& daughter : particle.daughters_as()) { // look for Λc+ daughter decaying in pK-π+ if (std::abs(daughter.pdgCode()) != Pdg::kLambdaCPlus) continue; - // if (std::abs(daughter.flagMcMatchGen()) == (1 << aod::hf_cand_3prong::DecayType::LcToPKPi)) { if (RecoDecay::isMatchedMCGen(mcParticles, daughter, Pdg::kLambdaCPlus, std::array{+kProton, -kKPlus, +kPiPlus}, true, &sign, 2)) { /// Λc+ daughter decaying in pK-π+ found! - flag = sign * (1 << aod::hf_cand_sigmac::DecayType::Sc0ToPKPiPi); + flag = sign * BIT(aod::hf_cand_sigmac::DecayType::Sc0ToPKPiPi); break; } } } else if (RecoDecay::isMatchedMCGen(mcParticles, particle, Pdg::kSigmaCPlusPlus, std::array{static_cast(Pdg::kLambdaCPlus), static_cast(kPiPlus)}, true, &sign, 1)) { - // generated Σc++ - // for (const auto& daughter : particle.daughters_as()) { + // generated Σc++(2455) for (const auto& daughter : particle.daughters_as()) { // look for Λc+ daughter decaying in pK-π+ if (std::abs(daughter.pdgCode()) != Pdg::kLambdaCPlus) continue; - // if (std::abs(daughter.flagMcMatchGen()) == (1 << aod::hf_cand_3prong::DecayType::LcToPKPi)) { if (RecoDecay::isMatchedMCGen(mcParticles, daughter, Pdg::kLambdaCPlus, std::array{+kProton, -kKPlus, +kPiPlus}, true, &sign, 2)) { /// Λc+ daughter decaying in pK-π+ found! - flag = sign * (1 << aod::hf_cand_sigmac::DecayType::ScplusplusToPKPiPi); + flag = sign * BIT(aod::hf_cand_sigmac::DecayType::ScplusplusToPKPiPi); break; } } } + /// look for Σc0,++(2520) + if (flag == 0) { + if (RecoDecay::isMatchedMCGen(mcParticles, particle, Pdg::kSigmaCStar0, std::array{static_cast(Pdg::kLambdaCPlus), static_cast(kPiMinus)}, true, &sign, 1)) { + // generated Σc0(2520) + for (const auto& daughter : particle.daughters_as()) { + // look for Λc+ daughter decaying in pK-π+ + if (std::abs(daughter.pdgCode()) != Pdg::kLambdaCPlus) + continue; + if (RecoDecay::isMatchedMCGen(mcParticles, daughter, Pdg::kLambdaCPlus, std::array{+kProton, -kKPlus, +kPiPlus}, true, &sign, 2)) { + /// Λc+ daughter decaying in pK-π+ found! + flag = sign * BIT(aod::hf_cand_sigmac::DecayType::ScStar0ToPKPiPi); + break; + } + } + } else if (RecoDecay::isMatchedMCGen(mcParticles, particle, Pdg::kSigmaCStarPlusPlus, std::array{static_cast(Pdg::kLambdaCPlus), static_cast(kPiPlus)}, true, &sign, 1)) { + // generated Σc++(2520) + for (const auto& daughter : particle.daughters_as()) { + // look for Λc+ daughter decaying in pK-π+ + if (std::abs(daughter.pdgCode()) != Pdg::kLambdaCPlus) + continue; + if (RecoDecay::isMatchedMCGen(mcParticles, daughter, Pdg::kLambdaCPlus, std::array{+kProton, -kKPlus, +kPiPlus}, true, &sign, 2)) { + /// Λc+ daughter decaying in pK-π+ found! + flag = sign * BIT(aod::hf_cand_sigmac::DecayType::ScStarPlusPlusToPKPiPi); + break; + } + } + } + } + /// check the origin (prompt vs. non-prompt) if (flag != 0) { origin = RecoDecay::getCharmHadronOrigin(mcParticles, particle, false, &idxBhadMothers); @@ -547,6 +611,12 @@ struct HfCandidateSigmac0plusplusMc { } else { rowMCMatchScGen(flag, origin, -1); } + + // debug + // if(origin != RecoDecay::OriginType::Prompt && origin != RecoDecay::OriginType::NonPrompt) { + // LOG(info) << " --> origin " << static_cast(origin) << ", flag " << static_cast(flag); + //} + } /// end loop over mcParticles } /// end processMc PROCESS_SWITCH(HfCandidateSigmac0plusplusMc, processMc, "Process MC", false);