Skip to content

Conversation

@hannahbaumann
Copy link
Contributor

@hannahbaumann hannahbaumann commented Dec 17, 2024

Checklist

  • Added a news entry

Developers certificate of origin

@hannahbaumann hannahbaumann changed the title [ WIP ] SepTop Protocol [WIP] SepTop Protocol Dec 17, 2024
@codecov
Copy link

codecov bot commented Dec 17, 2024

Codecov Report

❌ Patch coverage is 93.03323% with 130 lines in your changes missing coverage. Please review.
✅ Project coverage is 92.35%. Comparing base (1cb3ac7) to head (dffae05).
⚠️ Report is 119 commits behind head on main.

Files with missing lines Patch % Lines
.../tests/protocols/openmm_septop/test_septop_slow.py 67.41% 58 Missing ⚠️
openfe/protocols/openmm_septop/base.py 85.09% 38 Missing ⚠️
...nfe/protocols/openmm_septop/equil_septop_method.py 94.77% 26 Missing ⚠️
openfe/protocols/openmm_septop/utils.py 95.31% 3 Missing ⚠️
openfe/tests/protocols/conftest.py 90.32% 3 Missing ⚠️
...e/protocols/openmm_septop/equil_septop_settings.py 98.03% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1057      +/-   ##
==========================================
- Coverage   95.54%   92.35%   -3.20%     
==========================================
  Files         163      172       +9     
  Lines       12593    14454    +1861     
==========================================
+ Hits        12032    13349    +1317     
- Misses        561     1105     +544     
Flag Coverage Δ
fast-tests 92.35% <93.03%> (?)
slow-tests ?

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@atravitz atravitz mentioned this pull request Aug 15, 2025
Copy link
Member

@IAlibay IAlibay left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Docs part of the review (will self-merge the proposed changes since they are typos).


Orientational, or Boresch-style, restraints are automaticallly (unless manually specified) applied between three protein and three ligand atoms using one bond,
two angle, and three dihedral restraints. Reference atoms are picked based on different criteria, such as the root mean squared
fluctuation of the atoms in a short MD simulation, the secondary structure of the protein, and the distance between atoms, based on heuristics from Baumann et al. [2]_.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO (issued raised): update the docs here (and in ABFEs) to reflect the new picking, i.e. it's getting closer to a mix between Hannah's appproach and MDRestraintsGenerator.

Molecular interactions are modified along an alchemical path using a discrete set of lambda windows.
For the transformation of ligand A to ligand B in the binding site, the following steps are carried out, starting with ligand A being fully interacting in the binding site while ligand B is decoupled.

1. Insert the non-interacting dummy ligand B into the binding site and restrain it using orientational restraints. The contribution of the restraints is calculated analytically.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Separate issue raised: the description of the lambda schedule is non symmetric, i.e. number 5 describes transferring the ligand A to solvent, but none of these refer to transferring ligand B from the solvent (I think it's what is meant by "insert the non-interacting dummy", but the language probably needs to be improved).


The :class:`.ProtocolDAG` of the :class:`SepTopProtocol <.SepTopProtocol>` contains :class:`.ProtocolUnit`\ s from both the complex and solvent transformations.
This means that both legs of the thermodynamic cycle are constructed and run sequentially in the same :class:`.ProtocolDAG`. This is different from the :class:`.RelativeHybridTopologyProtocol` where the :class:`.ProtocolDAG` only runs a single leg of a thermodynamic cycle.
If multiple ``protocol_repeats`` are run (default: ``protocol_repeats=3``), the :class:`.ProtocolDAG` contains multiple :class:`.ProtocolUnit`\ s of both complex and solvent transformations.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unclear from this text if that means that the same restraint will be used for all repeats.

Copy link
Member

@IAlibay IAlibay left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

review for tests


# Create parent directory if it doesn't exist
filename_basedir = filename.parent
if not filename_basedir.exists():
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I opened an issue for it.

from .geometry import BoreschRestraintGeometry, find_boresch_restraint
from .geometry import (
BoreschRestraintGeometry,
find_boresch_restraint,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure why these are necessary, but we'll let isort deal with it.

assert f.read() == "<data>"


def test_serialize_gz(tmpdir):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A lot of this is duplicated for gz and bz2, they can be parameterized.

Comment on lines +169 to +171
na_A,
na_B,
nonbonded,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Passing the tags this way is really confusing. Given it's used in only one test, I would suggest moving this to a test class and then specifically checking for the key strings in the test here.

timestep=to_openmm(integrator_settings.timestep),
collision_rate=to_openmm(integrator_settings.langevin_collision_rate),
n_steps=steps_per_iteration,
reassign_velocities=integrator_settings.reassign_velocities,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs guarding from virtual sites.

Copy link
Member

@IAlibay IAlibay left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review comments for equil_septop_method

return working_platforms


def compute_energy(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is best being somewhere else than in conftest.

This Protocol is based on, and leverages components originating from
the SepTop implementation from the Mobleylab
(https://github.com/MobleyLab/SeparatedTopologies) as well as
femto (https://github.com/Psivant/femto).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should update the text to reflect "inspired by" rather than "leverages components from".

Current limitations
-------------------
* Only small molecules are allowed to act as alchemical molecules.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add limitation re: net charges

Comment on lines +1492 to +1493
Chem.SanitizeMol(rdmol_A)
Chem.SanitizeMol(rdmol_B)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Opened issue #1526 - we should document at the very least.

Copy link
Member

@IAlibay IAlibay left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Final bit of the review

from openff.toolkit.topology import Molecule as OFFMolecule
from openff.units import unit
from openff.units.openmm import ensure_quantity, from_openmm, to_openmm
from openmm import app
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a few instances where you use openmm.app and others where app is used directly. That should be cleaned up.

smc_comps_B = smc_off_B | smc_off_both
smc_comps_AB = smc_off_A | smc_off_B | smc_off_both

return smc_comps_A, smc_comps_B, smc_comps_AB, smc_off_B
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, although if it works for now it's not a high priority.

@github-actions
Copy link

No API break detected ✅

@IAlibay IAlibay merged commit 7584efe into OpenFreeEnergy:main Sep 23, 2025
12 of 13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants