ATLAS Offline Software
Toggle main menu visibility
Loading...
Searching...
No Matches
Generators
Pythia8_i
src
UserHooks
suep_shower.cxx
Go to the documentation of this file.
1
/*
2
* This file is taken from the available public code at:
3
* https://gitlab.com/simonknapen/suep_generator
4
* by Simon Knapen.
5
*/
6
#include "
suep_shower.h
"
7
#include <functional>
// for bind()
8
#include <boost/math/tools/roots.hpp>
9
10
using namespace
boost::math::tools;
// For bracket_and_solve_root.
11
// using namespace std;
12
using namespace
Pythia8
;
13
14
// constructor
15
Suep_shower::Suep_shower
(
double
mass,
double
temperature,
double
energy, Pythia8::Rndm *rndm) {
16
m_m
= mass;
17
m_Temp
=temperature;
18
m_Etot
=energy;
19
m_rndmEngine
= rndm;
20
21
m_A
=
m_m
/
m_Temp
;
22
m_p_m
=std::sqrt(2/(
m_A
*
m_A
)*(1+std::sqrt(1+
m_A
*
m_A
)));
23
24
double
pmax=std::sqrt(2+2*std::sqrt(1+
m_A
*
m_A
))/
m_A
;
// compute the location of the maximum, to split the range
25
26
tolerance
tol = 0.00001;
27
m_p_plus
= (bisect(std::bind(&
Suep_shower::test_fun
,
this
, std::placeholders::_1),pmax,50.0, tol)).first;
// first root
28
m_p_minus
= (bisect(std::bind(&
Suep_shower::test_fun
,
this
, std::placeholders::_1), 0.0,pmax, tol)).first;
// second root
29
m_lambda_plus
= -
f
(
m_p_plus
)/
fp
(
m_p_plus
);
30
m_lambda_minus
=
f
(
m_p_minus
)/
fp
(
m_p_minus
);
31
m_q_plus
=
m_lambda_plus
/ (
m_p_plus
-
m_p_minus
);
32
m_q_minus
=
m_lambda_minus
/ (
m_p_plus
-
m_p_minus
);
33
m_q_m
= 1- (
m_q_plus
+
m_q_minus
);
34
35
}
36
37
// maxwell-boltzman distribution, slightly massaged
38
double
Suep_shower::f
(
double
p){
39
return
p*p*exp(-
m_A
*p*p/(1+std::sqrt(1+p*p)));
40
}
41
42
// derivative of maxwell-boltzmann
43
double
Suep_shower::fp
(
double
p){
44
return
exp(-
m_A
*p*p/(1+std::sqrt(1+p*p)))*p*(2-
m_A
*p*p/std::sqrt(1+p*p));
45
}
46
47
// test function to be solved for m_p_plus, m_p_minus
48
double
Suep_shower::test_fun
(
double
p){
49
return
log(
f
(p)/
f
(
m_p_m
))+1.0;
50
}
51
52
// generate one random 4 vector from the thermal distribution
53
Vec4
Suep_shower::generateFourVector
(){
54
55
Vec4 fourvec;
56
double
en,
phi
,
theta
, p;
//kinematic variables of the 4 vector
57
58
// first do momentum, following arxiv:1305.5226
59
double
U(0.0), V(0.0), X(0.0), Y(0.0), E(0.0);
60
int
i=0;
61
while
(i<100){
62
if
(
m_rndmEngine
) {
63
U =
m_rndmEngine
->flat();
64
V =
m_rndmEngine
->flat();
65
}
else
{
66
U = ((double) rand() / RAND_MAX);
67
V = ((double) rand() / RAND_MAX);
68
}
69
70
if
(U <
m_q_m
){
71
Y=U/
m_q_m
;
72
X=( 1 - Y )*(
m_p_minus
+
m_lambda_minus
)+Y*(
m_p_plus
-
m_lambda_plus
);
73
if
(V <
f
(X) /
f
(
m_p_m
) && X>0){
74
break
;
75
}
76
}
77
else
{
if
(U <
m_q_m
+
m_q_plus
){
78
E = -log((U-
m_q_m
)/
m_q_plus
);
79
X =
m_p_plus
-
m_lambda_plus
*(1-E);
80
if
(V<exp(E)*
f
(X)/
f
(
m_p_m
) && X>0){
81
break
;
82
}
83
}
84
else
{
85
E = - log((U-(
m_q_m
+
m_q_plus
))/
m_q_minus
);
86
X =
m_p_minus
+
m_lambda_minus
* (1 - E);
87
if
(V < exp(E)*
f
(X)/
f
(
m_p_m
) && X>0){
88
break
;
89
}
90
}
91
}
92
}
93
p=X*(this->
m_m
);
// X is the dimensionless momentum, p/m
94
95
// now do the angles
96
if
(
m_rndmEngine
) {
97
phi
= 2.0*
M_PI
*(
m_rndmEngine
->flat());
98
theta
= acos(2.0*
m_rndmEngine
->flat()-1.0);
99
}
else
{
100
//coverity[DC.WEAK_CRYPTO]
101
phi
= 2.0*
M_PI
*((double) rand() / RAND_MAX);
102
//coverity[DC.WEAK_CRYPTO]
103
theta
= acos(2.0*((
double
) rand() / RAND_MAX)-1.0);
104
}
105
106
// compose the 4 vector
107
en = std::sqrt(p*p+(this->
m_m
)*(this->
m_m
));
108
//coverity[COPY_PASTE_ERROR]
109
fourvec.p(p*cos(
phi
)*sin(
theta
), p*sin(
phi
)*sin(
theta
), p*cos(
theta
), en);
110
111
return
fourvec;
112
}
113
114
// auxiliary function which computes the total energy difference as a function of the momentum vectors and a scale factor "a"
115
// to ballance energy, we solve for "a" by demanding that this function vanishes
116
// By rescaling the momentum rather than the energy, I avoid having to do these annoying rotations from the previous version
117
double
Suep_shower::reballance_func
(
double
a
,
const
vector< Vec4 > &event){
118
double
result =0.0;
119
double
p2;
120
for
(
unsigned
n = 0; n<
event
.size();n++){
121
p2 =
event
[n].px()*
event
[n].px() +
event
[n].py()*
event
[n].py() +
event
[n].pz()*
event
[n].pz();
122
result += std::sqrt(
a
*
a
*p2 + (this->
m_m
)* (this->
m_m
));
123
}
124
return
result - (this->
m_Etot
);
125
}
126
127
// generate a shower event, in the rest frame of the shower
128
vector< Vec4 >
Suep_shower::generate_shower
(){
129
130
vector< Vec4 > event;
131
double
sum_E = 0.0;
132
133
// fill up event record
134
while
(sum_E<(this->
m_Etot
)){
135
event
.push_back(this->
generateFourVector
());
136
sum_E += (
event
.back()).e();
137
}
138
139
// reballance momenta
140
int
len =
event
.size();
141
double
sum_p, correction;
142
for
(
int
i = 1;i<4;i++){
// loop over 3 carthesian directions
143
144
sum_p = 0.0;
145
for
(
int
n=0;n<len;n++){
146
sum_p+=
event
[n][i];
147
}
148
correction=-1.0*sum_p/len;
149
150
for
(
int
n=0;n<len;n++){
151
event
[n][i] += correction;
152
}
153
}
154
155
//Shield against an exception in the calculation of "p_scale" further down. If it fails, abort the event.
156
if
(
Suep_shower::reballance_func
(2.0,event)<0.0){
157
// failed to balance energy.
158
event
.clear();
159
return
event;
160
}
161
162
// finally, ballance the total energy, without destroying momentum conservation
163
tolerance
tol = 0.00001;
164
double
p_scale;
165
try
{
166
p_scale = (bisect(std::bind(&
Suep_shower::reballance_func
,
this
, std::placeholders::_1, event),0.0,2.0, tol)).first;
167
}
catch
(std::exception &e) {
168
//in some rare circumstances, this balancing might fail
169
std::cout <<
"[SUEP_SHOWER] WARNING: Failed to rebalance the following event; Printing for debug and throw exception"
<< std::endl;
170
std::cout << e.what() << std::endl;
171
std::cout <<
"N. Particle, px, py, pz, E"
<< std::endl;
172
for
(
size_t
jj=0; jj <
event
.size(); jj++) {
173
//print out event
174
std::cout << jj <<
": "
<<
event
[jj].px() <<
", "
<<
event
[jj].py() <<
", "
<<
event
[jj].pz() <<
", "
<<
event
[jj].e() << std::endl;
175
}
176
throw
e;
177
}
178
179
for
(
int
n=0;n<len;n++){
180
event
[n].px(p_scale*event[n].px());
181
event
[n].py(p_scale*event[n].py());
182
event
[n].pz(p_scale*event[n].pz());
183
// force the energy with the on-shell condition
184
event
[n].e(std::sqrt(event[n].px()*event[n].px() + event[n].py()*event[n].py() + event[n].pz()*event[n].pz() + (this->
m_m
)*(this->
m_m
)));
185
}
186
187
return
event;
188
}
M_PI
#define M_PI
Definition
ActiveFraction.h:14
phi
Scalar phi() const
phi method
Definition
AmgMatrixBasePlugin.h:67
theta
Scalar theta() const
theta method
Definition
AmgMatrixBasePlugin.h:75
a
static Double_t a
Definition
LArPhysWaveHECTool.cxx:38
Suep_shower::Suep_shower
Suep_shower(double mass, double temperature, double energy, Pythia8::Rndm *rndm=0)
Constructor.
Definition
suep_shower.cxx:15
Suep_shower::test_fun
double test_fun(double p)
Test function to be solved for p_plus,p_minus.
Definition
suep_shower.cxx:48
Suep_shower::m_p_m
double m_p_m
convenience function of mass/Temperature ratio
Definition
suep_shower.h:81
Suep_shower::fp
double fp(double p)
Derivative of Maxwell-Boltzmann.
Definition
suep_shower.cxx:43
Suep_shower::m_q_plus
double m_q_plus
solutions for shower generation.
Definition
suep_shower.h:87
Suep_shower::m_p_minus
double m_p_minus
Definition
suep_shower.h:83
Suep_shower::generateFourVector
Pythia8::Vec4 generateFourVector()
generate one random 4 vector from the thermal distribution
Definition
suep_shower.cxx:53
Suep_shower::m_q_minus
double m_q_minus
Definition
suep_shower.h:87
Suep_shower::m_m
double m_m
Mass of the dark mesons to be generated in the shower.
Definition
suep_shower.h:51
Suep_shower::m_rndmEngine
Pythia8::Rndm * m_rndmEngine
Random number generator, if not provided will use rand().
Definition
suep_shower.h:48
Suep_shower::m_p_plus
double m_p_plus
solutions for shower generation.
Definition
suep_shower.h:83
Suep_shower::f
double f(double p)
Maxwell-Boltzman distribution, slightly massaged.
Definition
suep_shower.cxx:38
Suep_shower::m_lambda_minus
double m_lambda_minus
Definition
suep_shower.h:85
Suep_shower::m_Etot
double m_Etot
Total energy of the system.
Definition
suep_shower.h:57
Suep_shower::m_Temp
double m_Temp
Temperature parameter.
Definition
suep_shower.h:54
Suep_shower::m_lambda_plus
double m_lambda_plus
solutions in Lambda for shower generation
Definition
suep_shower.h:85
Suep_shower::generate_shower
std::vector< Pythia8::Vec4 > generate_shower()
Generate a shower event, in the rest frame of the showe.
Definition
suep_shower.cxx:128
Suep_shower::m_q_m
double m_q_m
Definition
suep_shower.h:87
Suep_shower::reballance_func
double reballance_func(double a, const std::vector< Pythia8::Vec4 > &event)
auxiliary function which computes the total energy difference as a function of the momentum vectors a...
Definition
suep_shower.cxx:117
Suep_shower::m_A
double m_A
mass/Temperature ratio
Definition
suep_shower.h:79
tolerance
Definition
suep_shower.h:15
Pythia8
Author: James Monk (jmonk@cern.ch).
Definition
IPythia8Custom.h:10
suep_shower.h
Generated on
for ATLAS Offline Software by
1.17.0