From 8ab0f8668d7fb3c0d4eddca620270d53932604fd Mon Sep 17 00:00:00 2001 From: Alyssa Travitz <31974495+atravitz@users.noreply.github.com> Date: Mon, 1 Dec 2025 10:01:33 -0800 Subject: [PATCH] pull names directly from ligandmapping (#1702) * pull names directly from ligandmapping * update news entry --- news/gather_by_gufe.rst | 2 +- openfecli/commands/gather.py | 20 ++- openfecli/tests/commands/conftest.py | 200 +++++++++++++++++++++++++++ 3 files changed, 210 insertions(+), 12 deletions(-) diff --git a/news/gather_by_gufe.rst b/news/gather_by_gufe.rst index c34d7200..32cc0b3a 100644 --- a/news/gather_by_gufe.rst +++ b/news/gather_by_gufe.rst @@ -4,7 +4,7 @@ **Changed:** -* ``openfe gather`` is now more rigorous in extracting ligand names and run types. These are now determined directly from component attributes, rather than relying on naming conventions. See `PR #1691 `_ for more details. +* ``openfe gather`` is now more rigorous in extracting ligand names and run types. These are now determined directly from component attributes, rather than relying on naming conventions. See `PR #1691 `_ for more details. **Deprecated:** diff --git a/openfecli/commands/gather.py b/openfecli/commands/gather.py index c8cb251f..4c37a6e5 100644 --- a/openfecli/commands/gather.py +++ b/openfecli/commands/gather.py @@ -221,25 +221,23 @@ def _get_names(result: dict) -> tuple[str, str]: # TODO: I don't like this [0][0] indexing, but I can't think of a better way currently protocol_data = list(result["protocol_result"]["data"].values())[0][0] - ligand_A = gufe.SmallMoleculeComponent.from_dict( - protocol_data["inputs"]["stateA"]["components"]["ligand"] - ) - ligand_B = gufe.SmallMoleculeComponent.from_dict( - protocol_data["inputs"]["stateB"]["components"]["ligand"] - ) - return ligand_A.name, ligand_B.name + name_A = protocol_data["inputs"]["ligandmapping"]["componentA"]["molprops"]["ofe-name"] + name_B = protocol_data["inputs"]["ligandmapping"]["componentB"]["molprops"]["ofe-name"] + + return name_A, name_B def _get_type(result: dict) -> Literal["vacuum", "solvent", "complex"]: """Determine the simulation type based on the component types.""" protocol_data = list(result["protocol_result"]["data"].values())[0][0] - chem_sys_A = gufe.ChemicalSystem.from_dict(protocol_data["inputs"]["stateA"]) - - if not chem_sys_A.contains(gufe.SolventComponent): + component_types = [ + x["__module__"] for x in protocol_data["inputs"]["stateA"]["components"].values() + ] + if "gufe.components.solventcomponent" not in component_types: return "vacuum" - elif chem_sys_A.contains(gufe.ProteinComponent): + elif "gufe.components.proteincomponent" in component_types: return "complex" else: return "solvent" diff --git a/openfecli/tests/commands/conftest.py b/openfecli/tests/commands/conftest.py index 197a03c2..00fa3382 100644 --- a/openfecli/tests/commands/conftest.py +++ b/openfecli/tests/commands/conftest.py @@ -207,6 +207,206 @@ def min_result_json(): "__qualname__": "ChemicalSystem", "__module__": "gufe.chemicalsystem", }, + "ligandmapping": { + "componentA": { + "atoms": [ + [1, 0, 0, False, 0, 0, {}], + [6, 0, 0, True, 0, 0, {}], + [6, 0, 0, True, 0, 0, {}], + [6, 0, 0, True, 0, 0, {}], + [6, 0, 0, True, 0, 0, {}], + [6, 0, 0, True, 0, 0, {}], + [6, 0, 0, True, 0, 0, {}], + [1, 0, 0, False, 0, 0, {}], + [17, 0, 0, False, 0, 0, {}], + [6, 0, 0, False, 0, 0, {}], + [8, 0, 0, False, 0, 0, {}], + [7, 0, 0, False, 0, 0, {}], + [1, 0, 0, False, 0, 0, {}], + [6, 0, 0, True, 0, 0, {}], + [6, 0, 0, True, 0, 0, {}], + [6, 0, 0, True, 0, 0, {}], + [7, 0, 0, True, 0, 0, {}], + [6, 0, 0, True, 0, 0, {}], + [6, 0, 0, True, 0, 0, {}], + [1, 0, 0, False, 0, 0, {}], + [7, 0, 0, False, 0, 0, {}], + [1, 0, 0, False, 0, 0, {}], + [6, 0, 0, False, 0, 0, {}], + [8, 0, 0, False, 0, 0, {}], + [6, 0, 0, False, 0, 0, {}], + [1, 0, 0, False, 0, 0, {}], + [1, 0, 0, False, 0, 0, {}], + [1, 0, 0, False, 0, 0, {}], + [1, 0, 0, False, 0, 0, {}], + [1, 0, 0, False, 0, 0, {}], + [17, 0, 0, False, 0, 0, {}], + [1, 0, 0, False, 0, 0, {}], + ], + "bonds": [ + [0, 1, 1, 0, {}], + [1, 6, 12, 0, {}], + [1, 2, 12, 0, {}], + [2, 3, 12, 0, {}], + [2, 31, 1, 0, {}], + [3, 4, 12, 0, {}], + [3, 30, 1, 0, {}], + [4, 5, 12, 0, {}], + [4, 9, 1, 0, {}], + [5, 6, 12, 0, {}], + [5, 8, 1, 0, {}], + [6, 7, 1, 0, {}], + [9, 10, 2, 0, {}], + [9, 11, 1, 0, {}], + [11, 12, 1, 0, {}], + [11, 13, 1, 0, {}], + [13, 18, 12, 0, {}], + [13, 14, 12, 0, {}], + [14, 15, 12, 0, {}], + [14, 29, 1, 0, {}], + [15, 16, 12, 0, {}], + [15, 28, 1, 0, {}], + [16, 17, 12, 0, {}], + [17, 18, 12, 0, {}], + [17, 20, 1, 0, {}], + [18, 19, 1, 0, {}], + [20, 21, 1, 0, {}], + [20, 22, 1, 0, {}], + [22, 23, 2, 0, {}], + [22, 24, 1, 0, {}], + [24, 25, 1, 0, {}], + [24, 26, 1, 0, {}], + [24, 27, 1, 0, {}], + ], + "conformer": [ + "\u0093NUMPY\u0001\u0000v\u0000{'descr': '\u00e8\u00d9\u00ac\u001a\"\u00c0\u0080\u00b7@\u0082\u00e2\u00e7)\u00c0\b=\u009bU\u009f\u009b4\u00c0r\u00f9\u000f\u00e9\u00b7O\"\u00c0\u00de\u0093\u0087\u0085Z\u00f3+\u00c0o\u0012\u0083\u00c0\u00caA4\u00c0\u008a\u008e\u00e4\u00f2\u001f\u0092 \u00c0\u00aa`TR'\u00e0)\u00c0n4\u0080\u00b7@b5\u00c0\u00e8j+\u00f6\u0097\u00fd#\u00c0\u00b3{\u00f2\u00b0PK)\u00c0:#J{\u0083\u000f5\u00c0\u008c\u00dbh\u0000o!&\u00c0\u00d9=yX\u00a8\u0015&\u00c0\u0012\u0014?\u00c6\u00dc\u00b5,\u00c0\u00a5\u00bd\u00c1\u0017&S#\u00c0io\u00f0\u0085\u00c9\u0014\"\u00c0\u00ab\u00cf\u00d5V\u00ec\u000f,\u00c0\u00e0\u009c\u0011\u00a5\u00bd\u0001\u0013\u00c0\u00ad\u00fa\\m\u00c5~\u001e\u00c0L7\u0089A`\u00a5/\u00c0\u0002\u009a\b\u001b\u009e\u00de\r\u00c0\u00c8\u0098\u00bb\u0096\u0090O\u0014\u00c0N\u00d1\u0091\\\u00fes0\u00c0", + {}, + ], + "molprops": {"ofe-name": "lig_ejm_31"}, + "__qualname__": "SmallMoleculeComponent", + "__module__": "gufe.components.smallmoleculecomponent", + }, + "componentB": { + "atoms": [ + [1, 0, 0, False, 0, 0, {}], + [6, 0, 0, True, 0, 0, {}], + [6, 0, 0, True, 0, 0, {}], + [6, 0, 0, True, 0, 0, {}], + [6, 0, 0, True, 0, 0, {}], + [6, 0, 0, True, 0, 0, {}], + [6, 0, 0, True, 0, 0, {}], + [1, 0, 0, False, 0, 0, {}], + [17, 0, 0, False, 0, 0, {}], + [6, 0, 0, False, 0, 0, {}], + [8, 0, 0, False, 0, 0, {}], + [7, 0, 0, False, 0, 0, {}], + [1, 0, 0, False, 0, 0, {}], + [6, 0, 0, True, 0, 0, {}], + [6, 0, 0, True, 0, 0, {}], + [6, 0, 0, True, 0, 0, {}], + [7, 0, 0, True, 0, 0, {}], + [6, 0, 0, True, 0, 0, {}], + [6, 0, 0, True, 0, 0, {}], + [1, 0, 0, False, 0, 0, {}], + [7, 0, 0, False, 0, 0, {}], + [1, 0, 0, False, 0, 0, {}], + [6, 0, 0, False, 0, 0, {}], + [8, 0, 0, False, 0, 0, {}], + [6, 0, 0, False, 0, 0, {}], + [1, 0, 0, False, 0, 0, {}], + [1, 0, 0, False, 0, 0, {}], + [6, 0, 0, False, 0, 0, {}], + [1, 0, 0, False, 0, 0, {}], + [1, 0, 0, False, 0, 0, {}], + [1, 0, 0, False, 0, 0, {}], + [1, 0, 0, False, 0, 0, {}], + [1, 0, 0, False, 0, 0, {}], + [17, 0, 0, False, 0, 0, {}], + [1, 0, 0, False, 0, 0, {}], + ], + "bonds": [ + [0, 1, 1, 0, {}], + [1, 6, 12, 0, {}], + [1, 2, 12, 0, {}], + [2, 3, 12, 0, {}], + [2, 34, 1, 0, {}], + [3, 4, 12, 0, {}], + [3, 33, 1, 0, {}], + [4, 5, 12, 0, {}], + [4, 9, 1, 0, {}], + [5, 6, 12, 0, {}], + [5, 8, 1, 0, {}], + [6, 7, 1, 0, {}], + [9, 10, 2, 0, {}], + [9, 11, 1, 0, {}], + [11, 12, 1, 0, {}], + [11, 13, 1, 0, {}], + [13, 18, 12, 0, {}], + [13, 14, 12, 0, {}], + [14, 15, 12, 0, {}], + [14, 32, 1, 0, {}], + [15, 16, 12, 0, {}], + [15, 31, 1, 0, {}], + [16, 17, 12, 0, {}], + [17, 18, 12, 0, {}], + [17, 20, 1, 0, {}], + [18, 19, 1, 0, {}], + [20, 21, 1, 0, {}], + [20, 22, 1, 0, {}], + [22, 23, 2, 0, {}], + [22, 24, 1, 0, {}], + [24, 25, 1, 0, {}], + [24, 26, 1, 0, {}], + [24, 27, 1, 0, {}], + [27, 28, 1, 0, {}], + [27, 29, 1, 0, {}], + [27, 30, 1, 0, {}], + ], + "conformer": [ + "\u0093NUMPY\u0001\u0000v\u0000{'descr': '\u00e8\u00d9\u00ac\u00fa\\\f\u00c0\u00aeG\u00e1z\u0014\u00ce/\u00c0\u0001M\u0084\rO\u00af\u001c\u00c0\u00d5x\u00e9&1\u0088\u0004\u00c0M\u00f3\u008eSt\u00e4/\u00c0\u009c3\u00a2\u00b47X\"\u00c0\u0088\u00f4\u00db\u00d7\u0081\u00b3\u0011\u00c0U\u00c1\u00a8\u00a4N`.\u00c0q\u001b\r\u00e0-\u00d0\u001e\u00c0\u00af%\u00e4\u0083\u009e\u008d\u001c\u00c0\u0002+\u0087\u0016\u00d9\u000e.\u00c0-!\u001f\u00f4l6 \u00c0\u009bU\u009f\u00ab\u00ad\u00d8\u001c\u00c0xz\u00a5,C\u00bc+\u00c0T\u00e3\u00a5\u009b\u00c4\u00a0\u001f\u00c0\u0099\u00bb\u0096\u0090\u000f\u001a \u00c09\u00b4\u00c8v\u00be\u00ff/\u00c0:\u0092\u00cb\u007fH\u00bf\u001d\u00c0:#J{\u0083o\u001f\u00c0\u001f\u0085\u00ebQ\u00b8\u00de0\u00c0\u00f8\u00c2d\u00aa`t!\u00c0\t\u001b\u009e^)k\"\u00c0\u00fee\u00f7\u00e4a\u00010\u00c0b\u0010X9\u00b4(#\u00c0\u0006\u0081\u0095C\u008b,#\u00c0h\"lxz\u00e5-\u00c0\u0016\u00fb\u00cb\u00ee\u00c9\u00c3$\u00c0\u00c1\u00ca\u00a1E\u00b6s%\u00c0\u00cd;N\u00d1\u0091<.\u00c0\u0093\u00a9\u0082QI\u00bd$\u00c0xz\u00a5,C\u00fc&\u00c0\u00ec/\u00bb'\u000f;0\u00c0\u00b6\u0084|\u00d0\u00b3\u0019#\u00c0\u0002+\u0087\u0016\u00d9N&\u00c0\u008c\u00dbh\u0000oA1\u00c0\u00fc\u0018s\u00d7\u0012r!\u00c0R'\u00a0\u0089\u00b0\u0001$\u00c0A\u00f1c\u00cc]+1\u00c04\u00116<\u00bd2 \u00c0\u0010\u00e9\u00b7\u00af\u0003g#\u00c0 c\u00eeZB\u00fe1\u00c0\u00b2\u009d\u00ef\u00a7\u00c6+#\u00c0\u00b8\u00af\u0003\u00e7\u008c\u00e8'\u00c0V\u000e-\u00b2\u009do2\u00c00\u00bb'\u000f\u000b\u00d5$\u00c0\u00e8\u00d9\u00ac\u00fa\\\r)\u00c0+\u00f6\u0097\u00dd\u0093\u00872\u00c0\u00ac\u001cZd;_!\u00c0\u00b8\u00af\u0003\u00e7\u008c((\u00c0X\u00ca2\u00c4\u00b1n3\u00c0\u00deq\u008a\u008e\u00e4r\u001e\u00c0\u00a0\u0089\u00b0\u00e1\u00e9\u00f5&\u00c0\"\u00fd\u00f6u\u00e0|3\u00c0yX\u00a85\u00cd\u001b\"\u00c0(\u000f\u000b\u00b5\u00a6\u0019*\u00c0\u00e3\u00a5\u009b\u00c4 \u00904\u00c01\b\u00ac\u001cZ\u00e4\"\u00c0Y\u00868\u00d6\u00c5\u00ed(\u00c0\u00a2E\u00b6\u00f3\u00fdd5\u00c0\u00d5\u00e7j+\u00f6\u00b7#\u00c0\u008cJ\u00ea\u00044q+\u00c0\u00e0\u00be\u000e\u009c3B4\u00c0\u00b3{\u00f2\u00b0Pk\u001f\u00c0\u00bb'\u000f\u000b\u00b5\u00c6+\u00c0\u00b6\u00f3\u00fd\u00d4x\t5\u00c0vq\u001b\r\u00e0M \u00c0\u008c\u00dbh\u0000o!-\u00c0\u00bc\u0096\u0090\u000fz\u00d65\u00c0_\u0098L\u0015\u008c\u00ca\u001d\u00c0\u00d1\u0091\\\u00feC\u00fa,\u00c0a\u00c3\u00d3+e94\u00c0K\u00ea\u00044\u00116\u001c\u00c0\u00a2\u00b47\u00f8\u00c2\u0084*\u00c0[\u00b1\u00bf\u00ec\u009el5\u00c0X9\u00b4\u00c8v\u001e&\u00c0p_\u0007\u00ce\u0019\u0011&\u00c0\u00ce\u0088\u00d2\u00de\u00e0\u00ab,\u00c0\u00d5\u00e7j+\u00f6W#\u00c0^\u00baI\f\u0002\u000b\"\u00c08gDio\u0010,\u00c0\u00c6m4\u0080\u00b7\u0000\u0013\u00c0\\ A\u00f1c\u008c\u001e\u00c0\u009e^)\u00cb\u0010\u00a7/\u00c0\u00e7\u00fb\u00a9\u00f1\u00d2\u00cd\r\u00c0\u009d\u0011\u00a5\u00bd\u00c1W\u0014\u00c0\u00f7\u00e4a\u00a1\u00d6t0\u00c0", + {}, + ], + "molprops": {"ofe-name": "lig_ejm_42"}, + "__qualname__": "SmallMoleculeComponent", + "__module__": "gufe.components.smallmoleculecomponent", + }, + "componentA_to_componentB": { + "0": 0, + "1": 1, + "2": 2, + "3": 3, + "4": 4, + "5": 5, + "6": 6, + "7": 7, + "8": 8, + "9": 9, + "10": 10, + "11": 11, + "12": 12, + "13": 13, + "14": 14, + "15": 15, + "16": 16, + "17": 17, + "18": 18, + "19": 19, + "20": 20, + "21": 21, + "22": 22, + "23": 23, + "24": 24, + "25": 26, + "27": 25, + "28": 31, + "29": 32, + "30": 33, + "31": 34, + }, + "annotations": '{"score": 0.09516258196404048}', + "__qualname__": "LigandAtomMapping", + "__module__": "gufe.mapping.ligandatommapping", + }, }, } ]