def calculate_fodf(gtab, images, name, sphere=default_sphere, radius=10, fa_threshold=0.7): response, ratio = auto_response(gtab, images, roi_radius=radius, fa_thr=fa_threshold) csd_model = ConstrainedSphericalDeconvModel(gtab, response) csd_fit = csd_model.fit(images) csd_odf = csd_fit.odf(sphere) fodf_spheres = actor.odf_slicer(csd_odf, sphere=sphere, scale=0.9, norm=False, colormap='plasma') ren = window.Scene() ren.add(fodf_spheres) print('Saving illustration as csd_odfs_{}.png'.format(name)) window.record(ren, out_path='results/csd_odfs_{}.png'.format(name), size=(600, 600)) return csd_fit
def visualize_pdf(pdf, gtab=None): signal = pdf s = signal.shape grid_s = math.ceil((signal.shape[-1])**(1 / 3)) signal = signal.reshape(*s[:-1], grid_s, grid_s, grid_s) sphere = get_sphere('repulsion724') if gtab: dsmodel = DiffusionSpectrumModel(gtab) signal_xq = np.fft.fftn(signal, axes=[-3, -2, -1]) dsfit = dsmodel.fit(signal_xq.reshape(*s[:2], -1)) odfs = dsfit.odf(sphere) else: signal = signal.reshape(-1, grid_s, grid_s, grid_s) odfs = np.stack([ get_odf(signal[vid], sphere) for vid in range(signal.shape[0]) ]).reshape(*s[:-1], -1) if len(odfs.shape) == 3: odfs = odfs[:, :, np.newaxis] # visualize r = window.Scene() sfu = actor.odf_slicer(odfs, sphere=sphere, colormap='plasma', scale=0.5) sfu.display(z=0) r.add(sfu) window.show(r)
def print_peaks(sh_signal, mask=None): if has_fury: data_small = sh_signal[:, :, 50:51] ren = window.Renderer() sh_order = order_from_ncoef(data_small.shape[-1]) theta = default_sphere.theta phi = default_sphere.phi sh_params = SIGNAL_PARAMETERS['processing_params']['sh_params'] basis_type = sh_params['basis_type'] sph_harm_basis = sph_harm_lookup.get(basis_type) sampling_matrix, m, n = sph_harm_basis(sh_order, theta, phi) odfs = np.dot(data_small, sampling_matrix.T) odfs = np.clip(odfs, 0, np.max(odfs, -1)[..., None]) odfs_actor = actor.odf_slicer(odfs, sphere=default_sphere, colormap='plasma', scale=0.4) odfs_actor.display(z=0) ren.add(odfs_actor) print('Saving illustration as csa_odfs.png') window.record(ren, n_frames=1, out_path='csa_odfs.png', size=(600, 600)) window.show(ren)
def plot_response(response_src, out_png=False): # start virtual display print("starting Xvfb"); vdisplay = Xvfb() vdisplay.start() response_src = np.loadtxt(src_txt) if len(response_src.shape) > 1: response_src = response_src[1] sphere = get_sphere('symmetric724') sh_resp = AxSymShResponse(0, response_src) sig_resp = sh_resp.on_sphere(sphere) sig_resp = sig_resp[None, None, None, :] ren = window.Renderer() sphere_actor = actor.odf_slicer(sig_resp, sphere=sphere,colormap='blues') ren.add(sphere_actor) my_camera = ren.camera() my_camera.SetPosition(1.62, -9.19, 4.01) my_camera.SetFocalPoint(0.01, -0.46, -0.19) my_camera.SetViewUp(0.24, 0.46, 0.86) if out_png != False: window.record(ren, out_path=out_png, magnification=10, size=(60, 60)) else: window.show(ren, reset_camera=False) print('Camera Settings') print('Position: ', '(%.2f, %.2f, %.2f)' % my_camera.GetPosition()) print('Focal Point: ', '(%.2f, %.2f, %.2f)' % my_camera.GetFocalPoint()) print('View Up: ', '(%.2f, %.2f, %.2f)' % my_camera.GetViewUp()) vdisplay.stop()
def vis_2d_field(odf, sphere): """ Visualize a 2D ODF field. """ r = window.Renderer() sfu = actor.odf_slicer(odf.reshape(1, *odf.shape), sphere=sphere, colormap='plasma', scale=0.5) sfu.display(x=0) r.add(sfu) window.show(r)
def calculate_fod(self, model): sphere = get_sphere(name='symmetric724').subdivide() print("calculating fod") fods = model.fod(sphere.vertices, visual_odi_lower_bound=0.18) print("finsih fod calculation. Start odf splicer") fod_spheres = actor.odf_slicer(fods, sphere=sphere, scale=1.0, norm=False, opacity=1.0) print("finish splicer") return fod_spheres
def show_odf_slicer(mcsd_model, data, slice): mcsd_fit = mcsd_model.fit(data[:, :, slice]) mcsd_odf = mcsd_fit.odf(sphere) fodf_spheres = actor.odf_slicer(mcsd_odf, sphere=sphere, scale=0.01, norm=False, colormap='plasma') interactive = False ren = window.Renderer() ren.add(fodf_spheres) ren.reset_camera_tight() print('Saving illustration as msdodf.png') window.record(ren, out_path='msdodf.png', size=(600, 600)) if interactive: window.show(ren)
def qball(gtab, data, name, sh_order=4): qballmodel = QballModel(gtab, sh_order) data_small = data[:, :, 39:40] qball_fit = qballmodel.fit(data_small) qball_odf = qball_fit.odf(default_sphere) odf_spheres = actor.odf_slicer(qball_odf, sphere=default_sphere, scale=0.9, norm=False, colormap='plasma') ren = window.Scene() ren.add(odf_spheres) print('Saving illustration as qball_odfs_{}.png'.format( name)) #data.shape[-1] - 1)) window.record(ren, out_path='results/qball_odfs_{}.png'.format(name), size=(600, 600)) return qball_odf, qball_fit.shm_coeff
def calculate_odf(gtab, data, sh_order=4): csamodel = CsaOdfModel(gtab, sh_order) data_small = data[30:65, 40:75, 39:40] csa_odf = csamodel.fit(data_small).odf(default_sphere) csa_odf = np.clip(csa_odf, 0, np.max(csa_odf, -1)[..., None]) odf_spheres = actor.odf_slicer(csa_odf, sphere=default_sphere, scale=0.9, norm=False, colormap='plasma') ren = window.Scene() ren.add(odf_spheres) print('Saving illustration as csa_odfs_{}.png'.format(data.shape[-1] - 1)) window.record(ren, out_path='results/csa_odfs_{}.png'.format(data.shape[-1] - 1), size=(600, 600)) return csa_odf
def test_odf_slicer(interactive=False): sphere = get_sphere('symmetric362') shape = (11, 11, 11, sphere.vertices.shape[0]) fid, fname = mkstemp(suffix='_odf_slicer.mmap') print(fid) print(fname) odfs = np.memmap(fname, dtype=np.float64, mode='w+', shape=shape) odfs[:] = 1 affine = np.eye(4) renderer = window.Renderer() mask = np.ones(odfs.shape[:3]) mask[:4, :4, :4] = 0 odfs[..., 0] = 1 odf_actor = actor.odf_slicer(odfs, affine, mask=mask, sphere=sphere, scale=.25, colormap='jet') fa = 0. * np.zeros(odfs.shape[:3]) fa[:, 0, :] = 1. fa[:, -1, :] = 1. fa[0, :, :] = 1. fa[-1, :, :] = 1. fa[5, 5, 5] = 1 k = 5 I, J, K = odfs.shape[:3] fa_actor = actor.slicer(fa, affine) fa_actor.display_extent(0, I, 0, J, k, k) renderer.add(odf_actor) renderer.reset_camera() renderer.reset_clipping_range() odf_actor.display_extent(0, I, 0, J, k, k) odf_actor.GetProperty().SetOpacity(1.0) if interactive: window.show(renderer, reset_camera=False) arr = window.snapshot(renderer) report = window.analyze_snapshot(arr, find_objects=True) npt.assert_equal(report.objects, 11 * 11) renderer.clear() renderer.add(fa_actor) renderer.reset_camera() renderer.reset_clipping_range() if interactive: window.show(renderer) mask[:] = 0 mask[5, 5, 5] = 1 fa[5, 5, 5] = 0 fa_actor = actor.slicer(fa, None) fa_actor.display(None, None, 5) odf_actor = actor.odf_slicer(odfs, None, mask=mask, sphere=sphere, scale=.25, colormap='jet', norm=False, global_cm=True) renderer.clear() renderer.add(fa_actor) renderer.add(odf_actor) renderer.reset_camera() renderer.reset_clipping_range() if interactive: window.show(renderer) renderer.clear() renderer.add(odf_actor) renderer.add(fa_actor) odfs[:, :, :] = 1 mask = np.ones(odfs.shape[:3]) odf_actor = actor.odf_slicer(odfs, None, mask=mask, sphere=sphere, scale=.25, colormap='jet', norm=False, global_cm=True) renderer.clear() renderer.add(odf_actor) renderer.add(fa_actor) renderer.add(actor.axes((11, 11, 11))) for i in range(11): odf_actor.display(i, None, None) fa_actor.display(i, None, None) if interactive: window.show(renderer) for j in range(11): odf_actor.display(None, j, None) fa_actor.display(None, j, None) if interactive: window.show(renderer) # with mask equal to zero everything should be black mask = np.zeros(odfs.shape[:3]) odf_actor = actor.odf_slicer(odfs, None, mask=mask, sphere=sphere, scale=.25, colormap='plasma', norm=False, global_cm=True) renderer.clear() renderer.add(odf_actor) renderer.reset_camera() renderer.reset_clipping_range() if interactive: window.show(renderer) report = window.analyze_renderer(renderer) npt.assert_equal(report.actors, 1) npt.assert_equal(report.actors_classnames[0], 'vtkLODActor') del odf_actor odfs._mmap.close() del odfs os.close(fid) os.remove(fname)
from dipy.viz import window, actor # Enables/disables interactive visualization interactive = False ren = window.Renderer() evals = response[0] evecs = np.array([[0, 1, 0], [0, 0, 1], [1, 0, 0]]).T from dipy.data import get_sphere sphere = get_sphere('symmetric724') from dipy.sims.voxel import single_tensor_odf response_odf = single_tensor_odf(sphere.vertices, evals, evecs) # transform our data from 1D to 4D response_odf = response_odf[None, None, None, :] response_actor = actor.odf_slicer(response_odf, sphere=sphere, colormap='jet') ren.add(response_actor) print('Saving illustration as csd_response.png') window.record(ren, out_path='csd_response.png', size=(200, 200)) if interactive: window.show(ren) """ .. figure:: csd_response.png :align: center Estimated response function. """ ren.rm(response_actor) """
hcp_fod_pkl_path = r'/nfs/masi/nathv/hcp_fod_sig.pkl' with open(hcp_sig_pkl_path, 'rb') as fin: dw_signal = pickle.load(fin) with open(hcp_fod_pkl_path, 'rb') as fin2: fod_signal = pickle.load(fin2) #sh_slice = dw_signal[:, :, 0, 0] #plt.imshow(rotate(np.squeeze(dw_signal[:, :, 0, 1]), 90)) #plt.show() dw_slice = dw_signal[44:60, 120:136, :, :] fod_slice = fod_signal[44:60, 120:136, :, :] dw_spheres = actor.odf_slicer(dw_signal, sphere=sph, scale=0.9, norm=True) ren = window.Renderer() ren.add(dw_spheres) window.show(ren) #slice = dw_sig_full_sphere[rand_indx, :] #slice_re = slice.reshape([8, 8, 1, 200]) dw_spheres = actor.odf_slicer(dw_slice, sphere=sph, scale=0.9, norm=False) ren = window.Renderer() ren.add(dw_spheres) window.show(ren) fod_spheres = actor.odf_slicer(fod_slice, sphere=sph, scale=0.9, norm=False) ren = window.Renderer() ren.add(fod_spheres) window.show(ren)
""" For the purpose of the example, we will consider a small volume of data containing parts of the corpus callosum and of the centrum semiovale """ data_small = data[20:50, 55:85, 38:39] """ Fitting the model to this small volume of data, we calculate the ODF of this model on the sphere, and plot it. """ sf_fit = sf_model.fit(data_small) sf_odf = sf_fit.odf(sphere) fodf_spheres = actor.odf_slicer(sf_odf, sphere=sphere, scale=1.3, colormap='plasma') ren = window.Renderer() ren.add(fodf_spheres) print('Saving illustration as sf_odfs.png') 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,
def show_odfs_and_fa(fa, pam, mask, affine, sphere, ftmp='odf.mmap', basis_type=None, norm_odfs=True, scale_odfs=0.5): renderer = window.Renderer() renderer.background((1, 1, 1)) slice_actor = actor.slicer(fa) #, value_range) odf_shape = fa.shape + (sphere.vertices.shape[0],) odfs = np.memmap(ftmp, dtype=np.float32, mode='w+', shape=odf_shape) sph_harm_basis = sph_harm_lookup.get(basis_type) if sph_harm_basis is None: raise ValueError("Invalid basis name.") B, m, n = sph_harm_basis(8, sphere.theta, sphere.phi) odfs[:] = np.dot(pam.shm_coeff.astype('f4'), B.T.astype('f4')) odf_slicer = actor.odf_slicer(odfs, mask=mask, sphere=sphere, scale=scale_odfs, norm=norm_odfs, colormap='magma') renderer.add(odf_slicer) renderer.add(slice_actor) show_m = window.ShowManager(renderer, size=(2000, 1000)) show_m.initialize() """ We'll start by creating the panel and adding it to the ``ShowManager`` """ label_position = ui.TextBlock2D(text='Position:') label_value = ui.TextBlock2D(text='Value:') result_position = ui.TextBlock2D(text='') result_value = ui.TextBlock2D(text='') line_slider_z = ui.LineSlider2D(min_value=0, max_value=shape[2] - 1, initial_value=shape[2] / 2, text_template="{value:.0f}", length=140) def change_slice_z(i_ren, obj, slider): z = int(np.round(slider.value)) slice_actor.display(z=z) odf_slicer.display(z=z) show_m.render() line_slider_z.add_callback(line_slider_z.slider_disk, "LeftButtonReleaseEvent", change_slice_z) panel_picking = ui.Panel2D(center=(200, 120), size=(250, 225), color=(0, 0, 0), opacity=0.75, align="left") # panel_picking.add_element(label_position, 'relative', (0.1, 0.55)) # panel_picking.add_element(label_value, 'relative', (0.1, 0.25)) # panel_picking.add_element(result_position, 'relative', (0.45, 0.55)) # panel_picking.add_element(result_value, 'relative', (0.45, 0.25)) panel_picking.add_element(line_slider_z, 'relative', (0.5, 0.9)) show_m.ren.add(panel_picking) def left_click_callback(obj, ev): """Get the value of the clicked voxel and show it in the panel.""" event_pos = show_m.iren.GetEventPosition() obj.picker.Pick(event_pos[0], event_pos[1], 0, show_m.ren) i, j, k = obj.picker.GetPointIJK() print(i,j,k) result_position.message = '({}, {}, {})'.format(str(i), str(j), str(k)) result_value.message = '%.3f' % fa[i, j, k] slice_actor.SetInterpolate(True) slice_actor.AddObserver('LeftButtonPressEvent', left_click_callback, 1.0) show_m.start() odfs._mmap.close() del odfs os.remove(ftmp)
""" Compute the ODFs """ odf = asmfit.odf(sphere) print('odf.shape (%d, %d, %d)' % odf.shape) """ Display the ODFs """ # Enables/disables interactive visualization interactive = False ren = window.Renderer() sfu = actor.odf_slicer(odf[:, None, :], sphere=sphere, colormap='jet', scale=0.5) sfu.RotateX(-90) sfu.display(y=0) ren.add(sfu) window.record(ren, out_path='odfs.png', size=(600, 600)) if interactive: window.show(ren) """ .. figure:: odfs.png :align: center Orientation distribution functions. References ----------
The radial order ``s`` can be increased to sharpen the results, but it might also make the ODFs noisier. Always check the results visually. """ odf = mapfit_both_iso.odf(sphere, s=2) print('odf.shape (%d, %d, %d, %d)' % odf.shape) """ Display the ODFs. """ # Enables/disables interactive visualization interactive = False r = window.Renderer() sfu = actor.odf_slicer(odf, sphere=sphere, colormap='plasma', scale=0.5) sfu.display(y=0) sfu.RotateX(-90) r.add(sfu) window.record(r, out_path='odfs.png', size=(600, 600)) if interactive: window.show(r) """ .. figure:: odfs.png :align: center Orientation distribution functions (ODFs). References ----------
.. figure:: tensor_ellipsoids.png :align: center Tensor Ellipsoids. """ window.clear(ren) """ Finally, we can visualize the tensor Orientation Distribution Functions for the same area as we did with the ellipsoids. """ tensor_odfs = tenmodel.fit(data[20:50, 55:85, 38:39]).odf(sphere) odf_actor = actor.odf_slicer(tensor_odfs, sphere=sphere, scale=0.5, colormap=None) ren.add(odf_actor) print('Saving illustration as tensor_odfs.png') window.record(ren, n_frames=1, out_path='tensor_odfs.png', size=(600, 600)) if interactive: window.show(ren) """ .. figure:: tensor_odfs.png :align: center Tensor ODFs. Note that while the tensor model is an accurate and reliable model of the diffusion signal in the white matter, it has the drawback that it only has one principal diffusion direction. Therefore, in locations in the brain that
""" sphere = get_sphere('symmetric724') sphere = sphere.subdivide(2) odf = multi_tensor_odf(sphere.vertices, mevals, angles, fractions) from dipy.viz import window, actor # Enables/disables interactive visualization interactive = False ren = window.Renderer() odf_actor = actor.odf_slicer(odf[None, None, None, :], sphere=sphere, colormap='plasma') odf_actor.RotateX(90) ren.add(odf_actor) print('Saving illustration as multi_tensor_simulation') window.record(ren, out_path='multi_tensor_simulation.png', size=(300, 300)) if interactive: window.show(ren) """ .. figure:: multi_tensor_simulation.png :align: center Simulating a MultiTensor ODF.
from dipy.viz import window, actor # Enables/disables interactive visualization interactive = False ren = window.Renderer() csaodfs = csamodel.fit(data_small).odf(default_sphere) """ It is common with CSA ODFs to produce negative values, we can remove those using ``np.clip`` """ csaodfs = np.clip(csaodfs, 0, np.max(csaodfs, -1)[..., None]) csa_odfs_actor = actor.odf_slicer(csaodfs, sphere=default_sphere, colormap='plasma', scale=0.4) csa_odfs_actor.display(z=0) ren.add(csa_odfs_actor) print('Saving illustration as csa_odfs.png') window.record(ren, n_frames=1, out_path='csa_odfs.png', size=(600, 600)) if interactive: window.show(ren) """ .. figure:: csa_odfs.png :align: center Constant Solid Angle ODFs. .. include:: ../links_names.inc
from dipy.viz import window, actor # Enables/disables interactive visualization interactive = False r = window.Renderer() csaodfs = csamodel.fit(data_small).odf(sphere) """ It is common with CSA ODFs to produce negative values, we can remove those using ``np.clip`` """ csaodfs = np.clip(csaodfs, 0, np.max(csaodfs, -1)[..., None]) csa_odfs_actor = actor.odf_slicer(csaodfs, sphere=sphere, colormap='jet', scale=0.4) csa_odfs_actor.display(z=0) r.add(csa_odfs_actor) print('Saving illustration as csa_odfs.png') window.record(r, n_frames=1, out_path='csa_odfs.png', size=(600, 600)) if interactive: window.show(r) """ .. figure:: csa_odfs.png :align: center Constant Solid Angle ODFs. .. include:: ../links_names.inc
def dMRI2ODF_DTI(PATH): ''' Input the dMRI data return the ODF ''' dMRI_path = PATH + 'data.nii.gz' mask_path = PATH + 'nodif_brain_mask.nii.gz' dMRI_img = nib.load(dMRI_path) dMRI_data = dMRI_img.get_fdata() mask_img = nib.load(mask_path) mask = mask_img.get_fdata() ########## subsample ########## # dMRI_data = dMRI_data[45:-48,50:-65,51:-54,...] # mask = mask[45:-48,50:-65,51:-54] # breakpoint() dMRI_data = dMRI_data[:, 87, ...] mask = mask[:, 87, ...] for cnt in range(10): fig = plt.imshow(dMRI_data[:, :, cnt].transpose(1, 0), cmap='Greys', interpolation='nearest') plt.axis('off') # plt.imshow(dMRI_data[:,15,:,cnt].transpose(1,0),cmap='Greys') plt.savefig(str(cnt) + '.png', bbox_inches='tight', dpi=300, transparent=True, pad_inches=0) # breakpoint() bval = PATH + "bvals" bvec = PATH + "bvecs" radial_order = 6 zeta = 700 lambdaN = 1e-8 lambdaL = 1e-8 gtab = gradient_table(bvals=bval, bvecs=bvec) asm = ShoreModel(gtab, radial_order=radial_order, zeta=zeta, lambdaN=lambdaN, lambdaL=lambdaL) asmfit = asm.fit(dMRI_data, mask=mask) sphere = get_sphere('symmetric362') dMRI_odf = asmfit.odf(sphere) dMRI_odf[dMRI_odf <= 0] = 0 tenmodel = dti.TensorModel(gtab) tenfit = tenmodel.fit(dMRI_data, mask) dMRI_dti = tenfit.quadratic_form FA = fractional_anisotropy(tenfit.evals) FA[np.isnan(FA)] = 0 FA = np.clip(FA, 0, 1) RGB = color_fa(FA, tenfit.evecs) evals = tenfit.evals + 1e-20 evecs = tenfit.evecs cfa = RGB + 1e-20 cfa /= cfa.max() evals = np.expand_dims(evals, 2) evecs = np.expand_dims(evecs, 2) cfa = np.expand_dims(cfa, 2) ren = window.Scene() sphere = get_sphere('symmetric362') ren.add( actor.tensor_slicer(evals, evecs, scalar_colors=cfa, sphere=sphere, scale=0.5)) window.record(ren, n_frames=1, out_path='../data/tensor.png', size=(5000, 5000)) odf_ = dMRI_odf ren = window.Scene() sfu = actor.odf_slicer(np.expand_dims(odf_, 2), sphere=sphere, colormap="plasma", scale=0.5) ren.add(sfu) window.record(ren, n_frames=1, out_path='../data/odfs.png', size=(5000, 5000)) return None
asmfit = asm.fit(one_vox) sphere = get_sphere('symmetric724') odf = asmfit.odf(sphere) odf = np.reshape(odf, [10, 1, 1, 724]) odf_stack[i, :, :, :] = odf[0, :, :, :] print('odf.shape (%d, %d, %d, %d)' % odf.shape) zeta = zeta + 200 # Enables/disables interactive visualization interactive = True ren = window.Renderer() sfu = actor.odf_slicer(odf_stack[0:5, None, 0], sphere=sphere, colormap='plasma', scale=4, norm=False, radial_scale=True) sfu.RotateX(-1) sfu.RotateY(90) sfu.display(z=0) ren.add(sfu) out_path_name = 'odfs_b6k' + str(zeta) + '.png' window.record(ren, out_path=out_path_name, size=(200, 20)) #scale_val = scale_val + 0.5 if interactive: window.show(ren)
Load an odf reconstruction sphere """ sphere = get_sphere('symmetric724') """ Compute the fODFs. """ odf = f_fit.odf(sphere) print('fODF.shape (%d, %d, %d, %d)' % odf.shape) """ Display a part of the fODFs """ odf_actor = actor.odf_slicer(odf[16:36, :, 30:45], sphere=sphere, colormap='plasma', scale=0.6) odf_actor.display(y=0) odf_actor.RotateX(-90) ren = window.Renderer() ren.add(odf_actor) window.record(ren, out_path='fODFs.png', size=(600, 600), magnification=4) """ .. figure:: fODFs.png :align: center **Fiber Orientation Distribution Functions, in a small ROI of the brain**. .. [Anderson2005] Anderson A. W., "Measurement of Fiber Orientation Distributions Using High Angular Resolution Diffusion Imaging", Magnetic Resonance in Medicine, 2005.
""" For the purpose of the example, we will consider a small volume of data containing parts of the corpus callosum and of the centrum semiovale """ data_small = data[20:50, 55:85, 38:39] """ Fitting the model to this small volume of data, we calculate the ODF of this model on the sphere, and plot it. """ sf_fit = sf_model.fit(data_small) sf_odf = sf_fit.odf(sphere) fodf_spheres = actor.odf_slicer(sf_odf, sphere=sphere, scale=1.3, colormap='jet') ren = window.Renderer() ren.add(fodf_spheres) print('Saving illustration as sf_odfs.png') 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,
from dipy.viz import window, actor # Enables/disables interactive visualization interactive = False ren = window.Renderer() evals = response[0] evecs = np.array([[0, 1, 0], [0, 0, 1], [1, 0, 0]]).T from dipy.data import get_sphere sphere = get_sphere('symmetric724') from dipy.sims.voxel import single_tensor_odf response_odf = single_tensor_odf(sphere.vertices, evals, evecs) # transform our data from 1D to 4D response_odf = response_odf[None, None, None, :] response_actor = actor.odf_slicer(response_odf, sphere=sphere, colormap='plasma') ren.add(response_actor) print('Saving illustration as csd_response.png') window.record(ren, out_path='csd_response.png', size=(200, 200)) if interactive: window.show(ren) """ .. figure:: csd_response.png :align: center Estimated response function. """ ren.rm(response_actor)
cached spheres, which we can read in the following way. """ sphere = get_sphere('symmetric724') sphere = sphere.subdivide(2) odf = multi_tensor_odf(sphere.vertices, mevals, angles, fractions) from dipy.viz import window, actor # Enables/disables interactive visualization interactive = False ren = window.Renderer() odf_actor = actor.odf_slicer(odf[None, None, None, :], sphere=sphere, colormap='plasma') odf_actor.RotateX(90) ren.add(odf_actor) print('Saving illustration as multi_tensor_simulation') window.record(ren, out_path='multi_tensor_simulation.png', size=(300, 300)) if interactive: window.show(ren) """ .. figure:: multi_tensor_simulation.png :align: center Simulating a MultiTensor ODF.
data_masked, mask = median_otsu(data, 2, 1, vol_idx=np.arange(1, 11), dilate=1) print('Finished masking') print('Started DTI processing ...') tenmodel = TensorModel(gtab) tenfit = tenmodel.fit(data, mask=mask) print('Finished DTI processing ...') shape = mask.shape odf = tenfit.odf(sphere) ren = window.Renderer() #odf_slicer odf_slicer_actor = actor.odf_slicer(odfs=odf, mask=mask, sphere=sphere, scale=.5) ren.add(odf_slicer_actor) slider(odf_slicer_actor, None) data_small = data[:, :, 38:39] dti_wls = dti.TensorModel(gtab) fit_wls = dti_wls.fit(data_small) fa1 = fit_wls.fa evals1 = fit_wls.evals evecs1 = fit_wls.evecs cfa1 = dti.color_fa(fa1, evecs1) ren = fvtk.ren() fvtk.add(ren, fvtk.tensor(evals1, evecs1, cfa1, sphere)) #fvtk.record(ren, n_frames=1, out_path='tensor_ellipsoids.png',
""" sphere = get_sphere('symmetric724') """ Compute the fODFs. """ odf = f_fit.odf(sphere) print('fODF.shape (%d, %d, %d, %d)' % odf.shape) """ Display a part of the fODFs """ odf_actor = actor.odf_slicer(odf[16:36, :, 30:45], sphere=sphere, colormap='plasma', scale=0.6) odf_actor.display(y=0) odf_actor.RotateX(-90) ren = window.Renderer() ren.add(odf_actor) window.record(ren, out_path='fODFs.png', size=(600, 600), magnification=4) """ .. figure:: fODFs.png :align: center **Fiber Orientation Distribution Functions, in a small ROI of the brain**. References ----------
def show_odfs_and_fa(fa, pam, mask, affine, sphere, ftmp='odf.mmap', basis_type=None, norm_odfs=True, scale_odfs=0.5): renderer = window.Renderer() renderer.background((1, 1, 1)) slice_actor = actor.slicer(fa) #, value_range) odf_shape = fa.shape + (sphere.vertices.shape[0], ) odfs = np.memmap(ftmp, dtype=np.float32, mode='w+', shape=odf_shape) sph_harm_basis = sph_harm_lookup.get(basis_type) if sph_harm_basis is None: raise ValueError("Invalid basis name.") B, m, n = sph_harm_basis(8, sphere.theta, sphere.phi) odfs[:] = np.dot(pam.shm_coeff.astype('f4'), B.T.astype('f4')) odf_slicer = actor.odf_slicer(odfs, mask=mask, sphere=sphere, scale=scale_odfs, norm=norm_odfs, colormap='magma') renderer.add(odf_slicer) renderer.add(slice_actor) show_m = window.ShowManager(renderer, size=(2000, 1000)) show_m.initialize() """ We'll start by creating the panel and adding it to the ``ShowManager`` """ label_position = ui.TextBlock2D(text='Position:') label_value = ui.TextBlock2D(text='Value:') result_position = ui.TextBlock2D(text='') result_value = ui.TextBlock2D(text='') line_slider_z = ui.LineSlider2D(min_value=0, max_value=shape[2] - 1, initial_value=shape[2] / 2, text_template="{value:.0f}", length=140) def change_slice_z(i_ren, obj, slider): z = int(np.round(slider.value)) slice_actor.display(z=z) odf_slicer.display(z=z) show_m.render() line_slider_z.add_callback(line_slider_z.slider_disk, "LeftButtonReleaseEvent", change_slice_z) panel_picking = ui.Panel2D(center=(200, 120), size=(250, 225), color=(0, 0, 0), opacity=0.75, align="left") # panel_picking.add_element(label_position, 'relative', (0.1, 0.55)) # panel_picking.add_element(label_value, 'relative', (0.1, 0.25)) # panel_picking.add_element(result_position, 'relative', (0.45, 0.55)) # panel_picking.add_element(result_value, 'relative', (0.45, 0.25)) panel_picking.add_element(line_slider_z, 'relative', (0.5, 0.9)) show_m.ren.add(panel_picking) def left_click_callback(obj, ev): """Get the value of the clicked voxel and show it in the panel.""" event_pos = show_m.iren.GetEventPosition() obj.picker.Pick(event_pos[0], event_pos[1], 0, show_m.ren) i, j, k = obj.picker.GetPointIJK() print(i, j, k) result_position.message = '({}, {}, {})'.format(str(i), str(j), str(k)) result_value.message = '%.3f' % fa[i, j, k] slice_actor.SetInterpolate(True) slice_actor.AddObserver('LeftButtonPressEvent', left_click_callback, 1.0) show_m.start() odfs._mmap.close() del odfs os.remove(ftmp)
mcsd_pred = mcsd_fit.predict() mcsd_pred = mcsd_model.predict(mcsd_fit.all_shm_coeff) """ From the fit obtained in the previous step, we generate the ODFs which can be visualized as follows: """ mcsd_odf = mcsd_fit.odf(sphere) print("ODF") print(mcsd_odf.shape) print(mcsd_odf[40, 40, 0]) fodf_spheres = actor.odf_slicer(mcsd_odf, sphere=sphere, scale=1, norm=False, colormap='plasma') interactive = True scene = window.Scene() scene.add(fodf_spheres) scene.reset_camera_tight() print('Saving illustration as msdodf.png') #window.record(scene, out_path='msdodf.png', size=(600, 600)) if interactive: window.show(scene) """ .. figure:: msdodf.png
from dipy.sims.voxel import multi_tensor_odf mevals = np.array([[0.0015, 0.00015, 0.00015], [0.0015, 0.00015, 0.00015]]) angles = [(0, 0), (60, 0)] odf = multi_tensor_odf(sph.vertices, mevals, angles, [50, 50]) from dipy.viz import window, actor # Enables/disables interactive visualization interactive = False scene = window.Scene() scene.SetBackground(1, 1, 1) odf_actor = actor.odf_slicer(odf[None, None, None, :], sphere=sph) odf_actor.RotateX(90) scene.add(odf_actor) print('Saving illustration as symm_signal.png') window.record(scene, out_path='symm_signal.png', size=(300, 300)) if interactive: window.show(scene) """ .. figure:: symm_signal.png :align: center Illustration of the simulated signal sampled on a sphere of 64 points per hemisphere We can now express this signal as a series of SH coefficients using
from dipy.viz import window, actor from dipy.reconst.shm import sf_to_sh, sh_to_sf scene = window.Scene() # convolve kernel with delta spike spike = np.zeros((7, 7, 7, k.get_orientations().shape[0]), dtype=np.float64) spike[3, 3, 3, 0] = 1 spike_shm_conv = convolve(sf_to_sh(spike, k.get_sphere(), sh_order=8), k, sh_order=8, test_mode=True) spike_sf_conv = sh_to_sf(spike_shm_conv, default_sphere, sh_order=8) model_kernel = actor.odf_slicer(spike_sf_conv * 6, sphere=default_sphere, norm=False, scale=0.4) model_kernel.display(x=3) scene.add(model_kernel) scene.set_camera(position=(30, 0, 0), focal_point=(0, 0, 0), view_up=(0, 0, 1)) window.record(scene, out_path='kernel.png', size=(900, 900)) if interactive: window.show(scene) """ .. figure:: kernel.png :align: center Visualization of the contour enhancement kernel. """ """ Shift-twist convolution is applied on the noisy data
""" For the purpose of the example, we will consider a small volume of data containing parts of the corpus callosum and of the centrum semiovale """ data_small = data[20:50, 55:85, 38:39] """ Fitting the model to this small volume of data, we calculate the ODF of this model on the sphere, and plot it. """ sf_fit = sf_model.fit(data_small) sf_odf = sf_fit.odf(sphere) fodf_spheres = actor.odf_slicer(sf_odf, sphere=sphere, scale=0.8, colormap='plasma') ren = window.Renderer() ren.add(fodf_spheres) print('Saving illustration as sf_odfs.png') 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,
""" Finally, we can visualize the ground truth ODF, together with the DSI and DSI with deconvolution ODFs and observe that with the deconvolved method it is easier to resolve the correct fiber directions because the ODF is sharper. """ from dipy.viz import window, actor # Enables/disables interactive visualization interactive = False ren = window.Renderer() # concatenate data as 4D array odfs = np.vstack((odf_gt, dsi_odf, dsid_odf))[:, None, None] odf_actor = actor.odf_slicer(odfs, sphere=sphere, scale=0.5, colormap='plasma') odf_actor.display(y=0) odf_actor.RotateX(90) ren.add(odf_actor) window.record(ren, out_path='dsid.png', size=(300, 300)) if interactive: window.show(ren) """ .. figure:: dsid.png :align: center Ground truth ODF (left), DSI ODF (middle), DSI with Deconvolution ODF (right). .. [Canales10] Canales-Rodriguez et al., Deconvolution in Diffusion Spectrum Imaging, Neuroimage, vol 50, no 1, p. 136-149, 2010.
Finally, we can visualize the ground truth ODF, together with the DSI and DSI with deconvolution ODFs and observe that with the deconvolved method it is easier to resolve the correct fiber directions because the ODF is sharper. """ from dipy.viz import window, actor # Enables/disables interactive visualization interactive = False ren = window.Renderer() # concatenate data as 4D array odfs = np.vstack((odf_gt, dsi_odf, dsid_odf))[:, None, None] odf_actor = actor.odf_slicer(odfs, sphere=sphere, scale=0.5, colormap='plasma') odf_actor.display(y=0) odf_actor.RotateX(90) ren.add(odf_actor) window.record(ren, out_path='dsid.png', size=(300, 300)) if interactive: window.show(ren) """ .. figure:: dsid.png :align: center Ground truth ODF (left), DSI ODF (middle), DSI with Deconvolution ODF (right). .. [Canales10] Canales-Rodriguez et al., Deconvolution in Diffusion Spectrum Imaging,
from dipy.viz import window, actor from dipy.sims.voxel import single_tensor_odf # Enables/disables interactive visualization interactive = False scene = window.Scene() evals = response[0] evecs = np.array([[0, 1, 0], [0, 0, 1], [1, 0, 0]]).T response_odf = single_tensor_odf(default_sphere.vertices, evals, evecs) # transform our data from 1D to 4D response_odf = response_odf[None, None, None, :] response_actor = actor.odf_slicer(response_odf, sphere=default_sphere, colormap='plasma') scene.add(response_actor) print('Saving illustration as csd_response.png') window.record(scene, out_path='csd_response.png', size=(200, 200)) if interactive: window.show(scene) """ .. figure:: csd_response.png :align: center Estimated response function. """ scene.rm(response_actor)
from dipy.viz import window, actor # Enables/disables interactive visualization interactive = False r = window.Renderer() csaodfs = csamodel.fit(data_small).odf(sphere) """ It is common with CSA ODFs to produce negative values, we can remove those using ``np.clip`` """ csaodfs = np.clip(csaodfs, 0, np.max(csaodfs, -1)[..., None]) csa_odfs_actor = actor.odf_slicer(csaodfs, sphere=sphere, colormap='plasma', scale=0.4) csa_odfs_actor.display(z=0) r.add(csa_odfs_actor) print('Saving illustration as csa_odfs.png') window.record(r, n_frames=1, out_path='csa_odfs.png', size=(600, 600)) if interactive: window.show(r) """ .. figure:: csa_odfs.png :align: center Constant Solid Angle ODFs. .. include:: ../links_names.inc
The radial order ``s`` can be increased to sharpen the results, but it might also make the ODFs noisier. Always check the results visually. """ odf = mapfit_both_iso.odf(sphere, s=2) print('odf.shape (%d, %d, %d, %d)' % odf.shape) """ Display the ODFs. """ # Enables/disables interactive visualization interactive = False r = window.Renderer() sfu = actor.odf_slicer(odf, sphere=sphere, colormap='plasma', scale=0.5) sfu.display(y=0) r.add(sfu) window.record(r, out_path='odfs.png', size=(600, 600)) if interactive: window.show(r) """ .. figure:: odfs.png :align: center Orientation distribution functions (ODFs). References ----------
from dipy.viz import window, actor from dipy.data import get_sphere from dipy.reconst.shm import sf_to_sh, sh_to_sf ren = window.Renderer() # convolve kernel with delta spike spike = np.zeros((7, 7, 7, k.get_orientations().shape[0]), dtype=np.float64) spike[3, 3, 3, 0] = 1 spike_shm_conv = convolve(sf_to_sh(spike, k.get_sphere(), sh_order=8), k, sh_order=8, test_mode=True) sphere = get_sphere('symmetric724') spike_sf_conv = sh_to_sf(spike_shm_conv, sphere, sh_order=8) model_kernel = actor.odf_slicer(spike_sf_conv * 6, sphere=sphere, norm=False, scale=0.4) model_kernel.display(x=3) ren.add(model_kernel) ren.set_camera(position=(30, 0, 0), focal_point=(0, 0, 0), view_up=(0, 0, 1)) window.record(ren, out_path='kernel.png', size=(900, 900)) if interactive: window.show(ren) """ .. figure:: kernel.png :align: center Visualization of the contour enhancement kernel. """