ATLAS Offline Software
Loading...
Searching...
No Matches
Acts::InPlaceClusterization Namespace Reference

Namespaces

namespace  traits

Classes

struct  Cell
 A possible Cell type, that can be clustered. More...
struct  ConnectionHelper
 default connection helper which should work for arbitrary cells which fulfil the CellWithLabelConcept More...

Concepts

concept  CellWithLabel
 concept of a call object that can be clustered.
concept  SequenceContainer
 base concept for the container that can be used for a cell collection
concept  CellCollection
 concept of a cell container that can be clustered

Enumerations

enum class  EConnectionType { CommonEdgeOrCorner , CommonEdge }

Functions

template<typename coordinates_t>
bool isConnectedCommonEdgeOrCorner (const coordinates_t &coordinates_diff)
 test whether cells are connected considering common corners and edges.
template<typename coordinates_t>
bool isConnectedCommonEdge (const coordinates_t &coordinates_diff)
 test whether cells are connected considering common edges only.
template<EConnectionType connection_type = EConnectionType::CommonEdgeOrCorner, CellCollection cell_container_t = std::span<Cell<int, 2, unsigned int> >>
auto defaultConnectionHelper (const cell_container_t &cells)
template<typename coordinate_t>
auto absDifference (coordinate_t a, coordinate_t b)
 compute the absolute difference of two coordinates
template<unsigned int SORT_AXIS, CellCollection cell_collection_t, std::unsigned_integral index_t = unsigned int, typename connection_helper_t>
void labelSortedCells (cell_collection_t &cells, connection_helper_t &&connection_helper)
 Label cells which are in ascending order of the coordinate of the given axis.
template<unsigned int AXIS, CellCollection cell_collection_t, std::size_t NDim = 2, std::unsigned_integral index_t = unsigned int>
void sortCellsByCoordinate (cell_collection_t &cells)
 Sort the cells in ascending order of the coordinate of the specified axis.
template<CellCollection cell_collection_t>
void groupCellsByLabel (cell_collection_t &cells)
 Sort the cells in ascending order of the asscoiated label.
template<unsigned int SORT_AXIS, std::unsigned_integral index_t = unsigned int, CellCollection cell_collection_t = std::span<Cell<int, 2, unsigned int> >, typename connection_helper_t = ConnectionHelper<Cell<int, 2, unsigned int> >>
void clusterize (cell_collection_t &cells, connection_helper_t &&connection_helper=ConnectionHelper< typename cell_collection_t::value_type, EConnectionType::CommonEdgeOrCorner >{})
 Sort the cell collection in such a way that cells of a cluster are adjacent.
template<CellCollection cell_collection_t, std::unsigned_integral index_t = unsigned int>
std::size_t countLabels (const cell_collection_t &cells)
 determine the number of clusters.
template<CellCollection cell_collection_t, typename func_t>
void for_each_cluster (cell_collection_t &cells, func_t func)
 call the given function for each cluster of a label sorted cell collection.
template<CellCollection cell_collection_t, typename range_collection_t>
void addCellRanges (const cell_collection_t &cells, range_collection_t &ranges)
 Add element ranges for each cluster in the cell collection to the given range container.
template<unsigned int AXIS, CellCollection cell_collection_t, typename range_collection_t>
void addCellRangesAndSort (cell_collection_t &cells, range_collection_t &ranges)
 Sort the cells of each cluster by one coordinate and add cell ranges to the given range container.

Enumeration Type Documentation

◆ EConnectionType

Function Documentation

◆ absDifference()

template<typename coordinate_t>
auto Acts::InPlaceClusterization::absDifference ( coordinate_t a,
coordinate_t b )

compute the absolute difference of two coordinates

Definition at line 176 of file InPlaceClusterization.h.

176 {
177 if constexpr (std::is_signed_v<coordinate_t>) {
178 // @TODO check overflow with C++26, or change return type to
179 // an unsigned integer of same size.
180 return static_cast<coordinate_t>(std::abs(a - b));
181 } else {
182 return static_cast<coordinate_t>((a > b ? a - b : b - a));
183 }
184}
static Double_t a

◆ addCellRanges()

template<CellCollection cell_collection_t, typename range_collection_t>
void Acts::InPlaceClusterization::addCellRanges ( const cell_collection_t & cells,
range_collection_t & ranges )

Add element ranges for each cluster in the cell collection to the given range container.

Parameters
cellslabeled and label sorted cell collection
rangesa range container It is assumed that clusterize was called previously for the given cell collection i.e. the cells are labeled and sorted by label. Will add one cell range per cluster to the given range container. The value type of the range container has to be constructible by two indices the index of the first cell in a cluster and the index of the cell after the last cell of the cluster.

Definition at line 354 of file InPlaceClusterization.h.

354 {
356 cells, [&ranges]([[maybe_unused]] const cell_collection_t &all_cells,
357 unsigned int idx_begin, unsigned int idx_end) {
358 ranges.emplace_back(idx_begin, idx_end);
359 });
360}
void for_each_cluster(cell_collection_t &cells, func_t func)
call the given function for each cluster of a label sorted cell collection.

◆ addCellRangesAndSort()

template<unsigned int AXIS, CellCollection cell_collection_t, typename range_collection_t>
void Acts::InPlaceClusterization::addCellRangesAndSort ( cell_collection_t & cells,
range_collection_t & ranges )

Sort the cells of each cluster by one coordinate and add cell ranges to the given range container.

Parameters
cellslabeled and label sorted cell collection
rangesa range container It is assumed that clusterize was called previously for the given cell collection i.e. the cells are labeled and sorted by label. Will first sort the cells of each cluster by the coordinate of the specified axis and add one cell range per cluster to the given range container. The value type of the range container has to be constructible by two indices the index of the first cell in a cluster and the index of the cell after the last cell of the cluster.

Definition at line 374 of file InPlaceClusterization.h.

375 {
376 for_each_cluster(cells, [&ranges](cell_collection_t &all_cells,
377 unsigned int idx_begin,
378 unsigned int idx_end) {
379 auto cluster_range =
380 std::span(all_cells.begin() + idx_begin, all_cells.begin() + idx_end);
381 using cell_t = typename cell_collection_t::value_type;
382 std::ranges::sort(cluster_range, [](const cell_t &a, const cell_t &b) {
383 return traits::getCellCoordinate(a, AXIS) <
385 });
386 ranges.emplace_back(idx_begin, idx_end);
387 });
388}
auto getCellCoordinate(const cell_t &a, unsigned int axis_i)
Get the coordinates of a cell.

◆ clusterize()

template<unsigned int SORT_AXIS, std::unsigned_integral index_t = unsigned int, CellCollection cell_collection_t = std::span<Cell<int, 2, unsigned int> >, typename connection_helper_t = ConnectionHelper<Cell<int, 2, unsigned int> >>
void Acts::InPlaceClusterization::clusterize ( cell_collection_t & cells,
connection_helper_t && connection_helper = ConnectionHelper<typename cell_collection_t::value_type, EConnectionType::CommonEdgeOrCorner>{} )

Sort the cell collection in such a way that cells of a cluster are adjacent.

Parameters
cellsthe cell collection which will be sorted.
connection_helpera helper object to test for cell connections. Will sort the cells first by the coordinate of the specified axis to accelerate connection tests. Then associate the same label to connected cells where the label corresponds to the smallest cell index (in the sorted cell collection) of a cluster, where the cells are in ascending order of one of the coordinates Finally will sort the cells by the label in ascending order. As a consequence cells which belong to one cluster are adjacent and have the same label. index_t must be large enough to fit the number of cells in the collection.

Definition at line 291 of file InPlaceClusterization.h.

293 {}) {
294 assert(cells.size() <= std::numeric_limits<index_t>::max());
297 connection_helper);
298 groupCellsByLabel(cells);
299}
void labelSortedCells(cell_collection_t &cells, connection_helper_t &&connection_helper)
Label cells which are in ascending order of the coordinate of the given axis.
void sortCellsByCoordinate(cell_collection_t &cells)
Sort the cells in ascending order of the coordinate of the specified axis.
void groupCellsByLabel(cell_collection_t &cells)
Sort the cells in ascending order of the asscoiated label.

◆ countLabels()

template<CellCollection cell_collection_t, std::unsigned_integral index_t = unsigned int>
std::size_t Acts::InPlaceClusterization::countLabels ( const cell_collection_t & cells)

determine the number of clusters.

It is assumed that clusterize was called previously for the given cell collection i.e. the cells are labeled and sorted by label. It will count the number of different labels do determine the number of clusters in the collection.

Definition at line 309 of file InPlaceClusterization.h.

309 {
310 assert(cells.size() <= std::numeric_limits<index_t>::max());
311 std::size_t nlabels = cells.empty() ? 0 : 1;
312 for (index_t idx_a = 1; idx_a < cells.size(); ++idx_a) {
313 nlabels +=
314 traits::getLabel(cells[idx_a]) != traits::getLabel(cells[idx_a - 1]);
315 }
316 return nlabels;
317}
auto getLabel(const cell_t &a)
Get the label associated to the given cell.

◆ defaultConnectionHelper()

template<EConnectionType connection_type = EConnectionType::CommonEdgeOrCorner, CellCollection cell_container_t = std::span<Cell<int, 2, unsigned int> >>
auto Acts::InPlaceClusterization::defaultConnectionHelper ( const cell_container_t & cells)

Definition at line 169 of file InPlaceClusterization.h.

169 {
170 return ConnectionHelper<typename cell_container_t::value_type,
171 connection_type>{};
172}
default connection helper which should work for arbitrary cells which fulfil the CellWithLabelConcept

◆ for_each_cluster()

template<CellCollection cell_collection_t, typename func_t>
void Acts::InPlaceClusterization::for_each_cluster ( cell_collection_t & cells,
func_t func )

call the given function for each cluster of a label sorted cell collection.

It is assumed that clusterize was called previously for the given cell collection i.e. the cells are labeled and sorted by label. Will call the given function for each cluster, where the function gets a reference to the full cell collection and the begin and end cell index which defines the cell range of a cluster.

Definition at line 326 of file InPlaceClusterization.h.

326 {
327 if (cells.empty()) {
328 return;
329 }
330 using index_t = decltype(traits::getLabel(cells[0]));
331 index_t idx_begin = 0;
332 index_t idx = 1;
333 for (; idx < cells.size(); ++idx) {
334 if (traits::getLabel(cells[idx]) != traits::getLabel(cells[idx - 1])) {
335 func(cells, idx_begin, idx);
336 idx_begin = idx;
337 }
338 }
339 if (idx_begin < idx) {
340 func(cells, idx_begin, idx);
341 }
342}

◆ groupCellsByLabel()

template<CellCollection cell_collection_t>
void Acts::InPlaceClusterization::groupCellsByLabel ( cell_collection_t & cells)

Sort the cells in ascending order of the asscoiated label.

Definition at line 266 of file InPlaceClusterization.h.

266 {
267 using cell_t = typename cell_collection_t::value_type;
268 // stable sort to retain coordinate ordering
269 std::stable_sort(cells.begin(), cells.end(),
270 [](const cell_t &a, const cell_t &b) {
271 return traits::getLabel(a) < traits::getLabel(b);
272 });
273}
void stable_sort(DataModel_detail::iterator< DVL > beg, DataModel_detail::iterator< DVL > end)
Specialization of stable_sort for DataVector/List.

◆ isConnectedCommonEdge()

template<typename coordinates_t>
bool Acts::InPlaceClusterization::isConnectedCommonEdge ( const coordinates_t & coordinates_diff)

test whether cells are connected considering common edges only.

Parameters
coordinates_diffabsolute values of the differences of the cell coordinates Test whether two cells with the given coordinate differences are connected either horizontally, vertically or are equal.

Definition at line 119 of file InPlaceClusterization.h.

119 {
120 int connections = 0;
121 for (const auto &a_coordinate_diff : coordinates_diff) {
122 connections += a_coordinate_diff;
123 }
124 return connections <= 1;
125}

◆ isConnectedCommonEdgeOrCorner()

template<typename coordinates_t>
bool Acts::InPlaceClusterization::isConnectedCommonEdgeOrCorner ( const coordinates_t & coordinates_diff)

test whether cells are connected considering common corners and edges.

Parameters
coordinates_diffabsolute values of the differences of the cell coordinates Test whether two cells with the given coordinate differences are connected either horizontally, vertically, diagonally or are equal.

Definition at line 106 of file InPlaceClusterization.h.

106 {
107 bool connected = true;
108 for (const auto &a_coordinate_diff : coordinates_diff) {
109 connected &= a_coordinate_diff <= 1;
110 }
111 return connected;
112}

◆ labelSortedCells()

template<unsigned int SORT_AXIS, CellCollection cell_collection_t, std::unsigned_integral index_t = unsigned int, typename connection_helper_t>
void Acts::InPlaceClusterization::labelSortedCells ( cell_collection_t & cells,
connection_helper_t && connection_helper )

Label cells which are in ascending order of the coordinate of the given axis.

Parameters
cellsthe sorted cell collection that should be labeled.
connection_helpera helper object to test for cell connections.

Definition at line 192 of file InPlaceClusterization.h.

193 {
194 using cell_t = typename cell_collection_t::value_type;
195 static constexpr std::size_t NDim = traits::getCellDimension<cell_t>();
196 static_assert(NDim > 0);
197 using label_t = std::remove_cvref_t<decltype(traits::getLabel(cells[0]))>;
198 using coordinate_t =
199 std::remove_cvref_t<decltype(traits::getCellCoordinate(cells[0], 0u))>;
200 static_assert(std::numeric_limits<index_t>::max() >=
201 std::numeric_limits<label_t>::max());
202 // cells are sorted in the first coordinate
203 // thus can stop searching for adjacent cells
204 // if distance in the sorted coordinate is too large
205 for (index_t idx_a = 0; idx_a < cells.size(); ++idx_a) {
206 traits::setLabel(cells[idx_a], idx_a);
207 for (index_t idx_b = idx_a; idx_b-- > 0;) {
208 // Unnecessary default initialization to satisfy clang-tidy:
209 std::array<coordinate_t, NDim> diff{};
210 for (unsigned int axis_i = 0; axis_i < NDim; ++axis_i) {
211 diff[axis_i] =
212 absDifference(traits::getCellCoordinate(cells[idx_a], axis_i),
213 traits::getCellCoordinate(cells[idx_b], axis_i));
214 }
215
216 if (connection_helper.isConnected(diff)) {
217 if (traits::getLabel(cells[idx_a]) < idx_a) {
218 // Unnecessary default initialization to satisfy clang-tidy:
219 label_t min_label{};
220 label_t max_label{};
221 if (traits::getLabel(cells[idx_a]) < traits::getLabel(cells[idx_b])) {
222 min_label = traits::getLabel(cells[idx_a]);
223 max_label = traits::getLabel(cells[idx_b]);
224 traits::setLabel(cells[idx_b], min_label);
225 } else {
226 max_label = traits::getLabel(cells[idx_a]);
227 min_label = traits::getLabel(cells[idx_b]);
228 traits::setLabel(cells[idx_a], min_label);
229 }
230 // nothing will be done if the min and the max label are identical
231 if (min_label != max_label) {
232 // can only encounter cells with label max_label down to index
233 // max_label
234 for (index_t idx = idx_a; idx-- > max_label;) {
235 if (traits::getLabel(cells[idx]) == max_label) {
236 traits::setLabel(cells[idx], min_label);
237 }
238 }
239 }
240 } else {
241 traits::setLabel(cells[idx_a], traits::getLabel(cells[idx_b]));
242 }
243 } else if (connection_helper.canAbortSearch(diff, SORT_AXIS)) {
244 // difference too large in sorted coordinate, there won't be any more
245 // candidates for merging. Can abort search for cell idx_a
246 break;
247 }
248 }
249 }
250}
void diff(const Jet &rJet1, const Jet &rJet2, std::map< std::string, double > varDiff)
Difference between jets - Non-Class function required by trigger.
Definition Jet.cxx:631
void setLabel(cell_t &a, index_t label)
Set a label for a given cell the label type must fit numbers as high as the number of cells which are...
auto absDifference(coordinate_t a, coordinate_t b)
compute the absolute difference of two coordinates

◆ sortCellsByCoordinate()

template<unsigned int AXIS, CellCollection cell_collection_t, std::size_t NDim = 2, std::unsigned_integral index_t = unsigned int>
void Acts::InPlaceClusterization::sortCellsByCoordinate ( cell_collection_t & cells)

Sort the cells in ascending order of the coordinate of the specified axis.

Definition at line 256 of file InPlaceClusterization.h.

256 {
257 using cell_t = typename cell_collection_t::value_type;
258 std::sort(cells.begin(), cells.end(), [](const cell_t &a, const cell_t &b) {
259 return traits::getCellCoordinate(a, AXIS) <
260 traits::getCellCoordinate(b, AXIS);
261 });
262}
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.