Back to home page

EIC code displayed by LXR

 
 

    


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

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/MultiTrajectory.hpp"
0013 #include "Acts/EventData/MultiTrajectoryBackendConcept.hpp"
0014 #include "Acts/EventData/ParticleHypothesis.hpp"
0015 #include "Acts/EventData/TrackContainerBackendConcept.hpp"
0016 #include "Acts/EventData/TrackParameters.hpp"
0017 #include "Acts/EventData/TrackProxyConcept.hpp"
0018 #include "Acts/EventData/TrackStatePropMask.hpp"
0019 #include "Acts/Utilities/HashedString.hpp"
0020 #include "Acts/Utilities/TypeTraits.hpp"
0021 #include "Acts/Utilities/UnitVectors.hpp"
0022 
0023 #include <iterator>
0024 
0025 namespace Acts {
0026 
0027 template <TrackContainerBackend track_container_t,
0028           CommonMultiTrajectoryBackend traj_t,
0029           template <typename> class holder_t>
0030 class TrackContainer;
0031 
0032 /// Proxy class representing a single track.
0033 /// This class provides a **view** into an associated @ref TrackContainer, and
0034 /// has **reference semantics**. You can think of it as a pointer to a vector
0035 /// of tracks, which exposes an object-oriented interface for accessing the
0036 /// track properties.
0037 ///
0038 /// @tparam track_container_t the container backend
0039 /// @tparam trajectory_t the track state container backend
0040 /// @tparam holder_t ownership management class for the backend
0041 /// @tparam read_only true if this track container is not mutable
0042 template <typename track_container_t, typename trajectory_t,
0043           template <typename> class holder_t, bool read_only = true>
0044 class TrackProxy {
0045  public:
0046   /// Indicates whether this track proxy is read-only or if it can be modified
0047   static constexpr bool ReadOnly = read_only;
0048 
0049   /// The track container backend given as a template parameter
0050   using Container = track_container_t;
0051 
0052   /// The track state container backend given as a template parameter
0053   using Trajectory = trajectory_t;
0054 
0055   /// The index type of the track container
0056   using IndexType = typename Container::IndexType;
0057 
0058   /// Sentinel value that indicates an invalid index
0059   static constexpr IndexType kInvalid = Container::kInvalid;
0060 
0061   /// Alias for the mutable version of this track proxy, with the same backends
0062   using MutableTrackProxy =
0063       TrackProxy<track_container_t, trajectory_t, holder_t, false>;
0064 
0065   /// Alias for the const version of this track proxy, with the same backends
0066   using ConstTrackProxy =
0067       TrackProxy<track_container_t, trajectory_t, holder_t, true>;
0068 
0069   /// Alias for an associated const track proxy, with the same backends
0070   using ConstProxyType = ConstTrackProxy;
0071 
0072   /// Alias for an associated mutable track state proxy, with the same backends
0073   using TrackStateProxy = typename Trajectory::TrackStateProxy;
0074 
0075   /// Alias for an associated const track state proxy, with the same backends
0076   using ConstTrackStateProxy = typename Trajectory::ConstTrackStateProxy;
0077 
0078   /// Map-type for a bound parameter vector. This has reference semantics, i.e.
0079   /// points at a matrix by an internal pointer.
0080   using Parameters =
0081       typename detail_lt::FixedSizeTypes<eBoundSize, false>::CoefficientsMap;
0082 
0083   /// Same as @ref Parameters, but with const semantics
0084   using ConstParameters =
0085       typename detail_lt::FixedSizeTypes<eBoundSize, true>::CoefficientsMap;
0086 
0087   /// Map-type for a bound covariance. This has reference semantics, i.e.
0088   /// points at a matrix by an internal pointer.
0089   using Covariance =
0090       typename detail_lt::FixedSizeTypes<eBoundSize, false>::CovarianceMap;
0091 
0092   /// Same as @ref Covariance, but with const semantics
0093   using ConstCovariance =
0094       typename detail_lt::FixedSizeTypes<eBoundSize, true>::CovarianceMap;
0095 
0096 #ifndef DOXYGEN
0097   friend TrackContainer<Container, Trajectory, holder_t>;
0098   friend MutableTrackProxy;
0099   friend ConstTrackProxy;
0100   // Track proxies are friends, not food!
0101   template <typename A, typename B, template <typename> class H, bool R>
0102   friend class TrackProxy;
0103 #endif
0104 
0105   /// @anchor track_proxy_construct
0106   /// @name Constructors and assignment operator
0107   ///
0108   /// Public constructors and assignment operators for @c TrackProxy only
0109   /// allow construction from another @c TrackProxy. You should generally
0110   /// not have to construct @c TrackProxy manually.
0111   ///
0112   /// @{
0113 
0114   /// Copy constructor from a mutable track proxy. This is always valid, either
0115   /// mutable to mutable or mutable to const
0116   /// @param other the other track state proxy
0117   TrackProxy(const MutableTrackProxy& other)
0118       : m_container{other.m_container}, m_index{other.m_index} {}
0119 
0120   /// Copy assignment operator from mutable track proxy. This is always valid,
0121   /// either mutable to mutable or mutable to const
0122   /// @param other the other track state proxy
0123   TrackProxy& operator=(const MutableTrackProxy& other) {
0124     m_container = other.m_container;
0125     m_index = other.m_index;
0126     return *this;
0127   }
0128 
0129   /// @}
0130 
0131   /// Equality operator with another track proxy
0132   /// Checks the container identity and the track index
0133   /// @return True if the track proxies refer to the same track
0134   bool operator==(const TrackProxy& other) const {
0135     return &(*m_container) == &(*other.m_container) && m_index == other.m_index;
0136   }
0137 
0138   /// @anchor track_proxy_props
0139   /// @name TrackProxy properties
0140   /// Methods that give access to the properties of a track represented by
0141   /// @c TrackProxy.
0142   ///
0143   /// Many of these methods come in a @c const and a non-@c const version. The
0144   /// non-@c const version is only available if you have an instance of
0145   /// @c TrackProxy that does not have the @c read_only template parameter set to
0146   /// @c true, even if you hold it as an lvalue.
0147   ///
0148   /// @{
0149 
0150   /// Get the tip index, i.e. the entry point into the track state container
0151   /// @return the tip index by value
0152   IndexType tipIndex() const {
0153     return component<IndexType>(hashString("tipIndex"));
0154   }
0155 
0156   /// Index of the stem, i.e. the innermost track state of the track.
0157   /// This might be invalid, signifying that the track state is not
0158   /// forward-linked.
0159   /// @return the stem index
0160   IndexType stemIndex() const {
0161     return component<IndexType>(hashString("stemIndex"));
0162   }
0163 
0164   /// Get a mutable reference to the tip index, i.e. the entry point into the
0165   /// track container
0166   /// @note Only available if the track proxy is not read-only
0167   /// @return mutable reference to the tip index
0168   IndexType& tipIndex()
0169     requires(!ReadOnly)
0170   {
0171     return component<IndexType>(hashString("tipIndex"));
0172   }
0173 
0174   /// Index of the stem, i.e. the innermost track state of the track.
0175   /// This might be invalid, signifying that the track state is not
0176   /// forward-linked.
0177   /// @note Only available if the track proxy is not read-only
0178   /// @return mutable reference to the stem index
0179   IndexType& stemIndex()
0180     requires(!ReadOnly)
0181   {
0182     return component<IndexType>(hashString("stemIndex"));
0183   }
0184 
0185   /// Get the reference surface of the track (e.g. the perigee)
0186   /// @return the reference surface
0187   const Surface& referenceSurface() const {
0188     return *m_container->container().referenceSurface_impl(m_index);
0189   }
0190 
0191   // NOLINTBEGIN(performance-unnecessary-value-param)
0192   // looks like a false-positive. clang-tidy believes `srf` is not movable.
0193   /// Set a new reference surface for this track
0194   /// @param srf The surface to set
0195   void setReferenceSurface(std::shared_ptr<const Surface> srf)
0196     requires(!ReadOnly)
0197   {
0198     m_container->container().setReferenceSurface_impl(m_index, std::move(srf));
0199   }
0200   // NOLINTEND(performance-unnecessary-value-param)
0201 
0202   /// Returns whether the track has a reference surface or not
0203   /// @return whether a surface exists or not
0204   bool hasReferenceSurface() const {
0205     // @TODO: This could be more efficient
0206     return m_container->container().referenceSurface_impl(m_index) != nullptr;
0207   }
0208 
0209   /// Get the parameters of the track at the reference surface (e.g. perigee).
0210   /// Const version
0211   /// @return Proxy vector for the parameters
0212   ConstParameters parameters() const {
0213     return m_container->parameters(m_index);
0214   }
0215 
0216   /// Get the covariance of the track at the reference surface (e.g. perigee).
0217   /// Const version
0218   /// @return Proxy matrix for the covariance
0219   ConstCovariance covariance() const {
0220     return m_container->covariance(m_index);
0221   }
0222 
0223   /// Get the parameters of the track at the reference surface (e.g. perigee).
0224   /// Mutable version
0225   /// @note Only available if the track proxy is not read-only
0226   /// @return Proxy vector for the parameters
0227   Parameters parameters()
0228     requires(!ReadOnly)
0229   {
0230     return m_container->parameters(m_index);
0231   }
0232 
0233   /// Get the covariance of the track at the reference surface (e.g. perigee).
0234   /// Mutable version
0235   /// @note Only available if the track proxy is not read-only
0236   /// @return Proxy matrix for the covariance
0237   Covariance covariance()
0238     requires(!ReadOnly)
0239   {
0240     return m_container->covariance(m_index);
0241   }
0242 
0243   /// Access the theta parameter of the track at the reference surface
0244   /// @return The theta parameter
0245   double theta() const { return parameters()[eBoundTheta]; }
0246 
0247   /// Access the phi parameter of the track at the reference surface
0248   /// @return The phi parameter
0249   double phi() const { return parameters()[eBoundPhi]; }
0250 
0251   /// Access the loc0 parameter of the track at the reference surface
0252   /// @return The loc0 parameter
0253   double loc0() const { return parameters()[eBoundLoc0]; }
0254 
0255   /// Access the loc1 parameter of the track at the reference surface
0256   /// @return The loc1 parameter
0257   double loc1() const { return parameters()[eBoundLoc1]; }
0258 
0259   /// Access the time parameter of the track at the reference surface
0260   /// @return The time parameter
0261   double time() const { return parameters()[eBoundTime]; }
0262 
0263   /// Access the q/p (curvature) parameter of the track at the reference surface
0264   /// @return The q/p parameter
0265   double qOverP() const { return parameters()[eBoundQOverP]; }
0266 
0267   /// Get the particle hypothesis
0268   /// @return the particle hypothesis
0269   ParticleHypothesis particleHypothesis() const {
0270     return m_container->container().particleHypothesis_impl(m_index);
0271   }
0272 
0273   /// Set a new particle hypothesis for this track
0274   /// @note Only available if the track proxy is not read-only
0275   /// @param particleHypothesis The particle hypothesis to set
0276   void setParticleHypothesis(const ParticleHypothesis& particleHypothesis)
0277     requires(!ReadOnly)
0278   {
0279     m_container->container().setParticleHypothesis_impl(m_index,
0280                                                         particleHypothesis);
0281   }
0282 
0283   /// Get the charge of the tack
0284   /// @note this depends on the charge hypothesis
0285   /// @return The absolute track momentum
0286   double charge() const { return particleHypothesis().qFromQOP(qOverP()); }
0287 
0288   /// Get the absolute momentum of the tack
0289   /// @return The absolute track momentum
0290   double absoluteMomentum() const {
0291     return particleHypothesis().extractMomentum(qOverP());
0292   }
0293 
0294   /// Get the transverse momentum of the track
0295   /// @return The track transverse momentum value
0296   double transverseMomentum() const {
0297     return std::sin(theta()) * absoluteMomentum();
0298   }
0299 
0300   /// Get a unit vector along the track direction at the reference surface
0301   /// @return The direction unit vector
0302   Vector3 direction() const {
0303     return makeDirectionFromPhiTheta(phi(), theta());
0304   }
0305 
0306   /// Get the global momentum vector
0307   /// @return the global momentum vector
0308   Vector3 momentum() const { return absoluteMomentum() * direction(); }
0309 
0310   /// Return the number of track states associated to this track
0311   /// @note This is calculated by iterating over the track states which is
0312   ///       somewhat expensive. Consider caching this value if you need It
0313   ///       more than once.
0314   /// @return The number of track states
0315   unsigned int nTrackStates() const {
0316     // @TODO: This should probably be cached, distance is expensive
0317     //        without random access
0318     if (tipIndex() == kInvalid) {
0319       // no tip index -> no track states
0320       return 0;
0321     }
0322     auto tsRange = trackStatesReversed();
0323     return std::distance(tsRange.begin(), tsRange.end());
0324   }
0325 
0326   /// Return a mutable reference to the number of measurements for the track.
0327   /// Mutable version
0328   /// @note Only available if the track proxy is not read-only
0329   /// @return The number of measurements
0330   unsigned int& nMeasurements()
0331     requires(!ReadOnly)
0332   {
0333     return component<unsigned int, hashString("nMeasurements")>();
0334   }
0335 
0336   /// Return the number of measurements for the track. Const version
0337   /// @return The number of measurements
0338   unsigned int nMeasurements() const {
0339     return component<unsigned int, hashString("nMeasurements")>();
0340   }
0341 
0342   /// Return a mutable reference to the number of holes for the track.
0343   /// Mutable version
0344   /// @note Only available if the track proxy is not read-only
0345   /// @return The number of holes
0346   unsigned int& nHoles()
0347     requires(!ReadOnly)
0348   {
0349     return component<unsigned int, hashString("nHoles")>();
0350   }
0351 
0352   /// Return the number of measurements for the track. Const version
0353   /// @return The number of measurements
0354   unsigned int nHoles() const {
0355     return component<unsigned int, hashString("nHoles")>();
0356   }
0357 
0358   /// Return a mutable reference to the number of outliers for the track.
0359   /// Mutable version
0360   /// @note Only available if the track proxy is not read-only
0361   /// @return The number of outliers
0362   unsigned int& nOutliers()
0363     requires(!ReadOnly)
0364   {
0365     return component<unsigned int, hashString("nOutliers")>();
0366   }
0367 
0368   /// Return the number of outliers for the track. Const version
0369   /// @return The number of outliers
0370   unsigned int nOutliers() const {
0371     return component<unsigned int, hashString("nOutliers")>();
0372   }
0373 
0374   /// Return a mutable reference to the number of shared hits for the track.
0375   /// Mutable version
0376   /// @note Only available if the track proxy is not read-only
0377   /// @return The number of shared hits
0378   unsigned int& nSharedHits()
0379     requires(!ReadOnly)
0380   {
0381     return component<unsigned int, hashString("nSharedHits")>();
0382   }
0383 
0384   /// Return the number of shared hits for the track. Const version
0385   /// @return The number of shared hits
0386   unsigned int nSharedHits() const {
0387     return component<unsigned int, hashString("nSharedHits")>();
0388   }
0389 
0390   /// Return a mutable reference to the chi squared
0391   /// Mutable version
0392   /// @note Only available if the track proxy is not read-only
0393   /// @return The chi squared
0394   float& chi2()
0395     requires(!ReadOnly)
0396   {
0397     return component<float, hashString("chi2")>();
0398   }
0399 
0400   /// Return the chi squared for the track. Const version
0401   /// @return The chi squared
0402   float chi2() const { return component<float, hashString("chi2")>(); }
0403 
0404   /// Return a mutable reference to the number of degrees of freedom for the
0405   /// track. Mutable version
0406   /// @note Only available if the track proxy is not read-only
0407   /// @return The number of degrees of freedom
0408   unsigned int& nDoF()
0409     requires(!ReadOnly)
0410   {
0411     return component<unsigned int, hashString("ndf")>();
0412   }
0413 
0414   /// Return the number of degrees of freedom for the track. Const version
0415   /// @return The number of degrees of freedom
0416   unsigned int nDoF() const {
0417     return component<unsigned int, hashString("ndf")>();
0418   }
0419 
0420   /// Return the index of this track in the track container
0421   /// @note This is separate from the tip index
0422   /// @return the track index
0423   IndexType index() const { return m_index; }
0424 
0425   /// @}
0426 
0427   /// @anchor track_proxy_track_states
0428   /// @name TrackProxy track state access
0429   /// Methods that give access to the track states of a track represented by @c TrackProxy.
0430   /// @{
0431 
0432   /// Return a const track state proxy to the outermost track state
0433   /// @return The outermost track state proxy
0434   ConstTrackStateProxy outermostTrackState() const {
0435     return m_container->trackStateContainer().getTrackState(tipIndex());
0436   }
0437 
0438   /// Return a mutable track state proxy to the outermost track state
0439   /// @return The outermost track state proxy
0440   TrackStateProxy outermostTrackState()
0441     requires(!ReadOnly)
0442   {
0443     return m_container->trackStateContainer().getTrackState(tipIndex());
0444   }
0445 
0446   /// Return a const track state proxy to the innermost track state
0447   /// @note This is only available, if the track is forward linked
0448   /// @return The innermost track state proxy
0449   auto innermostTrackState() const {
0450     using proxy_t = decltype(m_container->trackStateContainer().getTrackState(
0451         std::declval<IndexType>()));
0452 
0453     IndexType stem = component<IndexType, hashString("stemIndex")>();
0454     if (stem == kInvalid) {
0455       return std::optional<proxy_t>{};
0456     } else {
0457       return std::optional<proxy_t>{
0458           m_container->trackStateContainer().getTrackState(stem)};
0459     }
0460   }
0461 
0462   /// Return a mutable track state proxy to the innermost track state
0463   /// @note This is only available, if the track is forward linked
0464   /// @note Only available if the track proxy is not read-only
0465   /// @return The innermost track state proxy
0466   auto innermostTrackState()
0467     requires(!ReadOnly)
0468   {
0469     using proxy_t = decltype(m_container->trackStateContainer().getTrackState(
0470         std::declval<IndexType>()));
0471 
0472     IndexType stem = component<IndexType>(hashString("stemIndex"));
0473     if (stem == kInvalid) {
0474       return std::optional<proxy_t>{};
0475     } else {
0476       return std::optional<proxy_t>{
0477           m_container->trackStateContainer().getTrackState(stem)};
0478     }
0479   }
0480 
0481   /// Get a range over the track states of this track. Return value is
0482   /// compatible with range based for loop. Const version
0483   /// @note This range is from the outside inwards!
0484   /// @return Track state range to iterate over
0485   auto trackStatesReversed() const {
0486     return m_container->reverseTrackStateRange(m_index);
0487   }
0488 
0489   /// Get a range over the track states of this track. Return value is
0490   /// compatible with range based for loop. Mutable version
0491   /// @note Only available if the track proxy is not read-only
0492   /// @note This range is from the outside inwards!
0493   /// @return Track state range to iterate over
0494   auto trackStatesReversed()
0495     requires(!ReadOnly)
0496   {
0497     return m_container->reverseTrackStateRange(m_index);
0498   }
0499 
0500   /// Get a range over the track states of this track. Return value is
0501   /// compatible with range based for loop. This overload returns a const-only
0502   /// track state range, which means you cannot modify the track states obtained
0503   /// in the iteration.
0504   /// @note This range is from the inside out!
0505   /// @warning This access direction is only possible if the track states are
0506   ///          **forward-linked**.
0507   /// @return Track state range to iterate over
0508   auto trackStates() const {
0509     return m_container->forwardTrackStateRange(m_index);
0510   }
0511 
0512   /// Get a range over the track states of this track.
0513   /// Return value is compatible with range based for loop.
0514   /// This overload returns a mutable track state range, which means you
0515   /// can modify the track states obtained in the iteration.
0516   /// @note Only available if the track proxy is not read-only
0517   /// @note This range is from the inside out!
0518   /// @warning This access direction is only possible if the track states are
0519   ///          **forward-linked**.
0520   /// @return Track state range to iterate over
0521   auto trackStates()
0522     requires(!ReadOnly)
0523   {
0524     return m_container->forwardTrackStateRange(m_index);
0525   }
0526 
0527   /// @}
0528 
0529   /// @anchor track_proxy_track_state_manipulation
0530   /// @name TrackProxy track state manipulation
0531   /// Methods that manipulate the track states of a track represented by @c TrackProxy.
0532   /// @{
0533 
0534   /// Forward connect a track.
0535   /// This means setting indices from the inside out on all track states.
0536   /// @note Only available if the track proxy is not read-only
0537   void linkForward()
0538     requires(!ReadOnly)
0539   {
0540     IndexType last = kInvalid;
0541     for (auto ts : trackStatesReversed()) {
0542       ts.template component<IndexType>(hashString("next")) = last;
0543       last = ts.index();
0544     }
0545     stemIndex() = last;
0546   }
0547 
0548   /// Append a track state to this track.
0549   /// This will modify the tip index to point at the newly created track state,
0550   /// which will be directly after the previous track state at tip index.
0551   /// @note Only available if the track proxy is not read-only
0552   /// @param mask The allocation prop mask for the new track state
0553   /// @return The newly added track state
0554   auto appendTrackState(TrackStatePropMask mask = TrackStatePropMask::All)
0555     requires(!ReadOnly)
0556   {
0557     auto& tsc = m_container->trackStateContainer();
0558     auto ts = tsc.makeTrackState(mask, tipIndex());
0559     tipIndex() = ts.index();
0560     return ts;
0561   }
0562 
0563   /// Copy the content of another track proxy into this one
0564   /// @note Only available if the track proxy is not read-only
0565   /// @tparam track_proxy_t the other track proxy's type
0566   /// @param other The track proxy
0567   /// @param copyTrackStates Copy the track state sequence from @p other
0568   template <TrackProxyConcept track_proxy_t>
0569   void copyFrom(const track_proxy_t& other, bool copyTrackStates = true)
0570     requires(!ReadOnly)
0571   {
0572     // @TODO: Add constraint on which track proxies are allowed,
0573     // this is only implicit right now
0574 
0575     if (copyTrackStates) {
0576       // append track states (cheap), but they're in the wrong order
0577       for (const auto& srcTrackState : other.trackStatesReversed()) {
0578         auto destTrackState = appendTrackState(srcTrackState.getMask());
0579         destTrackState.copyFrom(srcTrackState, Acts::TrackStatePropMask::All,
0580                                 true);
0581       }
0582 
0583       // reverse using standard linked list reversal algorithm
0584       reverseTrackStates();
0585     }
0586 
0587     setParticleHypothesis(other.particleHypothesis());
0588 
0589     if (other.hasReferenceSurface()) {
0590       setReferenceSurface(other.referenceSurface().getSharedPtr());
0591       parameters() = other.parameters();
0592       covariance() = other.covariance();
0593     } else {
0594       setReferenceSurface(nullptr);
0595     }
0596 
0597     nMeasurements() = other.nMeasurements();
0598     nHoles() = other.nHoles();
0599     nOutliers() = other.nOutliers();
0600     nSharedHits() = other.nSharedHits();
0601     chi2() = other.chi2();
0602     nDoF() = other.nDoF();
0603 
0604     m_container->copyDynamicFrom(m_index, other.m_container->container(),
0605                                  other.m_index);
0606   }
0607 
0608   /// Creates  a *shallow copy* of the track. Track states are not copied, but
0609   /// the resulting track points at the same track states as the original.
0610   /// @note Only available if the track proxy is not read-only
0611   TrackProxy shallowCopy()
0612     requires(!ReadOnly)
0613   {
0614     auto ts = container().makeTrack();
0615     ts.copyFrom(*this, false);
0616     ts.tipIndex() = tipIndex();
0617     ts.stemIndex() = stemIndex();
0618     return ts;
0619   }
0620 
0621   /// Reverse the ordering of track states for this track
0622   /// Afterwards, the previous endpoint of the track state sequence will be the
0623   /// "innermost" track state
0624   /// @note Only available if the track proxy is not read-only
0625   /// @note This is dangerous with branching track state sequences, as it will break them
0626   /// @note This also automatically forward-links the track!
0627   /// @param invertJacobians Whether to invert the Jacobians of the track states
0628   void reverseTrackStates(bool invertJacobians = false)
0629     requires(!ReadOnly)
0630   {
0631     IndexType current = tipIndex();
0632     IndexType next = kInvalid;
0633     IndexType prev = kInvalid;
0634 
0635     stemIndex() = tipIndex();
0636 
0637     // @TODO: Maybe refactor to not need this variable if invertJacobians == false
0638     BoundMatrix nextJacobian;
0639 
0640     while (current != kInvalid) {
0641       auto ts = m_container->trackStateContainer().getTrackState(current);
0642       prev = ts.previous();
0643       ts.template component<IndexType>(hashString("next")) = prev;
0644       ts.previous() = next;
0645       if (invertJacobians) {
0646         if (next != kInvalid) {
0647           BoundMatrix curJacobian = ts.jacobian();
0648           ts.jacobian() = nextJacobian.inverse();
0649           nextJacobian = curJacobian;
0650         } else {
0651           nextJacobian = ts.jacobian();
0652           ts.jacobian().setZero();
0653         }
0654       }
0655       next = current;
0656       tipIndex() = current;
0657       current = prev;
0658     }
0659   }
0660 
0661   /// @}
0662 
0663   /// @anchor track_proxy_generic_component
0664   /// @name TrackProxy generic component access
0665   /// Methods that give access to generic components of a track represented by
0666   /// @c TrackProxy.  Internally, a compile-time hash of the component name is
0667   /// used to identify which component is being requested. Most of the named
0668   /// methods in @ref track_proxy_props "TrackProxy properties" use these
0669   /// methods to retrieve the actual data.
0670   ///
0671   /// A number of overloads exist, where you can either supply the
0672   /// @ref HashedString @c key as a template parameter or a runtime argument.  The
0673   /// former has the advantage of being guaranteed to be evaluated at
0674   /// compile-time.
0675   ///
0676   /// @{
0677 
0678   /// Retrieve a mutable reference to a component
0679   /// @tparam T The type of the component to access
0680   /// @tparam key String key for the component to access
0681   /// @return Mutable reference to the component given by @p key
0682   template <typename T, HashedString key>
0683   constexpr T& component()
0684     requires(!ReadOnly)
0685   {
0686     return m_container->template component<T, key>(m_index);
0687   }
0688 
0689   /// Retrieve a mutable reference to a component
0690   /// @tparam T The type of the component to access
0691   /// @param key String key for the component to access
0692   /// @return Mutable reference to the component given by @p key
0693   template <typename T>
0694   constexpr T& component(HashedString key)
0695     requires(!ReadOnly)
0696   {
0697     return m_container->template component<T>(key, m_index);
0698   }
0699 
0700   /// Retrieve a mutable reference to a component
0701   /// @tparam T The type of the component to access
0702   /// @param key String key for the component to access
0703   /// @note This might hash the @p key at runtime instead of compile-time
0704   /// @return Mutable reference to the component given by @p key
0705   template <typename T>
0706   constexpr T& component(std::string_view key)
0707     requires(!ReadOnly)
0708   {
0709     return m_container->template component<T>(hashStringDynamic(key), m_index);
0710   }
0711 
0712   /// Retrieve a const reference to a component
0713   /// @tparam T The type of the component to access
0714   /// @tparam key String key for the component to access
0715   /// @return Const reference to the component given by @p key
0716   template <typename T, HashedString key>
0717   constexpr const T& component() const {
0718     return m_container->template component<T, key>(m_index);
0719   }
0720 
0721   /// Retrieve a const reference to a component
0722   /// @tparam T The type of the component to access
0723   /// @param key String key for the component to access
0724   /// @return Const reference to the component given by @p key
0725   template <typename T>
0726   constexpr const T& component(HashedString key) const {
0727     return m_container->template component<T>(key, m_index);
0728   }
0729 
0730   /// Retrieve a const reference to a component
0731   /// @tparam T The type of the component to access
0732   /// @param key String key for the component to access
0733   /// @note This might hash the @p key at runtime instead of compile-time
0734   /// @return Const reference to the component given by @p key
0735   template <typename T>
0736   constexpr const T& component(std::string_view key) const {
0737     return m_container->template component<T>(hashStringDynamic(key), m_index);
0738   }
0739 
0740   /// @}
0741 
0742   /// Return the track parameters at the reference surface
0743   /// @note The parameters are created on the fly
0744   /// @return the track parameters
0745   BoundTrackParameters createParametersAtReference() const {
0746     return BoundTrackParameters(referenceSurface().getSharedPtr(), parameters(),
0747                                 covariance(), particleHypothesis());
0748   }
0749 
0750   /// Convert a track state into track parameters
0751   /// @note The parameters are created on the fly
0752   /// @return the track parameters
0753   BoundTrackParameters createParametersFromState(
0754       const ConstTrackStateProxy& trackState) const {
0755     return BoundTrackParameters(trackState.referenceSurface().getSharedPtr(),
0756                                 trackState.parameters(),
0757                                 trackState.covariance(), particleHypothesis());
0758   }
0759 
0760   /// Return a reference to the track container backend, mutable version.
0761   /// @note Only available if the track proxy is not read-only
0762   /// @return reference to the track container backend
0763   auto& container()
0764     requires(!ReadOnly)
0765   {
0766     return *m_container;
0767   }
0768 
0769   /// Return a reference to the track container backend, const version.
0770   /// @return reference to the track container backend
0771   const auto& container() const { return *m_container; }
0772 
0773  private:
0774   TrackProxy(
0775       const_if_t<ReadOnly, TrackContainer<Container, Trajectory, holder_t>>&
0776           container,
0777       IndexType itrack)
0778       : m_container{&container}, m_index{itrack} {}
0779 
0780   detail_lt::TransitiveConstPointer<
0781       const_if_t<ReadOnly, TrackContainer<Container, Trajectory, holder_t>>>
0782       m_container;
0783   IndexType m_index;
0784 };
0785 
0786 }  // namespace Acts