def parse_cif_ase(fileobj) -> Iterator[CIFBlock]: """Parse a CIF file using ase CIF parser.""" if isinstance(fileobj, str): with open(fileobj, 'rb') as fileobj: data = fileobj.read() else: data = fileobj.read() if isinstance(data, bytes): data = data.decode('latin1') data = format_unicode(data) lines = [e for e in data.split('\n') if len(e) > 0] if len(lines) > 0 and lines[0].rstrip() == '#\\#CIF_2.0': warnings.warn('CIF v2.0 file format detected; `ase` CIF reader might ' 'incorrectly interpret some syntax constructions, use ' '`pycodcif` reader instead') lines = [''] + lines[::-1] # all lines (reversed) while lines: line = lines.pop().strip() if not line or line.startswith('#'): continue yield parse_block(lines, line)
def parse_cif_ase(fileobj): """Parse a CIF file using ase CIF parser""" blocks = [] if isinstance(fileobj, basestring): fileobj = open(fileobj, 'rb') data = fileobj.read() if isinstance(data, bytes): data = data.decode('latin1') data = format_unicode(data) data = [e for e in data.split('\n') if len(e) > 0] if len(data) > 0 and data[0].rstrip() == '#\\#CIF_2.0': warnings.warn('CIF v2.0 file format detected; `ase` CIF reader might ' 'incorrectly interpret some syntax constructions, use ' '`pycodcif` reader instead') lines = [''] + data[::-1] # all lines (reversed) while True: if not lines: break line = lines.pop() line = line.strip() if not line or line.startswith('#'): continue blocks.append(parse_block(lines, line)) return blocks
def convert_value(value): """Convert CIF value string to corresponding python type.""" value = value.strip() if re.match('(".*")|(\'.*\')$', value): return format_unicode(value[1:-1]) elif re.match(r'[+-]?\d+$', value): return int(value) elif re.match(r'[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?$', value): return float(value) elif re.match(r'[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?\(\d+\)$', value): return float(value[:value.index('(')]) # strip off uncertainties elif re.match(r'[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?\(\d+$', value): warnings.warn('Badly formed number: "{0}"'.format(value)) return float(value[:value.index('(')]) # strip off uncertainties else: return format_unicode(value)