def test_peak_slicer(interactive=False): _peak_dirs = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]], dtype='f4') # peak_dirs.shape = (1, 1, 1) + peak_dirs.shape peak_dirs = np.zeros((11, 11, 11, 3, 3)) peak_values = np.random.rand(11, 11, 11, 3) peak_dirs[:, :, :] = _peak_dirs renderer = window.Renderer() peak_actor = actor.peak_slicer(peak_dirs) renderer.add(peak_actor) renderer.add(actor.axes((11, 11, 11))) if interactive: window.show(renderer) renderer.clear() renderer.add(peak_actor) renderer.add(actor.axes((11, 11, 11))) for k in range(11): peak_actor.display_extent(0, 10, 0, 10, k, k) for j in range(11): peak_actor.display_extent(0, 10, j, j, 0, 10) for i in range(11): peak_actor.display(i, None, None) renderer.rm_all() peak_actor = actor.peak_slicer( peak_dirs, peak_values, mask=None, affine=np.diag([3, 2, 1, 1]), colors=None, opacity=1, linewidth=3, lod=True, lod_points=10 ** 4, lod_points_size=3) renderer.add(peak_actor) renderer.add(actor.axes((11, 11, 11))) if interactive: window.show(renderer) report = window.analyze_renderer(renderer) ex = ['vtkLODActor', 'vtkOpenGLActor', 'vtkOpenGLActor', 'vtkOpenGLActor'] npt.assert_equal(report.actors_classnames, ex)
relative_peak_threshold=.8, min_separation_angle=45, mask=white_matter) """ For quality assurance we can also visualize a slice from the direction field which we will use as the basis to perform the tracking. The visualization will be done using the ``fury`` python package """ from dipy.viz import window, actor, has_fury if has_fury: ren = window.Renderer() ren.add( actor.peak_slicer(csa_peaks.peak_dirs, csa_peaks.peak_values, colors=None)) window.record(ren, out_path='csa_direction_field.png', size=(900, 900)) if interactive: window.show(ren, size=(800, 800)) """ .. figure:: csa_direction_field.png :align: center **Direction Field (peaks)** """ """ 2. Next we need some way of restricting the fiber tracking to areas with good directionality information. We've already created the white matter mask,
window.show(ren) """ We can extract the peaks from the ODF, and plot these as well """ sf_peaks = dpp.peaks_from_model(sf_model, data_small, sphere, relative_peak_threshold=.5, min_separation_angle=25, return_sh=False) window.clear(ren) fodf_peaks = actor.peak_slicer(sf_peaks.peak_dirs, sf_peaks.peak_values, scale=1.3) ren.add(fodf_peaks) print('Saving illustration as sf_peaks.png') window.record(ren, out_path='sf_peaks.png', size=(1000, 1000)) if interactive: window.show(ren) """ Finally, we plot both the peaks and the ODFs, overlayed: """ fodf_spheres.GetProperty().SetOpacity(0.4) ren.add(fodf_spheres) print('Saving illustration as sf_both.png')
In DIPY we also provide tools for finding the peak directions (maxima) of the ODFs. For this purpose we recommend using ``peaks_from_model``. """ from dipy.direction import peaks_from_model csd_peaks = peaks_from_model(model=csd_model, data=data_small, sphere=default_sphere, relative_peak_threshold=.5, min_separation_angle=25, parallel=True) scene.clear() fodf_peaks = actor.peak_slicer(csd_peaks.peak_dirs, csd_peaks.peak_values) scene.add(fodf_peaks) print('Saving illustration as csd_peaks.png') window.record(scene, out_path='csd_peaks.png', size=(600, 600)) if interactive: window.show(scene) """ .. figure:: csd_peaks.png :align: center CSD Peaks. We can finally visualize both the ODFs and peaks in the same space. """
""" Now, we need to set starting points for propagating each track. We call those seeds. Using ``random_seeds_from_mask`` we can select a specific number of seeds (``seeds_count``) in each voxel where the mask ``fa > 0.3`` is true. """ seeds = random_seeds_from_mask(fa > 0.3, seeds_count=1) """ For quality assurance we can also visualize a slice from the direction field which we will use as the basis to perform the tracking. """ ren = window.Renderer() ren.add(actor.peak_slicer(csd_peaks.peak_dirs, csd_peaks.peak_values, colors=None)) if interactive: window.show(ren, size=(900, 900)) else: window.record(ren, out_path='csd_direction_field.png', size=(900, 900)) """ .. figure:: csd_direction_field.png :align: center **Direction Field (peaks)** ``EuDX`` [Garyfallidis12]_ is a fast algorithm that we use here to generate streamlines. This algorithm is what is used here and the default option
window.record(ren, out_path='sf_odfs.png', size=(1000, 1000)) if interactive: window.show(ren) """ We can extract the peaks from the ODF, and plot these as well """ sf_peaks = dpp.peaks_from_model(sf_model, data_small, sphere, relative_peak_threshold=.5, min_separation_angle=25, return_sh=False) window.clear(ren) fodf_peaks = actor.peak_slicer(sf_peaks.peak_dirs, sf_peaks.peak_values) ren.add(fodf_peaks) print('Saving illustration as sf_peaks.png') window.record(ren, out_path='sf_peaks.png', size=(1000, 1000)) if interactive: window.show(ren) """ Finally, we plot both the peaks and the ODFs, overlayed: """ fodf_spheres.GetProperty().SetOpacity(0.4) ren.add(fodf_spheres) print('Saving illustration as sf_both.png') window.record(ren, out_path='sf_both.png', size=(1000, 1000))
def slicer_panel(scene, iren, data=None, affine=None, world_coords=False, pam=None, mask=None, mem=GlobalHorizon()): """ Slicer panel with slicer included Parameters ---------- scene : Scene iren : Interactor data : 3d ndarray affine : 4x4 ndarray world_coords : bool If True then the affine is applied. peaks : PeaksAndMetrics Default None mem : Returns ------- panel : Panel """ orig_shape = data.shape print('Original shape', orig_shape) ndim = data.ndim tmp = data if ndim == 4: if orig_shape[-1] > 3: orig_shape = orig_shape[:3] # Sometimes, first volume is null, so we try the next one. for i in range(orig_shape[-1]): tmp = data[..., i] value_range = np.percentile(data[..., i], q=[2, 98]) if np.sum(np.diff(value_range)) != 0: break if orig_shape[-1] == 3: value_range = (0, 1.) mem.slicer_rgb = True if ndim == 3: value_range = np.percentile(tmp, q=[2, 98]) if np.sum(np.diff(value_range)) == 0: msg = "Your data does not have any contrast. " msg += "Please, check the value range of your data." warnings.warn(msg) if not world_coords: affine = np.eye(4) image_actor_z = actor.slicer(tmp, affine=affine, value_range=value_range, interpolation='nearest', picking_tol=0.025) tmp_new = image_actor_z.resliced_array() if len(data.shape) == 4: if data.shape[-1] == 3: print('Resized to RAS shape ', tmp_new.shape) else: print('Resized to RAS shape ', tmp_new.shape + (data.shape[-1], )) else: print('Resized to RAS shape ', tmp_new.shape) shape = tmp_new.shape if pam is not None: peaks_actor_z = actor.peak_slicer(pam.peak_dirs, None, mask=mask, affine=affine, colors=None) slicer_opacity = 1. image_actor_z.opacity(slicer_opacity) image_actor_x = image_actor_z.copy() x_midpoint = int(np.round(shape[0] / 2)) image_actor_x.display_extent(x_midpoint, x_midpoint, 0, shape[1] - 1, 0, shape[2] - 1) image_actor_y = image_actor_z.copy() y_midpoint = int(np.round(shape[1] / 2)) image_actor_y.display_extent(0, shape[0] - 1, y_midpoint, y_midpoint, 0, shape[2] - 1) scene.add(image_actor_z) scene.add(image_actor_x) scene.add(image_actor_y) if pam is not None: scene.add(peaks_actor_z) line_slider_z = ui.LineSlider2D(min_value=0, max_value=shape[2] - 1, initial_value=shape[2] / 2, text_template="{value:.0f}", length=140) _color_slider(line_slider_z) def change_slice_z(slider): z = int(np.round(slider.value)) mem.slicer_curr_actor_z.display_extent(0, shape[0] - 1, 0, shape[1] - 1, z, z) if pam is not None: mem.slicer_peaks_actor_z.display_extent(0, shape[0] - 1, 0, shape[1] - 1, z, z) mem.slicer_curr_z = z scene.reset_clipping_range() line_slider_x = ui.LineSlider2D(min_value=0, max_value=shape[0] - 1, initial_value=shape[0] / 2, text_template="{value:.0f}", length=140) _color_slider(line_slider_x) def change_slice_x(slider): x = int(np.round(slider.value)) mem.slicer_curr_actor_x.display_extent(x, x, 0, shape[1] - 1, 0, shape[2] - 1) scene.reset_clipping_range() mem.slicer_curr_x = x mem.window_timer_cnt += 100 line_slider_y = ui.LineSlider2D(min_value=0, max_value=shape[1] - 1, initial_value=shape[1] / 2, text_template="{value:.0f}", length=140) _color_slider(line_slider_y) def change_slice_y(slider): y = int(np.round(slider.value)) mem.slicer_curr_actor_y.display_extent(0, shape[0] - 1, y, y, 0, shape[2] - 1) scene.reset_clipping_range() mem.slicer_curr_y = y # TODO there is some small bug when starting the app the handles # are sitting a bit low double_slider = ui.LineDoubleSlider2D(length=140, initial_values=value_range, min_value=tmp.min(), max_value=tmp.max(), shape='square') _color_dslider(double_slider) def apply_colormap(r1, r2): if mem.slicer_rgb: return if mem.slicer_colormap == 'disting': # use distinguishable colors rgb = colormap.distinguishable_colormap(nb_colors=256) rgb = np.asarray(rgb) else: # use matplotlib colormaps rgb = colormap.create_colormap(np.linspace(r1, r2, 256), name=mem.slicer_colormap, auto=True) N = rgb.shape[0] lut = colormap.LookupTable() lut.SetNumberOfTableValues(N) lut.SetRange(r1, r2) for i in range(N): r, g, b = rgb[i] lut.SetTableValue(i, r, g, b) lut.SetRampToLinear() lut.Build() mem.slicer_curr_actor_z.output.SetLookupTable(lut) mem.slicer_curr_actor_z.output.Update() def on_change_ds(slider): values = slider._values r1, r2 = values apply_colormap(r1, r2) # TODO trying to see why there is a small bug in double slider # double_slider.left_disk_value = 0 # double_slider.right_disk_value = 98 # double_slider.update(0) # double_slider.update(1) double_slider.on_change = on_change_ds opacity_slider = ui.LineSlider2D(min_value=0.0, max_value=1.0, initial_value=slicer_opacity, length=140, text_template="{ratio:.0%}") _color_slider(opacity_slider) def change_opacity(slider): slicer_opacity = slider.value mem.slicer_curr_actor_x.opacity(slicer_opacity) mem.slicer_curr_actor_y.opacity(slicer_opacity) mem.slicer_curr_actor_z.opacity(slicer_opacity) volume_slider = ui.LineSlider2D(min_value=0, max_value=data.shape[-1] - 1, initial_value=0, length=140, text_template="{value:.0f}", shape='square') _color_slider(volume_slider) def change_volume(istyle, obj, slider): vol_idx = int(np.round(slider.value)) mem.slicer_vol_idx = vol_idx scene.rm(mem.slicer_curr_actor_x) scene.rm(mem.slicer_curr_actor_y) scene.rm(mem.slicer_curr_actor_z) tmp = data[..., vol_idx] image_actor_z = actor.slicer(tmp, affine=affine, value_range=value_range, interpolation='nearest', picking_tol=0.025) tmp_new = image_actor_z.resliced_array() mem.slicer_vol = tmp_new z = mem.slicer_curr_z image_actor_z.display_extent(0, shape[0] - 1, 0, shape[1] - 1, z, z) mem.slicer_curr_actor_z = image_actor_z mem.slicer_curr_actor_x = image_actor_z.copy() if pam is not None: mem.slicer_peaks_actor_z = peaks_actor_z x = mem.slicer_curr_x mem.slicer_curr_actor_x.display_extent(x, x, 0, shape[1] - 1, 0, shape[2] - 1) mem.slicer_curr_actor_y = image_actor_z.copy() y = mem.slicer_curr_y mem.slicer_curr_actor_y.display_extent(0, shape[0] - 1, y, y, 0, shape[2] - 1) mem.slicer_curr_actor_z.AddObserver('LeftButtonPressEvent', left_click_picker_callback, 1.0) mem.slicer_curr_actor_x.AddObserver('LeftButtonPressEvent', left_click_picker_callback, 1.0) mem.slicer_curr_actor_y.AddObserver('LeftButtonPressEvent', left_click_picker_callback, 1.0) scene.add(mem.slicer_curr_actor_z) scene.add(mem.slicer_curr_actor_x) scene.add(mem.slicer_curr_actor_y) if pam is not None: scene.add(mem.slicer_peaks_actor_z) r1, r2 = double_slider._values apply_colormap(r1, r2) istyle.force_render() def left_click_picker_callback(obj, ev): ''' Get the value of the clicked voxel and show it in the panel.''' event_pos = iren.GetEventPosition() obj.picker.Pick(event_pos[0], event_pos[1], 0, scene) i, j, k = obj.picker.GetPointIJK() res = mem.slicer_vol[i, j, k] try: message = '%.3f' % res except TypeError: message = '%.3f %.3f %.3f' % (res[0], res[1], res[2]) picker_label.message = '({}, {}, {})'.format(str(i), str(j), str(k)) \ + ' ' + message mem.slicer_vol_idx = 0 mem.slicer_vol = tmp_new mem.slicer_curr_actor_x = image_actor_x mem.slicer_curr_actor_y = image_actor_y mem.slicer_curr_actor_z = image_actor_z if pam is not None: # change_volume.peaks_actor_z = peaks_actor_z mem.slicer_peaks_actor_z = peaks_actor_z mem.slicer_curr_actor_x.AddObserver('LeftButtonPressEvent', left_click_picker_callback, 1.0) mem.slicer_curr_actor_y.AddObserver('LeftButtonPressEvent', left_click_picker_callback, 1.0) mem.slicer_curr_actor_z.AddObserver('LeftButtonPressEvent', left_click_picker_callback, 1.0) if pam is not None: mem.slicer_peaks_actor_z.AddObserver('LeftButtonPressEvent', left_click_picker_callback, 1.0) mem.slicer_curr_x = int(np.round(shape[0] / 2)) mem.slicer_curr_y = int(np.round(shape[1] / 2)) mem.slicer_curr_z = int(np.round(shape[2] / 2)) line_slider_x.on_change = change_slice_x line_slider_y.on_change = change_slice_y line_slider_z.on_change = change_slice_z double_slider.on_change = on_change_ds opacity_slider.on_change = change_opacity volume_slider.handle_events(volume_slider.handle.actor) volume_slider.on_left_mouse_button_released = change_volume line_slider_label_x = build_label(text="X Slice") line_slider_label_x.visibility = True x_counter = itertools.count() def label_callback_x(obj, event): line_slider_label_x.visibility = not line_slider_label_x.visibility line_slider_x.set_visibility(line_slider_label_x.visibility) cnt = next(x_counter) if line_slider_label_x.visibility and cnt > 0: scene.add(mem.slicer_curr_actor_x) else: scene.rm(mem.slicer_curr_actor_x) iren.Render() line_slider_label_x.actor.AddObserver('LeftButtonPressEvent', label_callback_x, 1.0) line_slider_label_y = build_label(text="Y Slice") line_slider_label_y.visibility = True y_counter = itertools.count() def label_callback_y(obj, event): line_slider_label_y.visibility = not line_slider_label_y.visibility line_slider_y.set_visibility(line_slider_label_y.visibility) cnt = next(y_counter) if line_slider_label_y.visibility and cnt > 0: scene.add(mem.slicer_curr_actor_y) else: scene.rm(mem.slicer_curr_actor_y) iren.Render() line_slider_label_y.actor.AddObserver('LeftButtonPressEvent', label_callback_y, 1.0) line_slider_label_z = build_label(text="Z Slice") line_slider_label_z.visibility = True z_counter = itertools.count() def label_callback_z(obj, event): line_slider_label_z.visibility = not line_slider_label_z.visibility line_slider_z.set_visibility(line_slider_label_z.visibility) cnt = next(z_counter) if line_slider_label_z.visibility and cnt > 0: scene.add(mem.slicer_curr_actor_z) else: scene.rm(mem.slicer_curr_actor_z) iren.Render() line_slider_label_z.actor.AddObserver('LeftButtonPressEvent', label_callback_z, 1.0) opacity_slider_label = build_label(text="Opacity") volume_slider_label = build_label(text="Volume") picker_label = build_label(text='') double_slider_label = build_label(text='Colormap') slicer_panel_label = build_label(text="Slicer panel", bold=True) def label_colormap_callback(obj, event): if mem.slicer_colormap_cnt == len(mem.slicer_colormaps) - 1: mem.slicer_colormap_cnt = 0 else: mem.slicer_colormap_cnt += 1 cnt = mem.slicer_colormap_cnt mem.slicer_colormap = mem.slicer_colormaps[cnt] double_slider_label.message = mem.slicer_colormap values = double_slider._values r1, r2 = values apply_colormap(r1, r2) iren.Render() double_slider_label.actor.AddObserver('LeftButtonPressEvent', label_colormap_callback, 1.0) # volume_slider.on_right_mouse_button_released = change_volume2 def label_opacity_callback(obj, event): if opacity_slider.value == 0: opacity_slider.value = 100 opacity_slider.update() slicer_opacity = 1 else: opacity_slider.value = 0 opacity_slider.update() slicer_opacity = 0 mem.slicer_curr_actor_x.opacity(slicer_opacity) mem.slicer_curr_actor_y.opacity(slicer_opacity) mem.slicer_curr_actor_z.opacity(slicer_opacity) iren.Render() opacity_slider_label.actor.AddObserver('LeftButtonPressEvent', label_opacity_callback, 1.0) if data.ndim == 4: panel_size = (320, 400 + 100) if data.ndim == 3: panel_size = (320, 300 + 100) panel = ui.Panel2D(size=panel_size, position=(870, 10), color=(1, 1, 1), opacity=0.1, align="right") ys = np.linspace(0, 1, 10) panel.add_element(line_slider_z, coords=(0.42, ys[1])) panel.add_element(line_slider_y, coords=(0.42, ys[2])) panel.add_element(line_slider_x, coords=(0.42, ys[3])) panel.add_element(opacity_slider, coords=(0.42, ys[4])) panel.add_element(double_slider, coords=(0.42, (ys[7] + ys[8]) / 2.)) if data.ndim == 4: if data.shape[-1] > 3: panel.add_element(volume_slider, coords=(0.42, ys[6])) panel.add_element(line_slider_label_z, coords=(0.1, ys[1])) panel.add_element(line_slider_label_y, coords=(0.1, ys[2])) panel.add_element(line_slider_label_x, coords=(0.1, ys[3])) panel.add_element(opacity_slider_label, coords=(0.1, ys[4])) panel.add_element(double_slider_label, coords=(0.1, (ys[7] + ys[8]) / 2.)) if data.ndim == 4: if data.shape[-1] > 3: panel.add_element(volume_slider_label, coords=(0.1, ys[6])) panel.add_element(picker_label, coords=(0.2, ys[5])) panel.add_element(slicer_panel_label, coords=(0.05, 0.9)) scene.add(panel) # initialize colormap r1, r2 = value_range apply_colormap(r1, r2) return panel
def slicer_panel(renderer, iren, data=None, affine=None, world_coords=False, pam=None, mask=None): """ Slicer panel with slicer included Parameters ---------- renderer : Renderer iren : Interactor data : 3d ndarray affine : 4x4 ndarray world_coords : bool If True then the affine is applied. peaks : PeaksAndMetrics Default None Returns ------- panel : Panel """ orig_shape = data.shape print('Original shape', orig_shape) ndim = data.ndim tmp = data if ndim == 4: if orig_shape[-1] > 3: tmp = data[..., 0] orig_shape = orig_shape[:3] value_range = np.percentile(data[..., 0], q=[2, 98]) if orig_shape[-1] == 3: value_range = (0, 1.) HORIMEM.slicer_rgb = True if ndim == 3: value_range = np.percentile(tmp, q=[2, 98]) if not world_coords: affine = np.eye(4) image_actor_z = actor.slicer(tmp, affine=affine, value_range=value_range, interpolation='nearest', picking_tol=0.025) tmp_new = image_actor_z.resliced_array() if len(data.shape) == 4: if data.shape[-1] == 3: print('Resized to RAS shape ', tmp_new.shape) else: print('Resized to RAS shape ', tmp_new.shape + (data.shape[-1], )) else: print('Resized to RAS shape ', tmp_new.shape) shape = tmp_new.shape if pam is not None: peaks_actor_z = actor.peak_slicer(pam.peak_dirs, None, mask=mask, affine=affine, colors=None) slicer_opacity = 1. image_actor_z.opacity(slicer_opacity) image_actor_x = image_actor_z.copy() x_midpoint = int(np.round(shape[0] / 2)) image_actor_x.display_extent(x_midpoint, x_midpoint, 0, shape[1] - 1, 0, shape[2] - 1) image_actor_y = image_actor_z.copy() y_midpoint = int(np.round(shape[1] / 2)) image_actor_y.display_extent(0, shape[0] - 1, y_midpoint, y_midpoint, 0, shape[2] - 1) renderer.add(image_actor_z) renderer.add(image_actor_x) renderer.add(image_actor_y) if pam is not None: renderer.add(peaks_actor_z) line_slider_z = ui.LineSlider2D(min_value=0, max_value=shape[2] - 1, initial_value=shape[2] / 2, text_template="{value:.0f}", length=140) _color_slider(line_slider_z) button = ui.Button2D(icon_fnames, size=(20, 30)) def change_slice_z(slider): z = int(np.round(slider.value)) HORIMEM.slicer_curr_actor_z.display_extent(0, shape[0] - 1, 0, shape[1] - 1, z, z) if pam is not None: HORIMEM.slicer_peaks_actor_z.display_extent( 0, shape[0] - 1, 0, shape[1] - 1, z, z) HORIMEM.slicer_curr_z = z line_slider_x = ui.LineSlider2D(min_value=0, max_value=shape[0] - 1, initial_value=shape[0] / 2, text_template="{value:.0f}", length=140) _color_slider(line_slider_x) def change_slice_x(slider): x = int(np.round(slider.value)) HORIMEM.slicer_curr_actor_x.display_extent(x, x, 0, shape[1] - 1, 0, shape[2] - 1) HORIMEM.slicer_curr_x = x HORIMEM.window_timer_cnt += 100 line_slider_y = ui.LineSlider2D(min_value=0, max_value=shape[1] - 1, initial_value=shape[1] / 2, text_template="{value:.0f}", length=140) _color_slider(line_slider_y) def change_slice_y(slider): y = int(np.round(slider.value)) HORIMEM.slicer_curr_actor_y.display_extent(0, shape[0] - 1, y, y, 0, shape[2] - 1) HORIMEM.slicer_curr_y = y double_slider = ui.LineDoubleSlider2D(length=140, initial_values=value_range, min_value=tmp.min(), max_value=tmp.max(), shape='square') _color_dslider(double_slider) def apply_colormap(r1, r2): if HORIMEM.slicer_rgb: return if HORIMEM.slicer_colormap == 'disting': # use distinguishable colors rgb = colormap.distinguishable_colormap(nb_colors=256) rgb = np.asarray(rgb) else: # use matplotlib colormaps rgb = colormap.create_colormap(np.linspace(r1, r2, 256), name=HORIMEM.slicer_colormap, auto=True) N = rgb.shape[0] lut = colormap.vtk.vtkLookupTable() lut.SetNumberOfTableValues(N) lut.SetRange(r1, r2) for i in range(N): r, g, b = rgb[i] lut.SetTableValue(i, r, g, b) lut.SetRampToLinear() lut.Build() HORIMEM.slicer_curr_actor_z.output.SetLookupTable(lut) HORIMEM.slicer_curr_actor_z.output.Update() def on_change_ds(slider): values = slider._values r1, r2 = values apply_colormap(r1, r2) double_slider.on_change = on_change_ds opacity_slider = ui.LineSlider2D(min_value=0.0, max_value=1.0, initial_value=slicer_opacity, length=140, text_template="{ratio:.0%}") _color_slider(opacity_slider) def change_opacity(slider): slicer_opacity = slider.value HORIMEM.slicer_curr_actor_x.opacity(slicer_opacity) HORIMEM.slicer_curr_actor_y.opacity(slicer_opacity) HORIMEM.slicer_curr_actor_z.opacity(slicer_opacity) volume_slider = ui.LineSlider2D(min_value=0, max_value=data.shape[-1] - 1, initial_value=0, length=140, text_template="{value:.0f}", shape='square') _color_slider(volume_slider) def change_volume(istyle, obj, slider): vol_idx = int(np.round(slider.value)) HORIMEM.slicer_vol_idx = vol_idx renderer.rm(HORIMEM.slicer_curr_actor_x) renderer.rm(HORIMEM.slicer_curr_actor_y) renderer.rm(HORIMEM.slicer_curr_actor_z) tmp = data[..., vol_idx] image_actor_z = actor.slicer(tmp, affine=affine, value_range=value_range, interpolation='nearest', picking_tol=0.025) tmp_new = image_actor_z.resliced_array() HORIMEM.slicer_vol = tmp_new z = HORIMEM.slicer_curr_z image_actor_z.display_extent(0, shape[0] - 1, 0, shape[1] - 1, z, z) HORIMEM.slicer_curr_actor_z = image_actor_z HORIMEM.slicer_curr_actor_x = image_actor_z.copy() if pam is not None: HORIMEM.slicer_peaks_actor_z = peaks_actor_z x = HORIMEM.slicer_curr_x HORIMEM.slicer_curr_actor_x.display_extent(x, x, 0, shape[1] - 1, 0, shape[2] - 1) HORIMEM.slicer_curr_actor_y = image_actor_z.copy() y = HORIMEM.slicer_curr_y HORIMEM.slicer_curr_actor_y.display_extent(0, shape[0] - 1, y, y, 0, shape[2] - 1) HORIMEM.slicer_curr_actor_z.AddObserver('LeftButtonPressEvent', left_click_picker_callback, 1.0) HORIMEM.slicer_curr_actor_x.AddObserver('LeftButtonPressEvent', left_click_picker_callback, 1.0) HORIMEM.slicer_curr_actor_y.AddObserver('LeftButtonPressEvent', left_click_picker_callback, 1.0) renderer.add(HORIMEM.slicer_curr_actor_z) renderer.add(HORIMEM.slicer_curr_actor_x) renderer.add(HORIMEM.slicer_curr_actor_y) if pam is not None: renderer.add(HORIMEM.slicer_peaks_actor_z) r1, r2 = double_slider._values apply_colormap(r1, r2) istyle.force_render() def left_click_picker_callback(obj, ev): ''' Get the value of the clicked voxel and show it in the panel.''' event_pos = iren.GetEventPosition() obj.picker.Pick(event_pos[0], event_pos[1], 0, renderer) i, j, k = obj.picker.GetPointIJK() res = HORIMEM.slicer_vol[i, j, k] # generate figure cc_vox = data[i, j, k] print(cc_vox) plt.plot([cc_vox]) plt.savefig('test.png') icon_fnames = [('square', 'test.png'), ('square1', 'test.png')] # connect to button button = ui.Button2D(icon_fnames, size=(20, 30)) panel.add_element(button, coords=(0., 0.)) # make button visible try: message = '%.3f' % res except TypeError: message = '%.3f %.3f %.3f' % (res[0], res[1], res[2]) picker_label.message = '({}, {}, {})'.format(str(i), str(j), str(k)) \ + ' ' + message HORIMEM.slicer_vol_idx = 0 HORIMEM.slicer_vol = tmp_new HORIMEM.slicer_curr_actor_x = image_actor_x HORIMEM.slicer_curr_actor_y = image_actor_y HORIMEM.slicer_curr_actor_z = image_actor_z if pam is not None: # change_volume.peaks_actor_z = peaks_actor_z HORIMEM.slicer_peaks_actor_z = peaks_actor_z HORIMEM.slicer_curr_actor_x.AddObserver('LeftButtonPressEvent', left_click_picker_callback, 1.0) HORIMEM.slicer_curr_actor_y.AddObserver('LeftButtonPressEvent', left_click_picker_callback, 1.0) HORIMEM.slicer_curr_actor_z.AddObserver('LeftButtonPressEvent', left_click_picker_callback, 1.0) if pam is not None: HORIMEM.slicer_peaks_actor_z.AddObserver('LeftButtonPressEvent', left_click_picker_callback, 1.0) HORIMEM.slicer_curr_x = int(np.round(shape[0] / 2)) HORIMEM.slicer_curr_y = int(np.round(shape[1] / 2)) HORIMEM.slicer_curr_z = int(np.round(shape[2] / 2)) line_slider_x.on_change = change_slice_x line_slider_y.on_change = change_slice_y line_slider_z.on_change = change_slice_z double_slider.on_change = on_change_ds opacity_slider.on_change = change_opacity volume_slider.handle_events(volume_slider.handle.actor) volume_slider.on_left_mouse_button_released = change_volume # volume_slider.on_right_mouse_button_released = change_volume2 line_slider_label_x = build_label(text="X Slice") line_slider_label_x.visibility = True x_counter = itertools.count() def label_callback_x(obj, event): line_slider_label_x.visibility = not line_slider_label_x.visibility line_slider_x.set_visibility(line_slider_label_x.visibility) cnt = next(x_counter) if line_slider_label_x.visibility and cnt > 0: renderer.add(HORIMEM.slicer_curr_actor_x) else: renderer.rm(HORIMEM.slicer_curr_actor_x) iren.Render() line_slider_label_x.actor.AddObserver('LeftButtonPressEvent', label_callback_x, 1.0) line_slider_label_y = build_label(text="Y Slice") line_slider_label_y.visibility = True y_counter = itertools.count() def label_callback_y(obj, event): line_slider_label_y.visibility = not line_slider_label_y.visibility line_slider_y.set_visibility(line_slider_label_y.visibility) cnt = next(y_counter) if line_slider_label_y.visibility and cnt > 0: renderer.add(HORIMEM.slicer_curr_actor_y) else: renderer.rm(HORIMEM.slicer_curr_actor_y) iren.Render() line_slider_label_y.actor.AddObserver('LeftButtonPressEvent', label_callback_y, 1.0) line_slider_label_z = build_label(text="Z Slice") line_slider_label_z.visibility = True z_counter = itertools.count() def label_callback_z(obj, event): line_slider_label_z.visibility = not line_slider_label_z.visibility line_slider_z.set_visibility(line_slider_label_z.visibility) cnt = next(z_counter) if line_slider_label_z.visibility and cnt > 0: renderer.add(HORIMEM.slicer_curr_actor_z) else: renderer.rm(HORIMEM.slicer_curr_actor_z) iren.Render() line_slider_label_z.actor.AddObserver('LeftButtonPressEvent', label_callback_z, 1.0) opacity_slider_label = build_label(text="Opacity") volume_slider_label = build_label(text="Volume") picker_label = build_label(text='') double_slider_label = build_label(text='Colormap') def label_colormap_callback(obj, event): if HORIMEM.slicer_colormap_cnt == len(HORIMEM.slicer_colormaps) - 1: HORIMEM.slicer_colormap_cnt = 0 else: HORIMEM.slicer_colormap_cnt += 1 cnt = HORIMEM.slicer_colormap_cnt HORIMEM.slicer_colormap = HORIMEM.slicer_colormaps[cnt] double_slider_label.message = HORIMEM.slicer_colormap values = double_slider._values r1, r2 = values apply_colormap(r1, r2) iren.Render() double_slider_label.actor.AddObserver('LeftButtonPressEvent', label_colormap_callback, 1.0) if data.ndim == 4: panel_size = (400, 400 + 100) if data.ndim == 3: panel_size = (400, 300 + 100) panel = ui.Panel2D(size=panel_size, position=(850, 110), color=(1, 1, 1), opacity=0.1, align="right") ys = np.linspace(0, 1, 10) panel.add_element(line_slider_z, coords=(0.4, ys[1])) panel.add_element(line_slider_y, coords=(0.4, ys[2])) panel.add_element(line_slider_x, coords=(0.4, ys[3])) panel.add_element(opacity_slider, coords=(0.4, ys[4])) panel.add_element(double_slider, coords=(0.4, (ys[7] + ys[8]) / 2.)) if data.ndim == 4: if data.shape[-1] > 3: panel.add_element(volume_slider, coords=(0.4, ys[6])) panel.add_element(line_slider_label_z, coords=(0.1, ys[1])) panel.add_element(line_slider_label_y, coords=(0.1, ys[2])) panel.add_element(line_slider_label_x, coords=(0.1, ys[3])) panel.add_element(opacity_slider_label, coords=(0.1, ys[4])) panel.add_element(double_slider_label, coords=(0.1, (ys[7] + ys[8]) / 2.)) if data.ndim == 4: if data.shape[-1] > 3: panel.add_element(volume_slider_label, coords=(0.1, ys[6])) panel.add_element(picker_label, coords=(0.2, ys[5])) renderer.add(panel) # initialize colormap r1, r2 = value_range apply_colormap(r1, r2) return panel
In Dipy we also provide tools for finding the peak directions (maxima) of the ODFs. For this purpose we recommend using ``peaks_from_model``. """ from dipy.direction import peaks_from_model csd_peaks = peaks_from_model(model=csd_model, data=data_small, sphere=sphere, relative_peak_threshold=.5, min_separation_angle=25, parallel=True) window.clear(ren) fodf_peaks = actor.peak_slicer(csd_peaks.peak_dirs, csd_peaks.peak_values, scale=1.3) ren.add(fodf_peaks) print('Saving illustration as csd_peaks.png') window.record(ren, out_path='csd_peaks.png', size=(600, 600)) if interactive: window.show(ren) """ .. figure:: csd_peaks.png :align: center CSD Peaks. We can finally visualize both the ODFs and peaks in the same space. """
def show_peaks(pam): renderer = window.Renderer() peaks = actor.peak_slicer(pam.peak_dirs, colors=None) renderer.add(peaks) window.show(renderer)
window.show(ren) """ We can extract the peaks from the ODF, and plot these as well """ sf_peaks = dpp.peaks_from_model(sf_model, data_small, sphere, relative_peak_threshold=.5, min_separation_angle=25, return_sh=False) window.clear(ren) fodf_peaks = actor.peak_slicer(sf_peaks.peak_dirs, sf_peaks.peak_values) ren.add(fodf_peaks) print('Saving illustration as sf_peaks.png') window.record(ren, out_path='sf_peaks.png', size=(1000, 1000)) if interactive: window.show(ren) """ Finally, we plot both the peaks and the ODFs, overlayed: """ fodf_spheres.GetProperty().SetOpacity(0.4) ren.add(fodf_spheres) print('Saving illustration as sf_both.png')
print('Started CSD') response, ratio = auto_response(gtab, data, roi_radius=10, fa_thr=0.7) print('Finished response') csd_model = ConstrainedSphericalDeconvModel(gtab, response) csd_peaks = peaks_from_model(model=csd_model, data=data, sphere=sphere, mask=mask, relative_peak_threshold=.5, min_separation_angle=25, parallel=True) # using the peak_slicer peak_actor = actor.peak_slicer(csd_peaks.peak_dirs, csd_peaks.peak_values, colors=None) slider(peak_actor, None) #generating streamlines tissue_classifier = ThresholdTissueClassifier(tenfit.fa, 0.1) seeds = random_seeds_from_mask(tenfit.fa > 0.3, seeds_count=5) streamline_generator = LocalTracking(csd_peaks, tissue_classifier, seeds, affine=np.eye(4), step_size=0.5, return_all=True)
data=data_small, sphere=sphere, relative_peak_threshold=.5, min_separation_angle=25, normalize_peaks=False, parallel=True, num_processes=4) """ For visualization, we scale up the peak values. """ peak_values = np.clip(rumba_peaks.peak_values * 15, 0, 1) peak_dirs = rumba_peaks.peak_dirs fodf_peaks = actor.peak_slicer(peak_dirs, peak_values) scene.add(fodf_peaks) print('Saving illustration as rumba_peaks.png') window.record(scene, out_path='rumba_peaks.png', size=(600, 600)) if interactive: window.show(scene) """ .. figure:: rumba_peaks.png :align: center RUMBA-SD peaks """ scene.rm(fodf_peaks)