use tracing::debug;
use crate::annotations::{AnnotationId, OmimDiseaseId, OrphaDiseaseId};
use crate::stats::hypergeom::statrs::Hypergeometric;
use crate::stats::{f64_from_u64, Enrichment, SampleSet};
use crate::HpoTerm;
pub fn omim_disease_enrichment<'a, T, U>(background: T, set: U) -> Vec<Enrichment<OmimDiseaseId>>
where
T: IntoIterator<Item = HpoTerm<'a>>,
U: IntoIterator<Item = HpoTerm<'a>>,
{
let background = SampleSet::omim_disease(background);
let sample_set = SampleSet::omim_disease(set);
inner_disease_enrichment(&background, &sample_set)
}
pub fn orpha_disease_enrichment<'a, T, U>(background: T, set: U) -> Vec<Enrichment<OrphaDiseaseId>>
where
T: IntoIterator<Item = HpoTerm<'a>>,
U: IntoIterator<Item = HpoTerm<'a>>,
{
let background = SampleSet::orpha_disease(background);
let sample_set = SampleSet::orpha_disease(set);
inner_disease_enrichment(&background, &sample_set)
}
#[inline]
fn inner_disease_enrichment<ID: AnnotationId>(
background: &SampleSet<ID>,
sample_set: &SampleSet<ID>,
) -> Vec<Enrichment<ID>> {
let mut res = Vec::new();
for (disease, observed_successes) in sample_set {
if observed_successes == 0 {
debug!("Skipping {}", disease);
continue;
}
let successes = background
.get(&disease)
.expect("disease must be present in background set");
let hyper = Hypergeometric::new(
background.len(),
*successes,
sample_set.len(),
)
.expect("the set must not be larger than the background");
let pvalue = hyper.sf(observed_successes - 1);
let enrichment = (f64_from_u64(observed_successes) / f64_from_u64(sample_set.len()))
/ (f64_from_u64(*successes) / f64_from_u64(background.len()));
res.push(Enrichment::annotation(
disease,
pvalue,
observed_successes,
enrichment,
));
debug!(
"Disease:{}\tPopulation: {}, Successes: {}, Draws: {}, Observed: {}",
disease,
background.len(),
successes,
sample_set.len(),
observed_successes
);
}
res
}