pytme 0.3b0__cp311-cp311-macosx_15_0_arm64.whl → 0.3.1__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.3b0.data → pytme-0.3.1.data}/scripts/estimate_memory_usage.py +1 -5
- {pytme-0.3b0.data → pytme-0.3.1.data}/scripts/match_template.py +177 -226
- {pytme-0.3b0.data → pytme-0.3.1.data}/scripts/postprocess.py +69 -47
- {pytme-0.3b0.data → pytme-0.3.1.data}/scripts/preprocess.py +10 -23
- {pytme-0.3b0.data → pytme-0.3.1.data}/scripts/preprocessor_gui.py +98 -28
- pytme-0.3.1.data/scripts/pytme_runner.py +1223 -0
- {pytme-0.3b0.dist-info → pytme-0.3.1.dist-info}/METADATA +15 -15
- pytme-0.3.1.dist-info/RECORD +133 -0
- {pytme-0.3b0.dist-info → pytme-0.3.1.dist-info}/entry_points.txt +1 -0
- pytme-0.3.1.dist-info/licenses/LICENSE +339 -0
- scripts/estimate_memory_usage.py +1 -5
- scripts/eval.py +93 -0
- scripts/extract_candidates.py +118 -99
- scripts/match_template.py +177 -226
- scripts/match_template_filters.py +1200 -0
- scripts/postprocess.py +69 -47
- scripts/preprocess.py +10 -23
- scripts/preprocessor_gui.py +98 -28
- scripts/pytme_runner.py +1223 -0
- scripts/refine_matches.py +156 -387
- tests/data/.DS_Store +0 -0
- tests/data/Blurring/.DS_Store +0 -0
- tests/data/Maps/.DS_Store +0 -0
- tests/data/Raw/.DS_Store +0 -0
- tests/data/Structures/.DS_Store +0 -0
- tests/preprocessing/test_frequency_filters.py +19 -10
- tests/preprocessing/test_utils.py +18 -0
- tests/test_analyzer.py +122 -122
- tests/test_backends.py +4 -9
- tests/test_density.py +0 -1
- tests/test_matching_cli.py +30 -30
- tests/test_matching_data.py +5 -5
- tests/test_matching_utils.py +11 -61
- tests/test_rotations.py +1 -1
- tme/__version__.py +1 -1
- tme/analyzer/__init__.py +1 -1
- tme/analyzer/_utils.py +5 -8
- tme/analyzer/aggregation.py +28 -9
- tme/analyzer/base.py +25 -36
- tme/analyzer/peaks.py +49 -122
- tme/analyzer/proxy.py +1 -0
- tme/backends/_jax_utils.py +31 -28
- tme/backends/_numpyfftw_utils.py +270 -0
- tme/backends/cupy_backend.py +11 -54
- tme/backends/jax_backend.py +72 -48
- tme/backends/matching_backend.py +6 -51
- tme/backends/mlx_backend.py +1 -27
- tme/backends/npfftw_backend.py +95 -90
- tme/backends/pytorch_backend.py +5 -26
- tme/density.py +7 -10
- tme/extensions.cpython-311-darwin.so +0 -0
- tme/filters/__init__.py +2 -2
- tme/filters/_utils.py +32 -7
- tme/filters/bandpass.py +225 -186
- tme/filters/ctf.py +138 -87
- tme/filters/reconstruction.py +38 -9
- tme/filters/wedge.py +98 -112
- tme/filters/whitening.py +1 -6
- tme/mask.py +341 -0
- tme/matching_data.py +20 -44
- tme/matching_exhaustive.py +46 -56
- tme/matching_optimization.py +2 -1
- tme/matching_scores.py +216 -412
- tme/matching_utils.py +82 -424
- tme/memory.py +1 -1
- tme/orientations.py +16 -8
- tme/parser.py +109 -29
- tme/preprocessor.py +2 -2
- tme/rotations.py +1 -1
- pytme-0.3b0.dist-info/RECORD +0 -122
- pytme-0.3b0.dist-info/licenses/LICENSE +0 -153
- {pytme-0.3b0.dist-info → pytme-0.3.1.dist-info}/WHEEL +0 -0
- {pytme-0.3b0.dist-info → pytme-0.3.1.dist-info}/top_level.txt +0 -0
tme/filters/wedge.py
CHANGED
@@ -7,17 +7,17 @@ Copyright (c) 2024 European Molecular Biology Laboratory
|
|
7
7
|
Author: Valentin Maurer <valentin.maurer@embl-hamburg.de>
|
8
8
|
"""
|
9
9
|
|
10
|
-
import warnings
|
11
10
|
from typing import Tuple, Dict
|
11
|
+
from dataclasses import dataclass
|
12
12
|
|
13
13
|
import numpy as np
|
14
14
|
|
15
15
|
from ..types import NDArray
|
16
16
|
from ..backends import backend as be
|
17
17
|
from .compose import ComposableFilter
|
18
|
-
from ..matching_utils import
|
19
|
-
from ..parser import XMLParser, StarParser
|
18
|
+
from ..matching_utils import center_slice
|
20
19
|
from ..rotations import euler_to_rotationmatrix
|
20
|
+
from ..parser import XMLParser, StarParser, MDOCParser
|
21
21
|
from ._utils import (
|
22
22
|
centered_grid,
|
23
23
|
frequency_grid_at_angle,
|
@@ -31,56 +31,28 @@ from ._utils import (
|
|
31
31
|
__all__ = ["Wedge", "WedgeReconstructed"]
|
32
32
|
|
33
33
|
|
34
|
+
@dataclass
|
34
35
|
class Wedge(ComposableFilter):
|
35
36
|
"""
|
36
37
|
Generate wedge mask for tomographic data.
|
37
|
-
|
38
|
-
Parameters
|
39
|
-
----------
|
40
|
-
shape : tuple of int
|
41
|
-
The shape of the reconstruction volume.
|
42
|
-
tilt_axis : int
|
43
|
-
Axis the plane is tilted over, defaults to 0 (x).
|
44
|
-
opening_axis : int
|
45
|
-
The projection axis, defaults to 2 (z).
|
46
|
-
angles : tuple of float
|
47
|
-
The tilt angles.
|
48
|
-
weights : tuple of float
|
49
|
-
The weights corresponding to each tilt angle.
|
50
|
-
weight_type : str, optional
|
51
|
-
The type of weighting to apply, defaults to None.
|
52
|
-
frequency_cutoff : float, optional
|
53
|
-
Frequency cutoff for created mask. Nyquist 0.5 by default.
|
54
|
-
|
55
|
-
Returns
|
56
|
-
-------
|
57
|
-
dict
|
58
|
-
data: BackendArray
|
59
|
-
The filter mask.
|
60
|
-
shape: tuple of ints
|
61
|
-
The requested filter shape
|
62
|
-
return_real_fourier: bool
|
63
|
-
Whether data is compliant with rfftn.
|
64
|
-
is_multiplicative_filter: bool
|
65
|
-
Whether the filter is multiplicative in Fourier space.
|
66
38
|
"""
|
67
39
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
40
|
+
#: The shape of the reconstruction volume.
|
41
|
+
shape: Tuple[int] = None
|
42
|
+
#: The tilt angles.
|
43
|
+
angles: Tuple[float] = None
|
44
|
+
#: The weights corresponding to each tilt angle.
|
45
|
+
weights: Tuple[float] = None
|
46
|
+
#: Axis the plane is tilted over, defaults to 0 (x).
|
47
|
+
tilt_axis: int = 0
|
48
|
+
#: The projection axis, defaults to 2 (z).
|
49
|
+
opening_axis: int = 2
|
50
|
+
#: The type of weighting to apply, defaults to None.
|
51
|
+
weight_type: str = None
|
52
|
+
#: Frequency cutoff for created mask. Nyquist 0.5 by default.
|
53
|
+
frequency_cutoff: float = 0.5
|
54
|
+
#: The sampling rate, defaults to 1 Ångstrom / voxel.
|
55
|
+
sampling_rate: Tuple[float] = 1
|
84
56
|
|
85
57
|
@classmethod
|
86
58
|
def from_file(cls, filename: str) -> "Wedge":
|
@@ -93,6 +65,8 @@ class Wedge(ComposableFilter):
|
|
93
65
|
+-------+---------------------------------------------------------+
|
94
66
|
| .xml | WARP/M XML file |
|
95
67
|
+-------+---------------------------------------------------------+
|
68
|
+
| .mdoc | SerialEM file |
|
69
|
+
+-------+---------------------------------------------------------+
|
96
70
|
| .* | Tab-separated file with optional column names |
|
97
71
|
+-------+---------------------------------------------------------+
|
98
72
|
|
@@ -111,6 +85,8 @@ class Wedge(ComposableFilter):
|
|
111
85
|
func = _from_xml
|
112
86
|
elif filename.lower().endswith("star"):
|
113
87
|
func = _from_star
|
88
|
+
elif filename.lower().endswith("mdoc"):
|
89
|
+
func = _from_mdoc
|
114
90
|
|
115
91
|
data = func(filename)
|
116
92
|
angles, weights = data.get("angles", None), data.get("weights", None)
|
@@ -132,6 +108,9 @@ class Wedge(ComposableFilter):
|
|
132
108
|
)
|
133
109
|
|
134
110
|
def __call__(self, **kwargs: Dict) -> NDArray:
|
111
|
+
"""
|
112
|
+
Returns a Wedge stack of chosen parameters with DC component in the center.
|
113
|
+
"""
|
135
114
|
func_args = vars(self).copy()
|
136
115
|
func_args.update(kwargs)
|
137
116
|
|
@@ -170,6 +149,7 @@ class Wedge(ComposableFilter):
|
|
170
149
|
return {
|
171
150
|
"data": ret,
|
172
151
|
"shape": func_args["shape"],
|
152
|
+
"return_real_fourier": func_args.get("return_real_fourier", False),
|
173
153
|
"is_multiplicative_filter": True,
|
174
154
|
}
|
175
155
|
|
@@ -196,7 +176,12 @@ class Wedge(ComposableFilter):
|
|
196
176
|
return wedges
|
197
177
|
|
198
178
|
def weight_relion(
|
199
|
-
self,
|
179
|
+
self,
|
180
|
+
shape: Tuple[int],
|
181
|
+
opening_axis: int,
|
182
|
+
tilt_axis: int,
|
183
|
+
sampling_rate: float = 1.0,
|
184
|
+
**kwargs,
|
200
185
|
) -> NDArray:
|
201
186
|
"""
|
202
187
|
Generate weighted wedges based on the RELION 1.4 formalism, weighting each
|
@@ -211,7 +196,6 @@ class Wedge(ComposableFilter):
|
|
211
196
|
tilt_shape = compute_tilt_shape(
|
212
197
|
shape=shape, opening_axis=opening_axis, reduce_dim=True
|
213
198
|
)
|
214
|
-
|
215
199
|
wedges = np.zeros((len(self.angles), *tilt_shape))
|
216
200
|
for index, angle in enumerate(self.angles):
|
217
201
|
frequency_grid = frequency_grid_at_angle(
|
@@ -219,15 +203,14 @@ class Wedge(ComposableFilter):
|
|
219
203
|
opening_axis=opening_axis,
|
220
204
|
tilt_axis=tilt_axis,
|
221
205
|
angle=angle,
|
222
|
-
sampling_rate=
|
206
|
+
sampling_rate=sampling_rate,
|
223
207
|
)
|
224
208
|
sigma = np.sqrt(self.weights[index] * 4 / (8 * np.pi**2))
|
225
209
|
sigma = -2 * np.pi**2 * sigma**2
|
226
|
-
np.square(frequency_grid, out=frequency_grid)
|
227
|
-
np.multiply(sigma, frequency_grid, out=frequency_grid)
|
228
|
-
np.exp(frequency_grid, out=frequency_grid)
|
229
|
-
np.multiply(frequency_grid, np.cos(np.radians(angle))
|
230
|
-
wedges[index] = frequency_grid
|
210
|
+
frequency_grid = np.square(frequency_grid, out=frequency_grid)
|
211
|
+
frequency_grid = np.multiply(sigma, frequency_grid, out=frequency_grid)
|
212
|
+
frequency_grid = np.exp(frequency_grid, out=frequency_grid)
|
213
|
+
wedges[index] = np.multiply(frequency_grid, np.cos(np.radians(angle)))
|
231
214
|
|
232
215
|
return wedges
|
233
216
|
|
@@ -239,6 +222,7 @@ class Wedge(ComposableFilter):
|
|
239
222
|
amplitude: float = 0.245,
|
240
223
|
power: float = -1.665,
|
241
224
|
offset: float = 2.81,
|
225
|
+
sampling_rate: float = 1.0,
|
242
226
|
**kwargs,
|
243
227
|
) -> NDArray:
|
244
228
|
"""
|
@@ -264,7 +248,7 @@ class Wedge(ComposableFilter):
|
|
264
248
|
opening_axis=opening_axis,
|
265
249
|
tilt_axis=tilt_axis,
|
266
250
|
angle=angle,
|
267
|
-
sampling_rate=
|
251
|
+
sampling_rate=sampling_rate,
|
268
252
|
)
|
269
253
|
|
270
254
|
with np.errstate(divide="ignore"):
|
@@ -283,55 +267,35 @@ class Wedge(ComposableFilter):
|
|
283
267
|
return wedges
|
284
268
|
|
285
269
|
|
270
|
+
@dataclass
|
286
271
|
class WedgeReconstructed:
|
287
272
|
"""
|
288
273
|
Initialize :py:class:`WedgeReconstructed`.
|
289
|
-
|
290
|
-
Parameters
|
291
|
-
----------
|
292
|
-
angles :tuple of float, optional
|
293
|
-
The tilt angles, defaults to None.
|
294
|
-
tilt_axis : int
|
295
|
-
Axis the plane is tilted over, defaults to 0 (x).
|
296
|
-
opening_axis : int
|
297
|
-
The projection axis, defaults to 2 (z).
|
298
|
-
weights : tuple of float, optional
|
299
|
-
Weights to assign to individual wedge components.
|
300
|
-
weight_wedge : bool, optional
|
301
|
-
Whether individual wedge components should be weighted. If True and weights
|
302
|
-
is None, uses the cosine of the angle otherwise weights.
|
303
|
-
create_continuous_wedge: bool, optional
|
304
|
-
Whether to create a continous wedge or a per-component wedge. Weights are only
|
305
|
-
considered for non-continuous wedges.
|
306
|
-
frequency_cutoff : float, optional
|
307
|
-
Filter window applied during reconstruction.
|
308
|
-
**kwargs : Dict
|
309
|
-
Additional keyword arguments.
|
310
274
|
"""
|
311
275
|
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
self.create_continuous_wedge
|
331
|
-
|
276
|
+
#: The tilt angles, defaults to None.
|
277
|
+
angles: Tuple[float] = None
|
278
|
+
#: Weights to assign to individual wedge components. Not considered for continuous wedge
|
279
|
+
weights: Tuple[float] = None
|
280
|
+
#: Whether individual wedge components should be weighted.
|
281
|
+
weight_wedge: bool = False
|
282
|
+
#: Whether to create a continous wedge or a per-component wedge.
|
283
|
+
create_continuous_wedge: bool = False
|
284
|
+
#: Frequency cutoff of filter
|
285
|
+
frequency_cutoff: float = 0.5
|
286
|
+
#: Axis the plane is tilted over, defaults to 0 (x).
|
287
|
+
tilt_axis: int = 0
|
288
|
+
#: The projection axis, defaults to 2 (z).
|
289
|
+
opening_axis: int = 2
|
290
|
+
#: Filter window applied during reconstruction.
|
291
|
+
reconstruction_filter: str = None
|
292
|
+
|
293
|
+
def __post_init__(self):
|
294
|
+
if self.create_continuous_wedge:
|
295
|
+
self.angles = (min(self.angles), max(self.angles))
|
332
296
|
|
333
297
|
def __call__(
|
334
|
-
self, shape: Tuple[int], return_real_fourier: bool = False, **kwargs
|
298
|
+
self, shape: Tuple[int], return_real_fourier: bool = False, **kwargs
|
335
299
|
) -> Dict:
|
336
300
|
"""
|
337
301
|
Generate the reconstructed wedge.
|
@@ -341,10 +305,8 @@ class WedgeReconstructed:
|
|
341
305
|
shape : tuple of int
|
342
306
|
The shape of the reconstruction volume.
|
343
307
|
return_real_fourier : tuple of int
|
344
|
-
Return a shape compliant with
|
345
|
-
|
346
|
-
to False.
|
347
|
-
**kwargs : Dict
|
308
|
+
Return a shape compliant with rfftn. Defaults to False.
|
309
|
+
**kwargs : dict
|
348
310
|
Additional keyword arguments.
|
349
311
|
|
350
312
|
Returns
|
@@ -373,7 +335,6 @@ class WedgeReconstructed:
|
|
373
335
|
)
|
374
336
|
|
375
337
|
ret = func(shape=shape, **func_args)
|
376
|
-
|
377
338
|
frequency_cutoff = func_args.get("frequency_cutoff", None)
|
378
339
|
if frequency_cutoff is not None:
|
379
340
|
frequency_mask = fftfreqn(
|
@@ -528,7 +489,11 @@ class WedgeReconstructed:
|
|
528
489
|
)
|
529
490
|
wedge_volume += plane_rotated * weights[index]
|
530
491
|
|
531
|
-
|
492
|
+
subset = center_slice(
|
493
|
+
wedge_volume.shape, (shape[opening_axis], shape[tilt_axis])
|
494
|
+
)
|
495
|
+
wedge_volume = wedge_volume[subset]
|
496
|
+
|
532
497
|
np.fmin(wedge_volume, np.max(weights), wedge_volume)
|
533
498
|
|
534
499
|
if opening_axis > tilt_axis:
|
@@ -565,7 +530,7 @@ def _from_xml(filename: str, **kwargs) -> Dict:
|
|
565
530
|
|
566
531
|
def _from_star(filename: str, **kwargs) -> Dict:
|
567
532
|
"""
|
568
|
-
Read tilt data from a
|
533
|
+
Read tilt data from a STAR file.
|
569
534
|
|
570
535
|
Parameters
|
571
536
|
----------
|
@@ -577,8 +542,33 @@ def _from_star(filename: str, **kwargs) -> Dict:
|
|
577
542
|
Dict
|
578
543
|
A dictionary with one key for each column.
|
579
544
|
"""
|
580
|
-
data = StarParser(filename, delimiter=None)
|
581
|
-
|
545
|
+
data = StarParser(filename, delimiter=None)
|
546
|
+
if "data_stopgap_wedgelist" in data:
|
547
|
+
angles = data["data_stopgap_wedgelist"]["_tilt_angle"]
|
548
|
+
weights = data["data_stopgap_wedgelist"]["_exposure"]
|
549
|
+
else:
|
550
|
+
angles = data["data_"]["_wrpAxisAngle"]
|
551
|
+
weights = data["data_"]["_wrpDose"]
|
552
|
+
return {"angles": angles, "weights": weights}
|
553
|
+
|
554
|
+
|
555
|
+
def _from_mdoc(filename: str, **kwargs) -> Dict:
|
556
|
+
"""
|
557
|
+
Read tilt data from a SerialEM MDOC file.
|
558
|
+
|
559
|
+
Parameters
|
560
|
+
----------
|
561
|
+
filename : str
|
562
|
+
The path to the text file.
|
563
|
+
|
564
|
+
Returns
|
565
|
+
-------
|
566
|
+
Dict
|
567
|
+
A dictionary with one key for each column.
|
568
|
+
"""
|
569
|
+
data = MDOCParser(filename)
|
570
|
+
cumulative_exposure = np.multiply(np.add(1, data["ZValue"]), data["ExposureDose"])
|
571
|
+
return {"angles": data["TiltAngle"], "weights": cumulative_exposure}
|
582
572
|
|
583
573
|
|
584
574
|
def _from_text(filename: str, **kwargs) -> Dict:
|
@@ -604,10 +594,6 @@ def _from_text(filename: str, **kwargs) -> Dict:
|
|
604
594
|
if "angles" in data[0]:
|
605
595
|
headers = data.pop(0)
|
606
596
|
else:
|
607
|
-
warnings.warn(
|
608
|
-
f"Did not find a column named 'angles' in {filename}. Assuming "
|
609
|
-
"first column specifies angles."
|
610
|
-
)
|
611
597
|
if len(data[0]) != 1:
|
612
598
|
raise ValueError(
|
613
599
|
"Found more than one column without column names. Please add "
|
tme/filters/whitening.py
CHANGED
@@ -24,11 +24,6 @@ class LinearWhiteningFilter(ComposableFilter):
|
|
24
24
|
"""
|
25
25
|
Compute Fourier power spectrums and perform whitening.
|
26
26
|
|
27
|
-
Parameters
|
28
|
-
----------
|
29
|
-
**kwargs : Dict, optional
|
30
|
-
Additional keyword arguments.
|
31
|
-
|
32
27
|
References
|
33
28
|
----------
|
34
29
|
.. [1] de Teresa-Trueba, I.; Goetz, S. K.; Mattausch, A.; Stojanovska, F.; Zimmerli, C. E.;
|
@@ -39,7 +34,7 @@ class LinearWhiteningFilter(ComposableFilter):
|
|
39
34
|
13375 (2023)
|
40
35
|
"""
|
41
36
|
|
42
|
-
def __init__(self, **kwargs):
|
37
|
+
def __init__(self, *args, **kwargs):
|
43
38
|
pass
|
44
39
|
|
45
40
|
@staticmethod
|