def prepare_LSL_streaming(): print("Starting LSL streaming") if acc: infoACC = pylsl.StreamInfo('acc', 'ACC', 3, 32, 'int32', 'ACC-empatica_e4') global outletACC outletACC = pylsl.StreamOutlet(infoACC) if bvp: infoBVP = pylsl.StreamInfo('bvp', 'BVP', 1, 64, 'float32', 'BVP-empatica_e4') global outletBVP outletBVP = pylsl.StreamOutlet(infoBVP) if gsr: infoGSR = pylsl.StreamInfo('gsr', 'GSR', 1, 4, 'float32', 'GSR-empatica_e4') global outletGSR outletGSR = pylsl.StreamOutlet(infoGSR) if tmp: infoTemp = pylsl.StreamInfo('tmp', 'Temp', 1, 4, 'float32', 'Temp-empatica_e4') global outletTemp outletTemp = pylsl.StreamOutlet(infoTemp) if ibi: infoIBI = pylsl.StreamInfo('ibi', 'IBI', 1, 4, 'float32', 'IBI-empatica_e4') global outletIBI outletIBI = pylsl.StreamOutlet(infoIBI)
def __init__(self, chan_names=['Mock'], units='microvolts', types='EEG', fs=0): self.fs = fs self.chan_names = chan_names self.mrk_chan_idx = [] if 'MRK' in chan_names: self.mrk_chan_idx.append(chan_names.index('MRK')) if 'DTRIG' in chan_names: self.mrk_chan_idx.append(chan_names.index('DTRIG')) source_id = str(hex(getnode())) # --------------------------------------------------------------------- # create eeg info and stream eeg_info= pylsl.StreamInfo(name='neuroPrax', type='EEG', channel_count=len(chan_names), nominal_srate=fs, channel_format='float32', source_id='neuroPrax_EEG_' + source_id) acq = eeg_info.desc().append_child("acquisition") acq.append_child_value('manufacturer', 'neuroConn') acq.append_child_value('model', 'neuroPrax') acq.append_child_value('precision', '24') acq.append_child_value('compensated_lag', '0') channels = eeg_info.desc().append_child("channels") for c, u, t in zip(chan_names, units, types): channels.append_child("channel") \ .append_child_value("label", c) \ .append_child_value("unit", u) \ .append_child_value("type", t) self.eeg_stream = pylsl.StreamOutlet(eeg_info, chunk_size=0, max_buffered=1) print(f'EEG StreamOutlet created with source_id ' + f'"neuroPrax_EEG_{source_id}"') # --------------------------------------------------------------------- mrk_info= pylsl.StreamInfo(name='neuroPrax_Markers', type='Markers', channel_count=1, nominal_srate=0, channel_format='string', source_id='neuroPrax_MRK_' + source_id) self.mrk_stream = pylsl.StreamOutlet(mrk_info) print(f'Marker StreamOutlet created with source_id ' + f'"neuroPrax_MRK_{source_id}"') # --------------------------------------------------------------------- self.l0 = pylsl.local_clock()
def replay_xdf(path, files, auto=True): game_info = lsl.StreamInfo("Game State", "Flags", 1, 0, 'string', "jkllkjl") game_outlet = lsl.StreamOutlet(game_info) eeg_info = lsl.StreamInfo("NeuroneStream", "EEG", 75, 5000, 'float32', "SDQWD") eeg_outlet = lsl.StreamOutlet(eeg_info) for file in files: #load a file print('Reading ', file) stream = xdf.load_xdf(path + file, verbose=False) stream_names = np.array( [item['info']['name'][0] for item in stream[0]]) game_state = list(stream_names).index('Game State') eeg_data = list(stream_names).index('NeuroneStream') game_series = stream[0][game_state]['time_series'] game_time = stream[0][game_state]['time_stamps'] eeg_series = stream[0][eeg_data]['time_series'] eeg_time = stream[0][eeg_data]['time_stamps'] eeg_time = eeg_time - game_time[0] game_time = game_time - game_time[0] game_idx = 0 eeg_idx = eeg_time[eeg_time <= 0].size - 1 end = game_time.size - 1 if not auto: print('Press "Enter" to start streaming next file.') keyboard.wait('enter') start = time.time() min = 0 now = time.time() - start while game_idx <= end: now = time.time() - start game_target = game_time[game_time <= now].size - 1 eeg_target = eeg_time[eeg_time <= now].size - 1 while game_idx <= game_target: game_outlet.push_sample(game_series[game_idx]) game_idx += 1 while eeg_idx <= eeg_target: eeg_outlet.push_sample(eeg_series[eeg_idx]) eeg_idx += 1 if now / 60 > min: print("Streamed for", min, "out of 5 minutes.") min += 1 print("Streaming complete.")
def _create_fake_eeg_stream(self): """ Method for generating dummy EEG data for the muse. Sends randomly- generated data through an LSL outlet. :return: None """ def generate_muse_data(): """Generate 4 random floats, representing channels AF7, AF8, TP9, and TP10 on the muse headset""" return [random.random() for _ in range(4)] # create fake muse info = pylsl.StreamInfo(name='Muse', type='EEG', channel_count=4, nominal_srate=256, channel_format='float32', source_id='fake muse') info.desc().append_child_value('manufacturer', 'Muse') channels = info.desc().append_child('channels') # set channel names and units for c in ['TP9-l_ear', 'FP1-l_forehead', 'FP2-r_forehead', 'TP10-r_ear']: channels.append_child("channel") \ .append_child_value("label", c) \ .append_child_value("unit", "microvolts") \ .append_child_value("type", "EEG") outlet = pylsl.StreamOutlet(info) # continuously push data to outlet when active while self._fake_muse_active: outlet.push_sample(generate_muse_data()) time.sleep(0.00390625) # 256Hz
def send_markers(stop_event, markers=[], stream_name='BCI_select'): """ function to be run in a thread to send markers via lsl :param stop_event: threading.event that can be set to stop the server :param markers: buffer of markers. will send marker if new one is appended to markers :param stream_name: name of stream to be generated :return: """ print('The lsl BCI selection thread started.') # 1. create a new stream info = pylsl.StreamInfo(name=stream_name, type='marker', channel_count=1, channel_format='int32') # 2. make an outlet outlet = pylsl.StreamOutlet(info) print('Created marker stream :', outlet) stim_sent = 0 while not stop_event.is_set(): try: if len(markers) > stim_sent: stimulus = markers[-1] print('will send stimulus ', stimulus) outlet.push_sample([np.int32(stimulus)]) stim_sent += 1 time.sleep(5) except KeyboardInterrupt: break print('lsl send shutdown complete')
def send_data(stop_event, markers=[], stream_name='BCI_data'): """ function to generated random data to send via LSL. makes it easier to send markers in parralel :param stop_event: threading.event that can be set to stop the server :param markers: buffer of markers. will send marker if new one is appended to markers :param stream_name: name of stream to be generated :return: """ print('The lsl BCI selection thread started.') # 1. create a new stream info = pylsl.StreamInfo(name=stream_name, type='data', channel_count=1, nominal_srate=100, channel_format='float32') # 2. make an outlet outlet = pylsl.StreamOutlet(info) print('Created data stream :', outlet) while not stop_event.is_set(): try: mysample = [np.float32(np.random.rand(1, 1))] outlet.push_sample(mysample) time.sleep(0.01) except KeyboardInterrupt: break print('lsl send shutdown complete')
def setup_lsl(): global channels global gaze_stuff info = pylsl.StreamInfo('Tobii', 'ET', channels, 90, 'float32', mt.address) info.desc().append_child_value("manufacturer", "Tobii") channels = info.desc().append_child("channels") cnt = 0 for s in gaze_stuff: if s[1] == 1: cnt += 1 channels.append_child("channel") \ .append_child_value("label", s[0]) \ .append_child_value("unit", "device") \ .append_child_value("type", 'ET') else: for i in range(s[1]): cnt += 1 channels.append_child("channel") \ .append_child_value("label", "%s_%d" % (s[0], i)) \ .append_child_value("unit", "device") \ .append_child_value("type", 'ET') outlet = pylsl.StreamOutlet(info) return outlet
def __init__(self): super(LslMarkerWriter, self).__init__() markers_info = pylsl.StreamInfo("BCI Stimulus Markers", "Markers", 1, 0, 'string', "bci_stim_markers") self.markers_outlet = pylsl.StreamOutlet(markers_info) self._stamp = None
def test_marker_stream(): """Create and return marker lsl outlet.""" # create info = pylsl.StreamInfo('Markers', 'Markers', 4, 0, 'string', 'mywid32') # next make an outlet outlet = pylsl.StreamOutlet(info) return outlet
def create_lsl_outlet(name, frequency, channel_format, channel_labels, channel_types, type=''): # Create StreamInfo channel_count = len(channel_labels) source_id = str(uuid.uuid4()) info = lsl.StreamInfo(name=name, type=type, channel_count=channel_count, nominal_srate=frequency, channel_format=channel_format, source_id=source_id) # Add channel labels desc = info.desc() channels_tag = desc.append_child(name='channels') for label, channel_type in zip(channel_labels, channel_types): single_channel_tag = channels_tag.append_child(name='channel') single_channel_tag.append_child_value(name='label', value=label) single_channel_tag.append_child_value(name='type', value=channel_type) # Create outlet return lsl.StreamOutlet(info)
def __init__(self, stream_name: str = "BCI_Stimulus_Markers", stream_id: str = "bci_stim_markers"): super(LslMarkerWriter, self).__init__() self.stream_name = stream_name markers_info = pylsl.StreamInfo(stream_name, "Markers", 1, 0, 'string', stream_id) self.markers_outlet = pylsl.StreamOutlet(markers_info) self._stamp = None
def _create_python_repr_lsl_outlet(self, name): """Create 1 channel python representation outlet""" stream_info = lsl.StreamInfo(name=name, type='Pupil Capture', channel_count=1, channel_format=lsl.cf_string, source_id='%s @ %s' % (name, self.g_pool.ipc_sub_url)) self._append_channel_info(stream_info, ("Python Representation", )) self._append_acquisition_info(stream_info) return lsl.StreamOutlet(stream_info)
def _create_notify_lsl_outlet(url): """Creates notification outlet""" notification_info = lsl.StreamInfo(name='Notifications', type='Pupil Capture', channel_count=2, channel_format=lsl.cf_string, source_id='Notifications @ %s' % url) _append_channel_info(notification_info, ("subject", "Python Representation")) _append_acquisition_info(notification_info) return lsl.StreamOutlet(notification_info)
def recover_info(stream: StreamInlet) -> StreamInfo: "takes a StreamInlet and casts it into a StreamInfo" info = stream.info() return pylsl.StreamInfo( name=info.name(), type=info.type(), channel_count=info.channel_count(), nominal_srate=info.nominal_srate(), channel_format=info.channel_format(), source_id=info.source_id(), )
def __init__(self, *args, **kwargs): super(MappingWidget, self).__init__(*args, **kwargs) self.move(WINDOWDIMS_MAPPING[0], WINDOWDIMS_MAPPING[1]) self.resize(WINDOWDIMS_MAPPING[2], WINDOWDIMS_MAPPING[3]) # configure lsl stream outlet_info = pylsl.StreamInfo(name='sensorimotor_mapping', type='map', channel_count=1, nominal_srate=pylsl.IRREGULAR_RATE, channel_format=pylsl.cf_string, source_id='mapping1214') self.map_stream = pylsl.StreamOutlet(outlet_info)
def on_chk_LSL_clicked(self, state): print(f"LSL clicked state: {state}") if self.chk_LSL.isChecked(): outlet_info = pylsl.StreamInfo(name='electrode_depth', type='depth', channel_count=1, nominal_srate=pylsl.IRREGULAR_RATE, channel_format=pylsl.cf_float32, source_id='depth1214') self.depth_stream = pylsl.StreamOutlet(outlet_info) else: self.depth_stream = None
def _create_primitive_lsl_outlet(self,name): """Create 5 channel primitive data outlet""" stream_info = lsl.StreamInfo( name=name, type='Pupil Capture', channel_count=5, channel_format=lsl.cf_double64, source_id='%s @ %s'%(name,self.g_pool.ipc_sub_url)) self._append_channel_info(stream_info, ("diameter", "confidence", "timestamp", "norm_pos_x","norm_pos_y")) self._append_acquisition_info(stream_info) return lsl.StreamOutlet(stream_info)
def connect_lsl_sender_predictions(): global lsl_outlet_predictions print('lsl start StreamOutlet for predictions...', end='') stream_info = lsl.StreamInfo(LSL_SENDER_PREDS_NAME, \ LSL_SENDER_PREDS_TYPE, \ LSL_SENDER_PREDS_STREAMCHANNELS, \ lsl.IRREGULAR_RATE, \ 'float32', \ LSL_SENDER_PREDS_ID) lsl_outlet_predictions = lsl.StreamOutlet(stream_info) print('[done]')
def construct_outlet_video(self): stream_info = lsl.StreamInfo( name="pupil_capture_video", type="videostream", channel_count=1, channel_format=lsl.cf_int32, source_id=self.outlet_video_uuid, ) stream_info.desc().append_child_value("pupil_lsl_relay_version", VERSION) stream_info.desc().append_child_value("video_path", self.rec_dir) return lsl.StreamOutlet(stream_info)
def construct_streaminfo(self): self.setup_channels() stream_info = lsl.StreamInfo( name="pupil_capture", type="Gaze", channel_count=len(self.channels), channel_format=lsl.cf_double64, source_id=self.outlet_uuid, ) xml_channels = stream_info.desc().append_child("channels") for chan in self.channels: chan.append_to(xml_channels) return stream_info
def init_lsl(): """ Define the stream parameters and create outlet stream. :return: outlet stream object """ info = pylsl.StreamInfo('MarkerStream', 'Markers', 1, 0, 'string', 'myuniquesourceid23443') outlet_stream = pylsl.StreamOutlet(info) print('\nOpen Lab Recorder & check for MarkerStream and EEG stream') input('Start recording and hit any key to continue') return outlet_stream
def test_eeg_stream(): """Create and return marker lsl outlet.""" # create info = pylsl.StreamInfo('Muse', 'EEG', 4, 256, 'float32', 'MuseName') info.desc().append_child_value("manufacturer", "Muse") channels = info.desc().append_child("channels") for c in ['TP9-l_ear', 'FP1-l_forehead', 'FP2-r_forehead', 'TP10-r_ear']: channels.append_child("channel") \ .append_child_value("label", c) \ .append_child_value("unit", "microvolts") \ .append_child_value("type", "EEG") outlet = pylsl.StreamOutlet(info) return outlet
def pi_streaminfo(outlet_uuid, channels): stream_info = lsl.StreamInfo( name="pupil_invisible", type="Gaze", channel_count=len(channels), channel_format=lsl.cf_double64, source_id=outlet_uuid, ) stream_info.desc().append_child_value("pupil_invisible_lsl_relay_version", VERSION) xml_channels = stream_info.desc().append_child("channels") for chan in channels: chan.append_to(xml_channels) return stream_info
def _init_lsl_outlets(self): """Call in subclass after acquiring address.""" self._info = {} self._outlets = {} for name in self._subscriptions: info = {arg: self._stream_params[arg][name] for arg in INFO_ARGS} outlet_name = '{}-{}'.format(self._device_id, name) self._info[name] = lsl.StreamInfo(outlet_name, **info, source_id=self._device_id) self._add_device_info(name) chunk_size = self._stream_params["chunk_size"][name] self._outlets[name] = lsl.StreamOutlet(self._info[name], chunk_size=chunk_size, max_buffered=360)
def _create_buffered_lsl_outlet(url, name): """Create 5 channel primitive data outlet the five channels are "diameter_0", "diameter_1", "confidence_0", "confidence_1", "timestamp" """ stream_info = lsl.StreamInfo(name=name, type='Pupil Capture', channel_count=5, channel_format=lsl.cf_double64, source_id='%s @ %s' % (name, url)) _append_channel_info(stream_info, ("diameter_0", "diameter_1", "confidence_0", "confidence_1", "timestamp")) _append_acquisition_info(stream_info) return lsl.StreamOutlet(stream_info)
def construct_streaminfo(self) -> lsl.StreamInfo: stream_info = lsl.StreamInfo( name=self.name, type=self.lsl_type, channel_count=len(self.channels), channel_format=lsl.cf_double64, source_id=self.uuid, ) stream_info.desc().append_child_value("pupil_lsl_relay_version", VERSION) xml_channels = stream_info.desc().append_child("channels") for chan in self.channels: chan.append_to(xml_channels) logger.debug( f"Creating {self.name} outlet with stream info:\n{stream_info}") return stream_info
def set_device_info(self, device_info): import pylsl import uuid super(LslProcessor, self).set_device_info(device_info) channels = self._device_info.channels info = pylsl.StreamInfo(self._device_info.name, 'EEG', len(channels), self._device_info.fs, 'float32', str(uuid.uuid4())) meta_channels = info.desc().append_child('channels') for channel in channels: meta_channels.append_child('channel') \ .append_child_value('label', str(channel)) \ .append_child_value('unit', 'microvolts') \ .append_child_value('type', 'EEG') self._outlet = pylsl.StreamOutlet(info)
def main(): info = pylsl.StreamInfo('MarkerStream', 'Markers', 1, 0, 'string', 'myuniquesourceid23443') outlet_stream = pylsl.StreamOutlet(info) input('Start recording via Lab Recorder and press enter...') while True: # Push start trial input('Press to push `Start` sample') outlet_stream.push_sample(['1']) # Push start trial input('Press to push `End` sample') outlet_stream.push_sample(['11'])
async def enable_ecg(link, nameprefix, idprefix, **kwargs): """Enable the ECG data stream. This is the raw ECG waveform.""" info = pylsl.StreamInfo(nameprefix+'ECG', 'ECG', 1, nominal_srate=ECGWaveformMessage.srate, source_id=idprefix+'-ECG') desc = info.desc() chn = desc.append_child('channels').append_child('channel') chn.append_child_value('label', 'ECG1') chn.append_child_value('type', 'ECG') chn.append_child_value('unit', 'millivolts') add_manufacturer(desc) outlet = pylsl.StreamOutlet(info) def on_ecg(msg): outlet.push_chunk([[v] for v in msg.waveform]) await link.toggle_ecg(on_ecg)
def init_lsl(): """ Define the stream parameters and create outlet stream. :return: outlet stream object """ info = pylsl.StreamInfo('MarkerStream', 'Markers', 1, 0, 'string', 'myuniquesourceid23443') outlet_stream = pylsl.StreamOutlet(info) messagebox.showinfo( title=params['gui']['title'], message= 'Start Lab Recorder!\nBe sure to check your settings.\nClick okay to begin experiment.' ) return outlet_stream