def trial(self):

        if P.development_mode:
            print(self.image_name, self.mask_type)

        trial_countdown = CountDown(900) # 15 minutes
        while trial_countdown.remaining() > 0:
            q = pump(True)
            if key_pressed(sdl2.SDLK_DELETE, queue=q):
                # press 'Del' to skip trial
                break
            elif key_pressed(sdl2.SDLK_ESCAPE, queue=q):
                # Press 'escape' to pause and calibrate
                trial_countdown.pause()
                self.el.calibrate()
                self.el.drift_correct()
                self.el.start(P.trial_number)
                trial_countdown.resume()
                continue
            
            if trial_countdown.elapsed() >= self.first_warning_onset and not self.first_warning_played:
                self.warning_signal.play()
                self.first_warning_played = True
            if trial_countdown.elapsed() >= self.second_warning_onset and not self.second_warning_played:
                self.warning_signal.play()
                self.second_warning_played = True

            pos = self.el.gaze()
            fill()
            if int(pos[0]) != -32768: # if gaze not lost
                self.gaze_offscreen = time.time()
            if (pos[0] < 0) or (pos[0] > P.screen_x) or (pos[1] < 0) or (pos[1] > P.screen_y):
                pass
            elif (time.time() - self.gaze_offscreen) < self.gaze_timeout:
                blit(self.arrangement, 5, P.screen_c)
                if self.mask is not None and trial_countdown.elapsed() < self.mask_off_time:
                    blit(self.mask, 5, pos)
            flip()

        return {
            "trial_num":   P.trial_number,
            "block_num":   P.block_number,
            "arrangement": self.image_name,
            "mask_type":   self.mask_type
        }
Esempio n. 2
0
    def get_peak_during(self, period, msg=None):
        """Determines the peak loudness value recorded over a given period. Displays a visual
		callback that shows the current input volume and the loudest peak encounteredduring the
		interval so far.
		
		Args:
			period (numeric): the number of seconds to record input for.
			msg (:obj:`~klibs.KLGraphics.KLNumpySurface.NumpySurface`, optional): a rendered message
				to display in the top-right corner of the screen during the sampling loop.

		Returns:
			int: the loudest peak of all samples recorded during the period.

		"""
        local_peak = 0
        last_sample = 0
        if msg:
            msg = message(msg, blit_txt=False)

        flush()
        self.stream.start()
        sample_period = CountDown(period + 0.05)
        while sample_period.counting():
            ui_request()
            sample = self.stream.sample().peak
            if sample_period.elapsed() < 0.05:
                # Sometimes 1st or 2nd peaks are extremely high for no reason, so ignore first 50ms
                continue
            if sample > local_peak:
                local_peak = sample
            sample_avg = (sample + last_sample) / 2
            peak_circle = peak(5, int(
                (local_peak / 32767.0) * P.screen_y * 0.8))
            sample_circle = peak(
                5, int((sample_avg / 32767.0) * P.screen_y * 0.8))
            last_sample = sample

            fill()
            blit(Ellipse(peak_circle, fill=[255, 145, 0]),
                 location=P.screen_c,
                 registration=5)
            blit(Ellipse(sample_circle, fill=[84, 60, 182]),
                 location=P.screen_c,
                 registration=5)
            if msg:
                blit(msg, location=[25, 25], registration=7)
            flip()
        self.stream.stop()
        return local_peak
 def warm_up(self):
     warmup_timer = CountDown(600, start=True)
     self.first_signal_played = False
     self.second_signal_played = False
     self.third_signal_played = False
     self.fourth_signal_played = False
     while warmup_timer.counting():
         if key_pressed(sdl2.SDLK_DELETE):
             break
         
         t = warmup_timer.elapsed()
         if t < 60:
             tool = 'pencil'
         elif 60 <= t < 120:
             if not self.first_signal_played:
                 self.warning_signal.play()
                 self.first_signal_played = True
             tool = 'charcoal'
         elif 120 <= t < 180:
             if not self.second_signal_played:
                 self.warning_signal.play()
                 self.second_signal_played = True
             tool = 'smudger'
         elif 180 <= t < 240:
             if not self.third_signal_played:
                 self.warning_signal.play()
                 self.third_signal_played = True
             tool = 'eraser'
         else:
             if not self.fourth_signal_played:
                 self.warning_signal.play()
                 self.fourth_signal_played = True
             tool = 'any'
             
         fill()
         blit(self.images['warmup.png'], 5, P.screen_c)
         blit(self.warmup_txt[tool], 1, (30, P.screen_y-30))
         flip()
Esempio n. 4
0
    def block(self):

        halfway_block = (P.blocks_per_experiment / 2) + 1
        if P.run_practice_blocks and P.session_number == 1:
            halfway_block += 3

        if P.run_practice_blocks and P.session_number == 1 and P.block_number <= 3:
            txt = "This is a practice block ({0} of 3)\n\n".format(
                P.block_number)
            if P.block_number == 1:
                txt += (
                    "During this task, arrows will appear either above or below the '+' symbol.\n"
                    "Your job will be to indicate the direction of the middle arrow as quickly\n"
                    "and accurately as possible using the keyboard.\n\n"
                    "( c = left,  m = right )")
            elif P.block_number == 2:
                txt += (
                    "On some trials, the central arrow will be displaced upwards or downwards "
                    "by a large amount.\n"
                    "When this occurs, please press the space bar instead of the 'c' or 'm' keys."
                )
                self.trial_type = 'EV'
                self.ev_offset = 'below'
                demo_arrows = self.generate_arrows()
            else:
                txt += (
                    "On some trials, a large red countdown timer will appear instead of the arrows."
                    "\nWhen this occurs, please press the space bar as quickly as you can."
                )

            instructions = message(txt, align='center', blit_txt=False)
            continue_msg = message('Press any key to begin.',
                                   align='center',
                                   blit_txt=False)
            instruction_time = CountDown(3)
            while True:
                keydown = key_pressed()
                fill()
                blit(instructions, 8, (P.screen_c[0], int(P.screen_y * 0.1)))
                if P.block_number == 2:
                    blit(self.fixation, 5, P.screen_c)
                    for shape, loc in demo_arrows:
                        blit(shape, 5, loc)
                elif P.block_number == 3:
                    elapsed = min(
                        [int(instruction_time.elapsed() * 1000), 367])
                    demo_counter = message(str(elapsed).zfill(4),
                                           "PVT",
                                           blit_txt=False)
                    blit(demo_counter, 5, P.screen_c)
                if P.development_mode or instruction_time.counting() == False:
                    blit(continue_msg, 2,
                         (P.screen_c[0], int(P.screen_y * 0.9)))
                    if keydown == True:
                        break
                flip()

        elif P.run_practice_blocks and P.session_number == 1 and P.block_number == 4:
            self.block_msg(
                "Practice complete! Press any key to begin the task.")

        elif P.block_number == 1:
            self.block_msg("Press any key to begin the task.")

        elif P.block_number == halfway_block:
            self.block_msg(
                "Phew, you're halfway done! Press any key to continue.")
Esempio n. 5
0
    def instructions(self):

        p1 = (
            "During this task, you will presented with a sequence of letters in the middle of "
            "the screen.\n\nPress any key to see an example.")
        p2a = (
            "For some blocks, your task will be to indicate whether each letter matches "
            "the letter just before it:")
        p2b = (
            "For others, your task will be to indicate whether each letter matches "
            "the letter two before it:")
        p2c = "(matches for each block type are highlighted)"
        p3 = (
            "Occasionally, the task will be interrupted by screens asking you about your "
            "focus just prior.\nWhen this happens, please select the most accurate "
            "response using the mouse cursor.\n\nPress any key to see an example."
        )

        msg1 = message(p1, 'normal', blit_txt=False, align='center')
        msg2a = message(p2a,
                        'normal',
                        blit_txt=False,
                        wrap_width=int(P.screen_x * 0.8))
        msg2b = message(p2b,
                        'normal',
                        blit_txt=False,
                        wrap_width=int(P.screen_x * 0.8))
        msg2c = message(p2c, 'normal', blit_txt=False)
        msg3 = message(p3,
                       'normal',
                       blit_txt=False,
                       align='center',
                       wrap_width=int(P.screen_x * 0.8))

        # First page of instructions

        flush()
        fill()
        blit(msg1, 5, P.screen_c)
        flip()
        any_key(allow_mouse_click=False)

        # Example stimuli

        for letter in (1, 2, 1):
            trialtime = CountDown(2.5)
            while trialtime.counting():
                mask_on = trialtime.elapsed() > 0.5
                stim = self.mask if mask_on else self.letters[
                    self.letter_set[letter]]
                ui_request()
                fill()
                blit(self.accuracy_rect, 5, P.screen_c)
                blit(self.accuracy_mask, 5, P.screen_c)
                blit(stim, 5, P.screen_c)
                flip()

        # Task explanation/illustration

        fill()
        blit(msg2a, 8, (P.screen_c[0], int(P.screen_y * 0.15)))
        blit(msg2b, 8, (P.screen_c[0], int(P.screen_y * 0.45)))
        blit(msg2c, 2, (P.screen_c[0], int(P.screen_y * 0.8)))
        self.draw_nback_illustration(int(P.screen_y * 0.3), target=5)
        self.draw_nback_illustration(int(P.screen_y * 0.6), target=4)
        flip()
        any_key(allow_mouse_click=False)

        # Probe explanation + example probe

        fill()
        blit(msg3, 5, P.screen_c)
        flip()
        any_key()
        self.probe.collect()
Esempio n. 6
0
    def instructions(self):

        p1 = (
            "During this task, you will presented with a sequence of numbers in the middle of "
            "the screen.\n\nPress any key to see an example.")
        p2 = (
            "Your task will be to press the [space] key as quickly as possible whenever a "
            "number other than {0} appears, and to withhold your response whenever the number "
            "is {0}.\n\nPress any key to continue.".format(P.target))
        p3 = (
            "Occasionally, the task will be interrupted by screens asking you about your "
            "focus just prior.\nWhen this happens, please select the most accurate "
            "response using the mouse cursor.\n\nPress any key to see an example."
        )
        p4 = (
            "After responding, you will be asked how much effort you "
            "were putting into staying focused on the task before the interruption.\n\n"
            "When this happens, please answer using the scale from 0% to 100% that will appear "
            "on screen. Your responses will be anonymous so please answer honestly.\n\n"
            "Press any key to see an example.")

        msg1 = message(p1, 'normal', blit_txt=False, align='center')
        msg2 = message(p2,
                       'normal',
                       blit_txt=False,
                       align='center',
                       wrap_width=int(P.screen_x * 0.8))
        msg3 = message(p3,
                       'normal',
                       blit_txt=False,
                       align='center',
                       wrap_width=int(P.screen_x * 0.8))
        msg4 = message(p4,
                       'normal',
                       blit_txt=False,
                       align='center',
                       wrap_width=int(P.screen_x * 0.8))

        # First page of instructions

        flush()
        fill()
        blit(msg1, 5, P.screen_c)
        flip()
        any_key(allow_mouse_click=False)

        # Example stimuli

        numlist = [1, 2, 3, 4, 5, 6, 7, 8, 9]
        random.shuffle(numlist)
        for n in numlist[1:5]:
            trialtime = CountDown(1.125)
            numsize = random.choice(self.sizes)
            while trialtime.counting():
                ui_request()
                fill()
                mask_on = trialtime.elapsed() > 0.25
                if mask_on:
                    blit(self.mask_x, 5, P.screen_c)
                    blit(self.mask_ring, 5, P.screen_c)
                else:
                    blit(self.digits[n][numsize], 5, P.screen_c)
                flip()

        # Task explanation/illustration

        flush()
        fill()
        blit(msg2, 5, P.screen_c)
        flip()
        any_key(allow_mouse_click=False)

        # Probe explanation + example probe

        fill()
        blit(msg3, 5, P.screen_c)
        flip()
        any_key(allow_mouse_click=False)
        self.probe.collect()

        # Slider explanation + example slider

        fill()
        blit(msg4, 5, P.screen_c)
        flip()
        any_key(allow_mouse_click=False)
        self.get_effort()