rustalign_aligner/
constraint.rs1use rustalign_common::Score;
4use std::fmt;
5
6#[derive(Debug, Clone, PartialEq, Eq)]
8pub struct Constraint {
9 pub edits: i32,
11
12 pub mms: i32,
14
15 pub ins: i32,
17
18 pub dels: i32,
20
21 pub penalty: Score,
23
24 pub edits_ceil: i32,
27 pub mms_ceil: i32,
29 pub ins_ceil: i32,
31 pub dels_ceil: i32,
33 pub penalty_ceil: Score,
35}
36
37impl Constraint {
38 pub fn new() -> Self {
40 Self {
41 edits: 0,
42 mms: 0,
43 ins: 0,
44 dels: 0,
45 penalty: 0,
46 edits_ceil: i32::MAX,
47 mms_ceil: i32::MAX,
48 ins_ceil: i32::MAX,
49 dels_ceil: i32::MAX,
50 penalty_ceil: Score::MAX,
51 }
52 }
53
54 pub fn satisfied(&self) -> bool {
56 self.edits <= self.edits_ceil
57 && self.mms <= self.mms_ceil
58 && self.ins <= self.ins_ceil
59 && self.dels <= self.dels_ceil
60 && self.penalty <= self.penalty_ceil
61 }
62
63 pub fn add_mismatch(&mut self, penalty: Score) {
65 self.edits += 1;
66 self.mms += 1;
67 self.penalty += penalty;
68 }
69
70 pub fn add_insertion(&mut self, penalty: Score) {
72 self.edits += 1;
73 self.ins += 1;
74 self.penalty += penalty;
75 }
76
77 pub fn add_deletion(&mut self, penalty: Score) {
79 self.edits += 1;
80 self.dels += 1;
81 self.penalty += penalty;
82 }
83}
84
85impl Default for Constraint {
86 fn default() -> Self {
87 Self::new()
88 }
89}
90
91#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
93pub enum SeedType {
94 Exact,
96
97 OneMismatchLeftToRight,
99
100 OneMismatchRightToLeft,
102
103 MultiMismatchInsideOut,
105}
106
107impl fmt::Display for SeedType {
108 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
109 match self {
110 SeedType::Exact => write!(f, "Exact"),
111 SeedType::OneMismatchLeftToRight => write!(f, "1mm_L2R"),
112 SeedType::OneMismatchRightToLeft => write!(f, "1mm_R2L"),
113 SeedType::MultiMismatchInsideOut => write!(f, "MultiMM_IO"),
114 }
115 }
116}
117
118#[derive(Debug, Clone)]
120pub struct SeedPolicy {
121 pub seed_len: usize,
123
124 pub seed_interval: usize,
126
127 pub max_hits: usize,
129
130 pub seed_type: SeedType,
132
133 pub constraints: [Constraint; 3],
135}
136
137impl SeedPolicy {
138 pub fn new() -> Self {
140 Self {
141 seed_len: 22,
144 seed_interval: 10,
145 max_hits: 100,
146 seed_type: SeedType::Exact,
147 constraints: [Constraint::new(), Constraint::new(), Constraint::new()],
148 }
149 }
150
151 pub fn is_valid_seed_pos(&self, read_len: usize, pos: usize) -> bool {
153 pos + self.seed_len <= read_len
154 }
155}
156
157impl Default for SeedPolicy {
158 fn default() -> Self {
159 Self::new()
160 }
161}
162
163#[cfg(test)]
164mod tests {
165 use super::*;
166
167 #[test]
168 fn test_constraint_new() {
169 let c = Constraint::new();
170 assert_eq!(c.edits, 0);
171 assert!(c.satisfied());
172 }
173
174 #[test]
175 fn test_constraint_add_mismatch() {
176 let mut c = Constraint::new();
177 c.add_mismatch(2);
178 assert_eq!(c.edits, 1);
179 assert_eq!(c.mms, 1);
180 assert_eq!(c.penalty, 2);
181 }
182
183 #[test]
184 fn test_seed_policy() {
185 let policy = SeedPolicy::new();
186 assert_eq!(policy.seed_len, 22);
187 assert!(policy.is_valid_seed_pos(100, 50));
188 assert!(policy.is_valid_seed_pos(100, 10)); assert!(!policy.is_valid_seed_pos(25, 10)); }
191}