22 unstable releases (9 breaking)
new 0.10.0-dev.2 | Jan 13, 2025 |
---|---|
0.9.0 | Dec 6, 2024 |
0.9.0-dev.2 | Nov 23, 2024 |
0.8.1 | Jun 23, 2024 |
0.5.0 | Nov 24, 2023 |
#292 in Science
513 downloads per month
Used in 2 crates
1.5MB
34K
SLoC
groan_rs: Gromacs Analysis Library for Rust
Rust library for analyzing Gromacs simulations.
While the library is no longer in an early stage of development, it is still unstable. Breaking changes can appear in any new version.
Usage
Run
$ cargo add groan_rs
Import the crate in your Rust code:
use groan_rs::prelude::*;
License
This library is released under the MIT License.
Full documentation
For full documentation see the corresponding docs.rs page.
lib.rs
:
groan_rs: Gromacs Analysis Library for Rust
Rust library for analyzing Gromacs simulations.
While the library is no longer in an early stage of development, it is still unstable. Breaking changes can appear in any new version.
What it can do
- Read and write gro, pdb, pqr, ndx, xtc and trr files.
- Read topology and structure of the system from tpr files (using the
minitpr
crate). - Iterate over atoms and access their properties, including connectivity (bonds).
- Select atoms using a selection language similar to VMD.
- Calculate RMSD and perform RMSD fit for individual structures and for entire trajectories.
- Calculate distances between atoms respecting periodic boundary conditions.
- Select atoms based on geometric conditions.
- Assign elements to atoms and guess connectivity between the atoms.
- Calculate center of geometry or mass for any group of atoms.
- Center a group of atoms in a simulation box.
- Perform multithreaded iteration over a trajectory (if the
parallel
feature is enabled). - Help with specific analyses by providing utility data structures (e.g.,
GridMaps
). - Some other minor stuff...
What it CAN'T do (at the moment)
- Work with non-orthogonal periodic boundary conditions.
- Perform advanced analyses of structure and dynamics out of the box.
(But
groan_rs
library tries to make it simple to implement your own!)
Usage
Run
$ cargo add groan_rs
Import the crate in your Rust code:
use groan_rs::prelude::*;
Examples
Analyzing structure files
You can read structure files in various formats (GRO, PDB, PQR, TPR), add groups from NDX files, and perform analyses.
use groan_rs::prelude::*;
use std::error::Error;
fn main() -> Result<(), Box<dyn Error + Send + Sync>> {
// read a structure file (in GRO, PDB, PQR, or TPR format)
let mut system = System::from_file("system.gro")?;
// read an NDX file
// NDX groups will be automatically created inside `system`
system.read_ndx("index.ndx")?;
// calculate the center of geometry of a protein
// 'Protein' is the name of a group from the NDX file
let center = system.group_get_center("Protein")?;
// print the result
println!("{:?}", center);
Ok(())
}
Selecting atoms
You can select atoms using a query language similar to VMD.
use groan_rs::prelude::*;
use std::error::Error;
fn main() -> Result<(), Box<dyn Error + Send + Sync>> {
let system = System::from_file("system.gro")?;
// select some atoms using the groan selection language and iterate through them
for atom in system.selection_iter("serial 1-23 or (resname POPC and name P)")? {
// perform some operation with the atom
}
// you can temporarily store the selection iterator in a variable
// see the `@protein` query? => groan can autodetect common structures
// like atoms of membrane lipids or proteins
let iterator = system.selection_iter("@protein")?;
Ok(())
}
Creating groups
You can select atoms and save them into a group. This group is stored inside the system and can be quickly accessed multiple times.
use groan_rs::prelude::*;
use std::error::Error;
fn main() -> Result<(), Box<dyn Error + Send + Sync>> {
let mut system = System::from_file("system.gro")?;
// select atoms and store them into a group 'Selected'
system.group_create("Selected", "serial 1-23 or (resname POPC and name P)")?;
// iterate through the selected atoms
for atom in system.group_iter("Selected")? {
// perform some operation with the atom
}
// use the previously created group to construct another group
system.group_create("Some Atoms", "Selected || resid 87 to 124")?;
// modify the atoms in the group 'Some Atoms'
for atom in system.group_iter_mut("Some Atoms")? {
atom.set_residue_name("RES");
}
// each system always contains two groups called 'all' and 'All'
// these groups contain all the atoms in the system
assert!(system.group_exists("all"));
assert!(system.group_exists("All"));
Ok(())
}
Writing output structure files
You can write structure files in GRO, PDB, or PQR format.
use groan_rs::prelude::*;
use std::error::Error;
fn main() -> Result<(), Box<dyn Error + Send + Sync>> {
let mut system = System::from_file("system.gro")?;
// write the entire system as a PDB file
system.write_pdb("system.pdb", false)?;
// write only DNA atoms as a GRO file
system.group_create("DNA", "@dna")?;
system.group_write_gro("DNA", "dna.gro", false)?;
Ok(())
}
Geometry filtering of atoms
You can select atoms based on geometric conditions.
use groan_rs::prelude::*;
use std::error::Error;
fn main() -> Result<(), Box<dyn Error + Send + Sync>> {
// when reading a TPR file, you get information about
// the masses of atoms and connectivity between atoms
let mut system = System::from_file("system.tpr")?;
// load groups into the system
system.read_ndx("index.ndx")?;
// get the center of mass of the group 'Protein'
let protein_com = system.group_get_com("Protein")?;
// construct a cylinder with its base in the protein center of mass,
// a radius of 2 nm, height of 4 nm, and oriented along the z-axis
let cylinder = Cylinder::new(protein_com, 2.0, 4.0, Dimension::Z);
// iterate over atoms of water molecules located inside the cylinder
for atom in system.group_iter("Water")?.filter_geometry(cylinder) {
// perform some operation with the atom
}
Ok(())
}
Analyzing trajectory files
You can read trajectory files in XTC, TRR, or GRO format.
use groan_rs::prelude::*;
use std::error::Error;
fn main() -> Result<(), Box<dyn Error + Send + Sync>> {
let mut system = System::from_file("system.gro")?;
// load groups into the system
system.read_ndx("index.ndx")?;
for frame in system.xtc_iter("trajectory.xtc")? {
// check that the frame has been read correctly
let frame = frame?;
// calculate distance between two groups of atoms
let distance = frame.group_distance("Protein1", "Protein2", Dimension::XYZ)?;
}
Ok(())
}
You can also read only part of the trajectory file and/or skip some trajectory frames. You can concatenate trajectory files and print the progress of any trajectory iteration.
use groan_rs::prelude::*;
use std::error::Error;
fn main() -> Result<(), Box<dyn Error + Send + Sync>> {
let mut system = System::from_file("system.gro")?;
// read multiple trajectory files with additional options
for frame in system
.xtc_cat_iter(&["md1.xtc", "md2.xtc", "md3.xtc"])?
.with_range(50_000.0, 225_000.0)? // start at 50 ns, end at 225 ns
.with_step(3)? // read every 3rd step
.print_progress(ProgressPrinter::default()) {
// check that the frame has been read correctly
let frame = frame?;
// continue working with the frame
}
Ok(())
}
Calculating RMSD
You can calculate RMSD for two systems or for entire trajectories.
use groan_rs::prelude::*;
use std::error::Error;
fn main() -> Result<(), Box<dyn Error + Send + Sync>> {
let mut system = System::from_file("system.gro")?;
let system2 = System::from_file("system2.gro")?;
// calculate RMSD between all atoms of `system` and `system2`
let rmsd = system.calc_rmsd(&system2, "all")?;
// calculate RMSD for an entire trajectory
let reference = system.clone();
for frame_data in system.xtc_iter("trajectory.xtc")?.calc_rmsd(&reference, "all")? {
let (frame, rmsd) = frame_data?;
println!("{}: {}", frame.get_simulation_time(), rmsd);
}
Ok(())
}
Writing trajectory files
You can not only read but also write trajectory files in XTC, TRR, or GRO format.
use groan_rs::prelude::*;
use std::error::Error;
fn main() -> Result<(), Box<dyn Error + Send + Sync>> {
let mut system = System::from_file("system.gro")?;
// open an XTC file as output trajectory file
system.xtc_writer_init("trajectory.xtc")?;
// read frames from a TRR trajectory and write them in an XTC format
for frame in system.trr_iter("trajectory.trr")? {
let frame = frame?;
// write the frame into all open trajectory files associated with the system
frame.traj_write_frame()?;
}
Ok(())
}
Selecting atoms using GSL
Groan selection language (GSL) is a query language for selecting atoms in the groan_rs
library. In general, GSL is similar to the selection language used by VMD.
To understand the capabilities (and limitations) of the language, read this guide.
Error handling
Proper error handling and propagation is at heart of the groan_rs
library.
The individual error types provided by the groan_rs
are however not exported into the prelude
module.
If you want to use specific error type from the groan_rs
library, you will have to include
it explicitly from the errors
module. For instance, if you want to directly work with errors
that can occur when writing a pdb file, use:
use groan_rs::errors::WritePdbError;
Note that groan_rs
will still work correctly even if you do not explicitly include the error types.
Features
Default
molly
: Blazingly Fast Reading of XTC Files- Enables the use of the
molly
crate for very fast reading of xtc files. - Enables the use of
GroupXtcReader
for partial reading of XTC frames. - This feature is enabled by default.
- If disabled,
xdrfile
library will be used instead to read XTC files and partial reading of XTC frames will not be supported.
- Enables the use of the
Additional
-
serde
: Serialization Support- Enables the serialization and deserialization of
groan_rs
data structures through integration with theserde
framework.
- Enables the serialization and deserialization of
-
parallel
: Concurrency- Expands the
groan_rs
library with functions designed for multi-threaded execution.
- Expands the
-
no-xdrfile
: Pure Rust experience with no external C libraries- Removes the compilation and use of
xdrfile
library. - If enabled, you will lose the ability to write XTC files and both read and write TRR files.
- Removes the compilation and use of
Install the groan_rs
crate with a specific feature using cargo add groan_rs --features [FEATURE]
.
Limitations
-
Currently,
groan_rs
library is not able to properly work with periodic simulation boxes that are not orthogonal. While it can read structures and trajectories with non-orthogonal boxes, calculated distances and similar properties may be incorrect! Tread very carefully! -
While
groan_rs
can read double-precision trr and tpr files, it uses single-precision floating point numbers everywhere in its code. If you require double-precision for your analyses, look elsewhere.
License
This library is released under the MIT License.
Dependencies
~16–25MB
~412K SLoC