pytme 0.1.1__cp311-cp311-macosx_13_0_arm64.whl → 0.1.3__cp311-cp311-macosx_13_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.
tme/preprocessor.py CHANGED
@@ -183,6 +183,8 @@ class Preprocessor:
183
183
  NDArray
184
184
  The simulated electron densities after applying the Gaussian filter.
185
185
  """
186
+ sigma = 0 if sigma is None else sigma
187
+
186
188
  if sigma <= 0:
187
189
  return template
188
190
 
@@ -998,8 +1000,7 @@ class Preprocessor:
998
1000
  shape : Tuple of ints
999
1001
  Shape of the output wedge array.
1000
1002
  tilt_angles : NDArray
1001
- Tilt angles in format d dimensions N tilts [d x N], e.g.
1002
- x_axis tilt, y_axis tilt, ...
1003
+ Tilt angles in format d dimensions N tilts [d x N].
1003
1004
  sigma : float, optional
1004
1005
  Standard deviation for Gaussian kernel used for smoothing the wedge.
1005
1006
  omit_negative_frequencies : bool, optional
@@ -1011,17 +1012,65 @@ class Preprocessor:
1011
1012
  NDArray
1012
1013
  A numpy array containing the wedge mask.
1013
1014
 
1015
+ Notes
1016
+ -----
1017
+ The axis perpendicular to the tilts is the leftmost closest axis
1018
+ with minimal tilt.
1019
+
1020
+ Examples
1021
+ --------
1022
+ >>> import numpy as np
1023
+ >>> from tme import Preprocessor
1024
+ >>> angles = np.zeros((3, 10))
1025
+ >>> angles[2, :] = np.linspace(-50, 55, 10)
1026
+ >>> wedge = Preprocessor().wedge_mask(
1027
+ >>> shape = (50,50,50),
1028
+ >>> tilt_angles = angles,
1029
+ >>> omit_negative_frequencies = True
1030
+ >>> )
1031
+ >>> wedge = np.fft.fftshift(wedge)
1032
+
1033
+ This will create a wedge that is open along axis 1, tilted
1034
+ around axis 2 and propagated along axis 0. The code above would
1035
+ be equivalent to the following
1036
+
1037
+ >>> wedge = Preprocessor().continuous_wedge_mask(
1038
+ >>> shape = (50,50,50),
1039
+ >>> start_tilt = 50,
1040
+ >>> stop_tilt=55,
1041
+ >>> tilt_axis=1,
1042
+ >>> omit_negative_frequencies=False,
1043
+ >>> infinite_plane=False
1044
+ >>> )
1045
+ >>> wedge = np.fft.fftshift(wedge)
1046
+
1047
+ with the difference being that :py:meth:`Preprocessor.continuous_wedge_mask`
1048
+ does not consider individual plane tilts.
1049
+
1014
1050
  See Also
1015
1051
  --------
1016
1052
  :py:meth:`Preprocessor.continuous_wedge_mask`
1017
1053
  """
1018
1054
  plane = np.zeros(shape, dtype=np.float32)
1019
- plane[plane.shape[0] // 2] = 1
1055
+ opening_axis = np.argmax(np.abs(tilt_angles), axis=0)
1056
+ slices = tuple(slice(a, a + 1) for a in np.divide(shape, 2).astype(int))
1020
1057
  plane_rotated = np.zeros_like(plane)
1021
1058
  wedge_volume = np.zeros_like(plane)
1022
1059
  for index in range(tilt_angles.shape[1]):
1060
+ potential_axes, *_ = np.where(
1061
+ np.abs(tilt_angles[:, index]) == np.abs(tilt_angles[:, index]).min()
1062
+ )
1063
+ largest_tilt = np.argmax(np.abs(tilt_angles[:, index]))
1064
+ opening_axis_index = np.argmin(np.abs(potential_axes - largest_tilt))
1065
+ opening_axis = potential_axes[opening_axis_index]
1023
1066
  rotation_matrix = euler_to_rotationmatrix(tilt_angles[:, index])
1024
1067
  plane_rotated.fill(0)
1068
+ plane.fill(0)
1069
+ subset = tuple(
1070
+ slice(None) if i != opening_axis else slices[opening_axis]
1071
+ for i in range(plane.ndim)
1072
+ )
1073
+ plane[subset] = 1
1025
1074
  Density.rotate_array(
1026
1075
  arr=plane,
1027
1076
  rotation_matrix=rotation_matrix,
@@ -1051,6 +1100,7 @@ class Preprocessor:
1051
1100
  tilt_axis: int = 1,
1052
1101
  sigma: float = 0,
1053
1102
  extrude_plane: bool = True,
1103
+ infinite_plane: bool = True,
1054
1104
  omit_negative_frequencies: bool = True,
1055
1105
  ) -> NDArray:
1056
1106
  """
@@ -1066,7 +1116,7 @@ class Preprocessor:
1066
1116
  Ending tilt angle in degrees, , e.g. a stage tilt of -70 degrees
1067
1117
  would yield a stop_tilt value of 70.
1068
1118
  tilt_axis : int
1069
- Axis of tilt.
1119
+ Axis that runs through the empty part of the wedge.
1070
1120
  - 0 for X-axis
1071
1121
  - 1 for Y-axis
1072
1122
  - 2 for Z-axis
@@ -1082,6 +1132,9 @@ class Preprocessor:
1082
1132
  omit_negative_frequencies : bool, optional
1083
1133
  Whether the wedge mask should omit negative frequencies, i.e. be
1084
1134
  applicable to non hermitian-symmetric fourier transforms.
1135
+ infinite_plane : bool, optional
1136
+ Whether the plane should be considered to be larger than the shape. In this
1137
+ case the output wedge mask fill have no spheric component.
1085
1138
 
1086
1139
  Returns
1087
1140
  -------
@@ -1104,9 +1157,8 @@ class Preprocessor:
1104
1157
  """
1105
1158
  shape_center = np.divide(shape, 2).astype(int)
1106
1159
 
1107
- axis_indices = list(range(len(shape)))
1108
- base_axis = axis_indices.pop((tilt_axis + 1) % len(shape))
1109
- opening_axis = axis_indices.pop(0)
1160
+ opening_axis = tilt_axis
1161
+ base_axis = (tilt_axis + 1) % len(shape)
1110
1162
 
1111
1163
  grid = (np.indices(shape).T - shape_center).T
1112
1164
 
@@ -1130,7 +1182,9 @@ class Preprocessor:
1130
1182
  else:
1131
1183
  distances = np.linalg.norm(grid, axis=0)
1132
1184
 
1133
- np.multiply(wedge, distances <= shape[tilt_axis] // 2, out=wedge)
1185
+ if not infinite_plane:
1186
+ np.multiply(wedge, distances <= shape[opening_axis] // 2, out=wedge)
1187
+
1134
1188
  wedge = self.gaussian_filter(template=wedge, sigma=sigma, fourier=False)
1135
1189
  wedge = np.fft.ifftshift(wedge > np.exp(-2))
1136
1190