Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:10:48

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/MeasurementHelpers.hpp"
0014 #include "Acts/EventData/SourceLink.hpp"
0015 #include "Acts/EventData/TrackStatePropMask.hpp"
0016 #include "Acts/EventData/TrackStateProxy.hpp"
0017 #include "Acts/EventData/TrackStateProxyConcept.hpp"
0018 #include "Acts/EventData/TrackStateType.hpp"
0019 #include "Acts/EventData/Types.hpp"
0020 #include "Acts/Geometry/GeometryContext.hpp"
0021 #include "Acts/Utilities/AlgebraHelpers.hpp"
0022 #include "Acts/Utilities/HashedString.hpp"
0023 #include "Acts/Utilities/Helpers.hpp"
0024 #include "Acts/Utilities/ThrowAssert.hpp"
0025 
0026 #include <bitset>
0027 #include <cstddef>
0028 #include <cstdint>
0029 #include <iterator>
0030 #include <memory>
0031 #include <optional>
0032 #include <string_view>
0033 #include <type_traits>
0034 #include <vector>
0035 
0036 #include <Eigen/Core>
0037 
0038 namespace Acts {
0039 
0040 // forward declarations
0041 template <typename derived_t>
0042 class MultiTrajectory;
0043 class Surface;
0044 
0045 namespace detail_lt {
0046 
0047 /// Helper type that wraps two iterators
0048 template <bool reverse, typename trajectory_t, std::size_t M, bool ReadOnly>
0049 class TrackStateRange {
0050   using ProxyType = TrackStateProxy<trajectory_t, M, ReadOnly>;
0051   using IndexType = typename ProxyType::IndexType;
0052   static constexpr IndexType kInvalid = ProxyType::kInvalid;
0053 
0054  public:
0055   /// Iterator that wraps a track state proxy. The nullopt case signifies the
0056   /// end of the range, i.e. the "past-the-end" iterator
0057   struct Iterator {
0058     std::optional<ProxyType> proxy;
0059 
0060     using iterator_category = std::forward_iterator_tag;
0061     using value_type = ProxyType;
0062     using difference_type = std::ptrdiff_t;
0063     using pointer = void;
0064     using reference = void;
0065 
0066     Iterator& operator++() {
0067       if (!proxy) {
0068         return *this;
0069       }
0070       if constexpr (reverse) {
0071         if (proxy->hasPrevious()) {
0072           proxy = proxy->trajectory().getTrackState(proxy->previous());
0073           return *this;
0074         } else {
0075           proxy = std::nullopt;
0076           return *this;
0077         }
0078       } else {
0079         IndexType next =
0080             proxy->template component<IndexType, hashString("next")>();
0081         if (next != kInvalid) {
0082           proxy = proxy->trajectory().getTrackState(next);
0083           return *this;
0084         } else {
0085           proxy = std::nullopt;
0086           return *this;
0087         }
0088       }
0089     }
0090 
0091     Iterator operator++(int) {
0092       Iterator tmp(*this);
0093       operator++();
0094       return tmp;
0095     }
0096 
0097     bool operator==(const Iterator& other) const {
0098       if (!proxy && !other.proxy) {
0099         return true;
0100       }
0101       if (proxy && other.proxy) {
0102         return proxy->index() == other.proxy->index();
0103       }
0104       return false;
0105     }
0106 
0107     ProxyType operator*() const { return *proxy; }
0108     ProxyType operator*() { return *proxy; }
0109   };
0110 
0111   TrackStateRange(ProxyType _begin) : m_begin{_begin} {}
0112   TrackStateRange() : m_begin{std::nullopt} {}
0113 
0114   Iterator begin() { return m_begin; }
0115   Iterator end() { return Iterator{std::nullopt}; }
0116 
0117   Iterator cbegin() const { return m_begin; }
0118   Iterator cend() const { return Iterator{std::nullopt}; }
0119 
0120  private:
0121   Iterator m_begin;
0122 };
0123 
0124 // implement track state visitor concept
0125 template <typename T, typename TS>
0126 concept VisitorConcept = requires(T& t, TS& ts) {
0127   { t(ts) } -> Concepts::same_as_any_of<void, bool>;
0128 };
0129 
0130 }  // namespace detail_lt
0131 
0132 /// This namespace contains typedefs and constant values that are used by
0133 /// other parts of the @c MultiTrajectory implementation. It extracts these
0134 /// from @c TrackStateTraits using the default maximum measurement dimension.
0135 namespace MultiTrajectoryTraits {
0136 constexpr unsigned int MeasurementSizeMax = eBoundSize;
0137 using IndexType = TrackIndexType;
0138 constexpr IndexType kInvalid = kTrackIndexInvalid;
0139 }  // namespace MultiTrajectoryTraits
0140 
0141 template <typename T>
0142 struct IsReadOnlyMultiTrajectory;
0143 
0144 /// Store a trajectory of track states with multiple components.
0145 ///
0146 /// This container supports both simple, sequential trajectories as well
0147 /// as combinatorial or multi-component trajectories. Each point can store
0148 /// a parent point such that the trajectory forms a directed, acyclic graph
0149 /// of sub-trajectories. From a set of endpoints, all possible sub-components
0150 /// can be easily identified. Some functionality is provided to simplify
0151 /// iterating over specific sub-components.
0152 template <typename derived_t>
0153 class MultiTrajectory {
0154  public:
0155   using Derived = derived_t;
0156 
0157   static constexpr bool ReadOnly = IsReadOnlyMultiTrajectory<Derived>::value;
0158 
0159   // Pull out type alias and re-expose them for ease of use.
0160   static constexpr unsigned int MeasurementSizeMax =
0161       MultiTrajectoryTraits::MeasurementSizeMax;
0162 
0163   friend class TrackStateProxy<Derived, MeasurementSizeMax, true>;
0164   friend class TrackStateProxy<Derived, MeasurementSizeMax, false>;
0165   template <typename T>
0166   friend class MultiTrajectory;
0167 
0168   /// Alias for the const version of a track state proxy, with the same
0169   /// backends as this container
0170   using ConstTrackStateProxy =
0171       Acts::TrackStateProxy<Derived, MeasurementSizeMax, true>;
0172 
0173   /// Alias for the mutable version of a track state proxy, with the same
0174   /// backends as this container
0175   using TrackStateProxy =
0176       Acts::TrackStateProxy<Derived, MeasurementSizeMax, false>;
0177 
0178   /// The index type of the track state container
0179   using IndexType = typename TrackStateProxy::IndexType;
0180 
0181   /// Sentinel value that indicates an invalid index
0182   static constexpr IndexType kInvalid = TrackStateProxy::kInvalid;
0183 
0184  protected:
0185   MultiTrajectory() = default;  // pseudo abstract base class
0186 
0187  private:
0188   /// Helper to static cast this to the Derived class for CRTP
0189   constexpr Derived& self() { return static_cast<Derived&>(*this); }
0190   /// Helper to static cast this to the Derived class for CRTP. Const version.
0191   constexpr const Derived& self() const {
0192     return static_cast<const Derived&>(*this);
0193   }
0194 
0195   /// Helper function to check if a component exists IF it is an optional one.
0196   /// Used in assertions
0197   bool checkOptional(HashedString key, IndexType istate) const {
0198     using namespace Acts::HashedStringLiteral;
0199     switch (key) {
0200       case "predicted"_hash:
0201       case "filtered"_hash:
0202       case "smoothed"_hash:
0203       case "calibrated"_hash:
0204       case "jacobian"_hash:
0205       case "projector"_hash:
0206         return self().has_impl(key, istate);
0207       default:
0208         return true;
0209     }
0210   }
0211 
0212  public:
0213   /// @anchor track_state_container_track_access
0214   /// @name MultiTrajectory track state (proxy) access and manipulation
0215   ///
0216   /// These methods allow accessing track states, i.e. adding or retrieving a
0217   /// track state proxy that points at a specific track state in the container.
0218   ///
0219   /// @{
0220 
0221   /// Access a read-only point on the trajectory by index.
0222   /// @note Only available if the MultiTrajectory is not read-only
0223   /// @param istate The index to access
0224   /// @return Read only proxy to the stored track state
0225   ConstTrackStateProxy getTrackState(IndexType istate) const {
0226     return {*this, istate};
0227   }
0228 
0229   /// Access a writable point on the trajectory by index.
0230   /// @note Only available if the MultiTrajectory is not read-only
0231   /// @param istate The index to access
0232   /// @return Read-write proxy to the stored track state
0233   TrackStateProxy getTrackState(IndexType istate)
0234     requires(!ReadOnly)
0235   {
0236     return {*this, istate};
0237   }
0238 
0239   /// Add a track state without providing explicit information. Which components
0240   /// of the track state are initialized/allocated can be controlled via @p mask
0241   /// @note Only available if the MultiTrajectory is not read-only
0242   /// @param mask The bitmask that instructs which components to allocate and
0243   ///       which to leave invalid
0244   /// @param iprevious index of the previous state, kInvalid if first
0245   /// @return Index of the newly added track state
0246   IndexType addTrackState(TrackStatePropMask mask = TrackStatePropMask::All,
0247                           IndexType iprevious = kInvalid)
0248     requires(!ReadOnly)
0249   {
0250     return self().addTrackState_impl(mask, iprevious);
0251   }
0252 
0253   /// Add a track state to the container and return a track state proxy to it
0254   /// This effectively calls @c addTrackState and @c getTrackState
0255   /// @note Only available if the track state container is not read-only
0256   /// @return a track state proxy to the newly added track state
0257   TrackStateProxy makeTrackState(
0258       TrackStatePropMask mask = TrackStatePropMask::All,
0259       IndexType iprevious = kInvalid)
0260     requires(!ReadOnly)
0261   {
0262     return getTrackState(addTrackState(mask, iprevious));
0263   }
0264 
0265   /// @}
0266 
0267   /// @anchor track_state_container_iteration
0268   /// @name MultiTrajectory track state iteration
0269   /// @{
0270 
0271   /// Visit all previous states starting at a given endpoint.
0272   ///
0273   /// @param iendpoint  index of the last state
0274   /// @param callable   non-modifying functor to be called with each point
0275   template <typename F>
0276   void visitBackwards(IndexType iendpoint, F&& callable) const
0277     requires detail_lt::VisitorConcept<F, ConstTrackStateProxy>;
0278 
0279   /// Apply a function to all previous states starting at a given endpoint.
0280   ///
0281   /// @param iendpoint  index of the last state
0282   /// @param callable   modifying functor to be called with each point
0283   ///
0284   /// @warning If the trajectory contains multiple components with common
0285   ///          points, this can have an impact on the other components.
0286   /// @note Only available if the MultiTrajectory is not read-only
0287   template <typename F>
0288   void applyBackwards(IndexType iendpoint, F&& callable)
0289     requires(!ReadOnly) && detail_lt::VisitorConcept<F, TrackStateProxy>
0290   {
0291     if (iendpoint == MultiTrajectoryTraits::kInvalid) {
0292       throw std::runtime_error(
0293           "Cannot apply backwards with kInvalid as endpoint");
0294     }
0295 
0296     while (true) {
0297       auto ts = getTrackState(iendpoint);
0298       if constexpr (std::is_same_v<std::invoke_result_t<F, TrackStateProxy>,
0299                                    bool>) {
0300         bool proceed = callable(ts);
0301         // this point has no parent and ends the trajectory, or a break was
0302         // requested
0303         if (!proceed || !ts.hasPrevious()) {
0304           break;
0305         }
0306       } else {
0307         callable(ts);
0308         // this point has no parent and ends the trajectory
0309         if (!ts.hasPrevious()) {
0310           break;
0311         }
0312       }
0313       iendpoint = ts.previous();
0314     }
0315   }
0316 
0317   /// Range for the track states from @p iendpoint to the trajectory start
0318   /// @param iendpoint Trajectory entry point to start from
0319   /// @return Iterator pair to iterate over
0320   /// @note Const version
0321   auto reverseTrackStateRange(IndexType iendpoint) const {
0322     using range_t =
0323         detail_lt::TrackStateRange<true, Derived, MeasurementSizeMax, true>;
0324     if (iendpoint == kInvalid) {
0325       return range_t{};
0326     }
0327 
0328     return range_t{getTrackState(iendpoint)};
0329   }
0330 
0331   /// Range for the track states from @p iendpoint to the trajectory start,
0332   /// i.e from the outside in.
0333   /// @note Only available if the MultiTrajectory is not read-only
0334   /// @param iendpoint Trajectory entry point to start from
0335   /// @return Iterator pair to iterate over
0336   /// @note Mutable version
0337   auto reverseTrackStateRange(IndexType iendpoint)
0338     requires(!ReadOnly)
0339   {
0340     using range_t =
0341         detail_lt::TrackStateRange<true, Derived, MeasurementSizeMax, false>;
0342     if (iendpoint == kInvalid) {
0343       return range_t{};
0344     }
0345 
0346     return range_t{getTrackState(iendpoint)};
0347   }
0348 
0349   /// Range for the track states from @p istartpoint to the trajectory end,
0350   /// i.e from inside out
0351   /// @param istartpoint Trajectory state index for the innermost track
0352   ///        state to start from
0353   /// @return Iterator pair to iterate over
0354   /// @note Const version
0355   auto forwardTrackStateRange(IndexType istartpoint) const {
0356     using range_t =
0357         detail_lt::TrackStateRange<false, Derived, MeasurementSizeMax, true>;
0358     if (istartpoint == kInvalid) {
0359       return range_t{};
0360     }
0361 
0362     return range_t{getTrackState(istartpoint)};
0363   }
0364 
0365   /// Range for the track states from @p istartpoint to the trajectory end,
0366   /// i.e from inside out
0367   /// @note Only available if the MultiTrajectory is not read-only
0368   /// @param istartpoint Trajectory state index for the innermost track
0369   ///        state to start from
0370   /// @return Iterator pair to iterate over
0371   auto forwardTrackStateRange(IndexType istartpoint)
0372     requires(!ReadOnly)
0373   {
0374     using range_t =
0375         detail_lt::TrackStateRange<false, Derived, MeasurementSizeMax, false>;
0376     if (istartpoint == kInvalid) {
0377       return range_t{};
0378     }
0379 
0380     return range_t{getTrackState(istartpoint)};
0381   }
0382 
0383   /// @}
0384 
0385   /// @anchor track_state_container_columns
0386   /// @name MultiTrajectory column management
0387   /// MultiTrajectory can manage a set of common static columns, and dynamic
0388   /// columns that can be added at runtime. This set of methods allows you to
0389   /// manage the dynamic columns.
0390   /// @{
0391 
0392   /// Add a column to the @c MultiTrajectory
0393   /// @tparam T Type of the column values to add
0394   /// @param key the name of the column to be added
0395   /// @note This takes a string argument rather than a hashed string to maintain
0396   ///       compatibility with backends.
0397   /// @note Only available if the MultiTrajectory is not read-only
0398   template <typename T>
0399   void addColumn(std::string_view key)
0400     requires(!ReadOnly)
0401   {
0402     self().template addColumn_impl<T>(key);
0403   }
0404 
0405   /// Check if a column with a key @p key exists.
0406   /// @param key Key to check for a column with
0407   /// @return True if the column exists, false if not.
0408   bool hasColumn(HashedString key) const { return self().hasColumn_impl(key); }
0409 
0410   /// @}
0411 
0412   /// Clear the @c MultiTrajectory. Leaves the underlying storage untouched
0413   /// @note Only available if the MultiTrajectory is not read-only
0414   void clear()
0415     requires(!ReadOnly)
0416   {
0417     self().clear_impl();
0418   }
0419 
0420   /// Returns the number of track states contained
0421   /// @return The number of track states
0422   IndexType size() const { return self().size_impl(); }
0423 
0424  protected:
0425   // These are internal helper functions which the @c TrackStateProxy class talks to
0426 
0427   /// Check for component existence of @p key in track satet @p istate
0428   /// @param key The key for which to check
0429   /// @param istate The track state index to check
0430   /// @return True if the component exists, false if not
0431   bool has(HashedString key, IndexType istate) const {
0432     return self().has_impl(key, istate);
0433   }
0434 
0435   /// Check for component existence of @p key in track satet @p istate
0436   /// @tparam key The key for which to check
0437   /// @param istate The track state index to check
0438   /// @return True if the component exists, false if not
0439   template <HashedString key>
0440   bool has(IndexType istate) const {
0441     return self().has_impl(key, istate);
0442   }
0443 
0444   /// Retrieve a parameter proxy instance for parameters at a given index
0445   /// @param parIdx Index into the parameter column
0446   /// @return Mutable proxy
0447   typename TrackStateProxy::Parameters parameters(IndexType parIdx)
0448     requires(!ReadOnly)
0449   {
0450     return self().parameters_impl(parIdx);
0451   }
0452 
0453   /// Retrieve a parameter proxy instance for parameters at a given index
0454   /// @param parIdx Index into the parameter column
0455   /// @return Const proxy
0456   typename ConstTrackStateProxy::Parameters parameters(IndexType parIdx) const {
0457     return self().parameters_impl(parIdx);
0458   }
0459 
0460   /// Retrieve a covariance proxy instance for a covariance at a given index
0461   /// @param covIdx Index into the covariance column
0462   /// @return Mutable proxy
0463   typename TrackStateProxy::Covariance covariance(IndexType covIdx)
0464     requires(!ReadOnly)
0465   {
0466     return self().covariance_impl(covIdx);
0467   }
0468 
0469   /// Retrieve a covariance proxy instance for a covariance at a given index
0470   /// @param covIdx Index into the covariance column
0471   /// @return Const proxy
0472   typename ConstTrackStateProxy::Covariance covariance(IndexType covIdx) const {
0473     return self().covariance_impl(covIdx);
0474   }
0475 
0476   /// Retrieve a jacobian proxy instance for a jacobian at a given index
0477   /// @param istate The track state
0478   /// @return Mutable proxy
0479   typename TrackStateProxy::Covariance jacobian(IndexType istate)
0480     requires(!ReadOnly)
0481   {
0482     return self().jacobian_impl(istate);
0483   }
0484 
0485   /// Retrieve a jacobian proxy instance for a jacobian at a given index
0486   /// @param istate The track state
0487   /// @return Const proxy
0488   typename ConstTrackStateProxy::Covariance jacobian(IndexType istate) const {
0489     return self().jacobian_impl(istate);
0490   }
0491 
0492   /// Retrieve a calibrated measurement proxy instance for a measurement at a
0493   /// given index
0494   /// @tparam measdim the measurement dimension
0495   /// @param istate The track state
0496   /// @return Mutable proxy
0497   template <std::size_t measdim>
0498   typename TrackStateProxy::template Calibrated<measdim> calibrated(
0499       IndexType istate)
0500     requires(!ReadOnly)
0501   {
0502     return self().template calibrated_impl<measdim>(istate);
0503   }
0504 
0505   /// Retrieve a calibrated measurement proxy instance for a measurement at a
0506   /// given index
0507   /// @tparam measdim the measurement dimension
0508   /// @param istate The track state
0509   /// @return Const proxy
0510   template <std::size_t measdim>
0511   typename ConstTrackStateProxy::template Calibrated<measdim> calibrated(
0512       IndexType istate) const {
0513     return self().template calibrated_impl<measdim>(istate);
0514   }
0515 
0516   /// Retrieve a calibrated measurement covariance proxy instance for a
0517   /// measurement at a given index
0518   /// @tparam measdim the measurement dimension
0519   /// @param istate The track state
0520   /// @return Mutable proxy
0521   template <std::size_t measdim>
0522   typename TrackStateProxy::template CalibratedCovariance<measdim>
0523   calibratedCovariance(IndexType istate)
0524     requires(!ReadOnly)
0525   {
0526     return self().template calibratedCovariance_impl<measdim>(istate);
0527   }
0528 
0529   /// Retrieve a calibrated measurement covariance proxy instance for a
0530   /// measurement at a given index
0531   /// @param istate The track state
0532   /// @return Mutable proxy
0533   typename TrackStateProxy::EffectiveCalibrated effectiveCalibrated(
0534       IndexType istate)
0535     requires(!ReadOnly)
0536   {
0537     // This abuses an incorrectly sized vector / matrix to access the
0538     // data pointer! This works (don't use the matrix as is!), but be
0539     // careful!
0540     return typename TrackStateProxy::EffectiveCalibrated{
0541         calibrated<eBoundSize>(istate).data(), calibratedSize(istate)};
0542   }
0543 
0544   /// Retrieve a calibrated measurement covariance proxy instance for a
0545   /// measurement at a given index
0546   /// @param istate The track state
0547   /// @return Const proxy
0548   typename ConstTrackStateProxy::EffectiveCalibrated effectiveCalibrated(
0549       IndexType istate) const {
0550     // This abuses an incorrectly sized vector / matrix to access the
0551     // data pointer! This works (don't use the matrix as is!), but be
0552     // careful!
0553     return typename ConstTrackStateProxy::EffectiveCalibrated{
0554         calibrated<eBoundSize>(istate).data(), calibratedSize(istate)};
0555   }
0556 
0557   /// Retrieve a calibrated measurement covariance proxy instance for a
0558   /// measurement at a given index
0559   /// @param istate The track state
0560   /// @return Mutable proxy
0561   typename TrackStateProxy::EffectiveCalibratedCovariance
0562   effectiveCalibratedCovariance(IndexType istate)
0563     requires(!ReadOnly)
0564   {
0565     // This abuses an incorrectly sized vector / matrix to access the
0566     // data pointer! This works (don't use the matrix as is!), but be
0567     // careful!
0568     return typename TrackStateProxy::EffectiveCalibratedCovariance{
0569         calibratedCovariance<eBoundSize>(istate).data(), calibratedSize(istate),
0570         calibratedSize(istate)};
0571   }
0572 
0573   /// Retrieve a calibrated measurement covariance proxy instance for a
0574   /// measurement at a given index
0575   /// @param istate The track state
0576   /// @return Const proxy
0577   typename ConstTrackStateProxy::EffectiveCalibratedCovariance
0578   effectiveCalibratedCovariance(IndexType istate) const {
0579     // This abuses an incorrectly sized vector / matrix to access the
0580     // data pointer! This works (don't use the matrix as is!), but be
0581     // careful!
0582     return typename ConstTrackStateProxy::EffectiveCalibratedCovariance{
0583         calibratedCovariance<eBoundSize>(istate).data(), calibratedSize(istate),
0584         calibratedSize(istate)};
0585   }
0586 
0587   /// Retrieve a calibrated measurement covariance proxy instance for a
0588   /// measurement at a given index
0589   /// @param istate The track state
0590   /// @return Const proxy
0591   template <std::size_t measdim>
0592   typename ConstTrackStateProxy::template CalibratedCovariance<measdim>
0593   calibratedCovariance(IndexType istate) const {
0594     return self().template calibratedCovariance_impl<measdim>(istate);
0595   }
0596 
0597   /// Get the calibrated measurement size for a track state
0598   /// @param istate The track state
0599   /// @return the calibrated size
0600   IndexType calibratedSize(IndexType istate) const {
0601     return self().calibratedSize_impl(istate);
0602   }
0603 
0604   /// Share a shareable component from between track state.
0605   /// @param iself The track state index to share "into"
0606   /// @param iother The track state index to share from
0607   /// @param shareSource Which component to share from
0608   /// @param shareTarget Which component to share as. This doesn't have to be the same
0609   ///                    as @p shareSource, e.g. predicted can be shared as filtered.
0610   /// @note Shareable components are predicted, filtered, smoothed, calibrated, jacobian,
0611   ///       or projector. See @c TrackStatePropMask.
0612   /// @note The track states both need to be stored in the
0613   ///       same @c MultiTrajectory instance
0614   void shareFrom(IndexType iself, IndexType iother,
0615                  TrackStatePropMask shareSource, TrackStatePropMask shareTarget)
0616     requires(!ReadOnly)
0617   {
0618     self().shareFrom_impl(iself, iother, shareSource, shareTarget);
0619   }
0620 
0621   /// Unset an optional track state component
0622   /// @param target The component to unset
0623   /// @param istate The track state index to operate on
0624   void unset(TrackStatePropMask target, IndexType istate)
0625     requires(!ReadOnly)
0626   {
0627     self().unset_impl(target, istate);
0628   }
0629 
0630   /// Add additional components to an existing track state
0631   /// @note Only available if the track state container is not read-only
0632   /// @param istate The track state index to alter
0633   /// @param mask The bitmask that instructs which components to allocate
0634   void addTrackStateComponents(IndexType istate, TrackStatePropMask mask)
0635     requires(!ReadOnly)
0636   {
0637     self().addTrackStateComponents_impl(istate, mask);
0638   }
0639 
0640   /// Retrieve a mutable reference to a component
0641   /// @tparam T The type of the component to access
0642   /// @tparam key String key for the component to access
0643   /// @param istate The track state index to operate on
0644   /// @return Mutable reference to the component given by @p key
0645   template <typename T, HashedString key>
0646   T& component(IndexType istate)
0647     requires(!ReadOnly)
0648   {
0649     assert(checkOptional(key, istate));
0650     return *std::any_cast<T*>(self().component_impl(key, istate));
0651   }
0652 
0653   /// Retrieve a mutable reference to a component
0654   /// @tparam T The type of the component to access
0655   /// @param key String key for the component to access
0656   /// @param istate The track state index to operate on
0657   /// @return Mutable reference to the component given by @p key
0658   template <typename T>
0659   T& component(HashedString key, IndexType istate)
0660     requires(!ReadOnly)
0661   {
0662     assert(checkOptional(key, istate));
0663     return *std::any_cast<T*>(self().component_impl(key, istate));
0664   }
0665 
0666   /// Retrieve a const reference to a component
0667   /// @tparam T The type of the component to access
0668   /// @tparam key String key for the component to access
0669   /// @param istate The track state index to operate on
0670   /// @return Const reference to the component given by @p key
0671   template <typename T, HashedString key>
0672   const T& component(IndexType istate) const {
0673     assert(checkOptional(key, istate));
0674     return *std::any_cast<const T*>(self().component_impl(key, istate));
0675   }
0676 
0677   /// Retrieve a const reference to a component
0678   /// @tparam T The type of the component to access
0679   /// @param key String key for the component to access
0680   /// @param istate The track state index to operate on
0681   /// @return Const reference to the component given by @p key
0682   template <typename T>
0683   const T& component(HashedString key, IndexType istate) const {
0684     assert(checkOptional(key, istate));
0685     return *std::any_cast<const T*>(self().component_impl(key, istate));
0686   }
0687 
0688   /// Allocate storage for a calibrated measurement of specified dimension
0689   /// @param istate The track state to store for
0690   /// @param measdim the dimension of the measurement to store
0691   /// @note In case an allocation is already present, no additional allocation
0692   ///       will be performed, but the existing allocation will be zeroed.
0693   void allocateCalibrated(IndexType istate, std::size_t measdim) {
0694     throw_assert(measdim > 0 && measdim <= eBoundSize,
0695                  "Invalid measurement dimension detected");
0696 
0697     visit_measurement(measdim, [this, istate]<std::size_t DIM>(
0698                                    std::integral_constant<std::size_t, DIM>) {
0699       self().allocateCalibrated_impl(
0700           istate, ActsVector<DIM>{ActsVector<DIM>::Zero()},
0701           ActsSquareMatrix<DIM>{ActsSquareMatrix<DIM>::Zero()});
0702     });
0703   }
0704 
0705   template <std::size_t measdim, typename val_t, typename cov_t>
0706   void allocateCalibrated(IndexType istate, const Eigen::DenseBase<val_t>& val,
0707                           const Eigen::DenseBase<cov_t>& cov) {
0708     self().allocateCalibrated_impl(istate, val, cov);
0709   }
0710 
0711   void setUncalibratedSourceLink(IndexType istate, SourceLink&& sourceLink)
0712     requires(!ReadOnly)
0713   {
0714     self().setUncalibratedSourceLink_impl(istate, std::move(sourceLink));
0715   }
0716 
0717   SourceLink getUncalibratedSourceLink(IndexType istate) const {
0718     return self().getUncalibratedSourceLink_impl(istate);
0719   }
0720 
0721   const Surface* referenceSurface(IndexType istate) const {
0722     return self().referenceSurface_impl(istate);
0723   }
0724 
0725   void setReferenceSurface(IndexType istate,
0726                            std::shared_ptr<const Surface> surface)
0727     requires(!ReadOnly)
0728   {
0729     self().setReferenceSurface_impl(istate, std::move(surface));
0730   }
0731 
0732  private:
0733   template <typename T>
0734   void copyDynamicFrom(IndexType dstIdx, const T& src, IndexType srcIdx)
0735     requires(!ReadOnly)
0736   {
0737     const auto& dynamicKeys = src.self().dynamicKeys_impl();
0738     for (const auto key : dynamicKeys) {
0739       std::any srcPtr = src.self().component_impl(key, srcIdx);
0740       self().copyDynamicFrom_impl(dstIdx, key, srcPtr);
0741     }
0742   }
0743 };
0744 
0745 }  // namespace Acts
0746 
0747 #include "Acts/EventData/MultiTrajectory.ipp"