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    /// Canonical chain identifier (`label_asym_id`).
27    pub fn label_chain_id(&self) -> &'a str {
28        let chain_idx = self.model.hierarchy.chain_of_residue(self.res_idx);
29        &self.model.hierarchy.chains.label_asym_id[chain_idx]
30    }
31
32    pub fn is_amino_acid(&self) -> bool {
33        is_amino_acid(self.residue_name())
34    }
35
36    pub fn is_nucleotide(&self) -> bool {
37        is_nucleotide(self.residue_name())
38    }
39
40    pub fn is_carbohydrate(&self) -> bool {
41        is_carbohydrate(self.residue_name())
42    }
43
44    pub fn iter_atoms(&self) -> impl Iterator<Item = ModelAtomView<'a>> + '_ {
45        let range = self.model.hierarchy.atoms_in_residue(self.res_idx);
46        let model = self.model;
47        range.map(move |atom_idx| ModelAtomView::new(model, atom_idx))
48    }
49
50    pub fn residue_id(&self) -> i32 {
51        self.model.hierarchy.residues.auth_seq_id[self.res_idx]
52    }
53
54    pub fn residue_name(&self) -> &'a str {
55        &self.model.hierarchy.residues.comp_id[self.res_idx]
56    }
57
58    /// Author-assigned component identifier (`auth_comp_id`).
59    pub fn auth_residue_name(&self) -> &'a str {
60        &self.model.hierarchy.residues.auth_comp_id[self.res_idx]
61    }
62
63    pub fn find_atom_by_name(&self, name: &str) -> Option<ModelAtomView<'a>> {
64        let mut range = self.model.hierarchy.atoms_in_residue(self.res_idx);
65        let model = self.model;
66        range
67            .find(|&i| model.hierarchy.atoms.atom_name[i] == name)
68            .map(|idx| ModelAtomView::new(model, idx))
69    }
70}