Voxel-based diffusion metrics¶
Many voxel-based metrics can be derived from diffusion weighted imaging, including fractional anisotropy (FA) and the direction of the principal vector (V1). This notebook illustrates methods for viewing these modalities. While the images here are from FSL, you can also load voxel-based images from other tools including AFNI, MRtrix and DSI-studio. This notebook mirrors the NiiVue dti web page.
TODO: ipyniivue does not yet support isForceMouseClickToVoxelCenters
In [1]:
from ipyniivue import NiiVue, ShowRender
import ipywidgets as widgets
from IPython.display import display
nv = NiiVue(
back_color=(1, 1, 1, 1),
show_3d_crosshair=True,
multiplanar_show_render=ShowRender.ALWAYS,
height=1024
)
nv.load_volumes([
{'path': '../images/FA.nii.gz' },
{'path': '../images/V1.nii.gz', 'opacity': 1 }
])
nv.volumes[0].colorbar_visible = False
nv.opts.is_alpha_clip_dark = True
nv.set_crosshair_width(0.1)
nv.is_force_mouse_click_to_voxel_centers = True
## create widgets
# modulate_options = nv.mesh_shader_names()
modulate_options = {"FA", "V1", "V1xFA", "Lines", "LinesxFA"}
modulate_dropdown = widgets.Dropdown(
options=modulate_options,
value="V1", # Default shader
description="Shader:",
)
def on_modulate_change(change):
"""Set modulation."""
new_value = change["new"]
nv.volumes[0].opacity = 1.0
nv.volumes[1].opacity = 1.0
nv.set_modulation_image(nv.volumes[1].id, '')
nv.opts.is_v1_slice_shader = False
match new_value:
case "FA":
nv.volumes[1].opacity = 0.0
case "V1":
nv.volumes[0].opacity = 0.0
# nv.volumes[1].opacity = 1.0
case "V1xFA":
nv.set_modulation_image(nv.volumes[1].id,nv.volumes[0].id)
case "Lines":
nv.opts.is_v1_slice_shader = True
case "LinesxFA":
nv.opts.is_v1_slice_shader = True
nv.set_modulation_image(nv.volumes[1].id,nv.volumes[0].id)
case _:
print(f"Unknown shader option: {new_value}")
modulate_dropdown.observe(on_modulate_change, names="value")
dark_check = widgets.Checkbox(value=True, description="Clip Dark")
def on_dark_check_change(change):
"""Recreate nv with new anti_alias setting and re-apply settings."""
nv.opts.is_alpha_clip_dark = change["new"]
dark_check.observe(on_dark_check_change, names="value")
@nv.on_image_loaded
def on_image_loaded(volume):
"""Handle event after volume is loaded and ready."""
modulate_dropdown.value = "LinesxFA"
nv.move_crosshair_in_vox(0, 0, 0)
## Display
controls = widgets.HBox([modulate_dropdown, dark_check])
## Show widgets and view
display(controls)
display(nv)
In [ ]:
In [ ]: