File indexing completed on 2026-09-09 08:18:06
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include <boost/test/unit_test.hpp>
0012
0013 #include "Acts/Definitions/Algebra.hpp"
0014 #include "Acts/Definitions/TrackParametrization.hpp"
0015 #include "Acts/EventData/TrackStatePropMask.hpp"
0016 #include "Acts/EventData/VectorMultiTrajectory.hpp"
0017 #include "Acts/EventData/detail/TestSourceLink.hpp"
0018 #include "Acts/EventData/detail/TestTrackState.hpp"
0019 #include "Acts/Geometry/GeometryContext.hpp"
0020 #include "Acts/Utilities/CalibrationContext.hpp"
0021 #include "Acts/Utilities/HashedString.hpp"
0022
0023 #include <random>
0024 #include <stdexcept>
0025
0026 namespace Acts::detail::Test {
0027
0028 constexpr auto kInvalid = kTrackIndexInvalid;
0029
0030 template <typename factory_t>
0031 class MultiTrajectoryTestsCommon {
0032 using ParametersVector = BoundVector;
0033 using CovarianceMatrix = BoundMatrix;
0034 using Jacobian = BoundMatrix;
0035
0036 using trajectory_t = typename factory_t::trajectory_t;
0037 using const_trajectory_t = typename factory_t::const_trajectory_t;
0038
0039 private:
0040 factory_t m_factory;
0041
0042 public:
0043 void testBuild() {
0044 constexpr TrackStatePropMask kMask = TrackStatePropMask::Predicted;
0045
0046
0047 trajectory_t t = m_factory.create();
0048
0049 auto i0 = t.addTrackState(kMask);
0050
0051 auto i1a = t.addTrackState(kMask, i0);
0052 auto i1b = t.addTrackState(kMask, i0);
0053 auto i2a = t.addTrackState(kMask, i1a);
0054 auto i2b = t.addTrackState(kMask, i1b);
0055
0056
0057 std::vector<std::size_t> act;
0058 auto collect = [&](auto p) {
0059 act.push_back(p.index());
0060 BOOST_CHECK(!p.hasCalibrated());
0061 BOOST_CHECK(!p.hasFiltered());
0062 BOOST_CHECK(!p.hasSmoothed());
0063 BOOST_CHECK(!p.hasJacobian());
0064 BOOST_CHECK(!p.hasProjector());
0065 };
0066
0067 std::vector<std::size_t> exp = {i2a, i1a, i0};
0068 t.visitBackwards(i2a, collect);
0069 BOOST_CHECK_EQUAL_COLLECTIONS(act.begin(), act.end(), exp.begin(),
0070 exp.end());
0071
0072 act.clear();
0073 for (const auto& p : t.reverseTrackStateRange(i2a)) {
0074 act.push_back(p.index());
0075 }
0076 BOOST_CHECK_EQUAL_COLLECTIONS(act.begin(), act.end(), exp.begin(),
0077 exp.end());
0078
0079 act.clear();
0080 exp = {i2b, i1b, i0};
0081 t.visitBackwards(i2b, collect);
0082 BOOST_CHECK_EQUAL_COLLECTIONS(act.begin(), act.end(), exp.begin(),
0083 exp.end());
0084
0085 act.clear();
0086 for (const auto& p : t.reverseTrackStateRange(i2b)) {
0087 act.push_back(p.index());
0088 }
0089 BOOST_CHECK_EQUAL_COLLECTIONS(act.begin(), act.end(), exp.begin(),
0090 exp.end());
0091
0092 act.clear();
0093 t.applyBackwards(i2b, collect);
0094 BOOST_CHECK_EQUAL_COLLECTIONS(act.begin(), act.end(), exp.begin(),
0095 exp.end());
0096
0097 auto r = t.reverseTrackStateRange(i2b);
0098 BOOST_CHECK_EQUAL(std::distance(r.begin(), r.end()), 3);
0099
0100
0101 const auto& ct = t;
0102 std::vector<BoundVector> predicteds;
0103
0104 for (auto p : t.reverseTrackStateRange(i2b)) {
0105 predicteds.push_back(BoundVector::Random());
0106 p.predicted() = predicteds.back();
0107 }
0108 std::vector<BoundVector> predictedsAct;
0109 for (const auto& p : ct.reverseTrackStateRange(i2b)) {
0110 predictedsAct.push_back(p.predicted());
0111
0112
0113 }
0114 BOOST_CHECK_EQUAL_COLLECTIONS(predictedsAct.begin(), predictedsAct.end(),
0115 predicteds.begin(), predicteds.end());
0116
0117 {
0118 trajectory_t t2 = m_factory.create();
0119 auto ts = t2.makeTrackState(kMask);
0120 BOOST_CHECK_EQUAL(t2.size(), 1);
0121 auto ts2 = t2.makeTrackState(kMask, ts.index());
0122 BOOST_CHECK_EQUAL(t2.size(), 2);
0123 BOOST_CHECK_EQUAL(ts.previous(), kInvalid);
0124 BOOST_CHECK_EQUAL(ts2.previous(), ts.index());
0125 }
0126 }
0127
0128 void testClear() {
0129 constexpr TrackStatePropMask kMask = TrackStatePropMask::Predicted;
0130 trajectory_t t = m_factory.create();
0131 BOOST_CHECK_EQUAL(t.size(), 0);
0132
0133 auto i0 = t.addTrackState(kMask);
0134
0135 auto i1a = t.addTrackState(kMask, i0);
0136 auto i1b = t.addTrackState(kMask, i0);
0137 t.addTrackState(kMask, i1a);
0138 t.addTrackState(kMask, i1b);
0139
0140 BOOST_CHECK_EQUAL(t.size(), 5);
0141 t.clear();
0142 BOOST_CHECK_EQUAL(t.size(), 0);
0143 }
0144
0145 void testApplyWithAbort() {
0146 constexpr TrackStatePropMask kMask = TrackStatePropMask::Predicted;
0147
0148
0149 trajectory_t t = m_factory.create();
0150 auto i0 = t.addTrackState(kMask);
0151 auto i1 = t.addTrackState(kMask, i0);
0152 auto i2 = t.addTrackState(kMask, i1);
0153
0154 std::size_t n = 0;
0155 t.applyBackwards(i2, [&](const auto&) {
0156 n++;
0157 return false;
0158 });
0159 BOOST_CHECK_EQUAL(n, 1u);
0160
0161 n = 0;
0162 t.applyBackwards(i2, [&](const auto& ts) {
0163 n++;
0164 if (ts.index() == i1) {
0165 return false;
0166 }
0167 return true;
0168 });
0169 BOOST_CHECK_EQUAL(n, 2u);
0170
0171 n = 0;
0172 t.applyBackwards(i2, [&](const auto&) {
0173 n++;
0174 return true;
0175 });
0176 BOOST_CHECK_EQUAL(n, 3u);
0177 }
0178
0179 void testAddTrackStateWithBitMask() {
0180 using PM = TrackStatePropMask;
0181 using namespace Acts::HashedStringLiteral;
0182
0183 trajectory_t t = m_factory.create();
0184
0185 auto alwaysPresent = [](auto& ts) {
0186 BOOST_CHECK(ts.template has<"referenceSurface"_hash>());
0187 BOOST_CHECK(ts.template has<"measdim"_hash>());
0188 BOOST_CHECK(ts.template has<"chi2"_hash>());
0189 BOOST_CHECK(ts.template has<"pathLength"_hash>());
0190 BOOST_CHECK(ts.template has<"typeFlags"_hash>());
0191 };
0192
0193 auto ts = t.getTrackState(t.addTrackState(PM::All));
0194 BOOST_CHECK(ts.hasPredicted());
0195 BOOST_CHECK(ts.hasFiltered());
0196 BOOST_CHECK(ts.hasSmoothed());
0197 BOOST_CHECK(!ts.hasCalibrated());
0198 BOOST_CHECK(ts.hasProjector());
0199 BOOST_CHECK(ts.hasJacobian());
0200 alwaysPresent(ts);
0201 ts.allocateCalibrated(5);
0202 BOOST_CHECK(ts.hasCalibrated());
0203 BOOST_CHECK_EQUAL(ts.template calibrated<5>(), Vector<5>::Zero());
0204 BOOST_CHECK_EQUAL(ts.template calibratedCovariance<5>(),
0205 SquareMatrix<5>::Zero());
0206
0207 ts = t.getTrackState(t.addTrackState(PM::None));
0208 BOOST_CHECK(!ts.hasPredicted());
0209 BOOST_CHECK(!ts.hasFiltered());
0210 BOOST_CHECK(!ts.hasSmoothed());
0211 BOOST_CHECK(!ts.hasCalibrated());
0212 BOOST_CHECK(!ts.hasProjector());
0213 BOOST_CHECK(!ts.hasJacobian());
0214 alwaysPresent(ts);
0215
0216 ts = t.getTrackState(t.addTrackState(PM::Predicted));
0217 BOOST_CHECK(ts.hasPredicted());
0218 BOOST_CHECK(!ts.hasFiltered());
0219 BOOST_CHECK(!ts.hasSmoothed());
0220 BOOST_CHECK(!ts.hasCalibrated());
0221 BOOST_CHECK(!ts.hasProjector());
0222 BOOST_CHECK(!ts.hasJacobian());
0223 alwaysPresent(ts);
0224
0225 ts = t.getTrackState(t.addTrackState(PM::Filtered));
0226 BOOST_CHECK(!ts.hasPredicted());
0227 BOOST_CHECK(ts.hasFiltered());
0228 BOOST_CHECK(!ts.hasSmoothed());
0229 BOOST_CHECK(!ts.hasCalibrated());
0230 BOOST_CHECK(!ts.hasProjector());
0231 BOOST_CHECK(!ts.hasJacobian());
0232 alwaysPresent(ts);
0233
0234 ts = t.getTrackState(t.addTrackState(PM::Smoothed));
0235 BOOST_CHECK(!ts.hasPredicted());
0236 BOOST_CHECK(!ts.hasFiltered());
0237 BOOST_CHECK(ts.hasSmoothed());
0238 BOOST_CHECK(!ts.hasCalibrated());
0239 BOOST_CHECK(!ts.hasProjector());
0240 BOOST_CHECK(!ts.hasJacobian());
0241 alwaysPresent(ts);
0242
0243 ts = t.getTrackState(t.addTrackState(PM::Calibrated));
0244 BOOST_CHECK(!ts.hasPredicted());
0245 BOOST_CHECK(!ts.hasFiltered());
0246 BOOST_CHECK(!ts.hasSmoothed());
0247 BOOST_CHECK(!ts.hasCalibrated());
0248 BOOST_CHECK(ts.hasProjector());
0249 BOOST_CHECK(!ts.hasJacobian());
0250 ts.allocateCalibrated(5);
0251 BOOST_CHECK(ts.hasCalibrated());
0252 BOOST_CHECK_EQUAL(ts.template calibrated<5>(), Vector<5>::Zero());
0253 BOOST_CHECK_EQUAL(ts.template calibratedCovariance<5>(),
0254 SquareMatrix<5>::Zero());
0255
0256 ts = t.getTrackState(t.addTrackState(PM::Jacobian));
0257 BOOST_CHECK(!ts.hasPredicted());
0258 BOOST_CHECK(!ts.hasFiltered());
0259 BOOST_CHECK(!ts.hasSmoothed());
0260 BOOST_CHECK(!ts.hasCalibrated());
0261 BOOST_CHECK(!ts.hasProjector());
0262 BOOST_CHECK(ts.hasJacobian());
0263 alwaysPresent(ts);
0264 }
0265
0266 void testAddTrackStateComponents() {
0267 using PM = TrackStatePropMask;
0268
0269 trajectory_t t = m_factory.create();
0270
0271 auto ts = t.makeTrackState(PM::None);
0272 BOOST_CHECK(!ts.hasPredicted());
0273 BOOST_CHECK(!ts.hasFiltered());
0274 BOOST_CHECK(!ts.hasSmoothed());
0275 BOOST_CHECK(!ts.hasCalibrated());
0276 BOOST_CHECK(!ts.hasJacobian());
0277
0278 ts.addComponents(PM::None);
0279 BOOST_CHECK(!ts.hasPredicted());
0280 BOOST_CHECK(!ts.hasFiltered());
0281 BOOST_CHECK(!ts.hasSmoothed());
0282 BOOST_CHECK(!ts.hasCalibrated());
0283 BOOST_CHECK(!ts.hasJacobian());
0284
0285 ts.addComponents(PM::Predicted);
0286 BOOST_CHECK(ts.hasPredicted());
0287 BOOST_CHECK(!ts.hasFiltered());
0288 BOOST_CHECK(!ts.hasSmoothed());
0289 BOOST_CHECK(!ts.hasCalibrated());
0290 BOOST_CHECK(!ts.hasJacobian());
0291
0292 ts.addComponents(PM::Filtered);
0293 BOOST_CHECK(ts.hasPredicted());
0294 BOOST_CHECK(ts.hasFiltered());
0295 BOOST_CHECK(!ts.hasSmoothed());
0296 BOOST_CHECK(!ts.hasCalibrated());
0297 BOOST_CHECK(!ts.hasJacobian());
0298
0299 ts.addComponents(PM::Smoothed);
0300 BOOST_CHECK(ts.hasPredicted());
0301 BOOST_CHECK(ts.hasFiltered());
0302 BOOST_CHECK(ts.hasSmoothed());
0303 BOOST_CHECK(!ts.hasCalibrated());
0304 BOOST_CHECK(!ts.hasJacobian());
0305
0306 ts.addComponents(PM::Calibrated);
0307 ts.allocateCalibrated(5);
0308 BOOST_CHECK(ts.hasPredicted());
0309 BOOST_CHECK(ts.hasFiltered());
0310 BOOST_CHECK(ts.hasSmoothed());
0311 BOOST_CHECK(ts.hasCalibrated());
0312 BOOST_CHECK(!ts.hasJacobian());
0313 BOOST_CHECK_EQUAL(ts.template calibrated<5>(), Vector<5>::Zero());
0314 BOOST_CHECK_EQUAL(ts.template calibratedCovariance<5>(),
0315 SquareMatrix<5>::Zero());
0316
0317 ts.addComponents(PM::Jacobian);
0318 BOOST_CHECK(ts.hasPredicted());
0319 BOOST_CHECK(ts.hasFiltered());
0320 BOOST_CHECK(ts.hasSmoothed());
0321 BOOST_CHECK(ts.hasCalibrated());
0322 BOOST_CHECK(ts.hasJacobian());
0323
0324 ts.addComponents(PM::All);
0325 BOOST_CHECK(ts.hasPredicted());
0326 BOOST_CHECK(ts.hasFiltered());
0327 BOOST_CHECK(ts.hasSmoothed());
0328 BOOST_CHECK(ts.hasCalibrated());
0329 BOOST_CHECK(ts.hasJacobian());
0330 }
0331
0332 void testAddTrackStateComponentsAfterShareAndUnset() {
0333 using PM = TrackStatePropMask;
0334
0335 trajectory_t t = m_factory.create();
0336
0337
0338
0339 {
0340 auto ts = t.makeTrackState(PM::Predicted);
0341 ts.predicted() = BoundVector::Constant(42);
0342 ts.shareFrom(PM::Predicted, PM::Filtered);
0343 BOOST_CHECK(ts.hasFiltered());
0344
0345 ts.addComponents(PM::Filtered);
0346 BOOST_CHECK(ts.hasFiltered());
0347 BOOST_CHECK_EQUAL(ts.filtered(), BoundVector::Constant(42));
0348
0349 ts.predicted() = BoundVector::Constant(11);
0350 BOOST_CHECK_EQUAL(ts.filtered(), BoundVector::Constant(11));
0351 }
0352
0353
0354 {
0355 auto ts = t.makeTrackState(PM::Predicted | PM::Filtered);
0356 BOOST_CHECK(ts.hasFiltered());
0357
0358 ts.unset(PM::Filtered);
0359 BOOST_CHECK(!ts.hasFiltered());
0360
0361 ts.addComponents(PM::Filtered);
0362 BOOST_CHECK(ts.hasFiltered());
0363
0364 ts.filtered() = BoundVector::Constant(7);
0365 ts.predicted() = BoundVector::Constant(3);
0366
0367 BOOST_CHECK_EQUAL(ts.filtered(), BoundVector::Constant(7));
0368 }
0369 }
0370
0371 void testTrackStateProxyCrossTalk(std::default_random_engine& rng) {
0372 TestTrackState pc(rng, 2u);
0373
0374
0375 trajectory_t traj = m_factory.create();
0376 std::size_t index = traj.addTrackState();
0377 {
0378 auto ts = traj.getTrackState(index);
0379 fillTrackState<trajectory_t>(pc, TrackStatePropMask::All, ts);
0380 }
0381
0382 auto tsa = traj.getTrackState(index);
0383 auto tsb = traj.getTrackState(index);
0384
0385 {
0386 auto [par, cov] = generateBoundParametersCovariance(rng, {});
0387 tsb.predicted() = par;
0388 tsb.predictedCovariance() = cov;
0389 BOOST_CHECK_EQUAL(tsa.predicted(), par);
0390 BOOST_CHECK_EQUAL(tsa.predictedCovariance(), cov);
0391 BOOST_CHECK_EQUAL(tsb.predicted(), par);
0392 BOOST_CHECK_EQUAL(tsb.predictedCovariance(), cov);
0393 }
0394 {
0395 auto [par, cov] = generateBoundParametersCovariance(rng, {});
0396 tsb.filtered() = par;
0397 tsb.filteredCovariance() = cov;
0398 BOOST_CHECK_EQUAL(tsa.filtered(), par);
0399 BOOST_CHECK_EQUAL(tsa.filteredCovariance(), cov);
0400 BOOST_CHECK_EQUAL(tsb.filtered(), par);
0401 BOOST_CHECK_EQUAL(tsb.filteredCovariance(), cov);
0402 }
0403 {
0404 auto [par, cov] = generateBoundParametersCovariance(rng, {});
0405 tsb.smoothed() = par;
0406 tsb.smoothedCovariance() = cov;
0407 BOOST_CHECK_EQUAL(tsa.smoothed(), par);
0408 BOOST_CHECK_EQUAL(tsa.smoothedCovariance(), cov);
0409 BOOST_CHECK_EQUAL(tsb.smoothed(), par);
0410 BOOST_CHECK_EQUAL(tsb.smoothedCovariance(), cov);
0411 }
0412 {
0413
0414 TestSourceLink invalid;
0415 invalid.sourceId = -1;
0416 BOOST_CHECK_NE(
0417 tsa.getUncalibratedSourceLink().template get<TestSourceLink>(),
0418 invalid);
0419 BOOST_CHECK_NE(
0420 tsb.getUncalibratedSourceLink().template get<TestSourceLink>(),
0421 invalid);
0422 tsb.setUncalibratedSourceLink(SourceLink{invalid});
0423 BOOST_CHECK_EQUAL(
0424 tsa.getUncalibratedSourceLink().template get<TestSourceLink>(),
0425 invalid);
0426 BOOST_CHECK_EQUAL(
0427 tsb.getUncalibratedSourceLink().template get<TestSourceLink>(),
0428 invalid);
0429 }
0430 {
0431
0432 auto [measPar, measCov] = generateBoundParametersCovariance(rng, {});
0433
0434 tsb.unset(TrackStatePropMask::Calibrated);
0435 tsb.allocateCalibrated(eBoundSize);
0436 BOOST_CHECK_EQUAL(tsb.template calibrated<eBoundSize>(),
0437 BoundVector::Zero());
0438 BOOST_CHECK_EQUAL(tsb.template calibratedCovariance<eBoundSize>(),
0439 BoundMatrix::Zero());
0440 tsb.template calibrated<eBoundSize>() = measPar;
0441 tsb.template calibratedCovariance<eBoundSize>() = measCov;
0442 BOOST_CHECK_EQUAL(tsa.template calibrated<eBoundSize>(), measPar);
0443 BOOST_CHECK_EQUAL(tsa.template calibratedCovariance<eBoundSize>(),
0444 measCov);
0445 BOOST_CHECK_EQUAL(tsb.template calibrated<eBoundSize>(), measPar);
0446 BOOST_CHECK_EQUAL(tsb.template calibratedCovariance<eBoundSize>(),
0447 measCov);
0448 }
0449 {
0450
0451 auto [measPar, measCov] = generateBoundParametersCovariance(rng, {});
0452 std::size_t nMeasurements = tsb.effectiveCalibrated().rows();
0453 auto effPar = measPar.head(nMeasurements);
0454 auto effCov = measCov.topLeftCorner(nMeasurements, nMeasurements);
0455 tsb.allocateCalibrated(
0456 eBoundSize);
0457
0458 BOOST_CHECK_EQUAL(tsa.effectiveCalibrated(), BoundVector::Zero());
0459 BOOST_CHECK_EQUAL(tsa.effectiveCalibratedCovariance(),
0460 BoundMatrix::Zero());
0461 BOOST_CHECK_EQUAL(tsa.effectiveCalibrated(), BoundVector::Zero());
0462 BOOST_CHECK_EQUAL(tsa.effectiveCalibratedCovariance(),
0463 BoundMatrix::Zero());
0464 tsb.effectiveCalibrated() = effPar;
0465 tsb.effectiveCalibratedCovariance() = effCov;
0466 BOOST_CHECK_EQUAL(tsa.effectiveCalibrated(), effPar);
0467 BOOST_CHECK_EQUAL(tsa.effectiveCalibratedCovariance(), effCov);
0468 BOOST_CHECK_EQUAL(tsb.effectiveCalibrated(), effPar);
0469 BOOST_CHECK_EQUAL(tsb.effectiveCalibratedCovariance(), effCov);
0470 }
0471 {
0472 Jacobian jac = Jacobian::Identity();
0473 BOOST_CHECK_NE(tsa.jacobian(), jac);
0474 BOOST_CHECK_NE(tsb.jacobian(), jac);
0475 tsb.jacobian() = jac;
0476 BOOST_CHECK_EQUAL(tsa.jacobian(), jac);
0477 BOOST_CHECK_EQUAL(tsb.jacobian(), jac);
0478 }
0479 {
0480 tsb.chi2() = 98.0;
0481 BOOST_CHECK_EQUAL(tsa.chi2(), 98.0);
0482 BOOST_CHECK_EQUAL(tsb.chi2(), 98.0);
0483 }
0484 {
0485 tsb.pathLength() = 66.0;
0486 BOOST_CHECK_EQUAL(tsa.pathLength(), 66.0);
0487 BOOST_CHECK_EQUAL(tsb.pathLength(), 66.0);
0488 }
0489 }
0490
0491 void testTrackStateReassignment(std::default_random_engine& rng) {
0492 TestTrackState pc(rng, 1u);
0493
0494 trajectory_t t = m_factory.create();
0495 std::size_t index = t.addTrackState();
0496 auto ts = t.getTrackState(index);
0497 fillTrackState<trajectory_t>(pc, TrackStatePropMask::All, ts);
0498
0499
0500 BOOST_CHECK_EQUAL(ts.calibratedSize(), 1u);
0501 BOOST_CHECK_EQUAL(ts.effectiveCalibrated(),
0502 (pc.sourceLink.parameters.head<1>()));
0503 BOOST_CHECK_EQUAL(ts.effectiveCalibratedCovariance(),
0504 (pc.sourceLink.covariance.topLeftCorner<1, 1>()));
0505
0506
0507 TestTrackState ttsb(rng, 2u);
0508 const auto gctx = Acts::GeometryContext::dangerouslyDefaultConstruct();
0509 Acts::CalibrationContext cctx;
0510 BOOST_CHECK_EQUAL(
0511 ts.getUncalibratedSourceLink().template get<TestSourceLink>().sourceId,
0512 pc.sourceLink.sourceId);
0513
0514 ts.unset(TrackStatePropMask::Calibrated);
0515 testSourceLinkCalibrator<trajectory_t>(gctx, cctx,
0516 SourceLink{ttsb.sourceLink}, ts);
0517 BOOST_CHECK_EQUAL(
0518 ts.getUncalibratedSourceLink().template get<TestSourceLink>().sourceId,
0519 ttsb.sourceLink.sourceId);
0520
0521 BOOST_CHECK_EQUAL(ts.calibratedSize(), 2);
0522 BOOST_CHECK_EQUAL(ts.effectiveCalibrated(), ttsb.sourceLink.parameters);
0523 BOOST_CHECK_EQUAL(ts.effectiveCalibratedCovariance(),
0524 ttsb.sourceLink.covariance);
0525 }
0526
0527 void testTrackStateProxyStorage(std::default_random_engine& rng,
0528 std::size_t nMeasurements) {
0529 TestTrackState pc(rng, nMeasurements);
0530
0531
0532 trajectory_t t = m_factory.create();
0533 std::size_t index = t.addTrackState();
0534 auto ts = t.getTrackState(index);
0535 fillTrackState<trajectory_t>(pc, TrackStatePropMask::All, ts);
0536
0537
0538 BOOST_CHECK_EQUAL(&ts.referenceSurface(), pc.surface.get());
0539 BOOST_CHECK_EQUAL(ts.referenceSurface().geometryId(),
0540 pc.sourceLink.m_geometryId);
0541
0542
0543 BOOST_CHECK(ts.hasPredicted());
0544 BOOST_CHECK_EQUAL(ts.predicted(), pc.predicted.parameters());
0545 BOOST_CHECK(pc.predicted.covariance().has_value());
0546 BOOST_CHECK_EQUAL(ts.predictedCovariance(), *pc.predicted.covariance());
0547 BOOST_CHECK(ts.hasFiltered());
0548 BOOST_CHECK_EQUAL(ts.filtered(), pc.filtered.parameters());
0549 BOOST_CHECK(pc.filtered.covariance().has_value());
0550 BOOST_CHECK_EQUAL(ts.filteredCovariance(), *pc.filtered.covariance());
0551 BOOST_CHECK(ts.hasSmoothed());
0552 BOOST_CHECK_EQUAL(ts.smoothed(), pc.smoothed.parameters());
0553 BOOST_CHECK(pc.smoothed.covariance().has_value());
0554 BOOST_CHECK_EQUAL(ts.smoothedCovariance(), *pc.smoothed.covariance());
0555
0556
0557 BOOST_CHECK(ts.hasJacobian());
0558 BOOST_CHECK_EQUAL(ts.jacobian(), pc.jacobian);
0559 BOOST_CHECK_EQUAL(ts.pathLength(), pc.pathLength);
0560
0561 BOOST_CHECK_EQUAL(ts.chi2(), static_cast<float>(pc.chi2));
0562
0563
0564 BOOST_CHECK_EQUAL(
0565 ts.getUncalibratedSourceLink().template get<TestSourceLink>(),
0566 pc.sourceLink);
0567
0568
0569 BOOST_CHECK(ts.hasCalibrated());
0570 BOOST_CHECK_EQUAL(ts.effectiveCalibrated(),
0571 pc.sourceLink.parameters.head(nMeasurements));
0572 BOOST_CHECK_EQUAL(
0573 ts.effectiveCalibratedCovariance(),
0574 pc.sourceLink.covariance.topLeftCorner(nMeasurements, nMeasurements));
0575 {
0576 ParametersVector mParFull = ParametersVector::Zero();
0577 CovarianceMatrix mCovFull = CovarianceMatrix::Zero();
0578 mParFull.head(nMeasurements) =
0579 pc.sourceLink.parameters.head(nMeasurements);
0580 mCovFull.topLeftCorner(nMeasurements, nMeasurements) =
0581 pc.sourceLink.covariance.topLeftCorner(nMeasurements, nMeasurements);
0582
0583 auto expMeas = pc.sourceLink.parameters.head(nMeasurements);
0584 auto expCov =
0585 pc.sourceLink.covariance.topLeftCorner(nMeasurements, nMeasurements);
0586
0587 visit_measurement(ts.calibratedSize(), [&](auto N) {
0588 constexpr std::size_t measdim = decltype(N)::value;
0589 BOOST_CHECK_EQUAL(ts.template calibrated<measdim>(), expMeas);
0590 BOOST_CHECK_EQUAL(ts.template calibratedCovariance<measdim>(), expCov);
0591 });
0592 }
0593 }
0594
0595 void testTrackStateProxyAllocations(std::default_random_engine& rng) {
0596 using namespace Acts::HashedStringLiteral;
0597
0598 TestTrackState pc(rng, 2u);
0599
0600
0601 trajectory_t t = m_factory.create();
0602 std::size_t i = t.addTrackState(TrackStatePropMask::Predicted |
0603 TrackStatePropMask::Filtered |
0604 TrackStatePropMask::Jacobian);
0605 auto tso = t.getTrackState(i);
0606 fillTrackState<trajectory_t>(pc, TrackStatePropMask::Predicted, tso);
0607 fillTrackState<trajectory_t>(pc, TrackStatePropMask::Filtered, tso);
0608 fillTrackState<trajectory_t>(pc, TrackStatePropMask::Jacobian, tso);
0609
0610 BOOST_CHECK(tso.hasPredicted());
0611 BOOST_CHECK(tso.hasFiltered());
0612 BOOST_CHECK(!tso.hasSmoothed());
0613 BOOST_CHECK(!tso.hasCalibrated());
0614 BOOST_CHECK(tso.hasJacobian());
0615
0616 auto tsnone = t.getTrackState(t.addTrackState(TrackStatePropMask::None));
0617 BOOST_CHECK(!tsnone.template has<"predicted"_hash>());
0618 BOOST_CHECK(!tsnone.template has<"filtered"_hash>());
0619 BOOST_CHECK(!tsnone.template has<"smoothed"_hash>());
0620 BOOST_CHECK(!tsnone.template has<"jacobian"_hash>());
0621 BOOST_CHECK(!tsnone.template has<"calibrated"_hash>());
0622 BOOST_CHECK(!tsnone.template has<"projector"_hash>());
0623 BOOST_CHECK(
0624 !tsnone.template has<"uncalibratedSourceLink"_hash>());
0625
0626
0627 BOOST_CHECK(tsnone.template has<"referenceSurface"_hash>());
0628 BOOST_CHECK(tsnone.template has<"measdim"_hash>());
0629 BOOST_CHECK(tsnone.template has<"chi2"_hash>());
0630 BOOST_CHECK(tsnone.template has<"pathLength"_hash>());
0631 BOOST_CHECK(tsnone.template has<"typeFlags"_hash>());
0632
0633 auto tsall = t.getTrackState(t.addTrackState(TrackStatePropMask::All));
0634 BOOST_CHECK(tsall.template has<"predicted"_hash>());
0635 BOOST_CHECK(tsall.template has<"filtered"_hash>());
0636 BOOST_CHECK(tsall.template has<"smoothed"_hash>());
0637 BOOST_CHECK(tsall.template has<"jacobian"_hash>());
0638 BOOST_CHECK(!tsall.template has<"calibrated"_hash>());
0639 tsall.allocateCalibrated(5);
0640 BOOST_CHECK(tsall.template has<"calibrated"_hash>());
0641 BOOST_CHECK(tsall.template has<"projector"_hash>());
0642 BOOST_CHECK(!tsall.template has<
0643 "uncalibratedSourceLink"_hash>());
0644
0645 BOOST_CHECK(tsall.template has<"referenceSurface"_hash>());
0646 BOOST_CHECK(tsall.template has<"measdim"_hash>());
0647 BOOST_CHECK(tsall.template has<"chi2"_hash>());
0648 BOOST_CHECK(tsall.template has<"pathLength"_hash>());
0649 BOOST_CHECK(tsall.template has<"typeFlags"_hash>());
0650
0651 tsall.unset(TrackStatePropMask::Predicted);
0652 BOOST_CHECK(!tsall.template has<"predicted"_hash>());
0653 tsall.unset(TrackStatePropMask::Filtered);
0654 BOOST_CHECK(!tsall.template has<"filtered"_hash>());
0655 tsall.unset(TrackStatePropMask::Smoothed);
0656 BOOST_CHECK(!tsall.template has<"smoothed"_hash>());
0657 tsall.unset(TrackStatePropMask::Jacobian);
0658 BOOST_CHECK(!tsall.template has<"jacobian"_hash>());
0659 tsall.unset(TrackStatePropMask::Calibrated);
0660 BOOST_CHECK(!tsall.template has<"calibrated"_hash>());
0661 }
0662
0663 void testTrackStateProxyGetMask() {
0664 using PM = TrackStatePropMask;
0665
0666 std::array<PM, 5> values{PM::Predicted, PM::Filtered, PM::Smoothed,
0667 PM::Jacobian, PM::Calibrated};
0668 PM all = std::accumulate(values.begin(), values.end(), PM::None,
0669 [](auto a, auto b) { return a | b; });
0670
0671 trajectory_t mj = m_factory.create();
0672 {
0673 auto ts = mj.getTrackState(mj.addTrackState(PM::All));
0674
0675 BOOST_CHECK_EQUAL(ts.getMask(), (all & ~PM::Calibrated));
0676 ts.allocateCalibrated(4);
0677 BOOST_CHECK_EQUAL(ts.getMask(), all);
0678 }
0679 {
0680 auto ts =
0681 mj.getTrackState(mj.addTrackState(PM::Filtered | PM::Calibrated));
0682
0683 BOOST_CHECK_EQUAL(ts.getMask(), PM::Filtered);
0684 ts.allocateCalibrated(4);
0685 BOOST_CHECK_EQUAL(ts.getMask(), (PM::Filtered | PM::Calibrated));
0686 }
0687 {
0688 auto ts = mj.getTrackState(
0689 mj.addTrackState(PM::Filtered | PM::Smoothed | PM::Predicted));
0690 BOOST_CHECK_EQUAL(ts.getMask(),
0691 (PM::Filtered | PM::Smoothed | PM::Predicted));
0692 }
0693 {
0694 for (PM mask : values) {
0695 auto ts = mj.getTrackState(mj.addTrackState(mask));
0696
0697 BOOST_CHECK_EQUAL(ts.getMask(), (mask & ~PM::Calibrated));
0698 }
0699 }
0700 }
0701
0702 void testTrackStateProxyCopy(std::default_random_engine& rng) {
0703 using PM = TrackStatePropMask;
0704
0705 std::array<PM, 4> values{PM::Predicted, PM::Filtered, PM::Smoothed,
0706 PM::Jacobian};
0707
0708 trajectory_t mj = m_factory.create();
0709 auto mkts = [&](PM mask) {
0710 auto r = mj.getTrackState(mj.addTrackState(mask));
0711 return r;
0712 };
0713
0714
0715 for (PM a : values) {
0716 for (PM b : values) {
0717 auto tsa = mkts(a);
0718 auto tsb = mkts(b);
0719
0720 if (a != b) {
0721 BOOST_CHECK_THROW(tsa.copyFrom(tsb), std::runtime_error);
0722 BOOST_CHECK_THROW(tsb.copyFrom(tsa), std::runtime_error);
0723 } else {
0724 tsa.copyFrom(tsb);
0725 tsb.copyFrom(tsa);
0726 }
0727 }
0728 }
0729
0730 {
0731 BOOST_TEST_CHECKPOINT("Calib auto alloc");
0732 auto tsa = mkts(PM::All);
0733 auto tsb = mkts(PM::All);
0734 tsb.allocateCalibrated(5);
0735 tsb.template calibrated<5>().setRandom();
0736 tsb.template calibratedCovariance<5>().setRandom();
0737 tsa.copyFrom(tsb, PM::All);
0738 BOOST_CHECK_EQUAL(tsa.template calibrated<5>(),
0739 tsb.template calibrated<5>());
0740 BOOST_CHECK_EQUAL(tsa.template calibratedCovariance<5>(),
0741 tsb.template calibratedCovariance<5>());
0742 }
0743
0744 {
0745 BOOST_TEST_CHECKPOINT("Copy none");
0746 auto tsa = mkts(PM::All);
0747 auto tsb = mkts(PM::All);
0748 tsa.copyFrom(tsb, PM::None);
0749 }
0750
0751 auto ts1 = mkts(PM::Filtered | PM::Predicted);
0752 ts1.filtered().setRandom();
0753 ts1.filteredCovariance().setRandom();
0754 ts1.predicted().setRandom();
0755 ts1.predictedCovariance().setRandom();
0756
0757
0758 auto ts2 = mkts(PM::Predicted);
0759 ts2.predicted().setRandom();
0760 ts2.predictedCovariance().setRandom();
0761
0762
0763 BOOST_CHECK_NE(ts1.predicted(), ts2.predicted());
0764 BOOST_CHECK_NE(ts1.predictedCovariance(), ts2.predictedCovariance());
0765
0766
0767 BOOST_CHECK_THROW(ts2.copyFrom(ts1), std::runtime_error);
0768 BOOST_CHECK_NE(ts1.predicted(), ts2.predicted());
0769 BOOST_CHECK_NE(ts1.predictedCovariance(), ts2.predictedCovariance());
0770
0771
0772 ts1.copyFrom(ts2);
0773 BOOST_CHECK_EQUAL(ts1.predicted(), ts2.predicted());
0774 BOOST_CHECK_EQUAL(ts1.predictedCovariance(), ts2.predictedCovariance());
0775
0776 std::size_t i0 = mj.addTrackState();
0777 std::size_t i1 = mj.addTrackState();
0778 ts1 = mj.getTrackState(i0);
0779 ts2 = mj.getTrackState(i1);
0780 TestTrackState rts1(rng, 1u);
0781 TestTrackState rts2(rng, 2u);
0782 fillTrackState<trajectory_t>(rts1, TrackStatePropMask::All, ts1);
0783 fillTrackState<trajectory_t>(rts2, TrackStatePropMask::All, ts2);
0784
0785 auto ots1 = mkts(PM::All);
0786 auto ots2 = mkts(PM::All);
0787
0788 ots1.copyFrom(ts1);
0789 ots2.copyFrom(ts2);
0790
0791 BOOST_CHECK_NE(ts1.predicted(), ts2.predicted());
0792 BOOST_CHECK_NE(ts1.predictedCovariance(), ts2.predictedCovariance());
0793 BOOST_CHECK_NE(ts1.filtered(), ts2.filtered());
0794 BOOST_CHECK_NE(ts1.filteredCovariance(), ts2.filteredCovariance());
0795 BOOST_CHECK_NE(ts1.smoothed(), ts2.smoothed());
0796 BOOST_CHECK_NE(ts1.smoothedCovariance(), ts2.smoothedCovariance());
0797
0798 BOOST_CHECK_NE(
0799 ts1.getUncalibratedSourceLink().template get<TestSourceLink>(),
0800 ts2.getUncalibratedSourceLink().template get<TestSourceLink>());
0801
0802 BOOST_CHECK_NE(ts1.calibratedSize(), ts2.calibratedSize());
0803 BOOST_CHECK(ts1.projectorSubspaceIndices() !=
0804 ts2.projectorSubspaceIndices());
0805
0806 BOOST_CHECK_NE(ts1.jacobian(), ts2.jacobian());
0807 BOOST_CHECK_NE(ts1.chi2(), ts2.chi2());
0808 BOOST_CHECK_NE(ts1.pathLength(), ts2.pathLength());
0809 BOOST_CHECK_NE(&ts1.referenceSurface(), &ts2.referenceSurface());
0810
0811
0812 ts1.unset(TrackStatePropMask::Calibrated);
0813 ts1.copyFrom(ts2);
0814
0815 BOOST_CHECK_EQUAL(ts1.predicted(), ts2.predicted());
0816 BOOST_CHECK_EQUAL(ts1.predictedCovariance(), ts2.predictedCovariance());
0817 BOOST_CHECK_EQUAL(ts1.filtered(), ts2.filtered());
0818 BOOST_CHECK_EQUAL(ts1.filteredCovariance(), ts2.filteredCovariance());
0819 BOOST_CHECK_EQUAL(ts1.smoothed(), ts2.smoothed());
0820 BOOST_CHECK_EQUAL(ts1.smoothedCovariance(), ts2.smoothedCovariance());
0821
0822 BOOST_CHECK_EQUAL(
0823 ts1.getUncalibratedSourceLink().template get<TestSourceLink>(),
0824 ts2.getUncalibratedSourceLink().template get<TestSourceLink>());
0825
0826 visit_measurement(ts1.calibratedSize(), [&](auto N) {
0827 constexpr std::size_t measdim = decltype(N)::value;
0828 BOOST_CHECK_EQUAL(ts1.template calibrated<measdim>(),
0829 ts2.template calibrated<measdim>());
0830 BOOST_CHECK_EQUAL(ts1.template calibratedCovariance<measdim>(),
0831 ts2.template calibratedCovariance<measdim>());
0832 BOOST_CHECK(ts1.template projectorSubspaceIndices<measdim>() ==
0833 ts2.template projectorSubspaceIndices<measdim>());
0834 });
0835
0836 BOOST_CHECK_EQUAL(ts1.calibratedSize(), ts2.calibratedSize());
0837 BOOST_CHECK(ts1.projectorSubspaceIndices() ==
0838 ts2.projectorSubspaceIndices());
0839
0840 BOOST_CHECK_EQUAL(ts1.jacobian(), ts2.jacobian());
0841 BOOST_CHECK_EQUAL(ts1.chi2(), ts2.chi2());
0842 BOOST_CHECK_EQUAL(ts1.pathLength(), ts2.pathLength());
0843 BOOST_CHECK_EQUAL(&ts1.referenceSurface(), &ts2.referenceSurface());
0844
0845
0846 ts2 = mkts(PM::Predicted | PM::Jacobian | PM::Calibrated);
0847 ts2.copyFrom(ots2, PM::Predicted | PM::Jacobian | PM::Calibrated);
0848
0849
0850 ts1.unset(TrackStatePropMask::Calibrated);
0851 ts1.copyFrom(ots1);
0852
0853 BOOST_CHECK_NE(ts1.predicted(), ts2.predicted());
0854 BOOST_CHECK_NE(ts1.predictedCovariance(), ts2.predictedCovariance());
0855
0856 BOOST_CHECK_NE(ts1.calibratedSize(), ts2.calibratedSize());
0857 BOOST_CHECK(ts1.projectorSubspaceIndices() !=
0858 ts2.projectorSubspaceIndices());
0859
0860 BOOST_CHECK_NE(ts1.jacobian(), ts2.jacobian());
0861 BOOST_CHECK_NE(ts1.chi2(), ts2.chi2());
0862 BOOST_CHECK_NE(ts1.pathLength(), ts2.pathLength());
0863 BOOST_CHECK_NE(&ts1.referenceSurface(), &ts2.referenceSurface());
0864
0865
0866 ts1.unset(TrackStatePropMask::Calibrated);
0867 ts1.copyFrom(ts2);
0868
0869
0870 BOOST_CHECK_EQUAL(ts1.predicted(), ts2.predicted());
0871 BOOST_CHECK_EQUAL(ts1.predictedCovariance(), ts2.predictedCovariance());
0872
0873 visit_measurement(ts1.calibratedSize(), [&](auto N) {
0874 constexpr std::size_t measdim = decltype(N)::value;
0875 BOOST_CHECK_EQUAL(ts1.template calibrated<measdim>(),
0876 ts2.template calibrated<measdim>());
0877 BOOST_CHECK_EQUAL(ts1.template calibratedCovariance<measdim>(),
0878 ts2.template calibratedCovariance<measdim>());
0879 BOOST_CHECK(ts1.template projectorSubspaceIndices<measdim>() ==
0880 ts2.template projectorSubspaceIndices<measdim>());
0881 });
0882
0883 BOOST_CHECK_EQUAL(ts1.calibratedSize(), ts2.calibratedSize());
0884 BOOST_CHECK(ts1.projectorSubspaceIndices() ==
0885 ts2.projectorSubspaceIndices());
0886
0887 BOOST_CHECK_EQUAL(ts1.jacobian(), ts2.jacobian());
0888 BOOST_CHECK_EQUAL(ts1.chi2(), ts2.chi2());
0889 BOOST_CHECK_EQUAL(ts1.pathLength(), ts2.pathLength());
0890 BOOST_CHECK_EQUAL(&ts1.referenceSurface(),
0891 &ts2.referenceSurface());
0892 }
0893
0894 void testTrackStateCopyDynamicColumns() {
0895
0896 trajectory_t mtj = m_factory.create();
0897 mtj.template addColumn<std::uint64_t>("counter");
0898 mtj.template addColumn<std::uint8_t>("odd");
0899
0900 trajectory_t mtj2 = m_factory.create();
0901
0902
0903 trajectory_t mtj3 = m_factory.create();
0904 mtj3.template addColumn<std::uint64_t>("counter");
0905 mtj3.template addColumn<std::uint8_t>("odd");
0906
0907 for (TrackIndexType i = 0; i < 10; i++) {
0908 auto ts =
0909 mtj.getTrackState(mtj.addTrackState(TrackStatePropMask::All, i));
0910 ts.template component<std::uint64_t>("counter") = i;
0911 ts.template component<std::uint8_t>("odd") = i % 2 == 0;
0912
0913 auto ts2 =
0914 mtj2.getTrackState(mtj2.addTrackState(TrackStatePropMask::All, i));
0915 BOOST_CHECK_THROW(ts2.copyFrom(ts),
0916 std::invalid_argument);
0917
0918 auto ts3 =
0919 mtj3.getTrackState(mtj3.addTrackState(TrackStatePropMask::All, i));
0920 ts3.copyFrom(ts);
0921
0922 BOOST_CHECK_NE(ts3.index(), kInvalid);
0923
0924 BOOST_CHECK_EQUAL(ts.template component<std::uint64_t>("counter"),
0925 ts3.template component<std::uint64_t>("counter"));
0926 BOOST_CHECK_EQUAL(ts.template component<std::uint8_t>("odd"),
0927 ts3.template component<std::uint8_t>("odd"));
0928 }
0929
0930 std::size_t before = mtj.size();
0931 const_trajectory_t cmtj{mtj};
0932
0933 BOOST_REQUIRE_EQUAL(cmtj.size(), before);
0934
0935 VectorMultiTrajectory mtj5;
0936 mtj5.addColumn<std::uint64_t>("counter");
0937 mtj5.addColumn<std::uint8_t>("odd");
0938
0939 for (std::size_t i = 0; i < 10; i++) {
0940 auto ts4 = cmtj.getTrackState(i);
0941
0942 auto ts5 =
0943 mtj5.getTrackState(mtj5.addTrackState(TrackStatePropMask::All, 0));
0944 ts5.copyFrom(ts4);
0945
0946 BOOST_CHECK_NE(ts5.index(), kInvalid);
0947
0948 BOOST_CHECK_EQUAL(ts4.template component<std::uint64_t>("counter"),
0949 ts5.template component<std::uint64_t>("counter"));
0950 BOOST_CHECK_EQUAL(ts4.template component<std::uint8_t>("odd"),
0951 ts5.template component<std::uint8_t>("odd"));
0952 }
0953 }
0954
0955 void testTrackStateProxyCopyDiffMTJ() {
0956 using PM = TrackStatePropMask;
0957
0958 std::array<PM, 4> values{PM::Predicted, PM::Filtered, PM::Smoothed,
0959 PM::Jacobian};
0960
0961 trajectory_t mj = m_factory.create();
0962 trajectory_t mj2 = m_factory.create();
0963 auto mkts = [&](PM mask) {
0964 auto r = mj.getTrackState(mj.addTrackState(mask));
0965 return r;
0966 };
0967 auto mkts2 = [&](PM mask) {
0968 auto r = mj2.getTrackState(mj2.addTrackState(mask));
0969 return r;
0970 };
0971
0972
0973 for (PM a : values) {
0974 for (PM b : values) {
0975 auto tsa = mkts(a);
0976 auto tsb = mkts2(b);
0977
0978 if (a != b) {
0979 BOOST_CHECK_THROW(tsa.copyFrom(tsb), std::runtime_error);
0980 BOOST_CHECK_THROW(tsb.copyFrom(tsa), std::runtime_error);
0981 } else {
0982 tsa.copyFrom(tsb);
0983 tsb.copyFrom(tsa);
0984 }
0985 }
0986 }
0987
0988
0989 BOOST_CHECK_EQUAL(mj.size(), values.size() * values.size());
0990 BOOST_CHECK_EQUAL(mj2.size(), values.size() * values.size());
0991
0992 auto ts1 = mkts(PM::Filtered | PM::Predicted);
0993 ts1.filtered().setRandom();
0994 ts1.filteredCovariance().setRandom();
0995 ts1.predicted().setRandom();
0996 ts1.predictedCovariance().setRandom();
0997
0998
0999 auto ts2 = mkts2(PM::Predicted);
1000 ts2.predicted().setRandom();
1001 ts2.predictedCovariance().setRandom();
1002
1003
1004 BOOST_CHECK_NE(ts1.predicted(), ts2.predicted());
1005 BOOST_CHECK_NE(ts1.predictedCovariance(), ts2.predictedCovariance());
1006
1007
1008 BOOST_CHECK_THROW(ts2.copyFrom(ts1), std::runtime_error);
1009 BOOST_CHECK_NE(ts1.predicted(), ts2.predicted());
1010 BOOST_CHECK_NE(ts1.predictedCovariance(), ts2.predictedCovariance());
1011
1012
1013 ts1.copyFrom(ts2);
1014 BOOST_CHECK_EQUAL(ts1.predicted(), ts2.predicted());
1015 BOOST_CHECK_EQUAL(ts1.predictedCovariance(), ts2.predictedCovariance());
1016
1017 {
1018 BOOST_TEST_CHECKPOINT("Calib auto alloc");
1019 auto tsa = mkts(PM::All);
1020 auto tsb = mkts(PM::All);
1021 tsb.allocateCalibrated(5);
1022 tsb.template calibrated<5>().setRandom();
1023 tsb.template calibratedCovariance<5>().setRandom();
1024 tsa.copyFrom(tsb, PM::All);
1025 BOOST_CHECK_EQUAL(tsa.template calibrated<5>(),
1026 tsb.template calibrated<5>());
1027 BOOST_CHECK_EQUAL(tsa.template calibratedCovariance<5>(),
1028 tsb.template calibratedCovariance<5>());
1029 }
1030
1031 {
1032 BOOST_TEST_CHECKPOINT("Copy none");
1033 auto tsa = mkts(PM::All);
1034 auto tsb = mkts(PM::All);
1035 tsa.copyFrom(tsb, PM::None);
1036 }
1037 }
1038
1039 void testProxyAssignment() {
1040 constexpr TrackStatePropMask kMask = TrackStatePropMask::Predicted;
1041 trajectory_t t = m_factory.create();
1042 auto i0 = t.addTrackState(kMask);
1043
1044 typename trajectory_t::TrackStateProxy tp = t.getTrackState(i0);
1045 typename trajectory_t::TrackStateProxy tp2{tp};
1046 static_cast<void>(tp2);
1047 typename trajectory_t::ConstTrackStateProxy tp3{tp};
1048 static_cast<void>(tp3);
1049
1050
1051 }
1052
1053 void testCopyFromConst() {
1054
1055
1056
1057 using PM = TrackStatePropMask;
1058 trajectory_t mj = m_factory.create();
1059
1060 const auto idx_a = mj.addTrackState(PM::All);
1061 const auto idx_b = mj.addTrackState(PM::All);
1062
1063 typename trajectory_t::TrackStateProxy mutableProxy =
1064 mj.getTrackState(idx_a);
1065
1066 const trajectory_t& cmj = mj;
1067 typename trajectory_t::ConstTrackStateProxy constProxy =
1068 cmj.getTrackState(idx_b);
1069
1070 mutableProxy.copyFrom(constProxy);
1071
1072
1073
1074 }
1075
1076 void testTrackStateProxyShare(std::default_random_engine& rng) {
1077 TestTrackState pc(rng, 2u);
1078
1079 {
1080 trajectory_t traj = m_factory.create();
1081 std::size_t ia = traj.addTrackState(TrackStatePropMask::All);
1082 std::size_t ib = traj.addTrackState(TrackStatePropMask::None);
1083
1084 auto tsa = traj.getTrackState(ia);
1085 auto tsb = traj.getTrackState(ib);
1086
1087 fillTrackState<trajectory_t>(pc, TrackStatePropMask::All, tsa);
1088
1089 BOOST_CHECK(tsa.hasPredicted());
1090 BOOST_CHECK(!tsb.hasPredicted());
1091 tsb.shareFrom(tsa, TrackStatePropMask::Predicted);
1092 BOOST_CHECK(tsa.hasPredicted());
1093 BOOST_CHECK(tsb.hasPredicted());
1094 BOOST_CHECK_EQUAL(tsa.predicted(), tsb.predicted());
1095 BOOST_CHECK_EQUAL(tsa.predictedCovariance(), tsb.predictedCovariance());
1096
1097 BOOST_CHECK(tsa.hasFiltered());
1098 BOOST_CHECK(!tsb.hasFiltered());
1099 tsb.shareFrom(tsa, TrackStatePropMask::Filtered);
1100 BOOST_CHECK(tsa.hasFiltered());
1101 BOOST_CHECK(tsb.hasFiltered());
1102 BOOST_CHECK_EQUAL(tsa.filtered(), tsb.filtered());
1103 BOOST_CHECK_EQUAL(tsa.filteredCovariance(), tsb.filteredCovariance());
1104
1105 BOOST_CHECK(tsa.hasSmoothed());
1106 BOOST_CHECK(!tsb.hasSmoothed());
1107 tsb.shareFrom(tsa, TrackStatePropMask::Smoothed);
1108 BOOST_CHECK(tsa.hasSmoothed());
1109 BOOST_CHECK(tsb.hasSmoothed());
1110 BOOST_CHECK_EQUAL(tsa.smoothed(), tsb.smoothed());
1111 BOOST_CHECK_EQUAL(tsa.smoothedCovariance(), tsb.smoothedCovariance());
1112
1113 BOOST_CHECK(tsa.hasJacobian());
1114 BOOST_CHECK(!tsb.hasJacobian());
1115 tsb.shareFrom(tsa, TrackStatePropMask::Jacobian);
1116 BOOST_CHECK(tsa.hasJacobian());
1117 BOOST_CHECK(tsb.hasJacobian());
1118 BOOST_CHECK_EQUAL(tsa.jacobian(), tsb.jacobian());
1119 }
1120
1121 {
1122 trajectory_t traj = m_factory.create();
1123 std::size_t i = traj.addTrackState(TrackStatePropMask::All &
1124 ~TrackStatePropMask::Filtered &
1125 ~TrackStatePropMask::Smoothed);
1126
1127 auto ts = traj.getTrackState(i);
1128
1129 BOOST_CHECK(ts.hasPredicted());
1130 BOOST_CHECK(!ts.hasFiltered());
1131 BOOST_CHECK(!ts.hasSmoothed());
1132 ts.predicted().setRandom();
1133 ts.predictedCovariance().setRandom();
1134
1135 ts.shareFrom(TrackStatePropMask::Predicted, TrackStatePropMask::Filtered);
1136 BOOST_CHECK(ts.hasPredicted());
1137 BOOST_CHECK(ts.hasFiltered());
1138 BOOST_CHECK(!ts.hasSmoothed());
1139 BOOST_CHECK_EQUAL(ts.predicted(), ts.filtered());
1140 BOOST_CHECK_EQUAL(ts.predictedCovariance(), ts.filteredCovariance());
1141
1142 ts.shareFrom(TrackStatePropMask::Predicted, TrackStatePropMask::Smoothed);
1143 BOOST_CHECK(ts.hasPredicted());
1144 BOOST_CHECK(ts.hasFiltered());
1145 BOOST_CHECK(ts.hasSmoothed());
1146 BOOST_CHECK_EQUAL(ts.predicted(), ts.filtered());
1147 BOOST_CHECK_EQUAL(ts.predicted(), ts.smoothed());
1148 BOOST_CHECK_EQUAL(ts.predictedCovariance(), ts.filteredCovariance());
1149 BOOST_CHECK_EQUAL(ts.predictedCovariance(), ts.smoothedCovariance());
1150 }
1151 }
1152
1153 void testMultiTrajectoryExtraColumns() {
1154 using namespace HashedStringLiteral;
1155
1156 auto test = [&](const std::string& col, auto value) {
1157 using T = decltype(value);
1158 std::string col2 = col + "_2";
1159 HashedString h{hashStringDynamic(col)};
1160 HashedString h2{hashStringDynamic(col2)};
1161
1162 trajectory_t traj = m_factory.create();
1163 BOOST_CHECK(!traj.hasColumn(h));
1164 traj.template addColumn<T>(col);
1165 BOOST_CHECK(traj.hasColumn(h));
1166
1167 BOOST_CHECK(!traj.hasColumn(h2));
1168 traj.template addColumn<T>(col2);
1169 BOOST_CHECK(traj.hasColumn(h2));
1170
1171 auto ts1 = traj.getTrackState(traj.addTrackState());
1172 auto ts2 = traj.getTrackState(
1173 traj.addTrackState(TrackStatePropMask::All, ts1.index()));
1174 auto ts3 = traj.getTrackState(
1175 traj.addTrackState(TrackStatePropMask::All, ts2.index()));
1176
1177 BOOST_CHECK(ts1.has(h));
1178 BOOST_CHECK(ts2.has(h));
1179 BOOST_CHECK(ts3.has(h));
1180
1181 BOOST_CHECK(ts1.has(h2));
1182 BOOST_CHECK(ts2.has(h2));
1183 BOOST_CHECK(ts3.has(h2));
1184
1185 ts1.template component<T>(col) = value;
1186 BOOST_CHECK_EQUAL(ts1.template component<T>(col), value);
1187 };
1188
1189 test("std_uint32_t", std::uint32_t{1});
1190 test("std_uint64_t", std::uint64_t{2});
1191 test("std_int32_t", std::int32_t{-3});
1192 test("std_int64_t", std::int64_t{-4});
1193 test("float", float{8.9});
1194 test("double", double{656.2});
1195
1196 trajectory_t traj = m_factory.create();
1197 traj.template addColumn<int>("extra_column");
1198 traj.template addColumn<float>("another_column");
1199
1200 auto ts1 = traj.getTrackState(traj.addTrackState());
1201 auto ts2 = traj.getTrackState(
1202 traj.addTrackState(TrackStatePropMask::All, ts1.index()));
1203 auto ts3 = traj.getTrackState(
1204 traj.addTrackState(TrackStatePropMask::All, ts2.index()));
1205
1206 BOOST_CHECK(ts1.template has<"extra_column"_hash>());
1207 BOOST_CHECK(ts2.template has<"extra_column"_hash>());
1208 BOOST_CHECK(ts3.template has<"extra_column"_hash>());
1209
1210 BOOST_CHECK(ts1.template has<"another_column"_hash>());
1211 BOOST_CHECK(ts2.template has<"another_column"_hash>());
1212 BOOST_CHECK(ts3.template has<"another_column"_hash>());
1213
1214 ts2.template component<int, "extra_column"_hash>() = 6;
1215
1216 BOOST_CHECK_EQUAL((ts2.template component<int, "extra_column"_hash>()), 6);
1217
1218 ts3.template component<float, "another_column"_hash>() = 7.2f;
1219 BOOST_CHECK_EQUAL((ts3.template component<float, "another_column"_hash>()),
1220 7.2f);
1221 }
1222
1223 void testMultiTrajectoryExtraColumnsRuntime() {
1224 auto runTest = [&](auto&& fn) {
1225 trajectory_t mt = m_factory.create();
1226 std::vector<std::string> columns = {"one", "two", "three", "four"};
1227 for (const auto& c : columns) {
1228 BOOST_CHECK(!mt.hasColumn(fn(c)));
1229 mt.template addColumn<int>(c);
1230 BOOST_CHECK(mt.hasColumn(fn(c)));
1231 }
1232 for (const auto& c : columns) {
1233 auto ts1 = mt.getTrackState(mt.addTrackState());
1234 auto ts2 = mt.getTrackState(mt.addTrackState());
1235 BOOST_CHECK(ts1.has(fn(c)));
1236 BOOST_CHECK(ts2.has(fn(c)));
1237 ts1.template component<int>(fn(c)) = 674;
1238 ts2.template component<int>(fn(c)) = 421;
1239 BOOST_CHECK_EQUAL(ts1.template component<int>(fn(c)), 674);
1240 BOOST_CHECK_EQUAL(ts2.template component<int>(fn(c)), 421);
1241 }
1242 };
1243
1244 runTest([](const std::string& c) { return hashStringDynamic(c.c_str()); });
1245
1246
1247
1248 }
1249
1250 void testMultiTrajectoryAllocateCalibratedInit(
1251 std::default_random_engine& rng) {
1252 trajectory_t traj = m_factory.create();
1253 auto ts = traj.makeTrackState(TrackStatePropMask::All);
1254
1255 BOOST_CHECK_EQUAL(ts.calibratedSize(), kInvalid);
1256
1257 auto [par, cov] = generateBoundParametersCovariance(rng, {});
1258
1259 ts.allocateCalibrated(par.head<3>(), cov.topLeftCorner<3, 3>());
1260
1261 BOOST_CHECK_EQUAL(ts.calibratedSize(), 3);
1262 BOOST_CHECK_EQUAL(ts.template calibrated<3>(), par.head<3>());
1263 BOOST_CHECK_EQUAL(ts.template calibratedCovariance<3>(),
1264 (cov.topLeftCorner<3, 3>()));
1265
1266 auto [par2, cov2] = generateBoundParametersCovariance(rng, {});
1267
1268 ts.allocateCalibrated(3);
1269 BOOST_CHECK_EQUAL(ts.template calibrated<3>(), Vector3::Zero());
1270 BOOST_CHECK_EQUAL(ts.template calibratedCovariance<3>(),
1271 SquareMatrix<3>::Zero());
1272
1273 ts.allocateCalibrated(par2.head<3>(), cov2.topLeftCorner<3, 3>());
1274 BOOST_CHECK_EQUAL(ts.calibratedSize(), 3);
1275
1276 BOOST_CHECK_EQUAL(ts.template calibrated<3>(), par2.head<3>());
1277 BOOST_CHECK_EQUAL(ts.template calibratedCovariance<3>(),
1278 (cov2.topLeftCorner<3, 3>()));
1279
1280
1281 BOOST_CHECK_THROW(
1282 ts.allocateCalibrated(par2.head<4>(), cov2.topLeftCorner<4, 4>()),
1283 std::invalid_argument);
1284 }
1285 };
1286 }