brain_deer.surface.projection¶
Volume -> surface projection and voxel-wise thresholding.
project_vol2surf()samples a NIfTI volume at surface vertices (optionally averaging along the vertex normal to approximate ribbon sampling), yielding a per-vertex scalar suitable forbuild_vertexwise_scene().voxelwise_threshold()turns a volume into thresholded points/values for a voxel-wise 3D plot, accepting absolute numbers or percentile strings like'99%'.
Headless (numpy + nibabel only). Sampling uses the volume affine to map vertex mm (RAS+) into voxel space, then nearest or trilinear interpolation.
Functions¶
|
Resolve a threshold to an absolute number. |
|
Sample |
|
Sample |
|
Per-point scalars (one 1D array per streamline) → flat (N, 4) uint8 RGBA via a LUT. |
|
Return |
|
|
Module Contents¶
- brain_deer.surface.projection.parse_threshold(threshold: float | int | str | None, values: numpy.ndarray) float | None¶
Resolve a threshold to an absolute number.
None-> None (no threshold).number -> that number.
'99%'/'99.5%'-> that percentile of the finite absolute values.
- brain_deer.surface.projection.project_vol2surf(volume_img, vertices: numpy.ndarray, *, faces: numpy.ndarray | None = None, method: str = 'trilinear', ribbon_mm: float = 0.0, ribbon_steps: int = 3, agg: str = 'mean', dilate_vox: int = 0, ball_mm: float = 0.0) numpy.ndarray¶
Sample
volume_imgat surfacevertices(RAS+ mm) -> per-vertex values.method: ‘trilinear’ (default) or ‘nearest’.ribbon_mm> 0 samples along the vertex normal at +/- ribbon and aggregates (agg= ‘mean’ | ‘max’ | ‘min’); requiresfacesfor normals.dilate_vox> 1 maximum-filters positive peaks before sampling (matches sparse activation maps that look bright in 2D but miss the surface shell).ball_mm> 0 takes a further max over a voxel ball around each sample (robust when hotspots sit beside the shell, not only along the normal).
- brain_deer.surface.projection.project_vol2streamlines(volume_img, streamlines: Sequence[numpy.ndarray], *, method: str = 'trilinear') list[numpy.ndarray]¶
Sample
volume_imgat each streamline point (RAS+ mm) -> per-point values.Returns one 1D array per streamline, matching the SBA-style tractometry colouring path used by
build_tracts_scene().
- brain_deer.surface.projection.streamline_scalars_to_rgba(scalars: Sequence[numpy.ndarray], lut_rgba: numpy.ndarray, lo: float, hi: float, *, alpha_byte: int = 255, threshold: float | None = None) numpy.ndarray¶
Per-point scalars (one 1D array per streamline) → flat (N, 4) uint8 RGBA via a LUT.
Row order matches the concatenated streamline point order — the same order used when building display polydata — so the result can be written straight onto a VTK point scalar array. Non-finite or sub-threshold samples become fully transparent; the LUT’s own alpha column is ignored in favour of
alpha_byte(tract opacity lives in alpha).
- brain_deer.surface.projection.voxelwise_threshold(volume_img, *, threshold: float | str | None = None, absolute: bool = True)¶
Return
(points_mm, values)for voxels passingthreshold.Points are voxel-centre RAS+ mm coordinates (via the affine); values are the voxel intensities.
thresholdaccepts a number or percentile string (‘99%’).
- brain_deer.surface.projection.voxelwise_threshold_multi(volumes, *, threshold: float | str | None = None, absolute: bool = True) tuple[numpy.ndarray, numpy.ndarray]¶
voxelwise_threshold()over one or several volumes, concatenated.volumesis a single path/image or a list of them (e.g. the two per-hemisphere maps of a group result, which live in separate files). Each is thresholded independently and the surviving(points_mm, values)are stacked into one pair, so both sides plot in a single scene on a shared colour scale.