Integrating a Jupyter notebook server in CellProfiler?


#1

For debugging purposes and to interact with a live CellProfiler “session”, would it make sense to have a menu option to launch a notebook server from CellProfiler ?

It is something I did for Imaris, I’m just wondering if this would be as useful in CellProfiler.

XTension code here (mostly Python) and an example of what can be done with it.

For CellProfiler, IPython magic could potentially be written to fetch CellProfiler images / properties or to reload CellProfiler plugins.

As a first instance, I’ll try to use the CellProfiler Python library from a Jupyter notebook and see how far I can go that way…

Cheers,
Egor


#2

That’d be amazing! How do you manage the Jupyter process? Fork the running Imaris process?


#3

As far as I understand, when you call an XTension, Imaris launches an “ice server” in the background (?) with which Python communicates.

The most basic way to then communicate with Imaris from within your python code might be:

import code
vars = globals().copy()
vars.update(locals())
shell = code.InteractiveConsole(vars)
shell.interact()

The Imaris session you talk to can be located from the “aImarisId” variable passed to your xtension. Then you can call methods from ImarisLib (provided by Bitplane) to locate various variables from your session. A very rough example to retrieve the “dataset” would be:

vImarisLib = ImarisLib.ImarisLib()

# Get an imaris object with id aImarisId
vImaris = vImarisLib.GetApplication(aImarisId)

# Get the dataset
vDataSet = vImaris.GetDataSet()

If you execute this code before you call the shell.interact() you can get interactive access to any and all Imaris objects exposed through the Ice server (since your local variables are visible from within the interactive console).

In my jupyter xtension, the interactive shell is replaced by the launching of a jupyter server but the end result is the same.

So to reproduce this in CellProfiler, we would need some kind of CellProfiler object, the children of which would represent various aspects of the CellProfiler session, data, preferences etc…

Sorry if this doesn’t make sense :slight_smile:


#4

Quick and dirty test with this commit in my github fork.

I have added a menu option to pop-up the wxPython Widget Inspection Tool:

… which also contains a PyCrust pane:

Nowhere near the power of a Jupyter notebook, but still. As you can see, I am able to interact with the (event driven) wxPython CellProfiler app. Here are the commands if anyone wants to try then:

globals().keys()
['pp', 'shell', 'obj', '__builtins__', 'app', 'filling', 'notebook', 'wx']

app.frame.pipeline_controller
<cellprofiler.gui.pipelinecontroller.PipelineController object at 0x000000001B2C52E8>

app.frame.pipeline_controller.do_analyze_images()

Unfortunately for now, if you close the Inspection tool, relaunching it from the menu will crash CellProfiler (I really meant my “quick and dirty”).

Where do we go from here? Any interesting objects we can get at?

This is where defining some “IPython magic” would really help for command line interaction with CellProfiler. For example, substitute (if this is the right way to go about it) %analyse for app.frame.pipeline_controller.do_analyze_images()

Edit: Just found this code buried in cpframe.py:

#
# Lee wants the wx debugger
#
if os.environ.get("USERNAME", "").lower() == "leek":
    self.__menu_debug.Append(ID_FILE_WIDGET_INSPECTOR, "Widget inspector")

So that might explain why I never saw the widget inspector menu option. Well played Lee :slight_smile:

Although I still stand by my comments about IPython!

Cheers,
Egor