File indexing completed on 2025-08-06 08:11:39
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/Tolerance.hpp"
0014 #include "Acts/Geometry/GeometryContext.hpp"
0015 #include "Acts/Surfaces/DiscBounds.hpp"
0016 #include "Acts/Surfaces/DiscSurface.hpp"
0017 #include "Acts/Surfaces/PlanarBounds.hpp"
0018 #include "Acts/Surfaces/PlaneSurface.hpp"
0019 #include "Acts/Surfaces/RadialBounds.hpp"
0020 #include "Acts/Surfaces/RectangleBounds.hpp"
0021 #include "Acts/Surfaces/Surface.hpp"
0022 #include "Acts/Tests/CommonHelpers/FloatComparisons.hpp"
0023 #include "Acts/Utilities/Helpers.hpp"
0024 #include "Acts/Utilities/Result.hpp"
0025 #include "ActsFatras/Digitization/PlanarSurfaceMask.hpp"
0026
0027 #include <array>
0028 #include <cmath>
0029 #include <fstream>
0030 #include <memory>
0031 #include <string>
0032 #include <tuple>
0033 #include <utility>
0034 #include <vector>
0035
0036 #include "DigitizationCsvOutput.hpp"
0037 #include "PlanarSurfaceTestBeds.hpp"
0038
0039 namespace bdata = boost::unit_test::data;
0040
0041 namespace ActsFatras {
0042
0043 std::vector<std::array<std::ofstream, 3>> out;
0044
0045 BOOST_AUTO_TEST_SUITE(Digitization)
0046
0047 BOOST_AUTO_TEST_CASE(PlaneMaskRectangleBounds) {
0048 auto rectangleBounds = std::make_shared<Acts::RectangleBounds>(2., 3.5);
0049 auto planeSurface = Acts::Surface::makeShared<Acts::PlaneSurface>(
0050 Acts::Transform3::Identity(), rectangleBounds);
0051
0052 ActsFatras::PlanarSurfaceMask psm;
0053
0054
0055 std::array<Acts::Vector2, 2> segment = {Acts::Vector2(2.5, -4.5),
0056 Acts::Vector2(-1., -1.)};
0057 auto clipped = psm.apply(*planeSurface, segment).value();
0058
0059 CHECK_CLOSE_ABS(clipped[1].x(), segment[1].x(), Acts::s_epsilon);
0060 CHECK_CLOSE_ABS(clipped[1].y(), segment[1].y(), Acts::s_epsilon);
0061 CHECK_CLOSE_ABS(clipped[0].x(), 1.5, Acts::s_epsilon);
0062 CHECK_CLOSE_ABS(clipped[0].y(), -3.5, Acts::s_epsilon);
0063
0064
0065 segment = {Acts::Vector2(1., 4.), Acts::Vector2(3., 2.)};
0066 clipped = psm.apply(*planeSurface, segment).value();
0067
0068 CHECK_CLOSE_ABS(clipped[1].x(), 2., Acts::s_epsilon);
0069 CHECK_CLOSE_ABS(clipped[1].y(), 3., Acts::s_epsilon);
0070 CHECK_CLOSE_ABS(clipped[0].x(), 1.5, Acts::s_epsilon);
0071 CHECK_CLOSE_ABS(clipped[0].y(), 3.5, Acts::s_epsilon);
0072
0073
0074 segment = {Acts::Vector2(-1., 0.5), Acts::Vector2(0., 2.)};
0075 clipped = psm.apply(*planeSurface, segment).value();
0076
0077 CHECK_CLOSE_ABS(clipped[0].x(), segment[0].x(), Acts::s_epsilon);
0078 CHECK_CLOSE_ABS(clipped[0].y(), segment[0].y(), Acts::s_epsilon);
0079 CHECK_CLOSE_ABS(clipped[1].x(), segment[1].x(), Acts::s_epsilon);
0080 CHECK_CLOSE_ABS(clipped[1].y(), segment[1].y(), Acts::s_epsilon);
0081 }
0082
0083 BOOST_AUTO_TEST_CASE(DiscMaskRadialBounds) {
0084 auto discRadial =
0085 std::make_shared<Acts::RadialBounds>(2., 7.5, M_PI_4, M_PI_2);
0086 auto discSurface = Acts::Surface::makeShared<Acts::DiscSurface>(
0087 Acts::Transform3::Identity(), discRadial);
0088
0089 ActsFatras::PlanarSurfaceMask psm;
0090
0091
0092 std::array<Acts::Vector2, 2> segment = {Acts::Vector2(0.5, 1.8),
0093 Acts::Vector2(0.9, 6.)};
0094 auto clipped = psm.apply(*discSurface, segment).value();
0095
0096 CHECK_CLOSE_ABS(clipped[1].x(), segment[1].x(), Acts::s_epsilon);
0097 CHECK_CLOSE_ABS(clipped[1].y(), segment[1].y(), Acts::s_epsilon);
0098 CHECK_CLOSE_ABS(Acts::VectorHelpers::perp(clipped[0]), 2.,
0099 5 * Acts::s_epsilon);
0100
0101
0102 segment = {Acts::Vector2(0.5, 2.8), Acts::Vector2(0.9, 8.5)};
0103 clipped = psm.apply(*discSurface, segment).value();
0104
0105 CHECK_CLOSE_ABS(clipped[0].x(), segment[0].x(), Acts::s_epsilon);
0106 CHECK_CLOSE_ABS(clipped[0].y(), segment[0].y(), Acts::s_epsilon);
0107 CHECK_CLOSE_ABS(Acts::VectorHelpers::perp(clipped[1]), 7.5,
0108 5 * Acts::s_epsilon);
0109
0110
0111 segment = {Acts::Vector2(0.5, 1.8), Acts::Vector2(0.9, 8.5)};
0112 clipped = psm.apply(*discSurface, segment).value();
0113 CHECK_CLOSE_ABS(Acts::VectorHelpers::perp(clipped[0]), 2.,
0114 5 * Acts::s_epsilon);
0115 CHECK_CLOSE_ABS(Acts::VectorHelpers::perp(clipped[1]), 7.5,
0116 5 * Acts::s_epsilon);
0117
0118 segment = {Acts::Vector2(2.8, 2.5), Acts::Vector2(0., 3.5)};
0119 clipped = psm.apply(*discSurface, segment).value();
0120 CHECK_CLOSE_ABS(Acts::VectorHelpers::phi(clipped[0]), M_PI_4,
0121 Acts::s_epsilon);
0122
0123
0124 segment = {Acts::Vector2(0., 3.5), Acts::Vector2(-8., 5.)};
0125 clipped = psm.apply(*discSurface, segment).value();
0126 CHECK_CLOSE_ABS(Acts::VectorHelpers::phi(clipped[1]), M_PI_2 + M_PI_4,
0127 Acts::s_epsilon);
0128 }
0129
0130 std::vector<std::array<std::ofstream, 3>> segmentOutput;
0131 int ntests = 100;
0132
0133
0134 BOOST_DATA_TEST_CASE(
0135 RandomPlanarSurfaceMask,
0136 bdata::random((
0137 bdata::engine = std::mt19937(), bdata::seed = 1,
0138 bdata::distribution = std::uniform_real_distribution<double>(0., 1.))) ^
0139 bdata::random((bdata::engine = std::mt19937(), bdata::seed = 2,
0140 bdata::distribution =
0141 std::uniform_real_distribution<double>(0., 1.))) ^
0142 bdata::random((bdata::engine = std::mt19937(), bdata::seed = 3,
0143 bdata::distribution =
0144 std::uniform_real_distribution<double>(0., 1.))) ^
0145 bdata::random((bdata::engine = std::mt19937(), bdata::seed = 4,
0146 bdata::distribution =
0147 std::uniform_real_distribution<double>(0., 1.))) ^
0148 bdata::xrange(ntests),
0149 startR0, startR1, endR0, endR1, index) {
0150 Acts::GeometryContext geoCtx;
0151
0152 ActsFatras::PlanarSurfaceMask psm;
0153
0154
0155 PlanarSurfaceTestBeds pstd;
0156
0157 auto testBeds = pstd(1.1);
0158
0159 DigitizationCsvOutput csvHelper;
0160
0161 int itb = 0;
0162 for (const auto& tb : testBeds) {
0163 const auto& name = std::get<0>(tb);
0164 const auto* surface = (std::get<1>(tb)).get();
0165 const auto& randomizer = std::get<3>(tb);
0166
0167 if (index == 0) {
0168 std::ofstream shape;
0169 const Acts::Vector2 centerXY = surface->center(geoCtx).segment<2>(0);
0170
0171
0172 shape.open("PlanarSurfaceMask" + name + "Borders.csv");
0173 if (surface->type() == Acts::Surface::Plane) {
0174 const auto* pBounds =
0175 static_cast<const Acts::PlanarBounds*>(&(surface->bounds()));
0176 csvHelper.writePolygon(shape, pBounds->vertices(1), -centerXY);
0177 } else if (surface->type() == Acts::Surface::Disc) {
0178 const auto* dBounds =
0179 static_cast<const Acts::DiscBounds*>(&(surface->bounds()));
0180 csvHelper.writePolygon(shape, dBounds->vertices(72), -centerXY);
0181 }
0182
0183 segmentOutput.push_back(std::array<std::ofstream, 3>());
0184 segmentOutput[itb][0].open("PlanarSurfaceMask" + name + "Inside.csv");
0185 segmentOutput[itb][1].open("PlanarSurfaceMask" + name + "Clipped.csv");
0186 segmentOutput[itb][2].open("PlanarSurfaceMask" + name + "Outside.csv");
0187 }
0188
0189 auto start = randomizer(startR0, startR1);
0190 auto end = randomizer(endR0, endR1);
0191
0192 std::array<Acts::Vector2, 2> segment = {start, end};
0193 auto clippedTest = psm.apply(*surface, segment);
0194 if (clippedTest.ok()) {
0195 auto clipped = clippedTest.value();
0196 if (segment == clipped) {
0197 csvHelper.writeLine(segmentOutput[itb][0], start, end);
0198 } else {
0199 csvHelper.writeLine(segmentOutput[itb][1], clipped[0], clipped[1]);
0200 }
0201 } else {
0202 csvHelper.writeLine(segmentOutput[itb][2], start, end);
0203 }
0204 ++itb;
0205 }
0206
0207
0208 if (itb == ntests - 1) {
0209 segmentOutput[itb][0].close();
0210 segmentOutput[itb][1].close();
0211 segmentOutput[itb][2].close();
0212 }
0213 }
0214
0215 BOOST_AUTO_TEST_SUITE_END()
0216
0217 }