Phylo
Phylo a fast, extensible, general-purpose, and WebAssembly-capable library for phylogenetic analysis and inference written in Rust. Phylo-rs leverages a combination of memory safety, speed, and native WebAssembly support offered by Rust to provide a robust set of memory-efficient data structures with basic algorithms ranging from tree manipulation with SPR to computing tree statistics such as phylogenetic diversity.
A note on implementation
Implementation of tree-like structures in rust can be difficult and time-intensive. Additionally implementing tree traversals and operations on tree structures (recursive or otherwise) can be an even bigger task.
This crate aims to implement a majority of such methods as easily-derivable traits, so you don't have to implement them from scratch where they are not needed.
We also provide a struct so you don't have to implement one...
Using phylo
Most of the functionality is implemented in [crate::tree::simple_rtree]. The
[crate::tree::ops] module is used to dealt with phylolgenetic analysis that require tree mutations such as SPR, NNI, etc.
[crate::tree::simulation] module is used to simulate random trees
[crate::tree::io] module is used to read trees from various encodings
[crate::tree::distances] module is used to compute various types of distance between nodes in a tree and between trees
[crate::iter] is a helper module to provide tree traversals and iterations.
Building trees
The simplest way to build a tree is to create an empty tree, add a root node and then add children to the various added nodes:
use *;
let mut tree = new;
let new_node = new;
tree.add_child;
let new_node = new;
tree.add_child;
let new_node: Node = new;
tree.add_child;
let new_node: Node = new;
tree.add_child;
Reading and writing trees
This library can build trees strings (or files) encoded in the newick format:
use phylo::prelude::*;
let input_str = String::from("((A:0.1,B:0.2),C:0.6);");
let tree = SimpleRootedTree::from_newick(input_str.as_bytes())?;
Traversing trees
Several traversals are implemented to visit nodes in a particular order. pre-order,
post-order. A traversals returns an [Iterator] of either nodes or NodeID's
in the order they are to be visited in.
use *;
let input_str = Stringfrom;
let tree = from_newick?;
let dfs_traversal = tree.dfs.into_iter;
let bfs_traversal = tree.bfs_ids;
let postfix_traversal = tree.postord_ids;
Comparing trees
A number of metrics taking into account topology and branch lenghts are implemented in order to compare trees with each other:
use *;
let newick_1 = "((A:0.1,B:0.2):0.6,(C:0.3,D:0.4):0.5);";
let newick_2 = "((D:0.3,C:0.4):0.5,(B:0.2,A:0.1):0.6);";
let tree_1 = from_newick?;
let tree_2 = from_newick?;
tree_1.precompute_constant_time_lca;
tree_2.precompute_constant_time_lca;
tree_1.set_zeta;
tree_2.set_zeta;
let rfs = tree_1.rfs;
let wrfs = tree_1.wrfs;
let ca = tree_1.ca;
let cophen = tree_1.cophen_dist_naive;