def _get_direction_getter(args, mask_data): sh_data = nib.load(args.sh_file).get_data().astype('float64') sphere = HemiSphere.from_sphere(get_sphere(args.sphere)) theta = get_theta(args.theta, args.algo) if args.algo in ['det', 'prob']: if args.algo == 'det': dg_class = DeterministicMaximumDirectionGetter else: dg_class = ProbabilisticDirectionGetter return dg_class.from_shcoeff(shcoeff=sh_data, max_angle=theta, sphere=sphere, basis_type=args.sh_basis, relative_peak_threshold=args.sf_threshold) # Code for type EUDX. We don't use peaks_from_model # because we want the peaks from the provided sh. sh_shape_3d = sh_data.shape[:-1] npeaks = 5 peak_dirs = np.zeros((sh_shape_3d + (npeaks, 3))) peak_values = np.zeros((sh_shape_3d + (npeaks, ))) peak_indices = np.full((sh_shape_3d + (npeaks, )), -1, dtype='int') b_matrix = get_b_matrix(find_order_from_nb_coeff(sh_data), sphere, args.sh_basis) for idx in np.ndindex(sh_shape_3d): if not mask_data[idx]: continue directions, values, indices = get_maximas(sh_data[idx], sphere, b_matrix, args.sf_threshold, 0) if values.shape[0] != 0: n = min(npeaks, values.shape[0]) peak_dirs[idx][:n] = directions[:n] peak_values[idx][:n] = values[:n] peak_indices[idx][:n] = indices[:n] dg = PeaksAndMetrics() dg.sphere = sphere dg.peak_dirs = peak_dirs dg.peak_values = peak_values dg.peak_indices = peak_indices dg.ang_thr = theta dg.qa_thr = args.sf_threshold return dg
def test_io_save_peaks_error(): with InTemporaryDirectory(): fname = 'test.pam5' pam = PeaksAndMetrics() npt.assert_raises(IOError, save_peaks, 'test.pam', pam) npt.assert_raises(ValueError, save_peaks, fname, pam) pam.affine = np.eye(4) pam.peak_dirs = np.random.rand(10, 10, 10, 5, 3) pam.peak_values = np.zeros((10, 10, 10, 5)) pam.peak_indices = np.zeros((10, 10, 10, 5)) pam.shm_coeff = np.zeros((10, 10, 10, 45)) pam.sphere = default_sphere pam.B = np.zeros((45, default_sphere.vertices.shape[0])) pam.total_weight = 0.5 pam.ang_thr = 60 pam.gfa = np.zeros((10, 10, 10)) pam.qa = np.zeros((10, 10, 10, 5)) pam.odf = np.zeros((10, 10, 10, default_sphere.vertices.shape[0]))
def test_io_save_peaks_error(): with InTemporaryDirectory(): fname = 'test.pam5' pam = PeaksAndMetrics() npt.assert_raises(IOError, save_peaks, 'test.pam', pam) npt.assert_raises(ValueError, save_peaks, fname, pam) sphere = get_sphere('repulsion724') pam.affine = np.eye(4) pam.peak_dirs = np.random.rand(10, 10, 10, 5, 3) pam.peak_values = np.zeros((10, 10, 10, 5)) pam.peak_indices = np.zeros((10, 10, 10, 5)) pam.shm_coeff = np.zeros((10, 10, 10, 45)) pam.sphere = sphere pam.B = np.zeros((45, sphere.vertices.shape[0])) pam.total_weight = 0.5 pam.ang_thr = 60 pam.gfa = np.zeros((10, 10, 10)) pam.qa = np.zeros((10, 10, 10, 5)) pam.odf = np.zeros((10, 10, 10, sphere.vertices.shape[0]))
def test_io_peaks(): with InTemporaryDirectory(): fname = 'test.pam5' pam = PeaksAndMetrics() pam.affine = np.eye(4) pam.peak_dirs = np.random.rand(10, 10, 10, 5, 3) pam.peak_values = np.zeros((10, 10, 10, 5)) pam.peak_indices = np.zeros((10, 10, 10, 5)) pam.shm_coeff = np.zeros((10, 10, 10, 45)) pam.sphere = default_sphere pam.B = np.zeros((45, default_sphere.vertices.shape[0])) pam.total_weight = 0.5 pam.ang_thr = 60 pam.gfa = np.zeros((10, 10, 10)) pam.qa = np.zeros((10, 10, 10, 5)) pam.odf = np.zeros((10, 10, 10, default_sphere.vertices.shape[0])) save_peaks(fname, pam) pam2 = load_peaks(fname, verbose=True) npt.assert_array_equal(pam.peak_dirs, pam2.peak_dirs) pam2.affine = None fname2 = 'test2.pam5' save_peaks(fname2, pam2, np.eye(4)) pam2_res = load_peaks(fname2, verbose=True) npt.assert_array_equal(pam.peak_dirs, pam2_res.peak_dirs) pam3 = load_peaks(fname2, verbose=False) for attr in [ 'peak_dirs', 'peak_values', 'peak_indices', 'gfa', 'qa', 'shm_coeff', 'B', 'odf' ]: npt.assert_array_equal(getattr(pam3, attr), getattr(pam, attr)) npt.assert_equal(pam3.total_weight, pam.total_weight) npt.assert_equal(pam3.ang_thr, pam.ang_thr) npt.assert_array_almost_equal(pam3.sphere.vertices, pam.sphere.vertices) fname3 = 'test3.pam5' pam4 = PeaksAndMetrics() npt.assert_raises(ValueError, save_peaks, fname3, pam4) fname4 = 'test4.pam5' del pam.affine save_peaks(fname4, pam, affine=None) fname5 = 'test5.pkm' npt.assert_raises(IOError, save_peaks, fname5, pam) pam.affine = np.eye(4) fname6 = 'test6.pam5' save_peaks(fname6, pam, verbose=True) del pam.shm_coeff save_peaks(fname6, pam, verbose=False) pam.shm_coeff = np.zeros((10, 10, 10, 45)) del pam.odf save_peaks(fname6, pam) pam_tmp = load_peaks(fname6, True) npt.assert_equal(pam_tmp.odf, None) fname7 = 'test7.paw' npt.assert_raises(IOError, load_peaks, fname7) del pam.shm_coeff save_peaks(fname6, pam, verbose=True) fname_shm = 'shm.nii.gz' fname_dirs = 'dirs.nii.gz' fname_values = 'values.nii.gz' fname_indices = 'indices.nii.gz' fname_gfa = 'gfa.nii.gz' pam.shm_coeff = np.ones((10, 10, 10, 45)) peaks_to_niftis(pam, fname_shm, fname_dirs, fname_values, fname_indices, fname_gfa, reshape_dirs=False) os.path.isfile(fname_shm) os.path.isfile(fname_dirs) os.path.isfile(fname_values) os.path.isfile(fname_indices) os.path.isfile(fname_gfa)
def load_peaks(fname, verbose=False): """ Load a PeaksAndMetrics HDF5 file (PAM5) Parameters ---------- fname : string Filename of PAM5 file. verbose : bool Print summary information about the loaded file. Returns ------- pam : PeaksAndMetrics object """ if os.path.splitext(fname)[1].lower() != '.pam5': raise IOError('This function supports only PAM5 (HDF5) files') f = h5py.File(fname, 'r') pam = PeaksAndMetrics() pamh = f['pam'] version = f.attrs['version'] if version != '0.0.1': raise IOError('Incorrect PAM5 file version {0}'.format(version,)) try: affine = pamh['affine'][:] except KeyError: affine = None peak_dirs = pamh['peak_dirs'][:] peak_values = pamh['peak_values'][:] peak_indices = pamh['peak_indices'][:] try: shm_coeff = pamh['shm_coeff'][:] except KeyError: shm_coeff = None sphere_vertices = pamh['sphere_vertices'][:] try: odf = pamh['odf'][:] except KeyError: odf = None pam.affine = affine pam.peak_dirs = peak_dirs pam.peak_values = peak_values pam.peak_indices = peak_indices pam.shm_coeff = shm_coeff pam.sphere = Sphere(xyz=sphere_vertices) pam.B = pamh['B'][:] pam.total_weight = pamh['total_weight'][:][0] pam.ang_thr = pamh['ang_thr'][:][0] pam.gfa = pamh['gfa'][:] pam.qa = pamh['qa'][:] pam.odf = odf f.close() if verbose: print('PAM5 version') print(version) print('Affine') print(pam.affine) print('Dirs shape') print(pam.peak_dirs.shape) print('SH shape') if pam.shm_coeff is not None: print(pam.shm_coeff.shape) else: print('None') print('ODF shape') if pam.odf is not None: print(pam.odf.shape) else: print('None') print('Total weight') print(pam.total_weight) print('Angular threshold') print(pam.ang_thr) print('Sphere vertices shape') print(pam.sphere.vertices.shape) return pam
def test_io_peaks(): with InTemporaryDirectory(): fname = 'test.pam5' sphere = get_sphere('repulsion724') pam = PeaksAndMetrics() pam.affine = np.eye(4) pam.peak_dirs = np.random.rand(10, 10, 10, 5, 3) pam.peak_values = np.zeros((10, 10, 10, 5)) pam.peak_indices = np.zeros((10, 10, 10, 5)) pam.shm_coeff = np.zeros((10, 10, 10, 45)) pam.sphere = sphere pam.B = np.zeros((45, sphere.vertices.shape[0])) pam.total_weight = 0.5 pam.ang_thr = 60 pam.gfa = np.zeros((10, 10, 10)) pam.qa = np.zeros((10, 10, 10, 5)) pam.odf = np.zeros((10, 10, 10, sphere.vertices.shape[0])) save_peaks(fname, pam) pam2 = load_peaks(fname, verbose=True) npt.assert_array_equal(pam.peak_dirs, pam2.peak_dirs) pam2.affine = None fname2 = 'test2.pam5' save_peaks(fname2, pam2, np.eye(4)) pam2_res = load_peaks(fname2, verbose=True) npt.assert_array_equal(pam.peak_dirs, pam2_res.peak_dirs) pam3 = load_peaks(fname2, verbose=False) for attr in ['peak_dirs', 'peak_values', 'peak_indices', 'gfa', 'qa', 'shm_coeff', 'B', 'odf']: npt.assert_array_equal(getattr(pam3, attr), getattr(pam, attr)) npt.assert_equal(pam3.total_weight, pam.total_weight) npt.assert_equal(pam3.ang_thr, pam.ang_thr) npt.assert_array_almost_equal(pam3.sphere.vertices, pam.sphere.vertices) fname3 = 'test3.pam5' pam4 = PeaksAndMetrics() npt.assert_raises(ValueError, save_peaks, fname3, pam4) fname4 = 'test4.pam5' del pam.affine save_peaks(fname4, pam, affine=None) fname5 = 'test5.pkm' npt.assert_raises(IOError, save_peaks, fname5, pam) pam.affine = np.eye(4) fname6 = 'test6.pam5' save_peaks(fname6, pam, verbose=True) del pam.shm_coeff save_peaks(fname6, pam, verbose=False) pam.shm_coeff = np.zeros((10, 10, 10, 45)) del pam.odf save_peaks(fname6, pam) pam_tmp = load_peaks(fname6, True) npt.assert_equal(pam_tmp.odf, None) fname7 = 'test7.paw' npt.assert_raises(IOError, load_peaks, fname7) del pam.shm_coeff save_peaks(fname6, pam, verbose=True) fname_shm = 'shm.nii.gz' fname_dirs = 'dirs.nii.gz' fname_values = 'values.nii.gz' fname_indices = 'indices.nii.gz' fname_gfa = 'gfa.nii.gz' pam.shm_coeff = np.ones((10, 10, 10, 45)) peaks_to_niftis(pam, fname_shm, fname_dirs, fname_values, fname_indices, fname_gfa, reshape_dirs=False) os.path.isfile(fname_shm) os.path.isfile(fname_dirs) os.path.isfile(fname_values) os.path.isfile(fname_indices) os.path.isfile(fname_gfa)
def load_peaks(fname, verbose=False): """ Load a PeaksAndMetrics HDF5 file (PAM5) Parameters ---------- fname : string Filename of PAM5 file. verbose : bool Print summary information about the loaded file. Returns ------- pam : PeaksAndMetrics object """ if os.path.splitext(fname)[1] != '.pam5': raise IOError('This function supports only PAM5 (HDF5) files') if TABLES_LESS_3_0: func_open_file = tables.openFile else: func_open_file = tables.open_file f = func_open_file(fname, 'r') pam = PeaksAndMetrics() pamh = f.root.pam version = f.root.version[0].decode() if version != '0.0.1': raise IOError('Incorrect PAM5 file version') try: affine = pamh.affine[:] except tables.NoSuchNodeError: affine = None peak_dirs = pamh.peak_dirs[:] peak_values = pamh.peak_values[:] peak_indices = pamh.peak_indices[:] try: shm_coeff = pamh.shm_coeff[:] except tables.NoSuchNodeError: shm_coeff = None sphere_vertices = pamh.sphere_vertices[:] try: odf = pamh.odf[:] except tables.NoSuchNodeError: odf = None pam.affine = affine pam.peak_dirs = peak_dirs pam.peak_values = peak_values pam.peak_indices = peak_indices pam.shm_coeff = shm_coeff pam.sphere = Sphere(xyz=sphere_vertices) pam.B = pamh.B[:] pam.total_weight = pamh.total_weight[:][0] pam.ang_thr = pamh.ang_thr[:][0] pam.gfa = pamh.gfa[:] pam.qa = pamh.qa[:] pam.odf = odf f.close() if verbose: print('PAM5 version') print(version) print('Affine') print(pam.affine) print('Dirs shape') print(pam.peak_dirs.shape) print('SH shape') if pam.shm_coeff is not None: print(pam.shm_coeff.shape) else: print('None') print('ODF shape') if pam.odf is not None: print(pam.odf.shape) else: print('None') print('Total weight') print(pam.total_weight) print('Angular threshold') print(pam.ang_thr) print('Sphere vertices shape') print(pam.sphere.vertices.shape) return pam
def _get_direction_getter(args): odf_data = nib.load(args.in_odf).get_fdata(dtype=np.float32) sphere = HemiSphere.from_sphere(get_sphere(args.sphere)) theta = get_theta(args.theta, args.algo) non_zeros_count = np.count_nonzero(np.sum(odf_data, axis=-1)) non_first_val_count = np.count_nonzero(np.argmax(odf_data, axis=-1)) if args.algo in ['det', 'prob']: if non_first_val_count / non_zeros_count > 0.5: logging.warning('Input detected as peaks. Input should be' 'fodf for det/prob, verify input just in case.') if args.algo == 'det': dg_class = DeterministicMaximumDirectionGetter else: dg_class = ProbabilisticDirectionGetter return dg_class.from_shcoeff( shcoeff=odf_data, max_angle=theta, sphere=sphere, basis_type=args.sh_basis, relative_peak_threshold=args.sf_threshold) elif args.algo == 'eudx': # Code for type EUDX. We don't use peaks_from_model # because we want the peaks from the provided sh. odf_shape_3d = odf_data.shape[:-1] dg = PeaksAndMetrics() dg.sphere = sphere dg.ang_thr = theta dg.qa_thr = args.sf_threshold # Heuristic to find out if the input are peaks or fodf # fodf are always around 0.15 and peaks around 0.75 if non_first_val_count / non_zeros_count > 0.5: logging.info('Input detected as peaks.') nb_peaks = odf_data.shape[-1] // 3 slices = np.arange(0, 15+1, 3) peak_values = np.zeros(odf_shape_3d+(nb_peaks,)) peak_indices = np.zeros(odf_shape_3d+(nb_peaks,)) for idx in np.argwhere(np.sum(odf_data, axis=-1)): idx = tuple(idx) for i in range(nb_peaks): peak_values[idx][i] = np.linalg.norm( odf_data[idx][slices[i]:slices[i+1]], axis=-1) peak_indices[idx][i] = sphere.find_closest( odf_data[idx][slices[i]:slices[i+1]]) dg.peak_dirs = odf_data else: logging.info('Input detected as fodf.') npeaks = 5 peak_dirs = np.zeros((odf_shape_3d + (npeaks, 3))) peak_values = np.zeros((odf_shape_3d + (npeaks, ))) peak_indices = np.full((odf_shape_3d + (npeaks, )), -1, dtype='int') b_matrix = get_b_matrix( find_order_from_nb_coeff(odf_data), sphere, args.sh_basis) for idx in np.argwhere(np.sum(odf_data, axis=-1)): idx = tuple(idx) directions, values, indices = get_maximas(odf_data[idx], sphere, b_matrix, args.sf_threshold, 0) if values.shape[0] != 0: n = min(npeaks, values.shape[0]) peak_dirs[idx][:n] = directions[:n] peak_values[idx][:n] = values[:n] peak_indices[idx][:n] = indices[:n] dg.peak_dirs = peak_dirs dg.peak_values = peak_values dg.peak_indices = peak_indices return dg