Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] fix channel units for EEG and iEEG #124

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
6dbf9e2
Simplify raw_to_bids
jasmainak Oct 4, 2018
9f1afb2
TST start modifying tests
jasmainak Oct 14, 2018
e56fbc5
TST commands + io
jasmainak Oct 15, 2018
2329d6f
DOC update example
jasmainak Oct 15, 2018
e12fc43
TST more fixes
jasmainak Oct 15, 2018
3893742
ENH: don't need kind in write_raw_bids
jasmainak Oct 15, 2018
8c6ec21
MAINT change variable names
jasmainak Oct 15, 2018
bb8b955
Take care of hpi
jasmainak Oct 16, 2018
9aebb31
FIX for rebase after overwrite PR
jasmainak Oct 19, 2018
b56b1c9
TST improve coverage
jasmainak Oct 19, 2018
5a445c5
TST change eeglab checks
jasmainak Oct 19, 2018
208b815
DOC: Update readme.rst
jasmainak Oct 21, 2018
c7e2ae4
ENH: address sappelhoff comments
jasmainak Oct 21, 2018
afab4e2
FIX tests
jasmainak Oct 21, 2018
cc14f9c
ENH: address comments by Matt
jasmainak Oct 21, 2018
ef9e116
TST ordering of key-value pairs in filename
jasmainak Oct 21, 2018
b402150
ENH: add hpi param
jasmainak Oct 21, 2018
e1386b8
TST check kind
jasmainak Oct 21, 2018
2eaccda
TST for keeping same filetype
jasmainak Oct 22, 2018
1cf4e53
DOC minor fixes
jasmainak Oct 22, 2018
47f8e62
WIP: make_bids_basename
jasmainak Oct 23, 2018
976aba0
WIP: don't make read_raw public
jasmainak Oct 25, 2018
5afa95f
WIP: raw.preload=False
jasmainak Oct 25, 2018
2074a66
DOC: Update examples
jasmainak Oct 26, 2018
75b02c9
FIX test
jasmainak Oct 26, 2018
003a811
DOC update quickstart
jasmainak Oct 26, 2018
cc5ad78
add comment
jasmainak Oct 26, 2018
2444990
edf example + raw.preload
jasmainak Oct 26, 2018
0ea50dd
TST make circle happy
jasmainak Oct 27, 2018
450310b
FIX --raw_fname -> --raw
jasmainak Oct 29, 2018
2989e65
TST checks for making sure raw data does not change
jasmainak Oct 29, 2018
a471299
ENH: Use raw._init_kwargs to check raw.times
jasmainak Nov 1, 2018
1632aae
ENH add license (#121)
jasmainak Oct 19, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
source activate testenv
conda install --yes --quiet numpy=1.13.1 scipy=0.19.1 matplotlib pandas=0.20.3
pip install sphinx numpydoc sphinx-gallery sphinx_bootstrap_theme pillow
pip install mne
pip install -U https://api.github.com/repos/mne-tools/mne-python/zipball/master
python setup.py develop
- run:
name: Build the documentation
Expand Down
30 changes: 30 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
BSD 3-Clause License

Copyright (c) 2018, MNE tools for MEG and EEG data analysis
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.

* Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

7 changes: 4 additions & 3 deletions doc/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ MNE BIDS (:py:mod:`mne_bids.mne_bids`):
.. autosummary::
:toctree: generated/

raw_to_bids
write_raw_bids
make_bids_basename
make_bids_folders

Utils (:py:mod:`mne_bids.utils`):

Expand All @@ -23,10 +25,9 @@ Utils (:py:mod:`mne_bids.utils`):
:toctree: generated/

print_dir_tree
make_bids_folders
make_bids_filename
make_dataset_description
copyfile_brainvision
copyfile_eeglab

Datasets (:py:mod:`mne_bids.datasets`):

Expand Down
22 changes: 19 additions & 3 deletions doc/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,37 @@ Installation

We recommend the `Anaconda Python distribution <https://www.continuum.io/downloads>`_. To install ``mne_bids``, you first need to install its dependencies::

$ pip install pandas mne
$ pip install pandas
$ pip install -U https://api.github.com/repos/mne-tools/mne-python/zipball/master

Then install mne_bids::

$ pip install git+https://github.com/mne-tools/mne-bids.git#egg=mne-bids
$ pip install git+https://github.com/mne-tools/mne-bids.git#egg=mne-bids

If you do not have admin privileges on the computer, use the ``--user`` flag
with `pip`. To upgrade, use the ``--upgrade`` flag provided by `pip`.

To check if everything worked fine, you can do::

$ python -c 'import mne_bids'
$ python -c 'import mne_bids'

and it should not give any error messages.

Quickstart
==========

Currently, we support writing of BIDS datasets for MEG and EEG. Support for
iEEG is experimental at the moment.

.. code:: python

>>> from mne import io
>>> from mne_bids import write_raw_bids
>>> raw = io.read_raw_fif('my_old_file.fif')
>>> write_raw_bids(raw, 'sub-01_ses-01_run-05', output_path='./bids_dataset')

Reading of BIDS data will also be supported in the next version.

Bug reports
===========

Expand Down
79 changes: 41 additions & 38 deletions examples/convert_eeg_to_bids.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,11 @@
import os
import shutil as sh

import mne
from mne.datasets import eegbci
from mne.io import read_raw_edf
from mne.io.edf.edf import read_annotations_edf

from mne_bids import raw_to_bids
from mne_bids import write_raw_bids, make_bids_basename
from mne_bids.utils import print_dir_tree

###############################################################################
Expand Down Expand Up @@ -84,27 +85,35 @@
# --------------------------
#
# Let's start by formatting a single subject. We are reading the data using
# MNE-Python's io module and the `read_raw_edf` function.
data_dir = os.path.join(data_dir, 'physiobank', 'database', 'eegmmidb')
edf_path = os.path.join(data_dir, 'S001', 'S001R02.edf')
raw = read_raw_edf(edf_path, preload=True)
# MNE-Python's io module and the `read_raw_edf` function. Note that we must
# use `preload=False`, the default in MNE-Python. It prevents the data from
# being loaded and modified when converting to BIDS.
edf_path = eegbci.load_data(subject=1, runs=2)[0]
raw = mne.io.read_raw_edf(edf_path, preload=False, stim_channel=None)

###############################################################################
# The annotations stored in the file mut be read in separately and converted
# into a 2D numpy array of events that is compatible with MNE.
annot = read_annotations_edf(edf_path)
raw.set_annotations(annot)
events, event_id = mne.events_from_annotations(raw)

print(raw)

###############################################################################
# With this simple step we have everything to start a new BIDS directory using
# our data. To do that, we can use the high level function `raw_to_bids`, which
# is the core of MNE-BIDS. Generally, `raw_to_bids` tries to extract as much
# With this step, we have everything to start a new BIDS directory using
# our data. To do that, we can use the function `write_raw_bids`
# Generally, `write_raw_bids` tries to extract as much
# meta data as possible from the raw data and then formats it in a BIDS
# compatible way. `raw_to_bids` takes a bunch of inputs, most of which are
# compatible way. `write_raw_bids` takes a bunch of inputs, most of which are
# however optional. The required inputs are:
#
# * subject_id
# * task
# * raw_file
# * raw
# * bids_fname
# * output_path
#
# ... as you can see in the docstring:
print(raw_to_bids.__doc__)
print(write_raw_bids.__doc__)

###############################################################################
# We loaded 'S001R02.edf', which corresponds to subject 1 in the second task.
Expand All @@ -117,19 +126,15 @@
###############################################################################
# Now we just need to specify a few more EEG details to get something sensible:

# First, tell `MNE-BIDS` that it is working with EEG data:
kind = 'eeg'

# Brief description of the event markers present in the data. This will become
# the `trial_type` column in our BIDS `events.tsv`. We know about the event
# meaning from the documentation on PhysioBank
trial_type = {'rest': 0, 'imagine left fist': 1, 'imagine right fist': 2}

# Now convert our data to be in a new BIDS dataset.
raw_to_bids(subject_id=subject_id, task=task, raw_file=raw_file,
output_path=output_path, kind=kind, event_id=trial_type,
overwrite=False)

bids_fname = make_bids_basename(subject=subject_id, task=task)
write_raw_bids(raw_file, bids_fname, output_path, event_id=trial_type,
events_data=events, overwrite=True)
###############################################################################
# What does our fresh BIDS directory look like?
print_dir_tree(output_path)
Expand All @@ -155,21 +160,18 @@
for subj_idx in [1, 2]:
for task_idx in [2, 4, 12]:
# Load the data
edf_path = os.path.join(data_dir,
'S{:03}'.format(subj_idx),
'S{:03}R{:02}.edf'.format(subj_idx, task_idx))
raw = read_raw_edf(edf_path, preload=True)

# `kind` and `trial_type` were already defined above
raw_to_bids(subject_id='{:03}'.format(subj_idx),
task=task_names[task_idx],
run=run_mapping[task_idx],
raw_file=raw,
output_path=output_path,
kind=kind,
event_id=trial_type,
overwrite=True
)
edf_path = eegbci.load_data(subject=subj_idx, runs=task_idx)[0]

raw = mne.io.read_raw_edf(edf_path, preload=False, stim_channel=None)
annot = read_annotations_edf(edf_path)
raw.set_annotations(annot)
events, event_id = mne.events_from_annotations(raw)

make_bids_basename(
subject='{:03}'.format(subj_idx), task=task_names[task_idx],
run=run_mapping[task_idx])
write_raw_bids(raw, bids_fname, output_path, event_id=trial_type,
events_data=events, overwrite=True)

###############################################################################
# Step 3: Check and compare with standard
Expand All @@ -183,8 +185,9 @@
# initial `dataset_description` on top!
#
# Now it's time to manually check the BIDS directory and the meta files to add
# all the information that MNE-BIDS could not infer. These places are marked
# with "n/a".
# all the information that MNE-BIDS could not infer. For instance, you must
# describe EEGReference and EEGGround yourself. It's easy to find these by
# searching for "n/a" in the sidecar files.
#
# Remember that there is a convenient javascript tool to validate all your BIDS
# directories called the "BIDS-validator", available as a web version and a
Expand Down
19 changes: 11 additions & 8 deletions examples/convert_group_studies.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@
# Let us import ``mne_bids``

import os.path as op
from mne_bids import raw_to_bids

import mne
from mne_bids import write_raw_bids
from mne_bids.datasets import fetch_faces_data
from mne_bids.utils import print_dir_tree

Expand Down Expand Up @@ -63,13 +65,14 @@
for subject_id in subject_ids:
subject = 'sub%03d' % subject_id
for run in runs:
raw_file = op.join(data_path, repo, subject, 'MEG',
'run_%02d_raw.fif' % run)

# Make it BIDS compatible
raw_to_bids(subject_id='%02d' % subject_id, session_id='01', run=run,
task='VisualFaces', raw_file=raw_file, event_id=event_id,
output_path=output_path, overwrite=True)
raw_fname = op.join(data_path, repo, subject, 'MEG',
'run_%02d_raw.fif' % run)

raw = mne.io.read_raw_fif(raw_fname)
bids_fname = ('sub-%02d_ses-01_task-VisualFaces_run-%d'
% (subject_id, run))
write_raw_bids(raw, bids_fname, output_path, event_id=event_id,
overwrite=True)

###############################################################################
# Now let's see the structure of the BIDS folder we created.
Expand Down
15 changes: 9 additions & 6 deletions examples/convert_mne_sample.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,11 @@
# Let us import mne_bids

import os.path as op

import mne
from mne.datasets import sample
from mne_bids import raw_to_bids

from mne_bids import write_raw_bids
from mne_bids.utils import print_dir_tree

###############################################################################
Expand All @@ -28,17 +31,17 @@
event_id = {'Auditory/Left': 1, 'Auditory/Right': 2, 'Visual/Left': 3,
'Visual/Right': 4, 'Smiley': 5, 'Button': 32}

raw_file = op.join(data_path, 'MEG', 'sample', 'sample_audvis_raw.fif')
raw_fname = op.join(data_path, 'MEG', 'sample', 'sample_audvis_raw.fif')
events_data = op.join(data_path, 'MEG', 'sample', 'sample_audvis_raw-eve.fif')
output_path = op.join(data_path, '..', 'MNE-sample-data-bids')

###############################################################################
# Finally, we specify the raw_file and events_data

raw_to_bids(subject_id='01', run='01', session_id='01', task='audiovisual',
raw_file=raw_file, events_data=events_data,
output_path=output_path, event_id=event_id,
overwrite=False)
raw = mne.io.read_raw_fif(raw_fname)
bids_fname = 'sub-01_ses-01_task-audiovisual_run-01'
write_raw_bids(raw, bids_fname, output_path, events_data=events_data,
event_id=event_id, overwrite=True)

###############################################################################
# Now let's see the structure of the BIDS folder we created.
Expand Down
8 changes: 4 additions & 4 deletions examples/create_bids_folder.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,26 +19,26 @@
###############################################################################
# We'll import the relevant functions from the utils module

from mne_bids import make_bids_folders, make_bids_filename
from mne_bids import make_bids_folders, make_bids_basename

###############################################################################
# Creating file names for BIDS
# ----------------------------
#
# BIDS requires a specific ordering and structure for metadata fields in
# file paths, the function `filename_bids` allows you to specify many such
# file paths, the function `make_bids_basename` allows you to specify many such
# pieces of metadata, ensuring that they are in the correct order in the
# final file path. Omitted keys will not be included in the file path.

my_name = make_bids_filename(subject='test', session='two', task='mytask',
my_name = make_bids_basename(subject='test', session='two', task='mytask',
suffix='data.csv')
print(my_name)

###############################################################################
# You may also omit the suffix, which will result in *only* a prefix for a
# file name. This could then prepended to many more files.

my_name = make_bids_filename(subject='test', task='mytask')
my_name = make_bids_basename(subject='test', task='mytask')
print(my_name)

###############################################################################
Expand Down
4 changes: 2 additions & 2 deletions mne_bids/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
__version__ = '0.1.dev0'


from .mne_bids import raw_to_bids # noqa
from .utils import make_bids_folders, make_bids_filename # noqa
from .mne_bids import write_raw_bids # noqa
from .utils import make_bids_folders, make_bids_basename # noqa
from .config import BIDS_VERSION # noqa
26 changes: 15 additions & 11 deletions mne_bids/commands/mne_bids_raw_to_bids.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@
"""Command line interface for mne_bids.

example usage: $ mne_bids raw_to_bids --subject_id sub01 --task rest
--raw_file data.edf --output_path new_path
--raw data.edf --output_path new_path

"""

from mne_bids import raw_to_bids
from mne_bids import write_raw_bids, make_bids_basename
from mne_bids.io import _read_raw


def run():
Expand All @@ -24,7 +24,7 @@ def run():
parser.add_option('--task', dest='task',
help='Name of the task the data is based on.',
metavar='t')
parser.add_option('--raw_file', dest='raw_file',
parser.add_option('--raw', dest='raw_fname',
help='The path to the raw MEG file.', metavar='r')
parser.add_option('--output_path', dest='output_path',
help='The path of the BIDS compatible folder.',
Expand All @@ -35,6 +35,9 @@ def run():
parser.add_option('--run', dest='run',
help='The run number for this dataset.',
metavar='run')
parser.add_option('--acq', dest='acq',
help='The acquisition parameter.',
metavar='acq')
parser.add_option('--kind', dest='kind',
help='The kind of data being converted.',
metavar='k')
Expand All @@ -58,13 +61,14 @@ def run():

opt, args = parser.parse_args()

raw_to_bids(subject_id=opt.subject_id, task=opt.task,
raw_file=opt.raw_file, output_path=opt.output_path,
session_id=opt.session_id, run=opt.run, kind=opt.kind,
events_data=opt.events_data, event_id=opt.event_id,
hpi=opt.hpi, electrode=opt.electrode, hsp=opt.hsp,
config=opt.config, overwrite=opt.overwrite,
verbose=True)
bids_fname = make_bids_basename(
subject=opt.subject_id, session=opt.session_id, run=opt.run,
acquisition=opt.acq, task=opt.task)
raw = _read_raw(opt.raw_fname, hpi=opt.hpi, electrode=opt.electrode,
hsp=opt.hsp, config=opt.config)
write_raw_bids(raw, bids_fname, opt.output_path, event_id=opt.event_id,
events_data=opt.events_data, overwrite=opt.overwrite,
verbose=True)


is_main = (__name__ == '__main__')
Expand Down
Loading