File indexing completed on 2026-03-30 07:45:36
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include "Acts/EventData/SourceLink.hpp"
0012 #include "Acts/EventData/TrackStatePropMask.hpp"
0013 #include "Acts/EventData/TrackStateProxyCommon.hpp"
0014 #include "Acts/EventData/TrackStateProxyConcept.hpp"
0015 #include "Acts/EventData/Types.hpp"
0016 #include "Acts/Surfaces/Surface.hpp"
0017 #include "Acts/Utilities/HashedString.hpp"
0018 #include "Acts/Utilities/Helpers.hpp"
0019
0020 #include <cstddef>
0021
0022 #include <Eigen/Core>
0023
0024 namespace Acts {
0025
0026 template <typename derived_t>
0027 class MultiTrajectory;
0028
0029
0030
0031 template <bool read_only>
0032 class AnyTrackStateProxy;
0033
0034 namespace detail_lt {
0035
0036
0037 template <typename T>
0038 class TransitiveConstPointer {
0039 public:
0040 using element_type = T;
0041 TransitiveConstPointer() = default;
0042 explicit TransitiveConstPointer(T* ptr) : m_ptr{ptr} {}
0043
0044 template <typename U>
0045 explicit TransitiveConstPointer(const TransitiveConstPointer<U>& other)
0046 : m_ptr{other.ptr()} {}
0047
0048 template <typename U>
0049 TransitiveConstPointer& operator=(const TransitiveConstPointer<U>& other) {
0050 m_ptr = other.m_ptr;
0051 return *this;
0052 }
0053
0054 template <typename U>
0055 bool operator==(const TransitiveConstPointer<U>& other) const {
0056 return m_ptr == other.m_ptr;
0057 }
0058
0059 const T* operator->() const { return m_ptr; }
0060
0061 T* operator->() { return m_ptr; }
0062
0063 template <typename U>
0064 friend class TransitiveConstPointer;
0065 template <bool R>
0066 friend class AnyTrackStateProxy;
0067
0068 const T& operator*() const { return *m_ptr; }
0069
0070 T& operator*() { return *m_ptr; }
0071
0072 explicit operator bool() const { return m_ptr != nullptr; }
0073
0074 const T* ptr() const { return m_ptr; }
0075 T* ptr() { return m_ptr; }
0076
0077 private:
0078 T* m_ptr{nullptr};
0079 };
0080
0081 }
0082
0083
0084
0085
0086
0087
0088 template <typename trajectory_t, std::size_t M, bool read_only = true>
0089 class TrackStateProxy
0090 : public TrackStateProxyCommon<TrackStateProxy<trajectory_t, M, read_only>,
0091 read_only> {
0092 using Base =
0093 TrackStateProxyCommon<TrackStateProxy<trajectory_t, M, read_only>,
0094 read_only>;
0095
0096 friend class TrackStateProxyCommon<
0097 TrackStateProxy<trajectory_t, M, read_only>, read_only>;
0098
0099 public:
0100
0101
0102 static constexpr bool ReadOnly = read_only;
0103
0104
0105 using ConstProxyType = TrackStateProxy<trajectory_t, M, true>;
0106
0107
0108
0109 using Parameters = typename TrackStateTraits<M, false>::Parameters;
0110
0111
0112 using ConstParameters = typename TrackStateTraits<M, true>::Parameters;
0113
0114
0115
0116 using Covariance = typename TrackStateTraits<M, false>::Covariance;
0117
0118
0119 using Jacobian = typename TrackStateTraits<M, false>::Covariance;
0120
0121
0122 using ConstCovariance = typename TrackStateTraits<M, true>::Covariance;
0123
0124
0125 using ConstJacobian = typename TrackStateTraits<M, true>::Covariance;
0126
0127
0128
0129 template <std::size_t N>
0130 using Calibrated = typename TrackStateTraits<N, false>::Calibrated;
0131
0132
0133 template <std::size_t N>
0134 using ConstCalibrated = typename TrackStateTraits<N, true>::Calibrated;
0135
0136
0137
0138 template <std::size_t N>
0139 using CalibratedCovariance =
0140 typename TrackStateTraits<N, false>::CalibratedCovariance;
0141
0142
0143 template <std::size_t N>
0144 using ConstCalibratedCovariance =
0145 typename TrackStateTraits<N, true>::CalibratedCovariance;
0146
0147
0148
0149 using EffectiveCalibrated =
0150 typename TrackStateTraits<M, false>::EffectiveCalibrated;
0151
0152
0153 using ConstEffectiveCalibrated =
0154 typename TrackStateTraits<M, true>::EffectiveCalibrated;
0155
0156
0157
0158 using EffectiveCalibratedCovariance =
0159 typename TrackStateTraits<M, false>::EffectiveCalibratedCovariance;
0160
0161
0162 using ConstEffectiveCalibratedCovariance =
0163 typename TrackStateTraits<M, true>::EffectiveCalibratedCovariance;
0164
0165
0166 using IndexType = TrackIndexType;
0167
0168
0169 static constexpr IndexType kInvalid = kTrackIndexInvalid;
0170
0171
0172 using Trajectory = trajectory_t;
0173
0174 using Base::allocateCalibrated;
0175 using Base::calibrated;
0176 using Base::calibratedCovariance;
0177 using Base::chi2;
0178 using Base::covariance;
0179 using Base::effectiveCalibrated;
0180 using Base::effectiveCalibratedCovariance;
0181 using Base::filtered;
0182 using Base::filteredCovariance;
0183 using Base::getMask;
0184 using Base::hasCalibrated;
0185 using Base::hasFiltered;
0186 using Base::hasJacobian;
0187 using Base::hasPredicted;
0188 using Base::hasPrevious;
0189 using Base::hasProjector;
0190 using Base::hasSmoothed;
0191 using Base::parameters;
0192 using Base::pathLength;
0193 using Base::predicted;
0194 using Base::predictedCovariance;
0195 using Base::previous;
0196 using Base::projectorSubspaceHelper;
0197 using Base::projectorSubspaceIndices;
0198 using Base::setProjectorSubspaceIndices;
0199 using Base::smoothed;
0200 using Base::smoothedCovariance;
0201 using Base::typeFlags;
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214 TrackStateProxy(const TrackStateProxy& other) = default;
0215
0216
0217
0218
0219 TrackStateProxy& operator=(const TrackStateProxy& other) = default;
0220
0221
0222
0223
0224 explicit TrackStateProxy(const TrackStateProxy<Trajectory, M, false>& other)
0225 requires ReadOnly
0226 : m_traj{other.m_traj}, m_istate{other.m_istate} {}
0227
0228
0229
0230
0231
0232 TrackStateProxy& operator=(const TrackStateProxy<Trajectory, M, false>& other)
0233 requires ReadOnly
0234 {
0235 m_traj = other.m_traj;
0236 m_istate = other.m_istate;
0237
0238 return *this;
0239 }
0240
0241
0242
0243
0244
0245
0246
0247
0248
0249
0250
0251
0252
0253
0254
0255
0256
0257
0258
0259
0260
0261
0262
0263
0264
0265
0266
0267
0268
0269
0270
0271
0272
0273
0274
0275
0276
0277
0278
0279
0280
0281
0282
0283
0284
0285
0286
0287
0288
0289
0290 IndexType index() const { return m_istate; }
0291
0292
0293
0294
0295 void unset(TrackStatePropMask target)
0296 requires(!ReadOnly)
0297 {
0298 m_traj->self().unset(target, m_istate);
0299 }
0300
0301
0302
0303
0304 void addComponents(TrackStatePropMask mask)
0305 requires(!ReadOnly)
0306 {
0307 m_traj->self().addTrackStateComponents_impl(m_istate, mask);
0308 }
0309
0310
0311
0312 const Surface& referenceSurface() const {
0313 assert(hasReferenceSurface() &&
0314 "TrackState does not have reference surface");
0315 return *m_traj->referenceSurface(m_istate);
0316 }
0317
0318
0319
0320 bool hasReferenceSurface() const {
0321 return m_traj->referenceSurface(m_istate) != nullptr;
0322 }
0323
0324
0325
0326
0327
0328
0329
0330 void setReferenceSurface(std::shared_ptr<const Surface> srf)
0331 requires(!ReadOnly)
0332 {
0333 m_traj->setReferenceSurface(m_istate, std::move(srf));
0334 }
0335
0336
0337
0338
0339
0340
0341
0342 ConstCovariance jacobian() const {
0343 assert(has<detail_tsp::kJacobianKey>());
0344 return m_traj->self().jacobian(m_istate);
0345 }
0346
0347
0348
0349
0350 Covariance jacobian()
0351 requires(!ReadOnly)
0352 {
0353 assert(has<detail_tsp::kJacobianKey>());
0354 return m_traj->self().jacobian(m_istate);
0355 }
0356
0357
0358
0359
0360
0361
0362
0363
0364
0365
0366
0367
0368
0369
0370
0371
0372
0373
0374
0375
0376
0377
0378
0379
0380
0381
0382
0383
0384
0385
0386 SourceLink getUncalibratedSourceLink() const;
0387
0388
0389
0390 void setUncalibratedSourceLink(SourceLink&& sourceLink)
0391 requires(!ReadOnly)
0392 {
0393 m_traj->setUncalibratedSourceLink(m_istate, std::move(sourceLink));
0394 }
0395
0396
0397
0398
0399
0400 IndexType calibratedSize() const { return m_traj->calibratedSize(m_istate); }
0401
0402
0403
0404
0405
0406
0407
0408 void allocateCalibrated(std::size_t measdim)
0409 requires(!ReadOnly)
0410 {
0411 m_traj->allocateCalibrated(m_istate, measdim);
0412 }
0413
0414
0415
0416
0417
0418
0419
0420
0421
0422
0423
0424
0425
0426
0427
0428
0429
0430
0431
0432
0433
0434
0435
0436 void shareFrom(TrackStatePropMask shareSource, TrackStatePropMask shareTarget)
0437 requires(!ReadOnly)
0438 {
0439 shareFrom(*this, shareSource, shareTarget);
0440 }
0441
0442
0443
0444
0445
0446
0447 template <bool ReadOnlyOther>
0448 void shareFrom(const TrackStateProxy<Trajectory, M, ReadOnlyOther>& other,
0449 TrackStatePropMask component)
0450 requires(!ReadOnly)
0451 {
0452 shareFrom(other, component, component);
0453 }
0454
0455
0456
0457
0458
0459
0460
0461
0462 template <bool ReadOnlyOther>
0463 void shareFrom(const TrackStateProxy<Trajectory, M, ReadOnlyOther>& other,
0464 TrackStatePropMask shareSource, TrackStatePropMask shareTarget)
0465 requires(!ReadOnly)
0466 {
0467 assert(m_traj == other.m_traj &&
0468 "Cannot share components across MultiTrajectories");
0469
0470 assert(ACTS_CHECK_BIT(other.getMask(), shareSource) &&
0471 "Source has incompatible allocation");
0472
0473 m_traj->self().shareFrom(m_istate, other.m_istate, shareSource,
0474 shareTarget);
0475 }
0476
0477
0478
0479
0480
0481
0482
0483
0484
0485
0486 template <TrackStateProxyConcept track_state_proxy_t>
0487 void copyFrom(const track_state_proxy_t& other,
0488 TrackStatePropMask mask = TrackStatePropMask::All,
0489 bool onlyAllocated = true)
0490 requires(!ReadOnly)
0491 {
0492 using PM = TrackStatePropMask;
0493
0494 if (onlyAllocated) {
0495 auto dest = getMask();
0496 auto src = other.getMask() &
0497 mask;
0498
0499 if (ACTS_CHECK_BIT(src, PM::Calibrated)) {
0500
0501 dest |= PM::Calibrated;
0502 }
0503
0504 if ((static_cast<std::underlying_type_t<TrackStatePropMask>>(
0505 (src ^ dest) & src) != 0 ||
0506 dest == TrackStatePropMask::None ||
0507 src == TrackStatePropMask::None) &&
0508 mask != TrackStatePropMask::None) {
0509 throw std::runtime_error(
0510 "Attempt track state copy with incompatible allocations");
0511 }
0512
0513
0514 if (ACTS_CHECK_BIT(src, PM::Predicted)) {
0515 predicted() = other.predicted();
0516 predictedCovariance() = other.predictedCovariance();
0517 }
0518
0519 if (ACTS_CHECK_BIT(src, PM::Filtered)) {
0520 filtered() = other.filtered();
0521 filteredCovariance() = other.filteredCovariance();
0522 }
0523
0524 if (ACTS_CHECK_BIT(src, PM::Smoothed)) {
0525 smoothed() = other.smoothed();
0526 smoothedCovariance() = other.smoothedCovariance();
0527 }
0528
0529 if (other.hasUncalibratedSourceLink()) {
0530 setUncalibratedSourceLink(other.getUncalibratedSourceLink());
0531 }
0532
0533 if (ACTS_CHECK_BIT(src, PM::Jacobian)) {
0534 jacobian() = other.jacobian();
0535 }
0536
0537 if (ACTS_CHECK_BIT(src, PM::Calibrated)) {
0538 visit_measurement(other.calibratedSize(), [&](auto N) {
0539 constexpr int measdim = decltype(N)::value;
0540 allocateCalibrated(
0541 other.template calibrated<measdim>().eval(),
0542 other.template calibratedCovariance<measdim>().eval());
0543 });
0544
0545 setProjectorSubspaceIndices(other.projectorSubspaceIndices());
0546 }
0547 } else {
0548 if (ACTS_CHECK_BIT(mask, PM::Predicted) &&
0549 has<detail_tsp::kPredictedKey>() &&
0550 other.template has<detail_tsp::kPredictedKey>()) {
0551 predicted() = other.predicted();
0552 predictedCovariance() = other.predictedCovariance();
0553 }
0554
0555 if (ACTS_CHECK_BIT(mask, PM::Filtered) &&
0556 has<detail_tsp::kFilteredKey>() &&
0557 other.template has<detail_tsp::kFilteredKey>()) {
0558 filtered() = other.filtered();
0559 filteredCovariance() = other.filteredCovariance();
0560 }
0561
0562 if (ACTS_CHECK_BIT(mask, PM::Smoothed) &&
0563 has<detail_tsp::kSmoothedKey>() &&
0564 other.template has<detail_tsp::kSmoothedKey>()) {
0565 smoothed() = other.smoothed();
0566 smoothedCovariance() = other.smoothedCovariance();
0567 }
0568
0569 if (other.hasUncalibratedSourceLink()) {
0570 setUncalibratedSourceLink(other.getUncalibratedSourceLink());
0571 }
0572
0573 if (ACTS_CHECK_BIT(mask, PM::Jacobian) &&
0574 has<detail_tsp::kJacobianKey>() &&
0575 other.template has<detail_tsp::kJacobianKey>()) {
0576 jacobian() = other.jacobian();
0577 }
0578
0579
0580
0581 if (ACTS_CHECK_BIT(mask, PM::Calibrated) &&
0582 other.template has<detail_tsp::kCalibratedKey>()) {
0583 visit_measurement(other.calibratedSize(), [&](auto N) {
0584 constexpr int measdim = decltype(N)::value;
0585 allocateCalibrated(
0586 other.template calibrated<measdim>().eval(),
0587 other.template calibratedCovariance<measdim>().eval());
0588 });
0589
0590 setProjectorSubspaceIndices(other.projectorSubspaceIndices());
0591 }
0592 }
0593
0594 chi2() = other.chi2();
0595 pathLength() = other.pathLength();
0596 typeFlags() = other.typeFlags();
0597
0598 if (other.hasReferenceSurface()) {
0599 setReferenceSurface(other.referenceSurface().getSharedPtr());
0600 }
0601
0602 m_traj->copyDynamicFrom(m_istate, other.container(), other.index());
0603 }
0604
0605
0606
0607
0608
0609
0610
0611
0612
0613
0614 template <HashedString key>
0615 constexpr bool has() const {
0616 return m_traj->template has<key>(m_istate);
0617 }
0618
0619
0620
0621
0622 constexpr bool has(HashedString key) const {
0623 return m_traj->has(key, m_istate);
0624 }
0625
0626
0627
0628
0629
0630 constexpr bool has(std::string_view key) const {
0631 return has(hashStringDynamic(key));
0632 }
0633
0634
0635
0636
0637
0638 template <typename T, HashedString key>
0639 constexpr T& component()
0640 requires(!ReadOnly)
0641 {
0642 return m_traj->template component<T, key>(m_istate);
0643 }
0644
0645
0646
0647
0648
0649 template <typename T>
0650 constexpr T& component(HashedString key)
0651 requires(!ReadOnly)
0652 {
0653 return m_traj->template component<T>(key, m_istate);
0654 }
0655
0656
0657
0658
0659
0660
0661 template <typename T>
0662 constexpr T& component(std::string_view key)
0663 requires(!ReadOnly)
0664 {
0665 return m_traj->template component<T>(hashStringDynamic(key), m_istate);
0666 }
0667
0668
0669
0670
0671
0672 template <typename T, HashedString key>
0673 constexpr const T& component() const {
0674 return m_traj->template component<T, key>(m_istate);
0675 }
0676
0677
0678
0679
0680
0681 template <typename T>
0682 constexpr const T& component(HashedString key) const {
0683 return m_traj->template component<T>(key, m_istate);
0684 }
0685
0686
0687
0688
0689
0690
0691 template <typename T>
0692 constexpr const T& component(std::string_view key) const {
0693 return m_traj->template component<T>(hashStringDynamic(key), m_istate);
0694 }
0695
0696
0697
0698
0699
0700 MultiTrajectory<Trajectory>& trajectory()
0701 requires(!ReadOnly)
0702 {
0703 return *m_traj;
0704 }
0705
0706
0707
0708 const MultiTrajectory<Trajectory>& trajectory() const { return *m_traj; }
0709
0710
0711
0712 auto& container()
0713 requires(!ReadOnly)
0714 {
0715 return *m_traj;
0716 }
0717
0718
0719
0720 const auto& container() const { return *m_traj; }
0721
0722
0723
0724
0725 bool hasColumn(HashedString key) const { return container().hasColumn(key); }
0726
0727 protected:
0728
0729
0730
0731 ConstParameters parametersAtIndex(IndexType parIndex) const {
0732 return m_traj->parameters(parIndex);
0733 }
0734
0735
0736
0737
0738 Parameters parametersAtIndexMutable(IndexType parIndex)
0739 requires(!ReadOnly)
0740 {
0741 return m_traj->parameters(parIndex);
0742 }
0743
0744
0745
0746
0747 ConstCovariance covarianceAtIndex(IndexType covIndex) const {
0748 return m_traj->covariance(covIndex);
0749 }
0750
0751
0752
0753
0754 Covariance covarianceAtIndexMutable(IndexType covIndex)
0755 requires(!ReadOnly)
0756 {
0757 return m_traj->covariance(covIndex);
0758 }
0759
0760
0761
0762 double* calibratedDataMutable()
0763 requires(!ReadOnly)
0764 {
0765 return m_traj->template calibrated<M>(m_istate).data();
0766 }
0767
0768
0769
0770 const double* calibratedData() const {
0771 return m_traj->template calibrated<M>(m_istate).data();
0772 }
0773
0774
0775
0776 double* calibratedCovarianceDataMutable()
0777 requires(!ReadOnly)
0778 {
0779 return m_traj->template calibratedCovariance<M>(m_istate).data();
0780 }
0781
0782
0783
0784 const double* calibratedCovarianceData() const {
0785 return m_traj->template calibratedCovariance<M>(m_istate).data();
0786 }
0787
0788 private:
0789
0790 TrackStateProxy(const_if_t<ReadOnly, MultiTrajectory<Trajectory>>& trajectory,
0791 IndexType istate);
0792
0793 detail_lt::TransitiveConstPointer<
0794 const_if_t<ReadOnly, MultiTrajectory<Trajectory>>>
0795 m_traj;
0796 IndexType m_istate;
0797
0798 friend class Acts::MultiTrajectory<Trajectory>;
0799 friend class TrackStateProxy<Trajectory, M, true>;
0800 friend class TrackStateProxy<Trajectory, M, false>;
0801 template <bool R>
0802 friend class AnyTrackStateProxy;
0803
0804 const auto* rawTrajectoryPtr() const { return m_traj.ptr(); }
0805 auto* rawTrajectoryPtr() { return m_traj.ptr(); }
0806 };
0807 }
0808
0809 #include "Acts/EventData/TrackStateProxy.ipp"