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.
- pyemaps/COPYING +798 -0
- pyemaps/CifFile/CifFile_module.py +3117 -0
- pyemaps/CifFile/StarFile.py +2496 -0
- pyemaps/CifFile/TypeContentsParser.py +82 -0
- pyemaps/CifFile/YappsStarParser_1_0.py +289 -0
- pyemaps/CifFile/YappsStarParser_1_1.py +288 -0
- pyemaps/CifFile/YappsStarParser_2_0.py +369 -0
- pyemaps/CifFile/YappsStarParser_STAR2.py +382 -0
- pyemaps/CifFile/__init__.py +7 -0
- pyemaps/CifFile/drel/__init__.py +1 -0
- pyemaps/CifFile/drel/drel_ast_yacc.py +582 -0
- pyemaps/CifFile/drel/drel_lex.py +228 -0
- pyemaps/CifFile/drel/drel_runtime.py +126 -0
- pyemaps/CifFile/drel/parsetab.py +185 -0
- pyemaps/CifFile/drel/py_from_ast.py +628 -0
- pyemaps/CifFile/parsetab.py +185 -0
- pyemaps/CifFile/yapps3_compiled_rt.py +390 -0
- pyemaps/README.md +201 -0
- pyemaps/__config__.py +91 -0
- pyemaps/__init__.py +233 -0
- pyemaps/__main__.py +219 -0
- pyemaps/__version__.py +1 -0
- pyemaps/cdata/Aluminium.xtl +4 -0
- pyemaps/cdata/AluminiumOxide.xtl +5 -0
- pyemaps/cdata/Aluminium_FCC.xtl +4 -0
- pyemaps/cdata/BariumTitanate_180k.xtl +6 -0
- pyemaps/cdata/BariumTitanate_270k.xtl +7 -0
- pyemaps/cdata/BariumTitanate_Tetra.xtl +7 -0
- pyemaps/cdata/BiMnO3.xtl +27 -0
- pyemaps/cdata/Boron_Tetra.xtl +8 -0
- pyemaps/cdata/CadmiumSelenide_Hex.xtl +5 -0
- pyemaps/cdata/CadmiumSulfide_Cubic.xtl +5 -0
- pyemaps/cdata/CadmiumSulfide_Hex.xtl +5 -0
- pyemaps/cdata/Chromium_BCC.xtl +4 -0
- pyemaps/cdata/CoSb3_Skutterudite.xtl +5 -0
- pyemaps/cdata/CopperOxide.xtl +5 -0
- pyemaps/cdata/Copper_FCC.xtl +4 -0
- pyemaps/cdata/Cu2O_Cuprite.xtl +5 -0
- pyemaps/cdata/Diamond.xtl +4 -0
- pyemaps/cdata/ErbiumPyrogermanate.xtl +9 -0
- pyemaps/cdata/FePd_Tetra.xtl +5 -0
- pyemaps/cdata/FeS2_Pyrite.xtl +15 -0
- pyemaps/cdata/GalliumAntimonide.xtl +5 -0
- pyemaps/cdata/GalliumArsenide.xtl +5 -0
- pyemaps/cdata/GalliumNitride.xtl +5 -0
- pyemaps/cdata/Germanium.xtl +4 -0
- pyemaps/cdata/Gold_FCC.xtl +4 -0
- pyemaps/cdata/IndiumArsenide.xtl +5 -0
- pyemaps/cdata/LaMnO3.xtl +7 -0
- pyemaps/cdata/LeadZirconateTitanate.xtl +8 -0
- pyemaps/cdata/Li2MnO3.xtl +13 -0
- pyemaps/cdata/NaFeO2.xtl +6 -0
- pyemaps/cdata/Nb3Sn.xtl +5 -0
- pyemaps/cdata/Pentacene.xtl +39 -0
- pyemaps/cdata/Silicon.xtl +4 -0
- pyemaps/cdata/StrontiumTitanate.xtl +6 -0
- pyemaps/cdata/TelluriumDioxide.xtl +5 -0
- pyemaps/cdata/TinDioxide_RT.xtl +5 -0
- pyemaps/cdata/TitaniumDioxide_Anatase.xtl +5 -0
- pyemaps/cdata/TitaniumDioxide_Rutile.xtl +5 -0
- pyemaps/cdata/TungstenDiselenide.xtl +5 -0
- pyemaps/cdata/VanadiumDioxide_RT.xtl +6 -0
- pyemaps/cdata/ZincOxide.xtl +5 -0
- pyemaps/cdata/Zinc_HCP.xtl +4 -0
- pyemaps/cdata/ZirconiumNitride.xtl +5 -0
- pyemaps/cdata/limno2.xtl +6 -0
- pyemaps/crystals.py +1415 -0
- pyemaps/ddiffs.py +147 -0
- pyemaps/diffract/__init__.py +70 -0
- pyemaps/diffract/bloch_dec.py +779 -0
- pyemaps/diffract/csf_dec.py +242 -0
- pyemaps/diffract/dif_dec.py +519 -0
- pyemaps/diffract/dpgen_dec.py +175 -0
- pyemaps/diffract/mxtal_dec.py +201 -0
- pyemaps/diffract/powder_dec.py +137 -0
- pyemaps/diffract/stereo_dec.py +111 -0
- pyemaps/display.py +791 -0
- pyemaps/emcontrols.py +1017 -0
- pyemaps/errors.py +266 -0
- pyemaps/fileutils.py +1001 -0
- pyemaps/kdiffs.py +1221 -0
- pyemaps/license.txt +42 -0
- pyemaps/samples/adf.py +137 -0
- pyemaps/samples/al.img +0 -0
- pyemaps/samples/al_dpgen.py +57 -0
- pyemaps/samples/al_ediom.py +94 -0
- pyemaps/samples/convert_image.py +88 -0
- pyemaps/samples/dm_diff.py +225 -0
- pyemaps/samples/mask.im3 +0 -0
- pyemaps/samples/powder.py +51 -0
- pyemaps/samples/raw.img +0 -0
- pyemaps/samples/si_bloch.py +120 -0
- pyemaps/samples/si_constructor.py +51 -0
- pyemaps/samples/si_csf.py +59 -0
- pyemaps/samples/si_dif.py +134 -0
- pyemaps/samples/si_lacbed.py +59 -0
- pyemaps/samples/si_pyemaps.py +80 -0
- pyemaps/samples/si_scm.py +156 -0
- pyemaps/samples/si_stereo.py +116 -0
- pyemaps/scattering/__init__.py +26 -0
- pyemaps/scattering/sct_dec.py +31 -0
- pyemaps/spg/__init__.py +25 -0
- pyemaps/spg/spg_dec.py +60 -0
- pyemaps/stackimg.py +1031 -0
- pyemaps/xtal.py +222 -0
- pyemaps-2.0.0.dist-info/METADATA +231 -0
- pyemaps-2.0.0.dist-info/RECORD +112 -0
- pyemaps-2.0.0.dist-info/WHEEL +5 -0
- pyemaps-2.0.0.dist-info/entry_points.txt +2 -0
- pyemaps-2.0.0.dist-info/licenses/COPYING +798 -0
- pyemaps-2.0.0.dist-info/licenses/license.txt +42 -0
- pyemaps-2.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
'''
|
|
2
|
+
.. This file is part of pyEMAPS
|
|
3
|
+
|
|
4
|
+
.. ----
|
|
5
|
+
|
|
6
|
+
.. pyEMAPS is free software. You can redistribute it and/or modify
|
|
7
|
+
.. it under the terms of the GNU General Public License as published
|
|
8
|
+
.. by the Free Software Foundation, either version 3 of the License,
|
|
9
|
+
.. or (at your option) any later version..
|
|
10
|
+
|
|
11
|
+
.. pyEMAPS is distributed in the hope that it will be useful,
|
|
12
|
+
.. but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13
|
+
.. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
14
|
+
.. GNU General Public License for more details.
|
|
15
|
+
|
|
16
|
+
.. You should have received a copy of the GNU General Public License
|
|
17
|
+
.. along with pyEMAPS. If not, see `<https://www.gnu.org/licenses/>`_.
|
|
18
|
+
|
|
19
|
+
.. Contact supprort@emlabsoftware.com for any questions and comments.
|
|
20
|
+
|
|
21
|
+
.. ----
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
Author: EMLab Solutions, Inc.
|
|
25
|
+
Date Created: May 07, 2022
|
|
26
|
+
|
|
27
|
+
'''
|
|
28
|
+
def add_mxtal(target):
|
|
29
|
+
from . import dif
|
|
30
|
+
from .. import (ID_MATRIX, MLEN, DEF_CELLBOX,
|
|
31
|
+
DEF_XZ, DEF_ORSHIFT, DEF_TRSHIFT,
|
|
32
|
+
DEF_LOCASPACE)
|
|
33
|
+
from .. import MxtalError
|
|
34
|
+
from ..fileutils import compose_ofn
|
|
35
|
+
from ..xtal import Xtal
|
|
36
|
+
|
|
37
|
+
@staticmethod
|
|
38
|
+
def printXYZ( mx):
|
|
39
|
+
'''
|
|
40
|
+
Print mxtal data in .xyz format in standard output.
|
|
41
|
+
Refer to `XYZ format <https://wiki.jmol.org/index.php/File_formats/Formats/XYZ>`_
|
|
42
|
+
for its definition and usage.
|
|
43
|
+
|
|
44
|
+
:param mx: Crystal structure object defined in xtal.py defiend as Xtal.
|
|
45
|
+
:type mx: Xtal, required
|
|
46
|
+
|
|
47
|
+
.. note:: An example of Silicon atomic structure by pyemaps:
|
|
48
|
+
|
|
49
|
+
.. code-block:: console
|
|
50
|
+
|
|
51
|
+
216
|
|
52
|
+
50.0 50.0 50.0 90.0 90.0 90.0
|
|
53
|
+
SI 0.6788375000 0.6788375000 0.6788375000
|
|
54
|
+
SI 3.3941875000 3.3941875000 0.6788375000
|
|
55
|
+
SI 4.7518625000 2.0365125000 2.0365125000
|
|
56
|
+
SI 2.0365125000 4.7518625000 2.0365125000
|
|
57
|
+
SI 3.3941875000 0.6788375000 3.3941875000
|
|
58
|
+
...
|
|
59
|
+
|
|
60
|
+
'''
|
|
61
|
+
if not isinstance(mx, Xtal):
|
|
62
|
+
raise MxtalError("The print object is not valid atomic structure object.")
|
|
63
|
+
print(f'{str(mx)}')
|
|
64
|
+
|
|
65
|
+
def writeXYZ(self, mx, fn=None):
|
|
66
|
+
'''
|
|
67
|
+
Save crystal structure object data generated by pyemaps to a .xyz file <fn>
|
|
68
|
+
File path is composed by pyemaps depending on whether
|
|
69
|
+
PYEMAP_DATA environment variable is set. For details how
|
|
70
|
+
*pyemaps* compose the file name see
|
|
71
|
+
:ref:`Environment Variables <Environment Variables>`
|
|
72
|
+
for details.
|
|
73
|
+
|
|
74
|
+
The file can be imported into external tool such as Jmole to
|
|
75
|
+
view its content.
|
|
76
|
+
|
|
77
|
+
:param mx: Crystal structure object defined in xtal.py defiend as Xtal.
|
|
78
|
+
:type mx: Xtal, required
|
|
79
|
+
|
|
80
|
+
:param fn: file name for data to be saved.
|
|
81
|
+
:type fn: str, optional
|
|
82
|
+
|
|
83
|
+
'''
|
|
84
|
+
|
|
85
|
+
if not isinstance(mx, Xtal):
|
|
86
|
+
raise MxtalError("The print object is not valid atomic structure object.")
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
xyzfn = compose_ofn(fn, self.name, ty='mxtal') +'.xyz'
|
|
90
|
+
|
|
91
|
+
try:
|
|
92
|
+
with open(xyzfn, 'w') as f:
|
|
93
|
+
f.writelines(str(mx))
|
|
94
|
+
except (FileNotFoundError, IOError, PermissionError) as e:
|
|
95
|
+
print(f'Error writing xyz data file {fn}')
|
|
96
|
+
return -1
|
|
97
|
+
except Exception:
|
|
98
|
+
return -1
|
|
99
|
+
else:
|
|
100
|
+
print(f'Successfully saved mxtal data in file: {xyzfn}')
|
|
101
|
+
return 0
|
|
102
|
+
|
|
103
|
+
def generateMxtal(self,
|
|
104
|
+
trMatrix = ID_MATRIX,
|
|
105
|
+
trShift = DEF_TRSHIFT, #Transformation shift
|
|
106
|
+
cellbox = DEF_CELLBOX,
|
|
107
|
+
xz = DEF_XZ,
|
|
108
|
+
orShift = DEF_ORSHIFT, #Origin shift
|
|
109
|
+
locASpace = DEF_LOCASPACE,
|
|
110
|
+
bound = None): #location in A Space
|
|
111
|
+
"""
|
|
112
|
+
Generate the crystal atomic structure data in .xyz format.
|
|
113
|
+
|
|
114
|
+
:param trMatrix: Transformation matrix
|
|
115
|
+
:type trMatrix: array, optional
|
|
116
|
+
|
|
117
|
+
:param trShift: Transformation shift
|
|
118
|
+
:type trShift: array, optional
|
|
119
|
+
|
|
120
|
+
:param cellbox: Locate atoms inside a box defined.
|
|
121
|
+
:type cellbox: array, optional
|
|
122
|
+
|
|
123
|
+
:param xz: X and Z orientations in real space.
|
|
124
|
+
:type xz: array, optional
|
|
125
|
+
|
|
126
|
+
:param orShift: Origin shift.
|
|
127
|
+
:type orShift: float, optional
|
|
128
|
+
|
|
129
|
+
:param locASpace: Locate atoms inside a box defined.
|
|
130
|
+
:type locASpace: array, optional
|
|
131
|
+
|
|
132
|
+
:param bound: Location in A Space.
|
|
133
|
+
:type bound: float, optional
|
|
134
|
+
|
|
135
|
+
:return: a crystal structure object
|
|
136
|
+
:rtype: :py:mod:`pyemaps.Xtal` class
|
|
137
|
+
|
|
138
|
+
"""
|
|
139
|
+
import numpy as np
|
|
140
|
+
from numpy import asfortranarray as farray
|
|
141
|
+
from . import mxtal as MX
|
|
142
|
+
|
|
143
|
+
dif.initcontrols()
|
|
144
|
+
|
|
145
|
+
self.load(cty=1)
|
|
146
|
+
|
|
147
|
+
tmat = farray(np.array(trMatrix))
|
|
148
|
+
|
|
149
|
+
pxz = farray(np.array(xz))
|
|
150
|
+
|
|
151
|
+
if bound is not None:
|
|
152
|
+
ret = MX.do_mxtal(tmat, trShift, cellbox[0], cellbox[1],
|
|
153
|
+
pxz[0], pxz[1], orShift, locASpace, bound)
|
|
154
|
+
else:
|
|
155
|
+
ret = MX.do_mxtal(tmat, trShift, cellbox[0], cellbox[1],
|
|
156
|
+
pxz[0], pxz[1], orShift, locASpace)
|
|
157
|
+
|
|
158
|
+
if ret != 1:
|
|
159
|
+
raise MxtalError('Failed to starting mxtal module')
|
|
160
|
+
|
|
161
|
+
na = MX.get_nxyz()
|
|
162
|
+
|
|
163
|
+
if na <=0:
|
|
164
|
+
raise MxtalError('Failed to generate data')
|
|
165
|
+
|
|
166
|
+
xyz, ret = MX.get_xyzdata(na)
|
|
167
|
+
|
|
168
|
+
if ret != 1:
|
|
169
|
+
raise MxtalError('Failed to retrieve data')
|
|
170
|
+
|
|
171
|
+
sym = farray(np.empty((MLEN, na), dtype='c'))
|
|
172
|
+
sym, ret = MX.get_symdata(sym)
|
|
173
|
+
|
|
174
|
+
if ret != 1:
|
|
175
|
+
raise MxtalError('Failed to retrieve data')
|
|
176
|
+
|
|
177
|
+
tsym = np.transpose(sym)
|
|
178
|
+
txyz = np.transpose(xyz)
|
|
179
|
+
|
|
180
|
+
mx = Xtal()
|
|
181
|
+
for i in range(na):
|
|
182
|
+
s = bytearray(tsym[i]).decode('utf-8').strip(" \x00")
|
|
183
|
+
|
|
184
|
+
mx.add(s, txyz[i])
|
|
185
|
+
|
|
186
|
+
nc = 6
|
|
187
|
+
cell, ret = MX.get_cellconst(nc)
|
|
188
|
+
|
|
189
|
+
mx.cell = cell
|
|
190
|
+
|
|
191
|
+
if ret !=0:
|
|
192
|
+
raise MxtalError(f'Failed to retrieve cell constants: {ret}')
|
|
193
|
+
|
|
194
|
+
# clean up
|
|
195
|
+
MX.cleanup()
|
|
196
|
+
return mx
|
|
197
|
+
|
|
198
|
+
target.generateMxtal = generateMxtal
|
|
199
|
+
target.printXYZ = printXYZ
|
|
200
|
+
target.writeXYZ =writeXYZ
|
|
201
|
+
return target
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
'''
|
|
2
|
+
.. This file is part of pyEMAPS
|
|
3
|
+
|
|
4
|
+
.. ----
|
|
5
|
+
|
|
6
|
+
.. pyEMAPS is free software. You can redistribute it and/or modify
|
|
7
|
+
.. it under the terms of the GNU General Public License as published
|
|
8
|
+
.. by the Free Software Foundation, either version 3 of the License,
|
|
9
|
+
.. or (at your option) any later version..
|
|
10
|
+
|
|
11
|
+
.. pyEMAPS is distributed in the hope that it will be useful,
|
|
12
|
+
.. but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13
|
+
.. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
14
|
+
.. GNU General Public License for more details.
|
|
15
|
+
|
|
16
|
+
.. You should have received a copy of the GNU General Public License
|
|
17
|
+
.. along with pyEMAPS. If not, see `<https://www.gnu.org/licenses/>`_.
|
|
18
|
+
|
|
19
|
+
.. Contact supprort@emlabsoftware.com for any questions and comments.
|
|
20
|
+
|
|
21
|
+
.. ----
|
|
22
|
+
|
|
23
|
+
.. Author: EMLab Solutions, Inc.
|
|
24
|
+
.. Date Created: May 07, 2022
|
|
25
|
+
|
|
26
|
+
'''
|
|
27
|
+
def add_powder(target):
|
|
28
|
+
|
|
29
|
+
try:
|
|
30
|
+
from . import powder
|
|
31
|
+
|
|
32
|
+
except ImportError as e:
|
|
33
|
+
print(f"Error: required module pyemaps.powder not found")
|
|
34
|
+
|
|
35
|
+
def plotPowder(self, pw):
|
|
36
|
+
|
|
37
|
+
"""
|
|
38
|
+
Show powder diffraction created from
|
|
39
|
+
`generatePowder <pyemaps.crystals.html#pyemaps.crystals.Crystal.generatePowder>`_.
|
|
40
|
+
|
|
41
|
+
:param pw: Powder diffraction data
|
|
42
|
+
:type pw: array, required
|
|
43
|
+
|
|
44
|
+
"""
|
|
45
|
+
import numpy as np
|
|
46
|
+
import matplotlib.pyplot as plt
|
|
47
|
+
|
|
48
|
+
xdim, _ = np.shape(pw)
|
|
49
|
+
if xdim !=2:
|
|
50
|
+
raise ValueError("Failed to plot: data error")
|
|
51
|
+
|
|
52
|
+
fig, ax = plt.subplots()
|
|
53
|
+
# canvas.set_window_title was removed in matplotlib 3.6
|
|
54
|
+
if fig.canvas.manager is not None:
|
|
55
|
+
fig.canvas.manager.set_window_title('PYEMAPS')
|
|
56
|
+
fig.suptitle("Electron Powder Diffraction", fontsize=14, fontweight='bold')
|
|
57
|
+
|
|
58
|
+
ax.set_title(self.name)
|
|
59
|
+
|
|
60
|
+
ax.set_ylabel('Intensity')
|
|
61
|
+
ax.set_xlabel('Scattering Angle 2\u03F4 (Rad)')
|
|
62
|
+
ax.plot(pw[0], pw[1], 'b')
|
|
63
|
+
|
|
64
|
+
plt.show()
|
|
65
|
+
|
|
66
|
+
def generatePowder(self,
|
|
67
|
+
kv = 100,
|
|
68
|
+
t2max = 0.05,
|
|
69
|
+
smax = 1.0,
|
|
70
|
+
eta = 1.0,
|
|
71
|
+
gamma = 0.001,
|
|
72
|
+
absp = 0,
|
|
73
|
+
bg = False,
|
|
74
|
+
bamp = 0.35,
|
|
75
|
+
bgamma = 0.001,
|
|
76
|
+
bmfact = 0.02):
|
|
77
|
+
'''
|
|
78
|
+
Generates powder diffraction.
|
|
79
|
+
|
|
80
|
+
:param kv: Accelaration voltage in kilo-volts.
|
|
81
|
+
:type kv: int or float, optional
|
|
82
|
+
|
|
83
|
+
:param t2max: Maximum scattering angle.
|
|
84
|
+
:type t2max: float, optional
|
|
85
|
+
|
|
86
|
+
:param smax: Maximum Sin(theta)/Wavelength.
|
|
87
|
+
:type smax: float, optional
|
|
88
|
+
|
|
89
|
+
:param smax: Maximum Sin(theta)/Wavelength.
|
|
90
|
+
:type smax: float, optional
|
|
91
|
+
|
|
92
|
+
:param eta: the mixing coefficient between gaussian and lorentzian in a pseudo-Voight peak function.
|
|
93
|
+
:type eta: float, optional
|
|
94
|
+
|
|
95
|
+
:param gamma: Diffraction peaks half maximum half width.
|
|
96
|
+
:type gamma: float, optional
|
|
97
|
+
|
|
98
|
+
:param absp: With Absoption structure factor (1 -default) or not (0).
|
|
99
|
+
:type absp: int, optional
|
|
100
|
+
|
|
101
|
+
:param isbgdon: Background on or not (default no background).
|
|
102
|
+
:type isbgdon: int, optional
|
|
103
|
+
|
|
104
|
+
:param bamp: Background amplitude.
|
|
105
|
+
:type bamp: float, optional
|
|
106
|
+
|
|
107
|
+
:param bgamma: Background width.
|
|
108
|
+
:type bgamma: float, optional
|
|
109
|
+
|
|
110
|
+
:param bmfact: Background exponential damping factor.
|
|
111
|
+
:type bmfact: float, optional
|
|
112
|
+
|
|
113
|
+
:return: an array of 2 x 1000 with the first row representing the scattering angle 2theta and the second the intensity
|
|
114
|
+
:rtype: array
|
|
115
|
+
|
|
116
|
+
'''
|
|
117
|
+
import numpy as np
|
|
118
|
+
from numpy import asfortranarray as farray
|
|
119
|
+
|
|
120
|
+
self.load()
|
|
121
|
+
|
|
122
|
+
rawP = farray(np.zeros((2,1000), dtype=np.float32))
|
|
123
|
+
|
|
124
|
+
ret = powder.generate_powder(rawP, kv=kv, t2max=t2max,
|
|
125
|
+
smax = smax, eta=eta, gamma=gamma, isab = absp,
|
|
126
|
+
isbgdon = bg, bamp = bamp, bgamma = bgamma,
|
|
127
|
+
bmfact = bmfact)
|
|
128
|
+
|
|
129
|
+
if ret != 0:
|
|
130
|
+
print(f'Error generating powder data for {self.name}')
|
|
131
|
+
|
|
132
|
+
return rawP
|
|
133
|
+
|
|
134
|
+
target.generatePowder = generatePowder
|
|
135
|
+
target.plotPowder = plotPowder
|
|
136
|
+
|
|
137
|
+
return target
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
'''
|
|
2
|
+
.. This file is part of pyEMAPS
|
|
3
|
+
|
|
4
|
+
.. ----
|
|
5
|
+
|
|
6
|
+
.. pyEMAPS is free software. You can redistribute it and/or modify
|
|
7
|
+
.. it under the terms of the GNU General Public License as published
|
|
8
|
+
.. by the Free Software Foundation, either version 3 of the License,
|
|
9
|
+
.. or (at your option) any later version..
|
|
10
|
+
|
|
11
|
+
.. pyEMAPS is distributed in the hope that it will be useful,
|
|
12
|
+
.. but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13
|
+
.. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
14
|
+
.. GNU General Public License for more details.
|
|
15
|
+
|
|
16
|
+
.. You should have received a copy of the GNU General Public License
|
|
17
|
+
.. along with pyEMAPS. If not, see `<https://www.gnu.org/licenses/>`_.
|
|
18
|
+
|
|
19
|
+
.. Contact supprort@emlabsoftware.com for any questions and comments.
|
|
20
|
+
|
|
21
|
+
.. ----
|
|
22
|
+
|
|
23
|
+
.. Author: EMLab Solutions, Inc.
|
|
24
|
+
.. Date Created: May 07, 2022
|
|
25
|
+
|
|
26
|
+
'''
|
|
27
|
+
def add_stereo(target):
|
|
28
|
+
def generateStereo(self, xa = (0,2,0),
|
|
29
|
+
tilt=(0.0,0.0),
|
|
30
|
+
zone = (0, 0, 1)):
|
|
31
|
+
"""
|
|
32
|
+
Generate stereodiagram.
|
|
33
|
+
|
|
34
|
+
:param xa: Crystal horizontal axis in reciprical space
|
|
35
|
+
:type xa: tuple of 3 integers, optional
|
|
36
|
+
|
|
37
|
+
:param tilt: Sample tilts in (x,y)
|
|
38
|
+
:type tilt: tuple, optional
|
|
39
|
+
|
|
40
|
+
:param zone: Zone axis
|
|
41
|
+
:type zone: tuple, optional
|
|
42
|
+
|
|
43
|
+
:return: A list of stereodiagram elements represented by dict object
|
|
44
|
+
:rtype: list of dict object
|
|
45
|
+
|
|
46
|
+
Example of the stereodiagram output:
|
|
47
|
+
|
|
48
|
+
.. code-block:: python
|
|
49
|
+
|
|
50
|
+
[
|
|
51
|
+
{
|
|
52
|
+
"c": (x,y), # center
|
|
53
|
+
"r": 1.0, # radius
|
|
54
|
+
"idx": (h, k, l), # Miller Index
|
|
55
|
+
}
|
|
56
|
+
]
|
|
57
|
+
|
|
58
|
+
To display the resulting stereodiagram, use
|
|
59
|
+
`showStereo <pyemaps.display.html#pyemaps.display.showStereo>`_.
|
|
60
|
+
|
|
61
|
+
"""
|
|
62
|
+
from . import dif, stereo
|
|
63
|
+
|
|
64
|
+
import numpy as np
|
|
65
|
+
from numpy import asfortranarray as farray
|
|
66
|
+
|
|
67
|
+
from ..errors import StereodiagramError
|
|
68
|
+
from .. import DEF_XAXIS
|
|
69
|
+
|
|
70
|
+
dif.initcontrols()
|
|
71
|
+
dif.setzone(zone[0], zone[1], zone[2])
|
|
72
|
+
|
|
73
|
+
if xa != DEF_XAXIS:
|
|
74
|
+
dif.set_xaxis(1, xa[0], xa[1], xa[2])
|
|
75
|
+
dif.setsamplecontrols(tilt[0], tilt[1], 0.0, 0.0)
|
|
76
|
+
|
|
77
|
+
# load the crystal
|
|
78
|
+
|
|
79
|
+
self.load()
|
|
80
|
+
|
|
81
|
+
ret = dif.diffract(3)
|
|
82
|
+
if ret != 1:
|
|
83
|
+
raise StereodiagramError('Stereodiagram generation failed')
|
|
84
|
+
|
|
85
|
+
sl = stereo.get_stereolimit()
|
|
86
|
+
|
|
87
|
+
sdata = farray(np.zeros((6, sl)), dtype=float)
|
|
88
|
+
|
|
89
|
+
sdata, ns, ret = stereo.do_stereogram(sdata)
|
|
90
|
+
|
|
91
|
+
if ret != 1:
|
|
92
|
+
raise StereodiagramError('Stereodiagram generation failed')
|
|
93
|
+
|
|
94
|
+
stereo_list = []
|
|
95
|
+
for i in range(ns):
|
|
96
|
+
item = {}
|
|
97
|
+
s = sdata[0:, i]
|
|
98
|
+
item['c'] = (s[0], s[1])
|
|
99
|
+
item['r'] = s[2]
|
|
100
|
+
item['idx'] = (s[3], s[4],s[5])
|
|
101
|
+
stereo_list.append(item)
|
|
102
|
+
|
|
103
|
+
#release the memory
|
|
104
|
+
dif.diff_internaldelete(0)
|
|
105
|
+
dif.diff_delete()
|
|
106
|
+
|
|
107
|
+
return stereo_list
|
|
108
|
+
|
|
109
|
+
target.generateStereo = generateStereo
|
|
110
|
+
|
|
111
|
+
return target
|