HepMC3 event record library: WriterDOT.cc Source File

HepMC3 event record library

WriterDOT.cc
Go to the documentation of this file.
1// -*- C++ -*-
2//
3// This file is part of HepMC
4// Copyright (C) 2014-2023 The HepMC collaboration (see AUTHORS for details)
5//
6/**
7 * @file WriterDOT.cc
8 * @brief Implementation of converter of GenEvent into .dot format which can be used for event vizualization.
9 *
10 */
11#include "WriterDOT.h"
12namespace HepMC3
13{
14WriterDOT::WriterDOT(const std::string &filename,std::shared_ptr<GenRunInfo> /*run*/): m_file(filename),
15 m_stream(&m_file),
16 m_style(0),
17 m_buffer(nullptr),
18 m_cursor(nullptr),
19 m_buffer_size( 256*1024 )
20{
21 if ( !m_file.is_open() ) {
22 HEPMC3_ERROR_LEVEL(100,"WriterDOT: could not open output file: "<<filename )
23 }
24}
25
26 WriterDOT::WriterDOT(std::ostream &stream, std::shared_ptr<GenRunInfo> /*run*/)
27 : m_stream(&stream),
28 m_style(0),
29 m_buffer(nullptr),
30 m_cursor(nullptr),
31 m_buffer_size( 256*1024 )
32{}
33
34
35 void WriterDOT::close() {
36 auto* ofs = dynamic_cast<std::ofstream*>(m_stream);
37 if (ofs && !ofs->is_open()) return;
38 forced_flush();
39 if (ofs) ofs->close();
40}
41/// @brief Detects if particle is parton. Might be used to draw partons different from hadrons
42 bool is_parton(const int& pd )
43{
44 bool parton=false;
45
46 if (pd==81||pd==82||pd<25) parton=true;
47 if (
48 (pd/1000==1||pd/1000==2||pd/1000==3||pd/1000==4||pd/1000==5)
49 &&(pd%1000/100==1||pd%1000/100==2||pd%1000/100==3||pd%1000/100==4)
50 &&(pd%100==1||pd%100==3)
51 )
52 { parton = true;}
53 return parton;
54}
55 void WriterDOT::write_event(const GenEvent &evt)
56{
57 allocate_buffer();
58 if ( !m_buffer ) return;
59 flush();
60 m_cursor += sprintf(m_cursor, "digraph graphname%d {\n",evt.event_number());
61 m_cursor += sprintf(m_cursor, "v0[label=\"Machine\"];\n");
62 for(const auto& v: evt.vertices() ) {
63 if (m_style != 0)
64 {
65 if (m_style == 1) //paint decay and fragmentation vertices in green
66 {
67 if (v->status() == 2) {m_cursor += sprintf(m_cursor, "node [color=\"green\"];\n");}
68 else {m_cursor += sprintf(m_cursor, "node [color=\"black\"];\n");}
69 }
70 }
71 m_cursor += sprintf(m_cursor, "node [shape=ellipse];\n");
72 m_cursor += sprintf(m_cursor, "v%d[label=\"%d\"];\n", -v->id(),v->id());
73 flush();
74 }
75 for(const auto& p: evt.beams() ) {
76 if (!p->end_vertex()) continue;
77 m_cursor += sprintf(m_cursor, "node [shape=point];\n");
78 m_cursor += sprintf(m_cursor, "v0 -> v%d [label=\"%d(%d)\"];\n", -p->end_vertex()->id(),p->id(),p->pid());
79 }
80
81 for(const auto& v: evt.vertices() ) {
82 for(const auto& p: v->particles_out() ) {
83 {
84 if (m_style != 0)
85 {
86 if (m_style == 1) //paint suspected partons and 81/82 in red
87 {
88 if (is_parton(std::abs(p->pid()))&&p->status()!=1) {m_cursor += sprintf(m_cursor, "edge [color=\"red\"];\n");}
89 else { m_cursor +=sprintf(m_cursor, "edge [color=\"black\"];\n");}
90 }
91 }
92 if (!p->end_vertex())
93 {
94 m_cursor += sprintf(m_cursor, "node [shape=point];\n");
95 m_cursor += sprintf(m_cursor, "v%d -> o%d [label=\"%d(%d)\"];\n", -v->id(), p->id(), p->id(), p->pid());
96 flush();
97 continue;
98 }
99 m_cursor += sprintf(m_cursor, "node [shape=ellipse];\n");
100 m_cursor += sprintf(m_cursor, "v%d -> v%d [label=\"%d(%d)\"];\n", -v->id(), -p->end_vertex()->id(), p->id(), p->pid());
101 flush();
102 }
103 }
104 }
105 m_cursor += sprintf(m_cursor, "labelloc=\"t\";\nlabel=\"Event %d; Vertices %lu; Particles %lu;\";\n", evt.event_number(), evt.vertices().size(), evt.particles().size());
106 m_cursor += sprintf(m_cursor,"}\n\n");
107 forced_flush();
108}
109 void WriterDOT::allocate_buffer() {
110 if ( m_buffer ) return;
111 while( m_buffer == nullptr && m_buffer_size >= 256 ) {
112 try {
113 m_buffer = new char[ m_buffer_size ]();
114 } catch (const std::bad_alloc& e) {
115 delete[] m_buffer;
116 m_buffer_size /= 2;
117 HEPMC3_WARNING_LEVEL(200,"WriterDOT::allocate_buffer: buffer size too large. Dividing by 2. New size: " << m_buffer_size << e.what())
118 }
119 }
120
121 if ( !m_buffer ) {
122 HEPMC3_ERROR_LEVEL(200, "WriterDOT::allocate_buffer: could not allocate buffer!" )
123 return;
124 }
125 m_cursor = m_buffer;
126}
127 inline void WriterDOT::flush() {
128 // The maximum size of single add to the buffer (other than by
129 // using WriterDOT::write) is 32 bytes. This is a safe value as
130 // we will not allow precision larger than 24 anyway
131 if ( m_buffer + m_buffer_size < m_cursor + 256 ) {
132 m_stream->write( m_buffer, m_cursor - m_buffer );
133 m_cursor = m_buffer;
134 }
135}
136 inline void WriterDOT::forced_flush() {
137 m_stream->write( m_buffer, m_cursor - m_buffer );
138 m_cursor = m_buffer;
139}
140
141} // namespace HepMC3
HEPMC3_WARNING_LEVEL
#define HEPMC3_WARNING_LEVEL(LEVEL, MESSAGE)
Macro for printing HEPMC3_HEPMC3_WARNING messages.
Definition Errors.h:34
HEPMC3_ERROR_LEVEL
#define HEPMC3_ERROR_LEVEL(LEVEL, MESSAGE)
Macro for printing error messages.
Definition Errors.h:27
WriterDOT.h
Definition of class WriterDOT converter of GenEvent into .dot format.
HepMC3::GenEvent
Stores event-related information.
Definition GenEvent.h:47
HepMC3::GenEvent::event_number
int event_number() const
Get event number.
Definition GenEvent.h:155
HepMC3::GenEvent::beams
std::vector< ConstGenParticlePtr > beams() const
Vector of beam particles.
Definition GenEvent.cc:429
HepMC3::GenEvent::vertices
const std::vector< ConstGenVertexPtr > & vertices() const
Get list of vertices (const).
Definition GenEvent.cc:43
HepMC3::GenEvent::particles
const std::vector< ConstGenParticlePtr > & particles() const
Get list of particles (const).
Definition GenEvent.cc:39
HepMC3::WriterDOT::allocate_buffer
void allocate_buffer()
allocates buffer for output
Definition WriterDOT.cc:109
HepMC3::WriterDOT::m_cursor
char * m_cursor
Cursor inside stream buffer.
Definition WriterDOT.h:57
HepMC3::WriterDOT::m_buffer
char * m_buffer
Stream buffer.
Definition WriterDOT.h:56
HepMC3::WriterDOT::close
void close() override
Close file stream.
Definition WriterDOT.cc:35
HepMC3::WriterDOT::m_file
std::ofstream m_file
Output file.
Definition WriterDOT.h:53
HepMC3::WriterDOT::m_buffer_size
unsigned long m_buffer_size
Buffer size.
Definition WriterDOT.h:58
HepMC3::WriterDOT::write_event
void write_event(const GenEvent &evt) override
Write event to file.
Definition WriterDOT.cc:55
HepMC3::WriterDOT::flush
void flush()
flushes output buffer
Definition WriterDOT.cc:127
HepMC3::WriterDOT::forced_flush
void forced_flush()
flushes output buffer
Definition WriterDOT.cc:136
HepMC3::WriterDOT::m_stream
std::ostream * m_stream
Output stream.
Definition WriterDOT.h:54
HepMC3::WriterDOT::m_style
int m_style
style of dot file
Definition WriterDOT.h:55
HepMC3::WriterDOT::WriterDOT
WriterDOT(const std::string &filename, std::shared_ptr< GenRunInfo > run=std::shared_ptr< GenRunInfo >())
Constructor.
Definition WriterDOT.cc:14
HepMC3
HepMC3 main namespace.
Definition AnalysisExample.h:24
HepMC3::is_parton
bool is_parton(const int &pd)
Detects if particle is parton. Might be used to draw partons different from hadrons.
Definition WriterDOT.cc:42