cepgen
is hosted by
Hepforge
,
IPPP Durham
CepGen
1.2.5
Central exclusive processes event generator
Loading...
Searching...
No Matches
MadGraphInterface.cpp
Go to the documentation of this file.
1
/*
2
* CepGen: a central exclusive processes event generator
3
* Copyright (C) 2020-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
#ifndef MADGRAPH_BIN
20
#error "*** MADGRAPH_BIN variable not set! ***"
21
#endif
22
#ifndef MADGRAPH_PROC_TMPL
23
#error "*** MADGRAPH_PROC_TMPL variable not set! ***"
24
#endif
25
#ifndef CC_CFLAGS
26
#error "*** CC_CFLAGS variable not set! ***"
27
#endif
28
29
#include <array>
30
#include <fstream>
31
32
#include "
CepGen/Core/Exception.h
"
33
#include "
CepGen/Physics/PDG.h
"
34
#include "
CepGen/Utils/Caller.h
"
35
#include "
CepGen/Utils/String.h
"
36
#include "
CepGenAddOns/MadGraphWrapper/MadGraphInterface.h
"
37
#include "
CepGenAddOns/MadGraphWrapper/MadGraphProcess.h
"
38
#include "
CepGenAddOns/MadGraphWrapper/Utils.h
"
39
#include "
CepGenAddOns/PythonWrapper/Environment.h
"
40
41
namespace
cepgen
{
42
std::unordered_map<std::string, spdgid_t> MadGraphInterface::mg5_parts_ = {
43
{
"d"
, 1}, {
"d~"
, -1}, {
"u"
, 2}, {
"u~"
, -2}, {
"s"
, 3}, {
"s~"
, -3}, {
"c"
, 4}, {
"c~"
, -4},
44
{
"b"
, 5}, {
"b~"
, -5}, {
"t"
, 6}, {
"t~"
, -6}, {
"e+"
, -11}, {
"e-"
, 11}, {
"ve"
, 12}, {
"ve~"
, -12},
45
{
"mu+"
, -13}, {
"mu-"
, 13}, {
"vm"
, 14}, {
"vm~"
, -14}, {
"tau+"
, -15}, {
"tau-"
, 15}, {
"vt"
, 16}, {
"vt~"
, -16},
46
{
"g"
, 21}, {
"a"
, 22}, {
"z"
, 23}, {
"w+"
, -24}, {
"w-"
, 24}, {
"h"
, 25},
47
};
48
49
MadGraphInterface::MadGraphInterface
(
const
ParametersList
& params)
50
:
SteeredObject
(params),
51
proc_(steer<std::string>(
"process"
)),
52
model_(steer<std::string>(
"model"
)),
53
tmp_dir_(steerAs<std::string, fs::path>(
"tmpDir"
)),
54
card_path_(steerAs<std::string, fs::path>(
"cardPath"
)),
55
log_filename_(steer<std::string>(
"logFile"
)),
56
standalone_cpp_path_(steerAs<std::string, fs::path>(
"standaloneCppPath"
)),
57
extra_particles_(steer<
ParametersList
>(
"extraParticles"
)),
58
model_parameters_(steer<
ParametersList
>(
"modelParameters"
)) {
59
if
(proc_.empty() && standalone_cpp_path_.empty())
60
throw
CG_FATAL
(
"MadGraphInterface"
) <<
"Neither a 'process' keyword nor a path to a MadGraph process interface "
61
"already generated ('standaloneCppPath') was set to the parameters!\n"
62
<< params;
63
std::ofstream log(log_filename_, std::ios::trunc);
// clearing the log
64
parseExtraParticles();
65
}
66
67
void
MadGraphInterface::parseExtraParticles() {
68
for
(
const
auto
& extra_part : extra_particles_.keysOf<
ParticleProperties
>()) {
69
if
(mg5_parts_.count(extra_part) > 0)
70
throw
CG_FATAL
(
"MadGraphInterface"
)
71
<<
"Particle with name '"
<< extra_part <<
"' is already defined in internal LUT."
;
72
const
auto
& extra_part_prop = extra_particles_.
get
<
ParticleProperties
>(extra_part);
73
// find the equivalent MadGraph particle to alias
74
std::string found_mg_equiv;
75
for
(
const
auto
& part : mg5_parts_)
76
if ((
pdgid_t
)std::labs(part.second) == extra_part_prop.pdgid)
77
found_mg_equiv = part.first;
78
if
(found_mg_equiv.empty())
79
throw
CG_FATAL
(
"MadGraphInterface"
)
80
<<
"No equivalent for particle with PDG id="
<< extra_part_prop.pdgid <<
" in MadGraph LUT."
;
81
if
(found_mg_equiv.at(found_mg_equiv.size() - 1) ==
'+'
|| found_mg_equiv.at(found_mg_equiv.size() - 1) ==
'-'
)
82
found_mg_equiv.pop_back();
83
if
(!extra_part_prop.charges.empty()) {
84
extra_part_definitions_ +=
"\ndefine "
+ extra_part +
"+ = "
+ found_mg_equiv +
"+"
;
85
extra_part_definitions_ +=
"\ndefine "
+ extra_part +
"- = "
+ found_mg_equiv +
"-"
;
86
mg5_parts_[extra_part +
"+"
] = mg5_parts_.at(found_mg_equiv +
"+"
);
87
mg5_parts_[extra_part +
"-"
] = mg5_parts_.at(found_mg_equiv +
"-"
);
88
}
else
{
89
extra_part_definitions_ +=
"\ndefine "
+ extra_part +
" = "
+ found_mg_equiv;
90
mg5_parts_[extra_part] = mg5_parts_.at(found_mg_equiv);
91
}
92
//FIXME add extra particles properties (masses, ...)
93
CG_DEBUG
(
"MadGraphInterface"
) <<
"Defined '"
<< extra_part
94
<<
"' as MadGraph alias for CepGen particle with properties: "
<< extra_part_prop
95
<<
"."
;
96
}
97
}
98
99
std::string
MadGraphInterface::run
()
const
{
100
std::ofstream log(log_filename_, std::ios::app);
// appending at the end of the log
101
102
fs::path cpp_path, cg_proc;
103
if
(!standalone_cpp_path_.empty()) {
104
CG_INFO
(
"MadGraphInterface:run"
) <<
"Running on a process already generated by mg5_aMC: "
<< standalone_cpp_path_;
105
cpp_path = standalone_cpp_path_;
106
cg_proc = tmp_dir_ /
"cepgen_proc_interface.cpp"
;
107
}
else
{
108
CG_INFO
(
"MadGraphInterface:run"
) <<
"Running the mg5_aMC process generation."
;
109
std::vector<std::string> cmds;
110
if
(!model_.empty()) {
111
cmds.emplace_back(
"set auto_convert_model T"
);
112
cmds.emplace_back(
"import model "
+ model_);
113
}
114
cmds.emplace_back(extra_part_definitions_);
115
cmds.emplace_back(
"generate "
+ proc_);
116
cmds.emplace_back(
"output standalone_cpp "
+ tmp_dir_.string());
117
cpp_path = tmp_dir_;
118
const
auto
num_removed_files = fs::remove_all(cpp_path);
119
CG_DEBUG
(
"MadGraphInterface:run"
) <<
"Removed "
<<
utils::s
(
"file"
, num_removed_files,
true
)
120
<<
" from process directory "
<< cpp_path <<
"."
;
121
122
std::ofstream log(log_filename_, std::ios::app);
// appending at the end of the log
123
log <<
"\n\n*** mg5_aMC process generation ***\n\n"
;
124
log <<
utils::merge
(
mg5amc::runCommand
(cmds, card_path_,
true
),
"\n"
);
125
126
CG_INFO
(
"MadGraphInterface:run"
) <<
"Preparing the mg5_aMC process library."
;
127
log <<
"\n\n*** mg5_aMC process library compilation ***\n\n"
;
128
cg_proc = prepareMadGraphProcess();
129
}
130
131
#ifdef _WIN32
132
fs::path lib_path =
"CepGenMadGraphProcess.dll"
;
133
#else
134
fs::path lib_path =
"libCepGenMadGraphProcess.so"
;
135
#endif
136
137
generateLibrary(cg_proc, cpp_path, lib_path);
138
linkCards();
139
return
lib_path;
140
}
141
142
void
MadGraphInterface::linkCards()
const
{
143
for
(
const
auto
& f : fs::directory_iterator(tmp_dir_ /
"Cards"
))
144
if (f.path().extension() ==
".dat"
) {
145
fs::path link_path = f.path().filename();
146
if
(!fs::exists(link_path))
147
fs::create_symlink(f, link_path);
148
}
149
CG_DEBUG
(
"MadGraphInterface:run"
) <<
"Created links in current directory for all cards in '"
+
150
std::string(tmp_dir_ /
"Cards"
) +
"'."
;
151
}
152
153
std::string MadGraphInterface::prepareMadGraphProcess()
const
{
154
//--- open template file
155
std::ifstream tmpl_file(MADGRAPH_PROC_TMPL);
156
std::string tmpl = std::string(std::istreambuf_iterator<char>(tmpl_file), std::istreambuf_iterator<char>());
157
std::ofstream log(log_filename_, std::ios::app);
// appending at the end of the log
158
log <<
"\n\n*** mg5_aMC process library compilation ***\n\n"
;
159
160
const
auto
& parts =
mg5amc::unpackProcessParticles
(proc_);
161
std::vector<int> in_parts, out_parts;
162
for
(
const
auto
& in_part : parts.first) {
163
if
(mg5_parts_.count(in_part) == 0) {
164
const
auto
pprops =
mg5amc::describeParticle
(in_part, model_);
165
mg5_parts_[in_part] = pprops.pdgid;
166
PDG::get
().
define
(pprops);
167
}
168
in_parts.emplace_back(mg5_parts_.at(in_part));
169
}
170
for
(
const
auto
& out_part : parts.second) {
171
if
(mg5_parts_.count(out_part) == 0) {
172
const
auto
pprops =
mg5amc::describeParticle
(out_part, model_);
173
mg5_parts_[out_part] = pprops.pdgid;
174
PDG::get
().
define
(pprops);
175
}
176
out_parts.emplace_back(mg5_parts_.at(out_part));
177
}
178
CG_INFO
(
"MadGraphInterface.prepareMadGraphProcess"
) <<
"Unpacked process particles: "
179
<<
"incoming="
<< in_parts <<
", "
180
<<
"outgoing="
<< out_parts <<
"."
;
181
182
const
std::string process_description = proc_ + (!model_.empty() ?
" (model: "
+ model_ +
")"
:
""
);
183
184
std::string src_filename = tmp_dir_ /
"cepgen_proc_interface.cpp"
;
185
std::ofstream src_file(src_filename);
186
src_file <<
utils::replaceAll
(tmpl,
187
{{
"XXX_PART1_XXX"
, std::to_string(in_parts[0])},
188
{
"XXX_PART2_XXX"
, std::to_string(in_parts[1])},
189
{
"XXX_OUT_PART_XXX"
,
utils::merge
(out_parts,
", "
)},
190
{
"XXX_PROC_NAME_XXX"
,
mg5amc::normalise
(proc_)},
191
{
"XXX_PROC_DESCRIPTION_XXX"
, process_description}});
192
src_file.close();
193
return
src_filename;
194
}
195
196
void
MadGraphInterface::generateLibrary(
const
fs::path& proc_path,
197
const
fs::path& in_path,
198
const
fs::path& out_lib)
const
{
199
std::vector<std::string> src_files;
200
src_files.emplace_back(proc_path.string());
201
202
//--- find all processes registered
203
std::vector<std::string> processes;
204
try
{
205
for
(
const
auto
& p : fs::directory_iterator(in_path /
"SubProcesses"
))
206
if (p.path().filename().string()[0] ==
'P'
) {
207
processes.emplace_back(p.path());
208
for
(
const
auto
& f : fs::directory_iterator(p))
209
if (f.path().extension() ==
".cc"
)
210
src_files.emplace_back(f.path());
211
}
212
}
catch
(
const
fs::filesystem_error& err) {
213
throw
CG_FATAL
(
"MadGraphInterface:generateLibrary"
)
214
<<
"Failed to retrieve all subprocesses in path "
<< in_path <<
"!\n"
215
<< err.what();
216
}
217
218
CG_DEBUG
(
"MadGraphInterface:generateLibrary"
) <<
"Subprocess list: "
<< processes <<
"."
;
219
220
if
(processes.size() != 1)
221
throw
CG_FATAL
(
"MadGraphInterface:generateLibrary"
) <<
"Currently only single-process cases are supported!"
;
222
223
//--- find all model source files
224
for
(
const
auto
& f : fs::directory_iterator(in_path /
"src"
))
225
if (f.path().extension() ==
".cc"
)
226
src_files.emplace_back(f.path());
227
228
#ifdef _WIN32
229
throw
CG_FATAL
(
"MadGraphInterface:generateLibrary"
)
230
<<
"Library generation not yet implemented for Window$ systems!"
;
231
#else
232
{
233
utils::Caller caller;
234
caller.call({CC_CFLAGS,
235
"-fPIC"
,
236
"-shared"
,
237
"-Wno-unused-variable"
,
238
"-Wno-int-in-bool-context"
,
239
"-I"
+ (in_path /
"src"
).
string
(),
240
"-I"
+ processes.at(0),
241
utils::merge
(src_files,
" "
),
242
"-o "
+ out_lib.string()});
243
}
244
#endif
245
}
246
247
ParametersDescription
MadGraphInterface::extractParamCardParameters
(
const
std::string& card_content) {
248
ParametersDescription
output
, block_params, decay_params(
"DECAY"
);
249
std::string block_name;
250
for
(
const
auto
& buf :
utils::split
(card_content,
'\n'
,
true
)) {
251
if
(buf[0] ==
'#'
)
252
continue
;
253
const
auto
ln =
utils::split
(buf,
'#'
,
true
);
// info, comments
254
const
auto
vars =
utils::split
(ln.at(0),
' '
,
true
);
255
if
(
utils::toLower
(vars.at(0)) ==
"block"
) {
256
if
(!block_params.
empty
())
257
output
.add(block_name, block_params);
258
block_name = vars.at(1);
259
block_params =
ParametersDescription
(block_name);
260
if
(ln.size() > 1)
261
block_params.
setDescription
(ln.at(1));
262
continue
;
263
}
else
if
(vars.size() == 3 && vars.at(0) ==
"DECAY"
) {
264
if
(!block_params.
empty
())
265
output
.add(block_name, block_params);
266
auto
& par = decay_params.
add
<
double
>(vars.at(1), std::stod(vars.at(2)));
267
if
(ln.size() > 1)
268
par.
setDescription
(ln.at(1));
269
continue
;
270
}
271
if
(vars.size() == 2) {
272
auto
& par = block_params.
add
<
double
>(vars.at(0), std::stod(vars.at(1)));
273
if
(ln.size() > 1)
274
par.
setDescription
(ln.at(1));
275
}
else
276
throw
CG_ERROR
(
"MadGraphInterface:extractParamCardParameters"
)
277
<<
"Failed to unpack parameters line:\n\t"
<< buf;
278
}
279
if
(!block_params.
empty
())
280
output
.add(block_name, block_params);
281
output
.add(
"DECAY"
, decay_params);
282
return
output
;
283
}
284
285
std::string
MadGraphInterface::generateParamCard
(
const
ParametersDescription
& params) {
286
std::ostringstream
output
;
287
for
(
const
auto
& key : params.
parameters
().
keysOf
<
ParametersList
>()) {
288
const
auto
& block_params = params.
parameters
().
get
<
ParametersList
>(key);
289
if
(key ==
"DECAY"
)
290
for
(
const
auto
& key2 : block_params.keys())
291
output
<<
utils::format
(
"\n%5s %3s %.6e # "
, key.data(), key2.data(), block_params.get<
double
>(key2))
292
<< params.
get
(key).
get
(key2).
description
();
293
else
{
294
output
<<
"\nBlock "
<< key;
295
for
(
const
auto
& key2 : block_params.keys())
296
output
<<
utils::format
(
"\n%5s %.6e # "
, key2.data(), block_params.get<
double
>(key2))
297
<< params.
get
(key).
get
(key2).
description
();
298
}
299
}
300
return
output
.str();
301
}
302
303
ParametersDescription
MadGraphInterface::description
() {
304
auto
desc =
ParametersDescription
();
305
desc.add<std::string>(
"process"
,
""
).setDescription(
"MadGraph_aMC process definition"
);
306
desc.add<std::string>(
"model"
,
"sm-full"
).setDescription(
"MadGraph_aMC model name"
);
307
desc.add<std::string>(
"cardPath"
,
"/tmp/cepgen_mg5_input.dat"
)
308
.setDescription(
"Temporary file where to store the input card for MadGraph_aMC"
);
309
desc.add<std::string>(
"standaloneCppPath"
,
""
);
310
desc.add<std::string>(
"tmpDir"
,
"/tmp/cepgen_mg5_aMC"
)
311
.setDescription(
"Temporary path where to store the MadGraph_aMC process definition files"
);
312
desc.add<std::string>(
"logFile"
,
"/tmp/cepgen_mg5_aMC.log"
)
313
.setDescription(
"Temporary path where to store the log for this run"
);
314
desc.add<
ParametersDescription
>(
"extraParticles"
,
ParametersDescription
())
315
.setDescription(
"define internal MadGraph alias for a particle name"
);
316
desc.add<
ParametersDescription
>(
"modelParameters"
,
ParametersDescription
())
317
.setDescription(
"list of model parameters for the process generation"
);
318
return
desc;
319
}
320
}
// namespace cepgen
Caller.h
Exception.h
CG_FATAL
#define CG_FATAL(mod)
Definition
Exception.h:61
CG_ERROR
#define CG_ERROR(mod)
Definition
Exception.h:60
MadGraphInterface.h
MadGraphProcess.h
CG_DEBUG
#define CG_DEBUG(mod)
Definition
Message.h:220
CG_INFO
#define CG_INFO(mod)
Definition
Message.h:216
PDG.h
String.h
cepgen::MadGraphInterface::MadGraphInterface
MadGraphInterface(const ParametersList &)
Definition
MadGraphInterface.cpp:49
cepgen::MadGraphInterface::extractParamCardParameters
static ParametersDescription extractParamCardParameters(const std::string &)
Retrieve a CepGen-compatible parameters list from a MadGraph parameters card.
Definition
MadGraphInterface.cpp:247
cepgen::MadGraphInterface::run
std::string run() const
Definition
MadGraphInterface.cpp:99
cepgen::MadGraphInterface::description
static ParametersDescription description()
Definition
MadGraphInterface.cpp:303
cepgen::MadGraphInterface::generateParamCard
static std::string generateParamCard(const ParametersDescription &)
Generate a MadGraph parameters card from CepGen user-steered parameters.
Definition
MadGraphInterface.cpp:285
cepgen::PDG::define
void define(const ParticleProperties &)
Add a new particle definition to the library.
Definition
PDG.cpp:60
cepgen::PDG::get
static PDG & get()
Retrieve a unique instance of this particles info collection.
Definition
PDG.cpp:41
cepgen::ParametersDescription
A description object for parameters collection.
Definition
ParametersDescription.h:26
cepgen::ParametersDescription::add
ParametersDescription & add(const std::string &name, const T &def)
Add the description to a new parameter.
Definition
ParametersDescription.h:59
cepgen::ParametersDescription::parameters
ParametersList & parameters()
List of parameters associated to this description object.
Definition
ParametersDescription.cpp:216
cepgen::ParametersDescription::setDescription
ParametersDescription & setDescription(const std::string &descr)
Set the description of this parameter (or parameters collection)
Definition
ParametersDescription.cpp:167
cepgen::ParametersDescription::empty
bool empty() const
Does a description of this parameter (or parameters collection) exist?
Definition
ParametersDescription.cpp:48
cepgen::ParametersDescription::description
const std::string & description() const
Description of this parameter (or parameters collection)
Definition
ParametersDescription.h:51
cepgen::ParametersDescription::get
const ParametersDescription & get(const std::string &) const
Get the description of a sub-object.
Definition
ParametersDescription.cpp:74
cepgen::ParametersList
Definition
ParametersList.h:52
cepgen::ParametersList::get
T get(const std::string &key, const T &def=default_arg< T >::get()) const
Get a parameter value.
Definition
ParametersList.cpp:391
cepgen::ParametersList::keysOf
std::vector< std::string > keysOf() const
List of keys for one type in this list of parameters List of keys handled in this list of parameters.
cepgen::SteeredObject
Base user-steerable object.
Definition
SteeredObject.h:41
Utils.h
Environment.h
cepgen::mg5amc::describeParticle
ParticleProperties describeParticle(const std::string &part_name, const std::string &model)
Unpack all particle properties from MadGraph.
Definition
Utils.cpp:68
cepgen::mg5amc::unpackProcessParticles
ProcessParticles unpackProcessParticles(const std::string &proc)
Unpack the particles' content and role in the process from a string.
Definition
Utils.cpp:38
cepgen::mg5amc::normalise
std::string normalise(const std::string &proc_name, const std::string &model)
Normalise a process name to make it computer-readable.
Definition
Utils.cpp:172
cepgen::mg5amc::runCommand
std::vector< std::string > runCommand(const std::vector< std::string > &cmds, const std::string &card_path, bool keep_output)
Run a mg5_aMC command and return its result.
Definition
Utils.cpp:147
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::utils::toLower
std::string toLower(const std::string &str)
Lowercase version of a string.
Definition
String.cpp:304
cepgen::utils::replaceAll
size_t replaceAll(std::string &str, const std::string &from, const std::string &to)
Replace all occurrences of a text by another.
Definition
String.cpp:118
cepgen::utils::merge
std::string merge(const std::vector< T > &vec, const std::string &delim)
Merge a collection of a printable type in a single string.
Definition
String.cpp:248
cepgen::utils::split
std::vector< std::string > split(const std::string &str, char delim, bool trim)
Split a string according to a separation character.
Definition
String.cpp:233
cepgen
Common namespace for this Monte Carlo generator.
Definition
CommandLineHandler.cpp:36
cepgen::pdgid_t
unsigned long long pdgid_t
Alias for the integer-like particle PDG id.
Definition
ParticleProperties.h:26
output
Definition
output.py:1
cepgen::ParticleProperties
A collection of physics constants associated to a single particle.
Definition
ParticleProperties.h:31
CepGenAddOns
MadGraphWrapper
MadGraphInterface.cpp
Generated on Mon Jul 29 2024 for CepGen by
1.9.7