adaptivepy-sampling 0.1.0__tar.gz → 0.1.2__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.
- adaptivepy_sampling-0.1.2/PKG-INFO +108 -0
- adaptivepy_sampling-0.1.2/README.md +88 -0
- {adaptivepy_sampling-0.1.0 → adaptivepy_sampling-0.1.2}/adaptivepy/__init__.py +1 -1
- {adaptivepy_sampling-0.1.0 → adaptivepy_sampling-0.1.2}/adaptivepy/api.py +3 -4
- {adaptivepy_sampling-0.1.0 → adaptivepy_sampling-0.1.2}/adaptivepy/config/schema.py +1 -1
- {adaptivepy_sampling-0.1.0 → adaptivepy_sampling-0.1.2}/adaptivepy/io/__init__.py +4 -0
- {adaptivepy_sampling-0.1.0 → adaptivepy_sampling-0.1.2}/adaptivepy/io/loader.py +68 -9
- adaptivepy_sampling-0.1.2/adaptivepy_sampling.egg-info/PKG-INFO +108 -0
- {adaptivepy_sampling-0.1.0 → adaptivepy_sampling-0.1.2}/adaptivepy_sampling.egg-info/requires.txt +4 -0
- {adaptivepy_sampling-0.1.0 → adaptivepy_sampling-0.1.2}/pyproject.toml +5 -1
- {adaptivepy_sampling-0.1.0 → adaptivepy_sampling-0.1.2}/tests/test_adaptivepy.py +18 -0
- adaptivepy_sampling-0.1.0/PKG-INFO +0 -52
- adaptivepy_sampling-0.1.0/README.md +0 -35
- adaptivepy_sampling-0.1.0/adaptivepy_sampling.egg-info/PKG-INFO +0 -52
- {adaptivepy_sampling-0.1.0 → adaptivepy_sampling-0.1.2}/adaptivepy/cli/__init__.py +0 -0
- {adaptivepy_sampling-0.1.0 → adaptivepy_sampling-0.1.2}/adaptivepy/cli/run.py +0 -0
- {adaptivepy_sampling-0.1.0 → adaptivepy_sampling-0.1.2}/adaptivepy/clustering/__init__.py +0 -0
- {adaptivepy_sampling-0.1.0 → adaptivepy_sampling-0.1.2}/adaptivepy/clustering/base.py +0 -0
- {adaptivepy_sampling-0.1.0 → adaptivepy_sampling-0.1.2}/adaptivepy/clustering/regular_space.py +0 -0
- {adaptivepy_sampling-0.1.0 → adaptivepy_sampling-0.1.2}/adaptivepy/clustering/sklearn_kmeans.py +0 -0
- {adaptivepy_sampling-0.1.0 → adaptivepy_sampling-0.1.2}/adaptivepy/clustering/sklearn_minibatch.py +0 -0
- {adaptivepy_sampling-0.1.0 → adaptivepy_sampling-0.1.2}/adaptivepy/config/__init__.py +0 -0
- {adaptivepy_sampling-0.1.0 → adaptivepy_sampling-0.1.2}/adaptivepy/io/trajectory.py +0 -0
- {adaptivepy_sampling-0.1.0 → adaptivepy_sampling-0.1.2}/adaptivepy/models.py +0 -0
- {adaptivepy_sampling-0.1.0 → adaptivepy_sampling-0.1.2}/adaptivepy/output/__init__.py +0 -0
- {adaptivepy_sampling-0.1.0 → adaptivepy_sampling-0.1.2}/adaptivepy/output/pdb_writer.py +0 -0
- {adaptivepy_sampling-0.1.0 → adaptivepy_sampling-0.1.2}/adaptivepy/output/writer.py +0 -0
- {adaptivepy_sampling-0.1.0 → adaptivepy_sampling-0.1.2}/adaptivepy/policies/__init__.py +0 -0
- {adaptivepy_sampling-0.1.0 → adaptivepy_sampling-0.1.2}/adaptivepy/policies/base.py +0 -0
- {adaptivepy_sampling-0.1.0 → adaptivepy_sampling-0.1.2}/adaptivepy/policies/least_counts.py +0 -0
- {adaptivepy_sampling-0.1.0 → adaptivepy_sampling-0.1.2}/adaptivepy/policies/random.py +0 -0
- {adaptivepy_sampling-0.1.0 → adaptivepy_sampling-0.1.2}/adaptivepy/selection/__init__.py +0 -0
- {adaptivepy_sampling-0.1.0 → adaptivepy_sampling-0.1.2}/adaptivepy/selection/frame_selector.py +0 -0
- {adaptivepy_sampling-0.1.0 → adaptivepy_sampling-0.1.2}/adaptivepy/stats/__init__.py +0 -0
- {adaptivepy_sampling-0.1.0 → adaptivepy_sampling-0.1.2}/adaptivepy/stats/cluster_stats.py +0 -0
- {adaptivepy_sampling-0.1.0 → adaptivepy_sampling-0.1.2}/adaptivepy/utils/__init__.py +0 -0
- {adaptivepy_sampling-0.1.0 → adaptivepy_sampling-0.1.2}/adaptivepy/utils/io_utils.py +0 -0
- {adaptivepy_sampling-0.1.0 → adaptivepy_sampling-0.1.2}/adaptivepy/utils/logging.py +0 -0
- {adaptivepy_sampling-0.1.0 → adaptivepy_sampling-0.1.2}/adaptivepy_sampling.egg-info/SOURCES.txt +0 -0
- {adaptivepy_sampling-0.1.0 → adaptivepy_sampling-0.1.2}/adaptivepy_sampling.egg-info/dependency_links.txt +0 -0
- {adaptivepy_sampling-0.1.0 → adaptivepy_sampling-0.1.2}/adaptivepy_sampling.egg-info/entry_points.txt +0 -0
- {adaptivepy_sampling-0.1.0 → adaptivepy_sampling-0.1.2}/adaptivepy_sampling.egg-info/top_level.txt +0 -0
- {adaptivepy_sampling-0.1.0 → adaptivepy_sampling-0.1.2}/setup.cfg +0 -0
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: adaptivepy-sampling
|
|
3
|
+
Version: 0.1.2
|
|
4
|
+
Summary: Adaptive sampling on MD trajectories via clustering and policy-driven seed selection
|
|
5
|
+
Author: AdaptivePy Contributors
|
|
6
|
+
License: MIT
|
|
7
|
+
Requires-Python: >=3.9
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
Requires-Dist: numpy>=1.20
|
|
10
|
+
Requires-Dist: scikit-learn>=1.0
|
|
11
|
+
Requires-Dist: pyyaml>=6.0
|
|
12
|
+
Requires-Dist: click>=8.0
|
|
13
|
+
Requires-Dist: joblib>=1.0
|
|
14
|
+
Requires-Dist: mdtraj>=1.9
|
|
15
|
+
Provides-Extra: dev
|
|
16
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
17
|
+
Provides-Extra: docs
|
|
18
|
+
Requires-Dist: mkdocs-material>=9.0; extra == "docs"
|
|
19
|
+
Requires-Dist: mkdocstrings[python]>=0.24; extra == "docs"
|
|
20
|
+
|
|
21
|
+
# AdaptivePy
|
|
22
|
+
|
|
23
|
+
**Adaptive sampling for molecular dynamics trajectories**
|
|
24
|
+
|
|
25
|
+
Clustering-based state space partitioning and policy-driven seed selection for MD workflows.
|
|
26
|
+
|
|
27
|
+
[](https://hnadeem2.github.io/AdaptivePy/)
|
|
28
|
+
[](https://pypi.org/project/adaptivepy-sampling/)
|
|
29
|
+
[](https://www.python.org/)
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Overview
|
|
34
|
+
|
|
35
|
+
AdaptivePy helps you identify under-sampled regions of conformational space and select seed frames for new simulations. It loads per-trajectory feature arrays, clusters frames, applies adaptive policies, and writes reproducible metadata and optional PDB structures.
|
|
36
|
+
|
|
37
|
+
**Full documentation:** [https://hnadeem2.github.io/AdaptivePy/](https://hnadeem2.github.io/AdaptivePy/)
|
|
38
|
+
|
|
39
|
+
| | |
|
|
40
|
+
|---|---|
|
|
41
|
+
| **Input** | Feature arrays (`.npy` / `.pkl`), optional coordinate trajectories |
|
|
42
|
+
| **Clustering** | KMeans, MiniBatch KMeans, regular-space |
|
|
43
|
+
| **Policies** | Least counts, random (extensible) |
|
|
44
|
+
| **Output** | Seeds, cluster assignments, model, logs, optional PDBs |
|
|
45
|
+
|
|
46
|
+
## Installation
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
pip install adaptivepy-sampling
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
For development:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
git clone https://github.com/hnadeem2/AdaptivePy.git
|
|
56
|
+
cd AdaptivePy
|
|
57
|
+
pip install -e ".[dev,docs]"
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Quick start
|
|
61
|
+
|
|
62
|
+
1. **Prepare features** — one file per trajectory, shape `(n_frames, n_features)`:
|
|
63
|
+
|
|
64
|
+
```text
|
|
65
|
+
features/
|
|
66
|
+
├── traj_0.npy
|
|
67
|
+
└── traj_1.pkl
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
2. **Configure** — edit `examples/config.yaml` (or create your own).
|
|
71
|
+
|
|
72
|
+
3. **Run**:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
adaptivepy run examples/config.yaml
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
See the [Getting Started guide](https://hnadeem2.github.io/AdaptivePy/getting-started/) for a complete walkthrough.
|
|
79
|
+
|
|
80
|
+
## CLI
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
adaptivepy run config.yaml # run adaptive sampling
|
|
84
|
+
adaptivepy validate config.yaml # validate inputs only
|
|
85
|
+
adaptivepy list-policies # list available policies
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Python API
|
|
89
|
+
|
|
90
|
+
```python
|
|
91
|
+
from adaptivepy import run_adaptive_sampling
|
|
92
|
+
|
|
93
|
+
results = run_adaptive_sampling("config.yaml")
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Documentation
|
|
97
|
+
|
|
98
|
+
| Guide | Description |
|
|
99
|
+
|-------|-------------|
|
|
100
|
+
| [Getting Started](https://hnadeem2.github.io/AdaptivePy/getting-started/) | First run in minutes |
|
|
101
|
+
| [Configuration](https://hnadeem2.github.io/AdaptivePy/configuration/) | YAML options and defaults |
|
|
102
|
+
| [Feature Inputs](https://hnadeem2.github.io/AdaptivePy/features/) | File formats and layout |
|
|
103
|
+
| [Policies](https://hnadeem2.github.io/AdaptivePy/policies/) | Seed selection strategies |
|
|
104
|
+
| [API Reference](https://hnadeem2.github.io/AdaptivePy/reference/api/) | Module documentation |
|
|
105
|
+
|
|
106
|
+
## License
|
|
107
|
+
|
|
108
|
+
MIT
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# AdaptivePy
|
|
2
|
+
|
|
3
|
+
**Adaptive sampling for molecular dynamics trajectories**
|
|
4
|
+
|
|
5
|
+
Clustering-based state space partitioning and policy-driven seed selection for MD workflows.
|
|
6
|
+
|
|
7
|
+
[](https://hnadeem2.github.io/AdaptivePy/)
|
|
8
|
+
[](https://pypi.org/project/adaptivepy-sampling/)
|
|
9
|
+
[](https://www.python.org/)
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Overview
|
|
14
|
+
|
|
15
|
+
AdaptivePy helps you identify under-sampled regions of conformational space and select seed frames for new simulations. It loads per-trajectory feature arrays, clusters frames, applies adaptive policies, and writes reproducible metadata and optional PDB structures.
|
|
16
|
+
|
|
17
|
+
**Full documentation:** [https://hnadeem2.github.io/AdaptivePy/](https://hnadeem2.github.io/AdaptivePy/)
|
|
18
|
+
|
|
19
|
+
| | |
|
|
20
|
+
|---|---|
|
|
21
|
+
| **Input** | Feature arrays (`.npy` / `.pkl`), optional coordinate trajectories |
|
|
22
|
+
| **Clustering** | KMeans, MiniBatch KMeans, regular-space |
|
|
23
|
+
| **Policies** | Least counts, random (extensible) |
|
|
24
|
+
| **Output** | Seeds, cluster assignments, model, logs, optional PDBs |
|
|
25
|
+
|
|
26
|
+
## Installation
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
pip install adaptivepy-sampling
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
For development:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
git clone https://github.com/hnadeem2/AdaptivePy.git
|
|
36
|
+
cd AdaptivePy
|
|
37
|
+
pip install -e ".[dev,docs]"
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Quick start
|
|
41
|
+
|
|
42
|
+
1. **Prepare features** — one file per trajectory, shape `(n_frames, n_features)`:
|
|
43
|
+
|
|
44
|
+
```text
|
|
45
|
+
features/
|
|
46
|
+
├── traj_0.npy
|
|
47
|
+
└── traj_1.pkl
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
2. **Configure** — edit `examples/config.yaml` (or create your own).
|
|
51
|
+
|
|
52
|
+
3. **Run**:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
adaptivepy run examples/config.yaml
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
See the [Getting Started guide](https://hnadeem2.github.io/AdaptivePy/getting-started/) for a complete walkthrough.
|
|
59
|
+
|
|
60
|
+
## CLI
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
adaptivepy run config.yaml # run adaptive sampling
|
|
64
|
+
adaptivepy validate config.yaml # validate inputs only
|
|
65
|
+
adaptivepy list-policies # list available policies
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Python API
|
|
69
|
+
|
|
70
|
+
```python
|
|
71
|
+
from adaptivepy import run_adaptive_sampling
|
|
72
|
+
|
|
73
|
+
results = run_adaptive_sampling("config.yaml")
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Documentation
|
|
77
|
+
|
|
78
|
+
| Guide | Description |
|
|
79
|
+
|-------|-------------|
|
|
80
|
+
| [Getting Started](https://hnadeem2.github.io/AdaptivePy/getting-started/) | First run in minutes |
|
|
81
|
+
| [Configuration](https://hnadeem2.github.io/AdaptivePy/configuration/) | YAML options and defaults |
|
|
82
|
+
| [Feature Inputs](https://hnadeem2.github.io/AdaptivePy/features/) | File formats and layout |
|
|
83
|
+
| [Policies](https://hnadeem2.github.io/AdaptivePy/policies/) | Seed selection strategies |
|
|
84
|
+
| [API Reference](https://hnadeem2.github.io/AdaptivePy/reference/api/) | Module documentation |
|
|
85
|
+
|
|
86
|
+
## License
|
|
87
|
+
|
|
88
|
+
MIT
|
|
@@ -11,6 +11,7 @@ import numpy as np
|
|
|
11
11
|
from adaptivepy.clustering import create_clusterer, fit_clusterer
|
|
12
12
|
from adaptivepy.config.schema import RunConfig, load_config
|
|
13
13
|
from adaptivepy.io.loader import (
|
|
14
|
+
list_feature_files,
|
|
14
15
|
list_trajectory_files,
|
|
15
16
|
load_features,
|
|
16
17
|
validate_dataset,
|
|
@@ -84,7 +85,7 @@ def run_adaptive_sampling(
|
|
|
84
85
|
np.random.seed(config.random_seed)
|
|
85
86
|
|
|
86
87
|
# --- Load and validate data ---
|
|
87
|
-
feature_files =
|
|
88
|
+
feature_files = list_feature_files(config.features_dir)
|
|
88
89
|
trajectory_files: Optional[List[Path]] = None
|
|
89
90
|
trajectory_map: Optional[Dict[int, Path]] = None
|
|
90
91
|
|
|
@@ -199,9 +200,7 @@ def validate_config(config_path: str | Path) -> RunConfig:
|
|
|
199
200
|
config_path = Path(config_path)
|
|
200
201
|
config = load_config(config_path)
|
|
201
202
|
|
|
202
|
-
feature_files =
|
|
203
|
-
if not feature_files:
|
|
204
|
-
raise ValueError(f"No feature files in {config.features_dir}")
|
|
203
|
+
feature_files = list_feature_files(config.features_dir)
|
|
205
204
|
|
|
206
205
|
trajectory_files = None
|
|
207
206
|
if config.trajectories_dir is not None:
|
|
@@ -55,7 +55,7 @@ class RunConfig:
|
|
|
55
55
|
Attributes
|
|
56
56
|
----------
|
|
57
57
|
features_dir : Path
|
|
58
|
-
Directory containing ``*.npy`` feature files.
|
|
58
|
+
Directory containing ``*.npy`` or ``*.pkl`` feature files.
|
|
59
59
|
output_dir : Path
|
|
60
60
|
Directory where results are written.
|
|
61
61
|
trajectories_dir : Path or None
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
"""Input/output utilities for AdaptivePy."""
|
|
2
2
|
|
|
3
3
|
from adaptivepy.io.loader import (
|
|
4
|
+
FEATURE_EXTENSIONS,
|
|
4
5
|
list_feature_files,
|
|
5
6
|
list_trajectory_files,
|
|
7
|
+
load_feature_array,
|
|
6
8
|
load_features,
|
|
7
9
|
validate_dataset,
|
|
8
10
|
validate_feature_trajectory_mapping,
|
|
@@ -15,10 +17,12 @@ from adaptivepy.io.trajectory import (
|
|
|
15
17
|
)
|
|
16
18
|
|
|
17
19
|
__all__ = [
|
|
20
|
+
"FEATURE_EXTENSIONS",
|
|
18
21
|
"build_trajectory_map",
|
|
19
22
|
"extract_frame",
|
|
20
23
|
"list_feature_files",
|
|
21
24
|
"list_trajectory_files",
|
|
25
|
+
"load_feature_array",
|
|
22
26
|
"load_features",
|
|
23
27
|
"load_trajectory",
|
|
24
28
|
"validate_dataset",
|
|
@@ -6,15 +6,18 @@ import logging
|
|
|
6
6
|
from pathlib import Path
|
|
7
7
|
from typing import Dict, List, Optional, Tuple
|
|
8
8
|
|
|
9
|
+
import joblib
|
|
9
10
|
import numpy as np
|
|
10
11
|
|
|
11
12
|
from adaptivepy.models import Dataset, FrameRecord
|
|
12
13
|
|
|
13
14
|
logger = logging.getLogger(__name__)
|
|
14
15
|
|
|
16
|
+
FEATURE_EXTENSIONS = (".npy", ".pkl")
|
|
17
|
+
|
|
15
18
|
|
|
16
19
|
def list_feature_files(features_dir: Path) -> List[Path]:
|
|
17
|
-
"""List ``*.npy`` feature files in a directory, sorted by
|
|
20
|
+
"""List ``*.npy`` and ``*.pkl`` feature files in a directory, sorted by stem.
|
|
18
21
|
|
|
19
22
|
Parameters
|
|
20
23
|
----------
|
|
@@ -24,25 +27,80 @@ def list_feature_files(features_dir: Path) -> List[Path]:
|
|
|
24
27
|
Returns
|
|
25
28
|
-------
|
|
26
29
|
list of Path
|
|
27
|
-
Sorted paths to feature files.
|
|
30
|
+
Sorted paths to feature files (one file per trajectory stem).
|
|
28
31
|
|
|
29
32
|
Raises
|
|
30
33
|
------
|
|
31
34
|
FileNotFoundError
|
|
32
35
|
If the directory does not exist.
|
|
33
36
|
ValueError
|
|
34
|
-
If no
|
|
37
|
+
If no supported feature files are found or duplicate stems exist.
|
|
35
38
|
"""
|
|
36
39
|
features_dir = Path(features_dir)
|
|
37
40
|
if not features_dir.is_dir():
|
|
38
41
|
raise FileNotFoundError(f"Features directory not found: {features_dir}")
|
|
39
42
|
|
|
40
|
-
|
|
43
|
+
files_by_stem: Dict[str, Path] = {}
|
|
44
|
+
for path in sorted(features_dir.iterdir()):
|
|
45
|
+
if not path.is_file():
|
|
46
|
+
continue
|
|
47
|
+
suffix = path.suffix.lower()
|
|
48
|
+
if suffix not in FEATURE_EXTENSIONS:
|
|
49
|
+
continue
|
|
50
|
+
stem = path.stem
|
|
51
|
+
if stem in files_by_stem:
|
|
52
|
+
raise ValueError(
|
|
53
|
+
f"Duplicate feature files for '{stem}': "
|
|
54
|
+
f"{files_by_stem[stem].name} and {path.name}"
|
|
55
|
+
)
|
|
56
|
+
files_by_stem[stem] = path
|
|
57
|
+
|
|
58
|
+
files = [files_by_stem[stem] for stem in sorted(files_by_stem)]
|
|
41
59
|
if not files:
|
|
42
|
-
raise ValueError(
|
|
60
|
+
raise ValueError(
|
|
61
|
+
f"No .npy or .pkl feature files found in {features_dir}"
|
|
62
|
+
)
|
|
43
63
|
return files
|
|
44
64
|
|
|
45
65
|
|
|
66
|
+
def load_feature_array(path: Path) -> np.ndarray:
|
|
67
|
+
"""Load a feature array from a ``.npy`` or ``.pkl`` file.
|
|
68
|
+
|
|
69
|
+
Parameters
|
|
70
|
+
----------
|
|
71
|
+
path : Path
|
|
72
|
+
Path to a feature file.
|
|
73
|
+
|
|
74
|
+
Returns
|
|
75
|
+
-------
|
|
76
|
+
np.ndarray
|
|
77
|
+
Loaded feature array.
|
|
78
|
+
|
|
79
|
+
Raises
|
|
80
|
+
------
|
|
81
|
+
ValueError
|
|
82
|
+
If the file extension is unsupported or the loaded object cannot be
|
|
83
|
+
converted to an array.
|
|
84
|
+
"""
|
|
85
|
+
suffix = path.suffix.lower()
|
|
86
|
+
if suffix == ".npy":
|
|
87
|
+
data = np.load(path)
|
|
88
|
+
elif suffix == ".pkl":
|
|
89
|
+
data = joblib.load(path)
|
|
90
|
+
else:
|
|
91
|
+
raise ValueError(
|
|
92
|
+
f"Unsupported feature file extension '{suffix}' in {path}. "
|
|
93
|
+
f"Use one of: {', '.join(FEATURE_EXTENSIONS)}"
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
try:
|
|
97
|
+
return np.asarray(data)
|
|
98
|
+
except (TypeError, ValueError) as exc:
|
|
99
|
+
raise ValueError(
|
|
100
|
+
f"Feature file {path} does not contain a numeric array."
|
|
101
|
+
) from exc
|
|
102
|
+
|
|
103
|
+
|
|
46
104
|
def list_trajectory_files(trajectories_dir: Path) -> List[Path]:
|
|
47
105
|
"""List coordinate trajectory files supported by mdtraj.
|
|
48
106
|
|
|
@@ -96,7 +154,7 @@ def validate_feature_trajectory_mapping(
|
|
|
96
154
|
Parameters
|
|
97
155
|
----------
|
|
98
156
|
feature_files : list of Path
|
|
99
|
-
Feature ``.npy`` file paths.
|
|
157
|
+
Feature ``.npy`` or ``.pkl`` file paths.
|
|
100
158
|
trajectory_files : list of Path or None
|
|
101
159
|
Optional coordinate trajectory file paths.
|
|
102
160
|
|
|
@@ -130,8 +188,9 @@ def validate_feature_trajectory_mapping(
|
|
|
130
188
|
def load_features(features_dir: Path) -> Dataset:
|
|
131
189
|
"""Load feature arrays from disk and build a :class:`Dataset`.
|
|
132
190
|
|
|
133
|
-
Each ``*.npy`` file must have shape ``(n_frames, n_features)``.
|
|
134
|
-
``FrameRecord`` objects are created while preserving trajectory
|
|
191
|
+
Each ``*.npy`` or ``*.pkl`` file must have shape ``(n_frames, n_features)``.
|
|
192
|
+
Per-frame ``FrameRecord`` objects are created while preserving trajectory
|
|
193
|
+
identity.
|
|
135
194
|
|
|
136
195
|
Parameters
|
|
137
196
|
----------
|
|
@@ -157,7 +216,7 @@ def load_features(features_dir: Path) -> Dataset:
|
|
|
157
216
|
n_features: Optional[int] = None
|
|
158
217
|
|
|
159
218
|
for traj_id, feature_path in enumerate(feature_files):
|
|
160
|
-
features =
|
|
219
|
+
features = load_feature_array(feature_path)
|
|
161
220
|
if features.ndim != 2:
|
|
162
221
|
raise ValueError(
|
|
163
222
|
f"Feature file {feature_path} must be 2D (n_frames, n_features), "
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: adaptivepy-sampling
|
|
3
|
+
Version: 0.1.2
|
|
4
|
+
Summary: Adaptive sampling on MD trajectories via clustering and policy-driven seed selection
|
|
5
|
+
Author: AdaptivePy Contributors
|
|
6
|
+
License: MIT
|
|
7
|
+
Requires-Python: >=3.9
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
Requires-Dist: numpy>=1.20
|
|
10
|
+
Requires-Dist: scikit-learn>=1.0
|
|
11
|
+
Requires-Dist: pyyaml>=6.0
|
|
12
|
+
Requires-Dist: click>=8.0
|
|
13
|
+
Requires-Dist: joblib>=1.0
|
|
14
|
+
Requires-Dist: mdtraj>=1.9
|
|
15
|
+
Provides-Extra: dev
|
|
16
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
17
|
+
Provides-Extra: docs
|
|
18
|
+
Requires-Dist: mkdocs-material>=9.0; extra == "docs"
|
|
19
|
+
Requires-Dist: mkdocstrings[python]>=0.24; extra == "docs"
|
|
20
|
+
|
|
21
|
+
# AdaptivePy
|
|
22
|
+
|
|
23
|
+
**Adaptive sampling for molecular dynamics trajectories**
|
|
24
|
+
|
|
25
|
+
Clustering-based state space partitioning and policy-driven seed selection for MD workflows.
|
|
26
|
+
|
|
27
|
+
[](https://hnadeem2.github.io/AdaptivePy/)
|
|
28
|
+
[](https://pypi.org/project/adaptivepy-sampling/)
|
|
29
|
+
[](https://www.python.org/)
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Overview
|
|
34
|
+
|
|
35
|
+
AdaptivePy helps you identify under-sampled regions of conformational space and select seed frames for new simulations. It loads per-trajectory feature arrays, clusters frames, applies adaptive policies, and writes reproducible metadata and optional PDB structures.
|
|
36
|
+
|
|
37
|
+
**Full documentation:** [https://hnadeem2.github.io/AdaptivePy/](https://hnadeem2.github.io/AdaptivePy/)
|
|
38
|
+
|
|
39
|
+
| | |
|
|
40
|
+
|---|---|
|
|
41
|
+
| **Input** | Feature arrays (`.npy` / `.pkl`), optional coordinate trajectories |
|
|
42
|
+
| **Clustering** | KMeans, MiniBatch KMeans, regular-space |
|
|
43
|
+
| **Policies** | Least counts, random (extensible) |
|
|
44
|
+
| **Output** | Seeds, cluster assignments, model, logs, optional PDBs |
|
|
45
|
+
|
|
46
|
+
## Installation
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
pip install adaptivepy-sampling
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
For development:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
git clone https://github.com/hnadeem2/AdaptivePy.git
|
|
56
|
+
cd AdaptivePy
|
|
57
|
+
pip install -e ".[dev,docs]"
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Quick start
|
|
61
|
+
|
|
62
|
+
1. **Prepare features** — one file per trajectory, shape `(n_frames, n_features)`:
|
|
63
|
+
|
|
64
|
+
```text
|
|
65
|
+
features/
|
|
66
|
+
├── traj_0.npy
|
|
67
|
+
└── traj_1.pkl
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
2. **Configure** — edit `examples/config.yaml` (or create your own).
|
|
71
|
+
|
|
72
|
+
3. **Run**:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
adaptivepy run examples/config.yaml
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
See the [Getting Started guide](https://hnadeem2.github.io/AdaptivePy/getting-started/) for a complete walkthrough.
|
|
79
|
+
|
|
80
|
+
## CLI
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
adaptivepy run config.yaml # run adaptive sampling
|
|
84
|
+
adaptivepy validate config.yaml # validate inputs only
|
|
85
|
+
adaptivepy list-policies # list available policies
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Python API
|
|
89
|
+
|
|
90
|
+
```python
|
|
91
|
+
from adaptivepy import run_adaptive_sampling
|
|
92
|
+
|
|
93
|
+
results = run_adaptive_sampling("config.yaml")
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Documentation
|
|
97
|
+
|
|
98
|
+
| Guide | Description |
|
|
99
|
+
|-------|-------------|
|
|
100
|
+
| [Getting Started](https://hnadeem2.github.io/AdaptivePy/getting-started/) | First run in minutes |
|
|
101
|
+
| [Configuration](https://hnadeem2.github.io/AdaptivePy/configuration/) | YAML options and defaults |
|
|
102
|
+
| [Feature Inputs](https://hnadeem2.github.io/AdaptivePy/features/) | File formats and layout |
|
|
103
|
+
| [Policies](https://hnadeem2.github.io/AdaptivePy/policies/) | Seed selection strategies |
|
|
104
|
+
| [API Reference](https://hnadeem2.github.io/AdaptivePy/reference/api/) | Module documentation |
|
|
105
|
+
|
|
106
|
+
## License
|
|
107
|
+
|
|
108
|
+
MIT
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "adaptivepy-sampling"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.2"
|
|
8
8
|
description = "Adaptive sampling on MD trajectories via clustering and policy-driven seed selection"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.9"
|
|
@@ -21,6 +21,10 @@ dependencies = [
|
|
|
21
21
|
|
|
22
22
|
[project.optional-dependencies]
|
|
23
23
|
dev = ["pytest>=7.0"]
|
|
24
|
+
docs = [
|
|
25
|
+
"mkdocs-material>=9.0",
|
|
26
|
+
"mkdocstrings[python]>=0.24",
|
|
27
|
+
]
|
|
24
28
|
|
|
25
29
|
[project.scripts]
|
|
26
30
|
adaptivepy = "adaptivepy.cli.run:main"
|
|
@@ -4,10 +4,12 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
from pathlib import Path
|
|
6
6
|
|
|
7
|
+
import joblib
|
|
7
8
|
import numpy as np
|
|
8
9
|
import pytest
|
|
9
10
|
|
|
10
11
|
from adaptivepy.api import run_adaptive_sampling, validate_config
|
|
12
|
+
from adaptivepy.io.loader import load_feature_array, load_features
|
|
11
13
|
from adaptivepy.policies import list_policies
|
|
12
14
|
|
|
13
15
|
|
|
@@ -61,6 +63,22 @@ write_pdbs: false
|
|
|
61
63
|
assert (output_dir / "combined_metadata.csv").is_file()
|
|
62
64
|
|
|
63
65
|
|
|
66
|
+
def test_load_pkl_features(tmp_path: Path) -> None:
|
|
67
|
+
"""Feature loading supports .pkl files with the same shape contract."""
|
|
68
|
+
features_dir = tmp_path / "features"
|
|
69
|
+
features_dir.mkdir()
|
|
70
|
+
rng = np.random.default_rng(1)
|
|
71
|
+
array = rng.normal(size=(25, 6))
|
|
72
|
+
joblib.dump(array, features_dir / "traj_0.pkl")
|
|
73
|
+
|
|
74
|
+
loaded = load_feature_array(features_dir / "traj_0.pkl")
|
|
75
|
+
np.testing.assert_array_equal(loaded, array)
|
|
76
|
+
|
|
77
|
+
dataset = load_features(features_dir)
|
|
78
|
+
assert dataset.feature_matrix.shape == (25, 6)
|
|
79
|
+
assert dataset.traj_names == ["traj_0"]
|
|
80
|
+
|
|
81
|
+
|
|
64
82
|
def test_validate_config(tmp_path: Path, synthetic_features: Path) -> None:
|
|
65
83
|
"""Validation succeeds for a well-formed configuration."""
|
|
66
84
|
config_path = tmp_path / "config.yaml"
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: adaptivepy-sampling
|
|
3
|
-
Version: 0.1.0
|
|
4
|
-
Summary: Adaptive sampling on MD trajectories via clustering and policy-driven seed selection
|
|
5
|
-
Author: AdaptivePy Contributors
|
|
6
|
-
License: MIT
|
|
7
|
-
Requires-Python: >=3.9
|
|
8
|
-
Description-Content-Type: text/markdown
|
|
9
|
-
Requires-Dist: numpy>=1.20
|
|
10
|
-
Requires-Dist: scikit-learn>=1.0
|
|
11
|
-
Requires-Dist: pyyaml>=6.0
|
|
12
|
-
Requires-Dist: click>=8.0
|
|
13
|
-
Requires-Dist: joblib>=1.0
|
|
14
|
-
Requires-Dist: mdtraj>=1.9
|
|
15
|
-
Provides-Extra: dev
|
|
16
|
-
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
17
|
-
|
|
18
|
-
# AdaptivePy
|
|
19
|
-
|
|
20
|
-
Adaptive sampling on molecular dynamics trajectories using clustering-based state space partitioning and policy-driven seed selection.
|
|
21
|
-
|
|
22
|
-
## Installation
|
|
23
|
-
|
|
24
|
-
```bash
|
|
25
|
-
pip install -e .
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
## Quick start
|
|
29
|
-
|
|
30
|
-
1. Prepare feature files (`features/traj_0.npy`, ...) with shape `(n_frames, n_features)`.
|
|
31
|
-
2. Optionally add matching coordinate trajectories (`trajectories/traj_0.xtc`, ...) and a topology file.
|
|
32
|
-
3. Edit `examples/config.yaml` and run:
|
|
33
|
-
|
|
34
|
-
```bash
|
|
35
|
-
adaptivepy run examples/config.yaml
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
## CLI
|
|
39
|
-
|
|
40
|
-
```bash
|
|
41
|
-
adaptivepy run config.yaml
|
|
42
|
-
adaptivepy validate config.yaml
|
|
43
|
-
adaptivepy list-policies
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
## Python API
|
|
47
|
-
|
|
48
|
-
```python
|
|
49
|
-
from adaptivepy import run_adaptive_sampling
|
|
50
|
-
|
|
51
|
-
results = run_adaptive_sampling("config.yaml")
|
|
52
|
-
```
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
# AdaptivePy
|
|
2
|
-
|
|
3
|
-
Adaptive sampling on molecular dynamics trajectories using clustering-based state space partitioning and policy-driven seed selection.
|
|
4
|
-
|
|
5
|
-
## Installation
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
pip install -e .
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
## Quick start
|
|
12
|
-
|
|
13
|
-
1. Prepare feature files (`features/traj_0.npy`, ...) with shape `(n_frames, n_features)`.
|
|
14
|
-
2. Optionally add matching coordinate trajectories (`trajectories/traj_0.xtc`, ...) and a topology file.
|
|
15
|
-
3. Edit `examples/config.yaml` and run:
|
|
16
|
-
|
|
17
|
-
```bash
|
|
18
|
-
adaptivepy run examples/config.yaml
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
## CLI
|
|
22
|
-
|
|
23
|
-
```bash
|
|
24
|
-
adaptivepy run config.yaml
|
|
25
|
-
adaptivepy validate config.yaml
|
|
26
|
-
adaptivepy list-policies
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
## Python API
|
|
30
|
-
|
|
31
|
-
```python
|
|
32
|
-
from adaptivepy import run_adaptive_sampling
|
|
33
|
-
|
|
34
|
-
results = run_adaptive_sampling("config.yaml")
|
|
35
|
-
```
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: adaptivepy-sampling
|
|
3
|
-
Version: 0.1.0
|
|
4
|
-
Summary: Adaptive sampling on MD trajectories via clustering and policy-driven seed selection
|
|
5
|
-
Author: AdaptivePy Contributors
|
|
6
|
-
License: MIT
|
|
7
|
-
Requires-Python: >=3.9
|
|
8
|
-
Description-Content-Type: text/markdown
|
|
9
|
-
Requires-Dist: numpy>=1.20
|
|
10
|
-
Requires-Dist: scikit-learn>=1.0
|
|
11
|
-
Requires-Dist: pyyaml>=6.0
|
|
12
|
-
Requires-Dist: click>=8.0
|
|
13
|
-
Requires-Dist: joblib>=1.0
|
|
14
|
-
Requires-Dist: mdtraj>=1.9
|
|
15
|
-
Provides-Extra: dev
|
|
16
|
-
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
17
|
-
|
|
18
|
-
# AdaptivePy
|
|
19
|
-
|
|
20
|
-
Adaptive sampling on molecular dynamics trajectories using clustering-based state space partitioning and policy-driven seed selection.
|
|
21
|
-
|
|
22
|
-
## Installation
|
|
23
|
-
|
|
24
|
-
```bash
|
|
25
|
-
pip install -e .
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
## Quick start
|
|
29
|
-
|
|
30
|
-
1. Prepare feature files (`features/traj_0.npy`, ...) with shape `(n_frames, n_features)`.
|
|
31
|
-
2. Optionally add matching coordinate trajectories (`trajectories/traj_0.xtc`, ...) and a topology file.
|
|
32
|
-
3. Edit `examples/config.yaml` and run:
|
|
33
|
-
|
|
34
|
-
```bash
|
|
35
|
-
adaptivepy run examples/config.yaml
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
## CLI
|
|
39
|
-
|
|
40
|
-
```bash
|
|
41
|
-
adaptivepy run config.yaml
|
|
42
|
-
adaptivepy validate config.yaml
|
|
43
|
-
adaptivepy list-policies
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
## Python API
|
|
47
|
-
|
|
48
|
-
```python
|
|
49
|
-
from adaptivepy import run_adaptive_sampling
|
|
50
|
-
|
|
51
|
-
results = run_adaptive_sampling("config.yaml")
|
|
52
|
-
```
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{adaptivepy_sampling-0.1.0 → adaptivepy_sampling-0.1.2}/adaptivepy/clustering/regular_space.py
RENAMED
|
File without changes
|
{adaptivepy_sampling-0.1.0 → adaptivepy_sampling-0.1.2}/adaptivepy/clustering/sklearn_kmeans.py
RENAMED
|
File without changes
|
{adaptivepy_sampling-0.1.0 → adaptivepy_sampling-0.1.2}/adaptivepy/clustering/sklearn_minibatch.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{adaptivepy_sampling-0.1.0 → adaptivepy_sampling-0.1.2}/adaptivepy/selection/frame_selector.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{adaptivepy_sampling-0.1.0 → adaptivepy_sampling-0.1.2}/adaptivepy_sampling.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{adaptivepy_sampling-0.1.0 → adaptivepy_sampling-0.1.2}/adaptivepy_sampling.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|