Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-04-01 07:45:44

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