Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2026-07-16 08:07:26

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   using ConstProxyType = AnyTrackProxy<true>;
0306 
0307   using ParametersMap = detail_anytrack::ParametersMap;
0308   using ConstParametersMap = detail_anytrack::ConstParametersMap;
0309   using CovarianceMap = detail_anytrack::CovarianceMap;
0310   using ConstCovarianceMap = detail_anytrack::ConstCovarianceMap;
0311 
0312   using ContainerPointer = std::conditional_t<ReadOnly, const void*, void*>;
0313   using HandlerPointer =
0314       std::conditional_t<ReadOnly,
0315                          const detail_anytrack::TrackHandlerConstBase*,
0316                          const detail_anytrack::TrackHandlerMutableBase*>;
0317 
0318   /// Copy constructor: const to const or mutable to mutable
0319   /// @param other the other track
0320   AnyTrackProxy(const AnyTrackProxy& other) = default;
0321 
0322   /// Copy assignment operator: const to const or mutable to mutable
0323   /// @param other the other track
0324   /// @return reference to this track
0325   AnyTrackProxy& operator=(const AnyTrackProxy& other) = default;
0326 
0327  private:
0328   /// Constructor from mutable track
0329   /// @note Only available if this is read-only
0330   /// @param other the other track
0331   explicit AnyTrackProxy(const MutableTrackHandle& other)
0332     requires ReadOnly
0333       : m_container(other.m_container),
0334         m_index(other.m_index),
0335         m_handler(other.m_handler) {}
0336 
0337   /// Copy assignment operator from mutable track
0338   /// @note Only available if this is read-only
0339   /// @param other the other track
0340   /// @return reference to this track
0341   AnyTrackProxy& operator=(const MutableTrackHandle& other)
0342     requires ReadOnly
0343   {
0344     m_container = other.m_container;
0345     m_index = other.m_index;
0346     m_handler = other.m_handler;
0347     return *this;
0348   }
0349 
0350  public:
0351   /// Construct from a concrete track proxy
0352   /// @tparam track_proxy_t The concrete track proxy type
0353   /// @param track The track proxy to wrap
0354   /// @note Does not take ownership. The track container must outlive this object.
0355   /// @note AnyConstTrack can be constructed from both mutable and const track proxies.
0356   ///       AnyMutableTrack can only be constructed from mutable track proxies.
0357   template <TrackProxyConcept track_proxy_t>
0358     requires(ReadOnly || !track_proxy_t::ReadOnly)
0359   explicit AnyTrackProxy(track_proxy_t track)
0360       : m_container(nullptr), m_index(track.m_index), m_handler(nullptr) {
0361     using container_t = std::remove_reference_t<decltype(*track.m_container)>;
0362     auto* containerPtr = &(*track.m_container);
0363     if constexpr (ReadOnly) {
0364       m_container = static_cast<const void*>(containerPtr);
0365     } else {
0366       m_container = static_cast<void*>(containerPtr);
0367     }
0368     m_handler = &detail_anytrack::TrackHandler<container_t>::instance();
0369   }
0370 
0371   /// Get the index of this track
0372   /// @return The track index
0373   TrackIndexType index() const { return m_index; }
0374 
0375   /// Get the reference surface
0376   /// @return Reference to the reference surface
0377   const Surface& referenceSurface() const {
0378     const Surface* surface =
0379         constHandler()->referenceSurface(containerPtr(), m_index);
0380     assert(surface != nullptr);
0381     return *surface;
0382   }
0383 
0384   /// Check if track has a reference surface
0385   /// @return true if a reference surface exists
0386   bool hasReferenceSurface() const {
0387     return constHandler()->hasReferenceSurface(containerPtr(), m_index);
0388   }
0389 
0390   /// Get the particle hypothesis
0391   /// @return The particle hypothesis
0392   ParticleHypothesis particleHypothesis() const {
0393     return constHandler()->particleHypothesis(containerPtr(), m_index);
0394   }
0395 
0396   /// Get the bound parameters map
0397   ConstParametersMap parameters() const {
0398     return constHandler()->parameters(containerPtr(), m_index);
0399   }
0400 
0401   /// Get the mutable bound parameters map
0402   ParametersMap parameters()
0403     requires(!ReadOnly)
0404   {
0405     return mutableHandler()->parameters(mutableContainerPtr(), m_index);
0406   }
0407 
0408   /// Get a parameter value by index
0409   /// @param i The parameter index
0410   /// @return The parameter value
0411   double parameter(std::size_t i) const { return parameters()[i]; }
0412 
0413   /// Get a mutable reference to a parameter component
0414   /// @param i The parameter index
0415   /// @return Mutable reference to the value
0416   double& parameter(std::size_t i)
0417     requires(!ReadOnly)
0418   {
0419     auto params = parameters();
0420     return params[i];
0421   }
0422 
0423   /// Get the covariance map
0424   ConstCovarianceMap covariance() const {
0425     return constHandler()->covariance(containerPtr(), m_index);
0426   }
0427 
0428   /// Get the mutable covariance map
0429   CovarianceMap covariance()
0430     requires(!ReadOnly)
0431   {
0432     return mutableHandler()->covariance(mutableContainerPtr(), m_index);
0433   }
0434 
0435   /// Get a covariance matrix element
0436   /// @param i Row index
0437   /// @param j Column index
0438   /// @return The covariance element
0439   double covariance(std::size_t i, std::size_t j) const {
0440     return covariance()(i, j);
0441   }
0442 
0443   /// Get a mutable reference to a covariance element
0444   /// @param i Row index
0445   /// @param j Column index
0446   /// @return Mutable reference to the covariance value
0447   double& covariance(std::size_t i, std::size_t j)
0448     requires(!ReadOnly)
0449   {
0450     auto cov = covariance();
0451     return cov(i, j);
0452   }
0453 
0454   using Base::absoluteMomentum;
0455   using Base::charge;
0456   using Base::fourMomentum;
0457   using Base::loc0;
0458   using Base::loc1;
0459   using Base::phi;
0460   using Base::qOverP;
0461   using Base::theta;
0462   using Base::time;
0463   using Base::transverseMomentum;
0464 
0465   /// Get the number of track states
0466   /// @return The number of track states
0467   unsigned int nTrackStates() const {
0468     return constHandler()->nTrackStates(containerPtr(), m_index);
0469   }
0470 
0471   /// Check if the track has a specific dynamic column
0472   /// @param key The hashed column key
0473   /// @return true if the column exists
0474   bool hasColumn(HashedString key) const {
0475     return constHandler()->hasColumn(containerPtr(), key);
0476   }
0477 
0478   /// Get a mutable reference to a dynamic column component
0479   /// @tparam T The type of the component
0480   /// @tparam key String key for the component to access
0481   /// @return Mutable reference to the component
0482   /// @note Only available if ReadOnly is false
0483   template <typename T, HashedString key>
0484   T& component()
0485     requires(!ReadOnly)
0486   {
0487     std::any result =
0488         mutableHandler()->component(mutableContainerPtr(), m_index, key);
0489     return *std::any_cast<T*>(result);
0490   }
0491 
0492   /// Get a mutable reference to a dynamic column component
0493   /// @tparam T The type of the component
0494   /// @param key String key for the component to access
0495   /// @return Mutable reference to the component
0496   /// @note Only available if ReadOnly is false
0497   template <typename T>
0498   T& component(HashedString key)
0499     requires(!ReadOnly)
0500   {
0501     std::any result =
0502         mutableHandler()->component(mutableContainerPtr(), m_index, key);
0503     return *std::any_cast<T*>(result);
0504   }
0505 
0506   /// Get a const reference to a dynamic column component
0507   /// @tparam T The type of the component
0508   /// @tparam key String key for the component to access
0509   /// @return Const reference to the component
0510   template <typename T, HashedString key>
0511   const T& component() const {
0512     std::any result = constHandler()->component(containerPtr(), m_index, key);
0513     return *std::any_cast<const T*>(result);
0514   }
0515 
0516   /// Get a const reference to a dynamic column component
0517   /// @tparam T The type of the component
0518   /// @param key String key for the component to access
0519   /// @return Const reference to the component
0520   template <typename T>
0521   const T& component(HashedString key) const {
0522     std::any result = constHandler()->component(containerPtr(), m_index, key);
0523     return *std::any_cast<const T*>(result);
0524   }
0525 
0526  private:
0527   template <bool R>
0528   friend class AnyTrackProxy;
0529 
0530   const detail_anytrack::TrackHandlerConstBase* constHandler() const {
0531     return m_handler;
0532   }
0533 
0534   const detail_anytrack::TrackHandlerMutableBase* mutableHandler() const
0535     requires(!ReadOnly)
0536   {
0537     return m_handler;
0538   }
0539 
0540   const void* containerPtr() const {
0541     if constexpr (ReadOnly) {
0542       return m_container;
0543     } else {
0544       return static_cast<const void*>(m_container);
0545     }
0546   }
0547 
0548   void* mutableContainerPtr() const
0549     requires(!ReadOnly)
0550   {
0551     return m_container;
0552   }
0553 
0554   /// Pointer to the track container (non-owning)
0555   ContainerPointer m_container;
0556 
0557   /// Track index within the container
0558   TrackIndexType m_index;
0559 
0560   /// Pointer to the static handler instance
0561   HandlerPointer m_handler;
0562 };
0563 
0564 /// Alias for read-only type-erased track
0565 using AnyConstTrackProxy = AnyTrackProxy<true>;
0566 
0567 /// Alias for mutable type-erased track (though currently all operations are
0568 /// const)
0569 using AnyMutableTrackProxy = AnyTrackProxy<false>;
0570 
0571 static_assert(ConstTrackProxyConcept<AnyConstTrackProxy>);
0572 static_assert(MutableTrackProxyConcept<AnyMutableTrackProxy>);
0573 
0574 }  // namespace Acts