Issue with setting a montage

  • MNE-Python version: 0.23.0
  • operating system: Mac os (Big Sur)
import os
import numpy as np
import matplotlib as plt
import pandas
import pathlib
import mne
import mnelab

fname = "fname.fif"
plt.use('Qt5Agg')

raw = mne.io.read_raw_fif(fname, preload=True)
raw.crop(tmax=60).load_data()
montage = mne.channels.make_standard_montage('standard_1020')
raw.set_montage(montage, on_missing='ignore')
raw_1020 = raw.copy().set_montage(ten_twenty_montage)
ica = mne.preprocessing.ICA(n_components=15, random_state=97)
raw.plot_projs_topomap(colorbar=True)

I get a division by 0 error. I believe the issue is that the sensor localization is not taking. I am unsure how to fix this? I am using a traditional 10-20 electrode set up

Hello, could you please share the full error message?

(And to get good formatting, first paste it into the forum editor window, then select it, and click on the “Preformatted text” button in the toolbar; I’ve edited your previous post in a similar way to improve readability)

montage = mne.channels.make_standard_montage(‘standard_1020’)
raw.set_montage(montage, on_missing=‘ignore’)
raw_1020 = raw.copy().set_montage(ten_twenty_montage)
ica = mne.preprocessing.ICA(n_components=15, random_state=97)
ica.fit(raw)
ica.plot_sources(raw)
ica.plot_components()
montage = mne.channels.make_standard_montage(‘standard_1020’)
raw.set_montage(montage, on_missing=‘ignore’)
raw_1020 = raw.copy().set_montage(ten_twenty_montage)
ica = mne.preprocessing.ICA(n_components=15, random_state=97)
ica.fit(raw)
ica.plot_sources(raw)
ica.plot_components()


ValueError Traceback (most recent call last)
in
1 montage = mne.channels.make_standard_montage(‘standard_1020’)
2 raw.set_montage(montage, on_missing=‘ignore’)
----> 3 raw_1020 = raw.copy().set_montage(ten_twenty_montage)
4 ica = mne.preprocessing.ICA(n_components=15, random_state=97)
5 ica.fit(raw)

in set_montage(self, montage, match_case, match_alias, on_missing, verbose)

~/opt/anaconda3/lib/python3.8/site-packages/mne/io/meas_info.py in set_montage(self, montage, match_case, match_alias, on_missing, verbose)
168 from …channels.montage import _set_montage
169 info = self if isinstance(self, Info) else self.info
→ 170 _set_montage(info, montage, match_case, match_alias, on_missing)
171 return self
172

~/opt/anaconda3/lib/python3.8/site-packages/mne/channels/montage.py in _set_montage(failed resolving arguments)
890 ‘in your analyses.’
891 )
→ 892 _on_missing(on_missing, missing_coord_msg)
893
894 # set ch coordinates and names from digmontage or nan coords

~/opt/anaconda3/lib/python3.8/site-packages/mne/utils/check.py in _on_missing(on_missing, msg, name, error_klass)
755 on_missing = ‘warn’ if on_missing == ‘warning’ else on_missing
756 if on_missing == ‘raise’:
→ 757 raise error_klass(msg)
758 elif on_missing == ‘warn’:
759 warn(msg)

ValueError: DigMontage is only a subset of info. There are 24 channel positions not present in the DigMontage. The required channels are:

[‘EEG P3-Pz’, ‘EEG C3-Pz’, ‘EEG F3-Pz’, ‘EEG Fz-Pz’, ‘EEG F4-Pz’, ‘EEG C4-Pz’, ‘EEG P4-Pz’, ‘EEG Cz-Pz’, ‘CM’, ‘EEG A1-Pz’, ‘EEG Fp1-Pz’, ‘EEG Fp2-Pz’, ‘EEG T3-Pz’, ‘EEG T5-Pz’, ‘EEG O1-Pz’, ‘EEG O2-Pz’, ‘EEG X3-Pz’, ‘EEG X2-Pz’, ‘EEG F7-Pz’, ‘EEG F8-Pz’, ‘EEG X1-Pz’, ‘EEG A2-Pz’, ‘EEG T6-Pz’, ‘EEG T4-Pz’].

Consider using 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.

You need to pass on_missing=‘ignore’ to your call to set_montage() in line 3; or drop the channels that are not present in the montage from the data; or use a montage that actually contains all the channel names that are present in your data.

All problematic channel names end with -Pz, what does that mean?

Each electrode was normalized through the subtraction of the Pz electrode!

1 Like

This may be the case, but the electrodes don’t have standard naming anymore, so the montage that ships with MNE cannot be applied to them. So the easiest solution is probably to rename the electrodes to get rid of the suffix that was added through referencing. Let me know if you need help doing that.

Best wishes
Richard

Edit: And the “EEG” prefix must be removed too, I believe.

Thank you for that input. Realistically I will normally be working with edfs. Do you know the syntax for renaming edf channels?

This has nothing to do with the input format: once the data is loaded into MNE, it’s essentially all the same, no matter if the data was originally stored as an EDF or FIFF or BrainVision file on disk.

Once you’ve loaded your raw data, you can use Raw.rename_channels() to fix the channel naming. The method accepts a “callable” (i.e., a function) as first parameter. So let’s write a small function to clean up the channel names for you:

def rename_channel_to_standard(
    orig_name: str
) -> str:
    new_name = (orig_name
                .replace('EEG ', '')
                .replace('-Pz', ''))
    return new_name

You can then pass this function name to rename_channels():

raw = ...  # load your data here
raw.rename_channels(mapping=rename_channel_to_standard)

And you’re good! You can verify that the renaming was successful by looking at the channel names:

print(raw.ch_names)

This was very helpful! Thank you!