OpenMM MDAnalysis Reporter
The openmm-mdanalysis-reporter is a Python library that bridges OpenMM simulations with MDAnalysis. It allows users to create MDAnalysis Universe objects directly from OpenMM State objects and write trajectory data to any MDAnalysis-supported format, particularly the Universal Archive Format (UAF). The current version is 0.1, indicating an early development stage with an infrequent release cadence.
Common errors
-
ValueError: Cannot enforce periodic box for a system without periodic box vectors defined.
cause The `MDAnalysisReporter` was initialized with `enforcePeriodicBox=True`, but the OpenMM `System` does not have periodic box vectors set.fixSet `enforcePeriodicBox=False` when initializing the reporter for non-periodic systems, or ensure `system.setDefaultPeriodicBoxVectors` is explicitly called for periodic systems before running the simulation. -
MDAnalysis.exceptions.NoUniverseError: Unable to load topology or trajectory.
cause After simulation, MDAnalysis cannot open the generated trajectory file, possibly due to corruption, an incomplete write, or an unsupported format/version.fixVerify that the simulation completed without errors and the output file exists at the specified path. Ensure the file is being written to the recommended `.uaf` format. Check MDAnalysis compatibility with the file version by trying to load it manually outside the reporter's context. -
AttributeError: 'list' object has no attribute 'append'
cause This error or similar (e.g., `TypeError: 'MDAnalysisReporter' object is not iterable`) can occur if `simulation.reporters` is directly assigned a `MDAnalysisReporter` object instead of appending it.fixAlways use `simulation.reporters.append(MDAnalysisReporter(...))` to add the reporter instance to the list of reporters, rather than trying to assign it directly or iterate over a single object.
Warnings
- gotcha The `enforcePeriodicBox` parameter requires the OpenMM `System` to have periodic box vectors defined. If `enforcePeriodicBox=True` is used for a non-periodic system (e.g., implicit solvent, gas phase without explicit box definition), the reporter will raise a `ValueError` during the report step.
- gotcha The Universal Archive Format (`.uaf`) is the explicitly recommended output format for `MDAnalysisReporter`. While other MDAnalysis-supported formats might work, `.uaf` is designed for direct mapping from OpenMM states, offering better performance and reliability. Using other formats might lead to unexpected behavior, performance overheads, or data integrity issues.
- gotcha As a `0.1` release, this library is in an early development stage. While functional, its API may not be entirely stable, and performance might not be fully optimized for all complex scenarios. Future minor or patch releases could introduce breaking changes or significant API adjustments.
Install
-
pip install openmm-mdanalysis-reporter
Imports
- MDAnalysisReporter
from openmm_mdanalysis_reporter import MDAnalysisReporter
Quickstart
import openmm.app as app
import openmm as om
from openmm_mdanalysis_reporter import MDAnalysisReporter
import os
# Create a simple system (e.g., single atom, just for demonstration)
# In a real scenario, you'd load a PDB/GMX file with app.PDBFile, etc.
system = om.System()
system.addParticle(1.0) # mass in amu
# Create an integrator
integrator = om.VerletIntegrator(0.001) # 1 fs timestep
# Create a simulation object
# Use 'Reference' platform for broad compatibility without GPU
platform = om.Platform.getPlatformByName('Reference')
simulation = app.Simulation(system, integrator, platform)
simulation.context.setPositions([[0, 0, 0]]) # Set initial position
simulation.context.setVelocitiesToTemperature(300 * om.unit.kelvin) # Set initial velocities
# Define output file path for the trajectory
output_file = "trajectory.uaf" # UAF is recommended for MDAnalysisReporter
# Add the MDAnalysisReporter
# Report every 10 steps, enforce periodic box (set to False for this non-periodic system)
# For periodic systems, ensure system.setDefaultPeriodicBoxVectors is called.
reporter = MDAnalysisReporter(output_file, 10, enforcePeriodicBox=False)
simulation.reporters.append(reporter)
print(f"Running simulation and writing to {output_file}...")
simulation.step(100) # Run for 100 steps
print("Simulation finished.")
# Optional: Load and inspect the generated trajectory with MDAnalysis
try:
import MDAnalysis as mda
u = mda.Universe(output_file)
print(f"Loaded trajectory with {u.trajectory.n_frames} frames.")
# Clean up the generated file
os.remove(output_file)
print(f"Cleaned up {output_file}.")
except ImportError:
print("MDAnalysis not installed, skipping trajectory inspection and cleanup.")
except Exception as e:
print(f"Error loading trajectory with MDAnalysis: {e}. Attempting cleanup.")
if os.path.exists(output_file):
os.remove(output_file) # Still try to clean up