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
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pytme
3
- Version: 0.3b0.post1
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>
@@ -25,10 +25,8 @@ Requires-Dist: h5py
25
25
  Requires-Dist: importlib_resources
26
26
  Requires-Dist: joblib
27
27
  Provides-Extra: cupy
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"
28
+ Requires-Dist: cupy-cuda12x>13.0.0; extra == "cupy"
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"
@@ -77,8 +75,8 @@ You can find alternative installation methods in the [documentation](https://kos
77
75
 
78
76
  Learn how to get started with
79
77
 
80
- - [Installation:](https://kosinskilab.github.io/pyTME/quickstart/installation.html).
81
- - [Template matching:](https://kosinskilab.github.io/pyTME/quickstart/matching/particle_picking.html) Find your template of interest.
78
+ - [Installation](https://kosinskilab.github.io/pyTME/quickstart/installation.html)
79
+ - [Template matching](https://kosinskilab.github.io/pyTME/quickstart/matching/particle_picking.html) Find your template of interest.
82
80
  - [Postprocessing](https://kosinskilab.github.io/pyTME/quickstart/postprocessing/motivation.html) Analyze template matching results and downstream integrations.
83
81
 
84
82
  ## How to Cite
@@ -1,37 +1,42 @@
1
- pytme-0.3b0.post1.data/scripts/estimate_memory_usage.py,sha256=Ry46LXUv3SZ0g41g3RDUg9UH6hiSnnG3mHTyaGletXE,2114
2
- pytme-0.3b0.post1.data/scripts/match_template.py,sha256=GKTFpetaxNWpuGNX3fwmE8lMZ73MUaSe2caZoMV-UiA,37837
3
- pytme-0.3b0.post1.data/scripts/postprocess.py,sha256=qqndzyPK09ZqRVf0NyoGasQ8kw1J7BC5R8Ssrk0hIUg,27282
4
- pytme-0.3b0.post1.data/scripts/preprocess.py,sha256=eq-67cuj3WFx5jAdS56yQSVv_sCt7SRW-dqzQRbLnVE,6328
5
- pytme-0.3b0.post1.data/scripts/preprocessor_gui.py,sha256=JZv5r1iqsbtvRG_3h2PXEHQbb0fRCMAQdbc3hD6Cu8I,41834
6
- pytme-0.3b0.post1.data/scripts/pytme_runner.py,sha256=tVtF2sL4pRvWwbTiiU3Tv5hr0kpi2H3oAnt86ucmTss,26312
7
- pytme-0.3b0.post1.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
- scripts/extract_candidates.py,sha256=GnJb7LI0z2UpMvOS3uY6oIXUJ90R4f2V1jPK5SvJbXg,7246
12
- scripts/match_template.py,sha256=1PczCZKYFgk7JjmImXeomO2mcSFZaVXKlWrByGGFZa8,37838
13
+ scripts/extract_candidates.py,sha256=B2O4Xm0eVJzBZOblfkH5za8fTxLIdBRDl89Qwkq4Kjk,8097
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=rFg8roR6QSvLNNVPySST7n0U3bo0HyFo9Vp3IdddHxk,27283
17
+ scripts/postprocess.py,sha256=_9mFpFQww0TbMQeFaDRxR_AJh2wdGfXrNbqXVUZhtZY,27709
15
18
  scripts/preprocess.py,sha256=PrtO0aWGbTvSMqCdNYuzW02FoGvSsvQzJab52DTssQ4,6329
16
- scripts/preprocessor_gui.py,sha256=m7MK7unTd6Bk4ao-1D-sy29Z75v9B_0EIy7kCiHEA1E,41835
17
- scripts/pytme_runner.py,sha256=F81QrC13M5RqloDtEKUz0YKO8B31BJxsBmMdG7uf6Qo,26313
18
- scripts/refine_matches.py,sha256=pwhmIlApvtJ5uyZwqbgkETso_ggrfNa2HIYnkRtgv50,21899
19
+ scripts/preprocessor_gui.py,sha256=GUtq8_jU0NGqTEq5ZyjMaeBskJIxao4rznuraNv_02s,44201
20
+ scripts/pytme_runner.py,sha256=BD5u45vtzJo_d6ZAM2N_CKnGpfjtNg4v7C-31vbTGnU,40357
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
21
- tests/test_backends.py,sha256=sSiTQbtn7SOi-SDcBPKGXCA8X9_Ydo9iQPILAKlmxvE,17567
22
- tests/test_density.py,sha256=vzzy0Gk3uUR096aZgA-e5gOfLnw9qG3RH-xyXtHCO_I,18971
23
- tests/test_extensions.py,sha256=1Zv9dG_dmmC2mlbX91YIPyGLSToPC0202-ffLAfVcr4,5203
23
+ tests/test_analyzer.py,sha256=9TVJacQF44AnMYOWfLhqQgz1V2TeKjijVT1rJb50NMw,8360
24
+ tests/test_backends.py,sha256=65jCvPfB2YjUHkhmjkC49Rpd1SyPRQ7_lnLXHI5QC-U,17361
25
+ tests/test_density.py,sha256=JVQunV445qij5WdcpKn-5GKqT3endzjXvBPkIaXPADo,18914
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
- tests/test_matching_utils.py,sha256=mWX2_uaYMR49w-TF0-uDoWB5ffVLbY5kVXZ1KmCAeco,6318
30
- tests/test_orientations.py,sha256=ydqYZc3mOWSweFEGWMrMaygxX7-7in7forUtiNWfQKc,6767
32
+ tests/test_matching_utils.py,sha256=m6mkjo-rgA0q67MYQwjeyy_y6GBErh68A-lqxvQ8NT4,4948
33
+ tests/test_orientations.py,sha256=BnTWHXplucO9_f1TognyZNVQdzGgr1ckt-YGDrlHDcU,6250
31
34
  tests/test_parser.py,sha256=57oaksWrKNB4Z_22IxfW0nXMyQWLJFVsuvnJQPhMn10,993
32
- tests/test_rotations.py,sha256=CTEkpO8Z-6afgCIk2wGexXBaOqUeGJL2-krm1z4YRFY,5358
35
+ tests/test_rotations.py,sha256=Kll51PZm_5MWP6TcW_II6oJLgORM4piZtWbzhn2fiA8,5374
33
36
  tests/test_structure.py,sha256=Qgrex3wYl9TpFLcqMeUOkq-7w93bzEsMNStKdJdsbnw,8881
37
+ tests/data/.DS_Store,sha256=1lFlJ5EFymdzGAUAaI30vcaaLHt3F1LwpG7xILf9jsM,6148
34
38
  tests/data/README.md,sha256=RMyG_mojKLo6AEIHUj40nTPI7ZGcs_6dRzWSRGxTgGY,83
39
+ tests/data/Blurring/.DS_Store,sha256=1lFlJ5EFymdzGAUAaI30vcaaLHt3F1LwpG7xILf9jsM,6148
35
40
  tests/data/Blurring/blob_width18.npy,sha256=_BVu5T2q_8N5lA2KCMUTLwknec8fHXh9Nsyoa4ov0wo,21408
36
41
  tests/data/Blurring/edgegaussian_sigma3.npy,sha256=OvxXAyJs5V_m7b91BFhBqS9BnisKWbckVcMlHuChQiY,21408
37
42
  tests/data/Blurring/gaussian_sigma2.npy,sha256=OS9sNpu0Y7l--X8dyB-mp-EE5eaNHISqiNkOOutllfc,21408
@@ -41,8 +46,11 @@ tests/data/Blurring/localgaussian_sigma0510.npy,sha256=KXASnlhxAnvvcgIDCniIHkak-
41
46
  tests/data/Blurring/mean_size5.npy,sha256=2APwsCR_1fpwGIc_mG0dPegpcbgXhUbcEEeQo9Wa1iA,42688
42
47
  tests/data/Blurring/ntree_sigma0510.npy,sha256=HxYh_ItxdKulp8UiPMzQ0ze2iiQ3Oi7seWFvEzO1kWQ,21408
43
48
  tests/data/Blurring/rank_rank3.npy,sha256=MxCsomoNPmiV0Cd-5nl2S8TYCfLyEj-WV19gLH_xe0c,21408
49
+ tests/data/Maps/.DS_Store,sha256=1lFlJ5EFymdzGAUAaI30vcaaLHt3F1LwpG7xILf9jsM,6148
44
50
  tests/data/Maps/emd_8621.mrc.gz,sha256=ZAlSOQRT9B_e8xpeodio9j0WBzygl2R1ctg9m8QhCRA,4572566
51
+ tests/data/Raw/.DS_Store,sha256=1lFlJ5EFymdzGAUAaI30vcaaLHt3F1LwpG7xILf9jsM,6148
45
52
  tests/data/Raw/em_map.map,sha256=YeY_R0p-90-oZgxfbKGIsyE5bui_uWq9iGhWl0bLYZI,22304
53
+ tests/data/Structures/.DS_Store,sha256=1lFlJ5EFymdzGAUAaI30vcaaLHt3F1LwpG7xILf9jsM,6148
46
54
  tests/data/Structures/1pdj.cif,sha256=QdO4e2ulO621PVoK3q9n0qDPDKnzJpV6sPeG6zQec1A,169343
47
55
  tests/data/Structures/1pdj.pdb,sha256=nTFGjecultoXNVUBDdsyho0CEzX5i1fSo_aBYDh5-pU,115749
48
56
  tests/data/Structures/5khe.cif,sha256=SnC0so37wyuoYwAX5UDTTLvQiknZXxeJrvkGai-11rw,214644
@@ -53,39 +61,41 @@ tests/preprocessing/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSu
53
61
  tests/preprocessing/test_compose.py,sha256=z44fgQhxJU0-zHSV0CLBMEJqwhK5gEFDhUCLuVsQpQc,2490
54
62
  tests/preprocessing/test_frequency_filters.py,sha256=UmOK5a67tZeeppE0_O8f3ZczxI6RLIyBuVeHdaPT3tk,7057
55
63
  tests/preprocessing/test_preprocessor.py,sha256=XyR4xc4YM76PUKuTIiive76Q85DdcyDAvbXNGcoKL8w,4820
56
- tests/preprocessing/test_utils.py,sha256=2V1a9XtFZYmCyQzgsj0qWzWuXg-JAsOoG5_rtTwxvGg,3031
64
+ tests/preprocessing/test_utils.py,sha256=RnqlA3vHcVguWp0gmBOwBgUZK85ylNLqr_oFkf8wVFo,3706
57
65
  tme/__init__.py,sha256=GXfIuzU4fh2KZfgUOIXnNeKlJ8kSp3EqoBr6bSik848,217
58
- tme/__version__.py,sha256=qYfo45YGvS-HdfrXh9bz8U8hmQRcBHt7Oa8v3GN0B9E,29
66
+ tme/__version__.py,sha256=r4xAFihOf72W9TD-lpMi6ntWSTKTP2SlzKP1ytkjRbI,22
59
67
  tme/cli.py,sha256=48Q7QGIuCwNSms5wOnGmWjMSlZrXjAQUz_9zsIFT9tY,3652
60
- tme/density.py,sha256=GSKrM45ZixRjh86bekmR02m6NjoLsLG3NIHZRBXzojU,82514
61
- tme/extensions.cpython-311-darwin.so,sha256=vNaZYhhSrVlCjBlj5nzpKcnnJ_L_-84WhTRz2kWYK2Y,395696
62
- tme/matching_data.py,sha256=ts3RQePEHaL4FcNrYZHp3cUenpqZ3i0Brv6ZmeUwK_8,30898
63
- tme/matching_exhaustive.py,sha256=xUKe8eg4muEoHRDHHZTBlwntGFesM_0A-Oppt1e2aOg,18852
64
- tme/matching_optimization.py,sha256=xWWjCN_BsTEdHwkIs1-BgTh6ayh4e7SlwotSykDtix4,45687
65
- tme/matching_scores.py,sha256=UTaEdV3H6Wm3jpFkH8y-z8PiuzCnDjH8dd137-EI1VM,41376
66
- tme/matching_utils.py,sha256=NS18oIYdPnBYSy16HU7QPS3FIf9h0k8CvBMWM-4pp_8,37643
67
- tme/memory.py,sha256=UC8L00aINgz7po2xqwpZzKZRrnsoCJGp58rCjZSwGb4,9679
68
- tme/orientations.py,sha256=7rvhN3pmbCU5vzXRaCJQEKwWrjFTsWhFZ4TDUCar-CA,21394
68
+ tme/density.py,sha256=qYwLi6zuGlSYXP3mQwfahaAVrSolq718sujeK6ZSE1k,84484
69
+ tme/extensions.cpython-311-darwin.so,sha256=xUCjh1eMK3iKWMC04oFG3LzxBRAqHpl7idIIV4ezx3Q,415840
70
+ tme/mask.py,sha256=4xHqWtOabgdYDDCXHpXflaZmLlmE2_9-bxjs4AaCIYM,10472
71
+ tme/matching_data.py,sha256=y6UBUykYpZHsl5NEDyKthKztuwcKFIaOIlB0eEh-Sww,31255
72
+ tme/matching_exhaustive.py,sha256=DnWl7zBfnK83MFZzLDQ9WsBvI2mZkTikxpiXIWrdmxQ,18385
73
+ tme/matching_optimization.py,sha256=r2zMyOKyvoP8OX9xValJE0DLWbLpNdyY1MLWcOi-H1U,45715
74
+ tme/matching_scores.py,sha256=sX4hMki9WjwgenNWJ1wNu04J808wOgGuVqbRYSA2TB8,35860
75
+ tme/matching_utils.py,sha256=Qn65B2F8v1yHLetqpiirvUbj-A9-J1giq3lE9cSb-1E,27426
76
+ tme/memory.py,sha256=lOD_XJtAWo3IFG5fJIdYgLSpn8o0ORO6Vua_tlm5YEk,9683
77
+ tme/orientations.py,sha256=23HQ2jmW74cAY7RBHe-fB-T1sb8lJ7OfbnP4W5uYZ_M,21857
69
78
  tme/parser.py,sha256=d59A7meIUJ8OzfB6eaVqd7CwLj9oYnOfubqlvygbu1U,24210
70
79
  tme/preprocessor.py,sha256=7DAGRfCPc9ge-hEuYsNA_KCeajVnpWl-w4NzGQS53GM,40377
71
- tme/rotations.py,sha256=VTWzVyfsih1qGeE5hHPvusAAsic2trWA7-bjyAizoYU,10622
80
+ tme/rotations.py,sha256=wVnvZrRCHb1wd5E6yDsLxiP2G0Oin66A4W14vsz4i50,10641
72
81
  tme/structure.py,sha256=ojk-IQnIe1JrzxUVHlNlyLxtwzNkNykvxTaXvyBMmbs,72135
73
82
  tme/types.py,sha256=NAY7C4qxE6yz-DXVtClMvFfoOV-spWGLNfpLATZ1LcU,442
74
83
  tme/analyzer/__init__.py,sha256=aJyVGlQwO6Ij-_NZ5rBlgBQQSIj0dqpUwlmvIvnQqBM,89
75
- tme/analyzer/_utils.py,sha256=BFC1mWXqh5DGj1FmpjP4ZsIIEqegbdYnrL3ceI4Ux3k,6339
76
- tme/analyzer/aggregation.py,sha256=DaZ_lgKPernaEdoaIk_HTGUpdkEVrPv1zKtKT0AsI68,27757
84
+ tme/analyzer/_utils.py,sha256=48Xq2Hi_P3VYl1SozYz3WwEj3BwL1QdtFYx7dTxv0bc,6344
85
+ tme/analyzer/aggregation.py,sha256=3ieZlNcDp0dhnQ85DdVLsCFrRfqU4jim3JRcMwORF_U,28518
77
86
  tme/analyzer/base.py,sha256=2uEYKa0xLwggJUenAA6-l8DIO5sYtklHMg9dR3DzAOI,3887
78
- tme/analyzer/peaks.py,sha256=OISX30eqabTP_RoDTjlkrlYwaMPVGEErdglo88J6gU8,32682
87
+ tme/analyzer/peaks.py,sha256=y40YVa2zJFLWD3aoP0xtuhK8yOrQV0AVH6ElWyVjXkM,32587
79
88
  tme/analyzer/proxy.py,sha256=NH0J93ESl5NAVd_22rLZGDWjCx1ov8I995Fr3mYqUSM,4162
80
89
  tme/backends/__init__.py,sha256=VUvEnpfjmZQVn_9QHkLPBoa6y8M3gDyNNL9kq4OQNGE,5249
81
90
  tme/backends/_cupy_utils.py,sha256=scxCSK9BcsDaIbHR2mFxAJRIxdc0r5JTC1gCJmVJa64,24558
82
- tme/backends/_jax_utils.py,sha256=5VKafAuxl_oedeAB6DQ0cclITriv4vblbOQUHrFOWoY,5805
83
- tme/backends/cupy_backend.py,sha256=VkHbVriJqOUU6HtbAMWy58MDtqdQghzJNvlL8E_kaY4,9747
84
- tme/backends/jax_backend.py,sha256=nIiecMvdyjjvaHYYq27t_rgaA6jIp5qrtA7irXetnBg,11325
85
- tme/backends/matching_backend.py,sha256=eFBtFy4_kSoprFJugkXEZ8QYQsTFnJX46STRw6b70Aw,34856
86
- tme/backends/mlx_backend.py,sha256=DxcKJmORTDuFFJ6EVVhZOuuiYt88swc314M6MbmCfSw,7756
87
- tme/backends/npfftw_backend.py,sha256=LE7mgxsaKdqODXeG6uYvlC8ulZGtxGi9MYGD9rm5khc,19340
88
- tme/backends/pytorch_backend.py,sha256=xo3YxljJTCekl4XfaCPL1l7NOieTj9ORiManFGJj-3I,15163
91
+ tme/backends/_jax_utils.py,sha256=8zJJyUeXAT0txjmiDt_iCsmUMamJQuo4cz1RxE6UO6I,6853
92
+ tme/backends/_numpyfftw_utils.py,sha256=RnYgbSs_sL-NlwYGRqU9kziq0U5qzl9GecVx9uUeSJs,7904
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
96
+ tme/backends/mlx_backend.py,sha256=3aAKv7VkK_jfxwDMPQZsLp_lRU8MBJ6zNAzrs6VZd3s,6718
97
+ tme/backends/npfftw_backend.py,sha256=8-Hs3slqnWvsHpqICxKxb-fbmg3IbSok3sThXew-P7M,18800
98
+ tme/backends/pytorch_backend.py,sha256=yn1hhowUMmzMLHdh2jqw2B0CvBIVcSAWOvRMMDkSHmw,14229
89
99
  tme/data/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
90
100
  tme/data/c48n309.npy,sha256=NwH64mOEbm3tStq5c98o81fY1vMOoq4nvXDAh7Z7iZg,296768
91
101
  tme/data/c48n527.npy,sha256=saSUMTa1R0MisPvgFL02a7IHQSwEZ-mJu0v3qJjg5AU,506048
@@ -115,12 +125,12 @@ tme/filters/__init__.py,sha256=aDgaWTCcl01BVamzrc8iEyfTfeRB4OdNRU1ywRZ8450,292
115
125
  tme/filters/_utils.py,sha256=VZj7qixVhmFmXIvssxJ0PoUNv2SyyYXFLvY3zZoYyr8,10874
116
126
  tme/filters/bandpass.py,sha256=-xmoBhMIDQA_ah2kiERfom0T9oVZ5n0avt0HLZ90OtQ,8751
117
127
  tme/filters/compose.py,sha256=yeC84D0HznqhRJ7guV6Cpxzq2UWpvV6nouhFECjIDEw,1980
118
- tme/filters/ctf.py,sha256=SAkpjCPzM3YVHFHWLH422kqKmKS9XBD2eYxaALEex_I,24132
128
+ tme/filters/ctf.py,sha256=HNB03Pw3gn2Y8pIM2391iRHQzp2NcHZWFDC61v3K0oM,24520
119
129
  tme/filters/reconstruction.py,sha256=4gCGpuWuM-yCDQvuzyex_Q8bmsFqUI_8IoZnv3B_3UA,7564
120
- tme/filters/wedge.py,sha256=jB53gbBCtXm1Ga--vuObWaNV1T0bArskmSD4Xs6GEYo,19462
130
+ tme/filters/wedge.py,sha256=JWiN9IwRXnc7A7syq11kSuin6QjhlVmi38nwGHu4yxE,19541
121
131
  tme/filters/whitening.py,sha256=Zwk-0jMVqy_F8TdQ0ht5unMz2JBOePOC3okUhQpU0bo,6348
122
- pytme-0.3b0.post1.dist-info/METADATA,sha256=AKQpO_empsgGAkCbodWyG76HN3e3Bt5ZRn-Et2-JAZk,5090
123
- pytme-0.3b0.post1.dist-info/WHEEL,sha256=SPbiHAOPLnBtml4sk5MIwvWF6YnGfOfy9C__W6Bpeg4,109
124
- pytme-0.3b0.post1.dist-info/entry_points.txt,sha256=pbUSmB0J4Ghlg0w7jHfaFSvPMuvRWzeSuvdjdRPisAU,288
125
- pytme-0.3b0.post1.dist-info/top_level.txt,sha256=ovCUR7UXXouH3zYt_fJLoqr_vtjp1wudFgjVAnztQLE,18
126
- pytme-0.3b0.post1.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()
@@ -1,19 +1,22 @@
1
1
  #!python3
2
- """ Prepare orientations stack for refinement.
2
+ """Prepare orientations stack for refinement.
3
3
 
4
- Copyright (c) 2023 European Molecular Biology Laboratory
4
+ Copyright (c) 2023 European Molecular Biology Laboratory
5
5
 
6
- Author: Valentin Maurer <valentin.maurer@embl-hamburg.de>
6
+ Author: Valentin Maurer <valentin.maurer@embl-hamburg.de>
7
7
  """
8
8
  import argparse
9
- from os.path import splitext
9
+ from os import unlink
10
+ from os.path import splitext, basename
10
11
 
11
12
  import numpy as np
13
+ from collections import defaultdict
12
14
 
15
+ from tme.parser import StarParser
13
16
  from tme import Density, Orientations
14
- from tme.matching_utils import (
15
- generate_tempfile_name,
16
- rotation_aligning_vectors,
17
+ from tme.matching_utils import generate_tempfile_name
18
+ from tme.rotations import (
19
+ align_vectors,
17
20
  euler_from_rotationmatrix,
18
21
  euler_to_rotationmatrix,
19
22
  )
@@ -25,7 +28,7 @@ class ProgressBar:
25
28
  """
26
29
 
27
30
  def __init__(self, message: str, nchars: int, total: int):
28
- self._size = nchars - len(message) - (len(str(total))+2) * 2
31
+ self._size = nchars - len(message) - (len(str(total)) + 2) * 2
29
32
  self._message = message
30
33
  self._total = total
31
34
 
@@ -45,20 +48,14 @@ def parse_args():
45
48
  )
46
49
 
47
50
  io_group = parser.add_argument_group("Input / Output")
48
- io_group.add_argument(
49
- "--target",
50
- required=True,
51
- type=str,
52
- help="Extract candidates from this target.",
53
- )
54
51
  io_group.add_argument(
55
52
  "--orientations",
56
53
  required=True,
57
54
  type=str,
58
- help="Path to file generated by postprocess.py using output_format orientations.",
55
+ help="Star file with picks and micrograph names.",
59
56
  )
60
57
  io_group.add_argument(
61
- "--orientations_sampling",
58
+ "--orientations-scaling",
62
59
  required=False,
63
60
  type=float,
64
61
  default=1.0,
@@ -67,54 +64,59 @@ def parse_args():
67
64
  )
68
65
  io_group.add_argument(
69
66
  "-o",
70
- "--output_file",
67
+ "--output-prefix",
71
68
  required=True,
72
69
  type=str,
73
- help="Path to write output H5 file.",
70
+ help="Output prefix to use.",
74
71
  )
75
72
 
76
73
  alignment_group = parser.add_argument_group("Alignment")
77
74
  alignment_group.add_argument(
78
- "--align_orientations",
75
+ "--align-orientations",
79
76
  action="store_true",
80
77
  required=False,
81
78
  help="Whether to align extracted orientations based on their angles. Allows "
82
79
  "for efficient subsequent sampling of cone angles.",
83
80
  )
84
81
  alignment_group.add_argument(
85
- "--angles_are_vector",
82
+ "--angles-are-vector",
86
83
  action="store_true",
87
84
  required=False,
88
85
  help="Considers euler_z euler_y, euler_x as vector that will be rotated to align "
89
86
  "with the z-axis (1,0,0). Only considered when --align_orientations is set.",
90
87
  )
91
88
  alignment_group.add_argument(
92
- "--interpolation_order",
93
- dest="interpolation_order",
89
+ "--interpolation-order",
94
90
  required=False,
95
91
  type=int,
96
92
  default=1,
97
93
  help="Interpolation order for alignment, less than zero is no interpolation.",
98
94
  )
95
+ alignment_group.add_argument(
96
+ "--split-by-micrograph",
97
+ action="store_true",
98
+ required=False,
99
+ help="Create separate output files for each micrograph."
100
+ )
99
101
 
100
102
  extraction_group = parser.add_argument_group("Extraction")
101
103
  extraction_group.add_argument(
102
- "--box_size",
103
- required=False,
104
+ "--box-size",
105
+ required=True,
104
106
  type=int,
105
- help="Box size for extraction, defaults to two times the template.",
107
+ help="Box size for extraction.",
106
108
  )
107
109
  extraction_group.add_argument(
108
- "--translation_uncertainty",
110
+ "--translation-uncertainty",
109
111
  required=False,
110
112
  type=int,
111
113
  help="Sets box size for extraction to template box plus this value.",
112
114
  )
113
115
  extraction_group.add_argument(
114
- "--keep_out_of_box",
116
+ "--drop-out-of-box",
115
117
  action="store_true",
116
118
  required=False,
117
- help="Whether to keep orientations that fall outside the box. If the "
119
+ help="Whether to drop orientations that fall outside the box. If the "
118
120
  "orientations are sensible, it is safe to pass this flag.",
119
121
  )
120
122
 
@@ -125,100 +127,117 @@ def parse_args():
125
127
 
126
128
  def main():
127
129
  args = parse_args()
130
+
131
+ data = StarParser(args.orientations, delimiter="\t")
132
+ key = list(data.keys())[0]
133
+
134
+ index_map = defaultdict(list)
135
+ for index, value in enumerate(data[key]["_rlnMicrographName"]):
136
+ index_map[value].append(index)
137
+
128
138
  orientations = Orientations.from_file(args.orientations)
129
139
  orientations.translations = np.divide(
130
- orientations.translations, args.orientations_sampling
140
+ orientations.translations, args.orientations_scaling
131
141
  )
132
142
 
133
- target = Density.from_file(args.target, use_memmap=True)
134
-
135
143
  box_size = np.array(args.box_size)
136
- box_size = np.repeat(box_size, target.data.ndim // box_size.size).astype(int)
137
-
144
+ box_size = np.repeat(box_size, 3 // box_size.size).astype(int)
138
145
  extraction_shape = np.copy(box_size)
139
- if args.align_orientations:
140
- extraction_shape[:] = int(np.linalg.norm(box_size) + 1)
141
-
142
- orientations, cand_slices, obs_slices = orientations.get_extraction_slices(
143
- target_shape=target.shape,
144
- extraction_shape=extraction_shape,
145
- drop_out_of_box=not args.keep_out_of_box,
146
- return_orientations=True,
147
- )
148
146
 
149
147
  if args.align_orientations:
148
+ extraction_shape[:] = int(np.linalg.norm(box_size) + 1)
150
149
  for index in range(orientations.rotations.shape[0]):
151
150
  rotation_matrix = euler_to_rotationmatrix(orientations.rotations[index])
152
151
  rotation_matrix = np.linalg.inv(rotation_matrix)
153
152
  if args.angles_are_vector:
154
- rotation_matrix = rotation_aligning_vectors(
153
+ rotation_matrix = align_vectors(
155
154
  orientations.rotations[index], target_vector=(1, 0, 0)
156
155
  )
157
156
  orientations.rotations[index] = euler_from_rotationmatrix(rotation_matrix)
158
157
 
159
- filename = generate_tempfile_name()
160
- output_dtype = target.data.dtype
161
- if args.align_orientations is not None:
162
- output_dtype = np.float32
163
-
164
- target.data = target.data.astype(output_dtype)
165
-
166
- dens = Density(
167
- np.memmap(
168
- filename,
169
- mode="w+",
170
- shape=(len(obs_slices), *box_size),
171
- dtype=output_dtype,
172
- ),
173
- sampling_rate=(1, *target.sampling_rate),
174
- origin=(0, *target.origin),
175
- )
176
- dens.data[:] = target.metadata["mean"]
177
-
178
- data_subset = np.zeros(extraction_shape, dtype=target.data.dtype)
179
- pbar = ProgressBar(message="Aligning ", nchars=80, total=len(obs_slices))
180
- for index, (obs_slice, cand_slice) in enumerate(zip(obs_slices, cand_slices)):
181
- pbar.update(index + 1)
182
-
183
- data_subset.fill(0)
184
- data_subset[cand_slice] = target.data[obs_slice]
185
- target_subset = Density(
186
- data_subset,
187
- sampling_rate=target.sampling_rate,
188
- origin=target.origin,
158
+ ret_orientations, ret_dens, ix = [], [], 0
159
+ n_particles = orientations.translations.shape[0]
160
+ pbar = ProgressBar(message="Processing ", nchars=80, total=n_particles)
161
+ for target_path, indices in index_map.items():
162
+
163
+ target = Density.from_file(target_path, use_memmap=True)
164
+
165
+ subset = orientations[indices]
166
+ subset, cand_slices, obs_slices = subset.get_extraction_slices(
167
+ target_shape=target.shape,
168
+ extraction_shape=extraction_shape,
169
+ drop_out_of_box=args.drop_out_of_box,
170
+ return_orientations=True,
189
171
  )
190
172
 
191
- if args.align_orientations:
192
- rotation_matrix = euler_to_rotationmatrix(orientations.rotations[index])
193
- target_subset = target_subset.rigid_transform(
194
- rotation_matrix=rotation_matrix,
195
- use_geometric_center=True,
196
- order=args.interpolation_order,
173
+ dens = Density(
174
+ np.memmap(
175
+ generate_tempfile_name(),
176
+ mode="w+",
177
+ shape=(subset.translations.shape[0], *box_size),
178
+ dtype=np.float32,
179
+ ),
180
+ sampling_rate = (1, *target.sampling_rate),
181
+ metadata = {"batch_dimension" : (0,), "path" : target_path}
182
+ )
183
+
184
+ data_subset = np.zeros(extraction_shape, dtype=target.data.dtype)
185
+ for index, (obs_slice, cand_slice) in enumerate(zip(obs_slices, cand_slices)):
186
+ pbar.update(ix + 1)
187
+
188
+ data_subset.fill(0)
189
+ data_subset[cand_slice] = target.data[obs_slice]
190
+ target_subset = Density(
191
+ data_subset,
192
+ sampling_rate=target.sampling_rate,
193
+ origin=target.origin,
197
194
  )
198
- target_subset.pad(box_size, center=True)
199
195
 
200
- # target_value = target.data[tuple(orientations.translations[index].astype(int))]
201
- # center = np.divide(target_subset.data.shape, 2).astype(int)
202
- # print(np.where(target_subset.data == target_value), center)
203
- # print(target_subset.data[tuple(center.astype(int))],
204
- # target_value,
205
- # target_subset.data[tuple(center.astype(int))] == target_value
206
- # )
196
+ if args.align_orientations:
197
+ rotation_matrix = euler_to_rotationmatrix(subset.rotations[index])
198
+ target_subset = target_subset.rigid_transform(
199
+ rotation_matrix=rotation_matrix,
200
+ use_geometric_center=True,
201
+ order=args.interpolation_order,
202
+ )
203
+ target_subset.pad(box_size, center=True)
204
+ dens.data[index] = target_subset.data.astype(np.float32)
205
+ ix += 1
207
206
 
208
- dens.data[index] = target_subset.data
209
- print("")
207
+ ret_dens.append(dens)
208
+ ret_orientations.append(subset)
210
209
 
211
- target_meta = {
212
- k: v for k, v in target.metadata.items() if k in ("mean", "max", "min", "std")
213
- }
214
- dens.metadata.update(target_meta)
215
- dens.metadata["batch_dimension"] = (0,)
216
- dens.metadata["normals"] = orientations.rotations
210
+ if not len(ret_dens):
211
+ exit("Found no valid particles.")
217
212
 
218
- dens.to_file(args.output_file)
219
- orientations.to_file(
220
- f"{splitext(args.output_file)[0]}_aligned.tsv", file_format="text"
221
- )
213
+ print("")
214
+ if not args.split_by_micrograph:
215
+ ret_orientations = [Orientations(
216
+ translations=np.concatenate([x.translations for x in ret_orientations]),
217
+ rotations=np.concatenate([x.rotations for x in ret_orientations]),
218
+ scores=np.concatenate([x.scores for x in ret_orientations]),
219
+ details=np.concatenate([x.details for x in ret_orientations]),
220
+ )]
221
+ dens_data = Density(
222
+ np.concatenate([x.data for x in ret_dens]),
223
+ sampling_rate=ret_dens[0].sampling_rate
224
+ )
225
+ _ = [unlink(x.data.filename) for x in ret_dens]
226
+ dens_data.metadata.update({"batch_dimension" : (0, )})
227
+ ret_dens = [dens_data]
228
+
229
+ for orientation, dens in zip(ret_orientations, ret_dens):
230
+ fname = args.output_prefix
231
+ if args.split_by_micrograph:
232
+ target = splitext(basename(dens.metadata["path"]))[0]
233
+ fname = f"{args.output_prefix}_{target}"
234
+
235
+ dens.to_file(f"{fname}.h5")
236
+ orientation.to_file(f"{fname}_aligned.star")
237
+ try:
238
+ unlink(dens.data.filename)
239
+ except Exception:
240
+ continue
222
241
 
223
242
  if __name__ == "__main__":
224
243
  main()