# Changing EEG locations format from using montages

**URL:** <https://mne.discourse.group/t/changing-eeg-locations-format-from-using-montages/9122>\
**Category:** Support & Discussions\
**Created:** [July 25, 2024, 6:27pm UTC](https://mne.discourse.group/t/changing-eeg-locations-format-from-using-montages/9122 "2024-07-25T18:27:18Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![codZeus](https://avatars.discourse-cdn.com/v4/letter/c/f1d935/32.png) [@codZeus](https://mne.discourse.group/u/codZeus)\
**Post date:** [July 25, 2024, 6:27pm UTC](https://mne.discourse.group/t/changing-eeg-locations-format-from-using-montages/9122/1 "2024-07-25T18:27:18Z")

</div>

Hi everyone,

It’s been a while I asked a question.

A question was asked about getting eeg locations from montages from here  
[electrode positions](https://mne.discourse.group/t/mne-help-getting-electrode-positions-from-digmontage/2191/2)

When I use that method on an arbitrary data, I get the eeg locations in 3D but in this format

```python
'Fp1' = array([-0.0294367, 0.0839171, -0.00699])

```

whiles if I don’t use the set\_montage method, and I use my actual data

```python
raweeg['info']['channels'][0]['locations'][0]

```

I get this

```python
'Fp1' = {'X': ['-27.0'], 'Y': ['86.0'], 'Z': ['36.0']}

```

for the locations in 3D.  
So my question is when using the set\_montage method:

1. are the locations normalized? and How do I get them to the format

```python
{'X': ['-27.0'], 'Y': ['86.0'], 'Z': ['36.0']}

```

Also, I found this link [eeg\_positions](https://github.com/sappelhoff/eeg_positions?tab=readme-ov-file) it gives all the coordinates in 2d or 3d. I tried comparing them with the 1020 system coordinates using mne.channels.make\_standard\_montage(“standard\_1020”) and they were not the same.  
2. Which one is advisable to use?  
I am sorry I can’t provide my data for the experiment.

Any help is appreciated.

---

<div class="post-metadata">

**Author:** ![mscheltienne](https://yyz2.discourse-cdn.com/free1/user_avatar/mne.discourse.group/mscheltienne/32/827_2.png) [@mscheltienne](https://mne.discourse.group/u/mscheltienne)\
**Post date:** [July 26, 2024, 6:41am UTC](https://mne.discourse.group/t/changing-eeg-locations-format-from-using-montages/9122/2 "2024-07-26T06:41:48Z")

</div>

Hello,

First of all, this line `raweeg['info']['channels'][0]['locations'][0]` is not valid and will raise.  
Next, I believe you are looking at the same electrode position, in 2 different coordinate frames. If I look at the montage on the `sample` dataset, on the `raw` object and thus in the `head` coordinate frame, I get:

```python
from mne.datasets import sample
from mne.io import read_raw_fif

raw = read_raw_fif(
    sample.data_path() / "MEG" / "sample" / "sample_audvis_raw.fif", preload=False
)
raw.pick("eeg").load_data()
raw.get_montage()._get_ch_pos()["EEG 001"]
# array([-0.03737009, 0.10568011, 0.07333875])
raw.info["chs"][0]["loc"][:3]
# array([-0.03737009, 0.10568011, 0.07333875])

```

Mathieu

---

<div class="post-metadata">

**Author:** ![codZeus](https://avatars.discourse-cdn.com/v4/letter/c/f1d935/32.png) [@codZeus](https://mne.discourse.group/u/codZeus)\
**Post date:** [July 26, 2024, 7:04am UTC](https://mne.discourse.group/t/changing-eeg-locations-format-from-using-montages/9122/3 "2024-07-26T07:04:44Z")

</div>

HI,

That line is valid and does not raise an error. I believe there are different ways in reading the EEG data especially if the format you are using doesn’t require using read\_raw\_fif. I use xdf format.

What I am looking for is the electrode coordinate for the 10-20 montage system when I use

```python
mne.channels.make_standard_montage('standard_1020')

```

in this format

```python
{'X': ['-27.0'], 'Y': ['86.0'], 'Z': ['36.0']}

```

what i get is

```python
'Fp1' = array([-0.0294367, 0.0839171, -0.00699])

```

in 3D coordinate. So I want to know if those are actual 3d coordinates

---

<div class="post-metadata">

**Author:** ![mscheltienne](https://yyz2.discourse-cdn.com/free1/user_avatar/mne.discourse.group/mscheltienne/32/827_2.png) [@mscheltienne](https://mne.discourse.group/u/mscheltienne)\
**Post date:** [July 26, 2024, 8:21am UTC](https://mne.discourse.group/t/changing-eeg-locations-format-from-using-montages/9122/4 "2024-07-26T08:21:04Z")

</div>

All MNE reader functions load a `Raw` object, in which case the line you describe is not valid. However, reading an XDF file (with `pyxdf`, not with `mne`), you get a different data structure that should be (1) parsed and (2) provided to `mne.create_info` and `mne.io.RawArray` to create a `Raw` object for MNE.

Next, `mne.channels.make_standard_montage('standard_1020')` creates an ideal **template** 10/20 montage. There is no reason for this template to match the locations found in the XDF file, which can be either from (1) the same or a different template or (2) from an actual digitization measurement device (thus giving true electrode locations).

Next, there is no guarantee the locations in the XDF file are in the head coordinate frame. As a matter of fact, `mne.channels.make_standard_montage('standard_1020')` does not create a montage in the head coordinate frame either.

```python
from mne.channels import make_standard_montage

montage = make_standard_montage("standard_1020")
montage.dig

```

This code snippet outputs the lit of digitization points:

```python
<DigPoint | LPA : (-80.6, -29.1, -41.3) mm : MRI (surface RAS) frame>,
 <DigPoint | Nasion : (1.5, 85.1, -34.8) mm : MRI (surface RAS) frame>,
 <DigPoint | RPA : (84.4, -28.5, -41.3) mm : MRI (surface RAS) frame>,
 <DigPoint | EEG #1 : (-29.4, 83.9, -7.0) mm : MRI (surface RAS) frame>,
 <DigPoint | EEG #2 : (0.1, 88.2, -1.7) mm : MRI (surface RAS) frame>,
 <DigPoint | EEG #3 : (29.9, 84.9, -7.1) mm : MRI (surface RAS) frame>,
...

```

Which are in the MRI coordinate frame. Let’s now apply this montage to a `Raw` object:

```python
import numpy as np
from mne import create_info
from mne.channels import make_standard_montage
from mne.io import RawArray

montage = make_standard_montage("standard_1020")
info = create_info(montage.ch_names, sfreq=1000., ch_types="eeg")
raw = RawArray(np.zeros((len(montage.ch_names), 1000)), info)
raw.set_montage(montage)
raw.get_montage().dig

```

Again, we look at the list of digitization points:

```python
<DigPoint | LPA : (-82.5, -0.0, 0.0) mm : head frame>,
 <DigPoint | Nasion : (0.0, 114.0, 0.0) mm : head frame>,
 <DigPoint | RPA : (82.5, 0.0, -0.0) mm : head frame>,
 <DigPoint | EEG #1 : (-30.9, 114.6, 27.9) mm : head frame>,
 <DigPoint | EEG #2 : (-1.3, 119.1, 32.9) mm : head frame>,
 <DigPoint | EEG #3 : (28.4, 115.3, 27.7) mm : head frame>,
...

```

Now, the montage is in the head coordinate frame. Note that the X, Y, Z coordinate have ‘changed’, but in reality what changed is the position of the origin and the orientation of the X/Y/Z axis, i.e. the coordinate frame.  
See also this tutorial about the coordinate frames: [Source alignment and coordinate frames — MNE 1.7.1 documentation](https://mne.tools/stable/auto_tutorials/forward/20_source_alignment.html)

I hope that answer your question, good luck!

Mathieu

---

<div class="post-metadata">

**Author:** ![codZeus](https://avatars.discourse-cdn.com/v4/letter/c/f1d935/32.png) [@codZeus](https://mne.discourse.group/u/codZeus)\
**Post date:** [July 26, 2024, 3:31pm UTC](https://mne.discourse.group/t/changing-eeg-locations-format-from-using-montages/9122/5 "2024-07-26T15:31:35Z")

</div>

Hi, thanks for your response.

You are right in your first paragraph.

Secondly, I did not say the locations in the template `mne.channels.make_standard_montage('standard_1020')` will match that of the xdf file electrode locations.

Well if you use

```python
from mne.channels import make_standard_montage

montage = make_standard_montage("standard_1020")
montage._get_ch_pos()
>>>> array([-0.0294367, 0.0839171, -0.00699])

```

you will get positions in an numpy object.

Also, when you apply the montage to the mne object, it changes. That’s also true.

1. My question is it possible to get the location of the template montage in this format (angles)  
`{'X': ['-27.0'], 'Y': ['86.0'], 'Z': ['36.0']}` which is the output of the measurement device in one of the xdf file rather than this `array([-0.0294367, 0.0839171, -0.00699])` format.  
I am trying to convert the 3d coordinate into 2d.

2. I also asked if `array([-0.0294367, 0.0839171, -0.00699])` were normalized, i want to know if these are the actual coordinate values or they have been transformed.

That is all I am asking.

---

<div class="post-metadata">

**Author:** ![mscheltienne](https://yyz2.discourse-cdn.com/free1/user_avatar/mne.discourse.group/mscheltienne/32/827_2.png) [@mscheltienne](https://mne.discourse.group/u/mscheltienne)\
**Post date:** [July 26, 2024, 3:59pm UTC](https://mne.discourse.group/t/changing-eeg-locations-format-from-using-montages/9122/6 "2024-07-26T15:59:50Z")

</div>

> My question is it possible to get the location of the template montage in this format (angles)  
> `{'X': ['-27.0'], 'Y': ['86.0'], 'Z': ['36.0']}` which is the output of the measurement device in one of the xdf file rather than this `array([-0.0294367, 0.0839171, -0.00699])` format.  
> I am trying to convert the 3d coordinate into 2d.

You example is still 3D? What do you mean by ‘this format (angles)’?

> also asked if `array([-0.0294367, 0.0839171, -0.00699])` were normalized

There is no normalization, it’s just a matter of coordinate frame and units. Those values are expressed in meters, and the coordinate frame depends (MRI if you get the montage from `make_standard_montage`, head if you get the montage from a `raw` object).  
In any case, the value you get from `montage.dig` (or `_get_ch_pos`) are just the X/Y/Z coordinate of each point in the current montage coordinate frame, expressed in meters.

Mathieu

---

<div class="post-metadata">

**Author:** ![codZeus](https://avatars.discourse-cdn.com/v4/letter/c/f1d935/32.png) [@codZeus](https://mne.discourse.group/u/codZeus)\
**Post date:** [July 26, 2024, 4:28pm UTC](https://mne.discourse.group/t/changing-eeg-locations-format-from-using-montages/9122/7 "2024-07-26T16:28:48Z")

</div>

> You example is still 3D? What do you mean by ‘this format (angles)’?

Yeah, the output is in 3D. If i use the `make_standard_montage` i get the output in 3D. I want to know what the output is expressed in before I can change it to 2D.  
Also when i read the xdf file from the measurement device, I get my output in 3D but they look like this  
`{'X': ['-27.0'], 'Y': ['86.0'], 'Z': ['36.0']}` so supposedly I am thinking the output is in degrees. Sorry I said angles, I meant degrees.

> it’s just a matter of coordinate frame and units. Those values are expressed in meters, and the coordinate frame depends (MRI if you get the montage from `make_standard_montage` , head if you get the montage from a `raw` object).

Okay thank you.

1. So is it possible to get the actual coordinates in degrees or what I am asking for does not make sense?

Also, what is your take on this [eeglocations](https://stefanappelhoff.com/eeg_positions/auto_examples/plot_positions.html#sphx-glr-auto-examples-plot-positions-py)

---

<div class="post-metadata">

**Author:** ![mscheltienne](https://yyz2.discourse-cdn.com/free1/user_avatar/mne.discourse.group/mscheltienne/32/827_2.png) [@mscheltienne](https://mne.discourse.group/u/mscheltienne)\
**Post date:** [July 27, 2024, 8:59am UTC](https://mne.discourse.group/t/changing-eeg-locations-format-from-using-montages/9122/8 "2024-07-27T08:59:27Z")

</div>

You either have cartesian coordinates, or spherical coordinates. X, Y, Z is cartesian coordinates, thus `{'X': ['-27.0'], 'Y': ['86.0'], 'Z': ['36.0']}` likely represents the X, Y, Z coordinates of your sensor… but maybe in milimeters? I think it’s just a matter of units.

Mathieu

---

<div class="post-metadata">

**Author:** ![codZeus](https://avatars.discourse-cdn.com/v4/letter/c/f1d935/32.png) [@codZeus](https://mne.discourse.group/u/codZeus)\
**Post date:** [July 27, 2024, 3:36pm UTC](https://mne.discourse.group/t/changing-eeg-locations-format-from-using-montages/9122/9 "2024-07-27T15:36:31Z")

</div>

Thank you so much. makes sense
