Protocol Groups
The ProtocolGroup
class represents a collection of protocols which have been grouped together. All
protocols within a group will be executed together on a single compute resources, i.e. there is currently no support for
executing protocols within a group in parallel.
Protocol groups have a specialised ProtocolGroupSchema
which is essentially a collection of ProtocolSchema
objects.
Conditional Protocol Groups
A ConditionalGroup
is a special class of ProtocolGroup
which will execute all of the grouped protocols again
and again until a set of conditions has been met or until a maximum number of iterations (see max_iterations
) has been
performed. They can be thought of as being a protocol representation of a while
statement.
Each condition to be met is represented by a Condition
object:
condition = ConditionalGroup.Condition()
# Set the left and right hand values.
condition.left_hand_value = ...
condition.right_hand_value = ...
# Choose the type of condition
condition.type = ConditionalGroup.Condition.Type.LessThan
The left and right hand values can either be constants, or come from the output of another protocol (including grouped
protocols) using a ProtocolPath
. Currently a condition can either check that a value is less than or greater than
another value.
Conditional groups expose a current_iteration
attribute which tracks how many times the grouped protocols have been
executed. This can be used as input by any of the grouped protocols and is useful, for example, to run a simulation for
longer and longer until the groups condition has been met:
conditional_group = ConditionalGroup("conditional_group")
# Set up protocols to run a simulation and then to extract the
# value of the density and its uncertainty.
simulation = OpenMMSimulation("simulation")
simulation.input_coordinate_file = "coords.pdb"
simulation.parameterized_system = ...
extract_density = AverageObservable("extract_density")
extract_density.observable = simulation.observables["Density"]
# Set the total number of iterations the simulation should perform to be equal
# to the current iteration of the group. I.e the simulation should perform a
# new iteration at each group iteration.
simulation.total_number_of_iterations = ProtocolPath(
"current_iteration", conditional_group.id
)
# Add the protocols to the group.
conditional_group.add_protocols(production_simulation, analysis_protocol)
# Set up a condition which will check if the uncertainty is less than
# some threshold.
condition = ConditionalGroup.Condition()
condition.condition_type = groups.ConditionalGroup.Condition.Type.LessThan
condition.right_hand_value = 0.5 * unit.gram / unit.millilitre
condition.left_hand_value = ProtocolPath(
"value.error", conditional_group.id, analysis_protocol.id
)
# Add the condition.
conditional_group.add_condition(condition)
It is this idea which is used to continue running a molecular simulations until an observable of interest (such as the density) has been calculated to within a specified uncertainty.