pyimagej
pyimagej copied to clipboard
Add callback mechanism for GUI mode
Update
Update I wanted to preserve the original text (below) for this PR as its relevant to the goals (i.e. create a better experience for macOS users). With the awesome work that @ctrueden has done with jaunch
we now have a way to actually support interactive
mode on macOS. This PR introduces the following new elements and also paves the way for interactive mode on macOS via jaunch
.
This PR adds:
- A "global gateway" which enables other projects to hook into a already running instance of imagej (e.g. napari-imagej).
- A callback mechanism which enables users to register functions with
when_imagej_starts()
. This can enable some GUI related workflows on macOS (a kind of limited psuedo-interactive mode). See notebook 5 section5.2
for the relevant documentation. This callback mechanism is not compatible with napari. - An
override
flag to the maininit
method. This flag will enable users/developers to bypass initialization checks/blocks we've put in place to stop unsupported/application breaking behavior -- mainlyinteractive
mode on macOS. To test interactive mode on macOS:- Install/setup jaunch.
- Modify
jaunch
'sfiji.py
file. Add theoverride=True
flag toij = imagej.init(app_dir, mode="interactive")
on line 72. - Jaunch Fiji with
./fiji-macos-universal -i --python
.
Some other relevant information: Based on what I now understand about Python's threading system and some experimentation on macOS/Linux with jaunch
, Python will always think its in a main thread. There is no way (from what I gather) to know if a particular Python instance was started with/in a pthread
. Instead, threads that are spawned from an already running instance, say in a function that creates threads, are identified as "non-main" thread. This is obvious, but it would have been cool if there was a way to know about how the current instance was started.
Original text
Until we can find a true interactive mode for macOS (see https://github.com/imagej/pyimagej/issues/298) this callback mechanism gives macOS users the ability to run their desired Python functions before the REPL is locked by the AppHelper.runConsoleEventLoop()
.
Here's how you register a callback with PyImageJ:
import imagej
# register a function that takes no params
imagej.when_imagej_starts(lambda: func())
# register an ImageJ function (if a parameter is present, assume its ij)
imagej.when_imagej_starts(lambda ij: ij.RoiManager.getRoiManager())
# initialize ImageJ in GUI mode
ij = imagej.init(mode='gui')
Unfortunately this callback strategy doesn't work with napari
. Registering the callback lambda: napari.Viewer()
results in this segfault:
(pyimagej) loci@dyn-144-92-48-223 Documents % python test.py
WARNING: package sun.awt.X11 not in java.desktop
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by net.imagej.legacy.IJ1Helper (file:/Users/loci/.jgo/net.imagej/imagej/RELEASE/28b74e6959b0634f2a8e10c27afe06e7039fb4a0dc582d9746d028ba40e5bd04/imagej-legacy-1.2.1.jar) to method com.apple.eawt.Application.getApplication()
WARNING: Please consider reporting this to the maintainers of net.imagej.legacy.IJ1Helper
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
#
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGILL (0x4) at pc=0x00007ff8116c90c2, pid=2487, tid=42247
#
# JRE version: OpenJDK Runtime Environment Zulu11.70+15-CA (11.0.22+7) (build 11.0.22+7-LTS)
# Java VM: OpenJDK 64-Bit Server VM Zulu11.70+15-CA (11.0.22+7-LTS, mixed mode, tiered, compressed oops, g1 gc, bsd-amd64)
# Problematic frame:
# C [libdispatch.dylib+0x50c2] _dispatch_assert_queue_fail+0x66
#
# No core dump will be written. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
#
# An error report file with more information is saved as:
# /Users/loci/Documents/hs_err_pid2487.log
#
# If you would like to submit a bug report, please visit:
# http://www.azul.com/support/
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#
zsh: abort python test.py
(pyimagej) loci@dyn-144-92-48-223 Documents %
Codecov Report
Attention: Patch coverage is 78.39506%
with 35 lines
in your changes missing coverage. Please review.
Project coverage is 77.48%. Comparing base (
a173d5a
) to head (a833767
). Report is 14 commits behind head on main.
Files | Patch % | Lines |
---|---|---|
src/imagej/__init__.py | 43.33% | 17 Missing :warning: |
tests/test_legacy.py | 68.57% | 11 Missing :warning: |
tests/test_fiji.py | 12.50% | 7 Missing :warning: |
Additional details and impacted files
@@ Coverage Diff @@
## main #301 +/- ##
==========================================
- Coverage 77.81% 77.48% -0.33%
==========================================
Files 16 17 +1
Lines 2010 2034 +24
==========================================
+ Hits 1564 1576 +12
- Misses 446 458 +12
:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.
~~Just fyi all PyImageJ builds will fail for python 3.12
until labeling=0.1.14
no longer pins pillow <10
in the conda-feedstock recipe. See this issue.~~
Edit: This is no longer an issue with labeling 0.1.14
's release.
Thanks @gselzer for your review! It made it sooo much better! I addressed all your comments. Ready to merge?