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