#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Strand {
Forward,
Reverse,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum GapKind {
Spanning,
Unknown,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct CoverageGap {
pub start: usize,
pub end: usize,
pub kind: GapKind,
}
impl CoverageGap {
pub fn size(&self) -> usize {
self.end - self.start
}
pub fn min_size(&self) -> Option<usize> {
match self.kind {
GapKind::Spanning => Some(self.end - self.start),
GapKind::Unknown => None,
}
}
}
#[derive(Debug, Clone)]
pub struct BubbleSite {
pub consensus_pos: usize,
pub arm_read_counts: Vec<u32>,
pub arm_sequences: Vec<Vec<u8>>,
pub is_structural: bool,
}
#[derive(Debug, Clone)]
pub struct GraphNodeInfo {
pub node_idx: usize,
pub base: u8,
pub coverage: u32,
pub delete_count: u32,
pub topo_rank: usize,
}
#[derive(Debug, Clone)]
pub struct GraphEdgeInfo {
pub from_rank: usize,
pub to_rank: usize,
pub weight: i32,
}
#[derive(Debug, Clone)]
pub struct GraphTopology {
pub nodes: Vec<GraphNodeInfo>,
pub edges: Vec<GraphEdgeInfo>,
pub spine_ranks: Vec<usize>,
}
#[derive(Debug, Clone, Default)]
pub struct GraphStats {
pub node_count: usize,
pub edge_count: usize,
pub bubble_count: usize,
pub max_bubble_depth: usize,
pub coverage_mean: f64,
pub coverage_variance: f64,
pub edge_weight_gini: f64,
pub single_support_fraction: f64,
pub mean_column_entropy: f64,
pub longest_bubble_span: usize,
pub median_input_read_len: usize,
}
#[derive(Debug, Clone)]
pub struct Consensus {
pub sequence: Vec<u8>,
pub coverage: Vec<u32>,
pub path_weights: Vec<i32>,
pub n_reads: usize,
pub graph_stats: GraphStats,
pub gaps: Vec<CoverageGap>,
pub bubble_sites: Vec<BubbleSite>,
pub read_indices: Vec<usize>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum AdaptiveAction {
PassThrough,
MultiAllele,
TruncationRetry {
recovered: bool,
},
NoisyTighten,
AlternateSeedRetry,
MajorityFrequencyRetry,
SemiGlobalFallback,
}
#[derive(Debug, Clone)]
pub struct AdaptiveResult {
pub consensuses: Vec<Consensus>,
pub action: AdaptiveAction,
}
impl Consensus {
pub fn weight_fraction(&self) -> Vec<f32> {
if self.n_reads == 0 {
return vec![0.0; self.path_weights.len()];
}
self.path_weights
.iter()
.map(|&w| (w as f32 / self.n_reads as f32).clamp(0.0, 1.0))
.collect()
}
}