ACTS
Experiment-independent tracking
Loading...
Searching...
No Matches
random_scatterer.hpp
1// This file is part of the ACTS project.
2//
3// Copyright (C) 2016 CERN for the benefit of the ACTS project
4//
5// This Source Code Form is subject to the terms of the Mozilla Public
6// License, v. 2.0. If a copy of the MPL was not distributed with this
7// file, You can obtain one at https://mozilla.org/MPL/2.0/.
8
9#pragma once
10
11// Project include(s).
12#include "detray/definitions/algebra.hpp"
13#include "detray/definitions/detail/qualifiers.hpp"
14#include "detray/definitions/pdg_particle.hpp"
15#include "detray/definitions/track_parametrization.hpp"
16#include "detray/definitions/units.hpp"
17#include "detray/material/concepts.hpp"
18#include "detray/material/detail/material_accessor.hpp"
19#include "detray/material/interaction.hpp"
20#include "detray/propagator/actors/parameter_updater.hpp"
21#include "detray/propagator/base_actor.hpp"
22#include "detray/tracks/bound_track_parameters.hpp"
23#include "detray/utils/axis_rotation.hpp"
24#include "detray/utils/geometry_utils.hpp"
25#include "detray/utils/unit_vectors.hpp"
26
27// Detray test include(s)
28#include "detray/test/utils/landau_distribution.hpp"
29#include "detray/test/utils/scattering_helper.hpp"
30
31// System include(s).
32#include <limits>
33#include <random>
34
35namespace detray::actor {
36
38template <concepts::algebra algebra_t>
48
50 struct state {
52 std::random_device rd{};
54 std::mt19937_64 generator{rd()};
55
58
61
64
65 // Simulation setup
67 bool do_energy_loss = true;
70
74 explicit state(const uint_fast64_t sd = 0u) { generator.seed(sd); }
75
78 void set_seed(const uint_fast64_t sd) { generator.seed(sd); }
79 };
80
82 struct kernel {
92 template <typename mat_group_t, typename index_t>
93 DETRAY_HOST_DEVICE inline bool operator()(
94 [[maybe_unused]] const mat_group_t& material_group,
95 [[maybe_unused]] const index_t& mat_index,
96 [[maybe_unused]] typename random_scatterer::state& s,
97 [[maybe_unused]] const pdg_particle<scalar_type>& ptc,
98 [[maybe_unused]] const bound_track_parameters<algebra_t>& bound_params,
99 [[maybe_unused]] const scalar_type cos_inc_angle,
100 [[maybe_unused]] const scalar_type approach) const {
101 using material_t = typename mat_group_t::value_type;
102
104 const scalar_type qop = bound_params.qop();
105
106 const auto mat = detail::material_accessor::get(
107 material_group, mat_index, bound_params.bound_local());
108
109 // return early in case of zero thickness
110 if (mat.thickness() <= std::numeric_limits<scalar_type>::epsilon()) {
111 return false;
112 }
113
114 const scalar_type path_segment{
115 mat.path_segment(cos_inc_angle, approach)};
116
117 const detail::relativistic_quantities rq(ptc, qop);
118
119 // Energy Loss
120 if (s.do_energy_loss) {
122 path_segment, mat.get_material(), ptc, rq);
123
125 path_segment, mat.get_material(), ptc, rq);
126 }
127
128 // Scattering angle
129 if (s.do_multiple_scattering) {
130 // @todo: use momentum before or after energy loss in
131 // backward mode?
132 s.projected_scattering_angle =
134 mat.path_segment_in_X0(cos_inc_angle, approach), ptc, rq);
135 }
136
137 return true;
138 } else {
139 // For non-pointwise material interactions, do nothing
140 return false;
141 }
142 }
143 };
144
149
150 template <typename propagator_state_t>
151 DETRAY_HOST inline void operator()(
152 state& simulator_state, propagator_state_t& prop_state,
154 // @Todo: Make context part of propagation state
155 using detector_type = typename propagator_state_t::detector_type;
156 using geo_context_type = typename detector_type::geometry_context;
157
158 auto& navigation = prop_state.navigation();
159
160 if (!navigation.encountered_sf_material()) {
161 return;
162 }
163
164 auto& stepping = prop_state.stepping();
165 const auto& ptc = stepping.particle_hypothesis();
166 auto& bound_params = res.destination_params();
167 const auto sf = navigation.current_surface();
168 const scalar_type cos_inc_angle{cos_angle(geo_context_type{}, sf,
169 bound_params.dir(),
170 bound_params.bound_local())};
171
172 const bool success = sf.template visit_material<kernel>(
173 simulator_state, ptc, bound_params, cos_inc_angle,
174 bound_params.bound_local()[0]);
175
176 if (success) {
177 // Get the new momentum
178 const auto new_mom = attenuate(
179 simulator_state.e_loss_mpv, simulator_state.e_loss_sigma, ptc.mass(),
180 bound_params.p(ptc.charge()), simulator_state.generator);
181
182 // Update Qop
183 bound_params.set_qop(ptc.charge() / new_mom);
184
185 // Get the new direction from random scattering
186 const auto new_dir = scatter(bound_params.dir(),
187 simulator_state.projected_scattering_angle,
188 simulator_state.generator);
189
190 // Update Phi and Theta
191 bound_params.set_phi(vector::phi(new_dir));
192 bound_params.set_theta(vector::theta(new_dir));
193 // Signal parameter update
194 res.status = actor::status::e_success;
195
196 // Flag renavigation of the current candidate
197 prop_state.navigation().set_high_trust();
198 }
199 }
200
208 template <typename generator_t>
209 DETRAY_HOST inline scalar_type attenuate(const scalar_type mpv,
210 const scalar_type sigma,
211 const scalar_type m0,
212 const scalar_type p0,
213 generator_t& generator) const {
214 // Get the random energy loss
215 // @todo tune the scale parameters (e_loss_mpv and e_loss_sigma)
216 const auto e_loss =
217 landau_distribution<scalar_type>{}(generator, mpv, sigma);
218
219 // E = sqrt(m^2 + p^2)
220 const auto energy = math::sqrt(m0 * m0 + p0 * p0);
221 const auto new_energy = energy - e_loss;
222
223 auto p2 = new_energy * new_energy - m0 * m0;
224
225 // To avoid divergence
226 if (p2 < 0) {
228 }
229
230 // p = sqrt(E^2 - m^2)
231 return math::sqrt(p2);
232 }
233
240 template <typename generator_t>
241 DETRAY_HOST inline vector3_type scatter(
242 const vector3_type& dir, const scalar_type projected_scattering_angle,
243 generator_t& generator) const {
244 const auto scattering_angle =
245 constant<scalar_type>::sqrt2 * projected_scattering_angle;
246
247 return scattering_helper<algebra_t>()(dir, scattering_angle, generator);
248 }
249};
250
251} // namespace detray::actor
Landau distribution based on CERNLIB G110 Computer Physics Communications 31(1984) 97—111).
Definition landau_distribution.hpp:25
Material that can used for surfaces.
Definition concepts.hpp:111
get_scalar_t< A, T > dscalar
Scalar type for algebra A and value type T.
Definition algebra.hpp:64
constexpr dscalar< typename detector_t::algebra_type > cos_angle(const typename detector_t::geometry_context &ctx, geometry::surface< detector_t > sf, const dvector3D< typename detector_t::algebra_type > &dir, const point_t &loc)
Helper to get the incidence angle of a direction vector on a surface.
Definition geometry_utils.hpp:29
get_vector3D_t< A, T > dvector3D
Three-dimensional vector type for algebra A and value type T.
Definition algebra.hpp:80
get_transform3D_t< A, T > dtransform3D
Three-dimensional transform type for algebra A and value type T.
Definition algebra.hpp:84
Result of the param. transporter: bound track parameters at dest. sf.
Definition parameter_updater.hpp:210
constexpr const bound_track_parameters< algebra_t > & destination_params() const
Definition parameter_updater.hpp:236
Material store visitor.
Definition random_scatterer.hpp:82
bool operator()(const mat_group_t &material_group, const index_t &mat_index, typename random_scatterer::state &s, const pdg_particle< scalar_type > &ptc, const bound_track_parameters< algebra_t > &bound_params, const scalar_type cos_inc_angle, const scalar_type approach) const
Calculate material interaction quantities for the current surface.
Definition random_scatterer.hpp:93
Per-propagation state for random scattering and energy loss.
Definition random_scatterer.hpp:50
bool do_energy_loss
Whether to apply energy loss.
Definition random_scatterer.hpp:67
scalar_type e_loss_sigma
energy loss sigma
Definition random_scatterer.hpp:60
std::random_device rd
Random device used to initialize the generator.
Definition random_scatterer.hpp:52
scalar_type projected_scattering_angle
projected scattering angle
Definition random_scatterer.hpp:63
std::mt19937_64 generator
Random number generator for this actor state.
Definition random_scatterer.hpp:54
scalar_type e_loss_mpv
most probable energy loss
Definition random_scatterer.hpp:57
void set_seed(const uint_fast64_t sd)
Set the random number generator seed.
Definition random_scatterer.hpp:78
state(const uint_fast64_t sd=0u)
Constructor with seed.
Definition random_scatterer.hpp:74
bool do_multiple_scattering
Whether to apply multiple scattering.
Definition random_scatterer.hpp:69
Actor that applies random energy loss and multiple scattering in material.
Definition random_scatterer.hpp:39
dscalar< algebra_t > scalar_type
Scalar type used for the simulation quantities.
Definition random_scatterer.hpp:41
dvector3D< algebra_t > vector3_type
3D vector type used for directions.
Definition random_scatterer.hpp:43
interaction< scalar_type > interaction_type
Material interaction calculator type.
Definition random_scatterer.hpp:47
scalar_type attenuate(const scalar_type mpv, const scalar_type sigma, const scalar_type m0, const scalar_type p0, generator_t &generator) const
Get the new momentum from the landau distribution.
Definition random_scatterer.hpp:209
void operator()(state &simulator_state, propagator_state_t &prop_state, parameter_transporter_result< algebra_t > &res) const
Apply the sampled material effects to the transported parameters.
Definition random_scatterer.hpp:151
dtransform3D< algebra_t > transform3_type
3D transform type.
Definition random_scatterer.hpp:45
vector3_type scatter(const vector3_type &dir, const scalar_type projected_scattering_angle, generator_t &generator) const
Scatter the direction with projected scattering angle.
Definition random_scatterer.hpp:241
actor::status status
Navigation status reported by the principal actor.
Definition base_actor.hpp:36
Base class actor implementation.
Definition base_actor.hpp:20
Combine the bound track parameter vector with the covariance and associated surface.
Definition bound_track_parameters.hpp:297
static constexpr scalar_t sqrt2
√2
Definition units.hpp:149
Computes energy loss and multiple scattering in detector material.
Definition interaction.hpp:23
scalar_type compute_energy_loss_landau(const scalar_type path_segment, const material< scalar_type > &mat, const pdg_particle< scalar_type > &, const relativistic_quantities &rq) const
Compute the most-probable energy loss using the Landau approximation.
Definition interaction.hpp:222
scalar_type compute_multiple_scattering_theta0(const scalar_type xOverX0, const pdg_particle< scalar_type > &ptc, const relativistic_quantities &rq) const
Estimate the projected multiple-scattering angle for a material thickness.
Definition interaction.hpp:300
scalar_type compute_energy_loss_landau_sigma(const scalar_type path_segment, const material< scalar_type > &mat, const pdg_particle< scalar_type > &ptc, const relativistic_quantities &rq) const
Convert the Landau width to a Gaussian-equivalent energy-loss sigma.
Definition interaction.hpp:260
Particle hypothesis identified by PDG number, mass, and electric charge.
Definition pdg_particle.hpp:24
Generates a random direction after multiple scattering.
Definition scattering_helper.hpp:25
static constexpr scalar_t eV
Energy, native unit GeV.
Definition units.hpp:75