HepMC3 event record library
WriterDOT.cc
1 #include "WriterDOT.h"
2 namespace HepMC3
3 {
4 WriterDOT::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 
16 WriterDOT::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;
29  forced_flush();
30  if (ofs) ofs->close();
31 }
32 /// @brief Detects if particle is parton. Might be used to draw partons different from hadrons
33 bool 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");
98  forced_flush();
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  }
116  m_cursor = m_buffer;
117 }
118 inline 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  unsigned long length = m_cursor - m_buffer;
123  if ( m_buffer_size - length < 32 ) {
124  // m_file.write( m_buffer, length );
125  m_stream->write( m_buffer, length );
126  m_cursor = m_buffer;
127  }
128 }
129 inline void WriterDOT::forced_flush() {
130  // m_file.write( m_buffer, m_cursor-m_buffer );
131  m_stream->write( m_buffer, m_cursor - m_buffer );
132  m_cursor = m_buffer;
133 }
134 
135 } // namespace HepMC3
const std::vector< ConstGenVertexPtr > & vertices() const
Get list of vertices (const)
Definition: GenEvent.cc:43
int m_style
style of dot file
Definition: WriterDOT.h:50
#define HEPMC3_WARNING(MESSAGE)
Macro for printing HEPMC3_HEPMC3_WARNING messages.
Definition: Errors.h:26
std::ofstream m_file
Output file.
Definition: WriterDOT.h:48
char * m_buffer
Stream buffer.
Definition: WriterDOT.h:51
bool is_parton(const int &pd)
Detects if particle is parton. Might be used to draw partons different from hadrons.
Definition: WriterDOT.cc:33
void close()
Close file stream.
Definition: WriterDOT.cc:26
void allocate_buffer()
allocates buffer for output
Definition: WriterDOT.cc:100
int event_number() const
Get event number.
Definition: GenEvent.h:135
std::vector< ConstGenParticlePtr > beams() const
Vector of beam particles.
Definition: GenEvent.cc:420
void flush()
flushes output buffer
Definition: WriterDOT.cc:118
Stores event-related information.
Definition: GenEvent.h:41
WriterDOT(const std::string &filename, std::shared_ptr< GenRunInfo > run=std::shared_ptr< GenRunInfo >())
Constructor.
Definition: WriterDOT.cc:4
std::ostream * m_stream
Output stream.
Definition: WriterDOT.h:49
char * m_cursor
Cursor inside stream buffer.
Definition: WriterDOT.h:52
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
#define HEPMC3_ERROR(MESSAGE)
Macro for printing error messages.
Definition: Errors.h:23
Definition of class WriterDOT.
const std::vector< ConstGenParticlePtr > & particles() const
Get list of particles (const)
Definition: GenEvent.cc:39
Feature< Feature_type > abs(const Feature< Feature_type > &input)
Obtain the absolute value of a Feature. This works as you&#39;d expect. If foo is a valid Feature...
Definition: Feature.h:316
void forced_flush()
flushes output buffer
Definition: WriterDOT.cc:129