Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions doc/source/authors.rst
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ and may not be the current affiliation of a contributor.
* Aditya Singh (github)
* Stanley C.
* Axel Coiffard-Donaty
* Aaron Kanzer [53]

1. Centre de Recherche en Neuroscience de Lyon, CNRS UMR5292 - INSERM U1028 - Université Claude Bernard Lyon 1
2. Unité de Neuroscience, Information et Complexité, CNRS UPR 3293, Gif-sur-Yvette, France
Expand Down Expand Up @@ -159,6 +160,7 @@ and may not be the current affiliation of a contributor.
50. Ludwig-Maximilians-Universität München, Munich, Germany
51. Stony Brook University, Stony Brook, NY, USA
52. University of Sussex, Brighton, UK
53. Scigantic, USA



Expand Down
5 changes: 4 additions & 1 deletion neo/rawio/brainvisionrawio.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,10 @@ def _parse_header(self):
for i in range(len(all_info)):
ev_type, ev_label, pos, size, channel = all_info[f"Mk{i+1}"].split(",")[:5]
ev_types.append(ev_type)
ev_timestamps.append(int(pos))
# Marker positions are 1-based (the first data point is position 1), see
# section 4.3 of the BrainVision Core Data Format 1.0 specification:
# https://www.brainproducts.com/download/specification-of-brainvision-core-data-format-1-0/
ev_timestamps.append(int(pos) - 1)
ev_labels.append(ev_label)
ev_types = np.array(ev_types)
ev_timestamps = np.array(ev_timestamps)
Expand Down
49 changes: 49 additions & 0 deletions neo/test/rawiotest/test_brainvisionrawio.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
""" """

import tempfile
import unittest
from pathlib import Path

import numpy as np

from neo.rawio.brainvisionrawio import BrainVisionRawIO

Expand All @@ -24,5 +28,50 @@ class TestBrainVisionRawIO(
entities_to_download = ["brainvision"]


class TestBrainVisionRawIOMarkers(unittest.TestCase):
def test_marker_positions_are_one_based(self):
vhdr = (
"Brain Vision Data Exchange Header File Version 1.0\n"
"[Common Infos]\n"
"Codepage=UTF-8\n"
"DataFile=test.eeg\n"
"MarkerFile=test.vmrk\n"
"DataFormat=BINARY\n"
"DataOrientation=MULTIPLEXED\n"
"NumberOfChannels=1\n"
"SamplingInterval=1000\n"
"[Binary Infos]\n"
"BinaryFormat=INT_16\n"
"[Channel Infos]\n"
"Ch1=Fp1,,1,µV\n"
)
vmrk = (
"Brain Vision Data Exchange Marker File, Version 1.0\n"
"[Marker Infos]\n"
"Mk1=New Segment,,1,1,0\n"
"Mk2=Stimulus,S 1,11,1,0\n"
)
with tempfile.TemporaryDirectory() as tmp_dir:
tmp_dir = Path(tmp_dir)
(tmp_dir / "test.vhdr").write_text(vhdr, encoding="utf8")
(tmp_dir / "test.vmrk").write_text(vmrk, encoding="utf8")
np.arange(20, dtype="int16").tofile(tmp_dir / "test.eeg")

reader = BrainVisionRawIO(filename=tmp_dir / "test.vhdr")
reader.parse_header()
event_names = list(reader.header["event_channels"]["name"])

# position 1 is the first data point, so it is sample 0 and time 0 s
timestamps, _, _ = reader.get_event_timestamps(event_channel_index=event_names.index("New Segment"))
np.testing.assert_array_equal(timestamps, [0])

# position 11 is sample 10, 10 ms into the recording at 1 kHz
timestamps, _, labels = reader.get_event_timestamps(event_channel_index=event_names.index("Stimulus"))
np.testing.assert_array_equal(timestamps, [10])
np.testing.assert_array_equal(labels, ["S 1"])
times = reader.rescale_event_timestamp(timestamps, event_channel_index=event_names.index("Stimulus"))
np.testing.assert_allclose(times, [0.010])


if __name__ == "__main__":
unittest.main()