예제 #1
0
def make_dipole_projectors(info, pos, ori, bem, trans, verbose=None):
    """Make dipole projectors.

    Parameters
    ----------
    info : instance of Info
        The measurement info.
    pos : ndarray, shape (n_dip, 3)
        The dipole positions.
    ori : ndarray, shape (n_dip, 3)
        The dipole orientations.
    bem : instance of ConductorModel
        The conductor model to use.
    trans : instance of Transform
        The mri-to-head transformation.
    %(verbose)s

    Returns
    -------
    projs : list of Projection
        The projectors.
    """
    pos = np.atleast_2d(pos).astype(float)
    ori = np.atleast_2d(ori).astype(float)
    if pos.shape[1] != 3 or pos.shape != ori.shape:
        raise ValueError('pos and ori must be 2D, the same shape, and have '
                         f'last dimension 3, got {pos.shape} and {ori.shape}')
    dip = Dipole(pos=pos,
                 ori=ori,
                 amplitude=np.ones(pos.shape[0]),
                 gof=np.ones(pos.shape[0]),
                 times=np.arange(pos.shape[0]))
    info = pick_info(info, pick_types(info, meg=True, eeg=True, exclude=()))
    fwd, _ = make_forward_dipole(dip, bem, info, trans)
    assert fwd['sol']['data'].shape[1] == pos.shape[0]
    projs = list()
    for kind in ('meg', 'eeg'):
        kwargs = dict(meg=False, eeg=False, exclude=())
        kwargs.update({kind: True})
        picks = pick_types(info, **kwargs)
        if len(picks) > 0:
            ch_names = [info['ch_names'][pick] for pick in picks]
            projs.extend([
                Projection(data=dict(data=p[np.newaxis, picks],
                                     row_names=None,
                                     nrow=1,
                                     col_names=list(ch_names),
                                     ncol=len(ch_names)),
                           kind=FIFF.FIFFV_PROJ_ITEM_DIP_FIX,
                           explained_var=None,
                           active=False,
                           desc=f'Dipole #{pi}')
                for pi, p in enumerate(fwd['sol']['data'].T, 1)
            ])
    return projs
예제 #2
0
def gen_forward_solution(pos, bem, info, trans, verbose=True):
    # NOTE:
    # Both, dipole amplitude and orientation, are set to arbitrary values
    # here: They are merely required to instantiate a Dipole object, which
    # we then use to conveniently retrieve a forward solution via
    # `make_forward_dipole()`. This forward solution is returned in "fixed"
    # orientation. We then convert it back to "free" orientation mode before
    # returning the forward object.

    amplitude = np.array([1]).reshape(1, )  # Arbitraty amplitude.
    ori = np.array([1., 1., 1.]).reshape(1, 3)  # Arbitrary orientation.
    ori /= np.linalg.norm(ori)
    pos = pos.reshape(1, 3)
    gof = np.array([100]).reshape(1, )
    dip = mne.Dipole(times=[0], pos=pos, ori=ori, amplitude=amplitude, gof=gof)
    fwd, _ = mne.make_forward_dipole(dip,
                                     bem=bem,
                                     info=info,
                                     trans=trans,
                                     verbose=verbose)
    fwd = mne.convert_forward_solution(fwd, force_fixed=False, verbose=verbose)
    return fwd
예제 #3
0
def test_simulate_calculate_chpi_positions():
    """Test calculation of cHPI positions with simulated data."""
    # Read info dict from raw FIF file
    info = read_info(raw_fname)
    # Tune the info structure
    chpi_channel = u'STI201'
    ncoil = len(info['hpi_results'][0]['order'])
    coil_freq = 10 + np.arange(ncoil) * 5
    hpi_subsystem = {'event_channel': chpi_channel,
                     'hpi_coils': [{'event_bits': np.array([256, 0, 256, 256],
                                                           dtype=np.int32)},
                                   {'event_bits': np.array([512, 0, 512, 512],
                                                           dtype=np.int32)},
                                   {'event_bits':
                                       np.array([1024, 0, 1024, 1024],
                                                dtype=np.int32)},
                                   {'event_bits':
                                       np.array([2048, 0, 2048, 2048],
                                                dtype=np.int32)}],
                     'ncoil': ncoil}

    info['hpi_subsystem'] = hpi_subsystem
    for l, freq in enumerate(coil_freq):
            info['hpi_meas'][0]['hpi_coils'][l]['coil_freq'] = freq
    picks = pick_types(info, meg=True, stim=True, eeg=False, exclude=[])
    info['sfreq'] = 100.  # this will speed it up a lot
    info = pick_info(info, picks)
    info['chs'][info['ch_names'].index('STI 001')]['ch_name'] = 'STI201'
    info._update_redundant()
    info['projs'] = []

    info_trans = info['dev_head_t']['trans'].copy()

    dev_head_pos_ini = np.concatenate([rot_to_quat(info_trans[:3, :3]),
                                      info_trans[:3, 3]])
    ez = np.array([0, 0, 1])  # Unit vector in z-direction of head coordinates

    # Define some constants
    duration = 30  # Time / s

    # Quotient of head position sampling frequency
    # and raw sampling frequency
    head_pos_sfreq_quotient = 0.1

    # Round number of head positions to the next integer
    S = int(duration / (info['sfreq'] * head_pos_sfreq_quotient))
    dz = 0.001  # Shift in z-direction is 0.1mm for each step

    dev_head_pos = np.zeros((S, 10))
    dev_head_pos[:, 0] = np.arange(S) * info['sfreq'] * head_pos_sfreq_quotient
    dev_head_pos[:, 1:4] = dev_head_pos_ini[:3]
    dev_head_pos[:, 4:7] = dev_head_pos_ini[3:] + \
        np.outer(np.arange(S) * dz, ez)
    dev_head_pos[:, 7] = 1.0

    # cm/s
    dev_head_pos[:, 9] = 100 * dz / (info['sfreq'] * head_pos_sfreq_quotient)

    # Round number of samples to the next integer
    raw_data = np.zeros((len(picks), int(duration * info['sfreq'] + 0.5)))
    raw = RawArray(raw_data, info)

    dip = Dipole(np.array([0.0, 0.1, 0.2]),
                 np.array([[0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]]),
                 np.array([1e-9, 1e-9, 1e-9]),
                 np.array([[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]]),
                 np.array([1.0, 1.0, 1.0]), 'dip')
    sphere = make_sphere_model('auto', 'auto', info=info,
                               relative_radii=(1.0, 0.9), sigmas=(0.33, 0.3))
    fwd, stc = make_forward_dipole(dip, sphere, info)
    stc.resample(info['sfreq'])
    raw = simulate_raw(raw, stc, None, fwd['src'], sphere, cov=None,
                       blink=False, ecg=False, chpi=True,
                       head_pos=dev_head_pos, mindist=1.0, interp='zero',
                       verbose=None, use_cps=True)

    quats = _calculate_chpi_positions(
        raw, t_step_min=raw.info['sfreq'] * head_pos_sfreq_quotient,
        t_step_max=raw.info['sfreq'] * head_pos_sfreq_quotient, t_window=1.0)
    _assert_quats(quats, dev_head_pos, dist_tol=0.001, angle_tol=1.)
예제 #4
0
def test_simulate_calculate_chpi_positions():
    """Test calculation of cHPI positions with simulated data."""
    # Read info dict from raw FIF file
    info = read_info(raw_fname)
    # Tune the info structure
    chpi_channel = u'STI201'
    ncoil = len(info['hpi_results'][0]['order'])
    coil_freq = 10 + np.arange(ncoil) * 5
    hpi_subsystem = {
        'event_channel':
        chpi_channel,
        'hpi_coils': [{
            'event_bits':
            np.array([256, 0, 256, 256], dtype=np.int32)
        }, {
            'event_bits':
            np.array([512, 0, 512, 512], dtype=np.int32)
        }, {
            'event_bits':
            np.array([1024, 0, 1024, 1024], dtype=np.int32)
        }, {
            'event_bits':
            np.array([2048, 0, 2048, 2048], dtype=np.int32)
        }],
        'ncoil':
        ncoil
    }

    info['hpi_subsystem'] = hpi_subsystem
    for l, freq in enumerate(coil_freq):
        info['hpi_meas'][0]['hpi_coils'][l]['coil_freq'] = freq
    picks = pick_types(info, meg=True, stim=True, eeg=False, exclude=[])
    info['sfreq'] = 100.  # this will speed it up a lot
    info = pick_info(info, picks)
    info['chs'][info['ch_names'].index('STI 001')]['ch_name'] = 'STI201'
    info._update_redundant()
    info['projs'] = []

    info_trans = info['dev_head_t']['trans'].copy()

    dev_head_pos_ini = np.concatenate(
        [rot_to_quat(info_trans[:3, :3]), info_trans[:3, 3]])
    ez = np.array([0, 0, 1])  # Unit vector in z-direction of head coordinates

    # Define some constants
    duration = 30  # Time / s

    # Quotient of head position sampling frequency
    # and raw sampling frequency
    head_pos_sfreq_quotient = 0.1

    # Round number of head positions to the next integer
    S = int(duration / (info['sfreq'] * head_pos_sfreq_quotient))
    dz = 0.001  # Shift in z-direction is 0.1mm for each step

    dev_head_pos = np.zeros((S, 10))
    dev_head_pos[:, 0] = np.arange(S) * info['sfreq'] * head_pos_sfreq_quotient
    dev_head_pos[:, 1:4] = dev_head_pos_ini[:3]
    dev_head_pos[:, 4:7] = dev_head_pos_ini[3:] + \
        np.outer(np.arange(S) * dz, ez)
    dev_head_pos[:, 7] = 1.0

    # cm/s
    dev_head_pos[:, 9] = 100 * dz / (info['sfreq'] * head_pos_sfreq_quotient)

    # Round number of samples to the next integer
    raw_data = np.zeros((len(picks), int(duration * info['sfreq'] + 0.5)))
    raw = RawArray(raw_data, info)

    dip = Dipole(np.array([0.0, 0.1, 0.2]),
                 np.array([[0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]]),
                 np.array([1e-9, 1e-9, 1e-9]),
                 np.array([[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]]),
                 np.array([1.0, 1.0, 1.0]), 'dip')
    sphere = make_sphere_model('auto',
                               'auto',
                               info=info,
                               relative_radii=(1.0, 0.9),
                               sigmas=(0.33, 0.3))
    fwd, stc = make_forward_dipole(dip, sphere, info)
    stc.resample(info['sfreq'])
    raw = simulate_raw(raw,
                       stc,
                       None,
                       fwd['src'],
                       sphere,
                       cov=None,
                       blink=False,
                       ecg=False,
                       chpi=True,
                       head_pos=dev_head_pos,
                       mindist=1.0,
                       interp='zero',
                       verbose=None)

    quats = _calculate_chpi_positions(
        raw,
        t_step_min=raw.info['sfreq'] * head_pos_sfreq_quotient,
        t_step_max=raw.info['sfreq'] * head_pos_sfreq_quotient,
        t_window=1.0)
    _assert_quats(quats, dev_head_pos, dist_tol=0.001, angle_tol=1.)
예제 #5
0
evoked_fit_left.info.normalize_proj()
evoked_fit_right.info.normalize_proj()
cov_fit_left['projs'] = evoked_fit_left.info['projs']
cov_fit_right['projs'] = evoked_fit_right.info['projs']

# Fit the dipoles with the subset of sensors.
dip_left, _ = mne.fit_dipole(evoked_fit_left, cov_fit_left, bem)
dip_right, _ = mne.fit_dipole(evoked_fit_right, cov_fit_right, bem)

###############################################################################
# Now that we have the location and orientations of the dipoles, compute the
# full timecourses using MNE, assigning activity to both dipoles at the same
# time while preventing leakage between the two. We use a very low ``lambda``
# value to ensure both dipoles are fully used.

fwd, _ = mne.make_forward_dipole([dip_left, dip_right], bem, info)

# Apply MNE inverse
inv = make_inverse_operator(info, fwd, cov, fixed=True, depth=0)
stc_left = apply_inverse(evoked_left, inv, method='MNE', lambda2=1E-6)
stc_right = apply_inverse(evoked_right, inv, method='MNE', lambda2=1E-6)

# Plot the timecourses of the resulting source estimate
fig, axes = plt.subplots(nrows=2, sharex=True, sharey=True)
axes[0].plot(stc_left.times, stc_left.data.T)
axes[0].set_title('Left auditory stimulation')
axes[0].legend(['Dipole 1', 'Dipole 2'])
axes[1].plot(stc_right.times, stc_right.data.T)
axes[1].set_title('Right auditory stimulation')
axes[1].set_xlabel('Time (s)')
fig.supylabel('Dipole amplitude')