mirror of
https://github.com/biopython/biopython.git
synced 2025-10-20 13:43:47 +08:00
Fix calculating height of clades when building UPGMA tree version 2 (#3951)
* Fixed a bug in calculating the height of clades when building a UPGMA tree * added my name to contrib.rst alphabetically * minor corrections * formatting changes * Add tests --------- Co-authored-by: She Zhang <shz66@pitt.edu> Co-authored-by: Fabian Egli <fabianegli@users.noreply.github.com> Co-authored-by: Eric Talevich <etal@users.noreply.github.com>
This commit is contained in:
@ -745,15 +745,8 @@ class DistanceTreeConstructor(TreeConstructor):
|
|||||||
inner_clade.clades.append(clade1)
|
inner_clade.clades.append(clade1)
|
||||||
inner_clade.clades.append(clade2)
|
inner_clade.clades.append(clade2)
|
||||||
# assign branch length
|
# assign branch length
|
||||||
if clade1.is_terminal():
|
clade1.branch_length = min_dist * 1.0 / 2 - self._height_of(clade1)
|
||||||
clade1.branch_length = min_dist / 2
|
clade2.branch_length = min_dist * 1.0 / 2 - self._height_of(clade2)
|
||||||
else:
|
|
||||||
clade1.branch_length = min_dist / 2 - self._height_of(clade1)
|
|
||||||
|
|
||||||
if clade2.is_terminal():
|
|
||||||
clade2.branch_length = min_dist / 2
|
|
||||||
else:
|
|
||||||
clade2.branch_length = min_dist / 2 - self._height_of(clade2)
|
|
||||||
|
|
||||||
# update node list
|
# update node list
|
||||||
clades[min_j] = inner_clade
|
clades[min_j] = inner_clade
|
||||||
@ -876,11 +869,11 @@ class DistanceTreeConstructor(TreeConstructor):
|
|||||||
|
|
||||||
def _height_of(self, clade):
|
def _height_of(self, clade):
|
||||||
"""Calculate clade height -- the longest path to any terminal (PRIVATE)."""
|
"""Calculate clade height -- the longest path to any terminal (PRIVATE)."""
|
||||||
height = 0
|
|
||||||
if clade.is_terminal():
|
if clade.is_terminal():
|
||||||
height = clade.branch_length
|
height = 0
|
||||||
else:
|
else:
|
||||||
height = height + max(self._height_of(c) for c in clade.clades)
|
height = max(self._height_of(c) + c.branch_length for c in clade.clades)
|
||||||
|
|
||||||
return height
|
return height
|
||||||
|
|
||||||
|
|
||||||
|
@ -300,6 +300,7 @@ please open an issue on GitHub or mention it on the mailing list.
|
|||||||
- Sergei Lebedev <https://github.com/superbobry>
|
- Sergei Lebedev <https://github.com/superbobry>
|
||||||
- Sergio Valqui <https://github.com/svalqui>
|
- Sergio Valqui <https://github.com/svalqui>
|
||||||
- Seth Sims <seth.sims at gmail>
|
- Seth Sims <seth.sims at gmail>
|
||||||
|
- She Zhang <https://github.com/shz66>
|
||||||
- Shoichiro Kawauchi <https://github.com/lacrosse91>
|
- Shoichiro Kawauchi <https://github.com/lacrosse91>
|
||||||
- Shuichiro MAKIGAKI <https://github.com/shuichiro-makigaki>
|
- Shuichiro MAKIGAKI <https://github.com/shuichiro-makigaki>
|
||||||
- Shyam Saladi <https://github.com/smsaladi>
|
- Shyam Saladi <https://github.com/smsaladi>
|
||||||
|
@ -9,6 +9,7 @@ import os
|
|||||||
import tempfile
|
import tempfile
|
||||||
import unittest
|
import unittest
|
||||||
from io import StringIO
|
from io import StringIO
|
||||||
|
from itertools import combinations
|
||||||
|
|
||||||
from Bio import Align
|
from Bio import Align
|
||||||
from Bio import AlignIO
|
from Bio import AlignIO
|
||||||
@ -232,7 +233,13 @@ class DistanceTreeConstructorTest(unittest.TestCase):
|
|||||||
# Phylo.write(tree, tree_file, 'newick')
|
# Phylo.write(tree, tree_file, 'newick')
|
||||||
ref_tree = Phylo.read("./TreeConstruction/upgma.tre", "newick")
|
ref_tree = Phylo.read("./TreeConstruction/upgma.tre", "newick")
|
||||||
self.assertTrue(Consensus._equal_topology(tree, ref_tree))
|
self.assertTrue(Consensus._equal_topology(tree, ref_tree))
|
||||||
# ref_tree.close()
|
# check for equal distance of all terminal nodes from the root
|
||||||
|
ref_tree.root_at_midpoint()
|
||||||
|
for len1, len2 in combinations(
|
||||||
|
[depth for node, depth in ref_tree.depths().items() if node.is_terminal()],
|
||||||
|
2,
|
||||||
|
):
|
||||||
|
self.assertAlmostEqual(len1, len2)
|
||||||
|
|
||||||
def test_nj_msa(self):
|
def test_nj_msa(self):
|
||||||
tree = self.constructor.nj(self.dm_msa)
|
tree = self.constructor.nj(self.dm_msa)
|
||||||
|
Reference in New Issue
Block a user