HepMC3 event record library
Readerprotobuf.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 Readerprotobuf.cc
8 * @brief Implementation of \b class Readerprotobuf
9 *
10 */
12
13#include "HepMC3/Print.h"
14#include "HepMC3/Version.h"
15
17
18// protobuf header files
19#include "HepMC3.pb.h"
20
21namespace HepMC3 {
22
23/// @brief Header of the protobuf file
24std::string const ProtobufMagicHeader = "hmpb";
25/// @brief Size of the protobuf file header
26size_t const ProtobufMagicHeaderBytes = 4;
27
28HEPMC3_DECLARE_READER_FILE(Readerprotobuf)
29HEPMC3_DECLARE_READER_STREAM(Readerprotobuf)
30
31/// @brief Constant
32static size_t const MDBytesLength = 10;
33
34Readerprotobuf::Readerprotobuf(const std::string &filename)
35 : m_msg_type(HepMC3_pb::MessageDigest::unknown) {
36
37 m_md_buffer.resize(MDBytesLength);
38
39 m_in_file = std::unique_ptr<std::ifstream>(
40 new std::ifstream(filename, ios::in | ios::binary));
41
42 if (!m_in_file->is_open()) {
43 HEPMC3_ERROR("Readerprotobuf: Problem opening file: " << filename)
44 return;
45 }
46
47 m_in_stream = m_in_file.get();
48
49 read_file_start();
50}
51
52Readerprotobuf::Readerprotobuf(std::istream &stream)
53 : m_msg_type(HepMC3_pb::MessageDigest::unknown) {
54
55 if (!stream.good()) {
57 "Cannot initialize Readerprotobuf on istream which is not good().");
58 return;
59 }
60
62
63 m_in_stream = &stream;
65}
66
67Readerprotobuf::Readerprotobuf(std::shared_ptr<std::istream> stream)
68 : Readerprotobuf(*stream) {}
69
71
72 // Read the first 16 bytes, it should read "HepMC3::Protobuf"
73 std::string MagicIntro;
74 MagicIntro.resize(ProtobufMagicHeaderBytes);
75 m_in_stream->read(&MagicIntro[0], ProtobufMagicHeaderBytes);
76
77 if (MagicIntro != ProtobufMagicHeader) {
78 HEPMC3_ERROR("Failed to find expected Magic first "
80 << " bytes, is this really "
81 "a HepMC3::Protobuf file?");
82 return false;
83 }
84
85 if (!read_Header()) {
86 HEPMC3_ERROR("Readerprotobuf: Problem parsing start of file, expected to "
87 "find Header, but instead found message type: "
88 << m_msg_type);
89 return false;
90 }
91
92 if (!read_GenRunInfo()) {
93 HEPMC3_ERROR("Readerprotobuf: Problem parsing start of file, expected to "
94 "find RunInfo, but instead found message type: "
95 << m_msg_type);
96 return false;
97 }
98
99 return true;
100}
101
103 if (failed()) {
104 return false;
105 }
106
107 if (m_msg_buffer.size()) { // if we already have a message that hasn't been
108 // parsed, don't buffer the next one
109 return true;
110 }
111
112 m_msg_type = HepMC3_pb::MessageDigest::unknown;
113
115
116 if (failed()) {
117 return false;
118 }
119
121
122 HepMC3_pb::MessageDigest md;
123 if (!md.ParseFromString(m_md_buffer)) {
124 return false;
125 }
126
127 m_msg_type = md.message_type();
128
129 m_msg_buffer.resize(md.bytes());
130 m_in_stream->read(&m_msg_buffer[0], md.bytes());
131
132 if (failed()) {
133 return false;
134 }
135
136 m_bytes_read += md.bytes();
137
138 if (m_msg_type ==
139 HepMC3_pb::MessageDigest::Footer) { // close the stream if we have read to
140 // the end of the file
141 close();
142 }
143
144 return true;
145}
146
148 if (!buffer_message()) {
149 return false;
150 }
151
152 if (m_msg_type != HepMC3_pb::MessageDigest::Header) {
153 return false;
154 }
155
156 HepMC3_pb::Header Header_pb;
157 if (!Header_pb.ParseFromString(m_msg_buffer)) {
158 // if we fail to read a message then close the stream to indicate failed
159 // state
160 close();
161 return false;
162 }
163 m_msg_buffer.clear();
164
165 m_file_header.m_version_str = Header_pb.version_str();
166 m_file_header.m_version_maj = Header_pb.version_maj();
167 m_file_header.m_version_min = Header_pb.version_min();
168 m_file_header.m_version_patch = Header_pb.version_patch();
169 m_file_header.m_protobuf_version_maj = Header_pb.protobuf_version_maj();
170 m_file_header.m_protobuf_version_min = Header_pb.protobuf_version_min();
171 m_file_header.m_protobuf_version_patch = Header_pb.protobuf_version_patch();
172
173 return true;
174}
175
177 if (!buffer_message()) {
178 return false;
179 }
180
181 if (m_msg_type != HepMC3_pb::MessageDigest::RunInfo) {
182 return false;
183 }
184
185 set_run_info(std::make_shared<HepMC3::GenRunInfo>());
186
187 HepMC3_pb::GenRunInfoData GenRunInfo_pb;
188 if (!GenRunInfo_pb.ParseFromString(m_msg_buffer)) {
189 // if we fail to read a message then close the stream to indicate failed
190 // state
191 close();
192 return false;
193 }
194 m_msg_buffer.clear();
195
197
198 int vector_size = 0;
199
200 vector_size = GenRunInfo_pb.weight_names_size();
201 for (int it = 0; it < vector_size; ++it) {
202 gridata.weight_names.push_back(GenRunInfo_pb.weight_names(it));
203 }
204
205 vector_size = GenRunInfo_pb.tool_name_size();
206 for (int it = 0; it < vector_size; ++it) {
207 gridata.tool_name.push_back(GenRunInfo_pb.tool_name(it));
208 }
209
210 vector_size = GenRunInfo_pb.tool_version_size();
211 for (int it = 0; it < vector_size; ++it) {
212 gridata.tool_version.push_back(GenRunInfo_pb.tool_version(it));
213 }
214
215 vector_size = GenRunInfo_pb.tool_description_size();
216 for (int it = 0; it < vector_size; ++it) {
217 gridata.tool_description.push_back(GenRunInfo_pb.tool_description(it));
218 }
219
220 vector_size = GenRunInfo_pb.attribute_name_size();
221 for (int it = 0; it < vector_size; ++it) {
222 gridata.attribute_name.push_back(GenRunInfo_pb.attribute_name(it));
223 }
224
225 vector_size = GenRunInfo_pb.attribute_string_size();
226 for (int it = 0; it < vector_size; ++it) {
227 gridata.attribute_string.push_back(GenRunInfo_pb.attribute_string(it));
228 }
229
230 run_info()->read_data(gridata);
231 return true;
232}
233
235 if (!buffer_message()) {
236 return false;
237 }
238
239 if (m_msg_type != HepMC3_pb::MessageDigest::Event) {
240 return false;
241 }
242
243 if (skip) { // Don't parse to HepMC3 if skipping
244 m_msg_buffer.clear();
245 return true;
246 }
247
248 if (!m_msg_buffer.size()) { // empty event
250 return true;
251 }
252
253 HepMC3_pb::GenEventData ged_pb;
254 if (!ged_pb.ParseFromString(m_msg_buffer)) {
255 // if we fail to read a message then close the stream to indicate failed
256 // state
257 close();
258 return false;
259 }
260
261 m_evdata.event_number = ged_pb.event_number();
262
263 switch (ged_pb.momentum_unit()) {
264 case HepMC3_pb::GenEventData::MEV: {
265 m_evdata.momentum_unit = HepMC3::Units::MEV;
266 break;
267 }
268 case HepMC3_pb::GenEventData::GEV: {
269 m_evdata.momentum_unit = HepMC3::Units::GEV;
270 break;
271 }
272 default: {
273 HEPMC3_ERROR("Unknown momentum unit: " << ged_pb.momentum_unit());
274 return false;
275 }
276 }
277
278 switch (ged_pb.length_unit()) {
279 case HepMC3_pb::GenEventData::MM: {
280 m_evdata.length_unit = HepMC3::Units::MM;
281 break;
282 }
283 case HepMC3_pb::GenEventData::CM: {
284 m_evdata.length_unit = HepMC3::Units::CM;
285 break;
286 }
287 default: {
288 HEPMC3_ERROR("Unknown length unit: " << ged_pb.length_unit());
289 return false;
290 }
291 }
292
293 int vector_size = 0;
294
295 m_evdata.particles.clear();
296 vector_size = ged_pb.particles_size();
297 for (int it = 0; it < vector_size; ++it) {
298 auto particle_pb = ged_pb.particles(it);
299
301
302 pdata.pid = particle_pb.pid();
303 pdata.status = particle_pb.status();
304 pdata.is_mass_set = particle_pb.is_mass_set();
305 pdata.mass = particle_pb.mass();
306
308 particle_pb.momentum().m_v1(), particle_pb.momentum().m_v2(),
309 particle_pb.momentum().m_v3(), particle_pb.momentum().m_v4()};
310
311 m_evdata.particles.push_back(pdata);
312 }
313
314 m_evdata.vertices.clear();
315 vector_size = ged_pb.vertices_size();
316 for (int it = 0; it < vector_size; ++it) {
317 auto vertex_pb = ged_pb.vertices(it);
318
320
321 vdata.status = vertex_pb.status();
322
324 vertex_pb.position().m_v1(), vertex_pb.position().m_v2(),
325 vertex_pb.position().m_v3(), vertex_pb.position().m_v4()};
326
327 m_evdata.vertices.push_back(vdata);
328 }
329
330 m_evdata.weights.clear();
331 vector_size = ged_pb.weights_size();
332 for (int it = 0; it < vector_size; ++it) {
333 m_evdata.weights.push_back(ged_pb.weights(it));
334 }
335
336 m_evdata.links1.clear();
337 vector_size = ged_pb.links1_size();
338 for (int it = 0; it < vector_size; ++it) {
339 m_evdata.links1.push_back(ged_pb.links1(it));
340 }
341
342 m_evdata.links2.clear();
343 vector_size = ged_pb.links2_size();
344 for (int it = 0; it < vector_size; ++it) {
345 m_evdata.links2.push_back(ged_pb.links2(it));
346 }
347
349 HepMC3::FourVector{ged_pb.event_pos().m_v1(), ged_pb.event_pos().m_v2(),
350 ged_pb.event_pos().m_v3(), ged_pb.event_pos().m_v4()};
351
352 m_evdata.attribute_id.clear();
353 vector_size = ged_pb.attribute_id_size();
354 for (int it = 0; it < vector_size; ++it) {
355 m_evdata.attribute_id.push_back(ged_pb.attribute_id(it));
356 }
357
358 m_evdata.attribute_name.clear();
359 vector_size = ged_pb.attribute_name_size();
360 for (int it = 0; it < vector_size; ++it) {
361 m_evdata.attribute_name.push_back(ged_pb.attribute_name(it));
362 }
363
365 vector_size = ged_pb.attribute_string_size();
366 for (int it = 0; it < vector_size; ++it) {
367 m_evdata.attribute_string.push_back(ged_pb.attribute_string(it));
368 }
369
370 m_msg_buffer.clear();
371 return true;
372}
373
374bool Readerprotobuf::skip(const int n) {
375
376 for (int nn = n; nn > 0; --nn) {
377 if (!read_GenEvent(true)) {
378 return false;
379 }
380 }
381 return !failed();
382}
383
385
386 if (!read_GenEvent(false)) {
387 return false;
388 }
389
390 evt.read_data(m_evdata);
391 evt.set_run_info(run_info());
392
393 return true;
394}
395
397 if (m_in_file) {
398 m_in_file->close();
399 m_in_file.reset();
400 }
401 m_in_stream = nullptr;
402 m_msg_buffer.clear();
403}
404
406 if (m_in_file) {
407 return !m_in_file->is_open() || !m_in_file->good();
408 }
409 return !m_in_stream || !m_in_stream->good();
410}
411
412} // namespace HepMC3
#define HEPMC3_ERROR(MESSAGE)
Macro for printing error messages.
Definition Errors.h:24
Definition of struct GenRunInfoData.
Definition of static class Print.
Definition of class Readerprotobuf.
Generic 4-vector.
Definition FourVector.h:36
double m_v1
px or x. Interpretation depends on accessors used
Definition FourVector.h:305
Stores event-related information.
Definition GenEvent.h:41
void set_run_info(std::shared_ptr< GenRunInfo > run)
Set the GenRunInfo object by smart pointer.
Definition GenEvent.h:141
void read_data(const GenEventData &data)
Fill GenEvent based on GenEventData.
Definition GenEvent.cc:688
virtual void set_run_info(std::shared_ptr< GenRunInfo > run)
Set the global GenRunInfo object.
Definition Reader.h:56
virtual std::shared_ptr< GenRunInfo > run_info() const
Get the global GenRunInfo object.
Definition Reader.h:44
GenEvent I/O parsing and serialization for protobuf-based binary files.
bool read_event(GenEvent &evt) override
Read event from file.
std::string m_msg_buffer
The buffer used to hold the current message binary (header/genruninfo/genevent/footer)
std::istream * m_in_stream
The stream object that is read from.
bool failed() override
Get stream error state.
Readerprotobuf(const std::string &filename)
filename constructor
bool skip(const int the) override
skips the next N events
HepMC3::GenEventData m_evdata
The event data parsed from the message.
FileHeader m_file_header
A copy of the library version info stored in the proto file header.
void close() override
Close file stream.
bool buffer_message()
Read the next protobuf message into the message buffer.
bool read_GenRunInfo()
Parse the next protobuf message as a GenRunInfo message.
int m_msg_type
The type of current message.
std::unique_ptr< std::ifstream > m_in_file
The file stream of the file being read.
bool read_Header()
Parse the next protobuf message as a Header message.
std::string m_md_buffer
The buffer used to hold the current message digest binary (message frame)
bool read_GenEvent(bool skip=false)
Parse the next protobuf message as a GenEvent message.
bool read_file_start()
Parse the front matter of the protobuf message stream before the events.
size_t m_bytes_read
The total number of event bytes read, including message frames.
HepMC3 main namespace.
static size_t const MDBytesLength
Constant.
size_t const ProtobufMagicHeaderBytes
Size of the protobuf file header.
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 particle information.
double mass
Generated mass (if set)
FourVector momentum
Momentum.
bool is_mass_set
Check if generated mass is set.
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.
Stores serializable vertex information.
int status
Vertex status.
FourVector position
Position in time-space.