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