Python ete3 — есть ли способ растянуть ветви филогенетических деревьев?

Я пытаюсь прочитать филогенетическое дерево и растянуть его ветви, чтобы они были больше или меньше оригинала, но я не нашел, как это сделать. Натяжка должна быть на самом дереве, а не на его визуализации.

Например, следующий код считывает дерево и представляет его:

from ete3 import Tree

t = Tree("(2azaa:0.1871453443,1dz0a:0.1944528747,   (((1joi:0.1917345578,1nwpa:0.206793251):0.2050584423,"
     "(1jzga:0.3027313573,1rkra:0.2710518895):0.08148637118):0.06756061176,(1cuoa:0.2959705289,"
     "((1qhqa:0.585997308,1gy1a:2.509606787):0.1590837051,(1kdj:0.9427371887,"
     "((1iuz:0.1918780006,7pcy:0.2035503755):0.1750205426,((2plt:0.2727097306,(2b3ia:0.6259053315,"
     "(((1bawa:0.3036227494,1nin:0.5134587308):0.1375675558,((2raca:0.4617882857,1id2a:0.3274320042):0.7764884063,"
     "(1pmy:0.7017063073,(1bqk:0.2214168026,(1adwa:0.4171298259,1paz:0.4214910379):0.08599165577):0.2074622534):0.9354371144):0.4486761297)"
     ":0.1105387947,(1m9wa:0.4551681561,1bxva:0.3931722476):0.06879588421):0.1131812572):0.4242876607):0.1447393581,"
     "(1plb:0.2176281022,(1byoa:0.2314554253,(9pcy:0.2456728049,(1ag6:0.1776514893,1plc:0.318467746):0.02728470893)"
     ":0.07383541027):0.1260361833):0.2659408726):0.05013755844):0.2637791318):1.001560925):1.018869112):0.4609302267):0.1807238866);")

t.show()

По следующей ссылке обсуждается, как использовать библиотеку, но я не нашел то, что искал:

http://etetoolkit.org/docs/latest/tutorial/tutorial_trees.html

Кто-нибудь может помочь?

Редактировать: если есть другие библиотеки Python, которые могут это сделать, я хотел бы услышать, какие и как это делается.

Edit2: я знаю, что в R есть библиотека с именем «обезьяна», тогда это можно сделать очень просто... может быть, кто-то, кто с ней работает, знает параллельную операцию в какой-то библиотеке python?


person Yair    schedule 15.04.2017    source источник


Ответы (2)


Спустя долгое время я нашел решение: насколько мне известно, в филогенетических библиотеках Python нет встроенных функций для растягивания деревьев. Это очень странно, и я надеюсь, что ошибаюсь.

Однако, как только вы поймете их структуры данных, это будет легко сделать: все, что вам нужно сделать, это просто пробежаться по всем ребрам в деревьях и умножить их на желаемый коэффициент. Это делается по-разному, в зависимости от того, какую библиотеку вы используете. Вот два примера, как растянуть деревья в два раза, используя dendropy и ete3:

from ete3 import Tree
import dendropy as dp

original_tree = "(2azaa:0.1871453443,1dz0a:0.1944528747,(((1joi:0.1917345578,1nwpa:0.206793251):0.2050584423,"\
     "(1jzga:0.3027313573,1rkra:0.2710518895):0.08148637118):0.06756061176,(1cuoa:0.2959705289,"\
     "((1qhqa:0.585997308,1gy1a:2.509606787):0.1590837051,(1kdj:0.9427371887,"\
     "((1iuz:0.1918780006,7pcy:0.2035503755):0.1750205426,((2plt:0.2727097306,(2b3ia:0.6259053315,"\
     "(((1bawa:0.3036227494,1nin:0.5134587308):0.1375675558,((2raca:0.4617882857,1id2a:0.3274320042):0.7764884063,"\
     "(1pmy:0.7017063073,(1bqk:0.2214168026,(1adwa:0.4171298259,1paz:0.4214910379):0.08599165577):0.2074622534):0.9354371144):0.4486761297)"\
     ":0.1105387947,(1m9wa:0.4551681561,1bxva:0.3931722476):0.06879588421):0.1131812572):0.4242876607):0.1447393581,"\
     "(1plb:0.2176281022,(1byoa:0.2314554253,(9pcy:0.2456728049,(1ag6:0.1776514893,1plc:0.318467746):0.02728470893)"\
     ":0.07383541027):0.1260361833):0.2659408726):0.05013755844):0.2637791318):1.001560925):1.018869112):0.4609302267):0.1807238866);"

#dendropy test
print("These are the dendropy results:")
t1 = dp.Tree.get_from_string(original_tree,"newick")
t2 = dp.Tree.get_from_string(original_tree,"newick")
for edge in t2.levelorder_edge_iter():
    if(edge.length == None):
        continue
    edge.length *=2
print(t1)
print(t2)

#ete3 test
print("These are the ete3 results:")
t3 = Tree(original_tree)
t4 = Tree(original_tree)
for node in t4.iter_descendants():
    node.dist*=2
print(t3.write())
print(t4.write())

Еще один урок, который мы можем извлечь из этого случая - всегда делайте домашнее задание по структуре данных, с которой вы работаете, прежде чем искать встроенную функцию...

person Yair    schedule 16.04.2017

Пока я не нашел способ сделать эту растяжку...

Я сделал простой код, который проходит по строке, представляющей дерево, находит числа (которые являются длинами ветвей) и умножает их на 2. Это патч, а не реальное решение... все еще надеюсь, что у кого-то будет идея .

for c in original_tree:
if is_number(c) or c=='.':
    number+=c
else:
    if len(number)<5:
        stretched_tree+=number
        number=""
    elif number!="":
        stretched_tree+=str(float(number)*2)
        number = ""
    stretched_tree+=c
person Yair    schedule 15.04.2017