12#include "detray/core/concepts.hpp"
13#include "detray/definitions/algebra.hpp"
14#include "detray/geometry/surface.hpp"
15#include "detray/navigation/detail/intersection_kernel.hpp"
16#include "detray/navigation/intersection/intersection.hpp"
17#include "detray/navigation/intersector.hpp"
18#include "detray/tracks/free_track_parameters.hpp"
19#include "detray/tracks/trajectories.hpp"
22#include "detray/io/csv/intersection2D.hpp"
23#include "detray/io/csv/track_parameters.hpp"
26#include "detray/test/utils/data_record.hpp"
40template <
typename trajectory_t>
55 template <concepts::detector detector_t>
56 inline auto operator()(
const typename detector_t::geometry_context ctx,
57 const detector_t &detector,
const trajectory_t &traj,
58 const typename detector_t::scalar_type mask_tol = 0.f,
59 const typename detector_t::scalar_type p =
62 using algebra_t =
typename detector_t::algebra_type;
64 using sf_desc_t =
typename detector_t::surface_type;
65 using nav_link_t =
typename detector_t::surface_type::navigation_link;
67 using intersection_t =
69 using intersection_kernel_t = detail::intersection_initialize<intersector>;
71 constexpr scalar_t external_mask_tol{0.f};
73 .min_mask_tolerance =
static_cast<float>(mask_tol),
74 .max_mask_tolerance =
static_cast<float>(mask_tol),
75 .mask_tolerance_scalor = 0.f,
76 .overstep_tolerance = 0.f};
83 const scalar_t q{p * traj.qop()};
86 intersections.reserve(100u);
89 for (
const sf_desc_t &sf_desc : detector.
surfaces()) {
92 DETRAY_DEBUG_HOST(
"Intersecting sf: " << sf.identifier());
94 sf.template visit_mask<intersection_kernel_t>(
95 intersections, traj, sf_desc, trf_store, ctx, intr_cfg,
99 const std::size_t n_records{intersection_trace.size()};
100 for (
auto &sfi : intersections) {
101 if (sfi.is_along()) {
102 sfi.surface() = sf_desc;
104 intersection_trace.emplace_back(traj.pos(sfi.path()),
105 traj.dir(sfi.path()), sfi, q, p,
107 DETRAY_DEBUG_HOST(
"Recorded intersection: " << sfi);
110 intersections.clear();
112 if (n_records == intersection_trace.size()) {
113 DETRAY_DEBUG_HOST(
"No valid intersection found with this surface");
118 if (intersection_trace.empty()) {
119 std::stringstream stream;
120 stream <<
"No intersections found for traj: " << traj << std::endl;
123 DETRAY_FATAL_HOST(stream.str());
124 throw std::runtime_error(stream.str());
128 const auto &first_record = intersection_trace.front();
129 intersection_t start_intersection{};
132 start_intersection.set_surface(first_record.intersection().surface());
133 start_intersection.surface().set_id(surface_id::e_passive);
134 start_intersection.surface().set_index(0);
135 start_intersection.surface()
137 .set_id(detector_t::material::id::e_none)
139 start_intersection.set_path(0.f);
140 start_intersection.set_local({0.f, 0.f, 0.f});
141 start_intersection.set_volume_link(
142 static_cast<nav_link_t
>(first_record.volume()));
145 traj.pos(), traj.dir(), start_intersection,
146 q, p, first_record.volume()};
148 intersection_trace.insert(intersection_trace.begin(), start_record);
150 return intersection_trace;
155template <concepts::algebra algebra_t>
159template <concepts::algebra algebra_t>
172 typename trajectory_t,
typename... Args>
173inline auto run(
const typename detector_t::geometry_context gctx,
174 const detector_t &detector,
const trajectory_t &traj,
176 using algebra_t =
typename detector_t::algebra_type;
177 using nav_link_t =
typename detector_t::surface_type::navigation_link;
179 DETRAY_DEBUG_HOST(
"Trajectory: " << traj);
181 auto intersection_trace =
182 scan_type<algebra_t>{}(gctx, detector, traj, std::forward<Args>(args)...);
189 auto sort_path = [&](
const record_t &a,
const record_t &b) ->
bool {
190 return (a.intersection() < b.intersection());
193 std::ranges::stable_sort(intersection_trace, sort_path);
196 auto is_world_exit = [](
const record_t &r) {
197 return r.intersection().volume_link() ==
198 detray::detail::invalid_value<nav_link_t>();
201 if (
auto it = std::ranges::find_if(intersection_trace, is_world_exit);
202 it != intersection_trace.end()) {
203 auto n{
static_cast<std::size_t
>(it - intersection_trace.begin())};
204 intersection_trace.resize(n + 1u);
207 return intersection_trace;
214template <concepts::detector detector_t,
typename allocator_t>
216 const std::string &intersection_file_name,
218 &intersection_traces) {
220 using intersection_t =
typename record_t::intersection_type;
222 std::vector<std::vector<intersection_t>> intersections{};
225 for (
const auto &trace : intersection_traces) {
226 auto &intrs = intersections.emplace_back();
227 intrs.reserve(trace.size());
229 for (
const auto &record : trace) {
230 intrs.push_back(record.intersection());
235 io::csv::write_intersection2D(intersection_file_name, intersections);
242template <concepts::detector detector_t,
typename allocator_t>
244 const std::string &track_param_file_name,
246 &intersection_traces) {
249 using track_param_t =
252 std::vector<std::vector<std::pair<scalar_t, track_param_t>>> track_params{};
255 for (
const auto &trace : intersection_traces) {
256 track_params.push_back({});
257 track_params.back().reserve(trace.size());
259 for (
const auto &record : trace) {
260 track_params.back().emplace_back(record.template charge<value_t>(),
261 record.track_param());
266 io::csv::write_free_track_params(track_param_file_name, track_params);
274template <concepts::detector detector_t,
typename allocator_t>
276 const std::string &intersection_file_name,
277 const std::string &track_param_file_name,
279 &intersection_traces) {
283 auto intersections_per_track =
284 io::csv::read_intersection2D<detector_t>(intersection_file_name);
285 auto track_params_per_track =
286 io::csv::read_free_track_params<detector_t>(track_param_file_name);
288 if (intersections_per_track.size() != track_params_per_track.size()) {
289 throw std::invalid_argument(
290 "Detector scanner: intersection and track parameters collections have "
295 for (
dindex trk_idx = 0u; trk_idx < intersections_per_track.size();
297 const auto &intersections = intersections_per_track[trk_idx];
298 const auto &track_params = track_params_per_track[trk_idx];
301 if (intersections.size() != track_params.size()) {
302 throw std::invalid_argument(
303 "Detector scanner: Found different number of intersections and track "
304 "parameters for track no." +
305 std::to_string(trk_idx));
309 if (intersections.empty()) {
310 throw std::invalid_argument(
"Detector scanner: Found empty trace no." +
311 std::to_string(trk_idx));
315 if (intersection_traces.size() <= trk_idx) {
316 intersection_traces.push_back({});
320 for (
dindex i = 0u; i < intersections.size(); ++i) {
321 const track_t &free_param = track_params[i].second;
323 free_param.pos(), free_param.dir(), intersections[i],
324 track_params[i].first, free_param.p(track_params[i].first),
325 intersections[i].surface().volume()});
auto transform_store(const geometry_context &={}) const -> const transform_container &
Definition detector.hpp:301
auto surfaces() const -> const surface_lookup_container &
Definition detector.hpp:286
Facade for a detray detector surface.
Definition surface.hpp:36
Check if a type can be used as a detector.
Definition concepts.hpp:47
Run a scan on detector object by shooting test particles through it.
Definition detector_scan_utils.hpp:39
auto write_intersections(const std::string &intersection_file_name, const std::vector< dvector< intersection_record< detector_t > >, allocator_t > &intersection_traces)
Write the intersection_traces to file.
Definition detector_scanner.hpp:215
auto run(const typename detector_t::geometry_context gctx, const detector_t &detector, const trajectory_t &traj, Args &&...args)
Run a scan on detector object by shooting test particles through it.
Definition detector_scanner.hpp:173
auto read(const std::string &intersection_file_name, const std::string &track_param_file_name, std::vector< std::vector< intersection_record< detector_t >, allocator_t > > &intersection_traces)
Read the intersection_record from file.
Definition detector_scanner.hpp:275
auto write_tracks(const std::string &track_param_file_name, const std::vector< dvector< intersection_record< detector_t > >, allocator_t > &intersection_traces)
Write the intersection_traces to file.
Definition detector_scanner.hpp:243
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
vecmem::vector< value_t > dvector
Vector container backed by vecmem.
Definition containers.hpp:34
brute_force_scan< detail::ray< algebra_t > > ray_scan
Type of a ray scan for the selected algebra.
Definition detector_scanner.hpp:156
unsigned int dindex
Default index type.
Definition indexing.hpp:18
constexpr dindex dindex_invalid
Global invalid index definition.
Definition indexing.hpp:21
get_value_t< A > dvalue
Value scalar type of the algebra backend.
Definition algebra.hpp:48
brute_force_scan< detail::helix< algebra_t > > helix_scan
Type of a helix scan for the selected algebra.
Definition detector_scanner.hpp:160
free_parameters_vector< algebra_t > free_track_parameters
The free track parameters consist only of the parameter vector.
Definition free_track_parameters.hpp:249
struct that holds functionality to shoot a parametrized particle trajectory through a detector.
Definition detector_scanner.hpp:41
dvector< intersection_record< D > > intersection_trace_type
Type of the intersection trace produced for a detector.
Definition detector_scanner.hpp:44
trajectory_t trajectory_type
Type of trajectory scanned by this functor.
Definition detector_scanner.hpp:46
auto operator()(const typename detector_t::geometry_context ctx, const detector_t &detector, const trajectory_t &traj, const typename detector_t::scalar_type mask_tol=0.f, const typename detector_t::scalar_type p=1.f *unit< typename detector_t::scalar_type >::GeV)
Scan a detector along the configured trajectory.
Definition detector_scanner.hpp:56
Intersector configuration.
Definition intersection_config.hpp:21
Record of a surface intersection along a track.
Definition data_record.hpp:27
intersection2D< typename detector_t::surface_type, typename detector_t::algebra_type, intersection::contains_pos > intersection_type
Intersection result type stored by this record.
Definition data_record.hpp:41
static constexpr scalar_t GeV
Native energy unit, the gigaelectronvolt.
Definition units.hpp:81