12. Update BIDS datasets

When working with electrophysiological data in the BIDS format, we usually do not have all the metadata stored in the Raw mne-python object. We can update the BIDS sidecar files via the update_sidecar_json function.

In this tutorial, we show how update_sidecar_json can be used to update and modify BIDS-formatted data.

# Authors: Adam Li <adam2392@gmail.com>
#          mne-bids developers
#
# License: BSD (3-clause)

Imports

We are importing everything we need for this example:

from mne.datasets import somato

from mne_bids import (BIDSPath, read_raw_bids,
                      print_dir_tree, make_report, update_sidecar_json)

We will be using the MNE somato data, which is already stored in BIDS format. For more information, you can check out the respective example.

Download the somato BIDS dataset

Download the data if it hasn’t been downloaded already, and return the path to the download directory. This directory is the so-called root of this BIDS dataset.

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 three levels of folders, for better readability in this example.

print_dir_tree(bids_root, max_depth=3)

# We can generate a report of the existing dataset
print(make_report(bids_root))

Out:

|MNE-somato-data/
|--- CHANGES
|--- README
|--- dataset_description.json
|--- participants.json
|--- participants.tsv
|--- code/
|------ README
|------ convert_somato_data.py
|--- derivatives/
|------ freesurfer/
|--------- subjects/
|------ sub-01/
|--------- sub-01_task-somato-fwd.fif
|--- sub-01/
|------ sub-01_scans.tsv
|------ anat/
|--------- sub-01_T1w.json
|--------- sub-01_T1w.nii.gz
|------ meg/
|--------- sub-01_coordsystem.json
|--------- sub-01_task-somato_channels.tsv
|--------- sub-01_task-somato_events.tsv
|--------- sub-01_task-somato_meg.fif
|--------- sub-01_task-somato_meg.json
Summarizing participants.tsv /Users/hoechenberger/mne_data/MNE-somato-data/participants.tsv...
Summarizing scans.tsv files [PosixPath('/Users/hoechenberger/mne_data/MNE-somato-data/sub-01/sub-01_scans.tsv')]...
The participant template found: comprised of 1 men and 0 women;
handedness were all unknown; ages all unknown
The MNE-somato-data-bids dataset was created with BIDS version 1.2.0 by Lauri
Parkkonen. This report was generated with MNE-BIDS
(https://doi.org/10.21105/joss.01896). The dataset consists of 1 participants
(comprised of 1 men and 0 women; handedness were all unknown; ages all unknown).
Data was recorded using a MEG system (Elekta manufacturer) sampled at 300.31 Hz
with line noise at 50 Hz. There was 1 scan in total. Recording durations ranged
from 897.08 to 897.08 seconds (mean = 897.08, std = 0.0), for a total of 897.08
seconds of data recorded over all scans. For each dataset, there were on average
316.0 (std = 0.0) recording channels per scan, out of which 316.0 (std = 0.0)
were used in analysis (0.0 +/- 0.0 were removed from analysis).

Update the sidecar JSON dataset contents

We can use MNE-BIDS to update all sidecar files for a matching BIDSPath object. We then pass in a dictionary (or JSON file) to update all matching metadata fields within the BIDS dataset.

# create a BIDSPath object
bids_root = somato.data_path()
datatype = 'meg'
subject = '01'
task = 'somato'
suffix = 'meg'

bids_path = BIDSPath(subject=subject, task=task, suffix=suffix,
                     datatype=datatype, root=bids_root)
sidecar_path = bids_path.copy().update(extension='.json')

# We can now retrieve a list of all MEG-related files in the dataset:
# we will specifically now update the sidecar json file.
print(bids_path.match())

# Define a sidecar update as a dictionary
entries = {
    'PowerLineFrequency': 60,
    'Manufacturer': "MEGIN",
    'InstitutionName': "Martinos Center"
}

# Note: ``update_sidecar_json`` will perform essentially a
# dictionary update to your sidecar json file, so be absolutely sure
# that the ``entries`` are defined with the proper fields specified
# by BIDS. For example, if you are updating the ``coordsystem.json``
# file, then you don't want to include ``PowerLineFrequency`` in
# ``entries``.
#
# Now update all sidecar fields according to our updating dictionary
update_sidecar_json(bids_path=sidecar_path, entries=entries)

Out:

[BIDSPath(
root: /Users/hoechenberger/mne_data/MNE-somato-data
datatype: meg
basename: sub-01_task-somato_meg.fif)]

Writing '/Users/hoechenberger/mne_data/MNE-somato-data/sub-01/meg/sub-01_task-somato_meg.json'...

{
    "TaskName": "somato",
    "Manufacturer": "MEGIN",
    "PowerLineFrequency": 60,
    "SamplingFrequency": 300.3074951171875,
    "SoftwareFilters": "n/a",
    "RecordingDuration": 897.0771771609423,
    "RecordingType": "continuous",
    "DewarPosition": "n/a",
    "DigitizedLandmarks": false,
    "DigitizedHeadPoints": false,
    "MEGChannelCount": 306,
    "MEGREFChannelCount": 0,
    "EEGChannelCount": 0,
    "EOGChannelCount": 1,
    "ECGChannelCount": 0,
    "EMGChannelCount": 0,
    "MiscChannelCount": 0,
    "TriggerChannelCount": 9,
    "InstitutionName": "Martinos Center"
}

Read the updated dataset

# new line frequency is now 60 Hz
raw = read_raw_bids(bids_path=bids_path)
print(raw.info['line_freq'])

Out:

Opening raw data file /Users/hoechenberger/mne_data/MNE-somato-data/sub-01/meg/sub-01_task-somato_meg.fif...
    Range : 237600 ... 506999 =    791.189 ...  1688.266 secs
Ready.
Reading events from /Users/hoechenberger/mne_data/MNE-somato-data/sub-01/meg/sub-01_task-somato_events.tsv.
Reading channel info from /Users/hoechenberger/mne_data/MNE-somato-data/sub-01/meg/sub-01_task-somato_channels.tsv.
/Users/hoechenberger/Development/mne-bids/mne_bids/read.py:339: 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(channel_type_dict)
60

Generate a new report based on the updated metadata.

# The manufacturer was changed to ``MEGIN``
print(make_report(bids_root))

Out:

Summarizing participants.tsv /Users/hoechenberger/mne_data/MNE-somato-data/participants.tsv...
Summarizing scans.tsv files [PosixPath('/Users/hoechenberger/mne_data/MNE-somato-data/sub-01/sub-01_scans.tsv')]...
The participant template found: comprised of 1 men and 0 women;
handedness were all unknown; ages all unknown
The MNE-somato-data-bids dataset was created with BIDS version 1.2.0 by Lauri
Parkkonen. This report was generated with MNE-BIDS
(https://doi.org/10.21105/joss.01896). The dataset consists of 1 participants
(comprised of 1 men and 0 women; handedness were all unknown; ages all unknown).
Data was recorded using a MEG system (MEGIN manufacturer) sampled at 300.31 Hz
with line noise at 60 Hz. There was 1 scan in total. Recording durations ranged
from 897.08 to 897.08 seconds (mean = 897.08, std = 0.0), for a total of 897.08
seconds of data recorded over all scans. For each dataset, there were on average
316.0 (std = 0.0) recording channels per scan, out of which 316.0 (std = 0.0)
were used in analysis (0.0 +/- 0.0 were removed from analysis).

We can revert the changes by updating the sidecar again.

# update the sidecar data to have a new PowerLineFrequency
entries['Manufacturer'] = "Elekta"
entries['PowerLineFrequency'] = 50
update_sidecar_json(bids_path=sidecar_path, entries=entries)

Out:

Writing '/Users/hoechenberger/mne_data/MNE-somato-data/sub-01/meg/sub-01_task-somato_meg.json'...

{
    "TaskName": "somato",
    "Manufacturer": "Elekta",
    "PowerLineFrequency": 50,
    "SamplingFrequency": 300.3074951171875,
    "SoftwareFilters": "n/a",
    "RecordingDuration": 897.0771771609423,
    "RecordingType": "continuous",
    "DewarPosition": "n/a",
    "DigitizedLandmarks": false,
    "DigitizedHeadPoints": false,
    "MEGChannelCount": 306,
    "MEGREFChannelCount": 0,
    "EEGChannelCount": 0,
    "EOGChannelCount": 1,
    "ECGChannelCount": 0,
    "EMGChannelCount": 0,
    "MiscChannelCount": 0,
    "TriggerChannelCount": 9,
    "InstitutionName": "Martinos Center"
}

Now let us inspect the dataset again by generating the report again. Now that update_sidecar_json was called, the metadata will be updated.

# The power line frequency should now change back to 50 Hz
raw = read_raw_bids(bids_path=bids_path)
print(raw.info['line_freq'])

# Generate the report with updated fields
print(make_report(bids_root))

Out:

Opening raw data file /Users/hoechenberger/mne_data/MNE-somato-data/sub-01/meg/sub-01_task-somato_meg.fif...
    Range : 237600 ... 506999 =    791.189 ...  1688.266 secs
Ready.
Reading events from /Users/hoechenberger/mne_data/MNE-somato-data/sub-01/meg/sub-01_task-somato_events.tsv.
Reading channel info from /Users/hoechenberger/mne_data/MNE-somato-data/sub-01/meg/sub-01_task-somato_channels.tsv.
/Users/hoechenberger/Development/mne-bids/mne_bids/read.py:339: 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(channel_type_dict)
50
Summarizing participants.tsv /Users/hoechenberger/mne_data/MNE-somato-data/participants.tsv...
Summarizing scans.tsv files [PosixPath('/Users/hoechenberger/mne_data/MNE-somato-data/sub-01/sub-01_scans.tsv')]...
The participant template found: comprised of 1 men and 0 women;
handedness were all unknown; ages all unknown
The MNE-somato-data-bids dataset was created with BIDS version 1.2.0 by Lauri
Parkkonen. This report was generated with MNE-BIDS
(https://doi.org/10.21105/joss.01896). The dataset consists of 1 participants
(comprised of 1 men and 0 women; handedness were all unknown; ages all unknown).
Data was recorded using a MEG system (Elekta manufacturer) sampled at 300.31 Hz
with line noise at 50 Hz. There was 1 scan in total. Recording durations ranged
from 897.08 to 897.08 seconds (mean = 897.08, std = 0.0), for a total of 897.08
seconds of data recorded over all scans. For each dataset, there were on average
316.0 (std = 0.0) recording channels per scan, out of which 316.0 (std = 0.0)
were used in analysis (0.0 +/- 0.0 were removed from analysis).

Total running time of the script: ( 0 minutes 0.205 seconds)

Gallery generated by Sphinx-Gallery