diff --git a/PWGHF/HFC/TableProducer/producerCharmHadronsCharmFemtoDream.cxx b/PWGHF/HFC/TableProducer/producerCharmHadronsCharmFemtoDream.cxx index 84d6b21d897..848a74fcfca 100644 --- a/PWGHF/HFC/TableProducer/producerCharmHadronsCharmFemtoDream.cxx +++ b/PWGHF/HFC/TableProducer/producerCharmHadronsCharmFemtoDream.cxx @@ -26,6 +26,7 @@ #include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" +#include "Tools/ML/MlResponse.h" #include #include @@ -43,7 +44,6 @@ #include #include #include -#include #include #include @@ -67,40 +67,40 @@ struct HfProducerCharmHadronsCharmFemtoDream { Configurable ccdbUrl{"ccdbUrl", "http://alice-ccdb.cern.ch", "CCDB URL"}; Configurable ccdbPathGrpMag{ - "ccdbPathGrpMag", "GLO/Config/GRPMagField", "Run 3 magnetic field"}; + "ccdbPathGrpMag", "GLO/Config/GRPMagField", "Run 3 magnetic field"}; // Each species needs its own model, feature order and pT-dependent cuts. struct MlConfig : ConfigurableGroup { std::string prefix; static inline const std::array DefaultCuts{1., 0., 0.}; Configurable applyMlMode{ - "applyMlMode", FillMlFromSelector, - "0: no ML, 1: selector scores, 2: new BDT after selector"}; + "applyMlMode", FillMlFromSelector, + "0: no ML, 1: selector scores, 2: new BDT after selector"}; Configurable> binsPtMl{ - "binsPtMl", std::vector{0., 36.}, "pT bin limits for new BDT"}; + "binsPtMl", std::vector{0., 36.}, "pT bin limits for new BDT"}; Configurable> cutsMl{ - "cutsMl", - {DefaultCuts.data(), 1, 3}, - "New BDT cuts per pT bin: background, prompt, nonprompt"}; + "cutsMl", + {DefaultCuts.data(), 1, 3}, + "New BDT cuts per pT bin: background, prompt, nonprompt"}; Configurable> cutDirMl{ - "cutDirMl", std::vector{0, 1, 1}, - "Reject scores above (0), below (1), or do not cut (2)"}; + "cutDirMl", std::vector{0, 1, 1}, + "Reject scores above (0), below (1), or do not cut (2)"}; Configurable nClassesMl{ - "nClassesMl", 3, "Three output classes: background, prompt, nonprompt"}; + "nClassesMl", 3, "Three output classes: background, prompt, nonprompt"}; Configurable> namesInputFeatures{ - "namesInputFeatures", std::vector{}, - "Ordered input feature names for new BDT"}; + "namesInputFeatures", std::vector{}, + "Ordered input feature names for new BDT"}; Configurable> onnxFileNames{ - "onnxFileNames", std::vector{}, - "Model files, one per pT bin"}; + "onnxFileNames", std::vector{}, + "Model files, one per pT bin"}; Configurable> modelPathsCCDB{ - "modelPathsCCDB", std::vector{}, - "CCDB model paths, one per pT bin"}; + "modelPathsCCDB", std::vector{}, + "CCDB model paths, one per pT bin"}; Configurable timestampCCDB{"timestampCCDB", -1, "Timestamp used to retrieve models"}; Configurable loadModelsFromCCDB{ - "loadModelsFromCCDB", false, - "Load new BDT from CCDB instead of local files"}; + "loadModelsFromCCDB", false, + "Load new BDT from CCDB instead of local files"}; } mlD0{.prefix = "mlD0"}, mlDstar{.prefix = "mlDstar"}; Produces collisions; Produces rowMasks; @@ -122,20 +122,21 @@ struct HfProducerCharmHadronsCharmFemtoDream { using CollisionsWithFT0C = soa::Join; using D0s = soa::Join; using Dstars = - soa::Join; + soa::Join; using D0sMl = soa::Join; using DstarsMl = soa::Join; Filter filterSelectCandidateD0 = - (aod::hf_sel_candidate_d0::isSelD0 >= selectionFlagD0 || - aod::hf_sel_candidate_d0::isSelD0bar >= selectionFlagD0); + (aod::hf_sel_candidate_d0::isSelD0 >= selectionFlagD0 || + aod::hf_sel_candidate_d0::isSelD0bar >= selectionFlagD0); Filter filterSelectCandidateDstar = - aod::hf_sel_candidate_dstar::isSelDstarToD0Pi == true; + aod::hf_sel_candidate_dstar::isSelDstarToD0Pi == true; template - void initMl(MlConfig const &cfg, Response &response, bool withMl) { + void initMl(MlConfig const& cfg, Response& response, bool withMl) + { if (cfg.applyMlMode.value < NoMl || cfg.applyMlMode.value > FillMlFromNewBDT) { LOGP(fatal, "{}: invalid applyMlMode", cfg.prefix); @@ -146,7 +147,7 @@ struct HfProducerCharmHadronsCharmFemtoDream { if (!withMl) { LOGP(fatal, "{}: new BDT requires an Ml producer process", cfg.prefix); } - auto const &edges = cfg.binsPtMl.value; + auto const& edges = cfg.binsPtMl.value; if (edges.size() < 2 || !std::all_of(edges.begin(), edges.end(), [](double x) { return std::isfinite(x); }) || @@ -195,16 +196,17 @@ struct HfProducerCharmHadronsCharmFemtoDream { response.init(); } - void init(InitContext const &) { + void init(InitContext const&) + { const std::array processSwitches{ - static_cast(doprocessD0D0), - static_cast(doprocessD0Dstar), - static_cast(doprocessD0D0Ml), - static_cast(doprocessD0DstarMl), - static_cast(doprocessD0D0WithFT0C), - static_cast(doprocessD0DstarWithFT0C), - static_cast(doprocessD0D0MlWithFT0C), - static_cast(doprocessD0DstarMlWithFT0C)}; + static_cast(doprocessD0D0), + static_cast(doprocessD0Dstar), + static_cast(doprocessD0D0Ml), + static_cast(doprocessD0DstarMl), + static_cast(doprocessD0D0WithFT0C), + static_cast(doprocessD0DstarWithFT0C), + static_cast(doprocessD0D0MlWithFT0C), + static_cast(doprocessD0DstarMlWithFT0C)}; if (std::count(processSwitches.begin(), processSwitches.end(), true) != 1) { LOGP(fatal, "Enable exactly one charm-charm producer process"); } @@ -230,11 +232,12 @@ struct HfProducerCharmHadronsCharmFemtoDream { template - bool acceptCollision(Collision const &col) { + bool acceptCollision(Collision const& col) + { registry.fill(HIST("events"), 0); float cent = -1.f; // No centrality for pp MB. const auto rejectionMask = hfEvSel.getHfCollisionRejectionMask< - true, CentEstimator, aod::BCsWithTimestamps>(col, cent, ccdb, registry); + true, CentEstimator, aod::BCsWithTimestamps>(col, cent, ccdb, registry); hfEvSel.fillHistograms(col, rejectionMask, cent); if (rejectionMask != 0) { return false; @@ -245,7 +248,7 @@ struct HfProducerCharmHadronsCharmFemtoDream { initCCDB(bc, runNumber, ccdb, ccdbPathGrpMag.value, nullptr, false); // Propagator field is in kG; FemtoDream uses Tesla. const float fieldTesla = - 0.1f * o2::base::Propagator::Instance()->getNominalBz(); + 0.1f * o2::base::Propagator::Instance()->getNominalBz(); // MultV0M is the common reduced percentile column: FT0C or -1 (no // estimator). collisions(col.posZ(), cent, col.multNTracksPV(), 2.f, fieldTesla); @@ -255,7 +258,8 @@ struct HfProducerCharmHadronsCharmFemtoDream { } template - std::array readScores(Scores const &scores) { + std::array readScores(Scores const& scores) + { if (scores.size() != 3) { LOGP(fatal, "Expected three selector ML scores: background, prompt, nonprompt"); @@ -270,10 +274,11 @@ struct HfProducerCharmHadronsCharmFemtoDream { } template - void fillD0(Collision const &col, Candidates const &candidates) { + void fillD0(Collision const& col, Candidates const& candidates) + { const auto timestamp = - col.template bc_as().timestamp(); - for (auto const &cand : candidates) { + col.template bc_as().timestamp(); + for (auto const& cand : candidates) { auto p0 = cand.template prong0_as(); auto p1 = cand.template prong1_as(); // The OR filter accepts the row if either hypothesis passes. Write only @@ -299,7 +304,7 @@ struct HfProducerCharmHadronsCharmFemtoDream { const int pdgCode = hypothesis == 0 ? o2::constants::physics::kD0 : -o2::constants::physics::kD0; auto features = - hfMlResponseD0.getInputFeatures(cand, pdgCode); + hfMlResponseD0.getInputFeatures(cand, pdgCode); std::vector output; if (!hfMlResponseD0.isSelectedMl(features, cand.pt(), output)) { continue; // Reject this hypothesis only. @@ -318,10 +323,11 @@ struct HfProducerCharmHadronsCharmFemtoDream { } template - void fillDstar(Collision const &col, Candidates const &candidates) { + void fillDstar(Collision const& col, Candidates const& candidates) + { const auto timestamp = - col.template bc_as().timestamp(); - for (auto const &cand : candidates) { + col.template bc_as().timestamp(); + for (auto const& cand : candidates) { auto p0 = cand.template prong0_as(); auto p1 = cand.template prong1_as(); auto soft = cand.template prongPi_as(); @@ -354,9 +360,10 @@ struct HfProducerCharmHadronsCharmFemtoDream { } } - void processD0D0(Collisions::iterator const &col, - aod::BCsWithTimestamps const &, aod::Tracks const &, - soa::Filtered const &d0s) { + void processD0D0(Collisions::iterator const& col, + aod::BCsWithTimestamps const&, aod::Tracks const&, + soa::Filtered const& d0s) + { if (acceptCollision(col)) { fillD0(col, d0s); rowMasks(hasD0 ? 1 : 0, hasDstar ? 1 : 0, 0); @@ -365,10 +372,11 @@ struct HfProducerCharmHadronsCharmFemtoDream { PROCESS_SWITCH(HfProducerCharmHadronsCharmFemtoDream, processD0D0, "D0 only, data", true); - void processD0Dstar(Collisions::iterator const &col, - aod::BCsWithTimestamps const &, aod::Tracks const &, - soa::Filtered const &d0s, - soa::Filtered const &dstars) { + void processD0Dstar(Collisions::iterator const& col, + aod::BCsWithTimestamps const&, aod::Tracks const&, + soa::Filtered const& d0s, + soa::Filtered const& dstars) + { if (acceptCollision(col)) { fillD0(col, d0s); fillDstar(col, dstars); @@ -378,9 +386,10 @@ struct HfProducerCharmHadronsCharmFemtoDream { PROCESS_SWITCH(HfProducerCharmHadronsCharmFemtoDream, processD0Dstar, "D0 and Dstar, data", false); - void processD0D0Ml(Collisions::iterator const &col, - aod::BCsWithTimestamps const &, aod::Tracks const &, - soa::Filtered const &d0s) { + void processD0D0Ml(Collisions::iterator const& col, + aod::BCsWithTimestamps const&, aod::Tracks const&, + soa::Filtered const& d0s) + { if (acceptCollision(col)) { fillD0(col, d0s); rowMasks(hasD0 ? 1 : 0, hasDstar ? 1 : 0, 0); @@ -389,10 +398,11 @@ struct HfProducerCharmHadronsCharmFemtoDream { PROCESS_SWITCH(HfProducerCharmHadronsCharmFemtoDream, processD0D0Ml, "D0 with selector ML scores", false); - void processD0DstarMl(Collisions::iterator const &col, - aod::BCsWithTimestamps const &, aod::Tracks const &, - soa::Filtered const &d0s, - soa::Filtered const &dstars) { + void processD0DstarMl(Collisions::iterator const& col, + aod::BCsWithTimestamps const&, aod::Tracks const&, + soa::Filtered const& d0s, + soa::Filtered const& dstars) + { if (acceptCollision(col)) { fillD0(col, d0s); fillDstar(col, dstars); @@ -402,9 +412,10 @@ struct HfProducerCharmHadronsCharmFemtoDream { PROCESS_SWITCH(HfProducerCharmHadronsCharmFemtoDream, processD0DstarMl, "D0 and Dstar with selector ML scores", false); - void processD0D0WithFT0C(CollisionsWithFT0C::iterator const &col, - aod::BCsWithTimestamps const &, aod::Tracks const &, - soa::Filtered const &d0s) { + void processD0D0WithFT0C(CollisionsWithFT0C::iterator const& col, + aod::BCsWithTimestamps const&, aod::Tracks const&, + soa::Filtered const& d0s) + { if (acceptCollision(col)) { fillD0(col, d0s); rowMasks(hasD0 ? 1 : 0, hasDstar ? 1 : 0, 0); @@ -413,11 +424,12 @@ struct HfProducerCharmHadronsCharmFemtoDream { PROCESS_SWITCH(HfProducerCharmHadronsCharmFemtoDream, processD0D0WithFT0C, "D0 only, data with FT0C centrality", false); - void processD0DstarWithFT0C(CollisionsWithFT0C::iterator const &col, - aod::BCsWithTimestamps const &, - aod::Tracks const &, - soa::Filtered const &d0s, - soa::Filtered const &dstars) { + void processD0DstarWithFT0C(CollisionsWithFT0C::iterator const& col, + aod::BCsWithTimestamps const&, + aod::Tracks const&, + soa::Filtered const& d0s, + soa::Filtered const& dstars) + { if (acceptCollision(col)) { fillD0(col, d0s); fillDstar(col, dstars); @@ -427,10 +439,11 @@ struct HfProducerCharmHadronsCharmFemtoDream { PROCESS_SWITCH(HfProducerCharmHadronsCharmFemtoDream, processD0DstarWithFT0C, "D0 and Dstar, data with FT0C centrality", false); - void processD0D0MlWithFT0C(CollisionsWithFT0C::iterator const &col, - aod::BCsWithTimestamps const &, - aod::Tracks const &, - soa::Filtered const &d0s) { + void processD0D0MlWithFT0C(CollisionsWithFT0C::iterator const& col, + aod::BCsWithTimestamps const&, + aod::Tracks const&, + soa::Filtered const& d0s) + { if (acceptCollision(col)) { fillD0(col, d0s); rowMasks(hasD0 ? 1 : 0, hasDstar ? 1 : 0, 0); @@ -439,11 +452,12 @@ struct HfProducerCharmHadronsCharmFemtoDream { PROCESS_SWITCH(HfProducerCharmHadronsCharmFemtoDream, processD0D0MlWithFT0C, "D0 with selector ML scores and FT0C centrality", false); - void processD0DstarMlWithFT0C(CollisionsWithFT0C::iterator const &col, - aod::BCsWithTimestamps const &, - aod::Tracks const &, - soa::Filtered const &d0s, - soa::Filtered const &dstars) { + void processD0DstarMlWithFT0C(CollisionsWithFT0C::iterator const& col, + aod::BCsWithTimestamps const&, + aod::Tracks const&, + soa::Filtered const& d0s, + soa::Filtered const& dstars) + { if (acceptCollision(col)) { fillD0(col, d0s); fillDstar(col, dstars); @@ -456,7 +470,8 @@ struct HfProducerCharmHadronsCharmFemtoDream { false); }; -WorkflowSpec defineDataProcessing(ConfigContext const &cfgc) { +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ return WorkflowSpec{ - adaptAnalysisTask(cfgc)}; + adaptAnalysisTask(cfgc)}; } diff --git a/PWGHF/HFC/Tasks/taskCharmHadronsCharmFemtoDream.cxx b/PWGHF/HFC/Tasks/taskCharmHadronsCharmFemtoDream.cxx index c8cf10f3d77..6f01cc5678c 100644 --- a/PWGHF/HFC/Tasks/taskCharmHadronsCharmFemtoDream.cxx +++ b/PWGHF/HFC/Tasks/taskCharmHadronsCharmFemtoDream.cxx @@ -84,12 +84,12 @@ struct HfTaskCharmHadronsCharmFemtoDream { Configurable minPromptDstar{"minPromptDstar", 0.f, "Minimum Dstar prompt score"}; Configurable charmHadCandSel{ - "charmHadCandSel", 1, "Minimum reduced charm candidate selection flag"}; + "charmHadCandSel", 1, "Minimum reduced charm candidate selection flag"}; struct : ConfigurableGroup { std::string prefix = "eventSel"; Configurable useCentrality{ - "useCentrality", false, - "Apply percentile selection (requires a centrality-enabled producer)"}; + "useCentrality", false, + "Apply percentile selection (requires a centrality-enabled producer)"}; Configurable multMin{"multMin", 0, "Minimum multiplicity (MultNtr)"}; Configurable multMax{"multMax", 99999, "Maximum multiplicity (MultNtr)"}; @@ -102,7 +102,7 @@ struct HfTaskCharmHadronsCharmFemtoDream { struct : ConfigurableGroup { Configurable doMixEvent{"doMixEvent", true, "Enable mixed events"}; Configurable mixingBinPolicy{ - "mixingBinPolicy", 0, "0: multiplicity, 1: percentile, 2: both"}; + "mixingBinPolicy", 0, "0: multiplicity, 1: percentile, 2: both"}; Configurable mixingDepth{"mixingDepth", 5, "Number of neighbours for O2 event mixing"}; } mixSetting; @@ -110,59 +110,61 @@ struct HfTaskCharmHadronsCharmFemtoDream { {VARIABLE_WIDTH, 0.f, 20.f, 60.f, 200.f}, "Mixing bins - multiplicity"}; ConfigurableAxis mixingBinMultPercentile{ - "mixingBinMultPercentile", - {VARIABLE_WIDTH, 0.f, 100.f}, - "Mixing bins - multiplicity percentile"}; + "mixingBinMultPercentile", + {VARIABLE_WIDTH, 0.f, 100.f}, + "Mixing bins - multiplicity percentile"}; ConfigurableAxis mixingBinVztx{"mixingBinVztx", {VARIABLE_WIDTH, -10.f, -4.f, 0.f, 4.f, 10.f}, "Mixing bins - z-vertex"}; ColumnBinningPolicy - colBinningMult{{mixingBinVztx, mixingBinMult}, true}; + colBinningMult{{mixingBinVztx, mixingBinMult}, true}; ColumnBinningPolicy - colBinningMultPercentile{{mixingBinVztx, mixingBinMultPercentile}, true}; + colBinningMultPercentile{{mixingBinVztx, mixingBinMultPercentile}, true}; ColumnBinningPolicy - colBinningMultMultPercentile{ - {mixingBinVztx, mixingBinMult, mixingBinMultPercentile}, true}; + colBinningMultMultPercentile{ + {mixingBinVztx, mixingBinMult, mixingBinMultPercentile}, + true}; aod::femtodreamcollision::BitMaskType bitMask = 1 << 0; using FilteredCollisions = - soa::Filtered>; + soa::Filtered>; using FilteredCharmCand2Prongs = soa::Filtered; using FilteredCharmCandDstars = soa::Filtered; Filter eventMultiplicity = - aod::femtodreamcollision::multNtr >= eventSel.multMin && - aod::femtodreamcollision::multNtr <= eventSel.multMax; + aod::femtodreamcollision::multNtr >= eventSel.multMin && + aod::femtodreamcollision::multNtr <= eventSel.multMax; Filter eventMultiplicityPercentile = ifnode( - eventSel.useCentrality, - aod::femtodreamcollision::multV0M >= eventSel.multPercentileMin && - aod::femtodreamcollision::multV0M <= eventSel.multPercentileMax, - Node{LiteralNode{true}}); + eventSel.useCentrality, + aod::femtodreamcollision::multV0M >= eventSel.multPercentileMin && + aod::femtodreamcollision::multV0M <= eventSel.multPercentileMax, + Node{LiteralNode{true}}); Filter hfCandSelFilter = aod::fdhf::candidateSelFlag >= charmHadCandSel; Partition partitionCharmHadron2Prong = ifnode( - useMl, - aod::fdhf::bdtBkg <= maxBkgD0 && aod::fdhf::bdtPrompt >= minPromptD0, - Node{LiteralNode{true}}); + useMl, + aod::fdhf::bdtBkg <= maxBkgD0 && aod::fdhf::bdtPrompt >= minPromptD0, + Node{LiteralNode{true}}); Partition partitionCharmHadronDstar = - ifnode(useMl, - aod::fdhf::bdtBkg <= maxBkgDstar && - aod::fdhf::bdtPrompt >= minPromptDstar, - Node{LiteralNode{true}}); + ifnode(useMl, + aod::fdhf::bdtBkg <= maxBkgDstar && + aod::fdhf::bdtPrompt >= minPromptDstar, + Node{LiteralNode{true}}); // Full-table process inputs do not automatically register grouping caches. // Register both keys explicitly for the sliceByCached calls below. Preslice perCollisionD0 = - aod::femtodreamparticle::fdCollisionId; + aod::femtodreamparticle::fdCollisionId; Preslice perCollisionDstar = - aod::femtodreamparticle::fdCollisionId; + aod::femtodreamparticle::fdCollisionId; SliceCache cache; HistogramRegistry registry{"registry"}; Produces rowFemtoResultCharm2Prong; Produces rowFemtoResultCharmDstar; Produces rowFemtoResultColl; - void init(InitContext const &) { + void init(InitContext const&) + { if (doprocessD0D0 == doprocessD0Dstar) { LOGP(fatal, "Enable exactly one charm-charm analysis process"); } @@ -178,7 +180,7 @@ struct HfTaskCharmHadronsCharmFemtoDream { colBinningMult = {{mixingBinVztx, mixingBinMult}, true}; colBinningMultPercentile = {{mixingBinVztx, mixingBinMultPercentile}, true}; colBinningMultMultPercentile = { - {mixingBinVztx, mixingBinMult, mixingBinMultPercentile}, true}; + {mixingBinVztx, mixingBinMult, mixingBinMultPercentile}, true}; const AxisSpec kstar{400, 0., 2., "k* (GeV/c)"}; const AxisSpec massD0{300, massMinD0.value, massMaxD0.value, "M(Kpi) (GeV/c2)"}; @@ -215,7 +217,8 @@ struct HfTaskCharmHadronsCharmFemtoDream { } template - static bool sharesDaughter(D0Row const &a, OtherRow const &b) { + static bool sharesDaughter(D0Row const& a, OtherRow const& b) + { for (auto id : std::array{a.prong0Id(), a.prong1Id()}) { if (id < 0) { continue; @@ -234,11 +237,12 @@ struct HfTaskCharmHadronsCharmFemtoDream { // D0 charge denotes flavour, not electric charge. template - static PairChannel pairChannel(D0Row const &d0, OtherRow const &other) { + static PairChannel pairChannel(D0Row const& d0, OtherRow const& other) + { if constexpr (!IsDstar) { return d0.charge() != other.charge() - ? D0D0barUnlikeSign - : (d0.charge() > 0 ? D0D0LikeSign : D0barD0barLikeSign); + ? D0D0barUnlikeSign + : (d0.charge() > 0 ? D0D0LikeSign : D0barD0barLikeSign); } return d0.charge() > 0 ? (other.charge() > 0 ? D0DstarPlusLikeSign : D0DstarMinusUnlikeSign) @@ -249,7 +253,8 @@ struct HfTaskCharmHadronsCharmFemtoDream { // Canonical ordering keeps mass/pt axes independent of event ordering for // D0D0. template - static bool reverseD0Order(FirstRow const &first, SecondRow const &second) { + static bool reverseD0Order(FirstRow const& first, SecondRow const& second) + { if (first.charge() != second.charge()) { return first.charge() < second.charge(); // D0 first for D0-D0bar } @@ -257,21 +262,24 @@ struct HfTaskCharmHadronsCharmFemtoDream { } template - void validateMlScores(Candidates const &candidates) { + void validateMlScores(Candidates const& candidates) + { if (!useMl) { return; } - for (auto const &row : candidates) { + for (auto const& row : candidates) { if (!std::isfinite(row.bdtBkg()) || !std::isfinite(row.bdtPrompt()) || row.bdtBkg() < 0.f || row.bdtPrompt() < 0.f) { - LOGP(fatal, "ML cuts requested on missing/invalid scores: use an ML " - "producer process"); + LOGP(fatal, + "ML cuts requested on missing/invalid scores: use an ML " + "producer process"); } } } template - bool select(Row const &row, float &mass) { + bool select(Row const& row, float& mass) + { if (std::abs(row.charge()) != 1 || !std::isfinite(row.pt()) || !std::isfinite(row.eta()) || !std::isfinite(row.phi()) || std::abs(row.eta()) >= etaMax || @@ -280,8 +288,8 @@ struct HfTaskCharmHadronsCharmFemtoDream { return false; } const std::array masses = - row.charge() > 0 ? std::array{MassPiPlus, MassKPlus} - : std::array{MassKPlus, MassPiPlus}; + row.charge() > 0 ? std::array{MassPiPlus, MassKPlus} + : std::array{MassKPlus, MassPiPlus}; if constexpr (IsDstar) { const float daughterMass = row.mDaughD0(masses); if (!std::isfinite(daughterMass) || daughterMass < daughterMassMin || @@ -310,8 +318,9 @@ struct HfTaskCharmHadronsCharmFemtoDream { } template - void fillPair(FirstRow const &first, SecondRow const &second, float firstMass, - float secondMass, float mult) { + void fillPair(FirstRow const& first, SecondRow const& second, float firstMass, + float secondMass, float mult) + { if constexpr (!Mixed) { if (sharesDaughter(first, second)) { registry.fill(HIST("QA/sharedDaughters"), IsDstar ? 1 : 0); @@ -326,9 +335,9 @@ struct HfTaskCharmHadronsCharmFemtoDream { // Read kinematics directly from the candidate rows. Only D0D0 can reverse; // its two nominal parent masses are equal. Never use Dstar delta mass here. const float kstar = - reverse ? FemtoDreamMath::getkstar(second, MassD0, first, MassD0) - : FemtoDreamMath::getkstar(first, MassD0, second, - IsDstar ? MassDStar : MassD0); + reverse ? FemtoDreamMath::getkstar(second, MassD0, first, MassD0) + : FemtoDreamMath::getkstar(first, MassD0, second, + IsDstar ? MassDStar : MassD0); if (!std::isfinite(kstar)) { return; } @@ -349,33 +358,35 @@ struct HfTaskCharmHadronsCharmFemtoDream { } template - int mixingBin(Policy const &policy, Collision col) { + int mixingBin(Policy const& policy, Collision col) + { return policy.getBin(policy.getBinningValues(col)); } template - void doMixedEvent(FilteredCollisions const &cols, D0Table const &d0Rows, - OtherTable const &otherRows, Policy const &policy) { + void doMixedEvent(FilteredCollisions const& cols, D0Table const& d0Rows, + OtherTable const& otherRows, Policy const& policy) + { Partition partitionMaskedCol1 = - (aod::femtodreamcollision::bitmaskTrackOne & bitMask) == bitMask; + (aod::femtodreamcollision::bitmaskTrackOne & bitMask) == bitMask; // TrackOne denotes D0 presence, TrackTwo denotes Dstar presence. Partition partitionMaskedCol2 = - (aod::femtodreamcollision::bitmaskTrackOne & bitMask) == bitMask; + (aod::femtodreamcollision::bitmaskTrackOne & bitMask) == bitMask; Partition partitionMaskedColDstar = - (aod::femtodreamcollision::bitmaskTrackTwo & bitMask) == bitMask; + (aod::femtodreamcollision::bitmaskTrackTwo & bitMask) == bitMask; partitionMaskedCol1.bindTable(cols); if constexpr (IsDstar) { partitionMaskedColDstar.bindTable(cols); } else { partitionMaskedCol2.bindTable(cols); } - auto const &secondCollisions = IsDstar ? *partitionMaskedColDstar.mFiltered + auto const& secondCollisions = IsDstar ? *partitionMaskedColDstar.mFiltered : *partitionMaskedCol2.mFiltered; - for (auto const &[collision1, collision2] : + for (auto const& [collision1, collision2] : combinations(soa::CombinationsBlockFullIndexPolicy( - policy, mixSetting.mixingDepth, -1, *partitionMaskedCol1.mFiltered, - secondCollisions))) { + policy, mixSetting.mixingDepth, -1, *partitionMaskedCol1.mFiltered, + secondCollisions))) { if (collision1.globalIndex() == collision2.globalIndex()) { continue; } @@ -400,11 +411,11 @@ struct HfTaskCharmHadronsCharmFemtoDream { auto first = d0Rows.sliceByCached(aod::femtodreamparticle::fdCollisionId, collision1.globalIndex(), cache); auto second = - otherRows.sliceByCached(aod::femtodreamparticle::fdCollisionId, - collision2.globalIndex(), cache); + otherRows.sliceByCached(aod::femtodreamparticle::fdCollisionId, + collision2.globalIndex(), cache); // Species roles remain fixed; the full policy supplies the reverse event // orientation when eligible. Do not add a second manual reverse loop. - for (auto const &[row1, row2] : + for (auto const& [row1, row2] : combinations(soa::CombinationsFullIndexPolicy(first, second))) { float mass1{}, mass2{}; if (select(row1, mass1) && select(row2, mass2)) { @@ -419,8 +430,9 @@ struct HfTaskCharmHadronsCharmFemtoDream { // Reuse the same output tables and field conventions as the track/V0 tasks. template - void fillTables(CollType const &col, D0Slice const &d0s, - DstarSlice const &dstars) { + void fillTables(CollType const& col, D0Slice const& d0s, + DstarSlice const& dstars) + { int64_t timeStamp = -1; bool hasCandidate = false; auto recordTimeStamp = [&](int64_t value) { @@ -430,7 +442,7 @@ struct HfTaskCharmHadronsCharmFemtoDream { timeStamp = value; hasCandidate = true; }; - for (auto const &part : d0s) { + for (auto const& part : d0s) { float mass{}; if (!select(part, mass)) { continue; @@ -442,21 +454,21 @@ struct HfTaskCharmHadronsCharmFemtoDream { part.bdtPrompt(), part.bdtFD(), 0, 0); } if constexpr (WithDstar) { - for (auto const &part : dstars) { + for (auto const& part : dstars) { float mass{}; if (!select(part, mass)) { continue; } recordTimeStamp(part.timeStamp()); const std::array daughterMasses = - part.charge() > 0 ? std::array{MassPiPlus, MassKPlus} - : std::array{MassKPlus, MassPiPlus}; + part.charge() > 0 ? std::array{MassPiPlus, MassKPlus} + : std::array{MassKPlus, MassPiPlus}; // CharmM is delta mass, CharmDaughM is M(Kpi), as in D+Track. rowFemtoResultCharmDstar( - col.globalIndex(), timeStamp, mass, part.mDaughD0(daughterMasses), - part.pt(), part.eta(), part.phi(), part.prong0Id(), part.prong1Id(), - part.prong2Id(), part.charge(), part.bdtBkg(), part.bdtPrompt(), - part.bdtFD(), 0, 0); + col.globalIndex(), timeStamp, mass, part.mDaughD0(daughterMasses), + part.pt(), part.eta(), part.phi(), part.prong0Id(), part.prong1Id(), + part.prong2Id(), part.charge(), part.bdtBkg(), part.bdtPrompt(), + part.bdtFD(), 0, 0); } } // Retain D0-only/Dstar-only events even when no clean SE pair exists. @@ -469,16 +481,17 @@ struct HfTaskCharmHadronsCharmFemtoDream { template - void runWithPolicy(FilteredCollisions const &cols, D0Table const &d0Rows, - DstarTable const &dstarRows, Policy const &policy) { - for (auto const &col : cols) { + void runWithPolicy(FilteredCollisions const& cols, D0Table const& d0Rows, + DstarTable const& dstarRows, Policy const& policy) + { + for (auto const& col : cols) { auto d0s = d0Rows.sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); // Export before online mixing-bin cuts, so offline mixing can change // bins. if constexpr (WithDstar) { auto dstars = dstarRows.sliceByCached( - aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); + aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); fillTables(col, d0s, dstars); } else { fillTables(col, d0s, d0s); @@ -490,7 +503,7 @@ struct HfTaskCharmHadronsCharmFemtoDream { } registry.fill(HIST("QA/events"), 0); registry.fill(HIST("MixingQA/hSECollisionBins"), bin); - for (auto const &[row1, row2] : + for (auto const& [row1, row2] : combinations(soa::CombinationsStrictlyUpperIndexPolicy(d0s, d0s))) { float mass1{}, mass2{}; if (select(row1, mass1) && select(row2, mass2)) { @@ -499,8 +512,8 @@ struct HfTaskCharmHadronsCharmFemtoDream { } if constexpr (WithDstar) { auto dstars = dstarRows.sliceByCached( - aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); - for (auto const &[row1, row2] : + aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); + for (auto const& [row1, row2] : combinations(soa::CombinationsFullIndexPolicy(d0s, dstars))) { float mass1{}, mass2{}; if (select(row1, mass1) && select(row2, mass2)) { @@ -518,9 +531,10 @@ struct HfTaskCharmHadronsCharmFemtoDream { } template - void run(FilteredCollisions const &cols, - FilteredCharmCand2Prongs const &d0Rows, - DstarTable const &dstarRows) { + void run(FilteredCollisions const& cols, + FilteredCharmCand2Prongs const& d0Rows, + DstarTable const& dstarRows) + { validateMlScores(d0Rows); partitionCharmHadron2Prong.bindTable(d0Rows); if constexpr (WithDstar) { @@ -528,42 +542,45 @@ struct HfTaskCharmHadronsCharmFemtoDream { partitionCharmHadronDstar.bindTable(dstarRows); } switch (mixSetting.mixingBinPolicy) { - case aod::femtodreamcollision::kMult: - runWithPolicy(cols, partitionCharmHadron2Prong, - partitionCharmHadronDstar, colBinningMult); - break; - case aod::femtodreamcollision::kMultPercentile: - runWithPolicy(cols, partitionCharmHadron2Prong, - partitionCharmHadronDstar, - colBinningMultPercentile); - break; - case aod::femtodreamcollision::kMultMultPercentile: - runWithPolicy(cols, partitionCharmHadron2Prong, - partitionCharmHadronDstar, - colBinningMultMultPercentile); - break; - default: - LOGP(fatal, "Invalid mixing binning policy"); + case aod::femtodreamcollision::kMult: + runWithPolicy(cols, partitionCharmHadron2Prong, + partitionCharmHadronDstar, colBinningMult); + break; + case aod::femtodreamcollision::kMultPercentile: + runWithPolicy(cols, partitionCharmHadron2Prong, + partitionCharmHadronDstar, + colBinningMultPercentile); + break; + case aod::femtodreamcollision::kMultMultPercentile: + runWithPolicy(cols, partitionCharmHadron2Prong, + partitionCharmHadronDstar, + colBinningMultMultPercentile); + break; + default: + LOGP(fatal, "Invalid mixing binning policy"); } } - void processD0D0(FilteredCollisions const &cols, - FilteredCharmCand2Prongs const &d0s) { + void processD0D0(FilteredCollisions const& cols, + FilteredCharmCand2Prongs const& d0s) + { run(cols, d0s, d0s); } PROCESS_SWITCH(HfTaskCharmHadronsCharmFemtoDream, processD0D0, "D0D0 data, SE and ME", true); - void processD0Dstar(FilteredCollisions const &cols, - FilteredCharmCand2Prongs const &d0s, - FilteredCharmCandDstars const &dstars) { + void processD0Dstar(FilteredCollisions const& cols, + FilteredCharmCand2Prongs const& d0s, + FilteredCharmCandDstars const& dstars) + { run(cols, d0s, dstars); } PROCESS_SWITCH(HfTaskCharmHadronsCharmFemtoDream, processD0Dstar, "D0D0 and D0Dstar data, SE and ME", false); }; -WorkflowSpec defineDataProcessing(ConfigContext const &cfgc) { +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ return WorkflowSpec{ - adaptAnalysisTask(cfgc)}; + adaptAnalysisTask(cfgc)}; }