Example #1
0
def run():
    t0 = time.time()
    parser = get_optparser(__file__)
    parser.add_option("--raw",
                      dest="raw_in",
                      help="Input raw FIF file",
                      metavar="FILE")
    parser.add_option("--pos",
                      dest="pos",
                      default=None,
                      help="Position definition text file. Can be 'constant' "
                      "to hold the head position fixed",
                      metavar="FILE")
    parser.add_option("--dipoles",
                      dest="dipoles",
                      default=None,
                      help="Dipole definition file",
                      metavar="FILE")
    parser.add_option("--cov",
                      dest="cov",
                      help="Covariance to use for noise generation. Can be "
                      "'simple' to use a diagonal covariance, or 'off' to "
                      "omit noise",
                      metavar="FILE",
                      default='simple')
    parser.add_option("--duration",
                      dest="duration",
                      default=None,
                      help="Duration of each epoch (sec). If omitted, the last"
                      " time point in the dipole definition file plus 200 ms "
                      "will be used",
                      type="float")
    parser.add_option("-j",
                      "--jobs",
                      dest="n_jobs",
                      help="Number of jobs to"
                      " run in parallel",
                      type="int",
                      default=1)
    parser.add_option("--out",
                      dest="raw_out",
                      help="Output raw filename",
                      metavar="FILE")
    parser.add_option("--plot-dipoles",
                      dest="plot_dipoles",
                      help="Plot "
                      "input dipole positions",
                      action="store_true")
    parser.add_option("--plot-raw",
                      dest="plot_raw",
                      help="Plot the resulting "
                      "raw traces",
                      action="store_true")
    parser.add_option("--plot-evoked",
                      dest="plot_evoked",
                      help="Plot evoked "
                      "data",
                      action="store_true")
    parser.add_option("-p",
                      "--plot",
                      dest="plot",
                      help="Plot dipoles, raw, "
                      "and evoked",
                      action="store_true")
    parser.add_option("--overwrite",
                      dest="overwrite",
                      help="Overwrite the"
                      "output file if it exists",
                      action="store_true")
    options, args = parser.parse_args()

    raw_in = options.raw_in
    pos = options.pos
    raw_out = options.raw_out
    dipoles = options.dipoles
    n_jobs = options.n_jobs
    plot = options.plot
    plot_dipoles = options.plot_dipoles or plot
    plot_raw = options.plot_raw or plot
    plot_evoked = options.plot_evoked or plot
    overwrite = options.overwrite
    duration = options.duration
    cov = options.cov

    # check parameters
    if not (raw_out or plot_raw or plot_evoked):
        raise ValueError('data must either be saved (--out) or '
                         'plotted (--plot-raw or --plot_evoked)')
    if raw_out and op.isfile(raw_out) and not overwrite:
        raise ValueError('output file exists, use --overwrite (%s)' % raw_out)

    if raw_in is None or pos is None or dipoles is None:
        parser.print_help()
        sys.exit(1)

    s = 'Simulate raw data with head movements'
    print('\n%s\n%s\n%s\n' % ('-' * len(s), s, '-' * len(s)))

    # setup the simulation

    with printer('Reading dipole definitions'):
        if not op.isfile(dipoles):
            raise IOError('dipole file not found:\n%s' % dipoles)
        dipoles = np.loadtxt(dipoles, skiprows=1, dtype=float)
        n_dipoles = dipoles.shape[0]
        if dipoles.shape[1] != 8:
            raise ValueError('dipoles must have 8 columns')
        rr = dipoles[:, :3] * 1e-3
        nn = dipoles[:, 3:6]
        t = dipoles[:, 6:8]
        duration = t.max() + 0.2 if duration is None else duration
        if (t[:, 0] > t[:, 1]).any():
            raise ValueError('found tmin > tmax in dipole file')
        if (t < 0).any():
            raise ValueError('found t < 0 in dipole file')
        if (t > duration).any():
            raise ValueError('found t > duration in dipole file')
        amp = np.sqrt(np.sum(nn * nn, axis=1)) * 1e-9
        mne.surface._normalize_vectors(nn)
        nn[(nn == 0).all(axis=1)] = (1, 0, 0)
        src = mne.SourceSpaces([
            dict(rr=rr,
                 nn=nn,
                 inuse=np.ones(n_dipoles, int),
                 coord_frame=FIFF.FIFFV_COORD_HEAD)
        ])
        for key in ['pinfo', 'nuse_tri', 'use_tris', 'patch_inds']:
            src[0][key] = None
        trans = {
            'from': FIFF.FIFFV_COORD_HEAD,
            'to': FIFF.FIFFV_COORD_MRI,
            'trans': np.eye(4)
        }
        if (amp > 100e-9).any():
            print('')
            warnings.warn('Largest dipole amplitude %0.1f > 100 nA' %
                          (amp.max() * 1e9))

    if pos == 'constant':
        print('Holding head position constant')
        pos = None
    else:
        with printer('Loading head positions'):
            pos = mne.get_chpi_positions(pos)

    with printer('Loading raw data file'):
        with warnings.catch_warnings(record=True):
            raw = mne.io.Raw(raw_in,
                             preload=False,
                             allow_maxshield=True,
                             verbose=False)

    if cov == 'simple':
        print('Using diagonal covariance for brain noise')
    elif cov == 'off':
        print('Omitting brain noise in the simulation')
        cov = None
    else:
        with printer('Loading covariance file for brain noise'):
            cov = mne.read_cov(cov)

    with printer('Setting up spherical model'):
        bem = mne.bem.make_sphere_model('auto',
                                        'auto',
                                        raw.info,
                                        verbose=False)
        # check that our sources are reasonable
        rad = bem['layers'][0]['rad']
        r0 = bem['r0']
        outside = np.sqrt(np.sum((rr - r0)**2, axis=1)) >= rad
        n_outside = outside.sum()
        if n_outside > 0:
            print('')
            raise ValueError(
                '%s dipole%s outside the spherical model, are your positions '
                'in mm?' % (n_outside, 's were' if n_outside != 1 else ' was'))

    with printer('Constructing source estimate'):
        tmids = t.mean(axis=1)
        t = np.round(t * raw.info['sfreq']).astype(int)
        t[:, 1] += 1  # make it inclusive
        n_samp = int(np.ceil(duration * raw.info['sfreq']))
        data = np.zeros((n_dipoles, n_samp))
        for di, (t_, amp_) in enumerate(zip(t, amp)):
            data[di, t_[0]:t_[1]] = amp_ * np.hanning(t_[1] - t_[0])
        stc = mne.VolSourceEstimate(data, np.arange(n_dipoles), 0,
                                    1. / raw.info['sfreq'])

    # do the simulation
    print('')
    raw_mv = simulate_raw(raw,
                          stc,
                          trans,
                          src,
                          bem,
                          cov=cov,
                          head_pos=pos,
                          chpi=True,
                          n_jobs=n_jobs,
                          verbose=True)
    print('')

    if raw_out:
        with printer('Saving data'):
            raw_mv.save(raw_out, overwrite=overwrite)

    # plot results -- must be *after* save because we low-pass filter
    if plot_dipoles:
        with printer('Plotting dipoles'):
            fig, axs = plt.subplots(1, 3, figsize=(10, 3), facecolor='w')
            fig.canvas.set_window_title('Dipoles')
            meg_info = mne.pick_info(
                raw.info, mne.pick_types(raw.info, meg=True, eeg=False))
            helmet_rr = [
                ch['coil_trans'][:3, 3].copy() for ch in meg_info['chs']
            ]
            helmet_nn = np.zeros_like(helmet_rr)
            helmet_nn[:, 2] = 1.
            surf = dict(rr=helmet_rr,
                        nn=helmet_nn,
                        coord_frame=FIFF.FIFFV_COORD_DEVICE)
            helmet_rr = mne.surface.transform_surface_to(
                surf, 'head', meg_info['dev_head_t'])['rr']
            p = np.linspace(0, 2 * np.pi, 40)
            x_sphere, y_sphere = rad * np.sin(p), rad * np.cos(p)
            for ai, ax in enumerate(axs):
                others = np.setdiff1d(np.arange(3), [ai])
                ax.plot(helmet_rr[:, others[0]],
                        helmet_rr[:, others[1]],
                        marker='o',
                        linestyle='none',
                        alpha=0.1,
                        markeredgecolor='none',
                        markerfacecolor='b',
                        zorder=-2)
                ax.plot(x_sphere + r0[others[0]],
                        y_sphere + r0[others[1]],
                        color='y',
                        alpha=0.25,
                        zorder=-1)
                ax.quiver(rr[:, others[0]],
                          rr[:, others[1]],
                          amp * nn[:, others[0]],
                          amp * nn[:, others[1]],
                          angles='xy',
                          units='x',
                          color='k',
                          alpha=0.5)
                ax.set_aspect('equal')
                ax.set_xlabel(' - ' + 'xyz'[others[0]] + ' + ')
                ax.set_ylabel(' - ' + 'xyz'[others[1]] + ' + ')
                ax.set_xticks([])
                ax.set_yticks([])
                plt.setp(list(ax.spines.values()), color='none')
            plt.tight_layout()

    if plot_raw or plot_evoked:
        with printer('Low-pass filtering simulated data'):
            events = mne.find_events(raw_mv, 'STI101', verbose=False)
            b, a = signal.butter(4,
                                 40. / (raw.info['sfreq'] / 2.),
                                 'low',
                                 analog=False)
            raw_mv.filter(None,
                          40.,
                          method='iir',
                          iir_params=dict(b=b, a=a),
                          verbose=False,
                          n_jobs=n_jobs)
        if plot_raw:
            with printer('Plotting raw data'):
                raw_mv.plot(clipping='transparent', events=events, show=False)
        if plot_evoked:
            with printer('Plotting evoked data'):
                picks = mne.pick_types(raw_mv.info, meg=True, eeg=True)
                events[:, 2] = 1
                evoked = mne.Epochs(raw_mv, events, {
                    'Simulated': 1
                }, 0, duration, None, picks).average()
                evoked.plot_topomap(np.unique(tmids), show=False)

    print('\nTotal time: %0.1f sec' % (time.time() - t0))
    sys.stdout.flush()
    if any([plot_dipoles, plot_raw, plot_evoked]):
        plt.show(block=True)
Example #2
0
def run():
    t0 = time.time()
    parser = get_optparser(__file__)
    parser.add_option("--raw", dest="raw_in",
                      help="Input raw FIF file", metavar="FILE")
    parser.add_option("--pos", dest="pos", default=None,
                      help="Position definition text file. Can be 'constant' "
                      "to hold the head position fixed", metavar="FILE")
    parser.add_option("--dipoles", dest="dipoles", default=None,
                      help="Dipole definition file", metavar="FILE")
    parser.add_option("--cov", dest="cov",
                      help="Covariance to use for noise generation. Can be "
                      "'simple' to use a diagonal covariance, or 'off' to "
                      "omit noise",
                      metavar="FILE", default='simple')
    parser.add_option("--duration", dest="duration", default=None,
                      help="Duration of each epoch (sec). If omitted, the last"
                      " time point in the dipole definition file plus 200 ms "
                      "will be used", type="float")
    parser.add_option("-j", "--jobs", dest="n_jobs", help="Number of jobs to"
                      " run in parallel", type="int", default=1)
    parser.add_option("--out", dest="raw_out",
                      help="Output raw filename", metavar="FILE")
    parser.add_option("--plot-dipoles", dest="plot_dipoles", help="Plot "
                      "input dipole positions", action="store_true")
    parser.add_option("--plot-raw", dest="plot_raw", help="Plot the resulting "
                      "raw traces", action="store_true")
    parser.add_option("--plot-evoked", dest="plot_evoked", help="Plot evoked "
                      "data", action="store_true")
    parser.add_option("-p", "--plot", dest="plot", help="Plot dipoles, raw, "
                      "and evoked", action="store_true")
    parser.add_option("--overwrite", dest="overwrite", help="Overwrite the"
                      "output file if it exists", action="store_true")
    options, args = parser.parse_args()

    raw_in = options.raw_in
    pos = options.pos
    raw_out = options.raw_out
    dipoles = options.dipoles
    n_jobs = options.n_jobs
    plot = options.plot
    plot_dipoles = options.plot_dipoles or plot
    plot_raw = options.plot_raw or plot
    plot_evoked = options.plot_evoked or plot
    overwrite = options.overwrite
    duration = options.duration
    cov = options.cov

    # check parameters
    if not (raw_out or plot_raw or plot_evoked):
        raise ValueError('data must either be saved (--out) or '
                         'plotted (--plot-raw or --plot_evoked)')
    if raw_out and op.isfile(raw_out) and not overwrite:
        raise ValueError('output file exists, use --overwrite (%s)' % raw_out)

    if raw_in is None or pos is None or dipoles is None:
        parser.print_help()
        sys.exit(1)

    s = 'Simulate raw data with head movements'
    print('\n%s\n%s\n%s\n' % ('-' * len(s), s, '-' * len(s)))

    # setup the simulation

    with printer('Reading dipole definitions'):
        if not op.isfile(dipoles):
            raise IOError('dipole file not found:\n%s' % dipoles)
        dipoles = np.loadtxt(dipoles, skiprows=1, dtype=float)
        n_dipoles = dipoles.shape[0]
        if dipoles.shape[1] != 8:
            raise ValueError('dipoles must have 8 columns')
        rr = dipoles[:, :3] * 1e-3
        nn = dipoles[:, 3:6]
        t = dipoles[:, 6:8]
        duration = t.max() + 0.2 if duration is None else duration
        if (t[:, 0] > t[:, 1]).any():
            raise ValueError('found tmin > tmax in dipole file')
        if (t < 0).any():
            raise ValueError('found t < 0 in dipole file')
        if (t > duration).any():
            raise ValueError('found t > duration in dipole file')
        amp = np.sqrt(np.sum(nn * nn, axis=1)) * 1e-9
        mne.surface._normalize_vectors(nn)
        nn[(nn == 0).all(axis=1)] = (1, 0, 0)
        src = mne.SourceSpaces([
            dict(rr=rr, nn=nn, inuse=np.ones(n_dipoles, int),
                 coord_frame=FIFF.FIFFV_COORD_HEAD)])
        for key in ['pinfo', 'nuse_tri', 'use_tris', 'patch_inds']:
            src[0][key] = None
        trans = {'from': FIFF.FIFFV_COORD_HEAD, 'to': FIFF.FIFFV_COORD_MRI,
                 'trans': np.eye(4)}
        if (amp > 100e-9).any():
            print('')
            warnings.warn('Largest dipole amplitude %0.1f > 100 nA'
                          % (amp.max() * 1e9))

    if pos == 'constant':
        print('Holding head position constant')
        pos = None
    else:
        with printer('Loading head positions'):
            pos = mne.get_chpi_positions(pos)

    with printer('Loading raw data file'):
        with warnings.catch_warnings(record=True):
            raw = mne.io.Raw(raw_in, preload=False, allow_maxshield=True,
                             verbose=False)

    if cov == 'simple':
        print('Using diagonal covariance for brain noise')
    elif cov == 'off':
        print('Omitting brain noise in the simulation')
        cov = None
    else:
        with printer('Loading covariance file for brain noise'):
            cov = mne.read_cov(cov)

    with printer('Setting up spherical model'):
        bem = mne.bem.make_sphere_model('auto', 'auto', raw.info,
                                        verbose=False)
        # check that our sources are reasonable
        rad = bem['layers'][0]['rad']
        r0 = bem['r0']
        outside = np.sqrt(np.sum((rr - r0) ** 2, axis=1)) >= rad
        n_outside = outside.sum()
        if n_outside > 0:
            print('')
            raise ValueError(
                '%s dipole%s outside the spherical model, are your positions '
                'in mm?' % (n_outside, 's were' if n_outside != 1 else ' was'))

    with printer('Constructing source estimate'):
        tmids = t.mean(axis=1)
        t = np.round(t * raw.info['sfreq']).astype(int)
        t[:, 1] += 1  # make it inclusive
        n_samp = int(np.ceil(duration * raw.info['sfreq']))
        data = np.zeros((n_dipoles, n_samp))
        for di, (t_, amp_) in enumerate(zip(t, amp)):
            data[di, t_[0]:t_[1]] = amp_ * np.hanning(t_[1] - t_[0])
        stc = mne.VolSourceEstimate(data, np.arange(n_dipoles),
                                    0, 1. / raw.info['sfreq'])

    # do the simulation
    print('')
    raw_mv = simulate_raw(raw, stc, trans, src, bem, cov=cov, head_pos=pos,
                          chpi=True, n_jobs=n_jobs, verbose=True)
    print('')

    if raw_out:
        with printer('Saving data'):
            raw_mv.save(raw_out, overwrite=overwrite)

    # plot results -- must be *after* save because we low-pass filter
    if plot_dipoles:
        with printer('Plotting dipoles'):
            fig, axs = plt.subplots(1, 3, figsize=(10, 3), facecolor='w')
            fig.canvas.set_window_title('Dipoles')
            meg_info = mne.pick_info(raw.info,
                                     mne.pick_types(raw.info,
                                                    meg=True, eeg=False))
            helmet_rr = [ch['coil_trans'][:3, 3].copy()
                         for ch in meg_info['chs']]
            helmet_nn = np.zeros_like(helmet_rr)
            helmet_nn[:, 2] = 1.
            surf = dict(rr=helmet_rr, nn=helmet_nn,
                        coord_frame=FIFF.FIFFV_COORD_DEVICE)
            helmet_rr = mne.surface.transform_surface_to(
                surf, 'head', meg_info['dev_head_t'])['rr']
            p = np.linspace(0, 2 * np.pi, 40)
            x_sphere, y_sphere = rad * np.sin(p), rad * np.cos(p)
            for ai, ax in enumerate(axs):
                others = np.setdiff1d(np.arange(3), [ai])
                ax.plot(helmet_rr[:, others[0]], helmet_rr[:, others[1]],
                        marker='o', linestyle='none', alpha=0.1,
                        markeredgecolor='none', markerfacecolor='b', zorder=-2)
                ax.plot(x_sphere + r0[others[0]], y_sphere + r0[others[1]],
                        color='y', alpha=0.25, zorder=-1)
                ax.quiver(rr[:, others[0]], rr[:, others[1]],
                          amp * nn[:, others[0]], amp * nn[:, others[1]],
                          angles='xy', units='x', color='k', alpha=0.5)
                ax.set_aspect('equal')
                ax.set_xlabel(' - ' + 'xyz'[others[0]] + ' + ')
                ax.set_ylabel(' - ' + 'xyz'[others[1]] + ' + ')
                ax.set_xticks([])
                ax.set_yticks([])
                plt.setp(list(ax.spines.values()), color='none')
            plt.tight_layout()

    if plot_raw or plot_evoked:
        with printer('Low-pass filtering simulated data'):
            events = mne.find_events(raw_mv, 'STI101', verbose=False)
            b, a = signal.butter(4, 40. / (raw.info['sfreq'] / 2.), 'low',
                                 analog=False)
            raw_mv.filter(None, 40., method='iir', iir_params=dict(b=b, a=a),
                          verbose=False, n_jobs=n_jobs)
        if plot_raw:
            with printer('Plotting raw data'):
                raw_mv.plot(clipping='transparent', events=events,
                            show=False)
        if plot_evoked:
            with printer('Plotting evoked data'):
                picks = mne.pick_types(raw_mv.info, meg=True, eeg=True)
                events[:, 2] = 1
                evoked = mne.Epochs(raw_mv, events, {'Simulated': 1},
                                    0, duration, None, picks).average()
                evoked.plot_topomap(np.unique(tmids), show=False)

    print('\nTotal time: %0.1f sec' % (time.time() - t0))
    sys.stdout.flush()
    if any([plot_dipoles, plot_raw, plot_evoked]):
        plt.show(block=True)
Example #3
0
# ############################################################################
# Simulate data

# Simulate data with movement
with warnings.catch_warnings(record=True):
    raw = Raw(fname_raw, allow_maxshield=True)
raw_movement = simulate_movement(raw, fname_pos_orig, stc, trans, src, bem,
                                 interp='zero', n_jobs=6, verbose=True)

# Simulate data with no movement (use initial head position)
raw_stationary = simulate_movement(raw, None, stc, trans, src, bem,
                                   interp='zero', n_jobs=6, verbose=True)

# Extract positions
trans_move, rot_move, t_move = get_chpi_positions(fname_pos_move)
trans_stat, rot_stat, t_stat = get_chpi_positions(fname_pos_stat)
trans_orig, rot_orig, t_orig = get_chpi_positions(fname_pos_orig)

# ############################################################################
# Let's look at the results, just translation for simplicity

axes = 'XYZ'
fig = plt.figure(dpi=200)
ts = [t_orig, t_stat, t_move]
transs = [trans_orig, trans_stat, trans_move]
labels = ['original', 'stationary', 'simulated']
sizes = [10, 5, 5]
colors = 'kyr'
for ai, axis in enumerate(axes):
    ax = plt.subplot(3, 1, ai + 1)
Example #4
0
def simulate_movement(raw, pos, stc, trans, src, bem, cov='simple',
                      mindist=1.0, interp='linear', random_state=None,
                      n_jobs=1, verbose=None):
    """Simulate raw data with head movements

    Parameters
    ----------
    raw : instance of Raw
        The raw instance to use. The measurement info, including the
        head positions, will be used to simulate data.
    pos : str | dict | None
        Name of the position estimates file. Should be in the format of
        the files produced by maxfilter-produced. If dict, keys should
        be the time points and entries should be 4x3 ``dev_head_t``
        matrices. If None, the original head position (from
        ``raw.info['dev_head_t']``) will be used.
    stc : instance of SourceEstimate
        The source estimate to use to simulate data. Must have the same
        sample rate as the raw data.
    trans : dict | str
        Either a transformation filename (usually made using mne_analyze)
        or an info dict (usually opened using read_trans()).
        If string, an ending of `.fif` or `.fif.gz` will be assumed to
        be in FIF format, any other ending will be assumed to be a text
        file with a 4x4 transformation matrix (like the `--trans` MNE-C
        option).
    src : str | instance of SourceSpaces
        If string, should be a source space filename. Can also be an
        instance of loaded or generated SourceSpaces.
    bem : str
        Filename of the BEM (e.g., "sample-5120-5120-5120-bem-sol.fif").
    cov : instance of Covariance | 'simple' | None
        The sensor covariance matrix used to generate noise. If None,
        no noise will be added. If 'simple', a basic (diagonal) ad-hoc
        noise covariance will be used.
    mindist : float
        Minimum distance between sources and the inner skull boundary
        to use during forward calculation.
    interp : str
        Either 'linear' or 'zero', the type of forward-solution
        interpolation to use between provided time points.
    random_state : None | int | np.random.RandomState
        To specify the random generator state.
    n_jobs : int
        Number of jobs to use.
    verbose : bool, str, int, or None
        If not None, override default verbose level (see mne.verbose).

    Returns
    -------
    raw : instance of Raw
        The simulated raw file.

    Notes
    -----
    Events coded with the number of the forward solution used will be placed
    in the raw files in the trigger channel STI101 at the t=0 times of the
    SourceEstimates.

    The resulting SNR will be determined by the structure of the noise
    covariance, and the amplitudes of the SourceEstimate. Note that this
    will vary as a function of position.
    """
    if isinstance(raw, string_types):
        with warnings.catch_warnings(record=True):
            raw = Raw(raw, allow_maxshield=True, preload=True, verbose=False)
    else:
        raw = raw.copy()

    if not isinstance(stc, _BaseSourceEstimate):
        raise TypeError('stc must be a SourceEstimate')
    if not np.allclose(raw.info['sfreq'], 1. / stc.tstep):
        raise ValueError('stc and raw must have same sample rate')
    rng = check_random_state(random_state)
    if interp not in ('linear', 'zero'):
        raise ValueError('interp must be "linear" or "zero"')

    if pos is None:  # use pos from file
        dev_head_ts = [raw.info['dev_head_t']] * 2
        offsets = np.array([0, raw.n_times])
        interp = 'zero'
    else:
        if isinstance(pos, string_types):
            pos = get_chpi_positions(pos, verbose=False)
        if isinstance(pos, tuple):  # can be an already-loaded pos file
            transs, rots, ts = pos
            ts -= raw.first_samp / raw.info['sfreq']  # MF files need reref
            dev_head_ts = [np.r_[np.c_[r, t[:, np.newaxis]], [[0, 0, 0, 1]]]
                           for r, t in zip(rots, transs)]
            del transs, rots
        elif isinstance(pos, dict):
            ts = np.array(list(pos.keys()), float)
            ts.sort()
            dev_head_ts = [pos[float(tt)] for tt in ts]
        else:
            raise TypeError('unknown pos type %s' % type(pos))
        if not (ts >= 0).all():  # pathological if not
            raise RuntimeError('Cannot have t < 0 in transform file')
        tend = raw.times[-1]
        assert not (ts < 0).any()
        assert not (ts > tend).any()
        if ts[0] > 0:
            ts = np.r_[[0.], ts]
            dev_head_ts.insert(0, raw.info['dev_head_t']['trans'])
        dev_head_ts = [{'trans': d, 'to': raw.info['dev_head_t']['to'],
                        'from': raw.info['dev_head_t']['from']}
                       for d in dev_head_ts]
        if ts[-1] < tend:
            dev_head_ts.append(dev_head_ts[-1])
            ts = np.r_[ts, [tend]]
        offsets = raw.time_as_index(ts)
        offsets[-1] = raw.n_times  # fix for roundoff error
        assert offsets[-2] != offsets[-1]
        del ts
    if isinstance(cov, string_types):
        assert cov == 'simple'
        cov = make_ad_hoc_cov(raw.info, verbose=False)
    assert np.array_equal(offsets, np.unique(offsets))
    assert len(offsets) == len(dev_head_ts)
    approx_events = int((raw.n_times / raw.info['sfreq']) /
                        (stc.times[-1] - stc.times[0]))
    logger.info('Provided parameters will provide approximately %s event%s'
                % (approx_events, '' if approx_events == 1 else 's'))

    # get HPI freqs and reorder
    hpi_freqs = np.array([x['custom_ref'][0]
                          for x in raw.info['hpi_meas'][0]['hpi_coils']])
    n_freqs = len(hpi_freqs)
    order = [x['number'] - 1 for x in raw.info['hpi_meas'][0]['hpi_coils']]
    assert np.array_equal(np.unique(order), np.arange(n_freqs))
    hpi_freqs = hpi_freqs[order]
    hpi_order = raw.info['hpi_results'][0]['order'] - 1
    assert np.array_equal(np.unique(hpi_order), np.arange(n_freqs))
    hpi_freqs = hpi_freqs[hpi_order]

    # extract necessary info
    picks = pick_types(raw.info, meg=True, eeg=True)  # for simulation
    meg_picks = pick_types(raw.info, meg=True, eeg=False)  # for CHPI
    fwd_info = pick_info(raw.info, picks)
    fwd_info['projs'] = []
    logger.info('Setting up raw data simulation using %s head position%s'
                % (len(dev_head_ts), 's' if len(dev_head_ts) != 1 else ''))
    raw.preload_data(verbose=False)

    if isinstance(stc, VolSourceEstimate):
        verts = [stc.vertices]
    else:
        verts = stc.vertices
    src = _restrict_source_space_to(src, verts)

    # figure out our cHPI, ECG, and EOG dipoles
    dig = raw.info['dig']
    assert all([d['coord_frame'] == FIFF.FIFFV_COORD_HEAD
                for d in dig if d['kind'] == FIFF.FIFFV_POINT_HPI])
    chpi_rrs = [d['r'] for d in dig if d['kind'] == FIFF.FIFFV_POINT_HPI]
    R, r0 = fit_sphere_to_headshape(raw.info, verbose=False)[:2]
    R /= 1000.
    r0 /= 1000.
    ecg_rr = np.array([[-R, 0, -3 * R]])
    eog_rr = [d['r'] for d in raw.info['dig']
              if d['ident'] == FIFF.FIFFV_POINT_NASION][0]
    eog_rr = eog_rr - r0
    eog_rr = (eog_rr / np.sqrt(np.sum(eog_rr * eog_rr)) *
              0.98 * R)[np.newaxis, :]
    eog_rr += r0
    eog_bem = make_sphere_model(r0, head_radius=R, relative_radii=(0.99, 1.),
                                sigmas=(0.33, 0.33), verbose=False)
    # let's oscillate between resting (17 bpm) and reading (4.5 bpm) rate
    # http://www.ncbi.nlm.nih.gov/pubmed/9399231
    blink_rate = np.cos(2 * np.pi * 1. / 60. * raw.times)
    blink_rate *= 12.5 / 60.
    blink_rate += 4.5 / 60.
    blink_data = rng.rand(raw.n_times) < blink_rate / raw.info['sfreq']
    blink_data = blink_data * (rng.rand(raw.n_times) + 0.5)  # vary amplitudes
    blink_kernel = np.hanning(int(0.25 * raw.info['sfreq']))
    eog_data = np.convolve(blink_data, blink_kernel, 'same')[np.newaxis, :]
    eog_data += rng.randn(eog_data.shape[1]) * 0.05
    eog_data *= 100e-6
    del blink_data,

    max_beats = int(np.ceil(raw.times[-1] * 70. / 60.))
    cardiac_idx = np.cumsum(rng.uniform(60. / 70., 60. / 50., max_beats) *
                            raw.info['sfreq']).astype(int)
    cardiac_idx = cardiac_idx[cardiac_idx < raw.n_times]
    cardiac_data = np.zeros(raw.n_times)
    cardiac_data[cardiac_idx] = 1
    cardiac_kernel = np.concatenate([
        2 * np.hanning(int(0.04 * raw.info['sfreq'])),
        -0.3 * np.hanning(int(0.05 * raw.info['sfreq'])),
        0.2 * np.hanning(int(0.26 * raw.info['sfreq']))], axis=-1)
    ecg_data = np.convolve(cardiac_data, cardiac_kernel, 'same')[np.newaxis, :]
    ecg_data += rng.randn(ecg_data.shape[1]) * 0.05
    ecg_data *= 3e-4
    del cardiac_data

    # Add to data file, then rescale for simulation
    for data, scale, exg_ch in zip([eog_data, ecg_data],
                                   [1e-3, 5e-4],
                                   ['EOG062', 'ECG063']):
        ch = pick_channels(raw.ch_names, [exg_ch])
        if len(ch) == 1:
            raw._data[ch[0], :] = data
        data *= scale

    evoked = EvokedArray(np.zeros((len(picks), len(stc.times))), fwd_info,
                         stc.tmin, verbose=False)
    stc_event_idx = np.argmin(np.abs(stc.times))
    event_ch = pick_channels(raw.info['ch_names'], ['STI101'])[0]
    used = np.zeros(raw.n_times, bool)
    stc_indices = np.arange(raw.n_times) % len(stc.times)
    raw._data[event_ch, ].fill(0)
    hpi_mag = 25e-9
    last_fwd = last_fwd_chpi = last_fwd_eog = last_fwd_ecg = src_sel = None
    for fi, (fwd, fwd_eog, fwd_ecg, fwd_chpi) in \
        enumerate(_make_forward_solutions(
            fwd_info, trans, src, bem, eog_bem, dev_head_ts, mindist,
            chpi_rrs, eog_rr, ecg_rr, n_jobs)):
        # must be fixed orientation
        fwd = convert_forward_solution(fwd, surf_ori=True,
                                       force_fixed=True, verbose=False)
        # just use one arbitrary direction
        fwd_eog = fwd_eog['sol']['data'][:, ::3]
        fwd_ecg = fwd_ecg['sol']['data'][:, ::3]
        fwd_chpi = fwd_chpi[:, ::3]

        if src_sel is None:
            src_sel = _stc_src_sel(fwd['src'], stc)
            if isinstance(stc, VolSourceEstimate):
                verts = [stc.vertices]
            else:
                verts = stc.vertices
            diff_ = sum([len(v) for v in verts]) - len(src_sel)
            if diff_ != 0:
                warnings.warn('%s STC vertices omitted due to fwd calculation'
                              % (diff_,))
        if last_fwd is None:
            last_fwd, last_fwd_eog, last_fwd_ecg, last_fwd_chpi = \
                fwd, fwd_eog, fwd_ecg, fwd_chpi
            continue
        n_time = offsets[fi] - offsets[fi-1]

        time_slice = slice(offsets[fi-1], offsets[fi])
        assert not used[time_slice].any()
        stc_idxs = stc_indices[time_slice]
        event_idxs = np.where(stc_idxs == stc_event_idx)[0] + offsets[fi-1]
        used[time_slice] = True
        logger.info('  Simulating data for %0.3f-%0.3f sec with %s event%s'
                    % (tuple(offsets[fi-1:fi+1] / raw.info['sfreq']) +
                       (len(event_idxs), '' if len(event_idxs) == 1 else 's')))

        # simulate brain data
        stc_data = stc.data[:, stc_idxs][src_sel]
        data = _interp(last_fwd['sol']['data'], fwd['sol']['data'],
                       stc_data, interp)
        simulated = EvokedArray(data, evoked.info, 0)
        if cov is not None:
            noise = generate_noise_evoked(simulated, cov, [1, -1, 0.2], rng)
            simulated.data += noise.data
        assert simulated.data.shape[0] == len(picks)
        assert simulated.data.shape[1] == len(stc_idxs)
        raw._data[picks, time_slice] = simulated.data

        # add ECG, EOG, and CHPI traces
        raw._data[picks, time_slice] += \
            _interp(last_fwd_eog, fwd_eog, eog_data[:, time_slice], interp)
        raw._data[meg_picks, time_slice] += \
            _interp(last_fwd_ecg, fwd_ecg, ecg_data[:, time_slice], interp)
        this_t = np.arange(offsets[fi-1], offsets[fi]) / raw.info['sfreq']
        sinusoids = np.zeros((n_freqs, n_time))
        for fi, freq in enumerate(hpi_freqs):
            sinusoids[fi] = 2 * np.pi * freq * this_t
            sinusoids[fi] = hpi_mag * np.sin(sinusoids[fi])
        raw._data[meg_picks, time_slice] += \
            _interp(last_fwd_chpi, fwd_chpi, sinusoids, interp)

        # add events
        raw._data[event_ch, event_idxs] = fi

        # prepare for next iteration
        last_fwd, last_fwd_eog, last_fwd_ecg, last_fwd_chpi = \
            fwd, fwd_eog, fwd_ecg, fwd_chpi
    assert used.all()
    logger.info('Done')
    return raw
Example #5
0
                            head_pos=fname_pos_orig,
                            n_jobs=6,
                            verbose=True)

# Simulate data with no movement (use initial head position)
raw_stationary = simulate_raw(raw,
                              stc,
                              trans,
                              src,
                              bem,
                              chpi=True,
                              n_jobs=6,
                              verbose=True)

# Extract positions
trans_orig, rot_orig, t_orig = get_chpi_positions(fname_pos_orig)
t_orig -= raw.first_samp / raw.info['sfreq']
trans_move, rot_move, t_move = _calculate_chpi_positions(raw_movement)
trans_stat, rot_stat, t_stat = _calculate_chpi_positions(raw_stationary)

# ############################################################################
# Let's look at the results, just translation for simplicity

axes = 'XYZ'
fig = plt.figure(dpi=200)
ts = [t_orig, t_stat, t_move]
transs = [trans_orig, trans_stat, trans_move]
labels = ['original', 'stationary', 'simulated']
sizes = [10, 5, 5]
colors = 'kyr'
for ai, axis in enumerate(axes):
Example #6
0
                                 n_jobs=6,
                                 verbose=True)

# Simulate data with no movement (use initial head position)
raw_stationary = simulate_movement(raw,
                                   None,
                                   stc,
                                   trans,
                                   src,
                                   bem,
                                   interp='zero',
                                   n_jobs=6,
                                   verbose=True)

# Extract positions
trans_move, rot_move, t_move = get_chpi_positions(fname_pos_move)
trans_stat, rot_stat, t_stat = get_chpi_positions(fname_pos_stat)
trans_orig, rot_orig, t_orig = get_chpi_positions(fname_pos_orig)

# ############################################################################
# Let's look at the results, just translation for simplicity

axes = 'XYZ'
fig = plt.figure(dpi=200)
ts = [t_orig, t_stat, t_move]
transs = [trans_orig, trans_stat, trans_move]
labels = ['original', 'stationary', 'simulated']
sizes = [10, 5, 5]
colors = 'kyr'
for ai, axis in enumerate(axes):
    ax = plt.subplot(3, 1, ai + 1)
Example #7
0
def simulate_movement(raw,
                      pos,
                      stc,
                      trans,
                      src,
                      bem,
                      cov='simple',
                      mindist=1.0,
                      interp='linear',
                      random_state=None,
                      n_jobs=1,
                      verbose=None):
    """Simulate raw data with head movements

    Parameters
    ----------
    raw : instance of Raw
        The raw instance to use. The measurement info, including the
        head positions, will be used to simulate data.
    pos : str | dict | None
        Name of the position estimates file. Should be in the format of
        the files produced by maxfilter-produced. If dict, keys should
        be the time points and entries should be 4x3 ``dev_head_t``
        matrices. If None, the original head position (from
        ``raw.info['dev_head_t']``) will be used.
    stc : instance of SourceEstimate
        The source estimate to use to simulate data. Must have the same
        sample rate as the raw data.
    trans : dict | str
        Either a transformation filename (usually made using mne_analyze)
        or an info dict (usually opened using read_trans()).
        If string, an ending of `.fif` or `.fif.gz` will be assumed to
        be in FIF format, any other ending will be assumed to be a text
        file with a 4x4 transformation matrix (like the `--trans` MNE-C
        option).
    src : str | instance of SourceSpaces
        If string, should be a source space filename. Can also be an
        instance of loaded or generated SourceSpaces.
    bem : str
        Filename of the BEM (e.g., "sample-5120-5120-5120-bem-sol.fif").
    cov : instance of Covariance | 'simple' | None
        The sensor covariance matrix used to generate noise. If None,
        no noise will be added. If 'simple', a basic (diagonal) ad-hoc
        noise covariance will be used.
    mindist : float
        Minimum distance between sources and the inner skull boundary
        to use during forward calculation.
    interp : str
        Either 'linear' or 'zero', the type of forward-solution
        interpolation to use between provided time points.
    random_state : None | int | np.random.RandomState
        To specify the random generator state.
    n_jobs : int
        Number of jobs to use.
    verbose : bool, str, int, or None
        If not None, override default verbose level (see mne.verbose).

    Returns
    -------
    raw : instance of Raw
        The simulated raw file.

    Notes
    -----
    Events coded with the number of the forward solution used will be placed
    in the raw files in the trigger channel STI101 at the t=0 times of the
    SourceEstimates.

    The resulting SNR will be determined by the structure of the noise
    covariance, and the amplitudes of the SourceEstimate. Note that this
    will vary as a function of position.
    """
    if isinstance(raw, string_types):
        with warnings.catch_warnings(record=True):
            raw = Raw(raw, allow_maxshield=True, preload=True, verbose=False)
    else:
        raw = raw.copy()

    if not isinstance(stc, _BaseSourceEstimate):
        raise TypeError('stc must be a SourceEstimate')
    if not np.allclose(raw.info['sfreq'], 1. / stc.tstep):
        raise ValueError('stc and raw must have same sample rate')
    rng = check_random_state(random_state)
    if interp not in ('linear', 'zero'):
        raise ValueError('interp must be "linear" or "zero"')

    if pos is None:  # use pos from file
        dev_head_ts = [raw.info['dev_head_t']] * 2
        offsets = np.array([0, raw.n_times])
        interp = 'zero'
    else:
        if isinstance(pos, string_types):
            pos = get_chpi_positions(pos, verbose=False)
        if isinstance(pos, tuple):  # can be an already-loaded pos file
            transs, rots, ts = pos
            ts -= raw.first_samp / raw.info['sfreq']  # MF files need reref
            dev_head_ts = [
                np.r_[np.c_[r, t[:, np.newaxis]], [[0, 0, 0, 1]]]
                for r, t in zip(rots, transs)
            ]
            del transs, rots
        elif isinstance(pos, dict):
            ts = np.array(list(pos.keys()), float)
            ts.sort()
            dev_head_ts = [pos[float(tt)] for tt in ts]
        else:
            raise TypeError('unknown pos type %s' % type(pos))
        if not (ts >= 0).all():  # pathological if not
            raise RuntimeError('Cannot have t < 0 in transform file')
        tend = raw.times[-1]
        assert not (ts < 0).any()
        assert not (ts > tend).any()
        if ts[0] > 0:
            ts = np.r_[[0.], ts]
            dev_head_ts.insert(0, raw.info['dev_head_t']['trans'])
        dev_head_ts = [{
            'trans': d,
            'to': raw.info['dev_head_t']['to'],
            'from': raw.info['dev_head_t']['from']
        } for d in dev_head_ts]
        if ts[-1] < tend:
            dev_head_ts.append(dev_head_ts[-1])
            ts = np.r_[ts, [tend]]
        offsets = raw.time_as_index(ts)
        offsets[-1] = raw.n_times  # fix for roundoff error
        assert offsets[-2] != offsets[-1]
        del ts
    if isinstance(cov, string_types):
        assert cov == 'simple'
        cov = make_ad_hoc_cov(raw.info, verbose=False)
    assert np.array_equal(offsets, np.unique(offsets))
    assert len(offsets) == len(dev_head_ts)
    approx_events = int(
        (raw.n_times / raw.info['sfreq']) / (stc.times[-1] - stc.times[0]))
    logger.info('Provided parameters will provide approximately %s event%s' %
                (approx_events, '' if approx_events == 1 else 's'))

    # get HPI freqs and reorder
    hpi_freqs = np.array(
        [x['custom_ref'][0] for x in raw.info['hpi_meas'][0]['hpi_coils']])
    n_freqs = len(hpi_freqs)
    order = [x['number'] - 1 for x in raw.info['hpi_meas'][0]['hpi_coils']]
    assert np.array_equal(np.unique(order), np.arange(n_freqs))
    hpi_freqs = hpi_freqs[order]
    hpi_order = raw.info['hpi_results'][0]['order'] - 1
    assert np.array_equal(np.unique(hpi_order), np.arange(n_freqs))
    hpi_freqs = hpi_freqs[hpi_order]

    # extract necessary info
    picks = pick_types(raw.info, meg=True, eeg=True)  # for simulation
    meg_picks = pick_types(raw.info, meg=True, eeg=False)  # for CHPI
    fwd_info = pick_info(raw.info, picks)
    fwd_info['projs'] = []
    logger.info('Setting up raw data simulation using %s head position%s' %
                (len(dev_head_ts), 's' if len(dev_head_ts) != 1 else ''))
    raw.preload_data(verbose=False)

    if isinstance(stc, VolSourceEstimate):
        verts = [stc.vertices]
    else:
        verts = stc.vertices
    src = _restrict_source_space_to(src, verts)

    # figure out our cHPI, ECG, and EOG dipoles
    dig = raw.info['dig']
    assert all([
        d['coord_frame'] == FIFF.FIFFV_COORD_HEAD for d in dig
        if d['kind'] == FIFF.FIFFV_POINT_HPI
    ])
    chpi_rrs = [d['r'] for d in dig if d['kind'] == FIFF.FIFFV_POINT_HPI]
    R, r0 = fit_sphere_to_headshape(raw.info, verbose=False)[:2]
    R /= 1000.
    r0 /= 1000.
    ecg_rr = np.array([[-R, 0, -3 * R]])
    eog_rr = [
        d['r'] for d in raw.info['dig']
        if d['ident'] == FIFF.FIFFV_POINT_NASION
    ][0]
    eog_rr = eog_rr - r0
    eog_rr = (eog_rr / np.sqrt(np.sum(eog_rr * eog_rr)) * 0.98 *
              R)[np.newaxis, :]
    eog_rr += r0
    eog_bem = make_sphere_model(r0,
                                head_radius=R,
                                relative_radii=(0.99, 1.),
                                sigmas=(0.33, 0.33),
                                verbose=False)
    # let's oscillate between resting (17 bpm) and reading (4.5 bpm) rate
    # http://www.ncbi.nlm.nih.gov/pubmed/9399231
    blink_rate = np.cos(2 * np.pi * 1. / 60. * raw.times)
    blink_rate *= 12.5 / 60.
    blink_rate += 4.5 / 60.
    blink_data = rng.rand(raw.n_times) < blink_rate / raw.info['sfreq']
    blink_data = blink_data * (rng.rand(raw.n_times) + 0.5)  # vary amplitudes
    blink_kernel = np.hanning(int(0.25 * raw.info['sfreq']))
    eog_data = np.convolve(blink_data, blink_kernel, 'same')[np.newaxis, :]
    eog_data += rng.randn(eog_data.shape[1]) * 0.05
    eog_data *= 100e-6
    del blink_data,

    max_beats = int(np.ceil(raw.times[-1] * 70. / 60.))
    cardiac_idx = np.cumsum(
        rng.uniform(60. / 70., 60. / 50., max_beats) *
        raw.info['sfreq']).astype(int)
    cardiac_idx = cardiac_idx[cardiac_idx < raw.n_times]
    cardiac_data = np.zeros(raw.n_times)
    cardiac_data[cardiac_idx] = 1
    cardiac_kernel = np.concatenate([
        2 * np.hanning(int(0.04 * raw.info['sfreq'])),
        -0.3 * np.hanning(int(0.05 * raw.info['sfreq'])),
        0.2 * np.hanning(int(0.26 * raw.info['sfreq']))
    ],
                                    axis=-1)
    ecg_data = np.convolve(cardiac_data, cardiac_kernel, 'same')[np.newaxis, :]
    ecg_data += rng.randn(ecg_data.shape[1]) * 0.05
    ecg_data *= 3e-4
    del cardiac_data

    # Add to data file, then rescale for simulation
    for data, scale, exg_ch in zip([eog_data, ecg_data], [1e-3, 5e-4],
                                   ['EOG062', 'ECG063']):
        ch = pick_channels(raw.ch_names, [exg_ch])
        if len(ch) == 1:
            raw._data[ch[0], :] = data
        data *= scale

    evoked = EvokedArray(np.zeros((len(picks), len(stc.times))),
                         fwd_info,
                         stc.tmin,
                         verbose=False)
    stc_event_idx = np.argmin(np.abs(stc.times))
    event_ch = pick_channels(raw.info['ch_names'], ['STI101'])[0]
    used = np.zeros(raw.n_times, bool)
    stc_indices = np.arange(raw.n_times) % len(stc.times)
    raw._data[event_ch, ].fill(0)
    hpi_mag = 25e-9
    last_fwd = last_fwd_chpi = last_fwd_eog = last_fwd_ecg = src_sel = None
    for fi, (fwd, fwd_eog, fwd_ecg, fwd_chpi) in \
        enumerate(_make_forward_solutions(
            fwd_info, trans, src, bem, eog_bem, dev_head_ts, mindist,
            chpi_rrs, eog_rr, ecg_rr, n_jobs)):
        # must be fixed orientation
        fwd = convert_forward_solution(fwd,
                                       surf_ori=True,
                                       force_fixed=True,
                                       verbose=False)
        # just use one arbitrary direction
        fwd_eog = fwd_eog['sol']['data'][:, ::3]
        fwd_ecg = fwd_ecg['sol']['data'][:, ::3]
        fwd_chpi = fwd_chpi[:, ::3]

        if src_sel is None:
            src_sel = _stc_src_sel(fwd['src'], stc)
            if isinstance(stc, VolSourceEstimate):
                verts = [stc.vertices]
            else:
                verts = stc.vertices
            diff_ = sum([len(v) for v in verts]) - len(src_sel)
            if diff_ != 0:
                warnings.warn(
                    '%s STC vertices omitted due to fwd calculation' %
                    (diff_, ))
        if last_fwd is None:
            last_fwd, last_fwd_eog, last_fwd_ecg, last_fwd_chpi = \
                fwd, fwd_eog, fwd_ecg, fwd_chpi
            continue
        n_time = offsets[fi] - offsets[fi - 1]

        time_slice = slice(offsets[fi - 1], offsets[fi])
        assert not used[time_slice].any()
        stc_idxs = stc_indices[time_slice]
        event_idxs = np.where(stc_idxs == stc_event_idx)[0] + offsets[fi - 1]
        used[time_slice] = True
        logger.info('  Simulating data for %0.3f-%0.3f sec with %s event%s' %
                    (tuple(offsets[fi - 1:fi + 1] / raw.info['sfreq']) +
                     (len(event_idxs), '' if len(event_idxs) == 1 else 's')))

        # simulate brain data
        stc_data = stc.data[:, stc_idxs][src_sel]
        data = _interp(last_fwd['sol']['data'], fwd['sol']['data'], stc_data,
                       interp)
        simulated = EvokedArray(data, evoked.info, 0)
        if cov is not None:
            noise = generate_noise_evoked(simulated, cov, [1, -1, 0.2], rng)
            simulated.data += noise.data
        assert simulated.data.shape[0] == len(picks)
        assert simulated.data.shape[1] == len(stc_idxs)
        raw._data[picks, time_slice] = simulated.data

        # add ECG, EOG, and CHPI traces
        raw._data[picks, time_slice] += \
            _interp(last_fwd_eog, fwd_eog, eog_data[:, time_slice], interp)
        raw._data[meg_picks, time_slice] += \
            _interp(last_fwd_ecg, fwd_ecg, ecg_data[:, time_slice], interp)
        this_t = np.arange(offsets[fi - 1], offsets[fi]) / raw.info['sfreq']
        sinusoids = np.zeros((n_freqs, n_time))
        for fi, freq in enumerate(hpi_freqs):
            sinusoids[fi] = 2 * np.pi * freq * this_t
            sinusoids[fi] = hpi_mag * np.sin(sinusoids[fi])
        raw._data[meg_picks, time_slice] += \
            _interp(last_fwd_chpi, fwd_chpi, sinusoids, interp)

        # add events
        raw._data[event_ch, event_idxs] = fi

        # prepare for next iteration
        last_fwd, last_fwd_eog, last_fwd_ecg, last_fwd_chpi = \
            fwd, fwd_eog, fwd_ecg, fwd_chpi
    assert used.all()
    logger.info('Done')
    return raw
Example #8
0
stc.data.fill(0)
stc.data[:, (stc.times >= pulse_tmin) & (stc.times <= pulse_tmax)] = 10e-9

# ############################################################################
# Simulate data

# Simulate data with movement
with warnings.catch_warnings(record=True):
    raw = Raw(fname_raw, allow_maxshield=True)
raw_movement = simulate_raw(raw, stc, trans, src, bem, chpi=True, head_pos=fname_pos_orig, n_jobs=6, verbose=True)

# Simulate data with no movement (use initial head position)
raw_stationary = simulate_raw(raw, stc, trans, src, bem, chpi=True, n_jobs=6, verbose=True)

# Extract positions
trans_orig, rot_orig, t_orig = get_chpi_positions(fname_pos_orig)
t_orig -= raw.first_samp / raw.info["sfreq"]
trans_move, rot_move, t_move = _calculate_chpi_positions(raw_movement)
trans_stat, rot_stat, t_stat = _calculate_chpi_positions(raw_stationary)

# ############################################################################
# Let's look at the results, just translation for simplicity

axes = "XYZ"
fig = plt.figure(dpi=200)
ts = [t_orig, t_stat, t_move]
transs = [trans_orig, trans_stat, trans_move]
labels = ["original", "stationary", "simulated"]
sizes = [10, 5, 5]
colors = "kyr"
for ai, axis in enumerate(axes):