Source code for mne_bids.read

"""Check whether a file format is supported by BIDS and then load it."""
# Authors: Mainak Jas <mainak.jas@telecom-paristech.fr>
#          Alexandre Gramfort <alexandre.gramfort@telecom-paristech.fr>
#          Teon Brooks <teon.brooks@gmail.com>
#          Chris Holdgraf <choldgraf@berkeley.edu>
#          Stefan Appelhoff <stefan.appelhoff@mailbox.org>
#
# License: BSD (3-clause)
import os
import os.path as op
import glob

import numpy as np
from mne import io

from .tsv_handler import _from_tsv, _drop
from .config import ALLOWED_EXTENSIONS

reader = {'.con': io.read_raw_kit, '.sqd': io.read_raw_kit,
          '.fif': io.read_raw_fif, '.pdf': io.read_raw_bti,
          '.ds': io.read_raw_ctf, '.vhdr': io.read_raw_brainvision,
          '.edf': io.read_raw_edf, '.bdf': io.read_raw_edf,
          '.set': io.read_raw_eeglab}


def _parse_ext(raw_fname, verbose=False):
    """Split a filename into its name and extension."""
    fname, ext = os.path.splitext(raw_fname)
    # BTi data is the only file format that does not have a file extension
    if ext == '' or 'c,rf' in fname:
        if verbose is True:
            print('Found no extension for raw file, assuming "BTi" format and '
                  'appending extension .pdf')
        ext = '.pdf'
    return fname, ext


def _read_raw(raw_fname, electrode=None, hsp=None, hpi=None, config=None,
              montage=None, verbose=None, allow_maxshield=False):
    """Read a raw file into MNE, making inferences based on extension."""
    fname, ext = _parse_ext(raw_fname)

    # KIT systems
    if ext in ['.con', '.sqd']:
        raw = io.read_raw_kit(raw_fname, elp=electrode, hsp=hsp,
                              mrk=hpi, preload=False)

    # BTi systems
    elif ext == '.pdf':
        raw = io.read_raw_bti(raw_fname, config_fname=config,
                              head_shape_fname=hsp,
                              preload=False, verbose=verbose)

    elif ext == '.fif':
        raw = reader[ext](raw_fname, allow_maxshield=allow_maxshield)

    elif ext in ['.ds', '.vhdr', '.set']:
        raw = reader[ext](raw_fname)

    # EDF (european data format) or BDF (biosemi) format
    # TODO: integrate with lines above once MNE can read
    # annotations with preload=False
    elif ext in ['.edf', '.bdf']:
        raw = reader[ext](raw_fname, preload=True)

    # MEF and NWB are allowed, but not yet implemented
    elif ext in ['.mef', '.nwb']:
        raise ValueError('Got "{}" as extension. This is an allowed extension '
                         'but there is no IO support for this file format yet.'
                         .format(ext))

    # No supported data found ...
    # ---------------------------
    else:
        raise ValueError('Raw file name extension must be one of {}\n'
                         'Got {}'.format(ALLOWED_EXTENSIONS, ext))
    return raw


[docs]def read_raw_bids(bids_fname, bids_root, return_events=True, verbose=True): """Read BIDS compatible data. Parameters ---------- bids_fname : str Full name of the data file bids_root : str Path to root of the BIDS folder return_events: bool Whether to return events or not. Default is True. verbose : bool The verbosity level Returns ------- raw : instance of Raw The data as MNE-Python Raw object. events : ndarray, shape = (n_events, 3) The first column contains the event time in samples and the third column contains the event id. The second column is ignored for now but typically contains the value of the trigger channel either immediately before the event or immediately after. event_id : dict Dictionary of events in the raw data mapping from the event value to an index. """ from .utils import _parse_bids_filename # Full path to data file is needed so that mne-bids knows # what is the modality -- meg, eeg, ieeg to read bids_basename = '_'.join(bids_fname.split('_')[:-1]) kind = bids_fname.split('_')[-1].split('.')[0] _, ext = _parse_ext(bids_fname) params = _parse_bids_filename(bids_basename, verbose) kind_dir = op.join(bids_root, 'sub-%s' % params['sub'], 'ses-%s' % params['ses'], kind) config = None if ext in ('.fif', '.ds', '.vhdr', '.edf', '.bdf', '.set', '.sqd', '.con'): bids_fname = op.join(kind_dir, bids_basename + '_%s%s' % (kind, ext)) elif ext == '.pdf': bids_raw_folder = op.join(kind_dir, bids_basename + '_%s' % kind) bids_fname = glob.glob(op.join(bids_raw_folder, 'c,rf*'))[0] config = op.join(bids_raw_folder, 'config') raw = _read_raw(bids_fname, electrode=None, hsp=None, hpi=None, config=config, montage=None, verbose=None) events_fname = op.join(kind_dir, bids_basename + '_events.tsv') if not return_events: return raw if not op.exists(events_fname): raise ValueError('return_events=True but _events.tsv file' ' not found') events, event_id = None, dict() dtypes = [float, float, str, int, int] events_dict = _from_tsv(events_fname, dtypes=dtypes) events_dict = _drop(events_dict, 'n/a', 'trial_type') if 'trial_type' not in events_dict: raise ValueError('trial_type column is missing. Cannot' ' return events') for idx, ev in enumerate(np.unique(events_dict['trial_type'])): event_id[ev] = idx events = np.zeros((len(events_dict['onset']), 3), dtype=int) events[:, 0] = np.array(events_dict['onset']) * raw.info['sfreq'] + \ raw.first_samp events[:, 2] = np.array([event_id[ev] for ev in events_dict['trial_type']]) return raw, events, event_id