Note
Click here to download the full example code or to run this example in your browser via Binder
13. Writing modified files with MNE-BIDS¶
MNE-BIDS is designed such that it enforces good practices when working with
BIDS data. One of the principles of creating BIDS datasets from raw data is
that the raw data should ideally be written unmodified, as-is. To enforce
this, mne_bids.write_raw_bids()
performs some basic checks and will
throw an exception if it believes you’re doing something that you really
shouldn’t be doing (i.e., trying to store modified “raw” data as a BIDS
raw data set.)
There might be some – rare! – situations, however, when working around this
intentional limitation in MNE-BIDS can be warranted. For example, you might
encounter data that has manually been split across multiple files during
recording, even though it belongs to a single experimental run. In this case,
you might want to concatenate the data before storing them in BIDS. This
tutorial will give you an example on how to use mne_bids.write_raw_bids()
to store such data, despite it being modified before writing.
Warning
Please be aware that the situations in which you would need to apply the following solution are extremely rare. If you ever find yourself wanting to apply this solution, please take a step back, take a deep breath and re-consider whether this is absolutely necessary. If even a slight doubt remains, reach out to the MNE-BIDS developers.
# Authors: Richard Höchenberger <richard.hoechenberger@gmail.com>
# License: BSD (3-clause)
Load the sample
dataset, and create a concatenated raw data object.
from pathlib import Path
from tempfile import NamedTemporaryFile
import mne
from mne.datasets import sample
from mne_bids import write_raw_bids, BIDSPath
data_path = Path(sample.data_path())
raw_fname = data_path / 'MEG' / 'sample' / 'sample_audvis_raw.fif'
output_path = data_path / '..' / 'MNE-sample-data-bids'
bids_path = BIDSPath(subject='01', task='audiovisual', root=output_path)
raw = mne.io.read_raw_fif(raw_fname)
raw.info['line_freq'] = 60
raw_concat = mne.concatenate_raws([raw.copy(), raw])
Out:
Opening raw data file /home/stefanappelhoff/mne_data/MNE-sample-data/MEG/sample/sample_audvis_raw.fif...
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
Range : 25800 ... 192599 = 42.956 ... 320.670 secs
Ready.
Trying to write these data will fail.
try:
write_raw_bids(raw=raw_concat, bids_path=bids_path, overwrite=True)
except ValueError as e:
print(f'Data cannot be written. Exception message was: {e}')
Out:
Opening raw data file /home/stefanappelhoff/mne_data/MNE-sample-data/MEG/sample/sample_audvis_raw.fif...
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
Range : 25800 ... 192599 = 42.956 ... 320.670 secs
Ready.
Data cannot be written. Exception message was: The raw data you want to write contains more time points than the raw data on disk. It is possible that you concatenated your data, which write_raw_bids() won't accept. If you believe you have a valid use case that should be supported, please reach out to the developers at https://github.com/mne-tools/mne-bids/issues
We can work around this limitation by first writing the modified data to a temporary file, reading it back in, and then writing it via MNE-BIDS.
with NamedTemporaryFile(suffix='_raw.fif') as f:
fname = f.name
raw_concat.save(fname, overwrite=True)
raw_concat = mne.io.read_raw_fif(fname, preload=False)
write_raw_bids(raw=raw_concat, bids_path=bids_path, overwrite=True)
Out:
Overwriting existing file.
Writing /tmp/tmpdt5b_iy1_raw.fif
Closing /tmp/tmpdt5b_iy1_raw.fif
[done]
Opening raw data file /tmp/tmpdt5b_iy1_raw.fif...
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
Range : 25800 ... 359399 = 42.956 ... 598.385 secs
Ready.
Opening raw data file /tmp/tmpdt5b_iy1_raw.fif...
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
Range : 25800 ... 359399 = 42.956 ... 598.385 secs
Ready.
Writing '/home/stefanappelhoff/mne_data/MNE-sample-data/../MNE-sample-data-bids/participants.tsv'...
participant_id age sex hand
sub-01 n/a n/a n/a
sub-emptyroom n/a n/a n/a
Writing '/home/stefanappelhoff/mne_data/MNE-sample-data/../MNE-sample-data-bids/participants.json'...
{
"participant_id": {
"Description": "Unique participant identifier"
},
"age": {
"Description": "Age of the participant at time of testing",
"Units": "years"
},
"sex": {
"Description": "Biological sex of the participant",
"Levels": {
"F": "female",
"M": "male"
}
},
"hand": {
"Description": "Handedness of the participant",
"Levels": {
"R": "right",
"L": "left",
"A": "ambidextrous"
}
}
}
Writing '/home/stefanappelhoff/mne_data/MNE-sample-data/../MNE-sample-data-bids/sub-01/meg/sub-01_coordsystem.json'...
{
"MEGCoordinateSystem": "ElektaNeuromag",
"MEGCoordinateUnits": "m",
"MEGCoordinateSystemDescription": "RAS orientation and the origin between the ears",
"HeadCoilCoordinates": {
"NAS": [
3.725290298461914e-09,
0.10260561108589172,
4.190951585769653e-09
],
"LPA": [
-0.07137660682201385,
0.0,
5.122274160385132e-09
],
"RPA": [
0.07526767998933792,
0.0,
5.587935447692871e-09
],
"coil1": [
0.032922741025686264,
0.09897983074188232,
0.07984329760074615
],
"coil2": [
-0.06998106092214584,
0.06771647930145264,
0.06888450682163239
],
"coil3": [
-0.07260829955339432,
-0.02086828649044037,
0.0971473976969719
],
"coil4": [
0.04996863007545471,
-0.007233052980154753,
0.1228904277086258
]
},
"HeadCoilCoordinateSystem": "ElektaNeuromag",
"HeadCoilCoordinateUnits": "m",
"AnatomicalLandmarkCoordinates": {
"NAS": [
3.725290298461914e-09,
0.10260561108589172,
4.190951585769653e-09
],
"LPA": [
-0.07137660682201385,
0.0,
5.122274160385132e-09
],
"RPA": [
0.07526767998933792,
0.0,
5.587935447692871e-09
]
},
"AnatomicalLandmarkCoordinateSystem": "ElektaNeuromag",
"AnatomicalLandmarkCoordinateUnits": "m"
}
Writing '/home/stefanappelhoff/mne_data/MNE-sample-data/../MNE-sample-data-bids/sub-01/meg/sub-01_task-audiovisual_events.tsv'...
onset duration trial_type value sample
277.7153462901591 0.0 BAD boundary 1 166800
277.7153462901591 0.0 EDGE boundary 2 166800
Writing '/home/stefanappelhoff/mne_data/MNE-sample-data/../MNE-sample-data-bids/dataset_description.json'...
{
"Name": " ",
"BIDSVersion": "1.6.0",
"DatasetType": "raw",
"Authors": [
"[Unspecified]"
]
}
Writing '/home/stefanappelhoff/mne_data/MNE-sample-data/../MNE-sample-data-bids/sub-01/meg/sub-01_task-audiovisual_meg.json'...
{
"TaskName": "audiovisual",
"Manufacturer": "Elekta",
"PowerLineFrequency": 60.0,
"SamplingFrequency": 600.614990234375,
"SoftwareFilters": "n/a",
"RecordingDuration": 555.4290276202087,
"RecordingType": "continuous",
"DewarPosition": "n/a",
"DigitizedLandmarks": true,
"DigitizedHeadPoints": true,
"MEGChannelCount": 306,
"MEGREFChannelCount": 0,
"ContinuousHeadLocalization": false,
"HeadCoilFrequency": [],
"EEGChannelCount": 60,
"EOGChannelCount": 1,
"ECGChannelCount": 0,
"EMGChannelCount": 0,
"MiscChannelCount": 0,
"TriggerChannelCount": 9
}
Writing '/home/stefanappelhoff/mne_data/MNE-sample-data/../MNE-sample-data-bids/sub-01/meg/sub-01_task-audiovisual_channels.tsv'...
name type units low_cutoff high_cutoff description sampling_frequency status status_description
MEG 0113 MEGGRADPLANAR T/m 0.10000000149011612 172.17630004882812 Planar Gradiometer 600.614990234375 good n/a
MEG 0112 MEGGRADPLANAR T/m 0.10000000149011612 172.17630004882812 Planar Gradiometer 600.614990234375 good n/a
MEG 0111 MEGMAG T 0.10000000149011612 172.17630004882812 Magnetometer 600.614990234375 good n/a
MEG 0122 MEGGRADPLANAR T/m 0.10000000149011612 172.17630004882812 Planar Gradiometer 600.614990234375 good n/a
MEG 0123 MEGGRADPLANAR T/m 0.10000000149011612 172.17630004882812 Planar Gradiometer 600.614990234375 good n/a
Copying data files to sub-01_task-audiovisual_meg.fif
Reserving possible split file sub-01_task-audiovisual_split-01_meg.fif
Writing /home/stefanappelhoff/mne_data/MNE-sample-data-bids/sub-01/meg/sub-01_task-audiovisual_meg.fif
Closing /home/stefanappelhoff/mne_data/MNE-sample-data-bids/sub-01/meg/sub-01_task-audiovisual_meg.fif
[done]
Writing '/home/stefanappelhoff/mne_data/MNE-sample-data/../MNE-sample-data-bids/sub-01/sub-01_scans.tsv'...
filename acq_time
meg/sub-01_task-audiovisual_meg.fif 2002-12-03T19:01:10.720100Z
Wrote /home/stefanappelhoff/mne_data/MNE-sample-data/../MNE-sample-data-bids/sub-01/sub-01_scans.tsv entry with meg/sub-01_task-audiovisual_meg.fif.
That’s it!
Warning
Remember, this should only ever be a last resort!
Total running time of the script: ( 0 minutes 4.183 seconds)