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

Deprecate write_raw_bids()'s events_data parameter in favor of "events" #1054

Merged
merged 13 commits into from
Aug 21, 2022
2 changes: 2 additions & 0 deletions doc/whats_new.rst
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ Detailed list of changes
🧐 API and behavior changes
^^^^^^^^^^^^^^^^^^^^^^^^^^^

- The ``events_data`` parameter of :func:`~mne_bids.write_raw_bids` has been deprecated in favor of a new parameter named ``events``. This ensures more consistency between the MNE-BIDS and MNE-Python APIs. You may continue using the ``events_data`` parameter for now, but a ``FutureWarning`` will be raised. ``events_data`` will be removed in a future release, by `Richard Höchenberger`_ (:gh:`1054`)

- In many places, we used to infer the ``datatype`` of a :class:`~mne_bids.BIDSPath` from the ``suffix``, if not explicitly provided. However, this has lead to trouble in certain edge cases. In an effort to reduce the amount of implicit behavior in MNE-BIDS, we now require users to explicitly specify a ``datatype`` whenever the invoked functions or methods expect one, by `Richard Höchenberger`_ (:gh:`1030`)

- :func:`mne_bids.make_dataset_description` now accepts keyword arguments only, and can now also write the following metadata: ``HEDVersion``, ``EthicsApprovals``, ``GeneratedBy``, and ``SourceDatasets``, by `Stefan Appelhoff`_ (:gh:`406`)
Expand Down
2 changes: 1 addition & 1 deletion examples/anonymize_dataset.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@

# Write experimental MEG data, fine-calibration and crosstalk files
write_raw_bids(
raw=raw, bids_path=bids_path, events_data=events_path, event_id=event_id,
raw=raw, bids_path=bids_path, events=events_path, event_id=event_id,
empty_room=bids_path_er, verbose=False
)
write_meg_calibration(cal_path, bids_path=bids_path, verbose=False)
Expand Down
3 changes: 1 addition & 2 deletions examples/convert_empty_room.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,7 @@
shutil.rmtree(bids_root)

# %%
# Specify the raw_file and events_data and run the BIDS conversion, and write
# the BIDS data.
# Specify the raw file 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
Expand Down
6 changes: 3 additions & 3 deletions examples/convert_mne_sample.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
# Now we can read the MNE sample data. We define an `event_id` based on our
# knowledge of the data, to give meaning to events in the data.
#
# With `raw_fname` and `events_data`, we determine where to get the sample data
# With `raw_fname` and `events`, we determine where to get the sample data
# from. `output_path` determines where we will write the BIDS conversion to.

data_path = sample.data_path()
Expand All @@ -53,7 +53,7 @@

raw_fname = op.join(data_path, 'MEG', 'sample', 'sample_audvis_raw.fif')
er_fname = op.join(data_path, 'MEG', 'sample', 'ernoise_raw.fif') # empty room
events_data = op.join(data_path, 'MEG', 'sample', 'sample_audvis_raw-eve.fif')
events_fname = op.join(data_path, 'MEG', 'sample', 'sample_audvis_raw-eve.fif')
output_path = op.join(data_path, '..', 'MNE-sample-data-bids')

# %%
Expand Down Expand Up @@ -99,7 +99,7 @@
write_raw_bids(
raw=raw,
bids_path=bids_path,
events_data=events_data,
events=events_fname,
event_id=event_id,
empty_room=raw_er,
overwrite=True
Expand Down
4 changes: 2 additions & 2 deletions examples/convert_mri_and_trans.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
event_id = {'Auditory/Left': 1, 'Auditory/Right': 2, 'Visual/Left': 3,
'Visual/Right': 4, 'Smiley': 5, 'Button': 32}
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')
events_fname = op.join(data_path, 'MEG', 'sample', 'sample_audvis_raw-eve.fif')
output_path = op.abspath(op.join(data_path, '..', 'MNE-sample-data-bids'))
fs_subjects_dir = op.join(data_path, 'subjects') # FreeSurfer subjects dir

Expand All @@ -87,7 +87,7 @@
run = '01'
bids_path = BIDSPath(subject=sub, session=ses, task=task,
run=run, root=output_path)
write_raw_bids(raw, bids_path, events_data=events_data,
write_raw_bids(raw, bids_path, events=events_fname,
event_id=event_id, overwrite=True)

# %%
Expand Down
2 changes: 1 addition & 1 deletion examples/mark_bad_channels.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@

raw = mne.io.read_raw_fif(raw_fname, verbose=False)
raw.info['line_freq'] = 60 # Specify power line frequency as required by BIDS.
write_raw_bids(raw, bids_path=bids_path, events_data=events_fname,
write_raw_bids(raw, bids_path=bids_path, events=events_fname,
event_id=event_id, overwrite=True, verbose=False)

# %%
Expand Down
6 changes: 4 additions & 2 deletions mne_bids/commands/mne_bids_raw_to_bids.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ def run():
help='run number for this dataset')
parser.add_option('--acq', dest='acq',
help='acquisition parameter for this dataset')
parser.add_option('--events_data', dest='events_data',
parser.add_option('--events_data', dest='events',
help='Deprecated. Pass --events instead.')
parser.add_option('--events', dest='events',
help='events file (events.tsv)')
parser.add_option('--event_id', dest='event_id',
help='event id dict', metavar='eid')
Expand Down Expand Up @@ -81,7 +83,7 @@ def run():
line_freq = None if opt.line_freq == "None" else opt.line_freq
raw.info['line_freq'] = line_freq
write_raw_bids(raw, bids_path, event_id=opt.event_id,
events_data=opt.events_data, overwrite=opt.overwrite,
events=opt.events, overwrite=opt.overwrite,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will break backward compat if you don’t pass events_data no?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in f6de206

verbose=True)


Expand Down
4 changes: 2 additions & 2 deletions mne_bids/commands/tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -257,8 +257,8 @@ def test_count_events(tmp_path):
'visual/right': 4, 'face': 5, 'button': 32}

bids_path = BIDSPath(subject='01', root=output_path, task='foo')
write_raw_bids(raw, bids_path, events, event_id, overwrite=True,
verbose=False)
write_raw_bids(raw, bids_path, events=events, event_id=event_id,
overwrite=True, verbose=False)

with ArgvSetter(('--bids_root', output_path)):
mne_bids_count_events.run()
Expand Down
2 changes: 1 addition & 1 deletion mne_bids/inspect.py
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ def _save_annotations(*, annotations, bids_path):
raw = read_raw_bids(bids_path=bids_path, extra_params=extra_params,
verbose='warning')
raw.set_annotations(annotations)
events, durs, descrs = _read_events(events_data=None, event_id=None,
events, durs, descrs = _read_events(events=None, event_id=None,
bids_path=bids_path, raw=raw)

# Write sidecar – or remove it if no events are left.
Expand Down
26 changes: 13 additions & 13 deletions mne_bids/read.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,12 +74,12 @@ def _read_raw(raw_path, electrode=None, hsp=None, hpi=None,
return raw


def _read_events(events_data, event_id, raw, bids_path=None):
def _read_events(events, event_id, raw, bids_path=None):
"""Retrieve events (for use in *_events.tsv) from FIFF/array & Annotations.

Parameters
----------
events_data : path-like | np.ndarray | None
events : path-like | np.ndarray | None
If a string, a path to an events file. If an array, an MNE events array
(shape n_events, 3). If None, events will be generated from
``raw.annotations``.
Expand Down Expand Up @@ -107,19 +107,19 @@ def _read_events(events_data, event_id, raw, bids_path=None):
the values to the event IDs.

"""
# get events from events_data
if isinstance(events_data, np.ndarray):
if events_data.ndim != 2:
# retrieve events
if isinstance(events, np.ndarray):
if events.ndim != 2:
raise ValueError('Events must have two dimensions, '
f'found {events_data.ndim}')
if events_data.shape[1] != 3:
f'found {events.ndim}')
if events.shape[1] != 3:
raise ValueError('Events must have second dimension of length 3, '
f'found {events_data.shape[1]}')
events = events_data
elif events_data is None:
f'found {events.shape[1]}')
events = events
elif events is None:
events = np.empty(shape=(0, 3), dtype=int)
else:
events = read_events(events_data).astype(int)
events = read_events(events).astype(int)

if events.size > 0:
# Only keep events for which we have an ID <> description mapping.
Expand All @@ -129,7 +129,7 @@ def _read_events(events_data, event_id, raw, bids_path=None):
f'No description was specified for the following event(s): '
f'{", ".join([str(x) for x in sorted(ids_without_desc)])}. '
f'Please add them to the event_id dictionary, or drop them '
f'from the events_data array.'
f'from the events array.'
)
del ids_without_desc
mask = [e in list(event_id.values()) for e in events[:, 2]]
Expand Down Expand Up @@ -175,7 +175,7 @@ def _read_events(events_data, event_id, raw, bids_path=None):
)
):
warn('No events found or provided. Please add annotations to the raw '
'data, or provide the events_data and event_id parameters. For '
'data, or provide the events and event_id parameters. For '
'resting state data, BIDS recommends naming the task using '
'labels beginning with "rest".')

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
# %%

write_raw_bids(
raw, bids_path, events_data=events, event_id=event_id, overwrite=True
raw, bids_path, events=events, event_id=event_id, overwrite=True
)

# %%
Expand Down
2 changes: 1 addition & 1 deletion mne_bids/tests/test_inspect.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ def setup_bids_test_dir(bids_root):
events = events[events[:, 2] != 0]

bids_path = _bids_path.copy().update(root=bids_root)
write_raw_bids(raw, bids_path=bids_path, events_data=events,
write_raw_bids(raw, bids_path=bids_path, events=events,
event_id=event_id, overwrite=True)
write_meg_calibration(cal_fname, bids_path=bids_path)
write_meg_crosstalk(crosstalk_fname, bids_path=bids_path)
Expand Down
2 changes: 1 addition & 1 deletion mne_bids/tests/test_path.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ def return_bids_test_dir(tmp_path_factory):
# Write multiple runs for test_purposes
for run_idx in [run, '02']:
name = bids_path.copy().update(run=run_idx)
write_raw_bids(raw, name, events_data=events,
write_raw_bids(raw, name, events=events,
event_id=event_id, overwrite=True)

write_meg_calibration(cal_fname, bids_path=bids_path)
Expand Down
4 changes: 2 additions & 2 deletions mne_bids/tests/test_read.py
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ def test_get_head_mri_trans(tmp_path):
bids_path = _bids_path.copy().update(
root=tmp_path, datatype='meg', suffix='meg'
)
write_raw_bids(raw, bids_path, events_data=events, event_id=event_id,
write_raw_bids(raw, bids_path, events=events, event_id=event_id,
overwrite=False)

# We cannot recover trans if no MRI has yet been written
Expand Down Expand Up @@ -293,7 +293,7 @@ def test_get_head_mri_trans(tmp_path):
# test we are permissive for different casings of landmark names in the
# sidecar, and also accept "nasion" instead of just "NAS"
raw = _read_raw_fif(raw_fname)
write_raw_bids(raw, bids_path, events_data=events, event_id=event_id,
write_raw_bids(raw, bids_path, events=events, event_id=event_id,
overwrite=True) # overwrite with new acq
t1w_bids_path = write_anat(
t1w_mgh, bids_path=t1w_bids_path, landmarks=landmarks, overwrite=True
Expand Down
4 changes: 2 additions & 2 deletions mne_bids/tests/test_stats.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ def _make_dataset(root, subjects, tasks=(None,), runs=(None,),
bids_path = BIDSPath(
subject=subject, session=session, run=run, task=task, root=root,
)
write_raw_bids(raw, bids_path, events, event_id, overwrite=True,
verbose=False)
write_raw_bids(raw, bids_path, events=events, event_id=event_id,
overwrite=True, verbose=False)

return root, events, event_id

Expand Down
2 changes: 1 addition & 1 deletion mne_bids/tests/test_update.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ def _get_bids_test_dir(tmp_path_factory):
# Write multiple runs for test_purposes
for run_idx in [run, '02']:
name = bids_path.copy().update(run=run_idx)
write_raw_bids(raw, name, events_data=events,
write_raw_bids(raw, name, events=events,
event_id=event_id, overwrite=True)

write_meg_calibration(cal_fname, bids_path=bids_path)
Expand Down