1
2
3
4
5
6 from Bio.Alphabet import generic_alphabet
7
9 """Base class for building SeqRecord iterators.
10
11 You should write a next() method to return SeqRecord
12 objects. You may wish to redefine the __init__
13 method as well.
14 """
16 """Create a SequenceIterator object.
17
18 handle - input file
19 alphabet - optional, e.g. Bio.Alphabet.generic_protein
20
21 Note when subclassing:
22 - there should be a single non-optional argument,
23 the handle.
24 - you do not have to require an alphabet.
25 - you can add additional optional arguments."""
26 self.handle = handle
27 self.alphabet = alphabet
28
29
30
31
32
33
35 """Return the next record in the file
36 This method should be replaced by any derived class to do something useful."""
37 raise NotImplementedError, "This object should be subclassed"
38
39
40
41
42
43
45 """Iterate over the entries as a SeqRecord objects
46
47 Example usage for Fasta files:
48
49 myFile = open("example.fasta","r")
50 myFastaReader = FastaIterator(myFile)
51 for record in myFastaReader :
52 print record.id
53 print record.seq
54 myFile.close()"""
55 return iter(self.next, None)
56
58 """This class should be subclassed by any iterator for a non-sequential file type.
59
60 This object is not intended for use directly.
61
62 When writing a parser for any interlaced sequence file where the whole
63 file must be read in order to extract any single record, then you should
64 subclass this object.
65
66 All you need to do is to define your own:
67 (1) __init__ method to parse the file and call self.move_start()
68 (2) __len__ method to return the number of records
69 (3) __getitem__ to return any requested record.
70
71 This class will then provide the iterator methods including next(), but relies
72 on knowing the total number of records and tracking the pending record index in
73 as self._n
74
75 It is up to the subclassed object to decide if it wants to generate a cache of
76 SeqRecords when initialised, or simply use its own lists and dicts and create
77 SeqRecords on request.
78 """
79
81 """Create the object
82
83 This method should be replaced by any derived class to do something useful."""
84
85 self.move_start()
86 raise NotImplementedError, "This object method should be subclassed"
87
88
89
90
92 """Return the number of record
93
94 This method should be replaced by any derived class to do something useful."""
95 raise NotImplementedError, "This object method should be subclassed"
96
97
98
99
101 """Return the requested record
102
103 This method should be replaced by any derived class to do something
104 useful.
105
106 It should NOT touch the value of self._n"""
107 raise NotImplementedError, "This object method should be subclassed"
108
109
110
111
114
116 next_record = self._n
117 if next_record < len(self) :
118 self._n = next_record+1
119 return self[next_record]
120 else :
121
122 return None
123
125 return iter(self.next, None)
126
128 """This class should be subclassed.
129
130 Interlaced file formats (e.g. Clustal) should subclass directly.
131
132 Sequential file formats (e.g. Fasta, GenBank) should subclass
133 the SequentialSequenceWriter class instead.
134 """
136 """Creates the writer object
137
138 Use the method write_file() to actually record your sequence records."""
139 self.handle = handle
140
142 """Use this to avoid getting newlines in the output"""
143 answer = text
144 for x in ["\n", "\r"] :
145 answer = answer.replace(x, " ")
146 return answer.replace(" ", " ")
147
149 """Use this to write an entire file containing the given records.
150
151 records - A list or iterator returning SeqRecord objects
152
153 This method can only be called once."""
154
155 raise NotImplementedError, "This object should be subclassed"
156
157
158
159
161 """This class should be subclassed.
162
163 It is intended for sequential file formats with an (optional)
164 header, repeated records, and an (optional) footer.
165
166 In this case (as with interlaced file formats), the user may
167 simply call the write_file() method and be done.
168
169 However, they may also call the write_header(), followed
170 by multiple calls to write_record() and/or write_records()
171 followed finally by write_footer().
172
173 Users must call write_header() and write_footer() even when
174 the file format concerned doesn't have a header or footer.
175 This is to try and make life as easy as possible when
176 switching the output format.
177
178 Note that write_header() cannot require any assumptions about
179 the number of records.
180 """
186
188 assert not self._header_written, "You have aleady called write_header()"
189 assert not self._record_written, "You have aleady called write_record() or write_records()"
190 assert not self._footer_written, "You have aleady called write_footer()"
191 self._header_written = True
192
198
200 """Write a single record to the output file.
201
202 record - a SeqRecord object
203
204 Once you have called write_header() you can call write_record()
205 and/or write_records() as many times as needed. Then call
206 write_footer() and close()."""
207 assert self._header_written, "You must call write_header() first"
208 assert not self._footer_written, "You have already called write_footer()"
209 self._record_written = True
210 raise NotImplementedError, "This object should be subclassed"
211
212
213
214
216 """Write multiple record to the output file.
217
218 records - A list or iterator returning SeqRecord objects
219
220 Once you have called write_header() you can call write_record()
221 and/or write_records() as many times as needed. Then call
222 write_footer() and close()."""
223
224 assert self._header_written, "You must call write_header() first"
225 assert not self._footer_written, "You have already called write_footer()"
226 for record in records :
227 self.write_record(record)
228
229 self._record_written = True
230
232 """Use this to write an entire file containing the given records.
233
234 records - A list or iterator returning SeqRecord objects
235
236 This method can only be called once."""
237 self.write_header()
238 self.write_records(records)
239 self.write_footer()
240