Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-07-26 08:22:20

0001 /** TRACCC library, part of the ACTS project (R&D line)
0002  *
0003  * (c) 2026 CERN for the benefit of the ACTS project
0004  *
0005  * Mozilla Public License Version 2.0
0006  */
0007 
0008 #pragma once
0009 
0010 // Project include(s).
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 // Detray include(s).
0018 #include <detray/navigation/intersection/intersection.hpp>
0019 
0020 // Detray test include(s)
0021 #include <detray/test/utils/inspectors.hpp>  //< candidate_record type
0022 
0023 // System include(s)
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 /// Transcribe the hits for a particle to a candidate trace for the detray
0038 /// propagation validation tools
0039 ///
0040 /// @param ctx the geometric context
0041 /// @param det the detector
0042 /// @param ptc the truth particle
0043 /// @param hits all hits in the event
0044 /// @param n_hits_for_particle expected number of hits for the particle
0045 ///
0046 /// @returns a vector of intersection candidate records
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   // Fill the hits into the candidate trace
0059   for (const auto& h : hits) {
0060     if (h.particle_id != ptc.particle_id) {
0061       continue;
0062     }
0063 
0064     // Rough estimate of path
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     // Corresponding surface
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     // Build an intersection from the hit
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   // Sort records by intersection distance to origin of the trajectory
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 /// Transcribe the measurements for a particle to a candidate trace for the
0100 /// detray propagation validation tools
0101 ///
0102 /// @param ctx the geometric context
0103 /// @param det the detector
0104 /// @param ptc the truth particle
0105 /// @param ptc_to_meas_map map the truth particle to its measurements
0106 /// @param n_meas_for_particle expected number of ,easurements for the particle
0107 ///
0108 /// @returns a vector of intersection candidate records
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   // TODO: Not accurate for every measurement
0123   const scalar p{vector::norm(ptc.momentum)};
0124   const scalar q{ptc.charge};
0125 
0126   // Fill the hits into the candidate trace
0127   for (const auto& meas : ptc_to_meas_map.at(ptc)) {
0128     // Corresponding surface
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     // TODO: Use correct track direction at measurement for line sf.
0134     const vector3 dir{vector::normalize(ptc.momentum)};
0135     const point3 glob_pos{sf.local_to_global(ctx, meas.local_position(), dir)};
0136 
0137     // Rough estimate of intersection distance from origin
0138     const scalar path{vector::norm(glob_pos)};
0139 
0140     // Build an intersection
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     // TODO: Don't use initial particle momentum
0151     candidates.emplace_back(glob_pos, dir, intr, q, p);
0152   }
0153 
0154   // Sort records by intersection distance to origin of the trajectory
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 }  // namespace traccc::propagation_validator