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_suffix : str, 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.

>>> from simtk import openmm, 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]

Initialize self. See help(type(self)) for accurate signature.

Methods

__init__([parameters_name_suffix]) Initialize self.
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.
class GlobalParameter(parameter_name, standard_value, validator=None)[source]

Descriptor for a global parameter.

Parameters:
parameter_name : str

The name of the global parameter.

standard_value : float

The value of the global parameter in the standard state. This is used to define the concept of compatible states (i.e. whether a System or Context can be transformed from a state to another).

validator : callable, optional

A function to call before setting a new value with signature validator(self, instance, new_value) -> validated_value. It is also possible to define this through the validator decorator.

Methods

validator  
apply_to_context(context)[source]

Put the Context into this state.

Parameters:
context : simtk.openmm.Context

The context to set.

Raises:
GlobalParameterError

If the context does not have the required global parameters.

apply_to_system(system)[source]

Set the state of the system to this.

Parameters:
system : simtk.openmm.System

The system to modify.

Raises:
GlobalParameterError

If the system does not defined some of the global parameters controlled by this state.

check_system_consistency(system)[source]

Check if the system is in this state.

It raises a GlobalParameterError if the system is not consistent with this state.

Parameters:
system : simtk.openmm.System

The system to test.

Raises:
GlobalParameterError

If the system is not consistent with this state.

classmethod from_system(system, parameters_name_suffix=None)[source]

Static constructor reading the state from an OpenMM System.

Parameters:
system : simtk.openmm.System

An OpenMM System object defining a non-empty subset of global parameters controlled by this state.

parameters_name_suffix : str, optional

If specified, the state will search for a modified version of the global parameters with the name parameter_name + '_' + parameters_name_suffix.

Returns:
The GlobalParameterState object representing the state of the system.
Raises:
GlobalParameterStateError

If the same parameter has different values in the system, or if the system has no lambda parameters.

get_function_variable(variable_name)[source]

Return the value of the function variable.

Function variables are _not_ global parameters but rather variables entering mathematical expressions specified with GlobalParameterFunction, which can be use to enslave global parameter to arbitrary variables.

Parameters:
variable_name : str

The name of the function variable.

Returns:
variable_value : float

The value of the function variable.

set_function_variable(variable_name, new_value)[source]

Set the value of the function variable.

Function variables are _not_ global parameters but rather variables entering mathematical expressions specified with GlobalParameterFunction, which can be use to enslave global parameter to arbitrary variables.

Parameters:
variable_name : str

The name of the function variable.

new_value : float

The new value for the variable.