File indexing completed on 2025-01-18 09:10:48
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/Definitions/TrackParametrization.hpp"
0013 #include "Acts/EventData/MeasurementHelpers.hpp"
0014 #include "Acts/EventData/SourceLink.hpp"
0015 #include "Acts/EventData/TrackStatePropMask.hpp"
0016 #include "Acts/EventData/TrackStateProxy.hpp"
0017 #include "Acts/EventData/TrackStateProxyConcept.hpp"
0018 #include "Acts/EventData/TrackStateType.hpp"
0019 #include "Acts/EventData/Types.hpp"
0020 #include "Acts/Geometry/GeometryContext.hpp"
0021 #include "Acts/Utilities/AlgebraHelpers.hpp"
0022 #include "Acts/Utilities/HashedString.hpp"
0023 #include "Acts/Utilities/Helpers.hpp"
0024 #include "Acts/Utilities/ThrowAssert.hpp"
0025
0026 #include <bitset>
0027 #include <cstddef>
0028 #include <cstdint>
0029 #include <iterator>
0030 #include <memory>
0031 #include <optional>
0032 #include <string_view>
0033 #include <type_traits>
0034 #include <vector>
0035
0036 #include <Eigen/Core>
0037
0038 namespace Acts {
0039
0040
0041 template <typename derived_t>
0042 class MultiTrajectory;
0043 class Surface;
0044
0045 namespace detail_lt {
0046
0047
0048 template <bool reverse, typename trajectory_t, std::size_t M, bool ReadOnly>
0049 class TrackStateRange {
0050 using ProxyType = TrackStateProxy<trajectory_t, M, ReadOnly>;
0051 using IndexType = typename ProxyType::IndexType;
0052 static constexpr IndexType kInvalid = ProxyType::kInvalid;
0053
0054 public:
0055
0056
0057 struct Iterator {
0058 std::optional<ProxyType> proxy;
0059
0060 using iterator_category = std::forward_iterator_tag;
0061 using value_type = ProxyType;
0062 using difference_type = std::ptrdiff_t;
0063 using pointer = void;
0064 using reference = void;
0065
0066 Iterator& operator++() {
0067 if (!proxy) {
0068 return *this;
0069 }
0070 if constexpr (reverse) {
0071 if (proxy->hasPrevious()) {
0072 proxy = proxy->trajectory().getTrackState(proxy->previous());
0073 return *this;
0074 } else {
0075 proxy = std::nullopt;
0076 return *this;
0077 }
0078 } else {
0079 IndexType next =
0080 proxy->template component<IndexType, hashString("next")>();
0081 if (next != kInvalid) {
0082 proxy = proxy->trajectory().getTrackState(next);
0083 return *this;
0084 } else {
0085 proxy = std::nullopt;
0086 return *this;
0087 }
0088 }
0089 }
0090
0091 Iterator operator++(int) {
0092 Iterator tmp(*this);
0093 operator++();
0094 return tmp;
0095 }
0096
0097 bool operator==(const Iterator& other) const {
0098 if (!proxy && !other.proxy) {
0099 return true;
0100 }
0101 if (proxy && other.proxy) {
0102 return proxy->index() == other.proxy->index();
0103 }
0104 return false;
0105 }
0106
0107 ProxyType operator*() const { return *proxy; }
0108 ProxyType operator*() { return *proxy; }
0109 };
0110
0111 TrackStateRange(ProxyType _begin) : m_begin{_begin} {}
0112 TrackStateRange() : m_begin{std::nullopt} {}
0113
0114 Iterator begin() { return m_begin; }
0115 Iterator end() { return Iterator{std::nullopt}; }
0116
0117 Iterator cbegin() const { return m_begin; }
0118 Iterator cend() const { return Iterator{std::nullopt}; }
0119
0120 private:
0121 Iterator m_begin;
0122 };
0123
0124
0125 template <typename T, typename TS>
0126 concept VisitorConcept = requires(T& t, TS& ts) {
0127 { t(ts) } -> Concepts::same_as_any_of<void, bool>;
0128 };
0129
0130 }
0131
0132
0133
0134
0135 namespace MultiTrajectoryTraits {
0136 constexpr unsigned int MeasurementSizeMax = eBoundSize;
0137 using IndexType = TrackIndexType;
0138 constexpr IndexType kInvalid = kTrackIndexInvalid;
0139 }
0140
0141 template <typename T>
0142 struct IsReadOnlyMultiTrajectory;
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152 template <typename derived_t>
0153 class MultiTrajectory {
0154 public:
0155 using Derived = derived_t;
0156
0157 static constexpr bool ReadOnly = IsReadOnlyMultiTrajectory<Derived>::value;
0158
0159
0160 static constexpr unsigned int MeasurementSizeMax =
0161 MultiTrajectoryTraits::MeasurementSizeMax;
0162
0163 friend class TrackStateProxy<Derived, MeasurementSizeMax, true>;
0164 friend class TrackStateProxy<Derived, MeasurementSizeMax, false>;
0165 template <typename T>
0166 friend class MultiTrajectory;
0167
0168
0169
0170 using ConstTrackStateProxy =
0171 Acts::TrackStateProxy<Derived, MeasurementSizeMax, true>;
0172
0173
0174
0175 using TrackStateProxy =
0176 Acts::TrackStateProxy<Derived, MeasurementSizeMax, false>;
0177
0178
0179 using IndexType = typename TrackStateProxy::IndexType;
0180
0181
0182 static constexpr IndexType kInvalid = TrackStateProxy::kInvalid;
0183
0184 protected:
0185 MultiTrajectory() = default;
0186
0187 private:
0188
0189 constexpr Derived& self() { return static_cast<Derived&>(*this); }
0190
0191 constexpr const Derived& self() const {
0192 return static_cast<const Derived&>(*this);
0193 }
0194
0195
0196
0197 bool checkOptional(HashedString key, IndexType istate) const {
0198 using namespace Acts::HashedStringLiteral;
0199 switch (key) {
0200 case "predicted"_hash:
0201 case "filtered"_hash:
0202 case "smoothed"_hash:
0203 case "calibrated"_hash:
0204 case "jacobian"_hash:
0205 case "projector"_hash:
0206 return self().has_impl(key, istate);
0207 default:
0208 return true;
0209 }
0210 }
0211
0212 public:
0213
0214
0215
0216
0217
0218
0219
0220
0221
0222
0223
0224
0225 ConstTrackStateProxy getTrackState(IndexType istate) const {
0226 return {*this, istate};
0227 }
0228
0229
0230
0231
0232
0233 TrackStateProxy getTrackState(IndexType istate)
0234 requires(!ReadOnly)
0235 {
0236 return {*this, istate};
0237 }
0238
0239
0240
0241
0242
0243
0244
0245
0246 IndexType addTrackState(TrackStatePropMask mask = TrackStatePropMask::All,
0247 IndexType iprevious = kInvalid)
0248 requires(!ReadOnly)
0249 {
0250 return self().addTrackState_impl(mask, iprevious);
0251 }
0252
0253
0254
0255
0256
0257 TrackStateProxy makeTrackState(
0258 TrackStatePropMask mask = TrackStatePropMask::All,
0259 IndexType iprevious = kInvalid)
0260 requires(!ReadOnly)
0261 {
0262 return getTrackState(addTrackState(mask, iprevious));
0263 }
0264
0265
0266
0267
0268
0269
0270
0271
0272
0273
0274
0275 template <typename F>
0276 void visitBackwards(IndexType iendpoint, F&& callable) const
0277 requires detail_lt::VisitorConcept<F, ConstTrackStateProxy>;
0278
0279
0280
0281
0282
0283
0284
0285
0286
0287 template <typename F>
0288 void applyBackwards(IndexType iendpoint, F&& callable)
0289 requires(!ReadOnly) && detail_lt::VisitorConcept<F, TrackStateProxy>
0290 {
0291 if (iendpoint == MultiTrajectoryTraits::kInvalid) {
0292 throw std::runtime_error(
0293 "Cannot apply backwards with kInvalid as endpoint");
0294 }
0295
0296 while (true) {
0297 auto ts = getTrackState(iendpoint);
0298 if constexpr (std::is_same_v<std::invoke_result_t<F, TrackStateProxy>,
0299 bool>) {
0300 bool proceed = callable(ts);
0301
0302
0303 if (!proceed || !ts.hasPrevious()) {
0304 break;
0305 }
0306 } else {
0307 callable(ts);
0308
0309 if (!ts.hasPrevious()) {
0310 break;
0311 }
0312 }
0313 iendpoint = ts.previous();
0314 }
0315 }
0316
0317
0318
0319
0320
0321 auto reverseTrackStateRange(IndexType iendpoint) const {
0322 using range_t =
0323 detail_lt::TrackStateRange<true, Derived, MeasurementSizeMax, true>;
0324 if (iendpoint == kInvalid) {
0325 return range_t{};
0326 }
0327
0328 return range_t{getTrackState(iendpoint)};
0329 }
0330
0331
0332
0333
0334
0335
0336
0337 auto reverseTrackStateRange(IndexType iendpoint)
0338 requires(!ReadOnly)
0339 {
0340 using range_t =
0341 detail_lt::TrackStateRange<true, Derived, MeasurementSizeMax, false>;
0342 if (iendpoint == kInvalid) {
0343 return range_t{};
0344 }
0345
0346 return range_t{getTrackState(iendpoint)};
0347 }
0348
0349
0350
0351
0352
0353
0354
0355 auto forwardTrackStateRange(IndexType istartpoint) const {
0356 using range_t =
0357 detail_lt::TrackStateRange<false, Derived, MeasurementSizeMax, true>;
0358 if (istartpoint == kInvalid) {
0359 return range_t{};
0360 }
0361
0362 return range_t{getTrackState(istartpoint)};
0363 }
0364
0365
0366
0367
0368
0369
0370
0371 auto forwardTrackStateRange(IndexType istartpoint)
0372 requires(!ReadOnly)
0373 {
0374 using range_t =
0375 detail_lt::TrackStateRange<false, Derived, MeasurementSizeMax, false>;
0376 if (istartpoint == kInvalid) {
0377 return range_t{};
0378 }
0379
0380 return range_t{getTrackState(istartpoint)};
0381 }
0382
0383
0384
0385
0386
0387
0388
0389
0390
0391
0392
0393
0394
0395
0396
0397
0398 template <typename T>
0399 void addColumn(std::string_view key)
0400 requires(!ReadOnly)
0401 {
0402 self().template addColumn_impl<T>(key);
0403 }
0404
0405
0406
0407
0408 bool hasColumn(HashedString key) const { return self().hasColumn_impl(key); }
0409
0410
0411
0412
0413
0414 void clear()
0415 requires(!ReadOnly)
0416 {
0417 self().clear_impl();
0418 }
0419
0420
0421
0422 IndexType size() const { return self().size_impl(); }
0423
0424 protected:
0425
0426
0427
0428
0429
0430
0431 bool has(HashedString key, IndexType istate) const {
0432 return self().has_impl(key, istate);
0433 }
0434
0435
0436
0437
0438
0439 template <HashedString key>
0440 bool has(IndexType istate) const {
0441 return self().has_impl(key, istate);
0442 }
0443
0444
0445
0446
0447 typename TrackStateProxy::Parameters parameters(IndexType parIdx)
0448 requires(!ReadOnly)
0449 {
0450 return self().parameters_impl(parIdx);
0451 }
0452
0453
0454
0455
0456 typename ConstTrackStateProxy::Parameters parameters(IndexType parIdx) const {
0457 return self().parameters_impl(parIdx);
0458 }
0459
0460
0461
0462
0463 typename TrackStateProxy::Covariance covariance(IndexType covIdx)
0464 requires(!ReadOnly)
0465 {
0466 return self().covariance_impl(covIdx);
0467 }
0468
0469
0470
0471
0472 typename ConstTrackStateProxy::Covariance covariance(IndexType covIdx) const {
0473 return self().covariance_impl(covIdx);
0474 }
0475
0476
0477
0478
0479 typename TrackStateProxy::Covariance jacobian(IndexType istate)
0480 requires(!ReadOnly)
0481 {
0482 return self().jacobian_impl(istate);
0483 }
0484
0485
0486
0487
0488 typename ConstTrackStateProxy::Covariance jacobian(IndexType istate) const {
0489 return self().jacobian_impl(istate);
0490 }
0491
0492
0493
0494
0495
0496
0497 template <std::size_t measdim>
0498 typename TrackStateProxy::template Calibrated<measdim> calibrated(
0499 IndexType istate)
0500 requires(!ReadOnly)
0501 {
0502 return self().template calibrated_impl<measdim>(istate);
0503 }
0504
0505
0506
0507
0508
0509
0510 template <std::size_t measdim>
0511 typename ConstTrackStateProxy::template Calibrated<measdim> calibrated(
0512 IndexType istate) const {
0513 return self().template calibrated_impl<measdim>(istate);
0514 }
0515
0516
0517
0518
0519
0520
0521 template <std::size_t measdim>
0522 typename TrackStateProxy::template CalibratedCovariance<measdim>
0523 calibratedCovariance(IndexType istate)
0524 requires(!ReadOnly)
0525 {
0526 return self().template calibratedCovariance_impl<measdim>(istate);
0527 }
0528
0529
0530
0531
0532
0533 typename TrackStateProxy::EffectiveCalibrated effectiveCalibrated(
0534 IndexType istate)
0535 requires(!ReadOnly)
0536 {
0537
0538
0539
0540 return typename TrackStateProxy::EffectiveCalibrated{
0541 calibrated<eBoundSize>(istate).data(), calibratedSize(istate)};
0542 }
0543
0544
0545
0546
0547
0548 typename ConstTrackStateProxy::EffectiveCalibrated effectiveCalibrated(
0549 IndexType istate) const {
0550
0551
0552
0553 return typename ConstTrackStateProxy::EffectiveCalibrated{
0554 calibrated<eBoundSize>(istate).data(), calibratedSize(istate)};
0555 }
0556
0557
0558
0559
0560
0561 typename TrackStateProxy::EffectiveCalibratedCovariance
0562 effectiveCalibratedCovariance(IndexType istate)
0563 requires(!ReadOnly)
0564 {
0565
0566
0567
0568 return typename TrackStateProxy::EffectiveCalibratedCovariance{
0569 calibratedCovariance<eBoundSize>(istate).data(), calibratedSize(istate),
0570 calibratedSize(istate)};
0571 }
0572
0573
0574
0575
0576
0577 typename ConstTrackStateProxy::EffectiveCalibratedCovariance
0578 effectiveCalibratedCovariance(IndexType istate) const {
0579
0580
0581
0582 return typename ConstTrackStateProxy::EffectiveCalibratedCovariance{
0583 calibratedCovariance<eBoundSize>(istate).data(), calibratedSize(istate),
0584 calibratedSize(istate)};
0585 }
0586
0587
0588
0589
0590
0591 template <std::size_t measdim>
0592 typename ConstTrackStateProxy::template CalibratedCovariance<measdim>
0593 calibratedCovariance(IndexType istate) const {
0594 return self().template calibratedCovariance_impl<measdim>(istate);
0595 }
0596
0597
0598
0599
0600 IndexType calibratedSize(IndexType istate) const {
0601 return self().calibratedSize_impl(istate);
0602 }
0603
0604
0605
0606
0607
0608
0609
0610
0611
0612
0613
0614 void shareFrom(IndexType iself, IndexType iother,
0615 TrackStatePropMask shareSource, TrackStatePropMask shareTarget)
0616 requires(!ReadOnly)
0617 {
0618 self().shareFrom_impl(iself, iother, shareSource, shareTarget);
0619 }
0620
0621
0622
0623
0624 void unset(TrackStatePropMask target, IndexType istate)
0625 requires(!ReadOnly)
0626 {
0627 self().unset_impl(target, istate);
0628 }
0629
0630
0631
0632
0633
0634 void addTrackStateComponents(IndexType istate, TrackStatePropMask mask)
0635 requires(!ReadOnly)
0636 {
0637 self().addTrackStateComponents_impl(istate, mask);
0638 }
0639
0640
0641
0642
0643
0644
0645 template <typename T, HashedString key>
0646 T& component(IndexType istate)
0647 requires(!ReadOnly)
0648 {
0649 assert(checkOptional(key, istate));
0650 return *std::any_cast<T*>(self().component_impl(key, istate));
0651 }
0652
0653
0654
0655
0656
0657
0658 template <typename T>
0659 T& component(HashedString key, IndexType istate)
0660 requires(!ReadOnly)
0661 {
0662 assert(checkOptional(key, istate));
0663 return *std::any_cast<T*>(self().component_impl(key, istate));
0664 }
0665
0666
0667
0668
0669
0670
0671 template <typename T, HashedString key>
0672 const T& component(IndexType istate) const {
0673 assert(checkOptional(key, istate));
0674 return *std::any_cast<const T*>(self().component_impl(key, istate));
0675 }
0676
0677
0678
0679
0680
0681
0682 template <typename T>
0683 const T& component(HashedString key, IndexType istate) const {
0684 assert(checkOptional(key, istate));
0685 return *std::any_cast<const T*>(self().component_impl(key, istate));
0686 }
0687
0688
0689
0690
0691
0692
0693 void allocateCalibrated(IndexType istate, std::size_t measdim) {
0694 throw_assert(measdim > 0 && measdim <= eBoundSize,
0695 "Invalid measurement dimension detected");
0696
0697 visit_measurement(measdim, [this, istate]<std::size_t DIM>(
0698 std::integral_constant<std::size_t, DIM>) {
0699 self().allocateCalibrated_impl(
0700 istate, ActsVector<DIM>{ActsVector<DIM>::Zero()},
0701 ActsSquareMatrix<DIM>{ActsSquareMatrix<DIM>::Zero()});
0702 });
0703 }
0704
0705 template <std::size_t measdim, typename val_t, typename cov_t>
0706 void allocateCalibrated(IndexType istate, const Eigen::DenseBase<val_t>& val,
0707 const Eigen::DenseBase<cov_t>& cov) {
0708 self().allocateCalibrated_impl(istate, val, cov);
0709 }
0710
0711 void setUncalibratedSourceLink(IndexType istate, SourceLink&& sourceLink)
0712 requires(!ReadOnly)
0713 {
0714 self().setUncalibratedSourceLink_impl(istate, std::move(sourceLink));
0715 }
0716
0717 SourceLink getUncalibratedSourceLink(IndexType istate) const {
0718 return self().getUncalibratedSourceLink_impl(istate);
0719 }
0720
0721 const Surface* referenceSurface(IndexType istate) const {
0722 return self().referenceSurface_impl(istate);
0723 }
0724
0725 void setReferenceSurface(IndexType istate,
0726 std::shared_ptr<const Surface> surface)
0727 requires(!ReadOnly)
0728 {
0729 self().setReferenceSurface_impl(istate, std::move(surface));
0730 }
0731
0732 private:
0733 template <typename T>
0734 void copyDynamicFrom(IndexType dstIdx, const T& src, IndexType srcIdx)
0735 requires(!ReadOnly)
0736 {
0737 const auto& dynamicKeys = src.self().dynamicKeys_impl();
0738 for (const auto key : dynamicKeys) {
0739 std::any srcPtr = src.self().component_impl(key, srcIdx);
0740 self().copyDynamicFrom_impl(dstIdx, key, srcPtr);
0741 }
0742 }
0743 };
0744
0745 }
0746
0747 #include "Acts/EventData/MultiTrajectory.ipp"