State Sets and Hooks

If a malcolm Block has a state attribute, its controller has a StateSet that controls the valid transitions that it can make. These are arranged in a heirarchy.

StatefulController

A StatefulController has Ready, Fault and Disable states. It is used in blocks in the Hardware Layer. It implements the following statemachine:

class malcolm.modules.builtin.util.StatefulStates[source]

This state set covers controllers and parts that can be disabled and have faults, but otherwise have no state.

digraph { newrank=true; // Sensible ranking of clusters bgcolor=transparent compound=true rankdir=LR node [fontname=Arial fontsize=10 shape=rect style=filled fillcolor="#8BC4E9"] graph [fontname=Arial fontsize=11] edge [fontname=Arial fontsize=10 arrowhead=vee] Fault [fillcolor="#F03232"] Disabled [fillcolor="#AAAAAA"] subgraph cluster_normal { Ready [fillcolor="#BBE7BB"] Resetting -> Ready } Resetting -> Disabling [ltail=cluster_normal label="disable()"] Resetting -> Fault [ltail=cluster_normal label="on_error"] Fault -> Resetting [label="reset()"] Fault -> Disabling [label="disable()"] Disabling -> Fault [label="on_error"] Disabling -> Disabled Disabled -> Resetting [label="reset()"] label="Unlabelled transitions take place in response to internal actions\n Labelled transitions are triggered externally."; labelloc=bottom; }

The following Hooks are run during state transitions:

class malcolm.modules.builtin.hooks.InitHook(part: Anno(name='APart', typ=<class 'malcolm.core.part.Part'>, description='The part that has attached to the Hook'), context: Anno(name='AContext', typ=<class 'malcolm.core.context.Context'>, description='Context that should be used to perform operations on child blocks'), **kwargs: Any)[source]

Called when this controller is told to start by the process

Parameters
  • part (Part) – The part that has attached to the Hook

  • context (Context) – Context that should be used to perform operations on child blocks

class malcolm.modules.builtin.hooks.ResetHook(part: Anno(name='APart', typ=<class 'malcolm.core.part.Part'>, description='The part that has attached to the Hook'), context: Anno(name='AContext', typ=<class 'malcolm.core.context.Context'>, description='Context that should be used to perform operations on child blocks'), **kwargs: Any)[source]

Called at reset() to reset all parts to a known good state

Parameters
  • part (Part) – The part that has attached to the Hook

  • context (Context) – Context that should be used to perform operations on child blocks

class malcolm.modules.builtin.hooks.HaltHook(part: Anno(name='APart', typ=<class 'malcolm.core.part.Part'>, description='The part that has attached to the Hook'), context: Anno(name='AContext', typ=<class 'malcolm.core.context.Context'>, description='Context that should be used to perform operations on child blocks'), **kwargs: Any)[source]

Called when this controller is told to halt

Parameters
  • part (Part) – The part that has attached to the Hook

  • context (Context) – Context that should be used to perform operations on child blocks

class malcolm.modules.builtin.hooks.DisableHook(part: Anno(name='APart', typ=<class 'malcolm.core.part.Part'>, description='The part that has attached to the Hook'), context: Anno(name='AContext', typ=<class 'malcolm.core.context.Context'>, description='Context that should be used to perform operations on child blocks'), **kwargs: Any)[source]

Called at disable() to stop all parts updating their attributes

Parameters
  • part (Part) – The part that has attached to the Hook

  • context (Context) – Context that should be used to perform operations on child blocks

ManagerController

A ManagerController adds Loading/Saving. It is used in simple blocks in the Device Layer. It implements the following statemachine:

class malcolm.modules.builtin.util.ManagerStates[source]

This state set covers controllers and parts that have loadable and savable child state.

digraph { newrank=true; // Sensible ranking of clusters bgcolor=transparent compound=true rankdir=LR node [fontname=Arial fontsize=10 shape=rect style=filled fillcolor="#8BC4E9"] graph [fontname=Arial fontsize=11] edge [fontname=Arial fontsize=10 arrowhead=vee] Fault [fillcolor="#F03232"] Disabled [fillcolor="#AAAAAA"] subgraph cluster_normal { Ready [fillcolor="#BBE7BB"] Ready -> Saving [label="save()"] Saving -> Ready [weight=0] Ready -> Loading [label="put\ndesign"] Loading -> Ready [weight=0] Resetting -> Ready } Resetting -> Disabling [ltail=cluster_normal label="disable()"] Resetting -> Fault [ltail=cluster_normal label="on_error"] Fault -> Resetting [label="reset()"] Fault -> Disabling [label="disable()"] Disabling -> Fault [label="on_error"] Disabling -> Disabled Disabled -> Resetting [label="reset()"] label="Unlabelled transitions take place in response to internal actions\n Labelled transitions are triggered externally."; labelloc=bottom; }

The following Hooks are run during state transitions:

class malcolm.modules.builtin.hooks.LayoutHook(part: Anno(name='APart', typ=<class 'malcolm.core.part.Part'>, description='The part that has attached to the Hook'), context: Anno(name='AContext', typ=<class 'malcolm.core.context.Context'>, description='Context that should be used to perform operations on child blocks'), ports: Anno(name='APortMap', typ=(<class 'str'>, annotypes._array.Array[malcolm.modules.builtin.infos.PortInfo]), description='The PortInfos for all the parts'), layout: Anno(name='ALayoutTable', typ=<class 'malcolm.modules.builtin.util.LayoutTable'>, description='A possibly partial set of changes to the layout table that should be acted on'))[source]

Called when layout table set and at init to update child layout

Parameters
  • part (Part) – The part that has attached to the Hook

  • context (Context) – Context that should be used to perform operations on child blocks

  • ports – The PortInfos for all the parts

  • layout (LayoutTable) – A possibly partial set of changes to the layout table that should be acted on

validate_return(ret: Optional[Union[Anno(name='ALayoutInfos', typ=<class 'malcolm.modules.builtin.infos.LayoutInfo'>, description='The current layout information'), Sequence[malcolm.modules.builtin.infos.LayoutInfo], malcolm.modules.builtin.infos.LayoutInfo]]) -> Anno(name='ALayoutInfos', typ=<class 'malcolm.modules.builtin.infos.LayoutInfo'>, description='The current layout information')[source]

Check that all returned infos are LayoutInfos

class malcolm.modules.builtin.hooks.LoadHook(part: Anno(name='APart', typ=<class 'malcolm.core.part.Part'>, description='The part that has attached to the Hook'), context: Anno(name='AContext', typ=<class 'malcolm.core.context.Context'>, description='Context that should be used to perform operations on child blocks'), structure: Anno(name='AStructure', typ=(<class 'str'>, typing.Any), description='The serialized structure to load'), init: Anno(name='AInit', typ=<class 'bool'>, description='Whether this operation is taking place at init'))[source]

Called at load() to load child settings from a structure

Parameters
  • part (Part) – The part that has attached to the Hook

  • context (Context) – Context that should be used to perform operations on child blocks

  • structure – The serialized structure to load

  • init (bool) – Whether this operation is taking place at init

class malcolm.modules.builtin.hooks.SaveHook(part: Anno(name='APart', typ=<class 'malcolm.core.part.Part'>, description='The part that has attached to the Hook'), context: Anno(name='AContext', typ=<class 'malcolm.core.context.Context'>, description='Context that should be used to perform operations on child blocks'), **kwargs: Any)[source]

Called at save() to serialize child settings into a dict structure

Parameters
  • part (Part) – The part that has attached to the Hook

  • context (Context) – Context that should be used to perform operations on child blocks

validate_return(ret: Anno(name='AStructure', typ=(<class 'str'>, typing.Any), description='The serialized structure to load')) -> Anno(name='AStructure', typ=(<class 'str'>, typing.Any), description='The serialized structure to load')[source]

Check that a serialized structure is returned

RunnableController

A RunnableController adds Configuring/Running/Aborting/Seeking. It is used in blocks that support scans in the Device Layer or Scan Layer. It implements the following statemachine:

class malcolm.modules.scanning.util.RunnableStates[source]

This state set covers controllers and parts that can be configured and then run, and have the ability to pause and rewind

digraph { newrank=true; // Sensible ranking of clusters bgcolor=transparent compound=true rankdir=LR node [fontname=Arial fontsize=10 shape=rect style=filled fillcolor="#8BC4E9"] graph [fontname=Arial fontsize=11] edge [fontname=Arial fontsize=10 arrowhead=vee] Fault [fillcolor="#F03232"] Disabled [fillcolor="#AAAAAA"] subgraph cluster_normal { subgraph cluster_abortable { Ready [fillcolor="#BBE7BB"] Ready -> Configuring [label="configure()" weight=30] Ready -> Saving [label="save()"] Saving -> Ready [weight=0] Ready -> Loading [label="put\ndesign"] Loading -> Ready [weight=0] Armed [fillcolor="#BBE7BB"] Configuring -> Armed Armed -> Running [label="run()"] Armed -> Seeking [label="put\nsteps"] Running -> PostRun Running -> Seeking [label="pause()"] PostRun -> Finished PostRun -> Armed PostRun -> Seeking [label="pause()"] Finished [fillcolor="#BBE7BB"] Finished -> Seeking [label="pause()"] Finished -> Configuring [label="configure()" weight=30] Seeking -> Armed Seeking -> Paused Paused -> Seeking [label="put\nsteps"] Paused -> Running [label="resume()"] } Aborted [fillcolor="#FFBE89"] Resetting -> Ready Seeking -> Aborting [ltail=cluster_abortable label="abort()"] Aborting -> Aborted Aborted -> Resetting [label="reset()"] Armed -> Resetting [label="reset()"] Finished -> Resetting [label="reset()"] } Aborted -> Disabling [ltail=cluster_normal label="disable()"] Aborted -> Fault [ltail=cluster_normal label="on_error"] Fault -> Resetting [label="reset()"] Fault -> Disabling [label="disable()"] Disabling -> Fault [label="on_error"] Disabling -> Disabled Disabled -> Resetting [label="reset()"] {rank=min Ready Resetting Fault} {rank=same Loading Saving Configuring} {rank=same Armed Seeking Finished Aborted Disabling} {rank=max Paused Running PostRun Aborting Disabled} label="Unlabelled transitions take place in response to internal actions\n Labelled transitions are triggered externally."; labelloc=bottom; }

The following Hooks are run during state transitions:

class malcolm.modules.scanning.hooks.ValidateHook(part: Anno(name='APart', typ=<class 'malcolm.core.part.Part'>, description='The part that has attached to the Hook'), context: Anno(name='AContext', typ=<class 'malcolm.core.context.Context'>, description='Context that should be used to perform operations on child blocks'), part_info: Union[Anno(name='APartInfo', typ=(<class 'str'>, annotypes._array.Array[malcolm.core.info.Info]), description='The Infos returned from other Parts'), Mapping[str, Sequence[malcolm.core.info.Info]]], generator: Anno(name='AGenerator', typ=<class 'scanpointgenerator.core.compoundgenerator.CompoundGenerator'>, description='Generator instance providing specification for scan'), axesToMove: Anno(name='AAxesToMove', typ=<class 'str'>, description='List of axes in inner dimension of generator that should be moved'), breakpoints: Anno(name='ABreakpoints', typ=<class 'numpy.int32'>, description='List of points at which the run will return in Armed state'), **kwargs: Any)[source]

Called at validate() to check parameters are valid

Parameters
  • part (Part) – The part that has attached to the Hook

  • context (Context) – Context that should be used to perform operations on child blocks

  • part_info – The Infos returned from other Parts

  • generator (CompoundGenerator) – Generator instance providing specification for scan

  • axesToMove (str) – List of axes in inner dimension of generator that should be moved

  • breakpoints (int32) – List of points at which the run will return in Armed state

validate_return(ret: Optional[Union[Anno(name='AParameterTweakInfos', typ=<class 'malcolm.modules.scanning.infos.ParameterTweakInfo'>, description='Parameters that need to be changed to make them compatible'), Sequence[malcolm.modules.scanning.infos.ParameterTweakInfo], malcolm.modules.scanning.infos.ParameterTweakInfo]]) -> Anno(name='AParameterTweakInfos', typ=<class 'malcolm.modules.scanning.infos.ParameterTweakInfo'>, description='Parameters that need to be changed to make them compatible')[source]

Check that all returned infos are ParameterTweakInfo that list the parameters that need to be changed to make them compatible with this part. ValidateHook will be re-run with the modified parameters.

class malcolm.modules.scanning.hooks.ReportStatusHook(part: Anno(name='APart', typ=<class 'malcolm.core.part.Part'>, description='The part that has attached to the Hook'), context: Anno(name='AContext', typ=<class 'malcolm.core.context.Context'>, description='Context that should be used to perform operations on child blocks'), **kwargs: Any)[source]

Called before Validate, Configure, PostRunArmed and Seek hooks to report the current configuration of all parts

Parameters
  • part (Part) – The part that has attached to the Hook

  • context (Context) – Context that should be used to perform operations on child blocks

validate_return(ret: Optional[Union[Anno(name='AInfos', typ=<class 'malcolm.core.info.Info'>, description='Infos about current Part status to be passed to other parts'), Sequence[malcolm.core.info.Info], malcolm.core.info.Info]]) -> Anno(name='AInfos', typ=<class 'malcolm.core.info.Info'>, description='Infos about current Part status to be passed to other parts')[source]

Check that all parts return Info objects relevant to other parts

class malcolm.modules.scanning.hooks.PreConfigureHook(part: Anno(name='APart', typ=<class 'malcolm.core.part.Part'>, description='The part that has attached to the Hook'), context: Anno(name='AContext', typ=<class 'malcolm.core.context.Context'>, description='Context that should be used to perform operations on child blocks'), **kwargs: Any)[source]

Called before configure() to get the device into a suitable state to report status and run configure. Typically will load a saved design.

Parameters
  • part (Part) – The part that has attached to the Hook

  • context (Context) – Context that should be used to perform operations on child blocks

class malcolm.modules.scanning.hooks.ConfigureHook(part: Anno(name='APart', typ=<class 'malcolm.core.part.Part'>, description='The part that has attached to the Hook'), context: Anno(name='AContext', typ=<class 'malcolm.core.context.Context'>, description='Context that should be used to perform operations on child blocks'), completed_steps: Anno(name='ACompletedSteps', typ=<class 'int'>, description='Number of steps already completed'), steps_to_do: Anno(name='AStepsToDo', typ=<class 'int'>, description='Number of steps we should configure for'), part_info: Anno(name='APartInfo', typ=(<class 'str'>, annotypes._array.Array[malcolm.core.info.Info]), description='The Infos returned from other Parts'), generator: Anno(name='AGenerator', typ=<class 'scanpointgenerator.core.compoundgenerator.CompoundGenerator'>, description='Generator instance providing specification for scan'), axesToMove: Anno(name='AAxesToMove', typ=<class 'str'>, description='List of axes in inner dimension of generator that should be moved'), breakpoints: Anno(name='ABreakpoints', typ=<class 'numpy.int32'>, description='List of points at which the run will return in Armed state'), **kwargs: Any)[source]

Called at configure() to configure child block for a run

Parameters
  • part (Part) – The part that has attached to the Hook

  • context (Context) – Context that should be used to perform operations on child blocks

  • completed_steps (int) – Number of steps already completed

  • steps_to_do (int) – Number of steps we should configure for

  • part_info – The Infos returned from other Parts

  • generator (CompoundGenerator) – Generator instance providing specification for scan

  • axesToMove (str) – List of axes in inner dimension of generator that should be moved

  • breakpoints (int32) – List of points at which the run will return in Armed state

classmethod create_info(configure_func: Callable) malcolm.modules.scanning.infos.ConfigureParamsInfo[source]

Create a ConfigureParamsInfo describing the extra parameters that should be passed at configure

validate_return(ret: Optional[Union[Anno(name='AInfos', typ=<class 'malcolm.core.info.Info'>, description='Infos about current Part status to be passed to other parts'), Sequence[malcolm.core.info.Info], malcolm.core.info.Info]]) -> Anno(name='AInfos', typ=<class 'malcolm.core.info.Info'>, description='Infos about current Part status to be passed to other parts')[source]

Check that all parts return Info objects for storing as attributes

class malcolm.modules.scanning.hooks.PostConfigureHook(part: Anno(name='APart', typ=<class 'malcolm.core.part.Part'>, description='The part that has attached to the Hook'), context: Anno(name='AContext', typ=<class 'malcolm.core.context.Context'>, description='Context that should be used to perform operations on child blocks'), part_info: Anno(name='APartInfo', typ=(<class 'str'>, annotypes._array.Array[malcolm.core.info.Info]), description='The Infos returned from other Parts'))[source]

Called at the end of configure() to store configuration info calculated in the Configure hook

Parameters
  • part (Part) – The part that has attached to the Hook

  • context (Context) – Context that should be used to perform operations on child blocks

  • part_info – The Infos returned from other Parts

class malcolm.modules.scanning.hooks.PreRunHook(part: Anno(name='APart', typ=<class 'malcolm.core.part.Part'>, description='The part that has attached to the Hook'), context: Anno(name='AContext', typ=<class 'malcolm.core.context.Context'>, description='Context that should be used to perform operations on child blocks'), **kwargs: Any)[source]

Called at the start of run()

Parameters
  • part (Part) – The part that has attached to the Hook

  • context (Context) – Context that should be used to perform operations on child blocks

class malcolm.modules.scanning.hooks.RunHook(part: Anno(name='APart', typ=<class 'malcolm.core.part.Part'>, description='The part that has attached to the Hook'), context: Anno(name='AContext', typ=<class 'malcolm.core.context.Context'>, description='Context that should be used to perform operations on child blocks'), **kwargs: Any)[source]

Called at run() to start the configured steps running

Parameters
  • part (Part) – The part that has attached to the Hook

  • context (Context) – Context that should be used to perform operations on child blocks

class malcolm.modules.scanning.hooks.PostRunArmedHook(part: Anno(name='APart', typ=<class 'malcolm.core.part.Part'>, description='The part that has attached to the Hook'), context: Anno(name='AContext', typ=<class 'malcolm.core.context.Context'>, description='Context that should be used to perform operations on child blocks'), completed_steps: Anno(name='ACompletedSteps', typ=<class 'int'>, description='Number of steps already completed'), steps_to_do: Anno(name='AStepsToDo', typ=<class 'int'>, description='Number of steps we should configure for'), part_info: Union[Anno(name='APartInfo', typ=(<class 'str'>, annotypes._array.Array[malcolm.core.info.Info]), description='The Infos returned from other Parts'), Mapping[str, Sequence[malcolm.core.info.Info]]], generator: Anno(name='AGenerator', typ=<class 'scanpointgenerator.core.compoundgenerator.CompoundGenerator'>, description='Generator instance providing specification for scan'), axesToMove: Anno(name='AAxesToMove', typ=<class 'str'>, description='List of axes in inner dimension of generator that should be moved'), **kwargs: Any)[source]

Called at the end of run() when there are more steps to be run

Parameters
  • part (Part) – The part that has attached to the Hook

  • context (Context) – Context that should be used to perform operations on child blocks

  • completed_steps (int) – Number of steps already completed

  • steps_to_do (int) – Number of steps we should configure for

  • part_info – The Infos returned from other Parts

  • generator (CompoundGenerator) – Generator instance providing specification for scan

  • axesToMove (str) – List of axes in inner dimension of generator that should be moved

class malcolm.modules.scanning.hooks.PostRunReadyHook(part: Anno(name='APart', typ=<class 'malcolm.core.part.Part'>, description='The part that has attached to the Hook'), context: Anno(name='AContext', typ=<class 'malcolm.core.context.Context'>, description='Context that should be used to perform operations on child blocks'), **kwargs: Any)[source]

Called at the end of run() when there are no more steps to be run

Parameters
  • part (Part) – The part that has attached to the Hook

  • context (Context) – Context that should be used to perform operations on child blocks

class malcolm.modules.scanning.hooks.PauseHook(part: Anno(name='APart', typ=<class 'malcolm.core.part.Part'>, description='The part that has attached to the Hook'), context: Anno(name='AContext', typ=<class 'malcolm.core.context.Context'>, description='Context that should be used to perform operations on child blocks'), **kwargs: Any)[source]

Called at pause() to pause the current scan before Seek is called

Parameters
  • part (Part) – The part that has attached to the Hook

  • context (Context) – Context that should be used to perform operations on child blocks

class malcolm.modules.scanning.hooks.SeekHook(part: Anno(name='APart', typ=<class 'malcolm.core.part.Part'>, description='The part that has attached to the Hook'), context: Anno(name='AContext', typ=<class 'malcolm.core.context.Context'>, description='Context that should be used to perform operations on child blocks'), completed_steps: Anno(name='ACompletedSteps', typ=<class 'int'>, description='Number of steps already completed'), steps_to_do: Anno(name='AStepsToDo', typ=<class 'int'>, description='Number of steps we should configure for'), part_info: Anno(name='APartInfo', typ=(<class 'str'>, annotypes._array.Array[malcolm.core.info.Info]), description='The Infos returned from other Parts'), generator: Anno(name='AGenerator', typ=<class 'scanpointgenerator.core.compoundgenerator.CompoundGenerator'>, description='Generator instance providing specification for scan'), axesToMove: Anno(name='AAxesToMove', typ=<class 'str'>, description='List of axes in inner dimension of generator that should be moved'), **kwargs: Any)[source]

Called at seek() or at the end of pause() to reconfigure for a different number of completed_steps

Parameters
  • part (Part) – The part that has attached to the Hook

  • context (Context) – Context that should be used to perform operations on child blocks

  • completed_steps (int) – Number of steps already completed

  • steps_to_do (int) – Number of steps we should configure for

  • part_info – The Infos returned from other Parts

  • generator (CompoundGenerator) – Generator instance providing specification for scan

  • axesToMove (str) – List of axes in inner dimension of generator that should be moved

class malcolm.modules.scanning.hooks.AbortHook(part: Anno(name='APart', typ=<class 'malcolm.core.part.Part'>, description='The part that has attached to the Hook'), context: Anno(name='AContext', typ=<class 'malcolm.core.context.Context'>, description='Context that should be used to perform operations on child blocks'), **kwargs: Any)[source]

Called at abort() to stop the current scan

Parameters
  • part (Part) – The part that has attached to the Hook

  • context (Context) – Context that should be used to perform operations on child blocks