CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
MuonBremsstrahlungSimulator.cc
Go to the documentation of this file.
1 //MuonBremsstrahlungSimulator
3 // Description: Implementation of Muon bremsstrahlung using the Petrukhin model
4 //Authors :Sandro Fonseca de Souza and Andre Sznajder (UERJ/Brazil)
5 // Date: 23-Nov-2010
12 
13 #include <cmath>
14 #include <string>
15 #include <iostream>
16 
17 #include "TF1.h"
18 
21  double A, double Z, double density, double radLen, double photonEnergyCut, double photonFractECut)
22  : MaterialEffectsSimulator(A, Z, density, radLen) {
23  // Set the minimal photon energy for a Brem from mu+/-
24  photonEnergy = photonEnergyCut;
25  photonFractE = photonFractECut;
26  d = 0.; //distance
27  LogDebug("MuonBremsstrahlungSimulator") << "Starting the MuonBremsstrahlungSimulator" << std::endl;
28 }
29 
32  double NA = 6.022e+23; //Avogadro's number
33 
34  if (radLengths > 4.) {
35  Particle.particle().setMomentum(0., 0., 0., 0.);
36  deltaPMuon.SetXYZT(0., 0., 0., 0.);
37  brem_photon.SetXYZT(0., 0., 0., 0.);
38  }
39 
40  // Hard brem probability with a photon Energy above photonEnergy.
41 
42  double EMuon = Particle.particle().e(); //Muon Energy
43  if (EMuon < photonEnergy)
44  return;
45  xmin = std::max(photonEnergy / EMuon, photonFractE); //fraction of muon's energy transferred to the photon
46 
47  // xmax = photonEnergy/Particle.particle().e();
48  if (xmin >= 1. || xmin <= 0.)
49  return;
50 
51  xmax = 1.;
52  npar = 3; //Number of parameters
53 
54  // create TF1 using a free C function
55  f1 = new TF1("f1", PetrukhinFunc, xmin, xmax, npar);
56  //Setting parameters
57  f1->SetParameters(EMuon, A, Z);
59  //d = distance for several materials
60  //X0 = radLen
61  //d = radLengths * X0(for tracker,yoke,ECAL and HCAL)
62  d = radLengths * radLen;
63  //Integration
64  bremProba = density * d * (NA / A) * (f1->Integral(0., 1.));
65 
66  // Number of photons to be radiated.
67  unsigned int nPhotons = random->poissonShoot(bremProba);
68  _theUpdatedState.reserve(nPhotons);
69 
70  if (!nPhotons)
71  return;
72 
73  //Rotate to the lab frame
74  double chi = Particle.particle().theta();
75  double psi = Particle.particle().phi();
76  RawParticle::RotationZ rotZ(psi);
77  RawParticle::RotationY rotY(chi);
78 
79  // Energy of these photons
80  for (unsigned int i = 0; i < nPhotons; ++i) {
81  // Check that there is enough energy left.
82  if (Particle.particle().e() < photonEnergy)
83  break;
84  LogDebug("MuonBremsstrahlungSimulator") << "MuonBremsstrahlungSimulator parameters:" << std::endl;
85  LogDebug("MuonBremsstrahlungSimulator") << "xmin-> " << xmin << std::endl;
86  LogDebug("MuonBremsstrahlungSimulator") << "Atomic Weight-> " << A << std::endl;
87  LogDebug("MuonBremsstrahlungSimulator") << "Density-> " << density << std::endl;
88  LogDebug("MuonBremsstrahlungSimulator") << "Distance-> " << d << std::endl;
89  LogDebug("MuonBremsstrahlungSimulator") << "bremProba->" << bremProba << std::endl;
90  LogDebug("MuonBremsstrahlungSimulator") << "nPhotons->" << nPhotons << std::endl;
91  LogDebug("MuonBremsstrahlungSimulator") << " Muon_Energy-> " << EMuon << std::endl;
92  LogDebug("MuonBremsstrahlungSimulator") << "X0-> " << radLen << std::endl;
93  LogDebug("MuonBremsstrahlungSimulator") << " radLengths-> " << radLengths << std::endl;
94 
95  // Add a photon
96  RawParticle thePhoton = makeParticle(Particle.particleDataTable(), 22, brem(Particle, random));
97  if (thePhoton.E() > 0.) {
98  thePhoton.rotate(rotY);
99  thePhoton.rotate(rotZ);
100 
101  _theUpdatedState.push_back(thePhoton);
102 
103  // Update the original mu +/-
104  deltaPMuon = Particle.particle().momentum() -= thePhoton.momentum();
105  // Information of brem photon
106  brem_photon.SetXYZT(thePhoton.Px(), thePhoton.Py(), thePhoton.Pz(), thePhoton.E());
107 
108  LogDebug("MuonBremsstrahlungSimulator") << " Muon Bremsstrahlung: photon_energy-> " << thePhoton.E() << std::endl;
109  LogDebug("MuonBremsstrahlungSimulator") << "photon_px->" << thePhoton.Px() << std::endl;
110  LogDebug("MuonBremsstrahlungSimulator") << "photon_py->" << thePhoton.Py() << std::endl;
111  LogDebug("MuonBremsstrahlungSimulator") << "photon_pz->" << thePhoton.Pz() << std::endl;
112  }
113  }
114 }
117  RandomEngineAndDistribution const* random) const {
118  // This is a simple version of a Muon Brem using Petrukhin model .
119  //Ref: http://pdg.lbl.gov/2008/AtomicNuclearProperties/adndt.pdf
120  double mumass = 0.105658367; //mu mass (GeV/c^2)
121 
122  // RANDOM_NUMBER_ERROR
123  // Random number should be generated by the engines from the
124  // RandomNumberGeneratorService. This appears to use the global
125  // engine in ROOT. This is not thread safe unless the module using
126  // it is a one module and declares a shared resource and all
127  // other modules using it also declare the same shared resource.
128  // This also breaks replay.
129  // It might be that this is never used because of the std::cout
130  // statement 2 lines below. I've never seen or heard complaints
131  // about that vebosity ....
132  double xp = f1->GetRandom();
133  LogDebug("MuonBremsstrahlungSimulator") << "MuonBremsstrahlungSimulator: xp->" << xp << std::endl;
134  std::cout << "MuonBremsstrahlungSimulator: xp->" << xp << std::endl;
135 
136  // Have photon energy. Now generate angles with respect to the z axis
137  // defined by the incoming particle's momentum.
138 
139  // Isotropic in phi
140  const double phi = random->flatShoot() * 2 * M_PI;
141  // theta from universal distribution
142  const double theta = gbteth(pp.particle().e(), mumass, xp, random) * mumass / pp.particle().e();
143 
144  // Make momentum components
145  double stheta = std::sin(theta);
146  double ctheta = std::cos(theta);
147  double sphi = std::sin(phi);
148  double cphi = std::cos(phi);
149 
150  return xp * pp.particle().e() * XYZTLorentzVector(stheta * cphi, stheta * sphi, ctheta, 1.);
151 }
153 double MuonBremsstrahlungSimulator::gbteth(const double ener,
154  const double partm,
155  const double efrac,
156  RandomEngineAndDistribution const* random) const {
157  const double alfa = 0.625;
158 
159  const double d = 0.13 * (0.8 + 1.3 / theZ()) * (100.0 + (1.0 / ener)) * (1.0 + efrac);
160  const double w1 = 9.0 / (9.0 + d);
161  const double umax = ener * M_PI / partm;
162  double u;
163 
164  do {
165  double beta = (random->flatShoot() <= w1) ? alfa : 3.0 * alfa;
166  u = -std::log(random->flatShoot() * random->flatShoot()) / beta;
167  } while (u >= umax);
168 
169  return u;
170 }
static double constexpr NA
Avogadro&#39;s number.
Definition: Constants.h:16
void setMomentum(const XYZTLorentzVector &vtx)
set the momentum
Definition: RawParticle.h:328
const HepPDT::ParticleDataTable * particleDataTable() const
static std::vector< std::string > checklist log
double flatShoot(double xmin=0.0, double xmax=1.0) const
tuple pp
Definition: createTree.py:17
double gbteth(const double ener, const double partm, const double efrac, RandomEngineAndDistribution const *) const
A universal angular distribution - still from GEANT.
double PetrukhinFunc(double *x, double *p)
double xmin
The fractional photon energy cut (determined from the above two)
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
Geom::Theta< T > theta() const
void compute(ParticlePropagator &Particle, RandomEngineAndDistribution const *) override
Generate Bremsstrahlung photons.
RawParticle const & particle() const
The particle being propagated.
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
double phi() const
phi of momentum vector
Definition: RawParticle.h:316
const XYZTLorentzVector & momentum() const
the momentum fourvector
Definition: RawParticle.h:321
double e() const
energy of the momentum
Definition: RawParticle.h:305
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
double Py() const
y of the momentum
Definition: RawParticle.h:300
ROOT::Math::RotationY RotationY
Definition: RawParticle.h:47
void rotate(double rphi, const XYZVector &raxis)
Definition: RawParticle.cc:41
double Pz() const
z of the momentum
Definition: RawParticle.h:303
#define M_PI
MuonBremsstrahlungSimulator(double A, double Z, double density, double radLen, double photonEnergyCut, double photonFractECut)
Constructor.
double photonFractE
The minimum photon fractional energy (wrt that of the electron)
double theta() const
theta of momentum vector
Definition: RawParticle.h:315
std::vector< RawParticle > _theUpdatedState
double Px() const
x of the momentum
Definition: RawParticle.h:297
unsigned int poissonShoot(double mean) const
double E() const
energy of the momentum
Definition: RawParticle.h:306
XYZTLorentzVector brem(ParticlePropagator &p, RandomEngineAndDistribution const *) const
Compute Brem photon energy and angles, if any.
tuple cout
Definition: gather_cfg.py:144
double photonEnergy
The minimum photon energy to be radiated, in GeV.
math::XYZTLorentzVector XYZTLorentzVector
Definition: RawParticle.h:25
#define LogDebug(id)