Version: SMASH-2.0.2
smash.cc File Reference
#include <getopt.h>
#include <set>
#include <sstream>
#include <vector>
#include <boost/filesystem/fstream.hpp>
#include "smash/cxx14compat.h"
#include "smash/decaymodes.h"
#include "smash/experiment.h"
#include "smash/filelock.h"
#include "smash/random.h"
#include "smash/scatteractionsfinder.h"
#include "smash/setup_particles_decaymodes.h"
#include "smash/sha256.h"
#include "smash/stringfunctions.h"
#include "smash/config.h"

Go to the source code of this file.

Classes

struct  smash::anonymous_namespace{smash.cc}::OutputDirectoryExists
 
struct  smash::anonymous_namespace{smash.cc}::OutputDirectoryOutOfIds
 

Namespaces

 smash
 
 smash::anonymous_namespace{smash.cc}
 

Functions

void smash::anonymous_namespace{smash.cc}::print_disclaimer ()
 Print the disclaimer. More...
 
bf::path smash::anonymous_namespace{smash.cc}::default_output_path ()
 
void smash::anonymous_namespace{smash.cc}::ensure_path_is_valid (const bf::path &path)
 Ensures the output path is valid. More...
 
ScatterActionsFinder smash::anonymous_namespace{smash.cc}::actions_finder_for_dump (Configuration configuration)
 Prepares ActionsFinder for cross-section and reaction dumps. More...
 
void smash::anonymous_namespace{smash.cc}::check_config_version_is_compatible (Configuration configuration)
 Checks if the SMASH version is compatible with the version of the configuration file. More...
 
void smash::anonymous_namespace{smash.cc}::check_for_unused_config_values (const Configuration &configuration)
 Checks if there are unused config values. More...
 
void smash::anonymous_namespace{smash.cc}::ignore_simulation_config_values (Configuration &configuration)
 Remove all config values that are only needed for simulations. More...
 
void smash::anonymous_namespace{smash.cc}::initialize_particles_and_decays (Configuration &configuration)
 Initialize the particles and decays from the configuration. More...
 
void smash::anonymous_namespace{smash.cc}::initialize_particles_and_decays (Configuration &configuration, sha256::Hash hash, bf::path tabulations_path)
 Initialize the particles and decays from the configuration, the hash and the path to the cashed resonance integrals. More...
 
int main (int argc, char *argv[])
 Main program Smashes Many Accelerated Strongly-Interacting Hadrons :-) More...
 

Function Documentation

◆ main()

int main ( int  argc,
char *  argv[] 
)

Main program Smashes Many Accelerated Strongly-Interacting Hadrons :-)

Do command line parsing and hence decides modus

Parameters
[in]argcNumber of arguments on command-line
[in]argvList of arguments on command-line
Returns
Either 0 or EXIT_FAILURE.

Definition at line 410 of file smash.cc.

410  {
411  using namespace smash; // NOLINT(build/namespaces)
412 
413  constexpr option longopts[] = {
414  {"config", required_argument, 0, 'c'},
415  {"decaymodes", required_argument, 0, 'd'},
416  {"endtime", required_argument, 0, 'e'},
417  {"force", no_argument, 0, 'f'},
418  {"help", no_argument, 0, 'h'},
419  {"inputfile", required_argument, 0, 'i'},
420  {"modus", required_argument, 0, 'm'},
421  {"particles", required_argument, 0, 'p'},
422  {"output", required_argument, 0, 'o'},
423  {"list-2-to-n", no_argument, 0, 'l'},
424  {"resonance", required_argument, 0, 'r'},
425  {"cross-sections", required_argument, 0, 's'},
426  {"cross-sections-fs", required_argument, 0, 'S'},
427  {"dump-iSS", no_argument, 0, 'x'},
428  {"version", no_argument, 0, 'v'},
429  {"no-cache", no_argument, 0, 'n'},
430  {"quiet", no_argument, 0, 'q'},
431  {nullptr, 0, 0, 0}};
432 
433  // strip any path to progname
434  const std::string progname = bf::path(argv[0]).filename().native();
435 
436  try {
437  bool force_overwrite = false;
438  bf::path output_path = default_output_path(), input_path("./config.yaml");
439  std::vector<std::string> extra_config;
440  char *particles = nullptr, *decaymodes = nullptr, *modus = nullptr,
441  *end_time = nullptr, *pdg_string = nullptr, *cs_string = nullptr;
442  bool list2n_activated = false;
443  bool resonance_dump_activated = false;
444  bool cross_section_dump_activated = false;
445  bool final_state_cross_sections = false;
446  bool particles_dump_iSS_format = false;
447  bool cache_integrals = true;
448 
449  // parse command-line arguments
450  int opt;
451  bool suppress_disclaimer = false;
452  while ((opt = getopt_long(argc, argv, "c:d:e:fhi:m:p:o:lr:s:S:xvnq",
453  longopts, nullptr)) != -1) {
454  switch (opt) {
455  case 'c':
456  extra_config.emplace_back(optarg);
457  break;
458  case 'd':
459  decaymodes = optarg;
460  break;
461  case 'f':
462  force_overwrite = true;
463  break;
464  case 'i':
465  input_path = optarg;
466  break;
467  case 'h':
468  usage(EXIT_SUCCESS, progname);
469  break;
470  case 'm':
471  modus = optarg;
472  break;
473  case 'p':
474  particles = optarg;
475  break;
476  case 'e':
477  end_time = optarg;
478  break;
479  case 'o':
480  output_path = optarg;
481  break;
482  case 'l':
483  list2n_activated = true;
484  suppress_disclaimer = true;
485  break;
486  case 'r':
487  resonance_dump_activated = true;
488  pdg_string = optarg;
489  suppress_disclaimer = true;
490  break;
491  case 'S':
492  final_state_cross_sections = true;
493  // fallthrough
494  case 's':
495  cross_section_dump_activated = true;
496  cs_string = optarg;
497  suppress_disclaimer = true;
498  break;
499  case 'x':
500  particles_dump_iSS_format = true;
501  suppress_disclaimer = true;
502  break;
503  case 'v':
504  std::printf(
505  "%s\n"
506  "Branch : %s\nSystem : %s\nCompiler : %s %s\n"
507  "Build : %s\nDate : %s\n",
508  VERSION_MAJOR, GIT_BRANCH, CMAKE_SYSTEM, CMAKE_CXX_COMPILER_ID,
509  CMAKE_CXX_COMPILER_VERSION, CMAKE_BUILD_TYPE, BUILD_DATE);
510  std::exit(EXIT_SUCCESS);
511  case 'n':
512  cache_integrals = false;
513  break;
514  case 'q':
515  suppress_disclaimer = true;
516  break;
517  default:
518  usage(EXIT_FAILURE, progname);
519  }
520  }
521 
522  // Abort if there are unhandled arguments left.
523  if (optind < argc) {
524  std::cout << argv[0] << ": invalid argument -- '" << argv[optind]
525  << "'\n";
526  usage(EXIT_FAILURE, progname);
527  }
528 
529  if (!suppress_disclaimer) {
531  }
532 
533  // Read in config file
534  Configuration configuration(input_path.parent_path(),
535  input_path.filename());
536  // Merge config passed via command line
537  for (const auto &config : extra_config) {
538  configuration.merge_yaml(config);
539  }
540 
541  // Set up logging
543  configuration.take({"Logging", "default"}, einhard::ALL));
544  create_all_loggers(configuration["Logging"]);
545 
547 
548  // check if version matches before doing anything else
550 
552  " create ParticleType and DecayModes");
553 
554  auto particles_and_decays =
555  load_particles_and_decaymodes(particles, decaymodes);
556  /* For particles and decaymodes: external file is superior to config.
557  * Hovever, warn in case of conflict.
558  */
559  if (configuration.has_value({"particles"}) && particles) {
560  logg[LMain].warn(
561  "Ambiguity: particles from external file ", particles,
562  " requested, but there is also particle list in the config."
563  " Using particles from ",
564  particles);
565  }
566  if (!configuration.has_value({"particles"}) || particles) {
567  configuration["particles"] = particles_and_decays.first;
568  }
569 
570  if (configuration.has_value({"decaymodes"}) && decaymodes) {
571  logg[LMain].warn(
572  "Ambiguity: decaymodes from external file ", decaymodes,
573  " requested, but there is also decaymodes list in the config."
574  " Using decaymodes from",
575  decaymodes);
576  }
577  if (!configuration.has_value({"decaymodes"}) || decaymodes) {
578  configuration["decaymodes"] = particles_and_decays.second;
579  }
580 
581  // Calculate a hash of the SMASH version, the particles and decaymodes.
582  const std::string version(VERSION_MAJOR);
583  const std::string particle_string = configuration["particles"].to_string();
584  const std::string decay_string = configuration["decaymodes"].to_string();
585  sha256::Context hash_context;
586  hash_context.update(version);
587  hash_context.update(particle_string);
588  hash_context.update(decay_string);
589  const auto hash = hash_context.finalize();
590  logg[LMain].info() << "Config hash: " << sha256::hash_to_string(hash);
591 
592  bf::path tabulations_path;
593  if (cache_integrals) {
594  tabulations_path = output_path.parent_path() / "tabulations";
595  bf::create_directories(tabulations_path);
596  logg[LMain].info() << "Tabulations path: " << tabulations_path;
597  } else {
598  tabulations_path = "";
599  }
600  if (list2n_activated) {
601  /* Print only 2->n, n > 1. Do not dump decays, which can be found in
602  * decaymodes.txt anyway */
603  configuration.merge_yaml("{Collision_Term: {Two_to_One: False}}");
604  logg[LMain].info() << "Tabulations path: " << tabulations_path;
605  initialize_particles_and_decays(configuration, hash, tabulations_path);
606  auto scat_finder = actions_finder_for_dump(configuration);
607 
610 
611  scat_finder.dump_reactions();
612  std::exit(EXIT_SUCCESS);
613  }
614  if (particles_dump_iSS_format) {
616  ParticleTypePtrList list;
617  list.clear();
618  for (const auto &ptype : ParticleType::list_all()) {
619  list.push_back(&ptype);
620  }
621  std::sort(list.begin(), list.end(),
623  return a->mass() < b->mass();
624  });
625  for (const ParticleTypePtr &ptype : list) {
626  if (ptype->pdgcode().is_lepton() || ptype->baryon_number() < 0) {
627  continue;
628  }
629  const auto &decay_modes = ptype->decay_modes();
630  const auto &modelist = decay_modes.decay_mode_list();
631  int ndecays = ptype->is_stable() ? 1 : modelist.size();
632  std::printf("%13i %s %10.5f %10.5f %5i %5i %5i %5i %5i %5i %5i %5i\n",
633  ptype->pdgcode().get_decimal(),
634  smash::utf8::fill_left(ptype->name(), 12, ' ').c_str(),
635  ptype->mass(), ptype->width_at_pole(),
636  ptype->pdgcode().spin_degeneracy(), ptype->baryon_number(),
637  ptype->strangeness(), ptype->pdgcode().charmness(),
638  ptype->pdgcode().bottomness(), ptype->isospin() + 1,
639  ptype->charge(), ndecays);
640  if (!ptype->is_stable()) {
641  for (const auto &decay : modelist) {
642  auto ptypes = decay->particle_types();
643  std::printf("%13i %13i %20.5f %13i %13i %13i %13i %13i\n",
644  ptype->pdgcode().get_decimal(), 2, decay->weight(),
645  ptypes[0]->pdgcode().get_decimal(),
646  ptypes[1]->pdgcode().get_decimal(), 0, 0, 0);
647  }
648  } else {
649  std::printf("%13i %13i %20.5f %13i %13i %13i %13i %13i\n",
650  ptype->pdgcode().get_decimal(), 1, 1.0,
651  ptype->pdgcode().get_decimal(), 0, 0, 0, 0);
652  }
653  }
654  std::exit(EXIT_SUCCESS);
655  }
656  if (resonance_dump_activated) {
657  // Ignore config values that don't make sense.
658  initialize_particles_and_decays(configuration, hash, tabulations_path);
659  const auto _dummy = ExperimentBase::create(configuration, "");
662 
663  PdgCode pdg(pdg_string);
664  const ParticleType &res = ParticleType::find(pdg);
666  std::exit(EXIT_SUCCESS);
667  }
668  if (cross_section_dump_activated) {
669  initialize_particles_and_decays(configuration, hash, tabulations_path);
670  std::string arg_string(cs_string);
671  std::vector<std::string> args = split(arg_string, ',');
672  const unsigned int n_arg = args.size();
673  if (n_arg != 2 && n_arg != 4 && n_arg < 5) {
674  throw std::invalid_argument("-s usage: pdg1,pdg2[,m1,m2[,sqrts1,...]]");
675  }
676  PdgCode pdg_a(args[0]), pdg_b(args[1]);
677  const ParticleType &a = ParticleType::find(pdg_a);
678  const ParticleType &b = ParticleType::find(pdg_b);
679  if (n_arg < 4) {
680  for (unsigned int i = 0; i < 4 - n_arg; i++) {
681  args.push_back("");
682  }
683  }
684  double ma = (args[2] == "") ? a.mass() : std::stod(args[2]);
685  double mb = (args[3] == "") ? b.mass() : std::stod(args[3]);
686  if (a.is_stable() && args[2] != "" && std::stod(args[2]) != a.mass()) {
687  ma = a.mass();
688  std::cerr << "Warning: pole mass is used for stable particle "
689  << a.name() << " instead of " << args[2] << std::endl;
690  }
691  if (b.is_stable() && args[3] != "" && std::stod(args[3]) != b.mass()) {
692  mb = b.mass();
693  std::cerr << "Warning: pole mass is used for stable particle "
694  << b.name() << " instead of " << args[3] << std::endl;
695  }
696  const size_t plab_size = n_arg <= 4 ? 0 : n_arg - 4;
697  std::vector<double> plab;
698  plab.reserve(plab_size);
699  for (size_t i = 4; i < n_arg; i++) {
700  plab.push_back(std::stod(args.at(i)));
701  }
702  auto scat_finder = actions_finder_for_dump(configuration);
703 
706 
707  scat_finder.dump_cross_sections(a, b, ma, mb, final_state_cross_sections,
708  plab);
709  std::exit(EXIT_SUCCESS);
710  }
711  if (modus) {
712  configuration["General"]["Modus"] = std::string(modus);
713  }
714  if (end_time) {
715  configuration["General"]["End_Time"] = std::abs(std::atof(end_time));
716  }
717 
718  int64_t seed = configuration.read({"General", "Randomseed"});
719  if (seed < 0) {
720  configuration["General"]["Randomseed"] = random::generate_63bit_seed();
721  }
722 
723  // Check output path
724  ensure_path_is_valid(output_path);
725  const bf::path lock_path = output_path / "smash.lock";
726  FileLock lock(lock_path);
727  if (!lock.acquire()) {
728  throw std::runtime_error(
729  "Another instance of SMASH is already writing to the specified "
730  "output directory. If you are sure this is not the case, remove \"" +
731  lock_path.native() + "\".");
732  }
733  logg[LMain].debug("output path: ", output_path);
734  if (!force_overwrite && bf::exists(output_path / "config.yaml")) {
735  throw std::runtime_error(
736  "Output directory would get overwritten. Select a different output "
737  "directory, clean up, or tell SMASH to ignore existing files.");
738  }
739 
740  /* Keep a copy of the configuration that was used in the output directory
741  * also save information about SMASH build as a comment */
742  bf::ofstream(output_path / "config.yaml")
743  << "# " << VERSION_MAJOR << '\n'
744  << "# Branch : " << GIT_BRANCH << '\n'
745  << "# System : " << CMAKE_SYSTEM << '\n'
746  << "# Compiler : " << CMAKE_CXX_COMPILER_ID << ' '
747  << CMAKE_CXX_COMPILER_VERSION << '\n'
748  << "# Build : " << CMAKE_BUILD_TYPE << '\n'
749  << "# Date : " << BUILD_DATE << '\n'
750  << configuration.to_string() << '\n';
752  " create ParticleType and DecayModes");
753  initialize_particles_and_decays(configuration, hash, tabulations_path);
754 
755  // Create an experiment
756  logg[LMain].trace(SMASH_SOURCE_LOCATION, " create Experiment");
757  auto experiment = ExperimentBase::create(configuration, output_path);
758 
759  // Version value is not used in experiment. Get rid of it to prevent
760  // warning.
761  configuration.take({"Version"});
763 
764  // Run the experiment
765  logg[LMain].trace(SMASH_SOURCE_LOCATION, " run the Experiment");
766  experiment->run();
767  } catch (std::exception &e) {
768  logg[LMain].fatal() << "SMASH failed with the following error:\n"
769  << e.what();
770  return EXIT_FAILURE;
771  }
772 
773  logg[LMain].trace() << SMASH_SOURCE_LOCATION << " about to return from main";
774  return 0;
775 }
Here is the call graph for this function:
smash::split
std::vector< std::string > split(const std::string &s, char delim)
Split string by delimiter.
Definition: stringfunctions.cc:120
smash
Definition: action.h:24
smash::ParticleType::dump_width_and_spectral_function
void dump_width_and_spectral_function() const
Prints out width and spectral function versus mass to the standard output.
Definition: particletype.cc:723
smash::Test::configuration
Configuration configuration(std::string overrides={})
Return a configuration object filled with data from src/config.yaml.
Definition: setup.h:162
smash::anonymous_namespace{smash.cc}::check_for_unused_config_values
void check_for_unused_config_values(const Configuration &configuration)
Checks if there are unused config values.
Definition: smash.cc:353
smash::sha256::Context::update
void update(uint8_t const *buffer, size_t buffer_size)
Add data to the SHA256 context.
Definition: sha256.cc:153
smash::Configuration::read
Value read(std::initializer_list< const char * > keys) const
Additional interface for SMASH to read configuration values without removing them.
Definition: configuration.cc:158
smash::Configuration::to_string
std::string to_string() const
Returns a YAML string of the current tree.
Definition: configuration.cc:192
smash::utf8::fill_left
std::string fill_left(const std::string &s, size_t width, char fill=' ')
Fill string with characters to the left until the given width is reached.
Definition: stringfunctions.cc:47
smash::sha256::Context
A SHA256 context.
Definition: sha256.h:28
smash::ParticleType::mass
double mass() const
Definition: particletype.h:144
smash::Configuration::has_value
bool has_value(std::initializer_list< const char * > keys) const
Returns whether there is a non-empty value behind the requested keys.
Definition: configuration.cc:181
smash::FileLock
Guard to create a file lock.
Definition: filelock.h:30
smash::random::generate_63bit_seed
int64_t generate_63bit_seed()
Generates a seed with a truly random 63-bit value, if possible.
Definition: random.cc:18
smash::LMain
static constexpr int LMain
Definition: experiment.h:85
smash::set_default_loglevel
void set_default_loglevel(einhard::LogLevel level)
Set the default log level (what will be returned from subsequent default_loglevel calls).
Definition: logging.cc:24
smash::logg
std::array< einhard::Logger<>, std::tuple_size< LogArea::AreaTuple >::value > logg
An array that stores all pre-configured Logger objects.
Definition: logging.cc:39
smash::create_all_loggers
void create_all_loggers(Configuration config)
Called from main() right after the Configuration object is fully set up to create all logger objects ...
Definition: logging.cc:118
smash::ParticleType::find
static const ParticleType & find(PdgCode pdgcode)
Returns the ParticleType object for the given pdgcode.
Definition: particletype.cc:99
smash::anonymous_namespace{smash.cc}::check_config_version_is_compatible
void check_config_version_is_compatible(Configuration configuration)
Checks if the SMASH version is compatible with the version of the configuration file.
Definition: smash.cc:329
smash::Configuration
Interface to the SMASH configuration files.
Definition: configuration.h:464
smash::ParticleTypePtr
Definition: particletype.h:665
smash::load_particles_and_decaymodes
std::pair< std::string, std::string > load_particles_and_decaymodes(const char *particles_file, const char *decaymodes_file)
Loads particles and decaymodes from provided files particles_file and decaymodes_file.
Definition: setup_particles_decaymodes.cc:31
smash::ParticleType::is_stable
bool is_stable() const
Definition: particletype.h:239
smash::anonymous_namespace{smash.cc}::ignore_simulation_config_values
void ignore_simulation_config_values(Configuration &configuration)
Remove all config values that are only needed for simulations.
Definition: smash.cc:368
smash::ParticleType
Definition: particletype.h:97
smash::ParticleType::name
const std::string & name() const
Definition: particletype.h:141
smash::setup_default_float_traps
void setup_default_float_traps()
Setup the floating-point traps used throughout SMASH.
Definition: fpenvironment.cc:69
einhard::ALL
@ ALL
Log all message.
Definition: einhard.hpp:106
smash::PdgCode
Definition: pdgcode.h:108
smash::anonymous_namespace{smash.cc}::initialize_particles_and_decays
void initialize_particles_and_decays(Configuration &configuration, sha256::Hash hash, bf::path tabulations_path)
Initialize the particles and decays from the configuration, the hash and the path to the cashed reson...
Definition: smash.cc:388
smash::Configuration::merge_yaml
void merge_yaml(const std::string &yaml)
Merge the configuration in yaml into the existing tree.
Definition: configuration.cc:118
smash::sha256::hash_to_string
std::string hash_to_string(Hash hash)
Convert a SHA256 hash to a hexadecimal string.
Definition: sha256.cc:230
smash::Configuration::take
Value take(std::initializer_list< const char * > keys)
The default interface for SMASH to read configuration values.
Definition: configuration.cc:140
smash::anonymous_namespace{smash.cc}::ensure_path_is_valid
void ensure_path_is_valid(const bf::path &path)
Ensures the output path is valid.
Definition: smash.cc:287
SMASH_SOURCE_LOCATION
#define SMASH_SOURCE_LOCATION
Hackery that is required to output the location in the source code where the log statement occurs.
Definition: logging.h:243
smash::Test::experiment
std::unique_ptr< ExperimentBase > experiment(const Configuration &c=configuration())
Create an experiment.
Definition: setup.h:176
smash::ExperimentBase::create
static std::unique_ptr< ExperimentBase > create(Configuration config, const bf::path &output_path)
Factory method that creates and initializes a new Experiment<Modus>.
smash::anonymous_namespace{smash.cc}::default_output_path
bf::path default_output_path()
Definition: smash.cc:263
smash::ParticleType::list_all
static const ParticleTypeList & list_all()
Definition: particletype.cc:51
smash::anonymous_namespace{smash.cc}::actions_finder_for_dump
ScatterActionsFinder actions_finder_for_dump(Configuration configuration)
Prepares ActionsFinder for cross-section and reaction dumps.
Definition: smash.cc:309
smash::sha256::Context::finalize
Hash finalize()
Performs the final calculation of the hash and returns the digest (32 byte buffer containing 256bit h...
Definition: sha256.cc:185
smash::anonymous_namespace{smash.cc}::print_disclaimer
void print_disclaimer()
Print the disclaimer.
Definition: smash.cc:177