def exit_display(self): """Close the UI and cleanup""" # Say Goodbye! self.rsvp.text = trial_complete_message(self.window, self.parameters) self.rsvp.draw_static() self.window.flip() # Give the system time to process core.wait(self.buffer_val) if self.daq.is_calibrated: write_triggers_from_sequence_icon_to_icon( sequence_timing=['offset', self.daq.offset], trigger_file=self.trigger_file, target=None, target_displayed=False, offset=True) # Close this sessions trigger file and return some data self.trigger_file.close() # Wait some time before exiting so there is trailing eeg data saved core.wait(self.eeg_buffer)
def execute(self): self.logger.debug(f'Starting {self.name()}!') run = True # Check user input to make sure we should be going if not get_user_input(self.rsvp, self.wait_screen_message, self.wait_screen_message_color, first_run=True): run = False # Begin the Experiment while run: # Get sequence information given stimuli parameters (ele_sti, timing_sti, color_sti) = self.generate_stimuli() (task_text, task_color) = get_task_info(self.stim_number, self.task_info_color) # Execute the RSVP sequences for idx_o in range(len(task_text)): # check user input to make sure we should be going if not get_user_input(self.rsvp, self.wait_screen_message, self.wait_screen_message_color): break # Take a break every number of trials defined if self.enable_breaks: pause_calibration(self.window, self.rsvp, idx_o, self.parameters) # update task state self.rsvp.update_task_state(text=task_text[idx_o], color_list=task_color[idx_o]) # Draw and flip screen self.rsvp.draw_static() self.window.flip() # Get height self.rsvp.sti.height = self.stimuli_height # Schedule a sequence self.rsvp.stimuli_sequence = ele_sti[idx_o] # check if text stimuli or not for color information if self.is_txt_stim: self.rsvp.stimuli_colors = color_sti[idx_o] self.rsvp.stimuli_timing = timing_sti[idx_o] # Wait for a time core.wait(self.buffer_val) # Do the sequence last_sequence_timing = self.rsvp.do_sequence() # Write triggers for the sequence _write_triggers_from_sequence_calibration( last_sequence_timing, self.trigger_file) # Wait for a time core.wait(self.buffer_val) # Set run to False to stop looping run = False # Say Goodbye! self.rsvp.text = trial_complete_message(self.window, self.parameters) self.rsvp.draw_static() self.window.flip() # Give the system time to process core.wait(self.buffer_val) if self.daq.is_calibrated: _write_triggers_from_sequence_calibration( ['offset', self.daq.offset], self.trigger_file, offset=True) # Close this sessions trigger file and return some data self.trigger_file.close() # Wait some time before exiting so there is trailing eeg data saved core.wait(self.eeg_buffer) return self.file_save
def execute(self): self.logger.debug(f'Starting {self.name()}!') run = True # Check user input to make sure we should be going if not get_user_input(self.rsvp, self.wait_screen_message, self.wait_screen_message_color, first_run=True): run = False # Begin the Experiment while run: # Get random inquiry information given stimuli parameters (stimuli_elements, timing_sti, color_sti) = random_rsvp_calibration_inq_gen( self.alp, stim_number=self.stim_number, stim_length=self.stim_length, timing=self.timing, is_txt=self.is_txt_stim, color=self.color) (task_text, task_color) = get_task_info(self.stim_number, self._task.task_info_color) # Execute the RSVP inquiries for inquiry_idx in range(len(task_text)): # check user input to make sure we should be going if not get_user_input(self.rsvp, self.wait_screen_message, self.wait_screen_message_color): break if self.enable_breaks: pause_calibration(self.window, self.rsvp, inquiry_idx, self.parameters) # update task state self.rsvp.update_task_state(text=task_text[inquiry_idx], color_list=task_color[inquiry_idx]) # Draw and flip screen self.rsvp.draw_static() self.window.flip() # Get height self.rsvp.sti.height = self.stimuli_height # Schedule a inquiry self.rsvp.stimuli_inquiry = stimuli_elements[inquiry_idx] # check if text stimuli or not for color information if self.is_txt_stim: self.rsvp.stimuli_colors = color_sti[inquiry_idx] self.rsvp.stimuli_timing = timing_sti[inquiry_idx] # Wait for a time core.wait(self._task.buffer_val) # Do the inquiry last_inquiry_timing = self.rsvp.do_inquiry() # Write triggers for the inquiry _write_triggers_from_inquiry_calibration( last_inquiry_timing, self._task.trigger_file) self.logger.info('[Feedback] Getting Decision') position = self._get_feedback_decision(last_inquiry_timing) self.logger.info( f'[Feedback] Administering feedback position {position}') self.visual_feedback.administer(position=position) # Wait for a time core.wait(self._task.buffer_val) # Set run to False to stop looping run = False # Say Goodbye! self.rsvp.text = trial_complete_message(self.window, self.parameters) self.rsvp.draw_static() self.window.flip() # Give the system time to process core.wait(self._task.buffer_val) if self.daq.is_calibrated: _write_triggers_from_inquiry_calibration( ['offset', self.daq.offset], self._task.trigger_file, offset=True) # Close this sessions trigger file and return some data self._task.trigger_file.close() # Wait some time before exiting so there is trailing eeg data saved core.wait(self._task.eeg_buffer) return self.file_save
def execute(self): self.logger.debug('Starting Copy Phrase Task!') # already correctly spelled letters text_task = str(self.copy_phrase[0:self.spelled_letters_count]) task_list = [(str(self.copy_phrase), str(self.copy_phrase[0:self.spelled_letters_count]))] # Try Initializing Copy Phrase Wrapper: copy_phrase_task = CopyPhraseWrapper( self.min_num_inq, self.max_inq_per_trial, signal_model=self.signal_model, fs=self.daq.device_info.fs, k=2, alp=self.alp, task_list=task_list, lmodel=self.language_model, is_txt_stim=self.is_txt_stim, device_name=self.daq.device_info.name, device_channels=self.daq.device_info.channels, stimuli_timing=[self.time_cross, self.time_flash], decision_threshold=self.parameters['decision_threshold'], backspace_prob=self.parameters['lm_backspace_prob'], backspace_always_shown=self.parameters['backspace_always_shown'], filter_high=self.filter_high, filter_low=self.filter_low, filter_order=self.fitler_order, notch_filter_frequency=self.notch_filter_frequency) # Set new series (whether to present a new series), # run (whether to cont. session), # inquiry counter (how many inquiries have occured). # series counter and index # (what series, and how many inquiries within it) new_series = True run = True inq_counter = 0 series_counter = 0 series_index = 0 # Init session data and save before beginning data = { 'session': self.file_save, 'session_type': 'Copy Phrase', 'paradigm': 'RSVP', 'series': {}, 'total_time_spent': self.experiment_clock.getTime(), 'total_number_series': 0, } # Save session data _save_session_related_data(self.session_save_location, data) # check user input to make sure we should be going if not get_user_input(self.rsvp, self.wait_screen_message, self.wait_screen_message_color, first_run=True): run = False # Start the Session! while run: # check user input to make sure we should be going if not get_user_input(self.rsvp, self.wait_screen_message, self.wait_screen_message_color): break if self.copy_phrase[0:len(text_task)] == text_task: # if correctly spelled so far, get the next unspelled letter. target_letter = self.copy_phrase[len(text_task)] else: # otherwise target is the backspace char. target_letter = '<' # Get inquiry information if new_series: # Init an series, getting initial stimuli new_series, sti = copy_phrase_task.initialize_series() ele_sti = sti[0] timing_sti = sti[1] color_sti = sti[2] # Increase series number and reset series index series_counter += 1 data['series'][series_counter] = {} series_index = 0 else: series_index += 1 # Update task state and reset the static self.rsvp.update_task_state(text=text_task, color_list=['white']) self.rsvp.draw_static() self.window.flip() # Setup the new Stimuli self.rsvp.stimuli_inquiry = ele_sti[0] if self.is_txt_stim: self.rsvp.stimuli_colors = color_sti[0] self.rsvp.stimuli_timing = timing_sti[0] # Pause for a time core.wait(self.buffer_val) # Do the self.RSVP inquiry! inquiry_timing = self.rsvp.do_inquiry() # Write triggers to file _write_triggers_from_inquiry_copy_phrase(inquiry_timing, self.trigger_file, self.copy_phrase, text_task) core.wait(self.buffer_val) # Delete calibration if inq_counter == 0: del inquiry_timing[0] # reshape the data and triggers as needed for later modules raw_data, triggers, target_info = \ process_data_for_decision( inquiry_timing, self.daq, self.window, self.parameters, self.rsvp.first_stim_time, self.static_offset) # Uncomment this to turn off fake decisions, but use fake data. # self.fake = False if self.fake: # Construct Data Record data['series'][series_counter][series_index] = { 'stimuli': ele_sti, 'eeg_len': len(raw_data), 'timing_sti': timing_sti, 'triggers': triggers, 'target_info': target_info, 'target_letter': target_letter, 'current_text': text_task, 'copy_phrase': self.copy_phrase } # Evaluate this inquiry (target_letter, text_task, run) = \ fake_copy_phrase_decision(self.copy_phrase, target_letter, text_task) # here we assume, in fake mode, all inquiries result in a # selection. last_selection = text_task[-1] new_series, sti = copy_phrase_task.initialize_series() # Update next state for this record data['series'][ series_counter][ series_index][ 'next_display_state'] = \ text_task else: # Evaluate this inquiry, returning whether to gen a new # series (inq) or stimuli to present new_series, sti = \ copy_phrase_task.evaluate_inquiry( raw_data, triggers, target_info, self.collection_window_len) # Construct Data Record data['series'][series_counter][series_index] = { 'stimuli': ele_sti, 'eeg_len': len(raw_data), 'timing_sti': timing_sti, 'triggers': triggers, 'target_info': target_info, 'current_text': text_task, 'copy_phrase': self.copy_phrase, 'next_display_state': copy_phrase_task.decision_maker.displayed_state, 'lm_evidence': copy_phrase_task.conjugator.evidence_history['LM'] [0].tolist(), 'eeg_evidence': copy_phrase_task.conjugator.evidence_history['ERP'] [-1].tolist(), 'likelihood': copy_phrase_task.conjugator.likelihood.tolist() } # If new_series is False, get the stimuli info returned if not new_series: ele_sti = sti[0] timing_sti = sti[1] color_sti = sti[2] # Get the current task text from the decision maker text_task = copy_phrase_task.decision_maker.displayed_state last_selection = copy_phrase_task.decision_maker.last_selection # if a letter was selected and feedback enabled, show the chosen # letter if new_series and self.show_feedback: self.feedback.administer(last_selection, message='Selected:', line_color=self.feedback_color, fill_color=self.feedback_color) # Update time spent and save data data['total_time_spent'] = self.experiment_clock.getTime() data['total_number_series'] = series_counter _save_session_related_data(self.session_save_location, data) # Decide whether to keep the task going max_tries_exceeded = inq_counter >= self.max_inq_length max_time_exceeded = data['total_time_spent'] >= self.max_seconds if (text_task == self.copy_phrase or max_tries_exceeded or max_time_exceeded): if max_tries_exceeded: self.logger.debug( 'COPYPHRASE ERROR: Max tries exceeded. To allow for more tries ' 'adjust the max_inq_len parameter.') if max_time_exceeded: self.logger.debug( 'COPYPHRASE ERROR: Max time exceeded. To allow for more time ' 'adjust the max_minutes parameter.') run = False # Increment inquiry counter inq_counter += 1 # Update task state and reset the static self.rsvp.update_task_state(text=text_task, color_list=['white']) # Say Goodbye! self.rsvp.text = trial_complete_message(self.window, self.parameters) self.rsvp.draw_static() self.window.flip() # Give the system time to process core.wait(self.buffer_val) if self.daq.is_calibrated: _write_triggers_from_inquiry_copy_phrase( ['offset', self.daq.offset], self.trigger_file, self.copy_phrase, text_task, offset=True) # Close the trigger file for this session self.trigger_file.close() # Wait some time before exiting so there is trailing eeg data saved core.wait(self.eeg_buffer) return self.file_save