CMS 3D CMS Logo

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 
18 
20 // Author: Patrick Janot
21 // Date: 25-Dec-2003
22 //
23 // Revision: Class structure modified to match SimplifiedGeometryPropagator
24 // Fixed a bug in which particles could radiate more energy than they have
25 // S. Kurz, 29 May 2017
27 
28 
29 namespace fastsim
30 {
32 
37  {
38  public:
41 
43  ~Bremsstrahlung() override{;};
44 
46 
52  void interact(Particle & particle, const SimplifiedGeometry & layer, std::vector<std::unique_ptr<Particle> > & secondaries, const RandomEngineAndDistribution & random) override;
53 
54  private:
56 
62  math::XYZTLorentzVector brem(Particle & particle, double xmin, const RandomEngineAndDistribution & random) const;
63 
65 
72  double gbteth(const double ener,
73  const double partm,
74  const double efrac,
75  const RandomEngineAndDistribution & random) const ;
76 
79  double Z_;
80  };
81 }
82 
84  : fastsim::InteractionModel(name)
85 {
86  // Set the minimal photon energy for a Brem from e+/-
87  minPhotonEnergy_ = cfg.getParameter<double>("minPhotonEnergy");
88  minPhotonEnergyFraction_ = cfg.getParameter<double>("minPhotonEnergyFraction");
89  // Material properties
90  Z_ = cfg.getParameter<double>("Z");
91 }
92 
93 
94 void fastsim::Bremsstrahlung::interact(fastsim::Particle & particle, const SimplifiedGeometry & layer,std::vector<std::unique_ptr<fastsim::Particle> > & secondaries,const RandomEngineAndDistribution & random)
95 {
96  // only consider electrons and positrons
97  if(std::abs(particle.pdgId())!=11)
98  {
99  return;
100  }
101 
102  double radLengths = layer.getThickness(particle.position(),particle.momentum());
103  //
104  // no material
105  //
106  if(radLengths < 1E-10)
107  {
108  return;
109  }
110 
111  // Protection : Just stop the electron if more than 1 radiation lengths.
112  // This case corresponds to an electron entering the layer parallel to
113  // the layer axis - no reliable simulation can be done in that case...
114  if(radLengths > 4.)
115  {
116  particle.momentum().SetXYZT(0.,0.,0.,0.);
117  return;
118  }
119 
120  // electron must have more energy than minimum photon energy
121  if(particle.momentum().E() - particle.momentum().mass() < minPhotonEnergy_)
122  {
123  return;
124  }
125 
126  // Hard brem probability with a photon Energy above threshold.
128  if(xmin >=1. || xmin <=0.)
129  {
130  return;
131  }
132 
133  // probability to radiate a photon
134  double bremProba = radLengths * (4./3. * std::log(1./xmin)
135  - 4./3. * (1.-xmin)
136  + 1./2. * (1.-xmin*xmin));
137 
138 
139  // Number of photons to be radiated.
140  unsigned int nPhotons = random.poissonShoot(bremProba);
141  if(nPhotons == 0)
142  {
143  return;
144  }
145 
146  // Needed to rotate photons to the lab frame
147  double theta = particle.momentum().Theta();
148  double phi = particle.momentum().Phi();
149  double m2dontchange = particle.momentum().mass()*particle.momentum().mass();
150 
151  // Calculate energy of these photons and add them to the event
152  for(unsigned int i=0; i<nPhotons; ++i)
153  {
154  // Throw momentum of the photon
155  math::XYZTLorentzVector photonMom = brem(particle, xmin, random);
156 
157  // Check that there is enough energy left.
158  if(particle.momentum().E() - particle.momentum().mass() < photonMom.E()) break;
159 
160  // Rotate to the lab frame
161  photonMom = ROOT::Math::RotationZ(phi) * (ROOT::Math::RotationY(theta) * photonMom);
162 
163  // Add a photon
164  secondaries.emplace_back(new fastsim::Particle(22, particle.position(), photonMom));
165 
166  // Update the original e+/-
167  particle.momentum() -= photonMom;
168 
169  // Reset mass to original, since the above codes for decay e->e+gamma, ignoring proton
170  particle.momentum().SetXYZT(particle.momentum().px(),particle.momentum().py(), particle.momentum().pz(),sqrt(pow(particle.momentum().P(),2)+m2dontchange));
171  }
172 }
173 
174 
177 {
178  double xp=0;
179  double weight = 0.;
180 
181  do{
182  xp = xmin * std::exp ( -std::log(xmin) * random.flatShoot() );
183  weight = 1. - xp + 3./4.*xp*xp;
184  }while(weight < random.flatShoot());
185 
186 
187  // Have photon energy. Now generate angles with respect to the z axis
188  // defined by the incoming particle's momentum.
189 
190  // Isotropic in phi
191  const double phi = random.flatShoot() * 2. * M_PI;
192  // theta from universal distribution
193  const double theta = gbteth(particle.momentum().E(), fastsim::Constants::eMass, xp, random)
194  * fastsim::Constants::eMass / particle.momentum().E();
195 
196  // Make momentum components
197  double stheta = std::sin(theta);
198  double ctheta = std::cos(theta);
199  double sphi = std::sin(phi);
200  double cphi = std::cos(phi);
201 
202  return xp * particle.momentum().E() * math::XYZTLorentzVector(stheta*cphi, stheta*sphi, ctheta, 1.);
203 }
204 
205 double
207  const double partm,
208  const double efrac,
209  const RandomEngineAndDistribution & random) const
210 {
211  // Details on implementation here
212  // http://www.dnp.fmph.uniba.sk/cernlib/asdoc/geant_html3/node299.html#GBTETH
213  // http://svn.cern.ch/guest/AliRoot/tags/v3-07-03/GEANT321/gphys/gbteth.F
214 
215  const double alfa = 0.625;
216 
217  const double d = 0.13*(0.8+1.3/Z_)*(100.0+(1.0/ener))*(1.0+efrac);
218  const double w1 = 9.0/(9.0+d);
219  const double umax = ener*M_PI/partm;
220  double u;
221 
222  do
223  {
224  double beta = (random.flatShoot()<=w1) ? alfa : 3.0*alfa;
225  u = -std::log(random.flatShoot()*random.flatShoot())/beta;
226  }while (u >= umax);
227 
228  return u;
229 }
230 
234  "fastsim::Bremsstrahlung"
235  );
T getParameter(std::string const &) const
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:142
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)
Definition: weight.py:1
int pdgId() const
Return pdgId of the particle.
Definition: Particle.h:136
TRandom random
Definition: MVATrainer.cc:138
static double constexpr eMass
Electron mass[GeV].
Definition: Constants.h:17
Bremsstrahlung(const std::string &name, const edm::ParameterSet &cfg)
Constructor.
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.
T sqrt(T t)
Definition: SSEVec.h:18
~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.
Implementation of Bremsstrahlung from e+/e- in the tracker layers.
virtual const double getThickness(const math::XYZTLorentzVector &position) const =0
Return thickness of the layer at a given position.
unsigned int poissonShoot(double mean) const
const math::XYZTLorentzVector & momentum() const
Return momentum of the particle.
Definition: Particle.h:145
#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:19
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:40
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.