File indexing completed on 2025-08-06 08:09:55
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include <cmath>
0012
0013 #include "Acts/Utilities/Definitions.hpp"
0014 #include "Acts/Utilities/Helpers.hpp"
0015
0016 #include "Fatras/Kernel/detail/RandomNumberDistributions.hpp"
0017
0018 namespace Fatras {
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029 template <typename formula_t> struct Scattering {
0030
0031
0032 bool scattering = true;
0033
0034
0035 bool parametric = false;
0036 double projectionFactor = 1. / std::sqrt(2.);
0037
0038
0039 formula_t angle;
0040
0041
0042 template <typename generator_t, typename detector_t, typename particle_t>
0043 std::vector<particle_t> operator()(generator_t &gen, const detector_t &det,
0044 particle_t &in) const {
0045
0046
0047 if (not scattering) {
0048 return {};
0049 }
0050
0051
0052 double angle3D = angle(gen, det, in);
0053
0054
0055 if (parametric) {
0056
0057
0058 double theta = Acts::VectorHelpers::theta(in.momentum());
0059 double phi = Acts::VectorHelpers::phi(in.momentum());
0060 double sinTheta = (sin(theta) * sin(theta) > 10e-10) ? sin(theta) : 1.;
0061
0062
0063 double deltaTheta = projectionFactor * angle3D;
0064 double numDetlaPhi = 0.;
0065 double deltaPhi = projectionFactor * numDetlaPhi / sinTheta;
0066
0067
0068
0069 phi += deltaPhi;
0070 if (phi >= M_PI)
0071 phi -= M_PI;
0072 else if (phi < -M_PI)
0073 phi += M_PI;
0074
0075 theta += deltaTheta;
0076 if (theta > M_PI)
0077 theta -= M_PI;
0078 else if (theta < 0.)
0079 theta += M_PI;
0080
0081 double sphi = std::sin(phi);
0082 double cphi = std::cos(phi);
0083 double stheta = std::sin(theta);
0084 double ctheta = std::cos(theta);
0085
0086
0087 in.scatter(in.p() * Acts::Vector3D(cphi * stheta, sphi * stheta, ctheta));
0088 } else {
0089
0090
0091 UniformDist uniformDist = UniformDist(0., 1.);
0092
0093
0094 double psi = 2. * M_PI * uniformDist(gen);
0095
0096
0097 Acts::Vector3D pDirection(in.momentum().normalized());
0098 double x = -pDirection.y();
0099 double y = pDirection.x();
0100 double z = 0.;
0101
0102
0103 if (pDirection.z() * pDirection.z() > 0.999999) {
0104 x = 1.;
0105 y = 0.;
0106 }
0107
0108 Acts::Vector3D deflector(x, y, z);
0109
0110 Acts::RotationMatrix3D rotation;
0111 rotation = Acts::AngleAxis3D(psi, pDirection) *
0112 Acts::AngleAxis3D(angle3D, deflector);
0113
0114 in.scatter(in.p() * rotation * pDirection.normalized());
0115 }
0116
0117
0118 return {};
0119 }
0120 };
0121
0122 }