diff --git a/doc/changes/devel/12699.apichange.rst b/doc/changes/devel/12699.apichange.rst new file mode 100644 index 00000000000..37f489afeb6 --- /dev/null +++ b/doc/changes/devel/12699.apichange.rst @@ -0,0 +1 @@ +Documented that :func:`~mne.match_channel_orders` can also work on Epochs, and Evoked objects. Reflecting this, deprecated the ``raws`` parameter in favor of an ``insts`` parameter, by `Stefan Appelhoff`_. diff --git a/mne/io/base.py b/mne/io/base.py index d419bcb548f..a1485e6caf6 100644 --- a/mne/io/base.py +++ b/mne/io/base.py @@ -3083,25 +3083,44 @@ def concatenate_raws( @fill_doc -def match_channel_orders(raws, copy=True): - """Ensure consistent channel order across raws. +def match_channel_orders(insts=None, copy=True, *, raws=None): + """Ensure consistent channel order across instances (Raw, Epochs, or Evoked). Parameters ---------- - raws : list - List of :class:`~mne.io.Raw` instances to order. + insts : list + List of :class:`~mne.io.Raw`, :class:`~mne.Epochs`, + or :class:`~mne.Evoked` instances to order. %(copy_df)s + raws : list + This parameter is deprecated and will be removed in mne version 1.9. + Please use ``insts`` instead. Returns ------- - list of Raw - List of Raws with matched channel orders. + list of Raw | list of Epochs | list of Evoked + List of instances (Raw, Epochs, or Evoked) with channel orders matched + according to the order they had in the first item in the ``insts`` list. """ - raws = deepcopy(raws) if copy else raws - ch_order = raws[0].ch_names - for raw in raws[1:]: - raw.reorder_channels(ch_order) - return raws + # XXX: remove "raws" parameter and logic below with MNE version 1.9 + # and remove default parameter value of insts + if raws is not None: + warn( + "The ``raws`` parameter is deprecated and will be removed in version " + "1.9. Use the ``insts`` parameter to suppress this warning.", + DeprecationWarning, + ) + insts = raws + elif insts is None: + # both insts and raws is None + raise ValueError( + "You need to pass a list of Raw, Epochs, or Evoked to ``insts``." + ) + insts = deepcopy(insts) if copy else insts + ch_order = insts[0].ch_names + for inst in insts[1:]: + inst.reorder_channels(ch_order) + return insts def _check_maxshield(allow_maxshield): diff --git a/mne/io/fiff/tests/test_raw_fiff.py b/mne/io/fiff/tests/test_raw_fiff.py index b6abb73b926..3b5949539dd 100644 --- a/mne/io/fiff/tests/test_raw_fiff.py +++ b/mne/io/fiff/tests/test_raw_fiff.py @@ -475,11 +475,19 @@ def test_concatenate_raws_order(): with pytest.raises(ValueError, match="Channel order must match."): # still fails, because raws is copied and not changed in place - match_channel_orders(raws, copy=True) + match_channel_orders(insts=raws, copy=True) raw_concat = concatenate_raws(raws) + # XXX: remove in version 1.9 + with pytest.warns(DeprecationWarning, match="``raws`` parameter is deprecated"): + match_channel_orders(raws=raws) + + # XXX: remove in version 1.9 + with pytest.raises(ValueError, match="need to pass a list"): + match_channel_orders() + # Now passes because all raws have the same order - match_channel_orders(raws, copy=False) + match_channel_orders(insts=raws, copy=False) raw_concat = concatenate_raws(raws) ch0 = raw_concat.get_data(picks=["0"]) assert np.all(ch0 == 0)