pytme 0.3.1.post2__cp311-cp311-macosx_15_0_arm64.whl → 0.3.2__cp311-cp311-macosx_15_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.3.2.data/scripts/estimate_ram_usage.py +97 -0
- {pytme-0.3.1.post2.data → pytme-0.3.2.data}/scripts/match_template.py +213 -196
- {pytme-0.3.1.post2.data → pytme-0.3.2.data}/scripts/postprocess.py +40 -78
- {pytme-0.3.1.post2.data → pytme-0.3.2.data}/scripts/preprocess.py +4 -5
- {pytme-0.3.1.post2.data → pytme-0.3.2.data}/scripts/preprocessor_gui.py +49 -103
- {pytme-0.3.1.post2.data → pytme-0.3.2.data}/scripts/pytme_runner.py +46 -69
- {pytme-0.3.1.post2.dist-info → pytme-0.3.2.dist-info}/METADATA +3 -2
- {pytme-0.3.1.post2.dist-info → pytme-0.3.2.dist-info}/RECORD +68 -65
- scripts/estimate_ram_usage.py +97 -0
- scripts/match_template.py +213 -196
- scripts/match_template_devel.py +1339 -0
- scripts/postprocess.py +40 -78
- scripts/preprocess.py +4 -5
- scripts/preprocessor_gui.py +49 -103
- scripts/pytme_runner.py +46 -69
- tests/preprocessing/test_compose.py +31 -30
- tests/preprocessing/test_frequency_filters.py +17 -32
- tests/preprocessing/test_preprocessor.py +0 -19
- tests/preprocessing/test_utils.py +13 -1
- tests/test_analyzer.py +2 -10
- tests/test_backends.py +47 -18
- tests/test_density.py +72 -13
- tests/test_extensions.py +1 -0
- tests/test_matching_cli.py +23 -9
- tests/test_matching_exhaustive.py +5 -5
- tests/test_matching_utils.py +3 -3
- tests/test_orientations.py +12 -0
- tests/test_rotations.py +13 -23
- tests/test_structure.py +1 -7
- tme/__version__.py +1 -1
- tme/analyzer/aggregation.py +47 -16
- tme/analyzer/base.py +34 -0
- tme/analyzer/peaks.py +26 -13
- tme/analyzer/proxy.py +14 -0
- tme/backends/_jax_utils.py +91 -68
- tme/backends/cupy_backend.py +6 -19
- tme/backends/jax_backend.py +103 -98
- tme/backends/matching_backend.py +0 -17
- tme/backends/mlx_backend.py +0 -29
- tme/backends/npfftw_backend.py +100 -97
- tme/backends/pytorch_backend.py +65 -78
- tme/cli.py +2 -2
- tme/density.py +44 -57
- tme/extensions.cpython-311-darwin.so +0 -0
- tme/filters/_utils.py +52 -24
- tme/filters/bandpass.py +99 -105
- tme/filters/compose.py +133 -39
- tme/filters/ctf.py +51 -102
- tme/filters/reconstruction.py +67 -122
- tme/filters/wedge.py +296 -325
- tme/filters/whitening.py +39 -75
- tme/mask.py +2 -2
- tme/matching_data.py +87 -15
- tme/matching_exhaustive.py +70 -120
- tme/matching_optimization.py +9 -63
- tme/matching_scores.py +261 -100
- tme/matching_utils.py +150 -91
- tme/memory.py +1 -0
- tme/orientations.py +17 -3
- tme/preprocessor.py +0 -239
- tme/rotations.py +102 -70
- tme/structure.py +601 -631
- tme/types.py +1 -0
- {pytme-0.3.1.post2.data → pytme-0.3.2.data}/scripts/estimate_memory_usage.py +0 -0
- {pytme-0.3.1.post2.dist-info → pytme-0.3.2.dist-info}/WHEEL +0 -0
- {pytme-0.3.1.post2.dist-info → pytme-0.3.2.dist-info}/entry_points.txt +0 -0
- {pytme-0.3.1.post2.dist-info → pytme-0.3.2.dist-info}/licenses/LICENSE +0 -0
- {pytme-0.3.1.post2.dist-info → pytme-0.3.2.dist-info}/top_level.txt +0 -0
tme/rotations.py
CHANGED
@@ -7,7 +7,6 @@ Author: Valentin Maurer <valentin.maurer@embl-hamburg.de>
|
|
7
7
|
"""
|
8
8
|
|
9
9
|
import yaml
|
10
|
-
import warnings
|
11
10
|
from typing import Tuple
|
12
11
|
from os.path import join, dirname
|
13
12
|
|
@@ -68,12 +67,7 @@ def _sample_cone(
|
|
68
67
|
],
|
69
68
|
axis=1,
|
70
69
|
)
|
71
|
-
|
72
|
-
rotation = Rotation.from_euler(
|
73
|
-
angles=align_vectors((1, 0, 0), axis, seq="zyz"),
|
74
|
-
seq="zyz",
|
75
|
-
degrees=True,
|
76
|
-
)
|
70
|
+
rotation = Rotation.from_matrix(align_vectors((1, 0, 0), axis, seq=None))
|
77
71
|
return rotation.apply(points)
|
78
72
|
|
79
73
|
|
@@ -85,7 +79,7 @@ def get_cone_rotations(
|
|
85
79
|
axis_sampling: float = None,
|
86
80
|
reference: Tuple[float] = (1, 0, 0),
|
87
81
|
n_symmetry: int = 1,
|
88
|
-
|
82
|
+
**kwargs,
|
89
83
|
) -> NDArray:
|
90
84
|
"""
|
91
85
|
Generate rotations describing the possible placements of a vector in a cone.
|
@@ -108,14 +102,17 @@ def get_cone_rotations(
|
|
108
102
|
the principal axis of the template.
|
109
103
|
n_symmetry : int, optional
|
110
104
|
Number of symmetry axis around the vector axis.
|
111
|
-
seq : str
|
112
|
-
|
105
|
+
seq : str
|
106
|
+
Output convention.
|
107
|
+
|
108
|
+
.. deprecated:: 0.3.2
|
109
|
+
|
110
|
+
Returns rotation matrices always.
|
113
111
|
|
114
112
|
Returns
|
115
113
|
-------
|
116
114
|
NDArray
|
117
|
-
An arary of rotations represented as stack of rotation matrices
|
118
|
-
None (n, 3, 3) or an array of Euler angles (n, 3) for available conventions.
|
115
|
+
An arary of rotations represented as stack of rotation matrices (n, 3, 3).
|
119
116
|
"""
|
120
117
|
if axis_sampling is None:
|
121
118
|
axis_sampling = cone_sampling
|
@@ -133,17 +130,13 @@ def get_cone_rotations(
|
|
133
130
|
axis_rotation * Rotation.from_matrix(align_vectors(reference, x))
|
134
131
|
for x in points
|
135
132
|
]
|
133
|
+
return Rotation.concatenate(all_rotations).as_matrix()
|
136
134
|
|
137
|
-
rotations = Rotation.concatenate(all_rotations)
|
138
|
-
if seq is None:
|
139
|
-
return rotations.as_matrix()
|
140
135
|
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
def align_vectors(base: NDArray, target: NDArray = (0, 0, 1), seq: str = None):
|
136
|
+
def align_vectors(base: NDArray, target: NDArray = (0, 0, 1), **kwargs) -> NDArray:
|
145
137
|
"""
|
146
|
-
Compute the rotation matrix or Euler angles required to align an initial
|
138
|
+
Compute the rotation matrix or Euler angles required to align an initial
|
139
|
+
vector with a target vector.
|
147
140
|
|
148
141
|
Parameters
|
149
142
|
----------
|
@@ -151,77 +144,59 @@ def align_vectors(base: NDArray, target: NDArray = (0, 0, 1), seq: str = None):
|
|
151
144
|
The basis vector.
|
152
145
|
target : NDArray, optional
|
153
146
|
The vector to map base to, defaults to (0,0,1).
|
154
|
-
seq : str
|
155
|
-
|
147
|
+
seq : str
|
148
|
+
Output convention.
|
149
|
+
|
150
|
+
.. deprecated:: 0.3.2
|
151
|
+
|
152
|
+
Returns rotation matrices always.
|
156
153
|
|
157
154
|
Returns
|
158
155
|
-------
|
159
156
|
NDArray
|
160
|
-
Rotation matrix
|
157
|
+
Rotation matrix mapping base to target.
|
161
158
|
"""
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
rotation, error = Rotation.align_vectors(target, base)
|
166
|
-
if seq is None:
|
167
|
-
return rotation.as_matrix()
|
168
|
-
return rotation.as_euler(seq=seq, degrees=True)
|
159
|
+
rotation, _ = Rotation.align_vectors(target, base)
|
160
|
+
return rotation.as_matrix().astype(np.float32)
|
169
161
|
|
170
162
|
|
171
|
-
def euler_to_rotationmatrix(angles: Tuple[float], seq: str = "
|
163
|
+
def euler_to_rotationmatrix(angles: Tuple[float], seq: str = "ZYZ") -> NDArray:
|
172
164
|
"""
|
173
165
|
Convert Euler angles to a rotation matrix.
|
174
166
|
|
175
167
|
Parameters
|
176
168
|
----------
|
177
169
|
angles : tuple
|
178
|
-
|
170
|
+
Euler angles in degrees.
|
179
171
|
seq : str, optional
|
180
|
-
Euler angle convention.
|
172
|
+
Euler angle convention, defaults to ZYZ.
|
181
173
|
|
182
174
|
Returns
|
183
175
|
-------
|
184
176
|
NDArray
|
185
|
-
|
177
|
+
Corresponding rotation matrix.
|
186
178
|
"""
|
187
|
-
|
188
|
-
|
189
|
-
n_angles = len(angles)
|
190
|
-
if angles.ndim == 2:
|
191
|
-
n_angles = angles.shape[1]
|
192
|
-
|
193
|
-
rotation_matrix = Rotation.from_euler(
|
194
|
-
seq=seq[:n_angles], angles=angles, degrees=True
|
195
|
-
)
|
196
|
-
return rotation_matrix.as_matrix().astype(np.float32)
|
179
|
+
rotation = Rotation.from_euler(seq=seq, angles=angles, degrees=True)
|
180
|
+
return rotation.as_matrix().astype(np.float32)
|
197
181
|
|
198
182
|
|
199
|
-
def euler_from_rotationmatrix(rotation_matrix: NDArray, seq: str = "
|
183
|
+
def euler_from_rotationmatrix(rotation_matrix: NDArray, seq: str = "ZYZ") -> NDArray:
|
200
184
|
"""
|
201
|
-
Convert a rotation matrix to
|
185
|
+
Convert a rotation matrix to Euler angles.
|
202
186
|
|
203
187
|
Parameters
|
204
188
|
----------
|
205
189
|
rotation_matrix : NDArray
|
206
|
-
|
190
|
+
Rotation matrix (d,d).
|
207
191
|
seq : str, optional
|
208
|
-
Euler angle convention,
|
192
|
+
Euler angle convention, default to intrinsic ZYZ.
|
209
193
|
|
210
194
|
Returns
|
211
195
|
-------
|
212
|
-
|
213
|
-
|
196
|
+
NDArray
|
197
|
+
Corresponding Euler angles in degrees.
|
214
198
|
"""
|
215
|
-
|
216
|
-
temp_matrix = np.eye(3)
|
217
|
-
temp_matrix[:2, :2] = rotation_matrix
|
218
|
-
rotation_matrix = temp_matrix
|
219
|
-
|
220
|
-
with warnings.catch_warnings():
|
221
|
-
warnings.simplefilter("ignore")
|
222
|
-
rotation = Rotation.from_matrix(rotation_matrix)
|
223
|
-
angles = rotation.as_euler(seq=seq, degrees=True).astype(np.float32)
|
224
|
-
return angles
|
199
|
+
return Rotation.from_matrix(rotation_matrix).as_euler(seq=seq, degrees=True)
|
225
200
|
|
226
201
|
|
227
202
|
def get_rotation_matrices(
|
@@ -250,16 +225,16 @@ def get_rotation_matrices(
|
|
250
225
|
"""
|
251
226
|
if dim == 3 and use_optimized_set:
|
252
227
|
quaternions, *_ = _load_quaternions_by_angle(angular_sampling)
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
228
|
+
return Rotation.from_quat(quaternions, scalar_first=True).as_matrix()
|
229
|
+
|
230
|
+
num_rotations = dim * (dim - 1) // 2
|
231
|
+
k = int((360 / angular_sampling) ** num_rotations)
|
232
|
+
As = np.random.randn(k, dim, dim)
|
233
|
+
ret, _ = np.linalg.qr(As)
|
234
|
+
dets = np.linalg.det(ret)
|
235
|
+
neg_dets = dets < 0
|
236
|
+
ret[neg_dets, :, -1] *= -1
|
237
|
+
ret[0] = np.eye(dim, dtype=ret.dtype)
|
263
238
|
return ret
|
264
239
|
|
265
240
|
|
@@ -351,3 +326,60 @@ def align_to_axis(
|
|
351
326
|
eigenvalues, eigenvectors = np.linalg.eigh(cov_matrix)
|
352
327
|
eigenvector = eigenvectors[:, -(eigenvector_index + 1)]
|
353
328
|
return align_vectors(eigenvector, alignment_axis)
|
329
|
+
|
330
|
+
|
331
|
+
def get_symmetry_matrices(
|
332
|
+
symmetry_type: str, axis: Tuple[float] = (0, 0, 1)
|
333
|
+
) -> NDArray:
|
334
|
+
"""
|
335
|
+
Generate rotation matrices for common point group symmetries.
|
336
|
+
|
337
|
+
Parameters
|
338
|
+
----------
|
339
|
+
symmetry_type : str
|
340
|
+
Type of symmetry. Supported: 'C1', 'C2', 'C3', 'C4', 'C5', 'C6', 'D2', 'D3', 'D4'
|
341
|
+
axis : Tuple[float], optional
|
342
|
+
Symmetry axis as (x, y, z) vector, defaults to (0, 0, 1) for Z-axis.
|
343
|
+
|
344
|
+
Returns
|
345
|
+
-------
|
346
|
+
NDArray
|
347
|
+
Array of rotation matrices with shape (n, 3, 3).
|
348
|
+
|
349
|
+
"""
|
350
|
+
axis = np.array(axis, dtype=np.float32)
|
351
|
+
axis = axis / np.linalg.norm(axis)
|
352
|
+
|
353
|
+
try:
|
354
|
+
n = int(symmetry_type[1:])
|
355
|
+
except IndexError:
|
356
|
+
n = 1
|
357
|
+
|
358
|
+
matrices = []
|
359
|
+
symmetry = symmetry_type.upper()[0]
|
360
|
+
if symmetry == "C":
|
361
|
+
|
362
|
+
for i in range(n):
|
363
|
+
angle = 2 * np.pi * i / n
|
364
|
+
R = Rotation.from_rotvec(angle * axis)
|
365
|
+
matrices.append(R.as_matrix().astype(np.float32))
|
366
|
+
|
367
|
+
elif symmetry == "D":
|
368
|
+
# First add the Cn rotations around main axis
|
369
|
+
matrices.extend(get_symmetry_matrices(f"C{n}", axis=axis))
|
370
|
+
|
371
|
+
# Then add n 180° rotations around perpendicular axes
|
372
|
+
_, _, vh = np.linalg.svd(axis.reshape(1, -1))
|
373
|
+
|
374
|
+
perp = vh[-1].astype(np.float32)
|
375
|
+
perp = perp / np.linalg.norm(perp)
|
376
|
+
for i in range(n):
|
377
|
+
angle = 2 * np.pi * i / n
|
378
|
+
R = Rotation.from_rotvec(angle * axis)
|
379
|
+
|
380
|
+
R_180 = Rotation.from_rotvec(np.pi * R.apply(perp))
|
381
|
+
matrices.append(R_180.as_matrix().astype(np.float32))
|
382
|
+
else:
|
383
|
+
raise ValueError(f"Unsupported symmetry type: {symmetry_type}")
|
384
|
+
|
385
|
+
return np.array(matrices)
|