ATLAS Offline Software
Loading...
Searching...
No Matches
CellContainer.h
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3 */
4#ifndef ACTSTRK_CELLCONTAINER_H
5#define ACTSTRK_CELLCONTAINER_H
6
7#include <array>
8#include <cassert>
9#include <concepts>
10#include <cstdint>
11#include <span>
12#include <vector>
13
14namespace ActsTrk {
16// @TODO should used Acts version once the InPlaceClusterization is part of Acts
17template <typename coordinates_t, std::size_t NDIM, std::unsigned_integral index_t>
18struct CellTmpl {
19 CellTmpl(const std::array<coordinates_t, NDIM> &the_coordinates, index_t src_index)
20 : coordinates(the_coordinates), label(index_t{}), srcIndex(src_index) {}
21 std::array<coordinates_t, NDIM>
23 index_t label;
24 index_t srcIndex;
25};
26
28template <typename coordinates_t, std::size_t NDIM, std::unsigned_integral index_t>
30{
31public:
32 CellContainer(unsigned int n_modules,
33 unsigned int n_cluster_total,
34 unsigned int n_cells_total)
35 { reserve(n_modules, n_cluster_total, n_cells_total); }
36
40 void reserve(unsigned int n_modules,
41 unsigned int n_cluster_total,
42 unsigned int n_cells_total) {
43 m_moduleClusterRange.reserve(n_modules);
44 m_relativeClusterCellIndex.reserve(n_cluster_total+n_modules); // will contain per module i n_cluster_i+1 indices
45 m_cells.reserve(n_cells_total);
46 }
47
48 std::size_t nClustersTotal() const {
49 assert(m_relativeClusterCellIndex.size() >= nModules());
51 }
52 std::size_t nModules() const { return m_moduleClusterRange.size(); }
53 std::size_t nCellsTotal() const { return m_cells.size(); }
54 std::size_t size() const { return nModules(); }
55
57
58 // clusterization not necessarily executed in module order thus need cluster begin and end index.
59 // the cells of a module are in one consecutive chunk. To keep the cell indices per cluster compact
60 // store the full cell index per module and use relaive indices for cell indices per module.
61 struct ClusterRange {
62 unsigned int cellBeginIndex; // index of first cell for this module; has to be >> uint16_t to fit all clusters of all modules
63 unsigned int clusterRangeBeginIndex; // index of first cluster of this module; has to be >> uint16_t to fit all cells of all modules
64 unsigned int clusterRangeEndIndex; // index of first cluster not of this module; could be number of clusters instead which would fit in uint16_t
65 unsigned int idHash; // identifier hash of the module this range of clusters is associated to
66 unsigned int nClusters() const {
67 return static_cast<unsigned int>(clusterRangeEndIndex - clusterRangeBeginIndex );
68 }
69 };
70
72 ModuleRangeGuard(CellContainer &cell_container, unsigned int id_hash)
73 : m_cellContainer(&cell_container),
74 m_firstCell(cell_container.m_cells.size()),
76 m_idHash(id_hash)
77 {
78 // The module guard should be constructed after startNewModule was called
79 // and before any cluster was added.
80 assert( m_clusterBegin>0u);
81 assert( cell_container.m_relativeClusterCellIndex[m_clusterBegin-1u]==0u );
82 }
84 return ClusterRange{.cellBeginIndex = m_firstCell,
85 .clusterRangeBeginIndex = m_clusterBegin,
86 .clusterRangeEndIndex = static_cast<unsigned int>(m_cellContainer->m_relativeClusterCellIndex.size()),
87 .idHash = m_idHash };
88 }
89 std::span<Cell> moduleCellSpan() {
90 assert( m_cellContainer->m_cells.size() >= m_firstCell);
91 return std::span<Cell>(m_cellContainer->m_cells.begin()+m_firstCell,
92 m_cellContainer->m_cells.end());
93 }
95 return m_idHash;
96 }
97 private:
99 unsigned int m_firstCell;
100 unsigned int m_clusterBegin;
101 unsigned int m_idHash;
102 };
103
104 ModuleRangeGuard startNewModule(unsigned int id_hash) {
105 // relative cluster cell indices will always start with 0, will contain n_cluster+1 indices, where
106 // the last index will be the last relative index of the last cell.
107 // below test size+1 because there should also be space for at least the end index
108 assert( m_relativeClusterCellIndex.size()+1 < m_relativeClusterCellIndex.capacity());
109 m_relativeClusterCellIndex.push_back(index_t{});
110 return ModuleRangeGuard(*this, id_hash);
111 }
112 void emplace_back_cell(const std::array<coordinates_t, NDIM> &the_coordinates, index_t src_index) {
113 m_cells.emplace_back(the_coordinates, src_index);
114 }
115 void registerNewCluster([[maybe_unused]] index_t cell_begin_idx, index_t cell_end_idx) {
116 assert(!m_relativeClusterCellIndex.empty()); // startNewModule should have added a zero
117 assert( m_relativeClusterCellIndex.back() == cell_begin_idx); // clusters must be added in order
118 assert(cell_begin_idx < cell_end_idx); // a cluster must not be empty
119 // @TODO for debugging
120 assert( m_relativeClusterCellIndex.size() < m_relativeClusterCellIndex.capacity());
121
122 m_relativeClusterCellIndex.push_back(cell_end_idx);
123 }
124 void registerClustersForNewModule(const ClusterRange &a_range) {
125 // @TODO for debugging
126 assert( m_moduleClusterRange.size() < m_moduleClusterRange.capacity());
127
128 assert( a_range.clusterRangeEndIndex <= m_relativeClusterCellIndex.size() );
129 assert( a_range.clusterRangeEndIndex >0u );
130 assert( a_range.cellBeginIndex + m_relativeClusterCellIndex[a_range.clusterRangeEndIndex-1] <= m_cells.size() );
131
132 m_moduleClusterRange.push_back(a_range);
133 }
134 const ClusterRange &moduleClusterRange(unsigned int module_i) const {
135 assert(module_i<m_moduleClusterRange.size());
136 return m_moduleClusterRange[module_i];
137 }
138
139 std::vector<Cell> m_cells; // data of all cells of all clusters of all modules
140 std::vector<index_t> m_relativeClusterCellIndex; // cell index relative to the first cell index of a module, where two consecutive
141 // elements define the range of cells of a cluster.
142 std::vector<ClusterRange> m_moduleClusterRange; // cluster index range per module -> m_clusterCellRange
143};
144}
145#endif
This is a "hash" representation of an Identifier.
The AlignStoreProviderAlg loads the rigid alignment corrections and pipes them through the readout ge...
ModuleRangeGuard(CellContainer &cell_container, unsigned int id_hash)
void registerNewCluster(index_t cell_begin_idx, index_t cell_end_idx)
CellContainer(unsigned int n_modules, unsigned int n_cluster_total, unsigned int n_cells_total)
std::size_t nCellsTotal() const
void reserve(unsigned int n_modules, unsigned int n_cluster_total, unsigned int n_cells_total)
reserve storage for the cell and cluster data
void emplace_back_cell(const std::array< coordinates_t, NDIM > &the_coordinates, index_t src_index)
void registerClustersForNewModule(const ClusterRange &a_range)
CellTmpl< coordinates_t, NDIM, index_t > Cell
ModuleRangeGuard startNewModule(unsigned int id_hash)
std::size_t nClustersTotal() const
std::size_t size() const
const ClusterRange & moduleClusterRange(unsigned int module_i) const
Definition of a cell to be used by the in-place clusterization.
CellTmpl(const std::array< coordinates_t, NDIM > &the_coordinates, index_t src_index)
index_t label
a label which will be assigned by the clusterization
index_t srcIndex
the index to find the source cell
std::array< coordinates_t, NDIM > coordinates
the coordinates of the cell on the regular grid