9#include <generators/bbbrem/BBBrem.h>
10#include <framework/logging/Logger.h>
11#include <framework/gearbox/Const.h>
12#include <mdst/dataobjects/MCParticleGraph.h>
21void BBBrem::init(
double cmsEnergy,
double minPhotonEFrac,
bool unweighted,
double maxWeight,
int densitymode,
22 double densityparameter)
37 if ((minPhotonEFrac <= 0.0) || (minPhotonEFrac >= 1.0)) {
38 B2ERROR(
"BBBrem: The minimum photon energy fraction has to be in the range ]0,1[ !");
42 B2DEBUG(100,
"BBBrem: Center of mass energy: " << cmsEnergy);
43 B2DEBUG(100,
"BBBrem: Minimum photon energy: " << minPhotonEFrac <<
" * beam energy");
50 s = cmsEnergy * cmsEnergy;
54 z0 = minPhotonEFrac / (1.0 - minPhotonEFrac);
63 B2DEBUG(100,
"BBBrem: Approximate cross section: " <<
sigapp <<
" millibarn");
98 ran = gRandom->Uniform();
114 bool swapflag = (gRandom->Uniform() > 0.5) ?
true :
false;
117 for (
int i = 0; i < 4; i++) tmp[i] =
p2[i];
118 for (
int i = 0; i < 4; i++)
p2[i] =
q2[i];
119 for (
int i = 0; i < 4; i++)
q2[i] = tmp[i];
159 if (gRandom->Uniform() <
ac) {
160 double temp1 = gRandom->Uniform();
163 z = 1.0 / (temp1 * (expm1(
a1 * gRandom->Uniform())));
165 z =
z0 / gRandom->Uniform();
169 double y =
rme2s * z;
171 double temp1 =
pb *
pb -
eb * q0;
172 double temp2 = temp1 * temp1 -
rme2 - q0 * q0;
176 B2WARNING(
"BBBrem: y too large: delta_t^2 = " << temp2 <<
" !!!");
179 double tmin = -2.0 * (temp1 +
sqrt(temp2));
180 double tmax =
rme2 *
s * y * y / tmin;
184 double w2 = sy +
rme2;
186 double rlamx =
sqrt(temp1 * temp1 - 4.0 * w2 * tmax);
189 temp1 = rlamx - temp1;
191 temp1 = -4.0 * w2 * tmax / (rlamx + temp1);
199 b = exp(gRandom->Uniform() * log1p(2.0 * sy / temp1));
200 t = -b * z * z *
rme2 / ((b - 1) * (b * z + b - 1));
204 double rlam =
sqrt((sy - t) * (sy - t) - 4 *
rme2 * t);
205 double eps = 4 *
rme2 * w2 / (rlam * (rlam + w2 +
rme2 - t));
206 double rl = log((2 + eps) / eps);
209 double vgam = eps * (expm1(gRandom->Uniform() * rl));
210 double cgam = 1.0 - vgam;
211 double sgam =
sqrt(vgam * (2 - vgam));
214 double phi =
twopi * gRandom->Uniform();
215 double phig =
twopi * gRandom->Uniform();
218 double ql = (2.0 *
eb * q0 - t) *
rin2pb;
219 double qt =
sqrt((tmax - t) * (t - tmin)) *
rin2pb;
221 q[0] = qt * sin(phi);
222 q[1] = qt * cos(phi);
227 q2[0] =
q1[0] - q[0];
228 q2[1] =
q1[1] - q[1];
229 q2[2] =
q1[2] - q[2];
230 q2[3] =
q1[3] - q[3];
235 double rin2w = 0.5 / w;
236 double rinr0w = 1.0 / (r0 + w);
237 double eta = -(sy + 2 * w * q0 + t) * rin2w * rinr0w;
238 double phat1 = -q[0] * (1 + eta);
239 double phat2 = -q[1] * (1 + eta);
240 double phat3 =
pb * eta - ql * (1 + eta);
241 double phatl = rlam * rin2w;
242 double phatt =
sqrt(phat1 * phat1 + phat2 * phat2);
243 double sfhat = phat1 / phatt;
244 double cfhat = phat2 / phatt;
245 double sthat = phatt / phatl;
248 vthat = sthat * sthat / (1 -
sqrt(1 - sthat * sthat));
250 vthat = sthat * sthat / (1 +
sqrt(1 - sthat * sthat));
252 double cthat = vthat - 1.0;
255 double sfg = sin(phig);
256 double cfg = cos(phig);
258 temp2 = cthat * sgam * cfg + sthat * cgam;
259 double veg = vthat + vgam - vthat * vgam - sthat * sgam * cfg;
261 qkhat[3] = sy * rin2w;
262 qkhat[0] = qkhat[3] * (cfhat * temp1 + sfhat * temp2);
263 qkhat[1] = qkhat[3] * (-sfhat * temp1 + cfhat * temp2);
264 qkhat[2] = qkhat[3] * (veg - 1.0);
267 temp1 =
pb * qkhat[2];
269 temp2 = (
rme2 * qkhat[3] * qkhat[3] +
pb *
pb * (qkhat[0] * qkhat[0] + qkhat[1] * qkhat[1])) / (
eb * qkhat[3] + temp1);
271 temp2 =
eb * qkhat[3] - temp1;
274 qk[3] = (temp2 + qkhat[3] * q[3] + qkhat[0] * q[0] + qkhat[1] * q[1] + qkhat[2] * q[2]) / w;
275 temp1 = (
qk[3] + qkhat[3]) * rinr0w;
276 qk[0] = qkhat[0] + temp1 * q[0];
277 qk[1] = qkhat[1] + temp1 * q[1];
278 qk[2] = qkhat[2] + temp1 * (-
pb + ql);
294 double c1 = log1p(z) / log((2.0 + eps) / eps);
298 double vnumx =
sqrt(temp1 * temp1 - 4.0 *
rme2 * tmax) + temp1;
303 vdenx =
sqrt(temp1 * temp1 - 4.0 * w2 * tmax) - temp1;
305 vdenx = -4.0 * w2 * tmax / (
sqrt(temp1 * temp1 - 4.0 * w2 * tmax) + temp1);
308 double vnumn =
sqrt(temp1 * temp1 - 4.0 *
rme2 * tmin) + temp1;
313 vdenn =
sqrt(temp1 * temp1 - 4.0 * w2 * tmin) - temp1;
315 vdenn = -4.0 * w2 * tmin / (
sqrt(temp1 * temp1 - 4.0 * w2 * tmin) + temp1);
317 double c2 = 2.0 *
rls / log((vnumx * vdenn) / (vdenx * vnumn));
321 double rhat4 = -(2.0 *
rme2 * y + (1 - y) * t) * rin2w;
322 double etar = rhat4 * rinr0w;
323 double rhat1 = -q[0] * (1 + etar);
324 double rhat2 = -q[1] * (1 + etar);
325 double rhat3 = rlabl + (
pb - ql) * etar;
326 double zz =
s * (rhat4 * qkhat[3] - rhat1 * qkhat[0] - rhat2 * qkhat[1] - rhat3 * qkhat[2]);
329 double s1 = 4.0 *
eb * (
eb -
qk[3]);
330 double d1 = sy * rlam * (eps + vgam) * rin2w * rin2w;
331 double d2 = 0.5 * sy;
335 double rind1 = 1.0 / d1;
336 double rind12 = rind1 * rind1;
337 double rind2 = 1.0 / d2;
338 double rind22 = rind2 * rind2;
339 temp1 =
s + t - 2 * d2;
340 temp2 = s1 + t + 2 * d1;
341 double aa0 = (
s *
s + s1 * s1 + temp1 * temp1 + temp2 * temp2) * rind1 * rind2 * (-t);
342 double aa1 = -4.0 *
rme2 * zz * zz * rind12 * rind22;
343 double aa2 = -8.0 *
rme2 * (d1 * d1 + d2 * d2) * rind1 * rind2;
344 double aa3 = 16.0 *
rme2 *
rme2 * (d1 - d2) * zz * rind12 * rind22;
345 double aa4 = -16.0 *
rme2 *
rme2 *
rme2 * (d1 - d2) * (d1 - d2) * rind12 * rind22;
346 double rmex = aa0 + aa1 + aa2 + aa3 + aa4;
349 double rmap = 4.0 *
s *
s * rind1 * rind2 * (-t) * c1 * c2;
356 B2WARNING(
"BBBrem: Weight is nan! Setting the weight to zero.");
371 if (abs(t) < tc)
weight = 0.0;
373 if (t != tc)
weight *= t * t / (t - tc) / (t - tc);
383 ROOT::Math::LorentzRotation boost,
384 bool isVirtual,
bool isInitial)
391 }
else if (isInitial) {
399 if (pdg == 22 && !isVirtual) {
407 part.
setMomentum(ROOT::Math::XYZVector(mom[0], mom[1],
422 ROOT::Math::PxPyPzEVector p4 = part.
get4Vector();
long m_weightCountOver
Internal overweighted event counter.
double m_maxWeightDelivered
The maximum weight given by the BBBrem generation.
void storeParticle(MCParticleGraph &mcGraph, const double *mom, int pdg, ROOT::Math::XYZVector vertex, ROOT::Math::LorentzRotation boost, bool isVirtual=false, bool isInitial=false)
Store a single generated particle into the MonteCarlo graph.
double m_crossSection
The cross-section in millibarns.
bool m_unweighted
True if BBBrem should produce unweighted events.
double m_cmsEnergy
Center of mass energy (sqrt(s)).
double m_densityCorrectionParameter
Density correction parameter tc.
static constexpr double twopi
2*pi.
void calcOutgoingLeptonsAndWeight()
Calculate the outgoing leptons and the event weight for one single radiative Bhabha scattering.
long m_weightCount
Internal weighted event counter.
static constexpr double tomb
Conversion factor (hc)^2.
double m_sumWeightDeliveredOver
The sum of all overweights.
void term()
Terminates the generator.
double m_maxWeight
The maximum weight.
double generateEvent(MCParticleGraph &mcGraph, ROOT::Math::XYZVector vertex, ROOT::Math::LorentzRotation boost)
Generates one single event.
double m_sumWeightDelivered
The sum of all weights returned by the BBBrem generation.
void init(double cmsEnergy, double minPhotonEFrac, bool unweighted=true, double maxWeight=2000.0, int densitymode=1, double densityparameter=1.68e-17)
Initializes the generator.
double m_crossSectionError
The error on the cross-section in millibarns.
double m_sumWeightDeliveredSqrOver
The square of the sum of all overweights.
double m_sumWeightDeliveredSqr
The square of the sum of all weights returned by the BBBrem generation.
double m_photonEFrac
Minimum photon energy fraction.
int m_densityCorrectionMode
Mode for bunch density correction.
double m_crossSectionErrorOver
The overweight bias error on the cross-section in millibarns.
double m_crossSectionOver
The overweight bias cross-section in millibarns.
static const double electronMass
electron mass
static const double fineStrConst
The fine structure constant.
Class to represent Particle data in graph.
void setFirstDaughter(int daughter)
Set the 1-based index of the first daughter, 0 means no daughters.
void setLastDaughter(int daughter)
Set the 1-based index of the last daughter, 0 means no daughters.
Class to build, validate and sort a particle decay chain.
@ c_IsFSRPhoton
bit 7: Particle is from finial state radiation
@ c_Initial
bit 5: Particle is initial such as e+ or e- and not going to Geant4
@ c_PrimaryParticle
bit 0: Particle is primary particle.
@ c_IsVirtual
bit 4: Particle is virtual and not going to Geant4.
@ c_IsISRPhoton
bit 6: Particle is from initial state radiation
void addStatus(unsigned short int bitmask)
Add bitmask to current status.
void setEnergy(float energy)
Set energy.
ROOT::Math::XYZVector getProductionVertex() const
Return production vertex position.
void setValidVertex(bool valid)
Set indication wether vertex and time information is valid or just default.
void setProductionVertex(const ROOT::Math::XYZVector &vertex)
Set production vertex position.
ROOT::Math::PxPyPzEVector get4Vector() const
Return 4Vector of particle.
void setPDG(int pdg)
Set PDG code of the particle.
void set4Vector(const ROOT::Math::PxPyPzEVector &p4)
Sets the 4Vector of particle.
void setMomentum(const ROOT::Math::XYZVector &momentum)
Set particle momentum.
void setStatus(unsigned short int status)
Set Status code for the particle.
void setMassFromPDG()
Sets the mass for the particle from the particle's PDG code.
double sqrt(double a)
sqrt for double
GraphParticle & addParticle()
Add new particle to the graph.
Abstract base class for different kinds of events.