Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions src/nomad_simulation_parsers/parsers/vasp/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,16 @@
from .xml_parser import XMLArchiveWriter


def ref_reciprocal_lattice(archive: 'EntryArchive', logger: 'BoundLogger') -> None:
try:
d = archive.data
recip = d.model_method[0].numerical_settings[0].reciprocal_lattice_vectors
if recip is not None and len(recip) > 0:
d.outputs[0].electronic_eigenvalues[0].reciprocal_cell = recip
except (AttributeError, IndexError) as e:
logger.warning(f'Failed to set reciprocal lattice vectors: {e}')


class VASPParser(MatchingParser):
def parse(
self,
Expand All @@ -36,6 +46,8 @@ def parse(
archive_writer = XMLArchiveWriter()
archive_writer.write(mainfile, archive, logger, child_archives)

# ref_reciprocal_lattice(archive, logger)

# remove annotations
# TODO cache? put in close context
remove_mapping_annotations(vasp.general.Simulation.m_def)
49 changes: 43 additions & 6 deletions src/nomad_simulation_parsers/parsers/vasp/xml_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,31 @@ def logger(self):
def mix_alpha(self, mix: float, cond: bool) -> float:
return mix if cond else 0

def get_eigenvalues(self, array: list) -> dict[str, Any]:
if array is None:
return {}
transposed = np.transpose(array)
return dict(eigenvalues=transposed[0], occupations=transposed[1])
def get_bands(self, package: dict) -> dict[str, Any]:
"""
Extracts eigenvalues and occupations
from the VASP XML <eigenvalues.array> branch.
"""

def extract_layer(layers: list[dict | list], keys: list[str]) -> list:
"""
Extracts the specified keys from each layer in the layers list.
"""
if isinstance(layers, dict):
layers = [layers]

data = []
for lyr in layers:
if isinstance(lyr, dict):
for key in keys:
if key in lyr:
data.append(extract_layer(lyr[key], keys))
elif isinstance(lyr, list):
data.append(lyr)
return data

data = np.array(extract_layer(package.get('set', []), keys=['set', 'r'])[0])
return dict(eigenvalues=data[:, :, :, 0], occupations=data[:, :, :, 1])

def get_energy_contributions(
self, source: list[dict[str, Any]], **kwargs
Expand All @@ -58,7 +78,7 @@ def get_forces(self, source: dict[str, Any]) -> dict[str, Any]:
value = self.get_data(source, path='.varray.v')
if value is None:
return {}
return dict(forces=value, npoints=len(value), rank=[3])
return dict(forces=value, npoints=len(value)) # ! remove npoints

def reshape_array(self, source: np.ndarray, shape_rest: tuple = (3,)) -> np.ndarray:
if source is None:
Expand All @@ -67,6 +87,13 @@ def reshape_array(self, source: np.ndarray, shape_rest: tuple = (3,)) -> np.ndar
source, (np.size(source) // int(np.prod(shape_rest)), *shape_rest)
)

def get_dos(self, source: list[list[float]] | None) -> dict[str, Any]:
if source is None:
return {}

source = np.array([v.get('r') for k, v in source.items() if k == 'set'])
return dict(energies=source[0, :, 0], value=source[:, :, 1])


class XMLArchiveWriter(ArchiveWriter):
def write_to_archive(self) -> None:
Expand All @@ -75,9 +102,19 @@ def write_to_archive(self) -> None:

xml_parser = VasprunParser(filepath=self.mainfile)

# Process basic XML mappings first
data_parser.annotation_key = 'xml'
xml_parser.convert(data_parser)

# Process band structure mappings - append to create separate output
data_parser.annotation_key = 'xml_bands'
xml_parser.convert(data_parser, update_mode='append')

# Process DOS mappings - append to create another separate output
data_parser.annotation_key = 'xml_dos'
xml_parser.convert(data_parser, update_mode='append')

# Process remaining xml2 mappings
data_parser.annotation_key = 'xml2'
xml_parser.convert(data_parser)

Expand Down
4 changes: 2 additions & 2 deletions src/nomad_simulation_parsers/schema_packages/exciting.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,9 +172,9 @@ class ElectronicDensityOfStates(outputs.ElectronicDensityOfStates):
dos_xml=Mapper(mapper=('to_float', [r'.point[*]."@dos"']), unit='1/hartree')
)
)
outputs.ElectronicDensityOfStates.projected_dos.m_annotations[
"""outputs.ElectronicDensityOfStates.projected_dos.m_annotations[
MAPPING_ANNOTATION_KEY
] = dict(dos_xml=Mapper(mapper='dos.partialdos.diagram'))
] = dict(dos_xml=Mapper(mapper='dos.partialdos.diagram'))"""


try:
Expand Down
8 changes: 4 additions & 4 deletions src/nomad_simulation_parsers/schema_packages/fhiaims.py
Original file line number Diff line number Diff line change
Expand Up @@ -211,21 +211,21 @@ class ElectronicEigenvalues(properties.ElectronicEigenvalues):
).update(dict(text=Mapper(mapper='.occupations')))


class DOSProfile(properties.spectral_profile.DOSProfile):
"""class DOSProfile(properties.spectral_profile.DOSProfile):
### dos quantities
properties.spectral_profile.DOSProfile.value.m_annotations.setdefault(
MAPPING_ANNOTATION_KEY, {}
).update(dict(text_dos=Mapper(mapper='.values')))
).update(dict(text_dos=Mapper(mapper='.values')))"""


class ElectronicDensityOfStates(properties.spectral_profile.ElectronicDensityOfStates):
"""class ElectronicDensityOfStates(properties.spectral_profile.ElectronicDensityOfStates):
properties.spectral_profile.ElectronicDensityOfStates.value.m_annotations.setdefault(
MAPPING_ANNOTATION_KEY, {}
).update(dict(text_dos=Mapper(mapper='.values')))
### projected dos
properties.spectral_profile.ElectronicDensityOfStates.projected_dos.m_annotations.setdefault(
MAPPING_ANNOTATION_KEY, {}
).update(dict(text_dos=Mapper(mapper='.projected_dos')))
).update(dict(text_dos=Mapper(mapper='.projected_dos')))"""


class SimulationWorkflow(workflow.general.SimulationWorkflow):
Expand Down
67 changes: 45 additions & 22 deletions src/nomad_simulation_parsers/schema_packages/vasp.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
general.Simulation.m_def.m_annotations.setdefault(MAPPING_ANNOTATION_KEY, {}).update(
dict(
xml=MapperAnnotation(mapper='modeling'),
xml_bands=MapperAnnotation(mapper='modeling'),
xml_dos=MapperAnnotation(mapper='modeling'),
xml2=MapperAnnotation(mapper='modeling'),
outcar=MapperAnnotation(mapper='@'),
)
Expand Down Expand Up @@ -58,6 +60,8 @@ class Simulation(general.Simulation):
).update(
dict(
xml=MapperAnnotation(mapper='.calculation'),
xml_bands=MapperAnnotation(mapper='.calculation'),
xml_dos=MapperAnnotation(mapper='.calculation'),
xml2=MapperAnnotation(mapper='.calculation'),
outcar=MapperAnnotation(mapper='.calculation'),
)
Expand Down Expand Up @@ -132,13 +136,22 @@ class XCFunctional(model_method.XCFunctional):


class ModelMethod(model_method.ModelMethod):
# kspace numerical settings
numerical_settings.KSpace.m_def.m_annotations.setdefault(
MAPPING_ANNOTATION_KEY, {}
).update(dict(xml=MapperAnnotation(mapper='modeling.kpoints')))


class KSpace(numerical_settings.KSpace):
numerical_settings.KSpace.reciprocal_lattice_vectors.m_annotations.setdefault(
MAPPING_ANNOTATION_KEY, {}
).update(
dict(
xml=MapperAnnotation(
mapper='.generation.v[?starts_with("@name", \'genvec\')].__value',
unit='angstrom^-1',
),
)
)
numerical_settings.KSpace.k_mesh.m_annotations.setdefault(
MAPPING_ANNOTATION_KEY, {}
).update(dict(xml=MapperAnnotation(mapper='.@')))
Expand Down Expand Up @@ -253,17 +266,23 @@ class Outputs(outputs.Outputs):
outcar=MapperAnnotation(mapper=('get_forces', ['.@'])),
)
)
outputs.Outputs.electronic_eigenvalues.m_annotations.setdefault(
outputs.Outputs.electronic_band_structures.m_annotations.setdefault(
MAPPING_ANNOTATION_KEY, {}
).update(
dict(
xml=MapperAnnotation(mapper=('get_eigenvalues', ['eigenvalues'])),
xml2=MapperAnnotation(mapper=('get_eigenvalues', ['eigenvalues'])),
xml_bands=MapperAnnotation(mapper=('get_bands', ['.eigenvalues.array'])),
outcar=MapperAnnotation(
mapper=('get_eigenvalues', ['.eigenvalues', 'parameters'])
mapper=('get_bands', ['.eigenvalues', 'parameters'])
),
)
)
outputs.Outputs.electronic_dos.m_annotations.setdefault(
MAPPING_ANNOTATION_KEY, {}
).update(
dict(
xml_dos=MapperAnnotation(mapper=('get_dos', ['.dos.total.array.set'])),
)
)


class TotalEnergy(properties.energies.TotalEnergy):
Expand Down Expand Up @@ -330,36 +349,40 @@ class TotalForce(properties.forces.TotalForce):
)


class ElectronicEigenvalues(outputs.ElectronicEigenvalues):
outputs.ElectronicEigenvalues.n_bands.m_annotations.setdefault(
MAPPING_ANNOTATION_KEY, {}
).update(
dict(
xml=MapperAnnotation(mapper='length(.array.set.set.set[0].r)'),
xml2=MapperAnnotation(mapper='length(.array.set.set.set[0].r)'),
outcar=MapperAnnotation(mapper='.n_bands'),
)
)

# TODO This only works for non-spin pol
outputs.ElectronicEigenvalues.occupation.m_annotations.setdefault(
class ElectronicBandStructure(outputs.ElectronicBandStructure):
outputs.ElectronicBandStructure.occupation.m_annotations.setdefault(
MAPPING_ANNOTATION_KEY, {}
).update(
dict(
xml_bands=MapperAnnotation(mapper='.occupations'),
outcar=MapperAnnotation(mapper='.occupations'),
xml2=MapperAnnotation(mapper='.occupations'),
)
)
outputs.ElectronicEigenvalues.value.m_annotations.setdefault(
outputs.ElectronicBandStructure.value.m_annotations.setdefault(
MAPPING_ANNOTATION_KEY, {}
).update(
dict(
outcar=MapperAnnotation(mapper='.eigenvalues'),
xml2=MapperAnnotation(mapper='.eigenvalues'),
xml_bands=MapperAnnotation(mapper='.eigenvalues', unit='eV'),
outcar=MapperAnnotation(mapper='.eigenvalues', unit='eV'),
)
)


outputs.ElectronicDensityOfStates.value.m_annotations.setdefault(
MAPPING_ANNOTATION_KEY, {}
).update(
dict(
xml_dos=MapperAnnotation(mapper='.value', unit='1/eV'),
)
)
outputs.ElectronicDensityOfStates.energies.m_annotations.setdefault(
MAPPING_ANNOTATION_KEY, {}
).update(
dict(
xml_dos=MapperAnnotation(mapper='.energies', unit='eV'),
)
)

try:
m_package.__init_metainfo__()
except Exception:
Expand Down
Loading