File indexing completed on 2026-05-31 07:47:14
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include <memory>
0012 #include <vector>
0013
0014 #include <boost/pending/disjoint_sets.hpp>
0015
0016 namespace Acts::Ccl {
0017 using Label = int;
0018 constexpr Label NO_LABEL = 0;
0019 }
0020
0021 namespace Acts::Ccl {
0022
0023
0024
0025
0026 class DisjointSets {
0027 public:
0028
0029
0030 explicit DisjointSets(std::size_t initial_size = 128)
0031 : m_defaultSize(initial_size),
0032 m_size(initial_size),
0033 m_rank(m_size),
0034 m_parent(m_size),
0035 m_ds(&m_rank[0], &m_parent[0]) {}
0036
0037
0038
0039 Acts::Ccl::Label makeSet() {
0040
0041
0042 while (m_globalId >= m_size) {
0043 m_size *= 2;
0044 m_rank.resize(m_size);
0045 m_parent.resize(m_size);
0046 m_ds = boost::disjoint_sets<std::size_t*, std::size_t*>(&m_rank[0],
0047 &m_parent[0]);
0048 }
0049 m_ds.make_set(m_globalId);
0050 return static_cast<Acts::Ccl::Label>(m_globalId++);
0051 }
0052
0053
0054
0055
0056 void unionSet(std::size_t x, std::size_t y) { m_ds.union_set(x, y); }
0057
0058
0059
0060 Acts::Ccl::Label findSet(std::size_t x) {
0061 return static_cast<Acts::Ccl::Label>(m_ds.find_set(x));
0062 }
0063
0064
0065 void clear() {
0066 m_size = m_defaultSize;
0067 m_rank.clear();
0068 m_parent.clear();
0069 m_rank.resize(m_size);
0070 m_parent.resize(m_size);
0071 m_globalId = 1;
0072 m_ds = boost::disjoint_sets<std::size_t*, std::size_t*>(&m_rank[0],
0073 &m_parent[0]);
0074 }
0075
0076 private:
0077 std::size_t m_defaultSize{128};
0078 std::size_t m_globalId = 1;
0079 std::size_t m_size{m_defaultSize};
0080 std::vector<std::size_t> m_rank;
0081 std::vector<std::size_t> m_parent;
0082 boost::disjoint_sets<std::size_t*, std::size_t*> m_ds;
0083 };
0084
0085
0086 struct ClusteringData {
0087
0088 void clear() {
0089 labels.clear();
0090 nClusters.clear();
0091 ds.clear();
0092 }
0093
0094
0095 std::vector<Acts::Ccl::Label> labels{};
0096
0097 std::vector<std::size_t> nClusters{};
0098
0099 Acts::Ccl::DisjointSets ds{};
0100 };
0101
0102 template <typename Cell>
0103 concept HasRetrievableColumnInfo = requires(Cell cell) {
0104 { getCellColumn(cell) } -> std::same_as<int>;
0105 };
0106
0107 template <typename Cell>
0108 concept HasRetrievableRowInfo = requires(Cell cell) {
0109 { getCellRow(cell) } -> std::same_as<int>;
0110 };
0111
0112 template <typename Cell, typename Cluster>
0113 concept CanAcceptCell = requires(Cell cell, Cluster cluster) {
0114 { clusterAddCell(cluster, cell) } -> std::same_as<void>;
0115 };
0116
0117 template <typename Cluster>
0118 concept CanReserve = requires(Cluster cluster, std::size_t n) {
0119 { clusterReserve(cluster, n) } -> std::same_as<void>;
0120 };
0121
0122
0123
0124
0125
0126 enum class ConnectResult {
0127 eNoConn,
0128 eNoConnStop,
0129 eConn,
0130 eDuplicate
0131 };
0132
0133
0134 template <typename Cell>
0135 requires(Acts::Ccl::HasRetrievableColumnInfo<Cell> &&
0136 Acts::Ccl::HasRetrievableRowInfo<Cell>)
0137 struct Connect2D {
0138
0139 bool conn8{true};
0140 Connect2D() = default;
0141
0142
0143 explicit Connect2D(bool commonCorner) : conn8{commonCorner} {}
0144
0145
0146
0147
0148 virtual ConnectResult operator()(const Cell& ref, const Cell& iter) const;
0149 virtual ~Connect2D() = default;
0150 };
0151
0152
0153 template <Acts::Ccl::HasRetrievableColumnInfo Cell>
0154 struct Connect1D {
0155
0156
0157
0158
0159 virtual ConnectResult operator()(const Cell& ref, const Cell& iter) const;
0160 virtual ~Connect1D() = default;
0161 };
0162
0163
0164 template <typename Cell, std::size_t GridDim = 2>
0165 struct DefaultConnect {
0166 static_assert(GridDim != 1 && GridDim != 2,
0167 "Only grid dimensions of 1 or 2 are supported");
0168 };
0169
0170
0171 template <typename Cell>
0172 struct DefaultConnect<Cell, 1> : public Connect1D<Cell> {
0173 ~DefaultConnect() override = default;
0174 };
0175
0176
0177 template <typename Cell>
0178 struct DefaultConnect<Cell, 2> : public Connect2D<Cell> {
0179
0180
0181 explicit DefaultConnect(bool commonCorner) : Connect2D<Cell>(commonCorner) {}
0182 DefaultConnect() = default;
0183 ~DefaultConnect() override = default;
0184 };
0185
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196
0197 template <typename CellCollection, std::size_t GridDim = 2,
0198 typename Connect =
0199 DefaultConnect<typename CellCollection::value_type, GridDim>>
0200 void labelClusters(Acts::Ccl::ClusteringData& data, CellCollection& cells,
0201 Connect&& connect = Connect());
0202
0203
0204
0205
0206
0207
0208
0209 template <typename CellCollection, typename ClusterCollection>
0210 requires(Acts::Ccl::CanAcceptCell<typename CellCollection::value_type,
0211 typename ClusterCollection::value_type>)
0212 void mergeClusters(Acts::Ccl::ClusteringData& data, const CellCollection& cells,
0213 ClusterCollection& outv);
0214
0215
0216
0217
0218
0219 template <typename CellCollection, typename ClusterCollection,
0220 std::size_t GridDim = 2,
0221 typename Connect =
0222 DefaultConnect<typename CellCollection::value_type, GridDim>>
0223 requires(GridDim == 1 || GridDim == 2)
0224 void createClusters(Acts::Ccl::ClusteringData& data, CellCollection& cells,
0225 ClusterCollection& clusters, Connect&& connect = Connect());
0226
0227 }
0228
0229 #include "Acts/Clusterization/Clusterization.ipp"