Skip to content
Snippets Groups Projects
Commit 5ae2da3f authored by Gerardo Tauriello's avatar Gerardo Tauriello
Browse files

SCHWED-2440: use "peptide" flag to filter chains in mol.alg.Superpose.

This changes behaviors in MatchResidueByLocalAln and MatchResidueByGlobalAln (
or Superpose with match = local-aln or global-aln) which previously failed for
non-"protein" chains (i.e. anything w/o peptide bonds). Now, amino acid chains
without peptide bonds (e.g. CA-only) are acceptable and other chains (e.g.
ligands / water) are skipped correctly.
parent c57f05a5
Branches
Tags
No related merge requests found
......@@ -193,8 +193,8 @@ def _MatchResidueByAln(ent_a, ent_b, atoms, alnmethod):
## fetch chains (peptide-linking residues only)
chain_a = ent_a.chains[i]
chain_b = ent_b.chains[i]
chain_view_a = chain_a.Select('protein=true')
chain_view_b = chain_b.Select('protein=true')
chain_view_a = chain_a.Select('peptide=true')
chain_view_b = chain_b.Select('peptide=true')
if chain_view_a.chain_count == 0 or chain_view_b.chain_count == 0:
# skip empty chains
continue
......@@ -240,12 +240,12 @@ def MatchResidueByLocalAln(ent_a, ent_b, atoms='all'):
"""
Match residues by local alignment. Takes **ent_a** and **ent_b**, extracts the
sequences chain-wise and aligns them in Smith/Waterman manner using the
BLOSUM62 matrix for scoring. Only residues which are marked as "protein" (see
:attr:`~ost.mol.ResidueHandle.is_protein`) are considered for alignment. The
residues of the entities are then matched based on this alignment. Only atoms
present in both residues are included in the views. Chains are processed in
order of appearance. If **ent_a** and **ent_b** contain a different number of
chains, processing stops with the lower count.
BLOSUM62 matrix for scoring. Only residues which are marked as :attr:`peptide
linking <ost.mol.ResidueHandle.peptide_linking>` are considered for alignment.
The residues of the entities are then matched based on this alignment. Only
atoms present in both residues are included in the views. Chains are processed
in order of appearance. If **ent_a** and **ent_b** contain a different number
of chains, processing stops with the lower count.
:param ent_a: The first entity
:type ent_a: :class:`~ost.mol.EntityView` or :class:`~ost.mol.EntityHandle`
......
......@@ -176,7 +176,7 @@ class TestConvenientSuperpose(unittest.TestCase):
view1, view2 = mol.alg.MatchResidueByLocalAln(ent_view_wrong, ent_view)
self.assertEqualAtomOrder(view1, view2)
def testWrongResidueOrder(self):
def testWrongResidueOrder(self):
ent_view = io.LoadEntity(os.path.join("testfiles","1aho.pdb")).Select("")
ent_view_wrong = ent_view.CreateEmptyView()
for c in ent_view.chains:
......@@ -193,6 +193,37 @@ class TestConvenientSuperpose(unittest.TestCase):
view1, view2 = mol.alg.MatchResidueByNum(ent_view_wrong, ent_view)
self.assertEqualAtomOrder(view1, view2)
def testPeptideFilter(self):
# check that CA only chains are ok and ligand chains are skipped
ent_1_full = io.LoadPDB(os.path.join("testfiles", "5tglA.pdb"))
ent_2_full = io.LoadPDB(os.path.join("testfiles", "5tglA_modified.pdb"))
exp_atom_count = 253
# check CA-only chain
ent_1 = ent_1_full.Select("cname=A")
ent_2 = ent_2_full.Select("cname=A")
view1, view2 = mol.alg.MatchResidueByLocalAln(ent_1, ent_2)
self.assertEqual(view1.atom_count, exp_atom_count)
self.assertEqual(view2.atom_count, exp_atom_count)
view1, view2 = mol.alg.MatchResidueByGlobalAln(ent_1, ent_2)
self.assertEqual(view1.atom_count, exp_atom_count)
self.assertEqual(view2.atom_count, exp_atom_count)
# check ligand chain
ent_1_ligand = ent_1_full.Select("cname='_'")
ent_2_ligand = ent_2_full.Select("cname='_'")
view1, view2 = mol.alg.MatchResidueByLocalAln(ent_1_ligand, ent_2_ligand)
self.assertEqual(view1.atom_count, 0)
self.assertEqual(view2.atom_count, 0)
view1, view2 = mol.alg.MatchResidueByGlobalAln(ent_1_ligand, ent_2_ligand)
self.assertEqual(view1.atom_count, 0)
self.assertEqual(view2.atom_count, 0)
# check both together
view1, view2 = mol.alg.MatchResidueByLocalAln(ent_1_full, ent_2_full)
self.assertEqual(view1.atom_count, exp_atom_count)
self.assertEqual(view2.atom_count, exp_atom_count)
view1, view2 = mol.alg.MatchResidueByGlobalAln(ent_1_full, ent_2_full)
self.assertEqual(view1.atom_count, exp_atom_count)
self.assertEqual(view2.atom_count, exp_atom_count)
if __name__ == "__main__":
from ost import testutils
testutils.RunTests()
This diff is collapsed.
This diff is collapsed.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment