Skip to main content

molframe_core/
secondary.rs

1//! Per-residue secondary-structure vocabulary shared by readers and analyses.
2
3/// A residue-level structural assignment, in the DSSP vocabulary.
4#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
5pub enum SecondaryStructure {
6    /// The file and available analyses supplied no assignment.
7    #[default]
8    Unknown,
9    /// A residue outside every helix, ladder, turn and bend (DSSP blank).
10    Coil,
11    /// An α-helix, i → i+4 (DSSP `H`).
12    AlphaHelix,
13    /// A 3₁₀-helix, i → i+3 (DSSP `G`).
14    ThreeTenHelix,
15    /// A π-helix, i → i+5 (DSSP `I`).
16    PiHelix,
17    /// A helix whose class the source does not name as α, 3₁₀ or π.
18    OtherHelix,
19    /// An isolated β-bridge, a single bridge pair outside a ladder (DSSP `B`).
20    BetaBridge,
21    /// A residue in a β-ladder of two or more bridges (DSSP `E`).
22    Strand,
23    /// A hydrogen-bonded turn (DSSP `T`).
24    Turn,
25    /// A bend: Cα direction changes by more than 70° (DSSP `S`).
26    Bend,
27    /// A left-handed polyproline-II helix (DSSP 4 `P`); not sequence restricted.
28    PolyProline,
29}
30
31impl SecondaryStructure {
32    /// Whether the state is any kind of helix.
33    #[must_use]
34    pub const fn is_helix(self) -> bool {
35        matches!(
36            self,
37            Self::AlphaHelix
38                | Self::ThreeTenHelix
39                | Self::PiHelix
40                | Self::OtherHelix
41                | Self::PolyProline
42        )
43    }
44    /// Whether the residue belongs to a beta ladder rather than an isolated bridge.
45    #[must_use]
46    pub const fn is_strand(self) -> bool {
47        matches!(self, Self::Strand)
48    }
49
50    /// Whether the residue is a beta ladder or an isolated beta bridge.
51    #[must_use]
52    pub const fn is_sheet_like(self) -> bool {
53        matches!(self, Self::Strand | Self::BetaBridge)
54    }
55
56    /// The stable one-byte code exchanged with consumers such as the Python
57    /// binding and viewers. Codes 0–4 predate the 10-state vocabulary and keep
58    /// their meaning; the later states are appended.
59    #[must_use]
60    pub const fn code(self) -> u8 {
61        match self {
62            Self::Unknown => 0,
63            Self::Coil => 1,
64            Self::AlphaHelix => 2,
65            Self::Strand => 3,
66            Self::Turn => 4,
67            Self::ThreeTenHelix => 5,
68            Self::PiHelix => 6,
69            Self::OtherHelix => 7,
70            Self::BetaBridge => 8,
71            Self::Bend => 9,
72            Self::PolyProline => 10,
73        }
74    }
75}
76
77/// Where a residue's secondary-structure state came from.
78#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
79pub enum SecondarySource {
80    /// Nothing assigned the state.
81    #[default]
82    None,
83    /// The deposited file's helix and sheet records.
84    File,
85    /// Kabsch–Sander assignment from backbone hydrogen bonds.
86    Dssp,
87    /// The Cα-only fallback for a trace without backbone atoms.
88    CaOnly,
89}
90
91impl SecondarySource {
92    /// Precedence when two sources disagree; the higher rank wins.
93    #[must_use]
94    pub const fn rank(self) -> u8 {
95        match self {
96            Self::None => 0,
97            Self::CaOnly => 1,
98            Self::Dssp => 2,
99            Self::File => 3,
100        }
101    }
102
103    /// The stable one-byte code exchanged with consumers.
104    #[must_use]
105    pub const fn code(self) -> u8 {
106        match self {
107            Self::None => 0,
108            Self::File => 1,
109            Self::Dssp => 2,
110            Self::CaOnly => 3,
111        }
112    }
113}
114
115/// One residue's state together with where it came from.
116#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
117pub struct SecondaryAssignment {
118    /// The assigned state.
119    pub state: SecondaryStructure,
120    /// The source that assigned it.
121    pub source: SecondarySource,
122}
123
124#[cfg(test)]
125#[path = "secondary_tests.rs"]
126mod tests;