pyTEMlib 0.2024.2.2__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 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['acceleration_voltage_V'] = 200000
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-L3' in x_sections[str(element)]['lines']:
186
- if abs(x_sections[str(element)]['lines']['K-L3']['position']- energy_scale[peak]) <10:
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 'K-L2' in x_sections[str(element)]['lines']:
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']['ionization_x_section'] = xs['K']
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']['ionization_x_section'] = xs['L']
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']['ionization_x_section'] = xs['M']
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']['lines']
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
- lines['K-family']['height'] /= lines['K-family']['peaks'].max()
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'] /= lines['L-family']['peaks'].max()
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'] /= lines['M-family']['peaks'].max()
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
- energy_scale = spectrum.get_spectral_dims(return_axis=True)[0].values
370
- pp= spectrum.metadata['EDS']['parameters']
371
- for i in range(len(pp) - 3):
372
- model += peaks[i] * pp[i]
373
- if 'detector_efficiency' in spectrum.metadata['experiment']['detector'].keys():
374
- detector_efficiency = spectrum.metadata['experiment']['detector']['detector_efficiency']
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']['acceleration_voltage_V']
347
+ E_0 = spectrum.metadata['experiment']['acceleration_voltage']
378
348
 
379
- if detector_efficiency is not None:
380
- model[start:] += detector_efficiency[start:] * (pp[-3] + pp[-2] * (E_0 - energy_scale) / energy_scale +
381
- pp[-1] * (E_0 - energy_scale) ** 2 / energy_scale)
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['experiment'].keys():
391
- if 'start_channel' not in spectrum.metadata['experiment']['detector']:
392
- spectrum.metadata['experiment']['detector']['start_channel'] = np.searchsorted(energy_scale, 100)
393
- if 'detector_efficiency' in spectrum.metadata['experiment']['detector'].keys():
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['experiment']['detector']['detector_efficiency']
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['experiment']['detector']['start_channel']
371
+ start = spectrum.metadata['EDS']['detector']['start_channel']
402
372
  energy_scale = energy_scale[start:]
403
373
 
404
- E_0= spectrum.metadata['experiment']['acceleration_voltage_V']
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']['lines'] = out_tags
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']['height'] = p[index]
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']['height'] = p[index]
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']['height'] =p[index]
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(10, 20000)
467
- Xsection = pyTEMlib.eels_tools.xsec_xrpa(energy_scale, 200, z, 400.)
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
- if 'K1' in edge_info:
471
- start_bgd = edge_info['K1']['onset'] * 0.8
472
- end_bgd = edge_info['K1']['onset'] - 5
473
- if start_bgd > end_bgd:
474
- start_bgd = end_bgd-100
475
- if start_bgd > energy_scale[0] and end_bgd< energy_scale[-1]-100:
476
- eds_xsection = get_eds_xsection(Xsection, energy_scale, start_bgd, end_bgd)
477
- eds_xsection = Xsection - eds_xsection
478
- eds_xsection[eds_xsection<0] = 0.
479
- start_sum = np.searchsorted(energy_scale, edge_info['K1']['onset'])
480
- eds_cross_sections['K'] = eds_xsection[start_sum:start_sum+200].sum()
481
- if 'L3' in edge_info:
482
- start_bgd = edge_info['L3']['onset'] * 0.8
483
- end_bgd = edge_info['L3']['onset'] - 5
484
- if start_bgd > end_bgd:
485
- start_bgd = end_bgd-100
486
- if start_bgd > energy_scale[0] and end_bgd< energy_scale[-1]-100:
487
- eds_xsection = get_eds_xsection(Xsection, energy_scale, start_bgd, end_bgd)
488
- eds_xsection = Xsection - eds_xsection
489
- eds_xsection[eds_xsection<0] = 0.
490
- start_sum = np.searchsorted(energy_scale, edge_info['L3']['onset'])
491
- eds_cross_sections['L'] = eds_xsection[start_sum:start_sum+200].sum()
492
- if 'M5' in edge_info:
493
- start_bgd = edge_info['M5']['onset'] * 0.8
494
- end_bgd = edge_info['M5']['onset'] - 5
495
- if start_bgd > end_bgd:
496
- start_bgd = end_bgd-100
497
- if start_bgd > energy_scale[0] and end_bgd< energy_scale[-1]-100:
498
- eds_xsection = get_eds_xsection(Xsection, energy_scale, start_bgd, end_bgd)
499
- eds_xsection = Xsection - eds_xsection
500
- eds_xsection[eds_xsection<0] = 0.
501
- start_sum = np.searchsorted(energy_scale, edge_info['M5']['onset'])
502
- eds_cross_sections['M'] = eds_xsection[start_sum:start_sum+200].sum()
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/eels_dialog.py CHANGED
@@ -1,6 +1,4 @@
1
1
  """
2
- QT dialog window for EELS compositional analysis
3
-
4
2
  Author: Gerd Duscher
5
3
  """
6
4
 
@@ -93,7 +91,7 @@ class CurveVisualizer(object):
93
91
  legline.set_alpha(0.2)
94
92
  self.fig.canvas.draw()
95
93
 
96
- def get_sidebar():
94
+ def get_core_loss_sidebar():
97
95
  side_bar = ipywidgets.GridspecLayout(14, 3,width='auto', grid_gap="0px")
98
96
 
99
97
 
@@ -194,6 +192,7 @@ def get_sidebar():
194
192
  return side_bar
195
193
 
196
194
 
195
+
197
196
  class CompositionWidget(object):
198
197
  def __init__(self, datasets=None, key=None):
199
198
 
@@ -203,7 +202,7 @@ class CompositionWidget(object):
203
202
 
204
203
 
205
204
  self.model = []
206
- self.sidebar = get_sidebar()
205
+ self.sidebar = get_core_loss_sidebar()
207
206
 
208
207
  self.set_dataset(key)
209
208
 
@@ -312,11 +311,12 @@ class CompositionWidget(object):
312
311
  reference_list =[('None', -1)]
313
312
 
314
313
  for index, key in enumerate(self.datasets.keys()):
315
- if 'Reference' not in key:
316
- if 'SPECTR' in self.datasets[key].data_type.name:
317
- spectrum_list.append((f'{key}: {self.datasets[key].title}', index))
318
- self.spectrum_keys_list.append(key)
319
- reference_list.append((f'{key}: {self.datasets[key].title}', index))
314
+ if '_rel' not in key:
315
+ if 'Reference' not in key :
316
+ if 'SPECTR' in self.datasets[key].data_type.name:
317
+ spectrum_list.append((f'{key}: {self.datasets[key].title}', index))
318
+ self.spectrum_keys_list.append(key)
319
+ reference_list.append((f'{key}: {self.datasets[key].title}', index))
320
320
 
321
321
  if set_key in self.spectrum_keys_list:
322
322
  self.key = set_key
@@ -324,10 +324,11 @@ class CompositionWidget(object):
324
324
  self.key = self.spectrum_keys_list[-1]
325
325
  self.dataset = self.datasets[self.key]
326
326
 
327
- spec_dim = self.dataset.get_dimensions_by_type(sidpy.DimensionType.SPECTRAL)
328
- self.spec_dim = self.dataset._axes[spec_dim[0]]
327
+ self.spec_dim = self.dataset.get_spectral_dims(return_axis=True)[0]
329
328
 
330
329
  self.energy_scale = self.spec_dim.values
330
+ self.dd = (self.energy_scale[0], self.energy_scale[1])
331
+
331
332
  self.dataset.metadata['experiment']['offset'] = self.energy_scale[0]
332
333
  self.dataset.metadata['experiment']['dispersion'] = self.energy_scale[1] - self.energy_scale[0]
333
334
  if 'edges' not in self.dataset.metadata or self.dataset.metadata['edges'] == {}:
@@ -634,7 +635,7 @@ class CompositionWidget(object):
634
635
  raise ValueError('need a experiment parameter in metadata dictionary')
635
636
 
636
637
  eff_beta = eels.effective_collection_angle(self.energy_scale, alpha, beta, beam_kv)
637
-
638
+ eff_beta = beta
638
639
  self.low_loss = None
639
640
  if self.sidebar[12, 1].value:
640
641
  for key in self.datasets.keys():
@@ -1033,13 +1033,12 @@ class EdgesAtCursor(object):
1033
1033
  self.label.remove()
1034
1034
  self.line.remove()
1035
1035
  if event.button == 1:
1036
- self.label = self.ax.text(x, y_max, eels.find_major_edges(event.xdata, self.maximal_chemical_shift),
1036
+ self.label = self.ax.text(x, y_max, eels.find_all_edges(event.xdata, self.maximal_chemical_shift, major_edges_only=True),
1037
1037
  verticalalignment='top')
1038
1038
  self.line, = self.ax.plot([x, x], [y_min, y_max], color='black')
1039
1039
  if event.button == 3:
1040
1040
  self.line, = self.ax.plot([x, x], [y_min, y_max], color='black')
1041
- self.label = self.ax.text(x, y_max, eels.find_all_edges(event.xdata, self.maximal_chemical_shift),
1042
- verticalalignment='top')
1041
+ self.label = self.ax.text(x, y_max, eels.find_all_edges(event.xdata, self.maximal_chemical_shift), verticalalignment='top')
1043
1042
  self.ax.set_ylim(y_min, y_max)
1044
1043
 
1045
1044
  def mouse_move(self, event):