def test_threshold_tissue_classifier(): """This tests that the thresholdy tissue classifier returns expected tissue types. """ tissue_map = np.random.random((4, 4, 4)) ttc = ThresholdTissueClassifier(tissue_map.astype('float32'), 0.5) # test voxel center for ind in ndindex(tissue_map.shape): pts = np.array(ind, dtype='float64') state = ttc.check_point(pts) if tissue_map[ind] > 0.5: npt.assert_equal(state, TissueTypes.TRACKPOINT) else: npt.assert_equal(state, TissueTypes.ENDPOINT) # test random points in voxel inds = [[0, 1.4, 2.2], [0, 2.3, 2.3], [0, 2.2, 1.3], [0, 0.9, 2.2], [0, 2.8, 1.1], [0, 1.1, 3.3], [0, 2.1, 1.9], [0, 3.1, 3.1], [0, 0.1, 0.1], [0, 0.9, 0.5], [0, 0.9, 0.5], [0, 2.9, 0.1]] for pts in inds: pts = np.array(pts, dtype='float64') state = ttc.check_point(pts) res = scipy.ndimage.map_coordinates( tissue_map, np.reshape(pts, (3, 1)), order=1, mode='nearest') if res > 0.5: npt.assert_equal(state, TissueTypes.TRACKPOINT) else: npt.assert_equal(state, TissueTypes.ENDPOINT) # test outside points outside_pts = [[100, 100, 100], [0, -1, 1], [0, 10, 2], [0, 0.5, -0.51], [0, -0.51, 0.1]] for pts in outside_pts: pts = np.array(pts, dtype='float64') state = ttc.check_point(pts) npt.assert_equal(state, TissueTypes.OUTSIDEIMAGE)
def test_probabilistic_odf_weighted_tracker(): """This tests that the Probabalistic Direction Getter plays nice LocalTracking and produces reasonable streamlines in a simple example. """ sphere = HemiSphere.from_sphere(unit_octahedron) # A simple image with three possible configurations, a vertical tract, # a horizontal tract and a crossing pmf_lookup = np.array([[0., 0., 1.], [1., 0., 0.], [0., 1., 0.], [.6, .4, 0.]]) simple_image = np.array([ [0, 1, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0], [0, 3, 2, 2, 2, 0], [0, 1, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0], ]) simple_image = simple_image[..., None] pmf = pmf_lookup[simple_image] seeds = [np.array([1., 1., 0.])] * 30 mask = (simple_image > 0).astype(float) tc = ThresholdTissueClassifier(mask, .5) dg = ProbabilisticDirectionGetter.from_pmf(pmf, 90, sphere, pmf_threshold=0.1) streamlines = LocalTracking(dg, tc, seeds, np.eye(4), 1.) expected = [ np.array([[0., 1., 0.], [1., 1., 0.], [2., 1., 0.], [2., 2., 0.], [2., 3., 0.], [2., 4., 0.]]), np.array([[0., 1., 0.], [1., 1., 0.], [2., 1., 0.], [3., 1., 0.], [4., 1., 0.]]) ] def allclose(x, y): return x.shape == y.shape and np.allclose(x, y) path = [False, False] for sl in streamlines: if allclose(sl, expected[0]): path[0] = True elif allclose(sl, expected[1]): path[1] = True else: raise AssertionError() npt.assert_(all(path)) # The first path is not possible if 90 degree turns are excluded dg = ProbabilisticDirectionGetter.from_pmf(pmf, 80, sphere, pmf_threshold=0.1) streamlines = LocalTracking(dg, tc, seeds, np.eye(4), 1.) for sl in streamlines: npt.assert_(np.allclose(sl, expected[1])) # The first path is not possible if pmf_threshold > 0.67 # 0.4/0.6 < 2/3, multiplying the pmf should not change the ratio dg = ProbabilisticDirectionGetter.from_pmf(10 * pmf, 90, sphere, pmf_threshold=0.67) streamlines = LocalTracking(dg, tc, seeds, np.eye(4), 1.) for sl in streamlines: npt.assert_(np.allclose(sl, expected[1])) # Test non WM seed position seeds = [[0, 0, 0], [5, 5, 5]] streamlines = LocalTracking(dg, tc, seeds, np.eye(4), 0.2, max_cross=1, return_all=True) streamlines = Streamlines(streamlines) npt.assert_(len(streamlines[0]) == 1) # INVALIDPOINT npt.assert_(len(streamlines[1]) == 1) # OUTSIDEIMAGE # Test that all points are within the image volume seeds = seeds_from_mask(np.ones(mask.shape), density=2) streamline_generator = LocalTracking(dg, tc, seeds, np.eye(4), 0.5, return_all=True) streamlines = Streamlines(streamline_generator) for s in streamlines: npt.assert_(np.all((s + 0.5).astype(int) >= 0)) npt.assert_(np.all((s + 0.5).astype(int) < mask.shape)) # Test that the number of streamline return with return_all=True equal the # number of seeds places npt.assert_(np.array([len(streamlines) == len(seeds)])) # Test reproducibility tracking_1 = Streamlines( LocalTracking(dg, tc, seeds, np.eye(4), 0.5, random_seed=0)).data tracking_2 = Streamlines( LocalTracking(dg, tc, seeds, np.eye(4), 0.5, random_seed=0)).data npt.assert_equal(tracking_1, tracking_2)
csa_peaks = peaks_from_model(csa_model, data, default_sphere, relative_peak_threshold=.8, min_separation_angle=45, mask=white_matter) """ 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, but we can go a step further and restrict fiber tracking to those areas where the ODF shows significant restricted diffusion by thresholding on the general fractional anisotropy (GFA). """ from dipy.tracking.local import ThresholdTissueClassifier classifier = ThresholdTissueClassifier(csa_peaks.gfa, .25) """ 3. Before we can begin tracking is to specify where to "seed" (begin) the fiber tracking. Generally, the seeds chosen will depend on the pathways one is interested in modeling. In this example, we'll use a 2x2x2 grid of seeds per voxel, in a sagittal slice of the Corpus Callosum. Tracking from this region will give us a model of the Corpus Callosum tract. This slice has label value 2 in the labels image. """ from dipy.tracking import utils seed_mask = labels == 2 seeds = utils.seeds_from_mask(seed_mask, density=[2, 2, 2], affine=affine)
For the tracking part, we will use the fiber directions from the ``csd_model`` but stop tracking in areas where fractional anisotropy is low (< 0.1). To derive the FA, used here as a stopping criterion, we would need to fit a tensor model first. Here, we fit the tensor using weighted least squares (WLS). """ tensor_model = TensorModel(gtab, fit_method='WLS') tensor_fit = tensor_model.fit(data, mask) fa = tensor_fit.fa """ In this simple example we can use FA to stop tracking. Here we stop tracking when FA < 0.1. """ tissue_classifier = ThresholdTissueClassifier(fa, 0.1) """ 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))
def test_contour_from_roi(): # Render volume scene = window.Scene() data = np.zeros((50, 50, 50)) data[20:30, 25, 25] = 1. data[25, 20:30, 25] = 1. affine = np.eye(4) surface = actor.contour_from_roi(data, affine, color=np.array([1, 0, 1]), opacity=.5) scene.add(surface) scene.reset_camera() scene.reset_clipping_range() # window.show(scene) # Test binarization scene2 = window.Scene() data2 = np.zeros((50, 50, 50)) data2[20:30, 25, 25] = 1. data2[35:40, 25, 25] = 1. affine = np.eye(4) surface2 = actor.contour_from_roi(data2, affine, color=np.array([0, 1, 1]), opacity=.5) scene2.add(surface2) scene2.reset_camera() scene2.reset_clipping_range() # window.show(scene2) arr = window.snapshot(scene, 'test_surface.png', offscreen=True) arr2 = window.snapshot(scene2, 'test_surface2.png', offscreen=True) report = window.analyze_snapshot(arr, find_objects=True) report2 = window.analyze_snapshot(arr2, find_objects=True) npt.assert_equal(report.objects, 1) npt.assert_equal(report2.objects, 2) # test on real streamlines using tracking example from dipy.data import read_stanford_labels from dipy.reconst.shm import CsaOdfModel from dipy.data import default_sphere from dipy.direction import peaks_from_model from dipy.tracking.local import ThresholdTissueClassifier from dipy.tracking import utils from dipy.tracking.local import LocalTracking from fury.colormap import line_colors hardi_img, gtab, labels_img = read_stanford_labels() data = hardi_img.get_data() labels = labels_img.get_data() affine = hardi_img.affine white_matter = (labels == 1) | (labels == 2) csa_model = CsaOdfModel(gtab, sh_order=6) csa_peaks = peaks_from_model(csa_model, data, default_sphere, relative_peak_threshold=.8, min_separation_angle=45, mask=white_matter) classifier = ThresholdTissueClassifier(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 = list(streamlines) # Prepare the display objects. streamlines_actor = actor.line(streamlines, line_colors(streamlines)) seedroi_actor = actor.contour_from_roi(seed_mask, affine, [0, 1, 1], 0.5) # Create the 3d display. r = window.Scene() r2 = window.Scene() r.add(streamlines_actor) arr3 = window.snapshot(r, 'test_surface3.png', offscreen=True) report3 = window.analyze_snapshot(arr3, find_objects=True) r2.add(streamlines_actor) r2.add(seedroi_actor) arr4 = window.snapshot(r2, 'test_surface4.png', offscreen=True) report4 = window.analyze_snapshot(arr4, find_objects=True) # assert that the seed ROI rendering is not far # away from the streamlines (affine error) npt.assert_equal(report3.objects, report4.objects)
def track(dwi_file, bval, bvec, mask_file, stop_val=0.1): # """ # Tracking with basic tensors and basic eudx - experimental # We now force seeding at every voxel in the provided mask for # simplicity. Future functionality will extend these options. # **Positional Arguments:** # dwi_file: # - File (registered) to use for tensor/fiber tracking # mask_file: # - Brain mask to keep tensors inside the brain # gtab: # - dipy formatted bval/bvec Structure # **Optional Arguments:** # stop_val: # - Value to cutoff fiber track # """ #img = nb.load(dwi_file) #data = img.get_data() dwi = dipy.data.load(dwi_file) data = dwi.get_data() #img = nb.load(mask_file) #mask = img.get_data() dwi_mask = dipy.data.load(mask_file) mask = dwi_mask.get_data() gtab = gradient_table(bval, bvec) affine = dwi.affine seed_mask = mask seeds = utils.seeds_from_mask(seed_mask, density=1, affine=affine) # use all points in mask seedIdx = np.where(mask > 0) # seed everywhere not equal to zero seedIdx = np.transpose(seedIdx) sphere = get_sphere('symmetric724') csd_model = ConstrainedSphericalDeconvModel(gtab, None, sh_order=6) csd_fit = csd_model.fit(data, mask=mask) tensor_model = dti.TensorModel(gtab) tenfit = tensor_model.fit(data, mask=mask) FA = fractional_anisotropy(tenfit.evals) classifier = ThresholdTissueClassifier(FA, 0.1) dg = DeterministicMaximumDirectionGetter.from_shcoeff(csd_fit.shm_coeff, max_angle=80., sphere=sphere) streamlines_generator = LocalTracking(dg, classifier, seeds, affine, step_size=0.5) streamlines = Streamlines(streamlines_generator) trk_file = save_trk("deterministic_threshold_DDG_samp_data.trk", streamlines, affine=affine, shape=mask.shape)
def track(params_file, directions="det", max_angle=30., sphere=None, seed_mask=None, seeds=2, stop_mask=None, stop_threshold=0.2, step_size=0.5, n_jobs=-1, n_chunks=100, backend="threading", engine="dask"): """ Tractography Parameters ---------- params_file : str, nibabel img. Full path to a nifti file containing CSD spherical harmonic coefficients, or nibabel img with model params. directions : str How tracking directions are determined. One of: {"deterministic" | "probablistic"} max_angle : float, optional. The maximum turning angle in each step. Default: 30 sphere : Sphere object, optional. The discretization of direction getting. default: dipy.data.default_sphere. seed_mask : array, optional. Binary mask describing the ROI within which we seed for tracking. Default to the entire volume. seed : int or 2D array, optional. The seeding density: if this is an int, it is is how many seeds in each voxel on each dimension (for example, 2 => [2, 2, 2]). If this is a 2D array, these are the coordinates of the seeds. stop_mask : array, optional. A floating point value that determines a stopping criterion (e.g. FA). Default to no stopping (all ones). stop_threshold : float, optional. A value of the stop_mask below which tracking is terminated. Default to 0.2. step_size : float, optional. Returns ------- LocalTracking object. """ if isinstance(params_file, str): params_img = nib.load(params_file) else: params_img = params_file model_params = params_img.get_data() affine = params_img.get_affine() if isinstance(seeds, int): if seed_mask is None: seed_mask = np.ones(params_img.shape[:3]) seeds = dtu.seeds_from_mask(seed_mask, density=seeds, affine=affine) if sphere is None: sphere = dpd.default_sphere if directions == "det": dg = DeterministicMaximumDirectionGetter elif directions == "prob": dg = ProbabilisticDirectionGetter # These are models that have ODFs (there might be others in the future...) if model_params.shape[-1] == 12 or model_params.shape[-1] == 27: model = "ODF" # Could this be an SHM model? If the max order is a whole even number, it # might be: elif shm.calculate_max_order(model_params.shape[-1]) % 2 == 0: model = "SHM" if model == "SHM": dg = dg.from_shcoeff(model_params, max_angle=max_angle, sphere=sphere) elif model == "ODF": evals = model_params[..., :3] evecs = model_params[..., 3:12].reshape(params_img.shape[:3] + (3, 3)) odf = tensor_odf(evals, evecs, sphere) dg = dg.from_pmf(odf, max_angle=max_angle, sphere=sphere) if stop_mask is None: stop_mask = np.ones(params_img.shape[:3]) threshold_classifier = ThresholdTissueClassifier(stop_mask, stop_threshold) if engine == "serial": return _local_tracking(seeds, dg, threshold_classifier, affine, step_size=step_size) else: if n_chunks < seeds.shape[0]: seeds_list = [] i2 = 0 seeds_per_chunk = seeds.shape[0] // n_chunks for chunk in range(n_chunks - 1): i1 = i2 i2 = seeds_per_chunk * (chunk + 1) seeds_list.append(seeds[i1:i2]) else: seeds_list = seeds ll = parfor(_local_tracking, seeds_list, n_jobs=n_jobs, engine=engine, backend=backend, func_args=[dg, threshold_classifier, affine], func_kwargs=dict(step_size=step_size)) return (list(chain(*ll)))
def toGenerateBunddle(roi1, roi2, data, gtab, affine): print('Starting Bundles generator') from dipy.reconst.shm import CsaOdfModel from dipy.data import default_sphere from dipy.direction import peaks_from_model from dipy.tracking.local import LocalTracking from dipy.tracking import utils from dipy.tracking.local import ThresholdTissueClassifier lin_T, offset = _mapping_to_voxel(affine, None) volueMaskPath = '/home/jrudascas/Desktop/DWITest/Datos_Salida/Subject_Reslice_MedianOtsu_b0Masked_mask.nii.gz' masked = nib.load(volueMaskPath) dataMasked = masked.get_data() print('Starting the CsaOdfModel ROI') ROIPath = '/home/jrudascas/Desktop/DWITest/Datos_Salida/AAN_1mm_ROI_1.0.nii.gz' ROImasked = nib.load(ROIPath) maskROI = ROImasked.get_data() seeds = utils.seeds_from_mask(maskROI.astype(bool), density=[3, 3, 3], affine=affine) csa_model = CsaOdfModel(gtab, sh_order=6) csa_peaks = peaks_from_model(csa_model, data, default_sphere, sh_order=6, relative_peak_threshold=.8, min_separation_angle=45, mask=dataMasked.astype(bool)) classifier = ThresholdTissueClassifier(csa_peaks.gfa, .25) streamlines = LocalTracking(csa_peaks, classifier, seeds, affine, step_size=.5) streamlines = [s for s in streamlines if s.shape[0] > 5] streamlines = list(streamlines) save_trk("/home/jrudascas/Desktop/DWITest/Datos_Salida/CsaOdfModelROI.trk", streamlines, affine, roi1.shape) bunddle = [] for sl in streamlines: # sl += offset # sl_Aux = np.copy(sl) sl_Aux = sl sl = _to_voxel_coordinates(sl, lin_T, offset) i, j, k = sl.T labelsROI = roi2[i, j, k] if sum(labelsROI) > 0: bunddle.append(sl_Aux) save_trk( '/home/jrudascas/Desktop/DWITest/Datos_Salida/BundleROI_to_ROI.trk', bunddle, affine=affine, shape=roi2.shape)
def track(params_file, directions="det", max_angle=30., sphere=None, seed_mask=None, seeds=1, stop_mask=None, stop_threshold=0, step_size=0.5, min_length=10): """ Tractography Parameters ---------- params_file : str, nibabel img. Full path to a nifti file containing CSD spherical harmonic coefficients, or nibabel img with model params. directions : str How tracking directions are determined. One of: {"deterministic" | "probablistic"} max_angle : float, optional. The maximum turning angle in each step. Default: 30 sphere : Sphere object, optional. The discretization of direction getting. default: dipy.data.default_sphere. seed_mask : array, optional. Binary mask describing the ROI within which we seed for tracking. Default to the entire volume. seed : int or 2D array, optional. The seeding density: if this is an int, it is is how many seeds in each voxel on each dimension (for example, 2 => [2, 2, 2]). If this is a 2D array, these are the coordinates of the seeds. stop_mask : array, optional. A floating point value that determines a stopping criterion (e.g. FA). Default to no stopping (all ones). stop_threshold : float, optional. A value of the stop_mask below which tracking is terminated. Default to 0 (this means that if no stop_mask is passed, we will stop only at the edge of the image) step_size : float, optional. The size (in mm) of a step of tractography. Default: 0.5 min_length: int, optional The miminal length (no. of nodes) in a streamline. Default: 10 Returns ------- list of streamlines () """ if isinstance(params_file, str): params_img = nib.load(params_file) else: params_img = params_file model_params = params_img.get_data() affine = params_img.affine if isinstance(seeds, int): if seed_mask is None: seed_mask = np.ones(params_img.shape[:3]) seeds = dtu.seeds_from_mask(seed_mask, density=seeds, affine=affine) if sphere is None: sphere = dpd.default_sphere if directions == "det": dg = DeterministicMaximumDirectionGetter elif directions == "prob": dg = ProbabilisticDirectionGetter # These are models that have ODFs (there might be others in the future...) if model_params.shape[-1] == 12 or model_params.shape[-1] == 27: model = "ODF" # Could this be an SHM model? If the max order is a whole even number, it # might be: elif shm.calculate_max_order(model_params.shape[-1]) % 2 == 0: model = "SHM" if model == "SHM": dg = dg.from_shcoeff(model_params, max_angle=max_angle, sphere=sphere) elif model == "ODF": evals = model_params[..., :3] evecs = model_params[..., 3:12].reshape(params_img.shape[:3] + (3, 3)) odf = tensor_odf(evals, evecs, sphere) dg = dg.from_pmf(odf, max_angle=max_angle, sphere=sphere) if stop_mask is None: stop_mask = np.ones(params_img.shape[:3]) threshold_classifier = ThresholdTissueClassifier(stop_mask, stop_threshold) return _local_tracking(seeds, dg, threshold_classifier, affine, step_size=step_size, min_length=min_length)
def run_to_generate_bunddle(path_input, path_output, file_inMask="", fbval="", fbvec=""): folder = os.path.dirname(path_input) if fbval == "" or fbvec == "": folder_sujeto = path_output for l in os.listdir(folder_sujeto): if "TENSOR" in l and "bval" in l: fbval = os.path.join(folder_sujeto, l) if "TENSOR" in l and "bvec" in l: fbvec = os.path.join(folder_sujeto, l) if file_inMask == "": for i in os.listdir(folder): if "masked_mask" in i: file_inMask = os.path.join(folder, i) if not os.path.exists(os.path.join(path_output, 'feature.out')): list_path_atlas_1 = [] with open(os.path.join(folder, "list_path_atlas_1.txt")) as f: for line in f: list_path_atlas_1.append(line.strip()) list_path_atlas_2 = [] with open(os.path.join(folder, "list_path_atlas_2.txt")) as f: for line in f: list_path_atlas_2.append(line.strip()) list_path_atlas_3 = [] with open(os.path.join(folder, "list_path_atlas_3.txt")) as f: for line in f: list_path_atlas_3.append(line.strip()) list_path_atlas_4 = [] with open(os.path.join(folder, "list_path_atlas_4.txt")) as f: for line in f: list_path_atlas_4.append(line.strip()) # def to_generate_bunddle(path_dwi_input, path_output, path_binary_mask, path_bval, path_bvec, bunddle_rules, atlas_dict): from dipy.reconst.shm import CsaOdfModel from dipy.data import default_sphere from dipy.direction import peaks_from_model from dipy.tracking.local import LocalTracking from dipy.tracking import utils from dipy.tracking.local import ThresholdTissueClassifier from dipy.tracking._utils import (_mapping_to_voxel, _to_voxel_coordinates) print(d.separador + 'starting of model') dwi_img = nib.load(path_input) dwi_data = dwi_img.get_data() dwi_affine = dwi_img.affine dwi_mask_data = nib.load(file_inMask).get_data().astype(bool) g_tab = gradient_table(fbval, fbvec) csa_model = CsaOdfModel(g_tab, sh_order=6) csa_peaks = peaks_from_model(csa_model, dwi_data, default_sphere, sh_order=6, relative_peak_threshold=.8, min_separation_angle=35, mask=dwi_mask_data) print(d.separador + 'ending of model') print(d.separador + 'starting of classifier') classifier = ThresholdTissueClassifier(csa_peaks.gfa, .2) print(d.separador + 'ending of classifier') list_bunddle = [] ruleNumber = 1 indexHarvardOxfortCortical = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47 ] atlas_dict = { 'Morel': list_path_atlas_2, 'AAN': list_path_atlas_1, 'HarvardOxfordCort': list_path_atlas_4, 'HypothalamusAtlas': list_path_atlas_3 } bunddle_rules = [(('AAN', [1, 3]), ('Morel', [4, 5, 6, 18, 42, 43, 44, 56]), ('HarvardOxfordCort', indexHarvardOxfortCortical)), (('Morel', [4, 5, 6, 18, 42, 43, 44, 56]), ('HarvardOxfordCort', indexHarvardOxfortCortical)), (('HypothalamusAtlas', [1, 2, 3]), None)] for rule in bunddle_rules: print('Starting ROI reconstruction') for elementROI in rule[0][1]: if not ('roi' in locals()): roi = nib.load(atlas_dict[rule[0][0]] [elementROI]).get_data().astype(bool) else: roi = roi | nib.load(atlas_dict[rule[0][0]] [elementROI]).get_data().astype(bool) nib.save( nib.Nifti1Image(roi.astype(np.float32), dwi_affine), os.path.join(path_output, 'roi_rule_' + str(ruleNumber) + '.nii.gz')) seeds = utils.seeds_from_mask(roi, density=[2, 2, 2], affine=dwi_affine) streamlines = LocalTracking(csa_peaks, classifier, seeds, dwi_affine, step_size=1) streamlines = [s for s in streamlines if s.shape[0] > 30] streamlines = list(streamlines) #save_trk(path_output + 'bundleROI_rule_' + str(ruleNumber) + '.trk', streamlines, dwi_affine, roi.shape) print('Finished ROI reconstruction') print('Starting TARGET filtering') bunddle = [] lin_T, offset = _mapping_to_voxel(dwi_affine, None) if rule[1] is not None: for elementROI in rule[1][1]: if not ('target' in locals()): target = nib.load(atlas_dict[rule[1][0]] [elementROI]).get_data().astype(bool) else: target = target | nib.load(atlas_dict[ rule[1][0]][elementROI]).get_data().astype(bool) #nib.save(nib.Nifti1Image(target.astype(np.float32), dwi_affine), path_output + 'target_rule_' + str(ruleNumber) + '.nii.gz') for sl in streamlines: # sl += offset # sl_Aux = np.copy(sl) sl_Aux = sl sl = _to_voxel_coordinates(sl, lin_T, offset) i, j, k = sl.T labelsROI = target[i, j, k] if sum(labelsROI) > 0: bunddle.append(sl_Aux) else: bunddle = streamlines #save_trk(path_output + 'bundle_rule_' + str(ruleNumber) + '.trk', bunddle, dwi_affine, roi.shape) print('Finished TARGET filtering') if len(rule) == 3: # If is necessary other filtering (exclusition) for elementROI in rule[2][1]: if not ('roiFiltered' in locals()): roiFiltered = nib.load(atlas_dict[ rule[2][0]][elementROI]).get_data().astype(bool) else: roiFiltered = roiFiltered | nib.load(atlas_dict[ rule[2][0]][elementROI]).get_data().astype(bool) bunddleFiltered = [] for b in bunddle: b_Aux = b b = _to_voxel_coordinates(b, lin_T, offset) i, j, k = b.T labelsROI = roiFiltered[i, j, k] if sum(labelsROI) == 0: bunddleFiltered.append(b_Aux) print('Finished exclusive filtering:') if 'roiFiltered' in locals(): del roiFiltered else: if 'bunddleFiltered' in locals(): del bunddleFiltered bunddleFiltered = bunddle save_trk( os.path.join(path_output, 'bundle_rule_' + str(ruleNumber) + '.trk'), bunddleFiltered, dwi_affine, roi.shape) if 'roi' in locals(): del roi if 'target' in locals(): del target ruleNumber = ruleNumber + 1 list_bunddle.append(bunddleFiltered) print(list_bunddle) roi_rules = collections.OrderedDict() roi_rules['AAN'] = [1, 3] roi_rules['Morel'] = [4, 5, 6, 18, 42, 43, 44, 56] roi_rules['HypothalamusAtlas'] = [1, 2, 3] list_maps = [] with open(os.path.join(folder, "list_maps.txt")) as f: for line in f: list_maps.append(line.strip()) features = [] # Measuring over streamlines for bunddle in list_bunddle: features.append(len(bunddle)) # Fibers number # Measuring over roi list for key in roi_rules.keys(): print(key) for elementROI in roi_rules[key]: print(atlas_dict[key][elementROI]) roi = nib.load( atlas_dict[key][elementROI]).get_data().astype(bool) for map in list_maps: data_map = nib.load(map).get_data()[roi] features.append(np.mean(data_map)) features.append(np.min(data_map)) features.append(np.max(data_map)) features.append(np.std(data_map)) np.savetxt(os.path.join(path_output, 'feature.out'), np.array(features), delimiter=' ', fmt='%s') print(os.path.join(path_output, 'feature.out')) return path_input
def to_generate_bunddle(path_dwi_input, path_output, path_binary_mask, path_bval, path_bvec, bunddle_rules, atlas_dict): from dipy.reconst.shm import CsaOdfModel from dipy.data import default_sphere from dipy.direction import peaks_from_model from dipy.tracking.local import LocalTracking from dipy.tracking import utils from dipy.tracking.local import ThresholdTissueClassifier print(d.separador + 'starting of model') dwi_img = nib.load(path_dwi_input) dwi_data = dwi_img.get_data() dwi_affine = dwi_img.affine dwi_mask_data = nib.load(path_binary_mask).get_data().astype(bool) g_tab = gradient_table(path_bval, path_bvec) csa_model = CsaOdfModel(g_tab, sh_order=6) csa_peaks = peaks_from_model(csa_model, dwi_data, default_sphere, sh_order=6, relative_peak_threshold=.8, min_separation_angle=35, mask=dwi_mask_data) print(d.separador + 'ending of model') print(d.separador + 'starting of classifier') classifier = ThresholdTissueClassifier(csa_peaks.gfa, .2) print(d.separador + 'ending of classifier') list_bunddle = [] ruleNumber = 1 for rule in bunddle_rules: print('Starting ROI reconstruction') for elementROI in rule[0][1]: if not ('roi' in locals()): roi = nib.load( atlas_dict[rule[0][0]][elementROI]).get_data().astype(bool) else: roi = roi | nib.load( atlas_dict[rule[0][0]][elementROI]).get_data().astype(bool) nib.save(nib.Nifti1Image(roi.astype(np.float32), dwi_affine), path_output + 'roi_rule_' + str(ruleNumber) + '.nii.gz') seeds = utils.seeds_from_mask(roi, density=[2, 2, 2], affine=dwi_affine) streamlines = LocalTracking(csa_peaks, classifier, seeds, dwi_affine, step_size=1) streamlines = [s for s in streamlines if s.shape[0] > 30] streamlines = list(streamlines) #save_trk(path_output + 'bundleROI_rule_' + str(ruleNumber) + '.trk', streamlines, dwi_affine, roi.shape) print('Finished ROI reconstruction') print('Starting TARGET filtering') bunddle = [] lin_T, offset = _mapping_to_voxel(dwi_affine, None) if rule[1] is not None: for elementROI in rule[1][1]: if not ('target' in locals()): target = nib.load(atlas_dict[rule[1][0]] [elementROI]).get_data().astype(bool) else: target = target | nib.load(atlas_dict[ rule[1][0]][elementROI]).get_data().astype(bool) #nib.save(nib.Nifti1Image(target.astype(np.float32), dwi_affine), path_output + 'target_rule_' + str(ruleNumber) + '.nii.gz') for sl in streamlines: # sl += offset # sl_Aux = np.copy(sl) sl_Aux = sl sl = _to_voxel_coordinates(sl, lin_T, offset) i, j, k = sl.T labelsROI = target[i, j, k] if sum(labelsROI) > 0: bunddle.append(sl_Aux) else: bunddle = streamlines #save_trk(path_output + 'bundle_rule_' + str(ruleNumber) + '.trk', bunddle, dwi_affine, roi.shape) print('Finished TARGET filtering') if len(rule) == 3: # If is necessary other filtering (exclusition) for elementROI in rule[2][1]: if not ('roiFiltered' in locals()): roiFiltered = nib.load(atlas_dict[ rule[2][0]][elementROI]).get_data().astype(bool) else: roiFiltered = roiFiltered | nib.load(atlas_dict[ rule[2][0]][elementROI]).get_data().astype(bool) bunddleFiltered = [] for b in bunddle: b_Aux = b b = _to_voxel_coordinates(b, lin_T, offset) i, j, k = b.T labelsROI = roiFiltered[i, j, k] if sum(labelsROI) == 0: bunddleFiltered.append(b_Aux) print('Finished exclusive filtering:') if 'roiFiltered' in locals(): del roiFiltered else: if 'bunddleFiltered' in locals(): del bunddleFiltered bunddleFiltered = bunddle save_trk(path_output + 'bundle_rule_' + str(ruleNumber) + '.trk', bunddleFiltered, dwi_affine, roi.shape) if 'roi' in locals(): del roi if 'target' in locals(): del target ruleNumber = ruleNumber + 1 list_bunddle.append(bunddleFiltered) return list_bunddle
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) streamlines = Streamlines(streamline_generator) show_streamlines(streamlines) save_trk_n('streamlines.trk',
def dwi_deterministic_tracing(image, bvecs, bvals, wm, seeds, fibers, prune_length=3, plot=False, verbose=False): # Pipeline transcribed from: # http://nipy.org/dipy/examples_built/introduction_to_basic_tracking.html # Load Images dwi_loaded = nib.load(image) dwi_data = dwi_loaded.get_data() wm_loaded = nib.load(wm) wm_data = wm_loaded.get_data() seeds_loaded = nib.load(seeds) seeds_data = seeds_loaded.get_data() # Load B-values & B-vectors # NB. Use aligned b-vecs if providing eddy-aligned data bvals, bvecs = read_bvals_bvecs(bvals, bvecs) gtab = gradient_table(bvals, bvecs) # Establish ODF model csa_model = CsaOdfModel(gtab, sh_order=6) csa_peaks = peaks_from_model(csa_model, dwi_data, default_sphere, relative_peak_threshold=0.8, min_separation_angle=45, mask=wm_data) # Classify tissue for high FA and create seeds # (Putting this inside a looped try-block to handle fuzzy failures) classifier = ThresholdTissueClassifier(csa_peaks.gfa, 0.25) seeds = wrap_fuzzy_failures(utils.seeds_from_mask, args=[seeds_data], kwargs={"density": [2, 2, 2], "affine": np.eye(4)}, errortype=ValueError, failure_threshold=5, verbose=verbose) # Perform deterministic tracing # (Putting this inside a looped try-block to handle fuzzy failures) streamlines_generator = wrap_fuzzy_failures(LocalTracking, args=[csa_peaks, classifier, seeds], kwargs={"affine": np.eye(4), "step_size": 0.5}, errortype=ValueError, failure_threshold=5, verbose=verbose) streamlines = wrap_fuzzy_failures(Streamlines, args=[streamlines_generator], kwargs={}, errortype=IndexError, failure_threshold=5, verbose=verbose) # Prune streamlines streamlines = ArraySequence([strline for strline in streamlines if len(strline) > prune_length]) # Save streamlines save_trk(fibers + ".trk", streamlines, dwi_loaded.affine, shape=wm_data.shape, vox_size=wm_loaded.header.get_zooms()) # Visualize fibers if plot and have_fury: from dipy.viz import window, actor, colormap as cmap color = cmap.line_colors(streamlines) streamlines_actor = actor.line(streamlines, color) # Create the 3D display. r = window.Renderer() r.add(streamlines_actor) # Save still image. window.record(r, n_frames=1, out_path=fibers + ".png", size=(800, 800))
def main(): start = time.time() with open('config.json') as config_json: config = json.load(config_json) # Load the data dmri_image = nib.load(config['data_file']) dmri = dmri_image.get_data() affine = dmri_image.affine #aparc_im = nib.load(config['freesurfer']) aparc_im = nib.load('volume.nii.gz') aparc = aparc_im.get_data() end = time.time() print('Loaded Files: ' + str((end - start))) # Create the white matter and callosal masks start = time.time() wm_regions = [ 2, 41, 16, 17, 28, 60, 51, 53, 12, 52, 12, 52, 13, 18, 54, 50, 11, 251, 252, 253, 254, 255, 10, 49, 46, 7 ] wm_mask = np.zeros(aparc.shape) for l in wm_regions: wm_mask[aparc == l] = 1 # Create the gradient table from the bvals and bvecs bvals, bvecs = read_bvals_bvecs(config['data_bval'], config['data_bvec']) gtab = gradient_table(bvals, bvecs, b0_threshold=100) end = time.time() print('Created Gradient Table: ' + str((end - start))) ##The probabilistic model## # Use the Constant Solid Angle (CSA) to find the Orientation Dist. Function # Helps orient the wm tracts start = time.time() csa_model = CsaOdfModel(gtab, sh_order=6) csa_peaks = peaks_from_model(csa_model, dmri, default_sphere, relative_peak_threshold=.8, min_separation_angle=45, mask=wm_mask) print('Creating CSA Model: ' + str(time.time() - start)) # Begins the seed in the wm tracts seeds = utils.seeds_from_mask(wm_mask, density=[1, 1, 1], affine=affine) print('Created White Matter seeds: ' + str(time.time() - start)) # Create a CSD model to measure Fiber Orientation Dist print('Begin the probabilistic model') response, ratio = auto_response(gtab, dmri, roi_radius=10, fa_thr=0.7) csd_model = ConstrainedSphericalDeconvModel(gtab, response, sh_order=6) csd_fit = csd_model.fit(dmri, mask=wm_mask) print('Created the CSD model: ' + str(time.time() - start)) # Set the Direction Getter to randomly choose directions prob_dg = ProbabilisticDirectionGetter.from_shcoeff(csd_fit.shm_coeff, max_angle=30., sphere=default_sphere) print('Created the Direction Getter: ' + str(time.time() - start)) # Restrict the white matter tracking classifier = ThresholdTissueClassifier(csa_peaks.gfa, .25) print('Created the Tissue Classifier: ' + str(time.time() - start)) # Create the probabilistic model streamlines = LocalTracking(prob_dg, tissue_classifier=classifier, seeds=seeds, step_size=.5, max_cross=1, affine=affine) print('Created the probabilistic model: ' + str(time.time() - start)) # Compute streamlines and store as a list. streamlines = list(streamlines) print('Computed streamlines: ' + str(time.time() - start)) #from dipy.tracking.streamline import transform_streamlines #streamlines = transform_streamlines(streamlines, np.linalg.inv(affine)) # Create a tractogram from the streamlines and save it tractogram = Tractogram(streamlines, affine_to_rasmm=affine) #tractogram.apply_affine(np.linalg.inv(affine)) save(tractogram, 'track.tck') end = time.time() print("Created the tck file: " + str((end - start)))
def test_maximum_deterministic_tracker(): """This tests that the Maximum Deterministic Direction Getter plays nice LocalTracking and produces reasonable streamlines in a simple example. """ sphere = HemiSphere.from_sphere(unit_octahedron) # A simple image with three possible configurations, a vertical tract, # a horizontal tract and a crossing pmf_lookup = np.array([[0., 0., 1.], [1., 0., 0.], [0., 1., 0.], [.4, .6, 0.]]) simple_image = np.array([ [0, 1, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0], [0, 3, 2, 2, 2, 0], [0, 1, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0], ]) simple_image = simple_image[..., None] pmf = pmf_lookup[simple_image] seeds = [np.array([1., 1., 0.])] * 30 mask = (simple_image > 0).astype(float) tc = ThresholdTissueClassifier(mask, .5) dg = DeterministicMaximumDirectionGetter.from_pmf(pmf, 90, sphere, pmf_threshold=0.1) streamlines = LocalTracking(dg, tc, seeds, np.eye(4), 1.) expected = [ np.array([[0., 1., 0.], [1., 1., 0.], [2., 1., 0.], [2., 2., 0.], [2., 3., 0.], [2., 4., 0.]]), np.array([[0., 1., 0.], [1., 1., 0.], [2., 1., 0.], [3., 1., 0.], [4., 1., 0.]]), np.array([[0., 1., 0.], [1., 1., 0.], [2., 1., 0.]]) ] def allclose(x, y): return x.shape == y.shape and np.allclose(x, y) for sl in streamlines: if not allclose(sl, expected[0]): raise AssertionError() # The first path is not possible if 90 degree turns are excluded dg = DeterministicMaximumDirectionGetter.from_pmf(pmf, 80, sphere, pmf_threshold=0.1) streamlines = LocalTracking(dg, tc, seeds, np.eye(4), 1.) for sl in streamlines: npt.assert_(np.allclose(sl, expected[1])) # Both path are not possible if 90 degree turns are exclude and # if pmf_threshold is larger than 0.67. Streamlines should stop at # the crossing. # 0.4/0.6 < 2/3, multiplying the pmf should not change the ratio dg = DeterministicMaximumDirectionGetter.from_pmf(10 * pmf, 80, sphere, pmf_threshold=0.67) streamlines = LocalTracking(dg, tc, seeds, np.eye(4), 1.) for sl in streamlines: npt.assert_(np.allclose(sl, expected[2]))
white_matter = (labels == 1) | (labels == 2) from dipy.reconst.shm import CsaOdfModel from dipy.data import default_sphere from dipy.direction import peaks_from_model csa_model = CsaOdfModel(gtab, sh_order=6) csa_peaks = peaks_from_model(csa_model, data, default_sphere, relative_peak_threshold=.8, min_separation_angle=45, mask=white_matter) from dipy.tracking.local import ThresholdTissueClassifier classifier = ThresholdTissueClassifier(csa_peaks.gfa, .25) from dipy.tracking import utils from dipy.tracking.local import OptimizedLocalTracking seed_mask = labels == 2 seeds = utils.seeds_from_mask(seed_mask, density=[2, 2, 2], affine=affine) op_tracking = OptimizedLocalTracking(csa_peaks, classifier, seeds, affine, step_size=.5) """ import copy_reg def pickle_tissue_classifer(classifer_object):
save_peaks(fpeaks, peaks_csd) # In[40]: from dipy.io.trackvis import save_trk from dipy.tracking import utils from dipy.tracking.local import (ThresholdTissueClassifier, LocalTracking) stopping_thr = 0.25 #0.25 pam = load_peaks(fpeaks) #ffa = dname + 'tensor_fa_nomask.nii.gz' fa, fa_affine = load_nifti(ffa) classifier = ThresholdTissueClassifier(fa, stopping_thr) # In[41]: # seeds seed_density = 1 seed_mask = fa > 0.4 #0.4 #TODO: check this parameter seeds = utils.seeds_from_mask(seed_mask, density=seed_density, affine=affine) # In[ ]: # In[42]:
csd_model = ConstrainedSphericalDeconvModel(gtab, None, sh_order=6) csd_fit = csd_model.fit(data, mask=white_matter) """ We use the fractional anisotropy (FA) of the DTI model to build a tissue classifier. """ import dipy.reconst.dti as dti from dipy.reconst.dti import fractional_anisotropy tensor_model = dti.TensorModel(gtab) tenfit = tensor_model.fit(data, mask=white_matter) FA = fractional_anisotropy(tenfit.evals) classifier = ThresholdTissueClassifier(FA, .2) """ The Fiber Orientation Distribution (FOD) of the CSD model estimates the distribution of small fiber bundles within each voxel. This distribution can be used for deterministic fiber tracking. As for probabilistic tracking, there are many ways to provide those distributions to the deterministic maximum direction getter. Here, the spherical harmonic representation of the FOD is used. """ from dipy.data import default_sphere from dipy.direction import DeterministicMaximumDirectionGetter from dipy.io.streamline import save_trk detmax_dg = DeterministicMaximumDirectionGetter.from_shcoeff( csd_fit.shm_coeff, max_angle=30., sphere=default_sphere)
seed_mask = labels == 2 white_matter = (labels == 1) | (labels == 2) seeds = utils.seeds_from_mask(seed_mask, density=1, affine=affine) csd_model = ConstrainedSphericalDeconvModel(gtab, None, sh_order=6) csd_fit = csd_model.fit(data, mask=white_matter) """ We use the GFA of the CSA model to build a tissue classifier. """ from dipy.reconst.shm import CsaOdfModel csa_model = CsaOdfModel(gtab, sh_order=6) gfa = csa_model.fit(data, mask=white_matter).gfa classifier = ThresholdTissueClassifier(gfa, .25) """ The Fiber Orientation Distribution (FOD) of the CSD model estimates the distribution of small fiber bundles within each voxel. We can use this distribution for probabilistic fiber tracking. One way to do this is to represent the FOD using a discrete sphere. This discrete FOD can be used by the ``ProbabilisticDirectionGetter`` as a PMF for sampling tracking directions. We need to clip the FOD to use it as a PMF because the latter cannot have negative values. Ideally, the FOD should be strictly positive, but because of noise and/or model failures sometimes it can have negative values. """ from dipy.direction import ProbabilisticDirectionGetter from dipy.data import small_sphere from dipy.io.trackvis import save_trk
def test_probabilistic_odf_weighted_tracker(): """This tests that the Probabalistic Direction Getter plays nice LocalTracking and produces reasonable streamlines in a simple example. """ sphere = HemiSphere.from_sphere(unit_octahedron) # A simple image with three possible configurations, a vertical tract, # a horizontal tract and a crossing pmf_lookup = np.array([[0., 0., 1.], [1., 0., 0.], [0., 1., 0.], [.6, .4, 0.]]) simple_image = np.array([[0, 1, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0], [0, 3, 2, 2, 2, 0], [0, 1, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0], ]) simple_image = simple_image[..., None] pmf = pmf_lookup[simple_image] seeds = [np.array([1., 1., 0.])] * 30 mask = (simple_image > 0).astype(float) tc = ThresholdTissueClassifier(mask, .5) dg = ProbabilisticDirectionGetter.from_pmf(pmf, 90, sphere, pmf_threshold=0.1) streamlines = LocalTracking(dg, tc, seeds, np.eye(4), 1.) expected = [np.array([[0., 1., 0.], [1., 1., 0.], [2., 1., 0.], [2., 2., 0.], [2., 3., 0.], [2., 4., 0.], [2., 5., 0.]]), np.array([[0., 1., 0.], [1., 1., 0.], [2., 1., 0.], [3., 1., 0.], [4., 1., 0.]])] def allclose(x, y): return x.shape == y.shape and np.allclose(x, y) path = [False, False] for sl in streamlines: if allclose(sl, expected[0]): path[0] = True elif allclose(sl, expected[1]): path[1] = True else: raise AssertionError() npt.assert_(all(path)) # The first path is not possible if 90 degree turns are excluded dg = ProbabilisticDirectionGetter.from_pmf(pmf, 80, sphere, pmf_threshold=0.1) streamlines = LocalTracking(dg, tc, seeds, np.eye(4), 1.) for sl in streamlines: npt.assert_(np.allclose(sl, expected[1])) # The first path is not possible if pmf_threshold > 0.4 dg = ProbabilisticDirectionGetter.from_pmf(pmf, 90, sphere, pmf_threshold=0.5) streamlines = LocalTracking(dg, tc, seeds, np.eye(4), 1.) for sl in streamlines: npt.assert_(np.allclose(sl, expected[1]))
# this creates a mask which zeros (?) out all tissue which doesn't have label 1 or 2 (TODO: what is 1 or 2?) white_matter = (labels == 1) | (labels == 2) from dipy.reconst.shm import CsaOdfModel from dipy.data import default_sphere from dipy.direction import peaks_from_model csa_model = CsaOdfModel(gtab, sh_order=6) csa_peaks = peaks_from_model(csa_model, data, default_sphere, relative_peak_threshold=.8, min_separation_angle=45, mask=white_matter) from dipy.tracking.local import ThresholdTissueClassifier classifier = ThresholdTissueClassifier(csa_peaks.gfa, .25) from dipy.tracking import utils from dipy.tracking.local import OptimizedLocalTracking seed_mask = labels == 2 seeds = utils.seeds_from_mask(seed_mask, density=[2, 2, 2], affine=affine) op_tracking = OptimizedLocalTracking(csa_peaks, classifier, seeds, affine, step_size=.5) """ import copy_reg def pickle_tissue_classifer(classifer_object): return (ThresholdTissueClassifier, (classifer_object, classifer_object.metric_map, classifer_object.threshold))
def dwi_dipy_run(dwi_dir, node_size, dir_path, conn_model, parc, atlas_select, network, wm_mask=None): import os import glob import re import nipype.interfaces.fsl as fsl from dipy.reconst.dti import TensorModel, quantize_evecs from dipy.reconst.csdeconv import ConstrainedSphericalDeconvModel, recursive_response from dipy.tracking.local import LocalTracking, ThresholdTissueClassifier from dipy.tracking import utils from dipy.direction import peaks_from_model from dipy.tracking.eudx import EuDX from dipy.data import get_sphere from dipy.core.gradients import gradient_table from dipy.io import read_bvals_bvecs def atoi(text): return int(text) if text.isdigit() else text def natural_keys(text): return [atoi(c) for c in re.split('(\d+)', text)] dwi_img = "%s%s" % (dwi_dir, '/dwi.nii.gz') nodif_brain_mask_path = "%s%s" % (dwi_dir, '/nodif_brain_mask.nii.gz') bvals = "%s%s" % (dwi_dir, '/bval') bvecs = "%s%s" % (dwi_dir, '/bvec') img = nib.load(dwi_img) data = img.get_data() # Loads mask and ensures it's a true binary mask img = nib.load(nodif_brain_mask_path) mask = img.get_data() mask = mask > 0 [bvals, bvecs] = read_bvals_bvecs(bvals, bvecs) gtab = gradient_table(bvals, bvecs) # Estimates some tensors model = TensorModel(gtab) ten = model.fit(data, mask) sphere = get_sphere('symmetric724') ind = quantize_evecs(ten.evecs, sphere.vertices) # Tractography if conn_model == 'csd': trac_mod = 'csd' else: conn_model = 'tensor' trac_mod = ten.fa affine = img.affine print('Tracking with tensor model...') if wm_mask is None: mask = nib.load(mask).get_data() mask[0, :, :] = False mask[:, 0, :] = False mask[:, :, 0] = False seeds = utils.seeds_from_mask(mask, density=2) else: wm_mask_data = nib.load(wm_mask).get_data() wm_mask_data[0, :, :] = False wm_mask_data[:, 0, :] = False wm_mask_data[:, :, 0] = False seeds = utils.seeds_from_mask(wm_mask_data, density=2) #seeds = random_seeds_from_mask(ten.fa > 0.3, seeds_count=num_total_samples) if conn_model == 'tensor': eu = EuDX(a=trac_mod, ind=ind, seeds=seeds, odf_vertices=sphere.vertices, a_low=0.05, step_sz=.5) tracks = [e for e in eu] elif conn_model == 'csd': print('Tracking with CSD model...') if wm_mask is None: response = recursive_response(gtab, data, mask=mask.astype('bool'), sh_order=8, peak_thr=0.01, init_fa=0.08, init_trace=0.0021, iter=8, convergence=0.001, parallel=True) else: response = recursive_response(gtab, data, mask=wm_mask_data.astype('bool'), sh_order=8, peak_thr=0.01, init_fa=0.08, init_trace=0.0021, iter=8, convergence=0.001, parallel=True) csd_model = ConstrainedSphericalDeconvModel(gtab, response) csd_peaks = peaks_from_model(model=csd_model, data=data, sphere=sphere, relative_peak_threshold=.5, min_separation_angle=25, parallel=True) tissue_classifier = ThresholdTissueClassifier(ten.fa, 0.1) streamline_generator = LocalTracking(csd_peaks, tissue_classifier, seeds, affine=affine, step_size=0.5) tracks = [e for e in streamline_generator] if parc is True: node_size = 'parc' if network: seeds_dir = "%s%s%s%s%s%s%s" % (dir_path, '/seeds_', network, '_', atlas_select, '_', str(node_size)) else: seeds_dir = "%s%s%s%s%s" % (dir_path, '/seeds_', atlas_select, '_', str(node_size)) seed_files = glob.glob("%s%s" % (seeds_dir, '/*diff.nii.gz')) seed_files.sort(key=natural_keys) # Binarize ROIs print('\nBinarizing seed masks...') j = 1 for i in seed_files: args = ' -bin ' out_file = "%s%s" % (i.split('.nii.gz')[0], '_bin.nii.gz') maths = fsl.ImageMaths(in_file=i, op_string=args, out_file=out_file) os.system(maths.cmdline) args = ' -mul ' + str(j) maths = fsl.ImageMaths(in_file=out_file, op_string=args, out_file=out_file) os.system(maths.cmdline) j = j + 1 # Create atlas from ROIs seed_files = glob.glob("%s%s" % (seeds_dir, '/*diff_bin.nii.gz')) seed_files.sort(key=natural_keys) print('\nMerging seed masks into single labels image...') label_sum = "%s%s" % (seeds_dir, '/all_rois.nii.gz') args = ' -add ' + i maths = fsl.ImageMaths(in_file=seed_files[0], op_string=args, out_file=label_sum) os.system(maths.cmdline) for i in seed_files: args = ' -add ' + i maths = fsl.ImageMaths(in_file=label_sum, op_string=args, out_file=label_sum) os.system(maths.cmdline) labels_im = nib.load(label_sum) labels_data = labels_im.get_data().astype('int') conn_matrix, grouping = utils.connectivity_matrix( tracks, labels_data, affine=affine, return_mapping=True, mapping_as_streamlines=True) conn_matrix[:3, :] = 0 conn_matrix[:, :3] = 0 return conn_matrix