From 49a5803706208afbb59fae39dc6d075be7eb7131 Mon Sep 17 00:00:00 2001 From: marcellocosti Date: Tue, 26 Aug 2025 11:29:59 +0200 Subject: [PATCH 1/5] Task for D+ and Ds correlations in small systems --- .../DataModel/DerivedDataCorrelationTables.h | 66 +++- PWGHF/HFC/TableProducer/CMakeLists.txt | 5 + .../correlatorFlowCharmHadrons.cxx | 323 ++++++++++++++++++ 3 files changed, 384 insertions(+), 10 deletions(-) create mode 100644 PWGHF/HFC/TableProducer/correlatorFlowCharmHadrons.cxx diff --git a/PWGHF/HFC/DataModel/DerivedDataCorrelationTables.h b/PWGHF/HFC/DataModel/DerivedDataCorrelationTables.h index 39a3231977c..e551fe9c5c1 100644 --- a/PWGHF/HFC/DataModel/DerivedDataCorrelationTables.h +++ b/PWGHF/HFC/DataModel/DerivedDataCorrelationTables.h @@ -24,6 +24,7 @@ namespace hf_collisions_reduced { DECLARE_SOA_COLUMN(NumPvContrib, numPvContrib, int); //! Event multiplicity from PV contributors DECLARE_SOA_COLUMN(Multiplicity, multiplicity, float); //! Event multiplicity +DECLARE_SOA_COLUMN(Centrality, centrality, float); //! Event centrality DECLARE_SOA_COLUMN(PosZ, posZ, float); //! Primary vertex z position } // namespace hf_collisions_reduced @@ -34,6 +35,13 @@ DECLARE_SOA_TABLE(HfcRedCollisions, "AOD", "HFCREDCOLLISION", //! Table with col aod::hf_collisions_reduced::NumPvContrib, aod::hf_collisions_reduced::PosZ); +DECLARE_SOA_TABLE(HfcRedFlowColls, "AOD", "HFCREDFLOWCOLL", //! Table with collision info + soa::Index<>, + aod::hf_collisions_reduced::Multiplicity, + aod::hf_collisions_reduced::NumPvContrib, + aod::hf_collisions_reduced::Centrality, + aod::hf_collisions_reduced::PosZ); + using HfcRedCollision = HfcRedCollisions::iterator; // DECLARE_SOA_TABLE(HfCandColCounts, "AOD", "HFCANDCOLCOUNT", //! Table with number of collisions which contain at least one candidate @@ -41,16 +49,20 @@ using HfcRedCollision = HfcRedCollisions::iterator; namespace hf_candidate_reduced { -DECLARE_SOA_INDEX_COLUMN(HfcRedCollision, hfcRedCollision); //! ReducedCollision index -DECLARE_SOA_COLUMN(Prong0Id, prong0Id, int); //! Prong 0 index -DECLARE_SOA_COLUMN(Prong1Id, prong1Id, int); //! Prong 1 index -DECLARE_SOA_COLUMN(Prong2Id, prong2Id, int); //! Prong2 index -DECLARE_SOA_COLUMN(PhiCand, phiCand, float); //! Phi of the candidate -DECLARE_SOA_COLUMN(EtaCand, etaCand, float); //! Eta of the candidate -DECLARE_SOA_COLUMN(PtCand, ptCand, float); //! Pt of the candidate -DECLARE_SOA_COLUMN(InvMassDs, invMassDs, float); //! Invariant mass of Ds candidate -DECLARE_SOA_COLUMN(BdtScorePrompt, bdtScorePrompt, float); //! BDT output score for prompt hypothesis -DECLARE_SOA_COLUMN(BdtScoreBkg, bdtScoreBkg, float); //! BDT output score for backgronud hypothesis +DECLARE_SOA_INDEX_COLUMN(HfcRedCollision, hfcRedCollision); //! ReducedCollision index +DECLARE_SOA_INDEX_COLUMN(HfcRedFlowColl, hfcRedFlowColl); //! ReducedCollision index +DECLARE_SOA_COLUMN(Prong0Id, prong0Id, int); //! Prong 0 index +DECLARE_SOA_COLUMN(Prong1Id, prong1Id, int); //! Prong 1 index +DECLARE_SOA_COLUMN(Prong2Id, prong2Id, int); //! Prong2 index +DECLARE_SOA_COLUMN(PhiCand, phiCand, float); //! Phi of the candidate +DECLARE_SOA_COLUMN(EtaCand, etaCand, float); //! Eta of the candidate +DECLARE_SOA_COLUMN(PtCand, ptCand, float); //! Pt of the candidate +DECLARE_SOA_COLUMN(InvMassDs, invMassDs, float); //! Invariant mass of Ds candidate +DECLARE_SOA_COLUMN(InvMassCharmHad, invMassCharmHad, float); //! Invariant mass of CharmHad candidate +DECLARE_SOA_COLUMN(BdtScorePrompt, bdtScorePrompt, float); //! BDT output score for prompt hypothesis +DECLARE_SOA_COLUMN(BdtScoreBkg, bdtScoreBkg, float); //! BDT output score for backgronud hypothesis +DECLARE_SOA_COLUMN(BdtScore0, bdtScore0, float); //! First BDT output score +DECLARE_SOA_COLUMN(BdtScore1, bdtScore1, float); //! Second BDT output score } // namespace hf_candidate_reduced DECLARE_SOA_TABLE(DsCandReduceds, "AOD", "DSCANDREDUCED", //! Table with Ds candidate info soa::Index<>, @@ -69,6 +81,23 @@ DECLARE_SOA_TABLE(DsCandSelInfos, "AOD", "DSCANDSELINFO", //! Table with Ds cand aod::hf_candidate_reduced::BdtScorePrompt, aod::hf_candidate_reduced::BdtScoreBkg); +DECLARE_SOA_TABLE(HfcRedCharmHads, "AOD", "HFCREDCHARMHAD", //! Table with charm hadron candidate info + soa::Index<>, + aod::hf_candidate_reduced::HfcRedFlowCollId, + aod::hf_candidate_reduced::PhiCand, + aod::hf_candidate_reduced::EtaCand, + aod::hf_candidate_reduced::PtCand, + aod::hf_candidate_reduced::InvMassCharmHad, + aod::hf_candidate_reduced::Prong0Id, + aod::hf_candidate_reduced::Prong1Id, + aod::hf_candidate_reduced::Prong2Id); + +DECLARE_SOA_TABLE(HfcRedCharmMls, "AOD", "HFCREDCHARMML", //! Table with charm hadron candidate selection info + soa::Index<>, + aod::hf_candidate_reduced::HfcRedFlowCollId, + aod::hf_candidate_reduced::BdtScore0, + aod::hf_candidate_reduced::BdtScore1); + namespace hf_assoc_track_reduced { DECLARE_SOA_COLUMN(OriginTrackId, originTrackId, int); //! Original track index @@ -97,6 +126,23 @@ DECLARE_SOA_TABLE(AssocTrackSels, "AOD", "ASSOCTRACKSEL", //! Table with associa aod::hf_assoc_track_reduced::ItsNCls, aod::hf_assoc_track_reduced::DcaXY, aod::hf_assoc_track_reduced::DcaZ) + +DECLARE_SOA_TABLE(HfcRedTrkAssoc, "AOD", "HFCREDTRKASSOC", //! Table with associated track info + soa::Index<>, + aod::hf_candidate_reduced::HfcRedFlowCollId, + aod::hf_assoc_track_reduced::OriginTrackId, + aod::hf_assoc_track_reduced::PhiAssocTrack, + aod::hf_assoc_track_reduced::EtaAssocTrack, + aod::hf_assoc_track_reduced::PtAssocTrack); + +DECLARE_SOA_TABLE(HfcRedTrkSels, "AOD", "HFCREDTRKSELS", //! Table with associated track info + soa::Index<>, + aod::hf_candidate_reduced::HfcRedFlowCollId, + aod::hf_assoc_track_reduced::NTpcCrossedRows, + aod::hf_assoc_track_reduced::ItsClusterMap, + aod::hf_assoc_track_reduced::ItsNCls, + aod::hf_assoc_track_reduced::DcaXY, + aod::hf_assoc_track_reduced::DcaZ) } // namespace o2::aod #endif // PWGHF_HFC_DATAMODEL_DERIVEDDATACORRELATIONTABLES_H_ diff --git a/PWGHF/HFC/TableProducer/CMakeLists.txt b/PWGHF/HFC/TableProducer/CMakeLists.txt index 99f2c4fb152..eff0f6557b3 100644 --- a/PWGHF/HFC/TableProducer/CMakeLists.txt +++ b/PWGHF/HFC/TableProducer/CMakeLists.txt @@ -44,6 +44,11 @@ o2physics_add_dpl_workflow(correlator-ds-hadrons PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(correlator-flow-charm-hadrons + SOURCES correlatorFlowCharmHadrons.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2Physics::EventFilteringUtils + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(correlator-ds-hadrons-reduced SOURCES correlatorDsHadronsReduced.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore diff --git a/PWGHF/HFC/TableProducer/correlatorFlowCharmHadrons.cxx b/PWGHF/HFC/TableProducer/correlatorFlowCharmHadrons.cxx new file mode 100644 index 00000000000..861178bc8a9 --- /dev/null +++ b/PWGHF/HFC/TableProducer/correlatorFlowCharmHadrons.cxx @@ -0,0 +1,323 @@ +// 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 correlatorFlowCharmHadrons.cxx +/// \brief CharmHadrons-Hadrons correlator tree creator for data and MC-reco analyses +/// \author Marcello Di Costanzo , Politecnico and INFN Torino +/// \author Stefano PolitanĂ² , CERN + +#include "PWGHF/Core/HfHelper.h" +#include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/DataModel/CandidateSelectionTables.h" +#include "PWGHF/HFC/DataModel/DerivedDataCorrelationTables.h" +#include "PWGHF/Utils/utilsEvSelHf.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 + +using namespace o2; +using namespace o2::hf_centrality; +using namespace o2::hf_evsel; + +enum DecayChannel { + DplusToPiKPi = 0, + DsToKKPi, + DsToPiKK +}; + +/// Code to select collisions with at least one Ds meson +struct HfCorrelatorFlowCharmHadrons { + Produces rowCollisions; + Produces rowCharmCandidates; + Produces rowCharmCandidatesMl; + Produces rowAssocTrackReduced; + Produces rowAssocTrackSelInfo; + + Configurable centEstimator{"centEstimator", 2, "Centrality estimation (FT0A: 1, FT0C: 2, FT0M: 3, FV0A: 4)"}; + Configurable selectionFlag{"selectionFlag", 1, "Selection Flag for hadron (e.g. 1 for skimming, 3 for topo. and kine., 7 for PID)"}; + Configurable forceCharmInCollision{"forceCharmInCollision", false, "Flag to force charm in collision"}; + 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", 1., "min. cand. pT"}; + Configurable ptCandMax{"ptCandMax", 24., "max. cand. pT"}; + Configurable etaTrackMax{"etaTrackMax", 1., "max. track eta"}; + Configurable ptTrackMin{"ptTrackMin", 0.15, "min. track pT"}; + Configurable ptTrackMax{"ptTrackMax", 5., "max. track pT"}; + Configurable dcaXYTrackMax{"dcaXYTrackMax", 1., "max. track DCA XY"}; + Configurable dcaZTrackMax{"dcaZTrackMax", 1., "max. track DCA Z"}; + + HfHelper hfHelper; + HfEventSelection hfEvSel; // event selection and monitoring + o2::framework::Service ccdb; + SliceCache cache; + + double massCharm{0.}; + + using CollsWithCentMult = soa::Join; + using CandDsDataWMl = soa::Filtered>; + using CandDsData = soa::Filtered>; + using CandDplusDataWMl = soa::Filtered>; + using CandDplusData = 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; + Filter filterSelectTrackData = (nabs(aod::track::eta) < etaTrackMax) && (aod::track::pt > ptTrackMin) && (aod::track::pt < ptTrackMax) && (nabs(aod::track::dcaXY) < dcaXYTrackMax) && (nabs(aod::track::dcaZ) < dcaZTrackMax); + + Preslice candsDsPerColl = aod::hf_cand::collisionId; + Preslice candsDsPerCollWMl = aod::hf_cand::collisionId; + Preslice candsDplusPerColl = aod::hf_cand::collisionId; + Preslice candsDplusPerCollWMl = 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 selectedDsToKKPiWMl = aod::hf_sel_candidate_ds::isSelDsToKKPi >= selectionFlag; + Partition selectedDsToPiKKWMl = aod::hf_sel_candidate_ds::isSelDsToPiKK >= selectionFlag; + + HistogramRegistry registry{"registry", {}}; + + void init(InitContext&) { + if (doprocessDplus || doprocessDplusWithMl) { + massCharm = o2::constants::physics::MassDPlus; + } else if (doprocessDs || doprocessDsWithMl) { + massCharm = o2::constants::physics::MassDS; + } + + hfEvSel.addHistograms(registry); // collision monitoring + ccdb->setURL(ccdbUrl); + ccdb->setCaching(true); + ccdb->setLocalObjectValidityChecking(); + }; // end init + + /// Check event selections for collision and fill the collision table + /// \param collision is the collision with the Q vector information and event plane + template + bool checkAndFillCollision(Coll const& collision) + { + float cent{-1.f}; + float mult{-1.f}; + 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); + if (collRejMask != 0) { + return false; + } + rowCollisions(mult, collision.numContrib(), cent, collision.posZ()); + return true; + } + + /// Get charm hadron candidate mass + /// \param candidate is the charm hadron candidate + template + double getCandMass(const TCand& candidate) + { + if constexpr (channel == DecayChannel::DsToKKPi) { + return hfHelper.invMassDsToKKPi(candidate); + } + if constexpr (channel == DecayChannel::DsToPiKK){ + return hfHelper.invMassDsToPiKK(candidate); + } + if constexpr (channel == DecayChannel::DplusToPiKPi){ + return hfHelper.invMassDplusToPiKPi(candidate); + } + return -1.; + } + + /// Get charm hadron bdt scores + /// \param candidate is the charm hadron candidate + template + std::vector getCandMlScores(const TCand& candidate) + { + std::vector outputMl{ -999., -999. }; + if constexpr (channel == DecayChannel::DsToKKPi) { + for (unsigned int iclass = 0; iclass < classMl->size(); iclass++) { + outputMl[iclass] = candidate.mlProbDsToKKPi()[classMl->at(iclass)]; + } + } + if constexpr (channel == DecayChannel::DsToPiKK){ + for (unsigned int iclass = 0; iclass < classMl->size(); iclass++) { + outputMl[iclass] = candidate.mlProbDsToPiKK()[classMl->at(iclass)]; + } + } + if constexpr (channel == DecayChannel::DplusToPiKPi){ + for (unsigned int iclass = 0; iclass < classMl->size(); iclass++) { + outputMl[iclass] = candidate.mlProbDplusToPiKPi()[classMl->at(iclass)]; + } + } + return outputMl; + } + + /// Fill charm hadron tables + /// \param candidates are the selected charm hadron candidates + template + void fillCharmHadronTables(TCand const& candidates) + { + int indexRedColl = rowCollisions.lastIndex(); + for (const auto& candidate : candidates) { + if (std::abs(candidate.y(massCharm)) > yCandMax || candidate.pt() < ptCandMin || candidate.pt() > ptCandMax) { + continue; + } + double massCand = getCandMass(candidate); + rowCharmCandidates(indexRedColl, candidate.phi(), candidate.eta(), candidate.pt(), massCand, candidate.prong0Id(), candidate.prong1Id(), candidate.prong2Id()); + + if constexpr (applyMl) { + std::vector outputMl = getCandMlScores(candidate); + rowCharmCandidatesMl(indexRedColl, outputMl[0], outputMl[1]); + } + } + } + + /// Fill tracks tables + /// \param tracks are the selected tracks + template + void fillTracksTables(TTrack const& tracks) + { + int indexRedColl = rowCollisions.lastIndex(); + for (const auto& track : tracks) { + if (!track.isGlobalTrackWoDCA()) { + continue; + } + rowAssocTrackReduced(indexRedColl, track.globalIndex(), track.phi(), track.eta(), track.pt() * track.sign()); + rowAssocTrackSelInfo(indexRedColl, track.tpcNClsCrossedRows(), track.itsClusterMap(), track.itsNCls(), track.dcaXY(), track.dcaZ()); + } + } + + // Dplus with rectangular cuts + void processDplus(CollsWithCentMult const& colls, + CandDplusData const& candsDplus, + TracksData const& tracks) + { + for (const auto& coll : colls) { + auto thisCollId = coll.globalIndex(); + auto candsCThisColl = candsDplus.sliceBy(candsDplusPerColl, thisCollId); + if (forceCharmInCollision && candsCThisColl.size() < 1) { + continue; + } + if (!checkAndFillCollision(coll)) { + continue; + } + auto trackIdsThisColl = tracks.sliceBy(trackIndicesPerColl, thisCollId); + fillCharmHadronTables(candsCThisColl); + fillTracksTables(trackIdsThisColl); + } + } + PROCESS_SWITCH(HfCorrelatorFlowCharmHadrons, processDplus, "Process Dplus candidates", true); + + // Dplus with ML selections + void processDplusWithMl(CollsWithCentMult const& colls, + CandDplusDataWMl const& candsDplus, + TracksData const& tracks) + { + for (const auto& coll : colls) { + auto thisCollId = coll.globalIndex(); + auto candsCThisColl = candsDplus.sliceBy(candsDplusPerColl, thisCollId); + if (forceCharmInCollision && candsCThisColl.size() < 1) { + continue; + } + if (!checkAndFillCollision(coll)) { + continue; + } + auto trackIdsThisColl = tracks.sliceBy(trackIndicesPerColl, thisCollId); + fillCharmHadronTables(candsCThisColl); + fillTracksTables(trackIdsThisColl); + } + } + PROCESS_SWITCH(HfCorrelatorFlowCharmHadrons, processDplusWithMl, "Process Dplus candidates with ML info", false); + + // Ds with rectangular cuts + void processDs(CollsWithCentMult const& colls, + TracksData const& tracks, + CandDsData const&) + { + for (const auto& coll : colls) { + auto thisCollId = coll.globalIndex(); + auto candsDsToKKPi = selectedDsToKKPi->sliceByCached(aod::hf_cand::collisionId, thisCollId, cache); + auto candsDsToPiKK = selectedDsToPiKK->sliceByCached(aod::hf_cand::collisionId, thisCollId, cache); + if (forceCharmInCollision && candsDsToKKPi.size() < 1 && candsDsToPiKK.size() < 1) { + continue; + } + if (!checkAndFillCollision(coll)) { + continue; + } + auto trackIdsThisColl = tracks.sliceBy(trackIndicesPerColl, thisCollId); + fillCharmHadronTables(candsDsToPiKK); + fillCharmHadronTables(candsDsToKKPi); + fillTracksTables(trackIdsThisColl); + } + } + PROCESS_SWITCH(HfCorrelatorFlowCharmHadrons, processDs, "Process Ds candidates", false); + + // Ds with ML selections + void processDsWithMl(CollsWithCentMult const& colls, + TracksData const& tracks, + CandDsDataWMl const&) + { + for (const auto& coll : colls) { + auto thisCollId = coll.globalIndex(); + auto candsDsToKKPiWMl = selectedDsToKKPiWMl->sliceByCached(aod::hf_cand::collisionId, thisCollId, cache); + auto candsDsToPiKKWMl = selectedDsToPiKKWMl->sliceByCached(aod::hf_cand::collisionId, thisCollId, cache); + if (forceCharmInCollision && candsDsToKKPiWMl.size() < 1 && candsDsToPiKKWMl.size() < 1) { + continue; + } + if (!checkAndFillCollision(coll)) { + continue; + } + auto trackIdsThisColl = tracks.sliceBy(trackIndicesPerColl, thisCollId); + fillCharmHadronTables(candsDsToPiKKWMl); + fillCharmHadronTables(candsDsToKKPiWMl); + fillTracksTables(trackIdsThisColl); + } + } + PROCESS_SWITCH(HfCorrelatorFlowCharmHadrons, processDsWithMl, "Process Ds candidates with ML info", false); + +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{adaptAnalysisTask(cfgc)}; +} From 76fabcf9a570f29e15e65331be8ed44353febec2 Mon Sep 17 00:00:00 2001 From: ALICE Action Bot Date: Thu, 28 Aug 2025 12:38:50 +0000 Subject: [PATCH 2/5] Please consider the following formatting changes --- .../DataModel/DerivedDataCorrelationTables.h | 28 +++++------ .../correlatorFlowCharmHadrons.cxx | 50 +++++++++---------- 2 files changed, 39 insertions(+), 39 deletions(-) diff --git a/PWGHF/HFC/DataModel/DerivedDataCorrelationTables.h b/PWGHF/HFC/DataModel/DerivedDataCorrelationTables.h index e551fe9c5c1..d48cd0f9d10 100644 --- a/PWGHF/HFC/DataModel/DerivedDataCorrelationTables.h +++ b/PWGHF/HFC/DataModel/DerivedDataCorrelationTables.h @@ -49,20 +49,20 @@ using HfcRedCollision = HfcRedCollisions::iterator; namespace hf_candidate_reduced { -DECLARE_SOA_INDEX_COLUMN(HfcRedCollision, hfcRedCollision); //! ReducedCollision index -DECLARE_SOA_INDEX_COLUMN(HfcRedFlowColl, hfcRedFlowColl); //! ReducedCollision index -DECLARE_SOA_COLUMN(Prong0Id, prong0Id, int); //! Prong 0 index -DECLARE_SOA_COLUMN(Prong1Id, prong1Id, int); //! Prong 1 index -DECLARE_SOA_COLUMN(Prong2Id, prong2Id, int); //! Prong2 index -DECLARE_SOA_COLUMN(PhiCand, phiCand, float); //! Phi of the candidate -DECLARE_SOA_COLUMN(EtaCand, etaCand, float); //! Eta of the candidate -DECLARE_SOA_COLUMN(PtCand, ptCand, float); //! Pt of the candidate -DECLARE_SOA_COLUMN(InvMassDs, invMassDs, float); //! Invariant mass of Ds candidate -DECLARE_SOA_COLUMN(InvMassCharmHad, invMassCharmHad, float); //! Invariant mass of CharmHad candidate -DECLARE_SOA_COLUMN(BdtScorePrompt, bdtScorePrompt, float); //! BDT output score for prompt hypothesis -DECLARE_SOA_COLUMN(BdtScoreBkg, bdtScoreBkg, float); //! BDT output score for backgronud hypothesis -DECLARE_SOA_COLUMN(BdtScore0, bdtScore0, float); //! First BDT output score -DECLARE_SOA_COLUMN(BdtScore1, bdtScore1, float); //! Second BDT output score +DECLARE_SOA_INDEX_COLUMN(HfcRedCollision, hfcRedCollision); //! ReducedCollision index +DECLARE_SOA_INDEX_COLUMN(HfcRedFlowColl, hfcRedFlowColl); //! ReducedCollision index +DECLARE_SOA_COLUMN(Prong0Id, prong0Id, int); //! Prong 0 index +DECLARE_SOA_COLUMN(Prong1Id, prong1Id, int); //! Prong 1 index +DECLARE_SOA_COLUMN(Prong2Id, prong2Id, int); //! Prong2 index +DECLARE_SOA_COLUMN(PhiCand, phiCand, float); //! Phi of the candidate +DECLARE_SOA_COLUMN(EtaCand, etaCand, float); //! Eta of the candidate +DECLARE_SOA_COLUMN(PtCand, ptCand, float); //! Pt of the candidate +DECLARE_SOA_COLUMN(InvMassDs, invMassDs, float); //! Invariant mass of Ds candidate +DECLARE_SOA_COLUMN(InvMassCharmHad, invMassCharmHad, float); //! Invariant mass of CharmHad candidate +DECLARE_SOA_COLUMN(BdtScorePrompt, bdtScorePrompt, float); //! BDT output score for prompt hypothesis +DECLARE_SOA_COLUMN(BdtScoreBkg, bdtScoreBkg, float); //! BDT output score for backgronud hypothesis +DECLARE_SOA_COLUMN(BdtScore0, bdtScore0, float); //! First BDT output score +DECLARE_SOA_COLUMN(BdtScore1, bdtScore1, float); //! Second BDT output score } // namespace hf_candidate_reduced DECLARE_SOA_TABLE(DsCandReduceds, "AOD", "DSCANDREDUCED", //! Table with Ds candidate info soa::Index<>, diff --git a/PWGHF/HFC/TableProducer/correlatorFlowCharmHadrons.cxx b/PWGHF/HFC/TableProducer/correlatorFlowCharmHadrons.cxx index 861178bc8a9..38540eb6424 100644 --- a/PWGHF/HFC/TableProducer/correlatorFlowCharmHadrons.cxx +++ b/PWGHF/HFC/TableProducer/correlatorFlowCharmHadrons.cxx @@ -47,7 +47,7 @@ using namespace o2; using namespace o2::hf_centrality; using namespace o2::hf_evsel; -enum DecayChannel { +enum DecayChannel { DplusToPiKPi = 0, DsToKKPi, DsToPiKK @@ -106,7 +106,8 @@ struct HfCorrelatorFlowCharmHadrons { HistogramRegistry registry{"registry", {}}; - void init(InitContext&) { + void init(InitContext&) + { if (doprocessDplus || doprocessDplusWithMl) { massCharm = o2::constants::physics::MassDPlus; } else if (doprocessDs || doprocessDsWithMl) { @@ -159,32 +160,32 @@ struct HfCorrelatorFlowCharmHadrons { if constexpr (channel == DecayChannel::DsToKKPi) { return hfHelper.invMassDsToKKPi(candidate); } - if constexpr (channel == DecayChannel::DsToPiKK){ + if constexpr (channel == DecayChannel::DsToPiKK) { return hfHelper.invMassDsToPiKK(candidate); } - if constexpr (channel == DecayChannel::DplusToPiKPi){ + if constexpr (channel == DecayChannel::DplusToPiKPi) { return hfHelper.invMassDplusToPiKPi(candidate); } return -1.; } - + /// Get charm hadron bdt scores /// \param candidate is the charm hadron candidate template std::vector getCandMlScores(const TCand& candidate) { - std::vector outputMl{ -999., -999. }; + std::vector outputMl{-999., -999.}; if constexpr (channel == DecayChannel::DsToKKPi) { for (unsigned int iclass = 0; iclass < classMl->size(); iclass++) { outputMl[iclass] = candidate.mlProbDsToKKPi()[classMl->at(iclass)]; } } - if constexpr (channel == DecayChannel::DsToPiKK){ + if constexpr (channel == DecayChannel::DsToPiKK) { for (unsigned int iclass = 0; iclass < classMl->size(); iclass++) { outputMl[iclass] = candidate.mlProbDsToPiKK()[classMl->at(iclass)]; } } - if constexpr (channel == DecayChannel::DplusToPiKPi){ + if constexpr (channel == DecayChannel::DplusToPiKPi) { for (unsigned int iclass = 0; iclass < classMl->size(); iclass++) { outputMl[iclass] = candidate.mlProbDplusToPiKPi()[classMl->at(iclass)]; } @@ -204,7 +205,7 @@ struct HfCorrelatorFlowCharmHadrons { } double massCand = getCandMass(candidate); rowCharmCandidates(indexRedColl, candidate.phi(), candidate.eta(), candidate.pt(), massCand, candidate.prong0Id(), candidate.prong1Id(), candidate.prong2Id()); - + if constexpr (applyMl) { std::vector outputMl = getCandMlScores(candidate); rowCharmCandidatesMl(indexRedColl, outputMl[0], outputMl[1]); @@ -236,10 +237,10 @@ struct HfCorrelatorFlowCharmHadrons { auto thisCollId = coll.globalIndex(); auto candsCThisColl = candsDplus.sliceBy(candsDplusPerColl, thisCollId); if (forceCharmInCollision && candsCThisColl.size() < 1) { - continue; + continue; } if (!checkAndFillCollision(coll)) { - continue; + continue; } auto trackIdsThisColl = tracks.sliceBy(trackIndicesPerColl, thisCollId); fillCharmHadronTables(candsCThisColl); @@ -247,21 +248,21 @@ struct HfCorrelatorFlowCharmHadrons { } } PROCESS_SWITCH(HfCorrelatorFlowCharmHadrons, processDplus, "Process Dplus candidates", true); - + // Dplus with ML selections void processDplusWithMl(CollsWithCentMult const& colls, CandDplusDataWMl const& candsDplus, TracksData const& tracks) - { - for (const auto& coll : colls) { - auto thisCollId = coll.globalIndex(); - auto candsCThisColl = candsDplus.sliceBy(candsDplusPerColl, thisCollId); - if (forceCharmInCollision && candsCThisColl.size() < 1) { - continue; - } - if (!checkAndFillCollision(coll)) { - continue; - } + { + for (const auto& coll : colls) { + auto thisCollId = coll.globalIndex(); + auto candsCThisColl = candsDplus.sliceBy(candsDplusPerColl, thisCollId); + if (forceCharmInCollision && candsCThisColl.size() < 1) { + continue; + } + if (!checkAndFillCollision(coll)) { + continue; + } auto trackIdsThisColl = tracks.sliceBy(trackIndicesPerColl, thisCollId); fillCharmHadronTables(candsCThisColl); fillTracksTables(trackIdsThisColl); @@ -279,10 +280,10 @@ struct HfCorrelatorFlowCharmHadrons { auto candsDsToKKPi = selectedDsToKKPi->sliceByCached(aod::hf_cand::collisionId, thisCollId, cache); auto candsDsToPiKK = selectedDsToPiKK->sliceByCached(aod::hf_cand::collisionId, thisCollId, cache); if (forceCharmInCollision && candsDsToKKPi.size() < 1 && candsDsToPiKK.size() < 1) { - continue; + continue; } if (!checkAndFillCollision(coll)) { - continue; + continue; } auto trackIdsThisColl = tracks.sliceBy(trackIndicesPerColl, thisCollId); fillCharmHadronTables(candsDsToPiKK); @@ -314,7 +315,6 @@ struct HfCorrelatorFlowCharmHadrons { } } PROCESS_SWITCH(HfCorrelatorFlowCharmHadrons, processDsWithMl, "Process Ds candidates with ML info", false); - }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) From 99339f063abe76ce226cdbc9d140ff976c5e36e3 Mon Sep 17 00:00:00 2001 From: marcellocosti Date: Thu, 28 Aug 2025 14:47:58 +0200 Subject: [PATCH 3/5] Missing header --- PWGHF/HFC/TableProducer/correlatorFlowCharmHadrons.cxx | 1 + 1 file changed, 1 insertion(+) diff --git a/PWGHF/HFC/TableProducer/correlatorFlowCharmHadrons.cxx b/PWGHF/HFC/TableProducer/correlatorFlowCharmHadrons.cxx index 38540eb6424..746acdbadf7 100644 --- a/PWGHF/HFC/TableProducer/correlatorFlowCharmHadrons.cxx +++ b/PWGHF/HFC/TableProducer/correlatorFlowCharmHadrons.cxx @@ -41,6 +41,7 @@ #include #include +#include #include using namespace o2; From 604235e937fe5571106bbdfe8cdfa68396857527 Mon Sep 17 00:00:00 2001 From: marcellocosti Date: Thu, 28 Aug 2025 17:54:33 +0200 Subject: [PATCH 4/5] Implement Stefano comments --- .../correlatorFlowCharmHadrons.cxx | 72 +++---------------- 1 file changed, 10 insertions(+), 62 deletions(-) diff --git a/PWGHF/HFC/TableProducer/correlatorFlowCharmHadrons.cxx b/PWGHF/HFC/TableProducer/correlatorFlowCharmHadrons.cxx index 746acdbadf7..f9585c58085 100644 --- a/PWGHF/HFC/TableProducer/correlatorFlowCharmHadrons.cxx +++ b/PWGHF/HFC/TableProducer/correlatorFlowCharmHadrons.cxx @@ -85,23 +85,17 @@ struct HfCorrelatorFlowCharmHadrons { using CollsWithCentMult = soa::Join; using CandDsDataWMl = soa::Filtered>; - using CandDsData = soa::Filtered>; using CandDplusDataWMl = soa::Filtered>; - using CandDplusData = 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; Filter filterSelectTrackData = (nabs(aod::track::eta) < etaTrackMax) && (aod::track::pt > ptTrackMin) && (aod::track::pt < ptTrackMax) && (nabs(aod::track::dcaXY) < dcaXYTrackMax) && (nabs(aod::track::dcaZ) < dcaZTrackMax); - Preslice candsDsPerColl = aod::hf_cand::collisionId; Preslice candsDsPerCollWMl = aod::hf_cand::collisionId; - Preslice candsDplusPerColl = aod::hf_cand::collisionId; Preslice candsDplusPerCollWMl = 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 selectedDsToKKPiWMl = aod::hf_sel_candidate_ds::isSelDsToKKPi >= selectionFlag; Partition selectedDsToPiKKWMl = aod::hf_sel_candidate_ds::isSelDsToPiKK >= selectionFlag; @@ -109,9 +103,9 @@ struct HfCorrelatorFlowCharmHadrons { void init(InitContext&) { - if (doprocessDplus || doprocessDplusWithMl) { + if (doprocessDplusWithMl) { massCharm = o2::constants::physics::MassDPlus; - } else if (doprocessDs || doprocessDsWithMl) { + } else if (doprocessDsWithMl) { massCharm = o2::constants::physics::MassDS; } @@ -122,7 +116,7 @@ struct HfCorrelatorFlowCharmHadrons { }; // end init /// Check event selections for collision and fill the collision table - /// \param collision is the collision with the Q vector information and event plane + /// \param collision is the collision template bool checkAndFillCollision(Coll const& collision) { @@ -196,7 +190,7 @@ struct HfCorrelatorFlowCharmHadrons { /// Fill charm hadron tables /// \param candidates are the selected charm hadron candidates - template + template void fillCharmHadronTables(TCand const& candidates) { int indexRedColl = rowCollisions.lastIndex(); @@ -207,10 +201,8 @@ struct HfCorrelatorFlowCharmHadrons { double massCand = getCandMass(candidate); rowCharmCandidates(indexRedColl, candidate.phi(), candidate.eta(), candidate.pt(), massCand, candidate.prong0Id(), candidate.prong1Id(), candidate.prong2Id()); - if constexpr (applyMl) { - std::vector outputMl = getCandMlScores(candidate); - rowCharmCandidatesMl(indexRedColl, outputMl[0], outputMl[1]); - } + std::vector outputMl = getCandMlScores(candidate); + rowCharmCandidatesMl(indexRedColl, outputMl[0], outputMl[1]); } } @@ -229,27 +221,6 @@ struct HfCorrelatorFlowCharmHadrons { } } - // Dplus with rectangular cuts - void processDplus(CollsWithCentMult const& colls, - CandDplusData const& candsDplus, - TracksData const& tracks) - { - for (const auto& coll : colls) { - auto thisCollId = coll.globalIndex(); - auto candsCThisColl = candsDplus.sliceBy(candsDplusPerColl, thisCollId); - if (forceCharmInCollision && candsCThisColl.size() < 1) { - continue; - } - if (!checkAndFillCollision(coll)) { - continue; - } - auto trackIdsThisColl = tracks.sliceBy(trackIndicesPerColl, thisCollId); - fillCharmHadronTables(candsCThisColl); - fillTracksTables(trackIdsThisColl); - } - } - PROCESS_SWITCH(HfCorrelatorFlowCharmHadrons, processDplus, "Process Dplus candidates", true); - // Dplus with ML selections void processDplusWithMl(CollsWithCentMult const& colls, CandDplusDataWMl const& candsDplus, @@ -257,7 +228,7 @@ struct HfCorrelatorFlowCharmHadrons { { for (const auto& coll : colls) { auto thisCollId = coll.globalIndex(); - auto candsCThisColl = candsDplus.sliceBy(candsDplusPerColl, thisCollId); + auto candsCThisColl = candsDplus.sliceBy(candsDplusPerCollWMl, thisCollId); if (forceCharmInCollision && candsCThisColl.size() < 1) { continue; } @@ -265,35 +236,12 @@ struct HfCorrelatorFlowCharmHadrons { continue; } auto trackIdsThisColl = tracks.sliceBy(trackIndicesPerColl, thisCollId); - fillCharmHadronTables(candsCThisColl); + fillCharmHadronTables(candsCThisColl); fillTracksTables(trackIdsThisColl); } } PROCESS_SWITCH(HfCorrelatorFlowCharmHadrons, processDplusWithMl, "Process Dplus candidates with ML info", false); - // Ds with rectangular cuts - void processDs(CollsWithCentMult const& colls, - TracksData const& tracks, - CandDsData const&) - { - for (const auto& coll : colls) { - auto thisCollId = coll.globalIndex(); - auto candsDsToKKPi = selectedDsToKKPi->sliceByCached(aod::hf_cand::collisionId, thisCollId, cache); - auto candsDsToPiKK = selectedDsToPiKK->sliceByCached(aod::hf_cand::collisionId, thisCollId, cache); - if (forceCharmInCollision && candsDsToKKPi.size() < 1 && candsDsToPiKK.size() < 1) { - continue; - } - if (!checkAndFillCollision(coll)) { - continue; - } - auto trackIdsThisColl = tracks.sliceBy(trackIndicesPerColl, thisCollId); - fillCharmHadronTables(candsDsToPiKK); - fillCharmHadronTables(candsDsToKKPi); - fillTracksTables(trackIdsThisColl); - } - } - PROCESS_SWITCH(HfCorrelatorFlowCharmHadrons, processDs, "Process Ds candidates", false); - // Ds with ML selections void processDsWithMl(CollsWithCentMult const& colls, TracksData const& tracks, @@ -310,8 +258,8 @@ struct HfCorrelatorFlowCharmHadrons { continue; } auto trackIdsThisColl = tracks.sliceBy(trackIndicesPerColl, thisCollId); - fillCharmHadronTables(candsDsToPiKKWMl); - fillCharmHadronTables(candsDsToKKPiWMl); + fillCharmHadronTables(candsDsToPiKKWMl); + fillCharmHadronTables(candsDsToKKPiWMl); fillTracksTables(trackIdsThisColl); } } From 242fe37dcdc19b57a2c068e807444a2e7f318333 Mon Sep 17 00:00:00 2001 From: marcellocosti Date: Thu, 28 Aug 2025 18:06:38 +0200 Subject: [PATCH 5/5] Remove signed track pt --- PWGHF/HFC/TableProducer/correlatorFlowCharmHadrons.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PWGHF/HFC/TableProducer/correlatorFlowCharmHadrons.cxx b/PWGHF/HFC/TableProducer/correlatorFlowCharmHadrons.cxx index f9585c58085..ec5f2a40c19 100644 --- a/PWGHF/HFC/TableProducer/correlatorFlowCharmHadrons.cxx +++ b/PWGHF/HFC/TableProducer/correlatorFlowCharmHadrons.cxx @@ -216,7 +216,7 @@ struct HfCorrelatorFlowCharmHadrons { if (!track.isGlobalTrackWoDCA()) { continue; } - rowAssocTrackReduced(indexRedColl, track.globalIndex(), track.phi(), track.eta(), track.pt() * track.sign()); + rowAssocTrackReduced(indexRedColl, track.globalIndex(), track.phi(), track.eta(), track.pt()); rowAssocTrackSelInfo(indexRedColl, track.tpcNClsCrossedRows(), track.itsClusterMap(), track.itsNCls(), track.dcaXY(), track.dcaZ()); } }