22#include "HepMC3/Attribute.h"
23#include "HepMC3/GenEvent.h"
24#include "HepMC3/GenRunInfo.h"
25#include "HepMC3/ReaderAscii.h"
26#include "HepMC3/WriterAscii.h"
29#include "marley/OutputFileAscii.hh"
30#include "marley/Error.hh"
31#include "marley/Generator.hh"
32#include "marley/JSON.hh"
33#include "marley/JSONConfig.hh"
37 constexpr char DUMMY_CHAR =
'a';
45 std::streampos seek_to_last_genevent( std::fstream& stream ) {
47 char old_c = DUMMY_CHAR;
48 stream.seekg( 0, std::ios::end );
49 std::streampos size = stream.tellg();
50 for (
int i = 1; i <= size; ++i ) {
51 stream.seekg( -i, std::ios::end );
54 if ( c ==
'\n' && old_c ==
'E' ) {
55 stream.seekg( -i + 1, std::ios::end );
57 return stream.tellg();
60 return std::streampos( -1 );
65marley::OutputFileAscii::OutputFileAscii(
const marley::JSON& output_config )
66 : marley::OutputFile( output_config )
68 format_ = Format::ASCII;
71 reader_ = std::make_shared< HepMC3::ReaderAscii >( stream_ );
72 writer_ = std::make_shared< HepMC3::WriterAscii >( stream_ );
75 writer_->set_precision( std::numeric_limits<double>::max_digits10 );
82 auto open_mode_flag = std::ios::in | std::ios::out | std::ios::trunc;
84 if ( mode_ == Mode::RESUME ) {
87 " not open the file \"" +
name_ +
'\"' );
88 else open_mode_flag = std::ios::in | std::ios::out;
90 else if ( mode_ != Mode::OVERWRITE ) {
92 " OutputFileAscii::open()" );
100 long& num_previous_events )
102 if ( mode_ != Mode::RESUME ) {
103 throw marley::Error(
"Cannot call OutputFileAscii::resume() for an output"
104 " mode other than \"resume\"" );
108 MARLEY_LOG( INFO,
"io" ) <<
"Continuing previous run from the file " <<
name_;
111 auto evt = std::make_shared< HepMC3::GenEvent >();
115 stream_.seekg( 0, std::ios::beg );
116 bool read_ok =
reader_->read_event( *evt );
118 auto run_info = evt->run_info();
120 if ( !read_ok || !run_info ) {
121 throw marley::Error(
"Failed to retrieve run information from the file "
128 "MARLEY.JSONconfig" );
131 throw marley::Error(
"Failed to retrieve generator configuration from the"
141 " generator seed from the file " +
name_ );
146 auto json_config = marley::JSON::load( config_str->value() );
150 std::streampos last_event_pos = seek_to_last_genevent(
stream_ );
152 if ( last_event_pos == std::streampos( -1 ) ) {
153 throw marley::Error(
"Failed to find the last event in the file "
159 read_ok =
reader_->read_event( *evt );
162 "MARLEY.GeneratorState" );
164 if ( !read_ok || !state_str ) {
165 throw marley::Error(
"Failed to retrieve generator state from the file "
173 num_previous_events = evt->event_number();
175 MARLEY_LOG( INFO,
"io" ) <<
"Resuming run from \"" <<
name_ <<
"\":"
176 <<
" found " << num_previous_events <<
" previous event(s)";
181 gen->seed_using_state_string( state_str->value() );
183 MARLEY_LOG( INFO,
"io" ) <<
"The previous run was initialized using"
184 <<
" the random number generator seed " << seed_str->value();
194 gen->set_up_run_info();
203 evt->set_run_info( gen->run_info() );
204 evt->remove_attribute(
"MARLEY.GeneratorState" );
224 " OutputFileAscii::write_event()" );
228 std::filesystem::resize_file(
name_,
240 writer_->write_event( *event );
Stores event-related information.
Attribute that holds a string.
Base class for all exceptions thrown by MARLEY functions.
virtual void open()
Opens the owned std::fstream with the correct settings.
std::fstream stream_
Stream used to read and write from the output file as needed.
std::shared_ptr< HepMC3::ReaderAscii > reader_
std::shared_ptr< HepMC3::GenEvent > pending_flush_event_
virtual void write_event(HepMC3::GenEvent *event) override
Write a new HepMC3::GenEvent to this output file.
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 the outpu...
int_fast64_t byte_count_
Storage for the number of bytes written to disk.
std::streampos pending_truncate_pos_
std::shared_ptr< HepMC3::WriterAscii > writer_
Helper object used to produce standard ASCII HepMC3 output.
virtual int_fast64_t bytes_written() override
The number of bytes that have been written during the current MARLEY session to this file.
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...
void prompt_before_overwrite()
If mode_ is OVERWRITE and the output file already exists and force_ is false, prompt the user before ...
static void merge_reweight_provenance_weights(HepMC3::GenRunInfo &run_info, marley::Generator &gen)
When resuming from a file that has been through one or more reweight passes, merge the reweight prove...
bool check_if_file_exists(const std::string &filename)
Checks that a given file exists (and is readable)
std::string name_
Name of the file to receive output.