Skip to content

Commit 2fe69d1

Browse files
author
mlund
committed
Improved readability
1 parent cb67ea1 commit 2fe69d1

File tree

2 files changed

+29
-18
lines changed

2 files changed

+29
-18
lines changed

README.md

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -82,16 +82,14 @@ you may alternatively build and install directly from the source code:
8282
cargo install --git https://github.com/mlund/duello
8383
```
8484

85-
If you have compilation issues, try updating Rust with `rustup toolchain update`.
86-
8785
# Usage
8886

8987
The command-line tool `duello` does the 6D scanning and calculates
9088
the angularly averaged potential of mean force, _A(R)_ which
9189
is used to derive the 2nd virial coefficient and twobody dissociation constant, $K_d$.
9290
The two input structures should be in `.xyz` format and all particle names must
9391
be defined in the topology file under `atoms`.
94-
The topology also defines the particular pair-potential to use.
92+
The topology also defines the particular pair-potential to use, see below.
9593
Note that currently, a coulomb potential is automatically added and should
9694
hence _not_ be specified in the topology.
9795
The program is written in Rust and attempts to use all available CPU cores.
@@ -108,6 +106,24 @@ duello scan \
108106
--temperature 298.15
109107
```
110108

109+
## Preparing PDB files
110+
111+
The following uses `pdb2xyz` to create a coarse grained XYZ file and Calvados topology for Duello:
112+
113+
```sh
114+
pip install pdb2xyz
115+
pdb2xyz -i 4lzt.pdb -o 4lzt.xyz --pH 7.0 --sidechains
116+
duello scan \
117+
-1 4lzt.xyz -2 4lzt.xyz \
118+
--rmin 24 --rmax 80 --dr 0.5 \
119+
--resolution 0.6 \
120+
--top topology.yaml \
121+
--molarity 0.05
122+
```
123+
124+
If `pdb2xyz` give errors, you may be able to correct your PDB file with
125+
[pdbfixer](https://github.com/openmm/pdbfixer?tab=readme-ov-file).
126+
111127
## Examples
112128

113129
Ready run scripts examples are provided in the `scripts/` directory:
@@ -117,12 +133,6 @@ Command | Description
117133
`scripts/cppm.sh` | Spherical, multipolar particles using the CPPM model
118134
`scripts/calvados3.sh` | Two coarse grained lysozyme molecules w. Calvados3 interactions
119135

120-
## Converting PDB files
121-
122-
A simple script to convert protein structure files to coarse grained, one bead
123-
per amino acid XYZ files is provided in `pdb2xyz` which can be installed with
124-
`pip install pdb2xyz`. This can also generate a corresponding `atomfile.yaml`
125-
with atom properties.
126136

127137
## Interaction models
128138

src/icotable.rs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ use core::f64::consts::PI;
2121
use get_size::GetSize;
2222
use itertools::Itertools;
2323
use nalgebra::Matrix3;
24+
use std::fmt::Display;
2425
use std::io::Write;
2526
use std::path::Path;
2627
use std::sync::{Arc, OnceLock};
@@ -130,7 +131,7 @@ impl<T: Clone + GetSize> IcoTable2D<T> {
130131

131132
pub fn angle_resolution(&self) -> f64 {
132133
let n_points = self.data.len();
133-
(4.0 * std::f64::consts::PI / n_points as f64).sqrt()
134+
(4.0 * PI / n_points as f64).sqrt()
134135
}
135136

136137
/// Number of vertices in the table
@@ -146,7 +147,7 @@ impl<T: Clone + GetSize> IcoTable2D<T> {
146147
/// Set data associated with each vertex using a generator function
147148
/// The function takes the index of the vertex and its position
148149
/// Due to the `OnceLock` wrap, this can be done only once!
149-
pub fn set_vertex_data(&self, f: impl Fn(usize, &Vector3) -> T) -> anyhow::Result<()> {
150+
pub fn set_vertex_data(&self, f: impl Fn(usize, &Vector3) -> T) -> Result<()> {
150151
ensure!(
151152
self.data.iter().any(|v| v.get().is_none()),
152153
"Data already set for some vertices"
@@ -326,7 +327,7 @@ impl<T: Clone + GetSize> IcoTable2D<T> {
326327
}
327328
}
328329

329-
impl std::fmt::Display for IcoTable2D<f64> {
330+
impl Display for IcoTable2D<f64> {
330331
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
331332
writeln!(f, "# x y z θ φ data")?;
332333
for (pos, _, data) in self.iter() {
@@ -372,7 +373,7 @@ impl IcoTable4D {
372373
bary_a: &Vector3,
373374
bary_b: &Vector3,
374375
) -> f64 {
375-
let data_ab = Matrix3::<f64>::from_fn(|i, j| {
376+
let data_ab = Matrix3::from_fn(|i, j| {
376377
*self
377378
.get_data(face_a[i])
378379
.get()
@@ -404,7 +405,7 @@ impl Table6D {
404405
// Vertex positions and neighbors are shared across all tables w. thread-safe smart pointer.
405406
// Oncelocked data on the innermost table1 is left uninitialized and should be set later
406407
let vertices = Arc::new(vertices);
407-
let table_b = IcoTable2D::<f64>::from_vertices(vertices.clone(), None); // B: 𝜃 and 𝜑
408+
let table_b = IcoTable2D::from_vertices(vertices.clone(), None); // B: 𝜃 and 𝜑
408409

409410
// We have a new angular resolution, depending on number of subdivisions
410411
let angle_resolution = table_b.angle_resolution();
@@ -455,7 +456,7 @@ pub(crate) fn vmd_draw(
455456
icosphere: &IcoSphere,
456457
color: &str,
457458
scale: Option<f32>,
458-
) -> anyhow::Result<()> {
459+
) -> Result<()> {
459460
let num_faces = icosphere.get_all_indices().len() / 3;
460461
let path = path.with_extension(format!("faces{}.vmd", num_faces));
461462
let mut stream = std::fs::File::create(path)?;
@@ -514,7 +515,7 @@ mod tests {
514515
#[test]
515516
fn test_icosphere_table() {
516517
let icosphere = make_icosphere(3).unwrap();
517-
let icotable = IcoTable2D::<f64>::from_icosphere(&icosphere, 0.0);
518+
let icotable = IcoTable2D::from_icosphere(&icosphere, 0.0);
518519
assert_eq!(icotable.data.len(), 12);
519520

520521
let point = icotable.get_normalized_pos(0);
@@ -560,7 +561,7 @@ mod tests {
560561
#[test]
561562
fn test_icosphere_interpolate() {
562563
let icosphere = make_icosphere(3).unwrap();
563-
let icotable = IcoTable2D::<f64>::from_icosphere_without_data(&icosphere);
564+
let icotable = IcoTable2D::from_icosphere_without_data(&icosphere);
564565
icotable.set_vertex_data(|i, _| i as f64 + 1.0).unwrap();
565566

566567
let point = Vector3::new(0.5, 0.5, 0.5).normalize();
@@ -576,7 +577,7 @@ mod tests {
576577
fn test_face_face_interpolation() {
577578
let n_points = 12;
578579
let icosphere = make_icosphere(n_points).unwrap();
579-
let icotable = IcoTable2D::<f64>::from_icosphere_without_data(&icosphere);
580+
let icotable = IcoTable2D::from_icosphere_without_data(&icosphere);
580581
icotable.set_vertex_data(|i, _| i as f64).unwrap();
581582
let icotable_of_spheres = IcoTable4D::from_min_points(n_points, icotable).unwrap();
582583

0 commit comments

Comments
 (0)