1
2
3
4
5
6 """Code for dealing with sequence alignments.
7
8 One of the most important things in this module is the MultipleSeqAlignment
9 class, used in the Bio.AlignIO module.
10
11 """
12 __docformat__ = "epytext en"
13
14 from Bio.Seq import Seq
15 from Bio.SeqRecord import SeqRecord
16 from Bio import Alphabet
17
18
19 from Bio.Align.Generic import Alignment as _Alignment
21 """Represents a classical multiple sequence alignment (MSA).
22
23 By this we mean a collection of sequences (usually shown as rows) which
24 are all the same length (usually with gap characters for insertions or
25 padding). The data can then be regarded as a matrix of letters, with well
26 defined columns.
27
28 You would typically create an MSA by loading an alignment file with the
29 AlignIO module:
30
31 >>> from Bio import AlignIO
32 >>> align = AlignIO.read("Clustalw/opuntia.aln", "clustal")
33 >>> print align
34 SingleLetterAlphabet() alignment with 7 rows and 156 columns
35 TATACATTAAAGAAGGGGGATGCGGATAAATGGAAAGGCGAAAG...AGA gi|6273285|gb|AF191659.1|AF191
36 TATACATTAAAGAAGGGGGATGCGGATAAATGGAAAGGCGAAAG...AGA gi|6273284|gb|AF191658.1|AF191
37 TATACATTAAAGAAGGGGGATGCGGATAAATGGAAAGGCGAAAG...AGA gi|6273287|gb|AF191661.1|AF191
38 TATACATAAAAGAAGGGGGATGCGGATAAATGGAAAGGCGAAAG...AGA gi|6273286|gb|AF191660.1|AF191
39 TATACATTAAAGGAGGGGGATGCGGATAAATGGAAAGGCGAAAG...AGA gi|6273290|gb|AF191664.1|AF191
40 TATACATTAAAGGAGGGGGATGCGGATAAATGGAAAGGCGAAAG...AGA gi|6273289|gb|AF191663.1|AF191
41 TATACATTAAAGGAGGGGGATGCGGATAAATGGAAAGGCGAAAG...AGA gi|6273291|gb|AF191665.1|AF191
42
43 In some respects you can treat these objects as lists of SeqRecord objects,
44 each representing a row of the alignment. Iterating over an alignment gives
45 the SeqRecord object for each row:
46
47 >>> len(align)
48 7
49 >>> for record in align:
50 ... print record.id, len(record)
51 gi|6273285|gb|AF191659.1|AF191 156
52 gi|6273284|gb|AF191658.1|AF191 156
53 gi|6273287|gb|AF191661.1|AF191 156
54 gi|6273286|gb|AF191660.1|AF191 156
55 gi|6273290|gb|AF191664.1|AF191 156
56 gi|6273289|gb|AF191663.1|AF191 156
57 gi|6273291|gb|AF191665.1|AF191 156
58
59 You can also access individual rows as SeqRecord objects via their index:
60
61 >>> print align[0].id
62 gi|6273285|gb|AF191659.1|AF191
63 >>> print align[-1].id
64 gi|6273291|gb|AF191665.1|AF191
65
66 And extract columns as strings:
67
68 >>> print align[:,1]
69 AAAAAAA
70
71 Or, take just the first ten columns as a sub-alignment:
72
73 >>> print align[:,:10]
74 SingleLetterAlphabet() alignment with 7 rows and 10 columns
75 TATACATTAA gi|6273285|gb|AF191659.1|AF191
76 TATACATTAA gi|6273284|gb|AF191658.1|AF191
77 TATACATTAA gi|6273287|gb|AF191661.1|AF191
78 TATACATAAA gi|6273286|gb|AF191660.1|AF191
79 TATACATTAA gi|6273290|gb|AF191664.1|AF191
80 TATACATTAA gi|6273289|gb|AF191663.1|AF191
81 TATACATTAA gi|6273291|gb|AF191665.1|AF191
82
83 Combining this alignment slicing with alignment addition allows you to
84 remove a section of the alignment. For example, taking just the first
85 and last ten columns:
86
87 >>> print align[:,:10] + align[:,-10:]
88 SingleLetterAlphabet() alignment with 7 rows and 20 columns
89 TATACATTAAGTGTACCAGA gi|6273285|gb|AF191659.1|AF191
90 TATACATTAAGTGTACCAGA gi|6273284|gb|AF191658.1|AF191
91 TATACATTAAGTGTACCAGA gi|6273287|gb|AF191661.1|AF191
92 TATACATAAAGTGTACCAGA gi|6273286|gb|AF191660.1|AF191
93 TATACATTAAGTGTACCAGA gi|6273290|gb|AF191664.1|AF191
94 TATACATTAAGTATACCAGA gi|6273289|gb|AF191663.1|AF191
95 TATACATTAAGTGTACCAGA gi|6273291|gb|AF191665.1|AF191
96
97 Note - This object is intended to replace the existing Alignment object
98 defined in module Bio.Align.Generic but is not fully backwards compatible
99 with it.
100
101 Note - This object does NOT attempt to model the kind of alignments used
102 in next generation sequencing with multiple sequencing reads which are
103 much shorter than the alignment, and where there is usually a consensus or
104 reference sequence with special status.
105 """
106
107 - def __init__(self, records, alphabet=None):
108 """Initialize a new MultipleSeqAlignment object.
109
110 Arguments:
111 - records - A list (or iterator) of SeqRecord objects, whose
112 sequences are all the same length. This may be an be an
113 empty list.
114 - alphabet - The alphabet for the whole alignment, typically a gapped
115 alphabet, which should be a super-set of the individual
116 record alphabets. If omitted, a consensus alphabet is
117 used.
118
119 You would normally load a MSA from a file using Bio.AlignIO, but you
120 can do this from a list of SeqRecord objects too:
121
122 >>> from Bio.Alphabet import generic_dna
123 >>> from Bio.Seq import Seq
124 >>> from Bio.SeqRecord import SeqRecord
125 >>> a = SeqRecord(Seq("AAAACGT", generic_dna), id="Alpha")
126 >>> b = SeqRecord(Seq("AAA-CGT", generic_dna), id="Beta")
127 >>> c = SeqRecord(Seq("AAAAGGT", generic_dna), id="Gamma")
128 >>> align = MultipleSeqAlignment([a, b, c])
129 >>> print align
130 DNAAlphabet() alignment with 3 rows and 7 columns
131 AAAACGT Alpha
132 AAA-CGT Beta
133 AAAAGGT Gamma
134
135 NOTE - The older Bio.Align.Generic.Alignment class only accepted a
136 single argument, an alphabet. This is still supported via a backwards
137 compatible "hack" so as not to disrupt existing scripts and users, but
138 is deprecated and will be removed in a future release.
139 """
140 if isinstance(records, Alphabet.Alphabet) \
141 or isinstance(records, Alphabet.AlphabetEncoder):
142 if alphabet is None:
143
144 alphabet = records
145 records = []
146 import warnings
147 warnings.warn("Invalid records argument: While the old "
148 "Bio.Align.Generic.Alignment class only "
149 "accepted a single argument (the alphabet), the "
150 "newer Bio.Align.MultipleSeqAlignment class "
151 "expects a list/iterator of SeqRecord objects "
152 "(which can be an empty list) and an optional "
153 "alphabet argument")
154 else :
155 raise ValueError("Invalid records argument")
156 if alphabet is not None :
157 if not (isinstance(alphabet, Alphabet.Alphabet) \
158 or isinstance(alphabet, Alphabet.AlphabetEncoder)):
159 raise ValueError("Invalid alphabet argument")
160 self._alphabet = alphabet
161 else :
162
163 self._alphabet = Alphabet.single_letter_alphabet
164
165 self._records = []
166 if records:
167 self.extend(records)
168 if alphabet is None:
169
170 self._alphabet = Alphabet._consensus_alphabet(rec.seq.alphabet for \
171 rec in self._records \
172 if rec.seq is not None)
173
175 """Add more SeqRecord objects to the alignment as rows.
176
177 They must all have the same length as the original alignment, and have
178 alphabets compatible with the alignment's alphabet. For example,
179
180 >>> from Bio.Alphabet import generic_dna
181 >>> from Bio.Seq import Seq
182 >>> from Bio.SeqRecord import SeqRecord
183 >>> from Bio.Align import MultipleSeqAlignment
184 >>> a = SeqRecord(Seq("AAAACGT", generic_dna), id="Alpha")
185 >>> b = SeqRecord(Seq("AAA-CGT", generic_dna), id="Beta")
186 >>> c = SeqRecord(Seq("AAAAGGT", generic_dna), id="Gamma")
187 >>> d = SeqRecord(Seq("AAAACGT", generic_dna), id="Delta")
188 >>> e = SeqRecord(Seq("AAA-GGT", generic_dna), id="Epsilon")
189
190 First we create a small alignment (three rows):
191
192 >>> align = MultipleSeqAlignment([a, b, c])
193 >>> print align
194 DNAAlphabet() alignment with 3 rows and 7 columns
195 AAAACGT Alpha
196 AAA-CGT Beta
197 AAAAGGT Gamma
198
199 Now we can extend this alignment with another two rows:
200
201 >>> align.extend([d, e])
202 >>> print align
203 DNAAlphabet() alignment with 5 rows and 7 columns
204 AAAACGT Alpha
205 AAA-CGT Beta
206 AAAAGGT Gamma
207 AAAACGT Delta
208 AAA-GGT Epsilon
209
210 Because the alignment object allows iteration over the rows as
211 SeqRecords, you can use the extend method with a second alignment
212 (provided its sequences have the same length as the original alignment).
213 """
214 if len(self):
215
216 expected_length = self.get_alignment_length()
217 else:
218
219 records = iter(records)
220 try:
221 rec = records.next()
222 except StopIteration:
223
224 return
225 expected_length = len(rec)
226 self._append(rec, expected_length)
227
228
229 for rec in records:
230 self._append(rec, expected_length)
231
233 """Add one more SeqRecord object to the alignment as a new row.
234
235 This must have the same length as the original alignment (unless this is
236 the first record), and have an alphabet compatible with the alignment's
237 alphabet.
238
239 >>> from Bio import AlignIO
240 >>> align = AlignIO.read("Clustalw/opuntia.aln", "clustal")
241 >>> print align
242 SingleLetterAlphabet() alignment with 7 rows and 156 columns
243 TATACATTAAAGAAGGGGGATGCGGATAAATGGAAAGGCGAAAG...AGA gi|6273285|gb|AF191659.1|AF191
244 TATACATTAAAGAAGGGGGATGCGGATAAATGGAAAGGCGAAAG...AGA gi|6273284|gb|AF191658.1|AF191
245 TATACATTAAAGAAGGGGGATGCGGATAAATGGAAAGGCGAAAG...AGA gi|6273287|gb|AF191661.1|AF191
246 TATACATAAAAGAAGGGGGATGCGGATAAATGGAAAGGCGAAAG...AGA gi|6273286|gb|AF191660.1|AF191
247 TATACATTAAAGGAGGGGGATGCGGATAAATGGAAAGGCGAAAG...AGA gi|6273290|gb|AF191664.1|AF191
248 TATACATTAAAGGAGGGGGATGCGGATAAATGGAAAGGCGAAAG...AGA gi|6273289|gb|AF191663.1|AF191
249 TATACATTAAAGGAGGGGGATGCGGATAAATGGAAAGGCGAAAG...AGA gi|6273291|gb|AF191665.1|AF191
250 >>> len(align)
251 7
252
253 We'll now construct a dummy record to append as an example:
254
255 >>> from Bio.Seq import Seq
256 >>> from Bio.SeqRecord import SeqRecord
257 >>> dummy = SeqRecord(Seq("N"*156), id="dummy")
258
259 Now append this to the alignment,
260
261 >>> align.append(dummy)
262 >>> print align
263 SingleLetterAlphabet() alignment with 8 rows and 156 columns
264 TATACATTAAAGAAGGGGGATGCGGATAAATGGAAAGGCGAAAG...AGA gi|6273285|gb|AF191659.1|AF191
265 TATACATTAAAGAAGGGGGATGCGGATAAATGGAAAGGCGAAAG...AGA gi|6273284|gb|AF191658.1|AF191
266 TATACATTAAAGAAGGGGGATGCGGATAAATGGAAAGGCGAAAG...AGA gi|6273287|gb|AF191661.1|AF191
267 TATACATAAAAGAAGGGGGATGCGGATAAATGGAAAGGCGAAAG...AGA gi|6273286|gb|AF191660.1|AF191
268 TATACATTAAAGGAGGGGGATGCGGATAAATGGAAAGGCGAAAG...AGA gi|6273290|gb|AF191664.1|AF191
269 TATACATTAAAGGAGGGGGATGCGGATAAATGGAAAGGCGAAAG...AGA gi|6273289|gb|AF191663.1|AF191
270 TATACATTAAAGGAGGGGGATGCGGATAAATGGAAAGGCGAAAG...AGA gi|6273291|gb|AF191665.1|AF191
271 NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN...NNN dummy
272 >>> len(align)
273 8
274
275 """
276 if self._records:
277 self._append(record, self.get_alignment_length())
278 else:
279 self._append(record)
280
281 - def _append(self, record, expected_length=None):
282 """Helper function (PRIVATE)."""
283 if not isinstance(record, SeqRecord):
284 raise TypeError("New sequence is not a SeqRecord object")
285
286
287
288
289 if expected_length is not None and len(record) != expected_length:
290
291
292
293 raise ValueError("Sequences must all be the same length")
294
295
296
297 if not Alphabet._check_type_compatible([self._alphabet, record.seq.alphabet]):
298 raise ValueError("New sequence's alphabet is incompatible")
299 self._records.append(record)
300
302 """Combines to alignments with the same number of rows by adding them.
303
304 If you have two multiple sequence alignments (MSAs), there are two ways to think
305 about adding them - by row or by column. Using the extend method adds by row.
306 Using the addition operator adds by column. For example,
307
308 >>> from Bio.Alphabet import generic_dna
309 >>> from Bio.Seq import Seq
310 >>> from Bio.SeqRecord import SeqRecord
311 >>> from Bio.Align import MultipleSeqAlignment
312 >>> a1 = SeqRecord(Seq("AAAAC", generic_dna), id="Alpha")
313 >>> b1 = SeqRecord(Seq("AAA-C", generic_dna), id="Beta")
314 >>> c1 = SeqRecord(Seq("AAAAG", generic_dna), id="Gamma")
315 >>> a2 = SeqRecord(Seq("GT", generic_dna), id="Alpha")
316 >>> b2 = SeqRecord(Seq("GT", generic_dna), id="Beta")
317 >>> c2 = SeqRecord(Seq("GT", generic_dna), id="Gamma")
318 >>> left = MultipleSeqAlignment([a1, b1, c1])
319 >>> right = MultipleSeqAlignment([a2, b2, c2])
320
321 Now, let's look at these two alignments:
322
323 >>> print left
324 DNAAlphabet() alignment with 3 rows and 5 columns
325 AAAAC Alpha
326 AAA-C Beta
327 AAAAG Gamma
328 >>> print right
329 DNAAlphabet() alignment with 3 rows and 2 columns
330 GT Alpha
331 GT Beta
332 GT Gamma
333
334 And add them:
335
336 >>> print left + right
337 DNAAlphabet() alignment with 3 rows and 7 columns
338 AAAACGT Alpha
339 AAA-CGT Beta
340 AAAAGGT Gamma
341
342 For this to work, both alignments must have the same number of records (here
343 they both have 3 rows):
344
345 >>> len(left)
346 3
347 >>> len(right)
348 3
349
350 The individual rows are SeqRecord objects, and these can be added together. Refer
351 to the SeqRecord documentation for details of how the annotation is handled. This
352 example is a special case in that both original alignments shared the same names,
353 meaning when the rows are added they also get the same name.
354 """
355 if not isinstance(other, MultipleSeqAlignment):
356 raise NotImplementedError
357 if len(self) != len(other):
358 raise ValueError("When adding two alignments they must have the same length"
359 " (i.e. same number or rows)")
360 alpha = Alphabet._consensus_alphabet([self._alphabet, other._alphabet])
361 merged = (left+right for left,right in zip(self, other))
362 return MultipleSeqAlignment(merged, alpha)
363
365 """Access part of the alignment.
366
367 Depending on the indices, you can get a SeqRecord object
368 (representing a single row), a Seq object (for a single columns),
369 a string (for a single characters) or another alignment
370 (representing some part or all of the alignment).
371
372 align[r,c] gives a single character as a string
373 align[r] gives a row as a SeqRecord
374 align[r,:] gives a row as a SeqRecord
375 align[:,c] gives a column as a Seq (using the alignment's alphabet)
376
377 align[:] and align[:,:] give a copy of the alignment
378
379 Anything else gives a sub alignment, e.g.
380 align[0:2] or align[0:2,:] uses only row 0 and 1
381 align[:,1:3] uses only columns 1 and 2
382 align[0:2,1:3] uses only rows 0 & 1 and only cols 1 & 2
383
384 We'll use the following example alignment here for illustration:
385
386 >>> from Bio.Alphabet import generic_dna
387 >>> from Bio.Seq import Seq
388 >>> from Bio.SeqRecord import SeqRecord
389 >>> from Bio.Align import MultipleSeqAlignment
390 >>> a = SeqRecord(Seq("AAAACGT", generic_dna), id="Alpha")
391 >>> b = SeqRecord(Seq("AAA-CGT", generic_dna), id="Beta")
392 >>> c = SeqRecord(Seq("AAAAGGT", generic_dna), id="Gamma")
393 >>> d = SeqRecord(Seq("AAAACGT", generic_dna), id="Delta")
394 >>> e = SeqRecord(Seq("AAA-GGT", generic_dna), id="Epsilon")
395 >>> align = MultipleSeqAlignment([a, b, c, d, e], generic_dna)
396
397 You can access a row of the alignment as a SeqRecord using an integer
398 index (think of the alignment as a list of SeqRecord objects here):
399
400 >>> first_record = align[0]
401 >>> print first_record.id, first_record.seq
402 Alpha AAAACGT
403 >>> last_record = align[-1]
404 >>> print last_record.id, last_record.seq
405 Epsilon AAA-GGT
406
407 You can also access use python's slice notation to create a sub-alignment
408 containing only some of the SeqRecord objects:
409
410 >>> sub_alignment = align[2:5]
411 >>> print sub_alignment
412 DNAAlphabet() alignment with 3 rows and 7 columns
413 AAAAGGT Gamma
414 AAAACGT Delta
415 AAA-GGT Epsilon
416
417 This includes support for a step, i.e. align[start:end:step], which
418 can be used to select every second sequence:
419
420 >>> sub_alignment = align[::2]
421 >>> print sub_alignment
422 DNAAlphabet() alignment with 3 rows and 7 columns
423 AAAACGT Alpha
424 AAAAGGT Gamma
425 AAA-GGT Epsilon
426
427 Or to get a copy of the alignment with the rows in reverse order:
428
429 >>> rev_alignment = align[::-1]
430 >>> print rev_alignment
431 DNAAlphabet() alignment with 5 rows and 7 columns
432 AAA-GGT Epsilon
433 AAAACGT Delta
434 AAAAGGT Gamma
435 AAA-CGT Beta
436 AAAACGT Alpha
437
438 You can also use two indices to specify both rows and columns. Using simple
439 integers gives you the entry as a single character string. e.g.
440
441 >>> align[3,4]
442 'C'
443
444 This is equivalent to:
445
446 >>> align[3][4]
447 'C'
448
449 or:
450
451 >>> align[3].seq[4]
452 'C'
453
454 To get a single column (as a string) use this syntax:
455
456 >>> align[:,4]
457 'CCGCG'
458
459 Or, to get part of a column,
460
461 >>> align[1:3,4]
462 'CG'
463
464 However, in general you get a sub-alignment,
465
466 >>> print align[1:5,3:6]
467 DNAAlphabet() alignment with 4 rows and 3 columns
468 -CG Beta
469 AGG Gamma
470 ACG Delta
471 -GG Epsilon
472
473 This should all seem familiar to anyone who has used the NumPy
474 array or matrix objects.
475 """
476 if isinstance(index, int):
477
478
479 return self._records[index]
480 elif isinstance(index, slice):
481
482 return MultipleSeqAlignment(self._records[index], self._alphabet)
483 elif len(index)!=2:
484 raise TypeError("Invalid index type.")
485
486
487 row_index, col_index = index
488 if isinstance(row_index, int):
489
490 return self._records[row_index][col_index]
491 elif isinstance(col_index, int):
492
493 return "".join(rec[col_index] for rec in self._records[row_index])
494 else:
495
496 return MultipleSeqAlignment((rec[col_index] for rec in self._records[row_index]),
497 self._alphabet)
498
500 """Sort the rows (SeqRecord objects) of the alignment in place.
501
502 This sorts the rows alphabetically using the SeqRecord object id.
503 Currently no advanced sort options are available, although this may
504 be added in a future release of Biopython.
505
506 This is useful if you want to add two alignments which use the same
507 record identifiers, but in a different order. For example,
508
509 >>> from Bio.Alphabet import generic_dna
510 >>> from Bio.Seq import Seq
511 >>> from Bio.SeqRecord import SeqRecord
512 >>> from Bio.Align import MultipleSeqAlignment
513 >>> align1 = MultipleSeqAlignment([
514 ... SeqRecord(Seq("ACGT", generic_dna), id="Human"),
515 ... SeqRecord(Seq("ACGG", generic_dna), id="Mouse"),
516 ... SeqRecord(Seq("ACGC", generic_dna), id="Chicken"),
517 ... ])
518 >>> align2 = MultipleSeqAlignment([
519 ... SeqRecord(Seq("CGGT", generic_dna), id="Mouse"),
520 ... SeqRecord(Seq("CGTT", generic_dna), id="Human"),
521 ... SeqRecord(Seq("CGCT", generic_dna), id="Chicken"),
522 ... ])
523
524 If you simple try and add these without sorting, you get this:
525
526 >>> print align1 + align2
527 DNAAlphabet() alignment with 3 rows and 8 columns
528 ACGTCGGT <unknown id>
529 ACGGCGTT <unknown id>
530 ACGCCGCT Chicken
531
532 Consult the SeqRecord documentation which explains why you get a
533 default value when annotation like the identifier doesn't match up.
534 However, if we sort the alignments first, then add them we get the
535 desired result:
536
537 >>> align1.sort()
538 >>> align2.sort()
539 >>> print align1 + align2
540 DNAAlphabet() alignment with 3 rows and 8 columns
541 ACGCCGCT Chicken
542 ACGTCGTT Human
543 ACGGCGGT Mouse
544
545 """
546 self._records.sort(key = lambda r: r.id)
547
549 """Returns a string containing a given column (DEPRECATED).
550
551 This is a method provided for backwards compatibility with the old
552 Bio.Align.Generic.Alignment object. Please use the slice notation
553 instead, since get_column is likely to be removed in a future release
554 of Biopython..
555 """
556 import warnings
557 import Bio
558 warnings.warn("This method is deprecated and is provided for backwards compatibility with the old Bio.Align.Generic.Alignment object. Please use the slice notation instead, as get_column is likely to be removed in a future release of Biopython.", Bio.BiopythonDeprecationWarning)
559 return _Alignment.get_column(self, col)
560
561 - def add_sequence(self, descriptor, sequence, start = None, end = None,
562 weight = 1.0):
563 """Add a sequence to the alignment (DEPRECATED).
564
565 The start, end, and weight arguments are not supported! This method
566 only provides limited backwards compatibility with the old
567 Bio.Align.Generic.Alignment object. Please use the append method with
568 a SeqRecord instead, since add_sequence is likely to be removed in a
569 future release of Biopython.
570 """
571 import warnings
572 import Bio
573 warnings.warn("The start, end, and weight arguments are not supported! This method only provides limited backwards compatibility with the old Bio.Align.Generic.Alignment object. Please use the append method with a SeqRecord instead, as the add_sequence method is likely to be removed in a future release of Biopython.", Bio.BiopythonDeprecationWarning)
574
575
576 if start is not None or end is not None or weight != 1.0:
577 raise ValueError("The add_Sequence method is obsolete, and only "
578 "provides limited backwards compatibily. The"
579 "start, end and weight arguments are not "
580 "supported.")
581 self.append(SeqRecord(Seq(sequence, self._alphabet),
582 id = descriptor, description = descriptor))
583
584
586 """Run the Bio.Align module's doctests.
587
588 This will try and locate the unit tests directory, and run the doctests
589 from there in order that the relative paths used in the examples work.
590 """
591 import doctest
592 import os
593 if os.path.isdir(os.path.join("..", "..", "Tests", "Clustalw")):
594 print "Runing doctests..."
595 cur_dir = os.path.abspath(os.curdir)
596 os.chdir(os.path.join("..", "..", "Tests"))
597 doctest.testmod()
598 os.chdir(cur_dir)
599 del cur_dir
600 print "Done"
601 elif os.path.isdir(os.path.join("Tests", "Clustalw")):
602 print "Runing doctests..."
603 cur_dir = os.path.abspath(os.curdir)
604 os.chdir(os.path.join("Tests"))
605 doctest.testmod()
606 os.chdir(cur_dir)
607 del cur_dir
608 print "Done"
609
610 if __name__ == "__main__":
611
612 _test()
613