def record_start(self, timestamp): # eye-link time unnecessary as the eyelink will supply this in the EDF when written self.exp.evi.write(self.event_start_label + " (trial_time={0})".format(timestamp[0])) self.on_timestamp = timestamp Params.clock.register_event( ET(self.event_timeout_label, self.timeout_interval, relative=True))
def trial_prep(self): if self.search_type == SPACE: array_radius = deg_to_px(6) theta = 360.0 / self.cell_count self.item_locs = [] for i in range(0, self.cell_count): self.item_locs.append(point_pos(origin=P.screen_c, amplitude=array_radius, angle=0, rotation=theta*(i+1))) random.shuffle(self.item_locs) self.target_loc = self.item_locs.pop() self.target_bounds = [ point_pos(self.target_loc, amplitude=self.item_size/2, angle=0, rotation=135), point_pos(self.target_loc, amplitude=self.item_size/2, angle=0, rotation=315) ] self.spatial_rc.cursor_listener.add_boundary('target_boundary', self.target_bounds, RECT_BOUNDARY) else: self.rsvp_stream = self.prepare_stream() self.rsvp_stream.reverse() # items are extracted via pop() in present_stream() events = [[1000, 'present_target']] events.append([events[-1][0] + 1000, 'present_fixation']) events.append([events[-1][0] + 1000, 'search_onset']) for e in events: self.evm.register_ticket(ET(e[1], e[0])) hide_mouse_cursor() self.present_target()
def trial_prep(self): # Select target stimuli & durations self.t1_identity, self.t2_identity = random.sample(letters,2) self.t1_duration, self.m1_duration = self.t1_timings[self.t1_difficulty] # Init EventManager events = [[self.isoa, "T1_on"]] # Present T1 after some SOA from initiation events.append([events[-1][0] + self.t1_duration, 'T1_off']) # Remove T1 after its duration period events.append([events[-1][0] + self.isi, "T1_mask_on"]) # Present M1 shortly after T1 offset events.append([events[-1][0] + self.m1_duration, 'T1_mask_off']) # Remove M1 after its duration period events.append([events[-4][0] + self.ttoa, 'T2_on']) # TTOA = Time between onset of T1 & T2 events.append([events[-1][0] + self.t2_duration, 'T2_off']) # Remove T2 after its duration period events.append([events[-1][0] + self.isi, 'T2_mask_on']) # Present M2 shortly after T2 offset events.append([events[-1][0] + self.m2_duration, 'T2_mask_off']) # Remove M2 after its duration period # Register events to EventManager for e in events: self.evm.register_ticket(ET(e[1],e[0])) # Prepare stimulus stream self.tmtm_stream = self.prep_stream() # Hide mouse cursor during trial hide_mouse_cursor() # Present fix and wait until initiation response before beginning tiral sequence self.present_fixation()
def trial_prep(self): self.target_onset = NA if self.search_type == SPACE: array_radius = deg_to_px(8) theta = 360.0 / self.set_size self.item_locs = [] for i in range(0, self.set_size): self.item_locs.append( point_pos(origin=P.screen_c, amplitude=array_radius, angle=0, rotation=theta * (i + 1))) random.shuffle(self.item_locs) if self.present_absent == PRESENT: self.target_loc = self.item_locs.pop() else: self.rsvp_stream = self.prepare_stream() self.rsvp_stream.reverse( ) # items are extracted via pop() in present_stream() events = [[1000, 'present_target']] events.append([events[-1][0] + 1000, 'present_fixation']) events.append([events[-1][0] + 1000, 'search_onset']) for e in events: self.evm.register_ticket(ET(e[1], e[0])) hide_mouse_cursor() self.present_target()
def trial_prep(self): self.angle = int(self.angle) self.n_back = int(self.n_back) self.saccade_count = randrange(self.min_saccades, self.max_saccades) self.fill() m = self.message("Generating targets...", blit=False) self.blit(m) self.flip() errors = 0 while len(self.locations) != self.saccade_count: self.fill() self.blit(m, location=(25, 25)) try: self.generate_locations() except (TrialException, ValueError): errors += 1 self.message("Failed attempts: {0}".format(errors), location=(25, 50)) self.locations = [] self.flip() self.bg = self.background[choice(self.backgrounds.keys())] Params.clock.register_event( ET("initial fixation end", Params.fixation_interval)) self.eyelink.drift_correct(boundary="trial_fixation") self.display_refresh(True)
def trial_prep(self): # Reset error flag self.targets_shown = False self.err = None # TRAINING PROPERTIES if P.practicing: self.cotoa = 'NA' # No cue, so no COTOA # Establish location of target line if self.tilt_line_location == LEFT: self.tilt_line_loc = self.left_box_loc self.flat_line_loc = self.right_box_loc else: self.tilt_line_loc = self.right_box_loc self.flat_line_loc = self.left_box_loc # PROBE PROPERTIES else: # Rest breaks if P.trial_number % (P.trials_per_block / P.breaks_per_block) == 0: if P.trial_number < P.trials_per_block: fill() msg = message(self.rest_break_txt, 'myText', blit_txt=False) blit(msg, 5, P.screen_c) flip() any_key() # Establish & assign probe location self.probe_loc = self.right_box_loc if self.probe_location == RIGHT else self.left_box_loc # go/nogo signal always presented w/probe self.go_nogo_loc = self.probe_loc # Establish & assign probe colour if self.probe_colour == HIGH: self.probe.fill = self.high_value_colour elif self.probe_colour == LOW: self.probe.fill = self.low_value_colour else: self.probe.fill = self.neutral_value_colour # Add timecourse of events to EventManager if P.practicing: # training trials events = [[1000, 'target_on']] else: # Probe trials events = [[1000, 'cue_on']] events.append([events[-1][0] + 200, 'cue_off']) events.append([events[-1][0] + 200, 'cueback_off']) events.append([events[-2][0] + 800, 'target_on']) for e in events: self.evm.register_ticket(ET(e[1], e[0])) # Perform drift correct on Eyelink before trial start self.el.drift_correct()
def trial_prep(self): # Prepare colour wheels self.t1_wheel.rotation = random.randrange( 0, 360) # Randomly rotate wheel to prevent location biases self.t1_wheel.render() self.t2_wheel.rotation = random.randrange( 0, 360) # Randomly rotate wheel to prevent location biases self.t2_wheel.render() # Prepare T1 & T2 self.t1_identity = random.sample(numbers, 1)[0] # Select & assign identity self.t1_colour = self.t1_wheel.color_from_angle( random.randrange(0, 360)) # Select & assign colouring self.t1_time = random.sample( range(5), 1 )[0] + 5 # Select T1 stream position, no earlier than the 5th item self.t2_identity = random.sample(numbers, 1)[0] self.t2_colour = self.t2_wheel.color_from_angle( random.randrange(0, 360)) self.t2_time = self.t1_time + self.lag # Lag: # of items interspacing the two targets (can be 1-8) while self.t1_identity == self.t2_identity: # Ensure that T1 & T2 identities are unique self.t2_identity = random.sample(numbers, 1)[0] while self.t1_colour == self.t2_colour: # Similarly, colouring self.t2_colour = self.t2_wheel.color_from_angle( random.randrange(0, 360)) # Dummy objects to serve as reference point when calculating response error self.t1_dummy.fill = self.t1_colour self.t2_dummy.fill = self.t2_colour self.t1_colouring_rc.display_callback = self.wheel_callback self.t1_colouring_rc.display_kwargs = {'wheel': self.t1_wheel} self.t1_colouring_rc.color_listener.set_wheel( self.t1_wheel) # Set generated wheel as wheel to use self.t1_colouring_rc.color_listener.set_target(self.t1_dummy) self.t2_colouring_rc.display_callback = self.wheel_callback self.t2_colouring_rc.display_kwargs = {'wheel': self.t2_wheel} self.t2_colouring_rc.color_listener.set_wheel(self.t2_wheel) self.t2_colouring_rc.color_listener.set_target(self.t2_dummy) # Prepare stream according to response block (Identity | Colouring) self.rsvp_stream = self.prep_stream(self.block_type) # Initialize EventManager # Stream begins 1000ms after fixation self.evm.register_ticket(ET('stream_on', 1000))
def initial_fixation(self): self.display_refresh(True) while self.evi.before("initial fixation end", True): if self.eyelink.saccade_from_boundary("trial_fixation"): fif_e = ET("failed initial fixation", Params.clock.trial_time + 1.0, None, False, TK_S) Params.clock.register_event(fif_e) while self.evi.before("failed initial fixation", True): self.fill(RED) self.blit(self.looked_away_msg, BL_CENTER, Params.screen_c) self.flip() raise TrialException("Gaze out of bounds.") self.display_refresh(True)
def onset_delay(self, previous_disc): # not applicable on persistent-behavior targets if self.persists: return self.previous_disc = previous_disc if self.previous_disc.timed_out: return try: Params.clock.register_event( ET(self.onset_delay_label, self.idi, relative=True)) except TypeError: # ie. inter_disc_interval was False pass while self.exp.evi.before(self.onset_delay_label, True): pass self.previous_disc.allow_blit = False
def trial_prep(self): if self.search_type == SPACE: self.search_stimuli = self.prepare_spatial_array() self.rc.display_callback = self.present_spatial_array self.rc.display_kwargs = {'spatial_array': self.search_stimuli} else: self.search_stimuli = self.prepare_temporal_stream() self.rc.display_callback = self.present_temporal_stream self.rc.display_kwargs = {'temporal_stream': self.search_stimuli} events = [[1000, 'present_example_target']] events.append([events[-1][0] + 1000, 'present_fixation']) events.append([events[-1][0] + 1000, 'search_onset']) for e in events: self.evm.register_ticket(ET(e[1], e[0])) self.trial_sw = Stopwatch() self.present_target() hide_mouse_cursor()
def trial_prep(self): # Determine location of target and flankers if self.target_location == 'above': self.target_loc = self.above_loc self.flanker_locs = self.above_flanker_locs else: self.target_loc = self.below_loc self.flanker_locs = self.below_flanker_locs # Set central arrow and flanker arrow types if self.target_direction == "left": self.target = self.arrow_l if self.flanker_type == "congruent": self.flanker = self.arrow_l elif self.flanker_type == "incongruent": self.flanker = self.arrow_r else: self.flanker = self.line else: self.target = self.arrow_r if self.flanker_type == "congruent": self.flanker = self.arrow_r elif self.flanker_type == "incongruent": self.flanker = self.arrow_l else: self.flanker = self.line # Add timecourse of events to EventManager self.onset_delay = random.randrange( 400, 1650, 50) # random interval from 400 to 1600 events = [] events.append([self.onset_delay, 'tone_on']) events.append([events[-1][0] + 50, 'tone_off']) events.append([events[-1][0] + 400, 'cue_on']) events.append([events[-1][0] + P.cue_duration, 'cue_off']) events.append([events[-1][0] + self.soa, 'target_on']) events.append([3950 + self.soa, 'trial_end']) for e in events: self.evm.register_ticket(ET(e[1], e[0]))
def trial_prep(self): self.target_1_loc = self.box_l_pos if self.target_loc == LEFT else self.box_r_pos self.target_2_loc = self.box_r_pos if self.target_loc == LEFT else self.box_l_pos self.t1 = self.v_line.render( ) if self.first_target == VERTICAL else self.h_line.render() self.t2 = self.h_line.render( ) if self.first_target == VERTICAL else self.v_line.render() self.wheel_prototype.rotation = int(random.uniform(0, 360)) self.probe_angle = int(random.uniform(0, 360)) self.probe_color = colors[self.probe_angle] self.wheel = self.wheel_prototype.render() self.probe_prototype.fill = self.probe_color self.probe = self.probe_prototype.render() self.probe_loc = self.probe_locs.pop( ) if self.trial_type == PROBE else NA self.probe_pos = self.box_l_pos if self.probe_loc == LEFT else self.box_r_pos events = [[ self.t1_offset_constant + choice(range(15, 450, 15)), 'target_1_on' ]] events.append([events[-1][0] + 200, 'probe_off']) # original 350 ms events.append([events[-2][0] + int(self.soa), 'target_2_on']) events.append([events[-1][0] + 300, 'target_2_off']) for e in events: Params.clock.register_event(ET(e[1], e[0])) if Params.trial_number > 1: self.fill() self.blit(self.trial_start_message, registration=5, location=Params.screen_c) self.flip() self.any_key() self.fill() self.display_refresh(False)
def trial_prep(self): # Reset error flag self.targets_shown = False self.err = None # If probed trial, establish location of probe (default: left box) self.probe_loc = self.right_box_loc if self.probe_location == RIGHT else self.left_box_loc if self.high_value_location == LEFT: self.left_bandit.fill = self.high_value_color self.right_bandit.fill = self.low_value_color self.low_value_location = RIGHT else: self.left_bandit.fill = self.low_value_color self.right_bandit.fill = self.high_value_color self.low_value_location = LEFT self.left_bandit.render() self.right_bandit.render() # Randomly choose cue off-target on asynchrony (cotoa) on each trial self.cotoa = self.random_interval(self.cotoa_min, self.cotoa_max) # Add timecourse of events to EventManager events = [[1000, 'cue_on']] events.append([events[-1][0] + 200, 'cue_off']) events.append([events[-1][0] + 200, 'cueback_off']) events.append([events[-2][0] + self.cotoa, 'target_on']) # either probe or bandits if self.trial_type in [BANDIT, BOTH]: events.append([events[-1][0] + 500, 'nogo_end']) # should reduce to 500 or less for e in events: self.evm.register_ticket(ET(e[1], e[0])) # Perform drift correct on EyeLink before trial start self.el.drift_correct()
def trial_prep(self): # Determing the starting locations of the two target shapes if self.t1_location == "left": t1_x = self.left_x t2_x = self.right_x else: t1_x = self.right_x t2_x = self.left_x # Set shapes for t1 and t2 if self.t1_shape == "a": self.t1 = self.diamond_a self.t2 = self.diamond_b self.t1_line = self.line_b self.t2_line = self.line_a else: self.t1 = self.diamond_b self.t2 = self.diamond_a self.t1_line = self.line_a self.t2_line = self.line_b self.t1_pos = (t1_x, P.screen_c[1]) self.t2_pos = (t2_x, P.screen_c[1]) # Initialize start/end positions and animation paths if self.toj_type == "motion": self.start_offset = P.screen_y/4 + deg_to_px(random.uniform(-2, 2)) end_offset = deg_to_px(5.0) if self.upper_target == "t2": self.start_offset *= -1 end_offset *= -1 self.t1_reg = 8 self.t2_reg = 2 else: self.t1_reg = 2 self.t2_reg = 8 t1_start = (t1_x, P.screen_c[1]-self.start_offset) t1_end = (t1_x, P.screen_c[1]+end_offset) self.t1_path = Animation(t1_start, t1_end, self.motion_duration) t2_offset = self.t1_path.motion_per_ms[1] * self.t1_t2_soa t2_start = (t2_x, P.screen_c[1]+self.start_offset+t2_offset) t2_end = (t2_x, P.screen_c[1]-end_offset+t2_offset) self.t2_path = Animation(t2_start, t2_end, self.motion_duration) print(self.upper_target, self.t1_location, self.t1_t2_soa, self.start_offset, t2_offset) print("t1 start: {0} end: {1}".format(t1_start, t1_end)) print("t2 start: {0} end: {1}".format(t2_start, t2_end)) # Set up colour probe and colour wheel self.wheel.rotation = random.randrange(0, 360, 1) self.wheel.render() self.probe.fill = self.wheel.color_from_angle(random.randrange(0, 360, 1)) self.probe.render() # Determine the probe location for the trial self.probe_location = self.probe_locs.pop() self.probe_pos = self.probe_positions[self.probe_location] # Calculate when t1 onset and t2 off are going to be based on motion if self.toj_type == "motion": self.t1_on = (1/self.t1_path.motion_per_ms[1])*self.start_offset self.t2_off = (1/self.t1_path.motion_per_ms[1])*(self.start_offset+end_offset) else: self.t1_on = self.random_interval(700, 1200) self.t2_off = self.t1_on + self.t1_t2_soa-1 + 300 # Add timecourse of events to EventManager events = [] events.append([self.t1_on, 't1_on']) events.append([events[-1][0] + 200, 'probe_off']) events.append([events[-2][0] + self.t1_t2_soa-1, 't2_on']) events.append([self.t2_off, 't2_off']) for e in events: self.evm.register_ticket(ET(e[1], e[0]))
def trial_prep(self): # Prepare colour wheels self.t1_wheel.rotation = random.randrange( 0, 360) # Randomly rotate wheel to prevent location biases self.t2_wheel.rotation = random.randrange(0, 360) while self.t1_wheel.rotation == self.t2_wheel.rotation: # Ensure unique rotation values self.t2_wheel.rotation = random.randrange(0, 360) self.t1_wheel.render() self.t2_wheel.render() # Select target identities self.t1_identity = random.sample(numbers, 1)[0] # Select & assign identity self.t2_identity = random.sample(numbers, 1)[0] while self.t1_identity == self.t2_identity: # Ensure that T1 & T2 identities are unique self.t2_identity = random.sample(numbers, 1)[0] # Select target angles (for selecting colour from wheel) self.t1_angle = random.randrange(0, 360) self.t2_angle = random.randrange(0, 360) while self.t1_angle == self.t2_angle: self.t2_angle = random.randrange(0, 360) self.t1_colour = self.t1_wheel.color_from_angle( self.t1_angle) # Assign colouring self.t2_colour = self.t2_wheel.color_from_angle(self.t2_angle) # Dummy objects to serve as reference point when calculating response error self.t1_dummy.fill = self.t1_colour self.t2_dummy.fill = self.t2_colour self.t1_colouring_rc.display_callback = self.wheel_callback self.t1_colouring_rc.display_kwargs = {'wheel': self.t1_wheel} self.t1_colouring_rc.color_listener.set_wheel( self.t1_wheel) # Set generated wheel as wheel to use self.t1_colouring_rc.color_listener.set_target( self.t1_dummy) # Set dummy as target reference point self.t2_colouring_rc.display_callback = self.wheel_callback self.t2_colouring_rc.display_kwargs = { 'wheel': self.t2_wheel } # Passed as arg w/ calling wheel_callback() self.t2_colouring_rc.color_listener.set_wheel(self.t2_wheel) self.t2_colouring_rc.color_listener.set_target(self.t2_dummy) if self.block_type == IDENTITY: self.target_duration = self.id_target_duration self.mask_duration = self.id_mask_duration else: self.target_duration = self.col_target_duration self.mask_duration = self.col_mask_duration # Initialize EventManager if P.practicing: # T2 not present during practice blocks events = [[self.itoa, "T1_on"]] events.append([events[-1][0] + self.target_duration, 'T1_off']) events.append([events[-1][0] + self.isi, 'T1_mask_on']) events.append([events[-1][0] + self.mask_duration, 'T1_mask_off']) events.append([events[-1][0] + 300, 'response_foreperiod']) else: events = [[self.itoa, 'T1_on']] events.append([events[-1][0] + self.target_duration, 'T1_off']) events.append([events[-1][0] + self.isi, 'T1_mask_on']) events.append([events[-1][0] + self.mask_duration, 'T1_mask_off']) events.append([events[-4][0] + self.ttoa, 'T2_on']) # SOA = Time between onset of T1 & T2 events.append([events[-1][0] + self.target_duration, 'T2_off']) events.append([events[-1][0] + self.isi, 'T2_mask_on']) events.append([events[-1][0] + self.mask_duration, 'T2_mask_off']) events.append([events[-1][0] + 300, 'response_foreperiod']) # Stream begins 1000ms after fixation for e in events: self.evm.register_ticket(ET(e[1], e[0])) # Prepare stream self.tmtm_stream = self.prep_stream() # Present fixation & wait for initiation self.present_fixation()