예제 #1
0
def kfold_xval_MD_mod(data, bvals, bvecs, mask, func, n, factor = 1000,
                      initial="preset", bounds = "preset", params_file='temp',
                      signal="relative_signal"):
    """
    Finds the parameters of the given function to the given data
    that minimizes the sum squared errors using kfold cross validation.

    Parameters
    ----------
    data: 4 dimensional array
        Diffusion MRI data
    bvals: 1 dimensional array
        All b values
    bvecs: 3 dimensional array
        All the b vectors
    mask: 3 dimensional array
        Brain mask of the data
    func: function handle
        Mean model to perform kfold cross-validation on.
    initial: tuple
        Initial values for the parameters.
    n: int
        Integer indicating the percent of vertices that you want to predict
    factor: int
        Integer indicating the scaling factor for the b values
    bounds: list
        List containing tuples indicating the bounds for each parameter in
        the mean model function.

    Returns
    -------
    cod: 1 dimensional array
        Coefficent of Determination between data and predicted values
    predicted: 2 dimensional array
        Predicted mean for the vertices left out of the fit
    """
    if isinstance(func, str):
        # Grab the function handle for the desired mean model
        func = globals()[func]

    # Get the initial values for the desired mean model
    if (bounds == "preset") | (initial == "preset"):
        all_params = initial_params(data, bvecs, bvals, func, mask=mask,
                                    params_file=params_file)
    if bounds == "preset":
        bounds = all_params[0]
    if initial == "preset":
        func_initial = all_params[1]
    else:
        this_initial = initial

    bval_list, b_inds, unique_b, rounded_bvals = ozu.separate_bvals(bvals)
    all_b_idx, b0_inds = _diffusion_inds(bvals, b_inds, rounded_bvals)

    b_scaled = bvals/factor
    flat_data = data[np.where(mask)]

    # Pre-allocate outputs
    ss_err = np.zeros(int(np.sum(mask)))
    predict_out = np.zeros((int(np.sum(mask)),len(all_b_idx)))

    # Setting up for creating combinations of directions for kfold cross
    # validation:

    # Number of directions to leave out at a time.
    num_choose = (n/100.)*len(all_b_idx)

    # Find the indices to all the non-b = 0 directions and shuffle them.
    vec_pool = np.arange(len(all_b_idx))
    np.random.shuffle(vec_pool)
    all_inc_0 = np.arange(len(rounded_bvals))

    # Start cross-validation
    for combo_num in np.arange(np.floor(100./n)):
        (si, vec_combo, vec_combo_rm0,
         vec_pool_inds, these_bvecs, these_bvals,
         this_data, these_inc0) = ozu.create_combos(bvecs, bvals, data,
                                                    all_b_idx,
                                                    np.arange(len(all_b_idx)),
                                                    all_b_idx, vec_pool,
                                                    num_choose, combo_num)
        this_flat_data = this_data[np.where(mask)]

        for vox in np.arange(np.sum(mask)).astype(int):
            s0 = np.mean(flat_data[vox, b0_inds], -1)
            these_b = b_scaled[vec_combo] # b values to predict

            if initial == "preset":
                this_initial = func_initial[vox]

            input_signal = flat_data[vox, these_inc0]/s0

            if signal == "log":
                input_signal = np.log(input_signal)

            # Fit mean model to part of the data
            params, _ = opt.leastsq(err_func, this_initial,
                                    args=(b_scaled[these_inc0],
                                    input_signal, func))
            if bounds == None:
                params, _ = opt.leastsq(err_func, this_initial,
                                        args=(b_scaled[these_inc0],
                                        input_signal, func))
            else:
                lsq_b_out = lsq.leastsqbound(err_func, this_initial,
                                             args = (b_scaled[these_inc0],
                                                     input_signal, func),
                                             bounds = bounds)
                params = lsq_b_out[0]
            # Predict the mean values of the left out b values using the
            # parameters from fitting to part of the b values.
            predict = func(these_b, *params)
            predict_out[vox, vec_combo_rm0] = func(these_b, *params)

    # Find the relative diffusion signal.
    s0 = np.mean(flat_data[:, b0_inds], -1).astype(float)
    input_signal = flat_data[:, all_b_idx]/s0[..., None]
    if signal == "log":
        input_signal = np.log(input_signal)
    cod = ozu.coeff_of_determination(input_signal, predict_out, axis=-1)

    return cod, predict_out
예제 #2
0
def kfold_xval_MD_mod(data,
                      bvals,
                      bvecs,
                      mask,
                      func,
                      n,
                      factor=1000,
                      initial="preset",
                      bounds="preset",
                      params_file='temp',
                      signal="relative_signal"):
    """
    Finds the parameters of the given function to the given data
    that minimizes the sum squared errors using kfold cross validation.

    Parameters
    ----------
    data: 4 dimensional array
        Diffusion MRI data
    bvals: 1 dimensional array
        All b values
    bvecs: 3 dimensional array
        All the b vectors
    mask: 3 dimensional array
        Brain mask of the data
    func: function handle
        Mean model to perform kfold cross-validation on.
    initial: tuple
        Initial values for the parameters.
    n: int
        Integer indicating the percent of vertices that you want to predict
    factor: int
        Integer indicating the scaling factor for the b values
    bounds: list
        List containing tuples indicating the bounds for each parameter in
        the mean model function.

    Returns
    -------
    cod: 1 dimensional array
        Coefficent of Determination between data and predicted values
    predicted: 2 dimensional array
        Predicted mean for the vertices left out of the fit
    """
    if isinstance(func, str):
        # Grab the function handle for the desired isotropic model
        func = globals()[func]

    # Get the initial values for the desired isotropic model
    if (bounds == "preset") | (initial == "preset"):
        all_params = initial_params(data,
                                    bvecs,
                                    bvals,
                                    func,
                                    mask=mask,
                                    params_file=params_file)
        if bounds == "preset":
            bounds = all_params[0]
        if initial == "preset":
            func_initial = all_params[1]
    else:
        this_initial = initial

    bval_list, b_inds, unique_b, rounded_bvals = ozu.separate_bvals(bvals)
    all_b_idx, b0_inds = _diffusion_inds(bvals, b_inds, rounded_bvals)

    b_scaled = bvals / factor
    flat_data = data[np.where(mask)]

    # Pre-allocate outputs
    ss_err = np.zeros(int(np.sum(mask)))
    predict_out = np.zeros((int(np.sum(mask)), len(all_b_idx)))

    # Setting up for creating combinations of directions for kfold cross
    # validation:

    # Number of directions to leave out at a time.
    num_choose = (n / 100.) * len(all_b_idx)

    # Find the indices to all the non-b = 0 directions and shuffle them.
    vec_pool = np.arange(len(all_b_idx))
    np.random.shuffle(vec_pool)
    all_inc_0 = np.arange(len(rounded_bvals))

    # Start cross-validation
    for combo_num in np.arange(np.floor(100. / n)):
        (si, vec_combo, vec_combo_rm0, vec_pool_inds, these_bvecs, these_bvals,
         this_data, these_inc0) = ozu.create_combos(bvecs, bvals, data,
                                                    all_b_idx,
                                                    np.arange(len(all_b_idx)),
                                                    all_b_idx, vec_pool,
                                                    num_choose, combo_num)

        these_b = b_scaled[vec_combo]  # b values to predict
        for vox in np.arange(np.sum(mask)).astype(int):
            s0 = np.mean(flat_data[vox, b0_inds], -1)

            if initial == "preset":
                this_initial = func_initial[vox]

            input_signal = flat_data[vox, these_inc0] / s0

            if signal == "log":
                input_signal = np.log(input_signal)

            # Fit mean model to part of the data
            params, _ = opt.leastsq(err_func,
                                    this_initial,
                                    args=(b_scaled[these_inc0], input_signal,
                                          func))
            if bounds == None:
                params, _ = opt.leastsq(err_func,
                                        this_initial,
                                        args=(b_scaled[these_inc0],
                                              input_signal, func))
            else:
                lsq_b_out = lsq.leastsqbound(err_func,
                                             this_initial,
                                             args=(b_scaled[these_inc0],
                                                   input_signal, func),
                                             bounds=bounds)
                params = lsq_b_out[0]
            predict_out[vox, vec_combo_rm0] = func(these_b, *params)

    # Find the relative diffusion signal.
    s0 = np.mean(flat_data[:, b0_inds], -1).astype(float)
    input_signal = flat_data[:, all_b_idx] / s0[..., None]
    if signal == "log":
        input_signal = np.log(input_signal)
    cod = ozu.coeff_of_determination(input_signal, predict_out, axis=-1)

    return cod, predict_out