示例#1
0
    def _setup_linked_list(self, kwargs_list):
        last_node = None
        for idx, kwargs in enumerate(kwargs_list):
            new_node = TreeNode(**kwargs)

            if last_node is not None:
                new_node.append(last_node)
            last_node = new_node
        return last_node
示例#2
0
    def _setup_linked_list(self, kwargs_list):
        last_node = None
        for idx, kwargs in enumerate(kwargs_list):
            new_node = TreeNode(**kwargs)

            if last_node is not None:
                new_node.append(last_node)
            last_node = new_node
        return last_node
示例#3
0
 def test_missing_tip_name(self):
     """DndParser should produce the correct tree when missing a name"""
     obs = TreeNode.from_newick(missing_tip_name)
     exp = TreeNode()
     exp.append(TreeNode())
     exp.append(TreeNode())
     exp.children[0].append(TreeNode(name='a'))
     exp.children[0].append(TreeNode(name='b'))
     exp.children[1].append(TreeNode(name='c'))
     exp.children[1].append(TreeNode())
     self.assertEqual(str(obs), str(exp))
示例#4
0
 def test_nonames(self):
     """DndParser should produce the correct tree when there are no names"""
     obs = TreeNode.from_newick(no_names)
     exp = TreeNode()
     exp.append(TreeNode())
     exp.append(TreeNode())
     exp.children[0].append(TreeNode())
     exp.children[0].append(TreeNode())
     exp.children[1].append(TreeNode())
     exp.children[1].append(TreeNode())
     self.assertEqual(str(obs), str(exp))
示例#5
0
 def test_missing_tip_name(self):
     """DndParser should produce the correct tree when missing a name"""
     obs = TreeNode.from_newick(missing_tip_name)
     exp = TreeNode()
     exp.append(TreeNode())
     exp.append(TreeNode())
     exp.children[0].append(TreeNode(name='a'))
     exp.children[0].append(TreeNode(name='b'))
     exp.children[1].append(TreeNode(name='c'))
     exp.children[1].append(TreeNode())
     self.assertEqual(str(obs), str(exp))
示例#6
0
 def test_nonames(self):
     """DndParser should produce the correct tree when there are no names"""
     obs = TreeNode.from_newick(no_names)
     exp = TreeNode()
     exp.append(TreeNode())
     exp.append(TreeNode())
     exp.children[0].append(TreeNode())
     exp.children[0].append(TreeNode())
     exp.children[1].append(TreeNode())
     exp.children[1].append(TreeNode())
     self.assertEqual(str(obs), str(exp))
示例#7
0
 def test_gops(self):
     """Basic TreeNode operations should work as expected"""
     p = TreeNode()
     self.assertEqual(str(p), ';')
     p.name = 'abc'
     self.assertEqual(str(p), 'abc;')
     p.length = 3
     self.assertEqual(str(p), 'abc:3;')  # don't suppress branch from root
     q = TreeNode()
     p.append(q)
     self.assertEqual(str(p), '()abc:3;')
     r = TreeNode()
     q.append(r)
     self.assertEqual(str(p), '(())abc:3;')
     r.name = 'xyz'
     self.assertEqual(str(p), '((xyz))abc:3;')
     q.length = 2
     self.assertEqual(str(p), '((xyz):2)abc:3;')
示例#8
0
 def test_gops(self):
     """Basic TreeNode operations should work as expected"""
     p = TreeNode()
     self.assertEqual(str(p), ';\n')
     p.name = 'abc'
     self.assertEqual(str(p), 'abc;\n')
     p.length = 3
     self.assertEqual(str(p), 'abc:3;\n')  # don't suppress branch from root
     q = TreeNode()
     p.append(q)
     self.assertEqual(str(p), '()abc:3;\n')
     r = TreeNode()
     q.append(r)
     self.assertEqual(str(p), '(())abc:3;\n')
     r.name = 'xyz'
     self.assertEqual(str(p), '((xyz))abc:3;\n')
     q.length = 2
     self.assertEqual(str(p), '((xyz):2)abc:3;\n')
示例#9
0
 def test_minimal(self):
     """DndParser should produce the correct minimal tree"""
     obs = TreeNode.from_newick(minimal)
     exp = TreeNode()
     exp.append(TreeNode())
     self.assertEqual(str(obs), str(exp))
示例#10
0
def walk_copy(node, src):
    """Directionally and recursively copy a tree node and its neighbors.

    Parameters
    ----------
    node : skbio.TreeNode
        node and its neighbors to be copied
    src : skbio.TreeNode
        an upstream node determining the direction of walking (src -> node)

    Returns
    -------
    skbio.TreeNode
        copied node and its neighbors

    Notes
    -----
    After manipulation, `src` will become the parent of `node`, and all other
    neighbors of `node` will become children of it.

    Unlike scikit-bio's `unrooted_copy` function, this function has special
    treatment at root: For an unrooted tree, its "root" will be retained as a
    regular node; for a rooted tree, its root will be deleted, and all basal
    nodes will become immediate children of the basal node where the source is
    located.

    The function determines whether a tree is rooted or unrooted in such way:
    rooted: root has two children; unrooted: root has one or more than two
    children.

    Logic (pseudocode):
    if node is root:
        if tree is rooted:
            raise error
        else:
            if src in node.children:
                append node.other_child
            else:
                raise error
    elif node is basal (i.e., child of root):
        if tree is rooted:
            if src in node.siblings:
                append node.children
            elif src in node.children:
                append node.sibling and node.other_children
            else:
                raise error
        else:
            if src is node.parent (i.e., root):
                append node.children
            elif src in node.children:
                append node.parent and node.other_children
            else:
                raise error
    else: (i.e., node is derived)
        if src is node.parent:
            append node.children
        elif src in node.children:
            append node.parent and node.other_children
        else:
            raise error

    See Also
    --------
    root_above

    Raises
    ------
    ValueError
        if the input node is already a root or if the input node and input
        source node are not neighbors
    """
    parent = node.parent
    children = node.children

    # position of node
    pos = ('root'
           if node.is_root() else 'basal' if parent.is_root() else 'derived')

    # whether tree is rooted
    root = node if pos == 'root' else node.parent if pos == 'basal' else None
    rooted = None if pos == 'derived' else (
        True if len(root.children) == 2 else False)

    if rooted:
        if pos == 'root':
            raise ValueError('Cannot walk from root of a rooted tree.')
        elif pos == 'basal':
            sibling = [x for x in node.siblings()][0]

    # direction of walking
    move = ((
        'bottom' if src is sibling else 'top' if src in children else 'n/a')
            if rooted and pos == 'basal' else
            ('down' if src is parent else 'up' if src in children else 'n/a'))
    if move == 'n/a':
        raise ValueError('Source and node are not neighbors.')

    # create a new node
    res = TreeNode(node.name)

    # determine length of the new node
    res.length = (node.length if move == 'down' else src.length +
                  node.length if move == 'bottom' else src.length)  # up or top

    # determine support of the new node
    res.support = (node.support if move in ('down', 'bottom') else src.support)

    # append children except for src (if applies)
    res.extend([walk_copy(c, node) for c in children if c is not src])

    # append parent if walking up (except at root)
    if move == 'up' and pos != 'root':
        res.append(walk_copy(parent, node))

    # append sibling if walking from one basal node to another
    if move == 'top':
        res.append(walk_copy(sibling, node))

    return res
示例#11
0
 def test_minimal(self):
     """DndParser should produce the correct minimal tree"""
     obs = TreeNode.from_newick(minimal)
     exp = TreeNode()
     exp.append(TreeNode())
     self.assertEqual(str(obs), str(exp))