Hide keyboard shortcuts

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. 

7 

8"""A reader for XYZ (Cartesian coordinate) files.""" 

9 

10from cclib.io import filereader 

11from cclib.parser.data import ccData 

12from cclib.parser.utils import PeriodicTable 

13 

14 

15class XYZ(filereader.Reader): 

16 """A reader for XYZ (Cartesian coordinate) files.""" 

17 

18 def __init__(self, source, *args, **kwargs): 

19 super(XYZ, self).__init__(source, *args, **kwargs) 

20 

21 self.pt = PeriodicTable() 

22 

23 def parse(self): 

24 super(XYZ, self).parse() 

25 

26 self.generate_repr() 

27 

28 return self.data 

29 

30 def generate_repr(self): 

31 """Convert the raw contents of the source into the internal representation.""" 

32 

33 assert hasattr(self, 'filecontents') 

34 

35 it = iter(self.filecontents.splitlines()) 

36 

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 

44 

45 all_atomcoords = [] 

46 comments = [] 

47 

48 while True: 

49 

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]) 

57 

58 comments.append(next(it)) 

59 

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 

67 

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) 

73 

74 except StopIteration: 

75 break 

76 

77 attributes = { 

78 'natom': natom, 

79 'atomnos': atomnos, 

80 'atomcoords': all_atomcoords, 

81 'metadata': {"comments": comments}, 

82 } 

83 

84 self.data = ccData(attributes)