CASM  1.1.0
A Clusters Approach to Statistical Mechanics
ConfigIOStrucScore.cc
Go to the documentation of this file.
2 
3 #include <boost/filesystem.hpp>
4 #include <functional>
5 
10 #include "casm/clex/ConfigIO.hh"
13 #include "casm/clex/PrimClex.hh"
20 
21 namespace CASM {
22 
23 namespace {
24 fs::path _calc_properties_path(const Configuration &config) {
25  const PrimClex &primclex = config.primclex();
28 }
29 } // namespace
30 
31 namespace ConfigIO {
32 
35  "struc_score",
36  "Evaluates the mapping of a configuration onto an arbitrary "
37  "primitive structure, specified by its path. Allowed options are [ "
38  "'basis_score' (mean-square site displacement) | 'lattice_score' "
39  "(lattice deformation metric having units Angstr.^2) | 'total_score' "
40  "(w*lattice_score+(1.0-w)*basis_score) ]. The struc_score weighting "
41  "parameter 'w' can be provided as an optional decimal parameter from "
42  "0.0 to 1.0 (default 0.5). Ex: struc_score(path/to/PRIM, "
43  "basis_score, 0.4)"),
44  m_strain_weight(0.5){
45 
46  };
47 
50  m_altprim((RHS.m_altprim == nullptr)
51  ? nullptr
52  : new BasicStructure(*(RHS.m_altprim))),
53  m_strain_weight(RHS.m_strain_weight),
54  m_prim_path(RHS.m_prim_path),
55  m_prop_names(RHS.m_prop_names) {
56  if (RHS.m_strucmapper)
57  m_strucmapper = notstd::make_unique<StrucMapper>(*RHS.m_strucmapper);
58 }
59 
60 bool StrucScore::parse_args(const std::string &args) {
61  std::vector<std::string> splt_vec;
62  double _strain_weight = 0.5;
63  bool already_initialized = !m_prim_path.empty();
64  int pushed_args = 0;
65  boost::split(splt_vec, args, boost::is_any_of(", "),
66  boost::token_compress_on);
67  if (splt_vec.size() < 2 || splt_vec.size() > 4) {
68  throw std::runtime_error(
69  "Attempted to initialize format tag " + name() + " with " +
70  std::to_string(splt_vec.size()) + " arguments (" + args +
71  "). You must provide at least 2 arguments, but no more than 4.\n");
72  return false;
73  }
74  if (!m_prim_path.empty() && fs::path(splt_vec[0]) != m_prim_path)
75  return false;
76  if (m_prim_path.empty()) {
77  m_prim_path = splt_vec[0];
78  if (!fs::exists(m_prim_path)) {
79  throw std::runtime_error("Attempted to initialize format tag " + name() +
80  " invalid file path '" +
81  fs::absolute(m_prim_path).string() +
82  "'. File does not exist.\n");
83  }
84  }
85  for (Index i = 1; i < splt_vec.size(); ++i) {
86  if (splt_vec[i] != "basis_score" && splt_vec[i] != "lattice_score" &&
87  splt_vec[i] != "total_score") {
88  try {
89  _strain_weight = std::stod(splt_vec[i]);
90  } catch (...) {
91  throw std::runtime_error("Attempted to initialize format tag " +
92  name() + " with invalid argument '" +
93  splt_vec[i] +
94  "'. Valid arguments are [ basis_score | "
95  "lattice_score | total_score ]\n");
96  }
97  if (already_initialized &&
98  !almost_equal(_strain_weight, m_strain_weight)) {
99  for (; pushed_args > 0; pushed_args--) m_prop_names.pop_back();
100  return false;
101  }
102  } else {
103  m_prop_names.push_back(splt_vec[i]);
104  ++pushed_args;
105  }
106  }
107  return true;
108 }
109 
110 //****************************************************************************************
111 
113 bool StrucScore::init(const Configuration &_tmplt) const {
114  PrimClex const &pclex(_tmplt.primclex());
115  m_altprim.reset(
116  new BasicStructure(read_prim(m_prim_path, _tmplt.crystallography_tol())));
117 
118  m_strucmapper = notstd::make_unique<StrucMapper>(
120  return true;
121 }
122 
123 //****************************************************************************************
124 
125 bool StrucScore::validate(const Configuration &_config) const {
126  return fs::exists(_calc_properties_path(_config));
127 }
128 
129 //****************************************************************************************
130 
131 std::vector<std::string> StrucScore::col_header(
132  const Configuration &_tmplt) const {
133  std::vector<std::string> col;
134  for (Index i = 0; i < m_prop_names.size(); i++) {
135  std::stringstream t_ss;
136  t_ss << " " << name() << '(' << m_prim_path.string() << ','
137  << m_prop_names[i] << ',' << m_strucmapper->lattice_weight() << ')';
138  col.push_back(t_ss.str());
139  }
140  return col;
141 }
142 
143 //****************************************************************************************
144 
145 std::string StrucScore::short_header(const Configuration &_tmplt) const {
146  std::stringstream t_ss;
147  t_ss << name() << '(' << m_prim_path.string();
148  for (Index i = 0; i < m_prop_names.size(); i++)
149  t_ss << ',' << m_prop_names[i];
150  t_ss << ',' << m_strucmapper->lattice_weight() << ')';
151  return t_ss.str();
152 }
153 
154 //****************************************************************************************
156  SimpleStructure relaxed_struc;
157 
158  from_json(relaxed_struc, jsonParser(_calc_properties_path(_config)));
159 
160  auto result = m_strucmapper->map_deformed_struc(relaxed_struc);
161  Eigen::VectorXd result_vec(m_prop_names.size());
162  if (result.empty()) {
163  result_vec.setConstant(1e9);
164  return result_vec;
165  }
166 
167  MappingNode const &mapping(*result.begin());
168 
169  for (Index i = 0; i < m_prop_names.size(); i++) {
170  if (m_prop_names[i] == "basis_score") {
171  result_vec[i] = mapping.atomic_node.cost;
172  } else if (m_prop_names[i] == "lattice_score") {
173  result_vec[i] = mapping.lattice_node.cost;
174  } else if (m_prop_names[i] == "total_score") {
175  result_vec[i] = mapping.cost;
176  }
177  }
178 
179  return result_vec;
180 }
181 
182 } // namespace ConfigIO
183 } // namespace CASM
Abstract base class for creating 1D DatumFormatter.
const std::string & name() const
Returns a name for the formatter, which becomes the tag used for parsing.
Evaluates the mapping of a configuration onto an arbitrary primitive structure.
Eigen::VectorXd evaluate(Configuration const &_config) const override
bool validate(Configuration const &_config) const override
std::unique_ptr< StrucMapper > m_strucmapper
std::string short_header(Configuration const &_config) const override
bool init(Configuration const &tmplt) const override
If not yet initialized, use the default clexulator from the PrimClex.
std::vector< std::string > m_prop_names
std::vector< std::string > col_header(Configuration const &_config) const override
bool parse_args(std::string const &args) override
Default implementation calls _parse_index_expression.
std::unique_ptr< BasicStructure > m_altprim
fs::path calculated_properties(std::string configname, std::string calctype) const
Return properties.calc.json file path.
PrimClex is the top-level data structure for a CASM project.
Definition: PrimClex.hh:55
ClexDescription const & default_clex() const
Get default ClexDescription.
BasicStructure specifies the lattice and atomic basis of a crystal.
Representation of a crystal of molecular and/or atomic occupants, and any additional properties....
std::string to_string(ENUM val)
Return string representation of enum class.
Definition: io_traits.hh:172
ProjectSettings & settings()
Definition: PrimClex.cc:224
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
bool almost_equal(ClusterInvariants const &A, ClusterInvariants const &B, double tol)
Check if ClusterInvariants are equal.
xtal::BasicStructure read_prim(fs::path filename, double xtal_tol, ParsingDictionary< AnisoValTraits > const *_aniso_val_dict=nullptr)
void from_json(ClexDescription &desc, const jsonParser &json)
INDEX_TYPE Index
For long integer indexing:
Definition: definitions.hh:39
Eigen::VectorXd VectorXd
PrimClex * primclex
Definition: settings.cc:135
double cost
Total cost of best solution to the constrained assignment problem having some forced_on assignments.
double cost
strain_cost of the LatticeNode
AssignmentNode atomic_node
double cost
total, finalized cost, populated by a StrucMapCalculator. Not guaranteed to be a linear function of l...