class ModernaFragment5Tests(TestCase): """fragment attached at 3' end of model""" def setUp(self): self.m = RnaModel(data_type='file', data=MINI_TEMPLATE, seq=Sequence("GCGGAUUUALCUCAG")) self.s1 = ModernaStructure('file', SMALL_FRAGMENT, seq=Sequence("GCGG")) self.s2 = ModernaStructure('file', SMALL_FRAGMENT, seq=Sequence("GCGG")) def test_attributes(self): five = ModernaFragment5(self.s1, anchor5=self.m['15']) self.assertEqual(len(five.anchor_residues), 1) self.assertEqual(len(five.nonanchor_residues), 3) self.assertTrue(str(five)) def test_add_on_3_end(self): """Model sequence should change accordingly.""" five = ModernaFragment5(self.s1, anchor5=self.m['15']) self.m.insert_fragment(five) self.assertEqual(self.m.get_sequence(), Sequence("GCGGAUUUALCUCAGCGG")) self.assertTrue(five.rmsd <= 1.00) def test_add_on_3_end_replace(self): """Model sequence should change accordingly.""" five_overwrite = ModernaFragment5(self.s2, anchor5=self.m['9']) self.m.insert_fragment(five_overwrite) self.assertEqual(self.m.get_sequence(), Sequence("GCGGAUUUACGG")) self.assertTrue(five_overwrite.rmsd <= 1.00, 0)
def test_model_with_5p3p_ends(self): a = read_alignment('''> target CAUGCGGAYYYALCUCAGGUA > mini_template ---GCGGAUUUALCUCAG--- ''') m = RnaModel(self.t, a) m.create_model() self.assertEqual(m.get_sequence(), Sequence('CAUGCGGAYYYALCUCAGGUA'))
def test_gaps_in_target(self): """Moderna should model gaps in the target, too.""" a = read_alignment(ALIGN_TARGET_GAP) m = RnaModel(self.t, a) m.apply_alignment() m.insert_all_fragments() self.assertEqual( m.get_sequence().seq_with_modifications.replace('_', ''), '..CUGACCU#P')
def test_5p_extension(self): a = read_alignment("""> target AAAAAAAAAAGCGGAUUUALCUCAG > template ----------GCGGAUUUALCUCAG """) m = RnaModel(None, a, data_type='file', data=MINI_TEMPLATE) m.add_missing_5p() self.assertEqual(m.get_sequence(), a.target_seq)
class ModernaFragment3Tests(TestCase): def setUp(self): """ fragment attached at 5' end of model. """ self.m = RnaModel(data_type='file', data=MINI_TEMPLATE, seq=Sequence("GCGGAUUUALCUCAG")) self.s1 = ModernaStructure('file', SMALL_FRAGMENT, seq=Sequence("GCGG")) self.s2 = ModernaStructure('file', SMALL_FRAGMENT, seq=Sequence("GCGG")) def test_attributes(self): """Attributes of fragment are accessible.""" three = ModernaFragment3(self.s1, anchor3=self.m['1']) self.assertEqual(len(three.anchor_residues), 1) self.assertEqual(len(three.nonanchor_residues), 3) self.assertTrue(str(three)) def test_add_on_5_end(self): """Model sequence should change accordingly.""" three = ModernaFragment3(self.s1, anchor3=self.m['1']) self.m.insert_fragment(three) self.assertEqual(self.m.get_sequence(), Sequence("GCGGCGGAUUUALCUCAG")) self.assertTrue(three.rmsd <= 1.00) def test_add_on_5_end_exact(self): """Model sequence should change accordingly.""" # exactly fitting example replacing original residues. three_overwrite = ModernaFragment3(self.s2, anchor3=self.m['6']) self.m.insert_fragment(three_overwrite) self.assertEqual(self.m.get_sequence(), Sequence("GCGUUUALCUCAG")) self.assertTrue(three_overwrite.rmsd <= 1.00) def test_add_discontinuous(self): """Tries to add a helix to an end.""" helix = ModernaStructure('file', 'test_data/rna_structures/helix.pdb') helix_frag = ModernaFragment3(helix, anchor3=self.m['1'], strict=False) self.m.insert_fragment(helix_frag) self.assertEqual(self.m.get_sequence(), Sequence('CCGACCUUCGGCC_GGUGGCCGAAGGGCGGAUUUALCUCAG'))
def test_create_model_with_gaps(self): """Should create the model automatically.""" a = read_alignment(ALIGN_1B23_1QF6) t = Template(RNA_1B23, 'file', 'R') m = RnaModel(t, a) m.apply_alignment() m.insert_all_fragments() self.assertEqual( m.get_sequence().seq_with_modifications.replace('_', ''), 'GCCGAUAUAGCUCAGDDGGDAGAGCAGCGCAUUCGUEAUGCGAAG7UCGUAGGTPCGACUCCUAUUAUCGGCACCA' )
def test_model_with_hydro_template(self): """If the template contains hydrogens, modifications should be added.""" t = Template(RNA_HYDRO, 'file', 'B') a = read_alignment("""> 3tra_A.pdb Z73314.1/2358-2429 UPA > 1qru_B.pdb X55374.1/1-72 CAA """) m = RnaModel(t, a) m.create_model() self.assertEqual(m.get_sequence(), Sequence('UPA'))
def test_model_with_alignment_adjustment(self): """Introduces small corrections on alignment.""" a = read_alignment("""> target ACUGUGAYUA[UACCU#P-G > template with small errors. GCG7A----U.UAGCUCA_G """) t = Template(MINI_TEMPLATE, 'file') match_template_with_alignment(t, a) m = RnaModel(t, a) m.create_model() self.assertEqual(m.get_sequence(), Sequence("ACUGUGAYUA[UACCU#PG"))
def test_number_gap(self): """Builds model with numbering gap in the template.""" a = read_alignment("""> target CCGACCUUCGGCCACCUGACAGUCCUGUGCGGGAAACCGCACAGGACUGUCAACCAGGUAAUAUAACCACCGGGAAACGGUGGUUAUAUUACCUGGUACGCCUUGACGUGGGGGAAACCCCACGUCAAGGCGUGGUGGCCGAAGGUCGG > template CCGACCUUCGGCCACCUGACAGUCCUGUGCGG----CCGCACAGGACUGUCAACCAGGUAAUAUAACCACCGG----CGGUGGUUAUAUUACCUGGUACGCCUUGACGUGGGG----CCCCACGUCAAGGCGUGGUGGCCGAAGGUCGG """) t = Template(JMB_TEMPLATE, 'file') clean_structure(t) m = RnaModel(t, a) m.create_model() self.assertEqual(m.get_sequence().seq_without_breaks, a.target_seq)
def test_doublegap_model(self): """Should create a model filling two gaps""" a = read_alignment('''> target GGGAUAGUUCCAGABU#A > template GGGA-AG--CCAGABU#A ''') t = Template(DOUBLEGAP, 'file', 'A') m = RnaModel(t, a) m.apply_alignment() m.insert_all_fragments() m.fix_backbone() self.assertEqual(m.get_sequence(), Sequence('GGGAUAGUUCCAGABU#A'))
def test_insert_eliminate(self): """Inserts a 2D fragment into a model.""" helix = load_model(HELIX, 'A') helix = RnaModel(None, None, 'A', 'residues', helix['1':'8'] + helix['73':'80']) mf = ModernaFragment2D(self.motif, \ anchor5=helix['7'], anchor3=helix['74'], \ anchor5_upper=helix['8'], anchor3_upper=helix['73'], \ frag5_upper=self.motif['196'], frag3_upper=self.motif['217'], \ new_sequence=Sequence('C'), \ model=helix) helix.insert_fragment(mf) self.assertEqual(helix.get_sequence(), Sequence('AAAAAAAA_UCUUUUUUU')) self.assertEqual(helix.get_secstruc(), '(((((((().)))))))')
def test_oppositegap_model(self): """Should create a model with close gaps in the other respective sequence""" a = read_alignment('''> target GGGAGAGCRUUAG-BU#A > template GGGAGAGCR--AGABU#A ''') t = Template(OPPOSITEGAP, 'file', 'A') m = RnaModel(t, a) m.apply_alignment() m.insert_all_fragments() self.assertEqual( m.get_sequence().seq_with_modifications.replace('_', ''), 'GGGAGAGCRUUAGBU#A')
def test_long_5p_extension(self): a = read_alignment("""> target AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGCGGAUUUALCUCAG > template ----------------------------------------GCGGAUUUALCUCAG """) # first number == 1 should not work m = RnaModel(None, a, data_type='file', data=MINI_TEMPLATE) self.assertRaises(RenumeratorError, m.add_missing_5p) # first number == 100 should work m = RnaModel(None, a, data_type='file', data=MINI_TEMPLATE) renumber_chain(m, 100) m.add_missing_5p() self.assertEqual(m.get_sequence(), a.target_seq)
class FragmentInserterTests(TestCase): """ Tests for the FragmentInserter class """ def setUp(self): self.m = RnaModel(data_type='file',data=MINI_TEMPLATE, seq=Sequence("GCGGAUUUALCUCAG")) self.s1 = ModernaStructure('file', SMALL_FRAGMENT, seq=Sequence("GCGG")) #self.s2 = ModernaStructure('file',SMALL_FRAGMENT, seq=Sequence("GCGG")) #self.s3 = ModernaStructure('file', MINI_TEMPLATE, seq=Sequence("GCGGAUUUALCUCAG")) def test_insert(self): """Inserts fragment into a model""" f1 = ModernaFragment53(self.s1, anchor5=self.m['10'],anchor3=self.m['13']) finsert = FragmentInserter() finsert.insert_fragment(f1, self.m) self.assertEqual(self.m.get_sequence(),Sequence("GCGGAUUUALCGCAG"))
def test_fix_backbone_residues(self): """Accepts two residue numbers as parameters.""" m = RnaModel(data_type='file', data=FIXABLE_BACKBONE) fix_backbone(m, '4', '5') self.assertEqual(m.get_sequence(), Sequence('ACUGUG'))
def test_insert_indel_quality_1(self): """Insert a fragment without strand break""" t = Template('test_data/gaps/mini_1h4s_T_gap2.pdb', 'file', 'T') a = read_alignment('test_data/gaps/ali_gap2.fasta') m = RnaModel(t, a) self.assertEqual(m.get_sequence().seq_with_modifications.find('_'), -1)
class ModernaFragment53Tests(TestCase): """ Checks basic functionality of the ModernaFragment class. """ def setUp(self): self.m = RnaModel(data_type='file', data=MINI_TEMPLATE, seq=Sequence("GCGGAUUUALCUCAG")) self.s1 = ModernaStructure('file', SMALL_FRAGMENT, seq=Sequence("GCGG")) self.s2 = ModernaStructure('file', SMALL_FRAGMENT, seq=Sequence("GCGG")) self.s3 = ModernaStructure('file', MINI_TEMPLATE, seq=Sequence("GCGGAUUUALCUCAG")) def test_attributes(self): """object attributes are set up correctly.""" f1 = ModernaFragment53(self.s1, anchor5=self.m['10'], anchor3=self.m['13']) self.assertEqual(len(f1.struc), 4) self.assertEqual(f1.anchor5.fixed_resi, self.m['10']) self.assertEqual(f1.anchor3.fixed_resi, self.m['13']) self.assertEqual(f1.struc.get_sequence(), Sequence("GCGG")) self.assertTrue(str(f1)) # anchor residues self.assertEqual(len(f1.anchor_residues), 2) self.assertEqual(f1.anchor_residues[0].mobile_resi.identifier, '1') self.assertEqual(f1.anchor_residues[1].mobile_resi.identifier, '4') f1.prepare_anchor_residues() self.assertEqual(f1.anchor_residues[0].mobile_resi.identifier, '1') self.assertEqual(f1.anchor_residues[1].mobile_resi.identifier, '4') # non-anchors self.assertEqual(len(f1.nonanchor_residues), 2) # second example f2 = ModernaFragment53(self.s2, anchor5=self.m['1'], anchor3=self.m['4'], new_sequence=Sequence('GL')) self.assertEqual(len(f2.struc), 4) self.assertEqual(f2.struc.get_sequence(), Sequence("GCGG")) self.assertEqual(f2.new_sequence, Sequence("GL")) def test_get_resi_to_remove(self): """Should return resi identifiers between anchors and of anchors itself.""" f1 = ModernaFragment53(self.s1, anchor5=self.m['10'], anchor3=self.m['13']) result = f1.get_resi_to_remove(self.m) self.assertEqual(result, ['10', '11', '12', '13']) def test_renumber(self): """New numbering should start at anchor5, and then go through alphabet.""" f1 = ModernaFragment53(self.s1, anchor5=self.m['10'], anchor3=self.m['13']) f1.prepare_anchor_residues() f1.renumber() self.assertEqual([r.identifier for r in self.s1], ['10', '10A', '10B', '13']) # second example f2 = ModernaFragment53(self.s2, anchor5=self.m['1'], anchor3=self.m['4'], new_sequence=Sequence('GL')) f2.prepare_anchor_residues() f2.renumber() self.assertEqual([r.identifier for r in self.s2], ['1', '1A', '1B', '4']) def test_superimpose_fragment(self): """Should apply superimposition and return RMSD""" f1 = ModernaFragment53(self.s1, anchor5=self.m['10'], anchor3=self.m['13']) rmsd = f1.superimpose() self.assertAlmostEqual(rmsd, 1.0, 0) # MM: ? 1.1253267913922658 # second fragment should fit perfectly f2 = ModernaFragment53(self.s2, anchor5=self.m['1'], anchor3=self.m['4'], new_sequence=Sequence('GL')) rmsd = f2.superimpose() self.assertAlmostEqual(rmsd, 0.00) def test_refine(self): """Should change both numbers and sequence, and superimpose.""" f2 = ModernaFragment53(self.s2, anchor5=self.m['1'], anchor3=self.m['4'], new_sequence=Sequence('GL')) f2.superimpose() f2.prepare_anchor_residues() f2.renumber() f2.apply_seq() numbers = [r.identifier for r in self.s2] self.assertEqual(numbers, ['1', '1A', '1B', '4']) self.assertEqual(self.s2.get_sequence(), Sequence('GGLG')) def test_clash(self): """Should not clash with a given piece of structure.""" f1 = ModernaFragment53(self.s1, anchor5=self.m['10'], anchor3=self.m['13']) self.assertFalse(f1.has_clashes(self.m['8':'10'])) f2 = ModernaFragment53(self.s2, anchor5=self.m['1'], anchor3=self.m['4'], new_sequence=Sequence('GL')) self.assertTrue(f2.has_clashes(self.m['1':'4'])) def test_create_long_fragment(self): """Fragments with 26+ residues should be OK.""" t = load_template(RNA_1C0A, 'B') resis = t['5':'45'] long_seq = Sequence("AUAUAUAUAUGCGCGCGCGCAUAUAUAUAUGCGCGCGCG") struc = ModernaStructure('residues', resis) frag = ModernaFragment53(struc, anchor5=t['5'], anchor3=t['45'], new_sequence=long_seq) frag.superimpose() frag.prepare_anchor_residues() frag.renumber() frag.apply_seq() self.assertEqual(struc.get_sequence(), Sequence("CAUAUAUAUAUGCGCGCGCGCAUAUAUAUAUGCGCGCGCGG")) def test_add_numbering_letters(self): """Model numbers should change accordingly.""" middle1 = ModernaFragment53(self.s1, anchor5=self.m['9'], anchor3=self.m['14'], keep=keep_nothing) middle1.prepare_anchor_residues() middle1.renumber(self.m) self.m.insert_fragment(middle1) numbers = [r.identifier for r in self.m] expected = [ '1', '2', '3', '4', '5', '6', '7', '8', '9', '9A', '9B', '14', '15' ] self.assertEqual(numbers, expected) def test_add_keep_numbers(self): """Model numbers should change accordingly.""" middle1 = ModernaFragment53(self.s1, anchor5=self.m['9'], anchor3=self.m['14'], keep=keep_first_last) middle1.prepare_anchor_residues() middle1.renumber(self.m) self.m.insert_fragment(middle1) numbers = [r.identifier for r in self.m] expected = [ '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '13', '14', '15' ] self.assertEqual(numbers, expected) def test_add_continuous_exact(self): """Model sequence should change accordingly.""" f2 = ModernaFragment53(self.s2, anchor5=self.m['1'], anchor3=self.m['4'], new_sequence=Sequence('GL')) self.m.insert_fragment(f2) self.assertEqual(self.m.get_sequence(), Sequence("GGLGAUUUALCUCAG")) self.assertAlmostEqual(f2.rmsd, 0.000, 2)
def test_create_model_with_unknown(self): """Alignment that contains unknown bases in the target.""" a = read_alignment(MINI_ALIGNMENT_WITH_UNK) m = RnaModel(self.t, a) m.create_model() self.assertEqual(m.get_sequence(), Sequence('..CUGUQQUACCU#P'))
def test_fix_backbone(self): """Fixes backbone breaks.""" m = RnaModel(data_type='file', data=FIXABLE_BACKBONE) fix_backbone(m) self.assertEqual(m.get_sequence(), Sequence('ACUGUG'))
class ModelMinimization: """ Main class for minimizing models """ def __init__(self, options, temp_path): self.options = options # structure print 'Loading model from %s, chain %s'%(options.input_file, options.chain_name) self.model = load_model(options.input_file, options.chain_name) self.model_passive = None self.stem5, self.stem3 = None, None self.sequence_before = self.model.get_sequence() self.model_resnumbers = [] # parameters self.residues = None if options.residues: self.residues = options.residues.split('-') self.cycles = int(options.cycles) self.output_name = options.output_file self.modifications = [] self.restraints = [] self.mmtk_output_file = 'mmtk_output.pdb' self.temp_pdb_file = temp_path def model_to_tempfile(self): """writes model to temporary file.""" self.model.write_pdb_file(self.temp_pdb_file) self.model = None def tempfile_to_model(self): """Reads model from temporary file.""" self.model = load_model(self.temp_pdb_file, self.options.chain_name) def extract_region(self): self.model.renumber_chain() """Cuts out the residues for optimization and keeps the rest in memory.""" if self.residues: print '\nExtracting the region to be optimized (%s-%s) from the model.'%(self.residues[0], self.residues[1]) print '\t.. total residues in model : %4i'%len(self.model) self.model_passive = self.model.find_residues_not_in_range(self.residues[0], self.residues[1]) print '\t.. residues not participating in optimization : %4i (+2 for superposition afterwards)'%(len(self.model_passive)-2) print '\t '+','.join([r.identifier for r in self.model_passive]) self.model = RnaModel(None, None, self.options.chain_name, 'residues', self.model[self.residues[0]:self.residues[1]]) # memorize residue numbers because MMTK screws them self.model_resnumbers = [r.identifier for r in self.model] print '\t.. residues participating in optimization : %4i'%len(self.model) print '\t '+','.join([r.identifier for r in self.model]) # keeps duplicate versions of the residues indicated by self.residues, # so they can be superimposed later self.stem5, self.stem3 = self.model[self.residues[0]], self.model[self.residues[1]] else: self.struc_to_optimize = self.model def merge_region(self): """Merges the optimized residues with the memorized ones.""" residues = [r for r in self.model] if self.model_passive: # apply old residue numbers print '\nRestoring original numeration in the optimized region.' for num, resi in zip(self.model_resnumbers, residues): #print resi, num #self.model.renumber_residue(resi.identifier, num) resi.change_number(num) self.model = ModernaStructure('residues',residues) # do the superposition print '\nSuperimposing the optimized part onto the rest of the model.' all_atoms = self.model.get_all_atoms() sup = ModernaSuperimposer(moved_atoms = all_atoms) sup.get_atoms([self.stem5, self.stem3], BACKBONE_ATOMS, 'fixed') resi5, resi3 = self.model[self.residues[0]], self.model[self.residues[1]] sup.get_atoms([resi5, resi3], BACKBONE_ATOMS, 'moved') sup.superimpose() # merge residues print '\nMerging the optimized part with the rest of the model.' resi = [r for r in self.model] for r in self.model_passive: if r.identifier not in self.residues: resi.append(r) self.model = RnaModel(None, None, self.options.chain_name, 'residues', resi) def remove_modifications(self): """Memorizes modified nucleotides for later, and then removes them.""" print '\nRemoving modified bases from the model.' for resi in self.model.get_modified_residues(): resi=self.model[resi] modi = (resi.identifier, resi.long_abbrev) print '\t.. %s at position %s'%modi self.modifications.append(modi) self.model.remove_all_modifications() # check for O3 atoms for resi in self.model: if resi.child_dict.has_key(' O3P'): raise OptimizationError('O3P atoms cannot be handled by MMTK!') def change_atom_names(self, forth=False, back=False): """Replaces atom and residue names so that MMTK can iterpret them.""" print '\nReplacing names in temporary PDB file (%s)'%((forth and 'ModeRNA->MMTK') or (back and 'MMTK->ModeRNA')) if forth: nameset = FORTH_SET elif back: nameset = BACK_SET else: raise OptimizationError("Invalid options for changing atom names.") # replace residue and atom names out = [] for line in open(self.temp_pdb_file): if line.startswith('ATOM') or line.startswith('HETATM'): resiname = nameset.replace_residue_name(line[17:20]) atomname = nameset.replace_atom_name(line[12:16]) line = line[:12]+atomname+line[16:17]+resiname+line[20:] if len(line)>13 and line[13]!='H': # discard hydrogens out.append(line) open(self.temp_pdb_file, 'w').writelines(out) def create_restraints(self, chain): """If a residue range was specified, these residues are cut out, and """ if self.residues: print '\t.. building restraints' first_resi = chain[0] last_resi = chain[-1] # distances between the two terminal residues dist_po = (self.stem5['P'] - self.stem3["O3'"])/10.0 restraints = HarmonicDistanceRestraint(first_resi.phosphate.P, last_resi.sugar.O_3, dist_po, 10000.) dist_co = (self.stem5["O5'"] - self.stem3["O3'"])/10.0 restraints += HarmonicDistanceRestraint(first_resi.sugar.O_5, last_resi.sugar.C_3, dist_co, 10000.) dist_cc = (self.stem5["C5'"] - self.stem3["C4'"])/10.0 restraints += HarmonicDistanceRestraint(first_resi.sugar.C_5, last_resi.sugar.C_4, dist_cc, 10000.) # angles between the two terminal residues angle_cpo = calc_angle(self.stem5["C4'"].get_vector(), self.stem3["P"].get_vector(), self.stem3["O3'"].get_vector()) #angle_cpo = calc_angle(self.stem3["P"].coord-self.stem5["C4'"].coord, self.stem3["P"].coord-self.stem3["O3'"].coord) restraints += HarmonicAngleRestraint(first_resi.sugar.C_4, last_resi.phosphate.P, last_resi.sugar.O_3, angle_cpo, 100000.) angle_pco1 = calc_angle(self.stem5["P"].get_vector(), self.stem3["C4'"].get_vector(), self.stem3["O3'"].get_vector()) restraints += HarmonicAngleRestraint(first_resi.phosphate.P, last_resi.sugar.C_4, last_resi.sugar.O_3, angle_pco1, 10000.) angle_pco2 = calc_angle(self.stem5["P"].get_vector(), self.stem5["C4'"].get_vector(), self.stem3["O3'"].get_vector()) restraints += HarmonicAngleRestraint(first_resi.phosphate.P, first_resi.sugar.C_4, last_resi.sugar.O_3, angle_pco2, 10000.) angle_pcc = calc_angle(self.stem5["P"].get_vector(), self.stem5["C4'"].get_vector(), self.stem3["C4'"].get_vector()) restraints += HarmonicAngleRestraint(first_resi.phosphate.P, first_resi.sugar.C_4, last_resi.sugar.C_4, angle_pcc, 10000.) # torsion between the two terminal residues # THESE PRODUCE SEGMENTATION FAULTS - THE OTHERS MUST SUFFICE # restraints += HarmonicDihedralRestraint(first_resi.phosphate.P, first_resi.sugar.C_4, last_resi.phosphate.P, last_resi.sugar.C_4, 1.0, 10.) #restraints += HarmonicDihedralRestraint(first_resi.phosphate.P, first_resi.sugar.C_4, last_resi.sugar.C_4, last_resi.sugar.O_3, 0.0, 100000.) #restraints += HarmonicDihedralRestraint(first_resi.sugar.C_4, first_resi.sugar.O_3, last_resi.phosphate.P, last_resi.sugar.C_4, 0.0, 100000.) #restraints += HarmonicDihedralRestraint(first_resi.sugar.C_4, first_resi.sugar.O_3, last_resi.sugar.C_4, last_resi.sugar.O_3, 0.0, 100000.) return restraints def optimize(self): """Run the optimization with MMTK""" print '\n-------------------------------------------------------------------------------' print '\n MMTK Optimization starts...' print '\t.. building universe' configuration = PDBConfiguration(self.temp_pdb_file) # Construct the nucleotide chain object. This also constructs positions # for the missing hydrogens, using geometrical criteria. chain = configuration.createNucleotideChains()[0] universe = InfiniteUniverse() universe.addObject(chain) restraints = self.create_restraints(chain) # define force field print '\t.. setting up force field' if restraints: ff = Amber94ForceField() + restraints else: ff = Amber94ForceField() universe.setForceField(ff) # do the minimization print '\t.. starting minimization with %i cycles'%self.cycles minimizer = ConjugateGradientMinimizer(universe) minimizer(steps = self.cycles) # write the intermediate output print '\t.. writing MMTK output to %s'% self.temp_pdb_file if self.model_passive: print '\t (please note that MMTK applies a different numeration of residues.\n\t The original one will be restored in the final output).' universe.writeToFile(self.mmtk_output_file) open(self.temp_pdb_file, 'w').write(open(self.mmtk_output_file).read()) print '\n-------------------------------------------------------------------------------' def add_modifications(self): """Restores modifications on the model.""" print "\nAdding modifications back to the model:" for position, modif in self.modifications: print "\t.. adding %s in position %s"%(modif, position) self.model[position].add_modification(modif) # check if sequence stayed the same print '\nSequence before optimization' print self.sequence_before print 'Sequence after optimization' print self.model.get_sequence() def write_result(self): """Creates the output file.""" print "\nWriting final output to: %s"%self.output_name self.model.write_pdb_file(self.output_name)
class CommandTests(TestCase): """ Acceptance tests for all scripting commands in Moderna. The order of most function parameters follows the T.A.M. (template, alignment, model) paradigm: The first parameter of a function refers to the template or a part of a structure which is taken, the second to an alignment or residue name, the third to the model. """ def setUp(self): self.a = read_alignment(MINI_ALIGNMENT) self.a2 = read_alignment(MINI_ALIGNMENT_WITH_UNK) self.t = Template(MINI_TEMPLATE, seq=Sequence("GCGGAUUUALCUCAG")) self.m = RnaModel() def tearDown(self): self.a = None self.a2 = None self.t = None self.m = None def count_atoms(self, filename): # counts atoms in a PDB file atoms = 0 for l in open(filename): if l[:4] == 'ATOM': atoms += 1 return atoms #---------------------------------------------------------- def test_add_modification_in_model(self): """Add modification to a residue already in the model.""" copy_single_residue(self.t['5'], self.m) add_modification(self.m['5'], 'm1G') self.assertEqual(self.m.get_sequence(), Sequence('K')) def test_add_modification_and_copy(self): """Add modification and copy to model.""" add_modification(self.t['5'], 'm1G', self.m) self.assertEqual(self.m.get_sequence(), Sequence('K')) #---------------------------------------------------------- def test_add_all_modifications(self): """Add modifications from the alignment and copy.""" add_all_modifications(self.t, self.a, self.m) self.assertEqual(self.m.get_sequence(), Sequence('[_#P')) # KR: should the 'Y' in the loop be skipped because it is not there? # KR: should the residues be copied automatically? #---------------------------------------------------------- def test_add_pair_to_base(self): """ """ m = load_model(MINI_TEMPLATE) add_pair_to_base(m, '3', '20', Sequence('C')) self.assertEqual(m.get_sequence(), Sequence('GCGGAUUUALCUCAG_C')) self.assertEqual(m.get_secstruc(), '..(............)') #---------------------------------------------------------- def test_apply_alignment(self): """Do everything except inserting indels.""" apply_alignment(self.t, self.a, self.m) self.assertEqual(self.m.get_sequence(), Sequence('ACUGUA[UACCU#PG')) #---------------------------------------------------------- def test_apply_all_indels(self): """Do inserting indels only.""" self.m.template = self.t copy_some_residues(self.t['1':'15'], self.m) apply_all_indels(self.a, self.m) fix_backbone(self.m) self.assertEqual(self.m.get_sequence(), Sequence('GCGGUGAYUAUUALCUCAG')) def test_analyze_geometry(self): result = analyze_geometry(self.t) self.assertTrue(isinstance(result, GeometryAnalyzer)) #---------------------------------------------------------- def test_change_sequence(self): """Changes the entire sequence of a structure.""" m = load_model(MINI_TEMPLATE) change_sequence(m, "AGCU!#7/PYLLAAA") self.assertEqual(m.get_sequence(), Sequence("AGCU!#7/PYLLAAA")) #---------------------------------------------------------- def test_copy_identical_residues_default(self): """Copy all residues that are the same,including modifications.""" copy_identical_residues(self.t, self.a, self.m) self.assertEqual(self.m.get_sequence(), Sequence('C_G_UA_CU_G')) def test_copy_identical_residues_no_modif(self): """Copy all residues that are the same, excluding modifications.""" copy_identical_residues(self.t, self.a, self.m, modifications=False) self.assertEqual(self.m.get_sequence(), Sequence('C_G_UA_CU_G')) #---------------------------------------------------------- def test_copy_single_residue(self): """Copy residue from template.""" copy_single_residue(self.t['5'], self.m) self.assertEqual(self.m.get_sequence(), Sequence('A')) def test_copy_single_residue_number(self): """Copy residue, allow renumbering.""" copy_single_residue(self.t['5'], self.m, '6') self.assertEqual(self.m.get_sequence(), Sequence('A')) self.assertEqual(self.m['6'].short_abbrev, 'A') def test_copy_single_residue_strict(self): """Copy residue, but strict option rejects ... .""" copy_single_residue(self.t['5'], self.m, strict=True) self.assertEqual(self.m.get_sequence(), Sequence('A')) # KR: What should the strict option do? #---------------------------------------------------------- def test_copy_some_residues(self): """Copy more than one residue from template.""" copy_some_residues([self.t['5'], self.t['7']], self.m) self.assertEqual(self.m.get_sequence(), Sequence('A_U')) def test_copy_some_residues_range(self): """Copy more than one residue, allow range operator.""" copy_some_residues(self.t['5':'8'], self.m) self.assertEqual(self.m.get_sequence(), Sequence('AUUU')) def test_copy_some_residues_into_blank(self): """Should copy residues into an empty model without alignment""" t = load_template(RNA_1C0A, 'B') m = RnaModel() copy_some_residues(t['31':'35'] + t['38':'42'], m) self.assertEqual(len(m), 10) def test_copy_some_residues_number(self): """Copy more than one residue from template.""" copy_some_residues([self.t['5'], self.t['7']], self.m, ['4', '7A']) self.assertEqual(self.m.get_sequence(), Sequence('A_U')) self.assertEqual(self.m['4'].short_abbrev, 'A') self.assertEqual(self.m['7A'].short_abbrev, 'U') def test_copy_some_residues_strict(self): """Copy more than one residue, but strict option rejects ...""" copy_some_residues(self.t['5':'8'], self.m, strict=True) self.assertEqual(self.m.get_sequence(), Sequence('AUUU')) #---------------------------------------------------------- def test_create_fragment(self): """Loads a fragment.""" f = create_fragment(HELIX, anchor5=self.t['3'], anchor3=self.t['9']) self.assertEqual( f.struc.get_sequence(), Sequence( 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA_UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU' )) #---------------------------------------------------------- def test_create_model_empty(self): """No options result in an empty model.""" m = create_model() self.assertEqual(m.get_sequence(), Sequence('')) def test_create_model_ali(self): """Apply the alignment and insert indels automatically.""" m = create_model(self.t, self.a) self.assertEqual(m.get_sequence(), Sequence('ACUGUGAYUA[UACCU#PG')) def test_create_model_ali2(self): """Apply the alignment and insert indels automatically.""" m = create_model(self.t, self.a2) self.assertEqual(m.get_sequence(), Sequence('..CUGUQQUACCU#P')) def test_create_model_ali_improve(self): """Correct small errors in the alignment automatically.""" ali = read_alignment(MINI_ALIGNMENT_INACCURATE) m = create_model(self.t, ali) self.assertEqual(m.get_sequence(), Sequence('ACUGUA7UACCUAPG')) def test_create_model_incorrect(self): """Giving an improper template seq should raise an exception.""" # should also create log message. a = read_alignment(DNA_ALIGNMENT) self.assertRaises(ModernaError, create_model, self.t, a) #---------------------------------------------------------- def test_clean_structure(self): m = load_model(NASTY_PDB, 'A') result = clean_structure(m) self.assertTrue(result) self.assertFalse(re.search('Water residues present', str(result))) #---------------------------------------------------------- def test_delete_residue(self): """Removes a single residue completely.""" copy_some_residues(self.t['1':'4'], self.m) delete_residue('3', self.m) self.assertEqual(self.m.get_sequence(), Sequence('GC_G')) #---------------------------------------------------------- def test_examine_structure(self): m = load_model(NASTY_PDB, 'A') result = examine_structure(m) self.assertTrue(result) self.assertTrue(re.search('Water residues present', str(result))) #---------------------------------------------------------- def test_exchange_single_base_default(self): """Exchange base already in the model.""" copy_some_residues(self.t['6':'11'], self.m) exchange_single_base(self.m['7'], 'C') exchange_single_base(self.m['10'], 'A') self.assertEqual(self.m.get_sequence(), Sequence('UCUAAC')) def test_exchange_single_base_and_copy(self): """Exchange base and copy to the model.""" exchange_single_base(self.t['7'], 'C', self.m) exchange_single_base(self.t['10'], 'A', self.m) self.assertEqual(self.m.get_sequence(), Sequence('C_A')) #---------------------------------------------------------- def test_exchange_some_bases_default(self): """Exchange some bases already in the model.""" copy_some_residues(self.t['6':'11'], self.m) exchange_some_bases([self.m['7'], self.m['10']], 'CA') self.assertEqual(self.m.get_sequence(), Sequence('UCUAAC')) def test_exchange_some_bases_range(self): """Exchange some bases, apply range.""" copy_some_residues(self.t['6':'11'], self.m) exchange_some_bases(self.m['7':'9'], 'CAG') self.assertEqual(self.m.get_sequence(), Sequence('UCAGLC')) def test_exchange_some_bases_and_copy(self): """Exchange some bases and copy from template.""" exchange_some_bases(self.t['7':'9'], 'CGA', self.m) self.assertEqual(self.m.get_sequence(), Sequence('CGA')) def test_exchange_some_bases_and_copy_list(self): """Exchange some bases and copy from template.""" exchange_some_bases([self.t['7'], self.t['9']], 'CA', self.m) self.assertEqual(self.m.get_sequence(), Sequence('C_A')) #---------------------------------------------------------- def test_exchange_mismatches(self): """Exchanges all standard base mismatches and copies.""" exchange_mismatches(self.t, self.a, self.m) self.assertEqual(self.m.get_sequence(), Sequence('A_U_UA')) #---------------------------------------------------------- def test_extend_helix(self): m = load_model(RNA_1EHZ, 'A') extend_helix(m, '3', '70', Sequence("AGUC_GACU")) self.assertEqual( m.get_sequence(), Sequence( 'GCGAGUCGAUUUALCUCAGDDGGGAGAGCRCCAGABU#AAYAP?UGGAG7UC?UGUGTPCG"UCCACAGAAUUGACUCGCACCA' )) self.assertEqual( m.get_secstruc(), '(((((((((((..((((........)))).((((.........)))).....(((((.......))))))))))))))))....' ) #---------------------------------------------------------- def test_find_clashes(self): """Finds clashes.""" clashes = find_clashes(self.t) self.assertFalse(clashes) def test_find_clashes_empty(self): """Finding clashes works with empty model.""" clashes = find_clashes(self.m) self.assertFalse(clashes) def test_find_clashes_positive(self): """Finding clashes returns a list of clashing residue pairs.""" m = load_model(CLASHING_STRUCTURE) clashes = find_clashes(m) self.assertTrue(clashes) # check return type self.assertEqual(len(clashes), 1) self.assertEqual(clashes[0][0].identifier, '3') self.assertEqual(clashes[0][1].identifier, '4') def test_find_clashes_list(self): """Finding clashes works with a list as input.""" clashes = find_clashes([self.t['3'], self.t['6']]) self.assertFalse(clashes) def test_find_clashes_two_structures(self): """Finding clashes works with residues from two structures.""" copy_single_residue(self.t['3'], self.m) #clashes = find_clashes(self.t['1':'10']+ [self.m['3']]) clashes = find_clashes([self.t['3'], self.m['3']]) self.assertTrue(clashes) # check different expressions. clashes = find_clashes([self.t['3'], self.m['3']]) self.assertTrue(clashes) def test_find_clashes_two_structures_negative(self): """Make sure that two distinct residues do not collide.""" copy_single_residue(self.t['3'], self.m) clashes = find_clashes([self.t['7'], self.m['3']]) self.assertFalse(clashes) #---------------------------------------------------------- def test_find_modifications(self): """Finding modifications returns a dictionary.""" mods = find_modifications(self.t) self.assertTrue('10' in mods) self.assertEqual(mods['10'].long_abbrev, 'm2G') # KR: Check return type with MM def test_find_modifications_empty(self): """Finding modifications returns a dictionary.""" mods = find_modifications(self.m) self.assertEqual(mods, {}) # KR: Check return type with MM def test_find_modifications_advanced(self): """ Tests for the modification recognizer: take 1ehz, run the topology matcher on it, and compare the results to a manually entered list of modifications. """ # check the modifications in 1ehz ehz_modifications = (('10', 'L'), ('16', 'D'), ('17', 'D'), ('26', 'R'), ('32', 'B'), ('34', '#'), ('37', 'Y'), ('39', 'P'), ('40', '?'), ('46', '7'), ('49', '?'), ('54', 'T'), ('55', 'P'), ('58', '"')) t = load_template(RNA_1EHZ, 'A') modifications = find_modifications(t) self.assertEqual(len(modifications), len(ehz_modifications)) keys = list(modifications.keys()) keys.sort() for i in range(len(ehz_modifications)): self.assertEqual(keys[i], ehz_modifications[i][0]) self.assertEqual(modifications[keys[i]].identifier, ehz_modifications[i][0]) self.assertEqual(modifications[keys[i]].short_abbrev, ehz_modifications[i][1]) #---------------------------------------------------------- def test_fix_backbone(self): """Fixes backbone breaks.""" m = RnaModel(data_type='file', data=FIXABLE_BACKBONE) fix_backbone(m) self.assertEqual(m.get_sequence(), Sequence('ACUGUG')) def test_fix_backbone_residues(self): """Accepts two residue numbers as parameters.""" m = RnaModel(data_type='file', data=FIXABLE_BACKBONE) fix_backbone(m, '4', '5') self.assertEqual(m.get_sequence(), Sequence('ACUGUG')) #---------------------------------------------------------- def test_find_fragment(self): m = load_model(RNA_HAIRPIN, 'D') candidates = find_fragment(m, '30', '40', Sequence("AGCUAGCU")) self.assertTrue(len(candidates) > 0) self.assertTrue( isinstance(candidates[0].fragment_instance, ModernaFragment)) def test_find_fragment_secstruc(self): m = load_model(RNA_HAIRPIN, 'D') candidates = find_fragment(m, '30', '40', Sequence("AGCUAGCU"), secstruc='((....))') self.assertTrue(len(candidates) > 0) frag = candidates[0].fragment_instance finsert = FragmentInserter() finsert.prepare_fragment(frag, m) self.assertEqual(frag.struc.get_secstruc(), '(((....)))') def test_insert_fragment_cand(self): m = load_model(RNA_HAIRPIN, 'D') candidates = find_fragment(m, '30', '40', Sequence("AGCUAGCU")) insert_fragment(m, candidates[0]) self.assertEqual(m.get_sequence(), Sequence("CUGAGCUAGCUC")) def test_insert_fragment_cand_secstruc(self): m = load_model(RNA_HAIRPIN, 'D') #TODO: try this example candidates = find_fragment(m, '30', '40', Sequence('ACCGCCCGGU'), 20, secstruc='(((....)))') insert_fragment(m, candidates[0]) self.assertEqual(m.get_sequence(), Sequence("CUGACCGCCCGGUC")) self.assertEqual(m.get_secstruc(), "..((((....))))") def test_insert_two_strand_fragment(self): m = load_model(RNA_HAIRPIN, 'D') insert_two_strand_fragment(m, '30', '40', '31', '39', '195', '219', '196', '217', BULGE_MOTIF) fix_backbone(m) self.assertEqual(m.get_sequence(), Sequence("CUGCCUQUC/CGGC")) self.assertEqual(m.get_secstruc(), "..((.......).)") #---------------------------------------------------------- def test_get_base_pairs(self): result = get_base_pairs(self.t) self.assertEqual(str(result['8']), '[8 WH 14]') def test_get_sequence(self): """Returning the entire sequence of a structure object.""" seq = get_sequence(self.t) self.assertEqual(seq, Sequence('GCGGAUUUALCUCAG')) #TODO: Add test for discontinuous and strangely numbered struc. def test_get_sequence_chain(self): """Template structures should return their own sequence.""" t = load_template(MINI_TEMPLATE, MINI_TEMPLATE_CHAIN_NAME) seq = get_sequence(t) self.assertEqual(seq, Sequence("GCGGAUUUALCUCAG")) def test_get_secstruc(self): """Get secondary structure in dot-bracket format.""" h = load_template(RNA_HAIRPIN, 'D') ss = get_secstruc(h) self.assertEqual(ss, "..((.......))") def test_get_stacking(self): result = get_stacking(self.t) self.assertEqual(len(result), 9) self.assertEqual(result[0], ('1', '2', '>>')) #---------------------------------------------------------- def test_load_alignment(self): """Return alignment loaded from fasta file.""" a = load_alignment(MINI_ALIGNMENT) self.assertTrue(isinstance(a, RNAAlignment)) self.assertEqual(a.aligned_template_seq, Sequence('GCGGA----UUUALCUCAG')) self.assertEqual(a.aligned_target_seq, Sequence('ACUGUGAYUA[UACCU#PG')) #---------------------------------------------------------- def test_load_template(self): """Return template loaded from PDB file.""" t = load_template(MINI_TEMPLATE) self.assertTrue(isinstance(t, Template)) self.assertEqual(t.get_sequence(), Sequence('GCGGAUUUALCUCAG')) #---------------------------------------------------------- def test_load_model(self): """Return model loaded from PDB file.""" m = load_model(MINI_TEMPLATE) self.assertTrue(isinstance(m, RnaModel)) self.assertEqual(m.get_sequence(), Sequence('GCGGAUUUALCUCAG')) #---------------------------------------------------------- def test_match_template_with_alignment(self): """Check if template sequence and alignment match.""" # positive example self.assertTrue(match_template_with_alignment(self.t, self.a)) # negative example t = load_template(CLASHING_STRUCTURE) self.assertFalse(match_template_with_alignment(t, self.a)) #---------------------------------------------------------- def test_match_model_with_alignment(self): """Check if model sequence and alignment match.""" # negative example m = create_model() self.assertFalse(match_alignment_with_model(self.a, m)) # positive example m = create_model(self.t, self.a) self.assertTrue(match_alignment_with_model(self.a, m)) #---------------------------------------------------------- def test_rotate_chi(self): """Rotates chi angle of a single base.""" copy_some_residues(self.t['3':'5'], self.m) coord_before = self.m['4']['C5'].coord rotate_chi(self.m['4'], 90) coord_after = self.m['4']['C5'].coord self.assertNotEqual(list(coord_after), list(coord_before)) #---------------------------------------------------------- def test_remove_all_modifications(self): """Removes all modifications from a structure.""" copy_some_residues(self.t['1':'15'], self.m) remove_all_modifications(self.m) self.assertEqual(self.m.get_sequence(), Sequence('GCGGAUUUAGCUCAG')) def test_remove_modifications_advanced(self): """ Tests for modification removal: take 1ehz, remove all modifications. Run the modification recognizer. Make sure that no modifications are found, but the correct number of normal bases instead. """ m = load_model(MINI_TEMPLATE, MINI_TEMPLATE_CHAIN_NAME) remove_all_modifications(m) modifications = find_modifications(m) self.assertEqual(modifications, {}) self.assertEqual(len(m), 15) #---------------------------------------------------------- def test_remove_modification_default(self): """Removes a modification from the model.""" copy_some_residues(self.t['1':'15'], self.m) remove_modification(self.m['10']) self.assertEqual(self.m.get_sequence(), Sequence('GCGGAUUUAGCUCAG')) def test_remove_modification_empty(self): """Raises Exception if base is not modified.""" copy_some_residues(self.t['1':'15'], self.m) self.assertRaises(ModernaError, remove_modification, self.m['11']) def test_remove_modification_and_copy(self): """Removes a modification, copies to model.""" remove_modification(self.t['10'], self.m) self.assertEqual(self.m.get_sequence(), Sequence('G')) #---------------------------------------------------------- def test_remove_mismatching_modifications(self): """Removes modifications that are no matches in the alignment.""" remove_mismatching_modifications(self.t, self.a, self.m) # KR: !!! maybe apply_mismatching_modifications is better because of copy. self.assertEqual(self.m.get_sequence(), Sequence('C')) # KR: could add more sophisticated example. #---------------------------------------------------------- def test_renumber_chain(self): copy_some_residues(self.t['1':'15'], self.m) renumber_chain(self.m, '4') sumnum = sum([int(r.identifier) for r in self.m]) self.assertEqual(sumnum, 165) #---------------------------------------------------------- def test_shrink_helix(self): m = load_model(RNA_1EHZ, 'A') shrink_helix(m, '3', '70', '7', '66') self.assertEqual( m.get_sequence(), Sequence( 'GCGUUALCUCAGDDGGGAGAGCRCCAGABU#AAYAP?UGGAG7UC?UGUGTPCG"UCCACAGACGCACCA' )) self.assertEqual( m.get_secstruc(), '((((..((((........)))).((((.........)))).....(((((.......)))))))))....' ) #---------------------------------------------------------- def test_write_model(self): """Creates a PDB file.""" copy_some_residues(self.t['1':'5'], self.m) if os.access(OUTPUT, os.F_OK): os.remove(OUTPUT) write_model(self.m, OUTPUT) self.assertTrue(os.access(OUTPUT, os.F_OK)) # re-read new = load_model(OUTPUT) self.assertEqual(new.get_sequence(), Sequence('GCGGA')) # test writing a template t = load_template(MINI_TEMPLATE) write_model(t, OUTPUT) new = load_model(OUTPUT) self.assertEqual(new.get_sequence(), Sequence('GCGGAUUUALCUCAG')) #---------------------------------------------------------- def remove_frag_cand_files(self, testout): """Remove files with fragment candidates.""" if os.access(testout, os.F_OK): os.remove(testout) if os.access(testout[:-4], os.F_OK): for fn in os.listdir(testout[:-4]): os.remove(testout[:-4] + os.sep + fn) else: os.mkdir(testout[:-4]) def test_write_fragment_candidates(self): """Fragment candidate file should be created.""" testout = 'test_data/test_output.pdb' self.remove_frag_cand_files(testout) copy_some_residues(self.t['1':'10'], self.m) candidates = find_fragment(self.m, '2', '8', Sequence('AGCU#'), 20) write_fragment_candidates(candidates, testout[:-4]) self.assertTrue(os.access(testout[:-4], os.F_OK)) #---------------------------------------------------------- def test_write_fragment_candidates_contents(self): """Fragment candidate file should contain the right number of models.""" testout = 'test_data/test_output.pdb' self.remove_frag_cand_files(testout) copy_some_residues(self.t['1':'10'], self.m) candidates = find_fragment(self.m, '2', '8', Sequence('AGCU#'), 7) write_fragment_candidates(candidates, testout[:-4]) for i, fn in enumerate(os.listdir(testout[:-4])): if not fn.endswith('.pdb'): continue p = PDBParser() struc = p.get_structure('cand', testout[:-4] + os.sep + fn) self.assertEqual(len(struc.child_list), 1) self.assertEqual(i, 7) #---------------------------------------------------------- def test_write_secstruc(self): """Creates a Vienna file.""" if os.access(OUTPUT, os.F_OK): os.remove(OUTPUT) write_secstruc(self.t, OUTPUT) self.assertTrue(os.access(OUTPUT, os.F_OK)) r = open(OUTPUT).readlines() self.assertTrue(re.search("\A>", r[0])) self.assertTrue(re.search("\AGCGGAUUUALCUCAG\n", r[1])) self.assertTrue(re.search("\A\.{15}\Z", r[2])) os.remove(OUTPUT) #---------------------------------------------------------- # # SOME OTHER TESTS # def test_first_level(self): """only checks whether a pdb file was created.""" t = load_template(MINI_TEMPLATE, MINI_TEMPLATE_CHAIN_NAME) a = load_alignment(MINI_ALIGNMENT) m = create_model(t, a) if os.access(OUTPUT, os.F_OK): os.remove(OUTPUT) write_model(m, OUTPUT) self.assertTrue(os.access(OUTPUT, os.F_OK)) os.unlink(OUTPUT) def test_add_custom_fragment(self): """Fragments loaded from a file should be inserted.""" t = load_template(RNA_1C0A, 'B') m = create_model() copy_some_residues(t['31':'35'] + t['38':'42'], m) f = create_fragment(FRAGMENT1, anchor5=m['35'], anchor3=m['38'], chain_name='A', sequence=None) m.insert_fragment(f) self.assertTrue(m['35A'] and m['35B']) #---------------------------------------------------------- def test_read_write(self): """ Tests for file processing:take 1ehz and 2-3 other PDB files. Write it to a file. Read it again. Check that the structure contains the right number of atoms, and that the added residues are in the right position. """ m = load_model(RNA_1EHZ) atoms_before = self.count_atoms(RNA_1EHZ) if os.access(OUTPUT, os.F_OK): os.remove(OUTPUT) write_model(m, OUTPUT) self.assertTrue(os.access(OUTPUT, os.F_OK)) atoms_after = self.count_atoms(OUTPUT) self.assertEqual(atoms_after, atoms_before) os.unlink(OUTPUT) def test_build_model_2bte_B(self): """ Tests building model for 2j00_W on template 2bte_B.pdb""" ali_string = """> 2j00_W.pdb CP000026.1/4316393-4316321 GC-C--C--G---G--A-------U----A---G---C---U-C--AGU--------CGGU----------A-GA-G--C-------A----G---G-G----G-A--------U----------U-----G--------A-----------A----------A------------A-------------U---C--C--C-CGU--------------------------------------------------G--UC-C-U--U---G-G--U---U-C-G-----AU-----------U-----C---C--G---A---G--------U--C---C--G--G-GCA-CCA > 2bte_B.pdb GC-C--G--G---G--G-------U----G---G---C---G-G--A-AU-------GGGU----------A-GACG--C-------G----C---A-U----G-A--------C_---------A-----U--------C-----------A----------U------------G-------------U---G--C--G-CAA--------------------------------------------------G-CGU-G-C--G---G-G--U---U-C-A-----AG-----------U-----C---C--C---G---C--------C--C---C--C--G-GCA-CCA""" ali = read_alignment(ali_string) t = load_template(RNA_2BTE, 'B') m = create_model(t, ali, 'B') def test_build_model_1exd_B(self): """Tests building model for 2tra_A on template 1exd_B.pdb""" ali_string = """> 2tra_A UC-C--G--U---G--A-------U----A---G---U---U-P--AAD---------GGD---------CA-GA-A--U-------G----G---G-C----G-C--------P----------U-----G--------U-----------C----------K------------C-------------G---U--G--C-CAG--------------------------------------------------A---U-?-G--G---G-G--T ---P-C-A-----AU-----------U-----C---C--C---C---G--------U--C---G--C--G-GAG-C-- > 1ehd_B.pdb -G-G--G--G---U--A-------U----C---G---C---C-A--AGC---------GGU----------A-AG-G--C-------A----C---C-G----G-A--------U----------U-----C--------U-----------G----------A------------U-------------U---C--C--G-G-A--------------------------------------------------G--GU-C-G--A---G-G--U ---U-C-G-----AA-----------U-----C---C--U---C---G--------U--A---C--C--C-CAG-CCA""" ali = read_alignment(ali_string) t = load_template(RNA_1EXD, 'B') m = create_model(t, ali, 'B') def test_build_model_1efw_D(self): """ Tests building model for 1ehz_A on template 1efw_D. Should work even when 50 fragment candidates are checked""" ali_string = """> 1ehz_A.pdb M14856.1/1-73 GC-G--G--A---U--U-------U----A---L---C---U-C--AGD--------DGGG----------A-GA-G--C-------R----C---C-A----G-A--------B----------U-----#--------A-----------A----------Y------------A-------------P---?--U--G-GAG--------------------------------------------------7--UC-?-U--G---U-G--T ---P-C-G-----"U-----------C-----C---A--C---A---G--------A--A---U--U--C-GCA-CCA > 1efw_D.pdb GG-A--G--C---G--G-------4----A---G---U---U-C--AGD--------CGGD---------DA-GA-A--U-------A----C---C-U----G-C--------C----------U-----Q--------U-----------C----------/------------C-------------G---C--A--G-GGG--------------------------------------------------7--UC-G-C--G---G-G--018U---P-C-G-----AG-----------U-----C---C--C---G---P--------C--C---G--U--U-CC-----""" ali = read_alignment(ali_string) t = load_template(RNA_1EFW, 'D') m = create_model(t, ali, 'D') if os.access(OUTPUT, os.F_OK): os.remove(OUTPUT) write_model(m, OUTPUT) self.assertTrue(os.access(OUTPUT, os.F_OK))