Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SurfaceSvgConverterTests.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file SurfaceSvgConverterTests.cpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2022 CERN for the benefit of the Acts project
4 //
5 // This Source Code Form is subject to the terms of the Mozilla Public
6 // License, v. 2.0. If a copy of the MPL was not distributed with this
7 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 
9 #include <boost/test/unit_test.hpp>
10 
22 
23 #include <fstream>
24 
25 BOOST_AUTO_TEST_SUITE(ActSvg)
26 
27 namespace {
28 
33 void runPlanarTests(const Acts::Surface& surface, const Acts::Svg::Style& style,
34  const std::string& identification) {
35  // Default Geometry context
37 
38  using SurfaceOptions = Acts::Svg::SurfaceConverter::Options;
39 
40  SurfaceOptions sOptions;
41  sOptions.style = style;
42  sOptions.templateSurface = true;
43 
44  // Svg proto object & actual object
45  auto svgTemplate =
46  Acts::Svg::SurfaceConverter::convert(geoCtx, surface, sOptions);
47  auto xyTemplate =
48  Acts::Svg::View::xy(svgTemplate, identification + "_template");
49  Acts::Svg::toFile({xyTemplate}, xyTemplate._id + ".svg");
50  // Positioned
51  sOptions.templateSurface = false;
52  auto svgObject =
53  Acts::Svg::SurfaceConverter::convert(geoCtx, surface, sOptions);
54  auto xyObject = Acts::Svg::View::xy(svgObject, identification);
55  auto xyAxes =
56  Acts::Svg::axesXY(static_cast<Acts::ActsScalar>(xyObject._x_range[0]),
57  static_cast<Acts::ActsScalar>(xyObject._x_range[1]),
58  static_cast<Acts::ActsScalar>(xyObject._y_range[0]),
59  static_cast<Acts::ActsScalar>(xyObject._y_range[1]));
60 
61  Acts::Svg::toFile({xyObject, xyAxes}, xyObject._id + ".svg");
62  // As sheet
63  auto svgSheet = Acts::Svg::Sheet::xy(svgTemplate, identification + "_sheet");
64  Acts::Svg::toFile({svgSheet}, svgSheet._id + ".svg");
65 }
66 
67 } // namespace
68 
69 BOOST_AUTO_TEST_CASE(PlanarSurfaces) {
70  // Planar style
71  Acts::Svg::Style planarStyle;
72  planarStyle.fillColor = {51, 153, 255};
73  planarStyle.fillOpacity = 0.75;
74  planarStyle.highlightColor = {255, 153, 51};
75  planarStyle.highlights = {"mouseover", "mouseout"};
76  planarStyle.strokeWidth = 0.5;
77  planarStyle.nSegments = 0u;
78 
79  // Rectangle case
80  auto rectangleBounds = std::make_shared<Acts::RectangleBounds>(36., 64.);
81  auto transform = Acts::Transform3::Identity();
82  transform.pretranslate(Acts::Vector3{20., 20., 100.});
83  auto rectanglePlane =
84  Acts::Surface::makeShared<Acts::PlaneSurface>(transform, rectangleBounds);
85  runPlanarTests(*rectanglePlane, planarStyle, "rectangle");
86 
87  // Trapezoid case:
88  auto trapezoidBounds =
89  std::make_shared<Acts::TrapezoidBounds>(36., 64., 105.);
90  auto trapeozidPlane =
91  Acts::Surface::makeShared<Acts::PlaneSurface>(transform, trapezoidBounds);
92  runPlanarTests(*trapeozidPlane, planarStyle, "trapezoid");
93 
94  // Trapezoid case shifted and rotated
95  Acts::ActsScalar phi = 0.125 * M_PI;
96  Acts::ActsScalar radius = 150.;
97  Acts::Vector3 center(radius * std::cos(phi), radius * std::sin(phi), 0.);
98 
99  Acts::Vector3 localY(std::cos(phi), std::sin(phi), 0.);
100  Acts::Vector3 localZ(0., 0., 1.);
101  Acts::Vector3 localX = localY.cross(localZ);
102  Acts::RotationMatrix3 rotation;
103  rotation.col(0) = localX;
104  rotation.col(1) = localY;
105  rotation.col(2) = localZ;
106  transform = Acts::Transform3(Acts::Translation3(center) * rotation);
107  // Create the module surface
108  auto trapeozidPlaneTransformed =
109  Acts::Surface::makeShared<Acts::PlaneSurface>(transform, trapezoidBounds);
110 
111  runPlanarTests(*trapeozidPlaneTransformed, planarStyle, "trapezoid_rotated");
112  // A reference test for the rotated one
114  actsvg::proto::surface<std::vector<Acts::Vector3>> reference;
115  reference._vertices =
116  trapeozidPlaneTransformed->polyhedronRepresentation(geoCtx, 1u).vertices;
117  auto referenceTrapezoid = Acts::Svg::View::xy(reference, "trapezoid");
118  auto referenceAxes = Acts::Svg::axesXY(-200., 200., -200., 200);
119  Acts::Svg::toFile({referenceTrapezoid, referenceAxes},
120  "trapezoid_reference.svg");
121 
122  // Let's create one with a flipped z-axis
123  Acts::Vector3 flocalZ(0., 0., -1.);
124  Acts::Vector3 flocalX = localY.cross(flocalZ);
125  Acts::RotationMatrix3 frotation;
126  frotation.col(0) = flocalX;
127  frotation.col(1) = localY;
128  frotation.col(2) = flocalZ;
129  auto ftransform = Acts::Transform3(Acts::Translation3(center) * frotation);
130  // Create the module surface
131  auto ftrapeozidPlaneTransformed =
132  Acts::Surface::makeShared<Acts::PlaneSurface>(ftransform,
133  trapezoidBounds);
134 
135  runPlanarTests(*ftrapeozidPlaneTransformed, planarStyle,
136  "flipped_trapezoid_rotated");
137  actsvg::proto::surface<std::vector<Acts::Vector3>> freference;
138  freference._vertices =
139  ftrapeozidPlaneTransformed->polyhedronRepresentation(geoCtx, 1u).vertices;
140 
141  auto freferenceTrapezoid =
142  Acts::Svg::View::xy(freference, "flipped_trapezoid");
143  Acts::Svg::toFile({freferenceTrapezoid, referenceAxes},
144  "flipped_trapezoid_reference.svg");
145 
146  // Diamond
147  auto diamondBounds =
148  std::make_shared<Acts::DiamondBounds>(36., 64., 14., 40., 30.);
149  transform = Acts::Transform3::Identity();
150  auto diamond =
151  Acts::Surface::makeShared<Acts::PlaneSurface>(transform, diamondBounds);
152  runPlanarTests(*diamond, planarStyle, "diamond");
153 
154  // ConvexPolygon
155  std::vector<Acts::Vector2> vertices = {
156  {-10., -10.}, {10., -15.}, {20., 5.}, {-5., 15.}, {-12, 0.}};
157  auto polygonBounds =
158  std::make_shared<Acts::ConvexPolygonBounds<5u>>(vertices);
159  auto polygon =
160  Acts::Surface::makeShared<Acts::PlaneSurface>(transform, polygonBounds);
161  runPlanarTests(*polygon, planarStyle, "polygon");
162 }
163 
164 BOOST_AUTO_TEST_CASE(DiscSurfaces) {
165  // Planar style
166  Acts::Svg::Style discStyle;
167  discStyle.fillColor = {0, 204, 153};
168  discStyle.fillOpacity = 0.75;
169  discStyle.highlightColor = {153, 204, 0};
170  discStyle.highlights = {"mouseover", "mouseout"};
171  discStyle.strokeWidth = 0.5;
172  discStyle.nSegments = 72u;
173 
174  auto transform = Acts::Transform3::Identity();
175  transform.pretranslate(Acts::Vector3{20., 20., 100.});
176 
177  // Full disc case
178  auto fullDiscBounds = std::make_shared<Acts::RadialBounds>(0., 64.);
179  auto fullDisc =
180  Acts::Surface::makeShared<Acts::DiscSurface>(transform, fullDiscBounds);
181  runPlanarTests(*fullDisc, discStyle, "full_disc");
182 
183  // Full ring case:
184  auto fullRingBounds = std::make_shared<Acts::RadialBounds>(36., 64.);
185  auto fullRing =
186  Acts::Surface::makeShared<Acts::DiscSurface>(transform, fullRingBounds);
187  runPlanarTests(*fullRing, discStyle, "full_ring");
188 
189  // Sectorial disc case
190  auto sectoralDiscBounds =
191  std::make_shared<Acts::RadialBounds>(0., 64., 0.25 * M_PI, 0.5 * M_PI);
192  auto sectoralDisc = Acts::Surface::makeShared<Acts::DiscSurface>(
193  transform, sectoralDiscBounds);
194  runPlanarTests(*sectoralDisc, discStyle, "full_disc");
195 
196  // Annulus shape
197  double minRadius = 7.2;
198  double maxRadius = 12.0;
199  double minPhi = 0.74195;
200  double maxPhi = 1.33970;
201 
202  Acts::Vector2 offset{-3., 2.};
203 
204  auto annulusDiscBounds = std::make_shared<Acts::AnnulusBounds>(
206  auto annulusDisc = Acts::Surface::makeShared<Acts::DiscSurface>(
207  transform, annulusDiscBounds);
208  runPlanarTests(*annulusDisc, discStyle, "annulus_disc");
209 }
210 
211 BOOST_AUTO_TEST_SUITE_END()