pytme 0.1.9__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.9.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.9.data → pytme-0.2.0b0.data}/scripts/preprocessor_gui.py +244 -60
  4. {pytme-0.1.9.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.9.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 +74 -33
  23. tme/matching_exhaustive.py +351 -208
  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.9.data/scripts/postprocess.py +0 -625
  31. pytme-0.1.9.dist-info/RECORD +0 -61
  32. {pytme-0.1.9.data → pytme-0.2.0b0.data}/scripts/estimate_ram_usage.py +0 -0
  33. {pytme-0.1.9.data → pytme-0.2.0b0.data}/scripts/preprocess.py +0 -0
  34. {pytme-0.1.9.dist-info → pytme-0.2.0b0.dist-info}/LICENSE +0 -0
  35. {pytme-0.1.9.dist-info → pytme-0.2.0b0.dist-info}/entry_points.txt +0 -0
  36. {pytme-0.1.9.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
  )
@@ -176,11 +179,9 @@ class MatchingData:
176
179
  arr_max = _warn_on_mismatch(arr_max, arr.max(), "max")
177
180
 
178
181
  # Avoid in-place operation in case ret is not floating point
179
- ret = np.divide(
180
- np.subtract(-ret, arr_min),
181
- np.subtract(arr_max, arr_min)
182
+ ret = (
183
+ -np.divide(np.subtract(ret, arr_min), np.subtract(arr_max, arr_min)) + 1
182
184
  )
183
-
184
185
  return ret
185
186
 
186
187
  def subset_by_slice(
@@ -223,14 +224,16 @@ class MatchingData:
223
224
  if target_pad is None:
224
225
  target_pad = np.zeros(len(self._target.shape), dtype=int)
225
226
  if template_pad is None:
226
- template_pad = np.zeros(len(self._target.shape), dtype=int)
227
-
228
- indices = compute_full_convolution_index(
229
- outer_shape=self._target.shape,
230
- inner_shape=self._template.shape,
231
- outer_split=target_slice,
232
- inner_split=template_slice,
233
- )
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
+ )
234
237
 
235
238
  target_subset = self.subset_array(
236
239
  arr=self._target,
@@ -246,13 +249,19 @@ class MatchingData:
246
249
  )
247
250
  ret = self.__class__(target=target_subset, template=template_subset)
248
251
 
249
- ret._translation_offset = np.add(
250
- [x.start for x in target_slice],
251
- [x.start for x in template_slice],
252
- )
253
- 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)
254
261
 
255
- 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
256
265
  ret._target_pad, ret._template_pad = target_pad, template_pad
257
266
  ret._invert_target = self._invert_target
258
267
 
@@ -282,10 +291,14 @@ class MatchingData:
282
291
  """
283
292
  Transfer the class instance's numpy arrays to the current backend.
284
293
  """
294
+ backend_arr = type(backend.zeros((1), dtype=backend._default_dtype))
285
295
  for attr_name, attr_value in vars(self).items():
286
296
  if isinstance(attr_value, np.ndarray):
287
297
  converted_array = backend.to_backend_array(attr_value.copy())
288
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)
289
302
 
290
303
  self._default_dtype = backend._default_dtype
291
304
  self._complex_dtype = backend._complex_dtype
@@ -427,13 +440,13 @@ class MatchingData:
427
440
  An array indicating the padding for each dimension of the target.
428
441
  """
429
442
  target_padding = backend.zeros(
430
- len(self.target.shape), dtype=backend._default_dtype_int
443
+ len(self._output_target_shape), dtype=backend._default_dtype_int
431
444
  )
432
445
 
433
446
  if pad_target:
434
447
  backend.subtract(
435
- self._template.shape,
436
- backend.mod(self._template.shape, 2),
448
+ self._output_template_shape,
449
+ backend.mod(self._output_template_shape, 2),
437
450
  out=target_padding,
438
451
  )
439
452
  if hasattr(self, "_is_target_batch"):
@@ -475,20 +488,30 @@ class MatchingData:
475
488
  fourier_shift = backend.zeros(len(fourier_pad))
476
489
 
477
490
  if not pad_fourier:
478
- 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
+ )
479
496
 
480
497
  fourier_pad = backend.to_backend_array(fourier_pad)
481
498
  if hasattr(self, "_batch_mask"):
482
499
  batch_mask = backend.to_backend_array(self._batch_mask)
483
500
  fourier_pad[batch_mask] = 1
484
501
 
485
- 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)
486
504
  convolution_shape, fast_shape, fast_ft_shape = ret
487
505
  if not pad_fourier:
488
506
  fourier_shift = 1 - backend.astype(backend.divide(template_shape, 2), int)
489
507
  fourier_shift -= backend.mod(template_shape, 2)
490
508
  shape_diff = backend.subtract(fast_shape, convolution_shape)
491
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
+
492
515
  backend.add(fourier_shift, shape_diff, out=fourier_shift)
493
516
 
494
517
  return fast_shape, fast_ft_shape, fourier_shift
@@ -523,15 +546,21 @@ class MatchingData:
523
546
  def target(self):
524
547
  """Returns the target NDArray."""
525
548
  if isinstance(self._target, Density):
526
- return self._target.data
527
- 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))
528
554
 
529
555
  @property
530
556
  def template(self):
531
557
  """Returns the reversed template NDArray."""
558
+ template = self._template
532
559
  if isinstance(self._template, Density):
533
- return backend.reverse(self._template.data)
534
- 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))
535
564
 
536
565
  @template.setter
537
566
  def template(self, template: NDArray):
@@ -558,9 +587,15 @@ class MatchingData:
558
587
  @property
559
588
  def target_mask(self):
560
589
  """Returns the target mask NDArray."""
590
+ target_mask = self._target_mask
561
591
  if isinstance(self._target_mask, Density):
562
- return self._target_mask.data
563
- 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
564
599
 
565
600
  @target_mask.setter
566
601
  def target_mask(self, mask: NDArray):
@@ -587,9 +622,15 @@ class MatchingData:
587
622
  template : NDArray
588
623
  Array to set as the template.
589
624
  """
625
+ mask = self._template_mask
590
626
  if isinstance(self._template_mask, Density):
591
- return backend.reverse(self._template_mask.data)
592
- 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
593
634
 
594
635
  @template_mask.setter
595
636
  def template_mask(self, mask: NDArray):