def send_init(self, feedback): """Send 'send_init(feedback)' to Feedback Controller. :param feedback: Feedback """ signal = bcixml.BciSignal({"_feedback": str(feedback)}, [(bcixml.CMD_SEND_INIT, dict())], bcixml.INTERACTION_SIGNAL) self.send_signal(signal)
def load_configuration(self, filename): """Tell the Feedback to load variable values from given file. :param filename: Name of the file where to load the variables from :type filename: str """ signal = bcixml.BciSignal(None, [(bcixml.CMD_LOAD_VARIABLES, { 'filename': filename })], bcixml.INTERACTION_SIGNAL) self.send_signal(signal)
def save_configuration(self, filename): """Tell the Feedback to store it's variables to the given file. :param filename: Name of the file where to store the variables. :type filename: str """ signal = bcixml.BciSignal(None, [(bcixml.CMD_SAVE_VARIABLES, { 'filename': filename })], bcixml.INTERACTION_SIGNAL) self.send_signal(signal)
def get_variables(self): """Get variables (name, type and value) from currently running Feedback. :returns: variables """ signal = bcixml.BciSignal(None, [(bcixml.CMD_GET_VARIABLES, dict())], bcixml.INTERACTION_SIGNAL) self.send_signal(signal) data, addr = self.receive(TIMEOUT) if not data: self.logger.info("Did not receive answer on get_variables") return None answer = self.xmldecoder.decode_packet(data) return answer.data.get("variables")
def getAvailableFeedbacks(self): """Get available Feedbacks from Feedback Controller. :returns: Feedbacks """ signal = bcixml.BciSignal(None, [(bcixml.CMD_GET_FEEDBACKS, dict())], bcixml.INTERACTION_SIGNAL) self.send_signal(signal) data, addr = self.receive(TIMEOUT) if not data: self.logger.info( "Did not receive an answer on getAvailableFeedbacks") return None answer = self.xmldecoder.decode_packet(data) return answer.data.get("feedbacks")
def send_data_signal(self, dat): """ Sends the LAST sample to the stimulus setup (using appropriate scaling) ... I can also take average, or median? It'd no use sending ALL Data, since the line'll just get too big. """ this_signal = np.mean(dat.data[:,:],1) to_send = np.median(this_signal) # change scalings - emg from 0 to 1; eeg from -1 to +1 to_send_scaled = to_send / self._st_scaling + self._st_offset if self.bcinet is not None: self.bcinet.send_signal(bcixml.BciSignal({self.signal_key: to_send_scaled}, None, bcixml.CONTROL_SIGNAL)) else: return to_send_scaled
def set_threshold(self, new_threshold): """ Sets a new threshold -- it will also change the threshold sent to the ststim! """ # this changes the threshold... # so we do two things here: a) set internal transformation(s) so signal # is transformed accordingly in subsequent calls to send_data_signal and # check_data_threshold # # + send a signal to nfstim with the changes to threshold self.thr = new_threshold # change scalings - emg from 0 to 1; eeg from -1 to +1 new_threshold_for_st = self.thr / self._st_scaling + self._st_offset if self.bcinet is not None: self.bcinet.send_signal(bcixml.BciSignal({self.set_thr_key: new_threshold_for_st},None, bcixml.CONTROL_SIGNAL)) else: pass # print('sending: %.2f' % new_threshold_for_st) self._new_thr_for_st = new_threshold_for_st
def send_data_signal(self, dat): """ Sends a sample to the stimulus setup (using appropriate scaling) best not to send every sample! """ this_signal = dat # np.mean(dat[:,:],1) to_send = np.median(this_signal) # change scalings - emg from 0 to 1; eeg from -1 to +1 to_send_scaled = to_send / self._st_scaling + self._st_offset # check how much time since the last send: if time.time() - self.last_sent_time > self.dt_between_sending_data: if self.bcinet is not None: # send the actual signal. This is a horribly convoluted way of sending anything. # also no point in abstractifying this mess in order to make it more pretty. self.last_sent_time = time.time() self.bcinet.send_signal( bcixml.BciSignal({self.signal_key: to_send_scaled}, None, bcixml.CONTROL_SIGNAL)) return to_send_scaled
def quit_feedback_controller(self): """Send 'quit_feedback_controller' to Feedback Controller.""" signal = bcixml.BciSignal( None, [(bcixml.CMD_QUIT_FEEDBACK_CONTROLLER, dict())], bcixml.INTERACTION_SIGNAL) self.send_signal(signal)
def quit(self): """Send 'quit' to Feedback Controller.""" signal = bcixml.BciSignal(None, [(bcixml.CMD_QUIT, dict())], bcixml.INTERACTION_SIGNAL) self.send_signal(signal)
def stop(self): """Send 'stop' to Feedback Controller.""" signal = bcixml.BciSignal(None, [(bcixml.CMD_STOP, dict())], bcixml.INTERACTION_SIGNAL) self.send_signal(signal)
def pause(self): """Send 'pause' to Feedback Controller.""" signal = bcixml.BciSignal(None, [(bcixml.CMD_PAUSE, dict())], bcixml.INTERACTION_SIGNAL) self.send_signal(signal)
def _check_each_sample(self,s): """ A subfunction that runs on each sample and determines whether A trigger (of what kind) needs to be sent """ # s is the signal. self.TF = 0 self.audioTF = 0 # is it bigger than 0? if s > self.thr: self.psarea += (s-self.thr) / self.fs self.psduration += 1.0 / self.fs self.psareaduration += 1.0 / self.fs else: self.psarea = 0 self.psduration = 0 # total time above threshold self.psareaduration = 0 # total time abovethreshold since LAST AUDIO STIMULUS!! if self.psduration == 0: self.signal_counter_sent=False if self.pprev_areaduration == 0: self.signal_intensity_sent=False if self.pprev_duration == 0: self.dur_for_area = self.dur # so if bigger than duration -- send the signal, but don't keep sending it... if self.psduration >= self.dur and not self.signal_counter_sent: self.signal_counter_sent=True self.TF = 1 if self.bcinet is not None: self.bcinet.send_signal(bcixml.BciSignal({self.control_ev_key: [True, -1]},None, bcixml.CONTROL_SIGNAL)) else: pass print('sending signal -- I ! - %d - %d - %s - %s' % (self.datsamples, self.times_called, str(True), str(-1))) if self.pprev_areaduration >= self.dur_for_area and s < self.pprev_signal and not self.signal_intensity_sent: self.signal_intensity_sent=True self.psareaduration=0 # self.dur_for_area_to_send=self.psduration self.dur_for_area += 0.050 # this will be converted to a chime with the correct pitch to_send_rating_from_0_to_10 = self._from_st_duration_to_0_10_rating(self.psduration) self.audioTF = 1 if self.bcinet is not None: self.bcinet.send_signal(bcixml.BciSignal({self.control_ev_key: [False, to_send_rating_from_0_to_10]},None, bcixml.CONTROL_SIGNAL)) else: pass # import ipdb; ipdb.set_trace() print('sending signal! - %d %s - %s -- %s' % (self.times_called, str(False), str(self.pprev_area), str(self.dur_for_area))) self.pprev_signal = s self.pprev_duration = self.psduration self.pprev_areaduration = self.psareaduration self.pprev_area = self.psarea