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