Sensor Locations from spherical to cartesian

  • MNE version: 1.3.1
  • operating system: e.g. macOS 13 and Windows 10

Hello!

I have a problem reading my sensor locations for EEG. I use the brainvision recorder on the actichamp plus. My header file (vdhr) stores the sensor locations in the spherical system with radius, phi and theta. I needed to add the reference electrode back to the set and also needed to provide information for this electrode about its location in the cartesian coordinate system (XYZ). When I transform with formula the spherical information to cartesian information the sensor location doesnt match at all the other sensor locations that were included somehow automatically. The other locations also dont match the spherical coordinates that are in the header file.

Now I am confused what to put for my XYZ coordinates for the Ref electrode. Can you tell me how the XYZ coordinates used in MNE are calculated from the spherical so I can put the right coordinates?

Best regards

Till

Hello @TBlefthand and welcome to the forum!

This doesn’t exactly answer your question, but since it appears you didn’t actually measure electrode positions, you can just apply one of the template montages that ship with MNE-Python. In this case, I would suggest you choose the easycap-M1 (unless you want to do source modeling later on, in which case standard_1005 is the better choice):

# In case you only do sensor-level processing
raw.set_montage('easycap-M1')
raw.plot_sensors(show_names=True, sphere='eeglab')

# In case you do source-level processing
raw.set_montage('standard_1005')
raw.plot_sensors(show_names=True)

Then just add back your reference channel:

raw.add_reference_channels('Cz')  # or any other location that was used as ref

Best wishes,

Richard

Hello Richard,

thank you for your help. With your information I found a way to add the correct FCz position. The problem was, that in the beginning of my preprocessing the montage was set (I guess by default) before I added the FCz electrode. Hence the position for FCz was missing. I added then the position with the data from BrainVision Recorder by transforming from spherical to cartesian. Of course this didn’t work since the other electrode positions were set by MNE by default and are NOT connected to the BrainVision file.

I was afraid I had to do alle the preprocessing again now but i found a solution with using as a test on one of my data file:

import mne

# Provide the path to your BrainVision file (.vhdr)
file_path = 'path/to/your/file.vhdr'

# Read the BrainVision file
raw = mne.io.read_raw_brainvision(file_path, preload=True)

# Now already add the electrode
raw.add_reference_channels('FCz')

# Now set montage
raw.set_montage('easycap-M1')
raw.plot_sensors(show_names=True, sphere='eeglab')

# Get information about FCz location 
print(raw.info["chs"])

# Look for the coordinates of FCz and pass them into my tfr object
fcz_info = condition_a_tfr.info["chs"][condition_a_tfr.ch_names.index("FCz")]

# Set x, y, z coordinates for the new FCz channel 
fcz_info['loc'][0] = 2.27291122e-18 
fcz_info['loc'][1] =  3.71194572e-02      
fcz_info['loc'][2] = 1.27596696e-01

Although I see that the z coordinates seem not to fit. X and Y is perfect. Z is too high in the montage.

Do you know which montage is set with importing the raw data just without specifiying a montage?
Best regards,

Till

Sorry, the order of doing things that I proposed was incorrect. You should first add the reference channel, and then set the montage. Things become very straightforward that way:

# %%
import mne

ssvep_folder = mne.datasets.ssvep.data_path()
ssvep_data_raw_path = (
    ssvep_folder / "sub-02" / "ses-01" / "eeg" / "sub-02_ses-01_task-ssvep_eeg.vhdr"
)
ssvep_raw = mne.io.read_raw_brainvision(ssvep_data_raw_path, preload=True, verbose=False)

# %% Add reference channel back
ssvep_raw.add_reference_channels("FCz")
ssvep_raw.set_montage("easycap-M1")
ssvep_raw.plot_sensors(show_names=True)

No, I don’t know. @sappelhoff any idea? It’s for reading BV files.

Best wishes,
Richard

1 Like

Is there also a way to apply the set_montage on Epochs or TFR? I already did my preprocessing with the wrong coordinates and I would like to avoid computing everything again from the beginning…

I also figured out that the coordinates that got added by default have a very bad layout on the topography with the signal extending a lot over the head. When i apply the set_montage (easycap-M1) it fits good into the head of the topo.
Therefore I would also like to change them for visualisation purposes.

Best regards and thanks for the help,

Till


If a montage is present after reading a raw BrainVision file, then that means that the coordinates are present in the header file (.vhdr), see also this part of the code: https://github.com/mne-tools/mne-python/blob/c98749b529a41473cfccbc18485a9d1924546545/mne/io/brainvision/brainvision.py#L619-L626

Only the person who was recording the data will be able to tell you which exact montage the data in the .vhdr file corresponds to, but based on my experience this is not measured (i.e., digitized) electrode position data, but idealized “template” position data.

2 Likes