Skip to content

Commit fa9d1ae

Browse files
authored
Merge pull request #2 from Ladme/v0.4
v0.4
2 parents 3063626 + 16ea568 commit fa9d1ae

File tree

176 files changed

+441642
-286
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

176 files changed

+441642
-286
lines changed

CHANGELOG.md

+6
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
## Version 0.4.0
2+
- **Geometry selection:** Added the ability to select a geometric region for analysis. Users can now specify cuboidal, spherical, or cylindrical regions, and order parameters will be calculated only for bonds located within the selected region.
3+
- **Support for reading GRO, PDB, and PQR files:** These file formats are now supported as input structure files. In some cases, an additional "bonds" file specifying the system's connectivity may be required. Refer to the manual for more details.
4+
- **Manual assignment of lipids to leaflets:** Lipids can now be manually assigned to leaflets using a provided leaflet assignment file. Refer to the manual for detailed instructions.
5+
- **Calculating average results for the entire system:** YAML and TAB files now include information about the average order parameters calculated across all bonds and molecule types in the system. Additionally, ordermaps are generated for the entire system.
6+
17
## Version 0.3.0
28
- **Error estimation and convergence analysis**: Implemented error estimation and convergence analysis. Refer to the corresponding section of the manual for more details.
39
- **Leaflet classification**: Leaflet classification can now also be performed either every N analyzed trajectory frames or only once at the start of the analysis.

Cargo.lock

+84-5
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+8-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
[package]
22
name = "gorder"
3-
version = "0.3.0"
3+
version = "0.4.0"
44
description = "Calculating lipid order parameters from Gromacs simulations"
55
edition = "2021"
6+
rust-version = "1.82"
67
license = "MIT"
78
repository = "https://github.com/Ladme/gorder"
89
keywords = ["gromacs", "molecular-dynamics", "order", "nmr", "lipids"]
@@ -11,7 +12,11 @@ exclude = ["/tests", "/validation"]
1112

1213
[dependencies]
1314
backitup = "0.1.1"
14-
groan_rs = { version = "0.10.0-dev.1", features = ["parallel", "no-xdrfile"] }
15+
groan_rs = { version = "0.10.0-dev.2", features = [
16+
"parallel",
17+
"no-xdrfile",
18+
"serde",
19+
] }
1520
colored = "2.1"
1621
thiserror = "2.0.3"
1722
derive_builder = "0.20.2"
@@ -32,3 +37,4 @@ parking_lot = "0.12.3"
3237
approx = "0.5.1"
3338
tempfile = "3.14.0"
3439
assert_cmd = "2.0.16"
40+
rand = "0.8.5"

README.md

+7-7
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ $ cargo install gorder
2020
structure: system.tpr
2121
trajectory: md.xtc # use your MD trajectory directly - no PBC handling or molecule fixing needed
2222
analysis_type: !AAOrder
23-
heavy_atoms: "@membrane and element name carbon"
24-
hydrogens: "@membrane and element name hydrogen"
23+
heavy_atoms: "element name carbon"
24+
hydrogens: "element name hydrogen"
2525
output: order.yaml
2626
```
2727
@@ -38,19 +38,19 @@ $ gorder YOUR_INPUT_YAML_FILE
3838
## Features
3939
- **Atomistic and coarse-grained systems.** `gorder` is able to calculate atomistic and coarse-grained order parameters for individual bonds of individual lipid types.
4040
- **Powerful selection language.** `gorder` allows for simple yet powerful atom selection using a VMD-like selection language, supporting regular expressions and groups from NDX files. (Read more about the language [here](https://ladme.github.io/gsl-guide/).)
41-
- **Automatic identification of molecule types.** `gorder` automatically recognizes bonds and classifies molecule types based on their topology.
41+
- **Automatic identification of molecule types.** `gorder` automatically recognizes bonds and classifies molecule types based on their topology. Order parameters are calculated and reported separately for each molecule type.
4242
- **Various output formats.** `gorder` can output results in YAML, XVG, CSV, and custom "table" format.
43+
- **Supports any force-field.** `gorder` is completely force-field agnostic. Martini? CHARMM? Slipids? Your own toy force-field? As long as your lipids have bonds, it will work.
4344
- **Leaflet-wise analysis.** `gorder` can perform scrambling-safe assignment of lipids to membrane leaflets using three different methods, and then calculate lipid order parameters for individual leaflets.
4445
- **Order parameter maps.** `gorder` can construct 2D maps of order parameters, so you know what parts of the membrane are ordered and disordered.
4546
- **Error estimation.** `gorder` can automatically estimate the error of the analysis and indicate how well your analysis has converged.
46-
- **Supports any force-field.** `gorder` is completely force-field agnostic. Martini? CHARMM? Slipids? Your own toy force-field? As long as your lipids have bonds, it will work.
47+
- **Analysis of specific membrane regions.** `gorder` can dynamically select lipids in a specified part of the membrane and calculate order parameters only for them.
4748
- **Extremely fast.** `gorder` is extremely fast (see [below](#benchmarking)) due to its ability to read only the necessary atoms from XTC files and its support for multithreading.
4849
4950
## Planned
50-
- [ ] Dynamic selection of lipids for order parameter calculation based on geometric conditions (i.e., only calculating order parameters from a part of a membrane).
51-
- [ ] Dynamic membrane normal calculation, supporting membrane vesicles.
52-
- [ ] Python API: using `gorder` as a Python library.
5351
- [ ] United-atom order parameters.
52+
- [ ] Python API: using `gorder` as a Python library.
53+
- [ ] Dynamic membrane normal calculation, supporting membrane vesicles.
5454
- [ ] Improved multithreading (currently, multithreading is only implemented at the trajectory reading level).
5555
5656
## Validation

src/analysis/aaorder.rs

+35-9
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,24 @@
44
//! Contains the implementation of the calculation of the atomistic order parameters.
55
66
use super::{common::macros::group_name, topology::SystemTopology};
7-
use crate::analysis::common::{analyze_frame, prepare_master_group, sanity_check_molecules};
7+
use crate::analysis::common::{
8+
analyze_frame, prepare_geometry_selection, prepare_master_group, sanity_check_molecules,
9+
};
10+
use crate::analysis::structure;
811
use crate::errors::{AnalysisError, TopologyError};
12+
use crate::input::LeafletClassification;
913
use crate::presentation::aaresults::AAOrderResults;
1014
use crate::presentation::{AnalysisResults, OrderResults};
1115
use crate::{input::Analysis, PANIC_MESSAGE};
1216

17+
use groan_rs::prelude::ProgressPrinter;
1318
use groan_rs::prelude::{GroupXtcReader, OrderedAtomIterator};
14-
use groan_rs::{files::FileType, prelude::ProgressPrinter, system::System};
1519

1620
/// Calculate the atomistic order parameters.
17-
pub(super) fn analyze_atomistic<'a>(
21+
pub(super) fn analyze_atomistic(
1822
analysis: Analysis,
1923
) -> Result<AnalysisResults, Box<dyn std::error::Error + Send + Sync>> {
20-
let mut system = System::from_file_with_format(analysis.structure(), FileType::TPR)?;
21-
log::info!("Read molecular topology from '{}'.", analysis.structure());
24+
let mut system = structure::read_structure_and_topology(&analysis)?;
2225

2326
if let Some(ndx) = analysis.index() {
2427
system.read_ndx(ndx)?;
@@ -83,6 +86,9 @@ pub(super) fn analyze_atomistic<'a>(
8386
leaflet.prepare_system(&mut system)?;
8487
}
8588

89+
let geom = prepare_geometry_selection(analysis.geometry().as_ref(), &mut system)?;
90+
geom.info();
91+
8692
log::info!("Detecting molecule types...");
8793
log::logger().flush();
8894

@@ -103,15 +109,22 @@ pub(super) fn analyze_atomistic<'a>(
103109
return Ok(AnalysisResults::AA(AAOrderResults::empty(analysis)));
104110
}
105111

106-
let data = SystemTopology::new(
112+
let mut data = SystemTopology::new(
107113
molecules,
108114
analysis.membrane_normal().into(),
109115
analysis.estimate_error().clone(),
110116
analysis.step(),
111117
analysis.n_threads(),
118+
geom,
112119
);
120+
113121
data.info();
114122

123+
// finalize the manual leaflet classification
124+
if let Some(LeafletClassification::Manual(params)) = analysis.leaflets() {
125+
data.finalize_manual_leaflet_classification(params)?;
126+
}
127+
115128
let progress_printer = if analysis.silent() {
116129
None
117130
} else {
@@ -150,6 +163,9 @@ pub(super) fn analyze_atomistic<'a>(
150163
progress_printer,
151164
)?;
152165

166+
if let Some(LeafletClassification::Manual(_)) = analysis.leaflets() {
167+
result.validate_manual_leaflet_classification(&analysis)?;
168+
}
153169
result.log_total_analyzed_frames();
154170

155171
// print basic info about error estimation
@@ -163,11 +179,14 @@ pub(super) fn analyze_atomistic<'a>(
163179
#[cfg(test)]
164180
mod tests {
165181
use approx::assert_relative_eq;
166-
use groan_rs::prelude::Dimension;
182+
use groan_rs::{prelude::Dimension, system::System};
167183

168184
use super::*;
169185
use crate::{
170-
analysis::molecule::{BondType, MoleculeType},
186+
analysis::{
187+
geometry::GeometrySelectionType,
188+
molecule::{BondType, MoleculeType},
189+
},
171190
input::leaflets::LeafletClassification,
172191
};
173192

@@ -209,7 +228,14 @@ mod tests {
209228

210229
(
211230
system,
212-
SystemTopology::new(molecules, Dimension::Z, None, 1, 1),
231+
SystemTopology::new(
232+
molecules,
233+
Dimension::Z,
234+
None,
235+
1,
236+
1,
237+
GeometrySelectionType::default(),
238+
),
213239
)
214240
}
215241

0 commit comments

Comments
 (0)