# Sensor Locations from spherical to cartesian

**URL:** <https://mne.discourse.group/t/sensor-locations-from-spherical-to-cartesian/7043>\
**Category:** Support & Discussions\
**Tags:** sensor-space\
**Created:** [June 8, 2023, 1:49pm UTC](https://mne.discourse.group/t/sensor-locations-from-spherical-to-cartesian/7043 "2023-06-08T13:49:42Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![TBlefthand](https://avatars.discourse-cdn.com/v4/letter/t/b487fb/32.png) [@TBlefthand](https://mne.discourse.group/u/TBlefthand)\
**Post date:** [June 8, 2023, 1:49pm UTC](https://mne.discourse.group/t/sensor-locations-from-spherical-to-cartesian/7043/1 "2023-06-08T13:49:42Z")

</div>

- 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

---

<div class="post-metadata">

**Author:** ![richard](https://yyz2.discourse-cdn.com/free1/user_avatar/mne.discourse.group/richard/32/15_2.png) [@richard](https://mne.discourse.group/u/richard)\
**Post date:** [June 8, 2023, 1:59pm UTC](https://mne.discourse.group/t/sensor-locations-from-spherical-to-cartesian/7043/2 "2023-06-08T13:59:13Z")

</div>

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):

```python
# 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:

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

```

Best wishes,

Richard

---

<div class="post-metadata">

**Author:** ![TBlefthand](https://avatars.discourse-cdn.com/v4/letter/t/b487fb/32.png) [@TBlefthand](https://mne.discourse.group/u/TBlefthand)\
**Post date:** [June 9, 2023, 9:09am UTC](https://mne.discourse.group/t/sensor-locations-from-spherical-to-cartesian/7043/3 "2023-06-09T09:09:13Z")

</div>

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:

```python
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

---

<div class="post-metadata">

**Author:** ![richard](https://yyz2.discourse-cdn.com/free1/user_avatar/mne.discourse.group/richard/32/15_2.png) [@richard](https://mne.discourse.group/u/richard)\
**Post date:** [June 9, 2023, 10:22am UTC](https://mne.discourse.group/t/sensor-locations-from-spherical-to-cartesian/7043/4 "2023-06-09T10:22:32Z")

</div>

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:

```python
# %%
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)

```

> [@TBlefthand](#):
>
> Do you know which montage is set with importing the raw data just without specifiying a montage?

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

Best wishes,  
Richard

---

<div class="post-metadata">

**Author:** ![TBlefthand](https://avatars.discourse-cdn.com/v4/letter/t/b487fb/32.png) [@TBlefthand](https://mne.discourse.group/u/TBlefthand)\
**Post date:** [June 9, 2023, 1:44pm UTC](https://mne.discourse.group/t/sensor-locations-from-spherical-to-cartesian/7043/5 "2023-06-09T13:44:54Z")

</div>

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

 ![Bildschirmfoto 2023-06-09 um 15.44.23](https://global.discourse-cdn.com/free1/uploads/mne/original/2X/c/c49cbca752d5c66f253244487f8f9814f160e7b4.png)  
 ![Bildschirmfoto 2023-06-09 um 15.44.12](https://global.discourse-cdn.com/free1/uploads/mne/original/2X/d/d8256412989b6890f1ab6a9430ac87ad108b2361.png)

---

<div class="post-metadata">

**Author:** ![sappelhoff](https://yyz2.discourse-cdn.com/free1/user_avatar/mne.discourse.group/sappelhoff/32/3276_2.png) [@sappelhoff](https://mne.discourse.group/u/sappelhoff)\
**Post date:** [June 11, 2023, 10:32am UTC](https://mne.discourse.group/t/sensor-locations-from-spherical-to-cartesian/7043/6 "2023-06-11T10:32:14Z")

</div>

> [@richard](#):
>
> > [@TBlefthand](#):
> >
> > Do you know which montage is set with importing the raw data just without specifiying a montage?
> 
> No, I don’t know. @sappelhoff any idea? It’s for reading BV files.

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](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.
