diff --git a/PWGCF/DataModel/FemtoDerived.h b/PWGCF/DataModel/FemtoDerived.h index 4f15d00a342..a4d00d6d416 100644 --- a/PWGCF/DataModel/FemtoDerived.h +++ b/PWGCF/DataModel/FemtoDerived.h @@ -245,6 +245,7 @@ DECLARE_SOA_COLUMN(Charge, charge, int8_t); //! Charge of c DECLARE_SOA_COLUMN(Prong0Id, prong0Id, int); //! Track id of charm hadron prong0 DECLARE_SOA_COLUMN(Prong1Id, prong1Id, int); //! Track id of charm hadron prong1 DECLARE_SOA_COLUMN(Prong2Id, prong2Id, int); //! Track id of charm hadron prong2 +DECLARE_SOA_COLUMN(CascId, cascId, int); //! Cascade id of the Ξ prong in Ξc → Ξππ candidates DECLARE_SOA_COLUMN(Prong0Pt, prong0Pt, float); //! Track pT of charm hadron prong0 DECLARE_SOA_COLUMN(Prong1Pt, prong1Pt, float); //! Track pT of charm hadron prong1 DECLARE_SOA_COLUMN(Prong2Pt, prong2Pt, float); //! Track pT of charm hadron prong2 @@ -258,7 +259,19 @@ DECLARE_SOA_COLUMN(CandidateSelFlag, candidateSelFlag, int); //! Selection o DECLARE_SOA_COLUMN(BDTBkg, bdtBkg, float); //! Background score using Boosted Decision Tree for charm hadron DECLARE_SOA_COLUMN(BDTPrompt, bdtPrompt, float); //! Prompt signal score using Boosted Decision Tree for charm hadron DECLARE_SOA_COLUMN(BDTFD, bdtFD, float); //! Feed-down score using Boosted Decision Tree for charm hadron -DECLARE_SOA_COLUMN(FlagMc, flagMc, int); //! To select MC particle among charm hadrons, { DplusToPiKPi = 1, LcToPKPi = 17, DsToKKPi = 6, XicToPKPi = 21, N3ProngD = 2ecays }; +DECLARE_SOA_COLUMN(CascBachelorTrackId, cascBachelorTrackId, int); //! Bachelor track ID from Ξ cascade (Ξc± → Ξππ) +DECLARE_SOA_COLUMN(CascPosTrackId, cascPosTrackId, int); //! Positive track ID from Λ in Ξ cascade (Ξc± → Ξππ) +DECLARE_SOA_COLUMN(CascNegTrackId, cascNegTrackId, int); //! Negative track ID from Λ in Ξ cascade (Ξc± → Ξππ) +DECLARE_SOA_COLUMN(CascBachelorPt, cascBachelorPt, float); //! pT of the bachelor track from the Xi cascade +DECLARE_SOA_COLUMN(CascBachelorPhi, cascBachelorPhi, float); //! phi of the bachelor track from the Xi cascade +DECLARE_SOA_COLUMN(CascBachelorEta, cascBachelorEta, float); //! eta of the bachelor track from the Xi cascade +DECLARE_SOA_COLUMN(CascPosPt, cascPosPt, float); //! pT of the positive Lambda daughter track from the Xi cascade +DECLARE_SOA_COLUMN(CascPosPhi, cascPosPhi, float); //! phi of the positive Lambda daughter track from the Xi cascade +DECLARE_SOA_COLUMN(CascPosEta, cascPosEta, float); //! eta of the positive Lambda daughter track from the Xi cascade +DECLARE_SOA_COLUMN(CascNegPt, cascNegPt, float); //! pT of the negative Lambda daughter track from the Xi cascade +DECLARE_SOA_COLUMN(CascNegPhi, cascNegPhi, float); //! phi of the negative Lambda daughter track from the Xi cascade +DECLARE_SOA_COLUMN(CascNegEta, cascNegEta, float); //! eta of the negative Lambda daughter track from the Xi cascade +DECLARE_SOA_COLUMN(FlagMc, flagMc, int); //! MC matching flag for the selected charm hadron decay channel DECLARE_SOA_COLUMN(OriginMcRec, originMcRec, int); //! flag for reconstruction level matching (1 for prompt, 2 for non-prompt) DECLARE_SOA_COLUMN(OriginMcGen, originMcGen, int); //! flag for generator level matching (1 for prompt, 2 for non-prompt) DECLARE_SOA_COLUMN(IsCandidateSwapped, isCandidateSwapped, int); //! swapping of the prongs order (0 for Lc -> pkpi, 1 for Lc -> pikp) @@ -270,12 +283,12 @@ DECLARE_SOA_COLUMN(KT, kT, float); //! kT distribu DECLARE_SOA_COLUMN(MT, mT, float); //! Transverse mass distribution DECLARE_SOA_COLUMN(CharmM, charmM, float); //! Charm hadron mass DECLARE_SOA_COLUMN(CharmDaughM, charmDaughM, float); //! Charm hadron daughter mass -DECLARE_SOA_COLUMN(CharmTrkM, charmtrkM, float); //! Charm hadron track mass +DECLARE_SOA_COLUMN(CharmTrkM, charmtrkM, float); //! Invariant-mass difference of the charm-track pair DECLARE_SOA_COLUMN(CharmPt, charmPt, float); //! Transverse momentum of charm hadron for result task DECLARE_SOA_COLUMN(CharmEta, charmEta, float); //! Eta of charm hadron for result task DECLARE_SOA_COLUMN(CharmPhi, charmPhi, float); //! Phi of charm hadron for result task DECLARE_SOA_COLUMN(Mult, mult, int); //! Charge particle multiplicity -DECLARE_SOA_COLUMN(MultPercentile, multPercentile, float); //! Multiplicity precentile +DECLARE_SOA_COLUMN(MultPercentile, multPercentile, float); //! Multiplicity percentile DECLARE_SOA_COLUMN(PairSign, pairSign, int8_t); //! Selection between like sign (1) and unlike sign pair (2) DECLARE_SOA_COLUMN(ProcessType, processType, int64_t); //! Selection between same-event (1), and mixed-event (2) DECLARE_SOA_DYNAMIC_COLUMN(M, m, //! @@ -388,6 +401,16 @@ DECLARE_SOA_DYNAMIC_COLUMN(Eta, eta, RecoDecayPtEtaPhi::pVector(pt2, eta2, phi2))); }); //! Eta distribution of charm hadron } // namespace fdhf_dstar +namespace fdhf_xic +{ +DECLARE_SOA_DYNAMIC_COLUMN(Y, y, //! + [](float pt0, float phi0, float eta0, float pt1, float phi1, float eta1, float pt2, float phi2, float eta2) -> float { return RecoDecay::y(RecoDecay::pVec( + RecoDecayPtEtaPhi::pVector(pt0, eta0, phi0), + RecoDecayPtEtaPhi::pVector(pt1, eta1, phi1), + RecoDecayPtEtaPhi::pVector(pt2, eta2, phi2)), + o2::constants::physics::MassXiCPlus); }); //! Rapidity distribution of Xic candidates +} // namespace fdhf_xic + DECLARE_SOA_TABLE(FDHfCand3Prong, "AOD", "FDHFCAND3PRONG", //! Table to store the derived data for charm 3prong candidates o2::soa::Index<>, femtodreamparticle::FDCollisionId, @@ -416,6 +439,49 @@ DECLARE_SOA_TABLE(FDHfCand3Prong, "AOD", "FDHFCAND3PRONG", //! Table to store th fdhf::Phi, fdhf::Pt); +DECLARE_SOA_TABLE(FDHfCand3ProngXic, "AOD", "FDHFXIC3PRONG", //! Table to store the derived data for Ξc → Ξππ candidates + o2::soa::Index<>, + femtodreamparticle::FDCollisionId, + fdhf::TimeStamp, + fdhf::Charge, + fdhf::CascId, + fdhf::Prong1Id, + fdhf::Prong2Id, + fdhf::CascBachelorTrackId, + fdhf::CascPosTrackId, + fdhf::CascNegTrackId, + fdhf::Prong0Pt, + fdhf::Prong1Pt, + fdhf::Prong2Pt, + fdhf::Prong0Eta, + fdhf::Prong1Eta, + fdhf::Prong2Eta, + fdhf::Prong0Phi, + fdhf::Prong1Phi, + fdhf::Prong2Phi, + fdhf::CandidateSelFlag, + fdhf::BDTBkg, + fdhf::BDTPrompt, + fdhf::BDTFD, + fdhf::M, + fdhf::P, + fdhf_xic::Y, + fdhf::Eta, + fdhf::Phi, + fdhf::Pt); + +DECLARE_SOA_TABLE(FDHfCand3ProngXicQa, "AOD", "FDHFXIC3PQA", //! QA extension table for Ξ daughters in Ξc → Ξππ candidates + o2::soa::Index<>, + fdhf::CascBachelorPt, + fdhf::CascBachelorPhi, + fdhf::CascBachelorEta, + fdhf::CascPosPt, + fdhf::CascPosPhi, + fdhf::CascPosEta, + fdhf::CascNegPt, + fdhf::CascNegPhi, + fdhf::CascNegEta); + DECLARE_SOA_TABLE(FDHfCand2Prong, "AOD", "FDHFCAND2PRONG", //! Table to store the derived data for charm 3prong candidates o2::soa::Index<>, femtodreamparticle::FDCollisionId, @@ -681,8 +747,16 @@ static constexpr std::string_view ParticleOriginMCTruthName[kNOriginMCTruthTypes "_Material", "_NotPrimary", "_Fake", + "_WrongCollision", "_SecondaryDaughterLambda", - "_SecondaryDaughterSigmaPlus"}; + "_SecondaryDaughterSigmaPlus", + "_SecondaryDaughterSigma0", + "_SecondaryDaughterXiMinus", + "_SecondaryDaughterXi0", + "_SecondaryDaughterOmegaMinus", + "_SecondaryDaughterXistar0", + "_SecondaryDaughterXistarMinus", + "_Else"}; /// Distinguished between reconstructed and truth enum MCType { diff --git a/PWGCF/FemtoDream/Core/femtoDreamParticleHisto.h b/PWGCF/FemtoDream/Core/femtoDreamParticleHisto.h index 8371f683515..ae3e12e9f69 100644 --- a/PWGCF/FemtoDream/Core/femtoDreamParticleHisto.h +++ b/PWGCF/FemtoDream/Core/femtoDreamParticleHisto.h @@ -209,10 +209,11 @@ class FemtoDreamParticleHisto { /// Particle-type specific histograms std::string folderSuffix = static_cast(o2::aod::femtodreamMCparticle::MCTypeName[o2::aod::femtodreamMCparticle::MCType::kTruth]).c_str(); + const auto nMcOriginTypes = static_cast(o2::aod::femtodreamMCparticle::ParticleOriginMCTruth::kNOriginMCTruthTypes); mHistogramRegistry->add((folderName + folderSuffix + "/hPt_ReconNoFake").c_str(), "; #it{p}_{T} (GeV/#it{c}); Entries", o2::framework::HistType::kTH1F, {{240, 0, 6}}); mHistogramRegistry->add((folderName + folderSuffix + "/hPDG").c_str(), "; PDG; Entries", o2::framework::HistType::kTH1I, {{6001, -3000.5, 3000.5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hOrigin_MC").c_str(), "; Origin; Entries", o2::framework::HistType::kTH1I, {{7, -0.5, 6.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hOrigin_MC").c_str(), "; Origin; Entries", o2::framework::HistType::kTH1I, {{nMcOriginTypes, -0.5, static_cast(nMcOriginTypes) - 0.5}}); mHistogramRegistry->add((folderName + folderSuffix + "/hNoMCtruthCounter").c_str(), "; Counter; Entries", o2::framework::HistType::kTH1I, {{1, -0.5, 0.5}}); mHistogramRegistry->add((folderName + folderSuffix + "/hPt_DiffTruthReco").c_str(), "; p^{truth}_{T}; (p^{reco}_{T} - p^{truth}_{T}) / p^{truth}_{T}", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, {200, -1, 1}}); mHistogramRegistry->add((folderName + folderSuffix + "/hEta_DiffTruthReco").c_str(), "; #eta^{truth}; #eta^{reco} - #eta^{truth}", o2::framework::HistType::kTH2F, {{200, -1, 1}, {200, -1, 1}}); @@ -229,6 +230,7 @@ class FemtoDreamParticleHisto mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_Else").c_str(), "; PDG mother; Entries", o2::framework::HistType::kTH1I, {{6001, -3000.5, 3000.5}}); mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_SecondaryDaughterLambda").c_str(), "; PDG mother; Entries", o2::framework::HistType::kTH1I, {{12001, -6000.5, 6000.5}}); mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_SecondaryDaughterSigmaplus").c_str(), "; PDG mother; Entries", o2::framework::HistType::kTH1I, {{12001, -6000.5, 6000.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_SecondaryDaughterOmegaMinus").c_str(), "; PDG mother; Entries", o2::framework::HistType::kTH1I, {{12001, -6000.5, 6000.5}}); mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Primary").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, dcazAxis, multAxis}); mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Secondary").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, dcazAxis, multAxis}); @@ -237,6 +239,7 @@ class FemtoDreamParticleHisto mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Fake").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, dcazAxis, multAxis}); mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_SecondaryDaughterLambda").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, dcazAxis, multAxis}); mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_SecondaryDaughterSigmaplus").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, dcazAxis, multAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_SecondaryDaughterOmegaMinus").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, dcazAxis, multAxis}); mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Else").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, dcazAxis, multAxis}); } else { mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Primary").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); @@ -246,6 +249,7 @@ class FemtoDreamParticleHisto mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Fake").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_SecondaryDaughterLambda").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_SecondaryDaughterSigmaplus").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_SecondaryDaughterOmegaMinus").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Else").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); } @@ -616,6 +620,11 @@ class FemtoDreamParticleHisto mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/hDCAxy_SecondaryDaughterSigmaplus"), part.pt(), part.tempFitVar(), part.dcaZ(), mult); break; + case (o2::aod::femtodreamMCparticle::kSecondaryDaughterOmegaMinus): + mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/Debug/hPDGmother_SecondaryDaughterOmegaMinus"), part.fdExtMCParticle().motherPDG()); + mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/hDCAxy_SecondaryDaughterOmegaMinus"), + part.pt(), part.tempFitVar(), part.dcaZ(), mult); + break; case (o2::aod::femtodreamMCparticle::kElse): mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/Debug/hPDGmother_Else"), part.fdExtMCParticle().motherPDG()); mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/hDCAxy_Else"), @@ -654,6 +663,10 @@ class FemtoDreamParticleHisto mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/hDCAxy_SecondaryDaughterSigmaplus"), part.pt(), part.tempFitVar()); break; + case (o2::aod::femtodreamMCparticle::kSecondaryDaughterOmegaMinus): + mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/hDCAxy_SecondaryDaughterOmegaMinus"), + part.pt(), part.tempFitVar()); + break; case (o2::aod::femtodreamMCparticle::kElse): mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/hDCAxy_Else"), part.pt(), part.tempFitVar()); diff --git a/PWGCF/FemtoDream/Core/femtoDreamUtils.h b/PWGCF/FemtoDream/Core/femtoDreamUtils.h index efc075671c1..fde124f5db4 100644 --- a/PWGCF/FemtoDream/Core/femtoDreamUtils.h +++ b/PWGCF/FemtoDream/Core/femtoDreamUtils.h @@ -74,6 +74,9 @@ inline float getMass(int pdgCode) case o2::constants::physics::Pdg::kLambdaCPlus: mass = o2::constants::physics::MassLambdaCPlus; break; + case o2::constants::physics::Pdg::kXiCPlus: + mass = o2::constants::physics::MassXiCPlus; + break; case o2::constants::physics::Pdg::kDeuteron: mass = o2::constants::physics::MassDeuteron; break; @@ -99,11 +102,29 @@ inline float getMass(int pdgCode) return mass; } -inline int checkDaughterType(o2::aod::femtodreamparticle::ParticleType partType, int motherPDG) +inline int checkDaughterType(o2::aod::femtodreamparticle::ParticleType partType, int motherPDG, int daughterPDG = 0) { int partOrigin = 0; + const auto absMotherPDG = std::abs(motherPDG); + const auto absDaughterPDG = std::abs(daughterPDG); + const bool isTrackLike = partType == o2::aod::femtodreamparticle::ParticleType::kTrack || + partType == o2::aod::femtodreamparticle::ParticleType::kV0Child || + partType == o2::aod::femtodreamparticle::ParticleType::kCascadeV0Child || + partType == o2::aod::femtodreamparticle::ParticleType::kCascadeBachelor; + + if (absDaughterPDG == kKPlus && isTrackLike) { + switch (absMotherPDG) { + case kOmegaMinus: + partOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kSecondaryDaughterOmegaMinus; + break; + default: + partOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kSecondary; + } + return partOrigin; + } + if (partType == o2::aod::femtodreamparticle::ParticleType::kTrack) { - switch (std::abs(motherPDG)) { + switch (absMotherPDG) { case kLambda0: partOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kSecondaryDaughterLambda; break; @@ -115,7 +136,7 @@ inline int checkDaughterType(o2::aod::femtodreamparticle::ParticleType partType, } // switch } else if (partType == o2::aod::femtodreamparticle::ParticleType::kV0) { - switch (std::abs(motherPDG)) { + switch (absMotherPDG) { case kSigma0: partOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kSecondaryDaughterSigma0; break; @@ -130,7 +151,7 @@ inline int checkDaughterType(o2::aod::femtodreamparticle::ParticleType partType, } } else if (partType == o2::aod::femtodreamparticle::ParticleType::kV0Child || partType == o2::aod::femtodreamparticle::ParticleType::kCascadeV0Child || partType == o2::aod::femtodreamparticle::ParticleType::kCascadeBachelor) { - switch (abs(motherPDG)) { + switch (absMotherPDG) { case kLambda0: partOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kSecondaryDaughterLambda; break; @@ -142,7 +163,7 @@ inline int checkDaughterType(o2::aod::femtodreamparticle::ParticleType partType, } // switch } else if (partType == o2::aod::femtodreamparticle::ParticleType::kCascade) { - switch (std::abs(motherPDG)) { + switch (absMotherPDG) { case kOmegaMinus: partOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kSecondaryDaughterOmegaMinus; break; diff --git a/PWGCF/FemtoDream/TableProducer/femtoDreamProducerReducedTask.cxx b/PWGCF/FemtoDream/TableProducer/femtoDreamProducerReducedTask.cxx index 8d2a80b00c4..a35faf8c8a7 100644 --- a/PWGCF/FemtoDream/TableProducer/femtoDreamProducerReducedTask.cxx +++ b/PWGCF/FemtoDream/TableProducer/femtoDreamProducerReducedTask.cxx @@ -214,7 +214,7 @@ struct femtoDreamProducerReducedTask { } else if (particleMC.isPhysicalPrimary()) { particleOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kPrimary; } else if (motherparticleMC.isPhysicalPrimary() && particleMC.getProcess() == 4) { - particleOrigin = checkDaughterType(fdparttype, motherparticleMC.pdgCode()); + particleOrigin = checkDaughterType(fdparttype, motherparticleMC.pdgCode(), pdgCode); } else if (particleMC.getGenStatusCode() == -1) { particleOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kMaterial; } else { diff --git a/PWGCF/FemtoDream/TableProducer/femtoDreamProducerTask.cxx b/PWGCF/FemtoDream/TableProducer/femtoDreamProducerTask.cxx index 9f47d915620..bb88a135cb2 100644 --- a/PWGCF/FemtoDream/TableProducer/femtoDreamProducerTask.cxx +++ b/PWGCF/FemtoDream/TableProducer/femtoDreamProducerTask.cxx @@ -672,7 +672,7 @@ struct femtoDreamProducerTask { auto motherparticleMC = motherparticlesMC.front(); pdgCodeMother = motherparticleMC.pdgCode(); TrackRegistry.fill(HIST("AnalysisQA/Mother"), pdgCodeMother); - particleOrigin = checkDaughterType(fdparttype, motherparticleMC.pdgCode()); + particleOrigin = checkDaughterType(fdparttype, motherparticleMC.pdgCode(), pdgCode); // check if particle is material // particle is from inelastic hadronic interaction -> getProcess() == 23 // particle is generated during transport -> getGenStatusCode() == -1 diff --git a/PWGCF/FemtoDream/TableProducer/femtoDreamProducerTaskReso.cxx b/PWGCF/FemtoDream/TableProducer/femtoDreamProducerTaskReso.cxx index 9b0f753ef9c..03779b09ed9 100644 --- a/PWGCF/FemtoDream/TableProducer/femtoDreamProducerTaskReso.cxx +++ b/PWGCF/FemtoDream/TableProducer/femtoDreamProducerTaskReso.cxx @@ -928,7 +928,7 @@ struct FemtoDreamProducerTaskReso { auto motherparticleMC = motherparticlesMC.front(); pdgCodeMother = motherparticleMC.pdgCode(); trackRegistry.fill(HIST("AnalysisQA/Mother"), pdgCodeMother); - particleOrigin = checkDaughterType(fdparttype, motherparticleMC.pdgCode()); + particleOrigin = checkDaughterType(fdparttype, motherparticleMC.pdgCode(), pdgCode); // check if particle is material // particle is from inelastic hadronic interaction -> getProcess() == 23 // particle is generated during transport -> getGenStatusCode() == -1 diff --git a/PWGHF/HFC/TableProducer/producerCharmHadronsTrackFemtoDream.cxx b/PWGHF/HFC/TableProducer/producerCharmHadronsTrackFemtoDream.cxx index 8a75dbfecb9..d128f50fafb 100644 --- a/PWGHF/HFC/TableProducer/producerCharmHadronsTrackFemtoDream.cxx +++ b/PWGHF/HFC/TableProducer/producerCharmHadronsTrackFemtoDream.cxx @@ -21,10 +21,12 @@ #include "PWGCF/FemtoDream/Core/femtoDreamUtils.h" #include "PWGHF/Core/CentralityEstimation.h" #include "PWGHF/Core/DecayChannels.h" +#include "PWGHF/Core/DecayChannelsLegacy.h" #include "PWGHF/Core/HfMlResponseD0ToKPi.h" #include "PWGHF/Core/HfMlResponseDplusToPiKPi.h" #include "PWGHF/Core/HfMlResponseDstarToD0Pi.h" #include "PWGHF/Core/HfMlResponseLcToPKPi.h" +#include "PWGHF/Core/HfMlResponseXicToXiPiPi.h" #include "PWGHF/Core/SelectorCuts.h" #include "PWGHF/DataModel/AliasTables.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" @@ -32,6 +34,7 @@ #include "PWGHF/Utils/utilsBfieldCCDB.h" #include "PWGHF/Utils/utilsEvSelHf.h" +#include "Common/Core/RecoDecay.h" #include "Common/Core/ZorroSummary.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" @@ -98,7 +101,8 @@ enum MlMode : uint8_t { enum DecayChannel { DplusToPiKPi = 0, LcToPKPi, D0ToPiK, - DstarToD0Pi + DstarToD0Pi, + XicToXiPiPi }; enum class D0CandFlag : uint8_t { @@ -109,35 +113,38 @@ enum class D0CandFlag : uint8_t { struct HfProducerCharmHadronsTrackFemtoDream { - Produces outputCollision; - Produces rowMasks; - Produces rowCandCharm3Prong; - Produces rowCandCharm2Prong; - Produces rowCandCharmDstar; - Produces rowCandMcCharmHad; - Produces rowCandCharmHadGen; - Produces outputPartsIndex; - Produces outputPartsTime; - Produces outputMcCollision; - Produces outputCollsMcLabels; - Produces outputParts; - Produces outputPartsMc; - Produces outputDebugParts; - Produces outputPartsMcLabels; - Produces outputDebugPartsMc; - Produces outputPartsExtMcLabels; - - Configurable ccdbUrl{"ccdbUrl", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; - Configurable ccdbPathLut{"ccdbPathLut", "GLO/Param/MatLUT", "Path for LUT parametrization"}; - Configurable ccdbPathGrp{"ccdbPathGrp", "GLO/GRP/GRP", "Path of the grp file (Run 2)"}; - Configurable ccdbPathGrpMag{"ccdbPathGrpMag", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object (Run 3)"}; - - Configurable> modelPathsCCDB{"modelPathsCCDB", std::vector{"EventFiltering/PWGHF/BDTLc"}, "Paths of models on CCDB"}; - Configurable> onnxFileNames{"onnxFileNames", std::vector{"ModelHandler_onnx_LcToPKPi.onnx"}, "ONNX file names for each pT bin (if not from CCDB full path)"}; - Configurable timestampCCDB{"timestampCCDB", -1, "timestamp of the ONNX file for ML model used to query in CCDB"}; - Configurable loadModelsFromCCDB{"loadModelsFromCCDB", false, "Flag to enable or disable the loading of models from CCDB"}; - - // Configurable isForceGRP{"isForceGRP", false, "Set true if the magnetic field configuration is not available in the usual CCDB directory (e.g. for Run 2 converted data or unanchorad Monte Carlo)"}; + struct : ProducesGroup { + Produces outputCollision; + Produces rowMasks; + Produces rowCandCharm3Prong; + Produces rowCandCharm3ProngXic; + Produces rowCandCharm3ProngXicQa; + Produces rowCandCharm2Prong; + Produces rowCandCharmDstar; + Produces rowCandMcCharmHad; + Produces rowCandCharmHadGen; + Produces outputPartsIndex; + Produces outputPartsTime; + Produces outputMcCollision; + Produces outputCollsMcLabels; + Produces outputParts; + Produces outputPartsMc; + Produces outputDebugParts; + Produces outputPartsMcLabels; + Produces outputDebugPartsMc; + Produces outputPartsExtMcLabels; + } tables; + + struct : ConfigurableGroup { + Configurable ccdbUrl{"ccdbUrl", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable ccdbPathLut{"ccdbPathLut", "GLO/Param/MatLUT", "Path for LUT parametrization"}; + Configurable ccdbPathGrp{"ccdbPathGrp", "GLO/GRP/GRP", "Path of the grp file (Run 2)"}; + Configurable ccdbPathGrpMag{"ccdbPathGrpMag", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object (Run 3)"}; + Configurable> modelPathsCCDB{"modelPathsCCDB", std::vector{"EventFiltering/PWGHF/BDTLc"}, "Paths of models on CCDB"}; + Configurable> onnxFileNames{"onnxFileNames", std::vector{"ModelHandler_onnx_LcToPKPi.onnx"}, "ONNX file names for each pT bin (if not from CCDB full path)"}; + Configurable timestampCCDB{"timestampCCDB", -1, "timestamp of the ONNX file for ML model used to query in CCDB"}; + Configurable loadModelsFromCCDB{"loadModelsFromCCDB", false, "Flag to enable or disable the loading of models from CCDB"}; + } ccdbCfg; // ------------------------- // Kaon PID cut parameters @@ -157,37 +164,41 @@ struct HfProducerCharmHadronsTrackFemtoDream { Configurable nSigmaCombPiMax{"nSigmaCombPiMax", 6.f, "Kaon PID Method2: for p > pTrackTightMin require |nSigmaCombPi| < this"}; } kaonPidSel; - Configurable isDebug{"isDebug", true, "Enable Debug tables"}; - Configurable isRun3{"isRun3", true, "Running on Run3 or pilot"}; - - /// Charm hadron table - Configurable selectionFlagHadron{"selectionFlagHadron", 1, "Selection Flag for Charm Hadron: 1 for Lc, 7 for Dplus (Topologic and PID cuts)"}; - Configurable useCent{"useCent", false, "Enable centrality for Charm Hadron"}; - - Configurable trkPDGCode{"trkPDGCode", 2212, "PDG code of the selected track for Monte Carlo truth"}; - Configurable> trkCharge{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kSign, "trk"), std::vector{-1, 1}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kSign, "Track selection: ")}; - Configurable> trkDCAxyMax{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kDCAxyMax, "trk"), std::vector{0.1f, 3.5f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kDCAxyMax, "Track selection: ")}; - Configurable> trkDCAzMax{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kDCAzMax, "trk"), std::vector{0.2f, 3.5f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kDCAzMax, "Track selection: ")}; - Configurable> trkEta{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kEtaMax, "trk"), std::vector{0.8f, 0.7f, 0.9f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kEtaMax, "Track selection: ")}; - Configurable> trkPIDspecies{"trkPIDspecies", std::vector{o2::track::PID::Pion, o2::track::PID::Kaon, o2::track::PID::Proton, o2::track::PID::Deuteron}, "Trk sel: Particles species for PID"}; - Configurable> trkPIDnSigmaMax{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kPIDnSigmaMax, "trk"), std::vector{3.5f, 3.f, 2.5f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kPIDnSigmaMax, "Track selection: ")}; - Configurable trkPIDnSigmaOffsetTPC{"trkPIDnSigmaOffsetTPC", 0., "Offset for TPC nSigma because of bad calibration"}; - Configurable trkPIDnSigmaOffsetTOF{"trkPIDnSigmaOffsetTOF", 0., "Offset for TOF nSigma because of bad calibration"}; - Configurable> trkPtmax{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kpTMax, "trk"), std::vector{5.4f, 5.6f, 5.5f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kpTMax, "Track selection: ")}; - Configurable> trkPtmin{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kpTMin, "trk"), std::vector{0.5f, 0.4f, 0.6f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kpTMin, "Track selection: ")}; - Configurable> trkTPCcRowsMin{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kTPCcRowsMin, "trk"), std::vector{70.f, 60.f, 80.f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kTPCcRowsMin, "Track selection: ")}; - Configurable> trkTPCfCls{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kTPCfClsMin, "trk"), std::vector{0.7f, 0.83f, 0.9f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kTPCfClsMin, "Track selection: ")}; - Configurable> trkTPCnclsMin{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kTPCnClsMin, "trk"), std::vector{80.f, 70.f, 60.f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kTPCnClsMin, "Track selection: ")}; - Configurable> trkTPCsCls{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kTPCsClsMax, "trk"), std::vector{0.1f, 160.f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kTPCsClsMax, "Track selection: ")}; - Configurable> trkITSnclsIbMin{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kITSnClsIbMin, "trk"), std::vector{-1.f, 1.f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kITSnClsIbMin, "Track selection: ")}; - Configurable> trkITSnclsMin{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kITSnClsMin, "trk"), std::vector{-1.f, 2.f, 4.f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kITSnClsMin, "Track selection: ")}; - // ML inference - Configurable applyMlMode{"applyMlMode", 1, "None: 0, BDT model from candidate selector: 1, New BDT model on Top of candidate selector: 2"}; - Configurable> binsPtMl{"binsPtMl", std::vector{hf_cuts_ml::vecBinsPt}, "pT bin limits for ML application"}; - Configurable> cutDirMl{"cutDirMl", std::vector{hf_cuts_ml::vecCutDir}, "Whether to reject score values greater or smaller than the threshold"}; - Configurable> cutsMl{"cutsMl", {hf_cuts_ml::Cuts[0], hf_cuts_ml::NBinsPt, hf_cuts_ml::NCutScores, hf_cuts_ml::labelsPt, hf_cuts_ml::labelsCutScore}, "ML selections per pT bin"}; - Configurable nClassesMl{"nClassesMl", static_cast(hf_cuts_ml::NCutScores), "Number of classes in ML model"}; - Configurable> namesInputFeatures{"namesInputFeatures", std::vector{"feature1", "feature2"}, "Names of ML model input features"}; + struct : ConfigurableGroup { + Configurable isDebug{"isDebug", true, "Enable Debug tables"}; + Configurable isRun3{"isRun3", true, "Running on Run3 or pilot"}; + Configurable selectionFlagHadron{"selectionFlagHadron", 1, "Selection flag for charm hadrons; applied to D0, Dplus, Lc and Xic selector decisions"}; + Configurable useCent{"useCent", false, "Enable centrality for Charm Hadron"}; + } generalCfg; + + struct : ConfigurableGroup { + Configurable trkPDGCode{"trkPDGCode", 2212, "PDG code of the selected track for Monte Carlo truth"}; + Configurable> trkCharge{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kSign, "trk"), std::vector{-1, 1}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kSign, "Track selection: ")}; + Configurable> trkDCAxyMax{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kDCAxyMax, "trk"), std::vector{0.1f, 3.5f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kDCAxyMax, "Track selection: ")}; + Configurable> trkDCAzMax{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kDCAzMax, "trk"), std::vector{0.2f, 3.5f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kDCAzMax, "Track selection: ")}; + Configurable> trkEta{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kEtaMax, "trk"), std::vector{0.8f, 0.7f, 0.9f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kEtaMax, "Track selection: ")}; + Configurable> trkPIDspecies{"trkPIDspecies", std::vector{o2::track::PID::Pion, o2::track::PID::Kaon, o2::track::PID::Proton, o2::track::PID::Deuteron}, "Trk sel: Particles species for PID"}; + Configurable> trkPIDnSigmaMax{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kPIDnSigmaMax, "trk"), std::vector{3.5f, 3.f, 2.5f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kPIDnSigmaMax, "Track selection: ")}; + Configurable trkPIDnSigmaOffsetTPC{"trkPIDnSigmaOffsetTPC", 0., "Offset for TPC nSigma because of bad calibration"}; + Configurable trkPIDnSigmaOffsetTOF{"trkPIDnSigmaOffsetTOF", 0., "Offset for TOF nSigma because of bad calibration"}; + Configurable> trkPtmax{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kpTMax, "trk"), std::vector{5.4f, 5.6f, 5.5f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kpTMax, "Track selection: ")}; + Configurable> trkPtmin{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kpTMin, "trk"), std::vector{0.5f, 0.4f, 0.6f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kpTMin, "Track selection: ")}; + Configurable> trkTPCcRowsMin{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kTPCcRowsMin, "trk"), std::vector{70.f, 60.f, 80.f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kTPCcRowsMin, "Track selection: ")}; + Configurable> trkTPCfCls{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kTPCfClsMin, "trk"), std::vector{0.7f, 0.83f, 0.9f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kTPCfClsMin, "Track selection: ")}; + Configurable> trkTPCnclsMin{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kTPCnClsMin, "trk"), std::vector{80.f, 70.f, 60.f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kTPCnClsMin, "Track selection: ")}; + Configurable> trkTPCsCls{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kTPCsClsMax, "trk"), std::vector{0.1f, 160.f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kTPCsClsMax, "Track selection: ")}; + Configurable> trkITSnclsIbMin{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kITSnClsIbMin, "trk"), std::vector{-1.f, 1.f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kITSnClsIbMin, "Track selection: ")}; + Configurable> trkITSnclsMin{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kITSnClsMin, "trk"), std::vector{-1.f, 2.f, 4.f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kITSnClsMin, "Track selection: ")}; + } trackCfg; + + struct : ConfigurableGroup { + Configurable applyMlMode{"applyMlMode", 1, "None: 0, BDT model from candidate selector: 1, New BDT model on Top of candidate selector: 2"}; + Configurable> binsPtMl{"binsPtMl", std::vector{hf_cuts_ml::vecBinsPt}, "pT bin limits for ML application"}; + Configurable> cutDirMl{"cutDirMl", std::vector{hf_cuts_ml::vecCutDir}, "Whether to reject score values greater or smaller than the threshold"}; + Configurable> cutsMl{"cutsMl", {hf_cuts_ml::Cuts[0], hf_cuts_ml::NBinsPt, hf_cuts_ml::NCutScores, hf_cuts_ml::labelsPt, hf_cuts_ml::labelsCutScore}, "ML selections per pT bin"}; + Configurable nClassesMl{"nClassesMl", static_cast(hf_cuts_ml::NCutScores), "Number of classes in ML model"}; + Configurable> namesInputFeatures{"namesInputFeatures", std::vector{"feature1", "feature2"}, "Names of ML model input features"}; + } mlCfg; FemtoDreamTrackSelection trackCuts; @@ -195,6 +206,7 @@ struct HfProducerCharmHadronsTrackFemtoDream { o2::analysis::HfMlResponseDplusToPiKPi hfMlResponseDplus; o2::analysis::HfMlResponseD0ToKPi hfMlResponseD0; o2::analysis::HfMlResponseDstarToD0Pi hfMlResponseDstar; + o2::analysis::HfMlResponseXicToXiPiPi hfMlResponseXic; std::vector outputMlD0; std::vector outputMlD0bar; @@ -202,11 +214,11 @@ struct HfProducerCharmHadronsTrackFemtoDream { std::vector outputMlDplus; std::vector outputMlPKPi; std::vector outputMlPiKP; + std::vector outputMlXic; o2::ccdb::CcdbApi ccdbApi; o2::hf_evsel::HfEventSelection hfEvSel; Service ccdb{}; /// Accessing the CCDB o2::base::MatLayerCylSet* lut{}; - // if (doPvRefit){ lut = o2::base::MatLayerCylSet::rectifyPtrFromFile(ccdb->get(ccdbPathLut));} //! may be it useful, will check later float magField{}; int runNumber{}; @@ -218,6 +230,10 @@ struct HfProducerCharmHadronsTrackFemtoDream { using CandidateDplusMc = soa::Join; using CandidateLc = soa::Join; using CandidateLcMc = soa::Join; + using CandidateXic = soa::Join; + using CandidateXicMc = soa::Join; + using CandidateXicKf = soa::Join; + using CandidateXicKfMc = soa::Join; using FemtoFullCollision = soa::Join::iterator; using FemtoFullCollisionMc = soa::Join::iterator; @@ -231,11 +247,13 @@ struct HfProducerCharmHadronsTrackFemtoDream { using Generated3ProngMc = soa::Join; using Generated2ProngMc = soa::Join; using GeneratedDstarMc = soa::Join; + using GeneratedXicMc = soa::Join; - Filter filterSelectCandidateD0 = (aod::hf_sel_candidate_d0::isSelD0 >= selectionFlagHadron || aod::hf_sel_candidate_d0::isSelD0bar >= selectionFlagHadron); + Filter filterSelectCandidateD0 = (aod::hf_sel_candidate_d0::isSelD0 >= generalCfg.selectionFlagHadron || aod::hf_sel_candidate_d0::isSelD0bar >= generalCfg.selectionFlagHadron); Filter filterSelectCandidateDstar = aod::hf_sel_candidate_dstar::isSelDstarToD0Pi == true; - Filter filterSelectCandidateDplus = aod::hf_sel_candidate_dplus::isSelDplusToPiKPi >= selectionFlagHadron; - Filter filterSelectCandidateLc = (aod::hf_sel_candidate_lc::isSelLcToPKPi >= selectionFlagHadron || aod::hf_sel_candidate_lc::isSelLcToPiKP >= selectionFlagHadron); + Filter filterSelectCandidateDplus = aod::hf_sel_candidate_dplus::isSelDplusToPiKPi >= generalCfg.selectionFlagHadron; + Filter filterSelectCandidateLc = (aod::hf_sel_candidate_lc::isSelLcToPKPi >= generalCfg.selectionFlagHadron || aod::hf_sel_candidate_lc::isSelLcToPiKP >= generalCfg.selectionFlagHadron); + Filter filterSelectCandidateXic = aod::hf_sel_candidate_xic::isSelXicToXiPiPi >= generalCfg.selectionFlagHadron; HistogramRegistry qaRegistry{"QAHistos", {}, OutputObjHandlingPolicy::AnalysisObject}; HistogramRegistry trackRegistry{"Tracks", {}, OutputObjHandlingPolicy::AnalysisObject}; @@ -243,8 +261,12 @@ struct HfProducerCharmHadronsTrackFemtoDream { void init(InitContext&) { - std::array processes = {doprocessDataDplusToPiKPi, doprocessMcDplusToPiKPi, doprocessDataDplusToPiKPiWithML, doprocessMcDplusToPiKPiWithML, doprocessMcDplusToPiKPiGen, - doprocessDataLcToPKPi, doprocessMcLcToPKPi, doprocessDataLcToPKPiWithML, doprocessMcLcToPKPiWithML, doprocessMcLcToPKPiGen, doprocessDataD0ToPiK, doprocessMcD0ToPiK, doprocessDataD0ToPiKWithML, doprocessMcD0ToPiKWithML, doprocessMcD0ToPiKGen, doprocessDataDstarToD0Pi, doprocessMcDstarToD0Pi, doprocessDataDstarToD0PiWithML, doprocessMcDstarToD0PiWithML, doprocessMcDstarToD0PiGen}; + std::array processes = {doprocessDataDplusToPiKPi, doprocessMcDplusToPiKPi, doprocessDataDplusToPiKPiWithML, doprocessMcDplusToPiKPiWithML, doprocessMcDplusToPiKPiGen, + doprocessDataLcToPKPi, doprocessMcLcToPKPi, doprocessDataLcToPKPiWithML, doprocessMcLcToPKPiWithML, doprocessMcLcToPKPiGen, + doprocessDataD0ToPiK, doprocessMcD0ToPiK, doprocessDataD0ToPiKWithML, doprocessMcD0ToPiKWithML, doprocessMcD0ToPiKGen, + doprocessDataDstarToD0Pi, doprocessMcDstarToD0Pi, doprocessDataDstarToD0PiWithML, doprocessMcDstarToD0PiWithML, doprocessMcDstarToD0PiGen, + doprocessDataXicToXiPiPi, doprocessDataXicToXiPiPiKf, doprocessDataXicToXiPiPiWithML, doprocessDataXicToXiPiPiWithMLKf, + doprocessMcXicToXiPiPi, doprocessMcXicToXiPiPiKf, doprocessMcXicToXiPiPiWithML, doprocessMcXicToXiPiPiWithMLKf, doprocessMcXicToXiPiPiGen}; if (std::accumulate(processes.begin(), processes.end(), 0) != 1) { LOGP(fatal, "One and only one process function must be enabled at a time."); } @@ -268,27 +290,27 @@ struct HfProducerCharmHadronsTrackFemtoDream { qaRegistry.get(HIST("hEventQA"))->GetXaxis()->SetBinLabel(iBin + 1, labels[iBin].data()); } - trackCuts.setSelection(trkCharge, femtoDreamTrackSelection::kSign, femtoDreamSelection::kEqual); - trackCuts.setSelection(trkPtmin, femtoDreamTrackSelection::kpTMin, femtoDreamSelection::kLowerLimit); - trackCuts.setSelection(trkPtmax, femtoDreamTrackSelection::kpTMax, femtoDreamSelection::kUpperLimit); - trackCuts.setSelection(trkEta, femtoDreamTrackSelection::kEtaMax, femtoDreamSelection::kAbsUpperLimit); - trackCuts.setSelection(trkTPCnclsMin, femtoDreamTrackSelection::kTPCnClsMin, femtoDreamSelection::kLowerLimit); - trackCuts.setSelection(trkTPCfCls, femtoDreamTrackSelection::kTPCfClsMin, femtoDreamSelection::kLowerLimit); - trackCuts.setSelection(trkTPCcRowsMin, femtoDreamTrackSelection::kTPCcRowsMin, femtoDreamSelection::kLowerLimit); - trackCuts.setSelection(trkTPCsCls, femtoDreamTrackSelection::kTPCsClsMax, femtoDreamSelection::kUpperLimit); - trackCuts.setSelection(trkITSnclsMin, femtoDreamTrackSelection::kITSnClsMin, femtoDreamSelection::kLowerLimit); - trackCuts.setSelection(trkITSnclsIbMin, femtoDreamTrackSelection::kITSnClsIbMin, femtoDreamSelection::kLowerLimit); - trackCuts.setSelection(trkDCAxyMax, femtoDreamTrackSelection::kDCAxyMax, femtoDreamSelection::kAbsUpperLimit); - trackCuts.setSelection(trkDCAzMax, femtoDreamTrackSelection::kDCAzMax, femtoDreamSelection::kAbsUpperLimit); - trackCuts.setSelection(trkPIDnSigmaMax, femtoDreamTrackSelection::kPIDnSigmaMax, femtoDreamSelection::kAbsUpperLimit); - trackCuts.setPIDSpecies(trkPIDspecies); - trackCuts.setnSigmaPIDOffset(trkPIDnSigmaOffsetTPC, trkPIDnSigmaOffsetTOF); + trackCuts.setSelection(trackCfg.trkCharge, femtoDreamTrackSelection::kSign, femtoDreamSelection::kEqual); + trackCuts.setSelection(trackCfg.trkPtmin, femtoDreamTrackSelection::kpTMin, femtoDreamSelection::kLowerLimit); + trackCuts.setSelection(trackCfg.trkPtmax, femtoDreamTrackSelection::kpTMax, femtoDreamSelection::kUpperLimit); + trackCuts.setSelection(trackCfg.trkEta, femtoDreamTrackSelection::kEtaMax, femtoDreamSelection::kAbsUpperLimit); + trackCuts.setSelection(trackCfg.trkTPCnclsMin, femtoDreamTrackSelection::kTPCnClsMin, femtoDreamSelection::kLowerLimit); + trackCuts.setSelection(trackCfg.trkTPCfCls, femtoDreamTrackSelection::kTPCfClsMin, femtoDreamSelection::kLowerLimit); + trackCuts.setSelection(trackCfg.trkTPCcRowsMin, femtoDreamTrackSelection::kTPCcRowsMin, femtoDreamSelection::kLowerLimit); + trackCuts.setSelection(trackCfg.trkTPCsCls, femtoDreamTrackSelection::kTPCsClsMax, femtoDreamSelection::kUpperLimit); + trackCuts.setSelection(trackCfg.trkITSnclsMin, femtoDreamTrackSelection::kITSnClsMin, femtoDreamSelection::kLowerLimit); + trackCuts.setSelection(trackCfg.trkITSnclsIbMin, femtoDreamTrackSelection::kITSnClsIbMin, femtoDreamSelection::kLowerLimit); + trackCuts.setSelection(trackCfg.trkDCAxyMax, femtoDreamTrackSelection::kDCAxyMax, femtoDreamSelection::kAbsUpperLimit); + trackCuts.setSelection(trackCfg.trkDCAzMax, femtoDreamTrackSelection::kDCAzMax, femtoDreamSelection::kAbsUpperLimit); + trackCuts.setSelection(trackCfg.trkPIDnSigmaMax, femtoDreamTrackSelection::kPIDnSigmaMax, femtoDreamSelection::kAbsUpperLimit); + trackCuts.setPIDSpecies(trackCfg.trkPIDspecies); + trackCuts.setnSigmaPIDOffset(trackCfg.trkPIDnSigmaOffsetTPC, trackCfg.trkPIDnSigmaOffsetTOF); trackCuts.init(&qaRegistry, &trackRegistry); runNumber = 0; magField = 0.0; /// Initializing CCDB - ccdb->setURL(ccdbUrl); + ccdb->setURL(ccdbCfg.ccdbUrl); ccdb->setCaching(true); ccdb->setLocalObjectValidityChecking(); @@ -301,25 +323,27 @@ struct HfProducerCharmHadronsTrackFemtoDream { bool useDplusMl = doprocessDataDplusToPiKPiWithML || doprocessMcDplusToPiKPiWithML; bool useD0Ml = doprocessDataD0ToPiKWithML || doprocessMcD0ToPiKWithML; bool useDstarMl = doprocessDataDstarToD0PiWithML || doprocessMcDstarToD0PiWithML; + bool useXicMl = doprocessDataXicToXiPiPiWithML || doprocessMcXicToXiPiPiWithML || doprocessDataXicToXiPiPiWithMLKf || doprocessMcXicToXiPiPiWithMLKf; - if (applyMlMode == FillMlFromNewBDT) { + if (mlCfg.applyMlMode == FillMlFromNewBDT) { auto setupFeatures = [&](auto& hfResponse, bool useMlFlag) { if (!useMlFlag) { return; } - hfResponse.configure(binsPtMl, cutsMl, cutDirMl, nClassesMl); - hfResponse.cacheInputFeaturesIndices(namesInputFeatures); + hfResponse.configure(mlCfg.binsPtMl, mlCfg.cutsMl, mlCfg.cutDirMl, mlCfg.nClassesMl); + hfResponse.cacheInputFeaturesIndices(mlCfg.namesInputFeatures); }; setupFeatures(hfMlResponseLc, useLcMl); setupFeatures(hfMlResponseDplus, useDplusMl); setupFeatures(hfMlResponseD0, useD0Ml); setupFeatures(hfMlResponseDstar, useDstarMl); + setupFeatures(hfMlResponseXic, useXicMl); - const bool useAnyMl = useLcMl || useDplusMl || useD0Ml || useDstarMl; - if (loadModelsFromCCDB && useAnyMl) { - ccdbApi.init(ccdbUrl); + const bool useAnyMl = useLcMl || useDplusMl || useD0Ml || useDstarMl || useXicMl; + if (ccdbCfg.loadModelsFromCCDB && useAnyMl) { + ccdbApi.init(ccdbCfg.ccdbUrl); } auto initModel = [&](auto& hfResponse, bool useMlFlag) { @@ -327,10 +351,10 @@ struct HfProducerCharmHadronsTrackFemtoDream { return; } - if (loadModelsFromCCDB) { - hfResponse.setModelPathsCCDB(onnxFileNames, ccdbApi, modelPathsCCDB, timestampCCDB); + if (ccdbCfg.loadModelsFromCCDB) { + hfResponse.setModelPathsCCDB(ccdbCfg.onnxFileNames, ccdbApi, ccdbCfg.modelPathsCCDB, ccdbCfg.timestampCCDB); } else { - hfResponse.setModelPathsLocal(onnxFileNames); + hfResponse.setModelPathsLocal(ccdbCfg.onnxFileNames); } hfResponse.init(); }; @@ -339,6 +363,7 @@ struct HfProducerCharmHadronsTrackFemtoDream { initModel(hfMlResponseDplus, useDplusMl); initModel(hfMlResponseD0, useD0Ml); initModel(hfMlResponseDstar, useDstarMl); + initModel(hfMlResponseXic, useXicMl); } } @@ -403,41 +428,41 @@ struct HfProducerCharmHadronsTrackFemtoDream { /// Function to retrieve the nominal magnetic field in kG (0.1T) and convert it directly to T void getMagneticFieldTesla(const aod::BCsWithTimestamps::iterator& bc) { - initCCDB(bc, runNumber, ccdb, !isRun3 ? ccdbPathGrp : ccdbPathGrpMag, lut, !isRun3); + initCCDB(bc, runNumber, ccdb, !generalCfg.isRun3 ? ccdbCfg.ccdbPathGrp : ccdbCfg.ccdbPathGrpMag, lut, !generalCfg.isRun3); } template void fillDebugParticle(ParticleType const& particle) { - outputDebugParts(particle.sign(), - (uint8_t)particle.tpcNClsFound(), - particle.tpcNClsFindable(), - (uint8_t)particle.tpcNClsCrossedRows(), - particle.tpcNClsShared(), - particle.tpcInnerParam(), - particle.itsNCls(), - particle.itsNClsInnerBarrel(), - particle.dcaXY(), - particle.dcaZ(), - particle.tpcSignal(), - -999., - particle.tpcNSigmaPi(), - particle.tpcNSigmaKa(), - particle.tpcNSigmaPr(), - particle.tpcNSigmaDe(), - -999., - -999., - -999., - particle.tofNSigmaPi(), - particle.tofNSigmaKa(), - particle.tofNSigmaPr(), - particle.tofNSigmaDe(), - -999., -999., -999., -999., - -999., -999., -999., -999., - -999., -999., -999., -999., - -999., -999., -999., -999., - -999., -999., -999., -999., - -999., -999., -999.); + tables.outputDebugParts(particle.sign(), + (uint8_t)particle.tpcNClsFound(), + particle.tpcNClsFindable(), + (uint8_t)particle.tpcNClsCrossedRows(), + particle.tpcNClsShared(), + particle.tpcInnerParam(), + particle.itsNCls(), + particle.itsNClsInnerBarrel(), + particle.dcaXY(), + particle.dcaZ(), + particle.tpcSignal(), + -999., + particle.tpcNSigmaPi(), + particle.tpcNSigmaKa(), + particle.tpcNSigmaPr(), + particle.tpcNSigmaDe(), + -999., + -999., + -999., + particle.tofNSigmaPi(), + particle.tofNSigmaKa(), + particle.tofNSigmaPr(), + particle.tofNSigmaDe(), + -999., -999., -999., -999., + -999., -999., -999., -999., + -999., -999., -999., -999., + -999., -999., -999., -999., + -999., -999., -999., -999., + -999., -999., -999.); } template @@ -454,7 +479,7 @@ struct HfProducerCharmHadronsTrackFemtoDream { auto motherparticlesMc = particleMc.template mothers_as(); // check pdg code // if this fails, the particle is a fake - if (std::abs(pdgCode) == std::abs(trkPDGCode.value)) { + if (std::abs(pdgCode) == std::abs(trackCfg.trkPDGCode.value)) { // check first if particle is from pile up // check if the collision associated with the particle is the same as the analyzed collision by checking their Ids if ((col.has_mcCollision() && (particleMc.mcCollisionId() != col.mcCollisionId())) || !col.has_mcCollision()) { @@ -470,7 +495,7 @@ struct HfProducerCharmHadronsTrackFemtoDream { // get direct mother auto motherparticleMc = motherparticlesMc.front(); pdgCodeMother = motherparticleMc.pdgCode(); - particleOrigin = checkDaughterType(fdparttype, motherparticleMc.pdgCode()); + particleOrigin = checkDaughterType(fdparttype, motherparticleMc.pdgCode(), pdgCode); // check if particle is material // particle is from inelastic hadronic interaction -> getProcess() == 23 // particle is generated during transport -> getGenStatusCode() == -1 @@ -485,16 +510,16 @@ struct HfProducerCharmHadronsTrackFemtoDream { particleOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kFake; } - outputPartsMc(particleOrigin, pdgCode, particleMc.pt(), particleMc.eta(), particleMc.phi()); - outputPartsMcLabels(outputPartsMc.lastIndex()); - if (isDebug) { - outputPartsExtMcLabels(outputPartsMc.lastIndex()); - outputDebugPartsMc(pdgCodeMother); + tables.outputPartsMc(particleOrigin, pdgCode, particleMc.pt(), particleMc.eta(), particleMc.phi()); + tables.outputPartsMcLabels(tables.outputPartsMc.lastIndex()); + if (generalCfg.isDebug) { + tables.outputPartsExtMcLabels(tables.outputPartsMc.lastIndex()); + tables.outputDebugPartsMc(pdgCodeMother); } } else { - outputPartsMcLabels(-1); - if (isDebug) { - outputPartsExtMcLabels(-1); + tables.outputPartsMcLabels(-1); + if (generalCfg.isDebug) { + tables.outputPartsExtMcLabels(-1); } } } @@ -504,10 +529,10 @@ struct HfProducerCharmHadronsTrackFemtoDream { { if (col.has_mcCollision()) { // auto genMCcol = col.template mcCollision_as(); - // outputMcCollision(genMCcol.multMCNParticlesEta08()); - outputCollsMcLabels(outputMcCollision.lastIndex()); + // tables.outputMcCollision(genMCcol.multMCNParticlesEta08()); + tables.outputCollsMcLabels(tables.outputMcCollision.lastIndex()); } else { - outputCollsMcLabels(-1); + tables.outputCollsMcLabels(-1); } } @@ -532,35 +557,35 @@ struct HfProducerCharmHadronsTrackFemtoDream { auto bc = col.template bc_as(); int64_t timeStamp = bc.timestamp(); // track global index - outputPartsIndex(track.globalIndex()); - outputPartsTime(timeStamp); + tables.outputPartsIndex(track.globalIndex()); + tables.outputPartsTime(timeStamp); // now the table is filled - if (trkPDGCode == kKPlus) { + if (trackCfg.trkPDGCode == kKPlus) { const auto pidTrackPassBit = static_cast(isTrackKaonPidSelected(track)); - outputParts(outputCollision.lastIndex(), - track.pt(), - track.eta(), - track.phi(), - aod::femtodreamparticle::ParticleType::kTrack, - cutContainer.at(femtoDreamTrackSelection::TrackContainerPosition::kCuts), - pidTrackPassBit, - track.dcaXY(), childIDs, 0, 0); + tables.outputParts(tables.outputCollision.lastIndex(), + track.pt(), + track.eta(), + track.phi(), + aod::femtodreamparticle::ParticleType::kTrack, + cutContainer.at(femtoDreamTrackSelection::TrackContainerPosition::kCuts), + pidTrackPassBit, + track.dcaXY(), childIDs, 0, 0); } else { - outputParts(outputCollision.lastIndex(), - track.pt(), - track.eta(), - track.phi(), - aod::femtodreamparticle::ParticleType::kTrack, - cutContainer.at(femtoDreamTrackSelection::TrackContainerPosition::kCuts), - cutContainer.at(femtoDreamTrackSelection::TrackContainerPosition::kPID), - track.dcaXY(), childIDs, 0, 0); + tables.outputParts(tables.outputCollision.lastIndex(), + track.pt(), + track.eta(), + track.phi(), + aod::femtodreamparticle::ParticleType::kTrack, + cutContainer.at(femtoDreamTrackSelection::TrackContainerPosition::kCuts), + cutContainer.at(femtoDreamTrackSelection::TrackContainerPosition::kPID), + track.dcaXY(), childIDs, 0, 0); } fIsTrackFilled = true; // tmpIDtrack.push_back(track.globalIndex()); - if (isDebug.value) { + if (generalCfg.isDebug.value) { fillDebugParticle(track); } @@ -579,8 +604,8 @@ struct HfProducerCharmHadronsTrackFemtoDream { const auto spher = 2.; // dummy value for the moment float mult = 0; int multNtr = 0; - if (isRun3) { - if (useCent) { + if (generalCfg.isRun3) { + if (generalCfg.useCent) { mult = col.centFT0M(); } else { mult = 0; @@ -608,7 +633,7 @@ struct HfProducerCharmHadronsTrackFemtoDream { return; } - outputCollision(vtxZ, mult, multNtr, spher, magField); + tables.outputCollision(vtxZ, mult, multNtr, spher, magField); if constexpr (IsMc) { fillMcCollision(col); } @@ -622,11 +647,11 @@ struct HfProducerCharmHadronsTrackFemtoDream { bool isSelectedMlDstarToD0Pi = true; if constexpr (Channel == DecayChannel::DplusToPiKPi || Channel == DecayChannel::LcToPKPi) { - rowCandCharm3Prong.reserve(rowCandCharm3Prong.lastIndex() + sizeCand * 2 + 1); + tables.rowCandCharm3Prong.reserve(tables.rowCandCharm3Prong.lastIndex() + sizeCand * 2 + 1); } else if constexpr (Channel == DecayChannel::D0ToPiK) { - rowCandCharm2Prong.reserve(rowCandCharm2Prong.lastIndex() + sizeCand * 2 + 1); + tables.rowCandCharm2Prong.reserve(tables.rowCandCharm2Prong.lastIndex() + sizeCand * 2 + 1); } else if constexpr (Channel == DecayChannel::DstarToD0Pi) { - rowCandCharmDstar.reserve(rowCandCharmDstar.lastIndex() + sizeCand + 1); + tables.rowCandCharmDstar.reserve(tables.rowCandCharmDstar.lastIndex() + sizeCand + 1); } for (const auto& candidate : candidates) { @@ -650,8 +675,8 @@ struct HfProducerCharmHadronsTrackFemtoDream { if (functionSelection >= 1) { if constexpr (Channel == DecayChannel::DplusToPiKPi || Channel == DecayChannel::LcToPKPi) { auto trackPos2 = candidate.template prong2_as(); - rowCandCharm3Prong( - outputCollision.lastIndex(), + tables.rowCandCharm3Prong( + tables.outputCollision.lastIndex(), timeStamp, trackPos1.sign() + trackNeg.sign() + trackPos2.sign(), trackPos1.globalIndex(), @@ -682,8 +707,8 @@ struct HfProducerCharmHadronsTrackFemtoDream { } else { LOG(error) << "Unexpected candFlag = " << candFlag; } - rowCandCharm2Prong( - outputCollision.lastIndex(), + tables.rowCandCharm2Prong( + tables.outputCollision.lastIndex(), timeStamp, signD0, trackPos1.globalIndex(), @@ -700,8 +725,8 @@ struct HfProducerCharmHadronsTrackFemtoDream { bdtScoreFd); } else if constexpr (Channel == DecayChannel::DstarToD0Pi) { auto trackPos2 = candidate.template prongPi_as(); - rowCandCharmDstar( - outputCollision.lastIndex(), + tables.rowCandCharmDstar( + tables.outputCollision.lastIndex(), timeStamp, candidate.template prongPi_as().sign(), trackPos1.globalIndex(), @@ -723,7 +748,7 @@ struct HfProducerCharmHadronsTrackFemtoDream { } if constexpr (IsMc) { - rowCandMcCharmHad( + tables.rowCandMcCharmHad( candidate.flagMcMatchRec(), candidate.originMcRec()); } @@ -734,13 +759,13 @@ struct HfProducerCharmHadronsTrackFemtoDream { if constexpr (UseCharmMl) { /// fill with ML information /// BDT index 0: bkg score; BDT index 1: prompt score; BDT index 2: non-prompt score - if (applyMlMode == FillMlFromSelector) { + if (mlCfg.applyMlMode == FillMlFromSelector) { if (candidate.mlProbDplusToPiKPi().size() > 0) { outputMlDplus.at(0) = candidate.mlProbDplusToPiKPi()[0]; /// bkg score outputMlDplus.at(1) = candidate.mlProbDplusToPiKPi()[1]; /// prompt score outputMlDplus.at(2) = candidate.mlProbDplusToPiKPi()[2]; /// non-prompt score } - } else if (applyMlMode == FillMlFromNewBDT) { + } else if (mlCfg.applyMlMode == FillMlFromNewBDT) { isSelectedMlDplusToPiKPi = false; if (candidate.mlProbDplusToPiKPi().size() > 0) { std::vector inputFeaturesDplusToPiKPi = hfMlResponseDplus.getInputFeatures(candidate); @@ -759,7 +784,7 @@ struct HfProducerCharmHadronsTrackFemtoDream { if constexpr (UseCharmMl) { /// fill with ML information /// BDT index 0: bkg score; BDT index 1: prompt score; BDT index 2: non-prompt score - if (applyMlMode == FillMlFromSelector) { + if (mlCfg.applyMlMode == FillMlFromSelector) { if (candidate.mlProbLcToPKPi().size() > 0) { outputMlPKPi.at(0) = candidate.mlProbLcToPKPi()[0]; /// bkg score outputMlPKPi.at(1) = candidate.mlProbLcToPKPi()[1]; /// prompt score @@ -770,7 +795,7 @@ struct HfProducerCharmHadronsTrackFemtoDream { outputMlPiKP.at(1) = candidate.mlProbLcToPiKP()[1]; /// prompt score outputMlPiKP.at(2) = candidate.mlProbLcToPiKP()[2]; /// non-prompt score } - } else if (applyMlMode == FillMlFromNewBDT) { + } else if (mlCfg.applyMlMode == FillMlFromNewBDT) { isSelectedMlLcToPKPi = false; isSelectedMlLcToPiKP = false; if (candidate.mlProbLcToPKPi().size() > 0) { @@ -795,7 +820,7 @@ struct HfProducerCharmHadronsTrackFemtoDream { /// fill with ML information /// BDT index 0: bkg score; BDT index 1: prompt score; BDT index 2: non-prompt score - if (applyMlMode == FillMlFromSelector) { + if (mlCfg.applyMlMode == FillMlFromSelector) { if (candidate.mlProbD0().size() > 0) { outputMlD0.at(0) = candidate.mlProbD0()[0]; /// bkg score outputMlD0.at(1) = candidate.mlProbD0()[1]; /// prompt score @@ -807,7 +832,7 @@ struct HfProducerCharmHadronsTrackFemtoDream { outputMlD0bar.at(2) = candidate.mlProbD0bar()[2]; /// non-prompt score } - } else if (applyMlMode == FillMlFromNewBDT) { + } else if (mlCfg.applyMlMode == FillMlFromNewBDT) { isSelectedMlD0ToPiK = false; isSelectedMlD0barToKPi = false; @@ -837,13 +862,13 @@ struct HfProducerCharmHadronsTrackFemtoDream { if constexpr (UseCharmMl) { /// fill with ML information /// BDT index 0: bkg score; BDT index 1: prompt score; BDT index 2: non-prompt score - if (applyMlMode == FillMlFromSelector) { + if (mlCfg.applyMlMode == FillMlFromSelector) { if (candidate.mlProbDstarToD0Pi().size() > 0) { outputMlDstar.at(0) = candidate.mlProbDstarToD0Pi()[0]; /// bkg score outputMlDstar.at(1) = candidate.mlProbDstarToD0Pi()[1]; /// prompt score outputMlDstar.at(2) = candidate.mlProbDstarToD0Pi()[2]; /// non-prompt score } - } else if (applyMlMode == FillMlFromNewBDT) { + } else if (mlCfg.applyMlMode == FillMlFromNewBDT) { isSelectedMlDstarToD0Pi = false; if (candidate.mlProbDstarToD0Pi().size() > 0) { std::vector inputFeaturesDstarToD0Pi = hfMlResponseDstar.getInputFeatures(candidate, false); @@ -877,9 +902,153 @@ struct HfProducerCharmHadronsTrackFemtoDream { qaRegistry.fill(HIST("hEventQA"), 1 + Event::PairSelected); } - rowMasks(bitTrack, - bitCand, - 0); + tables.rowMasks(bitTrack, + bitCand, + 0); + } + + template + void fillXicHadronTable(CollisionType const& col, TrackType const& tracks, CandType const& candidates, DaughterTrackType const&) + { + const auto vtxZ = col.posZ(); + const auto sizeCand = candidates.size(); + const auto spher = 2.f; + float mult = 0; + int multNtr = 0; + if (generalCfg.isRun3) { + mult = generalCfg.useCent ? col.centFT0M() : 0.f; + multNtr = col.multNTracksPV(); + } else { + mult = 1.f; + multNtr = col.multTracklets(); + } + + const auto rejectionMask = hfEvSel.getHfCollisionRejectionMask(col, mult, ccdb, qaRegistry); + qaRegistry.fill(HIST("hEventQA"), 1 + Event::All); + hfEvSel.fillHistograms(col, rejectionMask, mult); + if (rejectionMask != 0) { + qaRegistry.fill(HIST("hEventQA"), 1 + Event::RejEveSel); + return; + } + + if (isNoSelectedTracks(col, tracks, trackCuts) && sizeCand <= 0) { + qaRegistry.fill(HIST("hEventQA"), 1 + Event::RejNoTracksAndCharm); + return; + } + + tables.outputCollision(vtxZ, mult, multNtr, spher, magField); + if constexpr (IsMc) { + fillMcCollision(col); + } + + tables.rowCandCharm3ProngXic.reserve(tables.rowCandCharm3ProngXic.lastIndex() + sizeCand + 1); + tables.rowCandCharm3ProngXicQa.reserve(tables.rowCandCharm3ProngXicQa.lastIndex() + sizeCand + 1); + + bool isTrackFilled = false; + int nSelectedXic = 0; + + for (const auto& candidate : candidates) { + if (candidate.isSelXicToXiPiPi() < generalCfg.selectionFlagHadron) { + continue; + } + + outputMlXic = {-1.f, -1.f, -1.f}; + bool isSelectedMlXicToXiPiPi = true; + if constexpr (UseCharmMl) { + if (mlCfg.applyMlMode == FillMlFromSelector) { + if (candidate.mlProbXicToXiPiPi().size() > 0) { + outputMlXic.at(0) = candidate.mlProbXicToXiPiPi()[0]; + outputMlXic.at(1) = candidate.mlProbXicToXiPiPi()[1]; + outputMlXic.at(2) = candidate.mlProbXicToXiPiPi()[2]; + } + } else if (mlCfg.applyMlMode == FillMlFromNewBDT) { + isSelectedMlXicToXiPiPi = false; + if (candidate.mlProbXicToXiPiPi().size() > 0) { + std::vector inputFeaturesXicToXiPiPi = hfMlResponseXic.getInputFeatures(candidate); + isSelectedMlXicToXiPiPi = hfMlResponseXic.isSelectedMl(inputFeaturesXicToXiPiPi, candidate.pt(), outputMlXic); + } + if (!isSelectedMlXicToXiPiPi) { + continue; + } + } else { + LOGF(fatal, "Please check your ML configuration."); + } + } + + auto bc = col.template bc_as(); + int64_t timeStamp = bc.timestamp(); + const auto eta0 = static_cast(RecoDecay::eta(std::array{candidate.pxProng0(), candidate.pyProng0(), candidate.pzProng0()})); + const auto eta1 = static_cast(RecoDecay::eta(std::array{candidate.pxProng1(), candidate.pyProng1(), candidate.pzProng1()})); + const auto eta2 = static_cast(RecoDecay::eta(std::array{candidate.pxProng2(), candidate.pyProng2(), candidate.pzProng2()})); + const auto phi0 = static_cast(RecoDecay::phi(candidate.pxProng0(), candidate.pyProng0())); + const auto phi1 = static_cast(RecoDecay::phi(candidate.pxProng1(), candidate.pyProng1())); + const auto phi2 = static_cast(RecoDecay::phi(candidate.pxProng2(), candidate.pyProng2())); + const auto cascBachelorTrack = candidate.template bachelor_as(); + const auto cascPosTrack = candidate.template posTrack_as(); + const auto cascNegTrack = candidate.template negTrack_as(); + + tables.rowCandCharm3ProngXic( + tables.outputCollision.lastIndex(), + timeStamp, + candidate.sign(), + candidate.cascadeId(), + candidate.pi0Id(), + candidate.pi1Id(), + candidate.bachelorId(), + candidate.posTrackId(), + candidate.negTrackId(), + candidate.ptProng0(), + candidate.ptProng1(), + candidate.ptProng2(), + eta0, + eta1, + eta2, + phi0, + phi1, + phi2, + 1 << 0, + outputMlXic.at(0), + outputMlXic.at(1), + outputMlXic.at(2)); + + tables.rowCandCharm3ProngXicQa( + cascBachelorTrack.pt(), + cascBachelorTrack.phi(), + cascBachelorTrack.eta(), + cascPosTrack.pt(), + cascPosTrack.phi(), + cascPosTrack.eta(), + cascNegTrack.pt(), + cascNegTrack.phi(), + cascNegTrack.eta()); + + ++nSelectedXic; + if constexpr (IsMc) { + tables.rowCandMcCharmHad( + candidate.flagMcMatchRec(), + candidate.originMcRec()); + } + } + + isTrackFilled = fillTracksForCharmHadron(col, tracks); + + aod::femtodreamcollision::BitMaskType bitTrack = 0; + if (isTrackFilled) { + bitTrack |= 1 << 0; + qaRegistry.fill(HIST("hEventQA"), 1 + Event::TrackSelected); + } + + aod::femtodreamcollision::BitMaskType bitCand = 0; + if (nSelectedXic > 0) { + bitCand |= 1 << 0; + qaRegistry.fill(HIST("hEventQA"), 1 + Event::CharmSelected); + } + + if (isTrackFilled && nSelectedXic > 0) { + qaRegistry.fill(HIST("hEventQA"), 1 + Event::PairSelected); + } + + tables.rowMasks(bitTrack, bitCand, 0); } // check if there is no selected track @@ -902,11 +1071,11 @@ struct HfProducerCharmHadronsTrackFemtoDream { void fillCharmHadMcGen(ParticleType particles) { // Filling particle properties - rowCandCharmHadGen.reserve(particles.size() + 1); + tables.rowCandCharmHadGen.reserve(particles.size() + 1); if constexpr (Channel == DecayChannel::DplusToPiKPi) { for (const auto& particle : particles) { if (std::abs(particle.flagMcMatchGen()) == hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKPi) { - rowCandCharmHadGen( + tables.rowCandCharmHadGen( particle.mcCollisionId(), particle.flagMcMatchGen(), particle.originMcGen()); @@ -915,7 +1084,7 @@ struct HfProducerCharmHadronsTrackFemtoDream { } else if constexpr (Channel == DecayChannel::LcToPKPi) { for (const auto& particle : particles) { if (std::abs(particle.flagMcMatchGen()) == hf_decay::hf_cand_3prong::DecayChannelMain::LcToPKPi) { - rowCandCharmHadGen( + tables.rowCandCharmHadGen( particle.mcCollisionId(), particle.flagMcMatchGen(), particle.originMcGen()); @@ -924,7 +1093,7 @@ struct HfProducerCharmHadronsTrackFemtoDream { } else if constexpr (Channel == DecayChannel::D0ToPiK) { for (const auto& particle : particles) { if (std::abs(particle.flagMcMatchGen()) == hf_decay::hf_cand_2prong::DecayChannelMain::D0ToPiK) { - rowCandCharmHadGen( + tables.rowCandCharmHadGen( particle.mcCollisionId(), particle.flagMcMatchGen(), particle.originMcGen()); @@ -933,7 +1102,7 @@ struct HfProducerCharmHadronsTrackFemtoDream { } else if constexpr (Channel == DecayChannel::DstarToD0Pi) { for (const auto& particle : particles) { if (std::abs(particle.flagMcMatchGen()) == hf_decay::hf_cand_dstar::DecayChannelMain::DstarToPiKPi) { - rowCandCharmHadGen( + tables.rowCandCharmHadGen( particle.mcCollisionId(), particle.flagMcMatchGen(), particle.originMcGen()); @@ -942,6 +1111,21 @@ struct HfProducerCharmHadronsTrackFemtoDream { } } + void fillXicMcGen(GeneratedXicMc const& particles) + { + tables.rowCandCharmHadGen.reserve(particles.size() + 1); + for (const auto& particle : particles) { + const int absFlag = std::abs(static_cast(particle.flagMcMatchGen())); + if (absFlag == (1 << o2::aod::hf_cand_xic_to_xi_pi_pi::DecayType::XicToXiPiPi) || + absFlag == (1 << o2::aod::hf_cand_xic_to_xi_pi_pi::DecayType::XicToXiResPiToXiPiPi)) { + tables.rowCandCharmHadGen( + particle.mcCollisionId(), + particle.flagMcMatchGen(), + particle.originMcGen()); + } + } + } + /// D0ToPiK void processDataD0ToPiK(FemtoFullCollision const& col, aod::BCsWithTimestamps const&, @@ -1166,6 +1350,105 @@ struct HfProducerCharmHadronsTrackFemtoDream { fillCharmHadMcGen(particles); } PROCESS_SWITCH(HfProducerCharmHadronsTrackFemtoDream, processMcLcToPKPiGen, "Provide Mc Generated lctopkpi", false); + + /// XicToXiPiPi + void processDataXicToXiPiPi(FemtoFullCollision const& col, + aod::BCsWithTimestamps const&, + FemtoHFTracks const& tracks, + aod::FullTracks const& daughterTracks, + soa::Filtered const& candidates) + { + getMagneticFieldTesla(col.bc_as()); + fillXicHadronTable(col, tracks, candidates, daughterTracks); + } + PROCESS_SWITCH(HfProducerCharmHadronsTrackFemtoDream, processDataXicToXiPiPi, "Data for XicToXiPiPi femto (DCAFitter; no HFCANDXICKF)", false); + + void processDataXicToXiPiPiKf(FemtoFullCollision const& col, + aod::BCsWithTimestamps const&, + FemtoHFTracks const& tracks, + aod::FullTracks const& daughterTracks, + soa::Filtered const& candidates) + { + getMagneticFieldTesla(col.bc_as()); + fillXicHadronTable(col, tracks, candidates, daughterTracks); + } + PROCESS_SWITCH(HfProducerCharmHadronsTrackFemtoDream, processDataXicToXiPiPiKf, "Data for XicToXiPiPi femto (KFParticle; requires HFCANDXICKF)", false); + + void processDataXicToXiPiPiWithML(FemtoFullCollision const& col, + aod::BCsWithTimestamps const&, + FemtoHFTracks const& tracks, + aod::FullTracks const& daughterTracks, + soa::Filtered> const& candidates) + { + getMagneticFieldTesla(col.bc_as()); + fillXicHadronTable(col, tracks, candidates, daughterTracks); + } + PROCESS_SWITCH(HfProducerCharmHadronsTrackFemtoDream, processDataXicToXiPiPiWithML, "Data for XicToXiPiPi femto with ML (DCAFitter)", false); + + void processDataXicToXiPiPiWithMLKf(FemtoFullCollision const& col, + aod::BCsWithTimestamps const&, + FemtoHFTracks const& tracks, + aod::FullTracks const& daughterTracks, + soa::Filtered> const& candidates) + { + getMagneticFieldTesla(col.bc_as()); + fillXicHadronTable(col, tracks, candidates, daughterTracks); + } + PROCESS_SWITCH(HfProducerCharmHadronsTrackFemtoDream, processDataXicToXiPiPiWithMLKf, "Data for XicToXiPiPi femto with ML (KFParticle)", false); + + void processMcXicToXiPiPi(FemtoFullCollisionMc const& col, + aod::BCsWithTimestamps const&, + FemtoHFMcTracks const& tracks, + aod::FullTracks const& daughterTracks, + aod::McParticles const&, + soa::Filtered const& candidates) + { + getMagneticFieldTesla(col.bc_as()); + fillXicHadronTable(col, tracks, candidates, daughterTracks); + } + PROCESS_SWITCH(HfProducerCharmHadronsTrackFemtoDream, processMcXicToXiPiPi, "MC for XicToXiPiPi (DCAFitter)", false); + + void processMcXicToXiPiPiKf(FemtoFullCollisionMc const& col, + aod::BCsWithTimestamps const&, + FemtoHFMcTracks const& tracks, + aod::FullTracks const& daughterTracks, + aod::McParticles const&, + soa::Filtered const& candidates) + { + getMagneticFieldTesla(col.bc_as()); + fillXicHadronTable(col, tracks, candidates, daughterTracks); + } + PROCESS_SWITCH(HfProducerCharmHadronsTrackFemtoDream, processMcXicToXiPiPiKf, "MC for XicToXiPiPi (KFParticle)", false); + + void processMcXicToXiPiPiWithML(FemtoFullCollisionMc const& col, + aod::BCsWithTimestamps const&, + FemtoHFMcTracks const& tracks, + aod::FullTracks const& daughterTracks, + aod::McParticles const&, + soa::Filtered> const& candidates) + { + getMagneticFieldTesla(col.bc_as()); + fillXicHadronTable(col, tracks, candidates, daughterTracks); + } + PROCESS_SWITCH(HfProducerCharmHadronsTrackFemtoDream, processMcXicToXiPiPiWithML, "MC for XicToXiPiPi with ML (DCAFitter)", false); + + void processMcXicToXiPiPiWithMLKf(FemtoFullCollisionMc const& col, + aod::BCsWithTimestamps const&, + FemtoHFMcTracks const& tracks, + aod::FullTracks const& daughterTracks, + aod::McParticles const&, + soa::Filtered> const& candidates) + { + getMagneticFieldTesla(col.bc_as()); + fillXicHadronTable(col, tracks, candidates, daughterTracks); + } + PROCESS_SWITCH(HfProducerCharmHadronsTrackFemtoDream, processMcXicToXiPiPiWithMLKf, "MC for XicToXiPiPi with ML (KFParticle)", false); + + void processMcXicToXiPiPiGen(GeneratedXicMc const& particles) + { + fillXicMcGen(particles); + } + PROCESS_SWITCH(HfProducerCharmHadronsTrackFemtoDream, processMcXicToXiPiPiGen, "MC generated XicToXiPiPi", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGHF/HFC/TableProducer/producerCharmHadronsV0FemtoDream.cxx b/PWGHF/HFC/TableProducer/producerCharmHadronsV0FemtoDream.cxx index 0fdbfec790e..b89a974f220 100644 --- a/PWGHF/HFC/TableProducer/producerCharmHadronsV0FemtoDream.cxx +++ b/PWGHF/HFC/TableProducer/producerCharmHadronsV0FemtoDream.cxx @@ -524,7 +524,7 @@ struct HfProducerCharmHadronsV0FemtoDream { // get direct mother auto motherparticleMc = motherparticlesMc.front(); pdgCodeMother = motherparticleMc.pdgCode(); - particleOrigin = checkDaughterType(fdparttype, motherparticleMc.pdgCode()); + particleOrigin = checkDaughterType(fdparttype, motherparticleMc.pdgCode(), pdgCode); // check if particle is material // particle is from inelastic hadronic interaction -> getProcess() == 23 // particle is generated during transport -> getGenStatusCode() == -1 diff --git a/PWGHF/HFC/Tasks/taskCharmHadronsTrackFemtoDream.cxx b/PWGHF/HFC/Tasks/taskCharmHadronsTrackFemtoDream.cxx index 5db5728d240..e7f10007cfa 100644 --- a/PWGHF/HFC/Tasks/taskCharmHadronsTrackFemtoDream.cxx +++ b/PWGHF/HFC/Tasks/taskCharmHadronsTrackFemtoDream.cxx @@ -86,7 +86,8 @@ struct HfTaskCharmHadronsTrackFemtoDream { enum DecayChannel { DplusToPiKPi = 0, LcToPKPi, D0ToPiK, - DstarToD0Pi + DstarToD0Pi, + XicToXiPiPi }; constexpr static int OriginRecPrompt = 1; @@ -107,14 +108,14 @@ struct HfTaskCharmHadronsTrackFemtoDream { struct : ConfigurableGroup { Configurable charmHadBkgBDTmax{"charmHadBkgBDTmax", 1., "Maximum background bdt score for Charm Hadron (particle 2)"}; Configurable charmHadCandSel{"charmHadCandSel", 1, "candidate selection for charm hadron"}; - Configurable charmHadMcSel{"charmHadMcSel", DecayChannelMain::LcToPKPi, "charm hadron selection for mc, DplusToPiKPi = 1, LcToPKPi = 17"}; + Configurable charmHadMcSel{"charmHadMcSel", DecayChannelMain::LcToPKPi, "MC matching flag for the selected charm hadron decay channel"}; Configurable charmHadFdBDTmin{"charmHadFdBDTmin", 0., "Minimum feed-down bdt score Charm Hadron (particle 2)"}; Configurable charmHadFdBDTmax{"charmHadFdBDTmax", 1., "Maximum feed-down bdt score Charm Hadron (particle 2)"}; Configurable charmHadMaxInvMass{"charmHadMaxInvMass", 2.45, "Maximum invariant mass of Charm Hadron (particle 2)"}; Configurable charmHadMinInvMass{"charmHadMinInvMass", 2.15, "Minimum invariant mass of Charm Hadron (particle 2)"}; Configurable charmHadMinPt{"charmHadMinPt", 0., "Minimum pT of Charm Hadron (particle 2)"}; Configurable charmHadMaxPt{"charmHadMaxPt", 999., "Maximum pT of Charm Hadron (particle 2)"}; - Configurable charmHadPDGCode{"charmHadPDGCode", 4122, "PDG code of particle 2 Charm Hadron"}; + Configurable charmHadPDGCode{"charmHadPDGCode", Pdg::kLambdaCPlus, "PDG code of particle 2 Charm Hadron"}; Configurable charmHadPromptBDTmin{"charmHadPromptBDTmin", 0., "Minimum prompt bdt score Charm Hadron (particle 2)"}; Configurable charmHadPromptBDTmax{"charmHadPromptBDTmax", 1., "Maximum prompt bdt score Charm Hadron (particle 2)"}; } charmSel; @@ -150,7 +151,7 @@ struct HfTaskCharmHadronsTrackFemtoDream { /// Particle 1 (track) struct : ConfigurableGroup { Configurable cutBitTrack1{"cutBitTrack1", 8188, "Particle 1 (Track) - Selection bit from cutCulator"}; - Configurable pdgCodeTrack1{"pdgCodeTrack1", 2212, "PDG code of Particle 1 (Track)"}; + Configurable pdgCodeTrack1{"pdgCodeTrack1", kProton, "PDG code of Particle 1 (Track)"}; Configurable pidThresTrack1{"pidThresTrack1", 0.75, "Momentum threshold for PID selection for particle 1 (Track)"}; Configurable tpcBitTrack1{"tpcBitTrack1", 4, "PID TPC bit from cutCulator for particle 1 (Track)"}; Configurable tpcTofBitTrack1{"tpcTofBitTrack1", 2, "PID TPCTOF bit from cutCulator for particle 1 (Track)"}; @@ -164,6 +165,9 @@ struct HfTaskCharmHadronsTrackFemtoDream { using FilteredCharmCand3Prongs = soa::Filtered; using FilteredCharmCand3Prong = FilteredCharmCand3Prongs::iterator; + using FilteredCharmCand3ProngsXic = soa::Filtered; + using FilteredCharmCand3ProngXic = FilteredCharmCand3ProngsXic::iterator; + using FilteredCharmCand2Prongs = soa::Filtered; using FilteredCharmCand2Prong = FilteredCharmCand2Prongs::iterator; @@ -173,6 +177,9 @@ struct HfTaskCharmHadronsTrackFemtoDream { using FilteredCharmMcCand3Prongs = soa::Filtered>; using FilteredCharmMcCand3Prong = FilteredCharmMcCand3Prongs::iterator; + using FilteredCharmMcCand3ProngsXic = soa::Filtered>; + using FilteredCharmMcCand3ProngXic = FilteredCharmMcCand3ProngsXic::iterator; + using FilteredCharmMcCand2Prongs = soa::Filtered>; using FilteredCharmMcCand2Prong = FilteredCharmMcCand2Prongs::iterator; @@ -200,10 +207,13 @@ struct HfTaskCharmHadronsTrackFemtoDream { Filter trackPtFilterLow = ifnode(aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack), aod::femtodreamparticle::pt < trackSel.ptTrack1Max, true); Filter trackPtFilterUp = ifnode(aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack), aod::femtodreamparticle::pt > trackSel.ptTrack1Min, true); - Preslice perCol = aod::femtodreamparticle::fdCollisionId; - Preslice perHf3ProngByCol = aod::femtodreamparticle::fdCollisionId; - Preslice perHf2ProngByCol = aod::femtodreamparticle::fdCollisionId; - Preslice perHfDstarByCol = aod::femtodreamparticle::fdCollisionId; + struct : PresliceGroup { + Preslice perCol = aod::femtodreamparticle::fdCollisionId; + Preslice perHf3ProngByCol = aod::femtodreamparticle::fdCollisionId; + Preslice perHf3ProngXicByCol = aod::femtodreamparticle::fdCollisionId; + Preslice perHf2ProngByCol = aod::femtodreamparticle::fdCollisionId; + Preslice perHfDstarByCol = aod::femtodreamparticle::fdCollisionId; + } preslices; /// Partition for particle 1 Partition partitionTrk1 = (aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack)) && (ncheckbit(aod::femtodreamparticle::cut, trackSel.cutBitTrack1)) && ifnode(aod::femtodreamparticle::pt * coshEta(aod::femtodreamparticle::eta) <= trackSel.pidThresTrack1, ncheckbit(aod::femtodreamparticle::pidcut, trackSel.tpcBitTrack1), ncheckbit(aod::femtodreamparticle::pidcut, trackSel.tpcTofBitTrack1)); @@ -217,10 +227,12 @@ struct HfTaskCharmHadronsTrackFemtoDream { /// Partition for particle 2 Partition partitionCharmHadron3Prong = aod::fdhf::bdtBkg < charmSel.charmHadBkgBDTmax && aod::fdhf::bdtFD < charmSel.charmHadFdBDTmax && aod::fdhf::bdtFD > charmSel.charmHadFdBDTmin&& aod::fdhf::bdtPrompt charmSel.charmHadPromptBDTmin; + Partition partitionCharmHadron3ProngXic = aod::fdhf::bdtBkg < charmSel.charmHadBkgBDTmax && aod::fdhf::bdtFD < charmSel.charmHadFdBDTmax && aod::fdhf::bdtFD > charmSel.charmHadFdBDTmin&& aod::fdhf::bdtPrompt charmSel.charmHadPromptBDTmin; Partition partitionCharmHadron2Prong = aod::fdhf::bdtBkg < charmSel.charmHadBkgBDTmax && aod::fdhf::bdtFD < charmSel.charmHadFdBDTmax && aod::fdhf::bdtFD > charmSel.charmHadFdBDTmin&& aod::fdhf::bdtPrompt charmSel.charmHadPromptBDTmin; Partition partitionCharmHadronDstar = aod::fdhf::bdtBkg < charmSel.charmHadBkgBDTmax && aod::fdhf::bdtFD < charmSel.charmHadFdBDTmax && aod::fdhf::bdtFD > charmSel.charmHadFdBDTmin&& aod::fdhf::bdtPrompt charmSel.charmHadPromptBDTmin; Partition partitionMcCharmHadron3Prong = aod::fdhf::originMcRec == OriginRecPrompt || aod::fdhf::originMcRec == OriginRecFD; + Partition partitionMcCharmHadron3ProngXic = aod::fdhf::originMcRec == OriginRecPrompt || aod::fdhf::originMcRec == OriginRecFD; Partition partitionMcCharmHadron2Prong = aod::fdhf::originMcRec == OriginRecPrompt || aod::fdhf::originMcRec == OriginRecFD; Partition partitionMcCharmHadronDstar = aod::fdhf::originMcRec == OriginRecPrompt || aod::fdhf::originMcRec == OriginRecFD; @@ -282,21 +294,23 @@ struct HfTaskCharmHadronsTrackFemtoDream { HistogramRegistry registryMixQa{"registryMixQa"}; HistogramRegistry registryCharmHadronQa{"registryCharmHadronQa"}; - float massOne = o2::analysis::femtoDream::getMass(trackSel.pdgCodeTrack1); - float massTwo = o2::analysis::femtoDream::getMass(charmSel.charmHadPDGCode); - int8_t partSign = 0; + float massOne = 0.f; + float massTwo = 0.f; int64_t processType = 0; void init(InitContext& /*context*/) { - std::array processes = {doprocessDataLcTrk, doprocessDataDplusTrk, doprocessDataD0Trk, doprocessDataDstarTrk, doprocessMcLcTrk, doprocessMcDplusTrk, doprocessMcD0Trk, doprocessMcDstarTrk}; + std::array processes = {doprocessDataLcTrk, doprocessDataDplusTrk, doprocessDataD0Trk, doprocessDataDstarTrk, doprocessDataXicTrk, doprocessMcLcTrk, doprocessMcDplusTrk, doprocessMcD0Trk, doprocessMcDstarTrk, doprocessMcXicTrk}; if (std::accumulate(processes.begin(), processes.end(), 0) != 1) { LOGP(fatal, "One and only one process function must be enabled at a time."); } - bool process3Prong = doprocessDataLcTrk || doprocessDataDplusTrk || doprocessMcLcTrk || doprocessMcDplusTrk; + bool process3Prong = doprocessDataLcTrk || doprocessDataDplusTrk || doprocessDataXicTrk || doprocessMcLcTrk || doprocessMcDplusTrk || doprocessMcXicTrk; bool process2Prong = doprocessDataD0Trk || doprocessMcD0Trk; bool processDstar = doprocessDataDstarTrk || doprocessMcDstarTrk; + massOne = o2::analysis::femtoDream::getMass(trackSel.pdgCodeTrack1.value); + massTwo = o2::analysis::femtoDream::getMass(charmSel.charmHadPDGCode.value); + // setup columnpolicy for binning colBinningMult = {{mixingBinVztx, mixingBinMult}, true}; colBinningMultPercentile = {{mixingBinVztx, mixingBinMultPercentile}, true}; @@ -312,7 +326,7 @@ struct HfTaskCharmHadronsTrackFemtoDream { highkstarCut, smearingByOrigin, binInvMass); - sameEventCont.setPDGCodes(trackSel.pdgCodeTrack1, charmSel.charmHadPDGCode); + sameEventCont.setPDGCodes(trackSel.pdgCodeTrack1.value, charmSel.charmHadPDGCode.value); mixedEventCont.init(®istry, binkstar, binpTTrack, binkT, binmT, mixingBinMult, mixingBinMultPercentile, bin4Dkstar, bin4DmT, bin4DMult, bin4DmultPercentile, @@ -320,7 +334,7 @@ struct HfTaskCharmHadronsTrackFemtoDream { highkstarCut, smearingByOrigin, binInvMass); - mixedEventCont.setPDGCodes(trackSel.pdgCodeTrack1, charmSel.charmHadPDGCode); + mixedEventCont.setPDGCodes(trackSel.pdgCodeTrack1.value, charmSel.charmHadPDGCode.value); registryMixQa.add("MixingQA/hSECollisionBins", "; bin; Entries", kTH1F, {{120, -0.5, 119.5}}); registryMixQa.add("MixingQA/hSECollisionPool", "; Vz (cm); Mul", kTH2F, {{100, -10, 10}, {200, 0, 200}}); registryMixQa.add("MixingQA/hMECollisionBins", "; bin; Entries", kTH1F, {{120, -0.5, 119.5}}); @@ -349,7 +363,7 @@ struct HfTaskCharmHadronsTrackFemtoDream { } /// Compute the charm hadron candidates mass with the daughter masses - /// assumes the candidate is either a D+ or Λc+ or D0 or Dstar + /// assumes the candidate is either a D+ or Λc+ or D0 or Dstar or Ξc+ template float getCharmHadronMass(const Candidate& cand, bool ReturnDaughMass = false) { @@ -387,6 +401,9 @@ struct HfTaskCharmHadronsTrackFemtoDream { } else { return mDstar - mD0; } + } else if constexpr (Channel == DecayChannel::XicToXiPiPi) { + invMass = cand.m(std::array{MassXiMinus, MassPiPlus, MassPiPlus}); + return invMass; } // Add more channels as needed return 0.f; @@ -433,7 +450,15 @@ struct HfTaskCharmHadronsTrackFemtoDream { return static_cast(RecoDecay::m(pVecCharmTrk, massCharmTrk)); } - // 3-prong:Λc → p K π, D+ → π K π + track + // Ξc⁺ → Ξ π π + track + if constexpr (Channel == DecayChannel::XicToXiPiPi) { + auto pVecProng2 = RecoDecayPtEtaPhi::pVector(cand.prong2Pt(), cand.prong2Eta(), cand.prong2Phi()); + const auto pVecCharmTrk = std::array{pVecProng0, pVecProng1, pVecProng2, pVecTrack}; + const std::array massCharmTrk{MassXiMinus, MassPiPlus, MassPiPlus, trackMassHyp}; + return static_cast(RecoDecay::m(pVecCharmTrk, massCharmTrk)); + } + + // 3-prong: Λc → p K π, D+ → π K π, D* → D0π + track if constexpr (Channel == DecayChannel::LcToPKPi || Channel == DecayChannel::DplusToPiKPi || Channel == DecayChannel::DstarToD0Pi) { auto pVecProng2 = RecoDecayPtEtaPhi::pVector(cand.prong2Pt(), cand.prong2Eta(), cand.prong2Phi()); const auto pVecCharmTrk = std::array{pVecProng0, pVecProng1, pVecProng2, pVecTrack}; @@ -502,6 +527,19 @@ struct HfTaskCharmHadronsTrackFemtoDream { } } + if constexpr (Channel == DecayChannel::XicToXiPiPi) { + if (p1.trackId() == p2.prong1Id() || p1.trackId() == p2.prong2Id() || + p1.trackId() == p2.cascBachelorTrackId() || + p1.trackId() == p2.cascPosTrackId() || p1.trackId() == p2.cascNegTrackId()) { + continue; + } + if (pairQASetting.useCPR.value) { + if (pairCloseRejectionSE3Prong.isClosePair(p1, p2, parts, col.magField())) { + continue; + } + } + } + if constexpr (Channel == DecayChannel::DstarToD0Pi) { if (p1.trackId() == p2.prong0Id() || p1.trackId() == p2.prong1Id() || p1.trackId() == p2.prong2Id()) { continue; @@ -533,7 +571,7 @@ struct HfTaskCharmHadronsTrackFemtoDream { float deltaInvMassPair = getCharmHadronTrackMass(p2, p1, trackSel.pdgCodeTrack1.value) - invMass; - // proton track charge + // associated track charge float chargeTrack = 0.; if ((p1.cut() & CutBitChargePositive) == CutBitChargePositive) { chargeTrack = PositiveCharge; @@ -632,6 +670,14 @@ struct HfTaskCharmHadronsTrackFemtoDream { } } + if constexpr (Channel == DecayChannel::XicToXiPiPi) { + if (pairQASetting.useCPR.value) { + if (pairCloseRejectionME3Prong.isClosePair(p1, p2, parts, collision1.magField())) { + continue; + } + } + } + if constexpr (Channel == DecayChannel::DstarToD0Pi) { if (pairQASetting.useCPR.value) { @@ -662,7 +708,7 @@ struct HfTaskCharmHadronsTrackFemtoDream { float deltaInvMassPair = getCharmHadronTrackMass(p2, p1, trackSel.pdgCodeTrack1.value) - invMass; - // proton track charge + // associated track charge float chargeTrack = 0.; if ((p1.cut() & CutBitChargePositive) == CutBitChargePositive) { chargeTrack = PositiveCharge; @@ -740,6 +786,21 @@ struct HfTaskCharmHadronsTrackFemtoDream { part.bdtBkg(), part.bdtPrompt(), part.bdtFD()); + } else if constexpr (Channel == DecayChannel::XicToXiPiPi) { + rowFemtoResultCharm3Prong( + col.globalIndex(), + timeStamp, + invMass, + part.pt(), + part.eta(), + part.phi(), + part.cascId(), + part.prong1Id(), + part.prong2Id(), + part.charge(), + part.bdtBkg(), + part.bdtPrompt(), + part.bdtFD()); } else if constexpr (Channel == DecayChannel::D0ToPiK) { rowFemtoResultCharm2Prong( col.globalIndex(), @@ -1000,6 +1061,49 @@ struct HfTaskCharmHadronsTrackFemtoDream { } PROCESS_SWITCH(HfTaskCharmHadronsTrackFemtoDream, processDataDstarTrk, "Enable processing DstarToD0Pi and Tracks correlation", false); + void processDataXicTrk(FilteredCollisions const& cols, + FilteredFDParticles const& parts, + FilteredCharmCand3ProngsXic const&) + { + for (const auto& col : cols) { + eventHisto.fillQA(col); + auto* partitionTrk1Selected = &partitionTrk1; + if (trackSel.pdgCodeTrack1.value == kKPlus) { + partitionTrk1Selected = &partitionTrk1Ka; + } + auto sliceTrk1 = partitionTrk1Selected->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); + auto sliceCharmHad = partitionCharmHadron3ProngXic->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); + if (fillTableWithCharm.value && sliceCharmHad.size() == 0) { + continue; + } else { + fillTables(col, sliceTrk1, sliceCharmHad); + } + if (sliceCharmHad.size() > 0 && sliceTrk1.size() > 0) { + doSameEvent(sliceCharmHad, sliceTrk1, parts, col); + } + } + if (mixSetting.doMixEvent) { + auto* partitionTrk1Selected = &partitionTrk1; + if (trackSel.pdgCodeTrack1.value == kKPlus) { + partitionTrk1Selected = &partitionTrk1Ka; + } + switch (mixSetting.mixingBinPolicy) { + case femtodreamcollision::kMult: + doMixedEvent(cols, partitionCharmHadron3ProngXic, *partitionTrk1Selected, parts, colBinningMult); + break; + case femtodreamcollision::kMultPercentile: + doMixedEvent(cols, partitionCharmHadron3ProngXic, *partitionTrk1Selected, parts, colBinningMultPercentile); + break; + case femtodreamcollision::kMultMultPercentile: + doMixedEvent(cols, partitionCharmHadron3ProngXic, *partitionTrk1Selected, parts, colBinningMultMultPercentile); + break; + default: + LOG(fatal) << "Invalid binning policiy specifed. Breaking..."; + } + } + } + PROCESS_SWITCH(HfTaskCharmHadronsTrackFemtoDream, processDataXicTrk, "Enable processing XicToXiPiPi and Tracks correlation", false); + void processMcLcTrk(FilteredMcColisions const& cols, FilteredFDMcParts const& parts, o2::aod::FDMCParticles const&, @@ -1139,6 +1243,47 @@ struct HfTaskCharmHadronsTrackFemtoDream { } } PROCESS_SWITCH(HfTaskCharmHadronsTrackFemtoDream, processMcDstarTrk, "Enable processing DstarToD0Pi and Tracks correlation for Monte Carlo", false); + + void processMcXicTrk(FilteredMcColisions const& cols, + FilteredFDMcParts const& parts, + o2::aod::FDMCParticles const&, + o2::aod::FDExtMCParticles const&, + FilteredCharmMcCand3ProngsXic const&) + { + for (const auto& col : cols) { + eventHisto.fillQA(col); + auto* partitionTrk1Selected = &partitionMcTrk1; + if (trackSel.pdgCodeTrack1.value == kKPlus) { + partitionTrk1Selected = &partitionMcTrk1Ka; + } + auto sliceMcTrk1 = partitionTrk1Selected->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); + auto sliceMcCharmHad = partitionMcCharmHadron3ProngXic->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); + if ((col.bitmaskTrackOne() & bitMask) != bitMask || (col.bitmaskTrackTwo() & bitMask) != bitMask) { + continue; + } + doSameEvent(sliceMcCharmHad, sliceMcTrk1, parts, col); + } + if (mixSetting.doMixEvent) { + auto* partitionTrk1Selected = &partitionMcTrk1; + if (trackSel.pdgCodeTrack1.value == kKPlus) { + partitionTrk1Selected = &partitionMcTrk1Ka; + } + switch (mixSetting.mixingBinPolicy) { + case femtodreamcollision::kMult: + doMixedEvent(cols, partitionMcCharmHadron3ProngXic, *partitionTrk1Selected, parts, colBinningMult); + break; + case femtodreamcollision::kMultPercentile: + doMixedEvent(cols, partitionMcCharmHadron3ProngXic, *partitionTrk1Selected, parts, colBinningMultPercentile); + break; + case femtodreamcollision::kMultMultPercentile: + doMixedEvent(cols, partitionMcCharmHadron3ProngXic, *partitionTrk1Selected, parts, colBinningMultMultPercentile); + break; + default: + LOG(fatal) << "Invalid binning policiy specifed. Breaking..."; + } + } + } + PROCESS_SWITCH(HfTaskCharmHadronsTrackFemtoDream, processMcXicTrk, "Enable processing XicToXiPiPi and Tracks correlation for Monte Carlo", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc)