Skip to main content

Calculates ligand strain of small molecules from their docked poses.

Project description

StrainRelief 💊

StrainRelief calculates the ligand strain of 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 and also Meta's FAIRChem models, such as e-SEN and UMA. Optimisations are run in parallel using the neural-optimiser package.

  • 📄 The publication can be found here.
  • 📊 All relevant datasets here.
  • 💬 RAG chatbot for questions about the paper and references.
  • 💻 Chatbot source code.
  • 📉 neural-optimiser package.

Strain Relief Logo

Update 1.0.0

This update focuses on accelerating the StrainRelief backend and increasig usability through simpler configurations and workflows:

  • Molecular optimisation are now paralellised using the neural-optimiser package providing a 3x speed-up.
  • New simplified hyra configuration. An example of the full configuration is given here.

Note: this introduces changes that are not backwards-compatible with previous versions.

Installation

Pre-requisities: Python 3.11, PyTorch and PyTorch Geometric compatible with your envirnment

# For example
uv pip install torch==2.8.0 -f https://data.pyg.org/whl/torch-2.8.0+cu128.html
uv pip install torch-geometric==2.7.0 torch-cluster -f https://data.pyg.org/whl/torch-2.8.0+cu128.html

Installation from PyPi

pip install strain-relief

Installation from source (uv)

uv sync --extra dev --editable

or create a virtual environment and install the package and its dependencies in editable mode:

uv venv
source .venv/bin/activate
# [install torch and torch-geometric as above]
uv pip install -e ".[dev]"
uv pip install --force-reinstall e3nn==0.5 fairchem-core

uv run pre-commit install

Note: 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).

The Protocol

The 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 a neural-optimiser Calculator class (such as an ASE calculator wrapper). Additionally, the package is already compatible with all MACE and Meta FAIRChem models.

Strain Relief Protocol

The protocol consists of 5 steps:

  1. Minimise the docked pose with a loose convergence criteria to give a local minimum.
  2. Generate 20 conformers from the docked ligand pose.
  3. Minimise the generated conformers (and the original docked pose) with a stricter convergence criteria.
  4. Evaluate the energy of all conformers and choose the lowest energy as an approximation of the global minimum.
  5. Calculate E(ligand strain) = E(local minimum) - E(global minimum) and apply threshold.

N.B. energies returned are in kcal/mol.

Usage

StrainRelief runs are configured using hydra configs.

Python Package

from strain_relief import compute_strain

computed = 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 set of examples see the tutorial notebook.

Command Line

strain-relief \
    experiment=mmff94 \
    io.input.parquet_path=data/example_ligboundconf_input.parquet \
    io.output.parquet_path=data/example_ligboundconf_output.parquet \
    conformers.numConfs=1 \

More examples are given here, including the command used for the calculations in the StrainRelief paper.

Adding Your Own Calculator

Add a new Calculator class from neural-optimiser to the strain_relief/calculators/ directory. This can be as simple as implementing a wrapper around an existing ASE calculator:

from neural_optimiser.calculators.base import Calculator

class YourCalculator(Calculator):

    def __init__(self, **kwargs):
        self.calculator = YourASECalculator(**kwargs)

    def _calculate(self, batch: Data | Batch) -> tuple[torch.Tensor, torch.Tensor]:
        """Return (energies, forces) from the calculator."""
        ase_atoms = batch.to_ase()
        ase_atoms.calc = self.calculator
        return ase_atoms.get_potential_energy(), ase_atoms.get_gradients()

Note: MACECalculator and FAIRChemCalculator from neural-optimiser use a from_atomic_data helper method. This converts ConformerBatch objects to AtomicData model inputs in a batched process; a workflow bottleneck not handled by either the MACE or FAIRChem internal ASE calculators. I would recommend implementing something similar for high throughput workflows.

Add a new config to hydra_config/calculator/your_calculator.yaml:

_target_: strain_relief.calculators.your_calculator.YourCalculator
model_paths: null
device: ${device}
any_other_kwargs: null

Configurations

Common kwargs

  • threshold (set by default to 16.1 kcal/mol - calibrated using LigBoundConf 2.0)
  • conformers.numConfs
  • global_optimiser.steps/local_optimiser.steps
  • global_optimiser.fmax/local_optimiser.fmax
  • io.input.include_charged
  • hydra.verbose
  • seed

Logging

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.

Unit Tests

  • uv run pytest tests/ - runs all tests (unit and integration)
  • uv run pytest tests/ -m "not integration" - runs all unit tests

Note: Unit tests will run on a GPU if available.

Citations

If you use StrainRelief or adapt the StrainRelief code for any purpose, please cite:

@article{wallace2025strain,
  title={Strain Problems Got You in a Twist? Try StrainRelief: A Quantum-Accurate Tool for Ligand Strain Calculations},
  author={Wallace, Ewan RS and Frey, Nathan C and Rackers, Joshua A},
  journal={Journal of Chemical Information and Modeling},
  year={2025},
  publisher={ACS Publications},
  url={https://pubs.acs.org/doi/10.1021/acs.jcim.5c00586}
}

More information

For any questions, please reach out to Ewan Wallace: ewan.wallace@roche.com

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

strain_relief-1.0.dev0.tar.gz (17.9 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

strain_relief-1.0.dev0-py3-none-any.whl (24.5 kB view details)

Uploaded Python 3

File details

Details for the file strain_relief-1.0.dev0.tar.gz.

File metadata

  • Download URL: strain_relief-1.0.dev0.tar.gz
  • Upload date:
  • Size: 17.9 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for strain_relief-1.0.dev0.tar.gz
Algorithm Hash digest
SHA256 fdffcaad250707fc76fd3c9e24470e5f7f0b9941abd7e53da1954bdbad3d46ec
MD5 11491a7a5fdd7c350df125ea638d5688
BLAKE2b-256 275bb43eae59b5a22b422282d1ac48e0ead615568adc03d7e73ef80072ca85d6

See more details on using hashes here.

Provenance

The following attestation bundles were made for strain_relief-1.0.dev0.tar.gz:

Publisher: pypi.yml on prescient-design/StrainRelief

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file strain_relief-1.0.dev0-py3-none-any.whl.

File metadata

File hashes

Hashes for strain_relief-1.0.dev0-py3-none-any.whl
Algorithm Hash digest
SHA256 d0b336a8d96a8b42257025b41e3e8c9a692c07a390d99fc2e908e6a69c1dc460
MD5 2113f79967c0b04cf600792469230604
BLAKE2b-256 58478177a7b8ef84991ba79cb76d4261eea3b0c1750d28644099417a357cae44

See more details on using hashes here.

Provenance

The following attestation bundles were made for strain_relief-1.0.dev0-py3-none-any.whl:

Publisher: pypi.yml on prescient-design/StrainRelief

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page