StrainRelief calculates the ligand strain of uncharged docked poses and has a suite of different force fields with which to do this. This includes our own MACE neural network potential trained on SPICE2 but also includes Meta's FairChem models such as e-SEN and UMA.
- 📄 The publication can be found here.
- 📊 All relevant datasets here.
- 💬 RAG chatbot for questions about the paper and references.
- 💻 Chatbot source code.
- 🐍 Published python package.
- Switched to uv for package management.
- Introduced custom typing (
MolsDict,MolPropertiesDict,EnergiesDictandConfEnergiesDict) to make functions more readable. - Updated workflows and
MolsDictto include charge and spin. This allows for charge aware NNPs such as eSEN and UMA. A boolean kwarg (include_charged=True) has been added toload_parquetsto optionally filter these out. - Restructured calling of the main function to make it more intuitive with PyPi packaging.
pip install strain-relief
Install uv if not already installed. Create a new uv enviroment using:
uv venv
source .venv/bin/activateFrom the root directory, run the following commands to install the package and its dependencies in editable mode:
(mace-torch==0.3.x requires e3nn==0.4.4 (only for training, not inference). fairchem-core requires e3nn>=0.5. So until mace-torch==0.4 is released we will have to do this finicky way of installing (GitHub issue).)
git clone https://github.com/prescient-design/StrainRelief.git
uv pip install -e ".[dev]"
uv pip install --force-reinstall e3nn==0.5 fairchem-core
uv run pre-commit installor if you have a uv.lock file:
uv sync --extra dev --editableThe protocol used in StrainRelief is designed to be simple, fast and model agnostic - all that is needed to apply a new force field is to write an ASE calculator wrapper. Additionally you can use any MACE model, such as these from the MACE-OFF23 repository.
The protocol consists of 5 steps:
- Minimise the docked pose with a loose convergence criteria to give a local minimum.
- Generate 20 conformers from the docked ligand pose.
- Minimise the generated conformers (and the original docked pose) with a stricter convergence criteria.
- Evaluate the energy of all conformers and choose the lowest energy as an approximation of the global minimum.
- Calculate
E(ligand strain) = E(local minimum) - E(global minimum)and apply threshold.
N.B. energies returned are in kcal/mol.
StrainRelief runs are configured using hydra configs.
from strain_relief import compute_strain
strains = compute_strain(poses: list[RDKit.Mol], config: DictConfig)
for i, r in computed.iterrows():
print(f"Pose {r['id']} has a strain of {r['ligand_strain']:.2f} kcal/mol")
For a complete example see the tutorial notebook.
strain-relief \
experiment=mmff94s \
io.input.parquet_path=data/example_ligboundconf_input.parquet \
io.output.parquet_path=data/example_ligboundconf_output.parquet \More examples are given here, including the command used for the calculations in the StrainRelief paper.
Add New ASE Calculator to strain_relief/calculators/_nnp.py:
def another_calculator(model_paths: str, device: str, default_dtype: str, **kwargs: Any) -> Calculator:
# set up your new ase calculator here
return calculatorAdd New Configs:
hydra_config/model/another_calculator.yamlhydra_config/energy_eval/another_calculator.yamlhydra_config/minimisation/another_calculator.yamlhydra_config/experiments[Optional]
Update Method Dicts:
strain_relief.minimisation._minimisation.METHODS_DICTstrain_relief.energy_eval._energy_eval.METHODS_DICTstrain_relief.calculators.__init__.CALCULATORS_DICT
RDKit kwargs
The following dictionaries are passed directly to the function of that name.
conformers(EmbedMultipleConfs)minimisation.MMFFGetMoleculePropertiesminimisation.MMFFGetMoleculeForceFieldenergy_eval.MMFFGetMoleculePropertiesenergy_eval.MMFFGetMoleculeForceField
The hydra config is set up to allow additional kwargs to be passed to these functions e.g. +minimisation.MMFFGetMoleculeProperties.mmffVerbosity=1.
Common kwargs
threshold(set by default to 16.1 kcal/mol - calibrated using LigBoundConf 2.0)conformers.numConfsglobal_min.maxIters/local_min.maxItersglobal_min.fmax/local_min.maxItersio.input.include_chargedhydra.verboseseed
Logging is set to the INFO level by default which logs only aggregate information. hydra.verbose=true can be used to activate DEBUG level logging which includes information for every molecule and conformer.
uv run pytest tests/- runs all tests (unit and integration)uv run pytest tests/ -m "not gpu"- excludes all MACE testsuv run pytest tests/ -m "not integration"- runs all unit tests
NB Tests requiring a FAIRChem model will be skipped if the OMol25 eSEN small conserving model is not located in tests/models/eSEN.pt. This model can be downloaded here.
If you use StrainRelief or adapt the StrainRelief code for any purpose, please cite:
@misc{wallace2025strainrelief,
title={Strain Problems got you in a Twist? Try StrainRelief: A Quantum-Accurate Tool for Ligand Strain Calculations},
author={Ewan R. S. Wallace and Nathan C. Frey and Joshua A. Rackers},
year={2025},
eprint={2503.13352},
archivePrefix={arXiv},
primaryClass={physics.chem-ph},
url={https://arxiv.org/abs/2503.13352},
}For any questions, please reach out to Ewan Wallace: ewan.wallace@roche.com

