napari-imagej Architecture

napari-imagej is divided into a few components, described briefly below:

The napari-imagej Widget

The napari-imagej widget provides the ability to access the ImageJ ecosystem from within napari.

Search Bar, Results Tree and Result Runner

The remaining components of the napari-imagej widget enable the user to execute ImageJ ecosystem functionality without launching the ImageJ UI.

The searchbar is used to identify ecosystem functionality through keywords; napari-imagej will populate the results tree with routines matching the keywords provided in the search bar.

When the user selects a routine in the results tree, the result runner at the bottom of the widget will provide a set of actions pertaining to the selection. These actions might include:

  • Executing the routine (either through a new window widget, shown below, or through a modal dialog)

  • Viewing the routine source code

  • Viewing the routine’s wiki page

The usage of these components is shown below:

Headless ImageJ ecosystem routines are executable directly from the napari interface by typing search terms into the napari-imagej search bar. A napari widget for executing a routine can then be generated by selecting any of the corresponding results shown in the panel beneath.

Type Logic and Type Converters

To call ImageJ routines on Python data structures, we require two additional steps when calling any ImageJ routine:

  1. Before calling the routine we must convert the provided Python objects into equivalent Java objects.

  2. After calling the routine we must convert the returned Java objects into equivalent Python objects.

Without the first step, ImageJ would not understand the user’s arguments. Without the second step, napari would not understand the routine’s outputs.

napari-imagej implements both of these steps transparently as shown below, through the use of a type conversion layer. User inputs from Module widgets are converted to Java equivalents before the ImageJ routine is called. Routine outputs are converted to Python equivalents before those outputs are provided back to the user.

To convert inputs, the data conversion layer maintains a list of conversion functions \(\{P_i:p_i\rightarrow j_i\}\) used to convert objects of Python type \(p_i\) into objects of Java type \(j_i\). As an example, one such function might convert napari Image layers into imglib2 Imgs.

To convert outputs, the layer maintains a similar set of conversion functions \(\{J_i:j_i\rightarrow p_i\}\) used to convert objects of java type \(j_i\) into Python type \(p_i\). For example, one such function might convert imglib2 Imgs into napari Image layers.

napari-imagej will only allow ImageJ routines to be called if it can map each Python input to some function \(P_i\), and each Java output to some function \(J_i\). When those routines are called, the following steps occur:

  1. Each input is passed to its corresponding input converter \(P_i\)

  2. The ImageJ routine is called on the returns of the inputs converters

  3. Each routine output is passed to its corresponding output converter \(J_i\)

  4. The returns of the output converters are provided back to the user

The backing PyImageJ instance

Without access to a backing ImageJ2 instance, napari-imagej could not execute ImageJ ecosystem functionality. The PyImageJ, able to provide ImageJ2 access in Python, is napari-imagej’s gateway to this functionality.

By using the settings button in the napari-imagej menu, this backing instance can be configured to enable ImageJ, ImageJ2, Fiji, and third-party functionality. Please see the configuration documentation for more information.