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 }
GenEvent I/O parsing for compressed files.
Definition: ReaderGZ.h:27
Definition of class WriterHEPEVT.
HepMC3 main namespace.
Definition of class ReaderHEPEVT.
Definition of interface Reader.
GenEvent I/O output to files similar to these produced by OPAL software.
Definition of class WriterRootTree.
Definition of class WriterAscii.
Definition of class ReaderRootTree.
Definition of class ReaderRoot.
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...
Definition of class ReaderAsciiHepMC2.
Stores event-related information.
Definition: GenEvent.h:41
Definition of class WriterPlugin.
Definition of class ReaderAscii.
Definition of class WriterAsciiHepMC2.
Definition of class WriterRoot.
GenEvent I/O serialization for compressed files.
Definition: WriterGZ.h:25
Definition of class ReaderPlugin.
Definition of class WriterGZ.
int main(int argc, char **argv)
Definition of class WriterRootTreeOPAL.
Definition of class WriterDOT.
Definition of class GenEvent.
Definition of class WriterHEPEVTZEUS.
Definition of class ReaderLHEF.
Definition of class ReaderGZ.
static void content(std::ostream &os, const GenEvent &event)
Print content of all GenEvent containers.
Definition: Print.cc:17