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,779 @@
|
|
|
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_bloch(target):
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
Dynamic Simulation Specific Controls Default Values:
|
|
31
|
+
----------------------------------------------------
|
|
32
|
+
|
|
33
|
+
.. data:: DEF_APERTURE
|
|
34
|
+
:value: 1.0
|
|
35
|
+
|
|
36
|
+
.. data:: DEF_OMEGA
|
|
37
|
+
:value: 10
|
|
38
|
+
|
|
39
|
+
.. data:: DEF_SAMPLING
|
|
40
|
+
:value: 8
|
|
41
|
+
|
|
42
|
+
.. data:: DEF_PIXSIZE
|
|
43
|
+
:value: 25
|
|
44
|
+
|
|
45
|
+
.. data:: DEF_DETSIZE
|
|
46
|
+
:value: 512
|
|
47
|
+
|
|
48
|
+
.. data:: DEF_CBED_DSIZE
|
|
49
|
+
:value: 0.16
|
|
50
|
+
|
|
51
|
+
.. data:: DEF_THICKNESS
|
|
52
|
+
:value: (200, 200, 100)
|
|
53
|
+
|
|
54
|
+
.. data:: DEF_DSIZE_LIMITS
|
|
55
|
+
:value: (0.01, 0.5)
|
|
56
|
+
|
|
57
|
+
"""
|
|
58
|
+
from . import bloch, dif
|
|
59
|
+
from .. import DEF_APERTURE, \
|
|
60
|
+
DEF_THICKNESS, \
|
|
61
|
+
DEF_SAMPLING, \
|
|
62
|
+
DEF_PIXSIZE, \
|
|
63
|
+
DEF_DETSIZE, \
|
|
64
|
+
MAX_DEPTH, \
|
|
65
|
+
DEF_OMEGA, \
|
|
66
|
+
DEF_CBED_DSIZE, \
|
|
67
|
+
DEF_MODE, \
|
|
68
|
+
DEF_DSIZE_LIMITS, \
|
|
69
|
+
DEF_XAXIS
|
|
70
|
+
from .. import BImgList, EMC, SIMC
|
|
71
|
+
|
|
72
|
+
from ..fileutils import compose_ofn
|
|
73
|
+
from .. import BlochError,BlochListError
|
|
74
|
+
import numpy as np
|
|
75
|
+
from numpy import asfortranarray as farray
|
|
76
|
+
from .. import TY_NORMAL, TY_LACBED
|
|
77
|
+
|
|
78
|
+
BIMG_EXT = '.im3'
|
|
79
|
+
MAX_BIMGFN = 256
|
|
80
|
+
CBED_MODE = DEF_MODE + 1
|
|
81
|
+
|
|
82
|
+
def _getBlochFN(self):
|
|
83
|
+
'''
|
|
84
|
+
Constructs a bloch image output file name.
|
|
85
|
+
|
|
86
|
+
Refer to :ref:`Environment Variables <Environment Variables>`
|
|
87
|
+
for how this file name is constructed.
|
|
88
|
+
|
|
89
|
+
'''
|
|
90
|
+
cfn = compose_ofn(None, self.name, ty='bloch')+BIMG_EXT
|
|
91
|
+
|
|
92
|
+
l = len(cfn)
|
|
93
|
+
if l > MAX_BIMGFN:
|
|
94
|
+
raise BlochError('Bloch image file name too long, it cant excced 256')
|
|
95
|
+
|
|
96
|
+
ffn = farray(np.empty((256), dtype='c'))
|
|
97
|
+
for i in range(l):
|
|
98
|
+
ffn[i] = cfn[i]
|
|
99
|
+
|
|
100
|
+
return cfn, ffn, l
|
|
101
|
+
|
|
102
|
+
def beginBloch(self, aperture = DEF_APERTURE,
|
|
103
|
+
omega = DEF_OMEGA,
|
|
104
|
+
sampling = DEF_SAMPLING,
|
|
105
|
+
dbsize = DEF_CBED_DSIZE,
|
|
106
|
+
em_controls = EMC(cl=200, # set smaller that 1000 default value
|
|
107
|
+
simc = SIMC(gmax=1.0,
|
|
108
|
+
excitation=(0.3,1.0)
|
|
109
|
+
)
|
|
110
|
+
)
|
|
111
|
+
):
|
|
112
|
+
"""
|
|
113
|
+
|
|
114
|
+
Begins a dynamic diffraction (Bloch) simulation session.
|
|
115
|
+
The simulation results are retained in the session between this and
|
|
116
|
+
`endBloch call <pyemaps.crystals.html#pyemaps.crystals.Crystal.endBloch>`_.
|
|
117
|
+
|
|
118
|
+
:param aperture: Optional. Objective aperture
|
|
119
|
+
:type aperture: float
|
|
120
|
+
|
|
121
|
+
:param omega: Optional. Diagnization cutoff value
|
|
122
|
+
:type omega: float
|
|
123
|
+
|
|
124
|
+
:param sampling: Optional. Number of sampling points
|
|
125
|
+
:type sampling: int
|
|
126
|
+
|
|
127
|
+
:param dbsize: Diffracted beams size.
|
|
128
|
+
:type dbsize: float, optional
|
|
129
|
+
|
|
130
|
+
:param em_controls: Optional. electron `microscope control <pyemaps.emcontrols.html#module-pyemaps.emcontrols>`_ object.
|
|
131
|
+
:type em_controls: pyemaps.EMC
|
|
132
|
+
|
|
133
|
+
:return: a tuple (n, ns) where ns is a list of sampling points; n is the number of sampling points
|
|
134
|
+
:rtype: tuple
|
|
135
|
+
|
|
136
|
+
Default values:
|
|
137
|
+
|
|
138
|
+
::
|
|
139
|
+
|
|
140
|
+
DEF_APERTURE = 1.0
|
|
141
|
+
DEF_OMEGA = 10
|
|
142
|
+
DEF_SAMPLING = 8
|
|
143
|
+
DEF_CBED_DSIZE - 0.16
|
|
144
|
+
DEF_DSIZE_LIMITS =(0.01, 0.5)
|
|
145
|
+
|
|
146
|
+
.. note::
|
|
147
|
+
|
|
148
|
+
During the simulation session, results are retained in pyemaps
|
|
149
|
+
bloch module. The following methods are used to retrieve the
|
|
150
|
+
result before the end of session:
|
|
151
|
+
|
|
152
|
+
1. `getBlochimages <pyemaps.crystals.html#pyemaps.crystals.Crystal.getBlochImages>`_.
|
|
153
|
+
Retrieve a list of bloch images
|
|
154
|
+
|
|
155
|
+
2. `getSCMatrix <pyemaps.crystals.html#pyemaps.crystals.Crystal.getSCMatrix>`_.
|
|
156
|
+
Retrieve a scattering matrix at a sampling point
|
|
157
|
+
|
|
158
|
+
.. note::
|
|
159
|
+
|
|
160
|
+
Other information available during the session:
|
|
161
|
+
|
|
162
|
+
a. List of sampling points, diffraction beams tilts etc
|
|
163
|
+
with `getIBDetails <pyemaps.crystals.html#pyemaps.crystals.Crystal.getIBDetails>`_;
|
|
164
|
+
|
|
165
|
+
b. getEigen function is folded into getSCMatrix call starting from Stable verion 1.0.3
|
|
166
|
+
|
|
167
|
+
c. Diagnization Miller indexes at each sampling point:
|
|
168
|
+
`getBeams <pyemaps.crystals.html#pyemaps.crystals.Crystal.getBeams>`_;
|
|
169
|
+
|
|
170
|
+
"""
|
|
171
|
+
if aperture is None or not isinstance(aperture, (int, float)):
|
|
172
|
+
raise BlochError('Objective aperture must be valid numberal')
|
|
173
|
+
|
|
174
|
+
if omega is None or not isinstance(omega, int):
|
|
175
|
+
raise BlochError('Diagnization cutoff value must be valid numberal')
|
|
176
|
+
|
|
177
|
+
if dbsize is None or not isinstance(dbsize, (int,float)) or \
|
|
178
|
+
dbsize < DEF_DSIZE_LIMITS[0] or dbsize > DEF_DSIZE_LIMITS[1]:
|
|
179
|
+
raise BlochError(f'Diffracted beam size must be in range {DEF_DSIZE_LIMITS}')
|
|
180
|
+
|
|
181
|
+
if em_controls is None or not isinstance(em_controls, EMC):
|
|
182
|
+
raise BlochError('Control object must be of EMControl type')
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
dif.initcontrols()
|
|
186
|
+
dif.setmode(CBED_MODE) # alway in CBED mode
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
# setting default simulation controls
|
|
190
|
+
self.set_sim_controls(em_controls.simc)
|
|
191
|
+
|
|
192
|
+
dif.setdisksize(dbsize)
|
|
193
|
+
|
|
194
|
+
self.load()
|
|
195
|
+
|
|
196
|
+
tx, ty = em_controls.tilt[0], em_controls.tilt[1]
|
|
197
|
+
dx, dy = em_controls.defl[0], em_controls.defl[1]
|
|
198
|
+
z = em_controls.zone
|
|
199
|
+
vt, cl = em_controls.vt, em_controls.cl
|
|
200
|
+
|
|
201
|
+
dif.setsamplecontrols(tx, ty, dx, dy)
|
|
202
|
+
dif.setemcontrols(cl, vt)
|
|
203
|
+
dif.setzone(z[0], z[1], z[2])
|
|
204
|
+
|
|
205
|
+
if em_controls.xaxis != DEF_XAXIS:
|
|
206
|
+
xa = em_controls.xaxis
|
|
207
|
+
dif.set_xaxis(1, xa[0], xa[1], xa[2])
|
|
208
|
+
|
|
209
|
+
ret = dif.diffract(1)
|
|
210
|
+
if ret == 0:
|
|
211
|
+
dif.diff_internaldelete(1)
|
|
212
|
+
raise BlochError('Error bloch runtime1')
|
|
213
|
+
|
|
214
|
+
dif.diff_internaldelete(1)
|
|
215
|
+
|
|
216
|
+
ret = bloch.dobloch(aperture,omega,sampling,0.0)
|
|
217
|
+
|
|
218
|
+
if ret == 2:
|
|
219
|
+
raise BlochError('Predefined Bloch computation resource limit reached')
|
|
220
|
+
|
|
221
|
+
if ret != 0:
|
|
222
|
+
raise BlochError('Error computing dynamic diffraction')
|
|
223
|
+
|
|
224
|
+
nsampling = bloch.get_nsampling()
|
|
225
|
+
sampling_points = farray(np.zeros((2, nsampling)), dtype=int)
|
|
226
|
+
sampling_points, ret = bloch.get_samplingpoints(sampling_points)
|
|
227
|
+
|
|
228
|
+
if ret != 0:
|
|
229
|
+
raise BlochError('Failed to retrive sampling points used in scattering matrix run')
|
|
230
|
+
|
|
231
|
+
spoints = np.transpose(sampling_points)
|
|
232
|
+
|
|
233
|
+
# convert the np array to a array of python native tuple
|
|
234
|
+
sp = [(list(p)[0].item(),list(p)[1].item()) for p in spoints]
|
|
235
|
+
|
|
236
|
+
# updating controls with input params as optional attributes for easy handling
|
|
237
|
+
em_controls(mode = 2,
|
|
238
|
+
dsize = dbsize,
|
|
239
|
+
aperture = aperture)
|
|
240
|
+
|
|
241
|
+
em_controls.simc(omega = omega,
|
|
242
|
+
sampling = sampling
|
|
243
|
+
)
|
|
244
|
+
# update x-axis if it was set to (0,0,0)
|
|
245
|
+
# and new xaxis is calculated by the backend
|
|
246
|
+
|
|
247
|
+
if em_controls.xaxis == DEF_XAXIS:
|
|
248
|
+
xa1 = 0
|
|
249
|
+
xa2 = 2
|
|
250
|
+
xa3 = 0
|
|
251
|
+
xa1, xa2, xa3 = dif.get_xaxis()
|
|
252
|
+
em_controls(xaxis = (xa1,xa2,xa3))
|
|
253
|
+
|
|
254
|
+
self.session_controls=em_controls
|
|
255
|
+
return nsampling, sp
|
|
256
|
+
|
|
257
|
+
def getBlochImages(self,
|
|
258
|
+
sample_thickness = DEF_THICKNESS,
|
|
259
|
+
pix_size = DEF_PIXSIZE,
|
|
260
|
+
det_size = DEF_DETSIZE,
|
|
261
|
+
nType = TY_NORMAL,
|
|
262
|
+
bSave = False):
|
|
263
|
+
"""
|
|
264
|
+
Retrieves a set of dynamic diffraction image from the simulation
|
|
265
|
+
sessiom marked by:
|
|
266
|
+
|
|
267
|
+
`beginBloch <pyemaps.crystals.html#pyemaps.crystals.Crystal.beginBloch>`_. and
|
|
268
|
+
`endBloch <pyemaps.crystals.html#pyemaps.crystals.Crystal.endBloch>`_.
|
|
269
|
+
|
|
270
|
+
:param thickness: sample thickness range and step in tuple of three integers (th_start, th_end, th_step)
|
|
271
|
+
:type thickness: int, optional
|
|
272
|
+
|
|
273
|
+
:param pix_size: Detector pixel size in microns
|
|
274
|
+
:type pix_size: int, optional
|
|
275
|
+
|
|
276
|
+
:param det_size: Detector size or output image size
|
|
277
|
+
:type det_size: int, optional
|
|
278
|
+
|
|
279
|
+
:param nType: type of bloch images generated. 0 for normal or 1 for large angle CBED images
|
|
280
|
+
:type nType: int, optional. defaults to 0
|
|
281
|
+
|
|
282
|
+
:param bSave: True - save the output to a raw image file with extension of 'im3'
|
|
283
|
+
:type bSave: bool, optional
|
|
284
|
+
|
|
285
|
+
:return: `BImgList <pyemaps.ddiffs.html#pyemaps.ddiffs.BlochImgs>`_ object
|
|
286
|
+
:rtype: BImgList
|
|
287
|
+
|
|
288
|
+
Default values:
|
|
289
|
+
|
|
290
|
+
::
|
|
291
|
+
|
|
292
|
+
DEF_PIXSIZE = 25
|
|
293
|
+
DEF_DETSIZE = 512
|
|
294
|
+
DEF_THICKNESS = (200, 200, 100)
|
|
295
|
+
|
|
296
|
+
.. warning::
|
|
297
|
+
|
|
298
|
+
Dynamic diffraction pattern generation or Bloch has an extensive memory
|
|
299
|
+
requirement for regular image generation:
|
|
300
|
+
|
|
301
|
+
nType = TY_NORMAL
|
|
302
|
+
|
|
303
|
+
Even more so for a large angle CBED generation when nType = TY_LACBED.
|
|
304
|
+
|
|
305
|
+
To reduce the memory needed, it is recommended to lower input parameters, particularly:
|
|
306
|
+
|
|
307
|
+
- The detector size *det_size*.
|
|
308
|
+
A reduction of the default value of 512 to 218 for example can reduce memory usage in
|
|
309
|
+
pyemaps without losing accuracies of the results.
|
|
310
|
+
|
|
311
|
+
- The number of sampling points in *sampling*.
|
|
312
|
+
With less available memory on the system where pyemaps is running, decreased sampling
|
|
313
|
+
points in *sampling* parameter can make a big difference in pyemaps performance.
|
|
314
|
+
"""
|
|
315
|
+
from copy import deepcopy
|
|
316
|
+
|
|
317
|
+
if pix_size is None or not isinstance(pix_size, int):
|
|
318
|
+
raise BlochListError('Pixel size input must be valid integert')
|
|
319
|
+
|
|
320
|
+
if det_size is None or not isinstance(det_size, int):
|
|
321
|
+
raise BlochListError('Pixel size input must be valid integert')
|
|
322
|
+
|
|
323
|
+
if sample_thickness is None or \
|
|
324
|
+
not all(isinstance(v, int) for v in sample_thickness) or \
|
|
325
|
+
len(sample_thickness) !=3:
|
|
326
|
+
raise BlochListError('Sample thickness input must be valid tuple of three integers')
|
|
327
|
+
|
|
328
|
+
th_start, th_end, th_step = sample_thickness
|
|
329
|
+
|
|
330
|
+
if th_start > th_end or th_step <= 0:
|
|
331
|
+
raise BlochListError('Sample thickness input must be valid integers range')
|
|
332
|
+
|
|
333
|
+
thlist = []
|
|
334
|
+
if th_start == th_end:
|
|
335
|
+
thlist.append(th_start)
|
|
336
|
+
else:
|
|
337
|
+
thlist = list(range(th_start, th_end, th_step))
|
|
338
|
+
thlist.append(th_end)
|
|
339
|
+
|
|
340
|
+
ndep = len(thlist)
|
|
341
|
+
|
|
342
|
+
if ndep > MAX_DEPTH:
|
|
343
|
+
raise BlochListError(f'Number of sample thickness cannot exceed {MAX_DEPTH}')
|
|
344
|
+
|
|
345
|
+
# save the input as optional control attributes
|
|
346
|
+
imgfn =''
|
|
347
|
+
if bSave:
|
|
348
|
+
imgfn, bfn, l = self._getBlochFN()
|
|
349
|
+
if l > MAX_BIMGFN-1:
|
|
350
|
+
raise BlochError(f'File name must not exceed {MAX_BIMGFN-1}')
|
|
351
|
+
|
|
352
|
+
if bloch.openimgfile(det_size, ndep, bfn, l) != 0:
|
|
353
|
+
raise BlochError('Error opening file for write, check if you have write permission')
|
|
354
|
+
|
|
355
|
+
isLACBED = (nType == TY_LACBED)
|
|
356
|
+
# for th in thlist:
|
|
357
|
+
nslices = ndep
|
|
358
|
+
nout = 0
|
|
359
|
+
if isLACBED:
|
|
360
|
+
nout = bloch.getncalcbeams()
|
|
361
|
+
nslices = ndep*nout
|
|
362
|
+
|
|
363
|
+
bimg = farray(np.zeros((det_size, det_size, nslices), dtype=np.float32))
|
|
364
|
+
thl = farray(np.array(thlist), dtype=int)
|
|
365
|
+
|
|
366
|
+
bimg, ret = bloch.getimage(thl,
|
|
367
|
+
bimg,
|
|
368
|
+
teta = 0,
|
|
369
|
+
pix = pix_size,
|
|
370
|
+
det = det_size,
|
|
371
|
+
blacbed = isLACBED,
|
|
372
|
+
bsave = bSave)
|
|
373
|
+
|
|
374
|
+
if(ret != 0):
|
|
375
|
+
raise BlochError("bloch image generation failed!")
|
|
376
|
+
|
|
377
|
+
# build a image list
|
|
378
|
+
bimgs = BImgList(self.name)
|
|
379
|
+
|
|
380
|
+
self.session_controls(pix_size=pix_size, det_size=det_size)
|
|
381
|
+
|
|
382
|
+
for i, th in enumerate(thlist):
|
|
383
|
+
emc = deepcopy(self.session_controls)
|
|
384
|
+
emc.simc(sth=th)
|
|
385
|
+
if isLACBED:
|
|
386
|
+
for j in range(nout):
|
|
387
|
+
bimgs.add(emc, bimg[:,:,i*nout + j])
|
|
388
|
+
else:
|
|
389
|
+
bimgs.add(emc, bimg[:,:,i])
|
|
390
|
+
|
|
391
|
+
|
|
392
|
+
if bSave:
|
|
393
|
+
if bloch.closeimgfile() != 0:
|
|
394
|
+
raise BlochError('Error closing file')
|
|
395
|
+
|
|
396
|
+
print(f'The raw bloch image(s) of dimensions {det_size}x{det_size}x{nslices} and an offset of 8 bytes successfully saved to: \n{imgfn}')
|
|
397
|
+
print(f'To view, import the file into ImageJ or other raw image visualization tools')
|
|
398
|
+
|
|
399
|
+
return bimgs
|
|
400
|
+
|
|
401
|
+
def getIBDetails(self, bPrint=True):
|
|
402
|
+
'''
|
|
403
|
+
Retrieve a dynamic diffraction simulation details during a session
|
|
404
|
+
marked by
|
|
405
|
+
`beginBloch <pyemaps.crystals.html#pyemaps.crystals.Crystal.beginBloch>`_. and
|
|
406
|
+
`endBloch <pyemaps.crystals.html#pyemaps.crystals.Crystal.endBloch>`_.
|
|
407
|
+
|
|
408
|
+
Information regarding the simulation session include sampling points and their
|
|
409
|
+
associated diffracted beam directions etc.
|
|
410
|
+
|
|
411
|
+
The information is available right after beginBloch call.
|
|
412
|
+
|
|
413
|
+
'''
|
|
414
|
+
nib = bloch.get_nsampling()
|
|
415
|
+
if nib <=0:
|
|
416
|
+
raise BlochError("Failed to retrieve number of incidental beams")
|
|
417
|
+
|
|
418
|
+
if nib == 0:
|
|
419
|
+
raise BlochError("No incidental beams found")
|
|
420
|
+
|
|
421
|
+
|
|
422
|
+
net = farray(np.zeros((2, nib), dtype=int))
|
|
423
|
+
tilt = farray(np.zeros((3, nib), dtype=float))
|
|
424
|
+
|
|
425
|
+
net, tilt, ret = bloch.getibinfo(net, tilt)
|
|
426
|
+
if ret != 0:
|
|
427
|
+
raise BlochError("failed to retrieve incidental beams info")
|
|
428
|
+
|
|
429
|
+
if bPrint:
|
|
430
|
+
print(f'\n-------Dynamic Diffraction Simulation Session for {self._name}---------\n')
|
|
431
|
+
print(f'Total Number of sampling points: {nib}\n')
|
|
432
|
+
|
|
433
|
+
smp = "Sampling"
|
|
434
|
+
stilt = "Beam Tilts In Reciprical Space"
|
|
435
|
+
|
|
436
|
+
print(f"{smp:^11}{stilt:^48}")
|
|
437
|
+
print(f"{'Points':^11}\n")
|
|
438
|
+
|
|
439
|
+
ibnet = np.transpose(net)
|
|
440
|
+
ibtilt = np.transpose(tilt)
|
|
441
|
+
|
|
442
|
+
# if bPrint:
|
|
443
|
+
ibs_list =[]
|
|
444
|
+
for i in range(1, nib+1, 1):
|
|
445
|
+
net1, net2 = ibnet[i-1]
|
|
446
|
+
t1,t2,t3 = ibtilt[i-1]
|
|
447
|
+
ibs_list.append(dict(ib=(net1, net2), tilt=ibtilt[i-1]))
|
|
448
|
+
if bPrint:
|
|
449
|
+
sn1 = '{0: < #06d}'. format(int(net1))
|
|
450
|
+
sn2 = '{0: < #06d}'. format(int(net2))
|
|
451
|
+
st1 = '{0: < #016.10f}'. format(float(t1))
|
|
452
|
+
st2 = '{0: < #016.10f}'. format(float(t2))
|
|
453
|
+
st3 = '{0: < #016.7g}'. format(float(t3))
|
|
454
|
+
|
|
455
|
+
print(f"{sn1}{sn2}{st1}{st2}{st3}")
|
|
456
|
+
|
|
457
|
+
return nib, ibs_list
|
|
458
|
+
|
|
459
|
+
def getCalculatedBeams(self, bPrint=False):
|
|
460
|
+
'''
|
|
461
|
+
Retieves and/or prints calculated beams for current dynamic diffraction simulation
|
|
462
|
+
session marked by
|
|
463
|
+
`beginBloch <pyemaps.crystals.html#pyemaps.crystals.Crystal.beginBloch>`_
|
|
464
|
+
and `endBloch <pyemaps.crystals.html#pyemaps.crystals.Crystal.endBloch>`_.
|
|
465
|
+
|
|
466
|
+
This information is available right after beginBloch call.
|
|
467
|
+
|
|
468
|
+
:param bPrint: whether to print selected diffracted beams info on standard output
|
|
469
|
+
:type bPrint: bool, optional, default `False`
|
|
470
|
+
|
|
471
|
+
:return: The number of selected beams and the selected beams list in Miller indexes.
|
|
472
|
+
:rtype: a python tuple.
|
|
473
|
+
|
|
474
|
+
'''
|
|
475
|
+
ncalcbeams = bloch.getncalcbeams()
|
|
476
|
+
if ncalcbeams <= 0:
|
|
477
|
+
raise BlochError("failed to retrieve diffracted beams info")
|
|
478
|
+
|
|
479
|
+
cb = farray(np.zeros((3, ncalcbeams), dtype=int))
|
|
480
|
+
|
|
481
|
+
cb, ret = bloch.getcalcbeams(cb)
|
|
482
|
+
|
|
483
|
+
if ret != 0:
|
|
484
|
+
raise BlochError("failed to retrieve incidental beams info")
|
|
485
|
+
|
|
486
|
+
cbms = np.transpose(cb)
|
|
487
|
+
|
|
488
|
+
if bPrint:
|
|
489
|
+
print('---------Calculated Beams in Miller Indexes---------')
|
|
490
|
+
shkl = "h K l"
|
|
491
|
+
print(f"{shkl:^12}")
|
|
492
|
+
|
|
493
|
+
for cbm in cbms:
|
|
494
|
+
h,k,l = cbm
|
|
495
|
+
sh = '{0: < #04d}'. format(int(h))
|
|
496
|
+
sk = '{0: < #04d}'. format(int(k))
|
|
497
|
+
sl = '{0: < #04d}'. format(int(l))
|
|
498
|
+
|
|
499
|
+
print(f"{sh}{sk}{sl}")
|
|
500
|
+
|
|
501
|
+
return ncalcbeams, cbms
|
|
502
|
+
|
|
503
|
+
# ----------------deprecated and folded into getSCMatrix call----------------
|
|
504
|
+
# def getEigen(self, ib_coords=(0,0)):
|
|
505
|
+
# '''
|
|
506
|
+
# Returns eigen values for given sampling point.
|
|
507
|
+
# It must be called during a dynamic diffraction simulation session
|
|
508
|
+
# marked by
|
|
509
|
+
# `beginBloch <pyemaps.crystals.html#pyemaps.crystals.Crystal.beginBloch>`_ and
|
|
510
|
+
# `endBloch <pyemaps.crystals.html#pyemaps.crystals.Crystal.endBloch>`_.
|
|
511
|
+
# :param ib_coords: Sampling point coordinates tuple
|
|
512
|
+
# :type ib_coords: tuple, optional, default (0,0)
|
|
513
|
+
# :return: a list of complex eigen values at sampling point location
|
|
514
|
+
# :rtype: numpy.ndarray
|
|
515
|
+
|
|
516
|
+
# Example of the eigen vales:
|
|
517
|
+
# .. code-block:: console
|
|
518
|
+
# Eigen values at: (0, 0):
|
|
519
|
+
# [ 0.04684002-0.00218389j -0.2064669 -0.00147516j -0.30446348+0.00055009j
|
|
520
|
+
# -0.27657617+0.00023512j -0.2765751 +0.00023515j 0.00539041-0.00382443j
|
|
521
|
+
# -0.535879 -0.00023585j -0.5612881 +0.00045343j -0.55369247+0.00026236j
|
|
522
|
+
# -0.55368818+0.00026249j -0.19093572+0.00066419j -0.1550311 +0.00045471j
|
|
523
|
+
# -0.15503166+0.00045471j -0.58842399-0.00202841j -0.67850191+0.00042728j
|
|
524
|
+
# -0.72713566+0.00060655j -0.70972681+0.00052279j -0.72092338+0.0005903j
|
|
525
|
+
# -0.72093237+0.00059052j -0.64608335-0.0001983j -0.64607544-0.00019853j]
|
|
526
|
+
# '''
|
|
527
|
+
# # validate the input values
|
|
528
|
+
|
|
529
|
+
# if ib_coords is None or not all(isinstance(v, int) for v in ib_coords) or len(ib_coords) != 2:
|
|
530
|
+
# raise BlochError("Invalid incident beam coordinates input, must be tuple of two integers")
|
|
531
|
+
|
|
532
|
+
# scmdim = bloch.get_scmdim(ib_coords)
|
|
533
|
+
# if scmdim <= 0:
|
|
534
|
+
# raise BlochError("Error finding corresponding scattering matrix, use getIBDetails to find potential input for ib_coords")
|
|
535
|
+
|
|
536
|
+
# ev = farray(np.zeros(scmdim, dtype=np.complex64))
|
|
537
|
+
# ev, ret = bloch.geteigenvalues(ib_coords, ev)
|
|
538
|
+
# if ret < 0 or ret > scmdim:
|
|
539
|
+
# raise BlochError("failed to retrieve incidental beams info")
|
|
540
|
+
|
|
541
|
+
# return ev
|
|
542
|
+
|
|
543
|
+
def getSCMatrix(self,
|
|
544
|
+
ib_coords = (0,0),
|
|
545
|
+
sample_thickness = DEF_THICKNESS[0],
|
|
546
|
+
rvec = (0.0,0.0,0.0)
|
|
547
|
+
):
|
|
548
|
+
'''
|
|
549
|
+
|
|
550
|
+
Obtains scattering matrix at a given sampling point. To get a list of sampling
|
|
551
|
+
points used in this dynamic simulation session, call
|
|
552
|
+
`getIBDetails <pyemaps.crystals.html#pyemaps.crystals.Crystal.getIBDetails>`_
|
|
553
|
+
after `beginBloch <pyemaps.crystals.html#pyemaps.crystals.Crystal.beginBloch>`_.
|
|
554
|
+
In addition to the scattering matrix, it also generates associated eigen values
|
|
555
|
+
and diffracted beams.
|
|
556
|
+
|
|
557
|
+
This call must be made during a dynamic simulation session marked by
|
|
558
|
+
`beginBloch <pyemaps.crystals.html#pyemaps.crystals.Crystal.beginBloch>`_ and
|
|
559
|
+
`endBloch <pyemaps.crystals.html#pyemaps.crystals.Crystal.endBloch>`_.
|
|
560
|
+
|
|
561
|
+
:param ib_coords: Sampling point coordinates tuple.
|
|
562
|
+
:type ib_coords: tuple, optional, defaults to (0, 0)
|
|
563
|
+
|
|
564
|
+
:param thickness: Sample thickness.
|
|
565
|
+
:type thickness: int, optional, defaults to 200
|
|
566
|
+
|
|
567
|
+
:param rvec: R vector shifting atom coordinates in crystal, each value between 0.0 and 1.0.
|
|
568
|
+
:type rvec: tuple of 3 floats, optional, defaults to (0.0,0.0,0.0)
|
|
569
|
+
|
|
570
|
+
:return: scattering matrix size; scattering matrix; eigen values; diffracted beams.
|
|
571
|
+
:rtype: a tuple.
|
|
572
|
+
|
|
573
|
+
Default values for sample_thickness:
|
|
574
|
+
|
|
575
|
+
::
|
|
576
|
+
|
|
577
|
+
DEF_THICKNESS[0] = 200
|
|
578
|
+
|
|
579
|
+
Example of the eigen vales:
|
|
580
|
+
|
|
581
|
+
.. code-block:: console
|
|
582
|
+
|
|
583
|
+
Eigen values at: (0, 0):
|
|
584
|
+
[ 0.04684002-0.00218389j -0.2064669 -0.00147516j -0.30446348+0.00055009j
|
|
585
|
+
-0.27657617+0.00023512j -0.2765751 +0.00023515j 0.00539041-0.00382443j
|
|
586
|
+
-0.535879 -0.00023585j -0.5612881 +0.00045343j -0.55369247+0.00026236j
|
|
587
|
+
-0.55368818+0.00026249j -0.19093572+0.00066419j -0.1550311 +0.00045471j
|
|
588
|
+
-0.15503166+0.00045471j -0.58842399-0.00202841j -0.67850191+0.00042728j
|
|
589
|
+
-0.72713566+0.00060655j -0.70972681+0.00052279j -0.72092338+0.0005903j
|
|
590
|
+
-0.72093237+0.00059052j -0.64608335-0.0001983j -0.64607544-0.00019853j]
|
|
591
|
+
|
|
592
|
+
'''
|
|
593
|
+
|
|
594
|
+
# validate the input values
|
|
595
|
+
if ib_coords is None or len(ib_coords) != 2 or not all(isinstance(v, int) for v in ib_coords):
|
|
596
|
+
raise BlochError("Invalid incident beam coordinates input, must be tuple of two integers2")
|
|
597
|
+
|
|
598
|
+
if sample_thickness is None or not isinstance(sample_thickness, int):
|
|
599
|
+
raise BlochError("Sample thickness ")
|
|
600
|
+
|
|
601
|
+
if rvec is None or not all(isinstance(v, (int,float)) for v in rvec) or len(rvec) != 3:
|
|
602
|
+
raise BlochError("Invalid R-vector input, must be tuple of three floats")
|
|
603
|
+
|
|
604
|
+
# get the dimension of the scattering matrix
|
|
605
|
+
scmdim, RET = bloch.compute_scm([ib_coords[0], ib_coords[1]])
|
|
606
|
+
|
|
607
|
+
if RET != 0 or scmdim <= 0:
|
|
608
|
+
raise BlochError("Error finding corresponding scattering matrix")
|
|
609
|
+
|
|
610
|
+
scm = farray(np.zeros((scmdim, scmdim)), dtype=np.complex64)
|
|
611
|
+
ev = farray(np.zeros(scmdim), dtype=np.complex64)
|
|
612
|
+
bms = farray(np.zeros((3, scmdim), dtype=int))
|
|
613
|
+
scm, ev, bms, ret = bloch.getscm(sample_thickness, rvec, scm, ev, bms)
|
|
614
|
+
if ret != 0:
|
|
615
|
+
raise BlochError('Error retieving scattering matrix, input matrix dimension too small, use getIBDetails to find extact dimentsion')
|
|
616
|
+
|
|
617
|
+
return scmdim, scm, ev, np.transpose(bms)
|
|
618
|
+
|
|
619
|
+
def endBloch(self):
|
|
620
|
+
"""
|
|
621
|
+
Clean up Bloch module. This function follows
|
|
622
|
+
`beginBloch <pyemaps.crystals.html#pyemaps.crystals.Crystal.beginBloch>`_
|
|
623
|
+
to mark the end of a dynamic simulation session.
|
|
624
|
+
|
|
625
|
+
"""
|
|
626
|
+
dif.diff_delete()
|
|
627
|
+
bloch.free_bloch()
|
|
628
|
+
|
|
629
|
+
def generateBloch(self, aperture = DEF_APERTURE,
|
|
630
|
+
omega = DEF_OMEGA,
|
|
631
|
+
sampling = DEF_SAMPLING,
|
|
632
|
+
pix_size = DEF_PIXSIZE,
|
|
633
|
+
det_size = DEF_DETSIZE,
|
|
634
|
+
disk_size = DEF_CBED_DSIZE,
|
|
635
|
+
sample_thickness = DEF_THICKNESS,
|
|
636
|
+
em_controls = EMC(cl=200, # set smaller that 1000 default value
|
|
637
|
+
simc = SIMC(gmax=1.0, excitation=(0.3,1.0))),
|
|
638
|
+
nType = TY_NORMAL,
|
|
639
|
+
bSave = False):
|
|
640
|
+
"""
|
|
641
|
+
Generates dynamic diffraction (Bloch) image(s). This function is equivalent to
|
|
642
|
+
calling :
|
|
643
|
+
|
|
644
|
+
1. `beginBloch <pyemaps.crystals.html#pyemaps.crystals.Crystal.beginBloch>`_
|
|
645
|
+
2. `getBlockImages <pyemaps.crystals.html#pyemaps.crystals.Crystal.getBlockImages>`_
|
|
646
|
+
3. `endBloch <pyemaps.crystals.html#pyemaps.crystals.Crystal.endBloch>`_
|
|
647
|
+
|
|
648
|
+
:param aperture: Objective aperture.
|
|
649
|
+
:type aperture: float, optional
|
|
650
|
+
|
|
651
|
+
:param omega: Diagnization cutoff value, defaults to 10.
|
|
652
|
+
:type omega: float, optional
|
|
653
|
+
|
|
654
|
+
:param sampling: Number of sampling points
|
|
655
|
+
:type sampling: int, optional
|
|
656
|
+
|
|
657
|
+
:param pix_size: Detector pixel size in microns
|
|
658
|
+
:type pix_size: int, optional
|
|
659
|
+
|
|
660
|
+
:param det_size: Detector size or output image size
|
|
661
|
+
:type det_size: int, optional
|
|
662
|
+
|
|
663
|
+
:param disk_size: Diffracted beams size in range
|
|
664
|
+
:type disk_size: float, optional
|
|
665
|
+
|
|
666
|
+
:param sample_thickness: Sample thickness in (start, end, step) tuple
|
|
667
|
+
:type sample_thickness: tuple of int, optional
|
|
668
|
+
|
|
669
|
+
:param nType: type of bloch images generated. 0 for normal or 1 for large angle CBED images
|
|
670
|
+
:type nType: int, optional. defaults to 0
|
|
671
|
+
|
|
672
|
+
:param em_controls: Microscope controls object
|
|
673
|
+
:type em_controls: `Microscope control <pyemaps.emcontrols.html#module-pyemaps.emcontrols>`_, optional
|
|
674
|
+
|
|
675
|
+
:param bSave: `True` - save the output to a raw image file (ext: im3)
|
|
676
|
+
:type bSave: bool, optional
|
|
677
|
+
|
|
678
|
+
:return: `BImgList <pyemaps.ddiffs.html#pyemaps.ddiffs.BlochImgs>`_ object
|
|
679
|
+
:rtype: BImgList
|
|
680
|
+
|
|
681
|
+
Default values:
|
|
682
|
+
|
|
683
|
+
::
|
|
684
|
+
|
|
685
|
+
DEF_APERTURE = 1.0
|
|
686
|
+
DEF_OMEGA = 10
|
|
687
|
+
DEF_SAMPLING = 8
|
|
688
|
+
DEF_CBED_DSIZE = 0.16
|
|
689
|
+
DEF_DSIZE_LIMITS =(0.01, 0.5)
|
|
690
|
+
DEF_PIXSIZE = 25
|
|
691
|
+
DEF_DETSIZE = 512
|
|
692
|
+
DEF_THICKNESS = (200, 200, 100)
|
|
693
|
+
|
|
694
|
+
.. note::
|
|
695
|
+
|
|
696
|
+
There will be one slice of image generated for each sample
|
|
697
|
+
thickness specified by sample_thickness = (start, end, step) arguement:
|
|
698
|
+
|
|
699
|
+
start, start+step ... start+N*step, end
|
|
700
|
+
|
|
701
|
+
.. warning::
|
|
702
|
+
|
|
703
|
+
Dynamic diffraction pattern generation or Bloch has an extensive memory
|
|
704
|
+
requirement for regular image generation:
|
|
705
|
+
|
|
706
|
+
nType = TY_NORMAL
|
|
707
|
+
|
|
708
|
+
Even more so for a large angle CBED generation when nType = TY_LACBED.
|
|
709
|
+
|
|
710
|
+
To reduce the memory needed, it is recommended to lower input parameters, particularly:
|
|
711
|
+
|
|
712
|
+
- The detector size *det_size*.
|
|
713
|
+
A reduction of the default value of 512 to 218 for example can reduce memory usage in
|
|
714
|
+
pyemaps without losing accuracies of the results.
|
|
715
|
+
|
|
716
|
+
- The number of sampling points in *sampling*.
|
|
717
|
+
With less available memory on the system where pyemaps is running, decreased sampling
|
|
718
|
+
points in *sampling* parameter can make a big difference in pyemaps performance.
|
|
719
|
+
|
|
720
|
+
"""
|
|
721
|
+
try:
|
|
722
|
+
|
|
723
|
+
_, _ = self.beginBloch(aperture=aperture,
|
|
724
|
+
omega=omega,
|
|
725
|
+
sampling=sampling,
|
|
726
|
+
dbsize = disk_size,
|
|
727
|
+
em_controls=em_controls)
|
|
728
|
+
|
|
729
|
+
except BlochError as e:
|
|
730
|
+
# re-raise the same error, so that the caller can handle it
|
|
731
|
+
raise e
|
|
732
|
+
|
|
733
|
+
except Exception as e:
|
|
734
|
+
# Any other exception will be handled by the callers as BlochError from this point on
|
|
735
|
+
raise BlochError(f'Something went wrong in starting bloch simulation') from e
|
|
736
|
+
|
|
737
|
+
else:
|
|
738
|
+
try:
|
|
739
|
+
bimgs = self.getBlochImages(
|
|
740
|
+
sample_thickness = sample_thickness,
|
|
741
|
+
pix_size = pix_size,
|
|
742
|
+
det_size = det_size,
|
|
743
|
+
nType = nType,
|
|
744
|
+
bSave = bSave)
|
|
745
|
+
|
|
746
|
+
except (BlochError, BlochListError) as e:
|
|
747
|
+
raise
|
|
748
|
+
|
|
749
|
+
except Exception as e:
|
|
750
|
+
raise BlochError(f'Something went wrong when retrieving bloch image {e}') from e
|
|
751
|
+
|
|
752
|
+
else:
|
|
753
|
+
return bimgs
|
|
754
|
+
|
|
755
|
+
finally:
|
|
756
|
+
self.endBloch()
|
|
757
|
+
|
|
758
|
+
finally:
|
|
759
|
+
self.endBloch()
|
|
760
|
+
|
|
761
|
+
|
|
762
|
+
|
|
763
|
+
target.beginBloch = beginBloch
|
|
764
|
+
target._getBlochFN = _getBlochFN
|
|
765
|
+
|
|
766
|
+
# ---These calls must be between beginBloch and endBloch calls
|
|
767
|
+
target.getIBDetails = getIBDetails
|
|
768
|
+
# target.getBeams = getBeams <-------deprecate
|
|
769
|
+
target.getSCMatrix = getSCMatrix
|
|
770
|
+
target.getBlochImages = getBlochImages
|
|
771
|
+
target.getCalculatedBeams = getCalculatedBeams
|
|
772
|
+
# target.getLACBEDImage = getLACBEDImage
|
|
773
|
+
# ---These calls must be between beginBloch and endBloch calls
|
|
774
|
+
|
|
775
|
+
target.endBloch = endBloch
|
|
776
|
+
|
|
777
|
+
target.generateBloch = generateBloch
|
|
778
|
+
|
|
779
|
+
return target
|