9.2.13. Technical point: Illustration of the volume to surface sampling schemes

In nilearn, nilearn.surface.vol_to_surf allows us to measure values of a 3d volume at the nodes of a cortical mesh, transforming it into surface data. This data can then be plotted with nilearn.plotting.plot_surf_stat_map for example.

This script shows, on a toy example, where samples are drawn around each mesh vertex. Image values are interpolated at each sample location, then these samples are averaged to produce a value for the vertex.

Three strategies are available to choose sample locations: they can be spread between corresponding nodes when we have two nested surfaces (e.g. a white matter and a pial surface), along the normal at each node, or inside a ball around each node. Don’t worry too much about choosing one or the other: they take a similar amount of time and give almost identical results for most images. If you do have both pial and white matter surfaces (as for the fsaverage and fsaverage5 surfaces fetched by nilearn.datasets) we recommend passing both to vol_to_surf.

import numpy as np

import matplotlib
from matplotlib import pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

from nilearn.surface import surface
from nilearn.plotting import show

9.2.13.1. Build a mesh (of a cylinder)

N_Z = 5
N_T = 10
u, v = np.mgrid[:N_T, :N_Z]
triangulation = matplotlib.tri.Triangulation(u.flatten(), v.flatten())
angles = u.flatten() * 2 * np.pi / N_T
x, y = np.cos(angles), np.sin(angles)
z = v.flatten() * 2 / N_Z

mesh = [np.asarray([x, y, z]).T, triangulation.triangles]
inner_mesh = [[.7, .7, 1.] * mesh[0], triangulation.triangles]

9.2.13.2. Get the locations from which vol_to_surf would draw its samples

nested_sample_points = surface._sample_locations_between_surfaces(
    mesh, inner_mesh, np.eye(4))

line_sample_points = surface._line_sample_locations(
    mesh, np.eye(4), segment_half_width=.2, n_points=6)

ball_sample_points = surface._ball_sample_locations(
    mesh, np.eye(4), ball_radius=.15, n_points=20)

9.2.13.3. Plot the mesh and the sample locations

fig = plt.figure()
ax = plt.subplot(projection='3d')
ax.view_init(67, -42)
ax.plot_trisurf(x, y, z, triangles=triangulation.triangles, alpha=.6)
ax.plot_trisurf(*inner_mesh[0].T, triangles=triangulation.triangles)
ax.scatter(*nested_sample_points.T, color='r')

for sample_points in [line_sample_points, ball_sample_points]:
    fig = plt.figure()
    ax = plt.subplot(projection='3d')
    ax.view_init(67, -42)
    ax.plot_trisurf(x, y, z, triangles=triangulation.triangles)
    ax.scatter(*sample_points.T, color='r')
  • plot surface projection strategies
  • plot surface projection strategies
  • plot surface projection strategies

9.2.13.4. Adjust the sample locations

For “line” and nested surfaces, the depth parameter allows adjusting the position of samples along the line

nested_sample_points = surface._sample_locations_between_surfaces(
    mesh, inner_mesh, np.eye(4), depth=[-.5, 0., .8, 1., 1.2])
fig = plt.figure()
ax = plt.subplot(projection='3d')
ax.view_init(67, -42)
ax.plot_trisurf(x, y, z, triangles=triangulation.triangles, alpha=.6)
ax.plot_trisurf(*inner_mesh[0].T, triangles=triangulation.triangles)
ax.scatter(*nested_sample_points.T, color='r')

show()
plot surface projection strategies

Total running time of the script: ( 0 minutes 0.403 seconds)

Gallery generated by Sphinx-Gallery