class StreamerLSL(): # From IPlugin def __init__(self, nb_channels, sample_rate, channel_type, ID): """ nb_channnels: max number of channels sample_rate: in Hz channel_type: serve as identifier, eg 'PPG" or 'face' ID: unique identifier associated to this stream TODO: check uniqueness """ stream_name = channel_type + "_" + str(ID) print "Creating stream:", stream_name, "of type:", channel_type # TODO: use cam/algo for unique id stream_id = stream_name # Create a new stream info_kinect = StreamInfo(stream_name, channel_type, nb_channels, sample_rate,'float32', stream_id); # make outlets self.outlet_kinect = StreamOutlet(info_kinect) # send channels values # sample: list of float values (one per face) def __call__(self, sample): self.outlet_kinect.push_sample(sample)
class StreamerLSL(plugintypes.IPluginExtended): # From IPlugin def activate(self): eeg_stream = "OpenBCI_EEG" eeg_id = "openbci_eeg_id1" aux_stream = "OpenBCI_AUX" aux_id = "openbci_aux_id1" if len(self.args) > 0: eeg_stream = self.args[0] if len(self.args) > 1: eeg_id = self.args[1] if len(self.args) > 2: aux_stream = self.args[2] if len(self.args) > 3: aux_id = self.args[3] # Create a new streams info, one for EEG values, one for AUX (eg, accelerometer) values print "Creating LSL stream for EEG. Name:", eeg_stream, "- ID:", eeg_id, "- data type: float32.", self.eeg_channels, "channels at", self.sample_rate, "Hz." info_eeg = StreamInfo(eeg_stream, 'EEG', self.eeg_channels,self.sample_rate,'float32',eeg_id); # NB: set float32 instead of int16 so as OpenViBE takes it into account print "Creating LSL stream for AUX. Name:", aux_stream, "- ID:", aux_id, "- data type: float32.", self.aux_channels, "channels at", self.sample_rate, "Hz." info_aux = StreamInfo(aux_stream, 'AUX', self.aux_channels,self.sample_rate,'float32',aux_id); # make outlets self.outlet_eeg = StreamOutlet(info_eeg) self.outlet_aux = StreamOutlet(info_aux) # send channels values def __call__(self, sample): self.outlet_eeg.push_sample(sample.channel_data) self.outlet_aux.push_sample(sample.aux_data) def show_help(self): print """Optional arguments: [EEG_stream_name [EEG_stream_ID [AUX_stream_name [AUX_stream_ID]]]]
def run_events_sim(name='events_example'): info = StreamInfo(name=name, type='EEG', channel_count=1, channel_format='float32', source_id='myuid34234') # channels labels (in accordance with XDF format, see also code.google.com/p/xdf) chns = info.desc().append_child("channels") for label in ['STIM']: ch = chns.append_child("channel") ch.append_child_value("label", label) outlet = StreamOutlet(info) # send data and print some info every 5 sec print('now sending data...') while True: outlet.push_sample([42]) time.sleep(1) print('42 sent') pass
class SignalsOutlet: def __init__(self, signals, fs, name='NFBLab_data1'): self.info = StreamInfo(name=name, type='', channel_count=len(signals), source_id='nfblab42', nominal_srate=fs) self.info.desc().append_child_value("manufacturer", "BioSemi") channels = self.info.desc().append_child("channels") for c in signals: channels.append_child("channel").append_child_value("name", c) self.outlet = StreamOutlet(self.info) def push_sample(self, data): self.outlet.push_sample(data) def push_repeated_chunk(self, data, n=1): #chunk = repeat(data, n).reshape(-1, n).T.tolist() #self.outlet.push_chunk(chunk) for k in range(n): self.outlet.push_sample(data) def push_chunk(self, data, n=1): self.outlet.push_chunk(data)
class StreamerLSL(plugintypes.IPluginExtended): # From IPlugin def activate(self): eeg_stream = "OpenBCI_EEG" eeg_id = "openbci_eeg_id1" aux_stream = "OpenBCI_AUX" aux_id = "openbci_aux_id1" imp_stream = "OpenBCI_Impedance" imp_id = "openbci_imp_id1" if len(self.args) > 0: eeg_stream = self.args[0] if len(self.args) > 1: eeg_id = self.args[1] if len(self.args) > 2: aux_stream = self.args[2] if len(self.args) > 3: aux_id = self.args[3] if len(self.args) > 4: imp_stream = self.args[4] if len(self.args) > 5: imp_id = self.args[5] # Create a new streams info, one for EEG values, one for AUX (eg, accelerometer) values print("Creating LSL stream for EEG. Name:" + eeg_stream + "- ID:" + eeg_id + "- data type: float32." + str(self.eeg_channels) + "channels at" + str(self.sample_rate) + "Hz.") info_eeg = StreamInfo(eeg_stream, 'EEG', self.eeg_channels, self.sample_rate, 'float32', eeg_id) # NB: set float32 instead of int16 so as OpenViBE takes it into account print("Creating LSL stream for AUX. Name:" + aux_stream + "- ID:" + aux_id + "- data type: float32." + str(self.aux_channels) + "channels at" + str(self.sample_rate) + "Hz.") info_aux = StreamInfo(aux_stream, 'AUX', self.aux_channels, self.sample_rate, 'float32', aux_id) # make outlets self.outlet_eeg = StreamOutlet(info_eeg) self.outlet_aux = StreamOutlet(info_aux) if self.imp_channels > 0: print("Creating LSL stream for Impedance. Name:" + imp_stream + "- ID:" + imp_id + "- data type: float32." + str(self.imp_channels) + "channels at" + str(self.sample_rate) + "Hz.") info_imp = StreamInfo(imp_stream, 'Impedance', self.imp_channels, self.sample_rate, 'float32', imp_id) self.outlet_imp = StreamOutlet(info_imp) # send channels values def __call__(self, sample): self.outlet_eeg.push_sample(sample.channel_data) self.outlet_aux.push_sample(sample.aux_data) if self.imp_channels > 0: self.outlet_imp.push_sample(sample.imp_data) def show_help(self): print("""Optional arguments: [EEG_stream_name [EEG_stream_ID [AUX_stream_name [AUX_stream_ID [Impedance_steam_name [Impedance_stream_ID]]]]]] \t Defaults: "OpenBCI_EEG" / "openbci_eeg_id1" and "OpenBCI_AUX" / "openbci_aux_id1" / "OpenBCI_Impedance" / "openbci_imp_id1".""")
mne_reject=1, reject_ch=True, flat=flat) if t_test > 0: epoch = (epoch + epoch_prev) / 2 epochs_fb[t_test, :, :] = epoch print('Epoch number: ' + str(t_test)) # Apply classifier for real-time decoding pred_prob = testEpoch(clf, epoch) # Apply offset correction for both binary categories. Limit prediction probability to a value between 0 and 1 pred_prob[0][0, 0] = np.min( [np.max([pred_prob[0][0, 0] + offset, 0]), 1]) pred_prob[0][0, 1] = np.min( [np.max([pred_prob[0][0, 1] - offset, 0]), 1]) clf_output = pred_prob[0][0, int(y[marker[0]])] - pred_prob[0][ 0, int(y[marker[0]] - 1)] # Compute alpha from the corrected classifier output using a sigmoid transfer function. Alpha value used for updating experimental stimuli. alpha = sigmoid(clf_output) marker_alpha = [marker[0][0], alpha] print('Marker number: ' + str(marker_alpha)) # Push alpha value to an outlet for use in experimental script outlet_alpha.push_sample([alpha]) epoch_prev = epoch #%% Terminate logging of print statements Transcript.stop()
# rate for spamming stdout displaySamplingRate = 10 ser = serial.Serial(port, baudrate) # create LSL StreamOutlet info = StreamInfo('breath','breath',1,samplingrate,'float32','conphyturebreathing1337') outlet = StreamOutlet(info) # some time for init? #time.sleep(0.5) n=0 while True: line = ser.readline() value = 0 # convert string to float (remove trailing line break at the same time...) try: value = float(line) except: # silently discard conversion problem pass #TODO: won't work if rates not dividers if n%(samplingrate/displaySamplingRate) == 0: print value outlet.push_sample([value]) n+=1 #time.sleep(0.002) ser.close()
ax.set_yticklabels(['']) ax.set_xticklabels(['']) t = plt.text(0.5, 0.5, '', horizontalalignment='center') plt.xlim(xmin=0, xmax=1) plt.ylim(ymin=0, ymax=1) plt.ion() plt.draw() plt.show() try: for trial in range(1, warmup_trials + trials_per_class * len(labels) + 1): if not plt.fignum_exists(hFigure.number): break choice = random.choice(range(len(labels))) t.set_text(labels[choice]) if trial == warmup_trials: outlet.push_sample(['calib-begin']) if trial > warmup_trials: outlet.push_sample([markers[choice]]) hFigure.canvas.draw() hFigure.canvas.flush_events() time.sleep(perform_time) t.set_text('') hFigure.canvas.draw() hFigure.canvas.flush_events() time.sleep(wait_time) if trial % pause_every == 0: t.set_text('Pause') hFigure.canvas.draw() hFigure.canvas.flush_events() time.sleep(pause_duration) t.set_text('')
t_start = time.clock() # real_time_BCI.sync_data() while (experiment_going): label = [] buffer_data = real_time_BCI.iter_bci_buffer(buffer_data, iter_n) real_time_BCI.read_bci_markers() if feedback: # print(buffer_data) if filter_rt: buffer_data = eeg_io_pp_2.butter_bandpass_filter( buffer_data, 7, 30, freq) x1 = eeg_io_pp_2.norm_dataset(buffer_data) x1 = x1.reshape(1, x1.shape[0], x1.shape[1]) try: a, cert = real_time_BCI.predict(clf, x1, label) except ValueError: a, cert = 1, 0.001 print(a, cert) outlet_fb.push_sample([int(a)]) outlet_cert.push_sample([cert]) if time.clock() > t_start + 300: exit() iter_n += 1
class EEG: def __init__( self, device=None, serial_port=None, serial_num=None, mac_addr=None, other=None, ip_addr=None, ): """The initialization function takes the name of the EEG device and determines whether or not the device belongs to the Muse or Brainflow families and initializes the appropriate backend. Parameters: device (str): name of eeg device used for reading data. """ # determine if board uses brainflow or muselsl backend self.device_name = device self.serial_num = serial_num self.serial_port = serial_port self.mac_address = mac_addr self.ip_addr = ip_addr self.other = other self.backend = self._get_backend(self.device_name) self.initialize_backend() def initialize_backend(self): if self.backend == "brainflow": self._init_brainflow() elif self.backend == "muselsl": self._init_muselsl() def _get_backend(self, device_name): if device_name in brainflow_devices: return "brainflow" elif device_name in ["muse2016", "muse2", "museS"]: return "muselsl" ##################### # MUSE functions # ##################### def _init_muselsl(self): # Currently there's nothing we need to do here. However keeping the # option open to add things with this init method. pass def _start_muse(self, duration): if sys.platform in ["linux", "linux2", "darwin"]: # Look for muses self.muses = list_muses() # self.muse = muses[0] # Start streaming process self.stream_process = Process(target=stream, args=(self.muses[0]["address"], )) self.stream_process.start() # Create markers stream outlet self.muse_StreamInfo = StreamInfo("Markers", "Markers", 1, 0, "int32", "myuidw43536") self.muse_StreamOutlet = StreamOutlet(self.muse_StreamInfo) # Start a background process that will stream data from the first available Muse print("starting background recording process") print("will save to file: %s" % self.save_fn) self.recording = Process(target=record, args=(duration, self.save_fn)) self.recording.start() time.sleep(5) self.push_sample([99], timestamp=time.time()) def _stop_muse(self): pass def _muse_push_sample(self, marker, timestamp): self.muse_StreamOutlet.push_sample(marker, timestamp) ########################## # BrainFlow functions # ########################## def _init_brainflow(self): """This function initializes the brainflow backend based on the input device name. It calls a utility function to determine the appropriate USB port to use based on the current operating system. Additionally, the system allows for passing a serial number in the case that they want to use either the BraintBit or the Unicorn EEG devices from the brainflow family. Parameters: serial_num (str or int): serial number for either the BrainBit or Unicorn devices. """ # Initialize brainflow parameters self.brainflow_params = BrainFlowInputParams() if self.device_name == "ganglion": self.brainflow_id = BoardIds.GANGLION_BOARD.value if self.serial_port == None: self.brainflow_params.serial_port = get_openbci_usb() # set mac address parameter in case if self.mac_address is None: print( "No MAC address provided, attempting to connect without one" ) else: self.brainflow_params.mac_address = self.mac_address elif self.device_name == "ganglion_wifi": self.brainflow_id = BoardIds.GANGLION_WIFI_BOARD.value if self.ip_addr is not None: self.brainflow_params.ip_address = self.ip_addr self.brainflow_params.ip_port = 6677 elif self.device_name == "cyton": self.brainflow_id = BoardIds.CYTON_BOARD.value if self.serial_port is None: self.brainflow_params.serial_port = get_openbci_usb() elif self.device_name == "cyton_wifi": self.brainflow_id = BoardIds.CYTON_WIFI_BOARD.value if self.ip_addr is not None: self.brainflow_params.ip_address = self.ip_addr self.brainflow_params.ip_port = 6677 elif self.device_name == "cyton_daisy": self.brainflow_id = BoardIds.CYTON_DAISY_BOARD.value if self.serial_port is None: self.brainflow_params.serial_port = get_openbci_usb() elif self.device_name == "cyton_daisy_wifi": self.brainflow_id = BoardIds.CYTON_DAISY_WIFI_BOARD.value if self.ip_addr is not None: self.brainflow_params.ip_address = self.ip_addr elif self.device_name == "brainbit": self.brainflow_id = BoardIds.BRAINBIT_BOARD.value elif self.device_name == "unicorn": self.brainflow_id = BoardIds.UNICORN_BOARD.value elif self.device_name == "callibri_eeg": self.brainflow_id = BoardIds.CALLIBRI_EEG_BOARD.value if self.other: self.brainflow_params.other_info = str(self.other) elif self.device_name == "notion1": self.brainflow_id = BoardIds.NOTION_1_BOARD.value elif self.device_name == "notion2": self.brainflow_id = BoardIds.NOTION_2_BOARD.value elif self.device_name == "freeeeg32": self.brainflow_id = BoardIds.FREEEEG32_BOARD.value if self.serial_port is None: self.brainflow_params.serial_port = get_openbci_usb() elif self.device_name == "synthetic": self.brainflow_id = BoardIds.SYNTHETIC_BOARD.value # some devices allow for an optional serial number parameter for better connection if self.serial_num: serial_num = str(self.serial_num) self.brainflow_params.serial_number = serial_num if self.serial_port: serial_port = str(self.serial_port) self.brainflow_params.serial_port = serial_port # Initialize board_shim self.sfreq = BoardShim.get_sampling_rate(self.brainflow_id) self.board = BoardShim(self.brainflow_id, self.brainflow_params) self.board.prepare_session() def _start_brainflow(self): self.board.start_stream() # wait for signal to settle sleep(5) def _stop_brainflow(self): """This functions kills the brainflow backend and saves the data to a CSV file.""" # Collect session data and kill session data = self.board.get_board_data() # will clear board buffer self.board.stop_stream() self.board.release_session() # transform data for saving data = data.T # transpose data # get the channel names for EEG data if (self.brainflow_id == BoardIds.GANGLION_BOARD.value or self.brainflow_id == BoardIds.GANGLION_WIFI_BOARD.value): # if a ganglion is used, use recommended default EEG channel names ch_names = ["fp1", "fp2", "tp7", "tp8"] elif (self.brainflow_id == BoardIds.FREEEEG32_BOARD.value): ch_names = [f'eeg_{i}' for i in range(0, 32)] else: # otherwise select eeg channel names via brainflow API ch_names = BoardShim.get_eeg_names(self.brainflow_id) # pull EEG channel data via brainflow API eeg_data = data[:, BoardShim.get_eeg_channels(self.brainflow_id)] timestamps = data[:, BoardShim.get_timestamp_channel(self.brainflow_id)] # Create a column for the stimuli to append to the EEG data stim_array = create_stim_array(timestamps, self.markers) timestamps = timestamps[ ..., None] # Add an additional dimension so that shapes match total_data = np.append(timestamps, eeg_data, 1) total_data = np.append(total_data, stim_array, 1) # Append the stim array to data. # Subtract five seconds of settling time from beginning total_data = total_data[5 * self.sfreq:] data_df = pd.DataFrame(total_data, columns=["timestamps"] + ch_names + ["stim"]) data_df.to_csv(self.save_fn, index=False) def _brainflow_push_sample(self, marker): last_timestamp = self.board.get_current_board_data(1)[-1][0] self.markers.append([marker, last_timestamp]) def start(self, fn, duration=None): """Starts the EEG device based on the defined backend. Parameters: fn (str): name of the file to save the sessions data to. """ if fn: self.save_fn = fn if self.backend == "brainflow": # Start brainflow backend self._start_brainflow() self.markers = [] elif self.backend == "muselsl": self._start_muse(duration) def push_sample(self, marker, timestamp): """Universal method for pushing a marker and its timestamp to store alongside the EEG data. Parameters: marker (int): marker number for the stimuli being presented. timestamp (float): timestamp of stimulus onset from time.time() function. """ if self.backend == "brainflow": self._brainflow_push_sample(marker=marker) elif self.backend == "muselsl": self._muse_push_sample(marker=marker, timestamp=timestamp) def stop(self): if self.backend == "brainflow": self._stop_brainflow() elif self.backend == "muselsl": pass
class MarkersGeneratorOutlet(object): phases = { 'precue': {'next': 'cue', 'duration': 1.0}, 'cue': {'next': 'go', 'duration': 0.5}, 'go': {'next': 'evaluate', 'duration': 5.0}, 'evaluate': {'next': 'precue', 'duration': 0.1} } def __init__(self, class_list=[1, 3], classes_rand=True, target_list=[1, 2], targets_rand=True): """ :param class_list: A list of integers comprising different class ids. Default: [1, 3] :param classes_rand: If True, classes are chosen randomly from list. If False, the list is cycled. Default: True :param target_list: A list of integers comprising different target ids. Default: [1, 2] :param targets_rand: If True, targets are chosen randomly from list. If False, the list is cycled. Default: True """ stream_name = 'GeneratedCentreOutMarkers' stream_type = 'Markers' outlet_info = StreamInfo(name=stream_name, type=stream_type, channel_count=1, nominal_srate=0, channel_format='string', source_id='centreoutmarkergen1234') outlet_xml = outlet_info.desc() channels_xml = outlet_xml.append_child("channels") chan_xml = channels_xml.append_child("channel") chan_xml.append_child_value("label", "EventMarkers") chan_xml.append_child_value("type", "generated") self.outlet = StreamOutlet(outlet_info) print("Created outlet with name {} and type {}".format(stream_name, stream_type)) self.class_list = class_list self.classes_rand = classes_rand self.target_list = target_list self.targets_rand = targets_rand self.next_transition = -1 self.in_phase = 'evaluate' self.trial_ix = 0 self.class_id = self.class_list[0] self.target_id = self.target_list[0] def update(self): now = local_clock() if (now > self.next_transition): # Transition phase self.in_phase = self.phases[self.in_phase]['next'] self.next_transition = now + self.phases[self.in_phase]['duration'] # Send markers out_string = "undefined" if self.in_phase == 'precue': # transition from evaluate to precue # print("Previous class_id: {}, target_id: {}".format(self.class_id, self.target_id)) self.trial_ix += 1 self.target_id = random.choice(self.target_list) if self.targets_rand else self.target_list[ (self.target_list.index(self.target_id) + 1) % len(self.target_list)] self.class_id = random.choice(self.class_list) if self.classes_rand else self.class_list[ (self.class_list.index(self.class_id) + 1) % len(self.class_list)] # print("New class_id: {}, target_id: {}".format(self.class_id, self.target_id)) out_string = "NewTrial {}, Class {}, Target {}".format(self.trial_ix, self.class_id, self.target_id) elif self.in_phase == 'cue': # transition from precue to cue out_string = "TargetCue, Class {}, Target {}".format(self.class_id, self.target_id) elif self.in_phase == 'go': # transition from cue to go out_string = "GoCue, Class {}, Target {}".format(self.class_id, self.target_id) elif self.in_phase == 'evaluate': # transition from go to evaluate hit_string = "Hit" if random.randint(0, 1) == 1 else "Miss" out_string = "{}, Class {}, Target {}".format(hit_string, self.class_id, self.target_id) print("Marker outlet pushing string: {}".format(out_string)) self.outlet.push_sample([out_string,]) return True return False
import sys; sys.path.append('./lib') # help python find pylsl relative to this example program from pylsl import StreamInfo, StreamOutlet import random import time # first create a new stream info (here we set the name to MyMarkerStream, the content-type to Markers, 1 channel, irregular sampling rate, and string-valued data) # The last value would be the locally unique identifier for the stream as far as available, e.g. program-scriptname-subjectnumber (you could also omit it but interrupted connections wouldn't auto-recover). # The important part is that the content-type is set to 'Markers', because then other programs will know how to interpret the content info = StreamInfo('MyMarkerStream','Markers',1,0,'string','myuidw43536'); # next make an outlet outlet = StreamOutlet(info) print("now sending markers...") markernames = ['coucou', 'OVTK_GDF_Start_Of_Trial', 'OVTK_StimulationId_Label_01'] while True: mark = random.choice(markernames) print "Sending: ", mark # pick a sample to send an wait for a bit outlet.push_sample([mark]) time.sleep(random.random()*3)
class Feedback(object): """ Base class for all feedbacks. This class provides methods which are called by the FeedbackController on certain events. Override the methods as needed. As a bare minimum you should override the :func:`on_play` method in your derived class to do anything useful. To get the data from control signals, you can use the `_data` variable in your feedback which will always hold the latest control signal. To get the data from the interaction signals, you can use the variable names just as sent by the GUI. This class provides the :func:`send_parallel` method which you can use to send arbitrary data to the parallel port. You don't have to override this method in your feedback. Example:: from FeedbackBase.Feedback import Feedback class MyFeedback(Feedback): def on_init(self): self.logger.debug("Feedback successfully loaded.") def on_play(self): self.logger.debug("Feedback started.") def on_quit(self): self.logger.debug("Feedback quit.") """ def __init__(self, port_num=None): """ Initializes the feedback. You should not override this method, override on_init instead. If you must override this method, make sure to call ``Feedback.__init__(self, pp)`` before anything else in your overridden __init__ method. """ self._data = None self.logger = logging.getLogger("FB." + self.__class__.__name__) """Inherited by all sub classes. Use this for logging.""" self.logger.debug("Loaded my logger.") # Setup the parallel port self._pport = None if sys.platform == 'win32': try: from ctypes import windll self._pport = windll.inpout32 except: self.logger.warning("Could not load inpout32.dll. Please make sure it is located in the system32 directory") else: try: import parallel self._pport = parallel.Parallel() except: self.logger.warning("Unable to open parallel port! Please install pyparallel to use it.") if port_num != None: self._port_num = port_num # used in windows only'' else: self._port_num = 0x378 self._playEvent = Event() self._shouldQuit = False # Initialize with dummy values so we cann call safely .cancel self._triggerResetTimer = Timer(0, None) self._triggerResetTime = 0.01 self.udp_markers_host = '127.0.0.1' self.udp_markers_port = 12344 self.ov_tcp_tag_enable = False self.ov_tcp_tag_host = '127.0.0.1' self.ov_tcp_tag_port = 15361 self._ov_tcp_tag_socket = self._ov_tcp_tag_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) print 'init base',self._ov_tcp_tag_socket #self.tcp_markers_enable = False #self.tcp_markers_host = '127.0.0.1' #self.tcp_markers_port = 12344 self._has_lsl = False try: from pylsl import StreamInfo, StreamOutlet self._has_lsl = True except: self.logger.warning("Could not import LabStreamingLayer. Ignore, if you don't want to send LSL Markers.") if self._has_lsl: try: # name: PyffMarkerStream, content-type: Markers, # channels: 1, irregular sampling rate, # type: string, id: pyffmarker info = StreamInfo('PyffMarkerStream', 'Markers', 1, 0, 'string', 'pyffmarker') self._lsl_outlet = StreamOutlet(info) except: self.logger.error("Unable to Create LSL Marker Outlet, but LSL is installed.") self._has_lsl = False # # Internal routines not inteded for overwriting # def _on_control_event(self, data): """ Store the data in the feedback and call on_control_event. You should not override this method, use on_control_event instead. """ self._data = data self.on_control_event(data) def _on_interaction_event(self, data): """ Store the variable-value pairs in the feedback and call on_interaction_event. You should not override this method, use on_interaction_event instead. """ data2 = dict() for key in data: # Oh man, das wird sich nochmal raechen! # Originalversion: #self.__setattr__(key, data[key]) # Problem: Variablen wie feedback_opt.fb_port oder # fedback_opt(1).bla # Loesung: nehme nur den Namen nach dem letzten Punkt key2 = key.split(".")[ - 1] #self.__setattr__(self.PREFIX+key2, data[key]) self.__setattr__(key2, data[key]) data2[key2] = data[key] self.on_interaction_event(data2) def _on_init(self): """ Calls on_init. You should not override this method, use on_init instead. """ self.on_init() def _on_play(self): """ Calls on_play. You should not override this method, use on_play instead. """ self._udp_markers_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # self.logger.info("Sending markers via TCP enabled") #if self.tcp_markers_enable: # self.logger.info("Connecting to " + self.tcp_markers_host + ":" + str(self.tcp_markers_port)) # self._tcp_markers_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # self._tcp_markers_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # self._tcp_markers_socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) # self._tcp_markers_socket.connect((self.tcp_markers_host, self.tcp_markers_port)) # self.logger.info("Sending markers via TCP/IP enabled.") self.on_play() def _on_pause(self): """ Calls on_pause. You should not override this method, use on_pause instead. """ self.on_pause() def _on_stop(self): """ Calls on_stop. You should not override this method, use on_stop instead. """ self.on_stop() def _on_quit(self): """ Calls on_quit. You should not override this method, use on_quit instead. """ self._shouldQuit = True self._playEvent.set() self.on_quit() # # Empty routines intended to be overwritten by derived classes # def on_init(self): """ This method is called right after the feedback object was loaded by the FeedbackController. Override this method to initialize everything you need before the feedback starts. """ self.logger.debug("on_init not implemented yet!") def on_play(self): """ This method is called by the FeedbackController when it received a "Play" event via interaction signal. Override this method to actually start your feedback. """ self.logger.debug("on_play not implemented yet!") def on_pause(self): """ This method is called by the FeedbackController when it received a "Pause" event via interaction signal. Override this method to pause your feedback. """ self.logger.debug("on_pause not implemented yet!") def on_stop(self): """ This method is called by the FeedbackController when it received a "Stop" event. Override this method to stop your feedback. It should be possible to start again when receiving the :func:`on_start` event. """ self._ov_tcp_tag_socket.close() self.logger.debug("on_stop not implemented yet!") def on_quit(self): """ This Method is called just before the FeedbackController will destroy the feedback object. The FeedbackController will not destroy the feedback object until this method has returned. Override this method to cleanup everything as needed or save information before the object gets destroyed. """ self.logger.debug("on_quit not implemented yet!") def on_interaction_event(self, data): """ This method is called after the FeedbackController received a interaction signal. The FeedbackController parses the signal, extracts the variable-value pairs, stores them as object-variables in your feedback and calls this method. If the FeedbackController detects a "play", "pause" or "quit" signal, it calls the appropriate ``on-method`` after this method has returned. If the FeedbackController detects an "init" signal, it calls :func:`on_init` before :func:`on_interaction_event`! Override this method if you want to react on interaction events. :param data: The content of the interaction signal. :type data: dict """ self.logger.debug("on_interaction_event not implemented yet!") def on_control_event(self, data): """ This method is called after the FeedbackController received a control signal. The FeedbackController parses the signal, extracts the values stores the resulting tuple in the object-variable "data" and calls this method. Override this method if you want to react on control events. :param data: The content of the control signal :type data: dict """ self.logger.debug("on_control_event not implemented yet!") # # Common routines for all feedbacks # def send_parallel(self, data, reset=True): """Sends the data to the parallel port. The data is sent to the parallel port. After a short amount of time the parallel port is reset automatically. :param data: Data to be sent to the parallel port :type data: int """ self.logger.info("Trigger: %s :%s" % (str(datetime.datetime.now()), str(data))) if reset == True: # A new trigger arrived before we could reset the old one self._triggerResetTimer.cancel() if self._pport: if sys.platform == 'win32': self._pport.Out32(self._port_num, data) else: self._pport.setData(data) if reset: self._triggerResetTimer = threading.Timer(self._triggerResetTime, self.send_parallel, (0x0, False)) self._triggerResetTimer.start() def send_udp(self, data): """Sends the data to UDP. Similar to :func:`send_parallel`. The data is send through UDP. ``send_udp`` will append an ``'\n'`` character to the end of ``data`` before sending it. :param data: Data to be sent to the UDP port. :type data: str the marker. """ self._udp_markers_socket.sendto(data + '\n', (self.udp_markers_host, self.udp_markers_port)) def send_lsl(self, data): """Sends Marker via LSL. Parameters ---------- data : str the marker """ if not self._has_lsl: self.logger.error("Lab Streaming Layer is not available, no markers have been sent!") # logger.error("Lab Streaming Layer is not available, no markers have been sent!") return self._lsl_outlet.push_sample([data]) """ """ def send_ov_tcp_tag(self, event): # create the three pieces of the tag, padding, event_id and timestamp padding = [0] * 8 event_id = list(self.to_byte(event, 8)) # send tag self._ov_tcp_tag_socket.sendall(bytearray(padding + event_id + padding)) """ Used by send_ov_tcp_tag """ # transform a value into an array of byte values in little-endian order. def to_byte(self, value, length): for x in range(length): yield value % 256 value //= 256 #def send_tcp(self, data): # """Sends marker via TCP/IP. # # Parameters # ---------- # data : str # the marker. The string must end with '\n'. # # """ # self._tcp_markers_socket.send(data) def _get_variables(self): """Return a dictionary of variables and their values.""" # try everything from self.__dict__: # must be pickable self.logger.debug("Preparing variables.") d = {} for key, val in self.__dict__.iteritems(): if key.startswith("_"): continue try: self.logger.debug("Trying to pickle %s %s" % (key, val)) s = pickle.dumps(val, pickle.HIGHEST_PROTOCOL) except: self.logger.warning("Unable to pickle %s" % key) continue d[key] = val self.logger.debug("Returning variables.") return d def save_variables(self, filename): """Save all variables which are pickleable in JSON format. :param filename: The file where to store the variables. :type filename: str """ # the json pickler cannot pickle everything the python pickler can, # prune away the variables which are not pickable, to avoid exception var_clean = dict() for k, v in self.__dict__.iteritems(): if k.startswith("_"): continue try: json.dumps(v) except TypeError: continue var_clean[k] = v filehandle = open(filename, 'w') json.dump(var_clean, filehandle, indent=4, sort_keys=True) filehandle.close() def load_variables(self, filename): """Load variables from file and (over)write object attributes with their values. :param filename: The file where the variables are stored. :type filename: str This method expects the file to be in the same format as the save_variables method produces (currently JSON). """ filehandle = open(filename, 'r') var = json.load(filehandle) filehandle.close() self.__dict__.update(var) def _playloop(self): """Loop which ensures that on_play always runs in main thread. Do not overwrite in derived classes unless you know what you're doing. """ self._shouldQuit = False while 1: self._playEvent.wait() if self._shouldQuit: break try: self.logger.debug("Starting on_play.") self._on_play() except: # The feedback's main thread crashed and we need to take care # that the pipe does not run full, otherwise the feedback # controller freezes on the last pipe[foo].send() # So let's just terminate the feedback process. self.logger.exception("on_play threw an exception:") return self._playEvent.clear() self.logger.debug("on_play terminated.") self.logger.debug("_playloop terminated.")
number_of_trials = 3 after_trial_pause = 90 command_display_time = 7 fixation_display_time = 3 # Flickering frequency for the Up-Down-Left-Right stimulus monitor_to_use = 1 square_left_number_frames = 3 # 3 frames ON and 3 frames OFF to make 10 Hz square_right_number_frames = 5 # 5 frames ON and 5 frames OFF to make 6 Hz square_up_number_frames = 4 # 4 frames ON and 4 frames OFF to make 7.5 Hz square_down_number_frames = 4 # 4 frames ON BUT 3 frames OFF to make 8.57 Hz # Create LSL inlet and send the first event "Waiting..." during the pause everything is being set up info = StreamInfo("MyMarkerStream", "Markers", 1, 0, "string", "Experiment01") outlet = StreamOutlet(info) outlet.push_sample(["Waiting..."]) time.sleep(1) # Create an artificial pause to give time to prepare LSL recording externally clock_object = core.Clock() recording_pause = 10 countdown_time = core.CountdownTimer(recording_pause) while countdown_time.getTime() > 0: elapsed_time = clock_object.getTime() clock_object.reset() elapsed_time = 0 # ---------------------------------------------------------------------------------------------------------------------- # ---------------------------------------------------------------------------------------------------------------------- # ---- Create a full-screen window with invisible mouse, collect real monitor refresh rate ----
class StreamerLSL(plugintypes.IPluginExtended): # From IPlugin def activate(self): eeg_stream = "OpenBCI_EEG" eeg_id = "openbci_eeg_id1" aux_stream = "OpenBCI_AUX" aux_id = "openbci_aux_id1" imp_stream = "OpenBCI_Impedance" imp_id = "openbci_imp_id1" if len(self.args) > 0: eeg_stream = self.args[0] if len(self.args) > 1: eeg_id = self.args[1] if len(self.args) > 2: aux_stream = self.args[2] if len(self.args) > 3: aux_id = self.args[3] if len(self.args) > 4: imp_stream = self.args[4] if len(self.args) > 5: imp_id = self.args[5] # Create a new streams info, one for EEG values, one for AUX (eg, accelerometer) values print("Creating LSL stream for EEG. Name:" + eeg_stream + "- ID:" + eeg_id + "- data type: float32." + str(self.eeg_channels) + "channels at" + str(self.sample_rate) + "Hz.") info_eeg = StreamInfo(eeg_stream, 'EEG', self.eeg_channels, self.sample_rate, 'float32', eeg_id) # NB: set float32 instead of int16 so as OpenViBE takes it into account print("Creating LSL stream for AUX. Name:" + aux_stream + "- ID:" + aux_id + "- data type: float32." + str(self.aux_channels) + "channels at" + str(self.sample_rate) + "Hz.") info_aux = StreamInfo(aux_stream, 'AUX', self.aux_channels, self.sample_rate, 'float32', aux_id) # make outlets self.outlet_eeg = StreamOutlet(info_eeg) self.outlet_aux = StreamOutlet(info_aux) if self.imp_channels > 0: print("Creating LSL stream for Impedance. Name:" + imp_stream + "- ID:" + imp_id + "- data type: float32." + str(self.imp_channels) + "channels at" + str(self.sample_rate) + "Hz.") info_imp = StreamInfo(imp_stream, 'Impedance', self.imp_channels, self.sample_rate, 'float32', imp_id) self.outlet_imp = StreamOutlet(info_imp) # send channels values def __call__(self, sample): self.outlet_eeg.push_sample(sample.channel_data) self.outlet_aux.push_sample(sample.aux_data) if self.imp_channels > 0: self.outlet_imp.push_sample(sample.imp_data) def show_help(self): print("""Optional arguments: [EEG_stream_name [EEG_stream_ID [AUX_stream_name [AUX_stream_ID [Impedance_steam_name [Impedance_stream_ID]]]]]] \t Defaults: "OpenBCI_EEG" / "openbci_eeg_id1" and "OpenBCI_AUX" / "openbci_aux_id1" / "OpenBCI_Impedance" / "openbci_imp_id1".""")
#unpack little endian(>) signed integer(i) (makes unpacking platform independent) myInt = struct.unpack('>i', packed)[0] return myInt if __name__=="__main__": try: board = Board(args.device_mac) # enable something?? # board.writeCharacteristic(0x0025, '\1\0', False) board.delegate.handleNotification = board.addData while True: board.waitForNotifications(1./samplingrate) # ugly way to stream and free board current buffer for s in board.samples: print "push sample: ", s.id, "values:", s.channel_data outlet_phibe.push_sample(s.channel_data) board.samples = [] finally: if board: # way get "" try: board.disconnect() print "disconnected" except: # may get "ValueError: need more than 1 value to unpack"?? print "error while disconnecting"
# first create a new stream info (here we set the name to BioSemi, # the content-type to EEG, 8 channels, 100 Hz, and float-valued data) The # last value would be the serial number of the device or some other more or # less locally unique identifier for the stream as far as available (you # could also omit it but interrupted connections wouldn't auto-recover) fs = 1000 info = StreamInfo('python', 'EEG', 2) # next make an outlet outlet = StreamOutlet(info) from pylsl import StreamInlet, resolve_stream print('resolving stream') streams = resolve_stream('name', 'matlab') # create a new inlet to read from the stream inlet = StreamInlet(streams[0]) print('resolved') t = 0 mean_time = 0 while True: #time.sleep(0.002) t += 1 clock = local_clock() outlet.push_sample([0, 1]) sample, timestamp = inlet.pull_sample(timeout=1) dt = local_clock() - clock mean_time += dt print(mean_time / t, dt) #time.sleep(0.001)
data_sampling_rate = 50 data_push_interval = 1/data_sampling_rate stream_name = 'RandomVectors' stream_type = 'EEG' device_name = 'Sample_PC' stream_info = StreamInfo(stream_name, stream_type, data_number_channels, data_sampling_rate, data_format, device_name) # Create Outlet outlet = StreamOutlet(stream_info) # Using an infinite loop, send data print("Now sending data through a "+stream_type+" Stream...") sample_data = list(range(data_number_channels)) while True: # Create sample that will be send (a random column vector in this case) for loop_var in range(data_number_channels): sample_data[loop_var] = random.random() # Push the sample on the outlet (creates the streaming) outlet.push_sample(sample_data) # Wait the required time to generate the desired sampling rate time.sleep(data_push_interval) print('Stream finished')
def present(duration=120): # Create markers stream outlet #info = StreamInfo('Markers', 'Markers', 1, 0, 'int32', 'myuidw43536') info = StreamInfo('Markers', 'Markers', 3, 0, 'int32', 'myuidw43536') outlet = StreamOutlet(info) #markernames = [1, 2] start = time() # Set up trial parameters #n_trials = 2010 iti = 0.8 soa = 0.2 jitter = 0.2 record_duration = np.float32(duration) # Setup trial list #image_type = np.random.binomial(1, 0.5, n_trials) #trials = DataFrame(dict(image_type=image_type, # timestamp=np.zeros(n_trials))) fso_ims = read_csv(fso_list_file) n_trials = fso_ims.shape[0] # Setup graphics def load_image(filename): return visual.ImageStim(win=mywin, image=filename) mywin = visual.Window([1600, 900], monitor='testMonitor', units='deg', winType='pygame', fullscr=True) #faces = list(map(load_image, glob( # 'stimulus_presentation/stim/face_house/faces/*_3.jpg'))) #houses = list(map(load_image, glob( # 'stimulus_presentation/stim/face_house/houses/*.3.jpg'))) #for ii, trial in trials.iterrows(): for ii, trial in fso_ims.iterrows(): trialnum, filename, facehouse, girlboy = trial.values filename = os.path.join(stim_dir, filename) # Intertrial interval core.wait(iti + np.random.rand() * jitter) # Select and display image #label = trials['image_type'].iloc[ii] #image = choice(faces if label == 1 else houses) image = load_image(filename) image.draw() # Send marker timestamp = time() #outlet.push_sample([markernames[label]], timestamp) outlet.push_sample([trialnum, facehouse + 1, girlboy + 1], timestamp) mywin.flip() # offset core.wait(soa) mywin.flip() if len(event.getKeys()) > 0 or (time() - start) > record_duration: break event.clearEvents() # Cleanup mywin.close()
# the content-type to EEG, 8 channels, 100 Hz, and float-valued data) The # last value would be the serial number of the device or some other more or # less locally unique identifier for the stream as far as available (you # could also omit it but interrupted connections wouldn't auto-recover) fs = 1000 info = StreamInfo('BioSemi', 'EEG', 2) # next make an outlet outlet = StreamOutlet(info) print("now sending data...") n_samples = fs * 100 recorder = np.zeros((n_samples, 2)) t = 0 t_start = local_clock() while True: if t > n_samples - 2: break clock = local_clock() if clock - t_start > (t+1)/fs: # make a new random 8-channel sample; this is converted into a # pylsl.vectorf (the data type that is expected by push_sample) second = int(clock) mysample = [clock, int(second%5 == 0) if second - t_start > 5 else -1] t += 1 outlet.push_sample(mysample, clock) recorder[t] = mysample print(local_clock() - t_start) np.save('sent_data.npy', recorder)
pts3D = affine_mat.dot(pts4D.T).T #pts3D = guessed_rot.dot(pts3D.T).T print("[3D POINTS]", pts3D) #rint("[ORIGINAL for above]", pts_without_affine) else: pts3D = np.array([[0, 0, 0]], dtype=float) print("[3D POINTS]", pts3D) # display nice images if args["display"] > 0: cv2.imshow("<--Left | Right-->", cv2.hconcat([imgs_to_show["left"], imgs_to_show["right"]])) # send data to lsl data_to_send = list(pts3D.reshape(-1)) #flatten to 1D data_to_send += [0.0] * (n_channels - len(data_to_send) ) #pad with zeros to fill all channels outlet.push_sample(data_to_send) # update the FPS counter fps.update() # stop the timer and display FPS fps.stop() print("[INFO] elasped time: {:.2f}".format(fps.elapsed())) print("[INFO] approx. FPS: {:.2f}".format(fps.fps())) # cleanup cv2.destroyAllWindows() vs.stop()
def run_eeg_sim(freq=None, chunk_size=0, source_buffer=None, name='example', labels=None): """ Make LSL Stream Outlet and send source_buffer data or simulate sin data :param n_channels: number of channels :param freq: frequency :param chunk_size: chunk size :param source_buffer: buffer for samples to push (if it's None sine data will be sended) :param name: name of outlet :return: """ # default freq freq = freq or 500 # labels and n_channels labels = labels or ch_names32 n_channels = len(labels) if labels is not None else 32 # stream info info = StreamInfo(name=name, type='EEG', channel_count=n_channels, nominal_srate=freq, channel_format='float32', source_id='myuid34234') # channels labels (in accordance with XDF format, see also code.google.com/p/xdf) chns = info.desc().append_child("channels") for label in labels: ch = chns.append_child("channel") ch.append_child_value("label", label) outlet = StreamOutlet(info, chunk_size=chunk_size) # send data and print some info every 5 sec print('now sending data...') t0 = time.time() t = t0 c = 1 ampl = 10 freqs = np.arange(n_channels)*5 + 10 sample = np.zeros((n_channels,)) if source_buffer is not None: source_buffer = np.concatenate([source_buffer.T, source_buffer.T[::-1]]).T while True: # if source_buffer is not None get sample from source_buffer # else simulate sin(a*t)*sin(b*t) if source_buffer is not None: sample[:source_buffer.shape[0]] = source_buffer[:, c % source_buffer.shape[1]] else: sample = np.sin(2 * np.pi * time.time() * 50) * 0 + np.sin(2 * np.pi * time.time() * freqs) # sample *= (np.sin(2 * np.pi * time.time() * 0.25) + 1) * ampl sample *= c % (500 * 4) * ampl if c % 20000 > 10000: sample[0] *= 1 # push sample end sleep 1/freq sec outlet.push_sample(sample) time.sleep(1. / freq) # print time, frequency and samples count every 5 sec if c % (freq * 5) == 0: t_curr = time.time() print('t={:.1f}, f={:.2f}, c={}'.format(t_curr - t0, 1. / (t_curr - t) * freq * 5, c)) t = t_curr c += 1 pass
channels.append_child(c) # Create outlets mocap_outlet = StreamOutlet(stream_info_mocap) print("now sending data...") while True: # send fake Muse/EEG data # make a new random 8-channel sample; this is converted into a # pylsl.vectorf (the data type that is expected by push_sample) mymusesample = [rand(), rand(), rand(), rand(), rand(), rand(), rand(), rand()] # now send it and wait for a bit muse_outlet.push_sample(mymusesample) # send fake HRV data myhrvsample = [rand(), rand(), rand()] hrv_outlet.push_sample(myhrvsample) # send fake MoCap data mymocapsample = [] for i in range(0,mocap_channels*mocap_sample_size): x = rand() mymocapsample.append(x) mocap_outlet.push_sample(mymocapsample)
global last_bpm, last_rr bpm = ord(data[1]) last_bpm = bpm print "BPM:", bpm, "- time: %.2f"%(time.time()-t0), # if retrieved data is longer, we got RR interval, take the first if len(data) >= 4: # UINT16 format rr = struct.unpack('H', data[2:4])[0] # units of RR interval is 1/1024 sec rr = rr/1024. last_rr = rr print "- RR:", rr, print "" hrm.delegate.handleNotification = print_hr while True: hrm.waitForNotifications(1./samplingrate) outlet_hr.push_sample([last_bpm]) outlet_rr.push_sample([last_rr]) finally: if hrm: # way get "" try: hrm.disconnect() print "disconnected" except: # may get "ValueError: need more than 1 value to unpack"?? print "error while disconnecting"
import sys; sys.path.append('..') # help python find pylsl relative to this example program from pylsl import StreamInfo, StreamOutlet, local_clock import random import time # first create a new stream info (here we set the name to BioSemi, the content-type to EEG, 8 channels, 100 Hz, and float-valued data) # The last value would be the serial number of the device or some other more or less locally unique identifier for the stream as far as available (you could also omit it but interrupted connections wouldn't auto-recover). info = StreamInfo('BioSemi','EEG',8,100,'float32','myuid2424'); # append some meta-data info.desc().append_child_value("manufacturer","BioSemi") channels = info.desc().append_child("channels") for c in ["C3","C4","Cz","FPz","POz","CPz","O1","O2"]: channels.append_child("channel").append_child_value("name",c).append_child_value("unit","microvolts").append_child_value("type","EEG") # next make an outlet; we set the transmission chunk size to 32 samples and the outgoing buffer size to 360 seconds (max.) outlet = StreamOutlet(info,32,360) print("now sending data...") while True: # make a new random 8-channel sample; this is converted into a pylsl.vectorf (the data type that is expected by push_sample) mysample = [random.random(),random.random(),random.random(),random.random(),random.random(),random.random(),random.random(),random.random()] # get a time stamp in seconds (we pretend that our samples are actually 125ms old, e.g., as if coming from some external hardware) stamp = local_clock()-0.125 # now send it and wait for a bit outlet.push_sample(mysample,stamp) time.sleep(0.01)
"""Example program to demonstrate how to send string-valued markers into LSL.""" import random import time from pylsl import StreamInfo, StreamOutlet # first create a new stream info (here we set the name to MyMarkerStream, # the content-type to Markers, 1 channel, irregular sampling rate, # and string-valued data) The last value would be the locally unique # identifier for the stream as far as available, e.g. # program-scriptname-subjectnumber (you could also omit it but interrupted # connections wouldn't auto-recover). The important part is that the # content-type is set to 'Markers', because then other programs will know how # to interpret the content info = StreamInfo('MyMarkerStream', 'Markers', 1, 0, 'string', 'myuidw43536') # next make an outlet outlet = StreamOutlet(info) print("now sending markers...") markernames = ['Test', 'Blah', 'Marker', 'XXX', 'Testtest', 'Test-1-2-3'] while True: # pick a sample to send an wait for a bit outlet.push_sample([random.choice(markernames)]) time.sleep(random.random()*3)
###define the number of trials, and tones per trial### trials = 10 low_rate = 0.8 high_rate = 0.2 low_tone = np.zeros(int(trials*low_rate)) high_tone = np.ones(int(trials*high_rate)) low_tone_list = low_tone.tolist() high_tone_list = high_tone.tolist() tones = low_tone_list + high_tone_list shuffle(tones) ###wait for button press to start experiment### pygame.mixer.music.load('/home/pi/Experiments/Sounds/ready.wav') timestamp = local_clock() outlet.push_sample([7], timestamp) GPIO.output(pi2trig(7),1) pygame.mixer.music.play() while pygame.mixer.music.get_busy() == True: continue time.sleep(1) GPIO.output(pi2trig(255),0) GPIO.wait_for_edge(pin,GPIO.RISING) time.sleep(1) GPIO.wait_for_edge(pin,GPIO.RISING) time.sleep(1) GPIO.wait_for_edge(pin,GPIO.RISING) pygame.mixer.music.load('/home/pi/Experiments/Sounds/countdown_10.wav') timestamp = local_clock() outlet.push_sample([9], timestamp)
class AlphaScanDevice: def __init__(self): ############################################################################### # TCP Settings ############################################################################### self.TCP_IP = '' self.TCP_PORT = 50007 #CONFIGURABLE self.user_input = '' self.data = '' ############################################################################### # UDP Settings ############################################################################### self.UDP_IP = "192.168.1.17" #This gets over written dynamically self.UDP_PORT = 2390 #CONFIGURABLE self.num = 10 self.MESSAGE = chr(self.num) self.num_iter = self.num * 100 self.skips = 0 self.reads = 0 self.DEV_streamActive = Event() self.DEV_streamActive.clear() self.DEV_log = list() self.inbuf = list() self.unknown_stream_errors = 0 self.begin = 0 self.end = 0 self.IS_CONNECTED = False self.time_alpha = 0 self.time_beta = 0 self.time_intervals = list() self.time_interval_count = 0 self.sqwave = list() self.info = StreamInfo('AlphaScan', 'EEG', 8, 100, 'float32', 'uid_18') self.outlet = StreamOutlet(self.info) self.mysample = [ random.random(), random.random(), random.random(), random.random(), random.random(), random.random(), random.random(), random.random() ] self.SysParams = { 'vcc': None, 'free_heap': None, 'mcu_chip_id': None, 'sdk_ver': None, 'boot_ver': None, 'boot_mode': None, 'cpu_freq_mhz': None, 'flash_chip_id': None, 'flash_chip_real_size': None, 'flash_chip_size': None, 'flash_chip_speed': None, 'flash_chip_mode': None, 'free_sketch_space': None } # Debug port variables self.debug_port_open = False self.debug_port_no = 2391 #self.open_debug_port() def open_debug_port(self): try: self.debug_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) self.debug_sock.bind(('', self.debug_port_no)) self.debug_sock.settimeout(0) self.debug_port_open = True return True except: return False def close_debug_port(self): try: self.debug_sock.close() self.debug_port_open = False return True except: return False def read_debug_port(self): if not self.debug_port_open: return False try: r = self.debug_sock.recv(1024) if len(r) > 0: return r except: return False def init_TCP(self): ############################################################################### # Initialize TCP Port ############################################################################### self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self.s.bind((self.TCP_IP, self.TCP_PORT)) # error: [Errno 10048] Only one usage of each socket address (protocol/network address/port) is normally permitted self.s.settimeout(10) self.s.listen(1) try: self.conn, addr = self.s.accept() self.conn.settimeout(.05) # TODO maybe want to make this smaller time.sleep(0.01) # time for device to respond self.UDP_IP = addr[0] # TODO this should say TCP_IP self.IS_CONNECTED = True return True except: self.IS_CONNECTED = False self.close_TCP() # cleanup socket return False def close_TCP(self): ################################################################################ # Close TCP connection ################################################################################ try: self.conn.close() #conn might not exist yet self.s.close() self.IS_CONNECTED = False except: pass def close_UDP(self): ################################################################################ # Close UDP connection ################################################################################ try: self.sock.close() except: pass def DEV_printStream(self): global sqwave ############################################################################### # UDP Stream thread target ############################################################################### self.skips = 0 self.reads = 0 self.unknown_stream_errors = 0 self.time_interval_count = 0 self.inbuf = list() self.time_intervals = list() self.DEV_streamActive.set() self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) self.sock.bind(('', self.UDP_PORT)) self.sock.settimeout(0) while self.DEV_streamActive.is_set(): try: self.data = self.sock.recv(128) self.inbuf += [ord(self.data[27:])] self.sqwave += [self.data] self.outlet.push_sample(self.mysample) self.reads += 1 #TODO count interval self.count_time_interval() except socket.error as e: if e.errno == 10035: self.skips += 1 elif e.errno == 9: self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) self.sock.bind(('', self.UDP_PORT)) self.sock.settimeout(0) except: self.unknown_stream_errors += 1 def DEV_printTCPStream_OLD(self): global sqwave ############################################################################### # UDP Stream thread target ############################################################################### self.reads = 0 self.unknown_stream_errors = 0 self.time_interval_count = 0 self.rx_count = 0 self.pre_rx = 0 self.timeout_count = 0 self.test_inbuf = list() self.inbuf = list() self.time_intervals = list() self.DEV_streamActive.set() self.error_array = list() deviceData = [0 for i in range(8)] # clear tcp inbuf #self.conn.recv(2048) # this is not a proper flush, rx size should be set to match self.flush_TCP() diff = 3 while self.DEV_streamActive.is_set(): try: self.pre_rx += 1 # TODO Receive and unpack sample from TCP connection ready = select.select([self.conn], [], [], 0) if (ready[0]): self.data = self.conn.recv(24 + diff) self.test_inbuf += [self.data] self.rx_count += 1 #self.inbuf += [ord(self.data)] # #TODO this is suspect since ord should only take 1 character, and will fill quick # Populate fresh channel data into self.mysample for j in xrange(8): deviceData[j] = [ self.data[diff + (j * 3):diff + (j * 3 + 3)] ] val = 0 for i in range(3): n = deviceData[j][0][i] try: val ^= ord(n) << ((2 - i) * 8) except ValueError as e: print("value error", e) except TypeError as e: print("value error", e) val = twos_comp(val) self.mysample[j] = val self.sqwave += [self.data] self.outlet.push_sample(self.mysample) self.reads += 1 #TODO count interval self.count_time_interval() except socket.timeout: self.timeout_count += 1 def DEV_printTCPStream(self): global sqwave ############################################################################### # UDP Stream thread target ############################################################################### self.reads = 0 self.unknown_stream_errors = 0 self.time_interval_count = 0 self.rx_count = 0 self.pre_rx = 0 self.timeout_count = 0 self.invalid_start = 0 self.test_inbuf = list() self.inbuf = list() self.time_intervals = list() self.DEV_streamActive.set() self.error_array = list() deviceData = [0 for i in range(8)] # clear tcp inbuf #self.conn.recv(2048) # this is not a proper flush, rx size should be set to match self.flush_TCP() diff = 3 while self.DEV_streamActive.is_set(): try: self.pre_rx += 1 # TODO Receive and unpack sample from TCP connection ready = select.select([self.conn], [], [], 0) if (ready[0]): self.data = self.conn.recv(24 + diff) self.rx_count += 1 if (len(self.data) == 27): if (ord(self.data[0]) == 0xf and ord(self.data[1]) == 0xf and ord(self.data[2]) == 0xf): self.test_inbuf += [self.data] #self.inbuf += [ord(self.data)] # #TODO this is suspect since ord should only take 1 character, and will fill quick # Populate fresh channel data into self.mysample for j in xrange(8): deviceData[j] = [ self.data[diff + (j * 3):diff + (j * 3 + 3)] ] val = 0 for s, n in list(enumerate(deviceData[j][0])): try: val ^= ord(n) << ((2 - s) * 8) except ValueError as e: print("value error", e) except TypeError as e: print("value error", e) val = twos_comp(val) self.mysample[j] = val self.sqwave += [self.data] self.outlet.push_sample(self.mysample) self.reads += 1 #TODO count interval self.count_time_interval() else: self.invalid_start += 1 except socket.timeout: self.timeout_count += 1 #============================================================================== # except socket.error as e: # self.error_array += [e] #============================================================================== #============================================================================== # except: # self.unknown_stream_errors += 1 #============================================================================== def generic_tcp_command_BYTE(self, cmd, extra=''): ############################################################################### # Get adc status ############################################################################### if not self.IS_CONNECTED or (self.DEV_streamActive.is_set() and "ADC_start_stream" not in cmd): return "ILLEGAL: Must be connected and not streaming" try: self.flush_TCP() self.conn.send( (chr(TCP_COMMAND[cmd]) + extra + chr(127)).encode('utf-8')) time.sleep(0.05) r_string = self.conn.recv(64) except: r_string = 'no_response' return r_string def generic_tcp_command_OPCODE(self, opcode, extra=''): ############################################################################### # Get adc status ############################################################################### self.flush_TCP() self.conn.send((chr(opcode) + extra + chr(127)).encode('utf-8')) time.sleep(0.05) try: r_string = self.conn.recv(72) except: r_string = 'no_response' return r_string def generic_tcp_command_STRING(self, txt): ############################################################################### # Get adc status ############################################################################### self.flush_TCP() self.conn.send((txt + chr(127)).encode('utf-8')) time.sleep(0.05) try: r_string = self.conn.recv(64) except: r_string = 'no_response' return r_string def read_tcp(self, num_bytes=64): try: r_string = self.conn.recv(num_bytes) except: r_string = 'no_response' return r_string def sync_adc_registers(self): ############################################################################### # Get all registers and return as list of lists ############################################################################### return [[True if i % 2 == 0 else False for i in range(8)] for j in range(24)] def initiate_UDP_stream(self): ############################################################################### # Begin UDP adc stream ############################################################################### # Start UDP rcv thread self.LSL_Thread = Thread(target=self.DEV_printStream) self.LSL_Thread.start() self.DEV_streamActive.set() # Send command to being self.begin = time.time() return self.generic_tcp_command_BYTE("ADC_start_stream") def initiate_TCP_stream(self): ############################################################################### # Begin TCP adc stream ############################################################################### # Start TCP rcv thread self.LSL_Thread = Thread(target=self.DEV_printTCPStream) self.LSL_Thread.start() self.DEV_streamActive.set() # Send command to being self.begin = time.time() return self.generic_tcp_command_OPCODE(0x03) # begins streaming TCP def initiate_TCP_stream_direct(self): ############################################################################### # Begin TCP adc stream ############################################################################### self.DEV_streamActive.set() # Send command to being self.begin = time.time() self.generic_tcp_command_OPCODE(0x03) self.DEV_printTCPStream() def terminate_UDP_stream(self): ############################################################################### # End UDP adc stream ############################################################################### #TODO NEED terminatino ACK, if NACK then resend termination command try: self.sock.sendto(('ttt'.encode('utf-8')), (self.UDP_IP, self.UDP_PORT)) except: #Make specific to error: [Errno 9] Bad file descriptor self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) #self.sock.setsockopt(socket.SOL_SOCKET,socket.SO_RCVBUF,8192) self.sock.bind(('', self.UDP_PORT)) self.sock.settimeout(0) self.sock.sendto(('ttt'.encode('utf-8')), (self.UDP_IP, self.UDP_PORT)) self.end = time.time() self.DEV_streamActive.clear() time.sleep(0.01) self.sock.close() drops = self.get_drop_rate() if not drops: avail = 0 else: avail = ((1.0 - ((drops * 1.0) / len(self.inbuf))) * 100.0) pckt_rate = len(self.inbuf) / (self.end - self.begin) return "Not Streaming", str(pckt_rate), str(avail), str(len( self.inbuf)), str(drops) def terminate_TCP_stream(self): ############################################################################### # End UDP adc stream ############################################################################### #TODO NEED terminatino ACK, if NACK then resend termination command try: self.generic_tcp_command_OPCODE(0xf) except: #Make specific to error: [Errno 9] Bad file descriptor print("Exception occured upon attempting stream termination") self.end = time.time() self.DEV_streamActive.clear() time.sleep(0.01) drops = self.get_drop_rate() if not drops: avail = 0 else: avail = ((1.0 - ((drops * 1.0) / len(self.inbuf))) * 100.0) pckt_rate = len(self.inbuf) / (self.end - self.begin) return "Not Streaming", str(pckt_rate), str(avail), str(len( self.inbuf)), str(drops) def flush_TCP(self): ############################################################################### # Clear TCP input buffer ############################################################################### try: self.conn.recv( self.conn.getsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF)) except: pass def flush_UDP(self): ############################################################################### # Clear udp input buffer ############################################################################### try: self.sock.recv(65535) except: pass def update_adc_registers(self, reg_to_update): #send adc registers to update over tcp self.flush_TCP() self.conn.send('u' + ''.join([str(t) for t in reg_to_update]) + chr(127).encode('utf-8')) time.sleep(0.01) # Time for device to respond return def update_command_map(self): # create csv string from command map dict if not self.IS_CONNECTED or self.DEV_streamActive.is_set(): return "ILLEGAL: Must be connected and not streaming" self.flush_TCP() self.conn.send((chr(TCP_COMMAND["GEN_update_cmd_map"]) + "_begin_cmd_map_" + str(TCP_COMMAND) + ', ' + chr(127)).encode('utf-8')) #NOTE: comma is necessary time.sleep(0.01) try: r_string = self.conn.recv(64) except: r_string = 'no_response' return r_string def get_drop_rate(self): i = 0 drops = 0 total_pckts = len(self.inbuf) if total_pckts == 0: return False for n in self.inbuf: if i != n: drops += 1 i = n if i == 255: #wrap around i = 0 else: i += 1 # return success rate return drops def broadcast_disco_beacon(self): # send broadcast beacon for device to discover this host s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) s.sendto( 'alpha_scan_beacon_xbx_' + str(self.TCP_PORT) + '_xex', ('255.255.255.255', self.UDP_PORT) ) #TODO this subnet might not work on all LAN's (see firmware method) # send desired TCP port in this beacon s.close() def listen_for_device_beacon(self): try: s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.bind(('', self.UDP_PORT)) s.settimeout( 0.05) #TODO this blocking causes slight lag while active data, addr = s.recvfrom(1024) s.close() if "I_AM_ALPHA_SCAN" in data: return True except: pass return False def connect_to_device(self): self.broadcast_disco_beacon() return self.init_TCP() def set_udp_delay(self, delay): extra = "_b_" + str(delay) + "_e_" return self.generic_tcp_command_BYTE("ADC_set_udp_delay", extra) def parse_sys_commands(self): #read tcp buff buf = self.read_tcp(1024) #check for complete system params respons if ('begin_sys_commands' not in buf) or ('end_sys_commands' not in buf): return False #else begin parsing buf_arr = buf.split(",") for e in buf_arr: for k in self.SysParams.keys(): if k in e: self.SysParams[k] = e[e.find(":") + 1:] break return True def ADC_send_hex_cmd(self, cmd): self.generic_tcp_command_BYTE("ADC_send_hex_cmd", chr(cmd)) def count_time_interval(self): self.time_beta = time.time() self.time_interval_count += 1 try: if (self.inbuf[-1] == (self.inbuf[-2] + 1)): self.time_intervals += [self.time_beta - self.time_alpha] except: pass self.time_alpha = self.time_beta
Rf = 287.0 elif (Range == 2): # kohm Rf = 1000.0 elif (Range == 3): # kohm Rf = 3300.0 else: Rf = 0 print("error") # convert GSR to kohm value gsr_to_volts = (GSR_raw & 0x3fff) * (3.0 / 4095.0) GSR_ohm = Rf / ((gsr_to_volts / 0.5) - 1.0) # convert PPG to milliVolt value PPG_mv = PPG_raw * (3000.0 / 4095.0) timestamp = timestamp0 + timestamp1 * 256 + timestamp2 * 65536 sensor_time = timestamp print("0x%02x\t\t%5d,\t%4d,\t%4d" % (packettype[0], timestamp, GSR_ohm, PPG_mv)) ppgOutlet.push_sample([PPG_mv]) gsrOutlet.push_sample([GSR_ohm]) finally: # send stop streaming command print("closing procedure") send_stop_streaming_command()
val = patch.getfloat('control', name) if val is None: continue # it should be skipped when not present in the ini or Redis if val == previous_val[name]: continue # it should be skipped when identical to the previous value previous_val[name] = val if lsl_format == 'value': # map the Redis values to LSL marker values # the scale and offset options are control channel specific and can be changed on the fly scale = patch.getfloat('scale', name, default=127) offset = patch.getfloat('offset', name, default=0) val = EEGsynth.rescale(val, slope=scale, offset=offset) # format the value as a string marker = '%g' % (val) else: marker = name with lock: monitor.debug(marker) outlet.push_sample([marker]) except KeyboardInterrupt: monitor.success('Closing threads') for thread in trigger: thread.stop() r.publish('OUTPUTLSL_UNBLOCK', 1) for thread in trigger: thread.join() sys.exit()
def present(duration=120, n_trials=10, iti=0.3, soa=0.2, jitter=0.2, secs=0.2, volume=0.8, random_state=None): # Create markers stream outlet info = StreamInfo('Markers', 'Markers', 1, 0, 'int32', 'myuidw43536') outlet = StreamOutlet(info) np.random.seed(random_state) markernames = [1, 2] start = time.time() # Set up trial parameters record_duration = np.float32(duration) # Initialize stimuli aud1 = sound.Sound('C', octave=5, sampleRate=44100, secs=secs) aud1.setVolume(volume) aud2 = sound.Sound('D', octave=6, sampleRate=44100, secs=secs) aud2.setVolume(volume) auds = [aud1, aud2] # Setup trial list sound_ind = np.random.binomial(1, 0.25, n_trials) itis = iti + np.random.rand(n_trials) * jitter trials = DataFrame(dict(sound_ind=sound_ind, iti=itis)) trials['soa'] = soa trials['secs'] = secs for ii, trial in trials.iterrows(): # Intertrial interval time.sleep(trial['iti']) # Select and play sound ind = int(trial['sound_ind']) auds[ind].stop() auds[ind].play() # Send marker timestamp = time.time() outlet.push_sample([markernames[ind]], timestamp) # Offset #time.sleep(soa) #if (time.time() - start) > record_duration: # break # offset core.wait(soa) if len(event.getKeys()) > 0 or (time.time() - start) > record_duration: break event.clearEvents() #if len(event.getKeys()) > 0 or (time() - start) > record_duration: # break #event.clearEvents() return trials
epoch = Epoch[-int(sampling_rate * epoch_length + 1):-1, :] filtered_data = filtering(epoch, sampling_rate, low, high) epoch = minmax(np.transpose(filtered_data)) corr[0] = correlate(epoch, n_components, reference1) corr[1] = correlate(epoch, n_components, reference2) corr[2] = correlate(epoch, n_components, reference3) print(Fre[corr.index(max(corr))]) if max(Corr) == deciding_num: pass else: Corr[corr.index( max(corr))] = Corr[corr.index(max(corr))] + 1 time.sleep(epoch_step) print(Corr) OUT = Corr.index(max(Corr)) if 0 == OUT: outlet.push_sample(['Left']) # sending elif 1 == OUT: outlet.push_sample(['Center']) # sending elif 2 == OUT: outlet.push_sample(['Right']) # sending print('sended') Pre.append(corr.index(max(corr))) break time.sleep(0.5) if len(Real) != 0: if Real[-1] == 'end': break
thisExp.addData('keyPressRun.keys',keyPressRun.keys) if keyPressRun.keys != None: # we had a response thisExp.addData('keyPressRun.rt', keyPressRun.rt) thisExp.nextEntry() # the Routine "instructions" was not non-slip safe, so reset the non-slip timer routineTimer.reset() # ------Prepare to start Routine "startWait3000"------- t = 0 startWait3000Clock.reset() # clock frameN = -1 continueRoutine = True routineTimer.add(3.000000) # update component parameters for each repeat # Send experiment onset marker to LSL outlet.push_sample('S') # keep track of which components have finished startWait3000Components = [preTrialScreen, preTrialText] for thisComponent in startWait3000Components: if hasattr(thisComponent, 'status'): thisComponent.status = NOT_STARTED # -------Start Routine "startWait3000"------- while continueRoutine and routineTimer.getTime() > 0: # get current time t = startWait3000Clock.getTime() frameN = frameN + 1 # number of completed frames (so 0 is the first frame) # update/draw components on each frame # *preTrialScreen* updates
def sendingData(): # first create a new stream info (here we set the name to BioSemi, # the content-type to EEG, 16 channels, 250 Hz, and float-valued data) The # last value would be the serial number of the device or some other more or # less locally unique identifier for the stream as far as available (you # could also omit it but interrupted connections wouldn't auto-recover). info = StreamInfo('BioSemi', 'EEG', channels, srate, 'float32', 'myuid34234') # next make an outlet outlet = StreamOutlet(info) print("now sending data...") alpha_low_bound = 8 beta_low_bound = 15 delta_low_bound = 0 theta_low_bound = 4 # y = np.sin(np.ones((250,)) * (x * (alpha_low_bound+alpha_random)))*8 x = np.linspace(0, 2 * np.pi, 250) # eeg_bands = {'Delta': (0, 4), # 'Theta': (4, 7), # 'Alpha': (8, 15), # 'Beta': (16, 31)} baseline_alpha = np.sin(x * (alpha_low_bound + 3)) * 4 baseline_beta = np.sin(x * (beta_low_bound + 8)) * 4 baseline_delta = np.sin(x * (delta_low_bound + 2)) * 4 baseline_theta = np.sin(x * (theta_low_bound + 1.5)) * 4 baseline = np.sum(np.array( [baseline_alpha, baseline_beta, baseline_delta, baseline_theta]).T, axis=1) real_fake_alpha = np.sin(x * (alpha_low_bound + 3)) * 6 real_fake_beta = np.sin(x * (beta_low_bound + 8)) * 2 real_fake_delta = np.sin(x * (delta_low_bound + 2)) * 18 real_fake_theta = np.sin(x * (theta_low_bound + 1.5)) * 0 real_fake_data = np.sum(np.array( [real_fake_alpha, real_fake_beta, real_fake_delta, real_fake_theta]).T, axis=1) # Psuedo-randomized frequency # alpha_random = random.random() * 7 # beta_random = random.random() * 10 # delta_random = random.random() * 4 # theta_random = random.random() * 3 # alpha = np.sin(np.ones((250,)) * np.pi/(alpha_low_bound+alpha_random) # beta = np.sin(np.ones((250,)) * np.pi/(beta_low_bound+beta_random)) # delta = np.sin(np.ones((250,)) * np.pi/(delta_low_bound+delta_random)) # theta = np.sin(np.ones((250,)) * np.pi/(theta_low_bound+theta_random)) count = 0 while True: # make a new random 16-channel sample; this is converted into a # pylsl.vectorf (the data type that is expected by push_sample) if count < 4500: baseline_current = baseline[count % 250] mysample = list( np.full(shape=channels, fill_value=baseline_current, dtype=np.int)) else: real_fake_data_current = real_fake_data[count % 250] mysample = list( np.full(shape=channels, fill_value=real_fake_data_current, dtype=np.int)) # now send it and wait for a bit outlet.push_sample(mysample) time.sleep(0.004) count += 1
def present(duration=120, width=500, height=400): # create info = StreamInfo('Markers', 'Markers', 1, 0, 'int32', 'myuidw43536') # next make an outlet outlet = StreamOutlet(info) markernames = [1, 2, 3] start = time() n_trials = floor(duration / 3.5) iti = 1 soa = 2.5 jitter = 0.3 record_duration = np.float32(duration) # Setup log position = np.random.randint(3, size=n_trials) trials = DataFrame(dict(position=position, timestamp=np.zeros(n_trials))) mywin = visual.Window([width, height], monitor="testMonitor", units="deg", fullscr=True) word_files = glob(r'stimulus_presentation\words\*.txt') negative = open(word_files[0]) neutral = open(word_files[1]) positive = open(word_files[2]) negative_words = list(reader(negative, delimiter=' ')) neutral_words = list(reader(neutral, delimiter=' ')) positive_words = list(reader(positive, delimiter=' ')) # converts from multilist to list negative_words = [ item for negative_list in negative_words for item in negative_list ] neutral_words = [ item for neutral_list in neutral_words for item in neutral_list ] positive_words = [ item for positive_list in positive_words for item in positive_list ] for ii, trial in trials.iterrows(): # inter trial interval core.wait(iti + np.random.rand() * jitter) # onset pos = trials['position'].iloc[ii] if pos == 0: word = choice(negative_words) elif pos == 1: word = choice(neutral_words) else: word = choice(positive_words) text = visual.TextStim(win=mywin, text=word, units='pix', font='Arial', height=175, alignHoriz='center') text.draw() timestamp = time() outlet.push_sample([markernames[pos]], timestamp) #q.put((markernames[pos], timestamp)) #test - hangs after showing 5th word when enabled mywin.flip() # offset core.wait(soa) mywin.flip() if len(event.getKeys()) > 0 or (time() - start) > record_duration: break event.clearEvents() # Cleanup mywin.close()
from kivy.app import App from kivy.uix.video import Video import sys import time from pylsl import StreamInfo, StreamOutlet try: input = raw_input except NameError: pass info = StreamInfo('Ganglion_EEG', 'Markers', 1, 0.0, 'int32', 'marker') outlet = StreamOutlet(info) outlet.push_sample([-1], time.time()) _ = input('\nStart recording and press Enter to start') if len(sys.argv) != 2: print("usage: %s file" % sys.argv[0]) sys.exit(1) class VideoApp(App): def build(self): self.v = Video(source=sys.argv[1], state='play') self.v.bind(state=self.update_state) return self.v def update_state(self, *args): if self.v.state == 'stop': outlet.push_sample([2], time.time()) exit()
def present(data, val_col_name, arous_col_name, duration=120, width=1000, height=800): # Create markers stream outlet #info = StreamInfo('Markers', 'Markers', 1, 0, 'int32', 'myuidw43536') info = StreamInfo('Markers', 'Markers', 2, 0, 'float32', 'myuidw43536') outlet = StreamOutlet(info) #markernames = [1, 2] start = time() # Set up trial parameters #n_trials = 2010 iti = 1 soa = 2.5 jitter = 0.3 record_duration = np.float32(duration) # Setup trial list #image_type = np.random.binomial(1, 0.5, n_trials) #trials = DataFrame(dict(image_type=image_type, # timestamp=np.zeros(n_trials))) #randomly shuffle dataframe data = data.sample(frac=1) #set up psychopy window mywin = visual.Window([width, height], monitor='testMonitor', units='deg', winType='pygame', fullscr=False) #get path from theme def get_path(theme): path = 'images/' + row['Theme'].strip() + '.jpg' return path #load image from path def load_image(path): return visual.ImageStim(win=mywin, image=path) #for ii, trial in trials.iterrows(): for ii, row in data.iterrows(): theme = row['Theme'] arousal = row[arous_col_name] valence = row[val_col_name] # Intertrial interval core.wait(iti + np.random.rand() * jitter) #get path from dataset im_path = get_path(theme) #get image image = load_image(im_path) image.draw() # Send marker timestamp = time() #outlet.push_sample([markernames[label]], timestamp) outlet.push_sample([valence, arousal], timestamp) mywin.flip() # offset core.wait(soa) mywin.flip() if len(event.getKeys()) > 0 or (time() - start) > record_duration: break event.clearEvents() # Cleanup mywin.close()
class SerialPort: def __init__(self, port, baud): self.port = serial.Serial(port, baud) self.lsl = False self.outlet = None self.port.close() if not self.port.isOpen(): self.port.open() def port_open(self): if not self.port.isOpen(): self.port.open() def port_close(self): self.port.close() def send_data(self, command): self.port.write(command.encode()) def read_data(self): data = self.port.readline() return data def IEMG(self): feedback = [] self.port.write("AT+IEMGSTRT\r\n".encode()) print("Start to acquire IEMG signal\n") self.start_lsl() #name = ['seq', 'ch1', 'ch2', 'ch3', 'ch4', 'ch5', 'ch6', 'ch7', 'ch8', 'ch9', 'ch10', # 'ch11', 'ch12', 'ch13', 'ch14', 'ch15', 'ch16', 'ch17', 'ch18', 'ch19', 'ch20', # 'ch21', 'ch22', 'ch23', 'ch24', 'ch25', 'ch26', 'ch27', 'ch28', 'ch29', 'ch30', # 'ch31', 'ch32', 'Tri1', 'Tri2', 'Tri3'] #csv_writer.writerow(name) try: while True: count = self.port.inWaiting() if count > 0: answer = self.port.read(count) data = [] for i in range(len(answer)): data.append(answer[i]) data = np.hstack((feedback, data)) feedback = self.save(data, 0x71) # self.save(data, 0x71) except KeyboardInterrupt: self.stop() def EMG(self): feedback = [] self.port.write("AT+EMGSTRT\r\n".encode()) print("Start to acquire raw EMG signal\n") self.start_lsl() #name = ['seq', 'ch1', 'ch2', 'ch3', 'ch4', 'ch5', 'ch6', 'ch7', 'ch8', 'ch9', 'ch10', # 'ch11', 'ch12', 'ch13', 'ch14', 'ch15', 'ch16', 'ch17', 'ch18', 'ch19', 'ch20', # 'ch21', 'ch22', 'ch23', 'ch24', 'ch25', 'ch26', 'ch27', 'ch28', 'ch29', 'ch30', # 'ch31', 'ch32', 'Tri1', 'Tri2', 'Tri3'] #csv_writer.writerow(name) try: while True: count = self.port.inWaiting() if count > 0: answer = self.port.read(count) data = [] for i in range(len(answer)): data.append(answer[i]) data = np.hstack((feedback, data)) feedback = self.save(data, 0x74) # self.save(data, 0x71) except KeyboardInterrupt: self.stop() def stop(self): self.port.write("AT+STOP\r\n".encode()) print("Stop Successfully!\n") def start_lsl(self): self.outlet = StreamOutlet( StreamInfo('SMK Array EMG system', 'EMG', 35, 500, 'int16', 'mysmk')) self.lsl = True def save(self, data, id): data_len = len(data) i = 0 while (i < data_len - 1): if data[i] == id and i + 70 <= data_len: data_set = data[i:i + 70] # seq = data_set[1] * 256 + data_set[2] iemg = data_set[3:67] trigger = [] trigger.append(data_set[67]) trigger.append(data_set[68]) trigger.append(data_set[69]) iemg_value = [] for j, k in zip(iemg[0::2], iemg[1::2]): iemg_value.append(j * 256 + k) DATA = np.hstack((iemg_value, trigger)) DATA_str = list(map(lambda x: str(x), DATA)) if trigger[0] == 0 and trigger[1] == 0 and trigger[2] == 0: print(DATA) try: # csv_writer.writerow(DATA_str) if self.lsl: self.outlet.push_sample(DATA) except Exception as e: raise e i = i + 70 elif data[i] == id and i + 70 > data_len: return data[i:data_len] else: i = i + 1
file = srcPath / "UJuan_S01_T01_BloodValidation_raw.edf" # srcPath = Path(r'C:\Users\asus\OneDrive - purdue.edu\RealtimeProject\Experiments3-Data\TestsWithVideo\Eyes-open-close-test\edf').resolve() # file = srcPath / "UJuan_S03_T01_Eyes-open-close_raw.edf" # srcPath = Path('./../deep_models/raw-data').resolve() # file = srcPath / "Juan_S04_T01_Low_raw.edf" # srcPath = Path(r'C:\Users\asus\OneDrive - purdue.edu\RealtimeProject\Experiments3-Data\VeinLigationSimulator-Tests\Jing\11-17-20\edf').resolve() # file = srcPath / "UJing_S03_T03_VeinLigationBlood_raw.edf" #Load data raw = mne.io.read_raw_edf(file, preload=True) rawArray = raw.get_data(picks=['eeg']) # Create LSL outlet info = StreamInfo("Gnautilus recording", 'eeg', 32, 250, 'float32', "gnaut.recorded") # Append channel meta-data info.desc().append_child_value("manufacturer", "G.tec") channels = info.desc().append_child("channels") for c in raw.ch_names: channels.append_child("channel") \ .append_child_value("label", c) \ .append_child_value("unit", "microvolts") \ .append_child_value("type", "EEG") outlet = StreamOutlet(info) print("Sending data ...") for idx in range(rawArray.shape[1]): # now send it and wait for a bit outlet.push_sample(rawArray[:,idx]*1e6) time.sleep(0.004) print("Finished sending data")
import sys sys.path.append('..') from pylsl import StreamInfo, StreamOutlet import time # first resolve a marker stream on the lab network info = StreamInfo('MyMarkerStream', 'Markers', 1, 0, 'string', 'Experiment01') outlet = StreamOutlet(info) data_sampling_rate = 512 # Desired sampling rate time_reduction_factor = 1.2 data_push_interval = float(1/data_sampling_rate) * ((100-time_reduction_factor)/100) # To recreate sampling rate cumulative_time = time.clock() while True: # get a new sample (you can also omit the timestamp part if you're not interested in it) outlet.push_sample(['Nothing']) cumulative_time = time.clock() push_interval_elapsed = time.clock() push_interval_target = (push_interval_elapsed + data_push_interval) while push_interval_elapsed <= push_interval_target: push_interval_elapsed = time.clock()
def lsl_stream(stream, delay, us_rate, repeat_times, verbose): s_info = stream["info"] # Copy the stream meta data if float(s_info["nominal_srate"][0]) < 0.00001: nominal_srate = IRREGULAR_RATE else: nominal_srate = float(s_info["nominal_srate"][0]) if us_rate: if us_rate > 0: if us_rate > nominal_srate: warnings.warn("Undersampling frequecy ({} Hz) greater".format(us_rate) + \ "than nominal sampling rate ({} Hz). Using original".format(nominal_srate), Warning) step = 1 else: step = int(nominal_srate // int(us_rate)) nominal_srate = int(us_rate) else: warnings.warn("Invalid undersampling frequency. Using original") step = 1 else: step = 1 # new stream info # trying to replicate the from s_info info = StreamInfo(s_info["name"][0], s_info["type"][0], int(s_info["channel_count"][0]), nominal_srate, s_info["channel_format"][0], "LSL_REPLAY") if (s_info["desc"][0] is not None): add_to_node(s_info["desc"][0], info.desc()) first_timestamp = stream["time_stamps"][0] cur_timestamp = stream["time_stamps"][0] last_timestamp = first_timestamp first_clock = local_clock() clock_offset = first_timestamp - first_clock remaining_loops = int(repeat_times) time_offset = 0 # Start the LSL stream print("Starting LSL stream: " + s_info['name'][0]) outlet = StreamOutlet(info, 1, 36) time.sleep(delay+5) while (remaining_loops >= 1 or remaining_loops == 0): # Reduce by 1 if not infinite loop key (0) # special case for 1 so its not the infinite loop key if remaining_loops > 1: remaining_loops -= 1 elif remaining_loops == 1: remaining_loops = -1 for x in range(0, len(stream["time_stamps"]), step): cur_timestamp = stream["time_stamps"][x] + time_offset mysample = stream["time_series"][x] stamp = cur_timestamp - clock_offset if verbose: print(mysample) delta = stamp - local_clock() if delta > 0: time.sleep(delta) outlet.push_sample(mysample, stamp) last_timestamp = cur_timestamp print("end of stream") time_offset = cur_timestamp - first_timestamp print("Ending LSL stream: " + s_info["name"][0])
def opencv_experiment_timer(): #Get cli arguments print(sys.argv) if len(sys.argv) >= 2: totalDuration = int(sys.argv[1]) else: print("Experiment default duration") totalDuration = 60 * 5 #Create marker stream print("Creating marker stream ...\n") info = StreamInfo('ExperimentMarkers', 'Markers', 2, 0, 'string', 'myuidw43536') outlet = StreamOutlet(info) #Load sound files startSound = sa.WaveObject.from_wave_file('./sounds/beep-07.wav') endSound = sa.WaveObject.from_wave_file('./sounds/beep-10.wav') state = "Stop" red = (0, 0, 255) green = (0, 255, 0) print("Before starting the experiment make sure that:") print("\t1) The G.Nautilus device is streaming data into LSL") print("\t2) LabRecoder program is recording the data") # input("Press any key to begin the experiment ") img = np.zeros((1500, 2500, 3)) font = cv2.FONT_HERSHEY_SIMPLEX cv2.putText(img, 'Recording for {:d}s'.format(totalDuration), (10, 200), font, 5, (255, 255, 255), 5, cv2.LINE_AA) cv2.putText(img, 'Press s to start counting'.format(totalDuration), (10, 400), font, 5, (255, 255, 255), 5, cv2.LINE_AA) cv2.putText(img, 'Press q to stop and restart'.format(totalDuration), (10, 600), font, 5, (255, 255, 255), 5, cv2.LINE_AA) cv2.putText(img, 'Press ESC to exit'.format(totalDuration), (10, 800), font, 5, (255, 255, 255), 5, cv2.LINE_AA) # cv2.putText(img, 'Status: {:}'.format(state), (10,1100), font, 5, red, 5, cv2.LINE_AA) img = changeState(img, "stop", red, 0) cv2.namedWindow('Experiment timer', cv2.WINDOW_NORMAL) cv2.imshow('Experiment timer', img) while True: cv2.imshow('Experiment timer', img) k = cv2.waitKey(50) if k == 27: # wait for ESC key to exit print("Exit program") cv2.destroyAllWindows() break elif k == ord('s'): # wait for 's' key to save and exit #Count time for _ in range(3): play_obj = startSound.play() play_obj.wait_done() time.sleep(1) startTime = time.time() outlet.push_sample(["started", "{:0.3f}".format(time.time())]) img = changeState(img, "counting", green, 0) cv2.imshow('Experiment timer', img) startTime = time.time() tempBeeps = 0 prevTime = time.time() while time.time() - startTime < totalDuration: if tempBeeps > 60: print("Experiment time ", time.time() - startTime) tempBeeps = 0 play_obj = startSound.play() play_obj.wait_done() k2 = cv2.waitKey(1) if k2 == ord('q'): img = changeState(img, "stop", red, int(time.time() - startTime)) cv2.imshow('Experiment timer', img) break else: img = changeState(img, "counting", green, int(time.time() - startTime)) cv2.imshow('Experiment timer', img) outlet.push_sample(["ended", "{:0.3f}".format(time.time())]) play_obj = endSound.play() play_obj.wait_done() img = changeState(img, "stop", red, int(time.time() - startTime)) cv2.imshow('Experiment timer', img)
Rf = 1000.0 # kohm elif (Range == 3): Rf = 3300.0 # kohm # convert GSR to kohm value gsr_to_volts = (GSR_raw & 0x3fff) * (3.0 / 4095.0) GSR_ohm = Rf / ((gsr_to_volts / 0.5) - 1.0) # convert PPG to milliVolt value PPG_mv = PPG_raw * (3000.0 / 4095.0) timestamp = timestamp0 + timestamp1 * 256 + timestamp2 * 65536 # Optional: uncomment the print command here below to visulise the measurements # print("0x{:.0f}02x,\t{:.0f},\t{:.4f},\t{:.4f}".format(packettype[0], timestamp, GSR_ohm, PPG_mv)) # Send data to LSL mysample = [GSR_ohm, PPG_mv, task] outlet.push_sample(mysample) except KeyboardInterrupt: #send stop streaming command ser.write(struct.pack('B', 0x20)) print print("stop command sent, waiting for ACK_COMMAND") wait_for_ack() print("ACK_COMMAND received.") #close serial port ser.close() print("All done")
fullscr=True) grating = visual.GratingStim(win=mywin, mask='circle', size=20, sf=4) fixation = visual.GratingStim(win=mywin, size=0.2, pos=[0, 0], sf=0, rgb=[1, 0, 0]) for ii, trial in trials.iterrows(): # inter trial interval core.wait(iti + np.random.rand() * jitter) # onset grating.phase += np.random.rand() pos = trials['position'].iloc[ii] grating.pos = [25 * (pos - 0.5), 0] grating.draw() fixation.draw() outlet.push_sample([markernames[pos]], local_clock()) mywin.flip() # offset core.wait(soa) fixation.draw() mywin.flip() if len(event.getKeys()) > 0 or (time() - start) > record_duration: break event.clearEvents() # Cleanup mywin.close()
from inlet import * from model import * import numpy as np from pylsl import StreamInfo, StreamOutlet period = 10 data = [] max_size = 256 info = StreamInfo('Control', 'C', 3, 128//period, 'float32', 'ctrlid') outlet = StreamOutlet(info) for timestamp, sample in get_response(): data.append(sample) if len(data) >= max_size: ctrl = predict(data[:max_size]) data = data[:max_size-period] outlet.push_sample(ctrl)
thisExp.addData('fixation.stopped', fixation.tStopRefresh) thisExp.addData('fixationImage.started', fixationImage.tStartRefresh) thisExp.addData('fixationImage.stopped', fixationImage.tStopRefresh) thisExp.addData('text.started', text.tStartRefresh) thisExp.addData('text.stopped', text.tStopRefresh) thisExp.addData('text_2.started', text_2.tStartRefresh) thisExp.addData('text_2.stopped', text_2.tStopRefresh) thisExp.addData('text_3.started', text_3.tStartRefresh) thisExp.addData('text_3.stopped', text_3.tStopRefresh) # ------Prepare to start Routine "EyesClose"------- continueRoutine = True routineTimer.add(92.000000) # update component parameters for each repeat # Send trial onset marker to LSL outlet.push_sample('c') # Send trial onset marker to serial port if isSerial != '': port_serial.write(b'c') greenProc.setSize(greenSize) ProcTarget.setSize(greenSize) ProcTarget.setImage('./stimuli/images/eyesClose.jpg') sound_1.setSound('A', secs=2.0, hamming=True) sound_1.setVolume(1, log=False) # keep track of which components have finished EyesCloseComponents = [blackProc, greenProc, ProcTarget, sound_1] for thisComponent in EyesCloseComponents: thisComponent.tStart = None thisComponent.tStop = None thisComponent.tStartRefresh = None
units='deg', fullscr=True) fixation = visual.GratingStim(win=mywin, size=0.2, pos=[0, 0], sf=0, rgb=[1, 0, 0]) fixation.setAutoDraw(True) mywin.flip() for ii, trial in trials.iterrows(): # Intertrial interval core.wait(iti + np.random.rand() * jitter) # Select and play sound ind = trials['sound_ind'].iloc[ii] auds[ind].play() # Send marker timestamp = local_clock() outlet.push_sample([markernames[ind]], timestamp) # offset core.wait(soa) if len(event.getKeys()) > 0 or (time() - start) > record_duration: break event.clearEvents() # Cleanup mywin.close()
def present(subject, session, duration=120): outdir = os.getcwd() + '/response_files/' if not os.path.exists(outdir): os.makedirs(outdir) ########################### more muse-lsl code ######################################## # create info = StreamInfo('Markers', 'Markers', 1, 0, 'int32', 'myuidw43536') # next make an outlet outlet = StreamOutlet(info) markernames = [1, 2] # Setup log # position = np.random.binomial(1, 0.15, n_trials) # trials = DataFrame(dict(position=position, timestamp=np.zeros(n_trials))) # graphics def loadImage(filename): return visual.ImageStim(win=mywin, image=filename) mywin = visual.Window([900, 500], monitor="testMonitor", units="deg", fullscr=False) targets = list( map(loadImage, glob('stimulus_presentation/stim/cats_dogs/target-*.jpg'))) nontargets = list( map(loadImage, glob('stimulus_presentation/stim/cats_dogs/nontarget-*.jpg'))) ####################################################################################### # code modified from https://github.com/djangraw/PsychoPyParadigms/blob/master/BasicExperiments/GoNoGoTask_d1.py # declare primary task params params = { # Declare stimulus and response parameters # time when stimulus is presented (in seconds) 'stimDur': .8, # time between when one stimulus disappears and the next appears (in seconds) 'ISI': .5, 'tStartup': 3, # pause time before starting first stimulus 'tCoolDown': 2, # pause time after end of last stimulus before "the end" text 'triggerKey': 't', # key from scanner that says scan is starting # keys to be used for responses (mapped to 1,2,3,4) 'respKeys': ['space'], 'goStim': 'square', # shape signaling respond 'noGoStim': 'diamond', # shape signaling don't respond 'goStimProb': 0.75, # probability of a given trial being a 'go' trial # declare prompt and question files 'skipPrompts': False, # go right to the scanner-wait page 'promptDir': 'Prompts/', # directory containing prompts and questions files 'promptFile': 'GoNoGoPrompts.txt', # Name of text file containing prompts # declare display parameters 'fullScreen': True, # run in full screen mode? # display on primary screen (0) or secondary (1)? 'screenToShow': 0, 'fixCrossSize': 60, # size of cross, in pixels # (x,y) pos of fixation cross displayed before each stimulus (for gaze drift correction) 'fixCrossPos': [0, 0], # in rgb255 space: (r,g,b) all between 0 and 255 'screenColor': (128, 128, 128) } n_trials = int((duration - params['tStartup'] - params['tCoolDown']) / (params['ISI'] + params['stimDur'])) screenRes = [800, 600] # create clocks and window globalClock = core.Clock() # to keep track of time trialClock = core.Clock() # to keep track of time win = visual.Window(screenRes, fullscr=params['fullScreen'], allowGUI=False, monitor='testMonitor', screen=params['screenToShow'], units='deg', name='win', color=params['screenColor'], colorSpace='rgb255') # create fixation cross fCS = params['fixCrossSize'] # size (for brevity) fCP = params['fixCrossPos'] # position (for brevity) fixation = visual.ShapeStim(win, lineColor='#000000', lineWidth=3.0, vertices=((fCP[0] - fCS / 2, fCP[1]), (fCP[0] + fCS / 2, fCP[1]), (fCP[0], fCP[1]), (fCP[0], fCP[1] + fCS / 2), (fCP[0], fCP[1] - fCS / 2)), units='pix', closeShape=False, name='fixCross') # create text stimuli message1 = visual.TextStim(win, pos=[0, +.5], wrapWidth=1.5, color='#000000', alignHoriz='center', name='topMsg', text="aaa", units='norm') message2 = visual.TextStim(win, pos=[0, 0], wrapWidth=1.5, color='#000000', alignHoriz='center', name='middleMsg', text="bbb", units='norm') message3 = visual.TextStim(win, pos=[0, -.5], wrapWidth=1.5, color='#000000', alignHoriz='center', name='bottomMsg', text="bbb", units='norm') # draw stimuli fCS_rt2 = fCS / math.sqrt(2) stims = {'square': [], 'diamond': [], 'circle': []} stims['square'] = visual.ShapeStim( win, lineColor='#000000', lineWidth=3.0, vertices=((fCP[0] - fCS / 2, fCP[1] - fCS / 2), (fCP[0] + fCS / 2, fCP[1] - fCS / 2), (fCP[0] + fCS / 2, fCP[1] + fCS / 2), (fCP[0] - fCS / 2, fCP[1] + fCS / 2), (fCP[0] - fCS / 2, fCP[1] - fCS / 2)), units='pix', closeShape=False, name='square') stims['diamond'] = visual.ShapeStim( win, lineColor='#000000', lineWidth=3.0, vertices=((fCP[0], fCP[1] - fCS_rt2), (fCP[0] - fCS_rt2, fCP[1]), (fCP[0], fCP[1] + fCS_rt2), (fCP[0] + fCS_rt2, fCP[1]), (fCP[0], fCP[1] - fCS_rt2)), units='pix', closeShape=False, name='diamond') stims['circle'] = visual.Circle(win, lineColor='#000000', lineWidth=3.0, radius=fCS_rt2, edges=32, units='pix') tNextFlip = [0.0] def AddToFlipTime(tIncrement=1.0): tNextFlip[0] += tIncrement # record responses, accuracy, etc. (added by AE) responses = [] hits_go = 0 hits_nogo = 0 fa_go = 0 fa_nogo = 0 count_go = 0 count_nogo = 0 rt = np.zeros((n_trials, 1)) for iTrial in range(0, n_trials): # Decide Trial Params isGoTrial = random.random() < params['goStimProb'] # display info to experimenter print(('Running Trial %d: isGo = %d, ISI = %.1f' % (iTrial, isGoTrial, params['ISI']))) if iTrial == 0: AddToFlipTime(2) fixation.draw() while (globalClock.getTime() < tNextFlip[0]): pass win.flip() tStimStart = globalClock.getTime() # record time when window flipped # set up next win flip time after this one AddToFlipTime(params['ISI']) # add to tNextFlip[0] # Draw stim if isGoTrial: stims[params['goStim']].draw() win.logOnFlip(level=logging.EXP, msg='Display go stim (%s)' % params['goStim']) timestamp = time() outlet.push_sample([markernames[0]], timestamp) else: stims[params['noGoStim']].draw() win.logOnFlip(level=logging.EXP, msg='Display no-go stim (%s)' % params['noGoStim']) timestamp = time() outlet.push_sample([markernames[1]], timestamp) # Wait until it's time to display while (globalClock.getTime() < tNextFlip[0]): pass # log & flip window to display image win.flip() tStimStart = globalClock.getTime() # record time when window flipped # set up next win flip time after this one AddToFlipTime(params['stimDur']) # add to tNextFlip[0] # Flush the key buffer and mouse movements event.clearEvents() # Wait for relevant key press or 'stimDur' seconds respKey = None thisKey = None t = None # until it's time for the next frame while (globalClock.getTime() < tNextFlip[0]): # get new keys #newKeys = event.getKeys(keyList=params['respKeys']+['q','escape'],timeStamped=globalClock) newKeys = event.getKeys(timeStamped=globalClock) # check each keypress for escape or response keys if len(newKeys) > 0: for thisKey in newKeys: respKey = thisKey[0] t = globalClock.getTime() - tStimStart #tempArray = [iTrial, isGoTrial, respKey[0]] # responses.append(tempArray) if thisKey[0] in ['q', 'escape']: # escape keys CoolDown() # exit gracefully # only take first keypress elif thisKey[0] in params['respKeys'] and respKey == None: respKey = thisKey # record keypress tempArray = [iTrial, isGoTrial, respKey, t] responses.append(tempArray) if isGoTrial: count_go += 1 else: count_nogo += 1 if isGoTrial: if respKey == 'space': hits_go += 1 else: fa_go += 1 elif ~isGoTrial: if respKey == None: hits_nogo += 1 else: fa_nogo += 1 # get RT for correct go trials if isGoTrial and respKey == 'space': rt[iTrial] = t else: rt[iTrial] = np.nan # Display the fixation cross if params['ISI'] > 0: # if there should be a fixation cross fixation.draw() # draw it win.logOnFlip(level=logging.EXP, msg='Display Fixation') win.flip() # return if iTrial == n_trials: AddToFlipTime(params['tCoolDown']) fixation.draw() win.flip() while (globalClock.getTime() < tNextFlip[0]): pass acc_go = np.round(float(hits_go) / float(count_go) * float(100), 2) acc_nogo = np.round(float(hits_nogo) / float(count_nogo) * float(100), 2) mean_rt = np.round(float(np.nanmean(rt)), 2) outname = outdir + 'behav_' + subject + \ '_run' + str(session) + '.mat' scipy.io.savemat( outname, { 'rt': rt, 'mean_rt': mean_rt, 'acc_go': acc_go, 'acc_nogo': acc_nogo, 'hits_go': hits_go, 'hits_nogo': hits_nogo, 'fa_go': fa_go, 'fa_nogo': fa_nogo, 'count_go': count_go, 'count_nogo': count_nogo }) # display results message1.setText("That's the end! Here are your results:") message2.setText( 'N trials = %d \nGo accuracy = %d/%d (%0.2f) \nNoGo accuracy = %d/%d (%0.2f) \nMean correct Go RT = %0.2f' % (params['nTrials'], hits_go, count_go, round(acc_go, 2), hits_nogo, count_nogo, round(acc_nogo, 2), round(mean_rt, 2))) message3.setText("Press 'q' or 'escape' to end the session.") win.logOnFlip(level=logging.EXP, msg='Display TheEnd') message1.draw() message2.draw() message3.draw() win.flip() thisKey = event.waitKeys(keyList=['q', 'escape']) core.quit() mywin.close()
"""Example program to demonstrate how to send a multi-channel time series to LSL.""" import time from random import random as rand from pylsl import StreamInfo, StreamOutlet # first create a new stream info (here we set the name to BioSemi, # the content-type to EEG, 8 channels, 100 Hz, and float-valued data) The # last value would be the serial number of the device or some other more or # less locally unique identifier for the stream as far as available (you # could also omit it but interrupted connections wouldn't auto-recover) info = StreamInfo('BioSemi', 'EEG', 8, 100, 'float32', 'myuid34234') # next make an outlet outlet = StreamOutlet(info) print("now sending data...") while True: # make a new random 8-channel sample; this is converted into a # pylsl.vectorf (the data type that is expected by push_sample) mysample = [rand(), rand(), rand(), rand(), rand(), rand(), rand(), rand()] # now send it and wait for a bit outlet.push_sample(mysample) time.sleep(0.01)
if t >= 0.0 and cross.status == NOT_STARTED: # keep track of start time/frame for later cross.tStart = t cross.frameNStart = frameN # exact frame index cross.setAutoDraw(True) frameRemains = 0.0 + 2.0 - win.monitorFramePeriod * 0.75 # most of one frame period left if cross.status == STARTED and t >= frameRemains: cross.setAutoDraw(False) # *go* updates if t >= 3.5 and go.status == NOT_STARTED: # keep track of start time/frame for later go.tStart = t go.frameNStart = frameN # exact frame index outlet.push_sample(x=[trials.thisIndex]) #send marker go.setAutoDraw(True) frameRemains = 3.5 + 5 - win.monitorFramePeriod * 0.75 # most of one frame period left if go.status == STARTED and t >= frameRemains: go.setAutoDraw(False) # *rest* updates if t >= 8.5 and rest.status == NOT_STARTED: # keep track of start time/frame for later rest.tStart = t rest.frameNStart = frameN # exact frame index rest.setAutoDraw(True) frameRemains = 8.5 + 3.5 - win.monitorFramePeriod * 0.75 # most of one frame period left if rest.status == STARTED and t >= frameRemains: rest.setAutoDraw(False)
command_display_time = 5 # In seconds arrow_display = False # Arrows start being displayed first, show fixation when value is False command_time_counter = 1 time_flip_counter = 0 trial_indicator_text_stimulus = visual.TextStim(win=window_handle, text=' ', pos=[0, -3]) trial_indicator_text_stimulus.setAutoDraw(True) executed_command = 0 # ---------------------------------------------------------------------------------------------------------------------- # ---------------------------------------------------------------------------------------------------------------------- # Create an outlet to transmit data (event markers) using LSL info = StreamInfo('MyMarkerStream', 'Markers', 1, 0, 'string', 'Experiment01') outlet = StreamOutlet(info) outlet.push_sample(['Waiting...']) time.sleep(10) # ---------------------------------------------------------------------------------------------------------------------- # Pre-allocate the event time log matrix events_per_trial = (len(command_sequence)*2)+1 event_matrix = np.zeros([2, (number_of_trials*events_per_trial)+1]) EVENT_LEFT = 1 EVENT_RIGHT = 2 EVENT_UP = 3 EVENT_DOWN = 4 EVENT_FACE = 5 EVENT_CROSS = 6 EVENT_REST = 7 EVENT_PAUSE = 8
print "MAC address (%s) is not defined..." %macAddress print "connecting to BITalino(%s)..." # Set battery threshold device.battery(batteryThreshold) # Read BITalino version print device.version() print "connected to BITalino(%s)" %macAddress print "creating Signal stream..." info = StreamInfo('BiTalino','BiTalino',+len(acqChannels),samplingRate,'float32','myuid34234'); # next make an outlet outlet = StreamOutlet(info) print"created Signal stream : %s" %info.name() print("starting acquisition...") # Start Acquisition device.start(samplingRate, acqChannels) # Read samples while 1: data=device.read(nSamples) print data outlet.push_sample(data[0][defaultChannel+1:]) # Turn BITalino led on device.trigger(digitalOutput) # Stop acquisition device.stop() # Close connection outlet.close() info.close() device.close()