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