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 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 _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 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 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): 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 send_server_config(self): logger.info('Creating server configuration outlet.') self.config_outlet = pylsl.StreamOutlet(self.config_outlet_streaminfo) # sleep shortly to allow server inlet to resolve the stream and be ready time.sleep(2) config_string = padded_lsl_string(yaml.dump(self.server_config)) logger.info('Pushing server configuration yaml string.') self.config_outlet.push_chunk(config_string)
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 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 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 __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 _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 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 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 _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 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
def make_outlet(device: str = "Amadeo", roms=None): if device == "Amadeo": info = pylsl.StreamInfo(name="tyroS", type="mixed", channel_count=10, nominal_srate=20, channel_format="float32", source_id="tyromotion") acq = info.desc().append_child("acquisition") acq.append_child_value('manufacturer', 'tyromotion') acq.append_child_value('model', str(device)) acq.append_child_value('compensated_lag', '0') channels = info.desc().append_child("channels") # position goes from -1 (mechanical limit flexion) to # 0 (mechanical limit extension) # force is in N, negative is in direction of flexion, # positive in direction of extension finger_names = ["pollex", "index", "medius", "anularius", "minimus"] types = chain((f"extension" for x in range(1, 6, 1)), (f"force" for x in range(1, 6, 1))) units = chain(("au" for x in range(1, 6, 1)), ("N" for x in range(1, 6, 1))) names = chain((f"position_{f}" for f in finger_names), (f"force_{f}" for f in finger_names)) for c, u, t in zip(names, units, types): channels.append_child("channel") \ .append_child_value("label", c) \ .append_child_value("unit", u) \ .append_child_value("type", t) if roms is not None: labels = chain((f"ext_{f}" for f in finger_names), (f"flex_{f}" for f in finger_names)) romdesc = info.desc().append_child("ROM") for rom, lbl in zip(roms, labels): romdesc.append_child("channel") \ .append_child_value("label", lbl) \ .append_child_value("rom", "{:.3f}".format(rom)) else: raise NotImplementedError("Only the Amadeo is currently supported") print("Robotic device was changed, resetting Outlet") print(info.as_xml()) return pylsl.StreamOutlet(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)
async def enable_respiration(link, nameprefix, idprefix, **kwargs): """Enable the respiration data stream. This is the raw respiration (chest expansion) waveform.""" info = pylsl.StreamInfo(nameprefix+'Resp', 'Respiration', 1, nominal_srate=BreathingWaveformMessage.srate, source_id=idprefix+'-Resp') desc = info.desc() chn = desc.append_child('channels').append_child('channel') chn.append_child_value('label', 'Respiration') chn.append_child_value('type', 'EXG') chn.append_child_value('unit', 'unnormalized') add_manufacturer(desc) outlet = pylsl.StreamOutlet(info) def on_breathing(msg): outlet.push_chunk([[v] for v in msg.waveform]) await link.toggle_breathing(on_breathing)
def app_init(): global reader, model, event, outlet, recorder, rec_lock, app_init reader = Reader(250, 5, 8) reader.start(type='Reader Outlet', method='process') time.sleep(0.2) model = Model(reader.sample_rate, reader.num_channel, reader.window_size, range(40)) event = Event() assert event.load_file(__events__) outlet = pylsl.StreamOutlet( pylsl.StreamInfo('EventIO', 'event', channel_format='int32', source_id=random_id())) recorder = Recorder(reader, chunk=False, event_merge=False) recorder.start() rec_lock = threading.Lock() app_init = null_func