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
13#include "HepMC3/Version.h"
14
17
18// protobuf header files
19#include "HepMC3.pb.h"
20
21namespace HepMC3 {
22
23std::string const ProtobufMagicHeader = "hmpb";
24
25HEPMC3_DECLARE_WRITER_FILE(Writerprotobuf)
26HEPMC3_DECLARE_WRITER_STREAM(Writerprotobuf)
27
28/// @brief Constant
29static size_t const MDBytesLength = 10;
30
31/// @brief Write a message
32template <typename T>
33size_t write_message(std::ostream *out_stream, T &msg,
34 HepMC3_pb::MessageDigest::MessageType type) {
35
36 std::string msg_str;
37 msg.SerializeToString(&msg_str);
38
39 HepMC3_pb::MessageDigest md;
40 md.set_bytes(msg_str.size());
41 md.set_message_type(type);
42
43 std::string md_str;
44 md.SerializeToString(&md_str);
45
46 if (md_str.size() != MDBytesLength) {
47 HEPMC3_ERROR("When writing protobuf message, the message digest was not "
48 "the expected length ("
49 << MDBytesLength << " bytes), but was instead "
50 << md_str.size() << " bytes.");
51 }
52
53 (*out_stream) << md_str;
54
55 (*out_stream) << msg_str;
56 return md_str.size() + msg_str.size();
57}
58
59Writerprotobuf::Writerprotobuf(const std::string &filename,
60 std::shared_ptr<GenRunInfo> run)
62
63 if (!run) {
64 run = std::make_shared<GenRunInfo>();
65 }
66 set_run_info(run);
67
68 // open file
69 m_out_file = std::unique_ptr<ofstream>(
70 new ofstream(filename, ios::out | ios::trunc | ios::binary));
71
72 // check that it is open
73 if (!m_out_file->is_open()) {
74 HEPMC3_ERROR("Writerprotobuf: problem opening file: " << filename)
75 return;
76 }
77
79 start_file();
80}
81
82Writerprotobuf::Writerprotobuf(std::ostream &stream,
83 std::shared_ptr<GenRunInfo> run)
85
86 if (!stream.good()) {
87 HEPMC3_ERROR(
88 "Cannot initialize Writerprotobuf on ostream which is not good().");
89 return;
90 }
91
92 if (!run) {
93 run = std::make_shared<GenRunInfo>();
94 }
95 set_run_info(run);
96
97 m_out_stream = &stream;
98 start_file();
99}
100
101Writerprotobuf::Writerprotobuf(std::shared_ptr<std::ostream> stream,
102 std::shared_ptr<GenRunInfo> run)
103 : Writerprotobuf(*stream, run) {}
104
106 // The first 16 bytes of a HepMC protobuf file
107 (*m_out_stream) << ProtobufMagicHeader;
108
109 HepMC3_pb::Header hdr;
110
111 (*hdr.mutable_version_str()) = HepMC3::version();
112 hdr.set_version_maj((HEPMC3_VERSION_CODE / 1000000) % 1000);
113 hdr.set_version_min((HEPMC3_VERSION_CODE / 1000) % 1000);
114 hdr.set_version_patch(HEPMC3_VERSION_CODE % 1000);
115
116 hdr.set_protobuf_version_maj((GOOGLE_PROTOBUF_VERSION / 1000000) % 1000);
117 hdr.set_protobuf_version_min((GOOGLE_PROTOBUF_VERSION / 1000) % 1000);
118 hdr.set_protobuf_version_patch(GOOGLE_PROTOBUF_VERSION % 1000);
119
120 write_message(m_out_stream, hdr, HepMC3_pb::MessageDigest::Header);
121
123}
124
126
127 GenEventData data;
128 evt.write_data(data);
129
130 HepMC3_pb::GenEventData ged_pb;
131 ged_pb.set_event_number(data.event_number);
132
133 switch (data.momentum_unit) {
134 case HepMC3::Units::MEV: {
135 ged_pb.set_momentum_unit(HepMC3_pb::GenEventData::MEV);
136 break;
137 }
138 case HepMC3::Units::GEV: {
139 ged_pb.set_momentum_unit(HepMC3_pb::GenEventData::GEV);
140 break;
141 }
142 default: {
143 HEPMC3_ERROR("Unknown momentum unit: " << data.momentum_unit);
144 return;
145 }
146 }
147
148 switch (data.length_unit) {
149 case HepMC3::Units::MM: {
150 ged_pb.set_length_unit(HepMC3_pb::GenEventData::MM);
151 break;
152 }
153 case HepMC3::Units::CM: {
154 ged_pb.set_length_unit(HepMC3_pb::GenEventData::CM);
155 break;
156 }
157 default: {
158 HEPMC3_ERROR("Unknown length unit: " << data.length_unit);
159 return;
160 }
161 }
162
163 for (auto const &pdata : data.particles) {
164 auto particle_pb = ged_pb.add_particles();
165 particle_pb->set_pid(pdata.pid);
166 particle_pb->set_status(pdata.status);
167 particle_pb->set_is_mass_set(pdata.is_mass_set);
168 particle_pb->set_mass(pdata.mass);
169
170 particle_pb->mutable_momentum()->set_m_v1(pdata.momentum.x());
171 particle_pb->mutable_momentum()->set_m_v2(pdata.momentum.y());
172 particle_pb->mutable_momentum()->set_m_v3(pdata.momentum.z());
173 particle_pb->mutable_momentum()->set_m_v4(pdata.momentum.t());
174 }
175
176 for (auto const &vdata : data.vertices) {
177 auto vertex_pb = ged_pb.add_vertices();
178 vertex_pb->set_status(vdata.status);
179
180 vertex_pb->mutable_position()->set_m_v1(vdata.position.x());
181 vertex_pb->mutable_position()->set_m_v2(vdata.position.y());
182 vertex_pb->mutable_position()->set_m_v3(vdata.position.z());
183 vertex_pb->mutable_position()->set_m_v4(vdata.position.t());
184 }
185
186 for (auto const &s : data.weights) {
187 ged_pb.add_weights(s);
188 }
189
190 for (auto const &s : data.links1) {
191 ged_pb.add_links1(s);
192 }
193 for (auto const &s : data.links2) {
194 ged_pb.add_links2(s);
195 }
196
197 ged_pb.mutable_event_pos()->set_m_v1(data.event_pos.x());
198 ged_pb.mutable_event_pos()->set_m_v2(data.event_pos.y());
199 ged_pb.mutable_event_pos()->set_m_v3(data.event_pos.z());
200 ged_pb.mutable_event_pos()->set_m_v4(data.event_pos.t());
201
202 for (auto const &s : data.attribute_id) {
203 ged_pb.add_attribute_id(s);
204 }
205 for (auto const &s : data.attribute_name) {
206 ged_pb.add_attribute_name(s);
207 }
208 for (auto const &s : data.attribute_string) {
209 ged_pb.add_attribute_string(s);
210 }
211
213 write_message(m_out_stream, ged_pb, HepMC3_pb::MessageDigest::Event);
215}
216
218
219 GenRunInfoData data;
220 run_info()->write_data(data);
221
222 HepMC3_pb::GenRunInfoData GenRunInfo_pb;
223
224 for (auto const &s : data.weight_names) {
225 GenRunInfo_pb.add_weight_names(s);
226 }
227
228 for (auto const &s : data.tool_name) {
229 GenRunInfo_pb.add_tool_name(s);
230 }
231 for (auto const &s : data.tool_version) {
232 GenRunInfo_pb.add_tool_version(s);
233 }
234 for (auto const &s : data.tool_description) {
235 GenRunInfo_pb.add_tool_description(s);
236 }
237
238 for (auto const &s : data.attribute_name) {
239 GenRunInfo_pb.add_attribute_name(s);
240 }
241 for (auto const &s : data.attribute_string) {
242 GenRunInfo_pb.add_attribute_string(s);
243 }
244
245 write_message(m_out_stream, GenRunInfo_pb, HepMC3_pb::MessageDigest::RunInfo);
246}
247
249 if (failed()) {
250 return;
251 }
252
253 if (!m_events_written) {
255 "No events were written, the output file will not be parseable.");
256 }
257
258 HepMC3_pb::Footer ftr;
259 ftr.set_nevents(m_events_written);
260 ftr.set_event_bytes_written(m_event_bytes_written);
261 write_message(m_out_stream, ftr, HepMC3_pb::MessageDigest::Footer);
262
263 if (m_out_file) {
264 m_out_file->close();
265 m_out_file.reset();
266 }
267 m_out_stream = nullptr;
268}
269
271 if (m_out_file) {
272 return !m_out_file->is_open() || !m_out_file->good();
273 }
274 return !m_out_stream || !m_out_stream->good();
275}
276
277} // namespace HepMC3
#define HEPMC3_ERROR(MESSAGE)
Macro for printing error messages.
Definition Errors.h:24
Definition of struct GenEventData.
Definition of struct GenRunInfoData.
Definition of class Writerprotobuf.
double t() const
Time component of position/displacement.
Definition FourVector.h:106
double x() const
x-component of position/displacement
Definition FourVector.h:85
double y() const
y-component of position/displacement
Definition FourVector.h:92
double z() const
z-component of position/displacement
Definition FourVector.h:99
Stores event-related information.
Definition GenEvent.h:41
void write_data(GenEventData &data) const
Fill GenEventData object.
Definition GenEvent.cc:631
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.
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, T &msg, HepMC3_pb::MessageDigest::MessageType type)
Write a message.
std::string version()
Get the HepMC library version string.
Definition Version.h:20
std::string const ProtobufMagicHeader
Header of the protobuf file.
Stores serializable event information.
std::vector< GenVertexData > vertices
Vertices.
std::vector< int > links2
Second id of the vertex links.
int event_number
Event number.
std::vector< std::string > attribute_string
Attribute serialized as string.
std::vector< GenParticleData > particles
Particles.
std::vector< int > links1
First id of the vertex links.
std::vector< std::string > attribute_name
Attribute name.
Units::LengthUnit length_unit
Length unit.
std::vector< int > attribute_id
Attribute owner id.
FourVector event_pos
Event position.
std::vector< double > weights
Weights.
Units::MomentumUnit momentum_unit
Momentum unit.
Stores serializable run information.
std::vector< std::string > tool_name
Tool names.
std::vector< std::string > tool_version
Tool versions.
std::vector< std::string > attribute_string
Attribute serialized as string.
std::vector< std::string > attribute_name
Attribute name.
std::vector< std::string > tool_description
Tool descriptions.
std::vector< std::string > weight_names
Weight names.