Version: SMASH-3.4
listmodus.cc
Go to the documentation of this file.
1 /*
2  *
3  * Copyright (c) 2015-2026
4  * SMASH Team
5  *
6  * GNU General Public License (GPLv3 or later)
7  *
8  */
9 
10 #include "smash/listmodus.h"
11 
12 #include <array>
13 #include <cmath>
14 #include <cstdio>
15 #include <cstdlib>
16 #include <filesystem>
17 #include <fstream>
18 #include <list>
19 #include <map>
20 #include <sstream>
21 #include <utility>
22 #include <vector>
23 
24 #include "smash/algorithms.h"
25 #include "smash/boxmodus.h"
26 #include "smash/configuration.h"
27 #include "smash/constants.h"
29 #include "smash/fourvector.h"
30 #include "smash/inputfunctions.h"
31 #include "smash/logging.h"
32 #include "smash/particledata.h"
33 #include "smash/propagation.h"
34 #include "smash/threevector.h"
36 
37 namespace smash {
38 static constexpr int LList = LogArea::List::id;
39 
40 static bool is_list_of_particles_invalid(const Particles &, int);
41 
43  const ExperimentParameters &param)
44  : file_id_{std::nullopt}, event_id_{0} {
45  /*
46  * Make some logic on config to understand whether to extract parent or
47  * children keys. These have all the same keys but have a different section
48  * name (like for instance 'ListBox' instead of 'List'). At the moment there
49  * is only one child and this approach is fine enough, although ugly.
50  */
51  const bool is_list =
53  const bool is_list_box =
55  if (is_list == is_list_box) {
56  throw std::logic_error(
57  "Unexpected error in ListModus constructor. Either List or ListBox "
58  "sections must be present in configuration.");
59  }
61  file_directory_key = InputKeys::modi_list_fileDirectory,
62  filename_key = InputKeys::modi_list_filename;
64  Key<std::vector<std::string>> optional_quantities_key =
66  if (is_list_box) {
67  file_prefix_key = InputKeys::modi_listBox_filePrefix;
68  file_directory_key = InputKeys::modi_listBox_fileDirectory;
69  filename_key = InputKeys::modi_listBox_filename;
70  shift_id_key = InputKeys::modi_listBox_shiftId;
71  optional_quantities_key = InputKeys::modi_listBox_optionalQuantities;
72  }
73 
74  // Set the default values for the spin interaction type
76 
77  // Impose strict requirement on possible keys present in configuration file
78  const bool file_prefix_used = modus_config.has_value(file_prefix_key);
79  const bool filename_used = modus_config.has_value(filename_key);
80  if (file_prefix_used == filename_used) {
81  throw std::invalid_argument(
82  "Either 'Filename' or 'File_Prefix' key must be used in 'Modi' section "
83  "in configuration file. Please, adjust your configuration file.");
84  }
85  if (file_prefix_used) {
86  particle_list_filename_or_prefix_ = modus_config.take(file_prefix_key);
87  file_id_ = modus_config.take(shift_id_key);
88  } else {
89  particle_list_filename_or_prefix_ = modus_config.take(filename_key);
90  }
91  particle_list_file_directory_ = modus_config.take(file_directory_key);
92  if (param.n_ensembles > 1) {
93  throw std::runtime_error("ListModus only makes sense with one ensemble");
94  }
95  optional_fields_ = modus_config.take(optional_quantities_key);
98 }
99 
100 /* console output on startup of List specific parameters */
101 std::ostream &operator<<(std::ostream &out, const ListModus &m) {
102  out << "-- List Modus\nInput directory for external particle lists:\n"
103  << m.particle_list_file_directory_ << "\n";
104  return out;
105 }
106 
108  /* (1) If particles are already at the same time - don't touch them
109  AND start at the start_time_ from the config. */
110  double earliest_formation_time = DBL_MAX;
111  double formation_time_difference = 0.0;
112  double reference_formation_time = 0.0; // avoid compiler warning
113  bool first_particle = true;
114  for (const auto &particle : particles) {
115  const double t = particle.position().x0();
116  if (t < earliest_formation_time) {
117  earliest_formation_time = t;
118  }
119  if (first_particle) {
120  reference_formation_time = t;
121  first_particle = false;
122  } else {
123  formation_time_difference += std::abs(t - reference_formation_time);
124  }
125  }
126  /* (2) If particles are NOT at the same time -> anti-stream them to
127  the earliest time (Note: not to the start_time_ set by config) */
128  bool anti_streaming_needed = (formation_time_difference > really_small);
129  start_time_ = earliest_formation_time;
130  if (anti_streaming_needed) {
132  }
133 }
134 
136  Particles &particles, PdgCode pdgcode, double t, double x, double y,
137  double z, double mass, double E, double px, double py, double pz,
138  const std::vector<std::string> &optional_quantities) {
139  try {
140  ParticleData new_particle =
142  pdgcode, mass, {t, x, y, z}, {E, px, py, pz}, LList,
144  insert_optional_quantities_to_(new_particle, optional_quantities);
145  particles.insert(new_particle);
147  logg[LList].warn() << "SMASH does not recognize pdg code " << pdgcode
148  << " loaded from file. This particle will be ignored.\n";
149  }
150 }
151 
153  ParticleData &p,
154  const std::vector<std::string> &optional_quantities) const {
155  if (optional_quantities.empty()) {
156  return;
157  } else if (optional_quantities.size() != optional_fields_.size()) {
158  using namespace std::string_literals; // NOLINT(build/namespaces)
159  throw std::out_of_range("Unexpected size mismatch in "s + __func__ +
160  " between the list of optional quantities values "
161  "passed in and the class member optional_fields_");
162  }
163  HistoryData hist = p.get_history();
164  std::ostringstream error_message{"", std::ios_base::ate};
165 
166  for (size_t i = 0; i < optional_fields_.size(); ++i) {
167  size_t len{};
168  auto field = optional_fields_[i];
169  auto quantity = optional_quantities[i];
170  if (field == "ID") {
171  // ID information is not relevant
172  continue;
173  } else if (field == "charge") {
174  const PdgCode pdgcode = p.pdgcode();
175  const int charge = std::stoi(optional_quantities[i], &len);
176  // Charge consistency check
177  if (pdgcode.charge() != charge) {
178  error_message << "Charge of pdg = " << pdgcode << " != " << charge
179  << ".\n";
180  throw std::invalid_argument("Inconsistent input (charge).");
181  }
182  } else if (field == "ncoll") {
183  const int ncoll = std::stoi(optional_quantities[i], &len);
184  if (ncoll < 0) {
185  error_message << "ncoll < 0.\n";
186  }
187  hist.collisions_per_particle = ncoll;
188  } else if (field == "form_time") {
189  p.set_formation_time(std::stod(quantity, &len));
190  } else if (field == "xsecfac") {
191  const double xsecfac = std::stod(quantity, &len);
192  if (xsecfac < 0 || xsecfac > 1) {
193  error_message << "xsecfac < 0 or xsecfac > 1.\n";
194  }
195  p.set_cross_section_scaling_factor(xsecfac);
196  } else if (field == "proc_type") {
197  const int proc_type = std::stoi(quantity, &len);
198  if (!is_valid_process_type(proc_type)) {
199  error_message << "Invalid proc_type.\n";
200  }
201  hist.process_type = static_cast<ProcessType>(proc_type);
202  } else if (field == "time_last_coll") {
203  const double t_last_coll = std::stod(quantity, &len);
204  if (t_last_coll > p.position().x0()) {
205  error_message << "time_last_coll > particle time.\n";
206  }
207  hist.time_last_collision = t_last_coll;
208  } else if (field == "pdg_mother1") {
209  if (quantity != "0") {
210  if (!ParticleType::exists(PdgCode(quantity))) {
211  error_message << "pdg_mother1 cannot be " << quantity << ".\n";
212  }
213  hist.p1 = PdgCode(quantity);
214  len = quantity.size();
215  }
216  } else if (field == "pdg_mother2") {
217  if (quantity != "0") {
218  if (!ParticleType::exists(PdgCode(quantity))) {
219  error_message << "pdg_mother2 cannot be " << quantity << ".\n";
220  }
221  hist.p2 = PdgCode(quantity);
222  len = quantity.size();
223  }
224  } else if (field == "spin0") {
225  const double s0 = std::stod(quantity, &len);
226  p.set_spin_vector_component(0, s0);
227  } else if (field == "spinx") {
228  const double s1 = std::stod(quantity, &len);
229  p.set_spin_vector_component(1, s1);
230  } else if (field == "spiny") {
231  const double s2 = std::stod(quantity, &len);
232  p.set_spin_vector_component(2, s2);
233  } else if (field == "spinz") {
234  const double s3 = std::stod(quantity, &len);
235  p.set_spin_vector_component(3, s3);
236  } else if (field == "perturbative_weight") {
237  const double weight = std::stod(quantity, &len);
238  if (0 > weight || weight > 1) {
239  error_message << "Perturbative weight must be between 0 and 1.\n";
240  }
241  p.set_perturbative_weight(weight);
242  } else {
243  /* Keep this else branch even if the list of optional fields is validated
244  * at take time from the configuration, because it might help the
245  * developer if they forget to add a new branch here above to handle the
246  * new quantity. */
247  error_message << " Unknown quantities given in the configuration.\n";
248  }
249  /* This is to assist the user, in case of a mistype in the inputfile.
250  * We do not throw here because it may be intentional. */
251  if (len != quantity.size()) {
252  logg[LList].warn()
253  << field << "=" << quantity
254  << " not read exactly as written in the input particle list.\n";
255  }
256  }
257 
258  if (error_message.str().size() > 0) {
259  logg[LList].error()
260  << "The reading-in of optional quantities had the following problems:\n"
261  << error_message.str();
262  throw std::invalid_argument(
263  "Please fix the list of input particles and/or configuration.");
264  }
265  p.set_history(std::move(hist));
266 }
267 
268 /* initial_conditions - sets particle data for @particles */
270  const ExperimentParameters &) {
272  if (particles->size() > 0) {
274  } else {
275  start_time_ = 0.0;
276  }
277  event_id_++;
278 
279  return start_time_;
280 }
281 
283  std::string particle_list = next_event_();
284  const std::vector<Line> event_content = line_parser(particle_list);
285  if (event_content.empty()) {
286  if (verbose_) {
287  logg[LList].warn(
288  "Encountered empty event while reading input particle lists data, "
289  "which will result in empty events in the output file!");
290  }
291  return;
292  }
293  for (const Line &line : event_content) {
294  std::istringstream lineinput(line.text);
295  double t, x, y, z, mass, E, px, py, pz;
296  std::string pdg_string;
297  lineinput >> t >> x >> y >> z >> mass >> E >> px >> py >> pz >> pdg_string;
298  std::vector<std::string> optional_quantities(optional_fields_.size());
299  for (size_t i = 0; i < optional_fields_.size(); ++i) {
300  std::string opt{};
301  lineinput >> opt;
302  optional_quantities[i] = std::move(opt);
303  }
304  if (lineinput.fail()) {
305  throw LoadFailure(
306  build_error_string("While loading external particle lists data:\n"
307  "Failed to convert the input string to the "
308  "expected data types.",
309  line));
310  }
311  PdgCode pdgcode(pdg_string);
312  logg[LList].debug("Particle ", pdgcode, " (x,y,z)= (", x, ", ", y, ", ", z,
313  ")");
314 
315  try_create_particle(particles, pdgcode, t, x, y, z, mass, E, px, py, pz,
316  optional_quantities);
317  }
318 }
319 
320 std::filesystem::path ListModus::file_path_(std::optional<int> file_id) {
321  std::string fname = particle_list_filename_or_prefix_ +
322  ((file_id) ? std::to_string(*file_id) : "");
323 
324  const std::filesystem::path default_path =
325  std::filesystem::absolute(particle_list_file_directory_);
326 
327  const std::filesystem::path fpath = default_path / fname;
328 
329  logg[LList].debug() << "File: " << std::filesystem::absolute(fpath) << '\n';
330 
331  if (!std::filesystem::exists(fpath)) {
332  if (verbose_) {
333  logg[LList].fatal()
334  << fpath.filename().native() << " does not exist! \n\n"
335  << "Usage of smash with external particle lists:\n"
336  << " 1. Put the external particle lists in one or more files\n"
337  << " according to the user guide instructions.\n"
338  << " 2. Particles info: t x y z mass p0 px py pz pdg ID charge\n"
339  << " in units of: fm fm fm fm GeV GeV GeV GeV GeV none none e\n";
340  }
341  throw std::runtime_error("External particle list does not exist!");
342  }
343 
344  return fpath;
345 }
346 
347 std::string ListModus::next_event_() {
348  const std::filesystem::path fpath = file_path_(file_id_);
349  std::ifstream ifs{fpath};
350  ifs.seekg(last_read_position_);
351 
352  if (!file_has_events_(fpath, last_read_position_)) {
353  if (file_id_) {
354  // Get next file and call this function recursively
355  (*file_id_)++;
357  ifs.close();
358  return next_event_();
359  } else {
360  throw std::runtime_error(
361  "Attempt to read in next event in ListModus object but no further "
362  "data found in single provided file. Please, check your setup.");
363  }
364  }
365 
366  // read one event. events marked by line # event end i in case of Oscar
367  // output. Assume one event per file for all other output formats
368  std::string event_string{};
369  const std::string needle = " end ";
370  std::string line{};
371  while (getline(ifs, line)) {
372  if (line.find(needle) == std::string::npos) {
373  event_string += line + "\n";
374  } else {
375  break;
376  }
377  }
378 
379  if (!ifs.eof() && (ifs.fail() || ifs.bad())) {
380  if (verbose_) {
381  logg[LList].fatal() << "Error while reading "
382  << fpath.filename().native();
383  }
384  throw std::runtime_error("Error while reading external particle list");
385  }
386  // save position for next event read
387  last_read_position_ = ifs.tellg();
388  ifs.close();
389 
390  return event_string;
391 }
392 
393 bool ListModus::file_has_events_(std::filesystem::path filepath,
394  std::streampos last_position) {
395  std::ifstream ifs{filepath};
396  std::string line;
397 
398  // last event read read at end of file. we know this because errors are
399  // handled in next_event
400  if (last_position == -1) {
401  return false;
402  }
403  ifs.seekg(last_position);
404  // skip over comment lines, assume that a max. of four consecutive comment
405  // lines can occur
406  int skipped_lines = 0;
407  const int max_comment_lines = 4;
408  while (std::getline(ifs, line) && line[0] != '#' &&
409  skipped_lines++ < max_comment_lines) {
410  }
411 
412  if (ifs.eof()) {
413  return false;
414  }
415 
416  if (!ifs.good()) {
417  if (verbose_) {
418  logg[LList].fatal() << "Error while reading "
419  << filepath.filename().native();
420  }
421  throw std::runtime_error("Error while reading external particle list");
422  }
423 
424  ifs.close();
425  return true;
426 }
427 
428 /* In this method, which is called from the constructor only, we "abuse" of the
429  * class functionality to read in all events and validate them. In order not to
430  * modify the original object we work on an utility copy. Note that the copy
431  * constructor provided by the compiler is enough as the class has only STL or
432  * builtin members.
433  */
435  ListModus utility_copy{*this};
436  utility_copy.verbose_ = false;
437  utility_copy.warn_about_mass_discrepancy_ = false;
438  utility_copy.warn_about_off_shell_particles_ = false;
439  bool are_there_faulty_events = false;
440  while (true) {
441  try {
442  Particles particles{};
443  utility_copy.read_particles_from_next_event_(particles);
444  if (is_list_of_particles_invalid(particles, utility_copy.event_id_)) {
445  are_there_faulty_events = true;
446  }
447  utility_copy.event_id_++;
448  } catch (const std::exception &) {
449  break;
450  }
451  }
452  if (are_there_faulty_events) {
453  throw InvalidEvents(
454  "More than 2 particles with the same 4-position have been found in the "
455  "same event.\nPlease, check your particles list file.");
456  }
457 }
458 
460  // If spin interactions are enabled, require all four spin components.
462  static constexpr std::array<std::string_view, 4> required_fields{
463  "spin0", "spinx", "spiny", "spinz"};
464 
465  const bool all_present = std::all_of(
466  required_fields.begin(), required_fields.end(), [this](auto field) {
467  return std::find(optional_fields_.begin(), optional_fields_.end(),
468  field) != optional_fields_.end();
469  });
470 
471  if (!all_present) {
472  throw std::invalid_argument(
473  "When spin interactions are enabled, all four spin components "
474  "(spin0, spinx, spiny, spinz) must be provided in the config "
475  "file.");
476  }
477  }
478 }
479 
481  const ExperimentParameters &param)
482  : ListModus(), length_(modus_config.take(InputKeys::modi_listBox_length)) {
483  /*
484  * ATTENTION: In a child class initialization list nothing can be done before
485  * calling the base constructor. However, here we cannot hand over the
486  * configuration to the base class as there are child-specific keys to be
487  * taken before. This cannot be done after having moved the configuration and
488  * changing the constructor signature would be a big change as all modus
489  * classes should have the same constructor signature to allow Experiment to
490  * template on it. Therefore, we abuse C++ here by default-initializing the
491  * parent class, then taking the child-specific key(s) and then assigning a
492  * parent instance to the child using the parent assignment operator. In
493  * general this would be risky as it would open up the possibility to leave
494  * part of the children uninitialized, but here we should have under control
495  * what exactly happens at initialization time.
496  */
497  this->ListModus::operator=(ListModus(std::move(modus_config), param));
498 }
499 
501  const OutputsList &output_list) {
502  int wraps = 0;
503  for (ParticleData &data : *particles) {
504  FourVector position = data.position();
505  bool wall_hit = enforce_periodic_boundaries(position.begin() + 1,
506  position.end(), length_);
507  if (wall_hit) {
508  const ParticleData incoming_particle(data);
509  data.set_4position(position);
510  ++wraps;
511  ActionPtr action =
512  std::make_unique<WallcrossingAction>(incoming_particle, data);
513  for (const auto &output : output_list) {
514  if (!output->is_dilepton_output() && !output->is_photon_output()) {
515  output->at_interaction(*action, 0.);
516  }
517  }
518  }
519  }
520 
521  logg[LList].debug("Moved ", wraps, " particles back into the box.");
522  return wraps;
523 }
524 
525 /* This function is meant to throw if there are more than two particles at the
526  * same position. To be more user-friendly we first check all particles and then
527  * report about all faulty groups of particles with their position. Only
528  * afterwards the simulation is aborted. */
529 static bool is_list_of_particles_invalid(const Particles &particles,
530  int event) {
531  /* In order to make the desired check, particles are classified in an std::map
532  * using their position as a key. However, to do so, the operator< of the
533  * FourVector class is not suitable since in a std::map, by default, two keys
534  * a and b are considered equivalent if !(a<b) && !(b<a). Therefore we convert
535  * the 4-postion to a string and use this as key. Note that this should also
536  * work in the case in which the file contains apparently different positions,
537  * i.e. with differences in the decimals beyond double precision. At this
538  * point the file has been already read and the 4-positions are stored in
539  * double position. */
540  auto to_string = [](const FourVector &v) {
541  return "(" + std::to_string(v[0]) + ", " + std::to_string(v[1]) + ", " +
542  std::to_string(v[2]) + ", " + std::to_string(v[3]) + ")";
543  };
544  std::map<std::string, int> checker{};
545  for (const auto &p : particles) {
546  checker[to_string(p.position())]++;
547  }
548  bool error_found = false;
549  for (const auto &[key, value] : checker) {
550  if (value > 2) {
551  logg[LList].error() << "Event " << event << ": Found " << value
552  << " particles at same position " << key;
553  error_found = true;
554  }
555  }
556  return error_found;
557 }
558 } // namespace smash
Generic algorithms on containers and ranges.
Interface to the SMASH configuration files.
bool has_value(const Key< T > &key) const
Return whether there is a non-empty value behind the requested key (which is supposed not to refer to...
T take(const Key< T > &key)
The default interface for SMASH to read configuration values.
The FourVector class holds relevant values in Minkowski spacetime with (+, −, −, −) metric signature.
Definition: fourvector.h:33
iterator end()
Definition: fourvector.h:294
iterator begin()
Definition: fourvector.h:291
const double length_
Length of the cube's edge in fm.
Definition: listmodus.h:374
int impose_boundary_conditions(Particles *particles, const OutputsList &output_list={})
Enforces that all particles are inside the box at the beginning of an event.
Definition: listmodus.cc:500
ListBoxModus(Configuration modus_config, const ExperimentParameters &parameters)
Constructor (This is the same as for the ListModus)
Definition: listmodus.cc:480
ListModus: Provides a modus for running SMASH on an external particle list, for example as an afterbu...
Definition: listmodus.h:57
bool file_has_events_(std::filesystem::path filepath, std::streampos last_position)
Check if the given file has events left after the given position.
Definition: listmodus.cc:393
std::optional< int > file_id_
The id of the current file.
Definition: listmodus.h:259
bool is_list() const
Definition: listmodus.h:148
std::string particle_list_filename_or_prefix_
Prefix of the file(s) containing the particle list.
Definition: listmodus.h:256
void backpropagate_to_same_time_if_needed_(Particles &particles)
Judge whether times are the same for all the particles; don't do anti-freestreaming if all particles ...
Definition: listmodus.cc:107
void validate_optional_fields_() const
Validate the optional fields.
Definition: listmodus.cc:459
std::filesystem::path file_path_(std::optional< int > file_id)
Return the absolute path of the data file.
Definition: listmodus.cc:320
SpinInteractionType spin_interaction_type_
Auxiliary flag to indicate the type of spin interaction used.
Definition: listmodus.h:275
std::string particle_list_file_directory_
File directory of the particle list.
Definition: listmodus.h:250
void validate_list_of_particles_of_all_events_() const
Read and validate all events particles.
Definition: listmodus.cc:434
void read_particles_from_next_event_(Particles &particles)
Read the next event from file.
Definition: listmodus.cc:282
double start_time_
Starting time for the List; changed to the earliest formation time.
Definition: listmodus.h:152
ListModus()=default
Construct an empty list.
bool verbose_
Flag to suppress some error messages.
Definition: listmodus.h:283
void try_create_particle(Particles &particles, PdgCode pdgcode, double t, double x, double y, double z, double mass, double E, double px, double py, double pz, const std::vector< std::string > &optional_quantities={})
Tries to add a new particle to particles and performs consistency checks: (i) The PDG code is legal a...
Definition: listmodus.cc:135
std::streampos last_read_position_
Last read position in current file.
Definition: listmodus.h:267
bool warn_about_mass_discrepancy_
Auxiliary flag to warn about mass-discrepancies only once per instance.
Definition: listmodus.h:270
bool warn_about_off_shell_particles_
Auxiliary flag to warn about off-shell particles only once per instance.
Definition: listmodus.h:272
std::string next_event_()
Read the next event.
Definition: listmodus.cc:347
std::vector< std::string > optional_fields_
Fields with optional quantities to be read.
Definition: listmodus.h:262
void insert_optional_quantities_to_(ParticleData &p, const std::vector< std::string > &optional_quantities) const
Sets the optional fields given in the input list into a particle.
Definition: listmodus.cc:152
double initial_conditions(Particles *particles, const ExperimentParameters &parameters)
Generates initial state of the particles in the system according to a list.
Definition: listmodus.cc:269
int event_id_
The unique id of the current event.
Definition: listmodus.h:264
ParticleData contains the dynamic information of a certain particle.
Definition: particledata.h:59
static bool exists(PdgCode pdgcode)
The Particles class abstracts the storage and manipulation of particles.
Definition: particles.h:33
size_t size() const
Definition: particles.h:87
const ParticleData & insert(const ParticleData &p)
Inserts the particle into the list of particles.
Definition: particles.cc:50
PdgCode stores a Particle Data Group Particle Numbering Scheme particle type number.
Definition: pdgcode.h:108
int charge() const
The charge of the particle.
Definition: pdgcode.h:650
Collection of useful constants that are known at compile time.
@ Off
No spin interactions.
std::ostream & operator<<(std::ostream &out, const ActionPtr &action)
Convenience: dereferences the ActionPtr to Action.
Definition: action.h:546
std::array< einhard::Logger<>, std::tuple_size< LogArea::AreaTuple >::value > & logg
An array that stores all pre-configured Logger objects.
Definition: logging.h:245
std::basic_ostream< CharT, Traits > & field(std::basic_ostream< CharT, Traits > &s)
Stream modifier to align the next object to a specific width w.
constexpr Section output
Section for the output information.
Definition: input_keys.h:205
constexpr int p
Proton.
Definition: action.h:24
bool is_valid_process_type(int v)
ProcessType
ProcessTypes are used to identify the type of the process.
Definition: processbranch.h:39
static bool enforce_periodic_boundaries(Iterator begin, const Iterator &end, typename std::iterator_traits< Iterator >::value_type length)
Enforces periodic boundaries on the given collection of values.
Definition: algorithms.h:53
build_vector_< Line > line_parser(const std::string &input)
Helper function for parsing particles.txt and decaymodes.txt.
bool all_of(Container &&c, UnaryPredicate &&p)
Convenience wrapper for std::all_of that operates on a complete container.
Definition: algorithms.h:80
std::string to_string(ThermodynamicQuantity quantity)
Convert a ThermodynamicQuantity enum value to its corresponding string.
Definition: stringify.cc:26
static constexpr int LList
Definition: listmodus.cc:38
ParticleData create_valid_smash_particle_matching_provided_quantities(PdgCode pdgcode, double mass, const FourVector &four_position, const FourVector &four_momentum, int log_area, bool &mass_warning, bool &on_shell_warning)
This function creates a SMASH particle validating the provided information.
constexpr double really_small
Numerical error tolerance.
Definition: constants.h:41
void backpropagate_straight_line(Particles *particles, double to_time)
Definition: propagation.cc:86
std::string build_error_string(std::string message, const Line &line)
Builds a meaningful error message.
static bool is_list_of_particles_invalid(const Particles &, int)
Definition: listmodus.cc:529
Helper structure for Experiment.
int n_ensembles
Number of parallel ensembles.
SpinInteractionType spin_interaction_type
Whether to include spin interactions.
A structure to hold information about the history of the particle, e.g.
Definition: particledata.h:31
double time_last_collision
Time of the last action (excluding walls), time of kinetic freeze_out for HBT analysis this time shou...
Definition: particledata.h:44
PdgCode p2
PdgCode of the second parent particles.
Definition: particledata.h:48
PdgCode p1
PdgCode of the first parent particles.
Definition: particledata.h:46
int32_t collisions_per_particle
Collision counter per particle, zero only for initially present particles.
Definition: particledata.h:33
ProcessType process_type
type of the last action
Definition: particledata.h:37
A container to keep track of all ever existed input keys.
Definition: input_keys.h:1255
static const Key< std::vector< std::string > > modi_listBox_optionalQuantities
See user guide description for more information.
Definition: input_keys.h:6101
static const Key< std::string > modi_list_fileDirectory
See user guide description for more information.
Definition: input_keys.h:5848
static const Key< std::string > modi_listBox_filePrefix
See user guide description for more information.
Definition: input_keys.h:6053
static const Key< std::vector< std::string > > modi_list_optionalQuantities
See user guide description for more information.
Definition: input_keys.h:5977
static const Key< std::string > modi_list_filename
See user guide description for more information.
Definition: input_keys.h:5868
static const Key< int > modi_listBox_shiftId
See user guide description for more information.
Definition: input_keys.h:6083
static const Key< int > modi_list_shiftId
See user guide description for more information.
Definition: input_keys.h:5908
static const Key< std::string > modi_list_filePrefix
See user guide description for more information.
Definition: input_keys.h:5889
static const Key< std::string > modi_listBox_filename
See user guide description for more information.
Definition: input_keys.h:6032
static const Key< std::string > modi_listBox_fileDirectory
See user guide description for more information.
Definition: input_keys.h:6014
Line consists of a line number and the contents of that line.
Used when external particle list is invalid.
Definition: listmodus.h:143
Used when external particle list cannot be found.
Definition: listmodus.h:136