CASM  1.1.0
A Clusters Approach to Statistical Mechanics
view.cc
Go to the documentation of this file.
1 #include <boost/filesystem/fstream.hpp>
2 
18 #include "casm/system/Popen.hh"
19 
20 // need to add specializations here
22 
23 namespace CASM {
24 
25 namespace Completer {
26 
28 
35  m_desc.add_options()("images,i", po::value<int>(&m_images)->default_value(0),
36  "Number of images between initial and final state when "
37  "viewing diff_trans_configs.")(
38  "relaxed,r",
39  "Attempt to display corresponding relaxed structures to the given "
40  "configurations.");
41 
42  return;
43 }
44 } // namespace Completer
45 
46 int view_command(const CommandArgs &args) {
47  fs::path selection;
48  po::variables_map vm;
49  // bool force;
50  std::vector<std::string> confignames;
51 
52  // Set command line options using boost program_options
53  Completer::ViewOption view_opt;
54 
55  // allow confignames as positional options
56  po::positional_options_description p;
57  p.add("confignames", -1);
58 
59  try {
60  po::store(po::command_line_parser(args.argc() - 1, args.argv() + 1)
61  .options(view_opt.desc())
62  .positional(p)
63  .run(),
64  vm);
65  // po::store(po::parse_command_line(argc, argv, view_opt.desc()), vm); //
66  // can throw
67 
70  if (vm.count("help")) {
71  log() << "\n";
72  log() << view_opt.desc() << std::endl;
73 
74  return 0;
75  }
76 
77  if (vm.count("desc")) {
78  log() << "\n";
79  log() << view_opt.desc() << std::endl;
80  log() << "This allows opening visualization programs directly from \n"
81  "CASM. It iterates over all selected configurations and \n"
82  "one by one writes a POSCAR and executes \n"
83  " '$VIEW_COMMAND /path/to/POSCAR' \n"
84  "where $VIEW_COMMAND is set via 'casm settings "
85  "--set-view-command'.\n"
86  "A script 'casm.view' is included with can be used to run \n"
87  "a command and then pause 1s, which is useful for opening \n"
88  "POSCARs with VESTA. An example on Mac might look like: \n"
89  " casm settings --set-view-command 'casm.view \"open -a "
90  "/Applications/VESTA/VESTA.app\"' \n\n";
91 
92  return 0;
93  }
94 
95  po::notify(vm); // throws on error, so do after help in case
96  // there are any problems
97 
98  selection = view_opt.selection_path().string();
99  confignames = view_opt.config_strs();
100  } catch (po::error &e) {
101  err_log() << "ERROR: " << e.what() << std::endl << std::endl;
102  err_log() << view_opt.desc() << std::endl;
103  return ERR_INVALID_ARG;
104  } catch (std::exception &e) {
105  err_log() << "Unhandled Exception reached the top of main: " << e.what()
106  << ", application will now exit" << std::endl;
107  return ERR_UNKNOWN;
108  }
109 
110  const fs::path &root = args.root;
111  if (root.empty()) {
112  err_log().error("No casm project found");
113  err_log() << std::endl;
114  return ERR_NO_PROJ;
115  }
116 
118  if (set.view_command().empty()) {
119  err_log() << "Error in 'casm view': No command set. Use 'casm settings "
120  "--set-view-command' to set the command to open visualization "
121  "software. It should take one argument, the path to a POSCAR "
122  "to be visualized. For example, to use VESTA on Mac: casm "
123  "settings --set-view-command 'casm.view \"open -a "
124  "/Applications/VESTA/VESTA.app\"'.\n";
125  return ERR_MISSING_DEPENDS;
126  }
127 
128  // If 'args.primclex', use that, else construct PrimClex in 'uniq_primclex'
129  // Then whichever exists, store reference in 'primclex'
130  std::unique_ptr<PrimClex> uniq_primclex;
131  PrimClex &primclex = make_primclex_if_not(args, uniq_primclex);
132 
133  DB::Selection<Configuration> config_select;
134  if (!vm.count("config")) {
135  config_select = DB::Selection<Configuration>(primclex, "NONE");
136  } else if (selection == "MASTER") {
137  config_select = DB::Selection<Configuration>(primclex);
138  } else {
139  config_select = DB::Selection<Configuration>(primclex, selection);
140  }
141 
142  // add --confignames (or positional) input
143  for (int i = 0; i < confignames.size(); i++) {
144  config_select.data()[confignames[i]] = true;
145  }
146 
147  fs::path tmp_dir = root / ".casm" / "tmp";
148  fs::create_directory(tmp_dir);
149 
150  // execute the 'casm view' command for each selected configuration
151  for (const auto &config : config_select.selected()) {
152  if (vm.count("relaxed") && is_calculated(config)) {
153  fs::ofstream file;
154  fs::path POSCARpath = tmp_dir / "POSCAR";
155 
156  // Make pos_path the path to properties.calc.json constructed from it
157  fs::path pos_path = calc_properties_path(primclex, config.name());
158  log() << "Obtaining relaxed structure from:\n";
159  log() << pos_path.string() << std::endl;
160  SimpleStructure import_struc;
161  jsonParser datajson(pos_path);
162  from_json(import_struc, datajson);
163 
164  file.open(POSCARpath);
165  VaspIO::PrintPOSCAR p(import_struc);
166  p.sort();
167  p.print(file);
168  file.close();
169  log() << config.name() << " relaxed"
170  << ":\n";
171  Popen popen;
172  popen.popen(set.view_command() + " " + POSCARpath.string());
173  popen.print(log());
174  } else {
175  // write '.casm/tmp/POSCAR'
176  fs::ofstream file;
177  fs::path POSCARpath = tmp_dir / "POSCAR";
178  file.open(POSCARpath);
180  p.sort();
181  p.print(file);
182  file.close();
183  if (vm.count("relaxed")) {
184  log() << "No relaxed structure found."
185  << "\n";
186  }
187  log() << config.name() << ":\n";
188  Popen popen;
189  popen.popen(set.view_command() + " " + POSCARpath.string());
190  popen.print(log());
191  }
192  }
193 
194  return 0;
195 };
196 
197 } // namespace CASM
#define ERR_NO_PROJ
Definition: errors.hh:13
#define ERR_MISSING_DEPENDS
Definition: errors.hh:26
#define ERR_UNKNOWN
Definition: errors.hh:10
#define ERR_INVALID_ARG
Definition: errors.hh:7
int argc() const
Definition: CLIParse.hh:20
char ** argv() const
Definition: CLIParse.hh:22
void add_confignames_suboption()
Add a –confignames suboption.
Definition: Handlers.cc:691
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_configtype_suboption(std::string _default, std::set< std::string > _configtype_opts)
Add –type suboption (default, set of short_name of allowed ConfigTypes)
Definition: Handlers.cc:511
void add_configlist_nodefault_suboption()
Add –config suboption (no default)
Definition: Handlers.cc:467
const std::vector< std::string > & config_strs() const
Definition: Handlers.cc:382
const fs::path & selection_path() const
Returns the string corresponding to add_config_suboption()
Definition: Handlers.cc:338
void initialize() override
Fill in the options descriptions accordingly.
Definition: view.cc:29
boost::iterator_range< iterator > selected()
Definition: Selection.cc:237
map_type & data()
Definition: Selection.cc:250
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
std::string view_command() const
Get current command used by 'casm view'.
Print POSCAR with formating options.
Definition: VaspIO.hh:40
void sort()
Default sort is by atom name.
Definition: VaspIO.cc:50
void print(std::ostream &sout) const
Print POSCAR to stream.
Definition: VaspIO.cc:56
Representation of a crystal of molecular and/or atomic occupants, and any additional properties....
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...
ProjectSettings open_project_settings(fs::path path_in_project)
ConfigIO::GenericConfigFormatter< jsonParser > config()
Definition: ConfigIO.cc:777
const std::set< std::string > & config_types_short()
std::set of all QueryTraits<ConfigType>::short_name
Main CASM namespace.
Definition: APICommand.hh:8
int view_command(const CommandArgs &args)
Definition: view.cc:46
xtal::SimpleStructure make_simple_structure(Supercell const &_scel, ConfigDoF const &_dof, std::vector< DoFKey > const &_which_dofs={})
Construct from ConfigDoF _dof belonging to provided Supercell _scel.
std::string calc_properties_path(const ConfigType &config, std::string calctype="")
Definition: Calculable.cc:197
Log & log()
Definition: Log.hh:424
bool is_calculated(const ConfigType &config, std::string calctype="")
Return true if all required properties have been been calculated for the configuration.
Definition: Calculable.cc:137
std::string pos_path(const ConfigType &config, std::string calctype="")
void from_json(ClexDescription &desc, const jsonParser &json)
Log & err_log()
Definition: Log.hh:426
PrimClex * primclex
Definition: settings.cc:135
ProjectSettings & set
Definition: settings.cc:137
Data structure holding basic CASM command info.