File indexing completed on 2025-01-18 09:13:07
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <boost/test/unit_test.hpp>
0010
0011 #include "Acts/Geometry/GeometryContext.hpp"
0012 #include "Acts/Plugins/ActSVG/SurfaceSvgConverter.hpp"
0013 #include "Acts/Plugins/ActSVG/SvgUtils.hpp"
0014 #include "Acts/Surfaces/AnnulusBounds.hpp"
0015 #include "Acts/Surfaces/ConvexPolygonBounds.hpp"
0016 #include "Acts/Surfaces/DiamondBounds.hpp"
0017 #include "Acts/Surfaces/DiscSurface.hpp"
0018 #include "Acts/Surfaces/PlaneSurface.hpp"
0019 #include "Acts/Surfaces/RadialBounds.hpp"
0020 #include "Acts/Surfaces/RectangleBounds.hpp"
0021 #include "Acts/Surfaces/TrapezoidBounds.hpp"
0022
0023 #include <fstream>
0024 #include <numbers>
0025
0026 BOOST_AUTO_TEST_SUITE(ActSvg)
0027
0028 namespace {
0029
0030
0031
0032
0033
0034 void runPlanarTests(const Acts::Surface& surface, const Acts::Svg::Style& style,
0035 const std::string& identification) {
0036
0037 Acts::GeometryContext geoCtx;
0038
0039 using SurfaceOptions = Acts::Svg::SurfaceConverter::Options;
0040
0041 SurfaceOptions sOptions;
0042 sOptions.style = style;
0043 sOptions.templateSurface = true;
0044
0045
0046 auto svgTemplate =
0047 Acts::Svg::SurfaceConverter::convert(geoCtx, surface, sOptions);
0048 auto xyTemplate =
0049 Acts::Svg::View::xy(svgTemplate, identification + "_template");
0050 Acts::Svg::toFile({xyTemplate}, xyTemplate._id + ".svg");
0051
0052 sOptions.templateSurface = false;
0053 auto svgObject =
0054 Acts::Svg::SurfaceConverter::convert(geoCtx, surface, sOptions);
0055 auto xyObject = Acts::Svg::View::xy(svgObject, identification);
0056 auto xyAxes = Acts::Svg::axesXY(static_cast<double>(xyObject._x_range[0]),
0057 static_cast<double>(xyObject._x_range[1]),
0058 static_cast<double>(xyObject._y_range[0]),
0059 static_cast<double>(xyObject._y_range[1]));
0060
0061 Acts::Svg::toFile({xyObject, xyAxes}, xyObject._id + ".svg");
0062
0063 auto svgSheet = Acts::Svg::Sheet::xy(svgTemplate, identification + "_sheet");
0064 Acts::Svg::toFile({svgSheet}, svgSheet._id + ".svg");
0065 }
0066
0067 }
0068
0069 BOOST_AUTO_TEST_CASE(PlanarSurfaces) {
0070
0071 Acts::Svg::Style planarStyle;
0072 planarStyle.fillColor = {51, 153, 255};
0073 planarStyle.fillOpacity = 0.75;
0074 planarStyle.highlightColor = {255, 153, 51};
0075 planarStyle.highlights = {"mouseover", "mouseout"};
0076 planarStyle.strokeWidth = 0.5;
0077 planarStyle.quarterSegments = 0u;
0078
0079
0080 auto rectangleBounds = std::make_shared<Acts::RectangleBounds>(36., 64.);
0081 auto transform = Acts::Transform3::Identity();
0082 transform.pretranslate(Acts::Vector3{20., 20., 100.});
0083 auto rectanglePlane =
0084 Acts::Surface::makeShared<Acts::PlaneSurface>(transform, rectangleBounds);
0085 runPlanarTests(*rectanglePlane, planarStyle, "rectangle");
0086
0087
0088 auto trapezoidBounds =
0089 std::make_shared<Acts::TrapezoidBounds>(36., 64., 105.);
0090 auto trapeozidPlane =
0091 Acts::Surface::makeShared<Acts::PlaneSurface>(transform, trapezoidBounds);
0092 runPlanarTests(*trapeozidPlane, planarStyle, "trapezoid");
0093
0094
0095 double phi = std::numbers::pi / 8.;
0096 double radius = 150.;
0097 Acts::Vector3 center(radius * std::cos(phi), radius * std::sin(phi), 0.);
0098
0099 Acts::Vector3 localY(std::cos(phi), std::sin(phi), 0.);
0100 Acts::Vector3 localZ(0., 0., 1.);
0101 Acts::Vector3 localX = localY.cross(localZ);
0102 Acts::RotationMatrix3 rotation;
0103 rotation.col(0) = localX;
0104 rotation.col(1) = localY;
0105 rotation.col(2) = localZ;
0106 transform = Acts::Transform3(Acts::Translation3(center) * rotation);
0107
0108 auto trapeozidPlaneTransformed =
0109 Acts::Surface::makeShared<Acts::PlaneSurface>(transform, trapezoidBounds);
0110
0111 runPlanarTests(*trapeozidPlaneTransformed, planarStyle, "trapezoid_rotated");
0112
0113 Acts::GeometryContext geoCtx;
0114 actsvg::proto::surface<std::vector<Acts::Vector3>> reference;
0115 reference._vertices =
0116 trapeozidPlaneTransformed->polyhedronRepresentation(geoCtx, 1u).vertices;
0117 auto referenceTrapezoid = Acts::Svg::View::xy(reference, "trapezoid");
0118 auto referenceAxes = Acts::Svg::axesXY(-200., 200., -200., 200);
0119 Acts::Svg::toFile({referenceTrapezoid, referenceAxes},
0120 "trapezoid_reference.svg");
0121
0122
0123 Acts::Vector3 flocalZ(0., 0., -1.);
0124 Acts::Vector3 flocalX = localY.cross(flocalZ);
0125 Acts::RotationMatrix3 frotation;
0126 frotation.col(0) = flocalX;
0127 frotation.col(1) = localY;
0128 frotation.col(2) = flocalZ;
0129 auto ftransform = Acts::Transform3(Acts::Translation3(center) * frotation);
0130
0131 auto ftrapeozidPlaneTransformed =
0132 Acts::Surface::makeShared<Acts::PlaneSurface>(ftransform,
0133 trapezoidBounds);
0134
0135 runPlanarTests(*ftrapeozidPlaneTransformed, planarStyle,
0136 "flipped_trapezoid_rotated");
0137 actsvg::proto::surface<std::vector<Acts::Vector3>> freference;
0138 freference._vertices =
0139 ftrapeozidPlaneTransformed->polyhedronRepresentation(geoCtx, 1u).vertices;
0140
0141 auto freferenceTrapezoid =
0142 Acts::Svg::View::xy(freference, "flipped_trapezoid");
0143 Acts::Svg::toFile({freferenceTrapezoid, referenceAxes},
0144 "flipped_trapezoid_reference.svg");
0145
0146
0147 auto diamondBounds =
0148 std::make_shared<Acts::DiamondBounds>(36., 64., 14., 40., 30.);
0149 transform = Acts::Transform3::Identity();
0150 auto diamond =
0151 Acts::Surface::makeShared<Acts::PlaneSurface>(transform, diamondBounds);
0152 runPlanarTests(*diamond, planarStyle, "diamond");
0153
0154
0155 std::vector<Acts::Vector2> vertices = {
0156 {-10., -10.}, {10., -15.}, {20., 5.}, {-5., 15.}, {-12, 0.}};
0157 auto polygonBounds =
0158 std::make_shared<Acts::ConvexPolygonBounds<5u>>(vertices);
0159 auto polygon =
0160 Acts::Surface::makeShared<Acts::PlaneSurface>(transform, polygonBounds);
0161 runPlanarTests(*polygon, planarStyle, "polygon");
0162 }
0163
0164 BOOST_AUTO_TEST_CASE(DiscSurfaces) {
0165
0166 Acts::Svg::Style discStyle;
0167 discStyle.fillColor = {0, 204, 153};
0168 discStyle.fillOpacity = 0.75;
0169 discStyle.highlightColor = {153, 204, 0};
0170 discStyle.highlights = {"mouseover", "mouseout"};
0171 discStyle.strokeWidth = 0.5;
0172 discStyle.quarterSegments = 72u;
0173
0174 auto transform = Acts::Transform3::Identity();
0175 transform.pretranslate(Acts::Vector3{20., 20., 100.});
0176
0177
0178 auto fullDiscBounds = std::make_shared<Acts::RadialBounds>(0., 64.);
0179 auto fullDisc =
0180 Acts::Surface::makeShared<Acts::DiscSurface>(transform, fullDiscBounds);
0181 runPlanarTests(*fullDisc, discStyle, "full_disc");
0182
0183
0184 auto fullRingBounds = std::make_shared<Acts::RadialBounds>(36., 64.);
0185 auto fullRing =
0186 Acts::Surface::makeShared<Acts::DiscSurface>(transform, fullRingBounds);
0187 runPlanarTests(*fullRing, discStyle, "full_ring");
0188
0189
0190 auto sectoralDiscBounds = std::make_shared<Acts::RadialBounds>(
0191 0., 64., std::numbers::pi / 4., std::numbers::pi / 2.);
0192 auto sectoralDisc = Acts::Surface::makeShared<Acts::DiscSurface>(
0193 transform, sectoralDiscBounds);
0194 runPlanarTests(*sectoralDisc, discStyle, "full_disc");
0195
0196
0197 double minRadius = 7.2;
0198 double maxRadius = 12.0;
0199 double minPhi = 0.74195;
0200 double maxPhi = 1.33970;
0201
0202 Acts::Vector2 offset{-3., 2.};
0203
0204 auto annulusDiscBounds = std::make_shared<Acts::AnnulusBounds>(
0205 minRadius, maxRadius, minPhi, maxPhi, offset);
0206 auto annulusDisc = Acts::Surface::makeShared<Acts::DiscSurface>(
0207 transform, annulusDiscBounds);
0208 runPlanarTests(*annulusDisc, discStyle, "annulus_disc");
0209 }
0210
0211 BOOST_AUTO_TEST_SUITE_END()