Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-03-30 07:45:36

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/EventData/SourceLink.hpp"
0012 #include "Acts/EventData/TrackStatePropMask.hpp"
0013 #include "Acts/EventData/TrackStateProxyCommon.hpp"
0014 #include "Acts/EventData/TrackStateProxyConcept.hpp"
0015 #include "Acts/EventData/Types.hpp"
0016 #include "Acts/Surfaces/Surface.hpp"
0017 #include "Acts/Utilities/HashedString.hpp"
0018 #include "Acts/Utilities/Helpers.hpp"
0019 
0020 #include <cstddef>
0021 
0022 #include <Eigen/Core>
0023 
0024 namespace Acts {
0025 
0026 template <typename derived_t>
0027 class MultiTrajectory;
0028 
0029 /// Type-erased track state proxy for any trajectory backend.
0030 /// @tparam read_only True for const access, false for mutable access.
0031 template <bool read_only>
0032 class AnyTrackStateProxy;
0033 
0034 namespace detail_lt {
0035 
0036 /// Helper type to make a member pointers constness transitive.
0037 template <typename T>
0038 class TransitiveConstPointer {
0039  public:
0040   using element_type = T;
0041   TransitiveConstPointer() = default;
0042   explicit TransitiveConstPointer(T* ptr) : m_ptr{ptr} {}
0043 
0044   template <typename U>
0045   explicit TransitiveConstPointer(const TransitiveConstPointer<U>& other)
0046       : m_ptr{other.ptr()} {}
0047 
0048   template <typename U>
0049   TransitiveConstPointer& operator=(const TransitiveConstPointer<U>& other) {
0050     m_ptr = other.m_ptr;
0051     return *this;
0052   }
0053 
0054   template <typename U>
0055   bool operator==(const TransitiveConstPointer<U>& other) const {
0056     return m_ptr == other.m_ptr;
0057   }
0058 
0059   const T* operator->() const { return m_ptr; }
0060 
0061   T* operator->() { return m_ptr; }
0062 
0063   template <typename U>
0064   friend class TransitiveConstPointer;
0065   template <bool R>
0066   friend class AnyTrackStateProxy;
0067 
0068   const T& operator*() const { return *m_ptr; }
0069 
0070   T& operator*() { return *m_ptr; }
0071 
0072   explicit operator bool() const { return m_ptr != nullptr; }
0073 
0074   const T* ptr() const { return m_ptr; }
0075   T* ptr() { return m_ptr; }
0076 
0077  private:
0078   T* m_ptr{nullptr};
0079 };
0080 
0081 }  // namespace detail_lt
0082 
0083 /// Proxy object to access a single point on the trajectory.
0084 ///
0085 /// @tparam SourceLink Type to link back to an original measurement
0086 /// @tparam M          Maximum number of measurement dimensions
0087 /// @tparam read_only  true for read-only access to underlying storage
0088 template <typename trajectory_t, std::size_t M, bool read_only = true>
0089 class TrackStateProxy
0090     : public TrackStateProxyCommon<TrackStateProxy<trajectory_t, M, read_only>,
0091                                    read_only> {
0092   using Base =
0093       TrackStateProxyCommon<TrackStateProxy<trajectory_t, M, read_only>,
0094                             read_only>;
0095 
0096   friend class TrackStateProxyCommon<
0097       TrackStateProxy<trajectory_t, M, read_only>, read_only>;
0098 
0099  public:
0100   /// Indicates whether this track state proxy is read-only or if it can be
0101   /// modified
0102   static constexpr bool ReadOnly = read_only;
0103 
0104   /// Alias for an associated const track state proxy, with the same backends
0105   using ConstProxyType = TrackStateProxy<trajectory_t, M, true>;
0106 
0107   /// Map-type for a bound parameter vector. This has reference semantics, i.e.
0108   /// points at a matrix by an internal pointer.
0109   using Parameters = typename TrackStateTraits<M, false>::Parameters;
0110 
0111   /// Same as @ref Parameters, but with const semantics
0112   using ConstParameters = typename TrackStateTraits<M, true>::Parameters;
0113 
0114   /// Map-type for a bound covariance. This has reference semantics, i.e.
0115   /// points at a matrix by an internal pointer.
0116   using Covariance = typename TrackStateTraits<M, false>::Covariance;
0117 
0118   /// Jacobian shape is identical to @ref Covariance
0119   using Jacobian = typename TrackStateTraits<M, false>::Covariance;
0120 
0121   /// Same as @ref Covariance, but with const semantics
0122   using ConstCovariance = typename TrackStateTraits<M, true>::Covariance;
0123 
0124   /// Jacobian shape is identical to @ref Covariance
0125   using ConstJacobian = typename TrackStateTraits<M, true>::Covariance;
0126 
0127   /// Map-type for a calibrated measurement vector, where the local measurement
0128   /// dimension is variable.
0129   template <std::size_t N>
0130   using Calibrated = typename TrackStateTraits<N, false>::Calibrated;
0131 
0132   /// Same as @c Calibrated, but with const semantics
0133   template <std::size_t N>
0134   using ConstCalibrated = typename TrackStateTraits<N, true>::Calibrated;
0135 
0136   /// Map-type for a calibrated measurement covariance matrix, where the local
0137   /// measurement dimension is variable.
0138   template <std::size_t N>
0139   using CalibratedCovariance =
0140       typename TrackStateTraits<N, false>::CalibratedCovariance;
0141 
0142   /// Same as @ref CalibratedCovariance, but with const semantics
0143   template <std::size_t N>
0144   using ConstCalibratedCovariance =
0145       typename TrackStateTraits<N, true>::CalibratedCovariance;
0146 
0147   /// Map-type for a measurement vector, where the local measurement dimension
0148   /// is variable.
0149   using EffectiveCalibrated =
0150       typename TrackStateTraits<M, false>::EffectiveCalibrated;
0151 
0152   /// Same as @c EffectiveCalibrated, but with const semantics
0153   using ConstEffectiveCalibrated =
0154       typename TrackStateTraits<M, true>::EffectiveCalibrated;
0155 
0156   /// Map-type for a measurement covariance matrix, where the local measurement
0157   /// dimension is variable.
0158   using EffectiveCalibratedCovariance =
0159       typename TrackStateTraits<M, false>::EffectiveCalibratedCovariance;
0160 
0161   /// Same as @ref EffectiveCalibratedCovariance, but with const semantics
0162   using ConstEffectiveCalibratedCovariance =
0163       typename TrackStateTraits<M, true>::EffectiveCalibratedCovariance;
0164 
0165   /// The index type of the track state container
0166   using IndexType = TrackIndexType;
0167 
0168   /// Sentinel value that indicates an invalid index
0169   static constexpr IndexType kInvalid = kTrackIndexInvalid;
0170 
0171   /// The track state container backend given as a template parameter
0172   using Trajectory = trajectory_t;
0173 
0174   using Base::allocateCalibrated;
0175   using Base::calibrated;
0176   using Base::calibratedCovariance;
0177   using Base::chi2;
0178   using Base::covariance;
0179   using Base::effectiveCalibrated;
0180   using Base::effectiveCalibratedCovariance;
0181   using Base::filtered;
0182   using Base::filteredCovariance;
0183   using Base::getMask;
0184   using Base::hasCalibrated;
0185   using Base::hasFiltered;
0186   using Base::hasJacobian;
0187   using Base::hasPredicted;
0188   using Base::hasPrevious;
0189   using Base::hasProjector;
0190   using Base::hasSmoothed;
0191   using Base::parameters;
0192   using Base::pathLength;
0193   using Base::predicted;
0194   using Base::predictedCovariance;
0195   using Base::previous;
0196   using Base::projectorSubspaceHelper;
0197   using Base::projectorSubspaceIndices;
0198   using Base::setProjectorSubspaceIndices;
0199   using Base::smoothed;
0200   using Base::smoothedCovariance;
0201   using Base::typeFlags;
0202 
0203   /// @anchor track_state_proxy_construct
0204   /// @name Constructors and assignment operator
0205   ///
0206   /// Public constructors and assignment operators for @c TrackStateProxy only
0207   /// allow construction from another @c TrackStateProxy. You should generally
0208   /// not have to construct @c TrackStateProxy manually.
0209   ///
0210   /// @{
0211 
0212   /// Copy constructor: const to const or mutable to mutable
0213   /// @param other The other TrackStateProxy to construct from
0214   TrackStateProxy(const TrackStateProxy& other) = default;
0215 
0216   /// Copy assignment operator: const to const or mutable to mutable
0217   /// @param other The other TrackStateProxy to assign from
0218   /// @return Reference to this TrackStateProxy
0219   TrackStateProxy& operator=(const TrackStateProxy& other) = default;
0220 
0221   /// Constructor from mutable TrackStateProxy
0222   /// @note Only available if the track state proxy is read-only
0223   /// @param other The other TrackStateProxy to construct from
0224   explicit TrackStateProxy(const TrackStateProxy<Trajectory, M, false>& other)
0225     requires ReadOnly
0226       : m_traj{other.m_traj}, m_istate{other.m_istate} {}
0227 
0228   /// Assignment operator to from mutable @c TrackStateProxy
0229   /// @param other The other TrackStateProxy to assign from
0230   /// @note Only available if the track state proxy is read-only
0231   /// @return Reference to this TrackStateProxy
0232   TrackStateProxy& operator=(const TrackStateProxy<Trajectory, M, false>& other)
0233     requires ReadOnly
0234   {
0235     m_traj = other.m_traj;
0236     m_istate = other.m_istate;
0237 
0238     return *this;
0239   }
0240 
0241   /// @}
0242 
0243   /// @anchor track_state_proxy_props
0244   /// @name Track state properties
0245   ///
0246   /// Properties of the track state represented by @c TrackStateProxy.
0247   ///
0248   /// Many of these methods come in a @c const and a non-@c const version. The
0249   /// non-@c const version is only available if you have an instance of
0250   /// @c TrackStateProxy that does not have the @c read_only template parameter set to
0251   /// @c true, even if you hold it as an lvalue.
0252   ///
0253   /// The track states each have an index in the track state container. The
0254   /// sequence of track states is implemented as a one or two-way linked list,
0255   /// which uses indices into the same container.
0256   ///
0257   /// Each track state has a @c previous index, which points at the track state
0258   /// immediately preceding. A track state with a @c previous index of @c
0259   /// kInvalid is the first (innermost) track state in a track or track
0260   /// candidate. This is also referred to as a *stem* at the track level.
0261   ///
0262   /// During track finding and fitting, track states are usually appended to the
0263   /// sequence, populating the @c previous index of the new track state. Combinatorial
0264   /// track finding can produce track states which fork in this way, by having
0265   /// more than one track state with the same @c previous index.
0266   ///
0267   /// The track states have static, optional and dynamic properties. Static
0268   /// properties are always present, and can always be retrieved. Optional
0269   /// components use an extra indirection mechanism that coordinates with the
0270   /// backend to allow both not having the component set, or sharing it with
0271   /// other track states. An example is a branching trajectory from track
0272   /// finding which shares the same predicted parameter vector and associated
0273   /// covariance.
0274   ///
0275   /// Optional components are
0276   /// - predicted parameters and covariance
0277   /// - filtered parameters and covariance
0278   /// - smoothed parameters and covariance
0279   /// - jacobian
0280   /// - calibrated measurement info including projector
0281   ///
0282   /// They can be unset via @ref unset, @ref getMask can be used to check which
0283   /// components are present. The first four are shareable between track
0284   /// states via @ref shareFrom.
0285   ///
0286   /// @{
0287 
0288   /// Index within the trajectory.
0289   /// @return the index
0290   IndexType index() const { return m_istate; }
0291 
0292   /// Unset an optional track state component
0293   /// @note Only available if the track state proxy is not read-only
0294   /// @param target The component to unset
0295   void unset(TrackStatePropMask target)
0296     requires(!ReadOnly)
0297   {
0298     m_traj->self().unset(target, m_istate);
0299   }
0300 
0301   /// Add additional components to the track state
0302   /// @note Only available if the track state proxy is not read-only
0303   /// @param mask The bitmask that instructs which components to allocate
0304   void addComponents(TrackStatePropMask mask)
0305     requires(!ReadOnly)
0306   {
0307     m_traj->self().addTrackStateComponents_impl(m_istate, mask);
0308   }
0309 
0310   /// Reference surface.
0311   /// @return the reference surface
0312   const Surface& referenceSurface() const {
0313     assert(hasReferenceSurface() &&
0314            "TrackState does not have reference surface");
0315     return *m_traj->referenceSurface(m_istate);
0316   }
0317 
0318   /// Returns if the track state has a non nullptr surface associated
0319   /// @return whether a surface exists or not
0320   bool hasReferenceSurface() const {
0321     return m_traj->referenceSurface(m_istate) != nullptr;
0322   }
0323 
0324   // NOLINTBEGIN(performance-unnecessary-value-param)
0325   // looks like a false-positive. clang-tidy believes `srf` is not movable.
0326 
0327   /// Set the reference surface to a given value
0328   /// @param srf Shared pointer to the surface to set
0329   /// @note This overload is only present in case @c ReadOnly is false.
0330   void setReferenceSurface(std::shared_ptr<const Surface> srf)
0331     requires(!ReadOnly)
0332   {
0333     m_traj->setReferenceSurface(m_istate, std::move(srf));
0334   }
0335   // NOLINTEND(performance-unnecessary-value-param)
0336 
0337   /// @}
0338 
0339   /// Returns the jacobian from the previous trackstate to this one
0340   /// @return The jacobian matrix
0341   /// @note Const version
0342   ConstCovariance jacobian() const {
0343     assert(has<detail_tsp::kJacobianKey>());
0344     return m_traj->self().jacobian(m_istate);
0345   }
0346 
0347   /// Returns the jacobian from the previous trackstate to this one
0348   /// @return The jacobian matrix
0349   /// @note Mutable version
0350   Covariance jacobian()
0351     requires(!ReadOnly)
0352   {
0353     assert(has<detail_tsp::kJacobianKey>());
0354     return m_traj->self().jacobian(m_istate);
0355   }
0356 
0357   /// @anchor track_state_proxy_meas
0358   /// @name Track state measurement properties
0359   ///
0360   /// Properties of the measurement associated with the track state represented.
0361   /// This consists of a vector and an associated square matrix of a measurement
0362   /// dimension which is between one and the size of the track parametrization.
0363   /// The measurement coordinate frame is required to be a strict subset of the
0364   /// bound track parametrization on the local geometry coordinate frame, i.e.
0365   /// using a pure projector matrix to convert from the bound parametrization to
0366   /// the measurement frame is possible.
0367   ///
0368   /// The track state stores the parameter vector and covariance, and the
0369   /// backend is given the possibility to do so in a jagged way, i.e. only
0370   /// storing the number of values needed. This requires calling
0371   /// @ref allocateCalibrated before storing the measurements
0372   /// (even if it might be a no-op).
0373   ///
0374   /// The projector matrix is packed as a bitset, which is converted to a matrix
0375   /// on-demand (and therefore returned by value).
0376   ///
0377   /// The track state also includes a @ref SourceLink which acts as a proxy
0378   /// to the original uncalibrated measurement that the calibrated measurement
0379   /// was derived from. It is set and returned by value, to allow unpacking /
0380   /// repacking by the backend, if needed.
0381   ///
0382   /// @{
0383 
0384   /// Uncalibrated measurement in the form of a source link. Const version
0385   /// @return The uncalibrated measurement source link
0386   SourceLink getUncalibratedSourceLink() const;
0387 
0388   /// Set an uncalibrated source link
0389   /// @param sourceLink The uncalibrated source link to set
0390   void setUncalibratedSourceLink(SourceLink&& sourceLink)
0391     requires(!ReadOnly)
0392   {
0393     m_traj->setUncalibratedSourceLink(m_istate, std::move(sourceLink));
0394   }
0395 
0396   /// Return the (dynamic) number of dimensions stored for this measurement.
0397   /// @note Depending on the backend, this size is used to determine the
0398   ///       memory range of the measurement vector and covariance.
0399   /// @return The number of dimensions
0400   IndexType calibratedSize() const { return m_traj->calibratedSize(m_istate); }
0401 
0402   /// Allocate storage to be able to store a measurement of size @p measdim.
0403   /// This must be called **before** setting the measurement content.
0404   /// @param measdim Number of measurement dimensions to allocate
0405   /// @note This does not allocate if an allocation of the same size already exists
0406   /// @note This will zero-initialize the allocated storage
0407   /// @note This is an error if an existing allocation has different size
0408   void allocateCalibrated(std::size_t measdim)
0409     requires(!ReadOnly)
0410   {
0411     m_traj->allocateCalibrated(m_istate, measdim);
0412   }
0413 
0414   /// @}
0415 
0416   /// @anchor track_state_share_copy
0417   /// @name Sharing and copying
0418   ///
0419   /// Methods to share and copy track state components. Sharing means setting up
0420   /// more than one track state to point to the same component.
0421   ///
0422   /// Shareable components are
0423   /// - predicted parameters and covariance
0424   /// - filtered parameters and covariance
0425   /// - smoothed parameters and covariance
0426   /// - jacobian
0427   ///
0428   /// See @ref TrackStatePropMask.
0429   ///
0430   /// @{
0431 
0432   /// Share a shareable component **within** this track state
0433   /// @param shareSource Which component to share from
0434   /// @param shareTarget Which component to share as. This should be different from
0435   ///                    as @p shareSource, e.g. predicted can be shared as filtered.
0436   void shareFrom(TrackStatePropMask shareSource, TrackStatePropMask shareTarget)
0437     requires(!ReadOnly)
0438   {
0439     shareFrom(*this, shareSource, shareTarget);
0440   }
0441 
0442   /// Share a shareable component from another track state.
0443   /// @param other Track state proxy to share component from
0444   /// @param component Which component to share.
0445   /// @note The track states both need to be stored in the
0446   ///       same @c MultiTrajectory instance
0447   template <bool ReadOnlyOther>
0448   void shareFrom(const TrackStateProxy<Trajectory, M, ReadOnlyOther>& other,
0449                  TrackStatePropMask component)
0450     requires(!ReadOnly)
0451   {
0452     shareFrom(other, component, component);
0453   }
0454 
0455   /// Share a shareable component from another track state
0456   /// @param other Track state proxy to share component(s) from
0457   /// @param shareSource Which component to share from
0458   /// @param shareTarget Which component to share as. This can be be different from
0459   ///                    as @p shareSource, e.g. predicted can be shared as filtered.
0460   /// @note Shareable components are predicted, filtered, smoothed, calibrated, jacobian,
0461   ///       or projector. See @c TrackStatePropMask.
0462   template <bool ReadOnlyOther>
0463   void shareFrom(const TrackStateProxy<Trajectory, M, ReadOnlyOther>& other,
0464                  TrackStatePropMask shareSource, TrackStatePropMask shareTarget)
0465     requires(!ReadOnly)
0466   {
0467     assert(m_traj == other.m_traj &&
0468            "Cannot share components across MultiTrajectories");
0469 
0470     assert(ACTS_CHECK_BIT(other.getMask(), shareSource) &&
0471            "Source has incompatible allocation");
0472 
0473     m_traj->self().shareFrom(m_istate, other.m_istate, shareSource,
0474                              shareTarget);
0475   }
0476 
0477   /// Copy the contents of another track state proxy into this one
0478   /// @param other The other track state to copy from
0479   /// @param mask An optional mask to determine what to copy from
0480   /// @param onlyAllocated Whether to only copy allocated components
0481   /// @note If the this track state proxy does not have compatible allocations
0482   ///       with the source track state proxy, and @p onlyAllocated is false,
0483   ///       an exception is thrown.
0484   /// @note The mask parameter will not cause a copy of components that are
0485   ///       not allocated in the source track state proxy.
0486   template <TrackStateProxyConcept track_state_proxy_t>
0487   void copyFrom(const track_state_proxy_t& other,
0488                 TrackStatePropMask mask = TrackStatePropMask::All,
0489                 bool onlyAllocated = true)
0490     requires(!ReadOnly)
0491   {
0492     using PM = TrackStatePropMask;
0493 
0494     if (onlyAllocated) {
0495       auto dest = getMask();
0496       auto src = other.getMask() &
0497                  mask;  // combine what we have with what we want to copy
0498 
0499       if (ACTS_CHECK_BIT(src, PM::Calibrated)) {
0500         // on-demand allocate calibrated
0501         dest |= PM::Calibrated;
0502       }
0503 
0504       if ((static_cast<std::underlying_type_t<TrackStatePropMask>>(
0505                (src ^ dest) & src) != 0 ||
0506            dest == TrackStatePropMask::None ||
0507            src == TrackStatePropMask::None) &&
0508           mask != TrackStatePropMask::None) {
0509         throw std::runtime_error(
0510             "Attempt track state copy with incompatible allocations");
0511       }
0512 
0513       // we're sure now this has correct allocations, so just copy
0514       if (ACTS_CHECK_BIT(src, PM::Predicted)) {
0515         predicted() = other.predicted();
0516         predictedCovariance() = other.predictedCovariance();
0517       }
0518 
0519       if (ACTS_CHECK_BIT(src, PM::Filtered)) {
0520         filtered() = other.filtered();
0521         filteredCovariance() = other.filteredCovariance();
0522       }
0523 
0524       if (ACTS_CHECK_BIT(src, PM::Smoothed)) {
0525         smoothed() = other.smoothed();
0526         smoothedCovariance() = other.smoothedCovariance();
0527       }
0528 
0529       if (other.hasUncalibratedSourceLink()) {
0530         setUncalibratedSourceLink(other.getUncalibratedSourceLink());
0531       }
0532 
0533       if (ACTS_CHECK_BIT(src, PM::Jacobian)) {
0534         jacobian() = other.jacobian();
0535       }
0536 
0537       if (ACTS_CHECK_BIT(src, PM::Calibrated)) {
0538         visit_measurement(other.calibratedSize(), [&](auto N) {
0539           constexpr int measdim = decltype(N)::value;
0540           allocateCalibrated(
0541               other.template calibrated<measdim>().eval(),
0542               other.template calibratedCovariance<measdim>().eval());
0543         });
0544 
0545         setProjectorSubspaceIndices(other.projectorSubspaceIndices());
0546       }
0547     } else {
0548       if (ACTS_CHECK_BIT(mask, PM::Predicted) &&
0549           has<detail_tsp::kPredictedKey>() &&
0550           other.template has<detail_tsp::kPredictedKey>()) {
0551         predicted() = other.predicted();
0552         predictedCovariance() = other.predictedCovariance();
0553       }
0554 
0555       if (ACTS_CHECK_BIT(mask, PM::Filtered) &&
0556           has<detail_tsp::kFilteredKey>() &&
0557           other.template has<detail_tsp::kFilteredKey>()) {
0558         filtered() = other.filtered();
0559         filteredCovariance() = other.filteredCovariance();
0560       }
0561 
0562       if (ACTS_CHECK_BIT(mask, PM::Smoothed) &&
0563           has<detail_tsp::kSmoothedKey>() &&
0564           other.template has<detail_tsp::kSmoothedKey>()) {
0565         smoothed() = other.smoothed();
0566         smoothedCovariance() = other.smoothedCovariance();
0567       }
0568 
0569       if (other.hasUncalibratedSourceLink()) {
0570         setUncalibratedSourceLink(other.getUncalibratedSourceLink());
0571       }
0572 
0573       if (ACTS_CHECK_BIT(mask, PM::Jacobian) &&
0574           has<detail_tsp::kJacobianKey>() &&
0575           other.template has<detail_tsp::kJacobianKey>()) {
0576         jacobian() = other.jacobian();
0577       }
0578 
0579       // NOTE: we should not check hasCalibrated on this, since it
0580       // may be not yet allocated
0581       if (ACTS_CHECK_BIT(mask, PM::Calibrated) &&
0582           other.template has<detail_tsp::kCalibratedKey>()) {
0583         visit_measurement(other.calibratedSize(), [&](auto N) {
0584           constexpr int measdim = decltype(N)::value;
0585           allocateCalibrated(
0586               other.template calibrated<measdim>().eval(),
0587               other.template calibratedCovariance<measdim>().eval());
0588         });
0589 
0590         setProjectorSubspaceIndices(other.projectorSubspaceIndices());
0591       }
0592     }
0593 
0594     chi2() = other.chi2();
0595     pathLength() = other.pathLength();
0596     typeFlags() = other.typeFlags();
0597 
0598     if (other.hasReferenceSurface()) {
0599       setReferenceSurface(other.referenceSurface().getSharedPtr());
0600     }
0601 
0602     m_traj->copyDynamicFrom(m_istate, other.container(), other.index());
0603   }
0604 
0605   /// @}
0606 
0607   /// @anchor track_state_proxy_generic_component
0608   /// @name Track state proxy Generic component access
0609   /// @{
0610 
0611   /// Check if a component is set
0612   /// @tparam key Hashed string key to check for
0613   /// @return true if the component exists, false if not
0614   template <HashedString key>
0615   constexpr bool has() const {
0616     return m_traj->template has<key>(m_istate);
0617   }
0618 
0619   /// Check if a component is set
0620   /// @param key Hashed string key to check for
0621   /// @return true if the component exists, false if not
0622   constexpr bool has(HashedString key) const {
0623     return m_traj->has(key, m_istate);
0624   }
0625 
0626   /// Check if a component is set
0627   /// @param key String key to check for
0628   /// @note This might hash the @p key at runtime instead of compile-time
0629   /// @return true if the component exists, false if not
0630   constexpr bool has(std::string_view key) const {
0631     return has(hashStringDynamic(key));
0632   }
0633 
0634   /// Retrieve a mutable reference to a component
0635   /// @tparam T The type of the component to access
0636   /// @tparam key String key for the component to access
0637   /// @return Mutable reference to the component given by @p key
0638   template <typename T, HashedString key>
0639   constexpr T& component()
0640     requires(!ReadOnly)
0641   {
0642     return m_traj->template component<T, key>(m_istate);
0643   }
0644 
0645   /// Retrieve a mutable reference to a component
0646   /// @tparam T The type of the component to access
0647   /// @param key String key for the component to access
0648   /// @return Mutable reference to the component given by @p key
0649   template <typename T>
0650   constexpr T& component(HashedString key)
0651     requires(!ReadOnly)
0652   {
0653     return m_traj->template component<T>(key, m_istate);
0654   }
0655 
0656   /// Retrieve a mutable reference to a component
0657   /// @tparam T The type of the component to access
0658   /// @param key String key for the component to access
0659   /// @note This might hash the @p key at runtime instead of compile-time
0660   /// @return Mutable reference to the component given by @p key
0661   template <typename T>
0662   constexpr T& component(std::string_view key)
0663     requires(!ReadOnly)
0664   {
0665     return m_traj->template component<T>(hashStringDynamic(key), m_istate);
0666   }
0667 
0668   /// Retrieve a const reference to a component
0669   /// @tparam T The type of the component to access
0670   /// @tparam key String key for the component to access
0671   /// @return Const reference to the component given by @p key
0672   template <typename T, HashedString key>
0673   constexpr const T& component() const {
0674     return m_traj->template component<T, key>(m_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   /// @return Const reference to the component given by @p key
0681   template <typename T>
0682   constexpr const T& component(HashedString key) const {
0683     return m_traj->template component<T>(key, m_istate);
0684   }
0685 
0686   /// Retrieve a const reference to a component
0687   /// @tparam T The type of the component to access
0688   /// @param key String key for the component to access
0689   /// @note This might hash the @p key at runtime instead of compile-time
0690   /// @return Const reference to the component given by @p key
0691   template <typename T>
0692   constexpr const T& component(std::string_view key) const {
0693     return m_traj->template component<T>(hashStringDynamic(key), m_istate);
0694   }
0695 
0696   /// @}
0697 
0698   /// Return a mutable reference to the underlying backend container
0699   /// @return A reference to the backend container
0700   MultiTrajectory<Trajectory>& trajectory()
0701     requires(!ReadOnly)
0702   {
0703     return *m_traj;
0704   }
0705 
0706   /// Return a const reference to the underlying backend container
0707   /// @return A const reference to the backend container
0708   const MultiTrajectory<Trajectory>& trajectory() const { return *m_traj; }
0709 
0710   /// Get a mutable reference to the track state container backend
0711   /// @return a mutable reference to the backend
0712   auto& container()
0713     requires(!ReadOnly)
0714   {
0715     return *m_traj;
0716   }
0717 
0718   /// Get a const reference to the track state container backend
0719   /// @return a const reference to the backend
0720   const auto& container() const { return *m_traj; }
0721 
0722   /// Check if the track state has a specific dynamic column
0723   /// @param key The hashed column key
0724   /// @return true if the column exists
0725   bool hasColumn(HashedString key) const { return container().hasColumn(key); }
0726 
0727  protected:
0728   /// Get parameters at given index
0729   /// @param parIndex Index of parameters
0730   /// @return Const parameters
0731   ConstParameters parametersAtIndex(IndexType parIndex) const {
0732     return m_traj->parameters(parIndex);
0733   }
0734 
0735   /// Get mutable parameters at given index
0736   /// @param parIndex Index of parameters
0737   /// @return Mutable parameters
0738   Parameters parametersAtIndexMutable(IndexType parIndex)
0739     requires(!ReadOnly)
0740   {
0741     return m_traj->parameters(parIndex);
0742   }
0743 
0744   /// Get covariance at given index
0745   /// @param covIndex Index of covariance
0746   /// @return Const covariance
0747   ConstCovariance covarianceAtIndex(IndexType covIndex) const {
0748     return m_traj->covariance(covIndex);
0749   }
0750 
0751   /// Get mutable covariance at given index
0752   /// @param covIndex Index of covariance
0753   /// @return Mutable covariance
0754   Covariance covarianceAtIndexMutable(IndexType covIndex)
0755     requires(!ReadOnly)
0756   {
0757     return m_traj->covariance(covIndex);
0758   }
0759 
0760   /// Get mutable pointer to calibrated measurement data
0761   /// @return Pointer to calibrated data array
0762   double* calibratedDataMutable()
0763     requires(!ReadOnly)
0764   {
0765     return m_traj->template calibrated<M>(m_istate).data();
0766   }
0767 
0768   /// Get const pointer to calibrated measurement data
0769   /// @return Const pointer to calibrated data array
0770   const double* calibratedData() const {
0771     return m_traj->template calibrated<M>(m_istate).data();
0772   }
0773 
0774   /// Get mutable pointer to calibrated covariance data
0775   /// @return Pointer to calibrated covariance array
0776   double* calibratedCovarianceDataMutable()
0777     requires(!ReadOnly)
0778   {
0779     return m_traj->template calibratedCovariance<M>(m_istate).data();
0780   }
0781 
0782   /// Get const pointer to calibrated covariance data
0783   /// @return Const pointer to calibrated covariance array
0784   const double* calibratedCovarianceData() const {
0785     return m_traj->template calibratedCovariance<M>(m_istate).data();
0786   }
0787 
0788  private:
0789   // Private since it can only be created by the trajectory.
0790   TrackStateProxy(const_if_t<ReadOnly, MultiTrajectory<Trajectory>>& trajectory,
0791                   IndexType istate);
0792 
0793   detail_lt::TransitiveConstPointer<
0794       const_if_t<ReadOnly, MultiTrajectory<Trajectory>>>
0795       m_traj;
0796   IndexType m_istate;
0797 
0798   friend class Acts::MultiTrajectory<Trajectory>;
0799   friend class TrackStateProxy<Trajectory, M, true>;
0800   friend class TrackStateProxy<Trajectory, M, false>;
0801   template <bool R>
0802   friend class AnyTrackStateProxy;
0803 
0804   const auto* rawTrajectoryPtr() const { return m_traj.ptr(); }
0805   auto* rawTrajectoryPtr() { return m_traj.ptr(); }
0806 };
0807 }  // namespace Acts
0808 
0809 #include "Acts/EventData/TrackStateProxy.ipp"