ScanImage often requires customization for end user needs, e.g. to coordinate imaging with stimulus, to perform on-line analysis, etc. This often can be accomplished by binding User Functions (M files written for the end user needs) to one or more ScanImage events.

Events are a relatively new concept in the Matlab language. ScanImage defines several events in its main scanImage.SI3 class – see the +scanImage folder in the ScanImage distribution. These include events like acquisitionStart, focusStart, focusAborted, etc.

User function bindings to these events can be made in the User Functions panel. Bindings can be made which are saved with either the Configuration (CFG) or the User Settings (USR) file. Bindings to the User Settings (USR) file should be made when the user function should always execute on the specified event, including for the special USR-only events, appOpen and appClose. Bindings to the Configuration (CFG) file should be made when the user function is only needed for particular acquisitions, i.e. those with a desired stimulus or other custom behavior.

User Function Signature

User functions, except when a Matlab built-in (rare), should have the following signature:

function myUserFunc(eventName, eventData, optArg1, optArg2,...)

This signature should be used even if the eventName or eventData arguments passed to the user function are not needed. These arguments are supplied by ScanImage. Optional arguments, if any, are passed starting from the third argument – these arguments are supplied by the User Functions dialog.

Using the eventName argument allows, for instance, using the same function bound to multiple events, with a different action occurring based on the particular event – this is readily implemented in the user function with a switch statement. This architecture can be used to make a fairly complex 'Plugins' (see below).

The eventData argument can contain a single value (possibly a structure of multiple values) that is specified by ScanImage at the time of the event. The value passed (if any) depends on the event. The scanimage.SI3 class contains a documentation string for each event, which provides information about any data passed with each event.

Plugins

For more complex user customization requirements, it is often needed to coordinate the response to multiple ScanImage events, while maintaining state relevant to the user customization.

In these cases, a useful approach is to write a single user function and bind it to the multiple events in the User Functions panel. We refer to this as a ScanImage plugin, illustrated here:

The function consists of a large switch statement, whose case is determined by the eventName argument. Often, initialization of figures, data acquisition channels, files, etc needed by the ScanImage customization is done in response to the appOpen event (and these can be cleaned up in response to the appClose event).

Persistent variables can be used to maintain state between the successive calls to the 'plugin' user function, i.e. between the various events the plugin responds to.

Setting up a 'plugin' requires specifying the multiple user function bindings in the User Functions panel and saving these to a Configuration file and/or a User Settings file. Saving one of each file type is typical – e.g. bindings to the appOpen and/or appClose events in the USR file and all other bindings in the CFG File.
(tick) If a binding to the appOpen event is stored to a USR file, ScanImage should be restarted, so that event will fire.

Examples of such ScanImage 'plugins' are provided in the ScanImage plugin repository, discussed next.

User Function & Plugin Repository

The ScanImage user community is diverse – each lab and even user may have custom needs. Even so, there are many common requirements, and many customization requirements can be solved using common patterns.

The User Function & Plugin Repository contains public examples of ScanImage user functions and plugins that can be reused or mimicked.

Please consider contributing your user function or plugin (mailto:iyerv@janelia.hhmi.org?subject=\[ScanImage/Ephus Plugin\]) if you develop one that may be of general interest.

Adding Custom Events

The list of events generated by ScanImage are specified directly in the scanimage.SI3 class – see the +scanimage folder in the ScanImage distribution.

The documentation for each event in this class file provides information about the event, and also specifies what, if any, eventData is passed to user functions for particular events.

If needed, end users are encouraged to simply add events to the scanImage.SI3 class file. These changes should be made to the file when ScanImage is not running and Matlab should typically be restarted following the addition. Then on subsequent ScanImage startup, the added event will appear in the User Functions dialog.

To 'fire' the event at appropriate location(s) in ScanImage code, the following syntax should be used:

state.userFcns.hEventManager.notify(eventName)
state.userFcns.hEventManager.notify(eventName,eventData)

where eventName specifies the event to 'fire', and the optional eventData argument passes value to the user functions invoked by this event.

  • No labels