Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
4f72294
Install PyTorch through the PyTorch extension and use slicer.util.pip…
JonaRichter Jul 22, 2026
b11da2b
Stop the dependency install when torch is not yet in place
JonaRichter Jul 22, 2026
65a8bca
Constrain numpy and opencv to versions the macOS torch build supports
JonaRichter Jul 22, 2026
9fff96b
Install all Python packages in one pip invocation with a numpy cap
JonaRichter Jul 22, 2026
a88ba41
Document the macOS NumPy constraint and the benign pyjpegls warning
JonaRichter Jul 22, 2026
b5830e1
Pass an absolute script path to slicer_add_python_unittest
JonaRichter Jul 22, 2026
c47031b
Install dependencies when an action needs them instead of on module open
JonaRichter Jul 22, 2026
85ee204
Route status through the module panel and use Slicer's standard dialogs
JonaRichter Jul 22, 2026
162c745
Replace the placeholder icon with a zebrafish larva icon
JonaRichter Jul 22, 2026
e1d5fa4
Announce missing packages in the panel and restart only when actually…
JonaRichter Jul 22, 2026
21cfd48
Drop the status panel and leave pip failures to Slicer's own dialog
JonaRichter Jul 22, 2026
2f63120
Drop the in-panel dependency notice and prompt only when an action ne…
JonaRichter Jul 22, 2026
eee58e9
Restore the in-panel notice about packages that still need installing
JonaRichter Jul 22, 2026
f8b3ccf
Ask for OpenCV before loading images instead of crashing in the gallery
JonaRichter Jul 22, 2026
9a802ab
Keep the UI responsive while loading images
JonaRichter Jul 22, 2026
f2932f2
Show determinate progress while loading images
JonaRichter Jul 22, 2026
d01ceeb
Report image loading progress on the button that started it
JonaRichter Jul 22, 2026
646e756
Let the load button cancel the image loading it started
JonaRichter Jul 22, 2026
50a8e32
Reorder the left panel and hide unused controls
JonaRichter Jul 23, 2026
55b089c
Change module category from Quantification to Analysis
JonaRichter Jul 23, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ set(EXTENSION_CONTRIBUTORS "Jona Richter, Mark Daniel Arndt")
set(EXTENSION_DESCRIPTION "Zebrafish body length, curvature, and eye metrics from 2D microscopy images.")
set(EXTENSION_ICONURL "https://raw.githubusercontent.com/MarkDanielArndt/SlicerZebrafishEmbryoAnalyzer/main/ZebrafishEmbryoAnalyzer/Resources/Icons/ZebrafishEmbryoAnalyzer.png")
set(EXTENSION_SCREENSHOTURLS "https://raw.githubusercontent.com/MarkDanielArndt/SlicerZebrafishEmbryoAnalyzer/main/Documentation_images/gallery.png https://raw.githubusercontent.com/MarkDanielArndt/SlicerZebrafishEmbryoAnalyzer/main/Documentation_images/detail.png https://raw.githubusercontent.com/MarkDanielArndt/SlicerZebrafishEmbryoAnalyzer/main/Documentation_images/setup_dialog.png https://raw.githubusercontent.com/MarkDanielArndt/SlicerZebrafishEmbryoAnalyzer/main/Documentation_images/manual_correction.png")
set(EXTENSION_DEPENDS "NA")
set(EXTENSION_DEPENDS "PyTorch")

find_package(Slicer REQUIRED)
include(${Slicer_USE_FILE})
Expand Down
31 changes: 26 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,14 +74,35 @@ On first open you will be prompted to install:

| Package | Purpose |
|---------|---------|
| `torch`, `torchvision`, `timm`, `segmentation-models-pytorch` | ML inference |
| `opencv-python`, `scipy`, `scikit-image`, `pillow` | Image processing |
| `openpyxl`, `matplotlib` | Export |
| `numpy<2` | Pinned for torch compatibility |
| `platformdirs` | Cache path lookup (soft dependency, falls back gracefully) |
| `torch`, `torchvision` | ML inference — installed through the PyTorch extension, not by this one |
| `segmentation-models-pytorch`, `timm` | Segmentation models |
| `scikit-image`, `opencv-python-headless` | Image processing |
| `huggingface_hub` | Model download |
| `openpyxl` | Excel export |
| `pytesseract` | Scale bar text recognition |

Nothing else is installed. `numpy`, `scipy`, `pillow` and `matplotlib` are used but
ship with Slicer's Python, so the extension never touches them.

Torch comes from the PyTorch extension so that the build matching your hardware
(CUDA, MPS or CPU) is selected, and so that any platform-specific constraints are
applied by the extension that owns them rather than by us. If the PyTorch extension
is not installed yet, it is installed first; Slicer then needs a restart before torch
itself can follow, and the remaining packages are installed on that next run.

Total download is several GB (PyTorch alone ~2 GB). Takes several minutes.

### A note on NumPy for macOS users

The newest PyTorch build available for macOS is 2.2, which is compiled against the NumPy 1
C API. The PyTorch extension therefore holds NumPy below 2 on that platform, and the
remaining packages are installed in the same step so that pip picks versions that fit.
On Linux and Windows a current PyTorch is used and NumPy is left alone.

During installation pip prints a warning that `pyjpegls` requires `numpy>=2.0`. This is a
metadata-level conflict only — `pyjpegls`, which Slicer ships for JPEG-LS DICOM decoding,
was verified to work with NumPy 1.26.

<img src="Documentation_images/setup_dialog.png" width="500" alt="Setup dialog showing packages and optional model download">

You can also pre-download models here to skip the prompt on first run.
Expand Down
Binary file modified ZebrafishEmbryoAnalyzer/Resources/Icons/ZebrafishEmbryoAnalyzer.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 5 additions & 1 deletion ZebrafishEmbryoAnalyzer/Testing/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,13 @@ set(KIT_PYTHON_SCRIPTS

set(KIT_PYTHON_RESOURCES)

# The script path must be absolute. slicer_add_python_unittest derives the directory it
# puts on sys.path from SCRIPT, and only falls back to CMAKE_CURRENT_SOURCE_DIR when that
# directory comes out empty. A relative "Python/..." yields the bare relative "Python",
# which is not empty, so the fallback is skipped and the test module cannot be imported.
foreach(script ${KIT_PYTHON_SCRIPTS})
slicer_add_python_unittest(
SCRIPT ${script}
SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/${script}
SLICER_ARGS --disable-cli-modules
)
endforeach()
9 changes: 7 additions & 2 deletions ZebrafishEmbryoAnalyzer/ZebrafishEmbryoAnalyzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class ZebrafishEmbryoAnalyzer(ScriptedLoadableModule):
def __init__(self, parent):
ScriptedLoadableModule.__init__(self, parent)
self.parent.title = "Zebrafish Embryo Analyzer"
self.parent.categories = ["Quantification"]
self.parent.categories = ["Analysis"]
self.parent.dependencies = []
self.parent.contributors = ["Jona Richter", "Mark Daniel Arndt"]
self.parent.helpText = (
Expand Down Expand Up @@ -107,7 +107,12 @@ def enter(self):
self.initializeParameterNode()
if self._main is not None:
self._main.apply_shell_layout()
self._main.prompt_install_if_missing()
# Refreshes the in-panel notice about missing packages. Deliberately not a
# dialog: opening the module must not interrupt, and browsing results of an
# existing scene needs none of the packages. But the user has to learn about a
# pending install before loading images and setting parameters, so the notice
# is updated here. Each action that needs packages still checks for itself.
self._main.refresh_dependency_status()

def exit(self):
if self._main is not None:
Expand Down
Loading
Loading