Skip to main content

Rust Simulation Tools

CI/CD PyPI version

High-performance molecular dynamics analysis library with a Python API. Written in Rust for speed, exposed to Python via PyO3.

Installation

From PyPI using uv:

uv pip install rust-simulation-tools

For the latest version which may not be on PyPI yet, make sure you have cloned this repo and have maturin installed to your environment of choice:

uv venv /path/to/env
source /path/to/env/bin/activate
uv pip install maturin

git clone https://github.com/msinclair-py/rust-simulation-tools.git
cd rust-simulation-tools
maturin develop --release

Features

  • File I/O: AMBER topology/coordinates, DCD and MDCRD trajectories; PDB, mmCIF, mol2, SDF structures
  • System building: tleap-style SystemBuilder — force fields, solvation, ions, prmtop/inpcrd output
  • Ligand parameterization: built-in antechamber — GAFF2 atom typing + AM1-BCC charges (no AmberTools needed)
  • Selections: VMD-style atom selection with property access
  • Analysis: SASA, trajectory unwrapping, Kabsch alignment
  • Fingerprints: Per-residue interaction energies (LJ + electrostatic)
  • Minimization: Steepest-descent + conjugate-gradient with optional restraints
  • MM-PBSA/GBSA: Binding free energy with per-residue decomposition
  • Interface scoring: ipSAE, pDockQ, pDockQ2, LIS, ipTM for predicted complexes

Quick Start

Load a System

from rust_simulation_tools import read_prmtop, read_inpcrd, DcdReader

# Load topology and coordinates
topo = read_prmtop("system.prmtop")
coords, box = read_inpcrd("system.inpcrd")

# Load trajectory
dcd = DcdReader("trajectory.dcd")
trajectory, boxes = dcd.read_all()

Build a System

The SystemBuilder parameterizes structures and writes simulation-ready AMBER files — no AmberTools install required.

from rust_simulation_tools import SystemBuilder

builder = SystemBuilder()
builder.load_protein_ff19sb()   # protein force field
builder.load_gaff2()            # small-molecule force field
builder.load_water_opc()        # OPC water model

# Load structures (PDB / mmCIF for proteins, mol2/SDF for ligands)
protein = builder.load_pdb("protein.pdb")
ligand  = builder.load_ligand("ligand.sdf", net_charge=0)  # auto GAFF2 + AM1-BCC

# Combine, solvate, ionize
system = builder.combine([protein, ligand])
builder.solvate_box(system, buffer=12.0)
builder.add_salt(system, "Na+", "Cl-", concentration=0.150)  # neutralize + 150 mM

# Write output
builder.write_amber(system, "complex.prmtop", "complex.inpcrd")
builder.write_pdb(system, "complex.pdb")

For implicit solvent, skip load_water_opc/solvation and write the topology directly. See examples/example_explicit_solvent.py, example_implicit_solvent.py, and example_protein_ligand.py.

Parameterize a Ligand

import rust_simulation_tools as rst

# Standalone: write a parameterized mol2 (GAFF2 types + charges)
rst.parameterize_ligand(
    "ligand.sdf", "ligand_gaff2.mol2",
    net_charge=0,
    charge_method="am1bcc",   # or "gasteiger" (faster, less accurate)
)

# Raw AM1 Mulliken charges from atomic numbers + coordinates
import numpy as np
charges = rst.compute_am1_charges(
    np.array([8, 1, 1], dtype=np.int64),          # O, H, H
    np.array([[0, 0, 0], [0, 0.757, 0.587], [0, -0.757, 0.587]], dtype=float),
    charge=0,
)

Atom Selection

Select atoms using VMD-style expressions. The select() method returns a Selection object with direct property access.

# Select protein backbone
backbone = topo.select("backbone")
print(f"{backbone.n_atoms} atoms, {backbone.n_residues} residues")

# Access properties directly
ca = topo.select("protein and name CA")
print(ca.masses)          # numpy array of masses
print(ca.charges)         # numpy array of charges
print(ca.total_mass())    # sum of masses

# Distance-based selection (requires coordinates)
near_lig = topo.select("protein and within 5.0 of resname LIG", coordinates=coords)

# Set operations
charged = topo.select("charge < -0.5 or charge > 0.5")
sidechain = topo.select("sidechain")
charged_sidechain = sidechain & charged  # intersection

Supported selection keywords:

  • protein, backbone, sidechain, water
  • name CA, resname ALA, resid 1-50
  • charge > 0.5, mass < 2.0
  • within 5.0 of resname LIG
  • Boolean: and, or, not

SASA Calculation

from rust_simulation_tools import compute_sasa_from_topology

# Single frame
sasa = compute_sasa_from_topology(topo, coords)
print(f"Total SASA: {sasa['total']:.1f} A^2")          # float
print(f"Per-atom: {sasa['per_atom'].shape}")           # ndarray (n_atoms,)
print(f"Per-residue: {sasa['per_residue'].shape}")     # ndarray (n_residues,), by residue index

# Trajectory: total -> ndarray (n_frames,), per_residue -> list of per-frame dicts
traj_sasa = compute_sasa_trajectory_from_topology(topo, trajectory)

Trajectory Alignment

from rust_simulation_tools import kabsch_align

# Align trajectory to first frame using backbone atoms
backbone = topo.select("backbone")
aligned = kabsch_align(trajectory, trajectory[0], backbone.indices)

Trajectory Unwrapping

from rust_simulation_tools import unwrap_dcd

# Remove periodic boundary artifacts
unwrapped, boxes = unwrap_dcd("trajectory.dcd")

Interaction Fingerprints

Calculate per-residue LJ and electrostatic interactions between a target and partner.

from rust_simulation_tools import FingerprintSession, FingerprintMode

session = FingerprintSession("system.prmtop", "trajectory.dcd")
session.set_target_residues(range(10))           # residues to fingerprint
session.set_binder_residues(range(10, 100))      # interaction partner

# Iterate over frames
for lj_fp, es_fp in session:
    print(f"LJ: {lj_fp.sum():.2f}, ES: {es_fp.sum():.2f} kJ/mol")

# Switch perspective: fingerprint binder residues instead
session.set_fingerprint_mode(FingerprintMode.Binder)
session.seek(0)

MM-PBSA/GBSA Binding Energy

Calculate binding free energy with Generalized Born or Poisson-Boltzmann solvation.

from rust_simulation_tools import (
    compute_binding_energy,
    decompose_binding_energy,
    GbModel, GbParams, PbParams, SaParams,
)

# MM-GBSA over trajectory
result = compute_binding_energy(
    topo,
    trajectory_path="trajectory.dcd",
    receptor_residues=list(range(0, 250)),
    ligand_residues=list(range(250, 251)),
    gb_params=GbParams(model=GbModel.ObcII, salt_concentration=0.15),
    sa_params=SaParams(),
    trajectory_format="dcd",
)

print(f"Delta G: {result.mean_delta_total:.2f} +/- {result.std_delta_total:.2f} kcal/mol")
print(f"  MM:  {result.mean_delta_mm:.2f}")
print(f"  GB:  {result.mean_delta_gb:.2f}")
print(f"  SA:  {result.mean_delta_sa:.2f}")

# MM-PBSA (use pb_params instead of gb_params)
pb_result = compute_binding_energy(
    topo, "trajectory.dcd",
    receptor_residues=list(range(0, 250)),
    ligand_residues=list(range(250, 251)),
    pb_params=PbParams(grid_spacing=0.5, salt_concentration=0.15),
)

# Per-residue decomposition
decomp = decompose_binding_energy(
    topo, coords,
    receptor_residues=list(range(0, 250)),
    ligand_residues=list(range(250, 251)),
)

for res in sorted(decomp.receptor_residues, key=lambda r: r.total())[:5]:
    print(f"{res.residue_label}{res.residue_index}: {res.total():.2f} kcal/mol")

Energy Minimization

Steepest-descent + conjugate-gradient minimization with optional positional restraints and a full energy-component breakdown.

from rust_simulation_tools import minimize, MinimizeConfig

config = MinimizeConfig(
    max_cycles=5000,
    sd_cycles=100,           # initial steepest-descent steps
    convergence_rms=0.01,
    cutoff=10.0,
    restraint_mask="backbone",  # optional; omit for unrestrained
    restraint_weight=10.0,
)

result = minimize("system.prmtop", "system.inpcrd", config=config, output="min.inpcrd")
print(f"Energy: {result.final_energy:.2f} kcal/mol  converged={result.converged}")

ec = result.energy_components       # bond, angle, dihedral, vdw,
print(ec.total(), ec.vdw, ec.elec_recip)   # elec_direct, elec_recip, vdw_14, elec_14

Use minimize_topology(topo, "system.inpcrd", ...) to reuse a pre-loaded topology. See examples/example_minimization.py.

Interface Scoring (ipSAE)

Score predicted complexes (AlphaFold-Multimer, Boltz, Chai) from pLDDT and PAE.

import numpy as np
from rust_simulation_tools import compute_ipsae

plddt = np.load("plddt.npy")            # per-residue, 0-100 scale, shape (N,)
pae = np.load("pae.npy").flatten()      # predicted aligned error, flattened (N*N,)

results = compute_ipsae("model.pdb", plddt, pae)   # PDB or CIF
for pair in results["max_pairs"]:       # also "directed_pairs"
    print(f"{pair['chain1']}-{pair['chain2']}: "
          f"ipSAE={pair['ipSAE']:.3f} pDockQ={pair['pDockQ']:.3f} LIS={pair['LIS']:.3f}")

compute_ipsae_from_arrays(coords, chains, chain_types, plddt, pae) does the same from in-memory arrays. See examples/example_ipsae.py.

API Reference

File I/O

Function Description
read_prmtop(path) Load AMBER topology, returns AmberTopology
read_inpcrd(path) Load AMBER coordinates, returns (coords, box)
DcdReader(path) DCD trajectory reader
MdcrdReader(path, n_atoms, has_box) AMBER ASCII trajectory reader

System Building

Method Description
SystemBuilder() Create a tleap-style builder
.load_protein_ff19sb(), .load_gaff2(), .load_water_opc() Load force fields / water model
.load_custom_frcmod(path), .load_custom_lib(path) Load custom ligand parameters
.load_pdb(path), .load_mmcif(path), .load_mol2(path) Load a structure, returns System
.load_ligand(path, net_charge=0) Load + parameterize a ligand (GAFF2 + AM1-BCC)
.combine([systems]) Merge systems into one System
.solvate_box(system, buffer=12.0, closeness=1.0) Solvate in an OPC water box
.add_ions(system, ion, count=None) Add ions ("neutralize", int count, or float conc.)
.add_salt(system, cation="Na+", anion="Cl-", concentration=0.150) Neutralize + add salt
.write_amber(system, prmtop, inpcrd), .write_prmtop/.write_inpcrd/.write_pdb Write output

System exposes .n_atoms, .n_residues, .total_charge, .box_dimensions, .box_angles.

Parameterization

Function Description
parameterize_ligand(input, output, net_charge=0, charge_method="am1bcc") Write a GAFF2/charge-assigned mol2 ("am1bcc" or "gasteiger")
compute_am1_charges(atomic_numbers, coords, charge=0) Raw AM1 Mulliken charges

AmberTopology

Property/Method Description
.n_atoms, .n_residues System size
.atom_names, .residue_labels Atom/residue names
.charges(), .sigmas(), .epsilons() Force field parameters
.select(expression, coordinates=None) VMD-style selection, returns Selection
.bonds() List of bonded atom pairs

Selection

Property/Method Description
.n_atoms, .n_residues Selection size
.indices Atom indices (numpy array)
.masses, .charges, .radii Per-atom properties
.atom_names, .residue_names Names as lists
.positions Coordinates (if provided during selection)
.total_mass(), .total_charge() Aggregate properties
&, |, - Set operations (intersection, union, difference)

DcdReader

Property/Method Description
.n_frames, .n_atoms Trajectory size
.read_frame() Read next frame, returns (coords, box)
.read_all() Read all frames, returns (trajectory, boxes)
.seek(frame) Jump to frame index

Analysis Functions

Function Description
compute_sasa_from_topology(topo, coords) SASA using topology for radii
compute_sasa_trajectory_from_topology(topo, trajectory) Per-frame SASA over a trajectory
calculate_sasa(coords, radii, residue_indices) SASA with explicit radii
kabsch_align(trajectory, reference, align_indices) RMSD-minimizing alignment
unwrap_dcd(path) Remove PBC artifacts from DCD
unwrap_system(trajectory, boxes) Remove PBC artifacts
FingerprintSession(prmtop, trajectory) Per-residue LJ/electrostatic fingerprints

Minimization

Function Description
minimize(prmtop, inpcrd, config=None, output=None) Minimize from files, returns MinimizeResult
minimize_topology(topo, inpcrd, config=None, output=None) Minimize with a pre-loaded topology
MinimizeConfig(max_cycles, sd_cycles, convergence_rms, cutoff, restraint_mask, restraint_weight, initial_step_size) Minimization settings

MinimizeResult exposes .final_energy, .final_rms, .cycles, .converged, .energy_components (.bond, .angle, .dihedral, .vdw, .elec_direct, .elec_recip, .vdw_14, .elec_14, .total()).

MM-PBSA/GBSA

Function Description
compute_binding_energy(...) Trajectory-averaged binding energy
compute_binding_energy_single_frame(...) Single frame binding energy
decompose_binding_energy(...) Per-residue energy decomposition
compute_mm_energy(topo, coords) Molecular mechanics energy
compute_gb_energy(topo, coords, params) GB solvation energy
compute_pb_energy(topo, coords, params) PB solvation energy
compute_sa_energy(topo, coords, params) Nonpolar surface-area energy
interaction_entropy(frames, temperature) Interaction-entropy correction
quasi_harmonic_entropy(...) Quasi-harmonic entropy estimate

Parameter objects: GbParams, PbParams, SaParams, GbModel.

Interface Scoring

Function Description
compute_ipsae(structure_path, plddt, pae, pdockq_cutoff=8.0, pae_cutoff=12.0) ipSAE/pDockQ/LIS/ipTM from a PDB/CIF file
compute_ipsae_from_arrays(coords, chains, chain_types, plddt, pae, ...) Same, from in-memory arrays

Agent Skills

The skills/ directory contains agent skills that teach AI coding assistants (e.g. Claude Code) how to use this package — system building, ligand parameterization, trajectory analysis, MM-PBSA, minimization, and ipSAE scoring. They are mirrored under .claude/skills/ so they load automatically when working in this repo. See skills/README.md for the full list and how to install them elsewhere.

Development

git clone https://github.com/msinclair-py/rust-simulation-tools.git
cd rust-simulation-tools
pip install maturin pytest numpy
maturin develop --release
pytest tests/ -v

License

MIT License

Release files for rust-simulation-tools 0.2.5

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for rust-simulation-tools 0.2.5
File Size Uploaded
rust_simulation_tools-0.2.5.tar.gz 1.2 MB Details

Built distributions (wheels)

Table of built distributions (wheels) for rust-simulation-tools 0.2.5
File
rust_simulation_tools-0.2.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.13 CPython 3.13 Linux glibc 2.17+ x86-64 Details
rust_simulation_tools-0.2.5-cp313-cp313-macosx_11_0_arm64.whl CPython 3.13 CPython 3.13 macOS 11.0+ ARM64 Details
rust_simulation_tools-0.2.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.12 CPython 3.12 Linux glibc 2.17+ x86-64 Details
rust_simulation_tools-0.2.5-cp312-cp312-macosx_11_0_arm64.whl CPython 3.12 CPython 3.12 macOS 11.0+ ARM64 Details
rust_simulation_tools-0.2.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.11 CPython 3.11 Linux glibc 2.17+ x86-64 Details
rust_simulation_tools-0.2.5-cp311-cp311-macosx_11_0_arm64.whl CPython 3.11 CPython 3.11 macOS 11.0+ ARM64 Details
rust_simulation_tools-0.2.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.10 CPython 3.10 Linux glibc 2.17+ x86-64 Details
rust_simulation_tools-0.2.5-cp310-cp310-macosx_11_0_arm64.whl CPython 3.10 CPython 3.10 macOS 11.0+ ARM64 Details

Total release size: 18.8 MB

Release files / rust_simulation_tools-0.2.5.tar.gz

Download URL rust_simulation_tools-0.2.5.tar.gz
Size 1.2 MB
Tags Source
SHA-256 checksum
How to use checksums
06c0e58782f44f5179c9528c81f8f62b1c8b5d0d50c98aadf18d0b3f39b45def
BLAKE2b-256 checksum
How to use checksums
4dbc9b1f68c8526479597e08fbd00ce2768f0807631760ddc4891c3d8f41a966
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via maturin/1.14.1

Release files / rust_simulation_tools-0.2.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL rust_simulation_tools-0.2.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 2.3 MB
Tags CPython 3.13 Linux glibc 2.17+ x86-64
SHA-256 checksum
How to use checksums
ac5c990ac53e10dff6a6bd5e3c9582519999b8aeafe001bc6a5eacd07e1bcf58
BLAKE2b-256 checksum
How to use checksums
1d74d7779427b4e0e212808b2aa78bc73a6811bc212c168d80a3762985117769
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via maturin/1.14.1

Release files / rust_simulation_tools-0.2.5-cp313-cp313-macosx_11_0_arm64.whl

Download URL rust_simulation_tools-0.2.5-cp313-cp313-macosx_11_0_arm64.whl
Size 2.1 MB
Tags CPython 3.13 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
36fa6c5e21b6b1e4581811f6870c501bdf689cdd58bc925aeb24e5b273decfe1
BLAKE2b-256 checksum
How to use checksums
56c2530758d85199e98d5033159659f32b9f8e8b395043e9c4f42ab18d81d7ae
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via maturin/1.14.1

Release files / rust_simulation_tools-0.2.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL rust_simulation_tools-0.2.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 2.3 MB
Tags CPython 3.12 Linux glibc 2.17+ x86-64
SHA-256 checksum
How to use checksums
b76f4e4da1c4c977b5ae55d307af1587a6aad20de623fd184122531d34084268
BLAKE2b-256 checksum
How to use checksums
843755f133c1eb47a76c85333ccbaa892b6e014e83f767e21163aefb8820056a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via maturin/1.14.1

Release files / rust_simulation_tools-0.2.5-cp312-cp312-macosx_11_0_arm64.whl

Download URL rust_simulation_tools-0.2.5-cp312-cp312-macosx_11_0_arm64.whl
Size 2.1 MB
Tags CPython 3.12 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
da5c7cea80c6be5d8c74e2da891720db021b281e2bd24f5043f01f0ac1a1cbbf
BLAKE2b-256 checksum
How to use checksums
8c40439c095989a79e7a258e4095ecbd45883f6fcc6e120a5c48ccaf2872f918
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via maturin/1.14.1

Release files / rust_simulation_tools-0.2.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL rust_simulation_tools-0.2.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 2.3 MB
Tags CPython 3.11 Linux glibc 2.17+ x86-64
SHA-256 checksum
How to use checksums
11fefdda040db14a37450f50a5d8df80166302ce64ff31161c7aa460ba6735ee
BLAKE2b-256 checksum
How to use checksums
da21b355a4b892a23d2b46756601089a740e207a3fa2fbb20940ad62bed02553
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via maturin/1.14.1

Release files / rust_simulation_tools-0.2.5-cp311-cp311-macosx_11_0_arm64.whl

Download URL rust_simulation_tools-0.2.5-cp311-cp311-macosx_11_0_arm64.whl
Size 2.1 MB
Tags CPython 3.11 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
f8c9dad2dff5bf58b709a01bf35f130e42830fbe8f94e5632d0c6a4c0c5df0a3
BLAKE2b-256 checksum
How to use checksums
05d8bcb1e20da1069317ddc03b3c790ca2f0b6ebc3299bf2d4ace3e225917cae
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via maturin/1.14.1

Release files / rust_simulation_tools-0.2.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL rust_simulation_tools-0.2.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 2.3 MB
Tags CPython 3.10 Linux glibc 2.17+ x86-64
SHA-256 checksum
How to use checksums
474106764d9afa705d8a7fb4289a9731554806b77211bd15172ce8ad86204608
BLAKE2b-256 checksum
How to use checksums
3d16056134be59e9eb673fce3b86a5cc5f8b347d896a0ae83d3d7b3b14c7c6a2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via maturin/1.14.1

Release files / rust_simulation_tools-0.2.5-cp310-cp310-macosx_11_0_arm64.whl

Download URL rust_simulation_tools-0.2.5-cp310-cp310-macosx_11_0_arm64.whl
Size 2.1 MB
Tags CPython 3.10 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
8708508a8b64c50ecbc45a566eb407d7741c9d653dda8f767bb04b67bdefb1fe
BLAKE2b-256 checksum
How to use checksums
ba7937ff369c2b41d6b2deeebfb806fda350bd9fd77c46baee6e4a05548836f4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via maturin/1.14.1

Release history Release notifications | RSS feed

This release

0.2.5 This release

9 release files

0.2.4

9 release files

0.2.2

9 release files

0.2.1

11 release files

0.2.0

16 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page