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 theGlobalParameterState.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.
See also
Notes
The class automatically implement the static constructor
from_system
that reads and create a state object from an OpenMMSystem
. The function calls__init__
and passes the parameter name suffix string as the first positional argument, so it is possible to overwrite__init__
and renameparameters_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 calledlambda_bonds
andgamma
.>>> 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
andlambda_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 OpenMMSystem
andContext
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.
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.