Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-10-25 07:57:19

0001 // This file is part of the ACTS project.
0002 //
0003 // Copyright (C) 2016 CERN for the benefit of the ACTS project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
0008 
0009 #include <boost/test/unit_test.hpp>
0010 
0011 #include "Acts/Geometry/GeometryContext.hpp"
0012 #include "Acts/Surfaces/AnnulusBounds.hpp"
0013 #include "Acts/Surfaces/ConvexPolygonBounds.hpp"
0014 #include "Acts/Surfaces/DiamondBounds.hpp"
0015 #include "Acts/Surfaces/DiscSurface.hpp"
0016 #include "Acts/Surfaces/PlaneSurface.hpp"
0017 #include "Acts/Surfaces/RadialBounds.hpp"
0018 #include "Acts/Surfaces/RectangleBounds.hpp"
0019 #include "Acts/Surfaces/TrapezoidBounds.hpp"
0020 #include "ActsPlugins/ActSVG/SurfaceSvgConverter.hpp"
0021 #include "ActsPlugins/ActSVG/SvgUtils.hpp"
0022 
0023 #include <fstream>
0024 #include <numbers>
0025 
0026 using namespace Acts;
0027 using namespace ActsPlugins;
0028 
0029 namespace ActsTests {
0030 
0031 /// Helper to run planar Test
0032 ///
0033 /// @param surface
0034 /// @param identification
0035 void runPlanarTests(const Surface& surface, const Svg::Style& style,
0036                     const std::string& identification) {
0037   // Default Geometry context
0038   GeometryContext geoCtx;
0039 
0040   using SurfaceOptions = Svg::SurfaceConverter::Options;
0041 
0042   SurfaceOptions sOptions;
0043   sOptions.style = style;
0044   sOptions.templateSurface = true;
0045 
0046   // Svg proto object & actual object
0047   auto svgTemplate = Svg::SurfaceConverter::convert(geoCtx, surface, sOptions);
0048   auto xyTemplate = Svg::View::xy(svgTemplate, identification + "_template");
0049   Svg::toFile({xyTemplate}, xyTemplate._id + ".svg");
0050   // Positioned
0051   sOptions.templateSurface = false;
0052   auto svgObject = Svg::SurfaceConverter::convert(geoCtx, surface, sOptions);
0053   auto xyObject = Svg::View::xy(svgObject, identification);
0054   auto xyAxes = Svg::axesXY(static_cast<double>(xyObject._x_range[0]),
0055                             static_cast<double>(xyObject._x_range[1]),
0056                             static_cast<double>(xyObject._y_range[0]),
0057                             static_cast<double>(xyObject._y_range[1]));
0058 
0059   Svg::toFile({xyObject, xyAxes}, xyObject._id + ".svg");
0060   // As sheet
0061   auto svgSheet = Svg::Sheet::xy(svgTemplate, identification + "_sheet");
0062   Svg::toFile({svgSheet}, svgSheet._id + ".svg");
0063 }
0064 
0065 BOOST_AUTO_TEST_SUITE(ActSvg)
0066 
0067 BOOST_AUTO_TEST_CASE(PlanarSurfaces) {
0068   // Planar style
0069   Svg::Style planarStyle;
0070   planarStyle.fillColor = {51, 153, 255};
0071   planarStyle.fillOpacity = 0.75;
0072   planarStyle.highlightColor = {255, 153, 51};
0073   planarStyle.highlights = {"mouseover", "mouseout"};
0074   planarStyle.strokeWidth = 0.5;
0075   planarStyle.quarterSegments = 0u;
0076 
0077   // Rectangle case
0078   auto rectangleBounds = std::make_shared<RectangleBounds>(36., 64.);
0079   auto transform = Transform3::Identity();
0080   transform.pretranslate(Vector3{20., 20., 100.});
0081   auto rectanglePlane =
0082       Surface::makeShared<PlaneSurface>(transform, rectangleBounds);
0083   runPlanarTests(*rectanglePlane, planarStyle, "rectangle");
0084 
0085   // Trapezoid case:
0086   auto trapezoidBounds = std::make_shared<TrapezoidBounds>(36., 64., 105.);
0087   auto trapeozidPlane =
0088       Surface::makeShared<PlaneSurface>(transform, trapezoidBounds);
0089   runPlanarTests(*trapeozidPlane, planarStyle, "trapezoid");
0090 
0091   // Trapezoid case shifted and rotated
0092   double phi = std::numbers::pi / 8.;
0093   double radius = 150.;
0094   Vector3 center(radius * std::cos(phi), radius * std::sin(phi), 0.);
0095 
0096   Vector3 localY(std::cos(phi), std::sin(phi), 0.);
0097   Vector3 localZ(0., 0., 1.);
0098   Vector3 localX = localY.cross(localZ);
0099   RotationMatrix3 rotation;
0100   rotation.col(0) = localX;
0101   rotation.col(1) = localY;
0102   rotation.col(2) = localZ;
0103   transform = Transform3(Translation3(center) * rotation);
0104   // Create the module surface
0105   auto trapeozidPlaneTransformed =
0106       Surface::makeShared<PlaneSurface>(transform, trapezoidBounds);
0107 
0108   runPlanarTests(*trapeozidPlaneTransformed, planarStyle, "trapezoid_rotated");
0109   // A reference test for the rotated one
0110   GeometryContext geoCtx;
0111   actsvg::proto::surface<std::vector<Vector3>> reference;
0112   reference._vertices =
0113       trapeozidPlaneTransformed->polyhedronRepresentation(geoCtx, 1u).vertices;
0114   auto referenceTrapezoid = Svg::View::xy(reference, "trapezoid");
0115   auto referenceAxes = Svg::axesXY(-200., 200., -200., 200);
0116   Svg::toFile({referenceTrapezoid, referenceAxes}, "trapezoid_reference.svg");
0117 
0118   // Let's create one with a flipped z-axis
0119   Vector3 flocalZ(0., 0., -1.);
0120   Vector3 flocalX = localY.cross(flocalZ);
0121   RotationMatrix3 frotation;
0122   frotation.col(0) = flocalX;
0123   frotation.col(1) = localY;
0124   frotation.col(2) = flocalZ;
0125   auto ftransform = Transform3(Translation3(center) * frotation);
0126   // Create the module surface
0127   auto ftrapeozidPlaneTransformed =
0128       Surface::makeShared<PlaneSurface>(ftransform, trapezoidBounds);
0129 
0130   runPlanarTests(*ftrapeozidPlaneTransformed, planarStyle,
0131                  "flipped_trapezoid_rotated");
0132   actsvg::proto::surface<std::vector<Vector3>> freference;
0133   freference._vertices =
0134       ftrapeozidPlaneTransformed->polyhedronRepresentation(geoCtx, 1u).vertices;
0135 
0136   auto freferenceTrapezoid = Svg::View::xy(freference, "flipped_trapezoid");
0137   Svg::toFile({freferenceTrapezoid, referenceAxes},
0138               "flipped_trapezoid_reference.svg");
0139 
0140   // Diamond
0141   auto diamondBounds = std::make_shared<DiamondBounds>(36., 64., 14., 40., 30.);
0142   transform = Transform3::Identity();
0143   auto diamond = Surface::makeShared<PlaneSurface>(transform, diamondBounds);
0144   runPlanarTests(*diamond, planarStyle, "diamond");
0145 
0146   // ConvexPolygon
0147   std::vector<Vector2> vertices = {
0148       {-10., -10.}, {10., -15.}, {20., 5.}, {-5., 15.}, {-12, 0.}};
0149   auto polygonBounds = std::make_shared<ConvexPolygonBounds<5u>>(vertices);
0150   auto polygon = Surface::makeShared<PlaneSurface>(transform, polygonBounds);
0151   runPlanarTests(*polygon, planarStyle, "polygon");
0152 }
0153 
0154 BOOST_AUTO_TEST_CASE(DiscSurfaces) {
0155   // Planar style
0156   Svg::Style discStyle;
0157   discStyle.fillColor = {0, 204, 153};
0158   discStyle.fillOpacity = 0.75;
0159   discStyle.highlightColor = {153, 204, 0};
0160   discStyle.highlights = {"mouseover", "mouseout"};
0161   discStyle.strokeWidth = 0.5;
0162   discStyle.quarterSegments = 72u;
0163 
0164   auto transform = Transform3::Identity();
0165   transform.pretranslate(Vector3{20., 20., 100.});
0166 
0167   // Full disc case
0168   auto fullDiscBounds = std::make_shared<RadialBounds>(0., 64.);
0169   auto fullDisc = Surface::makeShared<DiscSurface>(transform, fullDiscBounds);
0170   runPlanarTests(*fullDisc, discStyle, "full_disc");
0171 
0172   // Full ring case:
0173   auto fullRingBounds = std::make_shared<RadialBounds>(36., 64.);
0174   auto fullRing = Surface::makeShared<DiscSurface>(transform, fullRingBounds);
0175   runPlanarTests(*fullRing, discStyle, "full_ring");
0176 
0177   // Sectorial disc case
0178   auto sectoralDiscBounds = std::make_shared<RadialBounds>(
0179       0., 64., std::numbers::pi / 4., std::numbers::pi / 2.);
0180   auto sectoralDisc =
0181       Surface::makeShared<DiscSurface>(transform, sectoralDiscBounds);
0182   runPlanarTests(*sectoralDisc, discStyle, "full_disc");
0183 
0184   // Annulus shape
0185   double minRadius = 7.2;
0186   double maxRadius = 12.0;
0187   double minPhi = 0.74195;
0188   double maxPhi = 1.33970;
0189 
0190   Vector2 offset{-3., 2.};
0191 
0192   auto annulusDiscBounds = std::make_shared<AnnulusBounds>(
0193       minRadius, maxRadius, minPhi, maxPhi, offset);
0194   auto annulusDisc =
0195       Surface::makeShared<DiscSurface>(transform, annulusDiscBounds);
0196   runPlanarTests(*annulusDisc, discStyle, "annulus_disc");
0197 }
0198 
0199 BOOST_AUTO_TEST_SUITE_END()
0200 
0201 }  // namespace ActsTests