File indexing completed on 2025-02-22 09:55:27
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include "Acts/Material/Interactions.hpp"
0012
0013 #include <random>
0014
0015 namespace ActsFatras::detail {
0016
0017
0018 struct GaussianMixture {
0019
0020 bool optGaussianMixtureG4 = false;
0021 double gausMixSigma1_a0 = 8.471e-1;
0022 double gausMixSigma1_a1 = 3.347e-2;
0023 double gausMixSigma1_a2 = -1.843e-3;
0024 double gausMixEpsilon_a0 = 4.841e-2;
0025 double gausMixEpsilon_a1 = 6.348e-3;
0026 double gausMixEpsilon_a2 = 6.096e-4;
0027 double gausMixEpsilon_b0 = -1.908e-2;
0028 double gausMixEpsilon_b1 = 1.106e-1;
0029 double gausMixEpsilon_b2 = -5.729e-3;
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039 template <typename generator_t>
0040 double operator()(generator_t &generator, const Acts::MaterialSlab &slab,
0041 Particle &particle) const {
0042
0043 double sigma = Acts::computeMultipleScatteringTheta0(
0044 slab, particle.absolutePdg(), particle.mass(), particle.qOverP(),
0045 particle.absoluteCharge());
0046 double sigma2 = sigma * sigma;
0047
0048
0049 std::normal_distribution<double> gaussDist(0., 1.);
0050
0051 std::uniform_real_distribution<double> uniformDist(0., 1.);
0052
0053
0054
0055
0056
0057 double mOverP = particle.mass() / particle.absoluteMomentum();
0058 double beta2inv = 1 + mOverP * mOverP;
0059 double dprime = slab.thicknessInX0() * beta2inv;
0060 double log_dprime = std::log(dprime);
0061
0062 double log_dprimeprime =
0063 std::log(std::pow(slab.material().Z(), 2.0 / 3.0) * dprime);
0064
0065
0066 double epsilon =
0067 log_dprimeprime < 0.5
0068 ? gausMixEpsilon_a0 + gausMixEpsilon_a1 * log_dprimeprime +
0069 gausMixEpsilon_a2 * log_dprimeprime * log_dprimeprime
0070 : gausMixEpsilon_b0 + gausMixEpsilon_b1 * log_dprimeprime +
0071 gausMixEpsilon_b2 * log_dprimeprime * log_dprimeprime;
0072
0073
0074 double sigma1square = gausMixSigma1_a0 + gausMixSigma1_a1 * log_dprime +
0075 gausMixSigma1_a2 * log_dprime * log_dprime;
0076
0077
0078 if (optGaussianMixtureG4) {
0079 sigma2 = 225. * dprime /
0080 (particle.absoluteMomentum() * particle.absoluteMomentum());
0081 }
0082
0083 if (uniformDist(generator) < epsilon) {
0084 sigma2 *= (1. - (1. - epsilon) * sigma1square) / epsilon;
0085 }
0086
0087 return M_SQRT2 * std::sqrt(sigma2) * gaussDist(generator);
0088 }
0089 };
0090
0091 }