Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-06 08:10:01

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