Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-10-18 08:20:28

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/EventData/MultiTrajectory.hpp"
0012 #include "Acts/EventData/MultiTrajectoryBackendConcept.hpp"
0013 #include "Acts/EventData/TrackContainerBackendConcept.hpp"
0014 #include "Acts/EventData/TrackProxy.hpp"
0015 #include "Acts/EventData/Types.hpp"
0016 #include "Acts/EventData/Utils.hpp"
0017 #include "Acts/Utilities/HashedString.hpp"
0018 #include "Acts/Utilities/Holders.hpp"
0019 #include "Acts/Utilities/TypeTraits.hpp"
0020 #include "Acts/Utilities/detail/ContainerIterator.hpp"
0021 
0022 #include <any>
0023 #include <string>
0024 #include <string_view>
0025 
0026 namespace Acts {
0027 
0028 template <typename T>
0029 struct IsReadOnlyTrackContainer;
0030 
0031 /// Track container interface class. This type represents a collections of
0032 /// tracks. It uses a backend to store both the actual tracks and the
0033 /// associated track states.
0034 /// @tparam track_container_t the track container backend
0035 /// @tparam traj_t the track state container backend
0036 /// @tparam holder_t ownership management class for the backend
0037 template <TrackContainerBackend track_container_t,
0038           CommonMultiTrajectoryBackend traj_t,
0039           template <typename> class holder_t = detail::RefHolder>
0040 class TrackContainer {
0041  public:
0042   /// Indicates if this track container is read-only, or if it can be modified
0043   static constexpr bool ReadOnly =
0044       IsReadOnlyTrackContainer<track_container_t>::value;
0045 
0046   /// Indicates if the track state container is read-only, or if it can be
0047   /// modified
0048   static constexpr bool TrackStateReadOnly =
0049       IsReadOnlyMultiTrajectory<traj_t>::value;
0050 
0051   static_assert(ReadOnly == TrackStateReadOnly,
0052                 "Either both track container and track state container need to "
0053                 "be readonly or both have to be readwrite");
0054 
0055   /// The index type of the track container, taken from the container backend
0056   using IndexType = TrackIndexType;
0057 
0058   /// Sentinel value that indicates an invalid index
0059   static constexpr IndexType kInvalid = kTrackIndexInvalid;
0060 
0061   /// Alias for the mutable version of a track proxy, with the same backends as
0062   /// this container
0063   using TrackProxy =
0064       Acts::TrackProxy<track_container_t, traj_t, holder_t, false>;
0065 
0066   /// Alias for the const version of a track proxy, with the same backends as
0067   /// this container
0068   using ConstTrackProxy =
0069       Acts::TrackProxy<track_container_t, traj_t, holder_t, true>;
0070 
0071   /// Type alias for track container backend type
0072   using TrackContainerBackend = track_container_t;
0073   /// Type alias for track state container backend type
0074   using TrackStateContainerBackend = traj_t;
0075 
0076   /// Type alias for mutable track state proxy from multi-trajectory
0077   using TrackStateProxy = typename MultiTrajectory<traj_t>::TrackStateProxy;
0078   /// Type alias for const track state proxy from multi-trajectory
0079   using ConstTrackStateProxy =
0080       typename MultiTrajectory<traj_t>::ConstTrackStateProxy;
0081 
0082   /// Type alias for size type of track container
0083   using size_type = IndexType;
0084   /// Type alias for mutable iterator over tracks in container
0085   using iterator =
0086       detail::ContainerIterator<TrackContainer, TrackProxy, IndexType, false>;
0087   /// Type alias for const iterator over tracks in container
0088   using const_iterator =
0089       detail::ContainerIterator<TrackContainer, ConstTrackProxy, IndexType,
0090                                 true>;
0091 
0092 #ifndef DOXYGEN
0093   friend TrackProxy;
0094   friend ConstTrackProxy;
0095 #endif
0096 
0097   /// @anchor track_container_construction
0098   /// @name TrackContainer construction
0099   ///
0100   /// Constructors for the track container by using a set of backends
0101   /// (track + track state). The container can either take ownership of the
0102   /// backends or just hold references to them. This is driven by the @c
0103   /// holder_t template parameter, where you can also supply a custom holder
0104   /// type. Template deduction is used to try to guess the correct holder type.
0105   ///
0106   /// @{
0107 
0108   /// Constructor from a track container backend and a track state container
0109   /// backend
0110   /// @param container the track container backend
0111   /// @param traj the track state container backend
0112   TrackContainer(holder_t<track_container_t> container, holder_t<traj_t> traj)
0113       : m_container{std::move(container)}, m_traj{std::move(traj)} {}
0114 
0115   /// Constructor from references to a track container backend and to a track
0116   /// state container backend
0117   /// @note The track container will not assume ownership over the backends in this case.
0118   ///       You need to ensure suitable lifetime
0119   /// @param container the track container backend
0120   /// @param traj the track state container backend
0121   TrackContainer(auto& container, auto& traj)
0122     requires(detail::is_same_template<holder_t, detail::RefHolder>::value)
0123       : m_container{&container}, m_traj{&traj} {}
0124 
0125   /// Constructor from const references to a track container backend and to a
0126   /// track state container backend
0127   /// @note The track container will not assume ownership over the backends in this case.
0128   ///       You need to ensure suitable lifetime
0129   /// @param container the track container backend
0130   /// @param traj the track state container backend
0131   TrackContainer(const auto& container, const auto& traj)
0132     requires(detail::is_same_template<holder_t,
0133                                       detail::ConstRefHolder>::value &&
0134              ReadOnly && TrackStateReadOnly)
0135       : m_container{&container}, m_traj{&traj} {}
0136 
0137   /// @}
0138 
0139   /// @anchor track_container_track_access
0140   /// @name TrackContainer track (proxy) access and manipulation
0141   ///
0142   /// These methods allow accessing tracks, i.e. adding or retrieving a track
0143   /// proxy that points at a specific track in the container.
0144   ///
0145   /// @{
0146 
0147   /// Get a const track proxy for a track index
0148   /// @param itrack the track index in the container
0149   /// @return A const track proxy for the index
0150   ConstTrackProxy getTrack(IndexType itrack) const { return {*this, itrack}; }
0151 
0152   /// Get a mutable track proxy for a track index
0153   /// @note Only available if the track container is not read-only
0154   /// @param itrack the track index in the container
0155   /// @return A mutable track proxy for the index
0156   TrackProxy getTrack(IndexType itrack)
0157     requires(!ReadOnly)
0158   {
0159     return {*this, itrack};
0160   }
0161 
0162   /// Get a const track proxy for a track index
0163   /// @param itrack the track index in the container
0164   /// @return A const track proxy for the index
0165   ConstTrackProxy at(IndexType itrack) const { return getTrack(itrack); }
0166 
0167   /// Get a mutable track proxy for a track index
0168   /// @note Only available if the track container is not read-only
0169   /// @param itrack the track index in the container
0170   /// @return A mutable track proxy for the index
0171   TrackProxy at(IndexType itrack)
0172     requires(!ReadOnly)
0173   {
0174     return {*this, itrack};
0175   }
0176 
0177   /// Add a track to the container. Note this only creates the logical track and
0178   /// allocates memory. You can combine this with @c getTrack to obtain a track proxy
0179   /// @note Only available if the track container is not read-only
0180   /// @return the index to the newly added track
0181   IndexType addTrack()
0182     requires(!ReadOnly)
0183   {
0184     auto track = getTrack(m_container->addTrack_impl());
0185     track.tipIndex() = kInvalid;
0186     return track.index();
0187   }
0188 
0189   /// Add a track to the container and return a track proxy to it
0190   /// This effectively calls @c addTrack and @c getTrack
0191   /// @note Only available if the track container is not read-only
0192   /// @return a track proxy to the newly added track
0193   TrackProxy makeTrack()
0194     requires(!ReadOnly)
0195   {
0196     return getTrack(addTrack());
0197   }
0198 
0199   /// Remove a track at index @p itrack from the container
0200   /// @note Only available if the track container is not read-only
0201   /// @note This invalidates track proxies that point to tracks with larger
0202   ///       indices than @p itrack!
0203   /// @param itrack The index of the track to remove
0204   void removeTrack(IndexType itrack)
0205     requires(!ReadOnly)
0206   {
0207     m_container->removeTrack_impl(itrack);
0208   }
0209 
0210   /// Get a mutable iterator to the first track in the container
0211   /// @note Only available if the track container is not read-only
0212   /// @return a mutable iterator to the first track
0213   iterator begin()
0214     requires(!ReadOnly)
0215   {
0216     return iterator{*this, 0};
0217   }
0218 
0219   /// Get a past-the-end iterator for this container
0220   /// @note Only available if the track container is not read-only
0221   /// @return a past-the-end iterator
0222   iterator end()
0223     requires(!ReadOnly)
0224   {
0225     return iterator{*this, size()};
0226   }
0227 
0228   /// Get an const iterator to the first track in the container
0229   /// @return a const iterator to the first track
0230   const_iterator begin() const { return const_iterator{*this, 0}; }
0231 
0232   /// Get a past-the-end iterator for this container
0233   /// @return a past-the-end iterator
0234   const_iterator end() const { return const_iterator{*this, size()}; }
0235 
0236   /// @}
0237 
0238   /// @anchor track_container_columns
0239   /// @name TrackContainer column management
0240   /// TrackContainer can manage a set of common static columns, and dynamic
0241   /// columns that can be added at runtime. This set of methods allows you to
0242   /// manage the dynamic columns.
0243   /// @{
0244 
0245   /// Add a dymanic column to the track container
0246   /// @note Only available if the track container is not read-only
0247   /// @param key the name of the column to be added
0248   template <typename T>
0249   constexpr void addColumn(std::string_view key)
0250     requires(!ReadOnly)
0251   {
0252     m_container->template addColumn_impl<T>(key);
0253   }
0254 
0255   /// Check if this track container has a specific dynamic column
0256   /// @param key the key to check for
0257   /// @return true if the column exists
0258   constexpr bool hasColumn(const std::string& key) const {
0259     return m_container->hasColumn_impl(hashStringDynamic(key));
0260   }
0261 
0262   /// Check if a this track container has a specific dynamic column
0263   /// @param key the key to check for
0264   /// @return true if the column exists
0265   constexpr bool hasColumn(HashedString key) const {
0266     return m_container->hasColumn_impl(key);
0267   }
0268 
0269   /// Helper function to make this track container match the dynamic columns of
0270   /// another one. This will only work if the track container supports this
0271   /// source, and depends on the implementation details of the dynamic columns
0272   /// of the container
0273   /// @note Only available if the track container is not read-only
0274   /// @tparam other_track_container_t Type of the other track container
0275   /// @param other The other track container
0276   template <typename other_track_container_t>
0277   void ensureDynamicColumns(const other_track_container_t& other)
0278     requires(!ReadOnly)
0279   {
0280     container().ensureDynamicColumns_impl(other.container());
0281   }
0282 
0283   /// @}
0284 
0285   /// @anchor track_congtainer_backend_access
0286   /// @name TrackContainer backend access
0287   /// These methods allow accessing the backend of the track container. In most
0288   /// cases, this is not necessary for interacting with the container.
0289   /// @{
0290 
0291   /// Get a mutable reference to the track container backend
0292   /// @note Only available if the track container is not read-only
0293   /// @return a mutable reference to the backend
0294   auto& container()
0295     requires(!ReadOnly)
0296   {
0297     return *m_container;
0298   }
0299 
0300   /// Get a const reference to the track container backend
0301   /// @return a const reference to the backend
0302   const auto& container() const { return *m_container; }
0303 
0304   /// Get a mutable reference to the track state container backend
0305   /// @note Only available if the track container is not read-only
0306   /// @return a mutable reference to the backend
0307   auto& trackStateContainer()
0308     requires(!ReadOnly)
0309   {
0310     return *m_traj;
0311   }
0312 
0313   /// Retrieve the holder of the track state container
0314   /// @return The track state container including it's holder
0315   /// @note Only available if the track container is not read-only
0316   auto& trackStateContainerHolder()
0317     requires(!ReadOnly)
0318   {
0319     return m_traj;
0320   }
0321 
0322   /// Get a const reference to the track state container backend
0323   /// @return a const reference to the backend
0324   const auto& trackStateContainer() const { return *m_traj; }
0325 
0326   /// Retrieve the holder of the track state container
0327   /// @return The track state container including it's holder
0328   const auto& trackStateContainerHolder() const { return m_traj; }
0329 
0330   /// @}
0331 
0332   /// Get the size (number of tracks) of the track container
0333   /// @return the sixe
0334   constexpr IndexType size() const { return m_container->size_impl(); }
0335 
0336   /// Clear the content of the track container
0337   /// @note Only available if the track container is not read-only
0338   void clear()
0339     requires(!ReadOnly)
0340   {
0341     m_container->clear();
0342     m_traj->clear();
0343   }
0344 
0345  protected:
0346   /// @brief Get mutable reference to track component using compile-time key
0347   /// @tparam T Component type to retrieve
0348   /// @tparam key Hashed string key for the component
0349   /// @param itrack Track index to get component for
0350   /// @return Mutable reference to the component of type T
0351   template <typename T, HashedString key>
0352   constexpr T& component(IndexType itrack)
0353     requires(!ReadOnly)
0354   {
0355     return *std::any_cast<T*>(container().component_impl(key, itrack));
0356   }
0357 
0358   /// @brief Get mutable reference to track component using runtime key
0359   /// @tparam T Component type to retrieve
0360   /// @param key Hashed string key for the component
0361   /// @param itrack Track index to get component for
0362   /// @return Mutable reference to the component of type T
0363   template <typename T>
0364   constexpr T& component(HashedString key, IndexType itrack)
0365     requires(!ReadOnly)
0366   {
0367     return *std::any_cast<T*>(container().component_impl(key, itrack));
0368   }
0369 
0370   /// @brief Get const reference to track component using compile-time key
0371   /// @tparam T Component type to retrieve
0372   /// @tparam key Hashed string key for the component
0373   /// @param itrack Track index to get component for
0374   /// @return Const reference to the component of type T
0375   template <typename T, HashedString key>
0376   constexpr const T& component(IndexType itrack) const {
0377     return *std::any_cast<const T*>(container().component_impl(key, itrack));
0378   }
0379 
0380   /// @brief Get const reference to track component using runtime key
0381   /// @tparam T Component type to retrieve
0382   /// @param key Hashed string key for the component
0383   /// @param itrack Track index to get component for
0384   /// @return Const reference to the component of type T
0385   template <typename T>
0386   constexpr const T& component(HashedString key, IndexType itrack) const {
0387     return *std::any_cast<const T*>(container().component_impl(key, itrack));
0388   }
0389 
0390   /// Get mutable parameters for a track
0391   /// @param itrack Track index to get parameters for
0392   /// @return Mutable parameters object for the track
0393   constexpr typename TrackProxy::Parameters parameters(IndexType itrack)
0394     requires(!ReadOnly)
0395   {
0396     return container().parameters(itrack);
0397   }
0398 
0399   /// Get const parameters for a track
0400   /// @param itrack Track index to get parameters for
0401   /// @return Const parameters object for the track
0402   constexpr typename ConstTrackProxy::ConstParameters parameters(
0403       IndexType itrack) const {
0404     return container().parameters(itrack);
0405   }
0406 
0407   /// @brief Get mutable covariance matrix for a track
0408   /// @param itrack Track index to get covariance for
0409   /// @return Mutable covariance matrix for the track
0410   constexpr typename TrackProxy::Covariance covariance(IndexType itrack)
0411     requires(!ReadOnly)
0412   {
0413     return container().covariance(itrack);
0414   }
0415 
0416   /// @brief Get const covariance matrix for a track
0417   /// @param itrack Track index to get covariance for
0418   /// @return Const covariance matrix for the track
0419   constexpr typename ConstTrackProxy::ConstCovariance covariance(
0420       IndexType itrack) const {
0421     return container().covariance(itrack);
0422   }
0423 
0424   /// @brief Get mutable range for iterating track states in reverse order
0425   /// @param itrack Track index to get state range for
0426   /// @return Range object for reverse iteration over track states from tip to stem
0427   auto reverseTrackStateRange(IndexType itrack)
0428     requires(!ReadOnly)
0429   {
0430     auto tip = component<IndexType, hashString("tipIndex")>(itrack);
0431     return m_traj->reverseTrackStateRange(tip);
0432   }
0433 
0434   /// @brief Get const range for iterating track states in reverse order
0435   /// @param itrack Track index to get state range for
0436   /// @return Const range object for reverse iteration over track states from tip to stem
0437   auto reverseTrackStateRange(IndexType itrack) const {
0438     auto tip = component<IndexType, hashString("tipIndex")>(itrack);
0439     return m_traj->reverseTrackStateRange(tip);
0440   }
0441 
0442   /// @brief Get mutable range for iterating track states in forward order
0443   /// @param itrack Track index to get state range for
0444   /// @return Range object for forward iteration over track states from stem to tip
0445   /// @throws std::invalid_argument if track has no stem index
0446   auto forwardTrackStateRange(IndexType itrack)
0447     requires(!ReadOnly)
0448   {
0449     auto stem = component<IndexType, hashString("stemIndex")>(itrack);
0450     if (stem == kInvalid) {
0451       throw std::invalid_argument{"Track has no stem index"};
0452     }
0453     return m_traj->forwardTrackStateRange(stem);
0454   }
0455 
0456   /// @brief Get const range for iterating track states in forward order
0457   /// @param itrack Track index to get state range for
0458   /// @return Const range object for forward iteration over track states from stem to tip
0459   /// @throws std::invalid_argument if track has no stem index
0460   auto forwardTrackStateRange(IndexType itrack) const {
0461     auto stem = component<IndexType, hashString("stemIndex")>(itrack);
0462     if (stem == kInvalid) {
0463       throw std::invalid_argument{"Track has no stem index"};
0464     }
0465     return m_traj->forwardTrackStateRange(stem);
0466   }
0467 
0468  private:
0469   template <typename T>
0470   void copyDynamicFrom(IndexType dstIdx, const T& src, IndexType srcIdx)
0471     requires(!ReadOnly)
0472   {
0473     const auto& dynamicKeys = src.dynamicKeys_impl();
0474     for (const auto key : dynamicKeys) {
0475       std::any srcPtr = src.component_impl(key, srcIdx);
0476       container().copyDynamicFrom_impl(dstIdx, key, srcPtr);
0477     }
0478   }
0479 
0480   const_if_t<ReadOnly, holder_t<track_container_t>> m_container;
0481   const_if_t<ReadOnly, holder_t<traj_t>> m_traj;
0482 };
0483 
0484 /// Deduction guide for TrackContainer with lvalue references
0485 /// @param container Track container reference
0486 /// @param traj Trajectory reference
0487 template <TrackContainerBackend track_container_t, typename traj_t>
0488 TrackContainer(track_container_t& container, traj_t& traj)
0489     -> TrackContainer<track_container_t, traj_t, detail::RefHolder>;
0490 
0491 /// Deduction guide for TrackContainer with const references
0492 /// @param container Const track container reference
0493 /// @param traj Const trajectory reference
0494 template <TrackContainerBackend track_container_t, typename traj_t>
0495 TrackContainer(const track_container_t& container, const traj_t& traj)
0496     -> TrackContainer<track_container_t, traj_t, detail::ConstRefHolder>;
0497 
0498 /// Deduction guide for TrackContainer with rvalue references
0499 /// @param container Track container rvalue reference
0500 /// @param traj Trajectory rvalue reference
0501 template <TrackContainerBackend track_container_t, typename traj_t>
0502 TrackContainer(track_container_t&& container, traj_t&& traj)
0503     -> TrackContainer<track_container_t, traj_t, detail::ValueHolder>;
0504 
0505 }  // namespace Acts