2#include "HepMC3/ReaderFactory.h"
6#include "HepMC3ViewerFrame.h"
13#include <graphviz/gvc.h>
14#define CONSERVATION_TOLERANCE 1e-5
16static char* create_image_from_dot(
char* m_buffer)
18 GVC_t * gvc=gvContext();
19 Agraph_t *g= agmemread(m_buffer);
20 gvLayout(gvc,g,
"dot");
28 err = gvRenderData(gvc, g,
"png", &data, &length);
31 data = (
char*)realloc(data, length + 1);
37static bool show_as_parton(HepMC3::ConstGenParticlePtr p )
39 const int pd=std::abs(p->pid());
42 if (pd==81||pd==82||pd<25) parton=
true;
44 (pd/1000==1||pd/1000==2||pd/1000==3||pd/1000==4||pd/1000==5)
45 &&(pd%1000/100==1||pd%1000/100==2||pd%1000/100==3||pd%1000/100==4)
46 &&(pd%100==1||pd%100==3)
49 if (p->status()==4) parton=
true;
53static char* write_event_to_dot(
char* used_cursor,
const HepMC3::GenEvent &evt,
int used_style=1)
55 used_cursor += sprintf(used_cursor,
"digraph graphname%d {\n",evt.
event_number());
56 used_cursor += sprintf(used_cursor,
"v0[label=\"Machine\"];\n");
63 if (v->status()==2) used_cursor += sprintf(used_cursor,
"node [color=\"green\"];\n");
64 else used_cursor += sprintf(used_cursor,
"node [color=\"black\"];\n");
70 for(
auto p1: v->particles_in() ) {
72 energy+=std::abs(p1->momentum().e());
74 for(
auto p2: v->particles_out() ) {
76 energy+=std::abs(p2->momentum().e());
81 double energyviolation=std::sqrt(momviolation.length2() +momviolation.e()*momviolation.e() );
83 if (energyviolation>CONSERVATION_TOLERANCE*energy) violation=
true;
87 used_cursor += sprintf(used_cursor,
"node [shape=rectangle];\n");
88 used_cursor += sprintf(used_cursor,
"v%d [label=\"%d\nd=%4.2f\"];\n", -v->id(),v->id(),energyviolation);
92 used_cursor += sprintf(used_cursor,
"node [shape=ellipse];\n");
93 used_cursor += sprintf(used_cursor,
"v%d[label=\"%d\"];\n", -v->id(),v->id());
96 used_cursor += sprintf(used_cursor,
"node [shape=ellipse];\n");
98 for(
auto p: evt.
beams() )
100 if (!p->end_vertex())
continue;
101 used_cursor += sprintf(used_cursor,
"node [shape=point];\n");
102 used_cursor += sprintf(used_cursor,
"v0 -> v%d [label=\"%d(%d)\"];\n", -p->end_vertex()->id(),p->id(),p->pid());
108 for(
auto p: v->particles_out() )
115 if (show_as_parton(p)&&p->status()!=1) used_cursor += sprintf(used_cursor,
"edge [color=\"red\"];\n");
116 else used_cursor +=sprintf(used_cursor,
"edge [color=\"black\"];\n");
119 if (!p->end_vertex())
121 used_cursor += sprintf(used_cursor,
"node [shape=point];\n");
122 used_cursor += sprintf(used_cursor,
"v%d -> o%d [label=\"%d(%d)\"];\n", -v->id(),p->id(),p->id(),p->pid());
126 used_cursor += sprintf(used_cursor,
"v%d -> v%d [label=\"%d(%d)\"];\n", -v->id(),-p->end_vertex()->id(),p->id(),p->pid());
130 used_cursor += sprintf(used_cursor,
"labelloc=\"t\";\nlabel=\"Event %d; Vertices %lu; Particles %lu;\";\n", evt.
event_number(), evt.
vertices().size(), evt.
particles().size());
131 used_cursor += sprintf(used_cursor,
"}\n\n");
140 char* m_cursor=m_buffer;
142 char *buf=create_image_from_dot(m_buffer);
157 TPad *p1 =
new TPad(
"i1",
"i1", 0.05, 0.05, 0.05+d*
fGraphImage->GetWidth()/
fGraphImage->GetHeight(), 0.95);
176 TH1S* particles1=
new TH1S();
178 particles1->SetTitle(
"Flavour: all particles; PDG ID; Number of particles");
179 particles1->SetFillColor(kBlue);
181 particles1->Fill((std::to_string(p->pid())).c_str(),1.0);
182 particles1->LabelsOption(
">",
"X");
184 TH1S* particles2=
new TH1S();
186 particles2->SetTitle(
"Flavour: particles with status 1; PDG ID; Number of particles");
187 particles2->SetFillColor(kBlue);
189 if(p->status()==1) particles2->Fill((std::to_string(p->pid())).c_str(),1.0);
190 particles2->LabelsOption(
">",
"X");
192 std::vector<double> masses;
194 if(show_as_parton(p)) masses.push_back(p->momentum().m());
195 TH1D* particles3=
new TH1D(
"particles3",
"Mass: parton particles; Mass, GeV; Number of particles",masses.size(),
196 0,*std::max_element(masses.begin(),masses.end()));
198 particles3->SetFillColor(kBlue);
199 for(
auto m: masses) particles3->Fill(m);
203 TPad *p1 =
new TPad(
"i1",
"i1", 0.00, 0.75, 1.0, 1.0);
208 TPad *p2 =
new TPad(
"i2",
"i2", 0.00, 0.50, 1.0, 0.75);
213 TPad *p3 =
new TPad(
"i3",
"i3", 0.00, 0.25, 1.0, 0.50);
233 if (pos==
fEventsCache.end()) printf(
"This event was not found in the cache. Cache size is %zu\n",
fEventsCache.size());
246 bool ok=
fReader->read_event(*(evt1));
265 static const char *FileType[] = {
"All",
"*.*",
"HepMC",
"*.hepmc*",
"LHEF",
"*.lhe*",
"ROOT",
"*.root", 0, 0 };
266 static TString dir(
"./");
268 fi.fFileTypes = FileType;
269 fi.fIniDir = StrDup(dir);
270 new TGFileDialog(gClient->GetRoot(),
this, kFDOpen, &fi);
278 fMainFrame =
new TGCompositeFrame(
this, 1350, 500, kHorizontalFrame|kFixedWidth);
292 fChooseInput->Connect(
"Clicked()",
"HepMC3ViewerFrame",
this,
"ChooseInput()");
299 fNextEvent->Connect(
"Clicked()",
"HepMC3ViewerFrame",
this,
"NextEvent()");
300 fNextEvent->SetToolTipText(
"Click to display next event");
305 fPreviousEvent->Connect(
"Clicked()",
"HepMC3ViewerFrame",
this,
"PreviousEvent()");
306 fPreviousEvent->SetToolTipText(
"Click to display previous event");
311 fClearEventCache->Connect(
"Clicked()",
"HepMC3ViewerFrame",
this,
"ClearEventCache()");
316 fExit->SetToolTipText(
"Click to exit");
317 fButtonFrame->AddFrame(
fExit,
new TGLayoutHints( kLHintsExpandX|kLHintsLeft,1,1,2,2));
319 AddFrame(
fMainFrame,
new TGLayoutHints(kLHintsTop |kLHintsExpandX| kLHintsExpandY, 1, 1, 2, 2));
321 SetWindowName(
"Event viewer");
323 Resize(GetDefaultSize());
Definition of class GenEvent.
Definition of class GenParticle.
Definition of class GenVertex.
Definition of class ReaderRootTree.
void DrawEvent()
Draw evemt.
virtual ~HepMC3ViewerFrame()
Destructor.
TCanvas * fAnalysisCanvas
Analysis canvas.
void ReadFile(const char *a)
Open file.
std::map< std::string, TH1 * > fAnalysisH
Analysis histograms.
HepMC3ViewerFrame(const TGWindow *p, UInt_t w, UInt_t h)
Constructor.
static const size_t m_char_buffer_size
Size of writer buffer.
TGCompositeFrame * fButtonFrame
Button frame.
std::shared_ptr< HepMC3::Reader > fReader
Reader.
TRootEmbeddedCanvas * fEmbAnalysisCanvas
Analysis canvas.
TCanvas * fEventImageCanvas
Event canvas.
TGCompositeFrame * fMainFrame
Main frame.
void ClearEventCache()
slot
TGTextButton * fChooseInput
Button.
std::vector< HepMC3::GenEvent * > fEventsCache
Cache of events.
TGTextButton * fExit
Button.
TImage * fGraphImage
Image passed from graphviz.
TGTextButton * fPreviousEvent
Button.
TGTextButton * fClearEventCache
Button.
TGTextButton * fNextEvent
Button.
HepMC3::GenEvent * fCurrentEvent
Event.
void DoAnalysis()
Do analysis.
TRootEmbeddedCanvas * fEmbEventImageCanvas
Event canvas.
Stores event-related information.
int event_number() const
Get event number.
std::vector< ConstGenParticlePtr > beams() const
Vector of beam particles.
const std::vector< ConstGenVertexPtr > & vertices() const
Get list of vertices (const)
const std::vector< ConstGenParticlePtr > & particles() const
Get list of particles (const)
std::shared_ptr< Reader > deduce_reader(std::istream &stream)
This function will deduce the type of input stream based on its content and will return appropriate R...