Back to home page

EIC code displayed by LXR

 
 

    


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

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