12#include "detray/core/concepts.hpp"
13#include "detray/definitions/algebra.hpp"
14#include "detray/utils/logging.hpp"
17#include "detray/plugins/svgtools/illustrator.hpp"
18#include "detray/plugins/svgtools/styling/styling.hpp"
19#include "detray/plugins/svgtools/writer.hpp"
22#include "detray/io/utils/create_path.hpp"
29#include <unordered_set>
31namespace detray::detail {
35template <
typename record_t>
36std::unordered_set<dindex> get_volume_indices(
38 std::unordered_set<dindex> volumes{};
39 volumes.reserve(intersection_record.size());
40 for (
const auto &single_ir : intersection_record) {
41 if (single_ir.intersection().surface().identifier().is_invalid()) {
44 volumes.insert(single_ir.volume());
52template <
typename surface_t, concepts::algebra algebra_t>
53std::unordered_set<dindex> get_volume_indices(
54 const dvector<detray::intersection2D<
55 surface_t, algebra_t, intersection::contains_pos>> &intersections) {
56 std::unordered_set<dindex> volumes{};
57 volumes.reserve(intersections.size());
58 for (
const auto &intr : intersections) {
59 if (intr.surface().identifier().is_invalid()) {
62 volumes.insert(intr.surface().volume());
70template <
template <
typename>
class candidate_t,
typename surface_t,
71 concepts::algebra algebra_t>
72std::unordered_set<dindex> get_volume_indices(
73 const dvector<candidate_t<detray::intersection2D<
74 surface_t, algebra_t, intersection::contains_pos>>> &candidates) {
75 std::unordered_set<dindex> volumes{};
76 volumes.reserve(candidates.size());
77 for (
const auto &cand : candidates) {
78 if (cand.intersection.surface().identifier().is_invalid()) {
81 volumes.insert(cand.intersection.surface().volume());
93template <
typename record_t,
typename ALLOC>
94auto transcribe_intersections(
95 const std::vector<record_t, ALLOC> &intersection_trace) {
96 using intersection_t =
typename record_t::intersection_type;
98 std::vector<intersection_t> intersections{};
99 intersections.reserve(intersection_trace.size());
100 for (
auto &ir : intersection_trace) {
102 if (ir.intersection().surface().identifier().is_invalid()) {
105 intersections.push_back(ir.intersection());
108 return intersections;
112template <concepts::detector detector_t,
typename truth_trace_t,
class traj_t,
113 typename recorded_trace_t,
typename view_t>
114auto draw_intersection_and_traj_svg(
115 const typename detector_t::geometry_context gctx,
116 detray::svgtools::illustrator<detector_t> &il,
117 const truth_trace_t &truth_trace,
const traj_t &traj,
118 const std::string &traj_name,
const recorded_trace_t &recorded_trace,
120 dindex_range highlight_idx = {detail::invalid_value<dindex>(),
121 detail::invalid_value<dindex>()}) {
123 auto truth_intersections = transcribe_intersections(truth_trace);
124 auto recorded_intersections = transcribe_intersections(recorded_trace);
127 if (truth_intersections.size() < truth_trace.size()) {
128 highlight_idx.shift(-1);
132 actsvg::svg::object svg_traj;
133 if (!truth_intersections.empty()) {
135 traj.dir(0.f), view, highlight_idx, gctx);
139 const auto path{math::max(math::fabs(truth_intersections.front().path()),
140 math::fabs(truth_intersections.back().path()))};
141 if (!recorded_intersections.empty()) {
143 traj_name, recorded_intersections, traj, view, path, highlight_idx,
153template <concepts::detector detector_t,
typename truth_trace_t,
class traj_t,
154 typename recorded_trace_t>
155inline void svg_display(
156 const typename detector_t::geometry_context gctx,
157 detray::svgtools::illustrator<detector_t> &il,
158 const truth_trace_t &truth_trace,
const traj_t &traj,
159 const std::string &traj_name,
160 const std::string &outfile =
"detector_display",
161 const recorded_trace_t &recorded_trace = {},
162 dindex_range highlight_idx = {detail::invalid_value<dindex>(),
163 detail::invalid_value<dindex>()},
164 const bool verbose =
true,
const std::string &outdir =
"./plots/") {
166 auto volumes = get_volume_indices(truth_trace);
167 if (!recorded_trace.empty()) {
168 const auto more_volumes = get_volume_indices(truth_trace);
169 volumes.insert(more_volumes.begin(), more_volumes.end());
175 actsvg::style::stroke stroke_black = actsvg::style::stroke();
178 auto xy_axis = actsvg::draw::x_y_axes(
"axes", {-1100, 1100}, {-1100, 1100},
179 stroke_black,
"x",
"y");
181 auto zr_axis = actsvg::draw::x_y_axes(
"axes", {-3100, 3100}, {-5, 1100},
182 stroke_black,
"z",
"r");
184 const actsvg::views::x_y xy{};
185 const actsvg::views::z_r zr{};
189 draw_intersection_and_traj_svg(gctx, il, truth_trace, traj, traj_name,
190 recorded_trace, xy, highlight_idx);
192 const auto [vol_xy_svg, _] = il.
draw_volumes(volumes, xy, gctx);
193 detray::svgtools::write_svg(
194 path / (outfile +
"_" + vol_xy_svg._id +
"_" + traj_name),
195 {xy_axis, vol_xy_svg, svg_traj});
199 draw_intersection_and_traj_svg(gctx, il, truth_trace, traj, traj_name,
200 recorded_trace, zr, highlight_idx);
203 detray::svgtools::write_svg(
204 path / (outfile +
"_" + vol_zr_svg._id +
"_" + traj_name),
205 {zr_axis, vol_zr_svg, svg_traj});
208 DETRAY_INFO_HOST(
"Wrote svgs for debugging in: " << path <<
"\n");
auto create_path(const std::string &outdir)
Check if a given file path exists and generate it if not.
Definition create_path.hpp:79
detail::index_range< dindex > dindex_range
Index ranges and sequences.
Definition indexing.hpp:24
vecmem::vector< value_t > dvector
Vector container backed by vecmem.
Definition containers.hpp:34