CMS 3D CMS Logo

BremsstrahlungSimulator.cc
Go to the documentation of this file.
1 //FAMOS Headers
5 
6 #include <cmath>
7 
9  // Set the minimal photon energy for a Brem from e+/-
11  photonFractE = photonFractECut;
12 }
13 
15  // Protection : Just stop the electron if more than 1 radiation lengths.
16  // This case corresponds to an electron entering the layer parallel to
17  // the layer axis - no reliable simulation can be done in that case...
18  // 08/02/06 - pv: increase protection from 1 to 4 X0 for eta>4.8 region
19  // if ( radLengths > 1. ) Particle.particle().setMomentum(0.,0.,0.,0.);
20  if (radLengths > 4.)
21  Particle.particle().setMomentum(0., 0., 0., 0.);
22 
23  // Hard brem probability with a photon Energy above photonEnergy.
24  if (Particle.particle().e() < photonEnergy)
25  return;
26  xmin = std::max(photonEnergy / Particle.particle().e(), photonFractE);
27  if (xmin >= 1. || xmin <= 0.)
28  return;
29 
30  double bremProba =
31  radLengths * (4. / 3. * std::log(1. / xmin) - 4. / 3. * (1. - xmin) + 1. / 2. * (1. - xmin * xmin));
32 
33  // Number of photons to be radiated.
34  unsigned int nPhotons = poisson(bremProba, random);
35  _theUpdatedState.reserve(nPhotons);
36 
37  if (!nPhotons)
38  return;
39 
40  //Rotate to the lab frame
41  double chi = Particle.particle().theta();
42  double psi = Particle.particle().phi();
44  RawParticle::RotationY rotY(chi);
45 
46  // Energy of these photons
47  for (unsigned int i = 0; i < nPhotons; ++i) {
48  // Check that there is enough energy left.
49  if (Particle.particle().e() < photonEnergy)
50  break;
51 
52  // Add a photon
53  RawParticle thePhoton = makeParticle(Particle.particleDataTable(), 22, brem(Particle, random));
54  thePhoton.rotate(rotY);
55  thePhoton.rotate(rotZ);
56  _theUpdatedState.push_back(thePhoton);
57 
58  // Update the original e+/-
59  Particle.particle().momentum() -= thePhoton.momentum();
60  }
61 }
62 
64  RandomEngineAndDistribution const* random) const {
65  // This is a simple version (a la PDG) of a Brem generator.
66  // It replaces the buggy GEANT3 -> C++ former version.
67  // Author : Patrick Janot - 25-Dec-2003
68  double emass = 0.0005109990615;
69  double xp = 0;
70  double weight = 0.;
71 
72  do {
73  xp = xmin * std::exp(-std::log(xmin) * random->flatShoot());
74  weight = 1. - xp + 3. / 4. * xp * xp;
75  } while (weight < random->flatShoot());
76 
77  // Have photon energy. Now generate angles with respect to the z axis
78  // defined by the incoming particle's momentum.
79 
80  // Isotropic in phi
81  const double phi = random->flatShoot() * 2 * M_PI;
82  // theta from universal distribution
83  const double theta = gbteth(pp.particle().e(), emass, xp, random) * emass / pp.particle().e();
84 
85  // Make momentum components
86  double stheta = std::sin(theta);
87  double ctheta = std::cos(theta);
88  double sphi = std::sin(phi);
89  double cphi = std::cos(phi);
90 
91  return xp * pp.particle().e() * XYZTLorentzVector(stheta * cphi, stheta * sphi, ctheta, 1.);
92 }
93 
94 double BremsstrahlungSimulator::gbteth(const double ener,
95  const double partm,
96  const double efrac,
97  RandomEngineAndDistribution const* random) const {
98  const double alfa = 0.625;
99 
100  const double d = 0.13 * (0.8 + 1.3 / theZ()) * (100.0 + (1.0 / ener)) * (1.0 + efrac);
101  const double w1 = 9.0 / (9.0 + d);
102  const double umax = ener * M_PI / partm;
103  double u;
104 
105  do {
106  double beta = (random->flatShoot() <= w1) ? alfa : 3.0 * alfa;
107  u = -std::log(random->flatShoot() * random->flatShoot()) / beta;
108  } while (u >= umax);
109 
110  return u;
111 }
112 
113 unsigned int BremsstrahlungSimulator::poisson(double ymu, RandomEngineAndDistribution const* random) {
114  unsigned int n = 0;
115  double prob = std::exp(-ymu);
116  double proba = prob;
117  double x = random->flatShoot();
118 
119  while (proba <= x) {
120  prob *= ymu / double(++n);
121  proba += prob;
122  }
123 
124  return n;
125 }
void compute(ParticlePropagator &Particle, RandomEngineAndDistribution const *) override
Generate Bremsstrahlung photons.
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
Definition: weight.py:1
const XYZTLorentzVector & momentum() const
the momentum fourvector
Definition: RawParticle.h:321
std::map< std::string, int, std::less< std::string > > psi
ROOT::Math::RotationZ RotationZ
Definition: RawParticle.h:48
RawParticle makeParticle(HepPDT::ParticleDataTable const *, int id, const math::XYZTLorentzVector &p)
Definition: makeParticle.cc:28
unsigned int poisson(double ymu, RandomEngineAndDistribution const *)
Generate numbers according to a Poisson distribution of mean ymu.
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
double gbteth(const double ener, const double partm, const double efrac, RandomEngineAndDistribution const *) const
A universal angular distribution - still from GEANT.
ROOT::Math::RotationY RotationY
Definition: RawParticle.h:47
BremsstrahlungSimulator(double photonEnergyCut, double photonFractECut)
Constructor.
void rotate(double rphi, const XYZVector &raxis)
Definition: RawParticle.cc:41
XYZTLorentzVector brem(ParticlePropagator &p, RandomEngineAndDistribution const *) const
Compute Brem photon energy and angles, if any.
d
Definition: ztail.py:151
#define M_PI
weight_default_t w1[2000]
Definition: w1.h:9
double xmin
The fractional photon energy cut (determined from the above two)
std::vector< RawParticle > _theUpdatedState
double flatShoot(double xmin=0.0, double xmax=1.0) const
double photonEnergy
The minimum photon energy to be radiated, in GeV.
Geom::Theta< T > theta() const
double photonFractE
The minimum photon fractional energy (wrt that of the electron)
math::XYZTLorentzVector XYZTLorentzVector
Definition: RawParticle.h:25