#![allow(dead_code)]
use gsva::{io::read_tsv_matrix, ExprMatrix};
pub fn worst_errors(
sets: &[String],
samples: &[String],
scores: &[f64],
reference_tsv: &str,
) -> (f64, f64) {
let reference: ExprMatrix = read_tsv_matrix(reference_tsv);
let ref_col: Vec<usize> = samples
.iter()
.map(|s| {
reference
.col_names()
.iter()
.position(|c| c == s)
.unwrap_or_else(|| panic!("sample '{s}' missing from reference"))
})
.collect();
let nsamp = samples.len();
let mut worst_abs = 0.0f64;
let mut worst_rel = 0.0f64;
for (si, set) in sets.iter().enumerate() {
let rrow = reference
.row_of(set)
.unwrap_or_else(|| panic!("gene set '{set}' missing from reference"));
for j in 0..nsamp {
let a = scores[si * nsamp + j];
let b = reference.get(rrow, ref_col[j]);
let abs = (a - b).abs();
let denom = a.abs().max(b.abs());
let rel = if denom > 0.0 { abs / denom } else { 0.0 };
worst_abs = worst_abs.max(abs);
worst_rel = worst_rel.max(rel);
}
}
(worst_abs, worst_rel)
}
pub fn worst_errors_sign_aligned(
sets: &[String],
samples: &[String],
scores: &[f64],
reference_tsv: &str,
) -> (f64, f64, usize) {
let reference: ExprMatrix = read_tsv_matrix(reference_tsv);
let ref_col: Vec<usize> = samples
.iter()
.map(|s| {
reference
.col_names()
.iter()
.position(|c| c == s)
.unwrap_or_else(|| panic!("sample '{s}' missing from reference"))
})
.collect();
let nsamp = samples.len();
let mut worst_abs = 0.0f64;
let mut worst_rel = 0.0f64;
let mut n_flips = 0usize;
for (si, set) in sets.iter().enumerate() {
let rrow = reference
.row_of(set)
.unwrap_or_else(|| panic!("gene set '{set}' missing from reference"));
let mut best = (f64::INFINITY, 0.0f64, false);
for &flip in &[false, true] {
let mul = if flip { -1.0 } else { 1.0 };
let mut wabs = 0.0f64;
let mut wrel = 0.0f64;
for j in 0..nsamp {
let a = mul * scores[si * nsamp + j];
let b = reference.get(rrow, ref_col[j]);
let abs = (a - b).abs();
let denom = a.abs().max(b.abs());
let rel = if denom > 0.0 { abs / denom } else { 0.0 };
wabs = wabs.max(abs);
wrel = wrel.max(rel);
}
if wabs < best.0 {
best = (wabs, wrel, flip);
}
}
worst_abs = worst_abs.max(best.0);
worst_rel = worst_rel.max(best.1);
if best.2 {
n_flips += 1;
}
}
(worst_abs, worst_rel, n_flips)
}