Skip to content
This repository was archived by the owner on Mar 10, 2026. It is now read-only.

Commit 9622f6d

Browse files
authored
Merge pull request #45 from caltechmsc/docs/44-implement-comprehensive-project-documentation
docs(project): Implement Comprehensive User, API, and Developer Documentation
2 parents a07686d + 17b1a80 commit 9622f6d

57 files changed

Lines changed: 7983 additions & 111 deletions

Some content is hidden

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

.github/workflows/release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ jobs:
6969
SOURCE_PATH="target/${{ matrix.target }}/release/$BINARY_NAME"
7070
7171
cp "$SOURCE_PATH" "$ARTIFACT_DIR/$BINARY_NAME"
72-
cp LICENSE README.md "$ARTIFACT_DIR/"
72+
cp LICENSE README.md docs/cli/USAGE.md docs/cli/config.template.toml "$ARTIFACT_DIR/"
7373
7474
cd $ARTIFACT_DIR
7575

README.md

Lines changed: 110 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,120 @@ The core mission of SCREAM++ is to provide a robust, reliable, and easy-to-use t
1212
- **Flexible Optimization Modes**: Supports both global side-chain optimization and focused refinement within a defined **binding site** or region of interest.
1313
- **Modern Tooling**: Managed by Cargo for simple, reproducible builds and dependency management.
1414
- **Multiple Interfaces**:
15-
- **Standalone CLI**: An easy-to-use command-line interface for standard prediction tasks.
16-
- **Python Package**: A user-friendly Python API (via PyO3) for scripting, integration, and advanced workflows.
17-
- **C-Compatible Library**: A C FFI layer for integration with C, C++, and other programming languages.
18-
- **Native Rust Crate**: A core Rust library (`screampp`) available on crates.io for direct use in other Rust-based scientific computing projects.
15+
- **Standalone CLI**: A powerful and easy-to-use command-line interface for all prediction tasks.
16+
- **Native Rust Crate**: The core library (`screampp`) is available on [crates.io](https://crates.io/crates/screampp) for direct use in other Rust-based scientific computing projects.
17+
- **Python Package (Future)**: A user-friendly Python API (via PyO3) for scripting and integration is planned for future releases.
18+
- **C-Compatible Library (Future)**: A C FFI layer for integration with C, C++, and other languages is planned for future releases.
19+
20+
## Getting Started
21+
22+
There are two main ways to use SCREAM++: as a standalone command-line tool or as a library in your own Rust project.
23+
24+
### 1. Using the Command-Line Interface (CLI)
25+
26+
This is the recommended method for most users.
27+
28+
#### Step 1: Download the executable
29+
30+
Go to the [**GitHub Releases page**](https://github.com/caltechmsc/screampp/releases) and download the pre-compiled binary for your operating system (Linux, macOS, Windows). Unzip the archive.
31+
32+
#### Step 2: Download the required data files
33+
34+
The first time you run the CLI, you must download the necessary forcefield and rotamer library files. This is a one-time setup.
35+
36+
```bash
37+
# On Linux/macOS
38+
./scream data download
39+
40+
# On Windows (Command Prompt)
41+
scream.exe data download
42+
```
43+
44+
This command will fetch and unpack the data to a default location on your system.
45+
46+
#### Step 3: Run a prediction
47+
48+
You are now ready to run a side-chain placement job.
49+
50+
```bash
51+
# Optimize all side-chains in input.bgf and save the result
52+
./scream place -i path/to/input.bgf -o path/to/output.bgf
53+
```
54+
55+
For detailed instructions on all commands, options, and advanced configuration, please refer to the [**CLI User Manual**](docs/cli/USAGE.md).
56+
57+
### 2. Using as a Rust Library
58+
59+
If you are a Rust developer, you can add `screampp` as a dependency to your project.
60+
61+
#### Step 1: Add to `Cargo.toml`
62+
63+
```toml
64+
[dependencies]
65+
screampp = "0.5.0"
66+
```
67+
68+
#### Step 2: Use in your code
69+
70+
You can now use the high-level `workflows` API to perform side-chain placement programmatically.
71+
72+
```rust
73+
use screampp::core::io::bgf::BgfFile;
74+
use screampp::engine::config::{PlacementConfigBuilder, ResidueSelection, ConvergenceConfig};
75+
use screampp::engine::progress::ProgressReporter;
76+
use screampp::workflows::place;
77+
78+
fn run_placement() -> Result<(), Box<dyn std::error::Error>> {
79+
let (system, metadata) = BgfFile::read_from_path("path/to/input.bgf")?;
80+
81+
let config = PlacementConfigBuilder::new()
82+
.forcefield_path("path/to/data/forcefield/dreiding-lj-12-6-0.4.toml")
83+
.delta_params_path("path/to/data/delta/delta-rmsd-1.0.csv")
84+
.s_factor(1.1)
85+
.rotamer_library_path("path/to/data/rotamers/charmm@rmsd-1.0.toml")
86+
.topology_registry_path("path/to/data/topology/registry.toml")
87+
.residues_to_optimize(ResidueSelection::All)
88+
.max_iterations(100)
89+
.num_solutions(1)
90+
.include_input_conformation(true)
91+
.final_refinement_iterations(2)
92+
.convergence_config(ConvergenceConfig {
93+
energy_threshold: 0.01,
94+
patience_iterations: 5,
95+
})
96+
.build()?;
97+
98+
let reporter = ProgressReporter::new(); // Or provide a callback for progress updates
99+
let result = place::run(&system, &config, &reporter)?;
100+
101+
if let Some(best_solution) = result.solutions.first() {
102+
println!("Best energy: {:.2} kcal/mol", best_solution.total_energy);
103+
}
104+
105+
Ok(())
106+
}
107+
```
108+
109+
## Documentation
110+
111+
Comprehensive documentation is available for both users and developers.
112+
113+
- **For Users**:
114+
115+
- [**CLI User Manual**](docs/cli/USAGE.md): A complete guide to installing and using the `scream` command-line tool, including detailed explanations of all commands, configuration options, and practical examples.
116+
117+
- **For Developers**:
118+
119+
- [**Rust Library API Docs (docs.rs)**](https://docs.rs/screampp): The official, versioned API documentation for the `scream-core` (`screampp`) crate, generated by `rustdoc`. This is the best resource for understanding the public API of the library.
120+
- **Developer Documentation**: In-depth documentation covering the architecture, data models, algorithms, and design philosophy of the entire project. This is essential reading for anyone looking to contribute to or deeply understand the internals of SCREAM++.
121+
- [**`scream-core` Developer Docs**](docs/dev/core/README.md): Details the internal architecture, data models, and algorithms of the `scream-core` library.
122+
- [**`scream-cli` Developer Docs**](docs/dev/cli/README.md): Provides a comprehensive technical breakdown of the `scream-cli` crate, including execution flow, configuration handling, and data management.
19123

20124
## Tech Stack
21125

22-
- **Language**: Rust
23-
- **Supported Languages**: Rust, Python (via PyO3), C/C++ (via FFI)
126+
- **Core Language**: Rust
24127
- **Build System**: Cargo
128+
- **Planned Interfaces**: Python (via PyO3), C/C++ (via FFI)
25129

26130
## License
27131

crates/scream-core/src/core/forcefield/energy.rs

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,59 @@ use crate::core::models::ids::ResidueId;
44
use std::f64::consts::PI;
55
use thiserror::Error;
66

7+
/// Represents errors that can occur during energy calculations in the force field.
8+
///
9+
/// This enum encapsulates various error conditions that may arise when computing
10+
/// interaction energies between atoms, providing detailed context for debugging
11+
/// and error handling in molecular simulations.
712
#[derive(Debug, Error)]
813
pub enum EnergyCalculationError {
14+
/// Indicates that an atom lacks the necessary parameters for van der Waals energy calculation.
15+
///
16+
/// This error occurs when attempting to compute VDW interactions for atoms that have
17+
/// not been parameterized with appropriate force field parameters (e.g., Lennard-Jones
18+
/// or Buckingham parameters).
919
#[error(
1020
"Atom '{atom_name}' in residue {residue_id:?} is not parameterized for VDW calculation"
1121
)]
1222
UnparameterizedAtom {
23+
/// The name of the atom that is missing parameters.
1324
atom_name: String,
25+
/// The ID of the residue containing the unparameterized atom.
1426
residue_id: ResidueId,
1527
},
1628
}
1729

30+
/// Provides static methods for calculating various types of molecular interaction energies.
31+
///
32+
/// This struct serves as a utility for computing energy contributions from different
33+
/// force field terms, including van der Waals, electrostatic, and hydrogen bonding
34+
/// interactions. All methods are designed to work with the SCREAM++ molecular
35+
/// data structures and follow standard force field conventions.
1836
pub struct EnergyCalculator;
1937

2038
impl EnergyCalculator {
39+
/// Calculates the van der Waals interaction energy between two atoms.
40+
///
41+
/// This method computes the VDW energy using either Lennard-Jones 12-6 or Buckingham
42+
/// exponential-6 potentials, depending on the parameterization of the atoms. It combines
43+
/// parameters from both atoms using standard mixing rules and applies a flat-bottom
44+
/// modification based on the atoms' delta values to handle close contacts.
45+
///
46+
/// # Arguments
47+
///
48+
/// * `atom1` - The first atom participating in the interaction
49+
/// * `atom2` - The second atom participating in the interaction
50+
///
51+
/// # Return
52+
///
53+
/// Returns the calculated VDW energy in kcal/mol. Positive values indicate repulsive
54+
/// interactions, negative values indicate attractive interactions.
55+
///
56+
/// # Errors
57+
///
58+
/// Returns `EnergyCalculationError::UnparameterizedAtom` if either atom lacks
59+
/// VDW parameters.
2160
pub fn calculate_vdw(atom1: &Atom, atom2: &Atom) -> Result<f64, EnergyCalculationError> {
2261
let extract_params = |atom: &Atom| match atom.vdw_param {
2362
CachedVdwParam::LennardJones { radius, well_depth } => Ok((radius, well_depth, 0.0)),
@@ -37,6 +76,7 @@ impl EnergyCalculator {
3776

3877
let dist = (atom1.position - atom2.position).norm();
3978

79+
// Combine delta values to determine the flat-bottom cutoff distance
4080
let total_delta = (atom1.delta.powi(2) + atom2.delta.powi(2)).sqrt();
4181
let r_min_combined = (r_min1 + r_min2) / 2.0;
4282
let well_depth_combined = (well_depth1 * well_depth2).sqrt();
@@ -54,11 +94,46 @@ impl EnergyCalculator {
5494
Ok(energy)
5595
}
5696

97+
/// Calculates the electrostatic Coulomb interaction energy between two atoms.
98+
///
99+
/// This method computes the electrostatic energy using Coulomb's law with a distance-
100+
/// dependent dielectric constant. The calculation assumes point charges and does not
101+
/// include any cutoff or screening effects beyond the dielectric.
102+
///
103+
/// # Arguments
104+
///
105+
/// * `atom1` - The first atom participating in the interaction
106+
/// * `atom2` - The second atom participating in the interaction
107+
/// * `dielectric` - The dielectric constant of the medium (dimensionless)
108+
///
109+
/// # Return
110+
///
111+
/// Returns the calculated Coulomb energy in kcal/mol. The sign depends on the
112+
/// charges: positive for like charges, negative for opposite charges.
57113
pub fn calculate_coulomb(atom1: &Atom, atom2: &Atom, dielectric: f64) -> f64 {
58114
let dist = (atom1.position - atom2.position).norm();
59115
potentials::coulomb(dist, atom1.partial_charge, atom2.partial_charge, dielectric)
60116
}
61117

118+
/// Calculates the hydrogen bonding interaction energy between donor, hydrogen, and acceptor atoms.
119+
///
120+
/// This method implements the Dreiding hydrogen bond potential with a 12-10 distance
121+
/// dependence and an angular term based on the donor-hydrogen-acceptor angle. The
122+
/// potential is zero for angles ≤ 90° and includes a flat-bottom modification for
123+
/// close contacts based on the atoms' delta values.
124+
///
125+
/// # Arguments
126+
///
127+
/// * `donor` - The donor atom in the hydrogen bond
128+
/// * `hydrogen` - The hydrogen atom attached to the donor
129+
/// * `acceptor` - The acceptor atom in the hydrogen bond
130+
/// * `r_hb` - The equilibrium hydrogen bond distance in Å
131+
/// * `d_hb` - The well depth of the hydrogen bond potential in kcal/mol
132+
///
133+
/// # Return
134+
///
135+
/// Returns the calculated hydrogen bond energy in kcal/mol. Negative values indicate
136+
/// favorable hydrogen bonding interactions.
62137
pub fn calculate_hbond(
63138
donor: &Atom,
64139
hydrogen: &Atom,
@@ -71,10 +146,12 @@ impl EnergyCalculator {
71146
let v_hd = donor.position - hydrogen.position;
72147
let angle_ahd_deg = v_ha.angle(&v_hd).to_degrees();
73148

149+
// Hydrogen bonds are only considered for angles > 90°
74150
if angle_ahd_deg <= 90.0 {
75151
return 0.0;
76152
}
77153

154+
// Combine delta values for flat-bottom cutoff
78155
let total_delta = (acceptor.delta.powi(2) + donor.delta.powi(2)).sqrt();
79156
let distance_potential_fn =
80157
|d: f64| -> f64 { potentials::dreiding_hbond_12_10(d, r_hb, d_hb) };
Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,43 @@
1-
pub mod energy;
1+
//! # Force Field Module
2+
//!
3+
//! This module provides the core functionality for molecular mechanics force field calculations
4+
//! in the SCREAM++ protein side-chain placement library. It implements energy evaluation,
5+
//! parameter management, and scoring algorithms for molecular interactions.
6+
//!
7+
//! ## Overview
8+
//!
9+
//! The force field module is responsible for computing interaction energies between atoms
10+
//! and molecular groups using classical molecular mechanics potentials. It supports:
11+
//!
12+
//! - **Van der Waals interactions** using Lennard-Jones and Buckingham potentials
13+
//! - **Electrostatic interactions** with Coulomb's law and distance-dependent dielectric
14+
//! - **Hydrogen bonding** using specialized 12-10 potentials
15+
//! - **Energy weighting** based on atom roles (backbone vs sidechain)
16+
//! - **Parameter management** for different force field types and atom types
17+
//!
18+
//! ## Key Components
19+
//!
20+
//! - [`params`] - Force field parameter structures and configuration
21+
//! - [`scoring`] - High-level energy scoring interface for molecular systems
22+
//! - [`term`] - Energy term aggregation and reporting
23+
//! - [`parameterization`] - Automatic assignment of force field parameters to atoms
24+
//!
25+
//! ## Usage
26+
//!
27+
//! The main entry point for energy calculations is the [`scoring::Scorer`] struct,
28+
//! which provides methods to compute interaction energies between atom groups while
29+
//! properly handling bonded exclusions and energy weighting.
30+
//!
31+
//! ```ignore
32+
//! use screampp::core::forcefield::scoring::Scorer;
33+
//!
34+
//! let scorer = Scorer::new(&system, &forcefield);
35+
//! let energy = scorer.score_interaction(query_atoms, environment_atoms)?;
36+
//! ```
37+
38+
pub(crate) mod energy;
239
pub mod parameterization;
340
pub mod params;
4-
pub mod potentials;
41+
pub(crate) mod potentials;
542
pub mod scoring;
643
pub mod term;

0 commit comments

Comments
 (0)