Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-07-26 08:18:42

0001 // This file is part of the ACTS project.
0002 //
0003 // Copyright (C) 2016 CERN for the benefit of the ACTS project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
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           // already handled above
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 }  // namespace Acts