pyTEMlib 0.2025.4.1__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.
- build/lib/pyTEMlib/__init__.py +33 -0
- build/lib/pyTEMlib/animation.py +640 -0
- build/lib/pyTEMlib/atom_tools.py +238 -0
- build/lib/pyTEMlib/config_dir.py +31 -0
- build/lib/pyTEMlib/crystal_tools.py +1219 -0
- build/lib/pyTEMlib/diffraction_plot.py +756 -0
- build/lib/pyTEMlib/dynamic_scattering.py +293 -0
- build/lib/pyTEMlib/eds_tools.py +826 -0
- build/lib/pyTEMlib/eds_xsections.py +432 -0
- build/lib/pyTEMlib/eels_tools/__init__.py +44 -0
- build/lib/pyTEMlib/eels_tools/core_loss_tools.py +751 -0
- build/lib/pyTEMlib/eels_tools/eels_database.py +134 -0
- build/lib/pyTEMlib/eels_tools/low_loss_tools.py +655 -0
- build/lib/pyTEMlib/eels_tools/peak_fit_tools.py +175 -0
- build/lib/pyTEMlib/eels_tools/zero_loss_tools.py +264 -0
- build/lib/pyTEMlib/file_reader.py +274 -0
- build/lib/pyTEMlib/file_tools.py +811 -0
- build/lib/pyTEMlib/get_bote_salvat.py +69 -0
- build/lib/pyTEMlib/graph_tools.py +1153 -0
- build/lib/pyTEMlib/graph_viz.py +599 -0
- build/lib/pyTEMlib/image/__init__.py +37 -0
- build/lib/pyTEMlib/image/image_atoms.py +270 -0
- build/lib/pyTEMlib/image/image_clean.py +197 -0
- build/lib/pyTEMlib/image/image_distortion.py +299 -0
- build/lib/pyTEMlib/image/image_fft.py +277 -0
- build/lib/pyTEMlib/image/image_graph.py +926 -0
- build/lib/pyTEMlib/image/image_registration.py +316 -0
- build/lib/pyTEMlib/image/image_utilities.py +309 -0
- build/lib/pyTEMlib/image/image_window.py +421 -0
- build/lib/pyTEMlib/image_tools.py +699 -0
- build/lib/pyTEMlib/interactive_image.py +1 -0
- build/lib/pyTEMlib/kinematic_scattering.py +1196 -0
- build/lib/pyTEMlib/microscope.py +61 -0
- build/lib/pyTEMlib/probe_tools.py +906 -0
- build/lib/pyTEMlib/sidpy_tools.py +153 -0
- build/lib/pyTEMlib/simulation_tools.py +104 -0
- build/lib/pyTEMlib/test.py +437 -0
- build/lib/pyTEMlib/utilities.py +314 -0
- build/lib/pyTEMlib/version.py +5 -0
- build/lib/pyTEMlib/xrpa_x_sections.py +20976 -0
- pyTEMlib/__init__.py +25 -3
- pyTEMlib/animation.py +31 -22
- pyTEMlib/atom_tools.py +29 -34
- pyTEMlib/config_dir.py +2 -28
- pyTEMlib/crystal_tools.py +129 -165
- pyTEMlib/eds_tools.py +559 -342
- pyTEMlib/eds_xsections.py +432 -0
- pyTEMlib/eels_tools/__init__.py +44 -0
- pyTEMlib/eels_tools/core_loss_tools.py +751 -0
- pyTEMlib/eels_tools/eels_database.py +134 -0
- pyTEMlib/eels_tools/low_loss_tools.py +655 -0
- pyTEMlib/eels_tools/peak_fit_tools.py +175 -0
- pyTEMlib/eels_tools/zero_loss_tools.py +264 -0
- pyTEMlib/file_reader.py +274 -0
- pyTEMlib/file_tools.py +260 -1130
- pyTEMlib/get_bote_salvat.py +69 -0
- pyTEMlib/graph_tools.py +101 -174
- pyTEMlib/graph_viz.py +150 -0
- pyTEMlib/image/__init__.py +37 -0
- pyTEMlib/image/image_atoms.py +270 -0
- pyTEMlib/image/image_clean.py +197 -0
- pyTEMlib/image/image_distortion.py +299 -0
- pyTEMlib/image/image_fft.py +277 -0
- pyTEMlib/image/image_graph.py +926 -0
- pyTEMlib/image/image_registration.py +316 -0
- pyTEMlib/image/image_utilities.py +309 -0
- pyTEMlib/image/image_window.py +421 -0
- pyTEMlib/image_tools.py +154 -915
- pyTEMlib/kinematic_scattering.py +1 -1
- pyTEMlib/probe_tools.py +1 -1
- pyTEMlib/test.py +437 -0
- pyTEMlib/utilities.py +314 -0
- pyTEMlib/version.py +2 -3
- pyTEMlib/xrpa_x_sections.py +14 -10
- {pytemlib-0.2025.4.1.dist-info → pytemlib-0.2025.9.1.dist-info}/METADATA +13 -16
- pytemlib-0.2025.9.1.dist-info/RECORD +86 -0
- {pytemlib-0.2025.4.1.dist-info → pytemlib-0.2025.9.1.dist-info}/WHEEL +1 -1
- pytemlib-0.2025.9.1.dist-info/top_level.txt +6 -0
- pyTEMlib/core_loss_widget.py +0 -721
- pyTEMlib/eels_dialog.py +0 -754
- pyTEMlib/eels_dialog_utilities.py +0 -1199
- pyTEMlib/eels_tools.py +0 -2359
- pyTEMlib/file_tools_qt.py +0 -193
- pyTEMlib/image_dialog.py +0 -158
- pyTEMlib/image_dlg.py +0 -146
- pyTEMlib/info_widget.py +0 -1086
- pyTEMlib/info_widget3.py +0 -1120
- pyTEMlib/low_loss_widget.py +0 -479
- pyTEMlib/peak_dialog.py +0 -1129
- pyTEMlib/peak_dlg.py +0 -286
- pytemlib-0.2025.4.1.dist-info/RECORD +0 -38
- pytemlib-0.2025.4.1.dist-info/top_level.txt +0 -1
- {pytemlib-0.2025.4.1.dist-info → pytemlib-0.2025.9.1.dist-info}/entry_points.txt +0 -0
- {pytemlib-0.2025.4.1.dist-info → pytemlib-0.2025.9.1.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,421 @@
|
|
|
1
|
+
# Image windowing class
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
import sidpy
|
|
5
|
+
from sidpy.base.num_utils import build_ind_val_matrices
|
|
6
|
+
from scipy.signal.windows import hamming, hann, blackman
|
|
7
|
+
from skimage.transform import rescale
|
|
8
|
+
import dask
|
|
9
|
+
|
|
10
|
+
class ImageWindowing:
|
|
11
|
+
"""
|
|
12
|
+
This class will generate windows from sidpy dataset objects. At present only 2D windowing is allowed.
|
|
13
|
+
"""
|
|
14
|
+
def __init__(self, parms_dict, verbose = False):
|
|
15
|
+
'''Sliding Window Class.
|
|
16
|
+
|
|
17
|
+
Parameters
|
|
18
|
+
----------
|
|
19
|
+
- parms_dict : dictionary
|
|
20
|
+
Dictionary with parameters of the windowing process, see below.
|
|
21
|
+
|
|
22
|
+
Keys:
|
|
23
|
+
- 'window_size_x' (integer) (required): size of the window across the x-axis
|
|
24
|
+
- 'window_size_y' (integer) (required): size of the window across the y-axis
|
|
25
|
+
- 'window_step_x' (integer) (required): step size of the window across the x-axis. Must divide into the image size in the x axis
|
|
26
|
+
- 'window_step_y' (integer) (required): step size of the window across the y-axis. Must divide into the image size in the y axis
|
|
27
|
+
- 'mode' (string) (Optional, default is 'image'): One of 'image' or 'fft' which defines the processing to be performed for each window.
|
|
28
|
+
The choice of 'fft' will perform 2D fast Fourier transforms on each image whereas 'image' will not perform any operation on the window
|
|
29
|
+
- 'fft_mode' (string) (Optional, default is 'abs'): If mode is 'fft', choose whether to look at amplitude or phase. Options are 'abs', 'phase' and 'complex'.
|
|
30
|
+
- 'interpol_factor' (float) (Optional, default is 1.0): Interpolation factor for windows to increase or decrease size of the windows.
|
|
31
|
+
- 'zoom_factor' (integer or list of ints) (Optional, default is 1): Zoom the window by this factor, typically done for 'fft' mode to observe higher frequencies clearly
|
|
32
|
+
If passing a list of ints, this will determine the degree of cropping per axis
|
|
33
|
+
- 'filter' (string) (Optional, default is None): Filtering to use for the image window. Options are 'blackman', 'hamming', 'hann'.
|
|
34
|
+
The filter is applied to each window before 'mode'.
|
|
35
|
+
- verbose : (Optional) Boolean
|
|
36
|
+
Verbose flag. Default is False.
|
|
37
|
+
|
|
38
|
+
Returns
|
|
39
|
+
--------
|
|
40
|
+
Instance of ImageWindowing object setup with parameters defined by the parms_dict above.
|
|
41
|
+
'''
|
|
42
|
+
|
|
43
|
+
self.window_step_x = parms_dict['window_step_x']
|
|
44
|
+
self.window_step_y = parms_dict['window_step_y']
|
|
45
|
+
self.window_size_x = parms_dict['window_size_x']
|
|
46
|
+
self.window_size_y = parms_dict['window_size_y']
|
|
47
|
+
self.fft_mode = 'abs'
|
|
48
|
+
self.verbose = verbose
|
|
49
|
+
|
|
50
|
+
if 'mode' in parms_dict.keys():
|
|
51
|
+
if parms_dict['mode'] not in ['image', 'fft']:
|
|
52
|
+
raise ValueError("Parameters dictionary field 'mode' must be one of 'image' or 'fft'."
|
|
53
|
+
"Try again with one of these two options.")
|
|
54
|
+
else:
|
|
55
|
+
self.mode = parms_dict['mode']
|
|
56
|
+
else:
|
|
57
|
+
self.mode = 'image'
|
|
58
|
+
parms_dict['mode'] = 'image'
|
|
59
|
+
|
|
60
|
+
if 'interpol_factor' in parms_dict.keys(): self.interpol_factor = parms_dict['interpol_factor']
|
|
61
|
+
else:
|
|
62
|
+
self.interpol_factor = 1
|
|
63
|
+
parms_dict['interpol_factor'] = 1
|
|
64
|
+
|
|
65
|
+
if 'zoom_factor' in parms_dict.keys(): self.zoom_factor = parms_dict['zoom_factor']
|
|
66
|
+
else:
|
|
67
|
+
self.zoom_factor = 1
|
|
68
|
+
parms_dict['zoom_factor'] = 1
|
|
69
|
+
|
|
70
|
+
# Based on the zoom and interpolation factors we need to figure out the final size of the window
|
|
71
|
+
self.window_size_final_x, self.window_size_final_y = self._get_window_size()
|
|
72
|
+
#Setup the filter for the window
|
|
73
|
+
if 'filter' in parms_dict.keys():
|
|
74
|
+
if parms_dict['filter'] not in ['blackman', 'hamming','hann']:
|
|
75
|
+
raise ValueError("Parameter 'filter' must be one of 'hamming', 'blackman', 'hann'")
|
|
76
|
+
else:
|
|
77
|
+
self.filter = parms_dict['filter']
|
|
78
|
+
if self.filter == 'hamming':
|
|
79
|
+
filter_x = hamming(self.window_size_final_x)
|
|
80
|
+
filter_y = hamming(self.window_size_final_y)
|
|
81
|
+
self.filter_mat = np.sqrt(np.outer(filter_x, filter_y))
|
|
82
|
+
elif self.filter == 'blackman':
|
|
83
|
+
filter_x = blackman(self.window_size_final_x)
|
|
84
|
+
filter_y = blackman(self.window_size_final_y)
|
|
85
|
+
self.filter_mat = np.sqrt(np.outer(filter_x, filter_y))
|
|
86
|
+
elif self.filter == 'hanning':
|
|
87
|
+
filter_x = hann(self.window_size_final_x)
|
|
88
|
+
filter_y = hann(self.window_size_final_y)
|
|
89
|
+
self.filter_mat = np.sqrt(np.outer(filter_x, filter_y))
|
|
90
|
+
else:
|
|
91
|
+
self.filter = 'None'
|
|
92
|
+
|
|
93
|
+
if self.mode=='fft':
|
|
94
|
+
#load FFT options
|
|
95
|
+
if 'fft_mode' in parms_dict.keys():
|
|
96
|
+
if parms_dict['fft_mode'] not in ['abs', 'phase', 'complex']:
|
|
97
|
+
raise ValueError("Parameter 'fft_mode' must be \
|
|
98
|
+
one of 'abs', 'phase' or 'complex' ")
|
|
99
|
+
else:
|
|
100
|
+
self.fft_mode = parms_dict['fft_mode']
|
|
101
|
+
else:
|
|
102
|
+
self.fft_mode = 'abs' #default to absolute value in case fft mode is not provided
|
|
103
|
+
parms_dict['fft_mode'] = 'abs'
|
|
104
|
+
if self.verbose:
|
|
105
|
+
print('ImageWindowing Object created with parameters {}'.format(parms_dict))
|
|
106
|
+
|
|
107
|
+
self.window_parms = parms_dict
|
|
108
|
+
self.window_dataset = None
|
|
109
|
+
return
|
|
110
|
+
|
|
111
|
+
def _get_window_size(self):
|
|
112
|
+
'''
|
|
113
|
+
Computes window size based on zoom and interpolation factors
|
|
114
|
+
'''
|
|
115
|
+
|
|
116
|
+
image_test = np.random.uniform(size=(self.window_size_x, self.window_size_y))
|
|
117
|
+
image_zoomed = self.zoom(image_test, self.zoom_factor)
|
|
118
|
+
|
|
119
|
+
#interpolate it
|
|
120
|
+
zoomed_interpolated = rescale(image_zoomed, self.interpol_factor)
|
|
121
|
+
return zoomed_interpolated.shape[0],zoomed_interpolated.shape[1]
|
|
122
|
+
|
|
123
|
+
def do_PCA_window_cleaning(self, num_comps = None):
|
|
124
|
+
"""
|
|
125
|
+
This function performs PCA cleaning
|
|
126
|
+
Inputs:
|
|
127
|
+
- num_comps: (int) (Default = None). Number of components to keep in reconstruction.
|
|
128
|
+
By default, num_comps is 0.5*(window_size_x * window_size_y)
|
|
129
|
+
"""
|
|
130
|
+
#Here we assume that the windowing has been done
|
|
131
|
+
|
|
132
|
+
if self.window_dataset is None:
|
|
133
|
+
raise ValueError("Windowing has not been done. Please perform windowing first before calling this function")
|
|
134
|
+
|
|
135
|
+
assert self.window_size_x == self.window_size_final_x, "Cannot use zoom and interpolation for PCA image cleaning, rerun without these"
|
|
136
|
+
assert self.window_size_y == self.window_size_final_y, "Cannot use zoom and interpolation for PCA image cleaning, rerun without these"
|
|
137
|
+
|
|
138
|
+
windows_2d = self.window_dataset.fold(method='spaspec')
|
|
139
|
+
u, s, vh = np.linalg.svd(np.array(windows_2d), full_matrices=False )
|
|
140
|
+
|
|
141
|
+
if num_comps is None:
|
|
142
|
+
num_comps = len(s)//2 #choose half the components as default
|
|
143
|
+
|
|
144
|
+
s[num_comps:] = 0
|
|
145
|
+
|
|
146
|
+
recon = np.dot(u * s, vh)
|
|
147
|
+
recon_4d = recon.reshape(self.window_dataset.shape)
|
|
148
|
+
|
|
149
|
+
recon_image = np.zeros(self.image_shape)
|
|
150
|
+
window_size = [self.window_size_final_x, self.window_size_final_y]
|
|
151
|
+
m=0
|
|
152
|
+
for xind in range(recon_4d.shape[0]):
|
|
153
|
+
for yind in range(recon_4d.shape[1]):
|
|
154
|
+
cur_slice = recon_4d[xind,yind,:,:]
|
|
155
|
+
pos =self.pos_vec[m]
|
|
156
|
+
start_stop = [slice(x, x + y, 1) for x, y in zip(pos, window_size)]
|
|
157
|
+
recon_image[tuple(start_stop)] = cur_slice
|
|
158
|
+
m+=1
|
|
159
|
+
|
|
160
|
+
self.recon_image = recon_image
|
|
161
|
+
|
|
162
|
+
#TODO: Need to return as a sidpy dataset
|
|
163
|
+
|
|
164
|
+
return recon_image
|
|
165
|
+
|
|
166
|
+
def MakeWindows(self, dataset, dim_slice=None):
|
|
167
|
+
'''
|
|
168
|
+
Image should be a sidpy dataset object
|
|
169
|
+
We will take the image to be the first two spatial dimensions,
|
|
170
|
+
unless dimensions are specified
|
|
171
|
+
|
|
172
|
+
Inputs:
|
|
173
|
+
- dataset (sidpy.Dataset object of the image to be windowed)
|
|
174
|
+
- dim_slice (List) (Optional). list of integers of the slices over which the
|
|
175
|
+
image windowing should take place. This should be of length number of dimensions of
|
|
176
|
+
the dataset minus two.
|
|
177
|
+
|
|
178
|
+
Returns:
|
|
179
|
+
- windowed_dataset (sidpy.Dataset) object with windows created as per
|
|
180
|
+
the parameters passed to the ImageWindowing class.
|
|
181
|
+
|
|
182
|
+
'''
|
|
183
|
+
|
|
184
|
+
# This is the windowing function. Will generate the windows (but not the FFT)
|
|
185
|
+
num_dimensions = dataset.ndim
|
|
186
|
+
self.dataset = dataset
|
|
187
|
+
if dim_slice is None:
|
|
188
|
+
if num_dimensions > 2:
|
|
189
|
+
raise ValueError('You have specified windowing on a sidpy dataset '
|
|
190
|
+
'with more than 2 dimensions without specifying slices')
|
|
191
|
+
else:
|
|
192
|
+
image_source = dataset[:]
|
|
193
|
+
image_dims = [0,1]
|
|
194
|
+
elif dim_slice is not None:
|
|
195
|
+
"""Get all spatial dimensions"""
|
|
196
|
+
image_dims = []
|
|
197
|
+
for dim, axis in dataset._axes.items():
|
|
198
|
+
if axis.dimension_type == sidpy.DimensionType.SPATIAL:
|
|
199
|
+
image_dims.append(dim)
|
|
200
|
+
all_dims = np.arange(0, num_dimensions)
|
|
201
|
+
slice_list = []
|
|
202
|
+
for k in range(num_dimensions):
|
|
203
|
+
if k in image_dims:
|
|
204
|
+
slice_list.append(slice(None, dataset.shape[k], 1))
|
|
205
|
+
else:
|
|
206
|
+
slice_list.append(dim_slice)
|
|
207
|
+
image_source = dataset[tuple(slice_list)]
|
|
208
|
+
|
|
209
|
+
self.image_shape = image_source.shape
|
|
210
|
+
|
|
211
|
+
if self.verbose:
|
|
212
|
+
print('Full image shape is {}'.format(self.image_shape))
|
|
213
|
+
|
|
214
|
+
window_step = [self.window_step_x, self.window_step_y]
|
|
215
|
+
window_size = [self.window_size_x, self.window_size_y]
|
|
216
|
+
window_size_final = [self.window_size_final_x, self.window_size_final_y]
|
|
217
|
+
#division_factor_x = self.window_size_x - self.window_step_x
|
|
218
|
+
#division_factor_y = self.window_size_y - self.window_step_y
|
|
219
|
+
if self.window_size_x == self.window_step_x: division_factor_x = self.window_size_x
|
|
220
|
+
if self.window_size_y == self.window_step_y: division_factor_y = self.window_size_y
|
|
221
|
+
|
|
222
|
+
#assert np.mod(self.image_shape[0] - self.window_size_x, self.window_step_x) ==0, "Image shape along y is {} but window size is {}, window step is ({}) are not divisible \
|
|
223
|
+
#without remainder, change your window size or window step".format(self.image_shape[0], self.window_size_x, self.window_step_x)
|
|
224
|
+
#assert np.mod(self.image_shape[1] - self.window_size_y, self.window_step_y) ==0, "Image shape along x is {} but window size is {}, and window step is ({}) are not divisible \
|
|
225
|
+
#without remainder, change your window size or window step".format(self.image_shape[1], self.window_size_y, self.window_step_y)
|
|
226
|
+
|
|
227
|
+
dim_vec = []
|
|
228
|
+
for i in range(2):
|
|
229
|
+
dim_vec.append(np.arange(0, self.image_shape[i] - window_size[i], window_step[i]))
|
|
230
|
+
dim_vec[i] = np.append(dim_vec[i], self.image_shape[i] - window_size[i])
|
|
231
|
+
|
|
232
|
+
if self.verbose:
|
|
233
|
+
print("dim vec is {}".format(dim_vec))
|
|
234
|
+
|
|
235
|
+
_, pos_vec = build_ind_val_matrices(dim_vec)
|
|
236
|
+
if self.verbose:
|
|
237
|
+
print("Pos vec is {}".format(pos_vec))
|
|
238
|
+
|
|
239
|
+
pca_mat = np.zeros(shape=(pos_vec.shape[0], np.prod(window_size_final)), dtype=np.complex64)
|
|
240
|
+
pos_vec = np.int32(pos_vec)
|
|
241
|
+
self.pos_vec = pos_vec
|
|
242
|
+
|
|
243
|
+
def make_windows_parallel(ind, pos):
|
|
244
|
+
start_stop = [slice(x, x + y, 1) for x, y in zip(pos, window_size)]
|
|
245
|
+
full_slice = image_source[tuple(start_stop)]
|
|
246
|
+
full_slice = self._return_win_image_processed(full_slice)
|
|
247
|
+
full_slice_flat = full_slice.flatten()
|
|
248
|
+
return full_slice_flat
|
|
249
|
+
|
|
250
|
+
window_results = []
|
|
251
|
+
for ind, pos in enumerate(pos_vec):
|
|
252
|
+
lazy_result = dask.delayed(make_windows_parallel)(ind, pos)
|
|
253
|
+
window_results.append(lazy_result)
|
|
254
|
+
|
|
255
|
+
pca_mat = dask.compute(*window_results)
|
|
256
|
+
pca_mat = np.array(pca_mat) #it comes out as a tuple, make it array
|
|
257
|
+
|
|
258
|
+
self.pos_vec = pos_vec
|
|
259
|
+
|
|
260
|
+
# Get the positions and make them dimensions
|
|
261
|
+
new_y_vals = np.linspace(dataset._axes[image_dims[0]].values.min(),
|
|
262
|
+
dataset._axes[image_dims[0]].values.max(), len(np.unique(pos_vec[:, 0])))
|
|
263
|
+
|
|
264
|
+
new_x_vals = np.linspace(dataset._axes[image_dims[1]].values.min(),
|
|
265
|
+
dataset._axes[image_dims[1]].values.max(), len(np.unique(pos_vec[:, 1])))
|
|
266
|
+
if self.verbose:
|
|
267
|
+
print("position values x {} and y {}".format(new_y_vals, new_x_vals))
|
|
268
|
+
|
|
269
|
+
self.pca_mat = pca_mat
|
|
270
|
+
windows_reshaped = pca_mat.reshape(len(new_x_vals), len(new_y_vals),
|
|
271
|
+
self.window_size_final_x, self.window_size_final_y)
|
|
272
|
+
if self.verbose:
|
|
273
|
+
print('Reshaped windows size is {}'.format(windows_reshaped.shape))
|
|
274
|
+
|
|
275
|
+
# Make a sidpy dataset
|
|
276
|
+
#if the data is complex, then convert it to absolute
|
|
277
|
+
#this needs to be changed..depending on user preferences.
|
|
278
|
+
if np.iscomplexobj(windows_reshaped):
|
|
279
|
+
if self.fft_mode == 'abs':
|
|
280
|
+
windows_reshaped = np.array(np.abs(windows_reshaped), dtype = np.float64)
|
|
281
|
+
elif self.fft_mode == 'phase':
|
|
282
|
+
windows_reshaped = np.array(np.angle(windows_reshaped), dtype=np.float64)
|
|
283
|
+
|
|
284
|
+
data_set = sidpy.Dataset.from_array(windows_reshaped,
|
|
285
|
+
name='Image_Windowed')
|
|
286
|
+
|
|
287
|
+
# Set the data type
|
|
288
|
+
data_set.data_type = 'Image_4d'
|
|
289
|
+
|
|
290
|
+
# Add quantity and units
|
|
291
|
+
data_set.units = dataset.units
|
|
292
|
+
data_set.quantity = dataset.quantity
|
|
293
|
+
|
|
294
|
+
# Add dimension info
|
|
295
|
+
|
|
296
|
+
window_size_fraction_x = window_size[0]/self.image_shape[0]
|
|
297
|
+
window_size_fraction_y = window_size[1] / self.image_shape[1]
|
|
298
|
+
|
|
299
|
+
window_extent_x = (dataset._axes[image_dims[0]].values.max() -
|
|
300
|
+
dataset._axes[image_dims[0]].values.min())*window_size_fraction_x
|
|
301
|
+
|
|
302
|
+
window_extent_y = (dataset._axes[image_dims[1]].values.max() -
|
|
303
|
+
dataset._axes[image_dims[1]].values.min()) * window_size_fraction_y
|
|
304
|
+
window_units = dataset._axes[image_dims[0]].units
|
|
305
|
+
if self.mode =='fft':
|
|
306
|
+
#to check if this is correct
|
|
307
|
+
z_dimx = np.linspace(0, 1.0/(window_extent_x / self.zoom_factor), data_set.shape[2])
|
|
308
|
+
z_dimy = np.linspace(0, 1.0/(window_extent_y / self.zoom_factor), data_set.shape[3])
|
|
309
|
+
window_units = dataset._axes[image_dims[0]].units + '^-1'
|
|
310
|
+
else:
|
|
311
|
+
z_dimx = np.linspace(0, window_extent_x/self.zoom_factor, data_set.shape[2])
|
|
312
|
+
z_dimy = np.linspace(0, window_extent_y/self.zoom_factor, data_set.shape[3])
|
|
313
|
+
|
|
314
|
+
data_set.set_dimension(0, sidpy.Dimension(new_x_vals,
|
|
315
|
+
name=dataset._axes[image_dims[0]].name,
|
|
316
|
+
units=dataset._axes[image_dims[0]].units,
|
|
317
|
+
quantity=dataset._axes[image_dims[0]].quantity,
|
|
318
|
+
dimension_type='spatial'))
|
|
319
|
+
|
|
320
|
+
data_set.set_dimension(1, sidpy.Dimension(new_y_vals,
|
|
321
|
+
name=dataset._axes[image_dims[1]].name,
|
|
322
|
+
units=dataset._axes[image_dims[1]].units,
|
|
323
|
+
quantity=dataset._axes[image_dims[1]].quantity,
|
|
324
|
+
dimension_type='spatial'))
|
|
325
|
+
|
|
326
|
+
data_set.set_dimension(2, sidpy.Dimension(z_dimx,
|
|
327
|
+
name='WindowX',
|
|
328
|
+
units=window_units, quantity='kx',
|
|
329
|
+
dimension_type='spectral'))
|
|
330
|
+
|
|
331
|
+
data_set.set_dimension(3, sidpy.Dimension(z_dimy,
|
|
332
|
+
name='WindowY',
|
|
333
|
+
units=window_units, quantity='ky',
|
|
334
|
+
dimension_type='spectral'))
|
|
335
|
+
|
|
336
|
+
# append metadata
|
|
337
|
+
data_set.metadata = self._merge_dictionaries(dataset.metadata, self.window_parms)
|
|
338
|
+
self.window_dataset = data_set
|
|
339
|
+
return data_set
|
|
340
|
+
|
|
341
|
+
def _return_win_image_processed(self, img_window):
|
|
342
|
+
#Real image slice, returns it back with image processed
|
|
343
|
+
|
|
344
|
+
|
|
345
|
+
if self.mode == 'fft': # Apply FFT if needed
|
|
346
|
+
img_window = np.array(img_window)
|
|
347
|
+
img_window = np.fft.fftshift(np.fft.fft2(img_window))
|
|
348
|
+
if self.fft_mode == 'amp':
|
|
349
|
+
img_window = np.abs(img_window,)
|
|
350
|
+
elif self.fft_mode == 'phase':
|
|
351
|
+
img_window = np.angle(img_window)
|
|
352
|
+
elif self.fft_mode == 'complex':
|
|
353
|
+
img_window = np.array(img_window, dtype = np.complex64)
|
|
354
|
+
|
|
355
|
+
#Zoom and interpolate if needed
|
|
356
|
+
if self.zoom_factor == 1 and self.interpol_factor == 1:
|
|
357
|
+
return img_window
|
|
358
|
+
else:
|
|
359
|
+
img_window = self.zoom(img_window, self.zoom_factor) # Zoom it
|
|
360
|
+
img_window = self.rescale_win(img_window, self.interpol_factor) # Rescale
|
|
361
|
+
|
|
362
|
+
if self.filter != 'None':
|
|
363
|
+
img_window *= self.filter_mat # Apply filter
|
|
364
|
+
|
|
365
|
+
return img_window
|
|
366
|
+
|
|
367
|
+
def _merge_dictionaries(self, dict1, dict2):
|
|
368
|
+
#given two dictionaries, merge them into one
|
|
369
|
+
merged_dict = {**dict1, **dict2}
|
|
370
|
+
return merged_dict
|
|
371
|
+
|
|
372
|
+
def zoom(self, img_window, zoom_factor):
|
|
373
|
+
#Zooms by the zoom factor
|
|
374
|
+
if zoom_factor==1:
|
|
375
|
+
return img_window
|
|
376
|
+
else:
|
|
377
|
+
if type(zoom_factor) is int:
|
|
378
|
+
zoom_factor = [zoom_factor, zoom_factor]
|
|
379
|
+
|
|
380
|
+
#Find the midpoint
|
|
381
|
+
img_x_mid = img_window.shape[0]//2
|
|
382
|
+
img_y_mid = img_window.shape[1]//2
|
|
383
|
+
zoom_x_size = (img_window.shape[0] / zoom_factor[0])/2
|
|
384
|
+
zoom_y_size = (img_window.shape[1] / zoom_factor[1])/2
|
|
385
|
+
|
|
386
|
+
img_window = img_window[int(img_x_mid - zoom_x_size) : int(img_x_mid + zoom_x_size),
|
|
387
|
+
int(img_y_mid - zoom_y_size ): int(img_y_mid + zoom_y_size)]
|
|
388
|
+
|
|
389
|
+
return img_window
|
|
390
|
+
|
|
391
|
+
def rescale_win(self, img_window, interpol_factor):
|
|
392
|
+
if self.fft_mode !='complex':
|
|
393
|
+
img_window = np.array(img_window, dtype = np.float32)
|
|
394
|
+
complex_rescaled_image = rescale(img_window, interpol_factor)
|
|
395
|
+
else:
|
|
396
|
+
real_img = np.real(img_window)
|
|
397
|
+
imag_img = np.imag(img_window)
|
|
398
|
+
real_img_scaled = rescale(real_img, interpol_factor)
|
|
399
|
+
imag_img_scaled = rescale(imag_img, interpol_factor)
|
|
400
|
+
complex_rescaled_image = real_img_scaled + 1j*imag_img_scaled
|
|
401
|
+
|
|
402
|
+
return complex_rescaled_image
|
|
403
|
+
|
|
404
|
+
#
|
|
405
|
+
'''
|
|
406
|
+
def clean_image(self, n_comps = 4):
|
|
407
|
+
self.mode = 'image'
|
|
408
|
+
self.interpol_factor = 1
|
|
409
|
+
self.zoom_factor = 1
|
|
410
|
+
self.window_size_final_x = self.window_size_x
|
|
411
|
+
self.window_size_final_y = self.window_size_y
|
|
412
|
+
new_windows = self.MakeWindows(self.dataset)
|
|
413
|
+
|
|
414
|
+
from ..learn.ml import MatrixFactor
|
|
415
|
+
svd_results = MatrixFactor(new_windows, method='svd', n_components = n_comps)
|
|
416
|
+
|
|
417
|
+
return svd_results'''
|
|
418
|
+
|
|
419
|
+
|
|
420
|
+
|
|
421
|
+
|