Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 09:22:20

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/TrackParametrization.hpp"
0012 #include "Acts/EventData/SourceLink.hpp"
0013 #include "Acts/EventData/SubspaceHelpers.hpp"
0014 #include "Acts/EventData/TrackStatePropMask.hpp"
0015 #include "Acts/EventData/TrackStateProxyConcept.hpp"
0016 #include "Acts/EventData/TrackStateType.hpp"
0017 #include "Acts/EventData/Types.hpp"
0018 #include "Acts/Surfaces/Surface.hpp"
0019 #include "Acts/Utilities/EigenConcepts.hpp"
0020 #include "Acts/Utilities/HashedString.hpp"
0021 #include "Acts/Utilities/Helpers.hpp"
0022 
0023 #include <cstddef>
0024 #include <ranges>
0025 #include <span>
0026 
0027 #include <Eigen/Core>
0028 
0029 namespace Acts {
0030 
0031 template <typename derived_t>
0032 class MultiTrajectory;
0033 
0034 namespace detail_tsp {
0035 inline constexpr HashedString kPreviousKey = hashString("previous");
0036 inline constexpr HashedString kChi2Key = hashString("chi2");
0037 inline constexpr HashedString kPathLengthKey = hashString("pathLength");
0038 inline constexpr HashedString kTypeFlagsKey = hashString("typeFlags");
0039 inline constexpr HashedString kPredictedKey = hashString("predicted");
0040 inline constexpr HashedString kFilteredKey = hashString("filtered");
0041 inline constexpr HashedString kSmoothedKey = hashString("smoothed");
0042 inline constexpr HashedString kJacobianKey = hashString("jacobian");
0043 inline constexpr HashedString kProjectorKey = hashString("projector");
0044 inline constexpr HashedString kUncalibratedKey =
0045     hashString("uncalibratedSourceLink");
0046 inline constexpr HashedString kCalibratedKey = hashString("calibrated");
0047 inline constexpr HashedString kCalibratedCovKey = hashString("calibratedCov");
0048 inline constexpr HashedString kNextKey = hashString("next");
0049 }  // namespace detail_tsp
0050 
0051 namespace detail_lt {
0052 
0053 /// Either type T or const T depending on the boolean.
0054 template <typename T, bool select>
0055 using ConstIf = std::conditional_t<select, const T, T>;
0056 
0057 /// Helper type to make a member pointers constness transitive.
0058 template <typename T>
0059 class TransitiveConstPointer {
0060  public:
0061   using element_type = T;
0062   TransitiveConstPointer() = default;
0063   explicit TransitiveConstPointer(T* ptr) : m_ptr{ptr} {}
0064 
0065   template <typename U>
0066   explicit TransitiveConstPointer(const TransitiveConstPointer<U>& other)
0067       : m_ptr{other.ptr()} {}
0068 
0069   template <typename U>
0070   TransitiveConstPointer& operator=(const TransitiveConstPointer<U>& other) {
0071     m_ptr = other.m_ptr;
0072     return *this;
0073   }
0074 
0075   template <typename U>
0076   bool operator==(const TransitiveConstPointer<U>& other) const {
0077     return m_ptr == other.m_ptr;
0078   }
0079 
0080   const T* operator->() const { return m_ptr; }
0081 
0082   T* operator->() { return m_ptr; }
0083 
0084   template <typename U>
0085   friend class TransitiveConstPointer;
0086 
0087   const T& operator*() const { return *m_ptr; }
0088 
0089   T& operator*() { return *m_ptr; }
0090 
0091   explicit operator bool() const { return m_ptr != nullptr; }
0092 
0093  private:
0094   T* ptr() const { return m_ptr; }
0095 
0096   T* m_ptr{nullptr};
0097 };
0098 
0099 /// Type construction helper for fixed size coefficients and associated
0100 /// covariances.
0101 template <std::size_t Size, bool ReadOnlyMaps = true>
0102 struct FixedSizeTypes {
0103   constexpr static auto Flags = Eigen::ColMajor | Eigen::AutoAlign;
0104 
0105   // single items
0106   using Coefficients = Eigen::Matrix<double, Size, 1, Flags>;
0107   using Covariance = Eigen::Matrix<double, Size, Size, Flags>;
0108   using CoefficientsMap = Eigen::Map<ConstIf<Coefficients, ReadOnlyMaps>>;
0109   using CovarianceMap = Eigen::Map<ConstIf<Covariance, ReadOnlyMaps>>;
0110 
0111   using DynamicCoefficients = Eigen::Matrix<double, Eigen::Dynamic, 1, Flags>;
0112   using DynamicCovariance =
0113       Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Flags>;
0114   using DynamicCoefficientsMap =
0115       Eigen::Map<ConstIf<DynamicCoefficients, ReadOnlyMaps>>;
0116   using DynamicCovarianceMap =
0117       Eigen::Map<ConstIf<DynamicCovariance, ReadOnlyMaps>>;
0118 };
0119 
0120 // Type construction helper for dynamic sized coefficients and associated
0121 /// covariances.
0122 template <bool ReadOnlyMaps = true>
0123 struct DynamicSizeTypes {
0124   constexpr static auto Flags = Eigen::ColMajor | Eigen::AutoAlign;
0125 
0126   using Coefficients = Eigen::Matrix<double, Eigen::Dynamic, 1, Flags>;
0127   using Covariance =
0128       Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Flags>;
0129   using CoefficientsMap = Eigen::Map<ConstIf<Coefficients, ReadOnlyMaps>>;
0130   using CovarianceMap = Eigen::Map<ConstIf<Covariance, ReadOnlyMaps>>;
0131 };
0132 
0133 }  // namespace detail_lt
0134 
0135 // This is public
0136 template <std::size_t M, bool ReadOnly = true>
0137 struct TrackStateTraits {
0138   using Parameters =
0139       typename detail_lt::FixedSizeTypes<eBoundSize, ReadOnly>::CoefficientsMap;
0140   using Covariance =
0141       typename detail_lt::FixedSizeTypes<eBoundSize, ReadOnly>::CovarianceMap;
0142   using Calibrated =
0143       typename detail_lt::FixedSizeTypes<M, ReadOnly>::CoefficientsMap;
0144   using CalibratedCovariance =
0145       typename detail_lt::FixedSizeTypes<M, ReadOnly>::CovarianceMap;
0146   using EffectiveCalibrated =
0147       typename detail_lt::DynamicSizeTypes<ReadOnly>::CoefficientsMap;
0148   using EffectiveCalibratedCovariance =
0149       typename detail_lt::DynamicSizeTypes<ReadOnly>::CovarianceMap;
0150 };
0151 
0152 /// Proxy object to access a single point on the trajectory.
0153 ///
0154 /// @tparam SourceLink Type to link back to an original measurement
0155 /// @tparam M          Maximum number of measurement dimensions
0156 /// @tparam read_only  true for read-only access to underlying storage
0157 template <typename trajectory_t, std::size_t M, bool read_only = true>
0158 class TrackStateProxy {
0159  public:
0160   /// Indicates whether this track state proxy is read-only or if it can be
0161   /// modified
0162   static constexpr bool ReadOnly = read_only;
0163 
0164   /// Alias for an associated const track state proxy, with the same backends
0165   using ConstProxyType = TrackStateProxy<trajectory_t, M, true>;
0166 
0167   /// Map-type for a bound parameter vector. This has reference semantics, i.e.
0168   /// points at a matrix by an internal pointer.
0169   using Parameters = typename TrackStateTraits<M, ReadOnly>::Parameters;
0170 
0171   /// Same as @ref Parameters, but with const semantics
0172   using ConstParameters = typename TrackStateTraits<M, true>::Parameters;
0173 
0174   /// Map-type for a bound covariance. This has reference semantics, i.e.
0175   /// points at a matrix by an internal pointer.
0176   using Covariance = typename TrackStateTraits<M, ReadOnly>::Covariance;
0177 
0178   /// Same as @ref Covariance, but with const semantics
0179   using ConstCovariance = typename TrackStateTraits<M, true>::Covariance;
0180 
0181   /// Map-type for a calibrated measurement vector, where the local measurement
0182   /// dimension is variable.
0183   template <std::size_t N>
0184   using Calibrated = typename TrackStateTraits<N, ReadOnly>::Calibrated;
0185 
0186   /// Same as @c Calibrated, but with const semantics
0187   template <std::size_t N>
0188   using ConstCalibrated = typename TrackStateTraits<N, true>::Calibrated;
0189 
0190   /// Map-type for a calibrated measurement covariance matrix, where the local
0191   /// measurement dimension is variable.
0192   template <std::size_t N>
0193   using CalibratedCovariance =
0194       typename TrackStateTraits<N, ReadOnly>::CalibratedCovariance;
0195 
0196   /// Same as @ref CalibratedCovariance, but with const semantics
0197   template <std::size_t N>
0198   using ConstCalibratedCovariance =
0199       typename TrackStateTraits<N, true>::CalibratedCovariance;
0200 
0201   /// Map-type for a measurement vector, where the local measurement dimension
0202   /// is variable.
0203   using EffectiveCalibrated =
0204       typename TrackStateTraits<M, ReadOnly>::EffectiveCalibrated;
0205 
0206   /// Same as @c EffectiveCalibrated, but with const semantics
0207   using ConstEffectiveCalibrated =
0208       typename TrackStateTraits<M, true>::EffectiveCalibrated;
0209 
0210   /// Map-type for a measurement covariance matrix, where the local measurement
0211   /// dimension is variable.
0212   using EffectiveCalibratedCovariance =
0213       typename TrackStateTraits<M, ReadOnly>::EffectiveCalibratedCovariance;
0214 
0215   /// Same as @ref EffectiveCalibratedCovariance, but with const semantics
0216   using ConstEffectiveCalibratedCovariance =
0217       typename TrackStateTraits<M, true>::EffectiveCalibratedCovariance;
0218 
0219   /// The index type of the track state container
0220   using IndexType = TrackIndexType;
0221 
0222   /// Sentinel value that indicates an invalid index
0223   static constexpr IndexType kInvalid = kTrackIndexInvalid;
0224 
0225   /// The track state container backend given as a template parameter
0226   using Trajectory = trajectory_t;
0227 
0228   /// @anchor track_state_proxy_construct
0229   /// @name Constructors and assignment operator
0230   ///
0231   /// Public constructors and assignment operators for @c TrackStateProxy only
0232   /// allow construction from another @c TrackStateProxy. You should generally
0233   /// not have to construct @c TrackStateProxy manually.
0234   ///
0235   /// @{
0236 
0237   /// Copy constructor: const to const or mutable to mutable
0238   /// @param other The other TrackStateProxy to construct from
0239   TrackStateProxy(const TrackStateProxy& other) = default;
0240 
0241   /// Copy assignment operator: const to const or mutable to mutable
0242   /// @param other The other TrackStateProxy to assign from
0243   /// @return Reference to this TrackStateProxy
0244   TrackStateProxy& operator=(const TrackStateProxy& other) = default;
0245 
0246   /// Constructor from mutable TrackStateProxy
0247   /// @note Only available if the track state proxy is read-only
0248   /// @param other The other TrackStateProxy to construct from
0249   explicit TrackStateProxy(const TrackStateProxy<Trajectory, M, false>& other)
0250     requires ReadOnly
0251       : m_traj{other.m_traj}, m_istate{other.m_istate} {}
0252 
0253   /// Assignment operator to from mutable @c TrackStateProxy
0254   /// @param other The other TrackStateProxy to assign from
0255   /// @note Only available if the track state proxy is read-only
0256   /// @return Reference to this TrackStateProxy
0257   TrackStateProxy& operator=(const TrackStateProxy<Trajectory, M, false>& other)
0258     requires ReadOnly
0259   {
0260     m_traj = other.m_traj;
0261     m_istate = other.m_istate;
0262 
0263     return *this;
0264   }
0265 
0266   /// @}
0267 
0268   /// @anchor track_state_proxy_props
0269   /// @name Track state properties
0270   ///
0271   /// Properties of the track state represented by @c TrackStateProxy.
0272   ///
0273   /// Many of these methods come in a @c const and a non-@c const version. The
0274   /// non-@c const version is only available if you have an instance of
0275   /// @c TrackStateProxy that does not have the @c read_only template parameter set to
0276   /// @c true, even if you hold it as an lvalue.
0277   ///
0278   /// The track states each have an index in the track state container. The
0279   /// sequence of track states is implemented as a one or two-way linked list,
0280   /// which uses indices into the same container.
0281   ///
0282   /// Each track state has a @c previous index, which points at the track state
0283   /// immediately preceding. A track state with a @c previous index of @c
0284   /// kInvalid is the first (innermost) track state in a track or track
0285   /// candidate. This is also referred to as a *stem* at the track level.
0286   ///
0287   /// During track finding and fitting, track states are usually appended to the
0288   /// sequence, populating the @c previous index of the new track state. Combinatorial
0289   /// track finding can produce track states which fork in this way, by having
0290   /// more than one track state with the same @c previous index.
0291   ///
0292   /// The track states have static, optional and dynamic properties. Static
0293   /// properties are always present, and can always be retrieved. Optional
0294   /// components use an extra indirection mechanism that coordinates with the
0295   /// backend to allow both not having the component set, or sharing it with
0296   /// other track states. An example is a branching trajectory from track
0297   /// finding which shares the same predicted parameter vector and associated
0298   /// covariance.
0299   ///
0300   /// Optional components are
0301   /// - predicted parameters and covariance
0302   /// - filtered parameters and covariance
0303   /// - smoothed parameters and covariance
0304   /// - jacobian
0305   /// - calibrated measurement info including projector
0306   ///
0307   /// They can be unset via @ref unset, @ref getMask can be used to check which
0308   /// components are present. The first four are shareable between track
0309   /// states via @ref shareFrom.
0310   ///
0311   /// @{
0312 
0313   /// Index within the trajectory.
0314   /// @return the index
0315   IndexType index() const { return m_istate; }
0316 
0317   /// Return the index of the track state `previous` in the track sequence
0318   /// @return The index of the previous track state.
0319   IndexType previous() const {
0320     return component<IndexType, detail_tsp::kPreviousKey>();
0321   }
0322 
0323   /// Return a mutable reference to the index of the track state 'previous' in
0324   /// the track sequence
0325   /// @note Only available if the track state proxy is not read-only
0326   /// @return The index of the previous track state.
0327   IndexType& previous()
0328     requires(!ReadOnly)
0329   {
0330     return component<IndexType, detail_tsp::kPreviousKey>();
0331   }
0332 
0333   /// Return whether this track state has a previous (parent) track state.
0334   /// @return Boolean indicating whether a previous track state exists
0335   bool hasPrevious() const {
0336     return component<IndexType, detail_tsp::kPreviousKey>() != kInvalid;
0337   }
0338 
0339   /// Build a mask that represents all the allocated components of this track
0340   /// state proxy
0341   /// @return The generated mask
0342   TrackStatePropMask getMask() const;
0343 
0344   /// Unset an optional track state component
0345   /// @note Only available if the track state proxy is not read-only
0346   /// @param target The component to unset
0347   void unset(TrackStatePropMask target)
0348     requires(!ReadOnly)
0349   {
0350     m_traj->self().unset(target, m_istate);
0351   }
0352 
0353   /// Add additional components to the track state
0354   /// @note Only available if the track state proxy is not read-only
0355   /// @param mask The bitmask that instructs which components to allocate
0356   void addComponents(TrackStatePropMask mask)
0357     requires(!ReadOnly)
0358   {
0359     m_traj->self().addTrackStateComponents_impl(m_istate, mask);
0360   }
0361 
0362   /// Reference surface.
0363   /// @return the reference surface
0364   const Surface& referenceSurface() const {
0365     assert(hasReferenceSurface() &&
0366            "TrackState does not have reference surface");
0367     return *m_traj->referenceSurface(m_istate);
0368   }
0369 
0370   /// Returns if the track state has a non nullptr surface associated
0371   /// @return whether a surface exists or not
0372   bool hasReferenceSurface() const {
0373     return m_traj->referenceSurface(m_istate) != nullptr;
0374   }
0375 
0376   // NOLINTBEGIN(performance-unnecessary-value-param)
0377   // looks like a false-positive. clang-tidy believes `srf` is not movable.
0378 
0379   /// Set the reference surface to a given value
0380   /// @param srf Shared pointer to the surface to set
0381   /// @note This overload is only present in case @c ReadOnly is false.
0382   void setReferenceSurface(std::shared_ptr<const Surface> srf)
0383     requires(!ReadOnly)
0384   {
0385     m_traj->setReferenceSurface(m_istate, std::move(srf));
0386   }
0387   // NOLINTEND(performance-unnecessary-value-param)
0388 
0389   /// Getter/setter for chi2 value associated with the track state
0390   /// This overload returns a mutable reference, which allows setting a new
0391   /// value directly into the backing store.
0392   /// @note this overload is only enabled in case the proxy is not read-only
0393   /// @return Mutable reference to the chi2 value
0394   float& chi2()
0395     requires(!ReadOnly)
0396   {
0397     return component<float, detail_tsp::kChi2Key>();
0398   }
0399 
0400   /// Getter for the chi2 value associated with the track state.
0401   /// This overload returns a copy of the chi2 value, and thus does not allow
0402   /// modification of the value in the backing storage.
0403   /// @return the chi2 value of the track state
0404   float chi2() const { return component<float, detail_tsp::kChi2Key>(); }
0405 
0406   /// Getter for the path length associated with the track state.
0407   /// This overloaded is only enabled if not read-only, and returns a mutable
0408   /// reference.
0409   /// @return Mutable reference to the pathlength.
0410   double& pathLength()
0411     requires(!ReadOnly)
0412   {
0413     return component<double, detail_tsp::kPathLengthKey>();
0414   }
0415 
0416   /// Getter for the path length. Returns a copy of the path length value.
0417   /// @return The path length of this track state
0418   double pathLength() const {
0419     return component<double, detail_tsp::kPathLengthKey>();
0420   }
0421 
0422   /// Getter for the type flags associated with the track state.
0423   /// This overloaded is only enabled if not read-only, and returns a mutable
0424   /// reference.
0425   /// @return reference to the type flags.
0426   TrackStateType typeFlags()
0427     requires(!ReadOnly)
0428   {
0429     return TrackStateType{
0430         component<TrackStateType::raw_type, detail_tsp::kTypeFlagsKey>()};
0431   }
0432 
0433   /// Getter for the type flags. Returns a copy of the type flags value.
0434   /// @return The type flags of this track state
0435   ConstTrackStateType typeFlags() const {
0436     return ConstTrackStateType{
0437         component<TrackStateType::raw_type, detail_tsp::kTypeFlagsKey>()};
0438   }
0439 
0440   /// @}
0441 
0442   /// @anchor track_state_proxy_params
0443   /// @name Track state parameters
0444   /// @{
0445 
0446   /// Track parameters vector. This tries to be somewhat smart and return the
0447   /// first parameters that are set in this order: predicted -> filtered ->
0448   /// smoothed
0449   /// @return one of predicted, filtered or smoothed parameters
0450   ConstParameters parameters() const;
0451 
0452   /// Track parameters covariance matrix. This tries to be somewhat smart and
0453   /// return the
0454   /// first parameters that are set in this order: predicted -> filtered ->
0455   /// smoothed
0456   /// @return one of predicted, filtered or smoothed covariances
0457   ConstCovariance covariance() const;
0458 
0459   /// Predicted track parameters vector
0460   /// @return The predicted parameters
0461   ConstParameters predicted() const {
0462     assert(has<detail_tsp::kPredictedKey>());
0463     return m_traj->self().parameters(
0464         component<IndexType, detail_tsp::kPredictedKey>());
0465   }
0466 
0467   /// Predicted track parameters vector (non-const version)
0468   /// @return The predicted parameters with mutable access
0469   Parameters predicted()
0470     requires(!ReadOnly)
0471   {
0472     assert(has<detail_tsp::kPredictedKey>());
0473     return m_traj->self().parameters(
0474         component<IndexType, detail_tsp::kPredictedKey>());
0475   }
0476 
0477   /// Predicted track parameters covariance matrix.
0478   /// @return The predicted track parameter covariance
0479   ConstCovariance predictedCovariance() const {
0480     assert(has<detail_tsp::kPredictedKey>());
0481     return m_traj->self().covariance(
0482         component<IndexType, detail_tsp::kPredictedKey>());
0483   }
0484 
0485   /// Predicted track parameters covariance matrix (non-const version)
0486   /// @return The predicted track parameter covariance with mutable access
0487   Covariance predictedCovariance()
0488     requires(!ReadOnly)
0489   {
0490     assert(has<detail_tsp::kPredictedKey>());
0491     return m_traj->self().covariance(
0492         component<IndexType, detail_tsp::kPredictedKey>());
0493   }
0494 
0495   /// Check whether the predicted parameters+covariance is set
0496   /// @return Whether it is set or not
0497   bool hasPredicted() const { return has<detail_tsp::kPredictedKey>(); }
0498 
0499   /// Filtered track parameters vector
0500   /// @return The filtered parameters
0501   /// @note Const version
0502   ConstParameters filtered() const {
0503     assert(has<detail_tsp::kFilteredKey>());
0504     return m_traj->self().parameters(
0505         component<IndexType, detail_tsp::kFilteredKey>());
0506   }
0507 
0508   /// Filtered track parameters vector
0509   /// @return The filtered parameters
0510   /// @note Mutable version
0511   Parameters filtered()
0512     requires(!ReadOnly)
0513   {
0514     assert(has<detail_tsp::kFilteredKey>());
0515     return m_traj->self().parameters(
0516         component<IndexType, detail_tsp::kFilteredKey>());
0517   }
0518 
0519   /// Filtered track parameters covariance matrix
0520   /// @return The filtered parameters covariance
0521   /// @note Const version
0522   ConstCovariance filteredCovariance() const {
0523     assert(has<detail_tsp::kFilteredKey>());
0524     return m_traj->self().covariance(
0525         component<IndexType, detail_tsp::kFilteredKey>());
0526   }
0527 
0528   /// Filtered track parameters covariance matrix
0529   /// @return The filtered parameters covariance
0530   /// @note Mutable version
0531   Covariance filteredCovariance()
0532     requires(!ReadOnly)
0533   {
0534     assert(has<detail_tsp::kFilteredKey>());
0535     return m_traj->self().covariance(
0536         component<IndexType, detail_tsp::kFilteredKey>());
0537   }
0538 
0539   /// Return whether filtered parameters+covariance is set
0540   /// @return Whether it is set
0541   bool hasFiltered() const { return has<detail_tsp::kFilteredKey>(); }
0542 
0543   /// Smoothed track parameters vector
0544   /// @return The smoothed parameters
0545   /// @note Const version
0546   ConstParameters smoothed() const {
0547     assert(has<detail_tsp::kSmoothedKey>());
0548     return m_traj->self().parameters(
0549         component<IndexType, detail_tsp::kSmoothedKey>());
0550   }
0551 
0552   /// Smoothed track parameters vector
0553   /// @return The smoothed parameters
0554   /// @note Mutable version
0555   Parameters smoothed()
0556     requires(!ReadOnly)
0557   {
0558     assert(has<detail_tsp::kSmoothedKey>());
0559     return m_traj->self().parameters(
0560         component<IndexType, detail_tsp::kSmoothedKey>());
0561   }
0562 
0563   /// Smoothed track parameters covariance matrix
0564   /// @return the parameter covariance matrix
0565   /// @note Const version
0566   ConstCovariance smoothedCovariance() const {
0567     assert(has<detail_tsp::kSmoothedKey>());
0568     return m_traj->self().covariance(
0569         component<IndexType, detail_tsp::kSmoothedKey>());
0570   }
0571 
0572   /// Smoothed track parameters covariance matrix
0573   /// @return the parameter covariance matrix
0574   /// @note Mutable version
0575   Covariance smoothedCovariance()
0576     requires(!ReadOnly)
0577   {
0578     assert(has<detail_tsp::kSmoothedKey>());
0579     return m_traj->self().covariance(
0580         component<IndexType, detail_tsp::kSmoothedKey>());
0581   }
0582 
0583   /// Return whether smoothed parameters+covariance is set
0584   /// @return Whether it is set
0585   bool hasSmoothed() const { return has<detail_tsp::kSmoothedKey>(); }
0586 
0587   /// Returns the jacobian from the previous trackstate to this one
0588   /// @return The jacobian matrix
0589   /// @note Const version
0590   ConstCovariance jacobian() const {
0591     assert(has<detail_tsp::kJacobianKey>());
0592     return m_traj->self().jacobian(m_istate);
0593   }
0594 
0595   /// Returns the jacobian from the previous trackstate to this one
0596   /// @return The jacobian matrix
0597   /// @note Mutable version
0598   Covariance jacobian()
0599     requires(!ReadOnly)
0600   {
0601     assert(has<detail_tsp::kJacobianKey>());
0602     return m_traj->self().jacobian(m_istate);
0603   }
0604 
0605   /// Returns whether a jacobian is set for this trackstate
0606   /// @return Whether it is set
0607   bool hasJacobian() const { return has<detail_tsp::kJacobianKey>(); }
0608 
0609   /// @}
0610 
0611   /// @anchor track_state_proxy_meas
0612   /// @name Track state measurement properties
0613   ///
0614   /// Properties of the measurement associated with the track state represented.
0615   /// This consists of a vector and an associated square matrix of a measurement
0616   /// dimension which is between one and the size of the track parametrization.
0617   /// The measurement coordinate frame is required to be a strict subset of the
0618   /// bound track parametrization on the local geometry coordinate frame, i.e.
0619   /// using a pure projector matrix to convert from the bound parametrization to
0620   /// the measurement frame is possible.
0621   ///
0622   /// The track state stores the parameter vector and covariance, and the
0623   /// backend is given the possibility to do so in a jagged way, i.e. only
0624   /// storing the number of values needed. This requires calling
0625   /// @ref allocateCalibrated before storing the measurements
0626   /// (even if it might be a no-op).
0627   ///
0628   /// The projector matrix is packed as a bitset, which is converted to a matrix
0629   /// on-demand (and therefore returned by value).
0630   ///
0631   /// The track state also includes a @ref SourceLink which acts as a proxy
0632   /// to the original uncalibrated measurement that the calibrated measurement
0633   /// was derived from. It is set and returned by value, to allow unpacking /
0634   /// repacking by the backend, if needed.
0635   ///
0636   /// @{
0637 
0638   /// Set the projector subspace indices
0639   /// @param subspaceIndices The projector subspace indices to set
0640   template <std::ranges::sized_range index_range_t>
0641   void setProjectorSubspaceIndices(const index_range_t& subspaceIndices)
0642     requires(!ReadOnly &&
0643              std::convertible_to<std::ranges::range_value_t<index_range_t>,
0644                                  std::uint8_t>)
0645   {
0646     assert(has<detail_tsp::kProjectorKey>());
0647     assert(subspaceIndices.size() <= eBoundSize);
0648     BoundSubspaceIndices boundSubspace{};
0649     std::transform(subspaceIndices.begin(), subspaceIndices.end(),
0650                    boundSubspace.begin(),
0651                    [](auto i) { return static_cast<std::uint8_t>(i); });
0652     component<SerializedSubspaceIndices, detail_tsp::kProjectorKey>() =
0653         serializeSubspaceIndices(boundSubspace);
0654   }
0655 
0656   /// Returns whether a projector is set
0657   /// @return Whether it is set
0658   bool hasProjector() const { return has<detail_tsp::kProjectorKey>(); }
0659 
0660   /// Returns the projector subspace indices
0661   /// @return The projector subspace indices
0662   BoundSubspaceIndices projectorSubspaceIndices() const {
0663     assert(has<detail_tsp::kProjectorKey>());
0664     return deserializeSubspaceIndices<eBoundSize>(
0665         component<SerializedSubspaceIndices, detail_tsp::kProjectorKey>());
0666   }
0667 
0668   /// Returns the projector subspace indices
0669   /// @return The projector subspace indices
0670   template <std::size_t measdim>
0671   SubspaceIndices<measdim> projectorSubspaceIndices() const {
0672     BoundSubspaceIndices boundSubspace = projectorSubspaceIndices();
0673     SubspaceIndices<measdim> subspace;
0674     std::copy(boundSubspace.begin(), boundSubspace.begin() + measdim,
0675               subspace.begin());
0676     return subspace;
0677   }
0678 
0679   /// Creates a variable size subspace helper
0680   /// @return The subspace helper
0681   VariableBoundSubspaceHelper projectorSubspaceHelper() const {
0682     BoundSubspaceIndices boundSubspace = projectorSubspaceIndices();
0683     std::span<std::uint8_t> validSubspaceIndices(
0684         boundSubspace.begin(), boundSubspace.begin() + calibratedSize());
0685     return VariableBoundSubspaceHelper(validSubspaceIndices);
0686   }
0687 
0688   /// Creates a fixed size subspace helper
0689   /// @return The subspace helper
0690   template <std::size_t measdim>
0691   FixedBoundSubspaceHelper<measdim> projectorSubspaceHelper() const {
0692     SubspaceIndices<measdim> subspace = projectorSubspaceIndices<measdim>();
0693     return FixedBoundSubspaceHelper<measdim>(subspace);
0694   }
0695 
0696   /// Uncalibrated measurement in the form of a source link. Const version
0697   /// @return The uncalibrated measurement source link
0698   SourceLink getUncalibratedSourceLink() const;
0699 
0700   /// Set an uncalibrated source link
0701   /// @param sourceLink The uncalibrated source link to set
0702   void setUncalibratedSourceLink(SourceLink&& sourceLink)
0703     requires(!ReadOnly)
0704   {
0705     m_traj->setUncalibratedSourceLink(m_istate, std::move(sourceLink));
0706   }
0707 
0708   /// Check if the point has an associated uncalibrated measurement.
0709   /// @return Whether it is set
0710   bool hasUncalibratedSourceLink() const {
0711     return has<detail_tsp::kUncalibratedKey>();
0712   }
0713 
0714   /// Check if the point has an associated calibrated measurement.
0715   /// @return Whether it is set
0716   bool hasCalibrated() const { return has<detail_tsp::kCalibratedKey>(); }
0717 
0718   /// Full calibrated measurement vector. Might contain additional zeroed
0719   /// dimensions.
0720   /// @return The measurement vector
0721   /// @note Const version
0722   template <std::size_t measdim>
0723   ConstCalibrated<measdim> calibrated() const {
0724     assert(has<detail_tsp::kCalibratedKey>());
0725     return m_traj->self().template calibrated<measdim>(m_istate);
0726   }
0727 
0728   /// Full calibrated measurement vector. Might contain additional zeroed
0729   /// dimensions.
0730   /// @return The measurement vector
0731   /// @note Mutable version
0732   template <std::size_t measdim>
0733   Calibrated<measdim> calibrated()
0734     requires(!ReadOnly)
0735   {
0736     assert(has<detail_tsp::kCalibratedKey>());
0737     return m_traj->self().template calibrated<measdim>(m_istate);
0738   }
0739 
0740   /// Const full calibrated measurement covariance matrix. The effective
0741   /// covariance is located in the top left corner, everything else is zeroed.
0742   /// @return The measurement covariance matrix
0743   template <std::size_t measdim>
0744   ConstCalibratedCovariance<measdim> calibratedCovariance() const {
0745     assert(has<detail_tsp::kCalibratedCovKey>());
0746     return m_traj->self().template calibratedCovariance<measdim>(m_istate);
0747   }
0748 
0749   /// Mutable full calibrated measurement covariance matrix. The effective
0750   /// covariance is located in the top left corner, everything else is zeroed.
0751   /// @return The measurement covariance matrix
0752   template <std::size_t measdim>
0753   CalibratedCovariance<measdim> calibratedCovariance()
0754     requires(!ReadOnly)
0755   {
0756     assert(has<detail_tsp::kCalibratedCovKey>());
0757     return m_traj->self().template calibratedCovariance<measdim>(m_istate);
0758   }
0759 
0760   /// Mutable dynamic measurement vector with only the valid dimensions.
0761   /// @warning The dynamic vector has a runtime overhead!
0762   /// @return The effective calibrated measurement vector
0763   EffectiveCalibrated effectiveCalibrated()
0764     requires(!ReadOnly)
0765   {
0766     assert(has<detail_tsp::kCalibratedKey>());
0767     return m_traj->self().effectiveCalibrated(m_istate);
0768   }
0769 
0770   /// Const dynamic measurement vector with only the valid dimensions.
0771   /// @warning The dynamic matrix has a runtime overhead!
0772   /// @return The effective calibrated measurement vector
0773   ConstEffectiveCalibrated effectiveCalibrated() const {
0774     assert(has<detail_tsp::kCalibratedKey>());
0775     return m_traj->self().effectiveCalibrated(m_istate);
0776   }
0777 
0778   /// Mutable dynamic measurement covariance matrix with only the valid
0779   /// dimensions.
0780   /// @warning The dynamic matrix has a runtime overhead!
0781   /// @return The effective calibrated covariance matrix
0782   EffectiveCalibratedCovariance effectiveCalibratedCovariance() {
0783     assert(has<detail_tsp::kCalibratedCovKey>());
0784     return m_traj->self().effectiveCalibratedCovariance(m_istate);
0785   }
0786 
0787   /// Const dynamic measurement covariance matrix with only the valid
0788   /// dimensions.
0789   /// @warning The dynamic matrix has a runtime overhead!
0790   /// @return The effective calibrated covariance matrix
0791   ConstEffectiveCalibratedCovariance effectiveCalibratedCovariance() const {
0792     assert(has<detail_tsp::kCalibratedCovKey>());
0793     return m_traj->self().effectiveCalibratedCovariance(m_istate);
0794   }
0795 
0796   /// Return the (dynamic) number of dimensions stored for this measurement.
0797   /// @note Depending on the backend, this size is used to determine the
0798   ///       memory range of the measurement vector and covariance.
0799   /// @return The number of dimensions
0800   IndexType calibratedSize() const { return m_traj->calibratedSize(m_istate); }
0801 
0802   /// Allocate storage to be able to store a measurement of size @p measdim.
0803   /// This must be called **before** setting the measurement content.
0804   /// @param measdim Number of measurement dimensions to allocate
0805   /// @note This does not allocate if an allocation of the same size already exists
0806   /// @note This will zero-initialize the allocated storage
0807   /// @note This is an error if an existing allocation has different size
0808   void allocateCalibrated(std::size_t measdim)
0809     requires(!ReadOnly)
0810   {
0811     m_traj->allocateCalibrated(m_istate, measdim);
0812   }
0813 
0814   /// Allocate storage and assign the given vector and covariance to it.
0815   /// The dimension is inferred from the given vector and matrix.
0816   /// @tparam val_t Type of the vector
0817   /// @tparam cov_t Type of the covariance matrix
0818   /// @param val The measurement vector
0819   /// @param cov The covariance matrix
0820   /// @note This does not allocate if an allocation of the same size already exists
0821   /// @note This throws an exception if an existing allocation has different size
0822   template <typename val_t, typename cov_t>
0823   void allocateCalibrated(const Eigen::DenseBase<val_t>& val,
0824                           const Eigen::DenseBase<cov_t>& cov)
0825     requires(!ReadOnly && Concepts::eigen_base_is_fixed_size<val_t> &&
0826              Concepts::eigen_bases_have_same_num_rows<val_t, cov_t> &&
0827              Concepts::eigen_base_is_square<cov_t> &&
0828              Eigen::PlainObjectBase<val_t>::RowsAtCompileTime <=
0829                  static_cast<std::underlying_type_t<BoundIndices>>(eBoundSize))
0830   {
0831     m_traj->template allocateCalibrated<
0832         Eigen::PlainObjectBase<val_t>::RowsAtCompileTime>(m_istate, val, cov);
0833   }
0834 
0835   /// @}
0836 
0837   /// @anchor track_state_share_copy
0838   /// @name Sharing and copying
0839   ///
0840   /// Methods to share and copy track state components. Sharing means setting up
0841   /// more than one track state to point to the same component.
0842   ///
0843   /// Shareable components are
0844   /// - predicted parameters and covariance
0845   /// - filtered parameters and covariance
0846   /// - smoothed parameters and covariance
0847   /// - jacobian
0848   ///
0849   /// See @ref TrackStatePropMask.
0850   ///
0851   /// @{
0852 
0853   /// Share a shareable component **within** this track state
0854   /// @param shareSource Which component to share from
0855   /// @param shareTarget Which component to share as. This should be different from
0856   ///                    as @p shareSource, e.g. predicted can be shared as filtered.
0857   void shareFrom(TrackStatePropMask shareSource, TrackStatePropMask shareTarget)
0858     requires(!ReadOnly)
0859   {
0860     shareFrom(*this, shareSource, shareTarget);
0861   }
0862 
0863   /// Share a shareable component from another track state.
0864   /// @param other Track state proxy to share component from
0865   /// @param component Which component to share.
0866   /// @note The track states both need to be stored in the
0867   ///       same @c MultiTrajectory instance
0868   template <bool ReadOnlyOther>
0869   void shareFrom(const TrackStateProxy<Trajectory, M, ReadOnlyOther>& other,
0870                  TrackStatePropMask component)
0871     requires(!ReadOnly)
0872   {
0873     shareFrom(other, component, component);
0874   }
0875 
0876   /// Share a shareable component from another track state
0877   /// @param other Track state proxy to share component(s) from
0878   /// @param shareSource Which component to share from
0879   /// @param shareTarget Which component to share as. This can be be different from
0880   ///                    as @p shareSource, e.g. predicted can be shared as filtered.
0881   /// @note Shareable components are predicted, filtered, smoothed, calibrated, jacobian,
0882   ///       or projector. See @c TrackStatePropMask.
0883   template <bool ReadOnlyOther>
0884   void shareFrom(const TrackStateProxy<Trajectory, M, ReadOnlyOther>& other,
0885                  TrackStatePropMask shareSource, TrackStatePropMask shareTarget)
0886     requires(!ReadOnly)
0887   {
0888     assert(m_traj == other.m_traj &&
0889            "Cannot share components across MultiTrajectories");
0890 
0891     assert(ACTS_CHECK_BIT(other.getMask(), shareSource) &&
0892            "Source has incompatible allocation");
0893 
0894     m_traj->self().shareFrom(m_istate, other.m_istate, shareSource,
0895                              shareTarget);
0896   }
0897 
0898   /// Copy the contents of another track state proxy into this one
0899   /// @param other The other track state to copy from
0900   /// @param mask An optional mask to determine what to copy from
0901   /// @param onlyAllocated Whether to only copy allocated components
0902   /// @note If the this track state proxy does not have compatible allocations
0903   ///       with the source track state proxy, and @p onlyAllocated is false,
0904   ///       an exception is thrown.
0905   /// @note The mask parameter will not cause a copy of components that are
0906   ///       not allocated in the source track state proxy.
0907   template <TrackStateProxyConcept track_state_proxy_t>
0908   void copyFrom(const track_state_proxy_t& other,
0909                 TrackStatePropMask mask = TrackStatePropMask::All,
0910                 bool onlyAllocated = true)
0911     requires(!ReadOnly)
0912   {
0913     using PM = TrackStatePropMask;
0914 
0915     if (onlyAllocated) {
0916       auto dest = getMask();
0917       auto src = other.getMask() &
0918                  mask;  // combine what we have with what we want to copy
0919 
0920       if (ACTS_CHECK_BIT(src, PM::Calibrated)) {
0921         // on-demand allocate calibrated
0922         dest |= PM::Calibrated;
0923       }
0924 
0925       if ((static_cast<std::underlying_type_t<TrackStatePropMask>>(
0926                (src ^ dest) & src) != 0 ||
0927            dest == TrackStatePropMask::None ||
0928            src == TrackStatePropMask::None) &&
0929           mask != TrackStatePropMask::None) {
0930         throw std::runtime_error(
0931             "Attempt track state copy with incompatible allocations");
0932       }
0933 
0934       // we're sure now this has correct allocations, so just copy
0935       if (ACTS_CHECK_BIT(src, PM::Predicted)) {
0936         predicted() = other.predicted();
0937         predictedCovariance() = other.predictedCovariance();
0938       }
0939 
0940       if (ACTS_CHECK_BIT(src, PM::Filtered)) {
0941         filtered() = other.filtered();
0942         filteredCovariance() = other.filteredCovariance();
0943       }
0944 
0945       if (ACTS_CHECK_BIT(src, PM::Smoothed)) {
0946         smoothed() = other.smoothed();
0947         smoothedCovariance() = other.smoothedCovariance();
0948       }
0949 
0950       if (other.hasUncalibratedSourceLink()) {
0951         setUncalibratedSourceLink(other.getUncalibratedSourceLink());
0952       }
0953 
0954       if (ACTS_CHECK_BIT(src, PM::Jacobian)) {
0955         jacobian() = other.jacobian();
0956       }
0957 
0958       if (ACTS_CHECK_BIT(src, PM::Calibrated)) {
0959         visit_measurement(other.calibratedSize(), [&](auto N) {
0960           constexpr int measdim = decltype(N)::value;
0961           allocateCalibrated(
0962               other.template calibrated<measdim>().eval(),
0963               other.template calibratedCovariance<measdim>().eval());
0964         });
0965 
0966         setProjectorSubspaceIndices(other.projectorSubspaceIndices());
0967       }
0968     } else {
0969       if (ACTS_CHECK_BIT(mask, PM::Predicted) &&
0970           has<detail_tsp::kPredictedKey>() &&
0971           other.template has<detail_tsp::kPredictedKey>()) {
0972         predicted() = other.predicted();
0973         predictedCovariance() = other.predictedCovariance();
0974       }
0975 
0976       if (ACTS_CHECK_BIT(mask, PM::Filtered) &&
0977           has<detail_tsp::kFilteredKey>() &&
0978           other.template has<detail_tsp::kFilteredKey>()) {
0979         filtered() = other.filtered();
0980         filteredCovariance() = other.filteredCovariance();
0981       }
0982 
0983       if (ACTS_CHECK_BIT(mask, PM::Smoothed) &&
0984           has<detail_tsp::kSmoothedKey>() &&
0985           other.template has<detail_tsp::kSmoothedKey>()) {
0986         smoothed() = other.smoothed();
0987         smoothedCovariance() = other.smoothedCovariance();
0988       }
0989 
0990       if (other.hasUncalibratedSourceLink()) {
0991         setUncalibratedSourceLink(other.getUncalibratedSourceLink());
0992       }
0993 
0994       if (ACTS_CHECK_BIT(mask, PM::Jacobian) &&
0995           has<detail_tsp::kJacobianKey>() &&
0996           other.template has<detail_tsp::kJacobianKey>()) {
0997         jacobian() = other.jacobian();
0998       }
0999 
1000       // NOTE: we should not check hasCalibrated on this, since it
1001       // may be not yet allocated
1002       if (ACTS_CHECK_BIT(mask, PM::Calibrated) &&
1003           other.template has<detail_tsp::kCalibratedKey>()) {
1004         visit_measurement(other.calibratedSize(), [&](auto N) {
1005           constexpr int measdim = decltype(N)::value;
1006           allocateCalibrated(
1007               other.template calibrated<measdim>().eval(),
1008               other.template calibratedCovariance<measdim>().eval());
1009         });
1010 
1011         setProjectorSubspaceIndices(other.projectorSubspaceIndices());
1012       }
1013     }
1014 
1015     chi2() = other.chi2();
1016     pathLength() = other.pathLength();
1017     typeFlags() = other.typeFlags();
1018 
1019     if (other.hasReferenceSurface()) {
1020       setReferenceSurface(other.referenceSurface().getSharedPtr());
1021     }
1022 
1023     m_traj->copyDynamicFrom(m_istate, other.container(), other.index());
1024   }
1025 
1026   /// @}
1027 
1028   /// @anchor track_state_proxy_generic_component
1029   /// @name Track state proxy Generic component access
1030   /// @{
1031 
1032   /// Check if a component is set
1033   /// @tparam key Hashed string key to check for
1034   /// @return true if the component exists, false if not
1035   template <HashedString key>
1036   constexpr bool has() const {
1037     return m_traj->template has<key>(m_istate);
1038   }
1039 
1040   /// Check if a component is set
1041   /// @param key Hashed string key to check for
1042   /// @return true if the component exists, false if not
1043   constexpr bool has(HashedString key) const {
1044     return m_traj->has(key, m_istate);
1045   }
1046 
1047   /// Check if a component is set
1048   /// @param key String key to check for
1049   /// @note This might hash the @p key at runtime instead of compile-time
1050   /// @return true if the component exists, false if not
1051   constexpr bool has(std::string_view key) const {
1052     return has(hashStringDynamic(key));
1053   }
1054 
1055   /// Retrieve a mutable reference to a component
1056   /// @tparam T The type of the component to access
1057   /// @tparam key String key for the component to access
1058   /// @return Mutable reference to the component given by @p key
1059   template <typename T, HashedString key>
1060   constexpr T& component()
1061     requires(!ReadOnly)
1062   {
1063     return m_traj->template component<T, key>(m_istate);
1064   }
1065 
1066   /// Retrieve a mutable reference to a component
1067   /// @tparam T The type of the component to access
1068   /// @param key String key for the component to access
1069   /// @return Mutable reference to the component given by @p key
1070   template <typename T>
1071   constexpr T& component(HashedString key)
1072     requires(!ReadOnly)
1073   {
1074     return m_traj->template component<T>(key, m_istate);
1075   }
1076 
1077   /// Retrieve a mutable reference to a component
1078   /// @tparam T The type of the component to access
1079   /// @param key String key for the component to access
1080   /// @note This might hash the @p key at runtime instead of compile-time
1081   /// @return Mutable reference to the component given by @p key
1082   template <typename T>
1083   constexpr T& component(std::string_view key)
1084     requires(!ReadOnly)
1085   {
1086     return m_traj->template component<T>(hashStringDynamic(key), m_istate);
1087   }
1088 
1089   /// Retrieve a const reference to a component
1090   /// @tparam T The type of the component to access
1091   /// @tparam key String key for the component to access
1092   /// @return Const reference to the component given by @p key
1093   template <typename T, HashedString key>
1094   constexpr const T& component() const {
1095     return m_traj->template component<T, key>(m_istate);
1096   }
1097 
1098   /// Retrieve a const reference to a component
1099   /// @tparam T The type of the component to access
1100   /// @param key String key for the component to access
1101   /// @return Const reference to the component given by @p key
1102   template <typename T>
1103   constexpr const T& component(HashedString key) const {
1104     return m_traj->template component<T>(key, m_istate);
1105   }
1106 
1107   /// Retrieve a const reference to a component
1108   /// @tparam T The type of the component to access
1109   /// @param key String key for the component to access
1110   /// @note This might hash the @p key at runtime instead of compile-time
1111   /// @return Const reference to the component given by @p key
1112   template <typename T>
1113   constexpr const T& component(std::string_view key) const {
1114     return m_traj->template component<T>(hashStringDynamic(key), m_istate);
1115   }
1116 
1117   /// @}
1118 
1119   /// Return a mutable reference to the underlying backend container
1120   /// @return A reference to the backend container
1121   MultiTrajectory<Trajectory>& trajectory()
1122     requires(!ReadOnly)
1123   {
1124     return *m_traj;
1125   }
1126 
1127   /// Return a const reference to the underlying backend container
1128   /// @return A const reference to the backend container
1129   const MultiTrajectory<Trajectory>& trajectory() const { return *m_traj; }
1130 
1131   /// Get a mutable reference to the track state container backend
1132   /// @return a mutable reference to the backend
1133   auto& container()
1134     requires(!ReadOnly)
1135   {
1136     return *m_traj;
1137   }
1138 
1139   /// Get a const reference to the track state container backend
1140   /// @return a const reference to the backend
1141   const auto& container() const { return *m_traj; }
1142 
1143   /// Check if the track state has a specific dynamic column
1144   /// @param key The hashed column key
1145   /// @return true if the column exists
1146   bool hasColumn(HashedString key) const { return container().hasColumn(key); }
1147 
1148  private:
1149   // Private since it can only be created by the trajectory.
1150   TrackStateProxy(
1151       detail_lt::ConstIf<MultiTrajectory<Trajectory>, ReadOnly>& trajectory,
1152       IndexType istate);
1153 
1154   detail_lt::TransitiveConstPointer<
1155       detail_lt::ConstIf<MultiTrajectory<Trajectory>, ReadOnly>>
1156       m_traj;
1157   IndexType m_istate;
1158 
1159   friend class Acts::MultiTrajectory<Trajectory>;
1160   friend class TrackStateProxy<Trajectory, M, true>;
1161   friend class TrackStateProxy<Trajectory, M, false>;
1162 };
1163 }  // namespace Acts
1164 
1165 #include "Acts/EventData/TrackStateProxy.ipp"