CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
Bremsstrahlung.cc
Go to the documentation of this file.
6 
7 #include <cmath>
8 #include <memory>
9 
10 #include <Math/RotationY.h>
11 #include <Math/RotationZ.h>
12 
17 
19 // Author: Patrick Janot
20 // Date: 25-Dec-2003
21 //
22 // Revision: Class structure modified to match SimplifiedGeometryPropagator
23 // Fixed a bug in which particles could radiate more energy than they have
24 // S. Kurz, 29 May 2017
26 
27 namespace fastsim {
29 
34  public:
37 
39  ~Bremsstrahlung() override { ; };
40 
42 
48  void interact(Particle& particle,
50  std::vector<std::unique_ptr<Particle> >& secondaries,
51  const RandomEngineAndDistribution& random) override;
52 
53  private:
55 
61  math::XYZTLorentzVector brem(Particle& particle, double xmin, const RandomEngineAndDistribution& random) const;
62 
64 
71  double gbteth(const double ener,
72  const double partm,
73  const double efrac,
74  const RandomEngineAndDistribution& random) const;
75 
78  double Z_;
79  };
80 } // namespace fastsim
81 
83  : fastsim::InteractionModel(name) {
84  // Set the minimal photon energy for a Brem from e+/-
85  minPhotonEnergy_ = cfg.getParameter<double>("minPhotonEnergy");
86  minPhotonEnergyFraction_ = cfg.getParameter<double>("minPhotonEnergyFraction");
87  // Material properties
88  Z_ = cfg.getParameter<double>("Z");
89 }
90 
93  std::vector<std::unique_ptr<fastsim::Particle> >& secondaries,
94  const RandomEngineAndDistribution& random) {
95  // only consider electrons and positrons
96  if (std::abs(particle.pdgId()) != 11) {
97  return;
98  }
99 
100  double radLengths = layer.getThickness(particle.position(), particle.momentum());
101  //
102  // no material
103  //
104  if (radLengths < 1E-10) {
105  return;
106  }
107 
108  // Protection : Just stop the electron if more than 1 radiation lengths.
109  // This case corresponds to an electron entering the layer parallel to
110  // the layer axis - no reliable simulation can be done in that case...
111  if (radLengths > 4.) {
112  particle.momentum().SetXYZT(0., 0., 0., 0.);
113  return;
114  }
115 
116  // electron must have more energy than minimum photon energy
117  if (particle.momentum().E() - particle.momentum().mass() < minPhotonEnergy_) {
118  return;
119  }
120 
121  // Hard brem probability with a photon Energy above threshold.
122  double xmin = std::max(minPhotonEnergy_ / particle.momentum().E(), minPhotonEnergyFraction_);
123  if (xmin >= 1. || xmin <= 0.) {
124  return;
125  }
126 
127  // probability to radiate a photon
128  double bremProba =
129  radLengths * (4. / 3. * std::log(1. / xmin) - 4. / 3. * (1. - xmin) + 1. / 2. * (1. - xmin * xmin));
130 
131  // Number of photons to be radiated.
132  unsigned int nPhotons = random.poissonShoot(bremProba);
133  if (nPhotons == 0) {
134  return;
135  }
136 
137  // Needed to rotate photons to the lab frame
138  double theta = particle.momentum().Theta();
139  double phi = particle.momentum().Phi();
140 
141  // Calculate energy of these photons and add them to the event
142  for (unsigned int i = 0; i < nPhotons; ++i) {
143  // Throw momentum of the photon
144  math::XYZTLorentzVector photonMom = brem(particle, xmin, random);
145 
146  // Check that there is enough energy left.
147  if (particle.momentum().E() - particle.momentum().mass() < photonMom.E())
148  break;
149 
150  // Rotate to the lab frame
151  photonMom = ROOT::Math::RotationZ(phi) * (ROOT::Math::RotationY(theta) * photonMom);
152 
153  // Add a photon
154  secondaries.emplace_back(new fastsim::Particle(22, particle.position(), photonMom));
155 
156  // Update the original e+/-
157  particle.momentum() -= photonMom;
158  }
159 }
160 
162  double xmin,
163  const RandomEngineAndDistribution& random) const {
164  double xp = 0;
165  double weight = 0.;
166 
167  do {
168  xp = xmin * std::exp(-std::log(xmin) * random.flatShoot());
169  weight = 1. - xp + 3. / 4. * xp * xp;
170  } while (weight < random.flatShoot());
171 
172  // Have photon energy. Now generate angles with respect to the z axis
173  // defined by the incoming particle's momentum.
174 
175  // Isotropic in phi
176  const double phi = random.flatShoot() * 2. * M_PI;
177  // theta from universal distribution
178  const double theta = gbteth(particle.momentum().E(), fastsim::Constants::eMass, xp, random) *
179  fastsim::Constants::eMass / particle.momentum().E();
180 
181  // Make momentum components
182  double stheta = std::sin(theta);
183  double ctheta = std::cos(theta);
184  double sphi = std::sin(phi);
185  double cphi = std::cos(phi);
186 
187  return xp * particle.momentum().E() * math::XYZTLorentzVector(stheta * cphi, stheta * sphi, ctheta, 1.);
188 }
189 
190 double fastsim::Bremsstrahlung::gbteth(const double ener,
191  const double partm,
192  const double efrac,
193  const RandomEngineAndDistribution& random) const {
194  // Details on implementation here
195  // http://www.dnp.fmph.uniba.sk/cernlib/asdoc/geant_html3/node299.html#GBTETH
196  // http://svn.cern.ch/guest/AliRoot/tags/v3-07-03/GEANT321/gphys/gbteth.F
197 
198  const double alfa = 0.625;
199 
200  const double d = 0.13 * (0.8 + 1.3 / Z_) * (100.0 + (1.0 / ener)) * (1.0 + efrac);
201  const double w1 = 9.0 / (9.0 + d);
202  const double umax = ener * M_PI / partm;
203  double u;
204 
205  do {
206  double beta = (random.flatShoot() <= w1) ? alfa : 3.0 * alfa;
207  u = -std::log(random.flatShoot() * random.flatShoot()) / beta;
208  } while (u >= umax);
209 
210  return u;
211 }
212 
static std::vector< std::string > checklist log
tuple cfg
Definition: looper.py:296
Implementation of a generic detector layer (base class for forward/barrel layers).
const math::XYZTLorentzVector & position() const
Return position of the particle.
Definition: Particle.h:140
virtual const double getThickness(const math::XYZTLorentzVector &position) const =0
Return thickness of the layer at a given position.
double flatShoot(double xmin=0.0, double xmax=1.0) const
double minPhotonEnergy_
Cut on minimum energy of bremsstrahlung photons.
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
Geom::Theta< T > theta() const
void interact(Particle &particle, const SimplifiedGeometry &layer, std::vector< std::unique_ptr< Particle > > &secondaries, const RandomEngineAndDistribution &random) override
Perform the interaction.
double Z_
Atomic number of material (usually silicon Z=14)
Exp< T >::type exp(const T &t)
Definition: Exp.h:22
int pdgId() const
Return pdgId of the particle.
Definition: Particle.h:134
static double constexpr eMass
Electron mass[GeV].
Definition: Constants.h:13
constexpr std::array< uint8_t, layerIndexSize > layer
Bremsstrahlung(const std::string &name, const edm::ParameterSet &cfg)
Constructor.
tuple d
Definition: ztail.py:151
XYZTLorentzVectorD XYZTLorentzVector
Lorentz vector with cylindrical internal representation using pseudorapidity.
Definition: LorentzVector.h:29
Base class for any interaction model between a particle and a tracker layer.
~Bremsstrahlung() override
Default destructor.
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
#define M_PI
double gbteth(const double ener, const double partm, const double efrac, const RandomEngineAndDistribution &random) const
A universal angular distribution.
T getParameter(std::string const &) const
Definition: ParameterSet.h:303
Implementation of Bremsstrahlung from e+/e- in the tracker layers.
unsigned int poissonShoot(double mean) const
const math::XYZTLorentzVector & momentum() const
Return momentum of the particle.
Definition: Particle.h:143
#define DEFINE_EDM_PLUGIN(factory, type, name)
Definition of a generic FastSim Particle which can be propagated through the detector (formerly Parti...
Definition: Particle.h:16
int weight
Definition: histoStyle.py:51
double minPhotonEnergyFraction_
Cut on minimum fraction of particle&#39;s energy which has to be carried by photon.
math::XYZTLorentzVector brem(Particle &particle, double xmin, const RandomEngineAndDistribution &random) const
Compute Brem photon energy and angles, if any.