use crate::collections::{FeatureList, RankedFeatureList};
pub fn compute_population_size(
ranked_feature_list1: &RankedFeatureList,
ranked_feature_list2: &RankedFeatureList,
background: Option<&FeatureList>,
) -> usize {
match background {
None => {
let intersection_size = ranked_feature_list1
.genes()
.intersect(ranked_feature_list2.genes())
.len();
if intersection_size != ranked_feature_list1.len()
|| intersection_size != ranked_feature_list2.len()
{
panic!(
"If no background is provided, the feature lists must have identical genes."
);
}
intersection_size
}
Some(bg) => {
for (ranked_list, list_name) in [
(ranked_feature_list1, "first"),
(ranked_feature_list2, "second"),
] {
let diff = ranked_list.genes().difference(bg, false);
if !diff.is_empty() {
panic!(
"The following genes in the {} ranked feature list are not in the background: {:?}",
list_name,
diff.iter().map(|g| g.id()).collect::<Vec<_>>()
);
}
}
bg.genes().len()
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::collections::{Feature, FeatureList, RankedFeatureList};
#[test]
#[should_panic(
expected = "If no background is provided, the feature lists must have identical genes."
)]
fn test_compute_population_size_no_background_mismatched_lists() {
let features1 = FeatureList::from(vec![
Feature::from("gene1"),
Feature::from("gene2"),
Feature::from("gene3"),
]);
let ranks1 = vec![1, 2, 3];
let ranked_feature_list1 = RankedFeatureList::from(features1, ranks1).unwrap();
let features2 = FeatureList::from(vec![
Feature::from("gene1"),
Feature::from("gene2"),
Feature::from("gene4"), ]);
let ranks2 = vec![1, 2, 3];
let ranked_feature_list2 = RankedFeatureList::from(features2, ranks2).unwrap();
compute_population_size(&ranked_feature_list1, &ranked_feature_list2, None);
}
#[test]
#[should_panic(
expected = "The following genes in the first ranked feature list are not in the background:"
)]
fn test_compute_population_size_missing_genes_in_background_list1() {
let features1 = FeatureList::from(vec![
Feature::from("gene1"),
Feature::from("gene2"),
Feature::from("gene3"),
]);
let ranks1 = vec![1, 2, 3];
let ranked_feature_list1 = RankedFeatureList::from(features1, ranks1).unwrap();
let features2 = FeatureList::from(vec![
Feature::from("gene1"),
Feature::from("gene2"),
Feature::from("gene3"),
]);
let ranks2 = vec![1, 2, 3];
let ranked_feature_list2 = RankedFeatureList::from(features2, ranks2).unwrap();
let background = FeatureList::from(vec![
Feature::from("gene1"),
Feature::from("gene2"),
]);
compute_population_size(
&ranked_feature_list1,
&ranked_feature_list2,
Some(&background),
);
}
#[test]
#[should_panic(
expected = "The following genes in the second ranked feature list are not in the background:"
)]
fn test_compute_population_size_missing_genes_in_background_list2() {
let features1 = FeatureList::from(vec![
Feature::from("gene1"),
Feature::from("gene2"),
Feature::from("gene3"),
]);
let ranks1 = vec![1, 2, 3];
let ranked_feature_list1 = RankedFeatureList::from(features1, ranks1).unwrap();
let features2 = FeatureList::from(vec![
Feature::from("gene1"),
Feature::from("gene2"),
Feature::from("gene4"), ]);
let ranks2 = vec![1, 2, 3];
let ranked_feature_list2 = RankedFeatureList::from(features2, ranks2).unwrap();
let background = FeatureList::from(vec![
Feature::from("gene1"),
Feature::from("gene2"),
Feature::from("gene3"),
]);
compute_population_size(
&ranked_feature_list1,
&ranked_feature_list2,
Some(&background),
);
}
#[test]
fn test_compute_population_size_valid_background() {
let features1 = FeatureList::from(vec![
Feature::from("gene1"),
Feature::from("gene2"),
Feature::from("gene3"),
]);
let ranks1 = vec![1, 2, 3];
let ranked_feature_list1 = RankedFeatureList::from(features1, ranks1).unwrap();
let features2 = FeatureList::from(vec![
Feature::from("gene1"),
Feature::from("gene2"),
Feature::from("gene3"),
]);
let ranks2 = vec![1, 2, 3];
let ranked_feature_list2 = RankedFeatureList::from(features2, ranks2).unwrap();
let background = FeatureList::from(vec![
Feature::from("gene1"),
Feature::from("gene2"),
Feature::from("gene3"),
Feature::from("gene4"), ]);
let population_size = compute_population_size(
&ranked_feature_list1,
&ranked_feature_list2,
Some(&background),
);
assert_eq!(population_size, 4); }
#[test]
fn test_compute_population_size_no_background_identical_lists() {
let features1 = FeatureList::from(vec![
Feature::from("gene1"),
Feature::from("gene2"),
Feature::from("gene3"),
]);
let ranks1 = vec![1, 2, 3];
let ranked_feature_list1 = RankedFeatureList::from(features1, ranks1).unwrap();
let features2 = FeatureList::from(vec![
Feature::from("gene1"),
Feature::from("gene2"),
Feature::from("gene3"),
]);
let ranks2 = vec![1, 2, 3];
let ranked_feature_list2 = RankedFeatureList::from(features2, ranks2).unwrap();
let population_size =
compute_population_size(&ranked_feature_list1, &ranked_feature_list2, None);
assert_eq!(population_size, 3); }
}