Skip to main content

ferritin_core/views/
residue.rs

1use super::atom::AtomView;
2use crate::AtomCollection;
3use crate::info::constants::{is_amino_acid, is_carbohydrate, is_nucleotide};
4
5/// View representing a residue (amino acid, nucleotide, etc.) in the molecule.
6pub struct ResidueView<'a> {
7    pub(crate) data: &'a AtomCollection,
8    pub(crate) start_atom_idx: usize,
9    pub(crate) end_atom_idx: usize,
10}
11
12impl<'a> ResidueView<'a> {
13    pub fn new(data: &'a AtomCollection, start_atom_idx: usize, end_atom_idx: usize) -> Self {
14        ResidueView {
15            data,
16            start_atom_idx,
17            end_atom_idx,
18        }
19    }
20
21    pub fn atom_count(&self) -> usize {
22        self.end_atom_idx - self.start_atom_idx
23    }
24
25    /// Returns the half-open range of atom indices `[start, end)` for this residue.
26    pub fn atom_range(&self) -> std::ops::Range<usize> {
27        self.start_atom_idx..self.end_atom_idx
28    }
29    pub fn chain_id(&self) -> &str {
30        self.data.get_chain_id(self.start_atom_idx)
31    }
32    pub fn is_amino_acid(&self) -> bool {
33        is_amino_acid(self.residue_name())
34    }
35    // Add methods for other residue types
36    pub fn is_nucleotide(&self) -> bool {
37        is_nucleotide(self.residue_name())
38    }
39    pub fn is_carbohydrate(&self) -> bool {
40        is_carbohydrate(self.residue_name())
41    }
42    pub fn iter_atoms(&self) -> impl Iterator<Item = AtomView<'_>> + '_ {
43        (self.start_atom_idx..self.end_atom_idx).map(move |idx| AtomView::new(self.data, idx))
44    }
45    pub fn residue_id(&self) -> i32 {
46        *self.data.get_res_id(self.start_atom_idx)
47    }
48    pub fn residue_name(&self) -> &str {
49        self.data.get_res_name(self.start_atom_idx)
50    }
51
52    pub fn is_hetero(&self) -> bool {
53        self.data.get_is_hetero(self.start_atom_idx)
54    }
55
56    pub fn is_water(&self) -> bool {
57        matches!(self.residue_name(), "HOH" | "WAT" | "H2O")
58    }
59
60    /// Single-atom hetero residue that is not water (e.g. Na+, Mg2+, Zn2+).
61    pub fn is_ion(&self) -> bool {
62        self.atom_count() == 1 && self.is_hetero() && !self.is_water()
63    }
64
65    // Get atom by name within this residue
66    pub fn find_atom_by_name(&self, name: &str) -> Option<AtomView<'a>> {
67        (self.start_atom_idx..self.end_atom_idx)
68            .find(|&i| self.data.get_atom_name(i) == name)
69            .map(|idx| AtomView::new(self.data, idx))
70    }
71}