示例#1
0
def test_edf(_bids_validate):
    """Test write_raw_bids conversion for European Data Format data."""
    output_path = _TempDir()
    data_path = op.join(testing.data_path(), 'EDF')
    raw_fname = op.join(data_path, 'test_reduced.edf')

    raw = mne.io.read_raw_edf(raw_fname, preload=True)
    # XXX: hack that should be fixed later. Annotation reading is
    # broken for this file with preload=False and read_annotations_edf
    raw.preload = False

    raw.rename_channels({raw.info['ch_names'][0]: 'EOG'})
    raw.info['chs'][0]['coil_type'] = FIFF.FIFFV_COIL_EEG_BIPOLAR
    raw.rename_channels({raw.info['ch_names'][1]: 'EMG'})
    raw.set_channel_types({'EMG': 'emg'})

    write_raw_bids(raw, bids_basename, output_path)

    # Reading the file back should raise an error, because we renamed channels
    # in `raw` and used that information to write a channels.tsv. Yet, we
    # saved the unchanged `raw` in the BIDS folder, so channels in the TSV and
    # in raw clash
    with pytest.raises(RuntimeError, match='Channels do not correspond'):
        read_raw_bids(bids_basename + '_eeg.edf', output_path)

    bids_fname = bids_basename.replace('run-01', 'run-%s' % run2)
    write_raw_bids(raw, bids_fname, output_path, overwrite=True)
    _bids_validate(output_path)

    # ensure there is an EMG channel in the channels.tsv:
    channels_tsv = make_bids_basename(subject=subject_id,
                                      session=session_id,
                                      task=task,
                                      run=run,
                                      suffix='channels.tsv',
                                      acquisition=acq,
                                      prefix=op.join(output_path, 'sub-01',
                                                     'ses-01', 'eeg'))
    data = _from_tsv(channels_tsv)
    assert 'ElectroMyoGram' in data['description']

    # check that the scans list contains two scans
    scans_tsv = make_bids_basename(subject=subject_id,
                                   session=session_id,
                                   suffix='scans.tsv',
                                   prefix=op.join(output_path, 'sub-01',
                                                  'ses-01'))
    data = _from_tsv(scans_tsv)
    assert len(list(data.values())[0]) == 2

    # Also cover iEEG
    # We use the same data and pretend that eeg channels are ecog
    raw.set_channel_types(
        {raw.ch_names[i]: 'ecog'
         for i in mne.pick_types(raw.info, eeg=True)})
    output_path = _TempDir()
    write_raw_bids(raw, bids_basename, output_path)
    _bids_validate(output_path)
示例#2
0
def test_copyfile_kit():
    """Test copying and renaming KIT files to a new location."""
    output_path = _TempDir()
    data_path = op.join(base_path, 'kit', 'tests', 'data')
    raw_fname = op.join(data_path, 'test.sqd')
    hpi_fname = op.join(data_path, 'test_mrk.sqd')
    electrode_fname = op.join(data_path, 'test.elp')
    headshape_fname = op.join(data_path, 'test.hsp')
    subject_id = '01'
    session_id = '01'
    run = '01'
    acq = '01'
    task = 'testing'

    bids_basename = make_bids_basename(
        subject=subject_id, session=session_id, run=run, acquisition=acq,
        task=task)

    kit_bids_basename = bids_basename.copy().update(acquisition=None,
                                                    prefix=output_path)

    raw = mne.io.read_raw_kit(
        raw_fname, mrk=hpi_fname, elp=electrode_fname,
        hsp=headshape_fname)
    _, ext = _parse_ext(raw_fname, verbose=True)
    kind = _handle_kind(raw)
    bids_fname = str(bids_basename.copy().update(suffix=f'{kind}{ext}',
                                                 prefix=output_path))

    copyfile_kit(raw_fname, bids_fname, subject_id, session_id,
                 task, run, raw._init_kwargs)
    assert op.exists(bids_fname)
    _, ext = _parse_ext(hpi_fname, verbose=True)
    if ext == '.sqd':
        kit_bids_basename.suffix = 'markers.sqd'
        assert op.exists(kit_bids_basename)
    elif ext == '.mrk':
        kit_bids_basename.suffix = 'markers.mrk'
        assert op.exists(kit_bids_basename)

    if op.exists(electrode_fname):
        task, run, key = None, None, 'ELP'
        elp_ext = '.pos'
        elp_fname = make_bids_basename(
            subject=subject_id, session=session_id, task=task, run=run,
            acquisition=key, suffix='headshape%s' % elp_ext,
            prefix=output_path)
        assert op.exists(elp_fname)

    if op.exists(headshape_fname):
        task, run, key = None, None, 'HSP'
        hsp_ext = '.pos'
        hsp_fname = make_bids_basename(
            subject=subject_id, session=session_id, task=task, run=run,
            acquisition=key, suffix='headshape%s' % hsp_ext,
            prefix=output_path)
        assert op.exists(hsp_fname)
示例#3
0
def run_ssp(subject, session=None):
    print("Processing subject: %s" % subject)

    print("  Loading one run to compute SSPs")

    # Construct the search path for the data file. `sub` is mandatory
    subject_path = op.join('sub-{}'.format(subject))
    # `session` is optional
    if session is not None:
        subject_path = op.join(subject_path, 'ses-{}'.format(session))

    subject_path = op.join(subject_path, config.kind)

    # compute SSP on first run of raw
    run = config.runs[0]

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

    # Prepare a name to save the data
    fpath_deriv = op.join(config.bids_root, 'derivatives',
                          config.PIPELINE_NAME, subject_path)

    raw_fname_in = \
        op.join(fpath_deriv, bids_basename + '_filt_raw.fif')

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

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

    print("Input: ", raw_fname_in)
    print("Output: ", proj_fname_out)

    raw = mne.io.read_raw_fif(raw_fname_in)
    # XXX : n_xxx should be options in config
    print("  Computing SSPs for ECG")
    ecg_projs, ecg_events = \
        compute_proj_ecg(raw, n_grad=1, n_mag=1, n_eeg=0, average=True)
    print("  Computing SSPs for EOG")
    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)
示例#4
0
def test_bids_path(return_bids_test_dir):
    """Test usage of BIDSPath object."""
    bids_root = return_bids_test_dir

    bids_basename = make_bids_basename(
        subject=subject_id, session=session_id, run=run, acquisition=acq,
        task=task)

    # get_bids_fname should fire warning
    with pytest.raises(ValueError, match='No filename extension was provided'):
        bids_fname = bids_basename.get_bids_fname()

    # should find the correct filename if bids_root was passed
    bids_fname = bids_basename.get_bids_fname(bids_root=bids_root)
    assert bids_fname == bids_basename.update(suffix='meg.fif')

    # confirm BIDSPath assigns properties correctly
    bids_basename = make_bids_basename(subject=subject_id,
                                       session=session_id)
    assert bids_basename.subject == subject_id
    assert bids_basename.session == session_id
    assert 'subject' in bids_basename.entities
    assert 'session' in bids_basename.entities
    print(bids_basename.entities)
    assert all(bids_basename.entities.get(entity) is None
               for entity in ['task', 'run', 'recording', 'acquisition',
                              'space', 'processing',
                              'prefix', 'suffix'])

    # test updating functionality
    bids_basename.update(acquisition='03', run='2', session='02',
                         task=None)
    assert bids_basename.subject == subject_id
    assert bids_basename.session == '02'
    assert bids_basename.acquisition == '03'
    assert bids_basename.run == '2'
    assert bids_basename.task is None

    new_bids_basename = bids_basename.copy().update(task='02',
                                                    acquisition=None)
    assert new_bids_basename.task == '02'
    assert new_bids_basename.acquisition is None

    # equality of bids basename
    assert new_bids_basename != bids_basename
    assert new_bids_basename == bids_basename.copy().update(task='02',
                                                            acquisition=None)

    # error check
    with pytest.raises(ValueError, match='Key must be one of*'):
        bids_basename.update(sub=subject_id, session=session_id)

    # test repr
    bids_path = make_bids_basename(subject='01', session='02',
                                   task='03', suffix='ieeg.edf')
    assert repr(bids_path) == 'BIDSPath(sub-01_ses-02_task-03_ieeg.edf)'
示例#5
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)
示例#6
0
def test_kit():
    """Test functionality of the write_raw_bids conversion for KIT data."""
    output_path = _TempDir()
    data_path = op.join(base_path, 'kit', 'tests', 'data')
    raw_fname = op.join(data_path, 'test.sqd')
    events_fname = op.join(data_path, 'test-eve.txt')
    hpi_fname = op.join(data_path, 'test_mrk.sqd')
    electrode_fname = op.join(data_path, 'test_elp.txt')
    headshape_fname = op.join(data_path, 'test_hsp.txt')
    event_id = dict(cond=1)

    raw = mne.io.read_raw_kit(raw_fname,
                              mrk=hpi_fname,
                              elp=electrode_fname,
                              hsp=headshape_fname)
    write_raw_bids(raw,
                   bids_basename,
                   output_path,
                   events_data=events_fname,
                   event_id=event_id,
                   overwrite=False)
    cmd = ['bids-validator', output_path]
    run_subprocess(cmd, shell=shell)
    assert op.exists(op.join(output_path, 'participants.tsv'))

    # ensure the channels file has no STI 014 channel:
    channels_tsv = make_bids_basename(subject=subject_id,
                                      session=session_id,
                                      task=task,
                                      run=run,
                                      suffix='channels.tsv',
                                      acquisition=acq,
                                      prefix=op.join(output_path,
                                                     'sub-01/ses-01/meg'))
    df = pd.read_csv(channels_tsv, sep='\t')
    assert not ('STI 014' in df['name'].values)

    # ensure the marker file is produced in the right place
    raw_folder = make_bids_basename(subject=subject_id,
                                    session=session_id,
                                    task=task,
                                    run=run,
                                    acquisition=acq,
                                    suffix='%s' % 'meg')
    marker_fname = make_bids_basename(subject=subject_id,
                                      session=session_id,
                                      task=task,
                                      run=run,
                                      acquisition=acq,
                                      suffix='markers.sqd',
                                      prefix=os.path.join(
                                          output_path, 'sub-01/ses-01/meg',
                                          raw_folder))
    assert op.exists(marker_fname)
示例#7
0
def test_edf():
    """Test write_raw_bids conversion for European Data Format data."""
    output_path = _TempDir()
    data_path = op.join(testing.data_path(), 'EDF')
    raw_fname = op.join(data_path, 'test_reduced.edf')

    raw = mne.io.read_raw_edf(raw_fname, preload=True)
    # XXX: hack that should be fixed later. Annotation reading is
    # broken for this file with preload=False and read_annotations_edf
    raw.preload = False

    raw.rename_channels({raw.info['ch_names'][0]: 'EOG'})
    raw.info['chs'][0]['coil_type'] = FIFF.FIFFV_COIL_EEG_BIPOLAR
    raw.rename_channels({raw.info['ch_names'][1]: 'EMG'})
    raw.set_channel_types({'EMG': 'emg'})

    write_raw_bids(raw, bids_basename, output_path)
    bids_fname = bids_basename.replace('run-01', 'run-%s' % run2)
    write_raw_bids(raw, bids_fname, output_path, overwrite=True)

    cmd = ['bids-validator', '--bep006', output_path]
    run_subprocess(cmd, shell=shell)

    # ensure there is an EMG channel in the channels.tsv:
    channels_tsv = make_bids_basename(subject=subject_id,
                                      session=session_id,
                                      task=task,
                                      run=run,
                                      suffix='channels.tsv',
                                      acquisition=acq,
                                      prefix=op.join(output_path,
                                                     'sub-01/ses-01/eeg'))
    df = pd.read_csv(channels_tsv, sep='\t')
    assert 'ElectroMyoGram' in df['description'].values

    # check that the scans list contains two scans
    scans_tsv = make_bids_basename(subject=subject_id,
                                   session=session_id,
                                   suffix='scans.tsv',
                                   prefix=op.join(output_path,
                                                  'sub-01/ses-01'))
    df = pd.read_csv(scans_tsv, sep='\t')
    assert df.shape[0] == 2

    # Also cover iEEG
    # We use the same data and pretend that eeg channels are ecog
    raw.set_channel_types(
        {raw.ch_names[i]: 'ecog'
         for i in mne.pick_types(raw.info, eeg=True)})
    output_path = _TempDir()
    write_raw_bids(raw, bids_basename, output_path)

    cmd = ['bids-validator', '--bep010', output_path]
    run_subprocess(cmd, shell=shell)
示例#8
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)
示例#9
0
    def rel_chanstsv_fpath(self):
        """
        Get the path of the channel tsv file.

        Returns
        -------
        Channel tsv path

        """
        return os.path.join(
            make_bids_basename(subject=self.subject_id),
            make_bids_basename(session=self.session_id),
            self.kind,
            self._make_bids_basename(suffix="channels.tsv",),
        )
示例#10
0
    def rel_sidecarjson_fpath(self):
        """
        Get the path of the sidecar json file.

        Returns
        -------
        Sidecar json path

        """
        return os.path.join(
            make_bids_basename(subject=self.subject_id),
            make_bids_basename(session=self.session_id),
            self.kind,
            self._make_bids_basename(suffix=f"{self.kind}.json",),
        )
示例#11
0
    def rel_datafile_fpath(self):
        """
        Get the path of the data file.

        Returns
        -------
        Data file path

        """
        return os.path.join(
            make_bids_basename(subject=self.subject_id),
            make_bids_basename(session=self.session_id),
            self.kind,
            self._make_bids_basename(suffix=f"{self.kind}.{self.ext}",),
        )
示例#12
0
def _get_bids_basename(subject, session, imgtype, ext="nii.gz", **bids_kwargs):
    """Wildcard function to get bids_basename."""
    bids_fname = make_bids_basename(subject,
                                    session=session,
                                    **bids_kwargs,
                                    suffix=f"{imgtype}.{ext}")
    return bids_fname
示例#13
0
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)
示例#14
0
    def rel_scanstsv_fpath(self):
        """
        Get the path of the scans tsv file.

        Returns
        -------
        Scans tsv path

        """
        return os.path.join(
            make_bids_basename(subject=self.subject_id),
            make_bids_basename(session=self.session_id),
            make_bids_basename(
                subject=self.subject_id, session=self.session_id, suffix="scans.tsv"
            ),
        )
示例#15
0
    def make_preprocessed_folder(datadir,
                                 subject_id,
                                 session="one",
                                 preprocess_name="preprocessed"):
        """
        Create the preproceesed data folder in the correct location if it does not already exist.

        Assumes session is 'one'.

        Parameters
        ----------
        datadir : Union[str, os.PathLike]
            The base directory for bids data
        subject_id : str
            The unique identifier for the BidsPatient
        session : str
            The identifier for this BidsPatient session
        preprocess_name : str
            The name of the preprocessed folder

        """
        basedir = os.path.join(
            datadir, make_bids_basename(subject=subject_id, session=session))
        preprocessed_dir = os.path.join(basedir, preprocess_name)
        if os.path.exists(preprocessed_dir):
            return 1
        else:
            os.mkdir(preprocessed_dir)
示例#16
0
    def test_baseio(self):
        test_subjectid = "0001"
        session_id = "seizure"
        kind = "eeg"
        run_id = "01"
        task = "monitor"
        bids_basename = make_bids_basename(
            subject=test_subjectid,
            session=session_id,
            acquisition=kind,
            run=run_id,
            task=task,
            # suffix=kind + ".fif",
        )
        ext = "fif"
        bids_root = os.path.join(os.getcwd(), "./data/bids_layout/")

        # instantiate a loader/writer
        loader = BidsLoader(
            bids_root=bids_root,
            bids_basename=bids_basename,
            kind=kind,
            datatype=ext,
        )
        participant_dict = loader.load_participants_json()
        participant_df = loader.load_participants_tsv()
        scans_df = loader.load_scans_tsv()
        sidecar = loader.load_sidecar_json()
        chans_df = loader.load_channels_tsv()

        # check basic funcs
        print(loader.chanstsv_fpath)
        print(loader.datafile_fpath)
        print(loader.eventstsv_fpath)
        print(loader.rel_chanstsv_fpath)
        print(loader.rel_datafile_fpath)
        print(loader.rel_eventstsv_fpath)
        print(loader.rel_participantsjson_fpath)
        print(loader.rel_participantstsv_fpath)
        print(loader.rel_scanstsv_fpath)
        print(loader.rel_sidecarjson_fpath)

        with tempfile.TemporaryDirectory() as bids_root:
            writer = BidsWriter(
                bids_root=bids_root,
                bids_basename=bids_basename,
                kind=kind,
                datatype=ext,
            )
            with pytest.raises(Exception):
                writer.write_channels_tsv(chans_df)
            with pytest.raises(Exception):
                writer.write_electrode_coords()
            with pytest.raises(Exception):
                writer.write_scans_tsv(scans_df)
            with pytest.raises(Exception):
                writer.write_sidecar_json(sidecar)

            writer.write_participants_json(participant_dict)
            writer.write_participants_tsv(participant_df)
示例#17
0
    def modify_participants_file(self, column_id: str, new_value: str):
        """
        Modify the BIDS dataset participants tsv file to include a new value.

        Parameters
        ----------
        column_id : str
            The name of the column to which data should be modified. Must exist in the tsv file
        new_value : str
            The new value of the column_id for this BidsPatient

        """
        # load in the data and do error check and set index
        participants_df = self.loader.load_participants_tsv()
        participants_df = participants_df.set_index("participant_id")
        colnames = participants_df.columns
        if column_id not in colnames:
            raise ValueError(
                f"{column_id} not in the existing participants file. Add it first."
            )

        # modify at the TSV level and reset_index
        participants_df.at[
            make_bids_basename(subject=self.subject_id), column_id
        ] = new_value
        self._write_to_participants_tsv(participants_df)

        # recreate metadata
        metadata = self._create_metadata()
        self._load_metadata(metadata)
示例#18
0
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)
示例#19
0
def find_bids_run_file(
    subject_id,
    session_id,
    task_id,
    acquisition_id,
    run_id,
    kind,
    datadir,
    ext,
    center=None,
):
    """
    Get the path of the data file of interest.

    TODO: Allow searching through other folders for preprocessed and results files for this run.
    TODO: Should this be done on BidsRun side?

    Parameters
    ----------
    subject_id : str
        The unique identifier for the subject. We may need to have some mapping functions.
    session_id : str
        The identifier for the session of the subject. Again, mapping may be necessary for anonymity.
    task_id : str or None
        Identifier for the task
    acquisition_id: str or None
        Identifier for the acquisition
    run_id : str
        The identifier for the run of the subject.
    kind : str
        The type of recording
    datadir : Union[str, os.PathLike]
        Base directory containing the bids data.
    ext : str (fif or edf)
        either fif or edf
    center : str or None
        The name of the center that the patient belongs to

    Returns
    -------
    bids_run_fpath: os.PathLike
        The location of the desired file.

    """
    if task_id is None:
        task_id = DEFAULT_TASK
    if acquisition_id is None:
        acquisition_id = DEFAULT_ACQUISITION
    bids_root = datadir
    bids_fname = make_bids_basename(
        subject=subject_id,
        session=session_id,
        task=task_id,
        acquisition=acquisition_id,
        run=run_id,
        suffix=f"{kind}.{ext}",
    )
    bids_run = BidsRun(bids_root, bids_fname)
    return bids_root, bids_fname, bids_run.fpath
def run_inverse(subject, session=None):
    print("Processing subject: %s" % subject)

    # Construct the search path for the data file. `sub` is mandatory
    subject_path = op.join('sub-{}'.format(subject))
    # `session` is optional
    if session is not None:
        subject_path = op.join(subject_path, 'ses-{}'.format(session))

    subject_path = op.join(subject_path, config.kind)

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

    fpath_deriv = op.join(config.bids_root, 'derivatives',
                          config.PIPELINE_NAME, subject_path)
    fname_ave = \
        op.join(fpath_deriv, bids_basename + '-ave.fif')

    fname_fwd = \
        op.join(fpath_deriv, bids_basename + '-fwd.fif')

    fname_cov = \
        op.join(fpath_deriv, bids_basename + '-cov.fif')

    fname_inv = \
        op.join(fpath_deriv, 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)
    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):
        stc = apply_inverse(evoked,
                            inverse_operator,
                            lambda2,
                            "dSPM",
                            pick_ori=None)
        stc.save(
            op.join(
                fpath_deriv, '%s_%s_mne_dSPM_inverse-%s' %
                (config.study_name, subject, condition.replace(op.sep, ''))))
示例#21
0
def update_markers(confile, fpath, bids_name):
    # TODO: shouldn't be needed once PR goes through on github
    """Update the markers provided and ensure that the BIDS output contains
    all the markers."""

    bids_params = _get_bids_params(bids_name)
    folder = None
    for f in os.listdir(fpath):
        if op.isdir(op.join(fpath, f)):
            if _bids_params_are_subsets(_get_bids_params(f), bids_params):
                # this is the folder containing the BIDS data we want.
                folder = op.join(fpath, f)
                break
    if folder is None:
        # In this case it is broken. Do nothing I guess...
        return
    fnames = list(os.listdir(folder))  # cache for safety
    # do a check for any existing marker files with acq in their title
    for fname in fnames:
        params = _get_bids_params(fname)
        if params['file'] == 'markers':
            if params.get('acq', None) is not None:
                os.remove(op.join(folder, fname))
                continue

    if len(confile.hpi) != 2:
        # If there is only one marker for the con file we don't need to do
        # anything.
        return

    # First entry in the list will always be the one that gets converted.
    converted = confile.hpi[0]
    not_converted = confile.hpi[1]

    # determine which marker is pre and which is post
    confile.hpi.sort(key=get_mrk_meas_date)
    order = ['pre', 'post']
    if confile.hpi.index(converted) != 0:
        order = ['post', 'pre']

    fnames = list(os.listdir(folder))  # recache for safety
    for fname in fnames:
        params = _get_bids_params(fname)
        if params['file'] == 'markers':
            params['suffix'] = params.pop('file') + params.pop('ext')
            bname = make_bids_basename(subject=params.get('sub', None),
                                       session=params.get('ses', None),
                                       run=params.get('run', None),
                                       task=params.get('task', None),
                                       suffix=params.get('suffix', None),
                                       acquisition=order[0])
            os.rename(op.join(folder, fname), op.join(folder, bname))
            bname = bname.replace('acq-{0}'.format(order[0]),
                                  'acq-{0}'.format(order[1]))
            shutil.copy(not_converted.file,
                        op.join(folder, op.basename(not_converted.file)))
            os.rename(op.join(folder, op.basename(not_converted.file)),
                      op.join(folder, bname))
def run_time_decoding(subject, condition1, condition2, session=None):
    print("Processing subject: %s (%s vs %s)"
          % (subject, condition1, condition2))

    # Construct the search path for the data file. `sub` is mandatory
    subject_path = op.join('sub-{}'.format(subject))
    # `session` is optional
    if session is not None:
        subject_path = op.join(subject_path, 'ses-{}'.format(session))

    subject_path = op.join(subject_path, config.kind)

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

    fpath_deriv = op.join(config.bids_root, 'derivatives',
                          config.PIPELINE_NAME, subject_path)
    fname_in = \
        op.join(fpath_deriv, bids_basename + '-epo.fif')

    epochs = mne.read_epochs(fname_in)

    # We define the epochs and the labels
    epochs = mne.concatenate_epochs([epochs[condition1],
                                     epochs[condition2]])
    epochs.apply_baseline()

    # Get the data and labels
    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)]

    # Use AUC because chance level is same regardless of the class balance
    se = SlidingEstimator(
        make_pipeline(StandardScaler(),
                      LogisticRegression(solver='liblinear',
                                         random_state=config.random_state)),
        scoring=config.decoding_metric, n_jobs=config.N_JOBS)
    cv = StratifiedKFold(random_state=config.random_state,
                         n_splits=config.decoding_n_splits)
    scores = cross_val_multiscore(se, X=X, y=y, cv=cv)

    # let's save the scores now
    a_vs_b = '%s_vs_%s' % (condition1, condition2)
    a_vs_b = a_vs_b.replace(op.sep, '')
    fname_td = op.join(config.bids_root, 'derivatives', config.PIPELINE_NAME,
                       '%s_%s_%s_%s.mat' %
                       (subject, config.study_name, a_vs_b,
                        config.decoding_metric))
    savemat(fname_td, {'scores': scores, 'times': epochs.times})
示例#23
0
def BrainSenseTimeDomain_to_bids(filename,
                                 subject,
                                 bids_folder='/bids',
                                 task='BrainSenseTimeDomain'):
    data = read_file(filename)
    opath, fname, ext = tb.fileparts(filename)
    if subject.find('-') > 0:
        subject = subject[subject.find('-') + 1:]
    session = data['SessionDate'][:-1].replace('-', '').replace(':', '')
    basename = make_bids_basename(subject=subject, task=task, session=session)
    bpath = make_bids_folders(subject=subject, session=session, make_dir=False)
    sourcename = make_bids_basename(subject=subject, session=session)
    raw = import_BrainSenseTimeDomain(filename)
    if raw is not None:
        rfig = raw.plot(color='k')
        rfig.savefig(
            pathlib.Path(bids_folder, bpath, 'eeg', 'sourcedata', 'figures',
                         basename + '.png'))
        if os.path.exists('tmp.edf'):
            os.remove('tmp.edf')
        ephys.mne_write_edf(raw, 'tmp.edf')
        raw = mne.io.read_raw_edf('tmp.edf')
        write_raw_bids(raw,
                       bids_basename=basename,
                       output_path=bids_folder,
                       overwrite=True)
        if not os.path.isdir(
                pathlib.Path(bids_folder, bpath, 'eeg', 'sourcedata')):
            os.makedirs(pathlib.Path(bids_folder, bpath, 'eeg', 'sourcedata'))
        shutil.copyfile(
            filename,
            pathlib.Path(bids_folder, bpath, 'eeg', 'sourcedata',
                         basename + ext))
        plot_wavelet_spectra(pathlib.Path(bids_folder, bpath, 'eeg',
                                          'sourcedata', basename + ext),
                             typefield=task)
        plot_BrainSenseLfp(
            pathlib.Path(bids_folder, bpath, 'eeg', 'sourcedata',
                         basename + ext))
        os.remove('tmp.edf')
        shutil.move(
            pathlib.Path(bids_folder, bpath, 'eeg', 'sourcedata',
                         basename + ext),
            pathlib.Path(bids_folder, bpath, 'eeg', 'sourcedata',
                         sourcename + ext))
示例#24
0
def test_make_filenames():
    """Test that we create filenames according to the BIDS spec."""
    # All keys work
    prefix_data = dict(subject='one',
                       session='two',
                       task='three',
                       acquisition='four',
                       run='five',
                       processing='six',
                       recording='seven',
                       suffix='suffix.csv')
    assert make_bids_basename(
        **prefix_data
    ) == 'sub-one_ses-two_task-three_acq-four_run-five_proc-six_recording-seven_suffix.csv'  # noqa

    # subsets of keys works
    assert make_bids_basename(subject='one', task='three',
                              run=4) == 'sub-one_task-three_run-04'  # noqa
    assert make_bids_basename(
        subject='one', task='three',
        suffix='hi.csv') == 'sub-one_task-three_hi.csv'  # noqa

    with pytest.raises(ValueError):
        make_bids_basename(subject='one-two', suffix='there.csv')

    with pytest.raises(ValueError, match='At least one'):
        make_bids_basename()
示例#25
0
 def _make_bids_basename(self, suffix):
     return make_bids_basename(
         subject=self.subject_id,
         session=self.session_id,
         acquisition=self.acquisition,
         task=self.task,
         run=self.run,
         suffix=suffix,
     )
示例#26
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()
示例#27
0
    def __init__(
        self, bids_root, bids_basename, kind=None, datatype="fif", verbose: bool = True
    ):
        self.bids_root = bids_root

        self.bids_basename = bids_basename
        # extract BIDS parameters from the bids filename to be loaded/modified
        # gets: subjectid, sessionid, acquisition type, task name, run, file extension
        params = _parse_bids_filename(self.bids_basename, verbose=verbose)
        self.subject_id, self.session_id = params["sub"], params["ses"]
        self.acquisition, self.task, self.run = (
            params["acq"],
            params["task"],
            params["run"],
        )
        self.ext = datatype.strip(".")

        if kind:
            self.kind = kind
        else:
            self.kind = self.acquisition
        if "meg" in self.kind:
            self.kind = "meg"
        elif "ieeg" in self.kind or "ecog" in self.kind or "seeg" in self.kind:
            self.kind = "ieeg"
        elif "eeg" in self.kind:
            self.kind = "eeg"

        self.subjdir = os.path.join(
            bids_root, make_bids_basename(subject=self.subject_id)
        )
        self.sessiondir = os.path.join(
            self.subjdir, make_bids_basename(session=self.session_id)
        )  # 'ses-' + self.session_id)
        self.runs_datadir = os.path.join(self.sessiondir, self.kind)

        SUPPORTED_DATATYPES = ["edf", "fif", "nii", "nii.gz", "mgz"]
        if self.ext.strip(".") not in SUPPORTED_DATATYPES:
            raise ValueError(
                f"Supported data file types are: {SUPPORTED_DATATYPES}. "
                f"You passed {self.ext}"
            )
示例#28
0
    def test_bids_setup(self, tmp_bids_root, edf_fpath):
        """
        Integration test for setting up a bids directory from scratch.

        Should test:
        1. Initial setup
        2. loading runs
        3. loading patients

        Parameters
        ----------
        bids_root :

        Returns
        -------

        """
        # create the BIDS dirctory structure
        test_subjectid = "0002"
        modality = "eeg"
        test_sessionid = "seizure"
        test_runid = "01"
        task = "monitor"
        line_freq = 60
        # create the BIDS directory structure
        if not os.path.exists(tmp_bids_root):
            print("Making bids root directory.")
            make_bids_folders(
                output_path=tmp_bids_root,
                session=test_sessionid,
                subject=test_subjectid,
                kind=modality,
            )
        # add a bids run
        bids_basename = make_bids_basename(
            subject=test_subjectid,
            acquisition=modality,
            session=test_sessionid,
            run=test_runid,
            task=task,
        )

        # call bidsbuilder pipeline
        tmp_bids_root = BidsConverter.convert_to_bids(
            edf_fpath=edf_fpath,
            bids_root=tmp_bids_root,
            bids_basename=bids_basename,
            line_freq=line_freq,
            overwrite=True,
        )

        # load it in using mne_bids again
        bids_fname = bids_basename + f"_{modality}.fif"
        raw = mne_bids.read_raw_bids(bids_fname, tmp_bids_root)
示例#29
0
def mne_write_bids(filename, subject, bids_folder='/bids', task='rest'):
    raw = mne.io.read_raw_brainvision(str(pathlib.Path(filename)))
    print(raw.annotations)
    raw.annotations.duration[raw.annotations.description ==
                             'DC Correction/'] = 6
    events, event_id = mne.events_from_annotations(
        raw)  # this needs to be checked
    write_raw_bids(raw,
                   make_bids_basename(subject=subject, task=task),
                   bids_folder,
                   overwrite=True)
示例#30
0
def run_maxwell_filter(subject, session=None):
    print("Processing subject: %s" % subject)

    # Construct the search path for the data file. `sub` is mandatory
    subject_path = op.join('sub-{}'.format(subject))
    # `session` is optional
    if session is not None:
        subject_path = op.join(subject_path, 'ses-{}'.format(session))

    subject_path = op.join(subject_path, config.kind)

    for run_idx, run in enumerate(config.runs):

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

        # Prepare a name to save the data
        fpath_deriv = op.join(config.bids_root, 'derivatives',
                              config.PIPELINE_NAME, subject_path)
        raw_fname_in = op.join(fpath_deriv, bids_basename + '_filt_raw.fif')
        raw_fname_out = op.join(fpath_deriv, bids_basename + '_sss_raw.fif')

        print("Input: ", raw_fname_in)
        print("Output: ", raw_fname_out)

        raw = mne.io.read_raw_fif(raw_fname_in, allow_maxshield=True)
        raw.fix_mag_coil_types()

        if run_idx == 0:
            destination = raw.info['dev_head_t']

        if config.mf_st_duration:
            print('    st_duration=%d' % (config.mf_st_duration, ))

        raw_sss = mne.preprocessing.maxwell_filter(
            raw,
            calibration=config.mf_cal_fname,
            cross_talk=config.mf_ctc_fname,
            st_duration=config.mf_st_duration,
            origin=config.mf_head_origin,
            destination=destination)

        raw_sss.save(raw_fname_out, overwrite=True)

        if config.plot:
            # plot maxfiltered data
            raw_sss.plot(n_channels=50, butterfly=True)