imcflibs

Python convenience from and for the IMCF (Imaging Core Facility).

IMCFlibs 🐍 β˜• πŸ”© πŸ”§ πŸͺ›

Build Status DOI

This package contains a diverse collection of Python functions dealing with paths, I/O (file handles, ...), strings etc. and tons of Fiji / ImageJ2 convenience wrappers to simplify scripting and reduce cross-script redundanciees.

Initially this has been a multi-purpose package where a substantial part had been useful in CPython as well. However, since the latest Jython release is still based on Python 2.7 (see the Jython 3 roadmap for more info), imcflibs is now basically limited to the Fiji / ImageJ2 ecosystem (which is also the reason why no pip installable package is provided).

Releases are made through Maven and published to the SciJava Maven repository. The easiest way to use the lib is by adding the IMCF Uni Basel update site to your ImageJ installation.

Developed and provided by the Imaging Core Facility (IMCF) of the Biozentrum, University of Basel, Switzerland.

Example usage

Shading correction / projection

Apply a shading correction model and create a maximum-intensity projection:

from imcflibs.imagej.shading import correct_and_project

model = "/path/to/shading_model.tif"
raw_image = "/path/to/raw_data/image.ome.tif"
out_path = "/path/to/processed_data/"

correct_and_project(raw_image, out_path, model, "Maximum", ".ics")

Split TIFFs by channels and slices

Use status and progress bar updates

Testing πŸ§ͺ in Fiji / ImageJ2

Unfortunately there is nothing like pytest available for the parts that are running exclusively in a ImageJ2 / Fiji context. So in order to provide at least some basic, semi-interactive tests the following conventions are being used:

  • Each function in any of the imcflibs.imagej submodules should have its own directory underneath /tests/imagej/, using their fully qualified name as the path (only skipping the imcflibs. prefix). For example test scripts for imcflibs.imagej.bioformats.import_image() will be placed in the directory /tests/imagej/bioformats/import_image/.
  • The scripts inside those directories are intended to be run interactively / manually in a (freshly started) Fiji instance. Yes, really. Any other suggestions are highly welcome!
  • To facilitate this, a collection of test images (and possibly other input data) should be cloned to the local file system. Currently this sample_data repository is NOT publicly available due to legal βš– uncertainties. A repo containing test data πŸ—ž that can be published should be assembled over time though!
  • Any interactive test script should start with a header similar to the one described below. Paths to input data inside the test scripts has to be relative to the location of the sample_data repository mentioned above. This will allow for a fairly okayish testing workflow like this:
    • Make your changes in VS Code, then trigger a build by pressing Shift + Ctrl + B. If things are configured as described in the DEVELOPMENT document, the resulting .jar file will be automatically placed in Fiji's jars/ folder.
    • Next, start a fresh instance of the Fiji that received the newly built JAR.
    • After Fiji has started, simply drag and drop the desired test script onto the main window. This will open the Script Editor, then press Ctrl + R to launch the script.
    • Only on the first run on the machine being used you will have to select the base location of the sample_data repository.
    • All subsequent runs of any test script using the defined Script Parameter IMCF_TESTDATA will remember this selection, so it will be sufficient to just confirm the dialog by pressing Enter.

Quick Workflow Summary

First, make sure to have the test data πŸ”¬πŸ”­around (or some mocks πŸͺ¨πŸͺ΅), then:

  1. Code πŸ“
  2. Build and deploy locally (Shift+Ctrl+B) πŸ“¦
  3. Start Fiji πŸ‡«πŸ‡―
  4. Drag-and-Drop the respective test script 🐍πŸ§ͺ
  5. Hit Ctrl+R to run it πŸƒβ€β™€οΈ
  6. Confirm dialog with Enter βœ…
  7. Inspect the output πŸ”ŽπŸ‘€
  8. Repeat πŸ”

Test Script Template πŸ—

As described above, each test script should use the IMCF_TESTDATA parameter to facilitate the manual testing approach. Simply use this template header for creating new scripts (or look into existing ones):

# @ File (label="IMCF testdata location", style="directory") IMCF_TESTDATA

import os
from imcflibs.pathtools import join2

testfile = join2(IMCF_TESTDATA, "systems/lsm700/beads/10x_phmax.czi")
assert os.path.exists(testfile)

In case the test requires the components of the testfile's path to be used, this snippet will do the job:

# @ File (label="IMCF testdata location", style="directory") IMCF_TESTDATA

import os
from imcflibs.pathtools import parse_path

components = parse_path("systems/lsm700/beads/10x_phmax.czi", IMCF_TESTDATA)
assert os.path.exists(components["full"])

Changelog 🧾

1.4.0

Added

Changed

1.3.0

Added

Changed

  • The functions below now also accept parameters of type java.io.File (instead of str), making them safe for being used directly with variables retrieved via ImageJ2's Script Parameter @# File:
  • Several changes in imcflibs.pathtools.parse_path:
    • The returned dict now contains an additional key basename that provides the filename without extension.
    • OME-TIFF filenames are now treated as special cases in the sense that the .ome part is stripped from the basename key and added to the ext key instead (as it is part of the suffix).
  • imcflibs.pathtools.listdir_matching now has an additional optional argument sort (defaulting to False) to request the resulting list to be sorted.
  • Many improvements / clarifications in function docstrings.
 1"""Python convenience from and for the IMCF (Imaging Core Facility).
 2
 3.. include:: ../../README.md
 4
 5.. include:: ../../TESTING.md
 6
 7.. include:: ../../CHANGELOG.md
 8"""
 9
10__version__ = "${project.version}"
11
12from . import iotools
13from . import log
14from . import pathtools
15from . import strtools
16
17# check if we're running in Jython, then also import the 'imagej' submodule:
18import platform as _python_platform
19
20if _python_platform.python_implementation() == "Jython":
21    from . import imagej
22del _python_platform