sawnergy 1.0.2__tar.gz → 1.0.4__tar.gz

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.

Potentially problematic release.


This version of sawnergy might be problematic. Click here for more details.

Files changed (31) hide show
  1. {sawnergy-1.0.2/sawnergy.egg-info → sawnergy-1.0.4}/PKG-INFO +10 -3
  2. {sawnergy-1.0.2 → sawnergy-1.0.4}/README.md +6 -2
  3. {sawnergy-1.0.2 → sawnergy-1.0.4}/sawnergy/rin/rin_builder.py +3 -3
  4. {sawnergy-1.0.2 → sawnergy-1.0.4}/sawnergy/walks/walker.py +43 -22
  5. {sawnergy-1.0.2 → sawnergy-1.0.4/sawnergy.egg-info}/PKG-INFO +10 -3
  6. {sawnergy-1.0.2 → sawnergy-1.0.4}/LICENSE +0 -0
  7. {sawnergy-1.0.2 → sawnergy-1.0.4}/NOTICE +0 -0
  8. {sawnergy-1.0.2 → sawnergy-1.0.4}/sawnergy/__init__.py +0 -0
  9. {sawnergy-1.0.2 → sawnergy-1.0.4}/sawnergy/embedding/SGNS_pml.py +0 -0
  10. {sawnergy-1.0.2 → sawnergy-1.0.4}/sawnergy/embedding/SGNS_torch.py +0 -0
  11. {sawnergy-1.0.2 → sawnergy-1.0.4}/sawnergy/embedding/__init__.py +0 -0
  12. {sawnergy-1.0.2 → sawnergy-1.0.4}/sawnergy/embedding/embedder.py +0 -0
  13. {sawnergy-1.0.2 → sawnergy-1.0.4}/sawnergy/logging_util.py +0 -0
  14. {sawnergy-1.0.2 → sawnergy-1.0.4}/sawnergy/rin/__init__.py +0 -0
  15. {sawnergy-1.0.2 → sawnergy-1.0.4}/sawnergy/rin/rin_util.py +0 -0
  16. {sawnergy-1.0.2 → sawnergy-1.0.4}/sawnergy/sawnergy_util.py +0 -0
  17. {sawnergy-1.0.2 → sawnergy-1.0.4}/sawnergy/visual/__init__.py +0 -0
  18. {sawnergy-1.0.2 → sawnergy-1.0.4}/sawnergy/visual/visualizer.py +0 -0
  19. {sawnergy-1.0.2 → sawnergy-1.0.4}/sawnergy/visual/visualizer_util.py +0 -0
  20. {sawnergy-1.0.2 → sawnergy-1.0.4}/sawnergy/walks/__init__.py +0 -0
  21. {sawnergy-1.0.2 → sawnergy-1.0.4}/sawnergy/walks/walker_util.py +0 -0
  22. {sawnergy-1.0.2 → sawnergy-1.0.4}/sawnergy.egg-info/SOURCES.txt +0 -0
  23. {sawnergy-1.0.2 → sawnergy-1.0.4}/sawnergy.egg-info/dependency_links.txt +0 -0
  24. {sawnergy-1.0.2 → sawnergy-1.0.4}/sawnergy.egg-info/requires.txt +0 -0
  25. {sawnergy-1.0.2 → sawnergy-1.0.4}/sawnergy.egg-info/top_level.txt +0 -0
  26. {sawnergy-1.0.2 → sawnergy-1.0.4}/setup.cfg +0 -0
  27. {sawnergy-1.0.2 → sawnergy-1.0.4}/tests/test_embedding.py +0 -0
  28. {sawnergy-1.0.2 → sawnergy-1.0.4}/tests/test_rin.py +0 -0
  29. {sawnergy-1.0.2 → sawnergy-1.0.4}/tests/test_storage.py +0 -0
  30. {sawnergy-1.0.2 → sawnergy-1.0.4}/tests/test_visual.py +0 -0
  31. {sawnergy-1.0.2 → sawnergy-1.0.4}/tests/test_walks.py +0 -0
@@ -1,10 +1,12 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sawnergy
3
- Version: 1.0.2
3
+ Version: 1.0.4
4
4
  Summary: Toolkit for transforming molecular dynamics (MD) trajectories into rich graph representations
5
5
  Home-page: https://github.com/Yehor-Mishchyriak/SAWNERGY
6
6
  Author: Yehor Mishchyriak
7
7
  License: Apache-2.0
8
+ Project-URL: Source, https://github.com/Yehor-Mishchyriak/SAWNERGY
9
+ Project-URL: Tracker, https://github.com/Yehor-Mishchyriak/SAWNERGY/issues
8
10
  Classifier: Programming Language :: Python :: 3
9
11
  Classifier: License :: OSI Approved :: Apache Software License
10
12
  Classifier: Operating System :: OS Independent
@@ -25,12 +27,17 @@ Dynamic: description-content-type
25
27
  Dynamic: home-page
26
28
  Dynamic: license
27
29
  Dynamic: license-file
30
+ Dynamic: project-url
28
31
  Dynamic: requires-dist
29
32
  Dynamic: requires-python
30
33
  Dynamic: summary
31
34
 
32
35
  # SAWNERGY
33
36
 
37
+ [![PyPI](https://img.shields.io/pypi/v/sawnergy)](https://pypi.org/project/sawnergy/)
38
+ [![License](https://img.shields.io/badge/license-Apache--2.0-blue)](https://github.com/Yehor-Mishchyriak/SAWNERGY/blob/main/LICENSE)
39
+ ![Python](https://img.shields.io/badge/python-3.11%2B-blue)
40
+
34
41
  A toolkit for transforming molecular dynamics (MD) trajectories into rich graph representations, sampling
35
42
  random and self-avoiding walks, learning node embeddings, and visualising residue interaction networks (RINs). SAWNERGY
36
43
  keeps the full workflow — from `cpptraj` output to skip-gram embeddings (node2vec approach) — inside Python, backed by efficient Zarr-based archives and optional GPU acceleration.
@@ -72,8 +79,8 @@ node indexing, and RNG seeds stay consistent across the toolchain.
72
79
  ---
73
80
 
74
81
  ## Small visual example (constructed fully from trajectory and topology files)
75
- ![rin](https://github.com/Yehor-Mishchyriak/SAWNERGY/blob/main/assets/rin.png)
76
- ![embedding](https://github.com/Yehor-Mishchyriak/SAWNERGY/blob/main/assets/embedding.png)
82
+ ![RIN](https://raw.githubusercontent.com/Yehor-Mishchyriak/SAWNERGY/main/assets/rin.png)
83
+ ![Embedding](https://raw.githubusercontent.com/Yehor-Mishchyriak/SAWNERGY/main/assets/embedding.png)
77
84
 
78
85
  ---
79
86
 
@@ -1,5 +1,9 @@
1
1
  # SAWNERGY
2
2
 
3
+ [![PyPI](https://img.shields.io/pypi/v/sawnergy)](https://pypi.org/project/sawnergy/)
4
+ [![License](https://img.shields.io/badge/license-Apache--2.0-blue)](https://github.com/Yehor-Mishchyriak/SAWNERGY/blob/main/LICENSE)
5
+ ![Python](https://img.shields.io/badge/python-3.11%2B-blue)
6
+
3
7
  A toolkit for transforming molecular dynamics (MD) trajectories into rich graph representations, sampling
4
8
  random and self-avoiding walks, learning node embeddings, and visualising residue interaction networks (RINs). SAWNERGY
5
9
  keeps the full workflow — from `cpptraj` output to skip-gram embeddings (node2vec approach) — inside Python, backed by efficient Zarr-based archives and optional GPU acceleration.
@@ -41,8 +45,8 @@ node indexing, and RNG seeds stay consistent across the toolchain.
41
45
  ---
42
46
 
43
47
  ## Small visual example (constructed fully from trajectory and topology files)
44
- ![rin](https://github.com/Yehor-Mishchyriak/SAWNERGY/blob/main/assets/rin.png)
45
- ![embedding](https://github.com/Yehor-Mishchyriak/SAWNERGY/blob/main/assets/embedding.png)
48
+ ![RIN](https://raw.githubusercontent.com/Yehor-Mishchyriak/SAWNERGY/main/assets/rin.png)
49
+ ![Embedding](https://raw.githubusercontent.com/Yehor-Mishchyriak/SAWNERGY/main/assets/embedding.png)
46
50
 
47
51
  ---
48
52
 
@@ -690,9 +690,9 @@ class RINBuilder:
690
690
 
691
691
  2. For each frame batch:
692
692
 
693
- a) Run cpptraj `pairwise` on atoms → EMAP + VMAP → sum (atomic matrix).
693
+ a) Run cpptraj 'pairwise' on atoms → EMAP + VMAP → sum (atomic matrix).
694
694
 
695
- b) Project atomic → residue with ``R = Pᵀ @ A @ P``.
695
+ b) Project atomic → residue with 'R = Pᵀ @ A @ P'.
696
696
 
697
697
  c) Post-process residue matrix:
698
698
  split into (attractive, repulsive) channels,
@@ -700,7 +700,7 @@ class RINBuilder:
700
700
  remove self-interactions,
701
701
  symmetrize.
702
702
 
703
- d. Optionally store **pre-normalized energies** (attractive or repulsive or both, depending on `include_<kind>`).
703
+ d. Optionally store **pre-normalized energies** (attractive or repulsive or both, depending on 'include_<kind>').
704
704
 
705
705
  e. Row-wise L1 normalize (directed transition probabilities) and store.
706
706
 
@@ -63,7 +63,7 @@ class Walker:
63
63
 
64
64
  # Load numpy arrays from read-only storage
65
65
  with sawnergy_util.ArrayStorage(RIN_path, mode="r") as storage:
66
- attr_name = storage.get_attr("attractive_transitions_name")
66
+ attr_name = storage.get_attr("attractive_transitions_name")
67
67
  repuls_name = storage.get_attr("repulsive_transitions_name")
68
68
  attr_matrices : np.ndarray | None = (
69
69
  storage.read(attr_name, slice(None)) if attr_name is not None else None
@@ -133,6 +133,9 @@ class Walker:
133
133
  ) if repuls_matrices is not None else None
134
134
  )
135
135
 
136
+ self._attr_owner_pid = os.getpid() if self.attr_matrices is not None else None
137
+ self._repuls_owner_pid = os.getpid() if self.repuls_matrices is not None else None
138
+
136
139
  _logger.debug(
137
140
  "SharedNDArray created | attr name=%r; repuls name=%r",
138
141
  getattr(self.attr_matrices, "name", None),
@@ -159,38 +162,56 @@ class Walker:
159
162
 
160
163
  # explicit resource cleanup
161
164
  def close(self) -> None:
162
- """Close shared-memory handles and (in main process) unlink segments.
165
+ """Release shared-memory resources used by this Walker.
166
+
167
+ This method:
168
+ - Closes local handles to the shared-memory backed arrays
169
+ (`self.attr_matrices`, `self.repuls_matrices`) in **the current process**.
170
+ - If the current process is the **creator** of a segment (its PID matches
171
+ `_attr_owner_pid` / `_repuls_owner_pid`), it also **unlinks** that segment
172
+ so the OS can reclaim it once all handles are closed.
173
+
174
+ Behavior & guarantees
175
+ ---------------------
176
+ - **Idempotent:** safe to call multiple times; subsequent calls are no-ops.
177
+ - **Multi-process aware:** non-creator processes only close their handles;
178
+ creators close **and** unlink. This prevents `resource_tracker` “leaked
179
+ shared_memory” warnings when using `ProcessPoolExecutor`/spawn.
180
+ - **Best-effort unlink:** `FileNotFoundError` during unlink (already unlinked
181
+ elsewhere) is swallowed.
182
+ - Invoked automatically by the context manager (`__exit__`) and destructor
183
+ (`__del__`), but it's fine to call explicitly.
184
+
185
+ After calling `close()`, any operation that relies on the shared arrays may
186
+ fail; treat the instance as finalized.
163
187
 
164
- Idempotent: if cleanup already occurred, returns immediately. Always
165
- closes local handles in the current process. If the caller is the main
166
- process (per ``sawnergy_util.is_main_process()``), also attempts to
167
- unlink the underlying shared-memory segments (best-effort; suppresses
168
- ``FileNotFoundError`` if already unlinked elsewhere).
188
+ Returns:
189
+ None
169
190
  """
170
191
  if self._memory_cleaned_up:
171
192
  _logger.debug("close(): already cleaned up; returning")
172
193
  return
173
- _logger.debug("Closing Walker resources (is_main=%s)", sawnergy_util.is_main_process())
194
+ _logger.debug("Closing Walker resources (pid=%s)", os.getpid())
174
195
  try:
175
196
  if self.attr_matrices is not None:
176
197
  self.attr_matrices.close()
177
198
  if self.repuls_matrices is not None:
178
199
  self.repuls_matrices.close()
179
200
  _logger.debug("SharedNDArray handles closed")
180
- if sawnergy_util.is_main_process():
181
- _logger.debug("Attempting to unlink shared memory segments (main process)")
182
- try:
183
- if self.attr_matrices is not None:
184
- self.attr_matrices.unlink()
185
- except FileNotFoundError:
186
- _logger.warning("attr SharedMemory already unlinked")
187
- try:
188
- if self.repuls_matrices is not None:
189
- self.repuls_matrices.unlink()
190
- except FileNotFoundError:
191
- _logger.warning("repuls SharedMemory already unlinked")
192
- else:
193
- _logger.debug("Not main process; skipping unlink")
201
+
202
+ # Unlink in whichever process actually CREATED the segment(s)
203
+ try:
204
+ if self.attr_matrices is not None and getattr(self, "_attr_owner_pid", None) == os.getpid():
205
+ self.attr_matrices.unlink()
206
+ except FileNotFoundError:
207
+ _logger.debug("attr SharedMemory already unlinked elsewhere")
208
+
209
+ try:
210
+ if self.repuls_matrices is not None and getattr(self, "_repuls_owner_pid", None) == os.getpid():
211
+ self.repuls_matrices.unlink()
212
+ except FileNotFoundError:
213
+ _logger.debug("repuls SharedMemory already unlinked elsewhere")
214
+
194
215
  finally:
195
216
  self._memory_cleaned_up = True
196
217
  _logger.debug("Cleanup complete")
@@ -1,10 +1,12 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sawnergy
3
- Version: 1.0.2
3
+ Version: 1.0.4
4
4
  Summary: Toolkit for transforming molecular dynamics (MD) trajectories into rich graph representations
5
5
  Home-page: https://github.com/Yehor-Mishchyriak/SAWNERGY
6
6
  Author: Yehor Mishchyriak
7
7
  License: Apache-2.0
8
+ Project-URL: Source, https://github.com/Yehor-Mishchyriak/SAWNERGY
9
+ Project-URL: Tracker, https://github.com/Yehor-Mishchyriak/SAWNERGY/issues
8
10
  Classifier: Programming Language :: Python :: 3
9
11
  Classifier: License :: OSI Approved :: Apache Software License
10
12
  Classifier: Operating System :: OS Independent
@@ -25,12 +27,17 @@ Dynamic: description-content-type
25
27
  Dynamic: home-page
26
28
  Dynamic: license
27
29
  Dynamic: license-file
30
+ Dynamic: project-url
28
31
  Dynamic: requires-dist
29
32
  Dynamic: requires-python
30
33
  Dynamic: summary
31
34
 
32
35
  # SAWNERGY
33
36
 
37
+ [![PyPI](https://img.shields.io/pypi/v/sawnergy)](https://pypi.org/project/sawnergy/)
38
+ [![License](https://img.shields.io/badge/license-Apache--2.0-blue)](https://github.com/Yehor-Mishchyriak/SAWNERGY/blob/main/LICENSE)
39
+ ![Python](https://img.shields.io/badge/python-3.11%2B-blue)
40
+
34
41
  A toolkit for transforming molecular dynamics (MD) trajectories into rich graph representations, sampling
35
42
  random and self-avoiding walks, learning node embeddings, and visualising residue interaction networks (RINs). SAWNERGY
36
43
  keeps the full workflow — from `cpptraj` output to skip-gram embeddings (node2vec approach) — inside Python, backed by efficient Zarr-based archives and optional GPU acceleration.
@@ -72,8 +79,8 @@ node indexing, and RNG seeds stay consistent across the toolchain.
72
79
  ---
73
80
 
74
81
  ## Small visual example (constructed fully from trajectory and topology files)
75
- ![rin](https://github.com/Yehor-Mishchyriak/SAWNERGY/blob/main/assets/rin.png)
76
- ![embedding](https://github.com/Yehor-Mishchyriak/SAWNERGY/blob/main/assets/embedding.png)
82
+ ![RIN](https://raw.githubusercontent.com/Yehor-Mishchyriak/SAWNERGY/main/assets/rin.png)
83
+ ![Embedding](https://raw.githubusercontent.com/Yehor-Mishchyriak/SAWNERGY/main/assets/embedding.png)
77
84
 
78
85
  ---
79
86
 
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes