Useful functions

Copy, convert

To make an independent copy of a tree, simply call copy.

julia> tree = parse_newick_string("((A:1,B:1)AB:2,C:3)R;");
julia> tree_copy = copy(tree);
julia> label!(tree_copy, "A", "Alfred") # relabel node A
julia> tree_copy ________________________ Alfred ______________________________________________| _| |________________________ B | |_______________________________________________________________________ C
julia> tree _________________________ A __________________________________________________| _| |_________________________ B | |____________________________________________________________________________ C

The convert function allows one to change the data type attached to nodes:

julia> typeof(tree)Tree{TreeTools.EmptyData}
julia> data(tree["A"])TreeTools.EmptyData()
julia> tree_with_data = convert(Tree{MiscData}, tree);
julia> typeof(tree_with_data)Tree{MiscData}
julia> data(tree_with_data["A"])["Hello"] = " world!"" world!"

MRCA, divergence time

The most recent common ancestor between two nodes or more is found using the function lca:

julia> lca(tree["A"], tree["B"]) # simplest formNode AB:
Ancestor: R, branch length = 2.0
2 children: ["A", "B"]
julia> lca(tree, "A", "B") # lca(tree, labels...)Node AB: Ancestor: R, branch length = 2.0 2 children: ["A", "B"]
julia> lca(tree, "A", "B", "C") # takes a variable number of labels as inputNode R (root) Ancestor : `nothing` (root) 2 children: ["AB", "C"]
julia> lca(tree, "A", "AB") # This is not restricted to leavesNode AB: Ancestor: R, branch length = 2.0 2 children: ["A", "B"]

To compute the distance or divergence time between two tree nodes, use distance. The topological keyword allows computing the number of branches separating two nodes.

julia> distance(tree, "A", "C")6.0
julia> distance(tree["A"], tree["C"]; topological=true)3.0

The function is_ancestor tells you if one node is found among the ancestors of another. This uses equality between TreeNode, which simply compares labels, see Basic concepts

julia> is_ancestor(tree, "A", "C")false
julia> is_ancestor(tree, "R", "A")true

Tree metrics

Tree height

julia> using TreeTools

julia> tree = parse_newick_string("((A:1,B:1)AB:2,(C:3,D:1)CD:1)R;");

julia> height(tree)
4.0

julia> height(tree; topological=true)  # Count edges instead of branch lengths
2.0

The height function calculates the maximum distance from the root to any leaf. Use topological=true to count the number of edges instead of summing branch lengths.

Tree diameter

diameter returns the longest path between any two leaves.

julia> diameter(tree)
7.0

julia> diameter(tree; topological=true)  # Count edges instead of branch lengths
4.0

Pairwise distance matrix

distance_matrix returns the matrix of pairwise distances between all leaves, arranged in post-order.

julia> D = TreeTools.distance_matrix(tree);

julia> size(D)
(4, 4)

julia> D[1,1]
0.0

Distance between trees

The distance function also lets you compute the distance between two trees. For now, only the Robinson-Foulds distance is implemented, but more could come.

julia> t1 = parse_newick_string("((A,B,D),C);");

julia> t2 = parse_newick_string("((A,(B,D)),C);");

julia> distance(t1, t2)
1

julia> round(distance(t1, t2; normalize=true), sigdigits=2)
0.33