use std::collections::HashMap;
use super::LfqEntry;
pub fn compute_qvalues(entries: &[LfqEntry]) -> HashMap<(usize, usize), f64> {
let mut sorted: Vec<&LfqEntry> = entries.iter().collect();
sorted.sort_by(|a, b| {
b.hybrid_score
.partial_cmp(&a.hybrid_score)
.unwrap_or(std::cmp::Ordering::Equal)
});
let mut n_target = 0usize;
let mut n_decoy = 0usize;
let mut raw: Vec<(usize, usize, f64)> = Vec::new();
for entry in &sorted {
if entry.is_decoy {
n_decoy += 1;
} else {
n_target += 1;
let fdr = if n_target > 0 {
n_decoy as f64 / n_target as f64
} else {
1.0
};
raw.push((entry.feature_idx, entry.run_idx, fdr));
}
}
let mut min_q = 1.0f64;
let mut q_values: HashMap<(usize, usize), f64> = HashMap::new();
for (feat_idx, run_idx, fdr) in raw.iter().rev() {
min_q = min_q.min(*fdr);
q_values.insert((*feat_idx, *run_idx), min_q);
}
q_values
}
#[cfg(test)]
#[path = "tdc_tests.rs"]
mod tests;