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