Exemple #1
0
def main():
    """Make reports."""
    parallel, run_func, _ = parallel_func(run_report,
                                          n_jobs=config.get_n_jobs())
    logs = parallel(
        run_func(
            cfg=get_config(subject=subject), subject=subject, session=session)
        for subject, session in itertools.product(config.get_subjects(),
                                                  config.get_sessions()))

    config.save_logs(logs)

    sessions = config.get_sessions()
    if not sessions:
        sessions = [None]

    if (config.get_task() is not None and config.get_task().lower() == 'rest'):
        msg = '    … skipping "average" report for "rest" task.'
        logger.info(**gen_log_kwargs(message=msg))
        return

    for session in sessions:
        run_report_average(cfg=get_config(subject='average'),
                           subject='average',
                           session=session)
def average_evokeds(session):
    # Container for all conditions:
    all_evokeds = defaultdict(list)

    for subject in config.get_subjects():
        fname_in = BIDSPath(subject=subject,
                            session=session,
                            task=config.get_task(),
                            acquisition=config.acq,
                            run=None,
                            recording=config.rec,
                            space=config.space,
                            suffix='ave',
                            extension='.fif',
                            datatype=config.get_datatype(),
                            root=config.deriv_root,
                            check=False)

        msg = f'Input: {fname_in}'
        logger.info(
            gen_log_message(message=msg,
                            step=9,
                            subject=subject,
                            session=session))

        evokeds = mne.read_evokeds(fname_in)
        for idx, evoked in enumerate(evokeds):
            all_evokeds[idx].append(evoked)  # Insert into the container

    for idx, evokeds in all_evokeds.items():
        all_evokeds[idx] = mne.grand_average(
            evokeds, interpolate_bads=config.interpolate_bads_grand_average
        )  # Combine subjects

    subject = 'average'
    fname_out = BIDSPath(subject=subject,
                         session=session,
                         task=config.get_task(),
                         acquisition=config.acq,
                         run=None,
                         processing=config.proc,
                         recording=config.rec,
                         space=config.space,
                         suffix='ave',
                         extension='.fif',
                         datatype=config.get_datatype(),
                         root=config.deriv_root,
                         check=False)

    if not fname_out.fpath.parent.exists():
        os.makedirs(fname_out.fpath.parent)

    msg = f'Saving grand-averaged evoked sensor data: {fname_out}'
    logger.info(
        gen_log_message(message=msg, step=9, subject=subject, session=session))
    mne.write_evokeds(fname_out, list(all_evokeds.values()))
    return list(all_evokeds.values())
Exemple #3
0
def run_forward(subject, session=None):
    deriv_path = config.get_subject_deriv_path(subject=subject,
                                               session=session,
                                               kind=config.get_kind())

    bids_basename = make_bids_basename(subject=subject,
                                       session=session,
                                       task=config.get_task(),
                                       acquisition=config.acq,
                                       run=None,
                                       processing=config.proc,
                                       recording=config.rec,
                                       space=config.space)

    fname_evoked = op.join(deriv_path, bids_basename + '-ave.fif')
    fname_trans = op.join(deriv_path, 'sub-{}'.format(subject) + '-trans.fif')
    fname_fwd = op.join(deriv_path, bids_basename + '-fwd.fif')

    msg = f'Input: {fname_evoked}, Output: {fname_fwd}'
    logger.info(gen_log_message(message=msg, step=10, subject=subject,
                                session=session))
    # Find the raw data file
    # XXX : maybe simplify
    bids_basename = make_bids_basename(subject=subject,
                                       session=session,
                                       task=config.get_task(),
                                       acquisition=config.acq,
                                       run=config.get_runs()[0],
                                       processing=config.proc,
                                       recording=config.rec,
                                       space=config.space)

    trans = get_head_mri_trans(bids_basename=bids_basename,
                               bids_root=config.bids_root)

    mne.write_trans(fname_trans, trans)

    src = mne.setup_source_space(subject, spacing=config.spacing,
                                 subjects_dir=config.get_fs_subjects_dir(),
                                 add_dist=False)

    evoked = mne.read_evokeds(fname_evoked, condition=0)

    # Here we only use 3-layers BEM only if EEG is available.
    if 'eeg' in config.ch_types:
        model = mne.make_bem_model(subject, ico=4,
                                   conductivity=(0.3, 0.006, 0.3),
                                   subjects_dir=config.get_fs_subjects_dir())
    else:
        model = mne.make_bem_model(subject, ico=4, conductivity=(0.3,),
                                   subjects_dir=config.get_fs_subjects_dir())

    bem = mne.make_bem_solution(model)
    fwd = mne.make_forward_solution(evoked.info, trans, src, bem,
                                    mindist=config.mindist)
    mne.write_forward_solution(fname_fwd, fwd, overwrite=True)
Exemple #4
0
def run_ssp(subject, session=None):
    deriv_path = config.get_subject_deriv_path(subject=subject,
                                               session=session,
                                               kind=config.get_kind())

    # compute SSP on first run of raw
    run = config.get_runs()[0]

    bids_basename = make_bids_basename(subject=subject,
                                       session=session,
                                       task=config.get_task(),
                                       acquisition=config.acq,
                                       run=run,
                                       processing=config.proc,
                                       recording=config.rec,
                                       space=config.space)

    # Prepare a name to save the data
    raw_fname_in = op.join(deriv_path, bids_basename + '_filt_raw.fif')

    # when saving proj, use bids_basename=None
    bids_basename = make_bids_basename(subject=subject,
                                       session=session,
                                       task=config.get_task(),
                                       acquisition=config.acq,
                                       run=None,
                                       processing=config.proc,
                                       recording=config.rec,
                                       space=config.space)

    proj_fname_out = op.join(deriv_path, bids_basename + '_ssp-proj.fif')

    msg = f'Input: {raw_fname_in}, Output: {proj_fname_out}'
    logger.info(
        gen_log_message(message=msg, step=4, subject=subject, session=session))

    raw = mne.io.read_raw_fif(raw_fname_in)
    # XXX : n_xxx should be options in config
    msg = 'Computing SSPs for ECG'
    logger.debug(
        gen_log_message(message=msg, step=4, subject=subject, session=session))
    ecg_projs, ecg_events = \
        compute_proj_ecg(raw, n_grad=1, n_mag=1, n_eeg=0, average=True)
    msg = 'Computing SSPs for EOG'
    logger.debug(
        gen_log_message(message=msg, step=4, subject=subject, session=session))
    eog_projs, eog_events = \
        compute_proj_eog(raw, n_grad=1, n_mag=1, n_eeg=1, average=True)

    mne.write_proj(proj_fname_out, eog_projs + ecg_projs)
Exemple #5
0
def get_config(
    subject: Optional[str] = None,
    session: Optional[str] = None
) -> BunchConst:
    cfg = BunchConst(
        subjects=config.get_subjects(),
        task=config.get_task(),
        datatype=config.get_datatype(),
        acq=config.acq,
        rec=config.rec,
        space=config.space,
        proc=config.proc,
        deriv_root=config.get_deriv_root(),
        conditions=config.conditions,
        contrasts=config.contrasts,
        decode=config.decode,
        decoding_metric=config.decoding_metric,
        decoding_n_splits=config.decoding_n_splits,
        random_state=config.random_state,
        n_boot=config.n_boot,
        analyze_channels=config.analyze_channels,
        interpolate_bads_grand_average=config.interpolate_bads_grand_average,
        ch_types=config.ch_types,
        eeg_reference=config.get_eeg_reference(),
        interactive=config.interactive
    )
    return cfg
def main():
    """Run group average in source space"""
    msg = 'Running Step 13: Grand-average source estimates'
    logger.info(gen_log_message(step=13, message=msg))

    if not config.run_source_estimation:
        msg = '    … skipping: run_source_estimation is set to False.'
        logger.info(gen_log_message(step=13, message=msg))
        return

    mne.datasets.fetch_fsaverage(subjects_dir=config.get_fs_subjects_dir())

    parallel, run_func, _ = parallel_func(morph_stc, n_jobs=config.N_JOBS)
    all_morphed_stcs = parallel(run_func(subject, session)
                                for subject, session in
                                itertools.product(config.get_subjects(),
                                                  config.get_sessions()))
    all_morphed_stcs = [morphed_stcs for morphed_stcs, subject in
                        zip(all_morphed_stcs, config.get_subjects())]
    mean_morphed_stcs = map(sum, zip(*all_morphed_stcs))

    subject = 'average'
    # XXX to fix
    if config.get_sessions():
        session = config.get_sessions()[0]
    else:
        session = None

    bids_path = BIDSPath(subject=subject,
                         session=session,
                         task=config.get_task(),
                         acquisition=config.acq,
                         run=None,
                         processing=config.proc,
                         recording=config.rec,
                         space=config.space,
                         datatype=config.get_datatype(),
                         root=config.deriv_root,
                         check=False)

    if isinstance(config.conditions, dict):
        conditions = list(config.conditions.keys())
    else:
        conditions = config.conditions

    for condition, this_stc in zip(conditions, mean_morphed_stcs):
        this_stc /= len(all_morphed_stcs)

        method = config.inverse_method
        cond_str = config.sanitize_cond_name(condition)
        inverse_str = method
        hemi_str = 'hemi'  # MNE will auto-append '-lh' and '-rh'.
        morph_str = 'morph2fsaverage'

        fname_stc_avg = bids_path.copy().update(
            suffix=f'{cond_str}+{inverse_str}+{morph_str}+{hemi_str}')
        this_stc.save(fname_stc_avg)

    msg = 'Completed Step 13: Grand-average source estimates'
    logger.info(gen_log_message(step=13, message=msg))
def compute_cov_from_epochs(subject, session, tmin, tmax):
    deriv_path = config.get_subject_deriv_path(subject=subject,
                                               session=session,
                                               kind=config.get_kind())

    bids_basename = make_bids_basename(subject=subject,
                                       session=session,
                                       task=config.get_task(),
                                       acquisition=config.acq,
                                       run=None,
                                       processing=config.proc,
                                       recording=config.rec,
                                       space=config.space)

    if config.use_ica or config.use_ssp:
        extension = '_cleaned-epo'
    else:
        extension = '-epo'

    epo_fname = op.join(deriv_path, bids_basename + '%s.fif' % extension)
    cov_fname = op.join(deriv_path, bids_basename + '-cov.fif')

    msg = (f"Computing regularized covariance based on epochs' baseline "
           f"periods. Input: {epo_fname}, Output: {cov_fname}")
    logger.info(
        gen_log_message(message=msg, step=11, subject=subject,
                        session=session))

    epochs = mne.read_epochs(epo_fname, preload=True)
    cov = mne.compute_covariance(epochs,
                                 tmin=tmin,
                                 tmax=tmax,
                                 method='shrunk',
                                 rank='info')
    cov.save(cov_fname)
def run_evoked(subject, session=None):
    bids_path = BIDSPath(subject=subject,
                         session=session,
                         task=config.get_task(),
                         acquisition=config.acq,
                         run=None,
                         recording=config.rec,
                         space=config.space,
                         extension='.fif',
                         datatype=config.get_datatype(),
                         root=config.deriv_root)

    processing = None
    if config.use_ica or config.use_ssp:
        processing = 'clean'

    fname_in = bids_path.copy().update(processing=processing, suffix='epo',
                                       check=False)
    fname_out = bids_path.copy().update(suffix='ave', check=False)

    msg = f'Input: {fname_in}, Output: {fname_out}'
    logger.info(gen_log_message(message=msg, step=6, subject=subject,
                                session=session))

    epochs = mne.read_epochs(fname_in, preload=True)

    msg = 'Creating evoked data based on experimental conditions …'
    logger.info(gen_log_message(message=msg, step=6, subject=subject,
                                session=session))
    all_evoked = dict()

    if isinstance(config.conditions, dict):
        for new_cond_name, orig_cond_name in config.conditions.items():
            evoked = epochs[orig_cond_name].average()
            evoked.comment = evoked.comment.replace(orig_cond_name,
                                                    new_cond_name)
            all_evoked[new_cond_name] = evoked
    else:
        for condition in config.conditions:
            evoked = epochs[condition].average()
            all_evoked[condition] = evoked

    if config.contrasts:
        msg = 'Contrasting evoked responses …'
        logger.info(gen_log_message(message=msg, step=6, subject=subject,
                                    session=session))

        for contrast in config.contrasts:
            cond_1, cond_2 = contrast
            evoked_diff = mne.combine_evoked([all_evoked[cond_1],
                                              all_evoked[cond_2]],
                                             weights=[1, -1])
            all_evoked[contrast] = evoked_diff

    evokeds = list(all_evoked.values())
    mne.write_evokeds(fname_out, evokeds)

    if config.interactive:
        for evoked in evokeds:
            evoked.plot()
Exemple #9
0
def plot_auto_scores(subject, session):
    """Plot automated bad channel detection scores.
    """
    import json_tricks

    fname_scores = BIDSPath(subject=subject,
                            session=session,
                            task=config.get_task(),
                            acquisition=config.acq,
                            run=None,
                            processing=config.proc,
                            recording=config.rec,
                            space=config.space,
                            suffix='scores',
                            extension='.json',
                            datatype=config.get_datatype(),
                            root=config.deriv_root,
                            check=False)

    all_figs = []
    all_captions = []
    for run in config.get_runs():
        with open(fname_scores.update(run=run), 'r') as f:
            auto_scores = json_tricks.load(f)

        figs = config.plot_auto_scores(auto_scores)
        all_figs.extend(figs)

        # Could be more than 1 fig, e.g. "grad" and "mag"
        captions = [f'Run {run}'] * len(figs)
        all_captions.extend(captions)

    return all_figs, all_captions
Exemple #10
0
def plot_events(subject, session):
    raws_filt = []
    raw_fname = BIDSPath(subject=subject,
                         session=session,
                         task=config.get_task(),
                         acquisition=config.acq,
                         recording=config.rec,
                         space=config.space,
                         processing='filt',
                         suffix='raw',
                         extension='.fif',
                         datatype=config.get_datatype(),
                         root=config.deriv_root,
                         check=False)

    for run in config.get_runs():
        this_raw_fname = raw_fname.copy().update(run=run)

        if this_raw_fname.copy().update(split='01').fpath.exists():
            this_raw_fname.update(split='01')

        raw_filt = mne.io.read_raw_fif(this_raw_fname)
        raws_filt.append(raw_filt)
        del this_raw_fname

    # Concatenate the filtered raws and extract the events.
    raw_filt_concat = mne.concatenate_raws(raws_filt)
    events, event_id = mne.events_from_annotations(raw=raw_filt_concat)
    fig = mne.viz.plot_events(events=events,
                              event_id=event_id,
                              first_samp=raw_filt_concat.first_samp,
                              sfreq=raw_filt_concat.info['sfreq'],
                              show=False)
    return fig
Exemple #11
0
def get_config(subject: Optional[str] = None,
               session: Optional[str] = None) -> BunchConst:
    cfg = BunchConst(task=config.get_task(),
                     datatype=config.get_datatype(),
                     runs=config.get_runs(subject=subject),
                     acq=config.acq,
                     rec=config.rec,
                     space=config.space,
                     deriv_root=config.get_deriv_root(),
                     interactive=config.interactive,
                     ica_l_freq=config.ica_l_freq,
                     ica_algorithm=config.ica_algorithm,
                     ica_n_components=config.ica_n_components,
                     ica_max_iterations=config.ica_max_iterations,
                     ica_decim=config.ica_decim,
                     ica_reject=config.get_ica_reject(),
                     ica_eog_threshold=config.ica_eog_threshold,
                     ica_ctps_ecg_threshold=config.ica_ctps_ecg_threshold,
                     random_state=config.random_state,
                     ch_types=config.ch_types,
                     l_freq=config.l_freq,
                     decim=config.decim,
                     resample_sfreq=config.resample_sfreq,
                     event_repeated=config.event_repeated,
                     epochs_tmin=config.epochs_tmin,
                     epochs_tmax=config.epochs_tmax,
                     eeg_reference=config.get_eeg_reference(),
                     eog_channels=config.eog_channels)
    return cfg
def compute_cov_from_empty_room(subject, session):
    deriv_path = config.get_subject_deriv_path(subject=subject,
                                               session=session,
                                               kind=config.get_kind())

    bids_basename = make_bids_basename(subject=subject,
                                       session=session,
                                       task=config.get_task(),
                                       acquisition=config.acq,
                                       run=None,
                                       processing=config.proc,
                                       recording=config.rec,
                                       space=config.space)

    raw_er_fname = op.join(deriv_path,
                           bids_basename + '_emptyroom_filt_raw.fif')
    cov_fname = op.join(deriv_path, bids_basename + '-cov.fif')

    extra_params = dict()
    if not config.use_maxwell_filter and config.allow_maxshield:
        extra_params['allow_maxshield'] = config.allow_maxshield

    msg = (f'Computing regularized covariance based on empty-room recording. '
           f'Input: {raw_er_fname}, Output: {cov_fname}')
    logger.info(
        gen_log_message(message=msg, step=11, subject=subject,
                        session=session))

    raw_er = mne.io.read_raw_fif(raw_er_fname, preload=True, **extra_params)
    cov = mne.compute_raw_covariance(raw_er, method='shrunk', rank='info')
    cov.save(cov_fname)
def compute_cov_from_empty_room(subject, session):
    bids_path = BIDSPath(subject=subject,
                         session=session,
                         task=config.get_task(),
                         acquisition=config.acq,
                         run=None,
                         recording=config.rec,
                         space=config.space,
                         extension='.fif',
                         datatype=config.get_datatype(),
                         root=config.deriv_root,
                         check=False)

    raw_er_fname = bids_path.copy().update(processing='filt',
                                           task='noise',
                                           suffix='raw')
    cov_fname = bids_path.copy().update(suffix='cov')

    extra_params = dict()
    if not config.use_maxwell_filter and config.allow_maxshield:
        extra_params['allow_maxshield'] = config.allow_maxshield

    msg = (f'Computing regularized covariance based on empty-room recording. '
           f'Input: {raw_er_fname}, Output: {cov_fname}')
    logger.info(
        gen_log_message(message=msg, step=11, subject=subject,
                        session=session))

    raw_er = mne.io.read_raw_fif(raw_er_fname, preload=True, **extra_params)
    cov = mne.compute_raw_covariance(raw_er, method='shrunk', rank='info')
    cov.save(cov_fname)
Exemple #14
0
def get_config(
    subject: Optional[str] = None,
    session: Optional[str] = None
) -> BunchConst:
    cfg = BunchConst(
        process_er=config.process_er,
        runs=config.get_runs(subject=subject),
        use_maxwell_filter=config.use_maxwell_filter,
        proc=config.proc,
        task=config.get_task(),
        datatype=config.get_datatype(),
        session=session,
        acq=config.acq,
        rec=config.rec,
        space=config.space,
        bids_root=config.get_bids_root(),
        deriv_root=config.get_deriv_root(),
        interactive=config.interactive,
        epochs_tmin=config.epochs_tmin,
        epochs_tmax=config.epochs_tmax,
        epochs_metadata_tmin=config.epochs_metadata_tmin,
        epochs_metadata_tmax=config.epochs_metadata_tmax,
        epochs_metadata_keep_first=config.epochs_metadata_keep_first,
        epochs_metadata_keep_last=config.epochs_metadata_keep_last,
        event_repeated=config.event_repeated,
        decim=config.decim,
        ch_types=config.ch_types,
        eeg_reference=config.get_eeg_reference()
    )
    return cfg
def compute_cov_from_epochs(subject, session, tmin, tmax):
    bids_path = BIDSPath(subject=subject,
                         session=session,
                         task=config.get_task(),
                         acquisition=config.acq,
                         run=None,
                         processing=config.proc,
                         recording=config.rec,
                         space=config.space,
                         extension='.fif',
                         datatype=config.get_datatype(),
                         root=config.deriv_root,
                         check=False)

    processing = None
    if config.use_ica or config.use_ssp:
        processing = 'clean'

    epo_fname = bids_path.copy().update(processing=processing, suffix='epo')
    cov_fname = bids_path.copy().update(suffix='cov')

    msg = (f"Computing regularized covariance based on epochs' baseline "
           f"periods. Input: {epo_fname}, Output: {cov_fname}")
    logger.info(
        gen_log_message(message=msg, step=11, subject=subject,
                        session=session))

    epochs = mne.read_epochs(epo_fname, preload=True)
    cov = mne.compute_covariance(epochs,
                                 tmin=tmin,
                                 tmax=tmax,
                                 method='shrunk',
                                 rank='info')
    cov.save(cov_fname)
def plot_events(subject, session, deriv_path):
    raws_filt = []
    bids_basename = BIDSPath(subject=subject,
                             session=session,
                             task=config.get_task(),
                             acquisition=config.acq,
                             recording=config.rec,
                             space=config.space,
                             prefix=deriv_path,
                             kind=config.get_kind(),
                             processing='filt',
                             extension='.fif')

    for run in config.get_runs():
        fname = bids_basename.copy().update(run=run)
        raw_filt = mne.io.read_raw_fif(fname)
        raws_filt.append(raw_filt)
        del fname

    # Concatenate the filtered raws and extract the events.
    raw_filt_concat = mne.concatenate_raws(raws_filt)
    events, event_id = mne.events_from_annotations(raw=raw_filt_concat)
    fig = mne.viz.plot_events(events=events, event_id=event_id,
                              first_samp=raw_filt_concat.first_samp,
                              sfreq=raw_filt_concat.info['sfreq'],
                              show=False)
    return fig
Exemple #17
0
def run_ssp(subject, session=None):
    # compute SSP on first run of raw
    run = config.get_runs()[0]
    bids_path = BIDSPath(subject=subject,
                         session=session,
                         task=config.get_task(),
                         acquisition=config.acq,
                         run=run,
                         recording=config.rec,
                         space=config.space,
                         extension='.fif',
                         datatype=config.get_datatype(),
                         root=config.deriv_root)

    # Prepare a name to save the data
    raw_fname_in = bids_path.copy().update(processing='filt',
                                           suffix='raw',
                                           check=False)

    # when saving proj, use run=None
    proj_fname_out = bids_path.copy().update(run=None,
                                             suffix='proj',
                                             check=False)

    msg = f'Input: {raw_fname_in}, Output: {proj_fname_out}'
    logger.info(
        gen_log_message(message=msg, step=4, subject=subject, session=session))

    if raw_fname_in.copy().update(split='01').fpath.exists():
        raw_fname_in.update(split='01')

    raw = mne.io.read_raw_fif(raw_fname_in)
    # XXX : n_xxx should be options in config
    msg = 'Computing SSPs for ECG'
    logger.debug(
        gen_log_message(message=msg, step=4, subject=subject, session=session))
    ecg_projs, ecg_events = compute_proj_ecg(raw,
                                             n_grad=1,
                                             n_mag=1,
                                             n_eeg=0,
                                             average=True)
    msg = 'Computing SSPs for EOG'
    logger.debug(
        gen_log_message(message=msg, step=4, subject=subject, session=session))
    if config.eog_channels:
        assert all(
            [ch_name in raw.ch_names for ch_name in config.eog_channels])
        ch_name = ','.join(config.eog_channels)
    else:
        ch_name = None

    eog_projs, eog_events = compute_proj_eog(raw,
                                             ch_name=ch_name,
                                             n_grad=1,
                                             n_mag=1,
                                             n_eeg=1,
                                             average=True)

    mne.write_proj(proj_fname_out, eog_projs + ecg_projs)
def run_inverse(subject, session=None):
    bids_path = BIDSPath(subject=subject,
                         session=session,
                         task=config.get_task(),
                         acquisition=config.acq,
                         run=None,
                         recording=config.rec,
                         space=config.space,
                         extension='.fif',
                         datatype=config.get_datatype(),
                         root=config.deriv_root,
                         check=False)

    fname_ave = bids_path.copy().update(suffix='ave')
    fname_fwd = bids_path.copy().update(suffix='fwd')
    fname_cov = bids_path.copy().update(suffix='cov')
    fname_inv = bids_path.copy().update(suffix='inv')

    evokeds = mne.read_evokeds(fname_ave)
    cov = mne.read_cov(fname_cov)
    forward = mne.read_forward_solution(fname_fwd)
    info = evokeds[0].info
    inverse_operator = make_inverse_operator(info,
                                             forward,
                                             cov,
                                             loose=0.2,
                                             depth=0.8,
                                             rank='info')
    write_inverse_operator(fname_inv, inverse_operator)

    # Apply inverse
    snr = 3.0
    lambda2 = 1.0 / snr**2

    if isinstance(config.conditions, dict):
        conditions = list(config.conditions.keys())
    else:
        conditions = config.conditions

    for condition, evoked in zip(conditions, evokeds):
        method = config.inverse_method
        pick_ori = None

        cond_str = config.sanitize_cond_name(condition)
        inverse_str = method
        hemi_str = 'hemi'  # MNE will auto-append '-lh' and '-rh'.
        fname_stc = bids_path.copy().update(
            suffix=f'{cond_str}+{inverse_str}+{hemi_str}', extension=None)

        if "eeg" in config.ch_types:
            evoked.set_eeg_reference('average', projection=True)

        stc = apply_inverse(evoked=evoked,
                            inverse_operator=inverse_operator,
                            lambda2=lambda2,
                            method=method,
                            pick_ori=pick_ori)
        stc.save(fname_stc)
Exemple #19
0
def run_evoked(subject, session=None):
    deriv_path = config.get_subject_deriv_path(subject=subject,
                                               session=session,
                                               kind=config.get_kind())

    bids_basename = make_bids_basename(subject=subject,
                                       session=session,
                                       task=config.get_task(),
                                       acquisition=config.acq,
                                       run=None,
                                       processing=config.proc,
                                       recording=config.rec,
                                       space=config.space)

    if config.use_ica or config.use_ssp:
        extension = '_cleaned-epo'
    else:
        extension = '-epo'

    fname_in = op.join(deriv_path, bids_basename + '%s.fif' % extension)
    fname_out = op.join(deriv_path, bids_basename + '-ave.fif')

    msg = f'Input: {fname_in}, Output: {fname_out}'
    logger.info(
        gen_log_message(message=msg, step=6, subject=subject, session=session))

    epochs = mne.read_epochs(fname_in, preload=True)

    msg = 'Creating evoked data based on experimental conditions …'
    logger.info(
        gen_log_message(message=msg, step=6, subject=subject, session=session))
    evokeds = []
    for condition in config.conditions:
        evoked = epochs[condition].average()
        evokeds.append(evoked)

    if config.contrasts:
        msg = 'Contrasting evoked responses …'
        logger.info(
            gen_log_message(message=msg,
                            step=6,
                            subject=subject,
                            session=session))

        for contrast in config.contrasts:
            cond_1, cond_2 = contrast
            evoked_1 = epochs[cond_1].average()
            evoked_2 = epochs[cond_2].average()
            evoked_diff = mne.combine_evoked([evoked_1, evoked_2],
                                             weights=[1, -1])
            evokeds.append(evoked_diff)

    mne.evoked.write_evokeds(fname_out, evokeds)

    if config.interactive:
        for evoked in evokeds:
            evoked.plot()
Exemple #20
0
def run_evoked(subject, session=None):
    bids_path = BIDSPath(subject=subject,
                         session=session,
                         task=config.get_task(),
                         acquisition=config.acq,
                         run=None,
                         recording=config.rec,
                         space=config.space,
                         extension='.fif',
                         datatype=config.get_datatype(),
                         root=config.deriv_root)

    processing = None
    if config.use_ica or config.use_ssp:
        processing = 'clean'

    fname_in = bids_path.copy().update(processing=processing,
                                       suffix='epo',
                                       check=False)
    fname_out = bids_path.copy().update(suffix='ave', check=False)

    msg = f'Input: {fname_in}, Output: {fname_out}'
    logger.info(
        gen_log_message(message=msg, step=6, subject=subject, session=session))

    epochs = mne.read_epochs(fname_in, preload=True)

    msg = 'Creating evoked data based on experimental conditions …'
    logger.info(
        gen_log_message(message=msg, step=6, subject=subject, session=session))
    evokeds = []
    for condition in config.conditions:
        evoked = epochs[condition].average()
        evokeds.append(evoked)

    if config.contrasts:
        msg = 'Contrasting evoked responses …'
        logger.info(
            gen_log_message(message=msg,
                            step=6,
                            subject=subject,
                            session=session))

        for contrast in config.contrasts:
            cond_1, cond_2 = contrast
            evoked_1 = epochs[cond_1].average()
            evoked_2 = epochs[cond_2].average()
            evoked_diff = mne.combine_evoked([evoked_1, evoked_2],
                                             weights=[1, -1])
            evokeds.append(evoked_diff)

    mne.write_evokeds(fname_out, evokeds)

    if config.interactive:
        for evoked in evokeds:
            evoked.plot()
def run_forward(subject, session=None):
    deriv_path = config.get_subject_deriv_path(subject=subject,
                                               session=session,
                                               kind=config.get_kind())

    bids_basename = BIDSPath(subject=subject,
                             session=session,
                             task=config.get_task(),
                             acquisition=config.acq,
                             run=None,
                             recording=config.rec,
                             space=config.space,
                             prefix=deriv_path,
                             check=False)

    fname_evoked = bids_basename.copy().update(kind='ave', extension='.fif')
    fname_trans = bids_basename.copy().update(kind='trans', extension='.fif')
    fname_fwd = bids_basename.copy().update(kind='fwd', extension='.fif')

    msg = f'Input: {fname_evoked}, Output: {fname_fwd}'
    logger.info(
        gen_log_message(message=msg, step=10, subject=subject,
                        session=session))
    # Find the raw data file
    trans = get_head_mri_trans(bids_basename=(bids_basename.copy().update(
        run=config.get_runs()[0], prefix=None)),
                               bids_root=config.bids_root)

    mne.write_trans(fname_trans, trans)

    src = mne.setup_source_space(subject,
                                 spacing=config.spacing,
                                 subjects_dir=config.get_fs_subjects_dir(),
                                 add_dist=False)

    evoked = mne.read_evokeds(fname_evoked, condition=0)

    # Here we only use 3-layers BEM only if EEG is available.
    if 'eeg' in config.ch_types:
        model = mne.make_bem_model(subject,
                                   ico=4,
                                   conductivity=(0.3, 0.006, 0.3),
                                   subjects_dir=config.get_fs_subjects_dir())
    else:
        model = mne.make_bem_model(subject,
                                   ico=4,
                                   conductivity=(0.3, ),
                                   subjects_dir=config.get_fs_subjects_dir())

    bem = mne.make_bem_solution(model)
    fwd = mne.make_forward_solution(evoked.info,
                                    trans,
                                    src,
                                    bem,
                                    mindist=config.mindist)
    mne.write_forward_solution(fname_fwd, fwd, overwrite=True)
Exemple #22
0
def run_forward(subject, session=None):
    bids_path = BIDSPath(subject=subject,
                         session=session,
                         task=config.get_task(),
                         acquisition=config.acq,
                         run=None,
                         recording=config.rec,
                         space=config.space,
                         extension='.fif',
                         datatype=config.get_datatype(),
                         root=config.deriv_root,
                         check=False)

    fname_evoked = bids_path.copy().update(suffix='ave')
    fname_trans = bids_path.copy().update(suffix='trans')
    fname_fwd = bids_path.copy().update(suffix='fwd')

    msg = f'Input: {fname_evoked}, Output: {fname_fwd}'
    logger.info(
        gen_log_message(message=msg, step=10, subject=subject,
                        session=session))

    # Retrieve the head -> MRI transformation matrix from the MRI sidecar file
    # in the input data, and save it to an MNE "trans" file in the derivatives
    # folder.
    trans = get_head_mri_trans(bids_path.copy().update(
        run=config.get_runs()[0], root=config.bids_root))
    mne.write_trans(fname_trans, trans)

    src = mne.setup_source_space(subject,
                                 spacing=config.spacing,
                                 subjects_dir=config.get_fs_subjects_dir(),
                                 add_dist=False)

    evoked = mne.read_evokeds(fname_evoked, condition=0)

    # Here we only use 3-layers BEM only if EEG is available.
    if 'eeg' in config.ch_types:
        model = mne.make_bem_model(subject,
                                   ico=4,
                                   conductivity=(0.3, 0.006, 0.3),
                                   subjects_dir=config.get_fs_subjects_dir())
    else:
        model = mne.make_bem_model(subject,
                                   ico=4,
                                   conductivity=(0.3, ),
                                   subjects_dir=config.get_fs_subjects_dir())

    bem = mne.make_bem_solution(model)
    fwd = mne.make_forward_solution(evoked.info,
                                    trans,
                                    src,
                                    bem,
                                    mindist=config.mindist)
    mne.write_forward_solution(fname_fwd, fwd, overwrite=True)
def run_time_decoding(subject, condition1, condition2, session=None):
    msg = f'Contrasting conditions: {condition1} – {condition2}'
    logger.info(
        gen_log_message(message=msg, step=7, subject=subject, session=session))

    fname_epochs = BIDSPath(subject=subject,
                            session=session,
                            task=config.get_task(),
                            acquisition=config.acq,
                            run=None,
                            recording=config.rec,
                            space=config.space,
                            suffix='epo',
                            extension='.fif',
                            datatype=config.get_datatype(),
                            root=config.deriv_root,
                            check=False)

    epochs = mne.read_epochs(fname_epochs)

    # We define the epochs and the labels
    epochs = mne.concatenate_epochs([epochs[condition1], epochs[condition2]])
    X = epochs.get_data()
    n_cond1 = len(epochs[condition1])
    n_cond2 = len(epochs[condition2])
    y = np.r_[np.ones(n_cond1), np.zeros(n_cond2)]

    clf = make_pipeline(
        StandardScaler(),
        LogisticRegression(solver='liblinear',
                           random_state=config.random_state))

    se = SlidingEstimator(clf,
                          scoring=config.decoding_metric,
                          n_jobs=config.N_JOBS)
    scores = cross_val_multiscore(se, X=X, y=y, cv=config.decoding_n_splits)

    # let's save the scores now
    a_vs_b = f'{condition1}-{condition2}'.replace(op.sep, '')
    processing = f'{a_vs_b}+{config.decoding_metric}'
    processing = processing.replace('_', '-').replace('-', '')

    fname_mat = fname_epochs.copy().update(suffix='decoding',
                                           processing=processing,
                                           extension='.mat')
    savemat(fname_mat, {'scores': scores, 'times': epochs.times})

    fname_tsv = fname_mat.copy().update(extension='.tsv')
    tabular_data = pd.DataFrame(
        dict(cond_1=[condition1] * len(epochs.times),
             cond_2=[condition2] * len(epochs.times),
             time=epochs.times,
             mean_crossval_score=scores.mean(axis=0),
             metric=[config.decoding_metric] * len(epochs.times)))
    tabular_data.to_csv(fname_tsv, sep='\t', index=False)
Exemple #24
0
def get_config(subject: Optional[str] = None,
               session: Optional[str] = None) -> BunchConst:
    cfg = BunchConst(
        task=config.get_task(),
        datatype=config.get_datatype(),
        acq=config.acq,
        rec=config.rec,
        space=config.space,
        deriv_root=config.get_deriv_root(),
    )
    return cfg
Exemple #25
0
def main():
    """Run grp ave."""
    msg = 'Running Step 13: Grand-average source estimates'
    logger.info(gen_log_message(step=13, message=msg))

    mne.datasets.fetch_fsaverage(subjects_dir=config.get_fs_subjects_dir())

    parallel, run_func, _ = parallel_func(morph_stc, n_jobs=config.N_JOBS)
    all_morphed_stcs = parallel(run_func(subject, session)
                                for subject, session in
                                itertools.product(config.get_subjects(),
                                                  config.get_sessions()))
    all_morphed_stcs = [morphed_stcs for morphed_stcs, subject in
                        zip(all_morphed_stcs, config.get_subjects())]
    mean_morphed_stcs = map(sum, zip(*all_morphed_stcs))

    subject = 'average'
    # XXX to fix
    if config.get_sessions():
        session = config.get_sessions()[0]
    else:
        session = None

    deriv_path = config.get_subject_deriv_path(subject=subject,
                                               session=session,
                                               kind=config.get_kind())

    bids_basename = BIDSPath(subject=subject,
                             session=session,
                             task=config.get_task(),
                             acquisition=config.acq,
                             run=None,
                             processing=config.proc,
                             recording=config.rec,
                             space=config.space,
                             prefix=deriv_path,
                             check=False)

    for condition, this_stc in zip(config.conditions, mean_morphed_stcs):
        this_stc /= len(all_morphed_stcs)

        method = config.inverse_method
        cond_str = condition.replace(op.sep, '').replace('_', '')
        inverse_str = method
        hemi_str = 'hemi'  # MNE will auto-append '-lh' and '-rh'.
        morph_str = 'morph2fsaverage'

        fname_stc_avg = bids_basename.copy().update(
            kind=f'{cond_str}+{inverse_str}+{morph_str}+{hemi_str}')
        this_stc.save(fname_stc_avg)

    msg = 'Completed Step 13: Grand-average source estimates'
    logger.info(gen_log_message(step=13, message=msg))
Exemple #26
0
def run_inverse(subject, session=None):
    deriv_path = config.get_subject_deriv_path(subject=subject,
                                               session=session,
                                               kind=config.get_kind())

    bids_basename = BIDSPath(subject=subject,
                             session=session,
                             task=config.get_task(),
                             acquisition=config.acq,
                             run=None,
                             recording=config.rec,
                             space=config.space,
                             prefix=deriv_path,
                             extension='.fif',
                             check=False)

    fname_ave = bids_basename.copy().update(kind='ave')
    fname_fwd = bids_basename.copy().update(kind='fwd')
    fname_cov = bids_basename.copy().update(kind='cov')
    fname_inv = bids_basename.copy().update(kind='inv')

    evokeds = mne.read_evokeds(fname_ave)
    cov = mne.read_cov(fname_cov)
    forward = mne.read_forward_solution(fname_fwd)
    info = evokeds[0].info
    inverse_operator = make_inverse_operator(info,
                                             forward,
                                             cov,
                                             loose=0.2,
                                             depth=0.8,
                                             rank='info')
    write_inverse_operator(fname_inv, inverse_operator)

    # Apply inverse
    snr = 3.0
    lambda2 = 1.0 / snr**2

    for condition, evoked in zip(config.conditions, evokeds):
        method = config.inverse_method
        pick_ori = None

        cond_str = condition.replace(op.sep, '').replace('_', '')
        inverse_str = method
        hemi_str = 'hemi'  # MNE will auto-append '-lh' and '-rh'.
        fname_stc = bids_basename.copy().update(
            kind=f'{cond_str}+{inverse_str}+{hemi_str}', extension=None)

        stc = apply_inverse(evoked=evoked,
                            inverse_operator=inverse_operator,
                            lambda2=lambda2,
                            method=method,
                            pick_ori=pick_ori)
        stc.save(fname_stc)
def get_config(subject: Optional[str] = None,
               session: Optional[str] = None) -> SimpleNamespace:
    cfg = SimpleNamespace(task=config.get_task(),
                          datatype=config.get_datatype(),
                          acq=config.acq,
                          rec=config.rec,
                          space=config.space,
                          deriv_root=config.get_deriv_root(),
                          interactive=config.interactive,
                          baseline=config.baseline,
                          ica_reject=config.get_ica_reject())
    return cfg
Exemple #28
0
def run_inverse(subject, session=None):
    deriv_path = config.get_subject_deriv_path(subject=subject,
                                               session=session,
                                               kind=config.get_kind())

    bids_basename = make_bids_basename(subject=subject,
                                       session=session,
                                       task=config.get_task(),
                                       acquisition=config.acq,
                                       run=None,
                                       processing=config.proc,
                                       recording=config.rec,
                                       space=config.space)

    fname_ave = op.join(deriv_path, bids_basename + '-ave.fif')
    fname_fwd = op.join(deriv_path, bids_basename + '-fwd.fif')
    fname_cov = op.join(deriv_path, bids_basename + '-cov.fif')
    fname_inv = op.join(deriv_path, bids_basename + '-inv.fif')

    evokeds = mne.read_evokeds(fname_ave)
    cov = mne.read_cov(fname_cov)
    forward = mne.read_forward_solution(fname_fwd)
    info = evokeds[0].info
    inverse_operator = make_inverse_operator(info,
                                             forward,
                                             cov,
                                             loose=0.2,
                                             depth=0.8,
                                             rank='info')
    write_inverse_operator(fname_inv, inverse_operator)

    # Apply inverse
    snr = 3.0
    lambda2 = 1.0 / snr**2

    for condition, evoked in zip(config.conditions, evokeds):
        method = config.inverse_method
        pick_ori = None

        cond_str = 'cond-%s' % condition.replace(op.sep, '')
        inverse_str = 'inverse-%s' % method
        hemi_str = 'hemi'  # MNE will auto-append '-lh' and '-rh'.
        fname_stc = op.join(
            deriv_path,
            '_'.join([bids_basename, cond_str, inverse_str, hemi_str]))

        stc = apply_inverse(evoked=evoked,
                            inverse_operator=inverse_operator,
                            lambda2=lambda2,
                            method=method,
                            pick_ori=pick_ori)
        stc.save(fname_stc)
def get_config(
    subject: Optional[str] = None,
    session: Optional[str] = None
) -> SimpleNamespace:
    cfg = SimpleNamespace(
        task=config.get_task(),
        datatype=config.get_datatype(),
        acq=config.acq,
        rec=config.rec,
        space=config.space,
        deriv_root=config.get_deriv_root(),
    )
    return cfg
Exemple #30
0
def get_config(subject: Optional[str] = None,
               session: Optional[str] = None) -> SimpleNamespace:
    # Deal with configurations where `deriv_root` was specified, but not
    # `fs_subjects_dir`. We normally raise an exception in this case in
    # `get_fs_subjects_dir()`. However, in situations where users only run the
    # sensor-space scripts, we never call this function, so everything works
    # totally fine at first (which is expected). Yet, when creating the
    # reports, the pipeline would fail with an exception – which is
    # unjustified, as it would not make sense to force users to provide an
    # `fs_subjects_dir` if they don't care about source analysis anyway! So
    # simply assign a dummy value in such cases.
    # `get_fs_subject()` calls `get_fs_subjects_dir()`, so take care of this
    # too.
    try:
        fs_subjects_dir = config.get_fs_subjects_dir()
    except ValueError:
        fs_subjects_dir = None
        fs_subject = None
    else:
        fs_subject = config.get_fs_subject(subject=subject)

    cfg = SimpleNamespace(
        task=config.get_task(),
        runs=config.get_runs(subject=subject),
        datatype=config.get_datatype(),
        acq=config.acq,
        rec=config.rec,
        space=config.space,
        proc=config.proc,
        analyze_channels=config.analyze_channels,
        process_er=config.process_er,
        find_noisy_channels_meg=config.find_noisy_channels_meg,
        h_freq=config.h_freq,
        spatial_filter=config.spatial_filter,
        ica_reject=config.ica_reject,
        conditions=config.conditions,
        contrasts=config.contrasts,
        time_frequency_conditions=config.time_frequency_conditions,
        decode=config.decode,
        decoding_metric=config.decoding_metric,
        n_boot=config.n_boot,
        inverse_method=config.inverse_method,
        fs_subject=fs_subject,
        fs_subjects_dir=fs_subjects_dir,
        deriv_root=config.get_deriv_root(),
        bids_root=config.get_bids_root(),
        use_template_mri=config.use_template_mri,
        interactive=config.interactive,
        plot_psd_for_runs=config.plot_psd_for_runs,
    )
    return cfg