407 using namespace smash;
409 constexpr option longopts[] = {
410 {
"config", required_argument, 0,
'c'},
411 {
"decaymodes", required_argument, 0,
'd'},
412 {
"endtime", required_argument, 0,
'e'},
413 {
"force", no_argument, 0,
'f'},
414 {
"help", no_argument, 0,
'h'},
415 {
"inputfile", required_argument, 0,
'i'},
416 {
"modus", required_argument, 0,
'm'},
417 {
"particles", required_argument, 0,
'p'},
418 {
"output", required_argument, 0,
'o'},
419 {
"list-2-to-n", no_argument, 0,
'l'},
420 {
"resonance", required_argument, 0,
'r'},
421 {
"cross-sections", required_argument, 0,
's'},
422 {
"cross-sections-fs", required_argument, 0,
'S'},
423 {
"dump-iSS", no_argument, 0,
'x'},
424 {
"version", no_argument, 0,
'v'},
425 {
"no-cache", no_argument, 0,
'n'},
429 const std::string progname = bf::path(argv[0]).filename().native();
432 bool force_overwrite =
false;
434 std::vector<std::string> extra_config;
435 char *particles =
nullptr, *decaymodes =
nullptr, *modus =
nullptr,
436 *end_time =
nullptr, *pdg_string =
nullptr, *cs_string =
nullptr;
437 bool list2n_activated =
false;
438 bool resonance_dump_activated =
false;
439 bool cross_section_dump_activated =
false;
440 bool final_state_cross_sections =
false;
441 bool particles_dump_iSS_format =
false;
442 bool cache_integrals =
true;
446 bool suppress_disclaimer =
false;
447 while ((opt = getopt_long(argc, argv,
"c:d:e:fhi:m:p:o:lr:s:S:xvn",
448 longopts,
nullptr)) != -1) {
451 extra_config.emplace_back(optarg);
457 force_overwrite =
true;
463 usage(EXIT_SUCCESS, progname);
475 output_path = optarg;
478 list2n_activated =
true;
479 suppress_disclaimer =
true;
482 resonance_dump_activated =
true;
484 suppress_disclaimer =
true;
487 final_state_cross_sections =
true;
490 cross_section_dump_activated =
true;
492 suppress_disclaimer =
true;
495 particles_dump_iSS_format =
true;
496 suppress_disclaimer =
true;
501 "Branch : %s\nSystem : %s\nCompiler : %s %s\n"
502 "Build : %s\nDate : %s\n",
503 VERSION_MAJOR, GIT_BRANCH, CMAKE_SYSTEM, CMAKE_CXX_COMPILER_ID,
504 CMAKE_CXX_COMPILER_VERSION, CMAKE_BUILD_TYPE, BUILD_DATE);
505 std::exit(EXIT_SUCCESS);
507 cache_integrals =
false;
510 usage(EXIT_FAILURE, progname);
516 std::cout << argv[0] <<
": invalid argument -- '" << argv[optind]
518 usage(EXIT_FAILURE, progname);
521 if (!suppress_disclaimer) {
529 input_path.filename());
531 for (
const auto &config : extra_config) {
545 auto particles_and_decays =
552 "Ambiguity: particles from external file ", particles,
553 " requested, but there is also particle list in the config."
554 " Using particles from ",
563 "Ambiguity: decaymodes from external file ", decaymodes,
564 " requested, but there is also decaymodes list in the config."
565 " Using decaymodes from",
573 const std::string version(VERSION_MAJOR);
577 hash_context.
update(version);
578 hash_context.
update(particle_string);
579 hash_context.
update(decay_string);
580 const auto hash = hash_context.
finalize();
583 bf::path tabulations_path;
584 if (cache_integrals) {
585 tabulations_path = output_path.parent_path() /
"tabulations";
586 bf::create_directories(tabulations_path);
587 logg[
LMain].info() <<
"Tabulations path: " << tabulations_path;
589 tabulations_path =
"";
591 if (list2n_activated) {
595 logg[
LMain].info() <<
"Tabulations path: " << tabulations_path;
602 scat_finder.dump_reactions();
603 std::exit(EXIT_SUCCESS);
605 if (particles_dump_iSS_format) {
607 ParticleTypePtrList list;
610 list.push_back(&ptype);
612 std::sort(list.begin(), list.end(),
614 return a->
mass() < b->mass();
617 if (ptype->pdgcode().is_lepton() || ptype->baryon_number() < 0) {
620 const auto &decay_modes = ptype->decay_modes();
621 const auto &modelist = decay_modes.decay_mode_list();
622 int ndecays = ptype->is_stable() ? 1 : modelist.size();
623 printf(
"%13i %s %10.5f %10.5f %5i %5i %5i %5i %5i %5i %5i %5i\n",
624 ptype->pdgcode().get_decimal(),
626 ptype->mass(), ptype->width_at_pole(),
627 ptype->pdgcode().spin_degeneracy(), ptype->baryon_number(),
628 ptype->strangeness(), ptype->pdgcode().charmness(),
629 ptype->pdgcode().bottomness(), ptype->isospin() + 1,
630 ptype->charge(), ndecays);
631 if (!ptype->is_stable()) {
632 for (
const auto &decay : modelist) {
633 auto ptypes = decay->particle_types();
634 printf(
"%13i %13i %20.5f %13i %13i %13i %13i %13i\n",
635 ptype->pdgcode().get_decimal(), 2, decay->weight(),
636 ptypes[0]->pdgcode().get_decimal(),
637 ptypes[1]->pdgcode().get_decimal(), 0, 0, 0);
640 printf(
"%13i %13i %20.5f %13i %13i %13i %13i %13i\n",
641 ptype->pdgcode().get_decimal(), 1, 1.0,
642 ptype->pdgcode().get_decimal(), 0, 0, 0, 0);
645 std::exit(EXIT_SUCCESS);
647 if (resonance_dump_activated) {
657 std::exit(EXIT_SUCCESS);
659 if (cross_section_dump_activated) {
661 std::string arg_string(cs_string);
662 std::vector<std::string> args =
split(arg_string,
',');
663 const unsigned int n_arg = args.size();
664 if (n_arg != 2 && n_arg != 4 && n_arg < 5) {
665 throw std::invalid_argument(
"-s usage: pdg1,pdg2[,m1,m2[,sqrts1,...]]");
667 PdgCode pdg_a(args[0]), pdg_b(args[1]);
671 for (
unsigned int i = 0; i < 4 - n_arg; i++) {
675 double ma = (args[2] ==
"") ? a.
mass() : std::stod(args[2]);
676 double mb = (args[3] ==
"") ? b.
mass() : std::stod(args[3]);
677 if (a.
is_stable() && args[2] !=
"" && std::stod(args[2]) != a.
mass()) {
679 std::cerr <<
"Warning: pole mass is used for stable particle "
680 << a.
name() <<
" instead of " << args[2] << std::endl;
682 if (b.
is_stable() && args[3] !=
"" && std::stod(args[3]) != b.
mass()) {
684 std::cerr <<
"Warning: pole mass is used for stable particle "
685 << b.
name() <<
" instead of " << args[3] << std::endl;
687 const size_t plab_size = n_arg <= 4 ? 0 : n_arg - 4;
688 std::vector<double> plab;
689 plab.reserve(plab_size);
690 for (
size_t i = 4; i < n_arg; i++) {
691 plab.push_back(std::stod(args.at(i)));
698 scat_finder.dump_cross_sections(a, b, ma, mb, final_state_cross_sections,
700 std::exit(EXIT_SUCCESS);
706 configuration[
"General"][
"End_Time"] = std::abs(std::atof(end_time));
716 const bf::path lock_path = output_path /
"smash.lock";
718 if (!lock.acquire()) {
719 throw std::runtime_error(
720 "Another instance of SMASH is already writing to the specified "
721 "output directory. If you are sure this is not the case, remove \"" +
722 lock_path.native() +
"\".");
724 logg[
LMain].debug(
"output path: ", output_path);
725 if (!force_overwrite && bf::exists(output_path /
"config.yaml")) {
726 throw std::runtime_error(
727 "Output directory would get overwritten. Select a different output "
728 "directory, clean up, or tell SMASH to ignore existing files.");
733 bf::ofstream(output_path /
"config.yaml")
734 <<
"# " << VERSION_MAJOR <<
'\n'
735 <<
"# Branch : " << GIT_BRANCH <<
'\n'
736 <<
"# System : " << CMAKE_SYSTEM <<
'\n'
737 <<
"# Compiler : " << CMAKE_CXX_COMPILER_ID <<
' '
738 << CMAKE_CXX_COMPILER_VERSION <<
'\n'
739 <<
"# Build : " << CMAKE_BUILD_TYPE <<
'\n'
740 <<
"# Date : " << BUILD_DATE <<
'\n'
757 }
catch (std::exception &e) {
758 logg[
LMain].fatal() <<
"SMASH failed with the following error:\n"