File indexing completed on 2025-10-16 08:04:36
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/EventData/detail/GenerateParameters.hpp"
0014 #include "Acts/Surfaces/StrawSurface.hpp"
0015 #include "Acts/Utilities/BinUtility.hpp"
0016 #include "Acts/Utilities/BinningType.hpp"
0017 #include "ActsExamples/Digitization/DigitizationConfig.hpp"
0018 #include "ActsExamples/Digitization/Smearers.hpp"
0019 #include "ActsExamples/Io/Json/JsonDigitizationConfig.hpp"
0020 #include "ActsFatras/Digitization/UncorrelatedHitSmearer.hpp"
0021 #include "ActsTests/CommonHelpers/FloatComparisons.hpp"
0022
0023 #include <fstream>
0024 #include <string>
0025 #include <vector>
0026
0027 #include <nlohmann/json.hpp>
0028
0029 using namespace Acts;
0030 using namespace ActsFatras;
0031 using namespace ActsExamples;
0032
0033 namespace {
0034 template <typename generator_t>
0035 struct Fixture {
0036 generator_t rng;
0037
0038 GeometryIdentifier gid;
0039 Barcode pid;
0040
0041 std::shared_ptr<Surface> surface;
0042 GeometryContext geoCtx;
0043
0044 BoundVector boundParams;
0045 FreeVector freeParams;
0046
0047 Hit hit;
0048
0049 Fixture(std::uint64_t rngSeed, std::shared_ptr<Surface> surf)
0050 : rng(rngSeed),
0051 gid(GeometryIdentifier().withVolume(1).withLayer(2).withSensitive(3)),
0052 pid(Barcode().withVertexPrimary(12).withParticle(23)),
0053 surface(std::move(surf)) {
0054 using namespace UnitLiterals;
0055 using VectorHelpers::makeVector4;
0056
0057 surface->assignGeometryId(gid);
0058
0059
0060 auto [par, cov] = detail::Test::generateBoundParametersCovariance(rng, {});
0061 boundParams = par;
0062
0063 freeParams = transformBoundToFreeParameters(*surface, geoCtx, boundParams);
0064
0065
0066 Vector4 r4;
0067 r4.segment<3>(ePos0) = freeParams.segment<3>(eFreePos0);
0068 r4[eTime] = freeParams[eFreeTime];
0069
0070 Vector4 p4;
0071 p4.segment<3>(eMom0) = freeParams.segment<3>(eFreeDir0).normalized();
0072 p4[eEnergy] = 1;
0073 p4 *= std::abs(1_e / freeParams[eFreeQOverP]);
0074
0075 hit = Hit(gid, pid, r4, p4, p4, 13);
0076 }
0077 };
0078 }
0079
0080 namespace ActsTests {
0081
0082 BOOST_AUTO_TEST_SUITE(JsonSuite)
0083
0084 BOOST_AUTO_TEST_CASE(GaussianSmearing) {
0085 nlohmann::json djson = nlohmann::json::parse(R"(
0086 {
0087 "acts-geometry-hierarchy-map" : {
0088 "format-version" : 0,
0089 "value-identifier" : "digitization-configuration"
0090 },
0091
0092 "entries"
0093 : [
0094 {
0095 "volume" : 1,
0096 "value" : {
0097 "smearing" : [
0098 {"index" : 0, "mean" : 0.0, "stddev" : 0.05, "type" : "Gauss", "forcePositiveValues" : true}
0099
0100
0101 ]
0102 }
0103 }
0104 ]
0105 })");
0106 double radius = 5.;
0107 double halfZ = 8.;
0108 Fixture<RandomEngine> f(
0109 123567, Surface::makeShared<StrawSurface>(
0110 Transform3(Translation3(0., 0., 0.)), radius, halfZ));
0111
0112
0113 auto digiConfig =
0114 DigiConfigConverter("digitization-configuration").fromJson(djson);
0115 BoundParametersSmearer<RandomEngine, 1u> s;
0116
0117 for (auto& el : digiConfig) {
0118 for (auto& smearing : el.smearingDigiConfig.params) {
0119
0120 BOOST_CHECK(smearing.forcePositiveValues);
0121 std::fill(std::begin(s.indices), std::end(s.indices),
0122 static_cast<BoundIndices>(smearing.index));
0123 std::fill(std::begin(s.smearFunctions), std::end(s.smearFunctions),
0124 smearing.smearFunction);
0125 std::fill(std::begin(s.forcePositive), std::end(s.forcePositive),
0126 smearing.forcePositiveValues);
0127 }
0128 }
0129
0130 auto ret = s(f.rng, f.hit, *f.surface, f.geoCtx);
0131
0132 BOOST_CHECK(ret.ok());
0133 auto [par, cov] = ret.value();
0134 for (std::size_t i = 0; i < s.indices.size(); i++) {
0135 BOOST_TEST_INFO("Comparing smeared measurement "
0136 << i << " originating from bound parameter "
0137 << s.indices[i]);
0138 double ref = f.boundParams[s.indices[i]];
0139 if (s.forcePositive[i]) {
0140 ref = std::abs(ref);
0141 }
0142 CHECK_CLOSE_REL(par[i], ref, 0.15);
0143 }
0144 }
0145
0146 BOOST_AUTO_TEST_CASE(DigitizationConfigRoundTrip) {
0147 std::ofstream out;
0148
0149
0150
0151
0152 DigiComponentsConfig dcf;
0153
0154 GeometricConfig gdc;
0155
0156 BinUtility segmentation;
0157 segmentation += BinUtility(336, -8.4, 8.4, open, AxisDirection::AxisX);
0158 segmentation += BinUtility(1280, -36, 36, open, AxisDirection::AxisY);
0159
0160 gdc.segmentation = segmentation;
0161 gdc.threshold = 0.01;
0162 gdc.thickness = 0.15;
0163 gdc.indices = {eBoundLoc0, eBoundLoc1};
0164 gdc.chargeSmearer = Digitization::Gauss(1.0);
0165
0166 DigiComponentsConfig dcRef;
0167 dcRef.geometricDigiConfig = gdc;
0168
0169 nlohmann::json dcJsonOut(dcRef);
0170 out.open("DigiComponentsConfig.json");
0171 out << dcJsonOut.dump(2);
0172 out.close();
0173
0174 auto in = std::ifstream("DigiComponentsConfig.json",
0175 std::ifstream::in | std::ifstream::binary);
0176 BOOST_CHECK(in.good());
0177 nlohmann::json dcJsonIn;
0178 in >> dcJsonIn;
0179 in.close();
0180
0181 DigiComponentsConfig dcTest(dcJsonIn);
0182 BOOST_CHECK(dcTest.geometricDigiConfig.indices ==
0183 dcRef.geometricDigiConfig.indices);
0184 BOOST_CHECK_EQUAL(dcTest.geometricDigiConfig.segmentation.dimensions(),
0185 dcRef.geometricDigiConfig.segmentation.dimensions());
0186 }
0187
0188 BOOST_AUTO_TEST_SUITE_END()
0189
0190 }