File indexing completed on 2025-01-18 09:10:50
0001
0002
0003
0004
0005
0006
0007
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>& ) noexcept {}
0060
0061 template <class U>
0062 bool operator==(const NonInitializingAllocator<U>& ) 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* ) const {
0073
0074
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
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
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
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
0361
0362
0363
0364
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 }
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
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
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
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
0630 };
0631
0632 static_assert(
0633 ConstMultiTrajectoryBackend<ConstVectorMultiTrajectory>,
0634 "ConctVectorMultiTrajectory does not fulfill ConstMultiTrajectoryBackend");
0635
0636 }