From 1dd5d7eab6388a3a29c5f16292741b1875b085ce Mon Sep 17 00:00:00 2001 From: Richard Gowers Date: Wed, 27 Mar 2024 02:49:35 +0000 Subject: [PATCH] update LomapAtomMapper default settings to established best practices (#730) * update LomapAtomMapper default settings to established best practices * fixup tests for relative_alchemical_network_planner following lomap default change make these tests use the legacy default settings for Lomap, they're just smoke testing and the actual mappings don't matter * fixup regression tests for command line plan-rbfe these are different now that the lomap defaults have been changed for 1.0 --------- Co-authored-by: Mike Henry <11765982+mikemhenry@users.noreply.github.com> --- .../relative_alchemical_network_planner.py | 8 +++-- ...est_relative_alchemical_network_planner.py | 30 ++++++++++++++++--- openfecli/parameters/plan_network_options.py | 9 ++++-- openfecli/tests/test_rbfe_tutorial.py | 30 +++++++++---------- 4 files changed, 54 insertions(+), 23 deletions(-) diff --git a/openfe/setup/alchemical_network_planner/relative_alchemical_network_planner.py b/openfe/setup/alchemical_network_planner/relative_alchemical_network_planner.py index 3dc060e91..fa5465c88 100644 --- a/openfe/setup/alchemical_network_planner/relative_alchemical_network_planner.py +++ b/openfe/setup/alchemical_network_planner/relative_alchemical_network_planner.py @@ -74,8 +74,12 @@ def __init__( if protocol is None: protocol = RelativeHybridTopologyProtocol(RelativeHybridTopologyProtocol.default_settings()) if mappers is None: - mappers = [LomapAtomMapper(time=20, threed=True, - element_change=False, max3d=1)] + mappers = [LomapAtomMapper(time=20, + threed=True, + max3d=1.0, + element_change=True, + shift=False, + )] self.name = name self._mappers = mappers diff --git a/openfe/tests/setup/alchemical_network_planner/test_relative_alchemical_network_planner.py b/openfe/tests/setup/alchemical_network_planner/test_relative_alchemical_network_planner.py index 187ea87eb..6f4166d41 100644 --- a/openfe/tests/setup/alchemical_network_planner/test_relative_alchemical_network_planner.py +++ b/openfe/tests/setup/alchemical_network_planner/test_relative_alchemical_network_planner.py @@ -7,6 +7,7 @@ from gufe import SolventComponent, AlchemicalNetwork from openfe.setup.alchemical_network_planner import RHFEAlchemicalNetworkPlanner, RBFEAlchemicalNetworkPlanner from .edge_types import r_complex_edge, r_solvent_edge, r_vacuum_edge +import openfe def test_rhfe_alchemical_network_planner_init(): @@ -22,7 +23,15 @@ def test_rbfe_alchemical_network_planner_init(): def test_rbfe_alchemical_network_planner_call(atom_mapping_basic_test_files, T4_protein_component): - alchem_planner = RBFEAlchemicalNetworkPlanner() + alchem_planner = RBFEAlchemicalNetworkPlanner( + # these aren't default settings, but the test ligands aren't aligned + mappers=[openfe.LomapAtomMapper( + time=20, + element_change=False, + max3d=1, + shift=True, + )] + ) alchem_network = alchem_planner( ligands=atom_mapping_basic_test_files.values(), solvent=SolventComponent(), @@ -34,14 +43,20 @@ def test_rbfe_alchemical_network_planner_call(atom_mapping_basic_test_files, T4_ edges = alchem_network.edges assert len(edges) == 14 # we build 2envs*8ligands-2startLigands = 14 relative edges. - print(edges) assert sum([r_complex_edge(e) for e in edges]) == 7 # half of the transformations should be complex (they always are)! assert sum([r_solvent_edge(e) for e in edges]) == 7 # half of the transformations should be solvent! assert sum([r_vacuum_edge(e) for e in edges]) == 0 # no vacuum here! def test_rhfe_alchemical_network_planner_call_multigraph(atom_mapping_basic_test_files): - alchem_planner = RHFEAlchemicalNetworkPlanner() + alchem_planner = RHFEAlchemicalNetworkPlanner( + mappers=[openfe.LomapAtomMapper( + time=20, + element_change=False, + max3d=1, + shift=True, + )] + ) ligand_network = alchem_planner._construct_ligand_network(atom_mapping_basic_test_files.values()) ligand_network_edges = list(ligand_network.edges) @@ -59,7 +74,14 @@ def test_rhfe_alchemical_network_planner_call_multigraph(atom_mapping_basic_test def test_rhfe_alchemical_network_planner_call(atom_mapping_basic_test_files): - alchem_planner = RHFEAlchemicalNetworkPlanner() + alchem_planner = RHFEAlchemicalNetworkPlanner( + mappers=[openfe.LomapAtomMapper( + time=20, + element_change=False, + max3d=1, + shift=True, + )] + ) alchem_network = alchem_planner(ligands=atom_mapping_basic_test_files.values(), solvent=SolventComponent()) assert isinstance(alchem_network, AlchemicalNetwork) diff --git a/openfecli/parameters/plan_network_options.py b/openfecli/parameters/plan_network_options.py index 3bd4c1d4b..e486973f5 100644 --- a/openfecli/parameters/plan_network_options.py +++ b/openfecli/parameters/plan_network_options.py @@ -138,8 +138,13 @@ def load_yaml_planner_options(path: Optional[str], context) -> PlanNetworkOption raise KeyError(f"Bad mapper choice: '{opt.mapper.method}'") mapper_obj = cls(**opt.mapper.settings) else: - mapper_obj = LomapAtomMapper(time=20, threed=True, element_change=False, - max3d=1) + mapper_obj = LomapAtomMapper( + time=20, + threed=True, + max3d=1.0, + element_change=True, + shift=False + ) # todo: choice of scorer goes here mapping_scorer = default_lomap_score diff --git a/openfecli/tests/test_rbfe_tutorial.py b/openfecli/tests/test_rbfe_tutorial.py index 89c55829c..7be44e5d2 100644 --- a/openfecli/tests/test_rbfe_tutorial.py +++ b/openfecli/tests/test_rbfe_tutorial.py @@ -31,24 +31,24 @@ def tyk2_protein(): @pytest.fixture def expected_transformations(): - return ['easy_rbfe_lig_ejm_31_complex_lig_ejm_42_complex.json', - 'easy_rbfe_lig_ejm_31_solvent_lig_ejm_50_solvent.json', - 'easy_rbfe_lig_ejm_31_complex_lig_ejm_46_complex.json', - 'easy_rbfe_lig_ejm_42_complex_lig_ejm_43_complex.json', + return ['easy_rbfe_lig_ejm_31_complex_lig_ejm_46_complex.json', 'easy_rbfe_lig_ejm_31_complex_lig_ejm_47_complex.json', - 'easy_rbfe_lig_ejm_42_solvent_lig_ejm_43_solvent.json', 'easy_rbfe_lig_ejm_31_complex_lig_ejm_48_complex.json', - 'easy_rbfe_lig_ejm_46_complex_lig_jmc_23_complex.json', 'easy_rbfe_lig_ejm_31_complex_lig_ejm_50_complex.json', - 'easy_rbfe_lig_ejm_46_complex_lig_jmc_27_complex.json', - 'easy_rbfe_lig_ejm_31_solvent_lig_ejm_42_solvent.json', - 'easy_rbfe_lig_ejm_46_complex_lig_jmc_28_complex.json', 'easy_rbfe_lig_ejm_31_solvent_lig_ejm_46_solvent.json', - 'easy_rbfe_lig_ejm_46_solvent_lig_jmc_23_solvent.json', 'easy_rbfe_lig_ejm_31_solvent_lig_ejm_47_solvent.json', - 'easy_rbfe_lig_ejm_46_solvent_lig_jmc_27_solvent.json', 'easy_rbfe_lig_ejm_31_solvent_lig_ejm_48_solvent.json', - 'easy_rbfe_lig_ejm_46_solvent_lig_jmc_28_solvent.json'] + 'easy_rbfe_lig_ejm_31_solvent_lig_ejm_50_solvent.json', + 'easy_rbfe_lig_ejm_42_complex_lig_ejm_43_complex.json', + 'easy_rbfe_lig_ejm_42_complex_lig_ejm_50_complex.json', + 'easy_rbfe_lig_ejm_42_solvent_lig_ejm_43_solvent.json', + 'easy_rbfe_lig_ejm_42_solvent_lig_ejm_50_solvent.json', + 'easy_rbfe_lig_ejm_46_complex_lig_jmc_27_complex.json', + 'easy_rbfe_lig_ejm_46_solvent_lig_jmc_27_solvent.json', + 'easy_rbfe_lig_jmc_23_complex_lig_jmc_27_complex.json', + 'easy_rbfe_lig_jmc_23_solvent_lig_jmc_27_solvent.json', + 'easy_rbfe_lig_jmc_27_complex_lig_jmc_28_complex.json', + 'easy_rbfe_lig_jmc_27_solvent_lig_jmc_28_solvent.json'] def test_plan_tyk2(tyk2_ligands, tyk2_protein, expected_transformations): @@ -88,15 +88,15 @@ def fake_execute(*args, **kwargs): def ref_gather(): return """\ ligand_i\tligand_j\tDDG(i->j) (kcal/mol)\tuncertainty (kcal/mol) -lig_ejm_31\tlig_ejm_42\t0.0\t0.0 lig_ejm_31\tlig_ejm_46\t0.0\t0.0 lig_ejm_31\tlig_ejm_47\t0.0\t0.0 lig_ejm_31\tlig_ejm_48\t0.0\t0.0 lig_ejm_31\tlig_ejm_50\t0.0\t0.0 lig_ejm_42\tlig_ejm_43\t0.0\t0.0 -lig_ejm_46\tlig_jmc_23\t0.0\t0.0 +lig_ejm_42\tlig_ejm_50\t0.0\t0.0 lig_ejm_46\tlig_jmc_27\t0.0\t0.0 -lig_ejm_46\tlig_jmc_28\t0.0\t0.0 +lig_jmc_23\tlig_jmc_27\t0.0\t0.0 +lig_jmc_27\tlig_jmc_28\t0.0\t0.0 """