1use conformation::{XYZ, Atom, Pose};
5use sampling::get_protocol;
6
7use std::fs::File;
8use std::error::Error;
9use std::io::prelude::*;
10
11pub struct Config {
12 pub protocol: String,
14 pub filename: String,
15}
16
17impl Config {
18 pub fn new(args: &[String]) -> Result<Config, &'static str> {
19 if args.len() < 3 {
20 return Err("not enough arguments");
21 }
22
23 let protocol = args[1].clone();
24 let filename = args[2].clone();
25
26 Ok(Config { protocol, filename })
27 }
28}
29
30pub struct Record {
47 pub xyz: XYZ,
52 pub charge: f64,
53 pub element: String,
54 pub residue_index: i32,
55 pub residue_name: String,
56}
57
58impl Record {
59 pub fn new(args: &str) -> Record {
60
61 let x: f64 = args[30..38].trim().parse().expect("X not a number");
63 let y: f64 = args[38..46].trim().parse().expect("Y not a number");
64 let z: f64 = args[46..54].trim().parse().expect("Z not a number");
65 let xyz = XYZ::new(x, y, z);
66
67 let residue_index: i32 = args[23..30].trim().parse().expect("Residue index not a number");
69 let residue_name = args[17..20].to_string(); let charge: f64 = -0.69; let element = args[11..17].trim().to_string();
74 Record { xyz, charge, element, residue_index, residue_name }
78 }
79}
80
81pub fn parse_pdb(contents: &str) -> Vec<Atom> {
82 let mut atoms = Vec::new();
85 for line in contents.lines() {
87 if line.starts_with("ATOM") {
88 let record = Record::new(&line);
89 let atom = Atom::new(&record);
90 atoms.push(atom);
91 }
92 }
93
94 atoms
95}
96
97pub fn run(config: Config) -> Result<(), Box<Error>> {
98
99 let mut f = File::open(config.filename)?;
101 let mut contents = String::new();
102 f.read_to_string(&mut contents)?;
103
104 let atoms = parse_pdb(&contents);
106 let mut pose = Pose::from_atoms(atoms);
107
108 let protocol = get_protocol(&config.protocol);
110 protocol.run(&mut pose);
111
112 Ok(())
115}
116
117#[cfg(test)]
118mod tests {
119 use super::*;
120
121 #[test]
122 fn test_new_atoms_testy() {
123 let record = Record::new("ATOM 8 OD2 ASP A 1 28.042 -10.262 20.858 1.00 0.00 O ");
124 let atom = Atom::new(&record);
125 assert_eq!(atom.xyz.x, 28.042);
126 }
127
128 #[test]
129 fn test_pdb_parsing() {
130 let contents = "ATOM 1 N ASP A 1 27.405 -7.086 18.389 1.00 0.00 N
131ATOM 2 CA ASP A 1 26.221 -7.728 18.989 1.00 0.00 C
132ATOM 3 C ASP A 1 25.150 -6.679 19.328 1.00 0.00 C
133ATOM 4 O ASP A 1 24.099 -6.710 18.722 1.00 0.00 O
134ATOM 5 CB ASP A 1 26.607 -8.504 20.250 1.00 0.00 C
135ATOM 6 CG ASP A 1 27.438 -9.745 19.951 1.00 0.00 C
136ATOM 7 OD1 ASP A 1 27.457 -10.165 18.817 1.00 0.00 O
137ATOM 8 OD2 ASP A 1 28.042 -10.262 20.858 1.00 0.00 O
138ATOM 9 1H ASP A 1 28.091 -7.781 18.175 1.00 0.00 H
139ATOM 10 2H ASP A 1 27.138 -6.611 17.550 1.00 0.00 H
140";
141 let atoms = parse_pdb(&contents);
142 let pose = Pose::from_atoms(atoms);
143
144 assert_eq!(pose.atoms.len(), 10);
145
146 }
147
148 #[test]
149 fn test_entropy_function() {
150
151 fn H(l: &f64) -> f64 {
153
154 let value = 1.0 - l;
161 l.ln() - value * value.ln()
162 }
163
164 let test_float: f64 = 18.11;
165 let answer: f64 = H(&test_float);
166 println!(">>> {}", answer);
167
168 }
170
171 #[test]
172 fn test_lennard_jones_atom_loading() {
173
174
175 }
176
177}