///|
/// Phylo.Consensus example: Consensus tree building algorithms.
///
/// Run: moon run examples/phylo_consensus_demo/main.mbt
fn main {
println("=== Bio.Phylo.Consensus Demo ===\n")
println("1. Parse Newick format:")
let newick1 = "((A,B),(C,D));"
let tree1 = @bio.newick_to_tree(newick1)
println(" Input: \{newick1}")
match tree1.root {
Some(root) => {
println(" Root: internal node with \{root.children.length()} children")
let leaves = root.get_leaves()
let mut leaves_str = " Leaves: "
let mut i = 0
while i < leaves.length() {
if i > 0 {
leaves_str = leaves_str + ", "
}
leaves_str = leaves_str + leaves[i]
i = i + 1
}
println(leaves_str)
}
None => println(" Failed to parse")
}
println("\n2. Newick roundtrip:")
let tree2 = @bio.newick_to_tree("((A:0.1,B:0.2):0.3,(C:0.4,D:0.5):0.6);")
let newick_out = tree2.to_newick()
println(" Input: ((A:0.1,B:0.2):0.3,(C:0.4,D:0.5):0.6);")
println(" Output: \{newick_out}")
println("\n3. Create example trees:")
let trees = @bio.create_example_trees()
println(" Created \{trees.length()} trees for consensus analysis")
let mut i = 0
while i < trees.length() {
println(" Tree \{i + 1}: \{trees[i].to_newick()}")
i = i + 1
}
println("\n4. Extract splits from tree:")
match trees[0].root {
Some(root) => {
let leaves = root.get_leaves()
let splits = @bio.get_all_splits(root, leaves)
println(" Splits in tree 1: \{splits.length()}")
let mut j = 0
while j < splits.length() {
println(" Split \{j + 1}: \{splits[j].hash()}")
j = j + 1
}
}
None => ()
}
println("\n5. Build Majority Rule Consensus (threshold=0.5):")
let majority = @bio.build_majority_consensus(trees)
println(" Majority consensus tree:")
println(" \{majority.to_newick()}")
println("\n6. Build Strict Consensus (threshold=1.0):")
let strict = @bio.build_strict_consensus(trees)
println(" Strict consensus tree:")
println(" \{strict.to_newick()}")
println("\n7. Build custom threshold consensus:")
let custom = @bio.build_consensus(trees, 0.6)
println(" Consensus with threshold=0.6:")
println(" \{custom.to_newick()}")
println("\n8. Calculate support for specific split:")
let split = @bio.Split::new(["A", "B"])
let support = @bio.calculate_consensus_support(trees, split)
println(" Support for split (A,B): \{support * 100.0}%")
println("\n9. Get all unique splits from trees:")
let all_splits = @bio.get_all_splits_from_trees(trees)
println(" Unique splits across all trees: \{all_splits.length()}")
let mut k = 0
while k < all_splits.length() {
let supp = @bio.calculate_consensus_support(trees, all_splits[k])
println(
" Split \{k + 1}: \{all_splits[k].hash()} (support: \{supp * 100.0}%)",
)
k = k + 1
}
println("\n10. Tree structure visualization:")
match majority.root {
Some(root) => {
println(" Majority consensus tree structure:")
println(root.to_string())
}
None => ()
}
println("\n=== Demo Complete ===")
}