334 using namespace smash;
336 const auto &log = logger<LogArea::Main>();
338 constexpr option longopts[] = {
339 {
"config", required_argument, 0,
'c'},
340 {
"decaymodes", required_argument, 0,
'd'},
341 {
"endtime", required_argument, 0,
'e'},
342 {
"force", no_argument, 0,
'f'},
343 {
"help", no_argument, 0,
'h'},
344 {
"inputfile", required_argument, 0,
'i'},
345 {
"modus", required_argument, 0,
'm'},
346 {
"particles", required_argument, 0,
'p'},
347 {
"output", required_argument, 0,
'o'},
348 {
"list-2-to-n", no_argument, 0,
'l'},
349 {
"resonance", required_argument, 0,
'r'},
350 {
"cross-sections", required_argument, 0,
's'},
351 {
"cross-sections-fs", required_argument, 0,
'S'},
352 {
"version", no_argument, 0,
'v'},
356 const std::string progname = bf::path(argv[0]).filename().native();
359 bool force_overwrite =
false;
361 std::vector<std::string> extra_config;
362 char *particles =
nullptr, *decaymodes =
nullptr, *modus =
nullptr,
363 *end_time =
nullptr, *pdg_string =
nullptr, *cs_string =
nullptr;
364 bool list2n_activated =
false;
365 bool resonance_dump_activated =
false;
366 bool cross_section_dump_activated =
false;
367 bool final_state_cross_sections =
false;
371 bool suppress_disclaimer =
false;
372 while ((opt = getopt_long(argc, argv,
"c:d:e:fhi:m:p:o:lr:s:S:v", longopts,
376 extra_config.emplace_back(optarg);
382 force_overwrite =
true;
388 usage(EXIT_SUCCESS, progname);
400 output_path = optarg;
403 list2n_activated =
true;
404 suppress_disclaimer =
true;
407 resonance_dump_activated =
true;
409 suppress_disclaimer =
true;
412 final_state_cross_sections =
true;
415 cross_section_dump_activated =
true;
417 suppress_disclaimer =
true;
422 "Branch : %s\nSystem : %s\nCompiler : %s %s\n" 423 "Build : %s\nDate : %s\n",
424 VERSION_MAJOR, GIT_BRANCH, CMAKE_SYSTEM, CMAKE_CXX_COMPILER_ID,
425 CMAKE_CXX_COMPILER_VERSION, CMAKE_BUILD_TYPE, BUILD_DATE);
426 std::exit(EXIT_SUCCESS);
428 usage(EXIT_FAILURE, progname);
434 std::cout << argv[0] <<
": invalid argument -- '" << argv[optind]
436 usage(EXIT_FAILURE, progname);
439 if (!suppress_disclaimer) {
447 input_path.filename());
448 for (
const auto &config : extra_config) {
456 if (!bf::exists(particles)) {
457 std::stringstream err;
458 err <<
"The particles file was expected at '" << particles
459 <<
"', but the file does not exist.";
460 throw std::runtime_error(err.str());
462 std::string particle_string =
read_all(bf::ifstream{particles});
464 std::stringstream err;
465 err <<
"The particles file has CR LF line endings. Please use LF" 467 throw std::runtime_error(err.str());
472 if (!bf::exists(decaymodes)) {
473 std::stringstream err;
474 err <<
"The decay modes file was expected at '" << decaymodes
475 <<
"', but the file does not exist.";
476 throw std::runtime_error(err.str());
478 std::string decay_string =
read_all(bf::ifstream{decaymodes});
480 std::stringstream err;
481 err <<
"The decay mode file has CR LF line endings. Please use LF" 483 throw std::runtime_error(err.str());
487 if (list2n_activated) {
495 scat_finder.dump_reactions();
496 std::exit(EXIT_SUCCESS);
498 if (resonance_dump_activated) {
505 std::exit(EXIT_SUCCESS);
507 if (cross_section_dump_activated) {
511 std::string arg_string(cs_string);
512 std::vector<std::string> args =
split(arg_string,
',');
513 const unsigned int n_arg = args.size();
514 if (n_arg < 2 || n_arg > 4) {
515 throw std::invalid_argument(
"-s usage: pdg1,pdg2[,m1][,m2]");
517 PdgCode pdg_a(args[0]), pdg_b(args[1]);
520 for (
unsigned int i = 0; i < 4 - n_arg; i++) {
523 double ma = (args[2] ==
"") ? a.
mass() : std::stod(args[2]);
524 double mb = (args[3] ==
"") ? b.
mass() : std::stod(args[3]);
527 std::cout <<
"Warning: pole mass is used for stable particle " 528 << a.
name() <<
" instead of " << args[2] << std::endl;
532 std::cout <<
"Warning: pole mass is used for stable particle " 533 << b.
name() <<
" instead of " << args[3] << std::endl;
536 scat_finder.dump_cross_sections(a, b, ma, mb, final_state_cross_sections);
537 std::exit(EXIT_SUCCESS);
543 configuration[
"General"][
"End_Time"] = std::abs(std::atof(end_time));
554 std::random_device rd;
555 static_assert(std::is_same<decltype(rd()), uint32_t>::value,
556 "random_device is assumed to generate uint32_t");
557 uint64_t unsigned_seed =
558 (
static_cast<uint64_t
>(rd()) << 32) |
static_cast<uint64_t
>(rd());
560 seed =
static_cast<int64_t
>(unsigned_seed >> 1);
566 const bf::path lock_path = output_path /
"smash.lock";
568 if (!lock.acquire()) {
569 throw std::runtime_error(
570 "Another instance of SMASH is already writing to the specified " 571 "output directory. If you are sure this is not the case, remove \"" +
572 lock_path.native() +
"\".");
574 log.debug(
"output path: ", output_path);
575 if (!force_overwrite && bf::exists(output_path /
"config.yaml")) {
576 throw std::runtime_error(
577 "Output directory would get overwritten. Select a different output " 578 "directory, clean up, or tell SMASH to ignore existing files.");
583 bf::ofstream(output_path /
"config.yaml")
584 <<
"# " << VERSION_MAJOR <<
'\n' 585 <<
"# Branch : " << GIT_BRANCH <<
'\n' 586 <<
"# System : " << CMAKE_SYSTEM <<
'\n' 587 <<
"# Compiler : " << CMAKE_CXX_COMPILER_ID <<
' ' 588 << CMAKE_CXX_COMPILER_VERSION <<
'\n' 589 <<
"# Build : " << CMAKE_BUILD_TYPE <<
'\n' 590 <<
"# Date : " << BUILD_DATE <<
'\n' 607 if (report !=
"{}") {
608 throw std::runtime_error(
609 "The following configuration values were not used:\n" + report);
615 }
catch (std::exception &e) {
616 log.fatal() <<
"SMASH failed with the following error:\n" << e.what();
Value read(std::initializer_list< const char *> keys) const
Additional interface for SMASH to read configuration values without removing them.
std::string unused_values_report() const
Returns a string listing the key/value pairs that have not been taken yet.
Configuration configuration(std::string overrides={})
Return a configuration object filled with data from src/config.yaml.
static std::unique_ptr< ExperimentBase > create(Configuration config, const bf::path &output_path)
Factory method that creates and initializes a new Experiment<Modus>.
ScatterActionsFinder actions_finder_for_dump(Configuration configuration)
Prepares ActionsFinder for cross-section and reaction dumps.
static void check_consistency()
void check_config_version_is_compatible(Configuration configuration)
Checks if the SMASH version is compatible with the version of the configuration file.
static void load_decaymodes(const std::string &input)
Loads the DecayModes map as described in the input string.
void dump_width_and_spectral_function() const
Prints out width and spectral function versus mass to the standard output.
void ensure_path_is_valid(const bf::path &path)
Ensures the output path is valid.
std::vector< std::string > split(const std::string &s, char delim)
Split string by delimiter.
Interface to the SMASH configuration files.
void setup_default_float_traps()
Setup the floating-point traps used throughout SMASH.
static const ParticleType & find(PdgCode pdgcode)
Returns the ParticleType object for the given pdgcode.
bf::path default_output_path()
void merge_yaml(const std::string &yaml)
Merge the configuration in yaml into the existing tree.
void create_all_loggers(Configuration config)
Called from main() right after the Configuration object is fully set up to create all logger objects ...
#define source_location
Hackery that is required to output the location in the source code where the log statement occurs...
Guard to create a file lock.
Particle type contains the static properties of a particle species.
void print_disclaimer()
Print the disclaimer.
PdgCode stores a Particle Data Group Particle Numbering Scheme particle type number.
static void create_type_list(const std::string &particles)
Initialize the global ParticleType list (list_all) from the given input data.
bool has_crlf_line_ending(const std::string in)
Check if a line in the string ends with \r\n.
void set_default_loglevel(einhard::LogLevel level)
Set the default log level (what will be returned from subsequent default_loglevel calls)...
Value take(std::initializer_list< const char *> keys)
The default interface for SMASH to read configuration values.
std::unique_ptr< ExperimentBase > experiment(const Configuration &c=configuration())
Create an experiment.
std::string to_string() const
Returns a YAML string of the current tree.
const std::string & name() const
std::string read_all(std::istream &&input)
Utility function to read a complete input stream (e.g.