01. Read BIDS datasets#

When working with electrophysiological data in the BIDS format, an important resource is the OpenNeuro database. OpenNeuro works great with MNE-BIDS because every dataset must pass a validator that tests to ensure its format meets BIDS specifications before the dataset can be uploaded, so you know the data will work with a script like in this example without modification.

We have various data types that can be loaded via the read_raw_bids function:

  • MEG

  • EEG (scalp electrodes)

  • iEEG (ECoG and SEEG)

  • the anatomical MRI scan of a study participant

In this tutorial, we show how read_raw_bids can be used to load and inspect BIDS-formatted data.

# Authors: Adam Li <adam2392@gmail.com>
#          Richard Höchenberger <richard.hoechenberger@gmail.com>
#          Alex Rockhill <aprockhill@mailbox.org>
#
# License: BSD-3-Clause

Imports#

We are importing everything we need for this example:

import os
import os.path as op
import openneuro

from mne.datasets import sample
from mne_bids import BIDSPath, read_raw_bids, print_dir_tree, make_report

Download a subject’s data from an OpenNeuro BIDS dataset#

Download the data, storing each in a target_dir target directory, which, in mne-bids terminology, is the root of each BIDS dataset. This example uses this EEG dataset of resting-state recordings of patients with Parkinson’s disease.

# .. note: If the keyword argument include is left out of
#          ``openneuro.download``, the whole dataset will be downloaded.
#          We're just using data from one subject to reduce the time
#          it takes to run the example.

dataset = 'ds002778'
subject = 'pd6'

# Download one subject's data from each dataset
bids_root = op.join(op.dirname(sample.data_path()), dataset)
if not op.isdir(bids_root):
    os.makedirs(bids_root)

openneuro.download(dataset=dataset, target_dir=bids_root,
                   include=[f'sub-{subject}'])
Hello! This is openneuro-py 2022.2.0. Great to see you!

      Please report problems and bugs at
      https://github.com/hoechenberger/openneuro-py/issues

Preparing to download ds002778 ...

Traversing directories for ds002778: 0 entities [00:00, ? entities/s]
Traversing directories for ds002778: 7 entities [00:00,  9.27 entities/s]
Traversing directories for ds002778: 8 entities [00:01,  5.91 entities/s]
Traversing directories for ds002778: 10 entities [00:01,  5.53 entities/s]
Traversing directories for ds002778: 14 entities [00:02,  5.20 entities/s]
Traversing directories for ds002778: 15 entities [00:02,  4.51 entities/s]
Traversing directories for ds002778: 17 entities [00:03,  4.56 entities/s]
Traversing directories for ds002778: 21 entities [00:04,  4.70 entities/s]
Traversing directories for ds002778: 22 entities [00:04,  4.15 entities/s]
Traversing directories for ds002778: 24 entities [00:04,  4.40 entities/s]
Traversing directories for ds002778: 28 entities [00:06,  3.09 entities/s]
Traversing directories for ds002778: 29 entities [00:06,  3.10 entities/s]
Traversing directories for ds002778: 31 entities [00:07,  3.48 entities/s]
Traversing directories for ds002778: 35 entities [00:08,  4.09 entities/s]
Traversing directories for ds002778: 36 entities [00:08,  3.87 entities/s]
Traversing directories for ds002778: 38 entities [00:08,  4.28 entities/s]
Traversing directories for ds002778: 42 entities [00:09,  4.57 entities/s]
Traversing directories for ds002778: 43 entities [00:10,  4.09 entities/s]
Traversing directories for ds002778: 45 entities [00:10,  4.48 entities/s]
Traversing directories for ds002778: 49 entities [00:11,  4.71 entities/s]
Traversing directories for ds002778: 50 entities [00:11,  4.18 entities/s]
Traversing directories for ds002778: 52 entities [00:11,  4.36 entities/s]
Traversing directories for ds002778: 56 entities [00:12,  4.58 entities/s]
Traversing directories for ds002778: 57 entities [00:13,  4.09 entities/s]
Traversing directories for ds002778: 59 entities [00:13,  4.29 entities/s]
Traversing directories for ds002778: 63 entities [00:14,  4.53 entities/s]
Traversing directories for ds002778: 64 entities [00:14,  4.06 entities/s]
Traversing directories for ds002778: 66 entities [00:15,  4.25 entities/s]
Traversing directories for ds002778: 70 entities [00:16,  4.52 entities/s]
Traversing directories for ds002778: 71 entities [00:16,  4.20 entities/s]
Traversing directories for ds002778: 73 entities [00:16,  4.46 entities/s]
Traversing directories for ds002778: 77 entities [00:17,  4.65 entities/s]
Traversing directories for ds002778: 78 entities [00:17,  4.36 entities/s]
Traversing directories for ds002778: 80 entities [00:18,  4.73 entities/s]
Traversing directories for ds002778: 84 entities [00:19,  4.88 entities/s]
Traversing directories for ds002778: 85 entities [00:19,  4.30 entities/s]
Traversing directories for ds002778: 87 entities [00:19,  4.44 entities/s]
Traversing directories for ds002778: 91 entities [00:20,  4.63 entities/s]
Traversing directories for ds002778: 92 entities [00:21,  4.12 entities/s]
Traversing directories for ds002778: 94 entities [00:21,  4.49 entities/s]
Traversing directories for ds002778: 98 entities [00:22,  4.95 entities/s]
Traversing directories for ds002778: 99 entities [00:22,  4.57 entities/s]
Traversing directories for ds002778: 101 entities [00:22,  4.79 entities/s]
Traversing directories for ds002778: 105 entities [00:23,  4.83 entities/s]
Traversing directories for ds002778: 106 entities [00:24,  4.26 entities/s]
Traversing directories for ds002778: 108 entities [00:24,  4.41 entities/s]
Traversing directories for ds002778: 112 entities [00:25,  4.86 entities/s]
Traversing directories for ds002778: 113 entities [00:25,  4.29 entities/s]
Traversing directories for ds002778: 115 entities [00:26,  4.44 entities/s]
Traversing directories for ds002778: 119 entities [00:26,  4.88 entities/s]
Traversing directories for ds002778: 120 entities [00:27,  4.50 entities/s]
Traversing directories for ds002778: 122 entities [00:27,  4.68 entities/s]
Traversing directories for ds002778: 126 entities [00:27,  6.09 entities/s]
Traversing directories for ds002778: 127 entities [00:28,  5.05 entities/s]
Traversing directories for ds002778: 129 entities [00:28,  5.01 entities/s]
Traversing directories for ds002778: 133 entities [00:29,  5.02 entities/s]
Traversing directories for ds002778: 134 entities [00:29,  4.32 entities/s]
Traversing directories for ds002778: 136 entities [00:30,  4.46 entities/s]
Traversing directories for ds002778: 140 entities [00:30,  5.89 entities/s]
Traversing directories for ds002778: 141 entities [00:31,  4.93 entities/s]
Traversing directories for ds002778: 143 entities [00:31,  4.93 entities/s]
Traversing directories for ds002778: 147 entities [00:32,  5.31 entities/s]
Traversing directories for ds002778: 148 entities [00:32,  4.76 entities/s]
Traversing directories for ds002778: 150 entities [00:32,  4.79 entities/s]
Traversing directories for ds002778: 154 entities [00:33,  5.80 entities/s]
Traversing directories for ds002778: 155 entities [00:33,  4.89 entities/s]
Traversing directories for ds002778: 157 entities [00:34,  4.87 entities/s]
Traversing directories for ds002778: 161 entities [00:35,  4.88 entities/s]
Traversing directories for ds002778: 162 entities [00:35,  4.29 entities/s]
Traversing directories for ds002778: 164 entities [00:35,  4.60 entities/s]
Traversing directories for ds002778: 168 entities [00:36,  5.80 entities/s]
Traversing directories for ds002778: 169 entities [00:36,  4.89 entities/s]
Traversing directories for ds002778: 171 entities [00:37,  4.89 entities/s]
Traversing directories for ds002778: 175 entities [00:37,  5.12 entities/s]
Traversing directories for ds002778: 176 entities [00:38,  4.49 entities/s]
Traversing directories for ds002778: 178 entities [00:38,  4.59 entities/s]
Traversing directories for ds002778: 182 entities [00:39,  6.01 entities/s]
Traversing directories for ds002778: 183 entities [00:39,  5.02 entities/s]
Traversing directories for ds002778: 185 entities [00:39,  4.97 entities/s]
Traversing directories for ds002778: 189 entities [00:40,  4.93 entities/s]
Traversing directories for ds002778: 190 entities [00:41,  4.32 entities/s]
Traversing directories for ds002778: 192 entities [00:41,  4.47 entities/s]
Traversing directories for ds002778: 196 entities [00:41,  5.89 entities/s]
Traversing directories for ds002778: 197 entities [00:42,  4.94 entities/s]
Traversing directories for ds002778: 199 entities [00:42,  4.93 entities/s]
Traversing directories for ds002778: 203 entities [00:43,  5.19 entities/s]
Traversing directories for ds002778: 204 entities [00:43,  4.68 entities/s]
Traversing directories for ds002778: 206 entities [00:44,  4.86 entities/s]
Traversing directories for ds002778: 210 entities [00:44,  6.27 entities/s]
Traversing directories for ds002778: 211 entities [00:45,  5.15 entities/s]
Traversing directories for ds002778: 213 entities [00:45,  5.32 entities/s]
Traversing directories for ds002778: 217 entities [00:46,  4.94 entities/s]
Traversing directories for ds002778: 218 entities [00:46,  4.33 entities/s]
Traversing directories for ds002778: 220 entities [00:47,  4.47 entities/s]
Traversing directories for ds002778: 224 entities [00:47,  5.90 entities/s]
Traversing directories for ds002778: 225 entities [00:47,  4.94 entities/s]
Traversing directories for ds002778: 227 entities [00:48,  5.14 entities/s]
Traversing directories for ds002778: 231 entities [00:49,  5.14 entities/s]
Traversing directories for ds002778: 232 entities [00:49,  4.47 entities/s]
Traversing directories for ds002778: 234 entities [00:49,  4.57 entities/s]
Traversing directories for ds002778: 238 entities [00:50,  6.00 entities/s]
Traversing directories for ds002778: 239 entities [00:50,  4.99 entities/s]
Traversing directories for ds002778: 241 entities [00:51,  4.96 entities/s]
Traversing directories for ds002778: 245 entities [00:51,  5.10 entities/s]
Traversing directories for ds002778: 246 entities [00:52,  4.55 entities/s]
Traversing directories for ds002778: 248 entities [00:52,  4.64 entities/s]
Traversing directories for ds002778: 252 entities [00:53,  6.06 entities/s]
Traversing directories for ds002778: 253 entities [00:53,  5.27 entities/s]
Traversing directories for ds002778: 255 entities [00:53,  5.44 entities/s]
Traversing directories for ds002778: 259 entities [00:54,  5.38 entities/s]
Traversing directories for ds002778: 260 entities [00:54,  4.62 entities/s]
Traversing directories for ds002778: 262 entities [00:55,  4.69 entities/s]
Traversing directories for ds002778: 266 entities [00:55,  6.11 entities/s]
Traversing directories for ds002778: 267 entities [00:56,  5.31 entities/s]
Traversing directories for ds002778: 269 entities [00:56,  5.32 entities/s]
Traversing directories for ds002778: 273 entities [00:57,  5.12 entities/s]
Traversing directories for ds002778: 274 entities [00:57,  4.44 entities/s]
Traversing directories for ds002778: 276 entities [00:57,  4.76 entities/s]
Traversing directories for ds002778: 280 entities [00:58,  6.33 entities/s]
Traversing directories for ds002778: 281 entities [00:58,  5.44 entities/s]
Traversing directories for ds002778: 283 entities [00:59,  5.43 entities/s]
Traversing directories for ds002778: 287 entities [00:59,  5.17 entities/s]
Traversing directories for ds002778: 288 entities [01:00,  4.48 entities/s]
Traversing directories for ds002778: 290 entities [01:00,  4.59 entities/s]
Traversing directories for ds002778: 294 entities [01:01,  6.01 entities/s]
Traversing directories for ds002778: 295 entities [01:01,  5.00 entities/s]
Traversing directories for ds002778: 297 entities [01:01,  4.97 entities/s]
Traversing directories for ds002778: 301 entities [01:02,  5.00 entities/s]
Traversing directories for ds002778: 302 entities [01:03,  4.31 entities/s]
Traversing directories for ds002778: 304 entities [01:03,  4.45 entities/s]
Traversing directories for ds002778: 308 entities [01:03,  6.15 entities/s]
Traversing directories for ds002778: 309 entities [01:04,  5.32 entities/s]
Traversing directories for ds002778: 311 entities [01:04,  5.10 entities/s]
Traversing directories for ds002778: 315 entities [01:05,  5.19 entities/s]
Traversing directories for ds002778: 316 entities [01:05,  4.59 entities/s]
Traversing directories for ds002778: 318 entities [01:06,  4.67 entities/s]
Traversing directories for ds002778: 322 entities [01:06,  6.31 entities/s]
Traversing directories for ds002778: 323 entities [01:06,  5.37 entities/s]
Traversing directories for ds002778: 325 entities [01:07,  5.23 entities/s]
Traversing directories for ds002778: 328 entities [01:07,  4.87 entities/s]
Retrieving up to 19 files (5 concurrent downloads).

Skipping participants.json: already downloaded.: 100%|##########| 1.24k/1.24k [00:00<?, ?B/s]


Skipping participants.tsv: already downloaded.: 100%|##########| 1.62k/1.62k [00:00<?, ?B/s]


Skipping sub-pd6_ses-off_task-rest_beh.tsv: already downloaded.: 100%|##########| 10.0/10.0 [00:00<?, ?B/s]


Skipping sub-pd6_ses-off_scans.tsv: already downloaded.: 100%|##########| 75.0/75.0 [00:00<?, ?B/s]


Skipping sub-pd6_ses-off_task-rest_eeg.json: already downloaded.: 100%|##########| 471/471 [00:00<?, ?B/s]


Skipping sub-pd6_ses-off_task-rest_channels.tsv: already downloaded.: 100%|##########| 2.22k/2.22k [00:00<?, ?B/s]


Skipping sub-pd6_ses-off_task-rest_eeg.bdf: already downloaded.: 100%|##########| 11.5M/11.5M [00:00<?, ?B/s]


Skipping sub-pd6_ses-off_task-rest_events.tsv: already downloaded.: 100%|##########| 66.0/66.0 [00:00<?, ?B/s]


Skipping sub-pd6_ses-on_scans.tsv: already downloaded.: 100%|##########| 74.0/74.0 [00:00<?, ?B/s]


Skipping sub-pd6_ses-on_task-rest_beh.tsv: already downloaded.: 100%|##########| 10.0/10.0 [00:00<?, ?B/s]


Skipping sub-pd6_ses-on_task-rest_channels.tsv: already downloaded.: 100%|##########| 2.22k/2.22k [00:00<?, ?B/s]


Skipping sub-pd6_ses-on_task-rest_beh.json: already downloaded.: 100%|##########| 433/433 [00:00<?, ?B/s]


Skipping sub-pd6_ses-on_task-rest_eeg.json: already downloaded.: 100%|##########| 471/471 [00:00<?, ?B/s]


Re-downloading CHANGES: file size mismatch.: 0.00B [00:00, ?B/s]


Re-downloading README: file size mismatch.: 0.00B [00:00, ?B/s]


Skipping sub-pd6_ses-on_task-rest_eeg.bdf: already downloaded.: 100%|##########| 17.4M/17.4M [00:00<?, ?B/s]


Skipping sub-pd6_ses-on_task-rest_events.tsv: already downloaded.: 100%|##########| 51.0/51.0 [00:00<?, ?B/s]


Re-downloading dataset_description.json: file size mismatch.: 0.00B [00:00, ?B/s]

Re-downloading sub-pd6_ses-off_task-rest_beh.json: file size mismatch.: 0.00B [00:00, ?B/s]


                                                                                           Finished downloading ds002778.

Please enjoy your brains.

Explore the dataset contents#

We can use MNE-BIDS to print a tree of all included files and folders. We pass the max_depth parameter to mne_bids.print_dir_tree to the output to four levels of folders, for better readability in this example.

print_dir_tree(bids_root, max_depth=4)
|ds002778/
|--- CHANGES
|--- README
|--- dataset_description.json
|--- participants.json
|--- participants.tsv
|--- sub-pd6/
|------ ses-off/
|--------- sub-pd6_ses-off_scans.tsv
|--------- beh/
|------------ sub-pd6_ses-off_task-rest_beh.json
|------------ sub-pd6_ses-off_task-rest_beh.tsv
|--------- eeg/
|------------ sub-pd6_ses-off_task-rest_channels.tsv
|------------ sub-pd6_ses-off_task-rest_eeg.bdf
|------------ sub-pd6_ses-off_task-rest_eeg.json
|------------ sub-pd6_ses-off_task-rest_events.tsv
|------ ses-on/
|--------- sub-pd6_ses-on_scans.tsv
|--------- beh/
|------------ sub-pd6_ses-on_task-rest_beh.json
|------------ sub-pd6_ses-on_task-rest_beh.tsv
|--------- eeg/
|------------ sub-pd6_ses-on_task-rest_channels.tsv
|------------ sub-pd6_ses-on_task-rest_eeg.bdf
|------------ sub-pd6_ses-on_task-rest_eeg.json
|------------ sub-pd6_ses-on_task-rest_events.tsv

We can even ask MNE-BIDS to produce a human-readbale summary report on the dataset contents.

Summarizing participants.tsv /home/stefanappelhoff/mne_data/ds002778/participants.tsv...
Summarizing scans.tsv files [PosixPath('/home/stefanappelhoff/mne_data/ds002778/sub-pd6/ses-on/sub-pd6_ses-on_scans.tsv'), PosixPath('/home/stefanappelhoff/mne_data/ds002778/sub-pd6/ses-off/sub-pd6_ses-off_scans.tsv')]...
The participant template found: comprised of 14 male and 17 female participants;
comprised of 31 right hand, 0 left hand and 0 ambidextrous;
ages ranged from 47.0 to 82.0 (mean = 63.39, std = 8.69)
 The UC San Diego Resting State EEG Data from Patients with Parkinson's Disease
dataset was created by Alexander P. Rockhill, Nicko Jackson, Jobi George, Adam
Aron, and Nicole C. Swann and conforms to BIDS version 1.2.2. This report was
generated with MNE-BIDS (https://doi.org/10.21105/joss.01896). The dataset
consists of 1 participants (comprised of 14 male and 17 female participants;
comprised of 31 right hand, 0 left hand and 0 ambidextrous; ages ranged from
47.0 to 82.0 (mean = 63.39, std = 8.69)) and 2 recording sessions: off, and on.
Data was recorded using an EEG system (Biosemi) sampled at 512.0 Hz with line
noise at 50, and 60 Hz. There were 2 scans in total. Recording durations ranged
from 191.0 to 289.0 seconds (mean = 240.0, std = 49.0), for a total of 480.0
seconds of data recorded over all scans. For each dataset, there were on average
41.0 (std = 0.0) recording channels per scan, out of which 41.0 (std = 0.0) were
used in analysis (0.0 +/- 0.0 were removed from analysis).

Now it’s time to get ready for reading some of the data! First, we need to create an mne_bids.BIDSPath, which is the workhorse object of MNE-BIDS when it comes to file and folder operations.

For now, we’re interested only in the EEG data in the BIDS root directory of the Parkinson’s disease patient dataset. There were two sessions, one where the patients took their regular anti-Parkinsonian medications and one where they abstained for more than twelve hours. Let’s start with the off-medication session.

We can now retrieve a list of all MEG-related files in the dataset:

print(bids_path.match())
[BIDSPath(
root: /home/stefanappelhoff/mne_data/ds002778
datatype: eeg
basename: sub-pd6_ses-off_task-rest_channels.tsv), BIDSPath(
root: /home/stefanappelhoff/mne_data/ds002778
datatype: eeg
basename: sub-pd6_ses-off_task-rest_eeg.bdf), BIDSPath(
root: /home/stefanappelhoff/mne_data/ds002778
datatype: eeg
basename: sub-pd6_ses-off_task-rest_events.tsv)]

The returned list contains BIDSpaths of 3 files: sub-pd6_ses-off_task-rest_channels.tsv, sub-pd6_ses-off_task-rest_events.tsv, and sub-pd6_ses-off_task-rest_eeg.bdf. The first two are so-called sidecar files that contain information on the recording channels and experimental events, and the third one is the actual data file.

Prepare reading the data#

There is only one subject and one experimental task (rest). Let’s use this knowledge to create a new BIDSPath with all the information required to actually read the EEG data. We also need to pass a suffix, which is the last part of the filename just before the extension – 'channels' and 'events' for the two TSV files in our example, and 'eeg' for EEG raw data. For MEG and EEG raw data, the suffix is identical to the datatype, so don’t let yourself be confused here!

Now let’s print the contents of bids_path.

print(bids_path)
/home/stefanappelhoff/mne_data/ds002778/sub-pd6/ses-off/eeg/sub-pd6_ses-off_task-rest_eeg.bdf

You probably noticed two things: Firstly, this looks like an ordinary string now, not like the more-or-less neatly formatted output we saw before. And secondly, that there’s suddenly a filename extension which we never specified anywhere!

The reason is that when you call print(bids_path), BIDSPath returns a string representation of BIDSPath.fpath, which looks different. If, instead, you simply typed bids_path (or print(repr(bids_path)), which is the same) into your Python console, you would get the nicely formatted output:

BIDSPath(
root: /home/stefanappelhoff/mne_data/ds002778
datatype: eeg
basename: sub-pd6_ses-off_task-rest_eeg)

The root here is – you guessed it – the directory we passed via the root parameter: the “home” of our BIDS dataset. The datatype, again, is self-explanatory. The basename, on the other hand, is created automatically based on the suffix and BIDS entities we passed to BIDSPath: in our case, subject, session and task.

Note

There are many more supported entities, the most-commonly used among them probably being acquisition. Please see our introduction to BIDSPath to learn more about entities, basename, and BIDSPath in general.

But what about that filename extension, now? BIDSPath.fpath, which – as you hopefully remember – is invoked when you run print(bids_path) – employs some heuristics to auto-detect some missing filename components. Omitting the filename extension in your script can make your code more portable. Note that, however, you can explicitly specify an extension too, by passing e.g. extension='.bdf' to BIDSPath.

Read the data#

Let’s read the data! It’s just a single line of code.

raw = read_raw_bids(bids_path=bids_path, verbose=False)

Now we can inspect the raw object to check that it contains to correct metadata.

Basic subject metadata is here.

print(raw.info['subject_info'])
{'his_id': 'sub-pd6', 'age': '62', 'gender': 'f', 'hand': 1, 'MMSE': '30', 'NAART': '42', 'disease_duration': '8', 'rl_deficits': 'L OFF meds, more R ON meds', 'notes': 'Used preprocessed data from EEGLAB .mat file instead of raw data for pd on'}

Power line frequency is here.

print(raw.info['line_freq'])
60.0

Sampling frequency is here.

print(raw.info['sfreq'])
512.0

Events are now Annotations

<Annotations | 2 segments: 1 (1), 65536 (1)>

Plot the raw data.

read bids datasets
Using matplotlib as 2D backend.

<MNEBrowseFigure size 2615.62x1442.71 with 4 Axes>

Total running time of the script: ( 1 minutes 11.662 seconds)

Gallery generated by Sphinx-Gallery