File indexing completed on 2025-08-06 08:11:30
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include <boost/test/unit_test.hpp>
0012
0013 #include "Acts/Definitions/Units.hpp"
0014 #include "Acts/EventData/MultiTrajectory.hpp"
0015 #include "Acts/EventData/ProxyAccessor.hpp"
0016 #include "Acts/EventData/SourceLink.hpp"
0017 #include "Acts/EventData/VectorMultiTrajectory.hpp"
0018 #include "Acts/EventData/VectorTrackContainer.hpp"
0019 #include "Acts/EventData/detail/TestSourceLink.hpp"
0020 #include "Acts/Geometry/TrackingGeometry.hpp"
0021 #include "Acts/MagneticField/ConstantBField.hpp"
0022 #include "Acts/MagneticField/MagneticFieldContext.hpp"
0023 #include "Acts/Propagator/Navigator.hpp"
0024 #include "Acts/Propagator/StraightLineStepper.hpp"
0025 #include "Acts/Tests/CommonHelpers/CubicTrackingGeometry.hpp"
0026 #include "Acts/Tests/CommonHelpers/FloatComparisons.hpp"
0027 #include "Acts/Tests/CommonHelpers/MeasurementsCreator.hpp"
0028 #include "Acts/TrackFitting/detail/KalmanGlobalCovariance.hpp"
0029 #include "Acts/Utilities/CalibrationContext.hpp"
0030 #include "Acts/Utilities/Logger.hpp"
0031
0032 #include <iterator>
0033
0034 using namespace Acts::UnitLiterals;
0035 using namespace Acts::Test;
0036
0037
0038
0039
0040
0041
0042
0043 struct TestOutlierFinder {
0044 double distanceMax = std::numeric_limits<double>::max();
0045
0046
0047
0048
0049
0050
0051
0052 template <typename traj_t>
0053 bool operator()(typename traj_t::ConstTrackStateProxy state) const {
0054
0055 if (!state.hasCalibrated() || !state.hasPredicted()) {
0056 return false;
0057 }
0058 auto residuals = (state.effectiveCalibrated() -
0059 state.effectiveProjector() * state.predicted())
0060 .eval();
0061 auto distance = residuals.norm();
0062 return (distanceMax <= distance);
0063 }
0064 };
0065
0066
0067
0068 struct TestReverseFilteringLogic {
0069 double momentumMax = std::numeric_limits<double>::max();
0070
0071
0072
0073
0074
0075
0076 template <typename traj_t>
0077 bool operator()(typename traj_t::ConstTrackStateProxy state) const {
0078
0079 auto momentum = fabs(1 / state.filtered()[Acts::eBoundQOverP]);
0080 std::cout << "momentum : " << momentum << std::endl;
0081 return (momentum <= momentumMax);
0082 }
0083 };
0084
0085
0086 auto makeStraightPropagator(std::shared_ptr<const Acts::TrackingGeometry> geo) {
0087 Acts::Navigator::Config cfg{std::move(geo)};
0088 cfg.resolvePassive = false;
0089 cfg.resolveMaterial = true;
0090 cfg.resolveSensitive = true;
0091 Acts::Navigator navigator(
0092 cfg, Acts::getDefaultLogger("Navigator", Acts::Logging::VERBOSE));
0093 Acts::StraightLineStepper stepper;
0094 return Acts::Propagator<Acts::StraightLineStepper, Acts::Navigator>(
0095 stepper, std::move(navigator));
0096 }
0097
0098
0099 template <typename stepper_t>
0100 auto makeConstantFieldPropagator(
0101 std::shared_ptr<const Acts::TrackingGeometry> geo, double bz) {
0102 Acts::Navigator::Config cfg{std::move(geo)};
0103 cfg.resolvePassive = false;
0104 cfg.resolveMaterial = true;
0105 cfg.resolveSensitive = true;
0106 Acts::Navigator navigator(
0107 cfg, Acts::getDefaultLogger("Navigator", Acts::Logging::VERBOSE));
0108 auto field =
0109 std::make_shared<Acts::ConstantBField>(Acts::Vector3(0.0, 0.0, bz));
0110 stepper_t stepper(std::move(field));
0111 return Acts::Propagator<decltype(stepper), Acts::Navigator>(
0112 std::move(stepper), std::move(navigator));
0113 }
0114
0115
0116
0117 struct FitterTester {
0118 using Rng = std::default_random_engine;
0119
0120
0121 Acts::GeometryContext geoCtx;
0122 Acts::MagneticFieldContext magCtx;
0123 Acts::CalibrationContext calCtx;
0124
0125
0126 CubicTrackingGeometry geometryStore{geoCtx};
0127 std::shared_ptr<const Acts::TrackingGeometry> geometry = geometryStore();
0128
0129 Acts::detail::Test::TestSourceLink::SurfaceAccessor surfaceAccessor{
0130 *geometry};
0131
0132
0133 constexpr static std::size_t nMeasurements = 6u;
0134
0135
0136 MeasurementResolution resPixel = {MeasurementType::eLoc01, {25_um, 50_um}};
0137 MeasurementResolution resStrip0 = {MeasurementType::eLoc0, {100_um}};
0138 MeasurementResolution resStrip1 = {MeasurementType::eLoc1, {150_um}};
0139 MeasurementResolutionMap resolutions = {
0140 {Acts::GeometryIdentifier().setVolume(2), resPixel},
0141 {Acts::GeometryIdentifier().setVolume(3).setLayer(2), resStrip0},
0142 {Acts::GeometryIdentifier().setVolume(3).setLayer(4), resStrip1},
0143 {Acts::GeometryIdentifier().setVolume(3).setLayer(6), resStrip0},
0144 {Acts::GeometryIdentifier().setVolume(3).setLayer(8), resStrip1},
0145 };
0146
0147
0148 Acts::Propagator<Acts::StraightLineStepper, Acts::Navigator> simPropagator =
0149 makeStraightPropagator(geometry);
0150
0151 static std::vector<Acts::SourceLink> prepareSourceLinks(
0152 const std::vector<Acts::detail::Test::TestSourceLink>& sourceLinks) {
0153 std::vector<Acts::SourceLink> result;
0154 std::transform(sourceLinks.begin(), sourceLinks.end(),
0155 std::back_inserter(result),
0156 [](const auto& sl) { return Acts::SourceLink{sl}; });
0157 return result;
0158 }
0159
0160
0161
0162
0163
0164 template <typename fitter_t, typename fitter_options_t, typename parameters_t>
0165 void test_ZeroFieldNoSurfaceForward(const fitter_t& fitter,
0166 fitter_options_t options,
0167 const parameters_t& start, Rng& rng,
0168 const bool expected_reversed,
0169 const bool expected_smoothed,
0170 const bool doDiag) const {
0171 auto measurements = createMeasurements(simPropagator, geoCtx, magCtx, start,
0172 resolutions, rng);
0173
0174 auto sourceLinks = prepareSourceLinks(measurements.sourceLinks);
0175 BOOST_REQUIRE_EQUAL(sourceLinks.size(), nMeasurements);
0176
0177
0178 options.referenceSurface = nullptr;
0179
0180 Acts::ConstProxyAccessor<bool> reversed{"reversed"};
0181 Acts::ConstProxyAccessor<bool> smoothed{"smoothed"};
0182
0183 auto doTest = [&](bool diag) {
0184 Acts::TrackContainer tracks{Acts::VectorTrackContainer{},
0185 Acts::VectorMultiTrajectory{}};
0186 if (diag) {
0187 tracks.addColumn<bool>("reversed");
0188 tracks.addColumn<bool>("smoothed");
0189
0190 BOOST_CHECK(tracks.hasColumn("reversed"));
0191 BOOST_CHECK(tracks.hasColumn("smoothed"));
0192 }
0193
0194 auto res = fitter.fit(sourceLinks.begin(), sourceLinks.end(), start,
0195 options, tracks);
0196 BOOST_REQUIRE(res.ok());
0197
0198 const auto track = res.value();
0199 BOOST_CHECK_NE(track.tipIndex(), Acts::MultiTrajectoryTraits::kInvalid);
0200 BOOST_CHECK(!track.hasReferenceSurface());
0201 BOOST_CHECK_EQUAL(track.nMeasurements(), sourceLinks.size());
0202 BOOST_CHECK_EQUAL(track.nHoles(), 0u);
0203
0204 if (diag) {
0205
0206 BOOST_CHECK_EQUAL(reversed(track), expected_reversed);
0207 BOOST_CHECK_EQUAL(smoothed(track), expected_smoothed);
0208 }
0209 };
0210
0211 if (doDiag) {
0212 doTest(true);
0213 }
0214 doTest(false);
0215 }
0216
0217 template <typename fitter_t, typename fitter_options_t, typename parameters_t>
0218 void test_ZeroFieldWithSurfaceForward(const fitter_t& fitter,
0219 fitter_options_t options,
0220 const parameters_t& start, Rng& rng,
0221 const bool expected_reversed,
0222 const bool expected_smoothed,
0223 const bool doDiag) const {
0224 auto measurements = createMeasurements(simPropagator, geoCtx, magCtx, start,
0225 resolutions, rng);
0226 auto sourceLinks = prepareSourceLinks(measurements.sourceLinks);
0227 BOOST_REQUIRE_EQUAL(sourceLinks.size(), nMeasurements);
0228
0229
0230
0231 options.referenceSurface = &start.referenceSurface();
0232
0233 options.propagatorPlainOptions.direction = Acts::Direction::Forward;
0234
0235 Acts::TrackContainer tracks{Acts::VectorTrackContainer{},
0236 Acts::VectorMultiTrajectory{}};
0237 tracks.addColumn<bool>("reversed");
0238 tracks.addColumn<bool>("smoothed");
0239
0240 auto res = fitter.fit(sourceLinks.begin(), sourceLinks.end(), start,
0241 options, tracks);
0242 BOOST_REQUIRE(res.ok());
0243
0244 const auto& track = res.value();
0245 BOOST_CHECK_NE(track.tipIndex(), Acts::MultiTrajectoryTraits::kInvalid);
0246 BOOST_CHECK(track.hasReferenceSurface());
0247 BOOST_CHECK_EQUAL(track.nMeasurements(), sourceLinks.size());
0248 BOOST_CHECK_EQUAL(track.nHoles(), 0u);
0249
0250 BOOST_CHECK(tracks.hasColumn("reversed"));
0251 BOOST_CHECK(tracks.hasColumn("smoothed"));
0252
0253 Acts::ConstProxyAccessor<bool> reversed{"reversed"};
0254 Acts::ConstProxyAccessor<bool> smoothed{"smoothed"};
0255
0256
0257 if (doDiag) {
0258 BOOST_CHECK_EQUAL(smoothed(track), expected_smoothed);
0259 BOOST_CHECK_EQUAL(reversed(track), expected_reversed);
0260 }
0261
0262
0263 if (expected_reversed && expected_smoothed) {
0264 std::size_t nSmoothed = 0;
0265 for (const auto ts : track.trackStatesReversed()) {
0266 nSmoothed += ts.hasSmoothed();
0267 }
0268 BOOST_CHECK_EQUAL(nSmoothed, sourceLinks.size());
0269 }
0270 }
0271
0272 template <typename fitter_t, typename fitter_options_t, typename parameters_t>
0273 void test_ZeroFieldWithSurfaceBackward(const fitter_t& fitter,
0274 fitter_options_t options,
0275 const parameters_t& start, Rng& rng,
0276 const bool expected_reversed,
0277 const bool expected_smoothed,
0278 const bool doDiag) const {
0279 auto measurements = createMeasurements(simPropagator, geoCtx, magCtx, start,
0280 resolutions, rng);
0281 auto sourceLinks = prepareSourceLinks(measurements.sourceLinks);
0282 BOOST_REQUIRE_EQUAL(sourceLinks.size(), nMeasurements);
0283
0284
0285 Acts::Vector4 posOuter = start.fourPosition(geoCtx);
0286 posOuter[Acts::ePos0] = 3_m;
0287 Acts::CurvilinearTrackParameters startOuter(
0288 posOuter, start.direction(), start.qOverP(), start.covariance(),
0289 Acts::ParticleHypothesis::pion());
0290
0291 options.referenceSurface = &startOuter.referenceSurface();
0292 options.propagatorPlainOptions.direction = Acts::Direction::Backward;
0293
0294 Acts::TrackContainer tracks{Acts::VectorTrackContainer{},
0295 Acts::VectorMultiTrajectory{}};
0296 tracks.addColumn<bool>("reversed");
0297 tracks.addColumn<bool>("smoothed");
0298
0299 auto res = fitter.fit(sourceLinks.begin(), sourceLinks.end(), startOuter,
0300 options, tracks);
0301 BOOST_CHECK(res.ok());
0302
0303 const auto& track = res.value();
0304 BOOST_CHECK_NE(track.tipIndex(), Acts::MultiTrajectoryTraits::kInvalid);
0305 BOOST_CHECK(track.hasReferenceSurface());
0306 BOOST_CHECK_EQUAL(track.nMeasurements(), sourceLinks.size());
0307 BOOST_CHECK_EQUAL(track.nHoles(), 0u);
0308
0309 Acts::ConstProxyAccessor<bool> reversed{"reversed"};
0310 Acts::ConstProxyAccessor<bool> smoothed{"smoothed"};
0311
0312 if (doDiag) {
0313 BOOST_CHECK_EQUAL(smoothed(track), expected_smoothed);
0314 BOOST_CHECK_EQUAL(reversed(track), expected_reversed);
0315 }
0316
0317
0318 if (expected_reversed && expected_smoothed) {
0319 std::size_t nSmoothed = 0;
0320 for (const auto ts : track.trackStatesReversed()) {
0321 nSmoothed += ts.hasSmoothed();
0322 }
0323 BOOST_CHECK_EQUAL(nSmoothed, sourceLinks.size());
0324 }
0325 }
0326
0327 template <typename fitter_t, typename fitter_options_t, typename parameters_t>
0328 void test_ZeroFieldWithSurfaceAtExit(const fitter_t& fitter,
0329 fitter_options_t options,
0330 const parameters_t& start, Rng& rng,
0331 const bool expected_reversed,
0332 const bool expected_smoothed,
0333 const bool doDiag) const {
0334 auto measurements = createMeasurements(simPropagator, geoCtx, magCtx, start,
0335 resolutions, rng);
0336 auto sourceLinks = prepareSourceLinks(measurements.sourceLinks);
0337 BOOST_REQUIRE_EQUAL(sourceLinks.size(), nMeasurements);
0338
0339
0340 Acts::Vector3 center(3._m, 0., 0.);
0341 Acts::Vector3 normal(1., 0., 0.);
0342 auto targetSurface =
0343 Acts::Surface::makeShared<Acts::PlaneSurface>(center, normal);
0344
0345 options.referenceSurface = targetSurface.get();
0346
0347 Acts::TrackContainer tracks{Acts::VectorTrackContainer{},
0348 Acts::VectorMultiTrajectory{}};
0349 tracks.addColumn<bool>("reversed");
0350 tracks.addColumn<bool>("smoothed");
0351
0352 auto res = fitter.fit(sourceLinks.begin(), sourceLinks.end(), start,
0353 options, tracks);
0354 BOOST_REQUIRE(res.ok());
0355
0356 const auto& track = res.value();
0357 BOOST_CHECK_NE(track.tipIndex(), Acts::MultiTrajectoryTraits::kInvalid);
0358 BOOST_CHECK(track.hasReferenceSurface());
0359 BOOST_CHECK_EQUAL(track.nMeasurements(), sourceLinks.size());
0360 BOOST_CHECK_EQUAL(track.nHoles(), 0u);
0361
0362 Acts::ConstProxyAccessor<bool> reversed{"reversed"};
0363 Acts::ConstProxyAccessor<bool> smoothed{"smoothed"};
0364
0365
0366 if (doDiag) {
0367 BOOST_CHECK_EQUAL(smoothed(track), expected_smoothed);
0368 BOOST_CHECK_EQUAL(reversed(track), expected_reversed);
0369 }
0370 }
0371
0372 template <typename fitter_t, typename fitter_options_t, typename parameters_t>
0373 void test_ZeroFieldShuffled(const fitter_t& fitter, fitter_options_t options,
0374 const parameters_t& start, Rng& rng,
0375 const bool expected_reversed,
0376 const bool expected_smoothed,
0377 const bool doDiag) const {
0378 auto measurements = createMeasurements(simPropagator, geoCtx, magCtx, start,
0379 resolutions, rng);
0380 auto sourceLinks = prepareSourceLinks(measurements.sourceLinks);
0381 BOOST_REQUIRE_EQUAL(sourceLinks.size(), nMeasurements);
0382
0383 options.referenceSurface = &start.referenceSurface();
0384
0385 Acts::BoundVector parameters = Acts::BoundVector::Zero();
0386
0387 Acts::TrackContainer tracks{Acts::VectorTrackContainer{},
0388 Acts::VectorMultiTrajectory{}};
0389 tracks.addColumn<bool>("reversed");
0390 tracks.addColumn<bool>("smoothed");
0391
0392 Acts::ConstProxyAccessor<bool> reversed{"reversed"};
0393 Acts::ConstProxyAccessor<bool> smoothed{"smoothed"};
0394
0395
0396 {
0397 auto res = fitter.fit(sourceLinks.begin(), sourceLinks.end(), start,
0398 options, tracks);
0399 BOOST_REQUIRE(res.ok());
0400
0401 const auto& track = res.value();
0402 BOOST_CHECK_NE(track.tipIndex(), Acts::MultiTrajectoryTraits::kInvalid);
0403 BOOST_CHECK_EQUAL(track.nMeasurements(), sourceLinks.size());
0404 BOOST_REQUIRE(track.hasReferenceSurface());
0405 parameters = track.parameters();
0406 BOOST_CHECK_EQUAL(track.nHoles(), 0u);
0407
0408
0409 if (doDiag) {
0410 BOOST_CHECK_EQUAL(smoothed(track), expected_smoothed);
0411 BOOST_CHECK_EQUAL(reversed(track), expected_reversed);
0412 }
0413 }
0414
0415 {
0416 decltype(sourceLinks) shuffledSourceLinks = sourceLinks;
0417 std::shuffle(shuffledSourceLinks.begin(), shuffledSourceLinks.end(), rng);
0418 auto res = fitter.fit(shuffledSourceLinks.begin(),
0419 shuffledSourceLinks.end(), start, options, tracks);
0420 BOOST_REQUIRE(res.ok());
0421
0422 const auto& track = res.value();
0423 BOOST_CHECK_NE(track.tipIndex(), Acts::MultiTrajectoryTraits::kInvalid);
0424 BOOST_REQUIRE(track.hasReferenceSurface());
0425
0426 CHECK_CLOSE_ABS(track.parameters(), parameters, 1e-5);
0427 BOOST_CHECK_EQUAL(track.nMeasurements(), sourceLinks.size());
0428
0429 if (doDiag) {
0430 BOOST_CHECK_EQUAL(smoothed(track), expected_smoothed);
0431 BOOST_CHECK_EQUAL(reversed(track), expected_reversed);
0432 }
0433 }
0434 }
0435
0436 template <typename fitter_t, typename fitter_options_t, typename parameters_t>
0437 void test_ZeroFieldWithHole(const fitter_t& fitter, fitter_options_t options,
0438 const parameters_t& start, Rng& rng,
0439 const bool expected_reversed,
0440 const bool expected_smoothed,
0441 const bool doDiag) const {
0442 auto measurements = createMeasurements(simPropagator, geoCtx, magCtx, start,
0443 resolutions, rng);
0444 auto sourceLinks = prepareSourceLinks(measurements.sourceLinks);
0445 BOOST_REQUIRE_EQUAL(sourceLinks.size(), nMeasurements);
0446
0447 Acts::TrackContainer tracks{Acts::VectorTrackContainer{},
0448 Acts::VectorMultiTrajectory{}};
0449 tracks.addColumn<bool>("reversed");
0450 tracks.addColumn<bool>("smoothed");
0451
0452 Acts::ConstProxyAccessor<bool> reversed{"reversed"};
0453 Acts::ConstProxyAccessor<bool> smoothed{"smoothed"};
0454
0455
0456
0457 for (std::size_t i = 1u; (i + 1u) < sourceLinks.size(); ++i) {
0458
0459 auto withHole = sourceLinks;
0460 withHole.erase(std::next(withHole.begin(), i));
0461 BOOST_REQUIRE_EQUAL(withHole.size() + 1u, sourceLinks.size());
0462 BOOST_TEST_INFO("Removed measurement " << i);
0463
0464 auto res =
0465 fitter.fit(withHole.begin(), withHole.end(), start, options, tracks);
0466 BOOST_REQUIRE(res.ok());
0467
0468 const auto& track = res.value();
0469 BOOST_CHECK_NE(track.tipIndex(), Acts::MultiTrajectoryTraits::kInvalid);
0470 BOOST_REQUIRE(!track.hasReferenceSurface());
0471 BOOST_CHECK_EQUAL(track.nMeasurements(), withHole.size());
0472
0473 if (doDiag) {
0474 BOOST_CHECK_EQUAL(smoothed(track), expected_smoothed);
0475 BOOST_CHECK_EQUAL(reversed(track), expected_reversed);
0476 }
0477 BOOST_CHECK_EQUAL(track.nHoles(), 1u);
0478 }
0479 BOOST_CHECK_EQUAL(tracks.size(), sourceLinks.size() - 2);
0480 }
0481
0482 template <typename fitter_t, typename fitter_options_t, typename parameters_t>
0483 void test_ZeroFieldWithOutliers(const fitter_t& fitter,
0484 fitter_options_t options,
0485 const parameters_t& start, Rng& rng,
0486 const bool expected_reversed,
0487 const bool expected_smoothed,
0488 const bool doDiag) const {
0489 auto measurements = createMeasurements(simPropagator, geoCtx, magCtx, start,
0490 resolutions, rng);
0491 auto sourceLinks = prepareSourceLinks(measurements.sourceLinks);
0492 auto outlierSourceLinks =
0493 prepareSourceLinks(measurements.outlierSourceLinks);
0494 BOOST_REQUIRE_EQUAL(sourceLinks.size(), nMeasurements);
0495 BOOST_REQUIRE_EQUAL(outlierSourceLinks.size(), nMeasurements);
0496
0497 Acts::TrackContainer tracks{Acts::VectorTrackContainer{},
0498 Acts::VectorMultiTrajectory{}};
0499 tracks.addColumn<bool>("reversed");
0500 tracks.addColumn<bool>("smoothed");
0501
0502 Acts::ConstProxyAccessor<bool> reversed{"reversed"};
0503 Acts::ConstProxyAccessor<bool> smoothed{"smoothed"};
0504
0505 for (std::size_t i = 0; i < sourceLinks.size(); ++i) {
0506
0507 auto withOutlier = sourceLinks;
0508 withOutlier[i] = outlierSourceLinks[i];
0509 BOOST_REQUIRE_EQUAL(withOutlier.size(), sourceLinks.size());
0510 BOOST_TEST_INFO("Replaced measurement " << i << " with outlier");
0511
0512 auto res = fitter.fit(withOutlier.begin(), withOutlier.end(), start,
0513 options, tracks);
0514 BOOST_REQUIRE(res.ok());
0515
0516 const auto& track = res.value();
0517 BOOST_CHECK_NE(track.tipIndex(), Acts::MultiTrajectoryTraits::kInvalid);
0518
0519 std::size_t nOutliers = 0;
0520 for (const auto state : track.trackStatesReversed()) {
0521 nOutliers += state.typeFlags().test(Acts::TrackStateFlag::OutlierFlag);
0522 }
0523 BOOST_CHECK_EQUAL(nOutliers, 1u);
0524 BOOST_REQUIRE(!track.hasReferenceSurface());
0525 BOOST_CHECK_EQUAL(track.nMeasurements(), withOutlier.size() - 1u);
0526
0527 if (doDiag) {
0528 BOOST_CHECK_EQUAL(smoothed(track), expected_smoothed);
0529 BOOST_CHECK_EQUAL(reversed(track), expected_reversed);
0530 }
0531 BOOST_CHECK_EQUAL(track.nHoles(), 0u);
0532 }
0533 BOOST_CHECK_EQUAL(tracks.size(), sourceLinks.size());
0534 }
0535
0536 template <typename fitter_t, typename fitter_options_t, typename parameters_t>
0537 void test_ZeroFieldWithReverseFiltering(const fitter_t& fitter,
0538 fitter_options_t options,
0539 const parameters_t& start, Rng& rng,
0540 const bool expected_reversed,
0541 const bool expected_smoothed,
0542 const bool doDiag) const {
0543 auto measurements = createMeasurements(simPropagator, geoCtx, magCtx, start,
0544 resolutions, rng);
0545
0546 Acts::TrackContainer tracks{Acts::VectorTrackContainer{},
0547 Acts::VectorMultiTrajectory{}};
0548 tracks.addColumn<bool>("reversed");
0549 tracks.addColumn<bool>("smoothed");
0550
0551 Acts::ConstProxyAccessor<bool> reversed{"reversed"};
0552 Acts::ConstProxyAccessor<bool> smoothed{"smoothed"};
0553
0554 auto sourceLinks = prepareSourceLinks(measurements.sourceLinks);
0555
0556 const auto& outlierSourceLinks = measurements.outlierSourceLinks;
0557 BOOST_REQUIRE_EQUAL(sourceLinks.size(), nMeasurements);
0558 BOOST_REQUIRE_EQUAL(outlierSourceLinks.size(), nMeasurements);
0559
0560
0561 Acts::Vector3 center(-3._m, 0., 0.);
0562 Acts::Vector3 normal(1., 0., 0.);
0563 auto targetSurface =
0564 Acts::Surface::makeShared<Acts::PlaneSurface>(center, normal);
0565
0566 options.referenceSurface = targetSurface.get();
0567
0568 auto res = fitter.fit(sourceLinks.begin(), sourceLinks.end(), start,
0569 options, tracks);
0570 BOOST_REQUIRE(res.ok());
0571 const auto& track = res.value();
0572
0573
0574
0575 if (doDiag) {
0576 BOOST_CHECK_EQUAL(smoothed(track), expected_smoothed);
0577 BOOST_CHECK_EQUAL(reversed(track), expected_reversed);
0578 }
0579 }
0580
0581
0582
0583 template <typename fitter_t, typename fitter_options_t, typename parameters_t>
0584 void test_GlobalCovariance(const fitter_t& fitter, fitter_options_t options,
0585 const parameters_t& start, Rng& rng) const {
0586 auto measurements = createMeasurements(simPropagator, geoCtx, magCtx, start,
0587 resolutions, rng);
0588 auto sourceLinks = prepareSourceLinks(measurements.sourceLinks);
0589 BOOST_REQUIRE_EQUAL(sourceLinks.size(), nMeasurements);
0590
0591 Acts::TrackContainer tracks{Acts::VectorTrackContainer{},
0592 Acts::VectorMultiTrajectory{}};
0593
0594 auto res = fitter.fit(sourceLinks.begin(), sourceLinks.end(), start,
0595 options, tracks);
0596 BOOST_REQUIRE(res.ok());
0597
0598
0599 const auto& track = res.value();
0600 auto [trackParamsCov, stateRowIndices] =
0601 Acts::detail::globalTrackParametersCovariance(
0602 tracks.trackStateContainer(), track.tipIndex());
0603 BOOST_CHECK_EQUAL(trackParamsCov.rows(),
0604 sourceLinks.size() * Acts::eBoundSize);
0605 BOOST_CHECK_EQUAL(stateRowIndices.size(), sourceLinks.size());
0606
0607
0608
0609
0610
0611 BOOST_CHECK_EQUAL(stateRowIndices.at(track.tipIndex()),
0612 Acts::eBoundSize * (nMeasurements - 1));
0613 }
0614 };