Custom Action Features¶
Overview¶
Questions¶
How do I access the simulation state information?
How do I create loggable quantities in custom actions?
What are other features provided by the custom action/operation API?
Objectives¶
Explain how to access simulation state in a custom action.
Explain how to expose loggable quantities in a custom action.
Demonstrate other miscellaneous features of custom actions.
Boilerplate Code¶
[1]:
import hoomd
cpu = hoomd.device.CPU()
simulation = hoomd.Simulation(device=cpu)
snap = hoomd.Snapshot()
snap.particles.N = 1
snap.particles.position[:] = [0, 0, 0]
snap.particles.types = ['A']
snap.particles.typeid[:] = [0]
snap.configuration.box = [10, 10, 10, 0, 0, 0]
simulation.create_state_from_snapshot(snap)
How Do I Access the Simulation State?¶
By the time that a custom action will have its act
method called it will have an attribute _state
accessible to it which is the simulation state for the simulation it is associated with. The behavior of this is controlled in the hoomd.custom.Action.attach
method. The method takes in a simulation object and performs any necessary set-up for the action call act
. By default, the method stores the simulation state in the _state
attribute.
We will create two custom actions class to show this. In one, we will not modify the attach
method, and in the other we will make attach
method also print out some information.
[2]:
class PrintTimestep(hoomd.custom.Action):
def act(self, timestep):
print(timestep)
class NotifyAttachWithPrint(hoomd.custom.Action):
def attach(self, simulation):
print(f"Has '_state' attribute {hasattr(self, '_state')}.")
super().attach(simulation)
print(f"Has '_state' attribute {hasattr(self, '_state')}.")
def act(self, timestep):
print(timestep)
Like in the previous section these are both writers. We will go ahead and wrap them and see what happens when we try to run the simulation.
[3]:
print_timestep = PrintTimestep()
print_timestep_operation = hoomd.write.CustomWriter(
action=print_timestep, trigger=hoomd.trigger.Periodic(10)
)
simulation.operations.writers.append(print_timestep_operation)
simulation.run(0)
[4]:
simulation.operations -= print_timestep_operation
print_timestep_with_notify = NotifyAttachWithPrint()
simulation.operations.writers.append(
hoomd.write.CustomWriter(
action=print_timestep_with_notify, trigger=hoomd.trigger.Periodic(10)
)
)
simulation.run(0)
Has '_state' attribute False.
Has '_state' attribute True.
Loggable Quantities in Custom Actions¶
Custom actions can hook into HOOMD-blue’s logging subsystem by using the hoomd.logging.log
decorator to document which methods/properties of a custom action are loggable. See the documentation on hoomd.logging.log
and hoomd.logging.TypeFlags
for complete documenation of the decorator and loggable types.
In general, log
as a decorator takes optional arguments that control whether to make a method a property, what type the loggable quantity is, and whether the quantity should be logged by default.
Rather than elaborate, we will use an example to explain these attributes.
[5]:
class ActionWithLoggables(hoomd.custom.Action):
@hoomd.logging.log
def scalar_property_loggable(self):
return 42
@hoomd.logging.log(category='string')
def string_loggable(self):
return 'I am a string loggable.'
def act(self, timestep):
pass
action = ActionWithLoggables()
[6]:
action.scalar_property_loggable
[6]:
42
[7]:
action.string_loggable
[7]:
'I am a string loggable.'
Custom Operation Wrapping¶
Another feature of the custom action API is that when an object is wrapped by a custom operation object (which is necessary to add a custom action to a simulation), the action’s attributes are available through the operation object as if the operation were the action. For example, we will wrap action
from the previous code block in a CustomWriter
and access its attributes that way.
Due to this wrapping the attribute trigger
should not exist in your custom action.
[8]:
custom_op = hoomd.write.CustomWriter(action=action, trigger=100)
custom_op.scalar_property_loggable
[8]:
42
[9]:
custom_op.string_loggable
[9]:
'I am a string loggable.'
Summary¶
These summarize most of the unique features of custom actions in Python. They are - Accessing simulation state through _state
- Exposing loggable quantities - Accessing action attributes through custom operation wrapper
With this information, you could write almost any action that is possible to write in Python for use in HOOMD-blue. The remain tutorial sections will focus on concrete examples and show some tricks to get the best performance. For the full list of accessible features for custom actions see the reference documentation.