openmmtools.states.GlobalParameterState

class openmmtools.states.GlobalParameterState(parameters_name_suffix=None, **kwargs)[source]

A composable state controlling one or more OpenMM Force’s global parameters.

This is a partially abstract class that provides facilities to implement composable states that control one or more global parameters defined in OpenMM Force objects. Global parameters are implemented through the use of the GlobalParameterState.GlobalParameter descriptor.

A Force object can use one or more global parameters that are controlled by the same state. Conversely, multiple ``Force``s can use the same global parameter (i.e. with the same name) controlled by the state object.

It is possible to enslave the global parameters to one or more arbitrary variables entering a mathematical expression through the use of GlobalParameterFunction. Global parameters that are associated to a global parameter function are validated on get rather than on set.

Parameters:
parameters_name_suffixstr, optional

If specified, the state will control a modified version of the global parameters with the name parameter_name + '_' + parameters_name_suffix. When this is the case, the normal parameters are not accessible.

**kwargs

The value of the parameters controlled by this state. Parameters that are not passed here are left undefined.

Notes

The class automatically implement the static constructor from_system that reads and create a state object from an OpenMM System. The function calls __init__ and passes the parameter name suffix string as the first positional argument, so it is possible to overwrite __init__ and rename parameters_name_suffix as long as it is the first parameter of the constructor.

Examples

Assume we have a System with a custom force object whose energy function is controlled by two global variables called lambda_bonds and gamma.

>>> import openmm
>>> from openmm import unit
>>> # Define a diatomic molecule.
>>> system = openmm.System()
>>> particle_idx = system.addParticle(40.0*unit.amu)
>>> particle_idx = system.addParticle(40.0*unit.amu)
>>> custom_force = openmm.CustomBondForce('lambda_bonds^gamma*60000*(r-0.15)^2;')
>>> parameter_idx = custom_force.addGlobalParameter('lambda_bonds', 1.0)  # Default value is 1.0.
>>> parameter_idx = custom_force.addGlobalParameter('gamma', 1.0)  # Default value is 1.0.
>>> bond_idx = custom_force.addBond(0, 1, [])
>>> force_index = system.addForce(custom_force)
>>> # Create a thermodynamic state object controlling the temperature of the system.
>>> thermodynamic_state = ThermodynamicState(system, temperature=300.0*unit.kelvin)

Define a composable state controlling the two global parameters gamma and lambda_bonds, both with standard state value 0.0. Parameters that are not specified in the constructor are left undefined.

>>> class MyComposableState(GlobalParameterState):
...     gamma = GlobalParameterState.GlobalParameter('gamma', standard_value=1.0)
...     lambda_bonds = GlobalParameterState.GlobalParameter('lambda_bonds', standard_value=1.0)
...
>>> my_composable_state = MyComposableState(gamma=1.0)
>>> my_composable_state.gamma
1.0
>>> my_composable_state.lambda_bonds is None
True

There is a second static constructor you can use to read the state of an OpenMM System from the default values of its force parameters.

>>> my_composable_state = MyComposableState.from_system(system)
>>> my_composable_state.lambda_bonds
1.0
>>> my_composable_state.gamma
1.0

Optionally, you can limit the values that a global parameter can assume. In this case, lambda_bonds is forced to be between 0.0 and 1.0.

>>> class MyComposableState(GlobalParameterState):
...     gamma = GlobalParameterState.GlobalParameter('gamma', standard_value=0.0)
...     lambda_bonds = GlobalParameterState.GlobalParameter('lambda_bonds', standard_value=0.0)
...     @lambda_bonds.validator
...     def lambda_bonds(self, instance, new_value):
...         if new_value is not None and not (0.0 <= new_value <= 1.0):
...             raise ValueError('lambda_bonds must be between 0.0 and 1.0')
...         return new_value
...
>>> my_composable_state = MyComposableState(gamma=1.0)
>>> my_composable_state.lambda_bonds = 2.0
Traceback (most recent call last):
...
ValueError: lambda_bonds must be between 0.0 and 1.0

You can then add it to a CompoundThermodynamicState to manipulate OpenMM System and Context objects.

>>> my_composable_state.lambda_bonds = 1.0
>>> compound_state = CompoundThermodynamicState(thermodynamic_state, composable_states=[my_composable_state])
>>> state_system = compound_state.get_system()
>>> state_system.getForce(0).getGlobalParameterDefaultValue(0)  # lambda_bonds global parameter.
1.0
>>> compound_state.lambda_bonds = 0.0
>>> state_system = compound_state.get_system()
>>> state_system.getForce(0).getGlobalParameterDefaultValue(0)  # lambda_bonds global parameter.
0.0
>>> context = compound_state.create_context(openmm.VerletIntegrator(1.0*unit.femtoseconds))
>>> context.getParameter('lambda_bonds')
0.0
>>> compound_state.lambda_bonds = 1.0
>>> compound_state.apply_to_context(context)
>>> context.getParameter('lambda_bonds')
1.0

You can express enslave global parameters to a mathematical expression involving arbitrary variables.

>>> compound_state.set_function_variable('lambda', 1.0)
>>> compound_state.lambda_bonds = GlobalParameterFunction('2*(lambda - 0.5) * step(lambda - 0.5)')
>>> for l in [0.5, 0.75, 1.0]:
...     compound_state.set_function_variable('lambda', l)
...     print(compound_state.lambda_bonds)
0.0
0.5
1.0

If you need to control similar forces with the same state object, this parent class provides a suffix mechanism to control different global variables with the same state object. This allows to reuse the same logic to control multiple objects

>>> # Add a second custom force using similar global parameters.
>>> custom_force = openmm.CustomBondForce('lambda_bonds_mysuffix*20000*(r-0.15)^2;')
>>> parameter_idx = custom_force.addGlobalParameter('lambda_bonds_mysuffix', 1.0)  # Default value is 1.0.
>>> bond_idx = custom_force.addBond(0, 1, [])
>>> force_idx = system.addForce(custom_force)
>>> # Create a state controlling the modified global parameter.
>>> my_composable_state = MyComposableState(parameters_name_suffix='mysuffix', lambda_bonds=0.0)
>>> my_composable_state.lambda_bonds_mysuffix = 1.0
>>> my_composable_state.gamma_mysuffix is None
True
>>> my_composable_state.apply_to_system(system)
>>> # The unmodified parameter becomes unaccessible.
>>> my_composable_state.apply_to_system(system)
>>> my_composable_state.lambda_bonds
Traceback (most recent call last):
...
AttributeError: This state does not control lambda_bonds but lambda_bonds_mysuffix.

Note also in the example above that the forces don’t need to define all the global parameters controlled by the state. The state object will perform some check to ensure that you won’t try to set an undefined parameter.

>>> my_composable_state.gamma_mysuffix = 2
>>> my_composable_state.apply_to_system(system)
Traceback (most recent call last):
...
openmmtools.states.GlobalParameterError: Could not find global parameter gamma_mysuffix in the system.

Methods

GlobalParameter(parameter_name, standard_value)

Descriptor for a global parameter.

apply_to_context(context)

Put the Context into this state.

apply_to_system(system)

Set the state of the system to this.

check_system_consistency(system)

Check if the system is in this state.

from_system(system[, parameters_name_suffix])

Static constructor reading the state from an OpenMM System.

get_function_variable(variable_name)

Return the value of the function variable.

set_function_variable(variable_name, new_value)

Set the value of the function variable.

__init__(parameters_name_suffix=None, **kwargs)[source]

Methods

__init__([parameters_name_suffix])

apply_to_context(context)

Put the Context into this state.

apply_to_system(system)

Set the state of the system to this.

check_system_consistency(system)

Check if the system is in this state.

from_system(system[, parameters_name_suffix])

Static constructor reading the state from an OpenMM System.

get_function_variable(variable_name)

Return the value of the function variable.

set_function_variable(variable_name, new_value)

Set the value of the function variable.