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 =
static_cast<char*
>(realloc(data, length + 1));
38static bool show_as_parton(HepMC3::ConstGenParticlePtr p )
40 const int pd=std::abs(p->pid());
43 if (pd==81||pd==82||pd<25) parton=
true;
45 (pd/1000==1||pd/1000==2||pd/1000==3||pd/1000==4||pd/1000==5)
46 &&(pd%1000/100==1||pd%1000/100==2||pd%1000/100==3||pd%1000/100==4)
47 &&(pd%100==1||pd%100==3)
50 if (p->status()==4) parton=
true;
54static char* write_event_to_dot(
char* used_cursor,
const HepMC3::GenEvent &evt,
int used_style=1)
56 used_cursor += sprintf(used_cursor,
"digraph graphname%d {\n",evt.
event_number());
57 used_cursor += sprintf(used_cursor,
"v0[label=\"Machine\"];\n");
64 if (v->status()==2) used_cursor += sprintf(used_cursor,
"node [color=\"green\"];\n");
65 else used_cursor += sprintf(used_cursor,
"node [color=\"black\"];\n");
71 for(
auto p1: v->particles_in() ) {
73 energy+=std::abs(p1->momentum().e());
75 for(
auto p2: v->particles_out() ) {
77 energy+=std::abs(p2->momentum().e());
82 double energyviolation=std::sqrt(momviolation.length2() +momviolation.e()*momviolation.e() );
84 if (energyviolation>CONSERVATION_TOLERANCE*energy) violation=
true;
88 used_cursor += sprintf(used_cursor,
"node [shape=rectangle];\n");
89 used_cursor += sprintf(used_cursor,
"v%d [label=\"%d\nd=%4.2f\"];\n", -v->id(),v->id(),energyviolation);
93 used_cursor += sprintf(used_cursor,
"node [shape=ellipse];\n");
94 used_cursor += sprintf(used_cursor,
"v%d[label=\"%d\"];\n", -v->id(),v->id());
97 used_cursor += sprintf(used_cursor,
"node [shape=ellipse];\n");
99 for(
auto p: evt.
beams() )
101 if (!p->end_vertex())
continue;
102 used_cursor += sprintf(used_cursor,
"node [shape=point];\n");
103 used_cursor += sprintf(used_cursor,
"v0 -> v%d [label=\"%d(%d)\"];\n", -p->end_vertex()->id(),p->id(),p->pid());
109 for(
auto p: v->particles_out() )
116 if (show_as_parton(p)&&p->status()!=1) used_cursor += sprintf(used_cursor,
"edge [color=\"red\"];\n");
117 else used_cursor +=sprintf(used_cursor,
"edge [color=\"black\"];\n");
120 if (!p->end_vertex())
122 used_cursor += sprintf(used_cursor,
"node [shape=point];\n");
123 used_cursor += sprintf(used_cursor,
"v%d -> o%d [label=\"%d(%d)\"];\n", -v->id(),p->id(),p->id(),p->pid());
127 used_cursor += sprintf(used_cursor,
"v%d -> v%d [label=\"%d(%d)\"];\n", -v->id(),-p->end_vertex()->id(),p->id(),p->pid());
131 used_cursor += sprintf(used_cursor,
"labelloc=\"t\";\nlabel=\"Event %d; Vertices %lu; Particles %lu;\";\n", evt.
event_number(), evt.
vertices().size(), evt.
particles().size());
132 used_cursor += sprintf(used_cursor,
"}\n\n");
141 char* m_cursor=m_buffer;
143 char *buf=create_image_from_dot(m_buffer);
158 TPad *p1 =
new TPad(
"i1",
"i1", 0.05, 0.05, 0.05+d*
fGraphImage->GetWidth()/
fGraphImage->GetHeight(), 0.95);
177 TH1S* particles1=
new TH1S();
179 particles1->SetTitle(
"Flavour: all particles; PDG ID; Number of particles");
180 particles1->SetFillColor(kBlue);
182 particles1->Fill((std::to_string(p->pid())).c_str(),1.0);
183 particles1->LabelsOption(
">",
"X");
185 TH1S* particles2=
new TH1S();
187 particles2->SetTitle(
"Flavour: particles with status 1; PDG ID; Number of particles");
188 particles2->SetFillColor(kBlue);
190 if(p->status()==1) particles2->Fill((std::to_string(p->pid())).c_str(),1.0);
191 particles2->LabelsOption(
">",
"X");
193 std::vector<double> masses;
195 if(show_as_parton(p)) masses.push_back(p->momentum().m());
196 TH1D* particles3=
new TH1D(
"particles3",
"Mass: parton particles; Mass, GeV; Number of particles",masses.size(),
197 0,*std::max_element(masses.begin(),masses.end()));
199 particles3->SetFillColor(kBlue);
200 for(
auto m: masses) particles3->Fill(m);
204 TPad *p1 =
new TPad(
"i1",
"i1", 0.00, 0.75, 1.0, 1.0);
209 TPad *p2 =
new TPad(
"i2",
"i2", 0.00, 0.50, 1.0, 0.75);
214 TPad *p3 =
new TPad(
"i3",
"i3", 0.00, 0.25, 1.0, 0.50);
234 if (pos==
fEventsCache.end()) printf(
"This event was not found in the cache. Cache size is %zu\n",
fEventsCache.size());
247 bool ok=
fReader->read_event(*(evt1));
266 static const char *FileType[] = {
"All",
"*.*",
"HepMC",
"*.hepmc*",
"LHEF",
"*.lhe*",
"ROOT",
"*.root", 0, 0 };
267 static TString dir(
"./");
269 fi.fFileTypes = FileType;
270 fi.fIniDir = StrDup(dir);
271 new TGFileDialog(gClient->GetRoot(),
this, kFDOpen, &fi);
279 fMainFrame =
new TGCompositeFrame(
this, 1350, 500, kHorizontalFrame|kFixedWidth);
293 fChooseInput->Connect(
"Clicked()",
"HepMC3ViewerFrame",
this,
"ChooseInput()");
300 fNextEvent->Connect(
"Clicked()",
"HepMC3ViewerFrame",
this,
"NextEvent()");
301 fNextEvent->SetToolTipText(
"Click to display next event");
306 fPreviousEvent->Connect(
"Clicked()",
"HepMC3ViewerFrame",
this,
"PreviousEvent()");
307 fPreviousEvent->SetToolTipText(
"Click to display previous event");
312 fClearEventCache->Connect(
"Clicked()",
"HepMC3ViewerFrame",
this,
"ClearEventCache()");
317 fExit->SetToolTipText(
"Click to exit");
318 fButtonFrame->AddFrame(
fExit,
new TGLayoutHints( kLHintsExpandX|kLHintsLeft,1,1,2,2));
320 AddFrame(
fMainFrame,
new TGLayoutHints(kLHintsTop |kLHintsExpandX| kLHintsExpandY, 1, 1, 2, 2));
322 SetWindowName(
"Event viewer");
324 Resize(GetDefaultSize());
Definition of class GenEvent.
Definition of class GenParticle.
Definition of class GenVertex.
Declaration of deduce_reader and related functions.
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(const std::string &filename)
This function deduces the type of input file based on the name/URL and its content,...