File indexing completed on 2026-07-26 08:22:20
0001
0002
0003
0004
0005
0006
0007
0008 #pragma once
0009
0010
0011 #include "traccc/edm/measurement_collection.hpp"
0012 #include "traccc/edm/particle.hpp"
0013 #include "traccc/edm/track_parameters.hpp"
0014 #include "traccc/io/csv/hit.hpp"
0015 #include "traccc/io/csv/particle.hpp"
0016
0017
0018 #include <detray/navigation/intersection/intersection.hpp>
0019
0020
0021 #include <detray/test/utils/inspectors.hpp> //< candidate_record type
0022
0023
0024 #include <algorithm>
0025
0026 namespace traccc::propagation_validator {
0027
0028 template <typename detector_t>
0029 using intersection_type =
0030 detray::intersection2D<typename detector_t::surface_type,
0031 typename detector_t::algebra_type, true>;
0032
0033 template <typename detector_t>
0034 using candidate_type =
0035 detray::navigation::detail::candidate_record<intersection_type<detector_t>>;
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047 template <typename detector_t>
0048 auto transcribe_to_trace(const typename detector_t::geometry_context ctx,
0049 const detector_t& det,
0050 const traccc::io::csv::particle& ptc,
0051 const std::vector<traccc::io::csv::hit>& hits,
0052 const std::size_t n_hits_for_particle = 10u) {
0053 using intersection_t = typename candidate_type<detector_t>::intersection_type;
0054
0055 detray::dvector<candidate_type<detector_t>> candidates{};
0056 candidates.reserve(n_hits_for_particle);
0057
0058
0059 for (const auto& h : hits) {
0060 if (h.particle_id != ptc.particle_id) {
0061 continue;
0062 }
0063
0064
0065 const point3 pos{h.tx, h.ty, h.tz};
0066 const vector3 mom{h.tpx, h.tpy, h.tpz};
0067 const vector3 dir = vector::normalize(mom);
0068 const scalar path{vector::norm(pos)};
0069
0070
0071 const detray::geometry::identifier geo_id{h.geometry_id};
0072 const auto sf_desc = det.surfaces().at(geo_id.index());
0073 const auto sf = detray::tracking_surface{det, geo_id};
0074
0075
0076 using nav_link_t = typename intersection_t::nav_link_t;
0077 auto loc_pos = sf.global_to_local(ctx, pos, dir);
0078 intersection_t intr{sf_desc,
0079 path,
0080 static_cast<nav_link_t>(geo_id.volume()),
0081 detray::intersection::status::e_inside,
0082 true,
0083 loc_pos};
0084
0085 candidates.emplace_back(pos, dir, intr, ptc.q, vector::norm(mom));
0086 }
0087
0088
0089 auto sort_by_path = [&](const candidate_type<detector_t>& a,
0090 const candidate_type<detector_t>& b) -> bool {
0091 return (a.intersection < b.intersection);
0092 };
0093
0094 std::ranges::stable_sort(candidates, sort_by_path);
0095
0096 return candidates;
0097 }
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109 template <typename detector_t>
0110 auto transcribe_to_trace(
0111 const typename detector_t::geometry_context ctx, const detector_t& det,
0112 const traccc::particle& ptc,
0113 const std::map<traccc::particle,
0114 std::vector<edm::measurement_collection::host::object_type>>&
0115 ptc_to_meas_map,
0116 const std::size_t n_meas_for_particle = 10u) {
0117 using intersection_t = typename candidate_type<detector_t>::intersection_type;
0118
0119 vecmem::vector<candidate_type<detector_t>> candidates{};
0120 candidates.reserve(n_meas_for_particle);
0121
0122
0123 const scalar p{vector::norm(ptc.momentum)};
0124 const scalar q{ptc.charge};
0125
0126
0127 for (const auto& meas : ptc_to_meas_map.at(ptc)) {
0128
0129 const detray::geometry::identifier geo_id{meas.surface_link()};
0130 const auto sf_desc = det.surfaces().at(geo_id.index());
0131 const auto sf = detray::tracking_surface{det, geo_id};
0132
0133
0134 const vector3 dir{vector::normalize(ptc.momentum)};
0135 const point3 glob_pos{sf.local_to_global(ctx, meas.local_position(), dir)};
0136
0137
0138 const scalar path{vector::norm(glob_pos)};
0139
0140
0141 using nav_link_t = typename intersection_t::nav_link_type;
0142 intersection_t intr{
0143 sf_desc,
0144 path,
0145 {meas.local_position()[0], meas.local_position()[1], 0.f},
0146 static_cast<nav_link_t>(geo_id.volume()),
0147 detray::intersection::status::e_inside,
0148 true};
0149
0150
0151 candidates.emplace_back(glob_pos, dir, intr, q, p);
0152 }
0153
0154
0155 auto sort_by_path = [&](const candidate_type<detector_t>& a,
0156 const candidate_type<detector_t>& b) -> bool {
0157 return (a.intersection < b.intersection);
0158 };
0159
0160 std::ranges::stable_sort(candidates, sort_by_path);
0161
0162 return candidates;
0163 }
0164
0165 }