Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-09 08:18:11

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/Definitions/TrackParametrization.hpp"
0012 #include "Acts/EventData/MultiTrajectory.hpp"
0013 #include "Acts/EventData/MultiTrajectoryBackendConcept.hpp"
0014 #include "Acts/EventData/SourceLink.hpp"
0015 #include "Acts/EventData/TrackStatePropMask.hpp"
0016 #include "Acts/EventData/Types.hpp"
0017 #include "Acts/EventData/detail/DynamicColumn.hpp"
0018 #include "Acts/EventData/detail/DynamicKeyIterator.hpp"
0019 #include "Acts/Utilities/EigenConcepts.hpp"
0020 #include "Acts/Utilities/HashedString.hpp"
0021 #include "Acts/Utilities/Helpers.hpp"
0022 
0023 #include <any>
0024 #include <cassert>
0025 #include <cstddef>
0026 #include <iosfwd>
0027 #include <memory>
0028 #include <optional>
0029 #include <stdexcept>
0030 #include <string>
0031 #include <string_view>
0032 #include <type_traits>
0033 #include <unordered_map>
0034 #include <utility>
0035 #include <vector>
0036 
0037 #include <boost/histogram.hpp>
0038 
0039 namespace Acts {
0040 class Surface;
0041 template <typename T>
0042 struct IsReadOnlyMultiTrajectory;
0043 
0044 namespace detail_vmt {
0045 
0046 using IndexType = TrackIndexType;
0047 
0048 constexpr auto kInvalid = kTrackIndexInvalid;
0049 constexpr auto MeasurementSizeMax = kMeasurementSizeMax;
0050 
0051 template <typename T>
0052 struct NonInitializingAllocator {
0053   using value_type = T;
0054 
0055   NonInitializingAllocator() noexcept = default;
0056 
0057   template <class U>
0058   explicit NonInitializingAllocator(
0059       const NonInitializingAllocator<U>& /*other*/) noexcept {}
0060 
0061   template <class U>
0062   bool operator==(const NonInitializingAllocator<U>& /*other*/) const noexcept {
0063     return true;
0064   }
0065 
0066   T* allocate(std::size_t n) const { return std::allocator<T>{}.allocate(n); }
0067 
0068   void deallocate(T* const p, std::size_t n) const noexcept {
0069     std::allocator<T>{}.deallocate(p, n);
0070   }
0071 
0072   void construct(T* /*p*/) const {
0073     // This construct function intentionally does not initialize the object!
0074     // Be very careful when using this allocator.
0075   }
0076 };
0077 
0078 class VectorMultiTrajectoryBase {
0079  public:
0080   struct Statistics {
0081     using axis_t = boost::histogram::axis::variant<
0082         boost::histogram::axis::category<std::string>,
0083         boost::histogram::axis::category<>>;
0084 
0085     using axes_t = std::vector<axis_t>;
0086     using hist_t = boost::histogram::histogram<axes_t>;
0087 
0088     hist_t hist;
0089 
0090     void toStream(std::ostream& os, std::size_t n = 1);
0091 
0092     // This is necessary to make the move constructor and assignment operator
0093     // noexcept
0094     Statistics() noexcept = default;
0095     explicit Statistics(const hist_t& h) noexcept : hist(h) {}
0096     explicit Statistics(hist_t&& h) noexcept : hist(std::move(h)) {}
0097     Statistics(const Statistics& other) = default;
0098     Statistics(Statistics&& other) noexcept = default;
0099     Statistics& operator=(const Statistics& other) = default;
0100     Statistics& operator=(Statistics&& other) noexcept = default;
0101   };
0102 
0103   template <typename T>
0104   Statistics statistics(T& instance) const {
0105     using namespace boost::histogram;
0106     using cat = axis::category<std::string>;
0107 
0108     Statistics::axes_t axes;
0109     axes.emplace_back(cat({
0110         "count",
0111         "index",
0112         "parPred",
0113         "covPred",
0114         "parFilt",
0115         "covFilt",
0116         "parSmth",
0117         "covSmth",
0118         "meas",
0119         "measOffset",
0120         "measCov",
0121         "measCovOffset",
0122         "jac",
0123         "sourceLinks",
0124         "projectors",
0125     }));
0126 
0127     axes.emplace_back(axis::category<>({0, 1}));
0128 
0129     auto h = make_histogram(axes);
0130 
0131     for (IndexType i = 0; i < instance.size(); i++) {
0132       auto ts = instance.getTrackState(i);
0133 
0134       bool isMeas = ts.typeFlags().hasMeasurement();
0135 
0136       h("count", isMeas);
0137 
0138       h("index", isMeas, weight(sizeof(IndexData)));
0139 
0140       using scalar = typename decltype(ts.predicted())::Scalar;
0141       std::size_t par_size = eBoundSize * sizeof(scalar);
0142       std::size_t cov_size = eBoundSize * eBoundSize * sizeof(scalar);
0143 
0144       const IndexData& index = m_index[i];
0145       if (ts.hasPredicted() &&
0146           ACTS_CHECK_BIT(index.allocMask, TrackStatePropMask::Predicted)) {
0147         h("parPred", isMeas, weight(par_size));
0148         h("covPred", isMeas, weight(cov_size));
0149       }
0150       if (ts.hasFiltered() &&
0151           ACTS_CHECK_BIT(index.allocMask, TrackStatePropMask::Filtered)) {
0152         h("parFilt", isMeas, weight(par_size));
0153         h("covFilt", isMeas, weight(cov_size));
0154       }
0155       if (ts.hasSmoothed() &&
0156           ACTS_CHECK_BIT(index.allocMask, TrackStatePropMask::Smoothed)) {
0157         h("parSmth", isMeas, weight(par_size));
0158         h("covSmth", isMeas, weight(cov_size));
0159       }
0160       h("sourceLinks", isMeas, weight(sizeof(SourceLink)));
0161       h("measOffset", isMeas,
0162         weight(sizeof(decltype(m_measOffset)::value_type)));
0163       h("measCovOffset", isMeas,
0164         weight(sizeof(decltype(m_measCovOffset)::value_type)));
0165       if (ts.hasCalibrated() &&
0166           ACTS_CHECK_BIT(index.allocMask, TrackStatePropMask::Calibrated)) {
0167         std::size_t meas_size = ts.calibratedSize() * sizeof(scalar);
0168         std::size_t meas_cov_size =
0169             ts.calibratedSize() * ts.calibratedSize() * sizeof(scalar);
0170 
0171         h("meas", isMeas, weight(meas_size));
0172         h("measCov", isMeas, weight(meas_cov_size));
0173         h("sourceLinks", isMeas, weight(sizeof(const SourceLink)));
0174         h("projectors", isMeas, weight(sizeof(SerializedSubspaceIndices)));
0175       }
0176 
0177       if (ts.hasJacobian() &&
0178           ACTS_CHECK_BIT(index.allocMask, TrackStatePropMask::Jacobian)) {
0179         h("jac", isMeas, weight(cov_size));
0180       }
0181     }
0182 
0183     return Statistics(std::move(h));
0184   }
0185 
0186  protected:
0187   struct IndexData {
0188     IndexType ipredicted = kInvalid;
0189     IndexType ifiltered = kInvalid;
0190     IndexType ismoothed = kInvalid;
0191     IndexType ijacobian = kInvalid;
0192     IndexType iprojector = kInvalid;
0193 
0194     float chi2 = 0;
0195     double pathLength = 0;
0196     TrackStateType::raw_type typeFlags{};
0197 
0198     IndexType iUncalibrated = kInvalid;
0199     IndexType iCalibratedSourceLink = kInvalid;
0200     IndexType measdim = kInvalid;
0201 
0202     TrackStatePropMask allocMask = TrackStatePropMask::None;
0203   };
0204 
0205   VectorMultiTrajectoryBase() noexcept = default;
0206 
0207   VectorMultiTrajectoryBase(const VectorMultiTrajectoryBase& other)
0208       : m_index{other.m_index},
0209         m_previous{other.m_previous},
0210         m_next{other.m_next},
0211         m_params{other.m_params},
0212         m_cov{other.m_cov},
0213         m_meas{other.m_meas},
0214         m_measOffset{other.m_measOffset},
0215         m_measCov{other.m_measCov},
0216         m_measCovOffset{other.m_measCovOffset},
0217         m_jac{other.m_jac},
0218         m_sourceLinks{other.m_sourceLinks},
0219         m_projectors{other.m_projectors},
0220         m_referenceSurfaces{other.m_referenceSurfaces} {
0221     for (const auto& [key, value] : other.m_dynamic) {
0222       m_dynamic.insert({key, value->clone()});
0223     }
0224     m_dynamicKeys = other.m_dynamicKeys;
0225   };
0226 
0227   VectorMultiTrajectoryBase(VectorMultiTrajectoryBase&& other) = default;
0228 
0229   // BEGIN INTERFACE HELPER
0230   template <typename T>
0231   static constexpr bool has_impl(T& instance, HashedString key,
0232                                  IndexType istate) {
0233     using namespace Acts::HashedStringLiteral;
0234     switch (key) {
0235       case "predicted"_hash:
0236         return instance.m_index[istate].ipredicted != kInvalid;
0237       case "filtered"_hash:
0238         return instance.m_index[istate].ifiltered != kInvalid;
0239       case "smoothed"_hash:
0240         return instance.m_index[istate].ismoothed != kInvalid;
0241       case "calibrated"_hash:
0242         return instance.m_measOffset[istate] != kInvalid;
0243       case "calibratedCov"_hash:
0244         return instance.m_measCovOffset[istate] != kInvalid;
0245       case "jacobian"_hash:
0246         return instance.m_index[istate].ijacobian != kInvalid;
0247       case "projector"_hash:
0248         return instance.m_index[istate].iprojector != kInvalid;
0249       case "uncalibratedSourceLink"_hash:
0250         return instance.m_sourceLinks[instance.m_index[istate].iUncalibrated]
0251             .has_value();
0252       case "previous"_hash:
0253       case "next"_hash:
0254       case "referenceSurface"_hash:
0255       case "measdim"_hash:
0256       case "chi2"_hash:
0257       case "pathLength"_hash:
0258       case "typeFlags"_hash:
0259         return true;
0260       default:
0261         return instance.m_dynamic.contains(key);
0262     }
0263   }
0264 
0265   template <bool EnsureConst, typename T>
0266   static std::any component_impl(T& instance, HashedString key,
0267                                  IndexType istate) {
0268     if constexpr (EnsureConst) {
0269       static_assert(std::is_const_v<std::remove_reference_t<T>>,
0270                     "Is not const");
0271     }
0272     using namespace Acts::HashedStringLiteral;
0273     switch (key) {
0274       case "previous"_hash:
0275         return &instance.m_previous[istate];
0276       case "next"_hash:
0277         return &instance.m_next[istate];
0278       case "predicted"_hash:
0279         return &instance.m_index[istate].ipredicted;
0280       case "filtered"_hash:
0281         return &instance.m_index[istate].ifiltered;
0282       case "smoothed"_hash:
0283         return &instance.m_index[istate].ismoothed;
0284       case "projector"_hash:
0285         return &instance.m_projectors[instance.m_index[istate].iprojector];
0286       case "measdim"_hash:
0287         return &instance.m_index[istate].measdim;
0288       case "chi2"_hash:
0289         return &instance.m_index[istate].chi2;
0290       case "pathLength"_hash:
0291         return &instance.m_index[istate].pathLength;
0292       case "typeFlags"_hash:
0293         return &instance.m_index[istate].typeFlags;
0294       default:
0295         auto it = instance.m_dynamic.find(key);
0296         if (it == instance.m_dynamic.end()) {
0297           throw std::runtime_error("Unable to handle this component");
0298         }
0299         std::conditional_t<EnsureConst, const detail::DynamicColumnBase*,
0300                            detail::DynamicColumnBase*>
0301             col = it->second.get();
0302         assert(col && "Dynamic column is null");
0303         return col->get(istate);
0304     }
0305   }
0306 
0307   template <typename T>
0308   static bool hasColumn_impl(T& instance, HashedString key) {
0309     using namespace Acts::HashedStringLiteral;
0310     switch (key) {
0311       case "predicted"_hash:
0312       case "filtered"_hash:
0313       case "smoothed"_hash:
0314       case "calibrated"_hash:
0315       case "calibratedCov"_hash:
0316       case "jacobian"_hash:
0317       case "projector"_hash:
0318       case "previous"_hash:
0319       case "next"_hash:
0320       case "uncalibratedSourceLink"_hash:
0321       case "referenceSurface"_hash:
0322       case "measdim"_hash:
0323       case "chi2"_hash:
0324       case "pathLength"_hash:
0325       case "typeFlags"_hash:
0326         return true;
0327       default:
0328         return instance.m_dynamic.contains(key);
0329     }
0330   }
0331 
0332  public:
0333   detail::DynamicKeyRange<detail::DynamicColumnBase> dynamicKeys_impl() const {
0334     return {m_dynamic.begin(), m_dynamic.end()};
0335   }
0336 
0337   // END INTERFACE HELPER
0338 
0339   IndexType calibratedSize_impl(IndexType istate) const {
0340     return m_index[istate].measdim;
0341   }
0342 
0343   SourceLink getUncalibratedSourceLink_impl(IndexType istate) const {
0344     return m_sourceLinks[m_index[istate].iUncalibrated].value();
0345   }
0346 
0347   const Surface* referenceSurface_impl(IndexType istate) const {
0348     return m_referenceSurfaces[istate].get();
0349   }
0350 
0351  protected:
0352   /// index to map track states to the corresponding
0353   std::vector<IndexData> m_index;
0354   std::vector<IndexType> m_previous;
0355   std::vector<IndexType> m_next;
0356   std::vector<typename detail_tsp::FixedSizeTypes<eBoundSize>::Coefficients>
0357       m_params;
0358   std::vector<typename detail_tsp::FixedSizeTypes<eBoundSize>::Covariance>
0359       m_cov;
0360 
0361   std::vector<double, NonInitializingAllocator<double>> m_meas;
0362   std::vector<IndexType> m_measOffset;
0363   std::vector<double, NonInitializingAllocator<double>> m_measCov;
0364   std::vector<IndexType> m_measCovOffset;
0365 
0366   std::vector<typename detail_tsp::FixedSizeTypes<eBoundSize>::Covariance>
0367       m_jac;
0368   std::vector<std::optional<SourceLink>> m_sourceLinks;
0369   std::vector<SerializedSubspaceIndices> m_projectors;
0370 
0371   // owning vector of shared pointers to surfaces
0372   //
0373   // This might be problematic when appending a large number of surfaces
0374   // trackstates, because vector has to reallocated and thus copy. This might
0375   // be handled in a smart way by moving but not sure.
0376   std::vector<std::shared_ptr<const Surface>> m_referenceSurfaces;
0377 
0378   std::vector<HashedString> m_dynamicKeys;
0379   std::unordered_map<HashedString, std::unique_ptr<detail::DynamicColumnBase>>
0380       m_dynamic;
0381 };
0382 
0383 }  // namespace detail_vmt
0384 
0385 class VectorMultiTrajectory;
0386 
0387 template <>
0388 struct IsReadOnlyMultiTrajectory<VectorMultiTrajectory> : std::false_type {};
0389 
0390 /// In-memory transient multi-trajectory implementation using @c std::vector as
0391 /// backend
0392 /// @ingroup eventdata_tracks
0393 class VectorMultiTrajectory final
0394     : public detail_vmt::VectorMultiTrajectoryBase,
0395       public MultiTrajectory<VectorMultiTrajectory> {
0396   friend class MultiTrajectory<VectorMultiTrajectory>;
0397 
0398  public:
0399   VectorMultiTrajectory() = default;
0400   using VectorMultiTrajectoryBase::VectorMultiTrajectoryBase;
0401 
0402   /// Get statistics about memory usage
0403   /// @return Statistics object
0404   Statistics statistics() const {
0405     return detail_vmt::VectorMultiTrajectoryBase::statistics(*this);
0406   }
0407 
0408   // BEGIN INTERFACE
0409   /// @cond
0410   TrackStateProxy::Parameters parameters_impl(IndexType parIdx) {
0411     return TrackStateProxy::Parameters{m_params[parIdx].data()};
0412   }
0413 
0414   ConstTrackStateProxy::ConstParameters parameters_impl(
0415       IndexType parIdx) const {
0416     return ConstTrackStateProxy::ConstParameters{m_params[parIdx].data()};
0417   }
0418 
0419   TrackStateProxy::Covariance covariance_impl(IndexType parIdx) {
0420     return TrackStateProxy::Covariance{m_cov[parIdx].data()};
0421   }
0422 
0423   ConstTrackStateProxy::ConstCovariance covariance_impl(
0424       IndexType parIdx) const {
0425     return ConstTrackStateProxy::ConstCovariance{m_cov[parIdx].data()};
0426   }
0427 
0428   TrackStateProxy::Covariance jacobian_impl(IndexType istate) {
0429     IndexType jacIdx = m_index[istate].ijacobian;
0430     return TrackStateProxy::Covariance{m_jac[jacIdx].data()};
0431   }
0432 
0433   ConstTrackStateProxy::ConstCovariance jacobian_impl(IndexType istate) const {
0434     IndexType jacIdx = m_index[istate].ijacobian;
0435     return ConstTrackStateProxy::ConstCovariance{m_jac[jacIdx].data()};
0436   }
0437 
0438   template <std::size_t measdim>
0439   TrackStateProxy::Calibrated<measdim> calibrated_impl(IndexType istate) {
0440     IndexType offset = m_measOffset[istate];
0441     return TrackStateProxy::Calibrated<measdim>{&m_meas[offset]};
0442   }
0443 
0444   template <std::size_t measdim>
0445   ConstTrackStateProxy::ConstCalibrated<measdim> calibrated_impl(
0446       IndexType istate) const {
0447     IndexType offset = m_measOffset[istate];
0448     return ConstTrackStateProxy::ConstCalibrated<measdim>{&m_meas[offset]};
0449   }
0450 
0451   template <std::size_t measdim>
0452   TrackStateProxy::CalibratedCovariance<measdim> calibratedCovariance_impl(
0453       IndexType istate) {
0454     IndexType offset = m_measCovOffset[istate];
0455     return TrackStateProxy::CalibratedCovariance<measdim>{&m_measCov[offset]};
0456   }
0457 
0458   template <std::size_t measdim>
0459   ConstTrackStateProxy::ConstCalibratedCovariance<measdim>
0460   calibratedCovariance_impl(IndexType istate) const {
0461     IndexType offset = m_measCovOffset[istate];
0462     return ConstTrackStateProxy::ConstCalibratedCovariance<measdim>{
0463         &m_measCov[offset]};
0464   }
0465 
0466   IndexType addTrackState_impl(
0467       TrackStatePropMask mask = TrackStatePropMask::All,
0468       IndexType iprevious = kInvalid);
0469 
0470   void addTrackStateComponents_impl(IndexType istate, TrackStatePropMask mask);
0471 
0472   void shareFrom_impl(IndexType iself, IndexType iother,
0473                       TrackStatePropMask shareSource,
0474                       TrackStatePropMask shareTarget);
0475 
0476   void unset_impl(TrackStatePropMask target, IndexType istate);
0477 
0478   bool has_impl(HashedString key, IndexType istate) const {
0479     return detail_vmt::VectorMultiTrajectoryBase::has_impl(*this, key, istate);
0480   }
0481 
0482   IndexType size_impl() const { return static_cast<IndexType>(m_index.size()); }
0483 
0484   void clear_impl();
0485 
0486   std::any component_impl(HashedString key, IndexType istate) {
0487     return detail_vmt::VectorMultiTrajectoryBase::component_impl<false>(
0488         *this, key, istate);
0489   }
0490 
0491   std::any component_impl(HashedString key, IndexType istate) const {
0492     return detail_vmt::VectorMultiTrajectoryBase::component_impl<true>(
0493         *this, key, istate);
0494   }
0495 
0496   template <typename T>
0497   void addColumn_impl(std::string_view key) {
0498     HashedString hashedKey = hashStringDynamic(key);
0499     auto insertItr = m_dynamic.insert(
0500         {hashedKey, std::make_unique<detail::DynamicColumn<T>>()});
0501     if (insertItr.second && size() > 0ul) {
0502       insertItr.first->second->resize(size());
0503     }
0504   }
0505 
0506   bool hasColumn_impl(HashedString key) const {
0507     return detail_vmt::VectorMultiTrajectoryBase::hasColumn_impl(*this, key);
0508   }
0509 
0510   template <typename val_t, typename cov_t>
0511   void allocateCalibrated_impl(IndexType istate,
0512                                const Eigen::DenseBase<val_t>& val,
0513                                const Eigen::DenseBase<cov_t>& cov)
0514     requires(Concepts::eigen_base_is_fixed_size<val_t> &&
0515              Concepts::eigen_bases_have_same_num_rows<val_t, cov_t> &&
0516              Concepts::eigen_base_is_square<cov_t> &&
0517              Eigen::PlainObjectBase<val_t>::RowsAtCompileTime <=
0518                  toUnderlying(eBoundSize))
0519   {
0520     constexpr std::size_t measdim = val_t::RowsAtCompileTime;
0521 
0522     if (m_index[istate].measdim != kInvalid &&
0523         m_index[istate].measdim != measdim) {
0524       throw std::invalid_argument{
0525           "Measurement dimension does not match the allocated dimension"};
0526     }
0527 
0528     if (m_measOffset[istate] == kInvalid ||
0529         m_measCovOffset[istate] == kInvalid) {
0530       m_measOffset[istate] = static_cast<IndexType>(m_meas.size());
0531       m_meas.resize(m_meas.size() + measdim);
0532 
0533       m_measCovOffset[istate] = static_cast<IndexType>(m_measCov.size());
0534       m_measCov.resize(m_measCov.size() + measdim * measdim);
0535     }
0536 
0537     m_index[istate].measdim = measdim;
0538 
0539     double* measPtr = &m_meas[m_measOffset[istate]];
0540     Eigen::Map<Vector<measdim>> valMap(measPtr);
0541     valMap = val;
0542 
0543     double* covPtr = &m_measCov[m_measCovOffset[istate]];
0544     Eigen::Map<SquareMatrix<measdim>> covMap(covPtr);
0545     covMap = cov;
0546   }
0547 
0548   void setUncalibratedSourceLink_impl(IndexType istate,
0549                                       SourceLink&& sourceLink) {
0550     m_sourceLinks[m_index[istate].iUncalibrated] = std::move(sourceLink);
0551   }
0552 
0553   void setReferenceSurface_impl(IndexType istate,
0554                                 std::shared_ptr<const Surface> surface) {
0555     m_referenceSurfaces[istate] = std::move(surface);
0556   }
0557 
0558   void copyDynamicFrom_impl(IndexType dstIdx, HashedString key,
0559                             const std::any& srcPtr);
0560   /// @endcond
0561 
0562   // END INTERFACE
0563 
0564   /// Reserve space for track states
0565   /// @param n Number of track states to reserve space for
0566   void reserve(std::size_t n);
0567 };
0568 
0569 static_assert(
0570     MutableMultiTrajectoryBackend<VectorMultiTrajectory>,
0571     "VectorMultiTrajectory does not fulfill MutableMultiTrajectoryBackend");
0572 
0573 class ConstVectorMultiTrajectory;
0574 
0575 template <>
0576 struct IsReadOnlyMultiTrajectory<ConstVectorMultiTrajectory> : std::true_type {
0577 };
0578 
0579 /// Const version of @ref VectorMultiTrajectory
0580 /// @ingroup eventdata_tracks
0581 class ConstVectorMultiTrajectory final
0582     : public detail_vmt::VectorMultiTrajectoryBase,
0583       public MultiTrajectory<ConstVectorMultiTrajectory> {
0584 #ifndef DOXYGEN
0585   friend MultiTrajectory<ConstVectorMultiTrajectory>;
0586 #endif
0587 
0588  public:
0589   ConstVectorMultiTrajectory() = default;
0590 
0591   using VectorMultiTrajectoryBase::VectorMultiTrajectoryBase;
0592 
0593   /// Constructor from VectorMultiTrajectory
0594   /// @param other VectorMultiTrajectory to construct from
0595   explicit ConstVectorMultiTrajectory(const VectorMultiTrajectory& other)
0596       : VectorMultiTrajectoryBase{other} {}
0597 
0598   /// Move constructor from VectorMultiTrajectory
0599   /// @param other VectorMultiTrajectory to move from
0600   explicit ConstVectorMultiTrajectory(VectorMultiTrajectory&& other)
0601       : VectorMultiTrajectoryBase{std::move(other)} {}
0602 
0603   /// Get statistics about this multi trajectory
0604   /// @return Statistics object
0605   Statistics statistics() const {
0606     return detail_vmt::VectorMultiTrajectoryBase::statistics(*this);
0607   }
0608 
0609   // BEGIN INTERFACE
0610 
0611   /// Get parameters for a track state
0612   /// @param parIdx The parameter index
0613   /// @return Parameters vector
0614   ConstTrackStateProxy::ConstParameters parameters_impl(
0615       IndexType parIdx) const {
0616     return ConstTrackStateProxy::ConstParameters{m_params[parIdx].data()};
0617   }
0618 
0619   /// Get covariance for a track state
0620   /// @param parIdx The parameter index
0621   /// @return Covariance matrix
0622   ConstTrackStateProxy::ConstCovariance covariance_impl(
0623       IndexType parIdx) const {
0624     return ConstTrackStateProxy::ConstCovariance{m_cov[parIdx].data()};
0625   }
0626 
0627   /// Get jacobian for a track state
0628   /// @param istate The track state index
0629   /// @return Jacobian matrix
0630   ConstTrackStateProxy::ConstCovariance jacobian_impl(IndexType istate) const {
0631     IndexType jacIdx = m_index[istate].ijacobian;
0632     return ConstTrackStateProxy::ConstCovariance{m_jac[jacIdx].data()};
0633   }
0634 
0635   /// Get calibrated measurement for a track state
0636   /// @param istate Index of the track state
0637   /// @return Calibrated measurement
0638   template <std::size_t measdim>
0639   ConstTrackStateProxy::ConstCalibrated<measdim> calibrated_impl(
0640       IndexType istate) const {
0641     IndexType offset = m_measOffset[istate];
0642     return ConstTrackStateProxy::ConstCalibrated<measdim>{&m_meas[offset]};
0643   }
0644 
0645   /// Get calibrated measurement covariance for a track state
0646   /// @param istate Index of the track state
0647   /// @return Calibrated measurement covariance
0648   template <std::size_t measdim>
0649   ConstTrackStateProxy::ConstCalibratedCovariance<measdim>
0650   calibratedCovariance_impl(IndexType istate) const {
0651     IndexType offset = m_measCovOffset[istate];
0652     return ConstTrackStateProxy::ConstCalibratedCovariance<measdim>{
0653         &m_measCov[offset]};
0654   }
0655 
0656   /// Check if a track state has a component
0657   /// @param key The component key
0658   /// @param istate The track state index
0659   /// @return True if the component exists
0660   bool has_impl(HashedString key, IndexType istate) const {
0661     return detail_vmt::VectorMultiTrajectoryBase::has_impl(*this, key, istate);
0662   }
0663 
0664   /// Get the number of track states
0665   /// @return Number of track states
0666   IndexType size_impl() const { return static_cast<IndexType>(m_index.size()); }
0667 
0668   /// Get a component from a track state
0669   /// @param key The component key
0670   /// @param istate The track state index
0671   /// @return The component value
0672   std::any component_impl(HashedString key, IndexType istate) const {
0673     return detail_vmt::VectorMultiTrajectoryBase::component_impl<true>(
0674         *this, key, istate);
0675   }
0676 
0677   /// Check if a column exists
0678   /// @param key The column key
0679   /// @return True if the column exists
0680   bool hasColumn_impl(HashedString key) const {
0681     return detail_vmt::VectorMultiTrajectoryBase::hasColumn_impl(*this, key);
0682   }
0683 
0684   // END INTERFACE
0685 };
0686 
0687 static_assert(
0688     ConstMultiTrajectoryBackend<ConstVectorMultiTrajectory>,
0689     "ConctVectorMultiTrajectory does not fulfill ConstMultiTrajectoryBackend");
0690 
0691 }  // namespace Acts