Phylo

Package for creating and manipulating phylogenies

Phylo is a Julia package that provides functionality for generating phylogenetic trees to feed into our Diversity package to calculate phylogenetic diversity (currently on master, accessible via Pkg.checkout(), but not released). Both are currently under development, so please raise an issue if you find any problems. Currently the package can be used to make trees manually, and to generate random trees using the framework from Distributions. For instance, to construct a sampler for 5 tip non-ultrametric trees, and then generate a random tree of that type:

julia> using Phylo

julia> nu = Nonultrametric(5);

julia> tree = rand(nu)
NamedTree phylogenetic tree with 9 nodes and 8 branches
Leaf names:
String["tip 1", "tip 2", "tip 3", "tip 4", "tip 5"]

The code also provides iterators, and filtered iterators over the branches, nodes, branchnames and nodenames of a tree:

julia> collect(nodeiter(tree))
9-element Array{Phylo.BinaryNode{Int64},1}:
 [branch 4]-->[leaf node]
 [branch 5]-->[leaf node]
 [branch 2]-->[leaf node]
 [branch 1]-->[leaf node]
 [branch 8]-->[leaf node]
 [branch 3]-->[internal node]-->[branches 1 and 2]
 [branch 6]-->[internal node]-->[branches 3 and 4]
 [branch 7]-->[internal node]-->[branches 5 and 6]
 [root node]-->[branches 7 and 8]

julia> collect(nodenamefilter(isroot, tree))
1-element Array{String,1}:
 "Node 4"

The current main purpose of this package is to provide a framework for phylogenetics to use in our Diversity package, and they will both be adapted as appropriate until both are functioning as required (though they are currently working together reasonably successfully).

However, it can also read newick trees:

julia> using Phylo

julia> simpletree = parsenewick("((,Tip:1.0)Internal,)Root;")
NamedTree phylogenetic tree with 5 nodes and 4 branches
Leaf names:
String["Node 2", "Tip", "Node 1"]

julia> getbranches(simpletree)
Dict{Int64,Phylo.Branch{String}} with 4 entries:
  4 => [node "Root"]-->[NaN length branch]-->[node "Node 2"]
  2 => [node "Internal"]-->[1.0 length branch]-->[node "Tip"]
  3 => [node "Root"]-->[NaN length branch]-->[node "Internal"]
  1 => [node "Internal"]-->[NaN length branch]-->[node "Node 1"]

julia> open(parsenewick, tree = open(parsenewick, Pkg.dir("Phylo", "test", "h1n1.trees")))
NamedTree phylogenetic tree with 1013 nodes and 1012 branches
Leaf names:
String["407", "153", "1", "54", "101", "371", "41", "464", "65", "475"    "336", "145", "36", "95", "414", "138", "294", "353", "232", "306"]

And while we wait for me (or kind contributors!) to fill out the other extensive functionality that many phylogenetics packages have in other languages, the other important feature that it offers is a fully(?)-functional interface to R, allowing any existing R library functions to be carried out on julia trees, and trees to be read from disk and written using R helper functions. Naturally the medium-term plan is to fill in as many of these gaps as possible in Julia, and as a result this R interface is not built into the package as it will make RCall (and R) a dependency, which I wanted to avoid. Instead, if you want to use the R interface you need to do it manually, as below:

julia> using RCall

julia> include(joinpath(Pkg.dir("Phylo"), "src", "rcall.jl"));

R> library(ape)

You can then translate back and forth using NamedTree contructors on R phylo objects, and RObject constructors on julia NamedTree types to keep them in Julia or @rput to move the object into R:

julia> rt = rcall(:rtree, 10)
RCall.RObject{RCall.VecSxp}

Phylogenetic tree with 10 tips and 9 internal nodes.

Tip labels:
    t10, t8, t1, t2, t6, t5, ...

Rooted; includes branch lengths.

julia> jt = NamedTree(rt)
NamedTree phylogenetic tree with 19 nodes and 18 branches
Leaf names:
String["t10", "t8", "t1", "t2", "t6", "t5", "t3", "t4", "t7", "t9"]

julia> @rput rt;

julia> @rput jt; # Automatically translates jt back to R

R> jt

Phylogenetic tree with 10 tips and 9 internal nodes.

Tip labels:
    t10, t8, t1, t2, t6, t5, ...

Rooted; includes branch lengths.

R> all.equal(rt, jt) # check no damage in translations
[1] TRUE

# PhyloModule.

Phylo package

The Phylo package provides a standard abstract interface to phylogenetic trees, by defining AbstractNode, AbstractBranch and AbstractTree supertypes, and methods to interface to them. It also provides (through the Phylo.API submodule) methods to (re)define to write your own phylogenetic type in a way that will interact cleanly with other phylogenetic packages. Finally, it provides a simple phylogenetics type.

source

# Phylo.BinaryNodeType.

BinaryNode{T}(AbstractVector{T}, AbstractVector{T}) <: AbstractNode

A node of strict binary phylogenetic tree

source

# Phylo.BinaryTreeType.

BinaryTree

Binary phylogenetic tree object with known leaves and per node data

source

# Phylo.BranchType.

Branch

A directed branch connecting two AbstractNodes of phylogenetic tree

source

# Phylo.NamedTreeType.

NamedTree

Binary phylogenetic tree object with known leaves

source

# Phylo.NonultrametricType.

Nonultrametric{T <: AbstractTree,
               RNG <: Sampleable}(n::Int,
                                  rng::RNG = Exponential())
Nonultrametric{T <: AbstractTree,
               RNG <: Sampleable}(tiplabels::Vector{String},
                                  rng::RNG = Exponential())

The sampler for non-ultrametric phylogenetic trees of size n or with tip labels tiplabels. Generate random trees by calling rand(). Currently only works for NamedTrees.

source

# Phylo.UltrametricType.

Ultrametric{T <: AbstractTree,
            RNG <: Sampleable}(n::Int,
                               rng::RNG = Exponential())
Ultrametric{T <: AbstractTree,
            RNG <: Sampleable}(tiplabels::Vector{String},
                               rng::RNG = Exponential())

The sampler for ultrametric phylogenetic trees of size n or with tip labels tiplabels. Generate random trees by calling rand(). Currently only works for NamedTrees.

source

# Phylo.addbranch!Function.

addbranch!(tree::AbstractTree, source, destination[, length::Float64];
           branchname = _newbranchlabel(tree))

Add a branch from source to destination on tree.

source

# Phylo.addnode!Function.

addnode!(tree::AbstractTree)
addnode!(tree::AbstractTree, nodename)

source

# Phylo.addnodes!Function.

addnodes!(tree::AbstractTree, nodenames::AbstractVector)
addnodes!(tree::AbstractTree, count::Integer)

source

# Phylo.branch!Function.

branch!(tree::AbstractTree, source[, length])
branch!(tree::AbstractTree, source[, length]; destination)
branch!(tree::AbstractTree, source[, length]; destination, branchname)

Branch from a source node source and create a destination node destination.

source

# Phylo.branchfilterMethod.

branchfilter(filterfn::Function, tree::AbstractTree)

Returns an iterator over the branches of any tree, where the AbstractBranch is filtered by the function filterfn.

source

# Phylo.branchhistoryMethod.

branchhistory(tree::AbstractTree, node)

Find the branch route between a node on a tree and its root

source

# Phylo.branchiterMethod.

branchiter(tree::AbstractTree)

Returns an iterator over the branches of any tree.

source

# Phylo.branchnamefilterMethod.

branchnamefilter(filterfn::Function, tree::AbstractTree)

Returns an iterator over the names of the branches of any tree, where the AbstractBranch is filtered by the function filterfn.

source

# Phylo.branchnameiterMethod.

branchnameiter(tree::AbstractTree)

Returns an iterator over the names of branches of any tree.

source

# Phylo.branchnametypeMethod.

branchnametype(::AbstractTree)

Returns type of branch names.

source

# Phylo.branchrouteMethod.

branchroute(tree::AbstractTree, node1, node2)

Find the branch route between two nodes on a tree

source

# Phylo.branchtypeMethod.

branchtype(tree::AbstractTree)

Returns type of branches in a tree.

source

# Phylo.changedst!Method.

changedst!(tree::AbstractTree, branchname, destination)

Change the destination node for this node.

source

# Phylo.changesrc!Method.

changesrc!(tree::AbstractTree, branchname, source)

Change the source node for this branch.

source

# Phylo.clearrootheight!Method.

clearrootheight(::AbstractTree)

Clears the tree's root height record.

source

# Phylo.deletebranch!Method.

deletebranch!(tree::AbstractTree, branchname)

Delete the branch branchname from tree.

source

# Phylo.deletenode!Method.

deletenode!(tree::AbstractTree, nodename)

source

# Phylo.distanceMethod.

distance(tree::AbstractTree, node1, node2)

Distance between two nodes on a tree

source

# Phylo.distancesMethod.

distances(tree::AbstractTree)

Pairwise distances between all leaf nodes on a tree

source

# Phylo.dstFunction.

dst(branch::AbstractBranch)
dst(tree::AbstractTree, branchname)

Return the destination node for this branch.

source

# Phylo.getancestorsMethod.

getancestors(tree::AbstractTree, nodename)

Return the name of all of the nodes that are ancestral to this node.

source

# Phylo.getbranchMethod.

getbranch(tree::AbstractTree, branchname)

source

# Phylo.getbranchnamesMethod.

getbranchnames(tree::AbstractTree)

source

# Phylo.getchildrenMethod.

getchildren(tree::AbstractTree, nodename)

Return the name(s) of the child node(s) for this node.

source

# Phylo.getdescendantsMethod.

getdescendants(tree::AbstractTree, nodename)

Return the names of all of the nodes that descend from this node.

source

# Phylo.getheightMethod.

getheight(tree::AbstractTree, nodename)

Return the height of the node.

source

# Phylo.getinboundFunction.

getinbound(node::AbstractNode)
getinbound(tree::AbstractTree, nodename)

return the name of the inbound branch to this node.

source

# Phylo.getleafinfoMethod.

getleafinfo(::AbstractTree, label)

retrieve the leaf info for a leaf of the tree.

source

# Phylo.getleafnamesMethod.

getleafnames(::AbstractTree)

Retrieve the leaf names from the tree.

source

# Phylo.getlengthFunction.

getlength(branch::AbstractBranch)
getlength(tree::AbstractTree, branchname)

Return the length of this branch.

source

# Phylo.getnodeMethod.

getnode(tree::AbstractTree, nodename)

source

# Phylo.getnodenamesMethod.

getnodenames(tree::AbstractTree)

source

# Phylo.getnoderecordMethod.

getnoderecord(::AbstractTree, label)

retrieve the node record for a leaf of the tree.

source

# Phylo.getoutboundsFunction.

getoutbounds(node::AbstractNode)
getoutbounds(tree::AbstractTree, nodename)

Return the names of the outbound branches from this node.

source

# Phylo.getparentMethod.

getparent(tree::AbstractTree, nodename)

Return the name of the parent node for this node.

source

# Phylo.getrootheightMethod.

getrootheight(tree::AbstractTree)

source

# Phylo.hasbranchMethod.

hasbranch(tree::AbstractTree, branchname)

source

# Phylo.hasheightFunction.

hasheight(tree::AbstractTree, nodename)

Does the node have a height defined?

source

# Phylo.hasinboundFunction.

hasinbound(node::AbstractNode)
hasinbound(tree::AbstractTree, nodename)

Does the node have an inbound connection?

source

# Phylo.hasinboundspaceFunction.

hasinboundspace(node::AbstractNode)
hasinboundspace(tree::AbstractTree, nodename)

Does the node have space for an inbound connection?

source

# Phylo.hasnodeMethod.

hasnode(tree::AbstractTree, nodename)

source

# Phylo.hasoutboundspaceFunction.

hasoutboundspace(node::AbstractNode)
hasoutboundspace(tree::AbstractTree, nodename)

Does the node have space for an[other] outbound connection?

source

# Phylo.hasrootheightMethod.

hasrootheight(tree::AbstractTree)

source

# Phylo.heightstorootMethod.

heights(tree::AbstractTree)

Height of all of the leaves of the tree above the root

source

# Phylo.heighttorootMethod.

height(tree::AbstractTree, node)

Height of a node of the tree above the root

source

# Phylo.indegreeFunction.

indegree(node::AbstractNode)
indegree(tree::AbstractTree, nodename)

source

# Phylo.isinternalFunction.

isinternal(node::AbstractNode)
isinternal(tree::AbstractTree, nodename)

source

# Phylo.isleafFunction.

isleaf(node::AbstractNode)
isleaf(tree::AbstractTree, nodename)

source

# Phylo.isrootFunction.

isroot(node::AbstractNode)
isroot(tree::AbstractTree, nodename)

source

# Phylo.isunattachedFunction.

isunattached(node::AbstractNode)
isunattached(tree::AbstractTree, nodename)

source

# Phylo.nodefilterMethod.

nodefilter(filterfn::Function, tree::AbstractTree)

Returns an iterator over the nodes of any tree, where the AbstractNode is filtered by the function filterfn.

source

# Phylo.nodehistoryMethod.

nodehistory(tree::AbstractTree, node)

Find the node route between a node on a tree and its root

source

# Phylo.nodeiterMethod.

nodeiter(tree::AbstractTree)

Returns an iterator over the nodes of any tree.

source

# Phylo.nodenamefilterMethod.

nodenamefilter(filterfn::Function, tree::AbstractTree)

Returns an iterator over the nodenames of any tree, where the AbstractNode itself is filtered by the function filterfn.

source

# Phylo.nodenameiterMethod.

nodenameiter(tree::AbstractTree)

Returns an iterator over the names of the nodes of any tree.

source

# Phylo.nodenametypeMethod.

nodenametype(::AbstractTree)

Returns type of node names.

source

# Phylo.noderouteMethod.

noderoute(tree::AbstractTree, node1, node2)

Find the node route between two nodes on a tree

source

# Phylo.nodetypeMethod.

nodetype(tree::AbstractTree)

Returns type of nodes in a tree.

source

# Phylo.outdegreeFunction.

outdegree(node::AbstractNode)
outdegree(tree::AbstractTree, nodename)

source

# Phylo.setheight!Method.

setheight!(tree::AbstractTree, nodename, height)

Set the height of the node.

source

# Phylo.setleafinfo!Method.

setleafinfo!(::AbstractTree, label, value)

Set the leaf info for a leaf of the tree.

source

# Phylo.setnoderecord!Method.

setnoderecord(::AbstractTree, label, value)

Set the node record for a node of the tree.

source

# Phylo.setrootheight!Method.

setrootheight!(tree::AbstractTree, height)

source

# Phylo.srcFunction.

src(branch::AbstractBranch)
src(tree::AbstractTree, branchname)

Return the source node for this branch.

source

# Phylo.validateMethod.

validate(tree::AbstractTree)

source