示例#1
0
    def run_block(self, block_num, total_blocks, block_type):
        cur_block = self.create_block(block_num, self.combinations, block_type)

        for i in range(cur_block.shape[0]):
            self.display_trial(i, cur_block, block_type)

        if block_type == "main":
            # Add block data to all_data
            self.all_data = pd.concat([self.all_data, cur_block])

        # End of block screen
        if block_num != total_blocks - 1:  # If not the final block
            self.screen.blit(self.background, (0, 0))
            display.text(
                self.screen,
                self.font,
                "End of current block. "
                "Start next block when you're ready...",
                100,
                "center",
            )
            display.text_space(self.screen, self.font, "center",
                               (self.screen_y / 2) + 100)
            pygame.display.flip()

            display.wait_for_space()
示例#2
0
    def display_sequence(self, sequence):
        for i, number in enumerate(sequence):
            # Display number
            self.screen.blit(self.background, (0, 0))
            display.text(self.screen, self.stim_font, number, "center",
                         "center")
            pygame.display.flip()

            display.wait(self.STIM_DURATION)

            # Display blank screen
            display.blank_screen(self.screen, self.background,
                                 self.BETWEEN_STIM_DURATION)
示例#3
0
    def display_sequence(self, sequence):
        for i, number in enumerate(sequence):
            # Display number
            self.screen.blit(self.background, (0, 0))
            display.text(self.screen, self.stim_font, number,
                         "center", "center")
            pygame.display.flip()

            display.wait(self.STIM_DURATION)

            # Display blank screen
            display.blank_screen(self.screen, self.background,
                                 self.BETWEEN_STIM_DURATION)
    def display_numbers(self, i, data):
        for number in data['sequence'][i]:
            self.screen.blit(self.background, (0, 0))
            display.text(self.screen, self.stimulus_font, number, "center",
                         "center")
            pygame.display.flip()

            display.wait(self.STIM_DURATION)

            self.screen.blit(self.background, (0, 0))
            pygame.display.flip()

            display.wait(self.INTER_NUMBER_DURATION)

        return data['sequence'][i]
示例#5
0
    def number_entry(self):
        user_sequence = ""

        # Clear the event queue before checking for responses
        pygame.event.clear()

        entry = True
        while entry:
            for event in pygame.event.get():
                if event.type == KEYDOWN and event.key == K_RETURN:
                    entry = False
                elif event.type == KEYDOWN and event.key == K_F12:
                    sys.exit(0)
                elif event.type == KEYDOWN and event.key == K_BACKSPACE:
                    if user_sequence:
                        # Remove last number in entered string
                        user_sequence = user_sequence[:-1]
                elif event.type == KEYDOWN:
                    try:
                        # Only allow key press of used numbers
                        key_pressed = int(pygame.key.name(event.key))
                        if key_pressed in self.NUMBERS_USED:
                            user_sequence += pygame.key.name(event.key)
                    except ValueError:
                        pass

            self.screen.blit(self.background, (0, 0))
            display.text(
                self.screen,
                self.font,
                "Type the sequence in backwards order:",
                50,
                self.screen_y / 4,
            )

            display.text(self.screen, self.stimulus_font, user_sequence,
                         "center", "center")

            pygame.display.flip()

        return user_sequence
示例#6
0
    def run_block(self, block_num, total_blocks, block_type):
        cur_block = self.create_block(
            block_num, self.combinations, block_type)

        for i in range(cur_block.shape[0]):
            self.display_trial(i, cur_block, block_type)

        if block_type == "main":
            # Add block data to all_data
            self.all_data = pd.concat([self.all_data, cur_block])

        # End of block screen
        if block_num != total_blocks - 1:  # If not the final block
            self.screen.blit(self.background, (0, 0))
            display.text(self.screen, self.font,
                         "End of current block. "
                         "Start next block when you're ready...",
                         100, "center")
            display.text_space(self.screen, self.font,
                               "center", (self.screen_y/2) + 100)
            pygame.display.flip()

            display.wait_for_space()
示例#7
0
    def run(self):
        # Instructions
        self.screen.blit(self.background, (0, 0))
        display.text(self.screen, self.font, "SART", "center",
                     self.screen_y / 2 - 250, (255, 255, 255))

        display.text(self.screen, self.font,
                     "Numbers will appear in the center of the screen.", 100,
                     self.screen_y / 2 - 150, (255, 255, 255))

        display.text(self.screen, self.font,
                     "Press the spacebar after you see a number.", 100,
                     self.screen_y / 2 - 50, (255, 255, 255))

        display.text(
            self.screen, self.font, "However, if the number is a 3, "
            "do NOT press the spacebar.", 100, self.screen_y / 2 + 50,
            (255, 255, 255))

        display.text(
            self.screen, self.font, "Please respond as quickly, "
            "and as accurately, as possible", 100, self.screen_y / 2 + 150,
            (255, 255, 255))

        display.text_space(self.screen, self.font, "center",
                           self.screen_y / 2 + 300, (255, 255, 255))

        pygame.display.flip()

        display.wait_for_space()

        # Instructions Practice
        self.screen.blit(self.background, (0, 0))
        display.text(self.screen, self.font,
                     "We will begin with a few practice trials...", "center",
                     "center", (255, 255, 255))

        display.text_space(self.screen, self.font, "center",
                           self.screen_y / 2 + 100, (255, 255, 255))

        pygame.display.flip()

        display.wait_for_space()

        # Blank screen
        display.blank_screen(self.screen, self.background, self.BLANK_DURATION)

        # Show practice trials
        practice_trials = pd.DataFrame([5, 7, 7, 3, 9, 2, 1, 3, 8, 6],
                                       columns=['stimulus'])

        for i in range(practice_trials.shape[0]):
            self.display_trial(i, practice_trials)

        # Practice end screen
        self.screen.blit(self.background, (0, 0))
        display.text(self.screen, self.font, "End of practice trials", 100,
                     self.screen_y / 2 - 100, (255, 255, 255))

        display.text(self.screen, self.font,
                     "We will now begin the main trials...", 100, "center",
                     (255, 255, 255))

        display.text_space(self.screen, self.font, "center",
                           self.screen_y / 2 + 100, (255, 255, 255))

        pygame.display.flip()

        display.wait_for_space()

        # Blank screen
        display.blank_screen(self.screen, self.background, self.BLANK_DURATION)

        # Show main trials
        for i in range(self.all_data.shape[0]):
            self.display_trial(i, self.all_data)

        # Rearrange dataframe
        columns = [
            'trial', 'stimulus', 'stimSize', 'RT', 'key press', 'accuracy'
        ]
        self.all_data = self.all_data[columns]

        # End screen
        self.screen.blit(self.background, (0, 0))
        display.text(self.screen, self.font, "End of task", "center", "center",
                     (255, 255, 255))

        display.text_space(self.screen, self.font, "center",
                           self.screen_y / 2 + 100, (255, 255, 255))

        pygame.display.flip()

        display.wait_for_space()

        print("- SART complete")

        return self.all_data
    def run(self):
        # Instructions
        self.screen.blit(self.background, (0, 0))

        display.text(self.screen, self.font, "Backwards Digit Span", "center",
                     self.screen_y / 2 - 300)

        display.text(
            self.screen, self.font, "You will be shown a number sequence, "
            "one number at a time", 100, self.screen_y / 2 - 200)

        display.text(self.screen, self.font, "Memorize the number sequence",
                     100, self.screen_y / 2 - 100)

        display.text(
            self.screen, self.font,
            "You will then be asked to type the sequence "
            "in reverse/backwards order. For example...", 100, "center")

        display.text(self.screen, self.font, "Sequence: 1 2 3 4 5", "center",
                     self.screen_y / 2 + 100)

        display.text(self.screen, self.font, "Correct: 5 4 3 2 1", "center",
                     self.screen_y / 2 + 150)

        display.text(
            self.screen, self.font,
            "The sequences will get longer throughout the experiment", 100,
            self.screen_y / 2 + 250)

        display.text_space(self.screen, self.font, "center",
                           self.screen_y / 2 + 350)

        pygame.display.flip()

        display.wait_for_space()

        # Instructions Practice
        self.screen.blit(self.background, (0, 0))

        display.text(self.screen, self.font,
                     "We will begin with a practice trial...", 100, "center")

        display.text_space(self.screen, self.font, "center",
                           self.screen_y / 2 + 100)

        pygame.display.flip()

        display.wait_for_space()

        # Practice trial
        practice_data = pd.DataFrame(['13579'], columns=['sequence'])
        correct_sequence_p = self.display_numbers(0, practice_data)
        user_sequence_p = self.number_entry()

        # Practice feedback screen
        self.screen.blit(self.background, (0, 0))

        # Check if reverse of user input matches the correct sequence
        if self.check_answer(user_sequence_p, correct_sequence_p):
            display.text(self.screen, self.font, "Correct", "center", "center",
                         (0, 255, 0))
        else:
            display.text(self.screen, self.font, "Incorrect", "center",
                         "center", (255, 0, 0))

        pygame.display.flip()

        display.wait(self.FEEDBACK_DURATION)

        # Practice end screen
        self.screen.blit(self.background, (0, 0))
        display.text(self.screen, self.font,
                     "We will now begin the main trials...", 100, "center")
        display.text_space(self.screen, self.font, "center",
                           self.screen_y / 2 + 100)

        pygame.display.flip()

        display.wait_for_space()

        # Main trials
        for i in range(len(self.all_data)):
            correct_sequence = self.display_numbers(i, self.all_data)
            user_sequence = self.number_entry()

            self.all_data.set_value(i, 'user_sequence', user_sequence)

            if self.check_answer(user_sequence, correct_sequence):
                self.all_data.set_value(i, 'correct', 1)
            else:
                self.all_data.set_value(i, 'correct', 0)

        # End screen
        self.screen.blit(self.background, (0, 0))
        display.text(self.screen, self.font, "End of task", "center", "center")
        display.text_space(self.screen, self.font, "center",
                           self.screen_y / 2 + 100)

        pygame.display.flip()

        display.wait_for_space()

        print("- Digit span (backwards) complete")

        return self.all_data
示例#9
0
    def run(self):
        # Instructions screen
        self.screen.blit(self.background, (0, 0))
        display.text(self.screen, self.font, "Sternberg Task", "center", 100)
        display.text(self.screen, self.font,
                     "You will see a sequence of numbers, one at a time. "
                     "Try your best to memorize them",
                     100, 200)

        display.text(self.screen, self.stim_font, "8 - 5 - 4 - 1 - 0 - 9",
                     "center", 300)

        display.text(self.screen, self.font,
                     "You will then be shown a single test number in blue",
                     100, 400)

        display.text(self.screen, self.stim_font, "0",
                     "center", 500, (0, 0, 255))

        display.text(self.screen, self.font,
                     "If this number was in the original sequence, "
                     "press the LEFT arrow",
                     100, 600)

        display.text(self.screen, self.font,
                     "If this number was NOT in the original sequence, "
                     "press the RIGHT arrow",
                     100, 700)

        display.text(self.screen, self.font,
                     "Try to do this as quickly, "
                     "and as accurately, as possible",
                     100, 800)

        display.text_space(self.screen, self.font, "center", 900)

        pygame.display.flip()

        display.wait_for_space()

        # Practice ready screen
        self.screen.blit(self.background, (0, 0))
        display.text(self.screen, self.font,
                     "We will begin with some practice trials...",
                     "center", "center")

        display.text_space(self.screen, self.font,
                           "center", self.screen_y/2 + 100)

        pygame.display.flip()

        display.wait_for_space()

        # Practice trials
        for i, r in self.practice_trials.iterrows():
            self.display_trial(self.practice_trials, i, r, "practice")

        # Main trials ready screen
        self.screen.blit(self.background, (0, 0))
        display.text(self.screen, self.font, "End of practice trials.",
                     100, 100)
        display.text(self.screen, self.font, "You may move on to the main "
                                             "trials when you're ready",
                     100, 300)

        display.text(self.screen, self.font, "Remember to respond as quickly "
                                             "and as accurately as possible",
                     100, 500)
        display.text(self.screen, self.font, "Your reaction time and accuracy"
                                             " will be recorded",
                     100, 600)
        display.text_space(self.screen, self.font,
                           "center", 800)

        pygame.display.flip()

        display.wait_for_space()

        # Main trials
        for i, block in enumerate(self.blocks):
            for j, r in block.iterrows():
                self.display_trial(block, j, r, "main")

            # If this is not the final block, show instructions for next block
            if i != len(self.blocks)-1:
                display.text(self.screen, self.font, "End of block.", 100, 200)
                display.text(self.screen, self.font,
                             "Take a short break, and press space when you're "
                             "ready to start the next block...", 100, 400)
                display.text_space(self.screen, self.font,
                                   "center", 700)

                pygame.display.flip()

                display.wait_for_space()

        # End screen
        self.screen.blit(self.background, (0, 0))
        display.text(self.screen, self.font, "End of task", "center", "center")
        display.text_space(self.screen, self.font,
                           "center", self.screen_y/2 + 100)
        pygame.display.flip()

        display.wait_for_space()

        # Concatenate blocks and add trial numbers
        all_data = pd.concat(self.blocks)
        all_data['trialNum'] = range(1, len(all_data) + 1)

        print "- Sternberg Task complete"

        return all_data
示例#10
0
 def display_flanker(self, flanker_type, direction):
     stimulus = self.flanker_stim[direction][flanker_type]
     display.text(
         self.screen, self.font_stim, stimulus, "center", "center", self.colour_font
     )
    def start(self):
        # Store input values
        sub_num = self.subNumBox.text()
        condition = self.conditionBox.text()
        age = self.ageBox.text()
        ra = self.raBox.text()
        current_date = datetime.datetime.now().strftime("%Y-%m-%d %H:%M")

        if self.maleRadio.isChecked():
            sex = "male"
        else:
            sex = "female"

        # Get *selected* tasks and task order
        selected_tasks = []
        for index in range(self.taskList.count()):
            # State 2 is set when item is selected
            if self.taskList.item(index).checkState() == 2:
                # Add selected task to task list
                selected_tasks.append(str(self.taskList.item(index).text()))

        # Check to see if a random order is desired
        # If so, shuffle tasks
        if self.random_order_selected():
            random.shuffle(selected_tasks)

        # Check for required inputs
        if not selected_tasks:
            self.error_dialog("No tasks selected")
        elif not ra:
            self.error_dialog("Please enter RA name...")
        elif not sub_num:
            self.error_dialog("Please enter a subject number...")
        elif not condition:
            self.error_dialog("Please enter a condition number...")
        elif not age:
            self.error_dialog("Please enter an age...")
        elif not self.maleRadio.isChecked() and not \
                self.femaleRadio.isChecked():
            self.error_dialog("Please select a sex...")
        else:
            # Store subject info into a dataframe
            subject_info = pd.DataFrame(data=[
                (str(current_date), str(sub_num), str(condition), int(age),
                 str(sex), str(ra), ", ".join(selected_tasks))
            ],
                                        columns=[
                                            "datetime", "sub_num", "condition",
                                            "age", "sex", "RA", "tasks"
                                        ])

            # Check if subject number already exists
            existing_subs = [
                x.split("_")[0] for x in os.listdir(self.dataPath)
            ]
            if sub_num in existing_subs:
                self.error_dialog("Subject number already exists")
            else:
                # Create the excel writer object and save the file
                data_file_name = "%s_%s.xls" % (sub_num, condition)
                output_file = os.path.join(self.dataPath, data_file_name)
                writer = pd.ExcelWriter(output_file)
                subject_info.to_excel(writer, "info", index=False)
                writer.save()

                # Minimize battery UI
                self.showMinimized()

                # Get most recent task settings from file
                self.get_settings()

                # Center all pygame windows if not fullscreen
                if not self.task_fullscreen:
                    pos_x = self.res_width // 2 - self.task_width // 2
                    pos_y = self.res_height // 2 - self.task_height // 2

                    os.environ["SDL_VIDEO_WINDOW_POS"] = \
                        "%s, %s" % (str(pos_x), str(pos_y))

                # Initialize pygame
                pygame.init()

                # Load beep sound
                beep_sound = pygame.mixer.Sound(
                    os.path.join(self.base_dir, "tasks", "media",
                                 "beep_med.wav"))

                # Set pygame icon image
                image = os.path.join(self.base_dir, "images", "icon_sml.png")
                icon_img = pygame.image.load(image)
                pygame.display.set_icon(icon_img)

                # Create primary task window
                # pygame_screen is passed to each task as the display window
                if self.task_fullscreen:
                    self.pygame_screen = pygame.display.set_mode(
                        (0, 0), pygame.FULLSCREEN)
                else:
                    if self.task_borderless:
                        self.pygame_screen = pygame.display.set_mode(
                            (self.task_width, self.task_height),
                            pygame.NOFRAME)
                    else:
                        self.pygame_screen = pygame.display.set_mode(
                            (self.task_width, self.task_height))

                background = pygame.Surface(self.pygame_screen.get_size())
                background = background.convert()

                # Run each task
                # Return and save their output to dataframe/excel
                for task in selected_tasks:
                    if task == "Attention Network Test (ANT)":
                        # Set number of blocks for ANT
                        ant_task = ant.ANT(self.pygame_screen,
                                           background,
                                           blocks=self.ant_blocks)
                        # Run ANT
                        ant_data = ant_task.run()
                        # Save ANT data to excel
                        ant_data.to_excel(writer, "ANT", index=False)
                    elif task == "Digit Span (backwards)":
                        digitspan_backwards_task = digitspan_backwards.DigitspanBackwards(
                            self.pygame_screen, background)
                        # Run Digit span (Backwards)
                        digitspan_backwards_data = digitspan_backwards_task.run(
                        )
                        # Save digit span (backwards) data to excel
                        digitspan_backwards_data.to_excel(
                            writer, "Digit span (backwards)", index=False)
                    elif task == "Eriksen Flanker Task":
                        flanker_task = flanker.Flanker(
                            self.pygame_screen, background,
                            self.flanker_dark_mode, self.flanker_sets_practice,
                            self.flanker_sets_main, self.flanker_blocks_compat,
                            self.flanker_blocks_incompat,
                            self.flanker_block_order)
                        # Run Eriksen Flanker
                        flanker_data = flanker_task.run()
                        # Save flanker data to excel
                        flanker_data.to_excel(writer,
                                              "Eriksen Flanker",
                                              index=False)
                    elif task == "Mental Rotation Task":
                        mrt_task = mrt.MRT(self.pygame_screen, background)
                        # Run MRT
                        mrt_data = mrt_task.run()
                        # Save MRT data to excel
                        mrt_data.to_excel(writer, "MRT", index=False)
                    elif task == "Raven's Progressive Matrices":
                        ravens_task = ravens.Ravens(
                            self.pygame_screen,
                            background,
                            start=self.ravens_start,
                            numTrials=self.ravens_trials)
                        # Run Raven's Matrices
                        ravens_data = ravens_task.run()
                        # Save ravens data to excel
                        ravens_data.to_excel(writer,
                                             "Ravens Matrices",
                                             index=False)
                    elif task == "Sternberg Task":
                        sternberg_task = sternberg.Sternberg(
                            self.pygame_screen,
                            background,
                            blocks=self.sternberg_blocks)
                        # Run Sternberg Task
                        sternberg_data = sternberg_task.run()
                        # Save sternberg data to excel
                        sternberg_data.to_excel(writer,
                                                "Sternberg",
                                                index=False)
                    elif task == "Sustained Attention to Response Task (SART)":
                        sart_task = sart.SART(self.pygame_screen, background)
                        # Run SART
                        sart_data = sart_task.run()
                        # Save SART data to excel
                        sart_data.to_excel(writer, "SART", index=False)

                    # Play beep after each task
                    if self.task_beep:
                        beep_sound.play()

                    # Save excel file
                    writer.save()

                # End of experiment screen
                pygame.display.set_caption("Cognitive Battery")
                pygame.mouse.set_visible(1)

                background.fill((255, 255, 255))
                self.pygame_screen.blit(background, (0, 0))

                font = pygame.font.SysFont("arial", 30)
                display.text(self.pygame_screen, font, "End of Experiment",
                             "center", "center")

                pygame.display.flip()

                display.wait_for_space()

                # Quit pygame
                pygame.quit()

                print("--- Experiment complete")
                self.close()
示例#12
0
    def display_trial(self, df, i, r, trial_type):
        # Clear screen
        self.screen.blit(self.background, (0, 0))
        pygame.display.flip()

        # Display number sequence
        self.display_sequence(r['set'])

        # Display probe warning
        self.screen.blit(self.background, (0, 0))
        display.text(self.screen, self.stim_font, "+", "center", "center")
        pygame.display.flip()

        display.wait(self.PROBE_WARN_DURATION)

        # Display blank screen
        display.blank_screen(self.screen, self.background,
                             self.BETWEEN_STIM_DURATION)

        # Display probe
        self.screen.blit(self.background, (0, 0))
        display.text(self.screen, self.stim_font, r['probe'], "center",
                     "center", (0, 0, 255))

        # Display key reminders if practice trials
        if trial_type == "practice":
            display.image(self.screen, self.img_left,
                          450 - self.img_left.get_rect().width / 2,
                          self.screen_y / 2 + 150)

            yes_text = self.font.render("(yes)", 1, (0, 0, 0))
            display.text(self.screen, self.font, yes_text,
                         450 - yes_text.get_rect().width / 2,
                         self.screen_y / 2 + 160)

            display.image(
                self.screen, self.img_right,
                self.screen_x - 450 - self.img_right.get_rect().width / 2,
                self.screen_y / 2 + 150)

            no_text = self.font.render("(no)", 1, (0, 0, 0))
            display.text(self.screen, self.font, no_text,
                         self.screen_x - 450 - no_text.get_rect().width / 2,
                         self.screen_y / 2 + 160)

        pygame.display.flip()

        start_time = int(round(time.time() * 1000))

        # Clear the event queue before checking for responses
        pygame.event.clear()
        wait_response = True
        while wait_response:
            for event in pygame.event.get():
                if event.type == KEYDOWN and event.key == K_LEFT:
                    df.set_value(i, "response", "present")
                    wait_response = False
                elif event.type == KEYDOWN and event.key == K_RIGHT:
                    df.set_value(i, "response", "absent")
                    wait_response = False
                elif event.type == KEYDOWN and event.key == K_F12:
                    sys.exit(0)

            end_time = int(round(time.time() * 1000))

            # If time limit has been reached, consider it a missed trial
            if end_time - start_time >= self.PROBE_DURATION:
                wait_response = False

        # Store RT
        rt = int(round(time.time() * 1000)) - start_time
        df.set_value(i, "RT", rt)

        # Display blank screen
        display.blank_screen(self.screen, self.background,
                             self.BETWEEN_STIM_DURATION)

        # Display feedback
        self.screen.blit(self.background, (0, 0))

        if rt >= self.PROBE_DURATION:
            df.set_value(i, "correct", 0)
            display.text(self.screen, self.font, "too slow", "center",
                         "center", (255, 165, 0))
        else:
            if df["probeType"][i] == df["response"][i]:
                df.set_value(i, "correct", 1)
                display.text(self.screen, self.font, "correct", "center",
                             "center", (0, 255, 0))
            else:
                df.set_value(i, "correct", 0)
                display.text(self.screen, self.font, "incorrect", "center",
                             "center", (255, 0, 0))

        pygame.display.flip()

        display.wait(self.FEEDBACK_DURATION)

        # Display blank screen (ITI)
        display.blank_screen(self.screen, self.background, self.ITI)
示例#13
0
    def run(self):
        if self.BLOCK_ORDER == "choose":
            # If the order is "choose" but one of the block types has a 0, then dont show choose screen
            if self.BLOCKS_COMPAT == 0:
                self.BLOCK_ORDER = "incompatible"
            elif self.BLOCKS_INCOMPAT == 0:
                self.BLOCK_ORDER = "compatible"
            else:
                self.screen.blit(self.background, (0, 0))
                display.text(
                    self.screen,
                    self.font,
                    "Choose block order:",
                    100,
                    self.screen_y / 2 - 300,
                    self.colour_font,
                )
                display.text(
                    self.screen,
                    self.font,
                    "1 - Compatible first",
                    100,
                    self.screen_y / 2 - 200,
                    self.colour_font,
                )
                display.text(
                    self.screen,
                    self.font,
                    "2 - Incompatible first",
                    100,
                    self.screen_y / 2 - 150,
                    self.colour_font,
                )
                pygame.display.flip()

                wait_response = True
                while wait_response:
                    for event in pygame.event.get():
                        if event.type == KEYDOWN and event.key == K_1:
                            self.BLOCK_ORDER = "compatible"
                            wait_response = False
                        elif event.type == KEYDOWN and event.key == K_2:
                            self.BLOCK_ORDER = "incompatible"
                            wait_response = False
                        elif event.type == KEYDOWN and event.key == K_F12:
                            sys.exit(0)

        # Set block order
        if self.BLOCK_ORDER == "compatible":
            self.block_type_list = (["compatible"] * self.BLOCKS_COMPAT) + (
                ["incompatible"] * self.BLOCKS_INCOMPAT
            )
        elif self.BLOCK_ORDER == "incompatible":
            self.block_type_list = (["incompatible"] * self.BLOCKS_INCOMPAT) + (
                ["compatible"] * self.BLOCKS_COMPAT
            )

        # Instructions
        self.screen.blit(self.background, (0, 0))
        display.text(
            self.screen,
            self.font,
            "Eriksen Flanker Task",
            "center",
            self.screen_y / 2 - 300,
            self.colour_font,
        )
        display.text(
            self.screen,
            self.font,
            "Keep your eyes on the fixation cross at the " "start of each trial:",
            100,
            self.screen_y / 2 - 200,
            self.colour_font,
        )
        display.text(
            self.screen,
            self.font,
            "+",
            "center",
            self.screen_y / 2 - 150,
            self.colour_font,
        )
        display.text(
            self.screen,
            self.font,
            "A set of arrows will appear:",
            100,
            self.screen_y / 2 - 100,
            self.colour_font,
        )
        display.text(
            self.screen,
            self.font_stim,
            self.flanker_stim["left"]["incongruent"],
            "center",
            self.screen_y / 2 - 60,
            self.colour_font,
        )

        if self.block_type_list[0] == "compatible":
            display.text(
                self.screen,
                self.font,
                "Use the Left / Right arrow keys to indicate "
                "the pointing direction of the CENTER arrow.",
                100,
                self.screen_y / 2 + 70,
                self.colour_font,
            )
            display.text(
                self.screen,
                self.font,
                "In example above, you should press the LEFT key.",
                100,
                self.screen_y / 2 + 120,
                self.colour_font,
            )
        elif self.block_type_list[0] == "incompatible":
            display.text(
                self.screen,
                self.font,
                "Use the Left / Right arrow keys to indicate "
                "the OPPOSITE pointing direction of the CENTER arrow.",
                100,
                self.screen_y / 2 + 70,
                self.colour_font,
            )
            display.text(
                self.screen,
                self.font,
                "In example above, you should press the RIGHT key.",
                100,
                self.screen_y / 2 + 120,
                self.colour_font,
            )

        display.text(
            self.screen,
            self.font,
            "Respond as quickly, and as accurately, as you can",
            100,
            self.screen_y / 2 + 200,
            self.colour_font,
        )

        display.text_space(
            self.screen,
            self.font,
            "center",
            (self.screen_y / 2) + 300,
            self.colour_font,
        )
        pygame.display.flip()
        display.wait_for_space()

        # Instructions Practice
        self.screen.blit(self.background, (0, 0))
        display.text(
            self.screen,
            self.font,
            "We'll begin with some practice trials...",
            "center",
            "center",
            self.colour_font,
        )
        display.text_space(
            self.screen, self.font, "center", self.screen_y / 2 + 100, self.colour_font
        )
        pygame.display.flip()
        display.wait_for_space()

        # Practice trials
        self.run_block(0, 1, "practice", self.block_type_list[0])

        # Instructions Practice End
        self.screen.blit(self.background, (0, 0))
        display.text(
            self.screen,
            self.font,
            "We will now begin the main trials...",
            100,
            self.screen_y / 2,
            self.colour_font,
        )
        display.text_space(
            self.screen, self.font, "center", self.screen_y / 2 + 200, self.colour_font
        )
        pygame.display.flip()
        display.wait_for_space()

        # Main task second half
        if self.block_type_list[0] == "compatible":
            for i in range(self.BLOCKS_COMPAT):
                self.run_block(i, self.BLOCKS_COMPAT, "main", self.block_type_list[0])
        elif self.block_type_list[0] == "incompatible":
            for i in range(self.BLOCKS_INCOMPAT):
                self.run_block(i, self.BLOCKS_INCOMPAT, "main", self.block_type_list[0])

        # Second half (if more than one compatibility type)
        if self.block_type_list[0] != self.block_type_list[-1]:
            self.screen.blit(self.background, (0, 0))
            display.text(
                self.screen,
                self.font,
                "End of first half. Please inform the experimenter.",
                100,
                self.screen_y / 2,
                self.colour_font,
            )

            display.text_space(
                self.screen,
                self.font,
                "center",
                self.screen_y / 2 + 200,
                self.colour_font,
            )
            pygame.display.flip()
            display.wait_for_space()

            # Practice instructions
            self.screen.blit(self.background, (0, 0))
            display.text(
                self.screen,
                self.font,
                "For the second half, the task will be slightly different:",
                100,
                self.screen_y / 2 - 300,
                self.colour_font,
            )

            display.text(
                self.screen,
                self.font_stim,
                self.flanker_stim["left"]["incongruent"],
                "center",
                self.screen_y / 2 - 250,
                self.colour_font,
            )

            if self.block_type_list[-1] == "compatible":
                display.text(
                    self.screen,
                    self.font,
                    "This time, indicate the pointing direction of the CENTER arrow",
                    100,
                    self.screen_y / 2 - 100,
                    self.colour_font,
                )
                display.text(
                    self.screen,
                    self.font,
                    "So in the example above, you would press LEFT",
                    100,
                    self.screen_y / 2,
                    self.colour_font,
                )
            elif self.block_type_list[-1] == "incompatible":
                display.text(
                    self.screen,
                    self.font,
                    "This time, indicate the OPPOSITE pointing direction of the CENTER arrow",
                    100,
                    self.screen_y / 2 - 100,
                    self.colour_font,
                )
                display.text(
                    self.screen,
                    self.font,
                    "So in the example above, you would press RIGHT",
                    100,
                    self.screen_y / 2,
                    self.colour_font,
                )

            display.text(
                self.screen,
                self.font,
                "Respond as quickly, and as accurately, as you can",
                100,
                self.screen_y / 2 + 100,
                self.colour_font,
            )

            display.text_space(
                self.screen,
                self.font,
                "center",
                self.screen_y / 2 + 250,
                self.colour_font,
            )
            pygame.display.flip()
            display.wait_for_space()

            # Instructions Practice
            self.screen.blit(self.background, (0, 0))
            display.text(
                self.screen,
                self.font,
                "We'll begin with some practice trials...",
                "center",
                "center",
                self.colour_font,
            )
            display.text_space(
                self.screen,
                self.font,
                "center",
                self.screen_y / 2 + 100,
                self.colour_font,
            )
            pygame.display.flip()
            display.wait_for_space()

            # Practice trials
            self.run_block(0, 1, "practice", self.block_type_list[-1])

            # Instructions Practice End
            self.screen.blit(self.background, (0, 0))
            display.text(
                self.screen,
                self.font,
                "We will now begin the main trials...",
                100,
                self.screen_y / 2,
                self.colour_font,
            )
            display.text_space(
                self.screen,
                self.font,
                "center",
                self.screen_y / 2 + 200,
                self.colour_font,
            )
            pygame.display.flip()
            display.wait_for_space()

            # Main task
            if self.block_type_list[-1] == "compatible":
                for i in range(self.BLOCKS_COMPAT):
                    self.run_block(
                        self.BLOCKS_INCOMPAT + i,
                        self.BLOCKS_COMPAT,
                        "main",
                        self.block_type_list[-1],
                        True,
                    )
            elif self.block_type_list[-1] == "incompatible":
                for i in range(self.BLOCKS_INCOMPAT):
                    self.run_block(
                        self.BLOCKS_COMPAT + i,
                        self.BLOCKS_INCOMPAT,
                        "main",
                        self.block_type_list[-1],
                        True,
                    )

        # Create trial number column
        self.all_data["trial"] = list(range(1, len(self.all_data) + 1))

        # Rearrange the dataframe
        columns = [
            "trial",
            "block",
            "compatibility",
            "congruency",
            "direction",
            "response",
            "correct",
            "RT",
        ]
        self.all_data = self.all_data[columns]

        # End screen
        self.screen.blit(self.background, (0, 0))
        display.text(
            self.screen, self.font, "End of task", "center", "center", self.colour_font
        )
        display.text_space(
            self.screen, self.font, "center", self.screen_y / 2 + 100, self.colour_font
        )
        pygame.display.flip()

        display.wait_for_space()

        print("- Flanker complete")

        return self.all_data
示例#14
0
    def display_trial(self, trial_num, data, trial_type):
        # Check for a quit press after stimulus was shown
        for event in pygame.event.get():
            if event.type == KEYDOWN and event.key == K_F12:
                sys.exit(0)

        # Display fixation
        self.screen.blit(self.background, (0, 0))
        display.image(self.screen, self.img_fixation, "center", "center")
        pygame.display.flip()

        display.wait(data["fixationTime"][trial_num])

        # Display cue
        self.screen.blit(self.background, (0, 0))

        cue_type = data["cue"][trial_num]

        if cue_type == "nocue":
            # Display fixation in the center
            display.image(self.screen, self.img_fixation, "center", "center")
        elif cue_type == "center":
            # Display cue in the center
            display.image(self.screen, self.img_cue, "center", "center")
        elif cue_type == "double":
            # Display fixation in the center
            display.image(self.screen, self.img_fixation, "center", "center")

            # Display cue above and below fixation
            display.image(
                self.screen, self.img_cue, "center",
                self.screen_y / 2 - self.fixation_h - self.TARGET_OFFSET)
            display.image(self.screen, self.img_cue, "center",
                          self.screen_y / 2 + self.TARGET_OFFSET)
        elif cue_type == "spatial":
            cue_location = data["location"][trial_num]

            # Display fixation in the center
            display.image(self.screen, self.img_fixation, "center", "center")

            # Display cue at target location
            if cue_location == "top":
                display.image(
                    self.screen, self.img_cue, "center",
                    self.screen_y / 2 - self.fixation_h - self.TARGET_OFFSET)
            elif cue_location == "bottom":
                display.image(self.screen, self.img_cue, "center",
                              self.screen_y / 2 + self.TARGET_OFFSET)

        pygame.display.flip()

        # Display cue for certain duration
        display.wait(self.CUE_DURATION)

        # Prestim interval with fixation
        self.screen.blit(self.background, (0, 0))
        display.image(self.screen, self.img_fixation, "center", "center")
        pygame.display.flip()

        display.wait(self.PRE_STIM_FIXATION_DURATION)

        # Display flanker target
        self.screen.blit(self.background, (0, 0))
        display.image(self.screen, self.img_fixation, "center", "center")

        self.display_flanker(data["congruency"][trial_num],
                             data["location"][trial_num],
                             data["direction"][trial_num])
        pygame.display.flip()

        start_time = int(round(time.time() * 1000))

        # Clear the event queue before checking for responses
        pygame.event.clear()
        response = "NA"
        wait_response = True
        while wait_response:
            for event in pygame.event.get():
                if event.type == KEYDOWN and event.key == K_LEFT:
                    response = "left"
                    wait_response = False
                elif event.type == KEYDOWN and event.key == K_RIGHT:
                    response = "right"
                    wait_response = False
                elif event.type == KEYDOWN and event.key == K_F12:
                    sys.exit(0)

            end_time = int(round(time.time() * 1000))

            # If time limit has been reached, consider it a missed trial
            if end_time - start_time >= self.FLANKER_DURATION:
                wait_response = False

        # Store reaction time and response
        rt = int(round(time.time() * 1000)) - start_time
        data.set_value(trial_num, 'RT', rt)
        data.set_value(trial_num, 'response', response)

        correct = 1 if response == data["direction"][trial_num] else 0
        data.set_value(trial_num, 'correct', correct)

        # Display feedback if practice trials
        if trial_type == "practice":
            self.screen.blit(self.background, (0, 0))
            if correct == 1:
                display.text(self.screen, self.font, "correct", "center",
                             "center", (0, 255, 0))
            else:
                display.text(self.screen, self.font, "incorrect", "center",
                             "center", (255, 0, 0))
            pygame.display.flip()

            display.wait(self.FEEDBACK_DURATION)

        # Display fixation during ITI
        self.screen.blit(self.background, (0, 0))
        display.image(self.screen, self.img_fixation, "center", "center")
        pygame.display.flip()

        iti = self.ITI_MAX - rt - data["fixationTime"][trial_num]
        data.set_value(trial_num, 'ITI', iti)

        display.wait(iti)
示例#15
0
    def display_trial(self, i, data):
        # Randomly choose font size for this trial
        size_index = random.randint(0, len(self.stim_fonts) - 1)
        trial_font = self.stim_fonts[size_index]

        key_press = 0
        data.set_value(i, 'RT', 1150)

        # Display number
        self.screen.blit(self.background, (0, 0))
        display.text(self.screen, trial_font, str(data["stimulus"][i]),
                     "center", "center", (255, 255, 255))
        pygame.display.flip()

        # Get start time in ms
        start_time = int(round(time.time() * 1000))

        # Clear the event queue before checking for responses
        pygame.event.clear()
        wait_response = True
        while wait_response:
            for event in pygame.event.get():
                if event.type == KEYDOWN and event.key == K_SPACE:
                    key_press = 1
                    data.set_value(i, 'RT',
                                   int(round(time.time() * 1000)) - start_time)
                elif event.type == KEYDOWN and event.key == K_F12:
                    sys.exit(0)

            end_time = int(round(time.time() * 1000))

            # Stop this loop if stim duration has passed
            if end_time - start_time >= self.STIM_DURATION:
                wait_response = False

        # Display mask
        self.screen.blit(self.background, (0, 0))
        display.image(self.screen, self.img_mask, "center", "center")
        pygame.display.flip()

        wait_response = True
        while wait_response:
            for event in pygame.event.get():
                if event.type == KEYDOWN and event.key == K_SPACE:
                    if key_press == 0:
                        key_press = 1
                        data.set_value(
                            i, 'RT',
                            int(round(time.time() * 1000)) - start_time)
                elif event.type == KEYDOWN and event.key == K_F12:
                    sys.exit(0)

            end_time = int(round(time.time() * 1000))

            # Stop this loop if mask duration has passed
            if end_time - start_time >= self.MASK_DURATION:
                wait_response = False

        # Check if response is correct
        if data["stimulus"][i] == 3:
            if key_press == 0:
                accuracy = 1
            else:
                accuracy = 0
        else:
            if key_press == 0:
                accuracy = 0
            else:
                accuracy = 1

        # Store key press data in dataframe
        data.set_value(i, 'key press', key_press)
        data.set_value(i, 'accuracy', accuracy)
        data.set_value(i, 'stimSize', self.STIMSIZES_PT[size_index])
示例#16
0
    def display_trial(self, trial_num, data, trial_type):
        # Check for a quit press after stimulus was shown
        for event in pygame.event.get():
            if event.type == KEYDOWN and event.key == K_F12:
                sys.exit(0)

        # Display fixation
        self.screen.blit(self.background, (0, 0))
        display.image(self.screen, self.img_fixation, "center", "center")
        pygame.display.flip()

        display.wait(data["fixationTime"][trial_num])

        # Display cue
        self.screen.blit(self.background, (0, 0))

        cue_type = data["cue"][trial_num]

        if cue_type == "nocue":
            # Display fixation in the center
            display.image(self.screen, self.img_fixation, "center", "center")
        elif cue_type == "center":
            # Display cue in the center
            display.image(self.screen, self.img_cue, "center", "center")
        elif cue_type == "double":
            # Display fixation in the center
            display.image(self.screen, self.img_fixation, "center", "center")

            # Display cue above and below fixation
            display.image(
                self.screen, self.img_cue, "center",
                self.screen_y/2 - self.fixation_h - self.TARGET_OFFSET)
            display.image(self.screen, self.img_cue,
                          "center", self.screen_y/2 + self.TARGET_OFFSET)
        elif cue_type == "spatial":
            cue_location = data["location"][trial_num]

            # Display fixation in the center
            display.image(self.screen, self.img_fixation, "center", "center")

            # Display cue at target location
            if cue_location == "top":
                display.image(
                    self.screen, self.img_cue, "center",
                    self.screen_y/2 - self.fixation_h - self.TARGET_OFFSET)
            elif cue_location == "bottom":
                display.image(self.screen, self.img_cue, "center",
                              self.screen_y/2 + self.TARGET_OFFSET)

        pygame.display.flip()

        # Display cue for certain duration
        display.wait(self.CUE_DURATION)

        # Prestim interval with fixation
        self.screen.blit(self.background, (0, 0))
        display.image(self.screen, self.img_fixation, "center", "center")
        pygame.display.flip()

        display.wait(self.PRE_STIM_FIXATION_DURATION)

        # Display flanker target
        self.screen.blit(self.background, (0, 0))
        display.image(self.screen, self.img_fixation, "center", "center")

        self.display_flanker(data["congruency"][trial_num],
                             data["location"][trial_num],
                             data["direction"][trial_num])
        pygame.display.flip()

        start_time = int(round(time.time() * 1000))

        # Clear the event queue before checking for responses
        pygame.event.clear()
        response = "NA"
        wait_response = True
        while wait_response:
            for event in pygame.event.get():
                if event.type == KEYDOWN and event.key == K_LEFT:
                    response = "left"
                    wait_response = False
                elif event.type == KEYDOWN and event.key == K_RIGHT:
                    response = "right"
                    wait_response = False
                elif event.type == KEYDOWN and event.key == K_F12:
                    sys.exit(0)

            end_time = int(round(time.time() * 1000))

            # If time limit has been reached, consider it a missed trial
            if end_time - start_time >= self.FLANKER_DURATION:
                wait_response = False

        # Store reaction time and response
        rt = int(round(time.time() * 1000)) - start_time
        data.set_value(trial_num, 'RT', rt)
        data.set_value(trial_num, 'response', response)

        correct = 1 if response == data["direction"][trial_num] else 0
        data.set_value(trial_num, 'correct', correct)

        # Display feedback if practice trials
        if trial_type == "practice":
            self.screen.blit(self.background, (0, 0))
            if correct == 1:
                display.text(self.screen, self.font, "correct",
                             "center", "center", (0, 255, 0))
            else:
                display.text(self.screen, self.font, "incorrect",
                             "center", "center", (255, 0, 0))
            pygame.display.flip()

            display.wait(self.FEEDBACK_DURATION)

        # Display fixation during ITI
        self.screen.blit(self.background, (0, 0))
        display.image(self.screen, self.img_fixation, "center", "center")
        pygame.display.flip()

        iti = self.ITI_MAX - rt - data["fixationTime"][trial_num]
        data.set_value(trial_num, 'ITI', iti)

        display.wait(iti)
示例#17
0
    def start(self):
        # Store input values
        sub_num = self.subNumBox.text()
        experiment_id = self.experimentIDBox.text()
        condition = self.conditionBox.text()
        age = self.ageBox.text()
        ra = self.raBox.text()
        current_date = datetime.datetime.now().strftime("%Y-%m-%d %H:%M")

        if self.maleRadio.isChecked():
            sex = 'male'
        else:
            sex = 'female'

        # Get *selected* tasks and task order
        selected_tasks = []
        for index in range(self.taskList.count()):
            # State 2 is set when item is selected
            if self.taskList.item(index).checkState() == 2:
                # Add selected task to task list
                selected_tasks.append(str(self.taskList.item(index).text()))

        # Check to see if a random order is desired
        # If so, shuffle tasks
        if self.random_order_selected():
            random.shuffle(selected_tasks)

        # Check for required inputs
        if not selected_tasks:
            self.error_dialog('No tasks selected')
        elif not ra:
            self.error_dialog('Please enter RA name...')
        elif not sub_num:
            self.error_dialog('Please enter a subject number...')
        elif not experiment_id:
            self.error_dialog('Please enter an experiment ID...')
        elif not condition:
            self.error_dialog('Please enter a condition number...')
        elif not age:
            self.error_dialog('Please enter an age...')
        elif not self.maleRadio.isChecked() and not \
                self.femaleRadio.isChecked():
            self.error_dialog('Please select a sex...')
        else:
            # Store subject info into a dataframe
            subject_info = pd.DataFrame(
                data=[(str(current_date), str(sub_num), str(experiment_id),
                       str(condition), int(age), str(sex), str(ra),
                       ', '.join(selected_tasks))],
                columns=['datetime', 'sub_num', 'expID', 'condition',
                         'age', 'sex', 'RA', 'tasks']
            )

            # Set the output file name
            data_file_name = "%s_%s_%s.xls" % (experiment_id, sub_num,
                                               condition)

            # Check if file already exists
            output_file = os.path.join(self.dataPath, data_file_name)
            if os.path.isfile(output_file):
                self.error_dialog('Data file already exists')
            else:
                # Create the excel writer object and save the file
                writer = pd.ExcelWriter(output_file)
                subject_info.to_excel(writer, 'info', index=False)
                writer.save()

                # Minimize battery UI
                self.showMinimized()

                # Get most recent task window settings from file
                self.get_task_settings()

                # Center all pygame windows if not fullscreen
                if not self.task_fullscreen:
                    pos_x = str(self.res_width / 2 - self.task_width / 2)
                    pos_y = str(self.res_height / 2 - self.task_height / 2)

                    os.environ['SDL_VIDEO_WINDOW_POS'] = \
                        "%s, %s" % (pos_x, pos_y)

                # Initialize pygame
                pygame.init()

                # Set pygame icon image
                image = os.path.join(self.directory, "images", "icon_sml.png")
                icon_img = pygame.image.load(image)
                pygame.display.set_icon(icon_img)

                # Create primary task window
                # pygame_screen is passed to each task as the display window
                if self.task_fullscreen:
                    self.pygame_screen = pygame.display.set_mode(
                        (0, 0), pygame.FULLSCREEN)
                else:
                    if self.task_borderless:
                        self.pygame_screen = pygame.display.set_mode(
                            (self.task_width, self.task_height),
                            pygame.NOFRAME)
                    else:
                        self.pygame_screen = pygame.display.set_mode(
                            (self.task_width, self.task_height))

                background = pygame.Surface(self.pygame_screen.get_size())
                background = background.convert()

                # Run each task
                # Return and save their output to dataframe/excel
                for task in selected_tasks:
                    if task == "Attention Network Test (ANT)":
                        # Set number of blocks for ANT
                        ant_task = ant.ANT(self.pygame_screen, background,
                                           blocks=3)
                        # Run ANT
                        ant_data = ant_task.run()
                        # Save ANT data to excel
                        ant_data.to_excel(writer, 'ANT', index=False)
                    elif task == "Mental Rotation Task":
                        mrt_task = mrt.MRT(self.pygame_screen, background)
                        # Run MRT
                        mrt_data = mrt_task.run()
                        # Save MRT data to excel
                        mrt_data.to_excel(writer, 'MRT', index=False)
                    elif task == "Sustained Attention to Response Task (SART)":
                        sart_task = sart.SART(self.pygame_screen, background)
                        # Run SART
                        sart_data = sart_task.run()
                        # Save SART data to excel
                        sart_data.to_excel(writer, 'SART', index=False)
                    elif task == "Digit Span (backwards)":
                        digitspan_backwards_task = \
                            digitspan_backwards.DigitspanBackwards(
                                self.pygame_screen, background)
                        # Run Digit span (Backwards)
                        digitspan_backwards_data = \
                            digitspan_backwards_task.run()
                        # Save digit span (backwards) data to excel
                        digitspan_backwards_data.to_excel(
                            writer, 'Digit span (backwards)', index=False)
                    elif task == "Raven's Progressive Matrices":
                        ravens_task = ravens.Ravens(
                            self.pygame_screen, background,
                            start=9, numTrials=12)
                        # Run Raven's Matrices
                        ravens_data = ravens_task.run()
                        # Save ravens data to excel
                        ravens_data.to_excel(writer, 'Ravens Matrices',
                                             index=False)
                    elif task == "Sternberg Task":
                        sternberg_task = sternberg.Sternberg(
                            self.pygame_screen, background)
                        # Run Sternberg Task
                        sternberg_data = sternberg_task.run()
                        # Save sternberg data to excel
                        sternberg_data.to_excel(writer, 'Sternberg',
                                                index=False)

                    # Save excel file
                    writer.save()

                # End of experiment screen
                pygame.display.set_caption("Cognitive Battery")
                pygame.mouse.set_visible(1)

                background.fill((255, 255, 255))
                self.pygame_screen.blit(background, (0, 0))

                font = pygame.font.SysFont("arial", 30)
                display.text(self.pygame_screen, font, "End of Experiment",
                             "center", "center")

                pygame.display.flip()

                display.wait_for_space()

                # Quit pygame
                pygame.quit()

                print "--- Experiment complete"
                self.close()
示例#18
0
    def run(self):
        # Instructions screen
        self.screen.blit(self.background, (0, 0))
        display.text(self.screen, self.font, "Sternberg Task", "center", 100)
        display.text(
            self.screen, self.font,
            "You will see a sequence of numbers, one at a time. "
            "Try your best to memorize them", 100, 200)

        display.text(self.screen, self.stim_font, "8 - 5 - 4 - 1 - 0 - 9",
                     "center", 300)

        display.text(self.screen, self.font,
                     "You will then be shown a single test number in blue",
                     100, 400)

        display.text(self.screen, self.stim_font, "0", "center", 500,
                     (0, 0, 255))

        display.text(
            self.screen, self.font,
            "If this number was in the original sequence, "
            "press the LEFT arrow", 100, 600)

        display.text(
            self.screen, self.font,
            "If this number was NOT in the original sequence, "
            "press the RIGHT arrow", 100, 700)

        display.text(
            self.screen, self.font, "Try to do this as quickly, "
            "and as accurately, as possible", 100, 800)

        display.text_space(self.screen, self.font, "center", 900)

        pygame.display.flip()

        display.wait_for_space()

        # Practice ready screen
        self.screen.blit(self.background, (0, 0))
        display.text(self.screen, self.font,
                     "We will begin with some practice trials...", "center",
                     "center")

        display.text_space(self.screen, self.font, "center",
                           self.screen_y / 2 + 100)

        pygame.display.flip()

        display.wait_for_space()

        # Practice trials
        for i, r in self.practice_trials.iterrows():
            self.display_trial(self.practice_trials, i, r, "practice")

        # Main trials ready screen
        self.screen.blit(self.background, (0, 0))
        display.text(self.screen, self.font, "End of practice trials.", 100,
                     100)
        display.text(self.screen, self.font, "You may move on to the main "
                     "trials when you're ready", 100, 300)

        display.text(
            self.screen, self.font, "Remember to respond as quickly "
            "and as accurately as possible", 100, 500)
        display.text(self.screen, self.font, "Your reaction time and accuracy"
                     " will be recorded", 100, 600)
        display.text_space(self.screen, self.font, "center", 800)

        pygame.display.flip()

        display.wait_for_space()

        # Main trials
        for i, block in enumerate(self.blocks):
            for j, r in block.iterrows():
                self.display_trial(block, j, r, "main")

            # If this is not the final block, show instructions for next block
            if i != len(self.blocks) - 1:
                display.text(self.screen, self.font, "End of block.", 100, 200)
                display.text(
                    self.screen, self.font,
                    "Take a short break, and press space when you're "
                    "ready to start the next block...", 100, 400)
                display.text_space(self.screen, self.font, "center", 700)

                pygame.display.flip()

                display.wait_for_space()

        # End screen
        self.screen.blit(self.background, (0, 0))
        display.text(self.screen, self.font, "End of task", "center", "center")
        display.text_space(self.screen, self.font, "center",
                           self.screen_y / 2 + 100)
        pygame.display.flip()

        display.wait_for_space()

        # Concatenate blocks and add trial numbers
        all_data = pd.concat(self.blocks)
        all_data['trialNum'] = list(range(1, len(all_data) + 1))

        print("- Sternberg Task complete")

        return all_data
示例#19
0
    def run(self):
        # Instructions
        self.screen.blit(self.background, (0, 0))
        display.text(self.screen, self.font, "Attentional Network Test",
                     "center", self.screen_y/2 - 300)
        display.text(self.screen, self.font,
                     "Keep your eyes on the fixation cross at the "
                     "start of each trial:",
                     100, self.screen_y/2 - 200)
        display.image(self.screen, self.img_fixation,
                      "center", self.screen_y/2 - 150)
        display.text(self.screen, self.font,
                     "A set of arrows will appear somewhere on the screen:",
                     100, self.screen_y/2 - 100)
        display.image(self.screen, self.img_left_incongruent,
                      "center", self.screen_y/2 - 50)
        display.text(self.screen, self.font,
                     "Use the Left / Right arrow keys to indicate "
                     "the direction of the CENTER arrow.",
                     100, self.screen_y/2 + 50)
        display.text(self.screen, self.font,
                     "In example above, you should press the Left arrow.",
                     100, self.screen_y/2 + 100)
        display.text_space(self.screen, self.font,
                           "center", (self.screen_y/2) + 300)
        pygame.display.flip()

        display.wait_for_space()

        # Instructions Practice
        self.screen.blit(self.background, (0, 0))
        display.text(self.screen, self.font,
                     "We'll begin with a some practice trials...",
                     "center", "center")
        display.text_space(self.screen, self.font,
                           "center", self.screen_y/2 + 100)
        pygame.display.flip()

        display.wait_for_space()

        # Practice trials
        self.run_block(0, 1, "practice")

        # Instructions Practice End
        self.screen.blit(self.background, (0, 0))
        display.text(self.screen, self.font,
                     "We will now begin the main trials...",
                     100, self.screen_y/2 - 50)
        display.text(self.screen, self.font,
                     "You will not receive feedback after each trial.",
                     100, self.screen_y/2 + 50)
        display.text_space(self.screen, self.font,
                           "center", self.screen_y/2 + 200)
        pygame.display.flip()

        display.wait_for_space()

        # Main task
        for i in range(self.NUM_BLOCKS):
            self.run_block(i, self.NUM_BLOCKS, "main")

        # Create trial number column
        self.all_data["trial"] = range(1, len(self.all_data) + 1)

        # Rearrange the dataframe
        columns = ['trial', 'block', 'congruency', 'cue', 'location',
                   'fixationTime', 'ITI', 'direction',
                   'response', 'correct', 'RT']
        self.all_data = self.all_data[columns]

        # End screen
        self.screen.blit(self.background, (0, 0))
        display.text(self.screen, self.font, "End of task", "center", "center")
        display.text_space(self.screen, self.font,
                           "center", self.screen_y/2 + 100)
        pygame.display.flip()

        display.wait_for_space()

        print "- ANT complete"

        return self.all_data
示例#20
0
    def display_trial(self, trial_num, data):
        # Check for a quit press after stimulus was shown
        for event in pygame.event.get():
            if event.type == KEYDOWN and event.key == K_F12:
                sys.exit(0)

        # Display fixation
        self.screen.blit(self.background, (0, 0))
        display.text(self.screen, self.font, "+", "center", "center", self.colour_font)
        pygame.display.flip()

        display.wait(self.FIXATION_DURATION)

        # Display flanker stimulus
        self.screen.blit(self.background, (0, 0))
        self.display_flanker(
            data["congruency"][trial_num], data["direction"][trial_num]
        )
        pygame.display.flip()

        # Clear the event queue before checking for responses
        pygame.event.clear()
        response = "NA"
        too_slow = False
        wait_response = True
        post_flanker_blank_shown = False

        start_time = int(round(time.time() * 1000))
        while wait_response:
            for event in pygame.event.get():
                if event.type == KEYDOWN and event.key == K_LEFT:
                    response = "left"
                    wait_response = False
                elif event.type == KEYDOWN and event.key == K_RIGHT:
                    response = "right"
                    wait_response = False
                elif event.type == KEYDOWN and event.key == K_F12:
                    sys.exit(0)

            end_time = int(round(time.time() * 1000))

            if end_time - start_time >= self.FLANKER_DURATION:
                if not post_flanker_blank_shown:
                    self.screen.blit(self.background, (0, 0))
                    pygame.display.flip()
                    post_flanker_blank_shown = True

            if end_time - start_time >= self.MAX_RESPONSE_TIME:
                # If time limit has been reached, consider it a missed trial
                wait_response = False
                too_slow = True

        # Store reaction time and response
        rt = int(round(time.time() * 1000)) - start_time
        data.set_value(trial_num, "RT", rt)
        data.set_value(trial_num, "response", response)

        if data["compatibility"][trial_num] == "compatible":
            correct = 1 if response == data["direction"][trial_num] else 0
        else:
            correct = 1 if response != data["direction"][trial_num] else 0
        data.set_value(trial_num, "correct", correct)

        # Display feedback
        self.screen.blit(self.background, (0, 0))
        if too_slow:
            display.text(
                self.screen, self.font, "too slow", "center", "center", self.colour_font
            )
        else:
            if correct == 1:
                display.text(
                    self.screen, self.font, "correct", "center", "center", (0, 255, 0)
                )
            else:
                display.text(
                    self.screen, self.font, "incorrect", "center", "center", (255, 0, 0)
                )
        pygame.display.flip()

        display.wait(self.FEEDBACK_DURATION)

        if trial_num != data.shape[0] - 1:
            # Display fixation
            self.screen.blit(self.background, (0, 0))
            display.text(
                self.screen, self.font, "+", "center", "center", self.colour_font
            )
            pygame.display.flip()
            display.wait(self.ITI)
示例#21
0
    def run(self):
        # Instructions
        self.screen.blit(self.background, (0, 0))
        display.text(self.screen, self.font, "Attentional Network Test",
                     "center", self.screen_y / 2 - 300)
        display.text(
            self.screen, self.font,
            "Keep your eyes on the fixation cross at the "
            "start of each trial:", 100, self.screen_y / 2 - 200)
        display.image(self.screen, self.img_fixation, "center",
                      self.screen_y / 2 - 150)
        display.text(self.screen, self.font,
                     "A set of arrows will appear somewhere on the screen:",
                     100, self.screen_y / 2 - 100)
        display.image(self.screen, self.img_left_incongruent, "center",
                      self.screen_y / 2 - 50)
        display.text(
            self.screen, self.font,
            "Use the Left / Right arrow keys to indicate "
            "the direction of the CENTER arrow.", 100, self.screen_y / 2 + 50)
        display.text(self.screen, self.font,
                     "In example above, you should press the Left arrow.", 100,
                     self.screen_y / 2 + 100)
        display.text_space(self.screen, self.font, "center",
                           (self.screen_y / 2) + 300)
        pygame.display.flip()

        display.wait_for_space()

        # Instructions Practice
        self.screen.blit(self.background, (0, 0))
        display.text(self.screen, self.font,
                     "We'll begin with some practice trials...", "center",
                     "center")
        display.text_space(self.screen, self.font, "center",
                           self.screen_y / 2 + 100)
        pygame.display.flip()

        display.wait_for_space()

        # Practice trials
        self.run_block(0, 1, "practice")

        # Instructions Practice End
        self.screen.blit(self.background, (0, 0))
        display.text(self.screen, self.font,
                     "We will now begin the main trials...", 100,
                     self.screen_y / 2 - 50)
        display.text(self.screen, self.font,
                     "You will not receive feedback after each trial.", 100,
                     self.screen_y / 2 + 50)
        display.text_space(self.screen, self.font, "center",
                           self.screen_y / 2 + 200)
        pygame.display.flip()

        display.wait_for_space()

        # Main task
        for i in range(self.NUM_BLOCKS):
            self.run_block(i, self.NUM_BLOCKS, "main")

        # Create trial number column
        self.all_data["trial"] = list(range(1, len(self.all_data) + 1))

        # Rearrange the dataframe
        columns = [
            'trial', 'block', 'congruency', 'cue', 'location', 'fixationTime',
            'ITI', 'direction', 'response', 'correct', 'RT'
        ]
        self.all_data = self.all_data[columns]

        # End screen
        self.screen.blit(self.background, (0, 0))
        display.text(self.screen, self.font, "End of task", "center", "center")
        display.text_space(self.screen, self.font, "center",
                           self.screen_y / 2 + 100)
        pygame.display.flip()

        display.wait_for_space()

        print("- ANT complete")

        return self.all_data
示例#22
0
    def display_trial(self, df, i, r, trial_type):
        # Clear screen
        self.screen.blit(self.background, (0, 0))
        pygame.display.flip()

        # Display number sequence
        self.display_sequence(r['set'])

        # Display probe warning
        self.screen.blit(self.background, (0, 0))
        display.text(self.screen, self.stim_font, "+", "center", "center")
        pygame.display.flip()

        display.wait(self.PROBE_WARN_DURATION)

        # Display blank screen
        display.blank_screen(self.screen, self.background,
                             self.BETWEEN_STIM_DURATION)

        # Display probe
        self.screen.blit(self.background, (0, 0))
        display.text(self.screen, self.stim_font, r['probe'],
                     "center", "center", (0, 0, 255))

        # Display key reminders if practice trials
        if trial_type == "practice":
            display.image(self.screen, self.img_left,
                          450 - self.img_left.get_rect().width/2,
                          self.screen_y/2 + 150)

            yes_text = self.font.render("(yes)", 1, (0, 0, 0))
            display.text(self.screen, self.font, yes_text,
                         450 - yes_text.get_rect().width/2,
                         self.screen_y/2 + 160)

            display.image(
                self.screen, self.img_right,
                self.screen_x - 450 - self.img_right.get_rect().width/2,
                self.screen_y/2 + 150)

            no_text = self.font.render("(no)", 1, (0, 0, 0))
            display.text(self.screen, self.font, no_text,
                         self.screen_x - 450 - no_text.get_rect().width/2,
                         self.screen_y/2 + 160)

        pygame.display.flip()

        start_time = int(round(time.time() * 1000))

        # Clear the event queue before checking for responses
        pygame.event.clear()
        wait_response = True
        while wait_response:
            for event in pygame.event.get():
                if event.type == KEYDOWN and event.key == K_LEFT:
                    df.set_value(i, "response", "present")
                    wait_response = False
                elif event.type == KEYDOWN and event.key == K_RIGHT:
                    df.set_value(i, "response", "absent")
                    wait_response = False
                elif event.type == KEYDOWN and event.key == K_F12:
                    sys.exit(0)

            end_time = int(round(time.time() * 1000))

            # If time limit has been reached, consider it a missed trial
            if end_time - start_time >= self.PROBE_DURATION:
                wait_response = False

        # Store RT
        rt = int(round(time.time() * 1000)) - start_time
        df.set_value(i, "RT", rt)

        # Display blank screen
        display.blank_screen(self.screen, self.background,
                             self.BETWEEN_STIM_DURATION)

        # Display feedback
        self.screen.blit(self.background, (0, 0))

        if rt >= self.PROBE_DURATION:
            df.set_value(i, "correct", 0)
            display.text(self.screen, self.font, "too slow",
                         "center", "center", (255, 165, 0))
        else:
            if df["probeType"][i] == df["response"][i]:
                df.set_value(i, "correct", 1)
                display.text(self.screen, self.font, "correct",
                             "center", "center", (0, 255, 0))
            else:
                df.set_value(i, "correct", 0)
                display.text(self.screen, self.font, "incorrect",
                             "center", "center", (255, 0, 0))

        pygame.display.flip()

        display.wait(self.FEEDBACK_DURATION)

        # Display blank screen (ITI)
        display.blank_screen(self.screen, self.background, self.ITI)