12#include "detray/core/concepts.hpp"
13#include "detray/navigation/intersection/intersection.hpp"
14#include "detray/propagator/rk_stepper.hpp"
15#include "detray/utils/logging.hpp"
18#include "detray/test/utils/perigee_stopper.hpp"
19#include "detray/test/validation/material_validation_utils.hpp"
20#include "detray/test/validation/navigation_validation_utils.hpp"
23#include <vecmem/memory/host_memory_resource.hpp>
34template <concepts::scalar scalar_t>
66template <concepts::detector detector_t,
typename bfield_view_t>
68 const detector_t& det,
const typename detector_t::name_map& names,
69 const std::optional<bfield_view_t>& bfield,
75 bool test_successful{
true};
77 using algebra_t =
typename detector_t::algebra_type;
85 vecmem::host_memory_resource host_mr;
88 const typename detector_t::geometry_context ctx{};
101 std::vector<dvector<data_record_t>> truth_traces_bw;
102 truth_traces_bw.reserve(tracks.capacity());
104 for (
const auto& truth_trace_fw : truth_traces_fw) {
107 std::ranges::reverse_copy(truth_trace_fw, truth_trace_bw.begin());
109 assert(!truth_trace_bw.empty());
111 truth_traces_bw.push_back(std::move(truth_trace_bw));
115 if (truth_traces_fw.empty() || truth_traces_bw.empty()) {
116 DETRAY_ERROR_HOST(
"Propagation truth data empty");
121 auto setup_actor_states = []<
typename... T>(
detray::dtuple<T...>& t) {
130 typename interactor::state interactor_state{};
136 std::cout <<
"-----------------------------------"
137 <<
"\nFORWARD - Propagation" << std::endl
138 <<
"-----------------------------------\n";
140 using parameter_updater = actor::parameter_updater<algebra_t, interactor>;
144 typename parameter_updater::state updater_state{};
145 updater_state.noise_estimation_cfg().n_stddev =
147 updater_state.noise_estimation_cfg().accumulated_error =
149 updater_state.noise_estimation_cfg().estimate_scattering_noise =
155 state_tuples.reserve(tracks.size());
156 state_ref_tuples.reserve(tracks.size());
158 for (std::size_t i = 0u; i < tracks.size(); ++i) {
160 updater_state.init(tracks.at(i));
164 state_ref_tuples.push_back(setup_actor_states(state_tuples.back()));
168 test_cfg.
name(det.name(names) +
"_GeV_fw");
170 const auto [trk_stats_fw, n_surfaces_fw, n_miss_nav_fw, n_miss_truth_fw,
171 step_traces_fw, track_mat_fw, mat_steps_fw] =
172 navigation_validator::compare_to_navigation<stepper_t, parameter_updater>(
173 test_cfg, host_mr, det, names, ctx, bfield, cfg.
propagation,
174 truth_traces_fw, tracks, state_ref_tuples);
177 auto n_tracks{
static_cast<double>(trk_stats_fw.n_tracks)};
178 if (
static_cast<double>(trk_stats_fw.n_tracks_w_holes) / n_tracks >
180 DETRAY_ERROR_HOST(
"Too many tracks with missing surfaces");
181 test_successful =
false;
183 if (
static_cast<double>(trk_stats_fw.n_tracks_w_extra) / n_tracks >
185 DETRAY_ERROR_HOST(
"Too many tracks with additional surfaces");
186 test_successful =
false;
189 std::cout <<
"\n-----------------------------------\n"
190 <<
"BACKWARD - Propagation" << std::endl
191 <<
"-----------------------------------\n";
198 bw_state_tuples.reserve(tracks.size());
199 bw_state_ref_tuples.reserve(tracks.size());
201 for (std::size_t i = 0u; i < tracks.size(); ++i) {
203 updater_state.init(tracks.at(i));
206 bw_state_tuples.push_back(
208 bw_state_ref_tuples.push_back(setup_actor_states(bw_state_tuples.back()));
212 test_cfg.
name(det.name(names) +
"_GeV_bw");
214 const auto [trk_stats_bw, n_surfaces_bw, n_miss_nav_bw, n_miss_truth_bw,
215 step_traces_bw, track_mat_bw, mat_steps_bw] =
216 navigation_validator::compare_to_navigation<stepper_t, parameter_updater,
218 test_cfg, host_mr, det, names, ctx, bfield, cfg.
propagation,
219 truth_traces_bw, tracks, bw_state_ref_tuples);
222 assert(trk_stats_fw.n_tracks > 0u);
223 assert(n_surfaces_fw.n_total() > 0u);
224 assert(trk_stats_bw.n_tracks > 0u);
225 assert(n_surfaces_bw.n_total() > 0u);
227 assert(trk_stats_fw.n_tracks == trk_stats_bw.n_tracks);
230 assert(step_traces_fw.size() == trk_stats_fw.n_tracks);
231 assert(mat_steps_fw.size() == trk_stats_fw.n_tracks);
232 assert(track_mat_fw.size() == trk_stats_fw.n_tracks);
233 assert(track_mat_fw.size() == track_mat_bw.size());
234 assert(step_traces_fw.size() == step_traces_bw.size());
235 assert(mat_steps_fw.size() == mat_steps_bw.size());
238 n_tracks =
static_cast<double>(trk_stats_bw.n_tracks);
239 if (
static_cast<double>(trk_stats_bw.n_tracks_w_holes) / n_tracks >
241 DETRAY_ERROR_HOST(
"Too many tracks with missing surfaces");
242 test_successful =
false;
244 if (
static_cast<double>(trk_stats_bw.n_tracks_w_extra) / n_tracks >
246 DETRAY_ERROR_HOST(
"Too many tracks with additional surfaces");
247 test_successful =
false;
250 std::cout <<
"\n-----------------------------------\n"
251 <<
"MATERIAL TRACE" << std::endl
252 <<
"-----------------------------------\n";
254 constexpr double rel_mat_error{0.01};
257 std::size_t n_bad_comp{0u};
259 std::size_t n_diff_mat{0u};
262 for (std::size_t i = 0u; i < track_mat_fw.size(); ++i) {
264 if (mat_steps_fw[i].empty() && mat_steps_bw[i].empty()) {
268 std::remove_cvref_t<
decltype(mat_steps_bw[i])> inv_mat_trace_bw{};
269 if (!mat_steps_bw[i].empty()) {
270 inv_mat_trace_bw.resize(mat_steps_bw[i].size());
273 std::ranges::reverse_copy(mat_steps_bw[i], inv_mat_trace_bw.begin());
275 assert(mat_steps_bw[i].size() == inv_mat_trace_bw.size());
279 const auto [is_bad_comp, is_diff_mat] = material_validator::compare_traces(
280 mat_steps_fw[i], track_mat_fw[i], inv_mat_trace_bw, track_mat_bw[i], i,
281 rel_mat_error, test_cfg.
verbose());
291 std::cout <<
"Total no. tracks with diff. material: "
292 << (n_bad_comp + n_diff_mat) <<
" ("
293 << 100. *
static_cast<double>(n_bad_comp + n_diff_mat) / n_tracks
294 <<
"%)" << std::endl;
296 std::cout <<
"No. identical tracks with diff. material: " << n_diff_mat
297 <<
" (" << 100. *
static_cast<double>(n_diff_mat) / n_tracks <<
"%)"
299 std::cout <<
"-----------------------------------\n" << std::endl;
302 if (n_diff_mat != 0) {
303 DETRAY_ERROR_HOST(
"" << n_diff_mat <<
" tracks have differing material");
304 test_successful =
false;
307 return test_successful;
The interface to the actors and aborters in the propagation.
Definition actor_chain.hpp:35
Runge-Kutta-Nystrom 4th order stepper implementation.
Definition rk_stepper.hpp:51
Detray include(s).
Definition array_operators.hpp:18
get_scalar_t< A, T > dscalar
Scalar type for algebra A and value type T.
Definition algebra.hpp:64
constexpr detray::tuple< std::decay_t< Ts >... > make_tuple(Ts &&...vs)
Construct a tuple by decaying and forwarding its arguments.
Definition tuple.hpp:219
vecmem::vector< value_t > dvector
Vector container backed by vecmem.
Definition containers.hpp:34
constexpr detray::tuple< Ts &... > tie(Ts &...args)
Create a tuple of references to the supplied objects.
Definition tuple.hpp:211
detray::tuple< types... > dtuple
Tuple type used by detray storage and dispatch.
Definition containers.hpp:46
free_parameters_vector< algebra_t > free_track_parameters
The free track parameters consist only of the parameter vector.
Definition free_track_parameters.hpp:249
bool propagation_validation(const detector_t &det, const typename detector_t::name_map &names, const std::optional< bfield_view_t > &bfield, const propagation_validation_config< typename detector_t::scalar_type > &cfg, const std::vector< free_track_parameters< typename detector_t::algebra_type > > &tracks, std::vector< dvector< intersection_record< detector_t > > > &truth_traces_fw)
Run a detray propagation and compare the surfaces that were encountered against a reference of truth ...
Definition propagation_validation.hpp:67
Apply energy-loss and multiple-scattering effects at material surfaces.
Definition pointwise_material_interactor.hpp:33
Record of a surface intersection along a track.
Definition data_record.hpp:27
Negative muon hypothesis.
Definition pdg_particle.hpp:111
float accumulated_error
Percentage of total track path to assume as accumulated error.
Definition navigation_config.hpp:34
int n_scattering_stddev
Number of standard deviations to assume to model the scattering noise.
Definition navigation_config.hpp:36
bool estimate_scattering_noise
Add adaptive mask tolerance to navigation.
Definition navigation_config.hpp:38
Particle hypothesis identified by PDG number, mass, and electric charge.
Definition pdg_particle.hpp:24
Per-actor configuration for checking the perigee.
Definition perigee_stopper.hpp:36
Actor that exits from a navigation stream, if it has reached the perigee.
Definition perigee_stopper.hpp:31
Configuration of the propagation.
Definition propagation_config.hpp:23
navigation::config navigation
Navigation options controlling candidate selection and stopping.
Definition propagation_config.hpp:25
Configure the Kalman Filter comparison test.
Definition propagation_validation.hpp:35
float max_percent_additional
Maximum allowed percentage of tracks with additional surfaces.
Definition propagation_validation.hpp:52
bool do_energy_loss
Whether energy loss is enabled.
Definition propagation_validation.hpp:45
propagation::config propagation
Propagation settings for the validation.
Definition propagation_validation.hpp:37
bool do_multiple_scattering
Whether multiple scattering is enabled.
Definition propagation_validation.hpp:43
pdg_particle< scalar_t > particle
Particle hypothesis used for propagation.
Definition propagation_validation.hpp:40
float max_percent_missed
Maximum allowed percentage of tracks with missed surfaces.
Definition propagation_validation.hpp:50
bool display_svg
Whether SVG output is enabled.
Definition propagation_validation.hpp:48
Specific navigation policy for the Runge-Kutta stepper: Use the relative amount of step size correcti...
Definition policies.hpp:101
A stepper inspector that prints information about the current stepper state.
Definition inspectors.hpp:371
Configuration for a detector scan test.
Definition navigation_validation_config.hpp:30
bool collect_sensitives_only() const
Check whether only sensitive surfaces are collected.
Definition navigation_validation_config.hpp:95
bool fail_on_diff() const
Check whether validation stops at the first difference.
Definition navigation_validation_config.hpp:104
bool display_svg() const
Check whether SVG output is enabled.
Definition navigation_validation_config.hpp:98
navigation::direction navigation_direction() const
Get the navigation direction.
Definition navigation_validation_config.hpp:92
bool verbose() const
Check whether verbose output is enabled.
Definition navigation_validation_config.hpp:107
pdg_particle< scalar_type > ptc_hypothesis() const
Get the particle hypothesis.
Definition navigation_validation_config.hpp:89
std::size_t n_tracks() const
Get the maximum number of tracks.
Definition navigation_validation_config.hpp:86
bool display_only_missed() const
Check whether SVG output is limited to missed surfaces.
Definition navigation_validation_config.hpp:101
const std::string & name() const
GettersGet the test name.
Definition navigation_validation_config.hpp:77