Skip to main content

Overview

Every warp-md analysis starts with two fundamental objects:
  • System: The topology — atom names, residues, chains, masses
  • Trajectory: The coordinate time-series — positions over time
These classes are exposed from the Rust traj-core crate via Python bindings.

System Class

The System represents molecular topology and metadata.

Loading a System

from warp_md import System

system = System.from_pdb("protein.pdb")
print(f"Loaded {system.n_atoms()} atoms")

System Methods

n_atoms
() -> int
Returns the number of atoms in the system.
n = system.n_atoms()
select
(expr: str) -> Selection
Compile and execute an atom selection expression. Results are cached.
backbone = system.select("backbone")
ca_atoms = system.select("name CA")
protein_a = system.select("protein and chain A")
See Selections for syntax details.
atom_table
() -> dict
Returns raw atom data as a dictionary with keys:
  • name: List of atom names
  • resname: List of residue names
  • resid: List of residue IDs (integers)
  • chain_id: List of chain identifiers
  • mass: List of atomic masses (float)
  • element_id: Element type identifiers

Internal Structure

From crates/traj-core/src/system.rs:29-52:
pub struct System {
    pub atoms: AtomTable,
    pub interner: StringInterner,
    pub positions0: Option<Vec<[f32; 4]>>,
    selection_cache: HashMap<String, Selection>,
}
  • atoms: Column-oriented storage for atom properties
  • interner: String deduplication (names, residues, chains)
  • positions0: Optional reference coordinates from topology file
  • selection_cache: Compiled selections for reuse
The System caches compiled selections. Calling system.select("backbone") multiple times returns the cached result without re-parsing.

Trajectory Class

The Trajectory reads coordinate frames from disk.

Opening a Trajectory

from warp_md import Trajectory

traj = Trajectory.open_xtc("trajectory.xtc", system)
print(f"Frames: {traj.n_frames()}")

Trajectory Methods

n_atoms
() -> int
Number of atoms per frame (must match system).
n_frames
() -> int
Total number of frames in the trajectory.
total = traj.n_frames()
read_chunk
(max_frames: int) -> dict | None
Read up to max_frames frames. Returns None at EOF.Returns dict with:
  • coords: np.ndarray shape (n_frames, n_atoms, 3), dtype float32
  • box: Optional box vectors
  • time: Optional timestamps
chunk = traj.read_chunk(128)
if chunk is not None:
    coords = chunk["coords"]
    print(coords.shape)  # (128, n_atoms, 3)
Trajectories are stateful readers. Calling read_chunk() advances the internal cursor. To re-read, you must re-open the trajectory.

Format Support

From python/warp_md/io.py:7:
_SUPPORTED_TRAJ_FORMATS = {"dcd", "xtc", "pdb", "pdbqt"}
FormatExtensionSourceNotes
XTC.xtcGROMACSCompressed, nanometer → Angstrom
DCD.dcdCHARMM/NAMDBinary, specify length_scale
PDB.pdbMulti-MODELText-based, slower
PDBQT.pdbqtAutoDockLike PDB with charges

Putting It Together

Typical workflow:
from warp_md import System, Trajectory, RmsdPlan

# 1. Load topology
system = System.from_pdb("protein.pdb")

# 2. Select atoms
backbone = system.select("backbone")

# 3. Open trajectory
traj = Trajectory.open_xtc("trajectory.xtc", system)

# 4. Run analysis
plan = RmsdPlan(backbone, reference="topology", align=True)
rmsd = plan.run(traj, system, device="auto")

print(f"Mean RMSD: {rmsd.mean():.2f} Å")
The system object is passed to both Trajectory.open_*() (for validation) and plan.run() (for atom metadata).

See Also

Build docs developers (and LLMs) love