11 #include <boost/test/unit_test.hpp>
32 using namespace Acts::UnitLiterals;
33 using namespace Acts::Test;
42 double distanceMax = std::numeric_limits<double>::max();
50 template <
typename traj_t>
53 if (not state.hasCalibrated() or not state.hasPredicted()) {
56 auto residuals = (state.effectiveCalibrated() -
57 state.effectiveProjector() * state.predicted())
67 double momentumMax = std::numeric_limits<double>::max();
74 template <
typename traj_t>
78 std::cout <<
"momentum : " <<
momentum << std::endl;
86 cfg.resolvePassive =
false;
87 cfg.resolveMaterial =
true;
88 cfg.resolveSensitive =
true;
96 template <
typename stepper_t>
98 std::shared_ptr<const Acts::TrackingGeometry> geo,
double bz) {
100 cfg.resolvePassive =
false;
101 cfg.resolveMaterial =
true;
102 cfg.resolveSensitive =
true;
105 std::make_shared<Acts::ConstantBField>(
Acts::Vector3(0.0, 0.0, bz));
114 using Rng = std::default_random_engine;
128 constexpr
static size_t nMeasurements = 6
u;
147 const std::vector<TestSourceLink>& sourceLinks) {
148 std::vector<Acts::SourceLink> result;
150 std::back_inserter(result),
159 template <
typename fitter_t,
typename fitter_options_t,
typename parameters_t>
160 void test_ZeroFieldNoSurfaceForward(
const fitter_t& fitter,
163 const bool expected_reversed,
164 const bool expected_smoothed,
165 const bool doDiag)
const {
170 BOOST_REQUIRE_EQUAL(sourceLinks.size(), nMeasurements);
173 options.referenceSurface =
nullptr;
178 auto doTest = [&](
bool diag) {
182 tracks.addColumn<
bool>(
"reversed");
183 tracks.addColumn<
bool>(
"smoothed");
185 BOOST_CHECK(
tracks.hasColumn(
"reversed"));
186 BOOST_CHECK(
tracks.hasColumn(
"smoothed"));
189 auto res = fitter.fit(sourceLinks.begin(), sourceLinks.end(),
start,
191 BOOST_REQUIRE(res.ok());
193 const auto track = res.value();
195 BOOST_CHECK(!track.hasReferenceSurface());
196 BOOST_CHECK_EQUAL(track.nMeasurements(), sourceLinks.size());
197 BOOST_CHECK_EQUAL(track.nHoles(), 0
u);
201 BOOST_CHECK_EQUAL(
reversed(track), expected_reversed);
202 BOOST_CHECK_EQUAL(smoothed(track), expected_smoothed);
212 template <
typename fitter_t,
typename fitter_options_t,
typename parameters_t>
213 void test_ZeroFieldWithSurfaceForward(
const fitter_t& fitter,
216 const bool expected_reversed,
217 const bool expected_smoothed,
218 const bool doDiag)
const {
222 BOOST_REQUIRE_EQUAL(sourceLinks.size(), nMeasurements);
226 options.referenceSurface = &start.referenceSurface();
232 tracks.addColumn<
bool>(
"reversed");
233 tracks.addColumn<
bool>(
"smoothed");
235 auto res = fitter.fit(sourceLinks.begin(), sourceLinks.end(),
start,
237 BOOST_REQUIRE(res.ok());
239 const auto& track = res.value();
241 BOOST_CHECK(track.hasReferenceSurface());
242 BOOST_CHECK_EQUAL(track.nMeasurements(), sourceLinks.size());
243 BOOST_CHECK_EQUAL(track.nHoles(), 0
u);
245 BOOST_CHECK(
tracks.hasColumn(
"reversed"));
246 BOOST_CHECK(
tracks.hasColumn(
"smoothed"));
253 BOOST_CHECK_EQUAL(smoothed(track), expected_smoothed);
254 BOOST_CHECK_EQUAL(
reversed(track), expected_reversed);
258 if (expected_reversed && expected_smoothed) {
259 size_t nSmoothed = 0;
260 for (
const auto ts : track.trackStatesReversed()) {
261 nSmoothed += ts.hasSmoothed();
263 BOOST_CHECK_EQUAL(nSmoothed, sourceLinks.size());
267 template <
typename fitter_t,
typename fitter_options_t,
typename parameters_t>
268 void test_ZeroFieldWithSurfaceBackward(
const fitter_t& fitter,
271 const bool expected_reversed,
272 const bool expected_smoothed,
273 const bool doDiag)
const {
277 BOOST_REQUIRE_EQUAL(sourceLinks.size(), nMeasurements);
283 posOuter, start.direction(), start.qOverP(), start.covariance(),
291 tracks.addColumn<
bool>(
"reversed");
292 tracks.addColumn<
bool>(
"smoothed");
294 auto res = fitter.fit(sourceLinks.begin(), sourceLinks.end(), startOuter,
296 BOOST_CHECK(res.ok());
298 const auto& track = res.value();
300 BOOST_CHECK(track.hasReferenceSurface());
301 BOOST_CHECK_EQUAL(track.nMeasurements(), sourceLinks.size());
302 BOOST_CHECK_EQUAL(track.nHoles(), 0
u);
308 BOOST_CHECK_EQUAL(smoothed(track), expected_smoothed);
309 BOOST_CHECK_EQUAL(
reversed(track), expected_reversed);
313 if (expected_reversed && expected_smoothed) {
314 size_t nSmoothed = 0;
315 for (
const auto ts : track.trackStatesReversed()) {
316 nSmoothed += ts.hasSmoothed();
318 BOOST_CHECK_EQUAL(nSmoothed, sourceLinks.size());
322 template <
typename fitter_t,
typename fitter_options_t,
typename parameters_t>
323 void test_ZeroFieldWithSurfaceAtExit(
const fitter_t& fitter,
326 const bool expected_reversed,
327 const bool expected_smoothed,
328 const bool doDiag)
const {
332 BOOST_REQUIRE_EQUAL(sourceLinks.size(), nMeasurements);
338 Acts::Surface::makeShared<Acts::PlaneSurface>(center, normal);
340 options.referenceSurface = targetSurface.get();
344 tracks.addColumn<
bool>(
"reversed");
345 tracks.addColumn<
bool>(
"smoothed");
347 auto res = fitter.fit(sourceLinks.begin(), sourceLinks.end(),
start,
349 BOOST_REQUIRE(res.ok());
351 const auto& track = res.value();
353 BOOST_CHECK(track.hasReferenceSurface());
354 BOOST_CHECK_EQUAL(track.nMeasurements(), sourceLinks.size());
355 BOOST_CHECK_EQUAL(track.nHoles(), 0
u);
362 BOOST_CHECK_EQUAL(smoothed(track), expected_smoothed);
363 BOOST_CHECK_EQUAL(
reversed(track), expected_reversed);
367 template <
typename fitter_t,
typename fitter_options_t,
typename parameters_t>
368 void test_ZeroFieldShuffled(
const fitter_t& fitter, fitter_options_t
options,
370 const bool expected_reversed,
371 const bool expected_smoothed,
372 const bool doDiag)
const {
376 BOOST_REQUIRE_EQUAL(sourceLinks.size(), nMeasurements);
378 options.referenceSurface = &start.referenceSurface();
384 tracks.addColumn<
bool>(
"reversed");
385 tracks.addColumn<
bool>(
"smoothed");
392 auto res = fitter.fit(sourceLinks.begin(), sourceLinks.end(),
start,
394 BOOST_REQUIRE(res.ok());
396 const auto& track = res.value();
398 BOOST_CHECK_EQUAL(track.nMeasurements(), sourceLinks.size());
399 BOOST_REQUIRE(track.hasReferenceSurface());
400 parameters = track.parameters();
401 BOOST_CHECK_EQUAL(track.nHoles(), 0
u);
405 BOOST_CHECK_EQUAL(smoothed(track), expected_smoothed);
406 BOOST_CHECK_EQUAL(
reversed(track), expected_reversed);
411 decltype(sourceLinks) shuffledSourceLinks = sourceLinks;
412 std::shuffle(shuffledSourceLinks.begin(), shuffledSourceLinks.end(),
rng);
413 auto res = fitter.fit(shuffledSourceLinks.begin(),
415 BOOST_REQUIRE(res.ok());
417 const auto& track = res.value();
419 BOOST_REQUIRE(track.hasReferenceSurface());
422 BOOST_CHECK_EQUAL(track.nMeasurements(), sourceLinks.size());
425 BOOST_CHECK_EQUAL(smoothed(track), expected_smoothed);
426 BOOST_CHECK_EQUAL(
reversed(track), expected_reversed);
431 template <
typename fitter_t,
typename fitter_options_t,
typename parameters_t>
432 void test_ZeroFieldWithHole(
const fitter_t& fitter, fitter_options_t
options,
434 const bool expected_reversed,
435 const bool expected_smoothed,
436 const bool doDiag)
const {
440 BOOST_REQUIRE_EQUAL(sourceLinks.size(), nMeasurements);
444 tracks.addColumn<
bool>(
"reversed");
445 tracks.addColumn<
bool>(
"smoothed");
452 for (
size_t i = 1
u; (
i + 1
u) < sourceLinks.size(); ++
i) {
454 auto withHole = sourceLinks;
455 withHole.erase(
std::next(withHole.begin(),
i));
456 BOOST_REQUIRE_EQUAL(withHole.size() + 1
u, sourceLinks.size());
457 BOOST_TEST_INFO(
"Removed measurement " <<
i);
461 BOOST_REQUIRE(res.ok());
463 const auto& track = res.value();
465 BOOST_REQUIRE(!track.hasReferenceSurface());
466 BOOST_CHECK_EQUAL(track.nMeasurements(), withHole.size());
469 BOOST_CHECK_EQUAL(smoothed(track), expected_smoothed);
470 BOOST_CHECK_EQUAL(
reversed(track), expected_reversed);
472 BOOST_CHECK_EQUAL(track.nHoles(), 1
u);
474 BOOST_CHECK_EQUAL(
tracks.size(), sourceLinks.size() - 2);
477 template <
typename fitter_t,
typename fitter_options_t,
typename parameters_t>
478 void test_ZeroFieldWithOutliers(
const fitter_t& fitter,
481 const bool expected_reversed,
482 const bool expected_smoothed,
483 const bool doDiag)
const {
487 auto outlierSourceLinks =
489 BOOST_REQUIRE_EQUAL(sourceLinks.size(), nMeasurements);
490 BOOST_REQUIRE_EQUAL(outlierSourceLinks.size(), nMeasurements);
494 tracks.addColumn<
bool>(
"reversed");
495 tracks.addColumn<
bool>(
"smoothed");
500 for (
size_t i = 0;
i < sourceLinks.size(); ++
i) {
502 auto withOutlier = sourceLinks;
503 withOutlier[
i] = outlierSourceLinks[
i];
504 BOOST_REQUIRE_EQUAL(withOutlier.size(), sourceLinks.size());
505 BOOST_TEST_INFO(
"Replaced measurement " <<
i <<
" with outlier");
507 auto res = fitter.fit(withOutlier.begin(), withOutlier.end(),
start,
509 BOOST_REQUIRE(res.ok());
511 const auto& track = res.value();
514 size_t nOutliers = 0;
515 for (
const auto state : track.trackStatesReversed()) {
518 BOOST_CHECK_EQUAL(nOutliers, 1
u);
519 BOOST_REQUIRE(!track.hasReferenceSurface());
520 BOOST_CHECK_EQUAL(track.nMeasurements(), withOutlier.size() - 1
u);
523 BOOST_CHECK_EQUAL(smoothed(track), expected_smoothed);
524 BOOST_CHECK_EQUAL(
reversed(track), expected_reversed);
526 BOOST_CHECK_EQUAL(track.nHoles(), 0
u);
528 BOOST_CHECK_EQUAL(
tracks.size(), sourceLinks.size());
531 template <
typename fitter_t,
typename fitter_options_t,
typename parameters_t>
532 void test_ZeroFieldWithReverseFiltering(
const fitter_t& fitter,
535 const bool expected_reversed,
536 const bool expected_smoothed,
537 const bool doDiag)
const {
543 tracks.addColumn<
bool>(
"reversed");
544 tracks.addColumn<
bool>(
"smoothed");
551 const auto& outlierSourceLinks = measurements.outlierSourceLinks;
552 BOOST_REQUIRE_EQUAL(sourceLinks.size(), nMeasurements);
553 BOOST_REQUIRE_EQUAL(outlierSourceLinks.size(), nMeasurements);
559 Acts::Surface::makeShared<Acts::PlaneSurface>(center, normal);
561 options.referenceSurface = targetSurface.get();
563 auto res = fitter.fit(sourceLinks.begin(), sourceLinks.end(),
start,
565 BOOST_REQUIRE(res.ok());
566 const auto& track = res.value();
571 BOOST_CHECK_EQUAL(smoothed(track), expected_smoothed);
572 BOOST_CHECK_EQUAL(
reversed(track), expected_reversed);
578 template <
typename fitter_t,
typename fitter_options_t,
typename parameters_t>
579 void test_GlobalCovariance(
const fitter_t& fitter, fitter_options_t
options,
584 BOOST_REQUIRE_EQUAL(sourceLinks.size(), nMeasurements);
589 auto res = fitter.fit(sourceLinks.begin(), sourceLinks.end(),
start,
591 BOOST_REQUIRE(res.ok());
594 const auto& track = res.value();
595 auto [trackParamsCov, stateRowIndices] =
597 tracks.trackStateContainer(), track.tipIndex());
598 BOOST_CHECK_EQUAL(trackParamsCov.rows(),
600 BOOST_CHECK_EQUAL(stateRowIndices.size(), sourceLinks.size());
606 BOOST_CHECK_EQUAL(stateRowIndices.at(track.tipIndex()),