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__ = "epytext en"
11
12 import BaseTree
13 import NewickIO
14 import NexusIO
15
16 try:
17 import PhyloXMLIO
18 except ImportError:
19
20
21
22
23 supported_formats = {
24 'newick': NewickIO,
25 'nexus': NexusIO,
26 }
27 else:
28 supported_formats = {
29 'newick': NewickIO,
30 'nexus': NexusIO,
31 'phyloxml': PhyloXMLIO,
32 }
33
34
36 """Iteratively parse a file and return each of the trees it contains.
37
38 If a file only contains one tree, this still returns an iterable object that
39 contains one element.
40
41 Example::
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):
55 yield tree
56
57 if do_close:
58 file.close()
59
60
61 -def read(file, format):
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)
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 return getattr(supported_formats[format], 'read')(file)
81
82
83 -def write(trees, file, format, **kwargs):
84 """Write a sequence of trees to file in the given format."""
85 if isinstance(trees, BaseTree.Tree):
86
87 trees = [trees]
88 do_close = False
89 if isinstance(file, basestring):
90 file = open(file, 'w+')
91 do_close = True
92 try:
93 n = getattr(supported_formats[format], 'write')(trees, file, **kwargs)
94 finally:
95 if do_close:
96 file.close()
97 return n
98
99
100 -def convert(in_file, in_format, out_file, out_format, **kwargs):
101 """Convert between two tree file formats."""
102 trees = parse(in_file, in_format)
103 return write(trees, out_file, out_format, **kwargs)
104