pyTEMlib 0.2024.6.0__py2.py3-none-any.whl → 0.2024.8.4__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/eds_tools.py +218 -167
- pyTEMlib/image_tools.py +8 -4
- pyTEMlib/version.py +2 -2
- pyTEMlib/xrpa_x_sections.py +140 -54
- {pyTEMlib-0.2024.6.0.dist-info → pyTEMlib-0.2024.8.4.dist-info}/METADATA +5 -6
- {pyTEMlib-0.2024.6.0.dist-info → pyTEMlib-0.2024.8.4.dist-info}/RECORD +10 -10
- {pyTEMlib-0.2024.6.0.dist-info → pyTEMlib-0.2024.8.4.dist-info}/WHEEL +1 -1
- {pyTEMlib-0.2024.6.0.dist-info → pyTEMlib-0.2024.8.4.dist-info}/entry_points.txt +0 -1
- {pyTEMlib-0.2024.6.0.dist-info → pyTEMlib-0.2024.8.4.dist-info}/LICENSE +0 -0
- {pyTEMlib-0.2024.6.0.dist-info → pyTEMlib-0.2024.8.4.dist-info}/top_level.txt +0 -0
pyTEMlib/eds_tools.py
CHANGED
|
@@ -56,7 +56,6 @@ shell_occupancy = {'K1': 2, 'L1': 2, 'L2': 2, 'L3': 4, 'M1': 2, 'M2': 2, 'M3': 4
|
|
|
56
56
|
def detector_response(dataset):
|
|
57
57
|
tags = dataset.metadata['experiment']
|
|
58
58
|
|
|
59
|
-
tags['acceleration_voltage_V'] = tags['microscope']['acceleration_voltage_V']
|
|
60
59
|
energy_scale = dataset.get_spectral_dims(return_axis=True)[0]
|
|
61
60
|
if 'start_channel' not in tags['detector']:
|
|
62
61
|
tags['detector']['start_channel'] = np.searchsorted(energy_scale, 100)
|
|
@@ -88,7 +87,7 @@ def get_detector_response(detector_definition, energy_scale):
|
|
|
88
87
|
-------
|
|
89
88
|
|
|
90
89
|
tags ={}
|
|
91
|
-
tags['
|
|
90
|
+
tags['acceleration_voltage'] = 200000
|
|
92
91
|
|
|
93
92
|
tags['detector'] ={}
|
|
94
93
|
|
|
@@ -182,19 +181,13 @@ def find_elements(spectrum, minor_peaks):
|
|
|
182
181
|
found = False
|
|
183
182
|
for element in range(3,82):
|
|
184
183
|
if 'lines' in x_sections[str(element)]:
|
|
185
|
-
if 'K-
|
|
186
|
-
if abs(x_sections[str(element)]['lines']['K-
|
|
184
|
+
if 'K-L2' in x_sections[str(element)]['lines']:
|
|
185
|
+
if abs(x_sections[str(element)]['lines']['K-L2']['position']- energy_scale[peak]) <10:
|
|
187
186
|
found = True
|
|
188
187
|
if x_sections[str(element)]['name'] not in elements:
|
|
189
188
|
elements.append( x_sections[str(element)]['name'])
|
|
190
189
|
if not found:
|
|
191
|
-
if '
|
|
192
|
-
if abs(x_sections[str(element)]['lines']['K-L2']['position']- energy_scale[peak]) <10:
|
|
193
|
-
found = True
|
|
194
|
-
if x_sections[str(element)]['name'] not in elements:
|
|
195
|
-
elements.append( x_sections[str(element)]['name'])
|
|
196
|
-
if not found:
|
|
197
|
-
if 'L3-M5' in x_sections[str(element)]['lines']:
|
|
190
|
+
if 'L3-M3' in x_sections[str(element)]['lines']:
|
|
198
191
|
if abs(x_sections[str(element)]['lines']['L3-M5']['position']- energy_scale[peak]) <30:
|
|
199
192
|
if x_sections[str(element)]['name'] not in elements:
|
|
200
193
|
elements.append( x_sections[str(element)]['name'])
|
|
@@ -212,87 +205,71 @@ def get_x_ray_lines(spectrum, elements):
|
|
|
212
205
|
# omega_K = Z**4/(alpha_K+Z**4)
|
|
213
206
|
# omega_L = Z**4/(alpha_L+Z**4)
|
|
214
207
|
# omega_M = Z**4/(alpha_M+Z**4)
|
|
215
|
-
energy_scale = spectrum.get_spectral_dims(return_axis=True)[0]
|
|
208
|
+
energy_scale = np.array(spectrum.get_spectral_dims(return_axis=True)[0].values)
|
|
216
209
|
for element in elements:
|
|
217
|
-
atomic_number = elements_list.index(element)
|
|
210
|
+
atomic_number = pyTEMlib.eds_tools.elements_list.index(element)
|
|
218
211
|
out_tags[element] ={'Z': atomic_number}
|
|
212
|
+
lines = x_sections[str(atomic_number)]['lines']
|
|
213
|
+
K_weight = 0
|
|
214
|
+
K_main = 'None'
|
|
215
|
+
K_lines = []
|
|
216
|
+
L_weight = 0
|
|
217
|
+
L_main = 'None'
|
|
218
|
+
L_lines = []
|
|
219
|
+
M_weight = 0
|
|
220
|
+
M_main = 'None'
|
|
221
|
+
M_lines = []
|
|
222
|
+
|
|
223
|
+
for key, line in lines.items():
|
|
224
|
+
if 'K' == key[0]:
|
|
225
|
+
if line['position'] < energy_scale[-1]:
|
|
226
|
+
K_lines.append(key)
|
|
227
|
+
if line['weight'] > K_weight:
|
|
228
|
+
K_weight = line['weight']
|
|
229
|
+
K_main = key
|
|
230
|
+
if 'L' == key[0]:
|
|
231
|
+
if line['position'] < energy_scale[-1]:
|
|
232
|
+
L_lines.append(key)
|
|
233
|
+
if line['weight'] > L_weight:
|
|
234
|
+
L_weight = line['weight']
|
|
235
|
+
L_main = key
|
|
236
|
+
if 'M' == key[0]:
|
|
237
|
+
if line['position'] < energy_scale[-1]:
|
|
238
|
+
M_lines.append(key)
|
|
239
|
+
if line['weight'] > M_weight:
|
|
240
|
+
M_weight = line['weight']
|
|
241
|
+
M_main = key
|
|
242
|
+
|
|
243
|
+
if K_weight > 0:
|
|
244
|
+
out_tags[element]['K-family'] = {'main': K_main, 'weight': K_weight, 'lines': K_lines}
|
|
245
|
+
height = spectrum[np.searchsorted(energy_scale, x_sections[str(atomic_number)]['lines'][K_main]['position'] )].compute()
|
|
246
|
+
out_tags[element]['K-family']['height'] = height/K_weight
|
|
247
|
+
for key in K_lines:
|
|
248
|
+
out_tags[element]['K-family'][key] = x_sections[str(atomic_number)]['lines'][key]
|
|
249
|
+
if L_weight > 0:
|
|
250
|
+
out_tags[element]['L-family'] = {'main': L_main, 'weight': L_weight, 'lines': L_lines}
|
|
251
|
+
height = spectrum[np.searchsorted(energy_scale, x_sections[str(atomic_number)]['lines'][L_main]['position'] )].compute()
|
|
252
|
+
out_tags[element]['L-family']['height'] = height/L_weight
|
|
253
|
+
for key in L_lines:
|
|
254
|
+
out_tags[element]['L-family'][key] = x_sections[str(atomic_number)]['lines'][key]
|
|
255
|
+
if M_weight > 0:
|
|
256
|
+
out_tags[element]['M-family'] = {'main': M_main, 'weight': M_weight, 'lines': M_lines}
|
|
257
|
+
height = spectrum[np.searchsorted(energy_scale, x_sections[str(atomic_number)]['lines'][M_main]['position'] )].compute()
|
|
258
|
+
out_tags[element]['M-family']['height'] = height/M_weight
|
|
259
|
+
for key in M_lines:
|
|
260
|
+
out_tags[element]['M-family'][key] = x_sections[str(atomic_number)]['lines'][key]
|
|
219
261
|
|
|
220
|
-
if 'K-L3' in x_sections[str(atomic_number)]['lines']:
|
|
221
|
-
if x_sections[str(atomic_number)]['lines']['K-L3']['position'] < energy_scale[-1]:
|
|
222
|
-
height = spectrum[np.searchsorted(energy_scale, x_sections[str(atomic_number)]['lines']['K-L3']['position'] )].compute()
|
|
223
|
-
out_tags[element]['K-family'] = {'height': height}
|
|
224
|
-
if 'K' in x_sections[str(atomic_number)]['fluorescent_yield']:
|
|
225
|
-
out_tags[element]['K-family']['yield'] = x_sections[str(atomic_number)]['fluorescent_yield']['K']
|
|
226
|
-
else:
|
|
227
|
-
out_tags[element]['K-family']['yield'] = atomic_number**4/(alpha_K+atomic_number**4)/4/1.4
|
|
228
|
-
|
|
229
|
-
if 'L3-M5' in x_sections[str(atomic_number)]['lines']:
|
|
230
|
-
if x_sections[str(atomic_number)]['lines']['L3-M5']['position'] < energy_scale[-1]:
|
|
231
|
-
height = spectrum[np.searchsorted(energy_scale, x_sections[str(atomic_number)]['lines']['L3-M5']['position'] )].compute()
|
|
232
|
-
out_tags[element]['L-family'] = {'height': height}
|
|
233
|
-
if 'L' in x_sections[str(atomic_number)]['fluorescent_yield']:
|
|
234
|
-
out_tags[element]['L-family']['yield'] = x_sections[str(atomic_number)]['fluorescent_yield']['L']
|
|
235
|
-
else:
|
|
236
|
-
out_tags[element]['L-family']['yield'] = (atomic_number**4/(alpha_L+atomic_number**4))**2
|
|
237
|
-
|
|
238
|
-
if 'M5-N6' in x_sections[str(atomic_number)]['lines']:
|
|
239
|
-
if x_sections[str(atomic_number)]['lines']['M5-N6']['position'] < energy_scale[-1]:
|
|
240
|
-
height = spectrum[np.searchsorted(energy_scale, x_sections[str(atomic_number)]['lines']['M5-N6']['position'] )].compute()
|
|
241
|
-
out_tags[element]['M-family'] = {'height': height}
|
|
242
|
-
if 'M' in x_sections[str(atomic_number)]['fluorescent_yield']:
|
|
243
|
-
out_tags[element]['M-family']['yield'] = x_sections[str(atomic_number)]['fluorescent_yield']['M']
|
|
244
|
-
else:
|
|
245
|
-
out_tags[element]['M-family']['yield'] = (atomic_number**4/(alpha_M+atomic_number**4))**2
|
|
246
|
-
|
|
247
|
-
for key, line in x_sections[str(atomic_number)]['lines'].items():
|
|
248
|
-
other = True
|
|
249
|
-
if line['weight'] > 0.01 and line['position'] < 3e4:
|
|
250
|
-
if 'K-family' in out_tags[element]:
|
|
251
|
-
if key[0] == 'K':
|
|
252
|
-
other = False
|
|
253
|
-
out_tags[element]['K-family'][key]=line
|
|
254
|
-
if 'L-family' in out_tags[element]:
|
|
255
|
-
if key[:2] in ['L2', 'L3']:
|
|
256
|
-
other = False
|
|
257
|
-
out_tags[element]['L-family'][key]=line
|
|
258
|
-
if 'M-family' in out_tags[element]:
|
|
259
|
-
if key[:2] in ['M5', 'M4']:
|
|
260
|
-
other = False
|
|
261
|
-
out_tags[element]['M-family'][key]=line
|
|
262
|
-
if other:
|
|
263
|
-
if 'other' not in out_tags[element]:
|
|
264
|
-
out_tags[element]['other'] = {}
|
|
265
|
-
height = spectrum[np.searchsorted(energy_scale, x_sections[str(atomic_number)]['lines'][key]['position'] )].compute()
|
|
266
|
-
out_tags[element]['other'][key]=line
|
|
267
|
-
out_tags[element]['other'][key]['height'] = height
|
|
268
|
-
|
|
269
262
|
xs = get_eds_cross_sections(atomic_number)
|
|
270
263
|
if 'K' in xs and 'K-family' in out_tags[element]:
|
|
271
|
-
out_tags[element]['K-family']['
|
|
264
|
+
out_tags[element]['K-family']['probability'] = xs['K']
|
|
272
265
|
if 'L' in xs and 'L-family' in out_tags[element]:
|
|
273
|
-
out_tags[element]['L-family']['
|
|
266
|
+
out_tags[element]['L-family']['probability'] = xs['L']
|
|
274
267
|
if 'M' in xs and 'M-family' in out_tags[element]:
|
|
275
|
-
out_tags[element]['M-family']['
|
|
268
|
+
out_tags[element]['M-family']['probability'] = xs['M']
|
|
276
269
|
|
|
277
|
-
"""
|
|
278
|
-
We really should use the sum of the family
|
|
279
|
-
for key, x_lines in out_tags.items():
|
|
280
|
-
if 'K-family' in x_lines:
|
|
281
|
-
xs = pyTEMlib.eels_tools.xsec_xrpa(np.arange(100)+x_sections[str(x_lines['Z'])]['K1']['onset'], 200,x_lines['Z'], 100).sum()
|
|
282
|
-
|
|
283
|
-
x_lines['K-family']['ionization_x_section'] = xs
|
|
284
|
-
|
|
285
|
-
if 'L-family' in x_lines:
|
|
286
|
-
xs = pyTEMlib.eels_tools.xsec_xrpa(np.arange(100)+x_sections[str(x_lines['Z'])]['L3']['onset'], 200,x_lines['Z'], 100).sum()
|
|
287
|
-
x_lines['L-family']['ionization_x_section'] = xs
|
|
288
|
-
if 'M-family' in x_lines:
|
|
289
|
-
xs = pyTEMlib.eels_tools.xsec_xrpa(np.arange(100)+x_sections[str(x_lines['Z'])]['M5']['onset'], 200,x_lines['Z'], 100).sum()
|
|
290
|
-
x_lines['M-family']['ionization_x_section'] = xs
|
|
291
|
-
"""
|
|
292
270
|
if 'EDS' not in spectrum.metadata:
|
|
293
271
|
spectrum.metadata['EDS'] = {}
|
|
294
|
-
|
|
295
|
-
spectrum.metadata['EDS']['lines'] = out_tags
|
|
272
|
+
spectrum.metadata['EDS'].update(out_tags)
|
|
296
273
|
return out_tags
|
|
297
274
|
|
|
298
275
|
|
|
@@ -313,7 +290,7 @@ def get_peak(E, energy_scale):
|
|
|
313
290
|
|
|
314
291
|
|
|
315
292
|
def initial_model_parameter(spectrum):
|
|
316
|
-
tags = spectrum.metadata['EDS']
|
|
293
|
+
tags = spectrum.metadata['EDS']
|
|
317
294
|
energy_scale = spectrum.get_spectral_dims(return_axis=True)[0]
|
|
318
295
|
p = []
|
|
319
296
|
peaks = []
|
|
@@ -324,9 +301,9 @@ def initial_model_parameter(spectrum):
|
|
|
324
301
|
for line, info in lines['K-family'].items():
|
|
325
302
|
if line[0] == 'K':
|
|
326
303
|
model += get_peak(info['position'], energy_scale)*info['weight']
|
|
327
|
-
lines['K-family']['peaks'] = model/model.sum()
|
|
328
|
-
|
|
329
|
-
p.append(lines['K-family']['height'])
|
|
304
|
+
lines['K-family']['peaks'] = model /model.sum() # *lines['K-family']['probability']
|
|
305
|
+
|
|
306
|
+
p.append(lines['K-family']['height'] / lines['K-family']['peaks'].max())
|
|
330
307
|
peaks.append(lines['K-family']['peaks'])
|
|
331
308
|
keys.append(element+':K-family')
|
|
332
309
|
if 'L-family' in lines:
|
|
@@ -334,9 +311,8 @@ def initial_model_parameter(spectrum):
|
|
|
334
311
|
for line, info in lines['L-family'].items():
|
|
335
312
|
if line[0] == 'L':
|
|
336
313
|
model += get_peak(info['position'], energy_scale)*info['weight']
|
|
337
|
-
lines['L-family']['peaks'] = model/model.sum()
|
|
338
|
-
lines['L-family']['height']
|
|
339
|
-
p.append(lines['L-family']['height'])
|
|
314
|
+
lines['L-family']['peaks'] = model /model.sum() # *lines['L-family']['probability']
|
|
315
|
+
p.append(lines['L-family']['height'] / lines['L-family']['peaks'].max())
|
|
340
316
|
peaks.append(lines['L-family']['peaks'])
|
|
341
317
|
keys.append(element+':L-family')
|
|
342
318
|
if 'M-family' in lines:
|
|
@@ -344,18 +320,11 @@ def initial_model_parameter(spectrum):
|
|
|
344
320
|
for line, info in lines['M-family'].items():
|
|
345
321
|
if line[0] == 'M':
|
|
346
322
|
model += get_peak(info['position'], energy_scale)*info['weight']
|
|
347
|
-
lines['M-family']['peaks'] = model/model.sum()
|
|
348
|
-
lines['M-family']['height']
|
|
349
|
-
p.append(lines['M-family']['height'])
|
|
323
|
+
lines['M-family']['peaks'] = model /model.sum()*lines['M-family']['probability']
|
|
324
|
+
p.append(lines['M-family']['height'] / lines['M-family']['peaks'].max())
|
|
350
325
|
peaks.append(lines['M-family']['peaks'])
|
|
351
326
|
keys.append(element+':M-family')
|
|
352
|
-
|
|
353
|
-
if 'other' in lines:
|
|
354
|
-
for line, info in lines['other'].items():
|
|
355
|
-
info['peak'] = get_peak(info['position'], energy_scale)
|
|
356
|
-
peaks.append(info['peak'])
|
|
357
|
-
p.append(info['height'])
|
|
358
|
-
keys.append(element+':other:'+line)
|
|
327
|
+
|
|
359
328
|
|
|
360
329
|
#p.extend([300, 10, 1.e-04])
|
|
361
330
|
# p.extend([1, 300, -.02])
|
|
@@ -363,22 +332,23 @@ def initial_model_parameter(spectrum):
|
|
|
363
332
|
return np.array(peaks), np.array(p), keys
|
|
364
333
|
|
|
365
334
|
def get_model(spectrum, start=100):
|
|
366
|
-
|
|
367
|
-
peaks, pp, keys = initial_model_parameter(spectrum)
|
|
368
335
|
model = np.zeros(len(spectrum))
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
336
|
+
for key in spectrum.metadata['EDS']:
|
|
337
|
+
for family in spectrum.metadata['EDS'][key]:
|
|
338
|
+
if isinstance(spectrum.metadata['EDS'][key][family], dict):
|
|
339
|
+
intensity = spectrum.metadata['EDS'][key][family]['areal_density']
|
|
340
|
+
peaks = spectrum.metadata['EDS'][key][family]['peaks']
|
|
341
|
+
model += peaks * intensity
|
|
342
|
+
|
|
343
|
+
if 'detector_efficiency' in spectrum.metadata['EDS']['detector'].keys():
|
|
344
|
+
detector_efficiency = spectrum.metadata['EDS']['detector']['detector_efficiency']
|
|
375
345
|
else:
|
|
376
346
|
detector_efficiency = None
|
|
377
|
-
E_0 = spectrum.metadata['experiment']['
|
|
347
|
+
E_0 = spectrum.metadata['experiment']['acceleration_voltage']
|
|
378
348
|
|
|
379
|
-
if detector_efficiency is not None:
|
|
380
|
-
|
|
381
|
-
|
|
349
|
+
# if detector_efficiency is not None:
|
|
350
|
+
# model[start:] += detector_efficiency[start:] * (pp[-3] + pp[-2] * (E_0 - energy_scale) / energy_scale +
|
|
351
|
+
# pp[-1] * (E_0 - energy_scale) ** 2 / energy_scale)
|
|
382
352
|
|
|
383
353
|
return model
|
|
384
354
|
|
|
@@ -386,22 +356,22 @@ def fit_model(spectrum, elements, use_detector_efficiency=False):
|
|
|
386
356
|
out_tags = get_x_ray_lines(spectrum, elements)
|
|
387
357
|
peaks, pin, keys = initial_model_parameter(spectrum)
|
|
388
358
|
energy_scale = spectrum.get_spectral_dims(return_axis=True)[0].values
|
|
389
|
-
|
|
390
|
-
if 'detector' in spectrum.metadata['
|
|
391
|
-
if 'start_channel' not in spectrum.metadata['
|
|
392
|
-
spectrum.metadata['
|
|
393
|
-
if 'detector_efficiency' in spectrum.metadata['
|
|
359
|
+
|
|
360
|
+
if 'detector' in spectrum.metadata['EDS'].keys():
|
|
361
|
+
if 'start_channel' not in spectrum.metadata['EDS']['detector']:
|
|
362
|
+
spectrum.metadata['EDS']['detector']['start_channel'] = np.searchsorted(energy_scale, 100)
|
|
363
|
+
if 'detector_efficiency' in spectrum.metadata['EDS']['detector'].keys():
|
|
394
364
|
if use_detector_efficiency:
|
|
395
|
-
detector_efficiency = spectrum.metadata['
|
|
365
|
+
detector_efficiency = spectrum.metadata['EDS']['detector']['detector_efficiency']
|
|
396
366
|
else:
|
|
397
367
|
use_detector_efficiency = False
|
|
398
368
|
else:
|
|
399
369
|
print('need detector information to fit spectrum')
|
|
400
370
|
return
|
|
401
|
-
start = spectrum.metadata['
|
|
371
|
+
start = spectrum.metadata['EDS']['detector']['start_channel']
|
|
402
372
|
energy_scale = energy_scale[start:]
|
|
403
373
|
|
|
404
|
-
E_0= spectrum.metadata['experiment']['
|
|
374
|
+
E_0= spectrum.metadata['experiment']['acceleration_voltage']
|
|
405
375
|
|
|
406
376
|
def residuals(pp, yy):
|
|
407
377
|
#get_model(peaks, pp, detector_efficiency=None)
|
|
@@ -426,33 +396,31 @@ def fit_model(spectrum, elements, use_detector_efficiency=False):
|
|
|
426
396
|
|
|
427
397
|
# print(pin[-6:], p[-6:])
|
|
428
398
|
|
|
429
|
-
update_fit_values(out_tags, p)
|
|
399
|
+
update_fit_values(out_tags, peaks, p)
|
|
430
400
|
|
|
431
401
|
|
|
432
402
|
if 'EDS' not in spectrum.metadata:
|
|
433
403
|
spectrum.metadata['EDS'] = {}
|
|
434
|
-
spectrum.metadata['EDS']
|
|
404
|
+
spectrum.metadata['EDS'].update(out_tags)
|
|
435
405
|
|
|
436
406
|
return np.array(peaks), np.array(p)
|
|
437
407
|
|
|
438
408
|
|
|
439
|
-
def update_fit_values(out_tags, p):
|
|
409
|
+
def update_fit_values(out_tags, peaks, p):
|
|
440
410
|
index = 0
|
|
441
411
|
for element, lines in out_tags.items():
|
|
442
412
|
if 'K-family' in lines:
|
|
443
|
-
lines['K-family']['
|
|
413
|
+
lines['K-family']['areal_density'] = p[index]
|
|
414
|
+
lines['K-family']['peaks'] = peaks[index]
|
|
444
415
|
index += 1
|
|
445
416
|
if 'L-family' in lines:
|
|
446
|
-
lines['L-family']['
|
|
417
|
+
lines['L-family']['areal_density'] = p[index]
|
|
418
|
+
lines['L-family']['peaks'] = peaks[index]
|
|
447
419
|
index += 1
|
|
448
420
|
if 'M-family' in lines:
|
|
449
|
-
lines['M-family']['
|
|
421
|
+
lines['M-family']['areal_density'] =p[index]
|
|
422
|
+
lines['M-family']['peaks'] = peaks[index]
|
|
450
423
|
index += 1
|
|
451
|
-
if 'other' in lines:
|
|
452
|
-
for line, info in lines['other'].items():
|
|
453
|
-
info['height'] = p[index]
|
|
454
|
-
index += 1
|
|
455
|
-
|
|
456
424
|
|
|
457
425
|
def get_eds_xsection(Xsection, energy_scale, start_bgd, end_bgd):
|
|
458
426
|
background = pyTEMlib.eels_tools.power_law_background(Xsection, energy_scale, [start_bgd, end_bgd], verbose=False)
|
|
@@ -462,44 +430,97 @@ def get_eds_xsection(Xsection, energy_scale, start_bgd, end_bgd):
|
|
|
462
430
|
return cross_section_core
|
|
463
431
|
|
|
464
432
|
|
|
465
|
-
def get_eds_cross_sections(z):
|
|
466
|
-
energy_scale = np.arange(
|
|
467
|
-
Xsection = pyTEMlib.eels_tools.xsec_xrpa(energy_scale,
|
|
433
|
+
def get_eds_cross_sections(z, acceleration_voltage=200000):
|
|
434
|
+
energy_scale = np.arange(1,20000)
|
|
435
|
+
Xsection = pyTEMlib.eels_tools.xsec_xrpa(energy_scale, acceleration_voltage/1000., z, 400.)
|
|
468
436
|
edge_info = pyTEMlib.eels_tools.get_x_sections(z)
|
|
437
|
+
|
|
438
|
+
|
|
469
439
|
eds_cross_sections = {}
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
start_bgd
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
440
|
+
Xyield = edge_info['total_fluorescent_yield']
|
|
441
|
+
if 'K' in Xyield:
|
|
442
|
+
start_bgd = edge_info['K1']['onset'] * 0.8
|
|
443
|
+
end_bgd = edge_info['K1']['onset'] - 5
|
|
444
|
+
if start_bgd > end_bgd:
|
|
445
|
+
start_bgd = end_bgd-100
|
|
446
|
+
if start_bgd > energy_scale[0] and end_bgd< energy_scale[-1]-100:
|
|
447
|
+
eds_xsection = get_eds_xsection(Xsection, energy_scale, start_bgd, end_bgd)
|
|
448
|
+
eds_xsection[eds_xsection<0] = 0.
|
|
449
|
+
start_sum = np.searchsorted(energy_scale, edge_info['K1']['onset'])
|
|
450
|
+
end_sum = start_sum+600
|
|
451
|
+
if end_sum> len(Xsection):
|
|
452
|
+
end_sum = len(Xsection)-1
|
|
453
|
+
eds_cross_sections['K1'] = eds_xsection[start_sum:end_sum].sum()
|
|
454
|
+
eds_cross_sections['K'] = eds_xsection[start_sum:end_sum].sum() * Xyield['K']
|
|
455
|
+
|
|
456
|
+
if 'L3' in Xyield:
|
|
457
|
+
start_bgd = edge_info['L3']['onset'] * 0.8
|
|
458
|
+
end_bgd = edge_info['L3']['onset'] - 5
|
|
459
|
+
if start_bgd > end_bgd:
|
|
460
|
+
start_bgd = end_bgd-100
|
|
461
|
+
if start_bgd > energy_scale[0] and end_bgd< energy_scale[-1]-100:
|
|
462
|
+
eds_xsection = get_eds_xsection(Xsection, energy_scale, start_bgd, end_bgd)
|
|
463
|
+
eds_xsection[eds_xsection<0] = 0.
|
|
464
|
+
start_sum = np.searchsorted(energy_scale, edge_info['L3']['onset'])
|
|
465
|
+
end_sum = start_sum+600
|
|
466
|
+
if end_sum> len(Xsection):
|
|
467
|
+
end_sum = len(Xsection)-1
|
|
468
|
+
if end_sum >np.searchsorted(energy_scale, edge_info['K1']['onset'])-10:
|
|
469
|
+
end_sum = np.searchsorted(energy_scale, edge_info['K1']['onset'])-10
|
|
470
|
+
eds_cross_sections['L'] = eds_xsection[start_sum:end_sum].sum()
|
|
471
|
+
L1_channel = np.searchsorted(energy_scale, edge_info['L1']['onset'])
|
|
472
|
+
m_start = start_sum-100
|
|
473
|
+
if m_start < 2:
|
|
474
|
+
m_start = start_sum-20
|
|
475
|
+
l3_rise = np.max(Xsection[m_start: L1_channel-10])-np.min(Xsection[m_start: L1_channel-10])
|
|
476
|
+
l1_rise = np.max(Xsection[L1_channel-10: L1_channel+100])-np.min(Xsection[L1_channel-10: L1_channel+100])
|
|
477
|
+
l1_ratio = l1_rise/l3_rise
|
|
478
|
+
|
|
479
|
+
eds_cross_sections['L1'] = l1_ratio * eds_cross_sections['L']
|
|
480
|
+
eds_cross_sections['L2'] = eds_cross_sections['L']*(1-l1_ratio)*1/3
|
|
481
|
+
eds_cross_sections['L3'] = eds_cross_sections['L']*(1-l1_ratio)*2/3
|
|
482
|
+
eds_cross_sections['yield_L1'] = Xyield['L1']
|
|
483
|
+
eds_cross_sections['yield_L2'] = Xyield['L2']
|
|
484
|
+
eds_cross_sections['yield_L3'] = Xyield['L3']
|
|
485
|
+
|
|
486
|
+
eds_cross_sections['L'] = eds_cross_sections['L1']*Xyield['L1']+eds_cross_sections['L2']*Xyield['L2']+eds_cross_sections['L3']*Xyield['L3']
|
|
487
|
+
# eds_cross_sections['L'] /= 8
|
|
488
|
+
if 'M5' in Xyield:
|
|
489
|
+
start_bgd = edge_info['M5']['onset'] * 0.8
|
|
490
|
+
end_bgd = edge_info['M5']['onset'] - 5
|
|
491
|
+
if start_bgd > end_bgd:
|
|
492
|
+
start_bgd = end_bgd-100
|
|
493
|
+
if start_bgd > energy_scale[0] and end_bgd< energy_scale[-1]-100:
|
|
494
|
+
eds_xsection = get_eds_xsection(Xsection, energy_scale, start_bgd, end_bgd)
|
|
495
|
+
eds_xsection[eds_xsection<0] = 0.
|
|
496
|
+
start_sum = np.searchsorted(energy_scale, edge_info['M5']['onset'])
|
|
497
|
+
end_sum = start_sum+600
|
|
498
|
+
if end_sum > np.searchsorted(energy_scale, edge_info['L3']['onset'])-10:
|
|
499
|
+
end_sum = np.searchsorted(energy_scale, edge_info['L3']['onset'])-10
|
|
500
|
+
eds_cross_sections['M'] = eds_xsection[start_sum:end_sum].sum()
|
|
501
|
+
#print(edge_info['M5']['onset'] - edge_info['M1']['onset'])
|
|
502
|
+
M3_channel = np.searchsorted(energy_scale, edge_info['M3']['onset'])
|
|
503
|
+
M1_channel = np.searchsorted(energy_scale, edge_info['M1']['onset'])
|
|
504
|
+
m5_rise = np.max(Xsection[start_sum-100: M3_channel-10])-np.min(Xsection[start_sum-100: M3_channel-10])
|
|
505
|
+
m3_rise = np.max(Xsection[M3_channel-10: M1_channel-10])-np.min(Xsection[M3_channel-10: M1_channel-10])
|
|
506
|
+
m1_rise = np.max(Xsection[M1_channel-10: M1_channel+100])-np.min(Xsection[M1_channel-10: M1_channel+100])
|
|
507
|
+
m1_ratio = m1_rise/m5_rise
|
|
508
|
+
m3_ratio = m3_rise/m5_rise
|
|
509
|
+
m5_ratio = 1-(m1_ratio+m3_ratio)
|
|
510
|
+
#print(m1_ratio, m3_ratio, 1-(m1_ratio+m3_ratio))
|
|
511
|
+
eds_cross_sections['M1'] = m1_ratio * eds_cross_sections['M']
|
|
512
|
+
eds_cross_sections['M2'] = m3_ratio * eds_cross_sections['M']*1/3
|
|
513
|
+
eds_cross_sections['M3'] = m3_ratio * eds_cross_sections['M']*2/3
|
|
514
|
+
eds_cross_sections['M4'] = m5_ratio * eds_cross_sections['M']*2/5
|
|
515
|
+
eds_cross_sections['M5'] = m5_ratio * eds_cross_sections['M']*3/5
|
|
516
|
+
eds_cross_sections['yield_M1'] = Xyield['M1']
|
|
517
|
+
eds_cross_sections['yield_M2'] = Xyield['M2']
|
|
518
|
+
eds_cross_sections['yield_M3'] = Xyield['M3']
|
|
519
|
+
eds_cross_sections['yield_M4'] = Xyield['M4']
|
|
520
|
+
eds_cross_sections['yield_M5'] = Xyield['M5']
|
|
521
|
+
eds_cross_sections['M'] = eds_cross_sections['M1']*Xyield['M1']+eds_cross_sections['M2']*Xyield['M2']+eds_cross_sections['M3']*Xyield['M3'] \
|
|
522
|
+
+eds_cross_sections['M4']*Xyield['M4']+eds_cross_sections['M5']*Xyield['M5']
|
|
523
|
+
#eds_cross_sections['M'] /= 18
|
|
503
524
|
return eds_cross_sections
|
|
504
525
|
|
|
505
526
|
|
|
@@ -555,4 +576,34 @@ def plot_phases(dataset, image=None, survey_image=None):
|
|
|
555
576
|
plt.legend()
|
|
556
577
|
plt.tight_layout()
|
|
557
578
|
plt.show()
|
|
558
|
-
return fig
|
|
579
|
+
return fig
|
|
580
|
+
|
|
581
|
+
|
|
582
|
+
def plot_lines(eds_quantification: dict, axis: plt.Axes):
|
|
583
|
+
for key, lines in eds_quantification.items():
|
|
584
|
+
if 'K-family' in lines:
|
|
585
|
+
intensity = lines['K-family']['height']
|
|
586
|
+
for line in lines['K-family']:
|
|
587
|
+
if line[0] == 'K':
|
|
588
|
+
pos = lines['K-family'][line]['position']
|
|
589
|
+
axis.plot([pos,pos], [0, intensity*lines['K-family'][line]['weight']], color='blue')
|
|
590
|
+
if line == lines['K-family']['main']:
|
|
591
|
+
axis.text(pos,0, key+'\n'+line, verticalalignment='top')
|
|
592
|
+
|
|
593
|
+
if 'L-family' in lines:
|
|
594
|
+
intensity = lines['L-family']['height']
|
|
595
|
+
for line in lines['L-family']:
|
|
596
|
+
if line[0] == 'L':
|
|
597
|
+
pos = lines['L-family'][line]['position']
|
|
598
|
+
axis.plot([pos,pos], [0, intensity*lines['L-family'][line]['weight']], color='black')
|
|
599
|
+
if line in [lines['L-family']['main'], 'L3-M5', 'L3-N5', 'L1-M3']:
|
|
600
|
+
axis.text(pos,0, key+'\n'+line, verticalalignment='top')
|
|
601
|
+
|
|
602
|
+
if 'M-family' in lines:
|
|
603
|
+
intensity = lines['M-family']['height']
|
|
604
|
+
for line in lines['M-family']:
|
|
605
|
+
if line[0] == 'M':
|
|
606
|
+
pos = lines['M-family'][line]['position']
|
|
607
|
+
axis.plot([pos,pos], [0, intensity*lines['M-family'][line]['weight']], color='green')
|
|
608
|
+
if line in [lines['M-family']['main'], 'M5-N7', 'M4-N6']:
|
|
609
|
+
axis.text(pos,0, key+'\n'+line, verticalalignment='top')
|
pyTEMlib/image_tools.py
CHANGED
|
@@ -601,8 +601,12 @@ def rigid_registration(dataset, sub_pixel=True):
|
|
|
601
601
|
rig_reg, drift = rig_reg_drift(dataset, relative_drift)
|
|
602
602
|
crop_reg, input_crop = crop_image_stack(rig_reg, drift)
|
|
603
603
|
|
|
604
|
-
rigid_registered =
|
|
605
|
-
|
|
604
|
+
rigid_registered = sidpy.Dataset.from_array(crop_reg,
|
|
605
|
+
title='Rigid Registration',
|
|
606
|
+
data_type='IMAGE_STACK',
|
|
607
|
+
quantity=dataset.quantity,
|
|
608
|
+
units=dataset.units)
|
|
609
|
+
rigid_registered.title = 'Rigid_Registration'
|
|
606
610
|
rigid_registered.source = dataset.title
|
|
607
611
|
rigid_registered.metadata = {'analysis': 'rigid sub-pixel registration', 'drift': drift,
|
|
608
612
|
'input_crop': input_crop, 'input_shape': dataset.shape[1:]}
|
|
@@ -664,9 +668,9 @@ def rig_reg_drift(dset, rel_drift):
|
|
|
664
668
|
# absolute drift
|
|
665
669
|
print(rel_drift)
|
|
666
670
|
drift = np.array(rel_drift).copy()
|
|
667
|
-
|
|
671
|
+
|
|
668
672
|
drift[0] = [0, 0]
|
|
669
|
-
for i in range(drift.shape[0]):
|
|
673
|
+
for i in range(1, drift.shape[0]):
|
|
670
674
|
drift[i] = drift[i - 1] + rel_drift[i]
|
|
671
675
|
center_drift = drift[int(drift.shape[0] / 2)]
|
|
672
676
|
drift = drift - center_drift
|
pyTEMlib/version.py
CHANGED