# brainvisa-soma -- the core of the BrainVISA neuroimaging suite: the AIMS # image, mesh and graph libraries with their ~220 command-line tools, soma-io # (file I/O: NIfTI, GIFTI, DICOM, MINC, OpenSlide, ...), the pyaims Python # bindings, the soma-base Python core, and the brainvisa-share templates and # models. Upstream ships this group as one conda package, "soma"; Anatomist, # Axon and Morphologist build on it. # # Layout facts the spec depends on (checked against the pinned commits): # - Five repositories, one build. aims-free finds soma-io and soma-base with # find_package() against the build tree, so they cannot be built and # installed one by one; upstream's bv_maker builds them in one CMake tree # from brainvisa-cmake's brainvisa-compilation.cmake with a bv_maker.cmake # cache listing the components. %%build writes those two files itself. # - The pins are the soma-env 6.0 branch's (conf/sources.d/soma-env.json on # brainvisa/soma-env@6.0), the commits BrainVISA 6.0.x is built from; all are # dated 2026-08-06. No 6.0 tags exist. # - BrainVISA's own build pins NumPy < 2 and uses clang; this is GCC 16 and # NumPy 2.4, hence Patch0 (two GCC 15/16 errors, the NumPy 2 symbol export, # empty-vector reads, and PyWeakref_GetRef for Python 3.15). # - Install goes through the install-runtime / install-dev targets with # BRAINVISA_INSTALL_PREFIX; libraries go to a hardcoded "lib" (about 40 # install rules) and are moved to %%{_libdir} afterwards. # - aims-free is a cleaned tarball without the nonfree ECAT library; see # brainvisa-soma-clean.sh and BUILD_ECAT=OFF below. # - Morphologist's image-processing core (VIP, morphologist-nonfree) is # "Proprietary-NeuroSpin" and is not part of this or any free package. %global bvver 6.0 %global snapdate 20260806 %global somabase_c 857c294babe65605d7d08d38584662f93a9020f7 %global somaio_c 7bf16700b33125dbe2473c6ac2d8794b2699b69b %global aimsfree_c 9ea2121280033e60bdaabe487dc9efa762d853e2 %global aimsgpl_c 333d6d9fec7016aec434833089613edbf0b321aa %global share_c e86e904c54f74176245f533e0e35a8f059bb3d05 %global aimsfree_s %(c=%{aimsfree_c}; echo ${c:0:7}) %global pyreldir %(echo %{python3_sitearch} | sed 's|^%{_prefix}/||') Name: brainvisa-soma Version: 6.0.20^%{snapdate}git%{aimsfree_s} Release: 6%{?dist} Summary: BrainVISA core: AIMS image libraries, tools and Python bindings # CeCILL-B: soma-base, soma-io, aims-free, brainvisa-share. # CECILL-2.1: aims-gpl and aims-free's aimscifti. # Bundled third-party code (see the Provides below): CiftiLib BSD-2-Clause, # RPly MIT, nifticlib/znzlib LicenseRef-Fedora-Public-Domain. The bundled # libkdtree++ is removed in %%prep; Fedora's libkdtree++ is used instead. License: CECILL-B AND CECILL-2.1 AND BSD-2-Clause AND MIT AND LicenseRef-Fedora-Public-Domain URL: https://brainvisa.info/ Source0: https://github.com/populse/soma-base/archive/%{somabase_c}/soma-base-%{somabase_c}.tar.gz Source1: https://github.com/brainvisa/soma-io/archive/%{somaio_c}/soma-io-%{somaio_c}.tar.gz # NOT an upstream tarball: brainvisa-soma-clean.sh removes the nonfree ECAT # library (University of Louvain: non-commercial use only, no modified # redistribution). Published in this project's COPR dist-git lookaside, which # is public and content-addressed by md5, as for invesalius and opencv. %global copr_lookaside https://copr-dist-git.fedorainfracloud.org/repo/pkgs/mhough/neurofedora/%{name} %global aimsfree_md5 490f433ed6eac20bf0d15694e636ada5 Source2: %{copr_lookaside}/aims-free-clean-%{aimsfree_s}.tar.xz/md5/%{aimsfree_md5}/aims-free-clean-%{aimsfree_s}.tar.xz Source3: https://github.com/brainvisa/aims-gpl/archive/%{aimsgpl_c}/aims-gpl-%{aimsgpl_c}.tar.gz Source4: https://github.com/brainvisa/brainvisa-share/archive/%{share_c}/brainvisa-share-%{share_c}.tar.gz Source10: brainvisa-soma-clean.sh # aims-free (branch fedora-gcc16-fixes, submitted upstream by the packager, # without its hunk for ecat/, which the cleaned tarball does not contain): # - greyLevelBlob other.node -> other._node (GCC 15 template-body check); # - export the NumPy C-API table from libpyaims (NumPy 2 hides it); # - mesh and FreeSurfer surface I/O took &v[0] of possibly empty vectors, # which aborts under _GLIBCXX_ASSERTIONS (writing a mesh without normals). Patch0: brainvisa-aims-fedora-fixes.patch # soma-io (submitted upstream by the packager): # - DcmCodec::decodedBitsAllocated for the JPEG 2000 codecs (DCMTK 3.7); # - fostreambuf asserted on a nonexistent member (hidden by NDEBUG upstream); # - the NIfTI reader indexed one past the end of its buffer: every NIfTI read # aborted under _GLIBCXX_ASSERTIONS, Fedora's default; # - the MINC checker lacked . Patch1: brainvisa-soma-io-fedora-fixes.patch # aims-gpl: import aims.sip after the Qt modules in the aimsgui bindings; # SIP 6.17 (rawhide) otherwise rejects PyQt6's %MinimumABIVersion. Patch2: brainvisa-aims-gpl-fedora-fixes.patch # -2 finds the system libkdtree++ (FindLibKDTree looked in the wrong place). BuildRequires: brainvisa-cmake >= 6.0.0^20260918git850b6f3-3 BuildRequires: cmake BuildRequires: make BuildRequires: gcc-c++ BuildRequires: gcc-gfortran BuildRequires: python3-devel BuildRequires: python3-numpy BuildRequires: python3-pyyaml BuildRequires: python3-dateutil # soma-base and brainvisa-share import six (about 70 modules, and a build # script); f44/f45 pulled it in indirectly, rawhide does not. BuildRequires: python3-six BuildRequires: sip6 BuildRequires: python3-pyqt6-devel BuildRequires: python3-pyqt6-sip BuildRequires: qt6-qtbase-devel BuildRequires: qt6-qt5compat-devel BuildRequires: qt6-qttools-devel BuildRequires: blitz-devel BuildRequires: libsigc++20-devel BuildRequires: boost-devel BuildRequires: libxml2-devel # DCMTK 3.7 from this COPR; Patch1 also keeps 3.6 working. BuildRequires: dcmtk-devel BuildRequires: openjpeg-devel BuildRequires: libtiff-devel BuildRequires: jasper-devel BuildRequires: openslide-devel BuildRequires: hdf5-devel BuildRequires: libminc-devel BuildRequires: libkdtree++-devel BuildRequires: libtirpc-devel BuildRequires: expat-devel BuildRequires: libpng-devel BuildRequires: libjpeg-turbo-devel BuildRequires: zlib-devel BuildRequires: pkgconf-pkg-config %description The core of the BrainVISA neuroimaging suite: the AIMS libraries for images, meshes, textures and graphs, their command-line tools, the soma-io file format layer (NIfTI, GIFTI, DICOM, MINC, OpenSlide and more), the pyaims Python bindings and the soma-base Python core. Anatomist, Axon and Morphologist are built on it. The ECAT PET file format is not supported: the library it needs is not free software. %package -n brainvisa-aims Summary: AIMS neuroimaging libraries and command-line tools Requires: brainvisa-share = %{version}-%{release} Provides: bundled(ciftilib) = 1.5.1 Provides: bundled(rply) = 1.1.1 Provides: bundled(nifticlib) %description -n brainvisa-aims AIMS (Analysis of Images and Meshes Software) is the C++ library and toolset at the core of BrainVISA: volumes, meshes, textures, graphs and transforms, with readers and writers for the common neuroimaging formats, image processing and resampling algorithms, and about 220 command-line tools (AimsFileInfo, AimsApplyTransform, AimsThreshold, ...). %package -n brainvisa-aims-devel Summary: Development files for the AIMS libraries Requires: brainvisa-aims%{?_isa} = %{version}-%{release} Requires: brainvisa-cmake # What the installed CMake configs find_package() as REQUIRED (soma-io, # aims-free), and the headers the AIMS headers include. Requires: libsigc++20-devel Requires: libxml2-devel Requires: boost-devel Requires: blitz-devel Requires: libkdtree++-devel Requires: qt6-qtbase-devel %description -n brainvisa-aims-devel Headers, libraries and CMake configuration for building software, such as Anatomist, against AIMS and soma-io. %package -n python3-brainvisa-aims Summary: Python bindings for AIMS (soma.aims) Requires: brainvisa-aims%{?_isa} = %{version}-%{release} Requires: python3-soma-base%{?_isa} = %{version}-%{release} Requires: python3-numpy Requires: python3-pyqt6 %description -n python3-brainvisa-aims pyaims, the Python bindings for AIMS: read, write and process volumes, meshes, textures and graphs from Python as NumPy arrays (soma.aims, soma.aimsalgo). %package -n python3-soma-base Summary: Python core of the BrainVISA/populse suites (soma package) Requires: python3-six Requires: python3-pyyaml %description -n python3-soma-base soma-base, the common Python layer of BrainVISA and populse: controllers, configuration, file-organisation models, subprocess and archive helpers. %package -n brainvisa-share Summary: Templates, atlases and models shared by BrainVISA tools BuildArch: noarch %description -n brainvisa-share Anatomical templates, standard meshes, nomenclatures, colour tables and models used by AIMS, Anatomist and Morphologist. %prep %setup -q -c -T tar -xzf %{SOURCE0} && mv soma-base-%{somabase_c} soma-base tar -xzf %{SOURCE1} && mv soma-io-%{somaio_c} soma-io tar -xJf %{SOURCE2} && mv aims-free-%{aimsfree_c} aims-free tar -xzf %{SOURCE3} && mv aims-gpl-%{aimsgpl_c} aims-gpl tar -xzf %{SOURCE4} && mv brainvisa-share-%{share_c} brainvisa-share test ! -e aims-free/ecat %patch -P0 -p1 -d aims-free %patch -P1 -p1 -d soma-io %patch -P2 -p1 -d aims-gpl # Use Fedora's libkdtree++ (header-only), not the older bundled copy; with # the bundled one brainvisa-aims-devel installed /usr/include/kdtree++ and # conflicted with libkdtree++-devel. rm -r aims-free/aimsdata/src/aimsdata/kdtree++ %build %set_build_flags mkdir -p bvbuild cd bvbuild # What bv_maker writes for a combined build (brainvisa_cmake/build.py). S=$PWD/.. cat > bv_maker.cmake < CMakeLists.txt </dev/null \ | xargs -0r sed -i -e 's|%{_prefix}/lib/|%{_libdir}/|g' -e 's|${prefix}/lib\b|${prefix}/%{_lib}|g' %endif # File lists instead of %%exclude: an excluded ELF file still gets its # build-id link in the excluding package, dangling there. (cd %{buildroot} ls -1d .%{_libdir}/lib*.so.* | sed 's|^\.||' | grep -v '/libpyaims' > %{_builddir}/aims-libs.files echo '%%dir %{python3_sitearch}/soma' > %{_builddir}/soma-base.files ls -1d .%{python3_sitearch}/soma/* | sed 's|^\.||' | grep -vE '/soma/(aims|aimsalgo|__pycache__)$' >> %{_builddir}/soma-base.files # Byte-compilation runs after %%install, so name its directory now. echo '%{python3_sitearch}/soma/__pycache__/' >> %{_builddir}/soma-base.files) %check export LD_LIBRARY_PATH=%{buildroot}%{_libdir} export PATH=%{buildroot}%{_bindir}:$PATH export PYTHONPATH=%{buildroot}%{python3_sitearch} export BRAINVISA_SHARE=%{buildroot}%{_datadir} # No ECAT anywhere. ! ls %{buildroot}%{_bindir} | grep -q -E '^(Ecat|AimsFovSplit|AimsSumPETFrame)' ! ls %{buildroot}%{_libdir} | grep -q -i ecat # Round trips under Fedora's flags (_GLIBCXX_ASSERTIONS caught two # out-of-range reads upstream does not see): volumes through NIfTI and the # AIMS GIS format, a mesh without normals or textures through GIFTI, PLY and # the AIMS mesh format, and a tool reading the result. %{python3} -W ignore - <<'EOF' import numpy as np, tempfile, os, subprocess from soma import aims d = tempfile.mkdtemp() v = aims.Volume(np.arange(4 * 5 * 6, dtype=np.int16).reshape(4, 5, 6)) v.header()['voxel_size'] = [1.5, 2.0, 2.5] for ext in ('.nii', '.nii.gz', '.ima'): f = os.path.join(d, 'v' + ext) aims.write(v, f) w = aims.read(f) assert np.array_equal(np.asarray(w)[..., 0], np.asarray(v)[..., 0]), ext assert np.allclose(list(w.header()['voxel_size'])[:3], [1.5, 2.0, 2.5]), ext m = aims.SurfaceGenerator.sphere(aims.Point3df(0, 0, 0), 10., 50) for ext in ('.gii', '.ply', '.mesh'): f = os.path.join(d, 'm' + ext) aims.write(m, f) assert len(aims.read(f).vertex()) == len(m.vertex()), ext info = subprocess.run(['AimsFileInfo', '-i', os.path.join(d, 'v.nii.gz')], capture_output=True, text=True, check=True).stdout assert "'sizeX' : 4" in info, info[:400] print('NIfTI, GIS, GIFTI, PLY and mesh round trips; AimsFileInfo reads the result') EOF %files -n brainvisa-aims -f %{_builddir}/aims-libs.files %license aims-free/LICENSE soma-io/LICENSE aims-gpl/LICENSE %doc aims-free/README.md %{_bindir}/* %{_datadir}/aims-%{bvver}/ %{_datadir}/aims-free-%{bvver}/ %{_datadir}/aims-gpl-%{bvver}/ %{_datadir}/soma-io-%{bvver}/ %{_datadir}/graph-%{bvver}/ %exclude %{_datadir}/*/cmake %files -n brainvisa-aims-devel %{_includedir}/* %{_libdir}/lib*.so %{_libdir}/pkgconfig/* %{_datadir}/*/cmake %files -n python3-brainvisa-aims %{_libdir}/libpyaims*.so.* %{python3_sitearch}/soma/aims/ %{python3_sitearch}/soma/aimsalgo/ %{python3_sitearch}/aims/ %{python3_sitearch}/brainvisa_share/ %files -n python3-soma-base -f %{_builddir}/soma-base.files %license soma-base/README.md %{_datadir}/soma-base-%{bvver}/ %files -n brainvisa-share %license brainvisa-share/LICENCE %{_datadir}/brainvisa-share-%{bvver}/ %changelog * Thu Oct 15 2026 Morgan Hough - 6.0.20^20260806git9ea2121-6 - libaimsdata exports the graph reader/writer ObjectWrapper members: they were explicitly instantiated only on macOS, and GCC's LTO dropped the implicit instances, so libanatomist failed to link (fifth aims-free commit). Build against brainvisa-cmake -3. * Thu Oct 15 2026 Morgan Hough - 6.0.20^20260806git9ea2121-5 - Build against Fedora's libkdtree++: the bundled copy is removed, and brainvisa-aims-devel no longer ships /usr/include/kdtree++ (it conflicted with libkdtree++-devel). Needs brainvisa-cmake -2. - brainvisa-aims-devel requires the -devel packages its CMake configs need (sigc++, libxml2, Boost, blitz, libkdtree++, Qt 6); found configuring Anatomist against the installed tree. * Thu Oct 15 2026 Morgan Hough - 6.0.20^20260806git9ea2121-4 - SIP 6.17 (rawhide): the aimsgui bindings imported aims.sip before the Qt modules, so PyQt6's %MinimumABIVersion came too late and sip-build failed. Patch2 (aims-gpl, on an upstream branch) imports Qt first. * Thu Oct 15 2026 Morgan Hough - 6.0.20^20260806git9ea2121-3 - BuildRequires and Requires python3-six (rawhide no longer pulls it in); python3-soma-base also requires the PyYAML it imports (soma.fom). * Thu Oct 15 2026 Morgan Hough - 6.0.20^20260806git9ea2121-2 - Python 3.15 (Fedora 45 and rawhide): pyaims used PyWeakref_GetObject, removed in 3.15; use PyWeakref_GetRef, owning the reference (also fixes a leaked weak reference on resize). Submitted upstream with the others. * Thu Oct 15 2026 Morgan Hough - 6.0.20^20260806git9ea2121-1 - Initial package: AIMS, soma-io, aims-gpl, soma-base and brainvisa-share built together at the soma-env 6.0 pins, with Qt 6, SIP 6, NumPy 2 and DCMTK 3.7. ECAT support removed (nonfree library, cleaned tarball). MINC support through Fedora's libminc. Seven fixes submitted upstream, two of them out-of-range reads that abort every NIfTI read and mesh write under Fedora's hardening flags.