Exemplo n.º 1
0
def apply_solver(evoked, forward, noise_cov, loose=0.2, depth=0.8, K=2000):
    all_ch_names = evoked.ch_names
    # put the forward solution in fixed orientation if it's not already
    if loose is None and not is_fixed_orient(forward):
        forward = deepcopy(forward)
        forward = mne.convert_forward_solution(forward, force_fixed=True)

    gain, gain_info, whitener, source_weighting, mask = _prepare_gain(
        forward,
        evoked.info,
        noise_cov,
        pca=False,
        depth=depth,
        loose=loose,
        weights=None,
        weights_min=None)

    n_locations = gain.shape[1]
    sel = [all_ch_names.index(name) for name in gain_info['ch_names']]
    M = evoked.data[sel]

    # Whiten data
    M = np.dot(whitener, M)

    n_orient = 1 if is_fixed_orient(forward) else 3

    # The value of lambda for which the solution will be all zero
    lambda_max = norm_l2inf(np.dot(gain.T, M), n_orient)

    lambda_ref = 0.1 * lambda_max

    out = mm_mixed_norm_bayes(M,
                              gain,
                              lambda_ref,
                              n_orient=n_orient,
                              K=K,
                              return_lpp=True)

    (Xs, active_sets), _, _, _, _ = out

    solution_support = np.zeros((K, n_locations))
    stcs, obj_fun = [], []
    for k in range(K):
        X = np.zeros((n_locations, Xs[k].shape[1]))
        X[active_sets[k]] = Xs[k]
        block_norms_new = compute_block_norms(X, n_orient)
        block_norms_new = (block_norms_new > 0.05 * block_norms_new.max())
        solution_support[k, :] = block_norms_new

        stc = _make_sparse_stc(Xs[k],
                               active_sets[k],
                               forward,
                               tmin=0.,
                               tstep=1. / evoked.info['sfreq'])
        stcs.append(stc)
        obj_fun.append(
            energy_l2half_reg(M, gain, stc.data, active_sets[k], lambda_ref,
                              n_orient))
    return solution_support, stcs, obj_fun
Exemplo n.º 2
0
def apply_solver_isdr(solver,
                      evoked,
                      forward,
                      noise_cov,
                      loose=0.2,
                      depth=0.8):
    # Import the necessary private functions
    from mne.inverse_sparse.mxne_inverse import \
        (_prepare_gain, _check_loose_forward, is_fixed_orient,
         _reapply_source_weighting, _make_sparse_stc)

    all_ch_names = evoked.ch_names

    loose, forward = _check_loose_forward(loose, forward)

    # put the forward solution in fixed orientation if it's not already
    if loose == 0. and not is_fixed_orient(forward):
        forward = mne.convert_forward_solution(forward,
                                               surf_ori=True,
                                               force_fixed=True,
                                               copy=True,
                                               use_cps=True)

    # Handle depth weighting and whitening (here is no weights)
    gain, gain_info, whitener, source_weighting, mask = _prepare_gain(
        forward,
        evoked.info,
        noise_cov,
        pca=False,
        depth=depth,
        loose=loose,
        weights=None,
        weights_min=None)
    print source_weighting
    # Select channels of interest
    sel = [all_ch_names.index(name) for name in gain_info['ch_names']]
    M = evoked.data[sel]

    # Whiten data
    M = np.dot(whitener, M).astype(np.double)
    active_set = np.zeros(gain.shape[1], dtype=bool)
    gain = gain[:, :].astype(np.double)
    n_orient = 1 if is_fixed_orient(forward) else 3
    SC = np.eye(np.shape(gain)[1]).astype(np.int32)
    GA = gain.copy().astype(np.double)
    X, n_active_set, coef = solver_isdr(M, gain, GA, SC)
    active_set[n_active_set] = True
    #X = _reapply_source_weighting(X, source_weighting, active_set, n_orient)
    #Z = np.zeros((np.shape(gain)[1], np.shape(M)[1]))
    #Z[np.array(n_active_set), :] = X[:np.shape(M)[1], :len(n_active_set)].T
    #stc = _make_sparse_stc(Z, active_set, forward, tmin=evoked.times[0], tstep=1. / evoked.info['sfreq'])

    return X  #stc
def apply_solver(solver, evoked, forward, noise_cov, loose=0.2, depth=0.8):
    """Call a custom solver on evoked data.

    This function does all the necessary computation:

    - to select the channels in the forward given the available ones in
      the data
    - to take into account the noise covariance and do the spatial whitening
    - to apply loose orientation constraint as MNE solvers
    - to apply a weigthing of the columns of the forward operator as in the
      weighted Minimum Norm formulation in order to limit the problem
      of depth bias.

    Parameters
    ----------
    solver : callable
        The solver takes 3 parameters: data M, gain matrix G, number of
        dipoles orientations per location (1 or 3). A solver shall return
        2 variables: X which contains the time series of the active dipoles
        and an active set which is a boolean mask to specify what dipoles are
        present in X.
    evoked : instance of mne.Evoked
        The evoked data
    forward : instance of Forward
        The forward solution.
    noise_cov : instance of Covariance
        The noise covariance.
    loose : float in [0, 1] | 'auto'
        Value that weights the source variances of the dipole components
        that are parallel (tangential) to the cortical surface. If loose
        is 0 then the solution is computed with fixed orientation.
        If loose is 1, it corresponds to free orientations.
        The default value ('auto') is set to 0.2 for surface-oriented source
        space and set to 1.0 for volumic or discrete source space.
    depth : None | float in [0, 1]
        Depth weighting coefficients. If None, no depth weighting is performed.

    Returns
    -------
    stc : instance of SourceEstimate
        The source estimates.
    """
    # Import the necessary private functions
    from mne.inverse_sparse.mxne_inverse import \
        (_prepare_gain, is_fixed_orient,
         _reapply_source_weighting, _make_sparse_stc)

    all_ch_names = evoked.ch_names

    # Handle depth weighting and whitening (here is no weights)
    forward, gain, gain_info, whitener, source_weighting, mask = _prepare_gain(
        forward, evoked.info, noise_cov, pca=False, depth=depth,
        loose=loose, weights=None, weights_min=None, rank=None)

    # Select channels of interest
    sel = [all_ch_names.index(name) for name in gain_info['ch_names']]
    M = evoked.data[sel]

    # Whiten data
    M = np.dot(whitener, M)

    n_orient = 1 if is_fixed_orient(forward) else 3
    X, active_set = solver(M, gain, n_orient)
    X = _reapply_source_weighting(X, source_weighting, active_set)

    stc = _make_sparse_stc(X, active_set, forward, tmin=evoked.times[0],
                           tstep=1. / evoked.info['sfreq'])

    return stc
def apply_solver(solver, evoked, forward, noise_cov, loose=0.2, depth=0.8):
    """Function to call a custom solver on evoked data

    This function does all the necessary computation:

    - to select the channels in the forward given the available ones in
      the data
    - to take into account the noise covariance and do the spatial whitening
    - to apply loose orientation constraint as MNE solvers
    - to apply a weigthing of the columns of the forward operator as in the
      weighted Minimum Norm formulation in order to limit the problem
      of depth bias.

    Parameters
    ----------
    solver : callable
        The solver takes 3 parameters: data M, gain matrix G, number of
        dipoles orientations per location (1 or 3). A solver shall return
        2 variables: X which contains the time series of the active dipoles
        and an active set which is a boolean mask to specify what dipoles are
        present in X.
    evoked : instance of mne.Evoked
        The evoked data
    forward : instance of Forward
        The forward solution.
    noise_cov : instance of Covariance
        The noise covariance.
    loose : None | float in [0, 1]
        Value that weights the source variances of the dipole components
        defining the tangent space of the cortical surfaces. Requires surface-
        based, free orientation forward solutions.
    depth : None | float in [0, 1]
        Depth weighting coefficients. If None, no depth weighting is performed.

    Returns
    -------
    stc : instance of SourceEstimate
        The source estimates.
    """
    # Import the necessary private functions
    from mne.inverse_sparse.mxne_inverse import \
        (_prepare_gain, _to_fixed_ori, is_fixed_orient,
         _reapply_source_weighting, _make_sparse_stc)

    all_ch_names = evoked.ch_names
    # put the forward solution in fixed orientation if it's not already
    if loose is None and not is_fixed_orient(forward):
        forward = forward.copy()
        _to_fixed_ori(forward)

    # Handle depth weighting and whitening (here is no weights)
    gain, gain_info, whitener, source_weighting, mask = _prepare_gain(
        forward, evoked.info, noise_cov, pca=False, depth=depth,
        loose=loose, weights=None, weights_min=None)

    # Select channels of interest
    sel = [all_ch_names.index(name) for name in gain_info['ch_names']]
    M = evoked.data[sel]

    # Whiten data
    M = np.dot(whitener, M)

    n_orient = 1 if is_fixed_orient(forward) else 3
    X, active_set = solver(M, gain, n_orient)
    X = _reapply_source_weighting(X, source_weighting, active_set, n_orient)

    stc = _make_sparse_stc(X, active_set, forward, tmin=evoked.times[0],
                           tstep=1. / evoked.info['sfreq'])

    return stc