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"
26 #include "HepMC3/ReaderRootTree.h"
27 #include "HepMC3/WriterRootTree.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"
55 using namespace HepMC3;
56 enum formats {autodetect, hepmc2, hepmc3, hpe,root, treeroot, treerootopal, hpezeus, lhef, dump, dot, uproot, plugin, none};
57 
58 template <class T>
59 std::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 }
68 template <class T>
69 std::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 
79 int 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...
int main(int argc, char **argv)