pyTEMlib 0.2023.3.0__py2.py3-none-any.whl → 0.2023.8.0__py2.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.
Potentially problematic release.
This version of pyTEMlib might be problematic. Click here for more details.
- pyTEMlib/crystal_tools.py +47 -5
- pyTEMlib/eels_dialog.py +673 -42
- pyTEMlib/eels_dialog_utilities.py +8 -4
- pyTEMlib/eels_dlg.py +6 -5
- pyTEMlib/eels_tools.py +118 -38
- pyTEMlib/file_tools.py +95 -13
- pyTEMlib/graph_tools.py +716 -10
- pyTEMlib/image_dialog.py +1 -1
- pyTEMlib/image_dlg.py +1 -1
- pyTEMlib/image_tools.py +82 -39
- pyTEMlib/info_dialog.py +356 -15
- pyTEMlib/info_dlg.py +1 -1
- pyTEMlib/info_widget.py +655 -0
- pyTEMlib/interactive_eels.py +12 -4
- pyTEMlib/peak_dialog.py +807 -120
- pyTEMlib/peak_dlg.py +53 -24
- pyTEMlib/version.py +2 -2
- pyTEMlib/viz.py +217 -0
- pyTEMlib/xrpa_x_sections.py +39 -25
- {pyTEMlib-0.2023.3.0.dist-info → pyTEMlib-0.2023.8.0.dist-info}/METADATA +5 -5
- pyTEMlib-0.2023.8.0.dist-info/RECORD +40 -0
- {pyTEMlib-0.2023.3.0.dist-info → pyTEMlib-0.2023.8.0.dist-info}/WHEEL +1 -1
- pyTEMlib-0.2023.3.0.dist-info/RECORD +0 -39
- {pyTEMlib-0.2023.3.0.dist-info → pyTEMlib-0.2023.8.0.dist-info}/LICENSE +0 -0
- {pyTEMlib-0.2023.3.0.dist-info → pyTEMlib-0.2023.8.0.dist-info}/entry_points.txt +0 -0
- {pyTEMlib-0.2023.3.0.dist-info → pyTEMlib-0.2023.8.0.dist-info}/top_level.txt +0 -0
|
@@ -12,7 +12,7 @@ try:
|
|
|
12
12
|
|
|
13
13
|
except:
|
|
14
14
|
Qt_available = False
|
|
15
|
-
print('Qt dialogs are not available')
|
|
15
|
+
# print('Qt dialogs are not available')
|
|
16
16
|
|
|
17
17
|
import sidpy
|
|
18
18
|
import matplotlib.patches as patches
|
|
@@ -233,7 +233,7 @@ if Qt_available:
|
|
|
233
233
|
|
|
234
234
|
self.selector = SpanSelector(self.axis, self.line_select_callback,
|
|
235
235
|
direction="horizontal",
|
|
236
|
-
|
|
236
|
+
interactive=True,
|
|
237
237
|
props=dict(facecolor='blue', alpha=0.2))
|
|
238
238
|
self.edit1.setText(f'{self.x_min:.3f}')
|
|
239
239
|
self.edit2.setText(f'{self.x_max:.3f}')
|
|
@@ -364,8 +364,10 @@ class RegionSelector(object):
|
|
|
364
364
|
self.xmin = 0
|
|
365
365
|
self.width = 0
|
|
366
366
|
|
|
367
|
-
self.span = SpanSelector(ax, self.on_select1,
|
|
368
|
-
|
|
367
|
+
self.span = SpanSelector(ax, self.on_select1,
|
|
368
|
+
direction="horizontal",
|
|
369
|
+
interactive=True,
|
|
370
|
+
props=dict(facecolor='blue', alpha=0.2))
|
|
369
371
|
self.cid = ax.figure.canvas.mpl_connect('key_press_event', self.click)
|
|
370
372
|
self.draw = ax.figure.canvas.mpl_connect('draw_event', self.onresize)
|
|
371
373
|
|
|
@@ -552,6 +554,8 @@ def get_likely_edges(energy_scale):
|
|
|
552
554
|
return likely_edges
|
|
553
555
|
|
|
554
556
|
|
|
557
|
+
|
|
558
|
+
|
|
555
559
|
def get_periodic_table_info():
|
|
556
560
|
"""Info for periodic table dialog"""
|
|
557
561
|
pt_info = \
|
pyTEMlib/eels_dlg.py
CHANGED
|
@@ -15,7 +15,7 @@ try:
|
|
|
15
15
|
from PyQt5 import QtCore, QtGui, QtWidgets
|
|
16
16
|
except:
|
|
17
17
|
Qt_available = False
|
|
18
|
-
print('Qt dialogs are not available')
|
|
18
|
+
# print('Qt dialogs are not available')
|
|
19
19
|
|
|
20
20
|
if Qt_available:
|
|
21
21
|
class UiDialog(object):
|
|
@@ -23,7 +23,7 @@ if Qt_available:
|
|
|
23
23
|
def __init__(self, dialog):
|
|
24
24
|
dialog.setObjectName('Fit Composition Input')
|
|
25
25
|
dialog.resize(371, 184)
|
|
26
|
-
|
|
26
|
+
self.dialog = dialog
|
|
27
27
|
valid_float = QtGui.QDoubleValidator()
|
|
28
28
|
valid_int = QtGui.QIntValidator()
|
|
29
29
|
valid_int.setBottom(0)
|
|
@@ -85,9 +85,9 @@ if Qt_available:
|
|
|
85
85
|
self.separator2.setText("Elements")
|
|
86
86
|
self.layout.addWidget(self.separator2, row, 0, 1, 4)
|
|
87
87
|
######################################################################
|
|
88
|
-
|
|
89
|
-
self.auto_id_button = QtWidgets.QPushButton('
|
|
90
|
-
self.select_button = QtWidgets.QPushButton('
|
|
88
|
+
|
|
89
|
+
self.auto_id_button = QtWidgets.QPushButton('Auto ID', dialog)
|
|
90
|
+
self.select_button = QtWidgets.QPushButton('Manual ID', dialog)
|
|
91
91
|
|
|
92
92
|
self.layout.addWidget(self.auto_id_button, row, 0)
|
|
93
93
|
self.layout.addWidget(self.select_button, row, 2)
|
|
@@ -238,6 +238,7 @@ if Qt_available:
|
|
|
238
238
|
|
|
239
239
|
self.do_fit_button = QtWidgets.QPushButton('Fit Composition', dialog)
|
|
240
240
|
self.do_fit_button.setCheckable(True)
|
|
241
|
+
self.do_fit_button.setDefault(True)
|
|
241
242
|
|
|
242
243
|
self.layout.addWidget(self.do_all_button, row, 0)
|
|
243
244
|
self.layout.addWidget(self.progress, row, 1)
|
pyTEMlib/eels_tools.py
CHANGED
|
@@ -28,11 +28,6 @@ from scipy.ndimage import gaussian_filter
|
|
|
28
28
|
|
|
29
29
|
from scipy import constants
|
|
30
30
|
import matplotlib.pyplot as plt
|
|
31
|
-
# import matplotlib.patches as patches
|
|
32
|
-
|
|
33
|
-
# from matplotlib.widgets import SpanSelector
|
|
34
|
-
# import ipywidgets as widgets
|
|
35
|
-
# from IPython.display import display
|
|
36
31
|
|
|
37
32
|
import requests
|
|
38
33
|
|
|
@@ -44,6 +39,7 @@ import pickle # pkg_resources,
|
|
|
44
39
|
import pyTEMlib.file_tools as ft
|
|
45
40
|
from pyTEMlib.xrpa_x_sections import x_sections
|
|
46
41
|
|
|
42
|
+
import sidpy
|
|
47
43
|
from sidpy.base.num_utils import get_slope
|
|
48
44
|
|
|
49
45
|
major_edges = ['K1', 'L3', 'M5', 'N5']
|
|
@@ -186,6 +182,7 @@ def fit_peaks(spectrum, energy_scale, pin, start_fit, end_fit, only_positive_int
|
|
|
186
182
|
# TODO: remove zero_loss_fit_width add absolute
|
|
187
183
|
|
|
188
184
|
fit_energy = energy_scale[start_fit:end_fit]
|
|
185
|
+
spectrum = np.array(spectrum)
|
|
189
186
|
fit_spectrum = spectrum[start_fit:end_fit]
|
|
190
187
|
|
|
191
188
|
pin_flat = [item for sublist in pin for item in sublist]
|
|
@@ -922,7 +919,10 @@ def find_peaks(dataset, fit_start, fit_end, sensitivity=2):
|
|
|
922
919
|
if start_channel < index < end_channel:
|
|
923
920
|
peaks.append(index - start_channel)
|
|
924
921
|
|
|
925
|
-
if
|
|
922
|
+
if 'model' in dataset.metadata:
|
|
923
|
+
model = dataset.metadata['model'][start_channel:end_channel]
|
|
924
|
+
|
|
925
|
+
elif energy_scale[0] > 0:
|
|
926
926
|
if 'edges' not in dataset.metadata:
|
|
927
927
|
return
|
|
928
928
|
if 'model' not in dataset.metadata['edges']:
|
|
@@ -936,6 +936,7 @@ def find_peaks(dataset, fit_start, fit_end, sensitivity=2):
|
|
|
936
936
|
|
|
937
937
|
difference = np.array(spectrum)[start_channel:end_channel] - model
|
|
938
938
|
fit = np.zeros(len(energy_scale))
|
|
939
|
+
p_out = []
|
|
939
940
|
if len(peaks) > 0:
|
|
940
941
|
p_in = np.ravel([[energy_scale[i], difference[i], .7] for i in peaks])
|
|
941
942
|
[p_out, _] = scipy.optimize.leastsq(residuals_smooth, p_in, ftol=1e-3, args=(energy_scale,
|
|
@@ -1097,11 +1098,26 @@ def fit_model(x, y, pin, number_of_peaks, peak_shape, p_zl, restrict_pos=0, rest
|
|
|
1097
1098
|
return p, peak_shape
|
|
1098
1099
|
|
|
1099
1100
|
|
|
1100
|
-
def fix_energy_scale(spec, energy):
|
|
1101
|
-
"""Shift energy scale according to zero-loss peak position
|
|
1101
|
+
def fix_energy_scale(spec, energy=None):
|
|
1102
|
+
"""Shift energy scale according to zero-loss peak position
|
|
1103
|
+
|
|
1104
|
+
This function assumes that the fzero loss peak is the maximum of the spectrum.
|
|
1105
|
+
"""
|
|
1106
|
+
|
|
1102
1107
|
# determine start and end fitting region in pixels
|
|
1103
|
-
|
|
1104
|
-
|
|
1108
|
+
if isinstance(spec, sidpy.Dataset):
|
|
1109
|
+
if energy is None:
|
|
1110
|
+
energy = spec.energy_loss.values
|
|
1111
|
+
spec = np.array(spec)
|
|
1112
|
+
|
|
1113
|
+
else:
|
|
1114
|
+
if energy is None:
|
|
1115
|
+
return
|
|
1116
|
+
if not isinstance(spec, np.ndarray):
|
|
1117
|
+
return
|
|
1118
|
+
|
|
1119
|
+
start = np.searchsorted(np.array(energy), -10)
|
|
1120
|
+
end = np.searchsorted(np.array(energy), 10)
|
|
1105
1121
|
startx = np.argmax(spec[start:end]) + start
|
|
1106
1122
|
|
|
1107
1123
|
end = startx + 3
|
|
@@ -1130,6 +1146,31 @@ def fix_energy_scale(spec, energy):
|
|
|
1130
1146
|
|
|
1131
1147
|
return fwhm, fit_mu
|
|
1132
1148
|
|
|
1149
|
+
def resolution_function2(dataset, width =0.3):
|
|
1150
|
+
guess = [0.2, 1000, 0.02, 0.2, 1000, 0.2]
|
|
1151
|
+
p0 = np.array(guess)
|
|
1152
|
+
|
|
1153
|
+
start = np.searchsorted(dataset.energy_loss, -width / 2.)
|
|
1154
|
+
end = np.searchsorted(dataset.energy_loss, width / 2.)
|
|
1155
|
+
x = dataset.energy_loss[start:end]
|
|
1156
|
+
y = np.array(dataset)[start:end]
|
|
1157
|
+
def zl2(pp, yy, xx):
|
|
1158
|
+
eerr = (yy - zl_func(pp, xx)) # /np.sqrt(y)
|
|
1159
|
+
return eerr
|
|
1160
|
+
|
|
1161
|
+
[p_zl, _] = leastsq(zl2, p0, args=(y, x), maxfev=2000)
|
|
1162
|
+
|
|
1163
|
+
z_loss = zl_func(p_zl, dataset.energy_loss)
|
|
1164
|
+
z_loss = dataset.like_data(z_loss)
|
|
1165
|
+
z_loss.title = 'resolution_function'
|
|
1166
|
+
z_loss.metadata['zero_loss_parameter']=p_zl
|
|
1167
|
+
|
|
1168
|
+
dataset.metadata['low_loss']['zero_loss'] = {'zero_loss_parameter': p_zl,
|
|
1169
|
+
'zero_loss_fit': 'Product2Lorentzians'}
|
|
1170
|
+
zero_loss = dataset.like_array(z_loss)
|
|
1171
|
+
return zero_loss, p_zl
|
|
1172
|
+
|
|
1173
|
+
|
|
1133
1174
|
|
|
1134
1175
|
def resolution_function(energy_scale, spectrum, width, verbose=False):
|
|
1135
1176
|
"""get resolution function (zero-loss peak shape) from low-loss spectrum"""
|
|
@@ -1193,26 +1234,69 @@ def resolution_function(energy_scale, spectrum, width, verbose=False):
|
|
|
1193
1234
|
return z_loss, p_zl
|
|
1194
1235
|
|
|
1195
1236
|
|
|
1196
|
-
def get_energy_shifts(spectrum_image, energy_scale, zero_loss_fit_width):
|
|
1197
|
-
"""get shift of spectrum
|
|
1237
|
+
def get_energy_shifts(spectrum_image, energy_scale=None, zero_loss_fit_width=0.3):
|
|
1238
|
+
""" get shift of spectrum from zero-loss peak position
|
|
1239
|
+
better to use get resolution_functions
|
|
1240
|
+
"""
|
|
1241
|
+
resolution_functions = get_resolution_functions(spectrum_image, energy_scale=energy_scale, zero_loss_fit_width=zero_loss_fit_width)
|
|
1242
|
+
return resolution_functions.metadata['low_loss']['shifts'], resolution_functions.metadata['low_loss']['widths']
|
|
1243
|
+
|
|
1244
|
+
def get_resolution_functions(spectrum_image, energy_scale=None, zero_loss_fit_width=0.3):
|
|
1245
|
+
"""get resolution_function and shift of spectra form zero-loss peak position"""
|
|
1246
|
+
if isinstance(spectrum_image, sidpy.Dataset):
|
|
1247
|
+
energy_dimension = spectrum_image.get_dimensions_by_type('spectral')
|
|
1248
|
+
if len(energy_dimension) != 1:
|
|
1249
|
+
raise TypeError('Dataset needs to have exactly one spectral dimension to analyze zero-loss peak')
|
|
1250
|
+
energy_dimension = spectrum_image.get_dimension_by_number(energy_dimension)[0]
|
|
1251
|
+
energy_scale = energy_dimension.values
|
|
1252
|
+
spatial_dimension = spectrum_image.get_dimensions_by_type('spatial')
|
|
1253
|
+
if len(spatial_dimension) == 0:
|
|
1254
|
+
fwhm, delta_e = fix_energy_scale(spectrum_image)
|
|
1255
|
+
z_loss, p_zl = resolution_function(energy_scale - delta_e, spectrum_image, zero_loss_fit_width)
|
|
1256
|
+
fwhm2, delta_e2 = fix_energy_scale(z_loss, energy_scale - delta_e)
|
|
1257
|
+
return delta_e + delta_e2, fwhm2
|
|
1258
|
+
elif len(spatial_dimension) != 2:
|
|
1259
|
+
return
|
|
1198
1260
|
shifts = np.zeros(spectrum_image.shape[0:2])
|
|
1261
|
+
widths = np.zeros(spectrum_image.shape[0:2])
|
|
1262
|
+
resolution_functions = spectrum_image.copy()
|
|
1199
1263
|
for x in range(spectrum_image.shape[0]):
|
|
1200
1264
|
for y in range(spectrum_image.shape[1]):
|
|
1201
|
-
spectrum = spectrum_image[x, y
|
|
1265
|
+
spectrum = np.array(spectrum_image[x, y])
|
|
1202
1266
|
fwhm, delta_e = fix_energy_scale(spectrum, energy_scale)
|
|
1203
1267
|
z_loss, p_zl = resolution_function(energy_scale - delta_e, spectrum, zero_loss_fit_width)
|
|
1268
|
+
resolution_functions[x, y] = z_loss
|
|
1204
1269
|
fwhm2, delta_e2 = fix_energy_scale(z_loss, energy_scale - delta_e)
|
|
1205
1270
|
shifts[x, y] = delta_e + delta_e2
|
|
1206
|
-
|
|
1271
|
+
widths[x,y] = fwhm2
|
|
1207
1272
|
|
|
1273
|
+
resolution_functions.metadata['low_loss'] = {'shifts': shifts,
|
|
1274
|
+
'widths': widths}
|
|
1275
|
+
return resolution_functions
|
|
1208
1276
|
|
|
1209
|
-
def shift_on_same_scale(spectrum_image, shift, energy_scale, master_energy_scale):
|
|
1210
|
-
"""shift spectrum in energy"""
|
|
1211
1277
|
|
|
1212
|
-
|
|
1278
|
+
def shift_on_same_scale(spectrum_image, shifts=None, energy_scale=None, master_energy_scale=None):
|
|
1279
|
+
"""shift spectrum in energy"""
|
|
1280
|
+
if isinstance(spectrum_image, sidpy.Dataset):
|
|
1281
|
+
if shifts is None:
|
|
1282
|
+
if 'low_loss' in spectrum_image.metadata:
|
|
1283
|
+
if 'shifts' in spectrum_image.metadata['low_loss']:
|
|
1284
|
+
shifts = spectrum_image.metadata['low_loss']['shifts']
|
|
1285
|
+
else:
|
|
1286
|
+
resolution_functions = get_resolution_functions(spectrum_image)
|
|
1287
|
+
shifts = resolution_functions.metadata['low_loss']['shifts']
|
|
1288
|
+
energy_dimension = spectrum_image.get_dimensions_by_type('spectral')
|
|
1289
|
+
if len(energy_dimension) != 1:
|
|
1290
|
+
raise TypeError('Dataset needs to have exactly one spectral dimension to analyze zero-loss peak')
|
|
1291
|
+
energy_dimension = spectrum_image.get_dimension_by_number(energy_dimension)[0]
|
|
1292
|
+
energy_scale = energy_dimension.values
|
|
1293
|
+
master_energy_scale = energy_scale.copy()
|
|
1294
|
+
|
|
1295
|
+
new_si = spectrum_image.copy()
|
|
1296
|
+
new_si *= 0.0
|
|
1213
1297
|
for x in range(spectrum_image.shape[0]):
|
|
1214
1298
|
for y in range(spectrum_image.shape[1]):
|
|
1215
|
-
tck = interpolate.splrep(energy_scale -
|
|
1299
|
+
tck = interpolate.splrep(np.array(energy_scale - shifts[x, y]), np.array(spectrum_image[x, y]), k=1, s=0)
|
|
1216
1300
|
new_si[x, y, :] = interpolate.splev(master_energy_scale, tck, der=0)
|
|
1217
1301
|
return new_si
|
|
1218
1302
|
|
|
@@ -1352,6 +1436,8 @@ def xsec_xrpa(energy_scale, e0, z, beta, shift=0):
|
|
|
1352
1436
|
enexs = x_sections['ene']
|
|
1353
1437
|
datxs = x_sections['dat']
|
|
1354
1438
|
|
|
1439
|
+
# enexs = enexs[:len(datxs)]
|
|
1440
|
+
|
|
1355
1441
|
#####
|
|
1356
1442
|
# Cross Section according to Egerton Ultramicroscopy 50 (1993) 13-28 equation (4)
|
|
1357
1443
|
#####
|
|
@@ -1432,29 +1518,27 @@ def drude_simulation(dset, e, ep, ew, tnm, eb):
|
|
|
1432
1518
|
the output is shown in Fig. b.1a,b.
|
|
1433
1519
|
|
|
1434
1520
|
"""
|
|
1521
|
+
|
|
1435
1522
|
epc = dset.energy_scale[1] - dset.energy_scale[0] # input('ev per channel : ');
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
b = dset.metadata['collection_angle'] # rad
|
|
1523
|
+
|
|
1524
|
+
b = dset.metadata['collection_angle']/ 1000. # rad
|
|
1440
1525
|
epc = dset.energy_scale[1] - dset.energy_scale[0] # input('ev per channel : ');
|
|
1441
1526
|
e0 = dset.metadata['acceleration_voltage'] / 1000. # input('incident energy e0(kev) : ');
|
|
1442
1527
|
|
|
1528
|
+
# effective kinetic energy: T = m_o v^2/2,
|
|
1443
1529
|
t = 1000.0 * e0 * (1. + e0 / 1022.12) / (1.0 + e0 / 511.06) ** 2 # eV # equ.5.2a or Appendix E p 427
|
|
1530
|
+
|
|
1531
|
+
# 2 gamma T
|
|
1444
1532
|
tgt = 1000 * e0 * (1022.12 + e0) / (511.06 + e0) # eV Appendix E p 427
|
|
1533
|
+
|
|
1445
1534
|
rk0 = 2590 * (1.0 + e0 / 511.06) * np.sqrt(2.0 * t / 511060)
|
|
1535
|
+
|
|
1446
1536
|
os = e[0]
|
|
1447
1537
|
ew_mod = eb
|
|
1448
1538
|
tags = dset.metadata
|
|
1449
|
-
|
|
1450
|
-
# eps = 1 - ep**2/(e**2+2*e*ew*1j) # eq 3.64
|
|
1451
|
-
# eps = 1 - (ep**2)/(e**2+e*ew*1j-ep**2) # Lorentz Term
|
|
1539
|
+
|
|
1452
1540
|
eps = 1 - (ep ** 2 - ew_mod * e * 1j) / (e ** 2 + 2 * e * ew * 1j) # Mod drude term
|
|
1453
|
-
|
|
1454
|
-
# eps2 = np.imag(eps);
|
|
1455
|
-
# eps1 = 1. - ep.^2./(e.^2+ew.^2); #eq 3.40
|
|
1456
|
-
# eps2 = ew.*ep.^2./e./(e.^2+ew.^2);#eq 3.40
|
|
1457
|
-
# elf = ep**2*e*ew/((e**2-ep**2)**2+(e*ew)**2); # eq 3.40?
|
|
1541
|
+
|
|
1458
1542
|
eps[np.nonzero(eps == 0.0)] = 1e-19
|
|
1459
1543
|
elf = np.imag(-1 / eps)
|
|
1460
1544
|
|
|
@@ -1464,16 +1548,16 @@ def drude_simulation(dset, e, ep, ew, tnm, eb):
|
|
|
1464
1548
|
angdep = np.arctan(b / the) / the - b / (b * b + the * the)
|
|
1465
1549
|
srfint = angdep * srfelf / (3.1416 * 0.05292 * rk0 * t) # probability per eV
|
|
1466
1550
|
anglog = np.log(1.0 + b * b / the / the)
|
|
1467
|
-
i0 =
|
|
1468
|
-
|
|
1551
|
+
i0 = dset.sum() # *tags['counts2e']
|
|
1552
|
+
|
|
1469
1553
|
|
|
1470
1554
|
# 2 * t = m_0 v**2 !!! a_0 = 0.05292 nm
|
|
1471
1555
|
volint = abs(tnm / (np.pi * 0.05292 * t * 2.0) * elf * anglog) # S equ 4.26% probability per eV
|
|
1472
1556
|
volint = volint * i0 / epc # S probability per channel
|
|
1473
1557
|
ssd = volint # + srfint;
|
|
1474
1558
|
|
|
1475
|
-
if
|
|
1476
|
-
xs = int(abs(-
|
|
1559
|
+
if e[0] < -1.0:
|
|
1560
|
+
xs = int(abs(-e[0] / epc))
|
|
1477
1561
|
|
|
1478
1562
|
ssd[0:xs] = 0.0
|
|
1479
1563
|
volint[0:xs] = 0.0
|
|
@@ -1486,10 +1570,6 @@ def drude_simulation(dset, e, ep, ew, tnm, eb):
|
|
|
1486
1570
|
lam = tnm / p_v # does NOT depend on free-electron approximation (no damping).
|
|
1487
1571
|
lamfe = 4.0 * 0.05292 * t / ep / np.log(1 + (b * tgt / ep) ** 2) # Eq.(3.44) approximation
|
|
1488
1572
|
|
|
1489
|
-
# print('p_s(2surfaces+begrenzung terms) =', p_s, 'p_v=t/lambda(beta)= ',p_v,'\n');
|
|
1490
|
-
# print('Volume-plasmon MFP(nm) = ', lam,' Free-electron MFP(nm) = ',lamfe,'\n');
|
|
1491
|
-
# print('--------------------------------\n');
|
|
1492
|
-
|
|
1493
1573
|
tags['eps'] = eps
|
|
1494
1574
|
tags['lam'] = lam
|
|
1495
1575
|
tags['lamfe'] = lamfe
|
pyTEMlib/file_tools.py
CHANGED
|
@@ -95,6 +95,8 @@ class FileWidget(object):
|
|
|
95
95
|
self.dir_list = ['.']
|
|
96
96
|
self.extensions = extension
|
|
97
97
|
self.file_name = ''
|
|
98
|
+
self.datasets ={}
|
|
99
|
+
self.dataset = None
|
|
98
100
|
|
|
99
101
|
self.select_files = widgets.Select(
|
|
100
102
|
options=self.dir_list,
|
|
@@ -104,9 +106,56 @@ class FileWidget(object):
|
|
|
104
106
|
rows=10,
|
|
105
107
|
layout=widgets.Layout(width='70%')
|
|
106
108
|
)
|
|
107
|
-
|
|
109
|
+
|
|
110
|
+
select_button = widgets.Button(description='Select Main',
|
|
111
|
+
layout=widgets.Layout(width='auto', grid_area='header'),
|
|
112
|
+
style=widgets.ButtonStyle(button_color='lightblue'))
|
|
113
|
+
|
|
114
|
+
add_button = widgets.Button(description='Add',
|
|
115
|
+
layout=widgets.Layout(width='auto', grid_area='header'),
|
|
116
|
+
style=widgets.ButtonStyle(button_color='lightblue'))
|
|
117
|
+
|
|
118
|
+
self.path_choice = widgets.Dropdown(options=['None'],
|
|
119
|
+
value='None',
|
|
120
|
+
description='directory:',
|
|
121
|
+
disabled=False,
|
|
122
|
+
button_style='',
|
|
123
|
+
layout=widgets.Layout(width='90%'))
|
|
124
|
+
self.dataset_list = ['None']
|
|
125
|
+
self.loaded_datasets = widgets.Dropdown(options=self.dataset_list,
|
|
126
|
+
value=self.dataset_list[0],
|
|
127
|
+
description='loaded datasets:',
|
|
128
|
+
disabled=False,
|
|
129
|
+
button_style='')
|
|
130
|
+
|
|
108
131
|
self.set_options()
|
|
132
|
+
ui = widgets.VBox([self.path_choice, self.select_files, widgets.HBox([select_button, add_button, self.loaded_datasets])])
|
|
133
|
+
display(ui)
|
|
134
|
+
|
|
109
135
|
self.select_files.observe(self.get_file_name, names='value')
|
|
136
|
+
self.path_choice.observe(self.set_dir, names='value')
|
|
137
|
+
|
|
138
|
+
select_button.on_click(self.select_main)
|
|
139
|
+
add_button.on_click(self.add_dataset)
|
|
140
|
+
self.loaded_datasets.observe(self.selected_dataset)
|
|
141
|
+
|
|
142
|
+
def select_main(self, value=0):
|
|
143
|
+
self.datasets = {}
|
|
144
|
+
self.loaded_datasets.value = self.dataset_list[0]
|
|
145
|
+
self.datasets = open_file(self.file_name)
|
|
146
|
+
self.dataset_list = []
|
|
147
|
+
for key in self.datasets.keys():
|
|
148
|
+
self.dataset_list.append(f'{key}: {self.datasets[key].title}')
|
|
149
|
+
self.loaded_datasets.options = self.dataset_list
|
|
150
|
+
self.loaded_datasets.value = self.dataset_list[0]
|
|
151
|
+
self.dataset = self.datasets[list(self.datasets.keys())[0]]
|
|
152
|
+
self.selected_dataset = self.dataset
|
|
153
|
+
|
|
154
|
+
def add_dataset(self, value=0):
|
|
155
|
+
key = add_dataset_from_file(self.datasets, self.file_name, 'Channel')
|
|
156
|
+
self.dataset_list.append(f'{key}: {self.datasets[key].title}')
|
|
157
|
+
self.loaded_datasets.options = self.dataset_list
|
|
158
|
+
self.loaded_datasets.value = self.dataset_list[-1]
|
|
110
159
|
|
|
111
160
|
def get_directory(self, directory=None):
|
|
112
161
|
self.dir_name = directory
|
|
@@ -114,6 +163,17 @@ class FileWidget(object):
|
|
|
114
163
|
self.dir_list = []
|
|
115
164
|
self.dir_list = ['.', '..'] + os.listdir(directory)
|
|
116
165
|
|
|
166
|
+
def set_dir(self, value=0):
|
|
167
|
+
self.dir_name = self.path_choice.value
|
|
168
|
+
self.select_files.index = 0
|
|
169
|
+
self.set_options()
|
|
170
|
+
|
|
171
|
+
def selected_dataset(self, value=0):
|
|
172
|
+
|
|
173
|
+
key = self.loaded_datasets.value.split(':')[0]
|
|
174
|
+
if key != 'None':
|
|
175
|
+
self.selected_dataset = self.datasets[key]
|
|
176
|
+
|
|
117
177
|
def set_options(self):
|
|
118
178
|
self.dir_name = os.path.abspath(os.path.join(self.dir_name, self.dir_list[self.select_files.index]))
|
|
119
179
|
dir_list = os.listdir(self.dir_name)
|
|
@@ -137,6 +197,16 @@ class FileWidget(object):
|
|
|
137
197
|
|
|
138
198
|
self.dir_label = os.path.split(self.dir_name)[-1] + ':'
|
|
139
199
|
self.select_files.options = self.display_list
|
|
200
|
+
|
|
201
|
+
path = self.dir_name
|
|
202
|
+
old_path = ' '
|
|
203
|
+
path_list = []
|
|
204
|
+
while path != old_path:
|
|
205
|
+
path_list.append(path)
|
|
206
|
+
old_path = path
|
|
207
|
+
path = os.path.split(path)[0]
|
|
208
|
+
self.path_choice.options = path_list
|
|
209
|
+
self.path_choice.value = path_list[0]
|
|
140
210
|
|
|
141
211
|
def get_file_name(self, b):
|
|
142
212
|
|
|
@@ -589,7 +659,7 @@ def open_file(filename=None, h5_group=None, write_hdf_file=False): # save_file
|
|
|
589
659
|
|
|
590
660
|
# tags = open_file(filename)
|
|
591
661
|
if extension in ['.dm3', '.dm4']:
|
|
592
|
-
reader = SciFiReaders.
|
|
662
|
+
reader = SciFiReaders.DMReader(filename)
|
|
593
663
|
|
|
594
664
|
elif extension in ['.emi']:
|
|
595
665
|
try:
|
|
@@ -875,7 +945,7 @@ def log_results(h5_group, dataset=None, attributes=None):
|
|
|
875
945
|
return log_group
|
|
876
946
|
|
|
877
947
|
|
|
878
|
-
def add_dataset_from_file(datasets, filename=None,
|
|
948
|
+
def add_dataset_from_file(datasets, filename=None, key_name='Log', single_dataset=True):
|
|
879
949
|
"""Add dataset to datasets dictionary
|
|
880
950
|
|
|
881
951
|
Parameters
|
|
@@ -884,23 +954,35 @@ def add_dataset_from_file(datasets, filename=None, keyname='Log'):
|
|
|
884
954
|
dictionary to write to file
|
|
885
955
|
filename: str, default: None,
|
|
886
956
|
name of file to open, if None, adialog will appear
|
|
887
|
-
|
|
957
|
+
key_name: str, default: 'Log'
|
|
888
958
|
name for key in dictionary with running number being added
|
|
889
959
|
|
|
890
|
-
|
|
891
960
|
Returns
|
|
892
961
|
-------
|
|
893
|
-
|
|
962
|
+
key_name: str
|
|
963
|
+
actual last used name of dictionary key
|
|
894
964
|
"""
|
|
895
965
|
|
|
896
966
|
datasets2 = open_file(filename=filename)
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
967
|
+
first_dataset = datasets2[list(datasets2)[0]]
|
|
968
|
+
if isinstance(first_dataset, sidpy.Dataset):
|
|
969
|
+
|
|
970
|
+
index = 0
|
|
971
|
+
for key in datasets.keys():
|
|
972
|
+
if key_name in key:
|
|
973
|
+
if int(key[-3:]) >= index:
|
|
974
|
+
index = int(key[-3:])+1
|
|
975
|
+
if single_dataset:
|
|
976
|
+
datasets[key_name+f'_{index:03}'] = first_dataset
|
|
977
|
+
else:
|
|
978
|
+
for dataset in datasets2.values():
|
|
979
|
+
datasets[key_name+f'_{index:03}'] = dataset
|
|
980
|
+
index += 1
|
|
981
|
+
index -= 1
|
|
982
|
+
else:
|
|
983
|
+
return None
|
|
984
|
+
|
|
985
|
+
return f'{key_name}_{index:03}'
|
|
904
986
|
|
|
905
987
|
|
|
906
988
|
# ##
|