def feedback(): for i in range(10): beforevents, state = bufhelp.buffer_newevents('classifier.prediction', 0, state=None) h.set(text='Think of your target letter and get ready') drawnow() sleep(2) h.set(text='', color='k') drawnow() sleep(1) charStim(None) h.set(text='', color='k') drawnow() sleep(1) feedbackevents, _state = bufhelp.buffer_newevents( 'classifier.prediction', state=state) # predictions contain both labels and values chars, predictions = np.array( [e.value.split('_') for e in feedbackevents]).T predictions = predictions.astype(float) # get the character with the highest mean prediction (currently random in feedback stage) best = max(np.unique(chars), key=lambda c: np.mean(predictions[chars == c])) h.set(text=best, color='b') drawnow() sleep(2)
def test(text, n_targets=10, repetitions=5): """ Online feedback phase Args: - text: handle to Text object - n_targets: Number of iterations to do - repetitions: Number of times each letter occurs per iteration """ letters = list(string.ascii_uppercase) letter2idx = {l: i for i, l in enumerate(letters)} # Make sure all classification events are retrieved bufhelp.MAXEVENTHISTORY = 800 bufhelp.sendEvent('experiment.start', 1) for target in range(n_targets): _, state = bufhelp.buffer_newevents('classifier.prediction', timeout_ms=0, state=None) flashes = np.zeros((len(letters), len(letters) * repetitions)) text.set(text='Think of your target letter\nand get ready', color='green', fontsize=14) drawnow() plt.pause(2) text.set(text='') drawnow() plt.pause(1) for i, letter in enumerate(np.random.permutation(letters * repetitions)): flashes[letter2idx[letter], i] = 1 text.set(text=letter, color='white', fontsize=120) drawnow() bufhelp.sendEvent('stimulus.type', 'test') plt.pause(0.1) text.set(text='') # Wait for classifier plt.pause(3) predictions, _ = bufhelp.buffer_newevents('classifier.prediction', state=state, timeout_ms=5000) # Make sure the predictions are in the right order predictions = sorted(predictions, key=lambda p: p.sample) if len(predictions) != flashes.shape[1]: print('Too few predictions found..., removing last trials') flashes = flashes[:, :len(predictions)] predictions = np.array([p.value[0] for p in predictions]) # Compute inner product of each letter similarities = flashes @ predictions # Pick the letter with the highest similarity letter = np.argmax(similarities) text.set(text=letters[letter], fontsize=120, color='blue') plt.pause(2) bufhelp.sendEvent('experiment.end', 1)
def processBufferEvents(): events = bufhelp.buffer_newevents() for evt in events: print(str(evt.sample) + ": " + str(evt)) # keyboard if evt.type == 'stimulus.prediction': if evt.value == '@FWRD': Nao.moveForward(50) elif evt.value == '@TRNL': Nao.turnLeft(90) elif evt.value == '@TRHT': Nao.turnRight(90) elif evt.value == '@LEFT': Nao.moveLeft(90) elif evt.value == '@RGHT': Nao.moveRight(90) elif evt.value == '@BACK': Nao.moveBackward(50) elif evt.value == '#HELLO': Nao.sayHello() elif evt.value == '#GBYE': Nao.sayBye() elif evt.value == '#HWRU': Nao.sayHRU() elif evt.value == '#FINE': Nao.sayFine() elif evt.value == '*TSK1': Nao.performTask(0) elif evt.value == '*TSK2': Nao.performTask(1) elif evt.value == '*TSK3': Nao.performTask(2)
def processBufferEvents(): global running events = bufhelp.buffer_newevents() for evt in events: print(str(evt.sample) + ": " + str(evt)) if evt.type == "classifier.prediction": pred = evt.value (m12, i12) = max2(pred) # find max value if m12[0] - m12[1] > THRESHOLDS[i12[0]]: send_command(CMDS[i12[0]]) # if above threshold send elif evt.type == "keyboard": if evt.value == "q": send_command(CMD_SPEED) elif evt.value == "w": send_command(CMD_JUMP) elif evt.value == "e": send_command(CMD_ROLL) elif evt.value == "esc": running = false elif evt.type == "startPhase.cmd": if evt.value == "quit": running = False
def action_for_option(self, option): if option == 8: print('Going to SOS') self.controller.sos_trigger() sos_stimulus = SOSInterfaceStimulus() sos_stimulus.start_stimulus() events, self.state = bufhelp.buffer_newevents( 'errp_clsfr.prediction', 1000, self.state) elif option > 8: print('Movement') self.controller.movement(option - 9) else: self.controller.phone_tv(option)
def echoClient(timeout=5000): ## init connection to the buffer ftc,hdr=bufhelp.connect(); # send event to buffer while True: events = bufhelp.buffer_newevents(state=True) for event in events: if event.type == 'quit': ftc.disconnect() return elif event.type != 'echo': bufhelp.sendEvent('echo', event.value)
def processBufferEvents(): global running trlen_ms = 600 events = bufhelp.buffer_newevents() for evt in events: if str(evt.type) == 'calibrate' and evt.value == 'start': print('Calibration phase, gathering data...') data, events, stopevents = bufhelp.gatherdata("stimulus.target", 750, ("calibrate", "end"), milliseconds=True) pickle.dump({ "events": events, "data": data }, open("subject_data", "w")) else: print(str(evt.sample) + ": " + str(evt))
def processBufferEvents(): global running events = bufhelp.buffer_newevents() for evt in events: print(str(evt.sample) + ": " + str(evt)) if evt.type == 'classifier.prediction': pred = evt.value (m12, i12) = max2(pred) # find max value if m12[0] - m12[1] > THRESHOLDS[i12[0]]: send_command(CMDS[i12[0]]) # if above threshold send elif evt.type == 'keyboard': if evt.value == 'q': send_command(CMD_SPEED) elif evt.value == 'w': send_command(CMD_JUMP) elif evt.value == 'e': send_command(CMD_ROLL) elif evt.value == 'esc': running = false elif evt.type == 'startPhase.cmd': if evt.value == 'quit': running = False
def start_stimulus(self): # Initialising the state with None doesn't work for some reason. I use this hack # to get the first value of the state variable _, state = bufhelp.buffer_newevents('p300.prediction', 1, None) bufhelp.sendEvent('p300.seq', 'start') # Start process # TODO: This should run forever, not just 10 times done = False while not done: self.si.wait(GETREADY_DURATION) total_sequence = self.single_character_flashing() # Get prediction event events, state = bufhelp.buffer_newevents('p300.prediction', 2000, state) if events is None or len(events) < 1: print("Error! no predictions, continuing") else: if len(events) > 1: print("Warning: multiple predictions. Some ignored.") # only use the last event evt = events[-1] # Get letter with best prediction prediction = self.get_best_by_mean(total_sequence, evt.value) if DEBUG: self.all_predictions.append(prediction) # Display predicted target bufhelp.sendEvent('stimulus.prediction', prediction) self.si.flash_option(prediction, color='blue', duration=PREDICTION_DURATION) skip_trial = False if INCLUDE_ERRP: # Listen for ErrP classifier signal events, state = bufhelp.buffer_newevents( 'errp_clsfr.prediction', 1000, state) # If ErrP detected, display second most confident prediction if len(events ) >= 1 and events[-1].value >= ERRP_CONFIDENCE: print('ErrP detected:', prediction) self.si.flash_option(prediction, color='red', duration=ERROR_DURATION) if RESTART_TRIAL: print('Skipping this trial') skip_trial = True else: print('Getting next best prediction') prediction = self.get_best_by_mean( total_sequence, evt.value, exclude=[prediction]) self.si.flash_option(prediction, color='blue', duration=PREDICTION_DURATION) if not skip_trial: if prediction < 3: self.controller.sos_panel(prediction) done = True self.si.close()
ftc.putEvents(e) if __name__ == '__main__': with open('classifier.pkl', 'rb') as f: clf = pickle.load(f) ftc, hdr = bufhelp.connect() trial_length_ms = 600 trial_length_samples = math.ceil((trial_length_ms / 1000.) * hdr.fSample) # gather stores events that haven't been long enough ago to collect data gather = [] print('Waiting for events...') while True: events = bufhelp.buffer_newevents('stimulus.type', timeout_ms=1000) for evt in events: end_sample = evt.sample + trial_length_samples - 1 gather.append((evt, end_sample)) # Current sample count nSamples = bufhelp.globalstate[0] for point in gather: evt, end_sample = point if end_sample < nSamples: # Enough time has passed to collect the data data = ftc.getData((evt.sample, end_sample)) # Preprocess data = preproc.detrend([data]) data = preproc.spectralfilter(data, (0, 1, 14, 15), hdr.fSample)
# Load the trained classifier with open('clsfr.pk', 'rb') as f: classifier = pickle.load(f) clf = classifier['classifier'] bad_channels = classifier['bad_channels'] good_channels = np.ones(10, dtype=np.bool) good_channels[bad_channels] = False ftc, hdr = bufhelp.connect() trial_length_samples = math.ceil((trlen_ms / 1000) * hdr.fSample) # gather stores events while we wait until enough time has passed gather = [] print('Waiting for events...') while True: events = bufhelp.buffer_newevents('experiment.predict', timeout_ms=1000) for evt in events: end_sample = evt.sample + trial_length_samples - 1 gather.append((evt, end_sample)) # Current sample count nSamples = bufhelp.globalstate[0] for point in gather: evt, end_sample = point if end_sample < nSamples: # Enough time has passed to collect the data data = ftc.getData((evt.sample, end_sample)) # Preprocess data = data[:, : 10] # select channels which were actually connected data = preproc.detrend([data])
def errp_communicate(menu, position): selected = False while True: events_errp, state_errp = bufhelp.buffer_newevents('errp.prediction', 1000, state=None) if events_errp == []: print("Error! no predictions, continuing") evt_errp = [] else: if len(events_errp) > 1: print("Warning: multiple predictions. Some ignored.") evt_errp = events_errp[-1] # only use the last event if evt_errp != []: if int(evt_errp.value) == 1: if menu['tv'] and position < 4: bufhelp.sendEvent('tv', position) phone_tv_screen(position, blue) break if menu['phone'] and position < 4: bufhelp.sendEvent('call', position) phone_tv_screen(position, blue) break if (menu['phone'] or menu['tv']) and position > 3: if menu['tv']: bufhelp.sendEvent('tv', 'end') if position == 4: menu = menu_dict(4, menu) selected = True menu_selecter(menu) break if position == 5: bufhelp.sendEvent('sos', 'on') menu = menu_dict(4, menu) selected = True menu_selecter(menu) break if menu['sos']: if position == 1: bufhelp.sendEvent('sos', 'pain') sos_screen(position, blue) break if position == 2: bufhelp.sendEvent('sos', 'food') sos_screen(position, blue) break if position == 3: bufhelp.sendEvent('sos', 'wc') sos_screen(position, blue) break if position == 4: selected = True menu = menu_dict(0, menu) menu_selecter(menu) break if menu['navigation']: if position == 1: bufhelp.sendEvent('navigate', 'up') navigation_screen(position, blue) break if position == 2: bufhelp.sendEvent('navigate', 'down') navigation_screen(position, blue) break if position == 3: bufhelp.sendEvent('navigate', 'left') navigation_screen(position, blue) break if position == 4: bufhelp.sendEvent('navigate', 'right') navigation_screen(position, blue) break if position == 5: selected = True menu = menu_dict(0, menu) menu_selecter(menu) break if position == 6: bufhelp.sendEvent('sos', 'on') selected = True menu = menu_dict(4, menu) menu_selecter(menu) break if menu['home']: selected = True menu = menu_dict(position, menu) menu_selecter(menu) break elif int(evt_errp.value) == 0: if menu['tv']: phone_tv_screen(position, yellow) if menu['home']: initial_screen(position, yellow) if menu['navigation']: navigation_screen(position, yellow) if menu['sos']: sos_screen(position, yellow) if menu['phone']: phone_tv_screen(position, yellow) break return selected
#wait for key-press to continue [_.set(color=bgColor) for _ in hdls] txthdl.set(text='Press key to start') drawnow() waitforkey(fig) txthdl.set(visible=False) plt.ion() [ _.set(visible=True) for _ in hdls] drawnow() bufhelp.sendEvent('stimulus.feedback','start'); # initialize the state for tracking and catching classifier prediction events #_,state = bufhelp.buffer_newevents('classifier.prediction',0,False,True) _ = bufhelp.buffer_newevents('classifier.prediction',0) ## STARTING stimulus loop for ti in range(nSeq): sleep(interSeqDuration) # reset the display [ _.set(color=bgColor) for _ in hdls] drawnow() sleep(postCueDuration) # start the scanning loop stimSeq=[] # [ nSymbs x nEpochs ] info on flash/non-flash state of each output for rep in range(nRep): # repeat enough times for si in range(nSymbs): # linear scan over outputs # flash
def start_stimulus(self): # Initialising the state with None doesn't work for some reason. I use this hack # to get the first value of the state variable _, self.state = bufhelp.buffer_newevents('p300.prediction', 1, None) bufhelp.sendEvent('p300.seq', 'start') self.si.show_instruction( 'Press any button to start the feedback sequence') self.si.wait_for_input() # Start process while True: self.si.show_instruction('Think of your target', GETREADY_DURATION) total_sequence = self.single_character_flashing() # Get prediction event events, self.state = bufhelp.buffer_newevents( 'p300.prediction', 1000, self.state) if events is None or len(events) < 1: print("Error! no predictions, continuing") else: if len(events) > 1: print("Warning: multiple predictions. Some ignored.") # only use the last event evt = events[-1] # Get letter with best prediction prediction = self.get_best_by_mean(total_sequence, evt.value) if DEBUG: self.all_predictions.append(prediction) # Display predicted target bufhelp.sendEvent('stimulus.prediction', str(prediction)) self.si.flash_option(prediction, color='blue', duration=PREDICTION_DURATION) skip_trial = False if INCLUDE_ERRP: # Listen for ErrP classifier signal events, self.state = bufhelp.buffer_newevents( 'errp_clsfr.prediction', 1000, self.state) # If ErrP detected, display second most confident prediction if len(events ) >= 1 and events[-1].value <= ERRP_CONFIDENCE: print('ErrP detected:', prediction) self.si.flash_option(prediction, color='red', duration=ERROR_DURATION) if RESTART_TRIAL: print('Skipping this trial') skip_trial = True else: print('Getting next best prediction') prediction = self.get_best_by_mean( total_sequence, evt.value, exclude=[prediction]) self.si.flash_option(prediction, color='blue', duration=PREDICTION_DURATION) if not skip_trial: self.action_for_option(prediction) if DEBUG: acc = accuracy_score(self.all_predictions, self.all_targets) print('Accuracy on feedback is: {}'.format(acc)) print(self.all_predictions) print(self.all_targets) bufhelp.sendEvent('p300.seq', 'end')
def select_icon_phone_tv_screen(position, menu): phone_tv_screen(position, yellow) while True: if position > 5: position = 1 phone_tv_screen(position, yellow) if position < 1: position = 5 phone_tv_screen(position, yellow) bufhelp.sendEvent('stimulus.target', "hey") if not DEBUG: sleep(3) events, state = bufhelp.buffer_newevents('classifier.prediction', 3000, state=None) if events == []: print("Error! no predictions, continuing") evt = [] else: if len(events) > 1: print("Warning: multiple predictions. Some ignored.") evt = events[-1] # only use the last event for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() quit() if evt != []: if int(evt.value) == 0: position = position - 1 phone_tv_screen(position, yellow) if int(evt.value) == 1: position = position + 1 phone_tv_screen(position, yellow) if int(evt.value) == 2: if menu["tv"]: if position == 1: phone_tv_screen(position, green) bufhelp.sendEvent('errp.trigger', 'start') if not DEBUG: sleep(1) selected = errp_communicate(menu, position) if selected: break if position == 2: phone_tv_screen(position, green) bufhelp.sendEvent('errp.trigger', 'start') if not DEBUG: sleep(1) selected = errp_communicate(menu, position) if selected: break if position == 3: phone_tv_screen(position, green) bufhelp.sendEvent('errp.trigger', 'start') if not DEBUG: sleep(1) selected = errp_communicate(menu, position) if selected: break elif menu['phone']: if position == 1: phone_tv_screen(position, green) bufhelp.sendEvent('errp.trigger', 'start') if not DEBUG: sleep(1) selected = errp_communicate(menu, position) if selected: break if position == 2: phone_tv_screen(position, green) bufhelp.sendEvent('errp.trigger', 'start') if not DEBUG: sleep(1) selected = errp_communicate(menu, position) if selected: break if position == 3: phone_tv_screen(position, green) bufhelp.sendEvent('errp.trigger', 'start') if not DEBUG: sleep(1) selected = errp_communicate(menu, position) if selected: break if position == 4: phone_tv_screen(position, green) bufhelp.sendEvent('errp.trigger', 'start') if not DEBUG: sleep(1) selected = errp_communicate(menu, position) if selected: break if position == 5: phone_tv_screen(position, green) bufhelp.sendEvent('errp.trigger', 'start') if not DEBUG: sleep(1) selected = errp_communicate(menu, position) if selected: break if int(evt.value) == 3: pass
#wait for key-press to continue [_.set(color=bgColor) for _ in hdls] txthdl.set(text='Press key to start') drawnow() waitforkey(fig) txthdl.set(visible=False) plt.ion() [_.set(visible=True) for _ in hdls] drawnow() bufhelp.sendEvent('stimulus.feedback', 'start') # initialize the state for tracking and catching classifier prediction events #_,state = bufhelp.buffer_newevents('classifier.prediction',0,False,True) _ = bufhelp.buffer_newevents('classifier.prediction', 0) ## STARTING stimulus loop for ti in range(nSeq): sleep(interSeqDuration) # reset the display [_.set(color=bgColor) for _ in hdls] drawnow() sleep(postCueDuration) # start the scanning loop stimSeq = [ ] # [ nSymbs x nEpochs ] info on flash/non-flash state of each output for rep in range(nRep): # repeat enough times for si in range(nSymbs): # linear scan over outputs
def run_feedback(nSequences, nBlock, trialDuration, feedbackDuration, intertrialDuration, baselineDuration, state=None): # Display fixation circle and two arows (left and right) initial_display() # pygame.time.delay(intertrialDuration) # make the target sequence nSymbols = 4 targetSequence = list(range(nSymbols)) * int(nSequences / nSymbols + 1) # sequence in sequential order last_trial_id = len(targetSequence) shuffle(targetSequence) # N.B. shuffle works in-place! # 0 - left, 1 - right, 2 - both, 3 - none (no movement) it = 0 for target in targetSequence: it +=1 sleep(intertrialDuration) # show the baseline pygame.draw.circle(display_surface, blue, [X // 2, Y // 2], 40) pygame.display.update() bufhelp.sendEvent('stimulus.baseline', 'start') sleep(baselineDuration) bufhelp.sendEvent('stimulus.baseline', 'end') # initial_display() # show the target in yellow if target == 0: pygame.draw.circle(display_surface, yellow, [X // 2, Y // 2], 40) # fixation yellow pygame.draw.circle(display_surface, yellow, (535, 400), 100) # mark target display_surface.blit(left_arr, (471, 336)) pygame.display.update() elif target == 1: pygame.draw.circle(display_surface, yellow, [X // 2, Y // 2], 40) # fixation yellow pygame.draw.circle(display_surface, yellow, (1065, 400), 100) # mark target display_surface.blit(right_arr, (1001, 336)) pygame.display.update() elif target == 2: pygame.draw.circle(display_surface, yellow, [X // 2, Y // 2], 40) # fixation yellow pygame.draw.circle(display_surface, yellow, (535, 400), 100) # mark target pygame.draw.circle(display_surface, yellow, (1065, 400), 100) # mark target display_surface.blit(left_arr, (471, 336)) display_surface.blit(right_arr, (1001, 336)) pygame.display.update() else: pygame.draw.circle(display_surface, yellow, [X // 2, Y // 2], 40) # fixation yellow pygame.display.update() bufhelp.sendEvent('stimulus.trial', 'start') if it == last_trial_id : bufhelp.sendEvent('stimulus.last_target', target) else: bufhelp.sendEvent('stimulus.target', target) injectERP(amp=1) sleep(trialDuration) bufhelp.sendEvent('stimulus.end_target', 'end') #catch the prediction # N.B. use state to track which events processed so far events,state = bufhelp.buffer_newevents('classifier.prediction',3000,state) if events == []: print("Error! no predictions, continuing") else: if len(events)>1: print("Warning: multiple predictions. Some ignored.") evt=events[-1] # only use the last event print(evt.value == target) if evt.value == target: bufhelp.sendEvent('stimulus.start_feedback', "1") else: bufhelp.sendEvent('stimulus.start_feedback', "0") # show prediction (user feedback) if evt.value == target : # good prediction ! # Turn the target green if target == 0: pygame.draw.circle(display_surface, green, [X // 2, Y // 2], 40) pygame.draw.circle(display_surface, green, (535, 400), 100) display_surface.blit(left_arr, (471, 336)) pygame.display.update() elif target == 1: pygame.draw.circle(display_surface, green, [X // 2, Y // 2], 40) pygame.draw.circle(display_surface, green, (1065, 400), 100) display_surface.blit(right_arr, (1001, 336)) pygame.display.update() elif target == 2: pygame.draw.circle(display_surface, green, [X // 2, Y // 2], 40) pygame.draw.circle(display_surface, green, (535, 400), 100) pygame.draw.circle(display_surface, green, (1065, 400), 100) display_surface.blit(left_arr, (471, 336)) display_surface.blit(right_arr, (1001, 336)) pygame.display.update() else: pygame.draw.circle(display_surface, green, [X // 2, Y // 2], 40) pygame.display.update() else : # wrong prediction ! # Turn target red if target == 0: pygame.draw.circle(display_surface, red, [X // 2, Y // 2], 40) pygame.draw.circle(display_surface, red, (535, 400), 100) display_surface.blit(left_arr, (471, 336)) pygame.display.update() elif target == 1: pygame.draw.circle(display_surface, red, [X // 2, Y // 2], 40) pygame.draw.circle(display_surface, red, (1065, 400), 100) display_surface.blit(right_arr, (1001, 336)) pygame.display.update() elif target == 2: pygame.draw.circle(display_surface, red, [X // 2, Y // 2], 40) pygame.draw.circle(display_surface, red, (535, 400), 100) pygame.draw.circle(display_surface, red, (1065, 400), 100) display_surface.blit(left_arr, (471, 336)) display_surface.blit(right_arr, (1001, 336)) pygame.display.update() else: pygame.draw.circle(display_surface, red, [X // 2, Y // 2], 40) pygame.display.update() injectERP(amp=1) sleep(feedbackDuration) bufhelp.sendEvent('stimulus.end_feedback', "end") bufhelp.sendEvent('stimulus.trial', 'end') # reset the display initial_display() sleep(1)
def select_icon_navigation_screen(position, menu): navigation_screen(position, yellow) while True: if position > 6: position = 1 navigation_screen(position, yellow) if position < 1: position = 6 navigation_screen(position, yellow) bufhelp.sendEvent('stimulus.target', "hey") if not DEBUG: sleep(3) events, state = bufhelp.buffer_newevents('classifier.prediction', 3000, state=None) if events == []: print("Error! no predictions, continuing") evt = [] else: if len(events) > 1: print("Warning: multiple predictions. Some ignored.") evt = events[-1] # only use the last event for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() quit() if evt != []: if int(evt.value) == 0: position = position - 1 navigation_screen(position, yellow) # if right movement is predicted if int(evt.value) == 1: position = position + 1 navigation_screen(position, yellow) # if both hands movement is predicted - select this option if int(evt.value) == 2: if position == 1: navigation_screen(position, green) bufhelp.sendEvent('errp.trigger', 'start') if not DEBUG: sleep(1) selected = errp_communicate(menu, position) if selected: break if position == 2: navigation_screen(position, green) bufhelp.sendEvent('errp.trigger', 'start') if not DEBUG: sleep(1) selected = errp_communicate(menu, position) if selected: break if position == 3: navigation_screen(position, green) bufhelp.sendEvent('errp.trigger', 'start') if not DEBUG: sleep(1) selected = errp_communicate(menu, position) if selected: break if position == 4: navigation_screen(position, green) bufhelp.sendEvent('errp.trigger', 'start') if not DEBUG: sleep(1) selected = errp_communicate(menu, position) if selected: break # home selected if position == 5: navigation_screen(position, green) bufhelp.sendEvent('errp.trigger', 'start') if not DEBUG: sleep(1) selected = errp_communicate(menu, position) if selected: break # sos selected if position == 6: navigation_screen(position, green) bufhelp.sendEvent('errp.trigger', 'start') if not DEBUG: sleep(1) selected = errp_communicate(menu, position) if selected: break if int(evt.value) == 3: pass
## init connection to the buffer ftc,hdr=bufhelp.connect(); #wait for key-press to continue [_.set(facecolor=bgColor) for _ in hdls] txthdl.set(text='Press key to start') drawnow() waitforkey(fig) bufhelp.sendEvent('stimulus.training','start') state=None ## STARTING stimulus loop for si,tgt in enumerate(tgtSeq): # YOUR CODE HERE # #catch the prediction # N.B. use state to track which events processed so far events,state = bufhelp.buffer_newevents('classifier.prediction',1500,state) # reset the display hdls[-1].set_xy(stimPos[-1,:]) [ _.set(visible=False) for _ in hdls] txthdl.set(visible=False) drawnow() bufhelp.sendEvent('stimulus.trial','end'); bufhelp.sendEvent('stimulus.training','end') txthdl.set(text=['Thanks for taking part!' '' 'Press key to finish']) waitforkey(fig)
keys[event.key] = down if event.type == QUIT or keys[K_ESCAPE]: sys.exit() screen.fill(BACKGROUND_COLOR) # check if an enemy needs to spawn if curtime - last_enemy_spawned > ENEMY_SPAWN_TIME: enemy_group.add(EnemySprite(left)) left = not left last_enemy_spawned = curtime if not SIMULATION and curtime - last_pred_time > PREDICTION_TIME and isinstance(controller, PlayerController): # Ask for a new prediction and process the predictions received from the BCI last_pred_time = curtime bufhelp.sendEvent('experiment.predict', 1) events = bufhelp.buffer_newevents('classifier.prediction', timeout_ms=0.01) for event in events: print(f'Got prediction event: {event.value}') controller.move(event.value[0]) ship_start_pos = ship.position[0] if SIMULATION and curtime - last_pred_time > PREDICTION_TIME and isinstance(controller, ProbablisticConroller): # Use the probabilistic controller last_pred_time = curtime if len(enemy_group) > 0: lowest_left = max(enemy_group, key=lambda e: e.rect.bottom if hasattr(e, 'rect') else 0).left controller.target_position = -1 if lowest_left else 1 controller.move(0) ship_start_pos = ship.position[0]