knuckles_parse/records/
anisotropic.rs1#[cfg(feature = "serde")]
2use serde::{Deserialize, Serialize};
3
4#[cfg(feature = "python")]
5use pyo3::prelude::*;
6
7#[cfg(feature = "python")]
8use knuckles_macro::pydefault;
9
10#[derive(Debug, Clone)]
11#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
12#[cfg_attr(feature = "python", pyclass(get_all, set_all))]
13#[cfg_attr(feature = "python", pydefault)]
14pub struct AnisotropicRecord {
15 pub serial: u32,
16 pub name: String,
17 pub alt_loc: Option<char>,
18 pub res_name: String,
19 pub chain_id: char,
20 pub res_seq: i16,
21 pub i_code: Option<char>,
22 pub u00: i32,
23 pub u11: i32,
24 pub u22: i32,
25 pub u01: i32,
26 pub u02: i32,
27 pub u12: i32,
28 pub element: Option<String>,
29 pub charge: Option<String>,
30}
31
32impl AnisotropicRecord {
33 pub fn new(str: &str) -> AnisotropicRecord {
34 AnisotropicRecord {
35 serial: str[6..11].trim().parse::<u32>().unwrap_or_default(),
36 name: str[12..16].trim().to_string(),
37 alt_loc: str[16..17].trim().parse::<char>().ok(),
38 res_name: str[17..20].trim().to_string(),
39 chain_id: str[21..22].trim().parse::<char>().unwrap(),
40 res_seq: str[22..26].trim().parse().unwrap(),
41 i_code: str[26..27].trim().parse::<char>().ok(),
42 u00: str[28..35].trim().parse().unwrap(),
43 u11: str[35..42].trim().parse().unwrap(),
44 u22: str[42..49].trim().parse().unwrap(),
45 u01: str[49..56].trim().parse().unwrap(),
46 u02: str[56..63].trim().parse().unwrap(),
47 u12: str[63..70].trim().parse().unwrap(),
48 element: str
49 .get(76..78)
50 .map(|str| str.trim().to_string())
51 .filter(|item| !item.is_empty()),
52 charge: str
53 .get(78..80)
54 .map(|str| str.trim().to_string())
55 .filter(|item| !item.is_empty()),
56 }
57 }
58}
59
60impl From<&str> for AnisotropicRecord {
61 fn from(str: &str) -> Self {
62 AnisotropicRecord::new(str)
63 }
64}
65
66#[cfg(test)]
67mod tests {
68 use super::*;
69
70 #[test]
71 fn parse_anisou_line_test() {
72 const LINE: &str =
73 "ANISOU 1 N MET A 1 688 1234 806 -19 -49 178 N ";
74 let record = AnisotropicRecord::new(LINE);
75 assert_eq!(record.serial, 1);
76 assert_eq!(record.name, "N");
77 assert_eq!(record.res_name, "MET");
78 assert_eq!(record.chain_id, 'A');
79 assert_eq!(record.res_seq, 1);
80 assert_eq!(record.u00, 688);
81 assert_eq!(record.u11, 1234);
82 assert_eq!(record.u22, 806);
83 assert_eq!(record.u01, -19);
84 assert_eq!(record.u02, -49);
85 assert_eq!(record.u12, 178);
86 assert_eq!(record.element, Some("N".to_string()));
87 const LINE2: &str =
88 "ANISOU 1 N MET A 1 688 1234 806 -19 -49 178 ";
89 let record = AnisotropicRecord::new(LINE2);
90 assert_eq!(record.serial, 1);
91 assert_eq!(record.name, "N");
92 assert_eq!(record.res_name, "MET");
93 assert_eq!(record.chain_id, 'A');
94 assert_eq!(record.res_seq, 1);
95 assert_eq!(record.u00, 688);
96 assert_eq!(record.u11, 1234);
97 assert_eq!(record.u22, 806);
98 assert_eq!(record.u01, -19);
99 assert_eq!(record.u02, -49);
100 assert_eq!(record.u12, 178);
101 assert_eq!(record.element, None);
102 }
103}