Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:12:13

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 
0015 #include <array>
0016 #include <cmath>
0017 #include <numbers>
0018 #include <random>
0019 
0020 namespace ActsFatras {
0021 
0022 /// Simulate electron energy loss using the Bethe-Heitler description.
0023 ///
0024 /// Bethe-Heitler for electron bremsstrahlung description as described here:
0025 /// "A Gaussian-mixture approximation of the Bethe–Heitler model of electron
0026 /// energy loss by bremsstrahlung" R. Frühwirth
0027 struct BetheHeitler {
0028   /// A scaling factor to
0029   double scaleFactor = 1.;
0030 
0031   // Simplified angle evaluation
0032   bool uniformHertzDipoleAngle = false;
0033 
0034   /// Simulate the photon emission
0035   ///
0036   /// @param [in] particle The unmodified electron
0037   /// @param [in] gammaE Energy of the photon
0038   /// @param [in] rndPsi Random number for the azimuthal angle
0039   /// @param [in] rndTheta1 Random number for the polar angle
0040   /// @param [in] rndTheta2 Random number for the polar angle
0041   /// @param [in] rndTheta3 Random number for the polar angle
0042   Particle bremPhoton(const Particle &particle, double gammaE, double rndPsi,
0043                       double rndTheta1, double rndTheta2,
0044                       double rndTheta3) const;
0045 
0046   /// Simulate energy loss and update the particle parameters.
0047   ///
0048   /// @param[in]     generator is the random number generator
0049   /// @param[in]     slab      defines the passed material
0050   /// @param[in,out] particle  is the particle being updated
0051   /// @return Produced photon.
0052   ///
0053   /// @tparam generator_t is a RandomNumberEngine
0054   template <typename generator_t>
0055   std::array<Particle, 1> operator()(generator_t &generator,
0056                                      const Acts::MaterialSlab &slab,
0057                                      Particle &particle) const {
0058     // Take a random gamma-distributed value - depending on t/X0
0059     std::gamma_distribution<double> gDist(
0060         slab.thicknessInX0() / std::numbers::ln2, 1.);
0061 
0062     const auto u = gDist(generator);
0063     const auto z = std::exp(-u);  // MARK: fpeMask(FLTUND, 1, #2346)
0064     const auto sampledEnergyLoss =
0065         std::abs(scaleFactor * particle.energy() * (z - 1.));
0066 
0067     std::uniform_real_distribution<double> uDist(0., 1.);
0068     // Build the produced photon
0069     Particle photon =
0070         bremPhoton(particle, sampledEnergyLoss, uDist(generator),
0071                    uDist(generator), uDist(generator), uDist(generator));
0072     // Recoil input momentum
0073     particle.setDirection(particle.direction() * particle.absoluteMomentum() -
0074                           photon.energy() * photon.direction());
0075 
0076     // apply the energy loss
0077     particle.correctEnergy(-sampledEnergyLoss);
0078 
0079     return {photon};
0080   }
0081 };
0082 
0083 }  // namespace ActsFatras