File indexing completed on 2026-07-26 08:18:42
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "Acts/EventData/SpacePointContainer.hpp"
0010
0011 #include "Acts/Utilities/Helpers.hpp"
0012
0013 #include <string_view>
0014 #include <unordered_set>
0015
0016 namespace {
0017
0018 template <typename Tuple>
0019 using tuple_indices =
0020 std::make_index_sequence<std::tuple_size_v<std::remove_reference_t<Tuple>>>;
0021
0022 }
0023
0024 namespace Acts {
0025
0026 static_assert(std::ranges::random_access_range<SpacePointContainer>);
0027 static_assert(
0028 std::ranges::random_access_range<SpacePointContainer::MutableRange>);
0029 static_assert(
0030 std::ranges::random_access_range<SpacePointContainer::ConstRange>);
0031 static_assert(
0032 std::ranges::random_access_range<SpacePointContainer::MutableSubset>);
0033 static_assert(
0034 std::ranges::random_access_range<SpacePointContainer::ConstSubset>);
0035
0036 SpacePointContainer::SpacePointContainer(SpacePointColumns columns) noexcept {
0037 createColumns(columns);
0038 }
0039
0040 SpacePointContainer::SpacePointContainer(
0041 const SpacePointContainer &other) noexcept
0042 : m_size(other.m_size), m_sourceLinks(other.m_sourceLinks) {
0043 copyColumns(other);
0044 }
0045
0046 SpacePointContainer::SpacePointContainer(SpacePointContainer &&other) noexcept
0047 : m_size(other.m_size), m_sourceLinks(std::move(other.m_sourceLinks)) {
0048 moveColumns(other);
0049
0050 other.m_size = 0;
0051 }
0052
0053 SpacePointContainer &SpacePointContainer::operator=(
0054 const SpacePointContainer &other) noexcept {
0055 if (this == &other) {
0056 return *this;
0057 }
0058
0059 copyColumns(other);
0060 m_sourceLinks = other.m_sourceLinks;
0061 m_size = other.m_size;
0062
0063 return *this;
0064 }
0065
0066 SpacePointContainer &SpacePointContainer::operator=(
0067 SpacePointContainer &&other) noexcept {
0068 if (this == &other) {
0069 return *this;
0070 }
0071
0072 moveColumns(other);
0073 m_sourceLinks = std::move(other.m_sourceLinks);
0074 m_size = other.m_size;
0075
0076 other.m_size = 0;
0077
0078 return *this;
0079 }
0080
0081 void SpacePointContainer::copyColumns(const SpacePointContainer &other) {
0082 m_allColumns.reserve(other.m_allColumns.size());
0083 m_dynamicColumns.reserve(other.m_dynamicColumns.size());
0084
0085 const auto copyKnownColumns =
0086 [&]<typename T>(std::string_view name,
0087 std::optional<ColumnHolder<T>> &column,
0088 const std::optional<ColumnHolder<T>> &otherColumn) {
0089 column = otherColumn;
0090 if (column.has_value()) {
0091 m_allColumns.try_emplace(std::string(name), &column.value());
0092 }
0093 };
0094
0095 [&]<std::size_t... Is>(std::index_sequence<Is...>) {
0096 ((copyKnownColumns(std::get<Is>(knownColumnNames()),
0097 std::get<Is>(knownColumns()),
0098 std::get<Is>(other.knownColumns()))),
0099 ...);
0100 }(tuple_indices<decltype(knownColumns())>{});
0101 m_knownColumns = other.m_knownColumns;
0102
0103 for (auto &[name, column] : other.m_dynamicColumns) {
0104 std::unique_ptr<ColumnHolderBase> columnCopy = column->copy();
0105 m_allColumns.try_emplace(name, columnCopy.get());
0106 m_dynamicColumns.try_emplace(name, std::move(columnCopy));
0107 }
0108 }
0109
0110 void SpacePointContainer::moveColumns(SpacePointContainer &other) noexcept {
0111 m_allColumns.reserve(other.m_allColumns.size());
0112 m_dynamicColumns.reserve(other.m_dynamicColumns.size());
0113
0114 const auto moveKnownColumns =
0115 [&]<typename T>(std::string_view name,
0116 std::optional<ColumnHolder<T>> &column,
0117 std::optional<ColumnHolder<T>> &otherColumn) {
0118 column = std::move(otherColumn);
0119 if (column.has_value()) {
0120 m_allColumns.try_emplace(std::string(name), &column.value());
0121 }
0122 };
0123
0124 [&]<std::size_t... Is>(std::index_sequence<Is...>) {
0125 ((moveKnownColumns(std::get<Is>(knownColumnNames()),
0126 std::get<Is>(knownColumns()),
0127 std::get<Is>(other.knownColumns()))),
0128 ...);
0129 }(tuple_indices<decltype(knownColumns())>{});
0130 m_knownColumns = other.m_knownColumns;
0131
0132 for (auto &[name, column] : other.m_dynamicColumns) {
0133 m_allColumns.try_emplace(name, column.get());
0134 m_dynamicColumns.try_emplace(name, std::move(column));
0135 }
0136
0137 other.m_allColumns.clear();
0138 other.m_knownColumns = SpacePointColumns::None;
0139 other.m_dynamicColumns.clear();
0140 }
0141
0142 void SpacePointContainer::reserve(std::uint32_t size,
0143 float averageSourceLinks) noexcept {
0144 if (hasColumns(SpacePointColumns::SourceLinks)) {
0145 m_sourceLinks.reserve(
0146 static_cast<std::uint32_t>(size * averageSourceLinks));
0147 }
0148
0149 for (const auto &[name, column] : m_allColumns) {
0150 column->reserve(size);
0151 }
0152 }
0153
0154 void SpacePointContainer::clear() noexcept {
0155 m_size = 0;
0156 m_sourceLinks.clear();
0157
0158 for (const auto &[name, column] : m_allColumns) {
0159 column->clear();
0160 }
0161 }
0162
0163 MutableSpacePointProxy SpacePointContainer::createSpacePoint() noexcept {
0164 ++m_size;
0165
0166 for (const auto &[name, column] : m_allColumns) {
0167 column->emplace_back();
0168 }
0169
0170 return MutableProxy(*this, size() - 1);
0171 }
0172
0173 void SpacePointContainer::copyFrom(Index index,
0174 const SpacePointContainer &otherContainer,
0175 Index otherIndex,
0176 SpacePointColumns columnsToCopy) {
0177 if (index >= size() || otherIndex >= otherContainer.size()) {
0178 throw std::out_of_range(
0179 "Index out of range in SpacePointContainer::copyFrom");
0180 }
0181 if ((columnsToCopy & otherContainer.m_knownColumns) != columnsToCopy) {
0182 throw std::logic_error(
0183 "Source container does not have all columns to copy");
0184 }
0185 if ((columnsToCopy & m_knownColumns) != columnsToCopy) {
0186 throw std::logic_error(
0187 "Destination container does not have all columns to copy");
0188 }
0189
0190 if (ACTS_CHECK_BIT(columnsToCopy, SpacePointColumns::SourceLinks)) {
0191 at(index).assignSourceLinks(otherContainer[otherIndex].sourceLinks());
0192 }
0193
0194 const auto copyColumn =
0195 [&]<typename T>(SpacePointColumns mask,
0196 std::optional<ColumnHolder<T>> &destinationColumn,
0197 const std::optional<ColumnHolder<T>> &sourceColumn) {
0198 if (mask == SpacePointColumns::SourceLinks) {
0199
0200 return;
0201 }
0202 if (ACTS_CHECK_BIT(columnsToCopy, mask)) {
0203 assert(destinationColumn.has_value() &&
0204 "Column is not available in destination container");
0205 assert(sourceColumn.has_value() &&
0206 "Column is not available in source container");
0207 destinationColumn->proxy(*this)[index] =
0208 sourceColumn->proxy(otherContainer)[otherIndex];
0209 }
0210 };
0211
0212 [&]<std::size_t... Is>(std::index_sequence<Is...>) {
0213 ((copyColumn(std::get<Is>(knownColumnMasks()), std::get<Is>(knownColumns()),
0214 std::get<Is>(otherContainer.knownColumns()))),
0215 ...);
0216 }(tuple_indices<decltype(knownColumns())>{});
0217 }
0218
0219 void SpacePointContainer::createColumns(SpacePointColumns columns) noexcept {
0220 using enum SpacePointColumns;
0221
0222 const auto createColumn =
0223 [&]<typename T>(SpacePointColumns mask, std::string_view name,
0224 T defaultValue, std::optional<ColumnHolder<T>> &column) {
0225 if (ACTS_CHECK_BIT(columns, mask) && !column.has_value()) {
0226 column = ColumnHolder<T>(std::move(defaultValue));
0227 column->resize(size());
0228 m_allColumns.try_emplace(std::string(name), &column.value());
0229 m_knownColumns = m_knownColumns | mask;
0230 }
0231 };
0232
0233 [&]<std::size_t... Is>(std::index_sequence<Is...>) {
0234 ((createColumn(
0235 std::get<Is>(knownColumnMasks()), std::get<Is>(knownColumnNames()),
0236 std::get<Is>(knownColumnDefaults()), std::get<Is>(knownColumns()))),
0237 ...);
0238 }(tuple_indices<decltype(knownColumns())>{});
0239 }
0240
0241 void SpacePointContainer::dropColumns(SpacePointColumns columns) noexcept {
0242 using enum SpacePointColumns;
0243
0244 const auto dropColumn = [&]<typename T>(
0245 SpacePointColumns mask, std::string_view name,
0246 std::optional<ColumnHolder<T>> &column) {
0247 if (ACTS_CHECK_BIT(columns, mask) && column.has_value()) {
0248 m_allColumns.erase(std::string(name));
0249 column.reset();
0250 m_knownColumns = m_knownColumns & ~mask;
0251 }
0252 };
0253
0254 [&]<std::size_t... Is>(std::index_sequence<Is...>) {
0255 ((dropColumn(std::get<Is>(knownColumnMasks()),
0256 std::get<Is>(knownColumnNames()),
0257 std::get<Is>(knownColumns()))),
0258 ...);
0259 }(tuple_indices<decltype(knownColumns())>{});
0260
0261 if (ACTS_CHECK_BIT(columns, SpacePointColumns::SourceLinks)) {
0262 m_sourceLinks.clear();
0263 }
0264 }
0265
0266 void SpacePointContainer::dropColumn(const std::string &name) {
0267 if (reservedColumn(name)) {
0268 throw std::runtime_error("Cannot drop reserved column: " + name);
0269 }
0270
0271 auto it = m_allColumns.find(name);
0272 if (it == m_allColumns.end()) {
0273 throw std::runtime_error("Column does not exist: " + name);
0274 }
0275
0276 m_allColumns.erase(it);
0277 m_dynamicColumns.erase(name);
0278 }
0279
0280 bool SpacePointContainer::reservedColumn(const std::string &name) noexcept {
0281 static const auto reservedColumns = std::apply(
0282 [](auto... reservedNames) {
0283 return std::unordered_set<std::string, std::hash<std::string_view>,
0284 std::equal_to<>>({reservedNames...});
0285 },
0286 knownColumnNames());
0287
0288 return reservedColumns.contains(name);
0289 }
0290
0291 }