Commit f7e22b11 authored by Alvin Noe Ladines's avatar Alvin Noe Ladines Committed by Markus Scheidgen
Browse files

Converted vaspparser to use metainfo

parent c8b3592a
Pipeline #79754 passed with stages
in 42 minutes and 27 seconds
Subproject commit 8776a0bc7b32fb51e98ea8fe7af7d5630240edd3 Subproject commit 2c8b7763eae8a27e7c1ca3a8ce86533978f42f73
...@@ -48,8 +48,9 @@ def parse( ...@@ -48,8 +48,9 @@ def parse(
if isinstance(parser_backend, MSection): if isinstance(parser_backend, MSection):
backend = Backend(parser._metainfo_env, parser.domain) backend = Backend(parser._metainfo_env, parser.domain)
root_section = str(datamodel.domains[parser.domain]['root_section']) root_section = parser_backend.m_def.name
setattr(backend.entry_archive, root_section, parser_backend) section_def = getattr(datamodel.EntryArchive, root_section)
backend.entry_archive.m_add_sub_section(section_def, parser_backend)
backend.resource.add(parser_backend) backend.resource.add(parser_backend)
parser_backend = backend parser_backend = backend
......
...@@ -3439,6 +3439,11 @@ class section_run(MSection): ...@@ -3439,6 +3439,11 @@ class section_run(MSection):
repeats=True, repeats=True,
a_legacy=LegacyDefinition(name='section_system')) a_legacy=LegacyDefinition(name='section_system'))
section_workflow = SubSection(
sub_section=SectionProxy('section_workflow'),
repeats=True
)
class section_sampling_method(MSection): class section_sampling_method(MSection):
''' '''
...@@ -5575,4 +5580,37 @@ class section_XC_functionals(MSection): ...@@ -5575,4 +5580,37 @@ class section_XC_functionals(MSection):
a_legacy=LegacyDefinition(name='XC_functional_weight')) a_legacy=LegacyDefinition(name='XC_functional_weight'))
class section_workflow(MSection):
'''
Section containing the results of a workflow.
'''
m_def = Section(validate=False, a_legacy=LegacyDefinition(name='section_workflow'))
workflow_type = Quantity(
type=str,
shape=[],
description='''
The type of calculation workflow. Can be one of relaxation, elastic, phonon,
molecular dynamics.
''',
a_legacy=LegacyDefinition(name='workflow_type'))
relaxation_energy_tolerance = Quantity(
type=np.dtype(np.float64),
shape=[],
unit='joule',
description='''
The tolerance value in the energy between relaxation steps for convergence.
''',
a_legacy=LegacyDefinition(name='relaxation_energy_tolerance'))
workflow_final_calculation_ref = Quantity(
type=Reference(SectionProxy('section_single_configuration_calculation')),
shape=[],
description='''
Reference to last calculation step.
''')
m_package.__init_metainfo__() m_package.__init_metainfo__()
...@@ -244,11 +244,14 @@ class Backend(AbstractParserBackend): ...@@ -244,11 +244,14 @@ class Backend(AbstractParserBackend):
if section_def.extends_base_section: if section_def.extends_base_section:
section_def = section_def.base_sections[0] section_def = section_def.base_sections[0]
section = self.__open_sections.get((section_def, -1), None)
if not section:
section = self.open_sections[(section_def, -1)]
if isinstance(property_def, Quantity): if isinstance(property_def, Quantity):
return self.__open_sections[(section_def, -1)].m_get(property_def) return section.m_get(property_def)
elif isinstance(property_def, SubSection): elif isinstance(property_def, SubSection):
return self.__open_sections[(section_def, -1)].m_get_sub_sections(property_def) return section.m_get_sub_sections(property_def)
def metaInfoEnv(self): def metaInfoEnv(self):
if self.__legacy_env is None: if self.__legacy_env is None:
...@@ -302,6 +305,12 @@ class Backend(AbstractParserBackend): ...@@ -302,6 +305,12 @@ class Backend(AbstractParserBackend):
section = self.resolve_context(context_uri) section = self.resolve_context(context_uri)
self.__close(section) self.__close(section)
@property
def open_sections(self):
for section in self.entry_archive.m_all_contents():
self.__open(section)
return self.__open_sections
def __open(self, section): def __open(self, section):
if section.m_parent_index != -1: if section.m_parent_index != -1:
self.__open_sections[(section.m_def, section.m_parent_index)] = section self.__open_sections[(section.m_def, section.m_parent_index)] = section
...@@ -357,7 +366,9 @@ class Backend(AbstractParserBackend): ...@@ -357,7 +366,9 @@ class Backend(AbstractParserBackend):
if section_def.extends_base_section: if section_def.extends_base_section:
section_def = section_def.base_sections[0] section_def = section_def.base_sections[0]
section = self.__open_sections[(section_def, g_index)] section = self.__open_sections.get((section_def, g_index), None)
if not section:
section = self.open_sections[(section_def, g_index)]
return section, quantity_def return section, quantity_def
......
...@@ -24,6 +24,7 @@ from .artificial import EmptyParser, GenerateRandomParser, TemplateParser, Chaos ...@@ -24,6 +24,7 @@ from .artificial import EmptyParser, GenerateRandomParser, TemplateParser, Chaos
from eelsparser import EelsParser from eelsparser import EelsParser
from mpesparser import MPESParser from mpesparser import MPESParser
from aptfimparser import APTFIMParser from aptfimparser import APTFIMParser
from vaspparser import VASPParser
try: try:
# these packages are not available without parsing extra, which is ok, if the # these packages are not available without parsing extra, which is ok, if the
...@@ -121,18 +122,7 @@ parsers = [ ...@@ -121,18 +122,7 @@ parsers = [
# mainfile_contents_re=r'', # Empty regex since this code calls other DFT codes. # mainfile_contents_re=r'', # Empty regex since this code calls other DFT codes.
mainfile_name_re=(r'.*/phonopy-FHI-aims-displacement-0*1/control.in$') mainfile_name_re=(r'.*/phonopy-FHI-aims-displacement-0*1/control.in$')
), ),
LegacyParser( VASPParser(),
name='parsers/vasp', code_name='VASP', code_homepage='https://www.vasp.at/',
parser_class_name='vaspparser.VASPRunParser',
mainfile_mime_re=r'(application/.*)|(text/.*)',
mainfile_contents_re=(
r'^\s*<\?xml version="1\.0" encoding="ISO-8859-1"\?>\s*'
r'?\s*<modeling>'
r'?\s*<generator>'
r'?\s*<i name="program" type="string">\s*vasp\s*</i>'
r'?'),
supported_compressions=['gz', 'bz2', 'xz']
),
VaspOutcarParser( VaspOutcarParser(
name='parsers/vasp-outcar', code_name='VASP', code_homepage='https://www.vasp.at/', name='parsers/vasp-outcar', code_name='VASP', code_homepage='https://www.vasp.at/',
parser_class_name='vaspparser.VaspOutcarParser', parser_class_name='vaspparser.VaspOutcarParser',
......
...@@ -388,8 +388,9 @@ class Calc(Proc): ...@@ -388,8 +388,9 @@ class Calc(Proc):
if isinstance(self._parser_backend, MSection): if isinstance(self._parser_backend, MSection):
backend = Backend(parser._metainfo_env, parser.domain) backend = Backend(parser._metainfo_env, parser.domain)
root_section = datamodel.domains[parser.domain]['root_section'] root_section = self._parser_backend.m_def.name
setattr(backend.entry_archive, root_section, self._parser_backend) section_def = getattr(datamodel.EntryArchive, root_section)
backend.entry_archive.m_add_sub_section(section_def, self._parser_backend)
backend.resource.add(self._parser_backend) backend.resource.add(self._parser_backend)
self._parser_backend = backend self._parser_backend = backend
......
...@@ -289,13 +289,22 @@ def create_reference(data, pretty): ...@@ -289,13 +289,22 @@ def create_reference(data, pretty):
return json.dumps(data, separators=(',', ':')) return json.dumps(data, separators=(',', ':'))
def assert_parser_result(backend, error=False): @pytest.fixture(scope='function')
status, errors = backend.status def assert_parser_result(caplog):
assert status == 'ParseSuccess' def _assert(backend, error=False):
if error: status, errors = backend.status
assert len(errors) > 0 assert status == 'ParseSuccess'
else: if error:
assert errors is None or len(errors) == 0 if not errors:
errors = []
for record in caplog.get_records(when='call'):
if record.levelname in ['WARNING', 'ERROR', 'CRITICAL']:
errors.append(record.msg)
assert len(errors) > 0
else:
assert errors is None or len(errors) == 0
return _assert
def assert_parser_dir_unchanged(previous_wd, current_wd): def assert_parser_dir_unchanged(previous_wd, current_wd):
...@@ -308,8 +317,9 @@ def run_parser(parser_name, mainfile): ...@@ -308,8 +317,9 @@ def run_parser(parser_name, mainfile):
result = parser.run(mainfile, logger=utils.get_logger(__name__)) result = parser.run(mainfile, logger=utils.get_logger(__name__))
if isinstance(result, MSection): if isinstance(result, MSection):
backend = Backend(parser._metainfo_env, parser.domain) backend = Backend(parser._metainfo_env, parser.domain)
root_section = datamodel.domains[parser.domain]['root_section'] root_section = result.m_def.name
setattr(backend.entry_archive, root_section, result) section_def = getattr(datamodel.EntryArchive, root_section)
backend.entry_archive.m_add_sub_section(section_def, result)
backend.resource.add(result) backend.resource.add(result)
result = backend result = backend
result.domain = parser.domain result.domain = parser.domain
...@@ -357,7 +367,7 @@ def add_calculation_info(backend: Backend, **kwargs) -> Backend: ...@@ -357,7 +367,7 @@ def add_calculation_info(backend: Backend, **kwargs) -> Backend:
@pytest.mark.parametrize('parser_name, mainfile', parser_examples) @pytest.mark.parametrize('parser_name, mainfile', parser_examples)
def test_parser(parser_name, mainfile): def test_parser(parser_name, mainfile, assert_parser_result):
previous_wd = os.getcwd() # Get Working directory before parsing. previous_wd = os.getcwd() # Get Working directory before parsing.
parsed_example = run_parser(parser_name, mainfile) parsed_example = run_parser(parser_name, mainfile)
assert_parser_result(parsed_example) assert_parser_result(parsed_example)
...@@ -365,7 +375,7 @@ def test_parser(parser_name, mainfile): ...@@ -365,7 +375,7 @@ def test_parser(parser_name, mainfile):
assert_parser_dir_unchanged(previous_wd, current_wd=os.getcwd()) assert_parser_dir_unchanged(previous_wd, current_wd=os.getcwd())
def test_broken_xml_vasp(): def test_broken_xml_vasp(assert_parser_result):
parser_name, mainfile = 'parsers/vasp', 'tests/data/parsers/vasp/broken.xml' parser_name, mainfile = 'parsers/vasp', 'tests/data/parsers/vasp/broken.xml'
previous_wd = os.getcwd() # Get Working directory before parsing. previous_wd = os.getcwd() # Get Working directory before parsing.
parsed_example = run_parser(parser_name, mainfile) parsed_example = run_parser(parser_name, mainfile)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment