CMS 3D CMS Logo

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)
23  // Set the minimal photon energy for a Brem from mu+/-
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();
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 }
XYZTLorentzVector brem(ParticlePropagator &p, RandomEngineAndDistribution const *) const
Compute Brem photon energy and angles, if any.
double Pz() const
z of the momentum
Definition: RawParticle.h:303
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
double E() const
energy of the momentum
Definition: RawParticle.h:306
void compute(ParticlePropagator &Particle, RandomEngineAndDistribution const *) override
Generate Bremsstrahlung photons.
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
double Py() const
y of the momentum
Definition: RawParticle.h:300
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
ROOT::Math::RotationY RotationY
Definition: RawParticle.h:47
void rotate(double rphi, const XYZVector &raxis)
Definition: RawParticle.cc:41
#define M_PI
MuonBremsstrahlungSimulator(double A, double Z, double density, double radLen, double photonEnergyCut, double photonFractECut)
Constructor.
unsigned int poissonShoot(double mean) const
double photonFractE
The minimum photon fractional energy (wrt that of the electron)
std::vector< RawParticle > _theUpdatedState
double photonEnergy
The minimum photon energy to be radiated, in GeV.
Definition: APVGainStruct.h:7
double flatShoot(double xmin=0.0, double xmax=1.0) const
double gbteth(const double ener, const double partm, const double efrac, RandomEngineAndDistribution const *) const
A universal angular distribution - still from GEANT.
Geom::Theta< T > theta() const
math::XYZTLorentzVector XYZTLorentzVector
Definition: RawParticle.h:25
const double NA
Definition: ZdcSD.cc:353
double Px() const
x of the momentum
Definition: RawParticle.h:297
#define LogDebug(id)