use spoars::align::{Alignment, AlignmentEngine, AlignmentType, Scoring, SisdEngine};
use spoars::graph::Graph;
use super::oracle::{AlignType, OracleCase};
fn alignment_type_from(ty: AlignType) -> AlignmentType {
match ty {
AlignType::Sw => AlignmentType::Local,
AlignType::Nw => AlignmentType::Global,
AlignType::Ov => AlignmentType::Overlap,
}
}
pub fn run_spoars(case: &OracleCase) -> (Vec<Alignment>, String) {
let scoring = Scoring::new(case.m, case.n, case.g, case.e, case.q, case.c)
.expect("run_spoars: Scoring::new rejected the oracle case's penalties");
let mut engine = SisdEngine::new(alignment_type_from(case.ty), scoring);
let mut graph = Graph::new();
let mut alignments = Vec::with_capacity(case.seqs.len());
for (i, seq) in case.seqs.iter().enumerate() {
let bytes = seq.as_bytes();
let (alignment, _score) = engine.align(bytes, &graph);
alignments.push(alignment.clone());
if let Some(quals) = &case.quals {
graph
.add_alignment_quality(&alignment, bytes, quals[i].as_bytes())
.unwrap_or_else(|e| {
panic!("run_spoars: add_alignment_quality failed (seq {i}): {e}")
});
} else {
graph
.add_alignment_weight(&alignment, bytes, 1)
.unwrap_or_else(|e| {
panic!("run_spoars: add_alignment_weight failed (seq {i}): {e}")
});
}
}
let consensus = graph.generate_consensus_min_coverage(case.min_coverage);
(alignments, consensus)
}