cepgen
is hosted by
Hepforge
,
IPPP Durham
CepGen
1.2.5
Central exclusive processes event generator
Loading...
Searching...
No Matches
GnuplotDrawer.cpp
Go to the documentation of this file.
1
/*
2
* CepGen: a central exclusive processes event generator
3
* Copyright (C) 2022-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 <fstream>
20
21
#include "
CepGen/Core/Exception.h
"
22
#include "
CepGen/Modules/DrawerFactory.h
"
23
#include "
CepGen/Utils/Drawer.h
"
24
#include "
CepGen/Utils/Graph.h
"
25
#include "
CepGen/Utils/Histogram.h
"
26
#include "
CepGen/Utils/Piper.h
"
27
#include "
CepGen/Utils/String.h
"
28
#include "
CepGen/Version.h
"
29
30
#ifndef GNUPLOT_BIN
31
#error "Gnuplot executable must be specified using GNUPLOT_BIN!"
32
#else
33
#define STRINGIFY(x) #x
34
#define TOSTRING(x) STRINGIFY(x)
35
#define GNUPLOT TOSTRING(GNUPLOT_BIN)
36
#endif
37
38
using namespace
std::string_literals;
39
40
namespace
cepgen
{
41
namespace
utils {
43
class
GnuplotDrawer
final :
public
Drawer
{
44
public
:
46
explicit
GnuplotDrawer
(
const
ParametersList
& params)
47
:
Drawer
(params),
48
extension_(
steer
<std::string>(
"extension"
)),
49
persist_(
steer
<bool>(
"persist"
)),
50
size_(
steer
<std::vector<std::string> >(
"size"
)),
51
font_(
steer
<std::string>(
"font"
)),
52
plot_style_(
steer
<std::string>(
"plotStyle"
)) {
53
if
(size_.size() != 2)
54
throw
CG_FATAL
(
"GnuplotDrawer"
) <<
"Invalid canvas size specified: "
<< size_ <<
"."
;
55
}
56
57
static
ParametersDescription
description
() {
58
auto
desc =
Drawer::description
();
59
desc.setDescription(
"Gnuplot drawing utility"
);
60
desc.add<std::string>(
"extension"
,
"png"
);
61
desc.add<
bool
>(
"persist"
,
false
);
62
desc.add<std::vector<std::string> >(
"size"
, {
"30cm"
,
"20cm"
});
63
desc.add<std::string>(
"font"
,
""
);
64
desc.add<std::string>(
"plotStyle"
,
"lp"
);
65
return
desc;
66
}
67
68
const
GnuplotDrawer
&
draw
(
const
Graph1D
&,
const
Mode&)
const override
;
69
const
GnuplotDrawer
&
draw
(
const
Graph2D
&,
const
Mode&)
const override
;
70
const
GnuplotDrawer
&
draw
(
const
Hist1D
&,
const
Mode&)
const override
;
71
const
GnuplotDrawer
&
draw
(
const
Hist2D
&,
const
Mode&)
const override
;
72
73
const
GnuplotDrawer
&
draw
(
const
DrawableColl
&,
74
const
std::string&
name
=
""
,
75
const
std::string& title =
""
,
76
const
Mode& mode = Mode::none)
const override
;
77
78
private
:
79
void
execute(
const
Piper::Commands
& cmds,
const
std::string&
name
)
const
{
80
std::string term;
81
if
(extension_ ==
"pdf"
)
82
term =
"pdfcairo enhanced"
;
83
else
if
(extension_ ==
"png"
)
84
term =
"pngcairo transparent enhanced"
;
85
else
if
(extension_ ==
"tex"
)
86
term =
"epslatex"
;
87
else
if
(extension_ ==
"ps"
)
88
term =
"postscript nobackground enhanced"
;
89
else
if
(extension_ ==
"fig"
)
90
term =
"fig"
;
91
else
92
throw
CG_FATAL
(
"GnuplotDrawer:execute"
) <<
"Invalid extension set: '"
+ extension_ +
"'"
;
93
if
(!font_.empty())
94
term +=
" font '"
+ font_ +
"'"
;
95
term +=
" size "
+
merge
(size_,
","
);
96
Piper::Commands
full_cmds{
"set term "
+ term,
"set output '"
+
name
+
"."
+ extension_ +
"'"
};
97
full_cmds += cmds;
98
full_cmds += Piper::Commands{
//"set key left bottom",
99
//"set key right top",
100
"exit"
};
101
Piper(std::string(GNUPLOT) + (persist_ ?
" -persist"
:
""
)).execute(full_cmds);
102
CG_DEBUG
(
"GnuplotDrawer:execute"
) <<
"Gnuplot just plotted:\n"
<< full_cmds;
103
}
104
105
static
Piper::Commands preDraw(
const
Drawable
& dr,
const
Mode& mode) {
106
Piper::Commands cmds;
107
//if (filling_)
108
if
(mode & Mode::grid)
109
cmds +=
"set grid x y mx my"
;
110
if
(mode & Mode::logx)
111
cmds +=
"set logscale x"
;
112
if
(mode & Mode::logy)
113
cmds +=
"set logscale y"
;
114
if
(mode & Mode::logz)
115
cmds +=
"set logscale z"
;
116
if
(!dr.title().empty())
117
cmds +=
"set title "
+ delatexify(dr.title());
118
for
(
const
auto
& ai : std::unordered_map<std::string, const
Drawable
::AxisInfo&>{
119
{
"x"
, dr.xAxis()}, {
"y"
, dr.yAxis()}, {
"z"
, dr.zAxis()}}) {
120
if
(!ai.second.label().empty())
121
cmds +=
"set "
+ ai.first +
"label "
+ delatexify(ai.second.label());
122
const
auto
& rng = ai.second.range();
123
if
(rng.valid())
124
cmds +=
"set "
+ ai.first +
"range ["
+ std::to_string(rng.min()) +
":"
+ std::to_string(rng.max()) +
"]"
;
125
}
126
cmds +=
"set label 'CepGen v"
+
version::tag
+
"' at graph 1,1.025 right"
;
127
return
cmds;
128
}
129
static
Piper::Commands drawGraph1D(
const
Graph1D
&,
const
Mode&,
const
std::string&);
130
static
Piper::Commands drawHist1D(
const
Hist1D
&,
const
Mode&);
131
static
std::string delatexify(
const
std::string& tok) {
132
//return "\""s + utils::replaceAll(tok, {{"\\", "\\\\"}}) + "\"";
133
return
"'"
s
+
utils::replaceAll
(tok, {{
"'"
,
"\\'"
}}) +
"'"
;
134
}
135
136
const
std::string extension_;
137
const
bool
persist_;
138
const
std::vector<std::string> size_;
139
const
std::string font_, plot_style_;
140
};
141
142
const
GnuplotDrawer
&
GnuplotDrawer::draw
(
const
Graph1D
& graph,
const
Mode
& mode)
const
{
143
auto
cmds = preDraw(graph, mode);
144
cmds += drawGraph1D(graph, mode, plot_style_);
145
execute(cmds, graph.
name
());
146
return
*
this
;
147
}
148
149
const
GnuplotDrawer
&
GnuplotDrawer::draw
(
const
Graph2D
& graph,
const
Mode
& mode)
const
{
150
auto
cmds = preDraw(graph, mode);
151
cmds +=
"$DATA << EOD"
;
152
const
auto
xs = graph.
xCoords
(), ys = graph.
yCoords
();
153
const
std::vector<double> xvec(xs.begin(), xs.end()), yvec(ys.begin(), ys.end());
154
cmds += std::to_string(yvec.size()) +
"\t"
+
merge
(xvec,
"\t"
);
155
for
(
const
auto
& y : yvec) {
156
std::ostringstream os;
157
os << y;
158
for
(
const
auto
& x : xvec)
159
os <<
"\t"
<< (
double
)graph.
valueAt
(x, y);
160
cmds += os.str();
161
}
162
cmds +=
"EOD"
;
163
cmds +=
"set autoscale xfix"
;
164
cmds +=
"set autoscale yfix"
;
165
cmds +=
"set autoscale cbfix"
;
166
if
(mode & Mode::col) {
167
cmds +=
"set hidden3d"
;
168
cmds +=
"plot '$DATA' matrix nonuniform with image notitle"
;
169
}
else
if
(mode & Mode::cont) {
170
cmds +=
"set view map"
;
171
cmds +=
"set contour"
;
172
cmds +=
"unset surface"
;
173
cmds +=
"set isosamples 500,100"
;
174
cmds +=
"set cntrlabel start 25 interval -1 font \",7\""
;
175
cmds +=
"splot '$DATA' matrix nonuniform with lines notitle"
;
176
}
else
{
177
cmds +=
"set hidden3d"
;
178
cmds +=
"set style data lines"
;
179
cmds +=
"unset contour"
;
180
cmds +=
"splot '$DATA' matrix nonuniform notitle"
;
181
}
182
execute(cmds, graph.
name
());
183
return
*
this
;
184
}
185
186
const
GnuplotDrawer
&
GnuplotDrawer::draw
(
const
Hist1D
& hist,
const
Mode
& mode)
const
{
187
auto
cmds = preDraw(hist, mode);
188
cmds += drawHist1D(hist, mode);
189
execute(cmds, hist.
name
());
190
return
*
this
;
191
}
192
193
const
GnuplotDrawer
&
GnuplotDrawer::draw
(
const
Hist2D
& hist,
const
Mode
& mode)
const
{
194
auto
cmds = preDraw(hist, mode);
195
cmds +=
"$DATA << EOD"
;
196
{
197
std::ostringstream os;
198
os << hist.
nbinsX
();
199
for
(
size_t
ix = 0; ix < hist.
nbinsX
(); ++ix)
200
os <<
"\t"
<< hist.
binRangeX
(ix).
x
(0.5);
201
cmds += os.str();
202
}
203
for
(
size_t
iy = 0; iy < hist.
nbinsY
(); ++iy) {
204
std::ostringstream os;
205
os << hist.
binRangeY
(iy).
x
(0.5);
206
for
(
size_t
ix = 0; ix < hist.
nbinsX
(); ++ix)
207
os <<
"\t"
<< (
double
)hist.
value
(ix, iy);
208
cmds += os.str();
209
}
210
cmds +=
"EOD"
;
211
if
(mode & Mode::col) {
212
cmds +=
"set hidden3d"
;
213
cmds +=
"plot '$DATA' matrix nonuniform with image notitle"
;
214
}
else
if
(mode & Mode::cont) {
215
cmds +=
"set view map"
;
216
cmds +=
"set contour"
;
217
cmds +=
"unset surface"
;
218
cmds +=
"set isosamples 500,100"
;
219
cmds +=
"splot '$DATA' matrix nonuniform with lines notitle"
;
220
}
else
{
221
cmds +=
"set hidden3d"
;
222
cmds +=
"set style data lines"
;
223
cmds +=
"unset contour"
;
224
cmds +=
"splot '$DATA' matrix nonuniform notitle"
;
225
}
226
execute(cmds, hist.
name
());
227
return
*
this
;
228
}
229
230
const
GnuplotDrawer
&
GnuplotDrawer::draw
(
const
DrawableColl
& objs,
231
const
std::string& name,
232
const
std::string& title,
233
const
Mode
& mode)
const
{
234
if
(objs.empty())
235
return
*
this
;
236
auto
cmds = preDraw(*objs.at(0), mode);
237
cmds +=
"set title "
+ delatexify(title);
238
std::vector<std::string> plot_cmds, splot_cmds;
239
for
(
const
auto
* obj : objs) {
240
if
(obj->isGraph1D()) {
241
if
(
const
auto
* gr =
dynamic_cast<
const
Graph1D
*
>
(obj); gr) {
242
auto
gr_cmds = drawGraph1D(*gr, mode, plot_style_);
243
auto
it = gr_cmds.begin();
244
while
(it != gr_cmds.end())
245
if
(
startsWith
(*it,
"plot"
)) {
246
plot_cmds.emplace_back(
replaceAll
(it->substr(5),
" notitle"
,
" title "
+ delatexify(obj->title())));
247
it = gr_cmds.erase(it);
248
}
else
if
(
startsWith
(*it,
"splot"
)) {
249
splot_cmds.emplace_back(
replaceAll
(it->substr(6),
" notitle"
,
" title "
+ delatexify(obj->title())));
250
it = gr_cmds.erase(it);
251
}
else
252
++it;
253
if
(plot_cmds.empty() && splot_cmds.empty())
254
throw
CG_FATAL
(
"GnuplotDrawer:draw"
)
255
<<
"No drawing command found for graph with name \""
<< obj->name() <<
"\"!"
;
256
cmds += gr_cmds;
257
}
258
}
else
if
(obj->isHist1D()) {
259
if
(
const
auto
* hist =
dynamic_cast<
const
Hist1D
*
>
(obj); hist) {
260
auto
h_cmds = drawHist1D(*hist, mode);
261
auto
it = h_cmds.begin();
262
while
(it != h_cmds.end())
263
if
(
startsWith
(*it,
"plot"
)) {
264
plot_cmds.emplace_back(
replaceAll
(it->substr(5),
" notitle"
,
" title "
+ delatexify(obj->title())));
265
it = h_cmds.erase(it);
266
}
else
if
(
startsWith
(*it,
"splot"
)) {
267
splot_cmds.emplace_back(
replaceAll
(it->substr(6),
" notitle"
,
" title "
+ delatexify(obj->title())));
268
it = h_cmds.erase(it);
269
}
else
270
++it;
271
if
(plot_cmds.empty() && splot_cmds.empty())
272
throw
CG_FATAL
(
"GnuplotDrawer:draw"
)
273
<<
"No drawing command found for histogram with name \""
<< obj->name() <<
"\"!"
;
274
cmds += h_cmds;
275
}
276
}
277
}
278
if
(plot_cmds.empty() && splot_cmds.empty())
279
throw
CG_FATAL
(
"GnuplotDrawer:draw"
) <<
"No drawing command found!"
;
280
else
if
(!plot_cmds.empty() && !splot_cmds.empty())
281
throw
CG_FATAL
(
"GnuplotDrawer:draw"
) <<
"Cannot combine 'flat', and surface-like drawing commands!"
;
282
else
if
(!plot_cmds.empty())
283
cmds +=
"plot "
+
merge
(plot_cmds,
", "
);
284
else
if
(!splot_cmds.empty())
285
cmds +=
"splot "
+
merge
(splot_cmds,
", "
);
286
execute(cmds,
name
);
287
return
*
this
;
288
}
289
290
Piper::Commands
GnuplotDrawer::drawGraph1D(
const
Graph1D
& graph,
const
Mode&,
const
std::string& style) {
291
Piper::Commands
cmds;
292
auto
rnd =
randomString
(5);
293
cmds +=
"$DATA_"
+ rnd +
" << EOD"
;
294
for
(
const
auto
& pt : graph.points())
295
cmds +=
296
merge
(std::vector<double>{pt.first.value, pt.first.value_unc, pt.second, pt.second.uncertainty()},
"\t"
);
297
cmds +=
"EOD"
;
298
cmds +=
"plot '$DATA_"
+ rnd +
"' u 1:3 w "
+ style +
" notitle"
;
299
return
cmds;
300
}
301
302
Piper::Commands GnuplotDrawer::drawHist1D(
const
Hist1D& hist,
const
Mode&) {
303
Piper::Commands cmds;
304
auto
rnd =
randomString
(5);
305
cmds +=
"set style data histograms"
;
306
cmds +=
"set style histogram gap 0."
;
307
//cmds += "set style fill solid 1.0 border -1";
308
cmds +=
"set style fill transparent pattern 2 bo"
;
309
310
cmds +=
"$DATA_"
+ rnd +
" << EOH"
;
311
for
(
size_t
ibin = 0; ibin < hist.nbins(); ++ibin)
312
cmds +=
merge
(std::vector<double>{hist.binRange(ibin).x(0.5), (
double
)hist.value(ibin)},
"\t"
);
313
cmds +=
"EOH"
;
314
cmds +=
"set style data lines"
;
315
cmds +=
"set yrange ["
+ std::to_string(hist.minimum()) +
":"
+ std::to_string(hist.maximum()) +
"]"
;
316
cmds +=
"set xtics 1 norangelimit nomirror"
;
317
cmds +=
"set style fill solid 0.5 noborder"
;
318
cmds +=
"set jitter spread 0.5"
;
319
cmds +=
"plot '$DATA_"
+ rnd +
"' using 1:2 bins="
+ std::to_string(hist.nbins()) +
" with boxes notitle"
;
320
return
cmds;
321
}
322
}
// namespace utils
323
}
// namespace cepgen
324
using
cepgen::utils::GnuplotDrawer
;
325
REGISTER_DRAWER
(
"gnuplot"
,
GnuplotDrawer
);
DrawerFactory.h
REGISTER_DRAWER
#define REGISTER_DRAWER(name, obj)
Add a drawing utilitary.
Definition
DrawerFactory.h:25
Drawer.h
Exception.h
CG_FATAL
#define CG_FATAL(mod)
Definition
Exception.h:61
Graph.h
Histogram.h
CG_DEBUG
#define CG_DEBUG(mod)
Definition
Message.h:220
Piper.h
String.h
Version.h
cepgen::Limits::x
double x(double v) const
Find the [0,1] value scaled between minimum and maximum.
Definition
Limits.cpp:97
cepgen::NamedModule< Drawer >::name
const std::string & name() const
Module unique indexing name.
Definition
NamedModule.h:42
cepgen::ParametersDescription
A description object for parameters collection.
Definition
ParametersDescription.h:26
cepgen::ParametersList
Definition
ParametersList.h:52
cepgen::Steerable::description
static ParametersDescription description()
Description of all object parameters.
Definition
Steerable.cpp:42
cepgen::Steerable::steer
T steer(const std::string &key) const
Retrieve a parameters as previously steered.
Definition
Steerable.h:39
cepgen::utils::Drawable::name
const std::string & name() const
Drawable name.
Definition
Drawable.h:37
cepgen::utils::Drawer::Mode
Definition
Drawer.h:41
cepgen::utils::Drawer
A generic drawing utility.
Definition
Drawer.h:36
cepgen::utils::Drawer::Hist1D
friend class Hist1D
Definition
Drawer.h:90
cepgen::utils::Drawer::Graph1D
friend class Graph1D
Definition
Drawer.h:88
cepgen::utils::Drawer::Drawable
friend class Drawable
Definition
Drawer.h:87
cepgen::utils::GnuplotDrawer
Gnuplot drawable objects drawing utility.
Definition
GnuplotDrawer.cpp:43
cepgen::utils::GnuplotDrawer::draw
const GnuplotDrawer & draw(const Graph1D &, const Mode &) const override
Draw a one-dimensional graph.
Definition
GnuplotDrawer.cpp:142
cepgen::utils::GnuplotDrawer::GnuplotDrawer
GnuplotDrawer(const ParametersList ¶ms)
Class constructor.
Definition
GnuplotDrawer.cpp:46
cepgen::utils::GnuplotDrawer::description
static ParametersDescription description()
Definition
GnuplotDrawer.cpp:57
cepgen::utils::Graph1D
A one-dimensional graph object.
Definition
Graph.h:29
cepgen::utils::Graph2D
A two-dimensional graph object.
Definition
Graph.h:58
cepgen::utils::Graph2D::yCoords
std::set< double > yCoords() const
List of vertical axis coordinates.
Definition
Graph.cpp:107
cepgen::utils::Graph2D::xCoords
std::set< double > xCoords() const
List of horizontal axis coordinates.
Definition
Graph.cpp:100
cepgen::utils::Graph2D::valueAt
const Value valueAt(double, double) const
Retrieve the value of the graph at the given coordinates.
Definition
Graph.cpp:115
cepgen::utils::Hist1D
1D histogram container
Definition
Histogram.h:72
cepgen::utils::Hist2D
2D histogram container
Definition
Histogram.h:146
cepgen::utils::Hist2D::binRangeX
Limits binRangeX(size_t bin) const
Range for a single x-axis bin.
Definition
Hist2D.cpp:183
cepgen::utils::Hist2D::nbinsX
size_t nbinsX() const
Number of x-axis bins.
Definition
Hist2D.cpp:173
cepgen::utils::Hist2D::value
Value value(size_t bin_x, size_t bin_y) const
Retrieve the value + uncertainty for one bin.
Definition
Hist2D.cpp:227
cepgen::utils::Hist2D::nbinsY
size_t nbinsY() const
Number of y-axis bins.
Definition
Hist2D.cpp:196
cepgen::utils::Hist2D::binRangeY
Limits binRangeY(size_t bin) const
Range for a single y-axis bin.
Definition
Hist2D.cpp:206
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::startsWith
bool startsWith(const std::string &str, const std::string &beg)
Check if a string starts with a given token.
Definition
String.cpp:365
cepgen::utils::DrawableColl
std::vector< const Drawable * > DrawableColl
A collection of drawable objects.
Definition
Drawer.h:34
cepgen::utils::randomString
std::string randomString(size_t size)
Generate a random string of a given size.
Definition
String.cpp:221
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
Common namespace for this Monte Carlo generator.
Definition
CommandLineHandler.cpp:36
cepgen::utils::Piper::Commands
A collection of commands to pipe to the session.
Definition
Piper.h:36
cepgen::version::tag
static const std::string tag
CepGen version.
Definition
Version.h:28
CepGenAddOns
GnuplotWrapper
GnuplotDrawer.cpp
Generated on Mon Jul 29 2024 for CepGen by
1.9.7