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 |
技术设计
有关实现计划的详细信息,请参阅技术设计文档