pytme 0.2.0b0__cp311-cp311-macosx_14_0_arm64.whl → 0.2.2__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.
Files changed (52) hide show
  1. pytme-0.2.2.data/scripts/match_template.py +1187 -0
  2. {pytme-0.2.0b0.data → pytme-0.2.2.data}/scripts/postprocess.py +170 -71
  3. {pytme-0.2.0b0.data → pytme-0.2.2.data}/scripts/preprocessor_gui.py +179 -86
  4. pytme-0.2.2.dist-info/METADATA +91 -0
  5. pytme-0.2.2.dist-info/RECORD +74 -0
  6. {pytme-0.2.0b0.dist-info → pytme-0.2.2.dist-info}/WHEEL +1 -1
  7. scripts/extract_candidates.py +126 -87
  8. scripts/match_template.py +596 -209
  9. scripts/match_template_filters.py +571 -223
  10. scripts/postprocess.py +170 -71
  11. scripts/preprocessor_gui.py +179 -86
  12. scripts/refine_matches.py +567 -159
  13. tme/__init__.py +0 -1
  14. tme/__version__.py +1 -1
  15. tme/analyzer.py +627 -855
  16. tme/backends/__init__.py +41 -11
  17. tme/backends/_jax_utils.py +185 -0
  18. tme/backends/cupy_backend.py +120 -225
  19. tme/backends/jax_backend.py +282 -0
  20. tme/backends/matching_backend.py +464 -388
  21. tme/backends/mlx_backend.py +45 -68
  22. tme/backends/npfftw_backend.py +256 -514
  23. tme/backends/pytorch_backend.py +41 -154
  24. tme/density.py +312 -421
  25. tme/extensions.cpython-311-darwin.so +0 -0
  26. tme/matching_data.py +366 -303
  27. tme/matching_exhaustive.py +279 -1521
  28. tme/matching_optimization.py +234 -129
  29. tme/matching_scores.py +884 -0
  30. tme/matching_utils.py +281 -387
  31. tme/memory.py +377 -0
  32. tme/orientations.py +226 -66
  33. tme/parser.py +3 -4
  34. tme/preprocessing/__init__.py +2 -0
  35. tme/preprocessing/_utils.py +217 -0
  36. tme/preprocessing/composable_filter.py +31 -0
  37. tme/preprocessing/compose.py +55 -0
  38. tme/preprocessing/frequency_filters.py +388 -0
  39. tme/preprocessing/tilt_series.py +1011 -0
  40. tme/preprocessor.py +574 -530
  41. tme/structure.py +495 -189
  42. tme/types.py +5 -3
  43. pytme-0.2.0b0.data/scripts/match_template.py +0 -800
  44. pytme-0.2.0b0.dist-info/METADATA +0 -73
  45. pytme-0.2.0b0.dist-info/RECORD +0 -66
  46. tme/helpers.py +0 -881
  47. tme/matching_constrained.py +0 -195
  48. {pytme-0.2.0b0.data → pytme-0.2.2.data}/scripts/estimate_ram_usage.py +0 -0
  49. {pytme-0.2.0b0.data → pytme-0.2.2.data}/scripts/preprocess.py +0 -0
  50. {pytme-0.2.0b0.dist-info → pytme-0.2.2.dist-info}/LICENSE +0 -0
  51. {pytme-0.2.0b0.dist-info → pytme-0.2.2.dist-info}/entry_points.txt +0 -0
  52. {pytme-0.2.0b0.dist-info → pytme-0.2.2.dist-info}/top_level.txt +0 -0
tme/memory.py ADDED
@@ -0,0 +1,377 @@
1
+ """ Compute memory consumption of template matching components.
2
+
3
+ Copyright (c) 2023 European Molecular Biology Laboratory
4
+
5
+ Author: Valentin Maurer <valentin.maurer@embl-hamburg.de>
6
+ """
7
+
8
+ from abc import ABC, abstractmethod
9
+ from typing import Tuple
10
+
11
+ import numpy as np
12
+ from pyfftw import next_fast_len
13
+
14
+
15
+ class MatchingMemoryUsage(ABC):
16
+ """
17
+ Class specification for estimating the memory requirements of template matching.
18
+
19
+ Parameters
20
+ ----------
21
+ fast_shape : tuple of int
22
+ Shape of the real array.
23
+ ft_shape : tuple of int
24
+ Shape of the complex array.
25
+ float_nbytes : int
26
+ Number of bytes of the used float, e.g. 4 for float32.
27
+ complex_nbytes : int
28
+ Number of bytes of the used complex, e.g. 8 for complex64.
29
+ integer_nbytes : int
30
+ Number of bytes of the used integer, e.g. 4 for int32.
31
+
32
+ Attributes
33
+ ----------
34
+ real_array_size : int
35
+ Number of elements in real array.
36
+ complex_array_size : int
37
+ Number of elements in complex array.
38
+ float_nbytes : int
39
+ Number of bytes of the used float, e.g. 4 for float32.
40
+ complex_nbytes : int
41
+ Number of bytes of the used complex, e.g. 8 for complex64.
42
+ integer_nbytes : int
43
+ Number of bytes of the used integer, e.g. 4 for int32.
44
+
45
+ Methods
46
+ -------
47
+ base_usage():
48
+ Returns the base memory usage in bytes.
49
+ per_fork():
50
+ Returns the memory usage in bytes per fork.
51
+ """
52
+
53
+ def __init__(
54
+ self,
55
+ fast_shape: Tuple[int],
56
+ ft_shape: Tuple[int],
57
+ float_nbytes: int,
58
+ complex_nbytes: int,
59
+ integer_nbytes: int,
60
+ ):
61
+ self.real_array_size = np.prod(fast_shape)
62
+ self.complex_array_size = np.prod(ft_shape)
63
+ self.float_nbytes = float_nbytes
64
+ self.complex_nbytes = complex_nbytes
65
+ self.integer_nbytes = integer_nbytes
66
+
67
+ @abstractmethod
68
+ def base_usage(self) -> int:
69
+ """Return the base memory usage in bytes."""
70
+
71
+ @abstractmethod
72
+ def per_fork(self) -> int:
73
+ """Return the memory usage per fork in bytes."""
74
+
75
+
76
+ class CCMemoryUsage(MatchingMemoryUsage):
77
+ """
78
+ Memory usage estimation for CC scoring.
79
+
80
+ See Also
81
+ --------
82
+ :py:meth:`tme.matching_exhaustive.cc_setup`.
83
+ """
84
+
85
+ def base_usage(self) -> int:
86
+ float_arrays = self.real_array_size * self.float_nbytes
87
+ complex_arrays = self.complex_array_size * self.complex_nbytes
88
+ return float_arrays + complex_arrays
89
+
90
+ def per_fork(self) -> int:
91
+ float_arrays = self.real_array_size * self.float_nbytes
92
+ complex_arrays = self.complex_array_size * self.complex_nbytes
93
+ return float_arrays + complex_arrays
94
+
95
+
96
+ class LCCMemoryUsage(CCMemoryUsage):
97
+ """
98
+ Memory usage estimation for LCC scoring.
99
+ See Also
100
+ --------
101
+ :py:meth:`tme.matching_exhaustive.lcc_setup`.
102
+ """
103
+
104
+
105
+ class CORRMemoryUsage(MatchingMemoryUsage):
106
+ """
107
+ Memory usage estimation for CORR scoring.
108
+
109
+ See Also
110
+ --------
111
+ :py:meth:`tme.matching_exhaustive.corr_setup`.
112
+ """
113
+
114
+ def base_usage(self) -> int:
115
+ float_arrays = self.real_array_size * self.float_nbytes * 4
116
+ complex_arrays = self.complex_array_size * self.complex_nbytes
117
+ return float_arrays + complex_arrays
118
+
119
+ def per_fork(self) -> int:
120
+ float_arrays = self.real_array_size * self.float_nbytes
121
+ complex_arrays = self.complex_array_size * self.complex_nbytes
122
+ return float_arrays + complex_arrays
123
+
124
+
125
+ class CAMMemoryUsage(CORRMemoryUsage):
126
+ """
127
+ Memory usage estimation for CAM scoring.
128
+
129
+ See Also
130
+ --------
131
+ :py:meth:`tme.matching_exhaustive.cam_setup`.
132
+ """
133
+
134
+
135
+ class FLCSphericalMaskMemoryUsage(CORRMemoryUsage):
136
+ """
137
+ Memory usage estimation for FLCMSphericalMask scoring.
138
+
139
+ See Also
140
+ --------
141
+ :py:meth:`tme.matching_exhaustive.flcSphericalMask_setup`.
142
+ """
143
+
144
+
145
+ class FLCMemoryUsage(MatchingMemoryUsage):
146
+ """
147
+ Memory usage estimation for FLC scoring.
148
+
149
+ See Also
150
+ --------
151
+ :py:meth:`tme.matching_exhaustive.flc_setup`.
152
+ """
153
+
154
+ def base_usage(self) -> int:
155
+ float_arrays = self.real_array_size * self.float_nbytes * 2
156
+ complex_arrays = self.complex_array_size * self.complex_nbytes * 2
157
+ return float_arrays + complex_arrays
158
+
159
+ def per_fork(self) -> int:
160
+ float_arrays = self.real_array_size * self.float_nbytes * 3
161
+ complex_arrays = self.complex_array_size * self.complex_nbytes * 2
162
+ return float_arrays + complex_arrays
163
+
164
+
165
+ class MCCMemoryUsage(MatchingMemoryUsage):
166
+ """
167
+ Memory usage estimation for MCC scoring.
168
+
169
+ See Also
170
+ --------
171
+ :py:meth:`tme.matching_exhaustive.mcc_setup`.
172
+ """
173
+
174
+ def base_usage(self) -> int:
175
+ float_arrays = self.real_array_size * self.float_nbytes * 2
176
+ complex_arrays = self.complex_array_size * self.complex_nbytes * 3
177
+ return float_arrays + complex_arrays
178
+
179
+ def per_fork(self) -> int:
180
+ float_arrays = self.real_array_size * self.float_nbytes * 6
181
+ complex_arrays = self.complex_array_size * self.complex_nbytes
182
+ return float_arrays + complex_arrays
183
+
184
+
185
+ class MaxScoreOverRotationsMemoryUsage(MatchingMemoryUsage):
186
+ """
187
+ Memory usage estimation MaxScoreOverRotations Analyzer.
188
+
189
+ See Also
190
+ --------
191
+ :py:class:`tme.analyzer.MaxScoreOverRotations`.
192
+ """
193
+
194
+ def base_usage(self) -> int:
195
+ float_arrays = self.real_array_size * self.float_nbytes * 2
196
+ return float_arrays
197
+
198
+ def per_fork(self) -> int:
199
+ return 0
200
+
201
+
202
+ class PeakCallerMaximumFilterMemoryUsage(MatchingMemoryUsage):
203
+ """
204
+ Memory usage estimation MaxScoreOverRotations Analyzer.
205
+
206
+ See Also
207
+ --------
208
+ :py:class:`tme.analyzer.PeakCallerMaximumFilter`.
209
+ """
210
+
211
+ def base_usage(self) -> int:
212
+ float_arrays = self.real_array_size * self.float_nbytes
213
+ return float_arrays
214
+
215
+ def per_fork(self) -> int:
216
+ float_arrays = self.real_array_size * self.float_nbytes
217
+ return float_arrays
218
+
219
+
220
+ class CupyBackendMemoryUsage(MatchingMemoryUsage):
221
+ """
222
+ Memory usage estimation for CupyBackend.
223
+
224
+ See Also
225
+ --------
226
+ :py:class:`tme.backends.CupyBackend`.
227
+ """
228
+
229
+ def base_usage(self) -> int:
230
+ # FFT plans, overhead from assigning FFT result, rotation interpolation
231
+ complex_arrays = self.real_array_size * self.complex_nbytes * 3
232
+ float_arrays = self.complex_array_size * self.float_nbytes * 2
233
+ return float_arrays + complex_arrays
234
+
235
+ def per_fork(self) -> int:
236
+ return 0
237
+
238
+
239
+ def _compute_convolution_shapes(
240
+ arr1_shape: Tuple[int], arr2_shape: Tuple[int]
241
+ ) -> Tuple[Tuple[int], Tuple[int], Tuple[int]]:
242
+ """
243
+ Computes regular, optimized and fourier convolution shape.
244
+
245
+ Parameters
246
+ ----------
247
+ arr1_shape : tuple
248
+ Tuple of integers corresponding to array1 shape.
249
+ arr2_shape : tuple
250
+ Tuple of integers corresponding to array2 shape.
251
+
252
+ Returns
253
+ -------
254
+ tuple
255
+ Tuple with regular convolution shape, convolution shape optimized for faster
256
+ fourier transform, shape of the forward fourier transform
257
+ (see :py:meth:`build_fft`).
258
+ """
259
+ convolution_shape = np.add(arr1_shape, arr2_shape) - 1
260
+ fast_shape = [next_fast_len(x) for x in convolution_shape]
261
+ fast_ft_shape = list(fast_shape[:-1]) + [fast_shape[-1] // 2 + 1]
262
+
263
+ return convolution_shape, fast_shape, fast_ft_shape
264
+
265
+
266
+ MATCHING_MEMORY_REGISTRY = {
267
+ "CC": CCMemoryUsage,
268
+ "LCC": LCCMemoryUsage,
269
+ "CORR": CORRMemoryUsage,
270
+ "CAM": CAMMemoryUsage,
271
+ "MCC": MCCMemoryUsage,
272
+ "FLCSphericalMask": FLCSphericalMaskMemoryUsage,
273
+ "FLC": FLCMemoryUsage,
274
+ "MaxScoreOverRotations": MaxScoreOverRotationsMemoryUsage,
275
+ "PeakCallerMaximumFilter": PeakCallerMaximumFilterMemoryUsage,
276
+ "cupy": CupyBackendMemoryUsage,
277
+ "pytorch": CupyBackendMemoryUsage,
278
+ }
279
+
280
+
281
+ def estimate_ram_usage(
282
+ shape1: Tuple[int],
283
+ shape2: Tuple[int],
284
+ matching_method: str,
285
+ ncores: int,
286
+ analyzer_method: str = None,
287
+ backend: str = None,
288
+ float_nbytes: int = 4,
289
+ complex_nbytes: int = 8,
290
+ integer_nbytes: int = 4,
291
+ ) -> int:
292
+ """
293
+ Estimate the RAM usage for a given convolution operation based on input shapes,
294
+ matching_method, and number of cores.
295
+
296
+ Parameters
297
+ ----------
298
+ shape1 : tuple
299
+ The shape of the input target.
300
+ shape2 : tuple
301
+ The shape of the input template.
302
+ matching_method : str
303
+ The method used for the operation.
304
+ is_gpu : bool, optional
305
+ Whether the computation is performed on GPU. This factors in FFT
306
+ plan caching.
307
+ analyzer_method : str, optional
308
+ The method used for score analysis.
309
+ backend : str, optional
310
+ Backend used for computation.
311
+ ncores : int
312
+ The number of CPU cores used for the operation.
313
+ float_nbytes : int
314
+ Number of bytes of the used float, e.g. 4 for float32.
315
+ complex_nbytes : int
316
+ Number of bytes of the used complex, e.g. 8 for complex64.
317
+ integer_nbytes : int
318
+ Number of bytes of the used integer, e.g. 4 for int32.
319
+
320
+ Returns
321
+ -------
322
+ int
323
+ The estimated RAM usage for the operation in bytes.
324
+
325
+ Notes
326
+ -----
327
+ Residual memory from other objects that may remain allocated during
328
+ template matching, e.g. the full sized target when using splitting,
329
+ are not considered by this function.
330
+
331
+ Raises
332
+ ------
333
+ ValueError
334
+ If an unsupported matching_methode is provided.
335
+ """
336
+ if matching_method not in MATCHING_MEMORY_REGISTRY:
337
+ raise ValueError(
338
+ f"Supported options are {','.join(MATCHING_MEMORY_REGISTRY.keys())}"
339
+ )
340
+
341
+ convolution_shape, fast_shape, ft_shape = _compute_convolution_shapes(
342
+ shape1, shape2
343
+ )
344
+
345
+ memory_instance = MATCHING_MEMORY_REGISTRY[matching_method](
346
+ fast_shape=fast_shape,
347
+ ft_shape=ft_shape,
348
+ float_nbytes=float_nbytes,
349
+ complex_nbytes=complex_nbytes,
350
+ integer_nbytes=integer_nbytes,
351
+ )
352
+
353
+ nbytes = memory_instance.base_usage() + memory_instance.per_fork() * ncores
354
+
355
+ analyzer_instance = MATCHING_MEMORY_REGISTRY.get(analyzer_method, None)
356
+ if analyzer_instance is not None:
357
+ analyzer_instance = analyzer_instance(
358
+ fast_shape=fast_shape,
359
+ ft_shape=ft_shape,
360
+ float_nbytes=float_nbytes,
361
+ complex_nbytes=complex_nbytes,
362
+ integer_nbytes=integer_nbytes,
363
+ )
364
+ nbytes += analyzer_instance.base_usage() + analyzer_instance.per_fork() * ncores
365
+
366
+ backend_instance = MATCHING_MEMORY_REGISTRY.get(backend, None)
367
+ if backend_instance is not None:
368
+ backend_instance = backend_instance(
369
+ fast_shape=fast_shape,
370
+ ft_shape=ft_shape,
371
+ float_nbytes=float_nbytes,
372
+ complex_nbytes=complex_nbytes,
373
+ integer_nbytes=integer_nbytes,
374
+ )
375
+ nbytes += backend_instance.base_usage() + backend_instance.per_fork() * ncores
376
+
377
+ return nbytes