ACTS
Experiment-independent tracking
Loading...
Searching...
No Matches
svg_display.hpp
1// This file is part of the ACTS project.
2//
3// Copyright (C) 2016 CERN for the benefit of the ACTS project
4//
5// This Source Code Form is subject to the terms of the Mozilla Public
6// License, v. 2.0. If a copy of the MPL was not distributed with this
7// file, You can obtain one at https://mozilla.org/MPL/2.0/.
8
9#pragma once
10
11// Project include(s)
12#include "detray/core/concepts.hpp"
13#include "detray/definitions/algebra.hpp"
14#include "detray/utils/logging.hpp"
15
16// Detray plugin include(s)
17#include "detray/plugins/svgtools/illustrator.hpp"
18#include "detray/plugins/svgtools/styling/styling.hpp"
19#include "detray/plugins/svgtools/writer.hpp"
20
21// Detray IO include(s)
22#include "detray/io/utils/create_path.hpp"
23
24// System include(s)
25#include <algorithm>
26#include <filesystem>
27#include <iostream>
28#include <string>
29#include <unordered_set>
30
31namespace detray::detail {
32
35template <typename record_t>
36std::unordered_set<dindex> get_volume_indices(
37 const dvector<record_t> &intersection_record) {
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()) {
42 continue;
43 }
44 volumes.insert(single_ir.volume());
45 }
46
47 return volumes;
48}
49
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()) {
60 continue;
61 }
62 volumes.insert(intr.surface().volume());
63 }
64
65 return volumes;
66}
67
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()) {
79 continue;
80 }
81 volumes.insert(cand.intersection.surface().volume());
82 }
83
84 return volumes;
85}
86
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;
97
98 std::vector<intersection_t> intersections{};
99 intersections.reserve(intersection_trace.size());
100 for (auto &ir : intersection_trace) {
101 // Dummy record
102 if (ir.intersection().surface().identifier().is_invalid()) {
103 continue;
104 }
105 intersections.push_back(ir.intersection());
106 }
107
108 return intersections;
109}
110
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,
119 const view_t &view,
120 dindex_range highlight_idx = {detail::invalid_value<dindex>(),
121 detail::invalid_value<dindex>()}) {
122 // Get only the intersections from the traces
123 auto truth_intersections = transcribe_intersections(truth_trace);
124 auto recorded_intersections = transcribe_intersections(recorded_trace);
125
126 // Was a dummy record removed before printing?
127 if (truth_intersections.size() < truth_trace.size()) {
128 highlight_idx.shift(-1);
129 }
130
131 // Draw the truth intersections as black crosses
132 actsvg::svg::object svg_traj;
133 if (!truth_intersections.empty()) {
134 svg_traj = il.draw_intersections("truth_trace", truth_intersections,
135 traj.dir(0.f), view, highlight_idx, gctx);
136 }
137
138 // Draw an approximation of the trajectory with the recorded intersections
139 const auto path{math::max(math::fabs(truth_intersections.front().path()),
140 math::fabs(truth_intersections.back().path()))};
141 if (!recorded_intersections.empty()) {
142 svg_traj.add_object(il.draw_intersections_and_trajectory(
143 traj_name, recorded_intersections, traj, view, path, highlight_idx,
144 gctx));
145 } else {
146 svg_traj.add_object(il.draw_trajectory(traj_name, traj, path, view));
147 }
148
149 return svg_traj;
150}
151
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/") {
165 // Gather all volumes that need to be displayed
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());
170 }
171
172 // General options
173 auto path = detray::io::create_path(outdir);
174
175 actsvg::style::stroke stroke_black = actsvg::style::stroke();
176
177 // x-y axis.
178 auto xy_axis = actsvg::draw::x_y_axes("axes", {-1100, 1100}, {-1100, 1100},
179 stroke_black, "x", "y");
180 // z-r axis.
181 auto zr_axis = actsvg::draw::x_y_axes("axes", {-3100, 3100}, {-5, 1100},
182 stroke_black, "z", "r");
183 // Creating the views.
184 const actsvg::views::x_y xy{};
185 const actsvg::views::z_r zr{};
186
187 // xy - view
188 auto svg_traj =
189 draw_intersection_and_traj_svg(gctx, il, truth_trace, traj, traj_name,
190 recorded_trace, xy, highlight_idx);
191
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});
196
197 // zr - view
198 svg_traj =
199 draw_intersection_and_traj_svg(gctx, il, truth_trace, traj, traj_name,
200 recorded_trace, zr, highlight_idx);
201
202 const auto vol_zr_svg = il.draw_detector(zr, gctx);
203 detray::svgtools::write_svg(
204 path / (outfile + "_" + vol_zr_svg._id + "_" + traj_name),
205 {zr_axis, vol_zr_svg, svg_traj});
206
207 if (verbose) {
208 DETRAY_INFO_HOST("Wrote svgs for debugging in: " << path << "\n");
209 }
210}
211
212} // namespace detray::detail
auto draw_intersections(const std::string &prefix, const std::vector< intersection_t > &intersections, const typename detector_t::vector3_type dir, const view_t &view, const dindex_range highlight_idx={detail::invalid_value< dindex >(), detail::invalid_value< dindex >()}, const typename detector_t::geometry_context &gctx={}) const
Converts a collection of intersections to an svg.
Definition illustrator.hpp:546
auto draw_trajectory(const std::string &prefix, const trajectory_t< algebra_t > &trajectory, const dscalar< algebra_t > path, const view_t &view) const
Converts a trajectory to an svg.
Definition illustrator.hpp:570
auto draw_intersections_and_trajectory(const std::string &prefix, const std::vector< intersection_t > &intersections, const trajectory_t &trajectory, const view_t &view, typename detector_t::scalar_type max_path=500.f, const dindex_range highlight_idx={detail::invalid_value< dindex >(), detail::invalid_value< dindex >()}, const typename detector_t::geometry_context &gctx={}) const
Converts a trajectory and its intersections to an svg with a related coloring.
Definition illustrator.hpp:611
auto draw_volumes(const range_t &volume_ids, const view_t &view, const typename detector_t::geometry_context &gctx={}) const
Converts multiple detray volumes of the detector to an svg.
Definition illustrator.hpp:445
auto draw_detector(const view_t &view, const typename detector_t::geometry_context &gctx={}, const float r_length=1100.f, const float z_length=3100.f) const
Converts a detray detector to an svg.
Definition illustrator.hpp:480
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