def prep_tissues(nodif_B0_mask, gm_in_dwi, vent_csf_in_dwi, wm_in_dwi, tiss_class, cmc_step_size=0.2): try: import cPickle as pickle except ImportError: import _pickle as pickle from dipy.tracking.local import ActTissueClassifier, CmcTissueClassifier, BinaryTissueClassifier # Loads mask and ensures it's a true binary mask mask_img = nib.load(nodif_B0_mask) # Load tissue maps and prepare tissue classifier gm_mask = nib.load(gm_in_dwi) gm_mask_data = gm_mask.get_fdata() wm_mask = nib.load(wm_in_dwi) wm_mask_data = wm_mask.get_fdata() if tiss_class == 'act': vent_csf_in_dwi = nib.load(vent_csf_in_dwi) vent_csf_in_dwi_data = vent_csf_in_dwi.get_fdata() background = np.ones(mask_img.shape) background[(gm_mask_data + wm_mask_data + vent_csf_in_dwi_data) > 0] = 0 include_map = gm_mask_data include_map[background > 0] = 1 exclude_map = vent_csf_in_dwi_data tiss_classifier = ActTissueClassifier(include_map, exclude_map) elif tiss_class == 'bin': wm_in_dwi_data = nib.load(wm_in_dwi).get_fdata().astype('bool') tiss_classifier = BinaryTissueClassifier(wm_in_dwi_data) elif tiss_class == 'cmc': vent_csf_in_dwi = nib.load(vent_csf_in_dwi) vent_csf_in_dwi_data = vent_csf_in_dwi.get_fdata() voxel_size = np.average(wm_mask.get_header()['pixdim'][1:4]) tiss_classifier = CmcTissueClassifier.from_pve(wm_mask_data, gm_mask_data, vent_csf_in_dwi_data, step_size=cmc_step_size, average_voxel_size=voxel_size) else: raise ValueError("%s%s%s" % ('Error: tissuer classification method: ', tiss_class, 'not found')) return tiss_classifier
def test_binary_tissue_classifier(): """This tests that the binary tissue classifier returns expected tissue types. """ mask = np.random.random((4, 4, 4)) mask[mask < 0.4] = 0.0 btc_boolean = BinaryTissueClassifier(mask > 0) btc_float64 = BinaryTissueClassifier(mask) # test voxel center for ind in ndindex(mask.shape): pts = np.array(ind, dtype='float64') state_boolean = btc_boolean.check_point(pts) state_float64 = btc_float64.check_point(pts) if mask[ind] > 0: npt.assert_equal(state_boolean, TissueTypes.TRACKPOINT) npt.assert_equal(state_float64, TissueTypes.TRACKPOINT) else: npt.assert_equal(state_boolean, TissueTypes.ENDPOINT) npt.assert_equal(state_float64, TissueTypes.ENDPOINT) # test random points in voxel for ind in ndindex(mask.shape): for _ in range(50): pts = np.array(ind, dtype='float64') + np.random.random(3) - 0.5 state_boolean = btc_boolean.check_point(pts) state_float64 = btc_float64.check_point(pts) if mask[ind] > 0: npt.assert_equal(state_boolean, TissueTypes.TRACKPOINT) npt.assert_equal(state_float64, TissueTypes.TRACKPOINT) else: npt.assert_equal(state_boolean, TissueTypes.ENDPOINT) npt.assert_equal(state_float64, 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], [4, 0, 0]] for pts in outside_pts: pts = np.array(pts, dtype='float64') state_boolean = btc_boolean.check_point(pts) state_float64 = btc_float64.check_point(pts) npt.assert_equal(state_boolean, TissueTypes.OUTSIDEIMAGE) npt.assert_equal(state_float64, TissueTypes.OUTSIDEIMAGE)
def main(): parser = _build_arg_parser() args = parser.parse_args() for param in ['theta', 'curvature']: # Default was removed for consistency. if param not in args: setattr(args, param, None) assert_inputs_exist(parser, [args.sh_file, args.seed_file, args.mask_file]) assert_outputs_exists(parser, args, [args.output_file]) np.random.seed(args.seed) mask_img = nib.load(args.mask_file) mask_data = mask_img.get_data() seeds = random_seeds_from_mask( nib.load(args.seed_file).get_data(), seeds_count=args.nts if 'nts' in args else args.npv, seed_count_per_voxel='nts' not in args) # Tracking is performed in voxel space streamlines = LocalTracking(_get_direction_getter(args, mask_data), BinaryTissueClassifier(mask_data), seeds, np.eye(4), step_size=args.step_size, max_cross=1, maxlen=int(args.max_len / args.step_size) + 1, fixedstep=True, return_all=True) filtered_streamlines = (s for s in streamlines if args.min_len <= length(s) <= args.max_len) if args.compress_streamlines: filtered_streamlines = (compress_streamlines(s, args.tolerance_error) for s in filtered_streamlines) tractogram = LazyTractogram(lambda: filtered_streamlines, affine_to_rasmm=mask_img.affine) # Header with the affine/shape from mask image header = { Field.VOXEL_TO_RASMM: mask_img.affine.copy(), Field.VOXEL_SIZES: mask_img.header.get_zooms(), Field.DIMENSIONS: mask_img.shape, Field.VOXEL_ORDER: ''.join(aff2axcodes(mask_img.affine)) } # Use generator to save the streamlines on-the-fly nib.streamlines.save(tractogram, args.output_file, header=header)
def test_closest_peak_tracker(): """This tests that the Closest Peak 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.], [.5, .5, 0.]]) simple_image = np.array([[0, 1, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0], [2, 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.]), np.array([2., 4., 0.])] mask = (simple_image > 0).astype(float) tc = BinaryTissueClassifier(mask) dg = ClosestPeakDirectionGetter.from_pmf(pmf, 90, sphere, pmf_threshold=0.1) streamlines = Streamlines(LocalTracking(dg, tc, seeds, np.eye(4), 1.)) expected = [np.array([[0., 1., 0.], [1., 1., 0.], [2., 1., 0.], [3., 1., 0.], [4., 1., 0.]]), np.array([[2., 0., 0.], [2., 1., 0.], [2., 2., 0.], [2., 3., 0.], [2., 4., 0.]])] def allclose(x, y): return x.shape == y.shape and np.allclose(x, y) if not allclose(streamlines[0], expected[0]): raise AssertionError() if not allclose(streamlines[1], expected[1]): raise AssertionError()
def test_binary_tissue_classifier(): """This tests that the binary tissue classifier returns expected tissue types. """ mask = np.random.random((4, 4, 4)) mask[mask < 0.4] = 0.0 btc_boolean = BinaryTissueClassifier(mask > 0) btc_float64 = BinaryTissueClassifier(mask) # test voxel center for ind in ndindex(mask.shape): pts = np.array(ind, dtype='float64') state_boolean = btc_boolean.check_point(pts) state_float64 = btc_float64.check_point(pts) if mask[ind] > 0: npt.assert_equal(state_boolean, TissueTypes.TRACKPOINT) npt.assert_equal(state_float64, TissueTypes.TRACKPOINT) else: npt.assert_equal(state_boolean, TissueTypes.ENDPOINT) npt.assert_equal(state_float64, TissueTypes.ENDPOINT) # test random points in voxel for ind in ndindex(mask.shape): for _ in range(50): pts = np.array(ind, dtype='float64') + np.random.random(3) - 0.5 state_boolean = btc_boolean.check_point(pts) state_float64 = btc_float64.check_point(pts) if mask[ind] > 0: npt.assert_equal(state_boolean, TissueTypes.TRACKPOINT) npt.assert_equal(state_float64, TissueTypes.TRACKPOINT) else: npt.assert_equal(state_boolean, TissueTypes.ENDPOINT) npt.assert_equal(state_float64, 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_boolean = btc_boolean.check_point(pts) state_float64 = btc_float64.check_point(pts) npt.assert_equal(state_boolean, TissueTypes.OUTSIDEIMAGE) npt.assert_equal(state_float64, TissueTypes.OUTSIDEIMAGE)
def tracking_maxodf(dir_src, dir_out, verbose=False): wm_name = 'wm_mask_' + par_b_tag + '_' + par_dim_tag + '.nii.gz' wm_mask, affine = load_nifti(pjoin(dir_src, wm_name), verbose) sh_name = 'sh_' + par_b_tag + '_' + par_dim_tag + '.nii.gz' sh, _ = load_nifti(pjoin(dir_src, sh_name), verbose) sphere = get_sphere('symmetric724') classifier = ThresholdTissueClassifier(wm_mask.astype('f8'), .5) classifier = BinaryTissueClassifier(wm_mask) max_dg = DeterministicMaximumDirectionGetter.from_shcoeff(sh, max_angle=par_trk_max_angle, sphere=sphere) seeds = utils.seeds_from_mask(wm_mask, density=2, affine=affine) streamlines = LocalTracking(max_dg, classifier, seeds, affine, step_size=par_trk_step_size) streamlines = list(streamlines) trk_name = 'tractogram_' + par_b_tag + '_' + par_dim_tag + '_' + par_trk_odf_tag + '.trk' save_trk(pjoin(dir_out, trk_name), streamlines, affine, wm_mask.shape)
def _core_run(self, stopping_path, use_binary_mask, stopping_thr, seeding_path, seed_density, step_size, direction_getter, out_tract, save_seeds): stop, affine = load_nifti(stopping_path) if use_binary_mask: classifier = BinaryTissueClassifier(stop > stopping_thr) else: classifier = ThresholdTissueClassifier(stop, stopping_thr) logging.info('classifier done') seed_mask, _ = load_nifti(seeding_path) seeds = \ utils.seeds_from_mask( seed_mask, density=[seed_density, seed_density, seed_density], affine=affine) logging.info('seeds done') tracking_result = LocalTracking(direction_getter, classifier, seeds, affine, step_size=step_size, save_seeds=save_seeds) logging.info('LocalTracking initiated') if save_seeds: streamlines, seeds = zip(*tracking_result) tractogram = Tractogram(streamlines, affine_to_rasmm=np.eye(4)) tractogram.data_per_streamline['seeds'] = seeds else: tractogram = Tractogram(tracking_result, affine_to_rasmm=np.eye(4)) save(tractogram, out_tract) logging.info('Saved {0}'.format(out_tract))
def test_bootstap_peak_tracker(): """This tests that the Bootstrat Peak Direction Getter plays nice LocalTracking and produces reasonable streamlines in a simple example. """ sphere = get_sphere('repulsion100') # A simple image with three possible configurations, a vertical tract, # a horizontal tract and a crossing simple_image = np.array([ [0, 1, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0], [2, 3, 2, 2, 2, 0], [0, 1, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0], ]) simple_image = simple_image[..., None] bvecs = sphere.vertices bvals = np.ones(len(bvecs)) * 1000 bvecs = np.insert(bvecs, 0, np.array([0, 0, 0]), axis=0) bvals = np.insert(bvals, 0, 0) gtab = gradient_table(bvals, bvecs) angles = [(90, 90), (90, 0)] fracs = [50, 50] mevals = np.array([[1.5, 0.4, 0.4], [1.5, 0.4, 0.4]]) * 1e-3 mevecs = [ np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]]), np.array([[0, 1, 0], [1, 0, 0], [0, 0, 1]]) ] voxel1 = single_tensor(gtab, 1, mevals[0], mevecs[0], snr=None) voxel2 = single_tensor(gtab, 1, mevals[0], mevecs[1], snr=None) voxel3, _ = multi_tensor(gtab, mevals, fractions=fracs, angles=angles, snr=None) data = np.tile(voxel3, [5, 6, 1, 1]) data[simple_image == 1] = voxel1 data[simple_image == 2] = voxel2 response = (np.array(mevals[1]), 1) csd_model = ConstrainedSphericalDeconvModel(gtab, response, sh_order=6) seeds = [np.array([0., 1., 0.]), np.array([2., 4., 0.])] tc = BinaryTissueClassifier((simple_image > 0).astype(float)) sphere = HemiSphere.from_sphere(get_sphere('symmetric724')) boot_dg = BootDirectionGetter.from_data(data, csd_model, 60, sphere=sphere) streamlines_generator = LocalTracking(boot_dg, tc, seeds, np.eye(4), 1.) streamlines = Streamlines(streamlines_generator) expected = [ np.array([[0., 1., 0.], [1., 1., 0.], [2., 1., 0.], [3., 1., 0.], [4., 1., 0.]]), np.array([ [2., 4., 0.], [2., 3., 0.], [2., 2., 0.], [2., 1., 0.], [2., 0., 0.], ]) ] def allclose(x, y): return x.shape == y.shape and np.allclose(x, y, atol=0.5) if not allclose(streamlines[0], expected[0]): raise AssertionError() if not allclose(streamlines[1], expected[1]): raise AssertionError()
def test_particle_filtering_tractography(): """This tests that the ParticleFilteringTracking produces more streamlines connecting the gray matter than LocalTracking. """ sphere = get_sphere('repulsion100') step_size = 0.2 # Simple tissue masks simple_wm = np.array([[0, 0, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0], [0, 1, 1, 1, 0, 0], [0, 1, 1, 1, 0, 0], [0, 0, 0, 0, 0, 0]]) simple_wm = np.dstack([ np.zeros(simple_wm.shape), simple_wm, simple_wm, simple_wm, np.zeros(simple_wm.shape) ]) simple_gm = np.array([[1, 1, 0, 0, 0, 0], [1, 1, 0, 0, 0, 0], [0, 1, 0, 0, 1, 0], [0, 0, 0, 0, 1, 0], [0, 0, 0, 0, 0, 0]]) simple_gm = np.dstack([ np.zeros(simple_gm.shape), simple_gm, simple_gm, simple_gm, np.zeros(simple_gm.shape) ]) simple_csf = np.ones(simple_wm.shape) - simple_wm - simple_gm tc = ActTissueClassifier.from_pve(simple_wm, simple_gm, simple_csf) seeds = seeds_from_mask(simple_wm, density=2) # Random pmf in every voxel shape_img = list(simple_wm.shape) shape_img.extend([sphere.vertices.shape[0]]) np.random.seed(0) # Random number generator initialization pmf = np.random.random(shape_img) # Test that PFT recover equal or more streamlines than localTracking dg = ProbabilisticDirectionGetter.from_pmf(pmf, 60, sphere) local_streamlines_generator = LocalTracking(dg, tc, seeds, np.eye(4), step_size, max_cross=1, return_all=False) local_streamlines = Streamlines(local_streamlines_generator) pft_streamlines_generator = ParticleFilteringTracking( dg, tc, seeds, np.eye(4), step_size, max_cross=1, return_all=False, pft_back_tracking_dist=1, pft_front_tracking_dist=0.5) pft_streamlines = Streamlines(pft_streamlines_generator) npt.assert_(np.array([len(pft_streamlines) > 0])) npt.assert_(np.array([len(pft_streamlines) >= len(local_streamlines)])) # Test that all points are equally spaced for l in [1, 2, 5, 10, 100]: pft_streamlines = ParticleFilteringTracking(dg, tc, seeds, np.eye(4), step_size, max_cross=1, return_all=True, maxlen=l) for s in pft_streamlines: for i in range(len(s) - 1): npt.assert_almost_equal(np.linalg.norm(s[i] - s[i + 1]), step_size) # Test that all points are within the image volume seeds = seeds_from_mask(np.ones(simple_wm.shape), density=1) pft_streamlines_generator = ParticleFilteringTracking(dg, tc, seeds, np.eye(4), step_size, max_cross=1, return_all=True) pft_streamlines = Streamlines(pft_streamlines_generator) for s in pft_streamlines: npt.assert_(np.all((s + 0.5).astype(int) >= 0)) npt.assert_(np.all((s + 0.5).astype(int) < simple_wm.shape)) # Test that the number of streamline return with return_all=True equal the # number of seeds places npt.assert_(np.array([len(pft_streamlines) == len(seeds)])) # Test non WM seed position seeds = [[0, 5, 4], [0, 0, 1], [50, 50, 50]] pft_streamlines_generator = ParticleFilteringTracking(dg, tc, seeds, np.eye(4), step_size, max_cross=1, return_all=True) pft_streamlines = Streamlines(pft_streamlines_generator) npt.assert_equal(len(pft_streamlines[0]), 3) # INVALIDPOINT npt.assert_equal(len(pft_streamlines[1]), 3) # ENDPOINT npt.assert_equal(len(pft_streamlines[2]), 1) # OUTSIDEIMAGE # Test with wrong tissueclassifier type tc_bin = BinaryTissueClassifier(simple_wm) npt.assert_raises( ValueError, lambda: ParticleFilteringTracking(dg, tc_bin, seeds, np.eye(4), step_size)) # Test with invalid back/front tracking distances npt.assert_raises( ValueError, lambda: ParticleFilteringTracking(dg, tc, seeds, np.eye(4), step_size, pft_back_tracking_dist=0, pft_front_tracking_dist=0)) npt.assert_raises( ValueError, lambda: ParticleFilteringTracking( dg, tc, seeds, np.eye(4), step_size, pft_back_tracking_dist=-1)) npt.assert_raises( ValueError, lambda: ParticleFilteringTracking(dg, tc, seeds, np.eye(4), step_size, pft_back_tracking_dist=0, pft_front_tracking_dist=-2)) # Test with invalid affine shape npt.assert_raises( ValueError, lambda: ParticleFilteringTracking(dg, tc, seeds, np.eye(3), step_size)) # Test with invalid maxlen npt.assert_raises( ValueError, lambda: ParticleFilteringTracking( dg, tc, seeds, np.eye(4), step_size, maxlen=0)) npt.assert_raises( ValueError, lambda: ParticleFilteringTracking( dg, tc, seeds, np.eye(4), step_size, maxlen=-1)) # Test with invalid particle count npt.assert_raises( ValueError, lambda: ParticleFilteringTracking( dg, tc, seeds, np.eye(4), step_size, particle_count=0)) npt.assert_raises( ValueError, lambda: ParticleFilteringTracking( dg, tc, seeds, np.eye(4), step_size, particle_count=-1)) # Test reproducibility tracking_1 = Streamlines( ParticleFilteringTracking(dg, tc, seeds, np.eye(4), step_size, random_seed=0)).data tracking_2 = Streamlines( ParticleFilteringTracking(dg, tc, seeds, np.eye(4), step_size, random_seed=0)).data npt.assert_equal(tracking_1, tracking_2)
if seeds[i][j]<0.: seeds[i][j]=-seeds[i][j] et3 = time.time() - st3 print 'seeding transformation finished, the total seeds are {}, running time is {}'.format(seeds.shape[0], et3) print 'generating streamlines begins' st4 = time.time() fod_coeff = csd_peaks.shm_coeff prob_dg = ProbabilisticDirectionGetter.from_shcoeff(fod_coeff, max_angle=70.,relative_peak_threshold=0.1, sphere=default_sphere) del data, img, labels, labels_img, csd_peaks, csd_model gc.collect() print 'data, img, labels, labels_img, csd_peaks, csd_model delete to save memory' classifier = BinaryTissueClassifier(mask) streamline_generator = LocalTracking(prob_dg, classifier, seeds, affine, step_size=.5) affine = streamline_generator.affine streamlines = Streamlines(streamline_generator) et4 = time.time() - st4 #lengths = [length(sl).astype(np.int) for sl in streamlines] #print 'generating streamlines finished, the length is {}~{}, running time is {}'.format(np.min(lengths), np.max(lengths), et4) del bm, mask, fod_coeff, prob_dg, classifier #, lengths gc.collect() print 'bm, mask, fod_coeff, prob_dg, classifier, lengths delete to save memory' #Cut streamlines #streamlines = [sl for sl in streamlines if length(sl).astype(np.int)>3] #print 'cutting short streamlines finished'
def execution(self, context): sh_coeff_vol = aims.read(self.sh_coefficients.fullPath()) header = sh_coeff_vol.header() #transformation from Aims LPI mm space to RAS mm (reference space) aims_mm_to_ras_mm = np.array(header['transformations'][0]).reshape((4, 4)) voxel_size = np.array(header['voxel_size']) if len(voxel_size) == 4: voxel_size = voxel_size[:-1] scaling = np.concatenate((voxel_size, np.ones(1))) #context.write(voxel_size.shape) scaling_mat = np.diag(scaling) #context.write(scaling_mat.shape, aims_mm_to_ras_mm.shape ) aims_voxel_to_ras_mm = np.dot(aims_mm_to_ras_mm, scaling_mat) affine_tracking = np.eye(4) sh = np.array(sh_coeff_vol, copy=True) sh = sh.astype(np.float64) vol_shape = sh.shape[:-1] if self.sphere is not None: sphere = read_sphere(self.sphere.fullPath()) else: context.write( 'No Projection Sphere provided. Default dipy sphere symmetric 362 is used' ) sphere = get_sphere() dg = DirectionGetter[self.type].from_shcoeff( sh, self.max_angle, sphere, basis_type=None, relative_peak_threshold=self.relative_peak_threshold, min_separation_angle=self.min_separation_angle) #Handling seeds in both deterministic and probabilistic framework s = np.loadtxt(self.seeds.fullPath()) s = s.astype(np.float32) i = np.arange(self.nb_samples) if self.nb_samples <= 1: seeds = s else: seeds = np.zeros((self.nb_samples, ) + s.shape) seeds[i] = s seeds = seeds.reshape((-1, 3)) #put seeds in voxel space context.write(seeds[0]) seeds = nib.affines.apply_affine(np.linalg.inv(scaling_mat), seeds) #building classifier context.write(seeds[0]) if self.constraint == 'Binary': mask_vol = aims.read(self.mask.fullPath()) mask = np.asarray(mask_vol)[..., 0] mask = mask.astype(bool) classifier = BinaryTissueClassifier(mask) elif self.constraint == 'Threshold': scal_vol = aims.read(self.scalar_volume.fullPath()) scal = np.asarray(scal_vol)[..., 0] scal = scal.astype(np.float32) classifier = ThresholdTissueClassifier(scal, self.threshold) else: csf_vol = aims.read(self.csf_pve.fullPath()) grey_vol = aims.read(self.gm_pve.fullPath()) white_vol = aims.read(self.wm_pve.fullPath()) csf = np.array(csf_vol) csf = csf[..., 0] gm = np.array(grey_vol) gm = gm[..., 0] wm = np.array(white_vol) wm = wm[..., 0] #rethreshold volumes due to interpolation (eg values >1) total = (csf + gm + wm).copy() csf[total <= 0] = 0 gm[total <= 0] = 0 wm[total <= 0] = 0 csf[total != 0] = (csf[total != 0]) / (total[total != 0]) wm[total != 0] = (wm[total != 0]) / (total[total != 0]) gm[total != 0] = gm[total != 0] / (total[total != 0]) if self.constraint == 'ACT': classifier = ActTissueClassifier.from_pve(wm_map=wm, gm_map=gm, csf_map=csf) elif self.constraint == 'CMC': classifier = CmcTissueClassifier.from_pve(wm_map=wm, gm_map=gm, csf_map=csf) #Tracking is made in the Aims LPO space (solve shear verification problem, does not work for anisotropic voxels) streamlines_generator = LocalTracking(dg, classifier, seeds, affine_tracking, step_size=self.step_size, max_cross=self.crossing_max, maxlen=self.nb_iter_max, fixedstep=np.float32( self.fixed_step), return_all=self.return_all) #Store Fibers directly in LPI orientation with appropriate transformation save_trk(self.streamlines.fullPath(), streamlines_generator, affine=aims_voxel_to_ras_mm, vox_size=voxel_size, shape=vol_shape) transformManager = getTransformationManager() transformManager.copyReferential(self.sh_coefficients, self.streamlines)
def main(): parser = _build_arg_parser() args = parser.parse_args() if args.isVerbose: logging.basicConfig(level=logging.DEBUG) assert_inputs_exist(parser, [args.sh_file, args.seed_file, args.mask_file]) assert_outputs_exist(parser, args, [args.output_file]) if not nib.streamlines.is_supported(args.output_file): parser.error('Invalid output streamline file format (must be trk or ' + 'tck): {0}'.format(args.output_file)) if not args.min_length > 0: parser.error('minL must be > 0, {}mm was provided.'.format( args.min_length)) if args.max_length < args.min_length: parser.error( 'maxL must be > than minL, (minL={}mm, maxL={}mm).'.format( args.min_length, args.max_length)) if args.compress: if args.compress < 0.001 or args.compress > 1: logging.warning( 'You are using an error rate of {}.\nWe recommend setting it ' 'between 0.001 and 1.\n0.001 will do almost nothing to the ' 'tracts while 1 will higly compress/linearize the tracts'. format(args.compress)) if args.npv and args.npv <= 0: parser.error('Number of seeds per voxel must be > 0.') if args.nt and args.nt <= 0: parser.error('Total number of seeds must be > 0.') mask_img = nib.load(args.mask_file) mask_data = mask_img.get_data() # Make sure the mask is isotropic. Else, the strategy used # when providing information to dipy (i.e. working as if in voxel space) # will not yield correct results. fodf_sh_img = nib.load(args.sh_file) if not np.allclose(np.mean(fodf_sh_img.header.get_zooms()[:3]), fodf_sh_img.header.get_zooms()[0], atol=1.e-3): parser.error( 'SH file is not isotropic. Tracking cannot be ran robustly.') if args.npv: nb_seeds = args.npv seed_per_vox = True elif args.nt: nb_seeds = args.nt seed_per_vox = False else: nb_seeds = 1 seed_per_vox = True voxel_size = fodf_sh_img.header.get_zooms()[0] vox_step_size = args.step_size / voxel_size seed_img = nib.load(args.seed_file) seeds = track_utils.random_seeds_from_mask( seed_img.get_data(), seeds_count=nb_seeds, seed_count_per_voxel=seed_per_vox, random_seed=args.seed) # Tracking is performed in voxel space max_steps = int(args.max_length / args.step_size) + 1 streamlines = LocalTracking(_get_direction_getter(args, mask_data), BinaryTissueClassifier(mask_data), seeds, np.eye(4), step_size=vox_step_size, max_cross=1, maxlen=max_steps, fixedstep=True, return_all=True, random_seed=args.seed) scaled_min_length = args.min_length / voxel_size scaled_max_length = args.max_length / voxel_size filtered_streamlines = ( s for s in streamlines if scaled_min_length <= length(s) <= scaled_max_length) if args.compress: filtered_streamlines = (compress_streamlines(s, args.compress) for s in filtered_streamlines) tractogram = LazyTractogram(lambda: filtered_streamlines, affine_to_rasmm=seed_img.affine) filetype = nib.streamlines.detect_format(args.output_file) header = create_header_from_anat(seed_img, base_filetype=filetype) # Use generator to save the streamlines on-the-fly nib.streamlines.save(tractogram, args.output_file, header=header)
csd_peaks = peaks_from_model(csd_model, data, sphere=peaks.default_sphere, relative_peak_threshold=0.5, min_separation_angle=60, mask=mask, return_odf=True, return_sh=False, parallel=True, nbr_processes=multiprocessing.cpu_count()) duration2 = time() - t2 print(runno + ' CSD duration %.3f' % (duration2, )) #mask and classifier seeds = utils.seeds_from_mask(mask, density=1, affine=np.eye(4)) classifier = BinaryTissueClassifier(bm) #local tracking streamlines_generator = LocalTracking(csd_peaks, classifier, seeds, affine=np.eye(4), step_size=.5) # save a smaller part by only keeping one in 10 streamlines t3 = time() sg_small = lambda: (s for i, s in enumerate(streamlines_generator) if i % 10 == 0) save_trk_heavy_duty(outpath + runno + "_bmCSD_detr_small60odf.trk", streamlines=sg_small, affine=affine, shape=mask.shape, vox_size=vox_size)
csamodel = shm.CsaOdfModel(gtab, 6) csapeaks = peaks.peaks_from_model(model=csamodel, data=data, sphere=peaks.default_sphere, relative_peak_threshold=.8, min_separation_angle=45, mask=white_matter) """ Now we can use EuDX to track all of the white matter. To keep things reasonably fast we use ``density=1`` which will result in 1 seeds per voxel. The tissue classifier, determining when the tracking stops, is set to stop when the tracking exit the white matter. """ seeds = utils.seeds_from_mask(white_matter, density=1) tissue_classifier = BinaryTissueClassifier(white_matter) affine = np.eye(4) streamline_generator = LocalTracking(csapeaks, tissue_classifier, seeds, affine=affine, step_size=0.5) streamlines = Streamlines(streamline_generator) """ The first of the tracking utilities we'll cover here is ``target``. This function takes a set of streamlines and a region of interest (ROI) and returns only those streamlines that pass though the ROI. The ROI should be an array such that the voxels that belong to the ROI are ``True`` and all other voxels are ``False`` (this type of binary array is sometimes called a mask). This function can also exclude all the streamlines that pass though an ROI by
def prep_tissues(B0_mask, gm_in_dwi, vent_csf_in_dwi, wm_in_dwi, tiss_class, cmc_step_size=0.2): ''' Estimate a tissue classifier for tractography. Parameters ---------- B0_mask : str File path to B0 brain mask. gm_in_dwi : str File path to grey-matter tissue segmentation Nifti1Image. vent_csf_in_dwi : str File path to ventricular CSF tissue segmentation Nifti1Image. wm_in_dwi : str File path to white-matter tissue segmentation Nifti1Image. tiss_class : str Tissue classification method. cmc_step_size : float Step size from CMC tissue classification method. Returns ------- tiss_classifier : obj Tissue classifier object. ''' try: import cPickle as pickle except ImportError: import _pickle as pickle from dipy.tracking.local import ActTissueClassifier, CmcTissueClassifier, BinaryTissueClassifier # Loads mask and ensures it's a true binary mask mask_img = nib.load(B0_mask) # Load tissue maps and prepare tissue classifier gm_mask = nib.load(gm_in_dwi) gm_mask_data = gm_mask.get_fdata() wm_mask = nib.load(wm_in_dwi) wm_mask_data = wm_mask.get_fdata() if tiss_class == 'act': vent_csf_in_dwi = nib.load(vent_csf_in_dwi) vent_csf_in_dwi_data = vent_csf_in_dwi.get_fdata() background = np.ones(mask_img.shape) background[(gm_mask_data + wm_mask_data + vent_csf_in_dwi_data) > 0] = 0 include_map = gm_mask_data include_map[background > 0] = 1 exclude_map = vent_csf_in_dwi_data tiss_classifier = ActTissueClassifier(include_map, exclude_map) elif tiss_class == 'bin': wm_in_dwi_data = nib.load(wm_in_dwi).get_fdata().astype('bool') tiss_classifier = BinaryTissueClassifier(wm_in_dwi_data) elif tiss_class == 'cmc': vent_csf_in_dwi = nib.load(vent_csf_in_dwi) vent_csf_in_dwi_data = vent_csf_in_dwi.get_fdata() voxel_size = np.average(wm_mask.get_header()['pixdim'][1:4]) tiss_classifier = CmcTissueClassifier.from_pve( wm_mask_data, gm_mask_data, vent_csf_in_dwi_data, step_size=cmc_step_size, average_voxel_size=voxel_size) else: B0_mask_data = nib.load(B0_mask).get_fdata().astype('bool') tiss_classifier = BinaryTissueClassifier(B0_mask_data) return tiss_classifier
def test_affine_transformations(): """This tests that the input affine is properly handled by 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, 0, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0], [0, 3, 2, 2, 2, 0], [0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], ]) simple_image = simple_image[..., None] pmf = pmf_lookup[simple_image] seeds = [np.array([1., 1., 0.]), np.array([2., 4., 0.])] expected = [ np.array([[1., 1., 0.], [2., 1., 0.], [3., 1., 0.]]), np.array([[2., 1., 0.], [2., 2., 0.], [2., 3., 0.], [2., 4., 0.]]) ] mask = (simple_image > 0).astype(float) tc = BinaryTissueClassifier(mask) dg = DeterministicMaximumDirectionGetter.from_pmf(pmf, 60, sphere, pmf_threshold=0.1) # TST- bad affine wrong shape bad_affine = np.eye(3) npt.assert_raises(ValueError, LocalTracking, dg, tc, seeds, bad_affine, 1.) # TST - bad affine with shearing bad_affine = np.eye(4) bad_affine[0, 1] = 1. npt.assert_raises(ValueError, LocalTracking, dg, tc, seeds, bad_affine, 1.) # TST - identity a0 = np.eye(4) # TST - affines with positive/negative offsets a1 = np.eye(4) a1[:3, 3] = [1, 2, 3] a2 = np.eye(4) a2[:3, 3] = [-2, 0, -1] # TST - affine with scaling a3 = np.eye(4) a3[0, 0] = a3[1, 1] = a3[2, 2] = 8 # TST - affine with axes inverting (negative value) a4 = np.eye(4) a4[1, 1] = a4[2, 2] = -1 # TST - combined affines a5 = a1 + a2 + a3 a5[3, 3] = 1 # TST - in vivo affine example # Sometimes data have affines with tiny shear components. # For example, the small_101D data-set has some of that: fdata, _, _ = get_fnames('small_101D') a6 = nib.load(fdata).affine for affine in [a0, a1, a2, a3, a4, a5, a6]: lin = affine[:3, :3] offset = affine[:3, 3] seeds_trans = [np.dot(lin, s) + offset for s in seeds] # We compute the voxel size to adjust the step size to one voxel voxel_size = np.mean(np.sqrt(np.dot(lin, lin).diagonal())) streamlines = LocalTracking(direction_getter=dg, tissue_classifier=tc, seeds=seeds_trans, affine=affine, step_size=voxel_size, return_all=True) # We apply the inverse affine transformation to the generated # streamlines. It should be equals to the expected streamlines # (generated with the identity affine matrix). affine_inv = np.linalg.inv(affine) lin = affine_inv[:3, :3] offset = affine_inv[:3, 3] streamlines_inv = [] for line in streamlines: streamlines_inv.append([np.dot(pts, lin) + offset for pts in line]) npt.assert_equal(len(streamlines_inv[0]), len(expected[0])) npt.assert_(np.allclose(streamlines_inv[0], expected[0], atol=0.3)) npt.assert_equal(len(streamlines_inv[1]), len(expected[1])) npt.assert_(np.allclose(streamlines_inv[1], expected[1], atol=0.3))
**Parameters** - mask: numpy array [:, :, :] **Stopping criterion** - 'ENDPOINT': mask = 0 - 'OUTSIDEIMAGE': tracking point outside of mask - 'TRACKPOINT': no direction is available - 'INVALIDPOINT': N/A """ from dipy.tracking.local import BinaryTissueClassifier binary_classifier = BinaryTissueClassifier(white_matter == 1) fig = plt.figure() plt.xticks([]) plt.yticks([]) fig.tight_layout() plt.imshow(white_matter[:, :, data.shape[2] // 2].T, cmap='gray', origin='lower', interpolation='nearest') fig.savefig('white_matter_mask.png') """ .. figure:: white_matter_mask.png :align: center **White matter binary mask.**
nbr_processes=4) duration2 = time() - t2 print(duration2)\ #wenlin make this change-adress name to each animal # print('CSA duration %.3f' % (duration2,)) print(runno + ' CSA duration %.3f' % (duration2, )) t3 = time() # from dipy.tracking.local import ThresholdTissueClassifier from dipy.tracking.local import BinaryTissueClassifier # Wenlin Make this change # classifier = ThresholdTissueClassifier(csa_peaks.gfa, .25) classifier = BinaryTissueClassifier(bm) # Wenlin Make this change from dipy.tracking import utils # generates about 2 seeds per voxel # seeds = utils.random_seeds_from_mask(fa > .2, seeds_count=2, # affine=np.eye(4)) # generates about 2 million streamlines #seeds = utils.seeds_from_mask(fa > .2, density=1, # affine=np.eye(4)) seeds = utils.seeds_from_mask(mask, density=1, affine=np.eye(4)) # Wenlin make this change streamlines_generator = LocalTracking(csa_peaks,