diff --git a/vermouth/processors/annotate_mut_mod.py b/vermouth/processors/annotate_mut_mod.py index a5a834421..52bdee045 100644 --- a/vermouth/processors/annotate_mut_mod.py +++ b/vermouth/processors/annotate_mut_mod.py @@ -210,10 +210,12 @@ def annotate_modifications(molecule, modifications, mutations): (mutations, 'mutation', molecule.force_field.blocks)] residue_graph = make_residue_graph(molecule) - for res_idx in residue_graph: - for mutmod, key, library in associations: - for resspec, mod in mutmod: + for mutmod, key, library in associations: + for resspec, mod in mutmod: + mod_found = False + for res_idx in residue_graph: if residue_matches(resspec, residue_graph, res_idx): + mod_found = True if mod != 'none' and mod not in library: raise NameError('{} is not known as a {} for ' 'force field {}' @@ -223,7 +225,10 @@ def annotate_modifications(molecule, modifications, mutations): _format_resname(res), key, mod) for node_idx in res['graph']: molecule.nodes[node_idx][key] = molecule.nodes[node_idx].get(key, []) + [mod] - + if mod_found == False: + LOGGER.warning('Mutation "{}" not found. ' + 'Check target resid!' + ''.format(_format_resname(resspec))) class AnnotateMutMod(Processor): """ diff --git a/vermouth/tests/test_annotate_mut_mod.py b/vermouth/tests/test_annotate_mut_mod.py index 6afd1d1fe..3608258be 100644 --- a/vermouth/tests/test_annotate_mut_mod.py +++ b/vermouth/tests/test_annotate_mut_mod.py @@ -270,7 +270,7 @@ def test_annotate_mutmod_processor(example_mol, modifications, mutations, expect [(0, 1), (1, 2)], {1: ['N-ter'], 3: ['C-ter']} ), -( + ( [ {'resname': 'XXX', 'resid': 1}, {'resname': 'ALA', 'resid': 2}, @@ -289,7 +289,8 @@ def test_nter_cter_modifications(node_data, edge_data, expected): mol = Molecule(force_field=ForceField(FF_UNIVERSAL_TEST)) mol.add_nodes_from(enumerate(node_data)) mol.add_edges_from(edge_data) - modification = [({'resname': 'cter'}, 'C-ter'), ({'resname': 'nter'}, 'N-ter')] + modification = [({'resname': 'cter'}, 'C-ter'), + ({'resname': 'nter'}, 'N-ter')] annotate_modifications(mol, modification, []) @@ -300,3 +301,39 @@ def test_nter_cter_modifications(node_data, edge_data, expected): found[node['resid']] = node['modification'] assert found == expected + +@pytest.mark.parametrize('node_data, edge_data, expected', [ + ( + [ + {'resname': 'GLY', 'resid': 1}, + {'resname': 'ALA', 'resid': 2}, + {'resname': 'ALA', 'resid': 3} + ], + [(0, 1), (1, 2)], + False + ), + ( + [ + {'resname': 'ALA', 'resid': 1}, + {'resname': 'ALA', 'resid': 2}, + {'resname': 'ALA', 'resid': 3} + ], + [(0, 1), (1, 2)], + True + )]) +def test_mod_resid_not_correct(caplog, node_data, edge_data, expected): + """ + Tests that the modification is found in the expected residue. + """ + mol = Molecule(force_field=ForceField(FF_UNIVERSAL_TEST)) + mol.add_nodes_from(enumerate(node_data)) + mol.add_edges_from(edge_data) + mutation = [({'resname': 'GLY', 'resid': 1}, 'MET')] + + caplog.clear() + annotate_modifications(mol, [], mutation) + + if expected: + assert '"GLY1" not found.' in str(caplog.records[0].getMessage()) + else: + assert caplog.records == []