From ec30e765b9c69586e65e16810d922edbd1328695 Mon Sep 17 00:00:00 2001 From: Valerio Di Bella Date: Fri, 18 Sep 2026 10:13:39 +0200 Subject: [PATCH] Adding : ML and skimming in correlator + other minor change --- .../HFC/DataModel/ReducedDMesonPairsTables.h | 50 +++--- PWGHF/HFC/TableProducer/CMakeLists.txt | 2 +- .../correlatorDplusDplusReduced.cxx | 130 ++++++++++++++- .../taskCorrelationDplusDplusReduced.cxx | 155 +++++++++++++++--- 4 files changed, 285 insertions(+), 52 deletions(-) diff --git a/PWGHF/HFC/DataModel/ReducedDMesonPairsTables.h b/PWGHF/HFC/DataModel/ReducedDMesonPairsTables.h index 9c4484de852..b78f46f2557 100644 --- a/PWGHF/HFC/DataModel/ReducedDMesonPairsTables.h +++ b/PWGHF/HFC/DataModel/ReducedDMesonPairsTables.h @@ -23,6 +23,8 @@ #include #include +#include + namespace o2::aod { DECLARE_SOA_TABLE(HfCandDpFullEvs, "AOD", "HFCANDDPFULLEV", @@ -38,6 +40,8 @@ DECLARE_SOA_TABLE(HfCandDpMcEvs, "AOD", "HFCANDDPMCEV", namespace full { +DECLARE_SOA_INDEX_COLUMN_FULL(HfCandDpFullEv, hfCandDpFullEv, int32_t, HfCandDpFullEvs, ""); +DECLARE_SOA_INDEX_COLUMN_FULL(HfCandDpMcEv, hfCandDpFullEvMC, int32_t, HfCandDpMcEvs, ""); DECLARE_SOA_COLUMN(RSecondaryVertex, rSecondaryVertex, float); //! Radius of secondary vertex (cm) DECLARE_SOA_COLUMN(PtProng0, ptProng0, float); //! Transverse momentum of prong0 (GeV/c) DECLARE_SOA_COLUMN(PProng0, pProng0, float); //! Momentum of prong0 (GeV/c) @@ -57,8 +61,6 @@ DECLARE_SOA_COLUMN(Eta, eta, float); DECLARE_SOA_COLUMN(Phi, phi, float); //! Azimuth angle of candidate DECLARE_SOA_COLUMN(E, e, float); //! Energy of candidate (GeV) DECLARE_SOA_COLUMN(Centrality, centrality, float); //! Collision centrality -DECLARE_SOA_INDEX_COLUMN(HfCandDpMcEv, hfCandDpMcEv); //! The Mc collision index this MC particles belongs to -DECLARE_SOA_INDEX_COLUMN(HfCandDpFullEv, hfCandDpFullEv); //! The collision index this candidate belongs to DECLARE_SOA_COLUMN(NSigTpcPi0, nSigTpcPi0, float); //! TPC Nsigma separation for prong0 with pion mass hypothesis DECLARE_SOA_COLUMN(NSigTpcKa0, nSigTpcKa0, float); //! TPC Nsigma separation for prong0 with kaon mass hypothesis DECLARE_SOA_COLUMN(NSigTofPi0, nSigTofPi0, float); //! TOF Nsigma separation for prong0 with pion mass hypothesis @@ -71,12 +73,12 @@ DECLARE_SOA_COLUMN(NSigTpcPi2, nSigTpcPi2, float); DECLARE_SOA_COLUMN(NSigTpcKa2, nSigTpcKa2, float); //! TPC Nsigma separation for prong2 with kaon mass hypothesis DECLARE_SOA_COLUMN(NSigTofPi2, nSigTofPi2, float); //! TOF Nsigma separation for prong2 with pion mass hypothesis DECLARE_SOA_COLUMN(NSigTofKa2, nSigTofKa2, float); //! TOF Nsigma separation for prong2 with kaon mass hypothesis -DECLARE_SOA_COLUMN(NSigTpcTofPi0, nSigTpcTofPi0, float); //! TPC and TOF combined Nsigma separation for prong0 with pion mass hypothesis -DECLARE_SOA_COLUMN(NSigTpcTofKa0, nSigTpcTofKa0, float); //! TPC and TOF combined Nsigma separation for prong0 with kaon mass hypothesis -DECLARE_SOA_COLUMN(NSigTpcTofPi1, nSigTpcTofPi1, float); //! TPC and TOF combined Nsigma separation for prong1 with pion mass hypothesis -DECLARE_SOA_COLUMN(NSigTpcTofKa1, nSigTpcTofKa1, float); //! TPC and TOF combined Nsigma separation for prong1 with kaon mass hypothesis -DECLARE_SOA_COLUMN(NSigTpcTofPi2, nSigTpcTofPi2, float); //! TPC and TOF combined Nsigma separation for prong2 with pion mass hypothesis -DECLARE_SOA_COLUMN(NSigTpcTofKa2, nSigTpcTofKa2, float); //! TPC and TOF combined Nsigma separation for prong2 with kaon mass hypothesis +DECLARE_SOA_COLUMN(TPCTofNSigmaPi0, tpcTofNSigmaPi0, float); //! TPC and TOF combined Nsigma separation for prong0 with pion mass hypothesis +DECLARE_SOA_COLUMN(TPCTofNSigmaKa0, tpcTofNSigmaKa0, float); //! TPC and TOF combined Nsigma separation for prong0 with kaon mass hypothesis +DECLARE_SOA_COLUMN(TPCTofNSigmaPi1, tpcTofNSigmaPi1, float); //! TPC and TOF combined Nsigma separation for prong1 with pion mass hypothesis +DECLARE_SOA_COLUMN(TPCTofNSigmaKa1, tpcTofNSigmaKa1, float); //! TPC and TOF combined Nsigma separation for prong1 with kaon mass hypothesis +DECLARE_SOA_COLUMN(TPCTofNSigmaPi2, tpcTofNSigmaPi2, float); //! TPC and TOF combined Nsigma separation for prong2 with pion mass hypothesis +DECLARE_SOA_COLUMN(TPCTofNSigmaKa2, tpcTofNSigmaKa2, float); //! TPC and TOF combined Nsigma separation for prong2 with kaon mass hypothesis DECLARE_SOA_COLUMN(DecayLength, decayLength, float); //! Decay length of candidate (cm) DECLARE_SOA_COLUMN(DecayLengthXY, decayLengthXY, float); //! Transverse decay length of candidate (cm) DECLARE_SOA_COLUMN(DecayLengthNormalised, decayLengthNormalised, float); //! Normalised decay length of candidate @@ -96,7 +98,7 @@ DECLARE_SOA_TABLE(HfCandDpMls, "AOD", "HFCANDDPML", full::MlScore0, full::MlScore1) -DECLARE_SOA_TABLE(HfCandDpTinys, "AOD", "HFCANDDPTINY", +DECLARE_SOA_TABLE(HfCandDpTinys, "AOD", "HFCANDDPTINY", o2::soa::Index<>, full::CandidateSelFlag, full::M, full::Pt, @@ -107,7 +109,7 @@ DECLARE_SOA_TABLE(HfCandDpTinys, "AOD", "HFCANDDPTINY", hf_cand_mc_flag::OriginMcRec, hf_cand_mc_flag::FlagMcDecayChanRec) -DECLARE_SOA_TABLE(HfCandDpLites, "AOD", "HFCANDDPLITE", +DECLARE_SOA_TABLE(HfCandDpLites, "AOD", "HFCANDDPLITE", o2::soa::Index<>, hf_cand::Chi2PCA, full::DecayLength, full::DecayLengthXY, @@ -126,20 +128,20 @@ DECLARE_SOA_TABLE(HfCandDpLites, "AOD", "HFCANDDPLITE", full::NSigTpcKa0, full::NSigTofPi0, full::NSigTofKa0, - full::NSigTpcTofPi0, - full::NSigTpcTofKa0, + full::TPCTofNSigmaPi0, + full::TPCTofNSigmaKa0, full::NSigTpcPi1, full::NSigTpcKa1, full::NSigTofPi1, full::NSigTofKa1, - full::NSigTpcTofPi1, - full::NSigTpcTofKa1, + full::TPCTofNSigmaPi1, + full::TPCTofNSigmaKa1, full::NSigTpcPi2, full::NSigTpcKa2, full::NSigTofPi2, full::NSigTofKa2, - full::NSigTpcTofPi2, - full::NSigTpcTofKa2, + full::TPCTofNSigmaPi2, + full::TPCTofNSigmaKa2, full::CandidateSelFlag, full::M, full::Pt, @@ -155,7 +157,7 @@ DECLARE_SOA_TABLE(HfCandDpLites, "AOD", "HFCANDDPLITE", hf_cand_mc_flag::OriginMcRec, hf_cand_mc_flag::FlagMcDecayChanRec) -DECLARE_SOA_TABLE(HfCandDpFulls, "AOD", "HFCANDDPFULL", +DECLARE_SOA_TABLE(HfCandDpFulls, "AOD", "HFCANDDPFULL", o2::soa::Index<>, hf_cand::XSecondaryVertex, hf_cand::YSecondaryVertex, hf_cand::ZSecondaryVertex, @@ -201,20 +203,20 @@ DECLARE_SOA_TABLE(HfCandDpFulls, "AOD", "HFCANDDPFULL", full::NSigTpcKa0, full::NSigTofPi0, full::NSigTofKa0, - full::NSigTpcTofPi0, - full::NSigTpcTofKa0, + full::TPCTofNSigmaPi0, + full::TPCTofNSigmaKa0, full::NSigTpcPi1, full::NSigTpcKa1, full::NSigTofPi1, full::NSigTofKa1, - full::NSigTpcTofPi1, - full::NSigTpcTofKa1, + full::TPCTofNSigmaPi1, + full::TPCTofNSigmaKa1, full::NSigTpcPi2, full::NSigTpcKa2, full::NSigTofPi2, full::NSigTofKa2, - full::NSigTpcTofPi2, - full::NSigTpcTofKa2, + full::TPCTofNSigmaPi2, + full::TPCTofNSigmaKa2, full::CandidateSelFlag, full::M, full::Pt, @@ -233,7 +235,7 @@ DECLARE_SOA_TABLE(HfCandDpFulls, "AOD", "HFCANDDPFULL", hf_cand_mc_flag::OriginMcRec, hf_cand_mc_flag::FlagMcDecayChanRec); -DECLARE_SOA_TABLE(HfCandDpMcPs, "AOD", "HFCANDDPMCP", +DECLARE_SOA_TABLE(HfCandDpMcPs, "AOD", "HFCANDDPMCP", o2::soa::Index<>, full::Pt, full::Eta, full::Phi, diff --git a/PWGHF/HFC/TableProducer/CMakeLists.txt b/PWGHF/HFC/TableProducer/CMakeLists.txt index 299981d8c1f..c6fb293ed89 100644 --- a/PWGHF/HFC/TableProducer/CMakeLists.txt +++ b/PWGHF/HFC/TableProducer/CMakeLists.txt @@ -36,7 +36,7 @@ o2physics_add_dpl_workflow(correlator-dplus-dminus o2physics_add_dpl_workflow(correlator-dplus-dplus-reduced SOURCES correlatorDplusDplusReduced.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2Physics::EventFilteringUtils + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2Physics::EventFilteringUtils O2Physics::MLCore COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(correlator-dplus-hadrons diff --git a/PWGHF/HFC/TableProducer/correlatorDplusDplusReduced.cxx b/PWGHF/HFC/TableProducer/correlatorDplusDplusReduced.cxx index d58da7fccd6..969955fafae 100644 --- a/PWGHF/HFC/TableProducer/correlatorDplusDplusReduced.cxx +++ b/PWGHF/HFC/TableProducer/correlatorDplusDplusReduced.cxx @@ -20,6 +20,8 @@ #include "PWGHF/Core/CentralityEstimation.h" #include "PWGHF/Core/DecayChannels.h" #include "PWGHF/Core/HfHelper.h" +#include "PWGHF/Core/HfMlResponseDplusToPiKPi.h" +#include "PWGHF/Core/SelectorCuts.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" #include "PWGHF/HFC/DataModel/ReducedDMesonPairsTables.h" @@ -30,10 +32,12 @@ #include "Common/DataModel/Centrality.h" #include +#include #include #include #include #include +#include #include #include #include @@ -41,9 +45,12 @@ #include #include +#include +#include #include using namespace o2; +using namespace o2::analysis; using namespace o2::framework; using namespace o2::framework::expressions; using namespace o2::hf_centrality; @@ -69,6 +76,34 @@ struct HfCorrelatorDplusDplusReduced { Configurable cfgSkimmedProcessing{"cfgSkimmedProcessing", true, "Enables processing of skimmed datasets"}; Configurable skipSingleD{"skipSingleD", true, "Skip collisions with one or less D candidates"}; + Configurable applyMl{"applyMl", false, "Flag to apply ML selections"}; + Configurable applySkimming{"applySkimming", false, "Flag to apply Skimming selections"}; + Configurable loadModelsFromCCDB{"loadModelsFromCCDB", false, "Flag to enable or disable the loading of models from CCDB"}; + 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 ccdbUrl{"ccdbUrl", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable> modelPathsCCDB{"modelPathsCCDB", std::vector{"EventFiltering/PWGHF/BDTDPlus"}, "Paths of models on CCDB"}; + Configurable> onnxFileNames{"onnxFileNames", std::vector{"ModelHandler_onnx_DPlusToKPiPi.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> namesInputFeatures{"namesInputFeatures", std::vector{"feature1", "feature2"}, "Names of ML model input features"}; + + Configurable> cutPtSkimming{"cutPtSkimming", {1, 5, 1000}, "pT bin limits for Skimming application"}; + Configurable> minM{"minM", {0.7, 0.7}, "Mass minimal for the cut for each pt bin"}; + Configurable> maxM{"maxM", {2.0, 2.1}, "Mass maximal for the cut for each pt bin"}; + Configurable> minCosTheta{"minCosTheta", {0.96, 0.98}, "CosTheta minimal for the cut for each pt bin"}; + Configurable> minDecayLength{"minDecayLength", {0.02, 0.03}, "DecayLength minimal for the cut for each pt bin"}; + Configurable> maxNsigmaTPC{"maxNsigmaTPC", {3, 3}, "NsigmaTPC maximal for the cut for each pt bin"}; + Configurable> maxNsigmaTOF{"maxNsigmaTOF", {3, 3}, "NsigmaTOF maximal for the cut for each pt bin"}; + + Configurable> binsPtSkimming{"binsPtSkimming", {0}, "pT bin limits for Skimming application"}; + + HfMlResponseDplusToPiKPi hfMlResponse; + + std::vector outputML; + o2::ccdb::CcdbApi ccdbApi; + HfHelper hfHelper; Service ccdb; @@ -102,6 +137,46 @@ struct HfCorrelatorDplusDplusReduced { if (cfgSkimmedProcessing) { zorroSummary.setObject(zorro.getZorroSummary()); } + + if (applyMl) { + hfMlResponse.configure(binsPtMl, cutsMl, cutDirMl, nClassesMl); + if (loadModelsFromCCDB) { + ccdbApi.init(ccdbUrl); + hfMlResponse.setModelPathsCCDB(onnxFileNames, ccdbApi, modelPathsCCDB, timestampCCDB); + } else { + hfMlResponse.setModelPathsLocal(onnxFileNames); + } + hfMlResponse.cacheInputFeaturesIndices(namesInputFeatures); + hfMlResponse.init(); + } + } + + bool Skimming(auto candidate, + auto PtcutSkimming, + auto Mmin, + auto Mmax, + auto CosThetamin, + auto DecayLengthmin, + auto NsigmaTPCmax, + auto NsigmaTOFmax) + { + if (candidate.pt() < PtcutSkimming[0] || candidate.pt() > PtcutSkimming[PtcutSkimming.size() - 1]) { + return false; + } + for (auto i = 1; i < PtcutSkimming.size(); i++) { + if (candidate.pt() <= PtcutSkimming[i]) { + if (hfHelper.invMassDplusToPiKPi(candidate) < Mmin[i - 1] || + hfHelper.invMassDplusToPiKPi(candidate) > Mmax[i - 1] || + candidate.cpa() < CosThetamin[i - 1] || + candidate.decayLength() < DecayLengthmin[i - 1] || + candidate.nSigTofKa1() > NsigmaTOFmax[i - 1] || + candidate.nSigTpcKa1() > NsigmaTPCmax[i - 1]) { + return false; + } + return true; + } + } + return false; } template @@ -127,14 +202,14 @@ struct HfCorrelatorDplusDplusReduced { channelMc = candidate.flagMcDecayChanRec(); } - std::vector outputMl = {-999., -999.}; + std::vector outML = {-999., -999.}; if constexpr (DoMl) { for (unsigned int iclass = 0; iclass < classMlIndexes->size(); iclass++) { - outputMl[iclass] = candidate.mlProbDplusToPiKPi()[classMlIndexes->at(iclass)]; + outML[iclass] = candidate.mlProbDplusToPiKPi()[classMlIndexes->at(iclass)]; } rowCandidateMl( - outputMl[0], - outputMl[1]); + outML[0], + outML[1]); } float cent{-1.}; @@ -291,7 +366,9 @@ struct HfCorrelatorDplusDplusReduced { static int lastRunNumber = -1; // reserve memory rowCandidateFullEvents.reserve(collisions.size()); - if (fillCandidateLiteTable) { + if (fillCandidateTinyTable) { + rowCandidateTiny.reserve(candidates.size()); + } else if (fillCandidateLiteTable) { rowCandidateLite.reserve(candidates.size()); } else { rowCandidateFull.reserve(candidates.size()); @@ -320,6 +397,26 @@ struct HfCorrelatorDplusDplusReduced { for (const auto& candidate : candidatesInThisCollision) { auto prongCandidate = candidate.prong1_as(); auto candidateSign = -prongCandidate.sign(); + + if (applySkimming && + !Skimming(candidate, + cutPtSkimming, + minM, + maxM, + minCosTheta, + minDecayLength, + maxNsigmaTPC, + maxNsigmaTOF)) { + continue; + } + + if (applyMl) { + std::vector inputFeatures = hfMlResponse.getInputFeatures(candidate); + bool const isSelectedMl = hfMlResponse.isSelectedMl(inputFeatures, abs(candidate.pt()), outputML); + if (!isSelectedMl) { + continue; + } + } fillCandidateTable(candidate, rowCandidateFullEvents.lastIndex(), candidateSign); } } @@ -332,7 +429,9 @@ struct HfCorrelatorDplusDplusReduced { { // reserve memory rowCandidateFullEvents.reserve(collisions.size()); - if (fillCandidateLiteTable) { + if (fillCandidateTinyTable) { + rowCandidateTiny.reserve(candidates.size()); + } else if (fillCandidateLiteTable) { rowCandidateLite.reserve(candidates.size()); } else { rowCandidateFull.reserve(candidates.size()); @@ -348,6 +447,25 @@ struct HfCorrelatorDplusDplusReduced { for (const auto& candidate : candidatesInThisCollision) { auto prongCandidate = candidate.prong1_as(); auto candidateSign = -prongCandidate.sign(); + + if (applySkimming && + !Skimming(candidate, + cutPtSkimming, + minM, + maxM, + minCosTheta, + minDecayLength, + maxNsigmaTPC, + maxNsigmaTOF)) { + continue; + } + if (applyMl) { + std::vector inputFeatures = hfMlResponse.getInputFeatures(candidate); + bool const isSelectedMl = hfMlResponse.isSelectedMl(inputFeatures, abs(candidate.pt()), outputML); + if (!isSelectedMl) { + continue; + } + } fillCandidateTable(candidate, rowCandidateFullEvents.lastIndex(), candidateSign); } } diff --git a/PWGHF/HFC/Tasks/taskCorrelationDplusDplusReduced.cxx b/PWGHF/HFC/Tasks/taskCorrelationDplusDplusReduced.cxx index c37c1f73feb..549ae024c52 100644 --- a/PWGHF/HFC/Tasks/taskCorrelationDplusDplusReduced.cxx +++ b/PWGHF/HFC/Tasks/taskCorrelationDplusDplusReduced.cxx @@ -37,8 +37,13 @@ using namespace o2::framework::expressions; struct HfTaskCorrelationDplusDplusReduced { Configurable selectionFlagDplus{"selectionFlagDplus", 1, "Selection Flag for Dplus"}; + Configurable selectionCutRapidity{"selectionCutRapidity", 1, "Selection the cut of rapidity"}; + Configurable applyMl{"applyMl", false, "Flag to apply ML selections"}; + Configurable applySkimming{"applySkimming", false, "Flag to apply Skimming selections"}; - using SelectedCandidates = soa::Filtered; + using SelectedCandidatesTiny = soa::Filtered; + using SelectedCandidatesLite = soa::Filtered; + using SelectedCandidatesFull = soa::Filtered; using SelectedMcParticles = o2::aod::HfCandDpMcPs; Filter filterSelectCandidates = aod::full::candidateSelFlag >= selectionFlagDplus; @@ -54,24 +59,28 @@ struct HfTaskCorrelationDplusDplusReduced { void init(InitContext const&) { - registry.add("hMassDplus", "D+ candidates;inv. mass (#pi#pi K) (GeV/#it{c}^{2}))", {HistType::kTH1F, {{120, 1.5848, 2.1848}}}); - registry.add("hMassDminus", "D- candidates;inv. mass (#pi#pi K) (GeV/#it{c}^{2}))", {HistType::kTH1F, {{120, 1.5848, 2.1848}}}); - registry.add("hMassDplusMatched", "D+ matched candidates;inv. mass (#pi#pi K) (GeV/#it{c}^{2}))", {HistType::kTH1F, {{120, 1.5848, 2.1848}}}); - registry.add("hMassDminusMatched", "D- matched candidates;inv. mass (#pi#pi K) (GeV/#it{c}^{2}))", {HistType::kTH1F, {{120, 1.5848, 2.1848}}}); - registry.add("hMassDplusminusPair", "D plus-minus pair candidates;inv. mass (#pi K) (GeV/#it{c}^{2});inv. mass (#pi K) (GeV/#it{c}^{2})", {HistType::kTH2F, {{120, 1.5848, 2.1848}, {120, 1.5848, 2.1848}}}); - registry.add("hMassDplusPair", "D plus pair candidates;inv. mass (#pi K) (GeV/#it{c}^{2});inv. mass (#pi K) (GeV/#it{c}^{2})", {HistType::kTH2F, {{120, 1.5848, 2.1848}, {120, 1.5848, 2.1848}}}); - registry.add("hMassDminusPair", "D minus pair candidates;inv. mass (#pi K) (GeV/#it{c}^{2});inv. mass (#pi K) (GeV/#it{c}^{2})", {HistType::kTH2F, {{120, 1.5848, 2.1848}, {120, 1.5848, 2.1848}}}); + registry.add("hMassDplus", "D^{+} candidates;inv. mass (#pi#pi K) (GeV/#it{c}^{2}))", {HistType::kTH1F, {{120, 1.5848, 2.1848}}}); + registry.add("hMassDminus", "D^{-} candidates;inv. mass (#pi#pi K) (GeV/#it{c}^{2}))", {HistType::kTH1F, {{120, 1.5848, 2.1848}}}); + registry.add("hMassDplusMatched", "D^{+} matched candidates;inv. mass (#pi#pi K) (GeV/#it{c}^{2}))", {HistType::kTH1F, {{120, 1.5848, 2.1848}}}); + registry.add("hMassDminusMatched", "D^{-} matched candidates;inv. mass (#pi#pi K) (GeV/#it{c}^{2}))", {HistType::kTH1F, {{120, 1.5848, 2.1848}}}); + registry.add("hMassDplusPairsMatched", "D^{+} matched pairs candidates;inv. mass (#pi#pi K) (GeV/#it{c}^{2});inv. mass (#pi#pi K) (GeV/#it{c}^{2})", {HistType::kTH2F, {{120, 1.5848, 2.1848}, {120, 1.5848, 2.1848}}}); + registry.add("hMassDminusPairsMatched", "D^{-} matched pairs candidates;inv. mass (#pi#pi K) (GeV/#it{c}^{2});inv. mass (#pi#pi K) (GeV/#it{c}^{2})", {HistType::kTH2F, {{120, 1.5848, 2.1848}, {120, 1.5848, 2.1848}}}); + registry.add("hMassDplusminusPairsMatched", "D^{+} and D^{-} matched pairs candidates;inv. mass (#pi#pi K) (GeV/#it{c}^{2});inv. mass (#pi#pi K) (GeV/#it{c}^{2})", {HistType::kTH2F, {{120, 1.5848, 2.1848}, {120, 1.5848, 2.1848}}}); + registry.add("hMassDplusminusPair", "D^{+-} pair candidates;inv. mass (#pi#pi K) (GeV/#it{c}^{2});inv. mass (#pi#pi K) (GeV/#it{c}^{2})", {HistType::kTH2F, {{120, 1.5848, 2.1848}, {120, 1.5848, 2.1848}}}); + registry.add("hMassDplusPair", "D^{+} pair candidates;inv. mass (#pi#pi K) (GeV/#it{c}^{2});inv. mass (#pi#pi K) (GeV/#it{c}^{2})", {HistType::kTH2F, {{120, 1.5848, 2.1848}, {120, 1.5848, 2.1848}}}); + registry.add("hMassDminusPair", "D^{-} pair candidates;inv. mass (#pi#pi K) (GeV/#it{c}^{2});inv. mass (#pi#pi K) (GeV/#it{c}^{2})", {HistType::kTH2F, {{120, 1.5848, 2.1848}, {120, 1.5848, 2.1848}}}); registry.add("hDltPhiMcGen", "Azimuthal correlation for D mesons; #Delta#phi", {HistType::kTH1F, {{100, -3.141593, 3.141593}}}); } - void processLocalData(o2::aod::HfCandDpFullEvs::iterator const&, - SelectedCandidates const& localCandidates) + template + void processData(const T& localCandidates) { registry.fill(HIST("hNCand"), localCandidates.size()); for (const auto& cand1 : localCandidates) { auto mass1 = cand1.m(); auto sign1 = 1; + auto flattening = 0; if (cand1.pt() < 0) { sign1 = -1; registry.fill(HIST("hMassDminus"), mass1); @@ -85,28 +94,45 @@ struct HfTaskCorrelationDplusDplusReduced { if (cand2.pt() < 0) { sign2 = -1; } - if (sign1 == sign2) { - if (sign1 == 1) { - registry.fill(HIST("hMassDplusPair"), mass2, mass1); + if (flattening == 0) { + if (sign1 == sign2) { + if (sign1 == 1) { + registry.fill(HIST("hMassDplusPair"), mass2, mass1); + } else { + registry.fill(HIST("hMassDminusPair"), mass2, mass1); + } } else { - registry.fill(HIST("hMassDminusPair"), mass2, mass1); + registry.fill(HIST("hMassDplusminusPair"), mass2, mass1); } - } else { - registry.fill(HIST("hMassDplusminusPair"), mass2, mass1); + flattening = 1; + } + if (flattening == 1) { + if (sign1 == sign2) { + if (sign1 == 1) { + registry.fill(HIST("hMassDplusPair"), mass1, mass2); + } else { + registry.fill(HIST("hMassDminusPair"), mass1, mass2); + } + } else { + registry.fill(HIST("hMassDplusminusPair"), mass1, mass2); + } + flattening = 0; } } } } - PROCESS_SWITCH(HfTaskCorrelationDplusDplusReduced, processLocalData, "Process local data", true); - void processLocalDataMcRec(o2::aod::HfCandDpFullEvs::iterator const&, - SelectedCandidates const& localCandidates) + template + void processLocalDataMcRec(const T& localCandidates) { registry.fill(HIST("hNMcRec"), localCandidates.size()); for (const auto& cand1 : localCandidates) { auto mass1 = cand1.m(); + auto sign1 = 1; + auto flattening = 0; if (cand1.pt() < 0) { + sign1 = -1; registry.fill(HIST("hMassDminus"), mass1); if (std::abs(cand1.flagMcMatchRec()) == hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKPi) registry.fill(HIST("hMassDminusMatched"), mass1); @@ -115,9 +141,94 @@ struct HfTaskCorrelationDplusDplusReduced { if (std::abs(cand1.flagMcMatchRec()) == hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKPi) registry.fill(HIST("hMassDplusMatched"), mass1); } + + for (auto cand2 = cand1 + 1; cand2 != localCandidates.end(); ++cand2) { + auto mass2 = cand2.m(); + auto sign2 = 1; + if (cand2.pt() < 0) { + sign2 = -1; + } + if (flattening == 0) { + if (sign1 == sign2) { + if (sign1 == 1) { + registry.fill(HIST("hMassDplusPair"), mass1, mass2); + if (std::abs(cand2.flagMcMatchRec()) == hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKPi && std::abs(cand1.flagMcMatchRec()) == hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKPi) + registry.fill(HIST("hMassDplusPairsMatched"), mass1, mass2); + } else { + registry.fill(HIST("hMassDminusPair"), mass1, mass2); + if (std::abs(cand2.flagMcMatchRec()) == hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKPi && std::abs(cand1.flagMcMatchRec()) == hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKPi) + registry.fill(HIST("hMassDminusPairsMatched"), mass1, mass2); + } + } else { + registry.fill(HIST("hMassDplusminusPair"), mass1, mass2); + if (std::abs(cand2.flagMcMatchRec()) == hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKPi && std::abs(cand1.flagMcMatchRec()) == hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKPi) + registry.fill(HIST("hMassDplusminusPairsMatched"), mass1, mass2); + } + flattening = 1; + } + if (flattening == 1) { + if (sign1 == sign2) { + if (sign1 == 1) { + registry.fill(HIST("hMassDplusPair"), mass2, mass1); + if (std::abs(cand2.flagMcMatchRec()) == hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKPi && std::abs(cand1.flagMcMatchRec()) == hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKPi) + registry.fill(HIST("hMassDplusPairsMatched"), mass2, mass1); + } else { + registry.fill(HIST("hMassDminusPair"), mass2, mass1); + if (std::abs(cand2.flagMcMatchRec()) == hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKPi && std::abs(cand1.flagMcMatchRec()) == hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKPi) + registry.fill(HIST("hMassDminusPairsMatched"), mass2, mass1); + } + } else { + registry.fill(HIST("hMassDplusminusPair"), mass2, mass1); + if (std::abs(cand2.flagMcMatchRec()) == hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKPi && std::abs(cand1.flagMcMatchRec()) == hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKPi) + registry.fill(HIST("hMassDplusminusPairsMatched"), mass2, mass1); + } + flattening = 0; + } + } } } - PROCESS_SWITCH(HfTaskCorrelationDplusDplusReduced, processLocalDataMcRec, "Process local MC data", false); + + void processLocalDataTiny(o2::aod::HfCandDpFullEvs::iterator const&, + SelectedCandidatesTiny const& localCandidates) + { + processData(localCandidates); + } + PROCESS_SWITCH(HfTaskCorrelationDplusDplusReduced, processLocalDataTiny, "Process local data for Tiny", true); + + void processLocalDataLite(o2::aod::HfCandDpFullEvs::iterator const&, + SelectedCandidatesLite const& localCandidates) + { + processData(localCandidates); + } + PROCESS_SWITCH(HfTaskCorrelationDplusDplusReduced, processLocalDataLite, "Process local data for Lite", true); + + void processLocalDataFull(o2::aod::HfCandDpFullEvs::iterator const&, + SelectedCandidatesFull const& localCandidates) + { + processData(localCandidates); + } + PROCESS_SWITCH(HfTaskCorrelationDplusDplusReduced, processLocalDataFull, "Process local data for Full", true); + + void processLocalDataMcRecTiny(o2::aod::HfCandDpFullEvs::iterator const&, + SelectedCandidatesTiny const& localCandidates) + { + processLocalDataMcRec(localCandidates); + } + PROCESS_SWITCH(HfTaskCorrelationDplusDplusReduced, processLocalDataMcRecTiny, "Process local MC data for Tiny", false); + + void processLocalDataMcRecLite(o2::aod::HfCandDpFullEvs::iterator const&, + SelectedCandidatesLite const& localCandidates) + { + processLocalDataMcRec(localCandidates); + } + PROCESS_SWITCH(HfTaskCorrelationDplusDplusReduced, processLocalDataMcRecLite, "Process local MC data for Lite", false); + + void processLocalDataMcRecFull(o2::aod::HfCandDpFullEvs::iterator const&, + SelectedCandidatesFull const& localCandidates) + { + processLocalDataMcRec(localCandidates); + } + PROCESS_SWITCH(HfTaskCorrelationDplusDplusReduced, processLocalDataMcRecFull, "Process local MC data for Full", false); void processLocalDataMcGen(o2::aod::HfCandDpMcEvs::iterator const&, SelectedMcParticles const& localMcParticles) @@ -126,7 +237,9 @@ struct HfTaskCorrelationDplusDplusReduced { for (const auto& part1 : localMcParticles) { for (auto part2 = part1 + 1; part2 != localMcParticles.end(); ++part2) { - registry.fill(HIST("hDltPhiMcGen"), part2.phi() - part1.phi()); + if (part1.eta() < selectionCutRapidity && part2.eta() < selectionCutRapidity) { + registry.fill(HIST("hDltPhiMcGen"), part2.phi() - part1.phi()); + } } } }