Commit d3e8fcd1 authored by Markus Scheidgen's avatar Markus Scheidgen
Browse files

Use FairdiParser with parse function for VASP and experimental parsers.

parent 2490668f
Subproject commit d394f7ae375cd2355127abc67e07b1592f18d4f4 Subproject commit ed482b9956088163db9370dd5eee9b184c47870a
Subproject commit 6f0e7ec897284382d8ef30b0ee0372f010ce468f Subproject commit 136ab4f5c17e340009a14df8dbb72dc101acb1b1
Subproject commit aa701e8f2780419e7911972c8e2a16d188008902 Subproject commit d4083cdadd4b34b9d99cbeed579c56c09aa7606b
Subproject commit 2c8b7763eae8a27e7c1ca3a8ce86533978f42f73 Subproject commit 8c2e56b0d9d17b777b5fa6a61c8e2877444ab603
...@@ -43,17 +43,6 @@ def parse( ...@@ -43,17 +43,6 @@ def parse(
parser_backend = parser.run(mainfile_path, logger=logger) parser_backend = parser.run(mainfile_path, logger=logger)
from nomad.metainfo import MSection
from nomad.parsing.legacy import Backend
if isinstance(parser_backend, MSection):
backend = Backend(parser._metainfo_env, parser.domain)
root_section = parser_backend.m_def.name
section_def = getattr(datamodel.EntryArchive, root_section)
backend.entry_archive.m_add_sub_section(section_def, parser_backend)
backend.resource.add(parser_backend)
parser_backend = backend
if not parser_backend.status[0] == 'ParseSuccess': if not parser_backend.status[0] == 'ParseSuccess':
logger.error('parsing was not successful', status=parser_backend.status) logger.error('parsing was not successful', status=parser_backend.status)
...@@ -74,7 +63,7 @@ def normalize( ...@@ -74,7 +63,7 @@ def normalize(
if normalizer_instance.__class__.__name__ == normalizer) if normalizer_instance.__class__.__name__ == normalizer)
assert normalizer is not None, 'there is no normalizer %s' % str(normalizer) assert normalizer is not None, 'there is no normalizer %s' % str(normalizer)
normalizer_instance = typing.cast(typing.Callable, normalizer)(parser_backend) normalizer_instance = typing.cast(typing.Callable, normalizer)(parser_backend.entry_archive)
logger = logger.bind(normalizer=normalizer_instance.__class__.__name__) logger = logger.bind(normalizer=normalizer_instance.__class__.__name__)
logger.info('identified normalizer') logger.info('identified normalizer')
......
...@@ -18,12 +18,18 @@ import re ...@@ -18,12 +18,18 @@ import re
import importlib import importlib
from nomad.metainfo import Environment from nomad.metainfo import Environment
from nomad.datamodel import EntryArchive
class Parser(metaclass=ABCMeta): class Parser(metaclass=ABCMeta):
''' '''
Instances specify a parser. It allows to find *main files* from given uploaded Instances specify a parser. It allows to find *main files* from given uploaded
and extracted files. Further, allows to run the parser on those 'main files'. and extracted files. Further, allows to run the parser on those 'main files'.
TODO: There are currently two "run" functions. :func:`run` and :func:`parse`.
Because we are in the middle of transitioning out of the backend dependence we currently
have both, where 'run' creates a backend and 'parse' simply gets an archive that the
parser is supposed to populate. Eventually, we will only have the 'parse' function.
''' '''
name = "parsers/parser" name = "parsers/parser"
...@@ -64,6 +70,19 @@ class Parser(metaclass=ABCMeta): ...@@ -64,6 +70,19 @@ class Parser(metaclass=ABCMeta):
The used :class:`Backend` with status information and result data. The used :class:`Backend` with status information and result data.
''' '''
def parse(self, mainfile: str, archive: EntryArchive, logger=None) -> None:
'''
Runs the parser on the given mainfile and populates the result in the given
archive root_section. It allows to be run repeatedly for different mainfiles.
Args:
mainfile: A path to a mainfile that this parser can parse.
archive: An instance of the section :class:`EntryArchive`. It might contain
a ``section_metadata`` with information about the entry.
logger: A optional logger
'''
pass
class BrokenParser(Parser): class BrokenParser(Parser):
''' '''
...@@ -156,28 +175,22 @@ class MatchingParser(Parser): ...@@ -156,28 +175,22 @@ class MatchingParser(Parser):
class FairdiParser(MatchingParser): class FairdiParser(MatchingParser):
def __init__(self, parser_class_name: str, *args, **kwargs):
super().__init__(*args, **kwargs)
self.parser_class_name = parser_class_name
module_name = self.parser_class_name.split('.')[:-1]
parser_class_name = self.parser_class_name.split('.')[-1]
self.__parser_impl = module_name, parser_class_name
self.__parser_class = None
@property
def parser_class(self):
if self.__parser_class is None:
module_name, parser_class_name = self.__parser_impl
module = importlib.import_module('.'.join(module_name))
self.__parser_class = getattr(module, parser_class_name)
return self.__parser_class
def run(self, mainfile: str, logger=None): def run(self, mainfile: str, logger=None):
parser = self.parser_class() # pylint: disable=not-callable from .legacy import Backend
root_section = parser.parse(mainfile, logger) python_module = importlib.import_module(self.__module__ + '.metainfo')
return root_section metainfo = getattr(python_module, 'm_env')
backend = Backend(metainfo, domain=self.domain, logger=logger)
self.parse(mainfile, backend.entry_archive, logger=logger)
return backend
def parse(self, mainfile: str, archive: EntryArchive, logger=None):
raise NotImplementedError()
@classmethod
def main(cls, mainfile):
archive = EntryArchive()
cls().parse(mainfile, archive) # pylint: disable=no-value-for-parameter
return archive
class MissingParser(MatchingParser): class MissingParser(MatchingParser):
......
...@@ -46,7 +46,6 @@ from nomad.archive import query_archive ...@@ -46,7 +46,6 @@ from nomad.archive import query_archive
from nomad.datamodel.encyclopedia import ( from nomad.datamodel.encyclopedia import (
EncyclopediaMetadata, EncyclopediaMetadata,
) )
from nomad.metainfo import MSection
import phonopyparser.metainfo import phonopyparser.metainfo
...@@ -386,14 +385,6 @@ class Calc(Proc): ...@@ -386,14 +385,6 @@ class Calc(Proc):
self._parser_backend = parser.run( self._parser_backend = parser.run(
self.upload_files.raw_file_object(self.mainfile).os_path, logger=logger) self.upload_files.raw_file_object(self.mainfile).os_path, logger=logger)
if isinstance(self._parser_backend, MSection):
backend = Backend(parser._metainfo_env, parser.domain)
root_section = self._parser_backend.m_def.name
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)
self._parser_backend = backend
except Exception as e: except Exception as e:
self.fail('parser failed with exception', exc_info=e, error=str(e), **context) self.fail('parser failed with exception', exc_info=e, error=str(e), **context)
return return
......
...@@ -23,7 +23,6 @@ from nomad import utils, files, datamodel ...@@ -23,7 +23,6 @@ from nomad import utils, files, datamodel
from nomad.parsing import BrokenParser, Backend from nomad.parsing import BrokenParser, Backend
from nomad.parsing.parsers import parser_dict, match_parser from nomad.parsing.parsers import parser_dict, match_parser
from nomad.app import dump_json from nomad.app import dump_json
from nomad.metainfo import MSection
parser_examples = [ parser_examples = [
('parsers/random', 'test/data/parsers/random_0'), ('parsers/random', 'test/data/parsers/random_0'),
...@@ -259,13 +258,7 @@ def assert_parser_dir_unchanged(previous_wd, current_wd): ...@@ -259,13 +258,7 @@ def assert_parser_dir_unchanged(previous_wd, current_wd):
def run_parser(parser_name, mainfile): def run_parser(parser_name, mainfile):
parser = parser_dict[parser_name] parser = parser_dict[parser_name]
result = parser.run(mainfile, logger=utils.get_logger(__name__)) result = parser.run(mainfile, logger=utils.get_logger(__name__))
if isinstance(result, MSection):
backend = Backend(parser._metainfo_env, parser.domain)
root_section = result.m_def.name
section_def = getattr(datamodel.EntryArchive, root_section)
backend.entry_archive.m_add_sub_section(section_def, result)
backend.resource.add(result)
result = backend
result.domain = parser.domain result.domain = parser.domain
return add_calculation_info(result, parser_name=parser_name) return add_calculation_info(result, parser_name=parser_name)
......
Supports Markdown
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