Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Properly set the cutoff distance in HTF nonbonded forces #675

Merged
merged 7 commits into from
Jan 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 4 additions & 6 deletions openfe/protocols/openmm_rfe/_rfe_utils/relative.py
Original file line number Diff line number Diff line change
Expand Up @@ -900,25 +900,21 @@ def _add_nonbonded_force_terms(self):
# Select functional form based on nonbonded method.
# TODO: check _nonbonded_custom_ewald and _nonbonded_custom_cutoff
# since they take arguments that are never used...
r_cutoff = self._old_system_forces['NonbondedForce'].getCutoffDistance()
IAlibay marked this conversation as resolved.
Show resolved Hide resolved
sterics_energy_expression = self._nonbonded_custom(self._softcore_LJ_v2)
if self._nonbonded_method in [openmm.NonbondedForce.NoCutoff]:
sterics_energy_expression = self._nonbonded_custom(
self._softcore_LJ_v2)
elif self._nonbonded_method in [openmm.NonbondedForce.CutoffPeriodic,
openmm.NonbondedForce.CutoffNonPeriodic]:
epsilon_solvent = self._old_system_forces['NonbondedForce'].getReactionFieldDielectric()
r_cutoff = self._old_system_forces['NonbondedForce'].getCutoffDistance()
sterics_energy_expression = self._nonbonded_custom(
self._softcore_LJ_v2)
standard_nonbonded_force.setReactionFieldDielectric(
epsilon_solvent)
standard_nonbonded_force.setCutoffDistance(r_cutoff)
elif self._nonbonded_method in [openmm.NonbondedForce.PME,
openmm.NonbondedForce.Ewald]:
[alpha_ewald, nx, ny, nz] = self._old_system_forces['NonbondedForce'].getPMEParameters()
delta = self._old_system_forces['NonbondedForce'].getEwaldErrorTolerance()
r_cutoff = self._old_system_forces['NonbondedForce'].getCutoffDistance()
sterics_energy_expression = self._nonbonded_custom(
self._softcore_LJ_v2)
standard_nonbonded_force.setPMEParameters(alpha_ewald, nx, ny, nz)
standard_nonbonded_force.setEwaldErrorTolerance(delta)
standard_nonbonded_force.setCutoffDistance(r_cutoff)
Expand All @@ -939,6 +935,8 @@ def _add_nonbonded_force_terms(self):

sterics_custom_nonbonded_force = openmm.CustomNonbondedForce(
total_sterics_energy)
# Match cutoff from non-custom NB forces
sterics_custom_nonbonded_force.setCutoffDistance(r_cutoff)

if self._softcore_LJ_v2:
sterics_custom_nonbonded_force.addGlobalParameter(
Expand Down
39 changes: 39 additions & 0 deletions openfe/tests/protocols/test_openmm_equil_rfe_protocols.py
Original file line number Diff line number Diff line change
Expand Up @@ -547,6 +547,45 @@
assert e1 == e2 == 0


@pytest.mark.slow
@pytest.mark.parametrize('cutoff',
[1.0 * unit.nanometer,
12.0 * unit.angstrom,
0.9 * unit.nanometer]
)
def test_dry_run_ligand_system_cutoff(
cutoff, benzene_system, toluene_system, benzene_to_toluene_mapping, tmpdir
):
"""
Test that the right nonbonded cutoff is propagated to the hybrid system.
"""
settings = openmm_rfe.RelativeHybridTopologyProtocol.default_settings()
settings.solvation_settings.solvent_padding = 1.5 * unit.nanometer
settings.system_settings.nonbonded_cutoff = cutoff

Check warning on line 564 in openfe/tests/protocols/test_openmm_equil_rfe_protocols.py

View check run for this annotation

Codecov / codecov/patch

openfe/tests/protocols/test_openmm_equil_rfe_protocols.py#L562-L564

Added lines #L562 - L564 were not covered by tests

protocol = openmm_rfe.RelativeHybridTopologyProtocol(

Check warning on line 566 in openfe/tests/protocols/test_openmm_equil_rfe_protocols.py

View check run for this annotation

Codecov / codecov/patch

openfe/tests/protocols/test_openmm_equil_rfe_protocols.py#L566

Added line #L566 was not covered by tests
settings=settings,
)
dag = protocol.create(

Check warning on line 569 in openfe/tests/protocols/test_openmm_equil_rfe_protocols.py

View check run for this annotation

Codecov / codecov/patch

openfe/tests/protocols/test_openmm_equil_rfe_protocols.py#L569

Added line #L569 was not covered by tests
stateA=benzene_system,
stateB=toluene_system,
mapping={'ligand': benzene_to_toluene_mapping},
)
dag_unit = list(dag.protocol_units)[0]

Check warning on line 574 in openfe/tests/protocols/test_openmm_equil_rfe_protocols.py

View check run for this annotation

Codecov / codecov/patch

openfe/tests/protocols/test_openmm_equil_rfe_protocols.py#L574

Added line #L574 was not covered by tests

with tmpdir.as_cwd():
sampler = dag_unit.run(dry=True)['debug']['sampler']
hs = sampler._factory.hybrid_system

Check warning on line 578 in openfe/tests/protocols/test_openmm_equil_rfe_protocols.py

View check run for this annotation

Codecov / codecov/patch

openfe/tests/protocols/test_openmm_equil_rfe_protocols.py#L578

Added line #L578 was not covered by tests

nbfs = [f for f in hs.getForces() if

Check warning on line 580 in openfe/tests/protocols/test_openmm_equil_rfe_protocols.py

View check run for this annotation

Codecov / codecov/patch

openfe/tests/protocols/test_openmm_equil_rfe_protocols.py#L580

Added line #L580 was not covered by tests
isinstance(f, CustomNonbondedForce) or
isinstance(f, NonbondedForce)]

for f in nbfs:
f_cutoff = from_openmm(f.getCutoffDistance())
assert f_cutoff == cutoff

Check warning on line 586 in openfe/tests/protocols/test_openmm_equil_rfe_protocols.py

View check run for this annotation

Codecov / codecov/patch

openfe/tests/protocols/test_openmm_equil_rfe_protocols.py#L584-L586

Added lines #L584 - L586 were not covered by tests


@pytest.mark.flaky(reruns=3) # bad minimisation can happen
def test_dry_run_user_charges(benzene_modifications, tmpdir):
"""
Expand Down