Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2024-11-15 09:01:28

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