Example #1
0
def write(obj, file, encoding=DEFAULT_ENCODING, indent=True):
    """Write a phyloXML file.

    :Parameters:
        obj
            an instance of `Phyloxml`, `Phylogeny` or `BaseTree.Tree`, or an
            iterable of either of the latter two. The object will be converted
            to a Phyloxml object before serialization.
        file
            either an open handle or a file name.

    """
    def fix_single(tree):
        if isinstance(tree, PX.Phylogeny):
            return tree
        if isinstance(tree, PX.Clade):
            return tree.to_phylogeny()
        if isinstance(tree, PX.BaseTree.Tree):
            return PX.Phylogeny.from_tree(tree)
        if isinstance(tree, PX.BaseTree.Clade):
            return PX.Phylogeny.from_tree(PX.BaseTree.Tree(root=tree))
        else:
            raise ValueError("iterable must contain Tree or Clade types")

    if isinstance(obj, PX.Phyloxml):
        pass
    elif isinstance(obj, (PX.BaseTree.Tree, PX.BaseTree.Clade)):
        obj = fix_single(obj).to_phyloxml()
    elif hasattr(obj, '__iter__'):
        obj = PX.Phyloxml({}, phylogenies=(fix_single(t) for t in obj))
    else:
        raise ValueError("First argument must be a Phyloxml, Phylogeny, "
                         "Tree, or iterable of Trees or Phylogenies.")
    return Writer(obj).write(file, encoding=encoding, indent=indent)
Example #2
0
 def read(self):
     """Parse the phyloXML file and create a single Phyloxml object."""
     phyloxml = PX.Phyloxml({_local(key): val for key, val in self.root.items()})
     other_depth = 0
     for event, elem in self.context:
         namespace, localtag = _split_namespace(elem.tag)
         if event == "start":
             if namespace != NAMESPACES["phy"]:
                 other_depth += 1
                 continue
             if localtag == "phylogeny":
                 phylogeny = self._parse_phylogeny(elem)
                 phyloxml.phylogenies.append(phylogeny)
         if event == "end" and namespace != NAMESPACES["phy"]:
             # Deal with items not specified by phyloXML
             other_depth -= 1
             if other_depth == 0:
                 # We're directly under the root node -- evaluate
                 otr = self.other(elem, namespace, localtag)
                 phyloxml.other.append(otr)
                 self.root.clear()
     return phyloxml