File indexing completed on 2026-09-09 08:21:44
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include <boost/test/unit_test.hpp>
0013
0014 #include "Acts/Definitions/TrackParametrization.hpp"
0015 #include "Acts/EventData/TrackContainer.hpp"
0016 #include "Acts/EventData/VectorMultiTrajectory.hpp"
0017 #include "Acts/EventData/VectorTrackContainer.hpp"
0018 #include "Acts/Surfaces/PlaneSurface.hpp"
0019 #include "Acts/Surfaces/RectangleBounds.hpp"
0020 #include "ActsExamples/EventData/Track.hpp"
0021 #include "ActsExamples/Validation/ParametersOnSurface.hpp"
0022
0023 #include <array>
0024 #include <cstdint>
0025 #include <memory>
0026 #include <span>
0027 #include <utility>
0028
0029 using namespace Acts;
0030 using namespace ActsExamples;
0031
0032 namespace {
0033
0034
0035
0036 constexpr double measLoc0 = 1.5;
0037 constexpr double measLoc1 = -2.5;
0038
0039 constexpr double measVar0 = 0.04;
0040 constexpr double measVar1 = 0.09;
0041
0042 constexpr double recoLoc0 = 1.7;
0043 constexpr double recoLoc1 = -2.1;
0044
0045 constexpr double recoVar0 = 0.01;
0046 constexpr double recoVar1 = 0.02;
0047
0048 std::shared_ptr<PlaneSurface> makeSurface() {
0049 return Surface::makeShared<PlaneSurface>(
0050 Transform3::Identity(), std::make_shared<RectangleBounds>(100., 100.));
0051 }
0052
0053
0054 BoundTrackParameters makeParameters(
0055 const std::shared_ptr<const Surface>& surface) {
0056 BoundVector parameters = BoundVector::Zero();
0057 parameters[eBoundLoc0] = recoLoc0;
0058 parameters[eBoundLoc1] = recoLoc1;
0059
0060 BoundMatrix covariance = BoundMatrix::Zero();
0061 covariance(eBoundLoc0, eBoundLoc0) = recoVar0;
0062 covariance(eBoundLoc1, eBoundLoc1) = recoVar1;
0063
0064 return BoundTrackParameters(surface, parameters, covariance,
0065 ParticleHypothesis::pion());
0066 }
0067
0068
0069
0070 struct Fixture {
0071 VectorTrackContainer trackBackend;
0072 VectorMultiTrajectory trajectory;
0073 Acts::TrackContainer<VectorTrackContainer, VectorMultiTrajectory,
0074 Acts::detail::RefHolder>
0075 container{trackBackend, trajectory};
0076
0077 std::shared_ptr<PlaneSurface> surface = makeSurface();
0078
0079
0080
0081
0082
0083
0084 ConstTrackStateProxy makeState(std::span<const std::uint8_t> indices) {
0085
0086 BOOST_REQUIRE(constContainer == nullptr);
0087
0088 auto state = container.trackStateContainer().makeTrackState();
0089 state.setReferenceSurface(surface);
0090
0091 if (!indices.empty()) {
0092 state.setProjectorSubspaceIndices(indices);
0093
0094 state.allocateCalibrated(indices.size());
0095 auto calibrated = state.effectiveCalibrated();
0096 auto calibratedCovariance = state.effectiveCalibratedCovariance();
0097 calibratedCovariance.setZero();
0098
0099 const std::array<double, 2> values{measLoc0, measLoc1};
0100 const std::array<double, 2> variances{measVar0, measVar1};
0101 for (std::size_t i = 0; i < indices.size(); ++i) {
0102 calibrated[i] = values.at(i);
0103 calibratedCovariance(i, i) = variances.at(i);
0104 }
0105 }
0106
0107 constContainer = std::make_unique<ConstTrackContainer>(
0108 std::make_shared<ConstVectorTrackContainer>(trackBackend),
0109 std::make_shared<ConstVectorMultiTrajectory>(trajectory));
0110 return constContainer->trackStateContainer().getTrackState(state.index());
0111 }
0112
0113 std::unique_ptr<ConstTrackContainer> constContainer;
0114 };
0115
0116 }
0117
0118 BOOST_AUTO_TEST_SUITE(ValidationMeasurementResidual)
0119
0120 BOOST_AUTO_TEST_CASE(TwoDimensionalMeasurement) {
0121 Fixture fixture;
0122 const std::array<std::uint8_t, 2> indices{eBoundLoc0, eBoundLoc1};
0123 const ConstTrackStateProxy state = fixture.makeState(indices);
0124
0125 const auto residual = measurementResidual(
0126 state, makeParameters(fixture.surface), TrackParameterType::Predicted);
0127 BOOST_REQUIRE(residual.has_value());
0128
0129 BOOST_CHECK_EQUAL(residual->subspace.size(), 2u);
0130 BOOST_CHECK(residual->subspace.contains(eBoundLoc0));
0131 BOOST_CHECK(residual->subspace.contains(eBoundLoc1));
0132
0133
0134 BOOST_CHECK_CLOSE(residual->residual[eBoundLoc0], recoLoc0 - measLoc0, 1e-9);
0135 BOOST_CHECK_CLOSE(residual->residual[eBoundLoc1], recoLoc1 - measLoc1, 1e-9);
0136
0137
0138 BOOST_CHECK_CLOSE(residual->covariance(eBoundLoc0, eBoundLoc0),
0139 measVar0 + recoVar0, 1e-9);
0140 BOOST_CHECK_CLOSE(residual->covariance(eBoundLoc1, eBoundLoc1),
0141 measVar1 + recoVar1, 1e-9);
0142
0143
0144 BOOST_CHECK_EQUAL(residual->residual[eBoundQOverP], 0.);
0145 BOOST_CHECK_EQUAL(residual->covariance(eBoundTheta, eBoundTheta), 0.);
0146 }
0147
0148 BOOST_AUTO_TEST_CASE(CovarianceSignFollowsTheParameterType) {
0149 using enum TrackParameterType;
0150
0151 Fixture fixture;
0152 const std::array<std::uint8_t, 2> indices{eBoundLoc0, eBoundLoc1};
0153 const ConstTrackStateProxy state = fixture.makeState(indices);
0154
0155
0156
0157 constexpr std::array<std::pair<TrackParameterType, bool>, 4> cases{
0158 {{Predicted, false},
0159 {Filtered, true},
0160 {Smoothed, true},
0161 {Unbiased, false}}};
0162
0163 for (const auto& [parameterType, correlated] : cases) {
0164 const auto residual = measurementResidual(
0165 state, makeParameters(fixture.surface), parameterType);
0166 BOOST_REQUIRE(residual.has_value());
0167
0168 const double sign = correlated ? -1. : 1.;
0169 BOOST_CHECK_CLOSE(residual->covariance(eBoundLoc0, eBoundLoc0),
0170 measVar0 + sign * recoVar0, 1e-9);
0171 BOOST_CHECK_CLOSE(residual->covariance(eBoundLoc1, eBoundLoc1),
0172 measVar1 + sign * recoVar1, 1e-9);
0173
0174
0175 BOOST_CHECK_CLOSE(residual->residual[eBoundLoc0], recoLoc0 - measLoc0,
0176 1e-9);
0177 }
0178 }
0179
0180 BOOST_AUTO_TEST_CASE(OneDimensionalMeasurement) {
0181 Fixture fixture;
0182 const std::array<std::uint8_t, 1> indices{eBoundLoc0};
0183 const ConstTrackStateProxy state = fixture.makeState(indices);
0184
0185 const auto residual = measurementResidual(
0186 state, makeParameters(fixture.surface), TrackParameterType::Predicted);
0187 BOOST_REQUIRE(residual.has_value());
0188
0189
0190
0191 BOOST_CHECK_EQUAL(residual->subspace.size(), 1u);
0192 BOOST_CHECK(residual->subspace.contains(eBoundLoc0));
0193 BOOST_CHECK(!residual->subspace.contains(eBoundLoc1));
0194
0195 BOOST_CHECK_CLOSE(residual->residual[eBoundLoc0], recoLoc0 - measLoc0, 1e-9);
0196 BOOST_CHECK_CLOSE(residual->covariance(eBoundLoc0, eBoundLoc0),
0197 measVar0 + recoVar0, 1e-9);
0198
0199 BOOST_CHECK_EQUAL(residual->residual[eBoundLoc1], 0.);
0200 BOOST_CHECK_EQUAL(residual->covariance(eBoundLoc1, eBoundLoc1), 0.);
0201 }
0202
0203 BOOST_AUTO_TEST_CASE(NoMeasurement) {
0204 Fixture fixture;
0205 const ConstTrackStateProxy state = fixture.makeState({});
0206
0207 BOOST_CHECK(!measurementResidual(state, makeParameters(fixture.surface),
0208 TrackParameterType::Predicted)
0209 .has_value());
0210 }
0211
0212 BOOST_AUTO_TEST_SUITE_END()