From c59456a4fc78b55f9763c2d6cc7a2afdefe0c82f Mon Sep 17 00:00:00 2001 From: ijpulidos <2949729+ijpulidos@users.noreply.github.com> Date: Thu, 9 Apr 2026 22:43:29 -0400 Subject: [PATCH 01/18] Using gufe mapping charge difference utility --- feflow/protocols/nonequilibrium_cycling.py | 13 ++----------- feflow/utils/charge.py | 4 ---- 2 files changed, 2 insertions(+), 15 deletions(-) diff --git a/feflow/protocols/nonequilibrium_cycling.py b/feflow/protocols/nonequilibrium_cycling.py index 1fe639ff..46980e35 100644 --- a/feflow/protocols/nonequilibrium_cycling.py +++ b/feflow/protocols/nonequilibrium_cycling.py @@ -239,17 +239,8 @@ def _execute(self, ctx, *, protocol, state_a, state_b, mapping, **inputs): ) # Handle charge corrections/transformations - # Get the change difference between the end states - # and check if the charge correction used is appropriate - try: # Catch unsupported charges differences and raise protocol error - charge_difference = get_alchemical_charge_difference( - mapping, - forcefield_settings.nonbonded_method, - alchemical_settings.explicit_charge_correction, - solvent_comp_a, # Solvent comp in a is expected to be the same as in b - ) - except ValueError as e: - raise ProtocolSupportError(str(e)) + # Get the formal change difference between the end states + charge_difference = mapping.get_alchemical_charge_difference() if alchemical_settings.explicit_charge_correction: alchem_water_resids = _rfe_utils.topologyhelpers.get_alchemical_waters( diff --git a/feflow/utils/charge.py b/feflow/utils/charge.py index 143a55a9..b21c156e 100644 --- a/feflow/utils/charge.py +++ b/feflow/utils/charge.py @@ -7,10 +7,6 @@ from openfe.protocols.openmm_utils.charge_generation import ( assign_offmol_partial_charges, ) -from openfe.protocols.openmm_rfe.equil_rfe_methods import ( - _get_alchemical_charge_difference, -) # TODO: Importing from OpenFE for now, should we migrate them here? assign_offmol_partial_charges = assign_offmol_partial_charges -get_alchemical_charge_difference = _get_alchemical_charge_difference From 28a666226bce3d47fc511a24a5948ac987058e80 Mon Sep 17 00:00:00 2001 From: ijpulidos <2949729+ijpulidos@users.noreply.github.com> Date: Thu, 9 Apr 2026 22:44:04 -0400 Subject: [PATCH 02/18] Using 1.9 gufe/openfe releases --- devtools/conda-envs/test_env.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/devtools/conda-envs/test_env.yaml b/devtools/conda-envs/test_env.yaml index a9c0a2ef..921a9ad0 100644 --- a/devtools/conda-envs/test_env.yaml +++ b/devtools/conda-envs/test_env.yaml @@ -4,9 +4,9 @@ channels: - openeye dependencies: # Base depends - - gufe ~=1.7.1 + - gufe ~=1.9.0 - numpy - - openfe ~=1.8.0 # TODO: Remove once we don't depend on openfe + - openfe ~=1.9.0 # TODO: Remove once we don't depend on openfe - openff-units - openmm - openmmforcefields >=0.14.1 # TODO: remove when upstream deps fix this From e07522d3f1b39c3fd060b3a517b5aaa33b440cb1 Mon Sep 17 00:00:00 2001 From: ijpulidos <2949729+ijpulidos@users.noreply.github.com> Date: Thu, 9 Apr 2026 22:51:15 -0400 Subject: [PATCH 03/18] gufe 1.9 support requires openfe 1.10 --- devtools/conda-envs/test_env.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/devtools/conda-envs/test_env.yaml b/devtools/conda-envs/test_env.yaml index 1293e885..1c729955 100644 --- a/devtools/conda-envs/test_env.yaml +++ b/devtools/conda-envs/test_env.yaml @@ -6,7 +6,7 @@ dependencies: # Base depends - gufe ~=1.9.0 - numpy - - openfe ~=1.9.0 # TODO: Remove once we don't depend on openfe + - openfe ~=1.10.0 # TODO: Remove once we don't depend on openfe - openff-units - openmm - openmmforcefields >=0.14.1 # TODO: remove when upstream deps fix this From 054ab37b7bfdf75c10b91edae2c3d03c17e67508 Mon Sep 17 00:00:00 2001 From: ijpulidos <2949729+ijpulidos@users.noreply.github.com> Date: Thu, 9 Apr 2026 23:00:16 -0400 Subject: [PATCH 04/18] Removing now unexisting import --- feflow/protocols/nonequilibrium_cycling.py | 1 - 1 file changed, 1 deletion(-) diff --git a/feflow/protocols/nonequilibrium_cycling.py b/feflow/protocols/nonequilibrium_cycling.py index 46980e35..5b463690 100644 --- a/feflow/protocols/nonequilibrium_cycling.py +++ b/feflow/protocols/nonequilibrium_cycling.py @@ -113,7 +113,6 @@ def _execute(self, ctx, *, protocol, state_a, state_b, mapping, **inputs): get_alchemical_components, ) from feflow.utils.hybrid_topology import HybridTopologyFactory - from feflow.utils.charge import get_alchemical_charge_difference from feflow.utils.misc import register_ff_parameters_template # Get receptor components from systems if found (None otherwise) From 8da0403f2deefdcc30cda8b5396af9942124f988 Mon Sep 17 00:00:00 2001 From: ijpulidos <2949729+ijpulidos@users.noreply.github.com> Date: Tue, 9 Jun 2026 13:17:12 -0400 Subject: [PATCH 05/18] Use CPU platform for tests --- feflow/tests/test_protein_mutation.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/feflow/tests/test_protein_mutation.py b/feflow/tests/test_protein_mutation.py index 4c151eb0..0ac8aec2 100644 --- a/feflow/tests/test_protein_mutation.py +++ b/feflow/tests/test_protein_mutation.py @@ -636,6 +636,8 @@ def test_double_charge_fails( from feflow.utils.exceptions import ProtocolSupportError settings = NonEquilibriumCyclingProtocol.default_settings() + # Change engine platform for tests + settings.engine_settings.compute_platform = "CPU" # We need to make sure we enable the alchemical charge correction settings.alchemical_settings.explicit_charge_correction = True From fc94b80ecd568dd1c8abd44521b233a5a3bb372d Mon Sep 17 00:00:00 2001 From: ijpulidos <2949729+ijpulidos@users.noreply.github.com> Date: Tue, 9 Jun 2026 13:22:32 -0400 Subject: [PATCH 06/18] gufe support following semver --- devtools/conda-envs/test_env.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/devtools/conda-envs/test_env.yaml b/devtools/conda-envs/test_env.yaml index 1c729955..0586ccc8 100644 --- a/devtools/conda-envs/test_env.yaml +++ b/devtools/conda-envs/test_env.yaml @@ -4,7 +4,7 @@ channels: - openeye dependencies: # Base depends - - gufe ~=1.9.0 + - gufe >=1.9.0,<2 - numpy - openfe ~=1.10.0 # TODO: Remove once we don't depend on openfe - openff-units From 0401ad3ab7e0be55d3fa2df2704a2a17fa58d9b2 Mon Sep 17 00:00:00 2001 From: ijpulidos <2949729+ijpulidos@users.noreply.github.com> Date: Tue, 9 Jun 2026 13:23:21 -0400 Subject: [PATCH 07/18] openfe support following semver --- devtools/conda-envs/test_env.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/devtools/conda-envs/test_env.yaml b/devtools/conda-envs/test_env.yaml index 0586ccc8..4c8a3a95 100644 --- a/devtools/conda-envs/test_env.yaml +++ b/devtools/conda-envs/test_env.yaml @@ -6,7 +6,7 @@ dependencies: # Base depends - gufe >=1.9.0,<2 - numpy - - openfe ~=1.10.0 # TODO: Remove once we don't depend on openfe + - openfe >=1.10.0,<2 # TODO: Remove once we don't depend on openfe - openff-units - openmm - openmmforcefields >=0.14.1 # TODO: remove when upstream deps fix this From 75d8ddab7894799214deb5a9f30a50318848a85c Mon Sep 17 00:00:00 2001 From: ijpulidos <2949729+ijpulidos@users.noreply.github.com> Date: Tue, 9 Jun 2026 13:41:55 -0400 Subject: [PATCH 08/18] openfe >=1.11 does not support neq integrators --- devtools/conda-envs/test_env.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/devtools/conda-envs/test_env.yaml b/devtools/conda-envs/test_env.yaml index 4c8a3a95..0586ccc8 100644 --- a/devtools/conda-envs/test_env.yaml +++ b/devtools/conda-envs/test_env.yaml @@ -6,7 +6,7 @@ dependencies: # Base depends - gufe >=1.9.0,<2 - numpy - - openfe >=1.10.0,<2 # TODO: Remove once we don't depend on openfe + - openfe ~=1.10.0 # TODO: Remove once we don't depend on openfe - openff-units - openmm - openmmforcefields >=0.14.1 # TODO: remove when upstream deps fix this From f29c7f821777132caf13ef9121c5b6e7b9b39cca Mon Sep 17 00:00:00 2001 From: ijpulidos <2949729+ijpulidos@users.noreply.github.com> Date: Tue, 9 Jun 2026 13:46:45 -0400 Subject: [PATCH 09/18] removing unused barostat setting --- feflow/settings/integrators.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/feflow/settings/integrators.py b/feflow/settings/integrators.py index 48d7a9f4..695457e7 100644 --- a/feflow/settings/integrators.py +++ b/feflow/settings/integrators.py @@ -35,12 +35,6 @@ class PeriodicNonequilibriumIntegratorSettings(SettingsBaseModel): """Number of steps for the equilibrium parts of the cycle. Default 12500""" nonequilibrium_steps: int = 12500 """Number of steps for the non-equilibrium parts of the cycle. Default 12500""" - barostat_frequency: TimestepQuantity = 25 * unit.timestep - """ - Frequency at which volume scaling changes should be attempted. - Note: The barostat frequency is ignored for gas-phase simulations. - Default 25 * unit.timestep. - """ remove_com: bool = False """ Whether or not to remove the center of mass motion. Default False. From cda67bd412b74fc5f69b3e731fd882e61a9cca94 Mon Sep 17 00:00:00 2001 From: ijpulidos <2949729+ijpulidos@users.noreply.github.com> Date: Tue, 9 Jun 2026 14:00:03 -0400 Subject: [PATCH 10/18] Revert "removing unused barostat setting" This reverts commit f29c7f821777132caf13ef9121c5b6e7b9b39cca. --- feflow/settings/integrators.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/feflow/settings/integrators.py b/feflow/settings/integrators.py index 695457e7..48d7a9f4 100644 --- a/feflow/settings/integrators.py +++ b/feflow/settings/integrators.py @@ -35,6 +35,12 @@ class PeriodicNonequilibriumIntegratorSettings(SettingsBaseModel): """Number of steps for the equilibrium parts of the cycle. Default 12500""" nonequilibrium_steps: int = 12500 """Number of steps for the non-equilibrium parts of the cycle. Default 12500""" + barostat_frequency: TimestepQuantity = 25 * unit.timestep + """ + Frequency at which volume scaling changes should be attempted. + Note: The barostat frequency is ignored for gas-phase simulations. + Default 25 * unit.timestep. + """ remove_com: bool = False """ Whether or not to remove the center of mass motion. Default False. From 36963323fbc62f9537a93aa545d0c753011a32c5 Mon Sep 17 00:00:00 2001 From: ijpulidos <2949729+ijpulidos@users.noreply.github.com> Date: Tue, 9 Jun 2026 14:44:34 -0400 Subject: [PATCH 11/18] Adding barostat attribute to support openfe 1.11+ --- devtools/conda-envs/test_env.yaml | 2 +- feflow/settings/integrators.py | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/devtools/conda-envs/test_env.yaml b/devtools/conda-envs/test_env.yaml index 0586ccc8..4c8a3a95 100644 --- a/devtools/conda-envs/test_env.yaml +++ b/devtools/conda-envs/test_env.yaml @@ -6,7 +6,7 @@ dependencies: # Base depends - gufe >=1.9.0,<2 - numpy - - openfe ~=1.10.0 # TODO: Remove once we don't depend on openfe + - openfe >=1.10.0,<2 # TODO: Remove once we don't depend on openfe - openff-units - openmm - openmmforcefields >=0.14.1 # TODO: remove when upstream deps fix this diff --git a/feflow/settings/integrators.py b/feflow/settings/integrators.py index 48d7a9f4..dbf79e68 100644 --- a/feflow/settings/integrators.py +++ b/feflow/settings/integrators.py @@ -6,7 +6,7 @@ for the specific integrator settings. """ -from typing import Annotated, TypeAlias +from typing import Annotated, TypeAlias, Literal from pydantic import ConfigDict, field_validator @@ -35,6 +35,13 @@ class PeriodicNonequilibriumIntegratorSettings(SettingsBaseModel): """Number of steps for the equilibrium parts of the cycle. Default 12500""" nonequilibrium_steps: int = 12500 """Number of steps for the non-equilibrium parts of the cycle. Default 12500""" + barostat: Literal["MonteCarloBarostat", "MonteCarloMembraneBarostat"] = "MonteCarloBarostat" + """ + The barostat to be used in the simulations. Default MonteCarloBarostat. + Notes + ----- + If the system contains a membrane, use the `MonteCarloMembraneBarostat`. + """ barostat_frequency: TimestepQuantity = 25 * unit.timestep """ Frequency at which volume scaling changes should be attempted. From 2d43609563f04b4699b4058a0dbd56dceee905bb Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 9 Jun 2026 18:46:22 +0000 Subject: [PATCH 12/18] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- feflow/settings/integrators.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/feflow/settings/integrators.py b/feflow/settings/integrators.py index dbf79e68..00590c53 100644 --- a/feflow/settings/integrators.py +++ b/feflow/settings/integrators.py @@ -35,7 +35,9 @@ class PeriodicNonequilibriumIntegratorSettings(SettingsBaseModel): """Number of steps for the equilibrium parts of the cycle. Default 12500""" nonequilibrium_steps: int = 12500 """Number of steps for the non-equilibrium parts of the cycle. Default 12500""" - barostat: Literal["MonteCarloBarostat", "MonteCarloMembraneBarostat"] = "MonteCarloBarostat" + barostat: Literal["MonteCarloBarostat", "MonteCarloMembraneBarostat"] = ( + "MonteCarloBarostat" + ) """ The barostat to be used in the simulations. Default MonteCarloBarostat. Notes From 1ebb346b3ee293b4cd08d482514d56c0ee85d636 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Pulido?= <2949729+ijpulidos@users.noreply.github.com> Date: Wed, 10 Jun 2026 11:05:10 -0400 Subject: [PATCH 13/18] testing CI with openfe 1.10.x --- devtools/conda-envs/test_env.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/devtools/conda-envs/test_env.yaml b/devtools/conda-envs/test_env.yaml index 4c8a3a95..0586ccc8 100644 --- a/devtools/conda-envs/test_env.yaml +++ b/devtools/conda-envs/test_env.yaml @@ -6,7 +6,7 @@ dependencies: # Base depends - gufe >=1.9.0,<2 - numpy - - openfe >=1.10.0,<2 # TODO: Remove once we don't depend on openfe + - openfe ~=1.10.0 # TODO: Remove once we don't depend on openfe - openff-units - openmm - openmmforcefields >=0.14.1 # TODO: remove when upstream deps fix this From 49c3283eb1cd60d968846ecbfbb38a67a5b2c0c0 Mon Sep 17 00:00:00 2001 From: ijpulidos <2949729+ijpulidos@users.noreply.github.com> Date: Thu, 11 Jun 2026 18:09:58 -0400 Subject: [PATCH 14/18] Validating charge changing transformations --- feflow/protocols/nonequilibrium_cycling.py | 12 ++- feflow/utils/charge.py | 97 +++++++++++++++++++++- 2 files changed, 107 insertions(+), 2 deletions(-) diff --git a/feflow/protocols/nonequilibrium_cycling.py b/feflow/protocols/nonequilibrium_cycling.py index 5b463690..9e0c5628 100644 --- a/feflow/protocols/nonequilibrium_cycling.py +++ b/feflow/protocols/nonequilibrium_cycling.py @@ -30,6 +30,7 @@ from openff.units.openmm import to_openmm, from_openmm from ..settings import NonEquilibriumCyclingSettings +from ..utils.charge import validate_charge_difference from ..utils.data import serialize, deserialize from ..utils.exceptions import ProtocolSupportError from ..utils.misc import ( @@ -239,7 +240,16 @@ def _execute(self, ctx, *, protocol, state_a, state_b, mapping, **inputs): # Handle charge corrections/transformations # Get the formal change difference between the end states - charge_difference = mapping.get_alchemical_charge_difference() + try: + charge_difference = validate_charge_difference( + mapping, + forcefield_settings.nonbonded_method, + alchemical_settings.explicit_charge_correction, + solvent_comp_a, # Solvent comp in a is expected to be the same as in b + ) + except ValueError as e: + raise ProtocolSupportError(str(e)) + if alchemical_settings.explicit_charge_correction: alchem_water_resids = _rfe_utils.topologyhelpers.get_alchemical_waters( diff --git a/feflow/utils/charge.py b/feflow/utils/charge.py index b21c156e..391f10e4 100644 --- a/feflow/utils/charge.py +++ b/feflow/utils/charge.py @@ -3,10 +3,105 @@ Such as assigning both formal and partial charges, or transforming solvent into ions or vice versa for charge-changing alchemical transformations. """ - +import logging +import warnings +from gufe import LigandAtomMapping, SolventComponent from openfe.protocols.openmm_utils.charge_generation import ( assign_offmol_partial_charges, ) # TODO: Importing from OpenFE for now, should we migrate them here? assign_offmol_partial_charges = assign_offmol_partial_charges + +logger = logging.getLogger(__name__) + + +# TODO: Re-evaluate if we want a more global utility function for this in the openfe "ecosystem" +# Vendored from openfe protocol method in https://github.com/OpenFreeEnergy/openfe/blob/75cb2e85a46514633ecfe33353dfa5e9dc22e729/src/openfe/protocols/openmm_rfe/hybridtop_protocols.py#L373 +def validate_charge_difference( + mapping: LigandAtomMapping, + nonbonded_method: str, + explicit_charge_correction: bool, + solvent_component: SolventComponent | None, +) -> int: + """ + Validates the net charge difference between the two states. + + Useful for uses in Hybrid Topology protocols where alchemical changes + of 2 or more charge units are not supported, and/or not using PME + when there is charge correction is not supported. + + Parameters + ---------- + mapping : LigandAtomMapping + Mapping object between transforming components. + nonbonded_method : str + The OpenMM nonbonded method used for the simulation. + explicit_charge_correction : bool + Whether to use an explicit charge correction. + solvent_component : openfe.SolventComponent | None + The SolventComponent of the simulation. + + Returns + ------- + int + The alchemical charge difference between the two states. + + Raises + ------ + ValueError + * If an explicit charge correction is attempted and the + nonbonded method is not PME. + * If the absolute charge difference is greater than one + and an explicit charge correction is attempted. + * If an explicit charge correction is attempted and there is no + solvent present. + UserWarning + * If there is any charge difference and no explicit charge + correction has been requested. + """ + difference = mapping.get_alchemical_charge_difference() + + if abs(difference) == 0: + return difference + + if not explicit_charge_correction: + wmsg = ( + f"A charge difference of {difference} is observed " + "between the end states. No charge correction has " + "been requested, please account for this in your " + "final results." + ) + logger.warning(wmsg) + warnings.warn(wmsg) + return difference + + if solvent_component is None: + errmsg = "Cannot use explicit charge correction without solvent" + raise ValueError(errmsg) + + # We implicitly check earlier that we have to have pme for a solvated + # system, so we only need to check the nonbonded method here + if nonbonded_method.lower() != "pme": + errmsg = "Explicit charge correction when not using PME is not currently supported." + raise ValueError(errmsg) + + if abs(difference) > 1: + errmsg = ( + f"A charge difference of {difference} is observed " + "between the end states and an explicit charge " + "correction has been requested. Unfortunately " + "only absolute differences of 1 are supported." + ) + raise ValueError(errmsg) + + ion = {-1: solvent_component.positive_ion, 1: solvent_component.negative_ion}[difference] + + wmsg = ( + f"A charge difference of {difference} is observed " + "between the end states. This will be addressed by " + f"transforming a water into a {ion} ion" + ) + logger.info(wmsg) + + return difference From f48ba0c888eeb4574b7e1e4d970eb96200780f0b Mon Sep 17 00:00:00 2001 From: ijpulidos <2949729+ijpulidos@users.noreply.github.com> Date: Thu, 11 Jun 2026 18:16:18 -0400 Subject: [PATCH 15/18] Test executing unit only. Avoiding whole DAG execution. --- feflow/tests/test_protein_mutation.py | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/feflow/tests/test_protein_mutation.py b/feflow/tests/test_protein_mutation.py index 0ac8aec2..e16d9fee 100644 --- a/feflow/tests/test_protein_mutation.py +++ b/feflow/tests/test_protein_mutation.py @@ -617,12 +617,12 @@ def test_double_charge_fails( ): """ Test that attempting a mutation with a double charge change between lysine and glutamate - systems raises a `NotSupportedError`. + systems raises a `ProtocolSupportError`. This test verifies that the `NonEquilibriumCyclingProtocol` correctly raises an error when trying to - create a directed acyclic graph (DAG) for an invalid mutation involving a double charge change. - The test expects the `NotSupportedError` to be raised with a message indicating that - double-charge transformations are not supported. + execute the setup of an invalid mutation involving a double charge change. The charge + validation happens in the `SetupUnit`, so we only execute that unit directly instead of + running the full DAG (which would also run the, much more expensive, simulation units). Parameters ---------- @@ -633,6 +633,7 @@ def test_double_charge_fails( lys_to_glu_mapping : LigandAtomMapping Atom mapping defining the correspondence between atoms in the lysine and glutamate systems. """ + from gufe.protocols.protocolunit import Context from feflow.utils.exceptions import ProtocolSupportError settings = NonEquilibriumCyclingProtocol.default_settings() @@ -646,11 +647,14 @@ def test_double_charge_fails( dag = protocol.create( stateA=lys_capped_system, stateB=glu_capped_system, - name="Invalid proline mutation", + name="Invalid double charge mutation", mapping=lys_to_glu_mapping, ) - # Expect an error when trying to create the DAG with this invalid transformation + # Charge validation happens in the setup unit -- run only that unit + setup_unit = dag.protocol_units[0] + + # Expect an error when trying to execute the setup for this invalid transformation with pytest.raises(ProtocolSupportError): with tmpdir.as_cwd(): shared = Path("shared") @@ -659,4 +663,7 @@ def test_double_charge_fails( scratch = Path("scratch") scratch.mkdir() - execute_DAG(dag, shared_basedir=shared, scratch_basedir=scratch) + context = Context(shared=shared, scratch=scratch) + setup_unit.execute( + context=context, raise_error=True, **setup_unit.inputs + ) From 403ace19ad08b0d16b4538a33b46156160911dca Mon Sep 17 00:00:00 2001 From: ijpulidos <2949729+ijpulidos@users.noreply.github.com> Date: Thu, 11 Jun 2026 18:20:31 -0400 Subject: [PATCH 16/18] Revert "testing CI with openfe 1.10.x" This reverts commit 1ebb346b3ee293b4cd08d482514d56c0ee85d636. --- devtools/conda-envs/test_env.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/devtools/conda-envs/test_env.yaml b/devtools/conda-envs/test_env.yaml index 0586ccc8..4c8a3a95 100644 --- a/devtools/conda-envs/test_env.yaml +++ b/devtools/conda-envs/test_env.yaml @@ -6,7 +6,7 @@ dependencies: # Base depends - gufe >=1.9.0,<2 - numpy - - openfe ~=1.10.0 # TODO: Remove once we don't depend on openfe + - openfe >=1.10.0,<2 # TODO: Remove once we don't depend on openfe - openff-units - openmm - openmmforcefields >=0.14.1 # TODO: remove when upstream deps fix this From 2d838fbf756d901de42524818bade15ce289ff49 Mon Sep 17 00:00:00 2001 From: ijpulidos <2949729+ijpulidos@users.noreply.github.com> Date: Thu, 11 Jun 2026 18:21:43 -0400 Subject: [PATCH 17/18] We only support MonteCarloBarostat for now --- feflow/settings/integrators.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/feflow/settings/integrators.py b/feflow/settings/integrators.py index 00590c53..81844ecc 100644 --- a/feflow/settings/integrators.py +++ b/feflow/settings/integrators.py @@ -35,7 +35,7 @@ class PeriodicNonequilibriumIntegratorSettings(SettingsBaseModel): """Number of steps for the equilibrium parts of the cycle. Default 12500""" nonequilibrium_steps: int = 12500 """Number of steps for the non-equilibrium parts of the cycle. Default 12500""" - barostat: Literal["MonteCarloBarostat", "MonteCarloMembraneBarostat"] = ( + barostat: Literal["MonteCarloBarostat"] = ( "MonteCarloBarostat" ) """ From 2d2d7f9b592e81eeeb4625e6b099a37ee066f746 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 11 Jun 2026 22:24:12 +0000 Subject: [PATCH 18/18] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- feflow/protocols/nonequilibrium_cycling.py | 1 - feflow/settings/integrators.py | 4 +--- feflow/utils/charge.py | 17 +++++++++++------ 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/feflow/protocols/nonequilibrium_cycling.py b/feflow/protocols/nonequilibrium_cycling.py index 9e0c5628..edf1358a 100644 --- a/feflow/protocols/nonequilibrium_cycling.py +++ b/feflow/protocols/nonequilibrium_cycling.py @@ -250,7 +250,6 @@ def _execute(self, ctx, *, protocol, state_a, state_b, mapping, **inputs): except ValueError as e: raise ProtocolSupportError(str(e)) - if alchemical_settings.explicit_charge_correction: alchem_water_resids = _rfe_utils.topologyhelpers.get_alchemical_waters( state_a_topology, diff --git a/feflow/settings/integrators.py b/feflow/settings/integrators.py index 81844ecc..26a0dc45 100644 --- a/feflow/settings/integrators.py +++ b/feflow/settings/integrators.py @@ -35,9 +35,7 @@ class PeriodicNonequilibriumIntegratorSettings(SettingsBaseModel): """Number of steps for the equilibrium parts of the cycle. Default 12500""" nonequilibrium_steps: int = 12500 """Number of steps for the non-equilibrium parts of the cycle. Default 12500""" - barostat: Literal["MonteCarloBarostat"] = ( - "MonteCarloBarostat" - ) + barostat: Literal["MonteCarloBarostat"] = "MonteCarloBarostat" """ The barostat to be used in the simulations. Default MonteCarloBarostat. Notes diff --git a/feflow/utils/charge.py b/feflow/utils/charge.py index 391f10e4..ef102e8d 100644 --- a/feflow/utils/charge.py +++ b/feflow/utils/charge.py @@ -3,6 +3,7 @@ Such as assigning both formal and partial charges, or transforming solvent into ions or vice versa for charge-changing alchemical transformations. """ + import logging import warnings from gufe import LigandAtomMapping, SolventComponent @@ -19,10 +20,10 @@ # TODO: Re-evaluate if we want a more global utility function for this in the openfe "ecosystem" # Vendored from openfe protocol method in https://github.com/OpenFreeEnergy/openfe/blob/75cb2e85a46514633ecfe33353dfa5e9dc22e729/src/openfe/protocols/openmm_rfe/hybridtop_protocols.py#L373 def validate_charge_difference( - mapping: LigandAtomMapping, - nonbonded_method: str, - explicit_charge_correction: bool, - solvent_component: SolventComponent | None, + mapping: LigandAtomMapping, + nonbonded_method: str, + explicit_charge_correction: bool, + solvent_component: SolventComponent | None, ) -> int: """ Validates the net charge difference between the two states. @@ -83,7 +84,9 @@ def validate_charge_difference( # We implicitly check earlier that we have to have pme for a solvated # system, so we only need to check the nonbonded method here if nonbonded_method.lower() != "pme": - errmsg = "Explicit charge correction when not using PME is not currently supported." + errmsg = ( + "Explicit charge correction when not using PME is not currently supported." + ) raise ValueError(errmsg) if abs(difference) > 1: @@ -95,7 +98,9 @@ def validate_charge_difference( ) raise ValueError(errmsg) - ion = {-1: solvent_component.positive_ion, 1: solvent_component.negative_ion}[difference] + ion = {-1: solvent_component.positive_ion, 1: solvent_component.negative_ion}[ + difference + ] wmsg = ( f"A charge difference of {difference} is observed "