pytme 0.1.7__cp311-cp311-macosx_14_0_arm64.whl → 0.1.8__cp311-cp311-macosx_14_0_arm64.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.
- {pytme-0.1.7.data → pytme-0.1.8.data}/scripts/match_template.py +12 -10
- {pytme-0.1.7.data → pytme-0.1.8.data}/scripts/postprocess.py +38 -12
- {pytme-0.1.7.data → pytme-0.1.8.data}/scripts/preprocessor_gui.py +74 -52
- {pytme-0.1.7.dist-info → pytme-0.1.8.dist-info}/METADATA +10 -8
- {pytme-0.1.7.dist-info → pytme-0.1.8.dist-info}/RECORD +21 -21
- scripts/match_template.py +12 -10
- scripts/postprocess.py +38 -12
- scripts/preprocessor_gui.py +74 -52
- tme/__version__.py +1 -1
- tme/backends/npfftw_backend.py +0 -7
- tme/density.py +17 -8
- tme/matching_data.py +55 -24
- tme/matching_exhaustive.py +67 -19
- tme/matching_utils.py +39 -13
- tme/preprocessor.py +113 -5
- {pytme-0.1.7.data → pytme-0.1.8.data}/scripts/estimate_ram_usage.py +0 -0
- {pytme-0.1.7.data → pytme-0.1.8.data}/scripts/preprocess.py +0 -0
- {pytme-0.1.7.dist-info → pytme-0.1.8.dist-info}/LICENSE +0 -0
- {pytme-0.1.7.dist-info → pytme-0.1.8.dist-info}/WHEEL +0 -0
- {pytme-0.1.7.dist-info → pytme-0.1.8.dist-info}/entry_points.txt +0 -0
- {pytme-0.1.7.dist-info → pytme-0.1.8.dist-info}/top_level.txt +0 -0
tme/matching_exhaustive.py
CHANGED
@@ -308,6 +308,49 @@ def cam_setup(**kwargs):
|
|
308
308
|
return corr_setup(**kwargs)
|
309
309
|
|
310
310
|
|
311
|
+
def _normalize_under_mask(template: NDArray, mask: NDArray, mask_intensity) -> None:
|
312
|
+
"""
|
313
|
+
Standardizes the values in in template by subtracting the mean and dividing by the
|
314
|
+
standard deviation based on the elements in mask. Subsequently, the template is
|
315
|
+
multiplied by the mask.
|
316
|
+
|
317
|
+
Parameters
|
318
|
+
----------
|
319
|
+
template : NDArray
|
320
|
+
The data array to be normalized. This array is modified in-place.
|
321
|
+
mask : NDArray
|
322
|
+
A boolean array of the same shape as `template`. True values indicate the positions in `template`
|
323
|
+
to consider for normalization.
|
324
|
+
mask_intensity : float
|
325
|
+
Mask intensity used to compute expectations.
|
326
|
+
|
327
|
+
References
|
328
|
+
----------
|
329
|
+
.. [1] T. Hrabe, Y. Chen, S. Pfeffer, L. Kuhn Cuellar, A.-V. Mangold,
|
330
|
+
and F. Förster, J. Struct. Biol. 178, 177 (2012).
|
331
|
+
.. [2] M. L. Chaillet, G. van der Schot, I. Gubins, S. Roet,
|
332
|
+
R. C. Veltkamp, and F. Förster, Int. J. Mol. Sci. 24,
|
333
|
+
13375 (2023)
|
334
|
+
|
335
|
+
Returns
|
336
|
+
-------
|
337
|
+
None
|
338
|
+
This function modifies `template` in-place and does not return any value.
|
339
|
+
"""
|
340
|
+
masked_mean = backend.sum(backend.multiply(template, mask))
|
341
|
+
masked_mean = backend.divide(masked_mean, mask_intensity)
|
342
|
+
masked_std = backend.sum(backend.multiply(backend.square(template), mask))
|
343
|
+
masked_std = backend.subtract(
|
344
|
+
masked_std / mask_intensity, backend.square(masked_mean)
|
345
|
+
)
|
346
|
+
masked_std = backend.sqrt(backend.maximum(masked_std, 0))
|
347
|
+
|
348
|
+
backend.subtract(template, masked_mean, out=template)
|
349
|
+
backend.divide(template, masked_std, out=template)
|
350
|
+
backend.multiply(template, mask, out=template)
|
351
|
+
return None
|
352
|
+
|
353
|
+
|
311
354
|
def flc_setup(
|
312
355
|
rfftn: Callable,
|
313
356
|
irfftn: Callable,
|
@@ -359,7 +402,8 @@ def flc_setup(
|
|
359
402
|
ft_target = backend.preallocate_array(fast_ft_shape, complex_dtype)
|
360
403
|
ft_target2 = backend.preallocate_array(fast_ft_shape, complex_dtype)
|
361
404
|
rfftn(target_pad, ft_target)
|
362
|
-
|
405
|
+
backend.square(target_pad, out=target_pad)
|
406
|
+
rfftn(target_pad, ft_target2)
|
363
407
|
|
364
408
|
# Convert arrays used in subsequent fitting to SharedMemory objects
|
365
409
|
ft_target = backend.arr_to_sharedarr(
|
@@ -369,13 +413,9 @@ def flc_setup(
|
|
369
413
|
arr=ft_target2, shared_memory_handler=shared_memory_handler
|
370
414
|
)
|
371
415
|
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
template_mask = backend.astype(template_mask, real_dtype)
|
376
|
-
|
377
|
-
backend.divide(template - template_mean, template_std, out=template)
|
378
|
-
backend.multiply(template, template_mask, out=template)
|
416
|
+
_normalize_under_mask(
|
417
|
+
template=template, mask=template_mask, mask_intensity=backend.sum(template_mask)
|
418
|
+
)
|
379
419
|
|
380
420
|
template_buffer = backend.arr_to_sharedarr(
|
381
421
|
arr=template, shared_memory_handler=shared_memory_handler
|
@@ -455,7 +495,6 @@ def flcSphericalMask_setup(
|
|
455
495
|
:py:meth:`corr_scoring`
|
456
496
|
"""
|
457
497
|
target_pad = backend.topleft_pad(target, fast_shape)
|
458
|
-
template_mask_pad = backend.topleft_pad(template_mask, fast_shape)
|
459
498
|
|
460
499
|
# Target and squared target window sums
|
461
500
|
ft_target = backend.preallocate_array(fast_ft_shape, complex_dtype)
|
@@ -467,16 +506,17 @@ def flcSphericalMask_setup(
|
|
467
506
|
numerator2 = backend.preallocate_array(1, real_dtype)
|
468
507
|
|
469
508
|
eps = backend.eps(real_dtype)
|
470
|
-
n_observations = backend.sum(
|
509
|
+
n_observations = backend.sum(template_mask)
|
510
|
+
|
511
|
+
template_mask_pad = backend.topleft_pad(template_mask, fast_shape)
|
471
512
|
rfftn(template_mask_pad, ft_template_mask)
|
472
513
|
|
473
|
-
#
|
514
|
+
# Denominator E(X^2) - E(X)^2
|
474
515
|
rfftn(backend.square(target_pad), ft_target)
|
475
516
|
backend.multiply(ft_target, ft_template_mask, out=ft_temp)
|
476
517
|
irfftn(ft_temp, temp2)
|
477
518
|
backend.divide(temp2, n_observations, out=temp2)
|
478
519
|
|
479
|
-
# Mean part denominator
|
480
520
|
rfftn(target_pad, ft_target)
|
481
521
|
backend.multiply(ft_target, ft_template_mask, out=ft_temp)
|
482
522
|
irfftn(ft_temp, temp)
|
@@ -495,14 +535,10 @@ def flcSphericalMask_setup(
|
|
495
535
|
backend.fill(temp2, 0)
|
496
536
|
temp2[nonzero_indices] = 1 / temp[nonzero_indices]
|
497
537
|
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
template = backend.divide(backend.subtract(template, template_mean), template_std)
|
503
|
-
backend.multiply(template, template_mask, out=template)
|
538
|
+
_normalize_under_mask(
|
539
|
+
template=template, mask=template_mask, mask_intensity=backend.sum(template_mask)
|
540
|
+
)
|
504
541
|
|
505
|
-
# Convert arrays used in subsequent fitting to SharedMemory objects
|
506
542
|
template_buffer = backend.arr_to_sharedarr(
|
507
543
|
arr=template, shared_memory_handler=shared_memory_handler
|
508
544
|
)
|
@@ -773,6 +809,7 @@ def corr_scoring(
|
|
773
809
|
fourier_shift = callback_class_args.get("fourier_shift", backend.zeros(arr.ndim))
|
774
810
|
fourier_shift_scores = backend.sum(fourier_shift != 0) != 0
|
775
811
|
|
812
|
+
template_sum = backend.sum(template)
|
776
813
|
for index in range(rotations.shape[0]):
|
777
814
|
rotation = rotations[index]
|
778
815
|
backend.fill(arr, 0)
|
@@ -783,6 +820,9 @@ def corr_scoring(
|
|
783
820
|
use_geometric_center=False,
|
784
821
|
order=interpolation_order,
|
785
822
|
)
|
823
|
+
rotation_norm = template_sum / backend.sum(arr)
|
824
|
+
backend.multiply(arr, rotation_norm, out=arr)
|
825
|
+
|
786
826
|
rfftn(arr, ft_temp)
|
787
827
|
template_filter_func(ft_temp, template_filter, out=ft_temp)
|
788
828
|
|
@@ -905,6 +945,7 @@ def flc_scoring(
|
|
905
945
|
fourier_shift = callback_class_args.get("fourier_shift", backend.zeros(arr.ndim))
|
906
946
|
fourier_shift_scores = backend.sum(fourier_shift != 0) != 0
|
907
947
|
|
948
|
+
unpadded_slice = tuple(slice(0, stop) for stop in template.shape)
|
908
949
|
for index in range(rotations.shape[0]):
|
909
950
|
rotation = rotations[index]
|
910
951
|
backend.fill(arr, 0)
|
@@ -918,8 +959,15 @@ def flc_scoring(
|
|
918
959
|
use_geometric_center=False,
|
919
960
|
order=interpolation_order,
|
920
961
|
)
|
962
|
+
# Given the amount of FFTs, might aswell normalize properly
|
921
963
|
n_observations = backend.sum(temp)
|
922
964
|
|
965
|
+
_normalize_under_mask(
|
966
|
+
template=arr[unpadded_slice],
|
967
|
+
mask=temp[unpadded_slice],
|
968
|
+
mask_intensity=n_observations,
|
969
|
+
)
|
970
|
+
|
923
971
|
rfftn(temp, ft_temp)
|
924
972
|
|
925
973
|
backend.multiply(ft_target, ft_temp, out=ft_denom)
|
tme/matching_utils.py
CHANGED
@@ -763,10 +763,14 @@ def euler_to_rotationmatrix(angles: Tuple[float]) -> NDArray:
|
|
763
763
|
NDArray
|
764
764
|
The generated rotation matrix.
|
765
765
|
"""
|
766
|
-
|
766
|
+
n_angles = len(angles)
|
767
|
+
angle_convention = "zyx"[:n_angles]
|
768
|
+
if n_angles == 1:
|
767
769
|
angles = (angles, 0, 0)
|
768
770
|
rotation_matrix = (
|
769
|
-
Rotation.from_euler(
|
771
|
+
Rotation.from_euler(angle_convention, angles, degrees=True)
|
772
|
+
.as_matrix()
|
773
|
+
.astype(np.float32)
|
770
774
|
)
|
771
775
|
return rotation_matrix
|
772
776
|
|
@@ -1052,7 +1056,7 @@ def tube_mask(
|
|
1052
1056
|
symmetry_axis : int
|
1053
1057
|
The axis of symmetry for the tube.
|
1054
1058
|
base_center : tuple
|
1055
|
-
Center of the
|
1059
|
+
Center of the tube.
|
1056
1060
|
inner_radius : float
|
1057
1061
|
Inner radius of the tube.
|
1058
1062
|
outer_radius : float
|
@@ -1068,8 +1072,9 @@ def tube_mask(
|
|
1068
1072
|
Raises
|
1069
1073
|
------
|
1070
1074
|
ValueError
|
1071
|
-
If the inner radius is larger than the outer radius
|
1072
|
-
than the symmetry axis shape
|
1075
|
+
If the inner radius is larger than the outer radius, height is larger
|
1076
|
+
than the symmetry axis shape, or if base_center and shape do not have the
|
1077
|
+
same length.
|
1073
1078
|
"""
|
1074
1079
|
if inner_radius > outer_radius:
|
1075
1080
|
raise ValueError("inner_radius should be smaller than outer_radius.")
|
@@ -1080,8 +1085,11 @@ def tube_mask(
|
|
1080
1085
|
if symmetry_axis > len(shape):
|
1081
1086
|
raise ValueError(f"symmetry_axis can be not larger than {len(shape)}.")
|
1082
1087
|
|
1088
|
+
if len(base_center) != len(shape):
|
1089
|
+
raise ValueError("shape and base_center need to have the same length.")
|
1090
|
+
|
1083
1091
|
circle_shape = tuple(b for ix, b in enumerate(shape) if ix != symmetry_axis)
|
1084
|
-
|
1092
|
+
circle_center = tuple(b for ix, b in enumerate(base_center) if ix != symmetry_axis)
|
1085
1093
|
|
1086
1094
|
inner_circle = np.zeros(circle_shape)
|
1087
1095
|
outer_circle = np.zeros_like(inner_circle)
|
@@ -1090,34 +1098,39 @@ def tube_mask(
|
|
1090
1098
|
mask_type="ellipse",
|
1091
1099
|
shape=circle_shape,
|
1092
1100
|
radius=inner_radius,
|
1093
|
-
center=
|
1101
|
+
center=circle_center,
|
1094
1102
|
)
|
1095
1103
|
if outer_radius > 0:
|
1096
1104
|
outer_circle = create_mask(
|
1097
1105
|
mask_type="ellipse",
|
1098
1106
|
shape=circle_shape,
|
1099
1107
|
radius=outer_radius,
|
1100
|
-
center=
|
1108
|
+
center=circle_center,
|
1101
1109
|
)
|
1102
1110
|
circle = outer_circle - inner_circle
|
1103
1111
|
circle = np.expand_dims(circle, axis=symmetry_axis)
|
1104
1112
|
|
1105
|
-
center =
|
1106
|
-
start_idx = center - height // 2
|
1107
|
-
stop_idx = center + height // 2 + height % 2
|
1113
|
+
center = base_center[symmetry_axis]
|
1114
|
+
start_idx = int(center - height // 2)
|
1115
|
+
stop_idx = int(center + height // 2 + height % 2)
|
1116
|
+
|
1117
|
+
start_idx, stop_idx = max(start_idx, 0), min(stop_idx, shape[symmetry_axis])
|
1108
1118
|
|
1109
1119
|
slice_indices = tuple(
|
1110
1120
|
slice(None) if i != symmetry_axis else slice(start_idx, stop_idx)
|
1111
1121
|
for i in range(len(shape))
|
1112
1122
|
)
|
1113
1123
|
tube = np.zeros(shape)
|
1114
|
-
tube[slice_indices] =
|
1124
|
+
tube[slice_indices] = circle
|
1115
1125
|
|
1116
1126
|
return tube
|
1117
1127
|
|
1118
1128
|
|
1119
1129
|
def scramble_phases(
|
1120
|
-
arr: NDArray,
|
1130
|
+
arr: NDArray,
|
1131
|
+
noise_proportion: float = 0.5,
|
1132
|
+
seed: int = 42,
|
1133
|
+
normalize_power: bool = True,
|
1121
1134
|
) -> NDArray:
|
1122
1135
|
"""
|
1123
1136
|
Applies random phase scrambling to a given array.
|
@@ -1135,6 +1148,8 @@ def scramble_phases(
|
|
1135
1148
|
The proportion of noise in the phase scrambling, by default 0.5.
|
1136
1149
|
seed : int, optional
|
1137
1150
|
The seed for the random phase scrambling, by default 42.
|
1151
|
+
normalize_power : bool, optional
|
1152
|
+
Whether the returned template should have the same sum of squares as arr.
|
1138
1153
|
|
1139
1154
|
Returns
|
1140
1155
|
-------
|
@@ -1158,6 +1173,17 @@ def scramble_phases(
|
|
1158
1173
|
ph_noise = np.random.permutation(ph)
|
1159
1174
|
ph_new = ph * (1 - noise_proportion) + ph_noise * noise_proportion
|
1160
1175
|
ret = np.real(np.fft.ifftn(amp * np.exp(1j * ph_new)))
|
1176
|
+
|
1177
|
+
if normalize_power:
|
1178
|
+
np.divide(
|
1179
|
+
np.subtract(ret, ret.min()), np.subtract(ret.max(), ret.min()), out=ret
|
1180
|
+
)
|
1181
|
+
np.multiply(ret, np.subtract(arr.max(), arr.min()), out=ret)
|
1182
|
+
np.add(ret, arr.min(), out=ret)
|
1183
|
+
|
1184
|
+
scaling = np.divide(np.abs(arr).sum(), np.abs(ret).sum())
|
1185
|
+
np.multiply(ret, scaling, out=ret)
|
1186
|
+
|
1161
1187
|
return ret
|
1162
1188
|
|
1163
1189
|
|
tme/preprocessor.py
CHANGED
@@ -1055,8 +1055,8 @@ class Preprocessor:
|
|
1055
1055
|
be equivalent to the following
|
1056
1056
|
|
1057
1057
|
>>> wedge = Preprocessor().continuous_wedge_mask(
|
1058
|
-
>>> shape
|
1059
|
-
>>> start_tilt
|
1058
|
+
>>> shape=(50,50,50),
|
1059
|
+
>>> start_tilt=50,
|
1060
1060
|
>>> stop_tilt=55,
|
1061
1061
|
>>> tilt_axis=1,
|
1062
1062
|
>>> omit_negative_frequencies=False,
|
@@ -1074,6 +1074,7 @@ class Preprocessor:
|
|
1074
1074
|
|
1075
1075
|
See Also
|
1076
1076
|
--------
|
1077
|
+
:py:meth:`Preprocessor.step_wedge_mask`
|
1077
1078
|
:py:meth:`Preprocessor.continuous_wedge_mask`
|
1078
1079
|
"""
|
1079
1080
|
opening_axes = np.asarray(opening_axes)
|
@@ -1124,6 +1125,112 @@ class Preprocessor:
|
|
1124
1125
|
|
1125
1126
|
return wedge_volume
|
1126
1127
|
|
1128
|
+
def step_wedge_mask(
|
1129
|
+
self,
|
1130
|
+
start_tilt: float,
|
1131
|
+
stop_tilt: float,
|
1132
|
+
tilt_step: float,
|
1133
|
+
shape: Tuple[int],
|
1134
|
+
opening_axis: int = 0,
|
1135
|
+
tilt_axis: int = 2,
|
1136
|
+
sigma: float = 0,
|
1137
|
+
omit_negative_frequencies: bool = True,
|
1138
|
+
) -> NDArray:
|
1139
|
+
"""
|
1140
|
+
Create a wedge mask with the same shape as template by rotating a
|
1141
|
+
plane according to tilt angles. The DC component of the filter is at the origin.
|
1142
|
+
|
1143
|
+
Parameters
|
1144
|
+
----------
|
1145
|
+
start_tilt : float
|
1146
|
+
Starting tilt angle in degrees, e.g. a stage tilt of 70 degrees
|
1147
|
+
would yield a start_tilt value of 70.
|
1148
|
+
stop_tilt : float
|
1149
|
+
Ending tilt angle in degrees, , e.g. a stage tilt of -70 degrees
|
1150
|
+
would yield a stop_tilt value of 70.
|
1151
|
+
tilt_step : float
|
1152
|
+
Angle between the different tilt planes.
|
1153
|
+
shape : Tuple of ints
|
1154
|
+
Shape of the output wedge array.
|
1155
|
+
tilt_axis : int, optional
|
1156
|
+
Axis that the plane is tilted over.
|
1157
|
+
- 0 for Z-axis
|
1158
|
+
- 1 for Y-axis
|
1159
|
+
- 2 for X-axis
|
1160
|
+
opening_axis : int, optional
|
1161
|
+
Axis running through the void defined by the wedge.
|
1162
|
+
- 0 for Z-axis
|
1163
|
+
- 1 for Y-axis
|
1164
|
+
- 2 for X-axis
|
1165
|
+
sigma : float, optional
|
1166
|
+
Standard deviation for Gaussian kernel used for smoothing the wedge.
|
1167
|
+
omit_negative_frequencies : bool, optional
|
1168
|
+
Whether the wedge mask should omit negative frequencies, i.e. be
|
1169
|
+
applicable to symmetric Fourier transforms (see :obj:`numpy.fft.fftn`)
|
1170
|
+
|
1171
|
+
Returns
|
1172
|
+
-------
|
1173
|
+
NDArray
|
1174
|
+
A numpy array containing the wedge mask.
|
1175
|
+
|
1176
|
+
Notes
|
1177
|
+
-----
|
1178
|
+
This function is equivalent to :py:meth:`Preprocessor.wedge_mask`, but much faster
|
1179
|
+
for large shapes because it only considers a single tilt angle rather than the rotation
|
1180
|
+
of an N-1 dimensional hyperplane in N dimensions.
|
1181
|
+
|
1182
|
+
See Also
|
1183
|
+
--------
|
1184
|
+
:py:meth:`Preprocessor.wedge_mask`
|
1185
|
+
:py:meth:`Preprocessor.continuous_wedge_mask`
|
1186
|
+
"""
|
1187
|
+
tilt_angles = np.arange(-start_tilt, stop_tilt + tilt_step, tilt_step)
|
1188
|
+
plane = np.zeros((shape[opening_axis], shape[tilt_axis]), dtype=np.float32)
|
1189
|
+
subset = tuple(
|
1190
|
+
slice(None) if i != 0 else slice(x // 2, x // 2 + 1)
|
1191
|
+
for i, x in enumerate(plane.shape)
|
1192
|
+
)
|
1193
|
+
plane[subset] = 1
|
1194
|
+
plane_rotated, wedge_volume = np.zeros_like(plane), np.zeros_like(plane)
|
1195
|
+
for index in range(tilt_angles.shape[0]):
|
1196
|
+
plane_rotated.fill(0)
|
1197
|
+
|
1198
|
+
rotation_matrix = euler_to_rotationmatrix((tilt_angles[index], 0))
|
1199
|
+
rotation_matrix = rotation_matrix[np.ix_((0, 1), (0, 1))]
|
1200
|
+
|
1201
|
+
Density.rotate_array(
|
1202
|
+
arr=plane,
|
1203
|
+
rotation_matrix=rotation_matrix,
|
1204
|
+
out=plane_rotated,
|
1205
|
+
use_geometric_center=True,
|
1206
|
+
order=1,
|
1207
|
+
)
|
1208
|
+
wedge_volume += plane_rotated
|
1209
|
+
|
1210
|
+
wedge_volume = self.gaussian_filter(
|
1211
|
+
template=wedge_volume, sigma=sigma, fourier=False
|
1212
|
+
)
|
1213
|
+
wedge_volume = np.where(wedge_volume > np.exp(-2), 1, 0)
|
1214
|
+
|
1215
|
+
if opening_axis > tilt_axis:
|
1216
|
+
wedge_volume = np.moveaxis(wedge_volume, 1, 0)
|
1217
|
+
|
1218
|
+
reshape_dimensions = tuple(
|
1219
|
+
x if i in (opening_axis, tilt_axis) else 1 for i, x in enumerate(shape)
|
1220
|
+
)
|
1221
|
+
|
1222
|
+
wedge_volume = wedge_volume.reshape(reshape_dimensions)
|
1223
|
+
tile_dimensions = np.divide(shape, reshape_dimensions).astype(int)
|
1224
|
+
wedge_volume = np.tile(wedge_volume, tile_dimensions)
|
1225
|
+
|
1226
|
+
wedge_volume = np.fft.ifftshift(wedge_volume)
|
1227
|
+
|
1228
|
+
if omit_negative_frequencies:
|
1229
|
+
stop = 1 + (wedge_volume.shape[-1] // 2)
|
1230
|
+
wedge_volume = wedge_volume[..., :stop]
|
1231
|
+
|
1232
|
+
return wedge_volume
|
1233
|
+
|
1127
1234
|
def continuous_wedge_mask(
|
1128
1235
|
self,
|
1129
1236
|
start_tilt: float,
|
@@ -1192,6 +1299,7 @@ class Preprocessor:
|
|
1192
1299
|
See Also
|
1193
1300
|
--------
|
1194
1301
|
:py:meth:`Preprocessor.wedge_mask`
|
1302
|
+
:py:meth:`Preprocessor.step_wedge_mask`
|
1195
1303
|
"""
|
1196
1304
|
shape_center = np.divide(shape, 2).astype(int)
|
1197
1305
|
|
@@ -1348,7 +1456,7 @@ class LinearWhiteningFilter:
|
|
1348
1456
|
def filter(
|
1349
1457
|
self, template: NDArray, n_bins: int = None
|
1350
1458
|
) -> Tuple[NDArray, NDArray, NDArray]:
|
1351
|
-
max_bins =
|
1459
|
+
max_bins = np.max(template.shape) // 2 + 1
|
1352
1460
|
n_bins = max_bins if n_bins is None else n_bins
|
1353
1461
|
n_bins = int(min(n_bins, max_bins))
|
1354
1462
|
|
@@ -1371,7 +1479,7 @@ class LinearWhiteningFilter:
|
|
1371
1479
|
np.multiply(fourier_transform, radial_averages[bins], out=fourier_transform)
|
1372
1480
|
|
1373
1481
|
ret = np.fft.irfftn(
|
1374
|
-
np.fft.ifftshift(fourier_transform, axes=fft_shift_axes)
|
1482
|
+
np.fft.ifftshift(fourier_transform, axes=fft_shift_axes), s=template.shape
|
1375
1483
|
).real
|
1376
1484
|
return ret, bin_edges, radial_averages
|
1377
1485
|
|
@@ -1389,7 +1497,7 @@ class LinearWhiteningFilter:
|
|
1389
1497
|
bins = np.digitize(frequency_grid, bins=bin_edges, right=True)
|
1390
1498
|
np.multiply(fourier_transform, radial_averages[bins], out=fourier_transform)
|
1391
1499
|
ret = np.fft.irfftn(
|
1392
|
-
np.fft.ifftshift(fourier_transform, axes=fft_shift_axes)
|
1500
|
+
np.fft.ifftshift(fourier_transform, axes=fft_shift_axes), s=template.shape
|
1393
1501
|
).real
|
1394
1502
|
|
1395
1503
|
return ret
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|