MSMH5 file#
Using the native MSMH5 OpenMM reporter#
import openmm as mm
from openmm import app
from openmm import unit
import molsysmt as msm
from molsysmt import pyunitwizard as puw
molsys = msm.convert('4POC')
molsys = msm.extract(molsys, selection='molecule_type=="protein"')
molsys = msm.build.add_missing_hydrogens(molsys)
molsys = msm.build.solvate(molsys)
topology = msm.convert(molsys, 'openmm.Topology')
coordinates = msm.get(molsys, coordinates=True)
Tip
Trajectory workflows can request selected atom data and system-level frame metadata together. For example, msm.get(molsys, element='atom', selection=atom_indices, coordinates=True, time=True) applies atom_indices only to the coordinates; time is evaluated at the system level. Results retain request order.
Tip
For a live OpenMM Simulation, msm.get(simulation, temperature=True, integrator=True, friction=True) retrieves metadata that the active integrator actually retains. Temperature and friction return None for integrators that do not define them. A force-field name is not inferred from an OpenMM System, because parameterization removes that unambiguous provenance.
positions = puw.convert(coordinates[0], to_form='openmm.unit')
forcefield = app.ForceField('amber14-all.xml', 'amber14/tip3p.xml')
system = forcefield.createSystem(topology, nonbondedMethod=app.PME,
nonbondedCutoff=1.2*unit.nanometer, constraints=app.HBonds)
integrator = mm.LangevinIntegrator(300*unit.kelvin, 1.0/unit.picosecond, 2.0*unit.femtoseconds)
platform = mm.Platform.getPlatformByName("CPU")
simulation = app.Simulation(topology, system, integrator, platform)
simulation.context.setPositions(positions)
simulation.minimizeEnergy()
simulation.context.setVelocitiesToTemperature(300*unit.kelvin)
from molsysmt.third_party.openmm.reporters import H5MSMReporter, TQDMReporter
The reporter creates H5MSM 0.4 output. Its topology is stored as a native reference chemical state, while trajectory arrays remain chunk-friendly datasets. Files written by older MolSysMT releases remain valid 0.3 migration inputs.
tqdm_reporter = TQDMReporter(1000, 50000)
simulation.reporters.append(tqdm_reporter)
msmh5_reporter = H5MSMReporter('traj.msmh5', 1000, steps=50000, selection='all',
topology=topology, time=True, box=True, coordinates=True, velocities=False,
potentialEnergy=True, kineticEnergy=True, temperature=True,
includeInitialContext=True, constantReportInterval=True,
constantStepSize=True, constantBox=True,
auto_close=True)
simulation.reporters.append(msmh5_reporter)
simulation.step(50000)
A first glance at the msmh5 file#
aa = msm.convert('traj.msmh5', 'molsysmt.MSMH5FileHandler')
'topology' in aa.file
aa.file['topology']['atoms'].attrs['n_atoms']
msm.get('traj.msmh5', n_lipids=True)
Extract a new msmh5 file#
When a long trajectory is processed in chunks, validate the requested frame range before starting expensive I/O. Public consumers such as msm.get(), msm.convert(), msm.extract(), and msm.Iterator raise molsysmt.ArgumentError immediately if a frame index is negative or outside the trajectory. Element selections and masks receive the same early validation, preventing a late backend-specific IndexError or a silent empty iteration after earlier work has already been performed.
# Bounded-memory ensemble descriptors
rg = msm.structure.get_radius_of_gyration('traj.msmh5', heavy_mode='force')
rmsf = msm.structure.get_rmsf('traj.msmh5', selection='backbone', heavy_mode='force')