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