Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Question about sensor types #128

Open
scott-huberty opened this issue Aug 15, 2024 · 4 comments
Open

Question about sensor types #128

scott-huberty opened this issue Aug 15, 2024 · 4 comments

Comments

@scott-huberty
Copy link

scott-huberty commented Aug 15, 2024

I'm looking at how easy it will be to load EGI/BEL files into Python using mffpy and porting the in-memory object to MNE, so we can eventually just directly depend on mffpy in MNE.

I am trying to figure out the best way to discern the channel type of the sensors in a file, I am hoping that some of the devs here can take some time to provide guidance:

Question 1: Where is the best place in an .mff file to find information on the channel type for each sensor?

Right now I am doing:

from pathlib import Path

import mffpy
import mne

fname = mne.datasets.testing.data_path() / "EGI" / "test_egi.mff"

mffpy.XML.from_file(fname / "sensorlayout.xml").get_content()["sensors"]

And I get something like this:

{1: {'name': 'None',
  'number': 1,
  'type': 0,
  'x': 162.908,
  'y': -158.388,
  'z': 0.0},
...
 129: {'name': 'VREF',
  'number': 129,
  'type': 1,
  'x': 0.0,
  'y': 0.0,
  'z': 0.0,
  'identifier': 1001},
...
 134: {'name': 'None',
  'number': 134,
  'type': 2,
  'x': -175.0,
  'y': 243.0,
  'z': 0.0,
  'identifier': 2505},
...
 135: {'name': 'COM',
  'number': 135,
  'type': 2,
  'x': 0.0,
  'y': 66.0,
  'z': 0.0,
  'identifier': 2506}}

Question 2: assuming this 'type' key is the right place to look, where can I find the code-to-description mapping?

Looking at the 'type' key in these dicts, I am guessing they specify the type of channel (EEG, EOG, PNS, etc) - and I am guessing that

  • 0 = "EEG"
  • 1 = Reference (but still an "EEG" channel?)
  • 2 = Reference (but again, still an "EEG" type channel?)

Is this right, and is this actually the best place to look for channel type information?

Thank you in advance 🙏

@scott-huberty
Copy link
Author

Gentle ping 🙂

Maybe @damian5710 knows?

@damian5710
Copy link
Collaborator

Hi @scott-huberty ! Thanks for using mffpy.

To answer your questions, let me point out that the sensorLayout.xml file (as well as the coordinates.xml file) provides information about EEG sensors for the particular sensor net used to create the mff (e.g., Geodesic Sensor Net 256 2.1).

In general, the MFF stores signal data in binary files (e.g., signal1.bin, signal2.bin etc.) and an XML file is provided for each of them (e.g., info1.xml, info2.xml etc.), which specifies the type of data in the signal file and some additional information. See for example example_3.mff .

Typical implementations use signal1.bin/info1.xml for EEG and signal2.bin/info2.xml for PNS data, although this is not a requirement and the infoN files should be consulted for the actual data type when reading files. You can use the following code to do that:

from mffpy import Reader
from mffpy.xml_files import XML

mff_reader = Reader('path/to/some.mff')

with mff_reader.directory.filepointer('info1') as fp:
    info = XML.from_file(fp)

print(info.generalInformation['channel_type'])

I hope this helps answer your questions.

@scott-huberty
Copy link
Author

Hey Thanks @damian5710 ! I'll give this a try.

@scott-huberty
Copy link
Author

Hi again @damian5710 .

One more question... Per my first message in this thread... What are the units of the x, y, and z cartesian coordinates for each sensor location? mm? cm?

e.g.

from pathlib import Path

import mffpy
import mne

fname = mne.datasets.testing.data_path() / "EGI" / "test_egi.mff"

mffpy.XML.from_file(fname / "sensorlayout.xml").get_content()["sensors"]
{1: {'name': 'None',
  'number': 1,
  'type': 0,
  'x': 162.908,
  'y': -158.388,
  'z': 0.0},
...
 129: {'name': 'VREF',
  'number': 129,
  'type': 1,
  'x': 0.0,
  'y': 0.0,
  'z': 0.0,
  'identifier': 1001},
...
 134: {'name': 'None',
  'number': 134,
  'type': 2,
  'x': -175.0,
  'y': 243.0,
  'z': 0.0,
  'identifier': 2505},
...
 135: {'name': 'COM',
  'number': 135,
  'type': 2,
  'x': 0.0,
  'y': 66.0,
  'z': 0.0,
  'identifier': 2506}}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants