From 23a9d6b27c73632d2ca41db4bfd9b4d6e018b18f Mon Sep 17 00:00:00 2001 From: csbrasnett Date: Mon, 28 Oct 2024 17:30:31 +0100 Subject: [PATCH 1/6] redid tests to fix and ensure coverage --- vermouth/processors/do_links.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/vermouth/processors/do_links.py b/vermouth/processors/do_links.py index 4284beab5..fa0f0c49d 100644 --- a/vermouth/processors/do_links.py +++ b/vermouth/processors/do_links.py @@ -23,6 +23,10 @@ from ..molecule import attributes_match from .processor import Processor +from ..log_helpers import StyleAdapter, get_logger + +LOGGER = StyleAdapter(get_logger(__name__)) + def _atoms_match(node1, node2): # node1 is molecule, node2 is link @@ -315,6 +319,12 @@ def run_molecule(self, molecule): for inter_type, interactions in link.interactions.items(): for interaction in interactions: interaction = _build_link_interaction_from(molecule, interaction, match) + if "comment" in interaction.meta: + if interaction.meta["comment"] == "Disulfide bridge": + res1 = molecule.nodes[interaction.atoms[0]].get("resid") + res2 = molecule.nodes[interaction.atoms[1]].get("resid") + msg = f"Disulfide bridge found between residues {res1} and {res2}" + LOGGER.info(msg) molecule.add_or_replace_interaction(inter_type, *interaction, link.citations) for loglevel, entries in link.log_entries.items(): From 1d3edf1dd835808467e01bec05c2d4eb7d3b5bc0 Mon Sep 17 00:00:00 2001 From: csbrasnett Date: Tue, 29 Oct 2024 09:10:47 +0100 Subject: [PATCH 2/6] Improve log message to include chainIDs --- vermouth/processors/do_links.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/vermouth/processors/do_links.py b/vermouth/processors/do_links.py index fa0f0c49d..3467b60b1 100644 --- a/vermouth/processors/do_links.py +++ b/vermouth/processors/do_links.py @@ -321,9 +321,14 @@ def run_molecule(self, molecule): interaction = _build_link_interaction_from(molecule, interaction, match) if "comment" in interaction.meta: if interaction.meta["comment"] == "Disulfide bridge": - res1 = molecule.nodes[interaction.atoms[0]].get("resid") - res2 = molecule.nodes[interaction.atoms[1]].get("resid") - msg = f"Disulfide bridge found between residues {res1} and {res2}" + msg = ("Disulfide bridge found between residues " + f"{molecule.nodes[interaction.atoms[0]].get('chain')}-" + f"{molecule.nodes[interaction.atoms[0]].get('resname')}" + f"{molecule.nodes[interaction.atoms[0]].get('resid')} and " + f"{molecule.nodes[interaction.atoms[1]].get('chain')}-" + f"{molecule.nodes[interaction.atoms[1]].get('resname')}" + f"{molecule.nodes[interaction.atoms[1]].get('resid')}" + ) LOGGER.info(msg) molecule.add_or_replace_interaction(inter_type, *interaction, link.citations) From 982de6d08edf2d7e96c907915330aac21d0363f6 Mon Sep 17 00:00:00 2001 From: csbrasnett Date: Tue, 29 Oct 2024 10:43:45 +0100 Subject: [PATCH 3/6] added draft of test - doesn't seem to assert correctly atm but not clear why, the link gets found correctly --- vermouth/processors/do_links.py | 17 +++++++-------- vermouth/tests/test_links.py | 38 +++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 9 deletions(-) diff --git a/vermouth/processors/do_links.py b/vermouth/processors/do_links.py index 3467b60b1..5f82ce028 100644 --- a/vermouth/processors/do_links.py +++ b/vermouth/processors/do_links.py @@ -321,15 +321,14 @@ def run_molecule(self, molecule): interaction = _build_link_interaction_from(molecule, interaction, match) if "comment" in interaction.meta: if interaction.meta["comment"] == "Disulfide bridge": - msg = ("Disulfide bridge found between residues " - f"{molecule.nodes[interaction.atoms[0]].get('chain')}-" - f"{molecule.nodes[interaction.atoms[0]].get('resname')}" - f"{molecule.nodes[interaction.atoms[0]].get('resid')} and " - f"{molecule.nodes[interaction.atoms[1]].get('chain')}-" - f"{molecule.nodes[interaction.atoms[1]].get('resname')}" - f"{molecule.nodes[interaction.atoms[1]].get('resid')}" - ) - LOGGER.info(msg) + LOGGER.info("Disulfide bridge found between residues {}-{}{} and {}-{}{}", + molecule.nodes[interaction.atoms[0]].get('chain'), + molecule.nodes[interaction.atoms[0]].get('resname'), + molecule.nodes[interaction.atoms[0]].get('resid'), + molecule.nodes[interaction.atoms[1]].get('chain'), + molecule.nodes[interaction.atoms[1]].get('resname'), + molecule.nodes[interaction.atoms[1]].get('resid') + ) molecule.add_or_replace_interaction(inter_type, *interaction, link.citations) for loglevel, entries in link.log_entries.items(): diff --git a/vermouth/tests/test_links.py b/vermouth/tests/test_links.py index 4bd8453ce..4da727801 100644 --- a/vermouth/tests/test_links.py +++ b/vermouth/tests/test_links.py @@ -314,3 +314,41 @@ def modification(*names): def test_modification_matching(mol_node, link_node, expected): found = _atoms_match(mol_node, link_node) assert found == expected + +@pytest.mark.parametrize('mol_nodes, mol_edges, expected', ( + ( + [(0, {'atomname': 'BB', 'resname': 'CYS', 'resid': 1, 'chain': 'A'}), + (1, {'atomname': 'SC1', 'resname': 'CYS', 'resid': 1, 'chain': 'A'}), + (2, {'atomname': 'BB', 'resname': 'GLY', 'resid': 2, 'chain': 'A'}), + (3, {'atomname': 'BB', 'resname': 'GLY', 'resid': 3, 'chain': 'A'}), + (4, {'atomname': 'BB', 'resname': 'GLY', 'resid': 4, 'chain': 'A'}), + (5, {'atomname': 'BB', 'resname': 'CYS', 'resid': 5, 'chain': 'A'}), + (6, {'atomname': 'SC1', 'resname': 'CYS', 'resid': 5, 'chain': 'A'}), + (7, {'atomname': 'BB', 'resname': 'GLY', 'resid': 6, 'chain': 'A'}), + ], + ((0, 1), (0, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7), (1, 6)), + True + ), + ( + [(0, {'atomname': 'BB', 'resname': 'CYS', 'resid': 1, 'chain': 'A'}), + (1, {'atomname': 'SC1', 'resname': 'CYS', 'resid': 1, 'chain': 'A'}), + (2, {'atomname': 'BB', 'resname': 'GLY', 'resid': 2, 'chain': 'A'}), + (3, {'atomname': 'BB', 'resname': 'GLY', 'resid': 3, 'chain': 'A'}), + (4, {'atomname': 'BB', 'resname': 'GLY', 'resid': 4, 'chain': 'A'}), + (5, {'atomname': 'BB', 'resname': 'CYS', 'resid': 5, 'chain': 'A'}), + (6, {'atomname': 'SC1', 'resname': 'CYS', 'resid': 5, 'chain': 'A'}), + (7, {'atomname': 'BB', 'resname': 'GLY', 'resid': 6, 'chain': 'A'}), + ], + ((0, 1), (0, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7)), + False + ) +)) +def test_disulfide_msg(mol_nodes, mol_edges, expected, caplog): + ff = vermouth.forcefield.get_native_force_field('martini3001') + mol = make_mol(mol_nodes, mol_edges, force_field=ff) + caplog.clear() + DoLinks().run_molecule(mol) + if expected: + assert any(rec.levelname == 'INFO' for rec in caplog.records) + else: + assert caplog.records == [] From 781147bd7c7d539d82ef1e13773b1b2e9de2d0c9 Mon Sep 17 00:00:00 2001 From: csbrasnett Date: Tue, 29 Oct 2024 11:17:43 +0100 Subject: [PATCH 4/6] Wrote info into force field file directly. Removed redundant test and code --- .../force_fields/martini3001/aminoacids.ff | 2 + vermouth/processors/do_links.py | 10 ----- vermouth/tests/test_links.py | 38 ------------------- 3 files changed, 2 insertions(+), 48 deletions(-) diff --git a/vermouth/data/force_fields/martini3001/aminoacids.ff b/vermouth/data/force_fields/martini3001/aminoacids.ff index fac831b52..a3ada6ef4 100644 --- a/vermouth/data/force_fields/martini3001/aminoacids.ff +++ b/vermouth/data/force_fields/martini3001/aminoacids.ff @@ -1275,3 +1275,5 @@ resname "CYS" SC1 >SC1 1 0.24 {"comment": "Disulfide bridge"} [ features ] disulfide +[ info ] +Disulfide bridge found between residues {SC1[chain]}-{SC1[resname]}{SC1[resid]} and {>SC1[chain]}-{>SC1[resname]}{>SC1[resid]} diff --git a/vermouth/processors/do_links.py b/vermouth/processors/do_links.py index 5f82ce028..2f54fd71e 100644 --- a/vermouth/processors/do_links.py +++ b/vermouth/processors/do_links.py @@ -319,16 +319,6 @@ def run_molecule(self, molecule): for inter_type, interactions in link.interactions.items(): for interaction in interactions: interaction = _build_link_interaction_from(molecule, interaction, match) - if "comment" in interaction.meta: - if interaction.meta["comment"] == "Disulfide bridge": - LOGGER.info("Disulfide bridge found between residues {}-{}{} and {}-{}{}", - molecule.nodes[interaction.atoms[0]].get('chain'), - molecule.nodes[interaction.atoms[0]].get('resname'), - molecule.nodes[interaction.atoms[0]].get('resid'), - molecule.nodes[interaction.atoms[1]].get('chain'), - molecule.nodes[interaction.atoms[1]].get('resname'), - molecule.nodes[interaction.atoms[1]].get('resid') - ) molecule.add_or_replace_interaction(inter_type, *interaction, link.citations) for loglevel, entries in link.log_entries.items(): diff --git a/vermouth/tests/test_links.py b/vermouth/tests/test_links.py index 4da727801..4bd8453ce 100644 --- a/vermouth/tests/test_links.py +++ b/vermouth/tests/test_links.py @@ -314,41 +314,3 @@ def modification(*names): def test_modification_matching(mol_node, link_node, expected): found = _atoms_match(mol_node, link_node) assert found == expected - -@pytest.mark.parametrize('mol_nodes, mol_edges, expected', ( - ( - [(0, {'atomname': 'BB', 'resname': 'CYS', 'resid': 1, 'chain': 'A'}), - (1, {'atomname': 'SC1', 'resname': 'CYS', 'resid': 1, 'chain': 'A'}), - (2, {'atomname': 'BB', 'resname': 'GLY', 'resid': 2, 'chain': 'A'}), - (3, {'atomname': 'BB', 'resname': 'GLY', 'resid': 3, 'chain': 'A'}), - (4, {'atomname': 'BB', 'resname': 'GLY', 'resid': 4, 'chain': 'A'}), - (5, {'atomname': 'BB', 'resname': 'CYS', 'resid': 5, 'chain': 'A'}), - (6, {'atomname': 'SC1', 'resname': 'CYS', 'resid': 5, 'chain': 'A'}), - (7, {'atomname': 'BB', 'resname': 'GLY', 'resid': 6, 'chain': 'A'}), - ], - ((0, 1), (0, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7), (1, 6)), - True - ), - ( - [(0, {'atomname': 'BB', 'resname': 'CYS', 'resid': 1, 'chain': 'A'}), - (1, {'atomname': 'SC1', 'resname': 'CYS', 'resid': 1, 'chain': 'A'}), - (2, {'atomname': 'BB', 'resname': 'GLY', 'resid': 2, 'chain': 'A'}), - (3, {'atomname': 'BB', 'resname': 'GLY', 'resid': 3, 'chain': 'A'}), - (4, {'atomname': 'BB', 'resname': 'GLY', 'resid': 4, 'chain': 'A'}), - (5, {'atomname': 'BB', 'resname': 'CYS', 'resid': 5, 'chain': 'A'}), - (6, {'atomname': 'SC1', 'resname': 'CYS', 'resid': 5, 'chain': 'A'}), - (7, {'atomname': 'BB', 'resname': 'GLY', 'resid': 6, 'chain': 'A'}), - ], - ((0, 1), (0, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7)), - False - ) -)) -def test_disulfide_msg(mol_nodes, mol_edges, expected, caplog): - ff = vermouth.forcefield.get_native_force_field('martini3001') - mol = make_mol(mol_nodes, mol_edges, force_field=ff) - caplog.clear() - DoLinks().run_molecule(mol) - if expected: - assert any(rec.levelname == 'INFO' for rec in caplog.records) - else: - assert caplog.records == [] From fb974ce4a3afe24c1b6632b45b0a5ed9c9733842 Mon Sep 17 00:00:00 2001 From: csbrasnett Date: Tue, 29 Oct 2024 11:28:53 +0100 Subject: [PATCH 5/6] Added cys info into other force field files --- vermouth/data/force_fields/elnedyn21/aminoacids.ff | 2 ++ vermouth/data/force_fields/elnedyn22/aminoacids.ff | 2 ++ vermouth/data/force_fields/elnedyn22p/aminoacids.ff | 2 ++ vermouth/data/force_fields/martini22/aminoacids.ff | 2 ++ vermouth/data/force_fields/martini22p/aminoacids.ff | 2 ++ vermouth/data/force_fields/martini30b32/aminoacids.ff | 2 ++ vermouth/data/force_fields/martini30dev/aminoacids.ff | 2 ++ 7 files changed, 14 insertions(+) diff --git a/vermouth/data/force_fields/elnedyn21/aminoacids.ff b/vermouth/data/force_fields/elnedyn21/aminoacids.ff index 20adc72c9..8e4bb8837 100644 --- a/vermouth/data/force_fields/elnedyn21/aminoacids.ff +++ b/vermouth/data/force_fields/elnedyn21/aminoacids.ff @@ -610,3 +610,5 @@ resname "CYS" SC1 >SC1 1 0.24 {"comment": "Disulfide bridge"} ;[ features ] ;disulfide +[ info ] +Disulfide bridge found between residues {SC1[chain]}-{SC1[resname]}{SC1[resid]} and {>SC1[chain]}-{>SC1[resname]}{>SC1[resid]} \ No newline at end of file diff --git a/vermouth/data/force_fields/elnedyn22/aminoacids.ff b/vermouth/data/force_fields/elnedyn22/aminoacids.ff index 52459be94..8d8865736 100644 --- a/vermouth/data/force_fields/elnedyn22/aminoacids.ff +++ b/vermouth/data/force_fields/elnedyn22/aminoacids.ff @@ -610,3 +610,5 @@ resname "CYS" SC1 >SC1 1 0.24 {"comment": "Disulfide bridge"} ;[ features ] ;disulfide +[ info ] +Disulfide bridge found between residues {SC1[chain]}-{SC1[resname]}{SC1[resid]} and {>SC1[chain]}-{>SC1[resname]}{>SC1[resid]} \ No newline at end of file diff --git a/vermouth/data/force_fields/elnedyn22p/aminoacids.ff b/vermouth/data/force_fields/elnedyn22p/aminoacids.ff index 7ec3bc7b8..d29a8fbff 100644 --- a/vermouth/data/force_fields/elnedyn22p/aminoacids.ff +++ b/vermouth/data/force_fields/elnedyn22p/aminoacids.ff @@ -686,6 +686,8 @@ resname "CYS" SC1 >SC1 1 0.24 {"comment": "Disulfide bridge"} ;[ features ] ;disulfide +[ info ] +Disulfide bridge found between residues {SC1[chain]}-{SC1[resname]}{SC1[resid]} and {>SC1[chain]}-{>SC1[resname]}{>SC1[resid]} ; Exclusions between the charged terminii and the charge dummies [ link ] diff --git a/vermouth/data/force_fields/martini22/aminoacids.ff b/vermouth/data/force_fields/martini22/aminoacids.ff index 76f79657f..f1da6e26d 100644 --- a/vermouth/data/force_fields/martini22/aminoacids.ff +++ b/vermouth/data/force_fields/martini22/aminoacids.ff @@ -883,3 +883,5 @@ resname "CYS" SC1 >SC1 1 0.24 {"comment": "Disulfide bridge"} ;[ features ] ;disulfide +[ info ] +Disulfide bridge found between residues {SC1[chain]}-{SC1[resname]}{SC1[resid]} and {>SC1[chain]}-{>SC1[resname]}{>SC1[resid]} \ No newline at end of file diff --git a/vermouth/data/force_fields/martini22p/aminoacids.ff b/vermouth/data/force_fields/martini22p/aminoacids.ff index 0931caead..a3c88a17c 100644 --- a/vermouth/data/force_fields/martini22p/aminoacids.ff +++ b/vermouth/data/force_fields/martini22p/aminoacids.ff @@ -889,6 +889,8 @@ resname "CYS" SC1 >SC1 1 0.24 {"comment": "Disulfide bridge"} ;[ features ] ;disulfide +[ info ] +Disulfide bridge found between residues {SC1[chain]}-{SC1[resname]}{SC1[resid]} and {>SC1[chain]}-{>SC1[resname]}{>SC1[resid]} ; Exclusions between the charged terminii and the charge dummies [ link ] diff --git a/vermouth/data/force_fields/martini30b32/aminoacids.ff b/vermouth/data/force_fields/martini30b32/aminoacids.ff index cdf1633bc..fdf8dd0f9 100644 --- a/vermouth/data/force_fields/martini30b32/aminoacids.ff +++ b/vermouth/data/force_fields/martini30b32/aminoacids.ff @@ -782,3 +782,5 @@ resname "CYS" SC1 >SC1 1 0.24 {"comment": "Disulfide bridge"} [ features ] disulfide +[ info ] +Disulfide bridge found between residues {SC1[chain]}-{SC1[resname]}{SC1[resid]} and {>SC1[chain]}-{>SC1[resname]}{>SC1[resid]} \ No newline at end of file diff --git a/vermouth/data/force_fields/martini30dev/aminoacids.ff b/vermouth/data/force_fields/martini30dev/aminoacids.ff index 1424029e6..d107751d8 100644 --- a/vermouth/data/force_fields/martini30dev/aminoacids.ff +++ b/vermouth/data/force_fields/martini30dev/aminoacids.ff @@ -827,3 +827,5 @@ resname "CYS" SC1 >SC1 1 0.24 {"comment": "Disulfide bridge"} [ features ] disulfide +[ info ] +Disulfide bridge found between residues {SC1[chain]}-{SC1[resname]}{SC1[resid]} and {>SC1[chain]}-{>SC1[resname]}{>SC1[resid]} \ No newline at end of file From 8d7fb128208a2792b8702f14d98fb9147d3fbdf4 Mon Sep 17 00:00:00 2001 From: csbrasnett Date: Tue, 29 Oct 2024 11:43:13 +0100 Subject: [PATCH 6/6] removed unnecessary import --- vermouth/processors/do_links.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/vermouth/processors/do_links.py b/vermouth/processors/do_links.py index 2f54fd71e..4284beab5 100644 --- a/vermouth/processors/do_links.py +++ b/vermouth/processors/do_links.py @@ -23,10 +23,6 @@ from ..molecule import attributes_match from .processor import Processor -from ..log_helpers import StyleAdapter, get_logger - -LOGGER = StyleAdapter(get_logger(__name__)) - def _atoms_match(node1, node2): # node1 is molecule, node2 is link