Skip to content

Commit 265b93c

Browse files
Merge pull request #68 from michellab/feature-decouple-somd-3
Feature decouple somd 3 to main branch Conflicts Resolved - Resolved all merge conflicts between feature-decouple-somd-3 and main branch - Integrated latest changes from main branch - Local and CI tests pass on all supported Python versions Ready for v0.4.0 release.
2 parents fdc9857 + 7a4d8ac commit 265b93c

File tree

1,618 files changed

+420180
-399314
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

1,618 files changed

+420180
-399314
lines changed

.github/workflows/CI.yaml

Lines changed: 18 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
name: CI
22

3+
concurrency:
4+
group: ${{ github.ref }}
5+
cancel-in-progress: true
6+
37
on:
48
# GitHub has started calling new repo's first branch "main" https://github.com/github/renaming
59
# The cookiecutter uses the "--initial-branch" flag when it runs git-init
@@ -16,70 +20,37 @@ on:
1620
- cron: "0 0 * * 0"
1721

1822
jobs:
19-
# Check with ruff and black
20-
lint_and_format:
21-
name: Check for style and formatting violations with Ruff
22-
runs-on: ubuntu-latest
23-
steps:
24-
- name: Check out code
25-
uses: actions/checkout@v2
26-
27-
- name: Set up Python
28-
uses: actions/setup-python@v2
29-
with:
30-
python-version: '3.10'
31-
32-
- name: Install dependencies
33-
run: |
34-
python -m pip install --upgrade pip
35-
pip install ruff
36-
37-
- name: Check style with Ruff
38-
run: ruff check .
39-
40-
- name: Check formatting with Ruff
41-
run: ruff format --check .
42-
4323
test:
4424
name: Test on ${{ matrix.os }}, Python ${{ matrix.python-version }}
4525
runs-on: ${{ matrix.os }}
4626
strategy:
4727
matrix:
4828
os: [ubuntu-latest]
4929
python-version: ['3.10', '3.11', '3.12']
50-
30+
container: condaforge/mambaforge:latest
31+
5132
steps:
52-
- uses: actions/checkout@v3
33+
- name: Check out code
34+
uses: actions/[email protected]
5335

54-
- name: Additional info about the build
55-
shell: bash
36+
- name: Install system dependencies
5637
run: |
57-
uname -a
58-
df -h
59-
ulimit -a
60-
61-
- uses: mamba-org/setup-micromamba@v1
62-
with:
63-
environment-file: devtools/conda-envs/test_env.yaml
64-
environment-name: test
65-
create-args: >- # beware the >- instead of |, we don't split on newlines but on spaces
66-
python=${{ matrix.python-version }}
38+
apt update && apt install -y git make
6739
68-
- name: Install package
69-
# conda setup requires this special shell
70-
shell: bash -l {0}
40+
- name: Setup environment for Python ${{ matrix.python-version }}
7141
run: |
72-
python -m pip install . --no-deps
73-
micromamba list
42+
make env-ci PYTHON_VERSION=${{ matrix.python-version }}
7443
75-
- name: Run tests
76-
# conda setup requires this special shell
77-
shell: bash -l {0}
44+
- name: Run linting and tests
7845
run: |
79-
pytest -v --cov=a3fe --cov-report=xml --color=yes a3fe/tests/
46+
make lint
47+
make test
48+
make docs
49+
make clean
8050
8151
- name: Upload coverage reports to Codecov
8252
uses: codecov/[email protected]
8353
with:
54+
file: ./coverage.xml
8455
token: ${{ secrets.CODECOV_TOKEN }}
8556
slug: michellab/a3fe

.pre-commit-config.yaml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# .pre-commit-config.yaml
2+
repos:
3+
# Basic file cleanup hooks
4+
- repo: https://github.com/pre-commit/pre-commit-hooks
5+
rev: v3.2.0
6+
hooks:
7+
- id: trailing-whitespace # delete trailing whitespace
8+
- id: end-of-file-fixer # ensure file ends with a blank line
9+
- id: check-yaml # check yaml syntax
10+
- id: check-added-large-files # prevent large files from being added
11+
- id: check-merge-conflict # check for unresolved merge conflicts
12+
13+
# Use local commands to format and check code
14+
- repo: local
15+
hooks:
16+
# code format hook
17+
- id: ruff
18+
name: Autoformat python code
19+
language: system
20+
entry: bash
21+
args: [-c, "make format"]
22+
23+
# code check hook
24+
- id: ruff
25+
name: Lint python code
26+
language: system
27+
entry: bash
28+
args: [-c, "make lint"]

.readthedocs.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,4 @@ sphinx:
1313
configuration: docs/conf.py
1414

1515
conda:
16-
environment: devtools/conda-envs/test_env.yaml
16+
environment: devtools/conda-envs/ci_env.yaml

CODE_OF_CONDUCT.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ project may be further defined and clarified by project maintainers.
5757
## Enforcement
5858

5959
Instances of abusive, harassing, or otherwise unacceptable behavior may be
60-
reported by contacting the project team at '[email protected]'. The project team will
60+
reported by contacting the project team at '[email protected] or [email protected]'. The project team will
6161
review and investigate all complaints, and will respond in a way that it deems
6262
appropriate to the circumstances. The project team is obligated to maintain
6363
confidentiality with regard to the reporter of an incident. Further details of

Makefile

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
PACKAGE_NAME := a3fe
2+
PACKAGE_DIR := a3fe
3+
4+
# Only need slurm, which is linux only
5+
CONDA_ENV_RUN = conda run --no-capture-output --name $(PACKAGE_NAME)
6+
7+
TEST_ARGS := -v --cov=$(PACKAGE_DIR) --cov-report=term --cov-report=xml --junitxml=unit.xml --color=yes
8+
9+
.PHONY: env env-dev env-ci lint format test test-integration docs-build docs clean
10+
11+
# Regular users:
12+
env:
13+
mamba create -y --name $(PACKAGE_NAME) $(if $(PYTHON_VERSION),python=$(PYTHON_VERSION))
14+
mamba env update --name $(PACKAGE_NAME) --file devtools/conda-envs/base_env.yaml
15+
$(CONDA_ENV_RUN) pip install --no-deps -e .
16+
17+
# Developers with local GROMACS
18+
env-dev:
19+
mamba create -y --name $(PACKAGE_NAME) $(if $(PYTHON_VERSION),python=$(PYTHON_VERSION))
20+
mamba env update --name $(PACKAGE_NAME) --file devtools/conda-envs/dev_env.yaml
21+
$(CONDA_ENV_RUN) pip install --no-deps -e .
22+
$(CONDA_ENV_RUN) pre-commit install || true
23+
24+
# CI and developers without GROMACS
25+
env-ci:
26+
mamba create -y --name $(PACKAGE_NAME) $(if $(PYTHON_VERSION),python=$(PYTHON_VERSION))
27+
mamba env update --name $(PACKAGE_NAME) --file devtools/conda-envs/ci_env.yaml
28+
$(CONDA_ENV_RUN) pip install --no-deps -e .
29+
$(CONDA_ENV_RUN) pre-commit install || true
30+
31+
# code check
32+
lint:
33+
$(CONDA_ENV_RUN) ruff check $(PACKAGE_DIR)
34+
35+
# code format
36+
format:
37+
$(CONDA_ENV_RUN) ruff format $(PACKAGE_DIR)
38+
$(CONDA_ENV_RUN) ruff check --fix --select I $(PACKAGE_DIR)
39+
40+
# run tests
41+
test:
42+
$(CONDA_ENV_RUN) pytest $(TEST_ARGS) $(PACKAGE_DIR)/tests/
43+
44+
# run integration tests (requires SLURM environment)
45+
test-integration:
46+
$(CONDA_ENV_RUN) RUN_SLURM_TESTS=1 pytest $(TEST_ARGS) $(PACKAGE_DIR)/tests/ --run-integration -v
47+
48+
# build docs
49+
docs-build:
50+
cd docs && $(CONDA_ENV_RUN) make html
51+
52+
docs:
53+
cd docs && $(CONDA_ENV_RUN) make html
54+
@echo "Documentation built in docs/_build/html/"
55+
56+
# clean build files
57+
clean:
58+
rm -rf docs/_build/
59+
rm -rf build/
60+
rm -rf dist/
61+
rm -rf *.egg-info
62+
find . -type d -name __pycache__ -exec rm -rf {} +
63+
find . -type f -name "*.pyc" -delete
64+
65+
# deploy docs
66+
# consider supporting this in the future

README.md

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ a3fe
66
[![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0)
77
[![Documentation Status](https://readthedocs.org/projects/a3fe/badge/?version=latest)](https://a3fe.readthedocs.io/en/latest/?badge=latest)
88
[![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
9-
9+
1010
<img src="./a3fe_logo.png" alt="Alt text" style="width: 50%; height: 50%;">
1111

1212
**A**utomated **A**daptive **A**bsolute alchemical **F**ree **E**nergy calculator. A package for running adaptive alchemical absolute binding free energy calculations with SOMD (distributed within [sire](https://sire.openbiosim.org/)) using adaptive protocols based on an ensemble of simulations. This requires the SLURM scheduling system. Please see the [**documentation**](https://a3fe.readthedocs.io/en/latest/?badge=latest).
@@ -19,26 +19,34 @@ For details of the algorithms and testing, please see the assocated paper:
1919

2020
a3fe depends on SLURM for scheduling jobs, and on GROMACS for running initial equilibration simulations. Please ensure that your have sourced your GMXRC or loaded your GROMACS module before proceeding with the installation. While we recommend installing with [mamba](https://mamba.readthedocs.io/en/latest/installation/mamba-installation.html), you can substitute `mamba` with `conda` in the following commands.
2121

22-
Now, download and install a3fe:
22+
Now, download and install a3fe. Choose the appropriate environment for your use case:
23+
24+
**Regular users:**
2325
```bash
2426
git clone https://github.com/michellab/a3fe.git
2527
cd a3fe
26-
mamba env create -f environment.yaml
28+
make env
2729
mamba activate a3fe
28-
python -m pip install --no-deps .
30+
```
31+
32+
**Developers with local GROMACS:**
33+
```bash
34+
make env-dev
2935
```
3036

3137
### Quick Start
3238

33-
- Activate your a3fe conda environment
39+
- Activate your a3fe conda environment
3440
- Create a base directory for the calculation and create an directory called `input` within this
3541
- Move your input files into the the input directory. For example, if you have parameterised AMBER-format input files, name these bound_param.rst7, bound_param.prm7, free_param.rst7, and free_param.prm7. For more details see the documentation. Alternatively, copy the example input files from a3fe/a3fe/data/example_run_dir to your input directory.
36-
- Copy run somd.sh and template_config.sh from a3fe/a3fe/data/example_run_dir to your `input` directory, making sure to the SLURM options in run_somd.sh so that the jobs will run on your cluster
3742
- In the calculation base directory, run the following python code, either through ipython or as a python script (you will likely want to run the script with `nohup`or use ipython through tmux to ensure that the calculation is not killed when you lose connection)
3843

3944
```python
40-
import a3fe as a3
41-
calc = a3.Calculation(ensemble_size=5)
45+
import a3fe as a3
46+
calc = a3.Calculation(
47+
ensemble_size=5, # Use 5 (independently equilibrated) replicate runs
48+
slurm_config=a3.SlurmConfig(partition="<desired partition>"), # Set your desired partition!
49+
)
4250
calc.setup()
4351
calc.get_optimal_lam_vals()
4452
calc.run(adaptive=False, runtime = 5) # Run non-adaptively for 5 ns per replicate
@@ -52,10 +60,10 @@ calc.save()
5260

5361
### Copyright
5462

55-
Copyright (c) 2023, Finlay Clark
63+
Copyright (c) 2025, Finlay Clark and Roy Haolin Du
5664

5765

5866
#### Acknowledgements
59-
60-
Project based on the
67+
68+
Project based on the
6169
[Computational Molecular Science Python Cookiecutter](https://github.com/molssi/cookiecutter-cms) version 1.1.

a3fe/__init__.py

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,25 @@
1616
from .run import (
1717
CalcSet,
1818
Calculation,
19-
JobStatus,
2019
LamWindow,
2120
Leg,
22-
LegType,
23-
PreparationStage,
2421
Simulation,
2522
Stage,
23+
)
24+
25+
from .configuration import (
26+
SlurmConfig,
27+
_EngineConfig,
28+
SomdConfig,
29+
EngineType,
30+
JobStatus,
31+
LegType,
32+
PreparationStage,
2633
StageType,
27-
SystemPreparationConfig,
2834
enums,
35+
SomdSystemPreparationConfig,
2936
)
3037

31-
_sys.modules["EnsEquil"] = _sys.modules["a3fe"]
32-
3338
# A3FE can open many files due to the use of multiprocessing and
3439
# threading with MBAR. This can cause a "Too many open files" error.
3540
# The following code increases the number of open files allowed to the

a3fe/_version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "0.3.6"
1+
__version__ = "0.4.0"

a3fe/analyse/detect_equil.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,10 @@ def check_equil_block_gradient(
5858
gradient_threshold = lam_win.gradient_threshold
5959

6060
# Conversion between time and gradient indices.
61-
time_to_ind = 1 / (lam_win.sims[0].timestep * lam_win.sims[0].nrg_freq)
61+
time_to_ind = 1 / (
62+
lam_win.sims[0].engine_config.timestep
63+
* lam_win.sims[0].engine_config.energy_frequency
64+
)
6265
idx_block_size = int(lam_win.block_size * time_to_ind)
6366

6467
# Read dh/dl data from all simulations and calculate the gradient of the
@@ -183,7 +186,10 @@ def check_equil_chodera(
183186
run_nos: _List[int] = lam_win._get_valid_run_nos(run_nos)
184187

185188
# Conversion between time and gradient indices.
186-
time_to_ind = 1 / (lam_win.sims[0].timestep * lam_win.sims[0].nrg_freq)
189+
time_to_ind = 1 / (
190+
lam_win.sims[0].engine_config.timestep
191+
* lam_win.sims[0].engine_config.energy_frequency
192+
)
187193

188194
# Read dh/dl data from all simulations
189195
dh_dls = []
@@ -323,7 +329,7 @@ def check_equil_multiwindow(
323329
equil_time = (
324330
_np.sum(
325331
[
326-
lam_win.get_total_simtime(run_nos=run_nos)
332+
lam_win.get_tot_simtime(run_nos=run_nos)
327333
for lam_win in lambda_windows
328334
]
329335
)

0 commit comments

Comments
 (0)