Troubleshooting
Are you having trouble getting PyImageJ up and running? Try the PyImageJ doctor!
python -c "import imagej.doctor; imagej.doctor.checkup()"
See The PyImageJ doctor below for details.
This document is divided into three main sections:
Known Limitations
For technical reasons, there are some aspects of ImageJ and ImageJ2 that cannot fully work from a Python script:
The original ImageJ API is limited in headless mode
Normally, the original ImageJ does not work headless at all. But thanks
to the ImageJ Legacy Bridge, most aspects of the original ImageJ work
in headless mode, including via PyImageJ when initializing with
imagej.init(mode='headless').
That said, there are a couple of major areas of functionality in the original ImageJ that do not work headless, and therefore do not work headless via PyImageJ.
ROI Manager
ImageJ’s ROI Manager allows you to work with multiple regions of interest
(ROIs) simultaneously. The ij.plugin.frame.RoiManager class is the API for
controlling these features. As one might guess just from its package name,
ij.plugin.frame.RoiManager is a java.awt.Frame, and therefore cannot be
used headless.
If you need to work with multiple ij.gui.Roi objects, one option that works
headless is to group them using an ij.gui.Overlay.
WindowManager
ImageJ’s ij.WindowManager class consists of static functions for working with
Java AWT windows, including ImageJ’s ij.gui.ImageWindow. Each ImageJ image is
an ij.ImagePlus linked to a corresponding ij.gui.ImageWindow. However, in
headless mode, there are no image windows, because they cannot exist headless.
Therefore, attempts to use the functions of the WindowManager will fail, with
functions like WindowManager.getCurrentWindow() always returning null.
Unfortunately, ImageJ tracks open images via their windows; therefore, you
cannot know which images have previously been opened while running headless,
nor is there an “active image window” while running headless because there are
no windows.
Note that if you are having problems with a null or incorrect active image
while running in GUI or INTERACTIVE mode (i.e. not HEADLESS), you
might need to call ij.py.sync_image(imp), where imp is the ij.ImagePlus
you want to register or update.
Non-blocking INTERACTIVE mode on macOS
On macOS, the CoreFoundation/AppKit event loop needs to be started from the
main thread before any Java-AWT-specific functions can work. And doing so
blocks the main thread. For this reason, PyImageJ includes two graphical modes,
GUI and INTERACTIVE, with GUI blocking the imagej.init invocation, and
INTERACTIVE returning immediately… but INTERACTIVE can only work on macOS
in certain scenarios. PyImageJ makes a best effort to check your environment
and report when interactive cannot work, and how you might go about fixing it.
Old versions of ImageJ2
PyImageJ uses some functions of ImageJ2 and supporting libraries that are not available in older versions of ImageJ2. While it may be possible to initialize an ImageJ2 gateway with an older version of ImageJ2, certain functionality may not behave as intended, so we advise to use version 2.11.0 or later if possible.
Starting Python from inside ImageJ
At the time of this writing, in order to use PyImageJ, you must start Python first, and initialize ImageJ2 from there.
We have plans to make it possible to go the other direction: starting ImageJ2 as usual and then calling Python scripts for the Script Editor. But this architecture is not complete yet; see this forum discussion for details.
Debugging Tips
The PyImageJ doctor
PyImageJ comes equipped with a troubleshooter that you can run to check for issues with your Python environment:
import imagej.doctor
imagej.doctor.checkup()
It is completely standalone, so alternately, you can run the latest version of the doctor by downloading and running it explicitly:
curl -fsLO https://raw.githubusercontent.com/imagej/pyimagej/main/src/imagej/doctor.py
python doctor.py
(If you don’t have curl, use wget or download using a web browser.)
Enabling debug logging
You can enable more verbose output about what is happening internally, such as which Java dependencies are being installed by jgo.
Add the following to the very beginning of your Python code:
import imagej.doctor
imagej.doctor.debug_to_stderr()
Under the hood, this debug_to_stderr() call sets the log level to DEBUG
for the relevant PyImageJ dependencies, and adds a logging handler that
emits output to the standard error stream.
Common Errors
Command died with Signals.SIGKILL: 9
If you see an error like:
subprocess.CalledProcessError: Command '['.../jre/bin/java', '-version']' died with <Signals.SIGKILL: 9>.
it might be that you are using an M1 Mac, and have OpenJDK 8 installed from conda-forge? Unfortunately, Version 8 of OpenJDK from conda-forge is known to be broken on Mac M1 machines.
Try mamba install openjdk=11 to update to version 11, and this problem should go away.
Could not transfer artifact
If the debugging output includes notices such as:
DEBUG:jgo: [ERROR] Non-resolvable import POM: Could not transfer artifact net.imglib2:imglib2-imglyb:pom:1.0.1 from/to scijava.public (https://maven.scijava.org/content/groups/public): Transfer failed for https://maven.scijava.org/content/groups/public/net/imglib2/imglib2-imglyb/1.0.1/imglib2-imglyb-1.0.1.pom @ line 8, column 29: Connect to maven.scijava.org:443 [maven.scijava.org/144.92.48.199] failed: Connection timed out:
This suggests you may be behind a firewall that is preventing necessary components from being downloaded. In this case you have a few options to try:
Tell Java to use your system proxy settings:
import os os.environ["JAVA_TOOL_OPTIONS"] = "-Djava.net.useSystemProxies=true"
Configure your proxy settings manually: (replacing
example.comand8080as appropriate)import os myhost = "example.com" myport = 8080 os.environ["JAVA_TOOL_OPTIONS"] = ( f"-Dhttp.proxyHost={myhost}" + f" -Dhttp.proxyPort={myport}" + f" -Dhttps.proxyHost={myhost}" + f" -Dhttps.proxyPort={myport}" )
Initialize with a local Fiji installation, so that PyImageJ does not need to download anything else from the Internet. In this case you will also have to manually download the latest
.jarfiles for imglib2-unsafe and imglib2-imglyb and place them in your localFiji/jarsdirectory, as these are required for PyImageJ but not part of the standard Fiji distribution.
Unable to find valid certification path
If the debugging output includes notices such as:
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.validator.PKIXValidator.doBuild (PKIXValidator.java:397)
at sun.security.validator.PKIXValidator.engineValidate (PKIXValidator.java:240)
This suggests the version of Java being used is too old and contains outdated
certificate information. This behavior has been confirmed with the openjdk
installed from the default conda channel (i.e. conda install openjdk). Try
using an openjdk from the
conda-forge channel instead.
I ran a plugin and see an updated image, but the numpy array and dataset are unchanged
This bug can occur in certain circumstances when using original ImageJ plugins
which update a corresponding ImagePlus. It can be worked around by calling:
imp = ij.WindowManager.getCurrentImage()
ij.py.sync_image(imp)
The same macro gives different results when run multiple times
This pernicious problem, covered by issue #148, has been observed and documented on a forum thread. No one has had time to fully investigate, determine how widespread the problem is, or fix it. Help wanted!
Original ImageJ classes not found
If you try to load an original ImageJ class (with package prefix ij),
and get a JavaException: Class not found error, this is because
the environment was initialized without the original ImageJ included.
See Initialization.md.
Not enough memory
You can increase the memory available to the JVM before starting it. See Initialization.md.
Python hangs when quitting
It’s probably because the JVM is not shutting down cleanly. JPype and scyjava try their best to shut down the JVM, and PyImageJ does its best to dispose all ImageJ2 resources when Python wants to shut down. However, in some scenarios there can still be problems; see #153.
You can try calling ij.dispose() yourself before quitting Python. If that is
not enough, you can even call scyjava.jimport('java.lang.System').exit(0)
(Java exit) or sys.exit(0) (Python exit), either of which will immediately
terminate both Java and Python.
log4j:WARN
With ImageJ2 v2.3.0 and earlier, there is an obnoxious warning at startup:
log4j:WARN No appenders could be found for logger (org.bushe.swing.event.EventService).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
This can safely be ignored, and will be fixed in the next release of ImageJ2.
TypeError: No matching overloads
Java has method overloading, whereas Python does not. The JPype library is very
smart about figuring which Java method you intend to call based on the argument
types. But it is not perfect—see e.g.
jpype-project/jpype#844.
Therefore, you might encounter an error TypeError: No matching overloads when
trying to call certain Java methods in some scenarios. Here is an example:
>>> ij = imagej.init()
>>> ij.op().create()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: No matching overloads found for org.scijava.plugin.PTService.create(), options are:
public default org.scijava.plugin.SciJavaPlugin org.scijava.plugin.PTService.create(java.lang.Class)
Until JPype is improved, you will need to work around the issue case by case.
For example, to avoid the error above with the create() method, you can use:
CreateNamespace = imagej.sj.jimport('net.imagej.ops.create.CreateNamespace')
create = ij.op().namespace(CreateNamespace)
And then create will contain the same object normally accessed via
ij.op().create().
If you are stuck, please post a topic on the Image.sc Forum.
pip install jpype1 fails on Windows
There is a known issue installing with pip on Windows with Python 3.10.
Please see
jpype-project/jpype#1009.
Until this issue is resolved, we suggest those on Windows either:
Install with
condarather thanpip(preferred).Downgrade to Python 3.9.