pytme 0.2.9__cp311-cp311-macosx_15_0_arm64.whl → 0.3b0__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.2.9.data/scripts/estimate_ram_usage.py → pytme-0.3b0.data/scripts/estimate_memory_usage.py +16 -33
- {pytme-0.2.9.data → pytme-0.3b0.data}/scripts/match_template.py +224 -223
- {pytme-0.2.9.data → pytme-0.3b0.data}/scripts/postprocess.py +283 -163
- {pytme-0.2.9.data → pytme-0.3b0.data}/scripts/preprocess.py +11 -8
- {pytme-0.2.9.data → pytme-0.3b0.data}/scripts/preprocessor_gui.py +10 -9
- {pytme-0.2.9.dist-info → pytme-0.3b0.dist-info}/METADATA +11 -9
- {pytme-0.2.9.dist-info → pytme-0.3b0.dist-info}/RECORD +61 -58
- {pytme-0.2.9.dist-info → pytme-0.3b0.dist-info}/entry_points.txt +1 -1
- scripts/{estimate_ram_usage.py → estimate_memory_usage.py} +16 -33
- scripts/extract_candidates.py +224 -0
- scripts/match_template.py +224 -223
- scripts/postprocess.py +283 -163
- scripts/preprocess.py +11 -8
- scripts/preprocessor_gui.py +10 -9
- scripts/refine_matches.py +626 -0
- tests/preprocessing/test_frequency_filters.py +9 -4
- tests/test_analyzer.py +143 -138
- tests/test_matching_cli.py +85 -29
- tests/test_matching_exhaustive.py +1 -2
- tests/test_matching_optimization.py +4 -9
- tests/test_orientations.py +0 -1
- tme/__version__.py +1 -1
- tme/analyzer/__init__.py +2 -0
- tme/analyzer/_utils.py +25 -17
- tme/analyzer/aggregation.py +385 -220
- tme/analyzer/base.py +138 -0
- tme/analyzer/peaks.py +150 -88
- tme/analyzer/proxy.py +122 -0
- tme/backends/__init__.py +4 -3
- tme/backends/_cupy_utils.py +25 -24
- tme/backends/_jax_utils.py +4 -3
- tme/backends/cupy_backend.py +4 -13
- tme/backends/jax_backend.py +6 -8
- tme/backends/matching_backend.py +4 -3
- tme/backends/mlx_backend.py +4 -3
- tme/backends/npfftw_backend.py +7 -5
- tme/backends/pytorch_backend.py +14 -4
- tme/cli.py +126 -0
- tme/density.py +4 -3
- tme/filters/__init__.py +1 -1
- tme/filters/_utils.py +4 -3
- tme/filters/bandpass.py +6 -4
- tme/filters/compose.py +5 -4
- tme/filters/ctf.py +426 -214
- tme/filters/reconstruction.py +58 -28
- tme/filters/wedge.py +139 -61
- tme/filters/whitening.py +36 -36
- tme/matching_data.py +4 -3
- tme/matching_exhaustive.py +17 -16
- tme/matching_optimization.py +5 -4
- tme/matching_scores.py +4 -3
- tme/matching_utils.py +6 -4
- tme/memory.py +4 -3
- tme/orientations.py +9 -6
- tme/parser.py +5 -4
- tme/preprocessor.py +4 -3
- tme/rotations.py +10 -7
- tme/structure.py +4 -3
- tests/data/Maps/.DS_Store +0 -0
- tests/data/Structures/.DS_Store +0 -0
- {pytme-0.2.9.dist-info → pytme-0.3b0.dist-info}/WHEEL +0 -0
- {pytme-0.2.9.dist-info → pytme-0.3b0.dist-info}/licenses/LICENSE +0 -0
- {pytme-0.2.9.dist-info → pytme-0.3b0.dist-info}/top_level.txt +0 -0
tme/backends/_cupy_utils.py
CHANGED
@@ -1,34 +1,35 @@
|
|
1
|
-
"""
|
1
|
+
"""
|
2
|
+
Utility functions for cupy backend.
|
2
3
|
|
3
|
-
|
4
|
-
|
5
|
-
|
4
|
+
The functions spline_filter, _prepad_for_spline_filter, _filter_input,
|
5
|
+
_get_coord_affine_batched and affine_transform are largely copied from
|
6
|
+
cupyx.scipy.ndimage which operates under the following license
|
6
7
|
|
7
|
-
|
8
|
-
|
8
|
+
Copyright (c) 2015 Preferred Infrastructure, Inc.
|
9
|
+
Copyright (c) 2015 Preferred Networks, Inc.
|
9
10
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
11
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
12
|
+
of this software and associated documentation files (the "Software"), to deal
|
13
|
+
in the Software without restriction, including without limitation the rights
|
14
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
15
|
+
copies of the Software, and to permit persons to whom the Software is
|
16
|
+
furnished to do so, subject to the following conditions:
|
16
17
|
|
17
|
-
|
18
|
-
|
18
|
+
The above copyright notice and this permission notice shall be included in
|
19
|
+
all copies or substantial portions of the Software.
|
19
20
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
21
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
22
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
23
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
24
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
25
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
26
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
27
|
+
THE SOFTWARE.
|
27
28
|
|
28
|
-
|
29
|
-
|
29
|
+
I have since extended the functionality of the cupyx.scipy.ndimage functions
|
30
|
+
in question to support batched inputs.
|
30
31
|
|
31
|
-
|
32
|
+
Author: Valentin Maurer <valentin.maurer@embl-hamburg.de>
|
32
33
|
"""
|
33
34
|
|
34
35
|
import numpy
|
tme/backends/_jax_utils.py
CHANGED
@@ -1,8 +1,9 @@
|
|
1
|
-
"""
|
1
|
+
"""
|
2
|
+
Utility functions for jax backend.
|
2
3
|
|
3
|
-
|
4
|
+
Copyright (c) 2023-2024 European Molecular Biology Laboratory
|
4
5
|
|
5
|
-
|
6
|
+
Author: Valentin Maurer <valentin.maurer@embl-hamburg.de>
|
6
7
|
"""
|
7
8
|
|
8
9
|
from typing import Tuple
|
tme/backends/cupy_backend.py
CHANGED
@@ -1,8 +1,9 @@
|
|
1
|
-
"""
|
1
|
+
"""
|
2
|
+
Backend using cupy for template matching.
|
2
3
|
|
3
|
-
|
4
|
+
Copyright (c) 2023 European Molecular Biology Laboratory
|
4
5
|
|
5
|
-
|
6
|
+
Author: Valentin Maurer <valentin.maurer@embl-hamburg.de>
|
6
7
|
"""
|
7
8
|
|
8
9
|
import warnings
|
@@ -113,16 +114,6 @@ class CupyBackend(NumpyFFTWBackend):
|
|
113
114
|
def unravel_index(self, indices, shape):
|
114
115
|
return self._array_backend.unravel_index(indices=indices, dims=shape)
|
115
116
|
|
116
|
-
def unique(self, ar, axis=None, *args, **kwargs):
|
117
|
-
if axis is None:
|
118
|
-
return self._array_backend.unique(ar=ar, axis=axis, *args, **kwargs)
|
119
|
-
|
120
|
-
warnings.warn("Axis argument not yet supported in CupY, falling back to NumPy.")
|
121
|
-
ret = np.unique(ar=self.to_numpy_array(ar), axis=axis, *args, **kwargs)
|
122
|
-
if not isinstance(ret, tuple):
|
123
|
-
return self.to_backend_array(ret)
|
124
|
-
return tuple(self.to_backend_array(k) for k in ret)
|
125
|
-
|
126
117
|
def build_fft(
|
127
118
|
self,
|
128
119
|
fwd_shape: Tuple[int],
|
tme/backends/jax_backend.py
CHANGED
@@ -1,8 +1,9 @@
|
|
1
|
-
"""
|
1
|
+
"""
|
2
|
+
Backend using jax for template matching.
|
2
3
|
|
3
|
-
|
4
|
+
Copyright (c) 2023-2024 European Molecular Biology Laboratory
|
4
5
|
|
5
|
-
|
6
|
+
Author: Valentin Maurer <valentin.maurer@embl-hamburg.de>
|
6
7
|
"""
|
7
8
|
|
8
9
|
from functools import wraps
|
@@ -288,13 +289,10 @@ class JaxBackend(NumpyFFTWBackend):
|
|
288
289
|
for index in range(scores.shape[0]):
|
289
290
|
temp = callback_class(
|
290
291
|
shape=scores.shape,
|
291
|
-
scores=scores[index],
|
292
|
-
rotations=rotations[index],
|
293
|
-
thread_safe=False,
|
294
292
|
offset=translation_offsets[index],
|
295
293
|
)
|
296
|
-
|
297
|
-
ret.append(
|
294
|
+
state = (scores, rotations, rotation_mapping)
|
295
|
+
ret.append(temp.result(state, **analyzer_args))
|
298
296
|
|
299
297
|
return ret
|
300
298
|
|
tme/backends/matching_backend.py
CHANGED
@@ -1,8 +1,9 @@
|
|
1
|
-
"""
|
1
|
+
"""
|
2
|
+
Strategy pattern to allow for flexible array / FFT backends.
|
2
3
|
|
3
|
-
|
4
|
+
Copyright (c) 2023 European Molecular Biology Laboratory
|
4
5
|
|
5
|
-
|
6
|
+
Author: Valentin Maurer <valentin.maurer@embl-hamburg.de>
|
6
7
|
"""
|
7
8
|
|
8
9
|
from abc import ABC, abstractmethod
|
tme/backends/mlx_backend.py
CHANGED
@@ -1,8 +1,9 @@
|
|
1
|
-
"""
|
1
|
+
"""
|
2
|
+
Backend using Apple's MLX library for template matching.
|
2
3
|
|
3
|
-
|
4
|
+
Copyright (c) 2024 European Molecular Biology Laboratory
|
4
5
|
|
5
|
-
|
6
|
+
Author: Valentin Maurer <valentin.maurer@embl-hamburg.de>
|
6
7
|
"""
|
7
8
|
|
8
9
|
from typing import Tuple, List, Callable
|
tme/backends/npfftw_backend.py
CHANGED
@@ -1,8 +1,9 @@
|
|
1
|
-
"""
|
1
|
+
"""
|
2
|
+
Backend using numpy and pyFFTW for template matching.
|
2
3
|
|
3
|
-
|
4
|
+
Copyright (c) 2023 European Molecular Biology Laboratory
|
4
5
|
|
5
|
-
|
6
|
+
Author: Valentin Maurer <valentin.maurer@embl-hamburg.de>
|
6
7
|
"""
|
7
8
|
|
8
9
|
import os
|
@@ -159,8 +160,9 @@ class NumpyFFTWBackend(_NumpyWrapper, MatchingBackend):
|
|
159
160
|
temp = self._array_backend.zeros(1, dtype=dtype)
|
160
161
|
return temp.nbytes
|
161
162
|
|
162
|
-
|
163
|
-
|
163
|
+
def astype(self, arr, dtype: Type) -> NDArray:
|
164
|
+
if self._array_backend.iscomplexobj(arr):
|
165
|
+
arr = arr.real
|
164
166
|
return arr.astype(dtype)
|
165
167
|
|
166
168
|
@staticmethod
|
tme/backends/pytorch_backend.py
CHANGED
@@ -1,9 +1,10 @@
|
|
1
|
-
"""
|
2
|
-
|
1
|
+
"""
|
2
|
+
Backend using pytorch and optionally GPU acceleration for
|
3
|
+
template matching.
|
3
4
|
|
4
|
-
|
5
|
+
Copyright (c) 2023 European Molecular Biology Laboratory
|
5
6
|
|
6
|
-
|
7
|
+
Author: Valentin Maurer <valentin.maurer@embl-hamburg.de>
|
7
8
|
"""
|
8
9
|
|
9
10
|
from typing import Tuple, Callable
|
@@ -134,6 +135,15 @@ class PytorchBackend(NumpyFFTWBackend):
|
|
134
135
|
def astype(self, arr: TorchTensor, dtype: type) -> TorchTensor:
|
135
136
|
return arr.to(dtype)
|
136
137
|
|
138
|
+
@staticmethod
|
139
|
+
def at(arr, idx, value) -> NDArray:
|
140
|
+
arr[idx] = value
|
141
|
+
return arr
|
142
|
+
|
143
|
+
@staticmethod
|
144
|
+
def addat(arr, indices, *args, **kwargs) -> NDArray:
|
145
|
+
return arr.index_put_(indices, *args, accumulate=True, **kwargs)
|
146
|
+
|
137
147
|
def flip(self, a, axis, **kwargs):
|
138
148
|
return self._array_backend.flip(input=a, dims=axis, **kwargs)
|
139
149
|
|
tme/cli.py
ADDED
@@ -0,0 +1,126 @@
|
|
1
|
+
#!python3
|
2
|
+
"""
|
3
|
+
CLI utility functions.
|
4
|
+
|
5
|
+
Copyright (c) 2025 European Molecular Biology Laboratory
|
6
|
+
|
7
|
+
Author: Valentin Maurer <valentin.maurer@embl-hamburg.de>
|
8
|
+
"""
|
9
|
+
|
10
|
+
import argparse
|
11
|
+
|
12
|
+
import numpy as np
|
13
|
+
from . import __version__
|
14
|
+
from .types import BackendArray
|
15
|
+
|
16
|
+
|
17
|
+
def match_template(
|
18
|
+
target: BackendArray,
|
19
|
+
template: BackendArray,
|
20
|
+
template_mask: BackendArray = None,
|
21
|
+
score="FLCSphericalMask",
|
22
|
+
rotations=None,
|
23
|
+
):
|
24
|
+
"""
|
25
|
+
Simple template matching run.
|
26
|
+
|
27
|
+
Parameters
|
28
|
+
----------
|
29
|
+
target : BackendArray
|
30
|
+
Target array.
|
31
|
+
template : BackendArray
|
32
|
+
Template to be matched against target.
|
33
|
+
template_mask : BackendArray, optional
|
34
|
+
Template mask for normalization, defaults to None.
|
35
|
+
score : str, optional
|
36
|
+
Scoring method to use, defaults to 'FLCSphericalMask'.
|
37
|
+
rotations: BackendArray, optional
|
38
|
+
Rotation matrices with shape (n, d, d), where d is the dimension
|
39
|
+
of the target. Defaults to the identity rotation matrix.
|
40
|
+
|
41
|
+
Returns
|
42
|
+
-------
|
43
|
+
tuple
|
44
|
+
scores : BackendArray
|
45
|
+
Computed cross-correlation scores.
|
46
|
+
offset : BackendArray
|
47
|
+
Offset in target, defaults to 0.
|
48
|
+
rotations : BackendArray
|
49
|
+
Map between translations and rotation indices
|
50
|
+
rotation_mapping : dict
|
51
|
+
Map between rotation indices and rotation matrices
|
52
|
+
"""
|
53
|
+
from .matching_data import MatchingData
|
54
|
+
from .analyzer import MaxScoreOverRotations
|
55
|
+
from .matching_exhaustive import scan_subsets, MATCHING_EXHAUSTIVE_REGISTER
|
56
|
+
|
57
|
+
if rotations is None:
|
58
|
+
rotations = np.eye(target.ndim).reshape(1, target.ndim, target.ndim)
|
59
|
+
|
60
|
+
if rotations.shape[-1] != target.ndim:
|
61
|
+
print(
|
62
|
+
f"Dimension of rotation matrix {rotations.shape[-1]} does not "
|
63
|
+
"match target dimension."
|
64
|
+
)
|
65
|
+
|
66
|
+
matching_data = MatchingData(
|
67
|
+
target=target,
|
68
|
+
template=template,
|
69
|
+
template_mask=template_mask,
|
70
|
+
rotations=rotations,
|
71
|
+
)
|
72
|
+
matching_data.template_mask = template_mask
|
73
|
+
matching_setup, matching_score = MATCHING_EXHAUSTIVE_REGISTER[score]
|
74
|
+
|
75
|
+
candidates = list(
|
76
|
+
scan_subsets(
|
77
|
+
matching_data=matching_data,
|
78
|
+
matching_score=matching_score,
|
79
|
+
matching_setup=matching_setup,
|
80
|
+
callback_class=MaxScoreOverRotations,
|
81
|
+
callback_class_args={
|
82
|
+
"score_threshold": -1,
|
83
|
+
},
|
84
|
+
pad_target_edges=True,
|
85
|
+
job_schedule=(1, 1),
|
86
|
+
)
|
87
|
+
)
|
88
|
+
return candidates
|
89
|
+
|
90
|
+
|
91
|
+
def sanitize_name(name: str):
|
92
|
+
return name.title().replace("_", " ").replace("-", " ")
|
93
|
+
|
94
|
+
|
95
|
+
def print_entry() -> None:
|
96
|
+
width = 80
|
97
|
+
text = f" pytme v{__version__} "
|
98
|
+
padding_total = width - len(text) - 2
|
99
|
+
padding_left = padding_total // 2
|
100
|
+
padding_right = padding_total - padding_left
|
101
|
+
|
102
|
+
print("*" * width)
|
103
|
+
print(f"*{ ' ' * padding_left }{text}{ ' ' * padding_right }*")
|
104
|
+
print("*" * width)
|
105
|
+
|
106
|
+
|
107
|
+
def get_func_fullname(func) -> str:
|
108
|
+
"""Returns the full name of the given function, including its module."""
|
109
|
+
return f"<function '{func.__module__}.{func.__name__}'>"
|
110
|
+
|
111
|
+
|
112
|
+
def print_block(name: str, data: dict, label_width=20) -> None:
|
113
|
+
"""Prints a formatted block of information."""
|
114
|
+
print(f"\n> {name}")
|
115
|
+
for key, value in data.items():
|
116
|
+
if isinstance(value, np.ndarray):
|
117
|
+
value = value.shape
|
118
|
+
formatted_value = str(value)
|
119
|
+
print(f" - {str(key) + ':':<{label_width}} {formatted_value}")
|
120
|
+
|
121
|
+
|
122
|
+
def check_positive(value):
|
123
|
+
ivalue = float(value)
|
124
|
+
if ivalue <= 0:
|
125
|
+
raise argparse.ArgumentTypeError("%s is an invalid positive float." % value)
|
126
|
+
return ivalue
|
tme/density.py
CHANGED
@@ -1,8 +1,9 @@
|
|
1
|
-
"""
|
1
|
+
"""
|
2
|
+
Representation of N-dimensional densities
|
2
3
|
|
3
|
-
|
4
|
+
Copyright (c) 2023 European Molecular Biology Laboratory
|
4
5
|
|
5
|
-
|
6
|
+
Author: Valentin Maurer <valentin.maurer@embl-hamburg.de>
|
6
7
|
"""
|
7
8
|
|
8
9
|
import warnings
|
tme/filters/__init__.py
CHANGED
tme/filters/_utils.py
CHANGED
@@ -1,8 +1,9 @@
|
|
1
|
-
"""
|
1
|
+
"""
|
2
|
+
Utilities for the generation of frequency grids.
|
2
3
|
|
3
|
-
|
4
|
+
Copyright (c) 2024 European Molecular Biology Laboratory
|
4
5
|
|
5
|
-
|
6
|
+
Author: Valentin Maurer <valentin.maurer@embl-hamburg.de>
|
6
7
|
"""
|
7
8
|
|
8
9
|
from typing import Tuple, List, Dict
|
tme/filters/bandpass.py
CHANGED
@@ -1,8 +1,9 @@
|
|
1
|
-
"""
|
1
|
+
"""
|
2
|
+
Implements class BandPassFilter to create Fourier filter representations.
|
2
3
|
|
3
|
-
|
4
|
+
Copyright (c) 2024 European Molecular Biology Laboratory
|
4
5
|
|
5
|
-
|
6
|
+
Author: Valentin Maurer <valentin.maurer@embl-hamburg.de>
|
6
7
|
"""
|
7
8
|
|
8
9
|
from typing import Tuple
|
@@ -225,6 +226,7 @@ class BandPassFilter(ComposableFilter):
|
|
225
226
|
|
226
227
|
return {
|
227
228
|
"data": be.to_backend_array(mask),
|
228
|
-
"
|
229
|
+
"shape": func_args["shape"],
|
230
|
+
"return_real_fourier": func_args.get("return_real_fourier"),
|
229
231
|
"is_multiplicative_filter": True,
|
230
232
|
}
|
tme/filters/compose.py
CHANGED
@@ -1,8 +1,9 @@
|
|
1
|
-
"""
|
1
|
+
"""
|
2
|
+
Combine filters using an interface analogous to pytorch's Compose.
|
2
3
|
|
3
|
-
|
4
|
+
Copyright (c) 2024 European Molecular Biology Laboratory
|
4
5
|
|
5
|
-
|
6
|
+
Author: Valentin Maurer <valentin.maurer@embl-hamburg.de>
|
6
7
|
"""
|
7
8
|
|
8
9
|
from typing import Tuple, Dict
|
@@ -60,7 +61,7 @@ class Compose:
|
|
60
61
|
|
61
62
|
class ComposableFilter(ABC):
|
62
63
|
"""
|
63
|
-
|
64
|
+
Base class for composable filters.
|
64
65
|
"""
|
65
66
|
|
66
67
|
@abstractmethod
|