File indexing completed on 2026-05-27 07:24:19
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include "detray/core/detector.hpp"
0011 #include "detray/definitions/units.hpp"
0012 #include "detray/navigation/volume_graph.hpp"
0013
0014
0015 #include "detray/io/frontend/detector_reader.hpp"
0016 #include "detray/io/utils/create_path.hpp"
0017
0018
0019 #include "detray/plugins/svgtools/illustrator.hpp"
0020 #include "detray/plugins/svgtools/writer.hpp"
0021
0022
0023 #include "detray/options/detector_io_options.hpp"
0024 #include "detray/options/parse_options.hpp"
0025 #include "detray/test/framework/types.hpp"
0026
0027
0028 #include <vecmem/memory/host_memory_resource.hpp>
0029
0030
0031 #include <actsvg/core.hpp>
0032
0033
0034 #include "detray/options/boost_program_options.hpp"
0035
0036
0037 #include <filesystem>
0038 #include <sstream>
0039 #include <stdexcept>
0040 #include <string>
0041
0042 namespace po = boost::program_options;
0043
0044 using namespace detray;
0045
0046 int main(int argc, char** argv) {
0047
0048 using metadata_t = detray::test::default_metadata;
0049 using detector_t = detray::detector<metadata_t>;
0050
0051
0052 auto style = detray::svgtools::styling::tableau_colorblind::style;
0053
0054
0055 po::options_description desc("\ndetray detector display options");
0056
0057 std::vector<dindex> volume_indices;
0058 std::vector<std::string> volume_names;
0059 std::vector<dindex> surfaces;
0060 std::vector<dindex> window;
0061 desc.add_options()("outdir", po::value<std::string>(),
0062 "Output directory for plots")(
0063 "context", po::value<dindex>(), "Number of the geometry context")(
0064 "r_axis", po::value<float>()->default_value(1100.f * unit<float>::mm),
0065 "Length of the radial axis")("x_axis", po::value<float>(),
0066 "Length of the x axis")(
0067 "y_axis", po::value<float>(), "Length of the y axis")(
0068 "z_axis", po::value<float>()->default_value(3100.f * unit<float>::mm),
0069 "Length of the z axis")(
0070 "font_size", po::value<unsigned int>()->default_value(35u), "Font size")(
0071 "search_window", po::value<std::vector<dindex>>(&window)->multitoken(),
0072 "Size of the grid surface search window")(
0073 "volume_indices",
0074 po::value<std::vector<dindex>>(&volume_indices)->multitoken(),
0075 "List of volumes that should be displayed by index")(
0076 "volume_names",
0077 po::value<std::vector<std::string>>(&volume_names)->multitoken(),
0078 "List of volumes that should be displayed by name")(
0079 "surfaces", po::value<std::vector<dindex>>(&surfaces)->multitoken(),
0080 "List of surfaces that should be displayed")("hide_portals",
0081 "Hide portal surfaces")(
0082 "hide_passives", "Hide passive surfaces")("hide_material",
0083 "Don't draw surface material")(
0084 "hide_eta_lines", "Hide eta lines")("show_info", "Show info boxes")(
0085 "write_volume_graph", "Writes the volume graph to file");
0086
0087
0088 detray::io::detector_reader_config reader_cfg{};
0089
0090 reader_cfg.do_check(false);
0091
0092 po::variables_map vm =
0093 detray::options::parse_options(desc, argc, argv, reader_cfg);
0094
0095
0096 std::string outdir{vm.count("outdir") != 0u ? vm["outdir"].as<std::string>()
0097 : "./plots/"};
0098 auto path = detray::io::create_path(outdir);
0099
0100 float r_axis{vm["r_axis"].as<float>()};
0101 float x_axis{r_axis};
0102 float y_axis{r_axis};
0103 if (vm.count("x_axis") != 0u) {
0104 x_axis = vm["x_axis"].as<float>();
0105 }
0106 if (vm.count("y_axis") != 0u) {
0107 y_axis = vm["y_axis"].as<float>();
0108 }
0109 const float z_axis{vm["z_axis"].as<float>()};
0110
0111
0112 detector_t::geometry_context gctx;
0113 if (vm.count("context") != 0u) {
0114 gctx = detector_t::geometry_context{vm["context"].as<dindex>()};
0115 }
0116
0117 if (vm.count("search_window") != 0u) {
0118 if (window.size() != 2u) {
0119 throw std::invalid_argument(
0120 "Incorrect surface grid search window. Please provide two "
0121 "integer distances.");
0122 }
0123 } else {
0124
0125 window = {1u, 1u};
0126 }
0127
0128
0129 vecmem::host_memory_resource host_mr;
0130
0131 const auto [det, names] =
0132 detray::io::read_detector<detector_t>(host_mr, reader_cfg);
0133
0134
0135 const unsigned int font_size{vm["font_size"].as<unsigned int>()};
0136 auto& vol_style = style._detector_style._volume_style;
0137 vol_style._sensitive_surface_style._font_size = font_size;
0138 vol_style._passive_surface_style._font_size = font_size;
0139 vol_style._portal_style._surface_style._font_size = font_size;
0140 style._eta_lines_style._font_size = font_size;
0141
0142
0143 std::array<actsvg::scalar, 2u> grad_pos{};
0144 grad_pos[0] = vm.count("x_axis") != 0u ? x_axis + 100.f : z_axis + 100.f;
0145 grad_pos[1] = -200.f;
0146
0147 vol_style._sensitive_surface_style._material_style._gradient_pos = grad_pos;
0148 vol_style._passive_surface_style._material_style._gradient_pos = grad_pos;
0149 vol_style._portal_style._surface_style._material_style._gradient_pos =
0150 grad_pos;
0151
0152
0153 detray::svgtools::illustrator il{det, names, style};
0154 il.show_info(vm.count("show_info") != 0u);
0155 il.hide_eta_lines(vm.count("hide_eta_lines") != 0u);
0156 il.hide_portals(vm.count("hide_portals") != 0u);
0157 il.hide_passives(vm.count("hide_passives") != 0u);
0158 il.hide_material(vm.count("material_file") == 0u ||
0159 vm.count("hide_material") != 0u);
0160 il.hide_grids(vm.count("grid_file") == 0u);
0161 il.search_window({window[0], window[1]});
0162
0163 actsvg::style::stroke stroke_black = actsvg::style::stroke();
0164 actsvg::style::font axis_font = actsvg::style::font();
0165 axis_font._size = font_size;
0166
0167
0168 auto xy_axis =
0169 actsvg::draw::x_y_axes("axes", {-x_axis, x_axis}, {-y_axis, y_axis},
0170 stroke_black, "x", "y", axis_font);
0171
0172 auto zr_axis = actsvg::draw::x_y_axes("axes", {-z_axis, z_axis}, {-5, r_axis},
0173 stroke_black, "z", "r", axis_font);
0174
0175 auto zphi_axis =
0176 actsvg::draw::x_y_axes("axes", {-z_axis, z_axis}, {-r_axis, r_axis},
0177 stroke_black, "z", "phi", axis_font);
0178
0179
0180 const actsvg::views::x_y xy;
0181 const actsvg::views::z_r zr;
0182 const actsvg::views::z_phi zphi;
0183 const actsvg::views::z_rphi zrphi;
0184
0185
0186 auto draw_volumes = [&]<typename range_t>(const range_t& vol_ids) {
0187 const auto [vol_xy_svg, xy_grids] = il.draw_volumes(vol_ids, xy, gctx);
0188 detray::svgtools::write_svg(path / vol_xy_svg._id, {xy_axis, vol_xy_svg});
0189 for (const auto& grid : xy_grids) {
0190 detray::svgtools::write_svg(path / grid._id, grid);
0191 }
0192
0193 const auto [vol_zr_svg, _] = il.draw_volumes(vol_ids, zr, gctx);
0194 detray::svgtools::write_svg(path / vol_zr_svg._id, {zr_axis, vol_zr_svg});
0195
0196 const auto [_vol, zrphi_grids] = il.draw_volumes(vol_ids, zrphi, gctx);
0197 for (const auto& grid : zrphi_grids) {
0198 detray::svgtools::write_svg(path / grid._id, grid);
0199 }
0200 };
0201
0202
0203 if (!volume_indices.empty()) {
0204 draw_volumes(volume_indices);
0205 }
0206 if (!volume_names.empty()) {
0207 draw_volumes(volume_names);
0208 }
0209
0210
0211 if (!surfaces.empty()) {
0212 const auto [sf_xy_svg, mat_xy_svg] = il.draw_surfaces(surfaces, xy, gctx);
0213 detray::svgtools::write_svg(path / sf_xy_svg._id, {xy_axis, sf_xy_svg});
0214 detray::svgtools::write_svg(path / mat_xy_svg._id, {xy_axis, mat_xy_svg});
0215
0216 [[maybe_unused]] const auto [sf_zr_svg, mat_zr_svg] =
0217 il.draw_surfaces(surfaces, zr, gctx);
0218 detray::svgtools::write_svg(path / sf_zr_svg._id, {zr_axis, sf_zr_svg});
0219
0220 [[maybe_unused]] const auto [sf_zphi_svg, mat_zphi_svg] =
0221 il.draw_surfaces(surfaces, zphi, gctx);
0222 detray::svgtools::write_svg(path / mat_zphi_svg._id,
0223 {zphi_axis, mat_zphi_svg});
0224 }
0225
0226
0227 if (volume_indices.empty() && volume_names.empty() && surfaces.empty()) {
0228 const auto det_xy_svg = il.draw_detector(xy, gctx);
0229 detray::svgtools::write_svg(path / det_xy_svg._id, {xy_axis, det_xy_svg});
0230
0231 const auto det_zr_svg = il.draw_detector(zr, gctx, r_axis, z_axis);
0232 detray::svgtools::write_svg(path / det_zr_svg._id, {zr_axis, det_zr_svg});
0233 }
0234
0235
0236 if (vm.count("write_volume_graph") != 0u) {
0237 detray::volume_graph graph(det);
0238
0239 detray::io::file_handle stream{
0240 path / (det.name(names) + "_volume_graph.dot"),
0241 std::ios::out | std::ios::trunc};
0242 *stream << graph.to_dot_string();
0243 }
0244 }