#tree-traversal #phylogenetic #bioinformatics

phylo

用Rust编写的可扩展系统发育库

6个版本

0.3.0 2024年8月16日
0.2.4 2024年8月1日
0.2.3 2024年7月24日
0.1.2 2024年7月23日

69生物学 分类中

Download history 213/week @ 2024-07-17 220/week @ 2024-07-24 128/week @ 2024-07-31 9/week @ 2024-08-07 200/week @ 2024-08-14

579 每月下载量

MIT 许可证

110KB
2.5K SLoC

Phylo

Phylo是一个用Rust编写的快速、可扩展、通用且支持WebAssembly的系统发育分析和推理库。Phylo-rs利用Rust提供的内存安全、速度和原生WebAssembly支持,提供了一组健壮的内存高效数据结构,从树操作(如SPR)到计算树统计(如系统发育多样性)的基本算法。

关于实现的说明

在Rust中实现树状结构可能很困难且耗时。此外,实现树遍历和树结构(递归或其他)的操作可能是一项更大的任务。

这个crate旨在将大多数此类方法实现为易于派生的特质,这样您就不必在不必要的地方从头实现它们。

我们还提供了一个结构体,这样您就不必自己实现...

使用phylo

大部分功能都实现在 crate::tree::simple_rtree 中。模块 crate::tree::ops 用于处理需要树变异的群体遗传学分析,如SPR、NNI等。模块 crate::tree::simulation 用于模拟随机树。模块 crate::tree::io 用于从各种编码中读取树。模块 crate::tree::distances 用于计算树中节点之间以及树之间的各种距离。模块 crate::iter 是一个辅助模块,用于提供树遍历和迭代。

构建树

构建树的最简单方法是创建一个空树,添加根节点,然后向各个已添加的节点添加子节点。

use phylo::prelude::*;

let mut tree = SimpleRootedTree::new(1);

let new_node = Node::new(2);
tree.add_child(tree.get_root_id(), new_node);
let new_node = Node::new(3);
tree.add_child(tree.get_root_id(), new_node);
let new_node: Node = Node::new(4);
tree.add_child(2, new_node);
let new_node: Node = Node::new(5);
tree.add_child(2, new_node);

读取和写入树

此库可以构建以 newick 格式编码的树字符串(或文件)。

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())?;

遍历树

实现了几种遍历以按照特定顺序访问节点。遍历返回一个 Iterator,其中包含节点或NodeID的迭代器,按照要访问的顺序排列。

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())?;

let dfs_traversal = tree.dfs(tree.get_root_id()).into_iter();
let bfs_traversal = tree.bfs_ids(tree.get_root_id());
let postfix_traversal = tree.postord_ids(tree.get_root_id());

比较树

为了比较树,实现了考虑拓扑和分支长度的多个指标。

use phylo::prelude::*;

fn depth(tree: &SimpleRootedTree, node_id: usize) -> f32 {
    tree.depth(node_id) as f32
}

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 = SimpleRootedTree::from_newick(newick_1.as_bytes())?;
let tree_2 = SimpleRootedTree::from_newick(newick_2.as_bytes())?;

tree_1.precompute_constant_time_lca();
tree_2.precompute_constant_time_lca();

tree_1.set_zeta(depth);
tree_2.set_zeta(depth);


let rfs = tree_1.rfs(&tree_2);
let wrfs = tree_1.wrfs(&tree_2);
let ca = tree_1.ca(&tree_2);
let cophen = tree_1.cophen_dist_naive(&tree_2, 2);

依赖关系

~3MB
~59K SLoC