Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-06 08:07:10

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