コード例 #1
0
    def _get_data_for_psd(self, inquiry_timing):
        # get data from the DAQ
        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,
            buf_length=self.trial_length)

        # filter it
        notch_filterted_data = notch.notch_filter(raw_data, self.fs,
                                                  self.notch_filter_frequency)
        filtered_data = bandpass.butter_bandpass_filter(
            notch_filterted_data,
            self.filter_low,
            self.filter_high,
            self.fs,
            order=self.filter_order)
        data = downsample.downsample(filtered_data,
                                     factor=self.downsample_rate)
        letters, times, target_info = self.letter_info(triggers, target_info)

        # reshape with the filtered data with our desired window length
        reshaped_data, _, _, _ = trial_reshaper(target_info,
                                                times,
                                                data,
                                                fs=self.fs,
                                                k=self.downsample_rate,
                                                mode='calibration',
                                                channel_map=self.channel_map,
                                                trial_length=self.trial_length)
        return reshaped_data
コード例 #2
0
ファイル: icon_to_icon.py プロジェクト: theGreenJedi/BciPy
    def execute(self):
        self.logger.debug('Starting Icon to Icon Task!')

        icons = [random.choice(self.alp) for _ in range(self.stim_number)]
        self.logger.debug(f'Icon sequence: {icons}')

        selections = []
        copy_phrase_task = self.init_copy_phrase_task(task_list=[(icons, [])])
        epoch = EpochManager(icons, copy_phrase_task, self.timing[0])
        correct_trials = 0

        data = self.init_session_data(save=True)
        run = self.await_start()

        epoch.next()
        while run and self.user_wants_to_continue():

            sequence_timing = self.present_sequence(
                epoch.current_sequence,
                epoch.current_durations,
                show_target=epoch.first_sequence)

            # Write triggers to file
            write_triggers_from_sequence_icon_to_icon(
                sequence_timing, self.trigger_file, epoch.target,
                target_displayed=epoch.first_sequence)

            core.wait(self.buffer_val)

            # Delete calibration
            if epoch.first_stimulus:
                del sequence_timing[0]

            # Delete the target presentation
            if epoch.first_sequence:
                del sequence_timing[0]

            # Reshape the data and triggers as needed for analysis.
            raw_data, triggers, target_info = process_data_for_decision(
                sequence_timing, self.daq, self.window, self.parameters,
                self.rsvp.first_stim_time)

            # Data Record for session.json
            entry = {
                'stimuli': epoch.stimuli,
                'eeg_len': len(raw_data),
                'timing_sti': epoch.timing_sti,
                'triggers': triggers,
                'target_info': target_info,
                'target_letter': epoch.target
            }

            if self.fake:
                new_epoch = True
                correct_trials += 1
                selections.append(epoch.target)
                self.display_feedback(selection=epoch.target, correct=True)
            else:
                # Evaluate the data and make a decision.
                decision_made, new_sti = copy_phrase_task.evaluate_sequence(
                    raw_data, triggers, target_info,
                    self.collection_window_len)
                new_epoch = decision_made

                # Add the evidence to the data record.
                ev_hist = copy_phrase_task.conjugator.evidence_history
                likelihood = copy_phrase_task.conjugator.likelihood
                entry['lm_evidence'] = ev_hist['LM'][0].tolist()
                entry['eeg_evidence'] = ev_hist['ERP'][-1].tolist()
                entry['likelihood'] = likelihood.tolist()

                if decision_made:
                    selection = copy_phrase_task.decision_maker.last_selection
                    selections.append(selection)
                    correct = selection == epoch.target
                    if correct:
                        correct_trials += 1
                    self.display_feedback(selection, correct)

            epoch.add_stim_data(entry)
            self.update_session_data(data, epoch, save=True)
            if new_epoch:
                epoch.next()
            else:
                epoch.next_stimulus(new_sti)

            run = self.stoppage_criteria_ok(epoch.seq_counter,
                                            data['total_time_spent'])
            # end while loop

        self.write_data(correct_trials, len(selections))
        self.exit_display()
        return self.file_save
コード例 #3
0
ファイル: copy_phrase.py プロジェクト: CAMBI-tech/BciPy
    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