Skip to content

Commit 55b013c

Browse files
committed
FIX: handle empty first Eyelink recording block
1 parent 5ce7c8d commit 55b013c

File tree

5 files changed

+34
-2
lines changed

5 files changed

+34
-2
lines changed

doc/changes/dev/13555.bugfix.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix bug where :func:`mne.io.read_raw_eyelink` raised an error when reading Eyelink files with an empty first recording block, by :newcontrib:`Varun Kasyap` (:gh:`13555`).

doc/changes/names.inc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,7 @@
336336
.. _Tziona NessAiver: https://github.com/TzionaN
337337
.. _user27182: https://github.com/user27182
338338
.. _Valerii Chirkov: https://github.com/vagechirkov
339+
.. _Varun Kasyap Pentamaraju: https://github.com/varunkasyap
339340
.. _Velu Prabhakar Kumaravel: https://github.com/vpKumaravel
340341
.. _Victor Ferat: https://github.com/vferat
341342
.. _Victoria Peterson: https://github.com/vpeterson

mne/io/eyelink/_utils.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,14 @@ def _parse_eyelink_ascii(
9090
raw_extras["dfs"][key], max_time=overlap_threshold
9191
)
9292
# ======================== Info for BaseRaw ========================
93-
eye_ch_data = raw_extras["dfs"]["samples"][ch_names].to_numpy().T
93+
dfs = raw_extras["dfs"]
94+
95+
if "samples" not in dfs or dfs["samples"].empty:
96+
logger.info("No sample data found, creating empty Raw object.")
97+
eye_ch_data = np.empty((len(ch_names), 0))
98+
else:
99+
eye_ch_data = dfs["samples"][ch_names].to_numpy().T
100+
94101
info = _create_info(ch_names, raw_extras)
95102

96103
return eye_ch_data, info, raw_extras

mne/io/eyelink/eyelink.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,9 @@ def __init__(
123123
eye_annots = _make_eyelink_annots(
124124
self._raw_extras[0]["dfs"], create_annotations, apply_offsets
125125
)
126-
if gap_annots and eye_annots: # set both
126+
if self.n_times == 0:
127+
logger.info("No samples found in recording, skipping annotation creation.")
128+
elif gap_annots and eye_annots: # set both
127129
self.set_annotations(gap_annots + eye_annots)
128130
elif gap_annots:
129131
self.set_annotations(gap_annots)

mne/io/eyelink/tests/test_eyelink.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -523,3 +523,24 @@ def test_href_eye_events(tmp_path):
523523
# Just check that we actually parsed the Saccade and Fixation events
524524
assert "saccade" in raw.annotations.description
525525
assert "fixation" in raw.annotations.description
526+
527+
528+
@requires_testing_data
529+
def test_empty_first_trial(tmp_path):
530+
"""Test reading a file with an empty first trial."""
531+
out_file = tmp_path / "tmp_eyelink.asc"
532+
# Use a real eyelink file as base
533+
lines = fname.read_text("utf-8").splitlines()
534+
# Find first START and END
535+
end_idx = next(i for i, line in enumerate(lines) if line.startswith("END"))
536+
# Keep headers + START..END but REMOVE all numeric sample lines
537+
first_block = []
538+
for line in lines[: end_idx + 1]:
539+
tokens = line.split()
540+
if line.startswith("START") or not tokens or not tokens[0].isdigit():
541+
first_block.append(line)
542+
543+
# Append rest of file (second trial onwards)
544+
rest = lines[end_idx + 1 :]
545+
out_file.write_text("\n".join(first_block + rest), encoding="utf-8")
546+
read_raw_eyelink(out_file)

0 commit comments

Comments
 (0)