Skip to content

Commit d2278f6

Browse files
[circle skip] [skip azp]
1 parent 346d5a1 commit d2278f6

2 files changed

Lines changed: 41 additions & 0 deletions

File tree

mne/io/egi/events.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,9 @@ def _read_mff_events(filename, sfreq, start_time):
6969
for track in tracks:
7070
for event in track.events:
7171
code_str = event["code"]
72+
cel = event.get("keys", {}).get("cel#")
73+
if cel is not None:
74+
code_str = f"{code_str}_{int(cel)}"
7275
if code_str not in code:
7376
code.append(code_str)
7477

mne/io/egi/tests/test_egi.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
from mne.datasets.testing import data_path, requires_testing_data
1919
from mne.io import read_evokeds_mff, read_raw_egi, read_raw_fif
2020
from mne.io.egi.egi import _combine_triggers
21+
from mne.io.egi.events import _read_mff_events
2122
from mne.io.tests.test_raw import _test_raw_reader
2223
from mne.utils import copytree_rw, object_diff
2324

@@ -598,3 +599,40 @@ def test_egi_mff_bad_xml(tmp_path):
598599
raw = read_raw_egi(mff_fname)
599600
# little check that the bad XML doesn't affect the parsing of other xml files
600601
assert "DIN1" in raw.annotations.description
602+
603+
604+
@requires_testing_data
605+
def test_egi_mff_cel_condition_codes():
606+
"""Test that cel# compound codes are only generated for repeated trial events.
607+
608+
EGI records a ``cel#`` key on each event to identify the experimental
609+
condition. When a code appears multiple times per condition (e.g. ``stm+``
610+
firing on every trial) ``read_raw_egi`` should append the cel# value and
611+
produce codes like ``stm+_1`` / ``stm+_2``.
612+
613+
However, some files use a once-per-condition-block ``CELL`` marker where
614+
each cel# value (1–5) fires exactly once. Splitting those into separate
615+
channels would create consecutive-sample trigger values that confuse
616+
``find_events`` and prevent ``STI 014`` from being synthesised. The reader
617+
must leave such codes unsplit.
618+
"""
619+
import mffpy
620+
621+
for fname in (egi_pause_fname, egi_eprime_pause_fname):
622+
r = mffpy.Reader(str(fname))
623+
_, codes = _read_mff_events(str(fname), 250.0, r.startdatetime)
624+
assert "CELL" in codes, f"CELL missing in {fname.name}"
625+
assert not any(c.startswith("CELL_") for c in codes), (
626+
f"CELL should not be split into per-condition channels in "
627+
f"{fname.name}; got {codes}"
628+
)
629+
630+
# Also verify end-to-end: STI 014 must be synthesised and CELL must appear
631+
# in raw.event_id (not split) when reading the full file.
632+
for fname in (egi_pause_fname, egi_eprime_pause_fname):
633+
raw = read_raw_egi(fname, events_as_annotations=False)
634+
assert "CELL" in raw.event_id, f"CELL missing from event_id in {fname.name}"
635+
assert not any(k.startswith("CELL_") for k in raw.event_id), (
636+
f"CELL should not be split in {fname.name}; got {list(raw.event_id)}"
637+
)
638+
assert "STI 014" in raw.ch_names, f"STI 014 not synthesised in {fname.name}"

0 commit comments

Comments
 (0)