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.
Files changed (36) hide show
  1. {pytme-0.1.8.data → pytme-0.2.0b0.data}/scripts/match_template.py +148 -126
  2. pytme-0.2.0b0.data/scripts/postprocess.py +570 -0
  3. {pytme-0.1.8.data → pytme-0.2.0b0.data}/scripts/preprocessor_gui.py +244 -60
  4. {pytme-0.1.8.dist-info → pytme-0.2.0b0.dist-info}/METADATA +3 -1
  5. pytme-0.2.0b0.dist-info/RECORD +66 -0
  6. {pytme-0.1.8.dist-info → pytme-0.2.0b0.dist-info}/WHEEL +1 -1
  7. scripts/extract_candidates.py +218 -0
  8. scripts/match_template.py +148 -126
  9. scripts/match_template_filters.py +852 -0
  10. scripts/postprocess.py +380 -435
  11. scripts/preprocessor_gui.py +244 -60
  12. scripts/refine_matches.py +218 -0
  13. tme/__init__.py +2 -1
  14. tme/__version__.py +1 -1
  15. tme/analyzer.py +545 -78
  16. tme/backends/cupy_backend.py +80 -15
  17. tme/backends/npfftw_backend.py +33 -2
  18. tme/backends/pytorch_backend.py +15 -7
  19. tme/density.py +156 -63
  20. tme/extensions.cpython-311-darwin.so +0 -0
  21. tme/matching_constrained.py +195 -0
  22. tme/matching_data.py +76 -32
  23. tme/matching_exhaustive.py +366 -204
  24. tme/matching_memory.py +1 -0
  25. tme/matching_optimization.py +728 -651
  26. tme/matching_utils.py +152 -8
  27. tme/orientations.py +561 -0
  28. tme/preprocessor.py +21 -18
  29. tme/structure.py +2 -37
  30. pytme-0.1.8.data/scripts/postprocess.py +0 -625
  31. pytme-0.1.8.dist-info/RECORD +0 -61
  32. {pytme-0.1.8.data → pytme-0.2.0b0.data}/scripts/estimate_ram_usage.py +0 -0
  33. {pytme-0.1.8.data → pytme-0.2.0b0.data}/scripts/preprocess.py +0 -0
  34. {pytme-0.1.8.dist-info → pytme-0.2.0b0.dist-info}/LICENSE +0 -0
  35. {pytme-0.1.8.dist-info → pytme-0.2.0b0.dist-info}/entry_points.txt +0 -0
  36. {pytme-0.1.8.dist-info → pytme-0.2.0b0.dist-info}/top_level.txt +0 -0
tme/matching_data.py CHANGED
@@ -47,6 +47,9 @@ class MatchingData:
47
47
  self.target_filter = {}
48
48
 
49
49
  self._invert_target = False
50
+ self._rotations = None
51
+
52
+ self._set_batch_dimension()
50
53
 
51
54
  @staticmethod
52
55
  def _shape_to_slice(shape: Tuple[int]):
@@ -149,13 +152,13 @@ class MatchingData:
149
152
  def _warn_on_mismatch(
150
153
  expectation: float, computation: float, name: str
151
154
  ) -> float:
152
- expectation, computation = float(expectation), float(computation)
153
155
  if expectation is None:
154
156
  expectation = computation
157
+ expectation, computation = float(expectation), float(computation)
155
158
 
156
159
  if abs(computation) > abs(expectation):
157
160
  warnings.warn(
158
- f"Computed {name} value is more extreme than value specified in file"
161
+ f"Computed {name} value is more extreme than value in file header"
159
162
  f" (|{computation}| > |{expectation}|). This may lead to issues"
160
163
  " with padding and contrast inversion."
161
164
  )
@@ -175,9 +178,10 @@ class MatchingData:
175
178
  arr_min = _warn_on_mismatch(arr_min, arr.min(), "min")
176
179
  arr_max = _warn_on_mismatch(arr_max, arr.max(), "max")
177
180
 
178
- np.subtract(-ret, arr_min, out=ret)
179
- np.divide(ret, arr_max - arr_min, out=ret)
180
-
181
+ # Avoid in-place operation in case ret is not floating point
182
+ ret = (
183
+ -np.divide(np.subtract(ret, arr_min), np.subtract(arr_max, arr_min)) + 1
184
+ )
181
185
  return ret
182
186
 
183
187
  def subset_by_slice(
@@ -220,14 +224,16 @@ class MatchingData:
220
224
  if target_pad is None:
221
225
  target_pad = np.zeros(len(self._target.shape), dtype=int)
222
226
  if template_pad is None:
223
- template_pad = np.zeros(len(self._target.shape), dtype=int)
224
-
225
- indices = compute_full_convolution_index(
226
- outer_shape=self._target.shape,
227
- inner_shape=self._template.shape,
228
- outer_split=target_slice,
229
- inner_split=template_slice,
230
- )
227
+ template_pad = np.zeros(len(self._template.shape), dtype=int)
228
+
229
+ indices = None
230
+ if len(self._target.shape) == len(self._template.shape):
231
+ indices = compute_full_convolution_index(
232
+ outer_shape=self._target.shape,
233
+ inner_shape=self._template.shape,
234
+ outer_split=target_slice,
235
+ inner_split=template_slice,
236
+ )
231
237
 
232
238
  target_subset = self.subset_array(
233
239
  arr=self._target,
@@ -243,13 +249,19 @@ class MatchingData:
243
249
  )
244
250
  ret = self.__class__(target=target_subset, template=template_subset)
245
251
 
246
- ret._translation_offset = np.add(
247
- [x.start for x in target_slice],
248
- [x.start for x in template_slice],
249
- )
250
- ret.template_filter = self.template_filter
252
+ target_offset = np.zeros(len(self._output_target_shape), dtype=int)
253
+ target_offset[(target_offset.size - len(target_slice)) :] = [
254
+ x.start for x in target_slice
255
+ ]
256
+ template_offset = np.zeros(len(self._output_target_shape), dtype=int)
257
+ template_offset[(template_offset.size - len(template_slice)) :] = [
258
+ x.start for x in template_slice
259
+ ]
260
+ ret._translation_offset = np.add(target_offset, template_offset)
251
261
 
252
- ret.rotations, ret.indices = self.rotations, indices
262
+ ret.template_filter = self.template_filter
263
+ ret.target_filter = self.target_filter
264
+ ret._rotations, ret.indices = self.rotations, indices
253
265
  ret._target_pad, ret._template_pad = target_pad, template_pad
254
266
  ret._invert_target = self._invert_target
255
267
 
@@ -279,10 +291,14 @@ class MatchingData:
279
291
  """
280
292
  Transfer the class instance's numpy arrays to the current backend.
281
293
  """
294
+ backend_arr = type(backend.zeros((1), dtype=backend._default_dtype))
282
295
  for attr_name, attr_value in vars(self).items():
283
296
  if isinstance(attr_value, np.ndarray):
284
297
  converted_array = backend.to_backend_array(attr_value.copy())
285
298
  setattr(self, attr_name, converted_array)
299
+ elif isinstance(attr_value, backend_arr):
300
+ converted_array = backend.to_backend_array(attr_value)
301
+ setattr(self, attr_name, converted_array)
286
302
 
287
303
  self._default_dtype = backend._default_dtype
288
304
  self._complex_dtype = backend._complex_dtype
@@ -424,13 +440,13 @@ class MatchingData:
424
440
  An array indicating the padding for each dimension of the target.
425
441
  """
426
442
  target_padding = backend.zeros(
427
- len(self.target.shape), dtype=backend._default_dtype_int
443
+ len(self._output_target_shape), dtype=backend._default_dtype_int
428
444
  )
429
445
 
430
446
  if pad_target:
431
447
  backend.subtract(
432
- self._template.shape,
433
- backend.mod(self._template.shape, 2),
448
+ self._output_template_shape,
449
+ backend.mod(self._output_template_shape, 2),
434
450
  out=target_padding,
435
451
  )
436
452
  if hasattr(self, "_is_target_batch"):
@@ -472,20 +488,30 @@ class MatchingData:
472
488
  fourier_shift = backend.zeros(len(fourier_pad))
473
489
 
474
490
  if not pad_fourier:
475
- fourier_pad = backend.full(shape=len(fourier_pad), fill_value=1, dtype=int)
491
+ fourier_pad = backend.full(
492
+ shape=(len(fourier_pad),),
493
+ fill_value=1,
494
+ dtype=backend._default_dtype_int,
495
+ )
476
496
 
477
497
  fourier_pad = backend.to_backend_array(fourier_pad)
478
498
  if hasattr(self, "_batch_mask"):
479
499
  batch_mask = backend.to_backend_array(self._batch_mask)
480
500
  fourier_pad[batch_mask] = 1
481
501
 
482
- ret = backend.compute_convolution_shapes(target_shape, fourier_pad)
502
+ pad_shape = backend.maximum(target_shape, template_shape)
503
+ ret = backend.compute_convolution_shapes(pad_shape, fourier_pad)
483
504
  convolution_shape, fast_shape, fast_ft_shape = ret
484
505
  if not pad_fourier:
485
506
  fourier_shift = 1 - backend.astype(backend.divide(template_shape, 2), int)
486
507
  fourier_shift -= backend.mod(template_shape, 2)
487
508
  shape_diff = backend.subtract(fast_shape, convolution_shape)
488
509
  shape_diff = backend.astype(backend.divide(shape_diff, 2), int)
510
+
511
+ if hasattr(self, "_batch_mask"):
512
+ batch_mask = backend.to_backend_array(self._batch_mask)
513
+ shape_diff[batch_mask] = 0
514
+
489
515
  backend.add(fourier_shift, shape_diff, out=fourier_shift)
490
516
 
491
517
  return fast_shape, fast_ft_shape, fourier_shift
@@ -520,15 +546,21 @@ class MatchingData:
520
546
  def target(self):
521
547
  """Returns the target NDArray."""
522
548
  if isinstance(self._target, Density):
523
- return self._target.data
524
- return self._target
549
+ target = self._target.data
550
+ else:
551
+ target = self._target
552
+ out_shape = backend.to_numpy_array(self._output_target_shape)
553
+ return target.reshape(tuple(int(x) for x in out_shape))
525
554
 
526
555
  @property
527
556
  def template(self):
528
557
  """Returns the reversed template NDArray."""
558
+ template = self._template
529
559
  if isinstance(self._template, Density):
530
- return backend.reverse(self._template.data)
531
- return backend.reverse(self._template)
560
+ template = self._template.data
561
+ template = backend.reverse(template)
562
+ out_shape = backend.to_numpy_array(self._output_template_shape)
563
+ return template.reshape(tuple(int(x) for x in out_shape))
532
564
 
533
565
  @template.setter
534
566
  def template(self, template: NDArray):
@@ -555,9 +587,15 @@ class MatchingData:
555
587
  @property
556
588
  def target_mask(self):
557
589
  """Returns the target mask NDArray."""
590
+ target_mask = self._target_mask
558
591
  if isinstance(self._target_mask, Density):
559
- return self._target_mask.data
560
- return self._target_mask
592
+ target_mask = self._target_mask.data
593
+
594
+ if target_mask is not None:
595
+ out_shape = backend.to_numpy_array(self._output_target_shape)
596
+ target_mask = target_mask.reshape(tuple(int(x) for x in out_shape))
597
+
598
+ return target_mask
561
599
 
562
600
  @target_mask.setter
563
601
  def target_mask(self, mask: NDArray):
@@ -584,9 +622,15 @@ class MatchingData:
584
622
  template : NDArray
585
623
  Array to set as the template.
586
624
  """
625
+ mask = self._template_mask
587
626
  if isinstance(self._template_mask, Density):
588
- return backend.reverse(self._template_mask.data)
589
- return backend.reverse(self._template_mask)
627
+ mask = self._template_mask.data
628
+
629
+ if mask is not None:
630
+ mask = backend.reverse(mask)
631
+ out_shape = backend.to_numpy_array(self._output_template_shape)
632
+ mask = mask.reshape(tuple(int(x) for x in out_shape))
633
+ return mask
590
634
 
591
635
  @template_mask.setter
592
636
  def template_mask(self, mask: NDArray):