diff --git a/PWGHF/HFC/DataModel/DerivedDataCorrelationTables.h b/PWGHF/HFC/DataModel/DerivedDataCorrelationTables.h index 40274d89cef..b0a9cf3e390 100644 --- a/PWGHF/HFC/DataModel/DerivedDataCorrelationTables.h +++ b/PWGHF/HFC/DataModel/DerivedDataCorrelationTables.h @@ -35,7 +35,7 @@ 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 +DECLARE_SOA_TABLE(HfcRedCorrColls, "AOD", "HFCREDCORRCOLL", //! Table with collision info soa::Index<>, aod::hf_collisions_reduced::Multiplicity, aod::hf_collisions_reduced::NumPvContrib, @@ -44,13 +44,9 @@ DECLARE_SOA_TABLE(HfcRedFlowColls, "AOD", "HFCREDFLOWCOLL", //! Table with colli using HfcRedCollision = HfcRedCollisions::iterator; -// DECLARE_SOA_TABLE(HfCandColCounts, "AOD", "HFCANDCOLCOUNT", //! Table with number of collisions which contain at least one candidate -// aod::hf_collisions_reduced::OriginalCollisionCount); - 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 @@ -58,11 +54,8 @@ DECLARE_SOA_COLUMN(PhiCand, phiCand, float); //! Phi of the candi 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 +74,6 @@ DECLARE_SOA_TABLE(DsCandSelInfos, "AOD", "DSCANDSELINFO", //! Table with Ds cand aod::hf_candidate_reduced::BdtScorePrompt, aod::hf_candidate_reduced::BdtScoreBkg); -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::InvMassCand, - 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 @@ -125,50 +101,154 @@ DECLARE_SOA_TABLE(AssocTrackSels, "AOD", "ASSOCTRACKSEL", //! Table with associa aod::hf_assoc_track_reduced::ItsClusterMap, aod::hf_assoc_track_reduced::ItsNCls, aod::hf_assoc_track_reduced::DcaXY, - aod::hf_assoc_track_reduced::DcaZ) - -DECLARE_SOA_TABLE(HfcRedTrkAssocs, "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", "HFCREDTRKSEL", //! 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) + 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 +namespace hf_correl_charm_had_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); - +// Correlation columns +DECLARE_SOA_INDEX_COLUMN(HfcRedCorrColl, hfcRedCorrColl); //! ReducedCollision 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 +// General trigger particle columns +DECLARE_SOA_COLUMN(PhiTrig, phiTrig, float); //! Phi of the trigger candidate +DECLARE_SOA_COLUMN(EtaTrig, etaTrig, float); //! Eta of the trigger candidate +DECLARE_SOA_COLUMN(PtTrig, ptTrig, float); //! Pt of the trigger candidate +// Charm trigger particle selection columns +DECLARE_SOA_COLUMN(InvMassTrig, invMassTrig, float); //! Invariant mass of Charm trigger candidate +DECLARE_SOA_COLUMN(BdtScore0Trig, bdtScore0Trig, float); //! First BDT output score +DECLARE_SOA_COLUMN(BdtScore1Trig, bdtScore1Trig, float); //! Second BDT output score +// Hadron trigger particle selection columns +DECLARE_SOA_COLUMN(NTpcCrossedRowsTrig, nTpcCrossedRowsTrig, int); //! Number of crossed TPC Rows +DECLARE_SOA_COLUMN(ItsClsMapTrig, itsClsMapTrig, int); //! ITS cluster map, one bit per a layer, starting from the innermost +DECLARE_SOA_COLUMN(ItsNClsTrig, itsNClsTrig, int); //! Number of ITS clusters +DECLARE_SOA_COLUMN(DcaXYTrig, dcaXYTrig, float); //! Impact parameter in XY of the track to the primary vertex +DECLARE_SOA_COLUMN(DcaZTrig, dcaZTrig, float); //! Impact parameter in Z of the track to the primary vertex +// General associated particle columns +DECLARE_SOA_COLUMN(EtaAssoc, etaAssoc, float); //! Eta of the associated candidate +DECLARE_SOA_COLUMN(PhiAssoc, phiAssoc, float); //! Phi of the associated candidate +DECLARE_SOA_COLUMN(PtAssoc, ptAssoc, float); //! Pt of the associated candidate +// Hadron associated particle selection columns +DECLARE_SOA_COLUMN(NTpcCrossedRowsAssoc, nTpcCrossedRowsAssoc, int); //! Number of crossed TPC Rows +DECLARE_SOA_COLUMN(ItsClsMapAssoc, itsClsMapAssoc, int); //! ITS cluster map, one bit per a layer, starting from the innermost +DECLARE_SOA_COLUMN(ItsNClsAssoc, itsNClsAssoc, int); //! Number of ITS clusters +DECLARE_SOA_COLUMN(DcaXYAssoc, dcaXYAssoc, float); //! Impact parameter in XY of the track to the primary vertex +DECLARE_SOA_COLUMN(DcaZAssoc, dcaZAssoc, float); //! Impact parameter in Z of the track to the primary vertex +} // namespace hf_correl_charm_had_reduced + +DECLARE_SOA_TABLE(HfcRedTrigBases, "AOD", "HFCREDTRIGBASE", //! Table with trigger candidate base info + soa::Index<>, + aod::hf_correl_charm_had_reduced::HfcRedCorrCollId, + aod::hf_correl_charm_had_reduced::PhiTrig, + aod::hf_correl_charm_had_reduced::EtaTrig, + aod::hf_correl_charm_had_reduced::PtTrig); + +DECLARE_SOA_TABLE(HfcRedTrigCharms, "AOD", "HFCREDTRIGCHARM", //! Table with Same Event Charm-Hadron pairs information + aod::hf_correl_charm_had_reduced::InvMassTrig, + aod::hf_correl_charm_had_reduced::BdtScore0Trig, + aod::hf_correl_charm_had_reduced::BdtScore1Trig); + +DECLARE_SOA_TABLE(HfcRedTrigTracks, "AOD", "HFCREDTRIGTRACK", //! Table with Same Event Charm-Hadron pairs information + aod::hf_correl_charm_had_reduced::NTpcCrossedRowsTrig, + aod::hf_correl_charm_had_reduced::ItsClsMapTrig, + aod::hf_correl_charm_had_reduced::ItsNClsTrig, + aod::hf_correl_charm_had_reduced::DcaXYTrig, + aod::hf_correl_charm_had_reduced::DcaZTrig); + +DECLARE_SOA_TABLE(HfcRedAssBases, "AOD", "HFCREDASSBASE", //! Table with associated candidate base info + soa::Index<>, + aod::hf_correl_charm_had_reduced::HfcRedCorrCollId, + aod::hf_correl_charm_had_reduced::PhiAssoc, + aod::hf_correl_charm_had_reduced::EtaAssoc, + aod::hf_correl_charm_had_reduced::PtAssoc); + +DECLARE_SOA_TABLE(HfcRedAssTracks, "AOD", "HFCREDASSTRACK", //! Table with Same Event Track Selections information + aod::hf_correl_charm_had_reduced::NTpcCrossedRowsAssoc, + aod::hf_correl_charm_had_reduced::ItsClsMapAssoc, + aod::hf_correl_charm_had_reduced::ItsNClsAssoc, + aod::hf_correl_charm_had_reduced::DcaXYAssoc, + aod::hf_correl_charm_had_reduced::DcaZAssoc); + +DECLARE_SOA_TABLE(HfcRedSEBases, "AOD", "HFCREDSEBASE", //! Table with Same Event Trig-Assoc pairs + aod::hf_correl_charm_had_reduced::HfcRedCorrCollId, + aod::hf_correl_charm_had_reduced::PtTrig, + aod::hf_correl_charm_had_reduced::PtAssoc, + aod::hf_correl_charm_had_reduced::DeltaEta, + aod::hf_correl_charm_had_reduced::DeltaPhi); + +DECLARE_SOA_TABLE(HfcRedSEChHads, "AOD", "HFCREDSECHHAD", //! Correlation pairs information Same Event + aod::hf_correl_charm_had_reduced::PoolBin, + aod::hf_correl_charm_had_reduced::PtTrig, + aod::hf_correl_charm_had_reduced::PtAssoc, + aod::hf_correl_charm_had_reduced::DeltaEta, + aod::hf_correl_charm_had_reduced::DeltaPhi, + aod::hf_correl_charm_had_reduced::InvMassTrig, + aod::hf_correl_charm_had_reduced::BdtScore0Trig, + aod::hf_correl_charm_had_reduced::BdtScore1Trig, + aod::hf_correl_charm_had_reduced::NTpcCrossedRowsAssoc, + aod::hf_correl_charm_had_reduced::ItsClsMapAssoc, + aod::hf_correl_charm_had_reduced::ItsNClsAssoc, + aod::hf_correl_charm_had_reduced::DcaXYAssoc, + aod::hf_correl_charm_had_reduced::DcaZAssoc, + soa::Marker<1>); + +DECLARE_SOA_TABLE(HfcRedMEChHads, "AOD", "HFCREDMECHHAD", //! Correlation pairs information Same Event + aod::hf_correl_charm_had_reduced::PoolBin, + aod::hf_correl_charm_had_reduced::PtTrig, + aod::hf_correl_charm_had_reduced::PtAssoc, + aod::hf_correl_charm_had_reduced::DeltaEta, + aod::hf_correl_charm_had_reduced::DeltaPhi, + aod::hf_correl_charm_had_reduced::InvMassTrig, + aod::hf_correl_charm_had_reduced::BdtScore0Trig, + aod::hf_correl_charm_had_reduced::BdtScore1Trig, + aod::hf_correl_charm_had_reduced::NTpcCrossedRowsAssoc, + aod::hf_correl_charm_had_reduced::ItsClsMapAssoc, + aod::hf_correl_charm_had_reduced::ItsNClsAssoc, + aod::hf_correl_charm_had_reduced::DcaXYAssoc, + aod::hf_correl_charm_had_reduced::DcaZAssoc, + soa::Marker<2>); + +DECLARE_SOA_TABLE(HfcRedSEHadHads, "AOD", "HFCREDSEHADHAD", //! Correlation pairs information Same Event + aod::hf_correl_charm_had_reduced::PoolBin, + aod::hf_correl_charm_had_reduced::PtTrig, + aod::hf_correl_charm_had_reduced::PtAssoc, + aod::hf_correl_charm_had_reduced::DeltaEta, + aod::hf_correl_charm_had_reduced::DeltaPhi, + aod::hf_correl_charm_had_reduced::NTpcCrossedRowsTrig, + aod::hf_correl_charm_had_reduced::ItsClsMapTrig, + aod::hf_correl_charm_had_reduced::ItsNClsTrig, + aod::hf_correl_charm_had_reduced::DcaXYTrig, + aod::hf_correl_charm_had_reduced::DcaZTrig, + aod::hf_correl_charm_had_reduced::NTpcCrossedRowsAssoc, + aod::hf_correl_charm_had_reduced::ItsClsMapAssoc, + aod::hf_correl_charm_had_reduced::ItsNClsAssoc, + aod::hf_correl_charm_had_reduced::DcaXYAssoc, + aod::hf_correl_charm_had_reduced::DcaZAssoc, + soa::Marker<1>); + +DECLARE_SOA_TABLE(HfcRedMEHadHads, "AOD", "HFCREDMEHADHAD", //! Correlation pairs information Same Event + aod::hf_correl_charm_had_reduced::PoolBin, + aod::hf_correl_charm_had_reduced::PtTrig, + aod::hf_correl_charm_had_reduced::PtAssoc, + aod::hf_correl_charm_had_reduced::DeltaEta, + aod::hf_correl_charm_had_reduced::DeltaPhi, + aod::hf_correl_charm_had_reduced::NTpcCrossedRowsTrig, + aod::hf_correl_charm_had_reduced::ItsClsMapTrig, + aod::hf_correl_charm_had_reduced::ItsNClsTrig, + aod::hf_correl_charm_had_reduced::DcaXYTrig, + aod::hf_correl_charm_had_reduced::DcaZTrig, + aod::hf_correl_charm_had_reduced::NTpcCrossedRowsAssoc, + aod::hf_correl_charm_had_reduced::ItsClsMapAssoc, + aod::hf_correl_charm_had_reduced::ItsNClsAssoc, + aod::hf_correl_charm_had_reduced::DcaXYAssoc, + aod::hf_correl_charm_had_reduced::DcaZAssoc, + soa::Marker<2>); + +DECLARE_SOA_TABLE(HfcRedCollInfos, "AOD", "HFCREDCOLLINFO", //! Table with collision info + aod::hf_collisions_reduced::Multiplicity, + aod::hf_collisions_reduced::NumPvContrib, + aod::hf_collisions_reduced::Centrality); } // namespace o2::aod #endif // PWGHF_HFC_DATAMODEL_DERIVEDDATACORRELATIONTABLES_H_ diff --git a/PWGHF/HFC/TableProducer/correlatorFlowCharmHadronsReduced.cxx b/PWGHF/HFC/TableProducer/correlatorFlowCharmHadronsReduced.cxx index e1d1662924e..85df595a4b0 100644 --- a/PWGHF/HFC/TableProducer/correlatorFlowCharmHadronsReduced.cxx +++ b/PWGHF/HFC/TableProducer/correlatorFlowCharmHadronsReduced.cxx @@ -40,6 +40,7 @@ #include #include +#include #include #include @@ -49,17 +50,57 @@ using namespace o2::framework::expressions; using namespace o2::hf_centrality; using namespace o2::hf_evsel; -using BinningTypeDerivedCent = ColumnBinningPolicy; -using BinningTypeDerivedMult = ColumnBinningPolicy; +using BinningCentPosZ = ColumnBinningPolicy; +using BinningMultPosZ = ColumnBinningPolicy; + +/// Get charm candidate or hadron track pT +/// \param track is the candidate +template +double getPt(const TTrack& track) +{ + if constexpr (requires { track.ptAssoc(); }) { + return track.ptAssoc(); + } else { + return track.ptTrig(); + } +} + +/// Get charm candidate or hadron track eta +/// \param track is the candidate +template +double getEta(const TTrack& track) +{ + if constexpr (requires { track.etaAssoc(); }) { + return track.etaAssoc(); + } else { + return track.etaTrig(); + } +} + +/// Get charm candidate or hadron track phi +/// \param track is the candidate +template +double getPhi(const TTrack& track) +{ + if constexpr (requires { track.phiAssoc(); }) { + return track.phiAssoc(); + } else { + return track.phiTrig(); + } +} struct HfCorrelatorFlowCharmHadronsReduced { - Produces entryCharmHadPair; - Produces entryHadHadPair; + Produces rowPairSECharmHads; //! Correlation pairs information Same Event + Produces rowPairMECharmHads; //! Correlation pairs information Mixed Event + Produces rowPairSEHadHads; //! Correlation pairs information Same Event + Produces rowPairMEHadHads; //! Correlation pairs information Mixed Event + Produces rowCollInfos; //! Collision info Configurable fillSparses{"fillSparses", true, "Fill sparse histograms"}; Configurable fillTables{"fillTables", false, "Fill tables"}; Configurable numberEventsMixed{"numberEventsMixed", 5, "Number of events mixed in ME process"}; - Configurable> binsPtTrig{"binsPtTrig", std::vector{1., 3., 5., 8., 16., 36.}, "pT bin limits for trigger candidates"}; + Configurable> binsPtTrig{"binsPtTrig", std::vector{0., 3., 5., 8., 16., 36.}, "pT bin limits for trigger candidates"}; + Configurable> bkgScoresPtMaxs{"bkgScoresPtMaxs", std::vector{0.1, 0.1, 0.1, 0.1, 0.1}, "pT-differential maximum bkg scores for charm 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"}; @@ -67,20 +108,30 @@ struct HfCorrelatorFlowCharmHadronsReduced { Configurable dcaZTrackMax{"dcaZTrackMax", 1., "max. track DCA Z"}; Configurable tpcCrossedRowsMin{"tpcCrossedRowsMin", 1, "min. TPC crossed rows"}; Configurable itsNClsMin{"itsNClsMin", 1, "min. ITS clusters"}; + Configurable downSamplePairs{"downSamplePairs", 1., "Fraction of pairs to keep"}; + Configurable ptMaxForDownSample{"ptMaxForDownSample", 10., "Maximum pt for the application of the downsampling factor"}; + Configurable centMaxForDownSample{"centMaxForDownSample", 10., "Maximum centrality for the application of the downsampling factor"}; SliceCache cache; - using AssocTracks = soa::Filtered>; + int poolBins{0}; - 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); + using SameEvtPairsChHad = soa::Filtered>; + using SameEvtPairsHadHad = soa::Filtered>; + using AssocTracks = soa::Filtered>; + using TrigCharmCands = soa::Join; - Preslice tracksPerCol = aod::hf_candidate_reduced::hfcRedFlowCollId; - Preslice candsPerCol = aod::hf_candidate_reduced::hfcRedFlowCollId; + Filter filterAssocTracks = (nabs(aod::hf_correl_charm_had_reduced::dcaXYAssoc) < dcaXYTrackMax) && (nabs(aod::hf_correl_charm_had_reduced::dcaZAssoc) < dcaZTrackMax) && (aod::hf_correl_charm_had_reduced::nTpcCrossedRowsAssoc > tpcCrossedRowsMin) && (aod::hf_correl_charm_had_reduced::itsNClsAssoc > itsNClsMin); + Filter filterTrigTracks = (nabs(aod::hf_correl_charm_had_reduced::dcaXYTrig) < dcaXYTrackMax) && (nabs(aod::hf_correl_charm_had_reduced::dcaZTrig) < dcaZTrackMax) && (aod::hf_correl_charm_had_reduced::nTpcCrossedRowsTrig > tpcCrossedRowsMin) && (aod::hf_correl_charm_had_reduced::itsNClsTrig > itsNClsMin); + Filter filterSameEvtPairs = (nabs(aod::hf_correl_charm_had_reduced::deltaEta) > deltaEtaAbsMin) && (nabs(aod::hf_correl_charm_had_reduced::deltaEta) < deltaEtaAbsMax); + + Preslice assocTracksPerCol = aod::hf_correl_charm_had_reduced::hfcRedCorrCollId; + Preslice trigCharmCandsPerCol = aod::hf_correl_charm_had_reduced::hfcRedCorrCollId; ConfigurableAxis zPoolBins{"zPoolBins", {VARIABLE_WIDTH, -10.0, -2.5, 2.5, 10.0}, "Z vertex position pools"}; ConfigurableAxis multPoolBins{"multPoolBins", {VARIABLE_WIDTH, 0., 900., 1800., 6000.}, "Event multiplicity pools (FT0M)"}; - ConfigurableAxis centPoolBins{"centPoolBins", {VARIABLE_WIDTH, 0., 10., 20., 30.}, "Event centrality pools"}; - ConfigurableAxis binsInvMass{"binsInvMass", {300, 1.6, 2.2}, ""}; + ConfigurableAxis centPoolBins{"centPoolBins", {VARIABLE_WIDTH, 0., 10., 20., 30., 40., 50., 60., 70., 80., 90., 100}, "Event centrality pools"}; + ConfigurableAxis binsInvMass{"binsInvMass", {300, 1.6, 2.2}, "Invariant mass bins"}; ConfigurableAxis binsMultFT0M{"binsMultFT0M", {100, 0., 10000.}, "Multiplicity as FT0M signal amplitude"}; ConfigurableAxis binsCent{"binsCent", {100, 0., 100.}, "Centrality bins"}; ConfigurableAxis binsPosZ{"binsPosZ", {100, -10., 10.}, "Primary vertex z coordinate"}; @@ -88,33 +139,40 @@ struct HfCorrelatorFlowCharmHadronsReduced { 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.}, ""}; + ConfigurableAxis binsMlOne{"binsMlOne", {100, 0., 1.}, "ML score index 1 bins"}; + ConfigurableAxis binsMlTwo{"binsMlTwo", {100, 0., 1.}, "ML score index 2 bins"}; HistogramRegistry registry{"registry", {}, OutputObjHandlingPolicy::AnalysisObject}; + BinningMultPosZ binPolicyPosZMult{{zPoolBins, multPoolBins}, true}; + BinningCentPosZ binPolicyPosZCent{{zPoolBins, centPoolBins}, true}; + 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"; - } + if ((doprocessSameEventCharmHadWCentMix && doprocessMixedEventCharmHadWMultMix) || + (doprocessSameEventCharmHadWMultMix && doprocessMixedEventCharmHadWCentMix) || + (doprocessSameEventHadHadWCentMix && doprocessMixedEventHadHadWMultMix) || + (doprocessSameEventHadHadWMultMix && doprocessMixedEventHadHadWCentMix)) { + LOGP(fatal, "You cannot mix centrality and multiplicity mixing in the same processing! Please check your configuration!"); + } + if (!fillSparses && !fillTables) { + LOGP(fatal, "At least one of fillSparses or fillTables must be true!"); + } + if (binsPtTrig.value.size() != (bkgScoresPtMaxs.value.size() + 1)) { + LOGP(fatal, "The size of binsPtTrig must be the one of bkgScorePtMaxs plus one!"); + } + + if (doprocessSameEventCharmHadWCentMix || doprocessSameEventHadHadWCentMix || doprocessMixedEventCharmHadWCentMix || doprocessMixedEventHadHadWCentMix) { + poolBins = (centPoolBins->size() - 1) * (zPoolBins->size() - 1); + } else { + poolBins = (multPoolBins->size() - 1) * (zPoolBins->size() - 1); } 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 axisPoolBin = {poolBins, 0., static_cast(poolBins), "PoolBin"}; const AxisSpec axisDeltaEta = {binsDeltaEta, "#Delta#it{#eta}"}; const AxisSpec axisDeltaPhi = {binsDeltaPhi, "#Delta#it{#varphi}"}; const AxisSpec axisPtTrig = {(std::vector)binsPtTrig, "#it{p}_{T} Trig (GeV/#it{c})"}; @@ -123,28 +181,29 @@ struct HfCorrelatorFlowCharmHadronsReduced { 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}}}); + if (doprocessSameEventCharmHadWCentMix || doprocessSameEventHadHadWCentMix) { + registry.add("hCentPoolBinSE", "Centrality SE", {HistType::kTH2F, {{axisCent}, {axisPoolBin}}}); + } else if (doprocessSameEventCharmHadWMultMix || doprocessSameEventHadHadWMultMix) { + registry.add("hMultFT0MPoolBinSE", "Multiplicity FT0M SE", {HistType::kTH2F, {{axisMultFT0M}, {axisPoolBin}}}); + } else if (doprocessMixedEventCharmHadWCentMix || doprocessMixedEventHadHadWCentMix) { + registry.add("hCentPoolBinME", "Centrality ME", {HistType::kTH2F, {{axisCent}, {axisPoolBin}}}); + } else if (doprocessMixedEventCharmHadWMultMix || doprocessMixedEventHadHadWMultMix) { + registry.add("hMultFT0MPoolBinME", "Multiplicity FT0M ME", {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}}}); - + registry.add("hZVtxPoolBinSE", "z vertex SE", {HistType::kTH2F, {{axisPosZ}, {axisPoolBin}}}); + registry.add("hZVtxPoolBinME", "z vertex ME", {HistType::kTH2F, {{axisPosZ}, {axisPoolBin}}}); + registry.add("hPoolBinTrigSE", "Trigger candidates pool bin SE", {HistType::kTH1F, {axisPoolBin}}); + registry.add("hPoolBinTrigME", "Trigger candidates pool bin ME", {HistType::kTH1F, {axisPoolBin}}); + registry.add("hPoolBinAssocSE", "Associated particles pool bin SE", {HistType::kTH1F, {axisPoolBin}}); + registry.add("hPoolBinAssocME", "Associated particles pool bin ME", {HistType::kTH1F, {axisPoolBin}}); if (fillSparses) { - std::vector axes = {axisPtTrig, axisPtAssoc, axisDeltaEta, axisDeltaPhi, axisPoolBin}; + std::vector axes = {axisPoolBin, axisPtTrig, axisPtAssoc, axisDeltaEta, axisDeltaPhi}; if (doprocessSameEventHadHadWCentMix || doprocessSameEventHadHadWMultMix) { registry.add("hSparseCorrelationsSEHadHad", "THn for SE Had-Had correlations", HistType::kTHnSparseF, axes); } else if (doprocessMixedEventHadHadWCentMix || doprocessMixedEventHadHadWMultMix) { registry.add("hSparseCorrelationsMEHadHad", "THn for ME Had-Had correlations", HistType::kTHnSparseF, axes); } else { - axes.insert(axes.end(), {axisMlOne, axisMlTwo, axisInvMass}); + axes.insert(axes.end(), {axisInvMass, axisMlOne, axisMlTwo}); if (doprocessSameEventCharmHadWCentMix || doprocessSameEventCharmHadWMultMix) { registry.add("hSparseCorrelationsSECharmHad", "THn for SE Charm-Had correlations", HistType::kTHnSparseF, axes); } else if (doprocessMixedEventCharmHadWCentMix || doprocessMixedEventCharmHadWMultMix) { @@ -154,312 +213,273 @@ struct HfCorrelatorFlowCharmHadronsReduced { } } - /// 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) + /// \param binPolicy is the binning policy for the correlation + template + int getPoolBin(const TColl& collision, const TBinningType& binPolicy) { 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); + if constexpr (std::is_same_v) { + poolBin = binPolicy.getBin(std::make_tuple(collision.posZ(), collision.centrality())); + if constexpr (isMixedEvent) { + registry.fill(HIST("hCentPoolBinME"), collision.centrality(), poolBin); + registry.fill(HIST("hZVtxPoolBinME"), collision.posZ(), poolBin); + } else { + registry.fill(HIST("hCentPoolBinSE"), collision.centrality(), poolBin); + registry.fill(HIST("hZVtxPoolBinSE"), collision.posZ(), 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) { + } else if constexpr (std::is_same_v) { + poolBin = binPolicy.getBin(std::make_tuple(collision.posZ(), collision.multiplicity())); if constexpr (isMixedEvent) { - registry.fill(HIST("hSparseCorrelationsMECharmHad"), getPt(trigCand), getPt(assocTrack), - deltaEta, deltaPhi, poolBin, trigCand.bdtScore0(), - trigCand.bdtScore1(), trigCand.invMassCand()); + registry.fill(HIST("hMultFT0MPoolBinME"), collision.multiplicity(), poolBin); + registry.fill(HIST("hZVtxPoolBinME"), collision.posZ(), poolBin); } else { - registry.fill(HIST("hSparseCorrelationsSECharmHad"), getPt(trigCand), getPt(assocTrack), - deltaEta, deltaPhi, poolBin, trigCand.bdtScore0(), - trigCand.bdtScore1(), trigCand.invMassCand()); + registry.fill(HIST("hMultFT0MPoolBinSE"), collision.multiplicity(), poolBin); + registry.fill(HIST("hZVtxPoolBinSE"), collision.posZ(), poolBin); } } + return poolBin; } - /// 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) + /// Apply pT-differential ML BDT bkg score cut + /// \param ptTrig is the pT of the charm candidate + template + bool isSelBdtBkgScoreCut(TCand const& cand, + double ptTrig) { - 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); + for (size_t iPt = 0; iPt < binsPtTrig.value.size() - 1; iPt++) { + if (ptTrig >= binsPtTrig.value[iPt] && ptTrig < binsPtTrig.value[iPt + 1]) { + return cand.bdtScore0Trig() < bkgScoresPtMaxs.value[iPt]; } } + return false; } /// 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) + /// \param binPolicy is the binning policy for the correlation + template + void fillSameEvent(TPair const& pair, + TBinningType binPolicy) { - 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); - } - } + auto collision = pair.template hfcRedCorrColl_as(); + double ptTrig = pair.ptTrig(); + if constexpr (requires { pair.bdtScore0Trig(); }) { // ML selection on bkg score for Charm-Had case + if (!isSelBdtBkgScoreCut(pair, ptTrig)) { + return; + } + } + if (downSamplePairs < 1.) { + float pseudoRndm = ptTrig * 1000. - static_cast(ptTrig * 1000); + if (ptTrig < ptMaxForDownSample && collision.centrality() < centMaxForDownSample && pseudoRndm >= downSamplePairs) { + return; + } + } + int poolBin = getPoolBin(collision, binPolicy); + registry.fill(HIST("hPoolBinTrigSE"), poolBin); + registry.fill(HIST("hPoolBinAssocSE"), poolBin); + if constexpr (fillTables) { + if constexpr (requires { pair.bdtScore0Trig(); }) { // Separate Charm-Had and Had-Had cases + rowPairSECharmHads(poolBin, ptTrig, pair.ptAssoc(), pair.deltaEta(), pair.deltaPhi(), + pair.invMassTrig(), pair.bdtScore0Trig(), pair.bdtScore1Trig(), + pair.nTpcCrossedRowsAssoc(), pair.itsClsMapAssoc(), pair.itsNClsAssoc(), pair.dcaXYAssoc(), pair.dcaZAssoc()); + } else { + rowPairSEHadHads(poolBin, ptTrig, pair.ptAssoc(), pair.deltaEta(), pair.deltaPhi(), + pair.nTpcCrossedRowsTrig(), pair.itsClsMapTrig(), pair.itsNClsTrig(), pair.dcaXYTrig(), pair.dcaZTrig(), + pair.nTpcCrossedRowsAssoc(), pair.itsClsMapAssoc(), pair.itsNClsAssoc(), pair.dcaXYAssoc(), pair.dcaZAssoc()); + } + rowCollInfos(collision.multiplicity(), collision.numPvContrib(), collision.centrality()); + } + if constexpr (fillSparses) { + if constexpr (requires { pair.bdtScore0Trig(); }) { // Separate Charm-Had and Had-Had cases + registry.fill(HIST("hSparseCorrelationsSECharmHad"), poolBin, ptTrig, pair.ptAssoc(), pair.deltaEta(), + pair.deltaPhi(), pair.invMassTrig(), pair.bdtScore0Trig(), pair.bdtScore1Trig()); + } else { + registry.fill(HIST("hSparseCorrelationsSEHadHad"), poolBin, ptTrig, pair.ptAssoc(), pair.deltaEta(), pair.deltaPhi()); } } } /// 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) + /// \param pairs are the mixed event pairs of trigger candidates and associated tracks + /// \param binPolicy is the binning policy for the correlation + template + void fillMixedEvent(TPairs const& pairs, + TBinningType binPolicy) { - 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) { + for (const auto& [trigColl, trigCands, assocColl, assocTracks] : pairs) { if (trigCands.size() == 0 || assocTracks.size() == 0) { continue; } - int poolBinCharm = getPoolBin(trigColl, corrBinning); - int poolBinAssoc = getPoolBin(assocColl, corrBinning); - if (poolBinAssoc != poolBinCharm) { + int poolBinTrig = getPoolBin(trigColl, binPolicy); + int poolBinAssoc = getPoolBin(assocColl, binPolicy); + if (poolBinAssoc != poolBinTrig) { LOGF(info, "Error, poolBins are different"); continue; } + registry.fill(HIST("hPoolBinTrigME"), poolBinTrig); + registry.fill(HIST("hPoolBinAssocME"), poolBinAssoc); for (const auto& [trigCand, assocTrack] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(trigCands, assocTracks))) { + // 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()); 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); + double ptTrig = getPt(trigCand); + if constexpr (requires { trigCand.bdtScore0Trig(); }) { // ML selection on bkg score for Charm-Had case + if (!isSelBdtBkgScoreCut(trigCand, ptTrig)) { + continue; + } + } + double ptAssoc = getPt(assocTrack); + if (downSamplePairs < 1.) { + float pseudoRndm = ptAssoc * 1000. - static_cast(ptAssoc * 1000); + if (ptTrig < ptMaxForDownSample && trigColl.centrality() < centMaxForDownSample && + assocColl.centrality() < centMaxForDownSample && pseudoRndm >= downSamplePairs) { + continue; + } + } + double deltaPhi = RecoDecay::constrainAngle(getPhi(assocTrack) - getPhi(trigCand), -o2::constants::math::PIHalf); + if constexpr (fillTables) { + if constexpr (requires { trigCand.bdtScore0Trig(); }) { // Separate Charm-Had and Had-Had cases + rowPairMECharmHads(poolBinTrig, ptTrig, ptAssoc, deltaEta, deltaPhi, + trigCand.invMassTrig(), trigCand.bdtScore0Trig(), trigCand.bdtScore1Trig(), + assocTrack.nTpcCrossedRowsAssoc(), assocTrack.itsClsMapAssoc(), assocTrack.itsNClsAssoc(), assocTrack.dcaXYAssoc(), assocTrack.dcaZAssoc()); + } else { + rowPairMEHadHads(poolBinTrig, ptTrig, ptAssoc, deltaEta, deltaPhi, + trigCand.nTpcCrossedRowsAssoc(), trigCand.itsClsMapAssoc(), trigCand.itsNClsAssoc(), trigCand.dcaXYAssoc(), trigCand.dcaZAssoc(), + assocTrack.nTpcCrossedRowsAssoc(), assocTrack.itsClsMapAssoc(), assocTrack.itsNClsAssoc(), assocTrack.dcaXYAssoc(), assocTrack.dcaZAssoc()); + } + rowCollInfos(trigColl.multiplicity(), trigColl.numPvContrib(), trigColl.centrality()); + } + if constexpr (fillSparses) { + if constexpr (requires { trigCand.bdtScore0Trig(); }) { // Separate Charm-Had and Had-Had cases + registry.fill(HIST("hSparseCorrelationsMECharmHad"), poolBinTrig, ptTrig, ptAssoc, deltaEta, + deltaPhi, trigCand.invMassTrig(), trigCand.bdtScore0Trig(), trigCand.bdtScore1Trig()); + } else { + registry.fill(HIST("hSparseCorrelationsMEHadHad"), poolBinTrig, ptTrig, ptAssoc, deltaEta, deltaPhi); + } } } } } - void processSameEventCharmHadWCentMix(aod::HfcRedFlowColls const& collisions, - soa::Join const& candidates, - AssocTracks const& tracks) + void processSameEventCharmHadWMultMix(SameEvtPairsChHad::iterator const& pair, + aod::HfcRedCorrColls const&) { - ColumnBinningPolicy corrBinningCent{{zPoolBins, centPoolBins}, true}; - fillSameEvent(collisions, candidates, tracks, corrBinningCent); + if (fillSparses && fillTables) { + fillSameEvent(pair, binPolicyPosZMult); + } else if (fillSparses) { + fillSameEvent(pair, binPolicyPosZMult); + } else if (fillTables) { + fillSameEvent(pair, binPolicyPosZMult); + } } - PROCESS_SWITCH(HfCorrelatorFlowCharmHadronsReduced, processSameEventCharmHadWCentMix, "Process Same Event for Charm-Had with centrality pools", true); + PROCESS_SWITCH(HfCorrelatorFlowCharmHadronsReduced, processSameEventCharmHadWMultMix, "Process Same Event for Charm-Had with multiplicity pools", true); - void processSameEventCharmHadWMultMix(aod::HfcRedFlowColls const& collisions, - soa::Join const& candidates, - AssocTracks const& tracks) + void processSameEventHadHadWMultMix(SameEvtPairsHadHad::iterator const& pair, + aod::HfcRedCorrColls const&) { - ColumnBinningPolicy corrBinningMult{{zPoolBins, multPoolBins}, true}; - fillSameEvent(collisions, candidates, tracks, corrBinningMult); + if (fillSparses && fillTables) { + fillSameEvent(pair, binPolicyPosZMult); + } else if (fillSparses) { + fillSameEvent(pair, binPolicyPosZMult); + } else if (fillTables) { + fillSameEvent(pair, binPolicyPosZMult); + } } - PROCESS_SWITCH(HfCorrelatorFlowCharmHadronsReduced, processSameEventCharmHadWMultMix, "Process Same Event for Charm-Had with multiplicity pools", false); + PROCESS_SWITCH(HfCorrelatorFlowCharmHadronsReduced, processSameEventHadHadWMultMix, "Process Same Event for Had-Had with multiplicity pools", false); - void processMixedEventCharmHadWCentMix(aod::HfcRedFlowColls const& collisions, - soa::Join const& candidates, - AssocTracks const& tracks) + void processSameEventCharmHadWCentMix(SameEvtPairsChHad::iterator const& pair, + aod::HfcRedCorrColls const&) { - ColumnBinningPolicy corrBinningCent{{zPoolBins, centPoolBins}, true}; - fillMixedEvent(collisions, candidates, tracks, corrBinningCent); + if (fillSparses && fillTables) { + fillSameEvent(pair, binPolicyPosZCent); + } else if (fillSparses) { + fillSameEvent(pair, binPolicyPosZCent); + } else if (fillTables) { + fillSameEvent(pair, binPolicyPosZCent); + } } - PROCESS_SWITCH(HfCorrelatorFlowCharmHadronsReduced, processMixedEventCharmHadWCentMix, "Process Mixed Event for Charm-Had with centrality pools", false); + PROCESS_SWITCH(HfCorrelatorFlowCharmHadronsReduced, processSameEventCharmHadWCentMix, "Process Same Event for Charm-Had with centrality pools", true); - void processMixedEventCharmHadWMultMix(aod::HfcRedFlowColls const& collisions, - soa::Join const& candidates, - AssocTracks const& tracks) + void processSameEventHadHadWCentMix(SameEvtPairsHadHad::iterator const& pair, + aod::HfcRedCorrColls const&) { - ColumnBinningPolicy corrBinningMult{{zPoolBins, multPoolBins}, true}; - fillMixedEvent(collisions, candidates, tracks, corrBinningMult); + if (fillSparses && fillTables) { + fillSameEvent(pair, binPolicyPosZCent); + } else if (fillSparses) { + fillSameEvent(pair, binPolicyPosZCent); + } else if (fillTables) { + fillSameEvent(pair, binPolicyPosZCent); + } } - PROCESS_SWITCH(HfCorrelatorFlowCharmHadronsReduced, processMixedEventCharmHadWMultMix, "Process Mixed Event for Charm-Had with multiplicity pools", false); + PROCESS_SWITCH(HfCorrelatorFlowCharmHadronsReduced, processSameEventHadHadWCentMix, "Process Same Event for Had-Had with centrality pools", false); - void processSameEventHadHadWCentMix(aod::HfcRedFlowColls const& collisions, - AssocTracks const& tracks) + void processMixedEventCharmHadWCentMix(aod::HfcRedCorrColls const& collisions, + TrigCharmCands const& candidates, + AssocTracks const& tracks) { - ColumnBinningPolicy corrBinningCent{{zPoolBins, centPoolBins}, true}; - fillSameEvent(collisions, tracks, tracks, corrBinningCent); + auto pairsTuple = std::make_tuple(candidates, tracks); + Pair pairs{binPolicyPosZCent, numberEventsMixed, -1, collisions, pairsTuple, &cache}; + if (fillSparses && fillTables) { + fillMixedEvent(pairs, binPolicyPosZCent); + } else if (fillSparses) { + fillMixedEvent(pairs, binPolicyPosZCent); + } else if (fillTables) { + fillMixedEvent(pairs, binPolicyPosZCent); + } } - PROCESS_SWITCH(HfCorrelatorFlowCharmHadronsReduced, processSameEventHadHadWCentMix, "Process Same Event for Had-Had with centrality pools", false); + PROCESS_SWITCH(HfCorrelatorFlowCharmHadronsReduced, processMixedEventCharmHadWCentMix, "Process Mixed Event for Charm-Had with centrality pools", false); - void processSameEventHadHadWMultMix(aod::HfcRedFlowColls const& collisions, - AssocTracks const& tracks) + void processMixedEventCharmHadWMultMix(aod::HfcRedCorrColls const& collisions, + TrigCharmCands const& candidates, + AssocTracks const& tracks) { - ColumnBinningPolicy corrBinningMult{{zPoolBins, multPoolBins}, true}; - fillSameEvent(collisions, tracks, tracks, corrBinningMult); + auto pairsTuple = std::make_tuple(candidates, tracks); + Pair pairs{binPolicyPosZMult, numberEventsMixed, -1, collisions, pairsTuple, &cache}; + if (fillSparses && fillTables) { + fillMixedEvent(pairs, binPolicyPosZMult); + } else if (fillSparses) { + fillMixedEvent(pairs, binPolicyPosZMult); + } else if (fillTables) { + fillMixedEvent(pairs, binPolicyPosZMult); + } } - PROCESS_SWITCH(HfCorrelatorFlowCharmHadronsReduced, processSameEventHadHadWMultMix, "Process Same Event for Had-Had with multiplicity pools", false); + PROCESS_SWITCH(HfCorrelatorFlowCharmHadronsReduced, processMixedEventCharmHadWMultMix, "Process Mixed Event for Charm-Had with multiplicity pools", false); - void processMixedEventHadHadWCentMix(aod::HfcRedFlowColls const& collisions, + void processMixedEventHadHadWCentMix(aod::HfcRedCorrColls const& collisions, AssocTracks const& tracks) { - ColumnBinningPolicy corrBinningCent{{zPoolBins, centPoolBins}, true}; - fillMixedEvent(collisions, tracks, tracks, corrBinningCent); + auto tracksTuple = std::make_tuple(tracks); + SameKindPair pairs{binPolicyPosZCent, numberEventsMixed, -1, collisions, tracksTuple, &cache}; + if (fillSparses && fillTables) { + fillMixedEvent(pairs, binPolicyPosZCent); + } else if (fillSparses) { + fillMixedEvent(pairs, binPolicyPosZCent); + } else if (fillTables) { + fillMixedEvent(pairs, binPolicyPosZCent); + } } PROCESS_SWITCH(HfCorrelatorFlowCharmHadronsReduced, processMixedEventHadHadWCentMix, "Process Mixed Event for Had-Had with centrality pools", false); - void processMixedEventHadHadWMultMix(aod::HfcRedFlowColls const& collisions, + void processMixedEventHadHadWMultMix(aod::HfcRedCorrColls const& collisions, AssocTracks const& tracks) { - ColumnBinningPolicy corrBinningMult{{zPoolBins, multPoolBins}, true}; - fillMixedEvent(collisions, tracks, tracks, corrBinningMult); + auto tracksTuple = std::make_tuple(tracks); + SameKindPair pairs{binPolicyPosZMult, numberEventsMixed, -1, collisions, tracksTuple, &cache}; + if (fillSparses && fillTables) { + fillMixedEvent(pairs, binPolicyPosZMult); + } else if (fillSparses) { + fillMixedEvent(pairs, binPolicyPosZMult); + } else if (fillTables) { + fillMixedEvent(pairs, binPolicyPosZMult); + } } PROCESS_SWITCH(HfCorrelatorFlowCharmHadronsReduced, processMixedEventHadHadWMultMix, "Process Mixed Event for Had-Had with multiplicity pools", false); }; diff --git a/PWGHF/HFC/TableProducer/derivedDataCreatorCorrelationsReduced.cxx b/PWGHF/HFC/TableProducer/derivedDataCreatorCorrelationsReduced.cxx index e5bb19f2e9e..e46a1d27bca 100644 --- a/PWGHF/HFC/TableProducer/derivedDataCreatorCorrelationsReduced.cxx +++ b/PWGHF/HFC/TableProducer/derivedDataCreatorCorrelationsReduced.cxx @@ -51,35 +51,49 @@ using namespace o2::framework::expressions; using namespace o2::hf_centrality; using namespace o2::hf_evsel; -enum DecayChannel { +enum CandType { DplusToPiKPi = 0, DsToKKPi, DsToPiKK, D0ToPiK, - D0ToKPi + D0ToKPi, + Hadron }; /// Code to select collisions with at least one Ds meson struct HfDerivedDataCreatorCorrelationsReduced { - Produces rowCollisions; - Produces rowCharmCandidates; - Produces rowCharmCandidatesMl; - Produces rowAssocTrackReduced; - Produces rowAssocTrackSelInfo; + Produces rowCollisions; // Table with reduced collision info + Produces rowSEPairs; // Table with same-event pairs info + Produces rowAssocBases; // Table with associated candidate base info + Produces rowAssocTrkSels; // Table with associated track selection info + Produces rowTrigBases; // Table with base trigger candidate info + Produces rowTrigCharms; // Table with charm trigger candidate selection info + Produces rowTrigHads; // Table with hadron trigger candidate selection info 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 selectionFlag{"selectionFlag", 15, "Selection Flag for hadron (ML score tables are required to run the task)"}; + Configurable forceCharmInCollision{"forceCharmInCollision", true, "Flag to force charm in collision"}; Configurable 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 ptCandMin{"ptCandMin", 0., "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"}; + Configurable tpcNClsCrossedRowsMin{"tpcNClsCrossedRowsMin", 70, "min. TPC crossed rows for associated tracks"}; + Configurable etaTrkMax{"etaTrkMax", 1., "max. track eta"}; + Configurable ptTrkMin{"ptTrkMin", 0.2, "min. track pT"}; + Configurable ptTrkMax{"ptTrkMax", 3., "max. track pT"}; + Configurable dcaXYTrkMax{"dcaXYTrkMax", 1., "max. track DCA XY"}; + Configurable dcaZTrkMax{"dcaZTrkMax", 1., "max. track DCA Z"}; + Configurable usePtDiffDcaXYCut{"usePtDiffDcaXYCut", false, "Use pt-differential DCAxy cut for associated tracks"}; + Configurable dcaXYTrkNSigmaMax{"dcaXYTrkNSigmaMax", 7, "Cut on number of sigma deviations from expected DCA in the transverse direction"}; + Configurable dcaXYPtPrimTrkFunc{"dcaXYPtPrimTrkFunc", "(0.0026+0.005/(x^1.01))", "Functional form of pt-dependent DCAxy cut"}; + Configurable deltaEtaAbsMin{"deltaEtaAbsMin", 0.5, "min. pair delta eta"}; + Configurable deltaEtaAbsMax{"deltaEtaAbsMax", 2., "max. pair delta eta"}; + Configurable downSampleTrksFactor{"downSampleTrksFactor", 1., "Fraction of associated tracks to keep"}; + Configurable ptMaxForDownSample{"ptMaxForDownSample", 10., "Maximum pt for the application of the downsampling factor"}; + Configurable centMaxForDownSample{"centMaxForDownSample", 101., "Maximum centrality for the application of the downsampling factor"}; + Configurable> binsPtTrig{"binsPtTrig", std::vector{0., 1., 2., 3., 5., 8., 12., 24., 36.}, "pT bin limits for trigger candidates"}; + Configurable> binsPtAssoc{"binsPtAssoc", std::vector{0.2, 1., 2., 50.}, "pT bin limits for associated particles"}; HfHelper hfHelper; HfEventSelection hfEvSel; // event selection and monitoring @@ -87,38 +101,53 @@ struct HfDerivedDataCreatorCorrelationsReduced { SliceCache cache; double massCharm{0.}; + TF1* funcDcaXYPtCutPrimTrk = nullptr; using CollsWithCentMult = soa::Join; - using CandDsDataWMl = soa::Filtered>; - using CandDplusDataWMl = soa::Filtered>; - using CandD0DataWMl = soa::Filtered>; + using CandDsData = soa::Filtered>; + using CandDplusData = soa::Filtered>; + using CandD0Data = 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 filterSelectD0Candidates = aod::hf_sel_candidate_d0::isSelD0 >= selectionFlag || aod::hf_sel_candidate_d0::isSelD0bar >= 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); + Filter filterSelectTrkData = (nabs(aod::track::eta) < etaTrkMax) && (aod::track::pt > ptTrkMin) && (aod::track::pt < ptTrkMax) && (nabs(aod::track::dcaXY) < dcaXYTrkMax) && (nabs(aod::track::dcaZ) < dcaZTrkMax); - Preslice candsDsPerCollWMl = aod::hf_cand::collisionId; - Preslice candsDplusPerCollWMl = aod::hf_cand::collisionId; - Preslice candsD0PerCollWMl = aod::hf_cand::collisionId; + Preslice candsDsPerColl = aod::hf_cand::collisionId; + Preslice candsDplusPerColl = aod::hf_cand::collisionId; + Preslice candsD0PerColl = aod::hf_cand::collisionId; Preslice trackIndicesPerColl = aod::track::collisionId; - Partition selectedDsToKKPiWMl = aod::hf_sel_candidate_ds::isSelDsToKKPi >= selectionFlag; - Partition selectedDsToPiKKWMl = aod::hf_sel_candidate_ds::isSelDsToPiKK >= selectionFlag; - Partition selectedD0ToPiKWMl = aod::hf_sel_candidate_d0::isSelD0 >= selectionFlag; - Partition selectedD0ToKPiWMl = aod::hf_sel_candidate_d0::isSelD0bar >= selectionFlag; + Partition selectedDsToKKPi = aod::hf_sel_candidate_ds::isSelDsToKKPi >= selectionFlag; + Partition selectedDsToPiKK = aod::hf_sel_candidate_ds::isSelDsToPiKK >= selectionFlag; + Partition selectedD0ToPiK = aod::hf_sel_candidate_d0::isSelD0 >= selectionFlag; + Partition selectedD0ToKPi = aod::hf_sel_candidate_d0::isSelD0bar >= selectionFlag; + + 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 binsMlOne{"binsMlOne", {100, 0., 1.}, ""}; + ConfigurableAxis binsMlTwo{"binsMlTwo", {100, 0., 1.}, ""}; + ConfigurableAxis binsDca{"binsDca", {200, -1., 1.}, ""}; HistogramRegistry registry{"registry", {}}; void init(InitContext&) { - if (doprocessDplusWithMl) { + if (doprocessDplusSameEvent || doprocessDplusMixedEvent) { massCharm = o2::constants::physics::MassDPlus; - } else if (doprocessDsWithMl) { + } else if (doprocessDsSameEvent || doprocessDsMixedEvent) { massCharm = o2::constants::physics::MassDS; - } else if (doprocessD0WithMl) { + } else if (doprocessD0SameEvent || doprocessD0MixedEvent) { massCharm = o2::constants::physics::MassD0; + } else if (doprocessHadronHadronSameEvent || doprocessHadronHadronMixedEvent) { + LOG(info) << "Charm mass not set, processing Hadron-Hadron case"; } else { LOG(fatal) << "No decay channel selected to process"; } @@ -127,58 +156,53 @@ struct HfDerivedDataCreatorCorrelationsReduced { 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 - 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; + const AxisSpec axisCent = {binsCent, "Centrality"}; + const AxisSpec axisMultFT0M = {binsMultFT0M, "MultiplicityFT0M"}; + const AxisSpec axisPosZ = {binsPosZ, "PosZ"}; + const AxisSpec axisEta = {binsEta, "#it{#eta}"}; + const AxisSpec axisPhi = {binsPhi, "#it{#varphi}"}; + const AxisSpec axisPtTrig = {(std::vector)binsPtTrig, "#it{p}_{T} Trig (GeV/#it{c})"}; + const AxisSpec axisPtAssoc = {(std::vector)binsPtAssoc, "#it{p}_{T} Assoc (GeV/#it{c})"}; + const AxisSpec axisDcaXY = {binsDca, "DCA XY (cm)"}; + const AxisSpec axisDcaZ = {binsDca, "DCA Z (cm)"}; + + // Histograms for data analysis + registry.add("hPhiVsPtTrig", "Trigger candidates phiVsPt", {HistType::kTH2F, {{axisPhi}, {axisPtTrig}}}); + registry.add("hEtaVsPtTrig", "Trigger candidates etaVsPt", {HistType::kTH2F, {{axisEta}, {axisPtTrig}}}); + registry.add("hPhiVsPtTrigAssoc", "Associated particles phiVsPt", {HistType::kTH3F, {{axisPhi}, {axisPtTrig}, {axisPtAssoc}}}); + registry.add("hEtaVsPtTrigAssoc", "Associated particles etaVsPt", {HistType::kTH3F, {{axisEta}, {axisPtTrig}, {axisPtAssoc}}}); + registry.add("hPhiVsPtAssoc", "Associated particles phiVsPt", {HistType::kTH2F, {{axisPhi}, {axisPtAssoc}}}); + registry.add("hEtaVsPtAssoc", "Associated particles etaVsPt", {HistType::kTH2F, {{axisEta}, {axisPtAssoc}}}); + registry.add("hDcaXYVsPtAssoc", "Associated particles DCAxyVsPt", {HistType::kTH2F, {{axisDcaXY}, {axisPtAssoc}}}); + registry.add("hDcaZVsPtAssoc", "Associated particles DCAzVsPt", {HistType::kTH2F, {{axisDcaZ}, {axisPtAssoc}}}); + + // Setup pt-dependent DCAxy cut function + if (usePtDiffDcaXYCut) { + funcDcaXYPtCutPrimTrk = new TF1("funcDcaXYPtCutPrimTrk", Form("[0]*%s", dcaXYPtPrimTrkFunc.value.data()), 0.001, 100); + funcDcaXYPtCutPrimTrk->SetParameter(0, dcaXYTrkNSigmaMax); + LOGF(info, "DCAxy pt-dependence function: %s", Form("[0]*%s", dcaXYPtPrimTrkFunc.value.data())); } - rowCollisions(mult, collision.numContrib(), cent, collision.posZ()); - return true; - } + }; // end init /// Get charm hadron candidate mass /// \param candidate is the charm hadron candidate - template + template double getCandMass(const TCand& candidate) { - if constexpr (channel == DecayChannel::DsToKKPi) { + if constexpr (candType == CandType::DsToKKPi) { return hfHelper.invMassDsToKKPi(candidate); } - if constexpr (channel == DecayChannel::DsToPiKK) { + if constexpr (candType == CandType::DsToPiKK) { return hfHelper.invMassDsToPiKK(candidate); } - if constexpr (channel == DecayChannel::DplusToPiKPi) { + if constexpr (candType == CandType::DplusToPiKPi) { return hfHelper.invMassDplusToPiKPi(candidate); } - if constexpr (channel == DecayChannel::D0ToPiK) { + if constexpr (candType == CandType::D0ToPiK) { return hfHelper.invMassD0ToPiK(candidate); } - if constexpr (channel == DecayChannel::D0ToKPi) { + if constexpr (candType == CandType::D0ToKPi) { return hfHelper.invMassD0barToKPi(candidate); } return -1.; @@ -186,31 +210,31 @@ struct HfDerivedDataCreatorCorrelationsReduced { /// Get charm hadron bdt scores /// \param candidate is the charm hadron candidate - template - std::vector getCandMlScores(const TCand& candidate) + template + std::array getCandMlScores(const TCand& candidate) { - std::vector outputMl{-999., -999.}; - if constexpr (channel == DecayChannel::DsToKKPi) { + std::array outputMl{-999.f, -999.f}; + if constexpr (candType == CandType::DsToKKPi) { for (unsigned int iclass = 0; iclass < classMl->size(); iclass++) { outputMl[iclass] = candidate.mlProbDsToKKPi()[classMl->at(iclass)]; } } - if constexpr (channel == DecayChannel::DsToPiKK) { + if constexpr (candType == CandType::DsToPiKK) { for (unsigned int iclass = 0; iclass < classMl->size(); iclass++) { outputMl[iclass] = candidate.mlProbDsToPiKK()[classMl->at(iclass)]; } } - if constexpr (channel == DecayChannel::DplusToPiKPi) { + if constexpr (candType == CandType::DplusToPiKPi) { for (unsigned int iclass = 0; iclass < classMl->size(); iclass++) { outputMl[iclass] = candidate.mlProbDplusToPiKPi()[classMl->at(iclass)]; } } - if constexpr (channel == DecayChannel::D0ToPiK) { + if constexpr (candType == CandType::D0ToPiK) { for (unsigned int iclass = 0; iclass < classMl->size(); iclass++) { outputMl[iclass] = candidate.mlProbD0()[classMl->at(iclass)]; } } - if constexpr (channel == DecayChannel::D0ToKPi) { + if constexpr (candType == CandType::D0ToKPi) { for (unsigned int iclass = 0; iclass < classMl->size(); iclass++) { outputMl[iclass] = candidate.mlProbD0bar()[classMl->at(iclass)]; } @@ -218,108 +242,315 @@ struct HfDerivedDataCreatorCorrelationsReduced { return outputMl; } - /// Fill charm hadron tables - /// \param candidates are the selected charm hadron candidates - template - void fillCharmHadronTables(TCand const& candidates) + /// Check event selections for collision and fill the collision table + /// \param collision is the collision + template + bool checkCollision(Coll const& collision, float& cent, float& mult) { - int indexRedColl = rowCollisions.lastIndex(); - for (const auto& candidate : candidates) { - if (std::abs(candidate.y(massCharm)) > yCandMax || candidate.pt() < ptCandMin || candidate.pt() > ptCandMax) { - continue; + 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; + } + return true; + } + + /// Checks if the trigger cand-associated track pair can be accepted for SE correlation + /// \param assTrk is the associated track + /// \param cand is the trigger candidate + template + bool acceptSameEvtPair(TAssocTrk const& assTrk, TCand const& cand, double deltaEta) + { + if (std::abs(deltaEta) <= deltaEtaAbsMin || std::abs(deltaEta) > deltaEtaAbsMax) { + return false; + } + + if (!assTrk.isGlobalTrackWoDCA() || assTrk.tpcNClsCrossedRows() < tpcNClsCrossedRowsMin) { + return false; + } + + int trackGlobalIndex = assTrk.globalIndex(); + if constexpr (candType == CandType::Hadron) { + if (!cand.isGlobalTrackWoDCA() || cand.tpcNClsCrossedRows() < tpcNClsCrossedRowsMin) { + return false; + } + if (trackGlobalIndex <= cand.globalIndex()) { + return false; // skip self-correlation and avoid pair duplication for hadron-hadron } - double massCand = getCandMass(candidate); - if constexpr (channel == DecayChannel::D0ToKPi || channel == DecayChannel::D0ToPiK) { - rowCharmCandidates(indexRedColl, candidate.phi(), candidate.eta(), candidate.pt(), massCand, candidate.prong0Id(), candidate.prong1Id(), -1); - } else { - rowCharmCandidates(indexRedColl, candidate.phi(), candidate.eta(), candidate.pt(), massCand, candidate.prong0Id(), candidate.prong1Id(), candidate.prong2Id()); + } else { // Remove Daughter-Cand pairs for charm-hadron correlations + if constexpr ((requires { cand.prong2Id(); })) { // Check 3-prong + if (trackGlobalIndex == cand.prong0Id() || trackGlobalIndex == cand.prong1Id() || trackGlobalIndex == cand.prong2Id()) { + return false; + } + } else { // Check 2-prong + if (trackGlobalIndex == cand.prong0Id() || trackGlobalIndex == cand.prong1Id()) { + return false; + } } - std::vector outputMl = getCandMlScores(candidate); - rowCharmCandidatesMl(indexRedColl, outputMl[0], outputMl[1]); } + return true; } - /// Fill tracks tables - /// \param tracks are the selected tracks - template - void fillTracksTables(TTrack const& tracks) + /// Fill histograms and tables for same-event correlations + /// \param trigCands are the trigger candidates + /// \param assTrks are the associated tracks + /// \param collCentrality is the collision centrality + template + void fillSameEvent(TTrigCands const& trigCands, + TAssocTrks const& assTrks, + const float collCentrality) { - int indexRedColl = rowCollisions.lastIndex(); - for (const auto& track : tracks) { - if (!track.isGlobalTrackWoDCA()) { - continue; + for (const auto& trigCand : trigCands) { + double trigCandPt = trigCand.pt(); + registry.fill(HIST("hPhiVsPtTrig"), RecoDecay::constrainAngle(trigCand.phi(), -o2::constants::math::PIHalf), trigCandPt); + registry.fill(HIST("hEtaVsPtTrig"), trigCand.eta(), trigCandPt); + for (const auto& assTrk : assTrks) { + double assTrkPt = assTrk.pt(); + if (usePtDiffDcaXYCut) { + float dcaXYTrkCut = funcDcaXYPtCutPrimTrk->Eval(assTrkPt); + if (std::fabs(assTrk.dcaXY()) > dcaXYTrkCut) { + continue; + } + } + + double deltaEta = assTrk.eta() - trigCand.eta(); + if (!acceptSameEvtPair(assTrk, trigCand, deltaEta)) { + continue; + } + if (downSampleTrksFactor < 1.) { + float pseudoRndm = assTrkPt * 1000. - static_cast(assTrkPt * 1000); + if (assTrkPt < ptMaxForDownSample && collCentrality < centMaxForDownSample && pseudoRndm >= downSampleTrksFactor) { + continue; + } + } + registry.fill(HIST("hPhiVsPtTrigAssoc"), RecoDecay::constrainAngle(assTrk.phi(), -o2::constants::math::PIHalf), trigCandPt, assTrkPt); + registry.fill(HIST("hEtaVsPtTrigAssoc"), assTrk.eta(), trigCandPt, assTrkPt); + registry.fill(HIST("hPhiVsPtAssoc"), RecoDecay::constrainAngle(assTrk.phi(), -o2::constants::math::PIHalf), assTrkPt); + registry.fill(HIST("hEtaVsPtAssoc"), assTrk.eta(), assTrkPt); + registry.fill(HIST("hDcaXYVsPtAssoc"), assTrk.dcaXY(), assTrkPt); + registry.fill(HIST("hDcaZVsPtAssoc"), assTrk.dcaZ(), assTrkPt); + + double deltaPhi = RecoDecay::constrainAngle(assTrk.phi() - trigCand.phi(), -o2::constants::math::PIHalf); + rowSEPairs(rowCollisions.lastIndex(), trigCandPt, assTrkPt, deltaEta, deltaPhi); + rowAssocTrkSels(assTrk.tpcNClsCrossedRows(), assTrk.itsClusterMap(), assTrk.itsNCls(), assTrk.dcaXY(), assTrk.dcaZ()); + if constexpr (candType == CandType::Hadron) { + rowTrigHads(trigCand.tpcNClsCrossedRows(), trigCand.itsClusterMap(), trigCand.itsNCls(), trigCand.dcaXY(), trigCand.dcaZ()); + } else { + std::array outputMl = getCandMlScores(trigCand); + rowTrigCharms(getCandMass(trigCand), outputMl[0], outputMl[1]); + } } - rowAssocTrackReduced(indexRedColl, track.globalIndex(), track.phi(), track.eta(), track.pt()); - rowAssocTrackSelInfo(indexRedColl, track.tpcNClsCrossedRows(), track.itsClusterMap(), track.itsNCls(), track.dcaXY(), track.dcaZ()); } } - // Dplus with ML selections - void processDplusWithMl(CollsWithCentMult const& colls, - CandDplusDataWMl const& candsDplus, - TracksData const& tracks) + /// Fill charm hadron tables for mixed-event + /// \param trigCands are the charm trigger candidates + template + void fillCharmMixedEvent(TTrigCands const& trigCands) + { + for (const auto& trigCand : trigCands) { + registry.fill(HIST("hPhiVsPtTrig"), RecoDecay::constrainAngle(trigCand.phi(), -o2::constants::math::PIHalf), trigCand.pt()); + registry.fill(HIST("hEtaVsPtTrig"), trigCand.eta(), trigCand.pt()); + + std::array outputMl = getCandMlScores(trigCand); + rowTrigBases(rowCollisions.lastIndex(), trigCand.phi(), trigCand.eta(), trigCand.pt()); + rowTrigCharms(getCandMass(trigCand), outputMl[0], outputMl[1]); + } + } + + /// Fill track tables for mixed-event + /// \param assTrks are the associated tracks + /// \param collCentrality is the collision centrality + template + void fillTrkMixedEvent(TAssocTrks const& assTrks, + const float collCentrality) { - for (const auto& coll : colls) { - auto thisCollId = coll.globalIndex(); - auto candsCThisColl = candsDplus.sliceBy(candsDplusPerCollWMl, thisCollId); - if (forceCharmInCollision && candsCThisColl.size() < 1) { + bool first = true; + for (const auto& assTrk : assTrks) { + if (!assTrk.isGlobalTrackWoDCA() || assTrk.tpcNClsCrossedRows() < tpcNClsCrossedRowsMin) { continue; } - if (!checkAndFillCollision(coll)) { - continue; + double assTrkPt = assTrk.pt(); + if (usePtDiffDcaXYCut) { + float dcaXYTrkCut = funcDcaXYPtCutPrimTrk->Eval(assTrkPt); + if (std::fabs(assTrk.dcaXY()) > dcaXYTrkCut) { + continue; + } } - auto trackIdsThisColl = tracks.sliceBy(trackIndicesPerColl, thisCollId); - fillCharmHadronTables(candsCThisColl); - fillTracksTables(trackIdsThisColl); + if (!first && downSampleTrksFactor < 1.) { // skip downsampling for the first track to avoid empty tables + float pseudoRndm = assTrkPt * 1000. - static_cast(assTrkPt * 1000); + if (assTrkPt < ptMaxForDownSample && collCentrality < centMaxForDownSample && pseudoRndm >= downSampleTrksFactor) { + continue; + } + } + first = false; + registry.fill(HIST("hPhiVsPtAssoc"), RecoDecay::constrainAngle(assTrk.phi(), -o2::constants::math::PIHalf), assTrkPt); + registry.fill(HIST("hEtaVsPtAssoc"), assTrk.eta(), assTrkPt); + registry.fill(HIST("hDcaXYVsPtAssoc"), assTrk.dcaXY(), assTrkPt); + registry.fill(HIST("hDcaZVsPtAssoc"), assTrk.dcaZ(), assTrkPt); + rowAssocBases(rowCollisions.lastIndex(), assTrk.phi(), assTrk.eta(), assTrkPt); + rowAssocTrkSels(assTrk.tpcNClsCrossedRows(), assTrk.itsClusterMap(), assTrk.itsNCls(), assTrk.dcaXY(), assTrk.dcaZ()); + } + } + + // Dplus with ML selections + void processDplusSameEvent(CollsWithCentMult::iterator const& coll, + CandDplusData const& candsDplus, + TracksData const& tracks) + { + if (forceCharmInCollision && candsDplus.size() < 1) { + return; + } + float cent{-1.}, mult{-1.}; + if (!checkCollision(coll, cent, mult)) { + return; + } + rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); + fillSameEvent(candsDplus, tracks, cent); + } + PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processDplusSameEvent, "Process Same Event for Dplus candidates", true); + + // Dplus with ML selections + void processDplusMixedEvent(CollsWithCentMult::iterator const& coll, + CandDplusData const& candsDplus, + TracksData const& tracks) + { + if (forceCharmInCollision && candsDplus.size() < 1) { + return; + } + float cent{-1.}, mult{-1.}; + if (!checkCollision(coll, cent, mult)) { + return; } + rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); + fillCharmMixedEvent(candsDplus); + fillTrkMixedEvent(tracks, cent); } - PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processDplusWithMl, "Process Dplus candidates with ML info", false); + PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processDplusMixedEvent, "Process Mixed Event for Dplus candidates", false); // Ds with ML selections - void processDsWithMl(CollsWithCentMult const& colls, - TracksData const& tracks, - CandDsDataWMl const&) + void processDsSameEvent(CollsWithCentMult::iterator const& coll, + TracksData const& tracks, + CandDsData 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); + auto candsDsToPiKK = selectedDsToPiKK->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); + auto candsDsToKKPi = selectedDsToKKPi->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); + if (forceCharmInCollision && candsDsToPiKK.size() < 1 && candsDsToKKPi.size() < 1) { + return; } + float cent{-1.}, mult{-1.}; + if (!checkCollision(coll, cent, mult)) { + return; + } + rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); + fillSameEvent(candsDsToPiKK, tracks, cent); + fillSameEvent(candsDsToKKPi, tracks, cent); } - PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processDsWithMl, "Process Ds candidates with ML info", false); + PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processDsSameEvent, "Process Same Event for Ds candidates", false); + + // Ds with ML selections + void processDsMixedEvent(CollsWithCentMult::iterator const& coll, + TracksData const& tracks, + CandDsData const&) + { + auto candsDsToPiKK = selectedDsToPiKK->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); + auto candsDsToKKPi = selectedDsToKKPi->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); + if (forceCharmInCollision && candsDsToPiKK.size() < 1 && candsDsToKKPi.size() < 1) { + return; + } + float cent{-1.}, mult{-1.}; + if (!checkCollision(coll, cent, mult)) { + return; + } + rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); + fillCharmMixedEvent(candsDsToPiKK); + fillCharmMixedEvent(candsDsToKKPi); + fillTrkMixedEvent(tracks, cent); + } + PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processDsMixedEvent, "Process Mixed Event for Ds candidates", false); // D0 with ML selections - void processD0WithMl(CollsWithCentMult const& colls, - TracksData const& tracks, - CandD0DataWMl const&) + void processD0SameEvent(CollsWithCentMult::iterator const& coll, + TracksData const& tracks, + CandD0Data const&) { - for (const auto& coll : colls) { - auto thisCollId = coll.globalIndex(); - auto candsD0ToPiKWMl = selectedD0ToPiKWMl->sliceByCached(aod::hf_cand::collisionId, thisCollId, cache); - auto candsD0ToKPiWMl = selectedD0ToKPiWMl->sliceByCached(aod::hf_cand::collisionId, thisCollId, cache); - if (forceCharmInCollision && candsD0ToPiKWMl.size() < 1 && candsD0ToKPiWMl.size() < 1) { - continue; - } - if (!checkAndFillCollision(coll)) { - continue; - } - auto trackIdsThisColl = tracks.sliceBy(trackIndicesPerColl, thisCollId); - fillCharmHadronTables(candsD0ToPiKWMl); - fillCharmHadronTables(candsD0ToKPiWMl); - fillTracksTables(trackIdsThisColl); + auto candsD0ToPiK = selectedD0ToPiK->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); + auto candsD0ToKPi = selectedD0ToKPi->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); + if (forceCharmInCollision && candsD0ToPiK.size() < 1 && candsD0ToKPi.size() < 1) { + return; + } + float cent{-1.}, mult{-1.}; + if (!checkCollision(coll, cent, mult)) { + return; + } + rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); + fillSameEvent(candsD0ToPiK, tracks, cent); + fillSameEvent(candsD0ToKPi, tracks, cent); + } + PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processD0SameEvent, "Process Same Event for D0 candidates", false); + + // D0 with ML selections + void processD0MixedEvent(CollsWithCentMult::iterator const& coll, + TracksData const& tracks, + CandD0Data const&) + { + auto candsD0ToPiK = selectedD0ToPiK->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); + auto candsD0ToKPi = selectedD0ToKPi->sliceByCached(aod::hf_cand::collisionId, coll.globalIndex(), cache); + if (forceCharmInCollision && candsD0ToPiK.size() < 1 && candsD0ToKPi.size() < 1) { + return; + } + float cent{-1.}, mult{-1.}; + if (!checkCollision(coll, cent, mult)) { + return; + } + rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); + fillCharmMixedEvent(candsD0ToPiK); + fillCharmMixedEvent(candsD0ToKPi); + fillTrkMixedEvent(tracks, cent); + } + PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processD0MixedEvent, "Process Mixed Event for D0 candidates", false); + + // Hadron Hadron Same Event + void processHadronHadronSameEvent(CollsWithCentMult::iterator const& coll, + TracksData const& tracks) + { + float cent{-1.}, mult{-1.}; + if (!checkCollision(coll, cent, mult)) { + return; + } + rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); + fillSameEvent(tracks, tracks, cent); + } + PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processHadronHadronSameEvent, "Process Same Event for hadron candidates", true); + + // Hadron Hadron Mixed Event + void processHadronHadronMixedEvent(CollsWithCentMult::iterator const& coll, + TracksData const& tracks) + { + float cent{-1.}, mult{-1.}; + if (!checkCollision(coll, cent, mult)) { + return; } + rowCollisions(mult, coll.numContrib(), cent, coll.posZ()); + fillTrkMixedEvent(tracks, cent); } - PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processD0WithMl, "Process D0 candidates with ML info", false); + PROCESS_SWITCH(HfDerivedDataCreatorCorrelationsReduced, processHadronHadronMixedEvent, "Process Mixed Event for hadron candidates", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc)