Commit 92b99489 authored by NOEL Philippe's avatar NOEL Philippe

Pre .gitignore changes

parent 185b506d
/target
**/*.rs.bk
Cargo.lock
.*/
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CargoProjects">
<cargoProject FILE="$PROJECT_DIR$/Cargo.toml" />
</component>
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.6" project-jdk-type="Python SDK" />
<component name="RustProjectSettings">
<option name="toolchainHomeDirectory" value="$USER_HOME$/.cargo/bin" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/pdbparser.iml" filepath="$PROJECT_DIR$/.idea/pdbparser.iml" />
</modules>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/examples" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/tests" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/benches" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
<component name="TestRunnerService">
<option name="PROJECT_TEST_RUNNER" value="Unittests" />
</component>
</module>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ChangeListManager">
<list default="true" id="64a2b8c5-21c2-4675-aa00-4ee42fda4a9b" name="Default Changelist" comment="" />
<option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="FUSProjectUsageTrigger">
<session id="-508214503">
<usages-collector id="statistics.lifecycle.project">
<counts>
<entry key="project.closed" value="1" />
<entry key="project.open.time.0" value="1" />
<entry key="project.opened" value="1" />
</counts>
</usages-collector>
<usages-collector id="statistics.file.extensions.open">
<counts>
<entry key="rs" value="3" />
</counts>
</usages-collector>
<usages-collector id="statistics.file.types.open">
<counts>
<entry key="Rust" value="3" />
</counts>
</usages-collector>
<usages-collector id="statistics.file.extensions.edit">
<counts>
<entry key="rs" value="51" />
</counts>
</usages-collector>
<usages-collector id="statistics.file.types.edit">
<counts>
<entry key="Rust" value="51" />
</counts>
</usages-collector>
</session>
</component>
<component name="FileEditorManager">
<leaf />
</component>
<component name="Git.Settings">
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
</component>
<component name="IdeDocumentHistory">
<option name="CHANGED_PATHS">
<list>
<option value="$PROJECT_DIR$/src/lib.rs" />
<option value="$PROJECT_DIR$/src/pdb/protein.rs" />
</list>
</option>
</component>
<component name="ProjectFrameBounds" extendedState="6">
<option name="x" value="1747" />
<option name="y" value="25" />
<option name="width" value="1853" />
<option name="height" value="1175" />
</component>
<component name="ProjectView">
<navigator proportions="" version="1">
<foldersAlwaysOnTop value="true" />
</navigator>
<panes>
<pane id="ProjectPane">
<subPane>
<expand>
<path>
<item name="pdbparser" type="b2602c69:ProjectViewProjectNode" />
<item name="pdbparser" type="462c0819:PsiDirectoryNode" />
</path>
<path>
<item name="pdbparser" type="b2602c69:ProjectViewProjectNode" />
<item name="pdbparser" type="462c0819:PsiDirectoryNode" />
<item name="src" type="462c0819:PsiDirectoryNode" />
</path>
<path>
<item name="pdbparser" type="b2602c69:ProjectViewProjectNode" />
<item name="pdbparser" type="462c0819:PsiDirectoryNode" />
<item name="src" type="462c0819:PsiDirectoryNode" />
<item name="pdb" type="462c0819:PsiDirectoryNode" />
</path>
<path>
<item name="pdbparser" type="b2602c69:ProjectViewProjectNode" />
<item name="pdbparser" type="462c0819:PsiDirectoryNode" />
<item name="src" type="462c0819:PsiDirectoryNode" />
<item name="tests" type="462c0819:PsiDirectoryNode" />
</path>
</expand>
<select />
</subPane>
</pane>
<pane id="Scope" />
</panes>
</component>
<component name="PropertiesComponent">
<property name="last_opened_file_path" value="$PROJECT_DIR$" />
<property name="org.rust.cargo.project.model.PROJECT_DISCOVERY" value="true" />
</component>
<component name="RunDashboard">
<option name="ruleStates">
<list>
<RuleState>
<option name="name" value="ConfigurationTypeDashboardGroupingRule" />
</RuleState>
<RuleState>
<option name="name" value="StatusDashboardGroupingRule" />
</RuleState>
</list>
</option>
</component>
<component name="RunManager" selected="Cargo Command.Run pdbparser">
<configuration name="Run pdbparser" type="CargoCommandRunConfiguration" factoryName="Cargo Command" temporary="true">
<option name="channel" value="DEFAULT" />
<option name="command" value="run --package pdbparser --bin pdbparser" />
<option name="nocapture" value="true" />
<option name="backtrace" value="SHORT" />
<option name="workingDirectory" value="file://$PROJECT_DIR$" />
<envs />
<method v="2" />
</configuration>
<configuration name="Test lib::tests" type="CargoCommandRunConfiguration" factoryName="Cargo Command" temporary="true">
<option name="channel" value="DEFAULT" />
<option name="command" value="test --package pdbparser --lib tests" />
<option name="nocapture" value="true" />
<option name="backtrace" value="SHORT" />
<option name="workingDirectory" value="file://$PROJECT_DIR$" />
<envs />
<method v="2" />
</configuration>
<list>
<item itemvalue="Cargo Command.Test lib::tests" />
<item itemvalue="Cargo Command.Run pdbparser" />
</list>
<recent_temporary>
<list>
<item itemvalue="Cargo Command.Run pdbparser" />
<item itemvalue="Cargo Command.Test lib::tests" />
</list>
</recent_temporary>
</component>
<component name="SvnConfiguration">
<configuration />
</component>
<component name="TaskManager">
<task active="true" id="Default" summary="Default task">
<changelist id="64a2b8c5-21c2-4675-aa00-4ee42fda4a9b" name="Default Changelist" comment="" />
<created>1539962937666</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1539962937666</updated>
</task>
<servers />
</component>
<component name="ToolWindowManager">
<frame x="1747" y="25" width="1853" height="1175" extended-state="6" />
<layout>
<window_info id="Favorites" side_tool="true" />
<window_info content_ui="combo" id="Project" order="0" visible="true" weight="0.24958494" />
<window_info id="Structure" order="1" side_tool="true" weight="0.25" />
<window_info anchor="bottom" id="Version Control" />
<window_info anchor="bottom" id="Python Console" />
<window_info anchor="bottom" id="Terminal" />
<window_info anchor="bottom" id="Event Log" side_tool="true" />
<window_info anchor="bottom" id="Message" order="0" />
<window_info anchor="bottom" id="Find" order="1" weight="0.3291866" />
<window_info anchor="bottom" id="Run" order="2" weight="0.3291866" />
<window_info anchor="bottom" id="Debug" order="3" weight="0.4" />
<window_info anchor="bottom" id="Cvs" order="4" weight="0.25" />
<window_info anchor="bottom" id="Inspection" order="5" weight="0.4" />
<window_info anchor="bottom" id="TODO" order="6" />
<window_info anchor="right" id="Cargo" />
<window_info anchor="right" id="Commander" internal_type="SLIDING" order="0" type="SLIDING" weight="0.4" />
<window_info anchor="right" id="Ant Build" order="1" weight="0.25" />
<window_info anchor="right" content_ui="combo" id="Hierarchy" order="2" weight="0.25" />
</layout>
</component>
<component name="VcsContentAnnotationSettings">
<option name="myLimit" value="2678400000" />
</component>
<component name="editorHistoryManager">
<entry file="file://$PROJECT_DIR$/src/main.rs">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="144">
<caret line="8" lean-forward="true" selection-start-line="8" selection-end-line="8" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/pdb/protein.rs">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="522">
<caret line="31" lean-forward="true" selection-start-line="31" selection-end-line="31" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/lib.rs">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="307">
<caret line="62" column="34" selection-start-line="62" selection-start-column="34" selection-end-line="62" selection-end-column="34" />
<folding>
<element signature="e#1947#1948#0" expanded="true" />
<element signature="e#1983#1984#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
</component>
</project>
\ No newline at end of file
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "lldb",
"request": "launch",
"name": "Debug unit tests in library 'pdbparser'",
"cargo": {
"args": [
"test",
"--no-run",
"--lib",
"--package=pdbparser"
],
"filter": {
"kind": "lib"
}
},
"args": [],
"cwd": "${workspaceFolder}"
},
{
"type": "lldb",
"request": "launch",
"name": "Debug executable 'pdbparser'",
"cargo": {
"args": [
"build",
"--bin=pdbparser",
"--package=pdbparser"
],
"filter": {
"kind": "bin"
}
},
"args": [],
"cwd": "${workspaceFolder}"
},
{
"type": "lldb",
"request": "launch",
"name": "Debug unit tests in executable 'pdbparser'",
"cargo": {
"args": [
"test",
"--no-run",
"--bin=pdbparser",
"--package=pdbparser"
],
"filter": {
"kind": "bin"
}
},
"args": [],
"cwd": "${workspaceFolder}"
}
]
}
\ No newline at end of file
[package]
name = "pdbparser"
version = "1.0.0"
authors = ["NOEL Philippe <philippe.noel@inria.fr>"]
edition = "2018"
include = ["Cargo.toml", "src/**/*.rs", "tests/**/*.rs", "README.md"]
[[bin]]
name = "pdbparser"
path = "src/main.rs"
[lib]
name = "pdbparser"
path = "src/lib.rs"
[dependencies]
# PDBparser
**PDBparser is a library written in rust to read and select atoms in protein structure files in the [PDB format](http://www.wwpdb.org/documentation/file-format)**
## Usage
Add this to your `Cargo.toml`:
```toml
[dependencies]
pdbparser = { git = "ssh://git@gitlab.inria.fr/pnoel/pdbparser.git" }
```
and this to your crate root:
```rust
extern crate pdbparser;
```
Here's a simple example that read a pdb file in tests/tests_file
```rust
extern crate pdbparser;
use pdbpaser::*;
fn main() {
let my_prot = parse_pdb("tests/tests_file/5jpq.pdb", "5jpq");
println!("Prot : {} \nn chain: {}\nn res: {}\nn atom: {}",
my_prot.name, my_prot.get_number_chain(),
my_prot.get_number_residue(),
my_prot.get_number_atom());
println!("Reduce protein");
let chain_a = my_prot.select_atoms("chain a").unwrap();
println!("Prot : {} \nn chain: {}\nn res: {}\nn atom: {}",
chain_a.name, chain_a.get_number_chain(),
chain_a.get_number_residue(),
chain_a.get_number_atom());
}
```
## Todo
- [ ] : PDB Writer
- [ ] : Structure to keep informations on nucleic acid/lipid/water
- [ ] : More options to select atoms (Alpha carbon, atoms near to an other, ...)
- [ ] : Support of PDBx/mmCIF format
//! # pdbparser
//!
//! `pdbparser` is a library to manipulate protein structure. It can parse, and filter PDB files.
//! You can create a protein structure by parsing with parse_pdb function. Then you can add filters on your protein.
//!
mod pdb;
pub use self::pdb::read_pdb::parse_pdb as parse_pdb;
pub use self::pdb::protein::Protein;
pub use self::pdb::atom::Atom;
pub use self::pdb::residue::Residue;
pub use self::pdb::chain::Chain;
extern crate pdbparser;
use pdbparser::*;
fn main() {
let my_prot = parse_pdb("tests/tests_file/5jpq.pdb", "5jpq");
println!("Prot : {} \nn chain: {}\nn res: {}\nn atom: {}", my_prot.name, my_prot.get_number_chain(), my_prot.get_number_residue(), my_prot.get_number_atom());
println!("Reduce protein");
let chain_a = my_prot.select_atoms("chain a").unwrap();
println!("Prot : {} \nn chain: {}\nn res: {}\nn atom: {}", chain_a.name, chain_a.get_number_chain(), chain_a.get_number_residue(), chain_a.get_number_atom());
}
use std::ops::Deref;
/// An `Atom` is a sub-structure linked to a `Residue`.
/// It stores the following properties:
/// - atom name;
/// - atom number (atomid);
/// - Coordinates x, y and z
/// - if the atom is a constituant of the backbone of the protein
///
#[derive(Debug)]
pub struct Atom {
pub name: String,
pub number: u64,
pub coord: [f32; 3],
pub is_backbone: bool,
}
impl Atom {
/// Create a new structure Atom. An atom have a name, a number and x, y, z coordinates
/// If the atom name is "C", "CA", "N", "O", "OT1" or "OT2", it will be consider as backbone
///
/// # Examples
///
/// ````
/// use pdbparser;
///
/// let hydrogen = pdbparser::Atom::new(String::from("HT1"), 1, [0.0, 0.0, 0.0]);
///
/// ````
pub fn new(name: String, number: u64, coord: [f32; 3]) -> Atom {
let n = name.deref();
let back = n == "C" || n == "CA" || n == "N" || n == "O" || n == "OT1" || n == "OT2";
Atom {
name,
number,
coord,
is_backbone: back,
}
}
/// Get the name of the atom
///
pub fn name(self) -> String{
self.name.clone()
}
/// Compute the distance between 2 Atoms
///
/// # Examples
///
/// ````
/// use pdbparser;
///
/// let h1 = pdbparser::Atom::new(String::from("HT1"), 1, [1.0, 5.0, 2.0]);
/// let h2 = pdbparser::Atom::new(String::from("HT1"), 1, [11.0, 17.0, 5.0]);
///
/// assert_eq!(15.905973, h1.compute_distance(&h2));
///
/// ````
pub fn compute_distance(&self, a: &Atom) -> f32 {
(
(self.coord[0] - a.coord[0]).powi(2) +
(self.coord[1] - a.coord[1]).powi(2) +
(self.coord[2] - a.coord[2]).powi(2)
).sqrt()
}
}
use super::residue::Residue;
/// A `Chain` is a sub-structure linked to a `Protein`.
/// It contain one or more `Residue` and a name
///
#[derive(Debug)]
pub struct Chain {
pub name: char,
pub lst_res: Vec<Residue>,
}
impl Chain {
/// Create a new chain structure with an empty list of residue
///
/// # Examples
///
/// ````
/// use pdbparser;
///
/// let my_chain = pdbparser::Chain::new('a');
///
/// ````
pub fn new(name: char) -> Chain {
Chain {
name,
lst_res: Vec::new(),
}
}
/// Add a new structure residue to the Chain
///
/// # Examples
///
/// ````
/// use pdbparser;
///
/// let mut my_chain = pdbparser::Chain::new('a');
/// let lys = pdbparser::Residue::new(String::from("lysine"), 1);
///
/// my_chain.add_res(lys);
///
/// assert_eq!(1, my_chain.get_number_residue());
///
/// ````
pub fn add_res(&mut self, r: Residue) {
self.lst_res.push(r);
}
/// Get the number of residue in the Chain
///
/// # Examples
///
/// ````
/// use pdbparser;
///
/// let my_chain = pdbparser::Chain::new('a');
///
/// assert_eq!(0, my_chain.get_number_residue());
///
/// ````
pub fn get_number_residue(&self) -> u64 {
self.lst_res.len() as u64
}
/// Return a mutable reference of a residue with its name. Return None if the
/// residue does not exist
///
/// # Examples
///
/// ````
/// use pdbparser;
///
/// let mut my_chain = pdbparser::Chain::new('a');
/// let lys = pdbparser::Residue::new(String::from("lysine"), 1);
/// my_chain.add_res(lys);
///
/// assert_eq!(1, my_chain.lst_res[0].res_num);
/// {
/// let mut res_ref = my_chain.get_residue_ref(1).unwrap();
/// res_ref.res_num = 4;
/// }
/// assert_eq!(4, my_chain.lst_res[0].res_num);
///
/// ````
pub fn get_residue_ref(&mut self, n: u64) -> Option<&mut Residue> {
for res in &mut self.lst_res {
if res.res_num == n {
return Some(res)
}
}
None
}
/// Get the name of the Chain
pub fn get_name(&self) -> char {
self.name
}
}
\ No newline at end of file
pub mod atom;
pub mod protein;
pub mod residue;
pub mod read_pdb;
pub mod chain;
mod selection_atom;
\ No newline at end of file
use super::atom::Atom;
use super::chain::Chain;
use super::residue::Residue;
use super::selection_atom;
use std::char;
/// A `Protein` is a struct extract from PDB file. It store `Chain` structure(s)
///
/// The `Protein` is the main structure to manipulate
#[derive(Debug)]
pub struct Protein {
pub name: String,
pub lst_chain: Vec<Chain>,
last_chain_added: char,
}
impl<'a> Protein {
/// Create a new protein structure
///
/// # Examples
///
/// ````
/// use pdbparser;
///
/// let my_prot = pdbparser::Protein::new(String::from("my_prot"));
///
/// ````
pub fn new(n : String) -> Protein {
Protein {
name: n,
lst_chain: Vec::new(),
last_chain_added: ' ',
}
}
/// Get the name of the protein
///
/// # Examples
///
/// ````
/// use pdbparser;
///
/// let my_prot = pdbparser::Protein::new(String::from("my_prot"));
///
/// assert_eq!("my_prot", my_prot.name());
///
/// ````
pub fn name(&self) -> &str {
&self.name
}
/// Return True if the chain is in the protein
///
/// # Examples
///
/// ````
/// use pdbparser;
///
/// let mut my_prot = pdbparser::Protein::new(String::from("my_prot"));
/// let my_chain_a = pdbparser::Chain::new('n');
/// my_prot.add_chain(my_chain_a);
///
/// assert!(my_prot.is_chain('n'));
///
/// ````
pub fn is_chain(&self, c: char) -> bool {
for ii in &self.lst_chain {
if ii.get_name() == c {
return true
}
}
false
}
/// Return a mutable reference of a chaine with its name. Return None if the
/// chain does not exist
///
/// # Examples
///
/// ````
/// use pdbparser;
///
/// let mut my_prot = pdbparser::Protein::new(String::from("my_prot"));
/// my_prot.add_chain(pdbparser::Chain::new('n'));
/// assert_eq!('n', my_prot.lst_chain[0].get_name());
/// {
/// let mut reference = my_prot.get_chain_ref('n').unwrap();
/// reference.name = 'a';
/// }
/// assert_eq!('a', my_prot.lst_chain[0].get_name());
/// ````
pub fn get_chain_ref(&mut self, c: char) -> Option<&mut Chain> {
for chain in &mut self.lst_chain {
if chain.name == c {
return Some(chain)
}
}
None
}
/// Get the number of chain in the protein
///
/// # Examples
///
/// ````
/// use pdbparser;
///
/// let my_prot = pdbparser::Protein::new(String::from("my_prot"));
///
/// assert_eq!(0, my_prot.get_number_chain());
/// ````
pub fn get_number_chain(&self) -> u32 {
self.lst_chain.len() as u32
}
/// Return the number of residue in the protein
///
/// # Examples
///
/// ````
/// use pdbparser;
///
/// let mut my_prot = pdbparser::Protein::new(String::from("my_prot"));
/// let mut my_chain = pdbparser::Chain::new('n');
/// let lys = pdbparser::Residue::new(String::from("lysine"), 1);
/// let pro = pdbparser::Residue::new(String::from("proline"), 2);
///
/// my_chain.add_res(lys);
/// my_chain.add_res(pro);
/// my_prot.add_chain(my_chain);
///
/// assert_eq!(2, my_prot.get_number_residue());
///
/// ````
pub fn get_number_residue(&self) -> u64 {
let mut n: u64 = 0;
for chain in self.lst_chain.iter() {
for _ in chain.lst_res.iter() {
n+= 1;
}
}
n
}
/// Return the number of atom in the protein
///
/// # Examples
///
/// ````
/// use pdbparser;