1
2
3
4
5
6 """I/O function wrappers for phylogenetic tree formats.
7
8 This API follows the same semantics as Biopython's `SeqIO` and `AlignIO`.
9 """
10 __docformat__ = "restructuredtext en"
11
12 from Bio.Phylo import BaseTree, NewickIO, NexusIO
13
14
15 try:
16 from Bio.Phylo import PhyloXMLIO
17 except ImportError:
18
19
20
21
22 supported_formats = {
23 'newick': NewickIO,
24 'nexus': NexusIO,
25 }
26 else:
27 supported_formats = {
28 'newick': NewickIO,
29 'nexus': NexusIO,
30 'phyloxml': PhyloXMLIO,
31 }
32
33
34 -def parse(file, format, **kwargs):
35 """Iteratively parse a file and return each of the trees it contains.
36
37 If a file only contains one tree, this still returns an iterable object that
38 contains one element.
39
40 Example
41 -------
42
43 >>> trees = parse('../../Tests/PhyloXML/apaf.xml', 'phyloxml')
44 >>> for tree in trees:
45 ... print tree.rooted
46 True
47 """
48 do_close = False
49 if isinstance(file, basestring):
50 file = open(file, 'r')
51 do_close = True
52
53
54 for tree in getattr(supported_formats[format], 'parse')(file, **kwargs):
55 yield tree
56
57 if do_close:
58 file.close()
59
60
61 -def read(file, format, **kwargs):
62 """Parse a file in the given format and return a single tree.
63
64 Raises a `ValueError` if there are zero or multiple trees -- if this occurs,
65 use `parse` instead to get the complete sequence of trees.
66 """
67 try:
68 tree_gen = parse(file, format, **kwargs)
69 tree = tree_gen.next()
70 except StopIteration:
71 raise ValueError("There are no trees in this file.")
72 try:
73 tree_gen.next()
74 except StopIteration:
75 return tree
76 else:
77 raise ValueError(
78 "There are multiple trees in this file; use parse() instead.")
79
80
81 -def write(trees, file, format, **kwargs):
82 """Write a sequence of trees to file in the given format."""
83 if isinstance(trees, BaseTree.Tree):
84
85 trees = [trees]
86 do_close = False
87 if isinstance(file, basestring):
88 file = open(file, 'w+')
89 do_close = True
90 try:
91 n = getattr(supported_formats[format], 'write')(trees, file, **kwargs)
92 finally:
93 if do_close:
94 file.close()
95 return n
96
97
98 -def convert(in_file, in_format, out_file, out_format, **kwargs):
99 """Convert between two tree file formats."""
100 trees = parse(in_file, in_format)
101 return write(trees, out_file, out_format, **kwargs)
102