cepgen
is hosted by
Hepforge
,
IPPP Durham
CepGen
1.2.5
Central exclusive processes event generator
Loading...
Searching...
No Matches
Generator.cpp
Go to the documentation of this file.
1
/*
2
* CepGen: a central exclusive processes event generator
3
* Copyright (C) 2013-2024 Laurent Forthomme
4
*
5
* This program is free software: you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation, either version 3 of the License, or
8
* any later version.
9
*
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
14
*
15
* You should have received a copy of the GNU General Public License
16
* along with this program. If not, see <http://www.gnu.org/licenses/>.
17
*/
18
19
#include <chrono>
20
21
#include "
CepGen/Cards/Handler.h
"
22
#include "
CepGen/Core/Exception.h
"
23
#include "
CepGen/Core/GeneratorWorker.h
"
24
#include "
CepGen/Core/RunParameters.h
"
25
#include "
CepGen/EventFilter/EventExporter.h
"
26
#include "
CepGen/EventFilter/EventModifier.h
"
27
#include "
CepGen/Generator.h
"
28
#include "
CepGen/Integration/Integrator.h
"
29
#include "
CepGen/Integration/ProcessIntegrand.h
"
30
#include "
CepGen/Modules/CardsHandlerFactory.h
"
31
#include "
CepGen/Modules/GeneratorWorkerFactory.h
"
32
#include "
CepGen/Modules/IntegratorFactory.h
"
33
#include "
CepGen/Process/Process.h
"
34
#include "
CepGen/Utils/String.h
"
35
#include "
CepGen/Utils/TimeKeeper.h
"
36
37
namespace
cepgen
{
38
Generator::Generator
(
bool
safe_mode) : parameters_(new
RunParameters
) {
39
static
bool
init =
false
;
40
if
(!init) {
41
cepgen::initialise
(safe_mode);
42
init =
true
;
43
CG_DEBUG
(
"Generator:init"
) <<
"Generator initialised"
;
44
}
45
//--- random number initialization
46
std::chrono::system_clock::time_point time = std::chrono::system_clock::now();
47
srandom(time.time_since_epoch().count());
48
}
49
50
Generator::Generator
(
RunParameters
* ip) : parameters_(ip) {}
51
52
Generator::~Generator
() {
53
if
(parameters_->timeKeeper())
54
CG_INFO
(
"Generator:destructor"
) << parameters_->timeKeeper()->summary();
55
}
56
57
void
Generator::clearRun() {
58
CG_DEBUG
(
"Generator:clearRun"
) <<
"Run is set to be cleared."
;
59
worker_ = GeneratorWorkerFactory::get().build(parameters_->generation().parameters().get<
ParametersList
>(
"worker"
));
60
CG_DEBUG
(
"Generator:clearRun"
) <<
"Initialised a generator worker with parameters: "
<< worker_->parameters()
61
<<
"."
;
62
// destroy and recreate the integrator instance
63
resetIntegrator();
64
65
worker_->setRunParameters(
const_cast<
const
RunParameters
*
>
(parameters_.get()));
66
worker_->setIntegrator(integrator_.get());
67
xsect_ =
Value
{-1., -1.};
68
parameters_->prepareRun();
69
initialised_ =
false
;
70
}
71
72
void
Generator::parseRunParameters
(
const
std::string& filename) {
73
setRunParameters
(
CardsHandlerFactory::get
().buildFromFilename(filename)->parseFile(filename).
runParameters
());
74
}
75
76
const
RunParameters
&
Generator::runParameters
()
const
{
77
if
(!parameters_)
78
throw
CG_FATAL
(
"Generator:runParameters"
) <<
"Run parameters object is not yet initialised."
;
79
return
*parameters_;
80
}
81
82
RunParameters
&
Generator::runParameters
() {
83
if
(!parameters_)
84
throw
CG_FATAL
(
"Generator:runParameters"
) <<
"Run parameters object is not yet initialised."
;
85
return
*parameters_;
86
}
87
88
void
Generator::setRunParameters
(std::unique_ptr<RunParameters>& ip) { parameters_ = std::move(ip); }
89
90
double
Generator::computePoint
(
const
std::vector<double>& coord) {
91
if
(!worker_)
92
clearRun();
93
if
(!parameters_->hasProcess())
94
throw
CG_FATAL
(
"Generator:computePoint"
) <<
"Trying to compute a point with no process specified!"
;
95
const
size_t
ndim = worker_->integrand().process().ndim();
96
if
(coord.size() != ndim)
97
throw
CG_FATAL
(
"Generator:computePoint"
)
98
<<
"Invalid phase space dimension (ndim="
<< ndim <<
", given="
<< coord.size() <<
")."
;
99
double
res = worker_->integrand().eval(coord);
100
CG_DEBUG
(
"Generator:computePoint"
) <<
"Result for x["
<< ndim <<
"] = "
<< coord <<
":\n\t"
<< res <<
"."
;
101
return
res;
102
}
103
104
void
Generator::computeXsection
(
double
& cross_section,
double
& err) {
105
const
auto
xsec =
computeXsection
();
106
cross_section = xsec;
107
err = xsec.uncertainty();
108
}
109
110
Value
Generator::computeXsection
() {
111
CG_INFO
(
"Generator"
) <<
"Starting the computation of the process cross-section."
;
112
113
integrate
();
// run is cleared here
114
115
if
(xsect_ < 1.e-2)
116
CG_INFO
(
"Generator"
) <<
"Total cross section: "
<< xsect_ * 1.e3 <<
" fb."
;
117
else
if
(xsect_ < 0.5e3)
118
CG_INFO
(
"Generator"
) <<
"Total cross section: "
<< xsect_ <<
" pb."
;
119
else
if
(xsect_ < 0.5e6)
120
CG_INFO
(
"Generator"
) <<
"Total cross section: "
<< xsect_ * 1.e-3 <<
" nb."
;
121
else
if
(xsect_ < 0.5e9)
122
CG_INFO
(
"Generator"
) <<
"Total cross section: "
<< xsect_ * 1.e-6 <<
" µb."
;
123
else
124
CG_INFO
(
"Generator"
) <<
"Total cross section: "
<< xsect_ * 1.e-9 <<
" mb."
;
125
126
return
xsect_;
127
}
128
129
void
Generator::resetIntegrator() {
130
CG_TICKER
(parameters_->timeKeeper());
131
// create a spec-defined integrator in the current scope
132
setIntegrator
(IntegratorFactory::get().build(parameters_->integrator()));
133
}
134
135
void
Generator::setIntegrator
(std::unique_ptr<Integrator> integ) {
136
CG_TICKER
(parameters_->timeKeeper());
137
// copy the integrator instance (or create it if unspecified) in the current scope
138
if
(!integ)
139
resetIntegrator();
140
else
141
integrator_ = std::move(integ);
142
CG_INFO
(
"Generator:integrator"
) <<
"Generator will use a "
<< integrator_->name() <<
"-type integrator."
;
143
}
144
145
void
Generator::integrate
() {
146
CG_TICKER
(parameters_->timeKeeper());
147
148
clearRun();
149
150
if
(!parameters_->hasProcess())
151
throw
CG_FATAL
(
"Generator:integrate"
) <<
"Trying to integrate while no process is specified!"
;
152
const
size_t
ndim = worker_->integrand().process().ndim();
153
if
(ndim == 0)
154
throw
CG_FATAL
(
"Generator:integrate"
) <<
"Invalid phase space dimension. "
155
<<
"At least one integration variable is required!"
;
156
157
CG_DEBUG
(
"Generator:integrate"
) <<
"New integrator instance created for "
<< ndim <<
"-dimensional integration."
;
158
159
if
(!integrator_)
160
throw
CG_FATAL
(
"Generator:integrate"
) <<
"No integrator object was declared for the generator!"
;
161
162
xsect_ = integrator_->integrate(worker_->integrand());
163
164
CG_DEBUG
(
"Generator:integrate"
) <<
"Computed cross section: ("
<< xsect_ <<
") pb."
;
165
166
// now that the cross section has been computed, feed it to the event modification algorithms...
167
for
(
auto
& mod : parameters_->eventModifiersSequence())
168
mod->setCrossSection(xsect_);
169
// ...and to the event storage algorithms
170
for
(
auto
& mod : parameters_->eventExportersSequence())
171
mod->setCrossSection(xsect_);
172
}
173
174
void
Generator::initialise() {
175
if
(!parameters_)
176
throw
CG_FATAL
(
"Generator:generate"
) <<
"No steering parameters specified!"
;
177
178
CG_TICKER
(parameters_->timeKeeper());
179
180
// if no worker is found, launch a new integration/run preparation
181
if
(!worker_)
182
integrate
();
183
184
// prepare the run parameters for event generation
185
parameters_->initialiseModules();
186
worker_->initialise();
187
188
initialised_ =
true
;
189
}
190
191
const
Event
&
Generator::next
() {
192
if
(!worker_ || !initialised_)
193
initialise();
194
size_t
num_try = 0;
195
while
(!worker_->next()) {
196
if
(num_try++ > 5)
197
throw
CG_FATAL
(
"Generator:next"
) <<
"Failed to generate the next event!"
;
198
}
199
return
worker_->integrand().process().event();
200
}
201
202
void
Generator::generate
(
size_t
num_events,
const
std::function<
void
(
const
proc::Process
&)>& callback) {
203
CG_TICKER
(parameters_->timeKeeper());
204
205
if
(!worker_ || !initialised_)
206
initialise();
207
208
//--- if invalid argument, retrieve from runtime parameters
209
if
(num_events < 1) {
210
if
(parameters_->generation().targetLuminosity() > 0.) {
211
num_events = std::ceil(parameters_->generation().targetLuminosity() * xsect_);
212
CG_INFO
(
"Generator"
) <<
"Target luminosity: "
<< parameters_->generation().targetLuminosity() <<
" pb-1."
;
213
}
else
214
num_events = parameters_->generation().maxGen();
215
}
216
217
CG_INFO
(
"Generator"
) <<
utils::s
(
"event"
, num_events,
true
) <<
" will be generated."
;
218
219
const
utils::Timer
tmr;
220
221
//--- launch the event generation
222
223
worker_->generate(num_events, callback);
224
225
const
double
gen_time_s = tmr.
elapsed
();
226
const
double
rate_ms =
227
(parameters_->numGeneratedEvents() > 0) ? gen_time_s / parameters_->numGeneratedEvents() * 1.e3 : 0.;
228
const
double
equiv_lumi = parameters_->numGeneratedEvents() /
crossSection
();
229
CG_INFO
(
"Generator"
) <<
utils::s
(
"event"
, parameters_->numGeneratedEvents()) <<
" generated in "
<< gen_time_s
230
<<
" s "
231
<<
"("
<< rate_ms <<
" ms/event).\n\t"
232
<<
"Equivalent luminosity: "
<<
utils::format
(
"%g"
, equiv_lumi) <<
" pb^-1."
;
233
}
234
235
void
Generator::generate
(
size_t
num_events,
const
std::function<
void
(
const
Event
&,
size_t
)>& callback) {
236
generate
(num_events, [&](
const
proc::Process
& proc) {
237
if
(callback)
238
callback(proc.
event
(), parameters_->numGeneratedEvents());
239
});
240
}
241
}
// namespace cepgen
CardsHandlerFactory.h
EventExporter.h
EventModifier.h
Exception.h
CG_FATAL
#define CG_FATAL(mod)
Definition
Exception.h:61
GeneratorWorkerFactory.h
GeneratorWorker.h
Generator.h
Handler.h
Integrator.h
IntegratorFactory.h
CG_DEBUG
#define CG_DEBUG(mod)
Definition
Message.h:220
CG_INFO
#define CG_INFO(mod)
Definition
Message.h:216
ProcessIntegrand.h
Process.h
RunParameters.h
String.h
TimeKeeper.h
CG_TICKER
#define CG_TICKER(tmr)
Definition
TimeKeeper.h:30
cepgen::Event
Container for the information on the in- and outgoing particles' kinematics.
Definition
Event.h:28
cepgen::Generator::generate
void generate(size_t num_events, const std::function< void(const Event &, size_t)> &)
Generate events.
Definition
Generator.cpp:235
cepgen::Generator::computePoint
double computePoint(const std::vector< double > &x)
Compute one single point from the total phase space.
Definition
Generator.cpp:90
cepgen::Generator::integrate
void integrate()
Integrate the functional over the phase space of interest.
Definition
Generator.cpp:145
cepgen::Generator::parseRunParameters
void parseRunParameters(const std::string &)
Read a steering card to populate the run parameters block.
Definition
Generator.cpp:72
cepgen::Generator::setIntegrator
void setIntegrator(std::unique_ptr< Integrator >)
Specify an integrator algorithm configuration.
Definition
Generator.cpp:135
cepgen::Generator::next
const Event & next()
Generate one single event.
Definition
Generator.cpp:191
cepgen::Generator::~Generator
~Generator()
Definition
Generator.cpp:52
cepgen::Generator::Generator
Generator(bool safe_mode=false)
Initialise the Monte Carlo integrator and event generator.
Definition
Generator.cpp:38
cepgen::Generator::setRunParameters
void setRunParameters(std::unique_ptr< RunParameters > &)
Feed the generator with a RunParameters object.
Definition
Generator.cpp:88
cepgen::Generator::crossSection
double crossSection() const
Last cross section computed by the generator.
Definition
Generator.h:69
cepgen::Generator::runParameters
const RunParameters & runParameters() const
Pointer to the parameters block.
Definition
Generator.cpp:76
cepgen::Generator::computeXsection
Value computeXsection()
Compute the cross section and uncertainty, in pb, for the run parameters Compute the cross section fo...
Definition
Generator.cpp:110
cepgen::ParametersList
Definition
ParametersList.h:52
cepgen::RunParameters
List of parameters used to start and run the simulation job.
Definition
RunParameters.h:41
cepgen::Value
A scalar value with its uncertainty.
Definition
Value.h:26
cepgen::proc::Process
Class template to define any process to compute using this MC integrator/events generator.
Definition
Process.h:34
cepgen::proc::Process::event
const Event & event() const
Handled particles objects and their relationships.
Definition
Process.cpp:267
cepgen::utils::Timer
A generic timer to extract the processing time between two steps in this software's flow.
Definition
Timer.h:30
cepgen::utils::Timer::elapsed
double elapsed() const
Time elapsed since the last reset call (or class construction)
Definition
Timer.h:37
cepgen::utils::format
std::string format(const std::string &fmt, Args... args)
Format a string using a printf style format descriptor.
Definition
String.h:61
cepgen::utils::s
std::string s(const std::string &word, float num, bool show_number)
Add a trailing "s" when needed.
Definition
String.cpp:228
cepgen
Common namespace for this Monte Carlo generator.
Definition
CommandLineHandler.cpp:36
cepgen::initialise
void initialise(bool safe_mode)
Definition
GlobalFunctions.cpp:91
cepgen::CardsHandlerFactory::get
static CardsHandlerFactory & get()
Definition
CardsHandlerFactory.cpp:25
CepGen
Core
Generator.cpp
Generated on Mon Jul 29 2024 for CepGen by
1.9.7