# TIRL, the Tensor Image Registration Library (FMRIB/Oxford, by Istvan Huszar; Python plus two Cython extensions; histology-to-MRI and general # image registration). FMRIB's FSL installer ships it as conda package fsl-tirl 3.6.3; not in Fedora. # # SOURCE: FMRIB publishes no 3.6.3 tag. Its project page (git.fmrib.ox.ac.uk/fsl/tirl) says development moved to GitHub (tirlworks/tirl, not # reachable), and its tags stop at 3.6.2; but the author's own repository, git.fmrib.ox.ac.uk/ihuszar/tirl (public, branch master), is three commits # past 3.6.2 and its master (commit 9b57d75, 2024-05-03) is what FSL ships: diffing FMRIB's installed 3.6.3 against that commit shows 82 files # differing ONLY in the licence-header substitution plus __version__ "3.6.2" -> "3.6.3" and __license__ "FSL" -> "ApacheV2". %prep applies those # two label changes. Licence is Apache-2.0 (LICENSE in the source and in FMRIB's install; conda metadata says "FSL"). The extensions link only # LAPACK/BLAS, so this lives in the FREE project. # # Patch0 ports it to NumPy 2: FMRIB's own shipped 3.6.3 fails on their bundled NumPy 2.4.6 (TImage creation, finv.invert). Patch1 drops setup.py's # install-time write into the installing user's ~/.config and its build-time import of tirl. %global commit 9b57d75ad23588936abaee8184b4528ad4e272cb %global pypi_name tirl %global tirl_requires python3-numpy python3-scipy python3-attrdict3 python3-dask python3-dill python3-imagecodecs python3-imageio python3-joblib python3-matplotlib python3-nibabel python3-nlopt python3-numba python3-opencv python3-openslide python3-pillow python3-psutil python3-pygments python3-dateutil python3-pyyaml python3-scikit-image python3-scikit-learn python3-simpleitk python3-threadpoolctl python3-tifffile Name: python-%{pypi_name} Version: 3.6.3 Release: 1%{?dist} Summary: TIRL - Tensor Image Registration Library License: Apache-2.0 URL: https://git.fmrib.ox.ac.uk/ihuszar/tirl Source0: https://git.fmrib.ox.ac.uk/ihuszar/tirl/-/archive/%{commit}/tirl-%{commit}.tar.gz Patch0: python-tirl-numpy2.patch Patch1: python-tirl-setup.patch BuildRequires: python3-devel BuildRequires: gcc BuildRequires: gcc-c++ BuildRequires: gcc-gfortran BuildRequires: lapack-devel BuildRequires: blas-devel BuildRequires: python3-Cython BuildRequires: %{tirl_requires} %global _description %{expand: TIRL registers images in arbitrary dimensions with linear and nonlinear transformations (including displacement fields and their inversion), tensor and scalar images, many cost functions and optimisers, with a TImage/TField data model. Includes FSLInterpolator, a Cython port of FLIRT's trilinear interpolation, and a field-inversion extension.} %description %_description %package -n python3-%{pypi_name} Summary: %{summary} Requires: %{tirl_requires} %description -n python3-%{pypi_name} %_description %prep %autosetup -p1 -n tirl-%{commit} # the release labelling FMRIB's FSL build applies to this commit (see the header): version and licence string only grep -q '^__version__ = "3.6.2"' tirl/__init__.py sed -i 's/^__version__ = "3.6.2"/__version__ = "%{version}"/' tirl/__init__.py grep -q '^__license__ = "FSL"' tirl/__init__.py sed -i 's/^__license__ = "FSL"/__license__ = "ApacheV2"/' tirl/__init__.py head -1 tirl/tirl | grep -q '^#!' %py3_shebang_fix tirl/tirl %generate_buildrequires %pyproject_buildrequires %build %pyproject_wheel %install %pyproject_install %pyproject_save_files tirl %check %pyproject_check_import # upstream ships no tests. Known-answer checks of what the NumPy 2 port touches, against the installed tree. export PYTHONPATH=%{buildroot}%{python3_sitearch} %{python3} -sP - <<'PY' import numpy as np, warnings, pkgutil, importlib warnings.simplefilter("ignore") import tirl # 1. FSLInterpolator: trilinear interpolation of a linear function is exact in the interior (it returns 0 on the last voxel index, like FLIRT) from tirl.cmodules.fslinterpolator import fslinterpolator i, j, k = np.meshgrid(np.arange(4), np.arange(5), np.arange(6), indexing="ij"); d = (2*i + 3*j + 5*k + 1).astype(np.float32) c = np.array([[1.5, 2.25, 3.75], [0, 0, 0], [2.9, 3.1, 4.2]], np.float32) got = np.asarray(fslinterpolator(d, c)); want = 2*c[:, 0] + 3*c[:, 1] + 5*c[:, 2] + 1 assert np.allclose(got, want, atol=1e-3), (got, want) # 2. field inversion: the inverse of a constant displacement (1, 0.5) is (-1, -0.5) (np.product in finv.pyx broke this on NumPy 2) from tirl.cmodules.finv import invert n = 8; g = np.stack(np.meshgrid(np.arange(n), np.arange(n), indexing="ij")).reshape(2, -1).T.astype(float) field = np.zeros((2, n, n)); field[0] = 1.0; field[1] = 0.5 out = np.asarray(invert(np.array([[3.0, 3.0], [4.0, 2.0]]), field, g)) assert np.allclose(out, [[-1, -1], [-0.5, -0.5]], atol=1e-6), out # 3. image construction and round trip (np.float_ default dtype and can_cast on a Python int broke this on NumPy 2) from tirl.timage import TImage a = np.arange(20, dtype=np.float32).reshape(4, 5); im = TImage(a) assert np.array_equal(np.asarray(im.data), a) and tuple(im.vshape) == (4, 5) # 4. every module imports bad = [] for m in pkgutil.walk_packages(tirl.__path__, "tirl."): try: importlib.import_module(m.name) except BaseException as e: bad.append((m.name, repr(e)[:80])) assert not bad, bad assert tirl.__version__ == "%{version}", tirl.__version__ print("tirl known-answer checks passed;", len(list(pkgutil.walk_packages(tirl.__path__, "tirl."))), "modules import") PY # a build must not write into the builder's home (upstream's setup.py used to copy tirl.yml there) test ! -e "$HOME/.config/tirl.yml" %files -n python3-%{pypi_name} -f %{pyproject_files} %license LICENSE NOTICE %doc README.md CHANGELOG.md ISSUES.txt tirl.yml tirlscripts.yml %{_bindir}/tirl %changelog * Fri Oct 09 2026 Morgan Hough - 3.6.3-1 - Rebase on the source FSL actually ships: the author's repository git.fmrib.ox.ac.uk/ihuszar/tirl at commit 9b57d75 (2024-05-03), whose files differ from FMRIB's installed tirl 3.6.3 only in the licence-header substitution (82 files) and __version__/__license__. This supersedes 3.6.2-1, which was built from the fsl/tirl mirror because no 3.6.3 source had been found; the earlier note that 3.6.3 had no public source was wrong about where to look. - Patch1 (setup.py): do not import tirl at build time and do not copy tirl.yml/tirlscripts.yml into the builder's ~/.config; both ship as %%doc. - %%check also asserts the version and that the build wrote nothing under $HOME/.config. * Fri Oct 09 2026 Morgan Hough - 3.6.2-1 - Initial package: TIRL 3.6.2 from FMRIB's GitLab mirror (the newest tag it publishes), with Patch0 porting it to NumPy 2 (np.product -> np.prod, np.float_ -> np.float64, np.complex -> complex, np.bool -> bool, np.in1d -> np.isin, and domain.py's can_cast(python int, dtype) -> an iinfo bound; 9 files). Unpatched on NumPy 2.4.6: finv.invert raises AttributeError (np.product), TImage(np.zeros((4,4))) raises TypeError (can_cast); patched: both work, field inversion returns the exact negative of a constant displacement, 85 of 85 modules import. - No upstream tests; %%check carries known-answer checks (interpolation exact, field inversion, TImage round trip, all modules import). No registration has been run end to end, so the optimisers and cost functions beyond import are untested.