From 37433985645773bf20bafcfb5348155d0f48efce Mon Sep 17 00:00:00 2001 From: Marcello Di Costanzo Date: Tue, 3 Nov 2026 22:04:19 +0100 Subject: [PATCH 01/18] Study ass. tracks and triggers efficiencies --- .../correlatorFlowCharmHadronsReduced.cxx | 44 +- .../derivedDataCreatorCorrelationsReduced.cxx | 86 ++- PWGHF/HFC/Tasks/CMakeLists.txt | 5 + .../Tasks/taskCorrelationsEfficiencies.cxx | 621 ++++++++++++++++++ PWGHF/HFC/Utils/utilsFlow.h | 222 +++++++ 5 files changed, 934 insertions(+), 44 deletions(-) create mode 100644 PWGHF/HFC/Tasks/taskCorrelationsEfficiencies.cxx create mode 100644 PWGHF/HFC/Utils/utilsFlow.h diff --git a/PWGHF/HFC/TableProducer/correlatorFlowCharmHadronsReduced.cxx b/PWGHF/HFC/TableProducer/correlatorFlowCharmHadronsReduced.cxx index 50e99a602e1..c5416a60e82 100644 --- a/PWGHF/HFC/TableProducer/correlatorFlowCharmHadronsReduced.cxx +++ b/PWGHF/HFC/TableProducer/correlatorFlowCharmHadronsReduced.cxx @@ -92,10 +92,8 @@ struct HfCorrelatorFlowCharmHadronsReduced { Configurable fillSparses{"fillSparses", true, "Fill sparse histograms"}; Configurable fillTables{"fillTables", false, "Fill tables"}; Configurable numberEventsMixed{"numberEventsMixed", 5, "Number of events mixed in ME process"}; - Configurable> binsPtTrig{"binsPtTrig", std::vector{0., 3., 5., 8., 16., 36.}, "pT bin limits for trigger candidates"}; Configurable> bdtScore0PtMaxs{"bdtScore0PtMaxs", std::vector{0.1, 0.1, 0.1, 0.1, 0.1}, "pT-differential maximum score 0 for charm candidates"}; Configurable> bdtScore1PtMins{"bdtScore1PtMins", std::vector{0.1, 0.1, 0.1, 0.1, 0.1}, "pT-differential minimum score 1 for charm candidates"}; - Configurable> binsPtAssoc{"binsPtAssoc", std::vector{0.3, 1., 2., 50.}, "pT bin limits for associated particles"}; Configurable selCentrality{"selCentrality", false, "Use centrality to select events"}; Configurable selMultiplicity{"selMultiplicity", false, "Use multiplicity to select events"}; Configurable centMin{"centMin", 0, "min. centrality"}; @@ -128,9 +126,11 @@ struct HfCorrelatorFlowCharmHadronsReduced { Preslice assocTracksPerCol = aod::hf_correl_charm_had_reduced::hfcRedCorrCollId; Preslice trigCharmCandsPerCol = aod::hf_correl_charm_had_reduced::hfcRedCorrCollId; - ConfigurableAxis zPoolBins{"zPoolBins", {VARIABLE_WIDTH, -10.0, -2.5, 2.5, 10.0}, "Z vertex position pools"}; - ConfigurableAxis multPoolBins{"multPoolBins", {VARIABLE_WIDTH, 0., 900., 1800., 6000.}, "Event multiplicity pools (FT0M)"}; - ConfigurableAxis centPoolBins{"centPoolBins", {VARIABLE_WIDTH, 0., 10., 20., 30., 40., 50., 60., 70., 80., 90., 100}, "Event centrality pools"}; + ConfigurableAxis binsPtTrig{"binsPtTrig", {VARIABLE_WIDTH, 0., 1., 2., 3., 4., 5., 6., 8., 10., 12., 16., 24.}, "Trigger candidate pT bins"}; + ConfigurableAxis binsPtAssoc{"binsPtAssoc", {VARIABLE_WIDTH, 0.3, 1., 2., 50.}, "Associated particle pT bins"}; + ConfigurableAxis binsZPool{"binsZPool", {VARIABLE_WIDTH, -10.0, -2.5, 2.5, 10.0}, "Z vertex position pools"}; + ConfigurableAxis binsMultPool{"binsMultPool", {VARIABLE_WIDTH, 0., 900., 1800., 6000.}, "Event multiplicity pools (FT0M)"}; + ConfigurableAxis binsCentPool{"binsCentPool", {VARIABLE_WIDTH, 0., 10., 20., 30., 40., 50., 60., 70., 80., 90., 100}, "Event centrality pools"}; ConfigurableAxis binsInvMass{"binsInvMass", {300, 1.6, 2.2}, "Invariant mass bins"}; ConfigurableAxis binsMultFT0M{"binsMultFT0M", {100, 0., 10000.}, "Multiplicity as FT0M signal amplitude"}; ConfigurableAxis binsCent{"binsCent", {100, 0., 100.}, "Centrality bins"}; @@ -168,14 +168,18 @@ struct HfCorrelatorFlowCharmHadronsReduced { if (!fillSparses && !fillTables) { LOGP(fatal, "At least one of fillSparses or fillTables must be true!"); } - if ((binsPtTrig.value.size() != (bdtScore0PtMaxs.value.size() + 1) || binsPtTrig.value.size() != (bdtScore1PtMins.value.size() + 1))) { + if (((binsPtTrig.value.size() - 1) != (bdtScore0PtMaxs.value.size() + 1) || + (binsPtTrig.value.size() - 1) != (bdtScore1PtMins.value.size() + 1))) { + LOG(info) << "binsPtTrig.value.size(): " << binsPtTrig.value.size(); + LOG(info) << "bdtScore0PtMaxs.value.size(): " << bdtScore0PtMaxs.value.size(); + LOG(info) << "bdtScore1PtMins.value.size(): " << bdtScore1PtMins.value.size(); LOGP(fatal, "The size of bdtScore0PtMaxs and bdtScore1PtMins must be the one of binsPtTrig minus one!"); } if (doprocessSameEventCharmHadWCentMix || doprocessSameEventHadHadWCentMix || doprocessMixedEventCharmHadWCentMix || doprocessMixedEventHadHadWCentMix || doprocessSameEventCharmHadWCentMixBase || doprocessMixedEventCharmHadWCentMixBase) { - poolBins = (centPoolBins->size() - 2) * (zPoolBins->size() - 2); + poolBins = (binsCentPool->size() - 2) * (binsZPool->size() - 2); } else { - poolBins = (multPoolBins->size() - 2) * (zPoolBins->size() - 2); + poolBins = (binsMultPool->size() - 2) * (binsZPool->size() - 2); } const AxisSpec axisInvMass{binsInvMass, "Inv. mass (GeV/#it{c}^{2})"}; @@ -185,8 +189,8 @@ struct HfCorrelatorFlowCharmHadronsReduced { const AxisSpec axisPoolBin = {poolBins, 0., static_cast(poolBins), "PoolBin"}; const AxisSpec axisDeltaEta = {binsDeltaEta, "#Delta#it{#eta}"}; const AxisSpec axisDeltaPhi = {binsDeltaPhi, "#Delta#it{#varphi}"}; - const AxisSpec axisPtTrig = {std::vector(binsPtTrig), "#it{p}_{T} Trig (GeV/#it{c})"}; - const AxisSpec axisPtAssoc = {std::vector(binsPtAssoc), "#it{p}_{T} Assoc (GeV/#it{c})"}; + const AxisSpec axisPtTrig = {binsPtTrig, "#it{p}_{T} Trig (GeV/#it{c})"}; + const AxisSpec axisPtAssoc = {binsPtAssoc, "#it{p}_{T} Assoc (GeV/#it{c})"}; const AxisSpec axisMlOne{binsMlOne, "bdtScore0"}; const AxisSpec axisMlTwo{binsMlTwo, "bdtScore1"}; @@ -509,7 +513,7 @@ struct HfCorrelatorFlowCharmHadronsReduced { aod::HfcRedTrigCharms const&, aod::HfcRedCorrColls const&) { - BinningMultPosZ binPolicyPosZMult{{zPoolBins, multPoolBins}}; + BinningMultPosZ binPolicyPosZMult{{binsZPool, binsMultPool}}; auto trigCand = pair.template hfcRedTrigCharm_as(); if (fillSparses && fillTables) { fillSameEvent(pair, trigCand, binPolicyPosZMult); @@ -525,7 +529,7 @@ struct HfCorrelatorFlowCharmHadronsReduced { aod::HfcRedTrigTracks const&, aod::HfcRedCorrColls const&) { - BinningMultPosZ binPolicyPosZMult{{zPoolBins, multPoolBins}}; + BinningMultPosZ binPolicyPosZMult{{binsZPool, binsMultPool}}; auto trigCand = pair.template hfcRedTrigTrack_as(); if (fillSparses && fillTables) { fillSameEvent(pair, trigCand, binPolicyPosZMult); @@ -541,7 +545,7 @@ struct HfCorrelatorFlowCharmHadronsReduced { aod::HfcRedTrigCharms const&, aod::HfcRedCorrColls const&) { - BinningCentPosZ binPolicyPosZCent{{zPoolBins, centPoolBins}}; + BinningCentPosZ binPolicyPosZCent{{binsZPool, binsCentPool}}; auto trigCand = pair.template hfcRedTrigCharm_as(); if (fillSparses && fillTables) { fillSameEvent(pair, trigCand, binPolicyPosZCent); @@ -557,7 +561,7 @@ struct HfCorrelatorFlowCharmHadronsReduced { aod::HfcRedTrigTracks const&, aod::HfcRedCorrColls const&) { - BinningCentPosZ binPolicyPosZCent{{zPoolBins, centPoolBins}}; + BinningCentPosZ binPolicyPosZCent{{binsZPool, binsCentPool}}; auto trigCand = pair.template hfcRedTrigTrack_as(); if (fillSparses && fillTables) { fillSameEvent(pair, trigCand, binPolicyPosZCent); @@ -573,7 +577,7 @@ struct HfCorrelatorFlowCharmHadronsReduced { TrigCharmCands const& candidates, AssocTracks const& tracks) { - BinningCentPosZ binPolicyPosZCent{{zPoolBins, centPoolBins}}; + BinningCentPosZ binPolicyPosZCent{{binsZPool, binsCentPool}}; auto pairsTuple = std::make_tuple(candidates, tracks); Pair const pairs{binPolicyPosZCent, numberEventsMixed, -1, collisions, pairsTuple, &cache}; if (fillSparses && fillTables) { @@ -590,7 +594,7 @@ struct HfCorrelatorFlowCharmHadronsReduced { TrigCharmCands const& candidates, AssocTracks const& tracks) { - BinningMultPosZ binPolicyPosZMult{{zPoolBins, multPoolBins}}; + BinningMultPosZ binPolicyPosZMult{{binsZPool, binsMultPool}}; auto pairsTuple = std::make_tuple(candidates, tracks); Pair const pairs{binPolicyPosZMult, numberEventsMixed, -1, collisions, pairsTuple, &cache}; if (fillSparses && fillTables) { @@ -606,7 +610,7 @@ struct HfCorrelatorFlowCharmHadronsReduced { void processMixedEventHadHadWCentMix(aod::HfcRedCorrColls const& collisions, AssocTracks const& tracks) { - BinningCentPosZ binPolicyPosZCent{{zPoolBins, centPoolBins}}; + BinningCentPosZ binPolicyPosZCent{{binsZPool, binsCentPool}}; auto tracksTuple = std::make_tuple(tracks); SameKindPair const pairs{binPolicyPosZCent, numberEventsMixed, -1, collisions, tracksTuple, &cache}; if (fillSparses && fillTables) { @@ -622,7 +626,7 @@ struct HfCorrelatorFlowCharmHadronsReduced { void processMixedEventHadHadWMultMix(aod::HfcRedCorrColls const& collisions, AssocTracks const& tracks) { - BinningMultPosZ binPolicyPosZMult{{zPoolBins, multPoolBins}}; + BinningMultPosZ binPolicyPosZMult{{binsZPool, binsMultPool}}; auto tracksTuple = std::make_tuple(tracks); SameKindPair const pairs{binPolicyPosZMult, numberEventsMixed, -1, collisions, tracksTuple, &cache}; if (fillSparses && fillTables) { @@ -656,7 +660,7 @@ struct HfCorrelatorFlowCharmHadronsReduced { TrigCharmCands const& candidates, aod::HfcRedAssBases const& tracks) { - BinningCentPosZ binPolicyPosZCent{{zPoolBins, centPoolBins}}; + BinningCentPosZ binPolicyPosZCent{{binsZPool, binsCentPool}}; for (const auto& collision : collisions) { if (!isSelCollision(collision)) { @@ -677,7 +681,7 @@ struct HfCorrelatorFlowCharmHadronsReduced { TrigCharmCands const& candidates, aod::HfcRedAssBases const& tracks) { - BinningCentPosZ binPolicyPosZCent{{zPoolBins, centPoolBins}}; + BinningCentPosZ binPolicyPosZCent{{binsZPool, binsCentPool}}; doCorrelationsMixedEvent(collisions, candidates, tracks, binPolicyPosZCent); } diff --git a/PWGHF/HFC/TableProducer/derivedDataCreatorCorrelationsReduced.cxx b/PWGHF/HFC/TableProducer/derivedDataCreatorCorrelationsReduced.cxx index 06ae7c8a758..ad36c4baecd 100644 --- a/PWGHF/HFC/TableProducer/derivedDataCreatorCorrelationsReduced.cxx +++ b/PWGHF/HFC/TableProducer/derivedDataCreatorCorrelationsReduced.cxx @@ -102,14 +102,11 @@ struct HfDerivedDataCreatorCorrelationsReduced { Configurable downSampleTrksFactor{"downSampleTrksFactor", 1., "Fraction of associated tracks to keep"}; Configurable ptMaxForDownSample{"ptMaxForDownSample", 10., "Maximum pt for the application of the downsampling factor"}; Configurable centMaxForDownSample{"centMaxForDownSample", 101., "Maximum centrality for the application of the downsampling factor"}; - Configurable> binsPtTrig{"binsPtTrig", std::vector{0., 1., 2., 3., 5., 8., 12., 24., 36.}, "pT bin limits for trigger candidates"}; - Configurable> binsPtAssoc{"binsPtAssoc", std::vector{0.2, 1., 2., 50.}, "pT bin limits for associated particles"}; HfEventSelection hfEvSel; // event selection and monitoring o2::framework::Service ccdb{}; SliceCache cache; - double massCharm{0.}; TF1* funcDcaXYPtCutPrimTrk = nullptr; using CollsWithCentMult = soa::Join; @@ -117,7 +114,7 @@ struct HfDerivedDataCreatorCorrelationsReduced { using CandDplusData = soa::Filtered>; using CandD0Data = soa::Filtered>; using CandLcData = soa::Filtered>; - using TracksData = soa::Filtered>; + using TracksData = soa::Filtered>; Filter filterSelectDsCandidates = aod::hf_sel_candidate_ds::isSelDsToKKPi >= selectionFlag || aod::hf_sel_candidate_ds::isSelDsToPiKK >= selectionFlag; Filter filterSelectDplusCandidates = aod::hf_sel_candidate_dplus::isSelDplusToPiKPi >= selectionFlag; @@ -138,48 +135,34 @@ struct HfDerivedDataCreatorCorrelationsReduced { Partition selectedLcToPKPi = aod::hf_sel_candidate_lc::isSelLcToPKPi >= selectionFlag; Partition selectedLcToPiKP = aod::hf_sel_candidate_lc::isSelLcToPiKP >= selectionFlag; - ConfigurableAxis binsInvMass{"binsInvMass", {300, 1.6, 2.2}, ""}; + ConfigurableAxis binsTpcSignal{"binsTpcSignal", {500, 0., 500.}, "TPC signal bins"}; + ConfigurableAxis binsPtTrig{"binsPtTrig", {24, 0, 24}, ""}; + ConfigurableAxis binsPtAssoc{"binsPtAssoc", {20, 0, 10}, ""}; ConfigurableAxis binsMult{"binsMult", {100, 0., 10000.}, "Multiplicity bins"}; ConfigurableAxis binsCent{"binsCent", {100, 0., 100.}, "Centrality bins"}; ConfigurableAxis binsPosZ{"binsPosZ", {100, -10., 10.}, "Primary vertex z coordinate"}; ConfigurableAxis binsEta{"binsEta", {50, -2., 2.}, "Eta bins"}; ConfigurableAxis binsPhi{"binsPhi", {64, -o2::constants::math::PIHalf, 3. * o2::constants::math::PIHalf}, "Phi bins"}; - ConfigurableAxis binsDeltaEta{"binsDeltaEta", {100, -2., 2.}, "Delta Eta bins"}; - ConfigurableAxis binsDeltaPhi{"binsDeltaPhi", {64, -3., 3.}, "Delta Phi bins"}; - ConfigurableAxis binsMlOne{"binsMlOne", {100, 0., 1.}, ""}; - ConfigurableAxis binsMlTwo{"binsMlTwo", {100, 0., 1.}, ""}; ConfigurableAxis binsDca{"binsDca", {200, -1., 1.}, ""}; HistogramRegistry registry{"registry", {}}; void init(InitContext&) { - if (doprocessDplusSameEvent || doprocessDplusMixedEvent) { - massCharm = o2::constants::physics::MassDPlus; - } else if (doprocessDsSameEvent || doprocessDsMixedEvent) { - massCharm = o2::constants::physics::MassDS; - } else if (doprocessD0SameEvent || doprocessD0MixedEvent) { - massCharm = o2::constants::physics::MassD0; - } else if (doprocessLcSameEvent || doprocessLcMixedEvent) { - massCharm = o2::constants::physics::MassLambdaCPlus; - } else if (doprocessHadronHadronSameEvent || doprocessHadronHadronMixedEvent) { - LOG(info) << "Charm mass not set, processing Hadron-Hadron case"; - } else { - LOG(fatal) << "No decay channel selected to process"; - } hfEvSel.addHistograms(registry); // collision monitoring ccdb->setURL(ccdbUrl); ccdb->setCaching(true); ccdb->setLocalObjectValidityChecking(); + const AxisSpec axisTpcSignal = {binsTpcSignal, "TPC Signal"}; const AxisSpec axisCent = {binsCent, "Centrality"}; const AxisSpec axisMult = {binsMult, "Multiplicity"}; const AxisSpec axisPosZ = {binsPosZ, "PosZ"}; const AxisSpec axisEta = {binsEta, "#it{#eta}"}; const AxisSpec axisPhi = {binsPhi, "#it{#varphi}"}; - const AxisSpec axisPtTrig = {std::vector(binsPtTrig), "#it{p}_{T} Trig (GeV/#it{c})"}; - const AxisSpec axisPtAssoc = {std::vector(binsPtAssoc), "#it{p}_{T} Assoc (GeV/#it{c})"}; + const AxisSpec axisPtTrig = {binsPtTrig, "#it{p}_{T} Trig (GeV/#it{c})"}; + const AxisSpec axisPtAssoc = {binsPtAssoc, "#it{p}_{T} Assoc (GeV/#it{c})"}; const AxisSpec axisDcaXY = {binsDca, "DCA XY (cm)"}; const AxisSpec axisDcaZ = {binsDca, "DCA Z (cm)"}; @@ -194,6 +177,19 @@ struct HfDerivedDataCreatorCorrelationsReduced { registry.add("hDcaZVsPtVsCentAssoc", "Associated particles DCAzVsPtVsCent", {HistType::kTH3F, {{axisPtAssoc}, {axisDcaZ}, {axisCent}}}); registry.add("hDcaXYVsPtVsMultAssoc", "Associated particles DCAxyVsPtVsMult", {HistType::kTH3F, {{axisPtAssoc}, {axisDcaXY}, {axisMult}}}); registry.add("hDcaZVsPtVsMultAssoc", "Associated particles DCAzVsPtVsMult", {HistType::kTH3F, {{axisPtAssoc}, {axisDcaZ}, {axisMult}}}); + registry.add("hAssocTrkPidTPC", "Associated tracks PID TPC", {HistType::kTH2F, {{axisPtAssoc}, {axisTpcSignal}}}); + registry.add("hTrackSelection", "Track selection", {HistType::kTH1F, {{11, -0.5, 10.5}}}); + registry.get(HIST("hTrackSelection"))->GetXaxis()->SetBinLabel(1, "All"); + registry.get(HIST("hTrackSelection"))->GetXaxis()->SetBinLabel(2, "IsQualityTrack"); + registry.get(HIST("hTrackSelection"))->GetXaxis()->SetBinLabel(3, "IsQualityTrackITS"); + registry.get(HIST("hTrackSelection"))->GetXaxis()->SetBinLabel(4, "IsQualityTrackTPC"); + registry.get(HIST("hTrackSelection"))->GetXaxis()->SetBinLabel(5, "IsPrimaryTrack"); + registry.get(HIST("hTrackSelection"))->GetXaxis()->SetBinLabel(6, "IsInAcceptanceTrack"); + registry.get(HIST("hTrackSelection"))->GetXaxis()->SetBinLabel(7, "IsGlobalTrack"); + registry.get(HIST("hTrackSelection"))->GetXaxis()->SetBinLabel(8, "IsGlobalTrackWoTPCCluster"); + registry.get(HIST("hTrackSelection"))->GetXaxis()->SetBinLabel(9, "IsGlobalTrackWoPtEta"); + registry.get(HIST("hTrackSelection"))->GetXaxis()->SetBinLabel(10, "IsGlobalTrackWoDCA"); + registry.get(HIST("hTrackSelection"))->GetXaxis()->SetBinLabel(11, "IsGlobalTrackWoDCATPCCluster"); // Setup pt-dependent DCAxy cut function if (usePtDiffDcaXYCut) { @@ -203,6 +199,44 @@ struct HfDerivedDataCreatorCorrelationsReduced { } }; // end init + /// Fill track selection histograms + /// \param track is the associated track + template + void fillTrkSelHistos(const TTrack& track) + { + registry.fill(HIST("hTrackSelection"), 0); // all tracks + if (track.isQualityTrack()) { + registry.fill(HIST("hTrackSelection"), 1); + } + if (track.isQualityTrackITS()) { + registry.fill(HIST("hTrackSelection"), 2); + } + if (track.isQualityTrackTPC()) { + registry.fill(HIST("hTrackSelection"), 3); + } + if (track.isPrimaryTrack()) { + registry.fill(HIST("hTrackSelection"), 4); + } + if (track.isInAcceptanceTrack()) { + registry.fill(HIST("hTrackSelection"), 5); + } + if (track.isGlobalTrack()) { + registry.fill(HIST("hTrackSelection"), 6); + } + if (track.isGlobalTrackWoTPCCluster()) { + registry.fill(HIST("hTrackSelection"), 7); + } + if (track.isGlobalTrackWoPtEta()) { + registry.fill(HIST("hTrackSelection"), 8); + } + if (track.isGlobalTrackWoDCA()) { + registry.fill(HIST("hTrackSelection"), 9); + } + if (track.isGlobalTrackWoDCATPCCluster()) { + registry.fill(HIST("hTrackSelection"), 10); + } + } + /// Get charm hadron candidate mass /// \param candidate is the charm hadron candidate template @@ -384,6 +418,7 @@ struct HfDerivedDataCreatorCorrelationsReduced { } for (const auto& assTrk : assTrks) { + fillTrkSelHistos(assTrk); double assTrkPt = assTrk.pt(); if (usePtDiffDcaXYCut) { float const dcaXYTrkCut = funcDcaXYPtCutPrimTrk->Eval(assTrkPt); @@ -410,6 +445,7 @@ struct HfDerivedDataCreatorCorrelationsReduced { registry.fill(HIST("hDcaZVsPtVsCentAssoc"), assTrkPt, assTrk.dcaZ(), cent); registry.fill(HIST("hDcaXYVsPtVsMultAssoc"), assTrkPt, assTrk.dcaXY(), mult); registry.fill(HIST("hDcaZVsPtVsMultAssoc"), assTrkPt, assTrk.dcaZ(), mult); + registry.fill(HIST("hAssocTrkPidTPC"), assTrkPt, assTrk.tpcSignal()); double deltaPhi = RecoDecay::constrainAngle(assTrk.phi() - trigCand.phi(), -o2::constants::math::PIHalf); rowAssocTrkSels(assTrk.tpcNClsCrossedRows(), assTrk.itsClusterMap(), assTrk.itsNCls(), assTrk.dcaXY(), assTrk.dcaZ()); @@ -451,6 +487,7 @@ struct HfDerivedDataCreatorCorrelationsReduced { { bool first = true; for (const auto& assTrk : assTrks) { + fillTrkSelHistos(assTrk); if (!assTrk.isGlobalTrackWoDCA() || assTrk.tpcNClsCrossedRows() < tpcNClsCrossedRowsMin) { continue; } @@ -474,6 +511,7 @@ struct HfDerivedDataCreatorCorrelationsReduced { registry.fill(HIST("hDcaZVsPtVsCentAssoc"), assTrkPt, assTrk.dcaZ(), cent); registry.fill(HIST("hDcaXYVsPtVsMultAssoc"), assTrkPt, assTrk.dcaXY(), mult); registry.fill(HIST("hDcaZVsPtVsMultAssoc"), assTrkPt, assTrk.dcaZ(), mult); + registry.fill(HIST("hAssocTrkPidTPC"), assTrkPt, assTrk.tpcSignal()); rowAssocBases(rowCollisions.lastIndex(), assTrk.phi(), assTrk.eta(), assTrkPt); rowAssocTrkSels(assTrk.tpcNClsCrossedRows(), assTrk.itsClusterMap(), assTrk.itsNCls(), assTrk.dcaXY(), assTrk.dcaZ()); } diff --git a/PWGHF/HFC/Tasks/CMakeLists.txt b/PWGHF/HFC/Tasks/CMakeLists.txt index 4551ccd2b0f..8c60c81b29d 100644 --- a/PWGHF/HFC/Tasks/CMakeLists.txt +++ b/PWGHF/HFC/Tasks/CMakeLists.txt @@ -74,6 +74,11 @@ o2physics_add_dpl_workflow(task-flow PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2Physics::PWGCFCore COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(task-correlations-efficiencies + SOURCES taskCorrelationsEfficiencies.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2Physics::EventFilteringUtils + COMPONENT_NAME Analysis) + include_directories(${CMAKE_CURRENT_SOURCE_DIR}/PWGCF/Core) o2physics_add_dpl_workflow(task-charm-hadrons-charm-femto-dream diff --git a/PWGHF/HFC/Tasks/taskCorrelationsEfficiencies.cxx b/PWGHF/HFC/Tasks/taskCorrelationsEfficiencies.cxx new file mode 100644 index 00000000000..1852d1cbeec --- /dev/null +++ b/PWGHF/HFC/Tasks/taskCorrelationsEfficiencies.cxx @@ -0,0 +1,621 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file taskCorrelationsEfficiencies.cxx +/// \brief Charm hadrons and associated tracks efficiency evaluation for correlations studies +/// \author Marcello Di Costanzo , Politecnico and INFN Torino + +#include "PWGHF/Core/CentralityEstimation.h" +#include "PWGHF/Core/HfHelper.h" +#include "PWGHF/DataModel/AliasTables.h" +#include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/DataModel/CandidateSelectionTables.h" +#include "PWGHF/HFC/DataModel/DerivedDataCorrelationTables.h" +#include "PWGHF/Utils/utilsEvSelHf.h" +#include "PWGHF/HFC/Utils/utilsFlow.h" + +#include "Common/Core/RecoDecay.h" +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Multiplicity.h" +#include "Common/DataModel/TrackSelectionTables.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; +using namespace o2::hf_centrality; +using namespace o2::hf_evsel; +using namespace o2::hfc_utils_flow; + +enum axesCharmReco { + kAxisPtTrig, + kAxisPvContrib, + kAxisEtaTrig, + kAxisPhiTrig, + kAxisMlScore0, + kAxisMlScore1 +}; + +enum SparseAxesCharmGen { + kAxisPtTrigGen, + kAxisEtaTrigGen, + kAxisPhiTrigGen +}; + +enum axesAssocTracks { + kAxisPtAssoc, + kAxisEtaAssoc, + kAxisPhiAssoc, + kAxisZVtx, + kAxisAssTrkSpecie, + kAxisAssTrkOrigin +}; + +/// Code to select collisions with at least one Ds meson +struct HfTaskCorrelationsEfficiencies { + + Configurable selectionFlag{"selectionFlag", 15, "Selection Flag for hadron (ML score tables are required to run the task)"}; + Configurable ccdbUrl{"ccdbUrl", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable> classMl{"classMl", {0, 2}, "Indexes of BDT scores to be stored. Two indexes max."}; + Configurable yCandMax{"yCandMax", 0.8, "max. cand. rapidity"}; + Configurable ptCandMin{"ptCandMin", 0., "min. cand. pT"}; + Configurable ptCandMax{"ptCandMax", 24., "max. cand. pT"}; + Configurable tpcNClsCrossedRowsMin{"tpcNClsCrossedRowsMin", 70, "min. TPC crossed rows for associated tracks"}; + Configurable etaTrkMax{"etaTrkMax", 1., "max. track eta"}; + Configurable ptTrkMin{"ptTrkMin", 0.3, "min. track pT"}; + Configurable ptTrkMax{"ptTrkMax", 3., "max. track pT"}; + Configurable dcaXYTrkMax{"dcaXYTrkMax", 1., "max. track DCA XY"}; + Configurable dcaZTrkMax{"dcaZTrkMax", 1., "max. track DCA Z"}; + Configurable usePtDiffDcaXYCut{"usePtDiffDcaXYCut", false, "Use pt-differential DCAxy cut for associated tracks"}; + Configurable dcaXYTrkNSigmaMax{"dcaXYTrkNSigmaMax", 7, "Cut on number of sigma deviations from expected DCA in the transverse direction"}; + Configurable dcaXYPtPrimTrkFunc{"dcaXYPtPrimTrkFunc", "(0.0026+0.005/(x^1.01))", "Functional form of pt-dependent DCAxy cut"}; + Configurable> bdtScore0PtMaxs{"bdtScore0PtMaxs", std::vector{0.1, 0.1, 0.1, 0.1, 0.1}, "pT-differential maximum score 0 for charm candidates"}; + Configurable> bdtScore1PtMins{"bdtScore1PtMins", std::vector{0.1, 0.1, 0.1, 0.1, 0.1}, "pT-differential minimum score 1 for charm candidates"}; + + // Configurables for efficiency validation + Configurable runEfficiencyValidation{"runEfficiencyValidation", false, "Flag for running efficiency validation"}; + Configurable> binsPtEffCharm{"binsPtEffCharm", std::vector{0., 2., 4., 6., 8., 10., 24.}, "pT bin limits for efficiency"}; + Configurable> binsPtEffAssTrk{"binsPtEffAssTrk", std::vector{0.3, 2., 4., 8., 12., 50.}, "pT bin limits for associated particle efficiency"}; + Configurable> effPromptCharm{"effPromptCharm", {1., 1., 1., 1., 1., 1.}, "efficiency values for prompt D+ meson"}; + Configurable> effFdCharm{"effFdCharm", {1., 1., 1., 1., 1., 1.}, "efficiency values for beauty feed-down D+ meson"}; + Configurable> effAssTrk{"effAssTrk", {1., 1., 1., 1., 1.}, "efficiency values for associated particles"}; + Configurable loadAccXEffFromCCDB{"loadAccXEffFromCCDB", false, "Flag for loading efficiency distributions from CCDB"}; + Configurable assTrkEffPath{"assTrkEffPath", "", "CCDB path for ass. tracks efficiency"}; + Configurable promptEffPath{"promptEffPath", "", "CCDB path for trigger prompt efficiency"}; + Configurable fdEffPath{"fdEffPath", "", "CCDB path for trigger fd efficiency"}; + Configurable timestampCcdb{"timestampCcdb", -1, "timestamp of the efficiency files used to query in CCDB"}; + Configurable ccdbNoLaterThan{"ccdbNoLaterThan", std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(), "latest acceptable timestamp of creation for the object"}; + + HfcFlowHelper hfcFlowHelper; // flow utilities + o2::framework::Service ccdb{}; + std::shared_ptr mRecoPrompt = nullptr; + std::shared_ptr mGenPrompt = nullptr; + std::shared_ptr mRecoFD = nullptr; + std::shared_ptr mGenFD = nullptr; + std::shared_ptr mRecoAssTrk = nullptr; + std::shared_ptr mGenAssTrk = nullptr; + SliceCache cache; + + TF1* funcDcaXYPtCutPrimTrk = nullptr; + + using RecoCollisions = soa::Join; + using McCandsDs = soa::Filtered>; + using McCandsDplus = soa::Filtered>; + using McCandsD0 = soa::Filtered>; + using McCandsLc = soa::Filtered>; + using McTracks = soa::Filtered>; + + Filter filterSelectDsCands = aod::hf_sel_candidate_ds::isSelDsToKKPi >= selectionFlag || aod::hf_sel_candidate_ds::isSelDsToPiKK >= selectionFlag; + Filter filterSelectDplusCands = aod::hf_sel_candidate_dplus::isSelDplusToPiKPi >= selectionFlag; + Filter filterSelectD0Cands = aod::hf_sel_candidate_d0::isSelD0 >= selectionFlag || aod::hf_sel_candidate_d0::isSelD0bar >= selectionFlag; + Filter filterSelectLcCands = aod::hf_sel_candidate_lc::isSelLcToPKPi >= selectionFlag || aod::hf_sel_candidate_lc::isSelLcToPiKP >= selectionFlag; + Filter filterSelectTrk = (nabs(aod::track::eta) < etaTrkMax) && (aod::track::pt > ptTrkMin) && (aod::track::pt < ptTrkMax) && (nabs(aod::track::dcaXY) < dcaXYTrkMax) && (nabs(aod::track::dcaZ) < dcaZTrkMax); + + Preslice candsDsPerColl = aod::hf_cand::collisionId; + Preslice candsDplusPerColl = aod::hf_cand::collisionId; + Preslice candsD0PerColl = aod::hf_cand::collisionId; + Preslice candsLcPerColl = aod::hf_cand::collisionId; + Preslice trackIndicesPerColl = aod::track::collisionId; + + PresliceUnsorted colPerMcCollision = aod::mccollisionlabel::mcCollisionId; + + ConfigurableAxis binsInvMass{"binsInvMass", {600, 1.6, 2.2}, ""}; + ConfigurableAxis binsPtCharm{"binsPtCharm", {VARIABLE_WIDTH, 0., 2., 4., 6., 8., 24.}, ""}; + ConfigurableAxis binsPtAssoc{"binsPtAssoc", {20, 0, 10}, ""}; + ConfigurableAxis binsZVtx{"binsZVtx", {120, -11, 11}, ""}; + ConfigurableAxis binsPvContrib{"binsPvContrib", {5001, -0.5, 5000.5}, ""}; + ConfigurableAxis binsEta{"binsEta", {50, -2., 2.}, ""}; + ConfigurableAxis binsPhi{"binsPhi", {64, 0, 6.28}, ""}; + ConfigurableAxis binsMlOne{"binsMlOne", {100, 0., 1.}, ""}; + ConfigurableAxis binsMlTwo{"binsMlTwo", {100, 0., 1.}, ""}; + + HistogramRegistry registry{"registry", {}}; + + void init(InitContext&) + { + + ccdb->setURL(ccdbUrl); + ccdb->setCaching(true); + ccdb->setLocalObjectValidityChecking(); + ccdb->setCreatedNotAfter(ccdbNoLaterThan.value); + + // Fetch CCDB correction histograms for efficiency validation + if (runEfficiencyValidation && loadAccXEffFromCCDB) { + + mRecoPrompt = std::shared_ptr(ccdb->getForTimeStamp(Form("%s/PromptReco.root", promptEffPath.value.c_str()), timestampCcdb)); + if (mRecoPrompt == nullptr) { + LOGF(fatal, "Could not load efficiency histogram for trigger particles from %s", promptEffPath.value.c_str()); + } + mGenPrompt = std::shared_ptr(ccdb->getForTimeStamp(Form("%s/PromptGen.root", promptEffPath.value.c_str()), timestampCcdb)); + if (mGenPrompt == nullptr) { + LOGF(fatal, "Could not load efficiency histogram for trigger particles from %s", promptEffPath.value.c_str()); + } + LOGF(info, "Loaded trigger efficiency (prompt D) histogram from %s", promptEffPath.value.c_str()); + + mRecoFD = std::shared_ptr(ccdb->getForTimeStamp(Form("%s/FDReco.root", fdEffPath.value.c_str()), timestampCcdb)); + if (mRecoFD == nullptr) { + LOGF(fatal, "Could not load efficiency histogram for trigger particles from %s", fdEffPath.value.c_str()); + } + mGenFD = std::shared_ptr(ccdb->getForTimeStamp(Form("%s/FDGen.root", fdEffPath.value.c_str()), timestampCcdb)); + if (mGenFD == nullptr) { + LOGF(fatal, "Could not load efficiency histogram for trigger particles from %s", fdEffPath.value.c_str()); + } + LOGF(info, "Loaded feed-down D meson efficiency histogram from %s", fdEffPath.value.c_str()); + + mRecoAssTrk = std::shared_ptr(ccdb->getForTimeStamp(Form("%s/TracksReco.root", assTrkEffPath.value.c_str()), timestampCcdb)); + if (mRecoAssTrk == nullptr) { + LOGF(fatal, "Could not load efficiency histogram for associated particles from %s", assTrkEffPath.value.c_str()); + } + mGenAssTrk = std::shared_ptr(ccdb->getForTimeStamp(Form("%s/TracksGen.root", assTrkEffPath.value.c_str()), timestampCcdb)); + if (mGenAssTrk == nullptr) { + LOGF(fatal, "Could not load efficiency histogram for associated particles from %s", assTrkEffPath.value.c_str()); + } + LOGF(info, "Loaded associated efficiency histogram from %s", assTrkEffPath.value.c_str()); + } + + std::vector classesMl; + for (const auto scoreClass : classMl.value) { + if (scoreClass < 0) { + LOG(fatal) << "ML class indexes must be non-negative"; + return; + } + classesMl.push_back(static_cast(scoreClass)); + } + + if (classesMl.size() > 2) { + LOG(fatal) << "At most two ML classes can be selected"; + return; + } + + hfcFlowHelper.init(ccdb, registry, classesMl, yCandMax.value); + + // Setup pt-dependent DCAxy cut function + if (usePtDiffDcaXYCut) { + funcDcaXYPtCutPrimTrk = new TF1("funcDcaXYPtCutPrimTrk", Form("[0]*%s", dcaXYPtPrimTrkFunc.value.data()), 0.001, 100); + funcDcaXYPtCutPrimTrk->SetParameter(0, dcaXYTrkNSigmaMax); + LOGF(info, "DCAxy pt-dependence function: %s", Form("[0]*%s", dcaXYPtPrimTrkFunc.value.data())); + } + + if (((binsPtCharm.value.size() - 1) != (bdtScore0PtMaxs.value.size() + 1) || + (binsPtCharm.value.size() - 1) != (bdtScore1PtMins.value.size() + 1))) { + LOG(info) << "binsPtCharm.value.size(): " << binsPtCharm.value.size(); + LOG(info) << "bdtScore0PtMaxs.value.size(): " << bdtScore0PtMaxs.value.size(); + LOG(info) << "bdtScore1PtMins.value.size(): " << bdtScore1PtMins.value.size(); + LOGP(fatal, "The size of bdtScore0PtMaxs and bdtScore1PtMins must be the one of binsPtCharm minus one!"); + } + + // Add efficiency sparses + // Axes: mass, pt, pv contributors, pseudo-rapidity, ml_score_0, ml_score_1 + const AxisSpec axisInvMass = {binsInvMass, "Mass (GeV/c^{2})"}; + const AxisSpec axisPtTrig = {binsPtCharm, "#it{p}_{T} Trig (GeV/#it{c})"}; + const AxisSpec axisPvContrib = {binsPvContrib, "PV contributors"}; + const AxisSpec axisEtaTrig = {binsEta, "#it{#eta}"}; + const AxisSpec axisPhiTrig = {binsPhi, "#it{#varphi}"}; + const AxisSpec axisMlScore0 = {binsMlOne, "ML score 0"}; + const AxisSpec axisMlScore1 = {binsMlTwo, "ML score 1"}; + std::vector axesCharmReco = {axisPtTrig, axisPvContrib, axisEtaTrig, axisPhiTrig, axisMlScore0, axisMlScore1}; + + registry.add("hCharmPromptGen", "Generated prompt charm-hadron candidates;;", {HistType::kTHnSparseF}, {{axisPtTrig}, {axisEtaTrig}, {axisPhiTrig}}); + registry.add("hCharmFdGen", "Generated non-prompt charm-hadron candidates;;", {HistType::kTHnSparseF}, {{axisPtTrig}, {axisEtaTrig}, {axisPhiTrig}}); + registry.add("hCharmPromptReco", "Reconstructed prompt charm-hadron candidates;;", {HistType::kTHnSparseF}, axesCharmReco); + registry.add("hCharmFdReco", "Reconstructed non-prompt charm-hadron candidates;;", {HistType::kTHnSparseF}, axesCharmReco); + if (runEfficiencyValidation) { + registry.add("hCharmPromptRecoPtRew", "Reconstructed prompt charm-hadron candidates;;", {HistType::kTHnSparseF}, axesCharmReco); + registry.add("hCharmFdRecoPtRew", "Reconstructed non-prompt charm-hadron candidates;;", {HistType::kTHnSparseF}, axesCharmReco); + registry.get(HIST("hCharmPromptRecoPtRew"))->Sumw2(); + registry.get(HIST("hCharmFdRecoPtRew"))->Sumw2(); + } + + // Axes: pt, eta, phi, z_vtx, specie + const AxisSpec axisPtAssoc = {binsPtAssoc, "#it{p}_{T} Assoc (GeV/#it{c})"}; + const AxisSpec axisEtaAssoc = {binsEta, "#it{#eta}"}; + const AxisSpec axisPhiAssoc = {binsPhi, "#it{#varphi}"}; + const AxisSpec axisZVtx = {binsZVtx, "#it{z}_{vtx}"}; + const AxisSpec axisAssTrkSpecie = {static_cast(NAssTracksTypes), + -0.5, static_cast(NAssTracksTypes) - 0.5, + "Particle species"}; + const AxisSpec axisTrackOrigin = {2, -0.5, 1.5, "Particle origin"}; + std::vector axesAssocTracks = {axisPtAssoc, axisEtaAssoc, axisPhiAssoc, axisZVtx, axisAssTrkSpecie, axisTrackOrigin}; + registry.add("hAssTrackReco", "Reconstructed associated tracks;;", {HistType::kTHnSparseF}, axesAssocTracks); + if (runEfficiencyValidation) { + registry.add("hAssTrackRecoPtRew", "Reconstructed associated tracks;;", {HistType::kTHnSparseF}, axesAssocTracks); + registry.get(HIST("hAssTrackRecoPtRew"))->Sumw2(); + if (loadAccXEffFromCCDB) { + registry.add("hAssTrackRecoPtEtaRew", "Reconstructed associated tracks;;", {HistType::kTHnSparseF}, axesAssocTracks); + registry.add("hAssTrackRecoPtEtaPhiRew", "Reconstructed associated tracks;;", {HistType::kTHnSparseF}, axesAssocTracks); + registry.add("hAssTrackRecoPtEtaPhiZVtxRew", "Reconstructed associated tracks;;", {HistType::kTHnSparseF}, axesAssocTracks); + registry.get(HIST("hAssTrackRecoPtEtaRew"))->Sumw2(); + registry.get(HIST("hAssTrackRecoPtEtaPhiRew"))->Sumw2(); + registry.get(HIST("hAssTrackRecoPtEtaPhiZVtxRew"))->Sumw2(); + } + } + registry.add("hAssTrackGen", "Generated associated tracks;;", {HistType::kTHnSparseF}, axesAssocTracks); + + } // end init + + /// Apply pT-differential ML BDT bkg score cut + /// \param ptTrig is the pT of the charm candidate + template + bool isSelBdtScoreCut(TCand const& cand, + double ptTrig) + { + std::array outputMl = hfcFlowHelper.getCandMlScores(cand); + for (size_t iPt = 0; iPt < binsPtCharm.value.size() - 1; iPt++) { + if (ptTrig >= binsPtCharm.value[iPt] && ptTrig < binsPtCharm.value[iPt + 1]) { + return (outputMl[0] < bdtScore0PtMaxs.value[iPt]) && (outputMl[1] > bdtScore1PtMins.value[iPt]); + } + } + return false; + } + + /// Match associated tracks based on their PDG code + /// \param assTrk is the associated track + /// \return the associated track specie index + template + bool isMcMatched(TCharmHad const& cand) + { + int flagMc{-1}, resoChannel{-1}; + if constexpr (IsReco) { + flagMc = std::abs(cand.flagMcMatchRec()); + resoChannel = std::abs(cand.flagMcDecayChanRec()); + } else { + flagMc = std::abs(cand.flagMcMatchGen()); + resoChannel = std::abs(cand.flagMcDecayChanGen()); + } + + if constexpr (CandType == TriggerChannels::D0ToPiK) { + return flagMc == static_cast(hf_decay::hf_cand_2prong::DecayChannelMain::D0ToPiK); + } else if constexpr (CandType == TriggerChannels::DplusToPiKPi) { + return flagMc == static_cast(hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKPi); + } else if constexpr (CandType == TriggerChannels::LcToPKPi) { + return flagMc == static_cast(hf_decay::hf_cand_3prong::DecayChannelMain::LcToPKPi); + } else { // Ds + int8_t reso{0}; + if constexpr (IsReco) { + reso = std::abs(cand.flagMcDecayChanRec()); + } else { + reso = std::abs(cand.flagMcDecayChanGen()); + } + return flagMc == static_cast(hf_decay::hf_cand_3prong::DecayChannelMain::DsToPiKK) && + reso == static_cast(hf_decay::hf_cand_3prong::DecayChannelResonant::DsToPhiPi); + } + } + + /// Fill histograms and tables for same-event correlations + /// \param trigCands are the trigger candidates + /// \param assTrks are the associated tracks + /// \param cent is the collision centrality + /// \param mult is the collision multiplicity + template + void fillCharmEfficiencies(TCharmCands const& charmCands, int numContrib) + { + for (const auto& cand : charmCands) { + if (!hfcFlowHelper.cutCandRapidity(cand)) { + continue; + } + + int channel = isMcMatched(cand); + if (channel < 0) { + continue; + } + + // Fill the sparse + std::array outputMl = hfcFlowHelper.getCandMlScores(cand); + if (cand.originMcRec() == RecoDecay::OriginType::Prompt) { + registry.fill(HIST("hCharmPromptReco"), cand.pt(), numContrib, cand.eta(), cand.phi(), outputMl[0], outputMl[1]); + } + if (cand.originMcRec() == RecoDecay::OriginType::NonPrompt) { + registry.fill(HIST("hCharmFdReco"), cand.pt(), numContrib, cand.eta(), cand.phi(), outputMl[0], outputMl[1]); + } + } + } + + template + double getCharmEffWeight(const TCharmCand& charmCand, bool isPrompt) + { + double eff = 1.; + double pt = charmCand.pt(); + if (loadAccXEffFromCCDB) { + + int ptBin = o2::analysis::findBin(binsPtCharm, pt); + double mlScore0Max = bdtScore0PtMaxs.value[ptBin]; + double mlScore1Min = bdtScore1PtMins.value[ptBin]; + + if (isPrompt) { + + int const sparsePtBin = mRecoPrompt->GetAxis(kAxisPtTrig)->FindBin(pt); + mRecoPrompt->GetAxis(kAxisPtTrig)->SetRange(sparsePtBin, sparsePtBin); + mRecoPrompt->GetAxis(kAxisMlScore0)->SetRangeUser(0., mlScore0Max); + mRecoPrompt->GetAxis(kAxisMlScore1)->SetRangeUser(mlScore1Min, 1.); + mGenPrompt->GetAxis(kAxisPtTrig)->SetRange(sparsePtBin, sparsePtBin); + eff = mRecoPrompt->Integral(kTRUE) / mGenPrompt->Integral(kTRUE); + + // Restore axes to full range + for (int i = 0; i < mRecoPrompt->GetNdimensions(); ++i) mRecoPrompt->GetAxis(i)->SetRange(0, 0); + for (int i = 0; i < mGenPrompt->GetNdimensions(); ++i) mGenPrompt->GetAxis(i)->SetRange(0, 0); + + } else { + + int const sparsePtBin = mRecoFD->GetAxis(kAxisPtTrig)->FindBin(pt); + mRecoFD->GetAxis(kAxisPtTrig)->SetRange(sparsePtBin, sparsePtBin); + mRecoFD->GetAxis(kAxisMlScore0)->SetRangeUser(0., mlScore0Max); + mRecoFD->GetAxis(kAxisMlScore1)->SetRangeUser(mlScore1Min, 1.); + mGenFD->GetAxis(kAxisPtTrig)->SetRange(sparsePtBin, sparsePtBin); + eff = mRecoFD->Integral(kTRUE) / mGenFD->Integral(kTRUE); + + // Restore axes to full range + for (int i = 0; i < mRecoFD->GetNdimensions(); ++i) mRecoFD->GetAxis(i)->SetRange(0, 0); + for (int i = 0; i < mGenFD->GetNdimensions(); ++i) mGenFD->GetAxis(i)->SetRange(0, 0); + + } + + } else { + int const bin = o2::analysis::findBin(binsPtEffCharm, pt); + eff = isPrompt ? effPromptCharm->at(bin) : effFdCharm->at(bin); + } + + return 1 / eff; + } + + /// Fill histograms and tables for same-event correlations + /// \param trigCands are the trigger candidates + /// \param assTrks are the associated tracks + /// \param cent is the collision centrality + /// \param mult is the collision multiplicity + template + void validateCharmEfficiencies(TCharmCands const& charmCands) + { + for (const auto& charmCand : charmCands) { + if (!hfcFlowHelper.cutCandRapidity(charmCand)) { + continue; + } + + int channel = isMcMatched(charmCand); + if (channel < 0) { + continue; + } + if (!isSelBdtScoreCut(charmCand, charmCand.pt())) { + continue; + } + + // Fill the sparse + std::array outputMl = hfcFlowHelper.getCandMlScores(charmCand); + bool isPrompt = (charmCand.originMcRec() == RecoDecay::OriginType::Prompt); + double effWeight = getCharmEffWeight(charmCand, isPrompt); + if (isPrompt) { + registry.fill(HIST("hCharmPromptRecoPtRew"), charmCand.pt(), charmCand.template collision_as().numContrib(), + charmCand.eta(), charmCand.phi(), outputMl[0], outputMl[1], effWeight); + } else { + registry.fill(HIST("hCharmFdRecoPtRew"), charmCand.pt(), charmCand.template collision_as().numContrib(), + charmCand.eta(), charmCand.phi(), outputMl[0], outputMl[1], effWeight); + } + } + } + + // Dplus efficiency + void processEffDplus(RecoCollisions const& recoCollisions, + McCandsDplus const& candsDplus, + soa::Join const& genParticles, + aod::McCollisions const&) + { + for (const auto& coll : recoCollisions) { + auto candsInColl = candsDplus.sliceBy(candsDplusPerColl, coll.globalIndex()); + if (candsInColl.size() < 1) { + continue; + } + float cent{-1.}, mult{-1.}; + if (!hfcFlowHelper.checkCollision(coll, cent, mult)) { + continue; + } + fillCharmEfficiencies(candsInColl, coll.numContrib()); + if (runEfficiencyValidation) { + validateCharmEfficiencies(candsInColl); + } + } + + for (const auto& genCand : genParticles) { + if (!genCand.has_mcCollision()) { + continue; + } + if (std::abs(genCand.y()) > yCandMax) { + continue; + } + int channel = isMcMatched(genCand); + if (channel < 0) { + continue; + } + + if (genCand.originMcGen() == RecoDecay::OriginType::Prompt) { + registry.fill(HIST("hCharmPromptGen"), genCand.pt(), genCand.eta(), genCand.phi()); + } + if (genCand.originMcGen() == RecoDecay::OriginType::NonPrompt) { + registry.fill(HIST("hCharmFdGen"), genCand.pt(), genCand.eta(), genCand.phi()); + } + } + } + PROCESS_SWITCH(HfTaskCorrelationsEfficiencies, processEffDplus, "Process efficiencies for Dplus candidates", true); + + /// Match associated tracks based on their PDG code + /// \param assTrk is the associated track + /// \return the associated track specie index + template + int getAssocTrkSpecie(TAssocTrk const& assTrk) + { + switch (std::abs(assTrk.pdgCode())) { + case kPiPlus: + return static_cast(AssTracksTypes::Pi); + case kKPlus: + return static_cast(AssTracksTypes::Ka); + case kProton: + return static_cast(AssTracksTypes::Pr); + case kElectron: + return static_cast(AssTracksTypes::El); + case kMuonMinus: + return static_cast(AssTracksTypes::Mu); + default: + return -1; + } + } + + // Associated Tracks + void processEffAssTracks(RecoCollisions const& recoCollisions, + McTracks const& recoTracks, + aod::McParticles const& genParticles, + aod::McCollisions const&) + { + for (const auto& coll : recoCollisions) { + float cent{-1.}, mult{-1.}; + if (!hfcFlowHelper.checkCollision(coll, cent, mult)) { + continue; + } + auto mcCollision = coll.template mcCollision_as(); + + auto tracksInColl = recoTracks.sliceBy(trackIndicesPerColl, coll.globalIndex()); + for (const auto& assTrk : tracksInColl) { + if (!assTrk.has_mcParticle()) { + continue; + } + auto mcParticle = assTrk.template mcParticle_as(); + int matchedSpecie = getAssocTrkSpecie(mcParticle); + if (matchedSpecie < 0) { + continue; + } + + // DCA selection + double assTrkPt = assTrk.pt(); + if (usePtDiffDcaXYCut) { + float const dcaXYTrkCut = funcDcaXYPtCutPrimTrk->Eval(assTrkPt); + if (std::fabs(assTrk.dcaXY()) > dcaXYTrkCut) { + continue; + } + } + int assTrkOrigin = mcParticle.isPhysicalPrimary() ? 0 : 1; // 0 for primary, 1 for secondary + + std::vector values = {mcParticle.pt(), mcParticle.eta(), mcParticle.phi(), mcCollision.posZ(), static_cast(matchedSpecie), static_cast(assTrkOrigin)}; + + // Fill histograms for associated tracks + registry.get(HIST("hAssTrackReco"))->Fill(values.data()); + + // Fill histograms for efficiency validation if enabled + if (runEfficiencyValidation) { + + float effWeightPt{1.f}; + if (!loadAccXEffFromCCDB) { + int const bin = o2::analysis::findBin(binsPtEffAssTrk, assTrkPt); + effWeightPt = 1. / effAssTrk->at(bin); + } else { + + float effWeightPtEta{1.f}, effWeightPtEtaPhi{1.f}, effWeightPtEtaPhiZVtx{1.f}; + + // Pt-reweighting + mRecoAssTrk->GetAxis(kAxisPtAssoc)->SetRangeUser(assTrkPt, assTrkPt); + mGenAssTrk->GetAxis(kAxisPtAssoc)->SetRangeUser(assTrkPt, assTrkPt); + effWeightPt = mRecoAssTrk->Integral(kTRUE) > 0 ? mGenAssTrk->Integral(kTRUE) / mRecoAssTrk->Integral(kTRUE) : 0; + + // Pt-eta-reweighting + mRecoAssTrk->GetAxis(kAxisEtaAssoc)->SetRangeUser(mcParticle.eta(), mcParticle.eta()); + mGenAssTrk->GetAxis(kAxisEtaAssoc)->SetRangeUser(mcParticle.eta(), mcParticle.eta()); + effWeightPtEta = mRecoAssTrk->Integral(kTRUE) > 0 ? mGenAssTrk->Integral(kTRUE) / mRecoAssTrk->Integral(kTRUE) : 0; + + // Pt-eta-phi-reweighting + mRecoAssTrk->GetAxis(kAxisPhiAssoc)->SetRangeUser(mcParticle.phi(), mcParticle.phi()); + mGenAssTrk->GetAxis(kAxisPhiAssoc)->SetRangeUser(mcParticle.phi(), mcParticle.phi()); + effWeightPtEtaPhi = mRecoAssTrk->Integral(kTRUE) > 0 ? mGenAssTrk->Integral(kTRUE) / mRecoAssTrk->Integral(kTRUE) : 0; + + // Pt-eta-phi-zvtx-reweighting + mRecoAssTrk->GetAxis(kAxisZVtx)->SetRangeUser(mcCollision.posZ(), mcCollision.posZ()); + mGenAssTrk->GetAxis(kAxisZVtx)->SetRangeUser(mcCollision.posZ(), mcCollision.posZ()); + effWeightPtEtaPhiZVtx = mRecoAssTrk->Integral(kTRUE) > 0 ? mGenAssTrk->Integral(kTRUE) / mRecoAssTrk->Integral(kTRUE) : 0; + + // Restore axes to full range + for (int i = 0; i < mRecoAssTrk->GetNdimensions(); ++i) mRecoAssTrk->GetAxis(i)->SetRange(0, 0); + for (int i = 0; i < mGenAssTrk->GetNdimensions(); ++i) mGenAssTrk->GetAxis(i)->SetRange(0, 0); + + registry.get(HIST("hAssTrackRecoPtEtaRew"))->Fill(values.data(), effWeightPtEta); + registry.get(HIST("hAssTrackRecoPtEtaPhiRew"))->Fill(values.data(), effWeightPtEtaPhi); + registry.get(HIST("hAssTrackRecoPtEtaPhiZVtxRew"))->Fill(values.data(), effWeightPtEtaPhiZVtx); + } + + registry.get(HIST("hAssTrackRecoPtRew"))->Fill(values.data(), effWeightPt); + + } + } + } + + // Fill histograms for generated associated tracks + for (const auto& genTrk : genParticles) { + int matchedSpecie = getAssocTrkSpecie(genTrk); + if (matchedSpecie < 0) { + continue; + } + + // Pt and eta selection + if (genTrk.pt() < ptTrkMin || genTrk.pt() > ptTrkMax || std::fabs(genTrk.eta()) > etaTrkMax) { + continue; + } + + int genTrkOrigin = genTrk.isPhysicalPrimary() ? 0 : 1; // 0 for primary, 1 for secondary + auto genCollision = genTrk.template mcCollision_as(); + registry.fill(HIST("hAssTrackGen"), genTrk.pt(), genTrk.eta(), genTrk.phi(), genCollision.posZ(), matchedSpecie, genTrkOrigin); + } + + } + PROCESS_SWITCH(HfTaskCorrelationsEfficiencies, processEffAssTracks, "Process efficiencies for associated tracks", true); + +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{adaptAnalysisTask(cfgc)}; +} diff --git a/PWGHF/HFC/Utils/utilsFlow.h b/PWGHF/HFC/Utils/utilsFlow.h new file mode 100644 index 00000000000..f99f2d6e3e1 --- /dev/null +++ b/PWGHF/HFC/Utils/utilsFlow.h @@ -0,0 +1,222 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file utilsFlow.h +/// \brief Utilities for HFC analyses +/// \author Marcello Di Costanzo + +#ifndef PWGHF_HFC_UTILS_FLOW_H_ +#define PWGHF_HFC_UTILS_FLOW_H_ + +#include "PWGHF/Core/CentralityEstimation.h" +#include "PWGHF/Core/DecayChannels.h" +#include "PWGHF/Core/HfHelper.h" +#include "PWGHF/Utils/utilsEvSelHf.h" + +#include "Common/Core/RecoDecay.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +namespace o2::hfc_utils_flow +{ + +enum TriggerChannels { + DplusToPiKPi = 0, + DsToKKPi, + DsToPiKK, + D0ToPiK, + D0ToKPi, + LcToPKPi, + LcToPiKP, + Hadron +}; + +enum AssTracksTypes { + Pi = 0, + Ka, + Pr, + El, + Mu, + NAssTracksTypes +}; + +class HfcFlowHelper { + + public: + + HfcFlowHelper() = default; + + void init(o2::framework::Service& ccdb, + o2::framework::HistogramRegistry& registry, + std::vector classMl, + float yCandMax) { + + LOG(info) << "Initializing HFC flow helper!"; + this->hfEvSel.addHistograms(registry); + this->ccdb = &ccdb; + this->registry = ®istry; + this->classMl = std::move(classMl); + this->yCandMax = yCandMax; + } + + /// Get charm hadron candidate mass + /// \param candidate is the charm hadron candidate + template + double getCandMass(const TCand& candidate) + { + if constexpr (CandType == TriggerChannels::DsToKKPi) { + return HfHelper::invMassDsToKKPi(candidate); + } + if constexpr (CandType == TriggerChannels::DsToPiKK) { + return HfHelper::invMassDsToPiKK(candidate); + } + if constexpr (CandType == TriggerChannels::DplusToPiKPi) { + return HfHelper::invMassDplusToPiKPi(candidate); + } + if constexpr (CandType == TriggerChannels::D0ToPiK) { + return HfHelper::invMassD0ToPiK(candidate); + } + if constexpr (CandType == TriggerChannels::D0ToKPi) { + return HfHelper::invMassD0barToKPi(candidate); + } + if constexpr (CandType == TriggerChannels::LcToPKPi) { + return HfHelper::invMassLcToPKPi(candidate); + } + if constexpr (CandType == TriggerChannels::LcToPiKP) { + return HfHelper::invMassLcToPiKP(candidate); + } + return -1.; + } + + /// Get charm hadron bdt scores + /// \param candidate is the charm hadron candidate + template + std::array getCandMlScores(const TCand& candidate) + { + std::array outputMl{-999.f, -999.f}; + if constexpr (CandType == TriggerChannels::DsToKKPi) { + for (unsigned int iclass = 0; iclass < classMl.size(); iclass++) { + outputMl[iclass] = candidate.mlProbDsToKKPi()[classMl.at(iclass)]; + } + } + if constexpr (CandType == TriggerChannels::DsToPiKK) { + for (unsigned int iclass = 0; iclass < classMl.size(); iclass++) { + outputMl[iclass] = candidate.mlProbDsToPiKK()[classMl.at(iclass)]; + } + } + if constexpr (CandType == TriggerChannels::DplusToPiKPi) { + for (unsigned int iclass = 0; iclass < classMl.size(); iclass++) { + outputMl[iclass] = candidate.mlProbDplusToPiKPi()[classMl.at(iclass)]; + } + } + if constexpr (CandType == TriggerChannels::D0ToPiK) { + for (unsigned int iclass = 0; iclass < classMl.size(); iclass++) { + outputMl[iclass] = candidate.mlProbD0()[classMl.at(iclass)]; + } + } + if constexpr (CandType == TriggerChannels::D0ToKPi) { + for (unsigned int iclass = 0; iclass < classMl.size(); iclass++) { + outputMl[iclass] = candidate.mlProbD0bar()[classMl.at(iclass)]; + } + } + if constexpr (CandType == TriggerChannels::LcToPKPi) { + for (unsigned int iclass = 0; iclass < classMl.size(); iclass++) { + outputMl[iclass] = candidate.mlProbLcToPKPi()[classMl.at(iclass)]; + } + } + if constexpr (CandType == TriggerChannels::LcToPiKP) { + for (unsigned int iclass = 0; iclass < classMl.size(); iclass++) { + outputMl[iclass] = candidate.mlProbLcToPiKP()[classMl.at(iclass)]; + } + } + return outputMl; + } + + /// Cut on rapidity of the candidate + /// \param candidate is the charm hadron candidate + template + bool cutCandRapidity(const TCand& candidate) + { + double y = 0.0; + if constexpr (CandType == TriggerChannels::DsToKKPi || CandType == TriggerChannels::DsToPiKK) { + y = HfHelper::yDs(candidate); + } else if constexpr (CandType == TriggerChannels::DplusToPiKPi) { + y = HfHelper::yDplus(candidate); + } else if constexpr (CandType == TriggerChannels::D0ToPiK || CandType == TriggerChannels::D0ToKPi) { + y = HfHelper::yD0(candidate); + } else if constexpr (CandType == TriggerChannels::LcToPKPi || CandType == TriggerChannels::LcToPiKP) { + y = HfHelper::yLc(candidate); + } else { + return true; + } + return std::fabs(y) < yCandMax; + } + + /// Check event selections for collision and fill the collision table + /// \param collision is the collision + template + bool checkCollision(Coll const& collision, float& cent, float& mult) + { + o2::hf_evsel::HfCollisionRejectionMask collRejMask{}; + if constexpr (CentEst == o2::hf_centrality::CentralityEstimator::FT0A) { + collRejMask = hfEvSel.getHfCollisionRejectionMask(collision, cent, *ccdb, *registry); + mult = collision.multFT0A(); + } else if constexpr (CentEst == o2::hf_centrality::CentralityEstimator::FT0C) { + collRejMask = hfEvSel.getHfCollisionRejectionMask(collision, cent, *ccdb, *registry); + mult = collision.multFT0C(); + } else if constexpr (CentEst == o2::hf_centrality::CentralityEstimator::FT0M) { + collRejMask = hfEvSel.getHfCollisionRejectionMask(collision, cent, *ccdb, *registry); + mult = collision.multFT0M(); + } else if constexpr (CentEst == o2::hf_centrality::CentralityEstimator::FV0A) { + collRejMask = hfEvSel.getHfCollisionRejectionMask(collision, cent, *ccdb, *registry); + mult = collision.multFV0A(); + } else if constexpr (CentEst == o2::hf_centrality::CentralityEstimator::None) { + collRejMask = hfEvSel.getHfCollisionRejectionMask(collision, cent, *ccdb, *registry); + mult = -1.f; + } else { + LOG(fatal) << "Centrality estimator not recognized for collision selection"; + std::abort(); + } + hfEvSel.fillHistograms(collision, collRejMask, cent); + return collRejMask == 0; + } + + private: + o2::hf_evsel::HfEventSelection hfEvSel; + o2::framework::Service* ccdb{nullptr}; + o2::framework::HistogramRegistry* registry{nullptr}; + std::vector classMl{}; + float yCandMax{-999.f}; +}; + + +} // namespace o2::analysis::hfc_utils_flow +#endif // PWGHF_HFC_UTILS_FLOW_H_ From a76474d22e90a98ac81fecc7308d2bf1ef8aed71 Mon Sep 17 00:00:00 2001 From: Marcello Di Costanzo Date: Thu, 5 Nov 2026 11:02:36 +0100 Subject: [PATCH 02/18] Implementation of MC closure and efficiency reweighting --- .../correlatorFlowCharmHadronsReduced.cxx | 592 ++++++++++-------- .../derivedDataCreatorCorrelationsReduced.cxx | 470 +++++++++----- .../Tasks/taskCorrelationsEfficiencies.cxx | 353 +++-------- 3 files changed, 729 insertions(+), 686 deletions(-) diff --git a/PWGHF/HFC/TableProducer/correlatorFlowCharmHadronsReduced.cxx b/PWGHF/HFC/TableProducer/correlatorFlowCharmHadronsReduced.cxx index c5416a60e82..e06fc024adf 100644 --- a/PWGHF/HFC/TableProducer/correlatorFlowCharmHadronsReduced.cxx +++ b/PWGHF/HFC/TableProducer/correlatorFlowCharmHadronsReduced.cxx @@ -17,6 +17,7 @@ #include "Common/Core/RecoDecay.h" +#include #include #include #include @@ -33,6 +34,13 @@ #include #include +#include +#include +#include +#include +#include + +#include #include #include #include @@ -82,15 +90,15 @@ double getPhi(const TTrack& track) } } +enum HistoEffType { + kTH1 = 0, + kTH2, + kTH3, + kTHnSparse +}; + struct HfCorrelatorFlowCharmHadronsReduced { - // Produces rowPairSECharmHads; //! Correlation pairs information Same Event - // Produces rowPairMECharmHads; //! Correlation pairs information Mixed Event - // Produces rowPairSEHadHads; //! Correlation pairs information Same Event - // Produces rowPairMEHadHads; //! Correlation pairs information Mixed Event - // Produces rowCollInfos; //! Collision info - - Configurable fillSparses{"fillSparses", true, "Fill sparse histograms"}; - Configurable fillTables{"fillTables", false, "Fill tables"}; + Configurable numberEventsMixed{"numberEventsMixed", 5, "Number of events mixed in ME process"}; Configurable> bdtScore0PtMaxs{"bdtScore0PtMaxs", std::vector{0.1, 0.1, 0.1, 0.1, 0.1}, "pT-differential maximum score 0 for charm candidates"}; Configurable> bdtScore1PtMins{"bdtScore1PtMins", std::vector{0.1, 0.1, 0.1, 0.1, 0.1}, "pT-differential minimum score 1 for charm candidates"}; @@ -110,10 +118,26 @@ struct HfCorrelatorFlowCharmHadronsReduced { Configurable ptMaxForDownSample{"ptMaxForDownSample", 10., "Maximum pt for the application of the downsampling factor"}; Configurable centMultMaxForDownSample{"centMultMaxForDownSample", 10., "Maximum centrality for the application of the downsampling factor"}; + // Efficiency correction + Configurable doEfficiencyCorrection{"doEfficiencyCorrection", false, "Flag for applying efficiency corrections"}; + Configurable effHistTypeCharm{"effHistTypeCharm", 0, "Histogram type for charm efficiency (0=TH1, 1=TH2, 2=TH3, 3=THnSparse)"}; + Configurable effHistTypeAssoc{"effHistTypeAssoc", 0, "Histogram type for associated efficiency (0=TH1, 1=TH2, 2=TH3, 3=THnSparse)"}; + Configurable ccdbUrl{"ccdbUrl", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable assocEffCcdbPath{"assocEffCcdbPath", "", "CCDB path for associated efficiency"}; + Configurable promptEffCcdbPath{"promptEffCcdbPath", "", "CCDB path for trigger efficiency"}; + Configurable timestampCcdb{"timestampCcdb", -1, "timestamp of the efficiency files used to query in CCDB"}; + Configurable ccdbNoLaterThan{"ccdbNoLaterThan", std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(), "latest acceptable timestamp of creation for the object"}; + SliceCache cache; + Service ccdb{}; + std::shared_ptr hEffPrompt = nullptr; + std::shared_ptr hEffAssoc = nullptr; + int poolBins{0}; + std::vector mPtEdgesTrig; + using SameEvtPairsChHadWEffInfo = soa::Filtered>; using SameEvtPairsChHad = soa::Filtered>; using SameEvtPairsHadHad = soa::Filtered>; using AssocTracks = soa::Filtered>; @@ -142,6 +166,33 @@ struct HfCorrelatorFlowCharmHadronsReduced { HistogramRegistry registry{"registry", {}, OutputObjHandlingPolicy::AnalysisObject}; + std::shared_ptr loadEfficiencyHistogram(const std::string& path, int histoType) { + TObject* object = nullptr; + + switch (histoType) { + case kTH1: + object = ccdb->getForTimeStamp(path, timestampCcdb); + break; + case kTH2: + object = ccdb->getForTimeStamp(path, timestampCcdb); + break; + case kTH3: + object = ccdb->getForTimeStamp(path, timestampCcdb); + break; + case kTHnSparse: + object = ccdb->getForTimeStamp(path, timestampCcdb); + break; + default: + LOGF(fatal, "Invalid efficiency histogram type: %d", histoType); + } + + if (!object) { + LOGF(fatal, "Could not load efficiency histogram from %s", path.c_str()); + } + + return std::shared_ptr(object); + } + void init(InitContext&) { if (selCentrality && selMultiplicity) { @@ -152,31 +203,30 @@ struct HfCorrelatorFlowCharmHadronsReduced { } // Fatal if selCentrality and process functions using multiplicity mixing, or selMultiplicity and process functions using centrality mixing - if (selCentrality && (doprocessSameEventCharmHadWMultMix || doprocessMixedEventCharmHadWMultMix || doprocessSameEventHadHadWMultMix || doprocessMixedEventHadHadWMultMix)) { + if (selCentrality && (doprocessSECharmHadWMultMix || doprocessMECharmHadWMultMix || doprocessSEHadHadWMultMix || doprocessMEHadHadWMultMix)) { LOGP(fatal, "You cannot select events based on centrality and process functions using multiplicity mixing! Please check your configuration!"); } - if (selMultiplicity && (doprocessSameEventCharmHadWCentMix || doprocessMixedEventCharmHadWCentMix || doprocessSameEventHadHadWCentMix || doprocessMixedEventHadHadWCentMix)) { + if (selMultiplicity && (doprocessSECharmHadWCentMix || doprocessMECharmHadWCentMix || doprocessSEHadHadWCentMix || doprocessMEHadHadWCentMix)) { LOGP(fatal, "You cannot select events based on multiplicity and process functions using centrality mixing! Please check your configuration!"); } - if ((doprocessSameEventCharmHadWCentMix && doprocessMixedEventCharmHadWMultMix) || - (doprocessSameEventCharmHadWMultMix && doprocessMixedEventCharmHadWCentMix) || - (doprocessSameEventHadHadWCentMix && doprocessMixedEventHadHadWMultMix) || - (doprocessSameEventHadHadWMultMix && doprocessMixedEventHadHadWCentMix)) { + if ((doprocessSECharmHadWCentMix && doprocessMECharmHadWMultMix) || + (doprocessSECharmHadWMultMix && doprocessMECharmHadWCentMix) || + (doprocessSEHadHadWCentMix && doprocessMEHadHadWMultMix) || + (doprocessSEHadHadWMultMix && doprocessMEHadHadWCentMix)) { LOGP(fatal, "You cannot mix centrality and multiplicity mixing in the same processing! Please check your configuration!"); } - if (!fillSparses && !fillTables) { - LOGP(fatal, "At least one of fillSparses or fillTables must be true!"); - } - if (((binsPtTrig.value.size() - 1) != (bdtScore0PtMaxs.value.size() + 1) || - (binsPtTrig.value.size() - 1) != (bdtScore1PtMins.value.size() + 1))) { - LOG(info) << "binsPtTrig.value.size(): " << binsPtTrig.value.size(); + + mPtEdgesTrig.assign(binsPtTrig.value.begin() + 1, binsPtTrig.value.end()); + if ((mPtEdgesTrig.size() != (bdtScore0PtMaxs.value.size() + 1) || + mPtEdgesTrig.size() != (bdtScore1PtMins.value.size() + 1))) { + LOG(info) << "mPtEdgesTrig.size(): " << mPtEdgesTrig.size(); LOG(info) << "bdtScore0PtMaxs.value.size(): " << bdtScore0PtMaxs.value.size(); LOG(info) << "bdtScore1PtMins.value.size(): " << bdtScore1PtMins.value.size(); LOGP(fatal, "The size of bdtScore0PtMaxs and bdtScore1PtMins must be the one of binsPtTrig minus one!"); } - if (doprocessSameEventCharmHadWCentMix || doprocessSameEventHadHadWCentMix || doprocessMixedEventCharmHadWCentMix || doprocessMixedEventHadHadWCentMix || doprocessSameEventCharmHadWCentMixBase || doprocessMixedEventCharmHadWCentMixBase) { + if (doprocessSECharmHadWCentMix || doprocessSEHadHadWCentMix || doprocessMECharmHadWCentMix || doprocessMEHadHadWCentMix) { poolBins = (binsCentPool->size() - 2) * (binsZPool->size() - 2); } else { poolBins = (binsMultPool->size() - 2) * (binsZPool->size() - 2); @@ -195,13 +245,13 @@ struct HfCorrelatorFlowCharmHadronsReduced { const AxisSpec axisMlTwo{binsMlTwo, "bdtScore1"}; // Histograms for data analysis - if (doprocessSameEventCharmHadWCentMix || doprocessSameEventHadHadWCentMix) { + if (doprocessSECharmHadWCentMix || doprocessSEHadHadWCentMix) { registry.add("hCentPoolBinSE", "Centrality SE", {HistType::kTH2F, {{axisCent}, {axisPoolBin}}}); - } else if (doprocessSameEventCharmHadWMultMix || doprocessSameEventHadHadWMultMix) { + } else if (doprocessSECharmHadWMultMix || doprocessSEHadHadWMultMix) { registry.add("hMultFT0MPoolBinSE", "Multiplicity FT0M SE", {HistType::kTH2F, {{axisMultFT0M}, {axisPoolBin}}}); - } else if (doprocessMixedEventCharmHadWCentMix || doprocessMixedEventHadHadWCentMix) { + } else if (doprocessMECharmHadWCentMix || doprocessMEHadHadWCentMix) { registry.add("hCentPoolBinME", "Centrality ME", {HistType::kTH2F, {{axisCent}, {axisPoolBin}}}); - } else if (doprocessMixedEventCharmHadWMultMix || doprocessMixedEventHadHadWMultMix) { + } else if (doprocessMECharmHadWMultMix || doprocessMEHadHadWMultMix) { registry.add("hMultFT0MPoolBinME", "Multiplicity FT0M ME", {HistType::kTH2F, {{axisMultFT0M}, {axisPoolBin}}}); } registry.add("hZVtxPoolBinSE", "z vertex SE", {HistType::kTH2F, {{axisPosZ}, {axisPoolBin}}}); @@ -212,28 +262,122 @@ struct HfCorrelatorFlowCharmHadronsReduced { registry.add("hPoolBinTrigME", "Trigger candidates pool bin ME", {HistType::kTH1F, {axisPoolBin}}); registry.add("hPoolBinAssocSE", "Associated particles pool bin SE", {HistType::kTH1F, {axisPoolBin}}); registry.add("hPoolBinAssocME", "Associated particles pool bin ME", {HistType::kTH1F, {axisPoolBin}}); - if (fillSparses) { - std::vector axesTrigger = {axisInvMass, axisPtTrig, axisMlOne, axisMlTwo}; - std::vector axes = {axisPoolBin, axisPtTrig, axisPtAssoc, axisDeltaEta, axisDeltaPhi}; - if (doprocessSameEventHadHadWCentMix || doprocessSameEventHadHadWMultMix) { - registry.add("hSparseCorrelationsSEHadHad", "THn for SE Had-Had correlations", HistType::kTHnSparseF, axes); - } else if (doprocessMixedEventHadHadWCentMix || doprocessMixedEventHadHadWMultMix) { - registry.add("hSparseCorrelationsMEHadHad", "THn for ME Had-Had correlations", HistType::kTHnSparseF, axes); - } else { - // axes.insert(axes.end(), {axisInvMass}); - axes.insert(axes.end(), {axisInvMass, axisMlOne, axisMlTwo}); - if (doprocessSameEventCharmHadWCentMix || doprocessSameEventCharmHadWMultMix || doprocessSameEventCharmHadWCentMixBase) { - registry.add("hSparseCorrelationsSECharmHad", "THn for SE Charm-Had correlations", HistType::kTHnSparseF, axes); - } else if (doprocessMixedEventCharmHadWCentMix || doprocessMixedEventCharmHadWMultMix || doprocessMixedEventCharmHadWCentMixBase) { - registry.add("hSparseCorrelationsMECharmHad", "THn for ME Charm-Had correlations", HistType::kTHnSparseF, axes); + + std::vector axesTrigger = {axisInvMass, axisPtTrig, axisMlOne, axisMlTwo}; + std::vector axes = {axisPoolBin, axisPtTrig, axisPtAssoc, axisDeltaEta, axisDeltaPhi}; + if (doprocessSEHadHadWCentMix || doprocessSEHadHadWMultMix) { + registry.add("hSparseCorrelationsSEHadHad", "THn for SE Had-Had correlations", HistType::kTHnSparseF, axes); + if (doEfficiencyCorrection) { + registry.get(HIST("hSparseCorrelationsSEHadHad"))->Sumw2(); + } + } else if (doprocessMEHadHadWCentMix || doprocessMEHadHadWMultMix) { + registry.add("hSparseCorrelationsMEHadHad", "THn for ME Had-Had correlations", HistType::kTHnSparseF, axes); + if (doEfficiencyCorrection) { + registry.get(HIST("hSparseCorrelationsMEHadHad"))->Sumw2(); + } + } else { + axes.insert(axes.end(), {axisInvMass, axisMlOne, axisMlTwo}); + if (doprocessSECharmHadWCentMix || doprocessSECharmHadWMultMix) { + registry.add("hSparseCorrelationsSECharmHad", "THn for SE Charm-Had correlations", HistType::kTHnSparseF, axes); + if (doEfficiencyCorrection) { + registry.get(HIST("hSparseCorrelationsSECharmHad"))->Sumw2(); + } + } else if (doprocessMECharmHadWCentMix || doprocessMECharmHadWMultMix) { + registry.add("hSparseCorrelationsMECharmHad", "THn for ME Charm-Had correlations", HistType::kTHnSparseF, axes); + if (doEfficiencyCorrection) { + registry.get(HIST("hSparseCorrelationsMECharmHad"))->Sumw2(); + } + } + if (doprocessCharmTriggers) { + registry.add("hSparseTrigCandsCharm", "THn for Charm trigger candidates", HistType::kTHnSparseF, axesTrigger); + if (doEfficiencyCorrection) { + registry.get(HIST("hSparseTrigCandsCharm"))->Sumw2(); + } + } + } + } + + template + double getEfficiency(TObject* hist, int histoType, const TCand& cand) //, const std::vector& values) + { + if (!hist) { + LOG(debug) << "Candidate does not have required efficiency histogram."; + return 0.; + } + + std::vector kineFeatures{}; + + // Charm triggers + if constexpr (IsCharm) { + kineFeatures = {cand.ptTrig(), cand.bdtScore0Trig(), cand.bdtScore1Trig(), cand.etaTrig(), cand.phiTrig()}; + } else { + auto collision = cand.template hfcRedCorrColl_as(); + kineFeatures = {cand.ptAssoc(), cand.etaAssoc(), cand.phiAssoc(), collision.posZ()}; + } + + // // Charm triggers + // {ptTrig, trigCand.bdtScore0Trig(), trigCand.bdtScore1Trig(), trigCand.etaTrig(), trigCand.phiTrig()} + // {ptTrig, trigCand.bdtScore0Trig(), trigCand.bdtScore1Trig(), getEta(trigCand), getPhi(trigCand)} + // {trigCand.ptTrig(), trigCand.bdtScore0Trig(), trigCand.bdtScore1Trig(), trigCand.etaTrig(), trigCand.phiTrig()} + // // Had triggers + // {ptTrig, trigCand.etaTrig(), trigCand.phiTrig(), collision.posZ()} + // {ptTrig, getEta(trigCand), getPhi(trigCand), trigColl.posZ()} + // // Had associated tracks + // {pair.ptAssoc(), pair.etaAssoc(), pair.phiAssoc(), collision.posZ()} + // {getPt(assocTrack), getEta(assocTrack), getPhi(assocTrack), assocColl.posZ()} + + switch (histoType) { + + case kTH1: { + auto* h = dynamic_cast(hist); + if (!h || kineFeatures.size() < 1) { + return 0.; } - if (doprocessCharmTriggers) { - registry.add("hSparseTrigCandsCharm", "THn for Charm trigger candidates", HistType::kTHnSparseF, axesTrigger); + return h->GetBinContent(h->FindBin(kineFeatures[0])); + } + + case kTH2: { + auto* h = dynamic_cast(hist); + if (!h || kineFeatures.size() < 2) { + return 0.; } + return h->GetBinContent(h->FindBin(kineFeatures[0], kineFeatures[1])); } + + case kTH3: { + auto* h = dynamic_cast(hist); + if (!h || kineFeatures.size() < 3) { + return 0.; + } + return h->GetBinContent( + h->FindBin(kineFeatures[0], kineFeatures[1], kineFeatures[2])); + } + + case kTHnSparse: { + auto* h = dynamic_cast(hist); + if (!h || kineFeatures.size() < static_cast(h->GetNdimensions())) { + return 0.; + } + + std::vector bins(h->GetNdimensions()); + + for (int i = 0; i < h->GetNdimensions(); ++i) { + bins[i] = h->GetAxis(i)->FindBin(kineFeatures[i]); + } + + return h->GetBinContent(bins.data()); + } + + default: + return 0.; } } + bool isValidEfficiency(double efficiency) + { + return std::isfinite(efficiency) && efficiency > 0.; + } + template bool isSelCollision(const TColl& collision) { @@ -281,8 +425,8 @@ struct HfCorrelatorFlowCharmHadronsReduced { bool isSelBdtScoreCut(TCand const& cand, double ptTrig) { - for (size_t iPt = 0; iPt < binsPtTrig.value.size() - 1; iPt++) { - if (ptTrig >= binsPtTrig.value[iPt] && ptTrig < binsPtTrig.value[iPt + 1]) { + for (size_t iPt = 0; iPt < mPtEdgesTrig.size() - 1; iPt++) { + if (ptTrig >= mPtEdgesTrig[iPt] && ptTrig < mPtEdgesTrig[iPt + 1]) { return (cand.bdtScore0Trig() < bdtScore0PtMaxs.value[iPt]) && (cand.bdtScore1Trig() > bdtScore1PtMins.value[iPt]); } } @@ -294,7 +438,7 @@ struct HfCorrelatorFlowCharmHadronsReduced { /// \param trigCands are the selected trigger candidates /// \param assocTracks are the selected associated tracks /// \param binPolicy is the binning policy for the correlation - template + template void fillSameEvent(TPair const& pair, TTrigCand const& trigCand, const TBinningType& binPolicy) @@ -322,25 +466,53 @@ struct HfCorrelatorFlowCharmHadronsReduced { int const poolBin = getPoolBin(collision, binPolicy); registry.fill(HIST("hPoolBinTrigSE"), poolBin); registry.fill(HIST("hPoolBinAssocSE"), poolBin); - // if constexpr (FillTables) { - // if constexpr (requires { trigCand.bdtScore0Trig(); }) { // Separate Charm-Had and Had-Had cases - // rowPairSECharmHads(poolBin, ptTrig, pair.ptAssoc(), pair.deltaEta(), pair.deltaPhi(), - // trigCand.invMassTrig(), trigCand.bdtScore0Trig(), trigCand.bdtScore1Trig(), - // pair.nTpcCrossedRowsAssoc(), pair.itsClsMapAssoc(), pair.itsNClsAssoc(), pair.dcaXYAssoc(), pair.dcaZAssoc()); - // } else { - // rowPairSEHadHads(poolBin, ptTrig, pair.ptAssoc(), pair.deltaEta(), pair.deltaPhi(), - // trigCand.nTpcCrossedRowsTrig(), trigCand.itsClsMapTrig(), trigCand.itsNClsTrig(), trigCand.dcaXYTrig(), trigCand.dcaZTrig(), - // pair.nTpcCrossedRowsAssoc(), pair.itsClsMapAssoc(), pair.itsNClsAssoc(), pair.dcaXYAssoc(), pair.dcaZAssoc()); - // } - // rowCollInfos(collision.multiplicity(), collision.numPvContrib(), collision.centrality()); - // } - if constexpr (FillSparses) { - if constexpr (requires { trigCand.bdtScore0Trig(); }) { // Separate Charm-Had and Had-Had cases - registry.fill(HIST("hSparseCorrelationsSECharmHad"), poolBin, ptTrig, pair.ptAssoc(), pair.deltaEta(), - pair.deltaPhi(), trigCand.invMassTrig(), trigCand.bdtScore0Trig(), trigCand.bdtScore1Trig()); - } else { - registry.fill(HIST("hSparseCorrelationsSEHadHad"), poolBin, ptTrig, pair.ptAssoc(), pair.deltaEta(), pair.deltaPhi()); + + double effAssoc{1.f}; + if constexpr (CorrectEff) { + if (doEfficiencyCorrection) { + effAssoc = getEfficiency(hEffAssoc.get(), effHistTypeAssoc.value, pair); + if (!isValidEfficiency(effAssoc)) { + LOGF(warn, "Invalid efficiency value for associated track: effAssoc = %f", effAssoc); + return; + } + } + } + + if constexpr (requires { trigCand.bdtScore0Trig(); }) { // Separate Charm-Had and Had-Had cases + + double effTrig{1.f}; + if constexpr (CorrectEff) { + if (doEfficiencyCorrection) { + effTrig = getEfficiency(hEffPrompt.get(), effHistTypeCharm.value, trigCand); + if (!isValidEfficiency(effTrig)) { + LOGF(warn, "Invalid efficiency value for trigger candidate: effTrig = %f", effTrig); + return; + } + } + } + + double weight = doEfficiencyCorrection ? 1 / (effTrig * effAssoc) : 1.f; + + std::vector values = {static_cast(poolBin), ptTrig, pair.ptAssoc(), pair.deltaEta(), pair.deltaPhi(), trigCand.invMassTrig(), trigCand.bdtScore0Trig(), trigCand.bdtScore1Trig()}; + + registry.get(HIST("hSparseCorrelationsSECharmHad"))->Fill(values.data(), weight); + } else { + + double effTrig{1.f}; + if constexpr (CorrectEff) { + if (doEfficiencyCorrection) { + effTrig = getEfficiency(hEffAssoc.get(), effHistTypeAssoc.value, trigCand); + if (!isValidEfficiency(effTrig)) { + LOGF(warn, "Invalid efficiency value for trigger candidate: effTrig = %f", effTrig); + return; + } + } } + + double weight = doEfficiencyCorrection ? 1 / (effTrig * effAssoc) : 1.f; + + std::vector valuesHadHad = {static_cast(poolBin), ptTrig, pair.ptAssoc(), pair.deltaEta(), pair.deltaPhi()}; + registry.get(HIST("hSparseCorrelationsSEHadHad"))->Fill(valuesHadHad.data(), weight); } } @@ -348,7 +520,7 @@ struct HfCorrelatorFlowCharmHadronsReduced { /// \param collisions are the selected collisions /// \param pairs are the mixed event pairs of trigger candidates and associated tracks /// \param binPolicy is the binning policy for the correlation - template + template void fillMixedEvent(TPairs const& pairs, const TBinningType& binPolicy) { @@ -396,248 +568,152 @@ struct HfCorrelatorFlowCharmHadronsReduced { } } double const deltaPhi = RecoDecay::constrainAngle(getPhi(assocTrack) - getPhi(trigCand), -o2::constants::math::PIHalf); - // if constexpr (FillTables) { - // if constexpr (requires { trigCand.bdtScore0Trig(); }) { // Separate Charm-Had and Had-Had cases - // rowPairMECharmHads(poolBinTrig, ptTrig, ptAssoc, deltaEta, deltaPhi, - // trigCand.invMassTrig(), trigCand.bdtScore0Trig(), trigCand.bdtScore1Trig(), - // assocTrack.nTpcCrossedRowsAssoc(), assocTrack.itsClsMapAssoc(), assocTrack.itsNClsAssoc(), assocTrack.dcaXYAssoc(), assocTrack.dcaZAssoc()); - // } else { - // rowPairMEHadHads(poolBinTrig, ptTrig, ptAssoc, deltaEta, deltaPhi, - // trigCand.nTpcCrossedRowsAssoc(), trigCand.itsClsMapAssoc(), trigCand.itsNClsAssoc(), trigCand.dcaXYAssoc(), trigCand.dcaZAssoc(), - // assocTrack.nTpcCrossedRowsAssoc(), assocTrack.itsClsMapAssoc(), assocTrack.itsNClsAssoc(), assocTrack.dcaXYAssoc(), assocTrack.dcaZAssoc()); - // } - // rowCollInfos(trigColl.multiplicity(), trigColl.numPvContrib(), trigColl.centrality()); - // } - if constexpr (FillSparses) { - if constexpr (requires { trigCand.bdtScore0Trig(); }) { // Separate Charm-Had and Had-Had cases - registry.fill(HIST("hSparseCorrelationsMECharmHad"), poolBinTrig, ptTrig, ptAssoc, deltaEta, - deltaPhi, trigCand.invMassTrig(), trigCand.bdtScore0Trig(), trigCand.bdtScore1Trig()); - } else { - registry.fill(HIST("hSparseCorrelationsMEHadHad"), poolBinTrig, ptTrig, ptAssoc, deltaEta, deltaPhi); - } - } - } - } - } - /// Correlations for Same Event pairs - /// \param poolBin collision pool bin based on multiplicity and z-vertex position - /// \param trigCandsThisColl are the selected trigger candidates in the collision - /// \param assocTracksThisColl are the selected associated tracks in the collision - template - void doCorrelationsSameEvent(int poolBin, - const TTrigCand& trigCandsThisColl, - const TTrackAssoc& assocTracksThisColl) - { - for (const auto& trigCand : trigCandsThisColl) { - double const ptTrig = trigCand.ptTrig(); - if constexpr (requires { trigCand.bdtScore0Trig(); }) { // ML selection on bkg score for Charm-Had case - if (!isSelBdtScoreCut(trigCand, ptTrig)) { - continue; - } - } - - for (const auto& assTrk : assocTracksThisColl) { - // TODO: Remove Ds daughters - /*if (assTrk.originTrackId() == candidate.prong0Id() || - assTrk.originTrackId() == candidate.prong1Id() || - assTrk.originTrackId() == candidate.prong2Id()) { - continue; - }*/ - // TODO: DCA cut - double deltaPhi = RecoDecay::constrainAngle(assTrk.phiAssoc() - trigCand.phiTrig(), -o2::constants::math::PIHalf); - double deltaEta = assTrk.etaAssoc() - trigCand.etaTrig(); - if constexpr (FillSparses) { - if constexpr (requires { trigCand.bdtScore0Trig(); }) { // Separate Charm-Had and Had-Had cases - registry.fill(HIST("hSparseCorrelationsSECharmHad"), poolBin, ptTrig, assTrk.ptAssoc(), deltaEta, - deltaPhi, trigCand.invMassTrig()); - } else { - registry.fill(HIST("hSparseCorrelationsSEHadHad"), poolBin, ptTrig, assTrk.ptAssoc(), deltaEta, deltaPhi); + double effAssoc{1.f}; + if (doEfficiencyCorrection) { + effAssoc = getEfficiency(hEffAssoc.get(), effHistTypeAssoc.value, assocTrack); + if (!isValidEfficiency(effAssoc)) { + LOGF(warn, "Invalid efficiency value for associated track: effAssoc = %f", effAssoc); + continue; } } - } - } - } - /// Correlations for Mixed Event pairs - /// \param collisions are the selected collisions - /// \param trigCands are the trigger candidates - /// \param assocTracks are the associated tracks - /// \param binPolicy is the binning policy for the correlation - template - void doCorrelationsMixedEvent(const TCollision& collisions, - const TTrigCand& trigCands, - const TTrackAssoc& assocTracks, - const TBinningType& binPolicy) - { - auto tracksTuple = std::make_tuple(trigCands, assocTracks); + if constexpr (requires { trigCand.bdtScore0Trig(); }) { // Separate Charm-Had and Had-Had cases - Pair pairData{binPolicy, numberEventsMixed, -1, collisions, tracksTuple, &cache}; + double effTrig{1.f}; + if (doEfficiencyCorrection) { + effTrig = getEfficiency(hEffPrompt.get(), effHistTypeCharm.value, trigCand); + if (!isValidEfficiency(effTrig)) { + LOGF(warn, "Invalid efficiency value for trigger candidate: effTrig = %f", effTrig); + continue; + } + } - for (const auto& [c1, tracks1, c2, tracks2] : pairData) { - if (!isSelCollision(c1) || !isSelCollision(c2)) { - continue; - } - if (tracks1.size() == 0) { - continue; - } + double weight = doEfficiencyCorrection ? 1 / (effTrig * effAssoc) : 1.f; - int poolBin = binPolicy.getBin({c2.posZ(), selCentrality ? c2.centrality() : c2.multiplicity()}); - int poolBinTrigCand = binPolicy.getBin({c1.posZ(), selCentrality ? c1.centrality() : c1.multiplicity()}); + std::vector values = {static_cast(poolBinTrig), ptTrig, ptAssoc, deltaEta, deltaPhi, trigCand.invMassTrig(), trigCand.bdtScore0Trig(), trigCand.bdtScore1Trig()}; + registry.get(HIST("hSparseCorrelationsMECharmHad"))->Fill(values.data(), weight); + } else { - if (poolBin != poolBinTrigCand) { - LOGF(info, "Error, poolBins are different"); - continue; - } + double effTrig{1.f}; + if (doEfficiencyCorrection) { + effTrig = getEfficiency(hEffAssoc.get(), effHistTypeAssoc.value, trigCand); + if (!isValidEfficiency(effTrig)) { + LOGF(warn, "Invalid efficiency value for trigger candidate: effTrig = %f", effTrig); + continue; + } + } - for (const auto& [trigCand, assTrk] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(tracks1, tracks2))) { - if (!isSelBdtScoreCut(trigCand, trigCand.ptTrig())) { - continue; - } + double weight = doEfficiencyCorrection ? 1 / (effTrig * effAssoc) : 1.f; - double deltaPhi = RecoDecay::constrainAngle(assTrk.phiAssoc() - trigCand.phiTrig(), -o2::constants::math::PIHalf); - double deltaEta = assTrk.etaAssoc() - trigCand.etaTrig(); - if constexpr (FillSparses) { - if constexpr (requires { trigCand.bdtScore0Trig(); }) { // Separate Charm-Had and Had-Had cases - registry.fill(HIST("hSparseCorrelationsMECharmHad"), poolBin, trigCand.ptTrig(), assTrk.ptAssoc(), deltaEta, - deltaPhi, trigCand.invMassTrig()); - } else { - registry.fill(HIST("hSparseCorrelationsMEHadHad"), poolBin, trigCand.ptTrig(), assTrk.ptAssoc(), deltaEta, deltaPhi); - } + std::vector valuesHadHad = {static_cast(poolBinTrig), ptTrig, ptAssoc, deltaEta, deltaPhi}; + registry.get(HIST("hSparseCorrelationsMEHadHad"))->Fill(valuesHadHad.data(), weight); } } } } - void processSameEventCharmHadWMultMix(SameEvtPairsChHad::iterator const& pair, + void processSECharmHadWMultMix(SameEvtPairsChHad::iterator const& pair, aod::HfcRedTrigCharms const&, aod::HfcRedCorrColls const&) { BinningMultPosZ binPolicyPosZMult{{binsZPool, binsMultPool}}; auto trigCand = pair.template hfcRedTrigCharm_as(); - if (fillSparses && fillTables) { - fillSameEvent(pair, trigCand, binPolicyPosZMult); - } else if (fillSparses) { - fillSameEvent(pair, trigCand, binPolicyPosZMult); - } else if (fillTables) { - fillSameEvent(pair, trigCand, binPolicyPosZMult); - } + fillSameEvent(pair, trigCand, binPolicyPosZMult); + } + PROCESS_SWITCH(HfCorrelatorFlowCharmHadronsReduced, processSECharmHadWMultMix, "Process Same Event for Charm-Had with multiplicity pools", false); + + void processSECharmHadWMultMixWEffInfo(SameEvtPairsChHadWEffInfo::iterator const& pair, + TrigCharmCands const&, + aod::HfcRedCorrColls const&) + { + BinningMultPosZ binPolicyPosZMult{{binsZPool, binsMultPool}}; + auto trigCand = pair.template hfcRedTrigCharm_as(); + fillSameEvent(pair, trigCand, binPolicyPosZMult); } - PROCESS_SWITCH(HfCorrelatorFlowCharmHadronsReduced, processSameEventCharmHadWMultMix, "Process Same Event for Charm-Had with multiplicity pools", false); + PROCESS_SWITCH(HfCorrelatorFlowCharmHadronsReduced, processSECharmHadWMultMixWEffInfo, "Process Same Event for Charm-Had with multiplicity pools", false); - void processSameEventHadHadWMultMix(SameEvtPairsHadHad::iterator const& pair, + void processSEHadHadWMultMix(SameEvtPairsHadHad::iterator const& pair, aod::HfcRedTrigTracks const&, aod::HfcRedCorrColls const&) { BinningMultPosZ binPolicyPosZMult{{binsZPool, binsMultPool}}; auto trigCand = pair.template hfcRedTrigTrack_as(); - if (fillSparses && fillTables) { - fillSameEvent(pair, trigCand, binPolicyPosZMult); - } else if (fillSparses) { - fillSameEvent(pair, trigCand, binPolicyPosZMult); - } else if (fillTables) { - fillSameEvent(pair, trigCand, binPolicyPosZMult); - } + fillSameEvent(pair, trigCand, binPolicyPosZMult); } - PROCESS_SWITCH(HfCorrelatorFlowCharmHadronsReduced, processSameEventHadHadWMultMix, "Process Same Event for Had-Had with multiplicity pools", false); + PROCESS_SWITCH(HfCorrelatorFlowCharmHadronsReduced, processSEHadHadWMultMix, "Process Same Event for Had-Had with multiplicity pools", false); - void processSameEventCharmHadWCentMix(SameEvtPairsChHad::iterator const& pair, + void processSECharmHadWCentMix(SameEvtPairsChHad::iterator const& pair, aod::HfcRedTrigCharms const&, aod::HfcRedCorrColls const&) { BinningCentPosZ binPolicyPosZCent{{binsZPool, binsCentPool}}; auto trigCand = pair.template hfcRedTrigCharm_as(); - if (fillSparses && fillTables) { - fillSameEvent(pair, trigCand, binPolicyPosZCent); - } else if (fillSparses) { - fillSameEvent(pair, trigCand, binPolicyPosZCent); - } else if (fillTables) { - fillSameEvent(pair, trigCand, binPolicyPosZCent); - } + fillSameEvent(pair, trigCand, binPolicyPosZCent); } - PROCESS_SWITCH(HfCorrelatorFlowCharmHadronsReduced, processSameEventCharmHadWCentMix, "Process Same Event for Charm-Had with centrality pools", true); + PROCESS_SWITCH(HfCorrelatorFlowCharmHadronsReduced, processSECharmHadWCentMix, "Process Same Event for Charm-Had with centrality pools", true); - void processSameEventHadHadWCentMix(SameEvtPairsHadHad::iterator const& pair, + void processSECharmHadWCentMixWEffInfo(SameEvtPairsChHadWEffInfo::iterator const& pair, + TrigCharmCands const&, + aod::HfcRedCorrColls const&) + { + BinningCentPosZ binPolicyPosZCent{{binsZPool, binsCentPool}}; + auto trigCand = pair.template hfcRedTrigCharm_as(); + fillSameEvent(pair, trigCand, binPolicyPosZCent); + } + PROCESS_SWITCH(HfCorrelatorFlowCharmHadronsReduced, processSECharmHadWCentMixWEffInfo, "Process Same Event for Charm-Had with centrality pools", true); + + void processSEHadHadWCentMix(SameEvtPairsHadHad::iterator const& pair, aod::HfcRedTrigTracks const&, aod::HfcRedCorrColls const&) { BinningCentPosZ binPolicyPosZCent{{binsZPool, binsCentPool}}; auto trigCand = pair.template hfcRedTrigTrack_as(); - if (fillSparses && fillTables) { - fillSameEvent(pair, trigCand, binPolicyPosZCent); - } else if (fillSparses) { - fillSameEvent(pair, trigCand, binPolicyPosZCent); - } else if (fillTables) { - fillSameEvent(pair, trigCand, binPolicyPosZCent); - } + fillSameEvent(pair, trigCand, binPolicyPosZCent); } - PROCESS_SWITCH(HfCorrelatorFlowCharmHadronsReduced, processSameEventHadHadWCentMix, "Process Same Event for Had-Had with centrality pools", false); + PROCESS_SWITCH(HfCorrelatorFlowCharmHadronsReduced, processSEHadHadWCentMix, "Process Same Event for Had-Had with centrality pools", false); - void processMixedEventCharmHadWCentMix(aod::HfcRedCorrColls const& collisions, - TrigCharmCands const& candidates, - AssocTracks const& tracks) + void processMECharmHadWCentMix(aod::HfcRedCorrColls const& collisions, + TrigCharmCands const& candidates, + AssocTracks const& tracks) { BinningCentPosZ binPolicyPosZCent{{binsZPool, binsCentPool}}; auto pairsTuple = std::make_tuple(candidates, tracks); Pair const pairs{binPolicyPosZCent, numberEventsMixed, -1, collisions, pairsTuple, &cache}; - if (fillSparses && fillTables) { - fillMixedEvent(pairs, binPolicyPosZCent); - } else if (fillSparses) { - fillMixedEvent(pairs, binPolicyPosZCent); - } else if (fillTables) { - fillMixedEvent(pairs, binPolicyPosZCent); - } + fillMixedEvent(pairs, binPolicyPosZCent); } - PROCESS_SWITCH(HfCorrelatorFlowCharmHadronsReduced, processMixedEventCharmHadWCentMix, "Process Mixed Event for Charm-Had with centrality pools", false); + PROCESS_SWITCH(HfCorrelatorFlowCharmHadronsReduced, processMECharmHadWCentMix, "Process Mixed Event for Charm-Had with centrality pools", false); - void processMixedEventCharmHadWMultMix(aod::HfcRedCorrColls const& collisions, + void processMECharmHadWMultMix(aod::HfcRedCorrColls const& collisions, TrigCharmCands const& candidates, AssocTracks const& tracks) { BinningMultPosZ binPolicyPosZMult{{binsZPool, binsMultPool}}; auto pairsTuple = std::make_tuple(candidates, tracks); Pair const pairs{binPolicyPosZMult, numberEventsMixed, -1, collisions, pairsTuple, &cache}; - if (fillSparses && fillTables) { - fillMixedEvent(pairs, binPolicyPosZMult); - } else if (fillSparses) { - fillMixedEvent(pairs, binPolicyPosZMult); - } else if (fillTables) { - fillMixedEvent(pairs, binPolicyPosZMult); - } + fillMixedEvent(pairs, binPolicyPosZMult); } - PROCESS_SWITCH(HfCorrelatorFlowCharmHadronsReduced, processMixedEventCharmHadWMultMix, "Process Mixed Event for Charm-Had with multiplicity pools", false); + PROCESS_SWITCH(HfCorrelatorFlowCharmHadronsReduced, processMECharmHadWMultMix, "Process Mixed Event for Charm-Had with multiplicity pools", false); - void processMixedEventHadHadWCentMix(aod::HfcRedCorrColls const& collisions, - AssocTracks const& tracks) + void processMEHadHadWCentMix(aod::HfcRedCorrColls const& collisions, + AssocTracks const& tracks) { BinningCentPosZ binPolicyPosZCent{{binsZPool, binsCentPool}}; auto tracksTuple = std::make_tuple(tracks); SameKindPair const pairs{binPolicyPosZCent, numberEventsMixed, -1, collisions, tracksTuple, &cache}; - if (fillSparses && fillTables) { - fillMixedEvent(pairs, binPolicyPosZCent); - } else if (fillSparses) { - fillMixedEvent(pairs, binPolicyPosZCent); - } else if (fillTables) { - fillMixedEvent(pairs, binPolicyPosZCent); - } + fillMixedEvent(pairs, binPolicyPosZCent); } - PROCESS_SWITCH(HfCorrelatorFlowCharmHadronsReduced, processMixedEventHadHadWCentMix, "Process Mixed Event for Had-Had with centrality pools", false); + PROCESS_SWITCH(HfCorrelatorFlowCharmHadronsReduced, processMEHadHadWCentMix, "Process Mixed Event for Had-Had with centrality pools", false); - void processMixedEventHadHadWMultMix(aod::HfcRedCorrColls const& collisions, - AssocTracks const& tracks) + void processMEHadHadWMultMix(aod::HfcRedCorrColls const& collisions, + AssocTracks const& tracks) { BinningMultPosZ binPolicyPosZMult{{binsZPool, binsMultPool}}; auto tracksTuple = std::make_tuple(tracks); SameKindPair const pairs{binPolicyPosZMult, numberEventsMixed, -1, collisions, tracksTuple, &cache}; - if (fillSparses && fillTables) { - fillMixedEvent(pairs, binPolicyPosZMult); - } else if (fillSparses) { - fillMixedEvent(pairs, binPolicyPosZMult); - } else if (fillTables) { - fillMixedEvent(pairs, binPolicyPosZMult); - } + fillMixedEvent(pairs, binPolicyPosZMult); } - PROCESS_SWITCH(HfCorrelatorFlowCharmHadronsReduced, processMixedEventHadHadWMultMix, "Process Mixed Event for Had-Had with multiplicity pools", false); + PROCESS_SWITCH(HfCorrelatorFlowCharmHadronsReduced, processMEHadHadWMultMix, "Process Mixed Event for Had-Had with multiplicity pools", false); void processCharmTriggers(aod::HfcRedTrigCharms const& trigCands, aod::HfcRedCorrColls const&) @@ -651,41 +727,37 @@ struct HfCorrelatorFlowCharmHadronsReduced { if (!isSelBdtScoreCut(trigCand, trigCand.ptTrig())) { continue; } - registry.fill(HIST("hSparseTrigCandsCharm"), trigCand.invMassTrig(), trigCand.ptTrig(), trigCand.bdtScore0Trig(), trigCand.bdtScore1Trig()); + + std::vector values = {trigCand.ptTrig(), trigCand.invMassTrig(), trigCand.bdtScore0Trig(), trigCand.bdtScore1Trig()}; + registry.get(HIST("hSparseTrigCandsCharm"))->Fill(values.data()); } } PROCESS_SWITCH(HfCorrelatorFlowCharmHadronsReduced, processCharmTriggers, "Process charm trigger info", false); - void processSameEventCharmHadWCentMixBase(aod::HfcRedCorrColls const& collisions, - TrigCharmCands const& candidates, - aod::HfcRedAssBases const& tracks) + void processCharmTriggersWEffInfo(TrigCharmCands const& trigCands, + aod::HfcRedCorrColls const&) { - BinningCentPosZ binPolicyPosZCent{{binsZPool, binsCentPool}}; - for (const auto& collision : collisions) { + for (const auto& trigCand : trigCands) { + auto collision = trigCand.template hfcRedCorrColl_as(); if (!isSelCollision(collision)) { continue; } - int poolBin = binPolicyPosZCent.getBin({collision.posZ(), collision.centrality()}); - - auto thisCollId = collision.globalIndex(); - auto candsThisColl = candidates.sliceBy(trigCharmCandsPerCol, thisCollId); - auto tracksThisColl = tracks.sliceBy(assocTracksPerCol, thisCollId); + if (!isSelBdtScoreCut(trigCand, trigCand.ptTrig())) { + continue; + } - doCorrelationsSameEvent(poolBin, candsThisColl, tracksThisColl); + double effTrig = doEfficiencyCorrection ? getEfficiency(hEffPrompt.get(), effHistTypeCharm.value, trigCand) : 1.; + if (doEfficiencyCorrection && !isValidEfficiency(effTrig)) { + LOGF(warn, "Invalid efficiency value for trigger candidate: effTrig = %f", effTrig); + continue; + } + std::vector values = {trigCand.ptTrig(), trigCand.invMassTrig(), trigCand.bdtScore0Trig(), trigCand.bdtScore1Trig()}; + double weight = doEfficiencyCorrection ? 1. / effTrig : 1.; + registry.get(HIST("hSparseTrigCandsCharm"))->Fill(values.data(), weight); } } - PROCESS_SWITCH(HfCorrelatorFlowCharmHadronsReduced, processSameEventCharmHadWCentMixBase, "Process Same Event base", false); - - void processMixedEventCharmHadWCentMixBase(aod::HfcRedCorrColls const& collisions, - TrigCharmCands const& candidates, - aod::HfcRedAssBases const& tracks) - { - BinningCentPosZ binPolicyPosZCent{{binsZPool, binsCentPool}}; - - doCorrelationsMixedEvent(collisions, candidates, tracks, binPolicyPosZCent); - } - PROCESS_SWITCH(HfCorrelatorFlowCharmHadronsReduced, processMixedEventCharmHadWCentMixBase, "Process Mixed Event base", false); + PROCESS_SWITCH(HfCorrelatorFlowCharmHadronsReduced, processCharmTriggersWEffInfo, "Process charm trigger info with efficiency", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGHF/HFC/TableProducer/derivedDataCreatorCorrelationsReduced.cxx b/PWGHF/HFC/TableProducer/derivedDataCreatorCorrelationsReduced.cxx index ad36c4baecd..75eb9ba2d61 100644 --- a/PWGHF/HFC/TableProducer/derivedDataCreatorCorrelationsReduced.cxx +++ b/PWGHF/HFC/TableProducer/derivedDataCreatorCorrelationsReduced.cxx @@ -16,6 +16,7 @@ /// \author Wu Chuntai , CCNU, INFN Padova, and Padova University #include "PWGHF/Core/CentralityEstimation.h" +#include "PWGHF/Core/DecayChannels.h" #include "PWGHF/Core/HfHelper.h" #include "PWGHF/DataModel/AliasTables.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" @@ -57,6 +58,7 @@ using namespace o2::framework; using namespace o2::framework::expressions; using namespace o2::hf_centrality; using namespace o2::hf_evsel; +using namespace o2::hf_decay; enum CandidateType { DplusToPiKPi = 0, @@ -83,6 +85,7 @@ struct HfDerivedDataCreatorCorrelationsReduced { Configurable centEstimator{"centEstimator", 2, "Centrality estimation (FT0A: 1, FT0C: 2, FT0M: 3, FV0A: 4)"}; Configurable selectionFlag{"selectionFlag", 15, "Selection Flag for hadron (ML score tables are required to run the task)"}; Configurable forceCharmInCollision{"forceCharmInCollision", true, "Flag to force charm in collision"}; + Configurable acceptOnlyPrompt{"acceptOnlyPrompt", true, "Flag to accept only prompt charm in the MC process functions"}; Configurable ccdbUrl{"ccdbUrl", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; Configurable> classMl{"classMl", {0, 2}, "Indexes of BDT scores to be stored. Two indexes max."}; Configurable yCandMax{"yCandMax", 0.8, "max. cand. rapidity"}; @@ -107,33 +110,44 @@ struct HfDerivedDataCreatorCorrelationsReduced { o2::framework::Service ccdb{}; SliceCache cache; - TF1* funcDcaXYPtCutPrimTrk = nullptr; + std::unique_ptr funcDcaXYPtCutPrimTrk{nullptr}; - using CollsWithCentMult = soa::Join; - using CandDsData = soa::Filtered>; - using CandDplusData = soa::Filtered>; + using DataCollsWithCentMult = soa::Join; + using McCollsWithCentMult = soa::Join; + + // Data using CandD0Data = soa::Filtered>; + using CandDplusData = soa::Filtered>; + using CandDsData = soa::Filtered>; using CandLcData = soa::Filtered>; - using TracksData = soa::Filtered>; + using TracksData = soa::Filtered>; //, aod::pidTPCFullMu, aod::pidTPCFullEl, aod::pidTPCFullPi, aod::pidTPCFullKa, aod::pidTPCFullPr>>; + // MC + using CandD0Mc = soa::Filtered>; + using CandDplusMc = soa::Filtered>; + using CandDsMc = soa::Filtered>; + using CandLcMc = soa::Filtered>; + using TracksMc = soa::Filtered>; //, aod::pidTPCFullMu, aod::pidTPCFullEl, aod::pidTPCFullPi, aod::pidTPCFullKa, aod::pidTPCFullPr>>; - Filter filterSelectDsCandidates = aod::hf_sel_candidate_ds::isSelDsToKKPi >= selectionFlag || aod::hf_sel_candidate_ds::isSelDsToPiKK >= selectionFlag; - Filter filterSelectDplusCandidates = aod::hf_sel_candidate_dplus::isSelDplusToPiKPi >= selectionFlag; Filter filterSelectD0Candidates = aod::hf_sel_candidate_d0::isSelD0 >= selectionFlag || aod::hf_sel_candidate_d0::isSelD0bar >= selectionFlag; + Filter filterSelectDplusCandidates = aod::hf_sel_candidate_dplus::isSelDplusToPiKPi >= selectionFlag; + Filter filterSelectDsCandidates = aod::hf_sel_candidate_ds::isSelDsToKKPi >= selectionFlag || aod::hf_sel_candidate_ds::isSelDsToPiKK >= selectionFlag; Filter filterSelectLcCandidates = aod::hf_sel_candidate_lc::isSelLcToPKPi >= selectionFlag || aod::hf_sel_candidate_lc::isSelLcToPiKP >= selectionFlag; Filter filterSelectTrkData = (nabs(aod::track::eta) < etaTrkMax) && (aod::track::pt > ptTrkMin) && (aod::track::pt < ptTrkMax) && (nabs(aod::track::dcaXY) < dcaXYTrkMax) && (nabs(aod::track::dcaZ) < dcaZTrkMax); - Preslice candsDsPerColl = aod::hf_cand::collisionId; - Preslice candsDplusPerColl = aod::hf_cand::collisionId; - Preslice candsD0PerColl = aod::hf_cand::collisionId; - Preslice candsLcPerColl = aod::hf_cand::collisionId; - Preslice trackIndicesPerColl = aod::track::collisionId; - - Partition selectedDsToKKPi = aod::hf_sel_candidate_ds::isSelDsToKKPi >= selectionFlag; - Partition selectedDsToPiKK = aod::hf_sel_candidate_ds::isSelDsToPiKK >= selectionFlag; - Partition selectedD0ToPiK = aod::hf_sel_candidate_d0::isSelD0 >= selectionFlag; - Partition selectedD0ToKPi = aod::hf_sel_candidate_d0::isSelD0bar >= selectionFlag; - Partition selectedLcToPKPi = aod::hf_sel_candidate_lc::isSelLcToPKPi >= selectionFlag; - Partition selectedLcToPiKP = aod::hf_sel_candidate_lc::isSelLcToPiKP >= selectionFlag; + Partition selD0ToPiK = aod::hf_sel_candidate_d0::isSelD0 >= selectionFlag; + Partition selD0ToKPi = aod::hf_sel_candidate_d0::isSelD0bar >= selectionFlag; + Partition selDsToKKPi = aod::hf_sel_candidate_ds::isSelDsToKKPi >= selectionFlag; + Partition selDsToPiKK = aod::hf_sel_candidate_ds::isSelDsToPiKK >= selectionFlag; + Partition selLcToPKPi = aod::hf_sel_candidate_lc::isSelLcToPKPi >= selectionFlag; + Partition selLcToPiKP = aod::hf_sel_candidate_lc::isSelLcToPiKP >= selectionFlag; + + Partition recoSelD0ToPiK = (nabs(aod::hf_cand_mc_flag::flagMcMatchRec) == static_cast(hf_cand_2prong::DecayChannelMain::D0ToPiK)) && aod::hf_sel_candidate_d0::isSelD0 >= selectionFlag && ((!acceptOnlyPrompt) || (acceptOnlyPrompt && aod::hf_cand_mc_flag::originMcRec == static_cast(RecoDecay::OriginType::Prompt))); + Partition recoSelD0ToKPi = (nabs(aod::hf_cand_mc_flag::flagMcMatchRec) == static_cast(hf_cand_2prong::DecayChannelMain::D0ToPiK)) && aod::hf_sel_candidate_d0::isSelD0bar >= selectionFlag && ((!acceptOnlyPrompt) || (acceptOnlyPrompt && aod::hf_cand_mc_flag::originMcRec == static_cast(RecoDecay::OriginType::Prompt))); + Partition recoSelDPlusCandidates = (nabs(aod::hf_cand_mc_flag::flagMcMatchRec) == static_cast(hf_cand_3prong::DecayChannelMain::DplusToPiKPi)) && aod::hf_sel_candidate_dplus::isSelDplusToPiKPi >= selectionFlag && ((!acceptOnlyPrompt) || (acceptOnlyPrompt && aod::hf_cand_mc_flag::originMcRec == static_cast(RecoDecay::OriginType::Prompt))); + Partition recoSelDsToKKPi = (nabs(aod::hf_cand_mc_flag::flagMcMatchRec) == static_cast(hf_cand_3prong::DecayChannelMain::DsToPiKK) && nabs(aod::hf_cand_mc_flag::flagMcDecayChanRec) == static_cast(hf_cand_3prong::DecayChannelResonant::DsToPhiPi)) && aod::hf_sel_candidate_ds::isSelDsToKKPi >= selectionFlag && ((!acceptOnlyPrompt) || (acceptOnlyPrompt && aod::hf_cand_mc_flag::originMcRec == static_cast(RecoDecay::OriginType::Prompt))); + Partition recoSelDsToPiKK = (nabs(aod::hf_cand_mc_flag::flagMcMatchRec) == static_cast(hf_cand_3prong::DecayChannelMain::DsToPiKK) && nabs(aod::hf_cand_mc_flag::flagMcDecayChanRec) == static_cast(hf_cand_3prong::DecayChannelResonant::DsToPhiPi)) && aod::hf_sel_candidate_ds::isSelDsToPiKK >= selectionFlag && ((!acceptOnlyPrompt) || (acceptOnlyPrompt && aod::hf_cand_mc_flag::originMcRec == static_cast(RecoDecay::OriginType::Prompt))); + Partition recoSelLcToPKPi = (nabs(aod::hf_cand_mc_flag::flagMcMatchRec) == static_cast(hf_cand_3prong::DecayChannelMain::LcToPKPi)) && aod::hf_sel_candidate_lc::isSelLcToPKPi >= selectionFlag && ((!acceptOnlyPrompt) || (acceptOnlyPrompt && aod::hf_cand_mc_flag::originMcRec == static_cast(RecoDecay::OriginType::Prompt))); + Partition recoSelLcToPiKP = (nabs(aod::hf_cand_mc_flag::flagMcMatchRec) == static_cast(hf_cand_3prong::DecayChannelMain::LcToPKPi)) && aod::hf_sel_candidate_lc::isSelLcToPiKP >= selectionFlag && ((!acceptOnlyPrompt) || (acceptOnlyPrompt && aod::hf_cand_mc_flag::originMcRec == static_cast(RecoDecay::OriginType::Prompt))); ConfigurableAxis binsTpcSignal{"binsTpcSignal", {500, 0., 500.}, "TPC signal bins"}; ConfigurableAxis binsPtTrig{"binsPtTrig", {24, 0, 24}, ""}; @@ -177,66 +191,15 @@ struct HfDerivedDataCreatorCorrelationsReduced { registry.add("hDcaZVsPtVsCentAssoc", "Associated particles DCAzVsPtVsCent", {HistType::kTH3F, {{axisPtAssoc}, {axisDcaZ}, {axisCent}}}); registry.add("hDcaXYVsPtVsMultAssoc", "Associated particles DCAxyVsPtVsMult", {HistType::kTH3F, {{axisPtAssoc}, {axisDcaXY}, {axisMult}}}); registry.add("hDcaZVsPtVsMultAssoc", "Associated particles DCAzVsPtVsMult", {HistType::kTH3F, {{axisPtAssoc}, {axisDcaZ}, {axisMult}}}); - registry.add("hAssocTrkPidTPC", "Associated tracks PID TPC", {HistType::kTH2F, {{axisPtAssoc}, {axisTpcSignal}}}); - registry.add("hTrackSelection", "Track selection", {HistType::kTH1F, {{11, -0.5, 10.5}}}); - registry.get(HIST("hTrackSelection"))->GetXaxis()->SetBinLabel(1, "All"); - registry.get(HIST("hTrackSelection"))->GetXaxis()->SetBinLabel(2, "IsQualityTrack"); - registry.get(HIST("hTrackSelection"))->GetXaxis()->SetBinLabel(3, "IsQualityTrackITS"); - registry.get(HIST("hTrackSelection"))->GetXaxis()->SetBinLabel(4, "IsQualityTrackTPC"); - registry.get(HIST("hTrackSelection"))->GetXaxis()->SetBinLabel(5, "IsPrimaryTrack"); - registry.get(HIST("hTrackSelection"))->GetXaxis()->SetBinLabel(6, "IsInAcceptanceTrack"); - registry.get(HIST("hTrackSelection"))->GetXaxis()->SetBinLabel(7, "IsGlobalTrack"); - registry.get(HIST("hTrackSelection"))->GetXaxis()->SetBinLabel(8, "IsGlobalTrackWoTPCCluster"); - registry.get(HIST("hTrackSelection"))->GetXaxis()->SetBinLabel(9, "IsGlobalTrackWoPtEta"); - registry.get(HIST("hTrackSelection"))->GetXaxis()->SetBinLabel(10, "IsGlobalTrackWoDCA"); - registry.get(HIST("hTrackSelection"))->GetXaxis()->SetBinLabel(11, "IsGlobalTrackWoDCATPCCluster"); // Setup pt-dependent DCAxy cut function if (usePtDiffDcaXYCut) { - funcDcaXYPtCutPrimTrk = new TF1("funcDcaXYPtCutPrimTrk", Form("[0]*%s", dcaXYPtPrimTrkFunc.value.data()), 0.001, 100); + funcDcaXYPtCutPrimTrk = std::make_unique("funcDcaXYPtCutPrimTrk", Form("[0]*%s", dcaXYPtPrimTrkFunc.value.data()), 0.001, 100.); funcDcaXYPtCutPrimTrk->SetParameter(0, dcaXYTrkNSigmaMax); LOGF(info, "DCAxy pt-dependence function: %s", Form("[0]*%s", dcaXYPtPrimTrkFunc.value.data())); } }; // end init - /// Fill track selection histograms - /// \param track is the associated track - template - void fillTrkSelHistos(const TTrack& track) - { - registry.fill(HIST("hTrackSelection"), 0); // all tracks - if (track.isQualityTrack()) { - registry.fill(HIST("hTrackSelection"), 1); - } - if (track.isQualityTrackITS()) { - registry.fill(HIST("hTrackSelection"), 2); - } - if (track.isQualityTrackTPC()) { - registry.fill(HIST("hTrackSelection"), 3); - } - if (track.isPrimaryTrack()) { - registry.fill(HIST("hTrackSelection"), 4); - } - if (track.isInAcceptanceTrack()) { - registry.fill(HIST("hTrackSelection"), 5); - } - if (track.isGlobalTrack()) { - registry.fill(HIST("hTrackSelection"), 6); - } - if (track.isGlobalTrackWoTPCCluster()) { - registry.fill(HIST("hTrackSelection"), 7); - } - if (track.isGlobalTrackWoPtEta()) { - registry.fill(HIST("hTrackSelection"), 8); - } - if (track.isGlobalTrackWoDCA()) { - registry.fill(HIST("hTrackSelection"), 9); - } - if (track.isGlobalTrackWoDCATPCCluster()) { - registry.fill(HIST("hTrackSelection"), 10); - } - } - /// Get charm hadron candidate mass /// \param candidate is the charm hadron candidate template @@ -397,7 +360,7 @@ struct HfDerivedDataCreatorCorrelationsReduced { /// \param assTrks are the associated tracks /// \param cent is the collision centrality /// \param mult is the collision multiplicity - template + template void fillSameEvent(TTrigCands const& trigCands, TAssocTrks const& assTrks, const float cent, @@ -415,10 +378,10 @@ struct HfDerivedDataCreatorCorrelationsReduced { } else { std::array outputMl = getCandMlScores(trigCand); rowTrigCharms(rowCollisions.lastIndex(), trigCandPt, getCandMass(trigCand), outputMl[0], outputMl[1]); + rowTrigBases(trigCand.phi(), trigCand.eta()); } for (const auto& assTrk : assTrks) { - fillTrkSelHistos(assTrk); double assTrkPt = assTrk.pt(); if (usePtDiffDcaXYCut) { float const dcaXYTrkCut = funcDcaXYPtCutPrimTrk->Eval(assTrkPt); @@ -442,12 +405,12 @@ struct HfDerivedDataCreatorCorrelationsReduced { registry.fill(HIST("hPhiVsPtAssoc"), RecoDecay::constrainAngle(assTrk.phi(), -o2::constants::math::PIHalf), assTrkPt); registry.fill(HIST("hEtaVsPtAssoc"), assTrk.eta(), assTrkPt); registry.fill(HIST("hDcaXYVsPtVsCentAssoc"), assTrkPt, assTrk.dcaXY(), cent); - registry.fill(HIST("hDcaZVsPtVsCentAssoc"), assTrkPt, assTrk.dcaZ(), cent); registry.fill(HIST("hDcaXYVsPtVsMultAssoc"), assTrkPt, assTrk.dcaXY(), mult); + registry.fill(HIST("hDcaZVsPtVsCentAssoc"), assTrkPt, assTrk.dcaZ(), cent); registry.fill(HIST("hDcaZVsPtVsMultAssoc"), assTrkPt, assTrk.dcaZ(), mult); - registry.fill(HIST("hAssocTrkPidTPC"), assTrkPt, assTrk.tpcSignal()); double deltaPhi = RecoDecay::constrainAngle(assTrk.phi() - trigCand.phi(), -o2::constants::math::PIHalf); + rowAssocBases(rowCollisions.lastIndex(), assTrk.phi(), assTrk.eta(), assTrkPt); rowAssocTrkSels(assTrk.tpcNClsCrossedRows(), assTrk.itsClusterMap(), assTrk.itsNCls(), assTrk.dcaXY(), assTrk.dcaZ()); if constexpr (CandType == CandidateType::Hadron) { rowSEHadHadPairs(rowCollisions.lastIndex(), rowTrigHads.lastIndex(), assTrkPt, deltaEta, deltaPhi); @@ -460,7 +423,7 @@ struct HfDerivedDataCreatorCorrelationsReduced { /// Fill charm hadron tables for mixed-event /// \param trigCands are the charm trigger candidates - template + template void fillCharmMixedEvent(TTrigCands const& trigCands) { for (const auto& trigCand : trigCands) { @@ -480,14 +443,13 @@ struct HfDerivedDataCreatorCorrelationsReduced { /// \param assTrks are the associated tracks /// \param cent is the collision centrality /// \param mult is the collision multiplicity - template + template void fillTrkMixedEvent(TAssocTrks const& assTrks, const float cent, const float mult) { bool first = true; for (const auto& assTrk : assTrks) { - fillTrkSelHistos(assTrk); if (!assTrk.isGlobalTrackWoDCA() || assTrk.tpcNClsCrossedRows() < tpcNClsCrossedRowsMin) { continue; } @@ -511,16 +473,16 @@ struct HfDerivedDataCreatorCorrelationsReduced { registry.fill(HIST("hDcaZVsPtVsCentAssoc"), assTrkPt, assTrk.dcaZ(), cent); registry.fill(HIST("hDcaXYVsPtVsMultAssoc"), assTrkPt, assTrk.dcaXY(), mult); registry.fill(HIST("hDcaZVsPtVsMultAssoc"), assTrkPt, assTrk.dcaZ(), mult); - registry.fill(HIST("hAssocTrkPidTPC"), assTrkPt, assTrk.tpcSignal()); rowAssocBases(rowCollisions.lastIndex(), assTrk.phi(), assTrk.eta(), assTrkPt); rowAssocTrkSels(assTrk.tpcNClsCrossedRows(), assTrk.itsClusterMap(), assTrk.itsNCls(), assTrk.dcaXY(), assTrk.dcaZ()); } } - // Dplus with ML selections - void processDplusSameEvent(CollsWithCentMult::iterator const& coll, - CandDplusData const& candsDplus, - TracksData const& tracks) + // CHARM-HADRON CORRELATIONS PROCESS FUNCTIONS --- DATA + // Dplus data + void processDataDplusSE(DataCollsWithCentMult::iterator const& coll, + CandDplusData const& candsDplus, + TracksData const& tracks) { if (forceCharmInCollision && candsDplus.size() < 1) { return; @@ -530,14 +492,14 @@ struct HfDerivedDataCreatorCorrelationsReduced { return; } rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); - fillSameEvent(candsDplus, tracks, cent, mult); + fillSameEvent(candsDplus, tracks, cent, mult); } - PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processDplusSameEvent, "Process Same Event for Dplus candidates", true); + PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processDataDplusSE, "Process Same Event for Dplus candidates", true); - // Dplus with ML selections - void processDplusMixedEvent(CollsWithCentMult::iterator const& coll, - CandDplusData const& candsDplus, - TracksData const& tracks) + // Dplus data + void processDataDplusME(DataCollsWithCentMult::iterator const& coll, + CandDplusData const& candsDplus, + TracksData const& tracks) { if (forceCharmInCollision && candsDplus.size() < 1) { return; @@ -547,18 +509,18 @@ struct HfDerivedDataCreatorCorrelationsReduced { return; } rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); - fillCharmMixedEvent(candsDplus); - fillTrkMixedEvent(tracks, cent, mult); + fillCharmMixedEvent(candsDplus); + fillTrkMixedEvent(tracks, cent, mult); } - PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processDplusMixedEvent, "Process Mixed Event for Dplus candidates", false); + PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processDataDplusME, "Process Mixed Event for Dplus candidates", false); - // Ds with ML selections - void processDsSameEvent(CollsWithCentMult::iterator const& coll, - TracksData const& tracks, - CandDsData const&) + // Ds data + void processDataDsSE(DataCollsWithCentMult::iterator const& coll, + TracksData const& tracks, + CandDsData const&) { - auto candsDsToPiKK = selectedDsToPiKK->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); - auto candsDsToKKPi = selectedDsToKKPi->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); + auto candsDsToPiKK = selDsToPiKK->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); + auto candsDsToKKPi = selDsToKKPi->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); if (forceCharmInCollision && candsDsToPiKK.size() < 1 && candsDsToKKPi.size() < 1) { return; } @@ -567,18 +529,18 @@ struct HfDerivedDataCreatorCorrelationsReduced { return; } rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); - fillSameEvent(candsDsToPiKK, tracks, cent, mult); - fillSameEvent(candsDsToKKPi, tracks, cent, mult); + fillSameEvent(candsDsToPiKK, tracks, cent, mult); + fillSameEvent(candsDsToKKPi, tracks, cent, mult); } - PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processDsSameEvent, "Process Same Event for Ds candidates", false); + PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processDataDsSE, "Process Same Event for Ds candidates", false); - // Ds with ML selections - void processDsMixedEvent(CollsWithCentMult::iterator const& coll, - TracksData const& tracks, - CandDsData const&) + // Ds data + void processDataDsME(DataCollsWithCentMult::iterator const& coll, + TracksData const& tracks, + CandDsData const&) { - auto candsDsToPiKK = selectedDsToPiKK->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); - auto candsDsToKKPi = selectedDsToKKPi->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); + auto candsDsToPiKK = selDsToPiKK->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); + auto candsDsToKKPi = selDsToKKPi->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); if (forceCharmInCollision && candsDsToPiKK.size() < 1 && candsDsToKKPi.size() < 1) { return; } @@ -587,19 +549,19 @@ struct HfDerivedDataCreatorCorrelationsReduced { return; } rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); - fillCharmMixedEvent(candsDsToPiKK); - fillCharmMixedEvent(candsDsToKKPi); - fillTrkMixedEvent(tracks, cent, mult); + fillCharmMixedEvent(candsDsToPiKK); + fillCharmMixedEvent(candsDsToKKPi); + fillTrkMixedEvent(tracks, cent, mult); } - PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processDsMixedEvent, "Process Mixed Event for Ds candidates", false); + PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processDataDsME, "Process Mixed Event for Ds candidates", false); - // D0 with ML selections - void processD0SameEvent(CollsWithCentMult::iterator const& coll, - TracksData const& tracks, - CandD0Data const&) + // D0 data + void processDataD0SE(DataCollsWithCentMult::iterator const& coll, + TracksData const& tracks, + CandD0Data const&) { - auto candsD0ToPiK = selectedD0ToPiK->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); - auto candsD0ToKPi = selectedD0ToKPi->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); + auto candsD0ToPiK = selD0ToPiK->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); + auto candsD0ToKPi = selD0ToKPi->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); if (forceCharmInCollision && candsD0ToPiK.size() < 1 && candsD0ToKPi.size() < 1) { return; } @@ -608,18 +570,18 @@ struct HfDerivedDataCreatorCorrelationsReduced { return; } rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); - fillSameEvent(candsD0ToPiK, tracks, cent, mult); - fillSameEvent(candsD0ToKPi, tracks, cent, mult); + fillSameEvent(candsD0ToPiK, tracks, cent, mult); + fillSameEvent(candsD0ToKPi, tracks, cent, mult); } - PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processD0SameEvent, "Process Same Event for D0 candidates", false); + PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processDataD0SE, "Process Same Event for D0 candidates", false); - // D0 with ML selections - void processD0MixedEvent(CollsWithCentMult::iterator const& coll, - TracksData const& tracks, - CandD0Data const&) + // D0 data + void processDataD0ME(DataCollsWithCentMult::iterator const& coll, + TracksData const& tracks, + CandD0Data const&) { - auto candsD0ToPiK = selectedD0ToPiK->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); - auto candsD0ToKPi = selectedD0ToKPi->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); + auto candsD0ToPiK = selD0ToPiK->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); + auto candsD0ToKPi = selD0ToKPi->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); if (forceCharmInCollision && candsD0ToPiK.size() < 1 && candsD0ToKPi.size() < 1) { return; } @@ -628,19 +590,19 @@ struct HfDerivedDataCreatorCorrelationsReduced { return; } rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); - fillCharmMixedEvent(candsD0ToPiK); - fillCharmMixedEvent(candsD0ToKPi); - fillTrkMixedEvent(tracks, cent, mult); + fillCharmMixedEvent(candsD0ToPiK); + fillCharmMixedEvent(candsD0ToKPi); + fillTrkMixedEvent(tracks, cent, mult); } - PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processD0MixedEvent, "Process Mixed Event for D0 candidates", false); + PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processDataD0ME, "Process Mixed Event for D0 candidates", false); - // Lc with ML selections - void processLcSameEvent(CollsWithCentMult::iterator const& coll, - TracksData const& tracks, - CandLcData const&) + // Lc data + void processDataLcSE(DataCollsWithCentMult::iterator const& coll, + TracksData const& tracks, + CandLcData const&) { - auto candsLcToPKPi = selectedLcToPKPi->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); - auto candsLcToPiKP = selectedLcToPiKP->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); + auto candsLcToPKPi = selLcToPKPi->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); + auto candsLcToPiKP = selLcToPiKP->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); if (forceCharmInCollision && candsLcToPKPi.size() < 1 && candsLcToPiKP.size() < 1) { return; } @@ -649,18 +611,18 @@ struct HfDerivedDataCreatorCorrelationsReduced { return; } rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); - fillSameEvent(candsLcToPKPi, tracks, cent, mult); - fillSameEvent(candsLcToPiKP, tracks, cent, mult); + fillSameEvent(candsLcToPKPi, tracks, cent, mult); + fillSameEvent(candsLcToPiKP, tracks, cent, mult); } - PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processLcSameEvent, "Process Same Event for Lc candidates", false); + PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processDataLcSE, "Process Same Event for Lc candidates", false); - // Lc with ML selections - void processLcMixedEvent(CollsWithCentMult::iterator const& coll, - TracksData const& tracks, - CandLcData const&) + // Lc data + void processDataLcME(DataCollsWithCentMult::iterator const& coll, + TracksData const& tracks, + CandLcData const&) { - auto candsLcToPKPi = selectedLcToPKPi->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); - auto candsLcToPiKP = selectedLcToPiKP->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); + auto candsLcToPKPi = selLcToPKPi->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); + auto candsLcToPiKP = selLcToPiKP->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); if (forceCharmInCollision && candsLcToPKPi.size() < 1 && candsLcToPiKP.size() < 1) { return; } @@ -669,37 +631,227 @@ struct HfDerivedDataCreatorCorrelationsReduced { return; } rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); - fillCharmMixedEvent(candsLcToPKPi); - fillCharmMixedEvent(candsLcToPiKP); - fillTrkMixedEvent(tracks, cent, mult); + fillCharmMixedEvent(candsLcToPKPi); + fillCharmMixedEvent(candsLcToPiKP); + fillTrkMixedEvent(tracks, cent, mult); } - PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processLcMixedEvent, "Process Mixed Event for Lc candidates", false); + PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processDataLcME, "Process Mixed Event for Lc candidates", false); - // Hadron Hadron Same Event - void processHadronHadronSameEvent(CollsWithCentMult::iterator const& coll, - TracksData const& tracks) + + // CHARM-HADRON CORRELATIONS PROCESS FUNCTIONS --- MC + // Dplus MC + void processMcDplusSE(McCollsWithCentMult::iterator const& coll, + CandDplusMc const& candsDplus, + TracksMc const& tracks) { + if (forceCharmInCollision && candsDplus.size() < 1) { + return; + } float cent{-1.}, mult{-1.}; if (!checkCollision(coll, cent, mult)) { return; } rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); - fillSameEvent(tracks, tracks, cent, mult); + fillSameEvent(candsDplus, tracks, cent, mult); } - PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processHadronHadronSameEvent, "Process Same Event for hadron candidates", false); + PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processMcDplusSE, "Process Same Event for Dplus candidates", false); - // Hadron Hadron Mixed Event - void processHadronHadronMixedEvent(CollsWithCentMult::iterator const& coll, - TracksData const& tracks) + // Dplus MC + void processMcDplusME(McCollsWithCentMult::iterator const& coll, + CandDplusMc const& candsDplus, + TracksMc const& tracks) + { + if (forceCharmInCollision && candsDplus.size() < 1) { + return; + } + float cent{-1.}, mult{-1.}; + if (!checkCollision(coll, cent, mult)) { + return; + } + rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); + fillCharmMixedEvent(candsDplus); + fillTrkMixedEvent(tracks, cent, mult); + } + PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processMcDplusME, "Process Mixed Event for Dplus candidates", false); + + // Ds MC + void processMcDsSE(McCollsWithCentMult::iterator const& coll, + TracksMc const& tracks, + CandDsMc const&) + { + auto candsDsToPiKK = recoSelDsToPiKK->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); + auto candsDsToKKPi = recoSelDsToKKPi->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); + if (forceCharmInCollision && candsDsToPiKK.size() < 1 && candsDsToKKPi.size() < 1) { + return; + } + float cent{-1.}, mult{-1.}; + if (!checkCollision(coll, cent, mult)) { + return; + } + rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); + fillSameEvent(candsDsToPiKK, tracks, cent, mult); + fillSameEvent(candsDsToKKPi, tracks, cent, mult); + } + PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processMcDsSE, "Process Same Event for Ds candidates", false); + + // Ds MC + void processMcDsME(McCollsWithCentMult::iterator const& coll, + TracksMc const& tracks, + CandDsMc const&) + { + auto candsDsToPiKK = recoSelDsToPiKK->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); + auto candsDsToKKPi = recoSelDsToKKPi->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); + if (forceCharmInCollision && candsDsToPiKK.size() < 1 && candsDsToKKPi.size() < 1) { + return; + } + float cent{-1.}, mult{-1.}; + if (!checkCollision(coll, cent, mult)) { + return; + } + rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); + fillCharmMixedEvent(candsDsToPiKK); + fillCharmMixedEvent(candsDsToKKPi); + fillTrkMixedEvent(tracks, cent, mult); + } + PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processMcDsME, "Process Mixed Event for Ds candidates", false); + + // D0 MC + void processMcD0SE(McCollsWithCentMult::iterator const& coll, + TracksMc const& tracks, + CandD0Mc const&) + { + auto candsD0ToPiK = recoSelD0ToPiK->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); + auto candsD0ToKPi = recoSelD0ToKPi->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); + if (forceCharmInCollision && candsD0ToPiK.size() < 1 && candsD0ToKPi.size() < 1) { + return; + } + float cent{-1.}, mult{-1.}; + if (!checkCollision(coll, cent, mult)) { + return; + } + rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); + fillSameEvent(candsD0ToPiK, tracks, cent, mult); + fillSameEvent(candsD0ToKPi, tracks, cent, mult); + } + PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processMcD0SE, "Process Same Event for D0 candidates", false); + + // D0 MC + void processMcD0ME(McCollsWithCentMult::iterator const& coll, + TracksMc const& tracks, + CandD0Mc const&) + { + auto candsD0ToPiK = recoSelD0ToPiK->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); + auto candsD0ToKPi = recoSelD0ToKPi->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); + if (forceCharmInCollision && candsD0ToPiK.size() < 1 && candsD0ToKPi.size() < 1) { + return; + } + float cent{-1.}, mult{-1.}; + if (!checkCollision(coll, cent, mult)) { + return; + } + rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); + fillCharmMixedEvent(candsD0ToPiK); + fillCharmMixedEvent(candsD0ToKPi); + fillTrkMixedEvent(tracks, cent, mult); + } + PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processMcD0ME, "Process Mixed Event for D0 candidates", false); + + // Lc MC + void processMcLcSE(McCollsWithCentMult::iterator const& coll, + TracksMc const& tracks, + CandLcMc const&) { + auto candsLcToPKPi = recoSelLcToPKPi->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); + auto candsLcToPiKP = recoSelLcToPiKP->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); + if (forceCharmInCollision && candsLcToPKPi.size() < 1 && candsLcToPiKP.size() < 1) { + return; + } + float cent{-1.}, mult{-1.}; + if (!checkCollision(coll, cent, mult)) { + return; + } + rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); + fillSameEvent(candsLcToPKPi, tracks, cent, mult); + fillSameEvent(candsLcToPiKP, tracks, cent, mult); + } + PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processMcLcSE, "Process Same Event for Lc candidates", false); + + // Lc MC + void processMcLcME(McCollsWithCentMult::iterator const& coll, + TracksMc const& tracks, + CandLcMc const&) + { + auto candsLcToPKPi = recoSelLcToPKPi->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); + auto candsLcToPiKP = recoSelLcToPiKP->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); + if (forceCharmInCollision && candsLcToPKPi.size() < 1 && candsLcToPiKP.size() < 1) { + return; + } + float cent{-1.}, mult{-1.}; + if (!checkCollision(coll, cent, mult)) { + return; + } + rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); + fillCharmMixedEvent(candsLcToPKPi); + fillCharmMixedEvent(candsLcToPiKP); + fillTrkMixedEvent(tracks, cent, mult); + } + PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processMcLcME, "Process Mixed Event for Lc candidates", false); + + + // HADRON-HADRON CORRELATIONS PROCESS FUNCTIONS --- DATA + // Hadron Hadron Same Event + void processDataHadronHadronSE(DataCollsWithCentMult::iterator const& coll, + TracksData const& tracks) + { + float cent{-1.}, mult{-1.}; + if (!checkCollision(coll, cent, mult)) { + return; + } + rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); + fillSameEvent(tracks, tracks, cent, mult); + } + PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processDataHadronHadronSE, "Process Same Event for hadron candidates", false); + + // Hadron Hadron Mixed Event + void processDataHadronHadronME(DataCollsWithCentMult::iterator const& coll, + TracksData const& tracks) + { + float cent{-1.}, mult{-1.}; + if (!checkCollision(coll, cent, mult)) { + return; + } + rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); + fillTrkMixedEvent(tracks, cent, mult); + } + PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processDataHadronHadronME, "Process Mixed Event for hadron candidates", false); + + + // HADRON-HADRON CORRELATIONS PROCESS FUNCTIONS --- MC + // Hadron Hadron Same Event + void processMcHadronHadronSE(McCollsWithCentMult::iterator const& coll, + TracksMc const& tracks) + { + float cent{-1.}, mult{-1.}; + if (!checkCollision(coll, cent, mult)) { + return; + } + rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); + fillSameEvent(tracks, tracks, cent, mult); + } + PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processMcHadronHadronSE, "Process Same Event for hadron candidates", false); + + // Hadron Hadron Mixed Event + void processMcHadronHadronME(McCollsWithCentMult::iterator const& coll, + TracksMc const& tracks) + { float cent{-1.}, mult{-1.}; if (!checkCollision(coll, cent, mult)) { return; } rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); - fillTrkMixedEvent(tracks, cent, mult); + fillTrkMixedEvent(tracks, cent, mult); } - PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processHadronHadronMixedEvent, "Process Mixed Event for hadron candidates", false); + PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processMcHadronHadronME, "Process Mixed Event for hadron candidates", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGHF/HFC/Tasks/taskCorrelationsEfficiencies.cxx b/PWGHF/HFC/Tasks/taskCorrelationsEfficiencies.cxx index 1852d1cbeec..5794bf7a7c2 100644 --- a/PWGHF/HFC/Tasks/taskCorrelationsEfficiencies.cxx +++ b/PWGHF/HFC/Tasks/taskCorrelationsEfficiencies.cxx @@ -58,39 +58,57 @@ using namespace o2::hf_centrality; using namespace o2::hf_evsel; using namespace o2::hfc_utils_flow; -enum axesCharmReco { - kAxisPtTrig, - kAxisPvContrib, - kAxisEtaTrig, - kAxisPhiTrig, - kAxisMlScore0, - kAxisMlScore1 -}; - -enum SparseAxesCharmGen { - kAxisPtTrigGen, - kAxisEtaTrigGen, - kAxisPhiTrigGen -}; - -enum axesAssocTracks { - kAxisPtAssoc, - kAxisEtaAssoc, - kAxisPhiAssoc, - kAxisZVtx, - kAxisAssTrkSpecie, - kAxisAssTrkOrigin -}; - -/// Code to select collisions with at least one Ds meson +namespace o2::aod +{ +namespace hf_correlations_eff +{ +// Charm-hadron candidate columns +DECLARE_SOA_COLUMN(Pt, pt, float); //! Transverse momentum of candidate (GeV/c) +DECLARE_SOA_COLUMN(PvContrib, pvContrib, int); //! Number of primary vertex contributors +DECLARE_SOA_COLUMN(Eta, eta, float); //! Pseudorapidity of candidate +DECLARE_SOA_COLUMN(Phi, phi, float); //! Azimuthal angle of candidate +DECLARE_SOA_COLUMN(Origin, origin, int); //! Origin of the candidate (prompt or non-prompt) +DECLARE_SOA_COLUMN(MlScore0, mlScore0, float); //! ML score of the first configured index +DECLARE_SOA_COLUMN(MlScore1, mlScore1, float); //! ML score of the second configured index + +// Associated track columns +DECLARE_SOA_COLUMN(PtAssoc, ptAssoc, float); //! Transverse momentum of associated track (GeV/c) +DECLARE_SOA_COLUMN(EtaAssoc, etaAssoc, float); //! Pseudorapidity of associated track +DECLARE_SOA_COLUMN(PhiAssoc, phiAssoc, float); //! Azimuthal angle of associated track +DECLARE_SOA_COLUMN(ZVtx, zVtx, float); //! Primary vertex z position (cm) +DECLARE_SOA_COLUMN(AssTrkSpecie, assTrkSpecie, int); //! Associated track species (0=pi, 1=K, 2=p, 3=el, 4=mu) +DECLARE_SOA_COLUMN(AssTrkOrigin, assTrkOrigin, int); //! Associated track origin (0=primary, 1=secondary) +} // namespace hf_correlations_eff + +DECLARE_SOA_TABLE(HfcMcrigInfo, "AOD", "HFCMCTRIGINFO", + hf_correlations_eff::Pt, + hf_correlations_eff::PvContrib, + hf_correlations_eff::Eta, + hf_correlations_eff::Phi, + hf_correlations_eff::Origin, + hf_correlations_eff::MlScore0, + hf_correlations_eff::MlScore1); + +DECLARE_SOA_TABLE(HfcMcAssocInfo, "AOD", "HFCMCASSOCINFO", + hf_correlations_eff::PtAssoc, + hf_correlations_eff::EtaAssoc, + hf_correlations_eff::PhiAssoc, + hf_correlations_eff::ZVtx, + hf_correlations_eff::AssTrkSpecie, + hf_correlations_eff::AssTrkOrigin); +} // namespace o2::aod + +/// Code to obtain efficiency correction factors for (Delta Eta, Delta Phi) correlation maps struct HfTaskCorrelationsEfficiencies { + Produces rowTrigMc; + Produces rowAssocMc; + Produces rowAssocTrkSels; + Configurable selectionFlag{"selectionFlag", 15, "Selection Flag for hadron (ML score tables are required to run the task)"}; Configurable ccdbUrl{"ccdbUrl", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; Configurable> classMl{"classMl", {0, 2}, "Indexes of BDT scores to be stored. Two indexes max."}; Configurable yCandMax{"yCandMax", 0.8, "max. cand. rapidity"}; - Configurable ptCandMin{"ptCandMin", 0., "min. cand. pT"}; - Configurable ptCandMax{"ptCandMax", 24., "max. cand. pT"}; Configurable tpcNClsCrossedRowsMin{"tpcNClsCrossedRowsMin", 70, "min. TPC crossed rows for associated tracks"}; Configurable etaTrkMax{"etaTrkMax", 1., "max. track eta"}; Configurable ptTrkMin{"ptTrkMin", 0.3, "min. track pT"}; @@ -100,34 +118,19 @@ struct HfTaskCorrelationsEfficiencies { Configurable usePtDiffDcaXYCut{"usePtDiffDcaXYCut", false, "Use pt-differential DCAxy cut for associated tracks"}; Configurable dcaXYTrkNSigmaMax{"dcaXYTrkNSigmaMax", 7, "Cut on number of sigma deviations from expected DCA in the transverse direction"}; Configurable dcaXYPtPrimTrkFunc{"dcaXYPtPrimTrkFunc", "(0.0026+0.005/(x^1.01))", "Functional form of pt-dependent DCAxy cut"}; - Configurable> bdtScore0PtMaxs{"bdtScore0PtMaxs", std::vector{0.1, 0.1, 0.1, 0.1, 0.1}, "pT-differential maximum score 0 for charm candidates"}; - Configurable> bdtScore1PtMins{"bdtScore1PtMins", std::vector{0.1, 0.1, 0.1, 0.1, 0.1}, "pT-differential minimum score 1 for charm candidates"}; - - // Configurables for efficiency validation - Configurable runEfficiencyValidation{"runEfficiencyValidation", false, "Flag for running efficiency validation"}; - Configurable> binsPtEffCharm{"binsPtEffCharm", std::vector{0., 2., 4., 6., 8., 10., 24.}, "pT bin limits for efficiency"}; - Configurable> binsPtEffAssTrk{"binsPtEffAssTrk", std::vector{0.3, 2., 4., 8., 12., 50.}, "pT bin limits for associated particle efficiency"}; - Configurable> effPromptCharm{"effPromptCharm", {1., 1., 1., 1., 1., 1.}, "efficiency values for prompt D+ meson"}; - Configurable> effFdCharm{"effFdCharm", {1., 1., 1., 1., 1., 1.}, "efficiency values for beauty feed-down D+ meson"}; - Configurable> effAssTrk{"effAssTrk", {1., 1., 1., 1., 1.}, "efficiency values for associated particles"}; - Configurable loadAccXEffFromCCDB{"loadAccXEffFromCCDB", false, "Flag for loading efficiency distributions from CCDB"}; - Configurable assTrkEffPath{"assTrkEffPath", "", "CCDB path for ass. tracks efficiency"}; - Configurable promptEffPath{"promptEffPath", "", "CCDB path for trigger prompt efficiency"}; - Configurable fdEffPath{"fdEffPath", "", "CCDB path for trigger fd efficiency"}; - Configurable timestampCcdb{"timestampCcdb", -1, "timestamp of the efficiency files used to query in CCDB"}; - Configurable ccdbNoLaterThan{"ccdbNoLaterThan", std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(), "latest acceptable timestamp of creation for the object"}; + + // Configurables for tree filling + Configurable fillRecoTrees{"fillRecoTrees", false, "Fill trees of reconstructed charmed hadrons and associated tracks"}; + Configurable downSampleTracks{"downSampleTracks", 1., "Fraction of tracks to keep"}; + Configurable ptMaxDownSampleTracks{"ptMaxDownSampleTracks", 10., "Maximum pt for the application of the downsampling factor"}; + Configurable downSampleCharm{"downSampleCharm", 1., "Fraction of pairs to keep"}; + Configurable ptMaxDownSampleCharm{"ptMaxDownSampleCharm", 10., "Maximum pt for the application of the downsampling factor"}; HfcFlowHelper hfcFlowHelper; // flow utilities o2::framework::Service ccdb{}; - std::shared_ptr mRecoPrompt = nullptr; - std::shared_ptr mGenPrompt = nullptr; - std::shared_ptr mRecoFD = nullptr; - std::shared_ptr mGenFD = nullptr; - std::shared_ptr mRecoAssTrk = nullptr; - std::shared_ptr mGenAssTrk = nullptr; SliceCache cache; - TF1* funcDcaXYPtCutPrimTrk = nullptr; + std::unique_ptr funcDcaXYPtCutPrimTrk{nullptr}; using RecoCollisions = soa::Join; using McCandsDs = soa::Filtered>; @@ -150,7 +153,6 @@ struct HfTaskCorrelationsEfficiencies { PresliceUnsorted colPerMcCollision = aod::mccollisionlabel::mcCollisionId; - ConfigurableAxis binsInvMass{"binsInvMass", {600, 1.6, 2.2}, ""}; ConfigurableAxis binsPtCharm{"binsPtCharm", {VARIABLE_WIDTH, 0., 2., 4., 6., 8., 24.}, ""}; ConfigurableAxis binsPtAssoc{"binsPtAssoc", {20, 0, 10}, ""}; ConfigurableAxis binsZVtx{"binsZVtx", {120, -11, 11}, ""}; @@ -168,41 +170,6 @@ struct HfTaskCorrelationsEfficiencies { ccdb->setURL(ccdbUrl); ccdb->setCaching(true); ccdb->setLocalObjectValidityChecking(); - ccdb->setCreatedNotAfter(ccdbNoLaterThan.value); - - // Fetch CCDB correction histograms for efficiency validation - if (runEfficiencyValidation && loadAccXEffFromCCDB) { - - mRecoPrompt = std::shared_ptr(ccdb->getForTimeStamp(Form("%s/PromptReco.root", promptEffPath.value.c_str()), timestampCcdb)); - if (mRecoPrompt == nullptr) { - LOGF(fatal, "Could not load efficiency histogram for trigger particles from %s", promptEffPath.value.c_str()); - } - mGenPrompt = std::shared_ptr(ccdb->getForTimeStamp(Form("%s/PromptGen.root", promptEffPath.value.c_str()), timestampCcdb)); - if (mGenPrompt == nullptr) { - LOGF(fatal, "Could not load efficiency histogram for trigger particles from %s", promptEffPath.value.c_str()); - } - LOGF(info, "Loaded trigger efficiency (prompt D) histogram from %s", promptEffPath.value.c_str()); - - mRecoFD = std::shared_ptr(ccdb->getForTimeStamp(Form("%s/FDReco.root", fdEffPath.value.c_str()), timestampCcdb)); - if (mRecoFD == nullptr) { - LOGF(fatal, "Could not load efficiency histogram for trigger particles from %s", fdEffPath.value.c_str()); - } - mGenFD = std::shared_ptr(ccdb->getForTimeStamp(Form("%s/FDGen.root", fdEffPath.value.c_str()), timestampCcdb)); - if (mGenFD == nullptr) { - LOGF(fatal, "Could not load efficiency histogram for trigger particles from %s", fdEffPath.value.c_str()); - } - LOGF(info, "Loaded feed-down D meson efficiency histogram from %s", fdEffPath.value.c_str()); - - mRecoAssTrk = std::shared_ptr(ccdb->getForTimeStamp(Form("%s/TracksReco.root", assTrkEffPath.value.c_str()), timestampCcdb)); - if (mRecoAssTrk == nullptr) { - LOGF(fatal, "Could not load efficiency histogram for associated particles from %s", assTrkEffPath.value.c_str()); - } - mGenAssTrk = std::shared_ptr(ccdb->getForTimeStamp(Form("%s/TracksGen.root", assTrkEffPath.value.c_str()), timestampCcdb)); - if (mGenAssTrk == nullptr) { - LOGF(fatal, "Could not load efficiency histogram for associated particles from %s", assTrkEffPath.value.c_str()); - } - LOGF(info, "Loaded associated efficiency histogram from %s", assTrkEffPath.value.c_str()); - } std::vector classesMl; for (const auto scoreClass : classMl.value) { @@ -222,22 +189,13 @@ struct HfTaskCorrelationsEfficiencies { // Setup pt-dependent DCAxy cut function if (usePtDiffDcaXYCut) { - funcDcaXYPtCutPrimTrk = new TF1("funcDcaXYPtCutPrimTrk", Form("[0]*%s", dcaXYPtPrimTrkFunc.value.data()), 0.001, 100); + funcDcaXYPtCutPrimTrk = std::make_unique("funcDcaXYPtCutPrimTrk", Form("[0]*%s", dcaXYPtPrimTrkFunc.value.data()), 0.001, 100.); funcDcaXYPtCutPrimTrk->SetParameter(0, dcaXYTrkNSigmaMax); LOGF(info, "DCAxy pt-dependence function: %s", Form("[0]*%s", dcaXYPtPrimTrkFunc.value.data())); } - if (((binsPtCharm.value.size() - 1) != (bdtScore0PtMaxs.value.size() + 1) || - (binsPtCharm.value.size() - 1) != (bdtScore1PtMins.value.size() + 1))) { - LOG(info) << "binsPtCharm.value.size(): " << binsPtCharm.value.size(); - LOG(info) << "bdtScore0PtMaxs.value.size(): " << bdtScore0PtMaxs.value.size(); - LOG(info) << "bdtScore1PtMins.value.size(): " << bdtScore1PtMins.value.size(); - LOGP(fatal, "The size of bdtScore0PtMaxs and bdtScore1PtMins must be the one of binsPtCharm minus one!"); - } - // Add efficiency sparses // Axes: mass, pt, pv contributors, pseudo-rapidity, ml_score_0, ml_score_1 - const AxisSpec axisInvMass = {binsInvMass, "Mass (GeV/c^{2})"}; const AxisSpec axisPtTrig = {binsPtCharm, "#it{p}_{T} Trig (GeV/#it{c})"}; const AxisSpec axisPvContrib = {binsPvContrib, "PV contributors"}; const AxisSpec axisEtaTrig = {binsEta, "#it{#eta}"}; @@ -250,68 +208,31 @@ struct HfTaskCorrelationsEfficiencies { registry.add("hCharmFdGen", "Generated non-prompt charm-hadron candidates;;", {HistType::kTHnSparseF}, {{axisPtTrig}, {axisEtaTrig}, {axisPhiTrig}}); registry.add("hCharmPromptReco", "Reconstructed prompt charm-hadron candidates;;", {HistType::kTHnSparseF}, axesCharmReco); registry.add("hCharmFdReco", "Reconstructed non-prompt charm-hadron candidates;;", {HistType::kTHnSparseF}, axesCharmReco); - if (runEfficiencyValidation) { - registry.add("hCharmPromptRecoPtRew", "Reconstructed prompt charm-hadron candidates;;", {HistType::kTHnSparseF}, axesCharmReco); - registry.add("hCharmFdRecoPtRew", "Reconstructed non-prompt charm-hadron candidates;;", {HistType::kTHnSparseF}, axesCharmReco); - registry.get(HIST("hCharmPromptRecoPtRew"))->Sumw2(); - registry.get(HIST("hCharmFdRecoPtRew"))->Sumw2(); - } // Axes: pt, eta, phi, z_vtx, specie const AxisSpec axisPtAssoc = {binsPtAssoc, "#it{p}_{T} Assoc (GeV/#it{c})"}; const AxisSpec axisEtaAssoc = {binsEta, "#it{#eta}"}; const AxisSpec axisPhiAssoc = {binsPhi, "#it{#varphi}"}; const AxisSpec axisZVtx = {binsZVtx, "#it{z}_{vtx}"}; - const AxisSpec axisAssTrkSpecie = {static_cast(NAssTracksTypes), - -0.5, static_cast(NAssTracksTypes) - 0.5, - "Particle species"}; + const AxisSpec axisAssTrkSpecie = {static_cast(NAssTracksTypes), -0.5, static_cast(NAssTracksTypes) - 0.5, "Particle species"}; const AxisSpec axisTrackOrigin = {2, -0.5, 1.5, "Particle origin"}; std::vector axesAssocTracks = {axisPtAssoc, axisEtaAssoc, axisPhiAssoc, axisZVtx, axisAssTrkSpecie, axisTrackOrigin}; registry.add("hAssTrackReco", "Reconstructed associated tracks;;", {HistType::kTHnSparseF}, axesAssocTracks); - if (runEfficiencyValidation) { - registry.add("hAssTrackRecoPtRew", "Reconstructed associated tracks;;", {HistType::kTHnSparseF}, axesAssocTracks); - registry.get(HIST("hAssTrackRecoPtRew"))->Sumw2(); - if (loadAccXEffFromCCDB) { - registry.add("hAssTrackRecoPtEtaRew", "Reconstructed associated tracks;;", {HistType::kTHnSparseF}, axesAssocTracks); - registry.add("hAssTrackRecoPtEtaPhiRew", "Reconstructed associated tracks;;", {HistType::kTHnSparseF}, axesAssocTracks); - registry.add("hAssTrackRecoPtEtaPhiZVtxRew", "Reconstructed associated tracks;;", {HistType::kTHnSparseF}, axesAssocTracks); - registry.get(HIST("hAssTrackRecoPtEtaRew"))->Sumw2(); - registry.get(HIST("hAssTrackRecoPtEtaPhiRew"))->Sumw2(); - registry.get(HIST("hAssTrackRecoPtEtaPhiZVtxRew"))->Sumw2(); - } - } registry.add("hAssTrackGen", "Generated associated tracks;;", {HistType::kTHnSparseF}, axesAssocTracks); - } // end init - - /// Apply pT-differential ML BDT bkg score cut - /// \param ptTrig is the pT of the charm candidate - template - bool isSelBdtScoreCut(TCand const& cand, - double ptTrig) - { - std::array outputMl = hfcFlowHelper.getCandMlScores(cand); - for (size_t iPt = 0; iPt < binsPtCharm.value.size() - 1; iPt++) { - if (ptTrig >= binsPtCharm.value[iPt] && ptTrig < binsPtCharm.value[iPt + 1]) { - return (outputMl[0] < bdtScore0PtMaxs.value[iPt]) && (outputMl[1] > bdtScore1PtMins.value[iPt]); - } - } - return false; } - /// Match associated tracks based on their PDG code + /// Match charm-hadron based on its reconstruction flag /// \param assTrk is the associated track /// \return the associated track specie index template bool isMcMatched(TCharmHad const& cand) { - int flagMc{-1}, resoChannel{-1}; + int flagMc{-1}; if constexpr (IsReco) { flagMc = std::abs(cand.flagMcMatchRec()); - resoChannel = std::abs(cand.flagMcDecayChanRec()); } else { flagMc = std::abs(cand.flagMcMatchGen()); - resoChannel = std::abs(cand.flagMcDecayChanGen()); } if constexpr (CandType == TriggerChannels::D0ToPiK) { @@ -332,7 +253,7 @@ struct HfTaskCorrelationsEfficiencies { } } - /// Fill histograms and tables for same-event correlations + /// Fill info for charm-hadron efficiencies /// \param trigCands are the trigger candidates /// \param assTrks are the associated tracks /// \param cent is the collision centrality @@ -345,8 +266,7 @@ struct HfTaskCorrelationsEfficiencies { continue; } - int channel = isMcMatched(cand); - if (channel < 0) { + if (!isMcMatched(cand)) { continue; } @@ -358,87 +278,16 @@ struct HfTaskCorrelationsEfficiencies { if (cand.originMcRec() == RecoDecay::OriginType::NonPrompt) { registry.fill(HIST("hCharmFdReco"), cand.pt(), numContrib, cand.eta(), cand.phi(), outputMl[0], outputMl[1]); } - } - } - - template - double getCharmEffWeight(const TCharmCand& charmCand, bool isPrompt) - { - double eff = 1.; - double pt = charmCand.pt(); - if (loadAccXEffFromCCDB) { - - int ptBin = o2::analysis::findBin(binsPtCharm, pt); - double mlScore0Max = bdtScore0PtMaxs.value[ptBin]; - double mlScore1Min = bdtScore1PtMins.value[ptBin]; - - if (isPrompt) { - - int const sparsePtBin = mRecoPrompt->GetAxis(kAxisPtTrig)->FindBin(pt); - mRecoPrompt->GetAxis(kAxisPtTrig)->SetRange(sparsePtBin, sparsePtBin); - mRecoPrompt->GetAxis(kAxisMlScore0)->SetRangeUser(0., mlScore0Max); - mRecoPrompt->GetAxis(kAxisMlScore1)->SetRangeUser(mlScore1Min, 1.); - mGenPrompt->GetAxis(kAxisPtTrig)->SetRange(sparsePtBin, sparsePtBin); - eff = mRecoPrompt->Integral(kTRUE) / mGenPrompt->Integral(kTRUE); - - // Restore axes to full range - for (int i = 0; i < mRecoPrompt->GetNdimensions(); ++i) mRecoPrompt->GetAxis(i)->SetRange(0, 0); - for (int i = 0; i < mGenPrompt->GetNdimensions(); ++i) mGenPrompt->GetAxis(i)->SetRange(0, 0); - - } else { - - int const sparsePtBin = mRecoFD->GetAxis(kAxisPtTrig)->FindBin(pt); - mRecoFD->GetAxis(kAxisPtTrig)->SetRange(sparsePtBin, sparsePtBin); - mRecoFD->GetAxis(kAxisMlScore0)->SetRangeUser(0., mlScore0Max); - mRecoFD->GetAxis(kAxisMlScore1)->SetRangeUser(mlScore1Min, 1.); - mGenFD->GetAxis(kAxisPtTrig)->SetRange(sparsePtBin, sparsePtBin); - eff = mRecoFD->Integral(kTRUE) / mGenFD->Integral(kTRUE); - - // Restore axes to full range - for (int i = 0; i < mRecoFD->GetNdimensions(); ++i) mRecoFD->GetAxis(i)->SetRange(0, 0); - for (int i = 0; i < mGenFD->GetNdimensions(); ++i) mGenFD->GetAxis(i)->SetRange(0, 0); - - } - - } else { - int const bin = o2::analysis::findBin(binsPtEffCharm, pt); - eff = isPrompt ? effPromptCharm->at(bin) : effFdCharm->at(bin); - } - - return 1 / eff; - } - - /// Fill histograms and tables for same-event correlations - /// \param trigCands are the trigger candidates - /// \param assTrks are the associated tracks - /// \param cent is the collision centrality - /// \param mult is the collision multiplicity - template - void validateCharmEfficiencies(TCharmCands const& charmCands) - { - for (const auto& charmCand : charmCands) { - if (!hfcFlowHelper.cutCandRapidity(charmCand)) { - continue; - } - - int channel = isMcMatched(charmCand); - if (channel < 0) { - continue; - } - if (!isSelBdtScoreCut(charmCand, charmCand.pt())) { - continue; - } - // Fill the sparse - std::array outputMl = hfcFlowHelper.getCandMlScores(charmCand); - bool isPrompt = (charmCand.originMcRec() == RecoDecay::OriginType::Prompt); - double effWeight = getCharmEffWeight(charmCand, isPrompt); - if (isPrompt) { - registry.fill(HIST("hCharmPromptRecoPtRew"), charmCand.pt(), charmCand.template collision_as().numContrib(), - charmCand.eta(), charmCand.phi(), outputMl[0], outputMl[1], effWeight); - } else { - registry.fill(HIST("hCharmFdRecoPtRew"), charmCand.pt(), charmCand.template collision_as().numContrib(), - charmCand.eta(), charmCand.phi(), outputMl[0], outputMl[1], effWeight); + if (fillRecoTrees) { + // Downsample charm candidates based on pt + if (downSampleCharm < 1.) { + float const pseudoRndm = cand.pt() * 1000. - static_cast(cand.pt() * 1000); + if (cand.pt() < ptMaxDownSampleCharm && pseudoRndm >= downSampleCharm) { + continue; + } + } + rowTrigMc(cand.pt(), numContrib, cand.eta(), cand.phi(), cand.originMcRec(), outputMl[0], outputMl[1]); } } } @@ -459,9 +308,6 @@ struct HfTaskCorrelationsEfficiencies { continue; } fillCharmEfficiencies(candsInColl, coll.numContrib()); - if (runEfficiencyValidation) { - validateCharmEfficiencies(candsInColl); - } } for (const auto& genCand : genParticles) { @@ -471,8 +317,7 @@ struct HfTaskCorrelationsEfficiencies { if (std::abs(genCand.y()) > yCandMax) { continue; } - int channel = isMcMatched(genCand); - if (channel < 0) { + if (!isMcMatched(genCand)) { continue; } @@ -484,7 +329,7 @@ struct HfTaskCorrelationsEfficiencies { } } } - PROCESS_SWITCH(HfTaskCorrelationsEfficiencies, processEffDplus, "Process efficiencies for Dplus candidates", true); + PROCESS_SWITCH(HfTaskCorrelationsEfficiencies, processEffDplus, "Process efficiencies for Dplus candidates", false); /// Match associated tracks based on their PDG code /// \param assTrk is the associated track @@ -519,6 +364,9 @@ struct HfTaskCorrelationsEfficiencies { if (!hfcFlowHelper.checkCollision(coll, cent, mult)) { continue; } + if (!coll.has_mcCollision()) { + continue; + } auto mcCollision = coll.template mcCollision_as(); auto tracksInColl = recoTracks.sliceBy(trackIndicesPerColl, coll.globalIndex()); @@ -542,53 +390,21 @@ struct HfTaskCorrelationsEfficiencies { } int assTrkOrigin = mcParticle.isPhysicalPrimary() ? 0 : 1; // 0 for primary, 1 for secondary - std::vector values = {mcParticle.pt(), mcParticle.eta(), mcParticle.phi(), mcCollision.posZ(), static_cast(matchedSpecie), static_cast(assTrkOrigin)}; + std::vector values = {assTrk.pt(), assTrk.eta(), assTrk.phi(), mcCollision.posZ(), static_cast(matchedSpecie), static_cast(assTrkOrigin)}; // Fill histograms for associated tracks registry.get(HIST("hAssTrackReco"))->Fill(values.data()); - // Fill histograms for efficiency validation if enabled - if (runEfficiencyValidation) { - - float effWeightPt{1.f}; - if (!loadAccXEffFromCCDB) { - int const bin = o2::analysis::findBin(binsPtEffAssTrk, assTrkPt); - effWeightPt = 1. / effAssTrk->at(bin); - } else { - - float effWeightPtEta{1.f}, effWeightPtEtaPhi{1.f}, effWeightPtEtaPhiZVtx{1.f}; - - // Pt-reweighting - mRecoAssTrk->GetAxis(kAxisPtAssoc)->SetRangeUser(assTrkPt, assTrkPt); - mGenAssTrk->GetAxis(kAxisPtAssoc)->SetRangeUser(assTrkPt, assTrkPt); - effWeightPt = mRecoAssTrk->Integral(kTRUE) > 0 ? mGenAssTrk->Integral(kTRUE) / mRecoAssTrk->Integral(kTRUE) : 0; - - // Pt-eta-reweighting - mRecoAssTrk->GetAxis(kAxisEtaAssoc)->SetRangeUser(mcParticle.eta(), mcParticle.eta()); - mGenAssTrk->GetAxis(kAxisEtaAssoc)->SetRangeUser(mcParticle.eta(), mcParticle.eta()); - effWeightPtEta = mRecoAssTrk->Integral(kTRUE) > 0 ? mGenAssTrk->Integral(kTRUE) / mRecoAssTrk->Integral(kTRUE) : 0; - - // Pt-eta-phi-reweighting - mRecoAssTrk->GetAxis(kAxisPhiAssoc)->SetRangeUser(mcParticle.phi(), mcParticle.phi()); - mGenAssTrk->GetAxis(kAxisPhiAssoc)->SetRangeUser(mcParticle.phi(), mcParticle.phi()); - effWeightPtEtaPhi = mRecoAssTrk->Integral(kTRUE) > 0 ? mGenAssTrk->Integral(kTRUE) / mRecoAssTrk->Integral(kTRUE) : 0; - - // Pt-eta-phi-zvtx-reweighting - mRecoAssTrk->GetAxis(kAxisZVtx)->SetRangeUser(mcCollision.posZ(), mcCollision.posZ()); - mGenAssTrk->GetAxis(kAxisZVtx)->SetRangeUser(mcCollision.posZ(), mcCollision.posZ()); - effWeightPtEtaPhiZVtx = mRecoAssTrk->Integral(kTRUE) > 0 ? mGenAssTrk->Integral(kTRUE) / mRecoAssTrk->Integral(kTRUE) : 0; - - // Restore axes to full range - for (int i = 0; i < mRecoAssTrk->GetNdimensions(); ++i) mRecoAssTrk->GetAxis(i)->SetRange(0, 0); - for (int i = 0; i < mGenAssTrk->GetNdimensions(); ++i) mGenAssTrk->GetAxis(i)->SetRange(0, 0); - - registry.get(HIST("hAssTrackRecoPtEtaRew"))->Fill(values.data(), effWeightPtEta); - registry.get(HIST("hAssTrackRecoPtEtaPhiRew"))->Fill(values.data(), effWeightPtEtaPhi); - registry.get(HIST("hAssTrackRecoPtEtaPhiZVtxRew"))->Fill(values.data(), effWeightPtEtaPhiZVtx); + if (fillRecoTrees) { + // Downsample tracks based on pt + if (downSampleTracks < 1.) { + float const pseudoRndm = assTrk.pt() * 1000. - static_cast(assTrk.pt() * 1000); + if (assTrk.pt() < ptMaxDownSampleTracks && pseudoRndm >= downSampleTracks) { + continue; + } } - - registry.get(HIST("hAssTrackRecoPtRew"))->Fill(values.data(), effWeightPt); - + rowAssocMc(assTrk.pt(), assTrk.eta(), assTrk.phi(), mcCollision.posZ(), matchedSpecie, assTrkOrigin); + rowAssocTrkSels(assTrk.tpcNClsCrossedRows(), assTrk.itsClusterMap(), assTrk.itsNCls(), assTrk.dcaXY(), assTrk.dcaZ()); } } } @@ -599,6 +415,9 @@ struct HfTaskCorrelationsEfficiencies { if (matchedSpecie < 0) { continue; } + if (!genTrk.has_mcCollision()) { + continue; + } // Pt and eta selection if (genTrk.pt() < ptTrkMin || genTrk.pt() > ptTrkMax || std::fabs(genTrk.eta()) > etaTrkMax) { From 14be999cf712490b62bbb7dc99d0a54d8ccda840 Mon Sep 17 00:00:00 2001 From: Marcello Di Costanzo Date: Thu, 5 Nov 2026 17:05:21 +0100 Subject: [PATCH 03/18] Implement CCDB histogram loading --- .../correlatorFlowCharmHadronsReduced.cxx | 76 +++++++------ .../derivedDataCreatorCorrelationsReduced.cxx | 104 +++++++++--------- 2 files changed, 95 insertions(+), 85 deletions(-) diff --git a/PWGHF/HFC/TableProducer/correlatorFlowCharmHadronsReduced.cxx b/PWGHF/HFC/TableProducer/correlatorFlowCharmHadronsReduced.cxx index e06fc024adf..b6d8857069f 100644 --- a/PWGHF/HFC/TableProducer/correlatorFlowCharmHadronsReduced.cxx +++ b/PWGHF/HFC/TableProducer/correlatorFlowCharmHadronsReduced.cxx @@ -171,16 +171,16 @@ struct HfCorrelatorFlowCharmHadronsReduced { switch (histoType) { case kTH1: - object = ccdb->getForTimeStamp(path, timestampCcdb); + object = ccdb->getForTimeStamp(Form("%s/TH1/", path.c_str()), timestampCcdb); break; case kTH2: - object = ccdb->getForTimeStamp(path, timestampCcdb); + object = ccdb->getForTimeStamp(Form("%s/TH2/", path.c_str()), timestampCcdb); break; case kTH3: - object = ccdb->getForTimeStamp(path, timestampCcdb); + object = ccdb->getForTimeStamp(Form("%s/TH3/", path.c_str()), timestampCcdb); break; case kTHnSparse: - object = ccdb->getForTimeStamp(path, timestampCcdb); + object = ccdb->getForTimeStamp(Form("%s/THnSparse/", path.c_str()), timestampCcdb); break; default: LOGF(fatal, "Invalid efficiency histogram type: %d", histoType); @@ -202,14 +202,6 @@ struct HfCorrelatorFlowCharmHadronsReduced { LOGP(fatal, "You must select events based on either centrality or multiplicity! Please check your configuration!"); } - // Fatal if selCentrality and process functions using multiplicity mixing, or selMultiplicity and process functions using centrality mixing - if (selCentrality && (doprocessSECharmHadWMultMix || doprocessMECharmHadWMultMix || doprocessSEHadHadWMultMix || doprocessMEHadHadWMultMix)) { - LOGP(fatal, "You cannot select events based on centrality and process functions using multiplicity mixing! Please check your configuration!"); - } - if (selMultiplicity && (doprocessSECharmHadWCentMix || doprocessMECharmHadWCentMix || doprocessSEHadHadWCentMix || doprocessMEHadHadWCentMix)) { - LOGP(fatal, "You cannot select events based on multiplicity and process functions using centrality mixing! Please check your configuration!"); - } - if ((doprocessSECharmHadWCentMix && doprocessMECharmHadWMultMix) || (doprocessSECharmHadWMultMix && doprocessMECharmHadWCentMix) || (doprocessSEHadHadWCentMix && doprocessMEHadHadWMultMix) || @@ -245,13 +237,13 @@ struct HfCorrelatorFlowCharmHadronsReduced { const AxisSpec axisMlTwo{binsMlTwo, "bdtScore1"}; // Histograms for data analysis - if (doprocessSECharmHadWCentMix || doprocessSEHadHadWCentMix) { + if (doprocessSECharmHadWCentMix || doprocessSECharmHadWCentMixWEffInfo || doprocessSEHadHadWCentMix) { registry.add("hCentPoolBinSE", "Centrality SE", {HistType::kTH2F, {{axisCent}, {axisPoolBin}}}); - } else if (doprocessSECharmHadWMultMix || doprocessSEHadHadWMultMix) { + } else if (doprocessSECharmHadWMultMix || doprocessSECharmHadWMultMixWEffInfo || doprocessSEHadHadWMultMix) { registry.add("hMultFT0MPoolBinSE", "Multiplicity FT0M SE", {HistType::kTH2F, {{axisMultFT0M}, {axisPoolBin}}}); - } else if (doprocessMECharmHadWCentMix || doprocessMEHadHadWCentMix) { + } else if (doprocessMECharmHadWCentMix || doprocessMECharmHadWCentMixWEffInfo || doprocessMEHadHadWCentMix) { registry.add("hCentPoolBinME", "Centrality ME", {HistType::kTH2F, {{axisCent}, {axisPoolBin}}}); - } else if (doprocessMECharmHadWMultMix || doprocessMEHadHadWMultMix) { + } else if (doprocessMECharmHadWMultMix || doprocessMECharmHadWMultMixWEffInfo || doprocessMEHadHadWMultMix) { registry.add("hMultFT0MPoolBinME", "Multiplicity FT0M ME", {HistType::kTH2F, {{axisMultFT0M}, {axisPoolBin}}}); } registry.add("hZVtxPoolBinSE", "z vertex SE", {HistType::kTH2F, {{axisPosZ}, {axisPoolBin}}}); @@ -277,24 +269,29 @@ struct HfCorrelatorFlowCharmHadronsReduced { } } else { axes.insert(axes.end(), {axisInvMass, axisMlOne, axisMlTwo}); - if (doprocessSECharmHadWCentMix || doprocessSECharmHadWMultMix) { + if (doprocessSECharmHadWCentMix || doprocessSECharmHadWCentMixWEffInfo || doprocessSECharmHadWMultMix || doprocessSECharmHadWMultMixWEffInfo) { registry.add("hSparseCorrelationsSECharmHad", "THn for SE Charm-Had correlations", HistType::kTHnSparseF, axes); if (doEfficiencyCorrection) { registry.get(HIST("hSparseCorrelationsSECharmHad"))->Sumw2(); } - } else if (doprocessMECharmHadWCentMix || doprocessMECharmHadWMultMix) { + } else if (doprocessMECharmHadWCentMix || doprocessMECharmHadWMultMixWEffInfo || doprocessMECharmHadWMultMix || doprocessMECharmHadWCentMixWEffInfo) { registry.add("hSparseCorrelationsMECharmHad", "THn for ME Charm-Had correlations", HistType::kTHnSparseF, axes); if (doEfficiencyCorrection) { registry.get(HIST("hSparseCorrelationsMECharmHad"))->Sumw2(); } } - if (doprocessCharmTriggers) { + if (doprocessCharmTriggers || doprocessCharmTriggersWEffInfo) { registry.add("hSparseTrigCandsCharm", "THn for Charm trigger candidates", HistType::kTHnSparseF, axesTrigger); if (doEfficiencyCorrection) { registry.get(HIST("hSparseTrigCandsCharm"))->Sumw2(); } } } + + if (doEfficiencyCorrection) { + hEffPrompt = loadEfficiencyHistogram(promptEffCcdbPath, effHistTypeCharm); + hEffAssoc = loadEfficiencyHistogram(assocEffCcdbPath, effHistTypeAssoc); + } } template @@ -315,17 +312,6 @@ struct HfCorrelatorFlowCharmHadronsReduced { kineFeatures = {cand.ptAssoc(), cand.etaAssoc(), cand.phiAssoc(), collision.posZ()}; } - // // Charm triggers - // {ptTrig, trigCand.bdtScore0Trig(), trigCand.bdtScore1Trig(), trigCand.etaTrig(), trigCand.phiTrig()} - // {ptTrig, trigCand.bdtScore0Trig(), trigCand.bdtScore1Trig(), getEta(trigCand), getPhi(trigCand)} - // {trigCand.ptTrig(), trigCand.bdtScore0Trig(), trigCand.bdtScore1Trig(), trigCand.etaTrig(), trigCand.phiTrig()} - // // Had triggers - // {ptTrig, trigCand.etaTrig(), trigCand.phiTrig(), collision.posZ()} - // {ptTrig, getEta(trigCand), getPhi(trigCand), trigColl.posZ()} - // // Had associated tracks - // {pair.ptAssoc(), pair.etaAssoc(), pair.phiAssoc(), collision.posZ()} - // {getPt(assocTrack), getEta(assocTrack), getPhi(assocTrack), assocColl.posZ()} - switch (histoType) { case kTH1: { @@ -661,7 +647,7 @@ struct HfCorrelatorFlowCharmHadronsReduced { auto trigCand = pair.template hfcRedTrigCharm_as(); fillSameEvent(pair, trigCand, binPolicyPosZCent); } - PROCESS_SWITCH(HfCorrelatorFlowCharmHadronsReduced, processSECharmHadWCentMixWEffInfo, "Process Same Event for Charm-Had with centrality pools", true); + PROCESS_SWITCH(HfCorrelatorFlowCharmHadronsReduced, processSECharmHadWCentMixWEffInfo, "Process Same Event for Charm-Had with centrality pools", false); void processSEHadHadWCentMix(SameEvtPairsHadHad::iterator const& pair, aod::HfcRedTrigTracks const&, @@ -684,9 +670,20 @@ struct HfCorrelatorFlowCharmHadronsReduced { } PROCESS_SWITCH(HfCorrelatorFlowCharmHadronsReduced, processMECharmHadWCentMix, "Process Mixed Event for Charm-Had with centrality pools", false); - void processMECharmHadWMultMix(aod::HfcRedCorrColls const& collisions, + void processMECharmHadWCentMixWEffInfo(aod::HfcRedCorrColls const& collisions, TrigCharmCands const& candidates, AssocTracks const& tracks) + { + BinningCentPosZ binPolicyPosZCent{{binsZPool, binsCentPool}}; + auto pairsTuple = std::make_tuple(candidates, tracks); + Pair const pairs{binPolicyPosZCent, numberEventsMixed, -1, collisions, pairsTuple, &cache}; + fillMixedEvent(pairs, binPolicyPosZCent); + } + PROCESS_SWITCH(HfCorrelatorFlowCharmHadronsReduced, processMECharmHadWCentMixWEffInfo, "Process Mixed Event for Charm-Had with centrality pools and efficiency information", false); + + void processMECharmHadWMultMix(aod::HfcRedCorrColls const& collisions, + TrigCharmCands const& candidates, + AssocTracks const& tracks) { BinningMultPosZ binPolicyPosZMult{{binsZPool, binsMultPool}}; auto pairsTuple = std::make_tuple(candidates, tracks); @@ -695,6 +692,17 @@ struct HfCorrelatorFlowCharmHadronsReduced { } PROCESS_SWITCH(HfCorrelatorFlowCharmHadronsReduced, processMECharmHadWMultMix, "Process Mixed Event for Charm-Had with multiplicity pools", false); + void processMECharmHadWMultMixWEffInfo(aod::HfcRedCorrColls const& collisions, + TrigCharmCands const& candidates, + AssocTracks const& tracks) + { + BinningMultPosZ binPolicyPosZMult{{binsZPool, binsMultPool}}; + auto pairsTuple = std::make_tuple(candidates, tracks); + Pair const pairs{binPolicyPosZMult, numberEventsMixed, -1, collisions, pairsTuple, &cache}; + fillMixedEvent(pairs, binPolicyPosZMult); + } + PROCESS_SWITCH(HfCorrelatorFlowCharmHadronsReduced, processMECharmHadWMultMixWEffInfo, "Process Mixed Event for Charm-Had with multiplicity pools and efficiency information", false); + void processMEHadHadWCentMix(aod::HfcRedCorrColls const& collisions, AssocTracks const& tracks) { @@ -728,7 +736,7 @@ struct HfCorrelatorFlowCharmHadronsReduced { continue; } - std::vector values = {trigCand.ptTrig(), trigCand.invMassTrig(), trigCand.bdtScore0Trig(), trigCand.bdtScore1Trig()}; + std::vector values = {trigCand.invMassTrig(), trigCand.ptTrig(), trigCand.bdtScore0Trig(), trigCand.bdtScore1Trig()}; registry.get(HIST("hSparseTrigCandsCharm"))->Fill(values.data()); } } @@ -752,7 +760,7 @@ struct HfCorrelatorFlowCharmHadronsReduced { LOGF(warn, "Invalid efficiency value for trigger candidate: effTrig = %f", effTrig); continue; } - std::vector values = {trigCand.ptTrig(), trigCand.invMassTrig(), trigCand.bdtScore0Trig(), trigCand.bdtScore1Trig()}; + std::vector values = {trigCand.invMassTrig(), trigCand.ptTrig(), trigCand.bdtScore0Trig(), trigCand.bdtScore1Trig()}; double weight = doEfficiencyCorrection ? 1. / effTrig : 1.; registry.get(HIST("hSparseTrigCandsCharm"))->Fill(values.data(), weight); } diff --git a/PWGHF/HFC/TableProducer/derivedDataCreatorCorrelationsReduced.cxx b/PWGHF/HFC/TableProducer/derivedDataCreatorCorrelationsReduced.cxx index 75eb9ba2d61..a6e34ed6efb 100644 --- a/PWGHF/HFC/TableProducer/derivedDataCreatorCorrelationsReduced.cxx +++ b/PWGHF/HFC/TableProducer/derivedDataCreatorCorrelationsReduced.cxx @@ -143,7 +143,7 @@ struct HfDerivedDataCreatorCorrelationsReduced { Partition recoSelD0ToPiK = (nabs(aod::hf_cand_mc_flag::flagMcMatchRec) == static_cast(hf_cand_2prong::DecayChannelMain::D0ToPiK)) && aod::hf_sel_candidate_d0::isSelD0 >= selectionFlag && ((!acceptOnlyPrompt) || (acceptOnlyPrompt && aod::hf_cand_mc_flag::originMcRec == static_cast(RecoDecay::OriginType::Prompt))); Partition recoSelD0ToKPi = (nabs(aod::hf_cand_mc_flag::flagMcMatchRec) == static_cast(hf_cand_2prong::DecayChannelMain::D0ToPiK)) && aod::hf_sel_candidate_d0::isSelD0bar >= selectionFlag && ((!acceptOnlyPrompt) || (acceptOnlyPrompt && aod::hf_cand_mc_flag::originMcRec == static_cast(RecoDecay::OriginType::Prompt))); - Partition recoSelDPlusCandidates = (nabs(aod::hf_cand_mc_flag::flagMcMatchRec) == static_cast(hf_cand_3prong::DecayChannelMain::DplusToPiKPi)) && aod::hf_sel_candidate_dplus::isSelDplusToPiKPi >= selectionFlag && ((!acceptOnlyPrompt) || (acceptOnlyPrompt && aod::hf_cand_mc_flag::originMcRec == static_cast(RecoDecay::OriginType::Prompt))); + Partition recoSelDPlusToPiKPi = (nabs(aod::hf_cand_mc_flag::flagMcMatchRec) == static_cast(hf_cand_3prong::DecayChannelMain::DplusToPiKPi)) && aod::hf_sel_candidate_dplus::isSelDplusToPiKPi >= selectionFlag && ((!acceptOnlyPrompt) || (acceptOnlyPrompt && aod::hf_cand_mc_flag::originMcRec == static_cast(RecoDecay::OriginType::Prompt))); Partition recoSelDsToKKPi = (nabs(aod::hf_cand_mc_flag::flagMcMatchRec) == static_cast(hf_cand_3prong::DecayChannelMain::DsToPiKK) && nabs(aod::hf_cand_mc_flag::flagMcDecayChanRec) == static_cast(hf_cand_3prong::DecayChannelResonant::DsToPhiPi)) && aod::hf_sel_candidate_ds::isSelDsToKKPi >= selectionFlag && ((!acceptOnlyPrompt) || (acceptOnlyPrompt && aod::hf_cand_mc_flag::originMcRec == static_cast(RecoDecay::OriginType::Prompt))); Partition recoSelDsToPiKK = (nabs(aod::hf_cand_mc_flag::flagMcMatchRec) == static_cast(hf_cand_3prong::DecayChannelMain::DsToPiKK) && nabs(aod::hf_cand_mc_flag::flagMcDecayChanRec) == static_cast(hf_cand_3prong::DecayChannelResonant::DsToPhiPi)) && aod::hf_sel_candidate_ds::isSelDsToPiKK >= selectionFlag && ((!acceptOnlyPrompt) || (acceptOnlyPrompt && aod::hf_cand_mc_flag::originMcRec == static_cast(RecoDecay::OriginType::Prompt))); Partition recoSelLcToPKPi = (nabs(aod::hf_cand_mc_flag::flagMcMatchRec) == static_cast(hf_cand_3prong::DecayChannelMain::LcToPKPi)) && aod::hf_sel_candidate_lc::isSelLcToPKPi >= selectionFlag && ((!acceptOnlyPrompt) || (acceptOnlyPrompt && aod::hf_cand_mc_flag::originMcRec == static_cast(RecoDecay::OriginType::Prompt))); @@ -481,8 +481,8 @@ struct HfDerivedDataCreatorCorrelationsReduced { // CHARM-HADRON CORRELATIONS PROCESS FUNCTIONS --- DATA // Dplus data void processDataDplusSE(DataCollsWithCentMult::iterator const& coll, - CandDplusData const& candsDplus, - TracksData const& tracks) + CandDplusData const& candsDplus, + TracksData const& tracks) { if (forceCharmInCollision && candsDplus.size() < 1) { return; @@ -498,8 +498,8 @@ struct HfDerivedDataCreatorCorrelationsReduced { // Dplus data void processDataDplusME(DataCollsWithCentMult::iterator const& coll, - CandDplusData const& candsDplus, - TracksData const& tracks) + CandDplusData const& candsDplus, + TracksData const& tracks) { if (forceCharmInCollision && candsDplus.size() < 1) { return; @@ -516,8 +516,8 @@ struct HfDerivedDataCreatorCorrelationsReduced { // Ds data void processDataDsSE(DataCollsWithCentMult::iterator const& coll, - TracksData const& tracks, - CandDsData const&) + TracksData const& tracks, + CandDsData const&) { auto candsDsToPiKK = selDsToPiKK->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); auto candsDsToKKPi = selDsToKKPi->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); @@ -536,8 +536,8 @@ struct HfDerivedDataCreatorCorrelationsReduced { // Ds data void processDataDsME(DataCollsWithCentMult::iterator const& coll, - TracksData const& tracks, - CandDsData const&) + TracksData const& tracks, + CandDsData const&) { auto candsDsToPiKK = selDsToPiKK->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); auto candsDsToKKPi = selDsToKKPi->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); @@ -557,8 +557,8 @@ struct HfDerivedDataCreatorCorrelationsReduced { // D0 data void processDataD0SE(DataCollsWithCentMult::iterator const& coll, - TracksData const& tracks, - CandD0Data const&) + TracksData const& tracks, + CandD0Data const&) { auto candsD0ToPiK = selD0ToPiK->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); auto candsD0ToKPi = selD0ToKPi->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); @@ -577,8 +577,8 @@ struct HfDerivedDataCreatorCorrelationsReduced { // D0 data void processDataD0ME(DataCollsWithCentMult::iterator const& coll, - TracksData const& tracks, - CandD0Data const&) + TracksData const& tracks, + CandD0Data const&) { auto candsD0ToPiK = selD0ToPiK->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); auto candsD0ToKPi = selD0ToKPi->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); @@ -641,10 +641,11 @@ struct HfDerivedDataCreatorCorrelationsReduced { // CHARM-HADRON CORRELATIONS PROCESS FUNCTIONS --- MC // Dplus MC void processMcDplusSE(McCollsWithCentMult::iterator const& coll, - CandDplusMc const& candsDplus, - TracksMc const& tracks) + TracksMc const& tracks, + CandDplusMc const&) { - if (forceCharmInCollision && candsDplus.size() < 1) { + auto candsRecoDplus = recoSelDPlusToPiKPi->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); + if (forceCharmInCollision && candsRecoDplus.size() < 1) { return; } float cent{-1.}, mult{-1.}; @@ -652,16 +653,17 @@ struct HfDerivedDataCreatorCorrelationsReduced { return; } rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); - fillSameEvent(candsDplus, tracks, cent, mult); + fillSameEvent(candsRecoDplus, tracks, cent, mult); } PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processMcDplusSE, "Process Same Event for Dplus candidates", false); // Dplus MC void processMcDplusME(McCollsWithCentMult::iterator const& coll, - CandDplusMc const& candsDplus, - TracksMc const& tracks) + TracksMc const& tracks, + CandDplusMc const&) { - if (forceCharmInCollision && candsDplus.size() < 1) { + auto candsRecoDplus = recoSelDPlusToPiKPi->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); + if (forceCharmInCollision && candsRecoDplus.size() < 1) { return; } float cent{-1.}, mult{-1.}; @@ -669,7 +671,7 @@ struct HfDerivedDataCreatorCorrelationsReduced { return; } rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); - fillCharmMixedEvent(candsDplus); + fillCharmMixedEvent(candsRecoDplus); fillTrkMixedEvent(tracks, cent, mult); } PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processMcDplusME, "Process Mixed Event for Dplus candidates", false); @@ -679,9 +681,9 @@ struct HfDerivedDataCreatorCorrelationsReduced { TracksMc const& tracks, CandDsMc const&) { - auto candsDsToPiKK = recoSelDsToPiKK->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); - auto candsDsToKKPi = recoSelDsToKKPi->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); - if (forceCharmInCollision && candsDsToPiKK.size() < 1 && candsDsToKKPi.size() < 1) { + auto candsRecoDsToPiKK = recoSelDsToPiKK->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); + auto candsRecoDsToKKPi = recoSelDsToKKPi->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); + if (forceCharmInCollision && candsRecoDsToPiKK.size() < 1 && candsRecoDsToKKPi.size() < 1) { return; } float cent{-1.}, mult{-1.}; @@ -689,8 +691,8 @@ struct HfDerivedDataCreatorCorrelationsReduced { return; } rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); - fillSameEvent(candsDsToPiKK, tracks, cent, mult); - fillSameEvent(candsDsToKKPi, tracks, cent, mult); + fillSameEvent(candsRecoDsToPiKK, tracks, cent, mult); + fillSameEvent(candsRecoDsToKKPi, tracks, cent, mult); } PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processMcDsSE, "Process Same Event for Ds candidates", false); @@ -699,9 +701,9 @@ struct HfDerivedDataCreatorCorrelationsReduced { TracksMc const& tracks, CandDsMc const&) { - auto candsDsToPiKK = recoSelDsToPiKK->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); - auto candsDsToKKPi = recoSelDsToKKPi->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); - if (forceCharmInCollision && candsDsToPiKK.size() < 1 && candsDsToKKPi.size() < 1) { + auto candsRecoDsToPiKK = recoSelDsToPiKK->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); + auto candsRecoDsToKKPi = recoSelDsToKKPi->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); + if (forceCharmInCollision && candsRecoDsToPiKK.size() < 1 && candsRecoDsToKKPi.size() < 1) { return; } float cent{-1.}, mult{-1.}; @@ -709,8 +711,8 @@ struct HfDerivedDataCreatorCorrelationsReduced { return; } rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); - fillCharmMixedEvent(candsDsToPiKK); - fillCharmMixedEvent(candsDsToKKPi); + fillCharmMixedEvent(candsRecoDsToPiKK); + fillCharmMixedEvent(candsRecoDsToKKPi); fillTrkMixedEvent(tracks, cent, mult); } PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processMcDsME, "Process Mixed Event for Ds candidates", false); @@ -720,9 +722,9 @@ struct HfDerivedDataCreatorCorrelationsReduced { TracksMc const& tracks, CandD0Mc const&) { - auto candsD0ToPiK = recoSelD0ToPiK->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); - auto candsD0ToKPi = recoSelD0ToKPi->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); - if (forceCharmInCollision && candsD0ToPiK.size() < 1 && candsD0ToKPi.size() < 1) { + auto candsRecoD0ToPiK = recoSelD0ToPiK->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); + auto candsRecoD0ToKPi = recoSelD0ToKPi->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); + if (forceCharmInCollision && candsRecoD0ToPiK.size() < 1 && candsRecoD0ToKPi.size() < 1) { return; } float cent{-1.}, mult{-1.}; @@ -730,8 +732,8 @@ struct HfDerivedDataCreatorCorrelationsReduced { return; } rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); - fillSameEvent(candsD0ToPiK, tracks, cent, mult); - fillSameEvent(candsD0ToKPi, tracks, cent, mult); + fillSameEvent(candsRecoD0ToPiK, tracks, cent, mult); + fillSameEvent(candsRecoD0ToKPi, tracks, cent, mult); } PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processMcD0SE, "Process Same Event for D0 candidates", false); @@ -740,9 +742,9 @@ struct HfDerivedDataCreatorCorrelationsReduced { TracksMc const& tracks, CandD0Mc const&) { - auto candsD0ToPiK = recoSelD0ToPiK->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); - auto candsD0ToKPi = recoSelD0ToKPi->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); - if (forceCharmInCollision && candsD0ToPiK.size() < 1 && candsD0ToKPi.size() < 1) { + auto candsRecoD0ToPiK = recoSelD0ToPiK->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); + auto candsRecoD0ToKPi = recoSelD0ToKPi->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); + if (forceCharmInCollision && candsRecoD0ToPiK.size() < 1 && candsRecoD0ToKPi.size() < 1) { return; } float cent{-1.}, mult{-1.}; @@ -750,8 +752,8 @@ struct HfDerivedDataCreatorCorrelationsReduced { return; } rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); - fillCharmMixedEvent(candsD0ToPiK); - fillCharmMixedEvent(candsD0ToKPi); + fillCharmMixedEvent(candsRecoD0ToPiK); + fillCharmMixedEvent(candsRecoD0ToKPi); fillTrkMixedEvent(tracks, cent, mult); } PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processMcD0ME, "Process Mixed Event for D0 candidates", false); @@ -761,9 +763,9 @@ struct HfDerivedDataCreatorCorrelationsReduced { TracksMc const& tracks, CandLcMc const&) { - auto candsLcToPKPi = recoSelLcToPKPi->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); - auto candsLcToPiKP = recoSelLcToPiKP->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); - if (forceCharmInCollision && candsLcToPKPi.size() < 1 && candsLcToPiKP.size() < 1) { + auto candsRecoLcToPKPi = recoSelLcToPKPi->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); + auto candsRecoLcToPiKP = recoSelLcToPiKP->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); + if (forceCharmInCollision && candsRecoLcToPKPi.size() < 1 && candsRecoLcToPiKP.size() < 1) { return; } float cent{-1.}, mult{-1.}; @@ -771,8 +773,8 @@ struct HfDerivedDataCreatorCorrelationsReduced { return; } rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); - fillSameEvent(candsLcToPKPi, tracks, cent, mult); - fillSameEvent(candsLcToPiKP, tracks, cent, mult); + fillSameEvent(candsRecoLcToPKPi, tracks, cent, mult); + fillSameEvent(candsRecoLcToPiKP, tracks, cent, mult); } PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processMcLcSE, "Process Same Event for Lc candidates", false); @@ -781,9 +783,9 @@ struct HfDerivedDataCreatorCorrelationsReduced { TracksMc const& tracks, CandLcMc const&) { - auto candsLcToPKPi = recoSelLcToPKPi->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); - auto candsLcToPiKP = recoSelLcToPiKP->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); - if (forceCharmInCollision && candsLcToPKPi.size() < 1 && candsLcToPiKP.size() < 1) { + auto candsRecoLcToPKPi = recoSelLcToPKPi->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); + auto candsRecoLcToPiKP = recoSelLcToPiKP->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); + if (forceCharmInCollision && candsRecoLcToPKPi.size() < 1 && candsRecoLcToPiKP.size() < 1) { return; } float cent{-1.}, mult{-1.}; @@ -791,8 +793,8 @@ struct HfDerivedDataCreatorCorrelationsReduced { return; } rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); - fillCharmMixedEvent(candsLcToPKPi); - fillCharmMixedEvent(candsLcToPiKP); + fillCharmMixedEvent(candsRecoLcToPKPi); + fillCharmMixedEvent(candsRecoLcToPiKP); fillTrkMixedEvent(tracks, cent, mult); } PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processMcLcME, "Process Mixed Event for Lc candidates", false); From ec76ec6ac7bc665927dc9faf12c6d46e345a80d3 Mon Sep 17 00:00:00 2001 From: ALICE Action Bot Date: Thu, 5 Nov 2026 16:15:28 +0000 Subject: [PATCH 04/18] Please consider the following formatting changes --- .../correlatorFlowCharmHadronsReduced.cxx | 19 +- .../derivedDataCreatorCorrelationsReduced.cxx | 11 +- .../Tasks/taskCorrelationsEfficiencies.cxx | 19 +- PWGHF/HFC/Utils/utilsFlow.h | 298 +++++++++--------- 4 files changed, 171 insertions(+), 176 deletions(-) diff --git a/PWGHF/HFC/TableProducer/correlatorFlowCharmHadronsReduced.cxx b/PWGHF/HFC/TableProducer/correlatorFlowCharmHadronsReduced.cxx index b6d8857069f..168dc87a9f3 100644 --- a/PWGHF/HFC/TableProducer/correlatorFlowCharmHadronsReduced.cxx +++ b/PWGHF/HFC/TableProducer/correlatorFlowCharmHadronsReduced.cxx @@ -166,7 +166,8 @@ struct HfCorrelatorFlowCharmHadronsReduced { HistogramRegistry registry{"registry", {}, OutputObjHandlingPolicy::AnalysisObject}; - std::shared_ptr loadEfficiencyHistogram(const std::string& path, int histoType) { + std::shared_ptr loadEfficiencyHistogram(const std::string& path, int histoType) + { TObject* object = nullptr; switch (histoType) { @@ -600,8 +601,8 @@ struct HfCorrelatorFlowCharmHadronsReduced { } void processSECharmHadWMultMix(SameEvtPairsChHad::iterator const& pair, - aod::HfcRedTrigCharms const&, - aod::HfcRedCorrColls const&) + aod::HfcRedTrigCharms const&, + aod::HfcRedCorrColls const&) { BinningMultPosZ binPolicyPosZMult{{binsZPool, binsMultPool}}; auto trigCand = pair.template hfcRedTrigCharm_as(); @@ -620,8 +621,8 @@ struct HfCorrelatorFlowCharmHadronsReduced { PROCESS_SWITCH(HfCorrelatorFlowCharmHadronsReduced, processSECharmHadWMultMixWEffInfo, "Process Same Event for Charm-Had with multiplicity pools", false); void processSEHadHadWMultMix(SameEvtPairsHadHad::iterator const& pair, - aod::HfcRedTrigTracks const&, - aod::HfcRedCorrColls const&) + aod::HfcRedTrigTracks const&, + aod::HfcRedCorrColls const&) { BinningMultPosZ binPolicyPosZMult{{binsZPool, binsMultPool}}; auto trigCand = pair.template hfcRedTrigTrack_as(); @@ -630,8 +631,8 @@ struct HfCorrelatorFlowCharmHadronsReduced { PROCESS_SWITCH(HfCorrelatorFlowCharmHadronsReduced, processSEHadHadWMultMix, "Process Same Event for Had-Had with multiplicity pools", false); void processSECharmHadWCentMix(SameEvtPairsChHad::iterator const& pair, - aod::HfcRedTrigCharms const&, - aod::HfcRedCorrColls const&) + aod::HfcRedTrigCharms const&, + aod::HfcRedCorrColls const&) { BinningCentPosZ binPolicyPosZCent{{binsZPool, binsCentPool}}; auto trigCand = pair.template hfcRedTrigCharm_as(); @@ -650,8 +651,8 @@ struct HfCorrelatorFlowCharmHadronsReduced { PROCESS_SWITCH(HfCorrelatorFlowCharmHadronsReduced, processSECharmHadWCentMixWEffInfo, "Process Same Event for Charm-Had with centrality pools", false); void processSEHadHadWCentMix(SameEvtPairsHadHad::iterator const& pair, - aod::HfcRedTrigTracks const&, - aod::HfcRedCorrColls const&) + aod::HfcRedTrigTracks const&, + aod::HfcRedCorrColls const&) { BinningCentPosZ binPolicyPosZCent{{binsZPool, binsCentPool}}; auto trigCand = pair.template hfcRedTrigTrack_as(); diff --git a/PWGHF/HFC/TableProducer/derivedDataCreatorCorrelationsReduced.cxx b/PWGHF/HFC/TableProducer/derivedDataCreatorCorrelationsReduced.cxx index a6e34ed6efb..64c534cd38b 100644 --- a/PWGHF/HFC/TableProducer/derivedDataCreatorCorrelationsReduced.cxx +++ b/PWGHF/HFC/TableProducer/derivedDataCreatorCorrelationsReduced.cxx @@ -637,7 +637,6 @@ struct HfDerivedDataCreatorCorrelationsReduced { } PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processDataLcME, "Process Mixed Event for Lc candidates", false); - // CHARM-HADRON CORRELATIONS PROCESS FUNCTIONS --- MC // Dplus MC void processMcDplusSE(McCollsWithCentMult::iterator const& coll, @@ -799,12 +798,11 @@ struct HfDerivedDataCreatorCorrelationsReduced { } PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processMcLcME, "Process Mixed Event for Lc candidates", false); - // HADRON-HADRON CORRELATIONS PROCESS FUNCTIONS --- DATA // Hadron Hadron Same Event void processDataHadronHadronSE(DataCollsWithCentMult::iterator const& coll, TracksData const& tracks) - { + { float cent{-1.}, mult{-1.}; if (!checkCollision(coll, cent, mult)) { return; @@ -817,7 +815,7 @@ struct HfDerivedDataCreatorCorrelationsReduced { // Hadron Hadron Mixed Event void processDataHadronHadronME(DataCollsWithCentMult::iterator const& coll, TracksData const& tracks) - { + { float cent{-1.}, mult{-1.}; if (!checkCollision(coll, cent, mult)) { return; @@ -827,12 +825,11 @@ struct HfDerivedDataCreatorCorrelationsReduced { } PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processDataHadronHadronME, "Process Mixed Event for hadron candidates", false); - // HADRON-HADRON CORRELATIONS PROCESS FUNCTIONS --- MC // Hadron Hadron Same Event void processMcHadronHadronSE(McCollsWithCentMult::iterator const& coll, TracksMc const& tracks) - { + { float cent{-1.}, mult{-1.}; if (!checkCollision(coll, cent, mult)) { return; @@ -845,7 +842,7 @@ struct HfDerivedDataCreatorCorrelationsReduced { // Hadron Hadron Mixed Event void processMcHadronHadronME(McCollsWithCentMult::iterator const& coll, TracksMc const& tracks) - { + { float cent{-1.}, mult{-1.}; if (!checkCollision(coll, cent, mult)) { return; diff --git a/PWGHF/HFC/Tasks/taskCorrelationsEfficiencies.cxx b/PWGHF/HFC/Tasks/taskCorrelationsEfficiencies.cxx index 5794bf7a7c2..d67836e2c22 100644 --- a/PWGHF/HFC/Tasks/taskCorrelationsEfficiencies.cxx +++ b/PWGHF/HFC/Tasks/taskCorrelationsEfficiencies.cxx @@ -19,8 +19,8 @@ #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" #include "PWGHF/HFC/DataModel/DerivedDataCorrelationTables.h" -#include "PWGHF/Utils/utilsEvSelHf.h" #include "PWGHF/HFC/Utils/utilsFlow.h" +#include "PWGHF/Utils/utilsEvSelHf.h" #include "Common/Core/RecoDecay.h" #include "Common/DataModel/Centrality.h" @@ -63,13 +63,13 @@ namespace o2::aod namespace hf_correlations_eff { // Charm-hadron candidate columns -DECLARE_SOA_COLUMN(Pt, pt, float); //! Transverse momentum of candidate (GeV/c) -DECLARE_SOA_COLUMN(PvContrib, pvContrib, int); //! Number of primary vertex contributors -DECLARE_SOA_COLUMN(Eta, eta, float); //! Pseudorapidity of candidate -DECLARE_SOA_COLUMN(Phi, phi, float); //! Azimuthal angle of candidate -DECLARE_SOA_COLUMN(Origin, origin, int); //! Origin of the candidate (prompt or non-prompt) -DECLARE_SOA_COLUMN(MlScore0, mlScore0, float); //! ML score of the first configured index -DECLARE_SOA_COLUMN(MlScore1, mlScore1, float); //! ML score of the second configured index +DECLARE_SOA_COLUMN(Pt, pt, float); //! Transverse momentum of candidate (GeV/c) +DECLARE_SOA_COLUMN(PvContrib, pvContrib, int); //! Number of primary vertex contributors +DECLARE_SOA_COLUMN(Eta, eta, float); //! Pseudorapidity of candidate +DECLARE_SOA_COLUMN(Phi, phi, float); //! Azimuthal angle of candidate +DECLARE_SOA_COLUMN(Origin, origin, int); //! Origin of the candidate (prompt or non-prompt) +DECLARE_SOA_COLUMN(MlScore0, mlScore0, float); //! ML score of the first configured index +DECLARE_SOA_COLUMN(MlScore1, mlScore1, float); //! ML score of the second configured index // Associated track columns DECLARE_SOA_COLUMN(PtAssoc, ptAssoc, float); //! Transverse momentum of associated track (GeV/c) @@ -219,7 +219,6 @@ struct HfTaskCorrelationsEfficiencies { std::vector axesAssocTracks = {axisPtAssoc, axisEtaAssoc, axisPhiAssoc, axisZVtx, axisAssTrkSpecie, axisTrackOrigin}; registry.add("hAssTrackReco", "Reconstructed associated tracks;;", {HistType::kTHnSparseF}, axesAssocTracks); registry.add("hAssTrackGen", "Generated associated tracks;;", {HistType::kTHnSparseF}, axesAssocTracks); - } /// Match charm-hadron based on its reconstruction flag @@ -428,10 +427,8 @@ struct HfTaskCorrelationsEfficiencies { auto genCollision = genTrk.template mcCollision_as(); registry.fill(HIST("hAssTrackGen"), genTrk.pt(), genTrk.eta(), genTrk.phi(), genCollision.posZ(), matchedSpecie, genTrkOrigin); } - } PROCESS_SWITCH(HfTaskCorrelationsEfficiencies, processEffAssTracks, "Process efficiencies for associated tracks", true); - }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGHF/HFC/Utils/utilsFlow.h b/PWGHF/HFC/Utils/utilsFlow.h index f99f2d6e3e1..31dda4f1943 100644 --- a/PWGHF/HFC/Utils/utilsFlow.h +++ b/PWGHF/HFC/Utils/utilsFlow.h @@ -68,155 +68,155 @@ enum AssTracksTypes { NAssTracksTypes }; -class HfcFlowHelper { - - public: - - HfcFlowHelper() = default; - - void init(o2::framework::Service& ccdb, - o2::framework::HistogramRegistry& registry, - std::vector classMl, - float yCandMax) { - - LOG(info) << "Initializing HFC flow helper!"; - this->hfEvSel.addHistograms(registry); - this->ccdb = &ccdb; - this->registry = ®istry; - this->classMl = std::move(classMl); - this->yCandMax = yCandMax; - } - - /// Get charm hadron candidate mass - /// \param candidate is the charm hadron candidate - template - double getCandMass(const TCand& candidate) - { - if constexpr (CandType == TriggerChannels::DsToKKPi) { - return HfHelper::invMassDsToKKPi(candidate); - } - if constexpr (CandType == TriggerChannels::DsToPiKK) { - return HfHelper::invMassDsToPiKK(candidate); - } - if constexpr (CandType == TriggerChannels::DplusToPiKPi) { - return HfHelper::invMassDplusToPiKPi(candidate); - } - if constexpr (CandType == TriggerChannels::D0ToPiK) { - return HfHelper::invMassD0ToPiK(candidate); - } - if constexpr (CandType == TriggerChannels::D0ToKPi) { - return HfHelper::invMassD0barToKPi(candidate); - } - if constexpr (CandType == TriggerChannels::LcToPKPi) { - return HfHelper::invMassLcToPKPi(candidate); - } - if constexpr (CandType == TriggerChannels::LcToPiKP) { - return HfHelper::invMassLcToPiKP(candidate); - } - return -1.; - } - - /// Get charm hadron bdt scores - /// \param candidate is the charm hadron candidate - template - std::array getCandMlScores(const TCand& candidate) - { - std::array outputMl{-999.f, -999.f}; - if constexpr (CandType == TriggerChannels::DsToKKPi) { - for (unsigned int iclass = 0; iclass < classMl.size(); iclass++) { - outputMl[iclass] = candidate.mlProbDsToKKPi()[classMl.at(iclass)]; - } - } - if constexpr (CandType == TriggerChannels::DsToPiKK) { - for (unsigned int iclass = 0; iclass < classMl.size(); iclass++) { - outputMl[iclass] = candidate.mlProbDsToPiKK()[classMl.at(iclass)]; - } - } - if constexpr (CandType == TriggerChannels::DplusToPiKPi) { - for (unsigned int iclass = 0; iclass < classMl.size(); iclass++) { - outputMl[iclass] = candidate.mlProbDplusToPiKPi()[classMl.at(iclass)]; - } - } - if constexpr (CandType == TriggerChannels::D0ToPiK) { - for (unsigned int iclass = 0; iclass < classMl.size(); iclass++) { - outputMl[iclass] = candidate.mlProbD0()[classMl.at(iclass)]; - } - } - if constexpr (CandType == TriggerChannels::D0ToKPi) { - for (unsigned int iclass = 0; iclass < classMl.size(); iclass++) { - outputMl[iclass] = candidate.mlProbD0bar()[classMl.at(iclass)]; - } - } - if constexpr (CandType == TriggerChannels::LcToPKPi) { - for (unsigned int iclass = 0; iclass < classMl.size(); iclass++) { - outputMl[iclass] = candidate.mlProbLcToPKPi()[classMl.at(iclass)]; - } - } - if constexpr (CandType == TriggerChannels::LcToPiKP) { - for (unsigned int iclass = 0; iclass < classMl.size(); iclass++) { - outputMl[iclass] = candidate.mlProbLcToPiKP()[classMl.at(iclass)]; - } - } - return outputMl; - } - - /// Cut on rapidity of the candidate - /// \param candidate is the charm hadron candidate - template - bool cutCandRapidity(const TCand& candidate) - { - double y = 0.0; - if constexpr (CandType == TriggerChannels::DsToKKPi || CandType == TriggerChannels::DsToPiKK) { - y = HfHelper::yDs(candidate); - } else if constexpr (CandType == TriggerChannels::DplusToPiKPi) { - y = HfHelper::yDplus(candidate); - } else if constexpr (CandType == TriggerChannels::D0ToPiK || CandType == TriggerChannels::D0ToKPi) { - y = HfHelper::yD0(candidate); - } else if constexpr (CandType == TriggerChannels::LcToPKPi || CandType == TriggerChannels::LcToPiKP) { - y = HfHelper::yLc(candidate); - } else { - return true; - } - return std::fabs(y) < yCandMax; - } - - /// Check event selections for collision and fill the collision table - /// \param collision is the collision - template - bool checkCollision(Coll const& collision, float& cent, float& mult) - { - o2::hf_evsel::HfCollisionRejectionMask collRejMask{}; - if constexpr (CentEst == o2::hf_centrality::CentralityEstimator::FT0A) { - collRejMask = hfEvSel.getHfCollisionRejectionMask(collision, cent, *ccdb, *registry); - mult = collision.multFT0A(); - } else if constexpr (CentEst == o2::hf_centrality::CentralityEstimator::FT0C) { - collRejMask = hfEvSel.getHfCollisionRejectionMask(collision, cent, *ccdb, *registry); - mult = collision.multFT0C(); - } else if constexpr (CentEst == o2::hf_centrality::CentralityEstimator::FT0M) { - collRejMask = hfEvSel.getHfCollisionRejectionMask(collision, cent, *ccdb, *registry); - mult = collision.multFT0M(); - } else if constexpr (CentEst == o2::hf_centrality::CentralityEstimator::FV0A) { - collRejMask = hfEvSel.getHfCollisionRejectionMask(collision, cent, *ccdb, *registry); - mult = collision.multFV0A(); - } else if constexpr (CentEst == o2::hf_centrality::CentralityEstimator::None) { - collRejMask = hfEvSel.getHfCollisionRejectionMask(collision, cent, *ccdb, *registry); - mult = -1.f; - } else { - LOG(fatal) << "Centrality estimator not recognized for collision selection"; - std::abort(); - } - hfEvSel.fillHistograms(collision, collRejMask, cent); - return collRejMask == 0; - } - - private: - o2::hf_evsel::HfEventSelection hfEvSel; - o2::framework::Service* ccdb{nullptr}; - o2::framework::HistogramRegistry* registry{nullptr}; - std::vector classMl{}; - float yCandMax{-999.f}; -}; +class HfcFlowHelper +{ + public: + HfcFlowHelper() = default; + + void init(o2::framework::Service& ccdb, + o2::framework::HistogramRegistry& registry, + std::vector classMl, + float yCandMax) + { + + LOG(info) << "Initializing HFC flow helper!"; + this->hfEvSel.addHistograms(registry); + this->ccdb = &ccdb; + this->registry = ®istry; + this->classMl = std::move(classMl); + this->yCandMax = yCandMax; + } + + /// Get charm hadron candidate mass + /// \param candidate is the charm hadron candidate + template + double getCandMass(const TCand& candidate) + { + if constexpr (CandType == TriggerChannels::DsToKKPi) { + return HfHelper::invMassDsToKKPi(candidate); + } + if constexpr (CandType == TriggerChannels::DsToPiKK) { + return HfHelper::invMassDsToPiKK(candidate); + } + if constexpr (CandType == TriggerChannels::DplusToPiKPi) { + return HfHelper::invMassDplusToPiKPi(candidate); + } + if constexpr (CandType == TriggerChannels::D0ToPiK) { + return HfHelper::invMassD0ToPiK(candidate); + } + if constexpr (CandType == TriggerChannels::D0ToKPi) { + return HfHelper::invMassD0barToKPi(candidate); + } + if constexpr (CandType == TriggerChannels::LcToPKPi) { + return HfHelper::invMassLcToPKPi(candidate); + } + if constexpr (CandType == TriggerChannels::LcToPiKP) { + return HfHelper::invMassLcToPiKP(candidate); + } + return -1.; + } + + /// Get charm hadron bdt scores + /// \param candidate is the charm hadron candidate + template + std::array getCandMlScores(const TCand& candidate) + { + std::array outputMl{-999.f, -999.f}; + if constexpr (CandType == TriggerChannels::DsToKKPi) { + for (unsigned int iclass = 0; iclass < classMl.size(); iclass++) { + outputMl[iclass] = candidate.mlProbDsToKKPi()[classMl.at(iclass)]; + } + } + if constexpr (CandType == TriggerChannels::DsToPiKK) { + for (unsigned int iclass = 0; iclass < classMl.size(); iclass++) { + outputMl[iclass] = candidate.mlProbDsToPiKK()[classMl.at(iclass)]; + } + } + if constexpr (CandType == TriggerChannels::DplusToPiKPi) { + for (unsigned int iclass = 0; iclass < classMl.size(); iclass++) { + outputMl[iclass] = candidate.mlProbDplusToPiKPi()[classMl.at(iclass)]; + } + } + if constexpr (CandType == TriggerChannels::D0ToPiK) { + for (unsigned int iclass = 0; iclass < classMl.size(); iclass++) { + outputMl[iclass] = candidate.mlProbD0()[classMl.at(iclass)]; + } + } + if constexpr (CandType == TriggerChannels::D0ToKPi) { + for (unsigned int iclass = 0; iclass < classMl.size(); iclass++) { + outputMl[iclass] = candidate.mlProbD0bar()[classMl.at(iclass)]; + } + } + if constexpr (CandType == TriggerChannels::LcToPKPi) { + for (unsigned int iclass = 0; iclass < classMl.size(); iclass++) { + outputMl[iclass] = candidate.mlProbLcToPKPi()[classMl.at(iclass)]; + } + } + if constexpr (CandType == TriggerChannels::LcToPiKP) { + for (unsigned int iclass = 0; iclass < classMl.size(); iclass++) { + outputMl[iclass] = candidate.mlProbLcToPiKP()[classMl.at(iclass)]; + } + } + return outputMl; + } + + /// Cut on rapidity of the candidate + /// \param candidate is the charm hadron candidate + template + bool cutCandRapidity(const TCand& candidate) + { + double y = 0.0; + if constexpr (CandType == TriggerChannels::DsToKKPi || CandType == TriggerChannels::DsToPiKK) { + y = HfHelper::yDs(candidate); + } else if constexpr (CandType == TriggerChannels::DplusToPiKPi) { + y = HfHelper::yDplus(candidate); + } else if constexpr (CandType == TriggerChannels::D0ToPiK || CandType == TriggerChannels::D0ToKPi) { + y = HfHelper::yD0(candidate); + } else if constexpr (CandType == TriggerChannels::LcToPKPi || CandType == TriggerChannels::LcToPiKP) { + y = HfHelper::yLc(candidate); + } else { + return true; + } + return std::fabs(y) < yCandMax; + } + + /// Check event selections for collision and fill the collision table + /// \param collision is the collision + template + bool checkCollision(Coll const& collision, float& cent, float& mult) + { + o2::hf_evsel::HfCollisionRejectionMask collRejMask{}; + if constexpr (CentEst == o2::hf_centrality::CentralityEstimator::FT0A) { + collRejMask = hfEvSel.getHfCollisionRejectionMask(collision, cent, *ccdb, *registry); + mult = collision.multFT0A(); + } else if constexpr (CentEst == o2::hf_centrality::CentralityEstimator::FT0C) { + collRejMask = hfEvSel.getHfCollisionRejectionMask(collision, cent, *ccdb, *registry); + mult = collision.multFT0C(); + } else if constexpr (CentEst == o2::hf_centrality::CentralityEstimator::FT0M) { + collRejMask = hfEvSel.getHfCollisionRejectionMask(collision, cent, *ccdb, *registry); + mult = collision.multFT0M(); + } else if constexpr (CentEst == o2::hf_centrality::CentralityEstimator::FV0A) { + collRejMask = hfEvSel.getHfCollisionRejectionMask(collision, cent, *ccdb, *registry); + mult = collision.multFV0A(); + } else if constexpr (CentEst == o2::hf_centrality::CentralityEstimator::None) { + collRejMask = hfEvSel.getHfCollisionRejectionMask(collision, cent, *ccdb, *registry); + mult = -1.f; + } else { + LOG(fatal) << "Centrality estimator not recognized for collision selection"; + std::abort(); + } + hfEvSel.fillHistograms(collision, collRejMask, cent); + return collRejMask == 0; + } + + private: + o2::hf_evsel::HfEventSelection hfEvSel; + o2::framework::Service* ccdb{nullptr}; + o2::framework::HistogramRegistry* registry{nullptr}; + std::vector classMl{}; + float yCandMax{-999.f}; +}; -} // namespace o2::analysis::hfc_utils_flow +} // namespace o2::hfc_utils_flow #endif // PWGHF_HFC_UTILS_FLOW_H_ From 5cda95df515a546d808ca9f7afdadd1d2c20642b Mon Sep 17 00:00:00 2001 From: Marcello Di Costanzo Date: Thu, 5 Nov 2026 17:27:40 +0100 Subject: [PATCH 05/18] Fix megalinter --- .../correlatorFlowCharmHadronsReduced.cxx | 1 + .../derivedDataCreatorCorrelationsReduced.cxx | 123 ++++-------------- .../Tasks/taskCorrelationsEfficiencies.cxx | 1 + PWGHF/HFC/Utils/utilsFlow.h | 24 ++-- 4 files changed, 38 insertions(+), 111 deletions(-) diff --git a/PWGHF/HFC/TableProducer/correlatorFlowCharmHadronsReduced.cxx b/PWGHF/HFC/TableProducer/correlatorFlowCharmHadronsReduced.cxx index b6d8857069f..25302ef9a10 100644 --- a/PWGHF/HFC/TableProducer/correlatorFlowCharmHadronsReduced.cxx +++ b/PWGHF/HFC/TableProducer/correlatorFlowCharmHadronsReduced.cxx @@ -44,6 +44,7 @@ #include #include #include +#include #include #include diff --git a/PWGHF/HFC/TableProducer/derivedDataCreatorCorrelationsReduced.cxx b/PWGHF/HFC/TableProducer/derivedDataCreatorCorrelationsReduced.cxx index a6e34ed6efb..1235dab3b39 100644 --- a/PWGHF/HFC/TableProducer/derivedDataCreatorCorrelationsReduced.cxx +++ b/PWGHF/HFC/TableProducer/derivedDataCreatorCorrelationsReduced.cxx @@ -23,6 +23,7 @@ #include "PWGHF/DataModel/CandidateSelectionTables.h" #include "PWGHF/HFC/DataModel/DerivedDataCorrelationTables.h" #include "PWGHF/Utils/utilsEvSelHf.h" +#include "PWGHF/HFC/Utils/utilsFlow.h" #include "Common/Core/RecoDecay.h" #include "Common/DataModel/Centrality.h" @@ -50,6 +51,7 @@ #include #include #include +#include #include #include @@ -169,6 +171,22 @@ struct HfDerivedDataCreatorCorrelationsReduced { ccdb->setCaching(true); ccdb->setLocalObjectValidityChecking(); + std::vector classesMl; + for (const auto scoreClass : classMl.value) { + if (scoreClass < 0) { + LOG(fatal) << "ML class indexes must be non-negative"; + return; + } + classesMl.push_back(static_cast(scoreClass)); + } + + if (classesMl.size() > 2) { + LOG(fatal) << "At most two ML classes can be selected"; + return; + } + + hfcFlowHelper.init(ccdb, registry, classesMl, yCandMax.value); + const AxisSpec axisTpcSignal = {binsTpcSignal, "TPC Signal"}; const AxisSpec axisCent = {binsCent, "Centrality"}; const AxisSpec axisMult = {binsMult, "Multiplicity"}; @@ -200,99 +218,6 @@ struct HfDerivedDataCreatorCorrelationsReduced { } }; // end init - /// Get charm hadron candidate mass - /// \param candidate is the charm hadron candidate - template - double getCandMass(const TCand& candidate) - { - if constexpr (CandType == CandidateType::DsToKKPi) { - return HfHelper::invMassDsToKKPi(candidate); - } - if constexpr (CandType == CandidateType::DsToPiKK) { - return HfHelper::invMassDsToPiKK(candidate); - } - if constexpr (CandType == CandidateType::DplusToPiKPi) { - return HfHelper::invMassDplusToPiKPi(candidate); - } - if constexpr (CandType == CandidateType::D0ToPiK) { - return HfHelper::invMassD0ToPiK(candidate); - } - if constexpr (CandType == CandidateType::D0ToKPi) { - return HfHelper::invMassD0barToKPi(candidate); - } - if constexpr (CandType == CandidateType::LcToPKPi) { - return HfHelper::invMassLcToPKPi(candidate); - } - if constexpr (CandType == CandidateType::LcToPiKP) { - return HfHelper::invMassLcToPiKP(candidate); - } - return -1.; - } - - /// Get charm hadron bdt scores - /// \param candidate is the charm hadron candidate - template - std::array getCandMlScores(const TCand& candidate) - { - std::array outputMl{-999.f, -999.f}; - if constexpr (CandType == CandidateType::DsToKKPi) { - for (unsigned int iclass = 0; iclass < classMl->size(); iclass++) { - outputMl[iclass] = candidate.mlProbDsToKKPi()[classMl->at(iclass)]; - } - } - if constexpr (CandType == CandidateType::DsToPiKK) { - for (unsigned int iclass = 0; iclass < classMl->size(); iclass++) { - outputMl[iclass] = candidate.mlProbDsToPiKK()[classMl->at(iclass)]; - } - } - if constexpr (CandType == CandidateType::DplusToPiKPi) { - for (unsigned int iclass = 0; iclass < classMl->size(); iclass++) { - outputMl[iclass] = candidate.mlProbDplusToPiKPi()[classMl->at(iclass)]; - } - } - if constexpr (CandType == CandidateType::D0ToPiK) { - for (unsigned int iclass = 0; iclass < classMl->size(); iclass++) { - outputMl[iclass] = candidate.mlProbD0()[classMl->at(iclass)]; - } - } - if constexpr (CandType == CandidateType::D0ToKPi) { - for (unsigned int iclass = 0; iclass < classMl->size(); iclass++) { - outputMl[iclass] = candidate.mlProbD0bar()[classMl->at(iclass)]; - } - } - if constexpr (CandType == CandidateType::LcToPKPi) { - for (unsigned int iclass = 0; iclass < classMl->size(); iclass++) { - outputMl[iclass] = candidate.mlProbLcToPKPi()[classMl->at(iclass)]; - } - } - if constexpr (CandType == CandidateType::LcToPiKP) { - for (unsigned int iclass = 0; iclass < classMl->size(); iclass++) { - outputMl[iclass] = candidate.mlProbLcToPiKP()[classMl->at(iclass)]; - } - } - return outputMl; - } - - /// Cut on rapidity of the candidate - /// \param candidate is the charm hadron candidate - template - bool cutCandRapidity(const TCand& candidate) - { - double y = 0.0; - if constexpr (CandType == CandidateType::DsToKKPi || CandType == CandidateType::DsToPiKK) { - y = HfHelper::yDs(candidate); - } else if constexpr (CandType == CandidateType::DplusToPiKPi) { - y = HfHelper::yDplus(candidate); - } else if constexpr (CandType == CandidateType::D0ToPiK || CandType == CandidateType::D0ToKPi) { - y = HfHelper::yD0(candidate); - } else if constexpr (CandType == CandidateType::LcToPKPi || CandType == CandidateType::LcToPiKP) { - y = HfHelper::yLc(candidate); - } else { - return true; - } - return std::fabs(y) < yCandMax; - } - /// Check event selections for collision and fill the collision table /// \param collision is the collision template @@ -367,7 +292,7 @@ struct HfDerivedDataCreatorCorrelationsReduced { const float mult) { for (const auto& trigCand : trigCands) { - if (!cutCandRapidity(trigCand)) { + if (!hfcFlowHelper.cutCandRapidity(trigCand)) { continue; } double trigCandPt = trigCand.pt(); @@ -376,8 +301,8 @@ struct HfDerivedDataCreatorCorrelationsReduced { if constexpr (CandType == CandidateType::Hadron) { rowTrigHads(rowCollisions.lastIndex(), trigCandPt, trigCand.tpcNClsCrossedRows(), trigCand.itsClusterMap(), trigCand.itsNCls(), trigCand.dcaXY(), trigCand.dcaZ()); } else { - std::array outputMl = getCandMlScores(trigCand); - rowTrigCharms(rowCollisions.lastIndex(), trigCandPt, getCandMass(trigCand), outputMl[0], outputMl[1]); + std::array outputMl = hfcFlowHelper.getCandMlScores(trigCand); + rowTrigCharms(rowCollisions.lastIndex(), trigCandPt, hfcFlowHelper.getCandMass(trigCand), outputMl[0], outputMl[1]); rowTrigBases(trigCand.phi(), trigCand.eta()); } @@ -427,15 +352,15 @@ struct HfDerivedDataCreatorCorrelationsReduced { void fillCharmMixedEvent(TTrigCands const& trigCands) { for (const auto& trigCand : trigCands) { - if (!cutCandRapidity(trigCand)) { + if (!hfcFlowHelper.cutCandRapidity(trigCand)) { continue; } registry.fill(HIST("hPhiVsPtTrig"), RecoDecay::constrainAngle(trigCand.phi(), -o2::constants::math::PIHalf), trigCand.pt()); registry.fill(HIST("hEtaVsPtTrig"), trigCand.eta(), trigCand.pt()); - std::array outputMl = getCandMlScores(trigCand); + std::array outputMl = hfcFlowHelper.getCandMlScores(trigCand); rowTrigBases(trigCand.phi(), trigCand.eta()); - rowTrigCharms(rowCollisions.lastIndex(), trigCand.pt(), getCandMass(trigCand), outputMl[0], outputMl[1]); + rowTrigCharms(rowCollisions.lastIndex(), trigCand.pt(), hfcFlowHelper.getCandMass(trigCand), outputMl[0], outputMl[1]); } } diff --git a/PWGHF/HFC/Tasks/taskCorrelationsEfficiencies.cxx b/PWGHF/HFC/Tasks/taskCorrelationsEfficiencies.cxx index 5794bf7a7c2..c918c90073f 100644 --- a/PWGHF/HFC/Tasks/taskCorrelationsEfficiencies.cxx +++ b/PWGHF/HFC/Tasks/taskCorrelationsEfficiencies.cxx @@ -48,6 +48,7 @@ #include #include #include +#include #include #include diff --git a/PWGHF/HFC/Utils/utilsFlow.h b/PWGHF/HFC/Utils/utilsFlow.h index f99f2d6e3e1..450f0f3bcb0 100644 --- a/PWGHF/HFC/Utils/utilsFlow.h +++ b/PWGHF/HFC/Utils/utilsFlow.h @@ -13,8 +13,8 @@ /// \brief Utilities for HFC analyses /// \author Marcello Di Costanzo -#ifndef PWGHF_HFC_UTILS_FLOW_H_ -#define PWGHF_HFC_UTILS_FLOW_H_ +#ifndef PWGHF_HFC_UTILS_UTILSFLOW_H_ +#define PWGHF_HFC_UTILS_UTILSFLOW_H_ #include "PWGHF/Core/CentralityEstimation.h" #include "PWGHF/Core/DecayChannels.h" @@ -74,17 +74,17 @@ class HfcFlowHelper { HfcFlowHelper() = default; - void init(o2::framework::Service& ccdb, - o2::framework::HistogramRegistry& registry, - std::vector classMl, - float yCandMax) { + void init(o2::framework::Service& ccdbService, + o2::framework::HistogramRegistry& histRegistry, + std::vector mlClasses, + float maxRapidity) { LOG(info) << "Initializing HFC flow helper!"; - this->hfEvSel.addHistograms(registry); - this->ccdb = &ccdb; - this->registry = ®istry; - this->classMl = std::move(classMl); - this->yCandMax = yCandMax; + this->hfEvSel.addHistograms(histRegistry); + this->ccdb = &ccdbService; + this->registry = &histRegistry; + this->classMl = std::move(mlClasses); + this->yCandMax = maxRapidity; } /// Get charm hadron candidate mass @@ -219,4 +219,4 @@ class HfcFlowHelper { } // namespace o2::analysis::hfc_utils_flow -#endif // PWGHF_HFC_UTILS_FLOW_H_ +#endif // PWGHF_HFC_UTILS_UTILSFLOW_H_ From 2eb2be6fdf031714ffb9cd92b6cca9c4d2f0c6d7 Mon Sep 17 00:00:00 2001 From: ALICE Action Bot Date: Thu, 5 Nov 2026 16:30:38 +0000 Subject: [PATCH 06/18] Please consider the following formatting changes --- .../derivedDataCreatorCorrelationsReduced.cxx | 2 +- PWGHF/HFC/Utils/utilsFlow.h | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/PWGHF/HFC/TableProducer/derivedDataCreatorCorrelationsReduced.cxx b/PWGHF/HFC/TableProducer/derivedDataCreatorCorrelationsReduced.cxx index 33d91218328..5bc3afa6138 100644 --- a/PWGHF/HFC/TableProducer/derivedDataCreatorCorrelationsReduced.cxx +++ b/PWGHF/HFC/TableProducer/derivedDataCreatorCorrelationsReduced.cxx @@ -22,8 +22,8 @@ #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" #include "PWGHF/HFC/DataModel/DerivedDataCorrelationTables.h" -#include "PWGHF/Utils/utilsEvSelHf.h" #include "PWGHF/HFC/Utils/utilsFlow.h" +#include "PWGHF/Utils/utilsEvSelHf.h" #include "Common/Core/RecoDecay.h" #include "Common/DataModel/Centrality.h" diff --git a/PWGHF/HFC/Utils/utilsFlow.h b/PWGHF/HFC/Utils/utilsFlow.h index 897ccebe62c..52b4885bfe4 100644 --- a/PWGHF/HFC/Utils/utilsFlow.h +++ b/PWGHF/HFC/Utils/utilsFlow.h @@ -80,9 +80,10 @@ class HfcFlowHelper /// \param mlClasses are the machine learning classes /// \param maxRapidity is the maximum rapidity void init(o2::framework::Service& ccdbService, - o2::framework::HistogramRegistry& histRegistry, - std::vector mlClasses, - float maxRapidity) { + o2::framework::HistogramRegistry& histRegistry, + std::vector mlClasses, + float maxRapidity) + { LOG(info) << "Initializing HFC flow helper!"; this->hfEvSel.addHistograms(histRegistry); @@ -222,5 +223,5 @@ class HfcFlowHelper float yCandMax{-999.f}; }; -} // namespace o2::analysis::hfc_utils_flow +} // namespace o2::hfc_utils_flow #endif // PWGHF_HFC_UTILS_UTILSFLOW_H_ From 1ac68ca86c9d0bd7eb19674fd57b569225251e7c Mon Sep 17 00:00:00 2001 From: Marcello Di Costanzo Date: Thu, 5 Nov 2026 17:44:44 +0100 Subject: [PATCH 07/18] Declare hfcFlowHelper --- .../HFC/TableProducer/derivedDataCreatorCorrelationsReduced.cxx | 1 + 1 file changed, 1 insertion(+) diff --git a/PWGHF/HFC/TableProducer/derivedDataCreatorCorrelationsReduced.cxx b/PWGHF/HFC/TableProducer/derivedDataCreatorCorrelationsReduced.cxx index 33d91218328..dffb4042b5d 100644 --- a/PWGHF/HFC/TableProducer/derivedDataCreatorCorrelationsReduced.cxx +++ b/PWGHF/HFC/TableProducer/derivedDataCreatorCorrelationsReduced.cxx @@ -109,6 +109,7 @@ struct HfDerivedDataCreatorCorrelationsReduced { Configurable centMaxForDownSample{"centMaxForDownSample", 101., "Maximum centrality for the application of the downsampling factor"}; HfEventSelection hfEvSel; // event selection and monitoring + HfcFlowHelper hfcFlowHelper; // flow utilities o2::framework::Service ccdb{}; SliceCache cache; From 94f2adabbd512046b02f7a4dd8d4d1bb440e4419 Mon Sep 17 00:00:00 2001 From: Marcello Di Costanzo Date: Thu, 5 Nov 2026 17:51:17 +0100 Subject: [PATCH 08/18] Add missing namespace --- .../HFC/TableProducer/derivedDataCreatorCorrelationsReduced.cxx | 1 + 1 file changed, 1 insertion(+) diff --git a/PWGHF/HFC/TableProducer/derivedDataCreatorCorrelationsReduced.cxx b/PWGHF/HFC/TableProducer/derivedDataCreatorCorrelationsReduced.cxx index edd6943aa6f..929190c28fa 100644 --- a/PWGHF/HFC/TableProducer/derivedDataCreatorCorrelationsReduced.cxx +++ b/PWGHF/HFC/TableProducer/derivedDataCreatorCorrelationsReduced.cxx @@ -61,6 +61,7 @@ using namespace o2::framework::expressions; using namespace o2::hf_centrality; using namespace o2::hf_evsel; using namespace o2::hf_decay; +using namespace o2::hfc_utils_flow; enum CandidateType { DplusToPiKPi = 0, From b8767108b9756facfc9ae24808421caf24c9fd88 Mon Sep 17 00:00:00 2001 From: Marcello Di Costanzo Date: Thu, 5 Nov 2026 18:26:13 +0100 Subject: [PATCH 09/18] Fix old enum --- .../derivedDataCreatorCorrelationsReduced.cxx | 85 ++++++++----------- 1 file changed, 37 insertions(+), 48 deletions(-) diff --git a/PWGHF/HFC/TableProducer/derivedDataCreatorCorrelationsReduced.cxx b/PWGHF/HFC/TableProducer/derivedDataCreatorCorrelationsReduced.cxx index 929190c28fa..3efa36a6d9f 100644 --- a/PWGHF/HFC/TableProducer/derivedDataCreatorCorrelationsReduced.cxx +++ b/PWGHF/HFC/TableProducer/derivedDataCreatorCorrelationsReduced.cxx @@ -63,18 +63,7 @@ using namespace o2::hf_evsel; using namespace o2::hf_decay; using namespace o2::hfc_utils_flow; -enum CandidateType { - DplusToPiKPi = 0, - DsToKKPi, - DsToPiKK, - D0ToPiK, - D0ToKPi, - LcToPKPi, - LcToPiKP, - Hadron -}; - -/// Code to select collisions with at least one Ds meson +/// Code to produce self-contained derived datasets for v2 analyses of charm hadrons via 2PC struct HfDerivedDataCreatorCorrelationsReduced { Produces rowCollisions; // Table with reduced collision info Produces rowSECharmHadPairs; // Table with same-event pairs info @@ -249,7 +238,7 @@ struct HfDerivedDataCreatorCorrelationsReduced { /// Checks if the trigger cand-associated track pair can be accepted for SE correlation /// \param assTrk is the associated track /// \param cand is the trigger candidate - template + template bool acceptSameEvtPair(TAssocTrk const& assTrk, TCand const& cand, double deltaEta) { if (std::abs(deltaEta) <= deltaEtaAbsMin || std::abs(deltaEta) > deltaEtaAbsMax) { @@ -261,7 +250,7 @@ struct HfDerivedDataCreatorCorrelationsReduced { } int const trackGlobalIndex = assTrk.globalIndex(); - if constexpr (CandType == CandidateType::Hadron) { + if constexpr (CandType == TriggerChannels::Hadron) { if (!cand.isGlobalTrackWoDCA() || cand.tpcNClsCrossedRows() < tpcNClsCrossedRowsMin) { return false; } @@ -287,7 +276,7 @@ struct HfDerivedDataCreatorCorrelationsReduced { /// \param assTrks are the associated tracks /// \param cent is the collision centrality /// \param mult is the collision multiplicity - template + template void fillSameEvent(TTrigCands const& trigCands, TAssocTrks const& assTrks, const float cent, @@ -300,7 +289,7 @@ struct HfDerivedDataCreatorCorrelationsReduced { double trigCandPt = trigCand.pt(); registry.fill(HIST("hPhiVsPtTrig"), RecoDecay::constrainAngle(trigCand.phi(), -o2::constants::math::PIHalf), trigCandPt); registry.fill(HIST("hEtaVsPtTrig"), trigCand.eta(), trigCandPt); - if constexpr (CandType == CandidateType::Hadron) { + if constexpr (CandType == TriggerChannels::Hadron) { rowTrigHads(rowCollisions.lastIndex(), trigCandPt, trigCand.tpcNClsCrossedRows(), trigCand.itsClusterMap(), trigCand.itsNCls(), trigCand.dcaXY(), trigCand.dcaZ()); } else { std::array outputMl = hfcFlowHelper.getCandMlScores(trigCand); @@ -339,7 +328,7 @@ struct HfDerivedDataCreatorCorrelationsReduced { double deltaPhi = RecoDecay::constrainAngle(assTrk.phi() - trigCand.phi(), -o2::constants::math::PIHalf); rowAssocBases(rowCollisions.lastIndex(), assTrk.phi(), assTrk.eta(), assTrkPt); rowAssocTrkSels(assTrk.tpcNClsCrossedRows(), assTrk.itsClusterMap(), assTrk.itsNCls(), assTrk.dcaXY(), assTrk.dcaZ()); - if constexpr (CandType == CandidateType::Hadron) { + if constexpr (CandType == TriggerChannels::Hadron) { rowSEHadHadPairs(rowCollisions.lastIndex(), rowTrigHads.lastIndex(), assTrkPt, deltaEta, deltaPhi); } else { rowSECharmHadPairs(rowCollisions.lastIndex(), rowTrigCharms.lastIndex(), assTrkPt, deltaEta, deltaPhi); @@ -350,7 +339,7 @@ struct HfDerivedDataCreatorCorrelationsReduced { /// Fill charm hadron tables for mixed-event /// \param trigCands are the charm trigger candidates - template + template void fillCharmMixedEvent(TTrigCands const& trigCands) { for (const auto& trigCand : trigCands) { @@ -419,7 +408,7 @@ struct HfDerivedDataCreatorCorrelationsReduced { return; } rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); - fillSameEvent(candsDplus, tracks, cent, mult); + fillSameEvent(candsDplus, tracks, cent, mult); } PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processDataDplusSE, "Process Same Event for Dplus candidates", true); @@ -436,7 +425,7 @@ struct HfDerivedDataCreatorCorrelationsReduced { return; } rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); - fillCharmMixedEvent(candsDplus); + fillCharmMixedEvent(candsDplus); fillTrkMixedEvent(tracks, cent, mult); } PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processDataDplusME, "Process Mixed Event for Dplus candidates", false); @@ -456,8 +445,8 @@ struct HfDerivedDataCreatorCorrelationsReduced { return; } rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); - fillSameEvent(candsDsToPiKK, tracks, cent, mult); - fillSameEvent(candsDsToKKPi, tracks, cent, mult); + fillSameEvent(candsDsToPiKK, tracks, cent, mult); + fillSameEvent(candsDsToKKPi, tracks, cent, mult); } PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processDataDsSE, "Process Same Event for Ds candidates", false); @@ -476,8 +465,8 @@ struct HfDerivedDataCreatorCorrelationsReduced { return; } rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); - fillCharmMixedEvent(candsDsToPiKK); - fillCharmMixedEvent(candsDsToKKPi); + fillCharmMixedEvent(candsDsToPiKK); + fillCharmMixedEvent(candsDsToKKPi); fillTrkMixedEvent(tracks, cent, mult); } PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processDataDsME, "Process Mixed Event for Ds candidates", false); @@ -497,8 +486,8 @@ struct HfDerivedDataCreatorCorrelationsReduced { return; } rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); - fillSameEvent(candsD0ToPiK, tracks, cent, mult); - fillSameEvent(candsD0ToKPi, tracks, cent, mult); + fillSameEvent(candsD0ToPiK, tracks, cent, mult); + fillSameEvent(candsD0ToKPi, tracks, cent, mult); } PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processDataD0SE, "Process Same Event for D0 candidates", false); @@ -517,8 +506,8 @@ struct HfDerivedDataCreatorCorrelationsReduced { return; } rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); - fillCharmMixedEvent(candsD0ToPiK); - fillCharmMixedEvent(candsD0ToKPi); + fillCharmMixedEvent(candsD0ToPiK); + fillCharmMixedEvent(candsD0ToKPi); fillTrkMixedEvent(tracks, cent, mult); } PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processDataD0ME, "Process Mixed Event for D0 candidates", false); @@ -538,8 +527,8 @@ struct HfDerivedDataCreatorCorrelationsReduced { return; } rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); - fillSameEvent(candsLcToPKPi, tracks, cent, mult); - fillSameEvent(candsLcToPiKP, tracks, cent, mult); + fillSameEvent(candsLcToPKPi, tracks, cent, mult); + fillSameEvent(candsLcToPiKP, tracks, cent, mult); } PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processDataLcSE, "Process Same Event for Lc candidates", false); @@ -558,8 +547,8 @@ struct HfDerivedDataCreatorCorrelationsReduced { return; } rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); - fillCharmMixedEvent(candsLcToPKPi); - fillCharmMixedEvent(candsLcToPiKP); + fillCharmMixedEvent(candsLcToPKPi); + fillCharmMixedEvent(candsLcToPiKP); fillTrkMixedEvent(tracks, cent, mult); } PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processDataLcME, "Process Mixed Event for Lc candidates", false); @@ -579,7 +568,7 @@ struct HfDerivedDataCreatorCorrelationsReduced { return; } rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); - fillSameEvent(candsRecoDplus, tracks, cent, mult); + fillSameEvent(candsRecoDplus, tracks, cent, mult); } PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processMcDplusSE, "Process Same Event for Dplus candidates", false); @@ -597,7 +586,7 @@ struct HfDerivedDataCreatorCorrelationsReduced { return; } rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); - fillCharmMixedEvent(candsRecoDplus); + fillCharmMixedEvent(candsRecoDplus); fillTrkMixedEvent(tracks, cent, mult); } PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processMcDplusME, "Process Mixed Event for Dplus candidates", false); @@ -617,8 +606,8 @@ struct HfDerivedDataCreatorCorrelationsReduced { return; } rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); - fillSameEvent(candsRecoDsToPiKK, tracks, cent, mult); - fillSameEvent(candsRecoDsToKKPi, tracks, cent, mult); + fillSameEvent(candsRecoDsToPiKK, tracks, cent, mult); + fillSameEvent(candsRecoDsToKKPi, tracks, cent, mult); } PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processMcDsSE, "Process Same Event for Ds candidates", false); @@ -637,8 +626,8 @@ struct HfDerivedDataCreatorCorrelationsReduced { return; } rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); - fillCharmMixedEvent(candsRecoDsToPiKK); - fillCharmMixedEvent(candsRecoDsToKKPi); + fillCharmMixedEvent(candsRecoDsToPiKK); + fillCharmMixedEvent(candsRecoDsToKKPi); fillTrkMixedEvent(tracks, cent, mult); } PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processMcDsME, "Process Mixed Event for Ds candidates", false); @@ -658,8 +647,8 @@ struct HfDerivedDataCreatorCorrelationsReduced { return; } rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); - fillSameEvent(candsRecoD0ToPiK, tracks, cent, mult); - fillSameEvent(candsRecoD0ToKPi, tracks, cent, mult); + fillSameEvent(candsRecoD0ToPiK, tracks, cent, mult); + fillSameEvent(candsRecoD0ToKPi, tracks, cent, mult); } PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processMcD0SE, "Process Same Event for D0 candidates", false); @@ -678,8 +667,8 @@ struct HfDerivedDataCreatorCorrelationsReduced { return; } rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); - fillCharmMixedEvent(candsRecoD0ToPiK); - fillCharmMixedEvent(candsRecoD0ToKPi); + fillCharmMixedEvent(candsRecoD0ToPiK); + fillCharmMixedEvent(candsRecoD0ToKPi); fillTrkMixedEvent(tracks, cent, mult); } PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processMcD0ME, "Process Mixed Event for D0 candidates", false); @@ -699,8 +688,8 @@ struct HfDerivedDataCreatorCorrelationsReduced { return; } rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); - fillSameEvent(candsRecoLcToPKPi, tracks, cent, mult); - fillSameEvent(candsRecoLcToPiKP, tracks, cent, mult); + fillSameEvent(candsRecoLcToPKPi, tracks, cent, mult); + fillSameEvent(candsRecoLcToPiKP, tracks, cent, mult); } PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processMcLcSE, "Process Same Event for Lc candidates", false); @@ -719,8 +708,8 @@ struct HfDerivedDataCreatorCorrelationsReduced { return; } rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); - fillCharmMixedEvent(candsRecoLcToPKPi); - fillCharmMixedEvent(candsRecoLcToPiKP); + fillCharmMixedEvent(candsRecoLcToPKPi); + fillCharmMixedEvent(candsRecoLcToPiKP); fillTrkMixedEvent(tracks, cent, mult); } PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processMcLcME, "Process Mixed Event for Lc candidates", false); @@ -735,7 +724,7 @@ struct HfDerivedDataCreatorCorrelationsReduced { return; } rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); - fillSameEvent(tracks, tracks, cent, mult); + fillSameEvent(tracks, tracks, cent, mult); } PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processDataHadronHadronSE, "Process Same Event for hadron candidates", false); @@ -762,7 +751,7 @@ struct HfDerivedDataCreatorCorrelationsReduced { return; } rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); - fillSameEvent(tracks, tracks, cent, mult); + fillSameEvent(tracks, tracks, cent, mult); } PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processMcHadronHadronSE, "Process Same Event for hadron candidates", false); From a30c9c11eda2714f903c3ce3179f149a840c1554 Mon Sep 17 00:00:00 2001 From: Marcello Di Costanzo Date: Thu, 5 Nov 2026 18:51:07 +0100 Subject: [PATCH 10/18] Remove redundant curly braces --- PWGHF/HFC/Tasks/taskCorrelationsEfficiencies.cxx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/PWGHF/HFC/Tasks/taskCorrelationsEfficiencies.cxx b/PWGHF/HFC/Tasks/taskCorrelationsEfficiencies.cxx index fe7ff6b7e5a..8407dcbde82 100644 --- a/PWGHF/HFC/Tasks/taskCorrelationsEfficiencies.cxx +++ b/PWGHF/HFC/Tasks/taskCorrelationsEfficiencies.cxx @@ -205,10 +205,10 @@ struct HfTaskCorrelationsEfficiencies { const AxisSpec axisMlScore1 = {binsMlTwo, "ML score 1"}; std::vector axesCharmReco = {axisPtTrig, axisPvContrib, axisEtaTrig, axisPhiTrig, axisMlScore0, axisMlScore1}; - registry.add("hCharmPromptGen", "Generated prompt charm-hadron candidates;;", {HistType::kTHnSparseF}, {{axisPtTrig}, {axisEtaTrig}, {axisPhiTrig}}); - registry.add("hCharmFdGen", "Generated non-prompt charm-hadron candidates;;", {HistType::kTHnSparseF}, {{axisPtTrig}, {axisEtaTrig}, {axisPhiTrig}}); - registry.add("hCharmPromptReco", "Reconstructed prompt charm-hadron candidates;;", {HistType::kTHnSparseF}, axesCharmReco); - registry.add("hCharmFdReco", "Reconstructed non-prompt charm-hadron candidates;;", {HistType::kTHnSparseF}, axesCharmReco); + registry.add("hCharmPromptGen", "Generated prompt charm-hadron candidates;;", HistType::kTHnSparseF, {{axisPtTrig}, {axisEtaTrig}, {axisPhiTrig}}); + registry.add("hCharmFdGen", "Generated non-prompt charm-hadron candidates;;", HistType::kTHnSparseF, {{axisPtTrig}, {axisEtaTrig}, {axisPhiTrig}}); + registry.add("hCharmPromptReco", "Reconstructed prompt charm-hadron candidates;;", HistType::kTHnSparseF, axesCharmReco); + registry.add("hCharmFdReco", "Reconstructed non-prompt charm-hadron candidates;;", HistType::kTHnSparseF, axesCharmReco); // Axes: pt, eta, phi, z_vtx, specie const AxisSpec axisPtAssoc = {binsPtAssoc, "#it{p}_{T} Assoc (GeV/#it{c})"}; @@ -218,8 +218,8 @@ struct HfTaskCorrelationsEfficiencies { const AxisSpec axisAssTrkSpecie = {static_cast(NAssTracksTypes), -0.5, static_cast(NAssTracksTypes) - 0.5, "Particle species"}; const AxisSpec axisTrackOrigin = {2, -0.5, 1.5, "Particle origin"}; std::vector axesAssocTracks = {axisPtAssoc, axisEtaAssoc, axisPhiAssoc, axisZVtx, axisAssTrkSpecie, axisTrackOrigin}; - registry.add("hAssTrackReco", "Reconstructed associated tracks;;", {HistType::kTHnSparseF}, axesAssocTracks); - registry.add("hAssTrackGen", "Generated associated tracks;;", {HistType::kTHnSparseF}, axesAssocTracks); + registry.add("hAssTrackReco", "Reconstructed associated tracks;;", HistType::kTHnSparseF, axesAssocTracks); + registry.add("hAssTrackGen", "Generated associated tracks;;", HistType::kTHnSparseF, axesAssocTracks); } /// Match charm-hadron based on its reconstruction flag From aea761f3bddcfd9e031ebf7654d686ada7b79de8 Mon Sep 17 00:00:00 2001 From: Marcello Di Costanzo Date: Fri, 6 Nov 2026 21:00:58 +0100 Subject: [PATCH 11/18] Apply selections on generated collisions and tracks --- .../derivedDataCreatorCorrelationsReduced.cxx | 92 ++++++------- .../Tasks/taskCorrelationsEfficiencies.cxx | 73 +++++++--- PWGHF/HFC/Utils/utilsFlow.h | 125 +++++++++++++----- 3 files changed, 188 insertions(+), 102 deletions(-) diff --git a/PWGHF/HFC/TableProducer/derivedDataCreatorCorrelationsReduced.cxx b/PWGHF/HFC/TableProducer/derivedDataCreatorCorrelationsReduced.cxx index 3efa36a6d9f..e75330029db 100644 --- a/PWGHF/HFC/TableProducer/derivedDataCreatorCorrelationsReduced.cxx +++ b/PWGHF/HFC/TableProducer/derivedDataCreatorCorrelationsReduced.cxx @@ -17,7 +17,6 @@ #include "PWGHF/Core/CentralityEstimation.h" #include "PWGHF/Core/DecayChannels.h" -#include "PWGHF/Core/HfHelper.h" #include "PWGHF/DataModel/AliasTables.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" @@ -157,7 +156,8 @@ struct HfDerivedDataCreatorCorrelationsReduced { void init(InitContext&) { - hfEvSel.addHistograms(registry); // collision monitoring + hfEvSel.init(registry); + ccdb->setURL(ccdbUrl); ccdb->setCaching(true); ccdb->setLocalObjectValidityChecking(); @@ -176,7 +176,7 @@ struct HfDerivedDataCreatorCorrelationsReduced { return; } - hfcFlowHelper.init(ccdb, registry, classesMl, yCandMax.value); + hfcFlowHelper.init(classesMl, yCandMax.value); const AxisSpec axisTpcSignal = {binsTpcSignal, "TPC Signal"}; const AxisSpec axisCent = {binsCent, "Centrality"}; @@ -209,32 +209,6 @@ struct HfDerivedDataCreatorCorrelationsReduced { } }; // end init - /// Check event selections for collision and fill the collision table - /// \param collision is the collision - template - bool checkCollision(Coll const& collision, float& cent, float& mult) - { - o2::hf_evsel::HfCollisionRejectionMask collRejMask{}; - if (centEstimator == CentralityEstimator::FT0A) { - collRejMask = hfEvSel.getHfCollisionRejectionMask(collision, cent, ccdb, registry); - mult = collision.multFT0A(); - } else if (centEstimator == CentralityEstimator::FT0C) { - collRejMask = hfEvSel.getHfCollisionRejectionMask(collision, cent, ccdb, registry); - mult = collision.multFT0C(); - } else if (centEstimator == CentralityEstimator::FT0M) { - collRejMask = hfEvSel.getHfCollisionRejectionMask(collision, cent, ccdb, registry); - mult = collision.multFT0M(); - } else if (centEstimator == CentralityEstimator::FV0A) { - collRejMask = hfEvSel.getHfCollisionRejectionMask(collision, cent, ccdb, registry); - mult = collision.multFV0A(); - } else { - LOG(fatal) << "Centrality estimator not recognized for collision selection"; - std::abort(); - } - hfEvSel.fillHistograms(collision, collRejMask, cent); - return collRejMask == 0; - } - /// Checks if the trigger cand-associated track pair can be accepted for SE correlation /// \param assTrk is the associated track /// \param cand is the trigger candidate @@ -404,7 +378,8 @@ struct HfDerivedDataCreatorCorrelationsReduced { return; } float cent{-1.}, mult{-1.}; - if (!checkCollision(coll, cent, mult)) { + CentralityEstimator centDetector = static_cast(centEstimator.value); + if (!hfcFlowHelper.selectRecoCollision(hfEvSel, ccdb, registry, coll, centDetector, cent, mult)) { return; } rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); @@ -421,7 +396,8 @@ struct HfDerivedDataCreatorCorrelationsReduced { return; } float cent{-1.}, mult{-1.}; - if (!checkCollision(coll, cent, mult)) { + CentralityEstimator centDetector = static_cast(centEstimator.value); + if (!hfcFlowHelper.selectRecoCollision(hfEvSel, ccdb, registry, coll, centDetector, cent, mult)) { return; } rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); @@ -441,7 +417,8 @@ struct HfDerivedDataCreatorCorrelationsReduced { return; } float cent{-1.}, mult{-1.}; - if (!checkCollision(coll, cent, mult)) { + CentralityEstimator centDetector = static_cast(centEstimator.value); + if (!hfcFlowHelper.selectRecoCollision(hfEvSel, ccdb, registry, coll, centDetector, cent, mult)) { return; } rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); @@ -461,7 +438,8 @@ struct HfDerivedDataCreatorCorrelationsReduced { return; } float cent{-1.}, mult{-1.}; - if (!checkCollision(coll, cent, mult)) { + CentralityEstimator centDetector = static_cast(centEstimator.value); + if (!hfcFlowHelper.selectRecoCollision(hfEvSel, ccdb, registry, coll, centDetector, cent, mult)) { return; } rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); @@ -482,7 +460,8 @@ struct HfDerivedDataCreatorCorrelationsReduced { return; } float cent{-1.}, mult{-1.}; - if (!checkCollision(coll, cent, mult)) { + CentralityEstimator centDetector = static_cast(centEstimator.value); + if (!hfcFlowHelper.selectRecoCollision(hfEvSel, ccdb, registry, coll, centDetector, cent, mult)) { return; } rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); @@ -502,7 +481,8 @@ struct HfDerivedDataCreatorCorrelationsReduced { return; } float cent{-1.}, mult{-1.}; - if (!checkCollision(coll, cent, mult)) { + CentralityEstimator centDetector = static_cast(centEstimator.value); + if (!hfcFlowHelper.selectRecoCollision(hfEvSel, ccdb, registry, coll, centDetector, cent, mult)) { return; } rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); @@ -523,7 +503,8 @@ struct HfDerivedDataCreatorCorrelationsReduced { return; } float cent{-1.}, mult{-1.}; - if (!checkCollision(coll, cent, mult)) { + CentralityEstimator centDetector = static_cast(centEstimator.value); + if (!hfcFlowHelper.selectRecoCollision(hfEvSel, ccdb, registry, coll, centDetector, cent, mult)) { return; } rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); @@ -543,7 +524,8 @@ struct HfDerivedDataCreatorCorrelationsReduced { return; } float cent{-1.}, mult{-1.}; - if (!checkCollision(coll, cent, mult)) { + CentralityEstimator centDetector = static_cast(centEstimator.value); + if (!hfcFlowHelper.selectRecoCollision(hfEvSel, ccdb, registry, coll, centDetector, cent, mult)) { return; } rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); @@ -564,7 +546,8 @@ struct HfDerivedDataCreatorCorrelationsReduced { return; } float cent{-1.}, mult{-1.}; - if (!checkCollision(coll, cent, mult)) { + CentralityEstimator centDetector = static_cast(centEstimator.value); + if (!hfcFlowHelper.selectRecoCollision(hfEvSel, ccdb, registry, coll, centDetector, cent, mult)) { return; } rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); @@ -582,7 +565,8 @@ struct HfDerivedDataCreatorCorrelationsReduced { return; } float cent{-1.}, mult{-1.}; - if (!checkCollision(coll, cent, mult)) { + CentralityEstimator centDetector = static_cast(centEstimator.value); + if (!hfcFlowHelper.selectRecoCollision(hfEvSel, ccdb, registry, coll, centDetector, cent, mult)) { return; } rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); @@ -602,7 +586,8 @@ struct HfDerivedDataCreatorCorrelationsReduced { return; } float cent{-1.}, mult{-1.}; - if (!checkCollision(coll, cent, mult)) { + CentralityEstimator centDetector = static_cast(centEstimator.value); + if (!hfcFlowHelper.selectRecoCollision(hfEvSel, ccdb, registry, coll, centDetector, cent, mult)) { return; } rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); @@ -622,7 +607,8 @@ struct HfDerivedDataCreatorCorrelationsReduced { return; } float cent{-1.}, mult{-1.}; - if (!checkCollision(coll, cent, mult)) { + CentralityEstimator centDetector = static_cast(centEstimator.value); + if (!hfcFlowHelper.selectRecoCollision(hfEvSel, ccdb, registry, coll, centDetector, cent, mult)) { return; } rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); @@ -643,7 +629,8 @@ struct HfDerivedDataCreatorCorrelationsReduced { return; } float cent{-1.}, mult{-1.}; - if (!checkCollision(coll, cent, mult)) { + CentralityEstimator centDetector = static_cast(centEstimator.value); + if (!hfcFlowHelper.selectRecoCollision(hfEvSel, ccdb, registry, coll, centDetector, cent, mult)) { return; } rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); @@ -663,7 +650,8 @@ struct HfDerivedDataCreatorCorrelationsReduced { return; } float cent{-1.}, mult{-1.}; - if (!checkCollision(coll, cent, mult)) { + CentralityEstimator centDetector = static_cast(centEstimator.value); + if (!hfcFlowHelper.selectRecoCollision(hfEvSel, ccdb, registry, coll, centDetector, cent, mult)) { return; } rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); @@ -684,7 +672,8 @@ struct HfDerivedDataCreatorCorrelationsReduced { return; } float cent{-1.}, mult{-1.}; - if (!checkCollision(coll, cent, mult)) { + CentralityEstimator centDetector = static_cast(centEstimator.value); + if (!hfcFlowHelper.selectRecoCollision(hfEvSel, ccdb, registry, coll, centDetector, cent, mult)) { return; } rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); @@ -704,7 +693,8 @@ struct HfDerivedDataCreatorCorrelationsReduced { return; } float cent{-1.}, mult{-1.}; - if (!checkCollision(coll, cent, mult)) { + CentralityEstimator centDetector = static_cast(centEstimator.value); + if (!hfcFlowHelper.selectRecoCollision(hfEvSel, ccdb, registry, coll, centDetector, cent, mult)) { return; } rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); @@ -720,7 +710,8 @@ struct HfDerivedDataCreatorCorrelationsReduced { TracksData const& tracks) { float cent{-1.}, mult{-1.}; - if (!checkCollision(coll, cent, mult)) { + CentralityEstimator centDetector = static_cast(centEstimator.value); + if (!hfcFlowHelper.selectRecoCollision(hfEvSel, ccdb, registry, coll, centDetector, cent, mult)) { return; } rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); @@ -733,7 +724,8 @@ struct HfDerivedDataCreatorCorrelationsReduced { TracksData const& tracks) { float cent{-1.}, mult{-1.}; - if (!checkCollision(coll, cent, mult)) { + CentralityEstimator centDetector = static_cast(centEstimator.value); + if (!hfcFlowHelper.selectRecoCollision(hfEvSel, ccdb, registry, coll, centDetector, cent, mult)) { return; } rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); @@ -747,7 +739,8 @@ struct HfDerivedDataCreatorCorrelationsReduced { TracksMc const& tracks) { float cent{-1.}, mult{-1.}; - if (!checkCollision(coll, cent, mult)) { + CentralityEstimator centDetector = static_cast(centEstimator.value); + if (!hfcFlowHelper.selectRecoCollision(hfEvSel, ccdb, registry, coll, centDetector, cent, mult)) { return; } rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); @@ -760,7 +753,8 @@ struct HfDerivedDataCreatorCorrelationsReduced { TracksMc const& tracks) { float cent{-1.}, mult{-1.}; - if (!checkCollision(coll, cent, mult)) { + CentralityEstimator centDetector = static_cast(centEstimator.value); + if (!hfcFlowHelper.selectRecoCollision(hfEvSel, ccdb, registry, coll, centDetector, cent, mult)) { return; } rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); diff --git a/PWGHF/HFC/Tasks/taskCorrelationsEfficiencies.cxx b/PWGHF/HFC/Tasks/taskCorrelationsEfficiencies.cxx index 8407dcbde82..4f7f23735e9 100644 --- a/PWGHF/HFC/Tasks/taskCorrelationsEfficiencies.cxx +++ b/PWGHF/HFC/Tasks/taskCorrelationsEfficiencies.cxx @@ -21,6 +21,7 @@ #include "PWGHF/HFC/DataModel/DerivedDataCorrelationTables.h" #include "PWGHF/HFC/Utils/utilsFlow.h" #include "PWGHF/Utils/utilsEvSelHf.h" +#include "PWGLF/DataModel/mcCentrality.h" #include "Common/Core/RecoDecay.h" #include "Common/DataModel/Centrality.h" @@ -127,13 +128,17 @@ struct HfTaskCorrelationsEfficiencies { Configurable downSampleCharm{"downSampleCharm", 1., "Fraction of pairs to keep"}; Configurable ptMaxDownSampleCharm{"ptMaxDownSampleCharm", 10., "Maximum pt for the application of the downsampling factor"}; + HfEventSelection hfEvSel; // event selection and monitoring + HfEventSelectionMc hfEvSelMc; HfcFlowHelper hfcFlowHelper; // flow utilities o2::framework::Service ccdb{}; SliceCache cache; std::unique_ptr funcDcaXYPtCutPrimTrk{nullptr}; - using RecoCollisions = soa::Join; + using BCsInfo = soa::Join; + using McCollisionsWMult = soa::Join; + using RecoCollisions = soa::Join; using McCandsDs = soa::Filtered>; using McCandsDplus = soa::Filtered>; using McCandsD0 = soa::Filtered>; @@ -152,6 +157,7 @@ struct HfTaskCorrelationsEfficiencies { Preslice candsLcPerColl = aod::hf_cand::collisionId; Preslice trackIndicesPerColl = aod::track::collisionId; + PresliceUnsorted mcPartsPerMcCollision = aod::mcparticle::mcCollisionId; PresliceUnsorted colPerMcCollision = aod::mccollisionlabel::mcCollisionId; ConfigurableAxis binsPtCharm{"binsPtCharm", {VARIABLE_WIDTH, 0., 2., 4., 6., 8., 24.}, ""}; @@ -165,9 +171,18 @@ struct HfTaskCorrelationsEfficiencies { HistogramRegistry registry{"registry", {}}; - void init(InitContext&) + void init(InitContext& initContext) { + hfEvSel.init(registry); + const auto& workflows = initContext.services().get(); + for (const DeviceSpec& device : workflows.devices) { + if (device.name == "hf-task-correlations-efficiencies") { + // init HF event selection helper + hfEvSelMc.init(device, registry); + break; + } + } ccdb->setURL(ccdbUrl); ccdb->setCaching(true); ccdb->setLocalObjectValidityChecking(); @@ -186,7 +201,7 @@ struct HfTaskCorrelationsEfficiencies { return; } - hfcFlowHelper.init(ccdb, registry, classesMl, yCandMax.value); + hfcFlowHelper.init(classesMl, yCandMax.value); // Setup pt-dependent DCAxy cut function if (usePtDiffDcaXYCut) { @@ -304,7 +319,8 @@ struct HfTaskCorrelationsEfficiencies { continue; } float cent{-1.}, mult{-1.}; - if (!hfcFlowHelper.checkCollision(coll, cent, mult)) { + CentralityEstimator centDetector = CentralityEstimator::None; + if (!hfcFlowHelper.selectRecoCollision(hfEvSel, ccdb, registry, coll, centDetector, cent, mult)) { continue; } fillCharmEfficiencies(candsInColl, coll.numContrib()); @@ -357,20 +373,27 @@ struct HfTaskCorrelationsEfficiencies { void processEffAssTracks(RecoCollisions const& recoCollisions, McTracks const& recoTracks, aod::McParticles const& genParticles, - aod::McCollisions const&) + McCollisionsWMult const& genCollisions, + BCsInfo const&) { for (const auto& coll : recoCollisions) { float cent{-1.}, mult{-1.}; - if (!hfcFlowHelper.checkCollision(coll, cent, mult)) { + CentralityEstimator centDetector = CentralityEstimator::None; + if (!hfcFlowHelper.selectRecoCollision(hfEvSel, ccdb, registry, coll, centDetector, cent, mult)) { continue; } if (!coll.has_mcCollision()) { continue; } - auto mcCollision = coll.template mcCollision_as(); + auto mcCollision = coll.template mcCollision_as(); auto tracksInColl = recoTracks.sliceBy(trackIndicesPerColl, coll.globalIndex()); for (const auto& assTrk : tracksInColl) { + + if (!assTrk.isGlobalTrackWoDCA() || assTrk.tpcNClsCrossedRows() < tpcNClsCrossedRowsMin) { + continue; + } + if (!assTrk.has_mcParticle()) { continue; } @@ -410,23 +433,33 @@ struct HfTaskCorrelationsEfficiencies { } // Fill histograms for generated associated tracks - for (const auto& genTrk : genParticles) { - int matchedSpecie = getAssocTrkSpecie(genTrk); - if (matchedSpecie < 0) { - continue; - } - if (!genTrk.has_mcCollision()) { - continue; - } + for (const auto& mcColl : genCollisions) { - // Pt and eta selection - if (genTrk.pt() < ptTrkMin || genTrk.pt() > ptTrkMax || std::fabs(genTrk.eta()) > etaTrkMax) { + float cent{-1.}, mult{-1.}; + const auto recoColls = recoCollisions.sliceBy(colPerMcCollision, mcColl.globalIndex()); + CentralityEstimator centDetector = CentralityEstimator::None; + if (!hfcFlowHelper.selectGenCollision(hfEvSelMc, mcColl, recoColls, centDetector, cent, mult)) { continue; } - int genTrkOrigin = genTrk.isPhysicalPrimary() ? 0 : 1; // 0 for primary, 1 for secondary - auto genCollision = genTrk.template mcCollision_as(); - registry.fill(HIST("hAssTrackGen"), genTrk.pt(), genTrk.eta(), genTrk.phi(), genCollision.posZ(), matchedSpecie, genTrkOrigin); + const auto groupedMcParticles = genParticles.sliceBy(mcPartsPerMcCollision, mcColl.globalIndex()); + for (const auto& genTrk : groupedMcParticles) { + int matchedSpecie = getAssocTrkSpecie(genTrk); + if (matchedSpecie < 0) { + continue; + } + if (!genTrk.has_mcCollision()) { + // Should never happen because we group on the generated collisions + continue; + } + + // Pt and eta selection + if (genTrk.pt() < ptTrkMin || genTrk.pt() > ptTrkMax || std::fabs(genTrk.eta()) > etaTrkMax) { + continue; + } + int genTrkOrigin = genTrk.isPhysicalPrimary() ? 0 : 1; // 0 for primary, 1 for secondary + registry.fill(HIST("hAssTrackGen"), genTrk.pt(), genTrk.eta(), genTrk.phi(), mcColl.posZ(), matchedSpecie, genTrkOrigin); + } } } PROCESS_SWITCH(HfTaskCorrelationsEfficiencies, processEffAssTracks, "Process efficiencies for associated tracks", true); diff --git a/PWGHF/HFC/Utils/utilsFlow.h b/PWGHF/HFC/Utils/utilsFlow.h index 52b4885bfe4..162aa414518 100644 --- a/PWGHF/HFC/Utils/utilsFlow.h +++ b/PWGHF/HFC/Utils/utilsFlow.h @@ -79,18 +79,12 @@ class HfcFlowHelper /// \param histRegistry is the histogram registry /// \param mlClasses are the machine learning classes /// \param maxRapidity is the maximum rapidity - void init(o2::framework::Service& ccdbService, - o2::framework::HistogramRegistry& histRegistry, - std::vector mlClasses, + void init(std::vector mlClasses, float maxRapidity) { - - LOG(info) << "Initializing HFC flow helper!"; - this->hfEvSel.addHistograms(histRegistry); - this->ccdb = &ccdbService; - this->registry = &histRegistry; this->classMl = std::move(mlClasses); this->yCandMax = maxRapidity; + LOG(info) << "HFC flow helper initialized"; } /// Get charm hadron candidate mass @@ -168,6 +162,7 @@ class HfcFlowHelper /// Cut on rapidity of the candidate /// \param candidate is the charm hadron candidate + /// \return true if the candidate passes the rapidity cut, false otherwise template bool cutCandRapidity(const TCand& candidate) { @@ -186,39 +181,103 @@ class HfcFlowHelper return std::fabs(y) < yCandMax; } - /// Check event selections for collision and fill the collision table + /// Runtime dispatch to the compile-time checkCollision /// \param collision is the collision - template - bool checkCollision(Coll const& collision, float& cent, float& mult) + /// \param centEst is the centrality estimator + /// \param cent is the centrality value + /// \param mult is the multiplicity value + template + bool selectGenCollision(o2::hf_evsel::HfEventSelectionMc& hfEvSelMc, + GenColl const& genColl, + RecoCollSlice const& recoCollsSlice, + o2::hf_centrality::CentralityEstimator centEst, + float& cent, + float& mult) { + int nSplitColl = recoCollsSlice.size(); o2::hf_evsel::HfCollisionRejectionMask collRejMask{}; - if constexpr (CentEst == o2::hf_centrality::CentralityEstimator::FT0A) { - collRejMask = hfEvSel.getHfCollisionRejectionMask(collision, cent, *ccdb, *registry); - mult = collision.multFT0A(); - } else if constexpr (CentEst == o2::hf_centrality::CentralityEstimator::FT0C) { - collRejMask = hfEvSel.getHfCollisionRejectionMask(collision, cent, *ccdb, *registry); - mult = collision.multFT0C(); - } else if constexpr (CentEst == o2::hf_centrality::CentralityEstimator::FT0M) { - collRejMask = hfEvSel.getHfCollisionRejectionMask(collision, cent, *ccdb, *registry); - mult = collision.multFT0M(); - } else if constexpr (CentEst == o2::hf_centrality::CentralityEstimator::FV0A) { - collRejMask = hfEvSel.getHfCollisionRejectionMask(collision, cent, *ccdb, *registry); - mult = collision.multFV0A(); - } else if constexpr (CentEst == o2::hf_centrality::CentralityEstimator::None) { - collRejMask = hfEvSel.getHfCollisionRejectionMask(collision, cent, *ccdb, *registry); - mult = -1.f; - } else { - LOG(fatal) << "Centrality estimator not recognized for collision selection"; - std::abort(); + switch (centEst) { + case o2::hf_centrality::CentralityEstimator::FT0A: + collRejMask = hfEvSelMc.getHfMcCollisionRejectionMask(genColl, recoCollsSlice, cent); + mult = o2::hf_centrality::getCentralityGenColl(recoCollsSlice, o2::hf_centrality::CentralityEstimator::FT0A); + hfEvSelMc.fillHistograms(genColl, collRejMask, nSplitColl); + break; + case o2::hf_centrality::CentralityEstimator::FT0C: + collRejMask = hfEvSelMc.getHfMcCollisionRejectionMask(genColl, recoCollsSlice, cent); + mult = o2::hf_centrality::getCentralityGenColl(recoCollsSlice, o2::hf_centrality::CentralityEstimator::FT0C); + hfEvSelMc.fillHistograms(genColl, collRejMask, nSplitColl); + break; + case o2::hf_centrality::CentralityEstimator::FT0M: + collRejMask = hfEvSelMc.getHfMcCollisionRejectionMask(genColl, recoCollsSlice, cent); + mult = o2::hf_centrality::getCentralityGenColl(recoCollsSlice, o2::hf_centrality::CentralityEstimator::FT0M); + hfEvSelMc.fillHistograms(genColl, collRejMask, nSplitColl); + break; + case o2::hf_centrality::CentralityEstimator::FV0A: + collRejMask = hfEvSelMc.getHfMcCollisionRejectionMask(genColl, recoCollsSlice, cent); + mult = o2::hf_centrality::getCentralityGenColl(recoCollsSlice, o2::hf_centrality::CentralityEstimator::FV0A); + hfEvSelMc.fillHistograms(genColl, collRejMask, nSplitColl); + break; + case o2::hf_centrality::CentralityEstimator::None: + collRejMask = hfEvSelMc.getHfMcCollisionRejectionMask(genColl, recoCollsSlice, cent); + mult = -1.f; + hfEvSelMc.fillHistograms(genColl, collRejMask, nSplitColl); + break; + default: + LOG(fatal) << "Centrality estimator not recognized for collision selection"; + std::abort(); + } + + + return (collRejMask == 0); + } + + /// Apply event selection on reconstructed collisions + /// \param collision is the collision + /// \param centEst is the centrality estimator + /// \param cent is the centrality value + /// \param mult is the multiplicity value + template + bool selectRecoCollision(o2::hf_evsel::HfEventSelection& hfEvSel, + o2::framework::Service& ccdb, + o2::framework::HistogramRegistry& registry, + Coll const& collision, + o2::hf_centrality::CentralityEstimator centEst, + float& cent, + float& mult) + { + o2::hf_evsel::HfCollisionRejectionMask collRejMask{}; + switch (centEst) { + case o2::hf_centrality::CentralityEstimator::FT0A: + collRejMask = hfEvSel.getHfCollisionRejectionMask(collision, cent, ccdb, registry); + mult = collision.multFT0A(); + break; + case o2::hf_centrality::CentralityEstimator::FT0C: + collRejMask = hfEvSel.getHfCollisionRejectionMask(collision, cent, ccdb, registry); + mult = collision.multFT0C(); + break; + case o2::hf_centrality::CentralityEstimator::FT0M: + collRejMask = hfEvSel.getHfCollisionRejectionMask(collision, cent, ccdb, registry); + mult = collision.multFT0M(); + break; + case o2::hf_centrality::CentralityEstimator::FV0A: + collRejMask = hfEvSel.getHfCollisionRejectionMask(collision, cent, ccdb, registry); + mult = collision.multFV0A(); + break; + case o2::hf_centrality::CentralityEstimator::None: + collRejMask = hfEvSel.getHfCollisionRejectionMask(collision, cent, ccdb, registry); + mult = -1.f; + break; + default: + LOG(fatal) << "Centrality estimator not recognized for collision selection"; + std::abort(); } + hfEvSel.fillHistograms(collision, collRejMask, cent); - return collRejMask == 0; + + return (collRejMask == 0); } private: - o2::hf_evsel::HfEventSelection hfEvSel; - o2::framework::Service* ccdb{nullptr}; - o2::framework::HistogramRegistry* registry{nullptr}; std::vector classMl{}; float yCandMax{-999.f}; }; From 3583ac85eec1b13d8a5d37082e118f02e7041775 Mon Sep 17 00:00:00 2001 From: ALICE Action Bot Date: Fri, 6 Nov 2026 20:02:21 +0000 Subject: [PATCH 12/18] Please consider the following formatting changes --- PWGHF/HFC/Utils/utilsFlow.h | 1 - 1 file changed, 1 deletion(-) diff --git a/PWGHF/HFC/Utils/utilsFlow.h b/PWGHF/HFC/Utils/utilsFlow.h index 162aa414518..8b88de446d8 100644 --- a/PWGHF/HFC/Utils/utilsFlow.h +++ b/PWGHF/HFC/Utils/utilsFlow.h @@ -227,7 +227,6 @@ class HfcFlowHelper std::abort(); } - return (collRejMask == 0); } From 843d69211a5cdad64a2d2ef8ee03a1dc1e7aebbb Mon Sep 17 00:00:00 2001 From: ALICE Action Bot Date: Fri, 6 Nov 2026 20:05:42 +0000 Subject: [PATCH 13/18] Please consider the following formatting changes --- PWGHF/HFC/Utils/utilsFlow.h | 1 - 1 file changed, 1 deletion(-) diff --git a/PWGHF/HFC/Utils/utilsFlow.h b/PWGHF/HFC/Utils/utilsFlow.h index 162aa414518..8b88de446d8 100644 --- a/PWGHF/HFC/Utils/utilsFlow.h +++ b/PWGHF/HFC/Utils/utilsFlow.h @@ -227,7 +227,6 @@ class HfcFlowHelper std::abort(); } - return (collRejMask == 0); } From b95cf70aed4b4fe349bda0c864e62ab1c0315f55 Mon Sep 17 00:00:00 2001 From: Marcello Di Costanzo Date: Fri, 6 Nov 2026 22:17:22 +0100 Subject: [PATCH 14/18] Fix code check --- PWGHF/HFC/Tasks/taskCorrelationsEfficiencies.cxx | 2 ++ PWGHF/HFC/Utils/utilsFlow.h | 12 ------------ 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/PWGHF/HFC/Tasks/taskCorrelationsEfficiencies.cxx b/PWGHF/HFC/Tasks/taskCorrelationsEfficiencies.cxx index 4f7f23735e9..48c9ba13e9f 100644 --- a/PWGHF/HFC/Tasks/taskCorrelationsEfficiencies.cxx +++ b/PWGHF/HFC/Tasks/taskCorrelationsEfficiencies.cxx @@ -15,6 +15,7 @@ #include "PWGHF/Core/CentralityEstimation.h" #include "PWGHF/Core/HfHelper.h" +#include "PWGHF/Core/DecayChannels.h" #include "PWGHF/DataModel/AliasTables.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" @@ -44,6 +45,7 @@ #include #include +#include #include #include diff --git a/PWGHF/HFC/Utils/utilsFlow.h b/PWGHF/HFC/Utils/utilsFlow.h index 162aa414518..d89fe0c487a 100644 --- a/PWGHF/HFC/Utils/utilsFlow.h +++ b/PWGHF/HFC/Utils/utilsFlow.h @@ -17,31 +17,19 @@ #define PWGHF_HFC_UTILS_UTILSFLOW_H_ #include "PWGHF/Core/CentralityEstimation.h" -#include "PWGHF/Core/DecayChannels.h" #include "PWGHF/Core/HfHelper.h" #include "PWGHF/Utils/utilsEvSelHf.h" -#include "Common/Core/RecoDecay.h" - #include -#include -#include #include #include #include -#include -#include #include -#include #include #include #include -#include - #include -#include -#include #include #include From 40a1e8ecbb29c53654460305186393b3567a0c53 Mon Sep 17 00:00:00 2001 From: ALICE Action Bot Date: Fri, 6 Nov 2026 21:19:12 +0000 Subject: [PATCH 15/18] Please consider the following formatting changes --- PWGHF/HFC/Tasks/taskCorrelationsEfficiencies.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PWGHF/HFC/Tasks/taskCorrelationsEfficiencies.cxx b/PWGHF/HFC/Tasks/taskCorrelationsEfficiencies.cxx index 48c9ba13e9f..753db335b82 100644 --- a/PWGHF/HFC/Tasks/taskCorrelationsEfficiencies.cxx +++ b/PWGHF/HFC/Tasks/taskCorrelationsEfficiencies.cxx @@ -14,8 +14,8 @@ /// \author Marcello Di Costanzo , Politecnico and INFN Torino #include "PWGHF/Core/CentralityEstimation.h" -#include "PWGHF/Core/HfHelper.h" #include "PWGHF/Core/DecayChannels.h" +#include "PWGHF/Core/HfHelper.h" #include "PWGHF/DataModel/AliasTables.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" From eb52e7ad58eb3562a48b191d10ba3d71ba4c5cf1 Mon Sep 17 00:00:00 2001 From: Marcello Di Costanzo Date: Sat, 7 Nov 2026 15:43:28 +0100 Subject: [PATCH 16/18] Fix code-check --- .../derivedDataCreatorCorrelationsReduced.cxx | 45 +++++++++---------- .../Tasks/taskCorrelationsEfficiencies.cxx | 10 ++--- PWGHF/HFC/Utils/utilsFlow.h | 5 ++- 3 files changed, 30 insertions(+), 30 deletions(-) diff --git a/PWGHF/HFC/TableProducer/derivedDataCreatorCorrelationsReduced.cxx b/PWGHF/HFC/TableProducer/derivedDataCreatorCorrelationsReduced.cxx index e75330029db..73157c06d08 100644 --- a/PWGHF/HFC/TableProducer/derivedDataCreatorCorrelationsReduced.cxx +++ b/PWGHF/HFC/TableProducer/derivedDataCreatorCorrelationsReduced.cxx @@ -32,7 +32,6 @@ #include #include -#include #include #include #include @@ -378,7 +377,7 @@ struct HfDerivedDataCreatorCorrelationsReduced { return; } float cent{-1.}, mult{-1.}; - CentralityEstimator centDetector = static_cast(centEstimator.value); + auto centDetector = static_cast(centEstimator.value); if (!hfcFlowHelper.selectRecoCollision(hfEvSel, ccdb, registry, coll, centDetector, cent, mult)) { return; } @@ -396,7 +395,7 @@ struct HfDerivedDataCreatorCorrelationsReduced { return; } float cent{-1.}, mult{-1.}; - CentralityEstimator centDetector = static_cast(centEstimator.value); + auto centDetector = static_cast(centEstimator.value); if (!hfcFlowHelper.selectRecoCollision(hfEvSel, ccdb, registry, coll, centDetector, cent, mult)) { return; } @@ -417,7 +416,7 @@ struct HfDerivedDataCreatorCorrelationsReduced { return; } float cent{-1.}, mult{-1.}; - CentralityEstimator centDetector = static_cast(centEstimator.value); + auto centDetector = static_cast(centEstimator.value); if (!hfcFlowHelper.selectRecoCollision(hfEvSel, ccdb, registry, coll, centDetector, cent, mult)) { return; } @@ -438,7 +437,7 @@ struct HfDerivedDataCreatorCorrelationsReduced { return; } float cent{-1.}, mult{-1.}; - CentralityEstimator centDetector = static_cast(centEstimator.value); + auto centDetector = static_cast(centEstimator.value); if (!hfcFlowHelper.selectRecoCollision(hfEvSel, ccdb, registry, coll, centDetector, cent, mult)) { return; } @@ -460,7 +459,7 @@ struct HfDerivedDataCreatorCorrelationsReduced { return; } float cent{-1.}, mult{-1.}; - CentralityEstimator centDetector = static_cast(centEstimator.value); + auto centDetector = static_cast(centEstimator.value); if (!hfcFlowHelper.selectRecoCollision(hfEvSel, ccdb, registry, coll, centDetector, cent, mult)) { return; } @@ -481,7 +480,7 @@ struct HfDerivedDataCreatorCorrelationsReduced { return; } float cent{-1.}, mult{-1.}; - CentralityEstimator centDetector = static_cast(centEstimator.value); + auto centDetector = static_cast(centEstimator.value); if (!hfcFlowHelper.selectRecoCollision(hfEvSel, ccdb, registry, coll, centDetector, cent, mult)) { return; } @@ -503,7 +502,7 @@ struct HfDerivedDataCreatorCorrelationsReduced { return; } float cent{-1.}, mult{-1.}; - CentralityEstimator centDetector = static_cast(centEstimator.value); + auto centDetector = static_cast(centEstimator.value); if (!hfcFlowHelper.selectRecoCollision(hfEvSel, ccdb, registry, coll, centDetector, cent, mult)) { return; } @@ -524,7 +523,7 @@ struct HfDerivedDataCreatorCorrelationsReduced { return; } float cent{-1.}, mult{-1.}; - CentralityEstimator centDetector = static_cast(centEstimator.value); + auto centDetector = static_cast(centEstimator.value); if (!hfcFlowHelper.selectRecoCollision(hfEvSel, ccdb, registry, coll, centDetector, cent, mult)) { return; } @@ -546,7 +545,7 @@ struct HfDerivedDataCreatorCorrelationsReduced { return; } float cent{-1.}, mult{-1.}; - CentralityEstimator centDetector = static_cast(centEstimator.value); + auto centDetector = static_cast(centEstimator.value); if (!hfcFlowHelper.selectRecoCollision(hfEvSel, ccdb, registry, coll, centDetector, cent, mult)) { return; } @@ -565,7 +564,7 @@ struct HfDerivedDataCreatorCorrelationsReduced { return; } float cent{-1.}, mult{-1.}; - CentralityEstimator centDetector = static_cast(centEstimator.value); + auto centDetector = static_cast(centEstimator.value); if (!hfcFlowHelper.selectRecoCollision(hfEvSel, ccdb, registry, coll, centDetector, cent, mult)) { return; } @@ -586,7 +585,7 @@ struct HfDerivedDataCreatorCorrelationsReduced { return; } float cent{-1.}, mult{-1.}; - CentralityEstimator centDetector = static_cast(centEstimator.value); + auto centDetector = static_cast(centEstimator.value); if (!hfcFlowHelper.selectRecoCollision(hfEvSel, ccdb, registry, coll, centDetector, cent, mult)) { return; } @@ -607,7 +606,7 @@ struct HfDerivedDataCreatorCorrelationsReduced { return; } float cent{-1.}, mult{-1.}; - CentralityEstimator centDetector = static_cast(centEstimator.value); + auto centDetector = static_cast(centEstimator.value); if (!hfcFlowHelper.selectRecoCollision(hfEvSel, ccdb, registry, coll, centDetector, cent, mult)) { return; } @@ -629,7 +628,7 @@ struct HfDerivedDataCreatorCorrelationsReduced { return; } float cent{-1.}, mult{-1.}; - CentralityEstimator centDetector = static_cast(centEstimator.value); + auto centDetector = static_cast(centEstimator.value); if (!hfcFlowHelper.selectRecoCollision(hfEvSel, ccdb, registry, coll, centDetector, cent, mult)) { return; } @@ -650,7 +649,7 @@ struct HfDerivedDataCreatorCorrelationsReduced { return; } float cent{-1.}, mult{-1.}; - CentralityEstimator centDetector = static_cast(centEstimator.value); + auto centDetector = static_cast(centEstimator.value); if (!hfcFlowHelper.selectRecoCollision(hfEvSel, ccdb, registry, coll, centDetector, cent, mult)) { return; } @@ -672,7 +671,7 @@ struct HfDerivedDataCreatorCorrelationsReduced { return; } float cent{-1.}, mult{-1.}; - CentralityEstimator centDetector = static_cast(centEstimator.value); + auto centDetector = static_cast(centEstimator.value); if (!hfcFlowHelper.selectRecoCollision(hfEvSel, ccdb, registry, coll, centDetector, cent, mult)) { return; } @@ -693,7 +692,7 @@ struct HfDerivedDataCreatorCorrelationsReduced { return; } float cent{-1.}, mult{-1.}; - CentralityEstimator centDetector = static_cast(centEstimator.value); + auto centDetector = static_cast(centEstimator.value); if (!hfcFlowHelper.selectRecoCollision(hfEvSel, ccdb, registry, coll, centDetector, cent, mult)) { return; } @@ -710,7 +709,7 @@ struct HfDerivedDataCreatorCorrelationsReduced { TracksData const& tracks) { float cent{-1.}, mult{-1.}; - CentralityEstimator centDetector = static_cast(centEstimator.value); + auto centDetector = static_cast(centEstimator.value); if (!hfcFlowHelper.selectRecoCollision(hfEvSel, ccdb, registry, coll, centDetector, cent, mult)) { return; } @@ -724,7 +723,7 @@ struct HfDerivedDataCreatorCorrelationsReduced { TracksData const& tracks) { float cent{-1.}, mult{-1.}; - CentralityEstimator centDetector = static_cast(centEstimator.value); + auto centDetector = static_cast(centEstimator.value); if (!hfcFlowHelper.selectRecoCollision(hfEvSel, ccdb, registry, coll, centDetector, cent, mult)) { return; } @@ -739,7 +738,7 @@ struct HfDerivedDataCreatorCorrelationsReduced { TracksMc const& tracks) { float cent{-1.}, mult{-1.}; - CentralityEstimator centDetector = static_cast(centEstimator.value); + auto centDetector = static_cast(centEstimator.value); if (!hfcFlowHelper.selectRecoCollision(hfEvSel, ccdb, registry, coll, centDetector, cent, mult)) { return; } @@ -753,7 +752,7 @@ struct HfDerivedDataCreatorCorrelationsReduced { TracksMc const& tracks) { float cent{-1.}, mult{-1.}; - CentralityEstimator centDetector = static_cast(centEstimator.value); + auto centDetector = static_cast(centEstimator.value); if (!hfcFlowHelper.selectRecoCollision(hfEvSel, ccdb, registry, coll, centDetector, cent, mult)) { return; } @@ -763,7 +762,7 @@ struct HfDerivedDataCreatorCorrelationsReduced { PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processMcHadronHadronME, "Process Mixed Event for hadron candidates", false); }; -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +WorkflowSpec defineDataProcessing(ConfigContext const& context) { - return WorkflowSpec{adaptAnalysisTask(cfgc)}; + return WorkflowSpec{adaptAnalysisTask(context)}; } diff --git a/PWGHF/HFC/Tasks/taskCorrelationsEfficiencies.cxx b/PWGHF/HFC/Tasks/taskCorrelationsEfficiencies.cxx index 48c9ba13e9f..39aee0aa764 100644 --- a/PWGHF/HFC/Tasks/taskCorrelationsEfficiencies.cxx +++ b/PWGHF/HFC/Tasks/taskCorrelationsEfficiencies.cxx @@ -14,7 +14,6 @@ /// \author Marcello Di Costanzo , Politecnico and INFN Torino #include "PWGHF/Core/CentralityEstimation.h" -#include "PWGHF/Core/HfHelper.h" #include "PWGHF/Core/DecayChannels.h" #include "PWGHF/DataModel/AliasTables.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" @@ -31,20 +30,21 @@ #include "Common/DataModel/TrackSelectionTables.h" #include -#include -#include #include #include #include #include #include +#include #include #include #include #include #include +#include #include +#include #include #include @@ -467,7 +467,7 @@ struct HfTaskCorrelationsEfficiencies { PROCESS_SWITCH(HfTaskCorrelationsEfficiencies, processEffAssTracks, "Process efficiencies for associated tracks", true); }; -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +WorkflowSpec defineDataProcessing(ConfigContext const& context) { - return WorkflowSpec{adaptAnalysisTask(cfgc)}; + return WorkflowSpec{adaptAnalysisTask(context)}; } diff --git a/PWGHF/HFC/Utils/utilsFlow.h b/PWGHF/HFC/Utils/utilsFlow.h index d9127e580f6..8d345728769 100644 --- a/PWGHF/HFC/Utils/utilsFlow.h +++ b/PWGHF/HFC/Utils/utilsFlow.h @@ -25,11 +25,12 @@ #include #include #include -#include #include #include #include +#include +#include #include #include @@ -265,7 +266,7 @@ class HfcFlowHelper } private: - std::vector classMl{}; + std::vector classMl; float yCandMax{-999.f}; }; From 0acb6ef786cfcbdbbecd5425dd5fbf57f86db8fb Mon Sep 17 00:00:00 2001 From: ALICE Action Bot Date: Sat, 7 Nov 2026 14:44:39 +0000 Subject: [PATCH 17/18] Please consider the following formatting changes --- PWGHF/HFC/Tasks/taskCorrelationsEfficiencies.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PWGHF/HFC/Tasks/taskCorrelationsEfficiencies.cxx b/PWGHF/HFC/Tasks/taskCorrelationsEfficiencies.cxx index 618223fe684..13f110350c8 100644 --- a/PWGHF/HFC/Tasks/taskCorrelationsEfficiencies.cxx +++ b/PWGHF/HFC/Tasks/taskCorrelationsEfficiencies.cxx @@ -41,8 +41,8 @@ #include #include #include -#include #include +#include #include #include From 110c106c948c9c5a4bccee6e726756c3a5525dc0 Mon Sep 17 00:00:00 2001 From: Marcello Di Costanzo Date: Sun, 8 Nov 2026 12:25:17 +0100 Subject: [PATCH 18/18] Remove redundant header --- PWGHF/HFC/Tasks/taskCorrelationsEfficiencies.cxx | 1 - 1 file changed, 1 deletion(-) diff --git a/PWGHF/HFC/Tasks/taskCorrelationsEfficiencies.cxx b/PWGHF/HFC/Tasks/taskCorrelationsEfficiencies.cxx index 618223fe684..39aee0aa764 100644 --- a/PWGHF/HFC/Tasks/taskCorrelationsEfficiencies.cxx +++ b/PWGHF/HFC/Tasks/taskCorrelationsEfficiencies.cxx @@ -15,7 +15,6 @@ #include "PWGHF/Core/CentralityEstimation.h" #include "PWGHF/Core/DecayChannels.h" -#include "PWGHF/Core/HfHelper.h" #include "PWGHF/DataModel/AliasTables.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h"