Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 09:22:19

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