Example #1
0
    def present_temporal_stream(self, temporal_stream):
        duration_cd = CountDown(ITEM_DURATION, start=False)
        mask_cd = CountDown(MASK_DURATION, start=False)

        response_window = CountDown(2, start=False)

        last_item = True if len(temporal_stream) == 1 else False

        item = temporal_stream.pop()

        if item[1]:
            self.target_onset = self.target_sw.elapsed()

        duration_cd.start()
        while duration_cd.counting():
            self.blit_img(item[0], reg=5, loc=P.screen_c)

        mask_cd.start()
        while mask_cd.counting():
            self.blit_img(self.mask, reg=5, loc=P.screen_c)

        if last_item:
            clear()
            response_window.start()
            while response_window.counting():
                fill()
                flip()
Example #2
0
    def feedback(self, response):
        if self.winning_bandit == HIGH:
            winning_bandit_loc = self.high_value_location
        else:
            winning_bandit_loc = self.low_value_location

        if response == winning_bandit_loc:
            points = self.bandit_payout(value=self.winning_bandit)
            msg = message("You won {0} points!".format(points),
                          "score up",
                          blit_txt=False)
        else:
            points = self.penalty  # -5
            msg = message("You lost 5 points!", "score down", blit_txt=False)
        self.total_score += points
        feedback = [points, msg]

        feedback_exposure = CountDown(self.feedback_exposure_period)
        while feedback_exposure.counting():
            ui_request()
            fill()
            blit(feedback[1], location=P.screen_c, registration=5)
            flip()

        return feedback[0]
Example #3
0
    def trial(self):

        # Clear screen and wait for target onset
        fill()
        flip()
        while self.evm.before('target_on'):
            ui_request()

        # Start timer and collect response
        self.rc.collect()
        response = self.rc.keypress_listener.response()

        # Stop timer and show for 1sec after response is made
        elapsed_msg = message(str(int(response.rt)).zfill(4),
                              style='PVT',
                              blit_txt=False)
        feedback_timer = CountDown(1)
        while feedback_timer.counting():
            fill()
            blit(elapsed_msg, 5, P.screen_c)
            flip()

        # Log trial data to database
        return {
            "block_num": P.block_number,
            "trial_num": P.trial_number,
            "isi": self.interstim_interval,
            "rt": response.rt
        }
Example #4
0
    def feedback(self, response):
        correct_response = True if response == self.tilt_line_location else False

        # Every 5 trials of a particular payoff, ask anticipated earnings
        if self.potential_payoff == HIGH:
            self.high_value_trial_count += 1
            if self.high_value_trial_count in [5, 10, 15]:
                self.query_learning(HIGH)
        else:
            self.low_value_trial_count += 1
            if self.low_value_trial_count in [5, 10, 15]:
                self.query_learning(LOW)

        # Determine payout for trial
        if correct_response & (self.winning_trial == YES):
            points = self.payout()
            msg = message("You won {0} points!".format(points),
                          'myText',
                          blit_txt=False)
        else:
            points = self.penalty
            msg = message("You lost 5 points!", 'myText', blit_txt=False)
        # Keep tally of score
        self.total_score += points
        feedback = [points, msg]

        # Present score
        feedback_exposure = CountDown(self.feedback_exposure_period)
        fill()
        blit(feedback[1], location=P.screen_c, registration=5)
        flip()
        while feedback_exposure.counting():
            ui_request()

        return feedback[0]
Example #5
0
    def block(self):

        # Show block message at start of every block
        header = "Block {0} of {1}".format(P.block_number,
                                           P.blocks_per_experiment)
        if P.practicing:
            header = "This is a practice block. ({0})".format(header)
            practice_msg = "During this block you will be given feedback for your responses."
            msg = message(header + "\n" + practice_msg,
                          align="center",
                          blit_txt=False)
        else:
            msg = message(header, blit_txt=False)

        message_interval = CountDown(1)
        while message_interval.counting():
            ui_request()  # Allow quitting during loop
            fill()
            blit(msg, 8, (P.screen_c[0], P.screen_y * 0.4))
            flip()
        flush()

        start_msg = message("Press any key to start.", blit_txt=False)
        fill()
        blit(msg, 8, (P.screen_c[0], P.screen_y * 0.4))
        blit(start_msg, 5, [P.screen_c[0], P.screen_y * 0.6])
        flip()
        any_key()
Example #6
0
    def present_feedback(self):
        msg = "Incorrect!"

        self.blit_msg(msg, 'left')

        feedback_cd = CountDown(0.5)
        while feedback_cd.counting():
            ui_request()
	def present_stream(self):
		duration_cd = CountDown(self.item_duration)
		isi_cd = CountDown(self.isi)
		item = self.rsvp_stream.pop()
		fill()
		blit(item[0], registration=5, location=P.screen_c)
		flip()

		duration_cd.reset()
		while duration_cd.counting():
			pass
		
		fill()

		if item[1]:
			self.temporal_presentation_times.append([self.evm.trial_time_ms, item[2]])
		isi_cd.reset()
		while isi_cd.counting():
			pass
Example #8
0
    def present_feedback(self):
        fill()
        message("Incorrect!",
                location=P.screen_c,
                registration=5,
                blit_txt=True)
        flip()

        feedback_period_cd = CountDown(0.5)  # seconds
        while feedback_period_cd.counting():
            ui_request()
Example #9
0
    def present_stream(self):

        duration_cd = CountDown(self.item_duration, start=False)
        isi_cd = CountDown(self.isi, start=False)

        item = self.rsvp_stream.pop()

        fill()
        blit(item[0], registration=5, location=P.screen_c)
        flip()

        duration_cd.start()
        while duration_cd.counting():
            pass

        fill()

        if item[1]:
            self.target_onset = self.target_sw.elapsed()

        isi_cd.start()
        while isi_cd.counting():
            pass
Example #10
0
    def get_ambient_level(self, period=1):
        """Determines the average ambient noise level from the input stream over a given period.
		Gives a 3-second countdown before starting to help the user ensure they are quiet.
		
		Args:
			period (numeric, optional): The number of seconds to record input for. Defaults to one
				second.

		Returns:
			int: The average of the peaks of all samples recorded during the period.

		"""
        warn_msg = (
            "Please remain quiet while the ambient noise level is sampled. "
            "Sampling will begin in {0} second{1}.")
        peaks = []

        wait_period = CountDown(3)
        while wait_period.counting():
            ui_request()
            fill()
            remaining = int(math.ceil(wait_period.remaining()))
            s = "" if remaining == 1 else "s"  # to avoid "1 seconds"
            message(warn_msg.format(remaining, s),
                    location=P.screen_c,
                    registration=5)
            flip()

        self.stream.start()
        fill()
        flip()
        sample_period = CountDown(period)
        while sample_period.counting():
            ui_request()
            peaks.append(self.stream.sample().peak)
        self.stream.stop()
        return sum(peaks) / float(len(peaks))
Example #11
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
Example #12
0
    def block(self):
        
        # Determine probe bias for block and generate list of probe locs accordingly
        
        if P.block_number > 3:
            self.probe_bias = "left"
            nonbiased_loc = "right"
        else:
            self.probe_bias = "right"
            nonbiased_loc = "left"
        loc_list = [self.probe_bias]*4 + [nonbiased_loc]
        self.probe_locs = loc_list * int(P.trials_per_block/float(len(loc_list))+1)
        random.shuffle(self.probe_locs)
        
        # At the start of each block, display a start message (block progress if experimental block,
        # practice message if practice block). After 3000ms, keypress will start first trial.
        
        probe_msg = (
            "During this block, the colour target will appear more often on the "
            "{0} and less often on the {1}.".format(self.probe_bias, nonbiased_loc)
        )
        header = "Block {0} of {1}".format(P.block_number, P.blocks_per_experiment)
        if P.practicing:
            header = "This is a practice block. ({0})".format(header)
        if P.block_number > 1:
            msg = message(header+"\n"+probe_msg, align="center", blit_txt=False)
        else:
            msg = message(header, blit_txt=False)

        message_interval = CountDown(1)
        while message_interval.counting():
            ui_request() # Allow quitting during loop
            fill()
            blit(msg, 8, (P.screen_c[0], P.screen_y*0.4))
            flip()
        flush()
        
        fill()
        blit(msg, 8, (P.screen_c[0], P.screen_y*0.4))
        message("Press any key to start.", registration=5, location=[P.screen_c[0], P.screen_y*0.6])
        flip()
        any_key()

        # When running participants, send halfway point and last-block notifications to researcher via Slack

        if not P.development_mode:
            if P.block_number == 3: # If participant is halfway done
                slack_message("Halfway done ({0}/{1})".format(P.block_number, P.blocks_per_experiment))
    def present_stream(self):
        # Each stream item presented for a pre-specified duration
        cd = CountDown(self.item_duration)
        sw = Stopwatch()
        for item in self.rsvp_stream:
            cd.reset()
            sw.reset()
            fill()
            blit(item, registration=5, location=P.screen_c)
            flip()

            #print(cd.elapsed)
            while cd.counting():
                ui_request()
            print(sw.elapsed())
            sw.reset()
Example #14
0
    def block(self):

        # Generate font sizes to use for numbers during the block

        self.num_sizes = []
        while len(self.num_sizes) <= P.trials_per_block:
            self.num_sizes = self.num_sizes + self.sizes
        random.shuffle(self.num_sizes)
        self.num_sizes = self.num_sizes[0:P.trials_per_block]

        # Generate block message

        header = ""  #"Block {0} of {1}".format(P.block_number, P.blocks_per_experiment)
        instructions = (
            "Please press the space key quickly when a digit other than {0} \nappears on screen, "
            "and withhold your response when the digit is {0}.".format(
                P.target))
        if P.practicing:
            header = "This is a practice block."
            instructions = instructions + "\nYou will be given feedback on your accuracy."
        msg = message(header + "\n\n" + instructions,
                      'normal',
                      align="center",
                      blit_txt=False)
        start_msg = message("Press the [space] key to start.",
                            'normal',
                            blit_txt=False)

        # Show block message, and wait for input before staring block

        if P.block_number in [1, self.first_nonpractice]:
            message_interval = CountDown(2)
            while message_interval.counting():
                ui_request()  # Allow quitting during loop
                fill()
                blit(msg, 8, (P.screen_c[0], int(P.screen_y * 0.15)))
                flip()

            while True:
                if key_pressed(' '):
                    break
                fill()
                blit(msg, 8, (P.screen_c[0], int(P.screen_y * 0.15)))
                blit(start_msg, 5, (P.screen_c[0], int(P.screen_y * 0.75)))
                flip()
    def trial(self):
        """
        trial_factors: 1 = mask_type, 2 = target_level, 3 = mask_size, 4 = target_shape]
        """
        if P.development_mode:
            print(self.mask_type, self.target_level, self.mask_size, self.target_shape)
        
        self.rc.collect()
        resp = self.rc.keypress_listener.response()
        
        if P.development_mode:
            print(resp)

        # handle timeouts
        if resp.rt == TIMEOUT:
            feedback = CountDown(1)
            msg = message("Too slow!", "alert", blit_txt=False)
            while feedback.counting():
                ui_request()
                fill()
                blit(msg, 5, P.screen_c)
                flip()
            clear()

        #  create readable data as fixation is currrently in (x,y) coordinates

        if self.fixation == self.fixation_top:
            initial_fixation = "TOP"
        elif self.fixation == self.fixation_central:
            initial_fixation = "CENTRAL"
        else:
            initial_fixation = "BOTTOM"

        return {"practicing": P.practicing,
                "response": resp.value,
                "rt": float(resp.rt),
                "mask_type": self.mask_type,
                "mask_size": self.mask_size,
                "local": self.target_shape if self.target_level == LOCAL else "D",
                "global": self.target_shape if self.target_level == GLOBAL else "D",
                "d_orientation": self.orientation,
                "trial_num": P.trial_number,
                "block_num": P.block_number,
                "initial_fixation": initial_fixation}
Example #16
0
    def feedback(self, response):

        # Keep count of bandit choices
        if response == self.high_value_location:
            self.bandit_selected = HIGH
            self.times_selected_high = self.times_selected_high + 1
            # Occasionally probe participant learning
            if self.times_selected_high in [5, 10, 15]:
                self.query_learning(HIGH)

        else:
            self.bandit_selected = LOW
            self.time_selected_low = self.time_selected_low + 1
            if self.time_selected_low in [5, 10, 15]:
                self.query_learning(LOW)

        # Determine payout
        if self.winning_trial == YES:
            points = self.bandit_payout(value=self.bandit_selected)
            msg = message("You won {0} points!".format(points),
                          "payout",
                          blit_txt=False)
        else:
            points = self.penalty  # -5
            msg = message("You lost 5 points!", "payout", blit_txt=False)

        # Running point total
        self.total_score += points
        feedback = [points, msg]

        # Present payout
        feedback_exposure = CountDown(self.feedback_exposure_period)
        while feedback_exposure.counting():
            ui_request()
            fill()
            blit(feedback[1], location=P.screen_c, registration=5)
            flip()

        return feedback[0]
 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()
Example #18
0
    def __validate(self):
        instruction = (
            "Okay, threshold set! "
            "To ensure its validity, please provide one (and only one) more response."
        )
        fill()
        message(instruction, location=P.screen_c, registration=5)
        flip()
        self.stream.start()
        validate_counter = CountDown(5)
        while validate_counter.counting():
            ui_request()
            if self.stream.sample().peak >= self.threshold:
                validate_counter.finish()
                self.threshold_valid = True
        self.stream.stop()

        if self.threshold_valid:
            validation_msg = "Great, validation was successful! Press any key to continue."
        else:
            validation_msg = (
                "Validation wasn't successful. "
                "Type C to re-calibrate or V to try validation again.")
        fill()
        message(validation_msg, location=P.screen_c, registration=5)
        flip()
        selection_made = False
        while not selection_made:
            q = pump(True)
            if self.threshold_valid:
                if key_pressed(queue=q):
                    return
            else:
                if key_pressed(SDLK_c, queue=q):
                    self.calibrate()
                elif key_pressed(SDLK_v, queue=q):
                    self.__validate()
Example #19
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()
Example #20
0
    def trial(self):

        fill()
        blit(self.digits[self.number][self.num_size], 5, P.screen_c)
        flip()

        self.rc.collect()
        response = self.rc.keypress_listener.response()

        if response.rt == klibs.TIMEOUT:
            resp, rt = ['nogo', 'NA']
        else:
            resp, rt = response
        correct_resp = 'nogo' if self.number == P.target else 'go'
        accuracy = resp == correct_resp

        while self.evm.before('trial_end'):
            ui_request()
            fill()
            blit(self.mask_x, 5, P.screen_c)
            blit(self.mask_ring, 5, P.screen_c)
            flip()

        if P.practicing:
            if accuracy == False:
                feedback = "Incorrect! "
                if correct_resp == 'nogo':
                    feedback += "Please withhold responses to the digit {0}.".format(
                        P.target)
                else:
                    feedback += "Please respond quickly to digits other than {0}.".format(
                        P.target)
            else:
                feedback = "Correct response!"
            feedback_msg = message(feedback, 'normal', blit_txt=False)
            feedback_timer = CountDown(1.5)
            while feedback_timer.counting():
                ui_request()
                fill()
                blit(feedback_msg, 5, P.screen_c)
                flip()

        # If probe trial, present MW probe and wait for response + keypress before ending trial

        if self.probe_trial:
            probe_resp, probe_rt = self.probe.collect()
            eff_level, eff_rt = self.get_effort()
            probe_rt = probe_rt * 1000  # convert seconds to ms
            eff_rt = eff_rt * 1000  # convert seconds to ms
            eff_level = eff_level * 100  # scale range to 0% - 100%
            resume_msg = message("Press the [space] key to resume the task.",
                                 'title',
                                 blit_txt=False)
            while True:
                if key_pressed(' '):
                    break
                fill()
                blit(resume_msg, 5, P.screen_c)
                flip()
        else:
            probe_resp, probe_rt, eff_level, eff_rt = ('NA', 'NA', 'NA', 'NA')

        return {
            "practicing": P.practicing,
            "block_num": P.block_number,
            "trial_num": P.trial_number,
            "digit": self.number,
            "digit_size": self.num_size,
            "target_digit": P.target,
            "response": resp,
            "rt": rt,
            "accuracy": accuracy,
            "probe_resp": probe_resp,
            "probe_rt": probe_rt,
            "effort_level": eff_level,
            "effort_rt": eff_rt
        }
Example #21
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.")
Example #22
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()
Example #23
0
    def block(self):

        # Initialize/reset list of previous letters presented

        self.past_letters = []

        # Determine nback difficulty for the block

        even_block = P.block_number % 2 == 0
        if self.first_nback == 1:
            self.nback = 2 if even_block else 1
        else:
            self.nback = 1 if even_block else 2

        # Determine positions of thought probes in trial sequence

        # Probes are pseudo-randomly distributed throughout blocks, with one probe in every set of
        # 30 trials. Probes cannot appear in the first 8 trials of a set, ensuring that probes are
        # at minimum 20 seconds apart.
        self.probe_trials = []
        noprobe_span = [False] * P.noprobe_span
        probe_span = [True] + [False] * P.probe_span
        while len(self.probe_trials) < P.trials_per_block:
            random.shuffle(probe_span)
            self.probe_trials += noprobe_span + probe_span

        # Generate block message

        header = "Block {0} of {1}".format(P.block_number,
                                           P.blocks_per_experiment)
        nback_txts = [' ', 'just before it', 'two before it']
        instructions = (
            "During this block, please press the [m] key when a letter matches\nthe letter "
            "{0}, and the [n] key when it does not.".format(
                nback_txts[self.nback]))
        if P.practicing:
            header = "This is a practice block. ({0})".format(header)
            instructions = instructions + "\nYou will be given feedback on your accuracy."
        msg = message(header + "\n\n" + instructions,
                      'normal',
                      align="center",
                      blit_txt=False)
        start_msg = message("Press the [n] key to start.",
                            'normal',
                            blit_txt=False)

        # Show block message, and wait for input before staring block

        message_interval = CountDown(2)
        while message_interval.counting():
            ui_request()  # Allow quitting during loop
            fill()
            blit(msg, 8, (P.screen_c[0], int(P.screen_y * 0.15)))
            self.draw_nback_illustration(P.screen_c[1],
                                         target=5 if self.nback == 1 else 4)
            flip()

        while True:
            if key_pressed('n'):
                break
            fill()
            blit(msg, 8, (P.screen_c[0], int(P.screen_y * 0.15)))
            self.draw_nback_illustration(P.screen_c[1],
                                         target=5 if self.nback == 1 else 4)
            blit(start_msg, 5, (P.screen_c[0], int(P.screen_y * 0.75)))
            flip()
Example #24
0
    def trial(self):

        start_delay = CountDown(P.origin_wait_time)
        while start_delay.counting():
            ui_request()
            fill()
            blit(self.tracker_dot, 5, self.origin_pos)
            flip()

        animate_start = self.evm.trial_time
        self.figure.animate()
        animate_time = self.evm.trial_time - animate_start
        avg_velocity = self.figure.path_length / animate_time

        if self.response_type == PHYS:
            self.physical_trial()
        elif self.response_type == MOTR:
            self.imagery_trial()
        else:
            self.control_trial()

        fill()
        flip()

        if self.__practicing__:
            return

        return {
            "session_num":
            self.session_number,
            "block_num":
            P.block_number,
            "trial_num":
            P.trial_number,
            "response_type":
            self.response_type,
            "feedback_type":
            self.feedback_type,
            "figure_type":
            self.figure_name,
            "figure_file":
            self.file_name + ".tlf",
            "stimulus_gt":
            self.animate_time,  # intended animation time
            "stimulus_mt":
            animate_time,  # actual animation time
            "avg_velocity":
            avg_velocity,  # in pixels per second
            "path_length":
            self.figure.path_length,
            "trace_file":
            (self.file_name + ".tlt") if self.response_type == PHYS else 'NA',
            "rt":
            self.rt,
            "it":
            self.it,
            "control_question":
            self.control_question if self.response_type == CTRL else 'NA',
            "control_response":
            self.control_response,
            "mt":
            self.mt
        }