owned this note
owned this note
Published
Linked with GitHub
# NiBabel Surface API meeting logs
## 10 February 2022
* State of the BIAP: https://github.com/effigies/nibabel/blob/biap/surfaces/doc/source/devel/biaps/biap_0009.rst
* Ready for final(ish) comment and move on to implementation.
## 28 January 2022
Attending: Chris, Joshua Teves
* MNE/STC
* Unincluded reference TriangularMesh
* Includes subsample indices
* lvertno = array of indices into left surface, rvertno ...
* (lvertno + rvertno, tpts)
* 2 patches, with deferred geometry (FreeSurfer subject)
* How to determine decimated mesh (mne.surface.decimate_surface)
* dsurface.triangles, dsurface.points
## 14 January 2022
Attending: Chris, Eric Larson
Notes:
* Patches
* (surface, index array-like)
## 19 November 2021
* Agenda
* CJM summary
* `Geometry` is now `Pointset` and `SurfaceGeometry` is now `TriangularMesh`
* From consideration of nitransforms SampledSpatialData + [NURBS](https://en.wikipedia.org/wiki/Non-uniform_rational_B-spline), should try to be more specific
* `Pointset` could be `Pointcloud`, which seems common in graphics world
* Haven't come up with a good name for `VolumeGeometry`; nitransforms uses `ImageGrid`
* CIFTI keeps throwing up wrinkles
* Loading VolumeGeometry is straightforward
* Meshes are subsetted without actually providing the mesh. Haven't fully thought through the deferred loading model, whether we need objects with different guarantees from TriangularMesh or to relax those guarantees.
* Got a [CaretSpecFile DTD](https://gist.github.com/effigies/06d77a9984f6ae4fa943d27830eebfb7) out of hcp-users
* Decisions:
* Bundle fsLR spec to reduce the scope for missing CIFTI geometry data
* Example task:
* Load patch by name from parcellation file, subsample CIFTI without loading wb.spec. Load wb.spec and retrieve coordinates.
Hao-Ting will take another shot at GIFTI. Oscar will review with an eye toward making sure we aren't making life harder for nitransforms.
## 5 November 2021
BIAP: https://github.com/nipy/nibabel/pull/1056
* BF: Make sure subsampling (e.g selecting parcels) of surface geometry is straightforward
* JT: MNE's STC format (pointset) -> GIFTI
* See test NPSurfaceImage
* OE: Nitransforms has a common concept for surface/volumetric structures
* CJM: I think this is [SampledSpatialData](https://nitransforms.readthedocs.io/en/latest/_api/base.html#nitransforms.base.SampledSpatialData)
Resources:
* [Nibabel presentations](https://github.com/effigies/nibabel-presentations)
* [CaretSpecFile C++ implementation](https://github.com/Washington-University/workbench/blob/0d551465c9c31a6b6342a271427a22df2bc5f7cc/src/Files/SpecFile.cxx)
Post-meeting comments from Satra, mixed freely with CJM commentary:
* Non-triangular meshes, such as NURBS are worth considering ([nurbs-python](https://nurbs-python.readthedocs.io/en/latest/index.html)), to avoid precluding in the future
* This represents a more generic curve/surface class. may be worthwhile looking into the library a bit.
* potential class structure: genericmesh -> triangularmesh-> GIFTI
* The [SpeechLab Toolkit](https://github.com/satra/SLT) has [SurfTools](https://github.com/satra/SLT/tree/master/SurfTools) for operating on surfaces. Ensuring that we enable these things (if not directly implement) would be a good check.
* other considerations are disconnected meshes (like left + right pairs) or tessellations for every parcellation?
* Are boundary-element/finite-element models in-scope for nibabel? In any event, ensure they are possible with our data structures.
---
# Nibabel Surface API initial meeting
## Logistics
~~Poll for date/time: https://doodle.com/poll/ih86eymx9h64vhai~~
Selected date/time: [Thursday 16 September 2021 @ 9am EDT](https://arewemeetingyet.com/New%20York/2021-09-16/09:00/Nibabel%20Surface%20API%20initial%20meeting#eyJ1cmwiOiJodHRwczovL3N0YW5mb3JkLnpvb20udXMvai85NjAyODk3OTYyNz9wd2Q9WXpkS1VpdHRjRk5OUVV4T1JXTlphMFYwVEhSbVFUMDkifQ==)
Call link: ~~[Zoom](https://stanford.zoom.us/j/96028979627?pwd=YzdKUittcFNNQUxORWNZa0V0THRmQT09) (has waiting room)~~ (expired)
Follow-up date/time: [Thursday 30 September 2021 @ 9am EDT](https://arewemeetingyet.com/New%20York/2021-09-30/09:00/Nibabel%20Surface%20API%20initial%20meeting#eyJ1cmwiOiJodHRwczovL3N0YW5mb3JkLnpvb20udXMvai85NjAyODk3OTYyNz9wd2Q9WXpkS1VpdHRjRk5OUVV4T1JXTlphMFYwVEhSbVFUMDkifQ==)
Follow-up call link: [Zoom](https://stanford.zoom.us/j/95458185136?pwd=NDVRTnlZTzZ0cGoweDkwUTVPWGJ5Zz09)
## Meeting Notes
## Resources
* Related threads
* RFP: SurfaceImage API ([nipy/nibabel#936](https://github.com/nipy/nibabel/issues/936))
* Improve support for surface data in nilearn? ([nilearn/nilearn#2171](https://github.com/nilearn/nilearn/issues/2171))
* Update surface functions ([nilearn/nilearn#2682](https://github.com/nilearn/nilearn/issues/2682))
* Preliminary notes on surface representations ([Discourse #57](https://nipy.discourse.group/t/preliminary-notes-on-surface-representations/57))
* Collecting use cases ([Discourse #58](https://nipy.discourse.group/t/collecting-use-cases/58))
* Software suite docs
* AFNI [SUMA](https://afni.nimh.nih.gov/pub/dist/doc/program_help/suma.html) docs
* [@SUMA_Make_Spec_FS](https://afni.nimh.nih.gov/pub/dist/doc/program_help/@SUMA_Make_Spec_FS.html)
* [@SUMA_Make_Spec_SF](https://afni.nimh.nih.gov/pub/dist/doc/program_help/@SUMA_Make_Spec_SF.html)
* Connectome Workbench
* [BALSA File Types](https://balsa.wustl.edu/about/fileTypes)
* FreeSurfer
* Directory structure explained starting [slide 18](https://gate.nmr.mgh.harvard.edu/wiki/whynhow/images/c/c2/Freesurfer_presentation_beginner.pdf)
*
## Potential API sketches
Please feel free to start an H3 block here and fiddle. Note your name so you can walk us through it. This does not need to be fully thought out.
### Chris M sketch
Desiderata
* Combine / select brain structures
* Simplest: lh + rh
* More complex: one or more parcellations
*
```python=
def plot(surf_img, surface=None):
texture = surf_img.get_data()
coords, triangles = surf_img.get_mesh(surface)
...
plot(surf_img) # Default surface
plot(surf_img, "inflated") # Associated surface
plot(surf_img, "pial")
def surface_maths(mathstr, surf_img1, surf_img2):
assert surf_img1.header == surf_img2.header
res = domaths(mathstr, surf_img1.get_data(), surf_img2.get_data())
return SurfaceImage(res, surf_img1.header)
def smooth_surf(surf_img, fwhm, surface=None):
coords, triangles = surf_img.get_mesh(surface)
...
def decimate(surf_hdr, *, vtx_count=None, ratio=None):
# Decimation creates a new mesh in the same space
# Can be simplified on a per-format basis if assumptions are met
def resample_from_to(surf_img, surf_hdr):
...
def decimate_and_resample(surf_img, *, vtx_count=None, ratio=None):
# From https://nipy.discourse.group/t/collecting-use-cases/58/4
new_header = decimate(surf_img.header, vtx_count=vtx_count, ratio=ratio)
fwhm = calculate_antialiasing_window(surf_img.header.vtx_count, new_header.vtx_count)
smoothed_img = smooth_surf(surf_img, fwhm)
return resample_from_to(surf_img, new_header)
class SurfaceImage:
header : SurfaceHeader
data : ndarray
def __init__(self, ndarray, ):
...
def load_header(self, path):
...
class SurfaceHeader:
```
* What happens when we lack some metadata?
### Related project
Diffusion emedding on connectome
https://github.com/MICA-MNI/BrainSpace
GLM on surface data:
https://github.com/MICA-MNI/BrainStat
A MATLAB tool for surface based GLM - reference for potential use cases and interface
https://www.math.mcgill.ca/keith/surfstat/
Surfplot
https://github.com/danjgale/surfplot