10 template<
typename ConfigIterType>
17 for(; begin != end; ++begin) {
18 if(begin.selected() == mk)
21 if(select_stream.
fail()) {
22 err_log <<
"Warning: Unable to apply criteria \"" << criteria <<
"\" to configuration " << begin.name() <<
"\n";
26 select_stream << tformat(*begin);
27 if(select_stream.
value()) {
28 begin.set_selected(mk);
33 for(; begin != end; ++begin) {
34 begin.set_selected(mk);
38 catch(std::exception &e) {
39 throw std::runtime_error(std::string(
"Failure to select using criteria \"") + criteria +
"\" for configuration " + begin.name() +
"\n Reason: " + e.what());
44 template<
typename ConfigIterType>
50 for(; begin != end; ++begin) {
52 if(select_stream.
fail()) {
53 err_log <<
"Warning: Unable to apply criteria \"" << criteria <<
"\" to configuration " << begin.name() <<
"\n";
56 select_stream << tformat(*begin);
57 begin.set_selected(select_stream.
value());
61 catch(std::exception &e) {
62 throw std::runtime_error(std::string(
"Failure to select using criteria \"") + criteria +
"\" for configuration " + begin.name() +
"\n Reason: " + e.what());
68 template<
bool IsConst>
70 if(fs::exists(out_path) && !force) {
71 err_log <<
"File " << out_path <<
" already exists. Use --force to force overwrite." << std::endl;
75 if(write_json || out_path.extension() ==
".json" || out_path.extension() ==
".JSON") {
77 config_select.
to_json(dict, json, only_selected);
93 _stream <<
"DESCRIPTION" << std::endl
95 <<
" Use '[--set | --set-on | --set-off] [criteria]' for specifying or editing a selection.\n";
97 for(
const std::string &str : help_opt) {
103 _stream <<
"Available operators for use within selection criteria:" << std::endl;
106 else if(str[0] ==
'p') {
107 _stream <<
"Available property tags are currently:" << std::endl;
110 _stream << std::endl;
112 _stream << std::endl;
115 namespace Completer {
128 (
"json",
"Write JSON output (otherwise CSV, unless output extension is '.json' or '.JSON')")
129 (
"subset",
"Only write selected configurations to output. Can be used by itself or in conjunction with other options")
130 (
"xor",
"Performs logical XOR on two configuration selections")
131 (
"not",
"Performs logical NOT on configuration selection")
132 (
"or",
"Write configurations selected in any of the input lists. Equivalent to logical OR")
133 (
"and",
"Write configurations selected in all of the input lists. Equivalent to logical AND")
134 (
"set-on", po::value<std::vector<std::string> >(&
m_criteria_vec)->multitoken()->zero_tokens(),
"Add configurations to selection if they meet specified criteria. Call using 'casm select --set-on [\"criteria\"]'")
135 (
"set-off", po::value<std::vector<std::string> >(&
m_criteria_vec)->multitoken()->zero_tokens(),
"Remove configurations from selection if they meet specified criteria. Call using 'casm select --set-off [\"criteria\"]'")
136 (
"set", po::value<std::vector<std::string> >(&
m_criteria_vec)->multitoken(),
"Create a selection of Configurations that meet specified criteria. Call using 'casm select --set [\"criteria\"]'")
137 (
"force,f",
"Overwrite output file");
144 template<
bool IsConst>
148 auto Ninclude = only_selected ? Nselected : std::distance(config_select.
config_begin(), config_select.
config_end());
150 log <<
"# configurations in this project: " << Ntot <<
"\n";
151 log <<
"# configurations included in this list: " << Ninclude <<
"\n";
152 log <<
"# configurations selected in this list: " << Nselected <<
"\n";
155 template<
bool IsConst>
160 log <<
"# configurations in this project: " << Ntot <<
"\n";
161 log <<
"# configurations selected in this list: " << Nselected <<
"\n";
173 std::vector<std::string> criteria_vec, help_opt_vec;
174 std::vector<fs::path> selection;
178 po::variables_map vm;
186 std::vector<std::string> allowed_cmd = {
"and",
"or",
"xor",
"not",
"set-on",
"set-off",
"set"};
189 po::store(po::parse_command_line(args.
argc, args.
argv, select_opt.
desc()), vm);
192 for(
const std::string &cmd_str : allowed_cmd) {
193 if(vm.count(cmd_str)) {
199 if(!vm.count(
"help")) {
201 args.
err_log <<
"Error in 'casm select'. Must use exactly one of --set-on, --set-off, --set, --and, --or, --xor, or --not." << std::endl;
204 else if(vm.count(
"subset") && vm.count(
"config") && selection.size() != 1) {
205 args.
err_log <<
"ERROR: 'casm select --subset' expects zero or one list as argument." << std::endl;
211 if(!vm.count(
"output") && (cmd ==
"or" || cmd ==
"and" || cmd ==
"xor" || cmd ==
"not")) {
212 args.
err_log <<
"ERROR: 'casm select --" << cmd <<
"' expects an --output file." << std::endl;
219 if(vm.count(
"help")) {
220 args.
log << std::endl << select_opt.
desc() << std::endl;
231 if(vm.count(
"help")) {
234 auto dict = make_dictionary<Configuration>();
239 Log &status_log = (out_path.string() ==
"STDOUT") ? args.
err_log : args.
log;
243 std::unique_ptr<PrimClex> uniq_primclex;
244 if(out_path.string() ==
"STDOUT") {
254 if((vm.count(
"set-on") || vm.count(
"set-off") || vm.count(
"set")) && vm.count(
"config") && selection.size() != 1) {
255 std::string cmd =
"--set-on";
256 if(vm.count(
"set-off")) {
259 if(vm.count(
"set")) {
263 args.
err_log <<
"Error in 'casm select " << cmd <<
"'. " << selection.size() <<
" config selections were specified, but no more than one selection is allowed (MASTER list is used if no other is specified)." << std::endl;
268 catch(po::error &e) {
270 args.
err_log <<
"ERROR: " << e.what() << std::endl << std::endl;
273 catch(std::exception &e) {
275 args.
err_log <<
"ERROR: " << e.what() << std::endl << std::endl;
280 if(vm.count(
"output") && out_path !=
"MASTER") {
283 if(fs::exists(out_path) && !vm.count(
"force")) {
284 args.
err_log <<
"ERROR: File " << out_path <<
" already exists. Use --force to force overwrite." << std::endl;
289 bool only_selected(
false);
290 if(selection.empty()) {
291 only_selected =
true;
292 selection.push_back(
"MASTER");
304 std::unique_ptr<PrimClex> uniq_primclex;
315 std::stringstream ss;
318 std::vector<ConstConfigSelection> tselect(selection.size() - 1);
319 for(
int i = 1; i < selection.size(); ++i) {
320 ss <<
", " << selection[i];
326 args.
log.
custom(
"Input config list", selection[0].
string());
328 args.
log << std::endl;
330 for(
int i = 1; i < selection.size(); ++i) {
331 args.
log.
custom(
"Input config list", selection[i].
string());
333 args.
log << std::endl;
336 if(vm.count(
"set-on") || vm.count(
"set-off") || vm.count(
"set")) {
337 bool select_switch = vm.count(
"set-on");
338 std::string criteria;
339 if(criteria_vec.size() == 1) {
340 criteria = criteria_vec[0];
342 else if(criteria_vec.size() > 1) {
343 args.
err_log <<
"ERROR: Selection criteria must be a single string. You provided " << criteria_vec.size() <<
" strings:\n";
344 for(
const std::string &str : criteria_vec)
345 args.
err_log <<
" - " << str <<
"\n";
349 if(vm.count(
"set-on")) {
352 if(vm.count(
"set-off")) {
355 if(vm.count(
"set")) {
366 catch(std::exception &e) {
367 args.
err_log <<
"ERROR: " << e.what() <<
"\n";
371 args.
log <<
"selection time: " << args.
log.
lap_time() <<
" (s)\n" << std::endl;
374 if(vm.count(
"subset")) {
377 args.
log <<
"selection time: " << args.
log.
lap_time() <<
" (s)\n" << std::endl;
378 only_selected =
true;
381 if(vm.count(
"not")) {
382 if(selection.size() != 1) {
383 args.
err_log <<
"ERROR: Option --not requires exactly 1 selection as argument\n";
387 args.
log.
custom(std::string(
"not ") + selection[0].
string());
391 auto it = config_select.config_begin();
392 for(; it != config_select.config_end(); ++it) {
393 it.set_selected(!it.selected());
395 args.
log <<
"selection time: " << args.
log.
lap_time() <<
" (s)\n" << std::endl;
400 args.
log.
custom(std::string(
"or(") + ss.str() +
")");
404 for(
int i = 1; i < selection.size(); i++) {
405 for(
auto it = tselect[i].selected_config_cbegin(); it != tselect[i].selected_config_cend(); ++it) {
406 config_select.set_selected(it.name(),
true);
409 args.
log <<
"selection time: " << args.
log.
lap_time() <<
" (s)\n" << std::endl;
410 only_selected =
true;
413 if(vm.count(
"and")) {
414 args.
log.
custom(std::string(
"and(") + ss.str() +
")");
418 for(
int i = 1; i < selection.size(); i++) {
419 auto it = config_select.selected_config_begin();
420 for(; it != config_select.selected_config_end(); ++it) {
421 it.set_selected(tselect[i].selected(it.name()));
425 args.
log <<
"selection time: " << args.
log.
lap_time() <<
" (s)\n" << std::endl;
426 only_selected =
true;
429 if(vm.count(
"xor")) {
430 if(selection.size() != 2) {
431 args.
err_log <<
"ERROR: Option --xor requires exactly 2 selections as argument\n";
435 args.
log.
custom(selection[0].
string() +
" xor " + selection[1].
string());
438 for(
auto it = tselect[1].selected_config_begin(); it != tselect[1].selected_config_end(); ++it) {
440 if(config_select.selected(it.name())) {
441 config_select.set_selected(it.name(),
false);
444 config_select.set_selected(it.name(),
true);
448 args.
log <<
"selection time: " << args.
log.
lap_time() <<
" (s)\n" << std::endl;
449 only_selected =
true;
453 if(!vm.count(
"output") || out_path ==
"MASTER") {
455 for(; pc_it != pc_end; ++pc_it) {
459 auto it = config_select.selected_config_begin(), it_end = config_select.selected_config_end();
460 for(; it != it_end; ++it) {
461 it->set_selected(
true);
464 args.
log.
write(
"Master config_list");
466 args.
log <<
"wrote: MASTER\n" << std::endl;
471 args.
log << std::endl;
478 args.
log <<
"write: " << out_path <<
"\n" << std::endl;
480 args.
log.
custom(
"Output config list", out_path.string());
483 args.
log << std::endl;
Data structure holding basic CASM command info.
void close()
Closes stream, and if not a failed write, removes "file" and renames "file.tmp" to "file"...
void add_output_suboption()
Add a –output suboption. Expects to allow "STDOUT" to print to screen.
void write_config_list(std::set< std::string > scel_to_delete={})
void write(const std::string &what)
jsonParser & to_json(const DataFormatterDictionary< Configuration > &_dict, jsonParser &_json, bool only_selected=false) const
void print(const DataFormatterDictionary< Configuration > &_dict, std::ostream &_out, bool only_selected=false) const
int select_command(const CommandArgs &args)
iterator selected_config_begin()
void add_general_help_suboption()
Add a smart –help suboption that takes "properties" or "operators".
Write to a temporary file to ensure a good write, then rename.
fs::ofstream & ofstream()
Access underlying stream.
void set_selected(bool _select)
config_iterator config_begin()
Configuration iterator: begin.
config_iterator config_end()
Configuration iterator: end.
void print(std::ostream &stream, unsigned int indent=2, unsigned int prec=12) const
Print json to stream.
void open(fs::path name, std::string tmp_ext="tmp")
Opens "file.tmp" for writing, with intended final target "file".
void add_configlists_suboption(const fs::path &_default="MASTER")
Add –configs suboption (defaults to MASTER)
void custom(const std::string &what)
const po::options_description & desc()
Get the program options, filled with the initialized values.
const std::vector< std::string > & criteria_vec() const
bool write_selection(const DataFormatterDictionary< Configuration > &dict, const ConfigSelection< IsConst > &config_select, bool force, const fs::path &out_path, bool write_json, bool only_selected, Log &err_log)
void select_help(const DataFormatterDictionary< Configuration > &_dict, std::ostream &_stream, std::vector< std::string > help_opt)
Read/modify settings of an already existing CASM project.
const std::vector< std::string > & help_opt_vec() const
Returns the list of strings corresponding to add_general_help_suboption()
EigenIndex Index
For long integer indexing:
QueryHandler< DataObject > & query_handler()
iterator selected_config_end()
std::vector< std::string > m_criteria_vec
po::options_description m_desc
Boost program options. All the derived classes have them, but will fill them up themselves.
ProjectSettings & settings()
void write_selection_stats(Index Ntot, const ConfigSelection< IsConst > &config_select, Log &log, bool only_selected)
PrimClex is the top-level data structure for a CASM project.
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...
void set_verbosity(int _verbosity)
void write_master_selection_stats(Index Ntot, const ConfigSelection< IsConst > &config_select, Log &log)
ConfigSelection< true > ConstConfigSelection
void error(const std::string &what)
void set_selection(const DataFormatterDictionary< Configuration > &dict, ConfigIterType begin, ConfigIterType end, const std::string &criteria, bool mk, Log &err_log)
const fs::path output_path() const
Returns the path corresponding to add_output_suboption()
#define ERR_EXISTING_FILE
void initialize() override
Fill in the options descriptions accordingly.
const std::vector< fs::path > & selection_paths() const
Returns the string corresponding to add_config_suboption()
A Configuration represents the values of all degrees of freedom in a Supercell.