Skip to content

Commit

Permalink
PsmlData: Add parsing of Z-valence from file
Browse files Browse the repository at this point in the history
  • Loading branch information
bosonie authored and sphuber committed Apr 30, 2022
1 parent d8125f6 commit ca3f065
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 4 deletions.
51 changes: 50 additions & 1 deletion src/aiida_pseudo/data/pseudo/psml.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
REGEX_ELEMENT = re.compile(r"""\s*(?P<element>[a-zA-Z]{1}[a-z]?)\s+.*""")


def parse_element(stream: typing.BinaryIO):
def parse_element(stream: typing.BinaryIO) -> str:
"""Parse the content of the PSML file to determine the element.
:param stream: a filelike object with the binary content of the file.
Expand All @@ -28,9 +28,36 @@ def parse_element(stream: typing.BinaryIO):
return element.capitalize()


def parse_z_valence(stream: typing.BinaryIO) -> int:
"""Parse the content of the PSML file to determine the Z valence.
:param stream: a filelike object with the binary content of the file.
:return: the Z valence.
"""
from xml.dom.minidom import parse

try:
xml = parse(stream)
z_valence = xml.getElementsByTagName('pseudo-atom-spec')[0].attributes['z-pseudo'].value
except (AttributeError, IndexError, KeyError) as exception:
raise ValueError(f'could not parse the Z valence from the PSML content: {exception}') from exception

try:
z_valence = float(z_valence)
except ValueError as exception:
raise ValueError(f'parsed value for the Z valence `{z_valence}` is not a valid number.') from exception

if int(z_valence) != z_valence:
raise ValueError(f'parsed value for the Z valence `{z_valence}` is not an integer.')

return int(z_valence)


class PsmlData(PseudoPotentialData):
"""Data plugin to represent a pseudo potential in PSML format."""

_key_z_valence = 'z_valence'

def set_file(self, source: typing.Union[str, pathlib.Path, typing.BinaryIO], filename: str = None, **kwargs): # pylint: disable=arguments-differ
"""Set the file content and parse other optional attributes from the content.
Expand All @@ -54,3 +81,25 @@ def set_file(self, source: typing.Union[str, pathlib.Path, typing.BinaryIO], fil
super().set_file(source, filename, **kwargs)
source.seek(0)
self.element = parse_element(source)
source.seek(0)
self.z_valence = parse_z_valence(source)

@property
def z_valence(self) -> typing.Optional[int]:
"""Return the Z valence.
:return: the Z valence.
"""
return self.base.attributes.get(self._key_z_valence, None)

@z_valence.setter
def z_valence(self, value: int):
"""Set the Z valence.
:param value: the Z valence.
:raises ValueError: if the value is not a positive integer.
"""
if not isinstance(value, int) or value < 0:
raise ValueError(f'`{value}` is not a positive integer')

self.base.attributes.set(self._key_z_valence, value)
3 changes: 3 additions & 0 deletions tests/data/pseudo/test_psml.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,16 @@ def test_set_file(filepath_pseudos, get_pseudo_potential_data):
"""
pseudo = get_pseudo_potential_data(element='Ar', entry_point='psml')
assert pseudo.element == 'Ar'
assert pseudo.z_valence == 8

with (filepath_pseudos('psml') / 'He.psml').open('rb') as handle:
pseudo.set_file(handle)
assert pseudo.element == 'He'
assert pseudo.z_valence == 2

pseudo.store()
assert pseudo.element == 'He'
assert pseudo.z_valence == 2

with pytest.raises(ModificationNotAllowed):
pseudo.set_file(handle)
2 changes: 1 addition & 1 deletion tests/fixtures/pseudos/psml/Ar.psml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="UTF-8" ?>
<psml version="1.1" energy_unit="hartree" length_unit="bohr">
<pseudo-atom-spec atomic-label="Ar" atomic-number="18"></pseudo-atom-spec>
<pseudo-atom-spec atomic-label="Ar" atomic-number="18" z-pseudo="8"></pseudo-atom-spec>
</psml>
2 changes: 1 addition & 1 deletion tests/fixtures/pseudos/psml/He.psml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="UTF-8" ?>
<psml version="1.1" energy_unit="hartree" length_unit="bohr">
<pseudo-atom-spec atomic-label="He" atomic-number="2"></pseudo-atom-spec>
<pseudo-atom-spec atomic-label="He" atomic-number="2" z-pseudo="2"></pseudo-atom-spec>
</psml>
2 changes: 1 addition & 1 deletion tests/fixtures/pseudos/psml/Ne.psml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="UTF-8" ?>
<psml version="1.1" energy_unit="hartree" length_unit="bohr">
<pseudo-atom-spec atomic-label="Ne" atomic-number="10"></pseudo-atom-spec>
<pseudo-atom-spec atomic-label="Ne" atomic-number="10" z-pseudo="8"></pseudo-atom-spec>
</psml>

0 comments on commit ca3f065

Please sign in to comment.