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()
Beispiel #2
0
def alert(text):
    '''A convenience function for clearing the screen and displaying an alert message. Will
	probably be depricated soon.

	'''
    clear()
    message(text, "alert", blit_txt=True, flip_screen=True)
Beispiel #3
0
    def __execute_experiment__(self, *args, **kwargs):
        """For internal use, actually runs the blocks/trials of the experiment in sequence.

		"""
        from klibs.KLGraphics import clear

        if self.blocks == None:
            self.blocks = self.trial_factory.export_trials()

        for block in self.blocks:
            P.recycle_count = 0
            P.block_number = self.blocks.i
            P.practicing = block.practice
            self.block()
            P.trial_number = 1
            for trial in block:  # ie. list of trials
                try:
                    try:
                        P.trial_id = self.database.last_id_from('trials') + 1
                    except TypeError:
                        P.trial_id = 1
                    self.__trial__(trial, block.practice)
                    P.trial_number += 1
                except TrialException:
                    block.recycle()
                    P.recycle_count += 1
                    clear()  # NOTE: is this actually wanted?
                self.rc.reset()
        self.clean_up()

        self.incomplete = False
        if 'session_info' in self.database.table_schemas.keys():
            where = {'session_number': P.session_number}
            self.database.update('session_info', {'complete': True}, where)
Beispiel #4
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()
    def trial(self):


        while self.evm.before('cue_on'):
            self.wait_time()

        self.display_refresh(cue=True)

        while self.evm.before('cue_off'):
            self.wait_time()


        self.display_refresh()

        while self.evm.before('target_on'):
            self.wait_time()

        flush()

        self.display_refresh(target=True)

        if P.saccade_response_cond:
            self.record_saccades()
            keypress_rt = 'NA'

        if P.keypress_response_cond:
            self.rc.collect()
            keypress_rt = self.rc.keypress_listener.response(rt=True, value=False)

        clear()
        smart_sleep(1000)

        if P.keypress_response_cond:
            if self.target_location == "catch" and keypress_rt != TIMEOUT:
                fill()
                message(self.err_msgs['early'], registration=5, location=P.screen_c)
                flip()
                any_key()
            elif self.moved_eyes_during_rc:
                fill()
                message("Moved eyes during response interval!", registration=5, location=P.screen_c)
                flip()
                any_key()

        return {
            "block_num": P.block_number,
            "trial_num": P.trial_number,
            'session_type': 'saccade' if P.saccade_response_cond else 'keypress',
            'box_alignment': self.box_alignment,
            'cue_location': self.cue_location,
            'target_location': self.target_location,
            'target_acquired': str(self.target_acquired).upper() if P.saccade_response_cond else NA,
            'keypress_rt': keypress_rt if P.keypress_response_cond else NA,
            'moved_eyes': str(self.moved_eyes_during_rc).upper() if P.keypress_response_cond else NA

        }
 def screen_refresh(self):
     position = self.el.gaze()
     fill()
     blit(self.figure, 5, P.screen_c)
     if not position:
         clear()
     else:
         if self.mask is not None:
             blit(self.mask, 5, position)
     flip()
	def trial(self):					
		# Wait 1s before presenting array
		while self.evm.before("present_fixation", True):
			ui_request()

		self.present_fixation()

		while self.evm.before("search_onset", True):
			ui_request()
		

		if self.search_type == SPACE:
			self.present_array()
			self.spatial_rc.collect()


			if len(self.spatial_rc.cursor_listener.responses):
				spatial_located, spatial_rt = self.spatial_rc.cursor_listener.response()
			else:
				spatial_located = 'miss'
				spatial_rt = 'NA'
		else:
			try:
				# the display callback "present_stream()" pops an element each pass; when all targets have been shown this bad boy throws an error
				self.temporal_rc.collect()
			except IndexError:
				self.temporal_responses = self.temporal_rc.mousebutton_listener.responses

		trial_data = {
			"block_num": P.block_number,
			"trial_num": P.trial_number,
			"search_type": "Spatial",
			"cell_count": self.cell_count,
			"target_distractor": self.target_distractor,
			"distractor_distractor": self.distractor_distractor,
		}
		if self.search_type == TIME:
			for tpt in self.temporal_presentation_times:
				onset_key = 't{0}_onset'.format(self.temporal_presentation_times.index(tpt)+1)
				onset_val = tpt[0]
				dist_count_key = 't{0}_distractor_count'.format(self.temporal_presentation_times.index(tpt)+1)
				dist_count_val = tpt[1]
				trial_data[onset_key] = onset_val
				trial_data[dist_count_key] = dist_count_val
		else:
			for i in range(0,15):
				onset_key = 't{0}_onset'.format(i+1)
				onset_val = 'NA'
				dist_count_key = 't{0}_distractor_count'.format(i+1)
				dist_count_val = 'NA'
				trial_data[onset_key] = onset_val
				trial_data[dist_count_key] = dist_count_val
		return trial_data
		clear()
Beispiel #8
0
	def trial(self):
		while self.evm.before('T1_on', True): ui_request()			# Variable delay following trial initiation

		self.blit_it(self.tmtm_stream['t1_target'])					# Blit T1 to screen
		while self.evm.before('T1_off', True): ui_request()			# Wait (conditional duration)
		self.flip_it()												# Remove T1

		while self.evm.before('T1_mask_on', True): ui_request() 	# Wait (ISI; fixed at ~17ms)

		self.blit_it(self.tmtm_stream['t1_mask'])					# Blit M1 to screen
		while self.evm.before('T1_mask_off', True): ui_request()	# Wait (conditional duration)
		self.flip_it()												# Remove M1

		while self.evm.before('T2_on', True): ui_request()			# Wait (TTOA)

		self.blit_it(self.tmtm_stream['t2_target'])					# Blit T2 to screen
		while self.evm.before('T2_off', True): ui_request()			# Wait (fixed at ~50ms)
		self.flip_it()												# Remove T2

		while self.evm.before('T2_mask_on', True): ui_request()		# Wait (ISI; fixed at ~17ms)

		self.blit_it(self.tmtm_stream['t2_mask'])					# Blit M2 to screen
		while self.evm.before('T2_mask_off', True): ui_request()	# Wait (fixed at ~50ms)
		self.flip_it()												# Remove M2

		self.t1_rc.collect()										# Request T1 identity
		self.t2_rc.collect()										# Request T2 identity

		# Save responses
		t1_response = self.t1_rc.keypress_listener.response(rt=False)
		t2_response = self.t2_rc.keypress_listener.response(rt=False)

		# Clear remaining stimuli from screen
		clear()

		# Log trial factors & responses
		return {
			"block_num": P.block_number,
			"trial_num": P.trial_number,
			"practicing": str(P.practicing),
			"isoa": self.isoa,
			"isi": self.isi,
			"ttoa": self.ttoa,
			"t1_difficulty": self.t1_difficulty,
			"t1_duration": self.t1_duration,
			"m1_duration": self.m1_duration,
			"t2_duration": self.t2_duration,
			"m2_duration": self.m2_duration,
			"t1_identity": self.t1_identity,
			"t2_identity": self.t2_identity,
			"t1_response": t1_response,
			"t2_response": t2_response
		}
    def trial_prep(self):

        if P.development_mode:
            print "\ntrial factors"
            print "======================"

            fill()
            msg = "Box Alignment: {0}\nCue Location: {1}\nTarget Location: {2}".format(
                self.box_alignment, self.cue_location, self.target_location)
            print msg
            print "======================"
            message(msg, registration=5, location=P.screen_c, blit_txt=True)
            flip()

            any_key()

            clear()
            any_key()


        self.placeholder = self.construct_placeholder()
        self.cue = self.construct_cue()

        self.cue_loc = self.locations[self.cue_location]

        self.set_box_positions()

        self.target_trial = False

        if self.target_location != 'catch':
            self.target_trial = True
            self.target_loc = self.get_target_location()

        self.evm.register_tickets([
            ('cue_on', 1000),       # Cue appears 1000ms after drift check
            ('cue_off', 1100),      # Cue removed after 100ms
            ('target_on', 1960),    # Target appears 860ms after cue removal
            ('task_end', 4460)     # 2500ms to respond to target before trial aborts
        ])

        # Reset trial flags
        self.before_target = True
        self.target_acquired = False
        self.moved_eyes_during_rc = False

        self.display_refresh()
        self.el.drift_correct(fill_color=BLACK, draw_target=EL_FALSE)
        self.fix.fill = WHITE
        self.display_refresh()
        flush()
Beispiel #10
0
    def trial(self):
        while self.evm.before("present_fixation", True):
            ui_request()

        self.blit_img(self.fixation, 5, P.screen_c)

        while self.evm.before("search_onset", True):
            ui_request()

        if self.search_type == SPACE:
            self.rc.collect()

        else:
            try:
                self.target_onset = 'NA'
                self.target_sw = Stopwatch()
                self.rc.collect()
            except IndexError:

                pass

        if len(self.rc.keypress_listener.responses):
            response, rt = self.rc.keypress_listener.response()
            if response != self.present_absent:
                self.present_feedback()

        else:
            response, rt = 'None', 'NA'

        clear()

        return {
            "practicing": str(P.practicing),
            "block_num": P.block_number,
            "trial_num": P.trial_number,
            "search_type": self.search_type,
            "stimulus_type": "LINE" if P.condition == 'line' else "COLOUR",
            "present_absent": self.present_absent,
            "set_size": self.set_size if self.search_type == SPACE else 'NA',
            "target_distractor": self.target_distractor,
            "distractor_distractor": self.distractor_distractor,
            "target_onset":
            self.target_onset if self.search_type == TIME else 'NA',
            "response": response,
            "rt": rt,
            "error": str(response != self.present_absent)
        }
    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}
Beispiel #12
0
    def trial(self):
        hide_mouse_cursor()

        while self.evm.before('cue_on'):
            ui_request()

        self.display_refresh(cue=self.cue_type, tone=self.tone_trial)

        while self.evm.before('cue_off'):
            ui_request()

        self.display_refresh()

        while self.evm.before('target_on'):
            ui_request()

        self.rc.collect()

        if self.rc.keypress_listener.response_count != 0:
            response, rt = self.rc.keypress_listener.response()

        else:
            response, rt = NA, NA

        self.present_feedback(rt=rt, response=response)

        clear()

        return {
            "block_num": P.block_number,
            "trial_num": P.trial_number,
            "practicing": str(P.practicing),
            'cue_type': self.cue_type,
            'ctoa': self.ctoa,
            'target_loc': self.target_loc,
            'target_side': self.target_side,
            'tone_trial': str(self.tone_trial),
            'response': response,
            'rt': rt
        }
    def __generate_stimuli(self):
        clear()
        msg = message("Generating stimuli...", "q_and_a", blit_txt=False)
        blit(msg, 5, P.screen_c)
        flip()

        stimuli_labels = [[(False, 0), (CIRCLE, 0)], [(False, 90), (CIRCLE, 0)], [(False, 180), (CIRCLE, 0)],
                          [(False, 270), (CIRCLE, 0)],
                          [(False, 0), (SQUARE, 0)], [(False, 90), (SQUARE, 0)], [(False, 180), (SQUARE, 0)],
                          [(False, 270), (SQUARE, 0)],
                          [(CIRCLE, 0), (False, 0)], [(CIRCLE, 0), (False, 90)], [(CIRCLE, 0), (False, 180)],
                          [(CIRCLE, 0), (False, 270)],
                          [(SQUARE, 0), (False, 0)], [(SQUARE, 0), (False, 90)], [(SQUARE, 0), (False, 180)],
                          [(SQUARE, 0), (False, 270)]]

        for sl in stimuli_labels:
            stim = self.render_texture(sl[1][0], sl[1][1])
            figure = self.render_figure(sl[0][0], sl[0][1])
            stim.putalpha(figure)
            stim = aggdraw_to_numpy_surface(stim)
            fig_text = sl[0][0] if sl[0][0] in (CIRCLE, SQUARE) else "D_%s" % sl[0][1]
            texture_text = sl[1][0] if sl[1][0] in (CIRCLE, SQUARE) else "D_%s" % sl[1][1]
            self.stimuli["{0}_{1}".format(fig_text, texture_text)] = stim.render()
    def trial_prep(self):
        clear()
        # choose randomly varying parts of trial
        self.orientation = random.choice(self.orientations)
        self.fixation = tuple(random.choice(self.exp_meta_factors['fixation']))

        # infer which mask & stim to use and retrieve them
        self.figure = self.target_shape if self.target_level == LOCAL else False

        if self.figure:
            stim_label = "{0}_D_{1}".format(self.target_shape, self.orientation)
        else:
            stim_label = "D_{0}_{1}".format(self.orientation, self.target_shape)
        self.figure = self.stimuli[stim_label]
        self.mask_label = "{0}_{1}".format(self.mask_type, self.mask_size)
        try:
            self.mask = self.masks[self.mask_label]
        except KeyError:
            self.mask = None  # for the no mask condition, easier than creating empty keys in self.masks
        blit(self.trial_start_msg, 5, P.screen_c)
        flip()
        any_key()
        self.el.drift_correct(self.fixation)
    def __generate_masks(self):
        smaller_than_screen = True
        while smaller_than_screen:
            self.maximum_mask_size += 1
            new_max_mask_px = deg_to_px(self.maximum_mask_size) + self.mask_blur_width * 4 + 2
            if new_max_mask_px > P.screen_y:
                smaller_than_screen = False
                self.maximum_mask_size -= 1
        for size in self.trial_factory.exp_factors['mask_size']:
            if size > self.maximum_mask_size:
                e_str = "The maximum mask size this monitor can support is {0} degrees.".format(self.maximum_mask_size)
                raise ValueError(e_str)

        clear()
        msg = message("Rendering masks...", "q_and_a", blit_txt=False)
        blit(msg, 5, P.screen_c)
        flip()

        self.masks = {}
        for size in self.trial_factory.exp_factors['mask_size']:
            ui_request()
            self.masks["{0}_{1}".format(CENTRAL, size)] = self.render_mask(size, CENTRAL).render()
            self.masks["{0}_{1}".format(PERIPHERAL, size)] = self.render_mask(size, PERIPHERAL).render()
Beispiel #16
0
    def trial(self):
        # Wait 1s before presenting array
        while self.evm.before("present_fixation", True):
            ui_request()

        self.present_fixation()

        while self.evm.before("search_onset", True):
            ui_request()

        if self.search_type == SPACE:
            self.present_array()
            self.spatial_rc.collect()

            if len(self.spatial_rc.keypress_listener.responses):
                spatial_response, spatial_rt = self.spatial_rc.keypress_listener.response(
                )

                if spatial_response != self.present_absent:
                    self.present_feedback()
            else:
                spatial_response = "None"
                spatial_rt = 'NA'
        else:

            try:
                self.response_sw = Stopwatch(
                )  # Used as RT stopwatch in cases where responses are made after stream has ended
                self.stream_sw = Stopwatch(
                )  # Records duration of stream, just in case it becomes handy to have
                self.target_sw = Stopwatch(
                )  # Records time that target is presented, again just in case.

                # the display callback "present_stream()" pops an element each pass; when all targets have been shown this bad boy throws an error
                self.temporal_pre_rc.collect()
            except IndexError:
                pass

            # Pause once stream has ended
            self.stream_sw.pause()

            if len(self.temporal_pre_rc.keypress_listener.responses):
                temporal_response, temporal_rt = self.temporal_pre_rc.keypress_listener.response(
                )

            else:
                self.temporal_post_rc.collect()

                if len(self.temporal_post_rc.keypress_listener.responses):
                    temporal_rt = self.response_sw.elapsed(
                    ) * 1000  # Rescale RT to ms and log
                    temporal_response = self.temporal_post_rc.keypress_listener.response(
                        rt=False)

                else:
                    temporal_response = "None"
                    temporal_rt = "NA"

            if temporal_response != self.present_absent:
                self.present_feedback()

        clear()

        return {
            "practicing":
            str(P.practicing),
            "block_num":
            P.block_number,
            "trial_num":
            P.trial_number,
            "search_type":
            self.search_type,
            "stimulus_type":
            'LINE',
            "present_absent":
            self.present_absent,
            "set_size":
            self.set_size if self.search_type == SPACE else 'NA',
            "target_distractor":
            self.target_distractor,
            "distractor_distractor":
            self.distractor_distractor,
            "target_time":
            self.target_time if self.search_type == TIME else "NA",
            "stream_duration":
            self.stream_sw.elapsed() if self.search_type == TIME else "NA",
            "target_onset":
            self.target_onset if self.search_type == TIME else "NA",
            "spatial_response":
            spatial_response if self.search_type == SPACE else "NA",
            "spatial_rt":
            spatial_rt if self.search_type == SPACE else "NA",
            "temporal_response":
            temporal_response if self.search_type == TIME else "NA",
            "temporal_rt":
            temporal_rt if self.search_type == TIME else "NA"
        }
    def trial(self):

        # Hide cursor during trial
        hide_mouse_cursor()

        # Present fixation & wait 1s before presenting RSVP stream
        self.present_fixation()
        while self.evm.before('stream_on', True):
            pass

        # Present RSVP stream
        self.present_stream()

        # For 'identity' blocks, request targets' numerical identity
        if self.block_type == IDENTITY:
            # Collect responses
            self.t1_identity_rc.collect()
            self.t2_identity_rc.collect()

            # Assign to return variables
            t1_id_response, t1_id_rt = self.t1_identity_rc.keypress_listener.response(
            )
            t2_id_response, t2_id_rt = self.t2_identity_rc.keypress_listener.response(
            )

            t1_response_err, t1_response_err_rt, t2_response_err, t2_response_err_rt = [
                'NA', 'NA', 'NA', 'NA'
            ]

        # For 'colour' blocks, request targets' colouring
        else:
            self.t1_colouring_rc.collect()
            self.t2_colouring_rc.collect()

            t1_response_err, t1_response_err_rt = self.t1_colouring_rc.color_listener.response(
            )
            t2_response_err, t2_response_err_rt = self.t2_colouring_rc.color_listener.response(
            )

            t1_id_response, t1_id_rt, t2_id_response, t2_id_rt = [
                'NA', 'NA', 'NA', 'NA'
            ]

        return {
            "block_num": P.block_number,
            "trial_num": P.trial_number,
            "block_type": self.block_type,
            "t1_time": self.t1_time,
            "t2_time": self.t2_time,
            "lag": self.lag,
            "t1_identity": self.t1_identity,
            "t2_identity": self.t2_identity,
            "t1_identity_response": t1_id_response,
            "t1_identity_rt": t1_id_rt,
            "t2_identity_response": t2_id_response,
            "t2_identity_rt": t2_id_rt,
            "t1_colour": self.t1_colour,
            "t2_colour": self.t2_colour,
            "t1_ang_err": t1_response_err,
            "t1_ang_err_rt": t1_response_err_rt,
            "t2_ang_err": t2_response_err,
            "t2_ang_err_rt": t2_response_err_rt,
            "t1_wheel_rotation": self.t1_wheel.rotation,
            "t2_wheel_rotation": self.t2_wheel.rotation
        }

        # Clear remaining stimuli from screen
        clear()
Beispiel #18
0
    def trial(self):

        # BANDIT TRIAL
        if P.practicing:
            cotoa, probe_rt = ['NA', 'NA']  # Don't occur in bandit blocks

            # Present placeholders
            while self.evm.before('target_on', True) and not self.err:
                self.confirm_fixation()
                self.present_neutral_boxes()
                flip()

            # BANDIT RESPONSE PERIOD
            self.targets_shown = True  # After bandits shown, don't recycle trial

            # Present bandits and listen for response
            self.bandit_rc.collect()

            # If wrong response made
            if self.err:
                bandit_choice, bandit_rt, reward = ['NA', 'NA', 'NA']
            else:
                self.err = 'NA'
                # Retrieve responses from ResponseCollector(s) & record data
                bandit_choice = self.bandit_rc.keypress_listener.response(
                    value=True, rt=False)
                bandit_rt = self.bandit_rc.keypress_listener.response(
                    value=False, rt=True)

                if bandit_rt == TIMEOUT:
                    self.show_error_message('bandit_timeout')
                    reward = 'NA'
                else:
                    # Determine bandit payout & display
                    reward = self.feedback(bandit_choice)

        # PROBE TRIAL
        else:
            bandit_choice, bandit_rt, reward = [
                'NA', 'NA', 'NA'
            ]  # Don't occur in probe trials

            # Present placeholders & confirm fixation
            while self.evm.before('target_on', True):
                self.confirm_fixation()
                self.present_neutral_boxes()

                # Present cue
                if self.evm.between('cue_on', 'cue_off'):
                    if self.cue_location == LEFT:
                        blit(self.thick_rect, 5, self.left_box_loc)
                    else:
                        blit(self.thick_rect, 5, self.right_box_loc)
                # Present cueback
                elif self.evm.between('cue_off', 'cueback_off'):
                    blit(self.star_cueback, 5, P.screen_c)

                flip()

            # PROBE RESPONSE PERIOD
            self.targets_shown = True  # After probe shown, don't recycle trial
            # Present probes & listen for response
            self.probe_rc.collect()

            # If 'go' trial, check for response
            if self.go_no_go == GO:
                # If wrong response made
                if self.err:
                    probe_rt = 'NA'
                # If correct response OR timeout
                else:
                    self.err = 'NA'
                    probe_rt = self.probe_rc.keypress_listener.response(
                        value=False, rt=True)
                    if probe_rt == TIMEOUT:
                        self.show_error_message('probe_timeout')
                        probe_rt = 'NA'
            # Similarly, for 'nogo' trials
            else:
                probe_rt = 'NA'
                # If response made, penalize
                if len(self.probe_rc.keypress_listener.responses):
                    self.show_error_message('response_on_nogo')
                    self.err = 'response_on_nogo'
                # If no response, continue as normal
                else:
                    self.err = 'NA'
        # Return trial data
        return {
            "block_num": P.block_number,
            "trial_num": P.trial_number,
            "block_type": "BANDIT" if P.practicing else "PROBE",
            "high_value_col":
            self.high_value_colour[:3] if P.practicing else 'NA',
            "high_value_loc":
            self.high_value_location if P.practicing else 'NA',
            "low_value_col":
            self.low_value_colour[:3] if P.practicing else 'NA',
            "low_value_loc": self.low_value_location if P.practicing else 'NA',
            "winning_trial": self.winning_trial if P.practicing else 'NA',
            "bandit_selected": self.bandit_selected if P.practicing else 'NA',
            "bandit_rt": bandit_rt,
            "reward": reward,
            "cue_loc": self.cue_location if not P.practicing else 'NA',
            "cotoa": self.cotoa if not P.practicing else 'NA',
            "probe_loc": self.probe_location if not P.practicing else 'NA',
            "probe_col": self.probe_colour if not P.practicing else 'NA',
            "go_no_go": self.go_no_go if not P.practicing else 'NA',
            "probe_rt": probe_rt,
            "err": self.err
        }
        # Clear remaining stimuli from screen
        clear()
Beispiel #19
0
    def trial(self):

        if P.development_mode:
            trial_info = (
                "\ntrial_type: '{0}', high_val_loc: '{1}', probe_loc: '{2}', "
                "cue_loc: '{3}', winning_bandit: '{4}'")
            print(
                trial_info.format(self.trial_type, self.high_value_location,
                                  self.probe_location, self.cue_location,
                                  self.winning_bandit))

        while self.evm.before('target_on', True) and not self.err:

            self.confirm_fixation()
            self.present_neutral_boxes()

            if self.evm.between('cue_on', 'cue_off'):
                if self.cue_location in [LEFT, DOUBLE]:
                    blit(self.thick_rect, 5, self.left_box_loc)
                if self.cue_location in [RIGHT, DOUBLE]:
                    blit(self.thick_rect, 5, self.right_box_loc)
            elif self.evm.between('cue_off', 'cueback_off'):
                blit(self.star_cueback, 5, P.screen_c)

            flip()

        self.targets_shown = True  # after bandits or probe shown, don't recycle trial on user error
        if self.trial_type in [BANDIT, BOTH] and not self.err:
            while self.evm.before('nogo_end') and not self.err:
                if key_pressed():
                    self.show_error_message('too_soon')
                    self.err = "early_response"
                    break
                self.confirm_fixation()
                self.bandit_callback(before_go=True)
                flip()

        #  PROBE RESPONSE PERIOD
        if self.trial_type in [PROBE, BOTH] and not self.err:
            self.probe_rc.collect()
            if not self.err:
                if len(self.probe_rc.keypress_listener.responses):
                    self.show_error_message('wrong_response')
                    self.err = 'keypress_on_probe'
                elif len(self.probe_rc.audio_listener.responses) == 0:
                    self.show_error_message('probe_timeout')
                    if self.probe_rc.audio_listener.stream_error:
                        self.err = 'microphone_error'
                    else:
                        self.err = 'probe_timeout'

        #  BANDIT RESPONSE PERIOD
        if self.trial_type in [BANDIT, BOTH] and not self.err:
            self.bandit_rc.collect()
            if self.trial_type == BANDIT and P.ignore_vocal_for_bandits == False:
                if len(self.bandit_rc.audio_listener.responses):
                    self.show_error_message('wrong_response')
                    self.err = 'vocal_on_bandit'

        # Retrieve collected response data before logging to database
        if self.err:
            bandit_choice, bandit_rt, reward = ['NA', 'NA', 'NA']
            probe_rt = 'NA'
        else:
            self.err = 'NA'
            # Retreive responses from RepsponseCollector(s) and record data
            if self.trial_type in [BANDIT, BOTH]:
                bandit_choice = self.bandit_rc.keypress_listener.response(
                    value=True, rt=False)
                bandit_rt = self.bandit_rc.keypress_listener.response(
                    value=False, rt=True)
                if bandit_rt == TIMEOUT:
                    self.show_error_message('bandit_timeout')
                    reward = 'NA'
                else:
                    # determine bandit payout (reward) and display feedback to participant
                    reward = self.feedback(bandit_choice)
            else:
                bandit_choice, bandit_rt, reward = ['NA', 'NA', 'NA']

            if self.trial_type in [PROBE, BOTH]:
                probe_rt = self.probe_rc.audio_listener.response(value=False,
                                                                 rt=True)
            else:
                probe_rt = 'NA'

        # Clear any remaining stimuli from screen before trial end
        clear()

        return {
            "block_num":
            P.block_number,
            "trial_num":
            P.trial_number,
            "trial_type":
            self.trial_type,
            "cue_loc":
            self.cue_location,
            "cotoa":
            self.cotoa,
            "high_value_col":
            self.high_value_color[:3] if self.trial_type != PROBE else "NA",
            "low_value_col":
            self.low_value_color[:3] if self.trial_type != PROBE else "NA",
            "high_value_loc":
            self.high_value_location if self.trial_type != PROBE else "NA",
            "winning_bandit":
            self.winning_bandit if self.trial_type != PROBE else "NA",
            "bandit_choice":
            bandit_choice,
            "bandit_rt":
            bandit_rt,
            "reward":
            reward,
            "probe_loc":
            self.probe_location if self.trial_type != BANDIT else "NA",
            "probe_rt":
            probe_rt,
            "err":
            self.err
        }
Beispiel #20
0
    def trial(self):
        # Wait 1s before presenting array
        while self.evm.before("present_fixation", True):
            ui_request()

        self.present_fixation()

        while self.evm.before("search_onset", True):
            ui_request()

        if self.search_type == SPACE:
            self.present_array()
            self.spatial_rc.collect()

            if len(self.spatial_rc.keypress_listener.responses):
                spatial_response, spatial_rt = self.spatial_rc.keypress_listener.response(
                )

                if spatial_response != self.present_absent:
                    self.present_feedback()

            else:
                spatial_response = "None"
                spatial_rt = 'NA'
        else:

            try:
                self.response_sw = Stopwatch()
                self.stream_sw = Stopwatch()
                self.target_sw = Stopwatch()

                # the display callback "present_stream()" pops an element each pass; when all targets have been shown this bad boy throws an error
                self.temporal_pre_rc.collect()
            except IndexError:
                pass

            self.stream_sw.pause()

            if len(self.temporal_pre_rc.keypress_listener.responses):
                temporal_response, temporal_rt = self.temporal_pre_rc.keypress_listener.response(
                )

            else:
                self.temporal_post_rc.collect()

                if len(self.temporal_post_rc.keypress_listener.responses):
                    temporal_response = self.temporal_post_rc.keypress_listener.response(
                        rt=False)
                    temporal_rt = self.response_sw.elapsed() * 1000

                else:
                    temporal_response = "None"
                    temporal_rt = "NA"

            if temporal_response != self.present_absent:
                self.present_feedback()

        clear()
        return {
            "practicing":
            str(P.practicing),
            "block_num":
            P.block_number,
            "trial_num":
            P.trial_number,
            "search_type":
            self.search_type,
            "stimulus_type":
            'COLOR',
            "present_absent":
            self.present_absent,
            "set_size":
            self.set_size if self.search_type == SPACE else "NA",
            "target_distractor":
            self.target_distractor,
            "distractor_distractor":
            self.distractor_distractor,
            "target_time":
            self.target_time if self.search_type == TIME else "NA",
            "stream_duration":
            self.stream_sw.elapsed() if self.search_type == TIME else "NA",
            "target_onset":
            self.target_onset if self.search_type == TIME else "NA",
            "spatial_response":
            spatial_response if self.search_type == SPACE else "NA",
            "spatial_rt":
            spatial_rt if self.search_type == SPACE else "NA",
            "temporal_response":
            temporal_response if self.search_type == TIME else "NA",
            "temporal_rt":
            temporal_rt if self.search_type == TIME else "NA"
        }
Beispiel #21
0
    def trial(self):

        while self.evm.before("cross fix end"):
            self.jc_wait_time()
            self.display_refresh(self.start_axis, self.cross_w)

        while self.evm.before("circle fix end"):
            self.jc_wait_time()
            self.display_refresh(self.start_axis, self.circle)

        while self.evm.before("cue end"):
            self.jc_wait_time()
            self.display_refresh(self.start_axis,
                                 self.circle,
                                 cue=self.cue_location)

        while self.evm.before("circle box end"):
            self.jc_wait_time()
            self.display_refresh(self.start_axis, self.circle)

        current_frame = 0
        while self.evm.before("animation end"):
            self.jc_wait_time()
            if self.animation_trial:
                if current_frame < self.animation_frames:
                    if self.evm.trial_time_ms > (
                            current_frame * self.frame_duration + 1600):
                        box_locs = self.frames[self.start_axis][
                            self.rotation_dir][current_frame]
                        self.display_refresh(box_locs, self.asterisk)
                        current_frame += 1
            else:
                self.display_refresh(self.start_axis, self.asterisk)

        while self.evm.before("asterisk end"):
            self.display_refresh(self.box_axis_during_target(), self.circle)
            self.jc_wait_time()

        flush()
        self.display_refresh(self.box_axis_during_target(),
                             self.circle,
                             target=self.target_location)

        if P.saccade_response_cond:
            self.jc_saccade_data()
            keypress_rt = NA

        if P.keypress_response_cond:
            self.rc.collect()
            keypress_rt = self.rc.keypress_listener.response(rt=True,
                                                             value=False)

        clear()
        smart_sleep(1000)

        if P.keypress_response_cond:
            if self.target_location == "none" and keypress_rt != TIMEOUT:
                fill()
                message(self.err_msgs['early'],
                        registration=5,
                        location=P.screen_c)
                flip()
                any_key()
            elif self.moved_eyes_during_rc:
                fill()
                message("Moved eyes during response interval!",
                        registration=5,
                        location=P.screen_c)
                flip()
                any_key()

        return {
            "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":
            str(self.animation_trial).upper(),
            "target_acquired":
            str(self.target_acquired).upper()
            if P.saccade_response_cond else NA,
            "keypress_rt":
            keypress_rt,
            "moved_eyes":
            str(self.moved_eyes_during_rc).upper()
            if P.keypress_response_cond else NA
        }
Beispiel #22
0
    def trial(self):
        # Hide cursor during trial
        hide_mouse_cursor()

        # Wait some foreperiod before presenting T1
        while self.evm.before('T1_on', True):
            ui_request()

        # Present T1
        fill()
        blit(self.tmtm_stream['t1_target'],
             registration=5,
             location=P.screen_c)
        flip()

        self.t1_sw = Stopwatch()

        # Don't do anything during T1 presentation
        while self.evm.before('T1_off', True):
            ui_request()

        self.t1_isi_sw = Stopwatch()
        # Remove T1
        fill()
        flip()
        self.t1_sw.pause()
        print("T1 duration actual: " + str(self.t1_sw.elapsed()))
        fill()
        flip()

        while self.evm.before('T1_mask_on', True):
            ui_request()

        self.t1_isi_sw.pause()

        print("ISI actual: " + str(self.t1_isi_sw.elapsed()))

        # After one refresh rate (how long it takes to remove T1) present mask
        fill()
        blit(self.tmtm_stream['t1_mask'], registration=5, location=P.screen_c)
        flip()

        self.t1_mask_sw = Stopwatch()

        # Don't do anything during presentation
        while self.evm.before('T1_mask_off', True):
            ui_request()

        # Remove mask
        fill()
        flip()
        self.t1_mask_sw.pause()
        print("T1 mask duration actual: " + str(self.t1_mask_sw.elapsed()))

        # If not practicing, present T2
        if not P.practicing:

            # After TTOA is up, present T2
            while self.evm.before('T2_on', True):
                ui_request()

            fill()
            blit(self.tmtm_stream['t2_target'],
                 registration=5,
                 location=P.screen_c)
            flip()

            self.t2_sw = Stopwatch()

            # Don't do anything during presentation
            while self.evm.before('T2_off', True):
                ui_request()

            self.t2_isi_sw = Stopwatch()

            # Remove T2
            fill()
            flip()

            self.t2_sw.pause()

            fill()
            flip()

            while self.evm.before('T2_mask_on', True):
                ui_request()

            self.t2_isi_sw.pause()

            # After one refresh rate, present mask
            fill()
            blit(self.tmtm_stream['t2_mask'],
                 registration=5,
                 location=P.screen_c)
            flip()

            self.t2_mask_sw = Stopwatch()

            # Don't do anything during presentation
            while self.evm.before('T2_mask_off', True):
                ui_request()

            # Remove mask
            fill()
            flip()

            self.t2_mask_sw.pause()

        # Wait 1/3 second before asking for responses
        while self.evm.before('response_foreperiod', True):
            ui_request()

        # Request & record responses
        if self.block_type == IDENTITY:
            # Not relevant to identity trials
            t1_response_err, t1_response_err_rt, t2_response_err, t2_response_err_rt = [
                'NA', 'NA', 'NA', 'NA'
            ]

            # Collect identity responses
            self.t1_identity_rc.collect()

            if not P.practicing:
                self.t2_identity_rc.collect()

            # Assign to variables returned
            t1_id_response, t1_id_rt = self.t1_identity_rc.keypress_listener.response(
            )

            # No T2 present during practice
            if not P.practicing:
                t2_id_response, t2_id_rt = self.t2_identity_rc.keypress_listener.response(
                )
            else:
                t2_id_response, t2_id_rt = ['NA', 'NA']

            # During practice, keep a tally of T1 performance
            if P.practicing:
                if t1_id_response == self.t1_identity:
                    self.t1_performance += 1

        else:  # Colour block
            # Not relevant to colour trials
            t1_id_response, t1_id_rt, t2_id_response, t2_id_rt = [
                'NA', 'NA', 'NA', 'NA'
            ]

            # Collect colour responses
            self.t1_colouring_rc.collect()

            if not P.practicing:
                self.t2_colouring_rc.collect()

            # Assign to variables returned
            t1_response_err, t1_response_err_rt = self.t1_colouring_rc.color_listener.response(
            )

            # T2 only presented during test blocks
            if not P.practicing:
                t2_response_err, t2_response_err_rt = self.t2_colouring_rc.color_listener.response(
                )
            else:
                t2_response_err, t2_response_err_rt = ['NA', 'NA']

            if P.practicing:
                # As numeric identities have 9 possible values, similarly the colour wheel can
                # be thought of as having 9 'bins' (each 40º wide). Colour responses are labelled
                # as 'correct' if their angular error does not exceed 20º in either direction.

                if (abs(t1_response_err) <= 20):
                    self.t1_performance += 1

        clear()

        print(self.target_duration)
        print(self.mask_duration)

        return {
            "practicing":
            str(P.practicing),
            "block_num":
            P.block_number,
            "trial_num":
            P.trial_number,
            "block_type":
            self.block_type,
            "itoa":
            self.itoa,
            "ttoa":
            self.ttoa,
            "target_duration":
            self.target_duration,
            "mask_duration":
            self.mask_duration,
            "t1_identity":
            self.t1_identity,
            "t2_identity":
            self.t2_identity if not P.practicing else 'NA',
            "t1_identity_response":
            t1_id_response,
            "t1_identity_rt":
            t1_id_rt,
            "t2_identity_response":
            t2_id_response,
            "t2_identity_rt":
            t2_id_rt,
            "t1_colour":
            self.t1_colour,
            "t1_angle":
            self.t1_angle,
            "t1_wheel_rotation":
            self.t1_wheel.rotation,
            "t2_colour":
            self.t2_colour if not P.practicing else 'NA',
            "t2_angle":
            self.t2_angle if not P.practicing else 'NA',
            "t2_wheel_rotation":
            self.t2_wheel.rotation if not P.practicing else 'NA',
            "t1_ang_err":
            t1_response_err,
            "t1_colour_rt":
            t1_response_err_rt,
            "t2_ang_err":
            t2_response_err,
            "t2_colour_rt":
            t2_response_err_rt,
            "t1_performance_practice":
            self.t1_performance if P.practicing else 'NA',
            "t1_duration_actual":
            self.t1_sw.elapsed(),
            "t1_isi_actual":
            self.t1_isi_sw.elapsed(),
            "t1_mask_duration_actual":
            self.t1_mask_sw.elapsed(),
            "t2_duration_actual":
            self.t2_sw.elapsed() if not P.practicing else 'NA',
            "t2_isi_actual":
            self.t2_isi_sw.elapsed() if not P.practicing else 'NA',
            "t2_mask_duration_actual":
            self.t2_mask_sw.elapsed() if not P.practicing else 'NA'
        }