示例#1
0
    def block(self):

        # Block type defaults to probe trials, overidden in practice block(s)
        self.block_type = PROBE

        # Show total score following completion of bandit task
        if self.total_score:
            fill()
            score_txt = "Total block score: {0} points!".format(
                self.total_score)
            msg = message(score_txt, 'timeout', blit_txt=False)
            blit(msg, 5, P.screen_c)
            flip()
            any_key()

        self.total_score = 0  # Reset score once presented

        # Bandit task
        if P.practicing:
            self.block_type == BANDIT
            # Initialize selection counters
            self.times_selected_high = 0
            self.time_selected_low = 0

        # End of block messaging
        if not P.practicing:
            self.block_type == PROBE
            fill()
            msg = message(self.end_of_block_txt, blit_txt=False)
            blit(msg, 5, P.screen_c)
            flip()
            any_key()
示例#2
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]
示例#3
0
 def run(self):
     if self.use_trial_clock:
         start = self.evm.trial_time
         if self.units == TK_S:
             start *= 0.001
     else:
         start = time()
         if self.units == TK_MS:
             start = int(start * 1000)
     for i in range(0, self.frame_count):
         if self.frames:
             for f in self.frames:
                 pass  # create a Frame class that knows how to blit itself after loading and rendering assets
         else:
             self.frame_draw_cb(*self.frame_draw_cb_args)
             if self.flip_after_cb:
                 flip()
         frame_running = True
         while frame_running:
             try:
                 self.frame_data_cb(self.frame_draw_cb_args)
             except TypeError:
                 pass
             if self.use_trial_clock:
                 elapsed = self.evm.trial_time
                 if self.units == TK_S:
                     elapsed *= 0.001
             else:
                 elapsed = time()
                 if self.units == TK_MS:
                     elapsed = int(start * 1000)
             frame_running = elapsed < i * self.frame_interval
             ui_request()
示例#4
0
    def block(self):
        # Show total score following completion of training task
        if self.total_score:
            fill()
            score_txt = "Total block score: {0} points!".format(
                self.total_score)
            msg = message(score_txt, 'myText', blit_txt=False)
            blit(msg, 5, P.screen_c)
            flip()
            any_key()

        self.total_score = 0  # Reset score once presented

        # Training task
        if P.practicing:
            self.block_type = TRAINING
            # Initialize selection counters
            self.high_value_trial_count = 0
            self.low_value_trial_count = 0

        # End of block messaging
        if not P.practicing:
            self.block_type = PROBE
            fill()
            msg = message(self.end_of_block_txt, 'myText', blit_txt=False)
            blit(msg, 5, P.screen_c)
            flip()
            any_key()
    def trial_prep(self):
        # Clear the screen of stimuli before the trial start
        clear()
        
        # Determine image and image name for trial
        self.image_name  = self.trial_factors[P.trial_number-1][0]
        self.arrangement = self.images[self.image_name]

        # infer which mask to use and retrieve it
        self.mask_type = self.trial_factors[P.trial_number-1][1]
        try:
            self.mask = self.masks[self.mask_type]
        except KeyError:
            self.mask = None
            
        # Reset warning signal flag
        self.first_warning_played = False
        self.second_warning_played = False
        
        #Reset gaze offscreen flag
        self.gaze_offscreen = time.time()
        
        # Display trial start message and perform drift correct after keypress
        blit(self.trial_start_msg, 5, P.screen_c)
        flip()
        any_key()
        self.el.drift_correct()
示例#6
0
    def draw_image_line(self, width, line, totlines, buff):
        '''
		Reads in the buffer from the EyeLink camera image line by line and writes it
		into a buffer of size (width * totlines). Once the last line of the image
		has been read into the buffer, the image buffer is placed in a PIL.Image
		with the palette set by set_image_palette, converted to RGBA, resized,
		and then rendered to the middle of the screen. After rendering, the image
		buffer is cleared.
		'''
        if len(self.imagebuffer) > (width * totlines):
            self.imagebuffer = []
        self.imagebuffer += buff
        if int(line) == int(totlines):
            # Render complete camera image and resize to self.size
            img = Image.new("P", (width, totlines), 0)
            img.putpalette(self.palette)
            img.putdata(self.imagebuffer)
            self.img = img.convert('RGBA').resize(self.size, Image.BILINEAR)
            # Set up aggdraw to draw crosshair/bounds/etc. on image surface
            self.drawer = Draw(self.img)
            self.drawer.setantialias(True)
            self.draw_cross_hair()
            self.drawer.flush()
            # Draw complete image to screen
            fill()
            blit(asarray(self.img), 5, P.screen_c)
            if self.title:
                loc_x = (P.screen_c[0])
                loc_y = (P.screen_c[1] + self.size[1] / 2 + 20)
                blit(self.title, 8, (loc_x, loc_y))
            flip()
            # Clear image buffer
            self.imagebuffer = []
示例#7
0
    def trial(self):
        # Set to true once played (to avoid repeats)
        tone_played = False

        # Prior to target onset, present fixation, tone & cue (when applicable)
        while self.evm.before('target_on'):
            fill()

            blit(self.fixation, registration=5, location=P.screen_c)

            # Tone
            if self.tone_trial and self.evm.between('tone_on', 'tone_off'):
                if not tone_played:
                    self.warning_tone.play()
                    tone_played = True

            # Cue
            if self.cue_location is not None and self.evm.between(
                    'cue_on', 'cue_off'):
                loc = self.cue_locations[self.cue_location]
                blit(self.cue, registration=5, location=loc)

            flip()
        # For some reason the cursor reappears here...
        hide_mouse_cursor()

        # Present target
        fill()
        blit(self.fixation, registration=5, location=P.screen_c)
        for shape, loc in self.arrows:
            blit(shape, registration=5, location=loc)
        flip()

        # Listen for response
        self.rc.collect()

        # Record response value & rt
        response, rt = self.rc.keypress_listener.response()
        # If no (valid) response made before timeout
        if rt == klibs.TIMEOUT:
            response = 'na'

        # Label response as correct/incorrect
        accuracy = int(response == self.target_direction)

        # Record trial data to database
        return {
            "block_num": P.block_number,
            "trial_num": P.trial_number,
            "practicing": P.practicing,
            "tone_trial": self.tone_trial,
            "tone_onset": self.tone_onset,
            "cue_type": self.cue_type,
            "congruent": self.congruent,
            "target_location": self.target_location,
            "target_direction": self.target_direction,
            "accuracy": accuracy,
            "response": response,
            "rt": rt
        }
示例#8
0
    def pre_trial(self):

        fill()
        blit(self.fixation, location=P.screen_c, registration=5)
        flip()

        any_key()
示例#9
0
    def get_effort(self):

        slider_loc = (P.screen_c[0], int(P.screen_y * 0.55))
        slider_cols = {'line': WHITE, 'slider': TRANSLUCENT_WHITE}
        scale = Slider(int(P.screen_x * 0.75),
                       ticks=5,
                       location=slider_loc,
                       fills=slider_cols)
        label_pad = scale.tick.surface_height

        show_mouse_cursor()
        onset = time.time()
        while True:
            sq = pump(True)
            ui_request(queue=sq)
            fill()
            blit(self.effort_q, 5, (P.screen_c[0], int(P.screen_y * 0.3)))
            blit(self.mineffort_msg, 8,
                 (scale.xmin, slider_loc[1] + label_pad))
            blit(self.maxeffort_msg, 8,
                 (scale.xmax, slider_loc[1] + label_pad))
            scale.draw()
            if scale.pos != None:
                self.submit.draw()
            flip()
            scale.listen(sq)
            if scale.pos != None:
                if self.submit.listen(sq) or key_pressed('Return', queue=sq):
                    rt = time.time() - onset
                    hide_mouse_cursor()
                    return (scale.pos, rt)
示例#10
0
    def wheel_callback(self, wheel):
        # Hide cursor during selection phase
        hide_mouse_cursor()

        # Response request msg
        colour_request_msg = self.t1_col_request if wheel == self.t1_wheel else self.t2_col_request
        message_offset = deg_to_px(1.5)
        message_loc = (P.screen_c[0], (P.screen_c[1] - message_offset))

        fill()

        # Present appropriate wheel
        if wheel == self.t1_wheel:
            blit(self.t1_wheel, registration=5, location=P.screen_c)
        else:
            blit(self.t2_wheel, registration=5, location=P.screen_c)
        # Present response request
        message(colour_request_msg,
                location=message_loc,
                registration=5,
                blit_txt=True)
        # Present annulus drawbject as cursor
        blit(self.cursor, registration=5, location=mouse_pos())

        flip()
    def block(self):
        # Present block progress
        block_txt = "Block {0} of {1}".format(P.block_number,
                                              P.blocks_per_experiment)
        progress_txt = self.anykey_txt.format(block_txt)

        if P.practicing:
            progress_txt += "\n(This is a practice block)"

        progress_msg = message(progress_txt, align='center', blit_txt=False)

        fill()
        blit(progress_msg, 5, P.screen_c)
        flip()
        any_key()

        # Inform as to block type
        if self.block_type == COLOUR:
            block_type_txt = self.anykey_txt.format(self.colour_instruct)
        else:
            block_type_txt = self.anykey_txt.format(self.identity_instruct)

        block_type_msg = message(block_type_txt,
                                 align='center',
                                 blit_txt=False)

        fill()
        blit(block_type_msg, 5, P.screen_c)
        flip()
        any_key()
    def trial_clean_up(self):
        # Reset ResponseCollectors
        self.t1_colouring_rc.color_listener.reset()
        self.t2_colouring_rc.color_listener.reset()

        self.t1_identity_rc.keypress_listener.reset()
        self.t2_identity_rc.keypress_listener.reset()

        # Switch block type
        if not P.practicing:
            if P.trial_number == P.trials_per_block:
                if P.block_number < P.blocks_per_experiment:
                    if self.block_type == IDENTITY:
                        self.block_type = COLOUR
                    else:
                        self.block_type = IDENTITY
        else:
            if P.trial_number == P.trials_per_practice_block:
                if self.block_type == IDENTITY:
                    self.block_type = COLOUR
                else:
                    self.block_type = IDENTITY

        if P.trial_number == P.trials_per_block:
            break_txt = self.anykey_txt.format("Good work! Take a break")
            break_msg = message(break_txt, align='center', blit_txt=False)

            fill()
            blit(break_msg, registration=5, location=P.screen_c)
            flip()
            any_key()
示例#13
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()
示例#14
0
文件: experiment.py 项目: a-hurst/PVT
    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
        }
    def display_refresh(self, cue=False, target=False):
        # In keypress condition, after target presented, check that gaze
        # is still within fixation bounds and print message at end if not
        if P.keypress_response_cond and not self.before_target:

            gaze = self.el.gaze()
            if not self.bi.within_boundary(label='drift_correct', p=gaze):
                self.moved_eyes_during_rc = True

        fill()

        blit(self.fix, registration=5, location=P.screen_c)

        blit(self.placeholder, registration=5, location=self.box1_loc)
        blit(self.placeholder, registration=5, location=self.box2_loc)

        if cue:
            blit(self.cue, registration=5, location=self.cue_loc)

        if target:
            if self.target_location != 'catch':
                blit(self.target, registration=5, location=self.target_loc)

            if self.before_target:
                self.before_target = False

        flip()
示例#16
0
    def init_figure_set(self):

        if not self.exp.figure_set_name or self.exp.figure_set_name == "NA":
            return

        if not self.exp.figure_set_name in self.exp.figure_sets:
            e_msg = "No figure set named '{0}' is registered.".format(
                self.exp.figure_set_name)
            raise ValueError(e_msg)

        # Verify that all figures listed in figure set exist, raising error if it doesn't
        figure_set = self.exp.figure_sets[self.exp.figure_set_name]
        for f in figure_set.names:
            f_path = os.path.join(P.resources_dir, "figures", f)
            if not os.path.exists(f_path + ".zip") and f != "random":
                fill()
                e_msg = (
                    "The figure '{0}' listed in the figure set '{1}' wasn't found.\n"
                    "Please check that the file is named correctly and try again. "
                    "TraceLab will now exit.".format(f,
                                                     self.exp.figure_set_name))
                blit(message(e_msg, blit_txt=False), 5, P.screen_c)
                flip()
                any_key()
                self.exp.quit()

        # Overwrite 'figure_name' trial factor with values defined in chosen figure set
        self.exp.trial_factory.exp_factors['figure_name'] = figure_set.to_list(
        )
示例#17
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]
示例#18
0
 def articulation_callback(self):
     fill()
     blit(self.fixation, 5, P.screen_c)
     if self.response_articulations == True:
         blit(self.articulations, 5, P.screen_c)
     blit(self.response_ring, 5, P.screen_c)
     flip()
示例#19
0
    def display_refresh(self, cue=None, tone=False, target=False):

        fill()

        blit(self.fixation, location=P.screen_c, registration=5)

        if cue is not None:
            if cue == TEMP_CUE:
                self.box_left.stroke = self.cued_stroke
                self.box_right.stroke = self.cued_stroke

            elif cue == VIS_LEFT:
                self.box_left.stroke = self.cued_stroke

            elif cue == VIS_RIGHT:
                self.box_right.stroke = self.cued_stroke

        else:
            self.box_right.stroke = self.uncued_stroke
            self.box_left.stroke = self.uncued_stroke

        blit(self.box_left, registration=5, location=self.locs['top_left'])
        blit(self.box_left, registration=5, location=self.locs['bottom_left'])
        blit(self.box_right, registration=5, location=self.locs['top_right'])
        blit(self.box_right, registration=5, location=self.locs['bottom_right'])

        if target:
            blit(self.target, registration=5, location=self.locs[self.target_loc])

        flip()

        if tone:
            self.audio_tone.play()
示例#20
0
    def log_and_recycle_trial(self, err_type):
        """
		Renders an error message to the screen and wait for a response. When a
		response is made, the incomplete trial data is logged to the trial_err
		table and the trial is recycled.
		
		"""
        flush()
        fill()
        message(self.err_msgs[err_type], registration=5, location=P.screen_c)
        flip()
        any_key()
        err_data = {
            "participant_id": P.participant_id,
            "block_num": P.block_number,
            "trial_num": P.trial_number,
            "session_type":
            'saccade' if P.saccade_response_cond else 'keypress',
            "cue_location": self.cue_location,
            "target_location": self.target_location,
            "start_axis": self.start_axis,
            "box_rotation": self.rotation_dir if self.animation_trial else NA,
            "animation_trial": boolean_to_logical(self.animation_trial),
            "err_type": err_type
        }
        self.database.insert(data=err_data, table="trials_err")
        raise TrialException(self.err_msgs[err_type])
示例#21
0
    def imagery_trial(self):

        fill()
        blit(self.origin_inactive, 5, self.origin_pos, flip_x=P.flip_x)
        flip()

        start = self.evm.trial_time
        if P.demo_mode or P.dm_always_show_cursor:
            show_mouse_cursor()

        at_origin = False
        while not at_origin:
            x, y, button = mouse_pos(return_button_state=True)
            left_button_down = button == 1
            if self.within_boundary('origin', (x, y)) and left_button_down:
                at_origin = True
                self.rt = self.evm.trial_time - start
            ui_request()
        fill()
        blit(self.origin_active, 5, self.origin_pos, flip_x=P.flip_x)
        flip()

        while at_origin:
            x, y, button = mouse_pos(return_button_state=True)
            left_button_down = button == 1
            if not (self.within_boundary('origin',
                                         (x, y)) and left_button_down):
                at_origin = False
        self.mt = self.evm.trial_time - (self.rt + start)
        if P.demo_mode:
            hide_mouse_cursor()
示例#22
0
    def ANT_callback(self):

        if self.evm.after('target_off') and not self.targets_removed:
            fill()
            blit(self.fixation, 5, P.screen_c)
            flip()
            self.targets_removed == True
示例#23
0
	def identity_callback(self, target):
		# Request appropriate identity
		identity_request_msg = self.t1_id_request if target == "T1" else self.t2_id_request
		
		fill()
		message(identity_request_msg, location=P.screen_c, registration=5, blit_txt=True)
		flip()
示例#24
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()
示例#25
0
    def block(self):

        if self.total_score:
            fill()
            score_txt = "Total block score: {0} points!".format(
                self.total_score)
            msg = message(score_txt, 'timeout', blit_txt=False)
            blit(msg, 5, P.screen_c)
            flip()
            any_key()
        self.total_score = 0  # reset total bandit score each block

        # Change bandit colours between blocks
        if P.practicing:
            greys = [(0, 0, 0, 255), (96, 96, 96, 255)]
            random.shuffle(greys)
            self.high_value_color = greys[0]
            self.low_value_color = greys[1]
        else:
            bandit_colours = self.bandit_colour_combos.pop()
            random.shuffle(bandit_colours)
            self.high_value_color = bandit_colours[0]
            self.low_value_color = bandit_colours[1]

        # Calibrate microphone for audio responses (people get quieter over time)
        threshold = self.audio.calibrate()
        self.probe_rc.audio_listener.threshold = threshold
        self.bandit_rc.audio_listener.threshold = threshold
示例#26
0
    def start_trial_button(self):

        fill()
        blit(self.next_trial_box,
             5,
             self.next_trial_button_loc,
             flip_x=P.flip_x)
        blit(self.next_trial_msg,
             5,
             self.next_trial_button_loc,
             flip_x=P.flip_x)
        flip()

        if P.demo_mode or P.dm_always_show_cursor:
            show_mouse_cursor()

        flush()
        clicked = False
        while not clicked:
            event_queue = pump(True)
            for e in event_queue:
                if e.type == SDL_MOUSEBUTTONDOWN:
                    clicked = self.within_boundary("next trial button",
                                                   [e.button.x, e.button.y])
                elif e.type == SDL_KEYDOWN:
                    ui_request(e.key.keysym)

        if not (P.demo_mode or P.dm_always_show_cursor):
            hide_mouse_cursor()
示例#27
0
    def calibrate(self):
        """Determines the loudness threshold for vocal responses based on sample input from the
		participant. 
		
		During calibration, input levels are monitored during three 3-second intervals in which 
		participants are asked to make a single vocal response. After all three samples are
		collected, the threshold is set to the smallest peak value of the three samples, and the
		participant is prompted to make one more response to see if it passes the threshold.
		If it does, calibration is complete and will end after any key is pressed. If it doesn't,
		the participant will be notified that calibration wasn't sucessful and will be prompted to
		press 'c' to calibrate again, or 'v' to try validation again.

		As a convenience for programmers writing and testing experiments using audio input, if
		KLibs is in development mode and the Params option 'dm_auto_threshold' is set to True, this
		calibration process will be skipped for a quicker one requiring no user input. In this
		mode, the ambient room noise is recorded for one second after a countdown, and the
		threshold is then set to be five times the average peak volume from that interval.
		This will not work if your microphone does not pick up any ambient room noise.

		Returns:
			int: an integer from 1 to 32767 representing the threshold value to use for vocal
				responses.

		Raises:
			RuntimeError: If using auto thresholding and the recorded ambient noise level is 0.
		"""
        if not self.stream:
            self.stream = self.exp.audio.stream
        if P.development_mode and P.dm_auto_threshold:
            ambient = self.get_ambient_level()
            if ambient == 0:
                e = (
                    "Ambient level appears to be zero, increase the gain on your microphone or "
                    "disable auto-thresholding.")
                raise RuntimeError(e)
            elif ambient * 5 > 32767:
                e = (
                    "Ambient noise level too high to use auto-thresholding. Reduce the gain on "
                    "your microphone or try and reduce the noise level in the room."
                )
                raise RuntimeError(e)
            self.threshold = ambient * 5
        else:
            peaks = []
            for i in range(0, 3):
                msg = "Provide a normal sample of your intended response."
                peaks.append(self.get_peak_during(3, msg))
                if i < 2:
                    s = "" if i == 1 else "s"  # to avoid "1 more samples"
                    next_message = ("Got it! {0} more sample{1} to collect. "
                                    "Press any key to continue".format(
                                        2 - i, s))
                    fill()
                    message(next_message, location=P.screen_c, registration=5)
                    flip()
                    any_key()
            self.threshold = min(peaks)
            self.__validate()
        return self.threshold
	def present_target(self):
		msg = "This is your target!"
		msg_loc = [P.screen_c[0], (P.screen_c[1] - deg_to_px(2))]

		fill()
		message(msg, location=msg_loc, registration=5)
		blit(self.target_item, location=P.screen_c, registration=5)
		flip()
示例#29
0
    def block_msg(self, text):

        msg = message(text, 'block_msg', blit_txt=False)
        fill()
        blit(msg, 5, P.screen_c)
        flip()
        flush()
        any_key()
示例#30
0
    def anykey_msg(self, msg):
        msg += "\n\n{press any key to continue}"

        fill()
        message(msg, location=P.screen_c, registration=5, align='center', blit_txt=True)
        flip()

        any_key()
示例#31
0
    def rc_callback(self):
        fill()

        blit(self.fixation, registration=5, location=P.screen_c)
        for shape, loc in self.arrows:
            blit(shape, registration=5, location=loc)

        flip()
示例#32
0
    def block(self):
        if P.block_number == int(math.ceil(P.blocks_per_experiment/2.0))+1:
			util.flush()
			msg_text = "Whew! You're halfway done.\nTake a break, then press any key to continue."
			msg = message(msg_text, align="center", blit_txt=False)
			fill()
			blit(msg, registration=5, location=P.screen_c)
			flip()
			any_key()
示例#33
0
    def trial(self):
        
        self.trial_time = time.time()        
        print(self.trial_articulations, self.response_articulations, self.duration, self.target_brightness)

        while self.evm.before('lines_on', True):
            fill()
            blit(self.fixation_light, 5, P.screen_c)
            flip()
            
        while self.evm.before('response_circle_on', True):
            self.start_time = time.time()
            target_on = self.evm.after('target_on') and self.evm.before('target_off')
            self.display_refresh(target_on)
            
            # Debug code for target timing, disabled by default
            self.elapsed = time.time() - self.start_time
            if 0.9 < (self.start_time - self.trial_time) <= 1.100 and self.debug_mode:
                print("init: %.3f" % (self.init_time - self.trial_time))
                if lines_on:
                    print("line: %.3f" % (self.line_time - self.trial_time))
                print("total: %.3f" % (self.elapsed))
        
        # Collect localization response and save response RT and response angle
        self.rc.collect()
        self.response_rt = self.rc.color_listener.response(False, True)
        self.deg_err = self.rc.color_listener.response(True, False)
        try:
            self.response_loc = (self.angle + self.deg_err) % 360
            print("Response accuracy: %.1f" % self.deg_err)
        except TypeError:
            self.response_loc = NA
        
        # Require participant to click center of screen to continue to next trial
        self.click_to_continue()

        return {
            "block_num": P.block_number,
            "trial_num": P.trial_number,
            "trial_articulations": self.trial_articulations,
            "response_articulations": self.response_articulations,
            "target_brightness": self.target_brightness,
            "duration": str(self.duration),
            "rt": self.response_rt,
            "target_refreshes": self.target_refreshes,
            "target_loc": self.angle,
            "response_loc": self.response_loc,
            "deg_err": self.deg_err
        }
示例#34
0
 def click_to_continue(self):        
     util.show_mouse_cursor()
     wait_for_click = True
     while wait_for_click:
         fill()
         blit(self.next_trial_circle, 5, P.screen_c)
         flip()
         events = util.pump(True)
         ui_request(queue=events)
         for e in events:
             if e.type == sdl2.SDL_MOUSEBUTTONUP:
                 pos = (e.button.x, e.button.y)
                 if self.within_boundary("center", pos):
                     fill()
                     flip()
                     wait_for_click = False      
     util.hide_mouse_cursor()
示例#35
0
 def display_refresh(self, target=False): 
     fill()
     blit(self.fixation, 5, P.screen_c)
     self.init_time = time.time() # for debug
     
     if self.trial_articulations:
         blit(self.articulations, 5, P.screen_c)
         self.line_time = time.time() # for debug
     
     if target:
         blit(self.target, 5, self.target_pos)
         self.target_refreshes += 1
     flip()
     
     if target and not self.target_already_on:
         self.target_ontime = time.time()
         print("target on! %.3f" % (self.target_ontime - self.trial_time))
         self.target_already_on = True   
     if not target and self.target_already_on:
         print("total target on-time: %.3f " % (time.time() - self.target_ontime))
         print("refreshes: {0} \n".format(self.target_refreshes))
         self.target_already_on = False
示例#36
0
    def trial_prep(self):
		
        # Define timecourse of events for the trial
             
        target_on = random.choice(range(500, 2050, 50))

        events = [[400-P.refresh_time, 'lines_on']]
        events.append([events[-1][0] + target_on, 'target_on']) 
        events.append([events[-1][0] + self.duration, 'target_off'])
        events.append([events[-1][0] + 1000, 'response_circle_on'])
        for e in events:
            self.evm.register_ticket(ET(e[1], e[0]))
        
        # Randomly select angle of target for the trial, and configure response collector accordingly
        
        self.angle = random.choice(range(0, 360, 1))
        self.response_ring.rotation = self.angle
        self.target_pos = util.point_pos(P.screen_c, self.circle_radius, -90, self.angle)
        self.rc.color_listener.set_target(self.target_pos)
        
        # Initialize target asterisk with random opacity within range
        
        self.target_brightness = random.choice(range(BRIGHTNESS_MIN, BRIGHTNESS_MAX+1, 1))
        target_colour = [self.target_brightness]*3 + [255]
        #self.target = kld.Asterisk(self.target_width, fill=target_colour, thickness=self.default_stroke/2).render()
        self.target = kld.Ellipse(self.target_width, fill=target_colour).render()

        # Reset debug flags before trial starts
        
        self.circle_already_on = False
        self.target_already_on = False
        self.target_refreshes = 0
        
        # Enter trial with screen already at desired state
        
        fill()
        blit(self.fixation_light, 5, P.screen_c)
        flip()