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()
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)
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()
def control_trial(self): if P.dm_always_show_cursor: show_mouse_cursor() self.control_bar.update_message( P.control_q.format(self.control_question)) self.control_bar.render() self.control_bar.collect_response() self.rt = self.control_bar.rt self.mt = self.control_bar.mt self.control_response = self.control_bar.response
def drift_correct(self, location=None, target=None, fill_color=None, draw_target=True): """Checks the accuracy of the eye tracker's calibration by presenting a fixation stimulus and requiring the participant to press the space bar while looking directly at it. If there is a large difference between the gaze location at the time the key was pressed and the true location of the fixation, it indicates that there has been drift in the calibration. In TryLink mode, drift correct targets are still displayed the same as with a hardware eye tracker. Simulated drift corrects are performed by clicking the drift correct target with the mouse. Args: location (Tuple(int, int), optional): The (x,y) pixel coordinates where the drift correct target should be located. Defaults to the center of the screen. target: A :obj:`Drawbject` or other :func:`KLGraphics.blit`-able shape to use as the drift correct target. Defaults to a circular :func:`drift_correct_target`. fill_color: A :obj:`List` or :obj:`Tuple` containing an RGBA colour to use for the background for the drift correct screen. Defaults to the value of ``P.default_fill_color``. draw_target (bool, optional): A flag indicating whether the function should draw the drift correct target itself (True), or whether it should leave it to the programmer to draw the target before :meth:`drift_correct` is called (False). Defaults to True. """ show_mouse_cursor() target = drift_correct_target() if target is None else target draw_target = EL_TRUE if draw_target in [EL_TRUE, True] else EL_FALSE location = P.screen_c if location is None else location if not iterable(location): raise ValueError("'location' must be a pair of (x,y) pixel coordinates.") dc_boundary = CircleBoundary('drift_correct', location, P.screen_y // 30) while True: event_queue = pump(True) ui_request(queue=event_queue) if draw_target == EL_TRUE: fill(P.default_fill_color if not fill_color else fill_color) blit(target, 5, location) flip() else: SDL_Delay(2) # required for pump() to reliably return mousebuttondown events for e in event_queue: if e.type == SDL_MOUSEBUTTONDOWN and dc_boundary.within([e.button.x, e.button.y]): hide_mouse_cursor() if draw_target == EL_TRUE: fill(P.default_fill_color if not fill_color else fill_color) flip() return 0
def collect(self): show_mouse_cursor() response = None onset = time.time() while response == None: fill() self._render() flip() response = self._collect() rt = time.time() - onset hide_mouse_cursor() return Response(response, rt)
def __trial__(self, trial, practice): """ Private method; manages a trial. """ from klibs.KLUtilities import pump, show_mouse_cursor, hide_mouse_cursor # At start of every trial, before setup_response_collector or trial_prep are run, retrieve # the values of the independent variables (factors) for that trial (as generated earlier by # TrialFactory) and set them as attributes of the experiment object. factors = list(self.trial_factory.exp_factors.keys()) for iv in factors: iv_value = trial[factors.index(iv)] setattr(self, iv, iv_value) pump() self.setup_response_collector() self.trial_prep() tx = None try: if P.development_mode and (P.dm_trial_show_mouse or (P.eye_tracking and not P.eye_tracker_available)): show_mouse_cursor() self.evm.start_clock() if P.eye_tracking and not P.manual_eyelink_recording: self.el.start(P.trial_number) P.in_trial = True self.__log_trial__(self.trial()) P.in_trial = False if P.eye_tracking and not P.manual_eyelink_recording: self.el.stop() if P.development_mode and (P.dm_trial_show_mouse or (P.eye_tracking and not P.eye_tracker_available)): hide_mouse_cursor() self.evm.stop_clock() self.trial_clean_up() except TrialException as e: P.trial_id = False self.trial_clean_up() self.evm.stop_clock() tx = e if P.eye_tracking and not P.manual_eyelink_recording: # todo: add a warning, here, if the recording hasn't been stopped when under manual control self.el.stop() if tx: raise tx
def collect_response(self): self.start = time.time() finished = False selection = None last_selected = None flush() mt_start = None while not finished: show_mouse_cursor() events = pump(True) for e in events: if e.type == sdl2.SDL_KEYDOWN: ui_request(e.key.keysym) elif e.type == sdl2.SDL_MOUSEBUTTONDOWN: selection = None for b in self.buttons: if self.within_boundary(b.button_text, [e.button.x, e.button.y]): self.toggle(b) if not self.rt: self.rt = time.time() - self.start mt_start = time.time() if b.active: selection = b last_selected = b if callable(b.callback): if self.finish_b is None: return b.callback else: b.callback() try: if self.finish_b.active and self.within_boundary( "Done", [e.button.x, e.button.y]): self.response = int(last_selected.button_text) self.mt = time.time() - mt_start finished = True except AttributeError: pass try: self.finish_b.active = selection is not None except AttributeError: pass self.render() fill() flip() hide_mouse_cursor()
def collect(self): show_mouse_cursor() onset = time.time() while self.scale.response == None: q = pump(True) ui_request(queue=q) fill() blit(self.q, location=self.origin, registration=8) self.scale.response_listener(q) flip() response = self.scale.response rt = time.time() - onset hide_mouse_cursor() self.scale.response = None # reset for next time return Response(response, rt)
def slide(self): show_mouse_cursor() self.blit() dragging = False while True: if not dragging: m_pos = mouse_pos() for event in pump(True): if event.type == sdl2.SDL_KEYDOWN: ui_request(event.key.keysym) elif event.type in (sdl2.SDL_MOUSEBUTTONDOWN, sdl2.SDL_MOUSEBUTTONUP): within_button = self.within_boundary("button", m_pos) if self.button_active and within_button: return self.response dragging = self.within_boundary("handle", m_pos) if dragging: button_up = False off_handle = False for event in pump(True): if event.type == sdl2.SDL_KEYDOWN: ui_request(event.key.keysym) elif event.type == sdl2.SDL_MOUSEBUTTONUP: button_up = True off_handle = not self.within_boundary("handle", mouse_pos()) if off_handle or button_up: dragging = False self.response = self.handle_value() self.button_active = True flush() return -1 self.handle_pos = mouse_pos()[0] self.blit() return False