Ejemplo n.º 1
0
def write(obj, handle, **kwargs):
    """Write a new Nexus file containing the given trees.

    Uses a simple Nexus template and the NewickIO writer to serialize just the
    trees and minimal supporting info needed for a valid Nexus file.
    """
    trees = list(obj)
    writer = NewickIO.Writer(trees)
    nexus_trees = [
        TREE_TEMPLATE % {
            'index': idx + 1,
            'tree': nwk
        } for idx, nwk in enumerate(
            writer.to_strings(plain=False, plain_newick=True, **kwargs))
    ]
    tax_labels = [
        str(x.name) for x in chain(*(t.get_terminals() for t in trees))
    ]
    text = NEX_TEMPLATE % {
        'count': len(tax_labels),
        'labels': ' '.join(tax_labels),
        'trees': '\n'.join(nexus_trees),
    }
    handle.write(text)
    return len(nexus_trees)
Ejemplo n.º 2
0
def nexus_text(obj, colour_branches, colours, **kwargs):
    """ Take tree-like object(s) and create nexus-format representation.
        Allows for colouring tip names.
        Modified from http://biopython.org/DIST/docs/api/Bio.Phylo.NexusIO-pysrc.html
        NB here we compensate for an apparent bug in the Biopython implementation, 
        whereby an additional colon is wrongly added to confidence values in the output tree strings.
    """
    try:
        trees = list(obj) # assume iterable
    except TypeError:
        trees = [obj]
    writer = NewickIO.Writer(trees) 
    nexus_trees = [TREE_TEMPLATE % {'index': idx + 1, 'tree': nwk} 
                 for idx, nwk in enumerate( 
      writer.to_strings(plain=False, plain_newick=True, 
                        **kwargs))] 
    # if branches are being coloured, then taxon names already contain colouring annotation
    # otherwise we need to add this annotation here
    tax_labels = [ colour_taxon(str(x.name), colours) if not colour_branches else str(x.name) for x in chain(*(t.get_terminals() for t in trees))] 
    text = NEX_TEMPLATE % { 
      'count': len(tax_labels), 
      'labels': ' '.join(tax_labels), # taxlabels all on one line 
      'trees': '\n'.join(nexus_trees), # trees on separate lines
    }
    return re.sub(r':([0-9]{1,3}\.[0-9]{1,3}):', r'\1:', text) # Corrects for biopython bug. eg ":50.00:" -> "50.00:"
Ejemplo n.º 3
0
    def to_nexus(self, filename):
        """Writes the tree to the given file in nexus format.

        This method doesn't call Bio.Phylo.NexusIO as BayesTraitsV2 requires a
        different dialect of Nexus format.
        """
        # Copy the tree before making any changes on it.
        tree = copy.deepcopy(self.tree)
        # BayesTraits requires the Nexus file to have a "Translate" block which
        # declares a number->taxon mapping so that numbers, not long taxa
        # names, are used in the tree descriptions.
        names_to_ints = dict((clade.name, i) for i, clade in enumerate(
            tree.get_terminals(), start=1))
        # Assign numbers to terminal clades
        for node in tree.get_terminals():
            node.name = str(names_to_ints[node.name])
        # Drop names of the inner nodes
        for n in tree.get_nonterminals():
            n.name = None
        # Tree to string
        writer = NewickIO.Writer([tree])
        nexus_tree = NEX_TEMPLATE % {
            'translate': ',\n'.join('%d %s' % (name, id)
                                    for id, name in names_to_ints.items()),
            'tree': next(writer.to_strings(plain=False, plain_newick=True))}
        # Write string to file
        with open(filename, 'w') as handle:
            handle.write(nexus_tree)
Ejemplo n.º 4
0
def write_nexus_trees_to_bayestraits(nx, handle, **kwargs):
    """Modified from Bio.Phylo.NexusIO.write():

    add a translate block converting leaf names to integers.
    """
    trees = BioNexusTrees_to_BioPhylo(nx.trees)
    writer = NewickIO.Writer(trees)
    nexus_trees = [
        TREE_TEMPLATE % {"index": idx + 1, "tree": nwk}
        for idx, nwk in enumerate(
            writer.to_strings(plain=False, plain_newick=True, **kwargs)
        )
    ]
    translate = ["%d %s" % id_name for id_name in nx.translate.items()]

    # Unused in my output format (BayesTraits) + why aren't they unique?
    tax_labels = [taxon for nt in nx.trees for taxon in nt.get_taxa()]
    #tax_labels = [str(x.name) for x in chain(*(t.get_terminals() for t in trees))]

    text = NEX_TEMPLATE % {
        "count": len(tax_labels),
        "labels": " ".join(tax_labels),
        "trees": "\n".join(nexus_trees),
        "translate": ",\n ".join(translate)
    }
    handle.write(text)
    return len(nexus_trees)
Ejemplo n.º 5
0
import sys

from Bio import Phylo
from Bio.Phylo import NewickIO

trees = list(Phylo.parse(sys.argv[1], "newick"))

print("Removing trees that are not bifurcating.")

for tree in trees:
    for nonterminal in tree.get_nonterminals():
        nonterminal.comment = None
        nonterminal.branch_length = None

writer = NewickIO.Writer([tree for tree in trees if tree.is_bifurcating()])

print()
print("Saving trees as plain newick files (no branch lengths).")
with open(sys.argv[2], "w") as handle:
    for newick_tree in writer.to_strings(plain=True):
        handle.write(newick_tree + "\n")