pyTEMlib 0.2025.4.2__py3-none-any.whl → 0.2025.9.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of pyTEMlib might be problematic. Click here for more details.

Files changed (94) hide show
  1. build/lib/pyTEMlib/__init__.py +33 -0
  2. build/lib/pyTEMlib/animation.py +640 -0
  3. build/lib/pyTEMlib/atom_tools.py +238 -0
  4. build/lib/pyTEMlib/config_dir.py +31 -0
  5. build/lib/pyTEMlib/crystal_tools.py +1219 -0
  6. build/lib/pyTEMlib/diffraction_plot.py +756 -0
  7. build/lib/pyTEMlib/dynamic_scattering.py +293 -0
  8. build/lib/pyTEMlib/eds_tools.py +826 -0
  9. build/lib/pyTEMlib/eds_xsections.py +432 -0
  10. build/lib/pyTEMlib/eels_tools/__init__.py +44 -0
  11. build/lib/pyTEMlib/eels_tools/core_loss_tools.py +751 -0
  12. build/lib/pyTEMlib/eels_tools/eels_database.py +134 -0
  13. build/lib/pyTEMlib/eels_tools/low_loss_tools.py +655 -0
  14. build/lib/pyTEMlib/eels_tools/peak_fit_tools.py +175 -0
  15. build/lib/pyTEMlib/eels_tools/zero_loss_tools.py +264 -0
  16. build/lib/pyTEMlib/file_reader.py +274 -0
  17. build/lib/pyTEMlib/file_tools.py +811 -0
  18. build/lib/pyTEMlib/get_bote_salvat.py +69 -0
  19. build/lib/pyTEMlib/graph_tools.py +1153 -0
  20. build/lib/pyTEMlib/graph_viz.py +599 -0
  21. build/lib/pyTEMlib/image/__init__.py +37 -0
  22. build/lib/pyTEMlib/image/image_atoms.py +270 -0
  23. build/lib/pyTEMlib/image/image_clean.py +197 -0
  24. build/lib/pyTEMlib/image/image_distortion.py +299 -0
  25. build/lib/pyTEMlib/image/image_fft.py +277 -0
  26. build/lib/pyTEMlib/image/image_graph.py +926 -0
  27. build/lib/pyTEMlib/image/image_registration.py +316 -0
  28. build/lib/pyTEMlib/image/image_utilities.py +309 -0
  29. build/lib/pyTEMlib/image/image_window.py +421 -0
  30. build/lib/pyTEMlib/image_tools.py +699 -0
  31. build/lib/pyTEMlib/interactive_image.py +1 -0
  32. build/lib/pyTEMlib/kinematic_scattering.py +1196 -0
  33. build/lib/pyTEMlib/microscope.py +61 -0
  34. build/lib/pyTEMlib/probe_tools.py +906 -0
  35. build/lib/pyTEMlib/sidpy_tools.py +153 -0
  36. build/lib/pyTEMlib/simulation_tools.py +104 -0
  37. build/lib/pyTEMlib/test.py +437 -0
  38. build/lib/pyTEMlib/utilities.py +314 -0
  39. build/lib/pyTEMlib/version.py +5 -0
  40. build/lib/pyTEMlib/xrpa_x_sections.py +20976 -0
  41. pyTEMlib/__init__.py +25 -3
  42. pyTEMlib/animation.py +31 -22
  43. pyTEMlib/atom_tools.py +29 -34
  44. pyTEMlib/config_dir.py +2 -28
  45. pyTEMlib/crystal_tools.py +129 -165
  46. pyTEMlib/eds_tools.py +559 -342
  47. pyTEMlib/eds_xsections.py +432 -0
  48. pyTEMlib/eels_tools/__init__.py +44 -0
  49. pyTEMlib/eels_tools/core_loss_tools.py +751 -0
  50. pyTEMlib/eels_tools/eels_database.py +134 -0
  51. pyTEMlib/eels_tools/low_loss_tools.py +655 -0
  52. pyTEMlib/eels_tools/peak_fit_tools.py +175 -0
  53. pyTEMlib/eels_tools/zero_loss_tools.py +264 -0
  54. pyTEMlib/file_reader.py +274 -0
  55. pyTEMlib/file_tools.py +260 -1130
  56. pyTEMlib/get_bote_salvat.py +69 -0
  57. pyTEMlib/graph_tools.py +101 -174
  58. pyTEMlib/graph_viz.py +150 -0
  59. pyTEMlib/image/__init__.py +37 -0
  60. pyTEMlib/image/image_atoms.py +270 -0
  61. pyTEMlib/image/image_clean.py +197 -0
  62. pyTEMlib/image/image_distortion.py +299 -0
  63. pyTEMlib/image/image_fft.py +277 -0
  64. pyTEMlib/image/image_graph.py +926 -0
  65. pyTEMlib/image/image_registration.py +316 -0
  66. pyTEMlib/image/image_utilities.py +309 -0
  67. pyTEMlib/image/image_window.py +421 -0
  68. pyTEMlib/image_tools.py +154 -928
  69. pyTEMlib/kinematic_scattering.py +1 -1
  70. pyTEMlib/probe_tools.py +1 -1
  71. pyTEMlib/test.py +437 -0
  72. pyTEMlib/utilities.py +314 -0
  73. pyTEMlib/version.py +2 -3
  74. pyTEMlib/xrpa_x_sections.py +14 -10
  75. {pytemlib-0.2025.4.2.dist-info → pytemlib-0.2025.9.1.dist-info}/METADATA +13 -16
  76. pytemlib-0.2025.9.1.dist-info/RECORD +86 -0
  77. {pytemlib-0.2025.4.2.dist-info → pytemlib-0.2025.9.1.dist-info}/WHEEL +1 -1
  78. pytemlib-0.2025.9.1.dist-info/top_level.txt +6 -0
  79. pyTEMlib/core_loss_widget.py +0 -721
  80. pyTEMlib/eels_dialog.py +0 -754
  81. pyTEMlib/eels_dialog_utilities.py +0 -1199
  82. pyTEMlib/eels_tools.py +0 -2359
  83. pyTEMlib/file_tools_qt.py +0 -193
  84. pyTEMlib/image_dialog.py +0 -158
  85. pyTEMlib/image_dlg.py +0 -146
  86. pyTEMlib/info_widget.py +0 -1086
  87. pyTEMlib/info_widget3.py +0 -1120
  88. pyTEMlib/low_loss_widget.py +0 -479
  89. pyTEMlib/peak_dialog.py +0 -1129
  90. pyTEMlib/peak_dlg.py +0 -286
  91. pytemlib-0.2025.4.2.dist-info/RECORD +0 -38
  92. pytemlib-0.2025.4.2.dist-info/top_level.txt +0 -1
  93. {pytemlib-0.2025.4.2.dist-info → pytemlib-0.2025.9.1.dist-info}/entry_points.txt +0 -0
  94. {pytemlib-0.2025.4.2.dist-info → pytemlib-0.2025.9.1.dist-info}/licenses/LICENSE +0 -0
pyTEMlib/info_widget.py DELETED
@@ -1,1086 +0,0 @@
1
- from typing import Any
2
-
3
- import numpy as np
4
- import os
5
- import sys
6
- import ipywidgets
7
- import matplotlib.pylab as plt
8
- import matplotlib
9
- from IPython.display import display
10
-
11
- import sidpy
12
- # from pyTEMlib.microscope import microscope
13
- from pyTEMlib import file_tools
14
- from pyTEMlib import eels_tools
15
- from pyTEMlib.core_loss_widget import get_core_loss_sidebar, CoreLoss
16
- from pyTEMlib.low_loss_widget import get_low_loss_sidebar, LowLoss
17
-
18
- def get_image_sidebar() -> Any:
19
- side_bar = ipywidgets.GridspecLayout(14, 3, width='auto', grid_gap="0px")
20
-
21
- side_bar[0, :2] = ipywidgets.Dropdown(
22
- options=[('None', 0)],
23
- value=0,
24
- description='Main Dataset:',
25
- disabled=False)
26
- row = 1
27
- side_bar[row, :3] = ipywidgets.Button(description='Image Scale',
28
- layout=ipywidgets.Layout(width='auto', grid_area='header'),
29
- style=ipywidgets.ButtonStyle(button_color='lightblue'))
30
- row += 1
31
- side_bar[row, :2] = ipywidgets.FloatText(value=7.5, description='x dim:', disabled=False, color='black',
32
- layout=ipywidgets.Layout(width='200px'))
33
- side_bar[row, 2] = ipywidgets.widgets.Label(value="nm", layout=ipywidgets.Layout(width='20px'))
34
- row += 1
35
- side_bar[row, :2] = ipywidgets.FloatText(value=7.5, description='y dim:', disabled=False, color='black',
36
- layout=ipywidgets.Layout(width='200px'))
37
- side_bar[row, 2] = ipywidgets.widgets.Label(value="nm", layout=ipywidgets.Layout(width='20px'))
38
- row += 1
39
-
40
- side_bar[row, :3] = ipywidgets.Button(description='Microscope',
41
- layout=ipywidgets.Layout(width='auto', grid_area='header'),
42
- style=ipywidgets.ButtonStyle(button_color='lightblue'))
43
- row += 1
44
- side_bar[row, :2] = ipywidgets.FloatText(value=-1, description='Conv.Angle:', disabled=False, color='black',
45
- layout=ipywidgets.Layout(width='200px'))
46
- side_bar[row, 2] = ipywidgets.widgets.Label(value="mrad", layout=ipywidgets.Layout(width='100px'))
47
- row += 1
48
- side_bar[row, :2] = ipywidgets.FloatText(value=-0.1, description='Coll.Angle:', disabled=False, color='black',
49
- layout=ipywidgets.Layout(width='200px'))
50
- side_bar[row, 2] = ipywidgets.widgets.Label(value="mrad", layout=ipywidgets.Layout(width='100px'))
51
- row += 1
52
- side_bar[row, :2] = ipywidgets.FloatText(value=.1, description='Acc Voltage:', disabled=False, color='black',
53
- layout=ipywidgets.Layout(width='200px'))
54
- side_bar[row, 2] = ipywidgets.widgets.Label(value="keV", layout=ipywidgets.Layout(width='100px'))
55
-
56
- row += 1
57
- side_bar[row, :3] = ipywidgets.Button(description='Calibration',
58
- layout=ipywidgets.Layout(width='auto', grid_area='header'),
59
- style=ipywidgets.ButtonStyle(button_color='lightblue'))
60
- row += 1
61
- side_bar[row, :2] = ipywidgets.FloatText(value=0.1, description='Pixel_Time:', disabled=False, color='black',
62
- layout=ipywidgets.Layout(width='200px'))
63
- side_bar[row, 2] = ipywidgets.widgets.Label(value="μs", layout=ipywidgets.Layout(width='100px'))
64
- row += 1
65
- side_bar[row, :2] = ipywidgets.FloatText(value=7.5, description='Screen Curr:', disabled=False, color='black',
66
- layout=ipywidgets.Layout(width='200px'))
67
- side_bar[row, 2] = ipywidgets.widgets.Label(value="pA", layout=ipywidgets.Layout(width='50px'))
68
- row += 1
69
-
70
- side_bar[row, 0] = ipywidgets.Button(description='FFT', disabled=True,
71
- layout=ipywidgets.Layout(width='auto'),
72
- style=ipywidgets.ButtonStyle(button_color='lightblue'))
73
- side_bar[row, 1] = ipywidgets.Button(description='LR-Decon', disabled=True,
74
- layout=ipywidgets.Layout(width='auto'),
75
- style=ipywidgets.ButtonStyle(button_color='lightblue'))
76
- side_bar[row, 2] = ipywidgets.Button(description='Find atoms', disabled=True,
77
- layout=ipywidgets.Layout(width='auto'),
78
- style=ipywidgets.ButtonStyle(button_color='lightblue'))
79
-
80
- row += 1
81
- side_bar[row, :3] = ipywidgets.Button(description='Image Stack',
82
- layout=ipywidgets.Layout(width='auto', grid_area='header'),
83
- style=ipywidgets.ButtonStyle(button_color='lightblue'))
84
- row += 1
85
- side_bar[row, 0] = ipywidgets.Button(description='Rig Reg.', disabled=True,
86
- layout=ipywidgets.Layout(width='auto'),
87
- style=ipywidgets.ButtonStyle(button_color='lightblue'))
88
- side_bar[row, 1] = ipywidgets.Button(description='Demon', disabled=True,
89
- layout=ipywidgets.Layout(width='auto'),
90
- style=ipywidgets.ButtonStyle(button_color='lightblue'))
91
- side_bar[row, 2] = ipywidgets.Button(description='Sum', disabled=True,
92
- layout=ipywidgets.Layout(width='auto'),
93
- style=ipywidgets.ButtonStyle(button_color='lightblue'))
94
-
95
- side_bar[-2, 0].layout.display = "none"
96
- for i in range(3):
97
- side_bar[-1, i].layout.display = "none"
98
- return side_bar
99
-
100
-
101
- def get_info_sidebar() -> Any:
102
- side_bar = ipywidgets.GridspecLayout(18, 3, width='auto', grid_gap="0px")
103
-
104
- side_bar[0, :2] = ipywidgets.Dropdown(
105
- options=[('None', 0)],
106
- value=0,
107
- description='Main Dataset:',
108
- disabled=False)
109
-
110
- row = 1
111
- side_bar[row, :3] = ipywidgets.Button(description='Energy Scale',
112
- layout=ipywidgets.Layout(width='auto', grid_area='header'),
113
- style=ipywidgets.ButtonStyle(button_color='lightblue'))
114
- row += 1
115
- side_bar[row, :2] = ipywidgets.FloatText(value=7.5, description='Offset:', disabled=False, color='black',
116
- layout=ipywidgets.Layout(width='200px'))
117
- side_bar[row, 2] = ipywidgets.widgets.Label(value="eV", layout=ipywidgets.Layout(width='20px'))
118
- row += 1
119
- side_bar[row, :2] = ipywidgets.FloatText(value=0.1, description='Dispersion:', disabled=False, color='black',
120
- layout=ipywidgets.Layout(width='200px'))
121
- side_bar[row, 2] = ipywidgets.widgets.Label(value="eV", layout=ipywidgets.Layout(width='20px'))
122
- row += 1
123
- side_bar[row, :3] = ipywidgets.Button(description='Microscope',
124
- layout=ipywidgets.Layout(width='auto', grid_area='header'),
125
- style=ipywidgets.ButtonStyle(button_color='lightblue'))
126
- row += 1
127
- side_bar[row, :2] = ipywidgets.FloatText(value=-1, description='Conv.Angle:', disabled=False, color='black',
128
- layout=ipywidgets.Layout(width='200px'))
129
- side_bar[row, 2] = ipywidgets.widgets.Label(value="mrad", layout=ipywidgets.Layout(width='100px'))
130
- row += 1
131
- side_bar[row, :2] = ipywidgets.FloatText(value=-0.1, description='Coll.Angle:', disabled=False, color='black',
132
- layout=ipywidgets.Layout(width='200px'))
133
- side_bar[row, 2] = ipywidgets.widgets.Label(value="mrad", layout=ipywidgets.Layout(width='100px'))
134
- row += 1
135
- side_bar[row, :2] = ipywidgets.FloatText(value=0.1, description='Acc Voltage:', disabled=False, color='black',
136
- layout=ipywidgets.Layout(width='200px'))
137
- side_bar[row, 2] = ipywidgets.widgets.Label(value="keV", layout=ipywidgets.Layout(width='100px'))
138
-
139
- row += 1
140
- side_bar[row, :3] = ipywidgets.Button(description='Calibration',
141
- layout=ipywidgets.Layout(width='auto', grid_area='header'),
142
- style=ipywidgets.ButtonStyle(button_color='lightblue'))
143
- row += 1
144
- side_bar[row, :2] = ipywidgets.Dropdown(
145
- options=[('None', 0)],
146
- value=0,
147
- description='Reference:',
148
- disabled=False)
149
- side_bar[row, 2] = ipywidgets.ToggleButton(description='Probability',
150
- disabled=False,
151
- button_style='', # 'success', 'info', 'warning', 'danger' or ''
152
- tooltip='Changes y-axis to probability if flux is given',
153
- layout=ipywidgets.Layout(width='100px'))
154
- row += 1
155
- side_bar[row, :2] = ipywidgets.FloatText(value=0.1, description='Exp_Time:', disabled=False, color='black',
156
- layout=ipywidgets.Layout(width='200px'))
157
- side_bar[row, 2] = ipywidgets.widgets.Label(value="s", layout=ipywidgets.Layout(width='100px'))
158
- row += 1
159
- side_bar[row, :2] = ipywidgets.FloatText(value=7.5, description='Flux:', disabled=False, color='black',
160
- layout=ipywidgets.Layout(width='200px'))
161
- side_bar[row, 2] = ipywidgets.widgets.Label(value="Mcounts", layout=ipywidgets.Layout(width='50px'))
162
- row += 1
163
- side_bar[row, :2] = ipywidgets.FloatText(value=0.1, description='Conversion:', disabled=False, color='black',
164
- layout=ipywidgets.Layout(width='200px'))
165
- side_bar[row, 2] = ipywidgets.widgets.Label(value="e⁻/counts", layout=ipywidgets.Layout(width='100px'))
166
- row += 1
167
- side_bar[row, :2] = ipywidgets.FloatText(value=0.1, description='Current:', disabled=False, color='black',
168
- layout=ipywidgets.Layout(width='200px'))
169
- side_bar[row, 2] = ipywidgets.widgets.Label(value="pA", layout=ipywidgets.Layout(width='100px'))
170
-
171
- row += 1
172
- side_bar[row, 0] = ipywidgets.Button(description='Get Shift', disabled=True,
173
- layout=ipywidgets.Layout(width='auto'),
174
- style=ipywidgets.ButtonStyle(button_color='lightblue'))
175
- side_bar[row, 1] = ipywidgets.Button(description='Shift Spec', disabled=True,
176
- layout=ipywidgets.Layout(width='auto'),
177
- style=ipywidgets.ButtonStyle(button_color='lightblue'))
178
- """
179
- side_bar[row, 2] = ipywidgets.Button(description='Res.Fct.', disabled=True,
180
- layout=ipywidgets.Layout(width='auto'),
181
- style=ipywidgets.ButtonStyle(button_color='lightblue'))
182
- """
183
-
184
- row += 1
185
- side_bar[row, :3] = ipywidgets.Button(description='Spectrum Image',
186
- layout=ipywidgets.Layout(width='auto', grid_area='header'),
187
- style=ipywidgets.ButtonStyle(button_color='lightblue'))
188
-
189
- row += 1
190
- side_bar[row, :2] = ipywidgets.IntText(value=1, description='bin X:', disabled=False, color='black',
191
- layout=ipywidgets.Layout(width='200px'))
192
- row += 1
193
- side_bar[row, :2] = ipywidgets.IntText(value=1, description='bin Y:', disabled=False, color='black',
194
- layout=ipywidgets.Layout(width='200px'))
195
-
196
- for i in range(15, 18):
197
- side_bar[i, 0].layout.display = "none"
198
- return side_bar
199
-
200
-
201
-
202
- def get_file_widget_ui():
203
- side_bar = ipywidgets.GridspecLayout(7, 3, height='500px', width='auto', grid_gap="0px")
204
- row = 0
205
- side_bar[row, :3] = ipywidgets.Dropdown(options=['None'], value='None', description='directory:', disabled=False,
206
- button_style='', layout=ipywidgets.Layout(width='auto', grid_area='header'))
207
- row += 1
208
- side_bar[row, :3] = ipywidgets.Select(options=['.'], value='.', description='Select file:', disabled=False,
209
- rows=10, layout=ipywidgets.Layout(width='auto'))
210
- row += 1
211
- side_bar[row, 0] = ipywidgets.Button(description='Select Main',
212
- layout=ipywidgets.Layout(width='100px'),
213
- style=ipywidgets.ButtonStyle(button_color='lightblue'))
214
- side_bar[row, 1] = ipywidgets.Button(description='Add',
215
- layout=ipywidgets.Layout(width='50px'),
216
- style=ipywidgets.ButtonStyle(button_color='lightblue'))
217
- side_bar[row, 2] = ipywidgets.Dropdown(options=['None'], value='None', description='loaded:', disabled=False,
218
- button_style='')
219
-
220
- row += 1
221
- side_bar[row, :3] = ipywidgets.Select(options=['None'], value='None', description='Spectral:',
222
- disabled=False, rows=3, layout=ipywidgets.Layout(width='auto'))
223
- row += 1
224
- side_bar[row, :3] = ipywidgets.Select(options=['Sum'], value='Sum', description='Images:',
225
- disabled=False, rows=3, layout=ipywidgets.Layout(width='auto'))
226
- row += 1
227
- side_bar[row, :3] = ipywidgets.Select(options=['None'], value='None', description='Survey:',
228
- disabled=False, rows=2, layout=ipywidgets.Layout(width='auto'))
229
- for i in range(3, 6):
230
- side_bar[i, 0].layout.display = "none"
231
-
232
- row += 1
233
- side_bar[row, 0] = ipywidgets.Button(description='Save',
234
- layout=ipywidgets.Layout(width='100px'),
235
- style=ipywidgets.ButtonStyle(button_color='lightblue'))
236
- side_bar[row, 1] = ipywidgets.Text(
237
- value='Test.hf5',
238
- placeholder='Type something',
239
- description='File:',
240
- disabled=False
241
- )
242
- return side_bar
243
-
244
-
245
- class EELSBaseWidget(object):
246
-
247
- def __init__(self, datasets=None, sidebar=None, tab_title=None):
248
-
249
- self.datasets = datasets
250
- self.dataset = None
251
- self.save_path = False
252
- self.dir_dictionary = {}
253
- self.dir_list = ['.', '..']
254
- self.display_list = ['.', '..']
255
- self.dataset_list = ['None']
256
- self.image_list = ['Sum']
257
- self.dir_name = file_tools.get_last_path()
258
-
259
- self.key = None
260
- self.new_info = False
261
- self.image = 'Sum'
262
- if 'google.colab' in sys.modules:
263
- self.google = True
264
- else:
265
- self.google = False
266
- # self.google = True
267
-
268
- self.save_path = True
269
-
270
- if not os.path.isdir(self.dir_name):
271
- self.dir_name = '.'
272
-
273
- self.get_directory(self.dir_name)
274
- self.dir_list = ['.']
275
- self.extensions = '*'
276
- self.file_name = ''
277
- self.datasets = {}
278
- self.dataset = None
279
- self.sd0 = 0
280
- self.sds = 0
281
-
282
- self.bin_x = 0
283
- self.bin_y = 0
284
-
285
- self.start_channel = -1
286
- self.end_channel = -2
287
-
288
- self.file_bar = get_file_widget_ui()
289
- children = [self.file_bar]
290
- titles = ['File']
291
- if isinstance(sidebar, dict):
292
- for sidebar_key, sidebar_gui in sidebar.items():
293
- children.append(sidebar_gui)
294
- titles.append(sidebar_key)
295
- elif not isinstance(sidebar, list):
296
- children = [self.file_bar, sidebar]
297
- titles = ['File', 'Info']
298
- if sidebar is None:
299
- children = [self.file_bar]
300
- titles = ['File']
301
-
302
- if self.google:
303
- self.buttons = []
304
- for i in range(len(children)):
305
- self.buttons.append(ipywidgets.Button(description=titles[i],
306
- disabled=False,
307
- button_style='', # 'success', 'info', 'warning', 'danger' or ''
308
- layout=ipywidgets.Layout(width='800px')))
309
-
310
-
311
- self.tab_buttons = ipywidgets.ToggleButtons(options=titles, description='', disabled=False,
312
- layout=ipywidgets.Layout(width='auto'),
313
- style={"button_width": "auto"})
314
- tab = ipywidgets.VBox([self.tab_buttons, self.file_bar])
315
- self.children = children
316
-
317
- else:
318
- tab = ipywidgets.Tab()
319
- tab.children = children
320
- tab.titles = titles
321
-
322
- with plt.ioff():
323
- self.figure = plt.figure()
324
- self.tab =tab
325
- self.figure.canvas.toolbar_position = 'right'
326
- self.figure.canvas.toolbar_visible = True
327
-
328
- self.start_cursor = ipywidgets.FloatText(value=0, description='Start:', disabled=False, color='black',
329
- layout=ipywidgets.Layout(width='200px'))
330
- self.end_cursor = ipywidgets.FloatText(value=0, description='End:', disabled=False, color='black',
331
- layout=ipywidgets.Layout(width='200px'))
332
- self.statusbar = ipywidgets.Text(value='Starting',
333
- placeholder='Type something',
334
- description='Status:',
335
- disabled=True,
336
- layout=ipywidgets.Layout(width='100%'))
337
- self.panel = ipywidgets.VBox([ipywidgets.HBox([ipywidgets.Label('', layout=ipywidgets.Layout(width='100px')),
338
- ipywidgets.Label('Cursor:'),
339
- self.start_cursor, ipywidgets.Label('eV'),
340
- self.end_cursor, ipywidgets.Label('eV')]),
341
- self.figure.canvas,
342
- self.statusbar])
343
-
344
- self.app_layout = ipywidgets.AppLayout(
345
- left_sidebar=tab,
346
- center=self.panel,
347
- footer=None, # message_bar,
348
- pane_heights=[0, 10, 0],
349
- pane_widths=[4, 10, 0],
350
- )
351
- # self.set_dataset()
352
- self.change_y_scale = 1.0
353
- self.x = 0
354
- self.y = 0
355
- self.bin_x = 1
356
- self.bin_y = 1
357
- self.count = 0
358
- display(self.app_layout)
359
-
360
- self.select_files = self.file_bar[1, 0]
361
- self.path_choice = self.file_bar[0, 0]
362
- self.set_file_options()
363
- select_button = self.file_bar[2, 0]
364
- add_button = self.file_bar[2, 1]
365
- self.loaded_datasets = self.file_bar[2, 2]
366
- self.select_files.observe(self.get_file_name, names='value')
367
- self.path_choice.observe(self.set_dir, names='value')
368
-
369
- select_button.on_click(self.select_main)
370
- add_button.on_click(self.add_dataset)
371
- self.loaded_datasets.observe(self.select_dataset, names='value')
372
- self.file_bar[4, 0].observe(self.set_image, names='value')
373
- self.file_bar[5, 0].observe(self.set_survey_image, names='value')
374
-
375
- self.file_bar[6, 0].observe(self.save_datasets)
376
-
377
- def save_datasets(self, value=0):
378
- import warnings
379
- file_name = self.file_bar[6, 1].value
380
- path = self.path_choice.options[0]
381
- with warnings.catch_warnings():
382
- warnings.simplefilter("ignore")
383
- h5_group = file_tools.save_dataset(self.datasets, os.path.join(path, file_name))
384
- h5_group.file.close()
385
- self.status_message(' File saved')
386
-
387
- def status_message(self, out: str):
388
- self.statusbar.value = out
389
-
390
- def set_survey_image(self, key=None):
391
-
392
- self.datasets['_relationship']['survey_image'] = self.file_bar[5, 0].value
393
- # ToDo: Find boundaries of scan.
394
-
395
- def get_image(self):
396
- if self.file_bar[4, 0].value == 'Sum':
397
- spec_dim = self.dataset.get_dimensions_by_type(sidpy.DimensionType.SPECTRAL)
398
- if len(spec_dim) != 1:
399
- raise ValueError('Only one spectral dimension')
400
-
401
- channel_dim = self.dataset.get_dimensions_by_type(sidpy.DimensionType.CHANNEL)
402
-
403
- if len(channel_dim) > 1:
404
- raise ValueError('Maximal one channel dimension')
405
-
406
- if len(channel_dim) > 0:
407
- self.image = self.dataset.mean(axis=(spec_dim[0], channel_dim[0]))
408
- else:
409
- self.image = self.dataset.mean(axis=(spec_dim[0]))
410
- image_key = 'Sum'
411
- else:
412
- image_key = self.file_bar[4, 0].value.split(':')[0]
413
- self.image = self.datasets[image_key]
414
- self.datasets['_relationship']['image'] = image_key
415
-
416
- def set_image(self, key=None):
417
- self.get_image()
418
- self.plot()
419
-
420
- def plot(self, scale=True):
421
- self.figure.clear()
422
- spec_dims = self.dataset.get_spectral_dims(return_axis=True)
423
- if len(spec_dims)>0:
424
- self.energy_scale = spec_dims[0]
425
- if self.dataset.data_type.name == 'SPECTRUM':
426
- self.axis = self.figure.subplots(ncols=1)
427
- else:
428
- self.get_image()
429
- self.plot_spectrum_image()
430
- self.axis = self.axes[-1]
431
- self.spectrum = self.get_spectrum()
432
- self.plot_spectrum()
433
-
434
- else:
435
- self.axis = self.figure.subplots(ncols=1)
436
- self.plot_image()
437
-
438
- def plot_image(self):
439
- # image_dims = self.dataset.get_image_dims()
440
- image_dims = []
441
- for dim, axis in self.dataset._axes.items():
442
- if axis.dimension_type in [sidpy.DimensionType.SPATIAL, sidpy.DimensionType.RECIPROCAL]:
443
- image_dims.append(dim)
444
- self.img = self.axis.imshow(self.dataset.T, extent=self.dataset.get_extent(image_dims))
445
- self.axis.set_xlabel(self.dataset.labels[image_dims[0]])
446
- self.axis.set_ylabel(self.dataset.labels[image_dims[1]])
447
-
448
- cbar = self.figure.colorbar(self.img)
449
- cbar.set_label(self.dataset.data_descriptor)
450
- if 'annotations' in self.dataset.metadata:
451
- kwargs={'edgecolor': 'red', 'facecolor': 'None'}
452
-
453
- annotations = self.dataset.metadata['annotations']
454
- for key in annotations:
455
- if annotations[key]['type'] == 'spectral_image':
456
- rectangle = matplotlib.patches.Rectangle(annotations[key]['position'], annotations[key]['width'], annotations[key]['height'], **kwargs)
457
- self.axis.text(annotations[key]['position'][0], annotations[key]['position'][1], annotations[key]['label'], color='r')
458
- self.axis.add_artist(rectangle)
459
- elif annotations[key]['type'] == 'text':
460
- self.axis.text(annotations[key]['position'][0], annotations[key]['position'][1], annotations[key]['label'], color='r')
461
- elif annotations[key]['type'] == 'circle':
462
- circle = matplotlib.patches.Circle(annotations[key]['position'], annotations[key]['radius'], **kwargs)
463
- self.axis.add_artist(circle)
464
- self.figure.tight_layout()
465
- self.axis.ticklabel_format(style='sci', scilimits=(-2, 3))
466
- self.figure.tight_layout()
467
- self.figure.canvas.draw_idle()
468
-
469
-
470
- def plot_spectrum(self):
471
- self.axis.plot(self.energy_scale, self.spectrum, label='spectrum')
472
- x_limit = self.axis.get_xlim()
473
- y_limit = np.array(self.axis.get_ylim())
474
- self.xlabel = self.datasets[self.key].labels[0]
475
- self.ylabel = self.datasets[self.key].data_descriptor
476
- self.axis.set_xlabel(self.datasets[self.key].labels[0])
477
- self.axis.set_ylabel(self.datasets[self.key].data_descriptor)
478
- self.axis.ticklabel_format(style='sci', scilimits=(-2, 4))
479
-
480
- # if scale:
481
- # self.axis.set_ylim(np.array(y_limit)*self.change_y_scale)
482
- self.change_y_scale = 1.0
483
- if self.y_scale != 1.:
484
- self.axis.set_ylabel('scattering probability (ppm/eV)')
485
- self.selector = matplotlib.widgets.SpanSelector(self.axis, self.line_select_callback,
486
- direction="horizontal",
487
- interactive=True,
488
- props=dict(facecolor='blue', alpha=0.2))
489
- self.axis.legend()
490
- if self.dataset.data_type.name == 'SPECTRUM':
491
- self.axis.set_title(self.dataset.title)
492
- else:
493
- self.axis.set_title(f'spectrum {self.x}, {self.y}')
494
- self.figure.canvas.draw_idle()
495
-
496
- def _update(self, ev=None):
497
- if hasattr(self, 'axes'):
498
- xlim = np.array(self.axes[1].get_xlim())
499
- ylim = np.array(self.axes[1].get_ylim())
500
- self.axes[1].clear()
501
- self.axis = self.axes[-1]
502
- else:
503
- xlim = np.array(self.axis.get_xlim())
504
- ylim = np.array(self.axis.get_ylim())
505
- self.axis.clear()
506
- self.get_spectrum()
507
- if len(self.energy_scale) != self.spectrum.shape[0]:
508
- self.spectrum = self.spectrum.T
509
- # self.axis.plot(self.energy_scale, self.spectrum.compute(), label='experiment')
510
- self.axis.plot(self.energy_scale, self.spectrum, label='experiment')
511
-
512
- self.axis.set_title(f'spectrum {self.x}, {self.y}')
513
- self.figure.tight_layout()
514
- self.selector = matplotlib.widgets.SpanSelector(self.axis, self.line_select_callback,
515
- direction="horizontal",
516
- interactive=True,
517
- props=dict(facecolor='blue', alpha=0.2))
518
-
519
- self.axis.set_xlim(xlim)
520
- self.axis.set_ylim(ylim*self.change_y_scale)
521
- self.axis.set_xlabel(self.xlabel)
522
- self.axis.set_ylabel(self.ylabel)
523
- self.change_y_scale = 1.0
524
- self.update_tab_spectra()
525
- self.figure.canvas.draw_idle()
526
-
527
- def update_tab_spectra(self):
528
- pass
529
-
530
- def _onclick(self, event):
531
- self.event = event
532
- if event.inaxes in [self.axes[0]]:
533
- x = int(event.xdata)
534
- y = int(event.ydata)
535
-
536
- x = int(x - self.rectangle[0])
537
- y = int(y - self.rectangle[2])
538
-
539
- if x >= 0 and y >= 0:
540
- if x <= self.rectangle[1] and y <= self.rectangle[3]:
541
- self.x = int(x / (self.rect.get_width() / self.bin_x))
542
- self.y = int(y / (self.rect.get_height() / self.bin_y))
543
- image_dims = self.dataset.get_image_dims()
544
-
545
- if self.x + self.bin_x > self.dataset.shape[image_dims[0]]:
546
- self.x = self.dataset.shape[image_dims[0]] - self.bin_x
547
- if self.y + self.bin_y > self.dataset.shape[image_dims[1]]:
548
- self.y = self.dataset.shape[image_dims[1]] - self.bin_y
549
-
550
- self.rect.set_xy([self.x * self.rect.get_width() / self.bin_x + self.rectangle[0],
551
- self.y * self.rect.get_height() / self.bin_y + self.rectangle[2]])
552
- # self.get_spectrum()
553
- self._update()
554
- else:
555
- if event.dblclick:
556
- bottom = float(self.spectrum.min())
557
- if bottom < 0:
558
- bottom *= 1.02
559
- else:
560
- bottom *= 0.98
561
- top = float(self.spectrum.max())
562
- if top > 0:
563
- top *= 1.02
564
- else:
565
- top *= 0.98
566
- self.axis.set_ylim(bottom=bottom, top=top)
567
-
568
- def get_spectrum(self):
569
- if self.dataset.data_type.name == 'SPECTRUM':
570
- self.spectrum = self.dataset.copy()
571
- else:
572
- image_dims = self.dataset.get_dimensions_by_type(sidpy.DimensionType.SPATIAL)
573
- if self.x > self.dataset.shape[image_dims[0]] - self.bin_x:
574
- self.x = self.dataset.shape[image_dims[0]] - self.bin_x
575
- if self.y > self.dataset.shape[image_dims[1]] - self.bin_y:
576
- self.y = self.dataset.shape[image_dims[1]] - self.bin_y
577
- selection = []
578
- self.axis.clear()
579
- for dim, axis in self.dataset._axes.items():
580
- if axis.dimension_type == sidpy.DimensionType.SPATIAL:
581
- if dim == image_dims[0]:
582
- selection.append(slice(self.x, self.x + self.bin_x))
583
- else:
584
- selection.append(slice(self.y, self.y + self.bin_y))
585
-
586
- elif axis.dimension_type == sidpy.DimensionType.SPECTRAL:
587
- selection.append(slice(None))
588
- elif axis.dimension_type == sidpy.DimensionType.CHANNEL:
589
- selection.append(slice(None))
590
- else:
591
- selection.append(slice(0, 1))
592
-
593
- self.spectrum = self.dataset[tuple(selection)].mean(axis=tuple(image_dims))
594
-
595
- self.spectrum *= self.y_scale
596
-
597
- return self.spectrum.squeeze()
598
-
599
- def plot_spectrum_image(self):
600
- self.axes = self.figure.subplots(ncols=2)
601
- self.axis = self.axes[-1]
602
-
603
- self.rect = matplotlib.patches.Rectangle((0, 0), self.bin_x, self.bin_y, linewidth=1, edgecolor='r',
604
- facecolor='red', alpha=0.2)
605
- image_dims = self.dataset.get_image_dims()
606
-
607
- size_x = self.dataset.shape[image_dims[0]]
608
- size_y = self.dataset.shape[image_dims[1]]
609
- self.extent = [0, size_x, size_y, 0]
610
- self.rectangle = [0, size_x, 0, size_y]
611
- self.axes[0].imshow(self.image.T, extent=self.extent)
612
- self.axes[0].set_aspect('equal')
613
- self.axes[0].add_patch(self.rect)
614
- self.cid = self.axes[0].figure.canvas.mpl_connect('button_press_event', self._onclick)
615
-
616
- def line_select_callback(self, x_min, x_max):
617
- self.start_cursor.value = np.round(x_min, 3)
618
- self.end_cursor.value = np.round(x_max, 3)
619
-
620
- energy_scale = self.dataset.get_spectral_dims(return_axis=True)[0]
621
- self.start_channel = np.searchsorted(energy_scale, self.start_cursor.value)
622
- self.end_channel = np.searchsorted(energy_scale, self.end_cursor.value)
623
-
624
- def set_dataset(self, key=None):
625
-
626
- if len(self.datasets) == 0:
627
- data_set = sidpy.Dataset.from_array([0, 1], name='generic')
628
- data_set.set_dimension(0, sidpy.Dimension([0, 1], 'energy_loss', units='channel', quantity='generic',
629
- dimension_type='spectral'))
630
- data_set.data_type = 'spectrum'
631
- data_set.metadata = {'experiment': {'convergence_angle': 0,
632
- 'collection_angle': 0,
633
- 'acceleration_voltage': 0,
634
- 'exposure_time': 0}}
635
- self.datasets = {'Nothing': data_set}
636
- key = 'Nothing'
637
-
638
- dataset_key = key
639
-
640
- self.dataset_list = []
641
- dataset_keys = []
642
- for key in self.datasets.keys():
643
- if isinstance(self.datasets[key], sidpy.Dataset):
644
- self.dataset_list.append(f'{key}: {self.datasets[key].title}')
645
- dataset_keys.append(key)
646
- if dataset_key not in dataset_keys:
647
- dataset_key = dataset_keys[0]
648
- self.key = dataset_key
649
-
650
- self.dataset = self.datasets[self.key]
651
-
652
- spectral_dims = self.dataset.get_spectral_dims(return_axis=True)
653
- if len(spectral_dims) >0:
654
- self.energy_scale = spectral_dims[0]
655
- self.y_scale = 1.0
656
- self.change_y_scale = 1.0
657
- self.x = 0
658
- self.y = 0
659
- self.bin_x = 1
660
- self.bin_y = 1
661
- self.count = 0
662
-
663
- self.update_sidebars()
664
- #self.update_sidebar()
665
- self.plot()
666
-
667
- def update_sidebars(self):
668
- pass
669
-
670
- def select_main(self, value=0):
671
- self.sds +=1
672
- self.datasets = {}
673
- # self.loaded_datasets.options = self.dataset_list
674
-
675
- self.datasets = file_tools.open_file(self.file_name)
676
-
677
- file_tools.save_path(self.file_name)
678
- self.dataset_list = []
679
- self.image_list = ['Sum']
680
- self.survey_list = ['None']
681
- self.spectral_list = ['None']
682
- for key in self.datasets.keys():
683
- if isinstance(self.datasets[key], sidpy.Dataset):
684
- self.dataset_list.append(f'{key}: {self.datasets[key].title}')
685
- if 'SPECTR' in self.datasets[key].data_type.name:
686
- self.spectral_list.append(f'{key}: {self.datasets[key].title}')
687
- if 'IMAGE' == self.datasets[key].data_type.name:
688
- if 'survey' in self.datasets[key].title.lower():
689
- self.survey_list.append(f'{key}: {self.datasets[key].title}')
690
- else:
691
- self.image_list.append(f'{key}: {self.datasets[key].title}')
692
-
693
-
694
- self.key = self.dataset_list[0].split(':')[0]
695
- self.dataset = self.datasets[self.key]
696
- self.new_info = True
697
-
698
- self.selected_dataset = self.dataset
699
- if len(self.image_list) > 0:
700
- self.file_bar[4, 0].options = self.image_list
701
- self.file_bar[5, 0].options = self.survey_list
702
- self.file_bar[4, 0].layout.display = "flex"
703
- self.file_bar[4, 0].value = self.image_list[0]
704
- self.file_bar[5, 0].layout.display = "flex"
705
- self.file_bar[5, 0].value = self.survey_list[0]
706
-
707
- self.file_bar[3, 0].options = self.dataset_list
708
- self.loaded_datasets.options = self.dataset_list
709
- self.loaded_datasets.value = self.dataset_list[0]
710
- path, filename = os.path.split(self.file_name)
711
- name, extension = os.path.splitext(filename)
712
- self.file_bar[6, 1].value = name+'.hf5'
713
- self.status_message(' New file loaded')
714
-
715
- def add_dataset(self, value=0):
716
- key = file_tools.add_dataset_from_file(self.datasets, self.file_name, 'Channel')
717
- self.dataset_list.append(f'{key}: {self.datasets[key].title}')
718
- self.loaded_datasets.options = self.dataset_list
719
- self.loaded_datasets.value = self.dataset_list[-1]
720
-
721
- if 'SPECTR' in self.datasets[key].data_type.name:
722
- self.spectral_list.append(f'{key}: {self.datasets[key].title}')
723
- if 'IMAGE' == self.datasets[key].data_type.name:
724
- if 'survey' in self.datasets[key].title.lower():
725
- self.survey_list.append(f'{key}: {self.datasets[key].title}')
726
- self.file_bar[5, 0].options = self.survey_list
727
- else:
728
- self.image_list.append(f'{key}: {self.datasets[key].title}')
729
- self.file_bar[4, 0].options = self.image_list
730
- self.status_message(' image list file loaded')
731
-
732
- def get_directory(self, directory='.'):
733
- self.dir_name = directory
734
- self.dir_dictionary = {}
735
- self.dir_list = []
736
- self.dir_list = ['.', '..'] + os.listdir(directory)
737
-
738
- def set_dir(self, value=0):
739
- self.dir_name = self.path_choice.value
740
- self.select_files.index = 0
741
- self.set_file_options()
742
-
743
- def select_dataset(self, value=0):
744
- key = self.loaded_datasets.value.split(':')[0]
745
- if key != 'None':
746
- self.selected_dataset = self.datasets[key]
747
- self.selected_key = key
748
- self.key = key
749
- self.datasets['_relationship'] = {'main_dataset': self.key}
750
-
751
- self.set_dataset()
752
-
753
- def set_file_options(self):
754
- self.dir_name = os.path.abspath(os.path.join(self.dir_name, self.dir_list[self.select_files.index]))
755
- dir_list = os.listdir(self.dir_name)
756
- file_dict = file_tools.update_directory_list(self.dir_name)
757
-
758
- sort = np.argsort(file_dict['directory_list'])
759
- self.dir_list = ['.', '..']
760
- self.display_list = ['.', '..']
761
- for j in sort:
762
- self.display_list.append(f" * {file_dict['directory_list'][j]}")
763
- self.dir_list.append(file_dict['directory_list'][j])
764
-
765
- sort = np.argsort(file_dict['display_file_list'])
766
-
767
- for i, j in enumerate(sort):
768
- if '--' in dir_list[j]:
769
- self.display_list.append(f" {i:3} {file_dict['display_file_list'][j]}")
770
- else:
771
- self.display_list.append(f" {i:3} {file_dict['display_file_list'][j]}")
772
- self.dir_list.append(file_dict['file_list'][j])
773
-
774
- self.dir_label = os.path.split(self.dir_name)[-1] + ':'
775
- self.select_files.options = self.display_list
776
-
777
- path = self.dir_name
778
- old_path = ' '
779
- path_list = []
780
- while path != old_path:
781
- path_list.append(path)
782
- old_path = path
783
- path = os.path.split(path)[0]
784
- self.path_choice.options = path_list
785
- self.path_choice.value = path_list[0]
786
-
787
- def get_file_name(self, b):
788
-
789
- if os.path.isdir(os.path.join(self.dir_name, self.dir_list[self.select_files.index])):
790
- self.set_file_options()
791
-
792
- elif os.path.isfile(os.path.join(self.dir_name, self.dir_list[self.select_files.index])):
793
- self.file_name = os.path.join(self.dir_name, self.dir_list[self.select_files.index])
794
-
795
- class EELSWidget(EELSBaseWidget):
796
- def __init__(self, datasets=None):
797
- self.lowloss_key = 'None'
798
- self.coreloss_key = 'None'
799
- self.info_key = 'None'
800
- self.tabval = 0
801
-
802
- sidebar = {'Spec.': get_info_sidebar(),
803
- 'LowLoss': get_low_loss_sidebar(),
804
- 'CoreLoss': get_core_loss_sidebar()}
805
- super().__init__(datasets, sidebar)
806
- self.info_tab = sidebar['Spec.']
807
- self.core_loss_tab = sidebar['CoreLoss']
808
- self.low_loss_tab = sidebar['LowLoss']
809
- super().set_dataset()
810
- self.info = Info(self.info_tab, self)
811
- self.low_loss = LowLoss(self.low_loss_tab, self)
812
- self.core_loss = CoreLoss(self.core_loss_tab, self)
813
-
814
- self.set_action()
815
-
816
- def set_action(self):
817
- if self.google:
818
- self.tab_buttons.observe(self.tab_activated)
819
- self.tab.observe(self.tab_activated)
820
-
821
- def tab_activated(self, val=0):
822
- if self.google:
823
- self.tab.children = [self.tab_buttons, self.children[self.tab_buttons.index]] # update sidebar gui
824
- self.tabval = self.tab_buttons.index
825
- else:
826
- if isinstance(val.new, int):
827
- self.tabval = val.new
828
- # self.update_sidebars()
829
- if self.tabval == 1:
830
- self.info.update_dataset()
831
- elif self.tabval == 2:
832
- self.low_loss.update_ll_sidebar()
833
- elif self.tabval == 3:
834
- self.core_loss.update_cl_sidebar()
835
-
836
-
837
- def update_tab_spectra(self):
838
- if self.tabval == 2:
839
- self.low_loss._update()
840
-
841
-
842
- def update_sidebars(self):
843
- if hasattr(self, 'info'):
844
- self.info.update_sidebar()
845
- #if hasattr(self, 'low_loss'):
846
- # self.low_loss.update_ll_sidebar()
847
- #if hasattr(self, 'core_loss'):
848
- # self.core_loss.update_cl_sidebar()
849
-
850
- class Info(object):
851
- def __init__(self, sidebar=None, parent=None):
852
- self.parent = parent
853
- self.info_tab = sidebar
854
- self.key = self.parent.info_key
855
- self.update_sidebar()
856
- self.set_action()
857
- self.count =0
858
-
859
- def set_energy_scale(self, value):
860
- self.ens = 1
861
- self.energy_scale = self.parent.datasets[self.key].get_spectral_dims(return_axis=True)[0]
862
- dispersion = self.parent.datasets[self.key].get_dimension_slope(self.energy_scale)
863
- self.ens = dispersion
864
- self.energy_scale *= (self.info_tab[3, 0].value / dispersion)
865
- self.energy_scale += (self.info_tab[2, 0].value - self.energy_scale[0])
866
- self.parent.plot()
867
-
868
- def set_y_scale(self, value):
869
- self.count += 1
870
- self.parent.change_y_scale = 1.0 / self.parent.y_scale
871
- if self.parent.datasets[self.parent.key].metadata['experiment']['flux_ppm'] > 1e-12:
872
- if self.info_tab[9, 2].value:
873
- dispersion = self.parent.datasets[self.parent.key].get_dimension_slope(self.parent.energy_scale)
874
- self.parent.y_scale = 1 / self.parent.datasets[self.parent.key].metadata['experiment']['flux_ppm'] * dispersion
875
- self.parent.ylabel = 'scattering probability (ppm)'
876
- else:
877
- self.parent.y_scale = 1.0
878
- self.parent.ylabel = 'intensity (counts)'
879
- self.parent.change_y_scale *= self.parent.y_scale
880
- self.parent._update()
881
-
882
- def set_flux(self, value):
883
- # self.parent.datasets[self.key].metadata['experiment']['exposure_time'] = self.info_tab[10, 0].value
884
- if self.info_tab[9, 0].value == 'None':
885
- self.parent.datasets[self.parent.key].metadata['experiment']['flux_ppm'] = 0.
886
- else:
887
- ll_key = self.info_tab[9, 0].value.split(':')[0]
888
- self.parent.datasets['_relationship']['low_loss'] = ll_key
889
- self.parent.lowloss_key = ll_key
890
- spectrum_dimensions = self.parent.dataset.get_spectral_dims()
891
-
892
- number_of_pixels = 1
893
- for index, dimension in enumerate(self.parent.dataset.shape):
894
- if index not in spectrum_dimensions:
895
- number_of_pixels *= dimension
896
- if self.parent.datasets[ll_key].metadata['experiment']['exposure_time'] == 0.0:
897
- if self.parent.datasets[ll_key].metadata['experiment']['single_exposure_time'] == 0.0:
898
- return
899
- else:
900
- self.parent.datasets[ll_key].metadata['experiment']['exposure_time'] = (self.parent.datasets[ll_key].metadata['experiment']['single_exposure_time'] *
901
- self.parent.datasets[ll_key].metadata['experiment']['number_of_frames'])
902
-
903
- self.parent.datasets[self.parent.key].metadata['experiment']['flux_ppm'] = ((np.array(self.parent.datasets[ll_key])*1e-6).sum() /
904
- self.parent.datasets[ll_key].metadata['experiment']['exposure_time'] /
905
- number_of_pixels)
906
- self.parent.datasets[self.parent.key].metadata['experiment']['flux_ppm'] *= self.parent.datasets[self.parent.key].metadata['experiment']['exposure_time']
907
- if 'SPECT' in self.parent.datasets[ll_key].data_type.name:
908
- self.info_tab[14, 0].disabled = False
909
- self.info_tab[11, 0].value = np.round(self.parent.datasets[self.parent.key].metadata['experiment']['flux_ppm'], 2)
910
-
911
- def set_microscope_parameter(self, value):
912
- if not self.parent.new_info:
913
- self.parent.datasets[self.key].metadata['experiment']['convergence_angle'] = self.info_tab[5, 0].value
914
- self.parent.datasets[self.key].metadata['experiment']['collection_angle'] = self.info_tab[6, 0].value
915
- self.parent.datasets[self.key].metadata['experiment']['acceleration_voltage'] = self.info_tab[7, 0].value*1000
916
-
917
- def cursor2energy_scale(self, value):
918
- self.energy_scale = self.parent.datasets[self.key].get_spectral_dims(return_axis=True)[0]
919
- dispersion = (self.parent.end_cursor.value - self.parent.start_cursor.value) / (self.parent.end_channel - self.parent.start_channel)
920
-
921
- self.energy_scale *= (self.info_tab[3, 0].value/dispersion)
922
-
923
- offset = self.parent.start_cursor.value - self.parent.start_channel * dispersion
924
- self.parent.energy_scale += (self.info_tab[2, 0].value-self.parent.energy_scale[0])
925
- self.info_tab[2, 0].value = np.round(offset,4)
926
- self.info_tab[3, 0].value = np.round(dispersion,4)
927
- self.parent.plot()
928
-
929
- def set_binning(self, value):
930
- if 'SPECTRAL' in self.parent.dataset.data_type.name:
931
- image_dims = self.parent.dataset.get_image_dims()
932
-
933
- self.bin_x = int(self.info_tab[16, 0].value)
934
- self.bin_y = int(self.info_tab[17, 0].value)
935
- if self.bin_x < 1:
936
- self.bin_x = 1
937
- self.info_tab[16, 0].value = self.bin_x
938
- if self.bin_y < 1:
939
- self.bin_y = 1
940
- self.info_tab[17, 0].value = self.bin_y
941
- if self.bin_x > self.parent.dataset.shape[image_dims[0]]:
942
- self.bin_x = self.parent.dataset.shape[image_dims[0]]
943
- self.info_tab[16, 0].value = self.bin_x
944
- if self.bin_y > self.parent.dataset.shape[image_dims[1]]:
945
- self.bin_y = self.parent.dataset.shape[image_dims[1]]
946
- self.info_tab[17, 0].value = self.bin_y
947
- self.parent.bin_x = self.bin_x
948
- self.parent.bin_y = self.bin_y
949
-
950
- self.parent.datasets[self.key].metadata['experiment']['SI_bin_x'] = self.bin_x
951
- self.parent.datasets[self.key].metadata['experiment']['SI_bin_y'] = self.bin_y
952
- self.parent.plot()
953
-
954
-
955
-
956
- def update_sidebar(self):
957
- spectrum_list = ['None']
958
- reference_list = ['None']
959
- data_list = []
960
-
961
- self.key = self.info_key = self.parent.info_key
962
-
963
- spectrum_data = False
964
- info_index= 0
965
- for key in self.parent.datasets.keys():
966
- if isinstance(self.parent.datasets[key], sidpy.Dataset):
967
- if key[0] != '_' :
968
- data_list.append(f'{key}: {self.parent.datasets[key].title}')
969
- if 'SPECTR' in self.parent.datasets[key].data_type.name:
970
- spectrum_data = True
971
- spectrum_list.append(f'{key}: {self.parent.datasets[key].title}')
972
- if self.info_key == key:
973
- info_index = len(spectrum_list)-1
974
- reference_list.append(f'{key}: {self.parent.datasets[key].title}')
975
- self.info_tab[0, 0].options = spectrum_list
976
- self.info_tab[9, 0].options = reference_list
977
- self.info_tab[0, 0].value = spectrum_list[info_index]
978
-
979
- if 'SPECTRUM' in self.parent.dataset.data_type.name:
980
- for i in range(15, 18):
981
- self.info_tab[i, 0].layout.display = "none"
982
- else:
983
- for i in range(15, 18):
984
- self.info_tab[i, 0].layout.display = "flex"
985
-
986
- if 'None' not in self.key:
987
- self.parent.new_info = True
988
- energy_scale = self.parent.datasets[self.key].get_spectral_dims(return_axis=True)
989
- if len(energy_scale) == 0:
990
- return
991
- energy_scale = energy_scale[0]
992
- offset = energy_scale[0]
993
- # dispersion = self.parent.datasets[self.key].get_dimension_slope(energy_scale)
994
- dispersion = energy_scale[1] - offset
995
-
996
- # self.info_tab[0,0].value = dataset_index #f'{self.key}: {self.parent.datasets[self.key].title}'
997
- self.info_tab[2, 0].value = np.round(offset, 3)
998
- self.info_tab[3, 0].value = np.round(dispersion, 4)
999
- self.info_tab[5, 0].value = np.round(self.parent.datasets[self.key].metadata['experiment']['convergence_angle'], 1)
1000
- self.info_tab[6, 0].value = np.round(self.parent.datasets[self.key].metadata['experiment']['collection_angle'], 1)
1001
- self.info_tab[7, 0].value = np.round(self.parent.datasets[self.key].metadata['experiment']['acceleration_voltage']/1000, 1)
1002
- # print(self.parent.datasets[self.key].metadata['experiment']['acceleration_voltage'])
1003
- self.info_tab[10, 0].value = np.round(self.parent.datasets[self.key].metadata['experiment']['exposure_time'], 4)
1004
- if 'flux_ppm' not in self.parent.datasets[self.key].metadata['experiment']:
1005
- self.parent.datasets[self.key].metadata['experiment']['flux_ppm'] = 0
1006
- self.info_tab[11, 0].value = self.parent.datasets[self.key].metadata['experiment']['flux_ppm']
1007
- if 'count_conversion' not in self.parent.datasets[self.key].metadata['experiment']:
1008
- self.parent.datasets[self.key].metadata['experiment']['count_conversion'] = 1
1009
- self.info_tab[12, 0].value = self.parent.datasets[self.key].metadata['experiment']['count_conversion']
1010
- if 'beam_current' not in self.parent.datasets[self.key].metadata['experiment']:
1011
- self.parent.datasets[self.key].metadata['experiment']['beam_current'] = 0
1012
- self.info_tab[13, 0].value = self.parent.datasets[self.key].metadata['experiment']['beam_current']
1013
- ll_key = 'None'
1014
- if '_relationship' in self.parent.datasets:
1015
- if 'low_loss' in self.parent.datasets['_relationship']:
1016
- ll_key = self.parent.datasets['_relationship']['low_loss']
1017
- ll_key = f'{ll_key}: {self.parent.datasets[ll_key].title}'
1018
- self.lowloss_key = ll_key
1019
- self.info_tab[9, 0].value = ll_key
1020
- self.parent.new_info = False
1021
-
1022
- def update_dataset(self, value=0):
1023
- self.key = self.info_tab[0, 0].value.split(':')[0]
1024
-
1025
- self.info_key = self.key
1026
- self.parent.info_key = self.key
1027
-
1028
- if self.info_key != 'None':
1029
- self.parent.set_dataset(self.info_key)
1030
- self.parent.status_message(self.key+' , '+ self.parent.info_key)
1031
- if '_relationship' in self.parent.datasets.keys():
1032
- self.parent.datasets['_relationship']['spectrum'] = self.info_key
1033
- self.update_sidebar()
1034
- self.parent._update(0)
1035
-
1036
- def shift_low_loss(self, value=0):
1037
- if 'low_loss' in self.parent.datasets['_relationship']:
1038
- low_loss = self.parent.datasets[self.parent.datasets['_relationship']['low_loss']]
1039
-
1040
- self.parent.datasets['shifted_low_loss'] = eels_tools.align_zero_loss(low_loss)
1041
- self.parent.datasets['shifted_low_loss'].title = self.parent.dataset.title + '_shifted'
1042
- self.parent.datasets['_relationship']['low_loss'] = 'shifted_low_loss'
1043
- self.update_sidebar()
1044
-
1045
- if 'low_loss' in self.parent.datasets['_relationship']:
1046
- if 'zero_loss' in self.parent.datasets[self.parent.datasets['_relationship']['low_loss']].metadata:
1047
- if 'shifted' in self.parent.datasets[self.parent.datasets['_relationship']['low_loss']].metadata['zero_loss'].keys():
1048
- self.info_tab[14, 1].disabled = False
1049
-
1050
-
1051
- def shift_spectrum(self, value=0):
1052
- shifts = self.parent.dataset.shape
1053
- if 'low_loss' in self.parent.datasets['_relationship']:
1054
- if 'zero_loss' in self.parent.datasets[self.parent.datasets['_relationship']['low_loss']].metadata:
1055
- if 'shifted' in self.parent.datasets[self.parent.datasets['_relationship']['low_loss']].metadata['zero_loss'].keys():
1056
- shifts = self.parent.datasets[self.parent.datasets['_relationship']['low_loss']].metadata['zero_loss']['shifted']
1057
- shifts_new = shifts.copy()
1058
- if 'zero_loss' in self.parent.dataset.metadata:
1059
- if 'shifted' in self.parent.dataset.metadata['zero_loss'].keys():
1060
- shifts_new = shifts-self.parent.dataset.metadata['zero_loss']['shifted']
1061
- else:
1062
- self.parent.dataset.metadata['zero_loss'] = {}
1063
-
1064
-
1065
- self.parent.dataset = eels_tools.shift_energy(self.parent.dataset, shifts_new)
1066
- self.parent.dataset.metadata['zero_loss']['shifted'] = shifts
1067
- self.parent.plot()
1068
-
1069
-
1070
- def set_action(self):
1071
- self.info_tab[0, 0].observe(self.update_dataset, names='value')
1072
- self.info_tab[1, 0].on_click(self.cursor2energy_scale)
1073
- self.info_tab[2, 0].observe(self.set_energy_scale, names='value')
1074
- self.info_tab[3, 0].observe(self.set_energy_scale, names='value')
1075
- self.info_tab[5, 0].observe(self.set_microscope_parameter)
1076
- self.info_tab[6, 0].observe(self.set_microscope_parameter)
1077
- self.info_tab[7, 0].observe(self.set_microscope_parameter)
1078
- self.info_tab[9, 0].observe(self.set_flux, names='value')
1079
- self.info_tab[9, 2].observe(self.set_y_scale, names='value')
1080
- self.info_tab[10, 0].observe(self.set_flux)
1081
- self.info_tab[14, 0].on_click(self.shift_low_loss)
1082
- self.info_tab[14, 1].on_click(self.shift_spectrum)
1083
- self.info_tab[14, 1].on_click(self.shift_spectrum)
1084
-
1085
- self.info_tab[16, 0].observe(self.set_binning)
1086
- self.info_tab[17, 0].observe(self.set_binning)