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_cmc_tissue_classifier(): """This tests that the cmc tissue classifier returns expected tissue types. """ gm = np.array([[[1, 1], [0, 0], [0, 0]]]) wm = np.array([[[0, 0], [1, 1], [0, 0]]]) csf = np.array([[[0, 0], [0, 0], [1, 1]]]) include_map = gm exclude_map = csf cmc_tc = CmcTissueClassifier(include_map=include_map, exclude_map=exclude_map, step_size=1, average_voxel_size=1) cmc_tc_from_pve = CmcTissueClassifier.from_pve(wm_map=wm, gm_map=gm, csf_map=csf, step_size=1, average_voxel_size=1) # Test constructors for idx in np.ndindex(wm.shape): idx = np.asarray(idx, dtype="float64") npt.assert_almost_equal(cmc_tc.get_include(idx), cmc_tc_from_pve.get_include(idx)) npt.assert_almost_equal(cmc_tc.get_exclude(idx), cmc_tc_from_pve.get_exclude(idx)) # Test voxel center for ind in ndindex(wm.shape): pts = np.array(ind, dtype='float64') state = cmc_tc.check_point(pts) if csf[ind] == 1: npt.assert_equal(state, TissueTypes.INVALIDPOINT) elif gm[ind] == 1: npt.assert_equal(state, TissueTypes.ENDPOINT) else: npt.assert_equal(state, TissueTypes.TRACKPOINT) # 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') npt.assert_equal(cmc_tc.check_point(pts), TissueTypes.OUTSIDEIMAGE) npt.assert_equal(cmc_tc.get_exclude(pts), 0) npt.assert_equal(cmc_tc.get_include(pts), 0)
def test_cmc_tissue_classifier(): """This tests that the cmc tissue classifier returns expected tissue types. """ gm = np.array([[[1, 1], [0, 0], [0, 0]]]) wm = np.array([[[0, 0], [1, 1], [0, 0]]]) csf = np.array([[[0, 0], [0, 0], [1, 1]]]) include_map = gm exclude_map = csf cmc_tc = CmcTissueClassifier(include_map=include_map, exclude_map=exclude_map, step_size=1, average_voxel_size=1) cmc_tc_from_pve = CmcTissueClassifier.from_pve(wm_map=wm, gm_map=gm, csf_map=csf, step_size=1, average_voxel_size=1) # Test contructors for idx in np.ndindex(wm.shape): idx = np.asarray(idx, dtype="float64") npt.assert_almost_equal(cmc_tc.get_include(idx), cmc_tc_from_pve.get_include(idx)) npt.assert_almost_equal(cmc_tc.get_exclude(idx), cmc_tc_from_pve.get_exclude(idx)) # Test voxel center for ind in ndindex(wm.shape): pts = np.array(ind, dtype='float64') state = cmc_tc.check_point(pts) if csf[ind] == 1: npt.assert_equal(state, TissueTypes.INVALIDPOINT) elif gm[ind] == 1: npt.assert_equal(state, TissueTypes.ENDPOINT) else: npt.assert_equal(state, TissueTypes.TRACKPOINT) # 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') npt.assert_equal(cmc_tc.check_point(pts), TissueTypes.OUTSIDEIMAGE) npt.assert_equal(cmc_tc.get_exclude(pts), 0) npt.assert_equal(cmc_tc.get_include(pts), 0)
Both tissue classifiers use a trilinear interpolation at the tracking position. CMC tissue classifier uses a probability derived from the PVE maps to determine if the streamline reaches a 'valid' or 'invalid' region. ACT uses a fixed threshold on the PVE maps. Both tissue classifiers can be used in conjunction with PFT. In this example, we used CMC. """ from dipy.tracking.local import CmcTissueClassifier from dipy.tracking.streamline import Streamlines voxel_size = np.average(img_pve_wm.get_header()['pixdim'][1:4]) step_size = 0.2 cmc_classifier = CmcTissueClassifier.from_pve(img_pve_wm.get_data(), img_pve_gm.get_data(), img_pve_csf.get_data(), step_size=step_size, average_voxel_size=voxel_size) # seeds are place in voxel of the corpus callosum containing only white matter seed_mask = labels == 2 seed_mask[img_pve_wm.get_data() < 0.5] = 0 seeds = utils.seeds_from_mask(seed_mask, density=2, affine=affine) # Particle Filtering Tractography pft_streamline_generator = ParticleFilteringTracking(dg, cmc_classifier, seeds, affine, max_cross=1, step_size=step_size,
def run(self, pam_files, wm_files, gm_files, csf_files, seeding_files, step_size=0.2, seed_density=1, pmf_threshold=0.1, max_angle=20., pft_back=2, pft_front=1, pft_count=15, out_dir='', out_tractogram='tractogram.trk', save_seeds=False): """Workflow for Particle Filtering Tracking. This workflow use a saved peaks and metrics (PAM) file as input. Parameters ---------- pam_files : string Path to the peaks and metrics files. This path may contain wildcards to use multiple masks at once. wm_files : string Path to white matter partial volume estimate for tracking (CMC). gm_files : string Path to grey matter partial volume estimate for tracking (CMC). csf_files : string Path to cerebrospinal fluid partial volume estimate for tracking (CMC). seeding_files : string A binary image showing where we need to seed for tracking. step_size : float, optional Step size used for tracking (default 0.2mm). seed_density : int, optional Number of seeds per dimension inside voxel (default 1). For example, seed_density of 2 means 8 regularly distributed points in the voxel. And seed density of 1 means 1 point at the center of the voxel. pmf_threshold : float, optional Threshold for ODF functions (default 0.1). max_angle : float, optional Maximum angle between streamline segments (range [0, 90], default 20). pft_back : float, optional Distance in mm to back track before starting the particle filtering tractography (defaul 2mm). The total particle filtering tractography distance is equal to back_tracking_dist + front_tracking_dist. pft_front : float, optional Distance in mm to run the particle filtering tractography after the the back track distance (default 1mm). The total particle filtering tractography distance is equal to back_tracking_dist + front_tracking_dist. pft_count : int, optional Number of particles to use in the particle filter (default 15). out_dir : string, optional Output directory (default input file directory) out_tractogram : string, optional Name of the tractogram file to be saved (default 'tractogram.trk') save_seeds : bool, optional If true, save the seeds associated to their streamline in the 'data_per_streamline' Tractogram dictionary using 'seeds' as the key References ---------- Girard, G., Whittingstall, K., Deriche, R., & Descoteaux, M. Towards quantitative connectivity analysis: reducing tractography biases. NeuroImage, 98, 266-278, 2014. """ io_it = self.get_io_iterator() for pams_path, wm_path, gm_path, csf_path, seeding_path, out_tract \ in io_it: logging.info( 'Particle Filtering tracking on {0}'.format(pams_path)) pam = load_peaks(pams_path, verbose=False) wm, affine, voxel_size = load_nifti(wm_path, return_voxsize=True) gm, _ = load_nifti(gm_path) csf, _ = load_nifti(csf_path) avs = sum(voxel_size) / len(voxel_size) # average_voxel_size classifier = CmcTissueClassifier.from_pve(wm, gm, csf, step_size=step_size, average_voxel_size=avs) 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') dg = ProbabilisticDirectionGetter direction_getter = dg.from_shcoeff(pam.shm_coeff, max_angle=max_angle, sphere=pam.sphere, pmf_threshold=pmf_threshold) tracking_result = ParticleFilteringTracking( direction_getter, classifier, seeds, affine, step_size=step_size, pft_back_tracking_dist=pft_back, pft_front_tracking_dist=pft_front, pft_max_trial=20, particle_count=pft_count, save_seeds=save_seeds) logging.info('ParticleFilteringTracking 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 main(): parser = _build_args_parser() args = parser.parse_args() if args.isVerbose: logging.basicConfig(level=logging.DEBUG) assert_inputs_exist(parser, [ args.sh_file, args.seed_file, args.map_include_file, args.map_exclude_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.particles <= 0: parser.error('--particles must be >= 1.') if args.back_tracking <= 0: parser.error('PFT backtracking distance must be > 0.') if args.forward_tracking <= 0: parser.error('PFT forward tracking distance must be > 0.') 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.') fodf_sh_img = nib.load(args.sh_file) 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.') tracking_sphere = HemiSphere.from_sphere(get_sphere('repulsion724')) # Check if sphere is unit, since we couldn't find such check in Dipy. if not np.allclose(np.linalg.norm(tracking_sphere.vertices, axis=1), 1.): raise RuntimeError('Tracking sphere should be unit normed.') sh_basis = args.sh_basis if args.algo == 'det': dgklass = DeterministicMaximumDirectionGetter else: dgklass = ProbabilisticDirectionGetter theta = get_theta(args.theta, args.algo) # Reminder for the future: # pmf_threshold == clip pmf under this # relative_peak_threshold is for initial directions filtering # min_separation_angle is the initial separation angle for peak extraction dg = dgklass.from_shcoeff(fodf_sh_img.get_data().astype(np.double), max_angle=theta, sphere=tracking_sphere, basis_type=sh_basis, pmf_threshold=args.sf_threshold, relative_peak_threshold=args.sf_threshold_init) map_include_img = nib.load(args.map_include_file) map_exclude_img = nib.load(args.map_exclude_file) voxel_size = np.average(map_include_img.get_header()['pixdim'][1:4]) tissue_classifier = None if not args.act: tissue_classifier = CmcTissueClassifier(map_include_img.get_data(), map_exclude_img.get_data(), step_size=args.step_size, average_voxel_size=voxel_size) else: tissue_classifier = ActTissueClassifier(map_include_img.get_data(), map_exclude_img.get_data()) 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) # Note that max steps is used once for the forward pass, and # once for the backwards. This doesn't, in fact, control the real # max length max_steps = int(args.max_length / args.step_size) + 1 pft_streamlines = ParticleFilteringTracking( dg, tissue_classifier, seeds, np.eye(4), max_cross=1, step_size=vox_step_size, maxlen=max_steps, pft_back_tracking_dist=args.back_tracking, pft_front_tracking_dist=args.forward_tracking, particle_count=args.particles, return_all=args.keep_all, 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 pft_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)
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 run(self, pam_files, wm_files, gm_files, csf_files, seeding_files, step_size=0.2, seed_density=1, pmf_threshold=0.1, max_angle=20., pft_back=2, pft_front=1, pft_count=15, out_dir='', out_tractogram='tractogram.trk'): """Workflow for Particle Filtering Tracking. This workflow use a saved peaks and metrics (PAM) file as input. Parameters ---------- pam_files : string Path to the peaks and metrics files. This path may contain wildcards to use multiple masks at once. wm_files : string Path to white matter partial volume estimate for tracking (CMC). gm_files : string Path to grey matter partial volume estimate for tracking (CMC). csf_files : string Path to cerebrospinal fluid partial volume estimate for tracking (CMC). seeding_files : string A binary image showing where we need to seed for tracking. step_size : float, optional Step size used for tracking (default 0.2mm). seed_density : int, optional Number of seeds per dimension inside voxel (default 1). For example, seed_density of 2 means 8 regularly distributed points in the voxel. And seed density of 1 means 1 point at the center of the voxel. pmf_threshold : float, optional Threshold for ODF functions (default 0.1). max_angle : float, optional Maximum angle between streamline segments (range [0, 90], default 20). pft_back : float, optional Distance in mm to back track before starting the particle filtering tractography (defaul 2mm). The total particle filtering tractography distance is equal to back_tracking_dist + front_tracking_dist. pft_front : float, optional Distance in mm to run the particle filtering tractography after the the back track distance (default 1mm). The total particle filtering tractography distance is equal to back_tracking_dist + front_tracking_dist. pft_count : int, optional Number of particles to use in the particle filter (default 15). out_dir : string, optional Output directory (default input file directory) out_tractogram : string, optional Name of the tractogram file to be saved (default 'tractogram.trk') References ---------- Girard, G., Whittingstall, K., Deriche, R., & Descoteaux, M. Towards quantitative connectivity analysis: reducing tractography biases. NeuroImage, 98, 266-278, 2014. """ io_it = self.get_io_iterator() for pams_path, wm_path, gm_path, csf_path, seeding_path, out_tract \ in io_it: logging.info('Particle Filtering tracking on {0}' .format(pams_path)) pam = load_peaks(pams_path, verbose=False) wm, affine, voxel_size = load_nifti(wm_path, return_voxsize=True) gm, _ = load_nifti(gm_path) csf, _ = load_nifti(csf_path) avs = sum(voxel_size) / len(voxel_size) # average_voxel_size classifier = CmcTissueClassifier.from_pve(wm, gm, csf, step_size=step_size, average_voxel_size=avs) 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') dg = ProbabilisticDirectionGetter direction_getter = dg.from_shcoeff(pam.shm_coeff, max_angle=max_angle, sphere=pam.sphere, pmf_threshold=pmf_threshold) streamlines_generator = ParticleFilteringTracking( direction_getter, classifier, seeds, affine, step_size=step_size, pft_back_tracking_dist=pft_back, pft_front_tracking_dist=pft_front, pft_max_trial=20, particle_count=pft_count) logging.info('ParticleFilteringTracking initiated') tractogram = Tractogram(streamlines_generator, affine_to_rasmm=np.eye(4)) save(tractogram, out_tract) logging.info('Saved {0}'.format(out_tract))
def run(self, pam_files, wm_files, gm_files, csf_files, seeding_files, step_size=0.2, back_tracking_dist=2, front_tracking_dist=1, max_trial=20, particle_count=15, seed_density=1, pmf_threshold=0.1, max_angle=30., out_dir='', out_tractogram='tractogram.trk'): """Workflow for Particle Filtering Tracking. This workflow use a saved peaks and metrics (PAM) file as input. Parameters ---------- pam_files : string Path to the peaks and metrics files. This path may contain wildcards to use multiple masks at once. wm_files : string Path of White matter for stopping criteria for tracking. gm_files : string Path of grey matter for stopping criteria for tracking. csf_files : string Path of cerebrospinal fluid for stopping criteria for tracking. seeding_files : string A binary image showing where we need to seed for tracking. step_size : float, optional Step size used for tracking. back_tracking_dist : float, optional Distance in mm to back track before starting the particle filtering tractography. The total particle filtering tractography distance is equal to back_tracking_dist + front_tracking_dist. By default this is set to 2 mm. front_tracking_dist : float, optional Distance in mm to run the particle filtering tractography after the the back track distance. The total particle filtering tractography distance is equal to back_tracking_dist + front_tracking_dist. By default this is set to 1 mm. max_trial : int, optional Maximum number of trial for the particle filtering tractography (Prevents infinite loops, default=20). particle_count : int, optional Number of particles to use in the particle filter. (default 15) seed_density : int, optional Number of seeds per dimension inside voxel (default 1). For example, seed_density of 2 means 8 regularly distributed points in the voxel. And seed density of 1 means 1 point at the center of the voxel. pmf_threshold : float, optional Threshold for ODF functions. (default 0.1) max_angle : float, optional Maximum angle between tract segments. This angle can be more generous (larger) than values typically used with probabilistic direction getters. The angle range is (0, 90) out_dir : string, optional Output directory (default input file directory) out_tractogram : string, optional Name of the tractogram file to be saved (default 'tractogram.trk') References ---------- Girard, G., Whittingstall, K., Deriche, R., & Descoteaux, M. Towards quantitative connectivity analysis: reducing tractography biases. NeuroImage, 98, 266-278, 2014.. """ io_it = self.get_io_iterator() for pams_path, wm_path, gm_path, csf_path, seeding_path, out_tract \ in io_it: logging.info( 'Particle Filtering tracking on {0}'.format(pams_path)) pam = load_peaks(pams_path, verbose=False) wm, affine, voxel_size = load_nifti(wm_path, return_voxsize=True) gm, _ = load_nifti(gm_path) csf, _ = load_nifti(csf_path) avs = sum(voxel_size) / len(voxel_size) # average_voxel_size classifier = CmcTissueClassifier.from_pve(wm, gm, csf, step_size=step_size, average_voxel_size=avs) 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') dg = ProbabilisticDirectionGetter direction_getter = dg.from_shcoeff(pam.shm_coeff, max_angle=max_angle, sphere=pam.sphere, pmf_threshold=pmf_threshold) streamlines = ParticleFilteringTracking( direction_getter, classifier, seeds, affine, step_size=step_size, pft_back_tracking_dist=back_tracking_dist, pft_front_tracking_dist=front_tracking_dist, pft_max_trial=max_trial, particle_count=particle_count) logging.info('ParticleFilteringTracking initiated') tractogram = Tractogram(streamlines, affine_to_rasmm=np.eye(4)) save(tractogram, out_tract) logging.info('Saved {0}'.format(out_tract))
mask=mask, parallel=parallel) ten_model = TensorModel(gtab) fa = ten_model.fit(data, mask).fa save_nifti(ffa, fa, affine) save_peaks(fpam5, pam, affine) show_odfs_and_fa(fa, pam, mask, None, sphere, ftmp='odf.mmap', basis_type=None) pve_csf, pve_gm, pve_wm = pve[..., 0], pve[..., 1], pve[..., 2] cmc_classifier = CmcTissueClassifier.from_pve( pve_wm, pve_gm, pve_csf, step_size=step_size, average_voxel_size=np.average(vox_size)) seed_mask = np.zeros(mask.shape) seed_mask[mask > 0] = 1 seed_mask[pve_wm < 0.5] = 0 seeds = utils.seeds_from_mask(seed_mask, density=1, affine=affine) det_streamline_generator = LocalTracking(pam, cmc_classifier, seeds, affine, step_size=step_size) # The line below is failing not sure why
csa_model = ConstrainedSphericalDeconvModel(gtab, response) csa_fit = csa_model.fit(data, mask=labels_wm) dg = ProbabilisticDirectionGetter.from_shcoeff(csa_fit.shm_coeff, max_angle=20., sphere=default_sphere) #Continous Map Criterion and Anatomically Constrainted Tractography(ACT) BOTH USES PVEs information from anatomical images to determine when the tractography stops. #Both tssue classifiers use a trilinear interpolation at the tracing position CMC tissue classifier uses a probability derived frm the PVE maps to determine if the #streamline reaches a 'valid' or 'invalid' region.ACT uses a fixed threshold on the PVE maps. Both tissue classifiers used in conjuction with PFT. voxel_size = 1 #avg_vox_size = np.average(voxel_size) step_size = 0.2 cmc_classifier = CmcTissueClassifier.from_pve(labels_img_wm.get_data(), labels_img_gm.get_data(), labels_img_csf.get_data(), step_size=step_size, average_voxel_size=voxel_size) seed_mask = labels_wm seeds = utils.seeds_from_mask(seed_mask, density=3, affine=affine) 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,
ten_model = TensorModel(gtab) fa = ten_model.fit(data, mask).fa save_nifti(ffa, fa, affine) save_peaks(fpam5, pam, affine) show_odfs_and_fa(fa, pam, mask, None, sphere, ftmp='odf.mmap', basis_type=None) pve_csf, pve_gm, pve_wm = pve[..., 0], pve[..., 1], pve[..., 2] cmc_classifier = CmcTissueClassifier.from_pve( pve_wm, pve_gm, pve_csf, step_size=step_size, average_voxel_size=np.average(vox_size)) seed_mask = np.zeros(mask.shape) seed_mask[mask > 0] = 1 seed_mask[pve_wm < 0.5] = 0 seeds = utils.seeds_from_mask(seed_mask, density=1, affine=affine) det_streamline_generator = LocalTracking(pam, cmc_classifier, seeds, affine, step_size=step_size)
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