Skip to content
Snippets Groups Projects
Select Git revision
  • 96054d054fea14290bef1c329e669810048768d6
  • master default protected
  • develop protected
  • cmake_boost_refactor
  • ubuntu_ci
  • mmtf
  • non-orthogonal-maps
  • no_boost_filesystem
  • data_viewer
  • 2.11.1
  • 2.11.0
  • 2.10.0
  • 2.9.3
  • 2.9.2
  • 2.9.1
  • 2.9.0
  • 2.8.0
  • 2.7.0
  • 2.6.1
  • 2.6.0
  • 2.6.0-rc4
  • 2.6.0-rc3
  • 2.6.0-rc2
  • 2.6.0-rc
  • 2.5.0
  • 2.5.0-rc2
  • 2.5.0-rc
  • 2.4.0
  • 2.4.0-rc2
29 results

bitmap_io.cc

Blame
  • test_close_gaps.py 28.68 KiB
    # Copyright (c) 2013-2020, SIB - Swiss Institute of Bioinformatics and
    #                          Biozentrum - University of Basel
    # 
    # Licensed under the Apache License, Version 2.0 (the "License");
    # you may not use this file except in compliance with the License.
    # You may obtain a copy of the License at
    # 
    #   http://www.apache.org/licenses/LICENSE-2.0
    # 
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    # See the License for the specific language governing permissions and
    # limitations under the License.
    
    
    """
    Unit tests for modelling components to close gaps.
    """
    import unittest
    import ost
    from ost import io, seq, geom
    from promod3 import loop, modelling, core
    
    # setting up an OST LogSink to capture messages
    class _FetchLog(ost.LogSink):
        def __init__(self):
            ost.LogSink.__init__(self)
            self.messages = dict()
    
        def LogMessage(self, message, severity):
            levels = ['ERROR', 'WARNING', 'SCRIPT', 'INFO', 'VERBOSE', 'DEBUG',
                      'TRACE']
            level = levels[severity]
            if not level in list(self.messages.keys()):
                self.messages[level] = list()
            self.messages[level].append(message.strip())
    
    class CloseGapsTests(unittest.TestCase):
        def setUp(self):
            self.log = _FetchLog()
            ost.PushLogSink(self.log)
            ost.PushVerbosityLevel(4)
    
        @classmethod
        def setUpClass(cls):
            '''Load dbs etc here for all tests.'''
            cls.frag_db = loop.LoadFragDB()
            cls.structure_db = loop.LoadStructureDB()
            cls.torsion_sampler = loop.LoadTorsionSamplerCoil()
    
        @classmethod
        def tearDownClass(cls):
            # show runtimes if this was enabled
            core.StaticRuntimeProfiler.PrintSummary(5)
    
        #######################################################################
        # HELPERs
        #######################################################################
    
        def backboneCheck(self, model, trg_seq, max_error = 0.3, chain_idx=0):
            '''Check if backbone bond lengths are reasonable.'''
            lastc = None
            # exp. from CHARMM
            exp_d0 = 1.345
            exp_d1 = 1.430
            exp_d2 = 1.490
            max_diff = 0
            seq = ''
            for res in model.chains[chain_idx].residues:
                seq = seq + res.one_letter_code
                n = res.FindAtom('N');
                ca = res.FindAtom('CA');
                c = res.FindAtom('C');
                if lastc is not None:
                    d0 = geom.Length(n.GetPos() - lastc.GetPos())
                    max_diff = max(abs(d0 - exp_d0), max_diff)
                d1 = geom.Length(ca.GetPos() - n.GetPos())
                max_diff = max(abs(d1 - exp_d1), max_diff)
                d2 = geom.Length(c.GetPos() - ca.GetPos())
                max_diff = max(abs(d2 - exp_d2), max_diff)
                lastc = c
            self.assertLess(max_diff, max_error)
            self.assertEqual(seq, trg_seq)
    
        def backboneCheckHandle(self, mhandle, max_error=0.3):
            '''Execute backboneCheck for all chains in mhandle.'''
            model = mhandle.model
            for chain_idx in range(model.chain_count):
                # cut to possibly remove termini from target sequence
                seqres = str(mhandle.seqres[chain_idx])
                a = model.chains[chain_idx].residues[0].GetNumber().GetNum()
                b = model.chains[chain_idx].residues[-1].GetNumber().GetNum()
                self.backboneCheck(model, seqres[a-1:b], max_error, chain_idx)
    
        def getGapTest(self):
            '''Helper to get test with 2 gaps.'''
            tpl = io.LoadPDB('data/2dbs.pdb')
            aln = seq.CreateAlignment(
                seq.CreateSequence('trg', 'TLNGFTVPAGNTLV--LNPDKGATVTMAAAA'),
                seq.CreateSequence('tpl', 'NGGTLLIPNGTYHFLGIQMKSN---VHIRVE'))
    
            aln.AttachView(1, tpl.CreateFullView())
            mhandle = modelling.BuildRawModel(aln)
            self.assertEqual(len(mhandle.gaps), 2)
            return mhandle
    
        def getGapTestDeletion(self):
            '''Helper to get test with deletion.'''
            tpl = io.LoadPDB('data/2dbs.pdb')
            aln = seq.CreateAlignment(
                seq.CreateSequence('trg', 'TLNGFTVPAGNTLV--LNPDKGATVTMA'),
                seq.CreateSequence('tpl', 'NGGTLLIPNGTYHFLGIQMKSNVHIRVE'))
    
            aln.AttachView(1, tpl.CreateFullView())
            mhandle = modelling.BuildRawModel(aln)
            self.assertEqual(len(mhandle.gaps), 1)
            return mhandle
    
        def getGapTestInsertion(self):
            '''Helper to get test with insertion.'''
            tpl = io.LoadPDB('data/2dbs.pdb')
            aln = seq.CreateAlignment(
                seq.CreateSequence('trg', 'TLNGFTVPAGNTLVAALNPDKGGAGATVTMA'),
                seq.CreateSequence('tpl', 'NGGTLLIPNGTYHFLGIQMKSN---VHIRVE'))
    
            aln.AttachView(1, tpl.CreateFullView())
            mhandle = modelling.BuildRawModel(aln)
            self.assertEqual(len(mhandle.gaps), 1)
            return mhandle
    
        def getGapTestInsertionTerminal(self):
            '''Helper to get test with insertion close to terminal.'''
            tpl = io.LoadPDB('data/2dbs.pdb')
            aln = seq.CreateAlignment(
                seq.CreateSequence('trg', 'TALNGFTVPAGNTLVAALNPDKGATVTMA'),
                seq.CreateSequence('tpl', 'N-GGTLLIPNGTYHFLGIQMKSNVHIRVE'))
    
            aln.AttachView(1, tpl.CreateFullView())
            mhandle = modelling.BuildRawModel(aln)
            self.assertEqual(len(mhandle.gaps), 1)
            return mhandle
    
        def getGapTestTerminal(self):
            '''Helper to get test with terminal gaps.'''
            tpl = io.LoadPDB('data/2dbs.pdb')
            aln = seq.CreateAlignment(
                seq.CreateSequence('trg', 'TLNGFTVPAGNTLVAALNPDKGGAGATVTMA'),
                seq.CreateSequence('tpl', '-NGGTLLIPNGTYHFLGIQMKSNVHIRVE--'))
    
            aln.AttachView(1, tpl.CreateFullView())
            mhandle = modelling.BuildRawModel(aln)
            self.assertEqual(len(mhandle.gaps), 2)
            return mhandle
    
        def getRawModelOligo(self, file_prefix):
            '''Get raw model for tests with oligomers.'''
            tpl = io.LoadPDB(file_prefix + '.pdb')
            alns = seq.AlignmentList()
            alns.append(io.LoadAlignment(file_prefix + "_A.fasta"))
            alns.append(io.LoadAlignment(file_prefix + "_B.fasta"))
            alns[0].AttachView(1, tpl.Select("cname=A").CreateFullView())
            alns[1].AttachView(1, tpl.Select("cname=B").CreateFullView())
            mhandle = modelling.BuildRawModel(alns)
            return mhandle
    
        #######################################################################
    
        def testCloseSmallDel(self):
            '''Check that very small gaps are closed.'''
            # create a raw model to work with (which actually is a bit dangerous:
            # the PDB file has nothing to do with the alignment...)
            tpl = io.LoadPDB('data/gly.pdb')
            # switch target and template in this alignment to get a deletion
            aln = seq.CreateAlignment(seq.CreateSequence('trg', 'GGG-GGG'),
                                      seq.CreateSequence('tpl', 'GGGAGGG'))
            aln.AttachView(1, tpl.CreateFullView())
            mhandle = modelling.BuildRawModel(aln)
            self.assertEqual(len(mhandle.gaps), 1)
            # close it
            nlogs = len(self.log.messages['INFO'])
            modelling.CloseSmallDeletions(mhandle)
            self.assertEqual(len(mhandle.gaps), 0)
            # check backbone
            self.backboneCheck(mhandle.model, 'GGGGGG')
            # check logs
            self.assertGreaterEqual(len(self.log.messages['INFO'])-nlogs, 1)
            self.assertEqual(self.log.messages['INFO'][-1],
                             'Closed: A.GLY3-()-A.GLY4 by relaxing A.GLY3-(GG)-A.GLY6')
    
        def testCloseSmallDelOligo(self):
            '''Check that very small gaps are closed for oligomers.'''
            tpl = io.LoadPDB('data/5d52-1.pdb')
            aln_A = seq.CreateAlignment(
                seq.CreateSequence('trg', 'GIV-QCCTSICSLYQLENYCN'),
                seq.CreateSequence('tpl', 'GIVEQCCTSICSLYQLENYCN'))
            aln_B = seq.CreateAlignment(
                seq.CreateSequence('trg', 'FVNQHLCGSH-LEALTLVCGERGFFYTPKA'),
                seq.CreateSequence('tpl', 'FVNQHLCGSHLVEALYLVCGERGFFYTPKA'))
            aln_A.AttachView(1, tpl.Select("cname=A").CreateFullView())
            aln_B.AttachView(1, tpl.Select("cname=B").CreateFullView())
            alns = seq.AlignmentList()
            alns.append(aln_A)
            alns.append(aln_B)
            mhandle = modelling.BuildRawModel(alns)
            self.assertEqual(len(mhandle.gaps), 2)
            # do it
            modelling.CloseSmallDeletions(mhandle)
            # check
            self.assertEqual(len(mhandle.gaps), 0)
            self.backboneCheckHandle(mhandle)
    
        def testMergeGapsByDistance(self):
            '''Test that merging two close gaps works.'''
            tpl = io.LoadPDB('data/1mcg.pdb')
            aln = seq.CreateAlignment(seq.CreateSequence('trg', 'DDFAGDTKNLGHN'),
                                      seq.CreateSequence('tpl', 'NN----A----LF'))
            aln.AttachView(1, tpl.CreateFullView())
            mhandle = modelling.BuildRawModel(aln)
            self.assertEqual(len(mhandle.gaps), 2)
            self.assertEqual(str(mhandle.gaps[0]), 'A.ASP2-(FAGD)-A.THR7')
            self.assertEqual(str(mhandle.gaps[1]), 'A.THR7-(KNLG)-A.HIS12')
            nlogs = len(self.log.messages['INFO'])
            modelling.MergeGapsByDistance(mhandle, 0)
            self.assertEqual(len(mhandle.gaps), 1)
            self.assertEqual(str(mhandle.gaps[0]), 'A.ASP2-(FAGDTKNLG)-A.HIS12')
            # check logs
            self.assertGreaterEqual(len(self.log.messages['INFO'])-nlogs, 1)
            self.assertEqual(self.log.messages['INFO'][-1],
                             'Merged gap A.ASP2-(FAGD)-A.THR7 and A.THR7-(KNLG)-'+
                             'A.HIS12 into A.ASP2-(FAGDTKNLG)-A.HIS12')
    
        def testMergeGapsByDistanceBothTerminals(self):
            '''Test that we do not delete the whole thing for gaps at terminals.'''
            tpl = io.LoadPDB('data/1mcg.pdb')
            aln = seq.CreateAlignment(seq.CreateSequence('trg', 'DDFAGDTKNLGHN'),
                                      seq.CreateSequence('tpl', '----NNALF----'))
            aln.AttachView(1, tpl.CreateFullView())
            mhandle = modelling.BuildRawModel(aln)
            self.assertEqual(len(mhandle.gaps), 2)
            modelling.MergeGapsByDistance(mhandle, 4)
            self.assertEqual(len(mhandle.gaps), 2)
    
        def testMergeGapsByDistanceOneTerminal(self):
            '''Test that we do not delete the whole thing for gaps at terminals.'''
            tpl = io.LoadPDB('data/1mcg.pdb')
            aln = seq.CreateAlignment(seq.CreateSequence('trg', 'DDFAGDTKNLGHN'),
                                      seq.CreateSequence('tpl', 'NN----ALF----'))
            aln.AttachView(1, tpl.CreateFullView())
            mhandle = modelling.BuildRawModel(aln)
            self.assertEqual(len(mhandle.gaps), 2)
            modelling.MergeGapsByDistance(mhandle, 2)
            self.assertEqual(len(mhandle.gaps), 1)
    
        def testMergeGapsByDistanceNonSequential(self):
            '''Test that we ignore and non-sequential gaps and are notified.'''
            tpl = io.LoadPDB('data/1mcg.pdb')
            aln = seq.CreateAlignment(seq.CreateSequence('trg', 'DFATHN'),
                                      seq.CreateSequence('tpl', 'NNA-LF'))
            aln.AttachView(1, tpl.CreateFullView())
            mhandle = modelling.BuildRawModel(aln)
            # add fake gap
            res = mhandle.model.FindResidue('A', 2)
            mygap = modelling.StructuralGap(res.prev, res.next, res.one_letter_code)
            mhandle.gaps.append(mygap)
            # check
            self.assertEqual(len(mhandle.gaps), 2)
            nlogs = len(self.log.messages['INFO'])
            modelling.MergeGapsByDistance(mhandle, 10)
            self.assertEqual(len(mhandle.gaps), 2)
            # check logs
            self.assertGreaterEqual(len(self.log.messages['INFO'])-nlogs, 1)
            self.assertEqual(self.log.messages['INFO'][-1],
                             'Non-sequential gaps found. Ignoring.')
    
        def testMergeGapsByDistanceOligomers(self):
            '''Test that we merge gaps on different chains w/o joining them.'''
            tpl = io.LoadPDB('data/5d52-1.pdb')
            aln_A = seq.CreateAlignment(
                seq.CreateSequence('trg', 'GIVEQAAAC-TSICSLYQLENYCN'),
                seq.CreateSequence('tpl', 'GIVEQ---CCTSICSLYQLENYCN'))
            aln_B = seq.CreateAlignment(
                seq.CreateSequence('trg', 'FVNQHLCGSH-LEAL--VACGERGFFYTPKA'),
                seq.CreateSequence('tpl', 'FVNQHLCGSHLVEALYLV-CGERGFFYTPKA'))
            aln_A.AttachView(1, tpl.Select("cname=A").CreateFullView())
            aln_B.AttachView(1, tpl.Select("cname=B").CreateFullView())
            alns = seq.AlignmentList()
            alns.append(aln_A)
            alns.append(aln_B)
            mhandle = modelling.BuildRawModel(alns)
            # check
            self.assertEqual(len(mhandle.gaps), 5)
            modelling.MergeGapsByDistance(mhandle, 0)
            self.assertEqual(len(mhandle.gaps), 3)
            self.assertEqual(str(mhandle.gaps[0]), 'A.GLN5-(AAAC)-A.THR10')
            self.assertEqual(str(mhandle.gaps[1]), 'B.HIS10-()-B.LEU11')
            self.assertEqual(str(mhandle.gaps[2]), 'B.LEU14-(VA)-B.CYS17')
    
        #######################################################################
    
        def testFillGapsByDatabase(self):
            '''Get rid of 2 gaps by db.'''
            mhandle = self.getGapTest()
            modelling.FillLoopsByDatabase(mhandle, self.frag_db,
                                          self.structure_db,
                                          self.torsion_sampler)
            self.assertEqual(len(mhandle.gaps), 0)
            # check backbone
            self.backboneCheck(mhandle.model, 'TLNGFTVPAGNTLVLNPDKGATVTMAAAA')
            # no log-check as this can easily change whenever we change DB
    
        def testFillGapsByDatabaseDeletion(self):
            '''Get rid of deletion by db.'''
            mhandle = self.getGapTestDeletion()
            modelling.FillLoopsByDatabase(mhandle, self.frag_db,
                                          self.structure_db,
                                          self.torsion_sampler)
            self.assertEqual(len(mhandle.gaps), 0)
            # check backbone
            self.backboneCheck(mhandle.model, 'TLNGFTVPAGNTLVLNPDKGATVTMA')
            # no log-check as this can easily change whenever we change DB
    
        def testFillGapsByDatabaseInsertion(self):
            '''Get rid of insertion by db.'''
            mhandle = self.getGapTestInsertion()
            modelling.FillLoopsByDatabase(mhandle, self.frag_db,
                                          self.structure_db,
                                          self.torsion_sampler)
            self.assertEqual(len(mhandle.gaps), 0)
            # check backbone
            self.backboneCheck(mhandle.model, 'TLNGFTVPAGNTLVAALNPDKGGAGATVTMA')
            # no log-check as this can easily change whenever we change DB
    
        def testFillGapsByDatabaseInsertionTerminal(self):
            '''Get rid of insertion by db close to terminal (needs FullExtender).'''
            mhandle = self.getGapTestInsertionTerminal()
            modelling.FillLoopsByDatabase(mhandle, self.frag_db,
                                          self.structure_db,
                                          self.torsion_sampler,
                                          use_full_extender=True)
            self.assertEqual(len(mhandle.gaps), 0)
            # check backbone
            self.backboneCheck(mhandle.model, 'TALNGFTVPAGNTLVAALNPDKGATVTMA')
            # no log-check as this can easily change whenever we change DB
    
        def testFillGapsByDatabaseTerminal(self):
            '''Terminal loops are not altered.'''
            mhandle = self.getGapTestTerminal()
            modelling.FillLoopsByDatabase(mhandle, self.frag_db,
                                          self.structure_db,
                                          self.torsion_sampler)
            self.assertEqual(len(mhandle.gaps), 2)
    
        def testFillGapsByDatabaseNoSE(self):
            '''Get rid of 2 gaps by db (without scoring extender).'''
            mhandle = self.getGapTest()
            modelling.FillLoopsByDatabase(mhandle, self.frag_db,
                                          self.structure_db,
                                          self.torsion_sampler,
                                          use_scoring_extender=False)
            self.assertEqual(len(mhandle.gaps), 0)
            # check backbone
            self.backboneCheck(mhandle.model, 'TLNGFTVPAGNTLVLNPDKGATVTMAAAA')
            # no log-check as this can easily change whenever we change DB
    
        def testFillGapsByDatabaseDeletionNoSE(self):
            '''Get rid of deletion by db (without scoring extender).'''
            mhandle = self.getGapTestDeletion()
            modelling.FillLoopsByDatabase(mhandle, self.frag_db,
                                          self.structure_db,
                                          self.torsion_sampler,
                                          use_scoring_extender=False)
            self.assertEqual(len(mhandle.gaps), 0)
            # check backbone
            self.backboneCheck(mhandle.model, 'TLNGFTVPAGNTLVLNPDKGATVTMA')
            # no log-check as this can easily change whenever we change DB
    
        def testFillGapsByDatabaseInsertionNoSE(self):
            '''Get rid of insertion by db (without scoring extender).'''
            mhandle = self.getGapTestInsertion()
            modelling.FillLoopsByDatabase(mhandle, self.frag_db,
                                          self.structure_db,
                                          self.torsion_sampler,
                                          use_scoring_extender=False)
            self.assertEqual(len(mhandle.gaps), 0)
            # check backbone
            self.backboneCheck(mhandle.model, 'TLNGFTVPAGNTLVAALNPDKGGAGATVTMA')
            # no log-check as this can easily change whenever we change DB
    
        def testFillGapsByDatabaseTerminalNoSE(self):
            '''Terminal loops are not altered (without scoring extender).'''
            mhandle = self.getGapTestTerminal()
            modelling.FillLoopsByDatabase(mhandle, self.frag_db,
                                          self.structure_db,
                                          self.torsion_sampler,
                                          use_scoring_extender=False)
            self.assertEqual(len(mhandle.gaps), 2)
    
        def testFillGapsByDatabaseNonDefSV(self):
            '''Get rid of 2 gaps by db (with non-def. score_variant).'''
            for score_variant in [1,2]:
                mhandle = self.getGapTest()
                modelling.FillLoopsByDatabase(mhandle, self.frag_db,
                                              self.structure_db,
                                              self.torsion_sampler,
                                              score_variant=score_variant)
                self.assertEqual(len(mhandle.gaps), 0)
                # check backbone
                self.backboneCheck(mhandle.model, 'TLNGFTVPAGNTLVLNPDKGATVTMAAAA')
                # no log-check as this can easily change whenever we change DB
    
        def testFillGapsByDatabaseAllAtom(self):
            '''Get rid of 2 gaps by db (with all atom scoring).'''
            for score_variant in [0,1,2]:
                mhandle = self.getGapTest()
                modelling.FillLoopsByDatabase(mhandle, self.frag_db,
                                              self.structure_db,
                                              self.torsion_sampler,
                                              score_variant=score_variant,
                                              max_num_all_atom=5)
                self.assertEqual(len(mhandle.gaps), 0)
                # check backbone
                self.backboneCheck(mhandle.model, 'TLNGFTVPAGNTLVLNPDKGATVTMAAAA')
                # no log-check as this can easily change whenever we change DB
            
        def testFillGapsByDatabaseHomoOligomer(self):
            '''Get rid of 2 gaps by db for homo oligomers.'''
            mhandle = self.getRawModelOligo("data/2aoh-1_cut")
            modelling.FillLoopsByDatabase(mhandle, self.frag_db,
                                          self.structure_db,
                                          self.torsion_sampler)
            self.assertEqual(len(mhandle.gaps), 0)
            self.backboneCheckHandle(mhandle)
            
        def testFillGapsByDatabaseHeteroOligomer(self):
            '''Get rid of 2 gaps by db for hetero oligomers.'''
            mhandle = self.getRawModelOligo("data/5d52-1_cut")
            modelling.FillLoopsByDatabase(mhandle, self.frag_db,
                                          self.structure_db,
                                          self.torsion_sampler)
            self.assertEqual(len(mhandle.gaps), 0)
            self.backboneCheckHandle(mhandle)
    
        #######################################################################
        
        def testFillGapsByMonteCarlo(self):
            '''Get rid of 2 gaps by MC.'''
            mhandle = self.getGapTest()
            modelling.FillLoopsByMonteCarlo(mhandle, self.torsion_sampler,
                                            mc_steps=100)
            self.assertEqual(len(mhandle.gaps), 0)
            # check backbone
            self.backboneCheck(mhandle.model, 'TLNGFTVPAGNTLVLNPDKGATVTMAAAA')
            # no log-check as this can easily change whenever we change DB
    
        def testFillGapsByMonteCarloDeletion(self):
            '''Get rid of deletion by MC.'''
            mhandle = self.getGapTestDeletion()
            modelling.FillLoopsByMonteCarlo(mhandle, self.torsion_sampler,
                                            mc_steps=100)
            self.assertEqual(len(mhandle.gaps), 0)
            # check backbone
            self.backboneCheck(mhandle.model, 'TLNGFTVPAGNTLVLNPDKGATVTMA')
            # no log-check as this can easily change whenever we change DB
    
        def testFillGapsByMonteCarloInsertion(self):
            '''Get rid of insertion by MC.'''
            mhandle = self.getGapTestInsertion()
            modelling.FillLoopsByMonteCarlo(mhandle, self.torsion_sampler,
                                            mc_steps=100)
            self.assertEqual(len(mhandle.gaps), 0)
            # check backbone
            self.backboneCheck(mhandle.model, 'TLNGFTVPAGNTLVAALNPDKGGAGATVTMA')
            # no log-check as this can easily change whenever we change DB
    
        def testFillGapsByMonteCarloTerminal(self):
            '''Terminal loops are not altered.'''
            mhandle = self.getGapTestTerminal()
            modelling.FillLoopsByMonteCarlo(mhandle, self.torsion_sampler,
                                            mc_steps=100)
            self.assertEqual(len(mhandle.gaps), 2)
            
        def testFillGapsByMonteCarloHomoOligomer(self):
            '''Get rid of 2 gaps by db for homo oligomers.'''
            mhandle = self.getRawModelOligo("data/2aoh-1_cut")
            modelling.FillLoopsByMonteCarlo(mhandle, self.torsion_sampler,
                                            mc_steps=100)
            self.assertEqual(len(mhandle.gaps), 0)
            self.backboneCheckHandle(mhandle)
            
        def testFillGapsByMonteCarloHeteroOligomer(self):
            '''Get rid of 2 gaps by db for hetero oligomers.'''
            mhandle = self.getRawModelOligo("data/5d52-1_cut")
            modelling.FillLoopsByMonteCarlo(mhandle, self.torsion_sampler,
                                            mc_steps=100)
            self.assertEqual(len(mhandle.gaps), 0)
            self.backboneCheckHandle(mhandle)
    
        def testModelTermini(self):
            '''Model terminal loops (and only those).'''
            tpl = io.LoadPDB('data/gly.pdb')
            aln = seq.CreateAlignment(
                seq.CreateSequence('trg', 'AAAAGGGGGGGGGGAAGGGGGGGGGGAAAAAA'),
                seq.CreateSequence('tpl', '----GGGGGGGGGG--GGGGGGGGGG------'))
            aln.AttachView(1, tpl.CreateFullView())
            mhandle = modelling.BuildRawModel(aln)
            self.assertEqual(len(mhandle.gaps), 3)
            # model termini
            modelling.ModelTermini(mhandle, self.torsion_sampler,
                                   mc_steps = 100)
            self.assertEqual(len(mhandle.gaps), 1)
            myseq = ''.join([r.one_letter_code for r in mhandle.model.residues])
            self.assertEqual(myseq, 'AAAAGGGGGGGGGGGGGGGGGGGGAAAAAA')
            # model rest
            modelling.FillLoopsByDatabase(mhandle, self.frag_db,
                                          self.structure_db,
                                          self.torsion_sampler)
            self.assertEqual(len(mhandle.gaps), 0)
            self.backboneCheck(mhandle.model, 'AAAAGGGGGGGGGGAAGGGGGGGGGGAAAAAA')
    
        def testModelTerminiOligo(self):
            '''Model terminal loops for two chains.'''
            tpl = io.LoadPDB('data/5d52-1.pdb')
            aln_A = seq.CreateAlignment(
                seq.CreateSequence('trg', 'HELLGIVEQCCTSICSLYQLENYCNYES'),
                seq.CreateSequence('tpl', '----GIVEQCCTSICSLYQLENYCN---'))
            aln_B = seq.CreateAlignment(
                seq.CreateSequence('trg', 'AAAFVNQHLCGSHLVEALYLVCGERGFFYTPKAGG'),
                seq.CreateSequence('tpl', '---FVNQHLCGSHLVEALYLVCGERGFFYTPKA--'))
            aln_A.AttachView(1, tpl.Select("cname=A").CreateFullView())
            aln_B.AttachView(1, tpl.Select("cname=B").CreateFullView())
            alns = seq.AlignmentList()
            alns.append(aln_A)
            alns.append(aln_B)
            mhandle = modelling.BuildRawModel(alns)
            self.assertEqual(len(mhandle.gaps), 4)
            # model termini
            modelling.ModelTermini(mhandle, self.torsion_sampler,
                                   mc_steps = 100)
            self.assertEqual(len(mhandle.gaps), 0)
            self.assertEqual(mhandle.model.residue_count, 63)
            self.backboneCheckHandle(mhandle)
    
        #######################################################################
    
        def testCloseLargeDeletions(self):
            '''Get rid of large deletion with linker.'''
            tpl = io.LoadPDB('data/2dbs.pdb')
            aln = seq.CreateAlignment(
                seq.CreateSequence('trg', 'NGGTFTVPA-----------KGATVRVE'),
                seq.CreateSequence('tpl', 'NGGTLLIPNGTYHFLGIQMKSNVHIRVE'))
            aln.AttachView(1, tpl.CreateFullView())
            mhandle = modelling.BuildRawModel(aln)
            self.assertEqual(len(mhandle.gaps), 1)
            modelling.CloseLargeDeletions(mhandle, self.structure_db,
                                          num_fragments=100)
            self.assertEqual(len(mhandle.gaps), 0)
            # check backbone
            self.backboneCheck(mhandle.model, 'NGGTFTVPAKGATVRVE')
    
        def testCloseLargeDeletionsMerge(self):
            '''Get rid of large deletion with linker after merge.'''
            tpl = io.LoadPDB('data/2dbs.pdb')
            aln = seq.CreateAlignment(
                seq.CreateSequence('trg', 'NGGTFTVPA-----GA----KGATVRVE'),
                seq.CreateSequence('tpl', 'NGGTLLIPNGTYHFLGIQMKSNVHIRVE'))
            aln.AttachView(1, tpl.CreateFullView())
            mhandle = modelling.BuildRawModel(aln)
            modelling.MergeGapsByDistance(mhandle, 1)
            self.assertEqual(len(mhandle.gaps), 1)
            modelling.CloseLargeDeletions(mhandle, self.structure_db,
                                          num_fragments=100)
            self.assertEqual(len(mhandle.gaps), 0)
            # check backbone
            self.backboneCheck(mhandle.model, 'NGGTFTVPAGAKGATVRVE')
    
        def testCloseLargeDeletionsSL(self):
            '''Get rid of large deletion with small linker.'''
            tpl = io.LoadPDB('data/2dbs.pdb')
            aln = seq.CreateAlignment(
                seq.CreateSequence('trg', 'NGG----------------------RVE'),
                seq.CreateSequence('tpl', 'NGGTLLIPNGTYHFLGIQMKSNVHIRVE'))
            aln.AttachView(1, tpl.CreateFullView())
            mhandle = modelling.BuildRawModel(aln)
            self.assertEqual(len(mhandle.gaps), 1)
            modelling.CloseLargeDeletions(mhandle, self.structure_db,
                                          num_fragments=100)
            self.assertEqual(len(mhandle.gaps), 0)
            # check backbone
            self.backboneCheck(mhandle.model, 'NGGRVE')
    
        def testCloseLargeDeletionsTer(self):
            '''Get rid of large deletion with N-terminal gap.'''
            tpl = io.LoadPDB('data/2dbs.pdb')
            aln = seq.CreateAlignment(
                seq.CreateSequence('trg', 'GAGAGAGANG--LLIPNGTYHFLGIQMKSNVHIRVE'),
                seq.CreateSequence('tpl', '--------NGGTLLIPNGTYHFLGIQMKSNVHIRVE'))
            aln.AttachView(1, tpl.CreateFullView())
            mhandle = modelling.BuildRawModel(aln)
            modelling.RemoveTerminalGaps(mhandle)
            self.assertEqual(len(mhandle.gaps), 1)
            modelling.CloseLargeDeletions(mhandle, self.structure_db,
                                          num_fragments=100)
            self.assertEqual(len(mhandle.gaps), 0)
            # check backbone
            self.backboneCheck(mhandle.model, 'NGLLIPNGTYHFLGIQMKSNVHIRVE')
    
        def testCloseLargeDeletionsOligo(self):
            '''Get rid of large deletions in two chains.'''
            tpl = io.LoadPDB('data/5d52-1.pdb')
            aln_A = seq.CreateAlignment(
                seq.CreateSequence('trg', 'GIVEQ-----------ENYCN'),
                seq.CreateSequence('tpl', 'GIVEQCCTSICSLYQLENYCN'))
            aln_B = seq.CreateAlignment(
                seq.CreateSequence('trg', 'FVNQHLCGSH-----------RGFFYTPKA'),
                seq.CreateSequence('tpl', 'FVNQHLCGSHLVEALYLVCGERGFFYTPKA'))
            aln_A.AttachView(1, tpl.Select("cname=A").CreateFullView())
            aln_B.AttachView(1, tpl.Select("cname=B").CreateFullView())
            alns = seq.AlignmentList()
            alns.append(aln_A)
            alns.append(aln_B)
            mhandle = modelling.BuildRawModel(alns)
            self.assertEqual(len(mhandle.gaps), 2)
            modelling.CloseLargeDeletions(mhandle, self.structure_db,
                                          num_fragments=100)
            self.assertEqual(len(mhandle.gaps), 0)
            # check backbone
            self.backboneCheckHandle(mhandle)
    
            
    if __name__ == "__main__":
        from ost import testutils
        testutils.RunTests()