OpenXPS: Extended Phase-Space Simulations with OpenMM
OpenXPS runs extended phase-space (XPS) simulations with OpenMM. It adds dynamical variables to a physical system and couples them to collective variables or to force parameters, as in temperature-accelerated molecular dynamics (TAMD), driven adiabatic free-energy dynamics (d-AFED) and unified free-energy dynamics (UFED).
Background
In an extended phase-space simulation, the physical coordinates r are augmented with dynamical variables s, which have masses and velocities of their own. Each dynamical variable sᵢ is coupled to a collective variable θᵢ(r), usually through a harmonic potential ½κᵢ[θᵢ(r) − sᵢ]². If the dynamical variables are much heavier than the collective variables, they move adiabatically: the physical system relaxes around each value of s. If, in addition, the dynamical variables are kept at a temperature Tₛ higher than the physical temperature T, they cross free-energy barriers faster, while their distribution remains proportional to exp[−A(s)/kBTₛ], where A is the free energy at the physical temperature, smoothed by the harmonic coupling. This is the idea behind TAMD (Maragliano and Vanden-Eijnden, 2006) and d-AFED (Abrams and Tuckerman, 2008).
A dynamical variable can also be a global parameter of OpenMM forces, such as an alchemical coupling parameter λ. Correa et al. (2026) combined λ-dynamics with d-AFED to compute solvation free energies.
UFED (Chen et al., 2012) combines d-AFED with a metadynamics bias (Laio and Parrinello, 2002; Barducci et al., 2008) applied to the dynamical variables. Free-energy surfaces can then be rebuilt from the mean forces that the physical system exerts on the dynamical variables, which Cuendet and Tuckerman (2014) found to be more accurate than histograms or the accumulated bias.
Keeping the dynamical variables at their own temperature calls for thermostats that hold up under these conditions. OpenXPS provides canonical sampling through velocity rescaling (Bussi et al., 2007), massive generalized Gaussian moment thermostatting (Liu and Tuckerman, 2000), regulated Nosé–Hoover–Langevin dynamics (Abreu and Tuckerman, 2021) and symmetric Langevin dynamics (Leimkuhler and Matthews, 2013), as well as multiple time-step integration of the physical and extension systems.
Features
- Dynamical variables with periodic, reflective or no bounds, in any units.
- Harmonic, collective-variable and inner-product couplings between dynamical variables and the physical system. Couplings can be summed.
ExtendedSpaceSimulationandExtendedSpaceContext, which keep the physical and extension contexts in sync and save or load both together.- Lockstep and multiple time-step integration of the two systems, with the thermostats listed above.
- Extended phase-space metadynamics.
ForceMatchingRegressor, which fits free-energy surfaces to mean forces with radial basis functions.ExtensionWriter, which reports extension-system data through CVPack reporters.
Installation
OpenXPS requires Python 3.10 or newer and OpenMM 8.4 or newer. Install it from the mdtools conda channel:
conda install -c conda-forge -c mdtools openxps
or from PyPI:
pip install openxps
PyTorch and Lightning, which ForceMatchingRegressor uses, are installed as
dependencies.
Quickstart
The script below runs a d-AFED simulation of alanine dipeptide in vacuum, with
dynamical variables coupled to the backbone dihedral angles φ and ψ. The physical
system is kept at 300 K and the dynamical variables at 1500 K. The molecule comes
from OpenMMTools, which you can install with pip install openmmtools or
conda install -c conda-forge openmmtools.
import sys
import cvpack
from openmm import unit
from openmmtools import testsystems
import openxps as xps
# Physical system: alanine dipeptide in vacuum
model = testsystems.AlanineDipeptideVacuum()
# Collective variables: the backbone dihedral angles phi and psi
backbone = [
atom.index for atom in model.topology.atoms() if atom.name in ("C", "CA", "N")
]
phi = cvpack.Torsion(*backbone[0:4], name="phi")
psi = cvpack.Torsion(*backbone[1:5], name="psi")
# Dynamical variables, harmonically coupled to the collective variables
mass = 12 * unit.dalton * (unit.nanometer / unit.radian) ** 2
kappa = 1000 * unit.kilojoule_per_mole / unit.radian**2
phi_s = xps.DynamicalVariable("phi_s", unit.radian, mass, xps.CircularBounds())
psi_s = xps.DynamicalVariable("psi_s", unit.radian, mass, xps.CircularBounds())
coupling = xps.HarmonicCoupling(phi, phi_s, kappa) + xps.HarmonicCoupling(
psi, psi_s, kappa
)
# Physical system at 300 K (2 fs steps), dynamical variables at 1500 K (8 fs steps)
integrator = xps.SplitIntegrator(
xps.integrators.SymmetricLangevinIntegrator(
300 * unit.kelvin, 1 / unit.picosecond, 2 * unit.femtoseconds
),
xps.integrators.SymmetricLangevinIntegrator(
1500 * unit.kelvin, 10 / unit.picosecond, 8 * unit.femtoseconds
),
)
simulation = xps.ExtendedSpaceSimulation(
model.topology, xps.ExtendedSpaceSystem(model.system, coupling), integrator
)
simulation.context.setPositions(model.positions)
simulation.context.setVelocitiesToTemperature(300 * unit.kelvin)
values = coupling.getCollectiveVariableValues(simulation.context)
simulation.context.setDynamicalVariableValues([values["phi"], values["psi"]])
simulation.context.setDynamicalVariableVelocitiesToTemperature(1500 * unit.kelvin)
simulation.reporters.append(
cvpack.reporting.StateDataReporter(
sys.stdout,
250,
step=True,
temperature=True,
writers=[xps.ExtensionWriter(temperature=True, dynamical_variables=True)],
)
)
simulation.step(2500) # 20 ps
Each line of the output reports the step, the physical and extension temperatures, and the values of the dynamical variables (your numbers will differ):
#"Step","Temperature (K)","Extension Temperature (K)","phi_s (rad)","psi_s (rad)"
250,250.67811271332351,1666.1861605801755,-2.154638148796597,2.617085205102951
500,272.0123447639219,1187.2009312011787,-2.831159123784501,-2.9213596609714596
...
With only two degrees of freedom, the extension temperature fluctuates widely, but its average approaches 1500 K in longer runs.
Examples
The alanine dipeptide examples include Jupyter notebooks on choosing masses and force constants for adiabatic simulations and on energy conservation in constant-energy simulations.
Documentation
The documentation of the latest release is available at GitHub Pages.
Citing OpenXPS
If you use OpenXPS in published work, please cite the software, using the metadata in
CITATION.cff (GitHub shows it under Cite this repository), and the
papers that introduced the methods you used, listed in Background.
License
OpenXPS is distributed under the MIT License.
Copyright (c) 2024-2026 C. Abreu
Metadata
Release files for openxps 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| openxps-0.2.0.tar.gz | 99.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| openxps-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 219.1 kB
Release files / openxps-0.2.0.tar.gz
| Download URL | openxps-0.2.0.tar.gz |
|---|---|
| Size | 99.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
fc05f7cd60d6edad3d71c8fc7424f1ec95bad48861c3bc11657d32274dbe9e5f
|
|
BLAKE2b-256 checksum How to use checksums |
46e3d3cd548b1b093ee48fd1940312b6712c5681d4b9cdb817a5e13143cd8fc3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.11.17
|
Release files / openxps-0.2.0-py3-none-any.whl
| Download URL | openxps-0.2.0-py3-none-any.whl |
|---|---|
| Size | 119.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
02cabf43abdbce621156691f2daaa34ab0415784aa07433e45c08019fc907237
|
|
BLAKE2b-256 checksum How to use checksums |
de8a2d7696d4507808e7614fa555a71dae9e943ccdba9b9b53b324e409274291
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.11.17
|