parser.py 3.46 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import os
import re
import logging
import importlib
from nomadcore.baseclasses import ParserInterface
logger = logging.getLogger("nomad")


class BigDFTParser(ParserInterface):
    """This class handles the initial setup before any parsing can happen. It
    determines which version of BigDFT was used to generate the output and then
    sets up a correct main parser.

    After the implementation has been setup, you can parse the files with
    parse().
    """
17
18
    def __init__(self, metainfo_to_keep=None, backend=None, default_units=None, metainfo_units=None, debug=True, log_level=logging.ERROR, store=True):
        super(BigDFTParser, self).__init__(metainfo_to_keep, backend, default_units, metainfo_units, debug, log_level, store)
19
20
21
22
23
24
25

    def setup_version(self):
        """Setups the version by looking at the output file and the version
        specified in it.
        """
        # Search for the BigDFT version specification. The correct parser is
        # initialized based on this information.
26
        regex_version = re.compile(" Version Number\s+: (\d\.\d)")
27
28
        version_id = None
        with open(self.parser_context.main_file, 'r') as outputfile:
29
30
31
32
            header = outputfile.read(50*80)
            for line in header.split("\n"):

                # Look for version definition
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
                result_version = regex_version.match(line)
                if result_version:
                    version_id = result_version.group(1).replace('.', '')

        if version_id is None:
            msg = "Could not find a version specification from the given main file."
            logger.exception(msg)
            raise RuntimeError(msg)

        # Setup the root folder to the fileservice that is used to access files
        dirpath, filename = os.path.split(self.parser_context.main_file)
        dirpath = os.path.abspath(dirpath)
        self.parser_context.file_service.setup_root_folder(dirpath)
        self.parser_context.file_service.set_file_id(filename, "output")

        # Setup the correct main parser based on the version id. If no match
        # for the version is found, use the main parser for NWChem 6.6
        self.setup_main_parser(version_id)

    def get_metainfo_filename(self):
        return "big_dft.nomadmetainfo.json"

    def get_parser_info(self):
        return {'name': 'big-dft-parser', 'version': '1.0'}

    def setup_main_parser(self, version_id):
        # Currently the version id is a pure integer, so it can directly be mapped
        # into a package name.
        base = "bigdftparser.versions.bigdft{}.mainparser".format(version_id)
        parser_module = None
        parser_class = None
        try:
            parser_module = importlib.import_module(base)
        except ImportError:
            logger.warning("Could not find a parser for version '{}'. Trying to default to the base implementation for BigDFT 1.8.0".format(version_id))
68
            base = "bigdftparser.versions.bigdft18.mainparser"
69
70
71
72
73
74
75
76
77
78
79
            try:
                parser_module = importlib.import_module(base)
            except ImportError:
                logger.exception("Could not find the module '{}'".format(base))
                raise
        try:
            class_name = "BigDFTMainParser"
            parser_class = getattr(parser_module, class_name)
        except AttributeError:
            logger.exception("A parser class '{}' could not be found in the module '[]'.".format(class_name, parser_module))
            raise
80
        self.main_parser = parser_class(self.parser_context)