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