Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-04-08 07:47:25

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 #pragma once
0010 
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/Definitions/TrackParametrization.hpp"
0013 #include "Acts/EventData/SubspaceHelpers.hpp"
0014 #include "Acts/EventData/Types.hpp"
0015 #include "Acts/Geometry/GeometryIdentifier.hpp"
0016 #include "Acts/Utilities/detail/ContainerIterator.hpp"
0017 #include "ActsExamples/EventData/GeometryContainers.hpp"
0018 #include "ActsExamples/EventData/IndexSourceLink.hpp"
0019 #include "ActsExamples/EventData/MeasurementConcept.hpp"
0020 
0021 #include <cstddef>
0022 #include <iterator>
0023 #include <type_traits>
0024 #include <vector>
0025 
0026 #include <boost/container/static_vector.hpp>
0027 
0028 namespace ActsExamples {
0029 
0030 template <typename Derived, std::size_t FullSize, bool ReadOnly>
0031 class MeasurementProxyBase;
0032 template <std::size_t FullSize, std::size_t Size, bool ReadOnly>
0033 class FixedMeasurementProxy;
0034 template <std::size_t FullSize, bool ReadOnly>
0035 class VariableMeasurementProxy;
0036 
0037 template <std::size_t Size>
0038 using FixedBoundMeasurementProxy =
0039     FixedMeasurementProxy<Acts::eBoundSize, Size, false>;
0040 template <std::size_t Size>
0041 using ConstFixedBoundMeasurementProxy =
0042     FixedMeasurementProxy<Acts::eBoundSize, Size, true>;
0043 using VariableBoundMeasurementProxy =
0044     VariableMeasurementProxy<Acts::eBoundSize, false>;
0045 using ConstVariableBoundMeasurementProxy =
0046     VariableMeasurementProxy<Acts::eBoundSize, true>;
0047 
0048 /// @brief A container to store and access measurements
0049 ///
0050 /// This container stores measurements of different sizes and provides
0051 /// access to them through fixed-size and variable-size proxies.
0052 ///
0053 /// The measurements are stored densely in a flat buffer and the proxies
0054 /// provide access to the individual measurements.
0055 class MeasurementContainer {
0056  public:
0057   using size_type = std::size_t;
0058   using Index = size_type;
0059   template <std::size_t Size>
0060   using FixedProxy = FixedMeasurementProxy<Acts::eBoundSize, Size, false>;
0061   template <std::size_t Size>
0062   using ConstFixedProxy = FixedMeasurementProxy<Acts::eBoundSize, Size, true>;
0063   using VariableProxy = VariableMeasurementProxy<Acts::eBoundSize, false>;
0064   using ConstVariableProxy = VariableMeasurementProxy<Acts::eBoundSize, true>;
0065   using OrderedIndices = GeometryIdMultiset<IndexSourceLink>;
0066 
0067   MeasurementContainer();
0068 
0069   /// @brief Get the number of measurements
0070   /// @return The number of measurements
0071   std::size_t size() const;
0072 
0073   /// @brief Reserve space for a number of measurements
0074   /// @param size The number of measurements to reserve space for
0075   void reserve(std::size_t size);
0076 
0077   /// @brief Add a measurement of a given size
0078   /// @param size The size of the measurement
0079   /// @param geometryId The geometry identifier of the measurement surface
0080   /// @return The index of the added measurement
0081   Index addMeasurement(std::uint8_t size, Acts::GeometryIdentifier geometryId);
0082 
0083   /// @brief Get a variable-size measurement proxy
0084   /// @param index The index of the measurement
0085   /// @return The variable-size measurement proxy
0086   VariableProxy at(Index index);
0087   /// @brief Get a const variable-size measurement proxy
0088   /// @param index The index of the measurement
0089   /// @return The const variable-size measurement proxy
0090   ConstVariableProxy at(Index index) const;
0091 
0092   /// @brief Get a variable-size measurement proxy
0093   /// @param index The index of the measurement
0094   /// @return The variable-size measurement proxy
0095   VariableProxy getMeasurement(Index index);
0096   /// @brief Get a const variable-size measurement proxy
0097   /// @param index The index of the measurement
0098   /// @return The const variable-size measurement proxy
0099   ConstVariableProxy getMeasurement(Index index) const;
0100 
0101   /// @brief Get a fixed-size measurement proxy
0102   /// @tparam Size The size of the measurement
0103   /// @param index The index of the measurement
0104   /// @return The fixed-size measurement proxy
0105   template <std::size_t Size>
0106   FixedProxy<Size> getMeasurement(Index index) {
0107     return FixedProxy<Size>{*this, index};
0108   }
0109   /// @brief Get a const fixed-size measurement proxy
0110   /// @tparam Size The size of the measurement
0111   /// @param index The index of the measurement
0112   /// @return The const fixed-size measurement proxy
0113   template <std::size_t Size>
0114   ConstFixedProxy<Size> getMeasurement(Index index) const {
0115     return ConstFixedProxy<Size>{*this, index};
0116   }
0117 
0118   /// @brief Make a measurement of a given size
0119   /// @param size The size of the measurement
0120   /// @param geometryId The geometry identifier of the measurement surface
0121   /// @return The variable-size measurement proxy
0122   VariableProxy makeMeasurement(std::uint8_t size,
0123                                 Acts::GeometryIdentifier geometryId);
0124   /// @brief Make a fixed-size measurement
0125   /// @tparam Size The size of the measurement
0126   /// @param geometryId The geometry identifier of the measurement surface
0127   /// @return The fixed-size measurement proxy
0128   template <std::size_t Size>
0129   FixedProxy<Size> makeMeasurement(Acts::GeometryIdentifier geometryId) {
0130     return getMeasurement<Size>(addMeasurement(Size, geometryId));
0131   }
0132 
0133   template <MeasurementConcept OtherDerived>
0134   VariableProxy copyMeasurement(const OtherDerived& other);
0135   template <MeasurementConcept OtherDerived, std::size_t Size>
0136   FixedProxy<Size> copyMeasurement(const OtherDerived& other);
0137 
0138   template <typename... Args>
0139   VariableProxy emplaceMeasurement(std::uint8_t size,
0140                                    Acts::GeometryIdentifier geometryId,
0141                                    Args&&... args);
0142 
0143   template <std::size_t Size, typename... Args>
0144   FixedProxy<Size> emplaceMeasurement(Acts::GeometryIdentifier geometryId,
0145                                       Args&&... args);
0146 
0147   const OrderedIndices& orderedIndices() const;
0148 
0149   using iterator = Acts::detail::ContainerIterator<MeasurementContainer,
0150                                                    VariableProxy, Index, false>;
0151   using const_iterator =
0152       Acts::detail::ContainerIterator<const MeasurementContainer,
0153                                       ConstVariableProxy, Index, true>;
0154 
0155   iterator begin();
0156   iterator end();
0157   const_iterator begin() const;
0158   const_iterator end() const;
0159   const_iterator cbegin() const;
0160   const_iterator cend() const;
0161 
0162  public:
0163   struct MeasurementEntry {
0164     std::size_t subspaceIndexOffset{};
0165     std::size_t parameterOffset{};
0166     std::size_t covarianceOffset{};
0167     std::uint8_t size{};
0168   };
0169 
0170   std::vector<MeasurementEntry> m_entries;
0171 
0172   std::vector<Acts::GeometryIdentifier> m_geometryIds;
0173   std::vector<std::uint8_t> m_subspaceIndices;
0174   std::vector<double> m_parameters;
0175   std::vector<double> m_covariances;
0176 
0177   OrderedIndices m_orderedIndices;
0178 };
0179 
0180 /// @brief Base class for measurement proxies
0181 ///
0182 /// This class provides common functionality for fixed-size and variable-size
0183 /// measurement proxies.
0184 ///
0185 /// @tparam Derived The derived measurement proxy class
0186 /// @tparam FullSize The full size of the measurement
0187 /// @tparam ReadOnly Whether the proxy is read-only
0188 template <typename Derived, std::size_t FullSize, bool ReadOnly>
0189 class MeasurementProxyBase {
0190  public:
0191   using Index = MeasurementContainer::Index;
0192   using SubspaceIndex = std::uint8_t;
0193   using Scalar = double;
0194 
0195   using FullVector = Acts::Vector<FullSize>;
0196   using FullSquareMatrix = Acts::SquareMatrix<FullSize>;
0197 
0198   using Container = std::conditional_t<ReadOnly, const MeasurementContainer,
0199                                        MeasurementContainer>;
0200 
0201   MeasurementProxyBase(Container& container_, Index index_)
0202       : m_container(&container_), m_index(index_) {}
0203   template <typename OtherDerived, bool OtherReadOnly>
0204   explicit MeasurementProxyBase(
0205       const MeasurementProxyBase<OtherDerived, FullSize, OtherReadOnly>& other)
0206     requires(ReadOnly == OtherReadOnly || ReadOnly)
0207       : m_container(&other.container()), m_index(other.index()) {}
0208 
0209   /// @brief Get the container of the measurement
0210   /// @return The container of the measurement
0211   Container& container() const { return *m_container; }
0212   /// @brief Get the index of the measurement
0213   /// @return The index of the measurement
0214   Index index() const { return m_index; }
0215 
0216   /// @brief Get the size of the measurement
0217   /// @return The size of the measurement
0218   std::size_t size() const { return container().m_entries.at(m_index).size; }
0219 
0220   /// @brief Check if the measurement contains a subspace index
0221   /// @param i The subspace index
0222   /// @return True if the measurement contains the subspace index
0223   template <typename indices_t>
0224   bool contains(indices_t i) const {
0225     return self().subspaceHelper().contains(i);
0226   }
0227 
0228   /// @brief Get the index of a subspace index in the measurement
0229   /// @param i The subspace index
0230   /// @return The index of the subspace index in the measurement
0231   template <typename indices_t>
0232   std::size_t indexOf(indices_t i) const {
0233     return self().subspaceHelper().indexOf(i);
0234   }
0235 
0236   /// @brief Get the geometry ID of the measurement
0237   /// @return The geometry ID
0238   Acts::GeometryIdentifier geometryId() const {
0239     return container().m_geometryIds.at(m_index);
0240   }
0241 
0242   /// @brief Set the subspace indices of the measurement
0243   /// @param indices The subspace indices
0244   template <typename IndexContainer>
0245   void setSubspaceIndices(const IndexContainer& indices)
0246     requires(!ReadOnly)
0247   {
0248     assert(Acts::checkSubspaceIndices(indices, FullSize, size()) &&
0249            "Invalid indices");
0250     std::transform(indices.begin(), indices.end(),
0251                    self().subspaceIndexVector().begin(),
0252                    [](auto index) { return static_cast<Index>(index); });
0253   }
0254 
0255   /// @brief Get the measurement as a full-size vector
0256   /// @return The full-size measurement vector
0257   FullVector fullParameters() const {
0258     return self().subspaceHelper().expandVector(self().parameters());
0259   }
0260 
0261   /// @brief Get the covariance as a full-size square matrix
0262   /// @return The full-size covariance matrix
0263   FullSquareMatrix fullCovariance() const {
0264     return self().subspaceHelper().expandMatrix(self().covariance());
0265   }
0266 
0267   /// @brief Construct the measurement from a subspace vector,
0268   /// parameters, and covariance.
0269   ///
0270   template <typename Subspace, typename ParameterDerived,
0271             typename CovarianceDerived>
0272   void fill(Subspace&& subspace,
0273             const Eigen::DenseBase<ParameterDerived>& parameters,
0274             const Eigen::DenseBase<CovarianceDerived>& covariance)
0275     requires(!ReadOnly)
0276   {
0277     self().setSubspaceIndices(std::forward<Subspace>(subspace));
0278     self().parameters() = parameters;
0279     self().covariance() = covariance;
0280   }
0281 
0282   /// @brief Construct the measurement from a subspace vector,
0283   /// parameters, and covariance.
0284   ///
0285   template <MeasurementConcept OtherDerived>
0286   void fill(const OtherDerived& other)
0287     requires(!ReadOnly)
0288   {
0289     assert(size() == other.size() && "Size mismatch");
0290     fill(other.subspaceIndexVector(), other.parameters(), other.covariance());
0291   }
0292 
0293   /// @brief Copy the data from another measurement
0294   /// @tparam OtherDerived The derived measurement proxy class of the other
0295   ///         measurement
0296   /// @param other The other measurement proxy
0297   template <typename OtherDerived>
0298   void copyFrom(const OtherDerived& other)
0299     requires(!ReadOnly) && requires {
0300       { this->fill(other) };
0301     }
0302   {
0303     fill(other);
0304   }
0305 
0306  protected:
0307   Derived& self() { return static_cast<Derived&>(*this); }
0308   const Derived& self() const { return static_cast<const Derived&>(*this); }
0309 
0310   Container* m_container;
0311   Index m_index;
0312 };
0313 
0314 /// @brief Fixed-size measurement proxy
0315 ///
0316 /// This class provides access to a fixed-size measurement in a measurement
0317 /// container.
0318 ///
0319 /// @tparam FullSize The full size of the measurement
0320 /// @tparam Size The size of the measurement
0321 /// @tparam ReadOnly Whether the proxy is read-only
0322 template <std::size_t FullSize, std::size_t Size, bool ReadOnly>
0323 class FixedMeasurementProxy
0324     : public MeasurementProxyBase<
0325           FixedMeasurementProxy<FullSize, Size, ReadOnly>, FullSize, ReadOnly> {
0326  public:
0327   using Base =
0328       MeasurementProxyBase<FixedMeasurementProxy<FullSize, Size, ReadOnly>,
0329                            FullSize, ReadOnly>;
0330   using Index = typename Base::Index;
0331   using SubspaceIndex = typename Base::SubspaceIndex;
0332   using Scalar = typename Base::Scalar;
0333   using Container = typename Base::Container;
0334 
0335   using SubspaceHelper = Acts::FixedSubspaceHelper<FullSize, Size>;
0336 
0337   using SubspaceVector = Eigen::Matrix<SubspaceIndex, Size, 1>;
0338   using SubspaceVectorMap =
0339       std::conditional_t<ReadOnly, Eigen::Map<const SubspaceVector>,
0340                          Eigen::Map<SubspaceVector>>;
0341 
0342   using ParametersVector = Eigen::Matrix<Scalar, Size, 1>;
0343   using ParametersVectorMap =
0344       std::conditional_t<ReadOnly, Eigen::Map<const ParametersVector>,
0345                          Eigen::Map<ParametersVector>>;
0346 
0347   using CovarianceMatrix = Eigen::Matrix<Scalar, Size, Size>;
0348   using CovarianceMatrixMap =
0349       std::conditional_t<ReadOnly, Eigen::Map<const CovarianceMatrix>,
0350                          Eigen::Map<CovarianceMatrix>>;
0351 
0352   FixedMeasurementProxy(Container& container_, Index index_)
0353       : Base(container_, index_) {
0354     assert(container().m_entries.at(index()).size == Size && "Size mismatch");
0355   }
0356   template <typename OtherDerived, bool OtherReadOnly>
0357   explicit FixedMeasurementProxy(
0358       const MeasurementProxyBase<OtherDerived, FullSize, OtherReadOnly>& other)
0359     requires(ReadOnly == OtherReadOnly || ReadOnly)
0360       : Base(other) {
0361     assert(container().m_entries.at(index()).size == Size && "Size mismatch");
0362   }
0363 
0364   using Base::container;
0365   using Base::index;
0366 
0367   /// @brief Get the size of the measurement
0368   /// @return The size of the measurement
0369   static constexpr std::size_t size() { return Size; }
0370 
0371   /// @brief Get the subspace helper for the measurement
0372   /// @return The subspace helper
0373   SubspaceHelper subspaceHelper() const {
0374     return SubspaceHelper{subspaceIndexVector()};
0375   }
0376 
0377   /// @brief Get the subspace indices of the measurement
0378   /// @return The subspace indices
0379   Acts::SubspaceIndices<Size> subspaceIndices() const {
0380     return subspaceHelper().indices();
0381   }
0382 
0383   /// @brief Get the subspace index vector of the measurement
0384   /// @return The subspace index vector
0385   SubspaceVectorMap subspaceIndexVector() const {
0386     return SubspaceVectorMap{
0387         container().m_subspaceIndices.data() +
0388         container().m_entries.at(index()).subspaceIndexOffset};
0389   }
0390 
0391   /// @brief Get the parameters of the measurement
0392   /// @return The parameters
0393   ParametersVectorMap parameters() const {
0394     return ParametersVectorMap{
0395         container().m_parameters.data() +
0396         container().m_entries.at(index()).parameterOffset};
0397   }
0398 
0399   /// @brief Get the covariance of the measurement
0400   /// @return The covariance
0401   CovarianceMatrixMap covariance() const {
0402     return CovarianceMatrixMap{
0403         container().m_covariances.data() +
0404         container().m_entries.at(index()).covarianceOffset};
0405   }
0406 };
0407 
0408 /// @brief Variable-size measurement proxy
0409 ///
0410 /// This class provides access to a variable-size measurement in a measurement
0411 /// container.
0412 ///
0413 /// @tparam FullSize The full size of the measurement
0414 /// @tparam ReadOnly Whether the proxy is read-only
0415 template <std::size_t FullSize, bool ReadOnly>
0416 class VariableMeasurementProxy
0417     : public MeasurementProxyBase<VariableMeasurementProxy<FullSize, ReadOnly>,
0418                                   FullSize, ReadOnly> {
0419  public:
0420   using Base =
0421       MeasurementProxyBase<VariableMeasurementProxy<FullSize, ReadOnly>,
0422                            FullSize, ReadOnly>;
0423   using Index = typename Base::Index;
0424   using SubspaceIndex = typename Base::SubspaceIndex;
0425   using Scalar = typename Base::Scalar;
0426   using Container = typename Base::Container;
0427 
0428   using SubspaceHelper = Acts::VariableSubspaceHelper<FullSize>;
0429 
0430   using SubspaceVector = Eigen::Matrix<SubspaceIndex, Eigen::Dynamic, 1>;
0431   using SubspaceVectorMap =
0432       std::conditional_t<ReadOnly, Eigen::Map<const SubspaceVector>,
0433                          Eigen::Map<SubspaceVector>>;
0434 
0435   using ParametersVector = Eigen::Matrix<Scalar, Eigen::Dynamic, 1>;
0436   using ParametersVectorMap =
0437       std::conditional_t<ReadOnly, Eigen::Map<const ParametersVector>,
0438                          Eigen::Map<ParametersVector>>;
0439 
0440   using CovarianceMatrix =
0441       Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic>;
0442   using CovarianceMatrixMap =
0443       std::conditional_t<ReadOnly, Eigen::Map<const CovarianceMatrix>,
0444                          Eigen::Map<CovarianceMatrix>>;
0445 
0446   VariableMeasurementProxy(Container& container_, Index index_)
0447       : Base(container_, index_) {}
0448   template <typename OtherDerived, bool OtherReadOnly>
0449   explicit VariableMeasurementProxy(
0450       const MeasurementProxyBase<OtherDerived, FullSize, OtherReadOnly>& other)
0451     requires(ReadOnly == OtherReadOnly || ReadOnly)
0452       : Base(other) {}
0453 
0454   using Base::container;
0455   using Base::index;
0456 
0457   /// @brief Get the subspace helper for the measurement
0458   /// @return The subspace helper
0459   SubspaceHelper subspaceHelper() const {
0460     return SubspaceHelper{subspaceIndexVector()};
0461   }
0462 
0463   /// @brief Get the subspace indices of the measurement
0464   /// @return The subspace indices
0465   SubspaceVectorMap subspaceIndexVector() const {
0466     const auto size = static_cast<Eigen::Index>(this->size());
0467     return SubspaceVectorMap{
0468         container().m_subspaceIndices.data() +
0469             container().m_entries.at(index()).subspaceIndexOffset,
0470         size};
0471   }
0472 
0473   /// @brief Get the parameters of the measurement
0474   /// @return The parameters
0475   ParametersVectorMap parameters() const {
0476     const auto size = static_cast<Eigen::Index>(this->size());
0477     return ParametersVectorMap{
0478         container().m_parameters.data() +
0479             container().m_entries.at(index()).parameterOffset,
0480         size};
0481   }
0482 
0483   /// @brief Get the covariance of the measurement
0484   /// @return The covariance
0485   CovarianceMatrixMap covariance() const {
0486     const auto size = static_cast<Eigen::Index>(this->size());
0487     return CovarianceMatrixMap{
0488         container().m_covariances.data() +
0489             container().m_entries.at(index()).covarianceOffset,
0490         size, size};
0491   }
0492 };
0493 
0494 template <MeasurementConcept OtherDerived>
0495 MeasurementContainer::VariableProxy MeasurementContainer::copyMeasurement(
0496     const OtherDerived& other) {
0497   VariableProxy meas = makeMeasurement(other.size(), other.geometryId());
0498   meas.copyFrom(other);
0499   return meas;
0500 }
0501 
0502 template <MeasurementConcept OtherDerived, std::size_t Size>
0503 MeasurementContainer::FixedProxy<Size> MeasurementContainer::copyMeasurement(
0504     const OtherDerived& other) {
0505   FixedProxy<Size> meas = makeMeasurement<Size>(other.geometryId());
0506   meas.copyFrom(other);
0507   return meas;
0508 }
0509 
0510 template <typename... Args>
0511 MeasurementContainer::VariableProxy MeasurementContainer::emplaceMeasurement(
0512     std::uint8_t size, Acts::GeometryIdentifier geometryId, Args&&... args) {
0513   VariableProxy meas = makeMeasurement(size, geometryId);
0514 
0515   meas.fill(std::forward<Args>(args)...);
0516 
0517   return meas;
0518 }
0519 
0520 template <std::size_t Size, typename... Args>
0521 MeasurementContainer::FixedProxy<Size> MeasurementContainer::emplaceMeasurement(
0522     Acts::GeometryIdentifier geometryId, Args&&... args) {
0523   FixedProxy<Size> meas = makeMeasurement<Size>(geometryId);
0524 
0525   meas.fill(std::forward<Args>(args)...);
0526 
0527   return meas;
0528 }
0529 
0530 static_assert(
0531     std::random_access_iterator<MeasurementContainer::iterator> &&
0532     std::random_access_iterator<MeasurementContainer::const_iterator>);
0533 
0534 }  // namespace ActsExamples