Table of Contents

DeconvTest: simulation framework for quantifying errors and selecting optimal parameters of image deconvolution

DOI

Author: Anna Medyukhina

Affiliation: Research Group Applied Systems Biology - Head: Prof. Dr. Marc Thilo Figge
https://www.leibniz-hki.de/en/applied-systems-biology.html
HKI-Center for Systems Biology of Infection
Leibniz Institute for Natural Product Research and Infection Biology -
Hans Knöll Insitute (HKI)
Adolf-Reichwein-Straße 23, 07745 Jena, Germany


DeconvTest is a Python-based simulation framework that allows the user to quantify and compare the performance of different deconvolution methods. The framework integrates all components needed for such quantitative comparison and consists of three main modules: (1) in silico microscopy, (2) deconvolution, and (3) performance quantification.

Source code

The source code of the package can be found at https://github.com/applied-systems-biology/DeconvTest

Installation

  1. Download Fiji, make sure that the Fiji installation path does not contain spaces; note the Fiji installation path: you will have to provide it later when installing the DeconvTest packge
  2. Download the DeconvolutionLab_2.jar and Iterative_Deconvolve_3D.class and copy them to the plugins folder of Fiji
  3. Install python or python Anaconda
  4. Download the DeconvTest package, enter the package directory and install the package by running python setup.py install
  5. Provide the path to Fiji when prompted

Requirements

The software was tested with the following versions of the required packakges:

  • scikit-image 0.15.0
  • pandas 0.25.1
  • numpy 1.16.5
  • seaborn 0.9.0
  • scipy 1.3.1
  • ddt 1.2.1

License

The source code of this framework is released under the 3-clause BSD license

Simulation of microscopy experiments

Microscopic imaging of a sample involves illuminating the sample with a light source, collecting the emitted light, and discretizing the signal by recoding it in a detector, such as a CCD camera. This process can be represented as a continuous convolution of the sample with a point spread function (PSF) - the image of a point source - and subsequent discretization. Convolution of complex continuous signals is non-trivial to compute. Hence, when simulating this process on a computer, we represent the continuous convolution process by a convolution of discrete signals of high resolution (very small voxel size), while the process of discretization is simulated by the subsequent downsampling (decrease of the resolution).

To simulate the whole microscopy process, we need to model the following steps and components:

  1. Images of cells
  2. Point spread function (PSF) of the imaging system
  3. Convolution and downsampling
  4. Noise

Generating synthetic cells

Synthetic cells can be generated with the class Cell, which is initialized with the following parameters:

In [1]:
from DeconvTest import Cell
print(Cell.__init__.__doc__)
        Initializes the cell image from a given list of indices or by reading from file.

        Parameters
        ----------
        filename: str, optional
            Path used to load the cell image.
            If None or non-existent, no image will be loaded.
            Default is None.
        ind : ndarray or list, optional
            3D coordinates of all pixels of the binary mask of the cell. 
            The size of the first axis of the ndarray or the length of the list should be equal to 
             the number of dimensions in the cell image (3 for 3D image). 
            The size of the second axis of the ndarray or the length of each sublist corresponds to 
             the number of pixels belonging to the cell mask.
        position : sequence of floats, optional
            Coordinates of the cell center in a multicellular stack in pixels. 
            The length of the sequence should correspond to the number of dimensions in the cell image
             (3 for 3D image).
        input_voxel_size : scalar or sequence of scalars, optional
            Voxel size in z, y and x used to generate the cell image.
            If not None, a cell image will be generated with the give voxel size and cell parameters specified 
             in `generate_kwargs`.
            Default is None.
        generate_kwargs : key, value pairings
            Keyword arguments passed to the `self.generate` function.
        

Cell of ellipsoidal, as well as realistic shapes can be generated:

In [2]:
print(Cell.generate.__doc__)
        Generates a synthetic object image from given parameters and stores the output in the `self.image` variable.

        Parameters
        ----------
        input_voxel_size : scalar or sequence of scalars
            Voxel size in z, y and x used to generate the object image.
            If one value is provided, the voxel size is assumed to be equal along all axes.
        input_cell_kind : string, optional
            Name of the shape of the ground truth object from set of
            {ellipsoid, spiky_cell}.
            Default is 'ellipsoid'
        kwargs : key, value pairings
            Keyword arguments passed to corresponding methods to generate synthetic objects.
        

Usage examples

Example 1

Generate a spherical cell with the diameter 10 µm and voxel size 0.3 µm per px and visualize its xy, xz, and yz maximum projections:

In [3]:
cell = Cell(input_voxel_size=0.3, 
            input_cell_kind='ellipsoid', 
            size=10)  
cell.show_2d_projections()

The input_cell_kind argument can be ommited in this case, because its default value is ellipsoid:

In [4]:
cell = Cell(input_voxel_size=0.3, 
            size=10)  
cell.show_2d_projections()
Example 2

Generate a cell with ellipsoidal shape with axes 10, 7, and 7 µm and voxel size 0.3 µm per px:

In [5]:
cell = Cell(input_voxel_size=0.3, 
            size=[10, 7, 7])  
cell.show_2d_projections()

Visualize the cell in 3D using ipyvolume:

In [6]:
import ipyvolume.pylab as p3
from IPython.core.display import HTML
p3.clear()
p3.plot_isosurface(cell.image)
p3.show()
Out[6]:
IPyVolume Widget
Example 3

Generate a cell with ellipsoidal shape with axes 10, 7, and 7 µm and rotation of π/4 along the polar axis and π/2 along the azimuthal axis. Voxel size is 0.3 µm per px:

In [7]:
import numpy as np
cell = Cell(input_voxel_size=0.3, 
            size=[10, 7, 7], 
            phi=np.pi/4, 
            theta=np.pi/2)  
cell.show_2d_projections()

The cell sizes can be alternatively specified by the arguments size_x, size_y and size_z:

In [8]:
cell = Cell(input_voxel_size=0.3, 
            size_x=7, 
            size_y=7, 
            size_z=10, 
            phi=np.pi/4, 
            theta=np.pi/2)  
cell.show_2d_projections()
Example 4

Generate a spiky cell with spikiness 0.5 (i.e., 50% of cell surface covered by spikes), spike size 1 cell radius, and spike smoothness 0.05 (i.e., the size of the smoothing filter equals to 5% of cell radius); the cell has ellipsoidal shape with axes 10, 7, and 7 µm and rotation of π/4 along the polar axis and π/2 along the azimuthal axis; voxel size is 0.3 µm per px:

In [9]:
cell = Cell(input_cell_kind='spiky_cell', 
            input_voxel_size=0.3, 
            size_x=7, 
            size_y=7, 
            size_z=10, 
            phi=np.pi/4, 
            theta=np.pi/2, 
            spikiness=0.5, 
            spike_size=1, 
            spike_smoothness=0.05) 
cell.show_2d_projections()
p3.clear()
p3.plot_isosurface(cell.image)
p3.show()
Out[9]:
IPyVolume Widget

Generating multicellular samples

To generate a multicellular sample one has to specify cell parameters (e.g. size and rotation) for each cell in the sample. This is done in two steps:

  1. Cell parameters for each sample are specified as pandas.DataFrame, or as an instance of the class CellParams, where the cell parameters are generated randomly with specified mean and standard deviation.
  2. Sample images are generated with a given voxel size.

Generating parameters for a multicellular sample

In [10]:
from DeconvTest import CellParams
print(CellParams.__init__.__doc__)
        Initializes the class for CellParams and generate random cell parameters with given properties.

        Keyword arguments:
        -----------
        input_cell_kind : string, optional
            Name of the shape of the ground truth object from set of
            {ellipsoid, spiky_cell}.
            Default is 'ellipsoid'
        number_of_stacks : int, optional
            Number of stacks to generate.
            If None, parameters for single cells will be generated
            Default is None.
        number_of_cells: int, optional
            Number of cells to generate.
            Default is 1.
        coordinates : bool, optional
            If True, relative cell coordinates will be generated.
            Default is True.
        kwargs : key, value pairings
            Further keyword arguments passed to corresponding methods to generate cell parameters.
        
        

Usage examples

Example 1

Generate random cell parameters for 5 spherical cells with diameters 10 $\pm$ 2 µm:

In [11]:
params = CellParams(number_of_cells=5, 
                    size_mean_and_std=(10, 2), 
                    equal_dimensions=True)
params
Out[11]:
size_x size_y size_z phi theta z y x input_cell_kind
0 10.622235 10.622235 10.622235 0 0 0.388699 0.632136 0.835086 ellipsoid
1 12.107066 12.107066 12.107066 0 0 0.041857 0.326144 0.739110 ellipsoid
2 6.425231 6.425231 6.425231 0 0 0.649720 0.077322 0.088054 ellipsoid
3 10.372747 10.372747 10.372747 0 0 0.400604 0.004007 0.168240 ellipsoid
4 8.690967 8.690967 8.690967 0 0 0.293970 0.204721 0.982759 ellipsoid
Example 2

Generate random cell parameters for 5 spiky ellipsoidal cells with axes sizes 10 $\pm$ 2 µm, spikiness from 0.1 to 1, spike size from 0.1 to 1 and spike smoothness from 0.05 to 0.07:

In [12]:
params = CellParams(number_of_cells=5, 
                    input_cell_kind='spiky_cell',
                    size_mean_and_std=(10, 2), 
                    equal_dimensions=False, 
                    spikiness_range=(0.1, 1), 
                    spike_size_range=(0.1, 1), 
                    spike_smoothness_range=(0.05, 0.07))
params
Out[12]:
size_x size_y size_z phi theta spikiness spike_size spike_smoothness z y x input_cell_kind
0 9.559672 7.257061 8.199977 0.772193 2.343945 0.694482 0.535540 0.064830 0.315120 0.774142 0.128627 spiky_cell
1 10.642330 7.593122 13.448859 6.146339 1.786036 0.708266 0.839482 0.055717 0.850541 0.084370 0.697277 spiky_cell
2 5.333567 13.829871 9.653306 2.054071 1.876519 0.839661 0.883497 0.050711 0.258778 0.220791 0.967620 spiky_cell
3 7.237454 8.715542 13.131329 3.043581 0.247296 0.493759 0.539404 0.059861 0.143567 0.557877 0.034623 spiky_cell
4 10.629596 7.663825 11.718086 3.931058 1.331277 0.673595 0.336582 0.061777 0.060485 0.138157 0.165865 spiky_cell

Save the cell parameters into a csv file:

In [13]:
params.save('code_examples/cell_parameters.csv')

Initialize a new class for cell parameters and read in the saved cell parameter:

In [14]:
params2 = CellParams()
params2.read_from_csv('code_examples/cell_parameters.csv')
params2
Out[14]:
size_x size_y size_z phi theta spikiness spike_size spike_smoothness z y x input_cell_kind
0 9.559672 7.257061 8.199977 0.772193 2.343945 0.694482 0.535540 0.064830 0.315120 0.774142 0.128627 spiky_cell
1 10.642330 7.593122 13.448859 6.146339 1.786036 0.708266 0.839482 0.055717 0.850541 0.084370 0.697277 spiky_cell
2 5.333567 13.829871 9.653306 2.054071 1.876519 0.839661 0.883497 0.050711 0.258778 0.220791 0.967620 spiky_cell
3 7.237454 8.715542 13.131329 3.043581 0.247296 0.493759 0.539404 0.059861 0.143567 0.557877 0.034623 spiky_cell
4 10.629596 7.663825 11.718086 3.931058 1.331277 0.673595 0.336582 0.061777 0.060485 0.138157 0.165865 spiky_cell
Example 3

Specify cell parameters as a pandas.DataFrame:

In [15]:
import pandas as pd
params = pd.DataFrame({'size_x': [10, 10, 10],
                      'size_y': [9, 10, 8], 
                      'size_z': [10, 11, 10],
                      'phi': [0, np.pi/4, np.pi/2],
                      'theta': [0, 0, 0],
                      'x': [0.1, 0.8, 0.2],
                      'y': [0.5, 0.5, 0.5],
                      'z': [0.2, 0.5, 0.8],
                       'input_cell_kind': 'spiky_cell',
                      'spikiness': [0, 0, 1],
                      'spike_size': [0, 0, 1],
                      'spike_smoothness': [0.05, 0.05, 0.05]})
params
Out[15]:
size_x size_y size_z phi theta x y z input_cell_kind spikiness spike_size spike_smoothness
0 10 9 10 0.000000 0 0.1 0.5 0.2 spiky_cell 0 0 0.05
1 10 10 11 0.785398 0 0.8 0.5 0.5 spiky_cell 0 0 0.05
2 10 8 10 1.570796 0 0.2 0.5 0.8 spiky_cell 1 1 0.05

Generating a multicellular sample from cell parameters

An image with multiple cells can be generated using the class Stack, which accepts the following arguments:

In [16]:
from DeconvTest import Stack
print(Stack.__init__.__doc__)
        Initializes the Stack class.

        Parameters
        ----------
        filename: str, optional
            Path used to load the cell image.
            If None or non-existent, no image will be loaded.
            Default is None.
        input_voxel_size : scalar or sequence of scalars, optional
            Voxel size used to generate the stack.
            If None, no stack will be generated.
            Default is None.
        stack_size : sequence of scalars, optional
            Dimensions of the image stack in micrometers.
            If None, no stack will be generated.
            Default is None.
        cell_params : pandas.DataFrame or CellParams
            Dictionary of cell parameters.
            The columns should include the keyword arguments passed though `Cell.generate`.
            If None, no stack will be generated.
            Default is None.
        

Usage examples

Example 1

Generate a multicellular sample with voxel size 0.5 µm and dimensions 50 x 50 x 50 µm using the cell parameters defined in Example 3 of section 2.2.1.1:

In [17]:
stack = Stack(cell_params=params, 
              input_voxel_size=0.5, 
              stack_size=[50, 50, 50])
stack.show_2d_projections()
p3.clear()
p3.plot_isosurface(stack.image)
p3.show()
Out[17]:
IPyVolume Widget