Skip to main content

kamino_cli/
recode.rs

1//! Amino-acid recoding schemes (6-letter alphabet, 3 bits/symbol).
2
3use clap::ValueEnum;
4
5pub const RECODE_ALPHABET_SIZE: usize = 6;
6pub const RECODE_BITS_PER_SYMBOL: u32 = 3;
7
8#[derive(Copy, Clone, Debug, Eq, PartialEq, ValueEnum)]
9pub enum RecodeScheme {
10    Dayhoff6,
11    SR6,
12    KGB6,
13}
14
15impl std::fmt::Display for RecodeScheme {
16    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
17        let name = match self {
18            RecodeScheme::Dayhoff6 => "Dayhoff6",
19            RecodeScheme::SR6 => "SR6",
20            RecodeScheme::KGB6 => "KGB6",
21        };
22        f.write_str(name)
23    }
24}
25
26/// Return class code (0..=5) or 255 for unknown/ambiguous.
27#[inline]
28pub fn recode_byte(b: u8, scheme: RecodeScheme) -> u8 {
29    match scheme {
30        RecodeScheme::Dayhoff6 => dayhoff6_code(b),
31        RecodeScheme::SR6 => sr6_code(b),
32        RecodeScheme::KGB6 => kgb6_code(b),
33    }
34}
35
36#[inline]
37fn dayhoff6_code(b: u8) -> u8 {
38    match b {
39        b'C' | b'c' => 0,                                                         // C
40        b'A' | b'a' | b'G' | b'g' | b'P' | b'p' | b'S' | b's' | b'T' | b't' => 1, // A/G/P/S/T
41        b'D' | b'd' | b'E' | b'e' | b'N' | b'n' | b'Q' | b'q' => 2,               // D/E/N/Q
42        b'H' | b'h' | b'K' | b'k' | b'R' | b'r' => 3,                             // H/K/R
43        b'I' | b'i' | b'L' | b'l' | b'M' | b'm' | b'V' | b'v' => 4,               // I/L/M/V
44        b'F' | b'f' | b'W' | b'w' | b'Y' | b'y' => 5,                             // F/W/Y
45        _ => 255,
46    }
47}
48
49#[inline]
50fn sr6_code(b: u8) -> u8 {
51    match b {
52        b'A' | b'a' | b'P' | b'p' | b'S' | b's' | b'T' | b't' => 0, // A/P/S/T
53        b'D' | b'd' | b'E' | b'e' | b'N' | b'n' | b'G' | b'g' => 1, // D/E/N/G
54        b'Q' | b'q' | b'K' | b'k' | b'R' | b'r' => 2,               // Q/K/R
55        b'M' | b'm' | b'I' | b'i' | b'V' | b'v' | b'L' | b'l' => 3, // M/I/V/L
56        b'W' | b'w' | b'C' | b'c' => 4,                             // W/C
57        b'F' | b'f' | b'Y' | b'y' | b'H' | b'h' => 5,               // F/Y/H
58        _ => 255,
59    }
60}
61
62#[inline]
63fn kgb6_code(b: u8) -> u8 {
64    match b {
65        b'A' | b'a' | b'G' | b'g' | b'P' | b'p' | b'S' | b's' => 0, // A/G/P/S
66        b'D' | b'd' | b'E' | b'e' | b'N' | b'n' | b'Q' | b'q' | b'H' | b'h' | b'K' | b'k'
67        | b'R' | b'r' | b'T' | b't' => 1, // D/E/N/Q/H/K/R/T
68        b'M' | b'm' | b'I' | b'i' | b'L' | b'l' => 2,               // M/I/L
69        b'W' | b'w' => 3,                                           // W
70        b'F' | b'f' | b'Y' | b'y' => 4,                             // F/Y
71        b'C' | b'c' | b'V' | b'v' => 5,                             // C/V
72        _ => 255,
73    }
74}