Add fmri_surface_data object for CIFTI/GIFTI surface & grayordinate data#86
Open
torwager wants to merge 7 commits into
Open
Add fmri_surface_data object for CIFTI/GIFTI surface & grayordinate data#86torwager wants to merge 7 commits into
torwager wants to merge 7 commits into
Conversation
New CANlab object `fmri_surface_data` (subclass of image_vector), the surface/
grayordinate analogue of fmri_data. Wraps the HCP CIFTI grayordinate standard as
a true CANlab object with full fmri_data-style method parity, running natively in
MATLAB with no external toolbox (sole exception: ica, which needs GIFT/icatb like
the base class).
Highlights:
- Native CIFTI-2 + GIFTI readers/writers (Surface_tools/canlab_read|write_cifti|
gifti), bit-exact vs cifti_read/gifti oracles; proven to work with those tools
removed from the path.
- Object: construction from CIFTI/GIFTI/struct/key-value; brain_model replaces
volInfo (volInfo populated for the subcortical sub-block); no empty-squeezing
(.dat always full; remove_empty/replace_empty are no-ops).
- Interop: reconstruct_image, to_fmri_data, compare_space (0/1/2/3), write.
- Volume<->surface: vol2surf / surf2vol via vendored CBIG RF warps (vol->surf->
vol r~1.0), fully native.
- Data/analysis: cat/horzcat, mean, apply_mask, threshold (+cluster-extent 'k'),
ttest, regress, predict, ica (predict/ttest/ica delegate to fmri_data via a
proxy and remap results).
- Rendering: surface (native 4-panel + on any addbrain/MNI surface via volume
resampling), render_on_surface, plot; reparse_contiguous (mesh graph),
apply_parcellation, surface_region.
- Docs: docs/fmri_surface_data_{design_plan,methods}.md + runnable walkthrough.m.
- Tests: Unit_tests/surface_data/ (7 files, 41 tests passing).
Also: fix a stray non-functional debug line in @image_vector/ica.m that errored
ica() for all image_vector subclasses; document the fs_LR/fsaverage standard-mesh
correspondence in addbrain.m; add deprecation pointers in the external-dependent
Cifti_plotting readers.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- docs/fmri_surface_data_methods.md: per-class methods page (properties + methods grouped by area), integrated into docs/Object_methods.md (class hierarchy + object-classes table) and docs/Workflows.md. - docs/workflows/fmri_surface_data_howto.md: intro workflow — load surface data and render it natively; map volumetric data to the surface (vol2surf) and back (surf2vol / to_fmri_data); parcellation, thresholding, and group analysis. Includes three rendered example figures. - Methods page includes a summarized inventory of surface atlases / maps available in the companion Neuroimaging_Pattern_Masks repository. - Sample data: bundle one small HCP Open Access group myelin map (Sample_datasets/CIFTI_surface_examples/) with a provenance README; additional surface atlases are resolved from Neuroimaging_Pattern_Masks. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Verified the whole object end-to-end (41 tests pass; walkthrough runs both with and without Neuroimaging_Pattern_Masks). Fixes from the review: - apply_mask: now falls back to the object's .mask property when no mask arg is passed (matching the documented behavior), with a clear error if neither is set. Added a unit test. - Walkthrough (CanlabCore/docs/fmri_surface_data_walkthrough.m): use the bundled HCP myelin map as the primary object so it runs with only CanlabCore; guard the subcortex / atlas / parcellation sections on NPM availability; fix the parcellation demo (previously skipped because spaces never matched). - How-to (docs/workflows/fmri_surface_data_howto.md): fix Section E/F snippets that referenced undefined variables (mydata, subj1..3, scores) and called regress before setting the design; they now match the runnable walkthrough. - Docs accuracy: regress is native OLS (not "delegated"); cluster-extent threshold is implemented (not "planned"); ica is a class override (not inherited); canlab_surface_vertexcolors signature includes graycolor. - Method help examples (vol2surf, surface, surf2vol, canlab_read_cifti): use the bundled emotionreg / myelin sample data instead of a private-repo image. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
32b80e6 to
f178d11
Compare
…ge/slices; doc links
- Volume-only image_vector methods (flip, isosurface, interpolate, resample_space,
extract_gray_white_csf, searchlight, slice_movie, trim_mask, read_from_file,
extract_roi_averages, ...) are overridden in a methods(Hidden) block: they no
longer clutter methods(obj)/tab-completion, and calling one raises a clear
fmri_surface_data:unsupportedMethod error pointing to the surface equivalent.
The class stays a full image_vector subclass.
- orthviews / montage / slices now route the subcortical grayordinates through
to_fmri_data and call the fmri_data method (meaningful subcortex display);
cortex-only objects get a clear "use surface(obj)" error.
- Added test_volume_only_methods_hidden; documented in the methods page
("Volume-only methods (redirected or masked)").
- Made the walkthrough / design-plan references in the docs into links.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ow a MATLAB table - Object property `intent` renamed to `imagetype` (holds dscalar/dtseries/dlabel/func/shape/label). The CIFTI/GIFTI reader & writer structs keep the faithful `intent`/`intents` field names at the I/O boundary; the constructor/write map between `obj.imagetype` and the CIFTI intent. - `label_table` property is now a MATLAB `table` (variables key, name, rgba) instead of a struct array — nicer to view/query. Boundary converters (private struct2labeltable / labeltable2struct) translate to/from the native readers' struct arrays; apply_parcellation accepts either format. - Updated tests (assert imagetype + istable(label_table)) and the methods docs. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ization pipeline surface() / render_on_surface() now accept the same colour vocabulary as the master visualization pipeline (addblobs / set_colormap): clim / cmaprange, colormap / colormapname (single sequential map), pos_colormap / neg_colormap, splitcolor, maxcolor / mincolor, and color (solid). surface() forwards any colour option straight through to render_on_surface, and the via-volume path forwards the compatible options to image_vector/render_on_surface. So the same options colour surface data and volume blobs. Added test_harmonized_color_options; updated surface() help and the methods page. (Level 1 of the visualization harmonization; the stateful fmridisplay-layer integration is the next step.) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…tive layers) Level 2 of the visualization harmonization: an fmri_surface_data can now be added to a managed fmridisplay and driven by the same controls as volume data. - @fmridisplay/addblobs: detects an fmri_surface_data and dispatches to a new @fmridisplay/add_surface_blobs, which registers it as a SURFACE-NATIVE layer (source_surface) rather than converting to a volume region. - @fmridisplay/render_layer_surfaces: paints surface-native layers by colouring the per-vertex data DIRECTLY on any registered mesh whose vertex count matches the object's space (fs_LR-32k / fsaverage-164k), at full fidelity, using the same central canlab_colormap value->colour map as montages (so colours match). set_colormap / set_opacity / removeblobs / refresh / the controller act on the layer like a volume layer. Non-matching meshes are skipped; a surface layer has no montage representation (use to_fmri_data / surf2vol for that). - Fix @fmri_surface_data/isempty: image_vector/isempty treats an empty volInfo as empty, but a cortex-only surface object legitimately has an empty volInfo, so a fully-populated cortical map wrongly reported empty. Now empty iff .dat has no rows. - Added canlab_test_surface_fmridisplay (addblobs paints, set_colormap/removeblobs propagate, non-matching/no-surface handled). Full surface suite: 47 passing. - Documented the managed-display integration in the methods page. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
New CANlab object
fmri_surface_data(subclass ofimage_vector) — the surface/grayordinate analogue offmri_data, wrapping the HCP CIFTI grayordinate standard as a true CANlab object. Runs natively in MATLAB with no external toolbox (sole exception:ica, which needs GIFT/icatb like the base class).What's included
CanlabCore/Surface_tools/canlab_*), bit-exact vscifti_read/gifti; verified to work with those tools removed from the path.brain_modelreplacesvolInfo(populated for the subcortical sub-block);.datalways full — no empty-squeezing (remove_empty/replace_emptyno-ops).reconstruct_image,to_fmri_data,compare_space,write.vol2surf/surf2volvia the vendored CBIG RF warps (vol→surf→vol r≈1.0), fully native.cat/horzcat,mean,apply_mask,threshold(+cluster-extentk),ttest,regress,predict,ica(predict/ttest/ica delegate tofmri_data+ remap).surface(native + any addbrain/MNI surface via resampling),render_on_surface,plot;reparse_contiguous,apply_parcellation,surface_region.docs/fmri_surface_data_methods.md(integrated intoObject_methods.md/Workflows.md),docs/workflows/fmri_surface_data_howto.md(with figures), plus developer docs + runnable walkthrough underCanlabCore/docs/.Sample_datasets/CIFTI_surface_examples/; other atlases resolve fromNeuroimaging_Pattern_Masks.CanlabCore/Unit_tests/surface_data/— 7 files, 41 tests passing (ica skipped when its toolbox is absent).Incidental fixes
@image_vector/ica.m: removed a stray non-functional debug line that madeicaerror for allimage_vectorsubclasses.addbrain.mhelp: documented the fs_LR/fsaverage standard-mesh correspondence.Cifti_plottingreaders.Notes / deferred (see design plan)
vol2surf/surf2voluse a fixed group MNI152↔fsaverage correspondence (not a per-subject ribbon mapper); fsaverage↔fs_LR deformation is a planned enhancement.fmri_surface_statistic_image/fmri_surface_atlassubclasses; CC0 TemplateFlow meshes.🤖 Generated with Claude Code