def __init__(self, first, last, width, height, style, registration=None, location=None): BoundaryInspector.__init__(self) self.range = range(first, last+1, 1) self.count = len(self.range) self.response = None self.height = height self.width = width self.circle_size = self.height self.gap = (width - self.circle_size * self.count) / (self.count - 1) self.__location = location if location else P.screen_c self.__registration = registration if registration else 5 self.__init_bounds() numlist = [] for num in self.range: num_txt = message("{0}".format(num), style, blit_txt=False) numlist.append((num, num_txt)) self.numbers = dict(numlist) self.selected = kld.Ellipse(self.circle_size-4, fill=TRANSLUCENT_GREY) self.mouseover = self.selected#kld.Annulus(self.circle_size-4, 6, fill=MED_GREY)
def test_mask(): # Initialize test surface and masks # NOTE: Testing KLDraw objects further down, since KLD rectangles have 1px # transparent padding that breaks this test loop's logic surface = NumpySurface(width=100, height=100, fill=[255, 0, 0]) nps_mask = NumpySurface(width=50, height=50, fill=[255, 255, 255]) np_mask = nps_mask.render() greyscale_mask = Image.new('L', (50, 50), 0) ImageDraw.Draw(greyscale_mask).rectangle((0, 0, 50, 50), fill=255) rgb_mask = Image.new('RGB', (50, 50), (0, 0, 0)) ImageDraw.Draw(rgb_mask).rectangle((0, 0, 50, 50), fill=(255, 0, 0)) # Test different mask types for mask in [nps_mask, np_mask, greyscale_mask, rgb_mask]: surf = surface.copy() surf.mask(mask, registration=7, location=(0, 0)) assert surf.content[49][49][3] == 0 assert surf.content[50][50][3] == 255 # Test legacy positioning surf = surface.copy() surf.mask(nps_mask, (25, 25)) assert surf.content[0][0][3] == 255 and surf.content[25][25][3] == 0 # Test with mask partially off surface surf = surface.copy() surf.mask(nps_mask, registration=3, location=(25, 25)) assert surf.content[24][24][3] == 0 and surf.content[25][25][3] == 255 surf.mask(nps_mask, registration=7, location=(75, 75)) assert surf.content[74][74][3] == 255 and surf.content[75][75][3] == 0 # Test inverse/non-inverse modes and complete masking circle_mask = kld.Ellipse(50, fill=(255, 255, 255)) for complete in [True, False]: surf = surface.copy() surf.mask(circle_mask, location=(0, 0), invert=True, complete=complete) assert surf.content[0][0][3] == 255 and surf.content[25][25][3] == 0 assert surf.content[-1][-1][3] == (0 if complete else 255) surf = surface.copy() surf.mask(circle_mask, location=(0, 0), invert=False, complete=complete) assert surf.content[0][0][3] == 0 and surf.content[25][25][3] == 255 assert surf.content[-1][-1][3] == (0 if complete else 255) # Test exception for invalid mask type with pytest.raises(TypeError): surf = surface.copy() surf.mask("hello")
def __init__(self, width, diameter=60, fills={}, ticks=None, location=None): self.width = width self.ticks = ticks self.location = location if location else P.screen_c _fills = {'line': MED_GREY, 'slider': TRANSLUCENT_BLUE} _fills.update(fills) # override default colours if fills provided self.line = kld.Rectangle(width, 2, fill=_fills['line']) self.tick = kld.Rectangle(2, int(diameter/2), fill=_fills['line']) self.button = kld.Ellipse(diameter, fill=_fills['slider']) self.__clicked = False self.__dragging = False self.__drag_offset = 0 self.__abs_pos = self.location
def setup(self): # Stimulus Sizes target_size = deg_to_px(3.0) diamond_size = sqrt(target_size**2/2.0) probe_diameter = deg_to_px(1.0) wheel_diameter = deg_to_px(16.0) # Stimulus Drawbjects self.line_a = kld.Rectangle(width=P.screen_x/2, height=2, fill=WHITE) self.line_b = kld.Rectangle(width=P.screen_x/2, height=2, fill=BLACK) self.diamond_a = kld.Rectangle(diamond_size, fill=WHITE, rotation=45) self.diamond_b = kld.Rectangle(diamond_size, fill=BLACK, rotation=45) self.probe = kld.Ellipse(probe_diameter, fill=None) self.wheel = kld.ColorWheel(wheel_diameter) self.line_a.render() self.line_b.render() self.diamond_a.render() self.diamond_b.render() # Layout self.left_x = P.screen_x/4 self.right_x = 3*P.screen_x/4 self.probe_positions = { "left": (self.left_x, P.screen_c[1]), "right": (self.right_x, P.screen_c[1]) } self.start_baseline = P.screen_y/4 self.end_offset = deg_to_px(5.0) self.left_start = [self.left_x, P.screen_y/4] self.right_start = [self.right_x, 3*P.screen_y/4] self.left_end = [self.left_x, P.screen_c[1]+self.end_offset] self.right_end = [self.right_x, P.screen_c[1]-self.end_offset] # Timing self.motion_duration = 1.5 # seconds # Experiment Messages if not P.condition: P.condition = P.default_condition toj_string = "Which shape {0} {1}?\n(White = 8 Black = 2)" stationary_string = toj_string.format("appeared", P.condition) motion_string = toj_string.format("touched the line", P.condition) self.toj_prompts = { 'stationary': message(stationary_string, align="center", blit_txt=False), 'motion': message(motion_string, align="center", blit_txt=False) } # Initialize ResponseCollector keymaps if P.use_numpad: keysyms = [sdl2.SDLK_KP_8, sdl2.SDLK_KP_2] else: keysyms = [sdl2.SDLK_8, sdl2.SDLK_2] self.toj_keymap = KeyMap( "toj_responses", # Name ['8', '2'], # UI labels ['white', 'black'], # Data labels keysyms # SDL2 Keysyms ) # Initialize second ResponseCollector object for colour wheel responses self.wheel_rc = ResponseCollector() # Generate practice blocks default_soas = self.trial_factory.exp_factors['t1_t2_soa'] toj_soas = [soa for soa in default_soas if soa!=0.0] toj_only = {"t1_t2_soa": toj_soas} probe_only = {"t1_t2_soa": [0.0]} if P.run_practice_blocks: num = P.trials_per_practice_block self.insert_practice_block(1, trial_counts=num, factor_mask=toj_only) self.insert_practice_block((2,4), trial_counts=num, factor_mask=probe_only) self.trial_factory.dump()
def setup(self): # ---------------------------------- # # Setup Stimuli # # ---------------------------------- # # Set stimulus sizes line_length = deg_to_px(2) line_thickness = deg_to_px(0.5) thick_rect_border = deg_to_px(0.7) thin_rect_border = deg_to_px(0.3) fix_size = deg_to_px(0.6) fix_thickness = deg_to_px(0.1) square_size = deg_to_px(3) large_text_size = deg_to_px(0.65) # Stimulus layout box_offset = deg_to_px(8.0) self.left_box_loc = (P.screen_c[0] - box_offset, P.screen_c[1]) self.right_box_loc = (P.screen_c[0] + box_offset, P.screen_c[1]) # Generate target colouring # Select target colours from randomly rotated colourwheel # ensuring those selected are unique and equidistant self.color_selecter = kld.ColorWheel(diameter=1, rotation=random.randrange(0, 360)) self.target_colours = [] for i in (0, 120, 240): self.target_colours.append(self.color_selecter.color_from_angle(i)) # Assign colours to payout valences random.shuffle(self.target_colours) self.high_value_colour = self.target_colours[0] self.low_value_colour = self.target_colours[1] self.neutral_value_colour = self.target_colours[2] # Initialize drawbjects self.thick_rect = kld.Rectangle( square_size, stroke=[thick_rect_border, WHITE, STROKE_CENTER]) self.thin_rect = kld.Rectangle( square_size, stroke=[thin_rect_border, WHITE, STROKE_CENTER]) self.high_val_rect = kld.Rectangle( square_size, stroke=[thin_rect_border, self.high_value_colour, STROKE_CENTER]) self.low_val_rect = kld.Rectangle( square_size, stroke=[thin_rect_border, self.low_value_colour, STROKE_CENTER]) self.fixation = kld.Asterisk(fix_size, fix_thickness, fill=WHITE) self.fix_cueback = kld.Asterisk(fix_size * 2, fix_thickness * 2, fill=WHITE) self.go = kld.FixationCross(fix_size, fix_thickness, fill=BLACK) self.nogo = kld.FixationCross(fix_size, fix_thickness, fill=BLACK, rotation=45) self.flat_line = kld.Rectangle(line_length, line_thickness, fill=BLACK) self.tilt_line = kld.Rectangle(line_length, line_thickness, fill=BLACK, rotation=45) self.probe = kld.Ellipse(int(0.75 * square_size)) # ---------------------------------- # # Setup other experiment factors # # ---------------------------------- # # COTOA = Cue-Offset|Target-Onset Asynchrony self.cotoa = 800 # ms self.feedback_exposure_period = 1.25 # sec # Training block payout variables self.high_payout_baseline = 12 self.low_payout_baseline = 8 self.total_score = None self.penalty = -5 # ---------------------------------- # # Setup Response Collectors # # ---------------------------------- # # Initialize response collectors self.probe_rc = ResponseCollector(uses=RC_KEYPRESS) self.training_rc = ResponseCollector(uses=RC_KEYPRESS) # Initialize ResponseCollector keymaps self.training_keymap = KeyMap( 'training_response', # Name ['z', '/'], # UI labels ["left", "right"], # Data labels [sdl2.SDLK_z, sdl2.SDLK_SLASH] # SDL2 Keysyms ) self.probe_keymap = KeyMap('probe_response', ['spacebar'], ["pressed"], [sdl2.SDLK_SPACE]) # --------------------------------- # # Setup Experiment Messages # # --------------------------------- # # Make default font size larger self.txtm.add_style('myText', large_text_size, WHITE) err_txt = "{0}\n\nPress any key to continue." lost_fixation_txt = err_txt.format( "Eyes moved! Please keep your eyes on the asterisk.") probe_timeout_txt = err_txt.format( "No response detected! Please respond as fast and as accurately as possible." ) training_timeout_txt = err_txt.format("Line response timed out!") response_on_nogo_txt = err_txt.format( "\'nogo\' signal (x) presented\nPlease only respond when you see " "the \'go\' signal (+).") self.err_msgs = { 'fixation': message(lost_fixation_txt, 'myText', align='center', blit_txt=False), 'probe_timeout': message(probe_timeout_txt, 'myText', align='center', blit_txt=False), 'training_timeout': message(training_timeout_txt, 'myText', align='center', blit_txt=False), 'response_on_nogo': message(response_on_nogo_txt, 'myText', align='center', blit_txt=False) } self.rest_break_txt = err_txt.format( "Whew! that was tricky eh? Go ahead and take a break before continuing." ) self.end_of_block_txt = "You're done the first task! Please buzz the researcher to let them know!" # -------------------------------- # # Setup Eyelink boundaries # # -------------------------------- # fix_bounds = [P.screen_c, square_size / 2] self.el.add_boundary('fixation', fix_bounds, CIRCLE_BOUNDARY) # --------------------------------- # # Insert training block (line task) # # --------------------------------- # if P.run_practice_blocks: self.insert_practice_block(1, trial_counts=P.trials_training_block)
def test_init_kldraw(self): d = kld.Ellipse(100, fill=(255, 255, 255)) surf = NumpySurface(d) assert d.surface_height == surf.height and d.surface_width == surf.width assert surf.content[50][50][0] == 255