Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-03-28 07:45:15

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/ParticleHypothesis.hpp"
0013 #include "Acts/EventData/TrackProxy.hpp"
0014 #include "Acts/EventData/TrackProxyCommon.hpp"
0015 #include "Acts/EventData/TrackProxyConcept.hpp"
0016 #include "Acts/EventData/Types.hpp"
0017 #include "Acts/Utilities/HashedString.hpp"
0018 
0019 #include <any>
0020 #include <cassert>
0021 #include <cmath>
0022 #include <type_traits>
0023 
0024 namespace Acts {
0025 
0026 class Surface;
0027 
0028 namespace detail_anytrack {
0029 
0030 using ParametersMap = detail_tpc::ParametersMap;
0031 using ConstParametersMap = detail_tpc::ConstParametersMap;
0032 using CovarianceMap = detail_tpc::CovarianceMap;
0033 using ConstCovarianceMap = detail_tpc::ConstCovarianceMap;
0034 
0035 /// Base class for read-only track handlers
0036 /// Provides accessors that return const references to the underlying data
0037 class TrackHandlerConstBase {
0038  public:
0039   virtual ~TrackHandlerConstBase() = default;
0040 
0041   /// Get the reference surface
0042   virtual const Surface* referenceSurface(const void* container,
0043                                           TrackIndexType index) const = 0;
0044 
0045   /// Check if track has a reference surface
0046   virtual bool hasReferenceSurface(const void* container,
0047                                    TrackIndexType index) const = 0;
0048 
0049   /// Get the particle hypothesis
0050   virtual ParticleHypothesis particleHypothesis(const void* container,
0051                                                 TrackIndexType index) const = 0;
0052 
0053   /// Get parameter vector
0054   virtual ConstParametersMap parameters(const void* container,
0055                                         TrackIndexType index) const = 0;
0056 
0057   /// Get covariance matrix
0058   virtual ConstCovarianceMap covariance(const void* container,
0059                                         TrackIndexType index) const = 0;
0060 
0061   /// Get number of track states
0062   virtual unsigned int nTrackStates(const void* container,
0063                                     TrackIndexType index) const = 0;
0064 
0065   /// Check if track has a specific dynamic column
0066   virtual bool hasColumn(const void* container, HashedString key) const = 0;
0067 
0068   /// Get a dynamic column component (type-erased)
0069   virtual std::any component(const void* container, TrackIndexType index,
0070                              HashedString key) const = 0;
0071 };
0072 
0073 /// Base class for mutable track handlers.
0074 /// Extends the const interface with mutable references to the data.
0075 class TrackHandlerMutableBase : public TrackHandlerConstBase {
0076  public:
0077   using TrackHandlerConstBase::component;
0078   using TrackHandlerConstBase::covariance;
0079   using TrackHandlerConstBase::parameters;
0080 
0081   /// Get mutable parameter vector
0082   virtual ParametersMap parameters(void* container,
0083                                    TrackIndexType index) const = 0;
0084 
0085   /// Get mutable covariance matrix
0086   virtual CovarianceMap covariance(void* container,
0087                                    TrackIndexType index) const = 0;
0088 
0089   /// Get mutable dynamic column component (type-erased)
0090   virtual std::any component(void* container, TrackIndexType index,
0091                              HashedString key) const = 0;
0092 };
0093 
0094 template <typename container_t>
0095 struct TrackHandlerTraits {
0096   using Container = std::remove_const_t<container_t>;
0097   static constexpr bool ReadOnly =
0098       std::is_const_v<container_t> || Container::ReadOnly;
0099 };
0100 
0101 /// Concrete handler for a specific track container type
0102 /// This templated class provides static instances that implement the virtual
0103 /// interface for a specific track container type. The static instance approach
0104 /// avoids heap allocation per handle.
0105 template <typename container_t,
0106           bool read_only = TrackHandlerTraits<container_t>::ReadOnly>
0107 class TrackHandler;
0108 
0109 template <typename container_t>
0110 class TrackHandler<container_t, true> final : public TrackHandlerConstBase {
0111   using ContainerType = typename TrackHandlerTraits<container_t>::Container;
0112 
0113  public:
0114   /// Get the singleton instance for this track container type
0115   static const TrackHandler& instance() {
0116     static const TrackHandler s_instance;
0117     return s_instance;
0118   }
0119 
0120   const Surface* referenceSurface(const void* container,
0121                                   TrackIndexType index) const override {
0122     assert(container != nullptr);
0123     const auto* tc = static_cast<const ContainerType*>(container);
0124     return &tc->getTrack(index).referenceSurface();
0125   }
0126 
0127   bool hasReferenceSurface(const void* container,
0128                            TrackIndexType index) const override {
0129     assert(container != nullptr);
0130     const auto* tc = static_cast<const ContainerType*>(container);
0131     return tc->getTrack(index).hasReferenceSurface();
0132   }
0133 
0134   ParticleHypothesis particleHypothesis(const void* container,
0135                                         TrackIndexType index) const override {
0136     assert(container != nullptr);
0137     const auto* tc = static_cast<const ContainerType*>(container);
0138     return tc->getTrack(index).particleHypothesis();
0139   }
0140 
0141   ConstParametersMap parameters(const void* container,
0142                                 TrackIndexType index) const override {
0143     assert(container != nullptr);
0144     const auto* tc = static_cast<const ContainerType*>(container);
0145     return tc->getTrack(index).parameters();
0146   }
0147 
0148   ConstCovarianceMap covariance(const void* container,
0149                                 TrackIndexType index) const override {
0150     assert(container != nullptr);
0151     const auto* tc = static_cast<const ContainerType*>(container);
0152     return tc->getTrack(index).covariance();
0153   }
0154 
0155   unsigned int nTrackStates(const void* container,
0156                             TrackIndexType index) const override {
0157     assert(container != nullptr);
0158     const auto* tc = static_cast<const ContainerType*>(container);
0159     return tc->getTrack(index).nTrackStates();
0160   }
0161 
0162   bool hasColumn(const void* container, HashedString key) const override {
0163     assert(container != nullptr);
0164     const auto* tc = static_cast<const ContainerType*>(container);
0165     return tc->hasColumn(key);
0166   }
0167 
0168   std::any component(const void* container, TrackIndexType index,
0169                      HashedString key) const override {
0170     assert(container != nullptr);
0171     const auto* tc = static_cast<const ContainerType*>(container);
0172     return tc->container().component_impl(key, index);
0173   }
0174 
0175  private:
0176   TrackHandler() = default;
0177 };
0178 
0179 template <typename container_t>
0180 class TrackHandler<container_t, false> final : public TrackHandlerMutableBase {
0181   using ContainerType = typename TrackHandlerTraits<container_t>::Container;
0182 
0183  public:
0184   /// Get the singleton instance for this track container type
0185   static const TrackHandler& instance() {
0186     static const TrackHandler s_instance;
0187     return s_instance;
0188   }
0189 
0190   const Surface* referenceSurface(const void* container,
0191                                   TrackIndexType index) const override {
0192     assert(container != nullptr);
0193     const auto* tc = static_cast<const ContainerType*>(container);
0194     return &tc->getTrack(index).referenceSurface();
0195   }
0196 
0197   bool hasReferenceSurface(const void* container,
0198                            TrackIndexType index) const override {
0199     assert(container != nullptr);
0200     const auto* tc = static_cast<const ContainerType*>(container);
0201     return tc->getTrack(index).hasReferenceSurface();
0202   }
0203 
0204   ParticleHypothesis particleHypothesis(const void* container,
0205                                         TrackIndexType index) const override {
0206     assert(container != nullptr);
0207     const auto* tc = static_cast<const ContainerType*>(container);
0208     return tc->getTrack(index).particleHypothesis();
0209   }
0210 
0211   ConstParametersMap parameters(const void* container,
0212                                 TrackIndexType index) const override {
0213     assert(container != nullptr);
0214     const auto* tc = static_cast<const ContainerType*>(container);
0215     return tc->getTrack(index).parameters();
0216   }
0217 
0218   ParametersMap parameters(void* container,
0219                            TrackIndexType index) const override {
0220     assert(container != nullptr);
0221     auto* tc = static_cast<ContainerType*>(container);
0222     return tc->getTrack(index).parameters();
0223   }
0224 
0225   ConstCovarianceMap covariance(const void* container,
0226                                 TrackIndexType index) const override {
0227     assert(container != nullptr);
0228     const auto* tc = static_cast<const ContainerType*>(container);
0229     return tc->getTrack(index).covariance();
0230   }
0231 
0232   CovarianceMap covariance(void* container,
0233                            TrackIndexType index) const override {
0234     assert(container != nullptr);
0235     auto* tc = static_cast<ContainerType*>(container);
0236     return tc->getTrack(index).covariance();
0237   }
0238 
0239   unsigned int nTrackStates(const void* container,
0240                             TrackIndexType index) const override {
0241     assert(container != nullptr);
0242     const auto* tc = static_cast<const ContainerType*>(container);
0243     return tc->getTrack(index).nTrackStates();
0244   }
0245 
0246   bool hasColumn(const void* container, HashedString key) const override {
0247     assert(container != nullptr);
0248     const auto* tc = static_cast<const ContainerType*>(container);
0249     return tc->hasColumn(key);
0250   }
0251 
0252   std::any component(const void* container, TrackIndexType index,
0253                      HashedString key) const override {
0254     assert(container != nullptr);
0255     const auto* tc = static_cast<const ContainerType*>(container);
0256     return tc->container().component_impl(key, index);
0257   }
0258 
0259   std::any component(void* container, TrackIndexType index,
0260                      HashedString key) const override {
0261     assert(container != nullptr);
0262     auto* tc = static_cast<ContainerType*>(container);
0263     return tc->container().component_impl(key, index);
0264   }
0265 
0266  private:
0267   TrackHandler() = default;
0268 };
0269 
0270 }  // namespace detail_anytrack
0271 
0272 /// Type-erased track object
0273 /// This class provides a type-erased interface to track proxies without
0274 /// requiring heap allocation per instance. It stores a pointer to the track
0275 /// container and the track index, similar to how TrackProxy works internally.
0276 ///
0277 /// The object does not take ownership of the container - the container must
0278 /// outlive the object.
0279 ///
0280 /// @tparam read_only If true, provides read-only access to the track
0281 ///
0282 /// Usage:
0283 /// @code
0284 /// TrackContainer tracks = ...;
0285 /// auto track = tracks.getTrack(0);
0286 /// AnyMutableTrack AnyTrackProxy(track);  // Mutable track
0287 /// AnyConstTrack constTrack(track);  // Read-only track
0288 /// std::cout << "Chi2: " << AnyTrackProxy.chi2() << std::endl;
0289 /// @endcode
0290 template <bool read_only = true>
0291 class AnyTrackProxy : public TrackProxyCommon<AnyTrackProxy<read_only>,
0292                                               TrackIndexType, read_only> {
0293   using Base =
0294       TrackProxyCommon<AnyTrackProxy<read_only>, TrackIndexType, read_only>;
0295 
0296  public:
0297   /// Indicates whether this track is read-only
0298   static constexpr bool ReadOnly = read_only;
0299 
0300   /// Alias for the mutable version
0301   using MutableTrackHandle = AnyTrackProxy<false>;
0302 
0303   /// Alias for the const version
0304   using ConstTrackHandle = AnyTrackProxy<true>;
0305   /// Alias for the const proxy type
0306   using ConstProxyType = AnyTrackProxy<true>;
0307 
0308   /// Mutable parameters map type
0309   using ParametersMap = detail_anytrack::ParametersMap;
0310   /// Const parameters map type
0311   using ConstParametersMap = detail_anytrack::ConstParametersMap;
0312   /// Mutable covariance map type
0313   using CovarianceMap = detail_anytrack::CovarianceMap;
0314   /// Const covariance map type
0315   using ConstCovarianceMap = detail_anytrack::ConstCovarianceMap;
0316 
0317   /// Container pointer type
0318   using ContainerPointer = std::conditional_t<ReadOnly, const void*, void*>;
0319   /// Handler pointer type
0320   using HandlerPointer =
0321       std::conditional_t<ReadOnly,
0322                          const detail_anytrack::TrackHandlerConstBase*,
0323                          const detail_anytrack::TrackHandlerMutableBase*>;
0324 
0325   /// Copy constructor: const to const or mutable to mutable
0326   /// @param other the other track
0327   AnyTrackProxy(const AnyTrackProxy& other) = default;
0328 
0329   /// Copy assignment operator: const to const or mutable to mutable
0330   /// @param other the other track
0331   /// @return reference to this track
0332   AnyTrackProxy& operator=(const AnyTrackProxy& other) = default;
0333 
0334  private:
0335   /// Constructor from mutable track
0336   /// @note Only available if this is read-only
0337   /// @param other the other track
0338   explicit AnyTrackProxy(const MutableTrackHandle& other)
0339     requires ReadOnly
0340       : m_container(other.m_container),
0341         m_index(other.m_index),
0342         m_handler(other.m_handler) {}
0343 
0344   /// Copy assignment operator from mutable track
0345   /// @note Only available if this is read-only
0346   /// @param other the other track
0347   /// @return reference to this track
0348   AnyTrackProxy& operator=(const MutableTrackHandle& other)
0349     requires ReadOnly
0350   {
0351     m_container = other.m_container;
0352     m_index = other.m_index;
0353     m_handler = other.m_handler;
0354     return *this;
0355   }
0356 
0357  public:
0358   /// Construct from a concrete track proxy
0359   /// @tparam track_proxy_t The concrete track proxy type
0360   /// @param track The track proxy to wrap
0361   /// @note Does not take ownership. The track container must outlive this object.
0362   /// @note AnyConstTrack can be constructed from both mutable and const track proxies.
0363   ///       AnyMutableTrack can only be constructed from mutable track proxies.
0364   template <TrackProxyConcept track_proxy_t>
0365     requires(ReadOnly || !track_proxy_t::ReadOnly)
0366   explicit AnyTrackProxy(track_proxy_t track)
0367       : m_container(nullptr), m_index(track.m_index), m_handler(nullptr) {
0368     using container_t = std::remove_reference_t<decltype(*track.m_container)>;
0369     auto* containerPtr = &(*track.m_container);
0370     if constexpr (ReadOnly) {
0371       m_container = static_cast<const void*>(containerPtr);
0372     } else {
0373       m_container = static_cast<void*>(containerPtr);
0374     }
0375     m_handler = &detail_anytrack::TrackHandler<container_t>::instance();
0376   }
0377 
0378   /// Get the index of this track
0379   /// @return The track index
0380   TrackIndexType index() const { return m_index; }
0381 
0382   /// Get the reference surface
0383   /// @return Reference to the reference surface
0384   const Surface& referenceSurface() const {
0385     const Surface* surface =
0386         constHandler()->referenceSurface(containerPtr(), m_index);
0387     assert(surface != nullptr);
0388     return *surface;
0389   }
0390 
0391   /// Check if track has a reference surface
0392   /// @return true if a reference surface exists
0393   bool hasReferenceSurface() const {
0394     return constHandler()->hasReferenceSurface(containerPtr(), m_index);
0395   }
0396 
0397   /// Get the particle hypothesis
0398   /// @return The particle hypothesis
0399   ParticleHypothesis particleHypothesis() const {
0400     return constHandler()->particleHypothesis(containerPtr(), m_index);
0401   }
0402 
0403   /// Get the bound parameters map
0404   /// @return The const parameters map
0405   ConstParametersMap parameters() const {
0406     return constHandler()->parameters(containerPtr(), m_index);
0407   }
0408 
0409   /// Get the mutable bound parameters map
0410   /// @return The mutable parameters map
0411   ParametersMap parameters()
0412     requires(!ReadOnly)
0413   {
0414     return mutableHandler()->parameters(mutableContainerPtr(), m_index);
0415   }
0416 
0417   /// Get a parameter value by index
0418   /// @param i The parameter index
0419   /// @return The parameter value
0420   double parameter(std::size_t i) const { return parameters()[i]; }
0421 
0422   /// Get a mutable reference to a parameter component
0423   /// @param i The parameter index
0424   /// @return Mutable reference to the value
0425   double& parameter(std::size_t i)
0426     requires(!ReadOnly)
0427   {
0428     auto params = parameters();
0429     return params[i];
0430   }
0431 
0432   /// Get the covariance map
0433   /// @return The const covariance map
0434   ConstCovarianceMap covariance() const {
0435     return constHandler()->covariance(containerPtr(), m_index);
0436   }
0437 
0438   /// Get the mutable covariance map
0439   /// @return The mutable covariance map
0440   CovarianceMap covariance()
0441     requires(!ReadOnly)
0442   {
0443     return mutableHandler()->covariance(mutableContainerPtr(), m_index);
0444   }
0445 
0446   /// Get a covariance matrix element
0447   /// @param i Row index
0448   /// @param j Column index
0449   /// @return The covariance element
0450   double covariance(std::size_t i, std::size_t j) const {
0451     return covariance()(i, j);
0452   }
0453 
0454   /// Get a mutable reference to a covariance element
0455   /// @param i Row index
0456   /// @param j Column index
0457   /// @return Mutable reference to the covariance value
0458   double& covariance(std::size_t i, std::size_t j)
0459     requires(!ReadOnly)
0460   {
0461     auto cov = covariance();
0462     return cov(i, j);
0463   }
0464 
0465   using Base::absoluteMomentum;
0466   using Base::charge;
0467   using Base::fourMomentum;
0468   using Base::loc0;
0469   using Base::loc1;
0470   using Base::phi;
0471   using Base::qOverP;
0472   using Base::theta;
0473   using Base::time;
0474   using Base::transverseMomentum;
0475 
0476   /// Get the number of track states
0477   /// @return The number of track states
0478   unsigned int nTrackStates() const {
0479     return constHandler()->nTrackStates(containerPtr(), m_index);
0480   }
0481 
0482   /// Check if the track has a specific dynamic column
0483   /// @param key The hashed column key
0484   /// @return true if the column exists
0485   bool hasColumn(HashedString key) const {
0486     return constHandler()->hasColumn(containerPtr(), key);
0487   }
0488 
0489   /// Get a mutable reference to a dynamic column component
0490   /// @tparam T The type of the component
0491   /// @tparam key String key for the component to access
0492   /// @return Mutable reference to the component
0493   /// @note Only available if ReadOnly is false
0494   template <typename T, HashedString key>
0495   T& component()
0496     requires(!ReadOnly)
0497   {
0498     std::any result =
0499         mutableHandler()->component(mutableContainerPtr(), m_index, key);
0500     return *std::any_cast<T*>(result);
0501   }
0502 
0503   /// Get a mutable reference to a dynamic column component
0504   /// @tparam T The type of the component
0505   /// @param key String key for the component to access
0506   /// @return Mutable reference to the component
0507   /// @note Only available if ReadOnly is false
0508   template <typename T>
0509   T& component(HashedString key)
0510     requires(!ReadOnly)
0511   {
0512     std::any result =
0513         mutableHandler()->component(mutableContainerPtr(), m_index, key);
0514     return *std::any_cast<T*>(result);
0515   }
0516 
0517   /// Get a const reference to a dynamic column component
0518   /// @tparam T The type of the component
0519   /// @tparam key String key for the component to access
0520   /// @return Const reference to the component
0521   template <typename T, HashedString key>
0522   const T& component() const {
0523     std::any result = constHandler()->component(containerPtr(), m_index, key);
0524     return *std::any_cast<const T*>(result);
0525   }
0526 
0527   /// Get a const reference to a dynamic column component
0528   /// @tparam T The type of the component
0529   /// @param key String key for the component to access
0530   /// @return Const reference to the component
0531   template <typename T>
0532   const T& component(HashedString key) const {
0533     std::any result = constHandler()->component(containerPtr(), m_index, key);
0534     return *std::any_cast<const T*>(result);
0535   }
0536 
0537  private:
0538   template <bool R>
0539   friend class AnyTrackProxy;
0540 
0541   const detail_anytrack::TrackHandlerConstBase* constHandler() const {
0542     return m_handler;
0543   }
0544 
0545   const detail_anytrack::TrackHandlerMutableBase* mutableHandler() const
0546     requires(!ReadOnly)
0547   {
0548     return m_handler;
0549   }
0550 
0551   const void* containerPtr() const {
0552     if constexpr (ReadOnly) {
0553       return m_container;
0554     } else {
0555       return static_cast<const void*>(m_container);
0556     }
0557   }
0558 
0559   void* mutableContainerPtr() const
0560     requires(!ReadOnly)
0561   {
0562     return m_container;
0563   }
0564 
0565   /// Pointer to the track container (non-owning)
0566   ContainerPointer m_container;
0567 
0568   /// Track index within the container
0569   TrackIndexType m_index;
0570 
0571   /// Pointer to the static handler instance
0572   HandlerPointer m_handler;
0573 };
0574 
0575 /// Alias for read-only type-erased track
0576 using AnyConstTrackProxy = AnyTrackProxy<true>;
0577 
0578 /// Alias for mutable type-erased track (though currently all operations are
0579 /// const)
0580 using AnyMutableTrackProxy = AnyTrackProxy<false>;
0581 
0582 static_assert(ConstTrackProxyConcept<AnyConstTrackProxy>);
0583 static_assert(MutableTrackProxyConcept<AnyMutableTrackProxy>);
0584 
0585 }  // namespace Acts