Image modulation¶

Functional data analysis yields several measures of brain activity, including effect size and statistical significance, which are closely related: effect size reflects the strength of the signal, while significance indicates how large that effect is relative to noise. Evaluating both measures—and their interaction—helps determine not only whether an observed effect is reliable, but also whether its magnitude is meaningful. This demo allows you to look at the effect size (COPE: contrast of parameter estimate) and significance (as a T-score). This jupyter script mirrors the JavaScript web page

In [1]:
import ipywidgets as widgets
from IPython.display import display
from ipyniivue import NiiVue


nv = NiiVue(
    back_color=(0.2, 0.2, 0.3, 1),
)

volume_list = [
    {
        "path": "../images/mean_func.nii.gz",
        "opacity": 1,
        "colormap": "gray",
    },
    {
        "path":  "../images/cope1.nii.gz",
        "colormap": "winter",
        "opacity": 0,
        "cal_min": 0.0,
        "cal_max": 100,
    },
    {
        "path":  "../images/tstat1.nii.gz",
        "opacity": 1,
        "colormap": "warm",
        "cal_min": 0,
        "cal_max": 4.5,
    },
]

nv.load_volumes(volume_list)

nv.overlay_outline_width = 0.25
nv.volumes[0].colorbar_visible = False
nv.opts.is_colorbar = True
nv.set_interpolation(True)
nv.scene.crosshair_pos = (0.55, 0.5, 0.8)
nv.opts.slice_type = "MULTIPLANAR"

## User interface

display_mode_dropdown = widgets.Dropdown(
    options=[("func", 0), ("cope", 1), ("tstat", 2), ("modulate", 3)],
    value=3,  # default is 'modulate'
    description="Display:",
)

tmax_slider = widgets.IntSlider(
    min=1,
    max=50,
    value=45,
    description="tMax",
)

cmax_slider = widgets.IntSlider(
    min=1,
    max=200,
    value=100,
    description="cMax",
)

outline_slider = widgets.FloatSlider(
    min=0,
    max=4,
    value=1,
    description="Outline",
)

clipdark_checkbox = widgets.Checkbox(
    value=False,
    description="ClipDark",
)

modulate_alpha_checkbox = widgets.Checkbox(
    value=True,
    description="ModulateAlpha",
)

## Callback functions

def on_tmax_slider_change(change):
    """Set tmax."""
    nv.volumes[2].cal_max = 0.1 * change["new"]


tmax_slider.observe(on_tmax_slider_change, names="value")


def on_cmax_slider_change(change):
    """Set cmax."""
    nv.volumes[1].cal_max = change["new"]


cmax_slider.observe(on_cmax_slider_change, names="value")


def on_outline_slider_change(change):
    """Set overlay outline width."""
    nv.overlay_outline_width = 0.25 * change["new"]


outline_slider.observe(on_outline_slider_change, names="value")


def on_clipdark_checkbox_change(change):
    """Set alpha clip dark."""
    nv.opts.is_alpha_clip_dark = change["new"]


clipdark_checkbox.observe(on_clipdark_checkbox_change, names="value")


def on_modulate_alpha_checkbox_change(change):
    """Modulate alpha."""
    on_display_mode_change({"new": display_mode_dropdown.value})


modulate_alpha_checkbox.observe(on_modulate_alpha_checkbox_change, names="value")


def on_display_mode_change(change):
    """Handle display mode change."""
    mode = change["new"]
    nv.set_opacity(0, 1.0)  # background opaque
    nv.set_opacity(1, 0.0)  # hide cope
    nv.set_opacity(2, 0.0)  # hide tstat
    idx = min(2, mode)
    nv.set_opacity(idx, 1.0)

    if mode == 3:  # modulate
        nv.set_opacity(1, 1.0)  # show cope
        nv.set_opacity(2, 0.0)  # hide tstat
        modulate_alpha = modulate_alpha_checkbox.value
        nv.set_modulation_image(
            nv.volumes[1].id,  # modulate this volume (cope)
            nv.volumes[2].id,  # with this volume (tstat)
            modulate_alpha,
        )
    else:
        nv.set_modulation_image(nv.volumes[1].id, "")


display_mode_dropdown.observe(on_display_mode_change, names="value")

## Actions

# Set the initial display mode.
# This function requires that the canvas is attached
# and all 3 volumes are loaded (ie, their IDs are defined)
# So, we use nv.on_image_loaded
def set_initial_display(volume):
    """Set initial display mode."""
    if all(v.id for v in nv.volumes):
        on_display_mode_change({"new": display_mode_dropdown.value})
        nv.on_image_loaded(set_initial_display, remove=True)  # remove after 1st run


nv.on_image_loaded(set_initial_display)

## Handle location change

location_output = widgets.HTML(value=" ")


def handle_location_change(location):
    """Handle location changes."""
    location_output.value = "  " + location["string"]


nv.on_location_change(handle_location_change)

## Display

controls = widgets.VBox(
    [
        display_mode_dropdown,
        tmax_slider,
        cmax_slider,
        outline_slider,
        clipdark_checkbox,
        modulate_alpha_checkbox,
    ]
)

display(widgets.VBox([controls, nv, location_output]))

## Optional: report scene settings

# nv.scene.scene_data
In [ ]: