use nalgebra::Vector3;
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub struct Atom {
pub serial: u32,
pub name: String,
pub alt_loc: Option<char>,
pub residue_name: String,
pub chain_id: char,
pub residue_seq: i32,
pub ins_code: Option<char>,
pub coord: Vector3<f32>,
pub occupancy: f32,
pub temp_factor: f32,
pub element: Element,
pub is_hetatm: bool,
}
impl Atom {
pub fn is_water(&self) -> bool {
matches!(self.residue_name.as_str(), "HOH" | "WAT" | "H2O" | "DOD")
}
#[allow(dead_code)]
pub fn is_backbone(&self) -> bool {
matches!(self.name.as_str(), "N" | "CA" | "C" | "O" | "P" | "O3'" | "O5'" | "C3'" | "C4'" | "C5'")
}
pub fn vdw_radius(&self) -> f32 {
self.element.vdw_radius()
}
#[allow(dead_code)]
pub fn covalent_radius(&self) -> f32 {
self.element.covalent_radius()
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[derive(Default)]
pub enum Element {
H,
C,
N,
O,
S,
P,
Fe,
Zn,
Ca,
Mg,
Na,
K,
Cl,
F,
Br,
I,
Se,
#[default]
Unknown,
}
impl Element {
pub fn from_symbol(s: &str) -> Self {
match s.trim().to_uppercase().as_str() {
"H" => Element::H,
"C" => Element::C,
"N" => Element::N,
"O" => Element::O,
"S" => Element::S,
"P" => Element::P,
"FE" => Element::Fe,
"ZN" => Element::Zn,
"CA" => Element::Ca,
"MG" => Element::Mg,
"NA" => Element::Na,
"K" => Element::K,
"CL" => Element::Cl,
"F" => Element::F,
"BR" => Element::Br,
"I" => Element::I,
"SE" => Element::Se,
_ => Element::Unknown,
}
}
pub fn vdw_radius(&self) -> f32 {
match self {
Element::H => 1.20,
Element::C => 1.70,
Element::N => 1.55,
Element::O => 1.52,
Element::S => 1.80,
Element::P => 1.80,
Element::Fe => 1.40,
Element::Zn => 1.39,
Element::Ca => 1.97,
Element::Mg => 1.73,
Element::Na => 2.27,
Element::K => 2.75,
Element::Cl => 1.75,
Element::F => 1.47,
Element::Br => 1.85,
Element::I => 1.98,
Element::Se => 1.90,
Element::Unknown => 1.50, }
}
#[allow(dead_code)]
pub fn covalent_radius(&self) -> f32 {
match self {
Element::H => 0.31,
Element::C => 0.76,
Element::N => 0.71,
Element::O => 0.66,
Element::S => 1.05,
Element::P => 1.07,
Element::Fe => 1.32,
Element::Zn => 1.22,
Element::Ca => 1.76,
Element::Mg => 1.41,
Element::Na => 1.66,
Element::K => 2.03,
Element::Cl => 1.02,
Element::F => 0.57,
Element::Br => 1.20,
Element::I => 1.39,
Element::Se => 1.20,
Element::Unknown => 0.80, }
}
#[allow(dead_code)]
pub fn cpk_color(&self) -> (u8, u8, u8) {
match self {
Element::H => (255, 255, 255), Element::C => (144, 144, 144), Element::N => (48, 80, 248), Element::O => (255, 13, 13), Element::S => (255, 255, 48), Element::P => (255, 128, 0), Element::Fe => (224, 102, 51), Element::Zn => (125, 128, 176), Element::Ca => (61, 255, 0), Element::Mg => (138, 255, 0), Element::Na => (171, 92, 242), Element::K => (143, 64, 212), Element::Cl => (31, 240, 31), Element::F => (144, 224, 80), Element::Br => (166, 41, 41), Element::I => (148, 0, 148), Element::Se => (255, 161, 0), Element::Unknown => (255, 20, 147), }
}
#[allow(dead_code)]
pub fn symbol(&self) -> &'static str {
match self {
Element::H => "H",
Element::C => "C",
Element::N => "N",
Element::O => "O",
Element::S => "S",
Element::P => "P",
Element::Fe => "Fe",
Element::Zn => "Zn",
Element::Ca => "Ca",
Element::Mg => "Mg",
Element::Na => "Na",
Element::K => "K",
Element::Cl => "Cl",
Element::F => "F",
Element::Br => "Br",
Element::I => "I",
Element::Se => "Se",
Element::Unknown => "X",
}
}
}