File indexing completed on 2026-07-12 07:50: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 = BoundTrackParameters::ParametersVector;
0033 using CovarianceMatrix = BoundTrackParameters::CovarianceMatrix;
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 testTrackStateProxyCrossTalk(std::default_random_engine& rng) {
0333 TestTrackState pc(rng, 2u);
0334
0335
0336 trajectory_t traj = m_factory.create();
0337 std::size_t index = traj.addTrackState();
0338 {
0339 auto ts = traj.getTrackState(index);
0340 fillTrackState<trajectory_t>(pc, TrackStatePropMask::All, ts);
0341 }
0342
0343 auto tsa = traj.getTrackState(index);
0344 auto tsb = traj.getTrackState(index);
0345
0346 {
0347 auto [par, cov] = generateBoundParametersCovariance(rng, {});
0348 tsb.predicted() = par;
0349 tsb.predictedCovariance() = cov;
0350 BOOST_CHECK_EQUAL(tsa.predicted(), par);
0351 BOOST_CHECK_EQUAL(tsa.predictedCovariance(), cov);
0352 BOOST_CHECK_EQUAL(tsb.predicted(), par);
0353 BOOST_CHECK_EQUAL(tsb.predictedCovariance(), cov);
0354 }
0355 {
0356 auto [par, cov] = generateBoundParametersCovariance(rng, {});
0357 tsb.filtered() = par;
0358 tsb.filteredCovariance() = cov;
0359 BOOST_CHECK_EQUAL(tsa.filtered(), par);
0360 BOOST_CHECK_EQUAL(tsa.filteredCovariance(), cov);
0361 BOOST_CHECK_EQUAL(tsb.filtered(), par);
0362 BOOST_CHECK_EQUAL(tsb.filteredCovariance(), cov);
0363 }
0364 {
0365 auto [par, cov] = generateBoundParametersCovariance(rng, {});
0366 tsb.smoothed() = par;
0367 tsb.smoothedCovariance() = cov;
0368 BOOST_CHECK_EQUAL(tsa.smoothed(), par);
0369 BOOST_CHECK_EQUAL(tsa.smoothedCovariance(), cov);
0370 BOOST_CHECK_EQUAL(tsb.smoothed(), par);
0371 BOOST_CHECK_EQUAL(tsb.smoothedCovariance(), cov);
0372 }
0373 {
0374
0375 TestSourceLink invalid;
0376 invalid.sourceId = -1;
0377 BOOST_CHECK_NE(
0378 tsa.getUncalibratedSourceLink().template get<TestSourceLink>(),
0379 invalid);
0380 BOOST_CHECK_NE(
0381 tsb.getUncalibratedSourceLink().template get<TestSourceLink>(),
0382 invalid);
0383 tsb.setUncalibratedSourceLink(SourceLink{invalid});
0384 BOOST_CHECK_EQUAL(
0385 tsa.getUncalibratedSourceLink().template get<TestSourceLink>(),
0386 invalid);
0387 BOOST_CHECK_EQUAL(
0388 tsb.getUncalibratedSourceLink().template get<TestSourceLink>(),
0389 invalid);
0390 }
0391 {
0392
0393 auto [measPar, measCov] = generateBoundParametersCovariance(rng, {});
0394
0395 tsb.unset(TrackStatePropMask::Calibrated);
0396 tsb.allocateCalibrated(eBoundSize);
0397 BOOST_CHECK_EQUAL(tsb.template calibrated<eBoundSize>(),
0398 BoundVector::Zero());
0399 BOOST_CHECK_EQUAL(tsb.template calibratedCovariance<eBoundSize>(),
0400 BoundMatrix::Zero());
0401 tsb.template calibrated<eBoundSize>() = measPar;
0402 tsb.template calibratedCovariance<eBoundSize>() = measCov;
0403 BOOST_CHECK_EQUAL(tsa.template calibrated<eBoundSize>(), measPar);
0404 BOOST_CHECK_EQUAL(tsa.template calibratedCovariance<eBoundSize>(),
0405 measCov);
0406 BOOST_CHECK_EQUAL(tsb.template calibrated<eBoundSize>(), measPar);
0407 BOOST_CHECK_EQUAL(tsb.template calibratedCovariance<eBoundSize>(),
0408 measCov);
0409 }
0410 {
0411
0412 auto [measPar, measCov] = generateBoundParametersCovariance(rng, {});
0413 std::size_t nMeasurements = tsb.effectiveCalibrated().rows();
0414 auto effPar = measPar.head(nMeasurements);
0415 auto effCov = measCov.topLeftCorner(nMeasurements, nMeasurements);
0416 tsb.allocateCalibrated(
0417 eBoundSize);
0418
0419 BOOST_CHECK_EQUAL(tsa.effectiveCalibrated(), BoundVector::Zero());
0420 BOOST_CHECK_EQUAL(tsa.effectiveCalibratedCovariance(),
0421 BoundMatrix::Zero());
0422 BOOST_CHECK_EQUAL(tsa.effectiveCalibrated(), BoundVector::Zero());
0423 BOOST_CHECK_EQUAL(tsa.effectiveCalibratedCovariance(),
0424 BoundMatrix::Zero());
0425 tsb.effectiveCalibrated() = effPar;
0426 tsb.effectiveCalibratedCovariance() = effCov;
0427 BOOST_CHECK_EQUAL(tsa.effectiveCalibrated(), effPar);
0428 BOOST_CHECK_EQUAL(tsa.effectiveCalibratedCovariance(), effCov);
0429 BOOST_CHECK_EQUAL(tsb.effectiveCalibrated(), effPar);
0430 BOOST_CHECK_EQUAL(tsb.effectiveCalibratedCovariance(), effCov);
0431 }
0432 {
0433 Jacobian jac = Jacobian::Identity();
0434 BOOST_CHECK_NE(tsa.jacobian(), jac);
0435 BOOST_CHECK_NE(tsb.jacobian(), jac);
0436 tsb.jacobian() = jac;
0437 BOOST_CHECK_EQUAL(tsa.jacobian(), jac);
0438 BOOST_CHECK_EQUAL(tsb.jacobian(), jac);
0439 }
0440 {
0441 tsb.chi2() = 98.0;
0442 BOOST_CHECK_EQUAL(tsa.chi2(), 98.0);
0443 BOOST_CHECK_EQUAL(tsb.chi2(), 98.0);
0444 }
0445 {
0446 tsb.pathLength() = 66.0;
0447 BOOST_CHECK_EQUAL(tsa.pathLength(), 66.0);
0448 BOOST_CHECK_EQUAL(tsb.pathLength(), 66.0);
0449 }
0450 }
0451
0452 void testTrackStateReassignment(std::default_random_engine& rng) {
0453 TestTrackState pc(rng, 1u);
0454
0455 trajectory_t t = m_factory.create();
0456 std::size_t index = t.addTrackState();
0457 auto ts = t.getTrackState(index);
0458 fillTrackState<trajectory_t>(pc, TrackStatePropMask::All, ts);
0459
0460
0461 BOOST_CHECK_EQUAL(ts.calibratedSize(), 1u);
0462 BOOST_CHECK_EQUAL(ts.effectiveCalibrated(),
0463 (pc.sourceLink.parameters.head<1>()));
0464 BOOST_CHECK_EQUAL(ts.effectiveCalibratedCovariance(),
0465 (pc.sourceLink.covariance.topLeftCorner<1, 1>()));
0466
0467
0468 TestTrackState ttsb(rng, 2u);
0469 const auto gctx = Acts::GeometryContext::dangerouslyDefaultConstruct();
0470 Acts::CalibrationContext cctx;
0471 BOOST_CHECK_EQUAL(
0472 ts.getUncalibratedSourceLink().template get<TestSourceLink>().sourceId,
0473 pc.sourceLink.sourceId);
0474
0475 ts.unset(TrackStatePropMask::Calibrated);
0476 testSourceLinkCalibrator<trajectory_t>(gctx, cctx,
0477 SourceLink{ttsb.sourceLink}, ts);
0478 BOOST_CHECK_EQUAL(
0479 ts.getUncalibratedSourceLink().template get<TestSourceLink>().sourceId,
0480 ttsb.sourceLink.sourceId);
0481
0482 BOOST_CHECK_EQUAL(ts.calibratedSize(), 2);
0483 BOOST_CHECK_EQUAL(ts.effectiveCalibrated(), ttsb.sourceLink.parameters);
0484 BOOST_CHECK_EQUAL(ts.effectiveCalibratedCovariance(),
0485 ttsb.sourceLink.covariance);
0486 }
0487
0488 void testTrackStateProxyStorage(std::default_random_engine& rng,
0489 std::size_t nMeasurements) {
0490 TestTrackState pc(rng, nMeasurements);
0491
0492
0493 trajectory_t t = m_factory.create();
0494 std::size_t index = t.addTrackState();
0495 auto ts = t.getTrackState(index);
0496 fillTrackState<trajectory_t>(pc, TrackStatePropMask::All, ts);
0497
0498
0499 BOOST_CHECK_EQUAL(&ts.referenceSurface(), pc.surface.get());
0500 BOOST_CHECK_EQUAL(ts.referenceSurface().geometryId(),
0501 pc.sourceLink.m_geometryId);
0502
0503
0504 BOOST_CHECK(ts.hasPredicted());
0505 BOOST_CHECK_EQUAL(ts.predicted(), pc.predicted.parameters());
0506 BOOST_CHECK(pc.predicted.covariance().has_value());
0507 BOOST_CHECK_EQUAL(ts.predictedCovariance(), *pc.predicted.covariance());
0508 BOOST_CHECK(ts.hasFiltered());
0509 BOOST_CHECK_EQUAL(ts.filtered(), pc.filtered.parameters());
0510 BOOST_CHECK(pc.filtered.covariance().has_value());
0511 BOOST_CHECK_EQUAL(ts.filteredCovariance(), *pc.filtered.covariance());
0512 BOOST_CHECK(ts.hasSmoothed());
0513 BOOST_CHECK_EQUAL(ts.smoothed(), pc.smoothed.parameters());
0514 BOOST_CHECK(pc.smoothed.covariance().has_value());
0515 BOOST_CHECK_EQUAL(ts.smoothedCovariance(), *pc.smoothed.covariance());
0516
0517
0518 BOOST_CHECK(ts.hasJacobian());
0519 BOOST_CHECK_EQUAL(ts.jacobian(), pc.jacobian);
0520 BOOST_CHECK_EQUAL(ts.pathLength(), pc.pathLength);
0521
0522 BOOST_CHECK_EQUAL(ts.chi2(), static_cast<float>(pc.chi2));
0523
0524
0525 BOOST_CHECK_EQUAL(
0526 ts.getUncalibratedSourceLink().template get<TestSourceLink>(),
0527 pc.sourceLink);
0528
0529
0530 BOOST_CHECK(ts.hasCalibrated());
0531 BOOST_CHECK_EQUAL(ts.effectiveCalibrated(),
0532 pc.sourceLink.parameters.head(nMeasurements));
0533 BOOST_CHECK_EQUAL(
0534 ts.effectiveCalibratedCovariance(),
0535 pc.sourceLink.covariance.topLeftCorner(nMeasurements, nMeasurements));
0536 {
0537 ParametersVector mParFull = ParametersVector::Zero();
0538 CovarianceMatrix mCovFull = CovarianceMatrix::Zero();
0539 mParFull.head(nMeasurements) =
0540 pc.sourceLink.parameters.head(nMeasurements);
0541 mCovFull.topLeftCorner(nMeasurements, nMeasurements) =
0542 pc.sourceLink.covariance.topLeftCorner(nMeasurements, nMeasurements);
0543
0544 auto expMeas = pc.sourceLink.parameters.head(nMeasurements);
0545 auto expCov =
0546 pc.sourceLink.covariance.topLeftCorner(nMeasurements, nMeasurements);
0547
0548 visit_measurement(ts.calibratedSize(), [&](auto N) {
0549 constexpr std::size_t measdim = decltype(N)::value;
0550 BOOST_CHECK_EQUAL(ts.template calibrated<measdim>(), expMeas);
0551 BOOST_CHECK_EQUAL(ts.template calibratedCovariance<measdim>(), expCov);
0552 });
0553 }
0554 }
0555
0556 void testTrackStateProxyAllocations(std::default_random_engine& rng) {
0557 using namespace Acts::HashedStringLiteral;
0558
0559 TestTrackState pc(rng, 2u);
0560
0561
0562 trajectory_t t = m_factory.create();
0563 std::size_t i = t.addTrackState(TrackStatePropMask::Predicted |
0564 TrackStatePropMask::Filtered |
0565 TrackStatePropMask::Jacobian);
0566 auto tso = t.getTrackState(i);
0567 fillTrackState<trajectory_t>(pc, TrackStatePropMask::Predicted, tso);
0568 fillTrackState<trajectory_t>(pc, TrackStatePropMask::Filtered, tso);
0569 fillTrackState<trajectory_t>(pc, TrackStatePropMask::Jacobian, tso);
0570
0571 BOOST_CHECK(tso.hasPredicted());
0572 BOOST_CHECK(tso.hasFiltered());
0573 BOOST_CHECK(!tso.hasSmoothed());
0574 BOOST_CHECK(!tso.hasCalibrated());
0575 BOOST_CHECK(tso.hasJacobian());
0576
0577 auto tsnone = t.getTrackState(t.addTrackState(TrackStatePropMask::None));
0578 BOOST_CHECK(!tsnone.template has<"predicted"_hash>());
0579 BOOST_CHECK(!tsnone.template has<"filtered"_hash>());
0580 BOOST_CHECK(!tsnone.template has<"smoothed"_hash>());
0581 BOOST_CHECK(!tsnone.template has<"jacobian"_hash>());
0582 BOOST_CHECK(!tsnone.template has<"calibrated"_hash>());
0583 BOOST_CHECK(!tsnone.template has<"projector"_hash>());
0584 BOOST_CHECK(
0585 !tsnone.template has<"uncalibratedSourceLink"_hash>());
0586
0587
0588 BOOST_CHECK(tsnone.template has<"referenceSurface"_hash>());
0589 BOOST_CHECK(tsnone.template has<"measdim"_hash>());
0590 BOOST_CHECK(tsnone.template has<"chi2"_hash>());
0591 BOOST_CHECK(tsnone.template has<"pathLength"_hash>());
0592 BOOST_CHECK(tsnone.template has<"typeFlags"_hash>());
0593
0594 auto tsall = t.getTrackState(t.addTrackState(TrackStatePropMask::All));
0595 BOOST_CHECK(tsall.template has<"predicted"_hash>());
0596 BOOST_CHECK(tsall.template has<"filtered"_hash>());
0597 BOOST_CHECK(tsall.template has<"smoothed"_hash>());
0598 BOOST_CHECK(tsall.template has<"jacobian"_hash>());
0599 BOOST_CHECK(!tsall.template has<"calibrated"_hash>());
0600 tsall.allocateCalibrated(5);
0601 BOOST_CHECK(tsall.template has<"calibrated"_hash>());
0602 BOOST_CHECK(tsall.template has<"projector"_hash>());
0603 BOOST_CHECK(!tsall.template has<
0604 "uncalibratedSourceLink"_hash>());
0605
0606 BOOST_CHECK(tsall.template has<"referenceSurface"_hash>());
0607 BOOST_CHECK(tsall.template has<"measdim"_hash>());
0608 BOOST_CHECK(tsall.template has<"chi2"_hash>());
0609 BOOST_CHECK(tsall.template has<"pathLength"_hash>());
0610 BOOST_CHECK(tsall.template has<"typeFlags"_hash>());
0611
0612 tsall.unset(TrackStatePropMask::Predicted);
0613 BOOST_CHECK(!tsall.template has<"predicted"_hash>());
0614 tsall.unset(TrackStatePropMask::Filtered);
0615 BOOST_CHECK(!tsall.template has<"filtered"_hash>());
0616 tsall.unset(TrackStatePropMask::Smoothed);
0617 BOOST_CHECK(!tsall.template has<"smoothed"_hash>());
0618 tsall.unset(TrackStatePropMask::Jacobian);
0619 BOOST_CHECK(!tsall.template has<"jacobian"_hash>());
0620 tsall.unset(TrackStatePropMask::Calibrated);
0621 BOOST_CHECK(!tsall.template has<"calibrated"_hash>());
0622 }
0623
0624 void testTrackStateProxyGetMask() {
0625 using PM = TrackStatePropMask;
0626
0627 std::array<PM, 5> values{PM::Predicted, PM::Filtered, PM::Smoothed,
0628 PM::Jacobian, PM::Calibrated};
0629 PM all = std::accumulate(values.begin(), values.end(), PM::None,
0630 [](auto a, auto b) { return a | b; });
0631
0632 trajectory_t mj = m_factory.create();
0633 {
0634 auto ts = mj.getTrackState(mj.addTrackState(PM::All));
0635
0636 BOOST_CHECK_EQUAL(ts.getMask(), (all & ~PM::Calibrated));
0637 ts.allocateCalibrated(4);
0638 BOOST_CHECK_EQUAL(ts.getMask(), all);
0639 }
0640 {
0641 auto ts =
0642 mj.getTrackState(mj.addTrackState(PM::Filtered | PM::Calibrated));
0643
0644 BOOST_CHECK_EQUAL(ts.getMask(), PM::Filtered);
0645 ts.allocateCalibrated(4);
0646 BOOST_CHECK_EQUAL(ts.getMask(), (PM::Filtered | PM::Calibrated));
0647 }
0648 {
0649 auto ts = mj.getTrackState(
0650 mj.addTrackState(PM::Filtered | PM::Smoothed | PM::Predicted));
0651 BOOST_CHECK_EQUAL(ts.getMask(),
0652 (PM::Filtered | PM::Smoothed | PM::Predicted));
0653 }
0654 {
0655 for (PM mask : values) {
0656 auto ts = mj.getTrackState(mj.addTrackState(mask));
0657
0658 BOOST_CHECK_EQUAL(ts.getMask(), (mask & ~PM::Calibrated));
0659 }
0660 }
0661 }
0662
0663 void testTrackStateProxyCopy(std::default_random_engine& rng) {
0664 using PM = TrackStatePropMask;
0665
0666 std::array<PM, 4> values{PM::Predicted, PM::Filtered, PM::Smoothed,
0667 PM::Jacobian};
0668
0669 trajectory_t mj = m_factory.create();
0670 auto mkts = [&](PM mask) {
0671 auto r = mj.getTrackState(mj.addTrackState(mask));
0672 return r;
0673 };
0674
0675
0676 for (PM a : values) {
0677 for (PM b : values) {
0678 auto tsa = mkts(a);
0679 auto tsb = mkts(b);
0680
0681 if (a != b) {
0682 BOOST_CHECK_THROW(tsa.copyFrom(tsb), std::runtime_error);
0683 BOOST_CHECK_THROW(tsb.copyFrom(tsa), std::runtime_error);
0684 } else {
0685 tsa.copyFrom(tsb);
0686 tsb.copyFrom(tsa);
0687 }
0688 }
0689 }
0690
0691 {
0692 BOOST_TEST_CHECKPOINT("Calib auto alloc");
0693 auto tsa = mkts(PM::All);
0694 auto tsb = mkts(PM::All);
0695 tsb.allocateCalibrated(5);
0696 tsb.template calibrated<5>().setRandom();
0697 tsb.template calibratedCovariance<5>().setRandom();
0698 tsa.copyFrom(tsb, PM::All);
0699 BOOST_CHECK_EQUAL(tsa.template calibrated<5>(),
0700 tsb.template calibrated<5>());
0701 BOOST_CHECK_EQUAL(tsa.template calibratedCovariance<5>(),
0702 tsb.template calibratedCovariance<5>());
0703 }
0704
0705 {
0706 BOOST_TEST_CHECKPOINT("Copy none");
0707 auto tsa = mkts(PM::All);
0708 auto tsb = mkts(PM::All);
0709 tsa.copyFrom(tsb, PM::None);
0710 }
0711
0712 auto ts1 = mkts(PM::Filtered | PM::Predicted);
0713 ts1.filtered().setRandom();
0714 ts1.filteredCovariance().setRandom();
0715 ts1.predicted().setRandom();
0716 ts1.predictedCovariance().setRandom();
0717
0718
0719 auto ts2 = mkts(PM::Predicted);
0720 ts2.predicted().setRandom();
0721 ts2.predictedCovariance().setRandom();
0722
0723
0724 BOOST_CHECK_NE(ts1.predicted(), ts2.predicted());
0725 BOOST_CHECK_NE(ts1.predictedCovariance(), ts2.predictedCovariance());
0726
0727
0728 BOOST_CHECK_THROW(ts2.copyFrom(ts1), std::runtime_error);
0729 BOOST_CHECK_NE(ts1.predicted(), ts2.predicted());
0730 BOOST_CHECK_NE(ts1.predictedCovariance(), ts2.predictedCovariance());
0731
0732
0733 ts1.copyFrom(ts2);
0734 BOOST_CHECK_EQUAL(ts1.predicted(), ts2.predicted());
0735 BOOST_CHECK_EQUAL(ts1.predictedCovariance(), ts2.predictedCovariance());
0736
0737 std::size_t i0 = mj.addTrackState();
0738 std::size_t i1 = mj.addTrackState();
0739 ts1 = mj.getTrackState(i0);
0740 ts2 = mj.getTrackState(i1);
0741 TestTrackState rts1(rng, 1u);
0742 TestTrackState rts2(rng, 2u);
0743 fillTrackState<trajectory_t>(rts1, TrackStatePropMask::All, ts1);
0744 fillTrackState<trajectory_t>(rts2, TrackStatePropMask::All, ts2);
0745
0746 auto ots1 = mkts(PM::All);
0747 auto ots2 = mkts(PM::All);
0748
0749 ots1.copyFrom(ts1);
0750 ots2.copyFrom(ts2);
0751
0752 BOOST_CHECK_NE(ts1.predicted(), ts2.predicted());
0753 BOOST_CHECK_NE(ts1.predictedCovariance(), ts2.predictedCovariance());
0754 BOOST_CHECK_NE(ts1.filtered(), ts2.filtered());
0755 BOOST_CHECK_NE(ts1.filteredCovariance(), ts2.filteredCovariance());
0756 BOOST_CHECK_NE(ts1.smoothed(), ts2.smoothed());
0757 BOOST_CHECK_NE(ts1.smoothedCovariance(), ts2.smoothedCovariance());
0758
0759 BOOST_CHECK_NE(
0760 ts1.getUncalibratedSourceLink().template get<TestSourceLink>(),
0761 ts2.getUncalibratedSourceLink().template get<TestSourceLink>());
0762
0763 BOOST_CHECK_NE(ts1.calibratedSize(), ts2.calibratedSize());
0764 BOOST_CHECK(ts1.projectorSubspaceIndices() !=
0765 ts2.projectorSubspaceIndices());
0766
0767 BOOST_CHECK_NE(ts1.jacobian(), ts2.jacobian());
0768 BOOST_CHECK_NE(ts1.chi2(), ts2.chi2());
0769 BOOST_CHECK_NE(ts1.pathLength(), ts2.pathLength());
0770 BOOST_CHECK_NE(&ts1.referenceSurface(), &ts2.referenceSurface());
0771
0772
0773 ts1.unset(TrackStatePropMask::Calibrated);
0774 ts1.copyFrom(ts2);
0775
0776 BOOST_CHECK_EQUAL(ts1.predicted(), ts2.predicted());
0777 BOOST_CHECK_EQUAL(ts1.predictedCovariance(), ts2.predictedCovariance());
0778 BOOST_CHECK_EQUAL(ts1.filtered(), ts2.filtered());
0779 BOOST_CHECK_EQUAL(ts1.filteredCovariance(), ts2.filteredCovariance());
0780 BOOST_CHECK_EQUAL(ts1.smoothed(), ts2.smoothed());
0781 BOOST_CHECK_EQUAL(ts1.smoothedCovariance(), ts2.smoothedCovariance());
0782
0783 BOOST_CHECK_EQUAL(
0784 ts1.getUncalibratedSourceLink().template get<TestSourceLink>(),
0785 ts2.getUncalibratedSourceLink().template get<TestSourceLink>());
0786
0787 visit_measurement(ts1.calibratedSize(), [&](auto N) {
0788 constexpr std::size_t measdim = decltype(N)::value;
0789 BOOST_CHECK_EQUAL(ts1.template calibrated<measdim>(),
0790 ts2.template calibrated<measdim>());
0791 BOOST_CHECK_EQUAL(ts1.template calibratedCovariance<measdim>(),
0792 ts2.template calibratedCovariance<measdim>());
0793 BOOST_CHECK(ts1.template projectorSubspaceIndices<measdim>() ==
0794 ts2.template projectorSubspaceIndices<measdim>());
0795 });
0796
0797 BOOST_CHECK_EQUAL(ts1.calibratedSize(), ts2.calibratedSize());
0798 BOOST_CHECK(ts1.projectorSubspaceIndices() ==
0799 ts2.projectorSubspaceIndices());
0800
0801 BOOST_CHECK_EQUAL(ts1.jacobian(), ts2.jacobian());
0802 BOOST_CHECK_EQUAL(ts1.chi2(), ts2.chi2());
0803 BOOST_CHECK_EQUAL(ts1.pathLength(), ts2.pathLength());
0804 BOOST_CHECK_EQUAL(&ts1.referenceSurface(), &ts2.referenceSurface());
0805
0806
0807 ts2 = mkts(PM::Predicted | PM::Jacobian | PM::Calibrated);
0808 ts2.copyFrom(ots2, PM::Predicted | PM::Jacobian | PM::Calibrated);
0809
0810
0811 ts1.unset(TrackStatePropMask::Calibrated);
0812 ts1.copyFrom(ots1);
0813
0814 BOOST_CHECK_NE(ts1.predicted(), ts2.predicted());
0815 BOOST_CHECK_NE(ts1.predictedCovariance(), ts2.predictedCovariance());
0816
0817 BOOST_CHECK_NE(ts1.calibratedSize(), ts2.calibratedSize());
0818 BOOST_CHECK(ts1.projectorSubspaceIndices() !=
0819 ts2.projectorSubspaceIndices());
0820
0821 BOOST_CHECK_NE(ts1.jacobian(), ts2.jacobian());
0822 BOOST_CHECK_NE(ts1.chi2(), ts2.chi2());
0823 BOOST_CHECK_NE(ts1.pathLength(), ts2.pathLength());
0824 BOOST_CHECK_NE(&ts1.referenceSurface(), &ts2.referenceSurface());
0825
0826
0827 ts1.unset(TrackStatePropMask::Calibrated);
0828 ts1.copyFrom(ts2);
0829
0830
0831 BOOST_CHECK_EQUAL(ts1.predicted(), ts2.predicted());
0832 BOOST_CHECK_EQUAL(ts1.predictedCovariance(), ts2.predictedCovariance());
0833
0834 visit_measurement(ts1.calibratedSize(), [&](auto N) {
0835 constexpr std::size_t measdim = decltype(N)::value;
0836 BOOST_CHECK_EQUAL(ts1.template calibrated<measdim>(),
0837 ts2.template calibrated<measdim>());
0838 BOOST_CHECK_EQUAL(ts1.template calibratedCovariance<measdim>(),
0839 ts2.template calibratedCovariance<measdim>());
0840 BOOST_CHECK(ts1.template projectorSubspaceIndices<measdim>() ==
0841 ts2.template projectorSubspaceIndices<measdim>());
0842 });
0843
0844 BOOST_CHECK_EQUAL(ts1.calibratedSize(), ts2.calibratedSize());
0845 BOOST_CHECK(ts1.projectorSubspaceIndices() ==
0846 ts2.projectorSubspaceIndices());
0847
0848 BOOST_CHECK_EQUAL(ts1.jacobian(), ts2.jacobian());
0849 BOOST_CHECK_EQUAL(ts1.chi2(), ts2.chi2());
0850 BOOST_CHECK_EQUAL(ts1.pathLength(), ts2.pathLength());
0851 BOOST_CHECK_EQUAL(&ts1.referenceSurface(),
0852 &ts2.referenceSurface());
0853 }
0854
0855 void testTrackStateCopyDynamicColumns() {
0856
0857 trajectory_t mtj = m_factory.create();
0858 mtj.template addColumn<std::uint64_t>("counter");
0859 mtj.template addColumn<std::uint8_t>("odd");
0860
0861 trajectory_t mtj2 = m_factory.create();
0862
0863
0864 trajectory_t mtj3 = m_factory.create();
0865 mtj3.template addColumn<std::uint64_t>("counter");
0866 mtj3.template addColumn<std::uint8_t>("odd");
0867
0868 for (TrackIndexType i = 0; i < 10; i++) {
0869 auto ts =
0870 mtj.getTrackState(mtj.addTrackState(TrackStatePropMask::All, i));
0871 ts.template component<std::uint64_t>("counter") = i;
0872 ts.template component<std::uint8_t>("odd") = i % 2 == 0;
0873
0874 auto ts2 =
0875 mtj2.getTrackState(mtj2.addTrackState(TrackStatePropMask::All, i));
0876 BOOST_CHECK_THROW(ts2.copyFrom(ts),
0877 std::invalid_argument);
0878
0879 auto ts3 =
0880 mtj3.getTrackState(mtj3.addTrackState(TrackStatePropMask::All, i));
0881 ts3.copyFrom(ts);
0882
0883 BOOST_CHECK_NE(ts3.index(), kInvalid);
0884
0885 BOOST_CHECK_EQUAL(ts.template component<std::uint64_t>("counter"),
0886 ts3.template component<std::uint64_t>("counter"));
0887 BOOST_CHECK_EQUAL(ts.template component<std::uint8_t>("odd"),
0888 ts3.template component<std::uint8_t>("odd"));
0889 }
0890
0891 std::size_t before = mtj.size();
0892 const_trajectory_t cmtj{mtj};
0893
0894 BOOST_REQUIRE_EQUAL(cmtj.size(), before);
0895
0896 VectorMultiTrajectory mtj5;
0897 mtj5.addColumn<std::uint64_t>("counter");
0898 mtj5.addColumn<std::uint8_t>("odd");
0899
0900 for (std::size_t i = 0; i < 10; i++) {
0901 auto ts4 = cmtj.getTrackState(i);
0902
0903 auto ts5 =
0904 mtj5.getTrackState(mtj5.addTrackState(TrackStatePropMask::All, 0));
0905 ts5.copyFrom(ts4);
0906
0907 BOOST_CHECK_NE(ts5.index(), kInvalid);
0908
0909 BOOST_CHECK_EQUAL(ts4.template component<std::uint64_t>("counter"),
0910 ts5.template component<std::uint64_t>("counter"));
0911 BOOST_CHECK_EQUAL(ts4.template component<std::uint8_t>("odd"),
0912 ts5.template component<std::uint8_t>("odd"));
0913 }
0914 }
0915
0916 void testTrackStateProxyCopyDiffMTJ() {
0917 using PM = TrackStatePropMask;
0918
0919 std::array<PM, 4> values{PM::Predicted, PM::Filtered, PM::Smoothed,
0920 PM::Jacobian};
0921
0922 trajectory_t mj = m_factory.create();
0923 trajectory_t mj2 = m_factory.create();
0924 auto mkts = [&](PM mask) {
0925 auto r = mj.getTrackState(mj.addTrackState(mask));
0926 return r;
0927 };
0928 auto mkts2 = [&](PM mask) {
0929 auto r = mj2.getTrackState(mj2.addTrackState(mask));
0930 return r;
0931 };
0932
0933
0934 for (PM a : values) {
0935 for (PM b : values) {
0936 auto tsa = mkts(a);
0937 auto tsb = mkts2(b);
0938
0939 if (a != b) {
0940 BOOST_CHECK_THROW(tsa.copyFrom(tsb), std::runtime_error);
0941 BOOST_CHECK_THROW(tsb.copyFrom(tsa), std::runtime_error);
0942 } else {
0943 tsa.copyFrom(tsb);
0944 tsb.copyFrom(tsa);
0945 }
0946 }
0947 }
0948
0949
0950 BOOST_CHECK_EQUAL(mj.size(), values.size() * values.size());
0951 BOOST_CHECK_EQUAL(mj2.size(), values.size() * values.size());
0952
0953 auto ts1 = mkts(PM::Filtered | PM::Predicted);
0954 ts1.filtered().setRandom();
0955 ts1.filteredCovariance().setRandom();
0956 ts1.predicted().setRandom();
0957 ts1.predictedCovariance().setRandom();
0958
0959
0960 auto ts2 = mkts2(PM::Predicted);
0961 ts2.predicted().setRandom();
0962 ts2.predictedCovariance().setRandom();
0963
0964
0965 BOOST_CHECK_NE(ts1.predicted(), ts2.predicted());
0966 BOOST_CHECK_NE(ts1.predictedCovariance(), ts2.predictedCovariance());
0967
0968
0969 BOOST_CHECK_THROW(ts2.copyFrom(ts1), std::runtime_error);
0970 BOOST_CHECK_NE(ts1.predicted(), ts2.predicted());
0971 BOOST_CHECK_NE(ts1.predictedCovariance(), ts2.predictedCovariance());
0972
0973
0974 ts1.copyFrom(ts2);
0975 BOOST_CHECK_EQUAL(ts1.predicted(), ts2.predicted());
0976 BOOST_CHECK_EQUAL(ts1.predictedCovariance(), ts2.predictedCovariance());
0977
0978 {
0979 BOOST_TEST_CHECKPOINT("Calib auto alloc");
0980 auto tsa = mkts(PM::All);
0981 auto tsb = mkts(PM::All);
0982 tsb.allocateCalibrated(5);
0983 tsb.template calibrated<5>().setRandom();
0984 tsb.template calibratedCovariance<5>().setRandom();
0985 tsa.copyFrom(tsb, PM::All);
0986 BOOST_CHECK_EQUAL(tsa.template calibrated<5>(),
0987 tsb.template calibrated<5>());
0988 BOOST_CHECK_EQUAL(tsa.template calibratedCovariance<5>(),
0989 tsb.template calibratedCovariance<5>());
0990 }
0991
0992 {
0993 BOOST_TEST_CHECKPOINT("Copy none");
0994 auto tsa = mkts(PM::All);
0995 auto tsb = mkts(PM::All);
0996 tsa.copyFrom(tsb, PM::None);
0997 }
0998 }
0999
1000 void testProxyAssignment() {
1001 constexpr TrackStatePropMask kMask = TrackStatePropMask::Predicted;
1002 trajectory_t t = m_factory.create();
1003 auto i0 = t.addTrackState(kMask);
1004
1005 typename trajectory_t::TrackStateProxy tp = t.getTrackState(i0);
1006 typename trajectory_t::TrackStateProxy tp2{tp};
1007 static_cast<void>(tp2);
1008 typename trajectory_t::ConstTrackStateProxy tp3{tp};
1009 static_cast<void>(tp3);
1010
1011
1012 }
1013
1014 void testCopyFromConst() {
1015
1016
1017
1018 using PM = TrackStatePropMask;
1019 trajectory_t mj = m_factory.create();
1020
1021 const auto idx_a = mj.addTrackState(PM::All);
1022 const auto idx_b = mj.addTrackState(PM::All);
1023
1024 typename trajectory_t::TrackStateProxy mutableProxy =
1025 mj.getTrackState(idx_a);
1026
1027 const trajectory_t& cmj = mj;
1028 typename trajectory_t::ConstTrackStateProxy constProxy =
1029 cmj.getTrackState(idx_b);
1030
1031 mutableProxy.copyFrom(constProxy);
1032
1033
1034
1035 }
1036
1037 void testTrackStateProxyShare(std::default_random_engine& rng) {
1038 TestTrackState pc(rng, 2u);
1039
1040 {
1041 trajectory_t traj = m_factory.create();
1042 std::size_t ia = traj.addTrackState(TrackStatePropMask::All);
1043 std::size_t ib = traj.addTrackState(TrackStatePropMask::None);
1044
1045 auto tsa = traj.getTrackState(ia);
1046 auto tsb = traj.getTrackState(ib);
1047
1048 fillTrackState<trajectory_t>(pc, TrackStatePropMask::All, tsa);
1049
1050 BOOST_CHECK(tsa.hasPredicted());
1051 BOOST_CHECK(!tsb.hasPredicted());
1052 tsb.shareFrom(tsa, TrackStatePropMask::Predicted);
1053 BOOST_CHECK(tsa.hasPredicted());
1054 BOOST_CHECK(tsb.hasPredicted());
1055 BOOST_CHECK_EQUAL(tsa.predicted(), tsb.predicted());
1056 BOOST_CHECK_EQUAL(tsa.predictedCovariance(), tsb.predictedCovariance());
1057
1058 BOOST_CHECK(tsa.hasFiltered());
1059 BOOST_CHECK(!tsb.hasFiltered());
1060 tsb.shareFrom(tsa, TrackStatePropMask::Filtered);
1061 BOOST_CHECK(tsa.hasFiltered());
1062 BOOST_CHECK(tsb.hasFiltered());
1063 BOOST_CHECK_EQUAL(tsa.filtered(), tsb.filtered());
1064 BOOST_CHECK_EQUAL(tsa.filteredCovariance(), tsb.filteredCovariance());
1065
1066 BOOST_CHECK(tsa.hasSmoothed());
1067 BOOST_CHECK(!tsb.hasSmoothed());
1068 tsb.shareFrom(tsa, TrackStatePropMask::Smoothed);
1069 BOOST_CHECK(tsa.hasSmoothed());
1070 BOOST_CHECK(tsb.hasSmoothed());
1071 BOOST_CHECK_EQUAL(tsa.smoothed(), tsb.smoothed());
1072 BOOST_CHECK_EQUAL(tsa.smoothedCovariance(), tsb.smoothedCovariance());
1073
1074 BOOST_CHECK(tsa.hasJacobian());
1075 BOOST_CHECK(!tsb.hasJacobian());
1076 tsb.shareFrom(tsa, TrackStatePropMask::Jacobian);
1077 BOOST_CHECK(tsa.hasJacobian());
1078 BOOST_CHECK(tsb.hasJacobian());
1079 BOOST_CHECK_EQUAL(tsa.jacobian(), tsb.jacobian());
1080 }
1081
1082 {
1083 trajectory_t traj = m_factory.create();
1084 std::size_t i = traj.addTrackState(TrackStatePropMask::All &
1085 ~TrackStatePropMask::Filtered &
1086 ~TrackStatePropMask::Smoothed);
1087
1088 auto ts = traj.getTrackState(i);
1089
1090 BOOST_CHECK(ts.hasPredicted());
1091 BOOST_CHECK(!ts.hasFiltered());
1092 BOOST_CHECK(!ts.hasSmoothed());
1093 ts.predicted().setRandom();
1094 ts.predictedCovariance().setRandom();
1095
1096 ts.shareFrom(TrackStatePropMask::Predicted, TrackStatePropMask::Filtered);
1097 BOOST_CHECK(ts.hasPredicted());
1098 BOOST_CHECK(ts.hasFiltered());
1099 BOOST_CHECK(!ts.hasSmoothed());
1100 BOOST_CHECK_EQUAL(ts.predicted(), ts.filtered());
1101 BOOST_CHECK_EQUAL(ts.predictedCovariance(), ts.filteredCovariance());
1102
1103 ts.shareFrom(TrackStatePropMask::Predicted, TrackStatePropMask::Smoothed);
1104 BOOST_CHECK(ts.hasPredicted());
1105 BOOST_CHECK(ts.hasFiltered());
1106 BOOST_CHECK(ts.hasSmoothed());
1107 BOOST_CHECK_EQUAL(ts.predicted(), ts.filtered());
1108 BOOST_CHECK_EQUAL(ts.predicted(), ts.smoothed());
1109 BOOST_CHECK_EQUAL(ts.predictedCovariance(), ts.filteredCovariance());
1110 BOOST_CHECK_EQUAL(ts.predictedCovariance(), ts.smoothedCovariance());
1111 }
1112 }
1113
1114 void testMultiTrajectoryExtraColumns() {
1115 using namespace HashedStringLiteral;
1116
1117 auto test = [&](const std::string& col, auto value) {
1118 using T = decltype(value);
1119 std::string col2 = col + "_2";
1120 HashedString h{hashStringDynamic(col)};
1121 HashedString h2{hashStringDynamic(col2)};
1122
1123 trajectory_t traj = m_factory.create();
1124 BOOST_CHECK(!traj.hasColumn(h));
1125 traj.template addColumn<T>(col);
1126 BOOST_CHECK(traj.hasColumn(h));
1127
1128 BOOST_CHECK(!traj.hasColumn(h2));
1129 traj.template addColumn<T>(col2);
1130 BOOST_CHECK(traj.hasColumn(h2));
1131
1132 auto ts1 = traj.getTrackState(traj.addTrackState());
1133 auto ts2 = traj.getTrackState(
1134 traj.addTrackState(TrackStatePropMask::All, ts1.index()));
1135 auto ts3 = traj.getTrackState(
1136 traj.addTrackState(TrackStatePropMask::All, ts2.index()));
1137
1138 BOOST_CHECK(ts1.has(h));
1139 BOOST_CHECK(ts2.has(h));
1140 BOOST_CHECK(ts3.has(h));
1141
1142 BOOST_CHECK(ts1.has(h2));
1143 BOOST_CHECK(ts2.has(h2));
1144 BOOST_CHECK(ts3.has(h2));
1145
1146 ts1.template component<T>(col) = value;
1147 BOOST_CHECK_EQUAL(ts1.template component<T>(col), value);
1148 };
1149
1150 test("std_uint32_t", std::uint32_t{1});
1151 test("std_uint64_t", std::uint64_t{2});
1152 test("std_int32_t", std::int32_t{-3});
1153 test("std_int64_t", std::int64_t{-4});
1154 test("float", float{8.9});
1155 test("double", double{656.2});
1156
1157 trajectory_t traj = m_factory.create();
1158 traj.template addColumn<int>("extra_column");
1159 traj.template addColumn<float>("another_column");
1160
1161 auto ts1 = traj.getTrackState(traj.addTrackState());
1162 auto ts2 = traj.getTrackState(
1163 traj.addTrackState(TrackStatePropMask::All, ts1.index()));
1164 auto ts3 = traj.getTrackState(
1165 traj.addTrackState(TrackStatePropMask::All, ts2.index()));
1166
1167 BOOST_CHECK(ts1.template has<"extra_column"_hash>());
1168 BOOST_CHECK(ts2.template has<"extra_column"_hash>());
1169 BOOST_CHECK(ts3.template has<"extra_column"_hash>());
1170
1171 BOOST_CHECK(ts1.template has<"another_column"_hash>());
1172 BOOST_CHECK(ts2.template has<"another_column"_hash>());
1173 BOOST_CHECK(ts3.template has<"another_column"_hash>());
1174
1175 ts2.template component<int, "extra_column"_hash>() = 6;
1176
1177 BOOST_CHECK_EQUAL((ts2.template component<int, "extra_column"_hash>()), 6);
1178
1179 ts3.template component<float, "another_column"_hash>() = 7.2f;
1180 BOOST_CHECK_EQUAL((ts3.template component<float, "another_column"_hash>()),
1181 7.2f);
1182 }
1183
1184 void testMultiTrajectoryExtraColumnsRuntime() {
1185 auto runTest = [&](auto&& fn) {
1186 trajectory_t mt = m_factory.create();
1187 std::vector<std::string> columns = {"one", "two", "three", "four"};
1188 for (const auto& c : columns) {
1189 BOOST_CHECK(!mt.hasColumn(fn(c)));
1190 mt.template addColumn<int>(c);
1191 BOOST_CHECK(mt.hasColumn(fn(c)));
1192 }
1193 for (const auto& c : columns) {
1194 auto ts1 = mt.getTrackState(mt.addTrackState());
1195 auto ts2 = mt.getTrackState(mt.addTrackState());
1196 BOOST_CHECK(ts1.has(fn(c)));
1197 BOOST_CHECK(ts2.has(fn(c)));
1198 ts1.template component<int>(fn(c)) = 674;
1199 ts2.template component<int>(fn(c)) = 421;
1200 BOOST_CHECK_EQUAL(ts1.template component<int>(fn(c)), 674);
1201 BOOST_CHECK_EQUAL(ts2.template component<int>(fn(c)), 421);
1202 }
1203 };
1204
1205 runTest([](const std::string& c) { return hashStringDynamic(c.c_str()); });
1206
1207
1208
1209 }
1210
1211 void testMultiTrajectoryAllocateCalibratedInit(
1212 std::default_random_engine& rng) {
1213 trajectory_t traj = m_factory.create();
1214 auto ts = traj.makeTrackState(TrackStatePropMask::All);
1215
1216 BOOST_CHECK_EQUAL(ts.calibratedSize(), kInvalid);
1217
1218 auto [par, cov] = generateBoundParametersCovariance(rng, {});
1219
1220 ts.allocateCalibrated(par.head<3>(), cov.topLeftCorner<3, 3>());
1221
1222 BOOST_CHECK_EQUAL(ts.calibratedSize(), 3);
1223 BOOST_CHECK_EQUAL(ts.template calibrated<3>(), par.head<3>());
1224 BOOST_CHECK_EQUAL(ts.template calibratedCovariance<3>(),
1225 (cov.topLeftCorner<3, 3>()));
1226
1227 auto [par2, cov2] = generateBoundParametersCovariance(rng, {});
1228
1229 ts.allocateCalibrated(3);
1230 BOOST_CHECK_EQUAL(ts.template calibrated<3>(), Vector3::Zero());
1231 BOOST_CHECK_EQUAL(ts.template calibratedCovariance<3>(),
1232 SquareMatrix<3>::Zero());
1233
1234 ts.allocateCalibrated(par2.head<3>(), cov2.topLeftCorner<3, 3>());
1235 BOOST_CHECK_EQUAL(ts.calibratedSize(), 3);
1236
1237 BOOST_CHECK_EQUAL(ts.template calibrated<3>(), par2.head<3>());
1238 BOOST_CHECK_EQUAL(ts.template calibratedCovariance<3>(),
1239 (cov2.topLeftCorner<3, 3>()));
1240
1241
1242 BOOST_CHECK_THROW(
1243 ts.allocateCalibrated(par2.head<4>(), cov2.topLeftCorner<4, 4>()),
1244 std::invalid_argument);
1245 }
1246 };
1247 }