Applet API

Workflow Concepts

A Workflow combines a set of applets together to form an entire computational pipeline, along with the GUI to configure it. A workflow is created when the user loads a project, and destroyed when the project is closed.

The workflow has three main responsibilities:

  • Instantiate a set of applets, and expose them as a list for the ilastik shell to display.
  • Build up a complete computational pipeline, one image lane at a time. This is done by connecting an individual image lane from each applet’s Top-Level Operator. (More on that in a bit.)
  • Select a particular slot to serve as the “image name slot” for the shell. The shell uses this slot as the “master list” of all image lanes present in the workflow at any time.

Image Lanes

Note

This section explains how multi-image support is implemented in ilastik. Most beginning developers don’t need to sweat the details here. Simple workflows can be designed with the assumption that only one image lane will be active. The StandardApplet base class handles multi-image support for you.

Workflows in ilastik are designed to work with an arbitrary number of input images. In the ilastik Applet/Workflow API, each image is said to occupy an image lane of the workflow. In the ilastik shell GUI, the user can view the results of only one lane at a time. He selects which lane to view using the shell’s “Current View” dropdown menu.

When the user adds a new input image to the workflow, the workflow creates a new image lane in each applet to process it. This is done by calling addLane on every applet’s topLevelOperator, and then calling connectLane to connect together the lanes from each applet. See MultiLaneOperatorABC for more details.

Many applet GUIs can be written without regard to the fact that the applet’s top-level operator handles multiple image lanes at once. In fact, most applet GUIs are written to handle only a single lane of the applet’s top-level operator. Instead of manipulating the top-level operator directly, most GUIs manipulate a view of the top-level operator for a particular image lane.

For example, consider this top-level operator diagram (the Workflow Design page explains how to interpret operator diagrams).

Deviation-From-Mean Top-Level Operator

If the Applet GUI is only interested in dealing with a single image (say, the second one), it can be written to use a view. In that case, the GUI is provided with an object that looks like this:

Deviation-From-Mean Top-Level Operator (View)

Notice that the view object has no multi-slots. As far as the GUI is concerned, there is only one image lane. (The dotted lines are just shown for comparison with the previous diagram. Click on the diagram and zoom in for better rendering.)

The Workflow Base Class

class ilastik.workflow.Workflow(shell, headless=False, workflow_cmdline_args=(), project_creation_args=(), parent=None, graph=None)[source]

Base class for all workflows.

__init__(shell, headless=False, workflow_cmdline_args=(), project_creation_args=(), parent=None, graph=None)[source]

Constructor. Subclasses MUST call this in their own __init__ functions. The parent and graph parameters will be passed directly to the Operator base class. If both are None, a new Graph is instantiated internally.

Parameters:
  • headless – Set to True if this workflow is being instantiated by a “headless” script, in which case the workflow should not attempt to access applet GUIs.
  • workflow_cmdline_args – a (possibly empty) sequence of arguments to control the workflow from the command line
  • project_creation_args – The original workflow_cmdline_args used when the project was first created.
  • parent – The parent operator of the workflow or None (see also: Operator)
  • graph – The graph instance the workflow is assigned to (see also: Operator)
applets

Abstract property. Return the list of applets that are owned by this workflow.

imageNameListSlot

Abstract property. Return the “image name list” slot, which lists the names of all image lanes (i.e. files) currently loaded by the workflow. This slot is typically provided by the DataSelection applet via its ImageName slot.

connectLane(laneIndex)[source]

When a new image lane has been added to the workflow, this workflow base class does the following:

  1. Create room for the new image lane by adding a lane to each applet’s topLevelOperator
  2. Ask the subclass to hook up the new image lane by calling this function.
prepareForNewLane(laneIndex)[source]

Workflows may override this method to prepare for a new lane, before the new lane is actually inserted.

For example they may copy cache states that will be invalidated by the insertion of the new lane, and restore those caches at the end of connectLane().

handleNewLanesAdded()[source]

Called immediately after a new lane is fully initialized with data. If a workflow wants to restore state previously saved in prepareForNewLane(), this is the place to do it.

This function must be called by any code that can add new lanes to the workflow and initialize them. That happens in only two places: The DataSelectionGui, and the BatchProcessingApplet.

onProjectLoaded(projectManager)[source]

Called by the project manager after the project is loaded (deserialized). Extra workflow initialization be done here.

handleAppletStateUpdateRequested()[source]

Called when an applet has fired the Applet.statusUpdateSignal Workflow subclasses should reimplement this method to enable/disable applet gui’s

cleanUp()[source]

The user closed the project, so this workflow is being destroyed. Tell the applet GUIs to stop processing data, and free any resources that are owned by this workflow or its applets.

menus()[source]

Returns an iterable of QMenus to be added to the GUI

Returns:
iterable: QMenus to be added to the GUI

Applets

Applet classes do not have much functionality, but instead serve as a container for the main components of an applet:

  • Top-level Operator
  • GUI
  • Serializer(s)

Applets must inherit from the Applet abstract base class. Subclasses should override the appropriate properties. The base class provides a few signals, which applets can use to communicate with the shell.

Applet Base Class

class ilastik.applets.base.applet.Applet(name, syncWithImageIndex=True, interactive=True)[source]

Base class for all applets. The shell and workflow depend on this interface only. Applets can subclass from this class directly, but in most cases it is easier to subclass StandardApplet.

__init__(name, syncWithImageIndex=True, interactive=True)[source]

Constructor. Subclasses must call this base implementation in their own __init__ methods. If they fail to do so, the shell raises an exception.

Parameters:
  • name – The applet’s name, which will appear as the applet drawer title.
  • syncWithImageIndex – If True, the shell/workflow will add an image lane to this applet for each image in the interactive workflow.
progressSignal = None

Progress signal. When the applet is doing something time-consuming, this signal tells the shell to show a progress bar. Signature: emit(percentComplete, canceled=false)

Note

To update the progress bar correctly, the shell expects that progress updates always begin with at least one zero update and end with at least one 100 update. That is: self.progressSignal.emit(0) ... more updates ... self.progressSignal.emit(100)

shellRequestSignal = None

Shell request signal is used to trigger certain shell actions. Signature: emit(request)

where request is an integer corresponding to the action the shell should take.

The allowable actions are enumerated in the ShellRequest class. Example invocation: self.shellRequest.emit(ShellRequest.RequestSave)

appletStateUpdateRequested = None
This signal informs the workflow that something has changed that might
affect the usability of various applets in the workflow.

Signature: emit()

sendMessageToServer = None

This signal tells the shell to send the dict ‘data’ to the (TCP) server ‘name’ (if connected) Signature: emit(servername, data)

topLevelOperator

Abstract property. The applet’s Top Level Operator, which is a single operator for all computation performed by the applet. Each applet has exactly one top-level operator for performing computations. Workflow managers can connect the top-level operator of one applet to others.

getMultiLaneGui()[source]

Abstract method. Provides the applet’s GUI, which must be an instance of AppletGuiInterface.

dataSerializers

A list of dataSerializer objects for loading/saving any project data the applet is responsible for. Each serializer must be an instance of AppletSerializer Subclasses should override this property. By default, returns [].

class ilastik.applets.base.applet.ShellRequest[source]

This class enumerates the actions that applets can ask the shell to perform via Applet.shellRequestSignal. At the moment, there is only one supported action.

RequestSave = 0

Request that the shell perform a “save project” action.

StandardApplet Base Class

class ilastik.applets.base.standardApplet.StandardApplet(name, workflow=None, interactive=True, *args, **kwargs)[source]

In most cases, it is easiest to use StandardApplet as a base class for your custom applet. StandardApplets are designed to simplify two tasks for most use-cases: Creating a top-level operator and creating a GUI.

StandardApplet subclasses may expose their top-level operator in one of two ways:

  1. (Advanced) Override the Applet.topLevelOperator property directly.
  2. (Simple) Override BOTH singleLaneOperatorClass and broadcastingSlots, in which case a default implementation of topLevelOperator is provided for you.

StandardApplet subclasses may expose their GUI in one of three ways:

  1. (Advanced) Override createMultiLaneGui().
  2. (Simpler) Override createSingleLaneGui(), in which case a default implementation of createMultiLaneGui() is provided for you.
  3. (Simplest) Override singleLaneGuiClass, in which case default implementations of createSingleLaneGui() and createMultiLaneGui() are provided for you.
__init__(name, workflow=None, interactive=True, *args, **kwargs)[source]

Constructor.

Parameters:
  • name – The applet’s name as it will appear in the GUI (e.g. the Applet Drawer title).
  • workflow – The workflow this applet belongs to (not required if the subclass provides its own topLevelOperator).
singleLaneOperatorClass

Return the operator class which handles a single image. Single-lane applets should override this property. (Multi-lane applets must override topLevelOperator directly.)

broadcastingSlots

Slots that should be connected to all image lanes are referred to as “broadcasting” slots. Single-lane applets should override this property to return a list of the broadcasting slots’ names. (Multi-lane applets must override topLevelOperator directly.)

topLevelOperator

Get the top-level (multi-image-lane) operator for the applet. This default implementation uses singleLaneOperatorClass and broadcastingSlots to generate the top-level operator. Applets that must be multi-image-lane-aware must override this property. Note that the top-level operator must adhere to the MultiLaneOperatorABC interface.

singleLaneGuiClass

Return the class that will be instantiated for each image lane the applet needs. The class constructor should accept a single parameter: a single-lane of the top-level operator.

createSingleLaneGui(imageLaneIndex)[source]

This function is called to create new instances of single-lane applet GUIs. If your applet’s single-lane GUI requires special constructor arguments, then override this method. Otherwise, this default implementation generates instances of your singleLaneGuiClass.

getMultiLaneGui()[source]

Override from Applet base class.

Top-level Operators

Everything an applet does is centered around the applet’s top-level operator. It is typically the keeper of all state associated with the applet. The top-level operators that the workflow and shell see must be capbable of handling multiple image lanes. That is, they must adhere to the MultiLaneOperatorABC. If your applet inherits from StandardApplet, then your single-lane top-level operator can be automatically adapted to the multi-lane interface.

The applet GUI and the applet serializers both make changes to the top-level operator and listen for changes made to the top-level operator. Here’s an example timeline, showing a typical sequence of interactions.

  1. The shell is launched with a blank workflow
    • All slots are connected, but none have any data
  2. The shell loads a project file
    • Calls each serializer to read settings from the project file and apply them to the appropriate slots of the top-level operator
  3. The GUI responds to the changes made to the top-level operator by updating the GUI appearance.
    • Widgets in the applet drawer for the applet are updated with the current operator slot values.
  4. The user changes a setting in the GUI, which in turn changes a slot value on the applet’s top-level operator.
    • The changes are propagated downstream from the top-level operator, possibly resulting in an update in the central widget.
    • The applet serializer also notices the change, and makes a note that the serializer is “dirty”.
  5. Step 4 is repeated as the user experiments with the workflow options.

  6. The user selects “Save Project”
    • The shell determines which serializers have work to do by calling isDirty()
    • The shell calls serializeToHdf5 on the dirty serializers, causing them to save the current state of the corresponding top-level operators to the project file.
  7. Repeat step 4 as the user experiments with more workflow options.

  8. The user attempts to close the project.
    • The shell determines if any serializers have work to do by calling isDirty(). If any declare themselves dirty, the user is asked to confirm his decision to close the project.

Applet GUIs

An applet’s GUI object is responsible for providing the widgets that the shell displays when this applet is selected by the user.

Here’s a screenshot of the ilastik-shell gui:

ilastik-shell screenshot

In the following figure, the areas of the GUI are labeled according to the terminology used in the ilastik code base:

ilastik-shell screenshot

An applet GUI is responsible for providing the widgets for each of the areas labeled above except for the “Current Image Menu”, which is created by the shell. Additionally, Applet GUIs provide any menu items that should be shown when an applet is being viewed by the user.

class ilastik.applets.base.appletGuiInterface.AppletGuiInterface(topLevelOperatorView)[source]

This is the abstract interface to which all applet GUI classes should adhere.

centralWidget()[source]

Abstract method. Return the widget that will be displayed in the main viewer area.

appletDrawer()[source]

Abstract method. Return the drawer widget for this applet.

menus()[source]

Abstract method. Return a list of QMenu widgets to be shown in the menu bar when this applet is visible.

viewerControlWidget()[source]

Abstract method. Return the widget that controls how the content of the central widget is displayed. Typically this consists of a layer list control.

setEnabled(enabled)[source]

Abstract method. Enable or disable the gui, including applet drawer, central widget, menus, and viewer controls.

setImageIndex(imageIndex)[source]

Abstract method. Called by the shell when the user has switched the input image he wants to view. The GUI should respond by updating the content of the central widget. Note: Single-image GUIs do not need to provide this function.

imageLaneAdded(laneIndex)[source]

Abstract method. Called when a new image lane has been added to the workflow, and the GUI should respond appropriately. Note: The default GUI provided by StandardApplet overrides this for you.

imageLaneRemoved(laneIndex, finalLength)[source]

Abstract method. Called when a new image lane is about to be removed from the workflow, and the GUI should respond appropriately. The GUI should clean up any resourecs it owns. Note: The default GUI provided by StandardApplet overrides this for you.

stopAndCleanUp()[source]

Abstract method. Called when the GUI is about to be destroyed. The gui should stop updating all data views and should clean up any resources it created (e.g. orphan operators).

allowLaneSelectionChange()[source]

Abstract method. Called by the shell to determine if the shell’s lane selection combobox should be displayed. Return False if your applet GUI handles switching between lanes itself (e.g. DataSelection, DataExport), or if the notion of lanes doesn’t apply to this applet (e.g. ProjectMetadata, BatchProcessing).

Applet Serializers

class ilastik.applets.base.appletSerializer.AppletSerializer(topGroupName, slots=None, operator=None)[source]

Base class for all AppletSerializers.

_serializeToHdf5(topGroup, hdf5File, projectFilePath)[source]

Child classes should override this function, if necessary.

_deserializeFromHdf5(topGroup, groupVersion, hdf5File, projectFilePath, headless=False)[source]

Child classes should override this function, if necessary.

isDirty()[source]

Returns true if the current state of this item (in memory) does not match the state of the HDF5 group on disk.

Subclasses only need override this method if ORing the flags is not enough.

shouldSerialize(hdf5File)[source]

Whether to serialize or not.

progressIncrement(group=None)[source]

Get the percentage progress for each slot.

Parameters:group – If None, all all slots are assumed to be processed. Otherwise, decides for each slot by calling slot.shouldSerialize(group).
serializeToHdf5(hdf5File, projectFilePath)[source]

Serialize the current applet state to the given hdf5 file.

Subclasses should not override this method. Instead, subclasses override the ‘private’ version, _serializetoHdf5

Parameters:
  • hdf5File – An h5py.File handle to the project file, which should already be open
  • projectFilePath – The path to the given file handle. (Most serializers do not use this parameter.)
deserializeFromHdf5(hdf5File, projectFilePath, headless=False)[source]

Read the the current applet state from the given hdf5File handle, which should already be open.

Subclasses should not override this method. Instead, subclasses override the ‘private’ version, _deserializeFromHdf5

Parameters:
  • hdf5File – An h5py.File handle to the project file, which should already be open
  • projectFilePath – The path to the given file handle. (Most serializers do not use this parameter.)
  • headless – Are we called in headless mode? (in headless mode corrupted files cannot be fixed via the GUI)
repairFile(path, filt=None)[source]

get new path to lost file

initWithoutTopGroup(hdf5File, projectFilePath)[source]

Optional override for subclasses. Called when there is no top group to deserialize.

updateWorkingDirectory(newdir, olddir)[source]

Optional override for subclasses. Called when the working directory is changed and relative paths have to be updated. Child Classes should overwrite this method if they store relative paths.

Serializable Slots

class ilastik.applets.base.appletSerializer.SerialSlot(slot, inslot=None, name=None, subname=None, default=None, depends=None, selfdepends=True)[source]

Implements the logic for serializing a slot.

__init__(slot, inslot=None, name=None, subname=None, default=None, depends=None, selfdepends=True)[source]
Parameters:
  • slot – where to get data to save
  • inslot – where to put loaded data. If None, it is the

same as ‘slot’.

Parameters:
  • name – name used for the group in the hdf5 file.
  • subname – used for creating subgroups for multislots. should be able to call subname.format(i), where i is an integer.
  • default – DEPRECATED
  • depends – a list of slots which must be ready before this slot can be serialized. If None, defaults to [].
  • selfdepends – whether ‘slot’ should be added to ‘depends’
_serialize(group, name, slot)[source]
Parameters:
  • group (h5py.Group) – The parent group.
  • name (string) – The name of the data or group
  • slot (SerialSlot) – the slot to serialize
_deserialize(subgroup, slot)[source]
Parameters:subgroup (h5py.Group) – not the parent group. This slot’s group.
shouldSerialize(group)[source]

Whether to serialize or not.

serialize(group)[source]

Performs tasks common to all serializations, like changing dirty status.

Do not override (unless for some reason this function does not do the right thing in your case). Instead override _serialize().

Parameters:group (h5py.Group) – The parent group in which to create this slot’s group.
deserialize(group)[source]

Performs tasks common to all deserializations.

Do not override (unless for some reason this function does not do the right thing in your case). Instead override _deserialize.

Parameters:group (h5py.Group) – The parent group in which to create this slot’s group.
class ilastik.applets.base.appletSerializer.SerialListSlot(slot, inslot=None, name=None, subname=None, default=None, depends=None, selfdepends=True, transform=None, store_transform=None, iterable=<type 'list'>)[source]

As the name implies: used for serializing a list.

The only differences from the base class are:

  • if deserializing fails, sets the slot value to [].
  • if it succeeds, applies a transform to every element of the list (for instance, to convert it to the proper type).
__init__(slot, inslot=None, name=None, subname=None, default=None, depends=None, selfdepends=True, transform=None, store_transform=None, iterable=<type 'list'>)[source]
Parameters:transform – function applied to members on deserialization.
class ilastik.applets.base.appletSerializer.SerialBlockSlot(slot, inslot, blockslot, name=None, subname=None, default=None, depends=None, selfdepends=True, shrink_to_bb=False, compression_level=0)[source]

A slot which only saves nonzero blocks.

__init__(slot, inslot, blockslot, name=None, subname=None, default=None, depends=None, selfdepends=True, shrink_to_bb=False, compression_level=0)[source]
Parameters:
  • blockslot – provides non-zero blocks.
  • shrink_to_bb – If true, reduce each block of data from the slot to its nonzero bounding box before feeding saving it.
class ilastik.applets.base.appletSerializer.SerialClassifierSlot(slot, cache, inslot=None, name=None, default=None, depends=None, selfdepends=True)[source]

For saving a classifier. Here we assume the classifier is stored in the .

__init__(slot, cache, inslot=None, name=None, default=None, depends=None, selfdepends=True)[source]
_serialize(group, name, slot)[source]
_deserialize(classifierGroup, slot)[source]
deserialize(group)[source]

Have to override this to ensure that dirty is always set False.

Applet Library

Finally, the ilastik project serves as a library of applets that are useful for many workflows. In particular, the Layer Viewer applet is a base class that implements simple display of arbitrary slots from your top-level operator. It is intended to be used as a base class for almost all user-defined applets.