From 03bfc17cef1eb80534e7342b7c8c76a2e197fa07 Mon Sep 17 00:00:00 2001 From: marcellocosti Date: Fri, 28 Aug 2026 12:19:45 +0200 Subject: [PATCH 1/4] Add candidate-by-candidate resolution correction --- PWGHF/D2H/Tasks/taskFlowCharmHadrons.cxx | 292 +++++++++++++++-------- PWGHF/D2H/Utils/utilsFlow.h | 49 ++++ 2 files changed, 237 insertions(+), 104 deletions(-) diff --git a/PWGHF/D2H/Tasks/taskFlowCharmHadrons.cxx b/PWGHF/D2H/Tasks/taskFlowCharmHadrons.cxx index e6b87bd46f9..3cb8e7ce7a1 100644 --- a/PWGHF/D2H/Tasks/taskFlowCharmHadrons.cxx +++ b/PWGHF/D2H/Tasks/taskFlowCharmHadrons.cxx @@ -76,6 +76,7 @@ DECLARE_SOA_COLUMN(MlScore0, mlScore0, float); //! ML score of the first con DECLARE_SOA_COLUMN(MlScore1, mlScore1, float); //! ML score of the second configured index DECLARE_SOA_COLUMN(ScalarProd, scalarProd, float); //! Scalar product DECLARE_SOA_COLUMN(Cent, cent, float); //! Centrality +DECLARE_SOA_COLUMN(PvContrib, pvContrib, float); //! Number of primary vertex contributors DECLARE_SOA_COLUMN(RedQVec, redQVec, float); //! Reduced Q-vector } // namespace full DECLARE_SOA_TABLE(HfCandMPtInfos, "AOD", "HFCANDMPTINFO", @@ -91,6 +92,14 @@ DECLARE_SOA_TABLE(HfCandFlowInfos, "AOD", "HFCANDFLOWINFO", full::MlScore1, full::ScalarProd, full::Cent); +DECLARE_SOA_TABLE(HfCandFlowMcs, "AOD", "HFCANDFLOWMC", + full::M, + full::Pt, + full::MlScore0, + full::MlScore1, + full::ScalarProd, + full::Cent, + full::PvContrib); DECLARE_SOA_TABLE(HfCandFlowEses, "AOD", "HFCANDFLOWESE", full::M, full::Pt, @@ -123,6 +132,7 @@ struct HfTaskFlowCharmHadrons { Produces rowCandMassPtMl; Produces rowCandMassPtMlSpCent; Produces rowCandFlowEsE; + Produces rowCandFlowMc; Configurable harmonic{"harmonic", 2, "harmonic number"}; Configurable qVecDetector{"qVecDetector", 3, "Detector for Q vector estimation (FV0A: 0, FT0M: 1, FT0A: 2, FT0C: 3, TPC Pos: 4, TPC Neg: 5, TPC Tot: 6)"}; @@ -135,8 +145,10 @@ struct HfTaskFlowCharmHadrons { Configurable storeMl{"storeMl", false, "Flag to store ML scores"}; Configurable storeSPQVec{"storeSPQVec", true, "Flag to store the Q-vectors for SP"}; Configurable storeRedQVec{"storeRedQVec", false, "Flag to store reduced Q-vectors for ESE"}; + Configurable subtractDaugsFromRedQVec{"subtractDaugsFromRedQVec", true, "Flag to subtract daughter tracks from reduced Q-vectors for ESE"}; Configurable fillMassPtMlTree{"fillMassPtMlTree", false, "Flag to fill mass, pt and ML scores tree"}; Configurable fillMassPtMlSpCentTree{"fillMassPtMlSpCentTree", false, "Flag to fill mass, pt, ML scores, SP and centrality tree"}; + Configurable fillMassPtMlSpCentPvTree{"fillMassPtMlSpCentPvTree", false, "Flag to fill mass, pt, ML scores, SP, centrality, PV contrib tree"}; Configurable fillSparse{"fillSparse", true, "Flag to fill sparse"}; Configurable downSampleFactor{"downSampleFactor", 1., "Fraction of candidates to keep in TTree"}; Configurable ptDownSampleMax{"ptDownSampleMax", 10., "Maximum pt for the application of the downsampling factor"}; @@ -149,12 +161,18 @@ struct HfTaskFlowCharmHadrons { Configurable occEstimator{"occEstimator", 0, "Occupancy estimation (0: None, 1: ITS, 2: FT0C)"}; Configurable saveEpResoHisto{"saveEpResoHisto", false, "Flag to save event plane resolution histogram"}; Configurable ccdbUrl{"ccdbUrl", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable ccdbResoHistPath{"ccdbResoHistPath", "", "path to the resolution histogram in the ccdb"}; + Configurable useOnlineResoCorrection{"useOnlineResoCorrection", false, "True to fill candidate histograms with SP / R"}; + Configurable resoTripletPath{"resoTripletPath", "FT0c_FV0a_TPCtot", "Detector resolution triplet for online correction"}; Configurable> classMl{"classMl", {0, 2}, "Indexes of BDT scores to be stored. Two indexes max."}; EventPlaneHelper epHelper; HfEventSelection hfEvSel; // event selection and monitoring o2::framework::Service ccdb{}; SliceCache cache; + QVectorResoHelper qVecResoHelper; + int lastRunNumber{-1}; + float scalarProdReso{-1.f}; // resolution value for online correction using CandDsDataWMl = soa::Filtered>; using CandDsData = soa::Filtered>; @@ -168,9 +186,9 @@ struct HfTaskFlowCharmHadrons { using CandXic0DataWMl = soa::Filtered>; using CandD0DataWMl = soa::Filtered>; using CandD0Data = soa::Filtered>; - using CollsWithSPQvecs = soa::Join; - using CollsWithEsEQvecs = soa::Join; - using CollsWithSPEsEQvecs = soa::Join; + using CollsWithSPQvecs = soa::Join; + using CollsWithEsEQvecs = soa::Join; + using CollsWithSPEsEQvecs = soa::Join; using TracksWithExtra = soa::Join; Filter filterSelectDsCandidates = aod::hf_sel_candidate_ds::isSelDsToKKPi >= selectionFlag || aod::hf_sel_candidate_ds::isSelDsToPiKK >= selectionFlag; @@ -199,28 +217,30 @@ struct HfTaskFlowCharmHadrons { Partition selectedXic0 = aod::hf_sel_toxipi::resultSelections == true; Partition selectedXic0WMl = aod::hf_sel_toxipi::resultSelections == true; - ConfigurableAxis thnConfigAxisInvMass{"thnConfigAxisInvMass", {100, 1.78, 2.05}, ""}; - ConfigurableAxis thnConfigAxisPt{"thnConfigAxisPt", {10, 0., 10.}, ""}; - ConfigurableAxis thnConfigAxisCent{"thnConfigAxisCent", {10000, 0., 100.}, ""}; - ConfigurableAxis thnConfigAxisCosNPhi{"thnConfigAxisCosNPhi", {100, -1., 1.}, ""}; - ConfigurableAxis thnConfigAxisPsi{"thnConfigAxisPsi", {6000, 0, constants::math::TwoPI}, ""}; - ConfigurableAxis thnConfigAxisCosDeltaPhi{"thnConfigAxisCosDeltaPhi", {100, -1., 1.}, ""}; - ConfigurableAxis thnConfigAxisScalarProd{"thnConfigAxisScalarProd", {100, 0., 1.}, ""}; - ConfigurableAxis thnConfigAxisMlOne{"thnConfigAxisMlOne", {1000, 0., 1.}, ""}; - ConfigurableAxis thnConfigAxisMlTwo{"thnConfigAxisMlTwo", {1000, 0., 1.}, ""}; - ConfigurableAxis thnConfigAxisOccupancyITS{"thnConfigAxisOccupancyITS", {14, 0, 14000}, ""}; - ConfigurableAxis thnConfigAxisOccupancyFT0C{"thnConfigAxisOccupancyFT0C", {14, 0, 140000}, ""}; - ConfigurableAxis thnConfigAxisNoSameBunchPileup{"thnConfigAxisNoSameBunchPileup", {2, 0, 2}, ""}; - ConfigurableAxis thnConfigAxisOccupancy{"thnConfigAxisOccupancy", {2, 0, 2}, ""}; - ConfigurableAxis thnConfigAxisNoCollInTimeRangeNarrow{"thnConfigAxisNoCollInTimeRangeNarrow", {2, 0, 2}, ""}; - ConfigurableAxis thnConfigAxisNoCollInTimeRangeStandard{"thnConfigAxisNoCollInTimeRangeStandard", {2, 0, 2}, ""}; - ConfigurableAxis thnConfigAxisNoCollInRofStandard{"thnConfigAxisNoCollInRofStandard", {2, 0, 2}, ""}; - ConfigurableAxis thnConfigAxisResoFT0cFV0a{"thnConfigAxisResoFT0cFV0a", {160, -8, 8}, ""}; - ConfigurableAxis thnConfigAxisResoFT0cTPCtot{"thnConfigAxisResoFT0cTPCtot", {160, -8, 8}, ""}; - ConfigurableAxis thnConfigAxisResoFV0aTPCtot{"thnConfigAxisResoFV0aTPCtot", {160, -8, 8}, ""}; - ConfigurableAxis thnConfigAxisCandidateEta{"thnConfigAxisCandidateEta", {100, -5, 5}, ""}; - ConfigurableAxis thnConfigAxisSign{"thnConfigAxisSign", {6, -3.0, 3.0}, ""}; - ConfigurableAxis thnConfigAxisRedQVec{"thnConfigAxisRedQVec", {1000, 0, 100}, ""}; + struct : o2::framework::ConfigurableGroup { + ConfigurableAxis thnConfigAxisInvMass{"thnConfigAxisInvMass", {100, 1.78, 2.05}, ""}; + ConfigurableAxis thnConfigAxisPt{"thnConfigAxisPt", {10, 0., 10.}, ""}; + ConfigurableAxis thnConfigAxisCent{"thnConfigAxisCent", {10000, 0., 100.}, ""}; + ConfigurableAxis thnConfigAxisCosNPhi{"thnConfigAxisCosNPhi", {100, -1., 1.}, ""}; + ConfigurableAxis thnConfigAxisPsi{"thnConfigAxisPsi", {6000, 0, constants::math::TwoPI}, ""}; + ConfigurableAxis thnConfigAxisCosDeltaPhi{"thnConfigAxisCosDeltaPhi", {100, -1., 1.}, ""}; + ConfigurableAxis thnConfigAxisScalarProd{"thnConfigAxisScalarProd", {100, 0., 1.}, ""}; + ConfigurableAxis thnConfigAxisMlOne{"thnConfigAxisMlOne", {1000, 0., 1.}, ""}; + ConfigurableAxis thnConfigAxisMlTwo{"thnConfigAxisMlTwo", {1000, 0., 1.}, ""}; + ConfigurableAxis thnConfigAxisOccupancyITS{"thnConfigAxisOccupancyITS", {14, 0, 14000}, ""}; + ConfigurableAxis thnConfigAxisOccupancyFT0C{"thnConfigAxisOccupancyFT0C", {14, 0, 140000}, ""}; + ConfigurableAxis thnConfigAxisNoSameBunchPileup{"thnConfigAxisNoSameBunchPileup", {2, 0, 2}, ""}; + ConfigurableAxis thnConfigAxisOccupancy{"thnConfigAxisOccupancy", {2, 0, 2}, ""}; + ConfigurableAxis thnConfigAxisNoCollInTimeRangeNarrow{"thnConfigAxisNoCollInTimeRangeNarrow", {2, 0, 2}, ""}; + ConfigurableAxis thnConfigAxisNoCollInTimeRangeStandard{"thnConfigAxisNoCollInTimeRangeStandard", {2, 0, 2}, ""}; + ConfigurableAxis thnConfigAxisNoCollInRofStandard{"thnConfigAxisNoCollInRofStandard", {2, 0, 2}, ""}; + ConfigurableAxis thnConfigAxisResoFT0cFV0a{"thnConfigAxisResoFT0cFV0a", {160, -8, 8}, ""}; + ConfigurableAxis thnConfigAxisResoFT0cTPCtot{"thnConfigAxisResoFT0cTPCtot", {160, -8, 8}, ""}; + ConfigurableAxis thnConfigAxisResoFV0aTPCtot{"thnConfigAxisResoFV0aTPCtot", {160, -8, 8}, ""}; + ConfigurableAxis thnConfigAxisCandidateEta{"thnConfigAxisCandidateEta", {100, -5, 5}, ""}; + ConfigurableAxis thnConfigAxisSign{"thnConfigAxisSign", {6, -3.0, 3.0}, ""}; + ConfigurableAxis thnConfigAxisRedQVec{"thnConfigAxisRedQVec", {1000, 0, 100}, ""}; + } thnAxesCfgs; HistogramRegistry registry{"registry", {}}; @@ -235,30 +255,30 @@ struct HfTaskFlowCharmHadrons { if (storeSPQVec && doprocessD0EsEMl) { LOGP(fatal, "Scalar product tables not available for this process function. Please check your configuration!"); } - const AxisSpec thnAxisInvMass{thnConfigAxisInvMass, "Inv. mass (GeV/#it{c}^{2})"}; - const AxisSpec thnAxisPt{thnConfigAxisPt, "#it{p}_{T} (GeV/#it{c})"}; - const AxisSpec thnAxisCent{thnConfigAxisCent, "Centrality"}; - const AxisSpec thnAxisCosNPhi{thnConfigAxisCosNPhi, Form("cos(%d#varphi)", harmonic.value)}; - const AxisSpec thnAxisSinNPhi{thnConfigAxisCosNPhi, Form("sin(%d#varphi)", harmonic.value)}; - const AxisSpec thnAxisPsi{thnConfigAxisPsi, Form("#Psi_{%d}", harmonic.value)}; - const AxisSpec thnAxisCosDeltaPhi{thnConfigAxisCosDeltaPhi, Form("cos(%d(#varphi - #Psi_{sub}))", harmonic.value)}; - const AxisSpec thnAxisScalarProd{thnConfigAxisScalarProd, "SP"}; - const AxisSpec thnAxisMlOne{thnConfigAxisMlOne, "Bkg score"}; - const AxisSpec thnAxisMlTwo{thnConfigAxisMlTwo, "FD score"}; - const AxisSpec thnAxisOccupancyITS{thnConfigAxisOccupancyITS, "OccupancyITS"}; - const AxisSpec thnAxisOccupancyFT0C{thnConfigAxisOccupancyFT0C, "OccupancyFT0C"}; - const AxisSpec thnAxisCandEta{thnConfigAxisCandidateEta, "#eta"}; - const AxisSpec thnAxisSign{thnConfigAxisSign, "Sign"}; - const AxisSpec thnAxisNoSameBunchPileup{thnConfigAxisNoSameBunchPileup, "NoSameBunchPileup"}; - const AxisSpec thnAxisOccupancy{thnConfigAxisOccupancy, "Occupancy"}; - const AxisSpec thnAxisNoCollInTimeRangeNarrow{thnConfigAxisNoCollInTimeRangeNarrow, "NoCollInTimeRangeNarrow"}; - const AxisSpec thnAxisNoCollInTimeRangeStandard{thnConfigAxisNoCollInTimeRangeStandard, "NoCollInTimeRangeStandard"}; - const AxisSpec thnAxisNoCollInRofStandard{thnConfigAxisNoCollInRofStandard, "NoCollInRofStandard"}; - const AxisSpec thnAxisRedQVec{thnConfigAxisRedQVec, "Reduced Q-vector"}; + const AxisSpec thnAxisInvMass{thnAxesCfgs.thnConfigAxisInvMass, "Inv. mass (GeV/#it{c}^{2})"}; + const AxisSpec thnAxisPt{thnAxesCfgs.thnConfigAxisPt, "#it{p}_{T} (GeV/#it{c})"}; + const AxisSpec thnAxisCent{thnAxesCfgs.thnConfigAxisCent, "Centrality"}; + const AxisSpec thnAxisCosNPhi{thnAxesCfgs.thnConfigAxisCosNPhi, Form("cos(%d#varphi)", harmonic.value)}; + const AxisSpec thnAxisSinNPhi{thnAxesCfgs.thnConfigAxisCosNPhi, Form("sin(%d#varphi)", harmonic.value)}; + const AxisSpec thnAxisPsi{thnAxesCfgs.thnConfigAxisPsi, Form("#Psi_{%d}", harmonic.value)}; + const AxisSpec thnAxisCosDeltaPhi{thnAxesCfgs.thnConfigAxisCosDeltaPhi, Form("cos(%d(#varphi - #Psi_{sub}))", harmonic.value)}; + const AxisSpec thnAxisScalarProd{thnAxesCfgs.thnConfigAxisScalarProd, "SP"}; + const AxisSpec thnAxisMlOne{thnAxesCfgs.thnConfigAxisMlOne, "Bkg score"}; + const AxisSpec thnAxisMlTwo{thnAxesCfgs.thnConfigAxisMlTwo, "FD score"}; + const AxisSpec thnAxisOccupancyITS{thnAxesCfgs.thnConfigAxisOccupancyITS, "OccupancyITS"}; + const AxisSpec thnAxisOccupancyFT0C{thnAxesCfgs.thnConfigAxisOccupancyFT0C, "OccupancyFT0C"}; + const AxisSpec thnAxisCandEta{thnAxesCfgs.thnConfigAxisCandidateEta, "#eta"}; + const AxisSpec thnAxisSign{thnAxesCfgs.thnConfigAxisSign, "Sign"}; + const AxisSpec thnAxisNoSameBunchPileup{thnAxesCfgs.thnConfigAxisNoSameBunchPileup, "NoSameBunchPileup"}; + const AxisSpec thnAxisOccupancy{thnAxesCfgs.thnConfigAxisOccupancy, "Occupancy"}; + const AxisSpec thnAxisNoCollInTimeRangeNarrow{thnAxesCfgs.thnConfigAxisNoCollInTimeRangeNarrow, "NoCollInTimeRangeNarrow"}; + const AxisSpec thnAxisNoCollInTimeRangeStandard{thnAxesCfgs.thnConfigAxisNoCollInTimeRangeStandard, "NoCollInTimeRangeStandard"}; + const AxisSpec thnAxisNoCollInRofStandard{thnAxesCfgs.thnConfigAxisNoCollInRofStandard, "NoCollInRofStandard"}; + const AxisSpec thnAxisRedQVec{thnAxesCfgs.thnConfigAxisRedQVec, "Reduced Q-vector"}; // TODO: currently only the Q vector of FT0c FV0a and TPCtot are considered - const AxisSpec thnAxisResoFT0cFV0a{thnConfigAxisResoFT0cFV0a, "Q_{FT0c} #bullet Q_{FV0a}"}; - const AxisSpec thnAxisResoFT0cTPCtot{thnConfigAxisResoFT0cTPCtot, "Q_{FT0c} #bullet Q_{TPCtot}"}; - const AxisSpec thnAxisResoFV0aTPCtot{thnConfigAxisResoFV0aTPCtot, "Q_{FV0a} #bullet Q_{TPCtot}"}; + const AxisSpec thnAxisResoFT0cFV0a{thnAxesCfgs.thnConfigAxisResoFT0cFV0a, "Q_{FT0c} #bullet Q_{FV0a}"}; + const AxisSpec thnAxisResoFT0cTPCtot{thnAxesCfgs.thnConfigAxisResoFT0cTPCtot, "Q_{FT0c} #bullet Q_{TPCtot}"}; + const AxisSpec thnAxisResoFV0aTPCtot{thnAxesCfgs.thnConfigAxisResoFV0aTPCtot, "Q_{FV0a} #bullet Q_{TPCtot}"}; std::vector axes = {thnAxisInvMass, thnAxisPt, thnAxisCent}; if (storeSPQVec) { @@ -612,6 +632,17 @@ struct HfTaskFlowCharmHadrons { float const yRedQVec = qVecRedComps[1]; float const amplRedQVec = qVecRedComps[2]; + if (useOnlineResoCorrection) { + // Per-run update + if (collision.runNumber() != lastRunNumber) { + LOG(info) << "Run number changed from " << lastRunNumber << " to " << collision.runNumber() << ". Updating resolution values."; + qVecResoHelper.update(ccdb, ccdbResoHistPath, resoTripletPath.value, collision.timestamp(), collision.runNumber()); + lastRunNumber = collision.runNumber(); + } + scalarProdReso = qVecResoHelper[static_cast(cent - 0.5f)]; // Cent is given in X.5f format + LOG(info) << "scalarProdReso: " << scalarProdReso << " for centrality " << cent; + } + for (const auto& candidate : candidates) { float massCand = 0.; float signCand = 0.; @@ -778,6 +809,11 @@ struct HfTaskFlowCharmHadrons { } else { scalprodCand = cosNPhi * xQVec + sinNPhi * yQVec; } + LOG(info) << "\nScalar product before correction" << scalprodCand; + if (useOnlineResoCorrection) { + scalprodCand /= scalarProdReso; + } + LOG(info) << "Scalar product after correction" << scalprodCand; if (fillMassPtMlTree || fillMassPtMlSpCentTree) { if (downSampleFactor < 1.) { @@ -792,11 +828,15 @@ struct HfTaskFlowCharmHadrons { if (fillMassPtMlSpCentTree) { rowCandMassPtMlSpCent(massCand, ptCand, outputMl[0], outputMl[1], scalprodCand, cent); } + if (fillMassPtMlSpCentPvTree) { + rowCandMassPtMlSpCentPv(massCand, ptCand, outputMl[0], outputMl[1], scalprodCand, cent, collision.numContrib()); + } } - bool subtractDaugsFromRedQVec = storeRedQVec && (qVecRedDetector == QvecEstimator::TPCNeg || - qVecRedDetector == QvecEstimator::TPCPos || - qVecRedDetector == QvecEstimator::TPCTot); + bool subtractDaugsFromRedQVec = storeRedQVec && subtrDaugsFromRedQVec && + (qVecRedDetector == QvecEstimator::TPCNeg || + qVecRedDetector == QvecEstimator::TPCPos || + qVecRedDetector == QvecEstimator::TPCTot); if (subtractDaugsFromRedQVec) { std::vector tracksRedQx; std::vector tracksRedQy; @@ -841,17 +881,29 @@ struct HfTaskFlowCharmHadrons { } PROCESS_SWITCH(HfTaskFlowCharmHadrons, processDsMl, "Process Ds candidates with ML", false); - // Ds with rectangular cuts - void processDs(CollsWithSPQvecs::iterator const& collision, - CandDsData const& /*candidatesDs*/, - TracksWithExtra const& tracks) + // Ds with ML EsE + void processDsEsEMl(CollsWithEsEQvecs::iterator const& collision, + CandDsDataWMl const& /*candidatesDs*/, + TracksWithExtra const& tracks) + { + auto candsDsToKKPiWMl = selectedDsToKKPiWMl->sliceByCached(aod::hf_cand::collisionId, collision.globalIndex(), cache); + auto candsDsToPiKKWMl = selectedDsToPiKKWMl->sliceByCached(aod::hf_cand::collisionId, collision.globalIndex(), cache); + runFlowAnalysis(collision, candsDsToKKPiWMl, tracks); + runFlowAnalysis(collision, candsDsToPiKKWMl, tracks); + } + PROCESS_SWITCH(HfTaskFlowCharmHadrons, processDsEsEMl, "Process Ds candidates with ML for EsE information", false); + + // Ds with ML EsE and SP + void processDsSPEsEMl(CollsWithSPEsEQvecs::iterator const& collision, + CandDsDataWMl const& /*candidatesDs*/, + TracksWithExtra const& tracks) { - auto candsDsToKKPi = selectedDsToKKPi->sliceByCached(aod::hf_cand::collisionId, collision.globalIndex(), cache); - auto candsDsToPiKK = selectedDsToPiKK->sliceByCached(aod::hf_cand::collisionId, collision.globalIndex(), cache); - runFlowAnalysis(collision, candsDsToKKPi, tracks); - runFlowAnalysis(collision, candsDsToPiKK, tracks); + auto candsDsToKKPiWMl = selectedDsToKKPiWMl->sliceByCached(aod::hf_cand::collisionId, collision.globalIndex(), cache); + auto candsDsToPiKKWMl = selectedDsToPiKKWMl->sliceByCached(aod::hf_cand::collisionId, collision.globalIndex(), cache); + runFlowAnalysis(collision, candsDsToKKPiWMl, tracks); + runFlowAnalysis(collision, candsDsToPiKKWMl, tracks); } - PROCESS_SWITCH(HfTaskFlowCharmHadrons, processDs, "Process Ds candidates", false); + PROCESS_SWITCH(HfTaskFlowCharmHadrons, processDsSPEsEMl, "Process Ds candidates with ML for SP and EsE information", false); // Dplus with ML void processDplusMl(CollsWithSPQvecs::iterator const& collision, @@ -862,14 +914,23 @@ struct HfTaskFlowCharmHadrons { } PROCESS_SWITCH(HfTaskFlowCharmHadrons, processDplusMl, "Process Dplus candidates with ML", false); - // Dplus with rectangular cuts - void processDplus(CollsWithSPQvecs::iterator const& collision, - CandDplusData const& candidatesDplus, - TracksWithExtra const& tracks) + // Dplus with ML EsE + void processDplusEsEMl(CollsWithEsEQvecs::iterator const& collision, + CandDplusDataWMl const& /*candidatesD0*/, + TracksWithExtra const& tracks) { - runFlowAnalysis(collision, candidatesDplus, tracks); + runFlowAnalysis(collision, candidatesDplus, tracks); + } + PROCESS_SWITCH(HfTaskFlowCharmHadrons, processDplusEsEMl, "Process Dplus candidates with ML for EsE information", false); + + // Dplus with ML SP and EsE + void processDplusSPEsEMl(CollsWithSPEsEQvecs::iterator const& collision, + CandDplusDataWMl const& /*candidatesD0*/, + TracksWithExtra const& tracks) + { + runFlowAnalysis(collision, candidatesDplus, tracks); } - PROCESS_SWITCH(HfTaskFlowCharmHadrons, processDplus, "Process Dplus candidates", true); + PROCESS_SWITCH(HfTaskFlowCharmHadrons, processDplusSPEsEMl, "Process Dplus candidates with ML for SP and EsE information", false); // D0 with ML void processD0Ml(CollsWithSPQvecs::iterator const& collision, @@ -907,18 +968,6 @@ struct HfTaskFlowCharmHadrons { } PROCESS_SWITCH(HfTaskFlowCharmHadrons, processD0SPEsEMl, "Process D0 candidates with ML for SP and EsE information", false); - // D0 with rectangular cuts - void processD0(CollsWithSPQvecs::iterator const& collision, - CandD0Data const& /*candidatesD0*/, - TracksWithExtra const& tracks) - { - auto candsD0ToPiK = selectedD0ToPiK->sliceByCached(aod::hf_cand::collisionId, collision.globalIndex(), cache); - auto candsD0ToKPi = selectedD0ToKPi->sliceByCached(aod::hf_cand::collisionId, collision.globalIndex(), cache); - runFlowAnalysis(collision, candsD0ToPiK, tracks); - runFlowAnalysis(collision, candsD0ToKPi, tracks); - } - PROCESS_SWITCH(HfTaskFlowCharmHadrons, processD0, "Process D0 candidates", false); - // Lc with ML void processLcMl(CollsWithSPQvecs::iterator const& collision, CandLcDataWMl const& /*candidatesLc*/, @@ -931,18 +980,6 @@ struct HfTaskFlowCharmHadrons { } PROCESS_SWITCH(HfTaskFlowCharmHadrons, processLcMl, "Process Lc candidates with ML", false); - // Lc with rectangular cuts - void processLc(CollsWithSPQvecs::iterator const& collision, - CandLcData const& /*candidatesLc*/, - TracksWithExtra const& tracks) - { - auto candsLcToPKPi = selectedLcToPKPi->sliceByCached(aod::hf_cand::collisionId, collision.globalIndex(), cache); - auto candsLcToPiKP = selectedLcToPiKP->sliceByCached(aod::hf_cand::collisionId, collision.globalIndex(), cache); - runFlowAnalysis(collision, candsLcToPKPi, tracks); - runFlowAnalysis(collision, candsLcToPiKP, tracks); - } - PROCESS_SWITCH(HfTaskFlowCharmHadrons, processLc, "Process Lc candidates", false); - // Xic with ML void processXicMl(CollsWithSPQvecs::iterator const& collision, CandXicDataWMl const& /*candidatesXic*/, @@ -955,18 +992,6 @@ struct HfTaskFlowCharmHadrons { } PROCESS_SWITCH(HfTaskFlowCharmHadrons, processXicMl, "Process Xic candidates with ML", false); - // Xic with rectangular cuts - void processXic(CollsWithSPQvecs::iterator const& collision, - CandXicData const& /*candidatesXic*/, - TracksWithExtra const& tracks) - { - auto candsXicToPKPi = selectedXicToPKPi->sliceByCached(aod::hf_cand::collisionId, collision.globalIndex(), cache); - auto candsXicToPiKP = selectedXicToPiKP->sliceByCached(aod::hf_cand::collisionId, collision.globalIndex(), cache); - runFlowAnalysis(collision, candsXicToPKPi, tracks); - runFlowAnalysis(collision, candsXicToPiKP, tracks); - } - PROCESS_SWITCH(HfTaskFlowCharmHadrons, processXic, "Process Xic candidates", false); - // Xic0 with ML void processXic0Ml(CollsWithSPQvecs::iterator const& collision, CandXic0DataWMl const& /*candidatesXic0*/, @@ -987,6 +1012,65 @@ struct HfTaskFlowCharmHadrons { } PROCESS_SWITCH(HfTaskFlowCharmHadrons, processXic0, "Process Xic0 candidates", false); + // // Ds with rectangular cuts + // void processDs(CollsWithSPQvecs::iterator const& collision, + // CandDsData const& /*candidatesDs*/, + // TracksWithExtra const& tracks) + // { + // auto candsDsToKKPi = selectedDsToKKPi->sliceByCached(aod::hf_cand::collisionId, collision.globalIndex(), cache); + // auto candsDsToPiKK = selectedDsToPiKK->sliceByCached(aod::hf_cand::collisionId, collision.globalIndex(), cache); + // runFlowAnalysis(collision, candsDsToKKPi, tracks); + // runFlowAnalysis(collision, candsDsToPiKK, tracks); + // } + // PROCESS_SWITCH(HfTaskFlowCharmHadrons, processDs, "Process Ds candidates", false); + + // // D0 with rectangular cuts + // void processD0(CollsWithSPQvecs::iterator const& collision, + // CandD0Data const& /*candidatesD0*/, + // TracksWithExtra const& tracks) + // { + // auto candsD0ToPiK = selectedD0ToPiK->sliceByCached(aod::hf_cand::collisionId, collision.globalIndex(), cache); + // auto candsD0ToKPi = selectedD0ToKPi->sliceByCached(aod::hf_cand::collisionId, collision.globalIndex(), cache); + // runFlowAnalysis(collision, candsD0ToPiK, tracks); + // runFlowAnalysis(collision, candsD0ToKPi, tracks); + // } + // PROCESS_SWITCH(HfTaskFlowCharmHadrons, processD0, "Process D0 candidates", false); + + // // Dplus with rectangular cuts + // void processDplus(CollsWithSPQvecs::iterator const& collision, + // CandDplusData const& candidatesDplus, + // TracksWithExtra const& tracks) + // { + // runFlowAnalysis(collision, candidatesDplus, tracks); + // } + // PROCESS_SWITCH(HfTaskFlowCharmHadrons, processDplus, "Process Dplus candidates", true); + + // // Lc with rectangular cuts + // void processLc(CollsWithSPQvecs::iterator const& collision, + // CandLcData const& /*candidatesLc*/, + // TracksWithExtra const& tracks) + // { + // auto candsLcToPKPi = selectedLcToPKPi->sliceByCached(aod::hf_cand::collisionId, collision.globalIndex(), cache); + // auto candsLcToPiKP = selectedLcToPiKP->sliceByCached(aod::hf_cand::collisionId, collision.globalIndex(), cache); + // runFlowAnalysis(collision, candsLcToPKPi, tracks); + // runFlowAnalysis(collision, candsLcToPiKP, tracks); + // } + // PROCESS_SWITCH(HfTaskFlowCharmHadrons, processLc, "Process Lc candidates", false); + + // // Xic with rectangular cuts + // void processXic(CollsWithSPQvecs::iterator const& collision, + // CandXicData const& /*candidatesXic*/, + // TracksWithExtra const& tracks) + // { + // auto candsXicToPKPi = selectedXicToPKPi->sliceByCached(aod::hf_cand::collisionId, collision.globalIndex(), cache); + // auto candsXicToPiKP = selectedXicToPiKP->sliceByCached(aod::hf_cand::collisionId, collision.globalIndex(), cache); + // runFlowAnalysis(collision, candsXicToPKPi, tracks); + // runFlowAnalysis(collision, candsXicToPiKP, tracks); + // } + // PROCESS_SWITCH(HfTaskFlowCharmHadrons, processXic, "Process Xic candidates", false); + + + /// Compute resolution /// \param collision is the collision with the Q vector information /// \param bcs is used for the event selection based on centrality estimators with time information @@ -1042,8 +1126,8 @@ struct HfTaskFlowCharmHadrons { return; } - float redQVec{-999.f}; - std::array qVecRedComps{-999.f, -999.f, -999.f}; + float redQVec{0.f}; + std::array qVecRedComps{0.f, 0.f, 0.f}; if constexpr (HasRedQVecs) { qVecRedComps = getEseQvec(collision, qVecRedDetector.value); } diff --git a/PWGHF/D2H/Utils/utilsFlow.h b/PWGHF/D2H/Utils/utilsFlow.h index 02171203eba..e01aef1bc28 100644 --- a/PWGHF/D2H/Utils/utilsFlow.h +++ b/PWGHF/D2H/Utils/utilsFlow.h @@ -18,10 +18,17 @@ #include "Common/Core/RecoDecay.h" +#include #include #include +#include #include +#include +#include +#include +#include + namespace o2::analysis { @@ -35,6 +42,48 @@ enum QvecEstimator { FV0A = 0, TPCNeg, TPCTot }; +class QVectorResoHelper { + public: + + QVectorResoHelper() = default; + + /// Call once per run / timestamp update + void update(o2::framework::Service& ccdb, + std::string const& basePath, + std::string const& tripletPath, + int64_t timestamp, + int runNumber) + { + if (mCurrentRun == runNumber && mResoValues != nullptr) { + return; + } + + std::string fullPath = basePath + "/" + tripletPath + "/"; + LOG(info) << "Fetching resolution array from CCDB path: " << fullPath << " for timestamp " << timestamp << " and run number " << runNumber; + + mResoValues = ccdb->getForTimeStamp>(fullPath, timestamp); + if (!mResoValues) { + LOGF(fatal, "Resolution array not found in CCDB at path: %s", fullPath.c_str()); + } + + mCurrentRun = runNumber; + } + + /// Get pointer to the full array + const std::array* getResoValues() const { return mResoValues; } + + /// Direct array access with simple float return type + float operator[](size_t index) const + { + assert(mResoValues != nullptr && "CCDB resolution array accessed before initialization!"); + return (*mResoValues)[index]; + } + + private: + const std::array* mResoValues{nullptr}; + int64_t mCurrentRun{-1}; +}; + /// Compute the delta psi in the range [0, pi/harmonic] /// \param psi1 is the first angle /// \param psi2 is the second angle From 119a46f3f59fad3e56f29715cd1394539e76d8e8 Mon Sep 17 00:00:00 2001 From: marcellocosti Date: Fri, 28 Aug 2026 17:09:03 +0200 Subject: [PATCH 2/4] Fixes --- PWGHF/D2H/Tasks/taskDplus.cxx | 88 +++++++++--------- PWGHF/D2H/Tasks/taskFlowCharmHadrons.cxx | 110 ++++++++--------------- PWGHF/D2H/Utils/utilsFlow.h | 4 +- 3 files changed, 85 insertions(+), 117 deletions(-) diff --git a/PWGHF/D2H/Tasks/taskDplus.cxx b/PWGHF/D2H/Tasks/taskDplus.cxx index d2d0f0279dd..f643962829d 100644 --- a/PWGHF/D2H/Tasks/taskDplus.cxx +++ b/PWGHF/D2H/Tasks/taskDplus.cxx @@ -121,6 +121,7 @@ struct HfTaskDplus { Partition recoBkgCandidates = nabs(aod::hf_cand_mc_flag::flagMcMatchRec) != static_cast(hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKPi) && aod::hf_sel_candidate_dplus::isSelDplusToPiKPi >= selectionFlagDplus; Partition recoBkgCandidatesWithMl = nabs(aod::hf_cand_mc_flag::flagMcMatchRec) != static_cast(hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKPi) && aod::hf_sel_candidate_dplus::isSelDplusToPiKPi >= selectionFlagDplus; + ConfigurableAxis thnConfigAxisPt{"thnConfigAxisPt", {50, 0, 25}, "Cand. pt bins"}; ConfigurableAxis thnConfigAxisMass{"thnConfigAxisMass", {600, 1.67, 2.27}, "Cand. mass bins"}; ConfigurableAxis thnConfigAxisY{"thnConfigAxisY", {40, -1, 1}, "Cand. rapidity bins"}; ConfigurableAxis thnConfigAxisCent{"thnConfigAxisCent", {110, 0., 110.}, "axis for centrality"}; @@ -156,13 +157,12 @@ struct HfTaskDplus { if ((std::accumulate(doprocess.begin(), doprocess.end(), 0)) != 1) { LOGP(fatal, "Only one process function should be enabled! Please check your configuration!"); } - auto vbins = static_cast>(binsPt); - AxisSpec const thnAxisPt = {vbins, "#it{p}_{T} (GeV/#it{c})"}; - AxisSpec const thnAxisMass = {thnConfigAxisMass, "inv. mass (K#pi#pi) (GeV/#it{c}^{2})"}; - AxisSpec const thnAxisY = {thnConfigAxisY, "y"}; - AxisSpec const thnAxisMlScore0 = {thnConfigAxisMlScore0, "Score 0"}; - AxisSpec const thnAxisMlScore1 = {thnConfigAxisMlScore1, "Score 1"}; - AxisSpec const thnAxisMlScore2 = {thnConfigAxisMlScore2, "Score 2"}; + AxisSpec const thnAxisPt{thnConfigAxisPt, "#it{p}_{T} (GeV/#it{c})"}; + AxisSpec const thnAxisMass{thnConfigAxisMass, "inv. mass (K#pi#pi) (GeV/#it{c}^{2})"}; + AxisSpec const thnAxisY{thnConfigAxisY, "y"}; + AxisSpec const thnAxisMlScore0{thnConfigAxisMlScore0, "Score 0"}; + AxisSpec const thnAxisMlScore1{thnConfigAxisMlScore1, "Score 1"}; + AxisSpec const thnAxisMlScore2{thnConfigAxisMlScore2, "Score 2"}; AxisSpec const thnAxisPtBHad{thnConfigAxisPtBHad, "#it{p}_{T,B} (GeV/#it{c})"}; AxisSpec const thnAxisFlagBHad{thnConfigAxisFlagBHad, "B Hadron flag"}; AxisSpec const thnAxisCent{thnConfigAxisCent, "Centrality"}; @@ -178,43 +178,43 @@ struct HfTaskDplus { AxisSpec const thnAxisZNA{thnConfigAxisZN, "ZNA energy"}; AxisSpec const thnAxisZNC{thnConfigAxisZN, "ZNC energy"}; - registry.add("hMass", "3-prong candidates;inv. mass (#pi K #pi) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {{350, 1.7, 2.05}, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hEta", "3-prong candidates;candidate #it{#eta};entries", {HistType::kTH2F, {{100, -2., 2.}, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hCt", "3-prong candidates;proper lifetime (D^{#pm}) * #it{c} (cm);entries", {HistType::kTH2F, {{120, -20., 100.}, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hDecayLength", "3-prong candidates;decay length (cm);entries", {HistType::kTH2F, {{200, 0., 2.}, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hDecayLengthXY", "3-prong candidates;decay length xy (cm);entries", {HistType::kTH2F, {{200, 0., 2.}, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hNormalisedDecayLengthXY", "3-prong candidates;norm. decay length xy;entries", {HistType::kTH2F, {{80, 0., 80.}, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hCPA", "3-prong candidates;cos. pointing angle;entries", {HistType::kTH2F, {{110, -1.1, 1.1}, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hCPAxy", "3-prong candidates;cos. pointing angle xy;entries", {HistType::kTH2F, {{110, -1.1, 1.1}, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hImpactParameterXY", "3-prong candidates;impact parameter xy (cm);entries", {HistType::kTH2F, {{200, -1., 1.}, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hMaxNormalisedDeltaIP", "3-prong candidates;norm. IP;entries", {HistType::kTH2F, {{200, -20., 20.}, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hImpactParameterProngSqSum", "3-prong candidates;squared sum of prong imp. par. (cm^{2});entries", {HistType::kTH2F, {{100, 0., 1.}, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hDecayLengthError", "3-prong candidates;decay length error (cm);entries", {HistType::kTH2F, {{100, 0., 1.}, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hDecayLengthXYError", "3-prong candidates;decay length xy error (cm);entries", {HistType::kTH2F, {{100, 0., 1.}, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hImpactParameterError", "3-prong candidates;impact parameter error (cm);entries", {HistType::kTH2F, {{100, 0., 1.}, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hd0Prong0", "3-prong candidates;prong 0 DCAxy to prim. vertex (cm);entries", {HistType::kTH2F, {{100, -1., 1.}, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hd0Prong1", "3-prong candidates;prong 1 DCAxy to prim. vertex (cm);entries", {HistType::kTH2F, {{100, -1., 1.}, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hd0Prong2", "3-prong candidates;prong 2 DCAxy to prim. vertex (cm);entries", {HistType::kTH2F, {{100, -1., 1.}, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hPtRecSig", "3-prong candidates (matched);#it{p}_{T}^{rec.} (GeV/#it{c});entries", {HistType::kTH1F, {{vbins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hPtRecSigPrompt", "3-prong candidates (matched, prompt);#it{p}_{T}^{rec.} (GeV/#it{c});entries", {HistType::kTH1F, {{vbins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hPtRecSigNonPrompt", "3-prong candidates (matched, non-prompt);#it{p}_{T}^{rec.} (GeV/#it{c});entries", {HistType::kTH1F, {{vbins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hPtRecBg", "3-prong candidates (unmatched);#it{p}_{T}^{rec.} (GeV/#it{c});entries", {HistType::kTH1F, {{vbins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hPtGen", "MC particles (matched);#it{p}_{T}^{gen.} (GeV/#it{c});entries", {HistType::kTH1F, {{vbins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hPtGenSig", "MC particles (matched);#it{p}_{T}^{gen.} (GeV/#it{c});entries", {HistType::kTH1F, {{vbins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hPtGenPrompt", "MC particles (matched, prompt);#it{p}_{T}^{gen.} (GeV/#it{c});entries", {HistType::kTH1F, {{vbins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hPtGenNonPrompt", "MC particles (matched, non-prompt);#it{p}_{T}^{gen.} (GeV/#it{c});entries", {HistType::kTH1F, {{vbins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hPtVsYRecSig_RecoPID", "3-prong candidates (RecoPID - matched);#it{p}_{T}^{rec.}; #it{y}", {HistType::kTH2F, {{vbins, "#it{p}_{T} (GeV/#it{c})"}, {100, -5., 5.}}}); - registry.add("hPtVsYRecSigPromptRecoPID", "3-prong candidates (RecoPID - matched, prompt);#it{p}_{T}^{rec.}; #it{y}", {HistType::kTH2F, {{vbins, "#it{p}_{T} (GeV/#it{c})"}, {100, -5., 5.}}}); - registry.add("hPtVsYRecSigNonPromptRecoPID", "3-prong candidates (RecoPID - matched, non-prompt);#it{p}_{T}^{rec.}; #it{y}", {HistType::kTH2F, {{vbins, "#it{p}_{T} (GeV/#it{c})"}, {100, -5., 5.}}}); - registry.add("hPtVsYRecSigRecoTopol", "3-prong candidates (RecoTopol - matched);#it{p}_{T}^{rec.}; #it{y}", {HistType::kTH2F, {{vbins, "#it{p}_{T} (GeV/#it{c})"}, {100, -5., 5.}}}); - registry.add("hPtVsYRecSigPromptRecoTopol", "3-prong candidates (RecoTopol - matched, prompt);#it{p}_{T}^{rec.}; #it{y}", {HistType::kTH2F, {{vbins, "#it{p}_{T} (GeV/#it{c})"}, {100, -5., 5.}}}); - registry.add("hPtVsYRecSigNonPromptRecoTopol", "3-prong candidates (RecoTopol - matched, non-prompt);#it{p}_{T}^{rec.}; #it{y}", {HistType::kTH2F, {{vbins, "#it{p}_{T} (GeV/#it{c})"}, {100, -5., 5.}}}); - registry.add("hPtVsYRecSig_RecoSkim", "3-prong candidates (RecoSkim - matched);#it{p}_{T}^{rec.}; #it{y}", {HistType::kTH2F, {{vbins, "#it{p}_{T} (GeV/#it{c})"}, {100, -5., 5.}}}); - registry.add("hPtVsYRecSigPrompt_RecoSkim", "3-prong candidates (RecoSkim - matched, prompt);#it{p}_{T}^{rec.}; #it{y}", {HistType::kTH2F, {{vbins, "#it{p}_{T} (GeV/#it{c})"}, {100, -5., 5.}}}); - registry.add("hPtVsYRecSigNonPrompt_RecoSkim", "3-prong candidates (RecoSkim - matched, non-prompt);#it{p}_{T}^{rec.}; #it{y}", {HistType::kTH2F, {{vbins, "#it{p}_{T} (GeV/#it{c})"}, {100, -5., 5.}}}); - registry.add("hPtVsYGen", "MC particles (matched);#it{p}_{T}^{gen.}; #it{y}", {HistType::kTH2F, {{vbins, "#it{p}_{T} (GeV/#it{c})"}, {100, -5., 5.}}}); - registry.add("hPtVsYGenPrompt", "MC particles (matched, prompt);#it{p}_{T}^{gen.}; #it{y}", {HistType::kTH2F, {{vbins, "#it{p}_{T} (GeV/#it{c})"}, {100, -5., 5.}}}); - registry.add("hPtVsYGenNonPrompt", "MC particles (matched, non-prompt);#it{p}_{T}^{gen.}; #it{y}", {HistType::kTH2F, {{vbins, "#it{p}_{T} (GeV/#it{c})"}, {100, -5., 5.}}}); + registry.add("hMass", "3-prong candidates;inv. mass (#pi K #pi) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {{350, 1.7, 2.05}, thnAxisPt}}); + registry.add("hEta", "3-prong candidates;candidate #it{#eta};entries", {HistType::kTH2F, {{100, -2., 2.}, thnAxisPt}}); + registry.add("hCt", "3-prong candidates;proper lifetime (D^{#pm}) * #it{c} (cm);entries", {HistType::kTH2F, {{120, -20., 100.}, thnAxisPt}}); + registry.add("hDecayLength", "3-prong candidates;decay length (cm);entries", {HistType::kTH2F, {{200, 0., 2.}, thnAxisPt}}); + registry.add("hDecayLengthXY", "3-prong candidates;decay length xy (cm);entries", {HistType::kTH2F, {{200, 0., 2.}, thnAxisPt}}); + registry.add("hNormalisedDecayLengthXY", "3-prong candidates;norm. decay length xy;entries", {HistType::kTH2F, {{80, 0., 80.}, thnAxisPt}}); + registry.add("hCPA", "3-prong candidates;cos. pointing angle;entries", {HistType::kTH2F, {{110, -1.1, 1.1}, thnAxisPt}}); + registry.add("hCPAxy", "3-prong candidates;cos. pointing angle xy;entries", {HistType::kTH2F, {{110, -1.1, 1.1}, thnAxisPt}}); + registry.add("hImpactParameterXY", "3-prong candidates;impact parameter xy (cm);entries", {HistType::kTH2F, {{200, -1., 1.}, thnAxisPt}}); + registry.add("hMaxNormalisedDeltaIP", "3-prong candidates;norm. IP;entries", {HistType::kTH2F, {{200, -20., 20.}, thnAxisPt}}); + registry.add("hImpactParameterProngSqSum", "3-prong candidates;squared sum of prong imp. par. (cm^{2});entries", {HistType::kTH2F, {{100, 0., 1.}, thnAxisPt}}); + registry.add("hDecayLengthError", "3-prong candidates;decay length error (cm);entries", {HistType::kTH2F, {{100, 0., 1.}, thnAxisPt}}); + registry.add("hDecayLengthXYError", "3-prong candidates;decay length xy error (cm);entries", {HistType::kTH2F, {{100, 0., 1.}, thnAxisPt}}); + registry.add("hImpactParameterError", "3-prong candidates;impact parameter error (cm);entries", {HistType::kTH2F, {{100, 0., 1.}, thnAxisPt}}); + registry.add("hd0Prong0", "3-prong candidates;prong 0 DCAxy to prim. vertex (cm);entries", {HistType::kTH2F, {{100, -1., 1.}, thnAxisPt}}); + registry.add("hd0Prong1", "3-prong candidates;prong 1 DCAxy to prim. vertex (cm);entries", {HistType::kTH2F, {{100, -1., 1.}, thnAxisPt}}); + registry.add("hd0Prong2", "3-prong candidates;prong 2 DCAxy to prim. vertex (cm);entries", {HistType::kTH2F, {{100, -1., 1.}, thnAxisPt}}); + registry.add("hPtRecSig", "3-prong candidates (matched);#it{p}_{T}^{rec.} (GeV/#it{c});entries", {HistType::kTH1F, {thnAxisPt}}); + registry.add("hPtRecSigPrompt", "3-prong candidates (matched, prompt);#it{p}_{T}^{rec.} (GeV/#it{c});entries", {HistType::kTH1F, {thnAxisPt}}); + registry.add("hPtRecSigNonPrompt", "3-prong candidates (matched, non-prompt);#it{p}_{T}^{rec.} (GeV/#it{c});entries", {HistType::kTH1F, {thnAxisPt}}); + registry.add("hPtRecBg", "3-prong candidates (unmatched);#it{p}_{T}^{rec.} (GeV/#it{c});entries", {HistType::kTH1F, {thnAxisPt}}); + registry.add("hPtGen", "MC particles (matched);#it{p}_{T}^{gen.} (GeV/#it{c});entries", {HistType::kTH1F, {thnAxisPt}}); + registry.add("hPtGenSig", "MC particles (matched);#it{p}_{T}^{gen.} (GeV/#it{c});entries", {HistType::kTH1F, {thnAxisPt}}); + registry.add("hPtGenPrompt", "MC particles (matched, prompt);#it{p}_{T}^{gen.} (GeV/#it{c});entries", {HistType::kTH1F, {thnAxisPt}}); + registry.add("hPtGenNonPrompt", "MC particles (matched, non-prompt);#it{p}_{T}^{gen.} (GeV/#it{c});entries", {HistType::kTH1F, {thnAxisPt}}); + registry.add("hPtVsYRecSig_RecoPID", "3-prong candidates (RecoPID - matched);#it{p}_{T}^{rec.}; #it{y}", {HistType::kTH2F, {thnAxisPt, {100, -5., 5.}}}); + registry.add("hPtVsYRecSigPromptRecoPID", "3-prong candidates (RecoPID - matched, prompt);#it{p}_{T}^{rec.}; #it{y}", {HistType::kTH2F, {thnAxisPt, {100, -5., 5.}}}); + registry.add("hPtVsYRecSigNonPromptRecoPID", "3-prong candidates (RecoPID - matched, non-prompt);#it{p}_{T}^{rec.}; #it{y}", {HistType::kTH2F, {thnAxisPt, {100, -5., 5.}}}); + registry.add("hPtVsYRecSigRecoTopol", "3-prong candidates (RecoTopol - matched);#it{p}_{T}^{rec.}; #it{y}", {HistType::kTH2F, {thnAxisPt, {100, -5., 5.}}}); + registry.add("hPtVsYRecSigPromptRecoTopol", "3-prong candidates (RecoTopol - matched, prompt);#it{p}_{T}^{rec.}; #it{y}", {HistType::kTH2F, {thnAxisPt, {100, -5., 5.}}}); + registry.add("hPtVsYRecSigNonPromptRecoTopol", "3-prong candidates (RecoTopol - matched, non-prompt);#it{p}_{T}^{rec.}; #it{y}", {HistType::kTH2F, {thnAxisPt, {100, -5., 5.}}}); + registry.add("hPtVsYRecSig_RecoSkim", "3-prong candidates (RecoSkim - matched);#it{p}_{T}^{rec.}; #it{y}", {HistType::kTH2F, {thnAxisPt, {100, -5., 5.}}}); + registry.add("hPtVsYRecSigPrompt_RecoSkim", "3-prong candidates (RecoSkim - matched, prompt);#it{p}_{T}^{rec.}; #it{y}", {HistType::kTH2F, {thnAxisPt, {100, -5., 5.}}}); + registry.add("hPtVsYRecSigNonPrompt_RecoSkim", "3-prong candidates (RecoSkim - matched, non-prompt);#it{p}_{T}^{rec.}; #it{y}", {HistType::kTH2F, {thnAxisPt, {100, -5., 5.}}}); + registry.add("hPtVsYGen", "MC particles (matched);#it{p}_{T}^{gen.}; #it{y}", {HistType::kTH2F, {thnAxisPt, {100, -5., 5.}}}); + registry.add("hPtVsYGenPrompt", "MC particles (matched, prompt);#it{p}_{T}^{gen.}; #it{y}", {HistType::kTH2F, {thnAxisPt, {100, -5., 5.}}}); + registry.add("hPtVsYGenNonPrompt", "MC particles (matched, non-prompt);#it{p}_{T}^{gen.}; #it{y}", {HistType::kTH2F, {thnAxisPt, {100, -5., 5.}}}); if (doprocessDataWithMl || doprocessData || doprocessDataWithMlWithUpc || doprocessDataWithUpc) { std::vector axes = {thnAxisMass, thnAxisPt}; diff --git a/PWGHF/D2H/Tasks/taskFlowCharmHadrons.cxx b/PWGHF/D2H/Tasks/taskFlowCharmHadrons.cxx index 3cb8e7ce7a1..65baa89b02f 100644 --- a/PWGHF/D2H/Tasks/taskFlowCharmHadrons.cxx +++ b/PWGHF/D2H/Tasks/taskFlowCharmHadrons.cxx @@ -92,7 +92,7 @@ DECLARE_SOA_TABLE(HfCandFlowInfos, "AOD", "HFCANDFLOWINFO", full::MlScore1, full::ScalarProd, full::Cent); -DECLARE_SOA_TABLE(HfCandFlowMcs, "AOD", "HFCANDFLOWMC", +DECLARE_SOA_TABLE(HfCandFlowPvs, "AOD", "HFCANDFLOWPV", full::M, full::Pt, full::MlScore0, @@ -132,7 +132,7 @@ struct HfTaskFlowCharmHadrons { Produces rowCandMassPtMl; Produces rowCandMassPtMlSpCent; Produces rowCandFlowEsE; - Produces rowCandFlowMc; + Produces rowCandMassPtMlSpCentPv; Configurable harmonic{"harmonic", 2, "harmonic number"}; Configurable qVecDetector{"qVecDetector", 3, "Detector for Q vector estimation (FV0A: 0, FT0M: 1, FT0A: 2, FT0C: 3, TPC Pos: 4, TPC Neg: 5, TPC Tot: 6)"}; @@ -145,7 +145,7 @@ struct HfTaskFlowCharmHadrons { Configurable storeMl{"storeMl", false, "Flag to store ML scores"}; Configurable storeSPQVec{"storeSPQVec", true, "Flag to store the Q-vectors for SP"}; Configurable storeRedQVec{"storeRedQVec", false, "Flag to store reduced Q-vectors for ESE"}; - Configurable subtractDaugsFromRedQVec{"subtractDaugsFromRedQVec", true, "Flag to subtract daughter tracks from reduced Q-vectors for ESE"}; + Configurable useRedQVecDaugsSubtr{"useRedQVecDaugsSubtr", true, "Flag to subtract daughter tracks from reduced Q-vectors for ESE"}; Configurable fillMassPtMlTree{"fillMassPtMlTree", false, "Flag to fill mass, pt and ML scores tree"}; Configurable fillMassPtMlSpCentTree{"fillMassPtMlSpCentTree", false, "Flag to fill mass, pt, ML scores, SP and centrality tree"}; Configurable fillMassPtMlSpCentPvTree{"fillMassPtMlSpCentPvTree", false, "Flag to fill mass, pt, ML scores, SP, centrality, PV contrib tree"}; @@ -170,22 +170,17 @@ struct HfTaskFlowCharmHadrons { HfEventSelection hfEvSel; // event selection and monitoring o2::framework::Service ccdb{}; SliceCache cache; - QVectorResoHelper qVecResoHelper; + HfQVectorResoHelper qVecResoHelper; int lastRunNumber{-1}; float scalarProdReso{-1.f}; // resolution value for online correction using CandDsDataWMl = soa::Filtered>; - using CandDsData = soa::Filtered>; using CandDplusDataWMl = soa::Filtered>; - using CandDplusData = soa::Filtered>; - using CandLcData = soa::Filtered>; using CandLcDataWMl = soa::Filtered>; - using CandXicData = soa::Filtered>; using CandXicDataWMl = soa::Filtered>; using CandXic0Data = soa::Filtered>; using CandXic0DataWMl = soa::Filtered>; using CandD0DataWMl = soa::Filtered>; - using CandD0Data = soa::Filtered>; using CollsWithSPQvecs = soa::Join; using CollsWithEsEQvecs = soa::Join; using CollsWithSPEsEQvecs = soa::Join; @@ -198,20 +193,12 @@ struct HfTaskFlowCharmHadrons { Filter filterSelectXicCandidates = aod::hf_sel_candidate_xic::isSelXicToPKPi >= selectionFlag || aod::hf_sel_candidate_xic::isSelXicToPiKP >= selectionFlag; Filter filterSelectXic0Candidates = aod::hf_sel_toxipi::resultSelections == true; - Partition selectedDsToKKPi = aod::hf_sel_candidate_ds::isSelDsToKKPi >= selectionFlag; - Partition selectedDsToPiKK = aod::hf_sel_candidate_ds::isSelDsToPiKK >= selectionFlag; Partition selectedDsToKKPiWMl = aod::hf_sel_candidate_ds::isSelDsToKKPi >= selectionFlag; Partition selectedDsToPiKKWMl = 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 selectedD0ToPiKWMl = aod::hf_sel_candidate_d0::isSelD0 >= selectionFlag; Partition selectedD0ToKPiWMl = 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 selectedLcToPKPiWMl = aod::hf_sel_candidate_lc::isSelLcToPKPi >= selectionFlag; Partition selectedLcToPiKPWMl = aod::hf_sel_candidate_lc::isSelLcToPiKP >= selectionFlag; - Partition selectedXicToPKPi = aod::hf_sel_candidate_xic::isSelXicToPKPi >= selectionFlag; - Partition selectedXicToPiKP = aod::hf_sel_candidate_xic::isSelXicToPiKP >= selectionFlag; Partition selectedXicToPKPiWMl = aod::hf_sel_candidate_xic::isSelXicToPKPi >= selectionFlag; Partition selectedXicToPiKPWMl = aod::hf_sel_candidate_xic::isSelXicToPiKP >= selectionFlag; Partition selectedXic0 = aod::hf_sel_toxipi::resultSelections == true; @@ -404,17 +391,17 @@ struct HfTaskFlowCharmHadrons { std::vector& tracksQx, std::vector& tracksQy, const float amplQVec, - QvecEstimator qVecDetector) + QvecEstimator qVecDet) { auto addProngIfInSubevent = [&](float px, float py, float pz) { const std::array pVec{px, py, pz}; const float eta = RecoDecay::eta(pVec); // only subtract daughters that actually contributed to THIS subevent Q - if (qVecDetector == QvecEstimator::TPCPos && eta <= 0.f) { + if (qVecDet == QvecEstimator::TPCPos && eta <= 0.f) { return; } - if (qVecDetector == QvecEstimator::TPCNeg && eta >= 0.f) { + if (qVecDet == QvecEstimator::TPCNeg && eta >= 0.f) { return; } // for TPCTot: no early return, all prongs contribute @@ -446,16 +433,16 @@ struct HfTaskFlowCharmHadrons { std::vector& tracksQx, std::vector& tracksQy, float amplQVec, - QvecEstimator qVecDetector) + QvecEstimator qVecDet) { auto addProngIfInSubevent = [&](float px, float py, float pz) { const std::array pVec{px, py, pz}; const float eta = RecoDecay::eta(pVec); - if (qVecDetector == QvecEstimator::TPCPos && eta <= 0.f) { + if (qVecDet == QvecEstimator::TPCPos && eta <= 0.f) { return; } - if (qVecDetector == QvecEstimator::TPCNeg && eta >= 0.f) { + if (qVecDet == QvecEstimator::TPCNeg && eta >= 0.f) { return; } @@ -640,49 +627,42 @@ struct HfTaskFlowCharmHadrons { lastRunNumber = collision.runNumber(); } scalarProdReso = qVecResoHelper[static_cast(cent - 0.5f)]; // Cent is given in X.5f format - LOG(info) << "scalarProdReso: " << scalarProdReso << " for centrality " << cent; } for (const auto& candidate : candidates) { float massCand = 0.; float signCand = 0.; std::vector outputMl = {-999., -999.}; - if constexpr (std::is_same_v || std::is_same_v) { + if constexpr (std::is_same_v) { switch (Channel) { case DecayChannel::DsToKKPi: massCand = HfHelper::invMassDsToKKPi(candidate); signCand = 1; - if constexpr (std::is_same_v) { - for (unsigned int iclass = 0; iclass < classMl->size(); iclass++) { - outputMl[iclass] = candidate.mlProbDsToKKPi()[classMl->at(iclass)]; - } + for (unsigned int iclass = 0; iclass < classMl->size(); iclass++) { + outputMl[iclass] = candidate.mlProbDsToKKPi()[classMl->at(iclass)]; } break; case DecayChannel::DsToPiKK: massCand = HfHelper::invMassDsToPiKK(candidate); signCand = -1; - if constexpr (std::is_same_v) { - for (unsigned int iclass = 0; iclass < classMl->size(); iclass++) { - outputMl[iclass] = candidate.mlProbDsToPiKK()[classMl->at(iclass)]; - } + for (unsigned int iclass = 0; iclass < classMl->size(); iclass++) { + outputMl[iclass] = candidate.mlProbDsToPiKK()[classMl->at(iclass)]; } break; default: break; } - } else if constexpr (std::is_same_v || std::is_same_v) { + } else if constexpr (std::is_same_v) { massCand = HfHelper::invMassDplusToPiKPi(candidate); if (std::abs(massCand - MassDPlus) < nSigmaMass * sigmaMDplus) { hasCandInMassWin = true; } auto trackprong0 = candidate.template prong0_as(); signCand = trackprong0.sign(); - if constexpr (std::is_same_v) { - for (unsigned int iclass = 0; iclass < classMl->size(); iclass++) { - outputMl[iclass] = candidate.mlProbDplusToPiKPi()[classMl->at(iclass)]; - } + for (unsigned int iclass = 0; iclass < classMl->size(); iclass++) { + outputMl[iclass] = candidate.mlProbDplusToPiKPi()[classMl->at(iclass)]; } - } else if constexpr (std::is_same_v || std::is_same_v) { + } else if constexpr (std::is_same_v) { switch (Channel) { case DecayChannel::D0ToPiK: signCand = candidate.isSelD0bar() ? 3 : 1; // 3: reflected D0bar, 1: pure D0 excluding reflected D0bar @@ -690,10 +670,8 @@ struct HfTaskFlowCharmHadrons { if (std::abs(massCand - MassD0) < nSigmaMass * sigmaMD0) { hasCandInMassWin = true; } - if constexpr (std::is_same_v) { - for (unsigned int iclass = 0; iclass < classMl->size(); iclass++) { - outputMl[iclass] = candidate.mlProbD0()[classMl->at(iclass)]; - } + for (unsigned int iclass = 0; iclass < classMl->size(); iclass++) { + outputMl[iclass] = candidate.mlProbD0()[classMl->at(iclass)]; } break; case DecayChannel::D0ToKPi: @@ -702,56 +680,46 @@ struct HfTaskFlowCharmHadrons { hasCandInMassWin = true; } signCand = candidate.isSelD0() ? 3 : 2; // 3: reflected D0, 2: pure D0bar excluding reflected D0 - if constexpr (std::is_same_v) { - for (unsigned int iclass = 0; iclass < classMl->size(); iclass++) { - outputMl[iclass] = candidate.mlProbD0bar()[classMl->at(iclass)]; - } + for (unsigned int iclass = 0; iclass < classMl->size(); iclass++) { + outputMl[iclass] = candidate.mlProbD0bar()[classMl->at(iclass)]; } break; default: break; } - } else if constexpr (std::is_same_v || std::is_same_v) { + } else if constexpr (std::is_same_v) { switch (Channel) { case DecayChannel::LcToPKPi: massCand = HfHelper::invMassLcToPKPi(candidate); signCand = 1; - if constexpr (std::is_same_v) { - for (unsigned int iclass = 0; iclass < classMl->size(); iclass++) { - outputMl[iclass] = candidate.mlProbLcToPKPi()[classMl->at(iclass)]; - } + for (unsigned int iclass = 0; iclass < classMl->size(); iclass++) { + outputMl[iclass] = candidate.mlProbLcToPKPi()[classMl->at(iclass)]; } break; case DecayChannel::LcToPiKP: massCand = HfHelper::invMassLcToPiKP(candidate); signCand = -1; - if constexpr (std::is_same_v) { - for (unsigned int iclass = 0; iclass < classMl->size(); iclass++) { - outputMl[iclass] = candidate.mlProbLcToPiKP()[classMl->at(iclass)]; - } + for (unsigned int iclass = 0; iclass < classMl->size(); iclass++) { + outputMl[iclass] = candidate.mlProbLcToPiKP()[classMl->at(iclass)]; } break; default: break; } - } else if constexpr (std::is_same_v || std::is_same_v) { + } else if constexpr (std::is_same_v) { switch (Channel) { case DecayChannel::XicToPKPi: massCand = HfHelper::invMassXicToPKPi(candidate); signCand = 1; - if constexpr (std::is_same_v) { - for (unsigned int iclass = 0; iclass < classMl->size(); iclass++) { - outputMl[iclass] = candidate.mlProbXicToPKPi()[classMl->at(iclass)]; - } + for (unsigned int iclass = 0; iclass < classMl->size(); iclass++) { + outputMl[iclass] = candidate.mlProbXicToPKPi()[classMl->at(iclass)]; } break; case DecayChannel::XicToPiKP: massCand = HfHelper::invMassXicToPiKP(candidate); signCand = -1; - if constexpr (std::is_same_v) { - for (unsigned int iclass = 0; iclass < classMl->size(); iclass++) { - outputMl[iclass] = candidate.mlProbXicToPiKP()[classMl->at(iclass)]; - } + for (unsigned int iclass = 0; iclass < classMl->size(); iclass++) { + outputMl[iclass] = candidate.mlProbXicToPiKP()[classMl->at(iclass)]; } break; default: @@ -810,12 +778,12 @@ struct HfTaskFlowCharmHadrons { scalprodCand = cosNPhi * xQVec + sinNPhi * yQVec; } LOG(info) << "\nScalar product before correction" << scalprodCand; - if (useOnlineResoCorrection) { + if (useOnlineResoCorrection && scalarProdReso > 1e-5f) { scalprodCand /= scalarProdReso; } LOG(info) << "Scalar product after correction" << scalprodCand; - if (fillMassPtMlTree || fillMassPtMlSpCentTree) { + if (fillMassPtMlTree || fillMassPtMlSpCentTree || fillMassPtMlSpCentPvTree) { if (downSampleFactor < 1.) { float const pseudoRndm = ptCand * 1000. - static_cast(ptCand * 1000); if (ptCand < ptDownSampleMax && pseudoRndm >= downSampleFactor) { @@ -833,7 +801,7 @@ struct HfTaskFlowCharmHadrons { } } - bool subtractDaugsFromRedQVec = storeRedQVec && subtrDaugsFromRedQVec && + bool subtractDaugsFromRedQVec = storeRedQVec && useRedQVecDaugsSubtr && (qVecRedDetector == QvecEstimator::TPCNeg || qVecRedDetector == QvecEstimator::TPCPos || qVecRedDetector == QvecEstimator::TPCTot); @@ -916,7 +884,7 @@ struct HfTaskFlowCharmHadrons { // Dplus with ML EsE void processDplusEsEMl(CollsWithEsEQvecs::iterator const& collision, - CandDplusDataWMl const& /*candidatesD0*/, + CandDplusDataWMl const& candidatesDplus, TracksWithExtra const& tracks) { runFlowAnalysis(collision, candidatesDplus, tracks); @@ -925,8 +893,8 @@ struct HfTaskFlowCharmHadrons { // Dplus with ML SP and EsE void processDplusSPEsEMl(CollsWithSPEsEQvecs::iterator const& collision, - CandDplusDataWMl const& /*candidatesD0*/, - TracksWithExtra const& tracks) + CandDplusDataWMl const& candidatesDplus, + TracksWithExtra const& tracks) { runFlowAnalysis(collision, candidatesDplus, tracks); } diff --git a/PWGHF/D2H/Utils/utilsFlow.h b/PWGHF/D2H/Utils/utilsFlow.h index e01aef1bc28..0f8af31fe3d 100644 --- a/PWGHF/D2H/Utils/utilsFlow.h +++ b/PWGHF/D2H/Utils/utilsFlow.h @@ -42,10 +42,10 @@ enum QvecEstimator { FV0A = 0, TPCNeg, TPCTot }; -class QVectorResoHelper { +class HfQVectorResoHelper { public: - QVectorResoHelper() = default; + HfQVectorResoHelper() = default; /// Call once per run / timestamp update void update(o2::framework::Service& ccdb, From 2e3b62cd04a222cf68202b91a93b7f004499265e Mon Sep 17 00:00:00 2001 From: ALICE Action Bot Date: Fri, 28 Aug 2026 15:09:58 +0000 Subject: [PATCH 3/4] Please consider the following formatting changes --- PWGHF/D2H/Tasks/taskFlowCharmHadrons.cxx | 4 +--- PWGHF/D2H/Utils/utilsFlow.h | 5 ++--- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/PWGHF/D2H/Tasks/taskFlowCharmHadrons.cxx b/PWGHF/D2H/Tasks/taskFlowCharmHadrons.cxx index 65baa89b02f..45a351dd1f8 100644 --- a/PWGHF/D2H/Tasks/taskFlowCharmHadrons.cxx +++ b/PWGHF/D2H/Tasks/taskFlowCharmHadrons.cxx @@ -801,7 +801,7 @@ struct HfTaskFlowCharmHadrons { } } - bool subtractDaugsFromRedQVec = storeRedQVec && useRedQVecDaugsSubtr && + bool subtractDaugsFromRedQVec = storeRedQVec && useRedQVecDaugsSubtr && (qVecRedDetector == QvecEstimator::TPCNeg || qVecRedDetector == QvecEstimator::TPCPos || qVecRedDetector == QvecEstimator::TPCTot); @@ -1037,8 +1037,6 @@ struct HfTaskFlowCharmHadrons { // } // PROCESS_SWITCH(HfTaskFlowCharmHadrons, processXic, "Process Xic candidates", false); - - /// Compute resolution /// \param collision is the collision with the Q vector information /// \param bcs is used for the event selection based on centrality estimators with time information diff --git a/PWGHF/D2H/Utils/utilsFlow.h b/PWGHF/D2H/Utils/utilsFlow.h index 0f8af31fe3d..79fdefc067d 100644 --- a/PWGHF/D2H/Utils/utilsFlow.h +++ b/PWGHF/D2H/Utils/utilsFlow.h @@ -29,7 +29,6 @@ #include #include - namespace o2::analysis { namespace hf_flow_utils @@ -42,9 +41,9 @@ enum QvecEstimator { FV0A = 0, TPCNeg, TPCTot }; -class HfQVectorResoHelper { +class HfQVectorResoHelper +{ public: - HfQVectorResoHelper() = default; /// Call once per run / timestamp update From c6397957082e57201c696a28ed6e95ff51623280 Mon Sep 17 00:00:00 2001 From: marcellocosti Date: Fri, 28 Aug 2026 18:58:31 +0200 Subject: [PATCH 4/4] Add missing headers --- PWGHF/D2H/Utils/utilsFlow.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/PWGHF/D2H/Utils/utilsFlow.h b/PWGHF/D2H/Utils/utilsFlow.h index 79fdefc067d..7d6fdcc7d0e 100644 --- a/PWGHF/D2H/Utils/utilsFlow.h +++ b/PWGHF/D2H/Utils/utilsFlow.h @@ -20,6 +20,9 @@ #include #include +#include +#include +#include #include #include