12#include "detray/core/concepts.hpp"
13#include "detray/definitions/algebra.hpp"
14#include "detray/material/concepts.hpp"
15#include "detray/material/detail/material_accessor.hpp"
16#include "detray/navigation/caching_navigator.hpp"
17#include "detray/navigation/detail/print_state.hpp"
18#include "detray/propagator/actors.hpp"
19#include "detray/propagator/line_stepper.hpp"
20#include "detray/propagator/propagator.hpp"
21#include "detray/utils/logging.hpp"
22#include "detray/utils/type_list.hpp"
25#include "detray/io/utils/create_path.hpp"
26#include "detray/io/utils/file_handle.hpp"
29#include "detray/test/utils/data_record.hpp"
32#include <vecmem/memory/memory_resource.hpp>
37namespace detray::material_validator {
43 double phi{detail::invalid_value<double>()};
45 double eta{detail::invalid_value<double>()};
69 [[maybe_unused]]
const mat_group_t &mat_group,
70 [[maybe_unused]]
const index_t &index,
71 [[maybe_unused]]
const point2_t &loc,
72 [[maybe_unused]]
const scalar_t cos_inc_angle)
const {
73 using material_t =
typename mat_group_t::value_type;
75 constexpr auto inv{detail::invalid_value<double>()};
81 const auto mat = detail::material_accessor::get(mat_group, index, loc);
89 const double seg{mat.path_segment(cos_inc_angle, loc[0])};
90 const double t{mat.thickness()};
91 const double mat_X0{mat.get_material().X0()};
92 const double mat_L0{mat.get_material().L0()};
106template <
template <
typename...>
class vector_t>
115 friend struct material_tracer;
120 explicit state(vecmem::memory_resource &resource)
121 : m_mat_steps(&resource) {}
126 explicit state(vector_t<material_record_type> &&steps)
127 : m_mat_steps(std::move(steps)) {}
154 vector_t<material_record_type> m_mat_steps{};
161 template <
typename propagator_state_t, concepts::algebra algebra_t>
163 state &tracer,
const propagator_state_t &prop_state,
165 record_track_dir(tracer, prop_state);
168 const auto &navigation = prop_state.navigation();
169 if (!navigation.encountered_sf_material()) {
174 typename propagator_state_t::detector_type::geometry_context gctx{};
179 record_mat_step(tracer, gctx, navigation.current_surface(), loc_pos,
186 template <
typename propagator_state_t>
188 state &tracer,
const propagator_state_t &prop_state)
const {
189 using algebra_t =
typename propagator_state_t::detector_type::algebra_type;
191 record_track_dir(tracer, prop_state);
194 const auto &navigation = prop_state.navigation();
195 if (!navigation.encountered_sf_material()) {
200 typename propagator_state_t::detector_type::geometry_context gctx{};
203 const auto sf = navigation.current_surface();
205 const auto &track_param = prop_state.stepping()();
208 sf.global_to_bound(gctx, track_param.pos(), glob_dir);
210 record_mat_step(tracer, gctx, sf, loc_pos, glob_dir);
215 template <
typename propagator_state_t>
216 DETRAY_HOST_DEVICE
inline auto record_track_dir(
217 state &tracer,
const propagator_state_t &prop_state)
const {
218 using algebra_t =
typename propagator_state_t::detector_type::algebra_type;
222 vector3_t glob_dir = prop_state.stepping()().dir();
223 if (detray::detail::is_invalid_value(tracer.m_track_material.eta) &&
224 detray::detail::is_invalid_value(tracer.m_track_material.phi)) {
225 tracer.m_track_material.eta = vector::eta(glob_dir);
226 tracer.m_track_material.phi = vector::phi(glob_dir);
231 template <concepts::detector detector_t>
232 DETRAY_HOST_DEVICE
inline auto record_mat_step(
233 state &tracer,
const typename detector_t::geometry_context &gctx,
238 const auto mat_params = sf.template visit_material<get_material_record>(
239 loc_pos,
cos_angle(gctx, sf, glob_dir, loc_pos));
241 const double seg{mat_params.path};
242 const double t{mat_params.thickness};
243 const double mx0{mat_params.mat_X0};
244 const double ml0{mat_params.mat_L0};
248 tracer.m_track_material.sX0 += seg / mx0;
249 tracer.m_track_material.tX0 += t / mx0;
252 tracer.m_track_material.sL0 += seg / ml0;
253 tracer.m_track_material.tL0 += t / ml0;
256 tracer.m_mat_steps.push_back({sf.identifier(), seg, t, mx0, ml0});
262template <concepts::detector detector_t>
263inline auto record_material(
264 const typename detector_t::geometry_context ,
265 vecmem::memory_resource *host_mr,
const detector_t &det,
266 const propagation::config &cfg,
268 using algebra_t =
typename detector_t::algebra_type;
271 using stepper_t = line_stepper<algebra_t>;
272 using navigator_t = caching_navigator<detector_t>;
275 using material_tracer_t = material_validator::material_tracer<vecmem::vector>;
276 using pathlimit_aborter_t = actor::pathlimit_aborter<scalar_t>;
277 using parameter_updater_t =
278 actor::parameter_updater<algebra_t,
279 actor::pointwise_material_interactor<algebra_t>,
281 using actor_chain_t = actor_chain<pathlimit_aborter_t, parameter_updater_t>;
282 using propagator_t = propagator<stepper_t, navigator_t, actor_chain_t>;
285 propagator_t prop{cfg};
288 typename pathlimit_aborter_t::state pathlimit_aborter_state{
289 cfg.stepping.path_limit};
290 actor::parameter_updater_state<algebra_t> updater_state{cfg, track};
291 typename actor::pointwise_material_interactor<algebra_t>::state
293 typename material_tracer_t::state mat_tracer_state{*host_mr};
295 auto actor_states =
detray::tie(pathlimit_aborter_state, updater_state,
296 interactor_state, mat_tracer_state);
298 typename propagator_t::state propagation{track, det, cfg.context};
301 bool success = prop.propagate(propagation, actor_states);
303 return std::make_tuple(success,
304 std::move(mat_tracer_state).release_track_material(),
305 std::move(mat_tracer_state).release_material_steps());
320inline auto compare_traces(
323 std::size_t trk_i = detail::invalid_value<std::size_t>(),
324 const double rel_tol = 0.01,
const bool verbose =
true) {
326 bool is_bad_comp{reference.size() != mat_trace.size()};
328 bool is_diff_mat{
false};
330 std::stringstream debug_msg{};
331 debug_msg <<
"Track No. " << trk_i <<
":\n----------------" << std::endl;
334 debug_msg <<
"-> Different no. of surfaces: " << mat_trace.size()
335 <<
" (ref.: " << reference.size() <<
")\n"
338 for (std::size_t j = 0u; j < math::min(reference.size(), mat_trace.size());
340 if (reference[j].geo_id != mat_trace[j].geo_id) {
342 debug_msg <<
"-> Surfaces don't match: " << mat_trace[j].geo_id
343 <<
" (ref.: " << reference[j].geo_id <<
")" << std::endl;
349 if ((reference[j].thickness - mat_trace[j].thickness) /
350 reference[j].thickness >
353 debug_msg <<
"-> On surface: " << reference[j].geo_id <<
":"
355 debug_msg <<
"-> thickness: " << mat_trace[j].thickness
356 <<
", thickness ref.: " << reference[j].thickness
361 if ((reference[j].mat_X0 - mat_trace[j].mat_X0) / reference[j].mat_X0 >
364 debug_msg <<
"-> On surface: " << reference[j].geo_id <<
":"
366 debug_msg <<
"-> X0: " << mat_trace[j].mat_X0
367 <<
", X0 ref.: " << reference[j].mat_X0 << std::endl;
371 if ((reference[j].mat_L0 - mat_trace[j].mat_L0) / reference[j].mat_L0 >
374 debug_msg <<
"-> On surface: " << reference[j].geo_id <<
":"
376 debug_msg <<
"-> L0: " << mat_trace[j].mat_L0
377 <<
", L0 ref.: " << reference[j].mat_L0 << std::endl;
381 if ((reference[j].path - mat_trace[j].path) / reference[j].path >
384 debug_msg <<
"-> On surface: " << reference[j].geo_id <<
":"
387 <<
" mm, mat. path ref.: "
394 const double rel_error{(ref_record.sX0 - mat_record.sX0) / ref_record.sX0};
395 const bool small_mat{ref_record.sX0 < rel_tol && mat_record.sX0 < rel_tol};
399 if (!(small_mat || (rel_error <= rel_tol))) {
405 debug_msg <<
"\nTotal material discrepancy of " << 100. * rel_error <<
"%\n"
409 if (verbose && (is_bad_comp || is_diff_mat)) {
410 DETRAY_INFO_HOST(debug_msg.str());
413 return std::make_tuple(is_bad_comp, is_diff_mat);
418inline auto write_material(
const std::string &mat_file_name,
420 const auto file_path = std::filesystem::path{mat_file_name};
421 assert(file_path.extension() ==
".csv");
426 detray::io::file_handle outfile{
427 mat_file_name, std::ios::out | std::ios::binary | std::ios::trunc};
428 *outfile <<
"eta,phi,mat_sX0,mat_sL0,mat_tX0,mat_tL0" << std::endl;
430 for (
const auto &rec : mat_records) {
431 *outfile << rec.eta <<
"," << rec.phi <<
"," << rec.sX0 <<
"," << rec.sL0
432 <<
"," << rec.tX0 <<
"," << rec.tL0 << std::endl;
Unique identifier for geometry objects, based on the ACTS GeometryIdentifier.
Definition identifier.hpp:36
Definition concepts.hpp:74
Scalar concept: Elements of vectors/matrices (can be simd vectors).
Definition concepts.hpp:40
Material that can used for surfaces.
Definition concepts.hpp:111
auto create_path(const std::string &outdir)
Check if a given file path exists and generate it if not.
Definition create_path.hpp:79
get_scalar_t< A, T > dscalar
Scalar type for algebra A and value type T.
Definition algebra.hpp:64
vecmem::vector< value_t > dvector
Vector container backed by vecmem.
Definition containers.hpp:34
constexpr dscalar< typename detector_t::algebra_type > cos_angle(const typename detector_t::geometry_context &ctx, geometry::surface< detector_t > sf, const dvector3D< typename detector_t::algebra_type > &dir, const point_t &loc)
Helper to get the incidence angle of a direction vector on a surface.
Definition geometry_utils.hpp:29
get_vector3D_t< A, T > dvector3D
Three-dimensional vector type for algebra A and value type T.
Definition algebra.hpp:80
constexpr detray::tuple< Ts &... > tie(Ts &...args)
Create a tuple of references to the supplied objects.
Definition tuple.hpp:211
tracking_surface(const detector_t &, const descr_t &) -> tracking_surface< detector_t >
Deduce the detector type from a detector and surface descriptor pair.
get_point2D_t< A, T > dpoint2D
Two-dimensional point type for algebra A and value type T.
Definition algebra.hpp:68
free_parameters_vector< algebra_t > free_track_parameters
The free track parameters consist only of the parameter vector.
Definition free_track_parameters.hpp:249
Result of the param. transporter: bound track parameters at dest. sf.
Definition parameter_updater.hpp:210
constexpr const bound_track_parameters< algebra_t > & destination_params() const
Definition parameter_updater.hpp:236
Base class actor implementation.
Definition base_actor.hpp:20
Contains the material parameters and the pathlength.
Definition data_record.hpp:303
Functor to retrieve the material parameters for a given local position.
Definition material_validation_utils.hpp:59
auto operator()(const mat_group_t &mat_group, const index_t &index, const point2_t &loc, const scalar_t cos_inc_angle) const
Retrieve the material record at a local position.
Definition material_validation_utils.hpp:68
State used to collect material during propagation.
Definition material_validation_utils.hpp:114
state(vecmem::memory_resource &resource)
Construct the vector containers with a given resource.
Definition material_validation_utils.hpp:120
const auto & get_material_steps() const
Access to the recorded material steps along the track - const.
Definition material_validation_utils.hpp:142
auto && release_track_material() &&
Move the total recorded material out of the actor.
Definition material_validation_utils.hpp:137
state(vector_t< material_record_type > &&steps)
Construct from externally provided vector for the steps.
Definition material_validation_utils.hpp:126
const auto & get_track_material() const
Access to the total recorded material along the track - const.
Definition material_validation_utils.hpp:132
auto && release_material_steps() &&
Move the recorded material steps pout of the actor.
Definition material_validation_utils.hpp:147
Actor that collects all material encountered by a track during navigation.
Definition material_validation_utils.hpp:107
material_record material_record_type
Type storing one material step.
Definition material_validation_utils.hpp:111
track_material track_material_type
Type storing accumulated track material.
Definition material_validation_utils.hpp:109
void operator()(state &tracer, const propagator_state_t &prop_state) const
Run in a propagation chain without covariance transport.
Definition material_validation_utils.hpp:187
void operator()(state &tracer, const propagator_state_t &prop_state, const detray::actor::parameter_transporter_result< algebra_t > &res) const
Run as observer to the parameter transporter (covariance transport).
Definition material_validation_utils.hpp:162
Record the total material budget per track.
Definition material_validation_utils.hpp:40
double sX0
Accumulated radiation length per pathlength through the material.
Definition material_validation_utils.hpp:48
double tL0
Accumulated interaction length per thickness.
Definition material_validation_utils.hpp:54
double sL0
Accumulated interaction length per pathlength through the material.
Definition material_validation_utils.hpp:52
double eta
Eta of the track.
Definition material_validation_utils.hpp:45
double tX0
Accumulated radiation length per thickness.
Definition material_validation_utils.hpp:50
double phi
Phi and eta values of the track for which the material was recorded.
Definition material_validation_utils.hpp:43
static constexpr scalar_t mm
Native length unit, the millimetre.
Definition units.hpp:27