use crate::{utils::recode_index, ResultsRRA};
use adjustp::Procedure;
use hashbrown::HashMap;
use ndarray::Array1;
use super::{
filter_alpha, group_sizes, normed_ranks,
permutations::run_permutations,
robust_rank::robust_rank_aggregation,
utils::{empirical_cdf, encode_index, select_ranks},
};
fn gene_rra(
current_idx: usize,
encodings: &[usize],
nranks: &Array1<f64>,
permutation_vectors: &HashMap<usize, Array1<f64>>,
alpha: f64,
) -> (f64, f64) {
let gene_ranks = select_ranks(current_idx, encodings, nranks);
let filtered = filter_alpha(&gene_ranks, alpha);
let score = robust_rank_aggregation(&filtered, gene_ranks.len());
(
score,
empirical_cdf(
score,
permutation_vectors
.get(&gene_ranks.len())
.expect("Unexpected missing key"),
),
)
}
fn generate_permutation_vectors(
n_genes: usize,
alpha: f64,
npermutations: usize,
sizes: &Vec<usize>,
) -> HashMap<usize, Array1<f64>> {
sizes
.iter()
.map(|unique_size| {
(
*unique_size,
run_permutations(n_genes, alpha, npermutations, *unique_size),
)
})
.map(|(u, v)| (u, Array1::from_vec(v)))
.collect::<HashMap<usize, Array1<f64>>>()
}
fn calculate_empirical_pvalues(
n_genes: usize,
encode: &[usize],
nranks: &Array1<f64>,
permutation_vectors: &HashMap<usize, Array1<f64>>,
alpha: f64,
) -> (Array1<f64>, Array1<f64>) {
let mut scores = Array1::zeros(n_genes);
let mut pvalues = Array1::zeros(n_genes);
(0..n_genes).for_each(|curr| {
let (score, pvalue) = gene_rra(curr, &encode, &nranks, &permutation_vectors, alpha);
scores[curr] = score;
pvalues[curr] = pvalue;
});
(scores, pvalues)
}
#[must_use]
pub fn alpha_rra(
pvalues: &Array1<f64>,
genes: &[String],
alpha: f64,
npermutations: usize,
correction: Procedure,
) -> ResultsRRA {
let (encode_map, encode) = encode_index(genes);
let n_genes = encode_map.len();
let nranks = normed_ranks(pvalues);
let sizes = group_sizes(&encode);
let num_permutations = npermutations * n_genes;
let permutation_vectors =
generate_permutation_vectors(n_genes, alpha, num_permutations, &sizes);
let (scores, pvalues) =
calculate_empirical_pvalues(n_genes, &encode, &nranks, &permutation_vectors, alpha);
let names = recode_index(n_genes, &encode_map);
ResultsRRA::new(names, scores, pvalues, correction)
}