Skip to content

molforge.md

md

Molecular dynamics: trajectory I/O, analysis, and engine wrappers.

A molecular dynamics simulation numerically integrates Newton's equations of motion for a system of atoms subject to a force field, typically over picosecond-to-microsecond timescales.

In molforge:

  • :class:Trajectory is a sequence of coordinate snapshots indexed by frame, with per-frame metadata (time, energy, temperature).
  • :class:Simulation is the snapshot of an in-progress simulation: topology, current coordinates, current velocities, the integrator's parameters. You can extend it with :meth:Simulation.run to produce more :class:Trajectory frames.
  • :class:MDEngine (in this package) is the abstract base for MD engine wrappers (OpenMM, GROMACS, ...). Concrete engines live under :mod:molforge.wrappers.md.

By convention, every MD engine wrapper exposes: - :meth:prepare(protein, force_field, ...) -> Simulation - :meth:minimize(simulation, ...) -> Simulation - :meth:run(simulation, n_steps, ...) -> Trajectory

So users get the same call structure regardless of which engine they're running under.

Trajectory dataclass

Trajectory(
    topology: Protein,
    coordinates: NDArray[float32],
    times: NDArray[float64] | None = None,
    energies: NDArray[float64] | None = None,
    temperatures: NDArray[float64] | None = None,
    metadata: dict[str, object] = dict(),
)

A frame-indexed MD trajectory.

Attributes:

Name Type Description
topology Protein

A :class:molforge.core.Protein defining the atoms, their elements/names/connectivity. The topology is the same across all frames.

coordinates NDArray[float32]

(n_frames, n_atoms, 3) float32 array of per-frame coordinates in Å.

times NDArray[float64] | None

(n_frames,) float array of simulation time per frame, in picoseconds. None if not recorded.

energies NDArray[float64] | None

(n_frames,) float array of potential energies (kJ/mol). None if not recorded.

temperatures NDArray[float64] | None

(n_frames,) float array of instantaneous temperatures (K). None if not recorded.

metadata dict[str, object]

engine-specific extras (force field name, integrator, timestep, etc.).

n_frames property

n_frames: int

Number of frames in the trajectory.

n_atoms property

n_atoms: int

Number of atoms (same across all frames).

frame

frame(i: int) -> Protein

Return frame i as a :class:Protein snapshot.

The returned Protein shares the topology of this trajectory but has its own coordinate array.

Simulation dataclass

Simulation(
    topology: Protein,
    coordinates: NDArray[float32],
    velocities: NDArray[float32] | None = None,
    time: float = 0.0,
    force_field: str = "",
    temperature: float = 300.0,
    timestep: float = 0.002,
    engine_handle: object | None = None,
    metadata: dict[str, object] = dict(),
)

The state of an in-progress MD simulation.

Attributes:

Name Type Description
topology Protein

The system's :class:Protein (atoms + connectivity).

coordinates NDArray[float32]

(n_atoms, 3) float32 current positions in Å.

velocities NDArray[float32] | None

(n_atoms, 3) float32 current velocities. None until the simulation has been initialized with a thermostat target.

time float

Current simulation time (ps).

force_field str

Force-field name (e.g. "amber99sb", "amber14-all").

temperature float

Thermostat target temperature (K).

timestep float

Integrator timestep (ps).

engine_handle object | None

Engine-private. Not part of the public API. An opaque reference to whatever live state the engine wrapper that produced this :class:Simulation needs to resume it — for OpenMM this is the openmm.app.Simulation object, for GROMACS a handle to the run directory, and so on. Its concrete type is intentionally object: callers must not inspect it, depend on its type, or set it themselves. It is engine wrapper ↔ engine wrapper plumbing.

Two consequences worth being explicit about:

  • It is not serialized. :class:Simulation is a plain dataclass, but engine_handle typically wraps C-extension state that cannot be pickled. Any persistence layer must drop this field and have the engine wrapper rebuild it on resume.
  • It carries no semantic-versioning guarantee. The set of things that may appear here, and the fact that the field exists at all, can change between minor releases.

For per-simulation data you do want to read, use :attr:metadata.

metadata dict[str, object]

Free-form engine-specific extras. Unlike engine_handle this is plain, inspectable data (strings, numbers, arrays) and is safe to read and serialize.

MDEngine

Bases: ABC

Abstract base for MD engines (OpenMM, GROMACS, ...).

Subclasses live under :mod:molforge.wrappers.md and must implement :meth:prepare, :meth:minimize, and :meth:run. The contract is deliberately small so users can swap engines without rewriting their pipeline.

Attributes:

Name Type Description
name str

Human-readable engine name (set by subclasses).

prepare abstractmethod

prepare(
    protein: Protein, *, force_field: str, **kwargs: object
) -> Simulation

Build a :class:Simulation from a protein structure.

Concrete engines handle the engine-specific setup: parameterize the system against the force field, build the topology, place the structure in a (possibly periodic) simulation box, add solvent if requested, etc.

minimize abstractmethod

minimize(
    simulation: Simulation,
    *,
    max_iterations: int = 1000,
    tolerance: float = 10.0,
    **kwargs: object,
) -> Simulation

Energy-minimize the system in place and return it.

Parameters:

Name Type Description Default
simulation Simulation

A :class:Simulation (typically just returned from :meth:prepare).

required
max_iterations int

Limit on minimizer steps.

1000
tolerance float

Convergence tolerance (kJ/mol/nm).

10.0

Returns:

Type Description
Simulation

The same :class:Simulation with updated coordinates.

run abstractmethod

run(
    simulation: Simulation,
    *,
    n_steps: int,
    save_every: int = 1,
    **kwargs: object,
) -> Trajectory

Integrate the simulation for n_steps and return a :class:Trajectory containing the recorded frames.

Parameters:

Name Type Description Default
simulation Simulation

A :class:Simulation.

required
n_steps int

Number of integrator steps to run.

required
save_every int

Record a frame every save_every steps. A trajectory has n_steps // save_every + 1 frames (the +1 is the initial state).

1

Returns:

Name Type Description
A Trajectory

class:Trajectory.

MDEngineNotInstalledError

Bases: ImportError

Raised when an MD engine's heavy dependencies aren't installed.