11 #ifndef Pythia8_Visualisation_H
12 #define Pythia8_Visualisation_H
21 string py_status(
int stAbs) {
23 if (stAbs > 20 && stAbs < 30) status =
"hardProcess";
24 else if (stAbs > 30 && stAbs < 40) status =
"MPI";
25 else if (stAbs > 40 && stAbs < 50) status =
"ISR";
26 else if (stAbs > 50 && stAbs < 60) status =
"FSR";
27 else if (stAbs > 60 && stAbs < 70) status =
"beamRemnants";
28 else if (stAbs > 70 && stAbs < 80) status =
"hadronizationPrep";
29 else if (stAbs > 80 && stAbs < 90) status =
"hadronization";
30 else if (stAbs > 90 && stAbs < 110) status =
"decays";
31 else status =
"default";
37 void makeArrow(map< pair<string,string>,
string >* arrows,
38 string identParent,
string identChild) {
39 pair<string,string> key = make_pair(identParent,identChild);
40 string value =
" " + identParent +
" -> " + identChild
41 +
" [weight=2,label=\" \"];";
42 arrows->insert( pair< pair<string,string>,
string>(key, value) );
52 void printEvent(
Event& evt,
string fileName =
"event") {
54 bool simplifyHadronization =
true;
55 bool addLegend =
true;
56 map<string, pair<string,string> > colMap;
57 colMap[
"default"] = make_pair(
"white",
"black");
58 colMap[
"hardProcess"] = make_pair(
"red",
"black");
59 colMap[
"MPI"] = make_pair(
"lightsalmon",
"black");
60 colMap[
"ISR"] = make_pair(
"lightseagreen",
"black");
61 colMap[
"FSR"] = make_pair(
"limegreen",
"black");
62 colMap[
"beamRemnants"] = make_pair(
"mediumpurple",
"black");
63 colMap[
"hadronizationPrep"] = make_pair(
"blue",
"black");
64 colMap[
"hadronization"] = make_pair(
"blue",
"black");
65 colMap[
"decays"] = make_pair(
"lightskyblue",
"black");
67 map<string,string> blobs;
68 map< pair<string,string>,
string > arrows;
69 vector< vector<int> > hadronGroups;
70 vector< vector<int> > hadronParents;
72 for (
int i=1; i<(int)evt.size(); i++) {
74 string ident =
"F" + std::to_string(10000+i);
76 string label = std::to_string(evt[i].
id()) +
" (" + evt[i].name() +
")";
78 string status = py_status(evt[i].statusAbs());
80 if (simplifyHadronization &&
81 (status ==
"decays" || status ==
"hadronization") )
continue;
83 bool checkDaughters = simplifyHadronization;
84 if (status !=
"hadronizationPrep" && status !=
"beamRemnants")
85 checkDaughters =
false;
88 vector<int> daus = evt[i].daughterList();
89 for (
int j=0; j<(int)daus.size(); j++)
90 if (py_status(evt[daus[j]].statusAbs()) !=
"hadronization")
91 checkDaughters =
false;
94 vector<int> daus = evt[i].daughterList();
96 bool foundSameDaus =
false;
97 for (
int j=0; j<(int)hadronGroups.size(); j++) {
98 if (daus.size() == hadronGroups[j].size()) {
100 for (
int k=0; k<(int)hadronGroups[j].size(); k++)
101 if (daus[k] != hadronGroups[j][k]) foundSameDaus =
false;
103 hadronParents[j].push_back(i);
108 if (!foundSameDaus) {
109 hadronGroups.push_back(daus);
110 vector<int> parents; parents.push_back(i);
111 hadronParents.push_back(parents);
113 if (status ==
"hadronizationPrep")
continue;
116 pair<string,string> colors = colMap[status];
117 string fillcolor = colors.first, fontcolor = colors.second;
118 blobs[ident] =
" " + ident +
" [shape=box,style=filled,fillcolor=\""
119 + fillcolor +
"\",fontcolor=\"" + fontcolor +
"\",label=\""
122 int mot1 = evt[i].mother1(), mot2 = evt[i].mother2();
123 if ( i > 3 && (mot1 == 0 || mot2 == 0) )
124 makeArrow(&arrows,
"F"+std::to_string(10000+max(mot1,mot2)), ident);
126 if (!checkDaughters) {
127 vector<int> daus = evt[i].daughterList();
128 for (
int j=0; j<(int)daus.size(); j++)
129 makeArrow(&arrows, ident,
"F"+std::to_string(10000+daus[j]));
134 map< pair<string,string>,
string > arrowsSav = arrows;
135 for (
int i=0; i<(int)hadronGroups.size(); i++) {
137 string ident =
"G" + std::to_string(10000+i);
138 pair<string,string> colors = colMap[
"hadronization"];
139 string fillcolor = colors.first, fontcolor = colors.second;
140 string line =
" " + ident +
" [shape=none,\n label = <<"
141 "table border=\"0\" cellspacing=\"0\">\n";
142 for (
int j=0; j<(int)hadronGroups[i].size(); j++) {
144 string label = std::to_string(evt[hadronGroups[i][j]].
id()) +
" ("
145 + evt[hadronGroups[i][j]].name() +
")";
146 line += (
" <tr><td port=\"port" + std::to_string(j)
147 +
"\" border=\"1\" bgcolor=\"" + fillcolor +
"\"><font color=\""
148 + fontcolor +
"\">" + label +
"</font></td></tr>\n" );
150 line +=
" </table>> ];";
154 for (
int j=0; j<(int)hadronParents[i].size(); j++) {
156 string identParent =
"F"+std::to_string(10000+hadronParents[i][j]);
158 vector<string> toErase;
159 toErase.push_back(identParent);
161 bool parentIsBR = (py_status(evt[hadronParents[i][j]].statusAbs()) ==
164 makeArrow(&arrows, identParent, ident);
166 int nrGP1 = evt[hadronParents[i][j]].mother1();
167 int nrGP2 = evt[hadronParents[i][j]].mother2();
170 if (py_status(evt[nrGP1].statusAbs()) ==
"hadronizationPrep") {
171 toErase.push_back(
"F"+std::to_string(10000+nrGP1));
172 int nrGGP1 = evt[nrGP1].mother1();
173 int nrGGP2 = evt[nrGP1].mother2();
175 makeArrow(&arrows,
"F"+std::to_string(10000+nrGGP1), ident);
176 if (nrGGP2 > 0 && nrGGP2 != nrGGP1)
177 makeArrow(&arrows,
"F"+std::to_string(10000+nrGGP2), ident);
178 }
else makeArrow(&arrows,
"F"+std::to_string(10000+nrGP1), ident);
180 if (nrGP2 > 0 && nrGP2 != nrGP1) {
182 if (py_status(evt[nrGP2].statusAbs()) ==
"hadronizationPrep") {
183 toErase.push_back(
"F"+std::to_string(10000+nrGP2));
184 int nrGGP1 = evt[nrGP2].mother1();
185 int nrGGP2 = evt[nrGP2].mother2();
187 makeArrow(&arrows,
"F"+std::to_string(10000+nrGGP1), ident);
188 if (nrGGP2 > 0 && nrGGP2 != nrGGP1)
189 makeArrow(&arrows,
"F"+std::to_string(10000+nrGGP2), ident);
190 }
else makeArrow(&arrows,
"F"+std::to_string(10000+nrGP2), ident);
193 for (
int iToE=0; iToE<(int)toErase.size(); iToE++)
194 if (blobs.find(toErase[iToE]) != blobs.end())
195 blobs.erase(toErase[iToE]);
196 for (map< pair<string,string>,
string >::iterator k=arrowsSav.begin();
197 k!=arrowsSav.end(); k++) {
198 for (
int iToE=0; iToE<(int)toErase.size(); iToE++) {
199 if (k->first.second == toErase[iToE])
200 arrows.erase(k->first);
209 outfile.open((
char*)(fileName+
".dot").c_str());
210 outfile <<
"digraph \"event\" {" << endl
211 <<
" rankdir=LR;" << endl;
212 for (map<string,string>::iterator iBlob=blobs.begin(); iBlob!=blobs.end();
213 iBlob++) outfile << iBlob->second << endl;
214 for (map< pair<string,string>,
string >::iterator iArrow=arrows.begin();
215 iArrow!=arrows.end(); iArrow++) outfile << iArrow->second << endl;
218 outfile <<
" { rank = source;" << endl
219 <<
" Legend [shape=none, margin=0, label=<<table border=\"0\""
220 <<
" cellspacing=\"0\">" << endl
221 <<
" <tr><td port=\"0\" border=\"1\"><b>Legend</b></td></tr>"
224 for (map<
string, pair<string,string> >::iterator iLeg=colMap.begin();
225 iLeg!=colMap.end(); iLeg++) {
226 if (iLeg->first ==
"default")
continue;
227 if (iLeg->first ==
"hadronizationPrep")
continue;
228 if (simplifyHadronization && iLeg->first ==
"decays")
continue;
229 string fillcolor = iLeg->second.first;
230 string fontcolor = iLeg->second.second;
231 outfile <<
" <tr><td port=\"port" << count <<
"\" border=\"1\" "
232 <<
"bgcolor=\"" << fillcolor <<
"\"><font color=\"" << fontcolor
233 <<
"\">" << iLeg->first <<
"</font></td></tr>" << endl;
236 outfile <<
" </table>" << endl <<
" >];" << endl <<
" }" << endl;
238 outfile <<
"}" << endl;
241 cout <<
"\n\nPrinted one event to output file " << fileName +
".dot\n";
243 if (system(
"which dot > /dev/null 2>&1") == 0) {
244 cout <<
"Producing .ps figure by using the 'dot' command." << endl;
245 string command =
"dot -Tps " + fileName +
".dot -o " + fileName+
".ps";
246 if (system(command.c_str()) == 0)
247 cout <<
"Stored event visualization in file " << fileName+
".ps"
250 cout <<
"Failed to store event visualization in file." << endl;
253 cout <<
"You can now produce a .ps figure by using the 'dot' command:\n\n"
254 <<
"dot -Tps " << fileName <<
".dot -o " << fileName <<
".ps" <<
"\n\n";
255 cout <<
"Note: 'dot' is part of the 'graphviz' package.\n"
256 <<
"You might want to install this package to produce the .ps event"
265 #endif // end Pythia8_Visualisation_H