diff --git a/PWGHF/HFC/DataModel/DerivedDataCorrelationTables.h b/PWGHF/HFC/DataModel/DerivedDataCorrelationTables.h index 4565189a5ab..40274d89cef 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(InvMassCand, invMassCand, float); //! Invariant mass of Charm candidate +DECLARE_SOA_COLUMN(BdtScorePrompt, bdtScorePrompt, float); //! BDT output score for prompt hypothesis +DECLARE_SOA_COLUMN(BdtScoreBkg, bdtScoreBkg, float); //! BDT output score for background 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<>, @@ -81,23 +81,13 @@ DECLARE_SOA_TABLE(DsCandSelInfos, "AOD", "DSCANDSELINFO", //! Table with Ds cand aod::hf_candidate_reduced::BdtScorePrompt, aod::hf_candidate_reduced::BdtScoreBkg); -DECLARE_SOA_TABLE(HfcRedCharmHads2P, "AOD", "HFCREDCHARM2P", //! Table with 2-prong charm hadron candidate info +DECLARE_SOA_TABLE(HfcRedCharmTrigs, "AOD", "HFCREDCHARMTRIG", //! 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); - -DECLARE_SOA_TABLE(HfcRedCharmHads3P, "AOD", "HFCREDCHARM3P", //! Table with 3-prong 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::InvMassCand, aod::hf_candidate_reduced::Prong0Id, aod::hf_candidate_reduced::Prong1Id, aod::hf_candidate_reduced::Prong2Id); @@ -137,7 +127,7 @@ DECLARE_SOA_TABLE(AssocTrackSels, "AOD", "ASSOCTRACKSEL", //! Table with associa aod::hf_assoc_track_reduced::DcaXY, aod::hf_assoc_track_reduced::DcaZ) -DECLARE_SOA_TABLE(HfcRedTrkAssoc, "AOD", "HFCREDTRKASSOC", //! Table with associated track info +DECLARE_SOA_TABLE(HfcRedTrkAssocs, "AOD", "HFCREDTRKASSOC", //! Table with associated track info soa::Index<>, aod::hf_candidate_reduced::HfcRedFlowCollId, aod::hf_assoc_track_reduced::OriginTrackId, @@ -145,7 +135,7 @@ DECLARE_SOA_TABLE(HfcRedTrkAssoc, "AOD", "HFCREDTRKASSOC", //! Table with associ aod::hf_assoc_track_reduced::EtaAssocTrack, aod::hf_assoc_track_reduced::PtAssocTrack); -DECLARE_SOA_TABLE(HfcRedTrkSels, "AOD", "HFCREDTRKSELS", //! Table with associated track info +DECLARE_SOA_TABLE(HfcRedTrkSels, "AOD", "HFCREDTRKSEL", //! Table with associated track info soa::Index<>, aod::hf_candidate_reduced::HfcRedFlowCollId, aod::hf_assoc_track_reduced::NTpcCrossedRows, @@ -153,6 +143,32 @@ DECLARE_SOA_TABLE(HfcRedTrkSels, "AOD", "HFCREDTRKSELS", //! Table with associat aod::hf_assoc_track_reduced::ItsNCls, aod::hf_assoc_track_reduced::DcaXY, aod::hf_assoc_track_reduced::DcaZ) + +// definition of columns and tables for Charm-Hadron and Hadron-Hadron correlation pairs +namespace hf_correlation_charm_hadron_reduced +{ +DECLARE_SOA_INDEX_COLUMN_FULL(CharmTrig, charmTrig, int, HfcRedCharmTrigs, "_0"); //! Reduced charm trigger candidate index +DECLARE_SOA_INDEX_COLUMN_FULL(HadTrig, hadTrig, int, HfcRedTrkAssocs, "_1"); //! Reduced hadron trigger candidate index +DECLARE_SOA_INDEX_COLUMN_FULL(TrkAssoc, trkAssoc, int, HfcRedTrkAssocs, "_2"); //! Reduced associated track index +DECLARE_SOA_COLUMN(DeltaPhi, deltaPhi, float); //! DeltaPhi between charm hadron and Hadrons +DECLARE_SOA_COLUMN(DeltaEta, deltaEta, float); //! DeltaEta between charm hadron and Hadrons +DECLARE_SOA_COLUMN(PoolBin, poolBin, int); //! Pool Bin for the MixedEvent +} // namespace hf_correlation_charm_hadron_reduced + +DECLARE_SOA_TABLE(HfcRedChHads, "AOD", "HFCREDCHHAD", //! Charm-Hadron pairs information + aod::hf_correlation_charm_hadron_reduced::CharmTrigId, + aod::hf_correlation_charm_hadron_reduced::TrkAssocId, + aod::hf_correlation_charm_hadron_reduced::DeltaEta, + aod::hf_correlation_charm_hadron_reduced::DeltaPhi, + aod::hf_correlation_charm_hadron_reduced::PoolBin); + +DECLARE_SOA_TABLE(HfcRedHadHads, "AOD", "HFCREDHADHAD", //! Hadron-Hadron pairs information + aod::hf_correlation_charm_hadron_reduced::HadTrigId, + aod::hf_correlation_charm_hadron_reduced::TrkAssocId, + aod::hf_correlation_charm_hadron_reduced::DeltaEta, + aod::hf_correlation_charm_hadron_reduced::DeltaPhi, + aod::hf_correlation_charm_hadron_reduced::PoolBin); + } // namespace o2::aod #endif // PWGHF_HFC_DATAMODEL_DERIVEDDATACORRELATIONTABLES_H_ diff --git a/PWGHF/HFC/TableProducer/CMakeLists.txt b/PWGHF/HFC/TableProducer/CMakeLists.txt index eff0f6557b3..28022d68247 100644 --- a/PWGHF/HFC/TableProducer/CMakeLists.txt +++ b/PWGHF/HFC/TableProducer/CMakeLists.txt @@ -44,11 +44,16 @@ 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 +o2physics_add_dpl_workflow(derived-data-creator-correlations-reduced + SOURCES derivedDataCreatorCorrelationsReduced.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2Physics::EventFilteringUtils COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(correlator-flow-charm-hadrons-reduced + SOURCES correlatorFlowCharmHadronsReduced.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + 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/correlatorFlowCharmHadronsReduced.cxx b/PWGHF/HFC/TableProducer/correlatorFlowCharmHadronsReduced.cxx new file mode 100644 index 00000000000..e1d1662924e --- /dev/null +++ b/PWGHF/HFC/TableProducer/correlatorFlowCharmHadronsReduced.cxx @@ -0,0 +1,470 @@ +// 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 correlatorFlowCharmHadronsReduced.cxx +/// \brief CharmHadrons-Hadrons correlator tree creator for data analyses +/// \author Marcello Di Costanzo , Politecnico and INFN Torino + +#include "PWGHF/Core/HfHelper.h" +#include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/DataModel/CandidateSelectionTables.h" +#include "PWGHF/HFC/DataModel/DerivedDataCorrelationTables.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 BinningTypeDerivedCent = ColumnBinningPolicy; +using BinningTypeDerivedMult = ColumnBinningPolicy; + +struct HfCorrelatorFlowCharmHadronsReduced { + Produces entryCharmHadPair; + Produces entryHadHadPair; + + 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{1., 3., 5., 8., 16., 36.}, "pT bin limits for trigger candidates"}; + Configurable> binsPtAssoc{"binsPtAssoc", std::vector{0.3, 1., 2., 50.}, "pT bin limits for associated particles"}; + Configurable deltaEtaAbsMin{"deltaEtaAbsMin", 0.5, "min. pair delta eta"}; + Configurable deltaEtaAbsMax{"deltaEtaAbsMax", 2., "max. pair delta eta"}; + Configurable dcaXYTrackMax{"dcaXYTrackMax", 1., "max. track DCA XY"}; + Configurable dcaZTrackMax{"dcaZTrackMax", 1., "max. track DCA Z"}; + Configurable tpcCrossedRowsMin{"tpcCrossedRowsMin", 1, "min. TPC crossed rows"}; + Configurable itsNClsMin{"itsNClsMin", 1, "min. ITS clusters"}; + + SliceCache cache; + + using AssocTracks = soa::Filtered>; + + Filter filterSelectTrackData = (nabs(aod::hf_assoc_track_reduced::dcaXY) < dcaXYTrackMax) && (nabs(aod::hf_assoc_track_reduced::dcaZ) < dcaZTrackMax) && (aod::hf_assoc_track_reduced::nTpcCrossedRows > tpcCrossedRowsMin) && (aod::hf_assoc_track_reduced::itsNCls > itsNClsMin); + + Preslice tracksPerCol = aod::hf_candidate_reduced::hfcRedFlowCollId; + Preslice candsPerCol = aod::hf_candidate_reduced::hfcRedFlowCollId; + + 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.}, "Event centrality pools"}; + ConfigurableAxis binsInvMass{"binsInvMass", {300, 1.6, 2.2}, ""}; + ConfigurableAxis binsMultFT0M{"binsMultFT0M", {100, 0., 10000.}, "Multiplicity as FT0M signal amplitude"}; + 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 binsPoolBin{"binsPoolBin", {9, 0., 9.}, "PoolBin"}; + ConfigurableAxis binsMlOne{"binsMlOne", {100, 0., 1.}, ""}; + ConfigurableAxis binsMlTwo{"binsMlTwo", {100, 0., 1.}, ""}; + + HistogramRegistry registry{"registry", {}, OutputObjHandlingPolicy::AnalysisObject}; + + void init(InitContext&) + { + std::array doprocess{doprocessSameEventCharmHadWCentMix, doprocessSameEventCharmHadWMultMix, doprocessMixedEventCharmHadWCentMix, doprocessMixedEventCharmHadWMultMix, + doprocessSameEventHadHadWCentMix, doprocessSameEventHadHadWMultMix, doprocessMixedEventHadHadWCentMix, doprocessMixedEventHadHadWMultMix}; + if ((std::accumulate(doprocess.begin(), doprocess.end(), 0)) > 1) { + LOGP(fatal, "Only one process function should be enabled! Please check your configuration!"); + if (!((doprocessSameEventCharmHadWCentMix && doprocessMixedEventCharmHadWCentMix) || (doprocessSameEventCharmHadWMultMix && doprocessMixedEventCharmHadWMultMix))) { + LOG(fatal) << "Different binning policies between Same Event and Mixed Event"; + } + if (!((doprocessSameEventHadHadWCentMix && doprocessMixedEventHadHadWCentMix) || (doprocessSameEventHadHadWMultMix && doprocessMixedEventHadHadWMultMix))) { + LOG(fatal) << "Different binning policies between Same Event and Mixed Event"; + } + } + + const AxisSpec axisInvMass{binsInvMass, "Inv. mass (GeV/#it{c}^{2})"}; + const AxisSpec axisCent = {binsCent, "Centrality"}; + const AxisSpec axisMultFT0M = {binsMultFT0M, "MultiplicityFT0M"}; + const AxisSpec axisPosZ = {binsPosZ, "PosZ"}; + const AxisSpec axisPoolBin = {binsPoolBin, "PoolBin"}; + const AxisSpec axisEta = {binsEta, "#it{#eta}"}; + const AxisSpec axisPhi = {binsPhi, "#it{#varphi}"}; + 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 axisMlOne{binsMlOne, "bdtScore0"}; + const AxisSpec axisMlTwo{binsMlTwo, "bdtScore1"}; + + // Histograms for data analysis + if (doprocessSameEventCharmHadWCentMix || doprocessMixedEventCharmHadWCentMix || doprocessSameEventHadHadWCentMix || doprocessMixedEventHadHadWCentMix) { + registry.add("hCent", "Centrality", {HistType::kTH2F, {{axisCent}, {axisPoolBin}}}); + } else { + registry.add("hMultFT0M", "Multiplicity FT0M", {HistType::kTH2F, {{axisMultFT0M}, {axisPoolBin}}}); + } + registry.add("hZVtx", "z vertex", {HistType::kTH2F, {{axisPosZ}, {axisPoolBin}}}); + registry.add("hCollisionPoolBin", "Collision pool bin", {HistType::kTH1F, {axisPoolBin}}); + registry.add("hPoolBinTrig", "Trigger candidates pool bin", {HistType::kTH1F, {axisPoolBin}}); + registry.add("hPhiVsPtTrig", "Trigger candidates phiVsPt", {HistType::kTH2F, {{axisPhi}, {axisPtTrig}}}); + registry.add("hEtaVsPtTrig", "Trigger candidates etaVsPt", {HistType::kTH2F, {{axisEta}, {axisPtTrig}}}); + registry.add("hPoolBinAssoc", "Associated particles pool bin", {HistType::kTH1F, {axisPoolBin}}); + registry.add("hPhiVsPtAssoc", "Associated particles phiVsPt", {HistType::kTH3F, {{axisPhi}, {axisPtTrig}, {axisPtAssoc}}}); + registry.add("hEtaVsPtAssoc", "Associated particles etaVsPt", {HistType::kTH3F, {{axisEta}, {axisPtTrig}, {axisPtAssoc}}}); + + if (fillSparses) { + std::vector axes = {axisPtTrig, axisPtAssoc, axisDeltaEta, axisDeltaPhi, axisPoolBin}; + 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(), {axisMlOne, axisMlTwo, axisInvMass}); + if (doprocessSameEventCharmHadWCentMix || doprocessSameEventCharmHadWMultMix) { + registry.add("hSparseCorrelationsSECharmHad", "THn for SE Charm-Had correlations", HistType::kTHnSparseF, axes); + } else if (doprocessMixedEventCharmHadWCentMix || doprocessMixedEventCharmHadWMultMix) { + registry.add("hSparseCorrelationsMECharmHad", "THn for ME Charm-Had correlations", HistType::kTHnSparseF, axes); + } + } + } + } + + /// Get charm candidate or hadron track pT + /// \param track is the candidate + template + double getPt(const TTrack& track) + { + if constexpr (requires { track.ptAssocTrack(); }) { + return track.ptAssocTrack(); + } else { + return track.ptCand(); + } + } + + /// Get charm candidate or hadron track eta + /// \param track is the candidate + template + double getEta(const TTrack& track) + { + if constexpr (requires { track.etaAssocTrack(); }) { + return track.etaAssocTrack(); + } else { + return track.etaCand(); + } + } + + /// Get charm candidate or hadron track phi + /// \param track is the candidate + template + double getPhi(const TTrack& track) + { + if constexpr (requires { track.phiAssocTrack(); }) { + return track.phiAssocTrack(); + } else { + return track.phiCand(); + } + } + + /// Get the binning pool associated to the collision + /// \param collision is the collision + /// \param corrBinning is the binning policy for the correlation + template + int getPoolBin(const TColl& collision, const TBinningType& corrBinning) + { + int poolBin{0}; + if constexpr (std::is_same_v) { + poolBin = corrBinning.getBin(std::make_tuple(collision.posZ(), collision.centrality())); + if constexpr (fillHistos) { + registry.fill(HIST("hCent"), collision.centrality(), poolBin); + } + } else if constexpr (std::is_same_v) { + poolBin = corrBinning.getBin(std::make_tuple(collision.posZ(), collision.multiplicity())); + if constexpr (fillHistos) { + registry.fill(HIST("hMultFT0M"), collision.multiplicity(), poolBin); + } + } + return poolBin; + } + + /// Reject daughter-track pairs and same-track pairs + /// \param cand is the trigger candidate + /// \param track is the associated track + template + bool rejSameEvtPair(const TTrigPart& cand, const TTrack& track) + { + if constexpr (requires { cand.originTrackId(); }) { + // Remove same track pairs for Had-Had correlations + return (cand.originTrackId() == track.originTrackId()); + } else { + // Remove pairs with 2- and 3-prong daughters (prong2Id returns -1 for 2-prongs) + return ((cand.prong0Id() == track.originTrackId()) || (cand.prong1Id() == track.originTrackId()) || (cand.prong2Id() == track.originTrackId())); + } + } + + /// Slice trigger candidates by collision + /// \param cands are the trigger candidates + /// \param collId is the collision index + template + auto sliceTrigCands(TTrigCands const& cands, const int collId) + { + if constexpr (std::is_same_v) { + return cands.sliceBy(tracksPerCol, collId); + } else { + return cands.sliceBy(candsPerCol, collId); + } + } + + /// Fill Charm-Hadron correlation table and sparse + /// \param trigCand is the trigger charm hadron candidate + /// \param assocTrack is the associated hadron track + /// \param poolBin is the pool bin of the collision + template + void fillCharmHadInfo(TTrigCand const& trigCand, + TTrack const& assocTrack, + const int poolBin) + { + double deltaEta = getEta(assocTrack) - getEta(trigCand); + double deltaPhi = RecoDecay::constrainAngle(getPhi(assocTrack) - getPhi(trigCand), -o2::constants::math::PIHalf); + if (fillTables) { + entryCharmHadPair(trigCand.globalIndex(), assocTrack.globalIndex(), deltaEta, deltaPhi, poolBin); + } + if (fillSparses) { + if constexpr (isMixedEvent) { + registry.fill(HIST("hSparseCorrelationsMECharmHad"), getPt(trigCand), getPt(assocTrack), + deltaEta, deltaPhi, poolBin, trigCand.bdtScore0(), + trigCand.bdtScore1(), trigCand.invMassCand()); + } else { + registry.fill(HIST("hSparseCorrelationsSECharmHad"), getPt(trigCand), getPt(assocTrack), + deltaEta, deltaPhi, poolBin, trigCand.bdtScore0(), + trigCand.bdtScore1(), trigCand.invMassCand()); + } + } + } + + /// Fill Hadron-Hadron correlation table and sparse + /// \param trigCand is the trigger hadron candidate + /// \param assocTrack is the associated hadron track + /// \param poolBin is the pool bin of the collision + template + void fillHadHadInfo(TCand const& trigCand, + TCand const& assocTrack, + const int poolBin) + { + double deltaEta = getEta(assocTrack) - getEta(trigCand); + double deltaPhi = RecoDecay::constrainAngle(getPhi(assocTrack) - getPhi(trigCand), -o2::constants::math::PIHalf); + if (fillTables) { + entryHadHadPair(trigCand.globalIndex(), assocTrack.globalIndex(), deltaEta, deltaPhi, poolBin); + } + if (fillSparses) { + if constexpr (isMixedEvent) { + registry.fill(HIST("hSparseCorrelationsMEHadHad"), getPt(trigCand), getPt(assocTrack), deltaEta, deltaPhi, poolBin); + } else { + registry.fill(HIST("hSparseCorrelationsSEHadHad"), getPt(trigCand), getPt(assocTrack), deltaEta, deltaPhi, poolBin); + } + } + } + + /// Save info for Same Event pairs + /// \param collisions are the selected collisions + /// \param trigCands are the selected trigger candidates + /// \param assocTracks are the selected associated tracks + /// \param corrBinning is the binning policy for the correlation + template + void fillSameEvent(aod::HfcRedFlowColls const& collisions, + TTrigCands const& trigCands, + TAssocTracks const& assocTracks, + TBinningType corrBinning) + { + for (const auto& collision : collisions) { + int poolBin = getPoolBin(collision, corrBinning); + registry.fill(HIST("hCollisionPoolBin"), poolBin); + registry.fill(HIST("hZVtx"), collision.posZ(), poolBin); + + auto thisCollId = collision.globalIndex(); + auto trigCandsThisColl = sliceTrigCands(trigCands, thisCollId); + auto assocTracksThisColl = assocTracks.sliceBy(tracksPerCol, thisCollId); + + for (const auto& trigCand : trigCandsThisColl) { + registry.fill(HIST("hPoolBinTrig"), poolBin); + registry.fill(HIST("hPhiVsPtTrig"), RecoDecay::constrainAngle(getPhi(trigCand), -o2::constants::math::PIHalf), getPt(trigCand)); + registry.fill(HIST("hEtaVsPtTrig"), getEta(trigCand), getPt(trigCand)); + for (const auto& assocTrack : assocTracksThisColl) { + if (rejSameEvtPair(trigCand, assocTrack)) { + continue; + } + double deltaEta = getEta(assocTrack) - getEta(trigCand); + if (std::abs(deltaEta) < deltaEtaAbsMin || std::abs(deltaEta) > deltaEtaAbsMax) { + continue; + } + registry.fill(HIST("hPoolBinAssoc"), poolBin); + registry.fill(HIST("hPhiVsPtAssoc"), RecoDecay::constrainAngle(getPhi(assocTrack), -o2::constants::math::PIHalf), getPt(trigCand), getPt(assocTrack)); + registry.fill(HIST("hEtaVsPtAssoc"), getEta(assocTrack), getPt(trigCand), getPt(assocTrack)); + + if constexpr (std::is_same_v) { + fillHadHadInfo(trigCand, assocTrack, poolBin); + } else { + fillCharmHadInfo(trigCand, assocTrack, poolBin); + } + } + } + } + } + + /// Save info for Mixed Event pairs + /// \param collisions are the selected collisions + /// \param trigCands are the selected trigger candidates + /// \param assocTracks are the selected associated tracks + /// \param corrBinning is the binning policy for the correlation + template + void fillMixedEvent(aod::HfcRedFlowColls const& collisions, + TTrigCands const& trigCands, + TAssocTracks const& assocTracks, + TBinningType corrBinning) + { + for (const auto& collision : collisions) { + int poolBin = getPoolBin(collision, corrBinning); + registry.fill(HIST("hCollisionPoolBin"), poolBin); + registry.fill(HIST("hZVtx"), collision.posZ(), poolBin); + + auto thisCollId = collision.globalIndex(); + auto trigCandsThisColl = sliceTrigCands(trigCands, thisCollId); + auto assocTracksThisColl = assocTracks.sliceBy(tracksPerCol, thisCollId); + for (const auto& trigCand : trigCandsThisColl) { + registry.fill(HIST("hPoolBinTrig"), poolBin); + registry.fill(HIST("hPhiVsPtTrig"), RecoDecay::constrainAngle(getPhi(trigCand), -o2::constants::math::PIHalf), getPt(trigCand)); + registry.fill(HIST("hEtaVsPtTrig"), getEta(trigCand), getPt(trigCand)); + for (const auto& assocTrack : assocTracksThisColl) { + registry.fill(HIST("hPoolBinAssoc"), poolBin); + registry.fill(HIST("hPhiVsPtAssoc"), RecoDecay::constrainAngle(getPhi(assocTrack), -o2::constants::math::PIHalf), getPt(trigCand), getPt(assocTrack)); + registry.fill(HIST("hEtaVsPtAssoc"), getEta(assocTrack), getPt(trigCand), getPt(assocTrack)); + } + } + } + + auto pairsTuple = std::make_tuple(trigCands, assocTracks); + Pair pairData{corrBinning, numberEventsMixed, -1, collisions, pairsTuple, &cache}; + + for (const auto& [trigColl, trigCands, assocColl, assocTracks] : pairData) { + if (trigCands.size() == 0 || assocTracks.size() == 0) { + continue; + } + int poolBinCharm = getPoolBin(trigColl, corrBinning); + int poolBinAssoc = getPoolBin(assocColl, corrBinning); + if (poolBinAssoc != poolBinCharm) { + LOGF(info, "Error, poolBins are different"); + continue; + } + + for (const auto& [trigCand, assocTrack] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(trigCands, assocTracks))) { + double deltaEta = getEta(assocTrack) - getEta(trigCand); + if (std::abs(deltaEta) < deltaEtaAbsMin || std::abs(deltaEta) > deltaEtaAbsMax) { + continue; + } + // LOGF(info, "Mixed event tracks pair: (%d, %d) from events (%d, %d), track event: (%d, %d)", trigCand.index(), assocTrack.index(), trigColl.index(), assocColl.index(), trigCand.hfcRedFlowCollId(), assocTrack.hfcRedFlowCollId()); + if constexpr (std::is_same_v) { + fillHadHadInfo(trigCand, assocTrack, poolBinCharm); + } else { + fillCharmHadInfo(trigCand, assocTrack, poolBinCharm); + } + } + } + } + + void processSameEventCharmHadWCentMix(aod::HfcRedFlowColls const& collisions, + soa::Join const& candidates, + AssocTracks const& tracks) + { + ColumnBinningPolicy corrBinningCent{{zPoolBins, centPoolBins}, true}; + fillSameEvent(collisions, candidates, tracks, corrBinningCent); + } + PROCESS_SWITCH(HfCorrelatorFlowCharmHadronsReduced, processSameEventCharmHadWCentMix, "Process Same Event for Charm-Had with centrality pools", true); + + void processSameEventCharmHadWMultMix(aod::HfcRedFlowColls const& collisions, + soa::Join const& candidates, + AssocTracks const& tracks) + { + ColumnBinningPolicy corrBinningMult{{zPoolBins, multPoolBins}, true}; + fillSameEvent(collisions, candidates, tracks, corrBinningMult); + } + PROCESS_SWITCH(HfCorrelatorFlowCharmHadronsReduced, processSameEventCharmHadWMultMix, "Process Same Event for Charm-Had with multiplicity pools", false); + + void processMixedEventCharmHadWCentMix(aod::HfcRedFlowColls const& collisions, + soa::Join const& candidates, + AssocTracks const& tracks) + { + ColumnBinningPolicy corrBinningCent{{zPoolBins, centPoolBins}, true}; + fillMixedEvent(collisions, candidates, tracks, corrBinningCent); + } + PROCESS_SWITCH(HfCorrelatorFlowCharmHadronsReduced, processMixedEventCharmHadWCentMix, "Process Mixed Event for Charm-Had with centrality pools", false); + + void processMixedEventCharmHadWMultMix(aod::HfcRedFlowColls const& collisions, + soa::Join const& candidates, + AssocTracks const& tracks) + { + ColumnBinningPolicy corrBinningMult{{zPoolBins, multPoolBins}, true}; + fillMixedEvent(collisions, candidates, tracks, corrBinningMult); + } + PROCESS_SWITCH(HfCorrelatorFlowCharmHadronsReduced, processMixedEventCharmHadWMultMix, "Process Mixed Event for Charm-Had with multiplicity pools", false); + + void processSameEventHadHadWCentMix(aod::HfcRedFlowColls const& collisions, + AssocTracks const& tracks) + { + ColumnBinningPolicy corrBinningCent{{zPoolBins, centPoolBins}, true}; + fillSameEvent(collisions, tracks, tracks, corrBinningCent); + } + PROCESS_SWITCH(HfCorrelatorFlowCharmHadronsReduced, processSameEventHadHadWCentMix, "Process Same Event for Had-Had with centrality pools", false); + + void processSameEventHadHadWMultMix(aod::HfcRedFlowColls const& collisions, + AssocTracks const& tracks) + { + ColumnBinningPolicy corrBinningMult{{zPoolBins, multPoolBins}, true}; + fillSameEvent(collisions, tracks, tracks, corrBinningMult); + } + PROCESS_SWITCH(HfCorrelatorFlowCharmHadronsReduced, processSameEventHadHadWMultMix, "Process Same Event for Had-Had with multiplicity pools", false); + + void processMixedEventHadHadWCentMix(aod::HfcRedFlowColls const& collisions, + AssocTracks const& tracks) + { + ColumnBinningPolicy corrBinningCent{{zPoolBins, centPoolBins}, true}; + fillMixedEvent(collisions, tracks, tracks, corrBinningCent); + } + PROCESS_SWITCH(HfCorrelatorFlowCharmHadronsReduced, processMixedEventHadHadWCentMix, "Process Mixed Event for Had-Had with centrality pools", false); + + void processMixedEventHadHadWMultMix(aod::HfcRedFlowColls const& collisions, + AssocTracks const& tracks) + { + ColumnBinningPolicy corrBinningMult{{zPoolBins, multPoolBins}, true}; + fillMixedEvent(collisions, tracks, tracks, corrBinningMult); + } + PROCESS_SWITCH(HfCorrelatorFlowCharmHadronsReduced, processMixedEventHadHadWMultMix, "Process Mixed Event for Had-Had with multiplicity pools", false); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{adaptAnalysisTask(cfgc)}; +} diff --git a/PWGHF/HFC/TableProducer/correlatorFlowCharmHadrons.cxx b/PWGHF/HFC/TableProducer/derivedDataCreatorCorrelationsReduced.cxx similarity index 93% rename from PWGHF/HFC/TableProducer/correlatorFlowCharmHadrons.cxx rename to PWGHF/HFC/TableProducer/derivedDataCreatorCorrelationsReduced.cxx index f4dd7761455..e5bb19f2e9e 100644 --- a/PWGHF/HFC/TableProducer/correlatorFlowCharmHadrons.cxx +++ b/PWGHF/HFC/TableProducer/derivedDataCreatorCorrelationsReduced.cxx @@ -9,7 +9,7 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -/// \file correlatorFlowCharmHadrons.cxx +/// \file derivedDataCreatorCorrelationsReduced.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 @@ -60,12 +60,11 @@ enum DecayChannel { }; /// Code to select collisions with at least one Ds meson -struct HfCorrelatorFlowCharmHadrons { +struct HfDerivedDataCreatorCorrelationsReduced { Produces rowCollisions; - Produces rowCharmCandidates2P; - Produces rowCharmCandidates3P; + Produces rowCharmCandidates; Produces rowCharmCandidatesMl; - Produces rowAssocTrackReduced; + Produces rowAssocTrackReduced; Produces rowAssocTrackSelInfo; Configurable centEstimator{"centEstimator", 2, "Centrality estimation (FT0A: 1, FT0C: 2, FT0M: 3, FV0A: 4)"}; @@ -231,9 +230,9 @@ struct HfCorrelatorFlowCharmHadrons { } double massCand = getCandMass(candidate); if constexpr (channel == DecayChannel::D0ToKPi || channel == DecayChannel::D0ToPiK) { - rowCharmCandidates2P(indexRedColl, candidate.phi(), candidate.eta(), candidate.pt(), massCand, candidate.prong0Id(), candidate.prong1Id()); + rowCharmCandidates(indexRedColl, candidate.phi(), candidate.eta(), candidate.pt(), massCand, candidate.prong0Id(), candidate.prong1Id(), -1); } else { - rowCharmCandidates3P(indexRedColl, candidate.phi(), candidate.eta(), candidate.pt(), massCand, candidate.prong0Id(), candidate.prong1Id(), candidate.prong2Id()); + rowCharmCandidates(indexRedColl, candidate.phi(), candidate.eta(), candidate.pt(), massCand, candidate.prong0Id(), candidate.prong1Id(), candidate.prong2Id()); } std::vector outputMl = getCandMlScores(candidate); rowCharmCandidatesMl(indexRedColl, outputMl[0], outputMl[1]); @@ -274,7 +273,7 @@ struct HfCorrelatorFlowCharmHadrons { fillTracksTables(trackIdsThisColl); } } - PROCESS_SWITCH(HfCorrelatorFlowCharmHadrons, processDplusWithMl, "Process Dplus candidates with ML info", false); + PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processDplusWithMl, "Process Dplus candidates with ML info", false); // Ds with ML selections void processDsWithMl(CollsWithCentMult const& colls, @@ -297,7 +296,7 @@ struct HfCorrelatorFlowCharmHadrons { fillTracksTables(trackIdsThisColl); } } - PROCESS_SWITCH(HfCorrelatorFlowCharmHadrons, processDsWithMl, "Process Ds candidates with ML info", false); + PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processDsWithMl, "Process Ds candidates with ML info", false); // D0 with ML selections void processD0WithMl(CollsWithCentMult const& colls, @@ -320,10 +319,10 @@ struct HfCorrelatorFlowCharmHadrons { fillTracksTables(trackIdsThisColl); } } - PROCESS_SWITCH(HfCorrelatorFlowCharmHadrons, processD0WithMl, "Process D0 candidates with ML info", false); + PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processD0WithMl, "Process D0 candidates with ML info", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { - return WorkflowSpec{adaptAnalysisTask(cfgc)}; + return WorkflowSpec{adaptAnalysisTask(cfgc)}; }