CMS 3D CMS Logo

PairProduction.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: 24-Dec-2003
22 //
23 // Revision: Class structure modified to match SimplifiedGeometryPropagator
24 // S. Kurz, 29 May 2017
26 
27 
28 namespace fastsim
29 {
31 
35  {
36  public:
39 
41  ~PairProduction() override{;};
42 
44 
50  void interact(fastsim::Particle & particle, const SimplifiedGeometry & layer,std::vector<std::unique_ptr<fastsim::Particle> > & secondaries,const RandomEngineAndDistribution & random) override;
51 
52  private:
54 
61  double gbteth(double ener,double partm,double efrac, const RandomEngineAndDistribution & random) const;
62 
64  double Z_;
65  };
66 }
67 
69  : fastsim::InteractionModel(name)
70 {
71  // Set the minimal photon energy for possible conversion
72  minPhotonEnergy_ = cfg.getParameter<double>("photonEnergyCut");
73  // Material properties
74  Z_ = cfg.getParameter<double>("Z");
75 }
76 
77 
78 void fastsim::PairProduction::interact(fastsim::Particle & particle, const SimplifiedGeometry & layer,std::vector<std::unique_ptr<fastsim::Particle> > & secondaries,const RandomEngineAndDistribution & random)
79 {
80 
81  double eGamma = particle.momentum().e();
82  //
83  // only consider photons
84  //
85  if(particle.pdgId()!=22)
86  {
87  return;
88  }
89 
90  double radLengths = layer.getThickness(particle.position(),particle.momentum());
91  //
92  // no material
93  //
94  if(radLengths < 1E-10)
95  {
96  return;
97  }
98 
99  //
100  // The photon has enough energy to create a pair
101  //
102  if (eGamma < minPhotonEnergy_)
103  {
104  return;
105  }
106 
107  //
108  // Probability to convert is 7/9*(dx/X0)
109  //
110  if(-std::log(random.flatShoot()) > (7./9.)*radLengths)
111  {
112  return;
113  }
114 
115  double xe=0;
117  double xm=eMass/eGamma;
118  double weight = 0.;
119 
120  // Generate electron energy between emass and eGamma-emass
121  do{
122  xe = random.flatShoot()*(1.-2.*xm) + xm;
123  weight = 1. - 4./3.*xe*(1.-xe);
124  }while(weight < random.flatShoot());
125 
126  // the electron
127  double eElectron = xe * eGamma;
128  double tElectron = eElectron-eMass;
129  double pElectron = std::sqrt(std::max((eElectron+eMass)*tElectron,0.));
130 
131  // the positron
132  double ePositron = eGamma-eElectron;
133  double tPositron = ePositron-eMass;
134  double pPositron = std::sqrt((ePositron+eMass)*tPositron);
135 
136  // Generate angles
137  double phi = random.flatShoot()*2.*M_PI;
138  double sphi = std::sin(phi);
139  double cphi = std::cos(phi);
140 
141  double stheta1, stheta2, ctheta1, ctheta2;
142 
143  if(eElectron > ePositron){
144  double theta1 = gbteth(eElectron,eMass,xe,random)*eMass/eElectron;
145  stheta1 = std::sin(theta1);
146  ctheta1 = std::cos(theta1);
147  stheta2 = stheta1*pElectron/pPositron;
148  ctheta2 = std::sqrt(std::max(0.,1.0-(stheta2*stheta2)));
149  }else{
150  double theta2 = gbteth(ePositron,eMass,xe,random)*eMass/ePositron;
151  stheta2 = std::sin(theta2);
152  ctheta2 = std::cos(theta2);
153  stheta1 = stheta2*pPositron/pElectron;
154  ctheta1 = std::sqrt(std::max(0.,1.0-(stheta1*stheta1)));
155  }
156 
157  //Rotate to the lab frame
158  double thetaLab = particle.momentum().Theta();
159  double phiLab = particle.momentum().Phi();
160 
161  // Add a electron
162  secondaries.emplace_back(new fastsim::Particle(11,particle.position(),
163  math::XYZTLorentzVector(pElectron*stheta1*cphi,
164  pElectron*stheta1*sphi,
165  pElectron*ctheta1,
166  eElectron)));
167  secondaries.back()->momentum() = ROOT::Math::RotationZ(phiLab)*(ROOT::Math::RotationY(thetaLab)*secondaries.back()->momentum());
168 
169  // Add a positron
170  secondaries.emplace_back(new fastsim::Particle(-11,particle.position(),
171  math::XYZTLorentzVector(-pPositron*stheta2*cphi,
172  -pPositron*stheta2*sphi,
173  pPositron*ctheta2,
174  ePositron)));
175  secondaries.back()->momentum() = ROOT::Math::RotationZ(phiLab)*(ROOT::Math::RotationY(thetaLab)*secondaries.back()->momentum());
176 
177  // The photon converted
178  particle.momentum().SetXYZT(0.,0.,0.,0.);
179 }
180 
181 double
183  const double partm,
184  const double efrac,
185  const RandomEngineAndDistribution & random) const
186 {
187  // Details on implementation here
188  // http://www.dnp.fmph.uniba.sk/cernlib/asdoc/geant_html3/node299.html#GBTETH
189  // http://svn.cern.ch/guest/AliRoot/tags/v3-07-03/GEANT321/gphys/gbteth.F
190 
191  const double alfa = 0.625;
192 
193  const double d = 0.13*(0.8+1.3/Z_)*(100.0+(1.0/ener))*(1.0+efrac);
194  const double w1 = 9.0/(9.0+d);
195  const double umax = ener*M_PI/partm;
196  double u;
197 
198  do
199  {
200  double beta = (random.flatShoot()<=w1) ? alfa : 3.0*alfa;
201  u = -std::log(random.flatShoot()*random.flatShoot())/beta;
202  }while (u>=umax);
203 
204  return u;
205 }
206 
207 
211  "fastsim::PairProduction"
212  );
const double beta
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
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
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
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
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
Computes the probability for photons to convert into an e+e- pair in the tracker layer.
#define M_PI
PairProduction(const std::string &name, const edm::ParameterSet &cfg)
Constructor.
virtual const double getThickness(const math::XYZTLorentzVector &position) const =0
Return thickness of the layer at a given position.
double minPhotonEnergy_
Cut on minimum energy of photons.
const math::XYZTLorentzVector & momentum() const
Return momentum of the particle.
Definition: Particle.h:145
~PairProduction() override
Default destructor.
#define DEFINE_EDM_PLUGIN(factory, type, name)
void interact(fastsim::Particle &particle, const SimplifiedGeometry &layer, std::vector< std::unique_ptr< fastsim::Particle > > &secondaries, const RandomEngineAndDistribution &random) override
Perform the interaction.
Definition of a generic FastSim Particle which can be propagated through the detector (formerly Parti...
Definition: Particle.h:19
double gbteth(double ener, double partm, double efrac, const RandomEngineAndDistribution &random) const
A universal angular distribution.