16#include "GaudiKernel/ThreadLocalContext.h"
17#include "CLHEP/Random/RandFlat.h"
25constexpr double s_main_RutherfordScott = 13.6 * Gaudi::Units::MeV;
26constexpr double s_log_RutherfordScott = 0.038;
28constexpr double s_main_RossiGreisen = 17.5 * Gaudi::Units::MeV;
29constexpr double s_log_RossiGreisen = 0.125;
32constexpr double s_gausMixSigma1_a0 = 8.471e-1;
33constexpr double s_gausMixSigma1_a1 = 3.347e-2;
34constexpr double s_gausMixSigma1_a2 = -1.843e-3;
36constexpr double s_gausMixEpsilon_a0 = 4.841e-2;
37constexpr double s_gausMixEpsilon_a1 = 6.348e-3;
38constexpr double s_gausMixEpsilon_a2 = 6.096e-4;
40constexpr double s_gausMixEpsilon_b0 = -1.908e-2;
41constexpr double s_gausMixEpsilon_b1 = 1.106e-1;
42constexpr double s_gausMixEpsilon_b2 = -5.729e-3;
48 const IInterface *p) :
50 declareInterface<IMultipleScatteringUpdator>(
this);
74 "Could not get random engine '" <<
m_randomEngineName <<
"' -> switching Gaussian mixture model off.");
84 return StatusCode::SUCCESS;
90 double pathcorrection,
98 pathcorrection *= pathcorrection < 0. ? (-1.) : (1);
101 double t = pathcorrection * mat.thicknessInX0();
105 double E = sqrt(p * p + m * m);
111 sigma2 = sigma * sigma;
123 sigma2 = s_main_RutherfordScott / denom;
127 sigma2 *= (1. + s_log_RutherfordScott * std::log(t));
130 sigma2 *= (sigma2 * t);
135 sigma2 = s_main_RossiGreisen / (beta * p);
136 sigma2 *= (sigma2 * t);
139 double factor = 1. + s_log_RossiGreisen * std::log10(10. * t);
148 const EventContext& ctx = Gaudi::Hive::currentContext();
153 wrapper_nc->setSeed (this->name(), ctx);
155 CLHEP::HepRandomEngine* engine =
m_rngWrapper->getEngine (ctx);
161 ATH_MSG_WARNING(
"Trk::MultipleScatteringUpdator::sigmaSquare: beta close to zero");
164 double log_dprime = std::log(dprime);
166 double log_dprimeprime = std::log(std::pow(mat.averageZ(), 2.0 / 3.0) * dprime);
168 double epsilon = log_dprimeprime < 0.5 ?
169 s_gausMixEpsilon_a0 + s_gausMixEpsilon_a1 * log_dprimeprime + s_gausMixEpsilon_a2 *
170 log_dprimeprime * log_dprimeprime :
171 s_gausMixEpsilon_b0 + s_gausMixEpsilon_b1 * log_dprimeprime + s_gausMixEpsilon_b2 *
172 log_dprimeprime * log_dprimeprime;
174 double sigma1square = s_gausMixSigma1_a0 + s_gausMixSigma1_a1 * log_dprime + s_gausMixSigma1_a2 * log_dprime *
179 sigma2 = 225. * dprime / (p * p);
181 ATH_MSG_WARNING(
"Trk::MultipleScatteringUpdator::sigmaSquare: p close to zero");
185 if (CLHEP::RandFlat::shoot(engine) < epsilon) {
186 sigma2 *= (1. - (1. - epsilon) * sigma1square) / epsilon;
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
bool close_to_zero(T value, T eps=std::numeric_limits< T >::epsilon())
Define macros for attributes used to control the static checker.
#define ATLAS_THREAD_SAFE
A wrapper class for event-slot-local random engines.
Material with information about thickness of material.
BooleanProperty m_optGaussianMixtureG4
ATHRNG::RNGWrapper * m_rngWrapper
Random engine.
BooleanProperty m_gaussianMixture
virtual StatusCode initialize() override
AlgTool initailize method.
MultipleScatteringUpdator(const std::string &, const std::string &, const IInterface *)
AlgTool like constructor.
BooleanProperty m_useTrkUtils
BooleanProperty m_log_include
virtual ~MultipleScatteringUpdator()
Virtual destructor.
ServiceHandle< IAthRNGSvc > m_rndGenSvc
Random Generator service.
StringProperty m_randomEngineName
virtual double sigmaSquare(const MaterialProperties &mat, double p, double pathcorrection, ParticleHypothesis particle=pion, double deltaE=0.) const override
Calculate the sigma on theta introduced by multiple scattering, according to the RutherFord-Scott For...
test if a value is close enough to zero to be an unreliable denominator.
bool close_to_zero(T value, T eps=std::numeric_limits< T >::epsilon())
constexpr double mass[PARTICLEHYPOTHESES]
the array of masses
ParticleHypothesis
Enumeration for Particle hypothesis respecting the interaction with material.
static double sigmaMS(double dInX0, double p, double beta)
multiple scattering as function of dInX0