Commit e1f92a6c authored by NOEL Philippe's avatar NOEL Philippe

add the filter selection (1 filter)

parent 7952e171
...@@ -3,8 +3,10 @@ extern crate pdbparser; ...@@ -3,8 +3,10 @@ extern crate pdbparser;
use pdbparser::*; use pdbparser::*;
fn main() { fn main() {
//let tutu = open_pdb_file("src/tests/f2_adn.pdb"); let toto = parse_pdb("src/tests_file/f2_adn.pdb");
let tutu = parse_pdb("src/tests_file/f2.pdb"); println!("Nb res : {}", toto.get_number_residue());
println!("Nb res : {}", tutu.get_number_residue()); println!("Nb chain : {}", toto.get_number_chain());
println!("Nb chain : {}", tutu.get_number_chain()); let toto_A = toto.select_atoms("Chain A");
println!("Nb res : {}", toto_A.get_number_residue());
println!("Nb chain : {}", toto_A.get_number_chain());
} }
...@@ -4,3 +4,4 @@ pub mod residue; ...@@ -4,3 +4,4 @@ pub mod residue;
pub mod read_pdb; pub mod read_pdb;
pub mod chain; pub mod chain;
mod selection_atom;
\ No newline at end of file
...@@ -2,6 +2,10 @@ use super::atom::Atom; ...@@ -2,6 +2,10 @@ use super::atom::Atom;
use super::chain::Chain; use super::chain::Chain;
use super::residue::Residue; use super::residue::Residue;
use super::selection_atom;
use std::char;
#[derive(Debug)] #[derive(Debug)]
pub struct Protein { pub struct Protein {
...@@ -222,4 +226,32 @@ impl<'a> Protein { ...@@ -222,4 +226,32 @@ impl<'a> Protein {
} }
lst lst
} }
/// Select atom from a pattern and return a new protein structure
///
/// TODO: The methode is idiot and need to be improve.
/// ex: don't parse the chain if it's not selected
///
pub fn select_atoms(&self, pattern: &str) -> Protein {
let mut n_prot = Protein::new(String::from("toto"));
let select = match selection_atom::parse_select(&pattern) {
Some(x) => x,
None => panic!("tutu"),
};
for chain in &self.lst_chain {
let c_chain = chain.name;
for residue in &chain.lst_res {
let c_res = residue.res_num;
for atom in &residue.lst_atom {
if selection_atom::atom_match(&select, c_chain, c_res) {
n_prot.update_protein(c_chain, residue.name.clone(), c_res, atom.name.clone(), atom.number, atom.coord)
}
}
}
}
n_prot
}
} }
#[derive(Debug, PartialEq)]
pub enum Select {
Chainid(char, char),
Resid(usize, usize),
Backbone,
}
/// Parse option given for the selection of residues and return
/// the index of begin and end of select residues.
///
///
///
fn parse_options_int(opt: &[&str]) -> Option<[usize; 2]> {
if opt.len() == 1 {
match opt[0].parse() {
Ok(v) => return Some([v, v]),
Err(_) => return None,
}
}
if opt.len() == 3 && opt[1] == "to" {
let index1: usize = match opt[0].parse() {
Ok(v) => v,
Err(_) => return None,
};
let index2: usize = match opt[2].parse() {
Ok(v) => v,
Err(_) => return None,
};
return Some([index1, index2])
}
None
}
/// Parse option given for the selection of atoms
///
/// TODO: Remove this one because it's a doublon of parse_option_int
///
fn parse_options_char(opt: &[&str]) -> Option<[char; 2]> {
if opt.len() == 1 {
match opt[0].parse() {
Ok(v) => return Some([v, v]),
Err(_) => return None,
}
}
if opt.len() == 3 && opt[1] == "to" {
let index1: char = match opt[0].parse() {
Ok(v) => v,
Err(_) => return None,
};
let index2: char = match opt[2].parse() {
Ok(v) => v,
Err(_) => return None,
};
return Some([index1, index2])
}
None
}
/// Parse the selection and return enum and options for atom/residue/chain/backbone
///
pub fn parse_select(select: &str) -> Option<Select> {
let sel: Vec<&str> = select.split_whitespace().collect();
if sel.len() == 0 {
return None;
}
match sel[0].to_lowercase().as_str() {
"resid" => {
match parse_options_int(&sel[1..]) {
Some(x) => return Some(Select::Resid(x[0], x[1])),
None => return None,
}
}
"chain" => {
match parse_options_char(&sel[1..]) {
Some(x) => return Some(Select::Chainid(x[0], x[1])),
None => return None,
}
}
"backbone" => Some(Select::Backbone),
_ => {
println!("Error in the selection");
None
},
}
}
pub fn atom_match(sel: &Select, chain: char, res_id: u64) -> bool {
match sel {
Select::Chainid(x, y) => {
if chain >= *x && chain <= *y {
return true
} else {
return false
}
},
Select::Backbone => {
return false
},
Select::Resid(x, y) => {
if res_id as usize >= *x && res_id as usize <= *y {
return true
} else {
return false
}
},
}
}
#[test]
fn test_fn(){
assert_eq!(None, parse_select(""));
assert_eq!(Some(Select::Resid(5, 96)), parse_select("resid 5 to 96"));
assert_eq!(None, parse_select("resid 5 t 96"));
assert_eq!(Some(Select::Backbone), parse_select("BaCkbone"));
assert_eq!(Some(Select::Chainid('B', 'B')), parse_select("chain B"));
assert_eq!(Some(Select::Chainid('B', 'C')), parse_select("chain B to C"));
assert_eq!(None, parse_select("resid 3 to TO"));
}
\ No newline at end of file
...@@ -8,4 +8,3 @@ fn test_parse_f2() { ...@@ -8,4 +8,3 @@ fn test_parse_f2() {
assert_eq!(66, my_prot.get_number_residue()); assert_eq!(66, my_prot.get_number_residue());
assert_eq!(1085, my_prot.get_number_atom()); assert_eq!(1085, my_prot.get_number_atom());
} }
Command being timed: "target/release/pdbparser"
User time (seconds): 0.45
System time (seconds): 0.00
Percent of CPU this job got: 99%
Elapsed (wall clock) time (h:mm:ss or m:ss): 0:00.45
Average shared text size (kbytes): 0
Average unshared data size (kbytes): 0
Average stack size (kbytes): 0
Average total size (kbytes): 0
Maximum resident set size (kbytes): 7352
Average resident set size (kbytes): 0
Major (requiring I/O) page faults: 0
Minor (reclaiming a frame) page faults: 1363
Voluntary context switches: 1
Involuntary context switches: 92
Swaps: 0
File system inputs: 0
File system outputs: 0
Socket messages sent: 0
Socket messages received: 0
Signals delivered: 0
Page size (bytes): 4096
Exit status: 0
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment