moabb
moabb copied to clipboard
`Ofner2017(executed=True)` can't set montage and fails
Hi, new bug encountered:
from moabb.datasets import Ofner2017
Ofner2017(executed=True).get_data([1])
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
Cell In[10], line 1
----> 1 Ofner2017(executed=True).get_data([1])
File ~/miniconda3/envs/motor_embedding_benchmark/lib/python3.10/site-packages/moabb/datasets/base.py:113, in BaseDataset.get_data(self, subjects)
111 if subject not in self.subject_list:
112 raise ValueError("Invalid subject {:d} given".format(subject))
--> 113 data[subject] = self._get_single_subject_data(subject)
115 return data
File ~/miniconda3/envs/motor_embedding_benchmark/lib/python3.10/site-packages/moabb/datasets/upper_limb.py:113, in Ofner2017._get_single_subject_data(self, subject)
109 for ii, path in enumerate(paths):
110 raw = read_raw_gdf(
111 path, eog=eog, misc=range(64, 96), preload=True, verbose="ERROR"
112 )
--> 113 raw.set_montage(montage)
114 # there is nan in the data
115 raw._data[np.isnan(raw._data)] = 0
File <decorator-gen-36>:12, in set_montage(self, montage, match_case, match_alias, on_missing, verbose)
File ~/miniconda3/envs/motor_embedding_benchmark/lib/python3.10/site-packages/mne/io/meas_info.py:423, in MontageMixin.set_montage(self, montage, match_case, match_alias, on_missing, verbose)
420 from ..channels.montage import _set_montage
422 info = self if isinstance(self, Info) else self.info
--> 423 _set_montage(info, montage, match_case, match_alias, on_missing)
424 return self
File ~/miniconda3/envs/motor_embedding_benchmark/lib/python3.10/site-packages/mne/channels/montage.py:1258, in _set_montage(***failed resolving arguments***)
1247 are_is = "are" if pl else "is"
1248 missing_coord_msg = (
1249 f"DigMontage is only a subset of info. There {are_is} "
1250 f"{len(missing)} channel position{pl} not present in the "
(...)
1256 f"position{pl} {are_is} allowed to be unknown in your analyses."
1257 )
-> 1258 _on_missing(on_missing, missing_coord_msg)
1260 # set ch coordinates and names from digmontage or nan coords
1261 for ii in missing:
File ~/miniconda3/envs/motor_embedding_benchmark/lib/python3.10/site-packages/mne/utils/check.py:1142, in _on_missing(on_missing, msg, name, error_klass)
1140 on_missing = "warn" if on_missing == "warning" else on_missing
1141 if on_missing == "raise":
-> 1142 raise error_klass(msg)
1143 elif on_missing == "warn":
1144 warn(msg)
ValueError: DigMontage is only a subset of info. There are 61 channel positions not present in the DigMontage. The channels missing from the montage are:
['eeg-0', 'eeg-1', 'eeg-2', 'eeg-3', 'eeg-4', 'eeg-5', 'eeg-6', 'eeg-7', 'eeg-8', 'eeg-9', 'eeg-10', 'eeg-11', 'eeg-12', 'eeg-13', 'eeg-14', 'eeg-15', 'eeg-16', 'eeg-17', 'eeg-18', 'eeg-19', 'eeg-20', 'eeg-21', 'eeg-22', 'eeg-23', 'eeg-24', 'eeg-25', 'eeg-26', 'eeg-27', 'eeg-28', 'eeg-29', 'eeg-30', 'eeg-31', 'eeg-32', 'eeg-33', 'eeg-34', 'eeg-35', 'eeg-36', 'eeg-37', 'eeg-38', 'eeg-39', 'eeg-40', 'eeg-41', 'eeg-42', 'eeg-43', 'eeg-44', 'eeg-45', 'eeg-46', 'eeg-47', 'eeg-48', 'eeg-49', 'eeg-50', 'eeg-51', 'eeg-52', 'eeg-53', 'eeg-54', 'eeg-55', 'eeg-56', 'eeg-57', 'eeg-58', 'eeg-59', 'eeg-60'].
Consider using inst.rename_channels to match the montage nomenclature, or inst.set_channel_types if these are not EEG channels, or use the on_missing parameter if the channel positions are allowed to be unknown in your analyses.
Good catch!
I think we need to rename the electrodes as no montage seems to map the electrode names (eeg-0, ..., eeg-60). The closest one are the "GSN-HydroCel-65_1.0" or "GSN-HydroCel-64_1.0", with E1, ..., E64 names. If there are sensors locations, we could use mne.channels.read_custom_montage
, mne.channels.make_dig_montage
or mne.channels.make_eeg_layout
.