Skip to main content

ferritin_core/views/
model_residue.rs

1use super::model_atom::ModelAtomView;
2use crate::info::constants::{is_amino_acid, is_carbohydrate, is_nucleotide};
3use crate::model::Model;
4
5/// Read-only view into a single residue from a [`Model`].
6pub struct ModelResidueView<'a> {
7    pub(crate) model: &'a Model,
8    pub(crate) res_idx: usize,
9}
10
11impl<'a> ModelResidueView<'a> {
12    pub(crate) fn new(model: &'a Model, res_idx: usize) -> Self {
13        ModelResidueView { model, res_idx }
14    }
15
16    pub fn atom_count(&self) -> usize {
17        let range = self.model.hierarchy.atoms_in_residue(self.res_idx);
18        range.end - range.start
19    }
20
21    pub fn chain_id(&self) -> &'a str {
22        let chain_idx = self.model.hierarchy.chain_of_residue(self.res_idx);
23        &self.model.hierarchy.chains.auth_asym_id[chain_idx]
24    }
25
26    pub fn is_amino_acid(&self) -> bool {
27        is_amino_acid(self.residue_name())
28    }
29
30    pub fn is_nucleotide(&self) -> bool {
31        is_nucleotide(self.residue_name())
32    }
33
34    pub fn is_carbohydrate(&self) -> bool {
35        is_carbohydrate(self.residue_name())
36    }
37
38    pub fn iter_atoms(&self) -> impl Iterator<Item = ModelAtomView<'a>> + '_ {
39        let range = self.model.hierarchy.atoms_in_residue(self.res_idx);
40        let model = self.model;
41        range.map(move |atom_idx| ModelAtomView::new(model, atom_idx))
42    }
43
44    pub fn residue_id(&self) -> i32 {
45        self.model.hierarchy.residues.auth_seq_id[self.res_idx]
46    }
47
48    pub fn residue_name(&self) -> &'a str {
49        &self.model.hierarchy.residues.comp_id[self.res_idx]
50    }
51
52    pub fn find_atom_by_name(&self, name: &str) -> Option<ModelAtomView<'a>> {
53        let mut range = self.model.hierarchy.atoms_in_residue(self.res_idx);
54        let model = self.model;
55        range.find(|&i| model.hierarchy.atoms.atom_name[i] == name)
56            .map(|idx| ModelAtomView::new(model, idx))
57    }
58}