Note
Click here to download the full example code or to run this example in your browser via Binder
09. Storing empty room data in BIDS format¶
This example demonstrates how to store empty room data in BIDS format and how to retrieve them.
# Authors: Mainak Jas <mainakjas@gmail.com>
#
# License: BSD-3-Clause
We are dealing with MEG data, which is often accompanied by so-called “empty room” recordings for noise modeling. Below we show that we can use MNE-BIDS to also save such a recording with the just converted data.
Let us first import mne_bids.
import os.path as op
import shutil
from datetime import datetime, timezone
import mne
from mne.datasets import sample
from mne_bids import (write_raw_bids, read_raw_bids,
BIDSPath, print_dir_tree)
And define the paths and event_id dictionary.
data_path = sample.data_path()
raw_fname = op.join(data_path, 'MEG', 'sample', 'sample_audvis_raw.fif')
bids_root = op.join(data_path, '..', 'MNE-sample-data-bids')
To ensure the output path doesn’t contain any leftover files from previous tests and example runs, we simply delete it.
Warning
Do not delete directories that may contain important data!
Specify the raw_file and events_data and run the BIDS conversion, and write the BIDS data.
raw = mne.io.read_raw_fif(raw_fname)
raw.info['line_freq'] = 60 # specify power line frequency as required by BIDS
bids_path = BIDSPath(subject='01', session='01',
task='audiovisual', run='01', root=bids_root)
write_raw_bids(raw, bids_path, overwrite=True)
Out:
INFO Opening raw data file
/Users/hoechenberger/mne_data/MNE-sample-data/MEG/sample/sample_audvis_raw.fif...
INFO Read a total of 3 projection items
PCA-v1 (1 x 102) idle
PCA-v2 (1 x 102) idle
PCA-v3 (1 x 102) idle
INFO Range : 25800 ... 192599 = 42.956 ... 320.670 secs
INFO Ready.
INFO Opening raw data file
/Users/hoechenberger/mne_data/MNE-sample-data/MEG/sample/sample_audvis_raw.fif...
INFO Read a total of 3 projection items
PCA-v1 (1 x 102) idle
PCA-v2 (1 x 102) idle
PCA-v3 (1 x 102) idle
INFO Range : 25800 ... 192599 = 42.956 ... 320.670 secs
INFO Ready.
INFO Writing '/Users/hoechenberger/mne_data/MNE-sample-data/../MNE-sample-data-bids/README'...
INFO Writing '/Users/hoechenberger/mne_data/MNE-sample-data/../MNE-sample-data-bids/participants.tsv'...
INFO Writing '/Users/hoechenberger/mne_data/MNE-sample-data/../MNE-sample-data-bids/participants.json'...
INFO Writing '/Users/hoechenberger/mne_data/MNE-sample-data/../MNE-sample-data-bids/sub-01/ses-01/meg/sub
-01_ses-01_coordsystem.json'...
INFO Writing '/Users/hoechenberger/mne_data/MNE-sample-data/../MNE-sample-data-bids/sub-01/ses-01/meg/sub
-01_ses-01_coordsystem.json'...
/Users/hoechenberger/Development/mne-bids/mne_bids/read.py:185: RuntimeWarning: No events found or provided. Please add annotations to the raw data, or provide the events_data and event_id parameters. For resting state data, BIDS recommends naming the task using labels beginning with "rest".
warn('No events found or provided. Please add annotations to the raw '
INFO Writing
'/Users/hoechenberger/mne_data/MNE-sample-data/../MNE-sample-data-bids/dataset_description.json'...
INFO Writing '/Users/hoechenberger/mne_data/MNE-sample-data/../MNE-sample-data-bids/sub-01/ses-01/meg/sub
-01_ses-01_task-audiovisual_run-01_meg.json'...
INFO Writing '/Users/hoechenberger/mne_data/MNE-sample-data/../MNE-sample-data-bids/sub-01/ses-01/meg/sub
-01_ses-01_task-audiovisual_run-01_channels.tsv'...
INFO Copying data files to sub-01_ses-01_task-audiovisual_run-01_meg.fif
INFO Reserving possible split file sub-01_ses-01_task-audiovisual_run-01_split-01_meg.fif
INFO Writing /Users/hoechenberger/mne_data/MNE-sample-data/../MNE-sample-data-bids/sub-01/ses-01/meg/sub-
01_ses-01_task-audiovisual_run-01_meg.fif
INFO Closing /Users/hoechenberger/mne_data/MNE-sample-data/../MNE-sample-data-bids/sub-01/ses-01/meg/sub-
01_ses-01_task-audiovisual_run-01_meg.fif
INFO [done]
INFO Writing '/Users/hoechenberger/mne_data/MNE-sample-data/../MNE-sample-data-bids/sub-01/ses-01/sub-01_
ses-01_scans.tsv'...
INFO Wrote /Users/hoechenberger/mne_data/MNE-sample-data/../MNE-sample-data-bids/sub-01/ses-01/sub-01_ses
-01_scans.tsv entry with meg/sub-01_ses-01_task-audiovisual_run-01_meg.fif.
BIDSPath(
root: /Users/hoechenberger/mne_data/MNE-sample-data/../MNE-sample-data-bids
datatype: meg
basename: sub-01_ses-01_task-audiovisual_run-01_meg.fif)
Specify some empty room data and run BIDS conversion on it.
er_raw_fname = op.join(data_path, 'MEG', 'sample', 'ernoise_raw.fif')
er_raw = mne.io.read_raw_fif(er_raw_fname)
er_raw.info['line_freq'] = 60 # specify power line frequency as req. by BIDS
# For empty room data we need to specify the recording date in the format
# YYYYMMDD for the session id.
er_date = er_raw.info['meas_date'].strftime('%Y%m%d')
print(er_date)
Out:
INFO Opening raw data file /Users/hoechenberger/mne_data/MNE-sample-data/MEG/sample/ernoise_raw.fif...
INFO Isotrak not found
INFO Read a total of 3 projection items
PCA-v1 (1 x 102) idle
PCA-v2 (1 x 102) idle
PCA-v3 (1 x 102) idle
INFO Range : 19800 ... 85867 = 32.966 ... 142.965 secs
INFO Ready.
20021206
The measurement date is
Out:
20021203
We also need to specify that the subject ID is ‘emptyroom’, and that the task is ‘noise’ (these are BIDS rules).
er_bids_path = BIDSPath(subject='emptyroom', session=er_date,
task='noise', root=bids_root)
write_raw_bids(er_raw, er_bids_path, overwrite=True)
Out:
INFO Opening raw data file /Users/hoechenberger/mne_data/MNE-sample-data/MEG/sample/ernoise_raw.fif...
INFO Isotrak not found
INFO Read a total of 3 projection items
PCA-v1 (1 x 102) idle
PCA-v2 (1 x 102) idle
PCA-v3 (1 x 102) idle
INFO Range : 19800 ... 85867 = 32.966 ... 142.965 secs
INFO Ready.
INFO Writing '/Users/hoechenberger/mne_data/MNE-sample-data/../MNE-sample-data-bids/participants.tsv'...
INFO Writing '/Users/hoechenberger/mne_data/MNE-sample-data/../MNE-sample-data-bids/participants.json'...
INFO Writing of electrodes.tsv is not supported for data type "meg". Skipping ...
INFO Writing
'/Users/hoechenberger/mne_data/MNE-sample-data/../MNE-sample-data-bids/dataset_description.json'...
INFO Writing '/Users/hoechenberger/mne_data/MNE-sample-data/../MNE-sample-data-bids/sub-emptyroom/ses-200
21206/meg/sub-emptyroom_ses-20021206_task-noise_meg.json'...
INFO Writing '/Users/hoechenberger/mne_data/MNE-sample-data/../MNE-sample-data-bids/sub-emptyroom/ses-200
21206/meg/sub-emptyroom_ses-20021206_task-noise_channels.tsv'...
INFO Copying data files to sub-emptyroom_ses-20021206_task-noise_meg.fif
INFO Reserving possible split file sub-emptyroom_ses-20021206_task-noise_split-01_meg.fif
INFO Writing /Users/hoechenberger/mne_data/MNE-sample-data/../MNE-sample-data-bids/sub-emptyroom/ses-2002
1206/meg/sub-emptyroom_ses-20021206_task-noise_meg.fif
INFO Closing /Users/hoechenberger/mne_data/MNE-sample-data/../MNE-sample-data-bids/sub-emptyroom/ses-2002
1206/meg/sub-emptyroom_ses-20021206_task-noise_meg.fif
INFO [done]
INFO Writing '/Users/hoechenberger/mne_data/MNE-sample-data/../MNE-sample-data-bids/sub-emptyroom/ses-200
21206/sub-emptyroom_ses-20021206_scans.tsv'...
INFO Wrote /Users/hoechenberger/mne_data/MNE-sample-data/../MNE-sample-data-bids/sub-emptyroom/ses-200212
06/sub-emptyroom_ses-20021206_scans.tsv entry with
meg/sub-emptyroom_ses-20021206_task-noise_meg.fif.
BIDSPath(
root: /Users/hoechenberger/mne_data/MNE-sample-data/../MNE-sample-data-bids
datatype: meg
basename: sub-emptyroom_ses-20021206_task-noise_meg.fif)
Just to illustrate, we can save more than one empty room file for different dates. Here, they will all contain the same data but in your study, they will be different on different days.
dates = ['20021204', '20021201', '20021001']
for date in dates:
er_bids_path.update(session=date)
er_meas_date = datetime.strptime(date, '%Y%m%d')
er_raw.set_meas_date(er_meas_date.replace(tzinfo=timezone.utc))
write_raw_bids(er_raw, er_bids_path, overwrite=True)
Out:
INFO Opening raw data file /Users/hoechenberger/mne_data/MNE-sample-data/MEG/sample/ernoise_raw.fif...
INFO Isotrak not found
INFO Read a total of 3 projection items
PCA-v1 (1 x 102) idle
PCA-v2 (1 x 102) idle
PCA-v3 (1 x 102) idle
INFO Range : 19800 ... 85867 = 32.966 ... 142.965 secs
INFO Ready.
INFO Writing '/Users/hoechenberger/mne_data/MNE-sample-data/../MNE-sample-data-bids/participants.tsv'...
INFO Writing '/Users/hoechenberger/mne_data/MNE-sample-data/../MNE-sample-data-bids/participants.json'...
INFO Writing of electrodes.tsv is not supported for data type "meg". Skipping ...
INFO Writing
'/Users/hoechenberger/mne_data/MNE-sample-data/../MNE-sample-data-bids/dataset_description.json'...
INFO Writing '/Users/hoechenberger/mne_data/MNE-sample-data/../MNE-sample-data-bids/sub-emptyroom/ses-200
21204/meg/sub-emptyroom_ses-20021204_task-noise_meg.json'...
INFO Writing '/Users/hoechenberger/mne_data/MNE-sample-data/../MNE-sample-data-bids/sub-emptyroom/ses-200
21204/meg/sub-emptyroom_ses-20021204_task-noise_channels.tsv'...
INFO Copying data files to sub-emptyroom_ses-20021204_task-noise_meg.fif
INFO Reserving possible split file sub-emptyroom_ses-20021204_task-noise_split-01_meg.fif
INFO Writing /Users/hoechenberger/mne_data/MNE-sample-data/../MNE-sample-data-bids/sub-emptyroom/ses-2002
1204/meg/sub-emptyroom_ses-20021204_task-noise_meg.fif
INFO Closing /Users/hoechenberger/mne_data/MNE-sample-data/../MNE-sample-data-bids/sub-emptyroom/ses-2002
1204/meg/sub-emptyroom_ses-20021204_task-noise_meg.fif
INFO [done]
INFO Writing '/Users/hoechenberger/mne_data/MNE-sample-data/../MNE-sample-data-bids/sub-emptyroom/ses-200
21204/sub-emptyroom_ses-20021204_scans.tsv'...
INFO Wrote /Users/hoechenberger/mne_data/MNE-sample-data/../MNE-sample-data-bids/sub-emptyroom/ses-200212
04/sub-emptyroom_ses-20021204_scans.tsv entry with
meg/sub-emptyroom_ses-20021204_task-noise_meg.fif.
INFO Opening raw data file /Users/hoechenberger/mne_data/MNE-sample-data/MEG/sample/ernoise_raw.fif...
INFO Isotrak not found
INFO Read a total of 3 projection items
PCA-v1 (1 x 102) idle
PCA-v2 (1 x 102) idle
PCA-v3 (1 x 102) idle
INFO Range : 19800 ... 85867 = 32.966 ... 142.965 secs
INFO Ready.
INFO Writing '/Users/hoechenberger/mne_data/MNE-sample-data/../MNE-sample-data-bids/participants.tsv'...
INFO Writing '/Users/hoechenberger/mne_data/MNE-sample-data/../MNE-sample-data-bids/participants.json'...
INFO Writing of electrodes.tsv is not supported for data type "meg". Skipping ...
INFO Writing
'/Users/hoechenberger/mne_data/MNE-sample-data/../MNE-sample-data-bids/dataset_description.json'...
INFO Writing '/Users/hoechenberger/mne_data/MNE-sample-data/../MNE-sample-data-bids/sub-emptyroom/ses-200
21201/meg/sub-emptyroom_ses-20021201_task-noise_meg.json'...
INFO Writing '/Users/hoechenberger/mne_data/MNE-sample-data/../MNE-sample-data-bids/sub-emptyroom/ses-200
21201/meg/sub-emptyroom_ses-20021201_task-noise_channels.tsv'...
INFO Copying data files to sub-emptyroom_ses-20021201_task-noise_meg.fif
INFO Reserving possible split file sub-emptyroom_ses-20021201_task-noise_split-01_meg.fif
INFO Writing /Users/hoechenberger/mne_data/MNE-sample-data/../MNE-sample-data-bids/sub-emptyroom/ses-2002
1201/meg/sub-emptyroom_ses-20021201_task-noise_meg.fif
INFO Closing /Users/hoechenberger/mne_data/MNE-sample-data/../MNE-sample-data-bids/sub-emptyroom/ses-2002
1201/meg/sub-emptyroom_ses-20021201_task-noise_meg.fif
INFO [done]
INFO Writing '/Users/hoechenberger/mne_data/MNE-sample-data/../MNE-sample-data-bids/sub-emptyroom/ses-200
21201/sub-emptyroom_ses-20021201_scans.tsv'...
INFO Wrote /Users/hoechenberger/mne_data/MNE-sample-data/../MNE-sample-data-bids/sub-emptyroom/ses-200212
01/sub-emptyroom_ses-20021201_scans.tsv entry with
meg/sub-emptyroom_ses-20021201_task-noise_meg.fif.
INFO Opening raw data file /Users/hoechenberger/mne_data/MNE-sample-data/MEG/sample/ernoise_raw.fif...
INFO Isotrak not found
INFO Read a total of 3 projection items
PCA-v1 (1 x 102) idle
PCA-v2 (1 x 102) idle
PCA-v3 (1 x 102) idle
INFO Range : 19800 ... 85867 = 32.966 ... 142.965 secs
INFO Ready.
INFO Writing '/Users/hoechenberger/mne_data/MNE-sample-data/../MNE-sample-data-bids/participants.tsv'...
INFO Writing '/Users/hoechenberger/mne_data/MNE-sample-data/../MNE-sample-data-bids/participants.json'...
INFO Writing of electrodes.tsv is not supported for data type "meg". Skipping ...
INFO Writing
'/Users/hoechenberger/mne_data/MNE-sample-data/../MNE-sample-data-bids/dataset_description.json'...
INFO Writing '/Users/hoechenberger/mne_data/MNE-sample-data/../MNE-sample-data-bids/sub-emptyroom/ses-200
21001/meg/sub-emptyroom_ses-20021001_task-noise_meg.json'...
INFO Writing '/Users/hoechenberger/mne_data/MNE-sample-data/../MNE-sample-data-bids/sub-emptyroom/ses-200
21001/meg/sub-emptyroom_ses-20021001_task-noise_channels.tsv'...
INFO Copying data files to sub-emptyroom_ses-20021001_task-noise_meg.fif
INFO Reserving possible split file sub-emptyroom_ses-20021001_task-noise_split-01_meg.fif
INFO Writing /Users/hoechenberger/mne_data/MNE-sample-data/../MNE-sample-data-bids/sub-emptyroom/ses-2002
1001/meg/sub-emptyroom_ses-20021001_task-noise_meg.fif
INFO Closing /Users/hoechenberger/mne_data/MNE-sample-data/../MNE-sample-data-bids/sub-emptyroom/ses-2002
1001/meg/sub-emptyroom_ses-20021001_task-noise_meg.fif
INFO [done]
INFO Writing '/Users/hoechenberger/mne_data/MNE-sample-data/../MNE-sample-data-bids/sub-emptyroom/ses-200
21001/sub-emptyroom_ses-20021001_scans.tsv'...
INFO Wrote /Users/hoechenberger/mne_data/MNE-sample-data/../MNE-sample-data-bids/sub-emptyroom/ses-200210
01/sub-emptyroom_ses-20021001_scans.tsv entry with
meg/sub-emptyroom_ses-20021001_task-noise_meg.fif.
Let us look at the directory structure
Out:
|MNE-sample-data-bids/
|--- README
|--- dataset_description.json
|--- participants.json
|--- participants.tsv
|--- sub-01/
|------ ses-01/
|--------- sub-01_ses-01_scans.tsv
|--------- meg/
|------------ sub-01_ses-01_coordsystem.json
|------------ sub-01_ses-01_task-audiovisual_run-01_channels.tsv
|------------ sub-01_ses-01_task-audiovisual_run-01_meg.fif
|------------ sub-01_ses-01_task-audiovisual_run-01_meg.json
|--- sub-emptyroom/
|------ ses-20021001/
|--------- sub-emptyroom_ses-20021001_scans.tsv
|--------- meg/
|------------ sub-emptyroom_ses-20021001_task-noise_channels.tsv
|------------ sub-emptyroom_ses-20021001_task-noise_meg.fif
|------------ sub-emptyroom_ses-20021001_task-noise_meg.json
|------ ses-20021201/
|--------- sub-emptyroom_ses-20021201_scans.tsv
|--------- meg/
|------------ sub-emptyroom_ses-20021201_task-noise_channels.tsv
|------------ sub-emptyroom_ses-20021201_task-noise_meg.fif
|------------ sub-emptyroom_ses-20021201_task-noise_meg.json
|------ ses-20021204/
|--------- sub-emptyroom_ses-20021204_scans.tsv
|--------- meg/
|------------ sub-emptyroom_ses-20021204_task-noise_channels.tsv
|------------ sub-emptyroom_ses-20021204_task-noise_meg.fif
|------------ sub-emptyroom_ses-20021204_task-noise_meg.json
|------ ses-20021206/
|--------- sub-emptyroom_ses-20021206_scans.tsv
|--------- meg/
|------------ sub-emptyroom_ses-20021206_task-noise_channels.tsv
|------------ sub-emptyroom_ses-20021206_task-noise_meg.fif
|------------ sub-emptyroom_ses-20021206_task-noise_meg.json
To get an accurate estimate of the noise, it is important that the empty room recording be as close in date as the raw data. We can retrieve the basename corresponding to the empty room recording that is closest in time to the experimental measurement.
er_bids_path = bids_path.find_empty_room()
print(er_bids_path)
Out:
INFO The MEG sidecar file does not contain an "AssociatedEmptyRoom" entry. Will try to find a matching
empty-room recording based on the measurement date …
INFO Opening raw data file /Users/hoechenberger/mne_data/MNE-sample-data/../MNE-sample-data-bids/sub-01/s
es-01/meg/sub-01_ses-01_task-audiovisual_run-01_meg.fif...
INFO Read a total of 3 projection items
PCA-v1 (1 x 102) idle
PCA-v2 (1 x 102) idle
PCA-v3 (1 x 102) idle
INFO Range : 25800 ... 192599 = 42.956 ... 320.670 secs
INFO Ready.
/Users/hoechenberger/Development/mne-bids/mne_bids/path.py:1483: RuntimeWarning: Did not find any events.tsv associated with sub-01_ses-01_task-audiovisual_run-01.
The search_str was "/Users/hoechenberger/mne_data/MNE-sample-data/../MNE-sample-data-bids/sub-01/**/meg/sub-01_ses-01*events.tsv"
warn(msg)
INFO Reading channel info from /Users/hoechenberger/mne_data/MNE-sample-data/../MNE-sample-data-bids/sub-
01/ses-01/meg/sub-01_ses-01_task-audiovisual_run-01_channels.tsv.
/Users/hoechenberger/Development/mne-bids/mne_bids/read.py:564: RuntimeWarning: The unit for channel(s) STI 001, STI 002, STI 003, STI 004, STI 005, STI 006, STI 014, STI 015, STI 016 has changed from V to NA.
raw.set_channel_types(ch_type_map_avail)
/Users/hoechenberger/mne_data/MNE-sample-data/../MNE-sample-data-bids/sub-emptyroom/ses-20021204/meg/sub-emptyroom_ses-20021204_task-noise_meg.fif
Finally, we can read the empty room file using
raw = read_raw_bids(bids_path=er_bids_path)
print(raw)
Out:
INFO Opening raw data file /Users/hoechenberger/mne_data/MNE-sample-data/../MNE-sample-data-bids/sub-empt
yroom/ses-20021204/meg/sub-emptyroom_ses-20021204_task-noise_meg.fif...
INFO Isotrak not found
INFO Read a total of 3 projection items
PCA-v1 (1 x 102) idle
PCA-v2 (1 x 102) idle
PCA-v3 (1 x 102) idle
INFO Range : 19800 ... 85867 = 32.966 ... 142.965 secs
INFO Ready.
/Users/hoechenberger/Development/mne-bids/mne_bids/path.py:1483: RuntimeWarning: Did not find any events.tsv associated with sub-emptyroom_ses-20021204_task-noise.
The search_str was "/Users/hoechenberger/mne_data/MNE-sample-data/../MNE-sample-data-bids/sub-emptyroom/**/meg/sub-emptyroom_ses-20021204*events.tsv"
warn(msg)
INFO Reading channel info from /Users/hoechenberger/mne_data/MNE-sample-data/../MNE-sample-data-bids/sub-
emptyroom/ses-20021204/meg/sub-emptyroom_ses-20021204_task-noise_channels.tsv.
/Users/hoechenberger/Development/mne-bids/mne_bids/read.py:564: RuntimeWarning: The unit for channel(s) STI 001, STI 002, STI 003, STI 004, STI 005, STI 006, STI 014, STI 015, STI 016 has changed from V to NA.
raw.set_channel_types(ch_type_map_avail)
<Raw | sub-emptyroom_ses-20021204_task-noise_meg.fif, 315 x 66068 (110.0 s), ~368 kB, data not loaded>
Total running time of the script: ( 0 minutes 2.926 seconds)