From b02364f23bff13a65e642f05e4262699250addc2 Mon Sep 17 00:00:00 2001 From: Jordi Date: Tue, 28 Nov 2023 14:12:36 +0100 Subject: [PATCH] Move t.unroot() to operations.pyx. --- ete4/core/operations.pyx | 15 +++++++++++++++ ete4/core/tree.pyx | 7 +------ 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/ete4/core/operations.pyx b/ete4/core/operations.pyx index 4c063b12..ac7a0ac2 100644 --- a/ete4/core/operations.pyx +++ b/ete4/core/operations.pyx @@ -176,6 +176,21 @@ def join_branch(node): child.up = up +def unroot(tree): + """Unroot the tree (make the root not have 2 children). + + The convention in phylogenetic trees is that if the root has 2 + children, it is a "rooted" tree (the root is a real ancestor). + Otherwise (typically a root with 3 children), the root is just + an arbitrary place to hang the tree. + """ + assert tree.is_root, 'unroot only makes sense from the root node' + if len(tree.children) == 2: + n1, n2 = tree.children + assert not (n1.is_leaf and n2.is_leaf), 'tree has just two leaves' + root_at(n1 if not n1.is_leaf else n2) + + def move(node, shift=1): """Change the position of the current node with respect to its parent.""" # ╴up╶┬╴node -> ╴up╶┬╴sibling diff --git a/ete4/core/tree.pyx b/ete4/core/tree.pyx index 2878bdb0..48c565e0 100644 --- a/ete4/core/tree.pyx +++ b/ete4/core/tree.pyx @@ -1086,12 +1086,7 @@ cdef class Tree(object): Otherwise (typically a root with 3 children), the root is just an arbitrary place to hang the tree. """ - assert self.is_root, 'unroot only makes sense from the root node' - if len(self.children) == 2: - n1, n2 = self.children - if n1.is_leaf and n2.is_leaf: - raise TreeError('cannot unroot a tree with only two leaves') - ops.root_at(n1 if not n1.is_leaf else n2) + ops.unroot(self) def show(self, layout=None, tree_style=None, name="ETE"): """Start an interactive session to visualize the current node."""