def save_roisubset(streamlines, roislist, roisexcel, labelmask, stringstep, ratios, trkpath, subject, affine, header): #atlas_legends = BIGGUS_DISKUS + "/atlases/CHASSSYMM3AtlasLegends.xlsx" df = pd.read_excel(roisexcel, sheet_name='Sheet1') df['Structure'] = df['Structure'].str.lower() for rois in roislist: if len(rois)==1: roiname = "_" + rois[0] + "_" elif len(rois)>1: roiname="_" for roi in rois: roiname = roiname + roi[0:4] roiname = roiname + "_" labelslist=[]#fimbria for roi in rois: rslt_df = df.loc[df['Structure'] == roi.lower()] if roi.lower() == "wholebrain" or roi.lower() == "brain": labelslist=None else: labelslist=np.concatenate((labelslist,np.array(rslt_df.index2))) if isempty(labelslist) and roi.lower() != "wholebrain" and roi.lower() != "brain": txt = "Warning: Unrecognized roi, will take whole brain as ROI. The roi specified was: " + roi print(txt) #bvec_orient=[-2,1,3] if isempty(labelslist): roimask = np.where(labelmask == 0, False, True) else: if labelmask is None: raise ("Bad label data, could not define ROI for streams") roimask = np.zeros(np.shape(labelmask),dtype=int) for label in labelslist: roimask = roimask + (labelmask == label) if not isempty(labelslist): trkroipath = trkpath + '/' + subject + roiname + "_stepsize_" + stringstep + '.trk' if not os.path.exists(trkroipath): affinetemp=np.eye(4) trkstreamlines = target(streamlines, affinetemp, roimask, include=True, strict="longstring") trkstreamlines = Streamlines(trkstreamlines) myheader = create_tractogram_header(trkroipath, *header) roi_sl = lambda: (s for s in trkstreamlines) save_trk_heavy_duty(trkroipath, streamlines=roi_sl, affine=affine, header=myheader) else: trkdata = load_trk(trkroipath, 'same') trkdata.to_vox() if hasattr(trkdata, 'space_attribute'): header = trkdata.space_attribute elif hasattr(trkdata, 'space_attributes'): header = trkdata.space_attributes trkstreamlines = trkdata.streamlines for ratio in ratios: if ratio != 1: trkroiminipath = trkpath + '/' + subject + '_ratio_' + ratios + roiname + "_stepsize_" + stringstep + '.trk' if not os.path.exists(trkroiminipath): ministream = [] for idx, stream in enumerate(trkstreamlines): if (idx % ratio) == 0: ministream.append(stream) trkstreamlines = ministream myheader = create_tractogram_header(trkminipath, *header) ratioed_roi_sl_gen = lambda: (s for s in trkstreamlines) if allsave: save_trk_heavy_duty(trkroiminipath, streamlines=ratioed_roi_sl_gen, affine=affine, header=myheader) else: trkdata = load_trk(trkminipath, 'same') trkdata.to_vox() if hasattr(trkdata, 'space_attribute'): header = trkdata.space_attribute elif hasattr(trkdata, 'space_attributes'): header = trkdata.space_attributes trkstreamlines = trkdata.streamlines
def test_set_number_of_points(): # Test resampling of only one streamline nb_points = 12 new_streamline_cython = set_number_of_points(streamline, nb_points) new_streamline_python = set_number_of_points_python(streamline, nb_points) assert_equal(len(new_streamline_cython), nb_points) # Using a 5 digits precision because of streamline is in float32. assert_array_almost_equal(new_streamline_cython, new_streamline_python, 5) new_streamline_cython = set_number_of_points(streamline_64bit, nb_points) new_streamline_python = set_number_of_points_python( streamline_64bit, nb_points) assert_equal(len(new_streamline_cython), nb_points) assert_array_almost_equal(new_streamline_cython, new_streamline_python) res = [] simple_streamline = np.array([[0, 0, 0], [1, 1, 1], [2, 2, 2]], 'f4') for nb_points in range(2, 200): new_streamline_cython = set_number_of_points(simple_streamline, nb_points) res.append(nb_points - len(new_streamline_cython)) assert_equal(np.sum(res), 0) # Test resampling of multiple streamlines of different nb_points nb_points = 12 new_streamlines_cython = set_number_of_points(streamlines, nb_points) for i, s in enumerate(streamlines): new_streamline_python = set_number_of_points_python(s, nb_points) # Using a 5 digits precision because of streamline is in float32. assert_array_almost_equal(new_streamlines_cython[i], new_streamline_python, 5) # ArraySequence arrseq = Streamlines(streamlines) new_streamlines_as_seq_cython = set_number_of_points(arrseq, nb_points) assert_array_almost_equal(new_streamlines_as_seq_cython, new_streamlines_cython) new_streamlines_cython = set_number_of_points(streamlines_64bit, nb_points) for i, s in enumerate(streamlines_64bit): new_streamline_python = set_number_of_points_python(s, nb_points) assert_array_almost_equal(new_streamlines_cython[i], new_streamline_python) # ArraySequence arrseq = Streamlines(streamlines_64bit) new_streamlines_as_seq_cython = set_number_of_points(arrseq, nb_points) assert_array_almost_equal(new_streamlines_as_seq_cython, new_streamlines_cython) # Test streamlines with mixed dtype streamlines_mixed_dtype = [ streamline, streamline.astype(np.float64), streamline.astype(np.int32), streamline.astype(np.int64) ] nb_points_mixed_dtype = [ len(s) for s in set_number_of_points(streamlines_mixed_dtype, nb_points) ] assert_array_equal(nb_points_mixed_dtype, [nb_points] * len(streamlines_mixed_dtype)) # Test streamlines with different shape new_streamlines_cython = set_number_of_points(heterogeneous_streamlines, nb_points) for i, s in enumerate(heterogeneous_streamlines): new_streamline_python = set_number_of_points_python(s, nb_points) assert_array_almost_equal(new_streamlines_cython[i], new_streamline_python) # Test streamline with integer dtype new_streamline = set_number_of_points(streamline.astype(np.int32)) assert_equal(new_streamline.dtype, np.float32) new_streamline = set_number_of_points(streamline.astype(np.int64)) assert_equal(new_streamline.dtype, np.float64) # Test empty list assert_equal(set_number_of_points([]), []) # Test streamline having only one point assert_raises(ValueError, set_number_of_points, np.array([[1, 2, 3]])) # We do not support list of lists, it should be numpy ndarray. streamline_unsupported = [[1, 2, 3], [4, 5, 5], [2, 1, 3], [4, 2, 1]] assert_raises(AttributeError, set_number_of_points, streamline_unsupported) # Test setting number of points of a numpy with flag WRITABLE=False streamline_readonly = streamline.copy() streamline_readonly.setflags(write=False) assert_equal(len(set_number_of_points(streamline_readonly, nb_points=42)), 42) # Test setting computing length of a numpy with flag WRITABLE=False streamlines_readonly = [] for s in streamlines: streamlines_readonly.append(s.copy()) streamlines_readonly[-1].setflags(write=False) assert_equal(len(set_number_of_points(streamlines_readonly, nb_points=42)), len(streamlines_readonly)) streamlines_readonly = [] for s in streamlines_64bit: streamlines_readonly.append(s.copy()) streamlines_readonly[-1].setflags(write=False) assert_equal(len(set_number_of_points(streamlines_readonly, nb_points=42)), len(streamlines_readonly)) # Test if nb_points is less than 2 assert_raises(ValueError, set_number_of_points, [np.ones( (10, 3)), np.ones((10, 3))], nb_points=1)
def test_values_from_volume(): decimal = 4 data3d = np.arange(2000).reshape(20, 10, 10) # Test two cases of 4D data (handled differently) # One where the last dimension is length 3: data4d_3vec = np.arange(6000).reshape(20, 10, 10, 3) # The other where the last dimension is not 3: data4d_2vec = np.arange(4000).reshape(20, 10, 10, 2) for dt in [np.float32, np.float64]: for data in [data3d, data4d_3vec, data4d_2vec]: sl1 = [ np.array([[1, 0, 0], [1.5, 0, 0], [2, 0, 0], [2.5, 0, 0]]).astype(dt), np.array([[2, 0, 0], [3.1, 0, 0], [3.9, 0, 0], [4.1, 0, 0]]).astype(dt) ] ans1 = [[ data[1, 0, 0], data[1, 0, 0] + (data[2, 0, 0] - data[1, 0, 0]) / 2, data[2, 0, 0], data[2, 0, 0] + (data[3, 0, 0] - data[2, 0, 0]) / 2 ], [ data[2, 0, 0], data[3, 0, 0] + (data[4, 0, 0] - data[3, 0, 0]) * 0.1, data[3, 0, 0] + (data[4, 0, 0] - data[3, 0, 0]) * 0.9, data[4, 0, 0] + (data[5, 0, 0] - data[4, 0, 0]) * 0.1 ]] vv = values_from_volume(data, sl1) npt.assert_almost_equal(vv, ans1, decimal=decimal) vv = values_from_volume(data, np.array(sl1)) npt.assert_almost_equal(vv, ans1, decimal=decimal) vv = values_from_volume(data, Streamlines(sl1)) npt.assert_almost_equal(vv, ans1, decimal=decimal) affine = np.eye(4) affine[:, 3] = [-100, 10, 1, 1] x_sl1 = ut.move_streamlines(sl1, affine) x_sl2 = ut.move_streamlines(sl1, affine) vv = values_from_volume(data, x_sl1, affine=affine) npt.assert_almost_equal(vv, ans1, decimal=decimal) # The generator has already been consumed so needs to be # regenerated: x_sl1 = list(ut.move_streamlines(sl1, affine)) vv = values_from_volume(data, x_sl1, affine=affine) npt.assert_almost_equal(vv, ans1, decimal=decimal) # Test that the streamlines haven't mutated: l_sl2 = list(x_sl2) npt.assert_equal(x_sl1, l_sl2) vv = values_from_volume(data, np.array(x_sl1), affine=affine) npt.assert_almost_equal(vv, ans1, decimal=decimal) npt.assert_equal(np.array(x_sl1), np.array(l_sl2)) # Test for lists of streamlines with different numbers of nodes: sl2 = [sl1[0][:-1], sl1[1]] ans2 = [ans1[0][:-1], ans1[1]] vv = values_from_volume(data, sl2) for ii, v in enumerate(vv): npt.assert_almost_equal(v, ans2[ii], decimal=decimal) # We raise an error if the streamlines fed don't make sense. In this # case, a tuple instead of a list, generator or array nonsense_sl = (np.array([[1, 0, 0], [1.5, 0, 0], [2, 0, 0], [2.5, 0, 0]]), np.array([[2, 0, 0], [3.1, 0, 0], [3.9, 0, 0], [4.1, 0, 0]])) npt.assert_raises(RuntimeError, values_from_volume, data, nonsense_sl) # For some use-cases we might have singleton streamlines (with only one # node each): data3D = np.ones((2, 2, 2)) streamlines = np.ones((10, 1, 3)) npt.assert_equal(values_from_volume(data3D, streamlines).shape, (10, 1)) data4D = np.ones((2, 2, 2, 2)) streamlines = np.ones((10, 1, 3)) npt.assert_equal(values_from_volume(data4D, streamlines).shape, (10, 1, 2))
tensor_model = dti.TensorModel(gtab) tenfit = tensor_model.fit(data, mask=white_matter) FA = fractional_anisotropy(tenfit.evals) classifier = ThresholdTissueClassifier(FA, .2) from dipy.data import default_sphere from dipy.direction import DeterministicMaximumDirectionGetter from dipy.io.streamline import save_trk, load_trk detmax_dg = DeterministicMaximumDirectionGetter.from_shcoeff( csd_fit.shm_coeff, max_angle=40., sphere=default_sphere) from dipy.tracking.streamline import Streamlines streamlines = Streamlines( LocalTracking(detmax_dg, classifier, seeds, affine, step_size=.1)) long_streamlines = np.ones((len(streamlines)), bool) for i in range(0, len(streamlines)): if streamlines[i].shape[0] < 70: long_streamlines[i] = False streamlines = streamlines[long_streamlines] from dipy.viz import window, actor, colormap as cmap streamlines_actor = actor.line(streamlines, cmap.line_colors(streamlines)) # weighted streamlines: from dipy.tracking.streamline import transform_streamlines ''' FA weighting: fa_name = r'20190211_134016ep2dd155D60MB3APs004a001_FA.nii'
def test_length(): # Test length of only one streamline length_streamline_cython = length(streamline) length_streamline_python = length_python(streamline) assert_almost_equal(length_streamline_cython, length_streamline_python) length_streamline_cython = length(streamline_64bit) length_streamline_python = length_python(streamline_64bit) assert_almost_equal(length_streamline_cython, length_streamline_python) # Test computing length of multiple streamlines of different nb_points length_streamlines_cython = length(streamlines) for i, s in enumerate(streamlines): length_streamline_python = length_python(s) assert_array_almost_equal(length_streamlines_cython[i], length_streamline_python) length_streamlines_cython = length(streamlines_64bit) for i, s in enumerate(streamlines_64bit): length_streamline_python = length_python(s) assert_array_almost_equal(length_streamlines_cython[i], length_streamline_python) # ArraySequence # Test length of only one streamline length_streamline_cython = length(streamline_64bit) length_streamline_arrseq = length(Streamlines([streamline])) assert_almost_equal(length_streamline_arrseq, length_streamline_cython) length_streamline_cython = length(streamline_64bit) length_streamline_arrseq = length(Streamlines([streamline_64bit])) assert_almost_equal(length_streamline_arrseq, length_streamline_cython) # Test computing length of multiple streamlines of different nb_points length_streamlines_cython = length(streamlines) length_streamlines_arrseq = length(Streamlines(streamlines)) assert_array_almost_equal(length_streamlines_arrseq, length_streamlines_cython) length_streamlines_cython = length(streamlines_64bit) length_streamlines_arrseq = length(Streamlines(streamlines_64bit)) assert_array_almost_equal(length_streamlines_arrseq, length_streamlines_cython) # Test on a sliced ArraySequence length_streamlines_cython = length(streamlines_64bit[::2]) length_streamlines_arrseq = length(Streamlines(streamlines_64bit)[::2]) assert_array_almost_equal(length_streamlines_arrseq, length_streamlines_cython) length_streamlines_cython = length(streamlines[::-1]) length_streamlines_arrseq = length(Streamlines(streamlines)[::-1]) assert_array_almost_equal(length_streamlines_arrseq, length_streamlines_cython) # Test streamlines having mixed dtype streamlines_mixed_dtype = [ streamline, streamline.astype(np.float64), streamline.astype(np.int32), streamline.astype(np.int64) ] lengths_mixed_dtype = [length(s) for s in streamlines_mixed_dtype] assert_array_equal(length(streamlines_mixed_dtype), lengths_mixed_dtype) # Test streamlines with different shape length_streamlines_cython = length(heterogeneous_streamlines) for i, s in enumerate(heterogeneous_streamlines): length_streamline_python = length_python(s) assert_array_almost_equal(length_streamlines_cython[i], length_streamline_python) # Test streamline having integer dtype length_streamline = length(streamline.astype('int')) assert_equal(length_streamline.dtype, np.float64) # Test empty list assert_equal(length([]), 0.0) # Test streamline having only one point assert_equal(length(np.array([[1, 2, 3]])), 0.0) # We do not support list of lists, it should be numpy ndarray. streamline_unsupported = [[1, 2, 3], [4, 5, 5], [2, 1, 3], [4, 2, 1]] assert_raises(AttributeError, length, streamline_unsupported) # Test setting computing length of a numpy with flag WRITABLE=False streamlines_readonly = [] for s in streamlines: streamlines_readonly.append(s.copy()) streamlines_readonly[-1].setflags(write=False) assert_array_almost_equal(length(streamlines_readonly), [length_python(s) for s in streamlines_readonly]) streamlines_readonly = [] for s in streamlines_64bit: streamlines_readonly.append(s.copy()) streamlines_readonly[-1].setflags(write=False) assert_array_almost_equal(length(streamlines_readonly), [length_python(s) for s in streamlines_readonly])
def test_orient_by_rois(): streamlines = Streamlines([ np.array([[0, 0., 0], [1, 0., 0.], [2, 0., 0.]]), np.array([[2, 0., 0.], [1, 0., 0], [0, 0, 0.]]) ]) # Make two ROIs: mask1_vol = np.zeros((4, 4, 4), dtype=bool) mask2_vol = np.zeros_like(mask1_vol) mask1_vol[0, 0, 0] = True mask2_vol[1, 0, 0] = True mask1_coords = np.array(np.where(mask1_vol)).T mask2_coords = np.array(np.where(mask2_vol)).T # If there is an affine, we'll use it: affine = np.eye(4) affine[:, 3] = [-1, 100, -20, 1] # Transform the streamlines: x_streamlines = Streamlines([sl + affine[:3, 3] for sl in streamlines]) # After reorientation, this should be the answer: flipped_sl = Streamlines([streamlines[0], streamlines[1][::-1]]) new_streamlines = orient_by_rois(streamlines, mask1_vol, mask2_vol, in_place=False, affine=None, as_generator=False) npt.assert_array_equal(new_streamlines, flipped_sl) npt.assert_(new_streamlines is not streamlines) # Test with affine: x_flipped_sl = Streamlines([s + affine[:3, 3] for s in flipped_sl]) new_streamlines = orient_by_rois(x_streamlines, mask1_vol, mask2_vol, in_place=False, affine=affine, as_generator=False) npt.assert_array_equal(new_streamlines, x_flipped_sl) npt.assert_(new_streamlines is not x_streamlines) # Test providing coord ROIs instead of vol ROIs: new_streamlines = orient_by_rois(x_streamlines, mask1_coords, mask2_coords, in_place=False, affine=affine, as_generator=False) npt.assert_array_equal(new_streamlines, x_flipped_sl) # Test with as_generator set to True new_streamlines = orient_by_rois(streamlines, mask1_vol, mask2_vol, in_place=False, affine=None, as_generator=True) npt.assert_(isinstance(new_streamlines, types.GeneratorType)) ll = Streamlines(new_streamlines) npt.assert_array_equal(ll, flipped_sl) # Test with as_generator set to True and with the affine new_streamlines = orient_by_rois(x_streamlines, mask1_vol, mask2_vol, in_place=False, affine=affine, as_generator=True) npt.assert_(isinstance(new_streamlines, types.GeneratorType)) ll = Streamlines(new_streamlines) npt.assert_array_equal(ll, x_flipped_sl) # Test with generator input: new_streamlines = orient_by_rois(generate_sl(streamlines), mask1_vol, mask2_vol, in_place=False, affine=None, as_generator=True) npt.assert_(isinstance(new_streamlines, types.GeneratorType)) ll = Streamlines(new_streamlines) npt.assert_array_equal(ll, flipped_sl) # Generator output cannot take a True `in_place` kwarg: npt.assert_raises(ValueError, orient_by_rois, *[generate_sl(streamlines), mask1_vol, mask2_vol], **dict(in_place=True, affine=None, as_generator=True)) # But you can input a generator and get a non-generator as output: new_streamlines = orient_by_rois(generate_sl(streamlines), mask1_vol, mask2_vol, in_place=False, affine=None, as_generator=False) npt.assert_(not isinstance(new_streamlines, types.GeneratorType)) npt.assert_array_equal(new_streamlines, flipped_sl) # Modify in-place: new_streamlines = orient_by_rois(streamlines, mask1_vol, mask2_vol, in_place=True, affine=None, as_generator=False) npt.assert_array_equal(new_streamlines, flipped_sl) # The two objects are one and the same: npt.assert_(new_streamlines is streamlines)
fig.savefig('threshold_fa.png') """ .. figure:: threshold_fa.png :align: center **Thresholded fractional anisotropy map.** """ all_streamline_threshold_tc_generator = LocalTracking(dg, threshold_classifier, seeds, affine, step_size=.5, return_all=True) streamlines = Streamlines(all_streamline_threshold_tc_generator) save_trk("all_streamlines_threshold_classifier.trk", streamlines, affine, labels.shape) if have_fury: window.clear(ren) ren.add(actor.line(streamlines, cmap.line_colors(streamlines))) window.record(ren, out_path='all_streamlines_threshold_classifier.png', size=(600, 600)) if interactive: window.show(ren) """ .. figure:: all_streamlines_threshold_classifier.png
[68.90222168, 93.46326447, 122.01765442], [68.99872589, 93.30039978, 122.84759521], [69.04119873, 93.05428314, 123.66156769], [69.05086517, 92.74394989, 124.45450592], [69.02742004, 92.40427399, 125.23509979], [68.95466614, 92.09059143, 126.02339935], [68.84975433, 91.79674531, 126.81564331], [68.72673798, 91.53726196, 127.61715698], [68.60685731, 91.30300141, 128.42681885], [68.50636292, 91.12481689, 129.25317383], [68.39311218, 91.01572418, 130.08976746], [68.25946808, 90.94654083, 130.92756653]], dtype=np.float32) streamlines = Streamlines([ streamline[[0, 10]], streamline, streamline[::2], streamline[::3], streamline[::5], streamline[::6] ]) def io_tractogram(extension): with InTemporaryDirectory(): fname = 'test.{}'.format(extension) in_affine = np.eye(4) in_dimensions = np.array([50, 50, 50]) in_voxel_sizes = np.array([2, 1.5, 1.5]) nii_header = create_nifti_header(in_affine, in_dimensions, in_voxel_sizes) sft = StatefulTractogram(streamlines, nii_header, space=Space.RASMM) save_tractogram(sft, fname, bbox_valid_check=False)
def read_bundles_2_subjects(subj_id='subj_1', metrics=['fa'], bundles=['af.left', 'cst.right', 'cc_1']): r"""Read images and streamlines from 2 subjects of the SNAIL dataset. Parameters ---------- subj_id : string Either ``subj_1`` or ``subj_2``. metrics : list Either ['fa'] or ['t1'] or ['fa', 't1'] bundles : list E.g., ['af.left', 'cst.right', 'cc_1']. See all the available bundles in the ``exp_bundles_maps/bundles_2_subjects`` directory of your ``$HOME/.dipy`` folder. Returns ------- dix : dict Dictionary with data of the metrics and the bundles as keys. Notes ----- If you are using these datasets please cite the following publications. References ---------- .. [1] Renauld, E., M. Descoteaux, M. Bernier, E. Garyfallidis, K. Whittingstall, "Morphology of thalamus, LGN and optic radiation do not influence EEG alpha waves", Plos One (under submission), 2015. .. [2] Garyfallidis, E., O. Ocegueda, D. Wassermann, M. Descoteaux. Robust and efficient linear registration of fascicles in the space of streamlines , Neuroimage, 117:124-140, 2015. """ dname = pjoin(dipy_home, 'exp_bundles_and_maps', 'bundles_2_subjects') from dipy.io.streamline import load_tractogram from dipy.tracking.streamline import Streamlines res = {} if 't1' in metrics: data, affine = load_nifti(pjoin(dname, subj_id, 't1_warped.nii.gz')) res['t1'] = data if 'fa' in metrics: fa, affine = load_nifti(pjoin(dname, subj_id, 'fa_1x1x1.nii.gz')) res['fa'] = fa res['affine'] = affine for bun in bundles: streams = load_tractogram(pjoin(dname, subj_id, 'bundles', 'bundles_' + bun + '.trk'), 'same', bbox_valid_check=False).streamlines streamlines = Streamlines(streams) res[bun] = streamlines return res
data, default_sphere, relative_peak_threshold=.8, min_separation_angle=45, mask=white_matter) classifier = ThresholdStoppingCriterion(csa_peaks.gfa, .25) seed_mask = labels == 2 seeds = utils.seeds_from_mask(seed_mask, density=[1, 1, 1], affine=affine) # Initialization of LocalTracking. The computation happens in the next step. streamlines = LocalTracking(csa_peaks, classifier, seeds, affine, step_size=2) # Compute streamlines and store as a list. streamlines = Streamlines(streamlines) ############################################################################### # We will create a streamline actor from the streamlines. streamlines_actor = actor.line(streamlines, line_colors(streamlines)) ############################################################################### # Next, we create a surface actor from the corpus callosum seed ROI. We # provide the ROI data, the affine, the color in [R,G,B], and the opacity as # a decimal between zero and one. Here, we set the color as blue/green with # 50% opacity. surface_opacity = 0.5 surface_color = [0, 1, 1]
def test_cluster_confidence(): mysl = np.array([np.arange(10)] * 3, 'float').T # a short streamline (<20 mm) should raise an error unless override=True test_streamlines = Streamlines() test_streamlines.append(mysl) assert_raises(ValueError, cluster_confidence, test_streamlines) cci = cluster_confidence(test_streamlines, override=True) # two identical streamlines should raise an error test_streamlines = Streamlines() test_streamlines.append(mysl, cache_build=True) test_streamlines.append(mysl) test_streamlines.finalize_append() assert_raises(ValueError, cluster_confidence, test_streamlines) # 3 offset collinear streamlines test_streamlines = Streamlines() test_streamlines.append(mysl, cache_build=True) test_streamlines.append(mysl+1) test_streamlines.append(mysl+2) test_streamlines.finalize_append() cci = cluster_confidence(test_streamlines, override=True) assert_equal(cci[0], cci[2]) assert_true(cci[1] > cci[0]) # 3 parallel streamlines mysl = np.zeros([10, 3]) mysl[:, 0] = np.arange(10) mysl2 = mysl.copy() mysl2[:, 1] = 1 mysl3 = mysl.copy() mysl3[:, 1] = 2 mysl4 = mysl.copy() mysl4[:, 1] = 4 mysl5 = mysl.copy() mysl5[:, 1] = 5000 test_streamlines_p1 = Streamlines() test_streamlines_p1.append(mysl, cache_build=True) test_streamlines_p1.append(mysl2) test_streamlines_p1.append(mysl3) test_streamlines_p1.finalize_append() test_streamlines_p2 = Streamlines() test_streamlines_p2.append(mysl, cache_build=True) test_streamlines_p2.append(mysl3) test_streamlines_p2.append(mysl4) test_streamlines_p2.finalize_append() test_streamlines_p3 = Streamlines() test_streamlines_p3.append(mysl, cache_build=True) test_streamlines_p3.append(mysl2) test_streamlines_p3.append(mysl3) test_streamlines_p3.append(mysl5) test_streamlines_p3.finalize_append() cci_p1 = cluster_confidence(test_streamlines_p1, override=True) cci_p2 = cluster_confidence(test_streamlines_p2, override=True) # test relative distance assert_array_equal(cci_p1, cci_p2*2) # test simple cci calculation expected_p1 = np.array([1./1+1./2, 1./1+1./1, 1./1+1./2]) expected_p2 = np.array([1./2+1./4, 1./2+1./2, 1./2+1./4]) assert_array_equal(expected_p1, cci_p1) assert_array_equal(expected_p2, cci_p2) # test power variable calculation (dropoff with distance) cci_p1_pow2 = cluster_confidence(test_streamlines_p1, power=2, override=True) expected_p1_pow2 = np.array([np.power(1./1, 2)+np.power(1./2, 2), np.power(1./1, 2)+np.power(1./1, 2), np.power(1./1, 2)+np.power(1./2, 2)]) assert_array_equal(cci_p1_pow2, expected_p1_pow2) # test max distance (ignore distant sls) cci_dist = cluster_confidence(test_streamlines_p3, max_mdf=5, override=True) expected_cci_dist = np.concatenate([cci_p1, np.zeros(1)]) assert_array_equal(cci_dist, expected_cci_dist)
from dipy.direction import ProbabilisticDirectionGetter from dipy.data import small_sphere from dipy.io.stateful_tractogram import Space, StatefulTractogram from dipy.io.streamline import save_trk fod = csd_fit.odf(small_sphere) pmf = fod.clip(min=0) prob_dg = ProbabilisticDirectionGetter.from_pmf(pmf, max_angle=30., sphere=small_sphere) streamline_generator = LocalTracking(prob_dg, stopping_criterion, seeds, affine, step_size=.5) streamlines = Streamlines(streamline_generator) sft = StatefulTractogram(streamlines, hardi_img, Space.RASMM) save_trk(sft, "tractogram_probabilistic_dg_pmf.trk") if has_fury: scene = window.Scene() scene.add(actor.line(streamlines, colormap.line_colors(streamlines))) window.record(scene, out_path='tractogram_probabilistic_dg_pmf.png', size=(800, 800)) if interactive: window.show(scene) """ .. figure:: tractogram_probabilistic_dg_pmf.png :align: center
step_size=step_size, average_voxel_size=voxel_size) # Particle Filtering Tractography pft_streamline_generator = ParticleFilteringTracking(dg, cmc_classifier, seeds, affine, max_cross=1, step_size=step_size, maxlen=1000, pft_back_tracking_dist=2, pft_front_tracking_dist=1, particle_count=15, return_all=False) streamlines = Streamlines(pft_streamline_generator) save_trk("tractogram_pft.trk", streamlines, affine, shape) if has_fury: r = window.Renderer() r.add(actor.line(streamlines, colormap.line_colors(streamlines))) window.record(r, out_path='tractogram_pft.png', size=(800, 800)) if interactive: window.show(r) """ .. figure:: tractogram_pft.png :align: center **Corpus Callosum using particle filtering tractography** """
def plot_bundles_with_metric(bundle_path, endings_path, brain_mask_path, bundle, metrics, output_path, tracking_format="trk_legacy", show_color_bar=True): import seaborn as sns # import in function to avoid error if not installed (this is only needed in this function) from dipy.viz import actor, window from tractseg.libs import vtk_utils def _add_extra_point_to_last_streamline(sl): # Coloring broken as soon as all streamlines have same number of points -> why??? # Add one number to last streamline to make it have a different number sl[-1] = np.append(sl[-1], [sl[-1][-1]], axis=0) return sl # Settings NR_SEGMENTS = 100 ANTI_INTERPOL_MULT = 1 # increase number of points to avoid interpolation to blur the colors algorithm = "distance_map" # equal_dist | distance_map | cutting_plane # colors = np.array(sns.color_palette("coolwarm", NR_SEGMENTS)) # colormap blue to red (does not fit to colorbar) colors = np.array(sns.light_palette( "red", NR_SEGMENTS)) # colormap only red, which fits to color_bar img_size = (1000, 1000) # Tractometry skips first and last element. Therefore we only have 98 instead of 100 elements. # Here we duplicate the first and last element to get back to 100 elements metrics = list(metrics) metrics = np.array([metrics[0]] + metrics + [metrics[-1]]) metrics_max = metrics.max() metrics_min = metrics.min() if metrics_max == metrics_min: metrics = np.zeros(len(metrics)) else: metrics = img_utils.scale_to_range( metrics, range=(0, 99)) # range needs to be same as segments in colormap orientation = dataset_specific_utils.get_optimal_orientation_for_bundle( bundle) # Load mask beginnings_img = nib.load(endings_path) beginnings = beginnings_img.get_fdata().astype(np.uint8) for i in range(1): beginnings = binary_dilation(beginnings) # Load trackings if tracking_format == "trk_legacy": streams, hdr = trackvis.read(bundle_path) streamlines = [s[0] for s in streams] else: sl_file = nib.streamlines.load(bundle_path) streamlines = sl_file.streamlines # Reduce streamline count streamlines = streamlines[::2] # Reorder to make all streamlines have same start region streamlines = fiber_utils.add_to_each_streamline(streamlines, 0.5) streamlines_new = [] for idx, sl in enumerate(streamlines): startpoint = sl[0] # Flip streamline if not in right order if beginnings[int(startpoint[0]), int(startpoint[1]), int(startpoint[2])] == 0: sl = sl[::-1, :] streamlines_new.append(sl) streamlines = fiber_utils.add_to_each_streamline(streamlines_new, -0.5) if algorithm == "distance_map" or algorithm == "equal_dist": streamlines = fiber_utils.resample_fibers( streamlines, NR_SEGMENTS * ANTI_INTERPOL_MULT) elif algorithm == "cutting_plane": streamlines = fiber_utils.resample_to_same_distance( streamlines, max_nr_points=NR_SEGMENTS, ANTI_INTERPOL_MULT=ANTI_INTERPOL_MULT) # Cut start and end by percentage # streamlines = FiberUtils.resample_fibers(streamlines, NR_SEGMENTS * ANTI_INTERPOL_MULT) # remove = int((NR_SEGMENTS * ANTI_INTERPOL_MULT) * 0.15) # remove X% in beginning and end # streamlines = np.array(streamlines)[:, remove:-remove, :] # streamlines = list(streamlines) if algorithm == "equal_dist": segment_idxs = [] for i in range(len(streamlines)): segment_idxs.append(list(range(NR_SEGMENTS * ANTI_INTERPOL_MULT))) segment_idxs = np.array(segment_idxs) elif algorithm == "distance_map": metric = AveragePointwiseEuclideanMetric() qb = QuickBundles(threshold=100., metric=metric) clusters = qb.cluster(streamlines) centroids = Streamlines(clusters.centroids) _, segment_idxs = cKDTree(centroids.data, 1, copy_data=True).query(streamlines, k=1) elif algorithm == "cutting_plane": streamlines_resamp = fiber_utils.resample_fibers( streamlines, NR_SEGMENTS * ANTI_INTERPOL_MULT) metric = AveragePointwiseEuclideanMetric() qb = QuickBundles(threshold=100., metric=metric) clusters = qb.cluster(streamlines_resamp) centroid = Streamlines(clusters.centroids)[0] # index of the middle cluster middle_idx = int(NR_SEGMENTS / 2) * ANTI_INTERPOL_MULT middle_point = centroid[middle_idx] segment_idxs = fiber_utils.get_idxs_of_closest_points( streamlines, middle_point) # Align along the middle and assign indices segment_idxs_eqlen = [] for idx, sl in enumerate(streamlines): sl_middle_pos = segment_idxs[idx] before_elems = sl_middle_pos after_elems = len(sl) - sl_middle_pos base_idx = 1000 # use higher index to avoid negative numbers for area below middle r = range((base_idx - before_elems), (base_idx + after_elems)) segment_idxs_eqlen.append(r) segment_idxs = segment_idxs_eqlen # Add extra point otherwise coloring BUG streamlines = _add_extra_point_to_last_streamline(streamlines) renderer = window.Renderer() colors_all = [] # final shape will be [nr_streamlines, nr_points, 3] for jdx, sl in enumerate(streamlines): colors_sl = [] for idx, p in enumerate(sl): if idx >= len(segment_idxs[jdx]): seg_idx = segment_idxs[jdx][idx - 1] else: seg_idx = segment_idxs[jdx][idx] m = metrics[int(seg_idx / ANTI_INTERPOL_MULT)] color = colors[int(m)] colors_sl.append(color) colors_all.append( colors_sl ) # this can not be converted to numpy array because last element has one more elem sl_actor = actor.streamtube(streamlines, colors=colors_all, linewidth=0.2, opacity=1) renderer.add(sl_actor) # plot brain mask mask = nib.load(brain_mask_path).get_fdata().astype(np.uint8) cont_actor = vtk_utils.contour_from_roi_smooth( mask, affine=beginnings_img.affine, color=[.9, .9, .9], opacity=.2, smoothing=50) renderer.add(cont_actor) if show_color_bar: lut_cmap = actor.colormap_lookup_table(scale_range=(metrics_min, metrics_max), hue_range=(0.0, 0.0), saturation_range=(0.0, 1.0)) renderer.add(actor.scalar_bar(lut_cmap)) if orientation == "sagittal": renderer.set_camera(position=(-412.95, -34.38, 80.15), focal_point=(102.46, -16.96, -11.71), view_up=(0.1806, 0.0, 0.9835)) elif orientation == "coronal": renderer.set_camera(position=(-48.63, 360.31, 98.37), focal_point=(-20.16, 92.89, 36.02), view_up=(-0.0047, -0.2275, 0.9737)) elif orientation == "axial": pass else: raise ValueError("Invalid orientation provided") # Use this to interatively get new camera angle # window.show(renderer, size=img_size, reset_camera=False) # print(renderer.get_camera()) window.record(renderer, out_path=output_path, size=img_size)
s_list = [] '''new func:''' for i in range(id.__len__()): # for j in range(i + 1): # edge_s_list = [] # print(i,j) if (i + 1, j + 1) in streamline_dict and mat_medians[i, j] > 0: edge_s_list += streamline_dict[(i + 1, j + 1)] if (j + 1, i + 1) in streamline_dict and mat_medians[i, j] > 0: edge_s_list += streamline_dict[(j + 1, i + 1)] edge_vec_vols = [mat_medians[i, j]] * edge_s_list.__len__() s_list = s_list + edge_s_list vec_vols = vec_vols + edge_vec_vols s = Streamlines(s_list) cci = cluster_confidence(s) keep_streamlines = Streamlines() for i, sl in enumerate(s): if cci[i] >= 1: keep_streamlines.append(sl) # Visualize the streamlines we kept ren = window.Renderer() keep_streamlines_actor = actor.line(keep_streamlines, linewidth=0.1) ren.add(keep_streamlines_actor)