Skip to content

Commit

Permalink
Merge pull request #1131 from pyiron/vasp_parser
Browse files Browse the repository at this point in the history
Refactor the VASP collect_output() parser
  • Loading branch information
jan-janssen authored Aug 21, 2023
2 parents b0c4456 + db0474b commit 16a085a
Show file tree
Hide file tree
Showing 6 changed files with 320 additions and 137 deletions.
120 changes: 73 additions & 47 deletions pyiron_atomistics/atomistics/structure/atoms.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
from pyiron_atomistics.atomistics.structure.periodic_table import (
PeriodicTable,
ChemicalElement,
chemical_element_dict_to_hdf,
)
from pyiron_base import state, deprecate
from collections.abc import Sequence
Expand Down Expand Up @@ -447,6 +448,54 @@ def copy(self):
"""
return self.__copy__()

def to_dict(self):
hdf_structure = {
"TYPE": str(type(self)),
"units": self.units,
"dimension": self.dimension,
"positions": self.positions,
"info": self.info,
}
for el in self.species:
if isinstance(el.tags, dict):
if "new_species" not in hdf_structure.keys():
hdf_structure["new_species"] = {}
hdf_structure["new_species"][el.Abbreviation] = el.to_dict()
hdf_structure["species"] = [el.Abbreviation for el in self.species]
hdf_structure["indices"] = self.indices

for tag, value in self.arrays.items():
if tag in ["positions", "numbers", "indices"]:
continue
if "tags" not in hdf_structure.keys():
hdf_structure["tags"] = {}
hdf_structure["tags"][tag] = value.tolist()

if self.cell is not None:
# Convert ASE cell object to numpy array before storing
hdf_structure["cell"] = {"cell": np.array(self.cell), "pbc": self.pbc}

if self.has("initial_magmoms"):
hdf_structure["spins"] = self.spins
# potentials with explicit bonds (TIP3P, harmonic, etc.)
if self.bonds is not None:
hdf_structure["explicit_bonds"] = self.bonds

if self._high_symmetry_points is not None:
hdf_structure["high_symmetry_points"] = self._high_symmetry_points

if self._high_symmetry_path is not None:
hdf_structure["high_symmetry_path"] = self._high_symmetry_path

if self.calc is not None:
calc_dict = self.calc.todict()
calc_dict["label"] = self.calc.label
calc_dict["class"] = (
self.calc.__class__.__module__ + "." + self.calc.__class__.__name__
)
hdf_structure["calculator"] = calc_dict
return hdf_structure

def to_hdf(self, hdf, group_name="structure"):
"""
Save the object in a HDF5 file
Expand All @@ -457,53 +506,7 @@ def to_hdf(self, hdf, group_name="structure"):
Group name with which the object should be stored. This same name should be used to retrieve the object
"""
# import time
with hdf.open(group_name) as hdf_structure:
hdf_structure["TYPE"] = str(type(self))
for el in self.species:
if isinstance(el.tags, dict):
with hdf_structure.open("new_species") as hdf_species:
el.to_hdf(hdf_species)
hdf_structure["species"] = [el.Abbreviation for el in self.species]
hdf_structure["indices"] = self.indices

with hdf_structure.open("tags") as hdf_tags:
for tag, value in self.arrays.items():
if tag in ["positions", "numbers", "indices"]:
continue
hdf_tags[tag] = value.tolist()
hdf_structure["units"] = self.units
hdf_structure["dimension"] = self.dimension

if self.cell is not None:
with hdf_structure.open("cell") as hdf_cell:
# Convert ASE cell object to numpy array before storing
hdf_cell["cell"] = np.array(self.cell)
hdf_cell["pbc"] = self.pbc

# hdf_structure["coordinates"] = self.positions # "Atomic coordinates"
hdf_structure["positions"] = self.positions # "Atomic coordinates"
if self.has("initial_magmoms"):
hdf_structure["spins"] = self.spins
# potentials with explicit bonds (TIP3P, harmonic, etc.)
if self.bonds is not None:
hdf_structure["explicit_bonds"] = self.bonds

if self._high_symmetry_points is not None:
hdf_structure["high_symmetry_points"] = self._high_symmetry_points

if self._high_symmetry_path is not None:
hdf_structure["high_symmetry_path"] = self._high_symmetry_path

hdf_structure["info"] = self.info

if self.calc is not None:
calc_dict = self.calc.todict()
calc_dict["label"] = self.calc.label
calc_dict["class"] = (
self.calc.__class__.__module__ + "." + self.calc.__class__.__name__
)
hdf_structure["calculator"] = calc_dict
structure_dict_to_hdf(data_dict=self.to_dict(), hdf=hdf, group_name=group_name)

def from_hdf(self, hdf, group_name="structure"):
"""
Expand Down Expand Up @@ -3439,3 +3442,26 @@ def __setitem__(self, key, value):
)
for i, el in enumerate(replace_elements):
self._structure[index_array[i]] = el


def structure_dict_to_hdf(data_dict, hdf, group_name="structure"):
with hdf.open(group_name) as hdf_structure:
for k, v in data_dict.items():
if k not in ["new_species", "cell", "tags"]:
hdf_structure[k] = v

if "new_species" in data_dict.keys():
for el, el_dict in data_dict["new_species"].items():
chemical_element_dict_to_hdf(
data_dict=el_dict, hdf=hdf_structure, group_name="new_species/" + el
)

dict_group_to_hdf(data_dict=data_dict, hdf=hdf_structure, group="tags")
dict_group_to_hdf(data_dict=data_dict, hdf=hdf_structure, group="cell")


def dict_group_to_hdf(data_dict, hdf, group):
if group in data_dict.keys():
with hdf.open(group) as hdf_tags:
for k, v in data_dict[group].items():
hdf_tags[k] = v
33 changes: 23 additions & 10 deletions pyiron_atomistics/atomistics/structure/periodic_table.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,22 +154,25 @@ def add_tags(self, tag_dic):
"""
(self.sub["tags"]).update(tag_dic)

def to_dict(self):
hdf_el = {}
# TODO: save all parameters that are different from the parent (e.g. modified mass)
if self.Parent is not None:
self._dataset = {"Parameter": ["Parent"], "Value": [self.Parent]}
hdf_el["elementData"] = self._dataset
# "Dictionary of element tag static"
hdf_el["tagData"] = {key: self.tags[key] for key in self.tags.keys()}
return hdf_el

def to_hdf(self, hdf):
"""
saves the element with his parameters into his hdf5 job file
Args:
hdf (Hdfio): Hdfio object which will be used
"""
with hdf.open(self.Abbreviation) as hdf_el: # "Symbol of the chemical element"
# TODO: save all parameters that are different from the parent (e.g. modified mass)
if self.Parent is not None:
self._dataset = {"Parameter": ["Parent"], "Value": [self.Parent]}
hdf_el["elementData"] = self._dataset
with hdf_el.open(
"tagData"
) as hdf_tag: # "Dictionary of element tag static"
for key in self.tags.keys():
hdf_tag[key] = self.tags[key]
chemical_element_dict_to_hdf(
data_dict=self.to_dict(), hdf=hdf, group_name=self.Abbreviation
)

def from_hdf(self, hdf):
"""
Expand Down Expand Up @@ -424,3 +427,13 @@ def _get_periodic_table_df(file_name):
+ file_name
+ " supported file formats are csv, h5."
)


def chemical_element_dict_to_hdf(data_dict, hdf, group_name):
with hdf.open(group_name) as hdf_el:
if "elementData" in data_dict.keys():
hdf_el["elementData"] = data_dict["elementData"]
with hdf_el.open("tagData") as hdf_tag:
if "tagData" in data_dict.keys():
for k, v in data_dict["tagData"].items():
hdf_tag[k] = v
63 changes: 44 additions & 19 deletions pyiron_atomistics/dft/waves/electronic.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@

import numpy as np

from pyiron_atomistics.atomistics.structure.atoms import Atoms
from pyiron_atomistics.atomistics.structure.atoms import (
Atoms,
structure_dict_to_hdf,
dict_group_to_hdf,
)
from pyiron_atomistics.dft.waves.dos import Dos

__author__ = "Sudarsan Surendralal"
Expand Down Expand Up @@ -481,24 +485,33 @@ def to_hdf(self, hdf, group_name="electronic_structure"):
hdf: Path to the hdf5 file/group in the file
group_name: Name of the group under which the attributes are o be stored
"""
with hdf.open(group_name) as h_es:
h_es["TYPE"] = str(type(self))
if self.structure is not None:
self.structure.to_hdf(h_es)
h_es["k_points"] = self.kpoint_list
h_es["k_weights"] = self.kpoint_weights
h_es["eig_matrix"] = self.eigenvalue_matrix
h_es["occ_matrix"] = self.occupancy_matrix
if self.efermi is not None:
h_es["efermi"] = self.efermi
with h_es.open("dos") as h_dos:
h_dos["energies"] = self.dos_energies
h_dos["tot_densities"] = self.dos_densities
h_dos["int_densities"] = self.dos_idensities
if self.grand_dos_matrix is not None:
h_dos["grand_dos_matrix"] = self.grand_dos_matrix
if self.resolved_densities is not None:
h_dos["resolved_densities"] = self.resolved_densities
electronic_structure_dict_to_hdf(
data_dict=self.to_dict(), hdf=hdf, group_name=group_name
)

def to_dict(self):
h_es = {
"TYPE": str(type(self)),
"k_points": self.kpoint_list,
"k_weights": self.kpoint_weights,
"eig_matrix": self.eigenvalue_matrix,
"occ_matrix": self.occupancy_matrix,
}
if self.structure is not None:
h_es["structure"] = self.structure.to_dict()
if self.efermi is not None:
h_es["efermi"] = self.efermi

h_es["dos"] = {
"energies": self.dos_energies,
"tot_densities": self.dos_densities,
"int_densities": self.dos_idensities,
}
if self.grand_dos_matrix is not None:
h_es["dos"]["grand_dos_matrix"] = self.grand_dos_matrix
if self.resolved_densities is not None:
h_es["dos"]["resolved_densities"] = self.resolved_densities
return h_es

def from_hdf(self, hdf, group_name="electronic_structure"):
"""
Expand Down Expand Up @@ -841,3 +854,15 @@ def resolved_dos_matrix(self):
@resolved_dos_matrix.setter
def resolved_dos_matrix(self, val):
self._resolved_dos_matrix = val


def electronic_structure_dict_to_hdf(data_dict, hdf, group_name):
with hdf.open(group_name) as h_es:
for k, v in data_dict.items():
if k not in ["structure", "dos"]:
h_es[k] = v

if "structure" in data_dict.keys():
structure_dict_to_hdf(data_dict=data_dict["structure"], hdf=h_es)

dict_group_to_hdf(data_dict=data_dict, hdf=h_es, group="dos")
Loading

0 comments on commit 16a085a

Please sign in to comment.