How to make a rooted tree ultrametric
2
3
Entering edit mode
7.6 years ago
nancydong20 ▴ 130

Hello all!

I have used OrthoFinder to identify orthogroups among five species. Part of the output is a rooted phylogenetic tree, but I think it is not ultrametric?

I would like to use the tree as part of the input for a CAFE analysis. The CAFE tutorial described using the program r8s to make a tree ultrametric, but I don't know the number of sites in the alignment used to estimate the species tree. TimeTree has approximate divergence time for some of the species in my tree, which I can use to calibrate the tree?

Any suggestions on how I can create an ultrametric phylogenetic tree would be greatly appreciated!

Nancy

Phylogenetic tree ultrametric CAFE • 12k views
ADD COMMENT
5
Entering edit mode
7.6 years ago

If you are familiar with Python you can convert a rooted tree into ultrametric topology (all leaves will have the same distance to root) using ETE Toolkit 2-3.

from ete2 import Tree

t = Tree('(A:1,(B:1,(C:1,D:1):0.5):0.5);')
# Root tree at B node.
t.set_outgroup('B')  

print('Non-ultrametric rooted tree:')
print(t.write())

t.convert_to_ultrametric()
print('Ultrametric rooted tree:')
print(t.write())

Output:

Non-ultrametric rooted tree:
(B:0.5,((C:1,D:1)1:0.5,A:1.5)1:0.5);

Ultrametric rooted tree:
(B:2,((C:0.666667,D:0.666667)1:0.666667,A:1.33333)1:0.666667);
ADD COMMENT
0
Entering edit mode

Thank you very much for your response!

This toolkit looks very helpful! I will study up on it.

ADD REPLY
0
Entering edit mode

Hi

Thank you for this solution. However, is there also a way to scale the branch lengths into time units (similar to what the r8S or pathD8 program does). If for example the divergence time ("cal" in pathD8, see example below) between B and D (e.g. 50 MYA) and the number of sites of the alignment ("seql" in pathD8, see example below) that was used to create the tree is known, then rescale the branch lengths to time units (see example below with pathD8 (which I can no longer run on OSX))?

Regards

Wannes

#

pathD8 example in R at https://rdrr.io/github/heibl/ips/man/pathd8.html :

cal <- rbind(cal1 = c("Rat", "Ostrich", "minage", 260), 
             cal2 = c("Human", "Platypus", "fixage", 125),
             cal3 = c("Alligator", "Ostrich", "minage", 150))
colnames(cal) = c("tax1", "tax2", "age_type", "age")
phy <- read.tree(text = "((((Rat:0.007148,Human:0.001808):0.024345,Platypus:0.016588):0.012920,(Ostrich:0.018119,Alligator:0. 006232):0.004708):0.028037,Frog:0);")
seql <- 1823
pathd8(phy, exec = "/Applications/PATHd8", seql = seql, calibration = cal)
ADD REPLY
0
Entering edit mode

Hi, Nancy Have you solved this? I am encountering the same problem. Fei

ADD REPLY
0
Entering edit mode

Hey there. I tried to use ete3's convert to ultra metric function and it runs and produces output but according to CRAN the output is not really ultra metric. I am using the following code: from ete3 import Tree

def main():

    with open('15.tree','r') as file:
        file_line = file.readlines()

    t = file_line[0]

    the_tree = Tree(t)

    the_tree.set_outgroup('HAEU') 

    the_tree.convert_to_ultrametric()

    print(the_tree.write())

main()

The tree that I am trying to convert is here https://mab.to/HsTDNMGBe

And the tree that the above code produces is: https://mab.to/XYy7cGP2s

And according to CRAN ape the output is not ultra metric.

The code to test if a given tree is ultrametric or not in Rlang is:

library("ape") # works best if installed with anaconda
library("TreeTools") # works best if installed with anaconda
tree <- read.tree('ultra_but_with_negative_lengths/15.tree.ultra')
is.ultrametric(tree)

I realize your answer is old so the safe guess probably is that ete is outdated but in just in case you might still be using ete toolkit, do you know what might be going on? My best guess is that there is a specific method to set the outgroup?

ADD REPLY
0
Entering edit mode
5.1 years ago
alslonik ▴ 320

I used function from here: http://blog.phytools.org/2017/03/forceultrametric-method-for-ultrametric.html

for the same purpose - using cafe with the output of Orthofinder. Basically the code looked like this:

library(phytools)
library(phangorn) 

tree_orthofinder = read.newick(file = "SpeciesTree_rooted_node_labels.txt",text)

force.ultrametric<-function(tree,method=c("nnls","extend")){
    method<-method[1]
    if(method=="nnls") tree<-nnls.tree(cophenetic(tree),tree,
        rooted=TRUE,trace=0)
    else if(method=="extend"){
        h<-diag(vcv(tree))
        d<-max(h)-h
        ii<-sapply(1:Ntip(tree),function(x,y) which(y==x),
            y=tree$edge[,2])
        tree$edge.length[ii]<-tree$edge.length[ii]+d
    } else 
        cat("method not recognized: returning input tree\n\n")
    tree
}

tree_orthofinder_ultra = force.ultrametric(tree_orthofinder)
write.tree(tree_orthofinder_ultra, file = "tree_ultrametric.txt", append = FALSE, digits = 10, tree.names = FALSE)
is.ultrametric(tree_orthofinder_ultra)
ADD COMMENT
0
Entering edit mode

Have you used this method recently? For some reason this code produces tress that are ultra metric but the output trees have negative lengths!

do you know what could cause something like that?

ADD REPLY

Login before adding your answer.

Traffic: 1375 users visited in the last hour
Help About
FAQ
Access RSS
API
Stats

Use of this site constitutes acceptance of our User Agreement and Privacy Policy.

Powered by the version 2.3.6