17 #include "smash/config.h"
22 template <OscarOutputFormat Format,
int Contents>
24 const std::filesystem::path &path,
const std::string &name,
25 const std::vector<std::string> quantities)
26 : OutputInterface(name),
27 file_{path / (name + ((Format ==
ASCII) ?
".dat" :
".oscar") +
30 formatter_{Format ==
ASCII ? quantities
32 ? OutputDefaultQuantities::oscar2013
34 ? OutputDefaultQuantities::oscar2013extended
35 : OutputDefaultQuantities::oscar1999} {
85 if (Format !=
ASCII && !quantities.empty()) {
86 throw std::logic_error(
87 "Non-empty Quantities given alongside format other than ASCII.");
89 std::string format_name;
90 if (Format ==
ASCII) {
91 format_name =
"ASCII";
93 format_name =
"OSCAR2013";
95 format_name =
"OSCAR2013Extended";
97 format_name =
"OSC1999A";
101 std::fprintf(file_.get(),
"#!%s %s %s", format_name.c_str(), name.c_str(),
102 formatter_.quantities_line().c_str());
103 std::fprintf(file_.get(),
"# Units: %s", formatter_.unit_line().c_str());
104 std::fprintf(file_.get(),
"# %s\n", SMASH_VERSION);
106 const std::string &oscar_name =
107 name ==
"particle_lists" ?
"final_id_p_x" : name;
111 std::fprintf(file_.get(),
"# %s\n# %s\n# %s\n", format_name.c_str(),
112 oscar_name.c_str(), SMASH_VERSION);
113 std::fprintf(file_.get(),
"# Block format:\n");
114 if (oscar_name ==
"full_event_history") {
115 std::fprintf(file_.get(),
116 "# nin nout density tot_weight part_weight proc_type\n");
118 std::fprintf(file_.get(),
"# nin nout event_number ensemble_number\n");
120 std::fprintf(file_.get(),
"# %s", formatter_.quantities_line().c_str());
123 "# End of event: 0 0 event_number ensemble_number impact_parameter\n");
124 std::fprintf(file_.get(),
"#\n");
128 template <OscarOutputFormat Format,
int Contents>
130 write_in_chunk<ToASCII>(
131 particles, formatter_,
135 template <OscarOutputFormat Format,
int Contents>
144 std::fprintf(file_.get(),
"# event %i ensemble %i in %zu\n",
151 const size_t zero = 0;
152 std::fprintf(file_.get(),
"%zu %zu %i %i\n", zero, particles.
size(),
159 std::fprintf(file_.get(),
"# event %i ensemble %i start\n",
162 const size_t zero = 0;
163 std::fprintf(file_.get(),
"%zu %zu %i %i\n", zero, zero,
169 template <OscarOutputFormat Format,
int Contents>
177 std::fprintf(file_.get(),
"# event %i ensemble %i out %zu\n",
184 const char *empty_event_str =
event.empty_event ?
"no" :
"yes";
185 std::fprintf(file_.get(),
186 "# event %i ensemble %i end 0 impact %7.3f "
187 "scattering_projectile_target %s\n",
191 std::fprintf(file_.get(),
"# event %i ensemble %i end\n",
198 const size_t zero = 0;
201 std::fprintf(file_.get(),
"%zu %zu %i %i\n", particles.
size(), zero,
206 std::fprintf(file_.get(),
"%zu %zu %i %i %7.3f\n", zero, zero,
211 std::fflush(file_.get());
214 template <OscarOutputFormat Format,
int Contents>
216 const double density) {
220 std::fprintf(file_.get(),
221 "# interaction in %zu out %zu rho %12.7f weight %12.7g"
222 " partial %12.7f type %5i\n",
226 static_cast<int>(action.
get_type()));
234 std::fprintf(file_.get(),
"%zu %zu %12.7f %12.7f %12.7f %5i\n",
238 static_cast<int>(action.
get_type()));
241 write_particledata(
p);
244 write_particledata(
p);
248 write_particledata(
p);
253 template <OscarOutputFormat Format,
int Contents>
255 const Particles &particles,
const std::unique_ptr<Clock> &,
261 std::fprintf(file_.get(),
"# event %i ensemble %i out %zu\n",
265 const size_t zero = 0;
266 std::fprintf(file_.get(),
"%zu %zu %i %i\n", particles.
size(), zero,
862 template <OscarOutputFormat Format,
int Contents>
865 std::fprintf(file_.get(),
"%s",
866 formatter_.single_particle_data(data).c_str());
869 template <OscarOutputFormat Format,
int Contents>
871 std::fprintf(file_.get(),
"%s", buffer.c_str());
889 template <
int Contents>
891 const std::filesystem::path &path,
const std::string &name,
892 bool modern_format,
bool extended_format,
bool custom_format,
893 const std::vector<std::string> &quantities) {
895 return std::make_unique<OscarOutput<ASCII, Contents>>(path, name,
898 if (modern_format && extended_format) {
899 return std::make_unique<OscarOutput<OscarFormat2013Extended, Contents>>(
901 }
else if (modern_format && !extended_format) {
902 return std::make_unique<OscarOutput<OscarFormat2013, Contents>>(path,
904 }
else if (!modern_format && !extended_format) {
905 return std::make_unique<OscarOutput<OscarFormat1999, Contents>>(path,
909 logg[
LOutput].warn() <<
"There is no extended Oscar1999 format, creating "
910 "a regular Oscar1999 output instead.";
911 return std::make_unique<OscarOutput<OscarFormat1999, Contents>>(path,
919 const std::string &
format,
const std::string &content,
922 throw std::invalid_argument(
"Creating Oscar output: unknown format");
924 const bool modern_format = (
format ==
"Oscar2013");
925 const bool custom_format = (
format ==
"ASCII");
926 const auto &quantities = custom_format ? out_par.
quantities.at(content)
927 : std::vector<std::string>{};
929 if (content ==
"Particles") {
931 return create_selected_format<OscarParticlesAtEventend>(
932 path,
"particle_lists", modern_format, out_par.
part_extended,
933 custom_format, quantities);
935 return create_selected_format<OscarParticlesAtEventendIfNotEmpty>(
936 path,
"particle_lists", modern_format, out_par.
part_extended,
937 custom_format, quantities);
941 path,
"particle_lists", modern_format, out_par.
part_extended,
942 custom_format, quantities);
944 }
else if (content ==
"Collisions") {
948 path,
"full_event_history", modern_format, out_par.
coll_extended,
949 custom_format, quantities);
951 return create_selected_format<OscarInteractions>(
952 path,
"full_event_history", modern_format, out_par.
coll_extended,
953 custom_format, quantities);
955 }
else if (content ==
"Dileptons") {
956 return create_selected_format<OscarInteractions>(
957 path,
"Dileptons", modern_format, out_par.
dil_extended, custom_format,
959 }
else if (content ==
"Photons") {
960 return create_selected_format<OscarInteractions>(
963 }
else if (content ==
"Initial_Conditions") {
964 return create_selected_format<OscarParticlesIC | OscarAtEventstart>(
965 path,
"SMASH_IC", modern_format, out_par.
ic_extended, custom_format,
969 throw std::invalid_argument(
"Create_oscar_output got unknown content.");
Action is the base class for a generic process that takes a number of incoming particles and transfor...
virtual ProcessType get_type() const
Get the process type.
virtual double get_total_weight() const =0
Return the total weight value, which is mainly used for the weight output entry.
const ParticleList & incoming_particles() const
Get the list of particles that go into the action.
virtual double get_partial_weight() const =0
Return the specific weight for the chosen outgoing channel, which is mainly used for the partial weig...
const ParticleList & outgoing_particles() const
Get the list of particles that resulted from the action.
A class to pre-calculate and store parameters relevant for density calculation.
ParticleData contains the dynamic information of a certain particle.
The Particles class abstracts the storage and manipulation of particles.
@ IfNotEmpty
Print only final-state particles, and those only if the event is not empty.
@ Yes
Print only final-state particles.
std::array< einhard::Logger<>, std::tuple_size< LogArea::AreaTuple >::value > logg
An array that stores all pre-configured Logger objects.
FormattingHelper< T > format(const T &value, const char *unit, int width=-1, int precision=-1)
Acts as a stream modifier for std::ostream to output an object with an optional suffix string and wit...
OscarOutput(const std::filesystem::path &path, const std::string &name, const std::vector< std::string > quantities={})
Create oscar output.
std::unique_ptr< OutputInterface > create_oscar_output(const std::string &format, const std::string &content, const std::filesystem::path &path, const OutputParameters &out_par)
@ OscarParticlesAtEventend
store the state at the end of each event (at_eventend)
@ OscarParticlesAtEventendIfNotEmpty
store the state at the end of each event if it is not empty (at_eventend)
@ OscarAtEventstart
store the state at the start of each event (at_eventstart)
@ OscarInteractions
store interaction information (write_interaction)
@ OscarParticlesIC
store the particles that are removed on the hypersurface
@ OscarTimesteps
store the state after N timesteps (after_Nth_timestep)
@ OscarFormat2013Extended
std::unique_ptr< OutputInterface > create_selected_format(const std::filesystem::path &path, const std::string &name, bool modern_format, bool extended_format, bool custom_format, const std::vector< std::string > &quantities)
Helper function that creates the oscar output with the format selected by create_oscar_output.
static constexpr int LOutput
Structure to contain custom data for output.
bool empty_event
True if no collisions happened.
double impact_parameter
Impact parameter for collider modus, otherwise dummy.
Structure to contain information about the event and ensemble numbers.
int32_t ensemble_number
The number of the ensemble.
int32_t event_number
The number of the event.
Helper structure for Experiment to hold output options and parameters.
bool dil_extended
Extended format for dilepton output.
bool coll_extended
Extended format for collisions output.
bool part_extended
Extended format for particles output.
bool photons_extended
Extended format for photon output.
std::map< std::string, std::vector< std::string > > quantities
Map of quantities to be printed in the output.
OutputOnlyFinal part_only_final
Print only final particles in event.
bool ic_extended
Extended initial conditions output.
bool coll_printstartend
Print initial and final particles in event into collision output.
std::string type
Return type of this converter.