{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Using FISSA with SIMA\n", "\n", "[SIMA](http://www.losonczylab.org/sima/) is a toolbox for motion correction and cell detection.\n", "Here we illustrate how to create a workflow which uses SIMA to detect cells and FISSA to extract decontaminated signals from those cells.\n", "\n", "**Reference:**\n", "Kaifosh, P., Zaremba, J. D., Danielson, N. B., Losonczy, A. SIMA: Python software for analysis of dynamic fluorescence imaging data. *Frontiers in neuroinformatics*, **8**(80), 2014. doi: [10.3389/fninf.2014.00080](https://doi.org/10.3389/fninf.2014.00080).\n", "\n", "Please note that SIMA only supports Python 3.6 and below." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Import packages" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# FISSA toolbox\n", "import fissa\n", "\n", "# SIMA toolbox\n", "import sima\n", "import sima.segment\n", "\n", "# File operations\n", "import glob\n", "\n", "# For plotting our results, use numpy and matplotlib\n", "import matplotlib.pyplot as plt\n", "import numpy as np" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Detecting cells with SIMA" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Setup data" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Define folder where tiffs are present\n", "tiff_folder = \"exampleData/20150529/\"\n", "\n", "# Find tiffs in folder\n", "tiffs = sorted(glob.glob(tiff_folder + \"/*.tif*\"))\n", "\n", "# define motion correction method\n", "mc_approach = sima.motion.DiscreteFourier2D()\n", "\n", "# Define SIMA dataset\n", "sequences = [sima.Sequence.create(\"TIFF\", tiff) for tiff in tiffs[:1]]\n", "try:\n", " dataset = sima.ImagingDataset(sequences, \"example.sima\")\n", "except BaseException:\n", " dataset = sima.ImagingDataset.load(\"example.sima\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Run SIMA segmentation algorithm" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "stica_approach = sima.segment.STICA(components=2)\n", "stica_approach.append(sima.segment.SparseROIsFromMasks())\n", "stica_approach.append(sima.segment.SmoothROIBoundaries())\n", "stica_approach.append(sima.segment.MergeOverlapping(threshold=0.5))\n", "rois = dataset.segment(stica_approach, \"auto_ROIs\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Plot detected cells" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Plotting lines surrounding each of the ROIs\n", "plt.figure(figsize=(7, 6))\n", "\n", "for roi in rois:\n", " # Plot border around cell\n", " plt.plot(roi.coords[0][:, 0], roi.coords[0][:, 1])\n", "\n", "# Invert the y-axis because image co-ordinates are labelled from top-left\n", "plt.gca().invert_yaxis()\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Extract decontaminated signals with FISSA\n", "\n", "FISSA needs either ImageJ ROIs or numpy arrays as inputs for the ROIs. \n", "\n", "SIMA outputs ROIs as numpy arrays, and can be directly read into FISSA.\n", "\n", "A given roi is given as\n", "```python\n", "rois[i].coords[0][:, :2]\n", "```\n", "\n", "FISSA expects rois to be provided as a list of lists\n", "```python\n", "[[roiA1, roiA2, roiA3, ...]]\n", "```\n", "So some formatting will need to be done first." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "rois_fissa = [roi.coords[0][:, :2] for roi in rois]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "rois[0].coords[0][:, :2].shape" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can then run FISSA on the data using the ROIs supplied by SIMA having converted them to a FISSA-compatible format, `rois_fissa`." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "output_folder = \"fissa_sima_example\"\n", "experiment = fissa.Experiment(tiff_folder, [rois_fissa], output_folder)\n", "experiment.separate()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Plotting the results" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Fetch the colormap object for Cynthia Brewer's Paired color scheme\n", "cmap = plt.get_cmap(\"Paired\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Select which trial (TIFF index) to plot\n", "trial = 0\n", "\n", "# Plot the mean image and ROIs from the FISSA experiment\n", "plt.figure(figsize=(7, 7))\n", "plt.imshow(experiment.means[trial], cmap=\"gray\")\n", "\n", "for i_roi in range(len(experiment.roi_polys)):\n", " # Plot border around ROI\n", " for contour in experiment.roi_polys[i_roi, trial][0]:\n", " plt.plot(\n", " contour[:, 1],\n", " contour[:, 0],\n", " color=cmap((i_roi * 2 + 1) % cmap.N),\n", " )\n", "\n", "plt.show()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Plot all ROIs and trials\n", "\n", "# Get the number of ROIs and trials\n", "n_roi = experiment.result.shape[0]\n", "n_trial = experiment.result.shape[1]\n", "\n", "# Find the maximum signal intensities for each ROI\n", "roi_max_raw = [\n", " np.max([np.max(experiment.raw[i_roi, i_trial][0]) for i_trial in range(n_trial)])\n", " for i_roi in range(n_roi)\n", "]\n", "roi_max_result = [\n", " np.max([np.max(experiment.result[i_roi, i_trial][0]) for i_trial in range(n_trial)])\n", " for i_roi in range(n_roi)\n", "]\n", "roi_max = np.maximum(roi_max_raw, roi_max_result)\n", "\n", "# Plot our figure using subplot panels\n", "plt.figure(figsize=(16, 10))\n", "for i_roi in range(n_roi):\n", " for i_trial in range(n_trial):\n", " # Make subplot axes\n", " i_subplot = 1 + i_trial * n_roi + i_roi\n", " plt.subplot(n_trial, n_roi, i_subplot)\n", " # Plot the data\n", " plt.plot(\n", " experiment.raw[i_roi][i_trial][0, :],\n", " label=\"Raw (SIMA)\",\n", " color=cmap((i_roi * 2) % cmap.N),\n", " )\n", " plt.plot(\n", " experiment.result[i_roi][i_trial][0, :],\n", " label=\"FISSA\",\n", " color=cmap((i_roi * 2 + 1) % cmap.N),\n", " )\n", " # Labels and boiler plate\n", " plt.ylim([-0.05 * roi_max[i_roi], roi_max[i_roi] * 1.05])\n", " if i_roi == 0:\n", " plt.ylabel(\n", " \"Trial {}\\n\\nSignal intensity\\n(candela per unit area)\".format(\n", " i_trial + 1\n", " )\n", " )\n", " if i_trial == 0:\n", " plt.legend()\n", " plt.title(\"ROI {}\".format(i_roi))\n", " if i_trial == n_trial - 1:\n", " plt.xlabel(\"Time (frame number)\")\n", "\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The figure shows the raw signal from the ROI identified by SIMA (pale), and after decontaminating with FISSA (dark).\n", "The hues match the ROI locations drawn above.\n", "Each column shows the results from one of the ROIs detected by SIMA.\n", "Each row shows the results from one of the three trials." ] } ], "metadata": { "kernelspec": { "display_name": "Python", "language": "python", "name": "python" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython", "version": "3.8.2" } }, "nbformat": 4, "nbformat_minor": 1 }