From 121eebc0d96031b85fdd1d00b3aeac98d8a6b1c8 Mon Sep 17 00:00:00 2001 From: John Griffiths Date: Mon, 1 Dec 2025 19:40:11 -0500 Subject: [PATCH 1/2] add pyxid2 device type for nirx nirspot2 triggers --- eegnb/devices/eeg.py | 48 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 44 insertions(+), 4 deletions(-) diff --git a/eegnb/devices/eeg.py b/eegnb/devices/eeg.py index f1581f66..ba85f2e2 100644 --- a/eegnb/devices/eeg.py +++ b/eegnb/devices/eeg.py @@ -20,6 +20,8 @@ from serial import Serial, EIGHTBITS, PARITY_NONE, STOPBITS_ONE +import pyxid2 + from eegnb.devices.utils import ( get_openbci_usb, create_stim_array, @@ -57,7 +59,9 @@ "muse2016_bfb", ] - +xid_devices = [ + "nirsport2" +] class EEG: device_name: str @@ -68,6 +72,7 @@ def __init__( device=None, serial_port=None, serial_num=None, + xid_num=None, mac_addr=None, other=None, ip_addr=None, @@ -88,6 +93,7 @@ def __init__( self.serial_num = serial_num self.serial_port = serial_port self.mac_address = mac_addr + self.xid_num = xid_num self.ip_addr = ip_addr self.other = other self.config = config @@ -112,7 +118,8 @@ def initialize_backend(self): self._init_kf() elif self.backend == "serialport": self._init_serial() - + elif self.backend == "xidport": + self._init_xid() def _get_backend(self, device_name): if device_name in brainflow_devices: @@ -123,6 +130,8 @@ def _get_backend(self, device_name): return "kernelflow" elif device_name in ["biosemi"]: return "serialport" + elif device_name in ["nirsport2"]: + return "xidport" ##################### @@ -606,6 +615,33 @@ def _serial_open_port(self,PORT_ID="COM4", BAUD=115200): + ################################ + # Cedrus XID port functions # + ################################ + + + def _init_xid(self): + if self.xid_num is not None: # if an xis device number is supplied, open and init that device + xids_list = pyxid2.get_xid_devices() + xid = xids_list[self.xid_num] + xid.init_device() + # (otherwise, don't open; assuming an xid attribute will be + # manually added later) + + xid.set_pulse_duration(1000) # [ is this needed / optimal in all cases ? ] + + print("\nOpened XID Device #%s:\n%s" %(self.xid_num, xid)) + + self.xid = xid + + + def _xid_push_sample(self, marker): + + if not (0 <= marker <= 255): raise ValueError("marker code must be 045255") + self.xid.activate_line(lines=[marker]) + + + ################################# # Highlevel device functions # @@ -628,7 +664,10 @@ def start(self, fn, duration=None): elif self.backend == "kernelflow": self._start_kf() elif self.backend == "serialport": - pass + pass + elif self.backend == "xidport": + pass + def push_sample(self, marker, timestamp, marker_name=None): @@ -647,7 +686,8 @@ def push_sample(self, marker, timestamp, marker_name=None): self._kf_push_sample(marker=marker,timestamp=timestamp, marker_name=marker_name) elif self.backend == "serialport": self._serial_push_sample(marker=marker) - + elif self.backend == "xidport": + self._xid_push_sample(marker=marker) def stop(self): if self.backend == "brainflow": From 865238b86a2ce753a9b575b8ad88ba997ed90e4c Mon Sep 17 00:00:00 2001 From: John Griffiths Date: Mon, 1 Dec 2025 19:40:46 -0500 Subject: [PATCH 2/2] added pyxid2 device functionality --- eegnb/devices/utils.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/eegnb/devices/utils.py b/eegnb/devices/utils.py index 38579196..c804befd 100644 --- a/eegnb/devices/utils.py +++ b/eegnb/devices/utils.py @@ -29,6 +29,7 @@ "freeeeg32": [f"eeg_{i}" for i in range(0, 32)], "kernelflow": [], "biosemi": [], + "nirsport2": [], } BRAINFLOW_CHANNELS = { @@ -60,6 +61,7 @@ "freeeeg32": BoardShim.get_eeg_channels(BoardIds.FREEEEG32_BOARD.value), "kernelflow": [], "biosemi": [], + "nirsport2": [], } SAMPLE_FREQS = { @@ -84,6 +86,7 @@ "freeeeg32": BoardShim.get_sampling_rate(BoardIds.FREEEEG32_BOARD.value), "kernelflow": [], "biosemi": [], + "nirsport2": [], }