Version: SMASH-1.7
oscaroutput.cc
Go to the documentation of this file.
1 /*
2  *
3  * Copyright (c) 2014-2019
4  * SMASH Team
5  *
6  * GNU General Public License (GPLv3 or later)
7  *
8  */
9 #include "smash/oscaroutput.h"
10 
11 #include <string>
12 
13 #include <boost/filesystem.hpp>
14 
15 #include "smash/action.h"
16 #include "smash/clock.h"
17 #include "smash/config.h"
18 #include "smash/configuration.h"
19 #include "smash/cxx14compat.h"
21 #include "smash/particles.h"
22 
23 namespace smash {
24 
25 template <OscarOutputFormat Format, int Contents>
27  const std::string &name)
28  : OutputInterface(name),
29  file_{path /
30  (name + ".oscar" + ((Format == OscarFormat1999) ? "1999" : "")),
31  "w"} {
81  if (Format == OscarFormat2013) {
82  std::fprintf(file_.get(),
83  "#!OSCAR2013 %s t x y z mass "
84  "p0 px py pz pdg ID charge\n",
85  name.c_str());
86  std::fprintf(file_.get(),
87  "# Units: fm fm fm fm "
88  "GeV GeV GeV GeV GeV none none e\n");
89  std::fprintf(file_.get(), "# %s\n", VERSION_MAJOR);
90  } else if (Format == OscarFormat2013Extended) {
91  std::fprintf(file_.get(),
92  "#!OSCAR2013Extended %s t x y z mass p0 px py pz"
93  " pdg ID charge ncoll form_time xsecfac proc_id_origin"
94  " proc_type_origin time_last_coll pdg_mother1 pdg_mother2\n",
95  name.c_str());
96  std::fprintf(file_.get(),
97  "# Units: fm fm fm fm GeV GeV GeV GeV GeV"
98  " none none e none fm none none none fm none none\n");
99  std::fprintf(file_.get(), "# %s\n", VERSION_MAJOR);
100  } else {
101  const std::string &oscar_name =
102  name == "particle_lists" ? "final_id_p_x" : name;
103  // This is necessary because OSCAR199A requires
104  // this particular string for particle output.
105 
106  std::fprintf(file_.get(), "# OSC1999A\n# %s\n# %s\n", oscar_name.c_str(),
107  VERSION_MAJOR);
108  std::fprintf(file_.get(), "# Block format:\n");
109  std::fprintf(file_.get(), "# nin nout event_number\n");
110  std::fprintf(file_.get(), "# id pdg 0 px py pz p0 mass x y z t\n");
111  std::fprintf(file_.get(),
112  "# End of event: 0 0 event_number"
113  " impact_parameter\n");
114  std::fprintf(file_.get(), "#\n");
115  }
116 }
117 
118 template <OscarOutputFormat Format, int Contents>
119 inline void OscarOutput<Format, Contents>::write(const Particles &particles) {
120  for (const ParticleData &data : particles) {
121  write_particledata(data);
122  }
123 }
124 
125 template <OscarOutputFormat Format, int Contents>
127  const int event_number) {
128  current_event_ = event_number;
129  if (Contents & OscarAtEventstart) {
130  if (Format == OscarFormat2013 || Format == OscarFormat2013Extended) {
131  std::fprintf(file_.get(), "# event %i in %zu\n", event_number + 1,
132  particles.size());
133  } else {
134  /* OSCAR line prefix : initial particles; final particles; event id
135  * First block of an event: initial = 0, final = number of particles
136  */
137  const size_t zero = 0;
138  std::fprintf(file_.get(), "%zu %zu %i\n", zero, particles.size(),
139  event_number + 1);
140  }
141  if (!(Contents == OscarParticlesIC)) {
142  // We do not want the inital particle list to be printed in case of IC
143  // output
144  write(particles);
145  }
146  }
147 }
148 
149 template <OscarOutputFormat Format, int Contents>
151  const int event_number,
152  double impact_parameter,
153  bool empty_event) {
154  if (Format == OscarFormat2013 || Format == OscarFormat2013Extended) {
155  if (Contents & OscarParticlesAtEventend) {
156  std::fprintf(file_.get(), "# event %i out %zu\n", event_number + 1,
157  particles.size());
158  write(particles);
159  }
160  // Comment end of an event
161  const char *empty_event_str = empty_event ? "yes" : "no";
162  std::fprintf(file_.get(), "# event %i end 0 impact %7.3f empty %s\n",
163  event_number + 1, impact_parameter, empty_event_str);
164  } else {
165  /* OSCAR line prefix : initial particles; final particles; event id
166  * Last block of an event: initial = number of particles, final = 0
167  * Block ends with null interaction. */
168  const size_t zero = 0;
169  if (Contents & OscarParticlesAtEventend) {
170  std::fprintf(file_.get(), "%zu %zu %i\n", particles.size(), zero,
171  event_number + 1);
172  write(particles);
173  }
174  // Null interaction marks the end of an event
175  std::fprintf(file_.get(), "%zu %zu %i %7.3f\n", zero, zero,
176  event_number + 1, impact_parameter);
177  }
178  // Flush to disk
179  std::fflush(file_.get());
180 
181  if (Contents == OscarParticlesIC) {
182  const auto &log = logger<LogArea::HyperSurfaceCrossing>();
183  // If the runtime is too short some particles might not yet have
184  // reached the hypersurface. Warning is printed.
185  if (particles.size() != 0) {
186  log.warn(
187  "End time might be too small for initial conditions output. "
188  "Hypersurface has not yet been crossed by ",
189  particles.size(), " particle(s).");
190  }
191  }
192 }
193 
194 template <OscarOutputFormat Format, int Contents>
196  const double density) {
197  if (Contents & OscarInteractions) {
198  if (Format == OscarFormat2013 || Format == OscarFormat2013Extended) {
199  std::fprintf(file_.get(),
200  "# interaction in %zu out %zu rho %12.7f weight %12.7g"
201  " partial %12.7f type %5i\n",
202  action.incoming_particles().size(),
203  action.outgoing_particles().size(), density,
204  action.get_total_weight(), action.get_partial_weight(),
205  static_cast<int>(action.get_type()));
206  } else {
207  /* OSCAR line prefix : initial final
208  * particle creation: 0 1
209  * particle 2<->2 collision: 2 2
210  * resonance formation: 2 1
211  * resonance decay: 1 2
212  * etc.*/
213  std::fprintf(file_.get(), "%zu %zu %12.7f %12.7f %12.7f %5i\n",
214  action.incoming_particles().size(),
215  action.outgoing_particles().size(), density,
216  action.get_total_weight(), action.get_partial_weight(),
217  static_cast<int>(action.get_type()));
218  }
219  for (const auto &p : action.incoming_particles()) {
220  write_particledata(p);
221  }
222  for (const auto &p : action.outgoing_particles()) {
223  write_particledata(p);
224  }
225  } else if (Contents == OscarParticlesIC) {
226  for (const auto &p : action.incoming_particles()) {
227  write_particledata(p);
228  }
229  }
230 }
231 
232 template <OscarOutputFormat Format, int Contents>
234  const Particles &particles, const std::unique_ptr<Clock> &,
235  const DensityParameters &) {
236  if (Contents & OscarTimesteps) {
237  if (Format == OscarFormat2013 || Format == OscarFormat2013Extended) {
238  std::fprintf(file_.get(), "# event %i out %zu\n", current_event_ + 1,
239  particles.size());
240  } else {
241  const size_t zero = 0;
242  std::fprintf(file_.get(), "%zu %zu %i\n", particles.size(), zero,
243  current_event_ + 1);
244  }
245  write(particles);
246  }
247 }
248 
699 template <OscarOutputFormat Format, int Contents>
701  const ParticleData &data) {
702  const FourVector pos = data.position();
703  const FourVector mom = data.momentum();
704  if (Format == OscarFormat2013) {
705  std::fprintf(file_.get(), "%g %g %g %g %g %.9g %.9g %.9g %.9g %s %i %i\n",
706  pos.x0(), pos.x1(), pos.x2(), pos.x3(), data.effective_mass(),
707  mom.x0(), mom.x1(), mom.x2(), mom.x3(),
708  data.pdgcode().string().c_str(), data.id(),
709  data.type().charge());
710  } else if (Format == OscarFormat2013Extended) {
711  const auto h = data.get_history();
712  std::fprintf(
713  file_.get(),
714  "%g %g %g %g %g %.9g %.9g %.9g"
715  " %.9g %s %i %i %i %g %g %i %i %g %s %s\n",
716  pos.x0(), pos.x1(), pos.x2(), pos.x3(), data.effective_mass(), mom.x0(),
717  mom.x1(), mom.x2(), mom.x3(), data.pdgcode().string().c_str(),
718  data.id(), data.type().charge(), h.collisions_per_particle,
719  data.formation_time(), data.xsec_scaling_factor(), h.id_process,
720  static_cast<int>(h.process_type), h.time_last_collision,
721  h.p1.string().c_str(), h.p2.string().c_str());
722  } else {
723  std::fprintf(file_.get(), "%i %s %i %g %g %g %g %g %g %g %g %g\n",
724  data.id(), data.pdgcode().string().c_str(), 0, mom.x1(),
725  mom.x2(), mom.x3(), mom.x0(), data.effective_mass(), pos.x1(),
726  pos.x2(), pos.x3(), pos.x0());
727  }
728 }
729 
730 namespace {
742 template <int Contents>
743 std::unique_ptr<OutputInterface> create_select_format(
744  bool modern_format, const bf::path &path, const OutputParameters &out_par,
745  const std::string &name) {
746  const auto &log = logger<LogArea::Output>();
747  bool extended_format = (Contents & OscarInteractions) ? out_par.coll_extended
748  : out_par.part_extended;
749  if (modern_format && extended_format) {
750  return make_unique<OscarOutput<OscarFormat2013Extended, Contents>>(path,
751  name);
752  } else if (modern_format && !extended_format) {
753  return make_unique<OscarOutput<OscarFormat2013, Contents>>(path, name);
754  } else if (!modern_format && !extended_format) {
755  return make_unique<OscarOutput<OscarFormat1999, Contents>>(path, name);
756  } else {
757  // Only remaining possibility: (!modern_format && extended_format)
758  log.warn() << "Creating Oscar output: "
759  << "There is no extended Oscar1999 format.";
760  return make_unique<OscarOutput<OscarFormat1999, Contents>>(path, name);
761  }
762 }
763 } // unnamed namespace
764 
765 std::unique_ptr<OutputInterface> create_oscar_output(
766  const std::string &format, const std::string &content, const bf::path &path,
767  const OutputParameters &out_par) {
768  const auto &log = logger<LogArea::Output>();
769  if (format != "Oscar2013" && format != "Oscar1999") {
770  throw std::invalid_argument("Creating Oscar output: unknown format");
771  }
772  const bool modern_format = (format == "Oscar2013");
773  if (content == "Particles") {
774  if (out_par.part_only_final) {
775  return create_select_format<OscarParticlesAtEventend>(
776  modern_format, path, out_par, "particle_lists");
777  } else {
780  modern_format, path, out_par, "particle_lists");
781  }
782  } else if (content == "Collisions") {
783  if (out_par.coll_printstartend) {
786  modern_format, path, out_par, "full_event_history");
787  } else {
788  return create_select_format<OscarInteractions>(
789  modern_format, path, out_par, "full_event_history");
790  }
791  } else if (content == "Dileptons") {
792  if (modern_format && out_par.dil_extended) {
793  return make_unique<
795  "Dileptons");
796  } else if (modern_format && !out_par.dil_extended) {
797  return make_unique<OscarOutput<OscarFormat2013, OscarInteractions>>(
798  path, "Dileptons");
799  } else if (!modern_format && !out_par.dil_extended) {
800  return make_unique<OscarOutput<OscarFormat1999, OscarInteractions>>(
801  path, "Dileptons");
802  } else if (!modern_format && out_par.dil_extended) {
803  log.warn() << "Creating Oscar output: "
804  << "There is no extended Oscar1999 (dileptons) format.";
805  }
806  } else if (content == "Photons") {
807  if (modern_format && !out_par.photons_extended) {
808  return make_unique<OscarOutput<OscarFormat2013, OscarInteractions>>(
809  path, "Photons");
810  } else if (modern_format && out_par.photons_extended) {
811  return make_unique<
813  "Photons");
814  } else if (!modern_format && !out_par.photons_extended) {
815  return make_unique<OscarOutput<OscarFormat1999, OscarInteractions>>(
816  path, "Photons");
817  } else if (!modern_format && out_par.photons_extended) {
818  log.warn() << "Creating Oscar output: "
819  << "There is no extended Oscar1999 (photons) format.";
820  }
821  } else if (content == "Initial_Conditions") {
822  if (modern_format && !out_par.ic_extended) {
823  return make_unique<OscarOutput<OscarFormat2013, OscarParticlesIC>>(
824  path, "SMASH_IC");
825  } else if (modern_format && out_par.ic_extended) {
826  return make_unique<
828  "SMASH_IC");
829  } else if (!modern_format && !out_par.ic_extended) {
830  return make_unique<OscarOutput<OscarFormat1999, OscarParticlesIC>>(
831  path, "SMASH_IC");
832  } else if (!modern_format && out_par.ic_extended) {
833  log.warn()
834  << "Creating Oscar output: "
835  << "There is no extended Oscar1999 (initial conditions) format.";
836  }
837  }
838 
839  throw std::invalid_argument("Create_oscar_output got unknown content.");
840 }
841 
842 } // namespace smash
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...
Definition: logging.h:317
store the state at the end of each event (at_eventend)
Definition: oscaroutput.h:50
double formation_time() const
Get the absolute formation time of the particle.
Definition: particledata.h:217
A class to pre-calculate and store parameters relevant for density calculation.
Definition: density.h:106
PdgCode pdgcode() const
Get the pdgcode of the particle.
Definition: particledata.h:81
std::unique_ptr< T > make_unique(Args &&...args)
Definition for make_unique Is in C++14&#39;s standard library; necessary for older compilers.
Definition: cxx14compat.h:25
const FourVector & position() const
Get the particle&#39;s position in Minkowski space.
Definition: particledata.h:185
bool part_extended
Extended format for particles output.
virtual double get_partial_weight() const =0
Return the specific weight for the chosen outgoing channel, which is mainly used for the partial weig...
bool ic_extended
Extended initial conditions output.
virtual ProcessType get_type() const
Get the process type.
Definition: action.h:130
void write_particledata(const ParticleData &data)
Write single particle information line to output.
Definition: oscaroutput.cc:700
double x0() const
Definition: fourvector.h:303
void at_eventend(const Particles &particles, const int event_number, double impact_parameter, bool empty_event) override
Writes the final particle information of an event to the oscar output.
Definition: oscaroutput.cc:150
double effective_mass() const
Get the particle&#39;s effective mass.
Definition: particledata.cc:21
bool coll_printstartend
Print initial and final particles in event into collision output.
std::unique_ptr< OutputInterface > create_oscar_output(const std::string &format, const std::string &content, const bf::path &path, const OutputParameters &out_par)
Definition: oscaroutput.cc:765
HistoryData get_history() const
Get history information.
Definition: particledata.h:120
store the state after N timesteps (after_Nth_timestep)
Definition: oscaroutput.h:46
double xsec_scaling_factor(double delta_time=0.) const
Return the cross section scaling factor at a given time.
Definition: particledata.cc:73
double x3() const
Definition: fourvector.h:315
bool photons_extended
Extended format for photon output.
bool part_only_final
Print only final particles in event.
size_t size() const
Definition: particles.h:87
bool coll_extended
Extended format for collisions output.
OscarOutput(const bf::path &path, const std::string &name)
Create oscar output.
Helper structure for Experiment to hold output options and parameters.
store the particles that are removed on the hypersurface
Definition: oscaroutput.h:52
const ParticleType & type() const
Get the type of the particle.
Definition: particledata.h:109
Action is the base class for a generic process that takes a number of incoming particles and transfor...
Definition: action.h:34
virtual double get_total_weight() const =0
Return the total weight value, which is mainly used for the weight output entry.
int32_t charge() const
The charge of the particle.
Definition: particletype.h:188
void at_eventstart(const Particles &particles, const int event_number) override
Writes the initial particle information of an event to the oscar output.
Definition: oscaroutput.cc:126
bool dil_extended
Extended format for dilepton output.
store the state at the start of each event (at_eventstart)
Definition: oscaroutput.h:48
constexpr int p
Proton.
void at_interaction(const Action &action, const double density) override
Writes a interaction prefix line and a line for every incoming and outgoing particle to the oscar out...
Definition: oscaroutput.cc:195
std::unique_ptr< OutputInterface > create_select_format(bool modern_format, const bf::path &path, const OutputParameters &out_par, const std::string &name)
Helper function that creates the oscar output with the format selected by create_oscar_output (except...
Definition: oscaroutput.cc:743
store interaction information (write_interaction)
Definition: oscaroutput.h:44
const ParticleList & incoming_particles() const
Get the list of particles that go into the action.
Definition: action.cc:58
double x2() const
Definition: fourvector.h:311
void at_intermediate_time(const Particles &particles, const std::unique_ptr< Clock > &clock, const DensityParameters &dens_param) override
Writes a prefix line then write out all current particles.
Definition: oscaroutput.cc:233
The Particles class abstracts the storage and manipulation of particles.
Definition: particles.h:33
const ParticleList & outgoing_particles() const
Get the list of particles that resulted from the action.
Definition: action.h:244
int32_t id() const
Get the id of the particle.
Definition: particledata.h:70
The FourVector class holds relevant values in Minkowski spacetime with (+, −, −, −) metric signature.
Definition: fourvector.h:33
double x1() const
Definition: fourvector.h:307
void write(const Particles &particles)
Write the particle information of a list of particles to the output.
Definition: oscaroutput.cc:119
ParticleData contains the dynamic information of a certain particle.
Definition: particledata.h:52
Definition: action.h:24
const FourVector & momentum() const
Get the particle&#39;s 4-momentum.
Definition: particledata.h:139
std::string string() const
Definition: pdgcode.h:252