File indexing completed on 2025-01-18 09:13:05
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <boost/test/data/test_case.hpp>
0010 #include <boost/test/unit_test.hpp>
0011
0012 #include "Acts/Definitions/Algebra.hpp"
0013 #include "Acts/Definitions/Common.hpp"
0014 #include "Acts/Definitions/TrackParametrization.hpp"
0015 #include "Acts/Definitions/Units.hpp"
0016 #include "Acts/EventData/TransformationHelpers.hpp"
0017 #include "Acts/EventData/detail/GenerateParameters.hpp"
0018 #include "Acts/Geometry/GeometryContext.hpp"
0019 #include "Acts/Geometry/GeometryIdentifier.hpp"
0020 #include "Acts/Surfaces/PlaneSurface.hpp"
0021 #include "Acts/Surfaces/Surface.hpp"
0022 #include "Acts/Tests/CommonHelpers/FloatComparisons.hpp"
0023 #include "Acts/Utilities/Result.hpp"
0024 #include "ActsFatras/Digitization/DigitizationError.hpp"
0025 #include "ActsFatras/Digitization/UncorrelatedHitSmearer.hpp"
0026 #include "ActsFatras/EventData/Barcode.hpp"
0027 #include "ActsFatras/EventData/Hit.hpp"
0028
0029 #include <algorithm>
0030 #include <array>
0031 #include <cstddef>
0032 #include <cstdint>
0033 #include <iterator>
0034 #include <limits>
0035 #include <memory>
0036 #include <random>
0037 #include <utility>
0038
0039 namespace {
0040
0041 namespace bd = boost::unit_test::data;
0042
0043 using RandomGenerator = std::default_random_engine;
0044
0045 struct SterileSmearer {
0046 Acts::Result<std::pair<double, double>> operator()(double value,
0047 RandomGenerator& ) {
0048 return Acts::Result<std::pair<double, double>>(
0049 std::make_pair<double, double>(value + 0., 0.));
0050 }
0051 };
0052
0053 struct AddSmearer {
0054 double offset = 1.0;
0055
0056 Acts::Result<std::pair<double, double>> operator()(double value,
0057 RandomGenerator& ) {
0058 return Acts::Result<std::pair<double, double>>(
0059 std::make_pair<double, double>(value + offset, 3.));
0060 }
0061 };
0062
0063 struct InvalidSmearer {
0064 Acts::Result<std::pair<double, double>> operator()(double ,
0065 RandomGenerator& ) {
0066 return Acts::Result<std::pair<double, double>>(
0067 ActsFatras::DigitizationError::SmearingError);
0068 }
0069 };
0070
0071 template <typename generator_t>
0072 struct Fixture {
0073 generator_t rng;
0074
0075 Acts::GeometryIdentifier gid;
0076 ActsFatras::Barcode pid;
0077
0078 std::shared_ptr<Acts::Surface> surface;
0079 Acts::GeometryContext geoCtx;
0080
0081 Acts::BoundVector boundParams;
0082 Acts::FreeVector freeParams;
0083
0084 ActsFatras::Hit hit;
0085
0086 Fixture(std::uint64_t rngSeed, std::shared_ptr<Acts::Surface> surf)
0087 : rng(rngSeed),
0088 gid(Acts::GeometryIdentifier().setVolume(1).setLayer(2).setSensitive(
0089 3)),
0090 pid(ActsFatras::Barcode().setVertexPrimary(12).setParticle(23)),
0091 surface(std::move(surf)) {
0092 using namespace Acts::UnitLiterals;
0093 using Acts::VectorHelpers::makeVector4;
0094
0095 surface->assignGeometryId(gid);
0096
0097
0098 auto [par, cov] =
0099 Acts::detail::Test::generateBoundParametersCovariance(rng, {});
0100 boundParams = par;
0101
0102 freeParams =
0103 Acts::transformBoundToFreeParameters(*surface, geoCtx, boundParams);
0104
0105
0106 Acts::Vector4 r4;
0107 r4.segment<3>(Acts::ePos0) = freeParams.segment<3>(Acts::eFreePos0);
0108 r4[Acts::eTime] = freeParams[Acts::eFreeTime];
0109
0110 Acts::Vector4 p4;
0111 p4.segment<3>(Acts::eMom0) =
0112 freeParams.segment<3>(Acts::eFreeDir0).normalized();
0113 p4[Acts::eEnergy] = 1;
0114 p4 *= std::abs(1_e / freeParams[Acts::eFreeQOverP]);
0115
0116 hit = ActsFatras::Hit(gid, pid, r4, p4, p4, 13);
0117 }
0118 };
0119
0120
0121
0122 const Acts::BoundIndices boundIndices[] = {
0123 Acts::eBoundLoc0, Acts::eBoundLoc1, Acts::eBoundTime,
0124 Acts::eBoundPhi, Acts::eBoundTheta,
0125 };
0126 const Acts::FreeIndices freeIndices[] = {
0127 Acts::eFreePos0, Acts::eFreePos1, Acts::eFreePos2, Acts::eFreeTime,
0128 Acts::eFreeDir0, Acts::eFreeDir1, Acts::eFreeDir2,
0129 };
0130
0131 constexpr auto tol = 128 * std::numeric_limits<double>::epsilon();
0132
0133 }
0134
0135 BOOST_AUTO_TEST_SUITE(FatrasUncorrelatedHitSmearer)
0136
0137 BOOST_DATA_TEST_CASE(Bound1, bd::make(boundIndices), index) {
0138 Fixture<RandomGenerator> f(
0139 123, Acts::Surface::makeShared<Acts::PlaneSurface>(
0140 Acts::Transform3(Acts::Translation3(3, 2, 1))));
0141 ActsFatras::BoundParametersSmearer<RandomGenerator, 1u> s;
0142 s.indices = {index};
0143
0144
0145 {
0146 s.smearFunctions.fill(SterileSmearer{});
0147 auto ret = s(f.rng, f.hit, *f.surface, f.geoCtx);
0148 BOOST_CHECK(ret.ok());
0149 auto [par, cov] = ret.value();
0150 CHECK_CLOSE_REL(par[0], f.boundParams[index], tol);
0151 }
0152
0153 {
0154 s.smearFunctions.fill(AddSmearer{-42.0});
0155 auto ret = s(f.rng, f.hit, *f.surface, f.geoCtx);
0156 BOOST_CHECK(ret.ok());
0157 auto [par, cov] = ret.value();
0158 CHECK_CLOSE_REL(par[0], f.boundParams[index] - 42.0, tol);
0159 }
0160
0161 {
0162 s.smearFunctions.fill(InvalidSmearer{});
0163 auto ret = s(f.rng, f.hit, *f.surface, f.geoCtx);
0164 BOOST_CHECK(!ret.ok());
0165 BOOST_CHECK(ret.error());
0166 }
0167 }
0168
0169 BOOST_AUTO_TEST_CASE(BoundAll) {
0170 Fixture<RandomGenerator> f(
0171 12356, Acts::Surface::makeShared<Acts::PlaneSurface>(
0172 Acts::Transform3(Acts::Translation3(3, 2, 1))));
0173
0174 ActsFatras::BoundParametersSmearer<RandomGenerator, std::size(boundIndices)>
0175 s;
0176 std::copy(std::begin(boundIndices), std::end(boundIndices),
0177 s.indices.begin());
0178
0179
0180 {
0181 s.smearFunctions.fill(SterileSmearer{});
0182 auto ret = s(f.rng, f.hit, *f.surface, f.geoCtx);
0183 BOOST_CHECK(ret.ok());
0184 auto [par, cov] = ret.value();
0185 for (std::size_t i = 0; i < s.indices.size(); ++i) {
0186 BOOST_TEST_INFO("Comparing smeared measurement "
0187 << i << " originating from bound parameter "
0188 << s.indices[i]);
0189 CHECK_CLOSE_REL(par[i], f.boundParams[s.indices[i]], tol);
0190 }
0191 }
0192
0193 {
0194 s.smearFunctions.fill(AddSmearer{-23.0});
0195 auto ret = s(f.rng, f.hit, *f.surface, f.geoCtx);
0196 BOOST_CHECK(ret.ok());
0197 auto [par, cov] = ret.value();
0198 for (std::size_t i = 0; i < s.indices.size(); ++i) {
0199 BOOST_TEST_INFO("Comparing smeared measurement "
0200 << i << " originating from bound parameter "
0201 << s.indices[i]);
0202 CHECK_CLOSE_REL(par[i], f.boundParams[s.indices[i]] - 23.0, tol);
0203 }
0204 }
0205
0206 {
0207 s.smearFunctions.fill(SterileSmearer{});
0208 s.smearFunctions[3] = InvalidSmearer{};
0209 auto ret = s(f.rng, f.hit, *f.surface, f.geoCtx);
0210 BOOST_CHECK(!ret.ok());
0211 BOOST_CHECK(ret.error());
0212 }
0213 }
0214
0215 BOOST_DATA_TEST_CASE(Free1, bd::make(freeIndices), index) {
0216 Fixture<RandomGenerator> f(
0217 1234, Acts::Surface::makeShared<Acts::PlaneSurface>(
0218 Acts::Transform3(Acts::Translation3(3, 2, 1))));
0219 ActsFatras::FreeParametersSmearer<RandomGenerator, 1u> s;
0220 s.indices = {index};
0221
0222
0223 {
0224 s.smearFunctions.fill(SterileSmearer{});
0225 auto ret = s(f.rng, f.hit);
0226 BOOST_CHECK(ret.ok());
0227 auto [par, cov] = ret.value();
0228 CHECK_CLOSE_REL(par[0], f.freeParams[index], tol);
0229 }
0230
0231 {
0232 s.smearFunctions.fill(AddSmearer{-42.0});
0233 auto ret = s(f.rng, f.hit);
0234 BOOST_CHECK(ret.ok());
0235 auto [par, cov] = ret.value();
0236 CHECK_CLOSE_REL(par[0], f.freeParams[index] - 42.0, tol);
0237 }
0238
0239 {
0240 s.smearFunctions.fill(InvalidSmearer{});
0241 auto ret = s(f.rng, f.hit);
0242 BOOST_CHECK(!ret.ok());
0243 BOOST_CHECK(ret.error());
0244 }
0245 }
0246
0247 BOOST_AUTO_TEST_CASE(FreeAll) {
0248 Fixture<RandomGenerator> f(
0249 123567, Acts::Surface::makeShared<Acts::PlaneSurface>(
0250 Acts::Transform3(Acts::Translation3(3, 2, 1))));
0251
0252 ActsFatras::FreeParametersSmearer<RandomGenerator, std::size(freeIndices)> s;
0253 std::copy(std::begin(freeIndices), std::end(freeIndices), s.indices.begin());
0254
0255
0256 {
0257 s.smearFunctions.fill(SterileSmearer{});
0258 auto ret = s(f.rng, f.hit);
0259 BOOST_CHECK(ret.ok());
0260 auto [par, cov] = ret.value();
0261 for (std::size_t i = 0; i < s.indices.size(); ++i) {
0262 BOOST_TEST_INFO("Comparing smeared measurement "
0263 << i << " originating from free parameter "
0264 << s.indices[i]);
0265 CHECK_CLOSE_REL(par[i], f.freeParams[s.indices[i]], tol);
0266 }
0267 }
0268
0269 {
0270 s.smearFunctions.fill(AddSmearer{42.0});
0271 auto ret = s(f.rng, f.hit);
0272 BOOST_CHECK(ret.ok());
0273 auto [par, cov] = ret.value();
0274 for (std::size_t i = 0; i < s.indices.size(); ++i) {
0275 BOOST_TEST_INFO("Comparing smeared measurement "
0276 << i << " originating from free parameter "
0277 << s.indices[i]);
0278 CHECK_CLOSE_REL(par[i], f.freeParams[s.indices[i]] + 42.0, tol);
0279 }
0280 }
0281
0282 {
0283 s.smearFunctions.fill(SterileSmearer{});
0284 s.smearFunctions[3] = InvalidSmearer{};
0285 auto ret = s(f.rng, f.hit);
0286 BOOST_CHECK(!ret.ok());
0287 BOOST_CHECK(ret.error());
0288 }
0289 }
0290
0291 BOOST_AUTO_TEST_SUITE_END()