Skip to content

Reading 3D coordinates from snirf produces different result than read_custom_montage() #545

@kdarti

Description

@kdarti

Describe the bug

I'm not completely sure that this is a bug, and I'm not sure it's even expected that you'd get the same results when automatically reading coordinates from a snirf file as when reading the same coordinates using read_custom_montage().

Steps to reproduce

20240327-snirf3d-mne.zip

import mne
mne.io.read_raw_snirf(r"2x12_nz-to-nasion.snirf").get_montage().plot()
mne.channels.read_custom_montage(r"digitisation_2x12.elc").plot()
mne.io.read_raw_snirf(r"2x12_nz-to-nasion.snirf").get_montage().get_positions()
mne.channels.read_custom_montage(r"digitisation_2x12.elc").get_positions()

Expected results

I'd expect the resulting coordinates to be the same, given the coordinates in the .snirf and the .elc files are identical.

The difference seems to lie here:

https://github.com/mne-tools/mne-python/blob/eee8e6fe580034f4a3a4fb13bdca3bfc99240708/mne/channels/_standard_montage_utils.py#L274

If I comment out that line I get identical results.

Actual results

image
image

I should say that the digitisation is bad and not realistic, but the result that I expect is what I get from read_custom_montage()

mne.io.read_raw_snirf(r"2x12_nz-to-nasion.snirf").get_montage().get_positions()
Loading ...\2x12_nz-to-nasion.snirf
Out[221]: 
{'ch_pos': OrderedDict([('S1', array([0.05263, 0.04361, 0.10604])),
              ('S2', array([-0.0598 ,  0.03692,  0.10477])),
              ('S3', array([-0.00454,  0.09951,  0.07741])),
              ('S4', array([0.05279, 0.11416, 0.00981])),
              ('S5', array([-0.06111,  0.11034,  0.00243])),
              ('S6', array([ 0.06122, -0.1047 ,  0.0347 ])),
              ('S7', array([-0.0399 , -0.10976,  0.04771])),
              ('S8', array([ 0.01618, -0.07903,  0.09699])),
              ('S9', array([ 0.07706, -0.03319,  0.09421])),
              ('S10', array([-0.04648, -0.03294,  0.11256])),
              ('D1', array([-0.00076,  0.04186,  0.119  ])),
              ('D2', array([0.05333, 0.08289, 0.07874])),
              ('D3', array([-0.06278,  0.08358,  0.07064])),
              ('D4', array([-0.0044 ,  0.12561,  0.01085])),
              ('D5', array([ 0.01436, -0.11273,  0.05478])),
              ('D6', array([ 0.07158, -0.08069,  0.06542])),
              ('D7', array([-0.03738, -0.07695,  0.09272])),
              ('D8', array([ 0.01718, -0.03431,  0.12018]))]),
 'coord_frame': 'unknown',
 'nasion': array([-0.001,  0.084, -0.043]),
 'lpa': array([-0.0825, -0.018 , -0.048 ]),
 'rpa': array([ 0.081, -0.019, -0.048]),
 'hsp': None,
 'hpi': None}

mne.channels.read_custom_montage(r"digitisation_2x12.elc").get_positions()
Out[222]: 
{'ch_pos': OrderedDict([('D1', array([-0.00057231,  0.03152226,  0.08961177])),
              ('D2', array([0.04015963, 0.06241949, 0.05929438])),
              ('D3', array([-0.04727586,  0.06293909,  0.05319475])),
              ('D4', array([-0.00331338,  0.09458937,  0.00817049])),
              ('D5', array([ 0.01081366, -0.08489021,  0.04125154])),
              ('D6', array([ 0.05390261, -0.06076281,  0.04926388])),
              ('D7', array([-0.02814864, -0.05794644,  0.06982188])),
              ('D8', array([ 0.01293723, -0.02583681,  0.09050036])),
              ('S1', array([0.0396325 , 0.03284008, 0.07985237])),
              ('S2', array([-0.0450318 ,  0.02780224,  0.07889601])),
              ('S3', array([-0.0034188 ,  0.07493502,  0.05829283])),
              ('S4', array([0.03975299, 0.08596706, 0.00738732])),
              ('S5', array([-0.04601828,  0.08309044,  0.00182989])),
              ('S6', array([ 0.04610111, -0.0788433 ,  0.02613049])),
              ('S7', array([-0.0300463 , -0.08265368,  0.03592754])),
              ('S8', array([ 0.01218419, -0.05951276,  0.07303736])),
              ('S9', array([ 0.05802927, -0.0249934 ,  0.07094391])),
              ('S10', array([-0.0350013 , -0.02480514,  0.08476219]))]),
 'coord_frame': 'unknown',
 'nasion': array([-0.00075304,  0.06325537, -0.03238072]),
 'lpa': array([-0.06212581, -0.01355472, -0.03614592]),
 'rpa': array([ 0.06099625, -0.01430776, -0.03614592]),
 'hsp': None,
 'hpi': None}

Additional information

Platform Windows-10-10.0.19045-SP0
Python 3.12.2 | packaged by conda-forge | (main, Feb 16 2024, 20:42:31) [MSC v.1937 64 bit (AMD64)]
Executable C:\Users\kdahlslatt\Anaconda3\envs\mne\python.exe
CPU Intel64 Family 6 Model 158 Stepping 10, GenuineIntel (12 cores)
Memory 15.7 GB

Core
├☑ mne 1.6.1 (latest release)
├☑ numpy 1.26.4 (OpenBLAS 0.3.26 with 12 threads)
├☑ scipy 1.12.0
├☑ matplotlib 3.8.3 (backend=Qt5Agg)
├☑ pooch 1.8.1
└☑ jinja2 3.1.3

Numerical (optional)
├☑ sklearn 1.4.1.post1
├☑ numba 0.59.1
├☑ nibabel 5.2.1
├☑ nilearn 0.10.3
├☑ dipy 1.9.0
├☑ openmeeg 2.5.7
├☑ pandas 2.2.1
└☐ unavailable cupy

Visualization (optional)
├☑ pyvista 0.43.4 (OpenGL 4.5.0 - Build 30.0.101.1404 via Intel(R) UHD Graphics 630)
├☑ pyvistaqt 0.11.0
├☑ vtk 9.2.6
├☑ qtpy 2.4.1 (PyQt5=5.15.8)
├☑ pyqtgraph 0.13.4
├☑ mne-qt-browser 0.6.2
├☑ ipywidgets 8.1.2
├☑ trame_client 2.16.5
├☑ trame_server 2.17.2
├☑ trame_vtk 2.8.5
├☑ trame_vuetify 2.4.3
└☐ unavailable ipympl

Ecosystem (optional)
├☑ mne-nirs 0.6.0
└☐ unavailable mne-bids, mne-features, mne-connectivity, mne-icalabel, mne-bids-pipeline

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions