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 科学

Download history 2/week @ 2024-05-16 1/week @ 2024-05-23 114/week @ 2024-06-06 233/week @ 2024-06-13 44/week @ 2024-06-20 3/week @ 2024-06-27 18/week @ 2024-07-04 122/week @ 2024-07-11 29/week @ 2024-07-25 16/week @ 2024-08-01

182 每月下载量
用于 viguno

MIT 许可证

2MB
6K SLoC

HPO

这个库是 PyHPO 的 Rust 实现。

这是什么?

HPO,即 人类表型本体,是人类疾病表型异常的标准词汇。它是一个本体,因此所有术语都相互连接,类似于有向图。

这个库提供了方便的 API 来与本体一起工作。主要目标是比较术语或术语集合,并运行富集分析统计。

特性

  • 计算 HPO 术语的相似度
  • 计算多个 HPO 术语集合的相似度(例如患者的临床信息)
  • 在 HPO 术语集合中对基因和疾病进行富集分析
  • 比较不同的 HPO 版本
  • 本体的基于图的分析
  • 完全用 Rust 编写,因此它非常快(基准

当前状态是什么?

库的功能基本上是完整的,至少对我来说是这样的。如果您有任何功能请求,请提出 Issue 或联系我。我非常希望得到反馈和新想法,以改进此项目。

API 主要稳定,但我可能会对某些部分进行重构,以使其更容易使用并提高性能。

如果您对这个项目感兴趣并希望贡献,请与我联系,我确实需要一些帮助。

文档

公共 API 在 docs.rs 上进行了完全文档化。

hpo 中使用的主要结构体

  • Ontologyhpo 中的主要结构体和入口点。
  • HpoTerm 表示单个 HPO 术语,并包含大量与之相关的功能。
  • HpoSetHpoTerm 的集合,如患者的临床信息。
  • Gene 表示单个基因,包括关联的 HpoTerm 信息。
  • OmimDisease 表示单个 OMIM 疾病,包括关联的 HpoTerm 信息。
  • OrphaDisease 表示单个 ORPHA 疾病,包括关联的 HpoTerm 信息。

最相关的模块有

  • annotations 包含了 GeneOmimDiseaseOrphaDisease 结构体以及一些相关的类型。
  • similarity 包含了用于比较 HpoTermHpoSet 相似性的结构体和辅助函数。
  • stats 包含计算基因或疾病的超几何富集分数的函数。

示例

一些(或多或少随机)的示例包含在 examples 文件夹 中。

首先需要从 Jax HPO 本身下载 HPO 数据。你需要以下文件

  • phenotype.hpoa,作为“下载 HPO 注释”提供(将 OmimDisease 连接到 HpoTerm 所必需)
  • genes_to_phenotype.txt,作为“基因到表型”提供(将 Gene 连接到 HpoTerm 所必需)
  • hp.obo(将 HpoTerm 及其相互连接所需)
  1. 可以直接从代码中通过 Ontology::from_standard 加载数据
    use hpo::Ontology;
    let ontology = Ontology::from_standard("/path/to/master-data/").unwrap();
  1. 或者通过复制 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();
  1. 另一种可能性是使用来自此 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.0Python 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

技术设计

有关实现计划的详细信息,请参阅技术设计文档

依赖关系