CASM  1.1.0
A Clusters Approach to Statistical Mechanics
run.cc
Go to the documentation of this file.
1 #include <unistd.h>
2 
3 #include <cstring>
4 
12 #include "casm/system/Popen.hh"
13 
14 namespace CASM {
15 
16 namespace Completer {
17 
19 
23 
24  m_desc.add_options()("exec,e",
25  po::value<std::string>(&m_exec_str)
26  ->required()
27  ->value_name(ArgHandler::command()),
28  "Command to execute");
29  return;
30 }
31 
32 const std::string &RunOption::exec_str() const { return m_exec_str; };
33 
34 } // namespace Completer
35 
36 // ///////////////////////////////////////
37 // 'run' function for casm
38 // (add an 'if-else' statement in casm.cpp to call this)
39 
40 int run_command(const CommandArgs &args) {
41  std::string exec;
42  fs::path selection;
43  po::variables_map vm;
44 
46  Completer::RunOption run_opt;
47 
48  try {
49  po::store(po::parse_command_line(args.argc(), args.argv(), run_opt.desc()),
50  vm); // can throw
51 
54  if (vm.count("help")) {
55  log() << "\n";
56  log() << run_opt.desc() << std::endl;
57 
58  return 0;
59  }
60 
61  if (vm.count("desc")) {
62  log() << "\n";
63  log() << run_opt.desc() << std::endl;
64  log() << "DESCRIPTION\n"
65  << " Executes the requested command for each selected "
66  "configuration,\n"
67  << " with the path to the configuration as an argument. "
68  " \n\n"
69  << " Example: casm run --exec \"vasp.relax\"\n"
70  << " - calls:\n"
71  << " 'vasp.relax $ROOT/training_data/$SCELNAME/$CONFIGID'\n"
72  << " for each config selected in config_list\n\n";
73 
74  return 0;
75  }
76 
77  po::notify(vm); // throws on error, so do after help in case
78  // there are any problems
79 
80  selection = run_opt.selection_path();
81  } catch (po::error &e) {
82  err_log() << "ERROR: " << e.what() << std::endl << std::endl;
83  err_log() << run_opt.desc() << std::endl;
84  return 1;
85  } catch (std::exception &e) {
86  err_log() << "ERROR: " << e.what() << ".\n Exiting..." << std::endl;
87  return 1;
88  }
89 
90  const fs::path &root = args.root;
91  if (root.empty()) {
92  err_log().error("No casm project found");
93  err_log() << std::endl;
94  return ERR_NO_PROJ;
95  }
96 
97  // If 'args.primclex', use that, else construct PrimClex in 'uniq_primclex'
98  // Then whichever exists, store reference in 'primclex'
99  std::unique_ptr<PrimClex> uniq_primclex;
100  PrimClex &primclex = make_primclex_if_not(args, uniq_primclex);
101 
102  try {
103  if (!vm.count("config") || (selection == "MASTER")) {
104  selection = "MASTER";
105  } else if (vm.count("config") && !fs::exists(selection)) {
106  std::cerr << "ERROR: Invalid input. Option '--config' accepts one "
107  "argument (either 'MASTER' or a path to a valid "
108  "configuration selection file)."
109  << std::endl
110  << " Exiting...\n";
111  return 1;
112  }
113 
115  selection);
116  for (const auto &config : config_select.selected()) {
119 
120  Popen process;
121 
122  process.popen(run_opt.exec_str() + " " +
123  primclex.dir().configuration_dir(config.name()).string());
124 
125  process.print(log());
126  }
127  } catch (std::exception &e) {
128  err_log() << "ERROR: Invalid input. Option '--config' accepts one argument "
129  "(either 'MASTER' or a path to a valid configuration "
130  "selection file)."
131  << std::endl
132  << " Exiting...\n";
133  return 1;
134  }
135 
136  log() << "\n***************************\n" << std::endl;
137 
138  log() << std::endl;
139 
140  return 0;
141 };
142 
143 } // namespace CASM
#define ERR_NO_PROJ
Definition: errors.hh:13
int argc() const
Definition: CLIParse.hh:20
char ** argv() const
Definition: CLIParse.hh:22
static std::string command()
Get value_type string for command completion (i.e. stuff in your $PATH)
Definition: Handlers.cc:58
const po::options_description & desc()
Get the program options, filled with the initialized values.
Definition: Handlers.cc:321
void add_help_suboption()
Add a plain –help and –desc suboptions.
Definition: Handlers.cc:561
po::options_description m_desc
Definition: Handlers.hh:260
void add_configlist_suboption(const fs::path &_default="MASTER")
Add –config suboption (defaults to MASTER)
Definition: Handlers.cc:431
void initialize() override
Fill in the options descriptions accordingly.
Definition: run.cc:20
const std::string & exec_str() const
Definition: run.cc:32
const fs::path & selection_path() const
Returns the string corresponding to add_config_suboption()
Definition: Handlers.cc:338
boost::iterator_range< iterator > selected()
Definition: Selection.cc:237
fs::path configuration_dir(std::string configname) const
Return configuration directory path.
void error(const std::string &what)
Definition: Log.hh:129
Remember how to use popen.
Definition: Popen.hh:13
void popen(std::string _command)
Execute popen for a given command.
Definition: Popen.cc:19
void print(std::ostream &sout) const
Print the last command executed and the resulting stdout.
Definition: Popen.cc:46
PrimClex is the top-level data structure for a CASM project.
Definition: PrimClex.hh:55
PrimClex & make_primclex_if_not(const CommandArgs &args, std::unique_ptr< PrimClex > &uniq_primclex)
If !_primclex, construct new PrimClex stored in uniq_primclex, then return reference to existing or c...
DB::Database< T > & db() const
Definition: PrimClex.cc:302
const DirectoryStructure & dir() const
Access DirectoryStructure object. Throw if not set.
Definition: PrimClex.cc:230
ConfigIO::GenericConfigFormatter< jsonParser > config()
Definition: ConfigIO.cc:777
Main CASM namespace.
Definition: APICommand.hh:8
void write_config_json(Configuration const &configuration, DirectoryStructure const &dir)
Definition: clex_io.cc:49
Log & log()
Definition: Log.hh:424
void write_pos(Configuration const &configuration, DirectoryStructure const &dir)
Write configuration "POS" file (VASP POSCAR) to standard location.
Definition: clex_io.cc:29
int run_command(const CommandArgs &args)
Definition: run.cc:40
Log & err_log()
Definition: Log.hh:426
PrimClex * primclex
Definition: settings.cc:135
Data structure holding basic CASM command info.