The ImgProcessor Class

The ImgProcessor is the key class that controls the flow of image processing in MOSAICpy. Each processor accepts a numpy array (the data) along with the metadata object, does something with the data and/or metadata, then passes them both on to the next processor. MOSAICpy takes care of converting all ImgProcessor s into a graphical interface in the MOSAICpy GUI, by introspecting the __init__() signature for parameter names, types, and default values.

All ImgProcessor subclasses should override the process() method.

A very simple (albeit useless) ImgProcessor might look something like this.

from mosaicpy import ImgProcessor

class Plugin(ImgProcessor):
    """ This Processor simply prints the shape of the
    data to the console."""

    def process(data, meta):
        print(f"The shape of this data is {data.shape}")
        return data, meta

ImgProcessor options:

  • verbose_name - Provide a verbose_name class attribute to change how the name of the processor appears in the GUI. Otherwise, the name of the class will be used in the GUI with CamelCaseWord split into Camel Case Word
  • processing_verb - Provide a processing_verb class attribute to change the message shown in the status bar during processing.
  • gui_layout - To override the way the widgets are laid out in the GUI, override the gui_layout class attribute, providing a dict of {'parameter': (row, column)} key-value pairs, where parameter matches one of the arguments in the __init__() method.
  • valid_range - To restrict the acceptable range of numeric parameters, override the valid_range class attribute, providing a dict of {'parameter': (min, max)} key-value pairs, where parameter matches one of the arguments in the __init__() method, the tuple contains the min and max valid values accepted by that parameter.
  • hint - To provide a brief help string in the GUI, add a class attribute hint.
  • verbose_help - To provide more extensive documentation, provide a verbose_help class attribute with a string value (can be a multiline string). If provided, a help button will appear at the top right of the widget, which, when clicked, will show a popup with the contents of verbose_help

As an example, here is an ImgProcessor as rendered in the GUI, and the corresponding python class

../_images/medianfilter.png
from mosaicpy.camera import selectiveMedianFilter
from mosaicpy import ImgProcessor

class SelectiveMedianProcessor(ImgProcessor):
    """Correct noisy pixels on sCMOS camera."""

    # `verbose_name` changes the name as it appears in the gui
    verbose_name = 'Selective Median Filter'

    # `processing_verb` changes the feedback string during processing
    processing_verb = 'Performing Median Filter'

    # to override the way the widgets are laid out, provide a dict to
    # `gui_layout`, where the keys are the names of parameters in the
    # __init__ function, and the values are 2-tuples of (row, column)
    # where you want that widget to appear
    gui_layout = {
        'background': (0, 1),
        'median_range': (0, 0),
        'with_mean': (0, 2),
    }

    # to limit the possible values for numerical inputs, provide
    # `valid_range` with a dict of parameter name keys and two-tuples
    # of (min, max) valid values.
    valid_range = {
        'background': (0, 1000),
        'median_range': (1, 9),
    }

    hint = "Selective median filter as in Amat 2015"

    def __init__(self, background=0, median_range=3, with_mean=True):
        """The gui generates the appropriate widget value type by
        introspecting the default values in the function signature.
        The __init__ method should not perform any actual processing.
        """
        super(SelectiveMedianProcessor, self).__init__()
        self.background = background
        self.median_range = median_range
        self.with_mean = with_mean

    def process(self, data, meta):
        """perform the actual processing"""
        nc = len(meta.get('c'))
        ny, nx = data.shape[-2:]
        if nc > 1:
            data = data.reshape(-1, ny, nx)
        data, _ = selectiveMedianFilter(
            data,
            self.background,
            self.median_range,
            self.with_mean
        )
        if nc > 1:
            data = data.reshape(nc, -1, ny, nx)
        return data, meta

How ImgProcessors are registered in the GUI

  • The main ImpListContainer instance creates an instance of ImpListWidget
  • The ImpListWidget maintains a list of active ImgProcessor s.
  • For each active ImgProcessor, an ImpFrame is instantiated.
  • The ImpFrame class builds a simple GUI from the ImgProcessor __init__() method signature.

ImgProcessors may be added to the list by clicking the “Add Processor” button. This opens an ImgProcessSelector window which imports all files in the plugins folder whose filename ends in .py. It then inspects the module for subclasses of ImgProcessor. Only subclasses that declare a process() method will be imported. The user can then select one or more processors to be added to the main window.

../_images/implist.png

Built in ImgProcessors

class mosaicpy.imgprocessors.imgprocessors.ImgProcessor

Image Processor abstract class.

All subclasses of ImgProcessor must override the process() method, which should accept a single numpy array and return a single processed array. channel_specific class attributes specify which of the parameters must be specified for each channel in the dataset

exception ImgProcessorError

generic ImgProcessor Exception Class

exception ImgProcessorInvalid

Error for when the ImgProcessor has been improperly written

classmethod from_llsdir(llsdir=None, **kwargs)

instantiate the class based on data from an llsdir object.

All ImgProcessors should be able to be completely instanstiated by calling ImgProcessor.from_llsdir(llsdir, **options), where options are any of the additional parameters required for instantiation that are not secific to the dataset. All other ImgProcessor parameters should have a default value with the same dtype of the eventual value. Validation of empty default values should be performed in __init__.

classmethod name()

look for attribute called verbose_name, otherwise return class name

process(data, meta)

All child classes must override this method.

Parameters:
  • data (np.ndarray) – Volume of data to be processed. should be able to handle data of arbitrary dimensions, data should be an info array that has an “axes” attribute, declaring the order of axes (usually CZYX).
  • meta (dict) –

    Information about the data. This dict is initialized by the ProcessPlan instance that executes the image processor, but can be modified during processing by each ImgProcessor in the chain. The API is still in flux, but current values will be:

    • axes (str): name of axes for each dimension
    • t (int, list): timepoint(s) in the current data volume
    • c (list): channel(s) in the current data volume
    • w (list): wavelength(s) in the current data, where len(w) == len(c)
    • params (dict): full llsdir.params dict
    • has_background (bool): whether background has been subbed
Returns:

(processed data, modified meta

Return type:

tuple

classmethod verb()

look for attribute called verbose_name, otherwise return class name

class mosaicpy.imgprocessors.imgprocessors.ImgWriter