-
Notifications
You must be signed in to change notification settings - Fork 61
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: vote for split node's clade to prevent mismatch
After the query node placement is adjusted during the [greedy tree building](https://docs.nextstrain.org/projects/nextclade/en/stable/user/algorithm/03-phylogenetic-placement.html#tree-building), sometimes the branch needs to be split and a new internal node inserted. Currently we copy the clade of this internal node from the attachment target node. However, this is not always correct and can lead to mismatch between clade of the query node and of the new internal node. Here I add a voting mechanism (simply a mode) between clades involved: of the parent, target and query nodes.
- Loading branch information
1 parent
ee51953
commit 4581a12
Showing
3 changed files
with
39 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
use itertools::Itertools; | ||
use std::hash::Hash; | ||
|
||
/// Calculate mode (the most frequently occurring element) of an iterator. | ||
/// In case of a tie, the first occurrence is returned. Returns `None` if the iterator is empty. | ||
pub fn mode<T: Hash + Eq + Clone>(items: impl IntoIterator<Item = T>) -> Option<T> { | ||
items | ||
.into_iter() | ||
.counts() | ||
.into_iter() | ||
.max_by_key(|&(_, count)| count) | ||
.map(|(item, _)| item) | ||
} |