3 #include <boost/filesystem.hpp>
20 _attr.
set_value(json[
"value"].get<Eigen::VectorXd>());
34 Eigen::Ref<const Eigen::Matrix3d>
const &c2f_mat) {
37 json[
"name"] = apos.
name();
45 Eigen::Ref<const Eigen::Matrix3d>
const &f2c_mat,
58 Eigen::Vector3d _pos(0., 0., 0.);
59 std::map<std::string, xtal::SpeciesAttribute> attr_map;
61 _name = json[
"name"].
get<std::string>();
63 _pos = f2c_mat * json[
"coordinate"].
get<Eigen::Vector3d>();
68 auto it = json[
"attributes"].
cbegin(), end_it = json[
"attributes"].
cend();
69 for (; it != end_it; ++it) {
71 attr_map.emplace(it.name(), _aniso_val_dict.
lookup(it.name()));
77 _name = json.
get<std::string>();
79 throw std::runtime_error(
80 "Invalid JSON input encountered. Unable to parse AtomPosition "
93 Eigen::Ref<const Eigen::Matrix3d>
const &c2f_mat) {
96 json[
"name"] = mol.
name();
109 Eigen::Ref<const Eigen::Matrix3d>
const &f2c_mat,
111 std::vector<xtal::AtomPosition> _atoms;
117 std::map<std::string, xtal::SpeciesAttribute> attr_map;
119 auto it = json[
"attributes"].
cbegin(), end_it = json[
"attributes"].
cend();
120 for (; it != end_it; ++it) {
122 attr_map.emplace(it.name(), _aniso_val_dict.
lookup(it.name()));
123 from_json(result_pair.first->second, *it);
138 const jsonParser &json, Eigen::Ref<const Eigen::Matrix3d>
const &f2c_mat,
147 std::map<std::string, xtal::Molecule>
const &mol_map,
150 CASM::from_json(result, json, _home, coordtype, mol_map, _aniso_val_dict);
161 if (coordtype ==
FRAC)
172 if (site.
dofs().size()) {
173 json[
"dofs"] = site.
dofs();
186 std::map<std::string, xtal::Molecule>
const &mol_map,
189 if (coordtype ==
FRAC)
190 site.
frac() = json[
"coordinate"].
get<Eigen::Vector3d>();
192 site.
cart() = json[
"coordinate"].
get<Eigen::Vector3d>();
199 throw std::runtime_error(
"JSON specification of site has {\"label\" : " +
201 "}, but \"label\" must be greater than 0.\n");
207 std::map<std::string, xtal::SiteDoFSet> _dof_map;
209 auto it = json[
"dofs"].
begin(), end_it = json[
"dofs"].
end();
210 for (; it != end_it; ++it) {
211 if (_dof_map.count(it.name()))
212 throw std::runtime_error(
213 "Error parsing local field \"dofs\" from JSON. DoF type " +
214 it.name() +
" cannot be repeated.");
220 _dof_map.emplace(std::make_pair(
225 }
catch (std::exception &e) {
226 throw std::runtime_error(
227 "Error parsing local field \"dofs\" from JSON. Failure for DoF "
229 it.name() +
": " + e.what());
235 std::vector<xtal::Molecule> t_occ;
238 occ_key =
"occupants";
239 else if (json.
contains(
"occupant_dof"))
240 occ_key =
"occupant_dof";
242 if (!occ_key.empty()) {
243 for (std::string
const &occ :
244 json[occ_key].
get<std::vector<std::string> >()) {
247 auto it = mol_map.find(occ);
248 if (it != mol_map.end())
249 t_occ.push_back(it->second);
260 fs::path filename,
double xtal_tol,
263 filename = fs::absolute(filename);
264 if (!fs::exists(filename)) {
265 throw std::invalid_argument(
"Error reading prim from file '" +
266 filename.string() +
"'. Does not exist.");
268 std::ifstream f(filename.string());
270 throw std::invalid_argument(
"Error reading prim from file '" +
272 "'. Does not contain valid input.");
274 while (!f.eof() && std::isspace(f.peek())) {
281 if (f.peek() ==
'{') {
284 }
catch (std::exception
const &ex) {
285 std::stringstream err_msg;
286 err_msg <<
"Error reading prim from JSON file '" << filename
289 throw std::invalid_argument(err_msg.str());
291 return read_prim(json, xtal_tol, _aniso_val_dict);
297 }
catch (std::exception
const &ex) {
298 std::stringstream err_msg;
299 err_msg <<
"Error reading prim from VASP-formatted file '" << filename
302 throw std::invalid_argument(err_msg.str());
313 if (_aniso_val_dict ==
nullptr) _aniso_val_dict = &default_aniso_val_dict;
319 from_json(latvec_transpose, json[
"lattice_vectors"]);
320 }
catch (std::exception &e) {
321 log() << e.what() << std::endl;
322 throw std::runtime_error(
323 "Error parsing global field \"lattice_vectors\" from prim JSON.");
333 prim.
set_title(json[
"title"].get<std::string>());
334 }
catch (std::exception &e) {
335 log() << e.what() << std::endl;
336 throw std::runtime_error(
337 "Error parsing global field \"title\" from prim JSON.");
344 std::map<std::string, xtal::DoFSet> _dof_map;
346 auto it = json[
"dofs"].
begin(), end_it = json[
"dofs"].
end();
347 for (; it != end_it; ++it) {
348 if (_dof_map.count(it.name()))
349 throw std::runtime_error(
350 "Error parsing global field \"dofs\" from prim JSON. DoF type " +
351 it.name() +
" cannot be repeated.");
359 _dof_map.emplace(std::make_pair(
362 }
catch (std::exception &e) {
363 log() << e.what() << std::endl;
364 throw std::runtime_error(
365 "Error parsing global field \"dofs\" from prim JSON. Failure for "
367 it.name() +
": " + e.what());
372 }
catch (std::exception &e) {
373 log() << e.what() << std::endl;
374 throw std::runtime_error(
375 "Error parsing global field \"dofs\" from prim JSON.");
381 from_json(mode, json[
"coordinate_mode"]);
382 }
catch (std::exception &e) {
383 log() << e.what() << std::endl;
384 throw std::runtime_error(
385 "Error parsing global field \"coordinate_mode\" from prim JSON.");
389 std::map<std::string, xtal::Molecule> mol_map;
398 auto it = json[
"species"].
begin();
399 auto it_end = json[
"species"].
end();
400 for (; it != it_end; ++it) {
401 std::string chem_name = it.
name();
402 it->get_if(chem_name,
"name");
406 from_json(mol_it->second, *it, f2c, *_aniso_val_dict);
409 }
catch (std::exception &e) {
410 log() << e.what() << std::endl;
411 throw std::runtime_error(
412 "Error parsing global field \"species\" from prim JSON.");
420 }
catch (std::exception &e) {
421 log() << e.what() << std::endl;
422 throw std::runtime_error(
423 "Error parsing global field \"basis\" from prim JSON.");
432 outfile.
open(filename);
448 json[
"title"] = prim.
title();
459 json[
"coordinate_mode"] =
"Fractional";
460 }
else if (mode ==
CART) {
461 c2f_mat.setIdentity();
462 json[
"coordinate_mode"] =
"Cartesian";
467 json[
"dofs"][_dof.first] = _dof.second;
472 for (
int i = 0; i < prim.
basis().size(); i++) {
473 if (!include_va && prim.
basis()[i].occupant_dof().size() == 1 &&
474 prim.
basis()[i].occupant_dof()[0].is_vacancy())
483 }
else if (mode ==
CART) {
489 if (prim.
basis()[i].dofs().size()) {
490 sjson[
"dofs"] = prim.
basis()[i].dofs();
494 prim.
basis()[i].occupant_dof().size()));
496 for (
int j = 0; j < prim.
basis()[i].occupant_dof().size(); j++) {
497 ojson[j] = mol_names[i][j];
498 if (prim.
basis()[i].occupant_dof()[j].name() != mol_names[i][j] ||
499 !prim.
basis()[i].occupant_dof()[j].is_atomic()) {
501 json[
"species"][mol_names[i][j]], c2f_mat);
510 prim =
read_prim(json, xtal_tol, _aniso_val_dict);
Parsing dictionary for obtaining the correct MoleculeAttribute given a name.
T const & lookup(const key_type &_name) const
Equivalent to find, but set 'home' and throws error with suggestion if.
Write to a temporary file to ensure a good write, then rename.
void close()
Closes stream, and if not a failed write, removes "file" and renames "file.tmp" to "file".
void open(fs::path name, std::string tmp_ext="tmp")
Opens "file.tmp" for writing, with intended final target "file".
fs::ofstream & ofstream()
Access underlying stream.
bool is_string() const
Check if string.
static jsonParser object()
Returns an empty json object.
iterator begin()
Returns const_iterator to beginning of JSON object or JSON array.
bool contains(const std::string &name) const
Return true if JSON object contains 'name'.
iterator end()
Returns iterator to end of JSON object or JSON array.
static jsonParser array()
Returns an empty json array.
const_iterator cend() const
Returns const_iterator to end of JSON object or JSON array.
jsonParser & put_obj()
Puts new empty JSON object.
jsonParser & put_array()
Puts new empty JSON array.
const_iterator cbegin() const
Returns const_iterator to beginning of JSON object or JSON array.
bool is_obj() const
Check if object type.
void print(std::ostream &stream, unsigned int indent=2, unsigned int prec=12) const
Print json to stream.
An atomic species associated with a position in space.
BasicStructure specifies the lattice and atomic basis of a crystal.
std::map< DoFKey, DoFSet > const & global_dofs() const
static BasicStructure from_poscar_stream(std::istream &poscar_stream, double tol=TOL)
const std::string & title() const
void set_title(std::string const &_title)
Set the title of the structure.
const Lattice & lattice() const
void push_back(Site const &_site, COORD_TYPE mode=CART)
Manually set the basis sites.
void set_global_dofs(std::map< DoFKey, DoFSet > const &new_dof_map)
Manually set the global DoFs.
const std::vector< Site > & basis() const
static COORD_TYPE CHECK()
get the current mode (call using COORD_MODE::CHECK())
const Lattice & home() const
Access the home lattice of the coordinate.
Coordinate_impl::CartCoordinate cart()
Set Cartesian coordinate vector and update fractional coordinate vector.
void set_lattice(const Lattice &new_lat, COORD_TYPE mode)
Change the home lattice of the coordinate, selecting one representation (either CART or FRAC) that re...
Coordinate_impl::FracCoordinate frac()
Set the fractional coordinate vector.
const Eigen::Matrix3d & lat_column_mat() const
3x3 matrix with lattice vectors as its columne
const Eigen::Matrix3d & inv_lat_column_mat() const
Inverse of Lattice::lat_column_mat() It is the transformation matrix 'C2F', such that f = C2F * c whe...
Class representing a Molecule.
std::map< std::string, SiteDoFSet > const & dofs() const
void set_dofs(std::map< std::string, SiteDoFSet > _dofs)
const std::vector< Molecule > & occupant_dof() const
void set_label(Index _new_label)
void set_allowed_occupants(const std::vector< Molecule > &new_occ_domain)
Index label() const
access m_label;
void set_value(Eigen::Ref< const Eigen::VectorXd > const &_value)
Eigen::VectorXd const & value() const
std::string to_string(ENUM val)
Return string representation of enum class.
void set_attributes(std::map< std::string, SpeciesAttribute > _attr)
Set all constitutent attributes of Molecule overwrites any existing attributes.
std::vector< AtomPosition > const & atoms() const
Const access of all contained AtomPositions.
static Molecule make_atom(std::string const &atom_name)
Return an atomic Molecule with specified name.
Eigen::Vector3d const & cart() const
Const access of Cartesian position of atom.
static Molecule make_unknown()
Return an atomic Molecule with specified name.
void set_atoms(std::vector< AtomPosition > _atoms)
set all constituent atoms of Molecule overwrites any existing atoms
void set_attributes(std::map< std::string, SpeciesAttribute > _attr)
std::string const & name() const
Designated name of Molecule (may be unrelated to constituent species)
std::string const & name() const
Const access of species name.
std::map< std::string, SpeciesAttribute > const & attributes() const
std::map< std::string, SpeciesAttribute > const & attributes() const
Returns dictionary of all constituent attributes of the Molecule Does not include attributes associat...
std::vector< std::vector< std::string > > allowed_molecule_unique_names(BasicStructure const &_struc)
Returns an Array of each possible Molecule in this Structure.
CASM::jsonParser & to_json_array(const Eigen::MatrixBase< Derived > &value, CASM::jsonParser &json)
Write Eigen Matrix with 1 row or 1 column to JSON array.
jsonParser & push_back(const T &value, Args &&... args)
T get(Args &&... args) const
Get data from json, using one of several alternatives.
IdentitySymRepBuilder Identity()
jsonParser & to_json(const ClexDescription &desc, jsonParser &json)
ParsingDictionary< AnisoValTraits > make_parsing_dictionary< AnisoValTraits >()
void write_prim(const xtal::BasicStructure &prim, fs::path filename, COORD_TYPE mode, bool include_va=false)
Write prim.json to file.
xtal::BasicStructure read_prim(fs::path filename, double xtal_tol, ParsingDictionary< AnisoValTraits > const *_aniso_val_dict=nullptr)
DoFSpecsType const & get(DoFKey const &key, BasisFunctionSpecs const &basis_function_specs)
void from_json(ClexDescription &desc, const jsonParser &json)
const COORD_TYPE COORD_DEFAULT
bool valid_index(Index i)
INDEX_TYPE Index
For long integer indexing:
static ReturnType from_json(const jsonParser &json)
Default from_json is equivalent to.