Skip to content

Commit

Permalink
ENH: Add option to get HREF data to read_mne_eyetracking_raw
Browse files Browse the repository at this point in the history
- if you pass "eyetrack_unit='href', a copy of the eyetracking file with units converted to HREF radians will be downloaded and synced with the raw EEG
  • Loading branch information
scott-huberty committed Feb 26, 2024
1 parent 9ec9c23 commit 570f0d5
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 14 deletions.
6 changes: 1 addition & 5 deletions eoglearn/datasets/eegeyenet.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import mne
from .utils import _fetch_dataset

PARAMS = {
"EP10_DOTS": list(
Expand All @@ -17,10 +17,6 @@
DOTS = {"EP10": PARAMS["EP10_DOTS"]}


def _fetch_dataset(fetch_dataset_kwargs):
return mne.datasets.fetch_dataset(**fetch_dataset_kwargs)


def fetch_eegeyenet(subject="EP10", run=0, fetch_dataset_kwargs=None):
"""Fetch a sample file from the EEG Eyenet dataset.
Expand Down
33 changes: 30 additions & 3 deletions eoglearn/datasets/mne.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,24 @@
import mne
from mne.utils import logger

from .utils import _fetch_dataset

def read_mne_eyetracking_raw(return_events=False, bandpass=True):

def read_mne_eyetracking_raw(return_events=False, bandpass=True, eyetrack_unit="px"):
"""Return an MNE Raw object containing the EyeLink dataset.
Parameters
----------
return_events : bool
If ``True``, return the events for the eyetracking and EEG data.
bandpass: bool
If ``True``, applied a [1, 30]Hz bandpass.
If ``True``, apply a [1, 30]Hz bandpass to the EEG data.
eyetrack_unit : str
The desired unit of the eyetracking data. Must be "px" or "href", corresponding
to pixels-on-screen or head-referenced-eye-angle, respectively. Note that
HREF data are reported in radians. If HREF data are requested, a separate data
file will be downloaded from OSF, to ``~/mne_data/eog-learn-example-data``.
Defaults to "px".
Returns
-------
Expand All @@ -33,11 +41,30 @@ def read_mne_eyetracking_raw(return_events=False, bandpass=True):
90_eyetracking_data.html>`_
for more information on this dataset.
"""
if eyetrack_unit not in ["px", "href"]:
raise ValueError("eyetrack_unit must be 'px' or 'href'")

data_path = mne.datasets.eyelink.data_path()
if mne.utils.check_version("mne", "1.6"):
data_path = data_path / "eeg-et"
et_fpath = data_path / "sub-01_task-plr_eyetrack.asc"

eeg_fpath = data_path / "sub-01_task-plr_eeg.mff"
# now get the eyetracking data
if eyetrack_unit == "px":
et_fpath = data_path / "sub-01_task-plr_eyetrack.asc"
elif eyetrack_unit == "href":
# the HREF file is not used by MNE and so we store it separately on OSF...
ds_params = dict(
dataset_params=dict(
url="https://osf.io/829m4/download?version=1",
archive_name="sub-01_task-plr-href_eyetrack.asc",
folder_name="eog-learn-example-data",
hash="sha256:e595e92efc63f608c0214caf4cee69a5b7ae2d08959503a3eef641931fcce32a",
dataset_name="PLR_HREF",
)
)
et_fpath = _fetch_dataset(ds_params)
et_fpath = et_fpath / "sub-01_task-plr-href_eyetrack.asc"

logger.debug(f"## EOGLEARN: Reading data from {et_fpath} and {eeg_fpath}")
raw_et = mne.io.read_raw_eyelink(et_fpath, create_annotations=["blinks"])
Expand Down
15 changes: 9 additions & 6 deletions eoglearn/datasets/tests/test_datasets.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
from eoglearn.datasets import fetch_eegeyenet
import pytest

from eoglearn.datasets import fetch_eegeyenet, read_mne_eyetracking_raw

def test_read_mne_eyetracking_raw(mne_fixture):

@pytest.mark.parametrize("unit", ["px", "href"])
def test_read_mne_eyetracking_raw(unit):
"""Test the read_mne_eyetracking_raw function."""
ch_types = mne_fixture.raw.get_channel_types()
raw, events = read_mne_eyetracking_raw(eyetrack_unit=unit, return_events=True)
ch_types = raw.get_channel_types()
assert ch_types.count("eyegaze") == 2
assert ch_types.count("pupil") == 1
assert ch_types.count("misc") == 3
assert ch_types.count("eeg") == 129
events_dict = mne_fixture.events_dict
assert len(events_dict["eeg"][:, -1]) == 16
assert len(events_dict["eyetrack"][:, -1]) == 16
assert len(events["eeg"][:, -1]) == 16
assert len(events["eyetrack"][:, -1]) == 16


def test_fetch_eegeyenet():
Expand Down
5 changes: 5 additions & 0 deletions eoglearn/datasets/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import mne


def _fetch_dataset(fetch_dataset_kwargs):
return mne.datasets.fetch_dataset(**fetch_dataset_kwargs)
6 changes: 6 additions & 0 deletions examples/plot_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@
# %%
raw

# %%
# .. note::
# If you want eye tracking data in head-referenced-eye-angle (HREF) units, you can
# pass ``eyetrack_unit="href"`` to
# :func:`~eoglearn.datasets.read_mne_eyetracking_raw`.

# %%
# Plot the data
raw.plot()
Expand Down

0 comments on commit 570f0d5

Please sign in to comment.