Back to index

python-biopython  1.60
_io.py
Go to the documentation of this file.
00001 # Copyright (C) 2009 by Eric Talevich (eric.talevich@gmail.com)
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 """I/O function wrappers for phylogenetic tree formats.
00007 
00008 This API follows the same semantics as Biopython's `SeqIO` and `AlignIO`.
00009 """
00010 
00011 # For with on Python/Jython 2.5
00012 from __future__ import with_statement
00013 __docformat__ = "restructuredtext en"
00014 
00015 from Bio import File
00016 from Bio.Phylo import BaseTree, NewickIO, NexusIO, PhyloXMLIO
00017 
00018 
00019 supported_formats = {
00020         'newick':   NewickIO,
00021         'nexus':    NexusIO,
00022         'phyloxml': PhyloXMLIO,
00023         }
00024 
00025 
00026 def parse(file, format, **kwargs):
00027     """Iteratively parse a file and return each of the trees it contains.
00028 
00029     If a file only contains one tree, this still returns an iterable object that
00030     contains one element.
00031 
00032     Example
00033     -------
00034 
00035     >>> trees = parse('../../Tests/PhyloXML/apaf.xml', 'phyloxml')
00036     >>> for tree in trees:
00037     ...     print tree.rooted
00038     True
00039     """
00040     with File.as_handle(file, 'r') as fp:
00041         for tree in getattr(supported_formats[format], 'parse')(fp, **kwargs):
00042             yield tree
00043 
00044 
00045 def read(file, format, **kwargs):
00046     """Parse a file in the given format and return a single tree.
00047 
00048     Raises a `ValueError` if there are zero or multiple trees -- if this occurs,
00049     use `parse` instead to get the complete sequence of trees.
00050     """
00051     try:
00052         tree_gen = parse(file, format, **kwargs)
00053         tree = tree_gen.next()
00054     except StopIteration:
00055         raise ValueError("There are no trees in this file.")
00056     try:
00057         tree_gen.next()
00058     except StopIteration:
00059         return tree
00060     else:
00061         raise ValueError(
00062                 "There are multiple trees in this file; use parse() instead.")
00063 
00064 
00065 def write(trees, file, format, **kwargs):
00066     """Write a sequence of trees to file in the given format."""
00067     if isinstance(trees, BaseTree.Tree) or isinstance(trees, BaseTree.Clade):
00068         # Passed a single tree instead of an iterable -- that's OK
00069         trees = [trees]
00070     with File.as_handle(file, 'w+') as fp:
00071         n = getattr(supported_formats[format], 'write')(trees, fp, **kwargs)
00072     return n
00073 
00074 
00075 def convert(in_file, in_format, out_file, out_format, **kwargs):
00076     """Convert between two tree file formats."""
00077     trees = parse(in_file, in_format)
00078     return write(trees, out_file, out_format, **kwargs)