File indexing completed on 2026-05-27 07:24:17
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011
0012 #include "detray/propagator/propagation_config.hpp"
0013
0014
0015 #include "detray/options/options_handling.hpp"
0016
0017
0018 #include "detray/options/boost_program_options.hpp"
0019
0020
0021 #include <stdexcept>
0022
0023 namespace detray::options {
0024
0025
0026 template <>
0027 void add_options<detray::navigation::config>(
0028 boost::program_options::options_description &desc,
0029 const detray::navigation::config &cfg) {
0030 desc.add_options()(
0031 "search_window",
0032 boost::program_options::value<std::vector<dindex>>()->multitoken(),
0033 "Search window size for the grid")(
0034 "min_mask_tolerance",
0035 boost::program_options::value<float>()->default_value(
0036 cfg.intersection.min_mask_tolerance / unit<float>::mm),
0037 "Minimum mask tolerance [mm]")(
0038 "max_mask_tolerance",
0039 boost::program_options::value<float>()->default_value(
0040 cfg.intersection.max_mask_tolerance / unit<float>::mm),
0041 "Maximum mask tolerance [mm]")(
0042 "mask_tolerance_scalor",
0043 boost::program_options::value<float>()->default_value(
0044 cfg.intersection.mask_tolerance_scalor),
0045 "Mask tolerance scale factor")(
0046 "overstep_tolerance",
0047 boost::program_options::value<float>()->default_value(
0048 cfg.intersection.overstep_tolerance / unit<float>::um),
0049 "Overstepping tolerance [um] NOTE: Must be negative!")(
0050 "path_tolerance",
0051 boost::program_options::value<float>()->default_value(
0052 cfg.intersection.path_tolerance / unit<float>::um),
0053 "Tol. to decide when a track is on surface [um]")(
0054 "estimate_scattering_noise",
0055 "Open the navigation surface tolerance according to an estimation of "
0056 "the noise due to multiple scattering")(
0057 "n_scattering_stddev",
0058 boost::program_options::value<int>()->default_value(
0059 cfg.n_scattering_stddev),
0060 "Number of standard deviations of estimated error to use for "
0061 "scattering noise")("accumulated_error",
0062 boost::program_options::value<float>()->default_value(
0063 cfg.accumulated_error),
0064 "Estimation of accumulated positional error [%]");
0065 }
0066
0067
0068 template <>
0069 void add_options<detray::stepping::config>(
0070 boost::program_options::options_description &desc,
0071 const detray::stepping::config &cfg) {
0072 desc.add_options()("minimum_stepsize",
0073 boost::program_options::value<float>()->default_value(
0074 cfg.min_stepsize / unit<float>::mm),
0075 "Minimum step size [mm]")(
0076 "step_contraint",
0077 boost::program_options::value<float>()->default_value(
0078 cfg.step_constraint / unit<float>::mm),
0079 "Maximum step size [mm]")(
0080 "rk-tolerance",
0081 boost::program_options::value<float>()->default_value(cfg.rk_error_tol /
0082 unit<float>::mm),
0083 "The Runge-Kutta integration error tolerance [mm]")(
0084 "path_limit",
0085 boost::program_options::value<float>()->default_value(cfg.path_limit /
0086 unit<float>::m),
0087 "Maximum path length for a track [m]")("mean_energy_loss",
0088 "Use Bethe energy loss")(
0089 "covariance_transport", "Run the covariance transport")(
0090 "eloss_gradient", "Use energy loss gradient in Jacobian transport")(
0091 "bfield_gradient", "Use B-field gradient in Jacobian transport");
0092 }
0093
0094
0095 template <>
0096 void add_options<detray::propagation::config>(
0097 boost::program_options::options_description &desc,
0098 const detray::propagation::config &cfg) {
0099 add_options(desc, cfg.navigation);
0100 add_options(desc, cfg.stepping);
0101 }
0102
0103
0104 template <>
0105 void configure_options<detray::navigation::config>(
0106 const boost::program_options::variables_map &vm,
0107 detray::navigation::config &cfg) {
0108
0109 if (vm.count("search_window") != 0u) {
0110 const auto window = vm["search_window"].as<std::vector<dindex>>();
0111 if (window.size() == 2u) {
0112 cfg.search_window = {window[0], window[1]};
0113 } else {
0114 throw std::invalid_argument(
0115 "Incorrect surface grid search window. Please provide two "
0116 "integer distances.");
0117 }
0118 }
0119
0120 if (!vm["min_mask_tolerance"].defaulted()) {
0121 const float mask_tol{vm["min_mask_tolerance"].as<float>()};
0122 assert(mask_tol >= 0.f);
0123
0124 cfg.intersection.min_mask_tolerance = mask_tol * unit<float>::mm;
0125 }
0126 if (!vm["max_mask_tolerance"].defaulted()) {
0127 const float mask_tol{vm["max_mask_tolerance"].as<float>()};
0128 assert(mask_tol >= 0.f);
0129
0130 cfg.intersection.max_mask_tolerance = mask_tol * unit<float>::mm;
0131 }
0132 if (!vm["mask_tolerance_scalor"].defaulted()) {
0133 const float mask_tol_scalor{vm["mask_tolerance_scalor"].as<float>()};
0134 assert(mask_tol_scalor >= 0.f);
0135
0136 cfg.intersection.mask_tolerance_scalor = mask_tol_scalor;
0137 }
0138 if (!vm["overstep_tolerance"].defaulted()) {
0139 const float overstep_tol{vm["overstep_tolerance"].as<float>()};
0140 assert(overstep_tol <= 0.f);
0141
0142 cfg.intersection.overstep_tolerance = overstep_tol * unit<float>::um;
0143 }
0144 if (!vm["path_tolerance"].defaulted()) {
0145 const float path_tol{vm["path_tolerance"].as<float>()};
0146 assert(path_tol >= 0.f);
0147
0148 cfg.intersection.path_tolerance = path_tol * unit<float>::um;
0149 }
0150 cfg.estimate_scattering_noise = false;
0151 if (vm.count("estimate_scattering_noise") != 0u) {
0152 cfg.estimate_scattering_noise = true;
0153
0154 if (!vm["n_scattering_stddev"].defaulted()) {
0155 const int n_stddev{vm["n_scattering_stddev"].as<int>()};
0156 assert(n_stddev >= 0);
0157
0158 cfg.n_scattering_stddev = n_stddev;
0159 }
0160
0161 if (!vm["accumulated_error"].defaulted()) {
0162 const float err{vm["accumulated_error"].as<float>()};
0163 assert(err >= 0.f);
0164
0165 cfg.accumulated_error = err;
0166 }
0167 } else {
0168 if (!vm["n_scattering_stddev"].defaulted()) {
0169 throw std::invalid_argument(
0170 "Option 'n_scattering_stddev' cannot not be configured unless "
0171 "'estimate_scattering_noise' is activated");
0172 }
0173 if (!vm["accumulated_error"].defaulted()) {
0174 throw std::invalid_argument(
0175 "Option 'accumulated_error' cannot not be configured unless "
0176 "'estimate_scattering_noise' is activated");
0177 }
0178 }
0179 }
0180
0181
0182 template <>
0183 void configure_options<detray::stepping::config>(
0184 const boost::program_options::variables_map &vm,
0185 detray::stepping::config &cfg) {
0186
0187 if (!vm["minimum_stepsize"].defaulted()) {
0188 const float min_step{vm["minimum_stepsize"].as<float>()};
0189 assert(min_step >= 0.f);
0190
0191 cfg.min_stepsize = min_step * unit<float>::mm;
0192 }
0193 if (!vm["step_contraint"].defaulted()) {
0194 const float constraint{vm["step_contraint"].as<float>()};
0195 assert(constraint >= 0.f);
0196
0197 cfg.step_constraint = constraint * unit<float>::mm;
0198 }
0199 if (!vm["rk-tolerance"].defaulted()) {
0200 const float err_tol{vm["rk-tolerance"].as<float>()};
0201 assert(err_tol >= 0.f);
0202
0203 cfg.rk_error_tol = err_tol * unit<float>::mm;
0204 }
0205 if (!vm["path_limit"].defaulted()) {
0206 const float path_limit{vm["path_limit"].as<float>()};
0207 assert(path_limit > 0.f);
0208
0209 cfg.path_limit = path_limit * unit<float>::m;
0210 }
0211 cfg.do_covariance_transport = false;
0212 if (vm.count("covariance_transport") != 0u) {
0213 cfg.do_covariance_transport = true;
0214 }
0215 if (vm.count("mean_eloss") != 0u) {
0216 cfg.use_mean_loss = true;
0217 }
0218 if (vm.count("eloss_gradient") != 0u) {
0219 cfg.use_eloss_gradient = true;
0220 }
0221 if (vm.count("bfield_gradient") != 0u) {
0222 cfg.use_field_gradient = true;
0223 }
0224 }
0225
0226
0227 template <>
0228 void configure_options<detray::propagation::config>(
0229 const boost::program_options::variables_map &vm,
0230 detray::propagation::config &cfg) {
0231 configure_options(vm, cfg.navigation);
0232 configure_options(vm, cfg.stepping);
0233 }
0234
0235 }