File indexing completed on 2025-08-06 08:11:38
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <boost/test/unit_test.hpp>
0010
0011 #include "Acts/Definitions/Units.hpp"
0012 #include "Acts/Surfaces/PlaneSurface.hpp"
0013 #include "Acts/Utilities/BinUtility.hpp"
0014 #include "ActsFatras/Digitization/Channelizer.hpp"
0015 #include "ActsFatras/Digitization/PlanarSurfaceDrift.hpp"
0016 #include "ActsFatras/Digitization/PlanarSurfaceMask.hpp"
0017
0018 #include <numeric>
0019
0020 using namespace Acts::UnitLiterals;
0021
0022 struct Helper {
0023 std::shared_ptr<Acts::Surface> surface;
0024 Acts::BinUtility segmentation;
0025
0026 Acts::GeometryContext gctx{};
0027 double thickness = 125_um;
0028 Acts::Vector3 driftDir = Acts::Vector3::Zero();
0029
0030 ActsFatras::Channelizer channelizer;
0031
0032 Helper() {
0033 surface = Acts::Surface::makeShared<Acts::PlaneSurface>(
0034 Acts::Vector3::Zero(), Acts::Vector3{0.0, 0.0, 1.0});
0035
0036 float pitchSize = 50_um;
0037 float min = -200_um;
0038 float max = 200_um;
0039 int bins = static_cast<int>((max - min) / pitchSize);
0040 segmentation = Acts::BinUtility(bins, min, max, Acts::BinningOption::open,
0041 Acts::BinningValue::binX);
0042 segmentation += Acts::BinUtility(bins, min, max, Acts::BinningOption::open,
0043 Acts::BinningValue::binY);
0044 }
0045
0046 auto channelize(const Acts::Vector3 &pos3, const Acts::Vector3 &dir3) const {
0047 Acts::Vector4 pos4 = Acts::Vector4::Zero();
0048 pos4.segment<3>(Acts::ePos0) = pos3;
0049 Acts::Vector4 mom4 = Acts::Vector4::Zero();
0050 mom4.segment<3>(Acts::eMom0) = dir3;
0051 ActsFatras::Hit hit({}, {}, pos4, mom4, mom4);
0052 auto res = channelizer.channelize(hit, *surface, gctx, driftDir,
0053 segmentation, thickness);
0054 BOOST_REQUIRE(res.ok());
0055 return *res;
0056 }
0057 };
0058
0059 BOOST_AUTO_TEST_CASE(test_upright_particle) {
0060 Helper helper;
0061
0062 Acts::Vector3 pos3 = Acts::Vector3{10_um, 10_um, 0.0};
0063 Acts::Vector3 dir3 = Acts::Vector3{0.0, 0.0, helper.thickness}.normalized();
0064
0065 auto segments = helper.channelize(pos3, dir3);
0066
0067 BOOST_CHECK_EQUAL(segments.size(), 1);
0068 BOOST_CHECK_CLOSE(segments[0].activation, helper.thickness, 1.e-8);
0069 }
0070
0071 BOOST_AUTO_TEST_CASE(test_tilted_particle) {
0072 Helper helper;
0073
0074 const double disp = 10_um;
0075
0076 Acts::Vector3 hitPosition = Acts::Vector3{10_um, 10_um, 0.0};
0077 Acts::Vector3 hitDirection =
0078 Acts::Vector3({disp, 0.0, helper.thickness}).normalized();
0079
0080 auto segments = helper.channelize(hitPosition, hitDirection);
0081
0082 std::cout << "Segments:\n";
0083 for (const auto &seg : segments) {
0084 std::cout << " - (" << seg.bin[0] << ", " << seg.bin[1]
0085 << "), activation: " << seg.activation << "\n";
0086 }
0087
0088 BOOST_CHECK_EQUAL(segments.size(), 1);
0089 BOOST_CHECK_CLOSE(segments[0].activation, std::hypot(disp, helper.thickness),
0090 1.e-8);
0091 }
0092
0093 BOOST_AUTO_TEST_CASE(test_more_tilted_particle) {
0094 Helper helper;
0095
0096 const double disp = 50_um;
0097
0098 Acts::Vector3 hitPosition = Acts::Vector3{10_um, 10_um, 0.0};
0099 Acts::Vector3 hitDirection =
0100 Acts::Vector3{disp, 0.0, helper.thickness}.normalized();
0101
0102 auto segments = helper.channelize(hitPosition, hitDirection);
0103
0104 BOOST_CHECK_EQUAL(segments.size(), 2);
0105 auto sum =
0106 std::accumulate(segments.begin(), segments.end(), 0.0,
0107 [](double s, auto seg) { return s + seg.activation; });
0108 BOOST_CHECK_CLOSE(sum, std::hypot(disp, helper.thickness), 1.e-8);
0109 }
0110
0111
0112 BOOST_AUTO_TEST_CASE(test_pathological_upright_particle) {
0113 Helper helper;
0114
0115 Acts::Vector3 hitPosition = Acts::Vector3{0.0, 10_um, 0.0};
0116 Acts::Vector3 hitDirection =
0117 Acts::Vector3{0.0, 0.0, helper.thickness}.normalized();
0118
0119 auto segments = helper.channelize(hitPosition, hitDirection);
0120
0121 BOOST_CHECK_EQUAL(segments.size(), 1);
0122 BOOST_CHECK_CLOSE(segments[0].activation, helper.thickness, 1.e-8);
0123 }
0124
0125
0126
0127 BOOST_AUTO_TEST_CASE(test_pathological_tilted_particle) {
0128 Helper helper;
0129
0130 double disp = 2.0_um;
0131
0132 Acts::Vector3 hitPosition = Acts::Vector3{-0.5 * disp, 10_um, 0.0};
0133 Acts::Vector3 hitDirection =
0134 Acts::Vector3{disp, 0.0, helper.thickness}.normalized();
0135
0136 auto segments = helper.channelize(hitPosition, hitDirection);
0137
0138 std::cout << "Segments:\n";
0139 for (const auto &seg : segments) {
0140 std::cout << " - (" << seg.bin[0] << ", " << seg.bin[1]
0141 << "), activation: " << seg.activation << "\n";
0142 }
0143
0144 BOOST_CHECK_EQUAL(segments.size(), 2);
0145 auto sum =
0146 std::accumulate(segments.begin(), segments.end(), 0.0,
0147 [](double s, auto seg) { return s + seg.activation; });
0148 BOOST_CHECK_CLOSE(sum, std::hypot(disp, helper.thickness), 1.e-8);
0149 }