Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-01 07:53:33

0001 // This file is part of the ACTS project.
0002 //
0003 // Copyright (C) 2016 CERN for the benefit of the ACTS project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
0008 
0009 #pragma once
0010 
0011 #include "Acts/Material/MaterialSlab.hpp"
0012 #include "Acts/Utilities/UnitVectors.hpp"
0013 #include "ActsFatras/EventData/Particle.hpp"
0014 #include "ActsFatras/Utilities/detail/FpeSafeGammaDistribution.hpp"
0015 
0016 #include <array>
0017 #include <cmath>
0018 #include <numbers>
0019 #include <random>
0020 
0021 namespace ActsFatras {
0022 
0023 /// Simulate electron energy loss using the Bethe-Heitler description.
0024 ///
0025 /// Bethe-Heitler for electron bremsstrahlung description as described here:
0026 /// "A Gaussian-mixture approximation of the Bethe–Heitler model of electron
0027 /// energy loss by bremsstrahlung" R. Frühwirth
0028 struct BetheHeitler {
0029   /// A scaling factor to
0030   double scaleFactor = 1.;
0031 
0032   // Simplified angle evaluation
0033   bool uniformHertzDipoleAngle = false;
0034 
0035   /// Simulate the photon emission
0036   ///
0037   /// @param [in] particle The unmodified electron
0038   /// @param [in] gammaE Energy of the photon
0039   /// @param [in] rndPsi Random number for the azimuthal angle
0040   /// @param [in] rndTheta1 Random number for the polar angle
0041   /// @param [in] rndTheta2 Random number for the polar angle
0042   /// @param [in] rndTheta3 Random number for the polar angle
0043   Particle bremPhoton(const Particle &particle, double gammaE, double rndPsi,
0044                       double rndTheta1, double rndTheta2,
0045                       double rndTheta3) const;
0046 
0047   /// Simulate energy loss and update the particle parameters.
0048   ///
0049   /// @param[in]     generator is the random number generator
0050   /// @param[in]     slab      defines the passed material
0051   /// @param[in,out] particle  is the particle being updated
0052   /// @return Produced photon.
0053   ///
0054   /// @tparam generator_t is a RandomNumberEngine
0055   template <typename generator_t>
0056   std::array<Particle, 1> operator()(generator_t &generator,
0057                                      const Acts::MaterialSlab &slab,
0058                                      Particle &particle) const {
0059     // Take a random gamma-distributed value - depending on t/X0
0060     detail::FpeSafeGammaDistribution gDist(
0061         slab.thicknessInX0() / std::numbers::ln2, 1.);
0062 
0063     const auto u = gDist(generator);
0064     const auto z = std::exp(-u);
0065     const auto sampledEnergyLoss =
0066         std::abs(scaleFactor * particle.energy() * (z - 1.));
0067 
0068     std::uniform_real_distribution<double> uDist(0., 1.);
0069     // Build the produced photon
0070     Particle photon =
0071         bremPhoton(particle, sampledEnergyLoss, uDist(generator),
0072                    uDist(generator), uDist(generator), uDist(generator));
0073     // Recoil input momentum
0074     particle.setDirection(particle.direction() * particle.absoluteMomentum() -
0075                           photon.energy() * photon.direction());
0076 
0077     // apply the energy loss
0078     particle.correctEnergy(-sampledEnergyLoss);
0079 
0080     return {photon};
0081   }
0082 };
0083 
0084 }  // namespace ActsFatras