36 static constexpr
int LList = LogArea::List::id;
40 : file_id_{std::nullopt}, event_id_{0} {
47 assert(config_sections.size() == 1);
51 bool file_prefix_used = plain_config.
has_value({
"File_Prefix"});
52 bool filename_used = plain_config.has_value({
"Filename"});
53 if (file_prefix_used == filename_used) {
54 throw std::invalid_argument(
55 "Either 'Filename' or 'File_Prefix' key must be used in 'List' section "
56 "in configuration file. Please, adjust your configuration file.");
58 std::string key_to_take =
"Filename";
59 if (file_prefix_used) {
60 key_to_take =
"File_Prefix";
61 file_id_ = plain_config.take({
"Shift_Id"}, 0);
64 plain_config.take({key_to_take.c_str()})
67 plain_config.take({
"File_Directory"})
70 throw std::runtime_error(
"ListModus only makes sense with one ensemble");
76 out <<
"-- List Modus\nInput directory for external particle lists:\n"
84 double earliest_formation_time = DBL_MAX;
85 double formation_time_difference = 0.0;
86 double reference_formation_time = 0.0;
87 bool first_particle =
true;
88 for (
const auto &particle : particles) {
89 const double t = particle.position().x0();
90 if (t < earliest_formation_time) {
91 earliest_formation_time = t;
94 reference_formation_time = t;
95 first_particle =
false;
97 formation_time_difference += std::abs(t - reference_formation_time);
102 bool anti_streaming_needed = (formation_time_difference >
really_small);
104 if (anti_streaming_needed) {
105 for (
auto &particle : particles) {
107 const double t = particle.position().x0();
110 particle.position().threevec() - delta_t * particle.velocity();
112 particle.set_formation_time(t);
113 particle.set_cross_section_scaling_factor(0.0);
119 double t,
double x,
double y,
double z,
120 double mass,
double E,
double px,
double py,
125 pdgcode, mass, {t, x, y, z}, {E, px, py, pz},
LList,
127 particles.
insert(new_particle);
129 logg[
LList].warn() <<
"SMASH does not recognize pdg code " << pdgcode
130 <<
" loaded from file. This particle will be ignored.\n";
139 std::istringstream lineinput(line.text);
140 double t, x, y, z, mass, E, px, py, pz;
142 std::string pdg_string;
143 lineinput >> t >> x >> y >> z >> mass >> E >> px >> py >> pz >>
144 pdg_string >>
id >> charge;
145 if (lineinput.fail()) {
148 "Failed to convert the input string to the "
149 "expected data types.",
153 logg[
LList].debug(
"Particle ", pdgcode,
" (x,y,z)= (", x,
", ", y,
", ", z,
157 if (pdgcode.
charge() != charge) {
158 logg[
LList].error() <<
"Charge of pdg = " << pdgcode <<
" != " << charge;
159 throw std::invalid_argument(
"Inconsistent input (charge).");
161 try_create_particle(*particles, pdgcode, t, x, y, z, mass, E, px, py, pz);
163 if (particles->
size() > 0) {
175 ((file_id) ? std::to_string(*file_id) :
"");
177 const std::filesystem::path default_path =
180 const std::filesystem::path fpath = default_path / fname;
182 logg[
LList].debug() <<
"File: " << std::filesystem::absolute(fpath) <<
'\n';
184 if (!std::filesystem::exists(fpath)) {
186 << fpath.filename().native() <<
" does not exist! \n\n"
187 <<
"Usage of smash with external particle lists:\n"
188 <<
" 1. Put the external particle lists in one or more files\n"
189 <<
" according to the user guide instructions.\n"
190 <<
" 2. Particles info: t x y z mass p0 px py pz pdg ID charge\n"
191 <<
" in units of: fm fm fm fm GeV GeV GeV GeV GeV none none e\n";
192 throw std::runtime_error(
"External particle list does not exist!");
200 std::ifstream ifs{fpath};
211 throw std::runtime_error(
212 "Attempt to read in next event in Listmodus object but no further "
213 "data found in single provided file. Please, check your setup.");
219 std::string event_string;
220 const std::string needle =
"end";
222 while (getline(ifs, line)) {
223 if (line.find(needle) == std::string::npos) {
224 event_string += line +
"\n";
230 if (!ifs.eof() && (ifs.fail() || ifs.bad())) {
231 logg[
LList].fatal() <<
"Error while reading " << fpath.filename().native();
232 throw std::runtime_error(
"Error while reading external particle list");
242 std::streampos last_position) {
243 std::ifstream ifs{filepath};
248 if (last_position == -1) {
251 ifs.seekg(last_position);
254 int skipped_lines = 0;
255 const int max_comment_lines = 4;
256 while (std::getline(ifs, line) && line[0] !=
'#' &&
257 skipped_lines++ < max_comment_lines) {
265 logg[
LList].fatal() <<
"Error while reading "
266 << filepath.filename().native();
267 throw std::runtime_error(
"Error while reading external particle list");
276 :
ListModus(), length_(modus_config.take({
"ListBox",
"Length"})) {
291 this->ListModus::operator=(
ListModus(std::move(modus_config), param));
295 const OutputsList &output_list) {
303 data.set_4position(position);
306 std::make_unique<WallcrossingAction>(incoming_particle, data);
307 for (
const auto &output : output_list) {
308 if (!output->is_dilepton_output() && !output->is_photon_output()) {
309 output->at_interaction(*action, 0.);
315 logg[
LList].debug(
"Moved ", wraps,
" particles back into the box.");
Generic algorithms on containers and ranges.
Interface to the SMASH configuration files.
bool has_value(std::initializer_list< const char * > keys) const
Return whether there is a non-empty value behind the requested keys.
Configuration extract_sub_configuration(std::initializer_list< const char * > keys, Configuration::GetEmpty empty_if_not_existing=Configuration::GetEmpty::No)
Create a new configuration from a then-removed section of the present object.
std::vector< std::string > list_upmost_nodes()
Lists all YAML::Nodes from the configuration setup.
The FourVector class holds relevant values in Minkowski spacetime with (+, −, −, −) metric signature.
const double length_
Length of the cube's edge in fm.
int impose_boundary_conditions(Particles *particles, const OutputsList &output_list={})
Enforces that all particles are inside the box at the beginning of an event.
ListBoxModus(Configuration modus_config, const ExperimentParameters ¶meters)
Constructor (This is the same as for the ListModus)
ListModus: Provides a modus for running SMASH on an external particle list, for example as an afterbu...
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 ...
bool file_has_events_(std::filesystem::path filepath, std::streampos last_position)
Check if the file given by filepath has events left after streampos last_position.
std::optional< int > file_id_
The id of the current file.
std::string particle_list_filename_or_prefix_
Prefix of the file(s) containing the particle list.
std::filesystem::path file_path_(std::optional< int > file_id)
Return the absolute path of the data file.
std::string particle_list_file_directory_
File directory of the particle list.
double start_time_
Starting time for the List; changed to the earliest formation time.
ListModus()=default
Construct an empty list.
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...
std::streampos last_read_position_
Last read position in current file.
bool warn_about_mass_discrepancy_
Auxiliary flag to warn about mass-discrepancies only once per instance.
bool warn_about_off_shell_particles_
Auxiliary flag to warn about off-shell particles only once per instance.
std::string next_event_()
Read the next event.
double initial_conditions(Particles *particles, const ExperimentParameters ¶meters)
Generates initial state of the particles in the system according to a list.
int event_id_
The unique id of the current event.
ParticleData contains the dynamic information of a certain particle.
The Particles class abstracts the storage and manipulation of particles.
const ParticleData & insert(const ParticleData &p)
Inserts the particle into the list of particles.
PdgCode stores a Particle Data Group Particle Numbering Scheme particle type number.
int charge() const
The charge of the particle.
The ThreeVector class represents a physical three-vector with the components .
Collection of useful constants that are known at compile time.
std::ostream & operator<<(std::ostream &out, const ActionPtr &action)
Convenience: dereferences the ActionPtr to Action.
std::array< einhard::Logger<>, std::tuple_size< LogArea::AreaTuple >::value > logg
An array that stores all pre-configured Logger objects.
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.
build_vector_< Line > line_parser(const std::string &input)
Helper function for parsing particles.txt and decaymodes.txt.
static constexpr int LList
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.
std::string build_error_string(std::string message, const Line &line)
Builds a meaningful error message.
Helper structure for Experiment.
int n_ensembles
Number of parallel ensembles.
Line consists of a line number and the contents of that line.
Used when external particle list cannot be found.