%global pypi_name openlifu Name: python-%{pypi_name} Version: 0.21.1 Release: 1%{?dist} Summary: Openwater Focused Ultrasound Toolkit # The bundled LICENSE is the GNU Affero GPL v3. Note that upstream's own # pyproject.toml classifier says "License :: OSI Approved :: MIT License", # which contradicts it; the sibling SlicerOpenLIFU extension is AGPL-3.0 too, so # the file is taken as authoritative and the classifier as the error. Reported # upstream alongside the numpy cap. License: AGPL-3.0-or-later URL: https://github.com/OpenwaterHealth/OpenLIFU-python Source0: https://files.pythonhosted.org/packages/source/o/%{pypi_name}/%{pypi_name}-%{version}.tar.gz # Upstream caps numpy below 2, which no current Fedora can satisfy. Verified # against numpy 2.4.6 before relaxing it -- see the patch header and # docs/upstream/openlifu-numpy2-cap.md. Patch0: openlifu-numpy2.patch BuildArch: noarch BuildRequires: python3-devel # %%check runs upstream's own suite. BuildRequires: python3-pytest BuildRequires: python3-pytest-mock BuildRequires: python3-nibabel BuildRequires: python3-pydicom BuildRequires: python3-vtk BuildRequires: python3-trimesh BuildRequires: python3-scikit-image BuildRequires: python3-pillow # cv2, for the MODNet image-preprocessing test in tests/test_photoscans.py. BuildRequires: python3-opencv # Optional at runtime, and each unlocks a specific part of the toolkit. They are # Recommends rather than Requires because openlifu imports them lazily, inside # the subpackage that needs them: the core numerical API works without any. Recommends: python3-nibabel Recommends: python3-pydicom Recommends: python3-vtk Recommends: python3-trimesh Recommends: python3-scikit-image Recommends: python3-pillow Recommends: python3-opencv Recommends: python3-watchdog Recommends: python3-socketio %global _description %{expand: openlifu is Openwater's Python toolkit for low-intensity focused ultrasound: transducer and protocol definitions, beam apodisation and delay methods, treatment-plan solution and analysis including time-averaged intensity, tissue segmentation helpers, and a treatment database. It is the library behind the SlicerOpenLIFU 3D Slicer extension.} %description %_description %package -n python3-%{pypi_name} Summary: %{summary} %description -n python3-%{pypi_name} %_description %prep %autosetup -n %{pypi_name}-%{version} -p1 %generate_buildrequires # hatch-vcs derives the version from git, which a PyPI sdist does not carry. export SETUPTOOLS_SCM_PRETEND_VERSION=%{version} %pyproject_buildrequires %build export SETUPTOOLS_SCM_PRETEND_VERSION=%{version} %pyproject_wheel %install export SETUPTOOLS_SCM_PRETEND_VERSION=%{version} %pyproject_install %pyproject_save_files -l %{pypi_name} %check # Excluded: these import optional modules at call time that are not packaged. # openlifu.sim / openlifu.cloud -> k-wave-python (pinned ==0.4.0 upstream), # nvidia-ml-py, python-socketio[client] # openlifu.io -> openlifu-sdk, crc %pyproject_check_import -e 'openlifu.sim*' -e 'openlifu.cloud*' -e 'openlifu.io*' # Upstream's suite, minus the four tests that need modules nothing packages: # k-wave-python (the simulation backend) and the photoscan loaders. Everything # else passes against numpy 2, which is the evidence the cap relaxation rests # on -- 243 passed, 1 skipped when this was verified. # -o filterwarnings=default is load-bearing. Upstream sets # filterwarnings = ["error"], and VTK 9.7 deprecated vtkTransformPolyDataFilter # (openlifu uses it in seg/skinseg.py:42,352 and nav/photoscan.py:221). The # warning is raised inside the C constructor, so turning it into an error # surfaces as "SystemError: ... returned a result with an exception set" and # fails three tests. The class still works in 9.7 -- it is deprecated, not # removed -- so a dependency's deprecation notice must not fail a package build. # This does not show up against Fedora's VTK 9.5; only against the COPR's 9.7. %pytest -o addopts= -o filterwarnings=default tests \ --deselect tests/test_assets.py::test_get_kwave_paths \ --deselect tests/test_sim.py::test_run_simulation_runs \ --deselect tests/test_database.py::test_load_photoscan \ --deselect tests/test_photoscans.py::test_load_photoscan %files -n python3-%{pypi_name} -f %{pyproject_files} %doc README.md %license LICENSE %changelog * Tue Sep 15 2026 Morgan Hough - 0.21.1-1 - Initial package. openlifu is the library behind the SlicerOpenLIFU extension, which currently pip-installs it from inside Slicer on first use (OpenLIFULib/lazyimport.py). Packaging it and python-segno removes that. - Relax upstream's "numpy<2" cap, which no current Fedora can satisfy and which made the pip fallback worse than useless: it would have pulled numpy 1.x into the very Python environment Slicer, VTK and every scripted module share. Tested before relaxing rather than assumed -- upstream's own suite gives 243 passed / 1 skipped / 4 failed against numpy 2.4.6, and all four failures are unpackaged optional modules, not numpy. A module sweep and a scan for numpy-2-removed APIs across all 95 source modules both come back clean. - License taken from the bundled LICENSE (AGPLv3), not from the pyproject classifier, which says MIT and contradicts it. - Do not let upstream's filterwarnings = ["error"] turn VTK 9.7's deprecation of vtkTransformPolyDataFilter into a test failure. openlifu calls that class in three places; it still works in 9.7, but the warning is raised inside the C constructor, so as an error it appears as an opaque SystemError. Invisible against Fedora's VTK 9.5 and only reachable against the COPR's 9.7.