Skip to content

Commit

Permalink
feat: visualization of grids (#552)
Browse files Browse the repository at this point in the history
Added visualization of acceleration grids. Furthermore simplified parts of the illustrator class. Note that I have added a webpage generation tool with detray in mind to ACTSVG which can be used for debugging purposes to easily merge and switch between svgs
  • Loading branch information
fredevb authored Oct 25, 2023
1 parent 5f52056 commit 4ec5231
Show file tree
Hide file tree
Showing 22 changed files with 792 additions and 164 deletions.
2 changes: 1 addition & 1 deletion extern/actsvg/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ message( STATUS "Building actsvg as part of the Detray project" )
# Declare where to get Actsvg from.
set( DETRAY_ACTSVG_GIT_REPOSITORY "https://github.com/acts-project/actsvg.git"
CACHE STRING "Git repository to take actsvg from" )
set( DETRAY_ACTSVG_GIT_TAG "v0.4.35" CACHE STRING "Version of actsvg to build" )
set( DETRAY_ACTSVG_GIT_TAG "v0.4.37" CACHE STRING "Version of actsvg to build" )
mark_as_advanced( DETRAY_ACTSVG_GIT_REPOSITORY DETRAY_ACTSVG_GIT_TAG )
FetchContent_Declare( actsvg
GIT_REPOSITORY "${DETRAY_ACTSVG_GIT_REPOSITORY}"
Expand Down
164 changes: 164 additions & 0 deletions plugins/svgtools/include/detray/plugins/svgtools/conversion/grid.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
/** Detray library, part of the ACTS project (R&D line)
*
* (c) 2023 CERN for the benefit of the ACTS project
*
* Mozilla Public License Version 2.0
*/

#pragma once

// Project include(s)
#include "detray/core/detector.hpp"
#include "detray/definitions/units.hpp"
#include "detray/grids/axis.hpp"

// Actsvg include(s)
#include "actsvg/proto/grid.hpp"

// System include(s)
#include <algorithm>
#include <optional>
#include <string>
#include <vector>

namespace detray::svgtools::conversion {

/// A functor to access the bin edges.
template <typename scalar_t, detray::n_axis::label axis_label>
struct edge_getter {
template <typename group_t, typename index_t, typename... Args>
DETRAY_HOST_DEVICE inline auto operator()(
[[maybe_unused]] const group_t& group,
[[maybe_unused]] const index_t index) const {
using accel_t = typename group_t::value_type;
if constexpr (detray::detail::is_grid_v<accel_t>) {
const auto grid = group[index];
const auto axis_bin_edges =
grid.axes().template get_axis<axis_label>().bin_edges();
std::vector<scalar_t> edges;
std::copy(axis_bin_edges.cbegin(), axis_bin_edges.cend(),
std::back_inserter(edges));
return edges;
}
return std::vector<scalar_t>{};
}
};

/// @return the bin edges of the grid.
template <typename detray::n_axis::label axis_label, typename detector_t,
typename link_t>
auto bin_edges(const detector_t& detector, const link_t& link) {
using d_scalar_t = typename detector_t::scalar_type;
return detector.accelerator_store()
.template visit<edge_getter<d_scalar_t, axis_label>>(link);
}

// Calculating r under the assumption that the cylinder grid is closed in phi:
// (bin_edge_min - bin_edge_max) / (2*pi).
template <typename d_scalar_t>
auto r_phi_split(const std::vector<d_scalar_t>& edges_rphi) {
const auto r = edges_rphi.back() * detray::constant<d_scalar_t>::inv_pi;
std::vector<d_scalar_t> edges_phi;
std::transform(edges_rphi.cbegin(), edges_rphi.cend(),
std::back_inserter(edges_phi),
[r](d_scalar_t e) { return e / r; });
return std::tuple(edges_phi, r);
}

/// @returns the actsvg grid type and edge values for a detray cylinder
/// grid.
template <typename detector_t, typename link_t, typename view_t>
auto cylinder2_grid_type_and_edges(const detector_t& detector,
const link_t& link, const view_t&) {
assert(link.id() == detector_t::accel::id::e_cylinder2_grid);
auto edges_rphi = bin_edges<detray::n_axis::label::e_rphi>(detector, link);
auto edges_z = bin_edges<detray::n_axis::label::e_cyl_z>(detector, link);
auto [edges_phi, r] = r_phi_split(edges_rphi);
std::vector edges_r{r, r};

if (std::is_same_v<view_t, actsvg::views::x_y>) {
return std::tuple(actsvg::proto::grid::e_r_phi, edges_r, edges_phi);
}
if (std::is_same_v<view_t, actsvg::views::z_r>) {
return std::tuple(actsvg::proto::grid::e_x_y, edges_z, edges_r);
}
if (std::is_same_v<view_t, actsvg::views::z_phi>) {
return std::tuple(actsvg::proto::grid::e_x_y, edges_z, edges_phi);
}
if (std::is_same_v<view_t, typename actsvg::views::z_rphi>) {
return std::tuple(actsvg::proto::grid::e_x_y, edges_z, edges_rphi);
}
using scalar_t = typename detector_t::scalar_type;
return std::tuple(actsvg::proto::grid::e_x_y, std::vector<scalar_t>{},
std::vector<scalar_t>{});
}

/// @returns the actsvg grid type and edge values for a detray disc grid.
template <typename detector_t, typename link_t, typename view_t>
auto disc_grid_type_and_edges(const detector_t& detector, const link_t& link,
const view_t&) {
assert(link.id() == detector_t::accel::id::e_disc_grid);
auto edges_r = bin_edges<detray::n_axis::label::e_r>(detector, link);
auto edges_phi = bin_edges<detray::n_axis::label::e_phi>(detector, link);

if (std::is_same_v<view_t, typename actsvg::views::x_y>) {
return std::tuple(actsvg::proto::grid::e_r_phi, edges_r, edges_phi);
}
using scalar_t = typename detector_t::scalar_type;
return std::tuple(actsvg::proto::grid::e_x_y, std::vector<scalar_t>{},
std::vector<scalar_t>{});
}

/// @returns the detray grids respective actsvg grid type and edge
/// values.
template <typename detector_t, typename link_t, typename view_t>
auto get_type_and_axes(const detector_t& detector, const link_t& link,
const view_t& view) {
using accel_ids_t = typename detector_t::accel::id;
switch (link.id()) {
case accel_ids_t::e_cylinder2_grid: {
return cylinder2_grid_type_and_edges(detector, link, view);
}
case accel_ids_t::e_disc_grid: {
return disc_grid_type_and_edges(detector, link, view);
}
default: {
using scalar_t = typename detector_t::scalar_type;
return std::tuple(actsvg::proto::grid::e_x_y,
std::vector<scalar_t>{}, std::vector<scalar_t>{});
}
}
}

/// @brief Converts a detray grid to a actsvg proto grid.
/// @param detector the detector
/// @param index the index of the grid's volume
/// @param view the view
/// @returns a proto grid
template <typename a_scalar_t, typename detector_t, typename view_t>
std::optional<actsvg::proto::grid> grid(const detector_t& detector,
const std::size_t index,
const view_t& view) {
using d_scalar_t = typename detector_t::scalar_type;
using geo_object_ids = typename detector_t::geo_obj_ids;

const auto vol_desc = detector.volumes()[index];
const auto link = vol_desc.template link<geo_object_ids::e_sensitive>();
actsvg::proto::grid p_grid;

if (not link.is_invalid()) {
const auto [type, edges0, edges1] =
get_type_and_axes(detector, link, view);
p_grid._type = type;
std::transform(edges0.cbegin(), edges0.cend(),
std::back_inserter(p_grid._edges_0),
[](d_scalar_t v) { return static_cast<a_scalar_t>(v); });
std::transform(edges1.cbegin(), edges1.cend(),
std::back_inserter(p_grid._edges_1),
[](d_scalar_t v) { return static_cast<a_scalar_t>(v); });
return p_grid;
}
return {};
}

} // namespace detray::svgtools::conversion
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

namespace detray::svgtools::conversion {

/// @returns a point as a string.
template <typename point3_t>
inline std::string point_to_string(point3_t point) {

Expand All @@ -33,6 +34,7 @@ inline std::string point_to_string(point3_t point) {
return stream.str();
}

/// @returns the information section for a detray surface.
template <typename point3_t, typename detector_t>
inline auto information_section(
const typename detector_t::geometry_context& context,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,26 @@
#include "detray/intersection/intersection.hpp"
#include "detray/plugins/svgtools/conversion/landmark.hpp"
#include "detray/plugins/svgtools/meta/proto/intersection_record.hpp"
#include "detray/plugins/svgtools/utils/intersection_utils.hpp"

// System include(s)
#include <vector>

namespace detray::svgtools::conversion {

/// @returns The proto intersection record from a list of points
template <typename point3_t, typename container_t>
inline auto intersection_record(const container_t& points) {
using p_intersection_record_t =
svgtools::meta::proto::intersection_record<point3_t>;
p_intersection_record_t p_ir;
for (const auto& point : points) {
const auto p_lm = svgtools::conversion::landmark<point3_t>(point);
p_ir._landmarks.push_back(p_lm);
}
return p_ir;
}

/// @returns The proto intersection record of a detray intersection record.
template <typename point3_t, typename detector_t>
inline auto intersection_record(
Expand All @@ -27,17 +41,13 @@ inline auto intersection_record(
detray::intersection2D<typename detector_t::surface_type,
typename detector_t::transform3>>>&
intersection_record) {
using p_intersection_record_t =
svgtools::meta::proto::intersection_record<point3_t>;
p_intersection_record_t p_ir;
std::vector<typename p_intersection_record_t::landmark_type> landmarks;
std::vector<typename detector_t::point3> points;
for (const auto& record : intersection_record) {
const auto p_lm = svgtools::conversion::landmark<point3_t>(
const auto point = svgtools::utils::intersection_point(
context, detector, record.second);
landmarks.push_back(p_lm);
points.push_back(point);
}
p_ir._landmarks = landmarks;
return p_ir;
return svgtools::conversion::intersection_record<point3_t>(points);
}

} // namespace detray::svgtools::conversion
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "detray/intersection/intersection.hpp"
#include "detray/plugins/svgtools/conversion/point.hpp"
#include "detray/plugins/svgtools/meta/proto/landmark.hpp"
#include "detray/plugins/svgtools/utils/intersection_utils.hpp"

namespace detray::svgtools::conversion {

Expand All @@ -23,15 +24,17 @@ inline auto landmark(
const detray::intersection2D<typename detector_t::surface_type,
typename detector_t::transform3>&
d_intersection) {
using p_landmark_t = svgtools::meta::proto::landmark<point3_t>;

const typename detector_t::vector3 dir{};
const detray::surface surface{detector, d_intersection.sf_desc};
const auto position = svgtools::conversion::point<point3_t>(
surface.local_to_global(context, d_intersection.local, dir));
const auto position =
svgtools::utils::intersection_point(context, detector, d_intersection);
return svgtools::conversion::landmark<point3>(position);
}

/// @returns The proto landmark of a detray point.
template <typename point3_t, typename d_point3_t>
inline auto landmark(d_point3_t& position) {
using p_landmark_t = svgtools::meta::proto::landmark<point3_t>;
p_landmark_t p_lm;
p_lm._position = position;
p_lm._position = svgtools::conversion::point<point3_t>(position);
return p_lm;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ inline auto link(const typename detector_t::geometry_context& context,

typename detector_t::vector3 dir{};

// Length of link arrow is currently hardcoded to 3.
constexpr double link_length = 3.;
// Length of link arrow is currently hardcoded.
constexpr double link_length = 4.;

const auto [start, end] = svgtools::utils::link_points(
context, detector, d_portal, dir, link_length);
Expand Down
Loading

0 comments on commit 4ec5231

Please sign in to comment.