pytme 0.3.1__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 (33) hide show
  1. pytme-0.3.1.dev20250731.data/scripts/estimate_ram_usage.py +97 -0
  2. {pytme-0.3.1.data → pytme-0.3.1.dev20250731.data}/scripts/match_template.py +2 -2
  3. {pytme-0.3.1.data → pytme-0.3.1.dev20250731.data}/scripts/postprocess.py +16 -15
  4. {pytme-0.3.1.data → pytme-0.3.1.dev20250731.data}/scripts/preprocessor_gui.py +1 -0
  5. {pytme-0.3.1.dist-info → pytme-0.3.1.dev20250731.dist-info}/METADATA +2 -4
  6. {pytme-0.3.1.dist-info → pytme-0.3.1.dev20250731.dist-info}/RECORD +33 -30
  7. scripts/estimate_ram_usage.py +97 -0
  8. scripts/match_template.py +2 -2
  9. scripts/match_template_devel.py +1339 -0
  10. scripts/postprocess.py +16 -15
  11. scripts/preprocessor_gui.py +1 -0
  12. scripts/refine_matches.py +5 -7
  13. tests/test_analyzer.py +2 -3
  14. tests/test_extensions.py +0 -1
  15. tests/test_orientations.py +0 -12
  16. tme/analyzer/aggregation.py +22 -12
  17. tme/backends/_jax_utils.py +60 -16
  18. tme/backends/cupy_backend.py +11 -11
  19. tme/backends/jax_backend.py +27 -9
  20. tme/backends/matching_backend.py +11 -0
  21. tme/backends/npfftw_backend.py +3 -0
  22. tme/density.py +58 -1
  23. tme/matching_data.py +24 -0
  24. tme/matching_exhaustive.py +5 -2
  25. tme/matching_scores.py +23 -0
  26. tme/orientations.py +20 -7
  27. {pytme-0.3.1.data → pytme-0.3.1.dev20250731.data}/scripts/estimate_memory_usage.py +0 -0
  28. {pytme-0.3.1.data → pytme-0.3.1.dev20250731.data}/scripts/preprocess.py +0 -0
  29. {pytme-0.3.1.data → pytme-0.3.1.dev20250731.data}/scripts/pytme_runner.py +0 -0
  30. {pytme-0.3.1.dist-info → pytme-0.3.1.dev20250731.dist-info}/WHEEL +0 -0
  31. {pytme-0.3.1.dist-info → pytme-0.3.1.dev20250731.dist-info}/entry_points.txt +0 -0
  32. {pytme-0.3.1.dist-info → pytme-0.3.1.dev20250731.dist-info}/licenses/LICENSE +0 -0
  33. {pytme-0.3.1.dist-info → pytme-0.3.1.dev20250731.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,97 @@
1
+ #!python
2
+ """ Estimate RAM requirements for template matching jobs.
3
+
4
+ Copyright (c) 2023 European Molecular Biology Laboratory
5
+
6
+ Author: Valentin Maurer <valentin.maurer@embl-hamburg.de>
7
+ """
8
+ import numpy as np
9
+ import argparse
10
+ from tme import Density
11
+ from tme.matching_utils import estimate_ram_usage
12
+ from tme.matching_exhaustive import MATCHING_EXHAUSTIVE_REGISTER
13
+
14
+
15
+ def parse_args():
16
+ parser = argparse.ArgumentParser(
17
+ description="Estimate RAM usage for template matching."
18
+ )
19
+ parser.add_argument(
20
+ "-m",
21
+ "--target",
22
+ dest="target",
23
+ type=str,
24
+ required=True,
25
+ help="Path to a target in CCP4/MRC format.",
26
+ )
27
+ parser.add_argument(
28
+ "-i",
29
+ "--template",
30
+ dest="template",
31
+ type=str,
32
+ required=True,
33
+ help="Path to a template in PDB/MMCIF or CCP4/MRC format.",
34
+ )
35
+ parser.add_argument(
36
+ "--matching_method",
37
+ required=False,
38
+ default=None,
39
+ help="Analyzer method to use.",
40
+ )
41
+ parser.add_argument(
42
+ "-s",
43
+ dest="score",
44
+ type=str,
45
+ default="FLCSphericalMask",
46
+ help="Template matching scoring function.",
47
+ choices=MATCHING_EXHAUSTIVE_REGISTER.keys(),
48
+ )
49
+ parser.add_argument(
50
+ "--ncores", type=int, help="Number of cores for parallelization.", required=True
51
+ )
52
+ parser.add_argument(
53
+ "--no_edge_padding",
54
+ dest="no_edge_padding",
55
+ action="store_true",
56
+ default=False,
57
+ help="Whether to pad the edges of the target. This is useful, if the target"
58
+ " has a well defined bounding box, e.g. a density map.",
59
+ )
60
+ parser.add_argument(
61
+ "--no_fourier_padding",
62
+ dest="no_fourier_padding",
63
+ action="store_true",
64
+ default=False,
65
+ help="Whether input arrays should be zero-padded to the full convolution shape"
66
+ " for numerical stability. When working with very large targets such as"
67
+ " tomograms it is safe to use this flag and benefit from the performance gain.",
68
+ )
69
+ args = parser.parse_args()
70
+ return args
71
+
72
+
73
+ def main():
74
+ args = parse_args()
75
+ target = Density.from_file(args.target)
76
+ template = Density.from_file(args.template)
77
+
78
+ target_box = target.shape
79
+ if not args.no_edge_padding:
80
+ target_box = np.add(target_box, template.shape)
81
+
82
+ template_box = template.shape
83
+ if args.no_fourier_padding:
84
+ template_box = np.ones(len(template_box), dtype=int)
85
+
86
+ result = estimate_ram_usage(
87
+ shape1=target_box,
88
+ shape2=template_box,
89
+ matching_method=args.score,
90
+ ncores=args.ncores,
91
+ analyzer_method="MaxScoreOverRotations",
92
+ )
93
+ print(result)
94
+
95
+
96
+ if __name__ == "__main__":
97
+ main()
@@ -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",
@@ -188,7 +188,7 @@ def parse_args():
188
188
  )
189
189
  additional_group.add_argument(
190
190
  "--n-false-positives",
191
- type=int,
191
+ type=float,
192
192
  default=None,
193
193
  required=False,
194
194
  help="Number of accepted false-positives picks to determine minimum score.",
@@ -318,11 +318,7 @@ def normalize_input(foregrounds: Tuple[str], backgrounds: Tuple[str]) -> Tuple:
318
318
  data = load_matching_output(foreground)
319
319
  scores, _, rotations, rotation_mapping, *_ = data
320
320
 
321
- # We could normalize to unit sdev, but that might lead to unexpected
322
- # results for flat background distributions
323
- # scores -= scores.mean()
324
321
  indices = tuple(slice(0, x) for x in scores.shape)
325
-
326
322
  indices_update = scores > scores_out[indices]
327
323
  scores_out[indices][indices_update] = scores[indices_update]
328
324
 
@@ -369,9 +365,7 @@ def normalize_input(foregrounds: Tuple[str], backgrounds: Tuple[str]) -> Tuple:
369
365
  scores_norm = np.full(out_shape_norm, fill_value=0, dtype=np.float32)
370
366
  for background in backgrounds:
371
367
  data_norm = load_matching_output(background)
372
-
373
- scores = data_norm[0]
374
- # scores -= scores.mean()
368
+ scores, _, rotations, rotation_mapping, *_ = data_norm
375
369
 
376
370
  indices = tuple(slice(0, x) for x in scores.shape)
377
371
  indices_update = scores > scores_norm[indices]
@@ -381,9 +375,10 @@ def normalize_input(foregrounds: Tuple[str], backgrounds: Tuple[str]) -> Tuple:
381
375
  update = tuple(slice(0, int(x)) for x in np.minimum(out_shape, scores.shape))
382
376
  scores_out = np.full(out_shape, fill_value=0, dtype=np.float32)
383
377
  scores_out[update] = data[0][update] - scores_norm[update]
378
+ scores_out = np.fmax(scores_out, 0, out=scores_out)
379
+ scores_out[update] += scores_norm[update].mean()
384
380
 
385
381
  # scores_out[update] = np.divide(scores_out[update], 1 - scores_norm[update])
386
- scores_out = np.fmax(scores_out, 0, out=scores_out)
387
382
  data[0] = scores_out
388
383
 
389
384
  fg, bg = simple_stats(data[0]), simple_stats(scores_norm)
@@ -485,8 +480,11 @@ def main():
485
480
  if orientations is None:
486
481
  translations, rotations, scores, details = [], [], [], []
487
482
 
488
- # Data processed by normalize_input is guaranteed to have this shape
489
- scores, offset, rotation_array, rotation_mapping, meta = data
483
+ var = None
484
+ # Data processed by normalize_input is guaranteed to have this shape)
485
+ scores, _, rotation_array, rotation_mapping, *_ = data
486
+ if len(data) == 6:
487
+ scores, _, rotation_array, rotation_mapping, var, *_ = data
490
488
 
491
489
  cropped_shape = np.subtract(
492
490
  scores.shape, np.multiply(args.min_boundary_distance, 2)
@@ -509,13 +507,16 @@ def main():
509
507
  )
510
508
  args.n_false_positives = max(args.n_false_positives, 1)
511
509
  n_correlations = np.size(scores[cropped_slice]) * len(rotation_mapping)
510
+ std = np.std(scores[cropped_slice])
511
+ if var is not None:
512
+ std = np.asarray(np.sqrt(var)).reshape(())
513
+
512
514
  minimum_score = np.multiply(
513
515
  erfcinv(2 * args.n_false_positives / n_correlations),
514
- np.sqrt(2) * np.std(scores[cropped_slice]),
516
+ np.sqrt(2) * std,
515
517
  )
516
- print(f"Determined minimum score cutoff: {minimum_score}.")
517
- minimum_score = max(minimum_score, 0)
518
- args.min_score = minimum_score
518
+ print(f"Determined cutoff --min-score {minimum_score}.")
519
+ args.min_score = max(minimum_score, 0)
519
520
 
520
521
  args.batch_dims = None
521
522
  if hasattr(cli_args, "batch_dims"):
@@ -474,6 +474,7 @@ def membrane_mask(
474
474
  **kwargs,
475
475
  ) -> NDArray:
476
476
  return create_mask(
477
+ center=(center_x, center_y, center_z),
477
478
  mask_type="membrane",
478
479
  shape=template.shape,
479
480
  radius=radius,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pytme
3
- Version: 0.3.1
3
+ Version: 0.3.1.dev20250731
4
4
  Summary: Python Template Matching Engine
5
5
  Author: Valentin Maurer
6
6
  Author-email: Valentin Maurer <valentin.maurer@embl-hamburg.de>
@@ -26,9 +26,7 @@ Requires-Dist: importlib_resources
26
26
  Requires-Dist: joblib
27
27
  Provides-Extra: cupy
28
28
  Requires-Dist: cupy-cuda12x>13.0.0; extra == "cupy"
29
- Provides-Extra: cupy-voltools
30
- Requires-Dist: cupy-cuda12x>13.0.0; extra == "cupy-voltools"
31
- Requires-Dist: voltools; extra == "cupy-voltools"
29
+ Requires-Dist: voltools; extra == "cupy"
32
30
  Provides-Extra: pytorch
33
31
  Requires-Dist: torch; extra == "pytorch"
34
32
  Requires-Dist: torchvision; extra == "pytorch"
@@ -1,33 +1,36 @@
1
- pytme-0.3.1.data/scripts/estimate_memory_usage.py,sha256=Ry46LXUv3SZ0g41g3RDUg9UH6hiSnnG3mHTyaGletXE,2114
2
- pytme-0.3.1.data/scripts/match_template.py,sha256=X0Sa4dBuE3fvKer--JgY7kPSyZ7H6fa5PKi2lxRoyzM,37563
3
- pytme-0.3.1.data/scripts/postprocess.py,sha256=0QOUzqa76Wrg7JK51qEtjm7XH78UFdMuDia50HmlXwU,27638
4
- pytme-0.3.1.data/scripts/preprocess.py,sha256=eq-67cuj3WFx5jAdS56yQSVv_sCt7SRW-dqzQRbLnVE,6328
5
- pytme-0.3.1.data/scripts/preprocessor_gui.py,sha256=R73N-UTSiAplTqyRw-SLGcGusnJVv2dlAFLuqmUrl-8,44153
6
- pytme-0.3.1.data/scripts/pytme_runner.py,sha256=dqCd60puAOOOSvuCxrJC1MbfdsRS-ctMso5YIwM-JkI,40356
7
- pytme-0.3.1.dist-info/licenses/LICENSE,sha256=gXf5dRMhNSbfLPYYTY_5hsZ1r7UU1OaKQEAQUhuIBkM,18092
1
+ pytme-0.3.1.dev20250731.data/scripts/estimate_memory_usage.py,sha256=Ry46LXUv3SZ0g41g3RDUg9UH6hiSnnG3mHTyaGletXE,2114
2
+ pytme-0.3.1.dev20250731.data/scripts/estimate_ram_usage.py,sha256=R1NDpFajcF-MonJ4a43SfDlA-nxBYwK7D2quzCdsVFM,2767
3
+ pytme-0.3.1.dev20250731.data/scripts/match_template.py,sha256=Px443VNaxto_GPuL16d2TcFp7zPrU-camVdGeW4dHNA,37556
4
+ pytme-0.3.1.dev20250731.data/scripts/postprocess.py,sha256=-n7WFjw-AoVe1BLFCgYtfnjdSpZE65o2qeYVmxO_Jh4,27708
5
+ pytme-0.3.1.dev20250731.data/scripts/preprocess.py,sha256=eq-67cuj3WFx5jAdS56yQSVv_sCt7SRW-dqzQRbLnVE,6328
6
+ pytme-0.3.1.dev20250731.data/scripts/preprocessor_gui.py,sha256=fw1Q0G11Eit7TRt9BNqqn5vYthOWt4GdaFS-WfeznbE,44200
7
+ pytme-0.3.1.dev20250731.data/scripts/pytme_runner.py,sha256=dqCd60puAOOOSvuCxrJC1MbfdsRS-ctMso5YIwM-JkI,40356
8
+ pytme-0.3.1.dev20250731.dist-info/licenses/LICENSE,sha256=gXf5dRMhNSbfLPYYTY_5hsZ1r7UU1OaKQEAQUhuIBkM,18092
8
9
  scripts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
10
  scripts/estimate_memory_usage.py,sha256=UiaX30o_H59vzTQZaXISxgzWj5jwgFbMoH1E5ydVHcw,2115
11
+ scripts/estimate_ram_usage.py,sha256=rN7haobnHg3YcgGJIp81FNiCzy8-saJGeEurQlmQmNQ,2768
10
12
  scripts/eval.py,sha256=ebJVLxbRlB6TI5YHNr0VavZ4lmaRdf8QVafyiDhh_oU,2528
11
13
  scripts/extract_candidates.py,sha256=B2O4Xm0eVJzBZOblfkH5za8fTxLIdBRDl89Qwkq4Kjk,8097
12
- scripts/match_template.py,sha256=LsoS7gPh6tx3c5uyF3v5XbATjb8jJ_jh91zmO2IruZ0,37564
14
+ scripts/match_template.py,sha256=akKSFalnhsk2OdqELCKFvrBhJ49U_UoWX4xs-42NKAY,37557
15
+ scripts/match_template_devel.py,sha256=JSeJd4L-vVUn4VYOoKms9RvGUKqLf5NTNoviz7F29ns,46599
13
16
  scripts/match_template_filters.py,sha256=Gj4a1b_S5NWp_dfFEPFn0D7jGf-qYgBbnTvZZ4bwqOQ,42036
14
- scripts/postprocess.py,sha256=YNSySz76axtNvz7R5eCvS90eJjtKQQbWMLSexFTkEbg,27639
17
+ scripts/postprocess.py,sha256=_9mFpFQww0TbMQeFaDRxR_AJh2wdGfXrNbqXVUZhtZY,27709
15
18
  scripts/preprocess.py,sha256=PrtO0aWGbTvSMqCdNYuzW02FoGvSsvQzJab52DTssQ4,6329
16
- scripts/preprocessor_gui.py,sha256=eozUE6D_vJOO11Prardwm7zWrjvTXLHFaAMmY7yfNIc,44154
19
+ scripts/preprocessor_gui.py,sha256=GUtq8_jU0NGqTEq5ZyjMaeBskJIxao4rznuraNv_02s,44201
17
20
  scripts/pytme_runner.py,sha256=BD5u45vtzJo_d6ZAM2N_CKnGpfjtNg4v7C-31vbTGnU,40357
18
- scripts/refine_matches.py,sha256=1AG-E2PuTauflR_qVC1CaZKg7ev9xxGu3CIYeyJ2-WQ,12777
21
+ scripts/refine_matches.py,sha256=dLu3aW0-iAn0Qn-GoQBaZfgEGUcTWMQ2J2tA8aNm5Yo,12725
19
22
  tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
20
- tests/test_analyzer.py,sha256=HNZf12dZbuMTJ1oYhdDd1nn9NSGXV12ReEqRjNQ96UI,8393
23
+ tests/test_analyzer.py,sha256=9TVJacQF44AnMYOWfLhqQgz1V2TeKjijVT1rJb50NMw,8360
21
24
  tests/test_backends.py,sha256=65jCvPfB2YjUHkhmjkC49Rpd1SyPRQ7_lnLXHI5QC-U,17361
22
25
  tests/test_density.py,sha256=JVQunV445qij5WdcpKn-5GKqT3endzjXvBPkIaXPADo,18914
23
- tests/test_extensions.py,sha256=1Zv9dG_dmmC2mlbX91YIPyGLSToPC0202-ffLAfVcr4,5203
26
+ tests/test_extensions.py,sha256=K71MvMhLdZz66ifJYqRl0IEr7-PCXSMxKokg-4NCc8Q,5170
24
27
  tests/test_matching_cli.py,sha256=JF7LQixpFQMpbijoPwtNSe9FoYXZmBR6J3T5BvsLbR8,11202
25
28
  tests/test_matching_data.py,sha256=U6ISe4lBLDj-OzgA6QAaoO_aegCJjPtXqHbPiPZ2tkA,6091
26
29
  tests/test_matching_exhaustive.py,sha256=bRPCN0pyZk3DmXMrWRcEGAksYoch8P7fRiwE3g0yIf4,4039
27
30
  tests/test_matching_memory.py,sha256=XrBGRi4cIp3-4nN6s7tj0pBbFJrvJaG3vQdtK-6uzY0,1151
28
31
  tests/test_matching_optimization.py,sha256=bYt3d_nHewTRxKCXgGaMLhObkqBufGwrYL4gfinr_jE,7732
29
32
  tests/test_matching_utils.py,sha256=m6mkjo-rgA0q67MYQwjeyy_y6GBErh68A-lqxvQ8NT4,4948
30
- tests/test_orientations.py,sha256=ydqYZc3mOWSweFEGWMrMaygxX7-7in7forUtiNWfQKc,6767
33
+ tests/test_orientations.py,sha256=BnTWHXplucO9_f1TognyZNVQdzGgr1ckt-YGDrlHDcU,6250
31
34
  tests/test_parser.py,sha256=57oaksWrKNB4Z_22IxfW0nXMyQWLJFVsuvnJQPhMn10,993
32
35
  tests/test_rotations.py,sha256=Kll51PZm_5MWP6TcW_II6oJLgORM4piZtWbzhn2fiA8,5374
33
36
  tests/test_structure.py,sha256=Qgrex3wYl9TpFLcqMeUOkq-7w93bzEsMNStKdJdsbnw,8881
@@ -62,16 +65,16 @@ tests/preprocessing/test_utils.py,sha256=RnqlA3vHcVguWp0gmBOwBgUZK85ylNLqr_oFkf8
62
65
  tme/__init__.py,sha256=GXfIuzU4fh2KZfgUOIXnNeKlJ8kSp3EqoBr6bSik848,217
63
66
  tme/__version__.py,sha256=r4xAFihOf72W9TD-lpMi6ntWSTKTP2SlzKP1ytkjRbI,22
64
67
  tme/cli.py,sha256=48Q7QGIuCwNSms5wOnGmWjMSlZrXjAQUz_9zsIFT9tY,3652
65
- tme/density.py,sha256=iupy3gL7gwE2Q9FHcZfHY_AcbOSUAo3i9tSbC-KF-DA,82405
68
+ tme/density.py,sha256=qYwLi6zuGlSYXP3mQwfahaAVrSolq718sujeK6ZSE1k,84484
66
69
  tme/extensions.cpython-311-darwin.so,sha256=xUCjh1eMK3iKWMC04oFG3LzxBRAqHpl7idIIV4ezx3Q,415840
67
70
  tme/mask.py,sha256=4xHqWtOabgdYDDCXHpXflaZmLlmE2_9-bxjs4AaCIYM,10472
68
- tme/matching_data.py,sha256=l9eIJOkANOn-sHWeCVU-1RskMloqH0KmUFQcOQTt6qQ,30361
69
- tme/matching_exhaustive.py,sha256=YswFCaRTaPaGQVRf7SgrmsqEHlnC83u8G4y-PIlR-8w,18270
71
+ tme/matching_data.py,sha256=y6UBUykYpZHsl5NEDyKthKztuwcKFIaOIlB0eEh-Sww,31255
72
+ tme/matching_exhaustive.py,sha256=DnWl7zBfnK83MFZzLDQ9WsBvI2mZkTikxpiXIWrdmxQ,18385
70
73
  tme/matching_optimization.py,sha256=r2zMyOKyvoP8OX9xValJE0DLWbLpNdyY1MLWcOi-H1U,45715
71
- tme/matching_scores.py,sha256=ZYw7ff0y0Zs6fzUwTCQ34Gth4Ckx2ZV7qNk1bH4NXdw,34849
74
+ tme/matching_scores.py,sha256=sX4hMki9WjwgenNWJ1wNu04J808wOgGuVqbRYSA2TB8,35860
72
75
  tme/matching_utils.py,sha256=Qn65B2F8v1yHLetqpiirvUbj-A9-J1giq3lE9cSb-1E,27426
73
76
  tme/memory.py,sha256=lOD_XJtAWo3IFG5fJIdYgLSpn8o0ORO6Vua_tlm5YEk,9683
74
- tme/orientations.py,sha256=93nmt4GPiuBsMWfwSuQVHUBrgY-5k53PlaCaDXZCZjc,21345
77
+ tme/orientations.py,sha256=23HQ2jmW74cAY7RBHe-fB-T1sb8lJ7OfbnP4W5uYZ_M,21857
75
78
  tme/parser.py,sha256=d59A7meIUJ8OzfB6eaVqd7CwLj9oYnOfubqlvygbu1U,24210
76
79
  tme/preprocessor.py,sha256=7DAGRfCPc9ge-hEuYsNA_KCeajVnpWl-w4NzGQS53GM,40377
77
80
  tme/rotations.py,sha256=wVnvZrRCHb1wd5E6yDsLxiP2G0Oin66A4W14vsz4i50,10641
@@ -79,19 +82,19 @@ tme/structure.py,sha256=ojk-IQnIe1JrzxUVHlNlyLxtwzNkNykvxTaXvyBMmbs,72135
79
82
  tme/types.py,sha256=NAY7C4qxE6yz-DXVtClMvFfoOV-spWGLNfpLATZ1LcU,442
80
83
  tme/analyzer/__init__.py,sha256=aJyVGlQwO6Ij-_NZ5rBlgBQQSIj0dqpUwlmvIvnQqBM,89
81
84
  tme/analyzer/_utils.py,sha256=48Xq2Hi_P3VYl1SozYz3WwEj3BwL1QdtFYx7dTxv0bc,6344
82
- tme/analyzer/aggregation.py,sha256=tl6Vw0VhdhPYwb-Y82eAK83odL2JD0d5C3N39qJRVZM,27875
85
+ tme/analyzer/aggregation.py,sha256=3ieZlNcDp0dhnQ85DdVLsCFrRfqU4jim3JRcMwORF_U,28518
83
86
  tme/analyzer/base.py,sha256=2uEYKa0xLwggJUenAA6-l8DIO5sYtklHMg9dR3DzAOI,3887
84
87
  tme/analyzer/peaks.py,sha256=y40YVa2zJFLWD3aoP0xtuhK8yOrQV0AVH6ElWyVjXkM,32587
85
88
  tme/analyzer/proxy.py,sha256=NH0J93ESl5NAVd_22rLZGDWjCx1ov8I995Fr3mYqUSM,4162
86
89
  tme/backends/__init__.py,sha256=VUvEnpfjmZQVn_9QHkLPBoa6y8M3gDyNNL9kq4OQNGE,5249
87
90
  tme/backends/_cupy_utils.py,sha256=scxCSK9BcsDaIbHR2mFxAJRIxdc0r5JTC1gCJmVJa64,24558
88
- tme/backends/_jax_utils.py,sha256=0rybsyG2QbGDdQg-1ruDIt1F15DZcz_TguZYjbepCA4,5838
91
+ tme/backends/_jax_utils.py,sha256=8zJJyUeXAT0txjmiDt_iCsmUMamJQuo4cz1RxE6UO6I,6853
89
92
  tme/backends/_numpyfftw_utils.py,sha256=RnYgbSs_sL-NlwYGRqU9kziq0U5qzl9GecVx9uUeSJs,7904
90
- tme/backends/cupy_backend.py,sha256=G3rsdmxWTes8pM82TTnWvoq1bwGrNsBTbfJMSc5gfTA,8269
91
- tme/backends/jax_backend.py,sha256=eHN0PvWVpjoKaYUJ0oRcdXwF7muKrgVAUzb96QRDXWI,12069
92
- tme/backends/matching_backend.py,sha256=oWARMu_Mt6apnvpYGCbQ1_x7tl_PZoxVtVb8HJgtQ-o,32953
93
+ tme/backends/cupy_backend.py,sha256=Ms2sObxr0xc_tdHctcL659G8YWOTqPG59F3665yZH4c,8163
94
+ tme/backends/jax_backend.py,sha256=Ei-MztdxZAzw-nKJIZhS_jTRAR6eZi5F5DGYhIBJOyU,12677
95
+ tme/backends/matching_backend.py,sha256=B9LXxKpfNYdJBIksyGm7g7V7SC9G3mrluscz3aqISsU,33199
93
96
  tme/backends/mlx_backend.py,sha256=3aAKv7VkK_jfxwDMPQZsLp_lRU8MBJ6zNAzrs6VZd3s,6718
94
- tme/backends/npfftw_backend.py,sha256=P151VbhML5myCMX1o4ArHYRNz_Dz6XoGVyQIesEK2zI,18698
97
+ tme/backends/npfftw_backend.py,sha256=8-Hs3slqnWvsHpqICxKxb-fbmg3IbSok3sThXew-P7M,18800
95
98
  tme/backends/pytorch_backend.py,sha256=yn1hhowUMmzMLHdh2jqw2B0CvBIVcSAWOvRMMDkSHmw,14229
96
99
  tme/data/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
97
100
  tme/data/c48n309.npy,sha256=NwH64mOEbm3tStq5c98o81fY1vMOoq4nvXDAh7Z7iZg,296768
@@ -126,8 +129,8 @@ tme/filters/ctf.py,sha256=HNB03Pw3gn2Y8pIM2391iRHQzp2NcHZWFDC61v3K0oM,24520
126
129
  tme/filters/reconstruction.py,sha256=4gCGpuWuM-yCDQvuzyex_Q8bmsFqUI_8IoZnv3B_3UA,7564
127
130
  tme/filters/wedge.py,sha256=JWiN9IwRXnc7A7syq11kSuin6QjhlVmi38nwGHu4yxE,19541
128
131
  tme/filters/whitening.py,sha256=Zwk-0jMVqy_F8TdQ0ht5unMz2JBOePOC3okUhQpU0bo,6348
129
- pytme-0.3.1.dist-info/METADATA,sha256=uGvw-jEiKmPKGI-cQurxjdCgvwrRhcCLZzbIQmF2NqM,5079
130
- pytme-0.3.1.dist-info/WHEEL,sha256=SPbiHAOPLnBtml4sk5MIwvWF6YnGfOfy9C__W6Bpeg4,109
131
- pytme-0.3.1.dist-info/entry_points.txt,sha256=pbUSmB0J4Ghlg0w7jHfaFSvPMuvRWzeSuvdjdRPisAU,288
132
- pytme-0.3.1.dist-info/top_level.txt,sha256=ovCUR7UXXouH3zYt_fJLoqr_vtjp1wudFgjVAnztQLE,18
133
- pytme-0.3.1.dist-info/RECORD,,
132
+ pytme-0.3.1.dev20250731.dist-info/METADATA,sha256=0wYI-yjiSeP9CdHpoZSjw8X9OCMk80UafjOVxZDB8YA,4991
133
+ pytme-0.3.1.dev20250731.dist-info/WHEEL,sha256=SPbiHAOPLnBtml4sk5MIwvWF6YnGfOfy9C__W6Bpeg4,109
134
+ pytme-0.3.1.dev20250731.dist-info/entry_points.txt,sha256=pbUSmB0J4Ghlg0w7jHfaFSvPMuvRWzeSuvdjdRPisAU,288
135
+ pytme-0.3.1.dev20250731.dist-info/top_level.txt,sha256=ovCUR7UXXouH3zYt_fJLoqr_vtjp1wudFgjVAnztQLE,18
136
+ pytme-0.3.1.dev20250731.dist-info/RECORD,,
@@ -0,0 +1,97 @@
1
+ #!python3
2
+ """ Estimate RAM requirements for template matching jobs.
3
+
4
+ Copyright (c) 2023 European Molecular Biology Laboratory
5
+
6
+ Author: Valentin Maurer <valentin.maurer@embl-hamburg.de>
7
+ """
8
+ import numpy as np
9
+ import argparse
10
+ from tme import Density
11
+ from tme.matching_utils import estimate_ram_usage
12
+ from tme.matching_exhaustive import MATCHING_EXHAUSTIVE_REGISTER
13
+
14
+
15
+ def parse_args():
16
+ parser = argparse.ArgumentParser(
17
+ description="Estimate RAM usage for template matching."
18
+ )
19
+ parser.add_argument(
20
+ "-m",
21
+ "--target",
22
+ dest="target",
23
+ type=str,
24
+ required=True,
25
+ help="Path to a target in CCP4/MRC format.",
26
+ )
27
+ parser.add_argument(
28
+ "-i",
29
+ "--template",
30
+ dest="template",
31
+ type=str,
32
+ required=True,
33
+ help="Path to a template in PDB/MMCIF or CCP4/MRC format.",
34
+ )
35
+ parser.add_argument(
36
+ "--matching_method",
37
+ required=False,
38
+ default=None,
39
+ help="Analyzer method to use.",
40
+ )
41
+ parser.add_argument(
42
+ "-s",
43
+ dest="score",
44
+ type=str,
45
+ default="FLCSphericalMask",
46
+ help="Template matching scoring function.",
47
+ choices=MATCHING_EXHAUSTIVE_REGISTER.keys(),
48
+ )
49
+ parser.add_argument(
50
+ "--ncores", type=int, help="Number of cores for parallelization.", required=True
51
+ )
52
+ parser.add_argument(
53
+ "--no_edge_padding",
54
+ dest="no_edge_padding",
55
+ action="store_true",
56
+ default=False,
57
+ help="Whether to pad the edges of the target. This is useful, if the target"
58
+ " has a well defined bounding box, e.g. a density map.",
59
+ )
60
+ parser.add_argument(
61
+ "--no_fourier_padding",
62
+ dest="no_fourier_padding",
63
+ action="store_true",
64
+ default=False,
65
+ help="Whether input arrays should be zero-padded to the full convolution shape"
66
+ " for numerical stability. When working with very large targets such as"
67
+ " tomograms it is safe to use this flag and benefit from the performance gain.",
68
+ )
69
+ args = parser.parse_args()
70
+ return args
71
+
72
+
73
+ def main():
74
+ args = parse_args()
75
+ target = Density.from_file(args.target)
76
+ template = Density.from_file(args.template)
77
+
78
+ target_box = target.shape
79
+ if not args.no_edge_padding:
80
+ target_box = np.add(target_box, template.shape)
81
+
82
+ template_box = template.shape
83
+ if args.no_fourier_padding:
84
+ template_box = np.ones(len(template_box), dtype=int)
85
+
86
+ result = estimate_ram_usage(
87
+ shape1=target_box,
88
+ shape2=template_box,
89
+ matching_method=args.score,
90
+ ncores=args.ncores,
91
+ analyzer_method="MaxScoreOverRotations",
92
+ )
93
+ print(result)
94
+
95
+
96
+ if __name__ == "__main__":
97
+ main()
scripts/match_template.py CHANGED
@@ -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",