23 个版本
| 0.10.1 | 2024年6月15日 |
|---|---|
| 0.9.1 | 2024年3月30日 |
| 0.8.1 | 2023年6月25日 |
| 0.6.1 | 2023年3月30日 |
| 0.2.0 | 2022年12月27日 |
#23 in 科学
182 每月下载量
用于 viguno
2MB
6K SLoC
HPO
这个库是 PyHPO 的 Rust 实现。
这是什么?
HPO,即 人类表型本体,是人类疾病表型异常的标准词汇。它是一个本体,因此所有术语都相互连接,类似于有向图。
这个库提供了方便的 API 来与本体一起工作。主要目标是比较术语或术语集合,并运行富集分析统计。
特性
- 计算 HPO 术语的相似度
- 计算多个 HPO 术语集合的相似度(例如患者的临床信息)
- 在 HPO 术语集合中对基因和疾病进行富集分析
- 比较不同的 HPO 版本
- 本体的基于图的分析
- 完全用 Rust 编写,因此它非常快(基准)
当前状态是什么?
库的功能基本上是完整的,至少对我来说是这样的。如果您有任何功能请求,请提出 Issue 或联系我。我非常希望得到反馈和新想法,以改进此项目。
API 主要稳定,但我可能会对某些部分进行重构,以使其更容易使用并提高性能。
如果您对这个项目感兴趣并希望贡献,请与我联系,我确实需要一些帮助。
文档
公共 API 在 docs.rs 上进行了完全文档化。
hpo 中使用的主要结构体
Ontology是hpo中的主要结构体和入口点。HpoTerm表示单个 HPO 术语,并包含大量与之相关的功能。HpoSet是HpoTerm的集合,如患者的临床信息。Gene表示单个基因,包括关联的HpoTerm信息。OmimDisease表示单个 OMIM 疾病,包括关联的HpoTerm信息。OrphaDisease表示单个 ORPHA 疾病,包括关联的HpoTerm信息。
最相关的模块有
annotations包含了Gene、OmimDisease和OrphaDisease结构体以及一些相关的类型。similarity包含了用于比较HpoTerm和HpoSet相似性的结构体和辅助函数。stats包含计算基因或疾病的超几何富集分数的函数。
示例
一些(或多或少随机)的示例包含在 examples 文件夹 中。
首先需要从 Jax HPO 本身下载 HPO 数据。你需要以下文件
- phenotype.hpoa,作为“下载 HPO 注释”提供(将
OmimDisease连接到HpoTerm所必需) - genes_to_phenotype.txt,作为“基因到表型”提供(将
Gene连接到HpoTerm所必需) - hp.obo(将
HpoTerm及其相互连接所需)
- 可以直接从代码中通过
Ontology::from_standard加载数据
use hpo::Ontology;
let ontology = Ontology::from_standard("/path/to/master-data/").unwrap();
- 或者通过复制
examples/obo_to_bin.rs到你的项目中,然后运行。使用以下命令:cargo run --example --release obo_to_bin <包含 JAX 数据的文件夹路径> <输出文件名>最后,使用Ontology::from_binary加载数据
use hpo::Ontology;
let ontology = Ontology::from_binary("your-hpo-binary.hpo").unwrap();
- 另一种可能性是使用来自此 crate 的 Github 仓库 的快照,该快照包含本体论的二进制构建 https://github.com/anergictcell/hpo/blob/main/tests/ontology.hpo。它可能不会总是最新的,所以请自行核实。
本体
use hpo::{Ontology, HpoTermId};
use hpo::annotations::{GeneId, OmimDiseaseId, OrphaDiseaseId};
fn example() {
let ontology = Ontology::from_standard("/path/to/master-data/").unwrap();
// iterate HPO terms
for term in &ontology {
// do something with term
}
// iterate Genes
for gene in ontology.genes() {
// do something with gene
}
// iterate omim diseases
for disease in ontology.omim_diseases() {
// do something with disease
}
// iterate orpha diseases
for disease in ontology.orpha_diseases() {
// do something with disease
}
// get a single HPO term using HPO ID
let hpo_id = HpoTermId::try_from("HP:0000123").unwrap();
let term = ontology.hpo(hpo_id);
// get a single HPO term using `u32` part of HPO ID
let term = ontology.hpo(123u32);
// get a single Omim disease
let disease_id = OmimDiseaseId::from(12345u32);
let disease = ontology.omim_disease(&disease_id);
// get a single Orpha disease
let disease_id = OrphaDiseaseId::from(12345u32);
let disease = ontology.orpha_disease(&disease_id);
// get a single Gene
let hgnc_id = GeneId::from(12345u32);
let gene = ontology.gene(&hgnc_id);
// get a single Gene by its symbol
let gene = ontology.gene_by_name("GBA");
}
HPO 术语
use hpo::Ontology;
fn example() {
let ontology = Ontology::from_binary("/path/to/binary.hpo").unwrap();
let term = ontology.hpo(123u32).unwrap();
assert_eq!("Abnormality of the nervous system", term.name());
assert_eq!("HP:000123".to_string(), term.id().to_string());
// iterate all parents
for p in term.parents() {
println!("{}", p.name())
}
// iterate all children
for p in term.children() {
println!("{}", p.name())
}
let term2 = ontology.hpo(1u32).unwrap();
assert!(term2.parent_of(&term));
assert!(term.child_of(&term2));
}
相似性
use hpo::Ontology;
use hpo::similarity::GraphIc;
use hpo::term::InformationContentKind;
fn example() {
let ontology = Ontology::from_binary("/path/to/binary.hpo").unwrap();
let term1 = ontology.hpo(123u32).unwrap();
let term2 = ontology.hpo(1u32).unwrap();
let ic = GraphIc::new(InformationContentKind::Omim);
let similarity = term1.similarity_score(&term2, &ic);
}
富集
识别哪些基因(或疾病)在 HpoTerms 集合中富集,例如在患者的临床信息或患者队列中
use hpo::Ontology;
use hpo::{HpoSet, term::HpoGroup};
use hpo::stats::hypergeom::gene_enrichment;
fn example() {
let ontology = Ontology::from_binary("/path/to/binary.hpo").unwrap();
let mut hpos = HpoGroup::new();
hpos.insert(2943u32);
hpos.insert(8458u32);
hpos.insert(100884u32);
hpos.insert(2944u32);
hpos.insert(2751u32);
let patient_ci = HpoSet::new(&ontology, hpos);
let mut enrichments = gene_enrichment(&ontology, &patient_ci);
// the results are not sorted by default
enrichments.sort_by(|a, b| {
a.pvalue().partial_cmp(&b.pvalue()).unwrap()
});
for gene in enrichments {
println!("{}\t{}\t({})", gene.id(), gene.pvalue(), gene.enrichment());
}
}
基准
俗话说:“先做出来,再做的好,最后做得快”。工作和好的部分已在PyHPO中实现。尽管我尽力使其快,但我仍然渴望更多。因此,我在2022年12月开始开发hpo Rust库。即使在没有像为PyHPO那样进行微基准测试和性能调优的情况下,hpo现在确实已经快得多。
以下基准测试是在非科学条件下运行的,您的结果可能会有所不同。我使用了MacBook Air M1,rustc 1.68.0,Python 3.9和/usr/bin/time进行计时。
| 基准测试 | PyHPO |
hpo(单线程) |
hpo(多线程) |
|---|---|---|---|
| 读取和解析本体 | 6.4秒 | 0.22秒 | 0.22秒 |
| 17,245 x 1,000个术语的相似度 | 98.5秒 | 4.6秒 | 1.0秒 |
| GBA1与所有疾病的相似度 | 380秒 | 15.8秒 | 3.0秒 |
| 所有基因中的疾病富集 | 11.8秒 | 0.4秒 | 0.3秒 |
| 17,245 x 10,000个术语的公共祖先 | 225.2秒 | 10.5 | 2.1 |
技术设计
有关实现计划的详细信息,请参阅技术设计文档