From 606feaac806d50783fa2e45e8a14bed31af61e99 Mon Sep 17 00:00:00 2001 From: Caitlin Lewis Date: Wed, 14 Sep 2022 13:56:56 -0400 Subject: [PATCH 1/4] redo of architecture, functioning cnmf and mcorr specific viewer...still need to make changes to cnmf viewer tabs --- examples/cnmf.ipynb | 241 +++++++++++++++++++ examples/mcorr.ipynb | 186 +++++++++++--- examples/old-viewer.ipynb | 148 ++++++++++++ mesmerize_viz/__init__.py | 2 +- mesmerize_viz/baseviewer.py | 151 ++++++++++++ mesmerize_viz/cnmfviewer.py | 165 +++++++++++++ mesmerize_viz/dataframeviewer.py | 20 ++ mesmerize_viz/{widgets.py => mcorrviewer.py} | 133 +--------- mesmerize_viz/selectviewer.py | 43 ++++ 9 files changed, 937 insertions(+), 152 deletions(-) create mode 100644 examples/cnmf.ipynb create mode 100644 examples/old-viewer.ipynb create mode 100644 mesmerize_viz/baseviewer.py create mode 100644 mesmerize_viz/cnmfviewer.py create mode 100644 mesmerize_viz/dataframeviewer.py rename mesmerize_viz/{widgets.py => mcorrviewer.py} (55%) create mode 100644 mesmerize_viz/selectviewer.py diff --git a/examples/cnmf.ipynb b/examples/cnmf.ipynb new file mode 100644 index 0000000..7ce04d4 --- /dev/null +++ b/examples/cnmf.ipynb @@ -0,0 +1,241 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "71858ecf-3017-460a-9f43-af29bc1dcaee", + "metadata": {}, + "outputs": [], + "source": [ + "# looking at cnmf viewer" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "930993e4-860f-48d6-81e0-884c602ff70f", + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "0ec8ddf3-533a-4941-a4d3-89d351473d46", + "metadata": {}, + "outputs": [], + "source": [ + "from mesmerize_viz.dataframeviewer import DataframeViewer\n", + "from mesmerize_viz.cnmfviewer import CNMFViewer\n", + "from mesmerize_viz.selectviewer import SelectViewer\n", + "from mesmerize_core import load_batch, set_parent_raw_data_path" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "28d12052-5afb-4958-8074-d184b20d7d85", + "metadata": {}, + "outputs": [], + "source": [ + "set_parent_raw_data_path(\"/data/wasabi-remote/hantmanlab/from_tier2/Teena/Experiments/Mesoscale/Opto_inter_region/\")\n", + "\n", + "df2 = load_batch(\"/data/wasabi-remote/hantmanlab/from_tier2/Teena/Experiments/Mesoscale/Opto_inter_region/mesmerize_batch/batch.pickle\")" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "912e73d2-4c78-4ea4-866e-4e24db6c7f44", + "metadata": {}, + "outputs": [], + "source": [ + "df = df2.loc[df2[\"algo\"] == \"cnmf\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "dc991487-8fab-4f89-9fef-13b9d3e80b7d", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
indexalgonameinput_movie_pathparamsoutputsuuidanimal_idsession_idtrial_df_pathexp-group
059cnmfoit4-080721-ap1_1_pt_5a9e7acfd3-e7e5-4c3a-a96d-2e1b586c0b58/9e7acfd3-...{'main': {'p': 2, 'nb': 1, 'rf': 60, 'stride':...{'mean-projection-path': faa06614-a582-43ff-b4...faa06614-a582-43ff-b4d3-16014dcc4fc4NaNNaNNaNopto
\n", + "
" + ], + "text/plain": [ + " index algo name \\\n", + "0 59 cnmf oit4-080721-ap1_1_pt_5a \n", + "\n", + " input_movie_path \\\n", + "0 9e7acfd3-e7e5-4c3a-a96d-2e1b586c0b58/9e7acfd3-... \n", + "\n", + " params \\\n", + "0 {'main': {'p': 2, 'nb': 1, 'rf': 60, 'stride':... \n", + "\n", + " outputs \\\n", + "0 {'mean-projection-path': faa06614-a582-43ff-b4... \n", + "\n", + " uuid animal_id session_id trial_df_path \\\n", + "0 faa06614-a582-43ff-b4d3-16014dcc4fc4 NaN NaN NaN \n", + "\n", + " exp-group \n", + "0 opto " + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df = df.reset_index()\n", + "df = df.drop(df.index[1:33])\n", + "df" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "2670fc40-5229-4dc9-b13d-d49c8474581c", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "368ac1c297da43ff8bea2a19e0476275", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "RFBOutputContext()" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/clewis7/repos/mesmerize-viz/mesmerize_viz/cnmfviewer.py:85: FutureWarning: You are trying to use the following experimental feature, this maybe change in the future without warning:\n", + "CaimanSeriesExtensions.get_input_movie\n", + "\n", + "\n", + " input=r.caiman.get_input_movie(),\n" + ] + } + ], + "source": [ + "cv = CNMFViewer(dataframe=df)\n", + "sv = SelectViewer(cv, grid_shape=(2,3))\n", + "dfv = DataframeViewer(cv, sv)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "518d2c7a-1767-4cd7-92d4-4db5d1f3cf8f", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "c6640bb164524f91b53f541a6c42cee6", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Tab(children=(VBox(children=(HBox(children=(Select(layout=Layout(height='200px'), options=('0: 🟢 oit4-080721-a…" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "dfv.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "050a0b5b-9915-4fe4-af8b-9bb9abd8cecb", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.2" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/mcorr.ipynb b/examples/mcorr.ipynb index 5866fde..0b86df7 100644 --- a/examples/mcorr.ipynb +++ b/examples/mcorr.ipynb @@ -3,7 +3,17 @@ { "cell_type": "code", "execution_count": 1, - "id": "3fda66e1-0973-4fba-bac4-31a44c8cbfa2", + "id": "b700ff69-2091-4e3f-aa72-8be5955312a0", + "metadata": {}, + "outputs": [], + "source": [ + "# demo using reformatted mes viz" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "43623668-2f0f-4307-b095-59860e628385", "metadata": {}, "outputs": [], "source": [ @@ -13,27 +23,20 @@ { "cell_type": "code", "execution_count": 2, - "id": "e4d01194-8f05-4221-821f-3550e7e039f7", + "id": "4f0233d8-8e67-48fe-a68e-8723376ebf76", "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "2022-06-27 02:08:57.611655: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcudart.so.11.0'; dlerror: libcudart.so.11.0: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /home/kushal/python-venvs/mescore/lib/python3.10/site-packages/cv2/../../lib64:\n", - "2022-06-27 02:08:57.611679: I tensorflow/stream_executor/cuda/cudart_stub.cc:29] Ignore above cudart dlerror if you do not have a GPU set up on your machine.\n" - ] - } - ], + "outputs": [], "source": [ - "from mesmerize_viz.widgets import MCorrViewer\n", + "from mesmerize_viz.dataframeviewer import DataframeViewer\n", + "from mesmerize_viz.mcorrviewer import MCorrViewer\n", + "from mesmerize_viz.selectviewer import SelectViewer\n", "from mesmerize_core import load_batch, set_parent_raw_data_path" ] }, { "cell_type": "code", "execution_count": 3, - "id": "1225545f-9056-435e-bfef-53ff98376c8e", + "id": "3058df65-c5df-4cac-ae6c-4cc2c21003a2", "metadata": {}, "outputs": [], "source": [ @@ -47,13 +50,13 @@ { "cell_type": "code", "execution_count": 4, - "id": "4fba5bc7-4d33-4a75-8770-e370e726fb1f", + "id": "5fe3f7aa-6113-4767-9642-3d7a3b0a69c5", "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "3d3568e9d449496e8f7a07b49d54b2d0", + "model_id": "36e5c4943c6d40f199924acb2d1747bc", "version_major": 2, "version_minor": 0 }, @@ -68,33 +71,35 @@ "name": "stderr", "output_type": "stream", "text": [ - "/home/kushal/Insync/kushalkolar@gmail.com/drive/repos/mesmerize-viz/mesmerize_viz/widgets.py:133: FutureWarning: You are trying to use the following experimental feature, this maybe change in the future without warning:\n", + "/home/clewis7/repos/mesmerize-viz/mesmerize_viz/mcorrviewer.py:88: FutureWarning: You are trying to use the following experimental feature, this maybe change in the future without warning:\n", "CaimanSeriesExtensions.get_input_movie\n", "\n", - "None\n", - " input=r.caiman.get_input_movie(),\n" + "\n", + " input=r.caiman.get_input_movie(\"append-tiff\"),\n" ] } ], "source": [ - "mv = MCorrViewer(dataframe=df)" + "mv = MCorrViewer(dataframe=df)\n", + "sv = SelectViewer(mv, grid_shape=(2,3))\n", + "dfv = DataframeViewer(mv, sv)" ] }, { "cell_type": "code", "execution_count": 5, - "id": "299b1a9c-c66a-4f41-8b52-77395265317a", + "id": "4c1e7344-1c22-4a8c-816e-5a00098e75d2", "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "abeef40312014c0895d8521890450edd", + "model_id": "7b8eff8b0d6f41c1a43a09b0937cf95b", "version_major": 2, "version_minor": 0 }, "text/plain": [ - "VBox(children=(HBox(children=(Select(layout=Layout(height='200px'), options=('🟢 my_movie', '🟢 my_movie'), valu…" + "Tab(children=(VBox(children=(HBox(children=(Select(layout=Layout(height='200px'), options=('0: 🟢 my_movie', '1…" ] }, "metadata": {}, @@ -102,23 +107,146 @@ } ], "source": [ - "mv.show()" + "dfv.show()" ] }, { "cell_type": "code", - "execution_count": 7, - "id": "eac8c4b3-3abe-4a81-bf88-76162b3c65db", + "execution_count": 9, + "id": "a61777f9-f66f-49db-837a-52fca826d6b6", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "mv.grid_plot.subplots[0,0]" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "d4f8e507-bf61-4e39-998b-b00c2ce51bef", "metadata": {}, "outputs": [], "source": [ - "mv.grid_plot.subplots[0, 0].center_scene()" + "from fastplotlib import *" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "f918b8b2-dc15-417c-8fb1-ba207bab6885", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "mv.grid_plot.subplots[1,1]" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "164b39a9-e248-4045-a17c-8149d452fc2c", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "0368183cc053421a9155f432af4d084e", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "RFBOutputContext()" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
initial snapshot
" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "ac9c03e76b7a4872bb635cb80ea925b1", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "JupyterWgpuCanvas()" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "plot = Plot()\n", + "\n", + "img_graphic = mv.grid_plot.subplots[1,1]\n", + "\n", + "plot.add_graphic(img_graphic)\n", + "\n", + "plot.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "0891f9d2-c7c8-4149-a7bc-d660e8b3a633", + "metadata": {}, + "outputs": [ + { + "ename": "AttributeError", + "evalue": "'Image' object has no attribute 'center_scene'", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)", + "Input \u001b[0;32mIn [14]\u001b[0m, in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[43mmv\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mgrid_plot\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mshow\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m~/repos/fastplotlib/fastplotlib/layouts.py:143\u001b[0m, in \u001b[0;36mGridPlot.show\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 140\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mcanvas\u001b[38;5;241m.\u001b[39mrequest_draw(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39manimate)\n\u001b[1;32m 142\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m subplot \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m:\n\u001b[0;32m--> 143\u001b[0m \u001b[43msubplot\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcenter_scene\u001b[49m()\n\u001b[1;32m 145\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mcanvas\n", + "\u001b[0;31mAttributeError\u001b[0m: 'Image' object has no attribute 'center_scene'" + ] + } + ], + "source": [ + "mv.grid_plot.show()" ] }, { "cell_type": "code", "execution_count": null, - "id": "5afce9e0-a5ba-4a38-97dd-93c07155e2d9", + "id": "b0684e17-774f-4c9c-8b43-e7f73bdfa014", "metadata": {}, "outputs": [], "source": [] @@ -140,7 +268,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.2" + "version": "3.9.2" } }, "nbformat": 4, diff --git a/examples/old-viewer.ipynb b/examples/old-viewer.ipynb new file mode 100644 index 0000000..65ad2be --- /dev/null +++ b/examples/old-viewer.ipynb @@ -0,0 +1,148 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "3fda66e1-0973-4fba-bac4-31a44c8cbfa2", + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "e4d01194-8f05-4221-821f-3550e7e039f7", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2022-06-27 02:08:57.611655: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcudart.so.11.0'; dlerror: libcudart.so.11.0: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /home/kushal/python-venvs/mescore/lib/python3.10/site-packages/cv2/../../lib64:\n", + "2022-06-27 02:08:57.611679: I tensorflow/stream_executor/cuda/cudart_stub.cc:29] Ignore above cudart dlerror if you do not have a GPU set up on your machine.\n" + ] + } + ], + "source": [ + "from mesmerize_viz.widgets import MCorrViewer\n", + "from mesmerize_core import load_batch, set_parent_raw_data_path" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "1225545f-9056-435e-bfef-53ff98376c8e", + "metadata": {}, + "outputs": [], + "source": [ + "set_parent_raw_data_path(\"/home/kushal/caiman_data/\")\n", + "\n", + "batch_path = \"/home/kushal/caiman_data/mesmerize-core-batch/batch2.pickle\"\n", + "\n", + "df = load_batch(batch_path)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "4fba5bc7-4d33-4a75-8770-e370e726fb1f", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "3d3568e9d449496e8f7a07b49d54b2d0", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "RFBOutputContext()" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/kushal/Insync/kushalkolar@gmail.com/drive/repos/mesmerize-viz/mesmerize_viz/widgets.py:133: FutureWarning: You are trying to use the following experimental feature, this maybe change in the future without warning:\n", + "CaimanSeriesExtensions.get_input_movie\n", + "\n", + "None\n", + " input=r.caiman.get_input_movie(),\n" + ] + } + ], + "source": [ + "mv = MCorrViewer(dataframe=df)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "299b1a9c-c66a-4f41-8b52-77395265317a", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "abeef40312014c0895d8521890450edd", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "VBox(children=(HBox(children=(Select(layout=Layout(height='200px'), options=('🟢 my_movie', '🟢 my_movie'), valu…" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "mv.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "eac8c4b3-3abe-4a81-bf88-76162b3c65db", + "metadata": {}, + "outputs": [], + "source": [ + "mv.grid_plot.subplots[0, 0].center_scene()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5afce9e0-a5ba-4a38-97dd-93c07155e2d9", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.2" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/mesmerize_viz/__init__.py b/mesmerize_viz/__init__.py index 1c95366..feb9535 100644 --- a/mesmerize_viz/__init__.py +++ b/mesmerize_viz/__init__.py @@ -1 +1 @@ -from .widgets import MCorrViewer \ No newline at end of file +from .mcorrviewer import MCorrViewer \ No newline at end of file diff --git a/mesmerize_viz/baseviewer.py b/mesmerize_viz/baseviewer.py new file mode 100644 index 0000000..9da8d3a --- /dev/null +++ b/mesmerize_viz/baseviewer.py @@ -0,0 +1,151 @@ +import numpy as np +from ipywidgets import widgets, VBox, HBox, Layout +from fastplotlib import GridPlot, Image, Subplot +from typing import * +import pandas as pd +from uuid import UUID +from collections import OrderedDict +import pims +import time + + +# formats dict to yaml-ish-style +is_pos = lambda x: 1 if x > 0 else 0 +format_key = lambda d, t: "\n" * is_pos(t) + \ + "\n".join( + [": ".join(["\t" * t + k, format_key(v, t + 1)]) for k, v in d.items()] + ) if isinstance(d, dict) else str(d) + + +input_readers = [ + "pims", +] + + +blue_circle = chr(int("0x1f535",base=16)) +green_circle = chr(int("0x1f7e2",base=16)) +red_circle = chr(int("0x1f534",base=16)) + + +class _BaseViewer: + def __init__( + self, + dataframe: pd.DataFrame, + grid_plot_shape: Tuple[int, int], + grid_plot_kwargs: Optional[dict] = None, + multi_select: bool = False, + ): + self.dataframe: pd.DataFrame = dataframe + self.grid_shape: Tuple[int, int] = None + + # in case the user did something weird with indexing + self.dataframe: pd.DataFrame = dataframe.reset_index(drop=True) + + self._init_batch_list_widget(multi_select) + self.batch_list_widget.layout = Layout(height="200px") + + self.batch_list_widget.observe(self.item_selection_changed) + + self.uuid_text_widget = widgets.Text(disabled=True, tooltip="UUID of item") + self.params_text_widget = widgets.Textarea(disabled=True, tooltip="Parameters of item") + + self.outputs_text_widget = widgets.Textarea(disabled=True, tooltip="Output info of item") + + self.grid_plot: GridPlot = GridPlot(shape=grid_plot_shape, **grid_plot_kwargs) + + self.frame_slider = widgets.IntSlider(value=0, min=0, description="frame index:") + self.grid_plot.renderer.add_event_handler(self._set_frame_slider_width, "resize") + + self.frame_slider.observe(self.update_frame, "value") + + self.play_button = widgets.Play( + value=self.frame_slider.value, + min=self.frame_slider.min, + max=self.frame_slider.max, + step=1, + interval=100, + ) + + widgets.jslink( + (self.play_button, 'value'), + (self.frame_slider, 'value') + ) + + self.button_reset_view = widgets.Button(description="Reset View") + self.button_reset_view.on_click(self.reset_grid_plot_scenes) + + def _init_batch_list_widget(self, multi_select: bool): + options = list() + for ix, r in self.dataframe.iterrows(): + if r["outputs"] is None: + indicator = blue_circle + elif r["outputs"]["success"] is True: + indicator = green_circle + elif r["outputs"]["success"] is False: + indicator = red_circle + name = r["name"] + options.append(f"{ix}: {indicator} {name}") + + if multi_select: + self.batch_list_widget: widgets.SelectMultiple = widgets.SelectMultiple( + options=options, + index=0 + ) + else: + self.batch_list_widget: widgets.Select = widgets.Select( + options=options, + index=0 + ) + + def _set_frame_slider_width(self, *args): + w, h = self.grid_plot.renderer.logical_size + self.frame_slider.layout = Layout(width=f"{w}px") + + def _set_frame_slider_minmax(self, minmax: Tuple[int, int]): + self.frame_slider.min = minmax[0] + self.frame_slider.max = minmax[1] + self.play_button.min = minmax[0] + self.play_button.max = minmax[1] + + def get_selected_index(self) -> int: + return self.batch_list_widget.index + + def get_selected_item(self) -> pd.Series: + if self.get_selected_index() is None: + return False + + ix = self.get_selected_index() + r = self.dataframe.iloc[ix] + + if r["outputs"]["success"] is False: + self.outputs_text_widget.value = r["outputs"]["traceback"] + return False + + return r + + def item_selection_changed(self): + pass + + def update_frame(self, *args): + pass + + def update_graphic(self, position: Tuple[int, int], change: str): + pass + + def get_layout(self): + uuid_params_output = VBox([self.uuid_text_widget, self.params_text_widget, self.outputs_text_widget]) + + info_widgets = HBox([self.batch_list_widget, uuid_params_output]) + + return VBox([ + info_widgets, + HBox([self.button_reset_view, self.play_button]), + self.frame_slider, + self.grid_plot.show(), + ]) + + def show(self): + return self.get_layout() + + def reset_grid_plot_scenes(self, *args): + self.grid_plot.subplots[0, 0].center_scene() \ No newline at end of file diff --git a/mesmerize_viz/cnmfviewer.py b/mesmerize_viz/cnmfviewer.py new file mode 100644 index 0000000..c4de665 --- /dev/null +++ b/mesmerize_viz/cnmfviewer.py @@ -0,0 +1,165 @@ +import numpy as np +from ipywidgets import widgets, VBox, HBox, Layout +from fastplotlib import GridPlot, Image, Subplot, Line +from typing import * +import pandas as pd +from uuid import UUID +from collections import OrderedDict +import pims +import time + +from mesmerize_viz.baseviewer import _BaseViewer + +# formats dict to yaml-ish-style +is_pos = lambda x: 1 if x > 0 else 0 +format_key = lambda d, t: "\n" * is_pos(t) + \ + "\n".join( + [": ".join(["\t" * t + k, format_key(v, t + 1)]) for k, v in d.items()] + ) if isinstance(d, dict) else str(d) + + +input_readers = [ + "pims", +] + + +blue_circle = chr(int("0x1f535",base=16)) +green_circle = chr(int("0x1f7e2",base=16)) +red_circle = chr(int("0x1f534",base=16)) + + +class _CNMFContainer: + def __init__( + self, + input: Union[Subplot, np.ndarray, Image], + contours: Union[Subplot, np.ndarray, Image], + reconstructed: Union[Subplot, np.ndarray, Image], + residuals: Union[Subplot, np.ndarray, Image], + #temporal: Union[Subplot, np.ndarray, Image], + background: Union[Subplot, np.ndarray, Image] + ): + self.input = input + self.contours = contours + self.reconstructed = reconstructed + self.residuals = residuals + #self.temporal = temporal + self.background = background + + +class CNMFViewer(_BaseViewer): + def __init__( + self, + dataframe: pd.DataFrame, + ): + super(CNMFViewer, self).__init__( + dataframe, + grid_plot_shape=(2, 3), + grid_plot_kwargs={"controllers": "sync"}, + multi_select=False + ) + + self.subplots = _CNMFContainer( + input=self.grid_plot.subplots[0, 0], + contours=self.grid_plot.subplots[0, 1], + reconstructed=self.grid_plot.subplots[0, 2], + residuals=self.grid_plot.subplots[1, 0], + #temporal=self.grid_plot.subplots[1, 1], + background=self.grid_plot.subplots[1, 2] + ) + + self._imaging_data: _CNMFContainer = None + self._graphics: _CNMFContainer = None + self.ds_window = 10 + + self.item_selection_changed() + + def item_selection_changed(self, *args): + r = self.get_selected_item() + if r is False: + return + + for subplot in self.grid_plot: + subplot.scene.clear() + + self._imaging_data = _CNMFContainer( + input=r.caiman.get_input_movie(), + contours=r.cnmf.get_contours()[0], + residuals=r.cnmf.get_residuals(), + reconstructed=r.cnmf.get_rcm(), + #temporal=r.cnmf.get_temporal(), + background=r.cnmf.get_rcb() + ) + + input_graphic = Image( + self._imaging_data.input[0], + cmap="gnuplot2" + ) + + self._set_frame_slider_minmax( + (0, self._imaging_data.reconstructed.shape[0]-1) + ) + + contours_graphic: List[Line] = list() + + for coor in self._imaging_data.contours: + zs = np.ones(coor.shape[0]) + coors_3d = np.dstack([coor[:,0], coor[:,1], zs])[0].astype(np.float32) + + colors = np.vstack([[1.,0.,0.,1.]]*coors_3d.shape[0]).astype(np.float32) + + contours_graphic.append(Line(data=coors_3d, colors=colors)) + + residuals_graphic = Image( + self._imaging_data.residuals[0], + cmap="gnuplot2" + ) + + reconstructed_graphic = Image( + self._imaging_data.reconstructed[0], + cmap="gnuplot2" + ) + + background_graphic = Image( + self._imaging_data.background[0], + cmap="gray" + ) + + self._graphics = _CNMFContainer( + input=input_graphic, + contours=contours_graphic, + residuals=residuals_graphic, + reconstructed=reconstructed_graphic, + # temporal, + background=background_graphic + ) + + for attr in ["input", "residuals", "reconstructed", "background"]: + subplot: Subplot = getattr(self.subplots, attr) + subplot.add_graphic(getattr(self._graphics, attr)) + + for line in contours_graphic: + self.subplots.input.add_graphic(line) + + u = str(r["uuid"]) + + self.uuid_text_widget.value = u + + self.params_text_widget.value = format_key(r["params"], 0) + self.outputs_text_widget.value = format_key(r["outputs"], 0) + + # this does work for some reason if not called from the nb itself ¯\_(ツ)_/¯ + self.reset_grid_plot_scenes() + + def update_frame(self, *args): + if self.get_selected_index() is None: + return + + ix = self.frame_slider.value + + for attr in ["input", "residuals", "reconstructed", "background"]: + graphic: Image = getattr(self._graphics, attr) + graphic.update_data(getattr(self._imaging_data, attr)[ix]) + + def _generate_grid_plot(self): + pass + diff --git a/mesmerize_viz/dataframeviewer.py b/mesmerize_viz/dataframeviewer.py new file mode 100644 index 0000000..a254b28 --- /dev/null +++ b/mesmerize_viz/dataframeviewer.py @@ -0,0 +1,20 @@ +from ipywidgets import Tab + + +class DataframeViewer: + def __init__( + self, + _BaseViewer, + SelectViewer + ): + self.base = _BaseViewer + self.select = SelectViewer + self.tab = Tab() + + self.tab.set_title(0, "Viewer") + self.tab.set_title(1, "Selector") + + self.tab.children = (self.base.get_layout(), self.select.get_layout()) + + def show(self): + return self.tab diff --git a/mesmerize_viz/widgets.py b/mesmerize_viz/mcorrviewer.py similarity index 55% rename from mesmerize_viz/widgets.py rename to mesmerize_viz/mcorrviewer.py index 2b4fb48..bf2145c 100644 --- a/mesmerize_viz/widgets.py +++ b/mesmerize_viz/mcorrviewer.py @@ -8,6 +8,7 @@ import pims import time +from mesmerize_viz.baseviewer import _BaseViewer # formats dict to yaml-ish-style is_pos = lambda x: 1 if x > 0 else 0 @@ -45,127 +46,6 @@ def __init__( self.shifts = shifts -class _BaseViewer: - def __init__( - self, - dataframe: pd.DataFrame, - grid_plot_shape: Tuple[int, int], - grid_plot_kwargs: Optional[dict] = None, - multi_select: bool = False, - ): - self.dataframe: pd.DataFrame = dataframe - self.grid_shape: Tuple[int, int] = None - - # in case the user did something weird with indexing - self.dataframe: pd.DataFrame = dataframe.reset_index(drop=True) - - self._init_batch_list_widget(multi_select) - self.batch_list_widget.layout = Layout(height="200px") - - self.batch_list_widget.observe(self.item_selection_changed) - - self.uuid_text_widget = widgets.Text(disabled=True, tooltip="UUID of item") - self.params_text_widget = widgets.Textarea(disabled=True, tooltip="Parameters of item") - - self.outputs_text_widget = widgets.Textarea(disabled=True, tooltip="Output info of item") - - self.grid_plot: GridPlot = GridPlot(shape=grid_plot_shape, **grid_plot_kwargs) - - self.frame_slider = widgets.IntSlider(value=0, min=0, description="frame index:") - self.grid_plot.renderer.add_event_handler(self._set_frame_slider_width, "resize") - - self.frame_slider.observe(self.update_frame, "value") - - self.play_button = widgets.Play( - value=self.frame_slider.value, - min=self.frame_slider.min, - max=self.frame_slider.max, - step=1, - interval=100, - ) - - widgets.jslink( - (self.play_button, 'value'), - (self.frame_slider, 'value') - ) - - self.button_reset_view = widgets.Button(description="Reset View") - self.button_reset_view.on_click(self.reset_grid_plot_scenes) - - def _init_batch_list_widget(self, multi_select: bool): - options = list() - for ix, r in self.dataframe.iterrows(): - if r["outputs"] is None: - indicator = blue_circle - elif r["outputs"]["success"] is True: - indicator = green_circle - elif r["outputs"]["success"] is False: - indicator = red_circle - name = r["name"] - options.append(f"{ix}: {indicator} {name}") - - if multi_select: - self.batch_list_widget: widgets.SelectMultiple = widgets.SelectMultiple( - options=options, - index=0 - ) - else: - self.batch_list_widget: widgets.Select = widgets.Select( - options=options, - index=0 - ) - - def _set_frame_slider_width(self, *args): - w, h = self.grid_plot.renderer.logical_size - self.frame_slider.layout = Layout(width=f"{w}px") - - def _set_frame_slider_minmax(self, minmax: Tuple[int, int]): - self.frame_slider.min = minmax[0] - self.frame_slider.max = minmax[1] - self.play_button.min = minmax[0] - self.play_button.max = minmax[1] - - def get_selected_index(self) -> int: - return self.batch_list_widget.index - - def get_selected_item(self) -> pd.Series: - if self.get_selected_index() is None: - return False - - ix = self.get_selected_index() - r = self.dataframe.iloc[ix] - - if r["outputs"]["success"] is False: - self.outputs_text_widget.value = r["outputs"]["traceback"] - return False - - return r - - def item_selection_changed(self): - pass - - def update_frame(self, *args): - pass - - def get_layout(self): - uuid_params_output = VBox([self.uuid_text_widget, self.params_text_widget, self.outputs_text_widget]) - - info_widgets = HBox([self.batch_list_widget, uuid_params_output]) - - return VBox([ - info_widgets, - HBox([self.button_reset_view, self.play_button]), - self.frame_slider, - self.grid_plot.show(), - ]) - - def show(self): - return self.get_layout() - - def reset_grid_plot_scenes(self, *args): - self.grid_plot.subplots[0, 0].center_scene() - - class MCorrViewer(_BaseViewer): def __init__( self, @@ -209,7 +89,7 @@ def item_selection_changed(self, *args): mcorr=r.mcorr.get_output(), dsavg=None, mean=r.caiman.get_projection("mean"), - corr=r.caiman.get_correlation_image(), + corr=r.caiman.get_corr_image(), shifts=None ) @@ -268,6 +148,15 @@ def item_selection_changed(self, *args): # this does work for some reason if not called from the nb itself ¯\_(ツ)_/¯ self.reset_grid_plot_scenes() + def update_graphic(self, position: Tuple[int, int], change: str): + self.grid_plot.subplots[position[0], position[1]].remove_graphic() + # new_graphic = create_graphic(change) + # self.grid_plot.subplots[position[0], position[1]].add_graphic(new_graphic) + + def create_graphic(self, graphic_type): + pass + # create a new graphic to add to subplot + def _get_dsavg(self, frame_index: int) -> np.ndarray: if self.ds_window % 2 == 1: # make sure it's even self.ds_window += 1 diff --git a/mesmerize_viz/selectviewer.py b/mesmerize_viz/selectviewer.py new file mode 100644 index 0000000..228854f --- /dev/null +++ b/mesmerize_viz/selectviewer.py @@ -0,0 +1,43 @@ +from typing import Tuple + +import numpy as np +from ipywidgets import GridspecLayout, Layout, Dropdown, VBox, HBox +from functools import partial +from itertools import product + + +class SelectViewer: + def __init__( + self, + _BaseViewer, + grid_shape: Tuple[int, int] = None, + multi_select: bool = False, + algo: str = "mcorr", + ): + self.grid_shape = grid_shape + self.table = GridspecLayout(self.grid_shape[0], self.grid_shape[1]) + self.algo = algo + self.base = _BaseViewer + self.grid_cells = np.empty(shape=self.grid_shape, dtype=object) + + self.set_grid() + + for i, j in product(range(self.grid_shape[0]), range(grid_shape[1])): + widget = self.grid_cells[i, j] + widget.observe(partial(self.item_selection_change, (i, j)), 'value') + + def set_grid(self): + for i in range(self.grid_shape[0]): + for j in range(self.grid_shape[1]): + self.table[i, j] = Dropdown( + options=['raw movie', 'mcorr movie', 'downsampled avg movie', 'correlation image', 'shifts']) + self.grid_cells[i, j] = (self.table[i, j]) + + def item_selection_change(self, *args): + grid_position = args[0] + change = args[1]["new"] + self.base.update_graphic(grid_position, change) + + def get_layout(self): + return self.table + From 2791f6a73d3b36ab029f40ef012c60cf5249f994 Mon Sep 17 00:00:00 2001 From: Caitlin Lewis Date: Wed, 14 Sep 2022 16:17:47 -0400 Subject: [PATCH 2/4] new branch for architecture, old one can be deleted --- mesmerize_viz/baseviewer.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/mesmerize_viz/baseviewer.py b/mesmerize_viz/baseviewer.py index 9da8d3a..75ce530 100644 --- a/mesmerize_viz/baseviewer.py +++ b/mesmerize_viz/baseviewer.py @@ -83,7 +83,10 @@ def _init_batch_list_widget(self, multi_select: bool): indicator = green_circle elif r["outputs"]["success"] is False: indicator = red_circle - name = r["name"] + try: + name = r["name"] + except: + name = r["item_name"] options.append(f"{ix}: {indicator} {name}") if multi_select: From b455ce0c8cc1b8678c3db597fc29932278a98ebe Mon Sep 17 00:00:00 2001 From: Caitlin Lewis Date: Wed, 21 Sep 2022 11:11:13 -0400 Subject: [PATCH 3/4] new branch for conference --- examples/cnmf.ipynb | 241 ---------------- examples/mcorr.ipynb | 276 ------------------ examples/old-viewer.ipynb | 148 ---------- examples/workshop.ipynb | 470 +++++++++++++++++++++++++++++++ mesmerize_viz/cnmfviewer.py | 15 +- mesmerize_viz/dataframeviewer.py | 5 +- mesmerize_viz/mcorrviewer.py | 1 + mesmerize_viz/selectviewer.py | 4 +- 8 files changed, 485 insertions(+), 675 deletions(-) delete mode 100644 examples/cnmf.ipynb delete mode 100644 examples/mcorr.ipynb delete mode 100644 examples/old-viewer.ipynb create mode 100644 examples/workshop.ipynb diff --git a/examples/cnmf.ipynb b/examples/cnmf.ipynb deleted file mode 100644 index 7ce04d4..0000000 --- a/examples/cnmf.ipynb +++ /dev/null @@ -1,241 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "id": "71858ecf-3017-460a-9f43-af29bc1dcaee", - "metadata": {}, - "outputs": [], - "source": [ - "# looking at cnmf viewer" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "930993e4-860f-48d6-81e0-884c602ff70f", - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "0ec8ddf3-533a-4941-a4d3-89d351473d46", - "metadata": {}, - "outputs": [], - "source": [ - "from mesmerize_viz.dataframeviewer import DataframeViewer\n", - "from mesmerize_viz.cnmfviewer import CNMFViewer\n", - "from mesmerize_viz.selectviewer import SelectViewer\n", - "from mesmerize_core import load_batch, set_parent_raw_data_path" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "28d12052-5afb-4958-8074-d184b20d7d85", - "metadata": {}, - "outputs": [], - "source": [ - "set_parent_raw_data_path(\"/data/wasabi-remote/hantmanlab/from_tier2/Teena/Experiments/Mesoscale/Opto_inter_region/\")\n", - "\n", - "df2 = load_batch(\"/data/wasabi-remote/hantmanlab/from_tier2/Teena/Experiments/Mesoscale/Opto_inter_region/mesmerize_batch/batch.pickle\")" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "912e73d2-4c78-4ea4-866e-4e24db6c7f44", - "metadata": {}, - "outputs": [], - "source": [ - "df = df2.loc[df2[\"algo\"] == \"cnmf\"]" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "dc991487-8fab-4f89-9fef-13b9d3e80b7d", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
indexalgonameinput_movie_pathparamsoutputsuuidanimal_idsession_idtrial_df_pathexp-group
059cnmfoit4-080721-ap1_1_pt_5a9e7acfd3-e7e5-4c3a-a96d-2e1b586c0b58/9e7acfd3-...{'main': {'p': 2, 'nb': 1, 'rf': 60, 'stride':...{'mean-projection-path': faa06614-a582-43ff-b4...faa06614-a582-43ff-b4d3-16014dcc4fc4NaNNaNNaNopto
\n", - "
" - ], - "text/plain": [ - " index algo name \\\n", - "0 59 cnmf oit4-080721-ap1_1_pt_5a \n", - "\n", - " input_movie_path \\\n", - "0 9e7acfd3-e7e5-4c3a-a96d-2e1b586c0b58/9e7acfd3-... \n", - "\n", - " params \\\n", - "0 {'main': {'p': 2, 'nb': 1, 'rf': 60, 'stride':... \n", - "\n", - " outputs \\\n", - "0 {'mean-projection-path': faa06614-a582-43ff-b4... \n", - "\n", - " uuid animal_id session_id trial_df_path \\\n", - "0 faa06614-a582-43ff-b4d3-16014dcc4fc4 NaN NaN NaN \n", - "\n", - " exp-group \n", - "0 opto " - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "df = df.reset_index()\n", - "df = df.drop(df.index[1:33])\n", - "df" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "2670fc40-5229-4dc9-b13d-d49c8474581c", - "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "368ac1c297da43ff8bea2a19e0476275", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "RFBOutputContext()" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/home/clewis7/repos/mesmerize-viz/mesmerize_viz/cnmfviewer.py:85: FutureWarning: You are trying to use the following experimental feature, this maybe change in the future without warning:\n", - "CaimanSeriesExtensions.get_input_movie\n", - "\n", - "\n", - " input=r.caiman.get_input_movie(),\n" - ] - } - ], - "source": [ - "cv = CNMFViewer(dataframe=df)\n", - "sv = SelectViewer(cv, grid_shape=(2,3))\n", - "dfv = DataframeViewer(cv, sv)" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "518d2c7a-1767-4cd7-92d4-4db5d1f3cf8f", - "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "c6640bb164524f91b53f541a6c42cee6", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "Tab(children=(VBox(children=(HBox(children=(Select(layout=Layout(height='200px'), options=('0: 🟢 oit4-080721-a…" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "dfv.show()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "050a0b5b-9915-4fe4-af8b-9bb9abd8cecb", - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.9.2" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/examples/mcorr.ipynb b/examples/mcorr.ipynb deleted file mode 100644 index 0b86df7..0000000 --- a/examples/mcorr.ipynb +++ /dev/null @@ -1,276 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "id": "b700ff69-2091-4e3f-aa72-8be5955312a0", - "metadata": {}, - "outputs": [], - "source": [ - "# demo using reformatted mes viz" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "43623668-2f0f-4307-b095-59860e628385", - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "4f0233d8-8e67-48fe-a68e-8723376ebf76", - "metadata": {}, - "outputs": [], - "source": [ - "from mesmerize_viz.dataframeviewer import DataframeViewer\n", - "from mesmerize_viz.mcorrviewer import MCorrViewer\n", - "from mesmerize_viz.selectviewer import SelectViewer\n", - "from mesmerize_core import load_batch, set_parent_raw_data_path" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "3058df65-c5df-4cac-ae6c-4cc2c21003a2", - "metadata": {}, - "outputs": [], - "source": [ - "set_parent_raw_data_path(\"/home/kushal/caiman_data/\")\n", - "\n", - "batch_path = \"/home/kushal/caiman_data/mesmerize-core-batch/batch2.pickle\"\n", - "\n", - "df = load_batch(batch_path)" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "5fe3f7aa-6113-4767-9642-3d7a3b0a69c5", - "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "36e5c4943c6d40f199924acb2d1747bc", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "RFBOutputContext()" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/home/clewis7/repos/mesmerize-viz/mesmerize_viz/mcorrviewer.py:88: FutureWarning: You are trying to use the following experimental feature, this maybe change in the future without warning:\n", - "CaimanSeriesExtensions.get_input_movie\n", - "\n", - "\n", - " input=r.caiman.get_input_movie(\"append-tiff\"),\n" - ] - } - ], - "source": [ - "mv = MCorrViewer(dataframe=df)\n", - "sv = SelectViewer(mv, grid_shape=(2,3))\n", - "dfv = DataframeViewer(mv, sv)" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "4c1e7344-1c22-4a8c-816e-5a00098e75d2", - "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "7b8eff8b0d6f41c1a43a09b0937cf95b", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "Tab(children=(VBox(children=(HBox(children=(Select(layout=Layout(height='200px'), options=('0: 🟢 my_movie', '1…" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "dfv.show()" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "a61777f9-f66f-49db-837a-52fca826d6b6", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "mv.grid_plot.subplots[0,0]" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "d4f8e507-bf61-4e39-998b-b00c2ce51bef", - "metadata": {}, - "outputs": [], - "source": [ - "from fastplotlib import *" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "id": "f918b8b2-dc15-417c-8fb1-ba207bab6885", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 15, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "mv.grid_plot.subplots[1,1]" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "164b39a9-e248-4045-a17c-8149d452fc2c", - "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "0368183cc053421a9155f432af4d084e", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "RFBOutputContext()" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
initial snapshot
" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "ac9c03e76b7a4872bb635cb80ea925b1", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "JupyterWgpuCanvas()" - ] - }, - "execution_count": 12, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plot = Plot()\n", - "\n", - "img_graphic = mv.grid_plot.subplots[1,1]\n", - "\n", - "plot.add_graphic(img_graphic)\n", - "\n", - "plot.show()" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "id": "0891f9d2-c7c8-4149-a7bc-d660e8b3a633", - "metadata": {}, - "outputs": [ - { - "ename": "AttributeError", - "evalue": "'Image' object has no attribute 'center_scene'", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)", - "Input \u001b[0;32mIn [14]\u001b[0m, in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[43mmv\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mgrid_plot\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mshow\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n", - "File \u001b[0;32m~/repos/fastplotlib/fastplotlib/layouts.py:143\u001b[0m, in \u001b[0;36mGridPlot.show\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 140\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mcanvas\u001b[38;5;241m.\u001b[39mrequest_draw(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39manimate)\n\u001b[1;32m 142\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m subplot \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m:\n\u001b[0;32m--> 143\u001b[0m \u001b[43msubplot\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcenter_scene\u001b[49m()\n\u001b[1;32m 145\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mcanvas\n", - "\u001b[0;31mAttributeError\u001b[0m: 'Image' object has no attribute 'center_scene'" - ] - } - ], - "source": [ - "mv.grid_plot.show()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b0684e17-774f-4c9c-8b43-e7f73bdfa014", - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.9.2" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/examples/old-viewer.ipynb b/examples/old-viewer.ipynb deleted file mode 100644 index 65ad2be..0000000 --- a/examples/old-viewer.ipynb +++ /dev/null @@ -1,148 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "id": "3fda66e1-0973-4fba-bac4-31a44c8cbfa2", - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "e4d01194-8f05-4221-821f-3550e7e039f7", - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "2022-06-27 02:08:57.611655: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcudart.so.11.0'; dlerror: libcudart.so.11.0: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /home/kushal/python-venvs/mescore/lib/python3.10/site-packages/cv2/../../lib64:\n", - "2022-06-27 02:08:57.611679: I tensorflow/stream_executor/cuda/cudart_stub.cc:29] Ignore above cudart dlerror if you do not have a GPU set up on your machine.\n" - ] - } - ], - "source": [ - "from mesmerize_viz.widgets import MCorrViewer\n", - "from mesmerize_core import load_batch, set_parent_raw_data_path" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "1225545f-9056-435e-bfef-53ff98376c8e", - "metadata": {}, - "outputs": [], - "source": [ - "set_parent_raw_data_path(\"/home/kushal/caiman_data/\")\n", - "\n", - "batch_path = \"/home/kushal/caiman_data/mesmerize-core-batch/batch2.pickle\"\n", - "\n", - "df = load_batch(batch_path)" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "4fba5bc7-4d33-4a75-8770-e370e726fb1f", - "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "3d3568e9d449496e8f7a07b49d54b2d0", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "RFBOutputContext()" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/home/kushal/Insync/kushalkolar@gmail.com/drive/repos/mesmerize-viz/mesmerize_viz/widgets.py:133: FutureWarning: You are trying to use the following experimental feature, this maybe change in the future without warning:\n", - "CaimanSeriesExtensions.get_input_movie\n", - "\n", - "None\n", - " input=r.caiman.get_input_movie(),\n" - ] - } - ], - "source": [ - "mv = MCorrViewer(dataframe=df)" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "299b1a9c-c66a-4f41-8b52-77395265317a", - "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "abeef40312014c0895d8521890450edd", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "VBox(children=(HBox(children=(Select(layout=Layout(height='200px'), options=('🟢 my_movie', '🟢 my_movie'), valu…" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "mv.show()" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "eac8c4b3-3abe-4a81-bf88-76162b3c65db", - "metadata": {}, - "outputs": [], - "source": [ - "mv.grid_plot.subplots[0, 0].center_scene()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5afce9e0-a5ba-4a38-97dd-93c07155e2d9", - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.9.2" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/examples/workshop.ipynb b/examples/workshop.ipynb new file mode 100644 index 0000000..8451027 --- /dev/null +++ b/examples/workshop.ipynb @@ -0,0 +1,470 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "55ec0e8b-2c76-4036-9a63-6b4e40797157", + "metadata": {}, + "source": [ + "# mesmerize-viz demo" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "d5cfa59f-5bc0-460b-bfca-72dee7467a1e", + "metadata": { + "pycharm": { + "name": "#%%\n" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "from mesmerize_core import *\n", + "import tifffile\n", + "import numpy as np\n", + "from matplotlib import pyplot as plt\n", + "import seaborn as sns\n", + "from copy import deepcopy\n", + "import pandas as pd" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "89c91d60-135f-458c-bd73-dfb2e2d65bb6", + "metadata": { + "pycharm": { + "name": "#%%\n" + } + }, + "outputs": [], + "source": [ + "from fastplotlib import GridPlot, Image, Plot\n", + "from ipywidgets.widgets import IntSlider, VBox\n", + "from mesmerize_viz.cnmfviewer import CNMFViewer\n", + "from mesmerize_viz.mcorrviewer import MCorrViewer\n", + "from mesmerize_viz.dataframeviewer import DataframeViewer\n", + "from mesmerize_viz.selectviewer import SelectViewer" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "30cab12c-afb5-4ee4-9d16-1b3cd03bdad5", + "metadata": { + "pycharm": { + "name": "#%%\n" + } + }, + "outputs": [], + "source": [ + "set_parent_raw_data_path(\"/home/clewis7/caiman_data/\")\n", + "\n", + "batch_path = \"/home/clewis7/caiman_data/mesmerize-core-batch/batch.pickle\"\n", + "\n", + "movie_path = \"/home/clewis7/caiman_data/example_movies/demoMovie.tif\"" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "cccb9c6b-02ee-4d32-bd5a-5496bcd18f5d", + "metadata": {}, + "outputs": [], + "source": [ + "mcorr_df = load_batch(batch_path)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "1590b646-af28-4cbf-b5f2-58784b67cf98", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
algoitem_nameinput_movie_pathparamsoutputscommentsuuid
0mcorrmy_movieexample_movies/demoMovie.tif{'main': {'max_shifts': (24, 24), 'strides': (...{'mean-projection-path': b6663bf9-bbf5-4b24-a1...Noneb6663bf9-bbf5-4b24-a184-b9eaed4b43cd
1mcorrmy_movieexample_movies/demoMovie.tif{'main': {'max_shifts': (24, 24), 'strides': (...{'mean-projection-path': 54663442-33d8-4763-9b...None54663442-33d8-4763-9b72-29c8c6f158d1
2cnmfmy_movieb6663bf9-bbf5-4b24-a184-b9eaed4b43cd/b6663bf9-...{'main': {'fr': 30, 'p': 1, 'nb': 2, 'merge_th...{'mean-projection-path': dce4e58a-2104-4ed2-b6...Nonedce4e58a-2104-4ed2-b6c1-ebfa2bb84185
3cnmfmy_movie54663442-33d8-4763-9b72-29c8c6f158d1/54663442-...{'main': {'fr': 30, 'p': 1, 'nb': 2, 'merge_th...{'mean-projection-path': 6bea8594-67ef-4ae7-8f...None6bea8594-67ef-4ae7-8fe6-2ef129f8dc6c
\n", + "
" + ], + "text/plain": [ + " algo item_name input_movie_path \\\n", + "0 mcorr my_movie example_movies/demoMovie.tif \n", + "1 mcorr my_movie example_movies/demoMovie.tif \n", + "2 cnmf my_movie b6663bf9-bbf5-4b24-a184-b9eaed4b43cd/b6663bf9-... \n", + "3 cnmf my_movie 54663442-33d8-4763-9b72-29c8c6f158d1/54663442-... \n", + "\n", + " params \\\n", + "0 {'main': {'max_shifts': (24, 24), 'strides': (... \n", + "1 {'main': {'max_shifts': (24, 24), 'strides': (... \n", + "2 {'main': {'fr': 30, 'p': 1, 'nb': 2, 'merge_th... \n", + "3 {'main': {'fr': 30, 'p': 1, 'nb': 2, 'merge_th... \n", + "\n", + " outputs comments \\\n", + "0 {'mean-projection-path': b6663bf9-bbf5-4b24-a1... None \n", + "1 {'mean-projection-path': 54663442-33d8-4763-9b... None \n", + "2 {'mean-projection-path': dce4e58a-2104-4ed2-b6... None \n", + "3 {'mean-projection-path': 6bea8594-67ef-4ae7-8f... None \n", + "\n", + " uuid \n", + "0 b6663bf9-bbf5-4b24-a184-b9eaed4b43cd \n", + "1 54663442-33d8-4763-9b72-29c8c6f158d1 \n", + "2 dce4e58a-2104-4ed2-b6c1-ebfa2bb84185 \n", + "3 6bea8594-67ef-4ae7-8fe6-2ef129f8dc6c " + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "mcorr_df" + ] + }, + { + "cell_type": "markdown", + "id": "4c9e9221-527a-4a4e-a182-8fa440f6bee3", + "metadata": {}, + "source": [ + "### Viewer for MCORR" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "68f68073-2eec-4162-9e85-0369a69ef978", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "d2c1f754ec5b4717a07b96226682b82e", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "RFBOutputContext()" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/clewis7/repos/mesmerize-viz/mesmerize_viz/mcorrviewer.py:89: FutureWarning: You are trying to use the following experimental feature, this may change in the future without warning:\n", + "CaimanSeriesExtensions.get_input_movie\n", + "\n", + "\n", + " input=r.caiman.get_input_movie(\"append-tiff\"),\n" + ] + } + ], + "source": [ + "mv = MCorrViewer(dataframe=mcorr_df)\n", + "sv = SelectViewer(mv, grid_shape=(2,3))\n", + "dfv = DataframeViewer(mv, sv)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "ea25018e-4298-4e2b-a36a-4ff7f0f8701d", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "3c17189d148c40fb98eb616a53449296", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "VBox(children=(HBox(children=(Select(layout=Layout(height='200px'), options=('0: 🟢 my_movie', '1: 🟢 my_movie',…" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "dfv.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "5f1352f2-95fb-4aab-8064-9f9a21b4a419", + "metadata": {}, + "outputs": [], + "source": [ + "cnmf_df = load_batch(batch_path)" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "528750d1-6253-4fb1-8219-95d8f2e97ad8", + "metadata": {}, + "outputs": [], + "source": [ + "cnmf_df = cnmf_df[cnmf_df[\"algo\"] == \"cnmf\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "3921c4c6-4d50-4614-a7c3-bb0bfc6451b6", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
indexalgoitem_nameinput_movie_pathparamsoutputscommentsuuid
02cnmfmy_movieb6663bf9-bbf5-4b24-a184-b9eaed4b43cd/b6663bf9-...{'main': {'fr': 30, 'p': 1, 'nb': 2, 'merge_th...{'mean-projection-path': dce4e58a-2104-4ed2-b6...Nonedce4e58a-2104-4ed2-b6c1-ebfa2bb84185
13cnmfmy_movie54663442-33d8-4763-9b72-29c8c6f158d1/54663442-...{'main': {'fr': 30, 'p': 1, 'nb': 2, 'merge_th...{'mean-projection-path': 6bea8594-67ef-4ae7-8f...None6bea8594-67ef-4ae7-8fe6-2ef129f8dc6c
\n", + "
" + ], + "text/plain": [ + " index algo item_name input_movie_path \\\n", + "0 2 cnmf my_movie b6663bf9-bbf5-4b24-a184-b9eaed4b43cd/b6663bf9-... \n", + "1 3 cnmf my_movie 54663442-33d8-4763-9b72-29c8c6f158d1/54663442-... \n", + "\n", + " params \\\n", + "0 {'main': {'fr': 30, 'p': 1, 'nb': 2, 'merge_th... \n", + "1 {'main': {'fr': 30, 'p': 1, 'nb': 2, 'merge_th... \n", + "\n", + " outputs comments \\\n", + "0 {'mean-projection-path': dce4e58a-2104-4ed2-b6... None \n", + "1 {'mean-projection-path': 6bea8594-67ef-4ae7-8f... None \n", + "\n", + " uuid \n", + "0 dce4e58a-2104-4ed2-b6c1-ebfa2bb84185 \n", + "1 6bea8594-67ef-4ae7-8fe6-2ef129f8dc6c " + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cnmf_df.reset_index()" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "431a372b-01a6-4e87-9a41-8e241eed9d92", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "598f26cf14564222a90af0704c033914", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "RFBOutputContext()" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/clewis7/repos/mesmerize-viz/mesmerize_viz/cnmfviewer.py:86: FutureWarning: You are trying to use the following experimental feature, this may change in the future without warning:\n", + "CaimanSeriesExtensions.get_input_movie\n", + "\n", + "\n", + " input=r.caiman.get_input_movie(),\n" + ] + } + ], + "source": [ + "cv = CNMFViewer(dataframe=cnmf_df)\n", + "sv = SelectViewer(cv, grid_shape=(2,2))\n", + "dfv = DataframeViewer(cv, sv)" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "7eb2c429-f549-4710-bb4e-cdef1bc55f46", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "11752d87893944cda5350dda04c9bea0", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Tab(children=(VBox(children=(HBox(children=(Select(layout=Layout(height='200px'), options=('0: 🟢 my_movie', '1…" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "dfv.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "85b3145c-1e4f-42bb-8ebc-f3a75dfdda78", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.2" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/mesmerize_viz/cnmfviewer.py b/mesmerize_viz/cnmfviewer.py index c4de665..5708354 100644 --- a/mesmerize_viz/cnmfviewer.py +++ b/mesmerize_viz/cnmfviewer.py @@ -53,23 +53,24 @@ def __init__( ): super(CNMFViewer, self).__init__( dataframe, - grid_plot_shape=(2, 3), + grid_plot_shape=(2, 2), grid_plot_kwargs={"controllers": "sync"}, multi_select=False ) self.subplots = _CNMFContainer( input=self.grid_plot.subplots[0, 0], - contours=self.grid_plot.subplots[0, 1], - reconstructed=self.grid_plot.subplots[0, 2], + contours=self.grid_plot.subplots[0, 0], + reconstructed=self.grid_plot.subplots[0, 1], residuals=self.grid_plot.subplots[1, 0], #temporal=self.grid_plot.subplots[1, 1], - background=self.grid_plot.subplots[1, 2] + background=self.grid_plot.subplots[1, 1] ) self._imaging_data: _CNMFContainer = None self._graphics: _CNMFContainer = None self.ds_window = 10 + self.algo = "cnmf" self.item_selection_changed() @@ -116,12 +117,14 @@ def item_selection_changed(self, *args): reconstructed_graphic = Image( self._imaging_data.reconstructed[0], - cmap="gnuplot2" + cmap="gnuplot2", + vmin=3, + vmax=30 ) background_graphic = Image( self._imaging_data.background[0], - cmap="gray" + cmap="gray", ) self._graphics = _CNMFContainer( diff --git a/mesmerize_viz/dataframeviewer.py b/mesmerize_viz/dataframeviewer.py index a254b28..c2a645b 100644 --- a/mesmerize_viz/dataframeviewer.py +++ b/mesmerize_viz/dataframeviewer.py @@ -17,4 +17,7 @@ def __init__( self.tab.children = (self.base.get_layout(), self.select.get_layout()) def show(self): - return self.tab + if self.base.algo == "mcorr": + return self.base.get_layout() + else: + return self.tab diff --git a/mesmerize_viz/mcorrviewer.py b/mesmerize_viz/mcorrviewer.py index bf2145c..01aa8df 100644 --- a/mesmerize_viz/mcorrviewer.py +++ b/mesmerize_viz/mcorrviewer.py @@ -71,6 +71,7 @@ def __init__( self._imaging_data: _MCorrContainer = None self._graphics: _MCorrContainer = None self.ds_window = 10 + self.algo = "mcorr" # Nothing works without this call # I don't know why ¯\_(ツ)_/¯ diff --git a/mesmerize_viz/selectviewer.py b/mesmerize_viz/selectviewer.py index 228854f..6399854 100644 --- a/mesmerize_viz/selectviewer.py +++ b/mesmerize_viz/selectviewer.py @@ -12,11 +12,9 @@ def __init__( _BaseViewer, grid_shape: Tuple[int, int] = None, multi_select: bool = False, - algo: str = "mcorr", ): self.grid_shape = grid_shape self.table = GridspecLayout(self.grid_shape[0], self.grid_shape[1]) - self.algo = algo self.base = _BaseViewer self.grid_cells = np.empty(shape=self.grid_shape, dtype=object) @@ -30,7 +28,7 @@ def set_grid(self): for i in range(self.grid_shape[0]): for j in range(self.grid_shape[1]): self.table[i, j] = Dropdown( - options=['raw movie', 'mcorr movie', 'downsampled avg movie', 'correlation image', 'shifts']) + options=['input', 'reconstructed', 'residuals', 'background']) self.grid_cells[i, j] = (self.table[i, j]) def item_selection_change(self, *args): From fb2b4126ac0ee1e51e4f41cc19378e6e93c42a93 Mon Sep 17 00:00:00 2001 From: Caitlin Lewis Date: Fri, 28 Oct 2022 15:55:52 -0400 Subject: [PATCH 4/4] optimizing cnmf viewer so that it should load faster --- mesmerize_viz/cnmfviewer.py | 82 ++++++++++++++++++++++++++++++------ mesmerize_viz/mcorrviewer.py | 9 ---- 2 files changed, 69 insertions(+), 22 deletions(-) diff --git a/mesmerize_viz/cnmfviewer.py b/mesmerize_viz/cnmfviewer.py index 5708354..21d778c 100644 --- a/mesmerize_viz/cnmfviewer.py +++ b/mesmerize_viz/cnmfviewer.py @@ -74,6 +74,17 @@ def __init__( self.item_selection_changed() + # self.positions = list() + # self.positions.append((0,0)) + # self.positions.append((0,1)) + # self.positions.append((1,0)) + # self.positions.append((1,1)) + # + # self.grid_plot[0,0].name = "input" + # self.grid_plot[0,1].name = "reconstructed" + # self.grid_plot[1,0].name = "residuals" + # self.grid_plot[1,1].name = "background" + def item_selection_changed(self, *args): r = self.get_selected_item() if r is False: @@ -81,23 +92,22 @@ def item_selection_changed(self, *args): for subplot in self.grid_plot: subplot.scene.clear() - + self._imaging_data = _CNMFContainer( input=r.caiman.get_input_movie(), - contours=r.cnmf.get_contours()[0], - residuals=r.cnmf.get_residuals(), - reconstructed=r.cnmf.get_rcm(), + contours=r.cnmf.get_contours("good", swap_dim=False)[0], + residuals=r.cnmf.get_residuals(frame_indices=0)[0], + reconstructed=r.cnmf.get_rcm(component_indices="good", frame_indices=0)[0], #temporal=r.cnmf.get_temporal(), - background=r.cnmf.get_rcb() + background=r.cnmf.get_rcb(frame_indices=0)[0] ) - input_graphic = Image( self._imaging_data.input[0], cmap="gnuplot2" ) self._set_frame_slider_minmax( - (0, self._imaging_data.reconstructed.shape[0]-1) + (0, self._imaging_data.input.shape[0] - 1) ) contours_graphic: List[Line] = list() @@ -111,19 +121,19 @@ def item_selection_changed(self, *args): contours_graphic.append(Line(data=coors_3d, colors=colors)) residuals_graphic = Image( - self._imaging_data.residuals[0], + self._imaging_data.residuals, cmap="gnuplot2" ) reconstructed_graphic = Image( - self._imaging_data.reconstructed[0], + self._imaging_data.reconstructed, cmap="gnuplot2", vmin=3, vmax=30 ) background_graphic = Image( - self._imaging_data.background[0], + self._imaging_data.background, cmap="gray", ) @@ -153,15 +163,61 @@ def item_selection_changed(self, *args): # this does work for some reason if not called from the nb itself ¯\_(ツ)_/¯ self.reset_grid_plot_scenes() + def update_graphic(self, position: Tuple[int, int], change: str): + self.grid_plot.subplots[position[0], position[1]].scene.clear() + new_graphic = self.create_graphic(change) + self.grid_plot.subplots[position[0], position[1]].add_graphic(new_graphic) + self.grid_plot[position[0], position[1]].name = change + self.grid_plot.show() + + def create_graphic(self, graphic_type): + if graphic_type == "input": + return Image( + self._imaging_data.input[0], + cmap="gnuplot2" + ) + elif graphic_type == "residuals": + return Image( + self._imaging_data.residuals[0], + cmap="gnuplot2" + ) + elif graphic_type == "background": + return Image( + self._imaging_data.background[0], + cmap="gray", + ) + else: + return Image( + self._imaging_data.reconstructed[0], + cmap="gnuplot2", + vmin=3, + vmax=30 + ) + def update_frame(self, *args): if self.get_selected_index() is None: return + + r = self.get_selected_item() + if r is False: + return ix = self.frame_slider.value - for attr in ["input", "residuals", "reconstructed", "background"]: - graphic: Image = getattr(self._graphics, attr) - graphic.update_data(getattr(self._imaging_data, attr)[ix]) + # for each position in the grid plot, update based on what is stored there + + # for position in self.positions: + # graphic: Image = getattr(self._graphics, self.grid_plot[position].name) + # graphic.update_data(getattr(self._imaging_data, self.grid_plot[position].name)[ix]) + + # for attr in ["input", "residuals", "reconstructed", "background"]: + # graphic: Image = getattr(self._graphics, attr) + # graphic.update_data(getattr(self._imaging_data, attr)[ix]) + + self._graphics.input.update_data(self._imaging_data.input[ix]) + self._graphics.reconstructed.update_data(r.cnmf.get_rcm(component_indices="good", frame_indices=ix)[0]) + self._graphics.residuals.update_data(r.cnmf.get_residuals(frame_indices=ix)[0]) + self._graphics.background.update_data(r.cnmf.get_rcb(frame_indices=ix)[0]) def _generate_grid_plot(self): pass diff --git a/mesmerize_viz/mcorrviewer.py b/mesmerize_viz/mcorrviewer.py index 01aa8df..242fe4b 100644 --- a/mesmerize_viz/mcorrviewer.py +++ b/mesmerize_viz/mcorrviewer.py @@ -149,15 +149,6 @@ def item_selection_changed(self, *args): # this does work for some reason if not called from the nb itself ¯\_(ツ)_/¯ self.reset_grid_plot_scenes() - def update_graphic(self, position: Tuple[int, int], change: str): - self.grid_plot.subplots[position[0], position[1]].remove_graphic() - # new_graphic = create_graphic(change) - # self.grid_plot.subplots[position[0], position[1]].add_graphic(new_graphic) - - def create_graphic(self, graphic_type): - pass - # create a new graphic to add to subplot - def _get_dsavg(self, frame_index: int) -> np.ndarray: if self.ds_window % 2 == 1: # make sure it's even self.ds_window += 1