1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/// A pre-alignment filter based upon [Sneaky Snake] (1) which will reject
/// queries exceeding a given edit distance from the reference.
///
/// The `threshold` is defined as a decimal between 0.0 and 1.0, representing a
/// proportion of the query length. For example, a threshold of 0.2 for a query
/// of length 100 will reject any query with more than 20 edits (insertions,
/// deletions, or substitutions) compared to the reference.
///
/// Returns `Some(true)` if number of edits between query and reference is
/// within the provided threshold. Returns `Some(false)` if number of edits
/// between query and reference exceeds the provided threshold. Returns `None`
/// if inputs are invalid.
///
/// ## Limitations
///
/// - The provided edit distance threshold must be greater than or equal to the
/// difference in length between the reference and the query. Returns `None`
/// otherwise.
/// - Although Sneaky Snake is designed for sequences of the same length, this
/// implementation is able to handle sequences of slightly different lengths
/// (following the above requirement that the length difference is less than
/// the edit distance threshold). The excess residues at either end of the
/// longer sequence are not penalized. More specifically, if the reference is
/// $\Delta$ residues longer than the query, the algorithm supports up to
/// $\Delta$ unpenalized residues at either end of the reference. Note that
/// this is not the same as semiglobal edit distance, since only $\Delta$
/// unpenalized residues are supported instead of arbitrarily many. Rather,
/// this algorithm is a relaxation of global edit distance, designed to not
/// overly penalize sequences with different lengths.
/// - The filter calculates an approximated edit distance value that is very
/// close to the actual edit distance. Its calculated edit distance is always
/// less than or equal to the actual edit distance and then compares to the
/// provided threshold.
///
/// ## Time Complexity
///
/// $N$ is the length of the shorter sequence and $E$ is the edit distance
/// threshold.
///
/// - When the true number of edits is close to the threshold, the worst case
/// time complexity approaches $ \mathcal{O}(N * E) $.
///
/// - When the sequences are nearly identical and when enough of the sequence
/// has been examined and cannot possibly get filtered out with the remaining
/// length, the best case time complexity approaches $ \Omega(N - E) $.
///
/// - Alternatively, when the sequences differ significantly at the beginning
/// causing early termination, the best case time complexity approaches $
/// \Omega(E^2) $.
///
/// ## Example
///
/// ```
/// # use zoe::alignment::sneaky_snake;
/// let reference = b"GGTGCAGAGCTC";
/// let query = b"GGTGAGAGTTGT";
/// let threshold = 0.25;
///
/// let result = sneaky_snake(reference, query, threshold);
/// assert_eq!(result, Some(true));
/// ```
///
/// ## Module Citations
///
/// 1. Alser, Mohammed; Shahroodi, Taha; Gómez-Luna, Juan; Alkan, Can; Mutlu,
/// Onur (2020). "SneakySnake: a fast and accurate universal genome
/// pre-alignment filter for CPUs, GPUs and FPGAs". *Bioinformatics*. 36
/// (22–23): 5282–5290.
///
/// [Sneaky Snake]: https://doi.org/10.1093/bioinformatics/btaa1015