pytme 0.3b0.post1__cp311-cp311-macosx_15_0_arm64.whl → 0.3.1.dev20250731__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.
Files changed (60) hide show
  1. pytme-0.3.1.dev20250731.data/scripts/estimate_ram_usage.py +97 -0
  2. {pytme-0.3b0.post1.data → pytme-0.3.1.dev20250731.data}/scripts/match_template.py +30 -41
  3. {pytme-0.3b0.post1.data → pytme-0.3.1.dev20250731.data}/scripts/postprocess.py +35 -21
  4. {pytme-0.3b0.post1.data → pytme-0.3.1.dev20250731.data}/scripts/preprocessor_gui.py +96 -24
  5. pytme-0.3.1.dev20250731.data/scripts/pytme_runner.py +1223 -0
  6. {pytme-0.3b0.post1.dist-info → pytme-0.3.1.dev20250731.dist-info}/METADATA +5 -7
  7. {pytme-0.3b0.post1.dist-info → pytme-0.3.1.dev20250731.dist-info}/RECORD +59 -49
  8. scripts/estimate_ram_usage.py +97 -0
  9. scripts/extract_candidates.py +118 -99
  10. scripts/match_template.py +30 -41
  11. scripts/match_template_devel.py +1339 -0
  12. scripts/postprocess.py +35 -21
  13. scripts/preprocessor_gui.py +96 -24
  14. scripts/pytme_runner.py +644 -190
  15. scripts/refine_matches.py +158 -390
  16. tests/data/.DS_Store +0 -0
  17. tests/data/Blurring/.DS_Store +0 -0
  18. tests/data/Maps/.DS_Store +0 -0
  19. tests/data/Raw/.DS_Store +0 -0
  20. tests/data/Structures/.DS_Store +0 -0
  21. tests/preprocessing/test_utils.py +18 -0
  22. tests/test_analyzer.py +2 -3
  23. tests/test_backends.py +3 -9
  24. tests/test_density.py +0 -1
  25. tests/test_extensions.py +0 -1
  26. tests/test_matching_utils.py +10 -60
  27. tests/test_orientations.py +0 -12
  28. tests/test_rotations.py +1 -1
  29. tme/__version__.py +1 -1
  30. tme/analyzer/_utils.py +4 -4
  31. tme/analyzer/aggregation.py +35 -15
  32. tme/analyzer/peaks.py +11 -10
  33. tme/backends/_jax_utils.py +64 -18
  34. tme/backends/_numpyfftw_utils.py +270 -0
  35. tme/backends/cupy_backend.py +16 -55
  36. tme/backends/jax_backend.py +79 -40
  37. tme/backends/matching_backend.py +17 -51
  38. tme/backends/mlx_backend.py +1 -27
  39. tme/backends/npfftw_backend.py +71 -65
  40. tme/backends/pytorch_backend.py +1 -26
  41. tme/density.py +58 -5
  42. tme/extensions.cpython-311-darwin.so +0 -0
  43. tme/filters/ctf.py +22 -21
  44. tme/filters/wedge.py +10 -7
  45. tme/mask.py +341 -0
  46. tme/matching_data.py +31 -19
  47. tme/matching_exhaustive.py +37 -47
  48. tme/matching_optimization.py +2 -1
  49. tme/matching_scores.py +229 -411
  50. tme/matching_utils.py +73 -422
  51. tme/memory.py +1 -1
  52. tme/orientations.py +24 -13
  53. tme/rotations.py +1 -1
  54. pytme-0.3b0.post1.data/scripts/pytme_runner.py +0 -769
  55. {pytme-0.3b0.post1.data → pytme-0.3.1.dev20250731.data}/scripts/estimate_memory_usage.py +0 -0
  56. {pytme-0.3b0.post1.data → pytme-0.3.1.dev20250731.data}/scripts/preprocess.py +0 -0
  57. {pytme-0.3b0.post1.dist-info → pytme-0.3.1.dev20250731.dist-info}/WHEEL +0 -0
  58. {pytme-0.3b0.post1.dist-info → pytme-0.3.1.dev20250731.dist-info}/entry_points.txt +0 -0
  59. {pytme-0.3b0.post1.dist-info → pytme-0.3.1.dev20250731.dist-info}/licenses/LICENSE +0 -0
  60. {pytme-0.3b0.post1.dist-info → pytme-0.3.1.dev20250731.dist-info}/top_level.txt +0 -0
scripts/match_template.py CHANGED
@@ -12,8 +12,8 @@ from sys import exit
12
12
  from time import time
13
13
  from typing import Tuple
14
14
  from copy import deepcopy
15
- from os.path import exists
16
15
  from tempfile import gettempdir
16
+ from os.path import exists, abspath
17
17
 
18
18
  import numpy as np
19
19
 
@@ -359,8 +359,8 @@ def parse_args():
359
359
  "--invert-target-contrast",
360
360
  action="store_true",
361
361
  default=False,
362
- help="Invert the target's contrast for cases where templates to-be-matched have "
363
- "negative values, e.g. tomograms.",
362
+ help="Invert the target contrast. Useful for matching on tomograms if the "
363
+ "template has not been inverted.",
364
364
  )
365
365
  io_group.add_argument(
366
366
  "--scramble-phases",
@@ -576,7 +576,7 @@ def parse_args():
576
576
  "'angles', or a single column file without header. Exposure will be taken from "
577
577
  "the input file , if you are using a tab-separated file, the column names "
578
578
  "'angles' and 'weights' need to be present. It is also possible to specify a "
579
- "continuous wedge mask using e.g., -50,45.",
579
+ "continuous wedge mask using e.g., 50,45.",
580
580
  )
581
581
  filter_group.add_argument(
582
582
  "--tilt-weighting",
@@ -685,13 +685,6 @@ def parse_args():
685
685
  help="Useful if the target does not have a well-defined bounding box. Will be "
686
686
  "activated automatically if splitting is required to avoid boundary artifacts.",
687
687
  )
688
- performance_group.add_argument(
689
- "--pad-filter",
690
- action="store_true",
691
- default=False,
692
- help="Pad the template filter to the shape of the target. Useful for fast "
693
- "oscilating filters to avoid aliasing effects.",
694
- )
695
688
  performance_group.add_argument(
696
689
  "--interpolation-order",
697
690
  required=False,
@@ -700,13 +693,6 @@ def parse_args():
700
693
  help="Spline interpolation used for rotations. Defaults to 3, and 1 for jax "
701
694
  "and pytorch backends.",
702
695
  )
703
- performance_group.add_argument(
704
- "--use-mixed-precision",
705
- action="store_true",
706
- default=False,
707
- help="Use float16 for real values operations where possible. Not supported "
708
- "for jax backend.",
709
- )
710
696
  performance_group.add_argument(
711
697
  "--use-memmap",
712
698
  action="store_true",
@@ -742,6 +728,7 @@ def parse_args():
742
728
  args.interpolation_order = 3
743
729
  if args.backend in ("jax", "pytorch"):
744
730
  args.interpolation_order = 1
731
+ args.reconstruction_interpolation_order = 1
745
732
 
746
733
  if args.interpolation_order < 0:
747
734
  args.interpolation_order = None
@@ -779,6 +766,14 @@ def parse_args():
779
766
  )
780
767
  args.orientations = orientations
781
768
 
769
+ args.target = abspath(args.target)
770
+ if args.target_mask is not None:
771
+ args.target_mask = abspath(args.target_mask)
772
+
773
+ args.template = abspath(args.template)
774
+ if args.template_mask is not None:
775
+ args.template_mask = abspath(args.template_mask)
776
+
782
777
  return args
783
778
 
784
779
 
@@ -796,15 +791,23 @@ def main():
796
791
  sampling_rate=target.sampling_rate,
797
792
  )
798
793
 
794
+ if np.allclose(target.sampling_rate, 1):
795
+ warnings.warn(
796
+ "Target sampling rate is 1.0, which may indicate missing or incorrect "
797
+ "metadata. Verify that your target file contains proper sampling rate "
798
+ "information, as filters (CTF, BandPass) require accurate sampling rates "
799
+ "to function correctly."
800
+ )
801
+
799
802
  if target.sampling_rate.size == template.sampling_rate.size:
800
803
  if not np.allclose(
801
804
  np.round(target.sampling_rate, 2), np.round(template.sampling_rate, 2)
802
805
  ):
803
- print(
804
- f"Resampling template to {target.sampling_rate}. "
805
- "Consider providing a template with the same sampling rate as the target."
806
+ warnings.warn(
807
+ f"Sampling rate mismatch detected: target={target.sampling_rate} "
808
+ f"template={template.sampling_rate}. Proceeding with user-provided "
809
+ f"values. Make sure this is intentional. "
806
810
  )
807
- template = template.resample(target.sampling_rate, order=3)
808
811
 
809
812
  template_mask = load_and_validate_mask(
810
813
  mask_target=template, mask_path=args.template_mask
@@ -881,16 +884,13 @@ def main():
881
884
  print("\n" + "-" * 80)
882
885
 
883
886
  if args.scramble_phases:
884
- template.data = scramble_phases(
885
- template.data, noise_proportion=1.0, normalize_power=False
886
- )
887
+ template.data = scramble_phases(template.data, noise_proportion=1.0)
887
888
 
888
889
  callback_class = MaxScoreOverRotations
889
- if args.peak_calling:
890
- callback_class = PeakCallerMaximumFilter
891
-
892
890
  if args.orientations is not None:
893
891
  callback_class = MaxScoreOverRotationsConstrained
892
+ elif args.peak_calling:
893
+ callback_class = PeakCallerMaximumFilter
894
894
 
895
895
  # Determine suitable backend for the selected operation
896
896
  available_backends = be.available_backends()
@@ -939,16 +939,6 @@ def main():
939
939
  args.use_gpu = False
940
940
  be.change_backend("pytorch", device=device)
941
941
 
942
- # TODO: Make the inverse casting from complex64 -> float 16 stable
943
- # if args.use_mixed_precision:
944
- # be.change_backend(
945
- # backend_name=args.backend,
946
- # float_dtype=be._array_backend.float16,
947
- # complex_dtype=be._array_backend.complex64,
948
- # int_dtype=be._array_backend.int16,
949
- # device=device,
950
- # )
951
-
952
942
  available_memory = be.get_available_memory() * be.device_count()
953
943
  if args.memory is None:
954
944
  args.memory = int(args.memory_scaling * available_memory)
@@ -976,6 +966,8 @@ def main():
976
966
  target_dim=target.metadata.get("batch_dimension", None),
977
967
  template_dim=template.metadata.get("batch_dimension", None),
978
968
  )
969
+ args.batch_dims = tuple(int(x) for x in np.where(matching_data._batch_mask)[0])
970
+
979
971
  splits, schedule = compute_schedule(args, matching_data, callback_class)
980
972
 
981
973
  n_splits = np.prod(list(splits.values()))
@@ -1004,7 +996,6 @@ def main():
1004
996
  compute_options = {
1005
997
  "Backend": be._BACKEND_REGISTRY[be._backend_name],
1006
998
  "Compute Devices": f"CPU [{args.cores}], GPU [{gpus_used}]",
1007
- "Use Mixed Precision": args.use_mixed_precision,
1008
999
  "Assigned Memory [MB]": f"{args.memory // 1e6} [out of {available_memory//1e6}]",
1009
1000
  "Temporary Directory": args.temp_directory,
1010
1001
  "Target Splits": f"{target_split} [N={n_splits}]",
@@ -1025,7 +1016,6 @@ def main():
1025
1016
  "Tilt Angles": args.tilt_angles,
1026
1017
  "Tilt Weighting": args.tilt_weighting,
1027
1018
  "Reconstruction Filter": args.reconstruction_filter,
1028
- "Extend Filter Grid": args.pad_filter,
1029
1019
  }
1030
1020
  if args.ctf_file is not None or args.defocus is not None:
1031
1021
  filter_args["CTF File"] = args.ctf_file
@@ -1081,7 +1071,6 @@ def main():
1081
1071
  callback_class_args=analyzer_args,
1082
1072
  target_splits=splits,
1083
1073
  pad_target_edges=args.pad_edges,
1084
- pad_template_filter=args.pad_filter,
1085
1074
  interpolation_order=args.interpolation_order,
1086
1075
  )
1087
1076