Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:10:49

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