fastmdxplora 2.0.0__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.
- fastmdxplora-2.0.0/.github/workflows/publish.yml +83 -0
- fastmdxplora-2.0.0/.github/workflows/tests.yml +49 -0
- fastmdxplora-2.0.0/.gitignore +50 -0
- fastmdxplora-2.0.0/.readthedocs.yaml +19 -0
- fastmdxplora-2.0.0/CHANGELOG.md +100 -0
- fastmdxplora-2.0.0/CITATION.cff +35 -0
- fastmdxplora-2.0.0/CODE_OF_CONDUCT.md +43 -0
- fastmdxplora-2.0.0/CONTRIBUTING.md +67 -0
- fastmdxplora-2.0.0/LICENSE +21 -0
- fastmdxplora-2.0.0/PKG-INFO +438 -0
- fastmdxplora-2.0.0/README.md +380 -0
- fastmdxplora-2.0.0/STRUCTURE.md +110 -0
- fastmdxplora-2.0.0/assets/README.md +6 -0
- fastmdxplora-2.0.0/docs/conf.py +37 -0
- fastmdxplora-2.0.0/docs/index.md +23 -0
- fastmdxplora-2.0.0/docs/usage_examples.md +509 -0
- fastmdxplora-2.0.0/environment.yml +34 -0
- fastmdxplora-2.0.0/examples/README.md +14 -0
- fastmdxplora-2.0.0/pyproject.toml +120 -0
- fastmdxplora-2.0.0/pytest.ini +6 -0
- fastmdxplora-2.0.0/recipes/fastmdx-alias/meta.yaml +52 -0
- fastmdxplora-2.0.0/recipes/fastmdxplora/meta.yaml +87 -0
- fastmdxplora-2.0.0/requirements.txt +2 -0
- fastmdxplora-2.0.0/scripts/README.md +3 -0
- fastmdxplora-2.0.0/scripts/make_benzene.py +91 -0
- fastmdxplora-2.0.0/setup.cfg +4 -0
- fastmdxplora-2.0.0/shim-package/README.md +36 -0
- fastmdxplora-2.0.0/shim-package/pyproject.toml +35 -0
- fastmdxplora-2.0.0/shim-package/src/fastmdx/__init__.py +34 -0
- fastmdxplora-2.0.0/src/fastmdxplora/__init__.py +78 -0
- fastmdxplora-2.0.0/src/fastmdxplora/_version.py +24 -0
- fastmdxplora-2.0.0/src/fastmdxplora/analysis/__init__.py +104 -0
- fastmdxplora-2.0.0/src/fastmdxplora/analysis/analyze.py +181 -0
- fastmdxplora-2.0.0/src/fastmdxplora/analysis/base.py +394 -0
- fastmdxplora-2.0.0/src/fastmdxplora/analysis/cluster.py +339 -0
- fastmdxplora-2.0.0/src/fastmdxplora/analysis/contacts.py +178 -0
- fastmdxplora-2.0.0/src/fastmdxplora/analysis/dihedrals.py +183 -0
- fastmdxplora-2.0.0/src/fastmdxplora/analysis/dimred.py +276 -0
- fastmdxplora-2.0.0/src/fastmdxplora/analysis/hbonds.py +191 -0
- fastmdxplora-2.0.0/src/fastmdxplora/analysis/ligand_rmsd.py +165 -0
- fastmdxplora-2.0.0/src/fastmdxplora/analysis/ligand_rmsf.py +124 -0
- fastmdxplora-2.0.0/src/fastmdxplora/analysis/loading.py +226 -0
- fastmdxplora-2.0.0/src/fastmdxplora/analysis/orchestrator.py +417 -0
- fastmdxplora-2.0.0/src/fastmdxplora/analysis/pl_hbonds.py +147 -0
- fastmdxplora-2.0.0/src/fastmdxplora/analysis/plotting.py +147 -0
- fastmdxplora-2.0.0/src/fastmdxplora/analysis/qvalue.py +176 -0
- fastmdxplora-2.0.0/src/fastmdxplora/analysis/rg.py +145 -0
- fastmdxplora-2.0.0/src/fastmdxplora/analysis/rmsd.py +171 -0
- fastmdxplora-2.0.0/src/fastmdxplora/analysis/rmsf.py +149 -0
- fastmdxplora-2.0.0/src/fastmdxplora/analysis/sasa.py +186 -0
- fastmdxplora-2.0.0/src/fastmdxplora/analysis/ss.py +172 -0
- fastmdxplora-2.0.0/src/fastmdxplora/batch/__init__.py +38 -0
- fastmdxplora-2.0.0/src/fastmdxplora/batch/compare.py +452 -0
- fastmdxplora-2.0.0/src/fastmdxplora/batch/explorer.py +442 -0
- fastmdxplora-2.0.0/src/fastmdxplora/batch/sweep.py +336 -0
- fastmdxplora-2.0.0/src/fastmdxplora/cli/__init__.py +5 -0
- fastmdxplora-2.0.0/src/fastmdxplora/cli/main.py +716 -0
- fastmdxplora-2.0.0/src/fastmdxplora/config/__init__.py +40 -0
- fastmdxplora-2.0.0/src/fastmdxplora/config/generate.py +293 -0
- fastmdxplora-2.0.0/src/fastmdxplora/config/loader.py +286 -0
- fastmdxplora-2.0.0/src/fastmdxplora/config/schema.py +412 -0
- fastmdxplora-2.0.0/src/fastmdxplora/datasets/__init__.py +9 -0
- fastmdxplora-2.0.0/src/fastmdxplora/datasets/trp_cage.py +33 -0
- fastmdxplora-2.0.0/src/fastmdxplora/orchestrator.py +634 -0
- fastmdxplora-2.0.0/src/fastmdxplora/report/__init__.py +18 -0
- fastmdxplora-2.0.0/src/fastmdxplora/report/bundle.py +68 -0
- fastmdxplora-2.0.0/src/fastmdxplora/report/document.py +262 -0
- fastmdxplora-2.0.0/src/fastmdxplora/report/run.py +96 -0
- fastmdxplora-2.0.0/src/fastmdxplora/report/slides.py +258 -0
- fastmdxplora-2.0.0/src/fastmdxplora/setup/__init__.py +25 -0
- fastmdxplora-2.0.0/src/fastmdxplora/setup/forcefields.py +147 -0
- fastmdxplora-2.0.0/src/fastmdxplora/setup/ligand.py +169 -0
- fastmdxplora-2.0.0/src/fastmdxplora/setup/pdbfix.py +110 -0
- fastmdxplora-2.0.0/src/fastmdxplora/setup/pipeline.py +428 -0
- fastmdxplora-2.0.0/src/fastmdxplora/setup/prepare.py +589 -0
- fastmdxplora-2.0.0/src/fastmdxplora/simulation/__init__.py +23 -0
- fastmdxplora-2.0.0/src/fastmdxplora/simulation/pipeline.py +290 -0
- fastmdxplora-2.0.0/src/fastmdxplora/simulation/plumed.py +146 -0
- fastmdxplora-2.0.0/src/fastmdxplora/simulation/runner.py +769 -0
- fastmdxplora-2.0.0/src/fastmdxplora/utils/__init__.py +31 -0
- fastmdxplora-2.0.0/src/fastmdxplora/utils/logging.py +278 -0
- fastmdxplora-2.0.0/src/fastmdxplora/utils/native_output.py +116 -0
- fastmdxplora-2.0.0/src/fastmdxplora/utils/presenter.py +387 -0
- fastmdxplora-2.0.0/src/fastmdxplora.egg-info/PKG-INFO +438 -0
- fastmdxplora-2.0.0/src/fastmdxplora.egg-info/SOURCES.txt +110 -0
- fastmdxplora-2.0.0/src/fastmdxplora.egg-info/dependency_links.txt +1 -0
- fastmdxplora-2.0.0/src/fastmdxplora.egg-info/entry_points.txt +2 -0
- fastmdxplora-2.0.0/src/fastmdxplora.egg-info/requires.txt +33 -0
- fastmdxplora-2.0.0/src/fastmdxplora.egg-info/top_level.txt +1 -0
- fastmdxplora-2.0.0/tests/__init__.py +0 -0
- fastmdxplora-2.0.0/tests/test_analysis_layer.py +513 -0
- fastmdxplora-2.0.0/tests/test_analysis_scope.py +254 -0
- fastmdxplora-2.0.0/tests/test_batch.py +627 -0
- fastmdxplora-2.0.0/tests/test_cli.py +175 -0
- fastmdxplora-2.0.0/tests/test_cli_flags.py +302 -0
- fastmdxplora-2.0.0/tests/test_compare.py +287 -0
- fastmdxplora-2.0.0/tests/test_concrete_analyses.py +420 -0
- fastmdxplora-2.0.0/tests/test_config.py +469 -0
- fastmdxplora-2.0.0/tests/test_forcefield_selector.py +178 -0
- fastmdxplora-2.0.0/tests/test_imports.py +58 -0
- fastmdxplora-2.0.0/tests/test_ligand.py +307 -0
- fastmdxplora-2.0.0/tests/test_ligand_rmsd.py +267 -0
- fastmdxplora-2.0.0/tests/test_logging.py +253 -0
- fastmdxplora-2.0.0/tests/test_md_engine_controls.py +507 -0
- fastmdxplora-2.0.0/tests/test_native_output.py +93 -0
- fastmdxplora-2.0.0/tests/test_orchestrator.py +250 -0
- fastmdxplora-2.0.0/tests/test_plumed.py +149 -0
- fastmdxplora-2.0.0/tests/test_presenter.py +307 -0
- fastmdxplora-2.0.0/tests/test_report_wiring.py +271 -0
- fastmdxplora-2.0.0/tests/test_setup_phase.py +491 -0
- fastmdxplora-2.0.0/tests/test_simulation_phase.py +588 -0
- fastmdxplora-2.0.0/tests/test_sub3_analyses.py +389 -0
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
build:
|
|
10
|
+
name: Build distributions
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
steps:
|
|
13
|
+
- uses: actions/checkout@v4
|
|
14
|
+
with:
|
|
15
|
+
fetch-depth: 0
|
|
16
|
+
|
|
17
|
+
- name: Set up Python
|
|
18
|
+
uses: actions/setup-python@v5
|
|
19
|
+
with:
|
|
20
|
+
python-version: "3.11"
|
|
21
|
+
|
|
22
|
+
- name: Install build
|
|
23
|
+
run: python -m pip install --upgrade pip build
|
|
24
|
+
|
|
25
|
+
- name: Build the canonical package (fastmdxplora)
|
|
26
|
+
run: python -m build
|
|
27
|
+
|
|
28
|
+
- name: Build the fastmdx alias
|
|
29
|
+
run: cd shim-package && python -m build
|
|
30
|
+
|
|
31
|
+
- name: Verify fastmdx alias version matches the release tag
|
|
32
|
+
run: |
|
|
33
|
+
TAG="${GITHUB_REF_NAME#v}"
|
|
34
|
+
VER=$(python -c "import tomllib; print(tomllib.load(open('shim-package/pyproject.toml','rb'))['project']['version'])")
|
|
35
|
+
echo "fastmdx version: $VER (tag: $TAG)"
|
|
36
|
+
if [ "$TAG" != "$VER" ]; then
|
|
37
|
+
echo "::error::fastmdx alias version ($VER) does not match release tag ($TAG). Bump shim-package/pyproject.toml before tagging."
|
|
38
|
+
exit 1
|
|
39
|
+
fi
|
|
40
|
+
|
|
41
|
+
- name: Upload fastmdxplora artifacts
|
|
42
|
+
uses: actions/upload-artifact@v4
|
|
43
|
+
with:
|
|
44
|
+
name: dist-fastmdxplora
|
|
45
|
+
path: dist/
|
|
46
|
+
|
|
47
|
+
- name: Upload fastmdx artifacts
|
|
48
|
+
uses: actions/upload-artifact@v4
|
|
49
|
+
with:
|
|
50
|
+
name: dist-fastmdx
|
|
51
|
+
path: shim-package/dist/
|
|
52
|
+
|
|
53
|
+
publish-fastmdxplora:
|
|
54
|
+
name: Publish fastmdxplora to PyPI
|
|
55
|
+
needs: build
|
|
56
|
+
runs-on: ubuntu-latest
|
|
57
|
+
environment: pypi
|
|
58
|
+
permissions:
|
|
59
|
+
id-token: write
|
|
60
|
+
steps:
|
|
61
|
+
- uses: actions/download-artifact@v4
|
|
62
|
+
with:
|
|
63
|
+
name: dist-fastmdxplora
|
|
64
|
+
path: dist/
|
|
65
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
66
|
+
with:
|
|
67
|
+
skip-existing: true
|
|
68
|
+
|
|
69
|
+
publish-fastmdx:
|
|
70
|
+
name: Publish fastmdx (alias) to PyPI
|
|
71
|
+
needs: publish-fastmdxplora
|
|
72
|
+
runs-on: ubuntu-latest
|
|
73
|
+
environment: pypi
|
|
74
|
+
permissions:
|
|
75
|
+
id-token: write
|
|
76
|
+
steps:
|
|
77
|
+
- uses: actions/download-artifact@v4
|
|
78
|
+
with:
|
|
79
|
+
name: dist-fastmdx
|
|
80
|
+
path: dist/
|
|
81
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
82
|
+
with:
|
|
83
|
+
skip-existing: true
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
name: Tests
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
runs-on: ${{ matrix.os }}
|
|
12
|
+
strategy:
|
|
13
|
+
fail-fast: false
|
|
14
|
+
matrix:
|
|
15
|
+
os: [ubuntu-latest, macos-latest, windows-latest]
|
|
16
|
+
python-version: ["3.9", "3.10", "3.11", "3.12"]
|
|
17
|
+
|
|
18
|
+
steps:
|
|
19
|
+
- uses: actions/checkout@v4
|
|
20
|
+
with:
|
|
21
|
+
fetch-depth: 0 # full history for setuptools-scm
|
|
22
|
+
|
|
23
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
24
|
+
uses: actions/setup-python@v5
|
|
25
|
+
with:
|
|
26
|
+
python-version: ${{ matrix.python-version }}
|
|
27
|
+
|
|
28
|
+
- name: Install package and test dependencies
|
|
29
|
+
run: |
|
|
30
|
+
python -m pip install --upgrade pip
|
|
31
|
+
python -m pip install -e ".[test,report]"
|
|
32
|
+
|
|
33
|
+
- name: Run tests
|
|
34
|
+
run: |
|
|
35
|
+
pytest --cov=fastmdxplora --cov-report=term-missing --cov-report=xml
|
|
36
|
+
|
|
37
|
+
- name: CLI smoke test
|
|
38
|
+
shell: bash
|
|
39
|
+
run: |
|
|
40
|
+
fastmdx --version
|
|
41
|
+
fastmdx info
|
|
42
|
+
fastmdx --cite
|
|
43
|
+
|
|
44
|
+
- name: Upload coverage
|
|
45
|
+
uses: codecov/codecov-action@v4
|
|
46
|
+
if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.11'
|
|
47
|
+
with:
|
|
48
|
+
files: ./coverage.xml
|
|
49
|
+
fail_ci_if_error: false
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# Distribution / packaging
|
|
7
|
+
.Python
|
|
8
|
+
build/
|
|
9
|
+
dist/
|
|
10
|
+
*.egg-info/
|
|
11
|
+
*.egg
|
|
12
|
+
wheels/
|
|
13
|
+
pip-wheel-metadata/
|
|
14
|
+
|
|
15
|
+
# Versioning artifact from setuptools-scm
|
|
16
|
+
src/fastmdxplora/_version.py
|
|
17
|
+
shim-package/src/fastmdx/_version.py
|
|
18
|
+
|
|
19
|
+
# Test / coverage artifacts
|
|
20
|
+
.pytest_cache/
|
|
21
|
+
.coverage
|
|
22
|
+
htmlcov/
|
|
23
|
+
coverage.xml
|
|
24
|
+
.tox/
|
|
25
|
+
.cache/
|
|
26
|
+
|
|
27
|
+
# Virtual environments
|
|
28
|
+
.venv/
|
|
29
|
+
venv/
|
|
30
|
+
env/
|
|
31
|
+
.env
|
|
32
|
+
|
|
33
|
+
# uv
|
|
34
|
+
.uv-cache/
|
|
35
|
+
|
|
36
|
+
# Editor / OS
|
|
37
|
+
.vscode/
|
|
38
|
+
.idea/
|
|
39
|
+
*.swp
|
|
40
|
+
*.swo
|
|
41
|
+
.DS_Store
|
|
42
|
+
Thumbs.db
|
|
43
|
+
|
|
44
|
+
# Documentation builds
|
|
45
|
+
docs/_build/
|
|
46
|
+
docs/build/
|
|
47
|
+
site/
|
|
48
|
+
|
|
49
|
+
# FastMDXplora run outputs (do not commit user data)
|
|
50
|
+
fastmdxplora_output_*/
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to FastMDXplora are documented in this file.
|
|
4
|
+
|
|
5
|
+
Format: [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) ·
|
|
6
|
+
Versioning: [SemVer 2.0.0](https://semver.org/spec/v2.0.0.html)
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [2.0.0] — 2026-05-25
|
|
11
|
+
|
|
12
|
+
**FastMDXplora** — Fully Automated SysTem for Molecular Dynamics eXploration.
|
|
13
|
+
A single command takes a structure (and optional bound ligand) from input to
|
|
14
|
+
publication-quality deliverable across four phases: setup, simulation
|
|
15
|
+
(including enhanced sampling), analysis (protein and protein-ligand), and
|
|
16
|
+
reporting.
|
|
17
|
+
|
|
18
|
+
### Packaging
|
|
19
|
+
- Canonical package: **`fastmdxplora`** (`import fastmdxplora`). The CLI
|
|
20
|
+
command is **`fastmdx`**.
|
|
21
|
+
- `fastmdx` remains available on PyPI as a short alias that installs and
|
|
22
|
+
re-exports `fastmdxplora`.
|
|
23
|
+
|
|
24
|
+
### Features
|
|
25
|
+
- End-to-end MD orchestration across four phases (setup, simulation, analysis, report).
|
|
26
|
+
- Named force-field selector; OpenFF ligand/cofactor parameterization with a setup-time pose clash check.
|
|
27
|
+
- Protein-ligand analyses: ligand pose RMSD, protein-ligand contacts + binding-site fingerprint, protein-ligand H-bonds, ligand RMSF — auto-detected for complexes.
|
|
28
|
+
- Analysis scope (`solute`/`protein`/`ligand`/`all`) keeping analyses off solvent.
|
|
29
|
+
- PLUMED enhanced sampling on the production stage (`--simulate-plumed-script`).
|
|
30
|
+
- Cross-platform CI (Linux/macOS/Windows); parallel batch execution and cross-run comparison.
|
|
31
|
+
|
|
32
|
+
## [0.3.0] — 2026-05-25
|
|
33
|
+
|
|
34
|
+
Enhanced sampling. FastMDXplora can now drive PLUMED collective-variable
|
|
35
|
+
biasing (metadynamics, umbrella sampling, steered MD, …) on the production
|
|
36
|
+
stage of a run, with equilibration left unbiased per standard protocol.
|
|
37
|
+
|
|
38
|
+
### Added
|
|
39
|
+
- **PLUMED enhanced sampling** (optional): supply a PLUMED script via `simulation.plumed` (config: `{enabled: true, script: "<inline or path to .dat>"}`) or `--simulate-plumed-script PATH` (CLI) to add collective-variable biasing — metadynamics, umbrella sampling, steered MD, etc. — to the **production** stage. Equilibration (NVT/NPT) runs unbiased, matching standard enhanced-sampling protocol; the biasing force is added just before production and the context reinitialized. PLUMED output files (COLVAR, HILLS, …) are redirected into the run's output directory, and the resolved script is saved as `plumed.dat` for reproducibility. Requires the `plumed` extra (`openmm-plumed`, installed via `conda install -c conda-forge openmm-plumed`); absent, enabling PLUMED raises a clear, actionable error.
|
|
40
|
+
|
|
41
|
+
### Changed
|
|
42
|
+
- Renamed the `test_md_parity.py` test module to `test_md_engine_controls.py` to match its content (MD engine controls). Trimmed the README (removed the Status and Project-family sections).
|
|
43
|
+
|
|
44
|
+
## [0.2.0] — 2026-05-25
|
|
45
|
+
|
|
46
|
+
End-to-end protein-ligand molecular dynamics. FastMDXplora can now set up,
|
|
47
|
+
simulate, and analyze a protein-ligand complex from a feasible bound pose:
|
|
48
|
+
named force fields with an OpenFF small-molecule path, a setup-time pose
|
|
49
|
+
sanity check, and the standard protein-ligand analysis suite, all detected
|
|
50
|
+
and wired automatically.
|
|
51
|
+
|
|
52
|
+
### Added
|
|
53
|
+
- **Protein-ligand analyses** (run automatically when a ligand is detected; `include`/`exclude` apply): in addition to ligand pose RMSD, three more commonly-reported analyses now run on protein-ligand complexes:
|
|
54
|
+
- `contacts` — protein-ligand contacts, reported two ways: a per-frame count of protein residues within a cutoff (default 0.4 nm) of the ligand (`contacts.dat`), and a per-residue contact-frequency "interaction fingerprint" identifying the binding-site residues (`contacts_per_residue.csv`, also shown as the figure)
|
|
55
|
+
- `pl_hbonds` — hydrogen bonds formed specifically between protein and ligand (per frame), distinct from the general intra-solute `hbonds` analysis
|
|
56
|
+
- `ligand_rmsf` — per-ligand-atom fluctuation after protein alignment: the ligand's internal flexibility in the pocket
|
|
57
|
+
- **Ligand pose RMSD** analysis (`ligand_rmsd`): the headline protein-ligand stability metric. Each frame is rigidly aligned onto the reference using the protein (Cα by default), then RMSD is measured on the ligand atoms of the aligned coordinates — i.e. how far the ligand has moved *relative to the protein frame*, which tells you whether it holds its binding pose or drifts/unbinds. This is distinct from the standard RMSD (which aligns and measures on the same atoms). It runs automatically when a ligand is detected (from `resolved_forcefield.ligand` in the setup manifest) and is skipped for protein-only runs; `include`/`exclude` still apply. Ligand-only analyses are marked with a `requires_ligand` flag on the analysis class, and the orchestrator supplies the detected ligand residue name automatically
|
|
58
|
+
- **Analysis scope** (`analysis.scope` / `--analyze-scope`): a single setting controls which atoms analyses operate on — `solute` (protein + ligand, the default), `protein`, `ligand`, or `all`. It resolves to a default atom selection applied to analyses that don't set their own (the solvent-blind ones: Rg, SASA, secondary structure, Q-value, hydrogen bonds), so they no longer run on solvent/ions by accident. Analyses with a meaningful own default (the Cα-based RMSD, RMSF, clustering, dimensionality reduction) keep it. An explicit per-analysis or orchestrator-wide `selection` still overrides the scope. When a ligand is present (detected from `resolved_forcefield.ligand` in the setup manifest), `solute` and `ligand` scopes include it automatically by residue name
|
|
59
|
+
- **Ligand / cofactor parameterization** (protein-ligand systems): supply a small-molecule ligand as an SDF or MOL2 file via `setup.ligand` (config) or `--setup-ligand` (CLI), parameterized with an OpenFF small-molecule force field through `openmmforcefields`' `SystemGenerator`. Selected with the ligand-capable `amber-openff` named force field (AMBER ff14SB protein + TIP3P water + OpenFF Sage 2.2.1 for the ligand). Net charge is inferred from the SDF formal charges unless set explicitly via `ligand_net_charge`; the ligand residue name (`ligand_name`, default `LIG`) and small-molecule force field (`ligand_forcefield`, e.g. `openff-2.2.1` or `gaff-2.2.20`) are configurable. The supplied ligand coordinates must be a feasible bound pose (from a co-crystal structure or docking); a setup-time clash check (`check_ligand_clashes`, `ligand_clash_threshold_nm`) fails with a clear message if the pose severely overlaps the protein, rather than letting it surface as a divergent simulation later. Incoherent combinations are rejected early with clear errors (a ligand with a non-ligand-capable force field, or with a raw XML list). The resolved ligand parameterization is recorded under `resolved_forcefield.ligand` in `setup_parameters.json`. Requires the `ligand` extra (`pip install 'fastmdxplora[ligand]'`); absent, the phase degrades with an actionable install message. Ligand input is list-shaped in config for future multi-ligand support; single-ligand parameterization is implemented now
|
|
60
|
+
- **Named force-field selector**: pick a force field by a short, documented name via `setup.forcefield` (config) or `--setup-forcefield` (CLI) — `charmm36` (default), `amber14`, `amber-fb15`, or `amber-openff` (ligand-capable) — instead of listing raw OpenMM XML filenames. Each name resolves to the correct protein/water XML set and default water model through a single registry (`setup/forcefields.py`). The raw `force_field` XML list remains as a power-user escape hatch; specifying both a named selector and a raw list is rejected with a clear error, as is an unknown force-field name (the message lists valid choices). The resolved force field (actual XMLs + water model) is recorded under `resolved_forcefield` in `setup_parameters.json` for reproducibility, regardless of which form the user chose
|
|
61
|
+
|
|
62
|
+
### Fixed
|
|
63
|
+
- The ligand residue in the prepared/solvated topology is now named with the configured ligand name (default `LIG`) instead of OpenFF's default `UNK`. Previously the written `topology.pdb` labelled the ligand `UNK` while the manifest recorded `LIG`, so resname-based selection silently failed — ligand-aware analyses found no ligand atoms, and the `solute`/`ligand` analysis scopes silently excluded the ligand. The name is now set on both the ligand topology and the merged topology so it survives `Modeller.add()` across OpenMM versions
|
|
64
|
+
- Clustering on a trajectory with fewer frames than the requested number of clusters now fails with a clear, actionable message ("Clustering needs at least n_clusters=N frames, but the trajectory has only M...") instead of an opaque scikit-learn internals error. k-means and hierarchical clustering are guarded; DBSCAN (which doesn't take a cluster count) is unaffected
|
|
65
|
+
- Analyses that operate on all atoms by default (Rg, SASA, secondary structure, Q-value, hydrogen bonds) now slice the trajectory to the resolved scope/selection *before* computing, rather than processing the full solvated system. Previously several of these passed the whole trajectory straight to the underlying calculation regardless of the selection — so on a solvated complex the Q-value analysis enumerated residue pairs across ~10k water residues (tens of millions of pairs) and effectively hung, and Rg/SASA were computed over water. With the new `solute` default scope and per-analysis slicing they operate on protein (+ ligand) only — a correctness fix for any solvated run and a large speedup
|
|
66
|
+
- **Named force-field selector**: pick a force field by a short, documented name via `setup.forcefield` (config) or `--setup-forcefield` (CLI) — `charmm36` (default), `amber14`, `amber-fb15`, or `amber-openff` (ligand-capable) — instead of listing raw OpenMM XML filenames. Each name resolves to the correct protein/water XML set and default water model through a single registry (`setup/forcefields.py`). The raw `force_field` XML list remains as a power-user escape hatch; specifying both a named selector and a raw list is rejected with a clear error, as is an unknown force-field name (the message lists valid choices). The resolved force field (actual XMLs + water model) is recorded under `resolved_forcefield` in `setup_parameters.json` for reproducibility, regardless of which form the user chose
|
|
67
|
+
|
|
68
|
+
## [0.1.0] — 2026-05-XX
|
|
69
|
+
|
|
70
|
+
Initial claim-staking release. Establishes the project-level orchestrator
|
|
71
|
+
scaffolding, the four-phase API (setup, simulation, analysis, report), and
|
|
72
|
+
the `fastmdx` CLI.
|
|
73
|
+
|
|
74
|
+
### Added
|
|
75
|
+
- **Robust auto platform selection**: when `platform=auto`, the simulation runner now verifies a GPU platform (CUDA/OpenCL) can actually create a Context before committing to it, and falls back to the next candidate (ultimately CPU) if not — instead of selecting a *registered-but-unusable* platform that then fails at Context construction with a confusing error. An explicit `platform=CUDA`/`OpenCL` request is still honored as-is (the user sees the real error if their choice is broken)
|
|
76
|
+
- **Clear periodic-box / cutoff guard**: `prepare_system` now raises an actionable error when the nonbonded cutoff exceeds half the smallest periodic box dimension (instead of OpenMM's cryptic `NonbondedForce` message), naming the cutoff, the box, and how to fix it (increase `solvent_padding_nm` or decrease `nonbonded_cutoff_nm`)
|
|
77
|
+
- **`environment.yml` + git install path** — clone the repo and `mamba env create -f environment.yml || conda env create -f environment.yml` then `pip install .` to get all four phases (the OpenMM/PDBFixer chemistry stack from conda-forge) without waiting on the conda-forge package. Plain `pip install fastmdxplora` still gives the analysis + report phases on their own
|
|
78
|
+
|
|
79
|
+
### Fixed
|
|
80
|
+
- **Parallel execution on Windows**: spawned worker processes now reconfigure their stdout/stderr to UTF-8 (as the CLI entry point does). Previously, because workers are spawned (not forked) on Windows and bypass the CLI entry, their streams stayed on the platform codec (cp1252) and crashed with `UnicodeEncodeError` the moment the presenter printed a status glyph (✓, ▸) — so every run in `mode: parallel` failed on Windows while sequential mode succeeded
|
|
81
|
+
- **Headless plotting**: the analysis package now forces matplotlib's non-interactive `Agg` backend before pyplot is imported (respecting an explicit `MPLBACKEND`). Previously the backend was only forced off-Windows with no `DISPLAY`, so analyses crashed on headless machines that didn't match that gate (notably headless Windows CI) with "Can't find a usable init.tcl". FastMDXplora always writes figures to files, so a non-interactive backend is always correct
|
|
82
|
+
- **Cross-platform paths in reports/manifests**: figure links in the Markdown report, zip archive entry names, and the relative artifact paths recorded in manifests now use forward slashes (`as_posix()`) on every OS. Previously, on Windows these were emitted with backslashes, breaking Markdown/HTML image links and producing non-portable manifests
|
|
83
|
+
- **UTF-8 file/stream encoding everywhere**: all text written by FastMDXplora (reports, comparison markdown, config templates, manifests, PDB/XML artifacts) now specifies `encoding="utf-8"` explicitly, and the CLI reconfigures stdout/stderr to UTF-8 at entry. Previously, on a machine whose default locale encoding was ASCII, writing the comparison report's `→` or the config template's `—` (or printing the banner) raised `UnicodeEncodeError`
|
|
84
|
+
- **FastMDXplora orchestrator class** (`fastmdxplora.FastMDXplora`) — project-level coordinator following a seven-phase orchestration pattern (Aina & Kwan, JCC 2026)
|
|
85
|
+
- **Four phases** under `fastmdxplora.setup`, `.simulation`, `.analysis`, `.report` — each with a `run(orchestrator, output_dir, **options)` entry point and a structured parameters manifest
|
|
86
|
+
- **`fastmdx` CLI** with subcommands `explore` (canonical), `xplore` (X-themed alias), `setup`, `simulate`, `analyze`, `report`, `info`, plus `--version` and `--cite` flags
|
|
87
|
+
- **Report phase artifacts**: Markdown study report, .pptx slide deck, self-contained .zip project bundle
|
|
88
|
+
- **YAML configuration files**: a single config captures an entire study — input is given as a canonical `systems:` list (always a list, even for one system), plus phase selection and all per-phase options; drives both the CLI (`--config` / `-c`) and the Python API (`FastMDXplora(config=...).explore()`); `fastmdx init-config` writes a fully-commented template; strict schema validation rejects typos with did-you-mean suggestions; command-line flags override file values; every run writes a re-runnable `resolved_config.yml` for reproducibility
|
|
89
|
+
- **Full MD engine controls**: integrator selection (`langevin_middle`, `langevin`, `brownian`, `verlet`, `variable_langevin`, `variable_verlet`); pressure in either `pressure_bar` or `pressure_atm` (auto-converted); GPU `device_index` selection; `checkpoint_interval_steps` writing a restart-ready `.chk`; `ForceField.createSystem` pass-throughs (`nonbonded_method`, `ewald_error_tolerance`, `use_switching_function`, `switch_distance_nm`, `dispersion_correction`, `remove_cm_motion`); and `fixed_pdb` to skip PDBFixer when a prepared structure is supplied
|
|
90
|
+
- **Many-system & parameter-sweep mode**: the `systems:` list can hold several systems, and an optional `sweep:` of parameter axes (dotted `phase.option` keys) runs the full cross-product (systems × sweep), each as a complete self-contained study. One run writes the flat output layout; multiple runs go in `runs/<id>/` indexed by a top-level `batch_manifest.json`. Per-system option overrides and swept values merge with correct precedence (base < per-system < sweep); typo'd sweep axes are rejected with the valid-option list. An optional `execution:` block runs studies in parallel (process pool) with round-robin GPU device pinning (one run per device)
|
|
91
|
+
- **Cross-run comparison report**: after a multi-run study, a `comparison/` report is built automatically at the batch root — per-frame **overlays** (RMSD, Rg, Q-value, total SASA across all runs on one axes), **trend** plots of each run's summary scalar against the swept parameter, a `comparison_summary.csv`, and a written `comparison_report.md` with a quantitative takeaway per property. Degrades gracefully (errored runs / missing analyses skipped); disable with `report: { comparison: false }`; (re)build via `FastMDXplora(...).compare()` (optionally `compare(output_dir=…)` for a batch that finished earlier)
|
|
92
|
+
- **Dry-run / plan-only mode**: `fastmdx explore --config … --dry-run` (or `explore(dry_run=True)`) prints every run, its system, swept values, target output directory, and the phases that would execute — then exits without running anything or writing to disk
|
|
93
|
+
- **Uniform return shape**: `FastMDXplora.explore()` always returns a `list[RunResult]` — a single study is a list of one, a sweep is a list of many. Each `RunResult` carries `run_id`, `system`, `status`, `output_dir`, `sweep_values`, and its per-phase `PhaseResult` list in `.phases` (with a `.phase(name)` lookup helper). The single user-facing entry point is always `FastMDXplora`; the batch machinery underneath is private
|
|
94
|
+
- **Reproducibility manifest** (`manifest.json`) written at the project root summarizing phases executed, parameters, software versions, and DOI
|
|
95
|
+
- **Datasets namespace** (`fastmdxplora.datasets`) with a TrpCage placeholder
|
|
96
|
+
- **CI**: matrix tests on ubuntu/macos/windows × Python 3.9–3.12 (GitHub Actions)
|
|
97
|
+
- **PyPI**: dual-name publishing — `fastmdxplora` is the primary package, `fastmdx` is a thin alias that depends on it
|
|
98
|
+
|
|
99
|
+
### Notes
|
|
100
|
+
- The analysis and report phases are self-contained (no heavy runtime dependencies); the setup and simulation phases require OpenMM + PDBFixer.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
cff-version: 1.2.0
|
|
2
|
+
message: >-
|
|
3
|
+
If you use FastMDXplora in your work, please cite the foundational
|
|
4
|
+
FastMDAnalysis paper below.
|
|
5
|
+
title: "FastMDXplora: Fully Automated SysTem for Molecular Dynamics eXploration"
|
|
6
|
+
type: software
|
|
7
|
+
authors:
|
|
8
|
+
- family-names: Aina
|
|
9
|
+
given-names: Adekunle
|
|
10
|
+
affiliation: "AAI Research Lab, California State University Dominguez Hills"
|
|
11
|
+
- family-names: Kwan
|
|
12
|
+
given-names: Derrick
|
|
13
|
+
affiliation: "AAI Research Lab, California State University Dominguez Hills"
|
|
14
|
+
repository-code: "https://github.com/aai-research-lab/FastMDXplora"
|
|
15
|
+
url: "https://github.com/aai-research-lab/FastMDXplora"
|
|
16
|
+
license: MIT
|
|
17
|
+
keywords:
|
|
18
|
+
- molecular-dynamics
|
|
19
|
+
- orchestrator
|
|
20
|
+
- automation
|
|
21
|
+
- computational-chemistry
|
|
22
|
+
- reproducibility
|
|
23
|
+
preferred-citation:
|
|
24
|
+
type: article
|
|
25
|
+
title: "FastMDAnalysis: Software for Automated Analysis of Molecular Dynamics Trajectories"
|
|
26
|
+
authors:
|
|
27
|
+
- family-names: Aina
|
|
28
|
+
given-names: Adekunle
|
|
29
|
+
- family-names: Kwan
|
|
30
|
+
given-names: Derrick
|
|
31
|
+
journal: "Journal of Computational Chemistry"
|
|
32
|
+
year: 2026
|
|
33
|
+
volume: 47
|
|
34
|
+
issue: 8
|
|
35
|
+
doi: "10.1002/jcc.70350"
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Code of Conduct
|
|
2
|
+
|
|
3
|
+
## Our pledge
|
|
4
|
+
|
|
5
|
+
We as members, contributors, and leaders pledge to make participation in
|
|
6
|
+
our community a harassment-free experience for everyone, regardless of
|
|
7
|
+
age, body size, visible or invisible disability, ethnicity, sex
|
|
8
|
+
characteristics, gender identity and expression, level of experience,
|
|
9
|
+
education, socio-economic status, nationality, personal appearance,
|
|
10
|
+
race, religion, or sexual identity and orientation.
|
|
11
|
+
|
|
12
|
+
We pledge to act and interact in ways that contribute to an open,
|
|
13
|
+
welcoming, diverse, inclusive, and healthy community.
|
|
14
|
+
|
|
15
|
+
## Our standards
|
|
16
|
+
|
|
17
|
+
Examples of behavior that contributes to a positive environment:
|
|
18
|
+
|
|
19
|
+
- Using welcoming and inclusive language
|
|
20
|
+
- Being respectful of differing viewpoints and experiences
|
|
21
|
+
- Gracefully accepting constructive criticism
|
|
22
|
+
- Focusing on what is best for the community
|
|
23
|
+
|
|
24
|
+
Examples of unacceptable behavior:
|
|
25
|
+
|
|
26
|
+
- Trolling, insulting or derogatory comments, and personal or political attacks
|
|
27
|
+
- Public or private harassment
|
|
28
|
+
- Publishing others' private information without explicit permission
|
|
29
|
+
- Other conduct which could reasonably be considered inappropriate in a
|
|
30
|
+
professional setting
|
|
31
|
+
|
|
32
|
+
## Enforcement
|
|
33
|
+
|
|
34
|
+
Project maintainers are responsible for clarifying and enforcing the
|
|
35
|
+
standards above. Instances of abusive or unacceptable behavior may be
|
|
36
|
+
reported to the project lead at the email listed on the AAI Research
|
|
37
|
+
Lab website. All complaints will be reviewed and investigated promptly
|
|
38
|
+
and fairly.
|
|
39
|
+
|
|
40
|
+
## Attribution
|
|
41
|
+
|
|
42
|
+
This Code of Conduct is adapted from the
|
|
43
|
+
[Contributor Covenant](https://www.contributor-covenant.org), version 2.1.
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# Contributing to FastMDXplora
|
|
2
|
+
|
|
3
|
+
Thank you for your interest in contributing to FastMDXplora. We welcome
|
|
4
|
+
contributions of all kinds — bug reports, feature requests, documentation
|
|
5
|
+
improvements, and code.
|
|
6
|
+
|
|
7
|
+
## Getting started
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
# Clone the repository
|
|
11
|
+
git clone https://github.com/aai-research-lab/FastMDXplora.git
|
|
12
|
+
cd FastMDXplora
|
|
13
|
+
|
|
14
|
+
# Create and activate a virtual environment
|
|
15
|
+
python -m venv .venv
|
|
16
|
+
source .venv/bin/activate # On Windows: .venv\Scripts\activate
|
|
17
|
+
|
|
18
|
+
# Install in editable mode with development dependencies
|
|
19
|
+
pip install -e ".[dev]"
|
|
20
|
+
|
|
21
|
+
# Verify the install
|
|
22
|
+
fastmdx --version
|
|
23
|
+
fastmdx info
|
|
24
|
+
pytest
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Development workflow
|
|
28
|
+
|
|
29
|
+
1. Open an issue describing the change you'd like to make (skip this for
|
|
30
|
+
trivial fixes such as typos).
|
|
31
|
+
2. Fork the repository and create a topic branch from `main`.
|
|
32
|
+
3. Make your changes. Write or update tests under `tests/`.
|
|
33
|
+
4. Run the test suite locally (`pytest`).
|
|
34
|
+
5. Run the linter (`ruff check src tests`) and ensure it passes.
|
|
35
|
+
6. Open a pull request against `main`.
|
|
36
|
+
|
|
37
|
+
## Coding conventions
|
|
38
|
+
|
|
39
|
+
- **Python ≥ 3.9.** Use modern type hints and the standard library where possible.
|
|
40
|
+
- **`src/` layout.** All package code lives under `src/fastmdxplora/`.
|
|
41
|
+
- **Docstrings.** Public functions and classes get NumPy-style docstrings.
|
|
42
|
+
- **Tests required for new functionality.** Smoke tests at minimum; full
|
|
43
|
+
numerical/equivalence tests for any analytical code migrated from
|
|
44
|
+
FastMDAnalysis (which FastMDXplora is the successor to).
|
|
45
|
+
- **Lazy imports for heavy optional dependencies** (OpenMM, PDBFixer,
|
|
46
|
+
python-pptx, etc.).
|
|
47
|
+
- **Consistent output structure.** Every phase writes its outputs to
|
|
48
|
+
`output_dir/<phase>/`, including a `*_parameters.json` manifest.
|
|
49
|
+
|
|
50
|
+
## Reporting issues
|
|
51
|
+
|
|
52
|
+
Please include:
|
|
53
|
+
|
|
54
|
+
- The output of `fastmdx info`
|
|
55
|
+
- The command line you ran (or the Python code snippet)
|
|
56
|
+
- The full error message and traceback
|
|
57
|
+
- A minimal reproducing example if possible
|
|
58
|
+
|
|
59
|
+
## Code of conduct
|
|
60
|
+
|
|
61
|
+
By participating in this project, you agree to abide by our
|
|
62
|
+
[Code of Conduct](CODE_OF_CONDUCT.md).
|
|
63
|
+
|
|
64
|
+
## License
|
|
65
|
+
|
|
66
|
+
By contributing, you agree that your contributions will be licensed under
|
|
67
|
+
the project's [MIT License](LICENSE).
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Adekunle Aina, Derrick Kwan, and FastMDXplora contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|