Back to index

python-biopython  1.60
test_SeqRecord.py
Go to the documentation of this file.
00001 # Copyright 2009 by Peter Cock.  All rights reserved.
00002 # This code is part of the Biopython distribution and governed by its
00003 # license.  Please see the LICENSE file that should have been included
00004 # as part of this package.
00005 
00006 """SeqFeature related tests for SeqRecord objects from Bio.SeqIO.
00007 
00008 Initially this takes matched tests of GenBank and FASTA files from the NCBI
00009 and confirms they are consistent using our different parsers.
00010 """
00011 import unittest
00012 from Bio import SeqIO
00013 from Bio.Alphabet import generic_dna, generic_rna, generic_protein
00014 from Bio.Seq import Seq
00015 from Bio.SeqRecord import SeqRecord
00016 from Bio.SeqFeature import SeqFeature, FeatureLocation, ExactPosition
00017 from Bio.SeqFeature import WithinPosition, BeforePosition, AfterPosition, OneOfPosition
00018 
00019 class SeqRecordCreation(unittest.TestCase):
00020     """Test basic creation of SeqRecords."""
00021     def test_annotations(self):
00022         """Pass in annotations to SeqRecords"""
00023         rec = SeqRecord(Seq("ACGT", generic_dna),
00024                         id="Test", name="Test", description="Test")
00025         self.assertEqual(rec.annotations, {})
00026         rec = SeqRecord(Seq("ACGT", generic_dna),
00027                         id="Test", name="Test", description="Test",
00028                         annotations={"test" : ["a test"]})
00029         self.assertEqual(rec.annotations["test"], ["a test"])
00030 
00031     def test_letter_annotations(self):
00032         """Pass in letter annotations to SeqRecords"""
00033         rec = SeqRecord(Seq("ACGT", generic_dna),
00034                         id="Test", name="Test", description="Test")
00035         self.assertEqual(rec.annotations, {})
00036         rec = SeqRecord(Seq("ACGT", generic_dna),
00037                         id="Test", name="Test", description="Test",
00038                         letter_annotations={"test" : [1, 2, 3, 4]})
00039         self.assertEqual(rec.letter_annotations["test"], [1, 2, 3, 4])
00040         #Now try modifying it to a bad value...
00041         try:
00042             rec.letter_annotations["bad"] = "abc"
00043             self.assertTrue(False, "Adding a bad letter_annotation should fail!")
00044         except (TypeError, ValueError), e:
00045             pass
00046         #Now try setting it afterwards to a bad value...
00047         rec = SeqRecord(Seq("ACGT", generic_dna),
00048                         id="Test", name="Test", description="Test")
00049         try:
00050             rec.letter_annotations={"test" : [1, 2, 3]}
00051             self.assertTrue(False, "Changing to bad letter_annotations should fail!")
00052         except (TypeError, ValueError), e:
00053             pass
00054         #Now try setting it at creation time to a bad value...
00055         try:
00056             rec = SeqRecord(Seq("ACGT", generic_dna),
00057                             id="Test", name="Test", description="Test",
00058                             letter_annotations={"test" : [1, 2, 3]})
00059             self.assertTrue(False, "Wrong length letter_annotations should fail!")
00060         except (TypeError, ValueError), e:
00061             pass
00062 
00063 class SeqRecordMethods(unittest.TestCase):
00064     """Test SeqRecord methods."""
00065 
00066     def setUp(self) :
00067         f0 = SeqFeature(FeatureLocation(0,26), type="source",
00068                         qualifiers={"mol_type":["fake protein"]})
00069         f1 = SeqFeature(FeatureLocation(0,ExactPosition(10)))
00070         f2 = SeqFeature(FeatureLocation(WithinPosition(12, left=12,right=15),BeforePosition(22)))
00071         f3 = SeqFeature(FeatureLocation(AfterPosition(16),
00072                                         OneOfPosition(26, [ExactPosition(25),AfterPosition(26)])))
00073         self.record = SeqRecord(Seq("ABCDEFGHIJKLMNOPQRSTUVWZYX", generic_protein),
00074                                 id="TestID", name="TestName", description="TestDescr",
00075                                 dbxrefs=["TestXRef"], annotations={"k":"v"},
00076                                 letter_annotations = {"fake":"X"*26},
00077                                 features = [f0,f1,f2,f3])
00078 
00079     def test_slice_variantes(self):
00080         """Simple slices using different start/end values"""
00081         for start in range(-30,30)+[None] :
00082             for end in range(-30,30)+[None] :
00083                 if start is None and end is None : continue
00084                 rec = self.record[start:end]
00085                 seq = self.record.seq[start:end]
00086                 seq_str = str(self.record.seq)[start:end]
00087                 self.assertEqual(seq_str, str(seq))
00088                 self.assertEqual(seq_str, str(rec.seq))
00089                 self.assertEqual("X"*len(seq_str), rec.letter_annotations["fake"])
00090 
00091     def test_slice_simple(self):
00092         """Simple slice"""
00093         rec = self.record
00094         self.assertEqual(len(rec), 26)
00095         left = rec[:10]
00096         self.assertEqual(str(left.seq), str(rec.seq[:10]))
00097         right = rec[-10:]
00098         self.assertEqual(str(right.seq), str(rec.seq[-10:]))
00099         mid = rec[12:22]
00100         self.assertEqual(str(mid.seq), str(rec.seq[12:22]))
00101         for sub in [left, right, mid] :
00102             self.assertEqual(len(sub), 10)
00103             self.assertEqual(sub.id, "TestID")
00104             self.assertEqual(sub.name, "TestName")
00105             self.assertEqual(sub.description, "TestDescr")
00106             self.assertEqual(sub.letter_annotations, {"fake":"X"*10})
00107             self.assertEqual(sub.dbxrefs, []) # May change this...
00108             self.assertEqual(sub.annotations, {}) # May change this...
00109             self.assertEqual(len(sub.features), 1)
00110             #By construction, each feature matches the full sliced region:
00111             self.assertEqual(str(sub.features[0].extract(sub.seq)), str(sub.seq))
00112             self.assertEqual(sub.features[0].extract(str(sub.seq)), str(sub.seq))
00113 
00114     def test_slice_zero(self):
00115         """Zero slice"""
00116         rec = self.record
00117         self.assertEqual(len(rec), 26)
00118         self.assertEqual(len(rec[2:-2]), 22)
00119         self.assertEqual(len(rec[5:2]), 0)
00120         self.assertEqual(len(rec[5:2][2:-2]), 0)
00121 
00122     def test_add_simple(self):
00123         """Simple addition"""
00124         rec = self.record + self.record
00125         self.assertEqual(len(rec), 52)
00126         self.assertEqual(rec.id, "TestID")
00127         self.assertEqual(rec.name, "TestName")
00128         self.assertEqual(rec.description, "TestDescr")
00129         self.assertEqual(rec.dbxrefs, ["TestXRef"])
00130         self.assertEqual(rec.annotations, {"k":"v"})
00131         self.assertEqual(rec.letter_annotations, {"fake":"X"*52})
00132         self.assertEqual(len(rec.features), 2*len(self.record.features))
00133 
00134     def test_add_seq(self):
00135         """Simple addition of Seq or string"""
00136         for other in [Seq("BIO"), "BIO"] :
00137             rec = self.record + other # will use SeqRecord's __add__ method
00138             self.assertEqual(len(rec), 26+3)
00139             self.assertEqual(str(rec.seq), str(self.record.seq)+"BIO")
00140             self.assertEqual(rec.id, "TestID")
00141             self.assertEqual(rec.name, "TestName")
00142             self.assertEqual(rec.description, "TestDescr")
00143             self.assertEqual(rec.dbxrefs, ["TestXRef"])
00144             self.assertEqual(rec.annotations, {"k":"v"})
00145             self.assertEqual(rec.letter_annotations, {})
00146             self.assertEqual(len(rec.features), len(self.record.features))
00147             self.assertEqual(rec.features[0].type, "source")
00148             self.assertEqual(rec.features[0].location.nofuzzy_start, 0)
00149             self.assertEqual(rec.features[0].location.nofuzzy_end, 26) #not +3
00150 
00151     def test_add_seqrecord(self):
00152         """Simple left addition of SeqRecord from genbank file."""
00153         other = SeqIO.read("GenBank/dbsource_wrap.gb", "gb")
00154         other.dbxrefs = ["dummy"]
00155         rec = self.record + other
00156         self.assertEqual(len(rec), len(self.record)+len(other))
00157         self.assertEqual(str(rec.seq), str(self.record.seq)+str(other.seq))
00158         self.assertEqual(rec.id, "<unknown id>")
00159         self.assertEqual(rec.name, "<unknown name>")
00160         self.assertEqual(rec.description, "<unknown description>")
00161         self.assertEqual(rec.dbxrefs, ["TestXRef", "dummy"])
00162         self.assertEqual(len(rec.annotations), 0)
00163         self.assertEqual(len(rec.letter_annotations),0)
00164         self.assertEqual(len(rec.features),
00165                          len(self.record.features) + len(other.features))
00166         self.assertEqual(rec.features[0].type, "source")
00167         self.assertEqual(rec.features[0].location.nofuzzy_start, 0)
00168         self.assertEqual(rec.features[0].location.nofuzzy_end, len(self.record)) #not +3
00169         i = len(self.record.features)
00170         self.assertEqual(rec.features[i].type, "source")
00171         self.assertEqual(rec.features[i].location.nofuzzy_start, len(self.record))
00172         self.assertEqual(rec.features[i].location.nofuzzy_end, len(rec))
00173 
00174     def test_add_seq_left(self):
00175         """Simple left addition of Seq or string"""
00176         for other in [Seq("BIO"), "BIO"] :
00177             rec = other + self.record # will use SeqRecord's __radd__ method
00178             self.assertEqual(len(rec), 26+3)
00179             self.assertEqual(str(rec.seq), "BIO"+str(self.record.seq))
00180             self.assertEqual(rec.id, "TestID")
00181             self.assertEqual(rec.name, "TestName")
00182             self.assertEqual(rec.description, "TestDescr")
00183             self.assertEqual(rec.dbxrefs, ["TestXRef"])
00184             self.assertEqual(rec.annotations, {"k":"v"})
00185             self.assertEqual(rec.letter_annotations, {})
00186             self.assertEqual(len(rec.features), len(self.record.features))
00187             self.assertEqual(rec.features[0].type, "source")
00188             self.assertEqual(rec.features[0].location.nofuzzy_start, 3)
00189             self.assertEqual(rec.features[0].location.nofuzzy_end, 26+3)
00190             
00191     def test_slice_add_simple(self):
00192         """Simple slice and add"""
00193         for cut in range(27) :
00194             rec = self.record[:cut] + self.record[cut:]
00195             self.assertEqual(str(rec.seq), str(self.record.seq))
00196             self.assertEqual(len(rec), 26)
00197             self.assertEqual(rec.id, "TestID")
00198             self.assertEqual(rec.name, "TestName")
00199             self.assertEqual(rec.description, "TestDescr")
00200             self.assertEqual(rec.dbxrefs, []) # May change this...
00201             self.assertEqual(rec.annotations, {}) # May change this...
00202             self.assertEqual(rec.letter_annotations, {"fake":"X"*26})
00203             self.assertTrue(len(rec.features) <= len(self.record.features))
00204 
00205     def test_slice_add_shift(self):
00206         """Simple slice and add to shift"""
00207         for cut in range(27) :
00208             rec = self.record[cut:] + self.record[:cut]
00209             self.assertEqual(str(rec.seq), str(self.record.seq[cut:] + self.record.seq[:cut]))
00210             self.assertEqual(len(rec), 26)
00211             self.assertEqual(rec.id, "TestID")
00212             self.assertEqual(rec.name, "TestName")
00213             self.assertEqual(rec.description, "TestDescr")
00214             self.assertEqual(rec.dbxrefs, []) # May change this...
00215             self.assertEqual(rec.annotations, {}) # May change this...
00216             self.assertEqual(rec.letter_annotations, {"fake":"X"*26})
00217             self.assertTrue(len(rec.features) <= len(self.record.features))
00218             
00219 if __name__ == "__main__":
00220     runner = unittest.TextTestRunner(verbosity = 2)
00221     unittest.main(testRunner=runner)