pyemaps 2.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. pyemaps/COPYING +798 -0
  2. pyemaps/CifFile/CifFile_module.py +3117 -0
  3. pyemaps/CifFile/StarFile.py +2496 -0
  4. pyemaps/CifFile/TypeContentsParser.py +82 -0
  5. pyemaps/CifFile/YappsStarParser_1_0.py +289 -0
  6. pyemaps/CifFile/YappsStarParser_1_1.py +288 -0
  7. pyemaps/CifFile/YappsStarParser_2_0.py +369 -0
  8. pyemaps/CifFile/YappsStarParser_STAR2.py +382 -0
  9. pyemaps/CifFile/__init__.py +7 -0
  10. pyemaps/CifFile/drel/__init__.py +1 -0
  11. pyemaps/CifFile/drel/drel_ast_yacc.py +582 -0
  12. pyemaps/CifFile/drel/drel_lex.py +228 -0
  13. pyemaps/CifFile/drel/drel_runtime.py +126 -0
  14. pyemaps/CifFile/drel/parsetab.py +185 -0
  15. pyemaps/CifFile/drel/py_from_ast.py +628 -0
  16. pyemaps/CifFile/parsetab.py +185 -0
  17. pyemaps/CifFile/yapps3_compiled_rt.py +390 -0
  18. pyemaps/README.md +201 -0
  19. pyemaps/__config__.py +91 -0
  20. pyemaps/__init__.py +233 -0
  21. pyemaps/__main__.py +219 -0
  22. pyemaps/__version__.py +1 -0
  23. pyemaps/cdata/Aluminium.xtl +4 -0
  24. pyemaps/cdata/AluminiumOxide.xtl +5 -0
  25. pyemaps/cdata/Aluminium_FCC.xtl +4 -0
  26. pyemaps/cdata/BariumTitanate_180k.xtl +6 -0
  27. pyemaps/cdata/BariumTitanate_270k.xtl +7 -0
  28. pyemaps/cdata/BariumTitanate_Tetra.xtl +7 -0
  29. pyemaps/cdata/BiMnO3.xtl +27 -0
  30. pyemaps/cdata/Boron_Tetra.xtl +8 -0
  31. pyemaps/cdata/CadmiumSelenide_Hex.xtl +5 -0
  32. pyemaps/cdata/CadmiumSulfide_Cubic.xtl +5 -0
  33. pyemaps/cdata/CadmiumSulfide_Hex.xtl +5 -0
  34. pyemaps/cdata/Chromium_BCC.xtl +4 -0
  35. pyemaps/cdata/CoSb3_Skutterudite.xtl +5 -0
  36. pyemaps/cdata/CopperOxide.xtl +5 -0
  37. pyemaps/cdata/Copper_FCC.xtl +4 -0
  38. pyemaps/cdata/Cu2O_Cuprite.xtl +5 -0
  39. pyemaps/cdata/Diamond.xtl +4 -0
  40. pyemaps/cdata/ErbiumPyrogermanate.xtl +9 -0
  41. pyemaps/cdata/FePd_Tetra.xtl +5 -0
  42. pyemaps/cdata/FeS2_Pyrite.xtl +15 -0
  43. pyemaps/cdata/GalliumAntimonide.xtl +5 -0
  44. pyemaps/cdata/GalliumArsenide.xtl +5 -0
  45. pyemaps/cdata/GalliumNitride.xtl +5 -0
  46. pyemaps/cdata/Germanium.xtl +4 -0
  47. pyemaps/cdata/Gold_FCC.xtl +4 -0
  48. pyemaps/cdata/IndiumArsenide.xtl +5 -0
  49. pyemaps/cdata/LaMnO3.xtl +7 -0
  50. pyemaps/cdata/LeadZirconateTitanate.xtl +8 -0
  51. pyemaps/cdata/Li2MnO3.xtl +13 -0
  52. pyemaps/cdata/NaFeO2.xtl +6 -0
  53. pyemaps/cdata/Nb3Sn.xtl +5 -0
  54. pyemaps/cdata/Pentacene.xtl +39 -0
  55. pyemaps/cdata/Silicon.xtl +4 -0
  56. pyemaps/cdata/StrontiumTitanate.xtl +6 -0
  57. pyemaps/cdata/TelluriumDioxide.xtl +5 -0
  58. pyemaps/cdata/TinDioxide_RT.xtl +5 -0
  59. pyemaps/cdata/TitaniumDioxide_Anatase.xtl +5 -0
  60. pyemaps/cdata/TitaniumDioxide_Rutile.xtl +5 -0
  61. pyemaps/cdata/TungstenDiselenide.xtl +5 -0
  62. pyemaps/cdata/VanadiumDioxide_RT.xtl +6 -0
  63. pyemaps/cdata/ZincOxide.xtl +5 -0
  64. pyemaps/cdata/Zinc_HCP.xtl +4 -0
  65. pyemaps/cdata/ZirconiumNitride.xtl +5 -0
  66. pyemaps/cdata/limno2.xtl +6 -0
  67. pyemaps/crystals.py +1415 -0
  68. pyemaps/ddiffs.py +147 -0
  69. pyemaps/diffract/__init__.py +70 -0
  70. pyemaps/diffract/bloch_dec.py +779 -0
  71. pyemaps/diffract/csf_dec.py +242 -0
  72. pyemaps/diffract/dif_dec.py +519 -0
  73. pyemaps/diffract/dpgen_dec.py +175 -0
  74. pyemaps/diffract/mxtal_dec.py +201 -0
  75. pyemaps/diffract/powder_dec.py +137 -0
  76. pyemaps/diffract/stereo_dec.py +111 -0
  77. pyemaps/display.py +791 -0
  78. pyemaps/emcontrols.py +1017 -0
  79. pyemaps/errors.py +266 -0
  80. pyemaps/fileutils.py +1001 -0
  81. pyemaps/kdiffs.py +1221 -0
  82. pyemaps/license.txt +42 -0
  83. pyemaps/samples/adf.py +137 -0
  84. pyemaps/samples/al.img +0 -0
  85. pyemaps/samples/al_dpgen.py +57 -0
  86. pyemaps/samples/al_ediom.py +94 -0
  87. pyemaps/samples/convert_image.py +88 -0
  88. pyemaps/samples/dm_diff.py +225 -0
  89. pyemaps/samples/mask.im3 +0 -0
  90. pyemaps/samples/powder.py +51 -0
  91. pyemaps/samples/raw.img +0 -0
  92. pyemaps/samples/si_bloch.py +120 -0
  93. pyemaps/samples/si_constructor.py +51 -0
  94. pyemaps/samples/si_csf.py +59 -0
  95. pyemaps/samples/si_dif.py +134 -0
  96. pyemaps/samples/si_lacbed.py +59 -0
  97. pyemaps/samples/si_pyemaps.py +80 -0
  98. pyemaps/samples/si_scm.py +156 -0
  99. pyemaps/samples/si_stereo.py +116 -0
  100. pyemaps/scattering/__init__.py +26 -0
  101. pyemaps/scattering/sct_dec.py +31 -0
  102. pyemaps/spg/__init__.py +25 -0
  103. pyemaps/spg/spg_dec.py +60 -0
  104. pyemaps/stackimg.py +1031 -0
  105. pyemaps/xtal.py +222 -0
  106. pyemaps-2.0.0.dist-info/METADATA +231 -0
  107. pyemaps-2.0.0.dist-info/RECORD +112 -0
  108. pyemaps-2.0.0.dist-info/WHEEL +5 -0
  109. pyemaps-2.0.0.dist-info/entry_points.txt +2 -0
  110. pyemaps-2.0.0.dist-info/licenses/COPYING +798 -0
  111. pyemaps-2.0.0.dist-info/licenses/license.txt +42 -0
  112. pyemaps-2.0.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,82 @@
1
+ # To maximize python3/python2 compatibility
2
+ from __future__ import print_function
3
+ from __future__ import unicode_literals
4
+ from __future__ import division
5
+ from __future__ import absolute_import
6
+
7
+ #
8
+ # helper code: we define our match tokens
9
+ lastval = ''
10
+ def monitor(location,value):
11
+ global lastval
12
+ #print 'At %s: %s' % (location,repr(value))
13
+ lastval = repr(value)
14
+ return value
15
+
16
+
17
+ # Begin -- grammar generated by Yapps
18
+ import sys, re
19
+ from . import yapps3_compiled_rt as yappsrt
20
+
21
+ class TypeParserScanner(yappsrt.Scanner):
22
+ def __init__(self, *args,**kwargs):
23
+ patterns = [
24
+ ('([ \t\n\r])', '([ \t\n\r])'),
25
+ ('container', '[A-Za-z]+\\('),
26
+ ('identifier', '[A-Za-z]+'),
27
+ ('c_c_b', '\\)'),
28
+ ('o_c_b', '\\('),
29
+ ('comma', '\\,'),
30
+ ('END', '$'),
31
+ ]
32
+ yappsrt.Scanner.__init__(self,patterns,['([ \t\n\r])'],*args,**kwargs)
33
+
34
+ class TypeParser(yappsrt.Parser):
35
+ Context = yappsrt.Context
36
+ def input(self, _parent=None):
37
+ _context = self.Context(_parent, self._scanner, self._pos, 'input', [])
38
+ base_element = self.base_element(_context)
39
+ p = [base_element]
40
+ while self._peek('END', 'comma') == 'comma':
41
+ comma = self._scan('comma')
42
+ base_element = self.base_element(_context)
43
+ p.append(base_element)
44
+ if self._peek() not in ['END', 'comma']:
45
+ raise yappsrt.YappsSyntaxError(charpos=self._scanner.get_prev_char_pos(), context=_context, msg='Need one of ' + ', '.join(['comma', 'END']))
46
+ END = self._scan('END')
47
+ if len(p)==1: p = p[0]
48
+ return p
49
+
50
+ def base_element(self, _parent=None):
51
+ _context = self.Context(_parent, self._scanner, self._pos, 'base_element', [])
52
+ _token = self._peek('container', 'identifier')
53
+ if _token == 'container':
54
+ container = self._scan('container')
55
+ element_list = self.element_list(_context)
56
+ c_c_b = self._scan('c_c_b')
57
+ return element_list
58
+ else: # == 'identifier'
59
+ identifier = self._scan('identifier')
60
+ return identifier
61
+
62
+ def element_list(self, _parent=None):
63
+ _context = self.Context(_parent, self._scanner, self._pos, 'element_list', [])
64
+ base_element = self.base_element(_context)
65
+ p = [base_element]
66
+ while self._peek('comma', 'c_c_b') == 'comma':
67
+ comma = self._scan('comma')
68
+ base_element = self.base_element(_context)
69
+ p.append(base_element)
70
+ if self._peek() not in ['comma', 'c_c_b']:
71
+ raise yappsrt.YappsSyntaxError(charpos=self._scanner.get_prev_char_pos(), context=_context, msg='Need one of ' + ', '.join(['comma', 'c_c_b']))
72
+ return p
73
+
74
+
75
+ def parse(rule, text):
76
+ P = TypeParser(TypeParserScanner(text))
77
+ return yappsrt.wrap_error_reporter(P, rule)
78
+
79
+ # End -- grammar generated by Yapps
80
+
81
+
82
+
@@ -0,0 +1,289 @@
1
+ # To maximize python3/python2 compatibility
2
+ from __future__ import print_function
3
+ from __future__ import unicode_literals
4
+ from __future__ import division
5
+ from __future__ import absolute_import
6
+
7
+ from .StarFile import StarBlock,StarFile,StarList,StarDict
8
+ from io import StringIO
9
+ # An alternative specification for the Cif Parser, based on Yapps2
10
+ # by Amit Patel (http://theory.stanford.edu/~amitp/Yapps)
11
+ #
12
+ # helper code: we define our match tokens
13
+ lastval = ''
14
+ def monitor(location,value):
15
+ global lastval
16
+ #print 'At %s: %s' % (location,repr(value))
17
+ lastval = repr(value)
18
+ return value
19
+
20
+ # Strip extras gets rid of leading and trailing whitespace, and
21
+ # semicolons.
22
+ def stripextras(value):
23
+ from .StarFile import remove_line_folding, remove_line_prefix
24
+ # we get rid of semicolons and leading/trailing terminators etc.
25
+ import re
26
+ jj = re.compile("[\n\r\f \t\v]*")
27
+ semis = re.compile("[\n\r\f \t\v]*[\n\r\f]\n*;")
28
+ cut = semis.match(value)
29
+ if cut: #we have a semicolon-delimited string
30
+ nv = value[cut.end():len(value)-2]
31
+ try:
32
+ if nv[-1]=='\r': nv = nv[:-1]
33
+ except IndexError: #empty data value
34
+ pass
35
+ # apply protocols
36
+ nv = remove_line_prefix(nv)
37
+ nv = remove_line_folding(nv)
38
+ return nv
39
+ else:
40
+ cut = jj.match(value)
41
+ if cut:
42
+ return stripstring(value[cut.end():])
43
+ return value
44
+
45
+ # helper function to get rid of inverted commas etc.
46
+
47
+ def stripstring(value):
48
+ if value:
49
+ if value[0]== '\'' and value[-1]=='\'':
50
+ return value[1:-1]
51
+ if value[0]=='"' and value[-1]=='"':
52
+ return value[1:-1]
53
+ return value
54
+
55
+ # helper function to get rid of triple quotes
56
+ def striptriple(value):
57
+ if value:
58
+ if value[:3] == '"""' and value[-3:] == '"""':
59
+ return value[3:-3]
60
+ if value[:3] == "'''" and value[-3:] == "'''":
61
+ return value[3:-3]
62
+ return value
63
+
64
+ # helper function to populate a StarBlock given a list of names
65
+ # and values .
66
+ #
67
+ # Note that there may be an empty list at the very end of our itemlists,
68
+ # so we remove that if necessary.
69
+ #
70
+
71
+ def makeloop(target_block,loopdata):
72
+ loop_seq,itemlists = loopdata
73
+ if itemlists[-1] == []: itemlists.pop(-1)
74
+ # print('Making loop with %s' % repr(itemlists))
75
+ step_size = len(loop_seq)
76
+ for col_no in range(step_size):
77
+ target_block.AddItem(loop_seq[col_no], itemlists[col_no::step_size],precheck=True)
78
+ # now construct the loop
79
+ try:
80
+ target_block.CreateLoop(loop_seq) #will raise ValueError on problem
81
+ except ValueError:
82
+ error_string = 'Incorrect number of loop values for loop containing %s' % repr(loop_seq)
83
+ print(error_string, file=sys.stderr)
84
+ raise ValueError(error_string)
85
+
86
+ # return an object with the appropriate amount of nesting
87
+ def make_empty(nestlevel):
88
+ gd = []
89
+ for i in range(1,nestlevel):
90
+ gd = [gd]
91
+ return gd
92
+
93
+ # this function updates a dictionary first checking for name collisions,
94
+ # which imply that the CIF is invalid. We need case insensitivity for
95
+ # names.
96
+
97
+ # Unfortunately we cannot check loop item contents against non-loop contents
98
+ # in a non-messy way during parsing, as we may not have easy access to previous
99
+ # key value pairs in the context of our call (unlike our built-in access to all
100
+ # previous loops).
101
+ # For this reason, we don't waste time checking looped items against non-looped
102
+ # names during parsing of a data block. This would only match a subset of the
103
+ # final items. We do check against ordinary items, however.
104
+ #
105
+ # Note the following situations:
106
+ # (1) new_dict is empty -> we have just added a loop; do no checking
107
+ # (2) new_dict is not empty -> we have some new key-value pairs
108
+ #
109
+ def cif_update(old_dict,new_dict,loops):
110
+ old_keys = map(lambda a:a.lower(),old_dict.keys())
111
+ if new_dict != {}: # otherwise we have a new loop
112
+ #print 'Comparing %s to %s' % (repr(old_keys),repr(new_dict.keys()))
113
+ for new_key in new_dict.keys():
114
+ if new_key.lower() in old_keys:
115
+ raise CifError("Duplicate dataname or blockname %s in input file" % new_key)
116
+ old_dict[new_key] = new_dict[new_key]
117
+ #
118
+ # this takes two lines, so we couldn't fit it into a one line execution statement...
119
+ def order_update(order_array,new_name):
120
+ order_array.append(new_name)
121
+ return new_name
122
+
123
+ # and finally...turn a sequence into a python dict (thanks to Stackoverflow)
124
+ def pairwise(iterable):
125
+ try:
126
+ it = iter(iterable)
127
+ while 1:
128
+ yield next(it), next(it)
129
+ except StopIteration:
130
+ return
131
+
132
+ # Begin -- grammar generated by Yapps
133
+ import sys, re
134
+ from . import yapps3_compiled_rt as yappsrt
135
+
136
+ class StarParserScanner(yappsrt.Scanner):
137
+ def __init__(self, *args,**kwargs):
138
+ patterns = [
139
+ ('([ \t\n\r](?!;))|[ \t]', '([ \t\n\r](?!;))|[ \t]'),
140
+ ('(#.*[\n\r](?!;))|(#.*)', '(#.*[\n\r](?!;))|(#.*)'),
141
+ ('LBLOCK', '(L|l)(O|o)(O|o)(P|p)_'),
142
+ ('GLOBAL', '(G|g)(L|l)(O|o)(B|b)(A|a)(L|l)_'),
143
+ ('STOP', '(S|s)(T|t)(O|o)(P|p)_'),
144
+ ('save_heading', '(S|s)(A|a)(V|v)(E|e)_[][!%&\\(\\)*+,./:<=>?@0-9A-Za-z\\\\^`{}\\|~"#$\';_-]+'),
145
+ ('save_end', '(S|s)(A|a)(V|v)(E|e)_'),
146
+ ('data_name', '_[][!%&\\(\\)*+,./:<=>?@0-9A-Za-z\\\\^`{}\\|~"#$\';_-]+'),
147
+ ('data_heading', '(D|d)(A|a)(T|t)(A|a)_[][!%&\\(\\)*+,./:<=>?@0-9A-Za-z\\\\^`{}\\|~"#$\';_-]+'),
148
+ ('start_sc_line', '(\n|\r\n);([^\n\r])*(\r\n|\r|\n)+'),
149
+ ('sc_line_of_text', '[^;\r\n]([^\r\n])*(\r\n|\r|\n)+'),
150
+ ('end_sc_line', ';'),
151
+ ('data_value_1', '((?!(((S|s)(A|a)(V|v)(E|e)_[^\\s]*)|((G|g)(L|l)(O|o)(B|b)(A|a)(L|l)_[^\\s]*)|((S|s)(T|t)(O|o)(P|p)_[^\\s]*)|((D|d)(A|a)(T|t)(A|a)_[^\\s]*)))[^\\s"#$\'_][^\\s]*)|\'((\'(?=\\S))|([^\n\r\x0c\']))*\'+|"(("(?=\\S))|([^\n\r"]))*"+'),
152
+ ('END', '$'),
153
+ ]
154
+ yappsrt.Scanner.__init__(self,patterns,['([ \t\n\r](?!;))|[ \t]', '(#.*[\n\r](?!;))|(#.*)'],*args,**kwargs)
155
+
156
+ class StarParser(yappsrt.Parser):
157
+ Context = yappsrt.Context
158
+ def input(self, prepared, _parent=None):
159
+ _context = self.Context(_parent, self._scanner, self._pos, 'input', [prepared])
160
+ _token = self._peek('END', 'data_heading')
161
+ if _token == 'data_heading':
162
+ dblock = self.dblock(prepared, _context)
163
+ allblocks = prepared;allblocks.merge_fast(dblock)
164
+ while self._peek('END', 'data_heading') == 'data_heading':
165
+ dblock = self.dblock(prepared, _context)
166
+ allblocks.merge_fast(dblock)
167
+ if self._peek() not in ['END', 'data_heading']:
168
+ raise yappsrt.YappsSyntaxError(charpos=self._scanner.get_prev_char_pos(), context=_context, msg='Need one of ' + ', '.join(['END', 'data_heading']))
169
+ END = self._scan('END')
170
+ else: # == 'END'
171
+ END = self._scan('END')
172
+ allblocks = prepared
173
+ allblocks.unlock();return allblocks
174
+
175
+ def dblock(self, prepared, _parent=None):
176
+ _context = self.Context(_parent, self._scanner, self._pos, 'dblock', [prepared])
177
+ data_heading = self._scan('data_heading')
178
+ heading = data_heading[5:];thisbc=StarFile(characterset='unicode',standard=prepared.standard);newname = thisbc.NewBlock(heading,prepared.blocktype(overwrite=False));act_block=thisbc[newname]
179
+ while self._peek('save_heading', 'LBLOCK', 'data_name', 'save_end', 'END', 'data_heading') in ['save_heading', 'LBLOCK', 'data_name']:
180
+ _token = self._peek('save_heading', 'LBLOCK', 'data_name')
181
+ if _token != 'save_heading':
182
+ dataseq = self.dataseq(thisbc[heading], _context)
183
+ else: # == 'save_heading'
184
+ save_frame = self.save_frame(prepared, _context)
185
+ thisbc.merge_fast(save_frame,parent=act_block)
186
+ if self._peek() not in ['save_heading', 'LBLOCK', 'data_name', 'save_end', 'END', 'data_heading']:
187
+ raise yappsrt.YappsSyntaxError(charpos=self._scanner.get_prev_char_pos(), context=_context, msg='Need one of ' + ', '.join(['save_heading', 'LBLOCK', 'data_name', 'save_end', 'END', 'data_heading']))
188
+ thisbc[heading].setmaxnamelength(thisbc[heading].maxnamelength);return (monitor('dblock',thisbc))
189
+
190
+ def dataseq(self, starblock, _parent=None):
191
+ _context = self.Context(_parent, self._scanner, self._pos, 'dataseq', [starblock])
192
+ data = self.data(starblock, _context)
193
+ while self._peek('LBLOCK', 'data_name', 'save_heading', 'save_end', 'END', 'data_heading') in ['LBLOCK', 'data_name']:
194
+ data = self.data(starblock, _context)
195
+ if self._peek() not in ['LBLOCK', 'data_name', 'save_heading', 'save_end', 'END', 'data_heading']:
196
+ raise yappsrt.YappsSyntaxError(charpos=self._scanner.get_prev_char_pos(), context=_context, msg='Need one of ' + ', '.join(['LBLOCK', 'data_name', 'save_heading', 'save_end', 'END', 'data_heading']))
197
+
198
+ def data(self, currentblock, _parent=None):
199
+ _context = self.Context(_parent, self._scanner, self._pos, 'data', [currentblock])
200
+ _token = self._peek('LBLOCK', 'data_name')
201
+ if _token == 'LBLOCK':
202
+ top_loop = self.top_loop(_context)
203
+ makeloop(currentblock,top_loop)
204
+ else: # == 'data_name'
205
+ datakvpair = self.datakvpair(_context)
206
+ currentblock.AddItem(datakvpair[0],datakvpair[1],precheck=True)
207
+
208
+ def datakvpair(self, _parent=None):
209
+ _context = self.Context(_parent, self._scanner, self._pos, 'datakvpair', [])
210
+ data_name = self._scan('data_name')
211
+ data_value = self.data_value(_context)
212
+ return [data_name,data_value]
213
+
214
+ def data_value(self, _parent=None):
215
+ _context = self.Context(_parent, self._scanner, self._pos, 'data_value', [])
216
+ _token = self._peek('data_value_1', 'start_sc_line')
217
+ if _token == 'data_value_1':
218
+ data_value_1 = self._scan('data_value_1')
219
+ thisval = stripstring(data_value_1)
220
+ else: # == 'start_sc_line'
221
+ sc_lines_of_text = self.sc_lines_of_text(_context)
222
+ thisval = stripextras(sc_lines_of_text)
223
+ return monitor('data_value',thisval)
224
+
225
+ def sc_lines_of_text(self, _parent=None):
226
+ _context = self.Context(_parent, self._scanner, self._pos, 'sc_lines_of_text', [])
227
+ start_sc_line = self._scan('start_sc_line')
228
+ lines = StringIO();lines.write(start_sc_line)
229
+ while self._peek('end_sc_line', 'sc_line_of_text') == 'sc_line_of_text':
230
+ sc_line_of_text = self._scan('sc_line_of_text')
231
+ lines.write(sc_line_of_text)
232
+ if self._peek() not in ['end_sc_line', 'sc_line_of_text']:
233
+ raise yappsrt.YappsSyntaxError(charpos=self._scanner.get_prev_char_pos(), context=_context, msg='Need one of ' + ', '.join(['sc_line_of_text', 'end_sc_line']))
234
+ end_sc_line = self._scan('end_sc_line')
235
+ lines.write(end_sc_line);return monitor('sc_line_of_text',lines.getvalue())
236
+
237
+ def top_loop(self, _parent=None):
238
+ _context = self.Context(_parent, self._scanner, self._pos, 'top_loop', [])
239
+ LBLOCK = self._scan('LBLOCK')
240
+ loopfield = self.loopfield(_context)
241
+ loopvalues = self.loopvalues(_context)
242
+ return loopfield,loopvalues
243
+
244
+ def loopfield(self, _parent=None):
245
+ _context = self.Context(_parent, self._scanner, self._pos, 'loopfield', [])
246
+ toploop=[]
247
+ while self._peek('data_name', 'data_value_1', 'start_sc_line') == 'data_name':
248
+ data_name = self._scan('data_name')
249
+ toploop.append(data_name)
250
+ if self._peek() not in ['data_name', 'data_value_1', 'start_sc_line']:
251
+ raise yappsrt.YappsSyntaxError(charpos=self._scanner.get_prev_char_pos(), context=_context, msg='Need one of ' + ', '.join(['data_name', 'data_value_1', 'start_sc_line']))
252
+ return toploop
253
+
254
+ def loopvalues(self, _parent=None):
255
+ _context = self.Context(_parent, self._scanner, self._pos, 'loopvalues', [])
256
+ data_value = self.data_value(_context)
257
+ dataloop=[data_value]
258
+ while self._peek('data_value_1', 'start_sc_line', 'LBLOCK', 'data_name', 'save_heading', 'save_end', 'END', 'data_heading') in ['data_value_1', 'start_sc_line']:
259
+ data_value = self.data_value(_context)
260
+ dataloop.append(monitor('loopval',data_value))
261
+ if self._peek() not in ['data_value_1', 'start_sc_line', 'LBLOCK', 'data_name', 'save_heading', 'save_end', 'END', 'data_heading']:
262
+ raise yappsrt.YappsSyntaxError(charpos=self._scanner.get_prev_char_pos(), context=_context, msg='Need one of ' + ', '.join(['data_value_1', 'start_sc_line', 'LBLOCK', 'data_name', 'save_heading', 'save_end', 'END', 'data_heading']))
263
+ return dataloop
264
+
265
+ def save_frame(self, prepared, _parent=None):
266
+ _context = self.Context(_parent, self._scanner, self._pos, 'save_frame', [prepared])
267
+ save_heading = self._scan('save_heading')
268
+ savehead = save_heading[5:];savebc = StarFile();newname=savebc.NewBlock(savehead,prepared.blocktype(overwrite=False));act_block=savebc[newname]
269
+ while self._peek('save_end', 'save_heading', 'LBLOCK', 'data_name', 'END', 'data_heading') in ['save_heading', 'LBLOCK', 'data_name']:
270
+ _token = self._peek('save_heading', 'LBLOCK', 'data_name')
271
+ if _token != 'save_heading':
272
+ dataseq = self.dataseq(savebc[savehead], _context)
273
+ else: # == 'save_heading'
274
+ save_frame = self.save_frame(prepared, _context)
275
+ savebc.merge_fast(save_frame,parent=act_block)
276
+ if self._peek() not in ['save_end', 'save_heading', 'LBLOCK', 'data_name', 'END', 'data_heading']:
277
+ raise yappsrt.YappsSyntaxError(charpos=self._scanner.get_prev_char_pos(), context=_context, msg='Need one of ' + ', '.join(['save_end', 'save_heading', 'LBLOCK', 'data_name', 'END', 'data_heading']))
278
+ save_end = self._scan('save_end')
279
+ return monitor('save_frame',savebc)
280
+
281
+
282
+ def parse(rule, text):
283
+ P = StarParser(StarParserScanner(text))
284
+ return yappsrt.wrap_error_reporter(P, rule)
285
+
286
+ # End -- grammar generated by Yapps
287
+
288
+
289
+
@@ -0,0 +1,288 @@
1
+ # To maximize python3/python2 compatibility
2
+ from __future__ import print_function
3
+ from __future__ import unicode_literals
4
+ from __future__ import division
5
+ from __future__ import absolute_import
6
+
7
+ from .StarFile import StarBlock,StarFile,StarList,StarDict
8
+ from io import StringIO
9
+ # An alternative specification for the Cif Parser, based on Yapps2
10
+ # by Amit Patel (http://theory.stanford.edu/~amitp/Yapps)
11
+ #
12
+ # helper code: we define our match tokens
13
+ lastval = ''
14
+ def monitor(location,value):
15
+ global lastval
16
+ #print 'At %s: %s' % (location,repr(value))
17
+ lastval = repr(value)
18
+ return value
19
+
20
+ # Strip extras gets rid of leading and trailing whitespace, and
21
+ # semicolons.
22
+ def stripextras(value):
23
+ from .StarFile import remove_line_folding, remove_line_prefix
24
+ # we get rid of semicolons and leading/trailing terminators etc.
25
+ import re
26
+ jj = re.compile("[\n\r\f \t\v]*")
27
+ semis = re.compile("[\n\r\f \t\v]*[\n\r\f]\n*;")
28
+ cut = semis.match(value)
29
+ if cut: #we have a semicolon-delimited string
30
+ nv = value[cut.end():len(value)-2]
31
+ try:
32
+ if nv[-1]=='\r': nv = nv[:-1]
33
+ except IndexError: #empty data value
34
+ pass
35
+ # apply protocols
36
+ nv = remove_line_prefix(nv)
37
+ nv = remove_line_folding(nv)
38
+ return nv
39
+ else:
40
+ cut = jj.match(value)
41
+ if cut:
42
+ return stripstring(value[cut.end():])
43
+ return value
44
+
45
+ # helper function to get rid of inverted commas etc.
46
+
47
+ def stripstring(value):
48
+ if value:
49
+ if value[0]== '\'' and value[-1]=='\'':
50
+ return value[1:-1]
51
+ if value[0]=='"' and value[-1]=='"':
52
+ return value[1:-1]
53
+ return value
54
+
55
+ # helper function to get rid of triple quotes
56
+ def striptriple(value):
57
+ if value:
58
+ if value[:3] == '"""' and value[-3:] == '"""':
59
+ return value[3:-3]
60
+ if value[:3] == "'''" and value[-3:] == "'''":
61
+ return value[3:-3]
62
+ return value
63
+
64
+ # helper function to populate a StarBlock given a list of names
65
+ # and values .
66
+ #
67
+ # Note that there may be an empty list at the very end of our itemlists,
68
+ # so we remove that if necessary.
69
+ #
70
+
71
+ def makeloop(target_block,loopdata):
72
+ loop_seq,itemlists = loopdata
73
+ if itemlists[-1] == []: itemlists.pop(-1)
74
+ # print('Making loop with %s' % repr(itemlists))
75
+ step_size = len(loop_seq)
76
+ for col_no in range(step_size):
77
+ target_block.AddItem(loop_seq[col_no], itemlists[col_no::step_size],precheck=True)
78
+ # now construct the loop
79
+ try:
80
+ target_block.CreateLoop(loop_seq) #will raise ValueError on problem
81
+ except ValueError:
82
+ error_string = 'Incorrect number of loop values for loop containing %s' % repr(loop_seq)
83
+ print(error_string, file=sys.stderr)
84
+ raise ValueError(error_string)
85
+
86
+ # return an object with the appropriate amount of nesting
87
+ def make_empty(nestlevel):
88
+ gd = []
89
+ for i in range(1,nestlevel):
90
+ gd = [gd]
91
+ return gd
92
+
93
+ # this function updates a dictionary first checking for name collisions,
94
+ # which imply that the CIF is invalid. We need case insensitivity for
95
+ # names.
96
+
97
+ # Unfortunately we cannot check loop item contents against non-loop contents
98
+ # in a non-messy way during parsing, as we may not have easy access to previous
99
+ # key value pairs in the context of our call (unlike our built-in access to all
100
+ # previous loops).
101
+ # For this reason, we don't waste time checking looped items against non-looped
102
+ # names during parsing of a data block. This would only match a subset of the
103
+ # final items. We do check against ordinary items, however.
104
+ #
105
+ # Note the following situations:
106
+ # (1) new_dict is empty -> we have just added a loop; do no checking
107
+ # (2) new_dict is not empty -> we have some new key-value pairs
108
+ #
109
+ def cif_update(old_dict,new_dict,loops):
110
+ old_keys = map(lambda a:a.lower(),old_dict.keys())
111
+ if new_dict != {}: # otherwise we have a new loop
112
+ #print 'Comparing %s to %s' % (repr(old_keys),repr(new_dict.keys()))
113
+ for new_key in new_dict.keys():
114
+ if new_key.lower() in old_keys:
115
+ raise CifError("Duplicate dataname or blockname %s in input file" % new_key)
116
+ old_dict[new_key] = new_dict[new_key]
117
+ #
118
+ # this takes two lines, so we couldn't fit it into a one line execution statement...
119
+ def order_update(order_array,new_name):
120
+ order_array.append(new_name)
121
+ return new_name
122
+
123
+ # and finally...turn a sequence into a python dict (thanks to Stackoverflow)
124
+ def pairwise(iterable):
125
+ try:
126
+ it = iter(iterable)
127
+ while 1:
128
+ yield next(it), next(it)
129
+ except StopIteration:
130
+ return
131
+
132
+ # Begin -- grammar generated by Yapps
133
+ import sys, re
134
+ from . import yapps3_compiled_rt as yappsrt
135
+
136
+ class StarParserScanner(yappsrt.Scanner):
137
+ def __init__(self, *args,**kwargs):
138
+ patterns = [
139
+ ('([ \t\n\r](?!;))|[ \t]', '([ \t\n\r](?!;))|[ \t]'),
140
+ ('(#.*[\n\r](?!;))|(#.*)', '(#.*[\n\r](?!;))|(#.*)'),
141
+ ('LBLOCK', '(L|l)(O|o)(O|o)(P|p)_'),
142
+ ('GLOBAL', '(G|g)(L|l)(O|o)(B|b)(A|a)(L|l)_'),
143
+ ('STOP', '(S|s)(T|t)(O|o)(P|p)_'),
144
+ ('save_heading', '(S|s)(A|a)(V|v)(E|e)_[][!%&\\(\\)*+,./:<=>?@0-9A-Za-z\\\\^`{}\\|~"#$\';_-]+'),
145
+ ('save_end', '(S|s)(A|a)(V|v)(E|e)_'),
146
+ ('data_name', '_[][!%&\\(\\)*+,./:<=>?@0-9A-Za-z\\\\^`{}\\|~"#$\';_-]+'),
147
+ ('data_heading', '(D|d)(A|a)(T|t)(A|a)_[][!%&\\(\\)*+,./:<=>?@0-9A-Za-z\\\\^`{}\\|~"#$\';_-]+'),
148
+ ('start_sc_line', '(\n|\r\n);([^\n\r])*(\r\n|\r|\n)+'),
149
+ ('sc_line_of_text', '[^;\r\n]([^\r\n])*(\r\n|\r|\n)+'),
150
+ ('end_sc_line', ';'),
151
+ ('data_value_1', '((?!(((S|s)(A|a)(V|v)(E|e)_[^\\s]*)|((G|g)(L|l)(O|o)(B|b)(A|a)(L|l)_[^\\s]*)|((S|s)(T|t)(O|o)(P|p)_[^\\s]*)|((D|d)(A|a)(T|t)(A|a)_[^\\s]*)))[^\\s"#$\'_\\{\\[\\]][^\\s]*)|\'((\'(?=\\S))|([^\n\r\x0c\']))*\'+|"(("(?=\\S))|([^\n\r"]))*"+'),
152
+ ('END', '$'),
153
+ ]
154
+ yappsrt.Scanner.__init__(self,patterns,['([ \t\n\r](?!;))|[ \t]', '(#.*[\n\r](?!;))|(#.*)'],*args,**kwargs)
155
+
156
+ class StarParser(yappsrt.Parser):
157
+ Context = yappsrt.Context
158
+ def input(self, prepared, _parent=None):
159
+ _context = self.Context(_parent, self._scanner, self._pos, 'input', [prepared])
160
+ _token = self._peek('END', 'data_heading')
161
+ if _token == 'data_heading':
162
+ dblock = self.dblock(prepared, _context)
163
+ allblocks = prepared;allblocks.merge_fast(dblock)
164
+ while self._peek('END', 'data_heading') == 'data_heading':
165
+ dblock = self.dblock(prepared, _context)
166
+ allblocks.merge_fast(dblock)
167
+ if self._peek() not in ['END', 'data_heading']:
168
+ raise yappsrt.YappsSyntaxError(charpos=self._scanner.get_prev_char_pos(), context=_context, msg='Need one of ' + ', '.join(['END', 'data_heading']))
169
+ END = self._scan('END')
170
+ else: # == 'END'
171
+ END = self._scan('END')
172
+ allblocks = prepared
173
+ allblocks.unlock();return allblocks
174
+
175
+ def dblock(self, prepared, _parent=None):
176
+ _context = self.Context(_parent, self._scanner, self._pos, 'dblock', [prepared])
177
+ data_heading = self._scan('data_heading')
178
+ heading = data_heading[5:];thisbc=StarFile(characterset='unicode',standard=prepared.standard);newname = thisbc.NewBlock(heading,prepared.blocktype(overwrite=False));act_block=thisbc[newname]
179
+ while self._peek('save_heading', 'LBLOCK', 'data_name', 'save_end', 'END', 'data_heading') in ['save_heading', 'LBLOCK', 'data_name']:
180
+ _token = self._peek('save_heading', 'LBLOCK', 'data_name')
181
+ if _token != 'save_heading':
182
+ dataseq = self.dataseq(thisbc[heading], _context)
183
+ else: # == 'save_heading'
184
+ save_frame = self.save_frame(prepared, _context)
185
+ thisbc.merge_fast(save_frame,parent=act_block)
186
+ if self._peek() not in ['save_heading', 'LBLOCK', 'data_name', 'save_end', 'END', 'data_heading']:
187
+ raise yappsrt.YappsSyntaxError(charpos=self._scanner.get_prev_char_pos(), context=_context, msg='Need one of ' + ', '.join(['save_heading', 'LBLOCK', 'data_name', 'save_end', 'END', 'data_heading']))
188
+ thisbc[heading].setmaxnamelength(thisbc[heading].maxnamelength);return (monitor('dblock',thisbc))
189
+
190
+ def dataseq(self, starblock, _parent=None):
191
+ _context = self.Context(_parent, self._scanner, self._pos, 'dataseq', [starblock])
192
+ data = self.data(starblock, _context)
193
+ while self._peek('LBLOCK', 'data_name', 'save_heading', 'save_end', 'END', 'data_heading') in ['LBLOCK', 'data_name']:
194
+ data = self.data(starblock, _context)
195
+ if self._peek() not in ['LBLOCK', 'data_name', 'save_heading', 'save_end', 'END', 'data_heading']:
196
+ raise yappsrt.YappsSyntaxError(charpos=self._scanner.get_prev_char_pos(), context=_context, msg='Need one of ' + ', '.join(['LBLOCK', 'data_name', 'save_heading', 'save_end', 'END', 'data_heading']))
197
+
198
+ def data(self, currentblock, _parent=None):
199
+ _context = self.Context(_parent, self._scanner, self._pos, 'data', [currentblock])
200
+ _token = self._peek('LBLOCK', 'data_name')
201
+ if _token == 'LBLOCK':
202
+ top_loop = self.top_loop(_context)
203
+ makeloop(currentblock,top_loop)
204
+ else: # == 'data_name'
205
+ datakvpair = self.datakvpair(_context)
206
+ currentblock.AddItem(datakvpair[0],datakvpair[1],precheck=True)
207
+
208
+ def datakvpair(self, _parent=None):
209
+ _context = self.Context(_parent, self._scanner, self._pos, 'datakvpair', [])
210
+ data_name = self._scan('data_name')
211
+ data_value = self.data_value(_context)
212
+ return [data_name,data_value]
213
+
214
+ def data_value(self, _parent=None):
215
+ _context = self.Context(_parent, self._scanner, self._pos, 'data_value', [])
216
+ _token = self._peek('data_value_1', 'start_sc_line')
217
+ if _token == 'data_value_1':
218
+ data_value_1 = self._scan('data_value_1')
219
+ thisval = stripstring(data_value_1)
220
+ else: # == 'start_sc_line'
221
+ sc_lines_of_text = self.sc_lines_of_text(_context)
222
+ thisval = stripextras(sc_lines_of_text)
223
+ return monitor('data_value',thisval)
224
+
225
+ def sc_lines_of_text(self, _parent=None):
226
+ _context = self.Context(_parent, self._scanner, self._pos, 'sc_lines_of_text', [])
227
+ start_sc_line = self._scan('start_sc_line')
228
+ lines = StringIO();lines.write(start_sc_line)
229
+ while self._peek('end_sc_line', 'sc_line_of_text') == 'sc_line_of_text':
230
+ sc_line_of_text = self._scan('sc_line_of_text')
231
+ lines.write(sc_line_of_text)
232
+ if self._peek() not in ['end_sc_line', 'sc_line_of_text']:
233
+ raise yappsrt.YappsSyntaxError(charpos=self._scanner.get_prev_char_pos(), context=_context, msg='Need one of ' + ', '.join(['sc_line_of_text', 'end_sc_line']))
234
+ end_sc_line = self._scan('end_sc_line')
235
+ lines.write(end_sc_line);return monitor('sc_line_of_text',lines.getvalue())
236
+
237
+ def top_loop(self, _parent=None):
238
+ _context = self.Context(_parent, self._scanner, self._pos, 'top_loop', [])
239
+ LBLOCK = self._scan('LBLOCK')
240
+ loopfield = self.loopfield(_context)
241
+ loopvalues = self.loopvalues(_context)
242
+ return loopfield,loopvalues
243
+
244
+ def loopfield(self, _parent=None):
245
+ _context = self.Context(_parent, self._scanner, self._pos, 'loopfield', [])
246
+ toploop=[]
247
+ while self._peek('data_name', 'data_value_1', 'start_sc_line') == 'data_name':
248
+ data_name = self._scan('data_name')
249
+ toploop.append(data_name)
250
+ if self._peek() not in ['data_name', 'data_value_1', 'start_sc_line']:
251
+ raise yappsrt.YappsSyntaxError(charpos=self._scanner.get_prev_char_pos(), context=_context, msg='Need one of ' + ', '.join(['data_name', 'data_value_1', 'start_sc_line']))
252
+ return toploop
253
+
254
+ def loopvalues(self, _parent=None):
255
+ _context = self.Context(_parent, self._scanner, self._pos, 'loopvalues', [])
256
+ data_value = self.data_value(_context)
257
+ dataloop=[data_value]
258
+ while self._peek('data_value_1', 'start_sc_line', 'LBLOCK', 'data_name', 'save_heading', 'save_end', 'END', 'data_heading') in ['data_value_1', 'start_sc_line']:
259
+ data_value = self.data_value(_context)
260
+ dataloop.append(monitor('loopval',data_value))
261
+ if self._peek() not in ['data_value_1', 'start_sc_line', 'LBLOCK', 'data_name', 'save_heading', 'save_end', 'END', 'data_heading']:
262
+ raise yappsrt.YappsSyntaxError(charpos=self._scanner.get_prev_char_pos(), context=_context, msg='Need one of ' + ', '.join(['data_value_1', 'start_sc_line', 'LBLOCK', 'data_name', 'save_heading', 'save_end', 'END', 'data_heading']))
263
+ return dataloop
264
+
265
+ def save_frame(self, prepared, _parent=None):
266
+ _context = self.Context(_parent, self._scanner, self._pos, 'save_frame', [prepared])
267
+ save_heading = self._scan('save_heading')
268
+ savehead = save_heading[5:];savebc = StarFile();newname=savebc.NewBlock(savehead,prepared.blocktype(overwrite=False));act_block=savebc[newname]
269
+ while self._peek('save_end', 'save_heading', 'LBLOCK', 'data_name', 'END', 'data_heading') in ['save_heading', 'LBLOCK', 'data_name']:
270
+ _token = self._peek('save_heading', 'LBLOCK', 'data_name')
271
+ if _token != 'save_heading':
272
+ dataseq = self.dataseq(savebc[savehead], _context)
273
+ else: # == 'save_heading'
274
+ save_frame = self.save_frame(prepared, _context)
275
+ savebc.merge_fast(save_frame,parent=act_block)
276
+ if self._peek() not in ['save_end', 'save_heading', 'LBLOCK', 'data_name', 'END', 'data_heading']:
277
+ raise yappsrt.YappsSyntaxError(charpos=self._scanner.get_prev_char_pos(), context=_context, msg='Need one of ' + ', '.join(['save_end', 'save_heading', 'LBLOCK', 'data_name', 'END', 'data_heading']))
278
+ save_end = self._scan('save_end')
279
+ return monitor('save_frame',savebc)
280
+
281
+
282
+ def parse(rule, text):
283
+ P = StarParser(StarParserScanner(text))
284
+ return yappsrt.wrap_error_reporter(P, rule)
285
+
286
+ # End -- grammar generated by Yapps
287
+
288
+