|
| 1 | +/** Detray library, part of the ACTS project (R&D line) |
| 2 | + * |
| 3 | + * (c) 2025 CERN for the benefit of the ACTS project |
| 4 | + * |
| 5 | + * Mozilla Public License Version 2.0 |
| 6 | + */ |
| 7 | + |
| 8 | +#pragma once |
| 9 | + |
| 10 | +// Project include(s) |
| 11 | +#include "detray/definitions/algebra.hpp" |
| 12 | +#include "detray/definitions/detail/qualifiers.hpp" |
| 13 | +#include "detray/definitions/math.hpp" |
| 14 | +#include "detray/definitions/units.hpp" |
| 15 | +#include "detray/geometry/surface.hpp" |
| 16 | +#include "detray/navigation/detail/print_state.hpp" |
| 17 | +#include "detray/navigation/navigation_config.hpp" |
| 18 | + |
| 19 | +// System include(s) |
| 20 | +#include <iomanip> |
| 21 | +#include <sstream> |
| 22 | +#include <string> |
| 23 | + |
| 24 | +namespace detray::navigation { |
| 25 | + |
| 26 | +/// Print basic information about the state of a navigation stream @param state |
| 27 | +template <typename state_type> |
| 28 | +DETRAY_HOST inline std::string print_state(const state_type &state) { |
| 29 | + |
| 30 | + // Gathers navigation information accross navigator update calls |
| 31 | + std::stringstream debug_stream{}; |
| 32 | + // Column width in output |
| 33 | + constexpr int cw{20}; |
| 34 | + |
| 35 | + debug_stream << std::left << std::setw(cw) << "Volume:" << state.volume() |
| 36 | + << std::endl; |
| 37 | + |
| 38 | + // Navigation direction |
| 39 | + debug_stream << std::setw(cw) << "direction:"; |
| 40 | + switch (state.direction()) { |
| 41 | + using enum direction; |
| 42 | + case e_backward: |
| 43 | + debug_stream << "backward"; |
| 44 | + break; |
| 45 | + case e_forward: |
| 46 | + debug_stream << "forward"; |
| 47 | + break; |
| 48 | + default: |
| 49 | + break; |
| 50 | + } |
| 51 | + debug_stream << std::endl; |
| 52 | + |
| 53 | + // Navigation status |
| 54 | + debug_stream << std::setw(cw) << "status:"; |
| 55 | + switch (state.status()) { |
| 56 | + using enum status; |
| 57 | + case e_abort: |
| 58 | + debug_stream << "abort"; |
| 59 | + break; |
| 60 | + case e_on_target: |
| 61 | + debug_stream << "on_target"; |
| 62 | + break; |
| 63 | + case e_unknown: |
| 64 | + debug_stream << "unknowm"; |
| 65 | + break; |
| 66 | + case e_towards_object: |
| 67 | + debug_stream << "towards_object"; |
| 68 | + break; |
| 69 | + case e_on_module: |
| 70 | + debug_stream << "on_object"; |
| 71 | + break; |
| 72 | + case e_on_portal: |
| 73 | + debug_stream << "on_portal"; |
| 74 | + break; |
| 75 | + default: |
| 76 | + break; |
| 77 | + } |
| 78 | + debug_stream << std::endl; |
| 79 | + |
| 80 | + // Navigation trust level |
| 81 | + debug_stream << std::setw(cw) << "trust:"; |
| 82 | + switch (state.trust_level()) { |
| 83 | + using enum trust_level; |
| 84 | + case e_no_trust: |
| 85 | + debug_stream << "no_trust"; |
| 86 | + break; |
| 87 | + case e_fair: |
| 88 | + debug_stream << "fair_trust"; |
| 89 | + break; |
| 90 | + case e_high: |
| 91 | + debug_stream << "high_trust"; |
| 92 | + break; |
| 93 | + case e_full: |
| 94 | + debug_stream << "full_trust"; |
| 95 | + break; |
| 96 | + default: |
| 97 | + break; |
| 98 | + } |
| 99 | + debug_stream << std::endl; |
| 100 | + |
| 101 | + // Number of reachable candidates |
| 102 | + debug_stream << std::setw(cw) << "No. reachable:" << state.n_candidates() |
| 103 | + << std::endl; |
| 104 | + |
| 105 | + // Current surface |
| 106 | + debug_stream << std::setw(cw) << "current object:"; |
| 107 | + if (state.is_on_surface()) { |
| 108 | + // If "exit" is called twice, the state has been cleared |
| 109 | + debug_stream << state.barcode() << std::endl; |
| 110 | + } else if (state.status() == status::e_on_target) { |
| 111 | + debug_stream << "exited" << std::endl; |
| 112 | + } else { |
| 113 | + debug_stream << "undefined" << std::endl; |
| 114 | + } |
| 115 | + |
| 116 | + // Next surface |
| 117 | + if (!state.candidates().empty()) { |
| 118 | + debug_stream << std::setw(cw) << "next object:"; |
| 119 | + if (state.n_candidates() == 0u) { |
| 120 | + debug_stream << "exhausted" << std::endl; |
| 121 | + } else { |
| 122 | + debug_stream << state.next_surface().barcode() << std::endl; |
| 123 | + } |
| 124 | + } |
| 125 | + |
| 126 | + // Distance to next |
| 127 | + debug_stream << std::setw(cw) << "distance to next:"; |
| 128 | + if (!state.is_exhausted() && state.is_on_surface()) { |
| 129 | + debug_stream << "on obj (within tol)" << std::endl; |
| 130 | + } else if (state.is_exhausted()) { |
| 131 | + debug_stream << "no target" << std::endl; |
| 132 | + } else { |
| 133 | + debug_stream << state() << std::endl; |
| 134 | + } |
| 135 | + |
| 136 | + return debug_stream.str(); |
| 137 | +} |
| 138 | + |
| 139 | +/// Print candidate and cofiguration information of a navigation state |
| 140 | +/// |
| 141 | +/// @param state the state object of the navigation stream |
| 142 | +/// @param cfg the navigation confuration object |
| 143 | +/// @param track_pos the current track position |
| 144 | +/// @param track_dir the current track direction |
| 145 | +template <typename state_type, concepts::point3D point3_t, |
| 146 | + concepts::vector3D vector3_t> |
| 147 | +DETRAY_HOST inline std::string print_candidates(const state_type &state, |
| 148 | + const navigation::config &cfg, |
| 149 | + const point3_t &track_pos, |
| 150 | + const vector3_t &track_dir) { |
| 151 | + |
| 152 | + using detector_t = typename state_type::detector_type; |
| 153 | + using geo_ctx_t = typename detector_t::geometry_context; |
| 154 | + using scalar_t = typename detector_t::scalar_type; |
| 155 | + |
| 156 | + // Gathers navigation information accross navigator update calls |
| 157 | + std::stringstream debug_stream{}; |
| 158 | + // Column width in output |
| 159 | + constexpr int cw{20}; |
| 160 | + |
| 161 | + debug_stream << std::left << std::setw(cw) << "Overstep tol.:" |
| 162 | + << cfg.overstep_tolerance / detray::unit<scalar_t>::mm << " mm" |
| 163 | + << std::endl; |
| 164 | + |
| 165 | + debug_stream << std::setw(cw) << "Track:" |
| 166 | + << "pos: [r = " << vector::perp(track_pos) |
| 167 | + << ", z = " << track_pos[2] << "]," << std::endl; |
| 168 | + |
| 169 | + debug_stream << std::setw(cw) << " " |
| 170 | + << "dir: [" << track_dir[0] << ", " << track_dir[1] << ", " |
| 171 | + << track_dir[2] << "]" << std::endl; |
| 172 | + |
| 173 | + debug_stream << "Surface candidates: " << std::endl; |
| 174 | + |
| 175 | + for (const auto &sf_cand : state) { |
| 176 | + |
| 177 | + debug_stream << std::left << std::setw(6) << "-> " << sf_cand; |
| 178 | + |
| 179 | + assert(!sf_cand.sf_desc.barcode().is_invalid()); |
| 180 | + |
| 181 | + // Use additional debug information that was gathered on the cand. |
| 182 | + if constexpr (state_type::value_type::is_debug()) { |
| 183 | + const auto &local = sf_cand.local; |
| 184 | + if (!sf_cand.sf_desc.barcode().is_invalid()) { |
| 185 | + point3_t pos = |
| 186 | + geometry::surface{state.detector(), sf_cand.sf_desc} |
| 187 | + .local_to_global(geo_ctx_t{}, local, track_dir); |
| 188 | + debug_stream << " glob: [r = " << vector::perp(pos) |
| 189 | + << ", z = " << pos[2] << "]" << std::endl; |
| 190 | + } |
| 191 | + } |
| 192 | + } |
| 193 | + |
| 194 | + return debug_stream.str(); |
| 195 | +} |
| 196 | + |
| 197 | +} // namespace detray::navigation |
0 commit comments