| Crates.io | voronota-ltr |
| lib.rs | voronota-ltr |
| version | 0.1.0 |
| created_at | 2026-01-22 12:47:53.515115+00 |
| updated_at | 2026-01-22 12:47:53.515115+00 |
| description | Voronota-LT is an alternative version of Voronota for constructing tessellation-derived atomic contact areas and volumes. |
| homepage | https://www.voronota.com/expansion_lt |
| repository | https://github.com/mlund/voronota-ltr |
| max_upload_size | |
| id | 2061475 |
| size | 999,720 |
Experimental, native Rust port of voronota-lt originally written in C++. Replaces the previous bindings crate. Computes radical Voronoi tessellation of atomic balls constrained inside a solvent-accessible surface. Outputs inter-atom contact areas, solvent accessible surface (SAS) areas, and volumes.
f5ad92de4e9723ab767db3e5035c0e7532f31595)The port can be used either as a library for other projects, or as a basic CLI tool:
cargo install voronota-ltr
use voronota_ltr::{Ball, Results, compute_tessellation};
let balls = vec![
Ball::new(0.0, 0.0, 0.0, 1.5),
Ball::new(3.0, 0.0, 0.0, 1.5),
Ball::new(1.5, 2.5, 0.0, 1.5),
];
let result = compute_tessellation(&balls, 1.4, None, None);
// Per-ball SAS areas and volumes (indexed by ball)
let sas_areas: Vec<f64> = result.sas_areas();
let volumes: Vec<f64> = result.volumes();
// Total SAS area
let total_sas: f64 = result.total_sas_area();
// Detailed contact and cell data
for contact in &result.contacts {
println!("Contact {}-{}: area={:.2}", contact.id_a, contact.id_b, contact.area);
}
use voronota_ltr::{Ball, PeriodicBox, compute_tessellation};
let balls = vec![Ball::new(0.0, 0.0, 0.0, 1.5)];
let pbox = PeriodicBox::from_corners((0.0, 0.0, 0.0), (10.0, 10.0, 10.0));
let result = compute_tessellation(&balls, 1.4, Some(&pbox), None);
For simulations where only a few spheres change position each step, UpdateableTessellation
provides efficient incremental updates:
use voronota_ltr::{Ball, UpdateableTessellation};
let mut balls = vec![
Ball::new(0.0, 0.0, 0.0, 1.0),
Ball::new(2.0, 0.0, 0.0, 1.0),
Ball::new(4.0, 0.0, 0.0, 1.0),
];
// Create with backup support for undo
let mut tess = UpdateableTessellation::with_backup();
tess.init(&balls, 1.0, None);
// Move first sphere
balls[0].x += 0.1;
tess.update_with_changed(&balls, &[0]); // Only recompute affected contacts
// Get results
let summary = tess.summary();
println!("Total contacts: {}", summary.contacts.len());
// Undo last update
tess.restore();
Supports PDB, mmCIF, and XYZR input formats (auto-detected from extension or content):
# PDB input
voronota-ltr -i structure.pdb --probe 1.4
# mmCIF input
voronota-ltr -i structure.cif --probe 1.4
# XYZR input (last 4 columns: x y z radius)
voronota-ltr -i atoms.xyzr --probe 1.4
# Save JSON output to file
voronota-ltr -i structure.pdb -o results.json
# Quiet mode (suppress log messages)
voronota-ltr -i structure.pdb -q -o results.json
# Exclude heteroatoms (HETATM records)
voronota-ltr -i structure.pdb --exclude-heteroatoms
# Include hydrogen atoms (excluded by default)
voronota-ltr -i structure.pdb --include-hydrogens
# Custom radii file (format: residue atom radius per line)
voronota-ltr -i structure.pdb --radii-file custom_radii.txt
# With periodic boundary conditions
voronota-ltr -i atoms.xyzr --periodic-box-corners 0 0 0 100 100 100
import json
with open("results.json") as f:
data = json.load(f)
# Per-ball data (indexed by ball)
sas_areas = data["sas_areas"]
volumes = data["volumes"]
# Totals
total_sasa = data["total_sas_area"]
total_volume = data["total_volume"]
total_contact_area = data["total_contact_area"]
# Contact details
for contact in data["contacts"]:
print(f"Contact {contact['id_a']}-{contact['id_b']}: area={contact['area']:.2f}")
Run benchmarks with cargo bench.
Performance on Apple M4 processor (10 cores) - the speedup is relative to single threaded runs:
| Dataset | Balls | C++ (OpenMP) | Rust (Rayon) | C++ Speedup | Rust Speedup |
|---|---|---|---|---|---|
balls_cs_1x1 |
100 | 179 µs | 79 µs | 0.4x | 0.8x |
balls_2zsk |
3545 | 14 ms | 12 ms | 5.1x | 5.9x |
balls_3dlb |
9745 | 38 ms | 30 ms | 5.0x | 5.9x |
MIT License
Copyright (c) 2026 Kliment Olechnovic and Mikael Lund