File indexing completed on 2026-09-05 08:18:37
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include "detray/algebra/concepts.hpp"
0011 #include "detray/core/detector.hpp"
0012 #include "detray/plugins/svgtools/illustrator.hpp"
0013 #include "detray/plugins/svgtools/styling/styling.hpp"
0014 #include "detray/plugins/svgtools/writer.hpp"
0015
0016
0017 #include "algebra/array.hpp"
0018 #include "detray/definitions/algebra.hpp"
0019 #include "detray/detectors/default_metadata.hpp"
0020
0021
0022 #include <actsvg/core/defs.hpp>
0023 #include <actsvg/core/draw.hpp>
0024 #include <actsvg/core/style.hpp>
0025 #include <actsvg/core/svg.hpp>
0026 #include <actsvg/core/views.hpp>
0027
0028
0029 #include <pybind11/pybind11.h>
0030 #include <pybind11/stl.h>
0031
0032
0033 #include <array>
0034 #include <string>
0035 #include <vector>
0036
0037 namespace py = pybind11;
0038
0039 namespace {
0040
0041 using scalar_t = DETRAY_CUSTOM_SCALARTYPE;
0042 using algebra_t = detray::array<scalar_t>;
0043 using detector_t = detray::detector<detray::default_metadata<algebra_t>>;
0044 using geometry_context_t = detector_t::geometry_context;
0045 using style_t = detray::svgtools::styling::style;
0046 using illustrator_t = detray::svgtools::illustrator<detector_t>;
0047
0048
0049 template <typename view_t>
0050 void bind_draw_methods(py::class_<illustrator_t> &c) {
0051 c.def(
0052 "drawDetector",
0053 [](const illustrator_t &il, const view_t &view,
0054 const geometry_context_t &gctx, float r_length, float z_length) {
0055 return il.draw_detector(view, gctx, r_length, z_length);
0056 },
0057 py::arg("view"), py::arg("gctx"), py::arg("rLength") = 1100.f,
0058 py::arg("zLength") = 3100.f, "Draw the whole detector");
0059
0060 c.def(
0061 "drawVolumes",
0062 [](const illustrator_t &il, const std::vector<detray::dindex> &indices,
0063 const view_t &view, const geometry_context_t &gctx) {
0064 return il.draw_volumes(indices, view, gctx);
0065 },
0066 py::arg("indices"), py::arg("view"), py::arg("gctx"),
0067 "Draw the volumes with the given indices. Returns their svg together "
0068 "with the svgs of their surface grids");
0069 c.def(
0070 "drawVolumes",
0071 [](const illustrator_t &il, const std::vector<std::string> &names,
0072 const view_t &view, const geometry_context_t &gctx) {
0073 return il.draw_volumes(names, view, gctx);
0074 },
0075 py::arg("names"), py::arg("view"), py::arg("gctx"),
0076 "Draw the volumes with the given names. Returns their svg together with "
0077 "the svgs of their surface grids");
0078
0079 c.def(
0080 "drawSurfaces",
0081 [](const illustrator_t &il, const std::vector<detray::dindex> &indices,
0082 const view_t &view, const geometry_context_t &gctx) {
0083 return il.draw_surfaces(indices, view, gctx);
0084 },
0085 py::arg("indices"), py::arg("view"), py::arg("gctx"),
0086 "Draw the surfaces with the given indices. Returns their svg together "
0087 "with the svg of their material");
0088 }
0089
0090 }
0091
0092 PYBIND11_MODULE(DetraySvgtoolsPythonBindings, m) {
0093 m.doc() = "Detray svgtools bindings";
0094
0095
0096 {
0097
0098
0099 py::class_<actsvg::svg::object>(m, "SvgObject", py::module_local())
0100 .def_readwrite("id", &actsvg::svg::object::_id,
0101 "Identification string");
0102
0103 m.def(
0104 "writeSvg",
0105 [](const std::string &path,
0106 const std::vector<actsvg::svg::object> &svgs,
0107 bool replace) { detray::svgtools::write_svg(path, svgs, replace); },
0108 py::arg("path"), py::arg("svgs"), py::arg("replace") = true,
0109 "Write svg objects to '<path>.svg'. Their ids must be unique");
0110
0111 m.def(
0112 "drawAxes",
0113 [](const std::string &name,
0114 const std::array<actsvg::scalar, 2> &x_range,
0115 const std::array<actsvg::scalar, 2> &y_range,
0116 const std::string &x_label, const std::string &y_label,
0117 unsigned int font_size) {
0118 actsvg::style::font font{};
0119 font._size = font_size;
0120
0121
0122 return actsvg::draw::x_y_axes(name, x_range, y_range,
0123 actsvg::style::stroke{}, x_label,
0124 y_label, font);
0125 },
0126 py::arg("name"), py::arg("xRange"), py::arg("yRange"),
0127 py::arg("xLabel") = "", py::arg("yLabel") = "",
0128 py::arg("fontSize") = 12u, "Draw a pair of x-y axes");
0129 }
0130
0131
0132 {
0133 py::class_<actsvg::views::x_y>(m, "ViewXY", py::module_local())
0134 .def(py::init<>(), "Transverse view");
0135 py::class_<actsvg::views::z_r>(m, "ViewZR", py::module_local())
0136 .def(py::init<>(), "Longitudinal view");
0137 py::class_<actsvg::views::z_phi>(m, "ViewZPhi", py::module_local())
0138 .def(py::init<>(), "Unrolled cylinder view");
0139 py::class_<actsvg::views::z_rphi>(m, "ViewZRPhi", py::module_local())
0140 .def(py::init<>(), "Unrolled cylinder view at a fixed radius");
0141 }
0142
0143
0144 {
0145 py::class_<style_t>(m, "Style")
0146 .def_property(
0147 "fontSize",
0148 [](const style_t &s) {
0149 return s._detector_style._volume_style._sensitive_surface_style
0150 ._font_size;
0151 },
0152 [](style_t &s, unsigned int font_size) {
0153 auto &vol_style = s._detector_style._volume_style;
0154 vol_style._sensitive_surface_style._font_size = font_size;
0155 vol_style._passive_surface_style._font_size = font_size;
0156 vol_style._portal_style._surface_style._font_size = font_size;
0157 s._eta_lines_style._font_size = font_size;
0158 },
0159 "Font size of all surface and eta line labels")
0160 .def_property(
0161 "materialGradientPos",
0162 [](const style_t &s) {
0163 return s._detector_style._volume_style._sensitive_surface_style
0164 ._material_style._gradient_pos;
0165 },
0166 [](style_t &s, const actsvg::point2 &pos) {
0167 auto &vol_style = s._detector_style._volume_style;
0168 vol_style._sensitive_surface_style._material_style._gradient_pos =
0169 pos;
0170 vol_style._passive_surface_style._material_style._gradient_pos =
0171 pos;
0172 vol_style._portal_style._surface_style._material_style
0173 ._gradient_pos = pos;
0174 },
0175 "Position of the material gradient box in all surface styles");
0176
0177 m.def(
0178 "tableauColorblindStyle",
0179 []() { return detray::svgtools::styling::tableau_colorblind::style; },
0180 "Style that matches the colors used in the data plotting");
0181 }
0182
0183
0184 {
0185 auto c =
0186 py::class_<illustrator_t>(m, "Illustrator")
0187 .def(py::init<const detector_t &, const detray::name_map &,
0188 const style_t &>(),
0189 py::arg("detector"), py::arg("names"), py::arg("style"),
0190 py::keep_alive<1, 2>(), py::keep_alive<1, 3>(),
0191 "Build the svg generator of a detector. The detector and its "
0192 "names are kept alive for as long as the illustrator is used, "
0193 "as it only references them. The style is copied")
0194 .def("showInfo", &illustrator_t::show_info,
0195 py::arg("toggle") = true, "Toggle the information boxes")
0196 .def("hideEtaLines", &illustrator_t::hide_eta_lines,
0197 py::arg("toggle") = true,
0198 "Toggle the eta lines of the z-r view")
0199 .def("hideGrids", &illustrator_t::hide_grids,
0200 py::arg("toggle") = true, "Toggle the surface grids")
0201 .def("hideMaterial", &illustrator_t::hide_material,
0202 py::arg("toggle") = true, "Toggle the surface material")
0203 .def("hidePortals", &illustrator_t::hide_portals,
0204 py::arg("toggle") = true, "Toggle the portal surfaces")
0205 .def("hidePassives", &illustrator_t::hide_passives,
0206 py::arg("toggle") = true, "Toggle the passive surfaces")
0207 .def("searchWindow", &illustrator_t::search_window,
0208 py::arg("window"),
0209 "Neighborhood search window for the grid display")
0210 .def_property_readonly("detName", &illustrator_t::det_name,
0211 "Name of the detector");
0212
0213 bind_draw_methods<actsvg::views::x_y>(c);
0214 bind_draw_methods<actsvg::views::z_r>(c);
0215 bind_draw_methods<actsvg::views::z_phi>(c);
0216 bind_draw_methods<actsvg::views::z_rphi>(c);
0217 }
0218 }