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