bio/scores/
blosum62.rs

1use super::lookup;
2use std::sync::LazyLock;
3
4// Copyright 2014-2017 M. Rizky Luthfianto.
5// Licensed under the MIT license (http://opensource.org/licenses/MIT)
6// This file may not be copied, modified, or distributed
7// except according to those terms.
8
9// taken from https://github.com/seqan/seqan/blob/master/include%2Fseqan%2Fscore%2Fscore_matrix_data.h#L327
10static MAT: LazyLock<[i32; 27 * 27]> = LazyLock::new(|| {
11    [
12        4, -2, 0, -2, -1, -2, 0, -2, -1, -1, -1, -1, -1, -2, 0, -1, -1, -1, 1, 0, 0, 0, -3, -2, -1,
13        0, -4, -2, 4, -3, 4, 1, -3, -1, 0, -3, -4, 0, -4, -3, 3, -1, -2, 0, -1, 0, -1, -1, -3, -4,
14        -3, 1, -1, -4, 0, -3, 9, -3, -4, -2, -3, -3, -1, -1, -3, -1, -1, -3, -2, -3, -3, -3, -1,
15        -1, -2, -1, -2, -2, -3, -2, -4, -2, 4, -3, 6, 2, -3, -1, -1, -3, -4, -1, -4, -3, 1, -1, -1,
16        0, -2, 0, -1, -1, -3, -4, -3, 1, -1, -4, -1, 1, -4, 2, 5, -3, -2, 0, -3, -3, 1, -3, -2, 0,
17        -1, -1, 2, 0, 0, -1, -1, -2, -3, -2, 4, -1, -4, -2, -3, -2, -3, -3, 6, -3, -1, 0, 0, -3, 0,
18        0, -3, -1, -4, -3, -3, -2, -2, -1, -1, 1, 3, -3, -1, -4, 0, -1, -3, -1, -2, -3, 6, -2, -4,
19        -4, -2, -4, -3, 0, -1, -2, -2, -2, 0, -2, -1, -3, -2, -3, -2, -1, -4, -2, 0, -3, -1, 0, -1,
20        -2, 8, -3, -3, -1, -3, -2, 1, -1, -2, 0, 0, -1, -2, -1, -3, -2, 2, 0, -1, -4, -1, -3, -1,
21        -3, -3, 0, -4, -3, 4, 3, -3, 2, 1, -3, -1, -3, -3, -3, -2, -1, -1, 3, -3, -1, -3, -1, -4,
22        -1, -4, -1, -4, -3, 0, -4, -3, 3, 3, -3, 3, 2, -3, -1, -3, -3, -3, -2, -1, -1, 2, -3, -1,
23        -3, -1, -4, -1, 0, -3, -1, 1, -3, -2, -1, -3, -3, 5, -2, -1, 0, -1, -1, 1, 2, 0, -1, -1,
24        -2, -3, -2, 1, -1, -4, -1, -4, -1, -4, -3, 0, -4, -3, 2, 3, -2, 4, 2, -3, -1, -3, -2, -2,
25        -2, -1, -1, 1, -2, -1, -3, -1, -4, -1, -3, -1, -3, -2, 0, -3, -2, 1, 2, -1, 2, 5, -2, -1,
26        -2, 0, -1, -1, -1, -1, 1, -1, -1, -1, -1, -4, -2, 3, -3, 1, 0, -3, 0, 1, -3, -3, 0, -3, -2,
27        6, -1, -2, 0, 0, 1, 0, -1, -3, -4, -2, 0, -1, -4, 0, -1, -2, -1, -1, -1, -1, -1, -1, -1,
28        -1, -1, -1, -1, -1, -2, -1, -1, 0, 0, -1, -1, -2, -1, -1, -1, -4, -1, -2, -3, -1, -1, -4,
29        -2, -2, -3, -3, -1, -3, -2, -2, -2, 7, -1, -2, -1, -1, -2, -2, -4, -3, -1, -2, -4, -1, 0,
30        -3, 0, 2, -3, -2, 0, -3, -3, 1, -2, 0, 0, -1, -1, 5, 1, 0, -1, -1, -2, -2, -1, 3, -1, -4,
31        -1, -1, -3, -2, 0, -3, -2, 0, -3, -3, 2, -2, -1, 0, -1, -2, 1, 5, -1, -1, -1, -3, -3, -2,
32        0, -1, -4, 1, 0, -1, 0, 0, -2, 0, -1, -2, -2, 0, -2, -1, 1, 0, -1, 0, -1, 4, 1, 0, -2, -3,
33        -2, 0, 0, -4, 0, -1, -1, -1, -1, -2, -2, -2, -1, -1, -1, -1, -1, 0, 0, -1, -1, -1, 1, 5, 0,
34        0, -2, -2, -1, 0, -4, 0, -1, -2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -2, -1,
35        -1, 0, 0, -1, -1, -2, -1, -1, -1, -4, 0, -3, -1, -3, -2, -1, -3, -3, 3, 2, -2, 1, 1, -3,
36        -1, -2, -2, -3, -2, 0, -1, 4, -3, -1, -2, -1, -4, -3, -4, -2, -4, -3, 1, -2, -2, -3, -3,
37        -3, -2, -1, -4, -2, -4, -2, -3, -3, -2, -2, -3, 11, 2, -3, -2, -4, -2, -3, -2, -3, -2, 3,
38        -3, 2, -1, -1, -2, -1, -1, -2, -1, -3, -1, -2, -2, -2, -1, -1, 2, 7, -2, -1, -4, -1, 1, -3,
39        1, 4, -3, -2, 0, -3, -3, 1, -3, -1, 0, -1, -1, 3, 0, 0, -1, -1, -2, -3, -2, 4, -1, -4, 0,
40        -1, -2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -2, -1, -1, 0, 0, -1, -1, -2, -1,
41        -1, -1, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4,
42        -4, -4, -4, -4, -4, -4, 1,
43    ]
44});
45
46/// Return the BLOSUM62 substitution matrix score of [a, b]
47///
48/// # Example
49///
50/// ```
51/// use bio::scores::blosum62;
52/// assert_eq!(blosum62(b'H', b'A'), -2);
53/// ```
54pub fn blosum62(a: u8, b: u8) -> i32 {
55    let a = lookup(a);
56    let b = lookup(b);
57    MAT[27 * a + b] // a = column index, b = row index
58}
59
60#[cfg(test)]
61mod tests {
62    use super::*;
63
64    #[test]
65    fn test_blosum62() {
66        let score1 = blosum62(b'H', b'H');
67        assert_eq!(score1, 8);
68        let score2 = blosum62(b'O', b'*');
69        assert_eq!(score2, -4);
70        let score3 = blosum62(b'A', b'*');
71        assert_eq!(score3, -4);
72        let score4 = blosum62(b'*', b'*');
73        assert_eq!(score4, 1);
74        let score5 = blosum62(b'X', b'X');
75        assert_eq!(score5, -1);
76        let score6 = blosum62(b'X', b'Z');
77        assert_eq!(score6, -1);
78    }
79}