use crate::alignment::phmm::{
LayerParams, PhmmNumber,
indexing::SeqIndex,
state::{PhmmState, PhmmStateOrEnter, best_state},
};
mod domain;
mod global;
mod local;
mod semilocal;
#[inline]
#[must_use]
fn update_insert<T: PhmmNumber, const S: usize>(
layer: &LayerParams<T, S>, x_idx: usize, mut match_val: T, mut delete_val: T, mut insert_val: T,
) -> (PhmmState, T) {
use crate::alignment::phmm::state::PhmmState::*;
match_val += layer.transition[(Match, Insert)];
delete_val += layer.transition[(Delete, Insert)];
insert_val += layer.transition[(Insert, Insert)];
let (state, best) = best_state(match_val, delete_val, insert_val);
(state, best + layer.emission_insert[x_idx])
}
#[inline]
#[must_use]
fn update_delete<T: PhmmNumber, const S: usize>(
layer: &LayerParams<T, S>, mut match_val: T, mut delete_val: T, mut insert_val: T,
) -> (PhmmState, T) {
use crate::alignment::phmm::state::PhmmState::*;
match_val += layer.transition[(Match, Delete)];
delete_val += layer.transition[(Delete, Delete)];
insert_val += layer.transition[(Insert, Delete)];
best_state(match_val, delete_val, insert_val)
}
struct ViterbiTraceback<T> {
data: Vec<T>,
cols: usize,
}
impl<T: Clone> ViterbiTraceback<T> {
#[inline]
#[must_use]
pub fn new(default: T, query_dim: usize, phmm_dim: usize) -> Self {
Self {
data: vec![default; query_dim * phmm_dim],
cols: query_dim,
}
}
}
impl<T> ViterbiTraceback<T> {
#[inline]
#[must_use]
pub fn get(&self, i: usize, j: usize) -> &T {
&self.data[self.cols * j + i]
}
#[inline]
#[must_use]
#[allow(dead_code)]
pub fn get_mut(&mut self, i: usize, j: usize) -> &mut T {
&mut self.data[self.cols * j + i]
}
#[inline]
#[must_use]
#[allow(dead_code)]
pub fn get_rows_mut(&mut self, j: usize) -> (&mut [T], &mut [T]) {
let start = self.cols * j;
self.data[start..2 * self.cols].split_at_mut(start + self.cols)
}
}
#[derive(Clone, Copy)]
enum ExitLocation {
Begin,
Match(SeqIndex),
End(PhmmStateOrEnter),
}