# hlsvdpropy: a pure-Python implementation of the HLSVDPRO 2.x algorithm (fit of a sum of Lorentzian decaying sinusoids to time-domain MRS data via # a Hankel/SVD state-space method). fsl_mrs imports it for water-peak removal; FMRIB's installer ships it as a conda dependency; not in Fedora. # # SOURCE: GitHub bsoher/hlsvdpropy has no tags. PyPI has only wheels, and the 2.0.2 wheel's __init__.py does 'import pkg_resources' unconditionally, # which current setuptools no longer ships. The repository's master (commit a2d2d778, 2025-03-18, still VERSION 2.0.2) first tries # importlib.metadata, so that commit is packaged. Otherwise the same code: the two files that differ from the wheel differ in __init__.py (that fix) # and line endings (CRLF in the wheel). %global pypi_name hlsvdpropy %global commit a2d2d778e62a02262d7591941946eff076922eb5 Name: python-%{pypi_name} Version: 2.0.2 Release: 1%{?dist} Summary: Pure-Python HLSVDPRO: sum-of-Lorentzians fitting of MRS time-domain data License: BSD-3-Clause URL: https://github.com/bsoher/hlsvdpropy Source0: %{url}/archive/%{commit}/%{pypi_name}-%{commit}.tar.gz BuildArch: noarch BuildRequires: python3-devel BuildRequires: python3-numpy BuildRequires: python3-scipy %global _description %{expand: hlsvdpropy fits a model of decaying sinusoids (a sum of Lorentzians) to complex time-domain signals using the state-space SVD algorithm of Laudadio et al. (J. Magn. Reson. 157, 292, 2002), as implemented in HLSVDPRO 2.x but in pure Python on NumPy and SciPy. It is used in magnetic resonance spectroscopy for removing the water resonance.} %description %_description %package -n python3-%{pypi_name} Summary: %{summary} Requires: python3-numpy Requires: python3-scipy %description -n python3-%{pypi_name} %_description %prep %autosetup -n %{pypi_name}-%{commit} %generate_buildrequires %pyproject_buildrequires %build %pyproject_wheel %install %pyproject_install %pyproject_save_files %{pypi_name} %check %pyproject_check_import # known answer: a noise-free sum of three decaying sinusoids is recovered exactly (frequency in kHz, damping as minus the decay time in ms, amplitude) export PYTHONPATH=%{buildroot}%{python3_sitelib} %{python3} -sP -W error - <<'PY' import numpy as np, hlsvdpropy assert hlsvdpropy.version_method == "importlib", "must not fall back to pkg_resources" assert hlsvdpropy.__version__ == "%{version}", hlsvdpropy.__version__ n, dwell = 512, 0.5 # points, ms t = np.arange(n) * dwell true = {0.30: (20.0, 1.0), -0.45: (15.0, 0.6), 0.10: (40.0, 0.3)} # frequency kHz -> (T2* ms, amplitude) sig = sum(a * np.exp(2j*np.pi*f*t) * np.exp(-t/T) for f, (T, a) in true.items()) nsv, sv, f, damp, amp, ph = hlsvdpropy.hlsvd(sig, 3, dwell) assert nsv == 3, nsv for fi, di, ai, pi in zip(f, damp, amp, ph): key = min(true, key=lambda k: abs(k - fi)) assert abs(key - fi) < 1e-3, (key, fi) assert abs(-di - true[key][0]) < 0.05, (key, di) assert abs(ai - true[key][1]) < 1e-3, (key, ai) assert abs(pi) < 0.1, pi assert sorted(round(x, 2) for x in f) == [-0.45, 0.10, 0.30], f print("hlsvdpropy known-answer check passed") PY %files -n python3-%{pypi_name} -f %{pyproject_files} %license LICENSE %doc README.md NEWS %changelog * Fri Oct 09 2026 Morgan Hough - 2.0.2-1 - Initial package: hlsvdpropy 2.0.2 (repository master a2d2d778, which adds the importlib.metadata path the PyPI 2.0.2 wheel lacks), a dependency of fsl_mrs. Free project (BSD-3-Clause). %%check: exact recovery of three known decaying sinusoids, run with warnings as errors so a pkg_resources fallback fails.