ACTS
Experiment-independent tracking
Loading...
Searching...
No Matches
pointwise_material_interactor.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/actor.hpp"
13#include "detray/definitions/algebra.hpp"
14#include "detray/definitions/detail/qualifiers.hpp"
15#include "detray/definitions/track_parametrization.hpp"
16#include "detray/material/concepts.hpp"
17#include "detray/material/detail/material_accessor.hpp"
18#include "detray/material/interaction.hpp"
19#include "detray/propagator/actors/parameter_updater.hpp"
20#include "detray/propagator/base_actor.hpp"
21#include "detray/tracks/bound_track_parameters.hpp"
22#include "detray/utils/geometry_utils.hpp"
23#include "detray/utils/logging.hpp"
24
25// System include(s)
26#include <limits>
27
28namespace detray::actor {
29
32template <concepts::algebra algebra_t>
35 using algebra_type = algebra_t;
48
50 struct state {
57
61 bool do_energy_loss = true;
64
66 DETRAY_HOST_DEVICE
67 void reset() {
68 e_loss = 0.f;
70 sigma_qop = 0.f;
71 }
72 };
73
75 struct kernel {
78
90 template <typename mat_group_t, typename index_t>
91 DETRAY_HOST_DEVICE inline bool operator()(
92 [[maybe_unused]] const mat_group_t &material_group,
93 [[maybe_unused]] const index_t &mat_index, [[maybe_unused]] state &s,
94 [[maybe_unused]] const pdg_particle<scalar_type> &ptc,
95 [[maybe_unused]] const bound_track_parameters<algebra_t> &bound_params,
96 [[maybe_unused]] const scalar_type cos_inc_angle,
97 [[maybe_unused]] const scalar_type approach) const {
98 using material_t = typename mat_group_t::value_type;
99
100 // Filter material types for which to do "pointwise" interactions
102 const auto mat = detail::material_accessor::get(
103 material_group, mat_index, bound_params.bound_local());
104
105 // Return early in case of zero thickness
106 if (mat.thickness() <= std::numeric_limits<scalar_type>::epsilon()) {
107 DETRAY_DEBUG_HOST_DEVICE("Zero thickness material: skipping");
108 return false;
109 }
110
111 DETRAY_VERBOSE_HOST_DEVICE(
112 "-> Material path per X0: %f",
113 mat.path_segment_in_X0(cos_inc_angle, approach));
114
115 const scalar_type qop = bound_params.qop();
116
117 // Set to exactly zero if the particle is not charged
118 if (qop == 0.f) {
119 // TODO: Implement interactions for neutral particles here
120
121 DETRAY_DEBUG_HOST_DEVICE(
122 "Currently no interactions for neutral particles "
123 "implemented: skipping");
124
125 return false;
126 }
127
128 const scalar_type path_segment{
129 mat.path_segment(cos_inc_angle, approach)};
130
131 detail::relativistic_quantities rq(ptc, qop);
132
133 // Energy Loss
134 if (s.do_energy_loss) {
136 path_segment, mat.get_material(), ptc, rq);
137 }
138
139 // @todo: include the radiative loss (Bremsstrahlung)
140 if (s.do_energy_loss && s.do_covariance_transport) {
141 s.sigma_qop =
143 path_segment, mat.get_material(), ptc, rq);
144 }
145
146 // Covariance update
147 if (s.do_multiple_scattering) {
148 // @todo: use momentum before or after energy loss in
149 // backward mode?
150 s.projected_scattering_angle =
152 mat.path_segment_in_X0(cos_inc_angle, approach), ptc, rq);
153 }
154
155 return true;
156
157 } else {
158 // For non-pointwise material interactions, do nothing
159 return false;
160 }
161 }
162 };
163
169 template <typename propagator_state_t>
170 DETRAY_HOST_DEVICE inline void operator()(
171 state &interactor_state, propagator_state_t &prop_state,
173 const auto &navigation = prop_state.navigation();
174
175 // Do material interaction when the track is on material surface
176 if (!navigation.encountered_sf_material()) {
177 return;
178 }
179
180 DETRAY_VERBOSE_HOST_DEVICE("Actor: Resolve material effects:");
181
182 interactor_state.reset();
183
184 const auto &stepping = prop_state.stepping();
185
186 const bool success = this->update(
187 prop_state.context(), stepping.particle_hypothesis(),
188 res.destination_params(), interactor_state,
189 static_cast<int>(navigation.direction()), navigation.current_surface());
190
191 res.status = success ? actor::status::e_success : res.status;
192 }
193
203 template <typename context_t, typename surface_t>
204 DETRAY_HOST_DEVICE inline bool update(
205 const context_t gctx, const pdg_particle<scalar_type> &ptc,
206 bound_track_parameters<algebra_t> &bound_params, state &interactor_state,
207 const int nav_dir, const surface_t &sf) const {
208 // Closest approach of the track to a line surface. Otherwise this is
209 // ignored.
210 const auto approach{bound_params[e_bound_loc0]};
211 const scalar_type cos_inc_angle{
212 cos_angle(gctx, sf, bound_params.dir(), bound_params.bound_local())};
213
214 const bool success = sf.template visit_material<kernel>(
215 interactor_state, ptc, bound_params, cos_inc_angle, approach);
216
217 if (success) {
218 auto &covariance = bound_params.covariance();
219
220 if (interactor_state.do_energy_loss) {
221 update_qop(bound_params, ptc, interactor_state.e_loss, nav_dir);
222
223 if (interactor_state.do_covariance_transport) {
224 update_qop_variance(covariance, interactor_state.sigma_qop);
225 }
226 }
227
228 if (interactor_state.do_covariance_transport) {
229 update_angle_variance(covariance, bound_params.dir(),
230 interactor_state.projected_scattering_angle);
231 }
232 }
233
234 assert(!bound_params.is_invalid());
235
236 return success;
237 }
238
245 DETRAY_HOST_DEVICE
247 const pdg_particle<scalar_type> &ptc,
248 const scalar_type e_loss, const int sign) const {
249 const scalar_type m = ptc.mass();
250 const scalar_type q = ptc.charge();
251 const scalar_type p = vector.p(q);
252
253 // Get new Energy
254 const scalar_type next_e{
255 math::sqrt(m * m + p * p) -
256 math::copysign(e_loss, static_cast<scalar_type>(sign))};
257
258 DETRAY_DEBUG_HOST_DEVICE("-> new energy: %f GeV", next_e);
259
260 // Put particle at rest if energy loss is too large
261 const scalar_type next_p{(m < next_e) ? math::sqrt(next_e * next_e - m * m)
262 : 0.f};
263
264 // For neutral particles, qoverp = 1/p
265 constexpr auto inv{detail::invalid_value<scalar_type>()};
266 const scalar_type next_qop{(q != 0.f) ? q / next_p : 1.f / next_p};
267 vector.set_qop((next_p == 0.f) ? inv : next_qop);
268
269 DETRAY_DEBUG_HOST_DEVICE("-> new abs. momentum: %f GeV", next_p);
270
271 DETRAY_DEBUG_HOST_DEVICE("-> Update qop: before: %f e/GeV, after: %f e/GeV",
272 q / p, vector.qop());
273 }
274
279 DETRAY_HOST_DEVICE inline void update_qop_variance(
280 bound_matrix_type &covariance, const scalar_type sigma_qop) const {
281 const scalar_type variance_qop{sigma_qop * sigma_qop};
282
283 DETRAY_DEBUG_HOST_DEVICE("-> qop variance: %f (e/GeV)^2", variance_qop);
284
285 getter::element(covariance, e_bound_qoverp, e_bound_qoverp) += variance_qop;
286
287 DETRAY_DEBUG_HOST_DEVICE(
288 "-> Update qop variance: before: %f (e/GeV)^2, after: %f "
289 "(e/GeV)^2",
290 getter::element(covariance, e_bound_qoverp, e_bound_qoverp) -
291 variance_qop,
292 getter::element(covariance, e_bound_qoverp, e_bound_qoverp));
293 }
294
300 DETRAY_HOST_DEVICE inline void update_angle_variance(
301 bound_matrix_type &covariance, const vector3_type &dir,
302 const scalar_type projected_scattering_angle) const {
303 const scalar_type var_scattering_angle{projected_scattering_angle *
304 projected_scattering_angle};
305
306 DETRAY_DEBUG_HOST_DEVICE("-> Scattering angle variance: %f rad^2",
307 var_scattering_angle);
308
309 constexpr auto inv{detail::invalid_value<scalar_type>()};
310
311 DETRAY_DEBUG_HOST_DEVICE("-> Update phi variance:");
312 DETRAY_DEBUG_HOST_DEVICE(
313 "--> before: %f rad^2",
314 getter::element(covariance, e_bound_phi, e_bound_phi));
315
316 getter::element(covariance, e_bound_phi, e_bound_phi) +=
317 (dir[2] == 1.f) ? inv : var_scattering_angle / (1.f - dir[2] * dir[2]);
318
319 DETRAY_DEBUG_HOST_DEVICE(
320 "--> after: %f rad^2",
321 getter::element(covariance, e_bound_phi, e_bound_phi));
322
323 DETRAY_DEBUG_HOST_DEVICE("-> Update theta variance:");
324 DETRAY_DEBUG_HOST_DEVICE(
325 "--> before: %f rad^2",
326 getter::element(covariance, e_bound_theta, e_bound_theta));
327
328 getter::element(covariance, e_bound_theta, e_bound_theta) +=
329 var_scattering_angle;
330
331 DETRAY_DEBUG_HOST_DEVICE(
332 "--> after: %f rad^2",
333 getter::element(covariance, e_bound_theta, e_bound_theta));
334 }
335};
336
337} // namespace detray::actor
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
dmatrix< algebra_t, e_bound_size, e_bound_size > bound_matrix
Covariance matrix type for bound track parametrization.
Definition track_parametrization.hpp:81
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 pointwise_material_interactor.hpp:75
typename pointwise_material_interactor::state state
State type shared with the interactor.
Definition pointwise_material_interactor.hpp:77
bool operator()(const mat_group_t &material_group, const index_t &mat_index, 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
Evaluate pointwise effects for a material group entry.
Definition pointwise_material_interactor.hpp:91
Per-surface material effects and their application settings.
Definition pointwise_material_interactor.hpp:50
scalar_type projected_scattering_angle
Evaluated projected scattering angle.
Definition pointwise_material_interactor.hpp:54
scalar_type sigma_qop
Evaluated sigma of qoverp.
Definition pointwise_material_interactor.hpp:56
scalar_type e_loss
Evaluated energy loss.
Definition pointwise_material_interactor.hpp:52
bool do_covariance_transport
Whether material contributions update the covariance.
Definition pointwise_material_interactor.hpp:59
void reset()
Clear accumulated material effects before processing a surface.
Definition pointwise_material_interactor.hpp:67
bool do_multiple_scattering
Whether multiple scattering is applied.
Definition pointwise_material_interactor.hpp:63
bool do_energy_loss
Whether mean energy loss is applied.
Definition pointwise_material_interactor.hpp:61
Apply energy-loss and multiple-scattering effects at material surfaces.
Definition pointwise_material_interactor.hpp:33
void update_angle_variance(bound_matrix_type &covariance, const vector3_type &dir, const scalar_type projected_scattering_angle) const
Update the variance of phi and theta of bound track parameter.
Definition pointwise_material_interactor.hpp:300
bound_matrix< algebra_t > bound_matrix_type
Bound covariance matrix type.
Definition pointwise_material_interactor.hpp:47
dscalar< algebra_t > scalar_type
Scalar type used for material calculations.
Definition pointwise_material_interactor.hpp:37
void operator()(state &interactor_state, propagator_state_t &prop_state, parameter_transporter_result< algebra_t > &res) const
Apply material effects after parameter transport reaches a surface.
Definition pointwise_material_interactor.hpp:170
bool update(const context_t gctx, const pdg_particle< scalar_type > &ptc, bound_track_parameters< algebra_t > &bound_params, state &interactor_state, const int nav_dir, const surface_t &sf) const
Update the bound track parameter.
Definition pointwise_material_interactor.hpp:204
algebra_t algebra_type
Algebra backend type.
Definition pointwise_material_interactor.hpp:35
bound_parameters_vector< algebra_t > bound_param_vector_type
Bound track-parameter vector type.
Definition pointwise_material_interactor.hpp:45
dvector3D< algebra_t > vector3_type
Three-dimensional vector type.
Definition pointwise_material_interactor.hpp:39
dtransform3D< algebra_t > transform3_type
Three-dimensional transform type.
Definition pointwise_material_interactor.hpp:41
interaction< scalar_type > interaction_type
Material interaction calculator type.
Definition pointwise_material_interactor.hpp:43
void update_qop(bound_param_vector_type &vector, const pdg_particle< scalar_type > &ptc, const scalar_type e_loss, const int sign) const
Update the q over p of bound track parameter.
Definition pointwise_material_interactor.hpp:246
void update_qop_variance(bound_matrix_type &covariance, const scalar_type sigma_qop) const
Update the variance of q over p of bound track parameter.
Definition pointwise_material_interactor.hpp:279
actor::status status
Navigation status reported by the principal actor.
Definition base_actor.hpp:36
Base class actor implementation.
Definition base_actor.hpp:20
Six-component parameter vector expressed in a surface-bound coordinate frame.
Definition bound_track_parameters.hpp:29
point2_type bound_local() const
Definition bound_track_parameters.hpp:133
vector3_type dir() const
Definition bound_track_parameters.hpp:176
Combine the bound track parameter vector with the covariance and associated surface.
Definition bound_track_parameters.hpp:297
constexpr bool is_invalid(const bool do_check=true) const
Definition bound_track_parameters.hpp:397
covariance_type & covariance()
Definition bound_track_parameters.hpp:382
Computes energy loss and multiple scattering in detector material.
Definition interaction.hpp:23
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_bethe_bloch(const scalar_type path_segment, const detray::material< scalar_type > &mat, const pdg_particle< scalar_type > &ptc, const relativistic_quantities &rq) const
Compute the collisional energy loss over a path segment.
Definition interaction.hpp:210
scalar_type compute_energy_loss_landau_sigma_QOverP(const scalar_type path_segment, const material_t &mat, const pdg_particle< scalar_type > &ptc, const relativistic_quantities &rq) const
Convert energy-loss sigma to a q/p uncertainty.
Definition interaction.hpp:277
Particle hypothesis identified by PDG number, mass, and electric charge.
Definition pdg_particle.hpp:24
constexpr scalar_type mass() const
Definition pdg_particle.hpp:45
constexpr scalar_type charge() const
Definition pdg_particle.hpp:49