# SlicerTotalSegmentator — fully automatic whole-body/organ CT (and more) # segmentation in 3D Slicer using the TotalSegmentator nnU-Net AI models. # PURE-SCRIPTED (Python) module: replicate slicerMacroBuildScriptedModule (drop # the module + resources into qt-scripted-modules), no find_package(Slicer), no # foundation -devel. The runtime (torch, nnunetv2, TotalSegmentator) is the packaged # python3-torch / python3-nnunetv2 / python3-totalsegmentator plus the 3dslicer-pytorch # and 3dslicer-nnunet extensions; Patch0 stops the module pip-installing them at first # use (the pattern of 3dslicer-nnunet). Small noarch package. # # This is the agent-drivable AI segmentation: an LLM agent can invoke it through # the Slicer Web Server (see python3-mcp-slicer). %global commit 519af9cbd306a35c87b7d804350d3343b200cd2e %global shortcommit %(c=%{commit}; echo ${c:0:8}) %global snapdate 20260528 %global slicer_inst %{_prefix}/lib/slicer %global slicer_subdir Slicer-5.12 %global qtsm %{slicer_inst}/lib/%{slicer_subdir}/qt-scripted-modules Name: 3dslicer-totalsegmentator Version: 1.0 Release: 0.8.%{snapdate}git%{shortcommit}%{?dist} Summary: TotalSegmentator automatic AI segmentation extension for 3D Slicer License: Apache-2.0 URL: https://github.com/lassoan/SlicerTotalSegmentator Source0: %{url}/archive/%{commit}/SlicerTotalSegmentator-%{shortcommit}.tar.gz # Use the packaged runtime; never pip-install (see the patch header). Patch0: 3dslicer-totalsegmentator-fedora-packages.patch # %%check compiles the module with %%{python3}; a noarch scripted module pulls in no Python otherwise. BuildRequires: python3 BuildArch: noarch Requires: 3dslicer # Scripted modules need the bug#9 scriptability layer to load. Requires: ctk-python Requires: python3-vtkAddon # The AI runtime the module used to pip-install (Patch0), and the two extensions it # imports (PyTorchUtils, SlicerNNUNetLib). Requires: python3-totalsegmentator Requires: python3-nnunetv2 Requires: python3-torch Requires: python3-pandas Requires: python3-dicom2nifti Requires: 3dslicer-pytorch Requires: 3dslicer-nnunet %description SlicerTotalSegmentator brings fully automatic AI segmentation to 3D Slicer using the TotalSegmentator nnU-Net models (whole-body CT organs, vertebrae, ribs, cardiac/muscle/vessel structures, and more). The AI runtime (torch, nnunetv2, TotalSegmentator) comes from the python3-torch, python3-nnunetv2 and python3-totalsegmentator packages; unlike upstream, this module never pip-installs anything. Model weights are downloaded by TotalSegmentator on first use. Because it runs in Slicer's Python, it can be driven by an LLM agent through the Slicer Web Server interface (see python3-mcp-slicer). %prep %autosetup -n SlicerTotalSegmentator-%{commit} -p1 %build # Pure-scripted: nothing to compile. %install mkdir -p %{buildroot}%{qtsm}/Resources/Icons mkdir -p %{buildroot}%{qtsm}/Resources/UI install -m0644 TotalSegmentator/TotalSegmentator.py %{buildroot}%{qtsm}/ install -m0644 TotalSegmentator/Resources/*.csv TotalSegmentator/Resources/*.json \ %{buildroot}%{qtsm}/Resources/ install -m0644 TotalSegmentator/Resources/UI/*.ui %{buildroot}%{qtsm}/Resources/UI/ install -m0644 TotalSegmentator/Resources/Icons/*.png %{buildroot}%{qtsm}/Resources/Icons/ %check # The module must compile, and the Fedora block that replaces pip must be in the # installed file (a silently un-applied patch would bring the pip path back). # ast.parse, not py_compile: py_compile writes __pycache__ into the buildroot, which rpm # then reports as an unpackaged file (0.7, 11188468). %{python3} -c 'import ast, sys; ast.parse(open(sys.argv[1], encoding="utf-8").read(), sys.argv[1])' %{buildroot}%{qtsm}/TotalSegmentator.py grep -q "this module never pip-installs" %{buildroot}%{qtsm}/TotalSegmentator.py # Nothing reachable may still call pip_install: every remaining call sits after the # early return in setupPythonRequirements or in pipInstallSelective, which only that # function called. Guard the count so an upstream rebase that adds a new caller shows up. # (Six after Patch0 at 519af9cb: one in pipInstallSelective, five in setupPythonRequirements.) n=$(grep -c "slicer.util.pip_install\|slicer.util.pip_uninstall" %{buildroot}%{qtsm}/TotalSegmentator.py) test "$n" -eq 6 || { echo "ERROR: $n pip_install/pip_uninstall calls, expected 6; re-check Patch0" >&2; exit 1; } %files %license LICENSE %doc README.md # Individual files dropped into the shared qt-scripted-modules / Resources dirs # (owned by the 3dslicer package); nothing TotalSegmentator-specific to %%dir-own. %{qtsm}/TotalSegmentator.py %{qtsm}/Resources/totalsegmentator_snomed_mapping.csv %{qtsm}/Resources/SegmentationCategoryTypeModifier-TotalSegmentator.term.json %{qtsm}/Resources/UI/TotalSegmentator.ui %{qtsm}/Resources/Icons/TotalSegmentator.png %changelog * Thu Oct 22 2026 Morgan Hough - 1.0-0.8.20260528git519af9cb - %%check: syntax-check with ast.parse instead of py_compile, which wrote __pycache__/TotalSegmentator.cpython-314.pyc into the buildroot and failed 0.7 as an unpackaged file on every chroot (11188468). * Thu Oct 22 2026 Morgan Hough - 1.0-0.7.20260528git519af9cb - %%check: the patched module has six pip_install/pip_uninstall calls, not seven; 0.6 failed its own count guard on every chroot (11187696). Verified by applying Patch0 to the pristine tarball. * Thu Oct 22 2026 Morgan Hough - 1.0-0.6.20260528git519af9cb - BuildRequires: python3 for the new %%check; 0.5 failed on every chroot with "/usr/bin/python3: No such file or directory" (11187545). * Thu Oct 22 2026 Morgan Hough - 1.0-0.5.20260528git519af9cb - Patch0: use the packaged runtime; setupPythonRequirements() only checks that torch, nnunetv2, totalsegmentator, pandas, dicom2nifti, PyTorchUtils and SlicerNNUNetLib import and names the missing RPMs, instead of pip-installing into Slicer's Python at first use. Requires on those packages and on 3dslicer-pytorch and 3dslicer-nnunet. The TotalSegmentator scripts are found in /usr/bin, with sys.executable when PythonSlicer is not on PATH. %%check compiles the module and asserts the patch is in. This was the one AI extension still installing with pip (readiness review 2026-10-22). * Fri Sep 25 2026 Morgan Hough - 1.0-0.4.%%{snapdate}git%%{shortcommit} - Release 0.2 -> 0.4, to get git back ahead of the repo. f44 (both arches) serves 0.3 while git says 0.2, so any rebuild from git produced 0.4-less-than-0.3 and superseded nothing -- the package could not be updated on f44 at all. - No content to recover. The published 0.3 SRPM differs from git by exactly TWO LINES, the Release itself: someone bumped to 0.3, built it on f44, and the bump never reached git. Verified by fetching the 0.3 SRPM and diffing, for all three extensions, rather than assuming a lost spec revision. - Skips 0.3 deliberately: a 0.3 here would tie the published f44 builds rather than beat them, and COPR then adds a sibling at an existing NVR while dnf serves the oldest. - Found by rpi-the-great while reconciling the f45 arch gap; same class as mrtrix3 and ANTs3. * Wed Jul 22 2026 Morgan Hough - 1.0-0.2.20260528git519af9cb - Retarget from Slicer-5.11 to Slicer-5.12 core (3dslicer 5.12.1); bump 3dslicer-devel floor to 5.12.1. * Tue Jun 16 2026 Morgan Hough - 1.0-0.1.20260528git519af9cb - Initial package. SlicerTotalSegmentator as a pure-scripted 3D Slicer extension: install the TotalSegmentator module + resources into qt-scripted-modules, no compilation / no foundation -devel. The torch/TotalSegmentator AI runtime is pip-installed by the module on first use, not packaged.