CASM  1.1.0
A Clusters Approach to Statistical Mechanics
settings.cc
Go to the documentation of this file.
1 #include <boost/filesystem.hpp>
2 #include <functional>
3 
7 #include "casm/casm_io/Log.hh"
8 #include "casm/clex/PrimClex.hh"
10 #include "casm/misc/algorithm.hh"
11 
12 namespace CASM {
13 
14 struct ClexDescription;
15 bool clex_exists(const DirectoryStructure &dir, const ClexDescription &desc);
16 
17 namespace {
18 std::string _wdefaultval(std::string name,
19  std::pair<std::string, std::string> val) {
20  return name + ": '" + val.first + "' (" + val.second + ")\n";
21 }
22 
23 std::string _wdefaultval(std::string name,
24  std::pair<fs::path, std::string> val) {
25  return _wdefaultval(name, std::make_pair(val.first.string(), val.second));
26 }
27 } // namespace
28 
29 namespace Completer {
31 
32 const std::string &SettingsOption::input_str() const { return m_input_str; }
33 
34 const std::vector<std::string> &SettingsOption::input_vec() const {
35  return m_input_vec;
36 }
37 
40 
41  m_desc.add_options()("list,l", "List project settings")(
42  "new-property", po::value<std::string>(&m_input_str),
43  "Create cluster expansions for a new property")(
44  "new-bset", po::value<std::string>(&m_input_str),
45  "Create a new basis set")("new-calctype",
46  po::value<std::string>(&m_input_str),
47  "Create a new calculation type")(
48  "new-ref", po::value<std::string>(&m_input_str),
49  "Create a new calculation reference")(
50  "new-eci", po::value<std::string>(&m_input_str),
51  "Create a new set of effective cluster interactions (ECI)")(
52  "set-formation-energy", po::value<std::string>(&m_input_str),
53  "Specify the cluster expansion to use for formation energy")(
54  "new-clex", po::value<std::string>(&m_input_str),
55  "Create a new cluster expansion")(
56  "set-default-clex",
57  po::value<std::string>(&m_input_str)->value_name(ArgHandler::clex()),
58  "Set the cluster expansion that CASM uses or acts on by default")(
59  "erase-clex",
60  po::value<std::string>(&m_input_str)->value_name(ArgHandler::clex()),
61  "Erase the specified cluster expansion. Does not erase underlying bset, "
62  "eci, etc.")("clex",
63  po::value<std::string>()->value_name(ArgHandler::clex()),
64  "The cluster expansion for which to set property, bset, "
65  "calctype, ref, or eci")(
66  "set-property",
67  po::value<std::string>(&m_input_str)->value_name(ArgHandler::property()),
68  "Set the property being cluster expanded")(
69  "set-bset",
70  po::value<std::string>(&m_input_str)->value_name(ArgHandler::bset()),
71  "Set the basis set")(
72  "set-calctype",
73  po::value<std::string>(&m_input_str)->value_name(ArgHandler::calctype()),
74  "Set the calculation type")(
75  "set-ref",
76  po::value<std::string>(&m_input_str)->value_name(ArgHandler::ref()),
77  "Set the calculation reference")(
78  "set-eci",
79  po::value<std::string>(&m_input_str)->value_name(ArgHandler::eci()),
80  "Set the effective cluster interactions (ECI)")(
81  "set-all",
82  po::value<std::vector<std::string> >(&m_input_vec)->multitoken(),
83  "Set the current property, calctype, ref, bset, and eci all at once.")(
84  "set-view-command", po::value<std::string>(&m_input_str),
85  "Set the command used by 'casm view'.")(
86  "set-view-command-video", po::value<std::string>(&m_input_str),
87  "Set the command used by 'casm view' for videos.")(
88  "set-cxx", po::value<std::string>(&m_input_str),
89  "Set the c++ compiler. Use '' to revert to default.")(
90  "set-cxxflags", po::value<std::string>(&m_input_str),
91  "Set the c++ compiler options. Use '' to revert to default.")(
92  "set-soflags", po::value<std::string>(&m_input_str),
93  "Set the shared library compilation options. Use '' to revert to "
94  "default.")("set-casm-prefix", po::value<std::string>(&m_input_str),
95  "Set the casm prefix. Use '' to revert to default.")(
96  "set-casm-includedir", po::value<std::string>(&m_input_str),
97  "Set the casm includedir. Use '' to revert to default.")(
98  "set-casm-libdir", po::value<std::string>(&m_input_str),
99  "Set the casm libdir. Use '' to revert to default.")(
100  "set-boost-prefix", po::value<std::string>(&m_input_str),
101  "Set the boost prefix. Use '' to revert to default.")(
102  "set-boost-includedir", po::value<std::string>(&m_input_str),
103  "Set the boost includedir. Use '' to revert to default.")(
104  "set-boost-libdir", po::value<std::string>(&m_input_str),
105  "Set the boost libdir. Use '' to revert to default.");
106  return;
107 }
108 
109 } // namespace Completer
110 
111 namespace {
112 
115 enum create_mode { create, do_not_create };
116 
118 struct Data {
119  typedef std::pair<std::string, create_mode> pair_type;
120 
121  Data(PrimClex *_primclex, DirectoryStructure const &_dir,
122  ProjectSettings &_set, ClexDescription &_desc)
123  : primclex(_primclex),
124  dir(_dir),
125  set(_set),
126  desc(_desc),
127  log(CASM::log()),
128  err_log(CASM::err_log()),
129  property(pair_type(desc.property, do_not_create)),
130  calctype(pair_type(desc.calctype, do_not_create)),
131  ref(pair_type(desc.ref, do_not_create)),
132  bset(pair_type(desc.bset, do_not_create)),
133  eci(pair_type(desc.eci, do_not_create)) {}
134 
135  PrimClex *primclex;
136  DirectoryStructure const &dir;
137  ProjectSettings &set;
138  ClexDescription &desc;
139  Log &log;
140  Log &err_log;
141 
142  pair_type property;
143  pair_type calctype;
144  pair_type ref;
145  pair_type bset;
146  pair_type eci;
147 
148  int update() {
149  // the resulting clex if successful
150  ClexDescription tdesc(desc.name, property.first, calctype.first, ref.first,
151  bset.first, eci.first);
152 
153  bool res =
154  try_new(
155  "property", property,
156  [&]() { return contains(dir.all_property(), tdesc.property); },
157  [&]() { return dir.new_clex_dir(tdesc.property); }) &&
158  try_new(
159  "calctype", calctype,
160  [&]() { return contains(dir.all_calctype(), tdesc.calctype); },
161  [&]() { return dir.new_calc_settings_dir(tdesc.calctype); }) &&
162  try_new(
163  "ref", ref,
164  [&]() { return contains(dir.all_ref(tdesc.calctype), tdesc.ref); },
165  [&]() { return dir.new_ref_dir(tdesc.calctype, tdesc.ref); }) &&
166  try_new(
167  "bset", bset,
168  [&]() { return contains(dir.all_bset(), tdesc.bset); },
169  [&]() { return dir.new_bset_dir(tdesc.bset); }) &&
170  try_new(
171  "eci", eci,
172  [&]() {
173  return contains(dir.all_eci(tdesc.property, tdesc.calctype,
174  tdesc.ref, tdesc.bset),
175  tdesc.eci);
176  },
177  [&]() {
178  return dir.new_eci_dir(tdesc.property, tdesc.calctype, tdesc.ref,
179  tdesc.bset, tdesc.eci);
180  });
181 
182  // If could not create settings directories
183  if (!res) {
184  return 1;
185  }
186 
187  if (clex_exists(dir, tdesc) && set.set_default_clex(tdesc)) {
188  commit(set);
189 
190  bool read_settings = true;
191  bool read_composition = false;
192 
193  bool read_chem_ref = false;
194  bool read_configs = false;
195  if ((desc.property != tdesc.property) ||
196  (desc.calctype != tdesc.calctype) || (desc.ref != tdesc.ref)) {
197  read_chem_ref = true;
198  read_configs = true;
199  }
200 
201  bool clear_clex = false;
202  if ((desc.property != tdesc.property) || (desc.bset != tdesc.bset) ||
203  (desc.eci != tdesc.eci)) {
204  clear_clex = true;
205  }
206 
207  desc = tdesc;
208  log << "Updated default settings:\n";
209  bool is_default = true;
210  int indent = 0;
211  desc.print(log, is_default, indent);
212 
213  if (primclex) {
214  primclex->refresh(read_settings, read_composition, read_chem_ref,
215  read_configs, clear_clex);
216  }
217  return 0;
218  } else {
219  err_log << "Unknown error: Could not switch settings." << std::endl;
220  err_log << "Tried to switch to:\n";
221  tdesc.print(err_log, false, 0);
222  return 1;
223  }
224  }
225 
241  bool try_new(std::string set_name, pair_type set,
242  std::function<bool()> check_f, std::function<bool()> new_f) {
243  create_mode _cmode = set.second;
244 
245  if (_cmode == create && check_f()) {
246  return true;
247  }
248  if (_cmode == create && !check_f()) {
249  bool res = new_f();
250  if (res) {
251  log << "Created new " << set_name << ": '" << set.first << "'\n";
252 
253  } else {
254  err_log << "Could not create new " << set_name << ": '" << set.first
255  << "'\n";
256  }
257  return res;
258  }
259 
260  if (_cmode == do_not_create && !check_f()) {
261  err_log << "Error: The " << set_name << " named '" << set.first
262  << "' does not exist.\n";
263  err_log << " Check your input or use --new-" << set_name
264  << " to create it first.\n";
265 
266  return false;
267  }
268 
269  if (_cmode == do_not_create && check_f()) {
270  return true;
271  }
272 
273  // shouldn't be able to get here
274  throw std::runtime_error("Unknown error updating CASM settings");
275  }
276 };
277 } // namespace
278 
279 // ///////////////////////////////////////
280 // 'settings' function for casm
281 // (add an 'if-else' statement in casm.cpp to call this)
282 
283 int settings_command(const CommandArgs &args) {
284  std::string single_input;
285  std::vector<std::string> multi_input;
286  po::variables_map vm;
287 
288  try {
290  Completer::SettingsOption settings_opt;
291  const po::options_description &desc =
292  settings_opt.desc(); // I'm tired of fixing merge conflicts, this is
293  // ugly and should not stay like this.
294 
295  try {
296  po::store(po::parse_command_line(args.argc(), args.argv(), desc),
297  vm); // can throw
298 
299  bool call_help = false;
300 
301  std::vector<std::string> all_opt = {"list",
302  "desc",
303  "new-property",
304  "new-bset",
305  "new-calctype",
306  "new-ref",
307  "new-eci",
308  "new-clex",
309  "set-formation-energy",
310  "erase-clex",
311  "set-default-clex",
312  "set-property",
313  "set-bset",
314  "set-calctype",
315  "set-ref",
316  "set-eci",
317  "set-all",
318  "set-cxx",
319  "set-cxxflags",
320  "set-soflags",
321  "set-casm-prefix",
322  "set-casm-includedir",
323  "set-casm-libdir",
324  "set-boost-prefix",
325  "set-boost-includedir",
326  "set-boost-libdir",
327  "set-view-command",
328  "set-view-command-video"};
329  int option_count = 0;
330  for (int i = 0; i < all_opt.size(); i++) {
331  option_count += vm.count(all_opt[i]);
332  }
333 
334  // must call one and only one option at a time:
335  if (!vm.count("help")) {
336  if (option_count == 0) {
337  log() << "Error in 'casm settings'. No option selected." << std::endl;
338  call_help = true;
339  } else if (option_count > 1) {
340  log() << "Error in 'casm settings'. Use one option (other than "
341  "--clex) at a time."
342  << std::endl;
343  call_help = true;
344  }
345  }
346 
347  // --help option
348  if (vm.count("help") || call_help) {
349  log() << "\n";
350  log() << desc << std::endl;
351 
352  return 0;
353  }
354 
355  if (vm.count("desc")) {
356  log() << "\n";
357  log() << desc << std::endl;
358  log() << "DESCRIPTION" << std::endl;
359  log() << "\n";
360  log()
361  << " Often it is useful to try multiple different basis sets, \n"
362  << " calculation settings, references, or ECI fits in a single\n"
363  << " project. The 'casm settings' option helps to organize \n"
364  << " these within a project and quickly switch between \n"
365  << " different settings. "
366  "\n";
367  log() << "\n";
368  log() << " Examples:\n";
369  log()
370  << " \n"
371  << " casm settings --list \n"
372  << " - List all settings, with '*' for current settings "
373  "\n\n"
374  <<
375 
376  " casm settings --new-clex 'my_newclex' \n"
377  << " casm settings --set-default-clex 'other_clex' \n"
378  << " - Creates a new group of settings for a cluster \n"
379  << " expansion \n"
380  << " - Includes property, calctype, ref, bset, and eci \n"
381  << " - Can be used in Monte Carlo input files, and as \n"
382  << " arguments to 'casm select' and 'casm query' \n"
383  << " properties such as 'clex' and 'corr' to specify which\n"
384  << " basis functions and eci to use. "
385  "\n\n"
386  <<
387 
388  " casm settings --set-formation-energy 'other_clex' \n"
389  << " - The cluster expansion 'other_clex' is copied to one \n"
390  << " named 'formation_energy' which is used as the default\n"
391  << " for grand canoncial Monte Carlo calculations and \n"
392  << " cluster expansion convex hull calculations. "
393  "\n\n"
394  <<
395 
396  " casm settings --new-property 'my_new_property' \n"
397  << " casm settings --new-bset 'my_new_bset' \n"
398  << " casm settings --new-calctype 'my_new_calctype' \n"
399  << " casm settings --new-ref 'my_new_ref' \n"
400  << " casm settings --new-eci 'my_new_eci' \n"
401  << " - Creates new settings directories with appropriate \n"
402  << " names \n"
403  << " - For --new-property, new 'default' calctype, ref, and \n"
404  << " eci are created. \n"
405  << " - For --new-calctype, a new 'default' ref is created. \n"
406  << " - For --new-ref, a new reference is created for the \n"
407  << " current calctype \n"
408  << " - For --new-eci, a new eci directory is created for the\n"
409  << " current clex, calctype and ref. "
410  "\n\n"
411  <<
412 
413  " casm settings --set-property 'other_property' \n"
414  << " casm settings --set-bset 'other_bset' \n"
415  << " casm settings --set-calctype 'other_calctype' \n"
416  << " casm settings --set-ref 'other_ref' \n"
417  << " casm settings --set-eci 'other_eci' \n"
418  << " casm settings --set-all 'property' 'calctype', 'ref', "
419  "'bset', 'eci'\n"
420  << " - Switch the current settings \n"
421  << " - For --set-property, standard options are: \n"
422  << " - 'formation_energy' (the only standard option for "
423  "now)\n"
424  << " After switching, the 'default' calctype, ref, bset, \n"
425  << " and eci are used"
426  " - For --set-calctype, the current property and bset are\n"
427  << " maintained, and the 'default' ref, and eci are used. \n"
428  << " - For --set-ref, the current property, calctype, and \n"
429  << " bset are maintained, and the 'default' eci is used. \n"
430  << " - For --set-bset, the current property, calctype, and \n"
431  << " ref are maintained, and the 'default' eci is used. \n"
432  << " - For --set-eci, the current property, calctype, ref, \n"
433  << " and bset are maintained. \n"
434  << " - For --set-all, all settings are switched at once. "
435  "\n\n"
436  <<
437 
438  " casm settings --set-cxx 'cxx' \n"
439  << " - Specifies compiler to use. In order of priority: \n"
440  " 1) User specified by 'casm settings --set-cxx' \n"
441  " (use '' to clear) \n"
442  " 2) $CASM_CXX \n"
443  " 3) $CXX \n"
444  " 4) \"g++\" \n\n"
445 
446  " casm settings --set-cxxflags 'cxxflags' \n"
447  " - Specifies compiler options. In order of priority: \n"
448  " 1) User specified by 'casm settings --set-cxxflags' \n"
449  " (use '' to clear) \n"
450  " 2) $CASM_CXXFLAGS \n"
451  " 3) \"-O3 -Wall -fPIC --std=c++17\" \n\n"
452 
453  " casm settings --set-soflags 'soflags' \n"
454  " - Specifies shared object construction flags. In order \n"
455  " of priority: \n"
456  " 1) User specified by 'casm settings --set-soflags' \n"
457  " (use '' to clear) \n"
458  " 2) $CASM_SOFLAGS \n"
459  " 3) \"-shared -lboost_system\" \n\n"
460 
461  " casm settings --set-casm-prefix 'casm_prefix' \n"
462  " casm settings --set-casm-includedir 'casm_includedir' \n"
463  " casm settings --set-casm-libdir 'casm_libdir' \n"
464  " - Specifies location to find CASM header files and "
465  "shared\n"
466  " libraries for runtime compilation and linking. "
467  "\n"
468  " In order of priority: \n"
469  " 1) User specified by via 'casm settings' (use '' to "
470  "clear) \n"
471  " 2) $CASM_INCLUDEDIR and $CASM_LIBDIR \n"
472  " 3) $CASM_PREFIX/include and $CASM_PREFIX/lib \n"
473  " 4) (default search paths) \n\n"
474 
475  " casm settings --set-boost-prefix 'boost_prefix' \n"
476  " casm settings --set-boost-includedir 'boost_includedir' "
477  "\n"
478  " casm settings --set-boost-libdir 'boost_libdir' \n"
479  " - Specifies location to find boost header files and "
480  "shared\n"
481  " libraries for runtime compilation and linking. "
482  "\n"
483  " In order of priority: \n"
484  " 1) User specified by via 'casm settings' (use '' to "
485  "clear) \n"
486  " 2) $CASM_BOOST_INCLUDEDIR and $CASM_BOOST_LIBDIR \n"
487  " 3) $CASM_BOOST_PREFIX/include and "
488  "$CASM_BOOST_PREFIX/lib \n"
489  " 4) (default search paths) \n\n"
490  " casm settings --set-view-command 'casm.view \"open -a "
491  "/Applications/VESTA/VESTA.app\"'\n"
492  << " - Sets the command used by 'casm view' to open \n"
493  << " visualization software. \n"
494  << " - Will be executed with '/path/to/POSCAR' as an \n"
495  << " argument, the location of a POSCAR for a "
496  "configuration\n"
497  << " selected for visualization. \n"
498  << " casm settings --set-view-command-video 'casm.view \"open "
499  "-a /Applications/Ovito/ovito.app\"'\n"
500  << " - Sets the command used by 'casm view' to open \n"
501  << " visualization software. \n"
502  << " - Will be executed with '/path/to/POSCAR' as an \n"
503  << " argument, the location of a POSCAR for a "
504  "diff_trans_config\n"
505  << " selected for visualization. \n"
506  << "\n";
507 
508  if (call_help) return 1;
509 
510  return 0;
511  }
512 
513  po::notify(vm); // throws on error, so do after help in case
514  // there are any problems
515 
516  single_input = settings_opt.input_str();
517  multi_input = settings_opt.input_vec();
518 
519  } catch (po::error &e) {
520  err_log() << "ERROR: " << e.what() << std::endl << std::endl;
521  err_log() << desc << std::endl;
522  return 1;
523  }
524  } catch (std::exception &e) {
525  err_log() << "Unhandled Exception reached the top of main: " << e.what()
526  << ", application will now exit" << std::endl;
527  return 1;
528  }
529 
530  const fs::path &root = args.root;
531  if (root.empty()) {
532  err_log().error("No casm project found");
533  err_log() << "current_path: " << fs::current_path() << std::endl;
534  err_log() << std::endl;
535  return ERR_NO_PROJ;
536  }
537 
539  DirectoryStructure const &dir = set.dir();
540  ClexDescription clex_desc = set.default_clex();
541 
542  if (vm.count("clex")) {
543  auto it = set.cluster_expansions().find(vm["clex"].as<std::string>());
544  if (it == set.cluster_expansions().end()) {
545  err_log().error("Invalid --clex value");
546  err_log() << vm["clex"].as<std::string>()
547  << " not found. expected basis set specifications file at: "
548  << dir.bspecs(clex_desc.bset) << "\n"
549  << std::endl;
550  return ERR_INVALID_ARG;
551  }
552  clex_desc = it->second;
553  }
554 
555  Data d(args.primclex, dir, set, clex_desc);
556 
557  typedef Data::pair_type pair_type;
558 
559  // disply all settings
560  if (vm.count("list")) {
561  print_summary(set, log());
562  return 0;
563  }
564 
565  // create new cluster_expansions/clex.property directory and sub-directories
566  else if (vm.count("new-property")) {
567  d.property = pair_type(single_input, create);
568  d.calctype = pair_type("default", create);
569  d.ref = pair_type("default", create);
570  d.bset = pair_type("default", create);
571  d.eci = pair_type("default", create);
572 
573  return d.update();
574  }
575 
576  // create new bset, and default eci for current calctype and ref
577  else if (vm.count("new-bset")) {
578  d.bset = pair_type(single_input, create);
579  d.eci = pair_type("default", create);
580 
581  return d.update();
582  }
583 
584  // create new calctype, and ref (either as specified, or default)
585  else if (vm.count("new-calctype")) {
586  d.calctype = pair_type(single_input, create);
587  d.ref = pair_type("default", create);
588  d.eci = pair_type("default", create);
589 
590  return d.update();
591  }
592 
593  // create new ref for current calctype
594  else if (vm.count("new-ref")) {
595  d.ref = pair_type(single_input, create);
596  d.eci = pair_type("default", create);
597 
598  return d.update();
599  }
600 
601  // create new eci directory
602  else if (vm.count("new-eci")) {
603  d.eci = pair_type(single_input, create);
604 
605  return d.update();
606  }
607 
608  // create new cluster expansion settings group
609  else if (vm.count("new-clex")) {
610  clex_desc.name = single_input;
611  if (set.insert_clex(clex_desc)) {
612  log() << "Created new cluster expansion named '" << single_input
613  << "'\n\n";
614  } else {
615  log() << "Could not create new cluster expansion named '" << single_input
616  << "'.\n\n";
617  return 1;
618  }
619 
620  if (clex_exists(dir, clex_desc) && set.set_default_clex(clex_desc)) {
621  commit(set);
622  if (args.primclex) {
623  args.primclex->refresh(true, false, true, true, true);
624  }
625  log() << "Set '" << clex_desc.name
626  << "' as default cluster expansion.\n\n";
627  return 0;
628  } else {
629  log() << "Could not set '" << clex_desc.name
630  << "' as default cluster expansion.\n\n";
631  return 1;
632  }
633  }
634 
635  // erase cluster expansion settings group
636  else if (vm.count("erase-clex")) {
637  if (set.default_clex().name == single_input) {
638  log() << "Coult not erase the cluster expansion named '" << single_input
639  << "' "
640  << "because it is the default cluster expansion.\n\n";
641  return 1;
642  }
643 
644  if (set.cluster_expansions().size() == 1) {
645  log() << "Could not erase the cluster expansion named '" << single_input
646  << "' "
647  << "because it is the only cluster expansion.\n\n";
648  return 1;
649  }
650 
651  if (set.erase_clex(set.clex(single_input))) {
652  commit(set);
653  if (args.primclex) {
654  args.primclex->refresh(true, false, true, true, true);
655  }
656  log() << "Erased cluster expansion named '" << single_input << "'\n\n";
657  return 0;
658  } else {
659  log() << "Could not erase cluster expansion named '" << single_input
660  << "'.\n\n";
661  return 1;
662  }
663  }
664 
665  // set clex to use by default for formation energy
666  else if (vm.count("set-formation-energy")) {
667  if (clex_desc.property != "formation_energy") {
668  err_log() << "Attempting to use cluster expansion '" << clex_desc.name
669  << "' for formation_energy, but it has 'property' value '"
670  << clex_desc.property << "'.\n\n";
671  return ERR_INVALID_ARG;
672  }
673 
674  auto it = set.cluster_expansions().find("formation_energy");
675  if (it != set.cluster_expansions().end()) {
676  set.erase_clex(it->second);
677  }
678  clex_desc.name = "formation_energy";
679  if (set.insert_clex(clex_desc)) {
680  commit(set);
681  if (args.primclex) {
682  args.primclex->refresh(true, false, true, true, true);
683  }
684  log() << "Now using cluster expansion '" << single_input
685  << "' as the default for formation_energy.\n\n";
686  return 0;
687  } else {
688  log() << "Could not use cluster expansion '" << single_input
689  << "' as the default for formation_energy.\n\n";
690  return 1;
691  }
692  }
693 
694  // set default clex
695  else if (vm.count("set-default-clex")) {
696  if (set.set_default_clex_name(single_input)) {
697  commit(set);
698  if (args.primclex) {
699  args.primclex->refresh(true, false, true, true, true);
700  }
701  log() << "Switched to cluster expansion '" << single_input << "'.\n\n";
702  return 0;
703  } else {
704  log() << "Could not switch to cluster expansion '" << single_input
705  << "'.\n\n";
706  return 1;
707  }
708  }
709 
710  // set property
711  else if (vm.count("set-property")) {
712  d.property = pair_type(single_input, do_not_create);
713  d.calctype = pair_type("default", do_not_create);
714  d.ref = pair_type("default", do_not_create);
715  d.bset = pair_type("default", do_not_create);
716  d.eci = pair_type("default", create);
717 
718  return d.update();
719  }
720 
721  // set bset
722  else if (vm.count("set-bset")) {
723  d.bset = pair_type(single_input, do_not_create);
724  d.eci = pair_type("default", create);
725 
726  return d.update();
727  }
728 
729  // set calctype
730  else if (vm.count("set-calctype")) {
731  d.calctype = pair_type(single_input, do_not_create);
732  d.ref = pair_type("default", do_not_create);
733  d.eci = pair_type("default", create);
734 
735  return d.update();
736  }
737 
738  // set ref
739  else if (vm.count("set-ref")) {
740  d.ref = pair_type(single_input, do_not_create);
741  d.eci = pair_type("default", create);
742 
743  return d.update();
744  }
745 
746  // set eci
747  else if (vm.count("set-eci")) {
748  d.eci = pair_type(single_input, do_not_create);
749 
750  return d.update();
751  }
752 
753  // set all
754  else if (vm.count("set-all")) {
755  if (multi_input.size() != 5) {
756  log() << "Error using --set-all: Expected 5 arguments: 'property' "
757  "'calctype' 'ref' 'bset' 'eci'"
758  << std::endl;
759  return ERR_INVALID_ARG;
760  }
761 
762  d.property = pair_type(multi_input[0], do_not_create);
763  d.calctype = pair_type(multi_input[1], do_not_create);
764  d.ref = pair_type(multi_input[2], do_not_create);
765  d.bset = pair_type(multi_input[3], do_not_create);
766  d.eci = pair_type(multi_input[4], create);
767 
768  return d.update();
769  }
770 
771  // set cxx
772  else if (vm.count("set-cxx")) {
773  set.set_cxx(single_input);
774  commit(set);
775  if (args.primclex) {
776  args.primclex->refresh(true, false, false, false, true);
777  }
778 
779  log() << "Set " << _wdefaultval("cxx", set.cxx());
780  log() << "Compile command is now: '" << set.compile_options() << "'\n\n";
781  log() << "Shared object compile command is now: '" << set.so_options()
782  << "'\n\n";
783 
784  return 0;
785  }
786 
787  // set cxxflags
788  else if (vm.count("set-cxxflags")) {
789  set.set_cxxflags(single_input);
790  commit(set);
791  if (args.primclex) {
792  args.primclex->refresh(true, false, false, false, true);
793  }
794 
795  log() << "Set " << _wdefaultval("cxxflags", set.cxxflags());
796  log() << "Compile command is now: '" << set.compile_options() << "'\n\n";
797 
798  return 0;
799  }
800 
801  // set soflags
802  else if (vm.count("set-soflags")) {
803  set.set_soflags(single_input);
804  commit(set);
805  if (args.primclex) {
806  args.primclex->refresh(true, false, false, false, true);
807  }
808 
809  log() << "Set " << _wdefaultval("soflags", set.soflags());
810  log() << "Shared object compile command is now: '" << set.so_options()
811  << "'\n\n";
812 
813  return 0;
814  }
815 
816  // set casm prefix
817  else if (vm.count("set-casm-prefix")) {
818  set.set_casm_prefix(single_input);
819  commit(set);
820  if (args.primclex) {
821  args.primclex->refresh(true, false, false, false, true);
822  }
823 
824  log() << "Set " << _wdefaultval("casm_includedir", set.casm_includedir());
825  log() << "Set " << _wdefaultval("casm_libdir", set.casm_libdir());
826  log() << "Compile command is now: '" << set.compile_options() << "'\n\n";
827  log() << "Shared object compile command is now: '" << set.so_options()
828  << "'\n\n";
829 
830  return 0;
831  }
832 
833  // set casm includedir
834  else if (vm.count("set-casm-includedir")) {
835  set.set_casm_includedir(single_input);
836  commit(set);
837  if (args.primclex) {
838  args.primclex->refresh(true, false, false, false, true);
839  }
840 
841  log() << "Set " << _wdefaultval("casm_includedir", set.casm_includedir());
842  log() << "Compile command is now: '" << set.compile_options() << "'\n\n";
843  log() << "Shared object compile command is now: '" << set.so_options()
844  << "'\n\n";
845 
846  return 0;
847  }
848 
849  // set casm libdir
850  else if (vm.count("set-casm-libdir")) {
851  set.set_casm_libdir(single_input);
852  commit(set);
853  if (args.primclex) {
854  args.primclex->refresh(true, false, false, false, true);
855  }
856 
857  log() << "Set " << _wdefaultval("casm_libdir", set.casm_libdir());
858  log() << "Compile command is now: '" << set.compile_options() << "'\n\n";
859  log() << "Shared object compile command is now: '" << set.so_options()
860  << "'\n\n";
861 
862  return 0;
863  }
864 
865  // set boost prefix
866  else if (vm.count("set-boost-prefix")) {
867  set.set_boost_prefix(single_input);
868  commit(set);
869  if (args.primclex) {
870  args.primclex->refresh(true, false, false, false, true);
871  }
872 
873  log() << "Set " << _wdefaultval("boost_includedir", set.boost_includedir());
874  log() << "Set " << _wdefaultval("boost_libdir", set.boost_libdir());
875  log() << "Compile command is now: '" << set.compile_options() << "'\n\n";
876  log() << "Shared object compile command is now: '" << set.so_options()
877  << "'\n\n";
878 
879  return 0;
880  }
881 
882  // set boost includedir
883  else if (vm.count("set-boost-includedir")) {
884  set.set_boost_includedir(single_input);
885  commit(set);
886  if (args.primclex) {
887  args.primclex->refresh(true, false, false, false, true);
888  }
889 
890  log() << "Set " << _wdefaultval("boost_includedir", set.boost_includedir());
891  log() << "Compile command is now: '" << set.compile_options() << "'\n\n";
892  log() << "Shared object compile command is now: '" << set.so_options()
893  << "'\n\n";
894 
895  return 0;
896  }
897 
898  // set boost libdir
899  else if (vm.count("set-boost-libdir")) {
900  set.set_boost_libdir(single_input);
901  commit(set);
902  if (args.primclex) {
903  args.primclex->refresh(true, false, false, false, true);
904  }
905 
906  log() << "Set " << _wdefaultval("boost_libdir", set.boost_libdir());
907  log() << "Compile command is now: '" << set.compile_options() << "'\n\n";
908  log() << "Shared object compile command is now: '" << set.so_options()
909  << "'\n\n";
910 
911  return 0;
912  }
913 
914  // set 'casm view' command
915  else if (vm.count("set-view-command")) {
916  set.set_view_command(single_input);
917  commit(set);
918  if (args.primclex) {
919  args.primclex->refresh(true, false, false, false, false);
920  }
921 
922  log() << "Set view command to: '" << set.view_command() << "'\n\n";
923 
924  return 0;
925  }
926 
927  // set 'casm view' command
928  else if (vm.count("set-view-command-video")) {
929  set.set_view_command_video(single_input);
930  commit(set);
931  if (args.primclex) {
932  args.primclex->refresh(true, false, false, false, false);
933  }
934 
935  log() << "Set video view command to: '" << set.view_command_video()
936  << "'\n\n";
937 
938  return 0;
939  }
940 
941  log() << std::endl;
942 
943  return 0;
944 };
945 
946 } // namespace CASM
#define ERR_NO_PROJ
Definition: errors.hh:13
#define ERR_INVALID_ARG
Definition: errors.hh:7
int argc() const
Definition: CLIParse.hh:20
char ** argv() const
Definition: CLIParse.hh:22
static std::string calctype()
Get value_type string for calctype mode completion.
Definition: Handlers.cc:76
static std::string property()
Get value_type string for property mode completion.
Definition: Handlers.cc:86
static std::string eci()
Get value_type string for eci mode completion.
Definition: Handlers.cc:84
static std::string ref()
Get value_type string for ref mode completion.
Definition: Handlers.cc:82
static std::string bset()
Get value_type string for bset mode completion.
Definition: Handlers.cc:78
static std::string clex()
Get value_type string for clex mode completion.
Definition: Handlers.cc:80
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
std::vector< std::string > m_input_vec
Definition: Handlers.hh:741
void initialize() override
Fill in the options descriptions accordingly.
Definition: settings.cc:38
const std::string & input_str() const
Definition: settings.cc:32
const std::vector< std::string > & input_vec() const
Definition: settings.cc:34
Specification of CASM project directory structure.
fs::path bspecs(std::string bset) const
Return basis function specs (bspecs.json) file path.
bool print() const
Definition: Log.cc:260
void error(const std::string &what)
Definition: Log.hh:129
std::pair< fs::path, std::string > boost_includedir() const
Get boost includedir (pair of value and source for the value)
ClexDescription const & clex(std::string clex_name) const
Get a ClexDescription by name.
std::string view_command() const
Get current command used by 'casm view'.
bool set_view_command(std::string opt)
Set command used by 'casm view'.
std::pair< fs::path, std::string > casm_libdir() const
Get casm libdir (pair of value and source for the value)
bool insert_clex(ClexDescription const &desc)
std::map< std::string, ClexDescription > const & cluster_expansions() const
Const access map of all ClexDescription.
bool set_cxxflags(std::string opt)
Set c++ compiler options (empty string to use default)
bool set_boost_libdir(fs::path dir)
Set boost libdir (empty string to use default)
DirectoryStructure const & dir() const
Access DirectoryStructure object. Throw if not set.
std::string compile_options() const
bool set_boost_prefix(fs::path dir)
Set boost prefix (empty string to use default)
std::pair< fs::path, std::string > casm_includedir() const
Get casm includedir (pair of value and source for the value)
bool set_default_clex_name(std::string const &clex_name)
Set default ClexDescription by name.
std::pair< fs::path, std::string > boost_libdir() const
Get boost libdir (pair of value and source for the value)
bool set_casm_includedir(fs::path dir)
Set casm includedir (empty string to use default)
bool set_casm_prefix(fs::path dir)
Set casm prefix (empty string to use default)
ClexDescription const & default_clex() const
Get default ClexDescription.
std::pair< std::string, std::string > soflags() const
Get shared object options (pair of value and source for the value)
bool set_view_command_video(std::string opt)
Set video viewing command used by 'casm view'.
std::string so_options() const
std::pair< std::string, std::string > cxx() const
Get c++ compiler (pair of value and source for the value)
bool set_default_clex(ClexDescription const &desc)
bool set_soflags(std::string opt)
Set shared object options (empty string to use default)
bool erase_clex(ClexDescription const &desc)
bool set_casm_libdir(fs::path dir)
Set casm libdir (empty string to use default)
bool set_boost_includedir(fs::path dir)
Set boost includedir (empty string to use default)
bool set_cxx(std::string opt)
Set c++ compiler (empty string to use default)
std::pair< std::string, std::string > cxxflags() const
Get c++ compiler options (pair of value and source for the value)
std::string view_command_video() const
Get current video viewing command used by 'casm view'.
void refresh(bool read_settings=false, bool read_composition=false, bool read_chem_ref=false, bool read_configs=false, bool clear_clex=false)
Reload PrimClex data from settings.
Definition: PrimClex.cc:156
void commit(ProjectSettings const &set)
ProjectSettings open_project_settings(fs::path path_in_project)
void print_summary(ProjectSettings const &set, Log &log)
Print summary of ProjectSettings, as for 'casm settings -l'.
Main CASM namespace.
Definition: APICommand.hh:8
Log & log()
Definition: Log.hh:424
bool clex_exists(const DirectoryStructure &dir, const ClexDescription &desc)
bool contains(const Container &container, const T &value)
Equivalent to container.end() != std::find(container.begin(), container.end(), value)
Definition: algorithm.hh:83
int settings_command(const CommandArgs &args)
Definition: settings.cc:283
Log & err_log()
Definition: Log.hh:426
pair_type ref
Definition: settings.cc:144
pair_type eci
Definition: settings.cc:146
PrimClex * primclex
Definition: settings.cc:135
ClexDescription & desc
Definition: settings.cc:138
pair_type calctype
Definition: settings.cc:143
pair_type property
Definition: settings.cc:142
DirectoryStructure const & dir
Definition: settings.cc:136
ProjectSettings & set
Definition: settings.cc:137
pair_type bset
Definition: settings.cc:145
Specifies a particular cluster expansion.
Data structure holding basic CASM command info.