Exemple #1
0
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