From c45a9379b7540fea1932bc51a85c94b5ba36869d Mon Sep 17 00:00:00 2001
From: Gabriel Studer <gabriel.studer@unibas.ch>
Date: Mon, 29 Jun 2020 08:18:19 +0200
Subject: [PATCH] perforn alignment preprocesing in BuildRawModel

---
 .../scripts/modelling_close_small_deletions.py |  4 ++--
 modelling/pymod/_raw_model.py                  | 18 ++++++++++++++++--
 modelling/tests/test_close_gaps.py             | 12 ++++++++----
 modelling/tests/test_modelling.py              |  6 ++++--
 4 files changed, 30 insertions(+), 10 deletions(-)

diff --git a/doc/tests/scripts/modelling_close_small_deletions.py b/doc/tests/scripts/modelling_close_small_deletions.py
index 9a7f2dac..caf6ad69 100644
--- a/doc/tests/scripts/modelling_close_small_deletions.py
+++ b/doc/tests/scripts/modelling_close_small_deletions.py
@@ -3,8 +3,8 @@ from promod3 import modelling
 
 # setup
 tpl = io.LoadPDB('data/gly.pdb')
-aln = seq.CreateAlignment(seq.CreateSequence('trg', 'GGG-GGG'),
-                          seq.CreateSequence('tpl', 'GGGAGGG'))
+aln = seq.CreateAlignment(seq.CreateSequence('trg', 'GGGG-GGGG'),
+                          seq.CreateSequence('tpl', 'GGGGAGGGG'))
 aln.AttachView(1, tpl.CreateFullView())
 mhandle = modelling.BuildRawModel(aln)
 # close small deletion
diff --git a/modelling/pymod/_raw_model.py b/modelling/pymod/_raw_model.py
index dd2b26e7..b08ae45b 100644
--- a/modelling/pymod/_raw_model.py
+++ b/modelling/pymod/_raw_model.py
@@ -15,11 +15,12 @@
 
 # internal
 from ._modelling import *
+from ._alignment_fiddling import *
 # external
 import ost
 
 def BuildRawModel(aln, chain_names = None, include_ligands = False, 
-                  spdbv_style = False):
+                  spdbv_style = False, aln_preprocessing='default'):
     '''Builds a raw (pseudo) model from the alignment. Can either take a single
       alignment handle or an alignment handle list. Every list item is treated as a
       single chain in the final raw model.
@@ -27,6 +28,9 @@ def BuildRawModel(aln, chain_names = None, include_ligands = False,
       Each alignment handle must contain exactly two sequences and the second
       sequence is considered the template sequence, which must have a 
       :class:`~ost.mol.EntityView` attached.
+
+      Before extracting the coordinates, the alignments are pre-processed 
+      according to *aln_preprocessing*.
     
       This is a basic protein core modelling algorithm that copies backbone
       coordinates based on the sequence alignment. For matching residues, the
@@ -79,7 +83,11 @@ def BuildRawModel(aln, chain_names = None, include_ligands = False,
     
       :param spdbv_style: True, if we need a model in the old SPDBV style.
       :type spdbv_style:  :class:`bool`
-    
+
+      :param aln_preprocessing: Calls :meth:`promod3.modelling.PullTerminalDeletions` 
+                                if set to 'default'. Can be disabled when set 
+                                to False.
+
       :return: Raw (pseudo) model from the alignment.
       :rtype:  :class:`ModellingHandle`
     
@@ -129,4 +137,10 @@ def BuildRawModel(aln, chain_names = None, include_ligands = False,
         raise RuntimeError('aln must be of type ost.seq.AlignmentHandle or '\
                            'ost.seq.AlignmentList')
 
+    if aln_preprocessing == 'default':
+        temp = ost.seq.AlignmentList()
+        for a in aln_list:
+            temp.append(PullTerminalDeletions(a))
+        aln_list = temp
+
     return MHandleFromAln(aln_list, name_list, include_ligands, spdbv_style)
diff --git a/modelling/tests/test_close_gaps.py b/modelling/tests/test_close_gaps.py
index f2eb4882..9b88c4fb 100644
--- a/modelling/tests/test_close_gaps.py
+++ b/modelling/tests/test_close_gaps.py
@@ -175,7 +175,8 @@ class CloseGapsTests(unittest.TestCase):
         aln = seq.CreateAlignment(seq.CreateSequence('trg', 'GGG-GGG'),
                                   seq.CreateSequence('tpl', 'GGGAGGG'))
         aln.AttachView(1, tpl.CreateFullView())
-        mhandle = modelling.BuildRawModel(aln)
+        # disable aln_preprocessing as deletion would be removed
+        mhandle = modelling.BuildRawModel(aln, aln_preprocessing=False)
         self.assertEqual(len(mhandle.gaps), 1)
         # close it
         nlogs = len(self.log.messages['INFO'])
@@ -202,7 +203,8 @@ class CloseGapsTests(unittest.TestCase):
         alns = seq.AlignmentList()
         alns.append(aln_A)
         alns.append(aln_B)
-        mhandle = modelling.BuildRawModel(alns)
+        # disable aln_preprocessing as one of the deletions would be removed
+        mhandle = modelling.BuildRawModel(alns, aln_preprocessing=False)
         self.assertEqual(len(mhandle.gaps), 2)
         # do it
         modelling.CloseSmallDeletions(mhandle)
@@ -581,7 +583,8 @@ class CloseGapsTests(unittest.TestCase):
             seq.CreateSequence('trg', 'NGG----------------------RVE'),
             seq.CreateSequence('tpl', 'NGGTLLIPNGTYHFLGIQMKSNVHIRVE'))
         aln.AttachView(1, tpl.CreateFullView())
-        mhandle = modelling.BuildRawModel(aln)
+        # disable aln_preprocessing as the deletion would be removed 
+        mhandle = modelling.BuildRawModel(aln, aln_preprocessing=False)
         self.assertEqual(len(mhandle.gaps), 1)
         modelling.CloseLargeDeletions(mhandle, self.structure_db,
                                       num_fragments=100)
@@ -596,7 +599,8 @@ class CloseGapsTests(unittest.TestCase):
             seq.CreateSequence('trg', 'GAGAGAGANG--LLIPNGTYHFLGIQMKSNVHIRVE'),
             seq.CreateSequence('tpl', '--------NGGTLLIPNGTYHFLGIQMKSNVHIRVE'))
         aln.AttachView(1, tpl.CreateFullView())
-        mhandle = modelling.BuildRawModel(aln)
+        # disable aln_preprocessing as the deletion would be removed
+        mhandle = modelling.BuildRawModel(aln, aln_preprocessing=False)
         modelling.RemoveTerminalGaps(mhandle)
         self.assertEqual(len(mhandle.gaps), 1)
         modelling.CloseLargeDeletions(mhandle, self.structure_db,
diff --git a/modelling/tests/test_modelling.py b/modelling/tests/test_modelling.py
index 382b1035..f8e8b946 100644
--- a/modelling/tests/test_modelling.py
+++ b/modelling/tests/test_modelling.py
@@ -109,7 +109,8 @@ class ModellingTests(unittest.TestCase):
         tpl = io.LoadPDB('data/gly.pdb')
         aln = io.LoadAlignment('data/del.fasta')
         aln.AttachView(1, tpl.CreateFullView())
-        result = modelling.BuildRawModel(aln)
+        # disable aln_preprocessing to keep the deletion in the example aln
+        result = modelling.BuildRawModel(aln, aln_preprocessing=False)
         residues = result.model.residues
         self.assertEqual(len(result.gaps), 1)
         self.assertEqual(result.gaps[0].before, residues[2])
@@ -432,7 +433,8 @@ class ModellingTests(unittest.TestCase):
             seq.CreateSequence('trg', 'TLNGFTVPAGNTLVLN---PDKG--ATVTM-A'),
             seq.CreateSequence('tpl', 'N-GG-TLLI--PNGTYHFLGIQMKSNVHIRVE'))
         aln.AttachView(1, tpl.CreateFullView())
-        mhandle = modelling.BuildRawModel(aln)
+        # disable aln_preprocessing to also keep the small deletion in the end
+        mhandle = modelling.BuildRawModel(aln, aln_preprocessing=False)
         # check
         self.assertEqual(len(mhandle.gaps), 6)
         self.assertEqual(modelling.ClearGaps(mhandle, mhandle.gaps[1]), 1)
-- 
GitLab