11TString Wrap(
const TString &text, Int_t width,
const char *br) {
12 TString out, line, tok;
14 while (text.Tokenize(tok, from,
" ")) {
15 if (line.Length() > 0 && line.Length() + 1 + tok.Length() > width) {
19 if (line.Length() > 0)
26TString EscapeHtml(
const TString &s) {
28 e.ReplaceAll(
"&",
"&");
29 e.ReplaceAll(
"<",
"<");
30 e.ReplaceAll(
">",
">");
31 e.ReplaceAll(
"\"",
""");
37TString EscapeMermaid(
const TString &s) {
39 e.ReplaceAll(
"&",
"&");
40 e.ReplaceAll(
"<",
"<");
41 e.ReplaceAll(
">",
">");
42 e.ReplaceAll(
"\"",
"#quot;");
48std::vector<SelectionStep> Live(
const std::vector<SelectionStep> &steps) {
49 std::vector<SelectionStep> live;
50 for (
size_t i = 0; i < steps.size(); i++)
52 live.push_back(steps[i]);
72 return "event-level cuts";
74 return "per reaction strip";
103std::vector<Edge> Chain(
const std::vector<SelectionStep> &steps) {
104 std::vector<Edge> edges;
105 TString prev, last_strip;
107 for (
size_t i = 0; i < steps.size(); i++) {
109 const Int_t col = Column(st.
stage);
111 if (st.
id ==
"tagged" && last_strip.Length())
112 edges.push_back({last_strip, st.
id, kTRUE});
113 else if (st.
id ==
"xs") {
114 edges.push_back({
"tagged", st.
id, kFALSE});
115 edges.push_back({
"n_beam", st.
id, kFALSE});
120 edges.push_back({prev, st.
id, col != prev_col});
132 const TString &title) {
133 const std::vector<SelectionStep> steps = Live(all);
134 const Int_t kWrap = 44;
135 std::ostringstream s;
136 s <<
"digraph selection {" << std::endl;
139 s << Form(
" graph [rankdir=TB, newrank=true, splines=ortho, nodesep=0.25, "
141 "fontname=\"Helvetica\", fontsize=13, labelloc=t, "
142 "label=<<B>%s</B>>];",
143 EscapeHtml(title).Data())
145 s <<
" node [shape=box, style=\"rounded,filled\", fillcolor=\"#f4f4f4\", "
146 "color=\"#555555\", fontname=\"Helvetica\", fontsize=10, "
147 "margin=\"0.16,0.08\"];"
149 s <<
" edge [color=\"#555555\", fontname=\"Helvetica\", fontsize=9, "
154 s << Form(
" subgraph cluster_%d {", stage) << std::endl;
155 s << Form(
" label=\"%s\"; labeljust=\"l\"; fontname=\"Helvetica-Bold\"; "
156 "fontsize=11; color=\"#aaaaaa\"; style=\"rounded\";",
159 for (
size_t i = 0; i < steps.size(); i++) {
161 if (st.
stage != stage)
163 const TString name = EscapeHtml(st.
name);
164 const TString detail = Wrap(EscapeHtml(st.
detail), kWrap,
"<BR/>");
165 const char *fill = IsCut(st) ?
"#f4f4f4"
166 : st.
id ==
"tagged" ?
"#e3f2e1"
168 s << Form(
" %s [fillcolor=\"%s\", label=<<B>%s</B><BR/>%s>];",
169 st.
id.Data(), fill, name.Data(), detail.Data())
174 s << Form(
" rej_%s [shape=plaintext, style=\"\", fontsize=9, "
175 "fontcolor=\"#b00020\", label=\"%s\"];",
176 st.
id.Data(), RejectLabel(st))
178 s << Form(
" rej_%s -> %s [dir=back, color=\"#b00020\", "
180 st.
id.Data(), st.
id.Data())
182 s << Form(
" {rank=same; rej_%s; %s;}", st.
id.Data(), st.
id.Data())
186 s <<
" }" << std::endl;
192 for (
size_t i = 0; i < steps.size(); i++) {
193 const Int_t col = Column(steps[i].stage);
196 heads += (heads.Length() ?
" -> " :
"") + steps[i].id;
199 s << Form(
" {rank=same; %s [style=invis];}", heads.Data()) << std::endl;
200 const std::vector<Edge> edges = Chain(steps);
201 for (
size_t i = 0; i < edges.size(); i++)
202 s << Form(
" %s -> %s%s;", edges[i].from.Data(), edges[i].to.Data(),
203 edges[i].across ?
" [constraint=false]" :
"")
205 s <<
"}" << std::endl;
210 const TString &title) {
211 const std::vector<SelectionStep> steps = Live(all);
212 const Int_t kWrap = 44;
213 std::ostringstream s;
214 s <<
"---" << std::endl;
215 s <<
"title: " << title << std::endl;
216 s <<
"---" << std::endl;
217 s <<
"flowchart TB" << std::endl;
218 s <<
" classDef cut fill:#f4f4f4,stroke:#555,color:#000;" << std::endl;
219 s <<
" classDef note fill:#e8eef7,stroke:#555,color:#000;" << std::endl;
220 s <<
" classDef tagged fill:#e3f2e1,stroke:#555,color:#000;" << std::endl;
221 s <<
" classDef rej fill:none,stroke:none,color:#b00020;" << std::endl;
224 s << Form(
" subgraph stage_%d[\"%s\"]", stage,
227 s <<
" direction TB" << std::endl;
228 for (
size_t i = 0; i < steps.size(); i++) {
230 if (st.
stage != stage)
232 const TString name = EscapeMermaid(st.
name);
233 const TString detail = Wrap(EscapeMermaid(st.
detail), kWrap,
"<br/>");
234 const char *cls = IsCut(st) ?
"cut"
235 : st.
id ==
"tagged" ?
"tagged"
237 s << Form(
" %s[\"<b>%s</b><br/>%s\"]:::%s", st.
id.Data(), name.Data(),
241 s << Form(
" rej_%s[\"%s\"]:::rej", st.
id.Data(), RejectLabel(st))
244 s <<
" end" << std::endl;
246 const std::vector<Edge> edges = Chain(steps);
247 for (
size_t i = 0; i < edges.size(); i++)
248 s << Form(
" %s --> %s", edges[i].from.Data(), edges[i].to.Data())
250 for (
size_t i = 0; i < steps.size(); i++)
252 s << Form(
" %s -.-> rej_%s", steps[i].
id.Data(), steps[i].
id.Data())
258 const TString &dir,
const TString &title) {
259 gSystem->mkdir(dir, kTRUE);
260 const TString base = dir +
"/selection";
262 std::ofstream f((base +
".dot").Data());
264 std::cerr <<
"selection diagram: cannot write " << base <<
".dot"
268 f <<
Dot(steps, title);
271 std::ofstream f((base +
".mmd").Data());
277 char *dot = gSystem->Which(gSystem->Getenv(
"PATH"),
"dot");
279 std::cout <<
"selection diagram: " << base <<
".dot and .mmd written "
280 <<
"(no `dot` on the PATH, not rendered)" << std::endl;
283 const char *fmt[2] = {
"png",
"pdf"};
285 for (Int_t k = 0; k < 2; k++) {
287 Form(
"\"%s\" -T%s%s -o \"%s.%s\" \"%s.dot\"", dot, fmt[k],
288 k == 0 ?
" -Gdpi=150" :
"", base.Data(), fmt[k], base.Data());
289 if (gSystem->Exec(cmd) != 0)
293 std::cout <<
"selection diagram: " << base <<
".{dot,mmd"
294 << (ok ?
",png,pdf}" :
"} (dot failed to render)") << std::endl;
Block diagram of the event selection, generated from the configuration.
void Write(const std::vector< SelectionStep > &steps, const TString &dir, const TString &title)
Write selection.dot and selection.mmd under dir, and render the DOT to selection.png and selection....
TString Mermaid(const std::vector< SelectionStep > &steps, const TString &title)
The steps as a Mermaid flowchart.
TString Dot(const std::vector< SelectionStep > &steps, const TString &title)
The steps as a Graphviz DOT graph.
One step of the event selection, as StripSumScatter::DescribeSelection lists them: in the order the c...
Int_t tag_cut
The TagCut it counts under, or -1.
TString id
Node identifier, [a-z0-9_].
Stage
Where in the selection the step sits.
Int_t pre_cut
The PreCut it counts under, or -1.
TString detail
One line: the condition to pass, with the numbers in.
TString name
Short name, as in the cut report.