6#include <unordered_map>
12using NodeVec = std::vector<std::size_t>;
17 explicit DSU(std::size_t n) : p(
n) { std::iota(p.begin(), p.end(), 0); }
19 std::size_t
find(std::size_t
x) {
return p[
x] ==
x ?
x : p[
x] =
find(p[
x]); }
20 void unite(std::size_t
a, std::size_t b) {
27void addUnique(std::vector<unsigned>& ids,
unsigned id) {
28 if (std::find(
ids.begin(),
ids.end(),
id) ==
ids.end())
ids.push_back(
id);
31std::uint64_t pairKey(std::size_t
a, std::size_t b) {
33 return (
static_cast<std::uint64_t
>(
a) << 32) |
static_cast<std::uint64_t
>(
b);
36std::pair<std::size_t, std::size_t> unpackPairKey(std::uint64_t key) {
37 return {
static_cast<std::size_t
>(
key >> 32),
38 static_cast<std::size_t
>(key & 0xffffffffu)};
41std::unordered_map<std::uint64_t, float>
43 const std::vector<SegmentEdgeScore>& scores,
44 const bool symmetrize) {
45 std::unordered_map<std::uint64_t, float> pairScore;
46 pairScore.reserve(scores.size());
48 if (
s.src >= graph.nNodes ||
s.dst >= graph.nNodes ||
s.src ==
s.dst)
continue;
49 const std::uint64_t
key = symmetrize ? pairKey(
s.src,
s.dst)
52 auto [
it, inserted] = pairScore.emplace(key,
s.probability);
53 if (!inserted)
it->second = std::max(
it->second,
s.probability);
59 const std::unordered_map<std::uint64_t, float>& pairScore,
60 const float threshold,
61 const bool keepIsolated) {
62 DSU dsu(graph.nNodes);
63 std::vector<char> touched(graph.nNodes,
false);
65 for (
const auto& [key, prob] : pairScore) {
66 if (prob < threshold)
continue;
67 const auto [
a,
b] = unpackPairKey(key);
68 if (
a >= graph.nNodes || b >= graph.nNodes)
continue;
74 std::unordered_map<std::size_t, NodeVec> byRoot;
75 byRoot.reserve(graph.nNodes);
76 for (std::size_t i = 0;
i < graph.nNodes; ++
i) {
77 if (!touched[i] && !keepIsolated)
continue;
78 byRoot[dsu.find(i)].push_back(i);
81 std::vector<NodeVec>
out;
82 out.reserve(byRoot.size());
83 for (
auto& [_, nodes] : byRoot) {
84 std::ranges::sort(nodes);
85 out.push_back(std::move(nodes));
94 const std::vector<SegmentEdgeScore>& scores,
95 std::vector<std::vector<unsigned>>& candidateIdsPerSegment)
const {
97 candidateIdsPerSegment.assign(graph.
nNodes, {});
99 if (graph.
nNodes == 0)
return StatusCode::SUCCESS;
104 std::vector<NodeVec> candidates =
105 componentsAboveThreshold(graph, pairScore,
117 std::vector<NodeVec> recovery =
118 componentsAboveThreshold(graph, pairScore,
121 candidates.insert(candidates.end(),
122 std::make_move_iterator(recovery.begin()),
123 std::make_move_iterator(recovery.end()));
133 NodeVec all(graph.
nNodes);
134 std::iota(all.begin(), all.end(), 0);
135 candidates.push_back(std::move(all));
139 std::set<NodeVec> seen;
141 for (NodeVec& nodes : candidates) {
143 nodes.erase(
std::unique(nodes.begin(), nodes.end()), nodes.end());
145 if (!seen.insert(nodes).second)
continue;
147 for (std::size_t n : nodes) {
148 addUnique(candidateIdsPerSegment[n], next);
153 for (
auto& ids : candidateIdsPerSegment) {
157 std::unordered_map<unsigned, unsigned> candSegCount;
158 candSegCount.reserve(next);
159 for (
const auto& ids : candidateIdsPerSegment) {
160 for (
unsigned id : ids) ++candSegCount[id];
163 std::size_t assignedNodes = 0;
164 std::size_t multiAssignedNodes = 0;
165 for (
const auto& ids : candidateIdsPerSegment) {
166 assignedNodes += !ids.empty();
167 multiAssignedNodes += ids.size() > 1;
171 <<
" candidate(s) from " << graph.
nNodes
172 <<
" segment(s); assignedNodes=" << assignedNodes
173 <<
", multiAssignedNodes=" << multiAssignedNodes
178 if (msgLvl(MSG::VERBOSE)) {
179 for (
const auto& [
id, nSegs] : candSegCount) {
180 ATH_MSG_VERBOSE(
" candidate " <<
id <<
": " << nSegs <<
" segment(s)");
184 return StatusCode::SUCCESS;
#define ATH_MSG_VERBOSE(x)
std::string find(const std::string &s)
return a remapped string
FastGraph::NodeVec NodeVec
DataModel_detail::iterator< DVL > unique(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of unique for DataVector/List.
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
void swap(ElementLinkVector< DOBJ > &lhs, ElementLinkVector< DOBJ > &rhs)