diffpy.structure 3.2.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 (42) hide show
  1. diffpy/Structure.py +35 -0
  2. diffpy/__init__.py +23 -0
  3. diffpy/structure/__init__.py +93 -0
  4. diffpy/structure/_legacy_importer.py +88 -0
  5. diffpy/structure/apps/__init__.py +17 -0
  6. diffpy/structure/apps/anyeye.py +284 -0
  7. diffpy/structure/apps/transtru.py +126 -0
  8. diffpy/structure/atom.py +544 -0
  9. diffpy/structure/expansion/__init__.py +27 -0
  10. diffpy/structure/expansion/makeellipsoid.py +129 -0
  11. diffpy/structure/expansion/shapeutils.py +44 -0
  12. diffpy/structure/expansion/supercell_mod.py +91 -0
  13. diffpy/structure/lattice.py +663 -0
  14. diffpy/structure/mmlibspacegroups.py +8154 -0
  15. diffpy/structure/parsers/__init__.py +83 -0
  16. diffpy/structure/parsers/p_auto.py +217 -0
  17. diffpy/structure/parsers/p_cif.py +876 -0
  18. diffpy/structure/parsers/p_discus.py +312 -0
  19. diffpy/structure/parsers/p_pdb.py +405 -0
  20. diffpy/structure/parsers/p_pdffit.py +290 -0
  21. diffpy/structure/parsers/p_rawxyz.py +149 -0
  22. diffpy/structure/parsers/p_xcfg.py +457 -0
  23. diffpy/structure/parsers/p_xyz.py +161 -0
  24. diffpy/structure/parsers/parser_index_mod.py +108 -0
  25. diffpy/structure/parsers/structureparser.py +80 -0
  26. diffpy/structure/pdffitstructure.py +109 -0
  27. diffpy/structure/sgtbxspacegroups.py +5198 -0
  28. diffpy/structure/spacegroupmod.py +329 -0
  29. diffpy/structure/spacegroups.py +1441 -0
  30. diffpy/structure/structure.py +866 -0
  31. diffpy/structure/structureerrors.py +35 -0
  32. diffpy/structure/symmetryutilities.py +1100 -0
  33. diffpy/structure/utils.py +126 -0
  34. diffpy/structure/version.py +26 -0
  35. diffpy.structure-3.2.0.dist-info/AUTHORS.rst +13 -0
  36. diffpy.structure-3.2.0.dist-info/LICENSE.rst +141 -0
  37. diffpy.structure-3.2.0.dist-info/LICENSE_DANSE.rst +50 -0
  38. diffpy.structure-3.2.0.dist-info/LICENSE_pymmlib.rst +203 -0
  39. diffpy.structure-3.2.0.dist-info/METADATA +197 -0
  40. diffpy.structure-3.2.0.dist-info/RECORD +42 -0
  41. diffpy.structure-3.2.0.dist-info/WHEEL +5 -0
  42. diffpy.structure-3.2.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,312 @@
1
+ #!/usr/bin/env python
2
+ ##############################################################################
3
+ #
4
+ # diffpy.structure by DANSE Diffraction group
5
+ # Simon J. L. Billinge
6
+ # (c) 2007 trustees of the Michigan State University.
7
+ # All rights reserved.
8
+ #
9
+ # File coded by: Pavol Juhas
10
+ #
11
+ # See AUTHORS.txt for a list of people who contributed.
12
+ # See LICENSE_DANSE.txt for license information.
13
+ #
14
+ ##############################################################################
15
+
16
+ """Parser for DISCUS structure format
17
+ """
18
+
19
+ import sys
20
+ from functools import reduce
21
+
22
+ from diffpy.structure import Lattice, PDFFitStructure
23
+ from diffpy.structure.parsers import StructureParser
24
+ from diffpy.structure.structureerrors import StructureFormatError
25
+
26
+
27
+ class P_discus(StructureParser):
28
+ """Parser for DISCUS structure format. The parser chokes
29
+ on molecule and generator records.
30
+
31
+ Attributes
32
+ ----------
33
+ format : str
34
+ File format name, default "discus".
35
+ nl : int
36
+ Line number of the current line being parsed.
37
+ lines : list of str
38
+ List of lines from the input file.
39
+ line : str
40
+ Current line being parsed.
41
+ stru : PDFFitStructure
42
+ Structure being parsed.
43
+ ignored_lines : list of str
44
+ List of lines that were ignored during parsing.
45
+ cell_read : bool
46
+ ``True`` if cell record processed.
47
+ ncell_read : bool
48
+ ``True`` if ncell record processed.
49
+ """
50
+
51
+ def __init__(self):
52
+ StructureParser.__init__(self)
53
+ self.format = "discus"
54
+ # helper variables
55
+ self.nl = None
56
+ self.lines = None
57
+ self.line = None
58
+ self.stru = None
59
+ self.ignored_lines = []
60
+ self.cell_read = False
61
+ self.ncell_read = False
62
+ return
63
+
64
+ def parseLines(self, lines):
65
+ """Parse list of lines in DISCUS format.
66
+
67
+ Parameters
68
+ ----------
69
+ lines : list of str
70
+ List of lines from the input file.
71
+
72
+ Returns
73
+ -------
74
+ PDFFitStructure
75
+ Parsed `PDFFitStructure` instance.
76
+
77
+ Raises
78
+ ------
79
+ StructureFormatError
80
+ If the file is not in DISCUS format.
81
+ """
82
+ self.lines = lines
83
+ ilines = self._linesIterator()
84
+ self.stru = PDFFitStructure()
85
+ record_parsers = {
86
+ "cell": self._parse_cell,
87
+ "format": self._parse_format,
88
+ "generator": self._parse_not_implemented,
89
+ "molecule": self._parse_not_implemented,
90
+ "ncell": self._parse_ncell,
91
+ "spcgr": self._parse_spcgr,
92
+ "symmetry": self._parse_not_implemented,
93
+ "title": self._parse_title,
94
+ "shape": self._parse_shape,
95
+ }
96
+ try:
97
+ # parse header
98
+ for self.line in ilines:
99
+ words = self.line.split()
100
+ if not words or words[0][0] == "#":
101
+ continue
102
+ if words[0] == "atoms":
103
+ break
104
+ rp = record_parsers.get(words[0], self._parse_unknown_record)
105
+ rp(words)
106
+ # check if cell has been defined
107
+ if not self.cell_read:
108
+ emsg = "%d: unit cell not defined" % self.nl
109
+ raise StructureFormatError(emsg)
110
+ # parse atoms
111
+ for self.line in ilines:
112
+ words = self.line.replace(",", " ").split()
113
+ if not words or words[0][0] == "#":
114
+ continue
115
+ self._parse_atom(words)
116
+ # self consistency check
117
+ exp_natoms = reduce(lambda x, y: x * y, self.stru.pdffit["ncell"])
118
+ # only check if ncell record exists
119
+ if self.ncell_read and exp_natoms != len(self.stru):
120
+ emsg = "Expected %d atoms, read %d." % (exp_natoms, len(self.stru))
121
+ raise StructureFormatError(emsg)
122
+ # take care of superlattice
123
+ if self.stru.pdffit["ncell"][:3] != [1, 1, 1]:
124
+ latpars = list(self.stru.lattice.abcABG())
125
+ superlatpars = [latpars[i] * self.stru.pdffit["ncell"][i] for i in range(3)] + latpars[3:]
126
+ superlattice = Lattice(*superlatpars)
127
+ self.stru.placeInLattice(superlattice)
128
+ self.stru.pdffit["ncell"] = [1, 1, 1, exp_natoms]
129
+ except (ValueError, IndexError):
130
+ exc_type, exc_value, exc_traceback = sys.exc_info()
131
+ emsg = "%d: file is not in DISCUS format" % self.nl
132
+ e = StructureFormatError(emsg)
133
+ raise e.with_traceback(exc_traceback)
134
+ return self.stru
135
+
136
+ def toLines(self, stru):
137
+ """Convert `Structure` stru to a list of lines in DISCUS format.
138
+
139
+ Parameters
140
+ ----------
141
+ stru : Structure
142
+ Structure to be converted.
143
+
144
+ Returns
145
+ -------
146
+ list of str
147
+ List of lines in DISCUS format.
148
+ """
149
+ self.stru = stru
150
+ # if necessary, convert self.stru to PDFFitStructure
151
+ if not isinstance(stru, PDFFitStructure):
152
+ self.stru = PDFFitStructure(stru)
153
+ # build the stru_pdffit dictionary initialized from the defaults
154
+ # in PDFFitStructure
155
+ stru_pdffit = PDFFitStructure().pdffit
156
+ if stru.pdffit:
157
+ stru_pdffit.update(stru.pdffit)
158
+ # here we can start
159
+ self.lines = lines = []
160
+ lines.append(("title " + self.stru.title).strip())
161
+ lines.append("spcgr " + stru_pdffit["spcgr"])
162
+ if stru_pdffit.get("spdiameter", 0.0) > 0.0:
163
+ line = "shape sphere, %g" % stru_pdffit["spdiameter"]
164
+ lines.append(line)
165
+ if stru_pdffit.get("stepcut", 0.0) > 0.0:
166
+ line = "shape stepcut, %g" % stru_pdffit["stepcut"]
167
+ lines.append(line)
168
+ lines.append("cell %9.6f, %9.6f, %9.6f, %9.6f, %9.6f, %9.6f" % self.stru.lattice.abcABG())
169
+ lines.append("ncell %9i, %9i, %9i, %9i" % (1, 1, 1, len(self.stru)))
170
+ lines.append("atoms")
171
+ for a in self.stru:
172
+ lines.append(
173
+ "%-4s %17.8f %17.8f %17.8f %12.4f" % (a.element.upper(), a.xyz[0], a.xyz[1], a.xyz[2], a.Bisoequiv)
174
+ )
175
+ return lines
176
+
177
+ def _linesIterator(self):
178
+ """Iterator over `self.lines`, which increments `self.nl`"""
179
+ # ignore trailing empty lines
180
+ stop = len(self.lines)
181
+ while stop > 0 and self.lines[stop - 1].strip() == "":
182
+ stop -= 1
183
+ self.nl = 0
184
+ # read header of PDFFit file
185
+ for self.line in self.lines[:stop]:
186
+ self.nl += 1
187
+ yield self.line
188
+ pass
189
+
190
+ def _parse_cell(self, words):
191
+ """Process the cell record from DISCUS structure file."""
192
+ # split again on spaces or commas
193
+ words = self.line.replace(",", " ").split()
194
+ latpars = [float(w) for w in words[1:7]]
195
+ try:
196
+ self.stru.lattice.setLatPar(*latpars)
197
+ except ZeroDivisionError:
198
+ emsg = "%d: Invalid lattice parameters - zero cell volume" % self.nl
199
+ raise StructureFormatError(emsg)
200
+ self.cell_read = True
201
+ return
202
+
203
+ def _parse_format(self, words):
204
+ """Process the format record from DISCUS structure file."""
205
+ if words[1] == "pdffit":
206
+ emsg = "%d: file is not in DISCUS format" % self.nl
207
+ raise StructureFormatError(emsg)
208
+ return
209
+
210
+ def _parse_ncell(self, words):
211
+ """Process the ncell record from DISCUS structure file."""
212
+ # split again on spaces or commas
213
+ words = self.line.replace(",", " ").split()
214
+ self.stru.pdffit["ncell"] = [int(w) for w in words[1:5]]
215
+ self.ncell_read = True
216
+ return
217
+
218
+ def _parse_spcgr(self, words):
219
+ """Process the spcgr record from DISCUS structure file."""
220
+ self.stru.pdffit["spcgr"] = "".join(words[1:])
221
+ return
222
+
223
+ def _parse_title(self, words):
224
+ """Process the title record from DISCUS structure file."""
225
+ self.stru.title = self.line.lstrip()[5:].strip()
226
+ return
227
+
228
+ def _parse_shape(self, words):
229
+ """Process the shape record from DISCUS structure file.
230
+
231
+ Parameters
232
+ ----------
233
+ words : list of str
234
+ List of words in the line.
235
+
236
+ Raises
237
+ ------
238
+ StructureFormatError
239
+ Invalid type of particle shape correction.
240
+ """
241
+ # strip away any commas
242
+ linefixed = " ".join(words).replace(",", " ")
243
+ wordsfixed = linefixed.split()
244
+ shapetype = wordsfixed[1]
245
+ if shapetype == "sphere":
246
+ self.stru.pdffit["spdiameter"] = float(words[2])
247
+ elif shapetype == "stepcut":
248
+ self.stru.pdffit["stepcut"] = float(words[2])
249
+ else:
250
+ emsg = "Invalid type of particle shape correction %r" % shapetype
251
+ raise StructureFormatError(emsg)
252
+ return
253
+
254
+ def _parse_atom(self, words):
255
+ """Process atom records in DISCUS structure file."""
256
+ element = words[0][0:1].upper() + words[0][1:].lower()
257
+ xyz = [float(w) for w in words[1:4]]
258
+ Biso = float(words[4])
259
+ self.stru.addNewAtom(element, xyz)
260
+ a = self.stru.getLastAtom()
261
+ a.Bisoequiv = Biso
262
+ return
263
+
264
+ def _parse_unknown_record(self, words):
265
+ """Process unknown record in DISCUS structure file.
266
+
267
+ Silently ignores the line and adds it to `self.ignored_lines`.
268
+
269
+ Parameters
270
+ ----------
271
+ words : list of str
272
+ List of words in the line.
273
+
274
+ Raises
275
+ ------
276
+ StructureFormatError
277
+ Unkown record.
278
+ """
279
+ self.ignored_lines.append(self.line)
280
+ return
281
+
282
+ def _parse_not_implemented(self, words):
283
+ """Process the unimplemented records from DISCUS structure file.
284
+
285
+ Parameters
286
+ ----------
287
+ words : list of str
288
+ List of words in the line.
289
+
290
+ Raises
291
+ ------
292
+ NotImplementedError
293
+ If the record is not implemented.
294
+ """
295
+ emsg = "%d: reading of DISCUS record %r is not implemented." % (self.nl, words[0])
296
+ raise NotImplementedError(emsg)
297
+
298
+
299
+ # End of class P_pdffit
300
+
301
+ # Routines -------------------------------------------------------------------
302
+
303
+
304
+ def getParser():
305
+ """Return new `parser` object for DISCUS format.
306
+
307
+ Returns
308
+ -------
309
+ P_discus
310
+ Instance of `P_discus`.
311
+ """
312
+ return P_discus()