To set my montage correctly

  • MNE version: 1.3.0
  • operating system: macOS 11.2

I want to set my montage with default β€˜standard_1020’.

My data has 62 channels, corresponding to 64 channels but β€˜M1’ and β€˜M2’ are missing.
My channels are [β€˜FP1’, β€˜FPZ’, β€˜FP2’, β€˜AF3’, β€˜AF4’, β€˜F7’, β€˜F5’, β€˜F3’, β€˜F1’, β€˜FZ’, β€˜F2’, β€˜F4’, β€˜F6’, β€˜F8’, β€˜FT7’, β€˜FC5’, β€˜FC3’, β€˜FC1’, β€˜FCZ’, β€˜FC2’, β€˜FC4’, β€˜FC6’, β€˜FT8’, β€˜T7’, β€˜C5’, β€˜C3’, β€˜C1’, β€˜CZ’, β€˜C2’, β€˜C4’, β€˜C6’, β€˜T8’, β€˜TP7’, β€˜CP5’, β€˜CP3’, β€˜CP1’, β€˜CPZ’, β€˜CP2’, β€˜CP4’, β€˜CP6’, β€˜TP8’, β€˜P7’, β€˜P5’, β€˜P3’, β€˜P1’, β€˜PZ’, β€˜P2’, β€˜P4’, β€˜P6’, β€˜P8’, β€˜PO7’, β€˜PO5’, β€˜PO3’, β€˜POZ’, β€˜PO4’, β€˜PO6’, β€˜PO8’, β€˜CB1’, β€˜O1’, β€˜OZ’, β€˜O2’, β€˜CB2’]

info = mne.create_info(ch_names, sfreq, ch_types='eeg')
# **samples** is a (62,37001) ndarray
raw = mne.io.RawArray(samples, info)
montage = mne.channels.make_standard_montage('standard_1020')
raw.set_montage(montage)

Then, when I try toraw.plot_psd_topo() it says ValueError: The following electrodes have overlapping positions, which causes problems during visualization: FP1, FPZ, FP2, FZ, FCZ, CZ, CPZ, PZ, POZ, CB1, OZ, CB2 but actually I use the default montage, why could this happen?

Hi @Chauncy ,

The channels that appear in the ValueError are channels that don’t have locations in the montage you set. I’m guessing that you set your montage to raw.set_montage(montage, on_missing="ignore") ?

From what I can tell, you will need to set the locations for all the electrodes before you call plot_topo.

There are a couple issues that you’ll need to fix. First, by default, set_montage is case sensitive and your channel names don’t match the case of the channel names in the standard_1020 template eeg montage (For example, it’s "Fp1" in the template montage, but your channel name is "FP1":

template_1020_montage = mne.channels.make_standard_montage("standard_1020")
print(template_1020_montage.ch_names)
# ['Fp1', 'Fpz', 'Fp2', 'AF9', 'AF7', 'AF5', 'AF3', .... 'A2']

Second, "CB1" and "CB2" are not in the standard 1020 montage. But you could use the "standard_1005" template montage, which has channels "P007" and "P008", which we know to be β€œaliases” for "CB1" and "CB2":

template_1005_montage = mne.channels.make_standard_montage('standard_1005')
print(template_1005_montage.ch_names)
# ['Fp1', 'Fpz', 'Fp2', ... , 'POO7',  'POO8', ..., 'A1', 'A2']
print(mne.io.constants.CHANNEL_LOC_ALIASES)
 # {'Cb1': 'POO7', ..., 'CB1': 'POO7', 'CB2': 'POO8', ..., }

So given your two issues, you can pass match_case=False and match_alias=True to set_montage to make channel matching case-insensitive, and to look for the known aliases we highlighted above:

raw.set_montage(template_1005_montage, match_case=False, match_alias=True)
psd = raw.compute_psd()
psd.plot_topo()

Note that raw.plot_psd_topo() is a legacy function and is not recommended. Please use raw.compute_psd().plot_topo() like I did in the code above.

Scott

2 Likes

Thank you for helping me, this really works! :wink:

1 Like