Skip to main content

RmsdPlan

Compute RMSD relative to a reference structure.

Constructor

from warp_md import RmsdPlan

plan = RmsdPlan(
    selection,
    reference_mode="first",
    fit=True,
    mass_weighted=False,
    pbc="none"
)
selection
Selection
required
Atoms to calculate RMSD for
reference_mode
str
default:"first"
Reference frame selection: "first", "average", or custom frame index
fit
bool
default:"True"
Whether to superpose structures before RMSD calculation
mass_weighted
bool
default:"False"
Use mass-weighted RMSD
pbc
str
default:"none"
Periodic boundary conditions: "none" or "orthorhombic"

run() Method

Returns: 1D array of RMSD values in Å (one per frame)

Example

import warp_md as wmd

system = wmd.System("system.pdb")
traj = wmd.open_trajectory("traj.xtc", system)

# Backbone RMSD relative to first frame
backbone = system.select("backbone")
plan = wmd.RmsdPlan(backbone, reference_mode="first", fit=True)
rmsd = plan.run(traj, system)

print(f"Max RMSD: {rmsd.max():.2f} Å")

SymmRmsdPlan

Compute RMSD accounting for molecular symmetry.

Constructor

plan = SymmRmsdPlan(
    selection,
    reference_mode="first",
    fit=True,
    pbc="none"
)
Automatically detects symmetric atoms and finds the optimal permutation.

Example

# RMSD of benzene ring accounting for 6-fold symmetry
ring = system.select("resname BNZ")
plan = wmd.SymmRmsdPlan(ring, fit=True)
rmsd = plan.run(traj, system)

DistanceRmsdPlan

Compute RMSD based on pairwise distances (coordinate-free).

Constructor

plan = DistanceRmsdPlan(
    selection,
    reference_mode="first",
    pbc="none"
)
selection
Selection
required
Atoms to analyze
reference_mode
str
default:"first"
Reference frame
pbc
str
default:"none"
Periodic boundary conditions

Example

# Distance RMSD for domain comparison
domain = system.select("resid 100:200")
plan = wmd.DistanceRmsdPlan(domain, reference_mode="average")
drmsd = plan.run(traj, system)
Distance RMSD is rotation-invariant and sensitive to internal conformational changes.

PairwiseRmsdPlan

Compute all-vs-all pairwise RMSD matrix.

Constructor

plan = PairwiseRmsdPlan(
    selection,
    fit=True,
    mass_weighted=False
)

run() Method

Returns: 2D array of shape (n_frames, n_frames) with pairwise RMSD values

Example

# Create pairwise RMSD matrix for clustering
ca_atoms = system.select("name CA")
plan = wmd.PairwiseRmsdPlan(ca_atoms, fit=True)
rmsd_matrix = plan.run(traj, system)

# Use for hierarchical clustering
from scipy.cluster.hierarchy import linkage, dendrogram
import matplotlib.pyplot as plt

linkage_matrix = linkage(rmsd_matrix, method='average')
dendrogram(linkage_matrix)
plt.ylabel("RMSD (Å)")
plt.show()
Pairwise RMSD has O(N²) complexity. For large trajectories, consider downsampling frames.

RmsdPerResPlan

Calculate per-residue RMSD to quantify flexibility of individual residues. Constructor:
from warp_md import RmsdPerResPlan

plan = RmsdPerResPlan(
    selection,           # Selection: residues to analyze
    reference_frame=0,   # int: reference frame index
    mass_weighted=False, # bool: use mass-weighted RMSD
    device="auto"        # str: execution device
)
selection
Selection
required
Residue selection to calculate per-residue RMSD
reference_frame
int
default:"0"
Frame index to use as reference structure
mass_weighted
bool
default:"False"
Whether to use mass-weighted RMSD
Returns: ndarray[frames, residues] — Per-residue RMSD in Ångströms Example:
from warp_md import System, Trajectory, RmsdPerResPlan

system = System.from_pdb("protein.pdb")
traj = Trajectory.open_xtc("traj.xtc", system)
protein = system.select("protein")

plan = RmsdPerResPlan(protein, reference_frame=0)
per_res_rmsd = plan.run(traj, system)

# Identify most flexible residues
mean_rmsd = per_res_rmsd.mean(axis=0)
print(f"Most flexible residue: {mean_rmsd.argmax()}, RMSD: {mean_rmsd.max():.2f} Å")

TrajectoryClusterPlan

Cluster trajectory frames using DBSCAN or k-means based on RMSD. Constructor:
from warp_md import TrajectoryClusterPlan

plan = TrajectoryClusterPlan(
    selection,              # Selection: atoms for alignment
    method="dbscan",        # str: "dbscan" or "kmeans"
    eps=2.0,               # float: DBSCAN epsilon (Å)
    min_samples=5,         # int: DBSCAN min_samples
    n_clusters=None,       # int: k-means cluster count
    metric="rmsd",         # str: distance metric
    mass_weighted=False,   # bool: mass-weighted RMSD
    device="auto"          # str: execution device
)
selection
Selection
required
Atoms used for RMSD calculation and alignment
method
str
default:"dbscan"
Clustering method: "dbscan" or "kmeans"
eps
float
default:"2.0"
DBSCAN epsilon parameter (maximum distance in Ångströms)
min_samples
int
default:"5"
DBSCAN minimum samples per cluster
n_clusters
int
Number of clusters for k-means (required if method=“kmeans”)
metric
str
default:"rmsd"
Distance metric (currently only “rmsd” supported)
mass_weighted
bool
default:"False"
Whether to use mass-weighted RMSD
Returns: ndarray[frames] — Cluster labels for each frame (-1 for noise in DBSCAN) Example:
from warp_md import System, Trajectory, TrajectoryClusterPlan

system = System.from_pdb("protein.pdb")
traj = Trajectory.open_xtc("traj.xtc", system)
backbone = system.select("protein and backbone")

# DBSCAN clustering
plan = TrajectoryClusterPlan(backbone, method="dbscan", eps=1.5, min_samples=10)
labels = plan.run(traj, system)

print(f"Found {len(set(labels)) - (1 if -1 in labels else 0)} clusters")
print(f"Noise points: {(labels == -1).sum()}")

# k-means clustering
plan_kmeans = TrajectoryClusterPlan(backbone, method="kmeans", n_clusters=5)
kmeans_labels = plan_kmeans.run(traj, system)

Build docs developers (and LLMs) love