MARLEY (Model of Argon Reaction Low Energy Yields)  v1.2.0
A Monte Carlo event generator for tens-of-MeV neutrino interactions
OutputFile.hh
1 //
5 // This file is part of MARLEY (Model of Argon Reaction Low Energy Yields)
6 //
7 // MARLEY is free software: you can redistribute it and/or modify it under the
8 // terms of version 3 of the GNU General Public License as published by the
9 // Free Software Foundation.
10 //
11 // For the full text of the license please see COPYING or
12 // visit http://opensource.org/licenses/GPL-3.0
13 //
14 // Please respect the MCnet academic usage guidelines. See GUIDELINES
15 // or visit https://www.montecarlonet.org/GUIDELINES for details.
16 
17 #pragma once
18 
19 // standard library includes
20 #include <fstream>
21 #include <string>
22 
23 namespace marley {
24 
25  class Generator;
26 
29  class OutputFile {
30 
31  public:
32 
33  // Arguments to the constructor correspond to fields in
34  // the JSON objects that appear under the "output" key
35  // in the "executable_settings" section of a MARLEY job
36  // configuration file
37  OutputFile(const std::string& name, const std::string& format,
38  const std::string& mode, bool force = false);
39 
40  virtual ~OutputFile() = default;
41 
42  const std::string& name() const { return name_; }
43 
50  virtual bool resume(std::unique_ptr<marley::Generator>& gen,
51  long& num_previous_events) = 0;
52 
56  virtual void close(const marley::JSON& json_config,
57  const marley::Generator& gen, const long num_events) = 0;
58 
61  virtual int_fast64_t bytes_written() = 0;
62 
66  virtual void write_event(const marley::Event* event) = 0;
67 
68  bool mode_is_resume() const { return mode_ == Mode::RESUME; }
69 
74  virtual void write_flux_avg_tot_xsec(double avg_tot_xsec) = 0;
75 
76  // Add more formats to the enum class as needed. This should include
77  // every event format that MARLEY knows how to write. The "ASCII" format
78  // is MARLEY's native format for textual input and output of
79  // marley::Event objects (via the << and >> operators on std::ostream and
80  // std::istream objects).
81  enum class Format { ROOT, HEPEVT, JSON, ASCII };
82 
83  protected:
84 
88  std::unique_ptr<marley::Generator> restore_generator(
89  const marley::JSON& config);
90 
92  inline bool check_if_file_exists(const std::string& filename) {
93  std::ifstream test_stream( filename );
94  return test_stream.good();
95  }
96 
100  virtual void open() = 0;
101 
104  virtual void write_generator_state(const marley::JSON& json_config,
105  const marley::Generator& gen, const long num_events) = 0;
106 
107  // Modes to use when writing output to files that are not initially empty
108  // OVERWRITE = removes any previous contents of the file, then writes new
109  // events in the requested format. This mode is allowed for all output
110  // formats.
111  // APPEND = adds new events to the end of the file without altering any
112  // previous contents. This mode is only allowed for formats that don't
113  // save metadata (random number generator state, etc.) to the file,
114  // i.e., the HEPEVT and ASCII formats.
115  // RESUME = uses saved metadata in a file to restore a previous MARLEY
116  // configuration (including the random number generator state), then
117  // appends new events after those currently saved in the file. This
118  // mode is only allowed for output formats that include such metadata,
119  // i.e., the ROOT and JSON formats.
120  enum class Mode { OVERWRITE, APPEND, RESUME };
121 
122  std::string name_;
123  Format format_;
124  Mode mode_;
125 
126  // Whether to force the current output mode without prompting the user.
127  // Currently only used when setting the OVERWRITE output mode.
128  bool force_;
129  };
130 
131  class TextOutputFile : public OutputFile {
132  private:
133 
134  // Formats the beginning of a JSON output file properly based on the
135  // current indent level. Writes the result to a std::ostream.
136  void start_json_output(bool start_array);
137 
138  // Stream used to read and write from the output file as needed
139  std::fstream stream_;
140 
141  // Flag used to see if we need a comma in front of the current
142  // JSON event or not. Unused by the other formats.
143  bool needs_comma_ = false;
144 
147  int indent_ = -1; // -1 gives the most compact JSON file possible
148 
150  int_fast64_t byte_count_ = 0;
151 
155  double flux_avg_tot_xsec_ = 0.;
156 
157  public:
158 
159  TextOutputFile(const std::string& name, const std::string& format,
160  const std::string& mode, bool force = false, int indent = -1);
161 
162  virtual ~TextOutputFile() = default;
163 
164  inline void set_indent(int indent) { indent_ = indent; }
165 
166  virtual void open() override;
167 
168  // TODO: consider a better way of doing this
169  // Returns true if the generator was successfully restored from the
170  // saved metadata, or false otherwise.
171  virtual bool resume(std::unique_ptr<marley::Generator>& gen,
172  long& num_previous_events) override;
173 
174  int_fast64_t bytes_written() override;
175 
176  // Write a new marley::Event to this output file
177  virtual void write_event(const marley::Event* event) override;
178 
179  void write_generator_state(const marley::JSON& json_config,
180  const marley::Generator& gen, const long num_events) override;
181 
182  virtual void close(const marley::JSON& json_config,
183  const marley::Generator& gen, const long num_events) override;
184 
185  // This function is a no-op for the JSON format (we will write the
186  // flux-averaged cross section to the output file when saving the
187  // generator state)
188  virtual void write_flux_avg_tot_xsec(double avg_tot_xsec) override;
189  };
190 
191 }
Container for ingoing and outgoing momentum 4-vectors from a reaction.
Definition: Event.hh:66
The MARLEY Event generator.
Definition: Generator.hh:42
Definition: JSON.hh:62
Abstract base class for objects that deliver output to a file opened by the marley command-line execu...
Definition: OutputFile.hh:29
virtual int_fast64_t bytes_written()=0
The number of bytes that have been written during the current MARLEY session to this file.
virtual void write_flux_avg_tot_xsec(double avg_tot_xsec)=0
If needed (for the HEPEVT and ASCII formats), write the flux-averaged total cross section to the file...
virtual void write_generator_state(const marley::JSON &json_config, const marley::Generator &gen, const long num_events)=0
For the file formats that support it, write metadata containing the generator state and configuration...
virtual void write_event(const marley::Event *event)=0
Write a new marley::Event to this output file.
Format format_
Format to use when writing events to the file.
Definition: OutputFile.hh:123
virtual void open()=0
Open the output file for writing.
virtual void close(const marley::JSON &json_config, const marley::Generator &gen, const long num_events)=0
Close the output file and perform any necessary cleanup.
std::unique_ptr< marley::Generator > restore_generator(const marley::JSON &config)
Helper function for resume() that instantiates a marley::Generator object given the previous JSON con...
Definition: OutputFile.cc:55
virtual bool resume(std::unique_ptr< marley::Generator > &gen, long &num_previous_events)=0
Load a marley::Generator object whose configuration and state were saved to the metadata in a ROOT or...
bool check_if_file_exists(const std::string &filename)
Checks that a given file exists (and is readable)
Definition: OutputFile.hh:92
std::string name_
Name of the file to receive output.
Definition: OutputFile.hh:122
Definition: OutputFile.hh:131
virtual void open() override
Open the output file for writing.
Definition: OutputFile.cc:97
void write_generator_state(const marley::JSON &json_config, const marley::Generator &gen, const long num_events) override
For the file formats that support it, write metadata containing the generator state and configuration...
Definition: OutputFile.cc:289
virtual bool resume(std::unique_ptr< marley::Generator > &gen, long &num_previous_events) override
Load a marley::Generator object whose configuration and state were saved to the metadata in a ROOT or...
Definition: OutputFile.cc:137
virtual void write_event(const marley::Event *event) override
Write a new marley::Event to this output file.
Definition: OutputFile.cc:252
virtual void write_flux_avg_tot_xsec(double avg_tot_xsec) override
If needed (for the HEPEVT and ASCII formats), write the flux-averaged total cross section to the file...
Definition: OutputFile.cc:341
virtual void close(const marley::JSON &json_config, const marley::Generator &gen, const long num_events) override
Close the output file and perform any necessary cleanup.
Definition: OutputFile.cc:318
int_fast64_t bytes_written() override
The number of bytes that have been written during the current MARLEY session to this file.
Definition: OutputFile.cc:242