Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-02-22 09:55:28

0001 // This file is part of the Acts project.
0002 //
0003 // Copyright (C) 2018-2021 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 http://mozilla.org/MPL/2.0/.
0008 
0009 #pragma once
0010 
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/Material/MaterialSlab.hpp"
0013 #include "Acts/Utilities/UnitVectors.hpp"
0014 #include "ActsFatras/EventData/Particle.hpp"
0015 #include "ActsFatras/Physics/ElectroMagnetic/detail/GaussianMixture.hpp"
0016 #include "ActsFatras/Physics/ElectroMagnetic/detail/GeneralMixture.hpp"
0017 #include "ActsFatras/Physics/ElectroMagnetic/detail/Highland.hpp"
0018 
0019 #include <array>
0020 #include <random>
0021 
0022 namespace ActsFatras {
0023 
0024 /// Simulate (multiple) scattering using a configurable scattering model.
0025 ///
0026 /// @tparam scattering_model_t Model implementation to draw a scattering angle.
0027 template <typename scattering_model_t>
0028 struct GenericScattering {
0029   /// The scattering formula
0030   scattering_model_t angle;
0031 
0032   /// Simulate scattering and update the particle parameters.
0033   ///
0034   /// @param[in]     generator is the random number generator
0035   /// @param[in]     slab      defines the passed material
0036   /// @param[in,out] particle  is the particle being updated
0037   /// @return Empty secondaries containers.
0038   ///
0039   /// @tparam generator_t is a RandomNumberEngine
0040   template <typename generator_t>
0041   std::array<Particle, 0> operator()(generator_t &generator,
0042                                      const Acts::MaterialSlab &slab,
0043                                      Particle &particle) const {
0044     // the scattered direction can be computed by rotating the initial
0045     // direction around a vector orthogonal to the initial direction, i.e. the
0046     // scattering deflector, by the scattering angle. there are an infinite
0047     // number of vectors orthogonal to the initial direction. the deflector is
0048     // rotated by some angle relative to some fixpoint.
0049     //
0050     // thus two random angles are required: the random deflector orientation
0051     // angle drawn uniformly from the [-pi,pi) range and the scattering angle
0052     // drawn from the specific scattering model distribution.
0053 
0054     // draw the random orientation angle
0055     const auto psi =
0056         std::uniform_real_distribution<double>(-M_PI, M_PI)(generator);
0057     // draw the scattering angle
0058     const auto theta = angle(generator, slab, particle);
0059 
0060     Acts::Vector3 direction = particle.direction();
0061     // construct the combined rotation to the scattered direction
0062     Acts::RotationMatrix3 rotation(
0063         // rotation of the scattering deflector axis relative to the reference
0064         Acts::AngleAxis3(psi, direction) *
0065         // rotation by the scattering angle around the deflector axis
0066         Acts::AngleAxis3(theta, Acts::makeCurvilinearUnitU(direction)));
0067     direction.applyOnTheLeft(rotation);
0068     particle.setDirection(direction);
0069 
0070     // scattering is non-destructive and produces no secondaries
0071     return {};
0072   }
0073 };
0074 
0075 using GaussianMixtureScattering = GenericScattering<detail::GaussianMixture>;
0076 using GeneralMixtureScattering = GenericScattering<detail::GeneralMixture>;
0077 using HighlandScattering = GenericScattering<detail::Highland>;
0078 
0079 }  // namespace ActsFatras