HepMC3 event record library
convert_example.cc
1// -*- C++ -*-
2//
3// This file is part of HepMC
4// Copyright (C) 2014-2023 The HepMC collaboration (see AUTHORS for details)
5//
6/// @example convert_example.cc
7/// @brief Utility to convert between different types of event records
8///
9#include "HepMC3/Print.h"
10#include "HepMC3/GenEvent.h"
11#include "HepMC3/Reader.h"
14#include "HepMC3/ReaderAscii.h"
15#include "HepMC3/WriterAscii.h"
16#include "HepMC3/WriterHEPEVT.h"
17#include "HepMC3/WriterPlugin.h"
18#include "HepMC3/ReaderHEPEVT.h"
19#include "HepMC3/ReaderLHEF.h"
20#include "HepMC3/ReaderPlugin.h"
21#include "HepMC3/ReaderFactory.h"
22
23#ifdef HEPMC3_ROOTIO
24#include "HepMC3/ReaderRoot.h"
25#include "HepMC3/WriterRoot.h"
28#endif
29#if HEPMC3_USE_COMPRESSION
30#include "HepMC3/ReaderGZ.h"
31#include "HepMC3/WriterGZ.h"
32#endif
33#ifdef HEPMC3_PROTOBUFIO
36#endif
37
38/* Extension example*/
39#ifdef HEPMCCONVERT_EXTENSION_ROOTTREEOPAL
40#ifndef HEPMC3_ROOTIO
41#warning "HEPMCCONVERT_EXTENSION_ROOTTREEOPAL requires compilation with of HepMC with ROOT, i.e. HEPMC3_ROOTIO.This extension will be disabled."
42#undef HEPMCCONVERT_EXTENSION_ROOTTREEOPAL
43#else
44#include "WriterRootTreeOPAL.h"
45#endif
46#endif
47#ifdef HEPMCCONVERT_EXTENSION_HEPEVTZEUS
48#include "WriterHEPEVTZEUS.h"
49#endif
50#ifdef HEPMCCONVERT_EXTENSION_DOT
51#include "WriterDOT.h"
52#endif
53#ifdef HEPMCCONVERT_EXTENSION_UPROOTTREEREADER
54#include "ReaderuprootTree.h"
55#endif
56
57
58#include "cmdline.h"
59using namespace HepMC3;
60enum formats {autodetect, hepmc2, hepmc3, hpe,root, treeroot, treerootopal, hpezeus, lhef, dump, dot, uproot, plugin, none, proto};
61
62template <class T>
63std::shared_ptr<Reader> get_input_file(const char* name, const bool input_is_stdin, const bool use_compression) {
64 std::string n(name);
65#if HEPMC3_USE_COMPRESSION
66 if (use_compression) {
67 return (input_is_stdin?std::make_shared<ReaderGZ<T> >(std::cin):std::make_shared<ReaderGZ<T> >(n));
68 }
69#endif
70 return (input_is_stdin?std::make_shared<T>(std::cin):std::make_shared<T>(n));
71}
72template <class T>
73std::shared_ptr<Writer> get_output_file(const char* name, const char* use_compression) {
74 std::string n(name);
75#if HEPMC3_USE_COMPRESSION
76 if (std::string(use_compression) == "z" ) return std::make_shared< WriterGZ<T,Compression::z> >(n);
77 if (std::string(use_compression) == "lzma" ) return std::make_shared< WriterGZ<T,Compression::lzma> >(n);
78 if (std::string(use_compression) == "bz2" ) return std::make_shared< WriterGZ<T,Compression::bz2> >(n);
79#endif
80 return std::make_shared<T>(n);
81}
82
83int main(int argc, char** argv)
84{
85 gengetopt_args_info ai;
86 if (cmdline_parser (argc, argv, &ai) != 0) {
87 exit(1);
88 }
89 if ( !( ( ai.inputs_num == 2 && ( std::string(ai.output_format_arg) != "none" )) || ( ai.inputs_num == 1 && ( std::string(ai.output_format_arg) == "none") ) ) )
90 {
91 printf("Exactly two arguments are requred: the name of input and output files if the output format in not \"none\"\n");
92 printf("In case the output format is \"none\" exactly one argument should be given: the name of input file.\n");
93 exit(1);
94 }
95 std::map<std::string,formats> format_map;
96 format_map.insert(std::pair<std::string,formats> ( "auto", autodetect ));
97 format_map.insert(std::pair<std::string,formats> ( "hepmc2", hepmc2 ));
98 format_map.insert(std::pair<std::string,formats> ( "hepmc3", hepmc3 ));
99 format_map.insert(std::pair<std::string,formats> ( "hpe", hpe ));
100 format_map.insert(std::pair<std::string,formats> ( "root", root ));
101 format_map.insert(std::pair<std::string,formats> ( "treeroot", treeroot ));
102 format_map.insert(std::pair<std::string,formats> ( "treerootopal", treerootopal ));
103 format_map.insert(std::pair<std::string,formats> ( "hpezeus", hpezeus ));
104 format_map.insert(std::pair<std::string,formats> ( "lhef", lhef ));
105 format_map.insert(std::pair<std::string,formats> ( "dump", dump ));
106 format_map.insert(std::pair<std::string,formats> ( "dot", dot ));
107 format_map.insert(std::pair<std::string,formats> ( "uproot", uproot ));
108 format_map.insert(std::pair<std::string,formats> ( "plugin", plugin ));
109 format_map.insert(std::pair<std::string,formats> ( "none", none ));
110 format_map.insert(std::pair<std::string,formats> ( "proto", proto ));
111 std::map<std::string, std::string> options;
112 for (size_t i=0; i<ai.extensions_given; i++)
113 {
114 std::string optarg=std::string(ai.extensions_arg[i]);
115 size_t pos = optarg.find_first_of('=');
116 if ( pos < optarg.length() ) {
117 options[std::string(optarg,0,pos)] = std::string(optarg, pos+1, optarg.length());
118 }
119 }
120 long int events_parsed = 0;
121 long int events_limit = ai.events_limit_arg;
122 long int first_event_number = ai.first_event_number_arg;
123 long int last_event_number = ai.last_event_number_arg;
124 long int print_each_events_parsed = ai.print_every_events_parsed_arg;
125 std::string InputPluginLibrary;
126 std::string InputPluginName;
127
128 std::string OutputPluginLibrary;
129 std::string OutputPluginName;
130
131 std::shared_ptr<Reader> input_file;
132 bool input_is_stdin = (std::string(ai.inputs[0]) == std::string("-"));
133 if (input_is_stdin) std::ios_base::sync_with_stdio(false);
134 bool ignore_writer = false;
135 switch (format_map.at(std::string(ai.input_format_arg)))
136 {
137 case autodetect:
138 input_file = (input_is_stdin?deduce_reader(std::cin):deduce_reader(ai.inputs[0]));
139 if (!input_file)
140 {
141 input_is_stdin?printf("Input format detection for std input has failed\n"):printf("Input format detection for file %s has failed\n",ai.inputs[0]);
142 exit(2);
143 }
144 break;
145 case hepmc2:
146 input_file = get_input_file<ReaderAsciiHepMC2>(ai.inputs[0], input_is_stdin, ai.compressed_input_flag);
147 break;
148 case hepmc3:
149 input_file = get_input_file<ReaderAscii>(ai.inputs[0], input_is_stdin, ai.compressed_input_flag);
150 break;
151 case hpe:
152 input_file = get_input_file<ReaderHEPEVT>(ai.inputs[0], input_is_stdin,ai.compressed_input_flag);
153 break;
154 case lhef:
155 input_file = get_input_file<ReaderLHEF>(ai.inputs[0], input_is_stdin, ai.compressed_input_flag);
156 break;
157 case uproot:
158#ifdef HEPMCCONVERT_EXTENSION_UPROOTTREEREADER
159 input_file = std::make_shared<ReaderuprootTree>(ai.inputs[0]);
160 break;
161#else
162 printf("Input format %s is not supported\n", ai.input_format_arg);
163 exit(2);
164#endif
165 case treeroot:
166#ifdef HEPMC3_ROOTIO
167 input_file = std::make_shared<ReaderRootTree>(ai.inputs[0]);
168 break;
169#else
170 printf("Input format %s is not supported\n", ai.input_format_arg);
171 exit(2);
172#endif
173 case root:
174#ifdef HEPMC3_ROOTIO
175 input_file = std::make_shared<ReaderRoot>(ai.inputs[0]);
176 break;
177#else
178 printf("Input format %s is not supported\n", ai.input_format_arg);
179 exit(2);
180#endif
181 case proto:
182#ifdef HEPMC3_PROTOBUFIO
183 input_file = std::make_shared<Readerprotobuf>(ai.inputs[0]);
184 break;
185#else
186 printf("Input format %s is not supported\n", ai.input_format_arg);
187 exit(2);
188#endif
189 case plugin:
190 if (options.find("InputPluginLibrary") == options.end()) {
191 printf("InputPluginLibrary option required\n");
192 exit(2);
193 }
194 else InputPluginLibrary = options.at("InputPluginLibrary");
195 if (options.find("InputPluginName") == options.end()) {
196 printf("InputPluginName option required\n");
197 exit(2);
198 }
199 else InputPluginName = options.at("InputPluginName");
200 input_file = std::make_shared<ReaderPlugin>(std::string(ai.inputs[0]), InputPluginLibrary, InputPluginName);
201 if (input_file->failed()) {
202 printf("Plugin initialization failed\n");
203 exit(2);
204 }
205 break;
206 default:
207 printf("Input format %s is not known\n", ai.input_format_arg);
208 exit(2);
209 break;
210 }
211 std::shared_ptr<Writer> output_file;
212 switch (format_map.at(std::string(ai.output_format_arg)))
213 {
214 case hepmc2:
215 output_file = get_output_file<WriterAsciiHepMC2>(ai.inputs[1], ai.compressed_output_arg);
216 break;
217 case hepmc3:
218 output_file = get_output_file<WriterAscii>(ai.inputs[1], ai.compressed_output_arg);
219 break;
220 case hpe:
221 output_file = get_output_file<WriterHEPEVT>(ai.inputs[1], ai.compressed_output_arg);
222 break;
223 case root:
224#ifdef HEPMC3_ROOTIO
225 output_file = std::make_shared<WriterRoot>(ai.inputs[1]);
226 break;
227#else
228 printf("Output format %s is not supported\n", ai.output_format_arg);
229 exit(2);
230#endif
231 case proto:
232#ifdef HEPMC3_PROTOBUFIO
233 output_file = std::make_shared<Writerprotobuf>(ai.inputs[1]);
234 break;
235#else
236 printf("Output format %s is not supported\n", ai.output_format_arg);
237 exit(2);
238#endif
239 case treeroot:
240#ifdef HEPMC3_ROOTIO
241 output_file = std::make_shared<WriterRootTree>(ai.inputs[1]);
242 break;
243#else
244 printf("Output format %s is not supported\n",ai.output_format_arg);
245 exit(2);
246#endif
247 /* Extension example*/
248 case treerootopal:
249#ifdef HEPMCCONVERT_EXTENSION_ROOTTREEOPAL
250 output_file = std::make_shared<WriterRootTreeOPAL>(ai.inputs[1]);
251 (std::dynamic_pointer_cast<WriterRootTreeOPAL>(output_file))->init_branches();
252 if (options.find("Run") != options.end()) (std::dynamic_pointer_cast<WriterRootTreeOPAL>(output_file))->set_run_number(std::atoi(options.at("Run").c_str()));
253 break;
254#else
255 printf("Output format %s is not supported\n",ai.output_format_arg);
256 exit(2);
257 break;
258#endif
259 case hpezeus:
260#ifdef HEPMCCONVERT_EXTENSION_HEPEVTZEUS
261 output_file = std::make_shared<WriterHEPEVTZEUS>(ai.inputs[1]);
262 break;
263#else
264 printf("Output format %s is not supported\n",ai.output_format_arg);
265 exit(2);
266#endif
267 case dot:
268#ifdef HEPMCCONVERT_EXTENSION_DOT
269 output_file = std::make_shared<WriterDOT>(ai.inputs[1]);
270 if (options.find("Style") != options.end()) (std::dynamic_pointer_cast<WriterDOT>(output_file))->set_style(std::atoi(options.at("Style").c_str()));
271 break;
272#else
273 printf("Output format %s is not supported\n",ai.output_format_arg);
274 exit(2);
275 break;
276#endif
277 case plugin:
278 if (options.find("OutputPluginLibrary") == options.end()) {
279 printf("OutputPluginLibrary option required, e.g. OutputPluginLibrary=libAnalysis.so\n");
280 exit(2);
281 }
282 else OutputPluginLibrary = options.at("OutputPluginLibrary");
283 if (options.find("OutputPluginName") == options.end()) {
284 printf("OutputPluginName option required, e.g. OutputPluginName=newAnalysisExamplefile\n");
285 exit(2);
286 }
287 else OutputPluginName = options.at("OutputPluginName");
288 output_file = std::make_shared<WriterPlugin>(std::string(ai.inputs[1]), OutputPluginLibrary, OutputPluginName);
289 if (output_file->failed()) {
290 printf("Plugin initialization failed\n");
291 exit(2);
292 }
293 break;
294 case dump:
295 output_file = nullptr;
296 break;
297 case none:
298 output_file = nullptr;
299 ignore_writer = true;
300 break;
301 default:
302 printf("Output format %s is not known\n", ai.output_format_arg);
303 exit(2);
304 break;
305 }
306 while( !input_file->failed() )
307 {
308 GenEvent evt(Units::GEV, Units::MM);
309 bool res_read = input_file->read_event(evt);
310
311 if( input_file->failed() ) {
312 printf("End of file reached. Exit.\n");
313 break;
314 }
315 if ( !res_read && ai.strict_read_arg) {
316 printf("Broken event. Exit.\n");
317 exit(3);
318 }
319 if (evt.event_number() < first_event_number) continue;
320 if (evt.event_number() > last_event_number) continue;
321 evt.set_run_info(input_file->run_info());
322 //Note the difference between ROOT and Ascii readers. The former read GenRunInfo before first event and the later at the same time as first event.
323 if (!ignore_writer)
324 {
325 if (output_file)
326 {
327 output_file->write_event(evt);
328 }
329 else
330 {
331 Print::content(evt);
332 }
333 }
334 evt.clear();
335 ++events_parsed;
336 if( events_parsed%print_each_events_parsed == 0 ) printf("Events parsed: %li\n", events_parsed);
337 if( events_parsed >= events_limit ) {
338 printf("Event limit reached:->events_parsed(%li) >= events_limit(%li)<-. Exit.\n", events_parsed, events_limit);
339 break;
340 }
341 }
342
343 if (input_file) input_file->close();
344 if (output_file) output_file->close();
345 cmdline_parser_free(&ai);
346 return EXIT_SUCCESS;
347}
Definition of class GenEvent.
Definition of static class Print.
Definition of class ReaderAsciiHepMC2.
Definition of class ReaderAscii.
Definition of class ReaderGZ.
Definition of class ReaderHEPEVT.
Definition of class ReaderLHEF.
Definition of class ReaderPlugin.
Definition of class ReaderRootTree.
Definition of class ReaderRoot.
Definition of interface Reader.
Definition of class Readerprotobuf.
Definition of class WriterAsciiHepMC2.
Definition of class WriterAscii.
Definition of class WriterDOT.
Definition of class WriterGZ.
Definition of class WriterHEPEVTZEUS.
Definition of class WriterHEPEVT.
Definition of class WriterPlugin.
Definition of class WriterRootTreeOPAL.
Definition of class WriterRootTree.
Definition of class WriterRoot.
Definition of class Writerprotobuf.
Stores event-related information.
Definition: GenEvent.h:41
static void content(std::ostream &os, const GenEvent &event)
Print content of all GenEvent containers.
Definition: Print.cc:17
GenEvent I/O parsing for compressed files.
Definition: ReaderGZ.h:27
GenEvent I/O serialization for compressed files.
Definition: WriterGZ.h:25
HepMC3 main namespace.
std::shared_ptr< Reader > deduce_reader(std::istream &stream)
This function will deduce the type of input stream based on its content and will return appropriate R...