Version: SMASH-1.7
smash::ListModus Class Reference

#include <listmodus.h>

ListModus: Provides a modus for running SMASH on an external particle list, for example as an afterburner calculation.

To use this modus, choose Modus: List

General:
Modus: List

in the configuration file.

Options for ListModus go in the "Modi"→"List" section of the configuration:

Modi:
List:
# options here

For configuring see List.

Since SMASH is searching for collisions in computational frame time 't', all particles need to be at the same time. If this is not the case in the list provided, the particles will be propagated backwards on straight lines ("anti-freestreaming"). To avoid unphysical interactions of these particles, the back-propagated particles receive a formation_time and zero cross_section_scaling_factor. The cross-sections are set to zero during the time, where the particle will just propagate on a straight line again to appear at the formation_time into the system.

Definition at line 56 of file listmodus.h.

Inheritance diagram for smash::ListModus:
[legend]
Collaboration diagram for smash::ListModus:
[legend]

Classes

struct  LoadFailure
 Used when external particle list cannot be found. More...
 

Public Member Functions

 ListModus (Configuration modus_config, const ExperimentParameters &parameters)
 Constructor. More...
 
 ListModus ()
 Construct an empty list. Useful for convenient JetScape connection. More...
 
double initial_conditions (Particles *particles, const ExperimentParameters &parameters)
 Generates initial state of the particles in the system according to a list. More...
 
void backpropagate_to_same_time (Particles &particles)
 Judge whether formation times are the same for all the particles; Don't do anti-freestreaming if all particles start already at the same time. More...
 
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)
 Tries to add a new particle to particles and performs consistency checks: (i) The PDG code is legal and exists in SMASH. More...
 
bool is_list () const
 
- Public Member Functions inherited from smash::ModusDefault
int impose_boundary_conditions (Particles *, const OutputsList &={})
 Enforces sensible positions for the particles. More...
 
int total_N_number () const
 
int proj_N_number () const
 
bool cll_in_nucleus () const
 
bool is_collider () const
 
bool is_list () const
 
double impact_parameter () const
 
double velocity_projectile () const
 
double velocity_target () const
 
FermiMotion fermi_motion () const
 
double max_timestep (double) const
 
double length () const
 
double nuclei_passing_time () const
 Get the passing time of the two nuclei in a collision. More...
 
Grid< GridOptions::Normalcreate_grid (const Particles &particles, double min_cell_length, double timestep_duration, CellSizeStrategy strategy=CellSizeStrategy::Optimal) const
 Creates the Grid with normal boundary conditions. More...
 

Protected Attributes

double start_time_ = 0.
 Starting time for the List; changed to the earliest formation time. More...
 

Private Member Functions

bool file_has_events_ (bf::path filepath, std::streampos last_position)
 Check if the file given by filepath has events left after streampos last_position. More...
 
bf::path file_path_ (const int file_id)
 Return the absolute file path based on given integer. More...
 
std::string next_event_ ()
 Read the next event. More...
 

Private Attributes

std::string particle_list_file_directory_
 File directory of the particle list. More...
 
std::string particle_list_file_prefix_
 File prefix of the particle list. More...
 
std::string current_particle_list_file_
 File name of current file. More...
 
const int shift_id_
 shift_id is the start number of file_id_ More...
 
int event_id_
 event_id_ = the unique id of the current event More...
 
int file_id_
 file_id_ is the id of the current file More...
 
int n_warns_precision_ = 0
 Counter for mass-check warnings to avoid spamming. More...
 
int n_warns_mass_consistency_ = 0
 Counter for energy-momentum conservation warnings to avoid spamming. More...
 
std::streampos last_read_position_
 last read position in current file More...
 

Friends

std::ostream & operator<< (std::ostream &, const ListModus &)
 Writes the initial state for the List to the output stream. More...
 

Constructor & Destructor Documentation

smash::ListModus::ListModus ( Configuration  modus_config,
const ExperimentParameters parameters 
)
explicit

Constructor.

Gathers all configuration variables for the List.

Parameters
[in]modus_configThe configuration object that sets all initial conditions of the experiment.
[in]parametersUnused, but necessary because of templated initialization

Definition at line 122 of file listmodus.cc.

123  : shift_id_(modus_config.take({"List", "Shift_Id"})) {
124  std::string fd = modus_config.take({"List", "File_Directory"});
126 
127  std::string fp = modus_config.take({"List", "File_Prefix"});
129 
130  event_id_ = 0;
132 }
std::string particle_list_file_directory_
File directory of the particle list.
Definition: listmodus.h:151
int file_id_
file_id_ is the id of the current file
Definition: listmodus.h:166
int event_id_
event_id_ = the unique id of the current event
Definition: listmodus.h:163
std::string particle_list_file_prefix_
File prefix of the particle list.
Definition: listmodus.h:154
const int shift_id_
shift_id is the start number of file_id_
Definition: listmodus.h:160
smash::ListModus::ListModus ( )
inline

Construct an empty list. Useful for convenient JetScape connection.

Definition at line 72 of file listmodus.h.

72 : shift_id_(0) {}
const int shift_id_
shift_id is the start number of file_id_
Definition: listmodus.h:160

Here is the call graph for this function:

Member Function Documentation

double smash::ListModus::initial_conditions ( Particles particles,
const ExperimentParameters parameters 
)

Generates initial state of the particles in the system according to a list.

Parameters
[out]particlesAn empty list that gets filled up by this function
[in]parametersUnused, but necessary because of templated use of this function
Returns
The starting time of the simulation
Exceptions
runtime_errorif an input list file could not be found
LoadFailureif an input list file is not correctly formatted
invalid_argumentif the listed charge of a particle does not correspond to its pdg charge

Definition at line 231 of file listmodus.cc.

232  {
233  const auto &log = logger<LogArea::List>();
234  std::string particle_list = next_event_();
235 
236  for (const Line &line : line_parser(particle_list)) {
237  std::istringstream lineinput(line.text);
238  double t, x, y, z, mass, E, px, py, pz;
239  int id, charge;
240  std::string pdg_string;
241  lineinput >> t >> x >> y >> z >> mass >> E >> px >> py >> pz >>
242  pdg_string >> id >> charge;
243  if (lineinput.fail()) {
244  throw LoadFailure(
245  build_error_string("While loading external particle lists data:\n"
246  "Failed to convert the input string to the "
247  "expected data types.",
248  line));
249  }
250  PdgCode pdgcode(pdg_string);
251  log.debug("Particle ", pdgcode, " (x,y,z)= (", x, ", ", y, ", ", z, ")");
252 
253  // Charge consistency check
254  if (pdgcode.charge() != charge) {
255  log.error() << "Charge of pdg = " << pdgcode << " != " << charge;
256  throw std::invalid_argument("Inconsistent input (charge).");
257  }
258  try_create_particle(*particles, pdgcode, t, x, y, z, mass, E, px, py, pz);
259  }
260  if (particles->size() > 0) {
261  backpropagate_to_same_time(*particles);
262  } else {
263  start_time_ = 0.0;
264  }
265  event_id_++;
266 
267  return start_time_;
268 }
void backpropagate_to_same_time(Particles &particles)
Judge whether formation times are the same for all the particles; Don&#39;t do anti-freestreaming if all ...
Definition: listmodus.cc:141
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)
Tries to add a new particle to particles and performs consistency checks: (i) The PDG code is legal a...
Definition: listmodus.cc:178
double start_time_
Starting time for the List; changed to the earliest formation time.
Definition: listmodus.h:147
int event_id_
event_id_ = the unique id of the current event
Definition: listmodus.h:163
build_vector_< Line > line_parser(const std::string &input)
Helper function for parsing particles.txt and decaymodes.txt.
std::string next_event_()
Read the next event.
Definition: listmodus.cc:297
std::string build_error_string(std::string message, const Line &line)
Builds a meaningful error message.

Here is the call graph for this function:

Here is the caller graph for this function:

void smash::ListModus::backpropagate_to_same_time ( Particles particles)

Judge whether formation times are the same for all the particles; Don't do anti-freestreaming if all particles start already at the same time.

If particles are at different times, calculate earliest formation time as start_time_ and free-stream all particles back to this time.

Parameters
particlesparticles to be checked and possibly back-streamed

Definition at line 141 of file listmodus.cc.

141  {
142  /* (1) If particles are already at the same time - don't touch them
143  AND start at the start_time_ from the config. */
144  double earliest_formation_time = DBL_MAX;
145  double formation_time_difference = 0.0;
146  double reference_formation_time = 0.0; // avoid compiler warning
147  bool first_particle = true;
148  for (const auto &particle : particles) {
149  const double t = particle.position().x0();
150  if (t < earliest_formation_time) {
151  earliest_formation_time = t;
152  }
153  if (first_particle) {
154  reference_formation_time = t;
155  first_particle = false;
156  } else {
157  formation_time_difference += std::abs(t - reference_formation_time);
158  }
159  }
160  /* (2) If particles are NOT at the same time -> anti-stream them to
161  the earliest time (Note: not to the start_time_ set by config) */
162  bool anti_streaming_needed = (formation_time_difference > really_small);
163  start_time_ = earliest_formation_time;
164  if (anti_streaming_needed) {
165  for (auto &particle : particles) {
166  /* for hydro output where formation time is different */
167  const double t = particle.position().x0();
168  const double delta_t = t - start_time_;
169  const ThreeVector r =
170  particle.position().threevec() - delta_t * particle.velocity();
171  particle.set_4position(FourVector(start_time_, r));
172  particle.set_formation_time(t);
173  particle.set_cross_section_scaling_factor(0.0);
174  }
175  }
176 }
constexpr double really_small
Numerical error tolerance.
Definition: constants.h:37
double start_time_
Starting time for the List; changed to the earliest formation time.
Definition: listmodus.h:147

Here is the caller graph for this function:

void smash::ListModus::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 
)

Tries to add a new particle to particles and performs consistency checks: (i) The PDG code is legal and exists in SMASH.

If not, a warning is printed and the particle is ignored. (ii) The mass matches the pole mass of pdgcode in SMASH. If it does not, then a warning is printed, the pole mass of the particle is set equal to the corresponding mass from SMASH particle table and it's energy is recomputed as \( E^2 = p^2 + m^2 \). (iii) Any stable particle is on-shell, i.e. \( E^2 - p^2 = m^2 \). If it is not, then a warning is printed and the energy is set to \( E^2 = p^2 + m^2 \). This very tolerant behaviour is justified by the practical usage of SMASH as afterburner. Usually particles unknown to SMASH are rare resonances, which do not play a large role. Mass mismatch is typically less than 1% and comes from rounding and from SMASH enforcing isospin symmetry (for example the mass of neutral pion is artificially forced to be the same as charged pion). On-shellness violation typically comes from the insufficient number of significant digits in the input file + rounding.

Parameters
[in]pdgcodepdg code of added particle
[in]ttime of added particle
[in]xx-coordinate of added particle
[in]yy-coordinate of added particle
[in]zz-coordinate of added particle
[in]massmass of added particle
[in]Eenergy of added particle
[in]pxx-component of momentum of added particle
[in]pyy-component of momentum of added particle
[in]pzz-component of momentum of added particle
[out]particlesstructure, to which the particle is added

Definition at line 178 of file listmodus.cc.

181  {
182  constexpr int max_warns_precision = 10, max_warn_mass_consistency = 10;
183  const auto &log = logger<LogArea::List>();
184  try {
185  ParticleData &particle = particles.create(pdgcode);
186  // SMASH mass versus input mass consistency check
187  if (particle.type().is_stable() &&
188  std::abs(mass - particle.pole_mass()) > really_small) {
189  if (n_warns_precision_ < max_warns_precision) {
190  log.warn() << "Provided mass of " << particle.type().name() << " = "
191  << mass << " [GeV] is inconsistent with SMASH value = "
192  << particle.pole_mass() << ". Forcing E = sqrt(p^2 + m^2)"
193  << ", where m is SMASH mass.";
195  } else if (n_warns_precision_ == max_warns_precision) {
196  log.warn(
197  "Further warnings about SMASH mass versus input mass"
198  " inconsistencies will be suppressed.");
200  }
201  particle.set_4momentum(mass, ThreeVector(px, py, pz));
202  }
203  particle.set_4momentum(FourVector(E, px, py, pz));
204  // On-shell condition consistency check
205  if (std::abs(particle.momentum().sqr() - mass * mass) > really_small) {
206  if (n_warns_mass_consistency_ < max_warn_mass_consistency) {
207  log.warn() << "Provided 4-momentum " << particle.momentum() << " and "
208  << " mass " << mass << " do not satisfy E^2 - p^2 = m^2."
209  << " This may originate from the lack of numerical"
210  << " precision in the input. Setting E to sqrt(p^2 + m^2).";
212  } else if (n_warns_mass_consistency_ == max_warn_mass_consistency) {
213  log.warn(
214  "Further warnings about E != sqrt(p^2 + m^2) will"
215  " be suppressed.");
217  }
218  particle.set_4momentum(mass, ThreeVector(px, py, pz));
219  }
220  // Set spatial coordinates, they will later be backpropagated if needed
221  particle.set_4position(FourVector(t, x, y, z));
222  particle.set_formation_time(t);
223  particle.set_cross_section_scaling_factor(1.0);
224  } catch (ParticleType::PdgNotFoundFailure &) {
225  log.warn() << "SMASH does not recognize pdg code " << pdgcode
226  << " loaded from file. This particle will be ignored.\n";
227  }
228 }
constexpr double really_small
Numerical error tolerance.
Definition: constants.h:37
int n_warns_mass_consistency_
Counter for energy-momentum conservation warnings to avoid spamming.
Definition: listmodus.h:171
int n_warns_precision_
Counter for mass-check warnings to avoid spamming.
Definition: listmodus.h:169

Here is the call graph for this function:

Here is the caller graph for this function:

bool smash::ListModus::is_list ( ) const
inline
Returns
whether the modus is list modus (which is, yes, trivially true)

Definition at line 143 of file listmodus.h.

143 { return true; }
bool smash::ListModus::file_has_events_ ( bf::path  filepath,
std::streampos  last_position 
)
private

Check if the file given by filepath has events left after streampos last_position.

Parameters
[in]filepathPath to file to be checked.
[in]last_positionStreamposition in file after which check is performed
Returns
True if there is at least one event left, false otherwise
Exceptions
runtime_errorIf file could not be read for whatever reason.

Definition at line 337 of file listmodus.cc.

338  {
339  const auto &log = logger<LogArea::List>();
340  bf::ifstream ifs{filepath};
341  std::string line;
342 
343  // last event read read at end of file. we know this because errors are
344  // handled in next_event
345  if (last_position == -1) {
346  return false;
347  }
348  ifs.seekg(last_position);
349  // skip over comment lines, assume that a max. of four consecutive comment
350  // lines can occur
351  int skipped_lines = 0;
352  const int max_comment_lines = 4;
353  while (std::getline(ifs, line) && line[0] != '#' &&
354  skipped_lines++ < max_comment_lines) {
355  }
356 
357  if (ifs.eof()) {
358  return false;
359  }
360 
361  if (!ifs.good()) {
362  log.fatal() << "Error while reading " << filepath.filename().native();
363  throw std::runtime_error("Error while reading external particle list");
364  }
365 
366  ifs.close();
367  return true;
368 }

Here is the caller graph for this function:

bf::path smash::ListModus::file_path_ ( const int  file_id)
private

Return the absolute file path based on given integer.

The filename is assumed to have the form (particle_list_prefix)_(file_id)

Parameters
[in]file_idinteger of wanted file
Returns
Absolute file path to file
Exceptions
runtime_errorif file does not exist.

Definition at line 270 of file listmodus.cc.

270  {
271  const auto &log = logger<LogArea::List>();
272  std::stringstream fname;
273  fname << particle_list_file_prefix_ << file_id;
274 
275  const bf::path default_path = bf::absolute(particle_list_file_directory_);
276 
277  const bf::path fpath = default_path / fname.str();
278 
279  log.debug() << fpath.filename().native() << '\n';
280 
281  if (!bf::exists(fpath)) {
282  log.fatal() << fpath.filename().native() << " does not exist! \n"
283  << "\n Usage of smash with external particle lists:\n"
284  << "1. Put the external particle lists in file \n"
285  << "File_Directory/File_Prefix{id} where {id} "
286  << "traversal [Shift_Id, Nevent-1]\n"
287  << "2. Particles info: t x y z mass p0 px py pz"
288  << " pdg ID charge\n"
289  << "in units of: fm fm fm fm GeV GeV GeV GeV GeV"
290  << " none none none\n";
291  throw std::runtime_error("External particle list does not exist!");
292  }
293 
294  return fpath;
295 }
std::string particle_list_file_directory_
File directory of the particle list.
Definition: listmodus.h:151
std::string particle_list_file_prefix_
File prefix of the particle list.
Definition: listmodus.h:154

Here is the caller graph for this function:

std::string smash::ListModus::next_event_ ( )
private

Read the next event.

Either from the current file if it has more events or from the next file (with file_id += 1)

Returns
One event as string.
Exceptions
runtime_errorIf file could not be read for whatever reason.

Definition at line 297 of file listmodus.cc.

297  {
298  const auto &log = logger<LogArea::List>();
299 
300  const bf::path fpath = file_path_(file_id_);
301  bf::ifstream ifs{fpath};
302  ifs.seekg(last_read_position_);
303 
304  if (!file_has_events_(fpath, last_read_position_)) {
305  // current file out of events. get next file and call this function
306  // recursively.
307  file_id_++;
309  ifs.close();
310  return next_event_();
311  }
312 
313  // read one event. events marked by line # event end i in case of Oscar
314  // output. Assume one event per file for all other output formats
315  std::string event_string;
316  const std::string needle = "end";
317  std::string line;
318  while (getline(ifs, line)) {
319  if (line.find(needle) == std::string::npos) {
320  event_string += line + "\n";
321  } else {
322  break;
323  }
324  }
325 
326  if (!ifs.eof() && (ifs.fail() || ifs.bad())) {
327  log.fatal() << "Error while reading " << fpath.filename().native();
328  throw std::runtime_error("Error while reading external particle list");
329  }
330  // save position for next event read
331  last_read_position_ = ifs.tellg();
332  ifs.close();
333 
334  return event_string;
335 }
int file_id_
file_id_ is the id of the current file
Definition: listmodus.h:166
bool file_has_events_(bf::path filepath, std::streampos last_position)
Check if the file given by filepath has events left after streampos last_position.
Definition: listmodus.cc:337
std::string next_event_()
Read the next event.
Definition: listmodus.cc:297
std::streampos last_read_position_
last read position in current file
Definition: listmodus.h:185
bf::path file_path_(const int file_id)
Return the absolute file path based on given integer.
Definition: listmodus.cc:270

Here is the call graph for this function:

Here is the caller graph for this function:

Member Data Documentation

double smash::ListModus::start_time_ = 0.
protected

Starting time for the List; changed to the earliest formation time.

Definition at line 147 of file listmodus.h.

std::string smash::ListModus::particle_list_file_directory_
private

File directory of the particle list.

Definition at line 151 of file listmodus.h.

std::string smash::ListModus::particle_list_file_prefix_
private

File prefix of the particle list.

Definition at line 154 of file listmodus.h.

std::string smash::ListModus::current_particle_list_file_
private

File name of current file.

Definition at line 157 of file listmodus.h.

const int smash::ListModus::shift_id_
private

shift_id is the start number of file_id_

Definition at line 160 of file listmodus.h.

int smash::ListModus::event_id_
private

event_id_ = the unique id of the current event

Definition at line 163 of file listmodus.h.

int smash::ListModus::file_id_
private

file_id_ is the id of the current file

Definition at line 166 of file listmodus.h.

int smash::ListModus::n_warns_precision_ = 0
private

Counter for mass-check warnings to avoid spamming.

Definition at line 169 of file listmodus.h.

int smash::ListModus::n_warns_mass_consistency_ = 0
private

Counter for energy-momentum conservation warnings to avoid spamming.

Definition at line 171 of file listmodus.h.

std::streampos smash::ListModus::last_read_position_
private

last read position in current file

Definition at line 185 of file listmodus.h.


The documentation for this class was generated from the following files: