From 5353493fa4101840406ff83f6eff02058f6e21f6 Mon Sep 17 00:00:00 2001 From: Joana Niermann Date: Wed, 15 Nov 2023 14:10:47 +0100 Subject: [PATCH] Fix the annulus mask svg rendering by using local cartesian vertices and streamlining some code in svgtools --- core/include/detray/masks/annulus2D.hpp | 34 ++++---- core/include/detray/masks/masks.hpp | 13 ---- .../plugins/svgtools/conversion/surface.hpp | 44 ++++------- .../svgtools/utils/surface_kernels.hpp | 78 ++++++++----------- tests/unit_tests/svgtools/masks.cpp | 8 +- 5 files changed, 68 insertions(+), 109 deletions(-) diff --git a/core/include/detray/masks/annulus2D.hpp b/core/include/detray/masks/annulus2D.hpp index 2c1e5db16d..c955381550 100644 --- a/core/include/detray/masks/annulus2D.hpp +++ b/core/include/detray/masks/annulus2D.hpp @@ -300,17 +300,17 @@ class annulus2D { scalar_t min_r = bounds[e_min_r]; scalar_t max_r = bounds[e_max_r]; - scalar_t min_phi_rel = bounds[e_min_phi_rel]; - scalar_t max_phi_rel = bounds[e_max_phi_rel]; - scalar_t origin_x = bounds[e_shift_x]; - scalar_t origin_y = bounds[e_shift_y]; + scalar_t min_phi = bounds[e_average_phi] + bounds[e_min_phi_rel]; + scalar_t max_phi = bounds[e_average_phi] + bounds[e_max_phi_rel]; + scalar_t origin_x = -bounds[e_shift_x]; + scalar_t origin_y = -bounds[e_shift_y]; point2_t origin_m = {origin_x, origin_y}; /// Helper method: find inner outer radius at edges in STRIP PC auto circIx = [](scalar_t O_x, scalar_t O_y, scalar_t r, scalar_t phi) -> point2_t { - // _____________________________________________ + // ____________________________________________ // / 2 2 2 2 2 2 // O_x + O_y*m - \/ - O_x *m + 2*O_x*O_y*m - O_y + m *r + r // x = @@ -342,30 +342,30 @@ class annulus2D { }; // calculate corners in STRIP XY - point2_t ul_xy = circIx(origin_x, origin_y, max_r, max_phi_rel); - point2_t ll_xy = circIx(origin_x, origin_y, min_r, max_phi_rel); - point2_t ur_xy = circIx(origin_x, origin_y, max_r, min_phi_rel); - point2_t lr_xy = circIx(origin_x, origin_y, min_r, min_phi_rel); + point2_t ul_xy = circIx(origin_x, origin_y, max_r, max_phi); + point2_t ll_xy = circIx(origin_x, origin_y, min_r, max_phi); + point2_t ur_xy = circIx(origin_x, origin_y, max_r, min_phi); + point2_t lr_xy = circIx(origin_x, origin_y, min_r, min_phi); auto inner_phi = - detail::phi_values(getter::phi(ll_xy - origin_m), - getter::phi(lr_xy - origin_m), n_seg); + detail::phi_values(getter::phi(lr_xy - origin_m), + getter::phi(ll_xy - origin_m), n_seg); auto outer_phi = - detail::phi_values(getter::phi(ur_xy - origin_m), - getter::phi(ul_xy - origin_m), n_seg); + detail::phi_values(getter::phi(ul_xy - origin_m), + getter::phi(ur_xy - origin_m), n_seg); dvector annulus_vertices; annulus_vertices.reserve(inner_phi.size() + outer_phi.size()); - for (auto iphi : inner_phi) { + for (scalar_t iphi : inner_phi) { annulus_vertices.push_back( point3_t{min_r * math_ns::cos(iphi) + origin_x, - min_r * std::sin(iphi) + origin_y, 0.f}); + min_r * math_ns::sin(iphi) + origin_y, 0.f}); } - for (auto ophi : outer_phi) { + for (scalar_t ophi : outer_phi) { annulus_vertices.push_back( point3_t{max_r * math_ns::cos(ophi) + origin_x, - max_r * std::sin(ophi) + origin_y, 0.f}); + max_r * math_ns::sin(ophi) + origin_y, 0.f}); } return annulus_vertices; diff --git a/core/include/detray/masks/masks.hpp b/core/include/detray/masks/masks.hpp index ed6b9b01a7..d31e6b653b 100644 --- a/core/include/detray/masks/masks.hpp +++ b/core/include/detray/masks/masks.hpp @@ -213,19 +213,6 @@ class mask { return {bounds, std::numeric_limits::max()}; } - /// @brief Calculates the center of the min bounds bounding box. - /// @returns The center point in global cartesian coordinates. - template - auto global_min_bounds_center(const transform3_t& trf) const { - const auto m = local_min_bounds(); - const auto center{ - 0.5f * (point3_t{m[cuboid3D<>::e_max_x], m[cuboid3D<>::e_max_y], - m[cuboid3D<>::e_max_z]} + - point3_t{m[cuboid3D<>::e_min_x], m[cuboid3D<>::e_min_y], - m[cuboid3D<>::e_min_z]})}; - return trf.point_to_global(center); - } - /// @brief Vertices of the mask in local cartesian coordinates. /// /// Computes vertices along the mask boundary. diff --git a/plugins/svgtools/include/detray/plugins/svgtools/conversion/surface.hpp b/plugins/svgtools/include/detray/plugins/svgtools/conversion/surface.hpp index 38e2c1ce68..0bccd74421 100644 --- a/plugins/svgtools/include/detray/plugins/svgtools/conversion/surface.hpp +++ b/plugins/svgtools/include/detray/plugins/svgtools/conversion/surface.hpp @@ -34,17 +34,14 @@ inline void set_measures(actsvg::proto::surface& p_surface, } /// @brief Sets the vertices of the proto surface to be the same as the mask. -template +template inline void set_vertices(actsvg::proto::surface& p_surface, - const transform_t& trf, const mask_t& m) { + const mask_t& m) { using point3_t = typename point3_container_t::value_type; - // Approximate any acrs in the mask shape with ten line segments + // Approximate any arcs in the mask shape with ten line segments auto vertices = m.vertices(10u); - for (std::size_t i = 0; i < vertices.size(); i++) { - vertices[i] = m.template to_global_frame(trf, vertices[i]); - } std::transform( vertices.cbegin(), vertices.cend(), @@ -57,14 +54,14 @@ inline void set_vertices(actsvg::proto::surface& p_surface, /// @note For lines, the thickness is fixed and not determined by the cross /// section. template -auto inline surface(const transform_t& transform, const mask_t& m) { +auto inline surface(const transform_t&, const mask_t& m) { using p_surface_t = actsvg::proto::surface; p_surface_t p_surface; p_surface._type = p_surface_t::type::e_polygon; set_measures(p_surface, m); - set_vertices(p_surface, transform, m); + set_vertices(p_surface, m); return p_surface; } @@ -77,9 +74,7 @@ auto inline surface(const transform_t& transform, // Rotation is currently not supported. // Furthermore, only translation on z axis is supported. - using mask_t = mask>; - using shape_t = typename mask_t::shape; - + using shape_t = cylinder2D; using point3_t = typename point3_container_t::value_type; using scalar_t = typename point3_t::value_type; using p_surface_t = actsvg::proto::surface; @@ -89,8 +84,7 @@ auto inline surface(const transform_t& transform, const auto r = static_cast(m[shape_t::e_r]); const auto nhz = static_cast(m[shape_t::e_n_half_z]); const auto phz = static_cast(m[shape_t::e_p_half_z]); - const auto center = - svgtools::conversion::point(transform.translation()); + const auto center = m.center(transform); const auto hz = (phz - nhz) / 2 + center[2]; p_surface._type = p_surface_t::type::e_cylinder; @@ -107,9 +101,7 @@ auto surface(const transform_t& transform, const mask>& m) { // Rotation is currently not supported. // Furthermore, only translation on z axis is supported. - using mask_t = mask>; - using shape_t = typename mask_t::shape; - + using shape_t = ring2D<>; using point3_t = typename point3_container_t::value_type; using scalar_t = typename point3_t::value_type; using p_surface_t = actsvg::proto::surface; @@ -118,8 +110,7 @@ auto surface(const transform_t& transform, const mask>& m) { const auto ri = static_cast(m[shape_t::e_inner_r]); const auto ro = static_cast(m[shape_t::e_outer_r]); - const auto center = - svgtools::conversion::point(transform.translation()); + const auto center = m.center(transform); p_surface._type = p_surface_t::type::e_disc; p_surface._radii = {ri, ro}; @@ -135,9 +126,7 @@ auto inline surface(const transform_t& transform, const mask>& m) { // Rotation is currently not supported. // Furthermore, only translation on z axis is supported. - using mask_t = mask>; - using shape_t = typename mask_t::shape; - + using shape_t = annulus2D<>; using point3_t = typename point3_container_t::value_type; using scalar_t = typename point3_t::value_type; using p_surface_t = actsvg::proto::surface; @@ -146,13 +135,13 @@ auto inline surface(const transform_t& transform, const mask>& m) { auto ri = static_cast(m[shape_t::e_min_r]); auto ro = static_cast(m[shape_t::e_max_r]); - auto center = svgtools::conversion::point(m.center(transform)); + auto center = m.center(transform); p_surface._type = p_surface_t::type::e_annulus; p_surface._radii = {ri, ro}; p_surface._zparameters = {center[2], 0.f}; set_measures(p_surface, m); - set_vertices(p_surface, transform, m); + set_vertices(p_surface, m); return p_surface; } @@ -165,9 +154,7 @@ auto surface(const transform_t& transform, // Rotation is currently not supported. // Furthermore, only translation on z axis is supported. - using mask_t = mask>; - using shape_t = typename mask_t::shape; - + using shape_t = line; using point3_t = typename point3_container_t::value_type; using scalar_t = typename point3_t::value_type; using p_surface_t = actsvg::proto::surface; @@ -177,13 +164,12 @@ auto surface(const transform_t& transform, // All line surfaces are drawn as a circles(straws) in xy-view const auto r{static_cast(m[shape_t::e_cross_section])}; const auto hz = static_cast(m[shape_t::e_half_z]); - const auto center = - svgtools::conversion::point(transform.translation()); + const auto center = m.center(transform); p_surface._type = p_surface_t::type::e_straw; p_surface._radii = {1.f, r}; p_surface._zparameters = {-hz, hz}; - p_surface._transform._tr = center; + p_surface._transform._tr = svgtools::conversion::point(center); set_measures(p_surface, m); return p_surface; diff --git a/plugins/svgtools/include/detray/plugins/svgtools/utils/surface_kernels.hpp b/plugins/svgtools/include/detray/plugins/svgtools/utils/surface_kernels.hpp index 573d1e9f3d..ea96b1a28e 100644 --- a/plugins/svgtools/include/detray/plugins/svgtools/utils/surface_kernels.hpp +++ b/plugins/svgtools/include/detray/plugins/svgtools/utils/surface_kernels.hpp @@ -101,44 +101,34 @@ struct link_start_getter { template auto inline link_start(const detray::mask>& mask, const transform_t& transform) const { - using mask_t = typename detray::mask>; - using shape_t = typename mask_t::shape; + + using shape_t = detray::ring2D<>; + using mask_t = detray::mask; using point3_t = typename mask_t::point3_t; using scalar_t = typename mask_t::scalar_type; - const scalar_t r{(mask[shape_t::e_inner_r] + mask[shape_t::e_outer_r]) / - 2.f}; + const scalar_t r{0.5f * + (mask[shape_t::e_inner_r] + mask[shape_t::e_outer_r])}; const scalar_t phi{detray::constant::pi_2}; - const scalar_t z{0}; - // Polar coordinate system. - const typename mask_t::local_frame_type frame{}; - - return frame.local_to_global(transform, point3_t{r, phi, z}); + return mask.to_global_frame(transform, point3_t{r, phi, 0.f}); } // Calculates the (optimal) link starting point for annuluses. template auto inline link_start(const detray::mask>& mask, const transform_t& transform) const { - using mask_t = typename detray::mask>; - using shape_t = typename mask_t::shape; + + using shape_t = detray::annulus2D<>; + using mask_t = detray::mask; using point3_t = typename mask_t::point3_t; using scalar_t = typename mask_t::scalar_type; const scalar_t r{(mask[shape_t::e_min_r] + mask[shape_t::e_max_r]) / 2.f}; const scalar_t phi{mask[shape_t::e_average_phi]}; - const scalar_t z{0}; - // Polar coordinate system. - const typename mask_t::local_frame_type frame{}; - - const auto true_center = mask.center(transform); - const auto rel_point = - frame.local_to_global(transform, point3_t{r, phi, z}) - - transform.translation(); - return rel_point + true_center; + return mask.to_global_frame(transform, point3_t{r, phi, 0.f}); } // Calculates the (optimal) link starting point for cylinders (2D). @@ -148,49 +138,45 @@ struct link_start_getter { const detray::mask>& mask, const transform_t& transform) const { - using mask_t = typename detray::mask< - detray::cylinder2D>; - using shape_t = typename mask_t::shape; + + using shape_t = detray::cylinder2D; + using mask_t = detray::mask; using point3_t = typename mask_t::point3_t; using scalar_t = typename mask_t::scalar_type; + const auto center = mask.center(transform); + const scalar_t mean_z{ + 0.5f * (mask[shape_t::e_n_half_z] + mask[shape_t::e_p_half_z])}; + const scalar_t r{mask[shape_t::e_r]}; const scalar_t phi{detray::constant::pi_2}; - const scalar_t z{0}; + // Shift the center to the actual cylider bounds + const scalar_t z{center[2] + mean_z}; - // Cylindrical coordinate system. - const typename mask_t::local_frame_type frame{}; - - const auto true_center = mask.global_min_bounds_center(transform); - const auto rel_point = - frame.local_to_global(transform, point3_t{r * phi, z, r}) - - transform.translation(); - return rel_point + true_center; + return mask.to_global_frame(transform, point3_t{r * phi, z, r}); } // Calculates the (optimal) link starting point for cylinders (3D). template auto inline link_start(const detray::mask& mask, const transform_t& transform) const { - using mask_t = typename detray::mask; - using shape_t = typename mask_t::shape; + + using shape_t = detray::cylinder3D; + using mask_t = detray::mask; using point3_t = typename mask_t::point3_t; using scalar_t = typename mask_t::scalar_type; - const scalar_t r{(mask[shape_t::e_min_r] + mask[shape_t::e_max_r]) / - 2.f}; - const scalar_t phi{ - (mask[shape_t::e_max_phi] + mask[shape_t::e_max_phi]) / 2.f}; - const scalar_t z{0}; + const auto center = mask.center(transform); + const scalar_t mean_z{ + 0.5f * (mask[shape_t::e_min_z] + mask[shape_t::e_min_z])}; - // Cylindrical coordinate system. - const typename mask_t::local_frame_type frame{}; + const scalar_t r{0.5f * + (mask[shape_t::e_min_r] + mask[shape_t::e_max_r])}; + const scalar_t phi{ + 0.5f * (mask[shape_t::e_max_phi] + mask[shape_t::e_max_phi])}; + const scalar_t z{center[2] + mean_z}; - const auto true_center = mask.global_min_bounds_center(transform); - const auto rel_point = - frame.local_to_global(transform, point3_t{r * phi, z, r}) - - transform.translation(); - return rel_point + true_center; + return mask.to_global_frame(transform, point3_t{r, phi, z}); } }; diff --git a/tests/unit_tests/svgtools/masks.cpp b/tests/unit_tests/svgtools/masks.cpp index f21d424a09..813d9e1d17 100644 --- a/tests/unit_tests/svgtools/masks.cpp +++ b/tests/unit_tests/svgtools/masks.cpp @@ -43,9 +43,9 @@ int main(int, char**) { // Visualize a 2D annulus. // e_min_r, e_max_r, e_min_phi_rel, e_max_phi_rel, e_average_phi, e_shift_x, - // e_shift_y, e_size - detray::mask> ann2D{0u, 100.f, 200.f, -1.f, - 1.f, 0.f, 0.f, 100.f}; + // e_shift_y + detray::mask> ann2D{0u, 100.f, 200.f, -0.5f, + 0.5f, 0.f, 4.f, 30.f}; const auto ann2D_proto = detray::svgtools::conversion::surface(transform, ann2D); @@ -53,7 +53,7 @@ int main(int, char**) { detray::svgtools::write_svg("test_svgtools_annulus2D", {axes, ann2D_svg}); // Visualize a 2D cylinder. - // e_r, e_n_half_z, e_p_half_z, e_size + // e_r, e_n_half_z, e_p_half_z detray::mask> cyl2D{0u, 100.f, -10.f, 10.f}; const auto cyl2D_proto = detray::svgtools::conversion::surface(transform,