Upgrade WhipperSnapPy from 1.3 to 2.0, simplify and streamline integration#795
Upgrade WhipperSnapPy from 1.3 to 2.0, simplify and streamline integration#795ClePol wants to merge 4 commits intoDeep-MI:devfrom
Conversation
…o 2.0:
1. pyproject.toml — Version pin updated
whippersnappy>=1.3.1 → whippersnappy>=2.0
2. requirements.mac.txt — Version pin updated
whippersnappy>=1.3.1 → whippersnappy>=2.0
3. run_fastsurfer.sh — Removed xvfb orchestration (lines 767–794 removed, line 1184 simplified)
Removed the entire maybe_xvfb block: xvfb-run detection, the glfw/OpenGL/whippersnappy.core import test, and all associated warning messages. Whippersnappy 2.0 renders headlessly via native EGL — no virtual framebuffer needed.
Removed "${maybe_xvfb[@]}" prefix from the CC module command invocation.
Removed the obsolete comment about xvfb-run wrapping.
4. tools/Docker/Dockerfile — Slimmed runtime dependencies
whippersnappy_opengl_deps="xvfb libglib2.0-0 libxkbcommon-x11-0 libgl1 libegl1 libfontconfig1 libdbus-1-3" → whippersnappy_egl_deps="libegl1 libgl1 libfontconfig1"
Removed: xvfb (virtual framebuffer, replaced by native EGL), libglib2.0-0 (X11/GUI stack), libxkbcommon-x11-0 (X11 keyboard), libdbus-1-3 (D-Bus, X11-related)
Kept: libegl1 (EGL rendering), libgl1 (OpenGL), libfontconfig1 (font rendering for captions/colorbars)
5. CorpusCallosum/shape/mesh.py — Updated import and API call
Removed import OpenGL.GL pre-check (whippersnappy 2.0 manages its own GL context)
Changed from whippersnappy.core import snap1 → from whippersnappy import snap1 (new top-level import)
Removed the except Exception handler about xvfb (no longer relevant with EGL)
Updated snap1() call: positional first arg → mesh=, overlaypath= → overlay= (new API parameter names)
6. CorpusCallosum/cc_visualization.py — Updated version references
Help text and warning messages: whippersnappy>=1.3.1 → whippersnappy>=2.0
7. CorpusCallosum/shape/postprocessing.py — Updated error messages
ImportError message: removed "glfw or OpenGL" (whippersnappy handles these internally)
Generic Exception message: replaced xvfb guidance with EGL/libegl1 guidance
◦ Detects if --thickness_image flag is present in cc_flags (which is set when the user uses --qc_snap) ◦ Checks whether the whippersnappy Python package is installed and >2.0 ◦ Raises an error and gives instruction if this is not the case.
|
I just remembered that some other files might also need version bumps besides pyproject.toml like mac requirements. I think the other files are auto-generated? |
…face and overlay files. Use direct passing of the surface and overlay data instead of writing the files to disc first. Remove and simplify commands, arguments and the like that are a relict of older whippersnappy versions, now fully requiring whippersnappy 2.
345c0bb to
84e3bdf
Compare
There was a problem hiding this comment.
Pull request overview
This pull request upgrades the whippersnappy dependency from version 1.3 to 2.0, which introduces native EGL headless rendering capabilities. This eliminates the need for xvfb (virtual framebuffer) orchestration, simplifies the codebase, and reduces Docker image size by removing X11-related dependencies.
Changes:
- Upgraded whippersnappy version requirement from >=1.3.1 to >=2.0 across all dependency files
- Removed xvfb orchestration logic and replaced with whippersnappy version validation in run_fastsurfer.sh
- Refactored mesh snapshot generation to use whippersnappy 2.0's in-memory API instead of disk-based I/O
- Reduced Docker runtime dependencies by removing xvfb and X11-related libraries (libglib2.0-0, libxkbcommon-x11-0, libdbus-1-3)
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| pyproject.toml | Updated whippersnappy version constraint in qc optional dependencies |
| requirements.mac.txt | Updated whippersnappy version constraint for macOS builds |
| tools/Docker/Dockerfile | Removed X11 dependencies and renamed variable to reflect EGL-based rendering |
| run_fastsurfer.sh | Replaced xvfb orchestration with version validation logic, added error handling for version mismatches |
| CorpusCallosum/shape/mesh.py | Updated API to use whippersnappy 2.0's direct data passing, added version check, updated imports |
| CorpusCallosum/shape/postprocessing.py | Simplified mesh processing and updated error messages for EGL rendering |
| CorpusCallosum/cc_visualization.py | Updated version references and adapted to new API signature |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| elif Path(template_dir / "mri/orig.mgz").exists() and Path(template_dir / "mri/transforms/cc_up.lta").exists(): | ||
| image = nib.load(template_dir / "mri" / "orig.mgz") | ||
| lta_mat = read_lta(template_dir / "mri/transforms/cc_up.lta")["lta"] | ||
| image.affine = apply_affine(lta_mat, image.affine) |
There was a problem hiding this comment.
The function apply_affine from nibabel.affines is used to transform points/vertices, not affine matrices. This line incorrectly applies apply_affine(lta_mat, image.affine) when it should be composing two affine matrices. The correct approach would be to matrix multiply: image.affine = lta_mat @ image.affine or use np.dot(lta_mat, image.affine). The current code will likely result in an error or incorrect transformation.
There was a problem hiding this comment.
Should be addressed by matrix multiplication.
| cc_mesh.snap_cc_picture(str(output_dir / "cc_mesh_snap.png")) | ||
| cc_mesh.snap_cc_picture(str(output_dir / "cc_mesh_snap.png"), ref_header=header) | ||
| logger.info(f"Writing 3D snapshot image to {output_dir / 'cc_mesh_snap.png'}") | ||
| except RuntimeError: |
There was a problem hiding this comment.
The exception handler is catching RuntimeError, but the snap_cc_picture method in mesh.py (line 527-531, 535-539) raises ImportError exceptions, not RuntimeError. The exception type should be changed to ImportError or a broader Exception to properly catch the errors from snap_cc_picture.
| except RuntimeError: | |
| except ImportError: |
| - -8 degrees around z-axis | ||
| 3. Adds a small translation for better centering | ||
| """ | ||
| from whippersnappy.gl.views import ViewType, get_view_matrix |
There was a problem hiding this comment.
The import from whippersnappy.gl.views import ViewType, get_view_matrix is placed inside the method, but the method is called from snap_cc_picture which may fail before reaching this line if whippersnappy is not installed. Consider moving this import to be alongside the whippersnappy version check in snap_cc_picture or ensuring this import is protected by the same try-except block. Additionally, this new dependency on whippersnappy.gl.views should be validated to ensure it exists in whippersnappy 2.0.
There was a problem hiding this comment.
I had made ViewType top level import for convenience:
from whippersnappy import ViewType
| Path to a FreeSurfer overlay file to use for the snapshot. | ||
| If None, the mesh is saved to a temporary file. | ||
| ref_image : Path, str, nibabelImage, optional | ||
| ref_header : Path, str, nibabelImage, optional |
There was a problem hiding this comment.
The docstring parameter description says "ref_header : Path, str, nibabelImage, optional" but the type annotation on line 506 shows it accepts "nibabelHeader" not "nibabelImage". The docstring should be corrected to say "ref_header : Path, str, nibabelHeader, optional" to match the actual type annotation.
| ref_header : Path, str, nibabelImage, optional | |
| ref_header : Path, str, nibabelHeader, optional |
There was a problem hiding this comment.
Well, actually this is the old type in the docstring. Most of the types of this string are currently not supported. We should just drop the types from the doc that are no longer supported.
Overview
Upgrade to whippersnappy 2.0 with native EGL headless rendering, eliminating xvfb dependency and reducing Docker image size.
Changes
Detailed Changes
pyproject.toml — Version pin updated
whippersnappy>=1.3.1→whippersnappy>=2.0requirements.mac.txt — Version pin updated
whippersnappy>=1.3.1→whippersnappy>=2.0run_fastsurfer.sh — Removed xvfb orchestration
maybe_xvfbblock (lines 767–794)"${maybe_xvfb[@]}"prefix from CC module command invocationtools/Docker/Dockerfile — Slimmed runtime dependencies
xvfb libglib2.0-0 libxkbcommon-x11-0 libgl1 libegl1 libfontconfig1 libdbus-1-3libegl1 libgl1 libfontconfig1xvfb(virtual framebuffer, replaced by native EGL)libglib2.0-0(X11/GUI stack)libxkbcommon-x11-0(X11 keyboard)libdbus-1-3(D-Bus, X11-related)libegl1(EGL rendering),libgl1(OpenGL),libfontconfig1(font rendering for captions/colorbars)CorpusCallosum/shape/mesh.py — Updated import and API call
import OpenGL.GLpre-check (whippersnappy 2.0 manages its own GL context)from whippersnappy.core import snap1→from whippersnappy import snap1(new top-level import)except Exceptionhandler about xvfb (no longer relevant with EGL)snap1()call:mesh=overlaypath=→overlay=(new API parameter names)CorpusCallosum/cc_visualization.py — Updated version references
whippersnappy>=1.3.1→whippersnappy>=2.0CorpusCallosum/shape/postprocessing.py — Updated error messages