Releases: Deep-MI/WhipperSnapPy
v2.1.0
CPU-based Rendering Support
This release adds EGL CPU rendering (via llvmpipe, "surfaceless") and also osMesa support for older systems. The advantage of EGL over osMesa is that it can do both GPU and CPU off-screen rendering, while osMesa is CPU only (and often osMesa libraries are not installed). This allows rendering without DISPLAY, no xvfb wrappers needed, with or without GPU. Specifically:
- You can render on a workstation via ssh login (no supported DISPLAY, either with GPU acceleration or CPU based)
- You can render in Docker (EGL CPU based or when
--gpus allis passed also with GPU) - You can render in Singularity (same, GPU requires passing
--nv) - You can render off screen in Windows (after installing the necessary dll (see our test CI workflow)
- You can render with DISPLAY and window manager on a Mac (or use a container for complete off-screen)
Note: osMesa might not be supported for very long, it is recommended to use EGL instead.
Together with this upgrade, we changed a few interfaces (breaking full backward-compatibility, in a few places). Since 2.0 was released last week, we think it is not widely adopted yet anyway and therefore proceed to 2.1 instead of 3.0. as the changes are too minor to warrant a major release.
What's Changed
- Add support for EGL CPU-based rendering (llvmpipe MESA) on Linux
- Add OSMesa for CPU rendering on Linux
- Make
get_view_matrixtop level import - In snap1 remove
viewmatparamter and pass it viaview(either a view type or matrix) (! breaks backward compatibility!) - In
snap_rotatealso allow passing a matrix viastart_view - Add
gl/osmesa_context.pyas a drop-in with the same public API (make_current, read_pixels, destroy). Raises a clear RuntimeError with a platform-specific install hint if libOSMesa is not found - Delete
gl/_platform.py— the PYOPENGL_PLATFORM=egl env-var setter is no longer needed - Delete
gl/views.py— redistributed its contents to their natural homes:get_view_matrices/get_view_matrix→utils/types.py(pure numpy, no GL, lives alongsideViewTypewhich it maps over)ViewState,arcball_*,compute_view_matrix→cli/whippersnap.py(only consumer; no reason to be in a shared module)
- Rename
_egl_context→_offscreen_contextin gl/utils.py — the old name was a historical artefact. - Fix
snap4to look like v1 images (slightly enlarge top views, remove padding, center colorbar) - unify parameter names
fthreshandfmax(also inplot3d, breaks backward compatibility) - Fix license syntax in
pyproject.toml - Bump action versions
- Set default visible false for snap functions (don't show on screen), visible window is only for the Qt GUI.
- Refactor some internal files (file names in the gl module and function names).
- Docs: Update README.md, DOCKER.md
- Docker: include only required dependencies and update to allow
--gpus allto run EGL GPU-based also.
CI (pytest.yml):
- Ubuntu installs libegl1 for headless CPU rendering.
- macOS requires a GLFW invisible window backed by GPU drivers (no headless, therefore skipping rendering in CI). If you need headless on Mac, use linux docker.
- Windows: we install the necessary dll and can do offscreen rendering also in CI.
Migration from 2.0 (breaking changes)
- Instead passing
viewmatinsnap1-> migrate to usingview - rename command line and function parameter
brain_scaletoscaleas we plot other geometries, not just brains. - In plot3d use
fthreshinstead ofminvalandfmaxinstead ofmaxvalfor consistency with other methods
Full Changelog: v2.0.0...v2.1.0
v2.0.0
WhipperSnapPy v2.0.0
! This major release breaks backward compatibility !
Migration to v2.0
- CLI Gui users, still use whippersnap (with extended functionality, like mouse navigation and screen shot via "s" key)
- CLI users for snapshots migrate to whippersnap4 for the 2x2 plot of brain surfaces, beware of different parameter names!
- Single view snapshots (snap1) now has its own CLI whippersnap1 and adds option to produce a video of rotating objects.
- New documentation can be found: https://deep-mi.org/whippersnappy
Major Innovations:
- Full support for off screen rendering on headless servers, dockers etc via EGL (no X wrappers needed)
- Complete code refactor and python interface for calling snap functions directly from python or ipynbs
- Function to grab a video of rotating 3d objects with overlays
- plot3d function for interactive rendering (webGL) in iypnb with our professional shaders
- Support of more mesh formats (ascii PLY ,VTK, OFF, gifti) and overlays, look-up-tables
- Updated documentation including a tutorial ipynb and example data (via data-v1.0 release assets)
- Updated Docker makefile for leaner image
Code Refactor
- core.py has been split up into meaningful modules, complete refactoring!
- snap1 and snap4 now always return the image (e.g. for visualisation in notebooks etc)
- logging was introduced instead of print
- errors are raised instead of sys.exit
- Qt6 optional, only needed for GUI CLI whippersnap, nowhere else
- bug fixes in the whippersnap CLI (and other places)
- consistent color overlay scale for snap4 across two semis when thresholds are not specifically provided
- added EGL support for completely headless without display (!! so cool!!)
- improved Docker for headless, no wrapper needed anymore
- refactor function parameter names and allow both strings for filenames and numpy arrays for direct passing
- functions (snap1, snap4, plot3d, CLI) now accept either file paths or numpy arrays for mesh, overlay, bg_map, roi, and annotation inputs.
- can pass a tuple of (vertices, faces) arrays directly instead of a mesh file path
- Mesh inputs now support OFF, VTK, PLY, GIfTI surface files, and FreeSurfer binary surfaces.
- Overlay inputs now support ASCII, NumPy, GIfTI, FreeSurfer morph, and MGH formats.
- Parameter renaming:
-- curvpath/--curv → bg_map/--bg-map
-- labelpath/--label → roi/--roi
-- meshpath/--mesh-path → mesh/--mesh
-- overlaypath/--overlaypath → overlay/--overlay
-- annotpath/--annotpath → annot/--annot
Python Notebooks
- plot3d was added to provide webGL based interactive viewing in ipython notebooks
- added functionality to download and run an example
Command Line Interfaces
- added whippersnap1 CLI for plotting a single mesh with overlays
- added functionality to rotate in whippersnap1 and create a video (!cool!)
- separated existing CLI into GUI (whippersnap) and the snap4 in whippersnap4 (!!<- call this now!!)
- allow CLI whippersnap GUI and other snap1 functions to load any mesh, not only from freesurfer/fastsurfer dirs
- The CLI scripts (whippersnap.py, whippersnap1.py, whippersnap4.py) now use the new parameter names.
Example: --bg-map replaces --curv, --roi replaces --label. - CLI can now load various triangle meshes, not just FreeSurfer surfaces.
GUI
- add mouse navigation for rotate, zoom and pan to GUI
- add snapshot via "s" key to GUI
- make GUI work on Mac
Documentation
- docstrings are added
- added ipynb tutorial, running an example brain downloaded from assets
- updated documentation and sphinx doc build, including rendering of tutorial, including monkeypatch for animated gif
- All code and docs are updated to use the new function and parameter names and input conventions.
Mainly this #57 pull request contains the majority of changes.
Full Changelog: v1.3.1...v2.0.0
Test & tutorial data (Rhineland) — data-v1.0
WhipperSnapPy Test & Tutorial Data v1.0
What this release contains
This is a data-only release. It provides the sample subject data required to run the WhipperSnapPy tutorial notebooks, build the Sphinx documentation with live notebook execution, and run the example tests.
For the WhipperSnapPy code release see the upcoming corresponding v2.0 tag.
Dataset
One anonymized subject from the Rhineland Study, processed with FreeSurfer/FastSurfer. Included files:
- surf/lh.white, surf/rh.white — white matter surface meshes
- surf/lh.curv, surf/rh.curv — mean curvature per vertex
- surf/lh.thickness, surf/rh.thickness — cortical thickness per vertex
- label/lh.cortex.label, label/rh.cortex.label — cortex mask labels
- label/lh.aparc.DKTatlas.mapped.annot, label/rh.aparc.DKTatlas.mapped.annot — DKT parcellation annotations
License
Creative Commons Attribution 4.0 International (CC BY 4.0)
Attribution
If you use this data, please cite:
Koch et al. (2024). Data from: Versatile MRI Acquisition and Processing Protocol for Population-Based Neuroimaging. Zenodo. https://doi.org/10.5281/zenodo.11186582
Usage
Download and unpack the asset archive into your WhipperSnapPy working directory so that the sample subject is accessible at the path expected by the tutorials (see tutorials/). This is however mainly used for the CI to build the tutorial webpage from our ipynb.
v1.3.1
v1.3.0
What's Changed
- Extend functionality for annotation files and flexible surface plotting by @kdiers in #44
- Added vertical colorbar and caption support for snap1 and fixed invisible caption issue by @cryptoradon in #45
- Normalized positioning and scaling by @cryptoradon in #47
- Fixed checks for height, width, and values to display by @kdiers in #49
- Make outpath argument non-optional by @kdiers in #50
New Contributors
Full Changelog: v1.2.0...v1.3.0
v1.2.0
What's Changed
- Autogenerated doc files as per LaPy method by @engrosamaali91 in #23
- gitaction local run by @agirodi in #28
- stop requesting x64 for mac to work on arm by @m-reuter in #34
- Migrating from PyQt5 to PyQt6: by @taha-abdullah in #36
- remove python3.8 and add 3.12 by @m-reuter in #37
- Replace isort and black with ruff by @m-reuter in #38
- fixed unreliable checksum generation for binary file (_fread3()) by @hensing1 in #40
- Band-aid fix for running snap4() on wayland by @hensing1 in #41
New Contributors
- @engrosamaali91 made their first contribution in #23
- @agirodi made their first contribution in #28
- @taha-abdullah made their first contribution in #36
- @hensing1 made their first contribution in #40
Full Changelog: v1.1.0...v1.2.0
v1.1.0
What's Changed
- Added handling of too few input arguments for surf by @ClePol in #18
- replace flake8 with faster ruff by @m-reuter in #19
- Fix: Broken rotation keys by @AhmedFaisal95 in #20
- Fix: Closing behaviour of interactive mode by @AhmedFaisal95 in #21
- Fix: OpenGL version by @AhmedFaisal95 in #22
Full Changelog: v1.0.0...v1.1.0