pyTEMlib : EELS_tools
Analysing Low-Loss Spectra with Drude Theory¶
part of
a pycroscopy ecosystem package Notebook by
Gerd Duscher
Microscopy Facilities
Materials Science & Engineering
Institute of Advanced Materials & Manufacturing
The University of Tennessee, Knoxville
Analyse EELS spectra and spectrum images.
Content¶
The main feature in a low-loss EELS spectrum is the volume plasmon peak.
This volume plasmon and all other features in the low-loss region of an EELS spectrum are described by Dielectric Theory of Electrodynamics.
The simplest theory to interprete this energy range is the Drude theory.
Another easy to observe component is the multiple scattering of this plasmon peak, which we can correct for or use for thickness determination.
See Notebook: Analysing Low-Loss Spectra with Drude Theory of the MSE672-Introduction-to-TEM Lecture in my Github account.
Load important packages¶
Check Installed Packages¶
import sys
import importlib.metadata
def test_package(package_name):
"""Test if package exists and returns version or -1"""
try:
version = importlib.metadata.version(package_name)
except importlib.metadata.PackageNotFoundError:
version = '-1'
return version
# pyTEMlib setup ------------------
if test_package('pyTEMlib') < '0.2025.1.0':
print('installing pyTEMlib')
!{sys.executable} -m pip install --upgrade git+https://github.com/pycroscopy/pyTEMlib.git@main -q --upgrade
# ------------------------------
print('done')done
Import all relevant libraries¶
Please note that the EELS_tools package from pyTEMlib is essential.
%matplotlib widget
import matplotlib.pyplot as plt
import numpy as np
import sys
%load_ext autoreload
%autoreload 2
if 'google.colab' in sys.modules:
from google.colab import output
output.enable_custom_widget_manager()
from google.colab import drive
sys.path.insert(0,'../../')
sys.path.insert(0,'../../../sidpy/')
import sidpy
# Import libraries from pyTEMlib
import pyTEMlib
import pyTEMlib.file_tools as ft # File input/ output library
from pyTEMlib import eels_tools
# import pyTEMlib.info_widget3
import pyTEMlib.kinematic_scattering as ks # Kinematic sCattering Library
# Atomic form factors from Kirklands book
# For archiving reasons it is a good idea to print the version numbers out at this point
print('pyTEM version: ',pyTEMlib.__version__)You don't have igor2 installed. If you wish to open igor files, you will need to install it (pip install igor2) before attempting.
You don't have gwyfile installed. If you wish to open .gwy files, you will need to install it (pip install gwyfile) before attempting.
Symmetry functions of spglib enabled
Using kinematic_scattering library version {_version_ } by G.Duscher
pyTEM version: 0.2025.02.2
if 'google.colab' in sys.modules:
drive.mount("/content/drive")
# infoWidget= pyTEMlib.info_widget3.EELSWidget()
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\ipywidgets\widgets\widget.py:721, in Widget._lock_property(self, **properties)
720 try:
--> 721 yield
722 finally:
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\ipywidgets\widgets\widget.py:650, in Widget.set_state(self, sync_data)
647 # The order of these context managers is important. Properties must
648 # be locked when the hold_trait_notification context manager is
649 # released and notifications are fired.
--> 650 with self._lock_property(**sync_data), self.hold_trait_notifications():
651 for name in sync_data:
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\contextlib.py:144, in _GeneratorContextManager.__exit__(self, typ, value, traceback)
143 try:
--> 144 next(self.gen)
145 except StopIteration:
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\traitlets\traitlets.py:1510, in HasTraits.hold_trait_notifications(self)
1509 for change in changes:
-> 1510 self.notify_change(change)
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\ipywidgets\widgets\widget.py:701, in Widget.notify_change(self, change)
700 self.send_state(key=name)
--> 701 super().notify_change(change)
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\traitlets\traitlets.py:1525, in HasTraits.notify_change(self, change)
1524 """Notify observers of a change event"""
-> 1525 return self._notify_observers(change)
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\traitlets\traitlets.py:1568, in HasTraits._notify_observers(self, event)
1566 c = getattr(self, c.name)
-> 1568 c(event)
File c:\Users\gduscher\OneDrive - University of Tennessee\GitHub\pyTEMlib\notebooks\Spectroscopy\../..\pyTEMlib\info_widget3.py:818, in EELSWidget.tab_activated(self, val)
817 if self.tabval == 1:
--> 818 self.info.update_dataset()
819 elif self.tabval == 2:
File c:\Users\gduscher\OneDrive - University of Tennessee\GitHub\pyTEMlib\notebooks\Spectroscopy\../..\pyTEMlib\info_widget3.py:1061, in Info.update_dataset(self, value)
1060 self.update_sidebar()
-> 1061 self.parent._update(0)
File c:\Users\gduscher\OneDrive - University of Tennessee\GitHub\pyTEMlib\notebooks\Spectroscopy\../..\pyTEMlib\info_widget3.py:514, in EELSBaseWidget._update(self, ev)
513 self.get_spectrum()
--> 514 self.plot_spectrum()
File c:\Users\gduscher\OneDrive - University of Tennessee\GitHub\pyTEMlib\notebooks\Spectroscopy\../..\pyTEMlib\info_widget3.py:492, in EELSBaseWidget.plot_spectrum(self)
490 self.spectrum_plot.data = [self.spectrum_plot.data[0]]
--> 492 self.xlabel = self.spectrum.labels[0]
493 self.ylabel = self.datasets[self.key].data_descriptor
IndexError: list index out of range
During handling of the above exception, another exception occurred:
IndexError Traceback (most recent call last)
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\ipywidgets\widgets\widget.py:773, in Widget._handle_msg(self, msg)
771 if 'buffer_paths' in data:
772 _put_buffers(state, data['buffer_paths'], msg['buffers'])
--> 773 self.set_state(state)
775 # Handle a state request.
776 elif method == 'request_state':
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\ipywidgets\widgets\widget.py:650, in Widget.set_state(self, sync_data)
645 self._send(msg, buffers=echo_buffers)
647 # The order of these context managers is important. Properties must
648 # be locked when the hold_trait_notification context manager is
649 # released and notifications are fired.
--> 650 with self._lock_property(**sync_data), self.hold_trait_notifications():
651 for name in sync_data:
652 if name in self.keys:
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\contextlib.py:158, in _GeneratorContextManager.__exit__(self, typ, value, traceback)
156 value = typ()
157 try:
--> 158 self.gen.throw(value)
159 except StopIteration as exc:
160 # Suppress StopIteration *unless* it's the same exception that
161 # was passed to throw(). This prevents a StopIteration
162 # raised inside the "with" statement from being suppressed.
163 return exc is not value
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\ipywidgets\widgets\widget.py:723, in Widget._lock_property(self, **properties)
721 yield
722 finally:
--> 723 self._property_lock = {}
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\traitlets\traitlets.py:716, in TraitType.__set__(self, obj, value)
714 if self.read_only:
715 raise TraitError('The "%s" trait is read-only.' % self.name)
--> 716 self.set(obj, value)
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\traitlets\traitlets.py:706, in TraitType.set(self, obj, value)
702 silent = False
703 if silent is not True:
704 # we explicitly compare silent to True just in case the equality
705 # comparison above returns something other than True/False
--> 706 obj._notify_trait(self.name, old_value, new_value)
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\traitlets\traitlets.py:1513, in HasTraits._notify_trait(self, name, old_value, new_value)
1512 def _notify_trait(self, name: str, old_value: t.Any, new_value: t.Any) -> None:
-> 1513 self.notify_change(
1514 Bunch(
1515 name=name,
1516 old=old_value,
1517 new=new_value,
1518 owner=self,
1519 type="change",
1520 )
1521 )
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\ipywidgets\widgets\widget.py:701, in Widget.notify_change(self, change)
698 if name in self.keys and self._should_send_property(name, getattr(self, name)):
699 # Send new state to front-end
700 self.send_state(key=name)
--> 701 super().notify_change(change)
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\traitlets\traitlets.py:1525, in HasTraits.notify_change(self, change)
1523 def notify_change(self, change: Bunch) -> None:
1524 """Notify observers of a change event"""
-> 1525 return self._notify_observers(change)
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\traitlets\traitlets.py:1568, in HasTraits._notify_observers(self, event)
1565 elif isinstance(c, EventHandler) and c.name is not None:
1566 c = getattr(self, c.name)
-> 1568 c(event)
File c:\Users\gduscher\OneDrive - University of Tennessee\GitHub\pyTEMlib\notebooks\Spectroscopy\../..\pyTEMlib\info_widget3.py:818, in EELSWidget.tab_activated(self, val)
816 # self.update_sidebars()
817 if self.tabval == 1:
--> 818 self.info.update_dataset()
819 elif self.tabval == 2:
820 self.low_loss.update_ll_sidebar()
File c:\Users\gduscher\OneDrive - University of Tennessee\GitHub\pyTEMlib\notebooks\Spectroscopy\../..\pyTEMlib\info_widget3.py:1061, in Info.update_dataset(self, value)
1059 self.parent.datasets['_relationship']['spectrum'] = self.info_key
1060 self.update_sidebar()
-> 1061 self.parent._update(0)
File c:\Users\gduscher\OneDrive - University of Tennessee\GitHub\pyTEMlib\notebooks\Spectroscopy\../..\pyTEMlib\info_widget3.py:514, in EELSBaseWidget._update(self, ev)
512 def _update(self, ev=None):
513 self.get_spectrum()
--> 514 self.plot_spectrum()
File c:\Users\gduscher\OneDrive - University of Tennessee\GitHub\pyTEMlib\notebooks\Spectroscopy\../..\pyTEMlib\info_widget3.py:492, in EELSBaseWidget.plot_spectrum(self)
489 self.spectrum_plot.add_trace(go.Scatter(x=self.energy_scale, y=self.spectrum, mode='markers+lines', marker_size=.1, name=self.dataset.title))
490 self.spectrum_plot.data = [self.spectrum_plot.data[0]]
--> 492 self.xlabel = self.spectrum.labels[0]
493 self.ylabel = self.datasets[self.key].data_descriptor
494 # self.change_y_scale = 1.0
IndexError: list index out of range---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\ipywidgets\widgets\widget.py:773, in Widget._handle_msg(self, msg)
771 if 'buffer_paths' in data:
772 _put_buffers(state, data['buffer_paths'], msg['buffers'])
--> 773 self.set_state(state)
775 # Handle a state request.
776 elif method == 'request_state':
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\ipywidgets\widgets\widget.py:650, in Widget.set_state(self, sync_data)
645 self._send(msg, buffers=echo_buffers)
647 # The order of these context managers is important. Properties must
648 # be locked when the hold_trait_notification context manager is
649 # released and notifications are fired.
--> 650 with self._lock_property(**sync_data), self.hold_trait_notifications():
651 for name in sync_data:
652 if name in self.keys:
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\contextlib.py:144, in _GeneratorContextManager.__exit__(self, typ, value, traceback)
142 if typ is None:
143 try:
--> 144 next(self.gen)
145 except StopIteration:
146 return False
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\traitlets\traitlets.py:1510, in HasTraits.hold_trait_notifications(self)
1508 for changes in cache.values():
1509 for change in changes:
-> 1510 self.notify_change(change)
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\ipywidgets\widgets\widget.py:701, in Widget.notify_change(self, change)
698 if name in self.keys and self._should_send_property(name, getattr(self, name)):
699 # Send new state to front-end
700 self.send_state(key=name)
--> 701 super().notify_change(change)
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\traitlets\traitlets.py:1525, in HasTraits.notify_change(self, change)
1523 def notify_change(self, change: Bunch) -> None:
1524 """Notify observers of a change event"""
-> 1525 return self._notify_observers(change)
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\traitlets\traitlets.py:1568, in HasTraits._notify_observers(self, event)
1565 elif isinstance(c, EventHandler) and c.name is not None:
1566 c = getattr(self, c.name)
-> 1568 c(event)
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\ipywidgets\widgets\widget_selection.py:236, in _Selection._propagate_index(self, change)
234 self.label = label
235 if self.value is not value:
--> 236 self.value = value
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\traitlets\traitlets.py:716, in TraitType.__set__(self, obj, value)
714 if self.read_only:
715 raise TraitError('The "%s" trait is read-only.' % self.name)
--> 716 self.set(obj, value)
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\traitlets\traitlets.py:706, in TraitType.set(self, obj, value)
702 silent = False
703 if silent is not True:
704 # we explicitly compare silent to True just in case the equality
705 # comparison above returns something other than True/False
--> 706 obj._notify_trait(self.name, old_value, new_value)
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\traitlets\traitlets.py:1513, in HasTraits._notify_trait(self, name, old_value, new_value)
1512 def _notify_trait(self, name: str, old_value: t.Any, new_value: t.Any) -> None:
-> 1513 self.notify_change(
1514 Bunch(
1515 name=name,
1516 old=old_value,
1517 new=new_value,
1518 owner=self,
1519 type="change",
1520 )
1521 )
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\ipywidgets\widgets\widget.py:701, in Widget.notify_change(self, change)
698 if name in self.keys and self._should_send_property(name, getattr(self, name)):
699 # Send new state to front-end
700 self.send_state(key=name)
--> 701 super().notify_change(change)
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\traitlets\traitlets.py:1525, in HasTraits.notify_change(self, change)
1523 def notify_change(self, change: Bunch) -> None:
1524 """Notify observers of a change event"""
-> 1525 return self._notify_observers(change)
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\traitlets\traitlets.py:1568, in HasTraits._notify_observers(self, event)
1565 elif isinstance(c, EventHandler) and c.name is not None:
1566 c = getattr(self, c.name)
-> 1568 c(event)
File c:\Users\gduscher\OneDrive - University of Tennessee\GitHub\pyTEMlib\notebooks\Spectroscopy\../..\pyTEMlib\info_widget3.py:1056, in Info.update_dataset(self, value)
1053 self.parent.info_key = self.key
1055 if self.info_key != 'None':
-> 1056 self.parent.set_dataset(self.info_key)
1057 self.parent.status_message(self.key+' , '+ self.parent.info_key)
1058 if '_relationship' in self.parent.datasets.keys():
File c:\Users\gduscher\OneDrive - University of Tennessee\GitHub\pyTEMlib\notebooks\Spectroscopy\../..\pyTEMlib\info_widget3.py:646, in EELSBaseWidget.set_dataset(self, key)
643 self.bin_y = 1
644 self.count = 0
--> 646 self.update_sidebars()
647 #self.update_sidebar()
648 self.plot()
File c:\Users\gduscher\OneDrive - University of Tennessee\GitHub\pyTEMlib\notebooks\Spectroscopy\../..\pyTEMlib\info_widget3.py:830, in EELSWidget.update_sidebars(self)
828 def update_sidebars(self):
829 if hasattr(self, 'info'):
--> 830 self.info.update_sidebar()
File c:\Users\gduscher\OneDrive - University of Tennessee\GitHub\pyTEMlib\notebooks\Spectroscopy\../..\pyTEMlib\info_widget3.py:1024, in Info.update_sidebar(self)
1022 self.info_tab[2, 0].unobserve_all()
1023 self.info_tab[2, 0].value = np.round(offset, 3)
-> 1024 self.info_tab[3, 0].value = np.round(dispersion, 4)
1025 self.info_tab[5, 0].value = np.round(self.parent.datasets[self.key].metadata['experiment']['convergence_angle'], 1)
1026 self.info_tab[6, 0].value = np.round(self.parent.datasets[self.key].metadata['experiment']['collection_angle'], 1)
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\traitlets\traitlets.py:716, in TraitType.__set__(self, obj, value)
714 if self.read_only:
715 raise TraitError('The "%s" trait is read-only.' % self.name)
--> 716 self.set(obj, value)
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\traitlets\traitlets.py:706, in TraitType.set(self, obj, value)
702 silent = False
703 if silent is not True:
704 # we explicitly compare silent to True just in case the equality
705 # comparison above returns something other than True/False
--> 706 obj._notify_trait(self.name, old_value, new_value)
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\traitlets\traitlets.py:1513, in HasTraits._notify_trait(self, name, old_value, new_value)
1512 def _notify_trait(self, name: str, old_value: t.Any, new_value: t.Any) -> None:
-> 1513 self.notify_change(
1514 Bunch(
1515 name=name,
1516 old=old_value,
1517 new=new_value,
1518 owner=self,
1519 type="change",
1520 )
1521 )
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\ipywidgets\widgets\widget.py:701, in Widget.notify_change(self, change)
698 if name in self.keys and self._should_send_property(name, getattr(self, name)):
699 # Send new state to front-end
700 self.send_state(key=name)
--> 701 super().notify_change(change)
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\traitlets\traitlets.py:1525, in HasTraits.notify_change(self, change)
1523 def notify_change(self, change: Bunch) -> None:
1524 """Notify observers of a change event"""
-> 1525 return self._notify_observers(change)
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\traitlets\traitlets.py:1568, in HasTraits._notify_observers(self, event)
1565 elif isinstance(c, EventHandler) and c.name is not None:
1566 c = getattr(self, c.name)
-> 1568 c(event)
File c:\Users\gduscher\OneDrive - University of Tennessee\GitHub\pyTEMlib\notebooks\Spectroscopy\../..\pyTEMlib\info_widget3.py:891, in Info.set_energy_scale(self, value)
889 self.energy_scale *= (self.info_tab[3, 0].value / dispersion)
890 self.energy_scale += (self.info_tab[2, 0].value - self.energy_scale[0])
--> 891 self.parent.plot()
File c:\Users\gduscher\OneDrive - University of Tennessee\GitHub\pyTEMlib\notebooks\Spectroscopy\../..\pyTEMlib\info_widget3.py:444, in EELSBaseWidget.plot(self, scale)
442 self.get_image()
443 self.canvas_plot.children = [self.image_plot, self.spectrum_plot]
--> 444 self.plot_spectrum_image()
445 # self.axis = self.axes[-1]
446 self.spectrum = self.get_spectrum()
File c:\Users\gduscher\OneDrive - University of Tennessee\GitHub\pyTEMlib\notebooks\Spectroscopy\../..\pyTEMlib\info_widget3.py:588, in EELSBaseWidget.plot_spectrum_image(self)
586 self.image_plot.data = [self.image_plot.data[0]]
587 self.image_plot.data[0].z=np.array(self.image).T
--> 588 self.plot_spectrum()
589 self.image_plot.add_trace(
590 go.Scatter(mode="markers", x=[0], y=[0], marker_symbol=[101],
591 marker_color="darkgray",
592 marker_line_width=1, marker_size=11, hovertemplate= 'x: %{x}<br>y: %{y}'))
594 self.image_plot.data[0].on_selection(self.selection_fn)
File c:\Users\gduscher\OneDrive - University of Tennessee\GitHub\pyTEMlib\notebooks\Spectroscopy\../..\pyTEMlib\info_widget3.py:492, in EELSBaseWidget.plot_spectrum(self)
489 self.spectrum_plot.add_trace(go.Scatter(x=self.energy_scale, y=self.spectrum, mode='markers+lines', marker_size=.1, name=self.dataset.title))
490 self.spectrum_plot.data = [self.spectrum_plot.data[0]]
--> 492 self.xlabel = self.spectrum.labels[0]
493 self.ylabel = self.datasets[self.key].data_descriptor
494 # self.change_y_scale = 1.0
IndexError: list index out of range---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\ipywidgets\widgets\widget.py:773, in Widget._handle_msg(self, msg)
771 if 'buffer_paths' in data:
772 _put_buffers(state, data['buffer_paths'], msg['buffers'])
--> 773 self.set_state(state)
775 # Handle a state request.
776 elif method == 'request_state':
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\ipywidgets\widgets\widget.py:650, in Widget.set_state(self, sync_data)
645 self._send(msg, buffers=echo_buffers)
647 # The order of these context managers is important. Properties must
648 # be locked when the hold_trait_notification context manager is
649 # released and notifications are fired.
--> 650 with self._lock_property(**sync_data), self.hold_trait_notifications():
651 for name in sync_data:
652 if name in self.keys:
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\contextlib.py:144, in _GeneratorContextManager.__exit__(self, typ, value, traceback)
142 if typ is None:
143 try:
--> 144 next(self.gen)
145 except StopIteration:
146 return False
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\traitlets\traitlets.py:1510, in HasTraits.hold_trait_notifications(self)
1508 for changes in cache.values():
1509 for change in changes:
-> 1510 self.notify_change(change)
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\ipywidgets\widgets\widget.py:701, in Widget.notify_change(self, change)
698 if name in self.keys and self._should_send_property(name, getattr(self, name)):
699 # Send new state to front-end
700 self.send_state(key=name)
--> 701 super().notify_change(change)
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\traitlets\traitlets.py:1525, in HasTraits.notify_change(self, change)
1523 def notify_change(self, change: Bunch) -> None:
1524 """Notify observers of a change event"""
-> 1525 return self._notify_observers(change)
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\traitlets\traitlets.py:1568, in HasTraits._notify_observers(self, event)
1565 elif isinstance(c, EventHandler) and c.name is not None:
1566 c = getattr(self, c.name)
-> 1568 c(event)
File c:\Users\gduscher\OneDrive - University of Tennessee\GitHub\pyTEMlib\notebooks\Spectroscopy\../..\pyTEMlib\info_widget3.py:896, in Info.set_y_scale(self, value)
894 self.count += 1
895 self.parent.change_y_scale = 1.0 / self.parent.y_scale
--> 896 if self.parent.datasets[self.parent.key].metadata['experiment']['flux_ppm'] > 1e-12:
897 if self.info_tab[9, 2].value:
898 dispersion = self.parent.datasets[self.parent.key].get_dimension_slope(self.parent.energy_scale)
KeyError: 'flux_ppm'---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\ipywidgets\widgets\widget.py:773, in Widget._handle_msg(self, msg)
771 if 'buffer_paths' in data:
772 _put_buffers(state, data['buffer_paths'], msg['buffers'])
--> 773 self.set_state(state)
775 # Handle a state request.
776 elif method == 'request_state':
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\ipywidgets\widgets\widget.py:650, in Widget.set_state(self, sync_data)
645 self._send(msg, buffers=echo_buffers)
647 # The order of these context managers is important. Properties must
648 # be locked when the hold_trait_notification context manager is
649 # released and notifications are fired.
--> 650 with self._lock_property(**sync_data), self.hold_trait_notifications():
651 for name in sync_data:
652 if name in self.keys:
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\contextlib.py:144, in _GeneratorContextManager.__exit__(self, typ, value, traceback)
142 if typ is None:
143 try:
--> 144 next(self.gen)
145 except StopIteration:
146 return False
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\traitlets\traitlets.py:1510, in HasTraits.hold_trait_notifications(self)
1508 for changes in cache.values():
1509 for change in changes:
-> 1510 self.notify_change(change)
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\ipywidgets\widgets\widget.py:701, in Widget.notify_change(self, change)
698 if name in self.keys and self._should_send_property(name, getattr(self, name)):
699 # Send new state to front-end
700 self.send_state(key=name)
--> 701 super().notify_change(change)
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\traitlets\traitlets.py:1525, in HasTraits.notify_change(self, change)
1523 def notify_change(self, change: Bunch) -> None:
1524 """Notify observers of a change event"""
-> 1525 return self._notify_observers(change)
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\traitlets\traitlets.py:1568, in HasTraits._notify_observers(self, event)
1565 elif isinstance(c, EventHandler) and c.name is not None:
1566 c = getattr(self, c.name)
-> 1568 c(event)
File c:\Users\gduscher\OneDrive - University of Tennessee\GitHub\pyTEMlib\notebooks\Spectroscopy\../..\pyTEMlib\info_widget3.py:896, in Info.set_y_scale(self, value)
894 self.count += 1
895 self.parent.change_y_scale = 1.0 / self.parent.y_scale
--> 896 if self.parent.datasets[self.parent.key].metadata['experiment']['flux_ppm'] > 1e-12:
897 if self.info_tab[9, 2].value:
898 dispersion = self.parent.datasets[self.parent.key].get_dimension_slope(self.parent.energy_scale)
KeyError: 'flux_ppm'file_widget = ft.FileWidget3()v =file_widget.selected_dataset.plot()dir(file_widget.dataset)['A',
'T',
'_Array__chunks',
'_Array__name',
'_Dataset__protected',
'_Dataset__rearrange_axes',
'_Dataset__reduce_dimensions',
'_Dataset__validate_dim',
'__abs__',
'__add__',
'__and__',
'__array__',
'__array_function__',
'__array_priority__',
'__array_ufunc__',
'__await__',
'__bool__',
'__class__',
'__complex__',
'__dask_graph__',
'__dask_keys__',
'__dask_layers__',
'__dask_optimize__',
'__dask_postcompute__',
'__dask_postpersist__',
'__dask_scheduler__',
'__dask_tokenize__',
'__deepcopy__',
'__delattr__',
'__dict__',
'__dir__',
'__div__',
'__divmod__',
'__doc__',
'__eq__',
'__float__',
'__floordiv__',
'__format__',
'__ge__',
'__getattribute__',
'__getitem__',
'__getstate__',
'__gt__',
'__hash__',
'__index__',
'__init__',
'__init_subclass__',
'__int__',
'__invert__',
'__iter__',
'__le__',
'__len__',
'__long__',
'__lshift__',
'__lt__',
'__matmul__',
'__mod__',
'__module__',
'__mul__',
'__ne__',
'__neg__',
'__new__',
'__nonzero__',
'__or__',
'__pos__',
'__pow__',
'__radd__',
'__rand__',
'__rdiv__',
'__rdivmod__',
'__reduce__',
'__reduce_ex__',
'__repr__',
'__rfloordiv__',
'__rlshift__',
'__rmatmul__',
'__rmod__',
'__rmul__',
'__ror__',
'__rpow__',
'__rrshift__',
'__rshift__',
'__rsub__',
'__rtruediv__',
'__rxor__',
'__setattr__',
'__setitem__',
'__sizeof__',
'__slots__',
'__str__',
'__sub__',
'__subclasshook__',
'__truediv__',
'__weakref__',
'__xor__',
'_axes',
'_cached_keys',
'_chunks',
'_closest_point',
'_data_type',
'_elemwise',
'_griddata_transform',
'_h5_dataset',
'_key_array',
'_meta',
'_metadata',
'_min_dist',
'_modality',
'_name',
'_original_metadata',
'_quantity',
'_rebuild',
'_repr_html_',
'_reset_cache',
'_scalarfunc',
'_source',
'_structures',
'_title',
'_units',
'_variance',
'_vindex',
'abs',
'add_provenance',
'add_structure',
'adjust_axis',
'all',
'angle',
'any',
'argmax',
'argmin',
'argtopk',
'astype',
'blocks',
'choose',
'chunks',
'chunksize',
'clip',
'compute',
'compute_chunk_sizes',
'conj',
'copy',
'cumprod',
'cumsum',
'dask',
'data_descriptor',
'data_type',
'del_dimension',
'dim_0',
'dot',
'dtype',
'energy_loss',
'fft',
'flatten',
'flatten_complex',
'fold',
'from_array',
'get_dimension_by_number',
'get_dimension_slope',
'get_dimensions_by_type',
'get_dimensions_types',
'get_extent',
'get_image_dims',
'get_spectral_dims',
'h5_dataset',
'hdf_close',
'imag',
'itemsize',
'labels',
'like_data',
'map_blocks',
'map_overlap',
'max',
'mean',
'metadata',
'min',
'modality',
'moment',
'name',
'nbytes',
'ndim',
'nonzero',
'npartitions',
'numblocks',
'original_metadata',
'partitions',
'persist',
'plot',
'point_cloud',
'prod',
'provenance',
'quantity',
'ravel',
'real',
'rechunk',
'reduce_dims',
'rename_dimension',
'repeat',
'reshape',
'round',
'set_dimension',
'set_thumbnail',
'shape',
'shuffle',
'size',
'source',
'squeeze',
'std',
'store',
'structures',
'sum',
'swapaxes',
'title',
'to_backend',
'to_dask_dataframe',
'to_delayed',
'to_hdf5',
'to_svg',
'to_tiledb',
'to_zarr',
'topk',
'trace',
'transpose',
'unfold',
'units',
'var',
'variance',
'view',
'view_metadata',
'view_original_metadata',
'vindex',
'visualize']dataset2 = xarray.Dataset( {"spectrum": ([ "energy_scale"], np.array(file_widget.dataset))},
coords={"energy_scale": np.array(file_widget.dataset.energy_loss),}
)
spectrum_smaller = dataset2['spectrum']/100
dataset2.attrs ={'units': 'counts',
'data_type': 'spectrum',
'quantity': 'intensity'}
dataset2.energy_scale.attrs={'units': 'eV',
'dimension_type': 'spectral',
'quantity': 'energy_loss'}
dataset2['energy_scale'].attrs, dataset2.energy_scale.units, list(dataset2.coords.keys()), list(dataset2.keys())
dataset2['spectrum2'] = spectrum_smaller
dataset2import xarray
import datetime
ds1 = xarray.Dataset({"file": file_widget.file_name })
ds1.attrs = file_widget.dataset.metadata
sidpy_tree = xarray.DataTree(name="root", dataset=ds1)
sidpy_tree.attrs = {'relationship': {'main': 'Channel_000'}}
sidpy_tree.children = {"Channel_000": xarray.DataTree(name="spectrum", dataset=dataset2)}
sidpy_tree['Channel_000'] -=sidpy_tree['Channel_000'].min()
#sidpy_tree['Channel_000'].coords = sidpy_tree['Channel_000'].coords['energy_scale']+1000
d = sidpy_tree['Channel_000']/sidpy_tree['Channel_000'].max()
d.name = 'sin'
sidpy_tree['Channel_000']['other'] = np.sin(d['spectrum'].to_dataset())+666
sidpy_tree['Channel_000']['spectrum'].attrs = file_widget.dataset.original_metadata
sidpy_tree['Channel_000'].attrs ={'units': 'counts',
'data_type': 'spectrum',
'quantity': 'intensity',
'provenance': {'sidpy': f"init_{sidpy.__version__}_"+str(datetime.datetime.now()).replace(' ','-')}}
print(sidpy_tree)
sidpy_tree['Channel_000'].to_dataset().attrs<xarray.DataTree 'root'>
Group: /
│ Dimensions: ()
│ Data variables:
│ file <U79 316B 'C:\\Users\\gduscher\\Desktop\\drive-download-20241125...
│ Attributes:
│ relationship: {'main': 'Channel_000'}
└── Group: /Channel_000
│ Dimensions: (energy_scale: 2048)
│ Coordinates:
│ * energy_scale (energy_scale) float64 16kB -6.126 -6.095 ... 56.06 56.1
│ Data variables:
│ spectrum (energy_scale) float64 16kB 3.205e+03 1.926e+03 ... 2.548e+04
│ spectrum2 (energy_scale) float64 16kB 32.05 19.26 3.979 ... 261.9 254.8
│ Attributes:
│ units: counts
│ data_type: spectrum
│ quantity: intensity
│ provenance: {'sidpy': 'init_0.12.3_2024-12-28-17:59:31.459046'}
└── Group: /Channel_000/other
Dimensions: (energy_scale: 2048)
Data variables:
spectrum (energy_scale) float64 16kB 666.0 666.0 666.0 ... 666.0 666.0
{'units': 'counts',
'data_type': 'spectrum',
'quantity': 'intensity',
'provenance': {'sidpy': 'init_0.12.3_2024-12-28-17:59:31.459046'}}import xarray
import pint_xarray
from enum import Enum
class DataType(Enum):
UNKNOWN = -1
SPECTRUM = 1
LINE_PLOT = 2
LINE_PLOT_FAMILY = 3
IMAGE = 4
IMAGE_MAP = 5
IMAGE_STACK = 6 # 3d
SPECTRAL_IMAGE = 7
IMAGE_4D = 8
POINT_CLOUD = 9
class DimensionType(Enum):
"""
Physical type of Dimension object. This information will be used for
visualization and processing purposes.
"""
UNKNOWN = -1
SPATIAL = 1
RECIPROCAL = 2
SPECTRAL = 3
TEMPORAL = 4
CHANNEL = 5
POINT_CLOUD = 6
@xarray.register_dataset_accessor("sidpy")
class SidpyAccessor:
def __init__(self, xarray_obj):
self._obj = xarray_obj
self._unit = None
self._dimensions ={}
self._data_type = ''
self._units = 'counts'
self._quantity ='intensity'
self.provenance = {}
print(list(self._obj.sizes.keys()))
@property
def units(self):
return self._units
@units.setter
def units(self, value):
if isinstance(value, str):
self._units = value
else:
raise ValueError('units needs to be a string')
@property
def quantity(self):
return self._quantity
@quantity.setter
def quantity(self, value):
if isinstance(value, str):
self._quantity = value
else:
raise ValueError('quantity needs to be a string')
@property
def data_type(self):
return self._data_type
@data_type.setter
def data_type(self, value):
if isinstance(value, str):
if value.upper() in DataType._member_names_:
self._data_type = DataType[value.upper()]
else:
self._data_type = DataType.UNKNOWN
raise Warning('Supported data_types for plotting are only: ', DataType._member_names_)
elif isinstance(value, DataType):
self._data_type = value
else:
raise ValueError('data_type needs to be a string')
def plot(self):
"""Plot data on a map."""
return "plotting!"
#print(sidpy_tree), d['spectrum']C:\Users\gduscher\AppData\Local\Temp\ipykernel_31260\4049633596.py:31: AccessorRegistrationWarning: registration of accessor <class '__main__.SidpyAccessor'> under name 'sidpy' for type <class 'xarray.core.dataset.Dataset'> is overriding a preexisting attribute with the same name.
@xarray.register_dataset_accessor("sidpy")
d = sidpy_tree['Channel_000'].to_dataset()/3
dir(d.energy_scale)
['T',
'_HANDLED_TYPES',
'__abs__',
'__add__',
'__and__',
'__annotations__',
'__array__',
'__array_priority__',
'__array_ufunc__',
'__array_wrap__',
'__bool__',
'__class__',
'__complex__',
'__contains__',
'__copy__',
'__dask_graph__',
'__dask_keys__',
'__dask_layers__',
'__dask_optimize__',
'__dask_postcompute__',
'__dask_postpersist__',
'__dask_scheduler__',
'__dask_tokenize__',
'__deepcopy__',
'__delattr__',
'__delitem__',
'__dir__',
'__doc__',
'__enter__',
'__eq__',
'__exit__',
'__float__',
'__floordiv__',
'__format__',
'__ge__',
'__getattr__',
'__getattribute__',
'__getitem__',
'__getstate__',
'__gt__',
'__hash__',
'__iadd__',
'__iand__',
'__ifloordiv__',
'__ilshift__',
'__imod__',
'__imul__',
'__init__',
'__init_subclass__',
'__int__',
'__invert__',
'__ior__',
'__ipow__',
'__irshift__',
'__isub__',
'__iter__',
'__itruediv__',
'__ixor__',
'__le__',
'__len__',
'__lshift__',
'__lt__',
'__matmul__',
'__mod__',
'__module__',
'__mul__',
'__ne__',
'__neg__',
'__new__',
'__or__',
'__pos__',
'__pow__',
'__radd__',
'__rand__',
'__reduce__',
'__reduce_ex__',
'__repr__',
'__rfloordiv__',
'__rmatmul__',
'__rmod__',
'__rmul__',
'__ror__',
'__rpow__',
'__rshift__',
'__rsub__',
'__rtruediv__',
'__rxor__',
'__setattr__',
'__setitem__',
'__sizeof__',
'__slots__',
'__str__',
'__sub__',
'__subclasshook__',
'__truediv__',
'__weakref__',
'__xor__',
'_all_compat',
'_attr_sources',
'_binary_op',
'_cache',
'_calc_assign_results',
'_close',
'_construct_direct',
'_coords',
'_copy',
'_copy_attrs_from',
'_cum_extra_args_docstring',
'_dask_finalize',
'_from_temp_dataset',
'_get_axis_num',
'_getitem_coord',
'_in_memory',
'_indexes',
'_inplace_binary_op',
'_ipython_key_completions_',
'_item_key_to_dict',
'_item_sources',
'_iter',
'_name',
'_overwrite_indexes',
'_reduce_extra_args_docstring',
'_reduce_method',
'_reindex_callback',
'_replace',
'_replace_maybe_drop_dims',
'_repr_html_',
'_resample',
'_setattr_dict',
'_shuffle',
'_title_for_slice',
'_to_dataset_split',
'_to_dataset_whole',
'_to_index',
'_to_temp_dataset',
'_unary_op',
'_variable',
'all',
'any',
'argmax',
'argmin',
'argsort',
'as_numpy',
'assign_attrs',
'assign_coords',
'astype',
'attrs',
'bfill',
'broadcast_equals',
'broadcast_like',
'chunk',
'chunks',
'chunksizes',
'clip',
'close',
'coarsen',
'combine_first',
'compute',
'conj',
'conjugate',
'convert_calendar',
'coords',
'copy',
'count',
'cumprod',
'cumsum',
'cumulative',
'cumulative_integrate',
'curvefit',
'data',
'diff',
'differentiate',
'dims',
'dot',
'drop',
'drop_attrs',
'drop_duplicates',
'drop_encoding',
'drop_indexes',
'drop_isel',
'drop_sel',
'drop_vars',
'dropna',
'dt',
'dtype',
'eV',
'encoding',
'energy_scale',
'equals',
'expand_dims',
'ffill',
'fillna',
'from_dict',
'from_iris',
'from_series',
'get_axis_num',
'get_index',
'groupby',
'groupby_bins',
'head',
'identical',
'idxmax',
'idxmin',
'imag',
'indexes',
'integrate',
'interp',
'interp_calendar',
'interp_like',
'interpolate_na',
'isel',
'isin',
'isnull',
'item',
'load',
'loc',
'map_blocks',
'max',
'mean',
'median',
'min',
'name',
'nbytes',
'ndim',
'notnull',
'pad',
'persist',
'pipe',
'plot',
'polyfit',
'prod',
'quantile',
'query',
'rank',
'real',
'reduce',
'reindex',
'reindex_like',
'rename',
'reorder_levels',
'resample',
'reset_coords',
'reset_encoding',
'reset_index',
'roll',
'rolling',
'rolling_exp',
'round',
'searchsorted',
'sel',
'set_close',
'set_index',
'set_xindex',
'shape',
'shift',
'size',
'sizes',
'sortby',
'squeeze',
'stack',
'std',
'str',
'sum',
'swap_dims',
'tail',
'thin',
'to_dask_dataframe',
'to_dataframe',
'to_dataset',
'to_dict',
'to_index',
'to_iris',
'to_masked_array',
'to_netcdf',
'to_numpy',
'to_pandas',
'to_series',
'to_unstacked_dataset',
'to_zarr',
'transpose',
'unify_chunks',
'unstack',
'values',
'var',
'variable',
'weighted',
'where',
'xindexes']float(d['spectrum'].max())---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
Cell In[268], line 1
----> 1 d.energy_scale.units()
File ~\AppData\Local\anaconda3\Lib\site-packages\xarray\core\common.py:302, in AttrAccessMixin.__getattr__(self, name)
300 with suppress(KeyError):
301 return source[name]
--> 302 raise AttributeError(
303 f"{type(self).__name__!r} object has no attribute {name!r}"
304 )
AttributeError: 'DataArray' object has no attribute 'units'ds2 = sidpy_tree['Channel_000']['other']
ds1.sidpy.units, ds2.sidpy.units# , list(ds2.sizes.keys()),
#ds2.sidpy.units, ds2.sidpy.dimensions={'energy_scale': {'units': 'eV', 'quantity': 'energy_loss', 'dimension_type': 'SPECTRAL'}}['energy_scale']
('counts', 'counts')Load and plot a spectrum¶
import matplotlib.pylab as plt
plt.figure()
sidpy_tree['Channel_000'].to_dataset().plot.scatter(x ='energy_scale', y ='Channel_000')infoWidget.low_loss._update()
# print(infoWidget.datasets['shifted_low_loss'])
print(infoWidget.datasets['Channel_000'])
isinstance(infoWidget.datasets['Channel_000'], sidpy.Dataset)sidpy.Dataset of type SPECTRAL_IMAGE with:
dask.array<array, shape=(25, 10, 2048), dtype=float32, chunksize=(25, 10, 2048), chunktype=numpy.ndarray>
data contains: intensity (counts)
and Dimensions:
x: distance (µm) of size (25,)
y: distance (µm) of size (10,)
energy_loss: energy-loss (eV) of size (2048,)
with metadata: ['experiment', 'annotations']
TrueinfoWidget.added_spectra
{}low_loss = infoWidget.dataset
sl = eels_tools.align_zero_loss(low_loss)
print(sl)sidpy.Dataset of type SPECTRAL_IMAGE with:
dask.array<setitem, shape=(25, 10, 2048), dtype=float32, chunksize=(25, 10, 2048), chunktype=numpy.ndarray>
data contains: intensity (counts)
and Dimensions:
x: distance (µm) of size (25,)
y: distance (µm) of size (10,)
energy_loss: energy-loss (eV) of size (2048,)
with metadata: ['experiment', 'annotations', 'zero_loss']
self = infoWidget.info
spectrum_list = ['None']
reference_list = ['None']
data_list = []
for key in self.parent.datasets.keys():
print(key)
if isinstance(self.parent.datasets[key], sidpy.Dataset):
if key[0] != '_' :
data_list.append(f'{key}: {self.parent.datasets[key].title}')
if 'SPECTR' in self.parent.datasets[key].data_type.name:
spectrum_data = True
spectrum_list.append(f'{key}: {self.parent.datasets[key].title}')
if self.info_key == key:
info_index = len(spectrum_list)-1
reference_list.append(f'{key}: {self.parent.datasets[key].title}')
reference_listChannel_000
_relationship
shifted_low_loss
['None', 'Channel_000: 11-eels']self.parent.datasets['shifted_low_loss']FalseinfoWidget.low_loss.get_drude()infoWidget._update()
resolution_function = infoWidget.low_loss.get_additional_spectrum('zero_loss')
infoWidget.spectrum_plot.add_trace(go.Scatter(x=infoWidget.energy_scale, y=resolution_function))---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Cell In[22], line 3
1 infoWidget._update()
2 resolution_function = infoWidget.low_loss.get_additional_spectrum('zero_loss')
----> 3 infoWidget.spectrum_plot.add_trace(go.Scatter(x=infoWidget.energy_scale, y=resolution_function))
NameError: name 'go' is not definedinfoWidget.energy_scale[:3].values
k = infoWidget.key
infoWidget.datasets['Channel_000'].energy_loss[:3].values
infoWidget.spectrum_plot.data[1].x[1]-infoWidget.spectrum_plot.data[1].x[0]infoWidget.canvas_plot.children = [infoWidget.image_plot]
infoWidget.canvas_plot.childreninfoWidget.image_plot.data[0].x = infoWidget.datasset.image_dims = infoWidget.dataset.get_image_dims(return_axis=True)
if len(infoWidget.image_plot.data) == 0:
infoWidget.image_plot.add_trace(go.Heatmap(z=self.dataset))
else:
infoWidget.image_plot.data[0].z=infoWidget.dataset
infoWidget.image_plot.data[0].x = image_dims[0].values
infoWidget.image_plot.data[0].y = image_dims[1].values
infoWidget.image_plot.update_layout(xaxis_title = f"{image_dims[0].quantity} ({image_dims[0].units})",
yaxis_title = f"{image_dims[0].quantity} ({image_dims[0].units})")
plasmon = eels_tools.fit_plasmon(infoWidget.dataset, 12, 20)
plasmon = np.array(plasmon)plasmon[23,0]array([1.47891069e+01, 5.24804751e+00, 1.59869663e+04])res = eels_tools.get_resolution_functions(infoWidget.dataset, startFitEnergy=-.5, endFitEnergy=.5, n_workers = 8, n_threads=32)
---------------------------------------------------------------------------
KeyboardInterrupt Traceback (most recent call last)
Cell In[126], line 1
----> 1 res = eels_tools.get_resolution_functions(infoWidget.dataset, startFitEnergy=-.5, endFitEnergy=.5, n_workers = 8, n_threads=32)
File c:\Users\gduscher\Documents\Github\pyTEMlib\notebooks\Spectroscopy\../..\pyTEMlib\eels_tools.py:494, in get_resolution_functions(dataset, startFitEnergy, endFitEnergy, n_workers, n_threads)
490 # apply to all spectra
491 zero_loss_fitter = SidFitter(fit_dset, zl_func, num_workers=n_workers, guess_fn=guess_function, threads=n_threads,
492 return_cov=False, return_fit=False, return_std=False, km_guess=False, num_fit_parms=6)
--> 494 [z_loss_params] = zero_loss_fitter.do_fit()
495 z_loss_dset = dataset.copy()
496 z_loss_dset *= 0.0
File c:\Users\gduscher\Documents\Github\pyTEMlib\notebooks\Spectroscopy\../../../sidpy\sidpy\proc\fitter.py:279, in SidFitter.do_fit(self, **kwargs)
273 lazy_result = dask.delayed(SidFitter.default_curve_fit)(self.fit_fn, self.dep_vec,
274 ydata, self.num_fit_parms,
275 return_cov=(self.return_cov or self.return_std),
276 p0=p0, **kwargs)
277 fit_results.append(lazy_result)
--> 279 fit_results_comp = dask.compute(*fit_results)
280 self.client.close()
282 else:
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\dask\base.py:661, in compute(traverse, optimize_graph, scheduler, get, *args, **kwargs)
658 postcomputes.append(x.__dask_postcompute__())
660 with shorten_traceback():
--> 661 results = schedule(dsk, keys, **kwargs)
663 return repack([f(r, *a) for r, (f, a) in zip(results, postcomputes)])
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\threading.py:655, in Event.wait(self, timeout)
653 signaled = self._flag
654 if not signaled:
--> 655 signaled = self._cond.wait(timeout)
656 return signaled
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\threading.py:359, in Condition.wait(self, timeout)
357 else:
358 if timeout > 0:
--> 359 gotit = waiter.acquire(True, timeout)
360 else:
361 gotit = waiter.acquire(False)
KeyboardInterrupt: v = res.plot()par = np.array(res.metadata['zero_loss']['fit_parameter'])
for x in range(par.shape[0]):
for y in range(par.shape[1]):
res[x,y] = eels_tools.zl_func(res.energy_loss, *par[x,y])
res.plot()[ 6.67765731e-02 5.41174565e+03 2.09773567e-01 -5.03759089e-02
4.60116290e+03 1.76471738e-01]
[ 6.40790854e-02 5.42690876e+03 1.95865661e-01 -5.43761627e-02
4.89364258e+03 1.77493041e-01]
[ 6.81077719e-02 6.43605514e+03 1.95012100e-01 -5.30016379e-02
4.43884015e+03 1.66523164e-01]
[ 6.64093078e-02 5.75427504e+03 1.97398452e-01 -5.44820718e-02
4.76615072e+03 1.74423078e-01]
[ 6.60569720e-02 5.51845692e+03 1.96624862e-01 -5.43996081e-02
4.90618330e+03 1.73954089e-01]
[ 6.88292998e-02 5.83932800e+03 2.00135178e-01 -5.42389948e-02
4.77339641e+03 1.73471449e-01]
[ 6.88602553e-02 6.40214431e+03 1.98363423e-01 -5.58406094e-02
4.40044152e+03 1.74087986e-01]
[ 6.85837537e-02 5.50451130e+03 2.04716106e-01 -5.38545064e-02
4.91184340e+03 1.76830016e-01]
[ 6.80843999e-02 5.92034916e+03 1.98310795e-01 -5.36603097e-02
4.72749111e+03 1.71696664e-01]
[ 7.02924129e-02 5.79923590e+03 2.03052815e-01 -6.00875377e-02
4.77021463e+03 1.85617368e-01]
[ 7.59351953e-02 5.74719392e+03 2.17761905e-01 -4.90964002e-02
4.57181160e+03 1.73439777e-01]
[ 7.14214173e-02 6.42868692e+03 2.00225951e-01 -5.61403256e-02
4.45349710e+03 1.73052011e-01]
[ 6.85377605e-02 6.03738747e+03 1.97822842e-01 -5.54147849e-02
4.65419643e+03 1.73201414e-01]
[ 6.73344556e-02 6.21211761e+03 1.93919859e-01 -5.67820114e-02
4.59378752e+03 1.73964356e-01]
[ 8.27238627e-02 6.45369213e+03 2.18628990e-01 -5.20886642e-02
4.36081813e+03 1.73897061e-01]
[ 7.06435960e-02 6.36686440e+03 1.96169775e-01 -5.63710159e-02
4.59170667e+03 1.72175490e-01]
[ 7.27963085e-02 6.55894563e+03 1.97397768e-01 -6.05839363e-02
4.55419840e+03 1.77460246e-01]
[ 6.83713072e-02 6.45395612e+03 1.91981356e-01 -5.61672744e-02
4.57266329e+03 1.69070320e-01]
[ 7.54707228e-02 5.14341506e+03 2.46466476e-01 -4.61403460e-02
4.52140072e+03 1.89674132e-01]
[ 7.26078887e-02 5.75959368e+03 2.12141579e-01 -5.14107506e-02
4.75981161e+03 1.73648064e-01]
[ 6.84163221e-02 5.74088531e+03 2.02574067e-01 -5.28523555e-02
4.65835166e+03 1.73869145e-01]
[ 6.65971194e-02 5.77069798e+03 1.99722139e-01 -5.26893130e-02
4.67800248e+03 1.73498950e-01]
[ 6.72157208e-02 5.92408665e+03 1.96250631e-01 -5.53627606e-02
4.71342603e+03 1.74468412e-01]
[ 6.61735212e-02 6.39596380e+03 1.89017846e-01 -5.70988566e-02
4.53804164e+03 1.71331806e-01]
[ 6.68025761e-02 5.63468078e+03 2.02774223e-01 -5.14165922e-02
4.67414362e+03 1.73111664e-01]
[ 6.75920132e-02 5.96000308e+03 1.96650576e-01 -5.61433858e-02
4.70591085e+03 1.75041706e-01]
[ 7.02985918e-02 6.39022118e+03 1.95886368e-01 -5.66922117e-02
4.62697084e+03 1.71689098e-01]
[ 7.01250351e-02 6.33569920e+03 1.96729667e-01 -5.53759978e-02
4.62154202e+03 1.71107272e-01]
[ 6.64675874e-02 6.50765523e+03 1.89619124e-01 -5.49894099e-02
4.47981522e+03 1.67988504e-01]
[ 7.20129273e-02 6.20841628e+03 2.01333628e-01 -5.59094321e-02
4.64307700e+03 1.74518796e-01]
[ 6.74800030e-02 5.29962324e+03 2.14577044e-01 -5.05834397e-02
4.62101331e+03 1.81137746e-01]
[ 7.27224927e-02 5.74897004e+03 2.07121011e-01 -5.61475091e-02
4.77914010e+03 1.77795688e-01]
[ 7.24757611e-02 5.47407419e+03 2.15253862e-01 -5.27279509e-02
4.82354314e+03 1.78170799e-01]
[ 7.13477161e-02 6.05142285e+03 2.04043003e-01 -5.59095898e-02
4.65357328e+03 1.76093187e-01]
[ 7.11669155e-02 5.86250488e+03 2.06734879e-01 -5.02780506e-02
4.61744850e+03 1.69751817e-01]
[ 6.89522783e-02 6.43281917e+03 1.93392595e-01 -5.57871904e-02
4.55906778e+03 1.69946641e-01]
[ 6.78458237e-02 6.66039151e+03 1.86035878e-01 -5.94598297e-02
4.57993305e+03 1.69507571e-01]
[ 6.77096956e-02 7.65977493e+03 1.85012212e-01 -5.73856381e-02
4.03951871e+03 1.65608309e-01]
[ 7.08814555e-02 6.29021760e+03 1.93424048e-01 -5.98209165e-02
4.77915795e+03 1.73819512e-01]
[ 7.00859517e-02 6.46491991e+03 1.99156446e-01 -5.84047231e-02
4.39119423e+03 1.78070478e-01]
[ 7.06292064e-02 5.45224373e+03 2.06111398e-01 -5.43028818e-02
4.83179853e+03 1.76307660e-01]
[ 6.66900737e-02 5.61556934e+03 2.05230411e-01 -5.27893901e-02
4.62721915e+03 1.77876480e-01]
[ 6.59869342e-02 5.90394411e+03 1.93202868e-01 -5.70168394e-02
4.73142528e+03 1.76152518e-01]
[ 6.91387387e-02 6.35144643e+03 1.91273166e-01 -5.56624168e-02
4.73715428e+03 1.67343119e-01]
[ 6.80138633e-02 5.95256430e+03 1.97297430e-01 -5.46779874e-02
4.57767742e+03 1.74371633e-01]
[ 6.95208941e-02 6.36534146e+03 1.93853224e-01 -5.83178979e-02
4.60897132e+03 1.73425950e-01]
[ 7.10639791e-02 6.52675354e+03 1.88968715e-01 -6.23933620e-02
4.82415039e+03 1.74154100e-01]
[ 6.70775051e-02 6.58511970e+03 1.88528458e-01 -6.01088540e-02
4.53488243e+03 1.74267170e-01]
[ 6.88841398e-02 6.51986233e+03 1.95551279e-01 -5.24628927e-02
4.46755380e+03 1.65445476e-01]
[ 7.14861896e-02 6.34824024e+03 2.05767984e-01 -7.27602007e-02
4.47027447e+03 2.08983426e-01]
[ 6.31795140e-02 5.03591942e+03 2.15235425e-01 -4.14925263e-02
4.52960478e+03 1.68592966e-01]
[ 6.60352936e-02 6.31494875e+03 1.89088966e-01 -5.32457308e-02
4.58802770e+03 1.65065264e-01]
[ 6.42608035e-02 6.10639452e+03 1.89587536e-01 -5.68037580e-02
4.57404674e+03 1.74820643e-01]
[ 6.92104636e-02 6.30186903e+03 1.95462970e-01 -5.39385588e-02
4.65726679e+03 1.67603141e-01]
[ 6.50354362e-02 5.32711943e+03 2.00461484e-01 -4.91218660e-02
4.83580371e+03 1.69841823e-01]
[ 6.75996801e-02 6.73229473e+03 1.86198089e-01 -5.78660506e-02
4.49850057e+03 1.67791499e-01]
[ 6.92084031e-02 6.96171782e+03 1.91248786e-01 -5.98826811e-02
4.29425083e+03 1.73932510e-01]
[ 6.96971358e-02 6.60540073e+03 1.91578024e-01 -5.86298381e-02
4.58449766e+03 1.71411968e-01]
[ 6.86357387e-02 6.53037773e+03 1.91083964e-01 -6.12751690e-02
4.54670096e+03 1.77990299e-01]
[ 6.83529589e-02 6.59229735e+03 1.89658160e-01 -5.87710899e-02
4.51745911e+03 1.71573881e-01]
[ 6.56597711e-02 6.72338626e+03 2.13806439e-01 -5.12216491e-02
3.48499282e+03 1.84807458e-01]
[ 6.80277351e-02 5.68966745e+03 2.05202690e-01 -5.31191750e-02
4.66281465e+03 1.76631524e-01]
[ 6.84217628e-02 5.79936250e+03 1.99967681e-01 -5.52690833e-02
4.77039134e+03 1.75172229e-01]
[ 6.76028138e-02 6.29915361e+03 1.92530377e-01 -6.03973213e-02
4.57550991e+03 1.79229410e-01]
[ 7.20094249e-02 5.61740804e+03 2.14095182e-01 -5.06940557e-02
4.58834471e+03 1.75331664e-01]
[ 6.94449612e-02 6.39884907e+03 1.91863973e-01 -5.70096192e-02
4.66530775e+03 1.69183065e-01]
[ 7.09248504e-02 7.29814268e+03 1.92846034e-01 -5.61491044e-02
4.18273987e+03 1.66975209e-01]
[ 7.43447951e-02 6.60909639e+03 1.93300752e-01 -5.77601124e-02
4.80292336e+03 1.67211477e-01]
[ 7.05282100e-02 6.53691790e+03 1.93562228e-01 -5.82143791e-02
4.57393247e+03 1.72673537e-01]
[ 8.25789922e-02 6.30894009e+03 2.29480756e-01 -6.23772840e-02
4.23125106e+03 1.97468337e-01]
[ 6.32390986e-02 5.06000088e+03 2.12677506e-01 -4.79246953e-02
4.55152127e+03 1.79429283e-01]
[ 6.51738468e-02 5.71673788e+03 1.94048771e-01 -5.39475817e-02
4.79827988e+03 1.71996033e-01]
[ 6.55109194e-02 6.21843454e+03 1.90642582e-01 -5.47139370e-02
4.58067988e+03 1.69382855e-01]
[ 6.80000319e-02 6.24224700e+03 1.93276102e-01 -5.57100175e-02
4.66467575e+03 1.70246915e-01]
[ 6.57226363e-02 5.01419126e+03 2.07819894e-01 -4.85739443e-02
4.94116582e+03 1.75159255e-01]
[ 6.78396195e-02 6.49612236e+03 1.92766765e-01 -5.45112093e-02
4.42881874e+03 1.68770081e-01]
[ 6.64915838e-02 5.92511373e+03 1.95473419e-01 -5.57630891e-02
4.70833920e+03 1.74733843e-01]
[ 6.86710925e-02 6.19695308e+03 1.97112715e-01 -5.80219344e-02
4.58496818e+03 1.77470099e-01]
[ 7.08991686e-02 6.39035517e+03 1.97741171e-01 -5.18675102e-02
4.63026135e+03 1.63492213e-01]
[ 6.86272148e-02 6.46193185e+03 1.92124356e-01 -5.82374004e-02
4.56020509e+03 1.72446721e-01]
[ 6.78998063e-02 4.89204770e+03 2.16082417e-01 -4.75957982e-02
4.83052207e+03 1.75833386e-01]
[ 7.01922405e-02 5.27529076e+03 2.15842068e-01 -5.43489574e-02
4.80221548e+03 1.86184512e-01]
[ 6.64744717e-02 6.29877626e+03 1.90595524e-01 -5.30355517e-02
4.59797516e+03 1.65609424e-01]
[ 6.99276461e-02 6.45931035e+03 1.97886406e-01 -5.43755757e-02
4.48848089e+03 1.70889444e-01]
[ 6.55687331e-02 5.67936200e+03 1.99380843e-01 -5.17950887e-02
4.62759387e+03 1.73851117e-01]
[ 6.89090131e-02 6.14081850e+03 1.96096680e-01 -5.40550106e-02
4.66357031e+03 1.70113432e-01]
[ 6.69297954e-02 6.57658519e+03 1.90944986e-01 -5.38256692e-02
4.42688845e+03 1.66509149e-01]
[ 6.66268592e-02 6.31840662e+03 1.87051056e-01 -5.84196199e-02
4.69854536e+03 1.70462983e-01]
[ 7.47530644e-02 6.27922702e+03 2.01292856e-01 -5.42117481e-02
4.76818877e+03 1.67721298e-01]
[ 6.84607158e-02 6.40459415e+03 1.92971552e-01 -5.79513074e-02
4.54229507e+03 1.73455914e-01]
[ 7.17223275e-02 5.36405420e+03 2.10619511e-01 -4.89687329e-02
4.80799346e+03 1.71095951e-01]
[ 6.76977723e-02 5.90746635e+03 1.99101075e-01 -5.56079203e-02
4.61296756e+03 1.76926346e-01]
[ 6.87809824e-02 5.72490285e+03 2.07654495e-01 -5.22544563e-02
4.62702725e+03 1.76133143e-01]
[ 7.79338022e-02 6.48734588e+03 2.11468730e-01 -5.60960346e-02
4.45464145e+03 1.75566909e-01]
[ 7.06625489e-02 5.56789041e+03 2.11385822e-01 -5.66078037e-02
4.66994967e+03 1.85700012e-01]
[ 6.91130402e-02 6.41656955e+03 1.96850681e-01 -5.38908610e-02
4.40773596e+03 1.70279793e-01]
[ 6.93167571e-02 6.41923786e+03 1.92106299e-01 -5.40455498e-02
4.67197829e+03 1.64943038e-01]
[ 7.07843774e-02 5.55536400e+03 2.11061150e-01 -5.11208147e-02
4.84067587e+03 1.74990352e-01]
[ 7.08848699e-02 6.57380932e+03 1.93528991e-01 -5.59929478e-02
4.59753651e+03 1.68176176e-01]
[ 7.13016014e-02 6.48794929e+03 1.98010186e-01 -5.49411053e-02
4.52365795e+03 1.70221475e-01]
[ 6.27014069e-02 5.17842533e+03 2.05006886e-01 -4.73110009e-02
4.59578530e+03 1.74372819e-01]
[ 6.73982752e-02 5.67044122e+03 2.03216853e-01 -5.06371497e-02
4.67903858e+03 1.71839377e-01]
[ 6.70349677e-02 5.57544983e+03 1.97797825e-01 -5.28015300e-02
4.90824392e+03 1.70465891e-01]
[ 6.81203598e-02 6.27449519e+03 1.94066179e-01 -5.86671225e-02
4.58735550e+03 1.76629163e-01]
[ 6.59545689e-02 5.73724612e+03 1.97352379e-01 -5.28783111e-02
4.67133288e+03 1.73404634e-01]
[ 6.71547954e-02 6.16934729e+03 1.94733413e-01 -5.31929494e-02
4.55130998e+03 1.69355340e-01]
[ 6.67107463e-02 6.09176988e+03 1.95985492e-01 -5.80258144e-02
4.54992960e+03 1.80027858e-01]
[ 6.73604032e-02 6.58259479e+03 1.88698182e-01 -5.85105419e-02
4.52571487e+03 1.72580554e-01]
[ 6.76337672e-02 6.42798340e+03 1.93795482e-01 -5.65714103e-02
4.48504945e+03 1.73023023e-01]
[ 6.90159261e-02 6.19971314e+03 1.95751436e-01 -5.72228751e-02
4.64867180e+03 1.73935019e-01]
[ 6.11260057e-02 5.03790196e+03 2.10117310e-01 -4.78493504e-02
4.44645655e+03 1.81628158e-01]
[ 7.20556550e-02 5.84883033e+03 2.05448253e-01 -5.28697895e-02
4.74810241e+03 1.72325825e-01]
[ 6.80240422e-02 5.55279625e+03 2.00849745e-01 -5.35456231e-02
4.90445582e+03 1.73284814e-01]
[ 8.10165938e-02 6.58239532e+03 2.04273852e-01 -5.86714548e-02
4.73023329e+03 1.72293689e-01]
[ 6.65355024e-02 5.44612759e+03 2.00811666e-01 -5.40579073e-02
4.84224109e+03 1.76645521e-01]
[ 6.61856796e-02 5.77868818e+03 1.99118755e-01 -5.54895594e-02
4.60498635e+03 1.78634638e-01]
[ 6.74058208e-02 5.86137900e+03 1.97201759e-01 -5.39572088e-02
4.74636661e+03 1.72346774e-01]
[ 6.94703568e-02 6.35049410e+03 1.92580373e-01 -5.66825202e-02
4.69140747e+03 1.70134815e-01]
[ 8.15472549e-02 6.34854818e+03 2.12531020e-01 -5.27694902e-02
4.65287533e+03 1.70627424e-01]
[ 7.46136511e-02 6.82465737e+03 1.90570139e-01 -6.03374050e-02
4.72468444e+03 1.68069340e-01]
[ 6.53272321e-02 5.16694716e+03 2.10648394e-01 -4.90759325e-02
4.62495967e+03 1.78173080e-01]
[ 6.79889053e-02 6.38247456e+03 1.95226881e-01 -5.43182214e-02
4.40621026e+03 1.69812726e-01]
[ 6.50445797e-02 5.61658383e+03 1.94379479e-01 -5.36735848e-02
4.86006709e+03 1.72729522e-01]
[ 6.71643426e-02 6.42490089e+03 1.94435757e-01 -5.48060319e-02
4.41511527e+03 1.70962194e-01]
[ 6.31431945e-02 5.60830993e+03 1.96704696e-01 -5.75166938e-02
4.57390264e+03 1.86122788e-01]
[ 6.76300110e-02 6.15856915e+03 1.95231679e-01 -5.40067021e-02
4.54184671e+03 1.69976297e-01]
[ 6.64897258e-02 6.11973959e+03 1.94456895e-01 -5.43714714e-02
4.55228522e+03 1.72091972e-01]
[ 6.95622449e-02 6.46002871e+03 1.94144541e-01 -5.64840785e-02
4.56641792e+03 1.71459880e-01]
[ 6.94738033e-02 6.51712724e+03 1.97886008e-01 -5.44272730e-02
4.42857799e+03 1.70170819e-01]
[ 7.01329142e-02 7.59547715e+03 1.88916268e-01 -5.67432762e-02
4.07225678e+03 1.65467238e-01]
[ 6.28544802e-02 5.11423596e+03 2.11274573e-01 -4.76060663e-02
4.51359601e+03 1.78450365e-01]
[ 6.83760842e-02 6.16108913e+03 1.93446827e-01 -5.57890554e-02
4.64467132e+03 1.70478710e-01]
[ 6.76158663e-02 5.45259476e+03 2.03040659e-01 -5.17696640e-02
4.91496688e+03 1.74171798e-01]
[ 6.87041929e-02 6.33520545e+03 1.93229588e-01 -5.63715315e-02
4.60760648e+03 1.70245785e-01]
[ 6.66804631e-02 6.16902317e+03 1.90716518e-01 -5.36180876e-02
4.63522272e+03 1.67034305e-01]
[ 6.66141288e-02 5.82859637e+03 1.94699437e-01 -5.46926679e-02
4.74420389e+03 1.72349028e-01]
[ 6.65690177e-02 6.50733437e+03 1.90060718e-01 -5.31312824e-02
4.46417549e+03 1.64691276e-01]
[ 6.55180227e-02 6.14829766e+03 1.93121294e-01 -5.82297849e-02
4.53921177e+03 1.79129502e-01]
[ 6.75438601e-02 6.42918262e+03 1.91808158e-01 -5.80760389e-02
4.51043067e+03 1.73936347e-01]
[ 6.74908455e-02 6.42142224e+03 1.88072603e-01 -5.53410302e-02
4.69270794e+03 1.65198669e-01]
[ 6.80929777e-02 5.45626075e+03 2.09482454e-01 -5.06805281e-02
4.60308516e+03 1.76125004e-01]
[ 6.81188753e-02 6.43714652e+03 1.90305092e-01 -5.73847572e-02
4.54559465e+03 1.70019205e-01]
[ 6.71106150e-02 6.13447570e+03 1.97086511e-01 -5.39414469e-02
4.52107146e+03 1.73192084e-01]
[ 6.74073795e-02 6.49384780e+03 1.88422731e-01 -5.65396816e-02
4.57078656e+03 1.68596679e-01]
[ 6.94192984e-02 5.35955926e+03 2.07827281e-01 -5.30397794e-02
4.89703719e+03 1.76656121e-01]
[ 6.71502545e-02 5.50393733e+03 1.99010505e-01 -5.42068652e-02
4.89735959e+03 1.74314024e-01]
[ 7.49144256e-02 6.26974006e+03 2.05093769e-01 -5.66842548e-02
4.61391252e+03 1.73505978e-01]
[ 6.98343024e-02 7.32924501e+03 1.89115470e-01 -6.00473027e-02
4.19109071e+03 1.72357228e-01]
[ 6.97690218e-02 6.13072289e+03 2.00207977e-01 -5.26772243e-02
4.64898751e+03 1.69426425e-01]
[ 7.01525135e-02 6.22626538e+03 1.99882500e-01 -5.75795649e-02
4.58005615e+03 1.77023149e-01]
[ 6.19899657e-02 4.85264185e+03 2.11021667e-01 -4.69958803e-02
4.77824688e+03 1.77863253e-01]
[ 6.86590087e-02 6.37627768e+03 1.91215532e-01 -5.48850355e-02
4.61975279e+03 1.66499832e-01]
[ 6.52153891e-02 5.75789724e+03 1.98562094e-01 -5.26411737e-02
4.62434467e+03 1.73561140e-01]
[ 6.74287363e-02 6.13339108e+03 1.95218492e-01 -5.35038197e-02
4.62721321e+03 1.69293487e-01]
[ 6.39138747e-02 5.64989327e+03 1.96275279e-01 -5.30286310e-02
4.59768205e+03 1.74528394e-01]
[ 6.53077693e-02 5.29264697e+03 2.01109433e-01 -5.26551896e-02
4.88204664e+03 1.75986527e-01]
[ 6.53010879e-02 5.35664902e+03 2.01456338e-01 -4.98447412e-02
4.86056411e+03 1.71980210e-01]
[ 6.79404452e-02 6.36423230e+03 1.91247784e-01 -5.86077456e-02
4.59817230e+03 1.74203105e-01]
[ 6.79406667e-02 6.40805525e+03 1.91851849e-01 -5.92671981e-02
4.53844810e+03 1.75730582e-01]
[ 6.73612735e-02 6.45286935e+03 1.91866892e-01 -5.70179432e-02
4.49131470e+03 1.72294985e-01]
[ 6.61441711e-02 4.85905951e+03 2.28286418e-01 -4.36170112e-02
4.56674631e+03 1.77620859e-01]
[ 7.24758855e-02 6.09388747e+03 2.04099016e-01 -5.27858366e-02
4.63089642e+03 1.69371805e-01]
[ 6.74634649e-02 6.02150366e+03 1.97912395e-01 -5.65196222e-02
4.57579422e+03 1.77954654e-01]
[ 6.86130645e-02 6.14041550e+03 1.98450708e-01 -5.52042885e-02
4.54729239e+03 1.73519304e-01]
[ 6.35926179e-02 5.25977151e+03 1.98134243e-01 -5.27086343e-02
4.82834735e+03 1.76642214e-01]
[ 6.62231617e-02 5.47749497e+03 2.05854359e-01 -4.81054728e-02
4.63302653e+03 1.71274231e-01]
[ 8.22183259e-02 7.87340712e+03 2.05107260e-01 -8.40056334e-02
3.91037092e+03 2.04703333e-01]
[ 6.69693430e-02 6.47741689e+03 1.92450068e-01 -5.65659622e-02
4.42157293e+03 1.72571151e-01]
[ 7.05177955e-02 5.82191747e+03 2.09248162e-01 -5.30113303e-02
4.61527477e+03 1.76700577e-01]
[ 6.76118983e-02 5.90203662e+03 1.96803939e-01 -5.51106652e-02
4.74988644e+03 1.73322632e-01]
[ 6.85513580e-02 5.31421910e+03 2.11600928e-01 -4.87395212e-02
4.62126826e+03 1.73918710e-01]
[ 6.56663074e-02 5.49051165e+03 1.98620726e-01 -5.46820679e-02
4.85211700e+03 1.78341831e-01]
[ 6.43771357e-02 5.74930459e+03 1.95127944e-01 -5.44050822e-02
4.65689042e+03 1.75365196e-01]
[ 7.07325484e-02 6.09006018e+03 2.00416848e-01 -5.60656392e-02
4.60514375e+03 1.75895878e-01]
[ 6.40547578e-02 4.89651411e+03 2.48470427e-01 -3.78183554e-02
3.95148159e+03 1.82806597e-01]
[ 6.09633995e-02 5.46680828e+03 2.24012892e-01 -4.55267772e-02
3.63543248e+03 1.87990107e-01]
[ 6.12890916e-02 4.56931340e+03 2.43971646e-01 -3.98568814e-02
4.03057631e+03 1.90589131e-01]
[ 6.75625687e-02 6.13723646e+03 1.95500986e-01 -5.22638487e-02
4.63590281e+03 1.67279720e-01]
[ 6.83062899e-02 6.12033209e+03 1.98988299e-01 -5.29302173e-02
4.56225929e+03 1.71493911e-01]
[ 6.55227079e-02 5.51720065e+03 1.96396557e-01 -5.41821392e-02
4.89548729e+03 1.74217393e-01]
[ 4.88824715e-02 4.83315064e+03 2.64339072e-01 -2.55110431e-02
3.13707942e+03 1.81756048e-01]
[ 5.92862593e-02 4.72494292e+03 2.19116446e-01 -4.35271827e-02
4.49063169e+03 1.81162528e-01]
[ 6.17100482e-02 4.97236100e+03 2.03161156e-01 -4.88621338e-02
4.85531887e+03 1.77433206e-01]
[ 5.98215850e-02 4.65051311e+03 2.17183250e-01 -4.38209774e-02
4.47647883e+03 1.82991891e-01]
[ 5.49587036e-02 4.47613700e+03 2.30744946e-01 -4.95239633e-02
3.13500910e+03 2.22445533e-01]
[ 4.20987252e-02 4.29382959e+03 2.81026597e-01 -1.93471244e-02
2.99393762e+03 1.78348657e-01]
[ 3.90424080e-02 4.25366418e+03 2.67481428e-01 -2.07010865e-02
2.94343252e+03 1.86559981e-01]
[ 5.74270473e-02 7.05727875e+03 2.30905585e-01 -4.05108417e-02
2.77499906e+03 1.87113693e-01]
[ 5.84887142e-02 4.77696522e+03 2.14308458e-01 -4.50424840e-02
4.49952360e+03 1.83415871e-01]
[ 5.55715272e-02 5.50325315e+03 2.33980265e-01 -3.85144127e-02
3.44093357e+03 1.86520272e-01]
[ 5.14990110e-02 4.11012086e+03 2.74435120e-01 -2.67742537e-02
3.00782867e+03 1.82437678e-01]
[ 3.24334266e-02 4.20278181e+03 2.48921173e-01 -2.58516054e-02
2.94980079e+03 2.18195050e-01]
[ 5.71802177e-02 4.72588092e+03 2.61743208e-01 -3.11795978e-02
3.29165616e+03 1.83769594e-01]
[ 5.90765245e-02 4.41030671e+03 2.63004403e-01 -3.27722477e-02
3.16890455e+03 1.82007473e-01]
[ 4.76327422e-02 3.99944060e+03 2.63830337e-01 -2.87103909e-02
2.81037994e+03 1.94376835e-01]
[ 6.16864615e-02 4.51623205e+03 2.21969952e-01 -6.28028230e-02
2.73008069e+03 2.26930146e-01]
[ 4.49690066e-02 3.81839382e+03 2.35711508e-01 -3.79473148e-02
2.83568686e+03 2.16960162e-01]
[ 4.03109414e-02 4.27408779e+03 2.75600359e-01 -2.10619694e-02
3.09461302e+03 1.84098150e-01]
[ 5.14757616e-02 4.38815517e+03 2.75048532e-01 -2.76837676e-02
3.10337777e+03 1.93570909e-01]
[ 7.27693365e-02 4.46137850e+03 3.39187024e-01 -2.00739231e-02
3.22146353e+03 1.63356101e-01]
[ 3.83970218e-02 3.75299198e+03 3.12718548e-01 -1.50738247e-02
2.65955143e+03 1.72866744e-01]
[ 6.86584714e-02 4.32916750e+03 2.59770632e-01 -3.37763147e-02
2.99669432e+03 1.74279223e-01]
[ 3.95956419e-02 4.07825052e+03 3.01203457e-01 -1.46396752e-02
2.90948230e+03 1.73131334e-01]
[ 3.85228684e-02 3.85794041e+03 3.01348827e-01 -1.61295841e-02
2.71396269e+03 1.76119786e-01]
[ 4.36078883e-02 3.67791404e+03 2.74391917e-01 -2.26160638e-02
2.69197645e+03 1.87572265e-01]
[ 7.95807487e-02 5.40535962e+03 1.72836124e-01 -1.09466775e-01
3.95350462e+03 2.00339957e-01]
[ 5.66891787e-02 3.72808615e+03 2.89832322e-01 -2.30327415e-02
2.63640291e+03 1.72020047e-01]
[ 3.55672519e-02 3.89121366e+03 3.01079871e-01 -1.52257076e-02
2.73044738e+03 1.76185718e-01]
[ 4.53117932e-02 4.05187149e+03 2.63650930e-01 -2.60322091e-02
2.88795083e+03 1.93420845e-01]
[ 4.06603892e-02 4.00824070e+03 3.07914620e-01 -1.43323409e-02
2.77089529e+03 1.72587035e-01]
[ 4.03202286e-02 3.54267278e+03 3.09620960e-01 -1.43560164e-02
2.58344585e+03 1.68750165e-01]
[ 3.92918122e-02 3.59861500e+03 3.10063435e-01 -1.52342711e-02
2.56365671e+03 1.83856587e-01]
[ 4.37984627e-02 3.75198308e+03 3.05861909e-01 -1.67356207e-02
2.71200773e+03 1.73817829e-01]
[ 4.84826089e-02 3.65153535e+03 2.82056052e-01 -2.24691509e-02
2.69440414e+03 1.82904807e-01]
[ 4.28457012e-02 3.87994709e+03 3.21233905e-01 -1.44219909e-02
2.27909731e+03 1.68457580e-01]
[ 4.98419477e-02 4.29916870e+03 1.79458608e-01 -1.05671680e-01
2.75913458e+03 2.76775599e-01]
[ 4.46354604e-02 3.37743979e+03 2.99396748e-01 -1.74288331e-02
2.45681810e+03 1.75743450e-01]
[ 3.93076640e-02 3.74276228e+03 3.02026924e-01 -1.46634165e-02
2.58756591e+03 1.72687605e-01]
[ 3.00156411e-02 3.58030535e+03 3.04777681e-01 -1.31494244e-02
2.56782746e+03 1.84212403e-01]
[ 6.32018219e-02 3.94382634e+03 2.92590178e-01 -2.84021785e-02
2.63819756e+03 1.80245025e-01]
[ 3.07268435e-02 3.24439911e+03 2.63085667e-01 -2.11473313e-02
2.32456439e+03 2.19561621e-01]
[ 5.11327364e-02 3.55390444e+03 3.19130249e-01 -1.87187913e-02
2.52237515e+03 1.71798319e-01]
[ 6.77751167e-02 3.56056107e+03 3.53856816e-01 -1.91533829e-02
2.57155792e+03 1.71395988e-01]
[ 5.52526376e-02 3.64563896e+03 2.98365541e-01 -2.42463899e-02
2.43722142e+03 1.76070527e-01]
[ 4.57592532e-02 3.54536981e+03 3.12010978e-01 -1.60119634e-02
2.32854784e+03 1.71442057e-01]
[ 6.43110531e-02 2.93899212e+03 2.94213237e-01 -5.42155618e-02
2.32244961e+03 2.69907579e-01]
[ 5.44617515e-02 3.16940164e+03 3.36870336e-01 -1.74343073e-02
2.28088419e+03 1.77666041e-01]
[ 4.55986290e-02 3.47910343e+03 3.13202054e-01 -1.53647777e-02
2.57120776e+03 1.67613896e-01]
[ 3.67587385e-02 3.42044590e+03 2.85187955e-01 -1.72873675e-02
2.49793470e+03 1.86155001e-01]
[ 3.90702694e-02 3.53052537e+03 3.09183388e-01 -1.46606205e-02
2.55466776e+03 1.72702961e-01]
[ 4.50571864e-02 3.41016115e+03 2.43402682e-01 -3.82871149e-02
2.19648816e+03 2.27337248e-01]
[ 4.79847411e-02 3.41023974e+03 3.06232851e-01 -1.77373947e-02
2.41478429e+03 1.70954724e-01]
[ 4.52086427e-02 3.44615883e+03 3.03251203e-01 -1.78517391e-02
2.43072865e+03 1.76794409e-01]
[ 3.51354713e-02 2.78554318e+03 2.78406497e-01 -1.89318610e-02
2.62260020e+03 1.93884693e-01]
[ 3.82350396e-02 3.17640304e+03 2.99484342e-01 -1.69094930e-02
2.26036559e+03 1.85150782e-01]
[ 3.06479200e-02 3.00845451e+03 3.24654219e-01 -1.13989899e-02
2.14646170e+03 1.77060504e-01]
[ 3.79865815e-02 3.15553278e+03 3.11347933e-01 -1.37329887e-02
2.17381820e+03 1.72145281e-01]
[ 4.46953922e-02 3.24805484e+03 3.24756688e-01 -1.45324786e-02
2.41856387e+03 1.68319156e-01]
[ 4.50063965e-02 3.35501979e+03 3.34790260e-01 -1.32011608e-02
2.34751635e+03 1.66246685e-01]
[ 3.47932607e-02 4.45450743e+03 3.46158776e-01 -1.06126082e-02
1.77494707e+03 1.63269847e-01]
[ 2.55044790e-02 2.93668730e+03 2.25557341e-01 -3.14044318e-02
2.05050509e+03 2.72177204e-01]
[ 2.86772092e-02 3.03888295e+03 2.96854827e-01 -1.45988483e-02
2.18803281e+03 1.95085785e-01]
[ 3.76314819e-02 3.43679108e+03 3.17737809e-01 -1.43514005e-02
2.13356286e+03 1.74398180e-01]
[ 4.29946839e-02 3.12196742e+03 3.33303874e-01 -1.35932901e-02
2.19135652e+03 1.69216099e-01]
[ 3.26110417e-02 3.01765104e+03 3.08710978e-01 -1.25171647e-02
2.15605348e+03 1.77918117e-01]
[ 4.51750926e-02 3.05198245e+03 2.21625896e-01 -5.99106299e-02
2.14073505e+03 2.69450412e-01]
[ 5.30518913e-02 2.98215835e+03 3.44273320e-01 -1.68104993e-02
2.15105332e+03 1.67860039e-01]
[ 4.19531029e-02 3.14733518e+03 3.04366475e-01 -1.68133893e-02
2.26088556e+03 1.77759014e-01]
[ 4.22684508e-02 3.12034457e+03 3.09989691e-01 -1.63226674e-02
2.23443181e+03 1.81891089e-01]
[ 4.36801118e-02 3.22171803e+03 3.35819649e-01 -1.51221867e-02
2.27832662e+03 1.67573166e-01]

for dset in infoWidget.datasets.values():
if isinstance(dset, sidpy.Dataset):
if 'Measurement' in dset.title:
dset.title = dset.title.split('/')[-1]
print(dset.title)
infoWidget.low_loss.get_drude()print(infoWidget.datasets.keys())
dat ={ 'Channel_000': infoWidget.datasets['Channel_000'],
'_relationship': infoWidget.datasets['_relationship'],
'plasmon': infoWidget.datasets['plasmon']}dict_keys(['Channel_000', '_relationship', 'shifted_low_loss', 'zero_loss', 'plasmon', 'low_loss_model'])
infoWidget.datasets['plasmon'].metadata['zero_loss'].keys()dict_keys(['shifted', 'parameter', 'startFitEnergy', 'endFitEnergy', 'fit_parameter', 'original_low_loss', (0, 0), (20, 6), '0,0', '0,1', '0,2', '0,3', '0,4', '0,5', '0,6', '0,7', '0,8', '0,9', '1,0', '1,1', '1,2', '1,3', '1,4', '1,5', '1,6', '1,7', '1,8', '1,9', '2,0', '2,1', '2,2', '2,3', '2,4', '2,5', '2,6', '2,7', '2,8', '2,9', '3,0', '3,1', '3,2', '3,3', '3,4', '3,5', '3,6', '3,7', '3,8', '3,9', '4,0', '4,1', '4,2', '4,3', '4,4', '4,5', '4,6', '4,7', '4,8', '4,9', '5,0', '5,1', '5,2', '5,3', '5,4', '5,5', '5,6', '5,7', '5,8', '5,9', '6,0', '6,1', '6,2', '6,3', '6,4', '6,5', '6,6', '6,7', '6,8', '6,9', '7,0', '7,1', '7,2', '7,3', '7,4', '7,5', '7,6', '7,7', '7,8', '7,9', '8,0', '8,1', '8,2', '8,3', '8,4', '8,5', '8,6', '8,7', '8,8', '8,9', '9,0', '9,1', '9,2', '9,3', '9,4', '9,5', '9,6', '9,7', '9,8', '9,9', '10,0', '10,1', '10,2', '10,3', '10,4', '10,5', '10,6', '10,7', '10,8', '10,9', '11,0', '11,1', '11,2', '11,3', '11,4', '11,5', '11,6', '11,7', '11,8', '11,9', '12,0', '12,1', '12,2', '12,3', '12,4', '12,5', '12,6', '12,7', '12,8', '12,9', '13,0', '13,1', '13,2', '13,3', '13,4', '13,5', '13,6', '13,7', '13,8', '13,9', '14,0', '14,1', '14,2', '14,3', '14,4', '14,5', '14,6', '14,7', '14,8', '14,9', '15,0', '15,1', '15,2', '15,3', '15,4', '15,5', '15,6', '15,7', '15,8', '15,9', '16,0', '16,1', '16,2', '16,3', '16,4', '16,5', '16,6', '16,7', '16,8', '16,9', '17,0', '17,1', '17,2', '17,3', '17,4', '17,5', '17,6', '17,7', '17,8', '17,9', '18,0', '18,1', '18,2', '18,3', '18,4', '18,5', '18,6', '18,7', '18,8', '18,9', '19,0', '19,1', '19,2', '19,3', '19,4', '19,5', '19,6', '19,7', '19,8', '19,9', '20,0', '20,1', '20,2', '20,3', '20,4', '20,5', '20,6', '20,7', '20,8', '20,9', '21,0', '21,1', '21,2', '21,3', '21,4', '21,5', '21,6', '21,7', '21,8', '21,9', '22,0', '22,1', '22,2', '22,3', '22,4', '22,5', '22,6', '22,7', '22,8', '22,9', '23,0', '23,1', '23,2', '23,3', '23,4', '23,5', '23,6', '23,7', '23,8', '23,9', '24,0', '24,1', '24,2', '24,3', '24,4', '24,5', '24,6', '24,7', '24,8', '24,9'])g =pyTEMlib.file_tools.save_dataset(infoWidget.datasets, '11_si.hf5')
Cannot overwrite file. Using: 11_si-1.hf5
c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\pyNSID\io\hdf_io.py:111: UserWarning: main_data_name should not contain the "-" character. Reformatted name from:11-eels to 11_eels
warn('main_data_name should not contain the "-" character. Reformatted'
c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\pyNSID\io\hdf_utils.py:381: FutureWarning: validate_h5_dimension may be removed in a future version
warn('validate_h5_dimension may be removed in a future version',
c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\pyNSID\io\hdf_io.py:111: UserWarning: main_data_name should not contain the "-" character. Reformatted name from:11-eels_new to 11_eels_new
warn('main_data_name should not contain the "-" character. Reformatted'
c:\Users\gduscher\Documents\Github\pyTEMlib\notebooks\Spectroscopy\../../../sidpy\sidpy\hdf\hdf_utils.py:387: UserWarning: Converted key: (0, 0) from type: <class 'tuple'> to str
warn('Converted key: {} from type: {} to str'
c:\Users\gduscher\Documents\Github\pyTEMlib\notebooks\Spectroscopy\../../../sidpy\sidpy\hdf\hdf_utils.py:387: UserWarning: Converted key: (19, 2) from type: <class 'tuple'> to str
warn('Converted key: {} from type: {} to str'
c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\pyNSID\io\hdf_utils.py:381: FutureWarning: validate_h5_dimension may be removed in a future version
warn('validate_h5_dimension may be removed in a future version',
c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\pyNSID\io\hdf_io.py:111: UserWarning: main_data_name should not contain the "-" character. Reformatted name from:11-eels_new_new to 11_eels_new_new
warn('main_data_name should not contain the "-" character. Reformatted'
c:\Users\gduscher\Documents\Github\pyTEMlib\notebooks\Spectroscopy\../../../sidpy\sidpy\hdf\hdf_utils.py:387: UserWarning: Converted key: (19, 2) from type: <class 'tuple'> to str
warn('Converted key: {} from type: {} to str'
c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\pyNSID\io\hdf_utils.py:381: FutureWarning: validate_h5_dimension may be removed in a future version
warn('validate_h5_dimension may be removed in a future version',
c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\pyNSID\io\hdf_io.py:111: UserWarning: main_data_name should not contain the "-" character. Reformatted name from:11-eels_new_new to 11_eels_new_new
warn('main_data_name should not contain the "-" character. Reformatted'
c:\Users\gduscher\Documents\Github\pyTEMlib\notebooks\Spectroscopy\../../../sidpy\sidpy\hdf\hdf_utils.py:387: UserWarning: Converted key: (0, 0) from type: <class 'tuple'> to str
warn('Converted key: {} from type: {} to str'
c:\Users\gduscher\Documents\Github\pyTEMlib\notebooks\Spectroscopy\../../../sidpy\sidpy\hdf\hdf_utils.py:387: UserWarning: Converted key: (19, 2) from type: <class 'tuple'> to str
warn('Converted key: {} from type: {} to str'
c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\pyNSID\io\hdf_utils.py:381: FutureWarning: validate_h5_dimension may be removed in a future version
warn('validate_h5_dimension may be removed in a future version',
c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\pyNSID\io\hdf_io.py:111: UserWarning: main_data_name should not contain the "-" character. Reformatted name from:11-eels_new_new to 11_eels_new_new
warn('main_data_name should not contain the "-" character. Reformatted'
c:\Users\gduscher\Documents\Github\pyTEMlib\notebooks\Spectroscopy\../../../sidpy\sidpy\hdf\hdf_utils.py:387: UserWarning: Converted key: (0, 0) from type: <class 'tuple'> to str
warn('Converted key: {} from type: {} to str'
c:\Users\gduscher\Documents\Github\pyTEMlib\notebooks\Spectroscopy\../../../sidpy\sidpy\hdf\hdf_utils.py:387: UserWarning: Converted key: (19, 2) from type: <class 'tuple'> to str
warn('Converted key: {} from type: {} to str'
c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\pyNSID\io\hdf_utils.py:381: FutureWarning: validate_h5_dimension may be removed in a future version
warn('validate_h5_dimension may be removed in a future version',
g.file.close()
dir(g)['_MutableMapping__marker',
'__abstractmethods__',
'__bool__',
'__class__',
'__class_getitem__',
'__contains__',
'__delattr__',
'__delitem__',
'__dict__',
'__dir__',
'__doc__',
'__eq__',
'__format__',
'__ge__',
'__getattribute__',
'__getitem__',
'__getnewargs__',
'__getstate__',
'__gt__',
'__hash__',
'__init__',
'__init_subclass__',
'__iter__',
'__le__',
'__len__',
'__lt__',
'__module__',
'__ne__',
'__new__',
'__nonzero__',
'__reduce__',
'__reduce_ex__',
'__repr__',
'__reversed__',
'__setattr__',
'__setitem__',
'__sizeof__',
'__slots__',
'__str__',
'__subclasshook__',
'__weakref__',
'_abc_impl',
'_d',
'_e',
'_gcpl_crt_order',
'_id',
'_ipython_key_completions_',
'_lapl',
'_lcpl',
'attrs',
'build_virtual_dataset',
'clear',
'copy',
'create_dataset',
'create_dataset_like',
'create_group',
'create_virtual_dataset',
'file',
'get',
'id',
'items',
'keys',
'move',
'name',
'parent',
'pop',
'popitem',
'ref',
'regionref',
'require_dataset',
'require_group',
'setdefault',
'update',
'values',
'visit',
'visit_links',
'visititems',
'visititems_links']infoWidget.datasets[infoWidget.datasets['_relationship']['low_loss']].metadata
{'experiment': {'single_exposure_time': 0.1,
'number_of_frames': 1,
'collection_angle': 100.0,
'convergence_angle': 0.0,
'exposure_time': 0.1,
'microscope': '',
'acceleration_voltage': 199990.28125,
'flux_ppm': 90.36209375,
'count_conversion': 1,
'beam_current': 0},
'annotations': {'0': {'type': 'spectral_image',
'label': '1',
'width': 0.004483174532651901,
'height': 0.04483174532651901,
'position': [0.07173079252243042, 0.0],
'Rectangle': array([ 0., 16., 10., 17.])}},
'zero_loss': {'shifted': array([[-0.17133928, -0.20872347, -0.15697378, -0.22911345, -0.41304692,
-0.27802566, -0.28852486, -0.19660906, -0.24778839, -0.29709778],
[-0.17452395, -0.25264281, -0.19338031, -0.22475387, -0.3867537 ,
-0.26830998, -0.30173948, -0.18973434, -0.24055065, -0.27581737],
[-0.18777319, -0.21813711, -0.23541803, -0.25136158, -0.37223943,
-0.28151478, -0.27689985, -0.20720506, -0.20844662, -0.26624501],
[-0.19766428, -0.22570338, -0.2310333 , -0.25888585, -0.36432819,
-0.26848219, -0.29230228, -0.23995783, -0.25165612, -0.29044124],
[-0.16309471, -0.20200637, -0.22812651, -0.24042406, -0.39094313,
-0.29055997, -0.27075889, -0.18784859, -0.2146395 , -0.332887 ],
[-0.18236734, -0.18087611, -0.22866335, -0.21551541, -0.36639231,
-0.29861265, -0.2925165 , -0.24927491, -0.20851182, -0.28348217],
[-0.19927829, -0.22898982, -0.26191095, -0.22834547, -0.36971682,
-0.30889951, -0.3012673 , -0.24113467, -0.17493781, -0.32168681],
[-0.1738958 , -0.1913216 , -0.21929859, -0.24915983, -0.3876799 ,
-0.30038999, -0.20116385, -0.26177179, -0.18331803, -0.34600463],
[-0.13096981, -0.2006438 , -0.21227983, -0.21064573, -0.33160388,
-0.36483439, -0.24456268, -0.26444754, -0.14945136, -0.28794927],
[-0.1462392 , -0.25174427, -0.19415191, -0.25038362, -0.35794843,
-0.30022434, -0.21339795, -0.23672159, -0.24448357, -0.27052469],
[-0.14685874, -0.17460282, -0.16165857, -0.22823609, -0.35877969,
-0.33408546, -0.24722202, -0.21119665, -0.22090627, -0.28490726],
[-0.16866301, -0.15241837, -0.16493974, -0.27075112, -0.32254401,
-0.31866055, -0.24792923, -0.23735904, -0.20442612, -0.30334064],
[-0.16050684, -0.14049517, -0.20804801, -0.25107936, -0.35387663,
-0.30954754, -0.20522215, -0.20693605, -0.21926198, -0.27534069],
[-0.17034575, -0.12584347, -0.24092053, -0.31105879, -0.33426595,
-0.30892898, -0.1836695 , -0.22767377, -0.2596248 , -0.24581365],
[-0.22159879, -0.12982051, -0.20819836, -0.27049065, -0.34958568,
-0.31558961, -0.19452586, -0.21314073, -0.24035954, -0.2328248 ],
[-0.2032972 , -0.14719534, -0.19907061, -0.2462344 , -0.31856248,
-0.3517771 , -0.20909715, -0.23441361, -0.25507181, -0.25137647],
[-0.17083077, -0.15719943, -0.2197162 , -0.28521577, -0.31527722,
-0.33289726, -0.18606309, -0.19628289, -0.25623027, -0.23231349],
[-0.12688726, -0.17655356, -0.19887589, -0.29611456, -0.37989474,
-0.32507459, -0.22918826, -0.21149825, -0.21018903, -0.2608516 ],
[-0.18858283, -0.17266317, -0.20583162, -0.29928345, -0.3205138 ,
-0.34542016, -0.25208158, -0.26567733, -0.19913084, -0.2670854 ],
[-0.20338365, -0.18022165, -0.22180157, -0.29435486, -0.35585983,
-0.37953179, -0.17357063, -0.20438077, -0.22438605, -0.24467854],
[-0.2061708 , -0.21012867, -0.24347788, -0.29475718, -0.34663862,
-0.41550053, -0.18316705, -0.23659631, -0.24869219, -0.21216895],
[-0.22316636, -0.21843133, -0.19459794, -0.30371964, -0.31803614,
-0.36346566, -0.1827611 , -0.24550804, -0.26715442, -0.23049209],
[-0.22549864, -0.20233576, -0.25172761, -0.32813819, -0.33494639,
-0.41605422, -0.182917 , -0.18322456, -0.28218851, -0.22714036],
[-0.22792804, -0.18826536, -0.25218583, -0.29268463, -0.32082594,
-0.32751488, -0.16049068, -0.19076274, -0.2756469 , -0.23645988],
[-0.17985229, -0.17842844, -0.20377253, -0.31785076, -0.34848329,
-0.41367577, -0.17336046, -0.16275926, -0.30444214, -0.2085971 ]]),
'startFitEnergy': -0.5,
'endFitEnergy': 0.5,
'fit_parameter': array([-1.51221768e-02, 2.67527012e+03, 1.67573156e-01, 4.36801062e-02,
2.74369530e+03, 3.35819747e-01]),
'original_low_loss': '11-eels_new_new',
'0-0': {...},
'0,0': {...},
'0,1': {...},
'0,2': {...},
'0,3': {...},
'0,4': {...},
'0,5': {...},
'0,6': {...},
'0,7': {...},
'0,8': {...},
'0,9': {...},
'1,0': {...},
'1,1': {...},
'1,2': {...},
'1,3': {...},
'1,4': {...},
'1,5': {...},
'1,6': {...},
'1,7': {...},
'1,8': {...},
'1,9': {...},
'2,0': {...},
'2,1': {...},
'2,2': {...},
'2,3': {...},
'2,4': {...},
'2,5': {...},
'2,6': {...},
'2,7': {...},
'2,8': {...},
'2,9': {...},
'3,0': {...},
'3,1': {...},
'3,2': {...},
'3,3': {...},
'3,4': {...},
'3,5': {...},
'3,6': {...},
'3,7': {...},
'3,8': {...},
'3,9': {...},
'4,0': {...},
'4,1': {...},
'4,2': {...},
'4,3': {...},
'4,4': {...},
'4,5': {...},
'4,6': {...},
'4,7': {...},
'4,8': {...},
'4,9': {...},
'5,0': {...},
'5,1': {...},
'5,2': {...},
'5,3': {...},
'5,4': {...},
'5,5': {...},
'5,6': {...},
'5,7': {...},
'5,8': {...},
'5,9': {...},
'6,0': {...},
'6,1': {...},
'6,2': {...},
'6,3': {...},
'6,4': {...},
'6,5': {...},
'6,6': {...},
'6,7': {...},
'6,8': {...},
'6,9': {...},
'7,0': {...},
'7,1': {...},
'7,2': {...},
'7,3': {...},
'7,4': {...},
'7,5': {...},
'7,6': {...},
'7,7': {...},
'7,8': {...},
'7,9': {...},
'8,0': {...},
'8,1': {...},
'8,2': {...},
'8,3': {...},
'8,4': {...},
'8,5': {...},
'8,6': {...},
'8,7': {...},
'8,8': {...},
'8,9': {...},
'9,0': {...},
'9,1': {...},
'9,2': {...},
'9,3': {...},
'9,4': {...},
'9,5': {...},
'9,6': {...},
'9,7': {...},
'9,8': {...},
'9,9': {...},
'10,0': {...},
'10,1': {...},
'10,2': {...},
'10,3': {...},
'10,4': {...},
'10,5': {...},
'10,6': {...},
'10,7': {...},
'10,8': {...},
'10,9': {...},
'11,0': {...},
'11,1': {...},
'11,2': {...},
'11,3': {...},
'11,4': {...},
'11,5': {...},
'11,6': {...},
'11,7': {...},
'11,8': {...},
'11,9': {...},
'12,0': {...},
'12,1': {...},
'12,2': {...},
'12,3': {...},
'12,4': {...},
'12,5': {...},
'12,6': {...},
'12,7': {...},
'12,8': {...},
'12,9': {...},
'13,0': {...},
'13,1': {...},
'13,2': {...},
'13,3': {...},
'13,4': {...},
'13,5': {...},
'13,6': {...},
'13,7': {...},
'13,8': {...},
'13,9': {...},
'14,0': {...},
'14,1': {...},
'14,2': {...},
'14,3': {...},
'14,4': {...},
'14,5': {...},
'14,6': {...},
'14,7': {...},
'14,8': {...},
'14,9': {...},
'15,0': {...},
'15,1': {...},
'15,2': {...},
'15,3': {...},
'15,4': {...},
'15,5': {...},
'15,6': {...},
'15,7': {...},
'15,8': {...},
'15,9': {...},
'16,0': {...},
'16,1': {...},
'16,2': {...},
'16,3': {...},
'16,4': {...},
'16,5': {...},
'16,6': {...},
'16,7': {...},
'16,8': {...},
'16,9': {...},
'17,0': {...},
'17,1': {...},
'17,2': {...},
'17,3': {...},
'17,4': {...},
'17,5': {...},
'17,6': {...},
'17,7': {...},
'17,8': {...},
'17,9': {...},
'18,0': {...},
'18,1': {...},
'18,2': {...},
'18,3': {...},
'18,4': {...},
'18,5': {...},
'18,6': {...},
'18,7': {...},
'18,8': {...},
'18,9': {...},
'19,0': {...},
'19,1': {...},
'19,2': {...},
'19,3': {...},
'19,4': {...},
'19,5': {...},
'19,6': {...},
'19,7': {...},
'19,8': {...},
'19,9': {...},
'20,0': {...},
'20,1': {...},
'20,2': {...},
'20,3': {...},
'20,4': {...},
'20,5': {...},
'20,6': {...},
'20,7': {...},
'20,8': {...},
'20,9': {...},
'21,0': {...},
'21,1': {...},
'21,2': {...},
'21,3': {...},
'21,4': {...},
'21,5': {...},
'21,6': {...},
'21,7': {...},
'21,8': {...},
'21,9': {...},
'22,0': {...},
'22,1': {...},
'22,2': {...},
'22,3': {...},
'22,4': {...},
'22,5': {...},
'22,6': {...},
'22,7': {...},
'22,8': {...},
'22,9': {...},
'23,0': {...},
'23,1': {...},
'23,2': {...},
'23,3': {...},
'23,4': {...},
'23,5': {...},
'23,6': {...},
'23,7': {...},
'23,8': {...},
'23,9': {...},
'24,0': {...},
'24,1': {...},
'24,2': {...},
'24,3': {...},
'24,4': {...},
'24,5': {...},
'24,6': {...},
'24,7': {...},
'24,8': {...},
'24,9': {...}}}infoWidget.low_loss.get_multiple_scattering()---------------------------------------------------------------------------
KeyboardInterrupt Traceback (most recent call last)
Cell In[20], line 1
----> 1 infoWidget.low_loss.get_multiple_scattering()
File c:\Users\gduscher\Documents\Github\pyTEMlib\notebooks\Spectroscopy\../..\pyTEMlib\low_loss_widget.py:281, in get_multiple_scattering(self, value)
0 <Error retrieving source code with stack_data see ipython/ipython#13598>
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\traitlets\traitlets.py:716, in TraitType.__set__(self, obj, value)
714 if self.read_only:
715 raise TraitError('The "%s" trait is read-only.' % self.name)
--> 716 self.set(obj, value)
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\traitlets\traitlets.py:706, in TraitType.set(self, obj, value)
702 silent = False
703 if silent is not True:
704 # we explicitly compare silent to True just in case the equality
705 # comparison above returns something other than True/False
--> 706 obj._notify_trait(self.name, old_value, new_value)
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\traitlets\traitlets.py:1513, in HasTraits._notify_trait(self, name, old_value, new_value)
1512 def _notify_trait(self, name: str, old_value: t.Any, new_value: t.Any) -> None:
-> 1513 self.notify_change(
1514 Bunch(
1515 name=name,
1516 old=old_value,
1517 new=new_value,
1518 owner=self,
1519 type="change",
1520 )
1521 )
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\ipywidgets\widgets\widget.py:687, in Widget.notify_change(self, change)
684 if name in self.keys and self._should_send_property(name, getattr(self, name)):
685 # Send new state to front-end
686 self.send_state(key=name)
--> 687 super(Widget, self).notify_change(change)
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\traitlets\traitlets.py:1525, in HasTraits.notify_change(self, change)
1523 def notify_change(self, change: Bunch) -> None:
1524 """Notify observers of a change event"""
-> 1525 return self._notify_observers(change)
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\traitlets\traitlets.py:1568, in HasTraits._notify_observers(self, event)
1565 elif isinstance(c, EventHandler) and c.name is not None:
1566 c = getattr(self, c.name)
-> 1568 c(event)
File c:\Users\gduscher\Documents\Github\pyTEMlib\notebooks\Spectroscopy\../..\pyTEMlib\info_widget.py:507, in EELSBaseWidget._update(self, ev)
505 self.axis.set_ylabel(self.ylabel)
506 self.change_y_scale = 1.0
--> 507 self.update_tab_spectra()
508 self.figure.canvas.draw_idle()
File c:\Users\gduscher\Documents\Github\pyTEMlib\notebooks\Spectroscopy\../..\pyTEMlib\info_widget.py:818, in EELSWidget.update_tab_spectra(self)
816 def update_tab_spectra(self):
817 if self.tabval == 2:
--> 818 self.low_loss._update()
File c:\Users\gduscher\Documents\Github\pyTEMlib\notebooks\Spectroscopy\../..\pyTEMlib\low_loss_widget.py:334, in LowLoss._update(self, ev)
332 difference -= plasmon
333 if self.low_loss_tab[3, 0].value + self.low_loss_tab[10, 0].value + self.low_loss_tab[15, 0].value > 0:
--> 334 self.parent.axis.plot(self.parent.energy_scale, difference, label='difference')
335 self.parent.axis.legend()
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\matplotlib\axes\_axes.py:1779, in Axes.plot(self, scalex, scaley, data, *args, **kwargs)
1536 """
1537 Plot y versus x as lines and/or markers.
1538
(...)
1776 (``'green'``) or hex strings (``'#008000'``).
1777 """
1778 kwargs = cbook.normalize_kwargs(kwargs, mlines.Line2D)
-> 1779 lines = [*self._get_lines(self, *args, data=data, **kwargs)]
1780 for line in lines:
1781 self.add_line(line)
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\matplotlib\axes\_base.py:296, in _process_plot_var_args.__call__(self, axes, data, *args, **kwargs)
294 this += args[0],
295 args = args[1:]
--> 296 yield from self._plot_args(
297 axes, this, kwargs, ambiguous_fmt_datakey=ambiguous_fmt_datakey)
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\matplotlib\axes\_base.py:483, in _process_plot_var_args._plot_args(self, axes, tup, kwargs, return_kwargs, ambiguous_fmt_datakey)
481 axes.xaxis.update_units(x)
482 if axes.yaxis is not None:
--> 483 axes.yaxis.update_units(y)
485 if x.shape[0] != y.shape[0]:
486 raise ValueError(f"x and y must have same first dimension, but "
487 f"have shapes {x.shape} and {y.shape}")
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\matplotlib\axis.py:1750, in Axis.update_units(self, data)
1744 def update_units(self, data):
1745 """
1746 Introspect *data* for units converter and update the
1747 ``axis.converter`` instance if necessary. Return *True*
1748 if *data* is registered for unit conversion.
1749 """
-> 1750 converter = munits.registry.get_converter(data)
1751 if converter is None:
1752 return False
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\matplotlib\units.py:183, in Registry.get_converter(self, x)
181 pass
182 try: # If cache lookup fails, look up based on first element...
--> 183 first = cbook._safe_first_finite(x)
184 except (TypeError, StopIteration):
185 pass
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\matplotlib\cbook.py:1782, in _safe_first_finite(obj)
1780 else:
1781 for val in obj:
-> 1782 if safe_isfinite(val):
1783 return val
1784 return safe_first_element(obj)
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\matplotlib\cbook.py:1762, in _safe_first_finite.<locals>.safe_isfinite(val)
1760 return False
1761 try:
-> 1762 return math.isfinite(val)
1763 except (TypeError, ValueError):
1764 # if the outer object is 2d, then val is a 1d array, and
1765 # - math.isfinite(numpy.zeros(3)) raises TypeError
1766 # - math.isfinite(torch.zeros(3)) raises ValueError
1767 pass
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\dask\array\core.py:1883, in Array.__float__(self)
1882 def __float__(self):
-> 1883 return self._scalarfunc(float)
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\dask\array\core.py:1875, in Array._scalarfunc(self, cast_type)
1873 raise TypeError("Only length-1 arrays can be converted to Python scalars")
1874 else:
-> 1875 return cast_type(self.compute().item())
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\dask\base.py:375, in DaskMethodsMixin.compute(self, **kwargs)
351 def compute(self, **kwargs):
352 """Compute this dask collection
353
354 This turns a lazy Dask collection into its in-memory equivalent.
(...)
373 dask.compute
374 """
--> 375 (result,) = compute(self, traverse=False, **kwargs)
376 return result
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\dask\base.py:654, in compute(traverse, optimize_graph, scheduler, get, *args, **kwargs)
646 return args
648 schedule = get_scheduler(
649 scheduler=scheduler,
650 collections=collections,
651 get=get,
652 )
--> 654 dsk = collections_to_dsk(collections, optimize_graph, **kwargs)
655 keys, postcomputes = [], []
656 for x in collections:
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\dask\base.py:427, in collections_to_dsk(collections, optimize_graph, optimizations, **kwargs)
425 for opt, val in groups.items():
426 dsk, keys = _extract_graph_and_keys(val)
--> 427 dsk = opt(dsk, keys, **kwargs)
429 for opt_inner in optimizations:
430 dsk = opt_inner(dsk, keys, **kwargs)
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\dask\array\optimization.py:51, in optimize(dsk, keys, fuse_keys, fast_functions, inline_functions_fast_functions, rename_fused_keys, **kwargs)
49 dsk = optimize_blockwise(dsk, keys=keys)
50 dsk = fuse_roots(dsk, keys=keys)
---> 51 dsk = dsk.cull(set(keys))
53 # Perform low-level fusion unless the user has
54 # specified False explicitly.
55 if config.get("optimization.fuse.active") is False:
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\dask\highlevelgraph.py:738, in HighLevelGraph.cull(self, keys)
736 output_keys = keys_set.intersection(layer.get_output_keys())
737 if output_keys:
--> 738 culled_layer, culled_deps = layer.cull(output_keys, all_ext_keys)
739 # Update `keys` with all layer's external key dependencies, which
740 # are all the layer's dependencies (`culled_deps`) excluding
741 # the layer's output keys.
742 external_deps = set()
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\dask\highlevelgraph.py:154, in Layer.cull(self, keys, all_hlg_keys)
152 k = work.pop()
153 out[k] = self[k]
--> 154 ret_deps[k] = self.get_dependencies(k, all_hlg_keys)
155 for d in ret_deps[k]:
156 if d not in seen:
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\dask\highlevelgraph.py:178, in Layer.get_dependencies(self, key, all_hlg_keys)
163 def get_dependencies(self, key: Key, all_hlg_keys: Collection[Key]) -> set:
164 """Get dependencies of `key` in the layer
165
166 Parameters
(...)
176 A set of dependencies
177 """
--> 178 return keys_in_tasks(all_hlg_keys, [self[key]])
File c:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\dask\core.py:199, in keys_in_tasks(keys, tasks, as_list)
197 pass
198 tasks = work
--> 199 return ret if as_list else set(ret)
KeyboardInterrupt: infoWidget.low_loss.do_all()0 0
0 1
0 2
0 3
0 4
0 5
0 6
0 7
0 8
0 9
1 0
1 1
1 2
1 3
1 4
1 5
1 6
1 7
1 8
1 9
2 0
2 1
2 2
2 3
2 4
2 5
2 6
2 7
2 8
2 9
3 0
3 1
3 2
3 3
3 4
3 5
3 6
3 7
3 8
3 9
4 0
4 1
4 2
4 3
4 4
4 5
4 6
4 7
4 8
4 9
5 0
5 1
5 2
5 3
5 4
5 5
5 6
5 7
5 8
5 9
6 0
6 1
6 2
6 3
6 4
6 5
6 6
6 7
6 8
6 9
7 0
7 1
7 2
7 3
7 4
7 5
7 6
7 7
7 8
7 9
8 0
8 1
8 2
8 3
8 4
8 5
8 6
8 7
8 8
8 9
9 0
9 1
9 2
9 3
9 4
9 5
9 6
9 7
9 8
9 9
10 0
10 1
10 2
10 3
10 4
10 5
10 6
10 7
10 8
10 9
11 0
11 1
11 2
11 3
11 4
11 5
11 6
11 7
11 8
11 9
12 0
12 1
12 2
12 3
12 4
12 5
12 6
12 7
12 8
12 9
13 0
13 1
13 2
13 3
13 4
13 5
13 6
13 7
13 8
13 9
14 0
14 1
14 2
14 3
14 4
14 5
14 6
14 7
14 8
14 9
15 0
15 1
15 2
15 3
15 4
15 5
15 6
15 7
15 8
15 9
16 0
16 1
16 2
16 3
16 4
16 5
16 6
16 7
16 8
16 9
17 0
17 1
17 2
17 3
17 4
17 5
17 6
17 7
17 8
17 9
18 0
18 1
18 2
18 3
18 4
18 5
18 6
18 7
18 8
18 9
19 0
19 1
19 2
19 3
19 4
19 5
19 6
19 7
19 8
19 9
20 0
20 1
20 2
20 3
20 4
20 5
20 6
20 7
20 8
20 9
21 0
21 1
21 2
21 3
21 4
21 5
21 6
21 7
21 8
21 9
22 0
22 1
22 2
22 3
22 4
22 5
22 6
22 7
22 8
22 9
23 0
23 1
23 2
23 3
23 4
23 5
23 6
23 7
23 8
23 9
24 0
24 1
24 2
24 3
24 4
24 5
24 6
24 7
24 8
24 9
infoWidget.datasets['low_loss_model'].plot()
infoWidgetplt.figure()
for key, dset in infoWidget.datasets.items():
if key[0] != '_':
print(dset.title, dset.shape)
plt.plot(dset.energy_loss, dset)
13-without blue laser 10% (2048,)
EELS Acquire (2048,)
13-with laser (2048,)
plt.close('all')class EELSWidget2(pyTEMlib.info_widget.EELSBaseWidget):
def __init__(self, datasets=None):
super().__init__(datasets, sidebar=None)
super().set_dataset()
infoWidget.low_loss.update_ll_sidebar()Channel_000 None 0
Channel_000 None 0
infoWidget.datasets['Channel_002'].original_metadata{'ImageData': {'Calibrations': {'Brightness': {'Origin': 0.0,
'Scale': 1.0,
'Units': ''},
'Dimension': {'0': {'Origin': 0.0,
'Scale': 0.1487438678741455,
'Units': 'nm'},
'1': {'Origin': 0.0, 'Scale': 0.1487438678741455, 'Units': 'nm'}},
'DisplayCalibratedUnits': 1},
'Data': 'read',
'DataType': 11,
'Dimensions': {'0': 1024, '1': 1024},
'PixelDepth': 4},
'ImageTags': {'DataBar': {'Acquisition Date': '3/16/2023',
'Acquisition Time': '1:23:37 PM',
'Acquisition Time (OS)': 1.3323461017764891e+17,
'Custom elements': {},
'Device Name': 'DigiScan',
'Exposure Number': 3960478},
'DigiScan': {'Bitshift': 0,
'Channel': 0,
'Flip': 0,
'Flyback': 50.0,
'Horizontal DS Offset': 0.0,
'Horizontal Image Center': 512.0,
'Horizontal Perpendicular Pixel Step': -16,
'Horizontal Pixel Step': -16,
'Horizontal Spacing': 22.4,
'Integrate Frames': 0,
'Integration Percentage': 80.0,
'Number Summing Frames': 5.0,
'Recorded': 1,
'Rotation': 45.0,
'Rotation Offset': 180.0,
'Sample Time': 32.400001525878906,
'SessionID': 1678985640,
'Signal Index': 0,
'Signals': {'0': {'Acquired': 1,
'Datatype': 4,
'Selected': 1,
'Signal ID': 0},
'1': {'Acquired': 0, 'Datatype': 4, 'Selected': 0, 'Signal ID': 1}},
'Slot': 0,
'Sum Frames': 0,
'Synchronize Lines': 1,
'TimeStamp': 'Thu Mar 16 13:23:03 2023\u2028',
'Vertical DS Offset': 0.0,
'Vertical Image Center': 512.0,
'Vertical Perpendicular Pixel Step': -16,
'Vertical Pixel Step': 16,
'Vertical Spacing': 22.4,
'Zoom factor': 0.7},
'Microscope Info': {'Cs(mm)': 2.2,
'Emission Current (A)': 230.0,
'Field of View (m)': 0.21540414060665797,
'Formatted Indicated Mag': '249.0kx',
'Formatted Voltage': '200.0kV',
'HT Extrapolated': 0,
'Illumination Mode': 'STEM',
'Imaging Mode': 'Diffraction Mag',
'Indicated Magnification': 248993.484375,
'Items': {'0': {'Data Type': 20,
'Label': 'Specimen',
'Tag path': 'Microscope Info:Specimen',
'Value': 'TEST-Helium bubble'},
'1': {'Data Type': 20,
'Label': 'Operator',
'Tag path': 'Microscope Info:Operator',
'Value': 'Shradha'},
'2': {'Data Type': 20,
'Label': 'Microscope',
'Tag path': 'Microscope Info:Microscope',
'Value': ''}},
'Magnification Interpolated': 0,
'Microscope': '',
'Name': 'Libra COM',
'Operation Mode': 'SCANNING',
'Operator': 'Shradha',
'Probe Current (nA)': 0.0,
'Probe Size (nm)': 0.0,
'Specimen': 'TEST-Helium bubble',
'STEM Camera Length': 1200.0000476837158,
'Voltage': 199990.28125},
'Survey Image': {'UID': {'0': 1024205530,
'1': 1461147407,
'2': 52899482,
'3': 519921575}}},
'Name': '12-survey',
'UniqueID': {'0': 1024205530, '1': 1461147407, '2': 52899482, '3': 519921575},
'DM': {'dm_version': 3,
'file_size': 4797467,
'full_file_name': 'C:\\Users\\gduscher\\Desktop\\drive-download-20241125T130908Z-001\\12-survey.dm3'},
'original_filename': 'C:\\Users\\gduscher\\Desktop\\drive-download-20241125T130908Z-001\\12-survey.dm3',
'ApplicationBounds': [0, 0, 1343, 2152],
'DocumentObjectList': {'0': {'AnnotationGroupList': {'0': {'AnnotationType': 27,
'BackgroundColor': [-1, -1, -1],
'BackgroundMode': 2,
'Color': [-1, 0, 0],
'FillMode': 2,
'ForegroundColor': [0, -1, 0],
'HasBackground': 0,
'IsDeletable': 1,
'IsMoveable': 1,
'IsResizable': 1,
'IsSelectable': 1,
'IsTranslatable': 1,
'IsVisible': 1,
'IsVolatile': 0,
'Label': 'Beam',
'Name': 'DS_BEAM',
'ObjectTags': {},
'Rectangle': [547.0, 769.0, 547.0, 769.0],
'SelectionStyle': 1,
'UniqueID': 13},
'1': {'AnnotationType': 23,
'BackgroundColor': [-1, -1, -1],
'BackgroundMode': 2,
'Color': [0, -1, 0],
'FillMode': 2,
'ForegroundColor': [0, -1, 0],
'HasBackground': 0,
'IsDeletable': 1,
'IsMoveable': 1,
'IsResizable': 1,
'IsSelectable': 1,
'IsTranslatable': 1,
'IsVisible': 1,
'IsVolatile': 0,
'Label': 'Spectrum Image',
'Name': 'Spectrum Image',
'ObjectTags': {},
'Rectangle': [341.0, 15.0, 590.0, 762.0],
'SelectionStyle': 1,
'UniqueID': 10},
'2': {'AnnotationType': 31,
'BackgroundColor': [-1, -1, -1],
'BackgroundMode': 2,
'FillMode': 2,
'Font': {'Attributes': 7, 'FamilyName': 'Lucida Console', 'Size': 40},
'ForegroundColor': [-1, -1, -1],
'HasBackground': 0,
'IsMoveable': 1,
'IsResizable': 1,
'IsSelectable': 1,
'IsTranslatable': 1,
'IsVisible': 1,
'ObjectTags': {},
'Rectangle': [884.0, 64.0, 960.0, 544.0],
'TextOffsetH': 1.0,
'TextOffsetV': 1.0,
'TextWidth': 95.0,
'UniqueID': 9}},
'AnnotationType': 20,
'BackgroundColor': [-1, -1, -1],
'BackgroundMode': 2,
'FillMode': 1,
'ForegroundColor': [0, -1, 0],
'HasBackground': 0,
'ImageDisplayInfo': {'BrightColor': [-1, -1, -1],
'Brightness': 0.5,
'CaptionOn': 0,
'CaptionSize': 12,
'CLUT': [[0, 0, 0],
[257, 257, 257],
[514, 514, 514],
[771, 771, 771],
[1028, 1028, 1028],
[1285, 1285, 1285],
[1542, 1542, 1542],
[1799, 1799, 1799],
[2056, 2056, 2056],
[2313, 2313, 2313],
[2570, 2570, 2570],
[2827, 2827, 2827],
[3084, 3084, 3084],
[3341, 3341, 3341],
[3598, 3598, 3598],
[3855, 3855, 3855],
[4112, 4112, 4112],
[4369, 4369, 4369],
[4626, 4626, 4626],
[4883, 4883, 4883],
[5140, 5140, 5140],
[5397, 5397, 5397],
[5654, 5654, 5654],
[5911, 5911, 5911],
[6168, 6168, 6168],
[6425, 6425, 6425],
[6682, 6682, 6682],
[6939, 6939, 6939],
[7196, 7196, 7196],
[7453, 7453, 7453],
[7710, 7710, 7710],
[7967, 7967, 7967],
[8224, 8224, 8224],
[8481, 8481, 8481],
[8738, 8738, 8738],
[8995, 8995, 8995],
[9252, 9252, 9252],
[9509, 9509, 9509],
[9766, 9766, 9766],
[10023, 10023, 10023],
[10280, 10280, 10280],
[10537, 10537, 10537],
[10794, 10794, 10794],
[11051, 11051, 11051],
[11308, 11308, 11308],
[11565, 11565, 11565],
[11822, 11822, 11822],
[12079, 12079, 12079],
[12336, 12336, 12336],
[12593, 12593, 12593],
[12850, 12850, 12850],
[13107, 13107, 13107],
[13364, 13364, 13364],
[13621, 13621, 13621],
[13878, 13878, 13878],
[14135, 14135, 14135],
[14392, 14392, 14392],
[14649, 14649, 14649],
[14906, 14906, 14906],
[15163, 15163, 15163],
[15420, 15420, 15420],
[15677, 15677, 15677],
[15934, 15934, 15934],
[16191, 16191, 16191],
[16448, 16448, 16448],
[16705, 16705, 16705],
[16962, 16962, 16962],
[17219, 17219, 17219],
[17476, 17476, 17476],
[17733, 17733, 17733],
[17990, 17990, 17990],
[18247, 18247, 18247],
[18504, 18504, 18504],
[18761, 18761, 18761],
[19018, 19018, 19018],
[19275, 19275, 19275],
[19532, 19532, 19532],
[19789, 19789, 19789],
[20046, 20046, 20046],
[20303, 20303, 20303],
[20560, 20560, 20560],
[20817, 20817, 20817],
[21074, 21074, 21074],
[21331, 21331, 21331],
[21588, 21588, 21588],
[21845, 21845, 21845],
[22102, 22102, 22102],
[22359, 22359, 22359],
[22616, 22616, 22616],
[22873, 22873, 22873],
[23130, 23130, 23130],
[23387, 23387, 23387],
[23644, 23644, 23644],
[23901, 23901, 23901],
[24158, 24158, 24158],
[24415, 24415, 24415],
[24672, 24672, 24672],
[24929, 24929, 24929],
[25186, 25186, 25186],
[25443, 25443, 25443],
[25700, 25700, 25700],
[25957, 25957, 25957],
[26214, 26214, 26214],
[26471, 26471, 26471],
[26728, 26728, 26728],
[26985, 26985, 26985],
[27242, 27242, 27242],
[27499, 27499, 27499],
[27756, 27756, 27756],
[28013, 28013, 28013],
[28270, 28270, 28270],
[28527, 28527, 28527],
[28784, 28784, 28784],
[29041, 29041, 29041],
[29298, 29298, 29298],
[29555, 29555, 29555],
[29812, 29812, 29812],
[30069, 30069, 30069],
[30326, 30326, 30326],
[30583, 30583, 30583],
[30840, 30840, 30840],
[31097, 31097, 31097],
[31354, 31354, 31354],
[31611, 31611, 31611],
[31868, 31868, 31868],
[32125, 32125, 32125],
[32382, 32382, 32382],
[32639, 32639, 32639],
[-32640, -32640, -32640],
[-32383, -32383, -32383],
[-32126, -32126, -32126],
[-31869, -31869, -31869],
[-31612, -31612, -31612],
[-31355, -31355, -31355],
[-31098, -31098, -31098],
[-30841, -30841, -30841],
[-30584, -30584, -30584],
[-30327, -30327, -30327],
[-30070, -30070, -30070],
[-29813, -29813, -29813],
[-29556, -29556, -29556],
[-29299, -29299, -29299],
[-29042, -29042, -29042],
[-28785, -28785, -28785],
[-28528, -28528, -28528],
[-28271, -28271, -28271],
[-28014, -28014, -28014],
[-27757, -27757, -27757],
[-27500, -27500, -27500],
[-27243, -27243, -27243],
[-26986, -26986, -26986],
[-26729, -26729, -26729],
[-26472, -26472, -26472],
[-26215, -26215, -26215],
[-25958, -25958, -25958],
[-25701, -25701, -25701],
[-25444, -25444, -25444],
[-25187, -25187, -25187],
[-24930, -24930, -24930],
[-24673, -24673, -24673],
[-24416, -24416, -24416],
[-24159, -24159, -24159],
[-23902, -23902, -23902],
[-23645, -23645, -23645],
[-23388, -23388, -23388],
[-23131, -23131, -23131],
[-22874, -22874, -22874],
[-22617, -22617, -22617],
[-22360, -22360, -22360],
[-22103, -22103, -22103],
[-21846, -21846, -21846],
[-21589, -21589, -21589],
[-21332, -21332, -21332],
[-21075, -21075, -21075],
[-20818, -20818, -20818],
[-20561, -20561, -20561],
[-20304, -20304, -20304],
[-20047, -20047, -20047],
[-19790, -19790, -19790],
[-19533, -19533, -19533],
[-19276, -19276, -19276],
[-19019, -19019, -19019],
[-18762, -18762, -18762],
[-18505, -18505, -18505],
[-18248, -18248, -18248],
[-17991, -17991, -17991],
[-17734, -17734, -17734],
[-17477, -17477, -17477],
[-17220, -17220, -17220],
[-16963, -16963, -16963],
[-16706, -16706, -16706],
[-16449, -16449, -16449],
[-16192, -16192, -16192],
[-15935, -15935, -15935],
[-15678, -15678, -15678],
[-15421, -15421, -15421],
[-15164, -15164, -15164],
[-14907, -14907, -14907],
[-14650, -14650, -14650],
[-14393, -14393, -14393],
[-14136, -14136, -14136],
[-13879, -13879, -13879],
[-13622, -13622, -13622],
[-13365, -13365, -13365],
[-13108, -13108, -13108],
[-12851, -12851, -12851],
[-12594, -12594, -12594],
[-12337, -12337, -12337],
[-12080, -12080, -12080],
[-11823, -11823, -11823],
[-11566, -11566, -11566],
[-11309, -11309, -11309],
[-11052, -11052, -11052],
[-10795, -10795, -10795],
[-10538, -10538, -10538],
[-10281, -10281, -10281],
[-10024, -10024, -10024],
[-9767, -9767, -9767],
[-9510, -9510, -9510],
[-9253, -9253, -9253],
[-8996, -8996, -8996],
[-8739, -8739, -8739],
[-8482, -8482, -8482],
[-8225, -8225, -8225],
[-7968, -7968, -7968],
[-7711, -7711, -7711],
[-7454, -7454, -7454],
[-7197, -7197, -7197],
[-6940, -6940, -6940],
[-6683, -6683, -6683],
[-6426, -6426, -6426],
[-6169, -6169, -6169],
[-5912, -5912, -5912],
[-5655, -5655, -5655],
[-5398, -5398, -5398],
[-5141, -5141, -5141],
[-4884, -4884, -4884],
[-4627, -4627, -4627],
[-4370, -4370, -4370],
[-4113, -4113, -4113],
[-3856, -3856, -3856],
[-3599, -3599, -3599],
[-3342, -3342, -3342],
[-3085, -3085, -3085],
[-2828, -2828, -2828],
[-2571, -2571, -2571],
[-2314, -2314, -2314],
[-2057, -2057, -2057],
[-1800, -1800, -1800],
[-1543, -1543, -1543],
[-1286, -1286, -1286],
[-1029, -1029, -1029],
[-772, -772, -772],
[-515, -515, -515],
[-258, -258, -258],
[-1, -1, -1]],
'CLUTName': 'Greyscale',
'ComplexMode': 4,
'ComplexRange': 1000.0,
'Contrast': 0.5,
'ContrastMode': 1,
'DimensionLabels': {'0': ''},
'DoAutoSurvey': 1,
'EstimatedMax': 156.0,
'EstimatedMaxTrimPercentage': 0.0010000000474974513,
'EstimatedMin': 808508.0,
'EstimatedMinTrimPercentage': 0.0010000000474974513,
'Gamma': 0.5,
'HighLimit': 664984.0625,
'HiLimitContrastDeltaTriggerPercentage': 0.0,
'IsInverted': 0,
'LowLimit': 1340.109375,
'LowLimitContrastDeltaTriggerPercentage': 0.0,
'MainSliceId': {'0': 0},
'MinimumContrast': 0.0,
'RangeAdjust': 1.0,
'SparseSurvey_GridSize': 16,
'SparseSurvey_NumberPixels': 32,
'SparseSurvey_UseNumberPixels': 1,
'SurveyTechique': 1},
'ImageDisplayType': 1,
'ImageSource': 0,
'IsMoveable': 1,
'IsResizable': 1,
'IsSelectable': 1,
'IsTranslatable': 1,
'IsVisible': 1,
'ObjectTags': {'__is_not_copy': 1, '__was_selected': 0},
'Rectangle': [0.0, 0.0, 628.0, 628.0],
'UniqueID': 8}},
'DocumentTags': {},
'HasWindowPosition': 1,
'Image Behavior': {'DoIntegralZoom': 0,
'ImageDisplayBounds': [0.0, 0.0, 628.0, 628.0],
'IsZoomedToWindow': 1,
'UnscaledTransform': {'Offset': [0.0, 0.0], 'Scale': [1.0, 1.0]},
'ViewDisplayID': 8,
'WindowRect': [0.0, 0.0, 628.0, 628.0],
'ZoomAndMoveTransform': {'Offset': [0.0, 0.0], 'Scale': [1.0, 1.0]}},
'ImageSourceList': {'0': {'ClassName': 'ImageSource:Simple',
'Id': {'0': 0},
'ImageRef': 1}},
'InImageMode': 1,
'MinVersionList': {'0': {'RequiredVersion': 50659328}},
'NextDocumentObjectID': 14,
'Page Behavior': {'DoIntegralZoom': 0,
'DrawMargins': 1,
'DrawPaper': 1,
'IsFixedInPageMode': 0,
'IsZoomedToWindow': 1,
'LayedOut': 0,
'PageTransform': {'Offset': [0.0, 0.0], 'Scale': [1.0, 1.0]},
'RestoreImageDisplayBounds': [0.0, 0.0, 1024.0, 1024.0],
'RestoreImageDisplayID': 8,
'TargetDisplayID': 4294967295},
'PageSetup': {'General': [1, 1000, 8500, 11000, 1000, 1000, -1000, -1000],
'Win32': b'\x04\x00\x00\x004!\x00\x00\xf8*\x00\x00M\x01\x00\x00M\x01\x00\x00\xfa\x00\x00\x00\xfa\x00\x00\x00\xe8\x03\x00\x00\xe8\x03\x00\x00\xe8\x03\x00\x00\xe8\x03\x00\x00\x00\x00\x00\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x1b\x10',
'Win32_DevModeW': b'S\x00e\x00n\x00d\x00 \x00T\x00o\x00 \x00O\x00n\x00e\x00N\x00o\x00t\x00e\x00 \x002\x000\x001\x000\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x04\x00\x06\xdc\x00\x0c\x03\x03\xff\x00\x00\x01\x00\x01\x00\xea\no\x08d\x00\x01\x00\x0f\x00X\x02\x02\x00\x01\x00X\x02\x02\x00\x00\x00L\x00e\x00t\x00t\x00e\x00r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00DINU"\x00\xd0\x00\x0c\x03\x00\x00\xc2\xac\x90Q\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd0\x00\x00\x00SMTJ\x00\x00\x00\x00\x10\x00\xc0\x00S\x00e\x00n\x00d\x00 \x00T\x00o\x00 \x00M\x00i\x00c\x00r\x00o\x00s\x00o\x00f\x00t\x00 \x00O\x00n\x00e\x00N\x00o\x00t\x00e\x00 \x002\x000\x001\x000\x00 \x00D\x00r\x00i\x00v\x00e\x00r\x00\x00\x00RESDLL\x00UniresDLL\x00PaperSize\x00LETTER\x00Orientation\x00PORTRAIT\x00Resolution\x00DPI600\x00ColorMode\x0024bpp\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
'Win32_DevNamesW': b'\x04\x00*\x00?\x00\x00\x00S\x00e\x00n\x00d\x00 \x00T\x00o\x00 \x00M\x00i\x00c\x00r\x00o\x00s\x00o\x00f\x00t\x00 \x00O\x00n\x00e\x00N\x00o\x00t\x00e\x00 \x002\x000\x001\x000\x00 \x00D\x00r\x00i\x00v\x00e\x00r\x00\x00\x00S\x00e\x00n\x00d\x00 \x00T\x00o\x00 \x00O\x00n\x00e\x00N\x00o\x00t\x00e\x00 \x002\x000\x001\x000\x00\x00\x00n\x00u\x00l\x00:\x00\x00\x00'},
'SentinelList': {},
'Thumbnails': {'0': {'ImageIndex': 0, 'SourceSize_Pixels': [628, 628]}},
'WindowPosition': [38, 9, 666, 637]}d = infoWidget.datasets['Channel_000'].original_metadata
rect = d['DocumentObjectList']['0']['AnnotationGroupList']['2']['Rectangle']
import matplotlib.patches
plt.figure()
plt.imshow(infoWidget.datasets['Channel_000'].T)
kwargs={'edgecolor': 'red', 'facecolor': 'None'}
r = matplotlib.patches.Rectangle([rect[0], rect[2]], rect[1]-rect[0], rect[3]-rect[2], **kwargs)
plt.gca().add_artist(r)
rect[884.0, 64.0, 960.0, 544.0]
def read_annotation(image):
scale_x = np.abs(image.x[1]-image.x[0])
scale_y = np.abs(image.y[1]-image.y[0])
rec_scale = np.array([scale_x, scale_y,scale_x, scale_y])
if 'DocumentObjectList' not in image.original_metadata:
return {}
if '0' not in image.original_metadata['DocumentObjectList']:
return {}
annotations = {}
tags = image.original_metadata['DocumentObjectList']['0']
for key in tags:
if 'AnnotationGroupList' in key:
an_tags = tags[key]
for key2 in an_tags:
if isinstance(an_tags[key2], dict):
if an_tags[key2]['AnnotationType'] == 13: #type 'text'
annotations[key2] = {'type': 'text'}
if 'Label' in an_tags:
annotations[key2]['label'] = an_tags['Label']
rect = np.array(an_tags[key2]['Rectangle']) * rec_scale
annotations[key2]['position'] = [rect[1],rect[0]]
annotations[key2]['text'] = an_tags['Text']
elif an_tags[key2]['AnnotationType']==6:
annotations[key2] = {'type': 'circle'}
if 'Label' in an_tags:
annotations[key2]['label'] = an_tags['Label']
rect = np.array(an_tags[key2]['Rectangle']) * rec_scale
annotations[key2]['radius'] =rect[3]-rect[1]
annotations[key2]['position'] = [rect[1],rect[0]]
elif an_tags[key2]['AnnotationType'] == 23:
print('1')
annotations[key2] = {'type': 'spectral_image'}
if 'Label' in an_tags[key2]:
annotations[key2]['label'] = an_tags[key2]['Label']
rect = np.array(an_tags[key2]['Rectangle']) * rec_scale
annotations[key2]['width'] =rect[3]-rect[1]
annotations[key2]['height'] =rect[2]-rect[0]
annotations[key2]['position'] = [rect[1],rect[0]]
annotations[key2]['Rectangle'] = np.array(an_tags[key2]['Rectangle'])
image.metadata['annotations'] = annotations
return annotations
dset = infoWidget.datasets['Channel_001']
read_annotation(dset)
dset.plot()
if 'annotations' in dset.metadata:
annotations = dset.metadata['annotations']
for key in annotations:
if annotations[key]['type'] == 'spectral_image':
kwargs={'edgecolor': 'red', 'facecolor': 'None'}
r = matplotlib.patches.Rectangle(annotations[key]['position'], annotations[key]['width'], annotations[key]['height'], **kwargs)
plt.gca().text(annotations[key]['position'][0], annotations[key]['position'][1], annotations[key]['label'], color='r')
plt.gca().add_artist(r)
dset.metadata{'image_type': 'survey image',
'experiment': {'microscope': '', 'acceleration_voltage': 199990.28125},
'annotations': {}}{'AnnotationType': 23,
'BackgroundColor': [-1, -1, -1],
'BackgroundMode': 2,
'Color': [-258, 0, 0],
'FillMode': 2,
'ForegroundColor': [0, -1, 0],
'HasBackground': 0,
'IsDeletable': 1,
'IsMoveable': 1,
'IsResizable': 1,
'IsSelectable': 1,
'IsTranslatable': 1,
'IsVisible': 1,
'IsVolatile': 0,
'Label': '1',
'Name': 'SICursor',
'ObjectTags': {},
'Rectangle': [1.0, 26.0, 10.0, 27.0],
'SelectionStyle': 1,
'UniqueID': 13}
if split_keys[5] in ['AnnotationType','Text','Rectangle','Name', 'Label']:
tags['annotations'] = {}
for key in annotations:
if annotations[key]['AnnotationType']==13:
if 'Label' in annotations[key]:
tags['annotations']['annotations_'+str(key)+'_label'] = annotations[key]['Label']
tags['annotations']['annotations_'+str(key)+'_type'] = 'text'
rect = np.array(annotations[key]['Rectangle'])* rec_scale
tags['annotations']['annotations_'+str(key)+'_x'] = rect[1]
tags['annotations']['annotations_'+str(key)+'_y'] = rect[0]
tags['annotations']['annotations_'+str(key)+'_text'] = annotations[key]['Text']
elif annotations[key]['AnnotationType']==6:
#out_tags['annotations'][key] = {}
if 'Label' in annotations[key]:
tags['annotations']['annotations_'+str(key)+'_label'] = annotations[key]['Label']
tags['annotations']['annotations_'+str(key)+'_type'] = 'circle'
rect = np.array(annotations[key]['Rectangle'])* rec_scale
tags['annotations']['annotations_'+str(key)+'_radius'] =rect[3]-rect[1]
tags['annotations']['annotations_'+str(key)+'_position'] = [rect[1],rect[0]]
elif annotations[key]['AnnotationType']==6:
#out_tags['annotations'][key] = {}
if 'Label' in annotations[key]:
tags['annotations']['annotations_'+str(key)+'_label'] = annotations[key]['Label']
tags['annotations']['annotations_'+str(key)+'_type'] = 'circle'
rect = np.array(annotations[key]['Rectangle'])* rec_scale
tags['annotations']['annotations_'+str(key)+'_radius'] =rect[3]-rect[1]
tags['annotations']['annotations_'+str(key)+'_position'] = [rect[1],rect[0]]
elif annotations[key]['AnnotationType']==23:
if 'Name' in annotations[key]:
if annotations[key]['Name'] == 'Spectrum Image':
#tags['annotations'][key] = {}
if 'Label' in annotations[key]:
tags['annotations']['annotations_'+str(key)+'_label'] = annotations[key]['Label']
tags['annotations']['annotations_'+str(key)+'_type'] = 'spectrum image'
rect = np.array(annotations[key]['Rectangle'])* rec_scale
tags['annotations']['annotations_'+str(key)+'_width'] =rect[3]-rect[1]
tags['annotations']['annotations_'+str(key)+'_height'] =rect[2]-rect[0]
tags['annotations']['annotations_'+str(key)+'_position'] = [rect[1],rect[0]]
Cell In[41], line 5
if annotations[key]['AnnotationType']==13:
^
IndentationError: expected an indented block after 'for' statement on line 4
infoWidget.tab_buttons.index = 2
infoWidget.low_loss.update_ll_sidebar()
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
Cell In[20], line 1
----> 1 infoWidget.tab_buttons.index = 2
3 infoWidget.low_loss.update_ll_sidebar()
AttributeError: 'EELSWidget' object has no attribute 'tab_buttons'infoWidget.tabval = 2
infoWidget.tab_activated()import ipywidgets
infoWidget.tab.children = [infoWidget.tab_buttons, infoWidget.children[infoWidget.tab_buttons.index]]infoWidget.info.update_dataset()infoWidget.low_loss._update()infoWidget.datasets['plasmon'].metadata{'experiment': {'single_exposure_time': 0.1,
'exposure_time': 10.0,
'number_of_frames': 100,
'collection_angle': 100.0,
'convergence_angle': 0.0,
'microscope': 'Libra 200 MC',
'acceleration_voltage': 199990.28125,
'flux_ppm': 4875.3037109375,
'count_conversion': 1,
'beam_current': 0},
'zero_loss': {'shifted': array([-0.14012023]),
'startFitEnergy': -0.5,
'endFitEnergy': 0.5,
'fit_parameter': array([ 3.38795373e-02, 2.04002455e+04, 2.93662064e-01, -1.63207014e-02,
2.28877644e+04, 1.92327898e-01]),
'original_low_loss': 'Squeezed_EELS90muOAonaxis3_new_new'},
'plasmon': {'parameter': array([1.50324046e+01, 7.46074698e-01, 7.41146395e+08]),
'epsilon': array([0.00000000e+00 +0.j ,
0.00000000e+00 +0.j ,
0.00000000e+00 +0.j , ...,
6.23143817e+08+21041344.40887087j,
6.23269871e+08+21023350.85181732j,
6.23395723e+08+21005387.31173421j])}}an, p = eels_tools.angle_correction(infoWidget.dataset)
plt.figure()
plt.plot(infoWidget.dataset/(an/an.max()))
plt.plot(infoWidget.dataset)pin = infoWidget.datasets['plasmon'].metadata['plasmon']['parameter']
pin = np.append(pin, [0.17])
print(pin)
c = eels_tools.fit_multiple_scattering(infoWidget.dataset, 5, 40, pin)
c.plot()
c.metadata[1.60512722e+01 1.76590538e+00 3.48812177e+05 1.70000000e-01]
{'experiment': {'single_exposure_time': 0.1,
'exposure_time': 10.0,
'number_of_frames': 100,
'collection_angle': 100.0,
'convergence_angle': 0.0,
'microscope': 'Libra 200 MC',
'acceleration_voltage': 199990.28125,
'flux_ppm': 4875.3037109375,
'count_conversion': 1,
'beam_current': 0},
'zero_loss': {'shifted': array([-0.14012023]),
'startFitEnergy': -0.5,
'endFitEnergy': 0.5,
'fit_parameter': array([ 3.38795373e-02, 2.04002455e+04, 2.93662064e-01, -1.63207014e-02,
2.28877644e+04, 1.92327898e-01]),
'original_low_loss': 'EELS90muOAonaxis3_new_new'},
'multiple_scattering': {'parameter': array([1.50313404e+01, 7.54438111e-01, 3.50839049e+05, 2.38991855e-01])}}
v = infoWidget.datasets['plasmon'].plot()
def energy_loss_function(energy_scale: np.ndarray, p: np.ndarray) -> np.ndarray:
eps = 1 - p[0]**2/(energy_scale**2+p[1]**2) + 1j * p[1] * p[0]**2/energy_scale/(energy_scale**2+p[1]**2)
elf = (-1/eps).imag
return elf*p[2]
def multiple_scattering(energy_scale: np.ndarray, p: list, core_loss=False)-> np.ndarray:
p = np.abs(p)
tmfp = p[3]
if core_loss:
dif = 1
else:
dif = 16
LLene = np.linspace(1, 2048-1,2048)/dif
SSD = energy_loss_function(LLene, p)
ssd = np.fft.fft(SSD)
ssd2 = ssd.copy()
### sum contribution from each order of scattering:
PSD = np.zeros(len(LLene))
for order in range(15):
# This order convoluted spectum
# convoluted SSD is SSD2
SSD2 = np.fft.ifft(ssd).real
# scale right (could be done better? GERD)
# And add this order to final spectrum
PSD += SSD2*abs(sum(SSD)/sum(SSD2)) / scipy.special.factorial(order+1)*np.power(tmfp, (order+1))*np.exp(-tmfp) #using equation 4.1 of egerton ed2
# next order convolution
ssd = ssd * ssd2
PSD /=tmfp*np.exp(-tmfp)
BGDcoef = scipy.interpolate.splrep(LLene, PSD, s=0)
return scipy.interpolate.splev(energy_scale, BGDcoef)
tmfp = .17 #p[3]
p0 =[1.50312722e+01, 7.45905380e-01, 3.48811157e+05, tmfp]
x = infoWidget.dataset.energy_loss
cts = multiple_scattering(x, p0, core_loss=False)
plt.figure()
plt.plot(x,cts)
plt.plot(x, infoWidget.dataset)
plt.plot(x, infoWidget.dataset-cts)
plt.plot(x, infoWidget.datasets['plasmon'])
multiple_scattering(energy_scale, p)
def errf_multi(p, y, x):
elf = multiple_scattering(x, p)
err = y - elf
#print (p,sum(np.abs(err)))
return np.abs(err) # /np.sqrt(y)
pin2 = np.array([9,1,.7, 1.11])
E = energy_scale = infoWidget.dataset.energy_loss
startFit =np.argmin(abs(energy_scale-6))
endFit = np.argmin(abs(energy_scale-35))
p2, lsq = leastsq(errf_multi, p0, args=(infoWidget.dataset[startFit:endFit], energy_scale[startFit:endFit]), maxfev=2000)
cts = multiple_scattering(x, p2, core_loss=False)
plt.figure()
plt.plot(x,cts)
plt.plot(x, infoWidget.dataset)
plt.plot(x, infoWidget.dataset-cts)
plt.plot(x, infoWidget.datasets['plasmon'])
p2, p0
(array([1.50313215e+01, 7.53493487e-01, 3.50578991e+05, 2.37203551e-01]),
[15.0312722, 0.74590538, 348811.157, 0.17])tags = {}
tags['dispersion'] = spec.energy_loss.slope
tags['E0'] = 200 # tags['E0']#input('incident energy E0(kev) : ');
tags['collAngle'] = 30 # tags['collAngle']
def Drude( tags, e, p):
return drude(tags, e, p[0], p[1], p[2], p[3])
def drude(tags, e, ep, ew, tnm, eb):
pc = tags['dispersion']#input('ev per channel : ');
e0 = tags['E0']#input('incident energy E0(kev) : ');
beta = tags['collAngle']#input('collection semiangle beta(mrad) : ');
#tnm = input('thickness(nm) : ');
b = beta/1000.0 # %rad
T = 1000.0*e0*(1.+e0/1022.12)/(1.0+e0/511.06)**2;# %eV # equ.5.2a or Appendix E p 427
tgt = 1000*e0*(1022.12 + e0)/(511.06 + e0);# %eV Appendix E p 427
rk0 = 2590*(1.0+e0/511.06)*np.sqrt(2.0*T/511060);
os = e[0]
ewMod = eb
eps = 1 - (ep**2-ewMod*e*1j)/(e**2+2*e*ew*1j) #Mod Drude term
eps[np.nonzero(eps==0.0)]= 1e-19
elf = np.imag(-1/eps)
the = e/tgt; #% varies with energy loss! # Appendix E p 427
srfelf=np.imag(-4./(1.0+eps))-elf; #% for 2 surfaces
angdep = np.arctan(b/the)/the - b/(b*b+the*the);
srfint = angdep*srfelf/(3.1416*0.05292*rk0*T); #% probability per eV
anglog = np.log(1.0+ b*b/the/the);
# I0 = tags['spec'].sum()#*self.tags['counts2e']
#print('counts2e',1/self.tags['counts2e'])
# 2 * T = m_0 v**2 !!! a_0 = 0.05292 nm
volint = abs(tnm/(np.pi*0.05292*T*2.0)*elf*anglog); #S equ 4.26% probability per eV
#volint = volint *I0/ epc #S probability per channel
ssd = volint #+ srfint;
if os <-1.0:
xs = int(abs(-os/epc))
ssd[0:xs]=0.0
volint[0:xs]=0.0
srfint[0:xs]=0.0
#if os <0:
Ps = np.trapz(e,srfint); #% 2 surfaces but includes negative begrenzungs contribn.
Pv = abs(np.trapz(e,abs(volint/self.tags['spec'].sum()))); #% integrated volume probability
Pv = (volint/I0).sum() ## our data have he same epc and the trapz formula does not include
lam = tnm/Pv; #% does NOT depend on free-electron approximation (no damping).
lamfe = 4.0*0.05292*T/ep/np.log(1+(b* tgt / ep) **2); #% Eq.(3.44) approximation
#print('Ps(2surfaces+begrenzung terms) =', Ps, 'Pv=t/lambda(beta)= ',Pv,'\n');
#print('Volume-plasmon MFP(nm) = ', lam,' Free-electron MFP(nm) = ',lamfe,'\n');
#print('--------------------------------\n');
"""self.tags['eps'] = eps
self.tags['lam'] = lam
self.tags['lamfe'] = lamfe
self.tags['Pv'] = Pv
"""
return ssd#/np.pi
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Cell In[3], line 2
1 tags = {}
----> 2 tags['dispersion'] = spec.energy_loss[1] - spec.energy_loss[10] # input('ev per channel : ');
3 tags['E0'] = 200 # tags['E0']#input('incident energy E0(kev) : ');
4 tags['collAngle'] = 30 # tags['collAngle']
NameError: name 'spec' is not defineddef newDrudeBgd(energy_scale,p):
tags = self.tags
startB = energy_scale[0]
endB = energy_scale[-1]
p = np.abs(p)
LLene = np.linspace(0, 2047,2048)
SSD = drude(LLene,p)
ssd = np.fft.fft(SSD)
ssd2 = ssd.copy()
SSD2 = SSD.copy()
### sum contribution from each order of scattering:
PSD = np.zeros(len(LLene))
for order in range(15):
# This order convoluted spectum
PPSD = np.zeros(len(LLene))
# convoluted SSD is SSD2
SSD2 = np.fft.ifft(ssd).real
# scale right (could be done better? GERD)
mult = sum(SSD)/sum(SSD2)
SSD2 *= abs(mult)
PPSD = SSD2/factorial(order+1)*np.power(tmfp,(order+1))*np.exp(-tmfp) #using equation 4.1 of egerton ed2
# Add this order to final spectrum
PSD += PPSD
# next order convolution
ssd = ssd * ssd2
cts = np.zeros(len(x))
if startB < 0:
startB = 0
BGDcoef = splrep(LLene[int(startB):int(endB)],PSD[int(startB):int(endB)],s=0)
lin = np.zeros(len(x))
cts =splev( x, BGDcoef)*p[1]
self.cor = self.EffectiveAngle(self.tags['E0'],x, self.tags['convAngle'], self.tags['collAngle'])
return cts#*self.cordef drude_simulation(dset, e, ep, ew, tnm, eb):
energy_scale = dset.get_spectral_dims(return_axis=True)[0]
dispersion = energy_scale.slope # input('ev per channel : ');
beta = dset.metadata['collection_angle'] / 1000. # rad
e0 = dset.metadata['acceleration_voltage'] / 1000. # input('incident energy e0(kev) : ');
# effective kinetic energy: T = m_o v^2/2,
t = 1000.0 * e0 * (1. + e0 / 1022.12) / (1.0 + e0 / 511.06) ** 2 # eV # equ.5.2a or Appendix E p 427
# 2 gamma T
tgt = 1000 * e0 * (1022.12 + e0) / (511.06 + e0) # eV Appendix E p 427
rk0 = 2590 * (1.0 + e0 / 511.06) * np.sqrt(2.0 * t / 511060)
os = e[0]
ew_mod = eb
tags = dset.metadata
eps = 1 - (ep ** 2 - ew_mod * e * 1j) / (e ** 2 + 2 * e * ew * 1j) # Mod drude term
eps[np.nonzero(eps == 0.0)] = 1e-19
elf = np.imag(-1 / eps)
the = e / tgt # varies with energy loss! # Appendix E p 427
# srfelf = 4..*eps2./((1+eps1).^2+eps2.^2) - elf; %equivalent
srfelf = np.imag(-4. / (1.0 + eps)) - elf # for 2 surfaces
angdep = np.arctan(beta / the) / the - beta/ (beta * beta + the * the)
srfint = angdep * srfelf / (3.1416 * 0.05292 * rk0 * t) # probability per eV
anglog = np.log(1.0 + beta * beta / the / the)
i0 = dset.sum() # *tags['counts2e']
# 2 * t = m_0 v**2 !!! a_0 = 0.05292 nm
volint = abs(tnm / (np.pi * 0.05292 * t * 2.0) * elf * anglog) # S equ 4.26% probability per eV
volint = volint * i0 / dispersion # S probability per channel
ssd = volint # + srfint;
if e[0] < -1.0:
xs = int(abs(-e[0] / dispersion))
ssd[0:xs] = 0.0
volint[0:xs] = 0.0
srfint[0:xs] = 0.0
# if os <0:
p_s = np.trapz(e, srfint) # 2 surfaces but includes negative Begrenzung contribution.
p_v = abs(np.trapz(e, abs(volint / tags['spec'].sum()))) # integrated volume probability
p_v = (volint / i0).sum() # our data have he same epc and the trapez formula does not include
lam = tnm / p_v # does NOT depend on free-electron approximation (no damping).
lamfe = 4.0 * 0.05292 * t / ep / np.log(1 + (beta * tgt / ep) ** 2) # Eq.(3.44) approximation
tags['eps'] = eps
tags['lam'] = lam
tags['lamfe'] = lamfe
tags['p_v'] = p_v
return ssd # /np.pipeak_model, p = pyTEMlib.eels_tools.gaussian_mixture_model(spectrum1, p_in=None)
print(int(len(p)/3))
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Cell In[4], line 1
----> 1 peak_model, p = pyTEMlib.eels_tools.gaussian_mixture_model(spectrum1, p_in=None)
3 print(int(len(p)/3))
NameError: name 'spectrum1' is not defined
spectrum = spectrum1.view.get_spectrum()
plt.figure()
plt.plot(spectrum, c='red')
plt.plot(peak_model, linewidth=2,c='blue')
plt.plot(spectrum-peak_model)
plt.plot((spectrum-peak_model)/np.sqrt(spectrum/20)*100)plt.figure()
plt.plot(spectrum.energy_loss, spectrum, c='r', label='experiment')
plt.plot(spectrum.energy_loss, peak_model, c='b',linewidth=2, label='model')
plt.plot(spectrum.energy_loss, (spectrum-peak_model)/np.sqrt(spectrum/20)*100, label='residuals')
for i in range(int(len(p)/3)):
plt.plot(spectrum.energy_loss, pyTEMlib.eels_tools.gauss(spectrum.energy_loss, p[i*3:(i+1)*3]), label=f'Gauss {i}')
plt.legend(loc='upper right')peakfit¶
from pyTEMlib import peak_dialog
peakFitWidget = peak_dialog.PeakFitWidget(infoWidget.datasets, infoWidget.datasets['_relationship']['low_loss'])infoWidget.datasets['_relationship']{'main_dataset': 'Channel_000',
'low_loss': 'Channel_000',
'resolution_functions': 'resolution_functions'}k = peakFitWidget.dataset-np.array(peakFitWidget.model)
v =k.plot()peakFitWidget.smooth()C:\Users\gduscher\Documents\Github\pyTEMlib\notebooks\Spectroscopy\../..\pyTEMlib\eels_tools.py:1829: RuntimeWarning: Number of calls to function has reached maxfev = 10000.
[p, _] = leastsq(residuals3, pin, args=(x, y),maxfev = 10000)
peakFitWidget.datasets.keys()dict_keys(['Channel_000', 'Channel_001', '_relationship', 'resolution_functions'])peakFitWidget.fit_peaks()C:\Users\gduscher\Documents\Github\pyTEMlib\notebooks\Spectroscopy\../..\pyTEMlib\peak_dialog.py:357: RuntimeWarning: Number of calls to function has reached maxfev = 11000.
#self.model[start_channel:end_channel] = model
C:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\jupyter_client\session.py:721: UserWarning: Message serialization failed with:
Out of range float values are not JSON compliant: nan
Supporting this message is deprecated in jupyter-client 7, please make sure your message is JSON-compliant
content = self.pack(content)
C:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\jupyter_client\session.py:721: UserWarning: Message serialization failed with:
Out of range float values are not JSON compliant: nan
Supporting this message is deprecated in jupyter-client 7, please make sure your message is JSON-compliant
content = self.pack(content)
ff = eels_tools.gmm(energy_scale, np.array(peakFitWidget.peak_out_list).flatten())
plt.figure()
plt.plot(ff)
#peakFitWidget.dataset.plot()
np.isnan(ff).sum(), np.isinf(ff).sum()peakFitWidget.peak_out_list = peak_modelplt.close('all')for index, peak in peakFitWidget.peaks['peaks'].items(): # ll
p = [peak['position'], peak['amplitude'], peak['width']]
print(p)
additional_spectra[f'peak {index}']= eels_tools.gauss(np.array(peakFitWidget.energy_scale), p)[0.25, 5595090.5, 4.747764687329006]
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Cell In[12], line 4
2 p = [peak['position'], peak['amplitude'], peak['width']]
3 print(p)
----> 4 additional_spectra[f'peak {index}']= eels_tools.gauss(np.array(peakFitWidget.energy_scale), p)
TypeError: can't unbox heterogeneous list: float64 != float32import scipy
spectrum = peakFitWidget.dataset
energy_scale = peakFitWidget.dataset.get_spectral_dims(return_axis=True)[0].values
pin = np.array(peakFitWidget.peak_out_list[:6]).flatten()
x = np.array(spectrum)
y = energy_scale
print(x.shape)
#p = scipy.optimize.least_squares(eels_tools.residuals3, pin, args=(x,y), method='lm', verbose= 2)
print(peak_model)
energy_scale[1]-energy_scale[0]
v = eels_tools.residuals3(pin, x, y)
plt.figure()
plt.plot(v)
np.isfinite(v).sum()(2048,)
[-4.83000000e+01 3.83246094e+03 2.80766823e+00 -2.13000000e+01
3.34756055e+03 2.50309866e+00 -1.36424205e-11 6.00148960e+07
1.69709218e+00 1.98000000e+01 2.50729328e+05 1.09172481e+01
8.07000000e+01 1.41388223e+04 6.03046268e+00 9.21000000e+01
1.34123496e+04 1.58681033e+00 1.15500000e+02 9.99801367e+03
1.67314163e+00 1.28400000e+02 8.61218750e+03 6.05662983e+00
1.63500000e+02 5.94440137e+03 1.55680767e+00 1.67100000e+02
5.93256055e+03 1.67007282e+00 1.98600000e+02 4.87127148e+03
1.65743531e+00 2.34600000e+02 3.18025830e+03 1.63774453e+00
2.50500000e+02 3.69103735e+03 1.52271110e+00 2.55900000e+02
3.20574658e+03 2.78972361e+00 2.67600000e+02 2.57806250e+03
2.29663513e+00 2.81100000e+02 3.54892529e+03 1.66879714e+00
3.07200000e+02 1.55079565e+03 1.95856399e+00 3.20400000e+02
2.64509766e+03 1.79741244e+00 3.40800000e+02 2.07240796e+03
2.33128935e+00 3.52500000e+02 2.45149805e+03 2.76355395e+00
3.58500000e+02 1.76404834e+03 1.98714577e+00 4.08600000e+02
1.12217920e+03 2.18032596e+00 4.11600000e+02 1.82581519e+03
1.92283312e+00 4.75800000e+02 1.60657446e+03 2.27419354e+00
4.78800000e+02 1.94508496e+03 1.82035011e+00 5.14200000e+02
1.01093506e+03 1.92720941e+00 5.42400000e+02 1.51592969e+03
2.27115801e+00 5.46300000e+02 1.11388831e+03 2.00918175e+00]
1847spectrum[spectrum<0]=10000
vv = spectrum.plot()import numpy as np
import matplotlib.pyplot as plt
from eels_tools import find_peaks
# Assuming peakFitWidget.dataset is your spectrum data
# Example data, replace with your actual spectrum
spectrum = peakFitWidget.dataset
peaks = peakFitWidget.dataset.metadata['peak_fit']
# Fit the peaks using the find_peaks function
peak_model, peak_out_list = find_peaks(spectrum, peaks['fit_start'], peaks['fit_end'])
# Extract the peak positions and amplitudes
peak_positions = [peak['center'] for peak in peak_out_list]
peak_amplitudes = [peak['amplitude'] for peak in peak_out_list]
# Plot the original spectrum
x = np.arange(len(spectrum))
plt.plot(x, spectrum, label='Original Spectrum', color='gray', alpha=0.5)
# Plot the identified peaks
for pos, amp in zip(peak_positions, peak_amplitudes):
plt.axvline(pos, color='red', linestyle=':', label=f'Peak at {pos:.2f}')
plt.plot(pos, amp, 'ro') # Mark the peak positions
plt.xlabel('Channel')
plt.ylabel('Intensity')
plt.title('Identified Peaks in Spectrum')
plt.legend()
plt.show()
# Print the peak positions for verification
print("Identified peak positions:", peak_positions)---------------------------------------------------------------------------
ModuleNotFoundError Traceback (most recent call last)
Cell In[8], line 3
1 import numpy as np
2 import matplotlib.pyplot as plt
----> 3 from eels_tools import find_peaks
5 # Assuming peakFitWidget.dataset is your spectrum data
6 # Example data, replace with your actual spectrum
7 spectrum = peakFitWidget.dataset
ModuleNotFoundError: No module named 'eels_tools'peaks = peakFitWidget.dataset.metadata['peak_fit']
peak_model, peak_out_list = eels_tools.find_peaks(peakFitWidget.dataset, peaks['fit_start'], peaks['fit_end'])C:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\numpy\core\_methods.py:206: RuntimeWarning: Degrees of freedom <= 0 for slice
ret = _var(a, axis=axis, dtype=dtype, out=out, ddof=ddof,
C:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\numpy\core\_methods.py:163: RuntimeWarning: invalid value encountered in divide
arrmean = um.true_divide(arrmean, div, out=arrmean,
C:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\numpy\core\_methods.py:198: RuntimeWarning: invalid value encountered in divide
ret = ret.dtype.type(ret / rcount)
peakFitWidget.smooth()
peakFitWidget.peak_out_listC:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\numpy\core\_methods.py:206: RuntimeWarning: Degrees of freedom <= 0 for slice
ret = _var(a, axis=axis, dtype=dtype, out=out, ddof=ddof,
C:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\numpy\core\_methods.py:163: RuntimeWarning: invalid value encountered in divide
arrmean = um.true_divide(arrmean, div, out=arrmean,
C:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\numpy\core\_methods.py:198: RuntimeWarning: invalid value encountered in divide
ret = ret.dtype.type(ret / rcount)
C:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\numpy\lib\function_base.py:520: RuntimeWarning: Mean of empty slice.
avg = a.mean(axis, **keepdims_kw)
C:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\numpy\core\_methods.py:129: RuntimeWarning: invalid value encountered in scalar divide
ret = ret.dtype.type(ret / rcount)
array([], shape=(0, 3), dtype=float64)infoWidget.datasets['_relationship']da = infoWidget.datasets[infoWidget.datasets['_relationship']['low_loss']]
gg = pyTEMlib.eels_tools.find_peaks(da, -4, 40)
C:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\numpy\core\_methods.py:206: RuntimeWarning: Degrees of freedom <= 0 for slice
ret = _var(a, axis=axis, dtype=dtype, out=out, ddof=ddof,
C:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\numpy\core\_methods.py:163: RuntimeWarning: invalid value encountered in divide
arrmean = um.true_divide(arrmean, div, out=arrmean,
C:\Users\gduscher\AppData\Local\anaconda3\Lib\site-packages\numpy\core\_methods.py:198: RuntimeWarning: invalid value encountered in divide
ret = ret.dtype.type(ret / rcount)
dir(da.view)['__bool__',
'__class__',
'__delattr__',
'__dir__',
'__doc__',
'__eq__',
'__format__',
'__ge__',
'__getattribute__',
'__getstate__',
'__gt__',
'__hash__',
'__init__',
'__init_subclass__',
'__le__',
'__lt__',
'__ne__',
'__new__',
'__reduce__',
'__reduce_ex__',
'__repr__',
'__setattr__',
'__sizeof__',
'__str__',
'__subclasshook__']da = infoWidget.datasets[infoWidget.datasets['_relationship']['low_loss']]
print(da)
da.metadata['peak_fit']sidpy.Dataset of type SPECTRAL_IMAGE with:
dask.array<setitem, shape=(23, 28, 2048), dtype=float32, chunksize=(23, 28, 2048), chunktype=numpy.ndarray>
data contains: intensity (counts)
and Dimensions:
x: distance (µm) of size (23,)
y: distance (µm) of size (28,)
energy_loss: energy-loss (eV) of size (2048,)
with metadata: ['experiment', 'peak_fit', 'zero_loss']
{'fit_start': -9.95,
'fit_end': 92.30000000000001,
'peaks': {'0': {'position': -9.95,
'amplitude': 1000.0,
'width': 1.0,
'type': 'Gauss',
'asymmetry': 0}}}gg
(array([0., 0., 0., ..., 0., 0., 0.]),
array([0.00000000e+00, 5.60210700e+06, 0.00000000e+00, 3.38997724e+00,
4.15490805e+04, 1.52867594e+00]))shifts = pyTEMlib.eels_tools.get_zero_loss_energy(infoWidget.datasets['Channel_002'])
---------------------------------------------------------------------------
KeyboardInterrupt Traceback (most recent call last)
Cell In[29], line 1
----> 1 shifts = pyTEMlib.eels_tools.get_zero_loss_energy(infoWidget.datasets['Channel_002'])
File ~\Documents\Github\pyTEMlib\notebooks\Spectroscopy\../..\pyTEMlib\eels_tools.py:340, in get_zero_loss_energy(dataset)
338 for x in range(dataset.shape[0]):
339 for y in range(dataset.shape[1]):
--> 340 _, shifts[x, y] = get_channel_zero(dataset[x, y, :], energy, width)
341 return shifts
File ~\Documents\Github\pyTEMlib\notebooks\Spectroscopy\../..\pyTEMlib\eels_tools.py:298, in get_channel_zero(spectrum, energy, width)
294 y = np.array(spectrum[int(zero-width):int(zero+width)]).copy()
296 y[np.nonzero(y <= 0)] = 1e-12
--> 298 p0 = [energy[zero], spectrum.max(), .5] # Initial guess is a normal distribution
300 def errfunc(pp, xx, yy):
301 return (gauss(xx, pp) - yy) / np.sqrt(yy) # Distance to the target function
File ~\AppData\Local\anaconda3\Lib\site-packages\sidpy\sid\dataset.py:1220, in Dataset.reduce_dims.<locals>.wrapper_method(self, *args, **kwargs)
1218 axis, keepdims = arguments.get('axis'), arguments.get('keepdims', False)
1219 if axis is None and not keepdims:
-> 1220 return result.compute()
1221 if axis is None:
1222 axes = list(np.arange(self.ndim))
File ~\AppData\Local\anaconda3\Lib\site-packages\dask\base.py:375, in DaskMethodsMixin.compute(self, **kwargs)
351 def compute(self, **kwargs):
352 """Compute this dask collection
353
354 This turns a lazy Dask collection into its in-memory equivalent.
(...)
373 dask.compute
374 """
--> 375 (result,) = compute(self, traverse=False, **kwargs)
376 return result
File ~\AppData\Local\anaconda3\Lib\site-packages\dask\base.py:661, in compute(traverse, optimize_graph, scheduler, get, *args, **kwargs)
658 postcomputes.append(x.__dask_postcompute__())
660 with shorten_traceback():
--> 661 results = schedule(dsk, keys, **kwargs)
663 return repack([f(r, *a) for r, (f, a) in zip(results, postcomputes)])
File ~\AppData\Local\anaconda3\Lib\queue.py:180, in Queue.get(self, block, timeout)
178 if remaining <= 0.0:
179 raise Empty
--> 180 self.not_empty.wait(remaining)
181 item = self._get()
182 self.not_full.notify()
File ~\AppData\Local\anaconda3\Lib\threading.py:359, in Condition.wait(self, timeout)
357 else:
358 if timeout > 0:
--> 359 gotit = waiter.acquire(True, timeout)
360 else:
361 gotit = waiter.acquire(False)
KeyboardInterrupt: import scipy
dataset = infoWidget.datasets['Channel_002']
spectrum = dataset.sum(axis=tuple(range(dataset.ndim - 1)))
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Cell In[1], line 2
1 import scipy
----> 2 dataset = infoWidget.datasets['Channel_002']
3 spectrum = dataset.sum(axis=tuple(range(dataset.ndim - 1)))
NameError: name 'infoWidget' is not definedimport scipy
dataset = infoWidget.datasets['Channel_002']
spectrum = dataset.sum(axis=tuple(range(dataset.ndim - 1)))
startx = scipy.signal.find_peaks(spectrum/np.max(spectrum), height=0.98)[0][0]
end = startx + 3
start = startx - 3
for i in range(10):
if spectrum[startx - i] < 0.3 * spectrum[startx]:
start = startx - i
if spectrum[startx + i] < 0.3 * spectrum[startx]:
end = startx + i
if end - start < 7:
end = startx + 4
start = startx - 4
energy = dataset.get_spectral_dims(return_axis=True)[0].values
if dataset.ndim == 1: # single spectrum
_, shifts = pyTEMlib.eels_tools.get_channel_zero(np.array(dataset), energy, width)
shifts = np.array([shifts])
elif dataset.ndim == 2: # line scan
shifts = np.zeros(dataset.shape[:1])
for x in range(dataset.shape[0]):
_, shifts[x] = pyTEMlib.eels_tools.get_channel_zero(dataset[x, :], energy, width)
elif dataset.ndim == 3: # spectral image
shifts = np.zeros(dataset.shape[:2])
for x in range(dataset.shape[0]):
for y in range(dataset.shape[1]):
_, shifts[x, y] = pyTEMlib.eels_tools.get_channel_zero(dataset[x, y, :], energy, width)
shifts210 202 8
4
array([[0.27885956, 0.27191713, 0.28913556, 0.25769037, 0.2942762 ,
0.28620583, 0.33639917, 0.29324584, 0.23019431, 0.24396385,
0.28630434, 0.34782575, 0.29164501, 0.32428319, 0.31925456,
0.33853458, 0.34647511, 0.31610986, 0.38146446, 0.31699432,
0.34575115, 0.35986766, 0.33364593, 0.33229606, 0.34956855,
0.33242329, 0.3915634 , 0.35407163],
[0.29500225, 0.2373293 , 0.25763805, 0.28486225, 0.31641727,
0.29900238, 0.28421314, 0.27215118, 0.25969281, 0.23715325,
0.3184073 , 0.29690798, 0.27968236, 0.32664399, 0.27429016,
0.30321827, 0.33636393, 0.33146419, 0.37165488, 0.31699942,
0.32685554, 0.37155651, 0.31661427, 0.34338988, 0.33284669,
0.31143029, 0.41046077, 0.35855505],
[0.29311011, 0.22077191, 0.3060771 , 0.27921994, 0.28125945,
0.3067318 , 0.26348024, 0.25086256, 0.25962378, 0.2529393 ,
0.31787102, 0.29516299, 0.28017314, 0.3592165 , 0.267943 ,
0.30651435, 0.33832316, 0.31661111, 0.34534481, 0.28676643,
0.33204225, 0.35063015, 0.34971729, 0.36301199, 0.35443506,
0.34508562, 0.41291565, 0.32720252],
[0.27862603, 0.2395802 , 0.27097475, 0.29844929, 0.32480325,
0.31210681, 0.30410157, 0.31895698, 0.25131819, 0.21974032,
0.26824316, 0.3026477 , 0.33016488, 0.36298262, 0.27516956,
0.32761501, 0.34910861, 0.30489061, 0.33654038, 0.27761667,
0.34485607, 0.41076118, 0.35082191, 0.41209721, 0.36572742,
0.35657333, 0.4043328 , 0.3366633 ],
[0.28915177, 0.25477428, 0.25937191, 0.28322656, 0.33555691,
0.31758257, 0.27861604, 0.25593468, 0.30145909, 0.21596642,
0.27045277, 0.28342595, 0.33550093, 0.37912592, 0.27235156,
0.29138667, 0.35342075, 0.3278171 , 0.33455263, 0.29913195,
0.35593614, 0.37443954, 0.3313424 , 0.39522888, 0.34047513,
0.34615577, 0.37257263, 0.35127896],
[0.26825451, 0.22317499, 0.27205782, 0.28977687, 0.31335867,
0.29903467, 0.30730622, 0.2254166 , 0.2501397 , 0.29506912,
0.29580712, 0.33147555, 0.3211084 , 0.34653584, 0.28070157,
0.29066366, 0.3425898 , 0.29964388, 0.33541241, 0.33303188,
0.32264911, 0.39229919, 0.34502718, 0.39487492, 0.36778998,
0.35605888, 0.3360836 , 0.34104887],
[0.25465607, 0.24582089, 0.29155236, 0.26238632, 0.29120902,
0.28021102, 0.2754898 , 0.24523182, 0.26776028, 0.31574981,
0.28385829, 0.28627776, 0.30463114, 0.32875661, 0.30105687,
0.3067776 , 0.30641951, 0.31796401, 0.31963128, 0.32909494,
0.36074269, 0.37515573, 0.34797653, 0.39295098, 0.35302315,
0.36683995, 0.36417993, 0.35364533],
[0.292511 , 0.23258882, 0.27376865, 0.2377322 , 0.28899703,
0.26824193, 0.27879703, 0.24322802, 0.27464024, 0.25538418,
0.25901674, 0.28047969, 0.29715362, 0.37488464, 0.25447685,
0.29050186, 0.30640089, 0.31729175, 0.33839128, 0.31065224,
0.37427601, 0.36502753, 0.35191241, 0.37469867, 0.34486259,
0.37088215, 0.34637744, 0.36111888],
[0.25635235, 0.27019416, 0.27881258, 0.24296847, 0.2439347 ,
0.26863875, 0.29996595, 0.25947241, 0.23179607, 0.25717334,
0.27921191, 0.30023848, 0.30469099, 0.31963415, 0.26250042,
0.3366933 , 0.31913805, 0.30438372, 0.35728285, 0.32887884,
0.35544641, 0.39674351, 0.34704318, 0.34718202, 0.34885386,
0.38141548, 0.36582743, 0.37162835],
[0.2779227 , 0.22507787, 0.25349302, 0.2489468 , 0.2574619 ,
0.24933503, 0.30956108, 0.29125198, 0.22917259, 0.2696706 ,
0.26321472, 0.29098226, 0.31207799, 0.31331197, 0.25208947,
0.3258606 , 0.37896905, 0.33075093, 0.34549619, 0.3101756 ,
0.38049917, 0.37980949, 0.32037619, 0.33618086, 0.35437024,
0.4081252 , 0.36734162, 0.39830539],
[0.28461448, 0.23650725, 0.26976286, 0.29007012, 0.23048943,
0.28403545, 0.28856561, 0.27275457, 0.26200055, 0.3145652 ,
0.28347842, 0.32009059, 0.31970605, 0.3433159 , 0.34734224,
0.32442136, 0.35281421, 0.31881861, 0.34979143, 0.32597294,
0.38637679, 0.35346344, 0.34316713, 0.37039857, 0.33056786,
0.37906996, 0.3923285 , 0.40072191],
[0.25815332, 0.25105465, 0.26434024, 0.24352999, 0.23606594,
0.25148725, 0.28777328, 0.29084688, 0.25366795, 0.27467238,
0.3378339 , 0.30900469, 0.2893221 , 0.31765853, 0.29397576,
0.33832071, 0.3457589 , 0.28472426, 0.35705654, 0.32174799,
0.38509935, 0.35920384, 0.36480676, 0.34173499, 0.35504551,
0.38998532, 0.38938545, 0.39183795],
[0.25616929, 0.27615618, 0.24044875, 0.27103228, 0.24235239,
0.2725113 , 0.2773447 , 0.29618213, 0.26213574, 0.2538839 ,
0.33352775, 0.26730384, 0.33472612, 0.35442554, 0.26483493,
0.31008077, 0.36259978, 0.29427468, 0.33403016, 0.34279215,
0.35625539, 0.34078648, 0.3623414 , 0.38548391, 0.36306584,
0.37939006, 0.36419213, 0.40813366],
[0.29477027, 0.29242067, 0.26208898, 0.22938211, 0.27008024,
0.26164282, 0.3395756 , 0.27354599, 0.24859205, 0.24623638,
0.28822334, 0.30557938, 0.29082779, 0.32814678, 0.29866092,
0.28825318, 0.31326961, 0.32114773, 0.32831089, 0.33195336,
0.33213739, 0.33702476, 0.38874667, 0.34270549, 0.35165803,
0.36284347, 0.33104932, 0.3598648 ],
[0.31484983, 0.27133482, 0.2796955 , 0.22614179, 0.25680333,
0.30342777, 0.31641074, 0.26352313, 0.27141102, 0.24704663,
0.29384235, 0.30671874, 0.29041037, 0.32165614, 0.32233128,
0.27004443, 0.34106865, 0.29358258, 0.30716426, 0.32627813,
0.34667117, 0.36114773, 0.36030183, 0.36726092, 0.31770244,
0.38873846, 0.35912585, 0.3779826 ],
[0.2745227 , 0.26616718, 0.23300789, 0.2661543 , 0.24198659,
0.26366613, 0.29255209, 0.26413508, 0.26059787, 0.26943424,
0.29420278, 0.29869293, 0.29239094, 0.27523946, 0.30449244,
0.26214181, 0.34524763, 0.30401337, 0.35973117, 0.33170239,
0.38205601, 0.36911811, 0.39509115, 0.35899128, 0.39090857,
0.37103475, 0.35419947, 0.36533401],
[0.25355474, 0.26453087, 0.24993006, 0.26617811, 0.26285823,
0.25894022, 0.29097809, 0.23530484, 0.2826482 , 0.24949959,
0.30660538, 0.25883084, 0.33691935, 0.28690654, 0.30184456,
0.3005378 , 0.27657854, 0.32545669, 0.3350722 , 0.32765956,
0.37492385, 0.34372024, 0.37620028, 0.3605306 , 0.34733479,
0.35119791, 0.35081045, 0.36945515],
[0.27058115, 0.29535405, 0.25933533, 0.24603051, 0.27246679,
0.27980309, 0.28700856, 0.22413112, 0.27118666, 0.28379198,
0.29113244, 0.28228985, 0.32547475, 0.29481563, 0.32189973,
0.29346086, 0.30910825, 0.33896943, 0.32250085, 0.35293158,
0.33332329, 0.34810451, 0.37229999, 0.37011539, 0.36788494,
0.32506948, 0.35174691, 0.39071821],
[0.25202181, 0.31131463, 0.24169004, 0.26346343, 0.22033775,
0.21069325, 0.31788773, 0.24929155, 0.28026672, 0.30283353,
0.32265208, 0.29598524, 0.33788357, 0.28828424, 0.29400025,
0.32044516, 0.32719666, 0.33894647, 0.33687651, 0.34735657,
0.35248941, 0.33570986, 0.36135229, 0.33214425, 0.35519827,
0.33985382, 0.33577196, 0.39142653],
[0.25719734, 0.28636417, 0.24679422, 0.25859183, 0.24966211,
0.29170404, 0.28522151, 0.23880383, 0.27825976, 0.28674107,
0.29818576, 0.26381539, 0.34813009, 0.26624489, 0.29720147,
0.30763793, 0.32224644, 0.32006327, 0.31661701, 0.38357174,
0.38138782, 0.31708329, 0.37834823, 0.34931166, 0.33390342,
0.30967558, 0.34603018, 0.38542046],
[0.26717053, 0.3187942 , 0.25688932, 0.26465117, 0.23794704,
0.28813324, 0.29058177, 0.24887995, 0.2133812 , 0.2922364 ,
0.3170021 , 0.27667117, 0.32899053, 0.30647512, 0.30744492,
0.30315152, 0.32894605, 0.36010006, 0.31707008, 0.34071347,
0.34518802, 0.2864612 , 0.32752686, 0.37130934, 0.33076248,
0.32663139, 0.33336231, 0.35315843],
[0.3171484 , 0.32838144, 0.26763272, 0.25482452, 0.24839447,
0.22693682, 0.25846255, 0.23695833, 0.24745501, 0.28812388,
0.30393928, 0.31321126, 0.2949203 , 0.30777781, 0.34019723,
0.32201243, 0.3350535 , 0.36631547, 0.32803027, 0.35022398,
0.33984022, 0.29018393, 0.35647662, 0.34727768, 0.30282655,
0.34913906, 0.36157026, 0.38905264],
[0.29772264, 0.31244 , 0.25824082, 0.2633365 , 0.29358153,
0.2853858 , 0.31198789, 0.25574126, 0.23576208, 0.33307473,
0.28249016, 0.30273328, 0.27431271, 0.31244071, 0.32128821,
0.31963668, 0.34839687, 0.35969038, 0.34473335, 0.34859848,
0.35485971, 0.3338992 , 0.35779789, 0.33342661, 0.32066506,
0.38048255, 0.35227182, 0.37892143]])dir(infoWidget.info.shift_low_loss)['__call__',
'__class__',
'__delattr__',
'__dir__',
'__doc__',
'__eq__',
'__format__',
'__func__',
'__ge__',
'__getattribute__',
'__getstate__',
'__gt__',
'__hash__',
'__init__',
'__init_subclass__',
'__le__',
'__lt__',
'__ne__',
'__new__',
'__reduce__',
'__reduce_ex__',
'__repr__',
'__self__',
'__setattr__',
'__sizeof__',
'__str__',
'__subclasshook__']import uuid
import time
# Combine UUID and timestamp
unique_id = f"{uuid.uuid4()}_{int(time.time() * 1000)}"
print(unique_id)
8aef8a91-2b7f-4834-a33b-c2c0b88d3b77_1715976165623
infoWidget.core_loss.update_cl_dataset()infoWidget.datasets['resolution_functions'].metadata{'experiment': {'single_exposure_time': 0.01,
'exposure_time': 0.21,
'number_of_frames': 21,
'collection_angle': 33.0,
'convergence_angle': 30.0,
'acceleration_voltage': 0.0,
'flux_ppm': 115.68867492675781,
'count_conversion': 1,
'beam_current': 0},
'zero_loss': {'shifted': array([1.0174319]),
'startFitEnergy': -1.0,
'endFitEnergy': 1.0,
'fit_parameter': array([-1.51964411e-01, 5.09698919e+03, 1.33700815e+00, 2.38917861e-01,
5.06085447e+03, 1.72056710e+00]),
'original_low_loss': '1EELS Acquire (low-loss)_new'}}infoWidget.datasets['Channel_000'].metadata{'experiment': {'single_exposure_time': 3.0,
'exposure_time': 63.0,
'number_of_frames': 21,
'collection_angle': 50.0,
'convergence_angle': 30.0,
'acceleration_voltage': 60000.0,
'flux_ppm': 34706.602478027344,
'count_conversion': 1,
'beam_current': 0},
'zero_loss': {'shifted': array([1.0174319])},
'edges': {'fit_area': {'fit_start': 120.0, 'fit_end': 600.0},
'0': {'z': 5,
'symmetry': 'K1',
'element': 'B',
'onset': 188.0,
'end_exclude': 238.0,
'start_exclude': 185.0,
'all_edges': {'K1': {'onset': 188.0}},
'chemical_shift': 0.0,
'areal_density': 1745395038619.995,
'original_onset': 188.0,
'data': array([5.66032845e-09, 5.61175423e-09, 5.56318001e-09, ...,
1.68366704e-10, 1.68110794e-10, 1.67854883e-10]),
'X_section_type': 'XRPA',
'X_section_source': 'pyTEMlib'},
'1': {'z': 7,
'symmetry': 'K1',
'element': 'N',
'onset': 401.6,
'end_exclude': 451.6,
'start_exclude': 396.6,
'all_edges': {'K1': {'onset': 401.6}},
'chemical_shift': 0.0,
'areal_density': 5330240008575.439,
'original_onset': 401.6,
'data': array([2.25376447e-08, 2.23462509e-08, 2.21548571e-08, ...,
5.61435758e-10, 5.60622520e-10, 5.59809282e-10]),
'X_section_type': 'XRPA',
'X_section_source': 'pyTEMlib'},
'model': {'background': energy_loss: energy-loss (eV) of size (2048,),
'background-poly_0': -7789207450.593016,
'background-poly_1': -92.67688006132725,
'background-poly_2': 0.07927340377406612,
'background-A': 7789231272.866521,
'background-r': -13.743081547476294,
'spectrum': energy_loss: energy-loss (eV) of size (2048,),
'blurred': array([139757.55 , 139617.84 , 139350.38 , ..., 658.92535,
628.73956, 612.56323], dtype=float32),
'mask': array([0., 0., 0., ..., 0., 0., 1.]),
'fit_parameter': array([ 7.78923127e+09, -1.37430815e+01, -7.78920745e+09, -9.26768801e+01,
7.92734038e-02, 1.74529850e+12, 5.33029998e+12]),
'fit_area_start': 120.0,
'fit_area_end': 600.0}}}plt.close('all')infoWidget.spectrum
ll = infoWidget.low_loss.dataset
zero_loss_fit_width = infoWidget.low_loss.low_loss_tab[5, 0].value
print(zero_loss_fit_width)
ll.plot()
#vplt.plot(ll.energy_loss, ll)0.3

infoWidget.datasets['resolution_functions'].metadata{'experiment': {'single_exposure_time': 0.01,
'exposure_time': 0.21,
'number_of_frames': 21,
'collection_angle': 0.0,
'convergence_angle': 30.0,
'acceleration_voltage': 0.0,
'flux_ppm': 115.68867492675781,
'count_conversion': 1,
'beam_current': 0},
'zero_loss': {'shifted': array([1.0174319]),
'startFitEnergy': -0.3,
'endFitEnergy': 0.3,
'fit_parameter': array([-1.49985841e-01, 2.33687317e+03, 1.33828265e+00, 2.36651224e-01,
1.09947513e+04, 1.72584231e+00]),
'original_low_loss': '1EELS Acquire (low-loss)_new'}}s = infoWidget.low_loss.parent.dataset
energy_offset = s.get_spectral_dims(return_axis=True)[0][0]
energy_offsetview = core_loss.plot()
core_loss.metadata['zero_loss']['shifted']---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Cell In[25], line 1
----> 1 view = core_loss.plot()
3 core_loss.metadata['zero_loss']['shifted']
NameError: name 'core_loss' is not definedfrom tqdm import tqdm, trange, auto
dataset = infoWidget.selected_dataset
dataset.original_metadata.keys()
dataset_np = np.array(dataset)
for i in trange(1,len(dataset.energy_loss)-1):
if np.abs(dataset_np[i] - dataset_np[i+1]) > 1e3 and np.abs(dataset_np[i] - dataset_np[i-1]) > 1e3:
dataset_np[i] = (dataset_np[i-1] + dataset_np[i+1])/2
pass
core_loss = dataset.like_data(dataset_np)
core_loss = eels_tools.shift_energy(core_loss, np.array([-0.2791726]))
view = core_loss.plot()100%|██████████████████████████████████████████████████████████████████████████| 2046/2046 [00:00<00:00, 130983.97it/s]
background, p = eels_tools.power_law_background(core_loss, core_loss.energy_loss, [250, 278])
spectrum = core_loss-background
spectrum.metadata = dataset.metadata.copy()
dataset.plot()
plt.gca().plot(spectrum.energy_loss, background)
plt.gca().plot(spectrum.energy_loss, spectrum)Everything we did in the dashboard above we do now one by one:
Fix energy scale and determine resolution function¶
please see Fitting the Zero-Loss Peak for details
Determine Relative Thickness¶
The probabaility of an low-loss function in a solid angle is then:
See Notebook: Analysing Low-Loss Spectra with Drude Theory of the MSE672-Introduction-to-TEM Lecture in my Github account.
low_loss = eels_tools.align_zero_loss(infoWidget.selected_dataset)
zero_loss = eels_tools.get_resolution_functions(low_loss, -.5, .5)
plt.close('all')
plt.figure()
plt.plot(low_loss.energy_loss, zero_loss, label='resolution funcion')
plt.plot(low_loss.energy_loss, low_loss, label = 'spectrum')
plt.plot(low_loss.energy_loss, low_loss-zero_loss, label = 'difference')
plt.legend()[-0.23899302] sidpy.Dataset of type SPECTRUM with:
dask.array<array, shape=(2048,), dtype=float32, chunksize=(2048,), chunktype=numpy.ndarray>
data contains: intensity (counts)
and Dimensions:
energy_loss: energy-loss (eV) of size (2048,)
with metadata: ['experiment']
infoWidget.dataset.metadata{'experiment': {'acceleration_voltage': 200000.0,
'beam_current': 0,
'collection_angle': 50.0,
'convergence_angle': 30.0,
'count_conversion': 1,
'exposure_time': 10.0,
'flux_ppm': 0.0,
'number_of_frames': 10000,
'single_exposure_time': 0.001},
'peak_fit': {'edge_model': array([0., 0., 0., ..., 0., 0., 0.]),
'fit_end': 30.0,
'fit_start': 1.0,
'peak_model': array([0., 0., 0., ..., 0., 0., 0.]),
'peak_out_list': array([[1.14401631e+01, 2.92439760e+06, 2.45501896e+01],
[7.97104419e-01, 2.89095444e+07, 1.71055819e+00]]),
'peaks': {'0': {'amplitude': 20986284.461096264,
'associated_edge': '',
'position': 0.8433632583641564,
'type': 'Gauss',
'width': 1.6347046209768021,
'asymmetry': 0.0},
'1': {'amplitude': 60297550.94024267,
'associated_edge': '',
'asymmetry': 0.0,
'position': 0.3943234078051374,
'type': 'Gauss',
'width': 0.8462042318305517},
'2': {'amplitude': 5149807.779796465,
'associated_edge': '',
'position': 4.681561552802686,
'type': 'Gauss',
'width': 3.805046085043105,
'asymmetry': 0.0},
'3': {'amplitude': 1768787.351821872,
'associated_edge': '',
'position': 15.717359457313327,
'type': 'Gauss',
'width': 5.034726824660322,
'asymmetry': 0.0},
'4': {'amplitude': 1860806.817558061,
'associated_edge': '',
'asymmetry': 0.0,
'position': 18.651735459709663,
'type': 'Gauss',
'width': 9.474450049577818},
'5': {'amplitude': 871061.5868498409,
'associated_edge': '',
'position': 27.65565717924107,
'type': 'Gauss',
'width': 11.173122920182822,
'asymmetry': 0.0},
'6': {'amplitude': 747444.1958128264,
'associated_edge': '',
'asymmetry': 0.0,
'position': 15.508181435473912,
'type': 'Gauss',
'width': 1.0964231231036516},
'7': {'amplitude': 582735.7941706154,
'associated_edge': '',
'position': 8.793443515617403,
'type': 'Gauss',
'width': 3.2503281905987924,
'asymmetry': 0.0},
'8': {'amplitude': 1490223.5949046034,
'associated_edge': '',
'asymmetry': 0.0,
'position': 5.072798469661356,
'type': 'Gauss',
'width': 0.8350422095351262},
'9': {'amplitude': 4264163.850603235,
'associated_edge': '',
'asymmetry': 0.0,
'position': 2.27260716852653,
'type': 'Gauss',
'width': 1.7783602300920873}}},
'zero_loss': {'endFitEnergy': 0.5,
'fit_parameter': array([ 1.55362639e-01, 1.46387345e+05, 4.26253898e-01, -7.36465028e-02,
2.54673199e+05, 2.91093028e-01]),
'original_low_loss': 'EELS_0290_new',
'shifted': array([-0.2791726]),
'startFitEnergy': -0.5}}peakfit¶
from pyTEMlib import peak_dialog
peakFitWidget = peak_dialog.PeakFitWidget({'low_loss':infoWidget.dataset})from pyTEMlib import peak_dialog¶
peakFitWidget = peak_dialog.PeakFitWidget({'core_loss': spectrum})fi.metadata
{'experiment': {'single_exposure_time': 5.0,
'exposure_time': 100.0,
'number_of_frames': 20,
'collection_angle': 50.0,
'convergence_angle': 5.4,
'acceleration_voltage': 60000.0,
'flux_ppm': 1470027.5390625,
'count_conversion': 1,
'beam_current': 0}}datasets = {'core_loss': spectrum, 'dataset': core_loss}
low_loss.metadata = infoWidget.selected_dataset.metadata
peakFitWidget = peak_dialog.PeakFitWidget(datasets)datasets = {'core_loss': spectrum, 'dataset': core_loss}
pyTEMlib.file_tools.save_dataset(datasets)C:\Users\gduscher\AppData\Local\anaconda3\envs\py11\Lib\site-packages\pyNSID\io\hdf_utils.py:381: FutureWarning: validate_h5_dimension may be removed in a future version
warn('validate_h5_dimension may be removed in a future version',
C:\Users\gduscher\AppData\Local\anaconda3\envs\py11\Lib\site-packages\pyNSID\io\hdf_utils.py:381: FutureWarning: validate_h5_dimension may be removed in a future version
warn('validate_h5_dimension may be removed in a future version',
<HDF5 group "/Measurement_000" (2 members)>
model = spectrum.metadata['peak_fit']['peak_model'].copy()
spectrum.energy_loss -= 250
spectrum.energy_loss *= 0.05
spectrum.energy_loss += 250
import scipy
help(eels_tools.gauss)
gauss = eels_tools.gauss(spectrum.energy_loss, [spectrum.energy_loss[1024], 1, .2])
gauss2 = eels_tools.gauss(spectrum.energy_loss, [spectrum.energy_loss[1024], 1, .1])
plt.figure()
plt.plot(gauss)
plt.plot(model)Help on function gauss in module pyTEMlib.eels_tools:
gauss(x, p)
Gaussian Function
p[0]==mean, p[1]= amplitude p[2]==fwhm
area = np.sqrt(2* np.pi)* p[1] * np.abs(p[2] / 2.3548)
FWHM = 2 * np.sqrt(2 np.log(2)) * sigma = 2.3548 * sigma
sigma = FWHM/3548
spectrum.energy_loss.values[:4]array([12.5 , 12.55, 12.6 , 12.65])spectrum = infoWidget.dataset.copy()
model = spectrum.metadata['peak_fit']['peak_model']
zero_loss = np.array(np.roll(zero_loss, -np.argmax(np.array(zero_loss))))
j = np.fft.fft(model/model.sum())
z = np.fft.fft(zero_loss/zero_loss.sum()+1e-12)
#z2 = np.fft.fft(gauss2/gauss2.sum()*2)
red =(np.fft.ifft(j/z).real)#
plt.figure()
plt.plot(spectrum.energy_loss, red/red.sum(), label='deconvoluted', linewidth=3)
#plt.plot(zero_loss/zero_loss.sum())
plt.plot(spectrum.energy_loss, model/model.sum(), label='Gaussian mixing')
# plt.plot(red-model)
plt.ylim(0,.005)
plt.legend()for peak in spectrum.metadata['peak_fit']['peaks'].values():
print (f"{peak['position']:.1f}, {peak['width']:.2f}, {peak['amplitude']:.0f}")285.8, 1.15, 58843
304.8, 13.34, 77560
293.0, 2.01, 80868
292.1, 0.64, 74606
296.5, 6.59, 64373
301.8, 2.73, 12192
308.9, 2.47, 3753
287.2, 2.06, 13455
290.2, 0.99, 6659
329.1, 26.32, 40827
289.0, 1.82, 11961
peakFitWidget.fit_peaks()
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Cell In[29], line 1
----> 1 peakFitWidget.fit_peaks()
NameError: name 'peakFitWidget' is not definedplt.close('all')
plt.figure()
plt.plot(peakFitWidget.energy_scale,peakFitWidget.peak_model, label='model')
plt.plot(peakFitWidget.energy_scale,peakFitWidget.dataset, label='spectrum')
plt.plot(peakFitWidget.energy_scale, peakFitWidget.dataset-peakFitWidget.peak_model-resolution_functions, label='dif')
plt.ylim(-4e7,1e8)
plt.legend()dataset = peakFitWidget.dataset
peak_model, peak_out_list = find_peaks(dataset-resolution_functions, -1, 30)
print(peak_out_list.reshape([int(len(peak_out_list)/3),3]))
plt.figure()
plt.plot(peak_model)
plt.plot(dataset-resolution_functions)---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
Cell In[215], line 2
1 dataset = peakFitWidget.dataset
----> 2 peak_model, peak_out_list = find_peaks(dataset-resolution_functions, -1, 30)
3 print(peak_out_list.reshape([int(len(peak_out_list)/3),3]))
4 plt.figure()
ValueError: too many values to unpack (expected 2)infoWidget.datasets['Channel_000'].metadata{'experiment': {'single_exposure_time': 5.0,
'exposure_time': 100.0,
'number_of_frames': 20,
'collection_angle': 50.0,
'convergence_angle': 5.42,
'acceleration_voltage': 60000.0,
'flux_ppm': 1477088.59375,
'count_conversion': 1,
'beam_current': 0},
'zero_loss': {'shifted': array([-0.2791726])},
'peak_fit': {'fit_start': 270.05000372603536,
'fit_end': 350.3000052496791,
'peaks': {'0': {'position': 285.5328133398505,
'amplitude': 56813.851980084386,
'width': 1.1447315680844505,
'type': 'Gauss',
'associated_edge': '',
'asymmetry': 0.0},
'1': {'position': 291.8502789181616,
'amplitude': 80137.36537116366,
'width': 0.631699853337263,
'type': 'Gauss',
'associated_edge': '',
'asymmetry': 0.0},
'2': {'position': 292.68460898549887,
'amplitude': 67856.46722391486,
'width': 1.6722959462172458,
'type': 'Gauss',
'associated_edge': '',
'asymmetry': 0.0},
'3': {'position': 288.33077096412796,
'amplitude': 15200.2171172901,
'width': 4.03592603054892,
'type': 'Gauss',
'associated_edge': '',
'asymmetry': 0.0},
'4': {'position': 300.97498872546737,
'amplitude': 29204.484305388254,
'width': 2.9452493043214063,
'type': 'Gauss',
'associated_edge': '',
'asymmetry': 0.0},
'5': {'position': 431.4963301648659,
'amplitude': 62303.24268512067,
'width': 160.13636902692892,
'type': 'Gauss',
'associated_edge': '',
'asymmetry': 0.0},
'6': {'position': 297.57744196974863,
'amplitude': 82438.00185689674,
'width': 4.570549606775482,
'type': 'Gauss',
'associated_edge': '',
'asymmetry': 0.0},
'7': {'position': 306.55294236999856,
'amplitude': 64324.25014690288,
'width': 8.408828675311156,
'type': 'Gauss',
'associated_edge': '',
'asymmetry': 0.0},
'8': {'position': 327.23866847395425,
'amplitude': 24332.78308524786,
'width': 16.520135069307326,
'type': 'Gauss',
'associated_edge': '',
'asymmetry': 0.0},
'9': {'position': 302.73254089477655,
'amplitude': 30379.325543758885,
'width': 4.215055093093726,
'type': 'Gauss',
'associated_edge': '',
'asymmetry': 0.0},
'10': {'position': 313.39578279938394,
'amplitude': 13507.040368003669,
'width': 9.086317779116715,
'type': 'Gauss',
'associated_edge': '',
'asymmetry': 0.0},
'11': {'position': 293.7938526566573,
'amplitude': 56893.252049088034,
'width': 3.7967168653233117,
'type': 'Gauss',
'associated_edge': '',
'asymmetry': 0.0}},
'edge_model': array([0., 0., 0., ..., 0., 0., 0.]),
'peak_model': array([0., 0., 0., ..., 0., 0., 0.])}}import scipy
def residuals_ll(p, x, y, only_positive_intensity):
"""part of fit"""
err = (y - model_ll(x, p, only_positive_intensity)) / np.sqrt(np.abs(y))
return err
def model_ll(x, p, only_positive_intensity):
"""part of fit"""
y = np.zeros(len(x))
number_of_peaks = int(len(p) / 3)
for i in range(number_of_peaks):
if only_positive_intensity:
p[i * 3 + 1] = abs(p[i * 3 + 1])
p[i * 3 + 2] = abs(p[i * 3 + 2])
if p[i * 3 + 2] > abs(p[i * 3]) * 4.29193 / 2.0:
p[i * 3 + 2] = abs(p[i * 3]) * 4.29193 / 2. # ## width cannot extend beyond zero, maximum is FWTM/2
y = y + gauss(x, p[i * 3:])
return y
def gauss(x, p): # p[0]==mean, p[1]= amplitude p[2]==fwhm,
"""Gaussian Function
p[0]==mean, p[1]= amplitude p[2]==fwhm
area = np.sqrt(2* np.pi)* p[1] * np.abs(p[2] / 2.3548)
FWHM = 2 * np.sqrt(2 np.log(2)) * sigma = 2.3548 * sigma
sigma = FWHM/3548
"""
if p[2] == 0:
return x * 0.
else:
return p[1] * np.exp(-(x - p[0]) ** 2 / (2.0 * (p[2] / 2.3548) ** 2))
def find_peaks(dataset, fit_start, fit_end):
energy_scale = dataset.get_spectral_dims(return_axis=True)[0].values
start_channel = np.searchsorted(energy_scale, fit_start)
end_channel = np.searchsorted(energy_scale, fit_end)
spectrum = np.abs(np.array(dataset)[start_channel:end_channel])
i_pk = scipy.signal.find_peaks_cwt(spectrum, widths=range(3, len(energy_scale) // 30)) #
p_in = np.ravel([[energy_scale[i]-fit_start, spectrum[i], .7] for i in i_pk])
return p_in
def fit_peaks(spectrum, pin, start_fit, end_fit, only_positive_intensity=False):
energy_scale = spectrum.get_spectral_dims(return_axis=True)[0]
start_fit = np.searchsorted(energy_scale, start_fit)
end_fit = np.searchsorted(energy_scale, end_fit)
fit_energy = energy_scale[start_fit:end_fit]
spectrum = np.array(spectrum)
fit_spectrum = spectrum[start_fit:end_fit]
#pin_flat = [item for sublist in pin for item in sublist]
[p_out, _] = leastsq(residuals_ll, np.array(pin), args=(fit_energy, fit_spectrum,
only_positive_intensity))
#p_out, pcov = curve_fit(residuals_ll, fit_energy, fit_spectrum, p0=np.array(pin))
p = []
for i in range(int(len(pin)/3)):
if only_positive_intensity:
p_out[i * 3 + 1] = abs(p_out[i * 3 + 1])
p.append([p_out[i * 3], p_out[i * 3 + 1], abs(p_out[i * 3 + 2])])
return p_out
fit_end = 40
peak_out_list = find_peaks(infoWidget.selected_dataset-resolution_functions, -1, fit_end)
p = fit_peaks(dataset-resolution_functions,peak_out_list,-1, fit_end)
model = model_ll(energy_scale,np.array(p), False)
print(len(peak_out_list)/3)
print(fit_end)
print(p.reshape([int(len(p)/3),3]))
print(len(p)/3)
plt.figure()
plt.plot(energy_scale, model)
plt.plot(energy_scale, dataset-resolution_functions)
plt.plot(energy_scale, dataset-resolution_functions-model)
plt.ylim(0,1e8)
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Cell In[28], line 73
69 return p_out
72 fit_end = 40
---> 73 peak_out_list = find_peaks(infoWidget.selected_dataset-resolution_functions, -1, fit_end)
74 p = fit_peaks(dataset-resolution_functions,peak_out_list,-1, fit_end)
75 model = model_ll(energy_scale,np.array(p), False)
NameError: name 'resolution_functions' is not definedpeak_out_list2 = find_peaks(infoWidget.selected_dataset-resolution_functions-model, -1, fit_end)
peak_out_list = np.append(peak_out_list,peak_out_list2)
print(len(peak_out_list)/3)
p = fit_peaks(dataset-resolution_functions,peak_out_list,-1, fit_end )
model = model_ll(energy_scale,np.array(p), False)
model2 = model_ll(energy_scale,np.array(peak_out_list2), False)
print(np.std(np.array(dataset-resolution_functions)-model))
print(len(p)/3)
plt.figure()
plt.plot(energy_scale, model+resolution_functions, label='model')
plt.plot(energy_scale, model2, label='model1')
plt.plot(energy_scale, dataset, label='spectrum')
plt.plot(energy_scale, dataset-resolution_functions-model, label='difference')
plt.ylim(0,1e8)
plt.legend()23.0
1877529801.672969
23.0
C:\Users\gduscher\AppData\Local\anaconda3\envs\py11\Lib\site-packages\scipy\optimize\_minpack_py.py:494: RuntimeWarning: Number of calls to function has reached maxfev = 14000.
warnings.warn(errors[info][0], RuntimeWarning)
model[:130] = 0.
model2_f = scipy.fft.fft(np.array(dataset)) #model+np.array(resolution_functions))
res_f =scipy.fft.fft(np.array(resolution_functions))
smear = gauss(energy_scale, [0,1, .2])
smear *= resolution_functions.sum()/smear.sum()
gaus_f = scipy.fft.fft(smear) # p[0]==mean, p[1]= amplitude p[2]==fwhm,
model2 = scipy.fft.ifft(model2_f/res_f*gaus_f).real
print(model2)
#model2 = model+np.array(resolution_functions)
print(model2.shape)
print(len(p)/3)
plt.figure()
plt.plot(energy_scale, model+resolution_functions, label='model')
plt.plot(energy_scale, model2, label='model1')
plt.plot(energy_scale, dataset, label='spectrum')
plt.plot(energy_scale, dataset-resolution_functions-model, label='difference')
plt.ylim(0,1e8)
plt.legend()[-1198221.9850117 2628210.59194557 4581554.52393588 ...
-2260492.70274396 -2410574.75171163 -2582093.5075449 ]
(2048,)
11.0
plt.figure()
#plt.plot(energy_scale, model+resolution_functions)
plt.plot(energy_scale, model2)np.append([1,2,3], [4,5,6])array([1, 2, 3, 4, 5, 6])plt.close('all')
peak_model, peak_out_list = eels_tools.find_peaks(infoWidget.selected_dataset, 1,40)
new_list = np.reshape(peak_out_list, [len(peak_out_list) // 3, 3])
area = np.sqrt(2 * np.pi) * np.abs(new_list[:, 1]) * np.abs(new_list[:, 2] / np.sqrt(2 * np.log(2)))
arg_list = np.argsort(area)[::-1]
area = area[arg_list]
peak_out_list = new_list[arg_list]
number_of_peaks = np.searchsorted(area * -1, -np.average(area))
peak_model, peak_out_list[0], number_of_peaks(array([0., 0., 0., ..., 0., 0., 0.]),
array([2.03888490e+01, 6.60088441e+05, 9.51555853e+00]),
7)peak_model, peak_out_list[0], number_of_peaks(19, 3)peakmodel, peak_out_list, number_of_peaks = smooth(infoWidget.selected_dataset, 1, False)def smooth(dataset, iterations, advanced_present):
"""Gaussian mixture model (non-Bayesian)
Fit lots of Gaussian to spectrum and let the program sort it out
We sort the peaks by area under the Gaussians, assuming that small areas mean noise.
"""
# TODO: add sensitivity to dialog and the two functions below
# peaks = dataset.metadata['peak_fit']
peaks ={'fit_start':1,
'fit_end': 40}
peak_model, peak_out_list = eels_tools.find_peaks(dataset, peaks['fit_start'], peaks['fit_end'])
peak_out_list = [peak_out_list]
flat_list = [item for sublist in peak_out_list for item in sublist]
new_list = np.reshape(flat_list, [len(flat_list) // 3, 3])
area = np.sqrt(2 * np.pi) * np.abs(new_list[:, 1]) * np.abs(new_list[:, 2] / np.sqrt(2 * np.log(2)))
arg_list = np.argsort(area)[::-1]
area = area[arg_list]
peak_out_list = new_list[arg_list]
number_of_peaks = np.searchsorted(area * -1, -np.average(area))
return peak_model, peak_out_list, number_of_peaks
len(peakFitWidget.peak_out_list)6peakFitWidget.sidebar[7,0].value = 2
options = list(peakFitWidget.sidebar[7,0].options)
options.insert(-1, (f'Peak {len(options)}', len(options)-1))
len(options), options(7,
[('Peak 1', 0),
('ll', -2),
('Peak 3', 2),
('Peak 4', 3),
('Peak 5', 4),
('Peak 6', 5),
('add peak', -1)])plt.figure()
plt.plot(resolution_functions)
plt.plot(eels_dataset)
view = resolution_functions.plot()
view.gca().plot(eels_dataset.energy_loss, eels_dataset)
eels_dataset.metadata
energy_shift = resolution_functions.metadata['low_loss']['shifts']
fwhm = resolution_functions.metadata['low_loss']['widths']
t_mfp = np.log(eels_dataset.sum(axis=2)/resolution_functions.sum(axis=2))
plt.figure()
ax1 = plt.subplot(131)
plt.imshow(energy_shift)
plt.colorbar()
plt.title(f' energy shift - mean: {np.mean(energy_shift):.2f}, std {np.std(energy_shift):.3f}')
ax2 = plt.subplot(132)
plt.imshow(fwhm)
plt.colorbar()
plt.title(f' peak widths - mean: {np.mean(fwhm):.2f}, std {np.std(fwhm):.3f}')
ax3 = plt.subplot(133)
plt.imshow(t_mfp)
plt.colorbar()
plt.title(f' thickness - mean: {np.mean(np.array(t_mfp)):.2f}, std {np.std(np.array(t_mfp)):.3f}')---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
c:\Users\gduscher\Documents\Github\pyTEMlib\notebooks\EELS\Analyse_Low_Loss.ipynb Cell 11 line 1
----> <a href='vscode-notebook-cell:/c%3A/Users/gduscher/Documents/Github/pyTEMlib/notebooks/EELS/Analyse_Low_Loss.ipynb#X13sZmlsZQ%3D%3D?line=0'>1</a> energy_shift = resolution_functions.metadata['low_loss']['shifts']
<a href='vscode-notebook-cell:/c%3A/Users/gduscher/Documents/Github/pyTEMlib/notebooks/EELS/Analyse_Low_Loss.ipynb#X13sZmlsZQ%3D%3D?line=1'>2</a> fwhm = resolution_functions.metadata['low_loss']['widths']
<a href='vscode-notebook-cell:/c%3A/Users/gduscher/Documents/Github/pyTEMlib/notebooks/EELS/Analyse_Low_Loss.ipynb#X13sZmlsZQ%3D%3D?line=3'>4</a> t_mfp = np.log(eels_dataset.sum(axis=2)/resolution_functions.sum(axis=2))
AttributeError: 'tuple' object has no attribute 'metadata'Shift energy scale¶
eels_dataset.metadata['low_loss'].update(resolution_functions.metadata['low_loss'])
shifted_dataset = eels_tools.shift_on_same_scale(eels_dataset)
view = shifted_dataset.plot()shifted_resolution_functions = eels_tools.get_resolution_functions(shifted_dataset, zero_loss_fit_width=.9)
dif = shifted_dataset - shifted_resolution_functions
view = dif.plot()c:\Users\gduscher\AppData\Local\anaconda3\envs\pyTEMlib\Lib\site-packages\scipy\optimize\_minpack_py.py:492: RuntimeWarning: Number of calls to function has reached maxfev = 2000.
warnings.warn(errors[info][0], RuntimeWarning)
datasets = fileWidget.datasets
#datasets['energy_corrected'] = shifted_dataset
#datasets['energy_corrected_resolution_function'] = shifted_resolution_functions
infoWidget= interactive_eels.InfoWidget(datasets)c:\Users\gduscher\AppData\Local\anaconda3\envs\pyTEMlib\Lib\site-packages\jupyter_client\session.py:719: UserWarning: Message serialization failed with:
Out of range float values are not JSON compliant
Supporting this message is deprecated in jupyter-client 7, please make sure your message is JSON-compliant
content = self.pack(content)
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
Cell In[8], line 5
1 datasets = fileWidget.datasets
2 #datasets['energy_corrected'] = shifted_dataset
3 #datasets['energy_corrected_resolution_function'] = shifted_resolution_functions
----> 5 infoWidget= interactive_eels.InfoWidget(datasets)
File c:\Users\gduscher\Documents\Github\pyTEMlib\notebooks\EELS\../..\pyTEMlib\info_dialog.py:428, in InfoWidget.__init__(self, datasets)
423 self.figure.canvas.toolbar_visible = True
426 self.axis = None
--> 428 self.set_dataset()
429 self.set_action()
431 self.start_cursor = ipywidgets.FloatText(value=0, description='Start:', disabled=False, color='black', layout=ipywidgets.Layout(width='200px'))
File c:\Users\gduscher\Documents\Github\pyTEMlib\notebooks\EELS\../..\pyTEMlib\info_dialog.py:527, in InfoWidget.set_dataset(self, index)
525 self.sidebar[13,0].value = self.datasets[self.key].metadata['experiment']['beam_current']
526 self.figure.clear()
--> 527 view = self.dataset.plot(figure=self.figure)
528 if hasattr(self.dataset.view, 'axes'):
529 self.axis = self.dataset.view.axes[-1]
File c:\Users\gduscher\AppData\Local\anaconda3\envs\pyTEMlib\Lib\site-packages\sidpy\sid\dataset.py:556, in Dataset.plot(self, verbose, figure, **kwargs)
554 self.view = ComplexSpectralImageVisualizer(self, figure=figure, **kwargs)
555 else:
--> 556 self.view = SpectralImageVisualizer(self, figure=figure, **kwargs)
557 # plt.show()
558 else:
559 raise NotImplementedError('Datasets with data_type {} cannot be plotted, yet.'.format(self.data_type))
File c:\Users\gduscher\AppData\Local\anaconda3\envs\pyTEMlib\Lib\site-packages\sidpy\viz\dataset_viz.py:593, in SpectralImageVisualizer.__init__(self, dset, figure, horizontal, **kwargs)
591 if len(self.energy_scale)!=self.spectrum.shape[0]:
592 self.spectrum = self.spectrum.T
--> 593 self.axes[1].plot(self.energy_scale, self.spectrum.compute())
594 self.axes[1].set_title('spectrum {}, {}'.format(self.x, self.y))
595 self.xlabel = self.dset.labels[self.spec_dim]
File c:\Users\gduscher\AppData\Local\anaconda3\envs\pyTEMlib\Lib\site-packages\matplotlib\axes\_axes.py:1690, in Axes.plot(self, scalex, scaley, data, *args, **kwargs)
1688 lines = [*self._get_lines(*args, data=data, **kwargs)]
1689 for line in lines:
-> 1690 self.add_line(line)
1691 if scalex:
1692 self._request_autoscale_view("x")
File c:\Users\gduscher\AppData\Local\anaconda3\envs\pyTEMlib\Lib\site-packages\matplotlib\axes\_base.py:2304, in _AxesBase.add_line(self, line)
2301 if line.get_clip_path() is None:
2302 line.set_clip_path(self.patch)
-> 2304 self._update_line_limits(line)
2305 if not line.get_label():
2306 line.set_label(f'_child{len(self._children)}')
File c:\Users\gduscher\AppData\Local\anaconda3\envs\pyTEMlib\Lib\site-packages\matplotlib\axes\_base.py:2327, in _AxesBase._update_line_limits(self, line)
2323 def _update_line_limits(self, line):
2324 """
2325 Figures out the data limit of the given line, updating self.dataLim.
2326 """
-> 2327 path = line.get_path()
2328 if path.vertices.size == 0:
2329 return
File c:\Users\gduscher\AppData\Local\anaconda3\envs\pyTEMlib\Lib\site-packages\matplotlib\lines.py:1029, in Line2D.get_path(self)
1027 """Return the `~matplotlib.path.Path` associated with this line."""
1028 if self._invalidy or self._invalidx:
-> 1029 self.recache()
1030 return self._path
File c:\Users\gduscher\AppData\Local\anaconda3\envs\pyTEMlib\Lib\site-packages\matplotlib\lines.py:681, in Line2D.recache(self, always)
679 self._x_filled = self._x.copy()
680 indices = np.arange(len(x))
--> 681 self._x_filled[nanmask] = np.interp(
682 indices[nanmask], indices[~nanmask], self._x[~nanmask])
683 else:
684 self._x_filled = self._x
File <__array_function__ internals>:200, in interp(*args, **kwargs)
File c:\Users\gduscher\AppData\Local\anaconda3\envs\pyTEMlib\Lib\site-packages\numpy\lib\function_base.py:1595, in interp(x, xp, fp, left, right, period)
1592 xp = np.concatenate((xp[-1:]-period, xp, xp[0:1]+period))
1593 fp = np.concatenate((fp[-1:], fp, fp[0:1]))
-> 1595 return interp_func(x, xp, fp, left, right)
ValueError: array of sample points is emptyv = shifted_dataset.plot()

FWHM, energy_shift = eels_tools.fix_energy_scale(eels_dataset)
print(f'Zero Loss with energy resolution of {FWHM:.2f} eV at position {energy_shift:.3f} eV')
eels_dataset.energy_loss -= energy_shift
zero_loss, _ = eels_tools.resolution_function(eels_dataset.energy_loss, eels_dataset, .4)
print(zero_loss)
plt.figure()
plt.plot(eels_dataset.energy_loss, eels_dataset, label='spectrum')
plt.plot(eels_dataset.energy_loss, zero_loss, label = 'zero-loss')
plt.plot(eels_dataset.energy_loss, np.array(eels_dataset)-zero_loss , label = 'difference')
plt.title ('Lorentzian Product Fit of Zero-Loss Peak')
#plt.xlim(-5,30)
plt.legend();
Izl = zero_loss.sum()
Itotal = np.array(eels_dataset).sum()
tmfp = np.log(Itotal/Izl)
print(f'Sum of Zero-Loss: {Izl:.3f} %')
print(f'Sum of Spectrum: {Itotal:.3f} %')
print (f'thickness [IMFP]: {tmfp:.5f}')---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
Cell In[40], line 1
----> 1 FWHM, energy_shift = eels_tools.fix_energy_scale(eels_dataset[0,0])
3 print(f'Zero Loss with energy resolution of {FWHM:.2f} eV at position {energy_shift:.3f} eV')
4 eels_dataset.energy_loss -= energy_shift
File c:\Users\gduscher\Documents\Github\pyTEMlib\notebooks\EELS\../..\pyTEMlib\eels_tools.py:1116, in fix_energy_scale(spec, energy)
1113 if not isinstance(spec, np.ndarray):
1114 return
-> 1116 start = np.searchsorted(energy, -10)
1117 end = np.searchsorted(energy, 10)
1118 startx = np.argmax(spec[start:end]) + start
File <__array_function__ internals>:200, in searchsorted(*args, **kwargs)
File c:\Users\gduscher\AppData\Local\anaconda3\envs\pyTEMlib\Lib\site-packages\numpy\core\fromnumeric.py:1413, in searchsorted(a, v, side, sorter)
1345 @array_function_dispatch(_searchsorted_dispatcher)
1346 def searchsorted(a, v, side='left', sorter=None):
1347 """
1348 Find indices where elements should be inserted to maintain order.
1349
(...)
1411
1412 """
-> 1413 return _wrapfunc(a, 'searchsorted', v, side=side, sorter=sorter)
File c:\Users\gduscher\AppData\Local\anaconda3\envs\pyTEMlib\Lib\site-packages\numpy\core\fromnumeric.py:54, in _wrapfunc(obj, method, *args, **kwds)
52 bound = getattr(obj, method, None)
53 if bound is None:
---> 54 return _wrapit(obj, method, *args, **kwds)
56 try:
57 return bound(*args, **kwds)
File c:\Users\gduscher\AppData\Local\anaconda3\envs\pyTEMlib\Lib\site-packages\numpy\core\fromnumeric.py:43, in _wrapit(obj, method, *args, **kwds)
41 except AttributeError:
42 wrap = None
---> 43 result = getattr(asarray(obj), method)(*args, **kwds)
44 if wrap:
45 if not isinstance(result, mu.ndarray):
ValueError: object of too small depth for desired arrayFitting a Drude Function to Plasmon¶
The position and the width are important materials parameters and we can derive them by fitting the Drude function to the volume plasmon region.
Drude Function¶
Most of the inelastically scattered electron arise from interaction with outer shell electrons. These interactions, therefore, have a high intensity and are easy to obtain.
The energy-loss function on the other hand is determined by the dielectric function through:
The dielectric function in the Drude theory is given by two input parameters the position of the plasmon energy and the width of the plasmon
Here is the angular frequency (rad/s) of forced oscillation and is the natural or resonance frequency for plasma oscillation, given by
A transmitted electron represents a sudden impulse of applied electric field, containing all angular frequencies (Fourier components). Setting up a plasma oscillation of the loosely bound outer-shell electrons in a solid is equivalent to creating a pseudoparticle of energy , known as a plasmon (Pines, 1963).
from scipy.optimize import leastsq, curve_fit
eels_dataset = spec
def Drude(E,Ep,Ew, gamma=1):
eps = 1 - Ep**2/(E**2+Ew**2) +1j* Ew* Ep**2/E/(E**2+Ew**2)
eps = 1 - (Ep**2 - Ew * E * 1j) / (E**2 + 2 * E * gamma * 1j) # Mod drude ter
elf = (-1/eps).imag
return eps,elf
def errfDrude(p, y, x):
eps,elf = Drude(x,p[0],p[1])
err = y - p[2]*elf
#print (p,sum(np.abs(err)))
return np.abs(err)#/np.sqrt(y)
pin2 = np.array([9,1,.7, 1.11])
E = energy_scale = eels_dataset.energy_loss
startFit =np.argmin(abs(energy_scale-6))
endFit = np.argmin(abs(energy_scale-15))
p2, lsq = leastsq(errfDrude, pin2, args=(eels_dataset[startFit:endFit], energy_scale[startFit:endFit]), maxfev=2000)
eps, elf =Drude(energy_scale,p2[0],p2[1],p2[3])
drudePSD = p2[2]* elf
plt.figure()
plt.plot(energy_scale,eels_dataset)
plt.plot(energy_scale,drudePSD)
plt.plot(energy_scale,eels_dataset-drudePSD)
plt.axhline(0, color='black')
#plt.gca().set_xlim(0,40)
#plt.gca().set_ylim(-0.01,0.2)
print(f"Drude Theory with Plamson Energy: {p2[0]:2f} eV and plasmon Width {p2[1]:.2f} eV")
print(f"Max of Plasmon at {energy_scale[drudePSD.argmax(0)]:.2f} eV")
print(f"Amplitude of {p2[2]:.2f} was deteremined by fit ")
p2
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Cell In[5], line 2
1 from scipy.optimize import leastsq, curve_fit
----> 2 eels_dataset = spec
3 def Drude(E,Ep,Ew, gamma=1):
4 eps = 1 - Ep**2/(E**2+Ew**2) +1j* Ew* Ep**2/E/(E**2+Ew**2)
NameError: name 'spec' is not definedplt.figure()
plt.title ('Drude Fit: Dielectric Function - Permittivity')
plt.plot(energy_scale,eps.real,label = 'Re($\epsilon)$')
plt.plot(energy_scale,eps.imag,label = 'Im($\epsilon)$')
plt.plot(energy_scale,drudePSD,label = 'loss-function$_{Drude}$')
plt.plot(energy_scale,eels_dataset,label = 'loss-function$_{exp}$')
plt.axhline(0, color='black')
plt.gca().set_xlim(0,40)
plt.gca().set_ylim(-2.5,5.3)
plt.legend();<>:3: SyntaxWarning: invalid escape sequence '\e'
<>:4: SyntaxWarning: invalid escape sequence '\e'
<>:3: SyntaxWarning: invalid escape sequence '\e'
<>:4: SyntaxWarning: invalid escape sequence '\e'
C:\Users\gduscher\AppData\Local\Temp\ipykernel_17524\467939617.py:3: SyntaxWarning: invalid escape sequence '\e'
plt.plot(energy_scale,eps.real,label = 'Re($\epsilon)$')
C:\Users\gduscher\AppData\Local\Temp\ipykernel_17524\467939617.py:4: SyntaxWarning: invalid escape sequence '\e'
plt.plot(energy_scale,eps.imag,label = 'Im($\epsilon)$')
tmfp = .3
zl2 = zero_loss
LLene = np.arange(1,2048)/5
zero_loss, _ = eels_tools.resolution_function(eels_dataset.energy_loss, eels_dataset, .4)
ZP = np.array(zl2).argmax(0) # zl peak position
print(ZP)
_, SSD = Drude(LLene,15, 2 )
PSD = np.zeros(len(LLene))
FAC = 1.
ssd = np.fft.fft(SSD)
ssd2 = ssd.copy()
SSD2 = SSD.copy()
for order in range(20):
# This order convoluted spectum
PPSD = np.zeros(len(LLene))
# convoluted SSD is SSD2
SSD2 = np.fft.ifft(ssd).real
# scale right (could be done better? GERD)
mult = sum(SSD)/sum(SSD2)
SSD2 *= mult.real/np.exp(-tmfp)
EP = np.array(SSD2).argmax(0)
PPSD = SSD2/FAC*np.power(tmfp,(order))*np.exp(-tmfp)*1e12
# Add this order t0 final spectrum
PSD += PPSD
# Get next order factor
FAC=FAC*(order+2.)
# convolute next order
ssd = ssd * ssd2
plt.figure()
plt.plot(SSD/SSD.max())
plt.plot(PSD/PSD.max())173
from scipy.interpolate import splev,splrep,splint
def MakeDrudeVL(dataset, tmfp, zero_loss, Ep, Ew, Eh):
energy_scale = np.arange(1,2049)/5
ZP = np.array(zero_loss).argmax(0) # zl peak position
_, PSD = Drude(energy_scale,Ep, Ew )
PSD /= PSD.sum()
FAC = 1.
### sum contribution from each order of scattering:
ssd = np.fft.fft(PSD)
SSD_sum = PSD.sum()
ssd2 = ssd.copy()
PSD /= FAC*np.power(tmfp,(0))*np.exp(-tmfp)
for order in range(1,15):
FAC=FAC*(order+2.)
ssd *= ssd2
# convoluted SSD is SSD2
SSD2 = np.fft.ifft(ssd).real
# scale right (could be done better? GERD)
mult = SSD_sum/sum(SSD2)
SSD2 *= mult.real/np.exp(-tmfp)
EP = np.array(SSD2).argmax(0)
PPSD = SSD2/FAC*np.power(tmfp,(order))*np.exp(-tmfp)
# Add this order t0 final spectrum
PSD += PPSD
# convolute next order
dispersion = dataset.energy_loss.slope
factorZL = Eh/dispersion*2 #, #zero_loss.sum()*(np.exp(tmfp)-1)/PSD.sum()*Eh/dispersion/4
#print(factorZL, Eh)
BGDcoef = splrep(energy_scale,PSD,s=0)
cts =splev( dataset.energy_loss, BGDcoef)*factorZL #*p[1]
#cts += zero_loss
return cts
#zero_loss, _ = eels_tools.resolution_function(eels_dataset.energy_loss, eels_dataset, .4)
#Izl = zero_loss.sum()
#Itotal = np.array(eels_dataset).sum()
#tmfp = np.log(Itotal/Izl)
tmfp = 0.3
zero_loss = infoWidget.datasets['resolution_function']
LL = MakeDrudeVL(spec, tmfp, zero_loss, p0[0]-5,.5, p0[2])
print(LL.max(), LL.sum())
plt.figure()
plt.plot(LL, label='Multi')
plt.plot(eels_dataset, label='spec')
plt.plot(eels_dataset-LL, label='dif')
plt.legend()
#plt.ylim(-.1,.2)229957.93374337783 45464262.67521657
def errfDrude(p, y):
LL = MakeDrudeVL(y, p[3], zero_loss, p[0],p[1],p[2])
err = y - LL
#print (p,sum(np.abs(err)))
return np.abs(err)#/np.sqrt(y)
pin2 = np.array([15,1,.7, 0.3])
E = energy_scale = eels_dataset.energy_loss
startFit =np.argmin(abs(energy_scale-13))
endFit = np.argmin(abs(energy_scale-18))
p2, lsq = leastsq(errfDrude, pin2, args=(eels_dataset), maxfev=2000)
LL = MakeDrudeVL(eels_dataset, p2[3], zero_loss, p2[0],p2[1],p2[2])
plt.figure()
plt.plot(LL)
plt.plot(eels_dataset)
plt.legend()
C:\Users\gduscher\AppData\Local\Temp\ipykernel_17524\2622750204.py:19: UserWarning: No artists with labels found to put in legend. Note that artists whose label start with an underscore are ignored when legend() is called with no argument.
plt.legend()
p2[3]0.8326588466281821np.power(0.3,(0))*np.exp(-.3)0.7408182206817179zero_loss.sum()array(1.68808473)def newDrudeBgd(x, p):
tmfp = 500 #p[3]
startB = x[0]
endB = x[-1]
p = np.abs(p)
LLene = np.linspace(1, 2047,2048)
eps = pyTEMlib.eels_tools.drude(LLene,p[0], p[1], p[2])
SSD = (-1/eps).imag
ssd = np.fft.fft(SSD)
ssd2 = ssd.copy()
SSD2 = SSD.copy()
### sum contribution from each order of scattering:
PSD = np.zeros(len(LLene))
for order in range(1):
# This order convoluted spectum
PPSD = np.zeros(len(LLene))
# convoluted SSD is SSD2
SSD2 = np.fft.ifft(ssd).real
# scale right (could be done better? GERD)
print( sum(SSD)/sum(SSD2))
mult = sum(SSD)/sum(SSD2)
SSD2 *= abs(mult)
PPSD = SSD2/scipy.special.factorial(order+1)*np.power(tmfp,(order+1))*np.exp(-tmfp) #using equation 4.1 of egerton ed2
# Add this order to final spectrum
PSD += PPSD
# next order convolution
ssd = ssd * ssd2
cts = np.zeros(len(x))
if startB < 0:
startB = 0
BGDcoef = scipy.interpolate.splrep(LLene[int(startB):int(endB)],PSD[int(startB):int(endB)],s=0)
lin = np.zeros(len(x))
cts = scipy.interpolate.splev( x, BGDcoef)*p[1]
return ctsLLene = np.linspace(1, 2047,2048)
p = p0
eps = pyTEMlib.eels_tools.drude(LLene,p[0], p[1], p[2])
SSD = (-1/eps).imag
plt.figure()
plt.plot(SSD)---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Cell In[7], line 2
1 LLene = np.linspace(1, 2047,2048)
----> 2 p = p0
3 eps = pyTEMlib.eels_tools.drude(LLene,p[0], p[1], p[2])
4 SSD = (-1/eps).imag
NameError: name 'p0' is not definednewDrudeBgd( np.array(spec.energy_loss[200:]), p0)---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Cell In[8], line 1
----> 1 newDrudeBgd( np.array(spec.energy_loss[200:]), p0)
NameError: name 'spec' is not defineddef DrudeBgd(y, x, imfp, p):
# Fit function is the spectrum - new LL bgd devided by poinson noise
def newLL(p, y, x):
err = (y - newDrudeBgd( x,p))
#print(p, sum( err))
return err
# Least square fit
pDLLBgd, lsq = scipy.optimize.leastsq(newLL, p0, args=(y, x), maxfev=2000)
#print(sum(newLL(pZL, y, x)))
# cts is the result of the fit
cts=newDrudeBgd(x, abs(pDLLBgd))
#print("new LLL background ", pZL)
#tags['DrudeLLBgd'] = pDLLBgd
print(pDLLBgd)
return ctsinfoWidget.datasets['plasmon'].metadata{'experiment': {'single_exposure_time': 0.1,
'exposure_time': 10.0,
'number_of_frames': 100,
'collection_angle': 100.0,
'convergence_angle': 0.0,
'microscope': 'Libra 200 MC',
'acceleration_voltage': 199990.28125,
'flux_ppm': 4875.3037109375,
'count_conversion': 1,
'beam_current': 0},
'zero_loss': {'shifted': array([-0.14012023]),
'startFitEnergy': -0.5,
'endFitEnergy': 0.5,
'fit_parameter': array([-1.63207010e-02, 2.06835590e+04, 1.92327897e-01, 3.38795374e-02,
2.25742582e+04, 2.93662067e-01]),
'original_low_loss': 'EELS90muOAonaxis3_new_new'},
'plasmon': {'parameter': array([1.50312722e+01, 7.45905381e-01, 3.48811157e+05]),
'epsilon': array([ 0. +0.j , 0. +0.j ,
0. +0.j , ...,
293283.07757369+9900.8221703j , 293342.39439935+9892.35528781j,
293401.61631948+9883.90252999j])}}import scipy
p0 = np.zeros(4)
#if 'Drude P Pos' in tags:
p0[:3] = [1.50312722e+01, 7.45905381e-01, 3.48811157e+05]
#p0[0] = tags['Drude P Pos']
#p0[1] = tags['Drude P Width']
#p0[2] = tags['Drude P thick']
p0[3] = 17. #tags['Drude P Assym']
spec = infoWidget.dataset
spec.energy_loss[200]
cts = DrudeBgd(np.array(spec[200:]), np.array(spec.energy_loss[200:]), .15, p0)
plt.figure()
plt.plot(cts)1.0000000000000007
1.0000000000000007
1.0000000000000007
0.9999999999999997
1.0
0.9999999999999997
1.0000000000000007
1.0000000000000007
[1.50312722e+01 7.45905381e-01 3.48811157e+05 1.70000000e+01]
def PMFP(ssdLL, energy_scale):
# Calculate plasmon mean free paths using a free-electron formula Eq.(3.58)
# with m = m0 and assuming small width of the plasmon peak.
# Equally good for calculating total-inelastic MFP using a value of
# Em in Eq.(5.38) or a more approximate value using Eq.(5.2).
# Probe convergence alpha incorporated using Scheinfein & Isaacson formula.
# Above values assume dipole conditions (beta* < Bethe-ridge angle).
# The program also estimates a total-inelastic MFP by using dipole formula
# with effective collection angle bstar = Bethe-ridge angle.
# To obtain this value, enter alarge value (~ 100 mrad) for alpha or beta.
E0 = 200000 #Incident-electron energy E0 (keV): ');
Ep = energy_scale[0]+ssdLL.argmax(0)*(energy_scale[1]-energy_scale[0]) #'Plasmon energy of mean energy loss (eV): ');
print(Ep, ssdLL.argmax(0))
alpha = 10 #'Convergence semiangle (mrad) [can be 0]: ');
beta = 30 #'Collection semiangle (mrad): ');
F = (1.0+E0/1022.0)/(1.0+E0/511.0)**2;
Fg = (1.0+E0/1022.0)/(1.0+E0/511.0);
T = E0*F; #keV
tgt = 2.0*Fg*E0;
a0 = 0.0529; #nm
#print('2.gamma.T = ',tgt);
# calculation of convergence correction
#tgt=2.*E0.*(1.+E0./1022.)./(1.+E0./511.); % keV
thetae=(Ep+1e-6)/tgt; # in mrad, avoid NaN for e=0
a2=alpha*alpha*1e-6 + 1e-10; #radians^2, avoiding inf for alpha=0
b2=beta*beta*1e-6; #radians^2
t2=thetae*thetae*1e-6; #radians^2
eta1=np.sqrt((a2+b2+t2)**2-4*a2*b2)-a2-b2-t2;
eta2=2*b2*np.log(0.5/t2*(np.sqrt((a2+t2-b2)**2+4*b2*t2)+a2+t2-b2));
eta3=2*a2*np.log(0.5/t2*(np.sqrt((b2+t2-a2)**2+4*a2*t2)+b2+t2-a2));
eta=(eta1+eta2+eta3)/a2/np.log(4/t2);
f1=(eta1+eta2+eta3)/2/a2/np.log(1+b2/t2);
f2=f1;
if(alpha/beta>1):
f2=f1*a2/b2;
bstar=thetae*np.sqrt(np.exp(f2*np.log(1+b2/t2))-1); #% mrad
#print('effective semiangle beta* = %g mrad\n',bstar);
bstar = 40
thetabr = 1000 * (Ep/E0/1000.0)**0.5;
print('Bethe Ridge Angle', thetabr)
#print('Bethe-ridge angle(mrad) = ',tags['Bethe Ridge Angle'],'nm\n')
pmfp = 0.0
imfp = 0.0
if (bstar < thetabr):
pmfp = 4000*a0*T/Ep/np.log(1+bstar**2/thetae**2);
imfp = 106*F*E0/Ep/np.log(2.0*bstar*E0/Ep);
#print('Free-electron MFP(nm) = %g nm\n',pmfp);
#print('Using Eq.(5.2), MFP(nm) = %g nm\n',imfp);
else:
#print('Dipole range is exceeded\n');
imfp = 4000*a0*T/Ep/np.log(1+thetabr**2/thetae**2);
#print('total-inelastic MFP(nm) = %g nm\n',imfp);
return pmfp, imfpEp = np.array(eels_dataset.energy_loss)[0]+np.array(ssdLL).argmax(0)*(np.array(eels_dataset.energy_loss)[1]-np.array(eels_dataset.energy_loss)[0])
Ep, np.array(ssdLL).argmax(0)(15.040794864773837, 920)PMFP(np.array(ssdLL), np.array(eels_dataset.energy_loss))15.040794864773837 920
Bethe Ridge Angle 0.27423343035426806
(0.0, 219.06514501302627)# Use resolution Function as ZL if existing
# print len(LLSpec)
LLSpec = eels_dataset
zero_loss, _ = eels_tools.resolution_function(eels_dataset.energy_loss, eels_dataset, .4)
j = np.fft.fft(eels_dataset)
z = np.fft.fft(zero_loss)
j1 = z*np.log(j/z)
ssdLL =np.fft.ifft(j1).real#,'fourier-log deconvolution')
#parent.text2.append('\n Single Scattering Deconvolution, Done')
if np.array(eels_dataset).sum() > 0.0:
tmfp = np.log(np.array(eels_dataset).sum()/zero_loss.sum())
else:
tmfp = 0.0
Ep = np.array(eels_dataset.energy_loss)[0]+np.array(ssdLL).argmax(0)*(np.array(eels_dataset.energy_loss)[1]-np.array(eels_dataset.energy_loss)[0])
print(tmfp)
plt.figure()
plt.plot(ssdLL)0.17584541453708571
def drude(dataset, ep, ew, tnm, eb, verbose=False):
e0 = 200
beta = 30
e = dataset.energy_loss
epc = e[1]-e[0]
b = beta/1000.0 # %rad
T = 1000.0*e0*(1.+e0/1022.12)/(1.0+e0/511.06)**2;# %eV # equ.5.2a or Appendix E p 427
tgt = 1000*e0*(1022.12 + e0)/(511.06 + e0);# %eV Appendix E p 427
rk0 = 2590*(1.0+e0/511.06)*np.sqrt(2.0*T/511060);
os = e[0]
ewMod = eb
eps = 1 - (ep**2-ewMod*e*1j)/(e**2+2*e*ew*1j) #Mod Drude term
eps[np.nonzero(eps==0.0)]= 1e-19
elf = np.imag(-1/eps)
the = e/tgt; #% varies with energy loss! # Appendix E p 427
srfelf=np.imag(-4./(1.0+eps))-elf; #% for 2 surfaces
angdep = np.arctan(b/the)/the - b/(b*b+the*the);
srfint = angdep*srfelf/(3.1416*0.05292*rk0*T); #% probability per eV
anglog = np.log(1.0+ b*b/the/the);
I0 = eels_dataset.sum() *1
volint = abs(tnm/(np.pi*0.05292*T*2)*elf*anglog); #S equ 4.26% probability per eV
volint = (volint+srfint) *I0 *epc #S probability per channel
ssd = volint #+ srfint;
if os <-1.0:
xs = int(abs(-os/epc))
ssd[0:xs]=0.0
volint[0:xs]=0.0
srfint[0:xs]=0.0
Ps = np.trapz(e,srfint); #% 2 surfaces but includes negative begrenzungs contribn.
Pv = abs(np.trapz(e,abs(volint/np.array(eels_dataset)))); #% integrated volume probability
Pv = (volint/I0).sum() ## our data have he same epc and the trapz formula does not include
lam = tnm/Pv; #% does NOT depend on free-electron approximation (no damping).
lamfe = 4.0*0.05292*T/ep/np.log(1+(b* tgt / ep) **2); #% Eq.(3.44) approximation
if verbose:
print('Ps(2surfaces+begrenzung terms) =', Ps, 'Pv=t/lambda(beta)= ',Pv,'\n');
print('Volume-plasmon MFP(nm) = ', lam,' Free-electron MFP(nm) = ',lamfe,'\n');
print('--------------------------------\n');
return ssd#/np.pissd = drude(eels_dataset, 15, .5, 3, 1)
plt.figure()
plt.plot(eels_dataset.energy_loss, ssd)def doSSD(LLSpec):
# Use resolution Function as ZL if existing
# print len(LLSpec)
extract_zero_loss(LLSpec)
j = np.fft.fft(LLSpec)
z = np.fft.fft(tags['zero_loss'])
z2 = z ## Could be a zl extracted from Spectrum
j1 = z2*np.log(j/z)
ssdLL =np.fft.ifft(j1).real#,'fourier-log deconvolution')
tags['ssdLL']=ssdLL.copy()
#parent.text2.append('\n Single Scattering Deconvolution, Done')
if np.array(LLSpec).sum() > 0.0:
tmfp = np.log(np.array(LLSpec).sum()/tags['zero_loss'].sum())
else:
tmfp = 0.0
# Use resolution function if available, use ZL otherwise
zl2 = tags['zero_loss']
#####################
####### for SSD convoluted Spectra
#####################
startE = (6.0-tags['offset'])/tags['dispersion']
SSD = ssdLL.copy()
SSD2 = SSD.copy()
SSD2[0:startE]=0.0
EP = np.array(SSD2).argmax(0) # plasmon peak position
ZP = np.array(zl2).argmax(0) # zl peak position
#print ('\n EP: ',EP,startE, tags['offset']+EP*tags['dispersion'])
guess = [tags['offset']+EP*tags['dispersion'], 10000.0, 6.0, 0.98]
pin = np.array(guess)
def errfct(p, y, x):
err = (y - Lorentzian(x,p))
return err
def Lorentzian(x,p):
y = ((0.5 * p[1]* p[2]/3.14)/((x- p[0])**2+(( p[2]/2)**2)))
return y
p, lsq = leastsq(errfct, pin, args=(SSD, tags['ene']), maxfev=2000)
tags['PLpos'] = p[0]
tags['PLwidth'] = p[2]
tags['PLarea'] = p[1]
#parent.text2.insertPlainText('\n Position 1 Amplitude 1, Width 1, \n')
#parent.text2.insertPlainText(str(p[0:3]))
PL1 = Lorentzian(tags['ene'],p)
pmfp, imfp = PMFP()
startxE = tags['Drude Fit Start']
endxE = tags['Drude Fit End']
startx = (startxE-tags['offset'])/tags['dispersion']
endx = (endxE-tags['offset'])/tags['dispersion']
if p[0] < startxE:
p[0] = startxE
if p[0] > endxE:
p[0] = endxE
if p[2] > (endxE-startxE)/2.0:
p[2] = (endxE-startxE)/2.0
guess = [p[0],p[2],tmfp*imfp,0.1,1.0]
guess = [22,10,50,0.1,1.0]
pin2 = np.array(guess)
def errfDrude(p, y, x):
p = abs(p)
if p[0] < startxE:
p[0] = startxE
if p[0] > endxE:
p[0] = endxE
if p[1] > endxE-startxE/3.0:
p[1] = endxE-startxE/3.0
if p[2] > 200:
p[2] = 200
if p[2]<0:
p[2] =0
if p[3] > 10:
p[3] = 10
if p[3]<0:
p[3] =0
if not tags['Drude Fit Asymm'] :
p[3] = 0
err = (y - drude(x,p[0],p[1],p[2],abs(p[3])))
y[np.nonzero(y<=0)] = 1e-12
return np.abs(err)/np.sqrt(y)
p2, lsq = leastsq(errfDrude, pin2, args=(tags['spec'][startx:endx], tags['ene'][startx:endx]), maxfev=2000)
p2[3] = abs(p2[3])
drudePSD = drude(tags['ene'],p2[0],p2[1],p2[2],abs(p2[3]))
tags['Drude SSD'] = drudePSD
tags['Drude P Pos'] = p2[0]
tags['Drude P Width'] = p2[1]
tags['Drude P thick'] = p2[2]
tags['Drude P Assym'] = abs(p2[3])
Pv = drudePSD.sum()/tags['spec'].sum()
tags['Drude P Probab'] = Pv
tags['Drude P IMFP'] = p2[2]/Pv #(Wave vs. intensity)
#tags['Drude P/LL IMFP',p2[2]/tmfp,'nm')
tags['LLthick'] = tmfp
e = 1.60217646E-19; #% electron charge in Coulomb
eps0 = 8.854187817*1e-12 # vacuum permittivity
mel = 9.109e-31; #% REST electron mass in kg
h = 4.135667516*1e-15; #% Planck's constant
hbar = h/2.0/np.pi;
tags['Drude e- density']= np.sqrt( (p2[0]/hbar)**2/e**2*eps0*mel)*1e-7 #gerd true? /nm^2
tags['Drude VL'] = MakeDrudeVL()
return tmfpSurface Plasmon¶
Spectra from thin specimen show the excitations of the surface plasmons on each side of the specimen. For any normal specimen these surface plasmons do interact, but this is not true for extremely thick specimen (nm).
The surface plasmon frequency for thin specimen is related to the bulk plasmon frequency by Ritchie [Ritchie-PR1957]:
The symmetric mode, where like charges face one another, corresponds to the higher angular frequency . Please note, that this relationship does only apply for large
The differential probability for surface excitation at both surfaces of a sample with thickness can be expressed (normal incident, no retardation effects) by:
with $$ R_c = \frac{\varepsilon_a \sin^2(tE/2\hbar\mu)}{\varepsilon_b + \varepsilon_z }\tanh (q_s t/2)
\frac{\varepsilon_a \cos^2(tE/2\hbar\mu)}{\varepsilon_b + \varepsilon_a} \coth (q_s t/2) $\varepsilon_a\varepsilon_b$ are the permitivities of the two surfaces.
A secondary effect of the surface excitation is the reduced intensity of the bulk plasmon peak. The effect is usually smaller than 1%, but can be larger for spectra with small collection angle, because the preferred scattering of surfuce losses into small angles. The correction for surface plasmon will be discussed in the Kramers--Kronig Analysis.
Summary¶
The beauty of Low--Loss spectroscopy is its derivation of the dielectric function to high energies without prior knowledge of the composition. The signal is strong and the acquisition time is mostly restricted by the dynamic range of the spectrum.
Think of low-loss spectroscopy as Electrodynamics
The advantages of EELS is the derivation of these values spatially resolved. And from a linescan across an Si/SiO interface the dielectric function per pixel can be obtained. From that we can calculate the dielectric polarizability , which may be a measure of the dielectric strength.
We obtain more or less easily:
relative thickness
absolute thickness
inelastic mean free path
plasmon frequency
plasmon width
band gap
dielectric function
reflectivity
absorption
effective number of electrons per atoms
The analysis of the optical data requires the exact knowledge of the zero-loss peak. Because of the weighting in the Fourier Analysis, the low energy part contributes heavily to the dielectric function. Therefore, energy resolution is critical for an exact determination of all the optical values from EELS. The new monochromated TEMs are now able to achieve an energy resolution of 10 meV (one is at the oak Ridge National Laboratory), which allows for a sharper zero-loss peak. Such a sharp zero-loss peak will enable us to extract this low energy data more accurately. The dielectric function and the parameters derived from it, can be more precisely determined from such EELS spectra.
