Coverage for cclib/io/xyzreader.py : 98%
Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# -*- coding: utf-8 -*-
2#
3# Copyright (c) 2017, the cclib development team
4#
5# This file is part of cclib (http://cclib.github.io) and is distributed under
6# the terms of the BSD 3-Clause License.
8"""A reader for XYZ (Cartesian coordinate) files."""
10from cclib.io import filereader
11from cclib.parser.data import ccData
12from cclib.parser.utils import PeriodicTable
15class XYZ(filereader.Reader):
16 """A reader for XYZ (Cartesian coordinate) files."""
18 def __init__(self, source, *args, **kwargs):
19 super(XYZ, self).__init__(source, *args, **kwargs)
21 self.pt = PeriodicTable()
23 def parse(self):
24 super(XYZ, self).parse()
26 self.generate_repr()
28 return self.data
30 def generate_repr(self):
31 """Convert the raw contents of the source into the internal representation."""
33 assert hasattr(self, 'filecontents')
35 it = iter(self.filecontents.splitlines())
37 # Ordering of lines:
38 # 1. number of atoms
39 # 2. comment line
40 # 3. line of at least 4 columns: 1 is atomic symbol (str), 2-4 are atomic coordinates (float)
41 # repeat for numver of atoms
42 # (4. optional blank line)
43 # repeat for multiple sets of coordinates
45 all_atomcoords = []
46 comments = []
48 while True:
50 try:
51 line = next(it)
52 if line.strip() == '':
53 line = next(it)
54 tokens = line.split()
55 assert len(tokens) >= 1
56 natom = int(tokens[0])
58 comments.append(next(it))
60 lines = []
61 for _ in range(natom):
62 line = next(it)
63 tokens = line.split()
64 assert len(tokens) >= 4
65 lines.append(tokens)
66 assert len(lines) == natom
68 atomsyms = [line[0] for line in lines]
69 atomnos = [self.pt.number[atomsym] for atomsym in atomsyms]
70 atomcoords = [line[1:4] for line in lines]
71 # Everything beyond the fourth column is ignored.
72 all_atomcoords.append(atomcoords)
74 except StopIteration:
75 break
77 attributes = {
78 'natom': natom,
79 'atomnos': atomnos,
80 'atomcoords': all_atomcoords,
81 'metadata': {"comments": comments},
82 }
84 self.data = ccData(attributes)