HepMC3 event record library
Writerprotobuf.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 Writerprotobuf.cc
8 * @brief Implementation of \b class Writerprotobuf
9 *
10 */
12
14
15#include "HepMC3/Version.h"
16
17// protobuf header files
18#include "HepMC3/HepMC3.pb.h"
19
20namespace HepMC3 {
21
22std::string const ProtobufMagicHeader = "hmpb";
23
24HEPMC3_DECLARE_WRITER_FILE(Writerprotobuf)
25HEPMC3_DECLARE_WRITER_STREAM(Writerprotobuf)
26HEPMC3_DECLARE_WRITER_SPSTREAM(Writerprotobuf)
27
28/// @brief Constant
29static size_t const MDBytesLength = 10;
30
31/// @brief Write a message
32size_t write_message(std::ostream *out_stream, std::string const &msg_str,
33 HepMC3_pb::MessageDigest::MessageType type) {
34
35 HepMC3_pb::MessageDigest md;
36 md.set_bytes(msg_str.size());
37 md.set_message_type(type);
38
39 std::string md_str;
40 md.SerializeToString(&md_str);
41
42 if (md_str.size() != MDBytesLength) {
43 HEPMC3_ERROR_LEVEL(100,"When writing protobuf message, the message digest was not the expected length ("<< MDBytesLength << " bytes), but was instead "<< md_str.size() << " bytes.")
44 }
45
46 (*out_stream) << md_str;
47 (*out_stream) << msg_str;
48 return md_str.size() + msg_str.size();
49}
50
51Writerprotobuf::Writerprotobuf(const std::string &filename,
52 std::shared_ptr<GenRunInfo> run)
54
55 if (!run) {
56 run = std::make_shared<GenRunInfo>();
57 }
58 set_run_info(run);
59
60 // open file
61 m_out_file = std::unique_ptr<ofstream>(
62 new ofstream(filename, ios::out | ios::trunc | ios::binary));
63
64 // check that it is open
65 if (!m_out_file->is_open()) {
66 HEPMC3_ERROR_LEVEL(100,"Writerprotobuf: problem opening file: " << filename)
67 return;
68 }
69
71 start_file();
72}
73
74Writerprotobuf::Writerprotobuf(std::ostream &stream,
75 std::shared_ptr<GenRunInfo> run)
77
78 if (!stream.good()) {
79 HEPMC3_ERROR_LEVEL(100,"Cannot initialize Writerprotobuf on ostream which is not good().")
80 return;
81 }
82
83 if (!run) {
84 run = std::make_shared<GenRunInfo>();
85 }
86 set_run_info(run);
87
88 m_out_stream = &stream;
89 start_file();
90}
91
92Writerprotobuf::Writerprotobuf(std::shared_ptr<std::ostream> stream,
93 std::shared_ptr<GenRunInfo> run)
94 : Writerprotobuf(*stream, run) {
95 m_shared_stream = stream;
96}
97
99 // The first 16 bytes of a HepMC protobuf file
100 (*m_out_stream) << ProtobufMagicHeader;
101
102 HepMC3_pb::Header hdr;
103
104 (*hdr.mutable_version_str()) = HepMC3::version();
105 hdr.set_version_maj((HEPMC3_VERSION_CODE / 1000000) % 1000);
106 hdr.set_version_min((HEPMC3_VERSION_CODE / 1000) % 1000);
107 hdr.set_version_patch(HEPMC3_VERSION_CODE % 1000);
108
109 hdr.set_protobuf_version_maj((GOOGLE_PROTOBUF_VERSION / 1000000) % 1000);
110 hdr.set_protobuf_version_min((GOOGLE_PROTOBUF_VERSION / 1000) % 1000);
111 hdr.set_protobuf_version_patch(GOOGLE_PROTOBUF_VERSION % 1000);
112
113 std::string hdr_msg;
114 hdr.SerializeToString(&hdr_msg);
115
116 write_message(m_out_stream, hdr_msg, HepMC3_pb::MessageDigest::Header);
117
119}
120
122 m_event_bytes_written += write_message(m_out_stream, Serialize::GenEvent(evt),
123 HepMC3_pb::MessageDigest::Event);
125}
126
128 write_message(m_out_stream, Serialize::GenRunInfo(*run_info()),
129 HepMC3_pb::MessageDigest::RunInfo);
130}
131
133 if (failed()) {
134 return;
135 }
136
137 if (!m_events_written) {
138 HEPMC3_ERROR_LEVEL(100,"No events were written, the output file will not be parseable.")
139 }
140
141 HepMC3_pb::Footer ftr;
142 ftr.set_nevents(m_events_written);
143 ftr.set_event_bytes_written(m_event_bytes_written);
144 std::string ftr_msg;
145 ftr.SerializeToString(&ftr_msg);
146
147 write_message(m_out_stream, ftr_msg, HepMC3_pb::MessageDigest::Footer);
148
149 if (m_out_file) {
150 m_out_file->close();
151 m_out_file.reset();
152 }
153 m_out_stream = nullptr;
154}
155
157 if (m_out_file) {
158 return !m_out_file->is_open() || !m_out_file->good();
159 }
160 return !m_out_stream || !m_out_stream->good();
161}
162
163} // namespace HepMC3
#define HEPMC3_ERROR_LEVEL(LEVEL, MESSAGE)
Macro for printing error messages.
Definition Errors.h:27
Declaration of the Verrion functions and some macros.
#define HEPMC3_VERSION_CODE
HepMC version as an integer, HepMC X.Y.Z = 1000000*X + 1000*Y + Z.
Definition Version.h:22
Definition of class Writerprotobuf.
Stores event-related information.
Definition GenEvent.h:47
virtual void set_run_info(std::shared_ptr< GenRunInfo > run)
Set the global GenRunInfo object.
Definition Writer.h:42
virtual std::shared_ptr< GenRunInfo > run_info() const
Get the global GenRunInfo object.
Definition Writer.h:45
GenEvent I/O serialization for protobuf-based binary files.
Writerprotobuf(const std::string &filename, std::shared_ptr< GenRunInfo > run=std::shared_ptr< GenRunInfo >())
New file constructor.
bool failed() override
Get stream error state flag.
void close() override
Close file stream.
std::unique_ptr< std::ofstream > m_out_file
The output file stream.
void start_file()
Write non-event front matter to the output stream.
std::shared_ptr< std::ostream > m_shared_stream
Passed in shared_ptr to an output stream.
void write_event(const GenEvent &evt) override
Write event to file.
void write_run_info()
Write the GenRunInfo object to file.
size_t m_events_written
The number of events written to the stream.
std::ostream * m_out_stream
The stream object that is written to.
size_t m_event_bytes_written
The number of event bytes written to the stream.
HepMC3 main namespace.
static size_t const MDBytesLength
Constant.
size_t write_message(std::ostream *out_stream, std::string const &msg_str, HepMC3_pb::MessageDigest::MessageType type)
Write a message.
std::string version()
Get the HepMC library version string.
Definition Version.h:25
bxz::ofstream ofstream
ofstream
std::string const ProtobufMagicHeader
Header of the protobuf file.
Definition of utility functions for protobufIO.