File indexing completed on 2025-08-06 08:11:30
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <boost/test/unit_test.hpp>
0010
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/Definitions/TrackParametrization.hpp"
0013 #include "Acts/Definitions/Units.hpp"
0014 #include "Acts/TrackFitting/GsfMixtureReduction.hpp"
0015 #include "Acts/TrackFitting/detail/SymmetricKlDistanceMatrix.hpp"
0016
0017 #include <algorithm>
0018 #include <array>
0019 #include <cstddef>
0020 #include <memory>
0021 #include <numeric>
0022 #include <tuple>
0023 #include <utility>
0024 #include <vector>
0025
0026 using namespace Acts;
0027
0028 BOOST_AUTO_TEST_CASE(test_distance_matrix_min_distance) {
0029 std::vector<GsfComponent> cmps = {
0030 {1. / 3., BoundVector::Constant(-2.), BoundSquareMatrix::Identity()},
0031 {1. / 3., BoundVector::Constant(+0.), BoundSquareMatrix::Identity()},
0032 {1. / 3., BoundVector::Constant(+1.), BoundSquareMatrix::Identity()},
0033 {1. / 3., BoundVector::Constant(+4.), BoundSquareMatrix::Identity()}};
0034
0035 const auto proj = [](auto &a) -> decltype(auto) { return a; };
0036 detail::SymmetricKLDistanceMatrix mat(cmps, proj);
0037
0038 const auto [i, j] = mat.minDistancePair();
0039 BOOST_CHECK_EQUAL(std::min(i, j), 1);
0040 BOOST_CHECK_EQUAL(std::max(i, j), 2);
0041 }
0042
0043 BOOST_AUTO_TEST_CASE(test_distance_matrix_masking) {
0044 std::vector<GsfComponent> cmps = {
0045 {1. / 3., BoundVector::Constant(-2.), BoundSquareMatrix::Identity()},
0046 {1. / 3., BoundVector::Constant(+0.), BoundSquareMatrix::Identity()},
0047 {1. / 3., BoundVector::Constant(+1.), BoundSquareMatrix::Identity()},
0048 {1. / 3., BoundVector::Constant(+4.), BoundSquareMatrix::Identity()}};
0049
0050 const auto proj = [](auto &a) -> decltype(auto) { return a; };
0051 const std::size_t cmp_to_mask = 2;
0052
0053 detail::SymmetricKLDistanceMatrix mat_full(cmps, proj);
0054 mat_full.maskAssociatedDistances(cmp_to_mask);
0055
0056 cmps.erase(cmps.begin() + cmp_to_mask);
0057 detail::SymmetricKLDistanceMatrix mat_small(cmps, proj);
0058
0059 const auto [full_i, full_j] = mat_full.minDistancePair();
0060 const auto [small_i, small_j] = mat_small.minDistancePair();
0061
0062 BOOST_CHECK_EQUAL(std::min(full_i, full_j), 0);
0063 BOOST_CHECK_EQUAL(std::max(full_i, full_j), 1);
0064 BOOST_CHECK_EQUAL(full_i, small_i);
0065 BOOST_CHECK_EQUAL(full_j, small_j);
0066 }
0067
0068 BOOST_AUTO_TEST_CASE(test_distance_matrix_recompute_distance) {
0069 std::vector<GsfComponent> cmps = {
0070 {1. / 3., BoundVector::Constant(-2.), BoundSquareMatrix::Identity()},
0071 {1. / 3., BoundVector::Constant(+0.), BoundSquareMatrix::Identity()},
0072 {1. / 3., BoundVector::Constant(+1.), BoundSquareMatrix::Identity()},
0073 {1. / 3., BoundVector::Constant(+4.), BoundSquareMatrix::Identity()}};
0074
0075 const auto proj = [](auto &a) -> decltype(auto) { return a; };
0076 detail::SymmetricKLDistanceMatrix mat(cmps, proj);
0077
0078 {
0079 const auto [i, j] = mat.minDistancePair();
0080 BOOST_CHECK_EQUAL(std::min(i, j), 1);
0081 BOOST_CHECK_EQUAL(std::max(i, j), 2);
0082 }
0083
0084 cmps[3].boundPars = BoundVector::Constant(0.1);
0085 mat.recomputeAssociatedDistances(3, cmps, proj);
0086
0087 {
0088 const auto [i, j] = mat.minDistancePair();
0089 BOOST_CHECK_EQUAL(std::min(i, j), 1);
0090 BOOST_CHECK_EQUAL(std::max(i, j), 3);
0091 }
0092
0093 cmps[0].boundPars = BoundVector::Constant(1.01);
0094 mat.recomputeAssociatedDistances(0, cmps, proj);
0095
0096 {
0097 const auto [i, j] = mat.minDistancePair();
0098 BOOST_CHECK_EQUAL(std::min(i, j), 0);
0099 BOOST_CHECK_EQUAL(std::max(i, j), 2);
0100 }
0101 }
0102
0103 BOOST_AUTO_TEST_CASE(test_mixture_reduction) {
0104 auto meanAndSumOfWeights = [](const auto &cmps) {
0105 const auto mean = std::accumulate(
0106 cmps.begin(), cmps.end(), Acts::BoundVector::Zero().eval(),
0107 [](auto sum, const auto &cmp) -> Acts::BoundVector {
0108 return sum + cmp.weight * cmp.boundPars;
0109 });
0110
0111 const double sumOfWeights = std::accumulate(
0112 cmps.begin(), cmps.end(), 0.0,
0113 [](auto sum, const auto &cmp) { return sum + cmp.weight; });
0114
0115 return std::make_tuple(mean, sumOfWeights);
0116 };
0117
0118
0119 auto surface = Acts::Surface::makeShared<PlaneSurface>(Vector3{0, 0, 0},
0120 Vector3{1, 0, 0});
0121 const std::size_t NComps = 4;
0122 std::vector<GsfComponent> cmps;
0123
0124 for (auto i = 0ul; i < NComps; ++i) {
0125 GsfComponent a;
0126 a.boundPars = BoundVector::Zero();
0127 a.boundCov = BoundSquareMatrix::Identity();
0128 a.weight = 1.0 / NComps;
0129 cmps.push_back(a);
0130 }
0131
0132 cmps[0].boundPars[eBoundQOverP] = 0.5_GeV;
0133 cmps[1].boundPars[eBoundQOverP] = 1.5_GeV;
0134 cmps[2].boundPars[eBoundQOverP] = 3.5_GeV;
0135 cmps[3].boundPars[eBoundQOverP] = 4.5_GeV;
0136
0137
0138 const auto [mean0, sumOfWeights0] = meanAndSumOfWeights(cmps);
0139
0140 BOOST_CHECK_CLOSE(mean0[eBoundQOverP], 2.5_GeV, 1.e-8);
0141 BOOST_CHECK_CLOSE(sumOfWeights0, 1.0, 1.e-8);
0142
0143
0144 Acts::reduceMixtureWithKLDistance(cmps, 2, *surface);
0145
0146 BOOST_CHECK_EQUAL(cmps.size(), 2);
0147
0148 std::sort(cmps.begin(), cmps.end(), [](const auto &a, const auto &b) {
0149 return a.boundPars[eBoundQOverP] < b.boundPars[eBoundQOverP];
0150 });
0151 BOOST_CHECK_CLOSE(cmps[0].boundPars[eBoundQOverP], 1.0_GeV, 1.e-8);
0152 BOOST_CHECK_CLOSE(cmps[1].boundPars[eBoundQOverP], 4.0_GeV, 1.e-8);
0153
0154 const auto [mean1, sumOfWeights1] = meanAndSumOfWeights(cmps);
0155
0156 BOOST_CHECK_CLOSE(mean1[eBoundQOverP], 2.5_GeV, 1.e-8);
0157 BOOST_CHECK_CLOSE(sumOfWeights1, 1.0, 1.e-8);
0158
0159
0160 Acts::reduceMixtureWithKLDistance(cmps, 1, *surface);
0161
0162 BOOST_CHECK_EQUAL(cmps.size(), 1);
0163 BOOST_CHECK_CLOSE(cmps[0].boundPars[eBoundQOverP], 2.5_GeV, 1.e-8);
0164 BOOST_CHECK_CLOSE(cmps[0].weight, 1.0, 1.e-8);
0165 }
0166
0167 BOOST_AUTO_TEST_CASE(test_weight_cut_reduction) {
0168 auto dummy = Acts::Surface::makeShared<PlaneSurface>(Vector3{0, 0, 0},
0169 Vector3{1, 0, 0});
0170 std::vector<GsfComponent> cmps;
0171
0172
0173 for (auto w : {1.0, 2.0, 3.0, 4.0}) {
0174 GsfComponent a;
0175 a.boundPars = BoundVector::Zero();
0176 a.boundCov = BoundSquareMatrix::Identity();
0177 a.weight = w;
0178 cmps.push_back(a);
0179 }
0180
0181 Acts::reduceMixtureLargestWeights(cmps, 2, *dummy);
0182
0183 BOOST_CHECK_EQUAL(cmps.size(), 2);
0184 std::sort(cmps.begin(), cmps.end(),
0185 [](const auto &a, const auto &b) { return a.weight < b.weight; });
0186
0187 BOOST_CHECK_EQUAL(cmps[0].weight, 3.0);
0188 BOOST_CHECK_EQUAL(cmps[1].weight, 4.0);
0189 }