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 _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