exa-analytics / exatomic

A unified platform for theoretical and computational chemists
https://exa-analytics.github.io/exatomic
Apache License 2.0
19 stars 12 forks source link

ADF parsers for new version #261

Closed herbertludowieg closed 1 year ago

herbertludowieg commented 2 years ago

Is your feature request related to a problem? Please describe. ADF/SCM seems to be making changes to the way their outputs are printing as they have transitioned into their new AMS driver. While there are a lot of similarities between the outputs for the new and old versions there are still changes that are not backwards compatible.

Describe the solution you'd like Implement new parsers for the AMS/ADF driver. Along with this I think it's a good idea to create a parser that can handle the different modules that can be used like NMR and ADF. This would allow us to separate the parsing functions to what is pertinent to each of the modules and make the code more readable. An example of this is the current implementation of the adf.Output.parse_atom method as it has multiple if statements if one uses the ADF or NMR modules.

Additional context Not sure if it would be better to have the classes in their own files, such as nmr_output.py, adf_output.py, and ams_output.py. Open to additional ideas.

Current work Currently, I have a working parser that stores the module that we are working with in the meta class attribute and we call the methods from the parsing class.

class Output(six.with_metaclass(OutMeta, Editor)):
    def _parse_data(self, attr):
        try:
            parser = getattr(self.meta['module'], attr)
        except AttributeError as e:
            if str(e).endswith("'"+attr+"'"):
                return
        parser(self)

    def parse_atom(self):
        self._parse_data('parse_atom')

    def __init__(self, file, *args, **kwargs):
        ed = _Editor(file)
        _readf = "A D F"
        _renmr = "N M R"
        _reams = "A M S"
        found = ed.find(_readf, _renmr, _reams, keys_only=True)
        super(Output, self).__init__(file, *args, **kwargs)
        if found[_renmr]:
            self.meta.update({'module': NMR})
        elif found[_readf]:
            self.meta.update({'module': ADF})
        elif found[_reams]:
            self.meta.update({'module': AMS})
        else:
            raise ValueError("Could not identify program from SCM")