Skip to content

OPES

OPES(system, variables, temperature, barrier, frequency, varianceFrequency, biasFactor=None, exploreMode=False, bounded=False, saveFrequency=None, biasDir=None, walkerId=None, warmupSteps=None, compressionThreshold=1.0, useExistingBandwidths=True, kernelShape='gaussian', statsWindowSize=10, minBandwidth=None, extraBias=None)

On-the-fly Probability Enhanced Sampling.

Implements OPES and its exploratory variant, following Invernizzi and Parrinello, https://doi.org/10.1021/acs.jpclett.0c00497 and https://doi.org/10.1021/acs.jctc.2c00152.

Parameters:

Name Type Description Default
system

The System to simulate. A CustomCVForce implementing the bias is created and added to it.

required
variables

The collective variables whose sampling should be enhanced.

required
temperature

The temperature at which the simulation is run.

required
barrier

The free energy barrier the simulation should overcome.

required
frequency

Interval in time steps at which to deposit a kernel.

required
varianceFrequency

Interval in time steps at which to update the CV variance. When None, the bandwidth is fixed and taken from each variable's biasWidth, which is interpreted as the standard deviation of the UNBIASED distribution, exactly as both papers define sigma^(0).

required
biasFactor

Defaults to barrier / kT. Must be finite: unlike PLUMED, the uniform-target limit inf is not supported.

None
exploreMode bool

Whether to apply the OPES-explore variant. Must match the mode of a snapshot passed to setState and of every walker sharing biasDir.

False
bounded bool

Whether non-periodic CVs have reflective boundaries.

False
saveFrequency

Interval in time steps at which to share the bias on disk. Must be a multiple of frequency.

None
biasDir

Directory shared with other walkers.

None
walkerId

This walker's identifier within biasDir. Random when omitted; pass a stable value across restarts so a resumed walker reclaims its own file rather than leaving the previous run's behind as a phantom peer.

None
warmupSteps

When given, run this many steps without depositing kernels while measuring the CV variance, then freeze it.

None
compressionThreshold float

Mahalanobis distance below which kernels are merged.

1.0
useExistingBandwidths bool

Whether the merge search scales by existing kernels' bandwidths.

True
kernelShape str

"gaussian" or "compact".

'gaussian'
statsWindowSize int

Window, in deposition strides, of the running CV-mean estimate. With an adaptive variance, the first kernel also waits this many strides, so that it is sized from a measured variance.

10
minBandwidth

Per-CV floor on the bandwidth of new kernels. By default there is none, as in PLUMED, so that Silverman's rule alone sets bandwidths.

None
extraBias

Other biases acting on the simulation, as PLUMED's EXTRA_BIAS: each sample is weighted by exp(beta (V + V_extra)), so that the free energy estimate removes them too. Items are force groups, Forces, or objects with a getBiasEnergy(context) method, such as other samplers. The bias itself still follows the density estimate as usual. In explore mode, only the reweighted estimate changes; PLUMED offers EXTRA_BIAS for OPES_METAD only.

None

addKernel

addKernel(values, biasEnergy, variance=None)

Deposit a kernel into the probability estimates.

Returns whether a kernel was actually deposited: a non-positive variance estimate is skipped rather than deposited, since a zero bandwidth gives the kernel -inf log height and poisons the estimate.

This does not refresh any Context; call updateContext afterwards if a simulation is running.

getAverageDensity

getAverageDensity()

Z_n, the mean density over the explored CV space.

NaN until the first kernel is deposited, like getFreeEnergy.

getBias

getBias()

The OPES bias potential on the grid.

With no kernels deposited yet the estimate is empty, and both the log PDF and the log mean density are -inf, whose difference is NaN. The bias is well defined in that limit, though: the regularization term dominates, leaving the flat -barrier floor. Returning it explicitly keeps NaN out of the forces.

getBiasEnergy

getBiasEnergy(context)

The bias energy V(s) this sampler applies in a Context.

Parameters:

Name Type Description Default
context

A Context of the System this sampler biases.

required

getCollectiveVariables

getCollectiveVariables(simulation)

Current values of all collective variables in a Simulation.

getCt

getCt(estimate='current')

c(t), the reweighting constant of the time-dependent bias.

Reweighting a sample taken at time t by exp(beta [V_t(s) - c(t)]) removes the bias even while it still changes. Two estimates are available:

  • "current": -kT ln over the reweighted density estimate P_n, for the bias acting now. It needs a reasonable P_n and is then unbiased.
  • "running": PLUMED's rct component, kT ln of the mean weight of all samples so far, including one fictitious sample under the initial flat bias -barrier. It averages over past biases, so it lags behind the current one. Like PLUMED, which warns against reweighting with rct, treat it as a convergence diagnostic: it should level off as the bias converges. With extraBias, the weights include the extra biases.

The current estimate is NaN before the first kernel.

getFreeEnergy

getFreeEnergy(correctSmoothing=False, pilotFactor=2.0)

Free energy as a function of the collective variables.

Returned as an N-dimensional array in kJ/mole. The i'th position along an axis corresponds to minValue + i*(maxValue-minValue)/(gridWidth-1), matching the numpy.linspace(minValue, maxValue, gridWidth) axis the estimate is built on. Always the importance-sampling estimate, which converges better than the direct one in explore mode.

Every entry is NaN until the first kernel is deposited: with no samples there is no density to take a logarithm of. Unlike getBias, this has no defined limit to fall back on, and it never reaches the forces.

Parameters:

Name Type Description Default
correctSmoothing bool

Whether to remove the smoothing bias of the kernel estimate, which makes steep basin walls too low and basin floors too high. Uses OnlineKDE.getCorrectedLogPDF, a multiplicative correction that also lowers the noise of a single run, at the cost of a few evaluations of the kernels per call. Free energy differences between basins are unchanged. It helps once the kernels are narrow next to the basins, but early in a run, while they are still wide, it can make the surface worse.

False
pilotFactor float

Broadening of the pilot kernels in that correction. Values of 1.5 to 3 work well; wider pilots leave more bias.

2.0

getNumKernels

getNumKernels()

Number of kernels in the estimate that defines the bias.

getState

getState()

Flat, npz-writable snapshot of this sampler's accumulated state.

getVariance

getVariance()

Variance currently used to size newly deposited kernels.

setState

setState(state)

Restore from a getState snapshot.

A snapshot from a single-walker run seeds this walker's own contribution to the shared bias, since that run had no peers.

The restored bias reaches the simulation at the start of the next step. Call updateContext to push it into a Context sooner, e.g. before computing energies.

step

step(simulation, steps)

Advance the simulation by a number of time steps.

Parameters:

Name Type Description Default
simulation

The Simulation to advance.

required
steps

The number of time steps to integrate.

required

stepTogether staticmethod

stepTogether(simulation, samplers, steps)

Advance a simulation biased by several OPES samplers at once.

Each sampler adds its own bias force to the same System, as several OPES actions do in a single PLUMED input. Each one deposits kernels on its own schedule and weights them by its own bias only. This is how, for instance, OPES and OPES-explore run together in OPES_COM (Ray & Rizzi, J. Chem. Theory Comput. 21, 58 (2025)).

Parameters:

Name Type Description Default
simulation

The Simulation to advance. Its System must contain the forces of all samplers.

required
samplers

The samplers acting on the simulation, all distinct.

required
steps

The number of time steps to integrate.

required

updateContext

updateContext(context)

Push the current bias into a Context.

The table stores V + barrier, so the energy the force contributes is the bias shifted up by barrier: the unexplored floor sits at 0. OpenMM's tabulated functions are zero outside their range, so a CV that leaves [minValue, maxValue] sees the bias of a region nothing has been deposited in, rather than a jump of barrier.