pytme 0.1.8__cp311-cp311-macosx_14_0_arm64.whl → 0.2.0b0__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.8.data → pytme-0.2.0b0.data}/scripts/match_template.py +148 -126
- pytme-0.2.0b0.data/scripts/postprocess.py +570 -0
- {pytme-0.1.8.data → pytme-0.2.0b0.data}/scripts/preprocessor_gui.py +244 -60
- {pytme-0.1.8.dist-info → pytme-0.2.0b0.dist-info}/METADATA +3 -1
- pytme-0.2.0b0.dist-info/RECORD +66 -0
- {pytme-0.1.8.dist-info → pytme-0.2.0b0.dist-info}/WHEEL +1 -1
- scripts/extract_candidates.py +218 -0
- scripts/match_template.py +148 -126
- scripts/match_template_filters.py +852 -0
- scripts/postprocess.py +380 -435
- scripts/preprocessor_gui.py +244 -60
- scripts/refine_matches.py +218 -0
- tme/__init__.py +2 -1
- tme/__version__.py +1 -1
- tme/analyzer.py +545 -78
- tme/backends/cupy_backend.py +80 -15
- tme/backends/npfftw_backend.py +33 -2
- tme/backends/pytorch_backend.py +15 -7
- tme/density.py +156 -63
- tme/extensions.cpython-311-darwin.so +0 -0
- tme/matching_constrained.py +195 -0
- tme/matching_data.py +76 -32
- tme/matching_exhaustive.py +366 -204
- tme/matching_memory.py +1 -0
- tme/matching_optimization.py +728 -651
- tme/matching_utils.py +152 -8
- tme/orientations.py +561 -0
- tme/preprocessor.py +21 -18
- tme/structure.py +2 -37
- pytme-0.1.8.data/scripts/postprocess.py +0 -625
- pytme-0.1.8.dist-info/RECORD +0 -61
- {pytme-0.1.8.data → pytme-0.2.0b0.data}/scripts/estimate_ram_usage.py +0 -0
- {pytme-0.1.8.data → pytme-0.2.0b0.data}/scripts/preprocess.py +0 -0
- {pytme-0.1.8.dist-info → pytme-0.2.0b0.dist-info}/LICENSE +0 -0
- {pytme-0.1.8.dist-info → pytme-0.2.0b0.dist-info}/entry_points.txt +0 -0
- {pytme-0.1.8.dist-info → pytme-0.2.0b0.dist-info}/top_level.txt +0 -0
tme/backends/cupy_backend.py
CHANGED
@@ -16,6 +16,8 @@ from numpy.typing import NDArray
|
|
16
16
|
from .npfftw_backend import NumpyFFTWBackend
|
17
17
|
from ..types import CupyArray
|
18
18
|
|
19
|
+
PLAN_CACHE = {}
|
20
|
+
|
19
21
|
|
20
22
|
class CupyBackend(NumpyFFTWBackend):
|
21
23
|
"""
|
@@ -44,6 +46,15 @@ class CupyBackend(NumpyFFTWBackend):
|
|
44
46
|
self.affine_transform = affine_transform
|
45
47
|
self.maximum_filter = maximum_filter
|
46
48
|
|
49
|
+
floating = f"float{self.datatype_bytes(default_dtype) * 8}"
|
50
|
+
integer = f"int{self.datatype_bytes(default_dtype_int) * 8}"
|
51
|
+
self._max_score_over_rotations = self._array_backend.ElementwiseKernel(
|
52
|
+
f"{floating} internal_scores, {floating} scores, {integer} rot_index",
|
53
|
+
f"{floating} out1, {integer} rotations",
|
54
|
+
"if (internal_scores < scores) {out1 = scores; rotations = rot_index;}",
|
55
|
+
"max_score_over_rotations",
|
56
|
+
)
|
57
|
+
|
47
58
|
def to_backend_array(self, arr: NDArray) -> CupyArray:
|
48
59
|
current_device = self._array_backend.cuda.device.get_device_id()
|
49
60
|
if (
|
@@ -60,7 +71,7 @@ class CupyBackend(NumpyFFTWBackend):
|
|
60
71
|
return self.to_numpy_array(arr)
|
61
72
|
|
62
73
|
def sharedarr_to_arr(
|
63
|
-
self, shape: Tuple[int], dtype: str
|
74
|
+
self, shm: CupyArray, shape: Tuple[int], dtype: str
|
64
75
|
) -> CupyArray:
|
65
76
|
return shm
|
66
77
|
|
@@ -109,8 +120,8 @@ class CupyBackend(NumpyFFTWBackend):
|
|
109
120
|
real_dtype: type,
|
110
121
|
complex_dtype: type,
|
111
122
|
fftargs: Dict = {},
|
112
|
-
|
113
|
-
|
123
|
+
inverse_fast_shape: Tuple[int] = None,
|
124
|
+
**kwargs,
|
114
125
|
) -> Tuple[Callable, Callable]:
|
115
126
|
"""
|
116
127
|
Build pyFFTW builder functions.
|
@@ -119,41 +130,54 @@ class CupyBackend(NumpyFFTWBackend):
|
|
119
130
|
----------
|
120
131
|
fast_shape : tuple
|
121
132
|
Tuple of integers corresponding to fast convolution shape
|
122
|
-
(see
|
133
|
+
(see :py:meth:`CupyBackend.compute_convolution_shapes`).
|
123
134
|
fast_ft_shape : tuple
|
124
135
|
Tuple of integers corresponding to the shape of the fourier
|
125
|
-
transform array (see
|
136
|
+
transform array (see :py:meth:`CupyBackend.compute_convolution_shapes`).
|
126
137
|
real_dtype : dtype
|
127
138
|
Numpy dtype of the inverse fourier transform.
|
128
139
|
complex_dtype : dtype
|
129
140
|
Numpy dtype of the fourier transform.
|
141
|
+
inverse_fast_shape : tuple, optional
|
142
|
+
Output shape of the inverse Fourier transform. By default fast_shape.
|
130
143
|
fftargs : dict, optional
|
131
144
|
Dictionary passed to pyFFTW builders.
|
132
|
-
|
133
|
-
|
134
|
-
temp_fft : NDArray, optional
|
135
|
-
Temporary fft numpy array, by default None.
|
145
|
+
**kwargs: dict, optional
|
146
|
+
Unused keyword arguments.
|
136
147
|
|
137
148
|
Returns
|
138
149
|
-------
|
139
150
|
tuple
|
140
151
|
Tupple containing callable rfft and irfft object.
|
141
152
|
"""
|
142
|
-
|
143
|
-
if temp_real is None:
|
144
|
-
temp_real = self.preallocate_array(fast_shape, real_dtype)
|
145
|
-
if temp_fft is None:
|
146
|
-
temp_fft = self.preallocate_array(fast_ft_shape, complex_dtype)
|
147
|
-
|
148
153
|
cache = self._array_backend.fft.config.get_plan_cache()
|
149
154
|
cache.set_size(2)
|
150
155
|
|
156
|
+
current_device = self._array_backend.cuda.device.get_device_id()
|
157
|
+
|
158
|
+
previous_transform = [fast_shape, fast_ft_shape]
|
159
|
+
if current_device in PLAN_CACHE:
|
160
|
+
previous_transform = PLAN_CACHE[current_device]
|
161
|
+
|
162
|
+
real_diff, cmplx_diff = True, True
|
163
|
+
if len(fast_shape) == len(previous_transform[0]):
|
164
|
+
real_diff = self.sum(self.subtract(fast_shape, previous_transform[0])) != 0
|
165
|
+
if len(fast_ft_shape) == len(previous_transform[1]):
|
166
|
+
cmplx_diff = (
|
167
|
+
self.sum(self.subtract(fast_ft_shape, previous_transform[1])) != 0
|
168
|
+
)
|
169
|
+
|
170
|
+
if real_diff or cmplx_diff:
|
171
|
+
cache.clear()
|
172
|
+
|
151
173
|
def rfftn(arr: CupyArray, out: CupyArray) -> None:
|
152
174
|
out[:] = self.fft.rfftn(arr)[:]
|
153
175
|
|
154
176
|
def irfftn(arr: CupyArray, out: CupyArray) -> None:
|
155
177
|
out[:] = self.fft.irfftn(arr)[:]
|
156
178
|
|
179
|
+
PLAN_CACHE[current_device] = [fast_shape, fast_ft_shape]
|
180
|
+
|
157
181
|
return rfftn, irfftn
|
158
182
|
|
159
183
|
def compute_convolution_shapes(
|
@@ -177,6 +201,17 @@ class CupyBackend(NumpyFFTWBackend):
|
|
177
201
|
peaks = self._array_backend.array(self._array_backend.nonzero(max_filter)).T
|
178
202
|
return peaks
|
179
203
|
|
204
|
+
# The default methods in Cupy were oddly slow
|
205
|
+
def var(self, a, *args, **kwargs):
|
206
|
+
out = a - self._array_backend.mean(a, *args, **kwargs)
|
207
|
+
self._array_backend.square(out, out)
|
208
|
+
out = self._array_backend.mean(out, *args, **kwargs)
|
209
|
+
return out
|
210
|
+
|
211
|
+
def std(self, a, *args, **kwargs):
|
212
|
+
out = self.var(a, *args, **kwargs)
|
213
|
+
return self._array_backend.sqrt(out)
|
214
|
+
|
180
215
|
def rotate_array(
|
181
216
|
self,
|
182
217
|
arr: CupyArray,
|
@@ -311,3 +346,33 @@ class CupyBackend(NumpyFFTWBackend):
|
|
311
346
|
Number of available GPU devices.
|
312
347
|
"""
|
313
348
|
return self._array_backend.cuda.runtime.getDeviceCount()
|
349
|
+
|
350
|
+
def max_score_over_rotations(
|
351
|
+
self,
|
352
|
+
score_space: CupyArray,
|
353
|
+
internal_scores: CupyArray,
|
354
|
+
internal_rotations: CupyArray,
|
355
|
+
rotation_index: int,
|
356
|
+
):
|
357
|
+
"""
|
358
|
+
Modify internal_scores and internal_rotations inplace with scores and rotation
|
359
|
+
index respectively, wherever score_sapce is larger than internal scores.
|
360
|
+
|
361
|
+
Parameters
|
362
|
+
----------
|
363
|
+
score_space : CupyArray
|
364
|
+
The score space to compare against internal_scores.
|
365
|
+
internal_scores : CupyArray
|
366
|
+
The internal scores to update with maximum scores.
|
367
|
+
internal_rotations : CupyArray
|
368
|
+
The internal rotations corresponding to the maximum scores.
|
369
|
+
rotation_index : int
|
370
|
+
The index representing the current rotation.
|
371
|
+
"""
|
372
|
+
self._max_score_over_rotations(
|
373
|
+
internal_scores,
|
374
|
+
score_space,
|
375
|
+
rotation_index,
|
376
|
+
internal_scores,
|
377
|
+
internal_rotations,
|
378
|
+
)
|
tme/backends/npfftw_backend.py
CHANGED
@@ -256,7 +256,7 @@ class NumpyFFTWBackend(MatchingBackend):
|
|
256
256
|
return arr
|
257
257
|
|
258
258
|
def sharedarr_to_arr(
|
259
|
-
self, shape: Tuple[int], dtype: str
|
259
|
+
self, shm: shared_memory.SharedMemory, shape: Tuple[int], dtype: str
|
260
260
|
) -> NDArray:
|
261
261
|
"""
|
262
262
|
Returns an array of given shape and dtype from shared memory location.
|
@@ -341,6 +341,7 @@ class NumpyFFTWBackend(MatchingBackend):
|
|
341
341
|
real_dtype: type,
|
342
342
|
complex_dtype: type,
|
343
343
|
fftargs: Dict = {},
|
344
|
+
inverse_fast_shape: Tuple[int] = None,
|
344
345
|
temp_real: NDArray = None,
|
345
346
|
temp_fft: NDArray = None,
|
346
347
|
) -> Tuple[FFTW, FFTW]:
|
@@ -359,6 +360,8 @@ class NumpyFFTWBackend(MatchingBackend):
|
|
359
360
|
Numpy dtype of the inverse fourier transform.
|
360
361
|
complex_dtype : dtype
|
361
362
|
Numpy dtype of the fourier transform.
|
363
|
+
inverse_fast_shape : tuple, optional
|
364
|
+
Output shape of the inverse Fourier transform. By default fast_shape.
|
362
365
|
fftargs : dict, optional
|
363
366
|
Dictionary passed to pyFFTW builders.
|
364
367
|
temp_real : NDArray, optional
|
@@ -376,6 +379,8 @@ class NumpyFFTWBackend(MatchingBackend):
|
|
376
379
|
temp_real = self.preallocate_array(fast_shape, real_dtype)
|
377
380
|
if temp_fft is None:
|
378
381
|
temp_fft = self.preallocate_array(fast_ft_shape, complex_dtype)
|
382
|
+
if inverse_fast_shape is None:
|
383
|
+
inverse_fast_shape = fast_shape
|
379
384
|
|
380
385
|
default_values = {
|
381
386
|
"planner_effort": "FFTW_MEASURE",
|
@@ -395,7 +400,7 @@ class NumpyFFTWBackend(MatchingBackend):
|
|
395
400
|
overwrite_input = None
|
396
401
|
if "overwrite_input" in fftargs:
|
397
402
|
overwrite_input = fftargs.pop("overwrite_input")
|
398
|
-
irfftn = irfftn_builder(temp_fft, s=
|
403
|
+
irfftn = irfftn_builder(temp_fft, s=inverse_fast_shape, **fftargs)
|
399
404
|
|
400
405
|
if overwrite_input is not None:
|
401
406
|
fftargs["overwrite_input"] = overwrite_input
|
@@ -756,3 +761,29 @@ class NumpyFFTWBackend(MatchingBackend):
|
|
756
761
|
Reversed array.
|
757
762
|
"""
|
758
763
|
return arr[(slice(None, None, -1),) * arr.ndim]
|
764
|
+
|
765
|
+
def max_score_over_rotations(
|
766
|
+
self,
|
767
|
+
score_space: NDArray,
|
768
|
+
internal_scores: NDArray,
|
769
|
+
internal_rotations: NDArray,
|
770
|
+
rotation_index: int,
|
771
|
+
) -> None:
|
772
|
+
"""
|
773
|
+
Modify internal_scores and internal_rotations inplace with scores and rotation
|
774
|
+
index respectively, wherever score_sapce is larger than internal scores.
|
775
|
+
|
776
|
+
Parameters
|
777
|
+
----------
|
778
|
+
score_space : numpy.ndarray
|
779
|
+
The score space to compare against internal_scores.
|
780
|
+
internal_scores : numpy.ndarray
|
781
|
+
The internal scores to update with maximum scores.
|
782
|
+
internal_rotations : numpy.ndarray
|
783
|
+
The internal rotations corresponding to the maximum scores.
|
784
|
+
rotation_index : int
|
785
|
+
The index representing the current rotation.
|
786
|
+
"""
|
787
|
+
indices = score_space > internal_scores
|
788
|
+
internal_scores[indices] = score_space[indices]
|
789
|
+
internal_rotations[indices] = rotation_index
|
tme/backends/pytorch_backend.py
CHANGED
@@ -237,7 +237,7 @@ class PytorchBackend(NumpyFFTWBackend):
|
|
237
237
|
return self._array_backend.repeat_interleave(*args, **kwargs)
|
238
238
|
|
239
239
|
def sharedarr_to_arr(
|
240
|
-
self, shape: Tuple[int], dtype: str
|
240
|
+
self, shm: TorchTensor, shape: Tuple[int], dtype: str
|
241
241
|
) -> TorchTensor:
|
242
242
|
if self.device == "cuda":
|
243
243
|
return shm
|
@@ -385,7 +385,11 @@ class PytorchBackend(NumpyFFTWBackend):
|
|
385
385
|
return out, out_mask
|
386
386
|
|
387
387
|
def build_fft(
|
388
|
-
self,
|
388
|
+
self,
|
389
|
+
fast_shape: Tuple[int],
|
390
|
+
fast_ft_shape: Tuple[int],
|
391
|
+
inverse_fast_shape: Tuple[int] = None,
|
392
|
+
**kwargs,
|
389
393
|
) -> Tuple[Callable, Callable]:
|
390
394
|
"""
|
391
395
|
Build fft builder functions.
|
@@ -394,18 +398,22 @@ class PytorchBackend(NumpyFFTWBackend):
|
|
394
398
|
----------
|
395
399
|
fast_shape : tuple
|
396
400
|
Tuple of integers corresponding to fast convolution shape
|
397
|
-
(see
|
401
|
+
(see :py:meth:`PytorchBackend.compute_convolution_shapes`).
|
398
402
|
fast_ft_shape : tuple
|
399
|
-
Tuple of integers corresponding to the shape of the
|
400
|
-
transform array (see
|
403
|
+
Tuple of integers corresponding to the shape of the Fourier
|
404
|
+
transform array (see :py:meth:`PytorchBackend.compute_convolution_shapes`).
|
405
|
+
inverse_fast_shape : tuple, optional
|
406
|
+
Output shape of the inverse Fourier transform. By default fast_shape.
|
401
407
|
**kwargs : dict, optional
|
402
|
-
|
408
|
+
Unused keyword arguments.
|
403
409
|
|
404
410
|
Returns
|
405
411
|
-------
|
406
412
|
tuple
|
407
413
|
Tupple containing callable rfft and irfft object.
|
408
414
|
"""
|
415
|
+
if inverse_fast_shape is None:
|
416
|
+
inverse_fast_shape = fast_shape
|
409
417
|
|
410
418
|
def rfftn(
|
411
419
|
arr: TorchTensor, out: TorchTensor, shape: Tuple[int] = fast_shape
|
@@ -413,7 +421,7 @@ class PytorchBackend(NumpyFFTWBackend):
|
|
413
421
|
return self._array_backend.fft.rfftn(arr, s=shape, out=out)
|
414
422
|
|
415
423
|
def irfftn(
|
416
|
-
arr: TorchTensor, out: TorchTensor, shape: Tuple[int] =
|
424
|
+
arr: TorchTensor, out: TorchTensor, shape: Tuple[int] = inverse_fast_shape
|
417
425
|
) -> None:
|
418
426
|
return self._array_backend.fft.irfftn(arr, s=shape, out=out)
|
419
427
|
|