From 316551a5fcd57205d88cd9f217095a1dc69b759f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrea=20Tavira=20Garc=C3=ADa?= <118979672+atavirag@users.noreply.github.com> Date: Mon, 27 Jul 2026 09:53:25 +0000 Subject: [PATCH 1/3] [PWGHF] Add event mixing on data in correlatorDMesonPairs.cxx --- PWGHF/HFC/DataModel/DMesonPairsTables.h | 45 ++++ .../TableProducer/correlatorDMesonPairs.cxx | 230 ++++++++++++++++-- 2 files changed, 250 insertions(+), 25 deletions(-) diff --git a/PWGHF/HFC/DataModel/DMesonPairsTables.h b/PWGHF/HFC/DataModel/DMesonPairsTables.h index 35e12760919..bb60923e02b 100644 --- a/PWGHF/HFC/DataModel/DMesonPairsTables.h +++ b/PWGHF/HFC/DataModel/DMesonPairsTables.h @@ -32,6 +32,8 @@ DECLARE_SOA_COLUMN(PtCand1, ptCand1, float); //! Transverse momentum of first DECLARE_SOA_COLUMN(PtCand2, ptCand2, float); //! Transverse momentum of second candidate DECLARE_SOA_COLUMN(YCand1, yCand1, float); //! Rapidity of first candidate DECLARE_SOA_COLUMN(YCand2, yCand2, float); //! Rapidity of second candidate +DECLARE_SOA_COLUMN(EtaCand1, etaCand1, float); //! Azimuthal angle of first candidate +DECLARE_SOA_COLUMN(EtaCand2, etaCand2, float); //! Azimuthal angle of second candidate DECLARE_SOA_COLUMN(PhiCand1, phiCand1, float); //! Azimuthal angle of first candidate DECLARE_SOA_COLUMN(PhiCand2, phiCand2, float); //! Azimuthal angle of second candidate // Invariant mass @@ -61,6 +63,8 @@ DECLARE_SOA_COLUMN(MlProbD0barCand2, mlProbD0barCand2, std::vector); //! hf_correlation_d_meson_pair::PtCand2, \ hf_correlation_d_meson_pair::YCand1, \ hf_correlation_d_meson_pair::YCand2, \ + hf_correlation_d_meson_pair::EtaCand1, \ + hf_correlation_d_meson_pair::EtaCand2, \ hf_correlation_d_meson_pair::PhiCand1, \ hf_correlation_d_meson_pair::PhiCand2, \ hf_correlation_d_meson_pair::MDCand1, \ @@ -93,6 +97,47 @@ DECLARE_DMESON_PAIR_MLINFO_TABLE(D0PairMl, 1, "D0PAIR"); //! D0 pairs ML Inf DECLARE_DMESON_PAIR_TABLE(D0PairMcGen, 2, "D0PAIRGEN"); //! D0 pairs MC Gen Kinematic Info DECLARE_DMESON_PAIR_MCINFO_TABLE(D0PairMcGenInfo, 2, "D0PAIRGEN"); //! D0 pairs MC Gen Info +namespace hf_correlation_d_meson_had +{ +// D candidate +DECLARE_SOA_COLUMN(PtD, pD, float); //! Transverse momentum of the D meson +DECLARE_SOA_COLUMN(YD, yD, float); //! Rapidity of the D meson +DECLARE_SOA_COLUMN(EtaD, etaD, float); //! Pseudorapidity of the D meson +DECLARE_SOA_COLUMN(PhiD, phiD, float); //! Azimuthal angle of the D meson +DECLARE_SOA_COLUMN(MD, mD, float); //! Invariant mass of the D meson +DECLARE_SOA_COLUMN(PoolBinD, poolBinD, int); //! Pool bin of the D meson +DECLARE_SOA_COLUMN(GIndexColD, gIndexColD, int); //! G-index column of the D meson +DECLARE_SOA_COLUMN(TimestampD, timestampD, int64_t); //! Timestamp of the D meson + +// Associated hadron +DECLARE_SOA_COLUMN(PtHad, pHad, float); //! Transverse momentum of the associated hadron +DECLARE_SOA_COLUMN(YHad, yHad, float); //! Rapidity of the associated hadron +DECLARE_SOA_COLUMN(EtaHad, etaHad, float); //! Pseudorapidity of the associated hadron +DECLARE_SOA_COLUMN(PhiHad, phiHad, float); //! Azimuthal angle of the associated hadron +DECLARE_SOA_COLUMN(PoolBinHad, poolBinHad, int); //! Pool bin of the associated hadron +DECLARE_SOA_COLUMN(GIndexColHad, gIndexColHad, int); //! G-index column of the associated hadron +DECLARE_SOA_COLUMN(TimestampHad, timestampHad, int64_t); //! Timestamp of the associated hadron + +} // namespace hf_correlation_d_meson_had + +// Definition of the D meson table for D-had correlations. Contains the info needed at Data level. +DECLARE_SOA_TABLE(DMesonCandInfo, "AOD", "DMESONCANDINFO", \ + hf_correlation_d_meson_had::PtD, \ + hf_correlation_d_meson_had::EtaD, \ + hf_correlation_d_meson_had::PhiD, \ + hf_correlation_d_meson_had::MD, \ + hf_correlation_d_meson_had::PoolBinD, \ + hf_correlation_d_meson_had::GIndexColD, \ + hf_correlation_d_meson_had::TimestampD); + +DECLARE_SOA_TABLE(AssocHadInfo, "AOD", "ASSOCHADINFO", \ + hf_correlation_d_meson_had::PtHad, \ + hf_correlation_d_meson_had::EtaHad, \ + hf_correlation_d_meson_had::PhiHad, \ + hf_correlation_d_meson_had::PoolBinHad, \ + hf_correlation_d_meson_had::GIndexColHad, \ + hf_correlation_d_meson_had::TimestampHad); + } // namespace o2::aod #endif // PWGHF_HFC_DATAMODEL_DMESONPAIRSTABLES_H_ diff --git a/PWGHF/HFC/TableProducer/correlatorDMesonPairs.cxx b/PWGHF/HFC/TableProducer/correlatorDMesonPairs.cxx index 77e43224d52..a8c036a7b4a 100644 --- a/PWGHF/HFC/TableProducer/correlatorDMesonPairs.cxx +++ b/PWGHF/HFC/TableProducer/correlatorDMesonPairs.cxx @@ -18,8 +18,10 @@ #include "PWGHF/Core/HfHelper.h" #include "PWGHF/Core/HfMlResponseD0ToKPi.h" #include "PWGHF/Core/SelectorCuts.h" +#include "PWGHF/DataModel/AliasTables.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" +#include "PWGHF/HFC/DataModel/CorrelationTables.h" #include "PWGHF/HFC/DataModel/DMesonPairsTables.h" #include "Common/Core/RecoDecay.h" @@ -71,6 +73,57 @@ enum PairTypeOfSelMassSel { } // namespace using McParticlesPlus2Prong = soa::Join; +// definition of ME variables +using BinningType = ColumnBinningPolicy>; + +struct HfCorrelatorD0HadronsSelection { + Produces d0Sel; + + Configurable useSel8{"useSel8", true, "Flag for applying sel8 for collision selection"}; + Configurable selNoSameBunchPileUpColl{"selNoSameBunchPileUpColl", true, "Flag for rejecting the collisions associated with the same bunch crossing"}; + Configurable doSelD0Collision{"doSelD0Collision", true, "Select collisions with at least one D0"}; + Configurable selectionFlagD0{"selectionFlagD0", 1, "Selection Flag for D0"}; + Configurable selectionFlagD0bar{"selectionFlagD0bar", 1, "Selection Flag for D0bar"}; + Configurable yCandMax{"yCandMax", 0.8, "max. cand. rapidity"}; + Configurable ptCandMin{"ptCandMin", 1., "min. cand. pT"}; + + SliceCache cache; + + using SelCollisions = soa::Join; + using CandidatesD0Data = soa::Join; + + Partition selectedD0Candidates = + aod::hf_sel_candidate_d0::isSelD0 >= 1 || + aod::hf_sel_candidate_d0::isSelD0bar >= 1; + + // Process function to select collisions with at least one D0 candidate passing the selection criteria + void processD0SelectionData(SelCollisions::iterator const& collision, + CandidatesD0Data const& candidates) + { + bool isSel8 = !useSel8 || collision.sel8(); + bool isNoSameBunchPileUp = !selNoSameBunchPileUpColl || + collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup); + bool isD0Found = !doSelD0Collision; + + if (doSelD0Collision) { + auto grouped = selectedD0Candidates.sliceByCached(aod::hf_cand::collisionId, collision.globalIndex(), cache); + for (const auto& candidate : grouped) { + + if (candidate.isSelD0() < selectionFlagD0 && candidate.isSelD0bar() < selectionFlagD0bar) { + continue; + } + if (std::abs(HfHelper::yD0(candidate)) > yCandMax || candidate.pt() < ptCandMin) { + continue; + } + isD0Found = true; + break; + } + } + + d0Sel(isD0Found && isSel8 && isNoSameBunchPileUp); + } + PROCESS_SWITCH(HfCorrelatorD0HadronsSelection, processD0SelectionData, "Process D0 Selection Data", true); +}; struct HfCorrelatorDMesonPairs { @@ -80,18 +133,33 @@ struct HfCorrelatorDMesonPairs { Produces entryD0PairMcGen; Produces entryD0PairMcGenInfo; + // Tables for event mixing + Produces entryDMesonCand; + Produces entryAssocHad; + Configurable selectionFlagD0{"selectionFlagD0", 1, "Selection Flag for D0"}; Configurable selectionFlagD0bar{"selectionFlagD0bar", 1, "Selection Flag for D0bar"}; Configurable selectionFlagHf{"selectionFlagHf", 1, "Selection Flag for HF flagged candidates"}; - Configurable yCandMax{"yCandMax", 0.8, "maxmum |y| of D0 candidates"}; + Configurable yCandMax{"yCandMax", 0.8, "maximum |y| of D0 candidates"}; Configurable ptCandMin{"ptCandMin", -1., "minimum pT of D0 candidates"}; Configurable> binsPt{"binsPt", std::vector{o2::analysis::hf_cuts_d0_to_pi_k::vecBinsPt}, "pT bin limits for candidate mass plots"}; Configurable selectSignalRegionOnly{"selectSignalRegionOnly", false, "only use events close to PDG peak"}; Configurable massCut{"massCut", 0.05, "Maximum deviation from PDG peak allowed for signal region"}; - Configurable daughterTracksCutFlag{"daughterTracksCutFlag", false, "Flag to add cut on daughter tracks"}; Configurable removeAmbiguous{"removeAmbiguous", false, "Flag to remove ambiguous candidates"}; Configurable ptMaxRemoveAmbiguous{"ptMaxRemoveAmbiguous", 5.0, "Max. pT to remove the ambiguous candidates"}; + // Event mixing configurables + Configurable applyMixedEvent{"applyMixedEvent", false, "Flag to make the event mixing"}; + Configurable daughterTracksCutFlag{"daughterTracksCutFlag", false, "Flag to add cut on daughter tracks"}; + Configurable> binsPtHadron{"binsPtHadron", std::vector{0.3, 2., 4., 8., 12., 50.}, "pT bin limits for assoc particle"}; + Configurable etaTrackMax{"etaTrackMax", 0.8, "max. eta of tracks"}; + Configurable dcaXYTrackMax{"dcaXYTrackMax", 1., "max. DCA_xy of tracks"}; + Configurable dcaZTrackMax{"dcaZTrackMax", 1., "max. DCA_z of tracks"}; + Configurable ptTrackMin{"ptTrackMin", 0.3, "min. track pT"}; + Configurable ptTrackMax{"ptTrackMax", 100., "max. track pT"}; + Configurable multMin{"multMin", 0., "minimum multiplicity accepted"}; + Configurable multMax{"multMax", 10000., "maximum multiplicity accepted"}; + // ML inference Configurable applyMl{"applyMl", false, "Flag to apply ML selections"}; Configurable> binsPtMl{"binsPtMl", std::vector{hf_cuts_ml::vecBinsPt}, "pT bin limits for ML application"}; @@ -108,7 +176,20 @@ struct HfCorrelatorDMesonPairs { Configurable loadModelsFromCCDB{"loadModelsFromCCDB", false, "Flag to enable or disable the loading of models from CCDB"}; SliceCache cache; + + using SelCollisionsWithD0 = soa::Filtered>; + using CandidatesD0Data = soa::Join; + + using FilteredD0Candidates = soa::Filtered; + using TracksData = soa::Filtered>; // trackFilter applied + + Filter collisionFilter = aod::hf_selection_dmeson_collision::dmesonSel == true; + Filter d0Filter = (o2::aod::hf_track_index::hfflag & static_cast(BIT(aod::hf_cand_2prong::DecayType::D0ToPiK))) != static_cast(0); + Filter trackFilter = (nabs(aod::track::eta) < etaTrackMax) && (nabs(aod::track::pt) > ptTrackMin) && (nabs(aod::track::dcaXY) < dcaXYTrackMax) && (nabs(aod::track::dcaZ) < dcaZTrackMax); + Preslice perCol2Prong = aod::hf_cand::collisionId; + Preslice candsD0PerCollision = aod::hf_cand::collisionId; + Preslice trackIndicesPerCollision = aod::track::collisionId; o2::analysis::HfMlResponseD0ToKPi hfMlResponse; o2::ccdb::CcdbApi ccdbApi; @@ -141,6 +222,13 @@ struct HfCorrelatorDMesonPairs { HistogramConfigSpec hTH2Pid{HistType::kTH2F, {{500, 0., 10.}, {400, -20., 20.}}}; HistogramConfigSpec hTH3PtVsYVsNContrib{HistType::kTH3F, {{360, 0., 36.}, {20, -1., 1.}, {120, -0.5, 119.5}}}; + ConfigurableAxis binsMultiplicity{"binsMultiplicity", {VARIABLE_WIDTH, 0.0f, 2000.0f, 6000.0f, 100000.0f}, "Mixing bins - multiplicity"}; + ConfigurableAxis binsZVtx{"binsZVtx", {VARIABLE_WIDTH, -10.0f, -2.5f, 2.5f, 10.0f}, "Mixing bins - z-vertex"}; + ConfigurableAxis binsPoolBin{"binsPoolBin", {9, 0., 9.}, "PoolBin"}; + ConfigurableAxis binsMultFT0M{"binsMultFT0M", {600, 0., 6000.}, "Multiplicity as FT0M signal amplitude"}; + ConfigurableAxis binsDcaXY{"binsDcaXY", {128, -0.2, 0.2}, "DCA xy"}; + BinningType corrBinning{{binsZVtx, binsMultiplicity}, true}; + HistogramRegistry registry{ "registry", {{"hPtCand", "D meson candidates;candidate #it{p}_{T} (GeV/#it{c});entries", hTH1Pt}, @@ -309,6 +397,24 @@ struct HfCorrelatorDMesonPairs { registry.add("hnDMeson", "Thn for D0 candidates", HistType::kTHnSparseD, axes); registry.get(HIST("hnDMeson"))->Sumw2(); } + + // Event mixing + AxisSpec axisPtHadron = {(std::vector)binsPtHadron, "#it{p}_{T} Hadron (GeV/#it{c})"}; + AxisSpec const axisMultiplicity = {binsMultiplicity, "Multiplicity"}; + AxisSpec axisMultFT0M = {binsMultFT0M, "MultiplicityFT0M"}; + AxisSpec const axisPosZ = {binsZVtx, "PosZ"}; + AxisSpec const axisPoolBin = {binsPoolBin, "PoolBin"}; + AxisSpec const axisDcaXY = {binsDcaXY, "DCA xy"}; + + if (applyMixedEvent) { + registry.add("hMultiplicityPreSelection", "multiplicity prior to selection;multiplicity;entries", {HistType::kTH1F, {{10000, 0., 10000.}}}); + registry.add("hMultiplicity", "multiplicity;multiplicity;entries", {HistType::kTH1F, {{10000, 0., 10000.}}}); + registry.add("hMultFT0M", "multiplicity;multiplicity;entries", {HistType::kTH1F, {{10000, 0., 10000.}}}); + registry.add("hZvtx", "z vertex;z vertex;entries", {HistType::kTH1F, {{200, -20., 20.}}}); + registry.add("hD0Bin", "D0 selected in pool Bin;pool Bin;entries", {HistType::kTH1F, {{9, 0., 9.}}}); + registry.add("hTracksBin", "Tracks selected in pool Bin;pool Bin;entries", {HistType::kTH1F, {{9, 0., 9.}}}); + registry.add("hDcaXYVsPt", "DCA xy vs pt", {HistType::kTH2F, {{axisDcaXY}, {axisPtHadron}}}); + } } /// Sets bits to select candidate type for D0 @@ -470,7 +576,7 @@ struct HfCorrelatorDMesonPairs { /// Fill selection status histogram void fillEntry(const bool& isDCand1, const bool& isDbarCand1, const bool& isDCand2, const bool& isDbarCand2, - const uint8_t& candidateType1, const uint8_t& candidateType2, float yCand1, float yCand2, float phiCand1, float phiCand2, + const uint8_t& candidateType1, const uint8_t& candidateType2, float yCand1, float yCand2, float phiCand1, float phiCand2, float etaCand1, float etaCand2, double ptCand1, double ptCand2, float massDCand1, float massDbarCand1, float massDCand2, float massDbarCand2) { @@ -525,7 +631,7 @@ struct HfCorrelatorDMesonPairs { } } - entryD0Pair(ptCand1, ptCand2, yCand1, yCand2, phiCand1, phiCand2, massDCand1, massDbarCand1, massDCand2, massDbarCand2, pairType, candidateType1, candidateType2); + entryD0Pair(ptCand1, ptCand2, yCand1, yCand2, etaCand1, etaCand2, phiCand1, phiCand2, massDCand1, massDbarCand1, massDCand2, massDbarCand2, pairType, candidateType1, candidateType2); } void fillMcHistos(int8_t matchedRec1, int8_t matchedRec2, int8_t isTrueDCand1, int8_t isTrueDbarCand1, int8_t isTrueDCand2, int8_t isTrueDbarCand2) @@ -571,13 +677,41 @@ struct HfCorrelatorDMesonPairs { } /// D0(bar)-D0(bar) correlation pair builder - for real data and data-like analysis (i.e. reco-level w/o matching request via MC truth) - void processData(aod::Collision const& collision, - soa::Join const& candidates, aod::Tracks const&) + void processData(SelCollisionsWithD0::iterator const& collision, + CandidatesD0Data const& candidates, TracksData const& tracks, aod::BCsWithTimestamps const&) { + + auto bc = collision.bc_as(); + int gCollisionId = collision.globalIndex(); + int64_t timeStamp = bc.timestamp(); + + int poolBin = corrBinning.getBin(std::make_tuple(collision.posZ(), collision.multFT0M())); + + int nTracks = 0; + if (collision.numContrib() > 1) { + for (const auto& track : tracks) { + if (std::abs(track.eta()) >= etaTrackMax || std::abs(track.dcaXY()) >= dcaXYTrackMax || std::abs(track.dcaZ()) >= dcaZTrackMax) { + continue; + } + nTracks++; + } + } + if (applyMixedEvent) { + registry.fill(HIST("hMultiplicityPreSelection"), nTracks); + } + if (nTracks < multMin || nTracks > multMax) { + return; + } + if (applyMixedEvent) { + registry.fill(HIST("hMultiplicity"), nTracks); + } + + int cntD0 = 0; + for (const auto& candidate : candidates) { analysePid(candidate); } - auto selectedD0CandidatesGrouped = selectedD0Candidates->sliceByCached(aod::hf_cand::collisionId, collision.globalIndex(), cache); + auto selectedD0CandidatesGrouped = selectedD0Candidates->sliceByCached(aod::hf_cand::collisionId, gCollisionId, cache); getCountersPerEvent(selectedD0CandidatesGrouped); // protection against empty tables to be sliced if (selectedD0Candidates.size() <= 1) { @@ -594,8 +728,8 @@ struct HfCorrelatorDMesonPairs { if (ptCandMin >= 0. && candidate1.pt() < ptCandMin) { continue; } - auto prong0Cand1 = candidate1.template prong0_as(); - auto prong1Cand1 = candidate1.template prong1_as(); + auto prong0Cand1 = candidate1.template prong0_as(); + auto prong1Cand1 = candidate1.template prong1_as(); bool const isSignalD0Cand1 = std::abs(HfHelper::invMassD0ToPiK(candidate1) - MassD0) < massCut; bool const isSignalD0barCand1 = std::abs(HfHelper::invMassD0barToKPi(candidate1) - MassD0Bar) < massCut; @@ -638,6 +772,9 @@ struct HfCorrelatorDMesonPairs { registry.fill(HIST("hY"), candidate1.y(MassD0)); registry.fill(HIST("hPtCandAfterCut"), candidate1.pt()); registry.fill(HIST("hPVContrib"), collision.numContrib()); + if (applyMixedEvent) { + registry.fill(HIST("hD0Bin"), poolBin); + } if (isDCand1) { registry.fill(HIST("hMass"), HfHelper::invMassD0ToPiK(candidate1), candidate1.pt()); @@ -646,6 +783,10 @@ struct HfCorrelatorDMesonPairs { } else { registry.fill(HIST("hnDMeson"), HfHelper::invMassD0ToPiK(candidate1), candidate1.pt(), candidate1.y(MassD0), collision.numContrib(), 0, candidateType1); } + // Fill D0 table for offline event mixing + if (applyMixedEvent) { + entryDMesonCand(candidate1.pt(), candidate1.eta(), candidate1.phi(), HfHelper::invMassD0ToPiK(candidate1), poolBin, gCollisionId, timeStamp); + } } if (isDbarCand1) { registry.fill(HIST("hMass"), HfHelper::invMassD0barToKPi(candidate1), candidate1.pt()); @@ -654,8 +795,39 @@ struct HfCorrelatorDMesonPairs { } else { registry.fill(HIST("hnDMeson"), HfHelper::invMassD0barToKPi(candidate1), candidate1.pt(), candidate1.y(MassD0), collision.numContrib(), 0, candidateType1); } + // Fill D0 table for offline event mixing + if (applyMixedEvent) { + entryDMesonCand(candidate1.pt(), candidate1.eta(), candidate1.phi(), HfHelper::invMassD0barToKPi(candidate1), poolBin, gCollisionId, timeStamp); + } } + if (applyMixedEvent) { + // Loop on the associated tracks for offline event mixing + for (const auto& track : tracks) { + // apply track selection + if (track.collisionId() != gCollisionId) continue; + + // Manual trackFilter check + if (std::abs(track.eta()) >= etaTrackMax) continue; + if (track.pt() <= ptTrackMin) continue; + if (std::abs(track.dcaXY()) >= dcaXYTrackMax) continue; + if (std::abs(track.dcaZ()) >= dcaZTrackMax) continue; + // Removing D0 daughters by checking track indices + if (daughterTracksCutFlag) { + if ((candidate1.prong0Id() == track.globalIndex()) || (candidate1.prong1Id() == track.globalIndex())) { + continue; + } + } + if (cntD0 == 0) { + entryAssocHad(track.pt(), track.eta(), track.phi(), poolBin, gCollisionId, timeStamp); + registry.fill(HIST("hTracksBin"), poolBin); + registry.fill(HIST("hDcaXYVsPt"), track.dcaXY(), track.pt()); + } + } // Hadron Tracks loop + cntD0++; + } + + // Loop on the second D0 candidate for (auto candidate2 = candidate1 + 1; candidate2 != selectedD0CandidatesGrouped.end(); ++candidate2) { outputMlD0Cand2.clear(); @@ -667,9 +839,9 @@ struct HfCorrelatorDMesonPairs { if (ptCandMin >= 0. && candidate2.pt() < ptCandMin) { continue; } - auto prong0Cand2 = candidate2.template prong0_as(); - auto prong1Cand2 = candidate2.template prong1_as(); - if (daughterTracksCutFlag && ((prong0Cand1 == prong0Cand2) || (prong1Cand1 == prong1Cand2) || (prong0Cand1 == prong1Cand2) || (prong1Cand1 == prong0Cand2))) { + auto prong0Cand2 = candidate2.template prong0_as(); + auto prong1Cand2 = candidate2.template prong1_as(); + if ((prong0Cand1 == prong0Cand2) || (prong1Cand1 == prong1Cand2) || (prong0Cand1 == prong1Cand2) || (prong1Cand1 == prong0Cand2)) { continue; } @@ -707,18 +879,25 @@ struct HfCorrelatorDMesonPairs { } fillEntry(isDCand1, isDbarCand1, isDCand2, isDbarCand2, candidateType1, candidateType2, HfHelper::yD0(candidate1), HfHelper::yD0(candidate2), - candidate1.phi(), candidate2.phi(), candidate1.pt(), candidate2.pt(), HfHelper::invMassD0ToPiK(candidate1), HfHelper::invMassD0barToKPi(candidate1), + candidate1.eta(), candidate2.eta(), candidate1.phi(), candidate2.phi(), + candidate1.pt(), candidate2.pt(), HfHelper::invMassD0ToPiK(candidate1), HfHelper::invMassD0barToKPi(candidate1), HfHelper::invMassD0ToPiK(candidate2), HfHelper::invMassD0barToKPi(candidate2)); entryD0PairMl(outputMlD0Cand1, outputMlD0barCand1, outputMlD0Cand2, outputMlD0barCand2); } else { // Fill entries - fillEntry(isDCand1, isDbarCand1, isDCand2, isDbarCand2, candidateType1, candidateType2, HfHelper::yD0(candidate1), HfHelper::yD0(candidate2), candidate1.phi(), candidate2.phi(), + fillEntry(isDCand1, isDbarCand1, isDCand2, isDbarCand2, candidateType1, candidateType2, HfHelper::yD0(candidate1), HfHelper::yD0(candidate2), + candidate1.eta(), candidate2.eta(), candidate1.phi(), candidate2.phi(), candidate1.pt(), candidate2.pt(), HfHelper::invMassD0ToPiK(candidate1), HfHelper::invMassD0barToKPi(candidate1), HfHelper::invMassD0ToPiK(candidate2), HfHelper::invMassD0barToKPi(candidate2)); } } // end inner loop (Cand2) } // end outer loop (Cand1) + + if (applyMixedEvent) { + registry.fill(HIST("hZvtx"), collision.posZ()); + registry.fill(HIST("hMultFT0M"), collision.multFT0M()); + } } PROCESS_SWITCH(HfCorrelatorDMesonPairs, processData, "Process data mode", true); @@ -730,10 +909,6 @@ struct HfCorrelatorDMesonPairs { } auto selectedD0CandidatesGroupedMc = selectedD0CandidatesMc->sliceByCached(aod::hf_cand::collisionId, collision.globalIndex(), cache); getCountersPerEvent(selectedD0CandidatesGroupedMc); - // protection against empty tables to be sliced - if (selectedD0CandidatesMc.size() <= 1) { - return; - } for (const auto& candidate1 : selectedD0CandidatesGroupedMc) { outputMlD0Cand1.clear(); @@ -742,10 +917,11 @@ struct HfCorrelatorDMesonPairs { auto ptCandidate1 = candidate1.pt(); auto yCandidate1 = HfHelper::yD0(candidate1); auto phiCandidate1 = candidate1.phi(); + auto etaCandidate1 = candidate1.eta(); float const massD0Cand1 = HfHelper::invMassD0ToPiK(candidate1); float const massD0barCand1 = HfHelper::invMassD0barToKPi(candidate1); - auto prong0Cand1 = candidate1.template prong0_as(); - auto prong1Cand1 = candidate1.template prong1_as(); + auto prong0Cand1 = candidate1.template prong0_as(); + auto prong1Cand1 = candidate1.template prong1_as(); if (std::abs(HfHelper::yD0(candidate1)) > yCandMax) { continue; @@ -857,6 +1033,7 @@ struct HfCorrelatorDMesonPairs { auto ptCandidate2 = candidate2.pt(); auto yCandidate2 = HfHelper::yD0(candidate2); auto phiCandidate2 = candidate2.phi(); + auto etaCandidate2 = candidate2.eta(); float const massD0Cand2 = HfHelper::invMassD0ToPiK(candidate2); float const massD0barCand2 = HfHelper::invMassD0barToKPi(candidate2); auto prong0Cand2 = candidate2.template prong0_as(); @@ -876,7 +1053,7 @@ struct HfCorrelatorDMesonPairs { if (candidate2.isSelD0() < selectionFlagD0 && candidate2.isSelD0bar() < selectionFlagD0bar) { continue; } - if (daughterTracksCutFlag && ((prong0Cand1 == prong0Cand2) || (prong1Cand1 == prong1Cand2) || (prong0Cand1 == prong1Cand2) || (prong1Cand1 == prong0Cand2))) { + if ((prong0Cand1 == prong0Cand2) || (prong1Cand1 == prong1Cand2) || (prong0Cand1 == prong1Cand2) || (prong1Cand1 == prong0Cand2)) { continue; } auto candidateType2 = assignCandidateTypeD0(candidate2); // Candidate type attribution @@ -913,7 +1090,7 @@ struct HfCorrelatorDMesonPairs { } // Fill tables - fillEntry(isDCand1, isDbarCand1, isDCand2, isDbarCand2, candidateType1, candidateType2, yCandidate1, yCandidate2, phiCandidate1, phiCandidate2, + fillEntry(isDCand1, isDbarCand1, isDCand2, isDbarCand2, candidateType1, candidateType2, yCandidate1, yCandidate2, etaCandidate1, etaCandidate2, phiCandidate1, phiCandidate2, ptCandidate1, ptCandidate2, massD0Cand1, massD0barCand1, massD0Cand2, massD0barCand2); fillMcHistos(matchedRec1, matchedRec2, static_cast(isTrueDCand1), static_cast(isTrueDbarCand1), static_cast(isTrueDCand2), static_cast(isTrueDbarCand2)); entryD0PairMcInfo(originRec1, originRec2, matchedRec1, matchedRec2); @@ -921,7 +1098,7 @@ struct HfCorrelatorDMesonPairs { } else { // Fill tables - fillEntry(isDCand1, isDbarCand1, isDCand2, isDbarCand2, candidateType1, candidateType2, yCandidate1, yCandidate2, phiCandidate1, phiCandidate2, + fillEntry(isDCand1, isDbarCand1, isDCand2, isDbarCand2, candidateType1, candidateType2, yCandidate1, yCandidate2, etaCandidate1, etaCandidate2, phiCandidate1, phiCandidate2, ptCandidate1, ptCandidate2, massD0Cand1, massD0barCand1, massD0Cand2, massD0barCand2); fillMcHistos(matchedRec1, matchedRec2, static_cast(isTrueDCand1), static_cast(isTrueDbarCand1), static_cast(isTrueDCand2), static_cast(isTrueDbarCand2)); entryD0PairMcInfo(originRec1, originRec2, matchedRec1, matchedRec2); @@ -1109,7 +1286,7 @@ struct HfCorrelatorDMesonPairs { } // Fill pair Selection Status - entryD0PairMcGen(particle1.pt(), particle2.pt(), particle1.y(), particle2.y(), particle1.phi(), particle2.phi(), MassD0, MassD0Bar, MassD0, MassD0Bar, pairType, particleType1, particleType2); + entryD0PairMcGen(particle1.pt(), particle2.pt(), particle1.y(), particle2.y(), particle1.eta(), particle2.eta(), particle1.phi(), particle2.phi(), MassD0, MassD0Bar, MassD0, MassD0Bar, pairType, particleType1, particleType2); entryD0PairMcGenInfo(originGen1, originGen2, matchedGen1, matchedGen2); } // end inner loop @@ -1121,5 +1298,8 @@ struct HfCorrelatorDMesonPairs { WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { - return WorkflowSpec{adaptAnalysisTask(cfgc)}; + return WorkflowSpec{ + adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc), + }; } From 498ee884de89a0c72cb066f643bc3b14c15a8793 Mon Sep 17 00:00:00 2001 From: ALICE Action Bot Date: Mon, 27 Jul 2026 09:56:22 +0000 Subject: [PATCH 2/3] Please consider the following formatting changes --- PWGHF/HFC/DataModel/DMesonPairsTables.h | 30 +++++------ .../TableProducer/correlatorDMesonPairs.cxx | 51 ++++++++++--------- 2 files changed, 43 insertions(+), 38 deletions(-) diff --git a/PWGHF/HFC/DataModel/DMesonPairsTables.h b/PWGHF/HFC/DataModel/DMesonPairsTables.h index bb60923e02b..01bb7984f1e 100644 --- a/PWGHF/HFC/DataModel/DMesonPairsTables.h +++ b/PWGHF/HFC/DataModel/DMesonPairsTables.h @@ -121,22 +121,22 @@ DECLARE_SOA_COLUMN(TimestampHad, timestampHad, int64_t); //! Timestamp of the as } // namespace hf_correlation_d_meson_had // Definition of the D meson table for D-had correlations. Contains the info needed at Data level. -DECLARE_SOA_TABLE(DMesonCandInfo, "AOD", "DMESONCANDINFO", \ - hf_correlation_d_meson_had::PtD, \ - hf_correlation_d_meson_had::EtaD, \ - hf_correlation_d_meson_had::PhiD, \ - hf_correlation_d_meson_had::MD, \ - hf_correlation_d_meson_had::PoolBinD, \ - hf_correlation_d_meson_had::GIndexColD, \ - hf_correlation_d_meson_had::TimestampD); +DECLARE_SOA_TABLE(DMesonCandInfo, "AOD", "DMESONCANDINFO", + hf_correlation_d_meson_had::PtD, + hf_correlation_d_meson_had::EtaD, + hf_correlation_d_meson_had::PhiD, + hf_correlation_d_meson_had::MD, + hf_correlation_d_meson_had::PoolBinD, + hf_correlation_d_meson_had::GIndexColD, + hf_correlation_d_meson_had::TimestampD); -DECLARE_SOA_TABLE(AssocHadInfo, "AOD", "ASSOCHADINFO", \ - hf_correlation_d_meson_had::PtHad, \ - hf_correlation_d_meson_had::EtaHad, \ - hf_correlation_d_meson_had::PhiHad, \ - hf_correlation_d_meson_had::PoolBinHad, \ - hf_correlation_d_meson_had::GIndexColHad, \ - hf_correlation_d_meson_had::TimestampHad); +DECLARE_SOA_TABLE(AssocHadInfo, "AOD", "ASSOCHADINFO", + hf_correlation_d_meson_had::PtHad, + hf_correlation_d_meson_had::EtaHad, + hf_correlation_d_meson_had::PhiHad, + hf_correlation_d_meson_had::PoolBinHad, + hf_correlation_d_meson_had::GIndexColHad, + hf_correlation_d_meson_had::TimestampHad); } // namespace o2::aod diff --git a/PWGHF/HFC/TableProducer/correlatorDMesonPairs.cxx b/PWGHF/HFC/TableProducer/correlatorDMesonPairs.cxx index a8c036a7b4a..2ec54bf78cd 100644 --- a/PWGHF/HFC/TableProducer/correlatorDMesonPairs.cxx +++ b/PWGHF/HFC/TableProducer/correlatorDMesonPairs.cxx @@ -98,11 +98,11 @@ struct HfCorrelatorD0HadronsSelection { // Process function to select collisions with at least one D0 candidate passing the selection criteria void processD0SelectionData(SelCollisions::iterator const& collision, - CandidatesD0Data const& candidates) + CandidatesD0Data const& candidates) { bool isSel8 = !useSel8 || collision.sel8(); bool isNoSameBunchPileUp = !selNoSameBunchPileUpColl || - collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup); + collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup); bool isD0Found = !doSelD0Collision; if (doSelD0Collision) { @@ -804,27 +804,32 @@ struct HfCorrelatorDMesonPairs { if (applyMixedEvent) { // Loop on the associated tracks for offline event mixing for (const auto& track : tracks) { - // apply track selection - if (track.collisionId() != gCollisionId) continue; - - // Manual trackFilter check - if (std::abs(track.eta()) >= etaTrackMax) continue; - if (track.pt() <= ptTrackMin) continue; - if (std::abs(track.dcaXY()) >= dcaXYTrackMax) continue; - if (std::abs(track.dcaZ()) >= dcaZTrackMax) continue; - // Removing D0 daughters by checking track indices - if (daughterTracksCutFlag) { - if ((candidate1.prong0Id() == track.globalIndex()) || (candidate1.prong1Id() == track.globalIndex())) { - continue; - } - } - if (cntD0 == 0) { - entryAssocHad(track.pt(), track.eta(), track.phi(), poolBin, gCollisionId, timeStamp); - registry.fill(HIST("hTracksBin"), poolBin); - registry.fill(HIST("hDcaXYVsPt"), track.dcaXY(), track.pt()); + // apply track selection + if (track.collisionId() != gCollisionId) + continue; + + // Manual trackFilter check + if (std::abs(track.eta()) >= etaTrackMax) + continue; + if (track.pt() <= ptTrackMin) + continue; + if (std::abs(track.dcaXY()) >= dcaXYTrackMax) + continue; + if (std::abs(track.dcaZ()) >= dcaZTrackMax) + continue; + // Removing D0 daughters by checking track indices + if (daughterTracksCutFlag) { + if ((candidate1.prong0Id() == track.globalIndex()) || (candidate1.prong1Id() == track.globalIndex())) { + continue; } - } // Hadron Tracks loop - cntD0++; + } + if (cntD0 == 0) { + entryAssocHad(track.pt(), track.eta(), track.phi(), poolBin, gCollisionId, timeStamp); + registry.fill(HIST("hTracksBin"), poolBin); + registry.fill(HIST("hDcaXYVsPt"), track.dcaXY(), track.pt()); + } + } // Hadron Tracks loop + cntD0++; } // Loop on the second D0 candidate @@ -886,7 +891,7 @@ struct HfCorrelatorDMesonPairs { entryD0PairMl(outputMlD0Cand1, outputMlD0barCand1, outputMlD0Cand2, outputMlD0barCand2); } else { // Fill entries - fillEntry(isDCand1, isDbarCand1, isDCand2, isDbarCand2, candidateType1, candidateType2, HfHelper::yD0(candidate1), HfHelper::yD0(candidate2), + fillEntry(isDCand1, isDbarCand1, isDCand2, isDbarCand2, candidateType1, candidateType2, HfHelper::yD0(candidate1), HfHelper::yD0(candidate2), candidate1.eta(), candidate2.eta(), candidate1.phi(), candidate2.phi(), candidate1.pt(), candidate2.pt(), HfHelper::invMassD0ToPiK(candidate1), HfHelper::invMassD0barToKPi(candidate1), HfHelper::invMassD0ToPiK(candidate2), HfHelper::invMassD0barToKPi(candidate2)); From 2bc5aba911e3a8158745a07abda0ecce87ebebd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrea=20Tavira=20Garc=C3=ADa?= <118979672+atavirag@users.noreply.github.com> Date: Mon, 27 Jul 2026 10:27:12 +0000 Subject: [PATCH 3/3] Fix linter issues --- PWGHF/HFC/DataModel/DMesonPairsTables.h | 4 ++-- PWGHF/HFC/TableProducer/correlatorDMesonPairs.cxx | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/PWGHF/HFC/DataModel/DMesonPairsTables.h b/PWGHF/HFC/DataModel/DMesonPairsTables.h index 01bb7984f1e..8f112cad74c 100644 --- a/PWGHF/HFC/DataModel/DMesonPairsTables.h +++ b/PWGHF/HFC/DataModel/DMesonPairsTables.h @@ -100,7 +100,7 @@ DECLARE_DMESON_PAIR_MCINFO_TABLE(D0PairMcGenInfo, 2, "D0PAIRGEN"); //! D0 pairs namespace hf_correlation_d_meson_had { // D candidate -DECLARE_SOA_COLUMN(PtD, pD, float); //! Transverse momentum of the D meson +DECLARE_SOA_COLUMN(PtD, ptD, float); //! Transverse momentum of the D meson DECLARE_SOA_COLUMN(YD, yD, float); //! Rapidity of the D meson DECLARE_SOA_COLUMN(EtaD, etaD, float); //! Pseudorapidity of the D meson DECLARE_SOA_COLUMN(PhiD, phiD, float); //! Azimuthal angle of the D meson @@ -110,7 +110,7 @@ DECLARE_SOA_COLUMN(GIndexColD, gIndexColD, int); //! G-index column of the D DECLARE_SOA_COLUMN(TimestampD, timestampD, int64_t); //! Timestamp of the D meson // Associated hadron -DECLARE_SOA_COLUMN(PtHad, pHad, float); //! Transverse momentum of the associated hadron +DECLARE_SOA_COLUMN(PtHad, ptHad, float); //! Transverse momentum of the associated hadron DECLARE_SOA_COLUMN(YHad, yHad, float); //! Rapidity of the associated hadron DECLARE_SOA_COLUMN(EtaHad, etaHad, float); //! Pseudorapidity of the associated hadron DECLARE_SOA_COLUMN(PhiHad, phiHad, float); //! Azimuthal angle of the associated hadron diff --git a/PWGHF/HFC/TableProducer/correlatorDMesonPairs.cxx b/PWGHF/HFC/TableProducer/correlatorDMesonPairs.cxx index 2ec54bf78cd..101e2a6c183 100644 --- a/PWGHF/HFC/TableProducer/correlatorDMesonPairs.cxx +++ b/PWGHF/HFC/TableProducer/correlatorDMesonPairs.cxx @@ -514,12 +514,12 @@ struct HfCorrelatorDMesonPairs { } /// Fill counters for D0 and D0bar - /// \param selectedD0Candidates contains all D0 candidates + /// \param d0Candidates contains all D0 candidates template - void getCountersPerEvent(const T& selectedD0Candidates) + void getCountersPerEvent(const T& d0Candidates) { int nDevent = 0, nDbarevent = 0, nDDbarevent = 0, nDorDbarevent = 0; - for (const auto& candidate : selectedD0Candidates) { + for (const auto& candidate : d0Candidates) { // Get counters per event bool const isSignalD0 = std::abs(HfHelper::invMassD0ToPiK(candidate) - MassD0) < massCut; bool const isSignalD0bar = std::abs(HfHelper::invMassD0barToKPi(candidate) - MassD0Bar) < massCut;