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