Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
107 commits
Select commit Hold shift + click to select a range
07070d0
Move SystemPreparationConfig to configuration module
Dec 31, 2024
cab2821
Update SystemPreparationConfig to avoid deprecation warnings
Dec 31, 2024
835fc9d
Serialise SystemPreparationConfig to YAML
Dec 31, 2024
9c9d808
Improve naming of sysprep config module
Dec 31, 2024
182b237
Improve the error message for attempted analysis when data is unequil…
Jan 3, 2025
289fd44
Merge branch 'michellab:feature-decouple-somd-2' into feature-decoupl…
fjclark Jan 3, 2025
b11c846
Merge pull request #23 from fjclark/feature-decouple-somd-2
Roy-Haolin-Du Jan 4, 2025
37566a8
Replace run_somd.sh with Pydantic config
Jan 4, 2025
ad9f1aa
Merge remote-tracking branch 'upstream/feature-decouple-somd-2' into …
Jan 4, 2025
3503aac
Merge pull request #25 from fjclark/feature-decouple-somd-2
Roy-Haolin-Du Jan 5, 2025
8dc92c7
Replace template_config.cfg with Pydantic config
Roy-Haolin-Du Jan 6, 2025
b654a04
test and format for removing run_somd.sh and template_config.cfg
Roy-Haolin-Du Jan 6, 2025
fb7346c
Update engine_config validation, ncycle, runtime and test passed
Roy-Haolin-Du Jan 8, 2025
ec4858f
keep partition as default
Roy-Haolin-Du Jan 8, 2025
abc0b9e
Flexibly handle SOMD configuration files and create an abstract base …
Roy-Haolin-Du Jan 9, 2025
624576e
engine_confi and test
Roy-Haolin-Du Jan 12, 2025
f0730aa
engine_confi and test
Roy-Haolin-Du Jan 12, 2025
8d7b957
only consult somd_config object, not read from files
Roy-Haolin-Du Jan 16, 2025
5c1c09f
consult engine_config to update somd.cfg with the necessary configura…
Roy-Haolin-Du Jan 20, 2025
3c760ef
refactor the lambda array and writing of somd.cfg at diff stages
Roy-Haolin-Du Jan 26, 2025
7b97261
nmoves is a required to be written into somd.cfg
Roy-Haolin-Du Jan 26, 2025
5be62d1
Pass self-set runtime and add simulation timestep attribute
Roy-Haolin-Du Jan 26, 2025
96a6b78
Tweak EngineConfig and refactor system preparation
Jan 28, 2025
c3abd46
save enginetype between loading and dump, job name at pre-stages
Roy-Haolin-Du Feb 2, 2025
7b8e4c3
pass lambda parameters
Roy-Haolin-Du Feb 3, 2025
d96c928
EnsEnsure first ensemble equilibration restraint is used for all runs
Feb 3, 2025
f832e86
Fix incorrect stage setter in Leg
Feb 3, 2025
99be80c
Move system prep config attribute descriptions to the fields
Feb 3, 2025
a8c315c
Make get_file_name a static method
Feb 3, 2025
08e0ef6
Make load function ignorant of derived classes
Feb 3, 2025
5612727
Fix order of decorators
Feb 3, 2025
76f40d4
Supply lambda values to engine config
Feb 3, 2025
d7eacda
Import dicts of engine type to config maps in __init__
Feb 3, 2025
b1d2368
Ensure lambda value information is passed to simulation configs
Feb 3, 2025
496aeff
check if need restraint at bound/free leg or not
Roy-Haolin-Du Feb 4, 2025
8c0351e
make sure write path for top,crd,mor files in somd.cfg
Roy-Haolin-Du Feb 5, 2025
484cc9d
Only restrain stage need turn on rep-lig on
Roy-Haolin-Du Feb 5, 2025
68fa305
pass timestep and nrg_freq to simulation attribute and correct crd to…
Roy-Haolin-Du Feb 6, 2025
1f63593
ruff check for removing unsed func
Roy-Haolin-Du Feb 6, 2025
a5348f0
add test for update_engine_config_option and modify engine_config tes…
Roy-Haolin-Du Feb 9, 2025
49b4e68
Delete redundant comments
Roy-Haolin-Du Feb 9, 2025
d4f4253
change for importng new SomdSystemPreparationConfig
Roy-Haolin-Du Feb 9, 2025
aa924a6
add test for the update_engine_config_option functio
Roy-Haolin-Du Feb 9, 2025
89490f8
Only bound state need restraints
Roy-Haolin-Du Feb 10, 2025
2b9bf88
self.engine_config.timestep/nrg_freq - make sure the information is s…
Roy-Haolin-Du Feb 10, 2025
19c5b98
import SomdSystemPreparationConfig instead of Systemprepconfig used b…
Roy-Haolin-Du Feb 10, 2025
b34738e
self.engine_config.timestep etc - this means the information is store…
Roy-Haolin-Du Feb 14, 2025
b231b56
Make new test files for testing
Roy-Haolin-Du Feb 14, 2025
1cdf9b3
Make new test files for testing
Roy-Haolin-Du Feb 14, 2025
6a0efab
self.engine_config.timestep etc - this means the information is store…
Roy-Haolin-Du Feb 14, 2025
2a59db6
copy restraint file into stage input and output folders
Roy-Haolin-Du Feb 14, 2025
68b1790
If read lambda from cfg file, make sure pass lambda to lambda_values
Roy-Haolin-Du Feb 14, 2025
d25f6e5
New test files
Roy-Haolin-Du Feb 14, 2025
50f3e1b
Make required stages a property of the sysprep config
Feb 19, 2025
23243d0
Move enums to configuration
Feb 19, 2025
7ac160e
In progress... store engine config info in EngineType enum
Feb 19, 2025
439d203
Merge branch 'feature-decouple-somd-3' of https://github.com/Roy-Haol…
Feb 19, 2025
d7614f3
changed the EngineType enum,removed the mapping dictionaries
Roy-Haolin-Du Feb 24, 2025
769fd70
making new test data for usage of testing
Roy-Haolin-Du Feb 24, 2025
dbdbaee
making sure somd.cfg is written in the correct place and lambda value…
Roy-Haolin-Du Feb 24, 2025
b353206
New test files for removing mapping, correct somd.cfg writen and lamb…
Roy-Haolin-Du Feb 24, 2025
2aed196
Make sure get_result function reads the Scorrect surm output file
Roy-Haolin-Du Feb 27, 2025
1db8210
Merge pull request #29 from Roy-Haolin-Du/feature-decouple-somd-3
Roy-Haolin-Du Feb 28, 2025
81819f1
ruff check for consistent file formatting
Roy-Haolin-Du Mar 3, 2025
a47a53e
changed the EngineType enum, remove the mapping dictionaries
Roy-Haolin-Du Mar 3, 2025
2a2c1c4
Test the EngineType enum
Roy-Haolin-Du Mar 3, 2025
833ab6a
Merge branch 'michellab:feature-decouple-somd-3' into feature-decoupl…
Roy-Haolin-Du Mar 3, 2025
aaf595d
Correct the tmp_files name in analyse
Roy-Haolin-Du Mar 4, 2025
d51eccd
Enable lam_vals to be set when lambda values are passed from engine_c…
Roy-Haolin-Du Mar 4, 2025
cf3fc80
Add integrations tests to be run locally, but won't be run on the CI
Roy-Haolin-Du Mar 4, 2025
d90398e
ruff formating for all files
Roy-Haolin-Du Mar 5, 2025
d106e89
Still import SomdConfig and SomdSystemPreparationConfig so that can a…
Roy-Haolin-Du Mar 12, 2025
50b2281
remove comments and redundant copy
Roy-Haolin-Du Mar 12, 2025
f1a80c4
Make the test functions specific to SOMD and pass engine_type into a3…
Roy-Haolin-Du Mar 12, 2025
320e6d4
updating config options at calculation level and checking the changes…
Roy-Haolin-Du Mar 12, 2025
57d1cdd
Make sure integrations test (non-)adapative run working
Roy-Haolin-Du Mar 13, 2025
a2826d3
ruff formating for all files
Roy-Haolin-Du Mar 13, 2025
81b5021
Some extensive docs on new features. Adding Makefile and pre-commit-c…
Roy-Haolin-Du Mar 20, 2025
954c8b2
Simplied env setup in Makefile and CI configuration
Roy-Haolin-Du Mar 27, 2025
9e46e01
Extensive docs on new features and simplify pre-commit hooks
Roy-Haolin-Du Apr 11, 2025
19b16bb
refactor calc.setup: sysprep_config setting both bound and free legs
Roy-Haolin-Du Apr 11, 2025
d7a1829
update engine config at top level using update_engine_config_option f…
Roy-Haolin-Du Apr 11, 2025
7ed93fe
check the exact expected equil time is found in adaptive test
Roy-Haolin-Du Apr 12, 2025
6864a47
Using a small system integration test convenient
Roy-Haolin-Du Apr 14, 2025
b44ad05
Adding python version support to make env and removing mike deployment
Roy-Haolin-Du Jun 10, 2025
4ba5fa5
Remove hardcoded leg types, enable flexible leg selection by moving v…
Roy-Haolin-Du Jun 22, 2025
bb428f2
added some guide links and config warnings to enhance documentation c…
Roy-Haolin-Du Jun 22, 2025
b73d624
Streamlined the installation process with a Makefile.
Roy-Haolin-Du Jun 23, 2025
2a83c5f
Remove hardcoded leg types, enable flexible leg selection by moving i…
Roy-Haolin-Du Jun 23, 2025
d754861
Format check
Roy-Haolin-Du Jun 23, 2025
048636f
Changed the copyright notice to 2023-2025 and include Roy
Roy-Haolin-Du Aug 11, 2025
0c46092
simfile_option related redundant functionality removed
Roy-Haolin-Du Sep 22, 2025
9c631e6
Make sure pydantic validation working and adding test
Roy-Haolin-Du Sep 22, 2025
e299a48
fix small typo
Roy-Haolin-Du Sep 22, 2025
152962f
fix small typo
Roy-Haolin-Du Sep 22, 2025
8a085c7
fix small typo
Roy-Haolin-Du Sep 22, 2025
9bae935
Coorect input validation in setup()
Roy-Haolin-Du Sep 22, 2025
afc38dd
Merge pull request #40 from Roy-Haolin-Du/feature-decouple-somd-3
Roy-Haolin-Du Sep 23, 2025
00590b2
Fix merge conflicts and complete test
Roy-Haolin-Du Oct 5, 2025
6fe519a
Merge branch 'michellab:feature-decouple-somd-3' into feature-decoupl…
Roy-Haolin-Du Oct 5, 2025
608ae3d
Merge pull request #71 from Roy-Haolin-Du/feature-decouple-somd-3
Roy-Haolin-Du Oct 5, 2025
dc2242d
Fix CI Docker image name from condaforge/mamba-base to condaforge/mam…
Roy-Haolin-Du Oct 5, 2025
0dee254
adding SLURM config for test fixtures
Roy-Haolin-Du Oct 5, 2025
6c5fc2a
adding SLURM config for test
Roy-Haolin-Du Oct 6, 2025
b293e61
Fix CI: build docs before cleanup in Makefile
Roy-Haolin-Du Oct 6, 2025
3e86e55
Fix CI: remove without sphinx-build in Makefile
Roy-Haolin-Du Oct 6, 2025
7a4d8ac
Added SLURM queue check intervals into SlurmConfig class Fixes #70
Roy-Haolin-Du Oct 8, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
65 changes: 18 additions & 47 deletions .github/workflows/CI.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
name: CI

concurrency:
group: ${{ github.ref }}
cancel-in-progress: true

on:
# GitHub has started calling new repo's first branch "main" https://github.com/github/renaming
# The cookiecutter uses the "--initial-branch" flag when it runs git-init
Expand All @@ -16,70 +20,37 @@ on:
- cron: "0 0 * * 0"

jobs:
# Check with ruff and black
lint_and_format:
name: Check for style and formatting violations with Ruff
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@v2

- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: '3.10'

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install ruff

- name: Check style with Ruff
run: ruff check .

- name: Check formatting with Ruff
run: ruff format --check .

test:
name: Test on ${{ matrix.os }}, Python ${{ matrix.python-version }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest]
python-version: ['3.10', '3.11', '3.12']

container: condaforge/mambaforge:latest

steps:
- uses: actions/checkout@v3
- name: Check out code
uses: actions/checkout@v3.3.0

- name: Additional info about the build
shell: bash
- name: Install system dependencies
run: |
uname -a
df -h
ulimit -a

- uses: mamba-org/setup-micromamba@v1
with:
environment-file: devtools/conda-envs/test_env.yaml
environment-name: test
create-args: >- # beware the >- instead of |, we don't split on newlines but on spaces
python=${{ matrix.python-version }}
apt update && apt install -y git make

- name: Install package
# conda setup requires this special shell
shell: bash -l {0}
- name: Setup environment for Python ${{ matrix.python-version }}
run: |
python -m pip install . --no-deps
micromamba list
make env-ci PYTHON_VERSION=${{ matrix.python-version }}

- name: Run tests
# conda setup requires this special shell
shell: bash -l {0}
- name: Run linting and tests
run: |
pytest -v --cov=a3fe --cov-report=xml --color=yes a3fe/tests/
make lint
make test
make docs
make clean

- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v4.0.1
with:
file: ./coverage.xml
token: ${{ secrets.CODECOV_TOKEN }}
slug: michellab/a3fe
28 changes: 28 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# .pre-commit-config.yaml
repos:
# Basic file cleanup hooks
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v3.2.0
hooks:
- id: trailing-whitespace # delete trailing whitespace
- id: end-of-file-fixer # ensure file ends with a blank line
- id: check-yaml # check yaml syntax
- id: check-added-large-files # prevent large files from being added
- id: check-merge-conflict # check for unresolved merge conflicts

# Use local commands to format and check code
- repo: local
hooks:
# code format hook
- id: ruff
name: Autoformat python code
language: system
entry: bash
args: [-c, "make format"]

# code check hook
- id: ruff
name: Lint python code
language: system
entry: bash
args: [-c, "make lint"]
2 changes: 1 addition & 1 deletion .readthedocs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@ sphinx:
configuration: docs/conf.py

conda:
environment: devtools/conda-envs/test_env.yaml
environment: devtools/conda-envs/ci_env.yaml
2 changes: 1 addition & 1 deletion CODE_OF_CONDUCT.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ project may be further defined and clarified by project maintainers.
## Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at 'finlay.clark@ed.ac.uk'. The project team will
reported by contacting the project team at 'finlay.clark@ed.ac.uk or s2015679@ed.ac.uk'. The project team will
review and investigate all complaints, and will respond in a way that it deems
appropriate to the circumstances. The project team is obligated to maintain
confidentiality with regard to the reporter of an incident. Further details of
Expand Down
66 changes: 66 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
PACKAGE_NAME := a3fe
PACKAGE_DIR := a3fe

# Only need slurm, which is linux only
CONDA_ENV_RUN = conda run --no-capture-output --name $(PACKAGE_NAME)

TEST_ARGS := -v --cov=$(PACKAGE_DIR) --cov-report=term --cov-report=xml --junitxml=unit.xml --color=yes

.PHONY: env env-dev env-ci lint format test test-integration docs-build docs clean

# Regular users:
env:
mamba create -y --name $(PACKAGE_NAME) $(if $(PYTHON_VERSION),python=$(PYTHON_VERSION))
mamba env update --name $(PACKAGE_NAME) --file devtools/conda-envs/base_env.yaml
$(CONDA_ENV_RUN) pip install --no-deps -e .

# Developers with local GROMACS
env-dev:
mamba create -y --name $(PACKAGE_NAME) $(if $(PYTHON_VERSION),python=$(PYTHON_VERSION))
mamba env update --name $(PACKAGE_NAME) --file devtools/conda-envs/dev_env.yaml
$(CONDA_ENV_RUN) pip install --no-deps -e .
$(CONDA_ENV_RUN) pre-commit install || true

# CI and developers without GROMACS
env-ci:
mamba create -y --name $(PACKAGE_NAME) $(if $(PYTHON_VERSION),python=$(PYTHON_VERSION))
mamba env update --name $(PACKAGE_NAME) --file devtools/conda-envs/ci_env.yaml
$(CONDA_ENV_RUN) pip install --no-deps -e .
$(CONDA_ENV_RUN) pre-commit install || true

# code check
lint:
$(CONDA_ENV_RUN) ruff check $(PACKAGE_DIR)

# code format
format:
$(CONDA_ENV_RUN) ruff format $(PACKAGE_DIR)
$(CONDA_ENV_RUN) ruff check --fix --select I $(PACKAGE_DIR)

# run tests
test:
$(CONDA_ENV_RUN) pytest $(TEST_ARGS) $(PACKAGE_DIR)/tests/

# run integration tests (requires SLURM environment)
test-integration:
$(CONDA_ENV_RUN) RUN_SLURM_TESTS=1 pytest $(TEST_ARGS) $(PACKAGE_DIR)/tests/ --run-integration -v

# build docs
docs-build:
cd docs && $(CONDA_ENV_RUN) make html

docs:
cd docs && $(CONDA_ENV_RUN) make html
@echo "Documentation built in docs/_build/html/"

# clean build files
clean:
rm -rf docs/_build/
rm -rf build/
rm -rf dist/
rm -rf *.egg-info
find . -type d -name __pycache__ -exec rm -rf {} +
find . -type f -name "*.pyc" -delete

# deploy docs
# consider supporting this in the future
30 changes: 19 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ a3fe
[![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0)
[![Documentation Status](https://readthedocs.org/projects/a3fe/badge/?version=latest)](https://a3fe.readthedocs.io/en/latest/?badge=latest)
[![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)

<img src="./a3fe_logo.png" alt="Alt text" style="width: 50%; height: 50%;">

**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).
Expand All @@ -19,26 +19,34 @@ For details of the algorithms and testing, please see the assocated paper:

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.

Now, download and install a3fe:
Now, download and install a3fe. Choose the appropriate environment for your use case:

**Regular users:**
```bash
git clone https://github.com/michellab/a3fe.git
cd a3fe
mamba env create -f environment.yaml
make env
mamba activate a3fe
python -m pip install --no-deps .
```

**Developers with local GROMACS:**
```bash
make env-dev
```

### Quick Start

- Activate your a3fe conda environment
- Activate your a3fe conda environment
- Create a base directory for the calculation and create an directory called `input` within this
- 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.
- 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
- 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)

```python
import a3fe as a3
calc = a3.Calculation(ensemble_size=5)
import a3fe as a3
calc = a3.Calculation(
ensemble_size=5, # Use 5 (independently equilibrated) replicate runs
slurm_config=a3.SlurmConfig(partition="<desired partition>"), # Set your desired partition!
)
calc.setup()
calc.get_optimal_lam_vals()
calc.run(adaptive=False, runtime = 5) # Run non-adaptively for 5 ns per replicate
Expand All @@ -52,10 +60,10 @@ calc.save()

### Copyright

Copyright (c) 2023, Finlay Clark
Copyright (c) 2025, Finlay Clark and Roy Haolin Du


#### Acknowledgements
Project based on the

Project based on the
[Computational Molecular Science Python Cookiecutter](https://github.com/molssi/cookiecutter-cms) version 1.1.
17 changes: 11 additions & 6 deletions a3fe/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,25 @@
from .run import (
CalcSet,
Calculation,
JobStatus,
LamWindow,
Leg,
LegType,
PreparationStage,
Simulation,
Stage,
)

from .configuration import (
SlurmConfig,
_EngineConfig,
SomdConfig,
EngineType,
JobStatus,
LegType,
PreparationStage,
StageType,
SystemPreparationConfig,
enums,
SomdSystemPreparationConfig,
)

_sys.modules["EnsEquil"] = _sys.modules["a3fe"]

# A3FE can open many files due to the use of multiprocessing and
# threading with MBAR. This can cause a "Too many open files" error.
# The following code increases the number of open files allowed to the
Expand Down
2 changes: 1 addition & 1 deletion a3fe/_version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "0.3.6"
__version__ = "0.4.0"
12 changes: 9 additions & 3 deletions a3fe/analyse/detect_equil.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,10 @@ def check_equil_block_gradient(
gradient_threshold = lam_win.gradient_threshold

# Conversion between time and gradient indices.
time_to_ind = 1 / (lam_win.sims[0].timestep * lam_win.sims[0].nrg_freq)
time_to_ind = 1 / (
lam_win.sims[0].engine_config.timestep
* lam_win.sims[0].engine_config.energy_frequency
)
idx_block_size = int(lam_win.block_size * time_to_ind)

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

# Conversion between time and gradient indices.
time_to_ind = 1 / (lam_win.sims[0].timestep * lam_win.sims[0].nrg_freq)
time_to_ind = 1 / (
lam_win.sims[0].engine_config.timestep
* lam_win.sims[0].engine_config.energy_frequency
)

# Read dh/dl data from all simulations
dh_dls = []
Expand Down Expand Up @@ -323,7 +329,7 @@ def check_equil_multiwindow(
equil_time = (
_np.sum(
[
lam_win.get_total_simtime(run_nos=run_nos)
lam_win.get_tot_simtime(run_nos=run_nos)
for lam_win in lambda_windows
]
)
Expand Down
Loading
Loading