Source code for diffpy.structure.parsers.p_auto

#!/usr/bin/env python
##############################################################################
#
# diffpy.structure  by DANSE Diffraction group
#                   Simon J. L. Billinge
#                   (c) 2007 trustees of the Michigan State University.
#                   All rights reserved.
#
# File coded by:    Pavol Juhas
#
# See AUTHORS.txt for a list of people who contributed.
# See LICENSE_DANSE.txt for license information.
#
##############################################################################

"""Parser for automatic file format detection.

This Parser does not provide the the `toLines()` method.
"""

import os

from diffpy.structure.parsers import StructureParser, parser_index
from diffpy.structure.structureerrors import StructureFormatError


[docs] class P_auto(StructureParser): """Parser with automatic detection of structure format. This parser attempts to automatically detect the format of a given structure file and parse it accordingly. When successful, it sets its `format` attribute to the detected structure format. Parameters ---------- **kw : dict Keyword arguments for the structure parser. Attributes ---------- format : str Detected structure format. Initially set to "auto" and updated after successful detection of the structure format. pkw : dict Keyword arguments passed to the parser. """ def __init__(self, **kw): StructureParser.__init__(self) self.format = "auto" self.pkw = kw return # parseLines helpers def _getOrderedFormats(self): """Build a list of relevance ordered structure formats. This only works when `self.filename` has a known extension. """ from diffpy.structure.parsers import inputFormats ofmts = [fmt for fmt in inputFormats() if fmt != "auto"] if not self.filename: return ofmts # filename is defined here filebase = os.path.basename(self.filename) from fnmatch import fnmatch # loop over copy of ofmts for fmt in list(ofmts): pattern = parser_index[fmt]["file_pattern"] if pattern in ("*.*", "*"): continue anymatch = [1 for p in pattern.split("|") if fnmatch(filebase, p)] if anymatch: ofmts.remove(fmt) ofmts.insert(0, fmt) return ofmts
[docs] def parseLines(self, lines): """Detect format and create `Structure` instance from a list of lines. Set format attribute to the detected file format. Parameters ---------- lines : list List of lines with structure data. Returns ------- Structure `Structure` object. Raises ------ StructureFormatError """ return self._wrapParseMethod("parseLines", lines)
[docs] def parse(self, s): """Detect format and create `Structure` instance from a string. Set format attribute to the detected file format. Parameters ---------- s : str String with structure data. Returns ------- Structure `Structure` object. Raises ------ StructureFormatError """ return self._wrapParseMethod("parse", s)
[docs] def parseFile(self, filename): """Detect format and create Structure instance from an existing file. Set format attribute to the detected file format. Parameters ---------- filename : str Path to structure file. Returns ------- Structure `Structure` object. Raises ------ StructureFormatError If the structure format is unknown or invalid. IOError If the file cannot be read. """ self.filename = filename return self._wrapParseMethod("parseFile", filename)
def _wrapParseMethod(self, method, *args, **kwargs): """A helper evaluator method that try the specified parse method with each registered structure parser and return the first successful resul. Structure parsers that match structure file extension are tried first. Parameters ---------- method : str Name of the parse method to call. *args : tuple Positional arguments for the parse method. **kwargs : dict Keyword arguments for the parse method. Returns ------- Structure `Structure` object. Raises ------ StructureFormatError """ from diffpy.structure.parsers import getParser ofmts = self._getOrderedFormats() stru = None # try all parsers in sequence parsers_emsgs = [] for fmt in ofmts: p = getParser(fmt, **self.pkw) try: pmethod = getattr(p, method) stru = pmethod(*args, **kwargs) self.format = fmt break except StructureFormatError as err: parsers_emsgs.append("%s: %s" % (fmt, err)) except NotImplementedError: pass if stru is None: emsg = "\n".join( ["Unknown or invalid structure format.", "Errors per each tested structure format:"] + parsers_emsgs ) raise StructureFormatError(emsg) self.__dict__.update(p.__dict__) return stru
# End of class P_auto # Routines -------------------------------------------------------------------
[docs] def getParser(**kw): """Return a new instance of the automatic parser. Parameters ---------- **kw : dict Keyword arguments for the structure parser Returns ------- P_auto Instance of `P_auto`. """ return P_auto(**kw)