Version: SMASH-3.4
oscaroutput.cc
Go to the documentation of this file.
1 /*
2  *
3  * Copyright (c) 2014-2026
4  * SMASH Team
5  *
6  * GNU General Public License (GPLv3 or later)
7  *
8  */
9 
10 #include "smash/oscaroutput.h"
11 
12 #include <filesystem>
13 #include <string>
14 
15 #include "smash/action.h"
16 #include "smash/clock.h"
17 #include "smash/config.h"
19 
20 namespace smash {
21 
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") +
28  ((Format == OscarFormat1999) ? "1999" : "")),
29  "w"},
30  formatter_{Format == ASCII ? quantities
31  : (Format == OscarFormat2013)
32  ? OutputDefaultQuantities::oscar2013
33  : (Format == OscarFormat2013Extended)
34  ? OutputDefaultQuantities::oscar2013extended
35  : OutputDefaultQuantities::oscar1999} {
36  /*!\Userguide
37  * \page doxypage_output_oscar
38  * OSCAR outputs are a family of ASCII and binary formats that follow
39  * the OSCAR format conventions. \n
40  * **All OSCAR outputs have the same general structure: a header and an
41  * arbitrary number of event blocks.** Each event block consists of an
42  * arbitrary number of output blocks and special event end lines that mark the
43  * end of an event. One output block consists of an output block header and N
44  * particle lines, where N is specified in the output block header. \n
45  * The file structure can be visualized in the following way:
46  * \code
47  * Header
48  * Event block 1
49  * output block 1
50  * output block header
51  * particle line 1
52  * particle line 2
53  * ...
54  * particle line N
55  * output block 2
56  * ...
57  * output block k
58  * event end line
59  * Event block 2
60  * ...
61  * \endcode
62  * To fully characterise any OSCAR output one has to specify the following
63  * formatting:
64  * \li header
65  * \li output block header
66  * \li particle line
67  * \li event end line
68  *
69  * Each OSCAR output can produce two types of files: collisions output (see
70  * \ref doxypage_output_oscar_collisions) and particles output (see \ref
71  * doxypage_output_oscar_particles). In both output types, the above
72  * structure is the same, however the meaning of the blocks is different. **In
73  * the collision file one output block typically corresponds to one collision
74  * / decay / box wall crossing, while in the particles output one block
75  * corresponds to the current particle list at one moment of time.**
76  * The particles output may contain the particle list at event start
77  * (immediately after initialization), at event end (which is reached when
78  * time is larger or equal than \c End_Time in configuration file) and
79  * periodically during the evolution, the output period is defined by
80  * the \c Output_Interval option in the configuration file, see
81  * \ref input_output_content_specific_ "content-specific output options".
82  * The collisions output contains all collisions / decays / box wall crossings
83  * and optionally the initial and final configuration.
84  */
85  if (Format != ASCII && !quantities.empty()) {
86  throw std::logic_error(
87  "Non-empty Quantities given alongside format other than ASCII.");
88  }
89  std::string format_name;
90  if (Format == ASCII) {
91  format_name = "ASCII";
92  } else if (Format == OscarFormat2013) {
93  format_name = "OSCAR2013";
94  } else if (Format == OscarFormat2013Extended) {
95  format_name = "OSCAR2013Extended";
96  } else {
97  format_name = "OSC1999A";
98  }
99  if (Format == ASCII || Format == OscarFormat2013 ||
100  Format == OscarFormat2013Extended) {
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);
105  } else {
106  const std::string &oscar_name =
107  name == "particle_lists" ? "final_id_p_x" : name;
108  // This is necessary because OSCAR1999A requires
109  // this particular string for particle output.
110 
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");
117  } else {
118  std::fprintf(file_.get(), "# nin nout event_number ensemble_number\n");
119  }
120  std::fprintf(file_.get(), "# %s", formatter_.quantities_line().c_str());
121  std::fprintf(
122  file_.get(),
123  "# End of event: 0 0 event_number ensemble_number impact_parameter\n");
124  std::fprintf(file_.get(), "#\n");
125  }
126 }
127 
128 template <OscarOutputFormat Format, int Contents>
129 inline void OscarOutput<Format, Contents>::write(const Particles &particles) {
130  write_in_chunk<ToASCII>(
131  particles, formatter_,
132  [this](const ToASCII::type &buf) { this->write(buf); });
133 }
134 
135 template <OscarOutputFormat Format, int Contents>
137  const EventLabel &event_label,
138  const EventInfo &) {
139  // We do not want the inital particle list or number to be printed in case of
140  // IC output
141  if (Contents & OscarAtEventstart && !(Contents & OscarParticlesIC)) {
142  if (Format == ASCII || Format == OscarFormat2013 ||
143  Format == OscarFormat2013Extended) {
144  std::fprintf(file_.get(), "# event %i ensemble %i in %zu\n",
145  event_label.event_number, event_label.ensemble_number,
146  particles.size());
147  } else {
148  /* OSCAR line prefix : initial particles; final particles; event id
149  * First block of an event: initial = 0, final = number of particles
150  */
151  const size_t zero = 0;
152  std::fprintf(file_.get(), "%zu %zu %i %i\n", zero, particles.size(),
153  event_label.event_number, event_label.ensemble_number);
154  }
155  write(particles);
156  } else if (Contents & OscarParticlesIC) {
157  if (Format == ASCII || Format == OscarFormat2013 ||
158  Format == OscarFormat2013Extended) {
159  std::fprintf(file_.get(), "# event %i ensemble %i start\n",
160  event_label.event_number, event_label.ensemble_number);
161  } else if (Format == OscarFormat1999) {
162  const size_t zero = 0;
163  std::fprintf(file_.get(), "%zu %zu %i %i\n", zero, zero,
164  event_label.event_number, event_label.ensemble_number);
165  }
166  }
167 }
168 
169 template <OscarOutputFormat Format, int Contents>
171  const EventLabel &event_label,
172  const EventInfo &event) {
173  if (Format == ASCII || Format == OscarFormat2013 ||
174  Format == OscarFormat2013Extended) {
175  if (Contents & OscarParticlesAtEventend ||
176  (Contents & OscarParticlesAtEventendIfNotEmpty && !event.empty_event)) {
177  std::fprintf(file_.get(), "# event %i ensemble %i out %zu\n",
178  event_label.event_number, event_label.ensemble_number,
179  particles.size());
180  write(particles);
181  }
182  // Comment end of an event
183  if (!(Contents & OscarParticlesIC)) {
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",
188  event_label.event_number, event_label.ensemble_number,
189  event.impact_parameter, empty_event_str);
190  } else {
191  std::fprintf(file_.get(), "# event %i ensemble %i end\n",
192  event_label.event_number, event_label.ensemble_number);
193  }
194  } else {
195  /* OSCAR line prefix : initial particles; final particles; event id
196  * Last block of an event: initial = number of particles, final = 0
197  * Block ends with null interaction. */
198  const size_t zero = 0;
199  if (Contents & OscarParticlesAtEventend ||
200  (Contents & OscarParticlesAtEventendIfNotEmpty && !event.empty_event)) {
201  std::fprintf(file_.get(), "%zu %zu %i %i\n", particles.size(), zero,
202  event_label.event_number, event_label.ensemble_number);
203  write(particles);
204  }
205  // Null interaction marks the end of an event
206  std::fprintf(file_.get(), "%zu %zu %i %i %7.3f\n", zero, zero,
207  event_label.event_number, event_label.ensemble_number,
208  event.impact_parameter);
209  }
210  // Flush to disk
211  std::fflush(file_.get());
212 }
213 
214 template <OscarOutputFormat Format, int Contents>
216  const double density) {
217  if (Contents & OscarInteractions) {
218  if (Format == ASCII || Format == OscarFormat2013 ||
219  Format == OscarFormat2013Extended) {
220  std::fprintf(file_.get(),
221  "# interaction in %zu out %zu rho %12.7f weight %12.7g"
222  " partial %12.7f type %5i\n",
223  action.incoming_particles().size(),
224  action.outgoing_particles().size(), density,
225  action.get_total_weight(), action.get_partial_weight(),
226  static_cast<int>(action.get_type()));
227  } else {
228  /* OSCAR line prefix : initial final
229  * particle creation: 0 1
230  * particle 2<->2 collision: 2 2
231  * resonance formation: 2 1
232  * resonance decay: 1 2
233  * etc.*/
234  std::fprintf(file_.get(), "%zu %zu %12.7f %12.7f %12.7f %5i\n",
235  action.incoming_particles().size(),
236  action.outgoing_particles().size(), density,
237  action.get_total_weight(), action.get_partial_weight(),
238  static_cast<int>(action.get_type()));
239  }
240  for (const auto &p : action.incoming_particles()) {
241  write_particledata(p);
242  }
243  for (const auto &p : action.outgoing_particles()) {
244  write_particledata(p);
245  }
246  } else if (Contents & OscarParticlesIC) {
247  for (const auto &p : action.incoming_particles()) {
248  write_particledata(p);
249  }
250  }
251 }
252 
253 template <OscarOutputFormat Format, int Contents>
255  const Particles &particles, const std::unique_ptr<Clock> &,
256  const DensityParameters &, const EventLabel &event_label,
257  const EventInfo &) {
258  if (Contents & OscarTimesteps) {
259  if (Format == ASCII || Format == OscarFormat2013 ||
260  Format == OscarFormat2013Extended) {
261  std::fprintf(file_.get(), "# event %i ensemble %i out %zu\n",
262  event_label.event_number, event_label.ensemble_number,
263  particles.size());
264  } else {
265  const size_t zero = 0;
266  std::fprintf(file_.get(), "%zu %zu %i %i\n", particles.size(), zero,
267  event_label.event_number, event_label.ensemble_number);
268  }
269  write(particles);
270  }
271 }
272 
273 /*!\Userguide
274  * \page doxypage_output_oscar_particles
275  * The OSCAR particles format follows the general block structure of the
276  * \ref doxypage_output_oscar. We distinguish between two versions, OSCAR2013
277  * and OSCAR1999. Additional information about OSCAR standard can be found
278  * <a href="http://phy.duke.edu/~jeb65/oscar2013">here</a>. \n Enabling
279  * the OSCAR output for particles in the config.yaml file (see \ref
280  * doxypage_input_conf_output), a so-called \c particle_lists.oscar file is
281  * produced when executing SMASH. It allows for a certain degree of flexibility,
282  * see \ref input_output_content_specific_ "Content-specific output options" for
283  * further details.
284  *
285  * **Unless IC output is enabled, the Particle output always provides the
286  * current particle list at a specific time.** See \ref
287  * doxypage_output_initial_conditions for details about the particles IC output.
288  * Even though they are compatible, we do not recommend using Oscar1999 for the
289  * Initial_Conditions output.
290  * \n
291  *
292  * \anchor oscar2013_format
293  * <h2> Oscar2013 </h2>
294  *
295  * Oscar2013 is an ASCII (text) human-readable output following the OSCAR 2013
296  * standard. The format specifics are the following:\n
297  * \n
298  * **File header**
299  * \code
300  * #!OSCAR2013 particle_lists t x y z mass p0 px py pz pdg ID charge
301  * # Units: fm fm fm fm GeV GeV GeV GeV GeV none none e
302  * # SMASH_version
303  * \endcode
304  * The header consists of 3 lines starting with '#'. They contain the following
305  * information:
306  * -# Output version (OSCAR2013) and the type of output (particle_lists),
307  * followed by the substructure of the particle lines.
308  * -# Units of the quantities in the particle lines
309  * -# SMASH version
310  *
311  * **File header for extended output**
312  *
313  * If desired, the OSCAR2013 output can be extended
314  * by additional particle properties. This requires enabling the extended
315  * output in the configuration file, see the \key Extended switch in
316  * \ref input_output_content_specific_ "content-specific output options" for
317  * further details. The header of the extended OSCAR output is structured
318  * identically to the non-extended version, but simply contains more columns
319  * because of the additional entries:
320  * <div class="fragment">
321  * <div class="line"><span class="preprocessor">#!OSCAR2013 particle_lists
322  * t x y z mass p0 px py pz pdg
323  * ID charge ncoll form_time xsecfac proc_id_origin proc_type_origin
324  * time_last_coll pdg_mother1 pdg_mother2 baryon_number strangeness</span>
325  * </div>
326  * <div class="line"><span class="preprocessor">\# Units: fm fm fm fm GeV GeV
327  * GeV GeV GeV none none e none fm none none none fm none none none none</span>
328  * </div> <div class="line"><span class="preprocessor">\# SMASH_version</span>
329  * </div>
330  * </div>
331  *
332  * **Block header**
333  *
334  * The OSCAR2013 format is based on a block structure. The beginning of a new
335  * block is marked by either the start of a new event or a new intermediate
336  * output (at the next timestep).
337  *
338  * Output block header for a new event:
339  * \code
340  * # event ev_num ensemble ens_num in Nparticles
341  * \endcode
342  * Where
343  * \li \key ev_num: Event number
344  * \li \key ens_num: Ensemble number
345  * \li \key Nparticles: Number of particles initialized at the beginning of
346  * the event
347  *
348  * Note that `event`, `ensemble` and `in` are no variables, but words that are
349  * printed in the header.
350  *
351  * Output block header for an intermediate output:
352  * \code
353  * # event ev_num ensemble ens_num out Nparticles
354  * \endcode
355  * Where
356  * \li \key ev_num: Event number
357  * \li \key ens_num: Ensemble number
358  * \li \key Nparticles: Number of particles at the end of the timestep
359  *
360  * Note that `event`, `ensemble` and `out` are no variables, but words that are
361  * printed in the header.
362  *
363  * **Particle line**
364  *
365  * The particle lines are formatted as follows:
366  * \code
367  * t x y z mass p0 px py pz pdg ID charge
368  * \endcode
369  *
370  * where
371  * \li \key t, \key x, \key y, \key z: Space-time coordinates
372  * \li \key mass: Rest-mass
373  * \li \key p0, \key px, \key py, \key pz: Energy and 3-momentum
374  * \li \key pdg: PDG code of the particle (see http://pdg.lbl.gov/).
375  * It contains all quantum numbers and uniquely identifies its type
376  * \li \key ID: Particle identifier in terms of an integer, it is
377  * unique for each particle in the event
378  * \li \key charge: the electric charge of the particle in units of the
379  * elementary charge e
380  *
381  * For the **extended output** the particle line contains
382  *
383  * <div class="fragment">
384  * <div class="line"><span class="preprocessor">t x y z mass p0 px py pz pdg
385  * ID charge ncoll form_time xsecfac proc_id_origin proc_type_origin
386  * time_last_coll pdg_mother1 pdg_mother2 baryon_number strangeness</span></div>
387  * </div>
388  *
389  * \anchor extended_output_format_
390  * The additional particle properties available in the extended output format
391  * are:
392  * \li \key ncoll: Number of collisions the particle has undergone
393  * \li \key form_time: Formation time of the particle
394  * \li \key xsecfac: Cross section scaling factor (if the particles are
395  * not yet fully formed at the time of interaction, the cross section for
396  * the underlying process is scaled down by the cross section scaling
397  * factor)
398  * \li \key proc_id_origin: ID of the process of the particle's last interaction
399  * \li \key proc_type_origin: Type of the last process the particle has
400  * undergone. The possible process types are listed in
401  * \ref doxypage_output_process_types
402  * \li \key time_last_coll: time of the particle's last interaction (except wall
403  * crossings)
404  * \li \key pdg_mother1: PDG code of the 1st mother particle (0 in case the
405  * particle is sampled in a thermal bubble. It is not updated by elastic
406  * scatterings)
407  * \li \key pdg_mother2: PDG code of the 2nd mother particle (0 in case the
408  * particle results from the decay of a resonance or the appearance of a
409  * thermal bubble. In the former case, \key pdg_mother1 is the PDG code of
410  * this resonance. It is not updated by elastic scatterings)
411  * \li \key baryon_number: Baryon number of the particle. 1 for baryons, -1 for
412  * anti-baryons and 0 for mesons
413  * \li \key strangeness: Strangeness of the particle
414  *
415  * The mother particles are also set in case of an elastic scattering process.
416  *
417  * **Event end line**\n
418  * The end of an event is indicated by the following line:
419  * \code
420  * # event ev_num ensemble ens_num end 0 impact impact_parameter empty yes_or_no
421  * \endcode
422  * Where
423  * \li \key ev_num: Event number
424  * \li \key ens_num: Ensemble number
425  * \li \key impact_parameter: Impact parameter of the collision in case of a
426  * collider setup, 0.0 otherwise
427  * \li \key yes_or_no: "no" if there was an interaction between the projectile
428  * and the target, "yes" otherwise. For non-collider setups, this is always
429  * "no"
430  *
431  * Note that `event`, `end`, `impact` and `empty` are no variables, but words
432  * that are printed in the header.
433  *
434  * <h2> Oscar1999 </h2>
435  *
436  * Oscar1999 is an ASCII (text) human-readable output following the OSCAR 1999
437  * standard. The format specifics are the following:
438  *
439  * **File header**
440  * \code
441  * # OSC1999A
442  * # final_id_p_x
443  * # smash <version>
444  * # Block format:
445  * # nin nout event_number ensemble_number
446  * # id pdg 0 px py pz p0 mass x y z t
447  * # End of event: 0 0 event_number ensemble_number impact_parameter
448  * #
449  * \endcode
450  * The header consists of 8 lines starting with '#', of which the last one
451  * is basically empty.
452  * They contain the following information:
453  * -# The specific OSCAR1999 version the formatting follows - OSCAR1999A
454  * -# The substructure of each particle line: (id - momentum - coordinates)
455  * -# The SMASH version with which the oputput was generated
456  * -# - 7. Info on the block structure
457  *
458  * **Block header**
459  *
460  * Each output block starts with a line indicating the numbers of ingoing and
461  * outgoing particles as well the numbers of the event and ensemble.
462  * \code
463  * nin nout event_number ensemble_number
464  * \endcode
465  * With
466  * \li \key nin: Number of ingoing particles
467  * \li \key nout: Number of outgoing particles
468  * \li \key event_number: Number of the event
469  * \li \key ensemble_number: Number of the ensemble
470  *
471  * For initial timesteps, (nin, nout) = (0, Nparticles), while (nin, nout) =
472  * (Nparticles, 0) for intermediate and final timesteps. Nparticles is the
473  * total number of particles at the specific timestep. It may differ from one
474  * timestep to another if the test case allows more interactions than only
475  * elastic scatterings. The output block header is followed by Nparticles
476  * particle lines. In the Initial_Conditions output, Nparticles is always 0.
477  *
478  * **Particle line**
479  *
480  * The particle lines are formatted as follows:
481  * \code
482  * id pdg 0 px py pz p0 mass x y z t
483  * \endcode
484  *
485  * Apart from the order, the entries are identical to those of the OSCAR2013
486  * output.
487  *
488  * **Event end line**
489  *
490  * The end of an event is indicated by the following line:
491  * \code
492  * 0 0 event_number ensemble_number impact_parameter
493  * \endcode
494  *
495  * With
496  * \li \key event_number: Number of the event
497  * \li \key ensemble_number: Number of the ensemble
498  * \li \key impact_parameter: Impact parameter of the collisions. In case of
499  * a box or sphere setup, this value is 0.0
500  *
501  * \page doxypage_output_process_types
502  * The available process types are summarized in the following table.
503  *
504  * <table>
505  * <tr><th>Process number<th>Description
506  * \process_type{0} No previous process yet, particle was created at
507  * initialization
508  * \process_type{1} Elastic scattering
509  * \process_type{2} Resonance formation (2 &rarr; 1)
510  * \process_type{3} Inelastic binary scattering (2 &rarr; 2)
511  * \process_type{4} Inelastic multi-particle scattering (2 &rarr; 3)
512  * \process_type{5} Resonance decay
513  * \process_type{6} Box wall crossing (due to periodic boundary conditions)
514  * \process_type{7} Forced thermalization, many particles are replaced by a
515  * thermalized ensemble
516  * \process_type{8} Fluidization, particles that obey the fluidization
517  * condition given in the configuration file are removed
518  * from the evolution and printed to a separate output, to
519  * serve as initial conditions for hybrid models.
520  * \process_type{21} Fluidization as above, but particles are not removed from
521  * the evolution. They are instead tagged as core.
522  * \process_type{9} Bremsstrahlung process: a + b &rarr; a + b + photon
523  * \process_type{16} Bremsstrahlung process: a + b &rarr; a + b + dilepton
524  * \process_type{10} Inelastic multi-particle meson scattering (3 &rarr; 1)
525  * \process_type{11} Inelastic multi-particle scattering (3 &rarr; 2)
526  * \process_type{12} Inelastic multi-particle scattering (5 &rarr; 2)
527  * \process_type{13} Inelastic multi-particle scattering (2 &rarr; 5)
528  * \process_type{14} Inelastic multi-particle scattering (4 &rarr; 2)
529  * \process_type{15} Inelastic multi-particle scattering (2 &rarr; 4)
530  * \process_type{41} Soft string excitation, single diffractive AB &rarr; AX.
531  * Both quark and anti-/di-quark taken from B.
532  * \process_type{42} Soft string excitation, single diffractive AB &rarr; XB.
533  * Both quark and anti-/di-quark taken from A. It makes sense
534  * to distinguish it from AB &rarr; AX, because A and B can
535  * be particles of different types, for example, a pion and a
536  * proton. It matters then whether the pion or the proton
537  * creates the string.
538  * \process_type{43} Soft string excitation, double diffractive. Two strings are
539  * formed, one from A and one from B.
540  * \process_type{44} Soft string N-Nbar annihilation, a special case of
541  * baryon-antibaryon annihilation. One pair qqbar annihilates
542  * immediately and then two strings are formed.
543  * \process_type{45} Soft string excitation, non-diffractive. Two strings are
544  * formed, both have ends in A and B.
545  * \process_type{46} Hard string excitation, non-diffractive. A hard
546  * 2 &rarr; 2 QCD process is generated by PYTHIA. Here
547  * quarks or gluons scatter at parton level before the
548  * strings are formed.
549  * \process_type{47} Hard string excitation, single diffractive AB &rarr; AX.
550  * Generated by PYTHIA with a hard diffractive process.
551  * \process_type{48} Hard string excitation, single diffractive AB &rarr; XB.
552  * Generated by PYTHIA with a hard diffractive process.
553  * \process_type{49} Hard string excitation, double diffractive. Generated by
554  * PYTHIA with a hard diffractive process.
555  * \process_type{50} Failed string process. A string process can fail due to
556  * lack of energy. This tag is added to avoid mislabeling the
557  * event.
558  * \process_type{90} Add or remove particle(s) process, which ignores
559  * conservation laws. It can be thought of as a 0 &rarr; 1 or
560  * a 1 &rarr; 0 process.
561  * </table>
562  *
563  * \page doxypage_output_oscar_collisions
564  * The OSCAR particles format follows the general block structure of the
565  * \ref doxypage_output_oscar. We distinguish between two versions, OSCAR2013
566  * and OSCAR1999. Additional information about OSCAR standard can be found
567  * <a href="http://phy.duke.edu/~jeb65/oscar2013">here</a>. \n
568  * Enabling the OSCAR output for collisions in the config.yaml file
569  * (see \ref doxypage_input_conf_output), a so-called \c
570  * full_event_history.oscar file is produced when executing SMASH. It allows for
571  * a certain degree of flexibility, see \ref input_output_content_specific_
572  * "Content-specific output options" for further details. \n
573  * **Collision output always gives
574  * a list of collisions/decays/box wall crossings plus optionally
575  * initial and final configuration.**
576  *
577  * See also \ref doxypage_output_collisions_box_modus. \n
578  *
579  * \note The particle and event end lines for both OSCAR 2013 and 1999 formats
580  * are identical as in the \ref doxypage_output_oscar_particles.
581  *
582  * <h2> Oscar2013 </h2>
583  *
584  * Oscar2013 is an ASCII (text) human-readable output following the OSCAR 2013
585  * standard. The format specifics are the following:\n
586  * \n
587  * **File header**
588  * \code
589  * #!OSCAR2013 full_event_history t x y z mass p0 px py pz pdg ID charge
590  * # Units: fm fm fm fm GeV GeV GeV GeV GeV none none
591  * # SMASH_version
592  * \endcode
593  * The header consists of 3 lines starting with '#'. They contain the following
594  * information:
595  * -# Output version (OSCAR2013) and the type of output (particle_lists),
596  * followed by the substructure of the particle lines
597  * -# Units of the quantities in the particle lines
598  * -# SMASH version
599  *
600  * **File header for extended output** \n
601  * If desired, the OSCAR2013 output can be extended
602  * by additional particle properties. This requires enabling the extended
603  * output in the configuration file, see the \key Extended switch in
604  * \ref input_output_content_specific_ "content-specific output options" for
605  * further details. The header of the extended OSCAR output is structured
606  * identically to the non-extended version, but simply contains more columns
607  * because of the additional entries:
608  * <div class="fragment">
609  * <div class="line"><span class="preprocessor">#!OSCAR2013 particle_lists
610  * t x y z mass p0 px py pz pdg
611  * ID charge ncoll form_time xsecfac proc_id_origin proc_type_origin
612  * time_last_coll pdg_mother1 pdg_mother2 baryon_number strangeness</span>
613  * </div>
614  * <div class="line"><span class="preprocessor">\# Units: fm fm fm fm GeV GeV
615  * GeV GeV GeV none none e none fm none none none fm none none none
616  * none</span></div> <div class="line"><span class="preprocessor">\#
617  * SMASH_version</span></div>
618  * </div>
619  *
620  * **Event block header**\n
621  * The OSCAR2013 format is based on a block structure, where each block
622  * corresponds to one interaction. Each block starts with a line formatted
623  * as follows:
624  * <div class="fragment">
625  * <div class="line"> <span class="preprocessor">
626  * \# interaction in nin out nout rho density weight tot_weight partial
627  *part_weight type proc_type </span></div>
628  * </div>
629  * where
630  * \li \key nin: Number of ingoing particles (initial state particles)
631  * \li \key nout: Number of outgoing particles (final state particles)
632  * \li \key density: Density at the interaction point
633  * \li \key tot_weight: Total weight of the interaction. This is the total
634  * cross section in case of a scattering and the total decay width in case
635  * of a decay. If there is no weight for the specific process, e.g. a wall
636  * crossing, it's value is 0.0
637  * \li \key part_weight: The partial weight of the interaction. This is the
638  * specific weight for the chosen final state
639  * \li \key proc_type: The type of the underlying process. See \ref
640  * doxypage_output_process_types for possible types
641  *
642  * Note, that "interaction", "in", "out", "rho", "weight", "partial" and "type"
643  * are no variables, but words that are printed.
644  *
645  * <h2> Oscar1999 </h2>
646  *
647  * Oscar1999 is an ASCII (text) human-readable output following the OSCAR 1999
648  * standard. The format specifics are the following:
649  *
650  * **File header**
651  * \code
652  * # OSC1999A
653  * # full_event_history
654  * # smash <version>
655  * # Block format:
656  * # nin nout density tot_weight part_weight proc_type
657  * # id pdg 0 px py pz p0 mass x y z t
658  * # End of event: 0 0 event_number
659  * #
660  * \endcode
661  * The header consists of 8 lines starting with '#', of which the last one
662  * is basically empty.
663  * They contain the following information:
664  * -# The specific OSCAR1999 version the formatting follows - OSC1999A
665  * -# The filename
666  * -# The SMASH version with which the oputput was generated
667  * -# - 7. Info on the block structure
668  *
669  * **Block header**\n
670  * Each output block starts with a line of the following format:
671  * \code
672  * nin nout density tot_weight part_weight proc_type
673  * \endcode
674  * With
675  * \li \key nin: Number of ingoing particles (initial state particles)
676  * \li \key nout: Number of outgoing particles (final state particles)
677  * \li \key density: Density at the interaction point
678  * \li \key tot_weight: Total weight of the interaction. This is the total cross
679  * section in case of a scattering and the total decay width in case of a decay.
680  * If there is no weight for the specific process, e.g. a wall crossing, it's
681  * value is 0.0
682  * \li \key part_weight: The partial weight of the interaction. This is the
683  * specific weight for the chosen final state
684  * \li \key proc_type: The type of the underlying process. See
685  * \ref doxypage_output_process_types for possible types
686  *
687  * If the \key Print_Start_End option is set (see \ref
688  * input_output_content_specific_ "content-specific output options" for
689  * details), (nin, nout) = (0, Nparticles) in the
690  * initial timestep and (nin, nout) = (Nparticles, 0) in the final timestep.
691  */
692 
693 /*!\Userguide
694  * \page doxypage_output_ascii
695  * The \c ASCII format follows the general block structure of the \ref
696  * doxypage_output_oscar, but offers more flexibility with the particle line
697  * quantities written in the file. It is available for the \c %Particles,
698  * \c Collisions, \c Dileptons, and \c Photons output contents (see \ref
699  * doxypage_output), creating files with the extension <em>.dat</em>.
700  * This format is useful to decrease storage usage.
701  * \n
702  *
703  * <table>
704  * <tr><th>Key(s)<th>C++ type <th> Description<th></tr>
705  * <tr>
706  * <td>\key t, \key x, \key y, \key z
707  * <td> \c double <td>Space-time coordinates
708  * </tr>
709  * <tr>
710  * <td>\key mass
711  * <td>\c double
712  * <td>Particle's rest-mass
713  * </tr>
714  * <tr>
715  * <td>\key p0, \key px, \key py, \key pz
716  * <td> \c double <td>Energy and 3-momentum
717  * </tr>
718  * <tr>
719  * <td>\key pdg
720  * <td>\c int32_t
721  * <td>PDG code of the particle (see http://pdg.lbl.gov/). It contains all
722  * quantum numbers and uniquely identifies its type
723  * </tr>
724  * <tr>
725  * <td>\key ID, \key id
726  * <td> \c int32_t
727  * <td>Particle identifier in terms of an integer. It is unique for every
728  * particle in the event. \key ID is used in the OSCAR 2013 standard, while
729  * \key id is used in OSCAR 1999
730  * </tr>
731  * <tr>
732  * <td>\key charge
733  * <td>\c int32_t
734  * <td>Electric charge of the particle in units of the elementary charge \f$e\f$
735  * </tr>
736  * <tr>
737  * <td>\key ncoll
738  * <td>\c int32_t
739  * <td>Number of collisions the particle has undergone
740  * </tr>
741  * <tr>
742  * <td>\key form_time
743  * <td>\c double
744  * <td>Formation time of the particle
745  * </tr>
746  * <tr>
747  * <td>\key xsecfac
748  * <td>\c double
749  * <td>Cross section scaling factor (if the particles are not yet fully formed
750  * at the time of interaction, the cross section for the underlying process
751  * is scaled down by the cross section scaling factor)
752  * </tr>
753  * <tr>
754  * <td>\key proc_id_origin
755  * <td>\c int32_t
756  * <td>ID of the process of the particle's last interaction
757  * </tr>
758  * <tr>
759  * <td>\key proc_type_origin
760  * <td>\c int32_t
761  * <td>Type of the last process the particle has undergone. The possible process
762  * types are listed in \ref doxypage_output_process_types
763  * </tr>
764  * <tr>
765  * <td>
766  * \key time_last_coll
767  * <td>\c double
768  * <td>Time of the particle's last interaction (except wall crossings)
769  * </tr>
770  * <tr>
771  * <td>\key pdg_mother1
772  * <td>\c int32_t
773  * <td>PDG code of the 1st mother particle (0 in case the particle is sampled in
774  * a thermal bubble. It is not updated by elastic scatterings)
775  * </tr>
776  * <tr>
777  * <td>\key pdg_mother2
778  * <td>\c int32_t
779  * <td>PDG code of the 2nd mother particle (0 in case the particle results from
780  * the decay of a resonance or the appearance of a thermal bubble. In the
781  * former case, \key pdg_mother1 is the PDG code of this resonance. It is
782  * not updated by elastic scatterings)
783  * </tr>
784  * <tr>
785  * <td>\key baryon_number
786  * <td>\c int32_t
787  * <td>Baryon number of the particle: 1 for baryons, -1 for anti-baryons and 0
788  * for mesons
789  * </tr>
790  * <tr>
791  * <td>\key strangeness
792  * <td>\c int32_t
793  * <td>Net-strangeness of the particles
794  * </tr>
795  * <tr>
796  * <td>\key 0
797  * <td>\c int32_t
798  * <td>Prints a column of 0 (for compatibility with OSCAR 1999)
799  * </tr>
800  * <tr>
801  * <td>\key tau
802  * <td>\c double
803  * <td>Hyperbolic time \f$\tau=\sqrt{t^2-z^2}\f$
804  * </tr>
805  * <tr>
806  * <td>\key eta, \key eta_s
807  * <td>\c double
808  * <td>Spacetime rapidity \f$\eta_s=\frac{1}{2}\log\frac{t+z}{t-z}\f$
809  * </tr>
810  * <tr>
811  * <td>\key mt
812  * <td>\c double
813  * <td>Transverse mass \f$m_\perp=\sqrt{p_0^2-p_z^2}=\sqrt{m^2+p_x^2+p_y^2}\f$
814  * </tr>
815  * <tr>
816  * <td>\key Rap, \key y_rap
817  * <td>\c double
818  * <td>Momentum rapidity
819  * \f$y_\mathrm{rap}=\frac{1}{2}\log\frac{p_0+p_z}{p_0-p_z}\f$
820  * </tr>
821  * <tr>
822  * <td>\key spin0, \key spinx, \key spiny, \key spinz
823  * <td> \c double
824  * <td>Components of the Pauli-Lubanski vector
825  * </tr>
826  * <tr>
827  * <td>\key perturbative_weight
828  * <td> \c double
829  * <td>Weight for treating particles perturbatively
830  * </tr>
831  * </table>
832  *
833  * \attention Not all combinations of quantities are allowed and, in particular:
834  * - synonym quantities cannot be given together;
835  * - the same quantity cannot be repeated.
836  *
837  * **Example**
838  *
839  * If one is interested, for example, in the rate of production/annihilation of
840  * resonances, for events divided into centrality classes based on the charged
841  * particle yield at midrapidity, the config file would contain the following:
842  *\verbatim
843  Output:
844  Particles:
845  Format: ["ASCII"]
846  Quantities: ["p0","pz","pdg","charge"]
847  Only_Final: IfNotEmpty
848  Collisions:
849  Format: ["ASCII"]
850  Quantities: ["t","pdg","ID","pdg_mother1","pdg_mother2"]
851  \endverbatim
852  *
853  * Then, the output files would have the following headers:
854  *
855  * *particle_lists.dat*
856  * \code
857  * #!ASCII particle_lists p0 pz pdg charge
858  * # Units: GeV GeV none e
859  * # SMASH_version
860  * \endcode
861  *
862  * *full_event_history.dat*
863  * \code
864  * #!ASCII full_event_history t pdg ID pdg_mother1 pdg_mother2
865  * # Units: fm none none none none
866  * # SMASH_version
867  * \endcode
868  */
869 
870 template <OscarOutputFormat Format, int Contents>
872  const ParticleData &data) {
873  std::fprintf(file_.get(), "%s",
874  formatter_.single_particle_data(data).c_str());
875 }
876 
877 template <OscarOutputFormat Format, int Contents>
879  std::fprintf(file_.get(), "%s", buffer.c_str());
880 }
881 
882 namespace {
883 /**
884  * Helper function that creates the oscar output with the format selected by
885  * create_oscar_output.
886  *
887  * \tparam Contents Determines what information will be written to the output
888  * \param[in] path Path of output
889  * \param[in] name (File)name of ouput
890  * \param[in] modern_format Use the 1999 or 2013 format
891  * \param[in] extended_format Whether the format is extended
892  * \param[in] custom_format Whether the output has user-defined quantities
893  * \param[in] quantities The user-defined quantities
894  *
895  * \return Unique pointer to oscar output
896  */
897 template <int Contents>
898 std::unique_ptr<OutputInterface> create_selected_format(
899  const std::filesystem::path &path, const std::string &name,
900  bool modern_format, bool extended_format, bool custom_format,
901  const std::vector<std::string> &quantities) {
902  if (custom_format) {
903  return std::make_unique<OscarOutput<ASCII, Contents>>(path, name,
904  quantities);
905  } else {
906  if (modern_format && extended_format) {
907  return std::make_unique<OscarOutput<OscarFormat2013Extended, Contents>>(
908  path, name);
909  } else if (modern_format && !extended_format) {
910  return std::make_unique<OscarOutput<OscarFormat2013, Contents>>(path,
911  name);
912  } else if (!modern_format && !extended_format) {
913  return std::make_unique<OscarOutput<OscarFormat1999, Contents>>(path,
914  name);
915  } else {
916  // Only remaining possibility: (!modern_format && extended_format)
917  logg[LOutput].warn() << "There is no extended Oscar1999 format, creating "
918  "a regular Oscar1999 output instead.";
919  return std::make_unique<OscarOutput<OscarFormat1999, Contents>>(path,
920  name);
921  }
922  }
923 }
924 } // unnamed namespace
925 
926 std::unique_ptr<OutputInterface> create_oscar_output(
927  const std::string &format, const std::string &content,
928  const std::filesystem::path &path, const OutputParameters &out_par) {
929  if (format != "Oscar2013" && format != "Oscar1999" && format != "ASCII") {
930  throw std::invalid_argument("Creating Oscar output: unknown format");
931  }
932  const bool modern_format = (format == "Oscar2013");
933  const bool custom_format = (format == "ASCII");
934  const auto &quantities = custom_format ? out_par.quantities.at(content)
935  : std::vector<std::string>{};
936 
937  if (content == "Particles") {
938  if (out_par.part_only_final == OutputOnlyFinal::Yes) {
939  return create_selected_format<OscarParticlesAtEventend>(
940  path, "particle_lists", modern_format, out_par.part_extended,
941  custom_format, quantities);
942  } else if (out_par.part_only_final == OutputOnlyFinal::IfNotEmpty) {
943  return create_selected_format<OscarParticlesAtEventendIfNotEmpty>(
944  path, "particle_lists", modern_format, out_par.part_extended,
945  custom_format, quantities);
946  } else { // out_par.part_only_final == OutputOnlyFinal::No
949  path, "particle_lists", modern_format, out_par.part_extended,
950  custom_format, quantities);
951  }
952  } else if (content == "Collisions") {
953  if (out_par.coll_printstartend) {
956  path, "full_event_history", modern_format, out_par.coll_extended,
957  custom_format, quantities);
958  } else {
959  return create_selected_format<OscarInteractions>(
960  path, "full_event_history", modern_format, out_par.coll_extended,
961  custom_format, quantities);
962  }
963  } else if (content == "Dileptons") {
964  return create_selected_format<OscarInteractions>(
965  path, "Dileptons", modern_format, out_par.dil_extended, custom_format,
966  quantities);
967  } else if (content == "Photons") {
968  return create_selected_format<OscarInteractions>(
969  path, "Photons", modern_format, out_par.photons_extended, custom_format,
970  quantities);
971  } else if (content == "Initial_Conditions") {
972  return create_selected_format<OscarParticlesIC | OscarAtEventstart>(
973  path, "SMASH_IC", modern_format, out_par.ic_extended, custom_format,
974  quantities);
975  }
976 
977  throw std::invalid_argument("Create_oscar_output got unknown content.");
978 }
979 
980 } // namespace smash
Action is the base class for a generic process that takes a number of incoming particles and transfor...
Definition: action.h:35
virtual ProcessType get_type() const
Get the process type.
Definition: action.h:131
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.
Definition: action.cc:61
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.
Definition: action.h:247
A class to pre-calculate and store parameters relevant for density calculation.
Definition: density.h:92
ParticleData contains the dynamic information of a certain particle.
Definition: particledata.h:59
The Particles class abstracts the storage and manipulation of particles.
Definition: particles.h:33
size_t size() const
Definition: particles.h:87
@ 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.
Definition: logging.h:245
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:217
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)
Definition: oscaroutput.cc:926
@ OscarParticlesAtEventend
store the state at the end of each event (at_eventend)
Definition: oscaroutput.h:53
@ OscarParticlesAtEventendIfNotEmpty
store the state at the end of each event if it is not empty (at_eventend)
Definition: oscaroutput.h:55
@ OscarAtEventstart
store the state at the start of each event (at_eventstart)
Definition: oscaroutput.h:51
@ OscarInteractions
store interaction information (write_interaction)
Definition: oscaroutput.h:47
@ OscarParticlesIC
store the particles that are removed on the hypersurface
Definition: oscaroutput.h:57
@ OscarTimesteps
store the state after N timesteps (after_Nth_timestep)
Definition: oscaroutput.h:49
@ OscarFormat1999
Definition: oscaroutput.h:34
@ OscarFormat2013Extended
Definition: oscaroutput.h:33
@ ASCII
Definition: oscaroutput.h:35
@ OscarFormat2013
Definition: oscaroutput.h:32
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.
Definition: oscaroutput.cc:898
constexpr int p
Proton.
Definition: action.h:24
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.