annotate linear_fascile_evaluation.py @ 3:0ddfcb3b5ce6 draft

Uploaded
author greg
date Wed, 29 Nov 2017 09:51:57 -0500
parents 84a2e30b5404
children eb03934e044f
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
cbfa8c336751 Uploaded
greg
parents:
diff changeset
1 #!/usr/bin/env python
cbfa8c336751 Uploaded
greg
parents:
diff changeset
2 import argparse
3
0ddfcb3b5ce6 Uploaded
greg
parents: 1
diff changeset
3 import shutil
0ddfcb3b5ce6 Uploaded
greg
parents: 1
diff changeset
4
0
cbfa8c336751 Uploaded
greg
parents:
diff changeset
5 import dipy.core.optimize as opt
cbfa8c336751 Uploaded
greg
parents:
diff changeset
6 import dipy.tracking.life as life
3
0ddfcb3b5ce6 Uploaded
greg
parents: 1
diff changeset
7 from dipy.data import fetch_stanford_t1, read_stanford_labels, read_stanford_t1
0ddfcb3b5ce6 Uploaded
greg
parents: 1
diff changeset
8 from dipy.viz import fvtk
0
cbfa8c336751 Uploaded
greg
parents:
diff changeset
9 from dipy.viz.colormap import line_colors
3
0ddfcb3b5ce6 Uploaded
greg
parents: 1
diff changeset
10
0ddfcb3b5ce6 Uploaded
greg
parents: 1
diff changeset
11 import matplotlib
0ddfcb3b5ce6 Uploaded
greg
parents: 1
diff changeset
12 import matplotlib.pyplot as plt
0ddfcb3b5ce6 Uploaded
greg
parents: 1
diff changeset
13
0
cbfa8c336751 Uploaded
greg
parents:
diff changeset
14 from mpl_toolkits.axes_grid1 import AxesGrid
3
0ddfcb3b5ce6 Uploaded
greg
parents: 1
diff changeset
15
0ddfcb3b5ce6 Uploaded
greg
parents: 1
diff changeset
16 import nibabel as nib
0ddfcb3b5ce6 Uploaded
greg
parents: 1
diff changeset
17
0ddfcb3b5ce6 Uploaded
greg
parents: 1
diff changeset
18 import numpy as np
0
cbfa8c336751 Uploaded
greg
parents:
diff changeset
19
cbfa8c336751 Uploaded
greg
parents:
diff changeset
20 parser = argparse.ArgumentParser()
3
0ddfcb3b5ce6 Uploaded
greg
parents: 1
diff changeset
21 parser.add_argument('--input', dest='input', help='Track Visualization Header dataset')
0
cbfa8c336751 Uploaded
greg
parents:
diff changeset
22 parser.add_argument('--output_life_candidates', dest='output_life_candidates', help='Output life candidates')
cbfa8c336751 Uploaded
greg
parents:
diff changeset
23 parser.add_argument('--output_life_optimized', dest='output_life_optimized', help='Output life optimized streamlines')
cbfa8c336751 Uploaded
greg
parents:
diff changeset
24 parser.add_argument('--output_beta_histogram', dest='output_beta_histogram', help='Output beta histogram')
cbfa8c336751 Uploaded
greg
parents:
diff changeset
25 parser.add_argument('--output_error_histograms', dest='output_error_histograms', help='Output error histograms')
cbfa8c336751 Uploaded
greg
parents:
diff changeset
26 parser.add_argument('--output_spatial_errors', dest='output_spatial_errors', help='Output spatial errors')
cbfa8c336751 Uploaded
greg
parents:
diff changeset
27
cbfa8c336751 Uploaded
greg
parents:
diff changeset
28 args = parser.parse_args()
cbfa8c336751 Uploaded
greg
parents:
diff changeset
29
1
84a2e30b5404 Uploaded
greg
parents: 0
diff changeset
30 # We'll need to know where the corpus callosum is from these variables.
84a2e30b5404 Uploaded
greg
parents: 0
diff changeset
31 hardi_img, gtab, labels_img = read_stanford_labels()
84a2e30b5404 Uploaded
greg
parents: 0
diff changeset
32 labels = labels_img.get_data()
84a2e30b5404 Uploaded
greg
parents: 0
diff changeset
33 cc_slice = labels == 2
84a2e30b5404 Uploaded
greg
parents: 0
diff changeset
34 fetch_stanford_t1()
84a2e30b5404 Uploaded
greg
parents: 0
diff changeset
35 t1 = read_stanford_t1()
84a2e30b5404 Uploaded
greg
parents: 0
diff changeset
36 t1_data = t1.get_data()
84a2e30b5404 Uploaded
greg
parents: 0
diff changeset
37 data = hardi_img.get_data()
0
cbfa8c336751 Uploaded
greg
parents:
diff changeset
38
cbfa8c336751 Uploaded
greg
parents:
diff changeset
39 # Read the candidates from file in voxel space:
3
0ddfcb3b5ce6 Uploaded
greg
parents: 1
diff changeset
40 candidate_sl = [s[0] for s in nib.trackvis.read(args.input, points_space='voxel')[0]]
0
cbfa8c336751 Uploaded
greg
parents:
diff changeset
41 # Visualize the initial candidate group of streamlines
cbfa8c336751 Uploaded
greg
parents:
diff changeset
42 # in 3D, relative to the anatomical structure of this brain.
cbfa8c336751 Uploaded
greg
parents:
diff changeset
43 candidate_streamlines_actor = fvtk.streamtube(candidate_sl, line_colors(candidate_sl))
cbfa8c336751 Uploaded
greg
parents:
diff changeset
44 cc_ROI_actor = fvtk.contour(cc_slice, levels=[1], colors=[(1., 1., 0.)], opacities=[1.])
cbfa8c336751 Uploaded
greg
parents:
diff changeset
45 vol_actor = fvtk.slicer(t1_data)
cbfa8c336751 Uploaded
greg
parents:
diff changeset
46 vol_actor.display(40, None, None)
cbfa8c336751 Uploaded
greg
parents:
diff changeset
47 vol_actor2 = vol_actor.copy()
cbfa8c336751 Uploaded
greg
parents:
diff changeset
48 vol_actor2.display(None, None, 35)
cbfa8c336751 Uploaded
greg
parents:
diff changeset
49 # Add display objects to canvas.
cbfa8c336751 Uploaded
greg
parents:
diff changeset
50 ren = fvtk.ren()
cbfa8c336751 Uploaded
greg
parents:
diff changeset
51 fvtk.add(ren, candidate_streamlines_actor)
cbfa8c336751 Uploaded
greg
parents:
diff changeset
52 fvtk.add(ren, cc_ROI_actor)
cbfa8c336751 Uploaded
greg
parents:
diff changeset
53 fvtk.add(ren, vol_actor)
cbfa8c336751 Uploaded
greg
parents:
diff changeset
54 fvtk.add(ren, vol_actor2)
3
0ddfcb3b5ce6 Uploaded
greg
parents: 1
diff changeset
55 fvtk.record(ren, n_frames=1, out_path="life_candidates.png", size=(800, 800))
0ddfcb3b5ce6 Uploaded
greg
parents: 1
diff changeset
56 shutil.move("life_candidates.png", args.output_life_candidates)
0
cbfa8c336751 Uploaded
greg
parents:
diff changeset
57 # Initialize a LiFE model.
cbfa8c336751 Uploaded
greg
parents:
diff changeset
58 fiber_model = life.FiberModel(gtab)
cbfa8c336751 Uploaded
greg
parents:
diff changeset
59 # Fit the model, producing a FiberFit class instance,
cbfa8c336751 Uploaded
greg
parents:
diff changeset
60 # that stores the data, as well as the results of the
cbfa8c336751 Uploaded
greg
parents:
diff changeset
61 # fitting procedure.
cbfa8c336751 Uploaded
greg
parents:
diff changeset
62 fiber_fit = fiber_model.fit(data, candidate_sl, affine=np.eye(4))
cbfa8c336751 Uploaded
greg
parents:
diff changeset
63 fig, ax = plt.subplots(1)
cbfa8c336751 Uploaded
greg
parents:
diff changeset
64 ax.hist(fiber_fit.beta, bins=100, histtype='step')
cbfa8c336751 Uploaded
greg
parents:
diff changeset
65 ax.set_xlabel('Fiber weights')
cbfa8c336751 Uploaded
greg
parents:
diff changeset
66 ax.set_ylabel('# fibers')
3
0ddfcb3b5ce6 Uploaded
greg
parents: 1
diff changeset
67 fig.savefig("beta_histogram.png")
0ddfcb3b5ce6 Uploaded
greg
parents: 1
diff changeset
68 shutil.move("beta_histogram.png", args.output_beta_histogram)
0
cbfa8c336751 Uploaded
greg
parents:
diff changeset
69 # Filter out these redundant streamlines and
cbfa8c336751 Uploaded
greg
parents:
diff changeset
70 # generate an optimized group of streamlines.
3
0ddfcb3b5ce6 Uploaded
greg
parents: 1
diff changeset
71 optimized_sl = list(np.array(candidate_sl)[np.where(fiber_fit.beta > 0)[0]])
0
cbfa8c336751 Uploaded
greg
parents:
diff changeset
72 ren = fvtk.ren()
cbfa8c336751 Uploaded
greg
parents:
diff changeset
73 fvtk.add(ren, fvtk.streamtube(optimized_sl, line_colors(optimized_sl)))
cbfa8c336751 Uploaded
greg
parents:
diff changeset
74 fvtk.add(ren, cc_ROI_actor)
cbfa8c336751 Uploaded
greg
parents:
diff changeset
75 fvtk.add(ren, vol_actor)
3
0ddfcb3b5ce6 Uploaded
greg
parents: 1
diff changeset
76 fvtk.record(ren, n_frames=1, out_path="optimized.png", size=(800, 800))
0ddfcb3b5ce6 Uploaded
greg
parents: 1
diff changeset
77 shutil.move("optimized.png", args.output_life_optimized)
0
cbfa8c336751 Uploaded
greg
parents:
diff changeset
78 model_predict = fiber_fit.predict()
cbfa8c336751 Uploaded
greg
parents:
diff changeset
79 # Focus on the error in prediction of the diffusion-weighted
cbfa8c336751 Uploaded
greg
parents:
diff changeset
80 # data, and calculate the root of the mean squared error.
cbfa8c336751 Uploaded
greg
parents:
diff changeset
81 model_error = model_predict - fiber_fit.data
cbfa8c336751 Uploaded
greg
parents:
diff changeset
82 model_rmse = np.sqrt(np.mean(model_error[:, 10:] ** 2, -1))
cbfa8c336751 Uploaded
greg
parents:
diff changeset
83 # Calculate another error term by assuming that the weight for each streamline
cbfa8c336751 Uploaded
greg
parents:
diff changeset
84 # is equal to zero. This produces the naive prediction of the mean of the
cbfa8c336751 Uploaded
greg
parents:
diff changeset
85 # signal in each voxel.
cbfa8c336751 Uploaded
greg
parents:
diff changeset
86 beta_baseline = np.zeros(fiber_fit.beta.shape[0])
cbfa8c336751 Uploaded
greg
parents:
diff changeset
87 pred_weighted = np.reshape(opt.spdot(fiber_fit.life_matrix, beta_baseline), (fiber_fit.vox_coords.shape[0], np.sum(~gtab.b0s_mask)))
cbfa8c336751 Uploaded
greg
parents:
diff changeset
88 mean_pred = np.empty((fiber_fit.vox_coords.shape[0], gtab.bvals.shape[0]))
cbfa8c336751 Uploaded
greg
parents:
diff changeset
89 S0 = fiber_fit.b0_signal
cbfa8c336751 Uploaded
greg
parents:
diff changeset
90 # Since the fitting is done in the demeaned S/S0 domain,
cbfa8c336751 Uploaded
greg
parents:
diff changeset
91 # add back the mean and then multiply by S0 in every voxel:
cbfa8c336751 Uploaded
greg
parents:
diff changeset
92 mean_pred[..., gtab.b0s_mask] = S0[:, None]
cbfa8c336751 Uploaded
greg
parents:
diff changeset
93 mean_pred[..., ~gtab.b0s_mask] = (pred_weighted + fiber_fit.mean_signal[:, None]) * S0[:, None]
cbfa8c336751 Uploaded
greg
parents:
diff changeset
94 mean_error = mean_pred - fiber_fit.data
cbfa8c336751 Uploaded
greg
parents:
diff changeset
95 mean_rmse = np.sqrt(np.mean(mean_error ** 2, -1))
cbfa8c336751 Uploaded
greg
parents:
diff changeset
96 # Compare the overall distribution of errors
cbfa8c336751 Uploaded
greg
parents:
diff changeset
97 # between these two alternative models of the ROI.
cbfa8c336751 Uploaded
greg
parents:
diff changeset
98 fig, ax = plt.subplots(1)
cbfa8c336751 Uploaded
greg
parents:
diff changeset
99 ax.hist(mean_rmse - model_rmse, bins=100, histtype='step')
3
0ddfcb3b5ce6 Uploaded
greg
parents: 1
diff changeset
100 ax.text(0.2, 0.9, 'Median RMSE, mean model: %.2f' % np.median(mean_rmse), horizontalalignment='left', verticalalignment='center', transform=ax.transAxes)
0ddfcb3b5ce6 Uploaded
greg
parents: 1
diff changeset
101 ax.text(0.2, 0.8, 'Median RMSE, LiFE: %.2f' % np.median(model_rmse), horizontalalignment='left', verticalalignment='center', transform=ax.transAxes)
0
cbfa8c336751 Uploaded
greg
parents:
diff changeset
102 ax.set_xlabel('RMS Error')
cbfa8c336751 Uploaded
greg
parents:
diff changeset
103 ax.set_ylabel('# voxels')
3
0ddfcb3b5ce6 Uploaded
greg
parents: 1
diff changeset
104 fig.savefig("error_histograms.png")
0ddfcb3b5ce6 Uploaded
greg
parents: 1
diff changeset
105 shutil.move("error_histograms.png", args.output_error_histograms)
0
cbfa8c336751 Uploaded
greg
parents:
diff changeset
106 # Show the spatial distribution of the two error terms,
cbfa8c336751 Uploaded
greg
parents:
diff changeset
107 # and of the improvement with the model fit:
cbfa8c336751 Uploaded
greg
parents:
diff changeset
108 vol_model = np.ones(data.shape[:3]) * np.nan
cbfa8c336751 Uploaded
greg
parents:
diff changeset
109 vol_model[fiber_fit.vox_coords[:, 0], fiber_fit.vox_coords[:, 1], fiber_fit.vox_coords[:, 2]] = model_rmse
cbfa8c336751 Uploaded
greg
parents:
diff changeset
110 vol_mean = np.ones(data.shape[:3]) * np.nan
cbfa8c336751 Uploaded
greg
parents:
diff changeset
111 vol_mean[fiber_fit.vox_coords[:, 0], fiber_fit.vox_coords[:, 1], fiber_fit.vox_coords[:, 2]] = mean_rmse
cbfa8c336751 Uploaded
greg
parents:
diff changeset
112 vol_improve = np.ones(data.shape[:3]) * np.nan
cbfa8c336751 Uploaded
greg
parents:
diff changeset
113 vol_improve[fiber_fit.vox_coords[:, 0], fiber_fit.vox_coords[:, 1], fiber_fit.vox_coords[:, 2]] = mean_rmse - model_rmse
cbfa8c336751 Uploaded
greg
parents:
diff changeset
114 sl_idx = 49
cbfa8c336751 Uploaded
greg
parents:
diff changeset
115 fig = plt.figure()
cbfa8c336751 Uploaded
greg
parents:
diff changeset
116 fig.subplots_adjust(left=0.05, right=0.95)
3
0ddfcb3b5ce6 Uploaded
greg
parents: 1
diff changeset
117 ax = AxesGrid(fig, 111, nrows_ncols=(1, 3), label_mode="1", share_all=True, cbar_location="top", cbar_mode="each", cbar_size="10%", cbar_pad="5%")
0
cbfa8c336751 Uploaded
greg
parents:
diff changeset
118 ax[0].matshow(np.rot90(t1_data[sl_idx, :, :]), cmap=matplotlib.cm.bone)
cbfa8c336751 Uploaded
greg
parents:
diff changeset
119 im = ax[0].matshow(np.rot90(vol_model[sl_idx, :, :]), cmap=matplotlib.cm.hot)
cbfa8c336751 Uploaded
greg
parents:
diff changeset
120 ax.cbar_axes[0].colorbar(im)
cbfa8c336751 Uploaded
greg
parents:
diff changeset
121 ax[1].matshow(np.rot90(t1_data[sl_idx, :, :]), cmap=matplotlib.cm.bone)
cbfa8c336751 Uploaded
greg
parents:
diff changeset
122 im = ax[1].matshow(np.rot90(vol_mean[sl_idx, :, :]), cmap=matplotlib.cm.hot)
cbfa8c336751 Uploaded
greg
parents:
diff changeset
123 ax.cbar_axes[1].colorbar(im)
cbfa8c336751 Uploaded
greg
parents:
diff changeset
124 ax[2].matshow(np.rot90(t1_data[sl_idx, :, :]), cmap=matplotlib.cm.bone)
cbfa8c336751 Uploaded
greg
parents:
diff changeset
125 im = ax[2].matshow(np.rot90(vol_improve[sl_idx, :, :]), cmap=matplotlib.cm.RdBu)
cbfa8c336751 Uploaded
greg
parents:
diff changeset
126 ax.cbar_axes[2].colorbar(im)
cbfa8c336751 Uploaded
greg
parents:
diff changeset
127 for lax in ax:
cbfa8c336751 Uploaded
greg
parents:
diff changeset
128 lax.set_xticks([])
cbfa8c336751 Uploaded
greg
parents:
diff changeset
129 lax.set_yticks([])
3
0ddfcb3b5ce6 Uploaded
greg
parents: 1
diff changeset
130 fig.savefig("spatial_errors.png")
0ddfcb3b5ce6 Uploaded
greg
parents: 1
diff changeset
131 shutil.move("spatial_errors.png", args.output_spatial_errors)